From b2edf254eda92f775e7d3d9b6793b4d77f9000b6 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 17 Aug 2002 17:00:51 +0000 Subject: sync 3.0 branch with head (This used to be commit 3928578b52cfc949be5e0ef444fce1558d75f290) --- source3/auth/auth.c | 14 ++--- source3/auth/auth_domain.c | 139 ++++++++++++++++++++++++++++++++------------ source3/auth/auth_sam.c | 19 +++++- source3/auth/auth_util.c | 5 +- source3/auth/auth_winbind.c | 70 +++++++++++++++------- 5 files changed, 178 insertions(+), 69 deletions(-) (limited to 'source3/auth') diff --git a/source3/auth/auth.c b/source3/auth/auth.c index 4f7a5c24a0..d43afc71e1 100644 --- a/source3/auth/auth.c +++ b/source3/auth/auth.c @@ -395,33 +395,33 @@ NTSTATUS make_auth_context_subsystem(struct auth_context **auth_context) { case SEC_DOMAIN: DEBUG(5,("Making default auth method list for security=domain\n")); - auth_method_list = str_list_make("guest sam ntdomain"); + auth_method_list = str_list_make("guest sam winbind ntdomain", NULL); break; case SEC_SERVER: DEBUG(5,("Making default auth method list for security=server\n")); - auth_method_list = str_list_make("guest sam smbserver"); + auth_method_list = str_list_make("guest sam smbserver", NULL); break; case SEC_USER: if (lp_encrypted_passwords()) { DEBUG(5,("Making default auth method list for security=user, encrypt passwords = yes\n")); - auth_method_list = str_list_make("guest sam"); + auth_method_list = str_list_make("guest sam", NULL); } else { DEBUG(5,("Making default auth method list for security=user, encrypt passwords = no\n")); - auth_method_list = str_list_make("guest unix"); + auth_method_list = str_list_make("guest unix", NULL); } break; case SEC_SHARE: if (lp_encrypted_passwords()) { DEBUG(5,("Making default auth method list for security=share, encrypt passwords = yes\n")); - auth_method_list = str_list_make("guest sam"); + auth_method_list = str_list_make("guest sam", NULL); } else { DEBUG(5,("Making default auth method list for security=share, encrypt passwords = no\n")); - auth_method_list = str_list_make("guest unix"); + auth_method_list = str_list_make("guest unix", NULL); } break; case SEC_ADS: DEBUG(5,("Making default auth method list for security=ADS\n")); - auth_method_list = str_list_make("guest sam ads ntdomain"); + auth_method_list = str_list_make("guest sam ads winbind ntdomain", NULL); break; default: DEBUG(5,("Unknown auth method!\n")); diff --git a/source3/auth/auth_domain.c b/source3/auth/auth_domain.c index 3352c5f9c8..d48cec5b29 100644 --- a/source3/auth/auth_domain.c +++ b/source3/auth/auth_domain.c @@ -29,6 +29,88 @@ BOOL global_machine_password_needs_changing = False; extern pstring global_myname; extern userdom_struct current_user_info; + +/* + resolve the name of a DC in ways appropriate for an ADS domain mode + an ADS domain may not have Netbios enabled at all, so this is + quite different from the RPC case + Note that we ignore the 'server' parameter here. That has the effect of using + the 'ADS server' smb.conf parameter, which is what we really want anyway + */ +static NTSTATUS ads_resolve_dc(fstring remote_machine, + struct in_addr *dest_ip) +{ + ADS_STRUCT *ads; + ads = ads_init_simple(); + if (!ads) { + return NT_STATUS_NO_LOGON_SERVERS; + } + + DEBUG(4,("ads_resolve_dc: realm=%s\n", ads->config.realm)); + + ads->auth.no_bind = 1; + +#ifdef HAVE_ADS + /* a full ads_connect() is actually overkill, as we don't srictly need + to do the SASL auth in order to get the info we need, but libads + doesn't offer a better way right now */ + ads_connect(ads); +#endif + + fstrcpy(remote_machine, ads->config.ldap_server_name); + strupper(remote_machine); + *dest_ip = ads->ldap_ip; + ads_destroy(&ads); + + if (!*remote_machine || is_zero_ip(*dest_ip)) { + return NT_STATUS_NO_LOGON_SERVERS; + } + + DEBUG(4,("ads_resolve_dc: using server='%s' IP=%s\n", + remote_machine, inet_ntoa(*dest_ip))); + + return NT_STATUS_OK; +} + +/* + resolve the name of a DC in ways appropriate for RPC domain mode + this relies on the server supporting netbios and port 137 not being + firewalled + */ +static NTSTATUS rpc_resolve_dc(const char *server, + fstring remote_machine, + struct in_addr *dest_ip) +{ + if (is_ipaddress(server)) { + struct in_addr to_ip = *interpret_addr2(server); + + /* we need to know the machines netbios name - this is a lousy + way to find it, but until we have a RPC call that does this + it will have to do */ + if (!name_status_find("*", 0x20, 0x20, to_ip, remote_machine)) { + DEBUG(2, ("connect_to_domain_password_server: Can't " + "resolve name for IP %s\n", server)); + return NT_STATUS_NO_LOGON_SERVERS; + } + + *dest_ip = to_ip; + return NT_STATUS_OK; + } + + fstrcpy(remote_machine, server); + strupper(remote_machine); + if (!resolve_name(remote_machine, dest_ip, 0x20)) { + DEBUG(1,("connect_to_domain_password_server: Can't resolve address for %s\n", + remote_machine)); + return NT_STATUS_NO_LOGON_SERVERS; + } + + DEBUG(4,("rpc_resolve_dc: using server='%s' IP=%s\n", + remote_machine, inet_ntoa(*dest_ip))); + + return NT_STATUS_OK; +} + /** * Connect to a remote server for domain security authenticaion. * @@ -50,37 +132,22 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli, fstring remote_machine; NTSTATUS result; - if (is_ipaddress(server)) { - struct in_addr to_ip; - - /* we shouldn't have 255.255.255.255 forthe IP address of - a password server anyways */ - if ((to_ip.s_addr=inet_addr(server)) == 0xFFFFFFFF) { - DEBUG (0,("connect_to_domain_password_server: inet_addr(%s) returned 0xFFFFFFFF!\n", server)); - return NT_STATUS_UNSUCCESSFUL; - } - - if (!name_status_find("*", 0x20, 0x20, to_ip, remote_machine)) { - DEBUG(0, ("connect_to_domain_password_server: Can't " - "resolve name for IP %s\n", server)); - return NT_STATUS_UNSUCCESSFUL; - } + if (lp_security() == SEC_ADS) { + result = ads_resolve_dc(remote_machine, &dest_ip); } else { - fstrcpy(remote_machine, server); + result = rpc_resolve_dc(server, remote_machine, &dest_ip); } - standard_sub_basic(current_user_info.smb_name, remote_machine, sizeof(remote_machine)); - strupper(remote_machine); - - if(!resolve_name( remote_machine, &dest_ip, 0x20)) { - DEBUG(1,("connect_to_domain_password_server: Can't resolve address for %s\n", remote_machine)); - return NT_STATUS_UNSUCCESSFUL; + if (!NT_STATUS_IS_OK(result)) { + DEBUG(2,("connect_to_domain_password_server: unable to resolve DC: %s\n", + nt_errstr(result))); + return result; } - + if (ismyip(dest_ip)) { DEBUG(1,("connect_to_domain_password_server: Password server loop - not using password server %s\n", remote_machine)); - return NT_STATUS_UNSUCCESSFUL; + return NT_STATUS_NO_LOGON_SERVERS; } /* TODO: Send a SAMLOGON request to determine whether this is a valid @@ -98,11 +165,11 @@ static NTSTATUS connect_to_domain_password_server(struct cli_state **cli, */ if (!grab_server_mutex(server)) - return NT_STATUS_UNSUCCESSFUL; + return NT_STATUS_NO_LOGON_SERVERS; /* Attempt connection */ - result = cli_full_connection(cli, global_myname, server, - &dest_ip, 0, "IPC$", "IPC", "", "", "", 0); + result = cli_full_connection(cli, global_myname, remote_machine, + &dest_ip, 0, "IPC$", "IPC", "", "", "",0); if (!NT_STATUS_IS_OK(result)) { release_server_mutex(); @@ -129,7 +196,7 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(*cli))); cli_ulogoff(*cli); cli_shutdown(*cli); release_server_mutex(); - return NT_STATUS_UNSUCCESSFUL; + return NT_STATUS_NO_LOGON_SERVERS; } snprintf((*cli)->mach_acct, sizeof((*cli)->mach_acct) - 1, "%s$", setup_creds_as); @@ -139,7 +206,7 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(*cli))); return NT_STATUS_NO_MEMORY; } - result = new_cli_nt_setup_creds(*cli, sec_chan, trust_passwd); + result = cli_nt_setup_creds(*cli, sec_chan, trust_passwd); if (!NT_STATUS_IS_OK(result)) { DEBUG(0,("connect_to_domain_password_server: unable to setup the PDC credentials to machine \ @@ -174,10 +241,10 @@ static NTSTATUS attempt_connect_to_dc(struct cli_state **cli, */ if (is_zero_ip(*ip)) - return NT_STATUS_UNSUCCESSFUL; + return NT_STATUS_NO_LOGON_SERVERS; if (!lookup_dc_name(global_myname, domain, ip, dc_name)) - return NT_STATUS_UNSUCCESSFUL; + return NT_STATUS_NO_LOGON_SERVERS; return connect_to_domain_password_server(cli, dc_name, setup_creds_as, sec_chan, trust_passwd); } @@ -196,7 +263,7 @@ static NTSTATUS find_connect_pdc(struct cli_state **cli, struct in_addr *ip_list = NULL; int count = 0; int i; - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + NTSTATUS nt_status = NT_STATUS_NO_LOGON_SERVERS; time_t time_now = time(NULL); BOOL use_pdc_only = False; @@ -212,7 +279,7 @@ static NTSTATUS find_connect_pdc(struct cli_state **cli, use_pdc_only = True; if (!get_dc_list(use_pdc_only, domain, &ip_list, &count)) - return NT_STATUS_UNSUCCESSFUL; + return NT_STATUS_NO_LOGON_SERVERS; /* * Firstly try and contact a PDC/BDC who has the same @@ -288,7 +355,7 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx, fstring remote_machine; NET_USER_INFO_3 info3; struct cli_state *cli = NULL; - NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; + NTSTATUS nt_status = NT_STATUS_NO_LOGON_SERVERS; /* * At this point, smb_apasswd points to the lanman response to @@ -300,7 +367,7 @@ static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx, while (!NT_STATUS_IS_OK(nt_status) && next_token(&server,remote_machine,LIST_SEP,sizeof(remote_machine))) { - if(strequal(remote_machine, "*")) { + if(lp_security() != SEC_ADS && strequal(remote_machine, "*")) { nt_status = find_connect_pdc(&cli, domain, setup_creds_as, sec_chan, trust_passwd, last_change_time); } else { nt_status = connect_to_domain_password_server(&cli, remote_machine, setup_creds_as, sec_chan, trust_passwd); @@ -503,7 +570,7 @@ static NTSTATUS check_trustdomain_security(const struct auth_context *auth_conte #ifdef DEBUG_PASSWORD DEBUG(100, ("Trust password for domain %s is %s\n", user_info->domain.str, trust_password)); #endif - E_md4hash((uchar *)trust_password, trust_md4_password); + E_md4hash(trust_password, trust_md4_password); SAFE_FREE(trust_password); #if 0 diff --git a/source3/auth/auth_sam.c b/source3/auth/auth_sam.c index 76579150ce..155370546a 100644 --- a/source3/auth/auth_sam.c +++ b/source3/auth/auth_sam.c @@ -107,7 +107,7 @@ static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB ntv2_response, memcpy(client_response, ntv2_response.data, sizeof(client_response)); ntv2_owf_gen(part_passwd, user, domain, kr); - SMBOWFencrypt_ntv2(kr, sec_blob, client_key_data, (char *)value_from_encryption); + SMBOWFencrypt_ntv2(kr, sec_blob, client_key_data, value_from_encryption); if (user_sess_key != NULL) { SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key); @@ -232,11 +232,26 @@ static NTSTATUS sam_password_ok(const struct auth_context *auth_context, { return NT_STATUS_OK; } else { + if (lp_ntlm_auth()) { + /* Apparently NT accepts NT responses in the LM feild + - I think this is related to Win9X pass-though authenticaion + */ + DEBUG(4,("sam_password_ok: Checking NT MD4 password in LM feild\n")); + if (smb_pwd_check_ntlmv1(user_info->lm_resp, + nt_pw, auth_context->challenge, + user_sess_key)) + { + return NT_STATUS_OK; + } else { + DEBUG(3,("sam_password_ok: NT MD4 password in LM feild failed for user %s\n",pdb_get_username(sampass))); + return NT_STATUS_WRONG_PASSWORD; + } + } DEBUG(4,("sam_password_ok: LM password check failed for user %s\n",pdb_get_username(sampass))); return NT_STATUS_WRONG_PASSWORD; } } - + /* Should not be reached, but if they send nothing... */ DEBUG(3,("sam_password_ok: NEITHER LanMan nor NT password supplied for user %s\n",pdb_get_username(sampass))); return NT_STATUS_WRONG_PASSWORD; diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index 3ade220c0f..f914d91871 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -25,7 +25,6 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_AUTH -extern fstring remote_machine; extern pstring global_myname; /**************************************************************************** @@ -394,7 +393,7 @@ BOOL make_user_info_for_reply(auth_usersupplied_info **user_info, ret = make_user_info_map(user_info, smb_name, client_domain, - remote_machine, + get_remote_machine_name(), local_lm_blob, local_nt_blob, plaintext_password, @@ -429,7 +428,7 @@ BOOL make_user_info_for_reply_enc(auth_usersupplied_info **user_info, return make_user_info_map(user_info, smb_name, client_domain, - remote_machine, + get_remote_machine_name(), lm_resp, nt_resp, no_plaintext_blob, diff --git a/source3/auth/auth_winbind.c b/source3/auth/auth_winbind.c index 671e198bf5..5bdccd39f3 100644 --- a/source3/auth/auth_winbind.c +++ b/source3/auth/auth_winbind.c @@ -32,6 +32,30 @@ NSS_STATUS winbindd_request(int req_type, struct winbindd_request *request, struct winbindd_response *response); +NTSTATUS get_info3_from_ndr(TALLOC_CTX *mem_ctx, struct winbindd_response *response, NET_USER_INFO_3 *info3) +{ + uint8 *info3_ndr; + size_t len = response->length - sizeof(response); + prs_struct ps; + if (len > 0) { + info3_ndr = response->extra_data; + if (!prs_init(&ps, len, mem_ctx, UNMARSHALL)) { + return NT_STATUS_NO_MEMORY; + } + prs_append_data(&ps, info3_ndr, len); + ps.data_offset = 0; + if (!net_io_user_info3("", info3, &ps, 1, 3)) { + DEBUG(2, ("get_info3_from_ndr: could not parse info3 struct!\n")); + return NT_STATUS_UNSUCCESSFUL; + } + prs_mem_free(&ps); + + return NT_STATUS_OK; + } else { + DEBUG(2, ("get_info3_from_ndr: No info3 struct found!\n")); + return NT_STATUS_UNSUCCESSFUL; + } +} /* Authenticate a user with a challenge/response */ @@ -44,11 +68,11 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context, struct winbindd_request request; struct winbindd_response response; NSS_STATUS result; - struct passwd *pw; NTSTATUS nt_status; + NET_USER_INFO_3 info3; if (!user_info) { - return NT_STATUS_UNSUCCESSFUL; + return NT_STATUS_INVALID_PARAMETER; } if (!auth_context) { @@ -62,11 +86,14 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context, ZERO_STRUCT(request); ZERO_STRUCT(response); - snprintf(request.data.auth_crap.user, sizeof(request.data.auth_crap.user), - "%s\\%s", user_info->domain.str, user_info->smb_name.str); + request.data.auth_crap.flags = WINBIND_PAM_INFO3_NDR; - fstrcpy(request.data.auth_crap.user, user_info->smb_name.str); - fstrcpy(request.data.auth_crap.domain, user_info->domain.str); + push_utf8_fstring(request.data.auth_crap.user, + user_info->smb_name.str); + push_utf8_fstring(request.data.auth_crap.domain, + user_info->domain.str); + push_utf8_fstring(request.data.auth_crap.workstation, + user_info->wksta_name.str); memcpy(request.data.auth_crap.chal, auth_context->challenge.data, sizeof(request.data.auth_crap.chal)); @@ -76,27 +103,28 @@ static NTSTATUS check_winbind_security(const struct auth_context *auth_context, sizeof(request.data.auth_crap.nt_resp)); memcpy(request.data.auth_crap.lm_resp, user_info->lm_resp.data, - sizeof(request.data.auth_crap.lm_resp_len)); - memcpy(request.data.auth_crap.nt_resp, user_info->nt_resp.data, request.data.auth_crap.lm_resp_len); + memcpy(request.data.auth_crap.nt_resp, user_info->nt_resp.data, + request.data.auth_crap.nt_resp_len); result = winbindd_request(WINBINDD_PAM_AUTH_CRAP, &request, &response); - if (result == NSS_STATUS_SUCCESS) { - - pw = Get_Pwnam(user_info->internal_username.str); - - if (pw) { - if (make_server_info_pw(server_info, pw)) { - nt_status = NT_STATUS_OK; - } else { - nt_status = NT_STATUS_NO_MEMORY; + nt_status = NT_STATUS(response.data.auth.nt_status); + + if (result == NSS_STATUS_SUCCESS && response.extra_data) { + if (NT_STATUS_IS_OK(nt_status)) { + if (NT_STATUS_IS_OK(nt_status = get_info3_from_ndr(mem_ctx, &response, &info3))) { + nt_status = + make_server_info_info3(mem_ctx, + user_info->internal_username.str, + user_info->smb_name.str, + user_info->domain.str, + server_info, + &info3); } - } else { - nt_status = NT_STATUS_NO_SUCH_USER; } - } else { - nt_status = NT_STATUS_LOGON_FAILURE; + } else if (NT_STATUS_IS_OK(nt_status)) { + nt_status = NT_STATUS_UNSUCCESSFUL; } return nt_status; -- cgit