summaryrefslogtreecommitdiffstats
path: root/source3/auth
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2014-03-22 21:23:48 -0700
committerJeremy Allison <jra@samba.org>2014-03-25 16:24:13 +0100
commita9fa09723bee3588db2168ac13f7ad0334452c11 (patch)
treeaf422643fb5063496159baf738ca1ef2a29ad118 /source3/auth
parent547111b2cf94d18ae7972308161d64b5504ee9fd (diff)
downloadsamba-a9fa09723bee3588db2168ac13f7ad0334452c11.tar.gz
samba-a9fa09723bee3588db2168ac13f7ad0334452c11.tar.xz
samba-a9fa09723bee3588db2168ac13f7ad0334452c11.zip
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>
Diffstat (limited to 'source3/auth')
-rw-r--r--source3/auth/token_util.c144
1 files changed, 92 insertions, 52 deletions
diff --git a/source3/auth/token_util.c b/source3/auth/token_util.c
index bccf1db499..82eaaff301 100644
--- a/source3/auth/token_util.c
+++ b/source3/auth/token_util.c
@@ -389,72 +389,112 @@ struct security_token *create_local_nt_token(TALLOC_CTX *mem_ctx,
return result;
}
-static NTSTATUS finalize_local_nt_token(struct security_token *result,
- bool is_guest)
+/***************************************************
+ Merge in any groups from /etc/group.
+***************************************************/
+
+static NTSTATUS add_local_groups(struct security_token *result,
+ bool is_guest)
{
- struct dom_sid dom_sid;
- gid_t gid;
- uid_t uid;
- NTSTATUS status;
+ gid_t *gids = NULL;
+ uint32_t getgroups_num_group_sids = 0;
+ struct passwd *pass = NULL;
+ TALLOC_CTX *tmp_ctx = talloc_stackframe();
+ int i;
- /* result->sids[0] is always the user sid. */
- if (sid_to_uid(&result->sids[0], &uid)) {
+ if (is_guest) {
/*
- * Now we must get any groups this user has been
- * added to in /etc/group and merge them in.
- * This has to be done in every code path
- * that creates an NT token, as remote users
- * may have been added to the local /etc/group
- * database. Tokens created merely from the
- * info3 structs (via the DC or via the krb5 PAC)
- * won't have these local groups. Note the
- * groups added here will only be UNIX groups
- * (S-1-22-2-XXXX groups) as getgroups_unix_user()
- * turns off winbindd before calling getgroups().
- *
- * NB. This is duplicating work already
- * done in the 'unix_user:' case of
- * create_token_from_sid() but won't
- * do anything other than be inefficient
- * in that case.
+ * 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.
*/
- struct passwd *pass = NULL;
- gid_t *gids = NULL;
- uint32_t getgroups_num_group_sids = 0;
- int i;
- TALLOC_CTX *tmp_ctx = talloc_stackframe();
+ 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, ("getpwuid(%u) failed\n",
+ DEBUG(1, ("SID %s -> getpwuid(%u) failed\n",
+ sid_string_dbg(&result->sids[0]),
(unsigned int)uid));
- TALLOC_FREE(tmp_ctx);
- return NT_STATUS_UNSUCCESSFUL;
}
+ }
- if (!getgroups_unix_user(tmp_ctx, pass->pw_name, pass->pw_gid,
- &gids, &getgroups_num_group_sids)) {
- DEBUG(1, ("getgroups_unix_user for user %s failed\n",
- pass->pw_name));
+ if (!pass) {
+ TALLOC_FREE(tmp_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /*
+ * Now we must get any groups this user has been
+ * added to in /etc/group and merge them in.
+ * This has to be done in every code path
+ * that creates an NT token, as remote users
+ * may have been added to the local /etc/group
+ * database. Tokens created merely from the
+ * info3 structs (via the DC or via the krb5 PAC)
+ * won't have these local groups. Note the
+ * groups added here will only be UNIX groups
+ * (S-1-22-2-XXXX groups) as getgroups_unix_user()
+ * turns off winbindd before calling getgroups().
+ *
+ * NB. This is duplicating work already
+ * done in the 'unix_user:' case of
+ * create_token_from_sid() but won't
+ * do anything other than be inefficient
+ * in that case.
+ */
+
+ if (!getgroups_unix_user(tmp_ctx, pass->pw_name, pass->pw_gid,
+ &gids, &getgroups_num_group_sids)) {
+ DEBUG(1, ("getgroups_unix_user for user %s failed\n",
+ pass->pw_name));
+ TALLOC_FREE(tmp_ctx);
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ for (i=0; i<getgroups_num_group_sids; i++) {
+ NTSTATUS status;
+ struct dom_sid grp_sid;
+ gid_to_sid(&grp_sid, gids[i]);
+
+ status = add_sid_to_array_unique(result,
+ &grp_sid,
+ &result->sids,
+ &result->num_sids);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(3, ("Failed to add UNIX SID to nt token\n"));
TALLOC_FREE(tmp_ctx);
- return NT_STATUS_UNSUCCESSFUL;
+ return status;
}
+ }
+ TALLOC_FREE(tmp_ctx);
+ return NT_STATUS_OK;
+}
- for (i=0; i<getgroups_num_group_sids; i++) {
- struct dom_sid grp_sid;
- gid_to_sid(&grp_sid, gids[i]);
+static NTSTATUS finalize_local_nt_token(struct security_token *result,
+ bool is_guest)
+{
+ struct dom_sid dom_sid;
+ gid_t gid;
+ NTSTATUS status;
- status = add_sid_to_array_unique(result,
- &grp_sid,
- &result->sids,
- &result->num_sids);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(3, ("Failed to add UNIX SID to nt token\n"));
- TALLOC_FREE(tmp_ctx);
- return status;
- }
- }
- TALLOC_FREE(tmp_ctx);
+ /* Add any local groups. */
+
+ status = add_local_groups(result, is_guest);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
/* Add in BUILTIN sids */