From 632b4f806eae15e319b8f62caef5d25634cf720c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 3 Jan 2000 06:30:50 +0000 Subject: added suppport for unexpected udp/138 packets I also fixed up the lookup_pdc_name() code so that it now works, even with a NT server that insists on replying to udp/138. The method I used to match packets was to use the mailslot string as a datagram ID. The true dgm_id doesn't work as NT doesn't set it correctly. uggh. PS: Jeremy, I had to change your code quite a bit, are you sure this worked with a Samba PDC?? The code looked broken, it got the offsets wrong in the SMB portion of the packet and filled in the IP incorrectly. (This used to be commit 32f66f4ea63038cb4b3785bdf1762abdde076f5d) --- source3/smbd/password.c | 163 ++++++++++++++++++++++++++---------------------- 1 file changed, 88 insertions(+), 75 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 9792c9ebc8..ca588c6681 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -959,16 +959,18 @@ struct cli_state *server_cryptkey(void) struct cli_state *cli; fstring desthost; struct in_addr dest_ip; - char *p; - BOOL connected_ok = False; + char *p, *pserver; + BOOL connected_ok = False; cli = server_client(); if (!cli_initialise(cli)) return NULL; - p = lp_passwordserver(); - while(p && next_token( &p, desthost, LIST_SEP, sizeof(desthost))) { + pserver = strdup(lp_passwordserver()); + p = pserver; + + while(next_token( &p, desthost, LIST_SEP, sizeof(desthost))) { standard_sub_basic(desthost); strupper(desthost); @@ -989,6 +991,8 @@ struct cli_state *server_cryptkey(void) } } + free(pserver); + if (!connected_ok) { DEBUG(0,("password server not available\n")); cli_shutdown(cli); @@ -1249,15 +1253,79 @@ static BOOL attempt_connect_to_dc(struct cli_state *pcli, struct in_addr *ip, un * Ignore addresses we have already tried. */ - if(ip_equal(ipzero, *ip)) - return False; + if (ip_equal(ipzero, *ip)) + return False; - if(!lookup_pdc_name(global_myname, lp_workgroup(), ip, dc_name)) - return False; + if (!lookup_pdc_name(global_myname, lp_workgroup(), ip, dc_name)) + return False; return connect_to_domain_password_server(pcli, dc_name, trust_passwd); } + + +/*********************************************************************** + We have been asked to dynamcially determine the IP addresses of + the PDC and BDC's for this DOMAIN, and query them in turn. +************************************************************************/ +static BOOL find_connect_pdc(struct cli_state *pcli, unsigned char *trust_passwd) +{ + struct in_addr *ip_list = NULL; + int count = 0; + int i; + BOOL connected_ok = False; + + if (!get_dc_list(lp_workgroup(), &ip_list, &count)) + return False; + + /* + * Firstly try and contact a PDC/BDC who has the same + * network address as any of our interfaces. + */ + for(i = 0; i < count; i++) { + if(!is_local_net(ip_list[i])) + continue; + + if((connected_ok = attempt_connect_to_dc(pcli, &ip_list[i], trust_passwd))) + break; + + ip_list[i] = ipzero; /* Tried and failed. */ + } + + /* + * Secondly try and contact a random PDC/BDC. + */ + if(!connected_ok) { + i = (sys_random() % count); + + if (!(connected_ok = attempt_connect_to_dc(pcli, &ip_list[i], trust_passwd))) + ip_list[i] = ipzero; /* Tried and failed. */ + } + + /* + * Finally go through the IP list in turn, ignoring any addresses + * we have already tried. + */ + if(!connected_ok) { + /* + * Try and connect to any of the other IP addresses in the PDC/BDC list. + * Note that from a WINS server the #1 IP address is the PDC. + */ + for(i = 0; i < count; i++) { + if((connected_ok = attempt_connect_to_dc(pcli, &ip_list[i], trust_passwd))) + break; + } + } + + if(ip_list != NULL) + free((char *)ip_list); + + + return connected_ok; +} + + + /*********************************************************************** Do the same as security=server, but using NT Domain calls and a session key from the machine password. @@ -1273,7 +1341,7 @@ BOOL domain_client_validate( char *user, char *domain, unsigned char local_nt_reponse[24]; unsigned char trust_passwd[16]; fstring remote_machine; - char *p; + char *p, *pserver; NET_ID_INFO_CTR ctr; NET_USER_INFO_3 info3; struct cli_state cli; @@ -1349,75 +1417,20 @@ BOOL domain_client_validate( char *user, char *domain, * PDC/BDC. Contact each in turn and try and authenticate. */ - p = lp_passwordserver(); - while(!connected_ok && p && - next_token(&p,remote_machine,LIST_SEP,sizeof(remote_machine))) { - if(strequal(remote_machine, "*")) { - - /* - * We have been asked to dynamcially determine the IP addresses of - * the PDC and BDC's for this DOMAIN, and query them in turn. - */ - - struct in_addr *ip_list = NULL; - int count = 0; - int i; - - if(!get_dc_list(lp_workgroup(), &ip_list, &count)) - continue; - - /* - * Firstly try and contact a PDC/BDC who has the same - * network address as any of our interfaces. - */ - - for(i = 0; i < count; i++) { - if(!is_local_net(ip_list[i])) - continue; - - if((connected_ok = attempt_connect_to_dc(&cli, &ip_list[i], trust_passwd))) - break; - - ip_list[i] = ipzero; /* Tried and failed. */ - } - - /* - * Secondly try and contact a random PDC/BDC. - */ - - if(!connected_ok) { - i = (sys_random() % count); + pserver = strdup(lp_passwordserver()); + p = pserver; - if(!(connected_ok = attempt_connect_to_dc(&cli, &ip_list[i], trust_passwd))) - ip_list[i] = ipzero; /* Tried and failed. */ - } - - /* - * Finally go through the IP list in turn, ignoring any addresses - * we have already tried. - */ - - if(!connected_ok) { - - /* - * Try and connect to any of the other IP addresses in the PDC/BDC list. - * Note that from a WINS server the #1 IP address is the PDC. - */ - - for(i = 0; i < count; i++) { - if((connected_ok = attempt_connect_to_dc(&cli, &ip_list[i], trust_passwd))) - break; - } - } - - if(ip_list != NULL) - free((char *)ip_list); - - } else { - connected_ok = connect_to_domain_password_server(&cli, remote_machine, trust_passwd); - } + while (!connected_ok && + next_token(&p,remote_machine,LIST_SEP,sizeof(remote_machine))) { + if(strequal(remote_machine, "*")) { + connected_ok = find_connect_pdc(&cli, trust_passwd); + } else { + connected_ok = connect_to_domain_password_server(&cli, remote_machine, trust_passwd); + } } + free(pserver); + if (!connected_ok) { DEBUG(0,("domain_client_validate: Domain password server not available.\n")); cli_shutdown(&cli); -- cgit