diff options
Diffstat (limited to 'fs/cifs/cifsacl.c')
-rw-r--r-- | fs/cifs/cifsacl.c | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index f93932c21772..1f5a4289b848 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * fs/cifs/cifsacl.c | 2 | * fs/cifs/cifsacl.c |
3 | * | 3 | * |
4 | * Copyright (C) International Business Machines Corp., 2007 | 4 | * Copyright (C) International Business Machines Corp., 2007,2008 |
5 | * Author(s): Steve French (sfrench@us.ibm.com) | 5 | * Author(s): Steve French (sfrench@us.ibm.com) |
6 | * | 6 | * |
7 | * Contains the routines for mapping CIFS/NTFS ACLs | 7 | * Contains the routines for mapping CIFS/NTFS ACLs |
@@ -556,9 +556,9 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, | |||
556 | 556 | ||
557 | /* Retrieve an ACL from the server */ | 557 | /* Retrieve an ACL from the server */ |
558 | static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode, | 558 | static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode, |
559 | const char *path) | 559 | const char *path, const __u16 *pfid) |
560 | { | 560 | { |
561 | struct cifsFileInfo *open_file; | 561 | struct cifsFileInfo *open_file = NULL; |
562 | int unlock_file = FALSE; | 562 | int unlock_file = FALSE; |
563 | int xid; | 563 | int xid; |
564 | int rc = -EIO; | 564 | int rc = -EIO; |
@@ -573,7 +573,11 @@ static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode, | |||
573 | return NULL; | 573 | return NULL; |
574 | 574 | ||
575 | xid = GetXid(); | 575 | xid = GetXid(); |
576 | open_file = find_readable_file(CIFS_I(inode)); | 576 | if (pfid == NULL) |
577 | open_file = find_readable_file(CIFS_I(inode)); | ||
578 | else | ||
579 | fid = *pfid; | ||
580 | |||
577 | sb = inode->i_sb; | 581 | sb = inode->i_sb; |
578 | if (sb == NULL) { | 582 | if (sb == NULL) { |
579 | FreeXid(xid); | 583 | FreeXid(xid); |
@@ -584,7 +588,7 @@ static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode, | |||
584 | if (open_file) { | 588 | if (open_file) { |
585 | unlock_file = TRUE; | 589 | unlock_file = TRUE; |
586 | fid = open_file->netfid; | 590 | fid = open_file->netfid; |
587 | } else { | 591 | } else if (pfid == NULL) { |
588 | int oplock = FALSE; | 592 | int oplock = FALSE; |
589 | /* open file */ | 593 | /* open file */ |
590 | rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, | 594 | rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, |
@@ -600,10 +604,11 @@ static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode, | |||
600 | 604 | ||
601 | rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, &pntsd, pacllen); | 605 | rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, &pntsd, pacllen); |
602 | cFYI(1, ("GetCIFSACL rc = %d ACL len %d", rc, *pacllen)); | 606 | cFYI(1, ("GetCIFSACL rc = %d ACL len %d", rc, *pacllen)); |
603 | if (unlock_file == TRUE) | 607 | if (unlock_file == TRUE) /* find_readable_file increments ref count */ |
604 | atomic_dec(&open_file->wrtPending); | 608 | atomic_dec(&open_file->wrtPending); |
605 | else | 609 | else if (pfid == NULL) /* if opened above we have to close the handle */ |
606 | CIFSSMBClose(xid, cifs_sb->tcon, fid); | 610 | CIFSSMBClose(xid, cifs_sb->tcon, fid); |
611 | /* else handle was passed in by caller */ | ||
607 | 612 | ||
608 | FreeXid(xid); | 613 | FreeXid(xid); |
609 | return pntsd; | 614 | return pntsd; |
@@ -664,14 +669,14 @@ static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen, | |||
664 | } | 669 | } |
665 | 670 | ||
666 | /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */ | 671 | /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */ |
667 | void acl_to_uid_mode(struct inode *inode, const char *path) | 672 | void acl_to_uid_mode(struct inode *inode, const char *path, const __u16 *pfid) |
668 | { | 673 | { |
669 | struct cifs_ntsd *pntsd = NULL; | 674 | struct cifs_ntsd *pntsd = NULL; |
670 | u32 acllen = 0; | 675 | u32 acllen = 0; |
671 | int rc = 0; | 676 | int rc = 0; |
672 | 677 | ||
673 | cFYI(DBG2, ("converting ACL to mode for %s", path)); | 678 | cFYI(DBG2, ("converting ACL to mode for %s", path)); |
674 | pntsd = get_cifs_acl(&acllen, inode, path); | 679 | pntsd = get_cifs_acl(&acllen, inode, path, pfid); |
675 | 680 | ||
676 | /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */ | 681 | /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */ |
677 | if (pntsd) | 682 | if (pntsd) |
@@ -694,7 +699,7 @@ int mode_to_acl(struct inode *inode, const char *path, __u64 nmode) | |||
694 | cFYI(DBG2, ("set ACL from mode for %s", path)); | 699 | cFYI(DBG2, ("set ACL from mode for %s", path)); |
695 | 700 | ||
696 | /* Get the security descriptor */ | 701 | /* Get the security descriptor */ |
697 | pntsd = get_cifs_acl(&acllen, inode, path); | 702 | pntsd = get_cifs_acl(&acllen, inode, path, NULL); |
698 | 703 | ||
699 | /* Add three ACEs for owner, group, everyone getting rid of | 704 | /* Add three ACEs for owner, group, everyone getting rid of |
700 | other ACEs as chmod disables ACEs and set the security descriptor */ | 705 | other ACEs as chmod disables ACEs and set the security descriptor */ |