Skip to content

Commit

Permalink
[CIFS] Support for CIFS ACLs (part 1)
Browse files Browse the repository at this point in the history
Add code to be able to dump CIFS ACL information
when Query Posix ACL with cifsacl mount parm enabled.

Signed-off-by: Shirish Pargoankar <shirishp@us.ibm.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
  • Loading branch information
Steve French committed Sep 24, 2007
1 parent 2224f4e commit 442aa31
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 8 deletions.
34 changes: 32 additions & 2 deletions fs/cifs/cifsacl.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,42 @@
#ifndef _CIFSACL_H
#define _CIFSACL_H

struct cifs_ntsd {
__u16 revision; /* revision level */
__u16 type;
__u32 osidoffset;
__u32 gsidoffset;
__u32 sacloffset;
__u32 dacloffset;
} __attribute__((packed));

struct cifs_sid {
__u8 revision; /* revision level */
__u8 num_subauths;
__u8 num_auth;
__u8 authority[6];
__u32 sub_auth[4];
__u32 rid;
} __attribute__((packed));

struct cifs_acl {
__u16 revision; /* revision level */
__u16 size;
__u32 num_aces;
} __attribute__((packed));

struct cifs_ntace {
__u8 type;
__u8 flags;
__u16 size;
__u32 access_req;
} __attribute__((packed));

struct cifs_ace {
__u8 revision; /* revision level */
__u8 num_auth;
__u8 authority[6];
__u32 sub_auth[4];
/* next sub_auth if any ... */
__u32 rid;
} __attribute__((packed));

/* everyone */
Expand Down
12 changes: 12 additions & 0 deletions fs/cifs/cifsglob.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <linux/in.h>
#include <linux/in6.h>
#include "cifs_fs_sb.h"
#include "cifsacl.h"
/*
* The sizes of various internal tables and strings
*/
Expand Down Expand Up @@ -115,6 +116,17 @@ struct mac_key {
} data;
};

struct cifs_cred {
int uid;
int gid;
int mode;
int cecount;
struct cifs_sid osid;
struct cifs_sid gsid;
struct cifs_ntace *ntaces;
struct cifs_ace *aces;
};

/*
*****************************************************************
* Except the CIFS PDUs themselves all the
Expand Down
101 changes: 97 additions & 4 deletions fs/cifs/cifssmb.c
Original file line number Diff line number Diff line change
Expand Up @@ -3048,17 +3048,110 @@ static const struct cifs_sid sid_everyone =
static const struct cifs_sid sid_user =
{1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}};

static void parse_sid(struct cifs_sid * psid, char * end_of_acl)
{
/* BB need to add parm so we can store the SID BB */

/* validate that we do not go past end of acl */
if (end_of_acl < (char *)psid + sizeof(struct cifs_sid)) {
cERROR(1, ("ACL to small to parse SID"));
return;
}
#ifdef CONFIG_CIFS_DEBUG2
cFYI(1, ("revision %d num_auth %d First subauth 0x%x",
psid->revision, psid->num_auth, psid->sub_auth[0]));

/* BB add length check to make sure that we do not have huge num auths
and therefore go off the end */
cFYI(1, ("RID 0x%x", le32_to_cpu(psid->sub_auth[psid->num_auth])));
#endif
return;
}

/* Convert CIFS ACL to POSIX form */
static int parse_sec_desc(struct cifs_sid *psec_desc, int acl_len)
static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len)
{
return 0;
int i;
int num_aces = 0;
int acl_size;
struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
struct cifs_acl *dacl_ptr; /* no need for SACL ptr */
struct cifs_ntace **ppntace;
struct cifs_ace **ppace;
char *acl_base;
char *end_of_acl = ((char *)pntsd) + acl_len;

owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
cpu_to_le32(pntsd->osidoffset));
group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
cpu_to_le32(pntsd->gsidoffset));
dacl_ptr = (struct cifs_acl *)((char *)pntsd +
cpu_to_le32(pntsd->dacloffset));
#ifdef CONFIG_CIFS_DEBUG2
cFYI(1,("revision %d type 0x%x ooffset 0x%x goffset 0x%x "
"sacloffset 0x%x dacloffset 0x%x", pntsd->revision, pntsd->type,
pntsd->osidoffset, pntsd->gsidoffset, pntsd->sacloffset,
pntsd->dacloffset));
#endif
parse_sid(owner_sid_ptr, end_of_acl);
parse_sid(group_sid_ptr, end_of_acl);

/* cifscred->uid = owner_sid_ptr->rid;
cifscred->gid = group_sid_ptr->rid;
memcpy((void *)(&(cifscred->osid)), (void *)owner_sid_ptr,
sizeof (struct cifs_sid));
memcpy((void *)(&(cifscred->gsid)), (void *)group_sid_ptr,
sizeof (struct cifs_sid)); */

num_aces = cpu_to_le32(dacl_ptr->num_aces);
cFYI(1, ("num aces %d", num_aces));
if (num_aces > 0) {
ppntace = kmalloc(num_aces * sizeof(struct cifs_ntace *),
GFP_KERNEL);
ppace = kmalloc(num_aces * sizeof(struct cifs_ace *),
GFP_KERNEL);

/* cifscred->cecount = dacl_ptr->num_aces;
cifscred->ntaces = kmalloc(num_aces *
sizeof(struct cifs_ntace *), GFP_KERNEL);
cifscred->aces = kmalloc(num_aces *
sizeof(struct cifs_ace *), GFP_KERNEL);*/

acl_base = (char *)dacl_ptr;
acl_size = sizeof(struct cifs_acl);

for (i = 0; i < num_aces; ++i) {
ppntace[i] = (struct cifs_ntace *)
(acl_base + acl_size);
ppace[i] = (struct cifs_ace *)
((char *)ppntace[i] +
sizeof(struct cifs_ntace));

/* memcpy((void *)(&(cifscred->ntaces[i])),
(void *)ntace_ptrptr[i],
sizeof(struct cifs_ntace));
memcpy((void *)(&(cifscred->aces[i])),
(void *)ace_ptrptr[i],
sizeof(struct cifs_ace)); */

acl_base = (char *)ppntace[i];
acl_size = cpu_to_le32(ppntace[i]->size);
#ifdef CONFIG_CIFS_DEBUG2
cFYI(1, ("ACE revision:%d", ppace[i]->revision));
}
#endif
kfree(ppace);
kfree(ppntace);
}

return (0);
}

/* Get Security Descriptor (by handle) from remote server for a file or dir */
int
CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
/* BB fix up return info */ char *acl_inf, const int buflen,
const int acl_type /* ACCESS/DEFAULT not sure implication */)
const int acl_type)
{
int rc = 0;
int buf_type = 0;
Expand Down Expand Up @@ -3088,7 +3181,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
if (rc) {
cFYI(1, ("Send error in QuerySecDesc = %d", rc));
} else { /* decode response */
struct cifs_sid *psec_desc;
struct cifs_ntsd *psec_desc;
__le32 * parm;
int parm_len;
int data_len;
Expand Down
4 changes: 2 additions & 2 deletions fs/cifs/connect.c
Original file line number Diff line number Diff line change
Expand Up @@ -1742,9 +1742,9 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
cFYI(1, ("very large write cap"));
#endif /* CIFS_DEBUG2 */
if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
if (vol_info == NULL)
if (vol_info == NULL) {
cFYI(1, ("resetting capabilities failed"));
else
} else
cERROR(1, ("Negotiating Unix capabilities "
"with the server failed. Consider "
"mounting with the Unix Extensions\n"
Expand Down

0 comments on commit 442aa31

Please sign in to comment.