/* Retrieve an ACL from the server */ static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode, const char *path, const __u16 *pfid) { struct cifsFileInfo *open_file = NULL; bool unlock_file = false; int xid; int rc = -EIO; __u16 fid; struct super_block *sb; struct cifs_sb_info *cifs_sb; struct cifs_ntsd *pntsd = NULL; cFYI(1, ("get mode from ACL for %s", path)); if (inode == NULL) return NULL; xid = GetXid(); if (pfid == NULL) open_file = find_readable_file(CIFS_I(inode)); else fid = *pfid; sb = inode->i_sb; if (sb == NULL) { FreeXid(xid); return NULL; } cifs_sb = CIFS_SB(sb); if (open_file) { unlock_file = true; fid = open_file->netfid; } else if (pfid == NULL) { int oplock = 0; /* open file */ rc = CIFSSMBOpen(xid, cifs_sb->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 != 0) { cERROR(1, ("Unable to open file to get ACL")); FreeXid(xid); return NULL; } } rc = CIFSSMBGetCIFSACL(xid, cifs_sb->tcon, fid, &pntsd, pacllen); cFYI(1, ("GetCIFSACL rc = %d ACL len %d", rc, *pacllen)); if (unlock_file == true) /* find_readable_file increments ref count */ atomic_dec(&open_file->wrtPending); 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; }
/* Set an ACL on the server */ static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen, struct inode *inode, const char *path) { struct cifsFileInfo *open_file; bool unlock_file = false; int xid; int rc = -EIO; __u16 fid; struct super_block *sb; struct cifs_sb_info *cifs_sb; cFYI(DBG2, ("set ACL for %s from mode 0x%x", path, inode->i_mode)); if (!inode) return rc; sb = inode->i_sb; if (sb == NULL) return rc; cifs_sb = CIFS_SB(sb); xid = GetXid(); open_file = find_readable_file(CIFS_I(inode)); if (open_file) { unlock_file = true; fid = open_file->netfid; } else { int oplock = 0; /* open file */ rc = CIFSSMBOpen(xid, cifs_sb->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 != 0) { cERROR(1, ("Unable to open file to set ACL")); FreeXid(xid); return rc; } } rc = CIFSSMBSetCIFSACL(xid, cifs_sb->tcon, fid, pnntsd, acllen); cFYI(DBG2, ("SetCIFSACL rc = %d", rc)); if (unlock_file) atomic_dec(&open_file->wrtPending); else CIFSSMBClose(xid, cifs_sb->tcon, fid); FreeXid(xid); return rc; }
/* Retrieve an ACL from the server */ static struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *cifs_sb, struct inode *inode, const char *path, u32 *pacllen) { struct cifs_ntsd *pntsd = NULL; struct cifsFileInfo *open_file = NULL; if (inode) open_file = find_readable_file(CIFS_I(inode)); if (!open_file) return get_cifs_acl_by_path(cifs_sb, path, pacllen); pntsd = get_cifs_acl_by_fid(cifs_sb, open_file->netfid, pacllen); cifsFileInfo_put(open_file); return pntsd; }
/* Set an ACL on the server */ static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen, struct inode *inode, const char *path) { struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); struct cifsFileInfo *open_file; int rc; cFYI(DBG2, "set ACL for %s from mode 0x%x", path, inode->i_mode); open_file = find_readable_file(CIFS_I(inode)); if (!open_file) return set_cifs_acl_by_path(cifs_sb, path, pnntsd, acllen); rc = set_cifs_acl_by_fid(cifs_sb, open_file->netfid, pnntsd, acllen); cifsFileInfo_put(open_file); return rc; }