Commit 953f8681 authored by Steve French's avatar Steve French

[CIFS] Don't request too much permission when reading an ACL

We were requesting GENERIC_READ but that fails when  we do not have
read permission on the file (even if we could read the ACL).

Also move the dump access control entry code into debug ifdef.
Signed-off-by: default avatarSteve French <sfrench@us.ibm.com>
parent e01b6400
...@@ -162,7 +162,8 @@ static void access_flags_to_mode(__u32 ace_flags, umode_t *pmode, ...@@ -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; int num_subauth;
...@@ -180,7 +181,6 @@ static void parse_ace(struct cifs_ace *pace, char *end_of_acl) ...@@ -180,7 +181,6 @@ static void parse_ace(struct cifs_ace *pace, char *end_of_acl)
num_subauth = pace->sid.num_subauth; num_subauth = pace->sid.num_subauth;
if (num_subauth) { if (num_subauth) {
#ifdef CONFIG_CIFS_DEBUG2
int i; int i;
cFYI(1, ("ACE revision %d num_auth %d type %d flags %d size %d", cFYI(1, ("ACE revision %d num_auth %d type %d flags %d size %d",
pace->sid.revision, pace->sid.num_subauth, pace->type, 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) ...@@ -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 /* BB add length check to make sure that we do not have huge
num auths and therefore go off the end */ num auths and therefore go off the end */
#endif
} }
return; return;
} }
#endif
static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, 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, ...@@ -240,9 +240,9 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
for (i = 0; i < num_aces; ++i) { for (i = 0; i < num_aces; ++i) {
ppace[i] = (struct cifs_ace *) (acl_base + acl_size); ppace[i] = (struct cifs_ace *) (acl_base + acl_size);
#ifdef CONFIG_CIFS_DEBUG2
parse_ace(ppace[i], end_of_acl); dump_ace(ppace[i], end_of_acl);
#endif
if (compare_sids(&(ppace[i]->sid), pownersid)) if (compare_sids(&(ppace[i]->sid), pownersid))
access_flags_to_mode(ppace[i]->access_req, access_flags_to_mode(ppace[i]->access_req,
&(inode->i_mode), S_IRWXU); &(inode->i_mode), S_IRWXU);
...@@ -385,7 +385,7 @@ void acl_to_uid_mode(struct inode *inode, const char *path) ...@@ -385,7 +385,7 @@ void acl_to_uid_mode(struct inode *inode, const char *path)
int oplock = FALSE; int oplock = FALSE;
/* open file */ /* open file */
rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN, 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_sb->local_nls, cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR); CIFS_MOUNT_MAP_SPECIAL_CHR);
if (rc != 0) { if (rc != 0) {
...@@ -409,4 +409,22 @@ void acl_to_uid_mode(struct inode *inode, const char *path) ...@@ -409,4 +409,22 @@ void acl_to_uid_mode(struct inode *inode, const char *path)
FreeXid(xid); FreeXid(xid);
return; 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 */ #endif /* CONFIG_CIFS_EXPERIMENTAL */
...@@ -220,6 +220,23 @@ ...@@ -220,6 +220,23 @@
| FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES) | FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES)
#define FILE_EXEC_RIGHTS (FILE_EXECUTE) #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 * Invalid readdir handle
......
...@@ -96,6 +96,8 @@ extern int cifs_get_inode_info_unix(struct inode **pinode, ...@@ -96,6 +96,8 @@ extern int cifs_get_inode_info_unix(struct inode **pinode,
const unsigned char *search_path, const unsigned char *search_path,
struct super_block *sb, int xid); struct super_block *sb, int xid);
extern void acl_to_uid_mode(struct inode *inode, const char *search_path); 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 *, extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *,
const char *); const char *);
extern int cifs_umount(struct super_block *, struct cifs_sb_info *); extern int cifs_umount(struct super_block *, struct cifs_sb_info *);
......
...@@ -289,7 +289,7 @@ static int decode_sfu_inode(struct inode *inode, __u64 size, ...@@ -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 */ #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, const unsigned char *path,
struct cifs_sb_info *cifs_sb, int xid) struct cifs_sb_info *cifs_sb, int xid)
{ {
...@@ -528,16 +528,15 @@ int cifs_get_inode_info(struct inode **pinode, ...@@ -528,16 +528,15 @@ int cifs_get_inode_info(struct inode **pinode,
/* BB fill in uid and gid here? with help from winbind? /* BB fill in uid and gid here? with help from winbind?
or retrieve from NTFS stream extended attribute */ or retrieve from NTFS stream extended attribute */
#ifdef CONFIG_CIFS_EXPERIMENTAL #ifdef CONFIG_CIFS_EXPERIMENTAL
/* fill in 0777 bits from ACL */
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
cFYI(1, ("Getting mode bits from ACL")); cFYI(1, ("Getting mode bits from ACL"));
acl_to_uid_mode(inode, search_path); acl_to_uid_mode(inode, search_path);
} }
#endif #endif
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) { if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
/* fill in uid, gid, mode from server ACL */ /* fill in remaining high mode bits e.g. SUID, VTX */
/* BB FIXME this should also take into account the get_sfu_mode(inode, search_path, cifs_sb, xid);
* default uid specified on mount if present */
get_sfu_uid_mode(inode, search_path, cifs_sb, xid);
} else if (atomic_read(&cifsInfo->inUse) == 0) { } else if (atomic_read(&cifsInfo->inUse) == 0) {
inode->i_uid = cifs_sb->mnt_uid; inode->i_uid = cifs_sb->mnt_uid;
inode->i_gid = cifs_sb->mnt_gid; inode->i_gid = cifs_sb->mnt_gid;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment