]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - fs/cifs/cifsacl.c
Merge tag 'v2.6.37' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[mv-sheeva.git] / fs / cifs / cifsacl.c
index 85d7cf7ff2c8f263780433f54abd101a2ca3d831..a437ec391a015fb7c05725543d6c118eadefc466 100644 (file)
@@ -30,8 +30,6 @@
 #include "cifs_debug.h"
 
 
-#ifdef CONFIG_CIFS_EXPERIMENTAL
-
 static struct cifs_wksid wksidarr[NUM_WK_SIDS] = {
        {{1, 0, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0} }, "null user"},
        {{1, 1, {0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0} }, "nobody"},
@@ -557,13 +555,20 @@ static struct cifs_ntsd *get_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb,
 {
        struct cifs_ntsd *pntsd = NULL;
        int xid, rc;
+       struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
+
+       if (IS_ERR(tlink))
+               return ERR_CAST(tlink);
 
        xid = GetXid();
-       rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, &pntsd, pacllen);
+       rc = CIFSSMBGetCIFSACL(xid, tlink_tcon(tlink), fid, &pntsd, pacllen);
        FreeXid(xid);
 
+       cifs_put_tlink(tlink);
 
-       cFYI(1, "GetCIFSACL rc = %d ACL len %d", rc, *pacllen);
+       cFYI(1, "%s: rc = %d ACL len %d", __func__, rc, *pacllen);
+       if (rc)
+               return ERR_PTR(rc);
        return pntsd;
 }
 
@@ -574,28 +579,34 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
        int oplock = 0;
        int xid, rc;
        __u16 fid;
+       struct cifsTconInfo *tcon;
+       struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
+
+       if (IS_ERR(tlink))
+               return ERR_CAST(tlink);
 
+       tcon = tlink_tcon(tlink);
        xid = GetXid();
 
-       rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, READ_CONTROL, 0,
+       rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, READ_CONTROL, 0,
                         &fid, &oplock, NULL, cifs_sb->local_nls,
                         cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
-       if (rc) {
-               cERROR(1, "Unable to open file to get ACL");
-               goto out;
+       if (!rc) {
+               rc = CIFSSMBGetCIFSACL(xid, tcon, fid, &pntsd, pacllen);
+               CIFSSMBClose(xid, tcon, fid);
        }
 
-       rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, &pntsd, pacllen);
-       cFYI(1, "GetCIFSACL rc = %d ACL len %d", rc, *pacllen);
-
-       CIFSSMBClose(xid, cifs_sb->tcon, fid);
- out:
+       cifs_put_tlink(tlink);
        FreeXid(xid);
+
+       cFYI(1, "%s: rc = %d ACL len %d", __func__, rc, *pacllen);
+       if (rc)
+               return ERR_PTR(rc);
        return pntsd;
 }
 
 /* Retrieve an ACL from the server */
-static struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
+struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
                                      struct inode *inode, const char *path,
                                      u32 *pacllen)
 {
@@ -603,7 +614,7 @@ static struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb,
        struct cifsFileInfo *open_file = NULL;
 
        if (inode)
-               open_file = find_readable_file(CIFS_I(inode));
+               open_file = find_readable_file(CIFS_I(inode), true);
        if (!open_file)
                return get_cifs_acl_by_path(cifs_sb, path, pacllen);
 
@@ -616,10 +627,15 @@ static int set_cifs_acl_by_fid(struct cifs_sb_info *cifs_sb, __u16 fid,
                struct cifs_ntsd *pnntsd, u32 acllen)
 {
        int xid, rc;
+       struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
+
+       if (IS_ERR(tlink))
+               return PTR_ERR(tlink);
 
        xid = GetXid();
-       rc = CIFSSMBSetCIFSACL(xid, cifs_sb->tcon, fid, pnntsd, acllen);
+       rc = CIFSSMBSetCIFSACL(xid, tlink_tcon(tlink), fid, pnntsd, acllen);
        FreeXid(xid);
+       cifs_put_tlink(tlink);
 
        cFYI(DBG2, "SetCIFSACL rc = %d", rc);
        return rc;
@@ -631,10 +647,16 @@ static int set_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, const char *path,
        int oplock = 0;
        int xid, rc;
        __u16 fid;
+       struct cifsTconInfo *tcon;
+       struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
 
+       if (IS_ERR(tlink))
+               return PTR_ERR(tlink);
+
+       tcon = tlink_tcon(tlink);
        xid = GetXid();
 
-       rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, WRITE_DAC, 0,
+       rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, WRITE_DAC, 0,
                         &fid, &oplock, NULL, cifs_sb->local_nls,
                         cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
        if (rc) {
@@ -642,12 +664,13 @@ static int set_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, const char *path,
                goto out;
        }
 
-       rc = CIFSSMBSetCIFSACL(xid, cifs_sb->tcon, fid, pnntsd, acllen);
+       rc = CIFSSMBSetCIFSACL(xid, tcon, fid, pnntsd, acllen);
        cFYI(DBG2, "SetCIFSACL rc = %d", rc);
 
-       CIFSSMBClose(xid, cifs_sb->tcon, fid);
- out:
+       CIFSSMBClose(xid, tcon, fid);
+out:
        FreeXid(xid);
+       cifs_put_tlink(tlink);
        return rc;
 }
 
@@ -661,7 +684,7 @@ static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
 
        cFYI(DBG2, "set ACL for %s from mode 0x%x", path, inode->i_mode);
 
-       open_file = find_readable_file(CIFS_I(inode));
+       open_file = find_readable_file(CIFS_I(inode), true);
        if (!open_file)
                return set_cifs_acl_by_path(cifs_sb, path, pnntsd, acllen);
 
@@ -671,7 +694,7 @@ 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
+int
 cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
                  struct inode *inode, const char *path, const __u16 *pfid)
 {
@@ -687,17 +710,21 @@ cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
                pntsd = get_cifs_acl(cifs_sb, inode, path, &acllen);
 
        /* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
-       if (pntsd)
+       if (IS_ERR(pntsd)) {
+               rc = PTR_ERR(pntsd);
+               cERROR(1, "%s: error %d getting sec desc", __func__, rc);
+       } else {
                rc = parse_sec_desc(pntsd, acllen, fattr);
-       if (rc)
-               cFYI(1, "parse sec desc failed rc = %d", rc);
+               kfree(pntsd);
+               if (rc)
+                       cERROR(1, "parse sec desc failed rc = %d", rc);
+       }
 
-       kfree(pntsd);
-       return;
+       return rc;
 }
 
 /* Convert mode bits to an ACL so we can update the ACL on the server */
-int mode_to_acl(struct inode *inode, const char *path, __u64 nmode)
+int mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode)
 {
        int rc = 0;
        __u32 secdesclen = 0;
@@ -712,7 +739,10 @@ int mode_to_acl(struct inode *inode, const char *path, __u64 nmode)
        /* Add three ACEs for owner, group, everyone getting rid of
           other ACEs as chmod disables ACEs and set the security descriptor */
 
-       if (pntsd) {
+       if (IS_ERR(pntsd)) {
+               rc = PTR_ERR(pntsd);
+               cERROR(1, "%s: error %d getting sec desc", __func__, rc);
+       } else {
                /* allocate memory for the smb header,
                   set security descriptor request security descriptor
                   parameters, and secuirty descriptor itself */
@@ -742,4 +772,3 @@ int mode_to_acl(struct inode *inode, const char *path, __u64 nmode)
 
        return rc;
 }
-#endif /* CONFIG_CIFS_EXPERIMENTAL */