diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index 629b96c2163..f1215df7fbe 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c @@ -162,7 +162,8 @@ static void access_flags_to_mode(__u32 ace_flags, umode_t *pmode, } -static void parse_ace(struct cifs_ace *pace, char *end_of_acl) +#ifdef CONFIG_CIFS_DEBUG2 +static void dump_ace(struct cifs_ace *pace, char *end_of_acl) { int num_subauth; @@ -180,7 +181,6 @@ static void parse_ace(struct cifs_ace *pace, char *end_of_acl) num_subauth = pace->sid.num_subauth; if (num_subauth) { -#ifdef CONFIG_CIFS_DEBUG2 int i; cFYI(1, ("ACE revision %d num_auth %d type %d flags %d size %d", pace->sid.revision, pace->sid.num_subauth, pace->type, @@ -192,11 +192,11 @@ static void parse_ace(struct cifs_ace *pace, char *end_of_acl) /* BB add length check to make sure that we do not have huge num auths and therefore go off the end */ -#endif } return; } +#endif static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, @@ -240,9 +240,9 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, for (i = 0; i < num_aces; ++i) { ppace[i] = (struct cifs_ace *) (acl_base + acl_size); - - parse_ace(ppace[i], end_of_acl); - +#ifdef CONFIG_CIFS_DEBUG2 + dump_ace(ppace[i], end_of_acl); +#endif if (compare_sids(&(ppace[i]->sid), pownersid)) access_flags_to_mode(ppace[i]->access_req, &(inode->i_mode), S_IRWXU); @@ -385,7 +385,7 @@ void acl_to_uid_mode(struct inode *inode, const char *path) int oplock = FALSE; /* open file */ rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, - GENERIC_READ, 0, &fid, &oplock, NULL, + READ_CONTROL, 0, &fid, &oplock, NULL, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); if (rc != 0) { @@ -409,4 +409,22 @@ void acl_to_uid_mode(struct inode *inode, const char *path) FreeXid(xid); return; } + +int mode_to_acl(struct inode *inode, const char *path) +{ + int rc = 0; + __u32 acllen = 0; + struct cifs_ntsd *pntsd = NULL; + + cFYI(1, ("set ACL from mode for %s", path)); + + /* Get the security descriptor */ + + /* Add/Modify the three ACEs for owner, group, everyone */ + + /* Set the security descriptor */ + kfree(pntsd); + + return rc; +} #endif /* CONFIG_CIFS_EXPERIMENTAL */ diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index c41ff74e912..07464b6ac12 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h @@ -220,6 +220,23 @@ | FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES) #define FILE_EXEC_RIGHTS (FILE_EXECUTE) +#define SET_FILE_READ_RIGHTS (FILE_READ_DATA | FILE_READ_EA | FILE_WRITE_EA \ + | FILE_READ_ATTRIBUTES \ + | FILE_WRITE_ATTRIBUTES \ + | DELETE | READ_CONTROL | WRITE_DAC \ + | WRITE_OWNER | SYNCHRONIZE) +#define SET_FILE_WRITE_RIGHTS (FILE_WRITE_DATA | FILE_APPEND_DATA \ + | FILE_READ_EA | FILE_WRITE_EA \ + | FILE_DELETE_CHILD | FILE_READ_ATTRIBUTES \ + | FILE_WRITE_ATTRIBUTES \ + | DELETE | READ_CONTROL | WRITE_DAC \ + | WRITE_OWNER | SYNCHRONIZE) +#define SET_FILE_EXEC_RIGHTS (FILE_READ_EA | FILE_WRITE_EA | FILE_EXECUTE \ + | FILE_READ_ATTRIBUTES \ + | FILE_WRITE_ATTRIBUTES \ + | DELETE | READ_CONTROL | WRITE_DAC \ + | WRITE_OWNER | SYNCHRONIZE) + /* * Invalid readdir handle diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 88c02ac97c3..1ffe25592b2 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -96,6 +96,8 @@ extern int cifs_get_inode_info_unix(struct inode **pinode, const unsigned char *search_path, struct super_block *sb, int xid); extern void acl_to_uid_mode(struct inode *inode, const char *search_path); +extern int mode_to_acl(struct inode *inode, const char *path); + extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *, const char *); extern int cifs_umount(struct super_block *, struct cifs_sb_info *); diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 9be0bbd20df..7d907e84e03 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -289,7 +289,7 @@ static int decode_sfu_inode(struct inode *inode, __u64 size, #define SFBITS_MASK (S_ISVTX | S_ISGID | S_ISUID) /* SETFILEBITS valid bits */ -static int get_sfu_uid_mode(struct inode *inode, +static int get_sfu_mode(struct inode *inode, const unsigned char *path, struct cifs_sb_info *cifs_sb, int xid) { @@ -528,16 +528,15 @@ int cifs_get_inode_info(struct inode **pinode, /* BB fill in uid and gid here? with help from winbind? or retrieve from NTFS stream extended attribute */ #ifdef CONFIG_CIFS_EXPERIMENTAL + /* fill in 0777 bits from ACL */ if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { cFYI(1, ("Getting mode bits from ACL")); acl_to_uid_mode(inode, search_path); } #endif if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { - /* fill in uid, gid, mode from server ACL */ - /* BB FIXME this should also take into account the - * default uid specified on mount if present */ - get_sfu_uid_mode(inode, search_path, cifs_sb, xid); + /* fill in remaining high mode bits e.g. SUID, VTX */ + get_sfu_mode(inode, search_path, cifs_sb, xid); } else if (atomic_read(&cifsInfo->inUse) == 0) { inode->i_uid = cifs_sb->mnt_uid; inode->i_gid = cifs_sb->mnt_gid;