diff options
author | Shirish Pargaonkar <shirishpargaonkar@gmail.com> | 2017-06-22 23:52:05 -0400 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2017-07-05 20:57:53 -0400 |
commit | 2f1afe25997fc28027ae95d89ccf03e1eef2dca1 (patch) | |
tree | 25e42529b3037a5745c230ea5d5a01ad05c575bd | |
parent | 42c493c16f0d8d88e081560cc6375a683807c5ea (diff) |
cifs: Use smb 2 - 3 and cifsacl mount options getacl functions
Fill in smb2/3 query acl functions in ops structures and use them.
Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
Signed-off-by: Steve French <smfrench@gmail.com>
-rw-r--r-- | fs/cifs/smb2ops.c | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 88fda3f5d105..f1d9c191c4e4 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c | |||
@@ -1288,6 +1288,107 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon, | |||
1288 | return rc; | 1288 | return rc; |
1289 | } | 1289 | } |
1290 | 1290 | ||
1291 | static struct cifs_ntsd * | ||
1292 | get_smb2_acl_by_fid(struct cifs_sb_info *cifs_sb, | ||
1293 | const struct cifs_fid *cifsfid, u32 *pacllen) | ||
1294 | { | ||
1295 | struct cifs_ntsd *pntsd = NULL; | ||
1296 | unsigned int xid; | ||
1297 | int rc = -EOPNOTSUPP; | ||
1298 | struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); | ||
1299 | |||
1300 | if (IS_ERR(tlink)) | ||
1301 | return ERR_CAST(tlink); | ||
1302 | |||
1303 | xid = get_xid(); | ||
1304 | cifs_dbg(FYI, "trying to get acl\n"); | ||
1305 | |||
1306 | rc = SMB2_query_acl(xid, tlink_tcon(tlink), cifsfid->persistent_fid, | ||
1307 | cifsfid->volatile_fid, (void **)&pntsd, pacllen); | ||
1308 | free_xid(xid); | ||
1309 | |||
1310 | cifs_put_tlink(tlink); | ||
1311 | |||
1312 | cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen); | ||
1313 | if (rc) | ||
1314 | return ERR_PTR(rc); | ||
1315 | return pntsd; | ||
1316 | |||
1317 | } | ||
1318 | |||
1319 | static struct cifs_ntsd * | ||
1320 | get_smb2_acl_by_path(struct cifs_sb_info *cifs_sb, | ||
1321 | const char *path, u32 *pacllen) | ||
1322 | { | ||
1323 | struct cifs_ntsd *pntsd = NULL; | ||
1324 | u8 oplock = SMB2_OPLOCK_LEVEL_NONE; | ||
1325 | unsigned int xid; | ||
1326 | int rc; | ||
1327 | struct cifs_tcon *tcon; | ||
1328 | struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); | ||
1329 | struct cifs_fid fid; | ||
1330 | struct cifs_open_parms oparms; | ||
1331 | __le16 *utf16_path; | ||
1332 | |||
1333 | cifs_dbg(FYI, "get smb3 acl for path %s\n", path); | ||
1334 | if (IS_ERR(tlink)) | ||
1335 | return ERR_CAST(tlink); | ||
1336 | |||
1337 | tcon = tlink_tcon(tlink); | ||
1338 | xid = get_xid(); | ||
1339 | |||
1340 | if (backup_cred(cifs_sb)) | ||
1341 | oparms.create_options |= CREATE_OPEN_BACKUP_INTENT; | ||
1342 | else | ||
1343 | oparms.create_options = 0; | ||
1344 | |||
1345 | utf16_path = cifs_convert_path_to_utf16(path, cifs_sb); | ||
1346 | if (!utf16_path) | ||
1347 | return ERR_PTR(-ENOMEM); | ||
1348 | |||
1349 | oparms.tcon = tcon; | ||
1350 | oparms.desired_access = READ_CONTROL; | ||
1351 | oparms.disposition = FILE_OPEN; | ||
1352 | oparms.fid = &fid; | ||
1353 | oparms.reconnect = false; | ||
1354 | |||
1355 | rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL); | ||
1356 | kfree(utf16_path); | ||
1357 | if (!rc) { | ||
1358 | rc = SMB2_query_acl(xid, tlink_tcon(tlink), fid.persistent_fid, | ||
1359 | fid.volatile_fid, (void **)&pntsd, pacllen); | ||
1360 | SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid); | ||
1361 | } | ||
1362 | |||
1363 | cifs_put_tlink(tlink); | ||
1364 | free_xid(xid); | ||
1365 | |||
1366 | cifs_dbg(FYI, "%s: rc = %d ACL len %d\n", __func__, rc, *pacllen); | ||
1367 | if (rc) | ||
1368 | return ERR_PTR(rc); | ||
1369 | return pntsd; | ||
1370 | } | ||
1371 | |||
1372 | /* Retrieve an ACL from the server */ | ||
1373 | static struct cifs_ntsd * | ||
1374 | get_smb2_acl(struct cifs_sb_info *cifs_sb, | ||
1375 | struct inode *inode, const char *path, | ||
1376 | u32 *pacllen) | ||
1377 | { | ||
1378 | struct cifs_ntsd *pntsd = NULL; | ||
1379 | struct cifsFileInfo *open_file = NULL; | ||
1380 | |||
1381 | if (inode) | ||
1382 | open_file = find_readable_file(CIFS_I(inode), true); | ||
1383 | if (!open_file) | ||
1384 | return get_smb2_acl_by_path(cifs_sb, path, pacllen); | ||
1385 | |||
1386 | pntsd = get_smb2_acl_by_fid(cifs_sb, &open_file->fid, pacllen); | ||
1387 | cifsFileInfo_put(open_file); | ||
1388 | return pntsd; | ||
1389 | } | ||
1390 | |||
1391 | |||
1291 | static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon, | 1392 | static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon, |
1292 | loff_t offset, loff_t len, bool keep_size) | 1393 | loff_t offset, loff_t len, bool keep_size) |
1293 | { | 1394 | { |
@@ -2393,6 +2494,11 @@ struct smb_version_operations smb20_operations = { | |||
2393 | .dir_needs_close = smb2_dir_needs_close, | 2494 | .dir_needs_close = smb2_dir_needs_close, |
2394 | .get_dfs_refer = smb2_get_dfs_refer, | 2495 | .get_dfs_refer = smb2_get_dfs_refer, |
2395 | .select_sectype = smb2_select_sectype, | 2496 | .select_sectype = smb2_select_sectype, |
2497 | #ifdef CONFIG_CIFS_ACL | ||
2498 | .get_acl = get_smb2_acl, | ||
2499 | .get_acl_by_fid = get_smb2_acl_by_fid, | ||
2500 | /* .set_acl = set_smb3_acl, */ | ||
2501 | #endif /* CIFS_ACL */ | ||
2396 | }; | 2502 | }; |
2397 | 2503 | ||
2398 | struct smb_version_operations smb21_operations = { | 2504 | struct smb_version_operations smb21_operations = { |
@@ -2477,6 +2583,11 @@ struct smb_version_operations smb21_operations = { | |||
2477 | .enum_snapshots = smb3_enum_snapshots, | 2583 | .enum_snapshots = smb3_enum_snapshots, |
2478 | .get_dfs_refer = smb2_get_dfs_refer, | 2584 | .get_dfs_refer = smb2_get_dfs_refer, |
2479 | .select_sectype = smb2_select_sectype, | 2585 | .select_sectype = smb2_select_sectype, |
2586 | #ifdef CONFIG_CIFS_ACL | ||
2587 | .get_acl = get_smb2_acl, | ||
2588 | .get_acl_by_fid = get_smb2_acl_by_fid, | ||
2589 | /* .set_acl = set_smb3_acl, */ | ||
2590 | #endif /* CIFS_ACL */ | ||
2480 | }; | 2591 | }; |
2481 | 2592 | ||
2482 | struct smb_version_operations smb30_operations = { | 2593 | struct smb_version_operations smb30_operations = { |
@@ -2571,6 +2682,11 @@ struct smb_version_operations smb30_operations = { | |||
2571 | .receive_transform = smb3_receive_transform, | 2682 | .receive_transform = smb3_receive_transform, |
2572 | .get_dfs_refer = smb2_get_dfs_refer, | 2683 | .get_dfs_refer = smb2_get_dfs_refer, |
2573 | .select_sectype = smb2_select_sectype, | 2684 | .select_sectype = smb2_select_sectype, |
2685 | #ifdef CONFIG_CIFS_ACL | ||
2686 | .get_acl = get_smb2_acl, | ||
2687 | .get_acl_by_fid = get_smb2_acl_by_fid, | ||
2688 | /* .set_acl = set_smb3_acl, */ | ||
2689 | #endif /* CIFS_ACL */ | ||
2574 | }; | 2690 | }; |
2575 | 2691 | ||
2576 | #ifdef CONFIG_CIFS_SMB311 | 2692 | #ifdef CONFIG_CIFS_SMB311 |