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 | } |
