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 void set_domain_online(struct winbindd_domain *domain)
149 DEBUG(10,("set_domain_offline: called for domain %s\n",
152 if (get_global_winbindd_state_offline()) {
153 DEBUG(10,("set_domain_online: domain %s remaining globally offline\n",
158 domain->online = True;
161 /****************************************************************
162 Add -ve connection cache entries for domain and realm.
163 ****************************************************************/
165 void winbind_add_failed_connection_entry(const struct winbindd_domain *domain,
169 add_failed_connection_entry(domain->name, server, result);
170 if (*domain->alt_name) {
171 add_failed_connection_entry(domain->alt_name, server, result);
175 /* Choose between anonymous or authenticated connections. We need to use
176 an authenticated connection if DCs have the RestrictAnonymous registry
177 entry set > 0, or the "Additional restrictions for anonymous
178 connections" set in the win2k Local Security Policy.
180 Caller to free() result in domain, username, password
183 static void cm_get_ipc_userpass(char **username, char **domain, char **password)
185 *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
186 *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
187 *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
189 if (*username && **username) {
191 if (!*domain || !**domain)
192 *domain = smb_xstrdup(lp_workgroup());
194 if (!*password || !**password)
195 *password = smb_xstrdup("");
197 DEBUG(3, ("cm_get_ipc_userpass: Retrieved auth-user from secrets.tdb [%s\\%s]\n",
198 *domain, *username));
201 DEBUG(3, ("cm_get_ipc_userpass: No auth-user defined\n"));
202 *username = smb_xstrdup("");
203 *domain = smb_xstrdup("");
204 *password = smb_xstrdup("");
208 static BOOL get_dc_name_via_netlogon(const struct winbindd_domain *domain,
209 fstring dcname, struct in_addr *dc_ip)
211 struct winbindd_domain *our_domain = NULL;
212 struct rpc_pipe_client *netlogon_pipe = NULL;
219 /* Hmmmm. We can only open one connection to the NETLOGON pipe at the
226 if (domain->primary) {
230 our_domain = find_our_domain();
232 if ((mem_ctx = talloc_init("get_dc_name_via_netlogon")) == NULL) {
236 result = cm_connect_netlogon(our_domain, &netlogon_pipe);
237 if (!NT_STATUS_IS_OK(result)) {
241 result = rpccli_netlogon_getdcname(netlogon_pipe, mem_ctx, our_domain->dcname,
244 talloc_destroy(mem_ctx);
246 if (!NT_STATUS_IS_OK(result)) {
247 DEBUG(10, ("rpccli_netlogon_getdcname failed: %s\n",
252 /* cli_netlogon_getdcname gives us a name with \\ */
263 DEBUG(10, ("rpccli_netlogon_getdcname returned %s\n", dcname));
265 if (!resolve_name(dcname, dc_ip, 0x20)) {
272 /************************************************************************
273 Given a fd with a just-connected TCP connection to a DC, open a connection
275 ************************************************************************/
277 static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
279 const char *controller,
280 struct cli_state **cli,
283 char *machine_password, *machine_krb5_principal, *machine_account;
284 char *ipc_username, *ipc_domain, *ipc_password;
288 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
290 struct sockaddr peeraddr;
291 socklen_t peeraddr_len;
293 struct sockaddr_in *peeraddr_in = (struct sockaddr_in *)&peeraddr;
295 machine_password = secrets_fetch_machine_password(lp_workgroup(), NULL,
298 if (asprintf(&machine_account, "%s$", global_myname()) == -1) {
299 SAFE_FREE(machine_password);
300 return NT_STATUS_NO_MEMORY;
303 if (asprintf(&machine_krb5_principal, "%s$@%s", global_myname(),
305 SAFE_FREE(machine_account);
306 SAFE_FREE(machine_password);
307 return NT_STATUS_NO_MEMORY;
310 cm_get_ipc_userpass(&ipc_username, &ipc_domain, &ipc_password);
314 got_mutex = secrets_named_mutex(controller,
315 WINBIND_SERVER_MUTEX_WAIT_TIME);
318 DEBUG(0,("cm_prepare_connection: mutex grab failed for %s\n",
320 result = NT_STATUS_POSSIBLE_DEADLOCK;
324 if ((*cli = cli_initialise()) == NULL) {
325 DEBUG(1, ("Could not cli_initialize\n"));
326 result = NT_STATUS_NO_MEMORY;
330 (*cli)->timeout = 10000; /* 10 seconds */
332 fstrcpy((*cli)->desthost, controller);
333 (*cli)->use_kerberos = True;
335 peeraddr_len = sizeof(peeraddr);
337 if ((getpeername((*cli)->fd, &peeraddr, &peeraddr_len) != 0) ||
338 (peeraddr_len != sizeof(struct sockaddr_in)) ||
339 (peeraddr_in->sin_family != PF_INET))
341 DEBUG(0,("cm_prepare_connection: %s\n", strerror(errno)));
342 result = NT_STATUS_UNSUCCESSFUL;
346 if (ntohs(peeraddr_in->sin_port) == 139) {
347 struct nmb_name calling;
348 struct nmb_name called;
350 make_nmb_name(&calling, global_myname(), 0x0);
351 make_nmb_name(&called, "*SMBSERVER", 0x20);
353 if (!cli_session_request(*cli, &calling, &called)) {
354 DEBUG(8, ("cli_session_request failed for %s\n",
356 result = NT_STATUS_UNSUCCESSFUL;
361 cli_setup_signing_state(*cli, Undefined);
363 if (!cli_negprot(*cli)) {
364 DEBUG(1, ("cli_negprot failed\n"));
365 result = NT_STATUS_UNSUCCESSFUL;
369 if ((*cli)->protocol >= PROTOCOL_NT1 && (*cli)->capabilities & CAP_EXTENDED_SECURITY) {
370 ADS_STATUS ads_status;
372 if (lp_security() == SEC_ADS) {
374 /* Try a krb5 session */
376 (*cli)->use_kerberos = True;
377 DEBUG(5, ("connecting to %s from %s with kerberos principal "
378 "[%s]\n", controller, global_myname(),
379 machine_krb5_principal));
381 ads_status = cli_session_setup_spnego(*cli,
382 machine_krb5_principal,
386 if (!ADS_ERR_OK(ads_status)) {
387 DEBUG(4,("failed kerberos session setup with %s\n",
388 ads_errstr(ads_status)));
391 result = ads_ntstatus(ads_status);
392 if (NT_STATUS_IS_OK(result)) {
393 /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
394 cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
395 goto session_setup_done;
399 /* Fall back to non-kerberos session setup using NTLMSSP SPNEGO with the machine account. */
400 (*cli)->use_kerberos = False;
402 DEBUG(5, ("connecting to %s from %s with username "
403 "[%s]\\[%s]\n", controller, global_myname(),
404 lp_workgroup(), machine_account));
406 ads_status = cli_session_setup_spnego(*cli,
410 if (!ADS_ERR_OK(ads_status)) {
411 DEBUG(4, ("authenticated session setup failed with %s\n",
412 ads_errstr(ads_status)));
415 result = ads_ntstatus(ads_status);
416 if (NT_STATUS_IS_OK(result)) {
417 /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
418 cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
419 goto session_setup_done;
423 /* Fall back to non-kerberos session setup */
425 (*cli)->use_kerberos = False;
427 if ((((*cli)->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) != 0) &&
428 (strlen(ipc_username) > 0)) {
430 /* Only try authenticated if we have a username */
432 DEBUG(5, ("connecting to %s from %s with username "
433 "[%s]\\[%s]\n", controller, global_myname(),
434 ipc_domain, ipc_username));
436 if (NT_STATUS_IS_OK(cli_session_setup(
438 ipc_password, strlen(ipc_password)+1,
439 ipc_password, strlen(ipc_password)+1,
441 /* Successful logon with given username. */
442 cli_init_creds(*cli, ipc_username, ipc_domain, ipc_password);
443 goto session_setup_done;
445 DEBUG(4, ("authenticated session setup with user %s\\%s failed.\n",
446 ipc_domain, ipc_username ));
450 /* Fall back to anonymous connection, this might fail later */
452 if (NT_STATUS_IS_OK(cli_session_setup(*cli, "", NULL, 0,
454 DEBUG(5, ("Connected anonymously\n"));
455 cli_init_creds(*cli, "", "", "");
456 goto session_setup_done;
459 result = cli_nt_error(*cli);
461 if (NT_STATUS_IS_OK(result))
462 result = NT_STATUS_UNSUCCESSFUL;
464 /* We can't session setup */
470 /* cache the server name for later connections */
472 saf_store( domain->name, (*cli)->desthost );
473 if (domain->alt_name && (*cli)->use_kerberos) {
474 saf_store( domain->alt_name, (*cli)->desthost );
477 if (!cli_send_tconX(*cli, "IPC$", "IPC", "", 0)) {
479 result = cli_nt_error(*cli);
481 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(result)));
483 if (NT_STATUS_IS_OK(result))
484 result = NT_STATUS_UNSUCCESSFUL;
489 secrets_named_mutex_release(controller);
493 /* set the domain if empty; needed for schannel connections */
494 if ( !*(*cli)->domain ) {
495 fstrcpy( (*cli)->domain, domain->name );
498 result = NT_STATUS_OK;
502 secrets_named_mutex_release(controller);
505 SAFE_FREE(machine_account);
506 SAFE_FREE(machine_password);
507 SAFE_FREE(machine_krb5_principal);
508 SAFE_FREE(ipc_username);
509 SAFE_FREE(ipc_domain);
510 SAFE_FREE(ipc_password);
512 if (!NT_STATUS_IS_OK(result)) {
513 winbind_add_failed_connection_entry(domain, controller, result);
514 if ((*cli) != NULL) {
528 static BOOL add_one_dc_unique(TALLOC_CTX *mem_ctx, const char *domain_name,
529 const char *dcname, struct in_addr ip,
530 struct dc_name_ip **dcs, int *num)
532 if (!NT_STATUS_IS_OK(check_negative_conn_cache(domain_name, dcname))) {
533 DEBUG(10, ("DC %s was in the negative conn cache\n", dcname));
537 *dcs = TALLOC_REALLOC_ARRAY(mem_ctx, *dcs, struct dc_name_ip, (*num)+1);
542 fstrcpy((*dcs)[*num].name, dcname);
543 (*dcs)[*num].ip = ip;
548 static BOOL add_sockaddr_to_array(TALLOC_CTX *mem_ctx,
549 struct in_addr ip, uint16 port,
550 struct sockaddr_in **addrs, int *num)
552 *addrs = TALLOC_REALLOC_ARRAY(mem_ctx, *addrs, struct sockaddr_in, (*num)+1);
557 (*addrs)[*num].sin_family = PF_INET;
558 putip((char *)&((*addrs)[*num].sin_addr), (char *)&ip);
559 (*addrs)[*num].sin_port = htons(port);
565 static void mailslot_name(struct in_addr dc_ip, fstring name)
567 fstr_sprintf(name, "\\MAILSLOT\\NET\\GETDC%X", dc_ip.s_addr);
570 static BOOL send_getdc_request(struct in_addr dc_ip,
571 const char *domain_name,
576 fstring my_acct_name;
579 mailslot_name(dc_ip, my_mailslot);
581 memset(outbuf, '\0', sizeof(outbuf));
585 SCVAL(p, 0, SAMLOGON);
588 SCVAL(p, 0, 0); /* Count pointer ... */
591 SIVAL(p, 0, 0); /* The sender's token ... */
594 p += dos_PutUniCode(p, global_myname(), sizeof(pstring), True);
595 fstr_sprintf(my_acct_name, "%s$", global_myname());
596 p += dos_PutUniCode(p, my_acct_name, sizeof(pstring), True);
598 memcpy(p, my_mailslot, strlen(my_mailslot)+1);
599 p += strlen(my_mailslot)+1;
604 SIVAL(p, 0, sid_size(sid));
607 p = ALIGN4(p, outbuf);
609 sid_linearize(p, sid_size(sid), sid);
617 return cli_send_mailslot(False, "\\MAILSLOT\\NET\\NTLOGON", 0,
618 outbuf, PTR_DIFF(p, outbuf),
619 global_myname(), 0, domain_name, 0x1c,
623 static BOOL receive_getdc_response(struct in_addr dc_ip,
624 const char *domain_name,
627 struct packet_struct *packet;
630 fstring dcname, user, domain;
633 mailslot_name(dc_ip, my_mailslot);
635 packet = receive_unexpected(DGRAM_PACKET, 0, my_mailslot);
637 if (packet == NULL) {
638 DEBUG(5, ("Did not receive packet for %s\n", my_mailslot));
642 DEBUG(5, ("Received packet for %s\n", my_mailslot));
644 buf = packet->packet.dgram.data;
645 len = packet->packet.dgram.datasize;
648 /* 70 is a completely arbitrary value to make sure
649 the SVAL below does not read uninitialized memory */
650 DEBUG(3, ("GetDC got short response\n"));
654 /* This should be (buf-4)+SVAL(buf-4, smb_vwv12)... */
655 p = buf+SVAL(buf, smb_vwv10);
657 if (CVAL(p,0) != SAMLOGON_R) {
658 DEBUG(8, ("GetDC got invalid response type %d\n", CVAL(p, 0)));
663 pull_ucs2(buf, dcname, p, sizeof(dcname), PTR_DIFF(buf+len, p),
664 STR_TERMINATE|STR_NOALIGN);
665 p = skip_unibuf(p, PTR_DIFF(buf+len, p));
666 pull_ucs2(buf, user, p, sizeof(dcname), PTR_DIFF(buf+len, p),
667 STR_TERMINATE|STR_NOALIGN);
668 p = skip_unibuf(p, PTR_DIFF(buf+len, p));
669 pull_ucs2(buf, domain, p, sizeof(dcname), PTR_DIFF(buf+len, p),
670 STR_TERMINATE|STR_NOALIGN);
671 p = skip_unibuf(p, PTR_DIFF(buf+len, p));
673 if (!strequal(domain, domain_name)) {
674 DEBUG(3, ("GetDC: Expected domain %s, got %s\n",
675 domain_name, domain));
680 if (*p == '\\') p += 1;
681 if (*p == '\\') p += 1;
685 DEBUG(10, ("GetDC gave name %s for domain %s\n",
691 /*******************************************************************
692 convert an ip to a name
693 *******************************************************************/
695 static BOOL dcip_to_name( const char *domainname, const char *realm,
696 const DOM_SID *sid, struct in_addr ip, fstring name )
698 struct ip_service ip_list;
704 /* For active directory servers, try to get the ldap server name.
705 None of these failures should be considered critical for now */
707 if (lp_security() == SEC_ADS) {
710 ads = ads_init(realm, domainname, NULL);
711 ads->auth.flags |= ADS_AUTH_NO_BIND;
713 if (ads_try_connect( ads, inet_ntoa(ip) ) ) {
714 char *sitename = sitename_fetch();
715 /* We got a cldap packet. */
716 fstrcpy(name, ads->config.ldap_server_name);
717 namecache_store(name, 0x20, 1, &ip_list);
719 DEBUG(10,("dcip_to_name: flags = 0x%x\n", (unsigned int)ads->config.flags));
721 if ((ads->config.flags & ADS_KDC) && ads_sitename_match(ads)) {
722 /* We're going to use this KDC for this realm/domain.
723 If we are using sites, then force the krb5 libs
726 create_local_private_krb5_conf_for_domain(realm,
740 /* try GETDC requests next */
742 if (send_getdc_request(ip, domainname, sid)) {
745 for (i=0; i<5; i++) {
746 if (receive_getdc_response(ip, domainname, name)) {
747 namecache_store(name, 0x20, 1, &ip_list);
754 /* try node status request */
756 if ( name_status_find(domainname, 0x1c, 0x20, ip, name) ) {
757 namecache_store(name, 0x20, 1, &ip_list);
763 /*******************************************************************
764 Retreive a list of IP address for domain controllers. Fill in
765 the dcs[] with results.
766 *******************************************************************/
768 static BOOL get_dcs(TALLOC_CTX *mem_ctx, const struct winbindd_domain *domain,
769 struct dc_name_ip **dcs, int *num_dcs)
773 struct ip_service *ip_list = NULL;
777 enum security_types sec = (enum security_types)lp_security();
779 is_our_domain = strequal(domain->name, lp_workgroup());
782 && get_dc_name_via_netlogon(domain, dcname, &ip)
783 && add_one_dc_unique(mem_ctx, domain->name, dcname, ip, dcs, num_dcs) )
785 DEBUG(10, ("Retrieved DC %s at %s via netlogon\n",
786 dcname, inet_ntoa(ip)));
791 if (sec == SEC_ADS) {
792 /* We need to make sure we know the local site before
793 doing any DNS queries, as this will restrict the
794 get_sorted_dc_list() call below to only fetching
795 DNS records for the correct site. */
797 /* Find any DC to get the site record.
798 We deliberately don't care about the
800 get_dc_name(domain->name, lp_realm(), dcname, &ip);
804 /* try standard netbios queries first */
806 get_sorted_dc_list(domain->name, &ip_list, &iplist_size, False);
808 /* check for security = ads and use DNS if we can */
810 if ( iplist_size==0 && sec == SEC_ADS )
811 get_sorted_dc_list(domain->alt_name, &ip_list, &iplist_size, True);
813 /* FIXME!! this is where we should re-insert the GETDC requests --jerry */
815 /* now add to the dc array. We'll wait until the last minute
816 to look up the name of the DC. But we fill in the char* for
817 the ip now in to make the failed connection cache work */
819 for ( i=0; i<iplist_size; i++ ) {
820 add_one_dc_unique(mem_ctx, domain->name, inet_ntoa(ip_list[i].ip),
821 ip_list[i].ip, dcs, num_dcs);
824 SAFE_FREE( ip_list );
829 static BOOL find_new_dc(TALLOC_CTX *mem_ctx,
830 const struct winbindd_domain *domain,
831 fstring dcname, struct sockaddr_in *addr, int *fd)
833 struct dc_name_ip *dcs = NULL;
836 const char **dcnames = NULL;
839 struct sockaddr_in *addrs = NULL;
845 if (!get_dcs(mem_ctx, domain, &dcs, &num_dcs) || (num_dcs == 0))
848 for (i=0; i<num_dcs; i++) {
850 add_string_to_array(mem_ctx, dcs[i].name,
851 &dcnames, &num_dcnames);
852 add_sockaddr_to_array(mem_ctx, dcs[i].ip, 445,
855 add_string_to_array(mem_ctx, dcs[i].name,
856 &dcnames, &num_dcnames);
857 add_sockaddr_to_array(mem_ctx, dcs[i].ip, 139,
861 if ((num_dcnames == 0) || (num_dcnames != num_addrs))
864 if ((addrs == NULL) || (dcnames == NULL))
867 /* 5 second timeout. */
868 if ( !open_any_socket_out(addrs, num_addrs, 5000, &fd_index, fd) )
870 for (i=0; i<num_dcs; i++) {
871 winbind_add_failed_connection_entry(domain,
872 dcs[i].name, NT_STATUS_UNSUCCESSFUL);
877 *addr = addrs[fd_index];
879 if (*dcnames[fd_index] != '\0' && !is_ipaddress(dcnames[fd_index])) {
880 /* Ok, we've got a name for the DC */
881 fstrcpy(dcname, dcnames[fd_index]);
885 /* Try to figure out the name */
886 if (dcip_to_name( domain->name, domain->alt_name, &domain->sid,
887 addr->sin_addr, dcname )) {
891 /* We can not continue without the DC's name */
892 winbind_add_failed_connection_entry(domain, dcs[fd_index].name,
893 NT_STATUS_UNSUCCESSFUL);
897 static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
898 struct winbindd_cm_conn *new_conn)
902 char *saf_servername = saf_fetch( domain->name );
905 if ((mem_ctx = talloc_init("cm_open_connection")) == NULL) {
906 SAFE_FREE(saf_servername);
907 set_domain_offline(domain);
908 return NT_STATUS_NO_MEMORY;
911 /* we have to check the server affinity cache here since
912 later we selecte a DC based on response time and not preference */
914 /* Check the negative connection cache
915 before talking to it. It going down may have
916 triggered the reconnection. */
918 if ( saf_servername && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, saf_servername))) {
920 /* convert an ip address to a name */
921 if ( is_ipaddress( saf_servername ) ) {
925 ip = *interpret_addr2( saf_servername );
926 if (dcip_to_name( domain->name, domain->alt_name,
927 &domain->sid, ip, saf_name )) {
928 fstrcpy( domain->dcname, saf_name );
930 winbind_add_failed_connection_entry(
931 domain, saf_servername,
932 NT_STATUS_UNSUCCESSFUL);
935 fstrcpy( domain->dcname, saf_servername );
938 SAFE_FREE( saf_servername );
941 for (retries = 0; retries < 3; retries++) {
946 result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
948 if ((strlen(domain->dcname) > 0)
949 && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, domain->dcname))
950 && (resolve_name(domain->dcname, &domain->dcaddr.sin_addr, 0x20)))
952 struct sockaddr_in *addrs = NULL;
956 add_sockaddr_to_array(mem_ctx, domain->dcaddr.sin_addr, 445, &addrs, &num_addrs);
957 add_sockaddr_to_array(mem_ctx, domain->dcaddr.sin_addr, 139, &addrs, &num_addrs);
959 /* 5 second timeout. */
960 if (!open_any_socket_out(addrs, num_addrs, 5000, &dummy, &fd)) {
966 && !find_new_dc(mem_ctx, domain, domain->dcname, &domain->dcaddr, &fd))
968 /* This is the one place where we will
969 set the global winbindd offline state
970 to true, if a "WINBINDD_OFFLINE" entry
971 is found in the winbindd cache. */
972 set_global_winbindd_state_offline();
976 new_conn->cli = NULL;
978 result = cm_prepare_connection(domain, fd, domain->dcname,
979 &new_conn->cli, &retry);
985 if (NT_STATUS_IS_OK(result)) {
986 if (domain->online == False) {
987 /* We're changing state from offline to online. */
988 set_global_winbindd_state_online();
990 set_domain_online(domain);
992 /* Ensure we setup the retry handler. */
993 set_domain_offline(domain);
996 talloc_destroy(mem_ctx);
1000 /* Close down all open pipes on a connection. */
1002 void invalidate_cm_connection(struct winbindd_cm_conn *conn)
1004 /* We're closing down a possibly dead
1005 connection. Don't have impossibly long (10s) timeouts. */
1008 cli_set_timeout(conn->cli, 1000); /* 1 second. */
1011 if (conn->samr_pipe != NULL) {
1012 if (!cli_rpc_pipe_close(conn->samr_pipe)) {
1013 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1015 cli_set_timeout(conn->cli, 500);
1018 conn->samr_pipe = NULL;
1021 if (conn->lsa_pipe != NULL) {
1022 if (!cli_rpc_pipe_close(conn->lsa_pipe)) {
1023 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1025 cli_set_timeout(conn->cli, 500);
1028 conn->lsa_pipe = NULL;
1031 if (conn->netlogon_pipe != NULL) {
1032 if (!cli_rpc_pipe_close(conn->netlogon_pipe)) {
1033 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1035 cli_set_timeout(conn->cli, 500);
1038 conn->netlogon_pipe = NULL;
1042 cli_shutdown(conn->cli);
1048 void close_conns_after_fork(void)
1050 struct winbindd_domain *domain;
1052 for (domain = domain_list(); domain; domain = domain->next) {
1053 if (domain->conn.cli == NULL)
1056 if (domain->conn.cli->fd == -1)
1059 close(domain->conn.cli->fd);
1060 domain->conn.cli->fd = -1;
1064 static BOOL connection_ok(struct winbindd_domain *domain)
1066 if (domain->conn.cli == NULL) {
1067 DEBUG(8, ("Connection to %s for domain %s has NULL "
1068 "cli!\n", domain->dcname, domain->name));
1072 if (!domain->conn.cli->initialised) {
1073 DEBUG(3, ("Connection to %s for domain %s was never "
1074 "initialised!\n", domain->dcname, domain->name));
1078 if (domain->conn.cli->fd == -1) {
1079 DEBUG(3, ("Connection to %s for domain %s has died or was "
1080 "never started (fd == -1)\n",
1081 domain->dcname, domain->name));
1088 /* Initialize a new connection up to the RPC BIND. */
1090 static NTSTATUS init_dc_connection(struct winbindd_domain *domain)
1092 if (connection_ok(domain))
1093 return NT_STATUS_OK;
1095 invalidate_cm_connection(&domain->conn);
1097 return cm_open_connection(domain, &domain->conn);
1100 /******************************************************************************
1101 We can 'sense' certain things about the DC by it's replies to certain
1104 This tells us if this particular remote server is Active Directory, and if it
1106 ******************************************************************************/
1108 void set_dc_type_and_flags( struct winbindd_domain *domain )
1112 TALLOC_CTX *mem_ctx = NULL;
1113 struct rpc_pipe_client *cli;
1116 char *domain_name = NULL;
1117 char *dns_name = NULL;
1118 DOM_SID *dom_sid = NULL;
1123 domain->native_mode = False;
1124 domain->active_directory = False;
1126 if (domain->internal) {
1127 domain->initialized = True;
1133 result = init_dc_connection(domain);
1134 if (!NT_STATUS_IS_OK(result) || try_count > 2) {
1135 DEBUG(5, ("set_dc_type_and_flags: Could not open a connection "
1136 "to %s: (%s)\n", domain->name, nt_errstr(result)));
1137 domain->initialized = True;
1141 cli = cli_rpc_pipe_open_noauth(domain->conn.cli, PI_LSARPC_DS,
1145 DEBUG(5, ("set_dc_type_and_flags: Could not bind to "
1146 "PI_LSARPC_DS on domain %s: (%s)\n",
1147 domain->name, nt_errstr(result)));
1148 domain->initialized = True;
1149 /* We want to detect network failures asap to try another dc. */
1154 result = rpccli_ds_getprimarydominfo(cli, cli->cli->mem_ctx,
1155 DsRolePrimaryDomainInfoBasic,
1157 cli_rpc_pipe_close(cli);
1159 if (!NT_STATUS_IS_OK(result)) {
1160 domain->initialized = True;
1164 if ((ctr.basic->flags & DSROLE_PRIMARY_DS_RUNNING) &&
1165 !(ctr.basic->flags & DSROLE_PRIMARY_DS_MIXED_MODE) )
1166 domain->native_mode = True;
1168 cli = cli_rpc_pipe_open_noauth(domain->conn.cli, PI_LSARPC, &result);
1171 domain->initialized = True;
1172 /* We want to detect network failures asap to try another dc. */
1177 mem_ctx = talloc_init("set_dc_type_and_flags on domain %s\n",
1180 DEBUG(1, ("set_dc_type_and_flags: talloc_init() failed\n"));
1181 cli_rpc_pipe_close(cli);
1185 result = rpccli_lsa_open_policy2(cli, mem_ctx, True,
1186 SEC_RIGHTS_MAXIMUM_ALLOWED, &pol);
1188 if (NT_STATUS_IS_OK(result)) {
1189 /* This particular query is exactly what Win2k clients use
1190 to determine that the DC is active directory */
1191 result = rpccli_lsa_query_info_policy2(cli, mem_ctx, &pol,
1197 if (NT_STATUS_IS_OK(result)) {
1199 fstrcpy(domain->name, domain_name);
1202 fstrcpy(domain->alt_name, dns_name);
1205 sid_copy(&domain->sid, dom_sid);
1207 domain->active_directory = True;
1210 result = rpccli_lsa_open_policy(cli, mem_ctx, True,
1211 SEC_RIGHTS_MAXIMUM_ALLOWED,
1214 if (!NT_STATUS_IS_OK(result))
1217 result = rpccli_lsa_query_info_policy(cli, mem_ctx,
1218 &pol, 5, &domain_name,
1221 if (NT_STATUS_IS_OK(result)) {
1223 fstrcpy(domain->name, domain_name);
1226 sid_copy(&domain->sid, dom_sid);
1231 cli_rpc_pipe_close(cli);
1233 talloc_destroy(mem_ctx);
1235 domain->initialized = True;
1240 static BOOL cm_get_schannel_dcinfo(struct winbindd_domain *domain,
1241 struct dcinfo **ppdc)
1244 struct rpc_pipe_client *netlogon_pipe;
1246 if (lp_client_schannel() == False) {
1250 result = cm_connect_netlogon(domain, &netlogon_pipe);
1251 if (!NT_STATUS_IS_OK(result)) {
1255 /* Return a pointer to the struct dcinfo from the
1258 *ppdc = domain->conn.netlogon_pipe->dc;
1262 NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
1263 struct rpc_pipe_client **cli, POLICY_HND *sam_handle)
1265 struct winbindd_cm_conn *conn;
1268 struct dcinfo *p_dcinfo;
1270 result = init_dc_connection(domain);
1271 if (!NT_STATUS_IS_OK(result)) {
1275 conn = &domain->conn;
1277 if (conn->samr_pipe != NULL) {
1282 * No SAMR pipe yet. Attempt to get an NTLMSSP SPNEGO authenticated
1283 * sign and sealed pipe using the machine account password by
1284 * preference. If we can't - try schannel, if that fails, try
1288 pwd_get_cleartext(&conn->cli->pwd, conn_pwd);
1289 if ((conn->cli->user_name[0] == '\0') ||
1290 (conn->cli->domain[0] == '\0') ||
1291 (conn_pwd[0] == '\0')) {
1292 DEBUG(10, ("cm_connect_sam: No no user available for "
1293 "domain %s, trying schannel\n", conn->cli->domain));
1297 /* We have an authenticated connection. Use a NTLMSSP SPNEGO
1298 authenticated SAMR pipe with sign & seal. */
1300 cli_rpc_pipe_open_spnego_ntlmssp(conn->cli, PI_SAMR,
1301 PIPE_AUTH_LEVEL_PRIVACY,
1303 conn->cli->user_name,
1306 if (conn->samr_pipe == NULL) {
1307 DEBUG(10,("cm_connect_sam: failed to connect to SAMR "
1308 "pipe for domain %s using NTLMSSP "
1309 "authenticated pipe: user %s\\%s. Error was "
1310 "%s\n", domain->name, conn->cli->domain,
1311 conn->cli->user_name, nt_errstr(result)));
1315 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for "
1316 "domain %s using NTLMSSP authenticated "
1317 "pipe: user %s\\%s\n", domain->name,
1318 conn->cli->domain, conn->cli->user_name ));
1320 result = rpccli_samr_connect(conn->samr_pipe, mem_ctx,
1321 SEC_RIGHTS_MAXIMUM_ALLOWED,
1322 &conn->sam_connect_handle);
1323 if (NT_STATUS_IS_OK(result)) {
1326 DEBUG(10,("cm_connect_sam: ntlmssp-sealed rpccli_samr_connect "
1327 "failed for domain %s, error was %s. Trying schannel\n",
1328 domain->name, nt_errstr(result) ));
1329 cli_rpc_pipe_close(conn->samr_pipe);
1333 /* Fall back to schannel if it's a W2K pre-SP1 box. */
1335 if (!cm_get_schannel_dcinfo(domain, &p_dcinfo)) {
1336 DEBUG(10, ("cm_connect_sam: Could not get schannel auth info "
1337 "for domain %s, trying anon\n", conn->cli->domain));
1340 conn->samr_pipe = cli_rpc_pipe_open_schannel_with_key
1341 (conn->cli, PI_SAMR, PIPE_AUTH_LEVEL_PRIVACY,
1342 domain->name, p_dcinfo, &result);
1344 if (conn->samr_pipe == NULL) {
1345 DEBUG(10,("cm_connect_sam: failed to connect to SAMR pipe for "
1346 "domain %s using schannel. Error was %s\n",
1347 domain->name, nt_errstr(result) ));
1350 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for domain %s using "
1351 "schannel.\n", domain->name ));
1353 result = rpccli_samr_connect(conn->samr_pipe, mem_ctx,
1354 SEC_RIGHTS_MAXIMUM_ALLOWED,
1355 &conn->sam_connect_handle);
1356 if (NT_STATUS_IS_OK(result)) {
1359 DEBUG(10,("cm_connect_sam: schannel-sealed rpccli_samr_connect failed "
1360 "for domain %s, error was %s. Trying anonymous\n",
1361 domain->name, nt_errstr(result) ));
1362 cli_rpc_pipe_close(conn->samr_pipe);
1366 /* Finally fall back to anonymous. */
1367 conn->samr_pipe = cli_rpc_pipe_open_noauth(conn->cli, PI_SAMR,
1370 if (conn->samr_pipe == NULL) {
1371 result = NT_STATUS_PIPE_NOT_AVAILABLE;
1375 result = rpccli_samr_connect(conn->samr_pipe, mem_ctx,
1376 SEC_RIGHTS_MAXIMUM_ALLOWED,
1377 &conn->sam_connect_handle);
1378 if (!NT_STATUS_IS_OK(result)) {
1379 DEBUG(10,("cm_connect_sam: rpccli_samr_connect failed "
1380 "for domain %s Error was %s\n",
1381 domain->name, nt_errstr(result) ));
1386 result = rpccli_samr_open_domain(conn->samr_pipe,
1388 &conn->sam_connect_handle,
1389 SEC_RIGHTS_MAXIMUM_ALLOWED,
1391 &conn->sam_domain_handle);
1395 if (!NT_STATUS_IS_OK(result)) {
1396 invalidate_cm_connection(conn);
1400 *cli = conn->samr_pipe;
1401 *sam_handle = conn->sam_domain_handle;
1405 NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
1406 struct rpc_pipe_client **cli, POLICY_HND *lsa_policy)
1408 struct winbindd_cm_conn *conn;
1411 struct dcinfo *p_dcinfo;
1413 result = init_dc_connection(domain);
1414 if (!NT_STATUS_IS_OK(result))
1417 conn = &domain->conn;
1419 if (conn->lsa_pipe != NULL) {
1423 pwd_get_cleartext(&conn->cli->pwd, conn_pwd);
1424 if ((conn->cli->user_name[0] == '\0') ||
1425 (conn->cli->domain[0] == '\0') ||
1426 (conn_pwd[0] == '\0')) {
1427 DEBUG(10, ("cm_connect_lsa: No no user available for "
1428 "domain %s, trying schannel\n", conn->cli->domain));
1432 /* We have an authenticated connection. Use a NTLMSSP SPNEGO
1433 * authenticated LSA pipe with sign & seal. */
1434 conn->lsa_pipe = cli_rpc_pipe_open_spnego_ntlmssp
1435 (conn->cli, PI_LSARPC, PIPE_AUTH_LEVEL_PRIVACY,
1436 conn->cli->domain, conn->cli->user_name, conn_pwd, &result);
1438 if (conn->lsa_pipe == NULL) {
1439 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
1440 "domain %s using NTLMSSP authenticated pipe: user "
1441 "%s\\%s. Error was %s. Trying schannel.\n",
1442 domain->name, conn->cli->domain,
1443 conn->cli->user_name, nt_errstr(result)));
1447 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
1448 "NTLMSSP authenticated pipe: user %s\\%s\n",
1449 domain->name, conn->cli->domain, conn->cli->user_name ));
1451 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
1452 SEC_RIGHTS_MAXIMUM_ALLOWED,
1454 if (NT_STATUS_IS_OK(result)) {
1458 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
1461 cli_rpc_pipe_close(conn->lsa_pipe);
1465 /* Fall back to schannel if it's a W2K pre-SP1 box. */
1467 if (!cm_get_schannel_dcinfo(domain, &p_dcinfo)) {
1468 DEBUG(10, ("cm_connect_lsa: Could not get schannel auth info "
1469 "for domain %s, trying anon\n", conn->cli->domain));
1472 conn->lsa_pipe = cli_rpc_pipe_open_schannel_with_key
1473 (conn->cli, PI_LSARPC, PIPE_AUTH_LEVEL_PRIVACY,
1474 domain->name, p_dcinfo, &result);
1476 if (conn->lsa_pipe == NULL) {
1477 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
1478 "domain %s using schannel. Error was %s\n",
1479 domain->name, nt_errstr(result) ));
1482 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
1483 "schannel.\n", domain->name ));
1485 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
1486 SEC_RIGHTS_MAXIMUM_ALLOWED,
1488 if (NT_STATUS_IS_OK(result)) {
1492 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
1495 cli_rpc_pipe_close(conn->lsa_pipe);
1499 conn->lsa_pipe = cli_rpc_pipe_open_noauth(conn->cli, PI_LSARPC,
1501 if (conn->lsa_pipe == NULL) {
1502 result = NT_STATUS_PIPE_NOT_AVAILABLE;
1506 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
1507 SEC_RIGHTS_MAXIMUM_ALLOWED,
1510 if (!NT_STATUS_IS_OK(result)) {
1511 invalidate_cm_connection(conn);
1512 return NT_STATUS_UNSUCCESSFUL;
1515 *cli = conn->lsa_pipe;
1516 *lsa_policy = conn->lsa_policy;
1520 /****************************************************************************
1521 Open the netlogon pipe to this DC. Use schannel if specified in client conf.
1522 session key stored in conn->netlogon_pipe->dc->sess_key.
1523 ****************************************************************************/
1525 NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
1526 struct rpc_pipe_client **cli)
1528 struct winbindd_cm_conn *conn;
1531 uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
1533 uint32 sec_chan_type;
1534 const char *account_name;
1535 struct rpc_pipe_client *netlogon_pipe = NULL;
1539 result = init_dc_connection(domain);
1540 if (!NT_STATUS_IS_OK(result)) {
1544 conn = &domain->conn;
1546 if (conn->netlogon_pipe != NULL) {
1547 *cli = conn->netlogon_pipe;
1548 return NT_STATUS_OK;
1551 if (!get_trust_pw(domain->name, mach_pwd, &sec_chan_type)) {
1552 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1555 netlogon_pipe = cli_rpc_pipe_open_noauth(conn->cli, PI_NETLOGON,
1557 if (netlogon_pipe == NULL) {
1561 if (lp_client_schannel() != False) {
1562 neg_flags |= NETLOGON_NEG_SCHANNEL;
1565 /* if we are a DC and this is a trusted domain, then we need to use our
1566 domain name in the net_req_auth2() request */
1569 && !strequal(domain->name, lp_workgroup())
1570 && lp_allow_trusted_domains() )
1572 account_name = lp_workgroup();
1574 account_name = domain->primary ?
1575 global_myname() : domain->name;
1578 if (account_name == NULL) {
1579 cli_rpc_pipe_close(netlogon_pipe);
1580 return NT_STATUS_NO_MEMORY;
1583 result = rpccli_netlogon_setup_creds(
1585 domain->dcname, /* server name. */
1586 domain->name, /* domain name */
1587 global_myname(), /* client name */
1588 account_name, /* machine account */
1589 mach_pwd, /* machine password */
1590 sec_chan_type, /* from get_trust_pw */
1593 if (!NT_STATUS_IS_OK(result)) {
1594 cli_rpc_pipe_close(netlogon_pipe);
1598 if ((lp_client_schannel() == True) &&
1599 ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
1600 DEBUG(3, ("Server did not offer schannel\n"));
1601 cli_rpc_pipe_close(netlogon_pipe);
1602 return NT_STATUS_ACCESS_DENIED;
1605 if ((lp_client_schannel() == False) ||
1606 ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
1607 /* We're done - just keep the existing connection to NETLOGON
1609 conn->netlogon_pipe = netlogon_pipe;
1610 *cli = conn->netlogon_pipe;
1611 return NT_STATUS_OK;
1614 /* Using the credentials from the first pipe, open a signed and sealed
1615 second netlogon pipe. The session key is stored in the schannel
1616 part of the new pipe auth struct.
1619 conn->netlogon_pipe =
1620 cli_rpc_pipe_open_schannel_with_key(conn->cli,
1622 PIPE_AUTH_LEVEL_PRIVACY,
1627 /* We can now close the initial netlogon pipe. */
1628 cli_rpc_pipe_close(netlogon_pipe);
1630 if (conn->netlogon_pipe == NULL) {
1631 DEBUG(3, ("Could not open schannel'ed NETLOGON pipe. Error "
1632 "was %s\n", nt_errstr(result)));
1634 /* make sure we return something besides OK */
1635 return !NT_STATUS_IS_OK(result) ? result : NT_STATUS_PIPE_NOT_AVAILABLE;
1638 *cli = conn->netlogon_pipe;
1639 return NT_STATUS_OK;