diff options
-rw-r--r-- | fs/cifs/cifspdu.h | 1 | ||||
-rw-r--r-- | fs/cifs/cifssmb.c | 16 | ||||
-rw-r--r-- | fs/cifs/dir.c | 16 | ||||
-rw-r--r-- | fs/cifs/inode.c | 15 |
4 files changed, 31 insertions, 17 deletions
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index a0d26b540d4e..c43bf4b7a556 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h | |||
@@ -340,6 +340,7 @@ | |||
340 | #define OPEN_NO_RECALL 0x00400000 | 340 | #define OPEN_NO_RECALL 0x00400000 |
341 | #define OPEN_FREE_SPACE_QUERY 0x00800000 /* should be zero */ | 341 | #define OPEN_FREE_SPACE_QUERY 0x00800000 /* should be zero */ |
342 | #define CREATE_OPTIONS_MASK 0x007FFFFF | 342 | #define CREATE_OPTIONS_MASK 0x007FFFFF |
343 | #define CREATE_OPTION_READONLY 0x10000000 | ||
343 | #define CREATE_OPTION_SPECIAL 0x20000000 /* system. NB not sent over wire */ | 344 | #define CREATE_OPTION_SPECIAL 0x20000000 /* system. NB not sent over wire */ |
344 | 345 | ||
345 | /* ImpersonationLevel flags */ | 346 | /* ImpersonationLevel flags */ |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index cfd9750852b3..95fbba4ea7d4 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -1224,11 +1224,8 @@ OldOpenRetry: | |||
1224 | else /* BB FIXME BB */ | 1224 | else /* BB FIXME BB */ |
1225 | pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/); | 1225 | pSMB->FileAttributes = cpu_to_le16(0/*ATTR_NORMAL*/); |
1226 | 1226 | ||
1227 | /* if ((omode & S_IWUGO) == 0) | 1227 | if (create_options & CREATE_OPTION_READONLY) |
1228 | pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);*/ | 1228 | pSMB->FileAttributes |= cpu_to_le16(ATTR_READONLY); |
1229 | /* Above line causes problems due to vfs splitting create into two | ||
1230 | pieces - need to set mode after file created not while it is | ||
1231 | being created */ | ||
1232 | 1229 | ||
1233 | /* BB FIXME BB */ | 1230 | /* BB FIXME BB */ |
1234 | /* pSMB->CreateOptions = cpu_to_le32(create_options & | 1231 | /* pSMB->CreateOptions = cpu_to_le32(create_options & |
@@ -1331,17 +1328,16 @@ openRetry: | |||
1331 | pSMB->FileAttributes = cpu_to_le32(ATTR_SYSTEM); | 1328 | pSMB->FileAttributes = cpu_to_le32(ATTR_SYSTEM); |
1332 | else | 1329 | else |
1333 | pSMB->FileAttributes = cpu_to_le32(ATTR_NORMAL); | 1330 | pSMB->FileAttributes = cpu_to_le32(ATTR_NORMAL); |
1331 | |||
1334 | /* XP does not handle ATTR_POSIX_SEMANTICS */ | 1332 | /* XP does not handle ATTR_POSIX_SEMANTICS */ |
1335 | /* but it helps speed up case sensitive checks for other | 1333 | /* but it helps speed up case sensitive checks for other |
1336 | servers such as Samba */ | 1334 | servers such as Samba */ |
1337 | if (tcon->ses->capabilities & CAP_UNIX) | 1335 | if (tcon->ses->capabilities & CAP_UNIX) |
1338 | pSMB->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS); | 1336 | pSMB->FileAttributes |= cpu_to_le32(ATTR_POSIX_SEMANTICS); |
1339 | 1337 | ||
1340 | /* if ((omode & S_IWUGO) == 0) | 1338 | if (create_options & CREATE_OPTION_READONLY) |
1341 | pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY);*/ | 1339 | pSMB->FileAttributes |= cpu_to_le32(ATTR_READONLY); |
1342 | /* Above line causes problems due to vfs splitting create into two | 1340 | |
1343 | pieces - need to set mode after file created not while it is | ||
1344 | being created */ | ||
1345 | pSMB->ShareAccess = cpu_to_le32(FILE_SHARE_ALL); | 1341 | pSMB->ShareAccess = cpu_to_le32(FILE_SHARE_ALL); |
1346 | pSMB->CreateDisposition = cpu_to_le32(openDisposition); | 1342 | pSMB->CreateDisposition = cpu_to_le32(openDisposition); |
1347 | pSMB->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK); | 1343 | pSMB->CreateOptions = cpu_to_le32(create_options & CREATE_OPTIONS_MASK); |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 6ed775986be9..e4e0078a0526 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -119,6 +119,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
119 | { | 119 | { |
120 | int rc = -ENOENT; | 120 | int rc = -ENOENT; |
121 | int xid; | 121 | int xid; |
122 | int create_options = CREATE_NOT_DIR; | ||
122 | int oplock = 0; | 123 | int oplock = 0; |
123 | int desiredAccess = GENERIC_READ | GENERIC_WRITE; | 124 | int desiredAccess = GENERIC_READ | GENERIC_WRITE; |
124 | __u16 fileHandle; | 125 | __u16 fileHandle; |
@@ -176,9 +177,19 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
176 | FreeXid(xid); | 177 | FreeXid(xid); |
177 | return -ENOMEM; | 178 | return -ENOMEM; |
178 | } | 179 | } |
180 | |||
181 | mode &= ~current->fs->umask; | ||
182 | |||
183 | /* | ||
184 | * if we're not using unix extensions, see if we need to set | ||
185 | * ATTR_READONLY on the create call | ||
186 | */ | ||
187 | if (!pTcon->unix_ext && (mode & S_IWUGO) == 0) | ||
188 | create_options |= CREATE_OPTION_READONLY; | ||
189 | |||
179 | if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS) | 190 | if (cifs_sb->tcon->ses->capabilities & CAP_NT_SMBS) |
180 | rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, | 191 | rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, |
181 | desiredAccess, CREATE_NOT_DIR, | 192 | desiredAccess, create_options, |
182 | &fileHandle, &oplock, buf, cifs_sb->local_nls, | 193 | &fileHandle, &oplock, buf, cifs_sb->local_nls, |
183 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | 194 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
184 | else | 195 | else |
@@ -187,7 +198,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
187 | if (rc == -EIO) { | 198 | if (rc == -EIO) { |
188 | /* old server, retry the open legacy style */ | 199 | /* old server, retry the open legacy style */ |
189 | rc = SMBLegacyOpen(xid, pTcon, full_path, disposition, | 200 | rc = SMBLegacyOpen(xid, pTcon, full_path, disposition, |
190 | desiredAccess, CREATE_NOT_DIR, | 201 | desiredAccess, create_options, |
191 | &fileHandle, &oplock, buf, cifs_sb->local_nls, | 202 | &fileHandle, &oplock, buf, cifs_sb->local_nls, |
192 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | 203 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
193 | } | 204 | } |
@@ -197,7 +208,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
197 | /* If Open reported that we actually created a file | 208 | /* If Open reported that we actually created a file |
198 | then we now have to set the mode if possible */ | 209 | then we now have to set the mode if possible */ |
199 | if ((pTcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) { | 210 | if ((pTcon->unix_ext) && (oplock & CIFS_CREATE_ACTION)) { |
200 | mode &= ~current->fs->umask; | ||
201 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { | 211 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { |
202 | CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, | 212 | CIFSSMBUnixSetPerms(xid, pTcon, full_path, mode, |
203 | (__u64)current->fsuid, | 213 | (__u64)current->fsuid, |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index d904a037c833..fcbdbb6ad7bf 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -974,8 +974,8 @@ mkdir_get_info: | |||
974 | * failed to get it from the server or was set bogus */ | 974 | * failed to get it from the server or was set bogus */ |
975 | if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2)) | 975 | if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2)) |
976 | direntry->d_inode->i_nlink = 2; | 976 | direntry->d_inode->i_nlink = 2; |
977 | mode &= ~current->fs->umask; | ||
977 | if (pTcon->unix_ext) { | 978 | if (pTcon->unix_ext) { |
978 | mode &= ~current->fs->umask; | ||
979 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { | 979 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { |
980 | CIFSSMBUnixSetPerms(xid, pTcon, full_path, | 980 | CIFSSMBUnixSetPerms(xid, pTcon, full_path, |
981 | mode, | 981 | mode, |
@@ -994,9 +994,16 @@ mkdir_get_info: | |||
994 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 994 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
995 | } | 995 | } |
996 | } else { | 996 | } else { |
997 | /* BB to be implemented via Windows secrty descriptors | 997 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) && |
998 | eg CIFSSMBWinSetPerms(xid, pTcon, full_path, mode, | 998 | (mode & S_IWUGO) == 0) { |
999 | -1, -1, local_nls); */ | 999 | FILE_BASIC_INFO pInfo; |
1000 | memset(&pInfo, 0, sizeof(pInfo)); | ||
1001 | pInfo.Attributes = cpu_to_le32(ATTR_READONLY); | ||
1002 | CIFSSMBSetTimes(xid, pTcon, full_path, | ||
1003 | &pInfo, cifs_sb->local_nls, | ||
1004 | cifs_sb->mnt_cifs_flags & | ||
1005 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
1006 | } | ||
1000 | if (direntry->d_inode) { | 1007 | if (direntry->d_inode) { |
1001 | direntry->d_inode->i_mode = mode; | 1008 | direntry->d_inode->i_mode = mode; |
1002 | direntry->d_inode->i_mode |= S_IFDIR; | 1009 | direntry->d_inode->i_mode |= S_IFDIR; |