1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-08 21:18:16 +03:00

s3: smbd: Factor out code that calls getgroups_unix_user() into a separate function.

This code needs to special-case the guest user, as
this token can have the token_sid[0] set to the Guest
SID, not the mapping of UNIX uid -> SID.

Other users that may have a well-known SID
set in token_sid[0] (like SYSTEM) are usually
not mappable to UNIX users and can be ignored
when adding local groups from /etc/group.

Found by <linux@kukkukk.com>.

Second part of the bugfix for:

https://bugzilla.samba.org/show_bug.cgi?id=10508

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by:  Andrew Bartlett <abartlet@samba.org>
This commit is contained in:
Jeremy Allison 2014-03-22 21:23:48 -07:00
parent 547111b2cf
commit a9fa09723b

View File

@ -389,16 +389,53 @@ struct security_token *create_local_nt_token(TALLOC_CTX *mem_ctx,
return result; return result;
} }
static NTSTATUS finalize_local_nt_token(struct security_token *result, /***************************************************
Merge in any groups from /etc/group.
***************************************************/
static NTSTATUS add_local_groups(struct security_token *result,
bool is_guest) bool is_guest)
{ {
struct dom_sid dom_sid; gid_t *gids = NULL;
gid_t gid; uint32_t getgroups_num_group_sids = 0;
uid_t uid; struct passwd *pass = NULL;
NTSTATUS status; TALLOC_CTX *tmp_ctx = talloc_stackframe();
int i;
if (is_guest) {
/*
* Guest is a special case. It's always
* a user that can be looked up, but
* result->sids[0] is set to DOMAIN\Guest.
* Lookup by account name instead.
*/
pass = Get_Pwnam_alloc(tmp_ctx, lp_guest_account());
} else {
uid_t uid;
/* For non-guest result->sids[0] is always the user sid. */
if (!sid_to_uid(&result->sids[0], &uid)) {
/*
* Non-mappable SID like SYSTEM.
* Can't be in any /etc/group groups.
*/
TALLOC_FREE(tmp_ctx);
return NT_STATUS_OK;
}
pass = getpwuid_alloc(tmp_ctx, uid);
if (pass == NULL) {
DEBUG(1, ("SID %s -> getpwuid(%u) failed\n",
sid_string_dbg(&result->sids[0]),
(unsigned int)uid));
}
}
if (!pass) {
TALLOC_FREE(tmp_ctx);
return NT_STATUS_UNSUCCESSFUL;
}
/* result->sids[0] is always the user sid. */
if (sid_to_uid(&result->sids[0], &uid)) {
/* /*
* Now we must get any groups this user has been * Now we must get any groups this user has been
* added to in /etc/group and merge them in. * added to in /etc/group and merge them in.
@ -418,19 +455,6 @@ static NTSTATUS finalize_local_nt_token(struct security_token *result,
* do anything other than be inefficient * do anything other than be inefficient
* in that case. * in that case.
*/ */
struct passwd *pass = NULL;
gid_t *gids = NULL;
uint32_t getgroups_num_group_sids = 0;
int i;
TALLOC_CTX *tmp_ctx = talloc_stackframe();
pass = getpwuid_alloc(tmp_ctx, uid);
if (pass == NULL) {
DEBUG(1, ("getpwuid(%u) failed\n",
(unsigned int)uid));
TALLOC_FREE(tmp_ctx);
return NT_STATUS_UNSUCCESSFUL;
}
if (!getgroups_unix_user(tmp_ctx, pass->pw_name, pass->pw_gid, if (!getgroups_unix_user(tmp_ctx, pass->pw_name, pass->pw_gid,
&gids, &getgroups_num_group_sids)) { &gids, &getgroups_num_group_sids)) {
@ -441,6 +465,7 @@ static NTSTATUS finalize_local_nt_token(struct security_token *result,
} }
for (i=0; i<getgroups_num_group_sids; i++) { for (i=0; i<getgroups_num_group_sids; i++) {
NTSTATUS status;
struct dom_sid grp_sid; struct dom_sid grp_sid;
gid_to_sid(&grp_sid, gids[i]); gid_to_sid(&grp_sid, gids[i]);
@ -455,6 +480,21 @@ static NTSTATUS finalize_local_nt_token(struct security_token *result,
} }
} }
TALLOC_FREE(tmp_ctx); TALLOC_FREE(tmp_ctx);
return NT_STATUS_OK;
}
static NTSTATUS finalize_local_nt_token(struct security_token *result,
bool is_guest)
{
struct dom_sid dom_sid;
gid_t gid;
NTSTATUS status;
/* Add any local groups. */
status = add_local_groups(result, is_guest);
if (!NT_STATUS_IS_OK(status)) {
return status;
} }
/* Add in BUILTIN sids */ /* Add in BUILTIN sids */