From aa1a3cbad2ed62d5b59c48a6e7726eef4776f461 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Fri, 28 May 2010 16:16:53 -0400 Subject: s3:auth create nt token from info3 directly Signed-off-by: Andrew Bartlett --- source3/auth/auth_util.c | 17 ++--- source3/auth/token_util.c | 183 +++++++++++++++++++++++++++++++++++++++------- source3/include/proto.h | 5 ++ 3 files changed, 167 insertions(+), 38 deletions(-) diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index 3591271157..ea95f33a86 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -463,7 +463,6 @@ NTSTATUS create_local_token(struct auth_serversupplied_info *server_info) NTSTATUS status; size_t i; struct dom_sid tmp_sid; - struct dom_sid user_sid; /* * If winbind is not around, we can not make much use of the SIDs the @@ -482,17 +481,11 @@ NTSTATUS create_local_token(struct auth_serversupplied_info *server_info) &server_info->ptok); } else { - sid_compose(&user_sid, - server_info->info3->base.domain_sid, - server_info->info3->base.rid); - - server_info->ptok = create_local_nt_token( - server_info, - &user_sid, - server_info->guest, - server_info->num_sids, server_info->sids); - status = server_info->ptok ? - NT_STATUS_OK : NT_STATUS_NO_SUCH_USER; + status = create_local_nt_token_from_info3(server_info, + server_info->guest, + server_info->info3, + &server_info->extra, + &server_info->ptok); } if (!NT_STATUS_IS_OK(status)) { diff --git a/source3/auth/token_util.c b/source3/auth/token_util.c index d2a03b4031..660fcf6192 100644 --- a/source3/auth/token_util.c +++ b/source3/auth/token_util.c @@ -335,6 +335,120 @@ NTSTATUS create_builtin_administrators(const struct dom_sid *dom_sid) return status; } +static NTSTATUS finalize_local_nt_token(struct nt_user_token *result, + bool is_guest); + +NTSTATUS create_local_nt_token_from_info3(TALLOC_CTX *mem_ctx, + bool is_guest, + struct netr_SamInfo3 *info3, + struct extra_auth_info *extra, + struct nt_user_token **ntok) +{ + struct nt_user_token *usrtok = NULL; + NTSTATUS status; + int i; + + DEBUG(10, ("Create local NT token for %s\n", + info3->base.account_name.string)); + + usrtok = talloc_zero(mem_ctx, struct nt_user_token); + if (!usrtok) { + DEBUG(0, ("talloc failed\n")); + return NT_STATUS_NO_MEMORY; + } + + /* Add the user and primary group sid FIRST */ + /* check if the user rid is the special "Domain Guests" rid. + * If so pick the first sid for the extra sids instead as it + * is a local fake account */ + usrtok->user_sids = talloc_array(usrtok, struct dom_sid, 2); + if (!usrtok->user_sids) { + TALLOC_FREE(usrtok); + return NT_STATUS_NO_MEMORY; + } + usrtok->num_sids = 2; + + /* USER SID */ + if (info3->base.rid == (uint32_t)(-1)) { + /* this is a signal the user was fake and generated, + * the actual SID we want to use is stored in the extra + * sids */ + if (is_null_sid(&extra->user_sid)) { + /* we couldn't find the user sid, bail out */ + DEBUG(3, ("Invalid user SID\n")); + TALLOC_FREE(usrtok); + return NT_STATUS_UNSUCCESSFUL; + } + sid_copy(&usrtok->user_sids[0], &extra->user_sid); + } else { + sid_copy(&usrtok->user_sids[0], info3->base.domain_sid); + sid_append_rid(&usrtok->user_sids[0], info3->base.rid); + } + + /* GROUP SID */ + if (info3->base.primary_gid == (uint32_t)(-1)) { + /* this is a signal the user was fake and generated, + * the actual SID we want to use is stored in the extra + * sids */ + if (is_null_sid(&extra->pgid_sid)) { + /* we couldn't find the user sid, bail out */ + DEBUG(3, ("Invalid group SID\n")); + TALLOC_FREE(usrtok); + return NT_STATUS_UNSUCCESSFUL; + } + sid_copy(&usrtok->user_sids[1], &extra->pgid_sid); + } else { + sid_copy(&usrtok->user_sids[1], info3->base.domain_sid); + sid_append_rid(&usrtok->user_sids[1], + info3->base.primary_gid); + } + + /* Now the SIDs we got from authentication. These are the ones from + * the info3 struct or from the pdb_enum_group_memberships, depending + * on who authenticated the user. + * Note that we start the for loop at "1" here, we already added the + * first group sid as primary above. */ + + for (i = 0; i < info3->base.groups.count; i++) { + struct dom_sid tmp_sid; + + sid_copy(&tmp_sid, info3->base.domain_sid); + sid_append_rid(&tmp_sid, info3->base.groups.rids[i].rid); + + status = add_sid_to_array_unique(usrtok, &tmp_sid, + &usrtok->user_sids, + &usrtok->num_sids); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(3, ("Failed to add SID to nt token\n")); + TALLOC_FREE(usrtok); + return status; + } + } + + /* now also add extra sids if they are not the special user/group + * sids */ + for (i = 0; i < info3->sidcount; i++) { + status = add_sid_to_array_unique(usrtok, + info3->sids[i].sid, + &usrtok->user_sids, + &usrtok->num_sids); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(3, ("Failed to add SID to nt token\n")); + TALLOC_FREE(usrtok); + return status; + } + } + + status = finalize_local_nt_token(usrtok, is_guest); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(3, ("Failed to finalize nt token\n")); + TALLOC_FREE(usrtok); + return status; + } + + *ntok = usrtok; + return NT_STATUS_OK; +} /******************************************************************* Create a NT token for the user, expanding local aliases @@ -349,8 +463,6 @@ struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx, struct nt_user_token *result = NULL; int i; NTSTATUS status; - gid_t gid; - struct dom_sid dom_sid; DEBUG(10, ("Create local NT token for %s\n", sid_string_dbg(user_sid))); @@ -365,6 +477,7 @@ struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx, status = add_sid_to_array(result, user_sid, &result->user_sids, &result->num_sids); if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(result); return NULL; } @@ -374,21 +487,54 @@ struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx, &result->user_sids, &result->num_sids); if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(result); return NULL; } } + /* Now the SIDs we got from authentication. These are the ones from + * the info3 struct or from the pdb_enum_group_memberships, depending + * on who authenticated the user. + * Note that we start the for loop at "1" here, we already added the + * first group sid as primary above. */ + + for (i=1; iuser_sids, + &result->num_sids); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(result); + return NULL; + } + } + + status = finalize_local_nt_token(result, is_guest); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(result); + return NULL; + } + + return result; +} + +static NTSTATUS finalize_local_nt_token(struct nt_user_token *result, + bool is_guest) +{ + struct dom_sid dom_sid; + gid_t gid; + NTSTATUS status; + /* Add in BUILTIN sids */ status = add_sid_to_array(result, &global_sid_World, &result->user_sids, &result->num_sids); if (!NT_STATUS_IS_OK(status)) { - return NULL; + return status; } status = add_sid_to_array(result, &global_sid_Network, &result->user_sids, &result->num_sids); if (!NT_STATUS_IS_OK(status)) { - return NULL; + return status; } if (is_guest) { @@ -396,7 +542,7 @@ struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx, &result->user_sids, &result->num_sids); if (!NT_STATUS_IS_OK(status)) { - return NULL; + return status; } } else { status = add_sid_to_array(result, @@ -404,22 +550,7 @@ struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx, &result->user_sids, &result->num_sids); if (!NT_STATUS_IS_OK(status)) { - return NULL; - } - } - - /* Now the SIDs we got from authentication. These are the ones from - * the info3 struct or from the pdb_enum_group_memberships, depending - * on who authenticated the user. - * Note that we start the for loop at "1" here, we already added the - * first group sid as primary above. */ - - for (i=1; iuser_sids, - &result->num_sids); - if (!NT_STATUS_IS_OK(status)) { - return NULL; + return status; } } @@ -490,8 +621,7 @@ struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx, if (!NT_STATUS_IS_OK(status)) { unbecome_root(); - TALLOC_FREE(result); - return NULL; + return status; } /* Finally the builtin ones */ @@ -500,17 +630,18 @@ struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx, if (!NT_STATUS_IS_OK(status)) { unbecome_root(); - TALLOC_FREE(result); - return NULL; + return status; } unbecome_root(); } + /* Add privileges based on current user sids */ get_privileges_for_sids(&result->privileges, result->user_sids, result->num_sids); - return result; + + return NT_STATUS_OK; } /**************************************************************************** diff --git a/source3/include/proto.h b/source3/include/proto.h index 9a53749646..393e7e277c 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -263,6 +263,11 @@ struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx, bool is_guest, int num_groupsids, const struct dom_sid *groupsids); +NTSTATUS create_local_nt_token_from_info3(TALLOC_CTX *mem_ctx, + bool is_guest, + struct netr_SamInfo3 *info3, + struct extra_auth_info *extra, + struct nt_user_token **ntok); void debug_nt_user_token(int dbg_class, int dbg_lev, NT_USER_TOKEN *token); void debug_unix_user_token(int dbg_class, int dbg_lev, uid_t uid, gid_t gid, int n_groups, gid_t *groups); -- cgit