diff options
Diffstat (limited to 'fs/cifs/cifsacl.c')
-rw-r--r-- | fs/cifs/cifsacl.c | 61 |
1 files changed, 48 insertions, 13 deletions
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index 8f9b4f710d4a..7ff866dbb89e 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c | |||
@@ -865,8 +865,8 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, | |||
865 | return rc; | 865 | return rc; |
866 | } | 866 | } |
867 | 867 | ||
868 | static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb, | 868 | struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb, |
869 | __u16 fid, u32 *pacllen) | 869 | const struct cifs_fid *cifsfid, u32 *pacllen) |
870 | { | 870 | { |
871 | struct cifs_ntsd *pntsd = NULL; | 871 | struct cifs_ntsd *pntsd = NULL; |
872 | unsigned int xid; | 872 | unsigned int xid; |
@@ -877,7 +877,8 @@ static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb, | |||
877 | return ERR_CAST(tlink); | 877 | return ERR_CAST(tlink); |
878 | 878 | ||
879 | xid = get_xid(); | 879 | xid = get_xid(); |
880 | rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), fid, &pntsd, pacllen); | 880 | rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), cifsfid->netfid, &pntsd, |
881 | pacllen); | ||
881 | free_xid(xid); | 882 | free_xid(xid); |
882 | 883 | ||
883 | cifs_put_tlink(tlink); | 884 | cifs_put_tlink(tlink); |
@@ -946,7 +947,7 @@ struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb, | |||
946 | if (!open_file) | 947 | if (!open_file) |
947 | return get_cifs_acl_by_path(cifs_sb, path, pacllen); | 948 | return get_cifs_acl_by_path(cifs_sb, path, pacllen); |
948 | 949 | ||
949 | pntsd = get_cifs_acl_by_fid(cifs_sb, open_file->fid.netfid, pacllen); | 950 | pntsd = get_cifs_acl_by_fid(cifs_sb, &open_file->fid, pacllen); |
950 | cifsFileInfo_put(open_file); | 951 | cifsFileInfo_put(open_file); |
951 | return pntsd; | 952 | return pntsd; |
952 | } | 953 | } |
@@ -1006,19 +1007,31 @@ out: | |||
1006 | /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */ | 1007 | /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */ |
1007 | int | 1008 | int |
1008 | cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr, | 1009 | cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr, |
1009 | struct inode *inode, const char *path, const __u16 *pfid) | 1010 | struct inode *inode, const char *path, |
1011 | const struct cifs_fid *pfid) | ||
1010 | { | 1012 | { |
1011 | struct cifs_ntsd *pntsd = NULL; | 1013 | struct cifs_ntsd *pntsd = NULL; |
1012 | u32 acllen = 0; | 1014 | u32 acllen = 0; |
1013 | int rc = 0; | 1015 | int rc = 0; |
1016 | struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); | ||
1017 | struct cifs_tcon *tcon; | ||
1014 | 1018 | ||
1015 | cifs_dbg(NOISY, "converting ACL to mode for %s\n", path); | 1019 | cifs_dbg(NOISY, "converting ACL to mode for %s\n", path); |
1016 | 1020 | ||
1017 | if (pfid) | 1021 | if (IS_ERR(tlink)) |
1018 | pntsd = get_cifs_acl_by_fid(cifs_sb, *pfid, &acllen); | 1022 | return PTR_ERR(tlink); |
1019 | else | 1023 | tcon = tlink_tcon(tlink); |
1020 | pntsd = get_cifs_acl(cifs_sb, inode, path, &acllen); | ||
1021 | 1024 | ||
1025 | if (pfid && (tcon->ses->server->ops->get_acl_by_fid)) | ||
1026 | pntsd = tcon->ses->server->ops->get_acl_by_fid(cifs_sb, pfid, | ||
1027 | &acllen); | ||
1028 | else if (tcon->ses->server->ops->get_acl) | ||
1029 | pntsd = tcon->ses->server->ops->get_acl(cifs_sb, inode, path, | ||
1030 | &acllen); | ||
1031 | else { | ||
1032 | cifs_put_tlink(tlink); | ||
1033 | return -EOPNOTSUPP; | ||
1034 | } | ||
1022 | /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */ | 1035 | /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */ |
1023 | if (IS_ERR(pntsd)) { | 1036 | if (IS_ERR(pntsd)) { |
1024 | rc = PTR_ERR(pntsd); | 1037 | rc = PTR_ERR(pntsd); |
@@ -1030,6 +1043,8 @@ cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr, | |||
1030 | cifs_dbg(VFS, "parse sec desc failed rc = %d\n", rc); | 1043 | cifs_dbg(VFS, "parse sec desc failed rc = %d\n", rc); |
1031 | } | 1044 | } |
1032 | 1045 | ||
1046 | cifs_put_tlink(tlink); | ||
1047 | |||
1033 | return rc; | 1048 | return rc; |
1034 | } | 1049 | } |
1035 | 1050 | ||
@@ -1043,15 +1058,30 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode, | |||
1043 | __u32 secdesclen = 0; | 1058 | __u32 secdesclen = 0; |
1044 | struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */ | 1059 | struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */ |
1045 | struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */ | 1060 | struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */ |
1061 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); | ||
1062 | struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); | ||
1063 | struct cifs_tcon *tcon; | ||
1064 | |||
1065 | if (IS_ERR(tlink)) | ||
1066 | return PTR_ERR(tlink); | ||
1067 | tcon = tlink_tcon(tlink); | ||
1046 | 1068 | ||
1047 | cifs_dbg(NOISY, "set ACL from mode for %s\n", path); | 1069 | cifs_dbg(NOISY, "set ACL from mode for %s\n", path); |
1048 | 1070 | ||
1049 | /* Get the security descriptor */ | 1071 | /* Get the security descriptor */ |
1050 | pntsd = get_cifs_acl(CIFS_SB(inode->i_sb), inode, path, &secdesclen); | 1072 | |
1073 | if (tcon->ses->server->ops->get_acl == NULL) { | ||
1074 | cifs_put_tlink(tlink); | ||
1075 | return -EOPNOTSUPP; | ||
1076 | } | ||
1077 | |||
1078 | pntsd = tcon->ses->server->ops->get_acl(cifs_sb, inode, path, | ||
1079 | &secdesclen); | ||
1051 | if (IS_ERR(pntsd)) { | 1080 | if (IS_ERR(pntsd)) { |
1052 | rc = PTR_ERR(pntsd); | 1081 | rc = PTR_ERR(pntsd); |
1053 | cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc); | 1082 | cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc); |
1054 | goto out; | 1083 | cifs_put_tlink(tlink); |
1084 | return rc; | ||
1055 | } | 1085 | } |
1056 | 1086 | ||
1057 | /* | 1087 | /* |
@@ -1064,6 +1094,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode, | |||
1064 | pnntsd = kmalloc(secdesclen, GFP_KERNEL); | 1094 | pnntsd = kmalloc(secdesclen, GFP_KERNEL); |
1065 | if (!pnntsd) { | 1095 | if (!pnntsd) { |
1066 | kfree(pntsd); | 1096 | kfree(pntsd); |
1097 | cifs_put_tlink(tlink); | ||
1067 | return -ENOMEM; | 1098 | return -ENOMEM; |
1068 | } | 1099 | } |
1069 | 1100 | ||
@@ -1072,14 +1103,18 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode, | |||
1072 | 1103 | ||
1073 | cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc); | 1104 | cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc); |
1074 | 1105 | ||
1106 | if (tcon->ses->server->ops->set_acl == NULL) | ||
1107 | rc = -EOPNOTSUPP; | ||
1108 | |||
1075 | if (!rc) { | 1109 | if (!rc) { |
1076 | /* Set the security descriptor */ | 1110 | /* Set the security descriptor */ |
1077 | rc = set_cifs_acl(pnntsd, secdesclen, inode, path, aclflag); | 1111 | rc = tcon->ses->server->ops->set_acl(pnntsd, secdesclen, inode, |
1112 | path, aclflag); | ||
1078 | cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc); | 1113 | cifs_dbg(NOISY, "set_cifs_acl rc: %d\n", rc); |
1079 | } | 1114 | } |
1115 | cifs_put_tlink(tlink); | ||
1080 | 1116 | ||
1081 | kfree(pnntsd); | 1117 | kfree(pnntsd); |
1082 | kfree(pntsd); | 1118 | kfree(pntsd); |
1083 | out: | ||
1084 | return rc; | 1119 | return rc; |
1085 | } | 1120 | } |