2 Unix SMB/CIFS implementation.
4 Winbind daemon connection manager
6 Copyright (C) Tim Potter 2001
7 Copyright (C) Andrew Bartlett 2002
8 Copyright (C) Gerald (Jerry) Carter 2003-2005.
9 Copyright (C) Volker Lendecke 2004-2005
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 We need to manage connections to domain controllers without having to
28 mess up the main winbindd code with other issues. The aim of the
29 connection manager is to:
31 - make connections to domain controllers and cache them
32 - re-establish connections when networks or servers go down
33 - centralise the policy on connection timeouts, domain controller
35 - manage re-entrancy for when winbindd becomes able to handle
36 multiple outstanding rpc requests
38 Why not have connection management as part of the rpc layer like tng?
39 Good question. This code may morph into libsmb/rpc_cache.c or something
40 like that but at the moment it's simply staying as part of winbind. I
41 think the TNG architecture of forcing every user of the rpc layer to use
42 the connection caching system is a bad idea. It should be an optional
43 method of using the routines.
45 The TNG design is quite good but I disagree with some aspects of the
53 - I'm pretty annoyed by all the make_nmb_name() stuff. It should be
54 moved down into another function.
56 - Take care when destroying cli_structs as they can be shared between
65 #define DBGC_CLASS DBGC_WINBIND
67 static NTSTATUS init_dc_connection(struct winbindd_domain *domain);
69 /****************************************************************
70 Handler triggered if we're offline to try and detect a DC.
71 ****************************************************************/
73 static void check_domain_online_handler(struct timed_event *te,
74 const struct timeval *now,
77 struct winbindd_domain *domain =
78 (struct winbindd_domain *)private_data;
80 DEBUG(10,("check_domain_online_handler: called for domain %s\n",
83 if (domain->check_online_event) {
84 TALLOC_FREE(domain->check_online_event);
87 /* We've been told to stay offline, so stay
90 if (get_global_winbindd_state_offline()) {
91 DEBUG(10,("check_domain_online_handler: domain %s remaining globally offline\n",
96 /* This call takes care of setting the online
97 flag to true if we connected, or re-adding
98 the offline handler if false. */
99 init_dc_connection(domain);
102 /****************************************************************
103 Set domain offline and also add handler to put us back online
105 ****************************************************************/
107 void set_domain_offline(struct winbindd_domain *domain)
109 DEBUG(10,("set_domain_offline: called for domain %s\n",
112 if (domain->check_online_event) {
113 TALLOC_FREE(domain->check_online_event);
116 domain->online = False;
118 /* We only add the timeout handler that checks and
119 allows us to go back online when we've not
120 been told to remain offline. */
122 if (get_global_winbindd_state_offline()) {
123 DEBUG(10,("set_domain_offline: domain %s remaining globally offline\n",
128 domain->check_online_event = add_timed_event( NULL,
129 timeval_current_ofs(lp_winbind_cache_time(), 0),
130 "check_domain_online_handler",
131 check_domain_online_handler,
134 /* The above *has* to succeed for winbindd to work. */
135 if (!domain->check_online_event) {
136 smb_panic("set_domain_offline: failed to add online handler.\n");
139 DEBUG(10,("set_domain_offline: added event handler for domain %s\n",
143 /****************************************************************
144 Set domain online - if allowed.
145 ****************************************************************/
147 static void set_domain_online(struct winbindd_domain *domain)
151 DEBUG(10,("set_domain_online: called for domain %s\n",
154 if (get_global_winbindd_state_offline()) {
155 DEBUG(10,("set_domain_online: domain %s remaining globally offline\n",
160 /* If we are waiting to get a krb5 ticket, trigger immediately. */
162 set_event_dispatch_time("krb5_ticket_gain_handler", now);
163 domain->online = True;
166 /****************************************************************
167 Requested to set a domain online.
168 ****************************************************************/
170 void set_domain_online_request(struct winbindd_domain *domain)
172 DEBUG(10,("set_domain_online_request: called for domain %s\n",
175 if (get_global_winbindd_state_offline()) {
176 DEBUG(10,("set_domain_online_request: domain %s remaining globally offline\n",
181 /* We've been told it's safe to go online and
182 try and connect to a DC. But I don't believe it...
183 Wait at least 5 seconds. Heuristics suck... */
185 if (!domain->check_online_event) {
186 DEBUG(5,("set_domain_online_request: no check_domain_online_handler "
187 "registered. Were we online (%d) ?\n", (int)domain->online ));
193 set_event_dispatch_time("check_domain_online_handler", tev);
197 /****************************************************************
198 Add -ve connection cache entries for domain and realm.
199 ****************************************************************/
201 void winbind_add_failed_connection_entry(const struct winbindd_domain *domain,
205 add_failed_connection_entry(domain->name, server, result);
206 /* If this was the saf name for the last thing we talked to,
208 saf_delete(domain->name, server);
209 if (*domain->alt_name) {
210 add_failed_connection_entry(domain->alt_name, server, result);
211 saf_delete(domain->alt_name, server);
215 /* Choose between anonymous or authenticated connections. We need to use
216 an authenticated connection if DCs have the RestrictAnonymous registry
217 entry set > 0, or the "Additional restrictions for anonymous
218 connections" set in the win2k Local Security Policy.
220 Caller to free() result in domain, username, password
223 static void cm_get_ipc_userpass(char **username, char **domain, char **password)
225 *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
226 *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
227 *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
229 if (*username && **username) {
231 if (!*domain || !**domain)
232 *domain = smb_xstrdup(lp_workgroup());
234 if (!*password || !**password)
235 *password = smb_xstrdup("");
237 DEBUG(3, ("cm_get_ipc_userpass: Retrieved auth-user from secrets.tdb [%s\\%s]\n",
238 *domain, *username));
241 DEBUG(3, ("cm_get_ipc_userpass: No auth-user defined\n"));
242 *username = smb_xstrdup("");
243 *domain = smb_xstrdup("");
244 *password = smb_xstrdup("");
248 static BOOL get_dc_name_via_netlogon(const struct winbindd_domain *domain,
249 fstring dcname, struct in_addr *dc_ip)
251 struct winbindd_domain *our_domain = NULL;
252 struct rpc_pipe_client *netlogon_pipe = NULL;
259 /* Hmmmm. We can only open one connection to the NETLOGON pipe at the
266 if (domain->primary) {
270 our_domain = find_our_domain();
272 if ((mem_ctx = talloc_init("get_dc_name_via_netlogon")) == NULL) {
276 result = cm_connect_netlogon(our_domain, &netlogon_pipe);
277 if (!NT_STATUS_IS_OK(result)) {
281 result = rpccli_netlogon_getdcname(netlogon_pipe, mem_ctx, our_domain->dcname,
284 talloc_destroy(mem_ctx);
286 if (!NT_STATUS_IS_OK(result)) {
287 DEBUG(10, ("rpccli_netlogon_getdcname failed: %s\n",
292 /* cli_netlogon_getdcname gives us a name with \\ */
303 DEBUG(10, ("rpccli_netlogon_getdcname returned %s\n", dcname));
305 if (!resolve_name(dcname, dc_ip, 0x20)) {
312 /************************************************************************
313 Given a fd with a just-connected TCP connection to a DC, open a connection
315 ************************************************************************/
317 static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
319 const char *controller,
320 struct cli_state **cli,
323 char *machine_password, *machine_krb5_principal, *machine_account;
324 char *ipc_username, *ipc_domain, *ipc_password;
328 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
330 struct sockaddr peeraddr;
331 socklen_t peeraddr_len;
333 struct sockaddr_in *peeraddr_in = (struct sockaddr_in *)&peeraddr;
335 DEBUG(10,("cm_prepare_connection: connecting to DC %s for domain %s\n",
336 controller, domain->name ));
338 machine_password = secrets_fetch_machine_password(lp_workgroup(), NULL,
341 if (asprintf(&machine_account, "%s$", global_myname()) == -1) {
342 SAFE_FREE(machine_password);
343 return NT_STATUS_NO_MEMORY;
346 if (asprintf(&machine_krb5_principal, "%s$@%s", global_myname(),
348 SAFE_FREE(machine_account);
349 SAFE_FREE(machine_password);
350 return NT_STATUS_NO_MEMORY;
353 cm_get_ipc_userpass(&ipc_username, &ipc_domain, &ipc_password);
357 got_mutex = secrets_named_mutex(controller,
358 WINBIND_SERVER_MUTEX_WAIT_TIME);
361 DEBUG(0,("cm_prepare_connection: mutex grab failed for %s\n",
363 result = NT_STATUS_POSSIBLE_DEADLOCK;
367 if ((*cli = cli_initialise()) == NULL) {
368 DEBUG(1, ("Could not cli_initialize\n"));
369 result = NT_STATUS_NO_MEMORY;
373 (*cli)->timeout = 10000; /* 10 seconds */
375 fstrcpy((*cli)->desthost, controller);
376 (*cli)->use_kerberos = True;
378 peeraddr_len = sizeof(peeraddr);
380 if ((getpeername((*cli)->fd, &peeraddr, &peeraddr_len) != 0) ||
381 (peeraddr_len != sizeof(struct sockaddr_in)) ||
382 (peeraddr_in->sin_family != PF_INET))
384 DEBUG(0,("cm_prepare_connection: %s\n", strerror(errno)));
385 result = NT_STATUS_UNSUCCESSFUL;
389 if (ntohs(peeraddr_in->sin_port) == 139) {
390 struct nmb_name calling;
391 struct nmb_name called;
393 make_nmb_name(&calling, global_myname(), 0x0);
394 make_nmb_name(&called, "*SMBSERVER", 0x20);
396 if (!cli_session_request(*cli, &calling, &called)) {
397 DEBUG(8, ("cli_session_request failed for %s\n",
399 result = NT_STATUS_UNSUCCESSFUL;
404 cli_setup_signing_state(*cli, Undefined);
406 if (!cli_negprot(*cli)) {
407 DEBUG(1, ("cli_negprot failed\n"));
408 result = NT_STATUS_UNSUCCESSFUL;
412 if ((*cli)->protocol >= PROTOCOL_NT1 && (*cli)->capabilities & CAP_EXTENDED_SECURITY) {
413 ADS_STATUS ads_status;
415 if (lp_security() == SEC_ADS) {
417 /* Try a krb5 session */
419 (*cli)->use_kerberos = True;
420 DEBUG(5, ("connecting to %s from %s with kerberos principal "
421 "[%s]\n", controller, global_myname(),
422 machine_krb5_principal));
424 ads_status = cli_session_setup_spnego(*cli,
425 machine_krb5_principal,
429 if (!ADS_ERR_OK(ads_status)) {
430 DEBUG(4,("failed kerberos session setup with %s\n",
431 ads_errstr(ads_status)));
434 result = ads_ntstatus(ads_status);
435 if (NT_STATUS_IS_OK(result)) {
436 /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
437 cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
438 goto session_setup_done;
442 /* Fall back to non-kerberos session setup using NTLMSSP SPNEGO with the machine account. */
443 (*cli)->use_kerberos = False;
445 DEBUG(5, ("connecting to %s from %s with username "
446 "[%s]\\[%s]\n", controller, global_myname(),
447 lp_workgroup(), machine_account));
449 ads_status = cli_session_setup_spnego(*cli,
453 if (!ADS_ERR_OK(ads_status)) {
454 DEBUG(4, ("authenticated session setup failed with %s\n",
455 ads_errstr(ads_status)));
458 result = ads_ntstatus(ads_status);
459 if (NT_STATUS_IS_OK(result)) {
460 /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
461 cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
462 goto session_setup_done;
466 /* Fall back to non-kerberos session setup */
468 (*cli)->use_kerberos = False;
470 if ((((*cli)->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) != 0) &&
471 (strlen(ipc_username) > 0)) {
473 /* Only try authenticated if we have a username */
475 DEBUG(5, ("connecting to %s from %s with username "
476 "[%s]\\[%s]\n", controller, global_myname(),
477 ipc_domain, ipc_username));
479 if (NT_STATUS_IS_OK(cli_session_setup(
481 ipc_password, strlen(ipc_password)+1,
482 ipc_password, strlen(ipc_password)+1,
484 /* Successful logon with given username. */
485 cli_init_creds(*cli, ipc_username, ipc_domain, ipc_password);
486 goto session_setup_done;
488 DEBUG(4, ("authenticated session setup with user %s\\%s failed.\n",
489 ipc_domain, ipc_username ));
493 /* Fall back to anonymous connection, this might fail later */
495 if (NT_STATUS_IS_OK(cli_session_setup(*cli, "", NULL, 0,
497 DEBUG(5, ("Connected anonymously\n"));
498 cli_init_creds(*cli, "", "", "");
499 goto session_setup_done;
502 result = cli_nt_error(*cli);
504 if (NT_STATUS_IS_OK(result))
505 result = NT_STATUS_UNSUCCESSFUL;
507 /* We can't session setup */
513 /* cache the server name for later connections */
515 saf_store( domain->name, (*cli)->desthost );
516 if (domain->alt_name && (*cli)->use_kerberos) {
517 saf_store( domain->alt_name, (*cli)->desthost );
520 if (!cli_send_tconX(*cli, "IPC$", "IPC", "", 0)) {
522 result = cli_nt_error(*cli);
524 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(result)));
526 if (NT_STATUS_IS_OK(result))
527 result = NT_STATUS_UNSUCCESSFUL;
532 secrets_named_mutex_release(controller);
536 /* set the domain if empty; needed for schannel connections */
537 if ( !*(*cli)->domain ) {
538 fstrcpy( (*cli)->domain, domain->name );
541 result = NT_STATUS_OK;
545 secrets_named_mutex_release(controller);
548 SAFE_FREE(machine_account);
549 SAFE_FREE(machine_password);
550 SAFE_FREE(machine_krb5_principal);
551 SAFE_FREE(ipc_username);
552 SAFE_FREE(ipc_domain);
553 SAFE_FREE(ipc_password);
555 if (!NT_STATUS_IS_OK(result)) {
556 winbind_add_failed_connection_entry(domain, controller, result);
557 if ((*cli) != NULL) {
571 static BOOL add_one_dc_unique(TALLOC_CTX *mem_ctx, const char *domain_name,
572 const char *dcname, struct in_addr ip,
573 struct dc_name_ip **dcs, int *num)
575 if (!NT_STATUS_IS_OK(check_negative_conn_cache(domain_name, dcname))) {
576 DEBUG(10, ("DC %s was in the negative conn cache\n", dcname));
580 *dcs = TALLOC_REALLOC_ARRAY(mem_ctx, *dcs, struct dc_name_ip, (*num)+1);
585 fstrcpy((*dcs)[*num].name, dcname);
586 (*dcs)[*num].ip = ip;
591 static BOOL add_sockaddr_to_array(TALLOC_CTX *mem_ctx,
592 struct in_addr ip, uint16 port,
593 struct sockaddr_in **addrs, int *num)
595 *addrs = TALLOC_REALLOC_ARRAY(mem_ctx, *addrs, struct sockaddr_in, (*num)+1);
600 (*addrs)[*num].sin_family = PF_INET;
601 putip((char *)&((*addrs)[*num].sin_addr), (char *)&ip);
602 (*addrs)[*num].sin_port = htons(port);
608 static void mailslot_name(struct in_addr dc_ip, fstring name)
610 fstr_sprintf(name, "\\MAILSLOT\\NET\\GETDC%X", dc_ip.s_addr);
613 static BOOL send_getdc_request(struct in_addr dc_ip,
614 const char *domain_name,
619 fstring my_acct_name;
622 mailslot_name(dc_ip, my_mailslot);
624 memset(outbuf, '\0', sizeof(outbuf));
628 SCVAL(p, 0, SAMLOGON);
631 SCVAL(p, 0, 0); /* Count pointer ... */
634 SIVAL(p, 0, 0); /* The sender's token ... */
637 p += dos_PutUniCode(p, global_myname(), sizeof(pstring), True);
638 fstr_sprintf(my_acct_name, "%s$", global_myname());
639 p += dos_PutUniCode(p, my_acct_name, sizeof(pstring), True);
641 memcpy(p, my_mailslot, strlen(my_mailslot)+1);
642 p += strlen(my_mailslot)+1;
647 SIVAL(p, 0, sid_size(sid));
650 p = ALIGN4(p, outbuf);
652 sid_linearize(p, sid_size(sid), sid);
660 return cli_send_mailslot(False, "\\MAILSLOT\\NET\\NTLOGON", 0,
661 outbuf, PTR_DIFF(p, outbuf),
662 global_myname(), 0, domain_name, 0x1c,
666 static BOOL receive_getdc_response(struct in_addr dc_ip,
667 const char *domain_name,
670 struct packet_struct *packet;
673 fstring dcname, user, domain;
676 mailslot_name(dc_ip, my_mailslot);
678 packet = receive_unexpected(DGRAM_PACKET, 0, my_mailslot);
680 if (packet == NULL) {
681 DEBUG(5, ("Did not receive packet for %s\n", my_mailslot));
685 DEBUG(5, ("Received packet for %s\n", my_mailslot));
687 buf = packet->packet.dgram.data;
688 len = packet->packet.dgram.datasize;
691 /* 70 is a completely arbitrary value to make sure
692 the SVAL below does not read uninitialized memory */
693 DEBUG(3, ("GetDC got short response\n"));
697 /* This should be (buf-4)+SVAL(buf-4, smb_vwv12)... */
698 p = buf+SVAL(buf, smb_vwv10);
700 if (CVAL(p,0) != SAMLOGON_R) {
701 DEBUG(8, ("GetDC got invalid response type %d\n", CVAL(p, 0)));
706 pull_ucs2(buf, dcname, p, sizeof(dcname), PTR_DIFF(buf+len, p),
707 STR_TERMINATE|STR_NOALIGN);
708 p = skip_unibuf(p, PTR_DIFF(buf+len, p));
709 pull_ucs2(buf, user, p, sizeof(dcname), PTR_DIFF(buf+len, p),
710 STR_TERMINATE|STR_NOALIGN);
711 p = skip_unibuf(p, PTR_DIFF(buf+len, p));
712 pull_ucs2(buf, domain, p, sizeof(dcname), PTR_DIFF(buf+len, p),
713 STR_TERMINATE|STR_NOALIGN);
714 p = skip_unibuf(p, PTR_DIFF(buf+len, p));
716 if (!strequal(domain, domain_name)) {
717 DEBUG(3, ("GetDC: Expected domain %s, got %s\n",
718 domain_name, domain));
723 if (*p == '\\') p += 1;
724 if (*p == '\\') p += 1;
728 DEBUG(10, ("GetDC gave name %s for domain %s\n",
734 /*******************************************************************
735 convert an ip to a name
736 *******************************************************************/
738 static BOOL dcip_to_name( const char *domainname, const char *realm,
739 const DOM_SID *sid, struct in_addr ip, fstring name )
741 struct ip_service ip_list;
747 /* For active directory servers, try to get the ldap server name.
748 None of these failures should be considered critical for now */
750 if (lp_security() == SEC_ADS) {
753 ads = ads_init(realm, domainname, NULL);
754 ads->auth.flags |= ADS_AUTH_NO_BIND;
756 if (ads_try_connect( ads, inet_ntoa(ip) ) ) {
757 char *sitename = sitename_fetch();
758 /* We got a cldap packet. */
759 fstrcpy(name, ads->config.ldap_server_name);
760 namecache_store(name, 0x20, 1, &ip_list);
762 DEBUG(10,("dcip_to_name: flags = 0x%x\n", (unsigned int)ads->config.flags));
764 if ((ads->config.flags & ADS_KDC) && ads_sitename_match(ads)) {
765 /* We're going to use this KDC for this realm/domain.
766 If we are using sites, then force the krb5 libs
769 create_local_private_krb5_conf_for_domain(realm,
783 /* try GETDC requests next */
785 if (send_getdc_request(ip, domainname, sid)) {
788 for (i=0; i<5; i++) {
789 if (receive_getdc_response(ip, domainname, name)) {
790 namecache_store(name, 0x20, 1, &ip_list);
797 /* try node status request */
799 if ( name_status_find(domainname, 0x1c, 0x20, ip, name) ) {
800 namecache_store(name, 0x20, 1, &ip_list);
806 /*******************************************************************
807 Retreive a list of IP address for domain controllers. Fill in
808 the dcs[] with results.
809 *******************************************************************/
811 static BOOL get_dcs(TALLOC_CTX *mem_ctx, const struct winbindd_domain *domain,
812 struct dc_name_ip **dcs, int *num_dcs)
816 struct ip_service *ip_list = NULL;
820 enum security_types sec = (enum security_types)lp_security();
822 is_our_domain = strequal(domain->name, lp_workgroup());
825 && get_dc_name_via_netlogon(domain, dcname, &ip)
826 && add_one_dc_unique(mem_ctx, domain->name, dcname, ip, dcs, num_dcs) )
828 DEBUG(10, ("Retrieved DC %s at %s via netlogon\n",
829 dcname, inet_ntoa(ip)));
834 if (sec == SEC_ADS) {
835 /* We need to make sure we know the local site before
836 doing any DNS queries, as this will restrict the
837 get_sorted_dc_list() call below to only fetching
838 DNS records for the correct site. */
840 /* Find any DC to get the site record.
841 We deliberately don't care about the
843 get_dc_name(domain->name, lp_realm(), dcname, &ip);
847 /* try standard netbios queries first */
849 get_sorted_dc_list(domain->name, &ip_list, &iplist_size, False);
851 /* check for security = ads and use DNS if we can */
853 if ( iplist_size==0 && sec == SEC_ADS )
854 get_sorted_dc_list(domain->alt_name, &ip_list, &iplist_size, True);
856 /* FIXME!! this is where we should re-insert the GETDC requests --jerry */
858 /* now add to the dc array. We'll wait until the last minute
859 to look up the name of the DC. But we fill in the char* for
860 the ip now in to make the failed connection cache work */
862 for ( i=0; i<iplist_size; i++ ) {
863 add_one_dc_unique(mem_ctx, domain->name, inet_ntoa(ip_list[i].ip),
864 ip_list[i].ip, dcs, num_dcs);
867 SAFE_FREE( ip_list );
872 static BOOL find_new_dc(TALLOC_CTX *mem_ctx,
873 const struct winbindd_domain *domain,
874 fstring dcname, struct sockaddr_in *addr, int *fd)
876 struct dc_name_ip *dcs = NULL;
879 const char **dcnames = NULL;
882 struct sockaddr_in *addrs = NULL;
888 if (!get_dcs(mem_ctx, domain, &dcs, &num_dcs) || (num_dcs == 0))
891 for (i=0; i<num_dcs; i++) {
893 add_string_to_array(mem_ctx, dcs[i].name,
894 &dcnames, &num_dcnames);
895 add_sockaddr_to_array(mem_ctx, dcs[i].ip, 445,
898 add_string_to_array(mem_ctx, dcs[i].name,
899 &dcnames, &num_dcnames);
900 add_sockaddr_to_array(mem_ctx, dcs[i].ip, 139,
904 if ((num_dcnames == 0) || (num_dcnames != num_addrs))
907 if ((addrs == NULL) || (dcnames == NULL))
910 /* 5 second timeout. */
911 if ( !open_any_socket_out(addrs, num_addrs, 5000, &fd_index, fd) )
913 for (i=0; i<num_dcs; i++) {
914 DEBUG(10, ("find_new_dc: open_any_socket_out failed for "
915 "domain %s address %s. Error was %s\n",
916 domain->name, inet_ntoa(dcs[i].ip), strerror(errno) ));
917 winbind_add_failed_connection_entry(domain,
918 dcs[i].name, NT_STATUS_UNSUCCESSFUL);
923 *addr = addrs[fd_index];
925 if (*dcnames[fd_index] != '\0' && !is_ipaddress(dcnames[fd_index])) {
926 /* Ok, we've got a name for the DC */
927 fstrcpy(dcname, dcnames[fd_index]);
931 /* Try to figure out the name */
932 if (dcip_to_name( domain->name, domain->alt_name, &domain->sid,
933 addr->sin_addr, dcname )) {
937 /* We can not continue without the DC's name */
938 winbind_add_failed_connection_entry(domain, dcs[fd_index].name,
939 NT_STATUS_UNSUCCESSFUL);
943 static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
944 struct winbindd_cm_conn *new_conn)
948 char *saf_servername = saf_fetch( domain->name );
951 if ((mem_ctx = talloc_init("cm_open_connection")) == NULL) {
952 SAFE_FREE(saf_servername);
953 set_domain_offline(domain);
954 return NT_STATUS_NO_MEMORY;
957 /* we have to check the server affinity cache here since
958 later we selecte a DC based on response time and not preference */
960 /* Check the negative connection cache
961 before talking to it. It going down may have
962 triggered the reconnection. */
964 if ( saf_servername && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, saf_servername))) {
966 DEBUG(10,("cm_open_connection: saf_servername is '%s' for domain %s\n",
967 saf_servername, domain->name ));
969 /* convert an ip address to a name */
970 if ( is_ipaddress( saf_servername ) ) {
974 ip = *interpret_addr2( saf_servername );
975 if (dcip_to_name( domain->name, domain->alt_name,
976 &domain->sid, ip, saf_name )) {
977 fstrcpy( domain->dcname, saf_name );
979 winbind_add_failed_connection_entry(
980 domain, saf_servername,
981 NT_STATUS_UNSUCCESSFUL);
984 fstrcpy( domain->dcname, saf_servername );
987 SAFE_FREE( saf_servername );
990 for (retries = 0; retries < 3; retries++) {
995 result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
997 DEBUG(10,("cm_open_connection: dcname is '%s' for domain %s\n",
998 domain->dcname, domain->name ));
1001 && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, domain->dcname))
1002 && (resolve_name(domain->dcname, &domain->dcaddr.sin_addr, 0x20)))
1004 struct sockaddr_in *addrs = NULL;
1008 add_sockaddr_to_array(mem_ctx, domain->dcaddr.sin_addr, 445, &addrs, &num_addrs);
1009 add_sockaddr_to_array(mem_ctx, domain->dcaddr.sin_addr, 139, &addrs, &num_addrs);
1011 /* 5 second timeout. */
1012 if (!open_any_socket_out(addrs, num_addrs, 5000, &dummy, &fd)) {
1018 && !find_new_dc(mem_ctx, domain, domain->dcname, &domain->dcaddr, &fd))
1020 /* This is the one place where we will
1021 set the global winbindd offline state
1022 to true, if a "WINBINDD_OFFLINE" entry
1023 is found in the winbindd cache. */
1024 set_global_winbindd_state_offline();
1028 new_conn->cli = NULL;
1030 result = cm_prepare_connection(domain, fd, domain->dcname,
1031 &new_conn->cli, &retry);
1037 if (NT_STATUS_IS_OK(result)) {
1038 if (domain->online == False) {
1039 /* We're changing state from offline to online. */
1040 set_global_winbindd_state_online();
1042 set_domain_online(domain);
1044 /* Ensure we setup the retry handler. */
1045 set_domain_offline(domain);
1048 talloc_destroy(mem_ctx);
1052 /* Close down all open pipes on a connection. */
1054 void invalidate_cm_connection(struct winbindd_cm_conn *conn)
1056 /* We're closing down a possibly dead
1057 connection. Don't have impossibly long (10s) timeouts. */
1060 cli_set_timeout(conn->cli, 1000); /* 1 second. */
1063 if (conn->samr_pipe != NULL) {
1064 if (!cli_rpc_pipe_close(conn->samr_pipe)) {
1065 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1067 cli_set_timeout(conn->cli, 500);
1070 conn->samr_pipe = NULL;
1073 if (conn->lsa_pipe != NULL) {
1074 if (!cli_rpc_pipe_close(conn->lsa_pipe)) {
1075 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1077 cli_set_timeout(conn->cli, 500);
1080 conn->lsa_pipe = NULL;
1083 if (conn->netlogon_pipe != NULL) {
1084 if (!cli_rpc_pipe_close(conn->netlogon_pipe)) {
1085 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1087 cli_set_timeout(conn->cli, 500);
1090 conn->netlogon_pipe = NULL;
1094 cli_shutdown(conn->cli);
1100 void close_conns_after_fork(void)
1102 struct winbindd_domain *domain;
1104 for (domain = domain_list(); domain; domain = domain->next) {
1105 if (domain->conn.cli == NULL)
1108 if (domain->conn.cli->fd == -1)
1111 close(domain->conn.cli->fd);
1112 domain->conn.cli->fd = -1;
1116 static BOOL connection_ok(struct winbindd_domain *domain)
1118 if (domain->conn.cli == NULL) {
1119 DEBUG(8, ("connection_ok: Connection to %s for domain %s has NULL "
1120 "cli!\n", domain->dcname, domain->name));
1124 if (!domain->conn.cli->initialised) {
1125 DEBUG(3, ("connection_ok: Connection to %s for domain %s was never "
1126 "initialised!\n", domain->dcname, domain->name));
1130 if (domain->conn.cli->fd == -1) {
1131 DEBUG(3, ("connection_ok: Connection to %s for domain %s has died or was "
1132 "never started (fd == -1)\n",
1133 domain->dcname, domain->name));
1137 if (domain->online == False) {
1138 DEBUG(3, ("connection_ok: Domain %s is offline\n", domain->name));
1145 /* Initialize a new connection up to the RPC BIND. */
1147 static NTSTATUS init_dc_connection(struct winbindd_domain *domain)
1149 if (connection_ok(domain))
1150 return NT_STATUS_OK;
1152 invalidate_cm_connection(&domain->conn);
1154 return cm_open_connection(domain, &domain->conn);
1157 /******************************************************************************
1158 We can 'sense' certain things about the DC by it's replies to certain
1161 This tells us if this particular remote server is Active Directory, and if it
1163 ******************************************************************************/
1165 void set_dc_type_and_flags( struct winbindd_domain *domain )
1169 TALLOC_CTX *mem_ctx = NULL;
1170 struct rpc_pipe_client *cli;
1173 char *domain_name = NULL;
1174 char *dns_name = NULL;
1175 DOM_SID *dom_sid = NULL;
1180 domain->native_mode = False;
1181 domain->active_directory = False;
1183 if (domain->internal) {
1184 domain->initialized = True;
1190 result = init_dc_connection(domain);
1191 if (!NT_STATUS_IS_OK(result) || try_count > 2) {
1192 DEBUG(5, ("set_dc_type_and_flags: Could not open a connection "
1193 "to %s: (%s)\n", domain->name, nt_errstr(result)));
1194 domain->initialized = True;
1198 cli = cli_rpc_pipe_open_noauth(domain->conn.cli, PI_LSARPC_DS,
1202 DEBUG(5, ("set_dc_type_and_flags: Could not bind to "
1203 "PI_LSARPC_DS on domain %s: (%s)\n",
1204 domain->name, nt_errstr(result)));
1205 domain->initialized = True;
1206 /* We want to detect network failures asap to try another dc. */
1211 result = rpccli_ds_getprimarydominfo(cli, cli->cli->mem_ctx,
1212 DsRolePrimaryDomainInfoBasic,
1214 cli_rpc_pipe_close(cli);
1216 if (!NT_STATUS_IS_OK(result)) {
1217 domain->initialized = True;
1221 if ((ctr.basic->flags & DSROLE_PRIMARY_DS_RUNNING) &&
1222 !(ctr.basic->flags & DSROLE_PRIMARY_DS_MIXED_MODE) )
1223 domain->native_mode = True;
1225 cli = cli_rpc_pipe_open_noauth(domain->conn.cli, PI_LSARPC, &result);
1228 domain->initialized = True;
1229 /* We want to detect network failures asap to try another dc. */
1234 mem_ctx = talloc_init("set_dc_type_and_flags on domain %s\n",
1237 DEBUG(1, ("set_dc_type_and_flags: talloc_init() failed\n"));
1238 cli_rpc_pipe_close(cli);
1242 result = rpccli_lsa_open_policy2(cli, mem_ctx, True,
1243 SEC_RIGHTS_MAXIMUM_ALLOWED, &pol);
1245 if (NT_STATUS_IS_OK(result)) {
1246 /* This particular query is exactly what Win2k clients use
1247 to determine that the DC is active directory */
1248 result = rpccli_lsa_query_info_policy2(cli, mem_ctx, &pol,
1254 if (NT_STATUS_IS_OK(result)) {
1256 fstrcpy(domain->name, domain_name);
1259 fstrcpy(domain->alt_name, dns_name);
1262 sid_copy(&domain->sid, dom_sid);
1264 domain->active_directory = True;
1267 result = rpccli_lsa_open_policy(cli, mem_ctx, True,
1268 SEC_RIGHTS_MAXIMUM_ALLOWED,
1271 if (!NT_STATUS_IS_OK(result))
1274 result = rpccli_lsa_query_info_policy(cli, mem_ctx,
1275 &pol, 5, &domain_name,
1278 if (NT_STATUS_IS_OK(result)) {
1280 fstrcpy(domain->name, domain_name);
1283 sid_copy(&domain->sid, dom_sid);
1288 cli_rpc_pipe_close(cli);
1290 talloc_destroy(mem_ctx);
1292 domain->initialized = True;
1297 static BOOL cm_get_schannel_dcinfo(struct winbindd_domain *domain,
1298 struct dcinfo **ppdc)
1301 struct rpc_pipe_client *netlogon_pipe;
1303 if (lp_client_schannel() == False) {
1307 result = cm_connect_netlogon(domain, &netlogon_pipe);
1308 if (!NT_STATUS_IS_OK(result)) {
1312 /* Return a pointer to the struct dcinfo from the
1315 *ppdc = domain->conn.netlogon_pipe->dc;
1319 NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
1320 struct rpc_pipe_client **cli, POLICY_HND *sam_handle)
1322 struct winbindd_cm_conn *conn;
1325 struct dcinfo *p_dcinfo;
1327 result = init_dc_connection(domain);
1328 if (!NT_STATUS_IS_OK(result)) {
1332 conn = &domain->conn;
1334 if (conn->samr_pipe != NULL) {
1339 * No SAMR pipe yet. Attempt to get an NTLMSSP SPNEGO authenticated
1340 * sign and sealed pipe using the machine account password by
1341 * preference. If we can't - try schannel, if that fails, try
1345 pwd_get_cleartext(&conn->cli->pwd, conn_pwd);
1346 if ((conn->cli->user_name[0] == '\0') ||
1347 (conn->cli->domain[0] == '\0') ||
1348 (conn_pwd[0] == '\0')) {
1349 DEBUG(10, ("cm_connect_sam: No no user available for "
1350 "domain %s, trying schannel\n", conn->cli->domain));
1354 /* We have an authenticated connection. Use a NTLMSSP SPNEGO
1355 authenticated SAMR pipe with sign & seal. */
1357 cli_rpc_pipe_open_spnego_ntlmssp(conn->cli, PI_SAMR,
1358 PIPE_AUTH_LEVEL_PRIVACY,
1360 conn->cli->user_name,
1363 if (conn->samr_pipe == NULL) {
1364 DEBUG(10,("cm_connect_sam: failed to connect to SAMR "
1365 "pipe for domain %s using NTLMSSP "
1366 "authenticated pipe: user %s\\%s. Error was "
1367 "%s\n", domain->name, conn->cli->domain,
1368 conn->cli->user_name, nt_errstr(result)));
1372 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for "
1373 "domain %s using NTLMSSP authenticated "
1374 "pipe: user %s\\%s\n", domain->name,
1375 conn->cli->domain, conn->cli->user_name ));
1377 result = rpccli_samr_connect(conn->samr_pipe, mem_ctx,
1378 SEC_RIGHTS_MAXIMUM_ALLOWED,
1379 &conn->sam_connect_handle);
1380 if (NT_STATUS_IS_OK(result)) {
1383 DEBUG(10,("cm_connect_sam: ntlmssp-sealed rpccli_samr_connect "
1384 "failed for domain %s, error was %s. Trying schannel\n",
1385 domain->name, nt_errstr(result) ));
1386 cli_rpc_pipe_close(conn->samr_pipe);
1390 /* Fall back to schannel if it's a W2K pre-SP1 box. */
1392 if (!cm_get_schannel_dcinfo(domain, &p_dcinfo)) {
1393 DEBUG(10, ("cm_connect_sam: Could not get schannel auth info "
1394 "for domain %s, trying anon\n", conn->cli->domain));
1397 conn->samr_pipe = cli_rpc_pipe_open_schannel_with_key
1398 (conn->cli, PI_SAMR, PIPE_AUTH_LEVEL_PRIVACY,
1399 domain->name, p_dcinfo, &result);
1401 if (conn->samr_pipe == NULL) {
1402 DEBUG(10,("cm_connect_sam: failed to connect to SAMR pipe for "
1403 "domain %s using schannel. Error was %s\n",
1404 domain->name, nt_errstr(result) ));
1407 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for domain %s using "
1408 "schannel.\n", domain->name ));
1410 result = rpccli_samr_connect(conn->samr_pipe, mem_ctx,
1411 SEC_RIGHTS_MAXIMUM_ALLOWED,
1412 &conn->sam_connect_handle);
1413 if (NT_STATUS_IS_OK(result)) {
1416 DEBUG(10,("cm_connect_sam: schannel-sealed rpccli_samr_connect failed "
1417 "for domain %s, error was %s. Trying anonymous\n",
1418 domain->name, nt_errstr(result) ));
1419 cli_rpc_pipe_close(conn->samr_pipe);
1423 /* Finally fall back to anonymous. */
1424 conn->samr_pipe = cli_rpc_pipe_open_noauth(conn->cli, PI_SAMR,
1427 if (conn->samr_pipe == NULL) {
1428 result = NT_STATUS_PIPE_NOT_AVAILABLE;
1432 result = rpccli_samr_connect(conn->samr_pipe, mem_ctx,
1433 SEC_RIGHTS_MAXIMUM_ALLOWED,
1434 &conn->sam_connect_handle);
1435 if (!NT_STATUS_IS_OK(result)) {
1436 DEBUG(10,("cm_connect_sam: rpccli_samr_connect failed "
1437 "for domain %s Error was %s\n",
1438 domain->name, nt_errstr(result) ));
1443 result = rpccli_samr_open_domain(conn->samr_pipe,
1445 &conn->sam_connect_handle,
1446 SEC_RIGHTS_MAXIMUM_ALLOWED,
1448 &conn->sam_domain_handle);
1452 if (!NT_STATUS_IS_OK(result)) {
1453 invalidate_cm_connection(conn);
1457 *cli = conn->samr_pipe;
1458 *sam_handle = conn->sam_domain_handle;
1462 NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
1463 struct rpc_pipe_client **cli, POLICY_HND *lsa_policy)
1465 struct winbindd_cm_conn *conn;
1468 struct dcinfo *p_dcinfo;
1470 result = init_dc_connection(domain);
1471 if (!NT_STATUS_IS_OK(result))
1474 conn = &domain->conn;
1476 if (conn->lsa_pipe != NULL) {
1480 pwd_get_cleartext(&conn->cli->pwd, conn_pwd);
1481 if ((conn->cli->user_name[0] == '\0') ||
1482 (conn->cli->domain[0] == '\0') ||
1483 (conn_pwd[0] == '\0')) {
1484 DEBUG(10, ("cm_connect_lsa: No no user available for "
1485 "domain %s, trying schannel\n", conn->cli->domain));
1489 /* We have an authenticated connection. Use a NTLMSSP SPNEGO
1490 * authenticated LSA pipe with sign & seal. */
1491 conn->lsa_pipe = cli_rpc_pipe_open_spnego_ntlmssp
1492 (conn->cli, PI_LSARPC, PIPE_AUTH_LEVEL_PRIVACY,
1493 conn->cli->domain, conn->cli->user_name, conn_pwd, &result);
1495 if (conn->lsa_pipe == NULL) {
1496 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
1497 "domain %s using NTLMSSP authenticated pipe: user "
1498 "%s\\%s. Error was %s. Trying schannel.\n",
1499 domain->name, conn->cli->domain,
1500 conn->cli->user_name, nt_errstr(result)));
1504 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
1505 "NTLMSSP authenticated pipe: user %s\\%s\n",
1506 domain->name, conn->cli->domain, conn->cli->user_name ));
1508 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
1509 SEC_RIGHTS_MAXIMUM_ALLOWED,
1511 if (NT_STATUS_IS_OK(result)) {
1515 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
1518 cli_rpc_pipe_close(conn->lsa_pipe);
1522 /* Fall back to schannel if it's a W2K pre-SP1 box. */
1524 if (!cm_get_schannel_dcinfo(domain, &p_dcinfo)) {
1525 DEBUG(10, ("cm_connect_lsa: Could not get schannel auth info "
1526 "for domain %s, trying anon\n", conn->cli->domain));
1529 conn->lsa_pipe = cli_rpc_pipe_open_schannel_with_key
1530 (conn->cli, PI_LSARPC, PIPE_AUTH_LEVEL_PRIVACY,
1531 domain->name, p_dcinfo, &result);
1533 if (conn->lsa_pipe == NULL) {
1534 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
1535 "domain %s using schannel. Error was %s\n",
1536 domain->name, nt_errstr(result) ));
1539 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
1540 "schannel.\n", domain->name ));
1542 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
1543 SEC_RIGHTS_MAXIMUM_ALLOWED,
1545 if (NT_STATUS_IS_OK(result)) {
1549 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
1552 cli_rpc_pipe_close(conn->lsa_pipe);
1556 conn->lsa_pipe = cli_rpc_pipe_open_noauth(conn->cli, PI_LSARPC,
1558 if (conn->lsa_pipe == NULL) {
1559 result = NT_STATUS_PIPE_NOT_AVAILABLE;
1563 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
1564 SEC_RIGHTS_MAXIMUM_ALLOWED,
1567 if (!NT_STATUS_IS_OK(result)) {
1568 invalidate_cm_connection(conn);
1569 return NT_STATUS_UNSUCCESSFUL;
1572 *cli = conn->lsa_pipe;
1573 *lsa_policy = conn->lsa_policy;
1577 /****************************************************************************
1578 Open the netlogon pipe to this DC. Use schannel if specified in client conf.
1579 session key stored in conn->netlogon_pipe->dc->sess_key.
1580 ****************************************************************************/
1582 NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
1583 struct rpc_pipe_client **cli)
1585 struct winbindd_cm_conn *conn;
1588 uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
1590 uint32 sec_chan_type;
1591 const char *account_name;
1592 struct rpc_pipe_client *netlogon_pipe = NULL;
1596 result = init_dc_connection(domain);
1597 if (!NT_STATUS_IS_OK(result)) {
1601 conn = &domain->conn;
1603 if (conn->netlogon_pipe != NULL) {
1604 *cli = conn->netlogon_pipe;
1605 return NT_STATUS_OK;
1608 if (!get_trust_pw(domain->name, mach_pwd, &sec_chan_type)) {
1609 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1612 netlogon_pipe = cli_rpc_pipe_open_noauth(conn->cli, PI_NETLOGON,
1614 if (netlogon_pipe == NULL) {
1618 if (lp_client_schannel() != False) {
1619 neg_flags |= NETLOGON_NEG_SCHANNEL;
1622 /* if we are a DC and this is a trusted domain, then we need to use our
1623 domain name in the net_req_auth2() request */
1626 && !strequal(domain->name, lp_workgroup())
1627 && lp_allow_trusted_domains() )
1629 account_name = lp_workgroup();
1631 account_name = domain->primary ?
1632 global_myname() : domain->name;
1635 if (account_name == NULL) {
1636 cli_rpc_pipe_close(netlogon_pipe);
1637 return NT_STATUS_NO_MEMORY;
1640 result = rpccli_netlogon_setup_creds(
1642 domain->dcname, /* server name. */
1643 domain->name, /* domain name */
1644 global_myname(), /* client name */
1645 account_name, /* machine account */
1646 mach_pwd, /* machine password */
1647 sec_chan_type, /* from get_trust_pw */
1650 if (!NT_STATUS_IS_OK(result)) {
1651 cli_rpc_pipe_close(netlogon_pipe);
1655 if ((lp_client_schannel() == True) &&
1656 ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
1657 DEBUG(3, ("Server did not offer schannel\n"));
1658 cli_rpc_pipe_close(netlogon_pipe);
1659 return NT_STATUS_ACCESS_DENIED;
1662 if ((lp_client_schannel() == False) ||
1663 ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
1664 /* We're done - just keep the existing connection to NETLOGON
1666 conn->netlogon_pipe = netlogon_pipe;
1667 *cli = conn->netlogon_pipe;
1668 return NT_STATUS_OK;
1671 /* Using the credentials from the first pipe, open a signed and sealed
1672 second netlogon pipe. The session key is stored in the schannel
1673 part of the new pipe auth struct.
1676 conn->netlogon_pipe =
1677 cli_rpc_pipe_open_schannel_with_key(conn->cli,
1679 PIPE_AUTH_LEVEL_PRIVACY,
1684 /* We can now close the initial netlogon pipe. */
1685 cli_rpc_pipe_close(netlogon_pipe);
1687 if (conn->netlogon_pipe == NULL) {
1688 DEBUG(3, ("Could not open schannel'ed NETLOGON pipe. Error "
1689 "was %s\n", nt_errstr(result)));
1691 /* make sure we return something besides OK */
1692 return !NT_STATUS_IS_OK(result) ? result : NT_STATUS_PIPE_NOT_AVAILABLE;
1695 *cli = conn->netlogon_pipe;
1696 return NT_STATUS_OK;