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_domain.c | 139 +++++++++++++++++++++++++++++++++------------ 1 file changed, 103 insertions(+), 36 deletions(-) (limited to 'source3/auth/auth_domain.c') 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 -- cgit