diff options
author | Shirish Pargaonkar <shirishpargaonkar@gmail.com> | 2011-10-13 11:26:03 -0400 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2011-10-17 10:11:11 -0400 |
commit | a5ff376966c079bd2f078524eff11b0c63cc2507 (patch) | |
tree | f0a6576a0987ba73589caaadc2b4fde1b24650b5 /fs/cifs/inode.c | |
parent | d59dad2be038132259ac99a2837d65a87fd90588 (diff) |
cifs: Call id to SID mapping functions to change owner/group (try #4 repost)
Now build security descriptor to change either owner or group at the
server. Initially security descriptor was built to change only
(D)ACL, that functionality has been extended.
When either an Owner or a Group of a file object at the server is changed,
rest of security descriptor remains same (DACL etc.).
To set security descriptor, it is necessary to open that file
with permission bits of either WRITE_DAC if DACL is being modified or
WRITE_OWNER (Take Ownership) if Owner or Group is being changed.
It is the server that decides whether a set security descriptor with
either owner or group change succeeds or not.
Signed-off-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs/cifs/inode.c')
-rw-r--r-- | fs/cifs/inode.c | 35 |
1 files changed, 23 insertions, 12 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index a7b2dcd4a53e..663c4e313be4 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -2096,6 +2096,8 @@ static int | |||
2096 | cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) | 2096 | cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) |
2097 | { | 2097 | { |
2098 | int xid; | 2098 | int xid; |
2099 | uid_t uid = NO_CHANGE_32; | ||
2100 | gid_t gid = NO_CHANGE_32; | ||
2099 | struct inode *inode = direntry->d_inode; | 2101 | struct inode *inode = direntry->d_inode; |
2100 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); | 2102 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
2101 | struct cifsInodeInfo *cifsInode = CIFS_I(inode); | 2103 | struct cifsInodeInfo *cifsInode = CIFS_I(inode); |
@@ -2146,13 +2148,25 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) | |||
2146 | goto cifs_setattr_exit; | 2148 | goto cifs_setattr_exit; |
2147 | } | 2149 | } |
2148 | 2150 | ||
2149 | /* | 2151 | if (attrs->ia_valid & ATTR_UID) |
2150 | * Without unix extensions we can't send ownership changes to the | 2152 | uid = attrs->ia_uid; |
2151 | * server, so silently ignore them. This is consistent with how | 2153 | |
2152 | * local DOS/Windows filesystems behave (VFAT, NTFS, etc). With | 2154 | if (attrs->ia_valid & ATTR_GID) |
2153 | * CIFSACL support + proper Windows to Unix idmapping, we may be | 2155 | gid = attrs->ia_gid; |
2154 | * able to support this in the future. | 2156 | |
2155 | */ | 2157 | #ifdef CONFIG_CIFS_ACL |
2158 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { | ||
2159 | if (uid != NO_CHANGE_32 || gid != NO_CHANGE_32) { | ||
2160 | rc = id_mode_to_cifs_acl(inode, full_path, NO_CHANGE_64, | ||
2161 | uid, gid); | ||
2162 | if (rc) { | ||
2163 | cFYI(1, "%s: Setting id failed with error: %d", | ||
2164 | __func__, rc); | ||
2165 | goto cifs_setattr_exit; | ||
2166 | } | ||
2167 | } | ||
2168 | } else | ||
2169 | #endif /* CONFIG_CIFS_ACL */ | ||
2156 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)) | 2170 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)) |
2157 | attrs->ia_valid &= ~(ATTR_UID | ATTR_GID); | 2171 | attrs->ia_valid &= ~(ATTR_UID | ATTR_GID); |
2158 | 2172 | ||
@@ -2161,15 +2175,12 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) | |||
2161 | attrs->ia_valid &= ~ATTR_MODE; | 2175 | attrs->ia_valid &= ~ATTR_MODE; |
2162 | 2176 | ||
2163 | if (attrs->ia_valid & ATTR_MODE) { | 2177 | if (attrs->ia_valid & ATTR_MODE) { |
2164 | cFYI(1, "Mode changed to 0%o", attrs->ia_mode); | ||
2165 | mode = attrs->ia_mode; | 2178 | mode = attrs->ia_mode; |
2166 | } | ||
2167 | |||
2168 | if (attrs->ia_valid & ATTR_MODE) { | ||
2169 | rc = 0; | 2179 | rc = 0; |
2170 | #ifdef CONFIG_CIFS_ACL | 2180 | #ifdef CONFIG_CIFS_ACL |
2171 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { | 2181 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { |
2172 | rc = mode_to_cifs_acl(inode, full_path, mode); | 2182 | rc = id_mode_to_cifs_acl(inode, full_path, mode, |
2183 | NO_CHANGE_32, NO_CHANGE_32); | ||
2173 | if (rc) { | 2184 | if (rc) { |
2174 | cFYI(1, "%s: Setting ACL failed with error: %d", | 2185 | cFYI(1, "%s: Setting ACL failed with error: %d", |
2175 | __func__, rc); | 2186 | __func__, rc); |