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
10 Copyright (C) Jeremy Allison 2006
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 We need to manage connections to domain controllers without having to
29 mess up the main winbindd code with other issues. The aim of the
30 connection manager is to:
32 - make connections to domain controllers and cache them
33 - re-establish connections when networks or servers go down
34 - centralise the policy on connection timeouts, domain controller
36 - manage re-entrancy for when winbindd becomes able to handle
37 multiple outstanding rpc requests
39 Why not have connection management as part of the rpc layer like tng?
40 Good question. This code may morph into libsmb/rpc_cache.c or something
41 like that but at the moment it's simply staying as part of winbind. I
42 think the TNG architecture of forcing every user of the rpc layer to use
43 the connection caching system is a bad idea. It should be an optional
44 method of using the routines.
46 The TNG design is quite good but I disagree with some aspects of the
54 - I'm pretty annoyed by all the make_nmb_name() stuff. It should be
55 moved down into another function.
57 - Take care when destroying cli_structs as they can be shared between
66 #define DBGC_CLASS DBGC_WINBIND
68 extern struct winbindd_methods reconnect_methods;
75 static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain);
76 static void set_dc_type_and_flags( struct winbindd_domain *domain );
77 static BOOL get_dcs(TALLOC_CTX *mem_ctx, const struct winbindd_domain *domain,
78 struct dc_name_ip **dcs, int *num_dcs);
80 /****************************************************************
81 Child failed to find DC's. Reschedule check.
82 ****************************************************************/
84 static void msg_failed_to_go_online(int msg_type, struct process_id src, void *buf, size_t len)
86 struct winbindd_domain *domain;
87 const char *domainname = (const char *)buf;
89 if (buf == NULL || len == 0) {
93 DEBUG(5,("msg_fail_to_go_online: received for domain %s.\n", domainname));
95 for (domain = domain_list(); domain; domain = domain->next) {
96 if (domain->internal) {
100 if (strequal(domain->name, domainname)) {
101 if (domain->online) {
102 /* We're already online, ignore. */
103 DEBUG(5,("msg_fail_to_go_online: domain %s "
104 "already online.\n", domainname));
108 /* Reschedule the online check. */
109 set_domain_offline(domain);
115 /****************************************************************
116 Actually cause a reconnect from a message.
117 ****************************************************************/
119 static void msg_try_to_go_online(int msg_type, struct process_id src, void *buf, size_t len)
121 struct winbindd_domain *domain;
122 const char *domainname = (const char *)buf;
124 if (buf == NULL || len == 0) {
128 DEBUG(5,("msg_try_to_go_online: received for domain %s.\n", domainname));
130 for (domain = domain_list(); domain; domain = domain->next) {
131 if (domain->internal) {
135 if (strequal(domain->name, domainname)) {
137 if (domain->online) {
138 /* We're already online, ignore. */
139 DEBUG(5,("msg_try_to_go_online: domain %s "
140 "already online.\n", domainname));
144 /* This call takes care of setting the online
145 flag to true if we connected, or re-adding
146 the offline handler if false. Bypasses online
147 check so always does network calls. */
149 init_dc_connection_network(domain);
155 /****************************************************************
156 Fork a child to try and contact a DC. Do this as contacting a
157 DC requires blocking lookups and we don't want to block our
159 ****************************************************************/
161 static BOOL fork_child_dc_connect(struct winbindd_domain *domain)
163 extern BOOL override_logfile;
164 struct dc_name_ip *dcs = NULL;
166 TALLOC_CTX *mem_ctx = NULL;
168 pid_t parent_pid = sys_getpid();
175 child_pid = sys_fork();
177 if (child_pid == -1) {
178 DEBUG(0, ("fork_child_dc_connect: Could not fork: %s\n", strerror(errno)));
183 if (child_pid != 0) {
185 message_register(MSG_WINBIND_TRY_TO_GO_ONLINE,msg_try_to_go_online);
186 message_register(MSG_WINBIND_FAILED_TO_GO_ONLINE,msg_failed_to_go_online);
193 /* Leave messages blocked - we will never process one. */
195 /* tdb needs special fork handling */
196 if (tdb_reopen_all(1) == -1) {
197 DEBUG(0,("tdb_reopen_all failed.\n"));
201 close_conns_after_fork();
203 if (!override_logfile) {
207 mem_ctx = talloc_init("fork_child_dc_connect");
209 DEBUG(0,("talloc_init failed.\n"));
213 if ((!get_dcs(mem_ctx, domain, &dcs, &num_dcs)) || (num_dcs == 0)) {
214 /* Still offline ? Can't find DC's. */
215 message_send_pid(pid_to_procid(parent_pid), MSG_WINBIND_FAILED_TO_GO_ONLINE,
217 strlen(domain->name)+1, False);
221 /* We got a DC. Send a message to our parent to get it to
222 try and do the same. */
224 message_send_pid(pid_to_procid(parent_pid), MSG_WINBIND_TRY_TO_GO_ONLINE,
226 strlen(domain->name)+1, False);
230 /****************************************************************
231 Handler triggered if we're offline to try and detect a DC.
232 ****************************************************************/
234 static void check_domain_online_handler(struct timed_event *te,
235 const struct timeval *now,
238 struct winbindd_domain *domain =
239 (struct winbindd_domain *)private_data;
241 DEBUG(10,("check_domain_online_handler: called for domain %s\n",
244 if (domain->check_online_event) {
245 TALLOC_FREE(domain->check_online_event);
248 /* Are we still in "startup" mode ? */
250 if (domain->startup && (now->tv_sec > domain->startup_time + 30)) {
251 /* No longer in "startup" mode. */
252 DEBUG(10,("check_domain_online_handler: domain %s no longer in 'startup' mode.\n",
254 domain->startup = False;
257 /* We've been told to stay offline, so stay
260 if (get_global_winbindd_state_offline()) {
261 DEBUG(10,("check_domain_online_handler: domain %s remaining globally offline\n",
266 /* Fork a child to test if it can contact a DC.
267 If it can then send ourselves a message to
268 cause a reconnect. */
270 fork_child_dc_connect(domain);
273 /****************************************************************
274 If we're still offline setup the timeout check.
275 ****************************************************************/
277 static void calc_new_online_timeout_check(struct winbindd_domain *domain)
279 int wbc = lp_winbind_cache_time();
281 if (domain->startup) {
282 domain->check_online_timeout = 10;
283 } else if (domain->check_online_timeout < wbc) {
284 domain->check_online_timeout = wbc;
288 /****************************************************************
289 Set domain offline and also add handler to put us back online
291 ****************************************************************/
293 void set_domain_offline(struct winbindd_domain *domain)
295 DEBUG(10,("set_domain_offline: called for domain %s\n",
298 if (domain->check_online_event) {
299 TALLOC_FREE(domain->check_online_event);
302 if (domain->internal) {
303 DEBUG(3,("set_domain_offline: domain %s is internal - logic error.\n",
308 domain->online = False;
310 /* Offline domains are always initialized. They're
311 re-initialized when they go back online. */
313 domain->initialized = True;
315 /* We only add the timeout handler that checks and
316 allows us to go back online when we've not
317 been told to remain offline. */
319 if (get_global_winbindd_state_offline()) {
320 DEBUG(10,("set_domain_offline: domain %s remaining globally offline\n",
325 /* If we're in statup mode, check again in 10 seconds, not in
326 lp_winbind_cache_time() seconds (which is 5 mins by default). */
328 calc_new_online_timeout_check(domain);
330 domain->check_online_event = add_timed_event( NULL,
331 timeval_current_ofs(domain->check_online_timeout,0),
332 "check_domain_online_handler",
333 check_domain_online_handler,
336 /* The above *has* to succeed for winbindd to work. */
337 if (!domain->check_online_event) {
338 smb_panic("set_domain_offline: failed to add online handler.\n");
341 DEBUG(10,("set_domain_offline: added event handler for domain %s\n",
345 /****************************************************************
346 Set domain online - if allowed.
347 ****************************************************************/
349 static void set_domain_online(struct winbindd_domain *domain)
353 DEBUG(10,("set_domain_online: called for domain %s\n",
356 if (domain->internal) {
357 DEBUG(3,("set_domain_offline: domain %s is internal - logic error.\n",
362 if (get_global_winbindd_state_offline()) {
363 DEBUG(10,("set_domain_online: domain %s remaining globally offline\n",
368 /* If we are waiting to get a krb5 ticket, trigger immediately. */
370 set_event_dispatch_time("krb5_ticket_gain_handler", now);
372 /* Ok, we're out of any startup mode now... */
373 domain->startup = False;
375 if (domain->online == False) {
376 /* We were offline - now we're online. We default to
377 using the MS-RPC backend if we started offline,
378 and if we're going online for the first time we
379 should really re-initialize the backends and the
380 checks to see if we're talking to an AD or NT domain.
383 domain->initialized = False;
385 /* 'reconnect_methods' is the MS-RPC backend. */
386 if (domain->backend == &reconnect_methods) {
387 domain->backend = NULL;
391 /* Ensure we have no online timeout checks. */
392 domain->check_online_timeout = 0;
393 if (domain->check_online_event) {
394 TALLOC_FREE(domain->check_online_event);
397 /* Ensure we ignore any pending child messages. */
398 message_deregister(MSG_WINBIND_TRY_TO_GO_ONLINE);
399 message_deregister(MSG_WINBIND_FAILED_TO_GO_ONLINE);
401 domain->online = True;
404 /****************************************************************
405 Requested to set a domain online.
406 ****************************************************************/
408 void set_domain_online_request(struct winbindd_domain *domain)
410 DEBUG(10,("set_domain_online_request: called for domain %s\n",
413 if (get_global_winbindd_state_offline()) {
414 DEBUG(10,("set_domain_online_request: domain %s remaining globally offline\n",
419 /* We've been told it's safe to go online and
420 try and connect to a DC. But I don't believe it
421 because network manager seems to lie.
422 Wait at least 5 seconds. Heuristics suck... */
424 if (!domain->check_online_event) {
425 DEBUG(5,("set_domain_online_request: no check_domain_online_handler "
426 "registered. Were we online (%d) ?\n", (int)domain->online ));
432 /* Go into "startup" mode again. */
433 domain->startup_time = tev.tv_sec;
434 domain->startup = True;
437 set_event_dispatch_time("check_domain_online_handler", tev);
441 /****************************************************************
442 Add -ve connection cache entries for domain and realm.
443 ****************************************************************/
445 void winbind_add_failed_connection_entry(const struct winbindd_domain *domain,
449 add_failed_connection_entry(domain->name, server, result);
450 /* If this was the saf name for the last thing we talked to,
452 saf_delete(domain->name);
453 if (*domain->alt_name) {
454 add_failed_connection_entry(domain->alt_name, server, result);
455 saf_delete(domain->alt_name);
459 /* Choose between anonymous or authenticated connections. We need to use
460 an authenticated connection if DCs have the RestrictAnonymous registry
461 entry set > 0, or the "Additional restrictions for anonymous
462 connections" set in the win2k Local Security Policy.
464 Caller to free() result in domain, username, password
467 static void cm_get_ipc_userpass(char **username, char **domain, char **password)
469 *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
470 *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
471 *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
473 if (*username && **username) {
475 if (!*domain || !**domain)
476 *domain = smb_xstrdup(lp_workgroup());
478 if (!*password || !**password)
479 *password = smb_xstrdup("");
481 DEBUG(3, ("cm_get_ipc_userpass: Retrieved auth-user from secrets.tdb [%s\\%s]\n",
482 *domain, *username));
485 DEBUG(3, ("cm_get_ipc_userpass: No auth-user defined\n"));
486 *username = smb_xstrdup("");
487 *domain = smb_xstrdup("");
488 *password = smb_xstrdup("");
492 static BOOL get_dc_name_via_netlogon(const struct winbindd_domain *domain,
493 fstring dcname, struct in_addr *dc_ip)
495 struct winbindd_domain *our_domain = NULL;
496 struct rpc_pipe_client *netlogon_pipe = NULL;
500 unsigned int orig_timeout;
504 /* Hmmmm. We can only open one connection to the NETLOGON pipe at the
511 if (domain->primary) {
515 our_domain = find_our_domain();
517 if ((mem_ctx = talloc_init("get_dc_name_via_netlogon")) == NULL) {
521 result = cm_connect_netlogon(our_domain, &netlogon_pipe);
522 if (!NT_STATUS_IS_OK(result)) {
523 talloc_destroy(mem_ctx);
527 /* This call can take a long time - allow the server to time out.
528 35 seconds should do it. */
530 orig_timeout = cli_set_timeout(netlogon_pipe->cli, 35000);
532 werr = rpccli_netlogon_getdcname(netlogon_pipe, mem_ctx, our_domain->dcname,
535 /* And restore our original timeout. */
536 cli_set_timeout(netlogon_pipe->cli, orig_timeout);
538 talloc_destroy(mem_ctx);
540 if (!W_ERROR_IS_OK(werr)) {
541 DEBUG(10, ("rpccli_netlogon_getdcname failed: %s\n",
546 /* cli_netlogon_getdcname gives us a name with \\ */
557 DEBUG(10, ("rpccli_netlogon_getdcname returned %s\n", dcname));
559 if (!resolve_name(dcname, dc_ip, 0x20)) {
566 /************************************************************************
567 Given a fd with a just-connected TCP connection to a DC, open a connection
569 ************************************************************************/
571 static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
573 const char *controller,
574 struct cli_state **cli,
577 char *machine_password, *machine_krb5_principal, *machine_account;
578 char *ipc_username, *ipc_domain, *ipc_password;
582 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
584 struct sockaddr peeraddr;
585 socklen_t peeraddr_len;
587 struct sockaddr_in *peeraddr_in = (struct sockaddr_in *)&peeraddr;
589 DEBUG(10,("cm_prepare_connection: connecting to DC %s for domain %s\n",
590 controller, domain->name ));
592 machine_password = secrets_fetch_machine_password(lp_workgroup(), NULL,
595 if (asprintf(&machine_account, "%s$", global_myname()) == -1) {
596 SAFE_FREE(machine_password);
597 return NT_STATUS_NO_MEMORY;
600 if (asprintf(&machine_krb5_principal, "%s$@%s", global_myname(),
602 SAFE_FREE(machine_account);
603 SAFE_FREE(machine_password);
604 return NT_STATUS_NO_MEMORY;
607 cm_get_ipc_userpass(&ipc_username, &ipc_domain, &ipc_password);
611 got_mutex = secrets_named_mutex(controller,
612 WINBIND_SERVER_MUTEX_WAIT_TIME);
615 DEBUG(0,("cm_prepare_connection: mutex grab failed for %s\n",
617 result = NT_STATUS_POSSIBLE_DEADLOCK;
621 if ((*cli = cli_initialise()) == NULL) {
622 DEBUG(1, ("Could not cli_initialize\n"));
623 result = NT_STATUS_NO_MEMORY;
627 (*cli)->timeout = 10000; /* 10 seconds */
629 fstrcpy((*cli)->desthost, controller);
630 (*cli)->use_kerberos = True;
632 peeraddr_len = sizeof(peeraddr);
634 if ((getpeername((*cli)->fd, &peeraddr, &peeraddr_len) != 0) ||
635 (peeraddr_len != sizeof(struct sockaddr_in)) ||
636 (peeraddr_in->sin_family != PF_INET))
638 DEBUG(0,("cm_prepare_connection: %s\n", strerror(errno)));
639 result = NT_STATUS_UNSUCCESSFUL;
643 if (ntohs(peeraddr_in->sin_port) == 139) {
644 struct nmb_name calling;
645 struct nmb_name called;
647 make_nmb_name(&calling, global_myname(), 0x0);
648 make_nmb_name(&called, "*SMBSERVER", 0x20);
650 if (!cli_session_request(*cli, &calling, &called)) {
651 DEBUG(8, ("cli_session_request failed for %s\n",
653 result = NT_STATUS_UNSUCCESSFUL;
658 cli_setup_signing_state(*cli, Undefined);
660 if (!cli_negprot(*cli)) {
661 DEBUG(1, ("cli_negprot failed\n"));
662 result = NT_STATUS_UNSUCCESSFUL;
666 if ((*cli)->protocol >= PROTOCOL_NT1 && (*cli)->capabilities & CAP_EXTENDED_SECURITY) {
667 ADS_STATUS ads_status;
669 if (lp_security() == SEC_ADS) {
671 /* Try a krb5 session */
673 (*cli)->use_kerberos = True;
674 DEBUG(5, ("connecting to %s from %s with kerberos principal "
675 "[%s]\n", controller, global_myname(),
676 machine_krb5_principal));
678 ads_status = cli_session_setup_spnego(*cli,
679 machine_krb5_principal,
683 if (!ADS_ERR_OK(ads_status)) {
684 DEBUG(4,("failed kerberos session setup with %s\n",
685 ads_errstr(ads_status)));
688 result = ads_ntstatus(ads_status);
689 if (NT_STATUS_IS_OK(result)) {
690 /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
691 cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
692 goto session_setup_done;
696 /* Fall back to non-kerberos session setup using NTLMSSP SPNEGO with the machine account. */
697 (*cli)->use_kerberos = False;
699 DEBUG(5, ("connecting to %s from %s with username "
700 "[%s]\\[%s]\n", controller, global_myname(),
701 lp_workgroup(), machine_account));
703 ads_status = cli_session_setup_spnego(*cli,
707 if (!ADS_ERR_OK(ads_status)) {
708 DEBUG(4, ("authenticated session setup failed with %s\n",
709 ads_errstr(ads_status)));
712 result = ads_ntstatus(ads_status);
713 if (NT_STATUS_IS_OK(result)) {
714 /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
715 cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
716 goto session_setup_done;
720 /* Fall back to non-kerberos session setup */
722 (*cli)->use_kerberos = False;
724 if ((((*cli)->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) != 0) &&
725 (strlen(ipc_username) > 0)) {
727 /* Only try authenticated if we have a username */
729 DEBUG(5, ("connecting to %s from %s with username "
730 "[%s]\\[%s]\n", controller, global_myname(),
731 ipc_domain, ipc_username));
733 if (NT_STATUS_IS_OK(cli_session_setup(
735 ipc_password, strlen(ipc_password)+1,
736 ipc_password, strlen(ipc_password)+1,
738 /* Successful logon with given username. */
739 cli_init_creds(*cli, ipc_username, ipc_domain, ipc_password);
740 goto session_setup_done;
742 DEBUG(4, ("authenticated session setup with user %s\\%s failed.\n",
743 ipc_domain, ipc_username ));
747 /* Fall back to anonymous connection, this might fail later */
749 if (NT_STATUS_IS_OK(cli_session_setup(*cli, "", NULL, 0,
751 DEBUG(5, ("Connected anonymously\n"));
752 cli_init_creds(*cli, "", "", "");
753 goto session_setup_done;
756 result = cli_nt_error(*cli);
758 if (NT_STATUS_IS_OK(result))
759 result = NT_STATUS_UNSUCCESSFUL;
761 /* We can't session setup */
767 /* cache the server name for later connections */
769 saf_store( domain->name, (*cli)->desthost );
770 if (domain->alt_name && (*cli)->use_kerberos) {
771 saf_store( domain->alt_name, (*cli)->desthost );
774 if (!cli_send_tconX(*cli, "IPC$", "IPC", "", 0)) {
776 result = cli_nt_error(*cli);
778 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(result)));
780 if (NT_STATUS_IS_OK(result))
781 result = NT_STATUS_UNSUCCESSFUL;
786 secrets_named_mutex_release(controller);
790 /* set the domain if empty; needed for schannel connections */
791 if ( !*(*cli)->domain ) {
792 fstrcpy( (*cli)->domain, domain->name );
795 result = NT_STATUS_OK;
799 secrets_named_mutex_release(controller);
802 SAFE_FREE(machine_account);
803 SAFE_FREE(machine_password);
804 SAFE_FREE(machine_krb5_principal);
805 SAFE_FREE(ipc_username);
806 SAFE_FREE(ipc_domain);
807 SAFE_FREE(ipc_password);
809 if (!NT_STATUS_IS_OK(result)) {
810 winbind_add_failed_connection_entry(domain, controller, result);
811 if ((*cli) != NULL) {
820 static BOOL add_one_dc_unique(TALLOC_CTX *mem_ctx, const char *domain_name,
821 const char *dcname, struct in_addr ip,
822 struct dc_name_ip **dcs, int *num)
824 if (!NT_STATUS_IS_OK(check_negative_conn_cache(domain_name, dcname))) {
825 DEBUG(10, ("DC %s was in the negative conn cache\n", dcname));
829 *dcs = TALLOC_REALLOC_ARRAY(mem_ctx, *dcs, struct dc_name_ip, (*num)+1);
834 fstrcpy((*dcs)[*num].name, dcname);
835 (*dcs)[*num].ip = ip;
840 static BOOL add_sockaddr_to_array(TALLOC_CTX *mem_ctx,
841 struct in_addr ip, uint16 port,
842 struct sockaddr_in **addrs, int *num)
844 *addrs = TALLOC_REALLOC_ARRAY(mem_ctx, *addrs, struct sockaddr_in, (*num)+1);
846 if (*addrs == NULL) {
851 (*addrs)[*num].sin_family = PF_INET;
852 putip((char *)&((*addrs)[*num].sin_addr), (char *)&ip);
853 (*addrs)[*num].sin_port = htons(port);
859 static void mailslot_name(struct in_addr dc_ip, fstring name)
861 fstr_sprintf(name, "\\MAILSLOT\\NET\\GETDC%X", dc_ip.s_addr);
864 static BOOL send_getdc_request(struct in_addr dc_ip,
865 const char *domain_name,
870 fstring my_acct_name;
873 mailslot_name(dc_ip, my_mailslot);
875 memset(outbuf, '\0', sizeof(outbuf));
879 SCVAL(p, 0, SAMLOGON);
882 SCVAL(p, 0, 0); /* Count pointer ... */
885 SIVAL(p, 0, 0); /* The sender's token ... */
888 p += dos_PutUniCode(p, global_myname(), sizeof(pstring), True);
889 fstr_sprintf(my_acct_name, "%s$", global_myname());
890 p += dos_PutUniCode(p, my_acct_name, sizeof(pstring), True);
892 memcpy(p, my_mailslot, strlen(my_mailslot)+1);
893 p += strlen(my_mailslot)+1;
898 SIVAL(p, 0, sid_size(sid));
901 p = ALIGN4(p, outbuf);
903 sid_linearize(p, sid_size(sid), sid);
911 return cli_send_mailslot(False, "\\MAILSLOT\\NET\\NTLOGON", 0,
912 outbuf, PTR_DIFF(p, outbuf),
913 global_myname(), 0, domain_name, 0x1c,
917 static BOOL receive_getdc_response(struct in_addr dc_ip,
918 const char *domain_name,
921 struct packet_struct *packet;
924 fstring dcname, user, domain;
927 mailslot_name(dc_ip, my_mailslot);
929 packet = receive_unexpected(DGRAM_PACKET, 0, my_mailslot);
931 if (packet == NULL) {
932 DEBUG(5, ("Did not receive packet for %s\n", my_mailslot));
936 DEBUG(5, ("Received packet for %s\n", my_mailslot));
938 buf = packet->packet.dgram.data;
939 len = packet->packet.dgram.datasize;
942 /* 70 is a completely arbitrary value to make sure
943 the SVAL below does not read uninitialized memory */
944 DEBUG(3, ("GetDC got short response\n"));
948 /* This should be (buf-4)+SVAL(buf-4, smb_vwv12)... */
949 p = buf+SVAL(buf, smb_vwv10);
951 if (CVAL(p,0) != SAMLOGON_R) {
952 DEBUG(8, ("GetDC got invalid response type %d\n", CVAL(p, 0)));
957 pull_ucs2(buf, dcname, p, sizeof(dcname), PTR_DIFF(buf+len, p),
958 STR_TERMINATE|STR_NOALIGN);
959 p = skip_unibuf(p, PTR_DIFF(buf+len, p));
960 pull_ucs2(buf, user, p, sizeof(dcname), PTR_DIFF(buf+len, p),
961 STR_TERMINATE|STR_NOALIGN);
962 p = skip_unibuf(p, PTR_DIFF(buf+len, p));
963 pull_ucs2(buf, domain, p, sizeof(dcname), PTR_DIFF(buf+len, p),
964 STR_TERMINATE|STR_NOALIGN);
965 p = skip_unibuf(p, PTR_DIFF(buf+len, p));
967 if (!strequal(domain, domain_name)) {
968 DEBUG(3, ("GetDC: Expected domain %s, got %s\n",
969 domain_name, domain));
974 if (*p == '\\') p += 1;
975 if (*p == '\\') p += 1;
979 DEBUG(10, ("GetDC gave name %s for domain %s\n",
985 /*******************************************************************
986 convert an ip to a name
987 *******************************************************************/
989 static BOOL dcip_to_name( const char *domainname, const char *realm,
990 const DOM_SID *sid, struct in_addr ip, fstring name )
992 struct ip_service ip_list;
998 /* For active directory servers, try to get the ldap server name.
999 None of these failures should be considered critical for now */
1001 if (lp_security() == SEC_ADS) {
1004 ads = ads_init(realm, domainname, NULL);
1005 ads->auth.flags |= ADS_AUTH_NO_BIND;
1007 if (ads_try_connect( ads, inet_ntoa(ip) ) ) {
1008 /* We got a cldap packet. */
1009 fstrcpy(name, ads->config.ldap_server_name);
1010 namecache_store(name, 0x20, 1, &ip_list);
1012 DEBUG(10,("dcip_to_name: flags = 0x%x\n", (unsigned int)ads->config.flags));
1014 if ((ads->config.flags & ADS_KDC) && ads_closest_dc(ads)) {
1015 /* We're going to use this KDC for this realm/domain.
1016 If we are using sites, then force the krb5 libs
1019 create_local_private_krb5_conf_for_domain(realm,
1023 /* Ensure we contact this DC also. */
1024 saf_store( domainname, name);
1025 saf_store( realm, name);
1028 ads_destroy( &ads );
1032 ads_destroy( &ads );
1036 /* try GETDC requests next */
1038 if (send_getdc_request(ip, domainname, sid)) {
1041 for (i=0; i<5; i++) {
1042 if (receive_getdc_response(ip, domainname, name)) {
1043 namecache_store(name, 0x20, 1, &ip_list);
1050 /* try node status request */
1052 if ( name_status_find(domainname, 0x1c, 0x20, ip, name) ) {
1053 namecache_store(name, 0x20, 1, &ip_list);
1059 /*******************************************************************
1060 Retreive a list of IP address for domain controllers. Fill in
1061 the dcs[] with results.
1062 *******************************************************************/
1064 static BOOL get_dcs(TALLOC_CTX *mem_ctx, const struct winbindd_domain *domain,
1065 struct dc_name_ip **dcs, int *num_dcs)
1069 struct ip_service *ip_list = NULL;
1070 int iplist_size = 0;
1073 enum security_types sec = (enum security_types)lp_security();
1075 is_our_domain = strequal(domain->name, lp_workgroup());
1078 && get_dc_name_via_netlogon(domain, dcname, &ip)
1079 && add_one_dc_unique(mem_ctx, domain->name, dcname, ip, dcs, num_dcs) )
1081 DEBUG(10, ("Retrieved DC %s at %s via netlogon\n",
1082 dcname, inet_ntoa(ip)));
1086 if (sec == SEC_ADS) {
1087 /* We need to make sure we know the local site before
1088 doing any DNS queries, as this will restrict the
1089 get_sorted_dc_list() call below to only fetching
1090 DNS records for the correct site. */
1092 /* Find any DC to get the site record.
1093 We deliberately don't care about the
1095 get_dc_name(domain->name, lp_realm(), dcname, &ip);
1097 /* Now do the site-specific AD dns lookup. */
1098 get_sorted_dc_list(domain->alt_name, &ip_list, &iplist_size, True);
1101 /* try standard netbios queries if no ADS */
1104 get_sorted_dc_list(domain->name, &ip_list, &iplist_size, False);
1106 /* FIXME!! this is where we should re-insert the GETDC requests --jerry */
1108 /* now add to the dc array. We'll wait until the last minute
1109 to look up the name of the DC. But we fill in the char* for
1110 the ip now in to make the failed connection cache work */
1112 for ( i=0; i<iplist_size; i++ ) {
1113 add_one_dc_unique(mem_ctx, domain->name, inet_ntoa(ip_list[i].ip),
1114 ip_list[i].ip, dcs, num_dcs);
1117 SAFE_FREE( ip_list );
1122 static BOOL find_new_dc(TALLOC_CTX *mem_ctx,
1123 const struct winbindd_domain *domain,
1124 fstring dcname, struct sockaddr_in *addr, int *fd)
1126 struct dc_name_ip *dcs = NULL;
1129 const char **dcnames = NULL;
1130 int num_dcnames = 0;
1132 struct sockaddr_in *addrs = NULL;
1138 if (!get_dcs(mem_ctx, domain, &dcs, &num_dcs) || (num_dcs == 0))
1141 for (i=0; i<num_dcs; i++) {
1143 if (!add_string_to_array(mem_ctx, dcs[i].name,
1144 &dcnames, &num_dcnames)) {
1147 if (!add_sockaddr_to_array(mem_ctx, dcs[i].ip, 445,
1148 &addrs, &num_addrs)) {
1152 if (!add_string_to_array(mem_ctx, dcs[i].name,
1153 &dcnames, &num_dcnames)) {
1156 if (!add_sockaddr_to_array(mem_ctx, dcs[i].ip, 139,
1157 &addrs, &num_addrs)) {
1162 if ((num_dcnames == 0) || (num_dcnames != num_addrs))
1165 if ((addrs == NULL) || (dcnames == NULL))
1168 /* 5 second timeout. */
1169 if ( !open_any_socket_out(addrs, num_addrs, 5000, &fd_index, fd) )
1171 for (i=0; i<num_dcs; i++) {
1172 DEBUG(10, ("find_new_dc: open_any_socket_out failed for "
1173 "domain %s address %s. Error was %s\n",
1174 domain->name, inet_ntoa(dcs[i].ip), strerror(errno) ));
1175 winbind_add_failed_connection_entry(domain,
1176 dcs[i].name, NT_STATUS_UNSUCCESSFUL);
1181 *addr = addrs[fd_index];
1183 if (*dcnames[fd_index] != '\0' && !is_ipaddress(dcnames[fd_index])) {
1184 /* Ok, we've got a name for the DC */
1185 fstrcpy(dcname, dcnames[fd_index]);
1189 /* Try to figure out the name */
1190 if (dcip_to_name( domain->name, domain->alt_name, &domain->sid,
1191 addr->sin_addr, dcname )) {
1195 /* We can not continue without the DC's name */
1196 winbind_add_failed_connection_entry(domain, dcs[fd_index].name,
1197 NT_STATUS_UNSUCCESSFUL);
1201 static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
1202 struct winbindd_cm_conn *new_conn)
1204 TALLOC_CTX *mem_ctx;
1206 char *saf_servername = saf_fetch( domain->name );
1209 if ((mem_ctx = talloc_init("cm_open_connection")) == NULL) {
1210 SAFE_FREE(saf_servername);
1211 set_domain_offline(domain);
1212 return NT_STATUS_NO_MEMORY;
1215 /* we have to check the server affinity cache here since
1216 later we selecte a DC based on response time and not preference */
1218 /* Check the negative connection cache
1219 before talking to it. It going down may have
1220 triggered the reconnection. */
1222 if ( saf_servername && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, saf_servername))) {
1224 DEBUG(10,("cm_open_connection: saf_servername is '%s' for domain %s\n",
1225 saf_servername, domain->name ));
1227 /* convert an ip address to a name */
1228 if ( is_ipaddress( saf_servername ) ) {
1232 ip = *interpret_addr2( saf_servername );
1233 if (dcip_to_name( domain->name, domain->alt_name,
1234 &domain->sid, ip, saf_name )) {
1235 fstrcpy( domain->dcname, saf_name );
1237 winbind_add_failed_connection_entry(
1238 domain, saf_servername,
1239 NT_STATUS_UNSUCCESSFUL);
1242 fstrcpy( domain->dcname, saf_servername );
1245 SAFE_FREE( saf_servername );
1248 for (retries = 0; retries < 3; retries++) {
1253 result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1255 DEBUG(10,("cm_open_connection: dcname is '%s' for domain %s\n",
1256 domain->dcname, domain->name ));
1259 && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, domain->dcname))
1260 && (resolve_name(domain->dcname, &domain->dcaddr.sin_addr, 0x20)))
1262 struct sockaddr_in *addrs = NULL;
1266 if (!add_sockaddr_to_array(mem_ctx, domain->dcaddr.sin_addr, 445, &addrs, &num_addrs)) {
1267 set_domain_offline(domain);
1268 talloc_destroy(mem_ctx);
1269 return NT_STATUS_NO_MEMORY;
1271 if (!add_sockaddr_to_array(mem_ctx, domain->dcaddr.sin_addr, 139, &addrs, &num_addrs)) {
1272 set_domain_offline(domain);
1273 talloc_destroy(mem_ctx);
1274 return NT_STATUS_NO_MEMORY;
1277 /* 5 second timeout. */
1278 if (!open_any_socket_out(addrs, num_addrs, 5000, &dummy, &fd)) {
1284 && !find_new_dc(mem_ctx, domain, domain->dcname, &domain->dcaddr, &fd))
1286 /* This is the one place where we will
1287 set the global winbindd offline state
1288 to true, if a "WINBINDD_OFFLINE" entry
1289 is found in the winbindd cache. */
1290 set_global_winbindd_state_offline();
1294 new_conn->cli = NULL;
1296 result = cm_prepare_connection(domain, fd, domain->dcname,
1297 &new_conn->cli, &retry);
1303 if (NT_STATUS_IS_OK(result)) {
1304 if (domain->online == False) {
1305 /* We're changing state from offline to online. */
1306 set_global_winbindd_state_online();
1308 set_domain_online(domain);
1310 /* Ensure we setup the retry handler. */
1311 set_domain_offline(domain);
1314 talloc_destroy(mem_ctx);
1318 /* Close down all open pipes on a connection. */
1320 void invalidate_cm_connection(struct winbindd_cm_conn *conn)
1322 /* We're closing down a possibly dead
1323 connection. Don't have impossibly long (10s) timeouts. */
1326 cli_set_timeout(conn->cli, 1000); /* 1 second. */
1329 if (conn->samr_pipe != NULL) {
1330 if (!cli_rpc_pipe_close(conn->samr_pipe)) {
1331 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1333 cli_set_timeout(conn->cli, 500);
1336 conn->samr_pipe = NULL;
1339 if (conn->lsa_pipe != NULL) {
1340 if (!cli_rpc_pipe_close(conn->lsa_pipe)) {
1341 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1343 cli_set_timeout(conn->cli, 500);
1346 conn->lsa_pipe = NULL;
1349 if (conn->netlogon_pipe != NULL) {
1350 if (!cli_rpc_pipe_close(conn->netlogon_pipe)) {
1351 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1353 cli_set_timeout(conn->cli, 500);
1356 conn->netlogon_pipe = NULL;
1360 cli_shutdown(conn->cli);
1366 void close_conns_after_fork(void)
1368 struct winbindd_domain *domain;
1370 for (domain = domain_list(); domain; domain = domain->next) {
1371 if (domain->conn.cli == NULL)
1374 if (domain->conn.cli->fd == -1)
1377 close(domain->conn.cli->fd);
1378 domain->conn.cli->fd = -1;
1382 static BOOL connection_ok(struct winbindd_domain *domain)
1384 if (domain->conn.cli == NULL) {
1385 DEBUG(8, ("connection_ok: Connection to %s for domain %s has NULL "
1386 "cli!\n", domain->dcname, domain->name));
1390 if (!domain->conn.cli->initialised) {
1391 DEBUG(3, ("connection_ok: Connection to %s for domain %s was never "
1392 "initialised!\n", domain->dcname, domain->name));
1396 if (domain->conn.cli->fd == -1) {
1397 DEBUG(3, ("connection_ok: Connection to %s for domain %s has died or was "
1398 "never started (fd == -1)\n",
1399 domain->dcname, domain->name));
1403 if (domain->online == False) {
1404 DEBUG(3, ("connection_ok: Domain %s is offline\n", domain->name));
1411 /* Initialize a new connection up to the RPC BIND.
1412 Bypass online status check so always does network calls. */
1414 static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain)
1418 /* Internal connections never use the network. */
1419 if (domain->internal) {
1420 domain->initialized = True;
1421 return NT_STATUS_OK;
1424 if (connection_ok(domain)) {
1425 if (!domain->initialized) {
1426 set_dc_type_and_flags(domain);
1428 return NT_STATUS_OK;
1431 invalidate_cm_connection(&domain->conn);
1433 result = cm_open_connection(domain, &domain->conn);
1435 if (NT_STATUS_IS_OK(result) && !domain->initialized) {
1436 set_dc_type_and_flags(domain);
1442 NTSTATUS init_dc_connection(struct winbindd_domain *domain)
1444 if (domain->initialized && !domain->online) {
1445 /* We check for online status elsewhere. */
1446 return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1449 return init_dc_connection_network(domain);
1452 /******************************************************************************
1453 We can 'sense' certain things about the DC by it's replies to certain
1456 This tells us if this particular remote server is Active Directory, and if it
1458 ******************************************************************************/
1460 static void set_dc_type_and_flags( struct winbindd_domain *domain )
1464 TALLOC_CTX *mem_ctx = NULL;
1465 struct rpc_pipe_client *cli;
1468 char *domain_name = NULL;
1469 char *dns_name = NULL;
1470 DOM_SID *dom_sid = NULL;
1474 if (!connection_ok(domain)) {
1478 DEBUG(5, ("set_dc_type_and_flags: domain %s\n", domain->name ));
1480 cli = cli_rpc_pipe_open_noauth(domain->conn.cli, PI_LSARPC_DS,
1484 DEBUG(5, ("set_dc_type_and_flags: Could not bind to "
1485 "PI_LSARPC_DS on domain %s: (%s)\n",
1486 domain->name, nt_errstr(result)));
1490 result = rpccli_ds_getprimarydominfo(cli, cli->cli->mem_ctx,
1491 DsRolePrimaryDomainInfoBasic,
1493 cli_rpc_pipe_close(cli);
1495 if (!NT_STATUS_IS_OK(result)) {
1496 DEBUG(5, ("set_dc_type_and_flags: rpccli_ds_getprimarydominfo "
1497 "on domain %s failed: (%s)\n",
1498 domain->name, nt_errstr(result)));
1502 if ((ctr.basic->flags & DSROLE_PRIMARY_DS_RUNNING) &&
1503 !(ctr.basic->flags & DSROLE_PRIMARY_DS_MIXED_MODE)) {
1504 domain->native_mode = True;
1506 domain->native_mode = False;
1509 cli = cli_rpc_pipe_open_noauth(domain->conn.cli, PI_LSARPC, &result);
1512 DEBUG(5, ("set_dc_type_and_flags: Could not bind to "
1513 "PI_LSARPC on domain %s: (%s)\n",
1514 domain->name, nt_errstr(result)));
1515 cli_rpc_pipe_close(cli);
1519 mem_ctx = talloc_init("set_dc_type_and_flags on domain %s\n",
1522 DEBUG(1, ("set_dc_type_and_flags: talloc_init() failed\n"));
1523 cli_rpc_pipe_close(cli);
1527 result = rpccli_lsa_open_policy2(cli, mem_ctx, True,
1528 SEC_RIGHTS_MAXIMUM_ALLOWED, &pol);
1530 if (NT_STATUS_IS_OK(result)) {
1531 /* This particular query is exactly what Win2k clients use
1532 to determine that the DC is active directory */
1533 result = rpccli_lsa_query_info_policy2(cli, mem_ctx, &pol,
1539 if (NT_STATUS_IS_OK(result)) {
1540 domain->active_directory = True;
1543 fstrcpy(domain->name, domain_name);
1546 fstrcpy(domain->alt_name, dns_name);
1549 sid_copy(&domain->sid, dom_sid);
1551 domain->active_directory = False;
1553 result = rpccli_lsa_open_policy(cli, mem_ctx, True,
1554 SEC_RIGHTS_MAXIMUM_ALLOWED,
1557 if (!NT_STATUS_IS_OK(result))
1560 result = rpccli_lsa_query_info_policy(cli, mem_ctx,
1561 &pol, 5, &domain_name,
1564 if (NT_STATUS_IS_OK(result)) {
1566 fstrcpy(domain->name, domain_name);
1569 sid_copy(&domain->sid, dom_sid);
1574 DEBUG(5, ("set_dc_type_and_flags: domain %s is %snative mode.\n",
1575 domain->name, domain->native_mode ? "" : "NOT "));
1577 DEBUG(5,("set_dc_type_and_flags: domain %s is %sactive directory.\n",
1578 domain->name, domain->active_directory ? "" : "NOT "));
1580 cli_rpc_pipe_close(cli);
1582 talloc_destroy(mem_ctx);
1584 domain->initialized = True;
1587 static BOOL cm_get_schannel_dcinfo(struct winbindd_domain *domain,
1588 struct dcinfo **ppdc)
1591 struct rpc_pipe_client *netlogon_pipe;
1593 if (lp_client_schannel() == False) {
1597 result = cm_connect_netlogon(domain, &netlogon_pipe);
1598 if (!NT_STATUS_IS_OK(result)) {
1602 /* Return a pointer to the struct dcinfo from the
1605 *ppdc = domain->conn.netlogon_pipe->dc;
1609 NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
1610 struct rpc_pipe_client **cli, POLICY_HND *sam_handle)
1612 struct winbindd_cm_conn *conn;
1615 struct dcinfo *p_dcinfo;
1617 result = init_dc_connection(domain);
1618 if (!NT_STATUS_IS_OK(result)) {
1622 conn = &domain->conn;
1624 if (conn->samr_pipe != NULL) {
1629 * No SAMR pipe yet. Attempt to get an NTLMSSP SPNEGO authenticated
1630 * sign and sealed pipe using the machine account password by
1631 * preference. If we can't - try schannel, if that fails, try
1635 pwd_get_cleartext(&conn->cli->pwd, conn_pwd);
1636 if ((conn->cli->user_name[0] == '\0') ||
1637 (conn->cli->domain[0] == '\0') ||
1638 (conn_pwd[0] == '\0')) {
1639 DEBUG(10, ("cm_connect_sam: No no user available for "
1640 "domain %s, trying schannel\n", conn->cli->domain));
1644 /* We have an authenticated connection. Use a NTLMSSP SPNEGO
1645 authenticated SAMR pipe with sign & seal. */
1647 cli_rpc_pipe_open_spnego_ntlmssp(conn->cli, PI_SAMR,
1648 PIPE_AUTH_LEVEL_PRIVACY,
1650 conn->cli->user_name,
1653 if (conn->samr_pipe == NULL) {
1654 DEBUG(10,("cm_connect_sam: failed to connect to SAMR "
1655 "pipe for domain %s using NTLMSSP "
1656 "authenticated pipe: user %s\\%s. Error was "
1657 "%s\n", domain->name, conn->cli->domain,
1658 conn->cli->user_name, nt_errstr(result)));
1662 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for "
1663 "domain %s using NTLMSSP authenticated "
1664 "pipe: user %s\\%s\n", domain->name,
1665 conn->cli->domain, conn->cli->user_name ));
1667 result = rpccli_samr_connect(conn->samr_pipe, mem_ctx,
1668 SEC_RIGHTS_MAXIMUM_ALLOWED,
1669 &conn->sam_connect_handle);
1670 if (NT_STATUS_IS_OK(result)) {
1673 DEBUG(10,("cm_connect_sam: ntlmssp-sealed rpccli_samr_connect "
1674 "failed for domain %s, error was %s. Trying schannel\n",
1675 domain->name, nt_errstr(result) ));
1676 cli_rpc_pipe_close(conn->samr_pipe);
1680 /* Fall back to schannel if it's a W2K pre-SP1 box. */
1682 if (!cm_get_schannel_dcinfo(domain, &p_dcinfo)) {
1683 DEBUG(10, ("cm_connect_sam: Could not get schannel auth info "
1684 "for domain %s, trying anon\n", conn->cli->domain));
1687 conn->samr_pipe = cli_rpc_pipe_open_schannel_with_key
1688 (conn->cli, PI_SAMR, PIPE_AUTH_LEVEL_PRIVACY,
1689 domain->name, p_dcinfo, &result);
1691 if (conn->samr_pipe == NULL) {
1692 DEBUG(10,("cm_connect_sam: failed to connect to SAMR pipe for "
1693 "domain %s using schannel. Error was %s\n",
1694 domain->name, nt_errstr(result) ));
1697 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for domain %s using "
1698 "schannel.\n", domain->name ));
1700 result = rpccli_samr_connect(conn->samr_pipe, mem_ctx,
1701 SEC_RIGHTS_MAXIMUM_ALLOWED,
1702 &conn->sam_connect_handle);
1703 if (NT_STATUS_IS_OK(result)) {
1706 DEBUG(10,("cm_connect_sam: schannel-sealed rpccli_samr_connect failed "
1707 "for domain %s, error was %s. Trying anonymous\n",
1708 domain->name, nt_errstr(result) ));
1709 cli_rpc_pipe_close(conn->samr_pipe);
1713 /* Finally fall back to anonymous. */
1714 conn->samr_pipe = cli_rpc_pipe_open_noauth(conn->cli, PI_SAMR,
1717 if (conn->samr_pipe == NULL) {
1718 result = NT_STATUS_PIPE_NOT_AVAILABLE;
1722 result = rpccli_samr_connect(conn->samr_pipe, mem_ctx,
1723 SEC_RIGHTS_MAXIMUM_ALLOWED,
1724 &conn->sam_connect_handle);
1725 if (!NT_STATUS_IS_OK(result)) {
1726 DEBUG(10,("cm_connect_sam: rpccli_samr_connect failed "
1727 "for domain %s Error was %s\n",
1728 domain->name, nt_errstr(result) ));
1733 result = rpccli_samr_open_domain(conn->samr_pipe,
1735 &conn->sam_connect_handle,
1736 SEC_RIGHTS_MAXIMUM_ALLOWED,
1738 &conn->sam_domain_handle);
1742 if (!NT_STATUS_IS_OK(result)) {
1743 invalidate_cm_connection(conn);
1747 *cli = conn->samr_pipe;
1748 *sam_handle = conn->sam_domain_handle;
1752 NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
1753 struct rpc_pipe_client **cli, POLICY_HND *lsa_policy)
1755 struct winbindd_cm_conn *conn;
1758 struct dcinfo *p_dcinfo;
1760 result = init_dc_connection(domain);
1761 if (!NT_STATUS_IS_OK(result))
1764 conn = &domain->conn;
1766 if (conn->lsa_pipe != NULL) {
1770 pwd_get_cleartext(&conn->cli->pwd, conn_pwd);
1771 if ((conn->cli->user_name[0] == '\0') ||
1772 (conn->cli->domain[0] == '\0') ||
1773 (conn_pwd[0] == '\0')) {
1774 DEBUG(10, ("cm_connect_lsa: No no user available for "
1775 "domain %s, trying schannel\n", conn->cli->domain));
1779 /* We have an authenticated connection. Use a NTLMSSP SPNEGO
1780 * authenticated LSA pipe with sign & seal. */
1781 conn->lsa_pipe = cli_rpc_pipe_open_spnego_ntlmssp
1782 (conn->cli, PI_LSARPC, PIPE_AUTH_LEVEL_PRIVACY,
1783 conn->cli->domain, conn->cli->user_name, conn_pwd, &result);
1785 if (conn->lsa_pipe == NULL) {
1786 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
1787 "domain %s using NTLMSSP authenticated pipe: user "
1788 "%s\\%s. Error was %s. Trying schannel.\n",
1789 domain->name, conn->cli->domain,
1790 conn->cli->user_name, nt_errstr(result)));
1794 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
1795 "NTLMSSP authenticated pipe: user %s\\%s\n",
1796 domain->name, conn->cli->domain, conn->cli->user_name ));
1798 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
1799 SEC_RIGHTS_MAXIMUM_ALLOWED,
1801 if (NT_STATUS_IS_OK(result)) {
1805 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
1808 cli_rpc_pipe_close(conn->lsa_pipe);
1812 /* Fall back to schannel if it's a W2K pre-SP1 box. */
1814 if (!cm_get_schannel_dcinfo(domain, &p_dcinfo)) {
1815 DEBUG(10, ("cm_connect_lsa: Could not get schannel auth info "
1816 "for domain %s, trying anon\n", conn->cli->domain));
1819 conn->lsa_pipe = cli_rpc_pipe_open_schannel_with_key
1820 (conn->cli, PI_LSARPC, PIPE_AUTH_LEVEL_PRIVACY,
1821 domain->name, p_dcinfo, &result);
1823 if (conn->lsa_pipe == NULL) {
1824 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
1825 "domain %s using schannel. Error was %s\n",
1826 domain->name, nt_errstr(result) ));
1829 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
1830 "schannel.\n", domain->name ));
1832 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
1833 SEC_RIGHTS_MAXIMUM_ALLOWED,
1835 if (NT_STATUS_IS_OK(result)) {
1839 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
1842 cli_rpc_pipe_close(conn->lsa_pipe);
1846 conn->lsa_pipe = cli_rpc_pipe_open_noauth(conn->cli, PI_LSARPC,
1848 if (conn->lsa_pipe == NULL) {
1849 result = NT_STATUS_PIPE_NOT_AVAILABLE;
1853 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
1854 SEC_RIGHTS_MAXIMUM_ALLOWED,
1857 if (!NT_STATUS_IS_OK(result)) {
1858 invalidate_cm_connection(conn);
1859 return NT_STATUS_UNSUCCESSFUL;
1862 *cli = conn->lsa_pipe;
1863 *lsa_policy = conn->lsa_policy;
1867 /****************************************************************************
1868 Open the netlogon pipe to this DC. Use schannel if specified in client conf.
1869 session key stored in conn->netlogon_pipe->dc->sess_key.
1870 ****************************************************************************/
1872 NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
1873 struct rpc_pipe_client **cli)
1875 struct winbindd_cm_conn *conn;
1878 uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
1880 uint32 sec_chan_type;
1881 const char *account_name;
1882 struct rpc_pipe_client *netlogon_pipe = NULL;
1886 result = init_dc_connection(domain);
1887 if (!NT_STATUS_IS_OK(result)) {
1891 conn = &domain->conn;
1893 if (conn->netlogon_pipe != NULL) {
1894 *cli = conn->netlogon_pipe;
1895 return NT_STATUS_OK;
1898 if (!get_trust_pw(domain->name, mach_pwd, &sec_chan_type)) {
1899 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1902 netlogon_pipe = cli_rpc_pipe_open_noauth(conn->cli, PI_NETLOGON,
1904 if (netlogon_pipe == NULL) {
1908 if (lp_client_schannel() != False) {
1909 neg_flags |= NETLOGON_NEG_SCHANNEL;
1912 /* if we are a DC and this is a trusted domain, then we need to use our
1913 domain name in the net_req_auth2() request */
1916 && !strequal(domain->name, lp_workgroup())
1917 && lp_allow_trusted_domains() )
1919 account_name = lp_workgroup();
1921 account_name = domain->primary ?
1922 global_myname() : domain->name;
1925 if (account_name == NULL) {
1926 cli_rpc_pipe_close(netlogon_pipe);
1927 return NT_STATUS_NO_MEMORY;
1930 result = rpccli_netlogon_setup_creds(
1932 domain->dcname, /* server name. */
1933 domain->name, /* domain name */
1934 global_myname(), /* client name */
1935 account_name, /* machine account */
1936 mach_pwd, /* machine password */
1937 sec_chan_type, /* from get_trust_pw */
1940 if (!NT_STATUS_IS_OK(result)) {
1941 cli_rpc_pipe_close(netlogon_pipe);
1945 if ((lp_client_schannel() == True) &&
1946 ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
1947 DEBUG(3, ("Server did not offer schannel\n"));
1948 cli_rpc_pipe_close(netlogon_pipe);
1949 return NT_STATUS_ACCESS_DENIED;
1952 if ((lp_client_schannel() == False) ||
1953 ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
1954 /* We're done - just keep the existing connection to NETLOGON
1956 conn->netlogon_pipe = netlogon_pipe;
1957 *cli = conn->netlogon_pipe;
1958 return NT_STATUS_OK;
1961 /* Using the credentials from the first pipe, open a signed and sealed
1962 second netlogon pipe. The session key is stored in the schannel
1963 part of the new pipe auth struct.
1966 conn->netlogon_pipe =
1967 cli_rpc_pipe_open_schannel_with_key(conn->cli,
1969 PIPE_AUTH_LEVEL_PRIVACY,
1974 /* We can now close the initial netlogon pipe. */
1975 cli_rpc_pipe_close(netlogon_pipe);
1977 if (conn->netlogon_pipe == NULL) {
1978 DEBUG(3, ("Could not open schannel'ed NETLOGON pipe. Error "
1979 "was %s\n", nt_errstr(result)));
1981 /* make sure we return something besides OK */
1982 return !NT_STATUS_IS_OK(result) ? result : NT_STATUS_PIPE_NOT_AVAILABLE;
1985 *cli = conn->netlogon_pipe;
1986 return NT_STATUS_OK;