Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ksmbd: add support for supplementary groups
Browse files Browse the repository at this point in the history
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
namjaejeon committed Sep 25, 2024
1 parent fd01fc4 commit c69e41c
Showing 5 changed files with 48 additions and 6 deletions.
4 changes: 4 additions & 0 deletions ksmbd_netlink.h
Original file line number Diff line number Diff line change
@@ -131,6 +131,8 @@ struct ksmbd_login_request {
__u32 reserved[16]; /* Reserved room */
};

#define KSMBD_MAX_NGROUPS 128

This comment has been minimized.

Copy link
@atheik

atheik Sep 25, 2024

Contributor

Inconsistent name. Cf. KSMBD_MAX_GROUPS in ksmbd-tools.

This comment has been minimized.

Copy link
@namjaejeon

namjaejeon Sep 25, 2024

Author Owner

I will fix it.


/*
* IPC user login response.
*/
@@ -143,6 +145,8 @@ struct ksmbd_login_response {
__u16 hash_sz; /* hash size */
__s8 hash[KSMBD_REQ_MAX_HASH_SZ]; /* password hash */
__u32 reserved[16]; /* Reserved room */

This comment has been minimized.

Copy link
@atheik

atheik Sep 25, 2024

Contributor

Is there any way to retain compatibility with ksmbd-tools that does not have support for supplementary groups?

This comment has been minimized.

Copy link
@namjaejeon

namjaejeon Sep 26, 2024

Author Owner

Maybe, possible, I will check it also.

__u32 ngroups; /* supplementary group count */
__u32 sgid[KSMBD_MAX_NGROUPS]; /* supplementary group id */
};

/*
12 changes: 12 additions & 0 deletions mgmt/user_config.c
Original file line number Diff line number Diff line change
@@ -31,6 +31,12 @@ struct ksmbd_user *ksmbd_alloc_user(struct ksmbd_login_response *resp)
{
struct ksmbd_user *user = NULL;

if (resp->ngroups > KSMBD_MAX_NGROUPS) {
pr_err("ngroups(%u) from login response exceed NGROUPS_MAX\n",

This comment has been minimized.

Copy link
@atheik

atheik Sep 25, 2024

Contributor

Inconsistent name. Grepping NGROUPS_MAX is not very helpful compared to MAX_NGROUPS (or MAX_GROUPS in ksmbd-tools).

This comment has been minimized.

Copy link
@namjaejeon

namjaejeon Sep 25, 2024

Author Owner

Right. I will fix it.

resp->ngroups);
return NULL;
}

user = kmalloc(sizeof(struct ksmbd_user), GFP_KERNEL);
if (!user)
return NULL;
@@ -50,6 +56,12 @@ struct ksmbd_user *ksmbd_alloc_user(struct ksmbd_login_response *resp)
kfree(user);
user = NULL;
}

user->sgid = kmemdup(resp->sgid, resp->ngroups * sizeof(__u32),
GFP_KERNEL);
if (user->sgid)
user->ngroups = resp->ngroups;

return user;
}

2 changes: 2 additions & 0 deletions mgmt/user_config.h
Original file line number Diff line number Diff line change
@@ -18,6 +18,8 @@ struct ksmbd_user {

size_t passkey_sz;
char *passkey;
unsigned int ngroups;
unsigned int *sgid;
};

static inline bool user_guest(struct ksmbd_user *user)
21 changes: 18 additions & 3 deletions smb_common.c
Original file line number Diff line number Diff line change
@@ -781,13 +781,15 @@ int __ksmbd_override_fsids(struct ksmbd_work *work,
struct ksmbd_share_config *share)
{
struct ksmbd_session *sess = work->sess;
struct ksmbd_user *user = sess->user;
struct cred *cred;
struct group_info *gi;
unsigned int uid;
unsigned int gid;
int i;

uid = user_uid(sess->user);
gid = user_gid(sess->user);
uid = user_uid(user);
gid = user_gid(user);
if (share->force_uid != KSMBD_SHARE_INVALID_UID)
uid = share->force_uid;
if (share->force_gid != KSMBD_SHARE_INVALID_GID)
@@ -800,11 +802,24 @@ int __ksmbd_override_fsids(struct ksmbd_work *work,
cred->fsuid = make_kuid(&init_user_ns, uid);
cred->fsgid = make_kgid(&init_user_ns, gid);

gi = groups_alloc(0);
gi = groups_alloc(user->ngroups);
if (!gi) {
abort_creds(cred);
return -ENOMEM;
}

for (i = 0; i < user->ngroups; i++) {
if (gid_eq(GLOBAL_ROOT_GID,
make_kgid(&init_user_ns, user->sgid[i])))
gi->gid[i] = cred->fsgid;
else
gi->gid[i] = make_kgid(&init_user_ns,
user->sgid[i]);
}

if (user->ngroups)
groups_sort(gi);

set_groups(cred, gi);
put_group_info(gi);

15 changes: 12 additions & 3 deletions transport_ipc.c
Original file line number Diff line number Diff line change
@@ -461,16 +461,24 @@ static int ipc_validate_msg(struct ipc_msg_table_entry *entry)
{
unsigned int msg_sz = entry->msg_sz;

if (entry->type == KSMBD_EVENT_RPC_REQUEST) {
switch (entry->type) {
case KSMBD_EVENT_RPC_REQUEST:
{
struct ksmbd_rpc_command *resp = entry->response;

msg_sz = sizeof(struct ksmbd_rpc_command) + resp->payload_sz;
} else if (entry->type == KSMBD_EVENT_SPNEGO_AUTHEN_REQUEST) {
break;
}
case KSMBD_EVENT_SPNEGO_AUTHEN_REQUEST:
{
struct ksmbd_spnego_authen_response *resp = entry->response;

msg_sz = sizeof(struct ksmbd_spnego_authen_response) +
resp->session_key_len + resp->spnego_blob_len;
} else if (entry->type == KSMBD_EVENT_SHARE_CONFIG_REQUEST) {
break;
}
case KSMBD_EVENT_SHARE_CONFIG_REQUEST:
{
struct ksmbd_share_config_response *resp = entry->response;

if (resp->payload_sz) {
@@ -481,6 +489,7 @@ static int ipc_validate_msg(struct ipc_msg_table_entry *entry)
resp->payload_sz;
}
}
}

return entry->msg_sz != msg_sz ? -EINVAL : 0;
}

0 comments on commit c69e41c

Please sign in to comment.