-
Notifications
You must be signed in to change notification settings - Fork 63
Commit
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
Even though system user has a supplementary group, It gets NT_STATUS_ACCESS_DENIED when attempting to create file or directory. This patch add KSMBD_EVENT_LOGIN_REQUEST_EXT/RESPONSE_EXT netlink events to get supplementary groups list. The new netlink event doesn't break backward compatibility when using old ksmbd-tools. Co-authored-by: Atte Heikkilä <[email protected]> Signed-off-by: Namjae Jeon <[email protected]>
- Loading branch information
1 parent
51480c0
commit be97dff
Showing
7 changed files
with
141 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,7 @@ | |
struct ksmbd_user *ksmbd_login_user(const char *account) | ||
{ | ||
struct ksmbd_login_response *resp; | ||
struct ksmbd_login_response_ext *resp_ext = NULL; | ||
struct ksmbd_user *user = NULL; | ||
|
||
resp = ksmbd_ipc_login_request(account); | ||
|
@@ -21,15 +22,19 @@ struct ksmbd_user *ksmbd_login_user(const char *account) | |
if (!(resp->status & KSMBD_USER_FLAG_OK)) | ||
goto out; | ||
|
||
user = ksmbd_alloc_user(resp); | ||
if (resp->status & KSMBD_USER_FLAG_EXTENSION) | ||
resp_ext = ksmbd_ipc_login_request_ext(account); | ||
|
||
user = ksmbd_alloc_user(resp, resp_ext); | ||
out: | ||
kvfree(resp); | ||
return user; | ||
} | ||
|
||
struct ksmbd_user *ksmbd_alloc_user(struct ksmbd_login_response *resp) | ||
struct ksmbd_user *ksmbd_alloc_user(struct ksmbd_login_response *resp, | ||
struct ksmbd_login_response_ext *resp_ext) | ||
{ | ||
struct ksmbd_user *user = NULL; | ||
struct ksmbd_user *user; | ||
|
||
user = kmalloc(sizeof(struct ksmbd_user), GFP_KERNEL); | ||
if (!user) | ||
|
@@ -44,18 +49,40 @@ struct ksmbd_user *ksmbd_alloc_user(struct ksmbd_login_response *resp) | |
if (user->passkey) | ||
memcpy(user->passkey, resp->hash, resp->hash_sz); | ||
|
||
if (!user->name || !user->passkey) { | ||
kfree(user->name); | ||
kfree(user->passkey); | ||
kfree(user); | ||
user = NULL; | ||
user->ngroups = 0; | ||
user->sgid = NULL; | ||
|
||
if (!user->name || !user->passkey) | ||
goto err_free; | ||
|
||
if (resp_ext) { | ||
if (resp_ext->ngroups > NGROUPS_MAX) { | ||
pr_err("ngroups(%u) from login response exceeds max groups(%d)\n", | ||
resp_ext->ngroups, NGROUPS_MAX); | ||
goto err_free; | ||
} | ||
|
||
user->sgid = kmemdup(resp_ext->____payload, | ||
resp_ext->ngroups * sizeof(gid_t), | ||
This comment has been minimized.
Sorry, something went wrong.
atheik
Author
Contributor
|
||
GFP_KERNEL); | ||
if (user->sgid) | ||
This comment has been minimized.
Sorry, something went wrong.
atheik
Author
Contributor
|
||
user->ngroups = resp_ext->ngroups; | ||
ksmbd_debug(SMB, "supplementary groups : %d\n", user->ngroups); | ||
} | ||
|
||
return user; | ||
|
||
err_free: | ||
kfree(user->name); | ||
kfree(user->passkey); | ||
kfree(user); | ||
return NULL; | ||
} | ||
|
||
void ksmbd_free_user(struct ksmbd_user *user) | ||
{ | ||
ksmbd_ipc_logout_request(user->name, user->flags); | ||
kfree(user->sgid); | ||
kfree(user->name); | ||
kfree(user->passkey); | ||
kfree(user); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -120,6 +120,12 @@ static const struct nla_policy ksmbd_nl_policy[KSMBD_EVENT_MAX + 1] = { | |
}, | ||
[KSMBD_EVENT_SPNEGO_AUTHEN_RESPONSE] = { | ||
}, | ||
[KSMBD_EVENT_LOGIN_REQUEST_EXT] = { | ||
.len = sizeof(struct ksmbd_login_request), | ||
}, | ||
[KSMBD_EVENT_LOGIN_RESPONSE_EXT] = { | ||
.len = sizeof(struct ksmbd_login_response_ext), | ||
}, | ||
}; | ||
|
||
static struct genl_ops ksmbd_genl_ops[] = { | ||
|
@@ -187,6 +193,14 @@ static struct genl_ops ksmbd_genl_ops[] = { | |
.cmd = KSMBD_EVENT_SPNEGO_AUTHEN_RESPONSE, | ||
.doit = handle_generic_event, | ||
}, | ||
{ | ||
.cmd = KSMBD_EVENT_LOGIN_REQUEST_EXT, | ||
.doit = handle_unsupported_event, | ||
}, | ||
{ | ||
.cmd = KSMBD_EVENT_LOGIN_RESPONSE_EXT, | ||
.doit = handle_generic_event, | ||
}, | ||
}; | ||
|
||
static struct genl_family ksmbd_genl_family = { | ||
|
@@ -199,7 +213,7 @@ static struct genl_family ksmbd_genl_family = { | |
.ops = ksmbd_genl_ops, | ||
.n_ops = ARRAY_SIZE(ksmbd_genl_ops), | ||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0) | ||
.resv_start_op = KSMBD_EVENT_SPNEGO_AUTHEN_RESPONSE + 1, | ||
.resv_start_op = KSMBD_EVENT_LOGIN_RESPONSE_EXT + 1, | ||
#endif | ||
}; | ||
|
||
|
@@ -461,16 +475,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) { | ||
|
@@ -480,6 +502,17 @@ static int ipc_validate_msg(struct ipc_msg_table_entry *entry) | |
msg_sz = sizeof(struct ksmbd_share_config_response) + | ||
resp->payload_sz; | ||
} | ||
break; | ||
} | ||
case KSMBD_EVENT_LOGIN_REQUEST_EXT: | ||
{ | ||
struct ksmbd_login_response_ext *resp = entry->response; | ||
|
||
if (resp->ngroups) { | ||
msg_sz = sizeof(struct ksmbd_login_response_ext) + | ||
resp->ngroups * sizeof(gid_t); | ||
This comment has been minimized.
Sorry, something went wrong.
atheik
Author
Contributor
|
||
} | ||
} | ||
} | ||
|
||
return entry->msg_sz != msg_sz ? -EINVAL : 0; | ||
|
@@ -561,6 +594,29 @@ struct ksmbd_login_response *ksmbd_ipc_login_request(const char *account) | |
return resp; | ||
} | ||
|
||
struct ksmbd_login_response_ext *ksmbd_ipc_login_request_ext(const char *account) | ||
{ | ||
struct ksmbd_ipc_msg *msg; | ||
struct ksmbd_login_request *req; | ||
struct ksmbd_login_response_ext *resp; | ||
|
||
if (strlen(account) >= KSMBD_REQ_MAX_ACCOUNT_NAME_SZ) | ||
return NULL; | ||
|
||
msg = ipc_msg_alloc(sizeof(struct ksmbd_login_request)); | ||
if (!msg) | ||
return NULL; | ||
|
||
msg->type = KSMBD_EVENT_LOGIN_REQUEST_EXT; | ||
req = (struct ksmbd_login_request *)msg->payload; | ||
req->handle = ksmbd_acquire_id(&ipc_ida); | ||
strscpy(req->account, account, KSMBD_REQ_MAX_ACCOUNT_NAME_SZ); | ||
resp = ipc_msg_send_request(msg, req->handle); | ||
ipc_msg_handle_free(req->handle); | ||
ipc_msg_free(msg); | ||
return resp; | ||
} | ||
|
||
struct ksmbd_spnego_authen_response * | ||
ksmbd_ipc_spnego_authen_request(const char *spnego_blob, int blob_len) | ||
{ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct ksmbd_login_response_ext *resp_ext
should be initialized toNULL
.