/*
* 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
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;
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));
/* 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;
/* 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;
- int unlock_file = FALSE;
+ struct cifsFileInfo *open_file = NULL;
+ bool unlock_file = false;
int xid;
int rc = -EIO;
__u16 fid;
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);
cifs_sb = CIFS_SB(sb);
if (open_file) {
- unlock_file = TRUE;
+ unlock_file = true;
fid = open_file->netfid;
- } else {
- int oplock = FALSE;
+ } else if (pfid == NULL) {
+ int oplock = 0;
/* open file */
rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN,
READ_CONTROL, 0, &fid, &oplock, NULL,
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;
struct inode *inode, const char *path)
{
struct cifsFileInfo *open_file;
- int unlock_file = FALSE;
+ bool unlock_file = false;
int xid;
int rc = -EIO;
__u16 fid;
open_file = find_readable_file(CIFS_I(inode));
if (open_file) {
- unlock_file = TRUE;
+ unlock_file = true;
fid = open_file->netfid;
} else {
- int oplock = FALSE;
+ int oplock = 0;
/* open file */
rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN,
WRITE_DAC, 0, &fid, &oplock, NULL,
rc = CIFSSMBSetCIFSACL(xid, cifs_sb->tcon, fid, pnntsd, acllen);
cFYI(DBG2, ("SetCIFSACL rc = %d", rc));
- if (unlock_file == TRUE)
+ if (unlock_file)
atomic_dec(&open_file->wrtPending);
else
CIFSSMBClose(xid, cifs_sb->tcon, fid);
}
/* 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;
cFYI(DBG2, ("converting ACL to mode for %s", path));
- pntsd = get_cifs_acl(&acllen, inode, path);
+ pntsd = get_cifs_acl(&acllen, inode, path, pfid);
/* if we can retrieve the ACL, now parse Access Control Entries, ACEs */
if (pntsd)
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 */
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 */
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);
cFYI(DBG2, ("build_sec_desc rc: %d", rc));
if (!rc) {
/* Set the security descriptor */
- rc = set_cifs_acl(pnntsd, acllen, inode, path);
+ rc = set_cifs_acl(pnntsd, secdesclen, inode, path);
cFYI(DBG2, ("set_cifs_acl rc: %d", rc));
}