cifs: Use kuids and kgids SID to uid/gid mapping
Update id_mode_to_cifs_acl to take a kuid_t and a kgid_t. Replace NO_CHANGE_32 with INVALID_UID and INVALID_GID, and tests for NO_CHANGE_32 with uid_valid and gid_valid. Carefully unpack the value returned from request_key. memcpy the value into the expected type. The convert the uid/gid into a kuid/kgid. And then only if the result is a valid kuid or kgid update fuid/fgid. Cc: Steve French <smfrench@gmail.com> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
This commit is contained in:
parent
8e3028b908
commit
8abf2775dd
|
@ -266,8 +266,8 @@ sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
|
||||||
struct key *sidkey;
|
struct key *sidkey;
|
||||||
char *sidstr;
|
char *sidstr;
|
||||||
const struct cred *saved_cred;
|
const struct cred *saved_cred;
|
||||||
uid_t fuid = cifs_sb->mnt_uid;
|
kuid_t fuid = cifs_sb->mnt_uid;
|
||||||
gid_t fgid = cifs_sb->mnt_gid;
|
kgid_t fgid = cifs_sb->mnt_gid;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we have too many subauthorities, then something is really wrong.
|
* If we have too many subauthorities, then something is really wrong.
|
||||||
|
@ -306,10 +306,21 @@ sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
|
||||||
goto out_key_put;
|
goto out_key_put;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sidtype == SIDOWNER)
|
if (sidtype == SIDOWNER) {
|
||||||
memcpy(&fuid, &sidkey->payload.value, sizeof(uid_t));
|
kuid_t uid;
|
||||||
else
|
uid_t id;
|
||||||
memcpy(&fgid, &sidkey->payload.value, sizeof(gid_t));
|
memcpy(&id, &sidkey->payload.value, sizeof(uid_t));
|
||||||
|
uid = make_kuid(&init_user_ns, id);
|
||||||
|
if (uid_valid(uid))
|
||||||
|
fuid = uid;
|
||||||
|
} else {
|
||||||
|
kgid_t gid;
|
||||||
|
gid_t id;
|
||||||
|
memcpy(&id, &sidkey->payload.value, sizeof(gid_t));
|
||||||
|
gid = make_kgid(&init_user_ns, id);
|
||||||
|
if (gid_valid(gid))
|
||||||
|
fgid = gid;
|
||||||
|
}
|
||||||
|
|
||||||
out_key_put:
|
out_key_put:
|
||||||
key_put(sidkey);
|
key_put(sidkey);
|
||||||
|
@ -776,7 +787,7 @@ static int parse_sec_desc(struct cifs_sb_info *cifs_sb,
|
||||||
|
|
||||||
/* Convert permission bits from mode to equivalent CIFS ACL */
|
/* Convert permission bits from mode to equivalent CIFS ACL */
|
||||||
static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
|
static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
|
||||||
__u32 secdesclen, __u64 nmode, uid_t uid, gid_t gid, int *aclflag)
|
__u32 secdesclen, __u64 nmode, kuid_t uid, kgid_t gid, int *aclflag)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
__u32 dacloffset;
|
__u32 dacloffset;
|
||||||
|
@ -808,17 +819,19 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
|
||||||
*aclflag = CIFS_ACL_DACL;
|
*aclflag = CIFS_ACL_DACL;
|
||||||
} else {
|
} else {
|
||||||
memcpy(pnntsd, pntsd, secdesclen);
|
memcpy(pnntsd, pntsd, secdesclen);
|
||||||
if (uid != NO_CHANGE_32) { /* chown */
|
if (uid_valid(uid)) { /* chown */
|
||||||
|
uid_t id;
|
||||||
owner_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
|
owner_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
|
||||||
le32_to_cpu(pnntsd->osidoffset));
|
le32_to_cpu(pnntsd->osidoffset));
|
||||||
nowner_sid_ptr = kmalloc(sizeof(struct cifs_sid),
|
nowner_sid_ptr = kmalloc(sizeof(struct cifs_sid),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!nowner_sid_ptr)
|
if (!nowner_sid_ptr)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
rc = id_to_sid(uid, SIDOWNER, nowner_sid_ptr);
|
id = from_kuid(&init_user_ns, uid);
|
||||||
|
rc = id_to_sid(id, SIDOWNER, nowner_sid_ptr);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
cFYI(1, "%s: Mapping error %d for owner id %d",
|
cFYI(1, "%s: Mapping error %d for owner id %d",
|
||||||
__func__, rc, uid);
|
__func__, rc, id);
|
||||||
kfree(nowner_sid_ptr);
|
kfree(nowner_sid_ptr);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -826,17 +839,19 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
|
||||||
kfree(nowner_sid_ptr);
|
kfree(nowner_sid_ptr);
|
||||||
*aclflag = CIFS_ACL_OWNER;
|
*aclflag = CIFS_ACL_OWNER;
|
||||||
}
|
}
|
||||||
if (gid != NO_CHANGE_32) { /* chgrp */
|
if (gid_valid(gid)) { /* chgrp */
|
||||||
|
gid_t id;
|
||||||
group_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
|
group_sid_ptr = (struct cifs_sid *)((char *)pnntsd +
|
||||||
le32_to_cpu(pnntsd->gsidoffset));
|
le32_to_cpu(pnntsd->gsidoffset));
|
||||||
ngroup_sid_ptr = kmalloc(sizeof(struct cifs_sid),
|
ngroup_sid_ptr = kmalloc(sizeof(struct cifs_sid),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!ngroup_sid_ptr)
|
if (!ngroup_sid_ptr)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
rc = id_to_sid(gid, SIDGROUP, ngroup_sid_ptr);
|
id = from_kgid(&init_user_ns, gid);
|
||||||
|
rc = id_to_sid(id, SIDGROUP, ngroup_sid_ptr);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
cFYI(1, "%s: Mapping error %d for group id %d",
|
cFYI(1, "%s: Mapping error %d for group id %d",
|
||||||
__func__, rc, gid);
|
__func__, rc, id);
|
||||||
kfree(ngroup_sid_ptr);
|
kfree(ngroup_sid_ptr);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -1004,7 +1019,7 @@ cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr,
|
||||||
/* Convert mode bits to an ACL so we can update the ACL on the server */
|
/* Convert mode bits to an ACL so we can update the ACL on the server */
|
||||||
int
|
int
|
||||||
id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
|
id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode,
|
||||||
uid_t uid, gid_t gid)
|
kuid_t uid, kgid_t gid)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
int aclflag = CIFS_ACL_DACL; /* default flag to set */
|
int aclflag = CIFS_ACL_DACL; /* default flag to set */
|
||||||
|
|
|
@ -277,7 +277,6 @@
|
||||||
#define CIFS_NO_HANDLE 0xFFFF
|
#define CIFS_NO_HANDLE 0xFFFF
|
||||||
|
|
||||||
#define NO_CHANGE_64 0xFFFFFFFFFFFFFFFFULL
|
#define NO_CHANGE_64 0xFFFFFFFFFFFFFFFFULL
|
||||||
#define NO_CHANGE_32 0xFFFFFFFFUL
|
|
||||||
|
|
||||||
/* IPC$ in ASCII */
|
/* IPC$ in ASCII */
|
||||||
#define CIFS_IPC_RESOURCE "\x49\x50\x43\x24"
|
#define CIFS_IPC_RESOURCE "\x49\x50\x43\x24"
|
||||||
|
|
|
@ -161,7 +161,7 @@ extern int cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb,
|
||||||
struct cifs_fattr *fattr, struct inode *inode,
|
struct cifs_fattr *fattr, struct inode *inode,
|
||||||
const char *path, const __u16 *pfid);
|
const char *path, const __u16 *pfid);
|
||||||
extern int id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64,
|
extern int id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64,
|
||||||
uid_t, gid_t);
|
kuid_t, kgid_t);
|
||||||
extern struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *, struct inode *,
|
extern struct cifs_ntsd *get_cifs_acl(struct cifs_sb_info *, struct inode *,
|
||||||
const char *, u32 *);
|
const char *, u32 *);
|
||||||
extern int set_cifs_acl(struct cifs_ntsd *, __u32, struct inode *,
|
extern int set_cifs_acl(struct cifs_ntsd *, __u32, struct inode *,
|
||||||
|
|
|
@ -2090,8 +2090,8 @@ static int
|
||||||
cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
|
cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
|
||||||
{
|
{
|
||||||
unsigned int xid;
|
unsigned int xid;
|
||||||
uid_t uid = NO_CHANGE_32;
|
kuid_t uid = INVALID_UID;
|
||||||
gid_t gid = NO_CHANGE_32;
|
kgid_t gid = INVALID_GID;
|
||||||
struct inode *inode = direntry->d_inode;
|
struct inode *inode = direntry->d_inode;
|
||||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||||
struct cifsInodeInfo *cifsInode = CIFS_I(inode);
|
struct cifsInodeInfo *cifsInode = CIFS_I(inode);
|
||||||
|
@ -2150,7 +2150,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
|
||||||
|
|
||||||
#ifdef CONFIG_CIFS_ACL
|
#ifdef CONFIG_CIFS_ACL
|
||||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
|
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
|
||||||
if (uid != NO_CHANGE_32 || gid != NO_CHANGE_32) {
|
if (uid_valid(uid) || gid_valid(gid)) {
|
||||||
rc = id_mode_to_cifs_acl(inode, full_path, NO_CHANGE_64,
|
rc = id_mode_to_cifs_acl(inode, full_path, NO_CHANGE_64,
|
||||||
uid, gid);
|
uid, gid);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
|
@ -2174,7 +2174,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
|
||||||
#ifdef CONFIG_CIFS_ACL
|
#ifdef CONFIG_CIFS_ACL
|
||||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
|
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
|
||||||
rc = id_mode_to_cifs_acl(inode, full_path, mode,
|
rc = id_mode_to_cifs_acl(inode, full_path, mode,
|
||||||
NO_CHANGE_32, NO_CHANGE_32);
|
INVALID_UID, INVALID_GID);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
cFYI(1, "%s: Setting ACL failed with error: %d",
|
cFYI(1, "%s: Setting ACL failed with error: %d",
|
||||||
__func__, rc);
|
__func__, rc);
|
||||||
|
|
Loading…
Reference in New Issue