aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2007-10-31 00:54:42 -0400
committerSteve French <sfrench@us.ibm.com>2007-10-31 00:54:42 -0400
commit953f868138dbf4300196780379476ab9f07f263a (patch)
treee0dfbaebe02e75094033425fc4274328c5928dd0
parente01b64001359034d04c695388870936ed3d1b56b (diff)
[CIFS] Don't request too much permission when reading an ACL
We were requesting GENERIC_READ but that fails when we do not have read permission on the file (even if we could read the ACL). Also move the dump access control entry code into debug ifdef. Signed-off-by: Steve French <sfrench@us.ibm.com>
-rw-r--r--fs/cifs/cifsacl.c32
-rw-r--r--fs/cifs/cifspdu.h17
-rw-r--r--fs/cifs/cifsproto.h2
-rw-r--r--fs/cifs/inode.c9
4 files changed, 48 insertions, 12 deletions
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index 629b96c21639..f1215df7fbee 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -162,7 +162,8 @@ static void access_flags_to_mode(__u32 ace_flags, umode_t *pmode,
162} 162}
163 163
164 164
165static void parse_ace(struct cifs_ace *pace, char *end_of_acl) 165#ifdef CONFIG_CIFS_DEBUG2
166static void dump_ace(struct cifs_ace *pace, char *end_of_acl)
166{ 167{
167 int num_subauth; 168 int num_subauth;
168 169
@@ -180,7 +181,6 @@ static void parse_ace(struct cifs_ace *pace, char *end_of_acl)
180 181
181 num_subauth = pace->sid.num_subauth; 182 num_subauth = pace->sid.num_subauth;
182 if (num_subauth) { 183 if (num_subauth) {
183#ifdef CONFIG_CIFS_DEBUG2
184 int i; 184 int i;
185 cFYI(1, ("ACE revision %d num_auth %d type %d flags %d size %d", 185 cFYI(1, ("ACE revision %d num_auth %d type %d flags %d size %d",
186 pace->sid.revision, pace->sid.num_subauth, pace->type, 186 pace->sid.revision, pace->sid.num_subauth, pace->type,
@@ -192,11 +192,11 @@ static void parse_ace(struct cifs_ace *pace, char *end_of_acl)
192 192
193 /* BB add length check to make sure that we do not have huge 193 /* BB add length check to make sure that we do not have huge
194 num auths and therefore go off the end */ 194 num auths and therefore go off the end */
195#endif
196 } 195 }
197 196
198 return; 197 return;
199} 198}
199#endif
200 200
201 201
202static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, 202static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
@@ -240,9 +240,9 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
240 240
241 for (i = 0; i < num_aces; ++i) { 241 for (i = 0; i < num_aces; ++i) {
242 ppace[i] = (struct cifs_ace *) (acl_base + acl_size); 242 ppace[i] = (struct cifs_ace *) (acl_base + acl_size);
243 243#ifdef CONFIG_CIFS_DEBUG2
244 parse_ace(ppace[i], end_of_acl); 244 dump_ace(ppace[i], end_of_acl);
245 245#endif
246 if (compare_sids(&(ppace[i]->sid), pownersid)) 246 if (compare_sids(&(ppace[i]->sid), pownersid))
247 access_flags_to_mode(ppace[i]->access_req, 247 access_flags_to_mode(ppace[i]->access_req,
248 &(inode->i_mode), S_IRWXU); 248 &(inode->i_mode), S_IRWXU);
@@ -385,7 +385,7 @@ void acl_to_uid_mode(struct inode *inode, const char *path)
385 int oplock = FALSE; 385 int oplock = FALSE;
386 /* open file */ 386 /* open file */
387 rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, 387 rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN,
388 GENERIC_READ, 0, &fid, &oplock, NULL, 388 READ_CONTROL, 0, &fid, &oplock, NULL,
389 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 389 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
390 CIFS_MOUNT_MAP_SPECIAL_CHR); 390 CIFS_MOUNT_MAP_SPECIAL_CHR);
391 if (rc != 0) { 391 if (rc != 0) {
@@ -409,4 +409,22 @@ void acl_to_uid_mode(struct inode *inode, const char *path)
409 FreeXid(xid); 409 FreeXid(xid);
410 return; 410 return;
411} 411}
412
413int mode_to_acl(struct inode *inode, const char *path)
414{
415 int rc = 0;
416 __u32 acllen = 0;
417 struct cifs_ntsd *pntsd = NULL;
418
419 cFYI(1, ("set ACL from mode for %s", path));
420
421 /* Get the security descriptor */
422
423 /* Add/Modify the three ACEs for owner, group, everyone */
424
425 /* Set the security descriptor */
426 kfree(pntsd);
427
428 return rc;
429}
412#endif /* CONFIG_CIFS_EXPERIMENTAL */ 430#endif /* CONFIG_CIFS_EXPERIMENTAL */
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
index c41ff74e9128..07464b6ac129 100644
--- a/fs/cifs/cifspdu.h
+++ b/fs/cifs/cifspdu.h
@@ -220,6 +220,23 @@
220 | FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES) 220 | FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES)
221#define FILE_EXEC_RIGHTS (FILE_EXECUTE) 221#define FILE_EXEC_RIGHTS (FILE_EXECUTE)
222 222
223#define SET_FILE_READ_RIGHTS (FILE_READ_DATA | FILE_READ_EA | FILE_WRITE_EA \
224 | FILE_READ_ATTRIBUTES \
225 | FILE_WRITE_ATTRIBUTES \
226 | DELETE | READ_CONTROL | WRITE_DAC \
227 | WRITE_OWNER | SYNCHRONIZE)
228#define SET_FILE_WRITE_RIGHTS (FILE_WRITE_DATA | FILE_APPEND_DATA \
229 | FILE_READ_EA | FILE_WRITE_EA \
230 | FILE_DELETE_CHILD | FILE_READ_ATTRIBUTES \
231 | FILE_WRITE_ATTRIBUTES \
232 | DELETE | READ_CONTROL | WRITE_DAC \
233 | WRITE_OWNER | SYNCHRONIZE)
234#define SET_FILE_EXEC_RIGHTS (FILE_READ_EA | FILE_WRITE_EA | FILE_EXECUTE \
235 | FILE_READ_ATTRIBUTES \
236 | FILE_WRITE_ATTRIBUTES \
237 | DELETE | READ_CONTROL | WRITE_DAC \
238 | WRITE_OWNER | SYNCHRONIZE)
239
223 240
224/* 241/*
225 * Invalid readdir handle 242 * Invalid readdir handle
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 88c02ac97c3f..1ffe25592b25 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -96,6 +96,8 @@ extern int cifs_get_inode_info_unix(struct inode **pinode,
96 const unsigned char *search_path, 96 const unsigned char *search_path,
97 struct super_block *sb, int xid); 97 struct super_block *sb, int xid);
98extern void acl_to_uid_mode(struct inode *inode, const char *search_path); 98extern void acl_to_uid_mode(struct inode *inode, const char *search_path);
99extern int mode_to_acl(struct inode *inode, const char *path);
100
99extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *, 101extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *,
100 const char *); 102 const char *);
101extern int cifs_umount(struct super_block *, struct cifs_sb_info *); 103extern int cifs_umount(struct super_block *, struct cifs_sb_info *);
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 9be0bbd20dfd..7d907e84e032 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -289,7 +289,7 @@ static int decode_sfu_inode(struct inode *inode, __u64 size,
289 289
290#define SFBITS_MASK (S_ISVTX | S_ISGID | S_ISUID) /* SETFILEBITS valid bits */ 290#define SFBITS_MASK (S_ISVTX | S_ISGID | S_ISUID) /* SETFILEBITS valid bits */
291 291
292static int get_sfu_uid_mode(struct inode *inode, 292static int get_sfu_mode(struct inode *inode,
293 const unsigned char *path, 293 const unsigned char *path,
294 struct cifs_sb_info *cifs_sb, int xid) 294 struct cifs_sb_info *cifs_sb, int xid)
295{ 295{
@@ -528,16 +528,15 @@ int cifs_get_inode_info(struct inode **pinode,
528 /* BB fill in uid and gid here? with help from winbind? 528 /* BB fill in uid and gid here? with help from winbind?
529 or retrieve from NTFS stream extended attribute */ 529 or retrieve from NTFS stream extended attribute */
530#ifdef CONFIG_CIFS_EXPERIMENTAL 530#ifdef CONFIG_CIFS_EXPERIMENTAL
531 /* fill in 0777 bits from ACL */
531 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { 532 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
532 cFYI(1, ("Getting mode bits from ACL")); 533 cFYI(1, ("Getting mode bits from ACL"));
533 acl_to_uid_mode(inode, search_path); 534 acl_to_uid_mode(inode, search_path);
534 } 535 }
535#endif 536#endif
536 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { 537 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
537 /* fill in uid, gid, mode from server ACL */ 538 /* fill in remaining high mode bits e.g. SUID, VTX */
538 /* BB FIXME this should also take into account the 539 get_sfu_mode(inode, search_path, cifs_sb, xid);
539 * default uid specified on mount if present */
540 get_sfu_uid_mode(inode, search_path, cifs_sb, xid);
541 } else if (atomic_read(&cifsInfo->inUse) == 0) { 540 } else if (atomic_read(&cifsInfo->inUse) == 0) {
542 inode->i_uid = cifs_sb->mnt_uid; 541 inode->i_uid = cifs_sb->mnt_uid;
543 inode->i_gid = cifs_sb->mnt_gid; 542 inode->i_gid = cifs_sb->mnt_gid;