diff options
Diffstat (limited to 'source3/auth/auth_util.c')
-rw-r--r-- | source3/auth/auth_util.c | 315 |
1 files changed, 0 insertions, 315 deletions
diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index b7a5aee2c5..647d20cd65 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -800,321 +800,6 @@ NTSTATUS create_local_token(struct auth_serversupplied_info *server_info) return status; } -/* - * Create an artificial NT token given just a username. (Initially intended - * for force user) - * - * We go through lookup_name() to avoid problems we had with 'winbind use - * default domain'. - * - * We have 3 cases: - * - * unmapped unix users: Go directly to nss to find the user's group. - * - * A passdb user: The list of groups is provided by pdb_enum_group_memberships. - * - * If the user is provided by winbind, the primary gid is set to "domain - * users" of the user's domain. For an explanation why this is necessary, see - * the thread starting at - * http://lists.samba.org/archive/samba-technical/2006-January/044803.html. - */ - -NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username, - bool is_guest, - uid_t *uid, gid_t *gid, - char **found_username, - struct nt_user_token **token) -{ - NTSTATUS result = NT_STATUS_NO_SUCH_USER; - TALLOC_CTX *tmp_ctx = talloc_stackframe(); - DOM_SID user_sid; - enum lsa_SidType type; - gid_t *gids; - DOM_SID *group_sids; - DOM_SID unix_group_sid; - size_t num_group_sids; - size_t num_gids; - size_t i; - - if (!lookup_name_smbconf(tmp_ctx, username, LOOKUP_NAME_ALL, - NULL, NULL, &user_sid, &type)) { - DEBUG(1, ("lookup_name_smbconf for %s failed\n", username)); - goto done; - } - - if (type != SID_NAME_USER) { - DEBUG(1, ("%s is a %s, not a user\n", username, - sid_type_lookup(type))); - goto done; - } - - if (sid_check_is_in_our_domain(&user_sid)) { - bool ret; - - /* This is a passdb user, so ask passdb */ - - struct samu *sam_acct = NULL; - - if ( !(sam_acct = samu_new( tmp_ctx )) ) { - result = NT_STATUS_NO_MEMORY; - goto done; - } - - become_root(); - ret = pdb_getsampwsid(sam_acct, &user_sid); - unbecome_root(); - - if (!ret) { - DEBUG(1, ("pdb_getsampwsid(%s) for user %s failed\n", - sid_string_dbg(&user_sid), username)); - DEBUGADD(1, ("Fall back to unix user %s\n", username)); - goto unix_user; - } - - result = pdb_enum_group_memberships(tmp_ctx, sam_acct, - &group_sids, &gids, - &num_group_sids); - if (!NT_STATUS_IS_OK(result)) { - DEBUG(1, ("enum_group_memberships failed for %s (%s): " - "%s\n", username, sid_string_dbg(&user_sid), - nt_errstr(result))); - DEBUGADD(1, ("Fall back to unix user %s\n", username)); - goto unix_user; - } - - /* see the smb_panic() in pdb_default_enum_group_memberships */ - SMB_ASSERT(num_group_sids > 0); - - *gid = gids[0]; - - /* Ensure we're returning the found_username on the right context. */ - *found_username = talloc_strdup(mem_ctx, - pdb_get_username(sam_acct)); - - /* - * If the SID from lookup_name() was the guest sid, passdb knows - * about the mapping of guest sid to lp_guestaccount() - * username and will return the unix_pw info for a guest - * user. Use it if it's there, else lookup the *uid details - * using getpwnam_alloc(). See bug #6291 for details. JRA. - */ - - /* We must always assign the *uid. */ - if (sam_acct->unix_pw == NULL) { - struct passwd *pwd = getpwnam_alloc(sam_acct, *found_username ); - if (!pwd) { - DEBUG(10, ("getpwnam_alloc failed for %s\n", - *found_username)); - result = NT_STATUS_NO_SUCH_USER; - goto done; - } - result = samu_set_unix(sam_acct, pwd ); - if (!NT_STATUS_IS_OK(result)) { - DEBUG(10, ("samu_set_unix failed for %s\n", - *found_username)); - result = NT_STATUS_NO_SUCH_USER; - goto done; - } - } - *uid = sam_acct->unix_pw->pw_uid; - - } else if (sid_check_is_in_unix_users(&user_sid)) { - - /* This is a unix user not in passdb. We need to ask nss - * directly, without consulting passdb */ - - struct passwd *pass; - - /* - * This goto target is used as a fallback for the passdb - * case. The concrete bug report is when passdb gave us an - * unmapped gid. - */ - - unix_user: - - if (!sid_to_uid(&user_sid, uid)) { - DEBUG(1, ("unix_user case, sid_to_uid for %s (%s) failed\n", - username, sid_string_dbg(&user_sid))); - result = NT_STATUS_NO_SUCH_USER; - goto done; - } - - uid_to_unix_users_sid(*uid, &user_sid); - - pass = getpwuid_alloc(tmp_ctx, *uid); - if (pass == NULL) { - DEBUG(1, ("getpwuid(%u) for user %s failed\n", - (unsigned int)*uid, username)); - goto done; - } - - if (!getgroups_unix_user(tmp_ctx, username, pass->pw_gid, - &gids, &num_group_sids)) { - DEBUG(1, ("getgroups_unix_user for user %s failed\n", - username)); - goto done; - } - - if (num_group_sids) { - group_sids = TALLOC_ARRAY(tmp_ctx, DOM_SID, num_group_sids); - if (group_sids == NULL) { - DEBUG(1, ("TALLOC_ARRAY failed\n")); - result = NT_STATUS_NO_MEMORY; - goto done; - } - } else { - group_sids = NULL; - } - - for (i=0; i<num_group_sids; i++) { - gid_to_sid(&group_sids[i], gids[i]); - } - - /* In getgroups_unix_user we always set the primary gid */ - SMB_ASSERT(num_group_sids > 0); - - *gid = gids[0]; - - /* Ensure we're returning the found_username on the right context. */ - *found_username = talloc_strdup(mem_ctx, pass->pw_name); - } else { - - /* This user is from winbind, force the primary gid to the - * user's "domain users" group. Under certain circumstances - * (user comes from NT4), this might be a loss of - * information. But we can not rely on winbind getting the - * correct info. AD might prohibit winbind looking up that - * information. */ - - uint32 dummy; - - /* We must always assign the *uid. */ - if (!sid_to_uid(&user_sid, uid)) { - DEBUG(1, ("winbindd case, sid_to_uid for %s (%s) failed\n", - username, sid_string_dbg(&user_sid))); - result = NT_STATUS_NO_SUCH_USER; - goto done; - } - - num_group_sids = 1; - group_sids = TALLOC_ARRAY(tmp_ctx, DOM_SID, num_group_sids); - if (group_sids == NULL) { - DEBUG(1, ("TALLOC_ARRAY failed\n")); - result = NT_STATUS_NO_MEMORY; - goto done; - } - - sid_copy(&group_sids[0], &user_sid); - sid_split_rid(&group_sids[0], &dummy); - sid_append_rid(&group_sids[0], DOMAIN_GROUP_RID_USERS); - - if (!sid_to_gid(&group_sids[0], gid)) { - DEBUG(1, ("sid_to_gid(%s) failed\n", - sid_string_dbg(&group_sids[0]))); - goto done; - } - - gids = gid; - - /* Ensure we're returning the found_username on the right context. */ - *found_username = talloc_strdup(mem_ctx, username); - } - - /* Add the "Unix Group" SID for each gid to catch mapped groups - and their Unix equivalent. This is to solve the backwards - compatibility problem of 'valid users = +ntadmin' where - ntadmin has been paired with "Domain Admins" in the group - mapping table. Otherwise smb.conf would need to be changed - to 'valid user = "Domain Admins"'. --jerry */ - - num_gids = num_group_sids; - for ( i=0; i<num_gids; i++ ) { - gid_t high, low; - - /* don't pickup anything managed by Winbind */ - - if ( lp_idmap_gid(&low, &high) && (gids[i] >= low) && (gids[i] <= high) ) - continue; - - if ( !gid_to_unix_groups_sid( gids[i], &unix_group_sid ) ) { - DEBUG(1,("create_token_from_username: Failed to create SID " - "for gid %u!\n", (unsigned int)gids[i])); - continue; - } - result = add_sid_to_array_unique(tmp_ctx, &unix_group_sid, - &group_sids, &num_group_sids); - if (!NT_STATUS_IS_OK(result)) { - goto done; - } - } - - /* Ensure we're creating the nt_token on the right context. */ - *token = create_local_nt_token(mem_ctx, &user_sid, - is_guest, num_group_sids, group_sids); - - if ((*token == NULL) || (*found_username == NULL)) { - result = NT_STATUS_NO_MEMORY; - goto done; - } - - result = NT_STATUS_OK; - done: - TALLOC_FREE(tmp_ctx); - return result; -} - -/*************************************************************************** - Build upon create_token_from_username: - - Expensive helper function to figure out whether a user given its name is - member of a particular group. -***************************************************************************/ - -bool user_in_group_sid(const char *username, const DOM_SID *group_sid) -{ - NTSTATUS status; - uid_t uid; - gid_t gid; - char *found_username; - struct nt_user_token *token; - bool result; - TALLOC_CTX *mem_ctx = talloc_stackframe(); - - status = create_token_from_username(mem_ctx, username, False, - &uid, &gid, &found_username, - &token); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(10, ("could not create token for %s\n", username)); - TALLOC_FREE(mem_ctx); - return False; - } - - result = nt_token_check_sid(group_sid, token); - - TALLOC_FREE(mem_ctx); - return result; -} - -bool user_in_group(const char *username, const char *groupname) -{ - TALLOC_CTX *mem_ctx = talloc_stackframe(); - DOM_SID group_sid; - bool ret; - - ret = lookup_name(mem_ctx, groupname, LOOKUP_NAME_ALL, - NULL, NULL, &group_sid, NULL); - TALLOC_FREE(mem_ctx); - - if (!ret) { - DEBUG(10, ("lookup_name for (%s) failed.\n", groupname)); - return False; - } - - return user_in_group_sid(username, &group_sid); -} - /*************************************************************************** Make (and fill) a server_info struct from a 'struct passwd' by conversion to a struct samu |