static NTSTATUS auth3_generate_session_info_pac(struct auth4_context *auth_ctx, TALLOC_CTX *mem_ctx, struct smb_krb5_context *smb_krb5_context, DATA_BLOB *pac_blob, const char *princ_name, const struct tsocket_address *remote_address, uint32_t session_info_flags, struct auth_session_info **session_info) { TALLOC_CTX *tmp_ctx; struct PAC_LOGON_INFO *logon_info = NULL; struct netr_SamInfo3 *info3_copy = NULL; bool is_mapped; bool is_guest; char *ntuser; char *ntdomain; char *username; char *rhost; struct passwd *pw; NTSTATUS status; int rc; tmp_ctx = talloc_new(mem_ctx); if (!tmp_ctx) { return NT_STATUS_NO_MEMORY; } if (pac_blob) { #ifdef HAVE_KRB5 status = kerberos_pac_logon_info(tmp_ctx, *pac_blob, NULL, NULL, NULL, NULL, 0, &logon_info); #else status = NT_STATUS_ACCESS_DENIED; #endif if (!NT_STATUS_IS_OK(status)) { goto done; } } rc = get_remote_hostname(remote_address, &rhost, tmp_ctx); if (rc < 0) { status = NT_STATUS_NO_MEMORY; goto done; } if (strequal(rhost, "UNKNOWN")) { rhost = tsocket_address_inet_addr_string(remote_address, tmp_ctx); if (rhost == NULL) { status = NT_STATUS_NO_MEMORY; goto done; } } status = get_user_from_kerberos_info(tmp_ctx, rhost, princ_name, logon_info, &is_mapped, &is_guest, &ntuser, &ntdomain, &username, &pw); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to map kerberos principal to system user " "(%s)\n", nt_errstr(status))); status = NT_STATUS_ACCESS_DENIED; goto done; } /* save the PAC data if we have it */ if (logon_info) { status = create_info3_from_pac_logon_info(tmp_ctx, logon_info, &info3_copy); if (!NT_STATUS_IS_OK(status)) { goto done; } netsamlogon_cache_store(ntuser, info3_copy); } /* setup the string used by %U */ sub_set_smb_name(username); /* reload services so that the new %U is taken into account */ lp_load_with_shares(get_dyn_CONFIGFILE()); status = make_session_info_krb5(mem_ctx, ntuser, ntdomain, username, pw, info3_copy, is_guest, is_mapped, NULL /* No session key for now, caller will sort it out */, session_info); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to map kerberos pac to server info (%s)\n", nt_errstr(status))); status = NT_STATUS_ACCESS_DENIED; goto done; } DEBUG(5, (__location__ "OK: user: %s domain: %s client: %s\n", ntuser, ntdomain, rhost)); status = NT_STATUS_OK; done: TALLOC_FREE(tmp_ctx); return status; }
NTSTATUS auth3_check_password(struct auth4_context *auth4_context, TALLOC_CTX *mem_ctx, const struct auth_usersupplied_info *user_info, void **server_returned_info, DATA_BLOB *session_key, DATA_BLOB *lm_session_key) { struct auth_context *auth_context = talloc_get_type_abort(auth4_context->private_data, struct auth_context); struct auth_usersupplied_info *mapped_user_info = NULL; struct auth_serversupplied_info *server_info; NTSTATUS nt_status; bool username_was_mapped; /* The client has given us its machine name (which we only get over NBT transport). We need to possibly reload smb.conf if smb.conf includes depend on the machine name. */ set_remote_machine_name(user_info->workstation_name, True); /* setup the string used by %U */ /* sub_set_smb_name checks for weird internally */ sub_set_smb_name(user_info->client.account_name); lp_load_with_shares(get_dyn_CONFIGFILE()); nt_status = make_user_info_map(talloc_tos(), &mapped_user_info, user_info->client.account_name, user_info->client.domain_name, user_info->workstation_name, user_info->remote_host, user_info->password.response.lanman.data ? &user_info->password.response.lanman : NULL, user_info->password.response.nt.data ? &user_info->password.response.nt : NULL, NULL, NULL, NULL, AUTH_PASSWORD_RESPONSE); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } mapped_user_info->logon_parameters = user_info->logon_parameters; mapped_user_info->flags = user_info->flags; nt_status = auth_check_ntlm_password(mem_ctx, auth_context, mapped_user_info, &server_info); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(5,("Checking NTLMSSP password for %s\\%s failed: %s\n", user_info->client.domain_name, user_info->client.account_name, nt_errstr(nt_status))); } username_was_mapped = mapped_user_info->was_mapped; TALLOC_FREE(mapped_user_info); if (!NT_STATUS_IS_OK(nt_status)) { nt_status = do_map_to_guest_server_info(mem_ctx, nt_status, user_info->client.account_name, user_info->client.domain_name, &server_info); *server_returned_info = talloc_steal(mem_ctx, server_info); return nt_status; } server_info->nss_token |= username_was_mapped; /* Clear out the session keys, and pass them to the caller. * They will not be used in this form again - instead the * NTLMSSP code will decide on the final correct session key, * and supply it to create_local_token() */ if (session_key) { DEBUG(10, ("Got NT session key of length %u\n", (unsigned int)server_info->session_key.length)); *session_key = server_info->session_key; talloc_steal(mem_ctx, server_info->session_key.data); server_info->session_key = data_blob_null; } if (lm_session_key) { DEBUG(10, ("Got LM session key of length %u\n", (unsigned int)server_info->lm_session_key.length)); *lm_session_key = server_info->lm_session_key; talloc_steal(mem_ctx, server_info->lm_session_key.data); server_info->lm_session_key = data_blob_null; } *server_returned_info = talloc_steal(mem_ctx, server_info); return nt_status; }