X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=fs%2Fcifs%2Fcifsacl.c;h=e99d4faf5f022e5c3315dbd38b63e12e85ccf0e7;hb=53492b1de46a7576170e865062ffcfc93bb5650b;hp=a7035bd18e4e4282ed4fcef9c22132c94c9e7f09;hpb=97837582bc1e191d2792af74c1f3762ed01243b9;p=safe%2Fjmp%2Flinux-2.6 diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index a7035bd..e99d4fa 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c @@ -1,7 +1,7 @@ /* * fs/cifs/cifsacl.c * - * Copyright (C) International Business Machines Corp., 2007 + * Copyright (C) International Business Machines Corp., 2007,2008 * Author(s): Steve French (sfrench@us.ibm.com) * * Contains the routines for mapping CIFS/NTFS ACLs @@ -46,8 +46,7 @@ static struct cifs_wksid wksidarr[NUM_WK_SIDS] = { static const struct cifs_sid sid_everyone = { 1, 1, {0, 0, 0, 0, 0, 1}, {0} }; /* group users */ -static const struct cifs_sid sid_user = - {1, 2 , {0, 0, 0, 0, 0, 5}, {} }; +static const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {} }; int match_sid(struct cifs_sid *ctsid) @@ -195,9 +194,9 @@ static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode, /* For deny ACEs we change the mask so that subsequent allow access control entries do not turn on the bits we are denying */ if (type == ACCESS_DENIED) { - if (flags & GENERIC_ALL) { + if (flags & GENERIC_ALL) *pbits_to_set &= ~S_IRWXUGO; - } + if ((flags & GENERIC_WRITE) || ((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS)) *pbits_to_set &= ~S_IWUGO; @@ -216,9 +215,7 @@ static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode, if (flags & GENERIC_ALL) { *pmode |= (S_IRWXUGO & (*pbits_to_set)); -#ifdef CONFIG_CIFS_DEBUG2 - cFYI(1, ("all perms")); -#endif + cFYI(DBG2, ("all perms")); return; } if ((flags & GENERIC_WRITE) || @@ -231,9 +228,7 @@ static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode, ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS)) *pmode |= (S_IXUGO & (*pbits_to_set)); -#ifdef CONFIG_CIFS_DEBUG2 - cFYI(1, ("access flags 0x%x mode now 0x%x", flags, *pmode)); -#endif + cFYI(DBG2, ("access flags 0x%x mode now 0x%x", flags, *pmode)); return; } @@ -262,13 +257,11 @@ static void mode_to_access_flags(umode_t mode, umode_t bits_to_use, if (mode & S_IXUGO) *pace_flags |= SET_FILE_EXEC_RIGHTS; -#ifdef CONFIG_CIFS_DEBUG2 - cFYI(1, ("mode: 0x%x, access flags now 0x%x", mode, *pace_flags)); -#endif + cFYI(DBG2, ("mode: 0x%x, access flags now 0x%x", mode, *pace_flags)); return; } -static __le16 fill_ace_for_sid(struct cifs_ace *pntace, +static __u16 fill_ace_for_sid(struct cifs_ace *pntace, const struct cifs_sid *psid, __u64 nmode, umode_t bits) { int i; @@ -358,11 +351,9 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, return; } -#ifdef CONFIG_CIFS_DEBUG2 - cFYI(1, ("DACL revision %d size %d num aces %d", + cFYI(DBG2, ("DACL revision %d size %d num aces %d", le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size), le32_to_cpu(pdacl->num_aces))); -#endif /* reset rwx permissions for user/group/other. Also, if num_aces is 0 i.e. DACL has no ACEs, @@ -381,10 +372,6 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, ppace = kmalloc(num_aces * sizeof(struct cifs_ace *), GFP_KERNEL); -/* cifscred->cecount = pdacl->num_aces; - cifscred->aces = kmalloc(num_aces * - sizeof(struct cifs_ace *), GFP_KERNEL);*/ - for (i = 0; i < num_aces; ++i) { ppace[i] = (struct cifs_ace *) (acl_base + acl_size); #ifdef CONFIG_CIFS_DEBUG2 @@ -424,7 +411,7 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid, struct cifs_sid *pgrpsid, __u64 nmode) { - __le16 size = 0; + u16 size = 0; struct cifs_acl *pnndacl; pnndacl = (struct cifs_acl *)((char *)pndacl + sizeof(struct cifs_acl)); @@ -437,7 +424,7 @@ static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid, &sid_everyone, nmode, S_IRWXO); pndacl->size = cpu_to_le16(size + sizeof(struct cifs_acl)); - pndacl->num_aces = 3; + pndacl->num_aces = cpu_to_le32(3); return (0); } @@ -495,13 +482,11 @@ static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len, le32_to_cpu(pntsd->gsidoffset)); dacloffset = le32_to_cpu(pntsd->dacloffset); dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset); -#ifdef CONFIG_CIFS_DEBUG2 - cFYI(1, ("revision %d type 0x%x ooffset 0x%x goffset 0x%x " + cFYI(DBG2, ("revision %d type 0x%x ooffset 0x%x goffset 0x%x " "sacloffset 0x%x dacloffset 0x%x", pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset), le32_to_cpu(pntsd->gsidoffset), le32_to_cpu(pntsd->sacloffset), dacloffset)); -#endif /* cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */ rc = parse_sid(owner_sid_ptr, end_of_acl); if (rc) @@ -531,7 +516,7 @@ static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len, /* Convert permission bits from mode to equivalent CIFS ACL */ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, - int acl_len, struct inode *inode, __u64 nmode) + struct inode *inode, __u64 nmode) { int rc = 0; __u32 dacloffset; @@ -571,9 +556,9 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, /* Retrieve an ACL from the server */ static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode, - const char *path) + const char *path, const __u16 *pfid) { - struct cifsFileInfo *open_file; + struct cifsFileInfo *open_file = NULL; int unlock_file = FALSE; int xid; int rc = -EIO; @@ -588,7 +573,11 @@ static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode, return NULL; xid = GetXid(); - open_file = find_readable_file(CIFS_I(inode)); + if (pfid == NULL) + open_file = find_readable_file(CIFS_I(inode)); + else + fid = *pfid; + sb = inode->i_sb; if (sb == NULL) { FreeXid(xid); @@ -599,7 +588,7 @@ static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode, if (open_file) { unlock_file = TRUE; fid = open_file->netfid; - } else { + } else if (pfid == NULL) { int oplock = FALSE; /* open file */ rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, @@ -615,10 +604,11 @@ static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode, rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, &pntsd, pacllen); cFYI(1, ("GetCIFSACL rc = %d ACL len %d", rc, *pacllen)); - if (unlock_file == TRUE) + if (unlock_file == TRUE) /* find_readable_file increments ref count */ atomic_dec(&open_file->wrtPending); - else + else if (pfid == NULL) /* if opened above we have to close the handle */ CIFSSMBClose(xid, cifs_sb->tcon, fid); + /* else handle was passed in by caller */ FreeXid(xid); return pntsd; @@ -636,9 +626,7 @@ static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen, struct super_block *sb; struct cifs_sb_info *cifs_sb; -#ifdef CONFIG_CIFS_DEBUG2 - cFYI(1, ("set ACL for %s from mode 0x%x", path, inode->i_mode)); -#endif + cFYI(DBG2, ("set ACL for %s from mode 0x%x", path, inode->i_mode)); if (!inode) return (rc); @@ -669,9 +657,7 @@ static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen, } rc = CIFSSMBSetCIFSACL(xid, cifs_sb->tcon, fid, pnntsd, acllen); -#ifdef CONFIG_CIFS_DEBUG2 - cFYI(1, ("SetCIFSACL rc = %d", rc)); -#endif + cFYI(DBG2, ("SetCIFSACL rc = %d", rc)); if (unlock_file == TRUE) atomic_dec(&open_file->wrtPending); else @@ -683,16 +669,14 @@ static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen, } /* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */ -void acl_to_uid_mode(struct inode *inode, const char *path) +void acl_to_uid_mode(struct inode *inode, const char *path, const __u16 *pfid) { struct cifs_ntsd *pntsd = NULL; u32 acllen = 0; int rc = 0; -#ifdef CONFIG_CIFS_DEBUG2 - cFYI(1, ("converting ACL to mode for %s", path)); -#endif - pntsd = get_cifs_acl(&acllen, inode, path); + cFYI(DBG2, ("converting ACL to mode for %s", path)); + pntsd = get_cifs_acl(&acllen, inode, path, pfid); /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */ if (pntsd) @@ -708,16 +692,14 @@ void acl_to_uid_mode(struct inode *inode, const char *path) int mode_to_acl(struct inode *inode, const char *path, __u64 nmode) { int rc = 0; - __u32 acllen = 0; + __u32 secdesclen = 0; struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */ struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */ -#ifdef CONFIG_CIFS_DEBUG2 - cFYI(1, ("set ACL from mode for %s", path)); -#endif + cFYI(DBG2, ("set ACL from mode for %s", path)); /* Get the security descriptor */ - pntsd = get_cifs_acl(&acllen, inode, path); + pntsd = get_cifs_acl(&secdesclen, inode, path, NULL); /* Add three ACEs for owner, group, everyone getting rid of other ACEs as chmod disables ACEs and set the security descriptor */ @@ -727,25 +709,23 @@ int mode_to_acl(struct inode *inode, const char *path, __u64 nmode) set security descriptor request security descriptor parameters, and secuirty descriptor itself */ - pnntsd = kmalloc(acllen, GFP_KERNEL); + secdesclen = secdesclen < DEFSECDESCLEN ? + DEFSECDESCLEN : secdesclen; + pnntsd = kmalloc(secdesclen, GFP_KERNEL); if (!pnntsd) { cERROR(1, ("Unable to allocate security descriptor")); kfree(pntsd); return (-ENOMEM); } - rc = build_sec_desc(pntsd, pnntsd, acllen, inode, nmode); + rc = build_sec_desc(pntsd, pnntsd, inode, nmode); -#ifdef CONFIG_CIFS_DEBUG2 - cFYI(1, ("build_sec_desc rc: %d", rc)); -#endif + cFYI(DBG2, ("build_sec_desc rc: %d", rc)); if (!rc) { /* Set the security descriptor */ - rc = set_cifs_acl(pnntsd, acllen, inode, path); -#ifdef CONFIG_CIFS_DEBUG2 - cFYI(1, ("set_cifs_acl rc: %d", rc)); -#endif + rc = set_cifs_acl(pnntsd, secdesclen, inode, path); + cFYI(DBG2, ("set_cifs_acl rc: %d", rc)); } kfree(pnntsd);