diff options
Diffstat (limited to 'source3/auth/auth_util.c')
-rw-r--r-- | source3/auth/auth_util.c | 285 |
1 files changed, 260 insertions, 25 deletions
diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index ce47e94eb5..a95a59ea46 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -1422,7 +1422,7 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, const char *sent_nt_username, const char *domain, auth_serversupplied_info **server_info, - NET_USER_INFO_3 *info3) + struct netr_SamInfo3 *info3) { char zeros[16]; @@ -1446,23 +1446,25 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, matches. */ - sid_copy(&user_sid, &info3->dom_sid.sid); - if (!sid_append_rid(&user_sid, info3->user_rid)) { + sid_copy(&user_sid, info3->base.domain_sid); + if (!sid_append_rid(&user_sid, info3->base.rid)) { return NT_STATUS_INVALID_PARAMETER; } - sid_copy(&group_sid, &info3->dom_sid.sid); - if (!sid_append_rid(&group_sid, info3->group_rid)) { + sid_copy(&group_sid, info3->base.domain_sid); + if (!sid_append_rid(&group_sid, info3->base.primary_gid)) { return NT_STATUS_INVALID_PARAMETER; } - if (!(nt_username = unistr2_to_ascii_talloc(mem_ctx, &(info3->uni_user_name)))) { + nt_username = talloc_strdup(mem_ctx, info3->base.account_name.string); + if (!nt_username) { /* If the server didn't give us one, just use the one we sent * them */ nt_username = sent_nt_username; } - if (!(nt_domain = unistr2_to_ascii_talloc(mem_ctx, &(info3->uni_logon_dom)))) { + nt_domain = talloc_strdup(mem_ctx, info3->base.domain.string); + if (!nt_domain) { /* If the server didn't give us one, just use the one we sent * them */ nt_domain = domain; @@ -1527,50 +1529,50 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, TALLOC_FREE(sam_account); return NT_STATUS_UNSUCCESSFUL; } - + if (!pdb_set_fullname(sam_account, - unistr2_static(&(info3->uni_full_name)), + info3->base.full_name.string, PDB_CHANGED)) { TALLOC_FREE(sam_account); return NT_STATUS_NO_MEMORY; } if (!pdb_set_logon_script(sam_account, - unistr2_static(&(info3->uni_logon_script)), + info3->base.logon_script.string, PDB_CHANGED)) { TALLOC_FREE(sam_account); return NT_STATUS_NO_MEMORY; } if (!pdb_set_profile_path(sam_account, - unistr2_static(&(info3->uni_profile_path)), + info3->base.profile_path.string, PDB_CHANGED)) { TALLOC_FREE(sam_account); return NT_STATUS_NO_MEMORY; } if (!pdb_set_homedir(sam_account, - unistr2_static(&(info3->uni_home_dir)), + info3->base.home_directory.string, PDB_CHANGED)) { TALLOC_FREE(sam_account); return NT_STATUS_NO_MEMORY; } if (!pdb_set_dir_drive(sam_account, - unistr2_static(&(info3->uni_dir_drive)), + info3->base.home_drive.string, PDB_CHANGED)) { TALLOC_FREE(sam_account); return NT_STATUS_NO_MEMORY; } - if (!pdb_set_acct_ctrl(sam_account, info3->acct_flags, PDB_CHANGED)) { + if (!pdb_set_acct_ctrl(sam_account, info3->base.acct_flags, PDB_CHANGED)) { TALLOC_FREE(sam_account); return NT_STATUS_NO_MEMORY; } if (!pdb_set_pass_last_set_time( sam_account, - nt_time_to_unix(info3->pass_last_set_time), + nt_time_to_unix(info3->base.last_password_change), PDB_CHANGED)) { TALLOC_FREE(sam_account); return NT_STATUS_NO_MEMORY; @@ -1578,7 +1580,7 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, if (!pdb_set_pass_can_change_time( sam_account, - nt_time_to_unix(info3->pass_can_change_time), + nt_time_to_unix(info3->base.allow_password_change), PDB_CHANGED)) { TALLOC_FREE(sam_account); return NT_STATUS_NO_MEMORY; @@ -1586,7 +1588,7 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, if (!pdb_set_pass_must_change_time( sam_account, - nt_time_to_unix(info3->pass_must_change_time), + nt_time_to_unix(info3->base.force_password_change), PDB_CHANGED)) { TALLOC_FREE(sam_account); return NT_STATUS_NO_MEMORY; @@ -1624,27 +1626,260 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, return nt_status; } - result->login_server = unistr2_to_ascii_talloc(result, - &(info3->uni_logon_srv)); + result->login_server = talloc_strdup(result, + info3->base.logon_server.string); + + /* ensure we are never given NULL session keys */ + + ZERO_STRUCT(zeros); + + if (memcmp(info3->base.key.key, zeros, sizeof(zeros)) == 0) { + result->user_session_key = data_blob_null; + } else { + result->user_session_key = data_blob_talloc( + result, info3->base.key.key, + sizeof(info3->base.key.key)); + } + + if (memcmp(info3->base.LMSessKey.key, zeros, 8) == 0) { + result->lm_session_key = data_blob_null; + } else { + result->lm_session_key = data_blob_talloc( + result, info3->base.LMSessKey.key, + sizeof(info3->base.LMSessKey.key)); + } + + result->was_mapped = username_was_mapped; + + *server_info = result; + + return NT_STATUS_OK; +} + +/***************************************************************************** + Make a server_info struct from the wbcAuthUserInfo returned by a domain logon +******************************************************************************/ + +NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx, + const char *sent_nt_username, + const char *domain, + const struct wbcAuthUserInfo *info, + auth_serversupplied_info **server_info) +{ + char zeros[16]; + + NTSTATUS nt_status = NT_STATUS_OK; + char *found_username = NULL; + const char *nt_domain; + const char *nt_username; + struct samu *sam_account = NULL; + DOM_SID user_sid; + DOM_SID group_sid; + bool username_was_mapped; + uint32_t i; + + uid_t uid = (uid_t)-1; + gid_t gid = (gid_t)-1; + + auth_serversupplied_info *result; + + result = make_server_info(NULL); + if (result == NULL) { + DEBUG(4, ("make_server_info failed!\n")); + return NT_STATUS_NO_MEMORY; + } + + /* + Here is where we should check the list of + trusted domains, and verify that the SID + matches. + */ + + memcpy(&user_sid, &info->sids[0].sid, sizeof(user_sid)); + memcpy(&group_sid, &info->sids[1].sid, sizeof(group_sid)); + + if (info->account_name) { + nt_username = talloc_strdup(result, info->account_name); + } else { + /* If the server didn't give us one, just use the one we sent + * them */ + nt_username = talloc_strdup(result, sent_nt_username); + } + if (!nt_username) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + if (info->domain_name) { + nt_domain = talloc_strdup(result, info->domain_name); + } else { + /* If the server didn't give us one, just use the one we sent + * them */ + nt_domain = talloc_strdup(result, domain); + } + if (!nt_domain) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + /* try to fill the SAM account.. If getpwnam() fails, then try the + add user script (2.2.x behavior). + + We use the _unmapped_ username here in an attempt to provide + consistent username mapping behavior between kerberos and NTLM[SSP] + authentication in domain mode security. I.E. Username mapping + should be applied to the fully qualified username + (e.g. DOMAIN\user) and not just the login name. Yes this means we + called map_username() unnecessarily in make_user_info_map() but + that is how the current code is designed. Making the change here + is the least disruptive place. -- jerry */ + + if ( !(sam_account = samu_new( result )) ) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + /* this call will try to create the user if necessary */ + + nt_status = fill_sam_account(result, nt_domain, sent_nt_username, + &found_username, &uid, &gid, sam_account, + &username_was_mapped); + + /* if we still don't have a valid unix account check for + 'map to guest = bad uid' */ + + if (!NT_STATUS_IS_OK(nt_status)) { + TALLOC_FREE( result ); + if ( lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID ) { + make_server_info_guest(server_info); + return NT_STATUS_OK; + } + return nt_status; + } + + if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) { + TALLOC_FREE(result); + return NT_STATUS_UNSUCCESSFUL; + } + + if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) { + TALLOC_FREE(result); + return NT_STATUS_UNSUCCESSFUL; + } + + if (!pdb_set_fullname(sam_account, info->full_name, PDB_CHANGED)) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + if (!pdb_set_logon_script(sam_account, info->logon_script, PDB_CHANGED)) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + if (!pdb_set_profile_path(sam_account, info->profile_path, PDB_CHANGED)) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + if (!pdb_set_homedir(sam_account, info->home_directory, PDB_CHANGED)) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + if (!pdb_set_dir_drive(sam_account, info->home_drive, PDB_CHANGED)) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + if (!pdb_set_acct_ctrl(sam_account, info->acct_flags, PDB_CHANGED)) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + if (!pdb_set_pass_last_set_time( + sam_account, + nt_time_to_unix(info->pass_last_set_time), + PDB_CHANGED)) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + if (!pdb_set_pass_can_change_time( + sam_account, + nt_time_to_unix(info->pass_can_change_time), + PDB_CHANGED)) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + if (!pdb_set_pass_must_change_time( + sam_account, + nt_time_to_unix(info->pass_must_change_time), + PDB_CHANGED)) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + /* save this here to _net_sam_logon() doesn't fail (it assumes a + valid struct samu) */ + + result->sam_account = sam_account; + result->unix_name = talloc_strdup(result, found_username); + + result->login_server = talloc_strdup(result, info->logon_server); + + /* Fill in the unix info we found on the way */ + + result->uid = uid; + result->gid = gid; + + /* Create a 'combined' list of all SIDs we might want in the SD */ + + result->num_sids = info->num_sids - 2; + result->sids = talloc_array(result, DOM_SID, result->num_sids); + if (result->sids == NULL) { + TALLOC_FREE(result); + return NT_STATUS_NO_MEMORY; + } + + for (i=0; i < result->num_sids; i++) { + memcpy(&result->sids[i], &info->sids[i+2].sid, sizeof(result->sids[i])); + } /* ensure we are never given NULL session keys */ ZERO_STRUCT(zeros); - if (memcmp(info3->user_sess_key, zeros, sizeof(zeros)) == 0) { + if (memcmp(info->user_session_key, zeros, sizeof(zeros)) == 0) { result->user_session_key = data_blob_null; } else { result->user_session_key = data_blob_talloc( - result, info3->user_sess_key, - sizeof(info3->user_sess_key)); + result, info->user_session_key, + sizeof(info->user_session_key)); } - if (memcmp(info3->lm_sess_key, zeros, 8) == 0) { + if (memcmp(info->lm_session_key, zeros, 8) == 0) { result->lm_session_key = data_blob_null; } else { result->lm_session_key = data_blob_talloc( - result, info3->lm_sess_key, - sizeof(info3->lm_sess_key)); + result, info->lm_session_key, + sizeof(info->lm_session_key)); } result->was_mapped = username_was_mapped; |