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, exponentially increase 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;
286 uint32 new_to = domain->check_online_timeout * 3;
287 if (new_to > (3*60*60)) {
288 new_to = 3*60*60; /* 3 hours. */
290 domain->check_online_timeout = new_to;
294 /****************************************************************
295 Set domain offline and also add handler to put us back online
297 ****************************************************************/
299 void set_domain_offline(struct winbindd_domain *domain)
301 DEBUG(10,("set_domain_offline: called for domain %s\n",
304 if (domain->check_online_event) {
305 TALLOC_FREE(domain->check_online_event);
308 if (domain->internal) {
309 DEBUG(3,("set_domain_offline: domain %s is internal - logic error.\n",
314 domain->online = False;
316 /* Offline domains are always initialized. They're
317 re-initialized when they go back online. */
319 domain->initialized = True;
321 /* We only add the timeout handler that checks and
322 allows us to go back online when we've not
323 been told to remain offline. */
325 if (get_global_winbindd_state_offline()) {
326 DEBUG(10,("set_domain_offline: domain %s remaining globally offline\n",
331 /* If we're in statup mode, check again in 10 seconds, not in
332 lp_winbind_cache_time() seconds (which is 5 mins by default). */
334 calc_new_online_timeout_check(domain);
336 domain->check_online_event = add_timed_event( NULL,
337 timeval_current_ofs(domain->check_online_timeout,0),
338 "check_domain_online_handler",
339 check_domain_online_handler,
342 /* The above *has* to succeed for winbindd to work. */
343 if (!domain->check_online_event) {
344 smb_panic("set_domain_offline: failed to add online handler.\n");
347 DEBUG(10,("set_domain_offline: added event handler for domain %s\n",
351 /****************************************************************
352 Set domain online - if allowed.
353 ****************************************************************/
355 static void set_domain_online(struct winbindd_domain *domain)
359 DEBUG(10,("set_domain_online: called for domain %s\n",
362 if (domain->internal) {
363 DEBUG(3,("set_domain_offline: domain %s is internal - logic error.\n",
368 if (get_global_winbindd_state_offline()) {
369 DEBUG(10,("set_domain_online: domain %s remaining globally offline\n",
374 /* If we are waiting to get a krb5 ticket, trigger immediately. */
376 set_event_dispatch_time("krb5_ticket_gain_handler", now);
378 /* Ok, we're out of any startup mode now... */
379 domain->startup = False;
381 if (domain->online == False) {
382 /* We were offline - now we're online. We default to
383 using the MS-RPC backend if we started offline,
384 and if we're going online for the first time we
385 should really re-initialize the backends and the
386 checks to see if we're talking to an AD or NT domain.
389 domain->initialized = False;
391 /* 'reconnect_methods' is the MS-RPC backend. */
392 if (domain->backend == &reconnect_methods) {
393 domain->backend = NULL;
397 /* Ensure we have no online timeout checks. */
398 domain->check_online_timeout = 0;
399 if (domain->check_online_event) {
400 TALLOC_FREE(domain->check_online_event);
403 /* Ensure we ignore any pending child messages. */
404 message_deregister(MSG_WINBIND_TRY_TO_GO_ONLINE);
405 message_deregister(MSG_WINBIND_FAILED_TO_GO_ONLINE);
407 domain->online = True;
410 /****************************************************************
411 Requested to set a domain online.
412 ****************************************************************/
414 void set_domain_online_request(struct winbindd_domain *domain)
416 DEBUG(10,("set_domain_online_request: called for domain %s\n",
419 if (get_global_winbindd_state_offline()) {
420 DEBUG(10,("set_domain_online_request: domain %s remaining globally offline\n",
425 /* We've been told it's safe to go online and
426 try and connect to a DC. But I don't believe it
427 because network manager seems to lie.
428 Wait at least 5 seconds. Heuristics suck... */
430 if (!domain->check_online_event) {
431 DEBUG(5,("set_domain_online_request: no check_domain_online_handler "
432 "registered. Were we online (%d) ?\n", (int)domain->online ));
438 /* Go into "startup" mode again. */
439 domain->startup_time = tev.tv_sec;
440 domain->startup = True;
443 set_event_dispatch_time("check_domain_online_handler", tev);
447 /****************************************************************
448 Add -ve connection cache entries for domain and realm.
449 ****************************************************************/
451 void winbind_add_failed_connection_entry(const struct winbindd_domain *domain,
455 add_failed_connection_entry(domain->name, server, result);
456 /* If this was the saf name for the last thing we talked to,
458 saf_delete(domain->name);
459 if (*domain->alt_name) {
460 add_failed_connection_entry(domain->alt_name, server, result);
461 saf_delete(domain->alt_name);
465 /* Choose between anonymous or authenticated connections. We need to use
466 an authenticated connection if DCs have the RestrictAnonymous registry
467 entry set > 0, or the "Additional restrictions for anonymous
468 connections" set in the win2k Local Security Policy.
470 Caller to free() result in domain, username, password
473 static void cm_get_ipc_userpass(char **username, char **domain, char **password)
475 *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
476 *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
477 *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
479 if (*username && **username) {
481 if (!*domain || !**domain)
482 *domain = smb_xstrdup(lp_workgroup());
484 if (!*password || !**password)
485 *password = smb_xstrdup("");
487 DEBUG(3, ("cm_get_ipc_userpass: Retrieved auth-user from secrets.tdb [%s\\%s]\n",
488 *domain, *username));
491 DEBUG(3, ("cm_get_ipc_userpass: No auth-user defined\n"));
492 *username = smb_xstrdup("");
493 *domain = smb_xstrdup("");
494 *password = smb_xstrdup("");
498 static BOOL get_dc_name_via_netlogon(const struct winbindd_domain *domain,
499 fstring dcname, struct in_addr *dc_ip)
501 struct winbindd_domain *our_domain = NULL;
502 struct rpc_pipe_client *netlogon_pipe = NULL;
506 unsigned int orig_timeout;
510 /* Hmmmm. We can only open one connection to the NETLOGON pipe at the
517 if (domain->primary) {
521 our_domain = find_our_domain();
523 if ((mem_ctx = talloc_init("get_dc_name_via_netlogon")) == NULL) {
527 result = cm_connect_netlogon(our_domain, &netlogon_pipe);
528 if (!NT_STATUS_IS_OK(result)) {
532 /* This call can take a long time - allow the server to time out.
533 35 seconds should do it. */
535 orig_timeout = cli_set_timeout(netlogon_pipe->cli, 35000);
537 werr = rpccli_netlogon_getdcname(netlogon_pipe, mem_ctx, our_domain->dcname,
540 /* And restore our original timeout. */
541 cli_set_timeout(netlogon_pipe->cli, orig_timeout);
543 talloc_destroy(mem_ctx);
545 if (!W_ERROR_IS_OK(werr)) {
546 DEBUG(10, ("rpccli_netlogon_getdcname failed: %s\n",
551 /* cli_netlogon_getdcname gives us a name with \\ */
562 DEBUG(10, ("rpccli_netlogon_getdcname returned %s\n", dcname));
564 if (!resolve_name(dcname, dc_ip, 0x20)) {
571 /************************************************************************
572 Given a fd with a just-connected TCP connection to a DC, open a connection
574 ************************************************************************/
576 static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
578 const char *controller,
579 struct cli_state **cli,
582 char *machine_password, *machine_krb5_principal, *machine_account;
583 char *ipc_username, *ipc_domain, *ipc_password;
587 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
589 struct sockaddr peeraddr;
590 socklen_t peeraddr_len;
592 struct sockaddr_in *peeraddr_in = (struct sockaddr_in *)&peeraddr;
594 DEBUG(10,("cm_prepare_connection: connecting to DC %s for domain %s\n",
595 controller, domain->name ));
597 machine_password = secrets_fetch_machine_password(lp_workgroup(), NULL,
600 if (asprintf(&machine_account, "%s$", global_myname()) == -1) {
601 SAFE_FREE(machine_password);
602 return NT_STATUS_NO_MEMORY;
605 if (asprintf(&machine_krb5_principal, "%s$@%s", global_myname(),
607 SAFE_FREE(machine_account);
608 SAFE_FREE(machine_password);
609 return NT_STATUS_NO_MEMORY;
612 cm_get_ipc_userpass(&ipc_username, &ipc_domain, &ipc_password);
616 got_mutex = secrets_named_mutex(controller,
617 WINBIND_SERVER_MUTEX_WAIT_TIME);
620 DEBUG(0,("cm_prepare_connection: mutex grab failed for %s\n",
622 result = NT_STATUS_POSSIBLE_DEADLOCK;
626 if ((*cli = cli_initialise()) == NULL) {
627 DEBUG(1, ("Could not cli_initialize\n"));
628 result = NT_STATUS_NO_MEMORY;
632 (*cli)->timeout = 10000; /* 10 seconds */
634 fstrcpy((*cli)->desthost, controller);
635 (*cli)->use_kerberos = True;
637 peeraddr_len = sizeof(peeraddr);
639 if ((getpeername((*cli)->fd, &peeraddr, &peeraddr_len) != 0) ||
640 (peeraddr_len != sizeof(struct sockaddr_in)) ||
641 (peeraddr_in->sin_family != PF_INET))
643 DEBUG(0,("cm_prepare_connection: %s\n", strerror(errno)));
644 result = NT_STATUS_UNSUCCESSFUL;
648 if (ntohs(peeraddr_in->sin_port) == 139) {
649 struct nmb_name calling;
650 struct nmb_name called;
652 make_nmb_name(&calling, global_myname(), 0x0);
653 make_nmb_name(&called, "*SMBSERVER", 0x20);
655 if (!cli_session_request(*cli, &calling, &called)) {
656 DEBUG(8, ("cli_session_request failed for %s\n",
658 result = NT_STATUS_UNSUCCESSFUL;
663 cli_setup_signing_state(*cli, Undefined);
665 if (!cli_negprot(*cli)) {
666 DEBUG(1, ("cli_negprot failed\n"));
667 result = NT_STATUS_UNSUCCESSFUL;
671 if ((*cli)->protocol >= PROTOCOL_NT1 && (*cli)->capabilities & CAP_EXTENDED_SECURITY) {
672 ADS_STATUS ads_status;
674 if (lp_security() == SEC_ADS) {
676 /* Try a krb5 session */
678 (*cli)->use_kerberos = True;
679 DEBUG(5, ("connecting to %s from %s with kerberos principal "
680 "[%s]\n", controller, global_myname(),
681 machine_krb5_principal));
683 ads_status = cli_session_setup_spnego(*cli,
684 machine_krb5_principal,
688 if (!ADS_ERR_OK(ads_status)) {
689 DEBUG(4,("failed kerberos session setup with %s\n",
690 ads_errstr(ads_status)));
693 result = ads_ntstatus(ads_status);
694 if (NT_STATUS_IS_OK(result)) {
695 /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
696 cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
697 goto session_setup_done;
701 /* Fall back to non-kerberos session setup using NTLMSSP SPNEGO with the machine account. */
702 (*cli)->use_kerberos = False;
704 DEBUG(5, ("connecting to %s from %s with username "
705 "[%s]\\[%s]\n", controller, global_myname(),
706 lp_workgroup(), machine_account));
708 ads_status = cli_session_setup_spnego(*cli,
712 if (!ADS_ERR_OK(ads_status)) {
713 DEBUG(4, ("authenticated session setup failed with %s\n",
714 ads_errstr(ads_status)));
717 result = ads_ntstatus(ads_status);
718 if (NT_STATUS_IS_OK(result)) {
719 /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
720 cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
721 goto session_setup_done;
725 /* Fall back to non-kerberos session setup */
727 (*cli)->use_kerberos = False;
729 if ((((*cli)->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) != 0) &&
730 (strlen(ipc_username) > 0)) {
732 /* Only try authenticated if we have a username */
734 DEBUG(5, ("connecting to %s from %s with username "
735 "[%s]\\[%s]\n", controller, global_myname(),
736 ipc_domain, ipc_username));
738 if (NT_STATUS_IS_OK(cli_session_setup(
740 ipc_password, strlen(ipc_password)+1,
741 ipc_password, strlen(ipc_password)+1,
743 /* Successful logon with given username. */
744 cli_init_creds(*cli, ipc_username, ipc_domain, ipc_password);
745 goto session_setup_done;
747 DEBUG(4, ("authenticated session setup with user %s\\%s failed.\n",
748 ipc_domain, ipc_username ));
752 /* Fall back to anonymous connection, this might fail later */
754 if (NT_STATUS_IS_OK(cli_session_setup(*cli, "", NULL, 0,
756 DEBUG(5, ("Connected anonymously\n"));
757 cli_init_creds(*cli, "", "", "");
758 goto session_setup_done;
761 result = cli_nt_error(*cli);
763 if (NT_STATUS_IS_OK(result))
764 result = NT_STATUS_UNSUCCESSFUL;
766 /* We can't session setup */
772 /* cache the server name for later connections */
774 saf_store( domain->name, (*cli)->desthost );
775 if (domain->alt_name && (*cli)->use_kerberos) {
776 saf_store( domain->alt_name, (*cli)->desthost );
779 if (!cli_send_tconX(*cli, "IPC$", "IPC", "", 0)) {
781 result = cli_nt_error(*cli);
783 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(result)));
785 if (NT_STATUS_IS_OK(result))
786 result = NT_STATUS_UNSUCCESSFUL;
791 secrets_named_mutex_release(controller);
795 /* set the domain if empty; needed for schannel connections */
796 if ( !*(*cli)->domain ) {
797 fstrcpy( (*cli)->domain, domain->name );
800 result = NT_STATUS_OK;
804 secrets_named_mutex_release(controller);
807 SAFE_FREE(machine_account);
808 SAFE_FREE(machine_password);
809 SAFE_FREE(machine_krb5_principal);
810 SAFE_FREE(ipc_username);
811 SAFE_FREE(ipc_domain);
812 SAFE_FREE(ipc_password);
814 if (!NT_STATUS_IS_OK(result)) {
815 winbind_add_failed_connection_entry(domain, controller, result);
816 if ((*cli) != NULL) {
825 static BOOL add_one_dc_unique(TALLOC_CTX *mem_ctx, const char *domain_name,
826 const char *dcname, struct in_addr ip,
827 struct dc_name_ip **dcs, int *num)
829 if (!NT_STATUS_IS_OK(check_negative_conn_cache(domain_name, dcname))) {
830 DEBUG(10, ("DC %s was in the negative conn cache\n", dcname));
834 *dcs = TALLOC_REALLOC_ARRAY(mem_ctx, *dcs, struct dc_name_ip, (*num)+1);
839 fstrcpy((*dcs)[*num].name, dcname);
840 (*dcs)[*num].ip = ip;
845 static BOOL add_sockaddr_to_array(TALLOC_CTX *mem_ctx,
846 struct in_addr ip, uint16 port,
847 struct sockaddr_in **addrs, int *num)
849 *addrs = TALLOC_REALLOC_ARRAY(mem_ctx, *addrs, struct sockaddr_in, (*num)+1);
851 if (*addrs == NULL) {
856 (*addrs)[*num].sin_family = PF_INET;
857 putip((char *)&((*addrs)[*num].sin_addr), (char *)&ip);
858 (*addrs)[*num].sin_port = htons(port);
864 static void mailslot_name(struct in_addr dc_ip, fstring name)
866 fstr_sprintf(name, "\\MAILSLOT\\NET\\GETDC%X", dc_ip.s_addr);
869 static BOOL send_getdc_request(struct in_addr dc_ip,
870 const char *domain_name,
875 fstring my_acct_name;
878 mailslot_name(dc_ip, my_mailslot);
880 memset(outbuf, '\0', sizeof(outbuf));
884 SCVAL(p, 0, SAMLOGON);
887 SCVAL(p, 0, 0); /* Count pointer ... */
890 SIVAL(p, 0, 0); /* The sender's token ... */
893 p += dos_PutUniCode(p, global_myname(), sizeof(pstring), True);
894 fstr_sprintf(my_acct_name, "%s$", global_myname());
895 p += dos_PutUniCode(p, my_acct_name, sizeof(pstring), True);
897 memcpy(p, my_mailslot, strlen(my_mailslot)+1);
898 p += strlen(my_mailslot)+1;
903 SIVAL(p, 0, sid_size(sid));
906 p = ALIGN4(p, outbuf);
908 sid_linearize(p, sid_size(sid), sid);
916 return cli_send_mailslot(False, "\\MAILSLOT\\NET\\NTLOGON", 0,
917 outbuf, PTR_DIFF(p, outbuf),
918 global_myname(), 0, domain_name, 0x1c,
922 static BOOL receive_getdc_response(struct in_addr dc_ip,
923 const char *domain_name,
926 struct packet_struct *packet;
929 fstring dcname, user, domain;
932 mailslot_name(dc_ip, my_mailslot);
934 packet = receive_unexpected(DGRAM_PACKET, 0, my_mailslot);
936 if (packet == NULL) {
937 DEBUG(5, ("Did not receive packet for %s\n", my_mailslot));
941 DEBUG(5, ("Received packet for %s\n", my_mailslot));
943 buf = packet->packet.dgram.data;
944 len = packet->packet.dgram.datasize;
947 /* 70 is a completely arbitrary value to make sure
948 the SVAL below does not read uninitialized memory */
949 DEBUG(3, ("GetDC got short response\n"));
953 /* This should be (buf-4)+SVAL(buf-4, smb_vwv12)... */
954 p = buf+SVAL(buf, smb_vwv10);
956 if (CVAL(p,0) != SAMLOGON_R) {
957 DEBUG(8, ("GetDC got invalid response type %d\n", CVAL(p, 0)));
962 pull_ucs2(buf, dcname, p, sizeof(dcname), PTR_DIFF(buf+len, p),
963 STR_TERMINATE|STR_NOALIGN);
964 p = skip_unibuf(p, PTR_DIFF(buf+len, p));
965 pull_ucs2(buf, user, p, sizeof(dcname), PTR_DIFF(buf+len, p),
966 STR_TERMINATE|STR_NOALIGN);
967 p = skip_unibuf(p, PTR_DIFF(buf+len, p));
968 pull_ucs2(buf, domain, p, sizeof(dcname), PTR_DIFF(buf+len, p),
969 STR_TERMINATE|STR_NOALIGN);
970 p = skip_unibuf(p, PTR_DIFF(buf+len, p));
972 if (!strequal(domain, domain_name)) {
973 DEBUG(3, ("GetDC: Expected domain %s, got %s\n",
974 domain_name, domain));
979 if (*p == '\\') p += 1;
980 if (*p == '\\') p += 1;
984 DEBUG(10, ("GetDC gave name %s for domain %s\n",
990 /*******************************************************************
991 convert an ip to a name
992 *******************************************************************/
994 static BOOL dcip_to_name( const char *domainname, const char *realm,
995 const DOM_SID *sid, struct in_addr ip, fstring name )
997 struct ip_service ip_list;
1003 /* For active directory servers, try to get the ldap server name.
1004 None of these failures should be considered critical for now */
1006 if (lp_security() == SEC_ADS) {
1009 ads = ads_init(realm, domainname, NULL);
1010 ads->auth.flags |= ADS_AUTH_NO_BIND;
1012 if (ads_try_connect( ads, inet_ntoa(ip) ) ) {
1013 /* We got a cldap packet. */
1014 fstrcpy(name, ads->config.ldap_server_name);
1015 namecache_store(name, 0x20, 1, &ip_list);
1017 DEBUG(10,("dcip_to_name: flags = 0x%x\n", (unsigned int)ads->config.flags));
1019 if ((ads->config.flags & ADS_KDC) && ads_closest_dc(ads)) {
1020 /* We're going to use this KDC for this realm/domain.
1021 If we are using sites, then force the krb5 libs
1024 create_local_private_krb5_conf_for_domain(realm,
1028 /* Ensure we contact this DC also. */
1029 saf_store( domainname, name);
1030 saf_store( realm, name);
1033 ads_destroy( &ads );
1037 ads_destroy( &ads );
1041 /* try GETDC requests next */
1043 if (send_getdc_request(ip, domainname, sid)) {
1046 for (i=0; i<5; i++) {
1047 if (receive_getdc_response(ip, domainname, name)) {
1048 namecache_store(name, 0x20, 1, &ip_list);
1055 /* try node status request */
1057 if ( name_status_find(domainname, 0x1c, 0x20, ip, name) ) {
1058 namecache_store(name, 0x20, 1, &ip_list);
1064 /*******************************************************************
1065 Retreive a list of IP address for domain controllers. Fill in
1066 the dcs[] with results.
1067 *******************************************************************/
1069 static BOOL get_dcs(TALLOC_CTX *mem_ctx, const struct winbindd_domain *domain,
1070 struct dc_name_ip **dcs, int *num_dcs)
1074 struct ip_service *ip_list = NULL;
1075 int iplist_size = 0;
1078 enum security_types sec = (enum security_types)lp_security();
1080 is_our_domain = strequal(domain->name, lp_workgroup());
1083 && get_dc_name_via_netlogon(domain, dcname, &ip)
1084 && add_one_dc_unique(mem_ctx, domain->name, dcname, ip, dcs, num_dcs) )
1086 DEBUG(10, ("Retrieved DC %s at %s via netlogon\n",
1087 dcname, inet_ntoa(ip)));
1091 if (sec == SEC_ADS) {
1092 /* We need to make sure we know the local site before
1093 doing any DNS queries, as this will restrict the
1094 get_sorted_dc_list() call below to only fetching
1095 DNS records for the correct site. */
1097 /* Find any DC to get the site record.
1098 We deliberately don't care about the
1100 get_dc_name(domain->name, lp_realm(), dcname, &ip);
1102 /* Now do the site-specific AD dns lookup. */
1103 get_sorted_dc_list(domain->alt_name, &ip_list, &iplist_size, True);
1106 /* try standard netbios queries if no ADS */
1109 get_sorted_dc_list(domain->name, &ip_list, &iplist_size, False);
1111 /* FIXME!! this is where we should re-insert the GETDC requests --jerry */
1113 /* now add to the dc array. We'll wait until the last minute
1114 to look up the name of the DC. But we fill in the char* for
1115 the ip now in to make the failed connection cache work */
1117 for ( i=0; i<iplist_size; i++ ) {
1118 add_one_dc_unique(mem_ctx, domain->name, inet_ntoa(ip_list[i].ip),
1119 ip_list[i].ip, dcs, num_dcs);
1122 SAFE_FREE( ip_list );
1127 static BOOL find_new_dc(TALLOC_CTX *mem_ctx,
1128 const struct winbindd_domain *domain,
1129 fstring dcname, struct sockaddr_in *addr, int *fd)
1131 struct dc_name_ip *dcs = NULL;
1134 const char **dcnames = NULL;
1135 int num_dcnames = 0;
1137 struct sockaddr_in *addrs = NULL;
1143 if (!get_dcs(mem_ctx, domain, &dcs, &num_dcs) || (num_dcs == 0))
1146 for (i=0; i<num_dcs; i++) {
1148 if (!add_string_to_array(mem_ctx, dcs[i].name,
1149 &dcnames, &num_dcnames)) {
1152 if (!add_sockaddr_to_array(mem_ctx, dcs[i].ip, 445,
1153 &addrs, &num_addrs)) {
1157 if (!add_string_to_array(mem_ctx, dcs[i].name,
1158 &dcnames, &num_dcnames)) {
1161 if (!add_sockaddr_to_array(mem_ctx, dcs[i].ip, 139,
1162 &addrs, &num_addrs)) {
1167 if ((num_dcnames == 0) || (num_dcnames != num_addrs))
1170 if ((addrs == NULL) || (dcnames == NULL))
1173 /* 5 second timeout. */
1174 if ( !open_any_socket_out(addrs, num_addrs, 5000, &fd_index, fd) )
1176 for (i=0; i<num_dcs; i++) {
1177 DEBUG(10, ("find_new_dc: open_any_socket_out failed for "
1178 "domain %s address %s. Error was %s\n",
1179 domain->name, inet_ntoa(dcs[i].ip), strerror(errno) ));
1180 winbind_add_failed_connection_entry(domain,
1181 dcs[i].name, NT_STATUS_UNSUCCESSFUL);
1186 *addr = addrs[fd_index];
1188 if (*dcnames[fd_index] != '\0' && !is_ipaddress(dcnames[fd_index])) {
1189 /* Ok, we've got a name for the DC */
1190 fstrcpy(dcname, dcnames[fd_index]);
1194 /* Try to figure out the name */
1195 if (dcip_to_name( domain->name, domain->alt_name, &domain->sid,
1196 addr->sin_addr, dcname )) {
1200 /* We can not continue without the DC's name */
1201 winbind_add_failed_connection_entry(domain, dcs[fd_index].name,
1202 NT_STATUS_UNSUCCESSFUL);
1206 static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
1207 struct winbindd_cm_conn *new_conn)
1209 TALLOC_CTX *mem_ctx;
1211 char *saf_servername = saf_fetch( domain->name );
1214 if ((mem_ctx = talloc_init("cm_open_connection")) == NULL) {
1215 SAFE_FREE(saf_servername);
1216 set_domain_offline(domain);
1217 return NT_STATUS_NO_MEMORY;
1220 /* we have to check the server affinity cache here since
1221 later we selecte a DC based on response time and not preference */
1223 /* Check the negative connection cache
1224 before talking to it. It going down may have
1225 triggered the reconnection. */
1227 if ( saf_servername && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, saf_servername))) {
1229 DEBUG(10,("cm_open_connection: saf_servername is '%s' for domain %s\n",
1230 saf_servername, domain->name ));
1232 /* convert an ip address to a name */
1233 if ( is_ipaddress( saf_servername ) ) {
1237 ip = *interpret_addr2( saf_servername );
1238 if (dcip_to_name( domain->name, domain->alt_name,
1239 &domain->sid, ip, saf_name )) {
1240 fstrcpy( domain->dcname, saf_name );
1242 winbind_add_failed_connection_entry(
1243 domain, saf_servername,
1244 NT_STATUS_UNSUCCESSFUL);
1247 fstrcpy( domain->dcname, saf_servername );
1250 SAFE_FREE( saf_servername );
1253 for (retries = 0; retries < 3; retries++) {
1258 result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1260 DEBUG(10,("cm_open_connection: dcname is '%s' for domain %s\n",
1261 domain->dcname, domain->name ));
1264 && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, domain->dcname))
1265 && (resolve_name(domain->dcname, &domain->dcaddr.sin_addr, 0x20)))
1267 struct sockaddr_in *addrs = NULL;
1271 if (!add_sockaddr_to_array(mem_ctx, domain->dcaddr.sin_addr, 445, &addrs, &num_addrs)) {
1272 set_domain_offline(domain);
1273 return NT_STATUS_NO_MEMORY;
1275 if (!add_sockaddr_to_array(mem_ctx, domain->dcaddr.sin_addr, 139, &addrs, &num_addrs)) {
1276 set_domain_offline(domain);
1277 return NT_STATUS_NO_MEMORY;
1280 /* 5 second timeout. */
1281 if (!open_any_socket_out(addrs, num_addrs, 5000, &dummy, &fd)) {
1287 && !find_new_dc(mem_ctx, domain, domain->dcname, &domain->dcaddr, &fd))
1289 /* This is the one place where we will
1290 set the global winbindd offline state
1291 to true, if a "WINBINDD_OFFLINE" entry
1292 is found in the winbindd cache. */
1293 set_global_winbindd_state_offline();
1297 new_conn->cli = NULL;
1299 result = cm_prepare_connection(domain, fd, domain->dcname,
1300 &new_conn->cli, &retry);
1306 if (NT_STATUS_IS_OK(result)) {
1307 if (domain->online == False) {
1308 /* We're changing state from offline to online. */
1309 set_global_winbindd_state_online();
1311 set_domain_online(domain);
1313 /* Ensure we setup the retry handler. */
1314 set_domain_offline(domain);
1317 talloc_destroy(mem_ctx);
1321 /* Close down all open pipes on a connection. */
1323 void invalidate_cm_connection(struct winbindd_cm_conn *conn)
1325 /* We're closing down a possibly dead
1326 connection. Don't have impossibly long (10s) timeouts. */
1329 cli_set_timeout(conn->cli, 1000); /* 1 second. */
1332 if (conn->samr_pipe != NULL) {
1333 if (!cli_rpc_pipe_close(conn->samr_pipe)) {
1334 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1336 cli_set_timeout(conn->cli, 500);
1339 conn->samr_pipe = NULL;
1342 if (conn->lsa_pipe != NULL) {
1343 if (!cli_rpc_pipe_close(conn->lsa_pipe)) {
1344 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1346 cli_set_timeout(conn->cli, 500);
1349 conn->lsa_pipe = NULL;
1352 if (conn->netlogon_pipe != NULL) {
1353 if (!cli_rpc_pipe_close(conn->netlogon_pipe)) {
1354 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1356 cli_set_timeout(conn->cli, 500);
1359 conn->netlogon_pipe = NULL;
1363 cli_shutdown(conn->cli);
1369 void close_conns_after_fork(void)
1371 struct winbindd_domain *domain;
1373 for (domain = domain_list(); domain; domain = domain->next) {
1374 if (domain->conn.cli == NULL)
1377 if (domain->conn.cli->fd == -1)
1380 close(domain->conn.cli->fd);
1381 domain->conn.cli->fd = -1;
1385 static BOOL connection_ok(struct winbindd_domain *domain)
1387 if (domain->conn.cli == NULL) {
1388 DEBUG(8, ("connection_ok: Connection to %s for domain %s has NULL "
1389 "cli!\n", domain->dcname, domain->name));
1393 if (!domain->conn.cli->initialised) {
1394 DEBUG(3, ("connection_ok: Connection to %s for domain %s was never "
1395 "initialised!\n", domain->dcname, domain->name));
1399 if (domain->conn.cli->fd == -1) {
1400 DEBUG(3, ("connection_ok: Connection to %s for domain %s has died or was "
1401 "never started (fd == -1)\n",
1402 domain->dcname, domain->name));
1406 if (domain->online == False) {
1407 DEBUG(3, ("connection_ok: Domain %s is offline\n", domain->name));
1414 /* Initialize a new connection up to the RPC BIND.
1415 Bypass online status check so always does network calls. */
1417 static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain)
1421 /* Internal connections never use the network. */
1422 if (domain->internal) {
1423 domain->initialized = True;
1424 return NT_STATUS_OK;
1427 if (connection_ok(domain)) {
1428 if (!domain->initialized) {
1429 set_dc_type_and_flags(domain);
1431 return NT_STATUS_OK;
1434 invalidate_cm_connection(&domain->conn);
1436 result = cm_open_connection(domain, &domain->conn);
1438 if (NT_STATUS_IS_OK(result) && !domain->initialized) {
1439 set_dc_type_and_flags(domain);
1445 NTSTATUS init_dc_connection(struct winbindd_domain *domain)
1447 if (domain->initialized && !domain->online) {
1448 /* We check for online status elsewhere. */
1449 return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1452 return init_dc_connection_network(domain);
1455 /******************************************************************************
1456 We can 'sense' certain things about the DC by it's replies to certain
1459 This tells us if this particular remote server is Active Directory, and if it
1461 ******************************************************************************/
1463 static void set_dc_type_and_flags( struct winbindd_domain *domain )
1467 TALLOC_CTX *mem_ctx = NULL;
1468 struct rpc_pipe_client *cli;
1471 char *domain_name = NULL;
1472 char *dns_name = NULL;
1473 DOM_SID *dom_sid = NULL;
1477 if (!connection_ok(domain)) {
1481 DEBUG(5, ("set_dc_type_and_flags: domain %s\n", domain->name ));
1483 cli = cli_rpc_pipe_open_noauth(domain->conn.cli, PI_LSARPC_DS,
1487 DEBUG(5, ("set_dc_type_and_flags: Could not bind to "
1488 "PI_LSARPC_DS on domain %s: (%s)\n",
1489 domain->name, nt_errstr(result)));
1493 result = rpccli_ds_getprimarydominfo(cli, cli->cli->mem_ctx,
1494 DsRolePrimaryDomainInfoBasic,
1496 cli_rpc_pipe_close(cli);
1498 if (!NT_STATUS_IS_OK(result)) {
1499 DEBUG(5, ("set_dc_type_and_flags: rpccli_ds_getprimarydominfo "
1500 "on domain %s failed: (%s)\n",
1501 domain->name, nt_errstr(result)));
1505 if ((ctr.basic->flags & DSROLE_PRIMARY_DS_RUNNING) &&
1506 !(ctr.basic->flags & DSROLE_PRIMARY_DS_MIXED_MODE)) {
1507 domain->native_mode = True;
1509 domain->native_mode = False;
1512 cli = cli_rpc_pipe_open_noauth(domain->conn.cli, PI_LSARPC, &result);
1515 DEBUG(5, ("set_dc_type_and_flags: Could not bind to "
1516 "PI_LSARPC on domain %s: (%s)\n",
1517 domain->name, nt_errstr(result)));
1518 cli_rpc_pipe_close(cli);
1522 mem_ctx = talloc_init("set_dc_type_and_flags on domain %s\n",
1525 DEBUG(1, ("set_dc_type_and_flags: talloc_init() failed\n"));
1526 cli_rpc_pipe_close(cli);
1530 result = rpccli_lsa_open_policy2(cli, mem_ctx, True,
1531 SEC_RIGHTS_MAXIMUM_ALLOWED, &pol);
1533 if (NT_STATUS_IS_OK(result)) {
1534 /* This particular query is exactly what Win2k clients use
1535 to determine that the DC is active directory */
1536 result = rpccli_lsa_query_info_policy2(cli, mem_ctx, &pol,
1542 if (NT_STATUS_IS_OK(result)) {
1543 domain->active_directory = True;
1546 fstrcpy(domain->name, domain_name);
1549 fstrcpy(domain->alt_name, dns_name);
1552 sid_copy(&domain->sid, dom_sid);
1554 domain->active_directory = False;
1556 result = rpccli_lsa_open_policy(cli, mem_ctx, True,
1557 SEC_RIGHTS_MAXIMUM_ALLOWED,
1560 if (!NT_STATUS_IS_OK(result))
1563 result = rpccli_lsa_query_info_policy(cli, mem_ctx,
1564 &pol, 5, &domain_name,
1567 if (NT_STATUS_IS_OK(result)) {
1569 fstrcpy(domain->name, domain_name);
1572 sid_copy(&domain->sid, dom_sid);
1577 DEBUG(5, ("set_dc_type_and_flags: domain %s is %snative mode.\n",
1578 domain->name, domain->native_mode ? "" : "NOT "));
1580 DEBUG(5,("set_dc_type_and_flags: domain %s is %sactive directory.\n",
1581 domain->name, domain->active_directory ? "" : "NOT "));
1583 cli_rpc_pipe_close(cli);
1585 talloc_destroy(mem_ctx);
1587 domain->initialized = True;
1590 static BOOL cm_get_schannel_dcinfo(struct winbindd_domain *domain,
1591 struct dcinfo **ppdc)
1594 struct rpc_pipe_client *netlogon_pipe;
1596 if (lp_client_schannel() == False) {
1600 result = cm_connect_netlogon(domain, &netlogon_pipe);
1601 if (!NT_STATUS_IS_OK(result)) {
1605 /* Return a pointer to the struct dcinfo from the
1608 *ppdc = domain->conn.netlogon_pipe->dc;
1612 NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
1613 struct rpc_pipe_client **cli, POLICY_HND *sam_handle)
1615 struct winbindd_cm_conn *conn;
1618 struct dcinfo *p_dcinfo;
1620 result = init_dc_connection(domain);
1621 if (!NT_STATUS_IS_OK(result)) {
1625 conn = &domain->conn;
1627 if (conn->samr_pipe != NULL) {
1632 * No SAMR pipe yet. Attempt to get an NTLMSSP SPNEGO authenticated
1633 * sign and sealed pipe using the machine account password by
1634 * preference. If we can't - try schannel, if that fails, try
1638 pwd_get_cleartext(&conn->cli->pwd, conn_pwd);
1639 if ((conn->cli->user_name[0] == '\0') ||
1640 (conn->cli->domain[0] == '\0') ||
1641 (conn_pwd[0] == '\0')) {
1642 DEBUG(10, ("cm_connect_sam: No no user available for "
1643 "domain %s, trying schannel\n", conn->cli->domain));
1647 /* We have an authenticated connection. Use a NTLMSSP SPNEGO
1648 authenticated SAMR pipe with sign & seal. */
1650 cli_rpc_pipe_open_spnego_ntlmssp(conn->cli, PI_SAMR,
1651 PIPE_AUTH_LEVEL_PRIVACY,
1653 conn->cli->user_name,
1656 if (conn->samr_pipe == NULL) {
1657 DEBUG(10,("cm_connect_sam: failed to connect to SAMR "
1658 "pipe for domain %s using NTLMSSP "
1659 "authenticated pipe: user %s\\%s. Error was "
1660 "%s\n", domain->name, conn->cli->domain,
1661 conn->cli->user_name, nt_errstr(result)));
1665 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for "
1666 "domain %s using NTLMSSP authenticated "
1667 "pipe: user %s\\%s\n", domain->name,
1668 conn->cli->domain, conn->cli->user_name ));
1670 result = rpccli_samr_connect(conn->samr_pipe, mem_ctx,
1671 SEC_RIGHTS_MAXIMUM_ALLOWED,
1672 &conn->sam_connect_handle);
1673 if (NT_STATUS_IS_OK(result)) {
1676 DEBUG(10,("cm_connect_sam: ntlmssp-sealed rpccli_samr_connect "
1677 "failed for domain %s, error was %s. Trying schannel\n",
1678 domain->name, nt_errstr(result) ));
1679 cli_rpc_pipe_close(conn->samr_pipe);
1683 /* Fall back to schannel if it's a W2K pre-SP1 box. */
1685 if (!cm_get_schannel_dcinfo(domain, &p_dcinfo)) {
1686 DEBUG(10, ("cm_connect_sam: Could not get schannel auth info "
1687 "for domain %s, trying anon\n", conn->cli->domain));
1690 conn->samr_pipe = cli_rpc_pipe_open_schannel_with_key
1691 (conn->cli, PI_SAMR, PIPE_AUTH_LEVEL_PRIVACY,
1692 domain->name, p_dcinfo, &result);
1694 if (conn->samr_pipe == NULL) {
1695 DEBUG(10,("cm_connect_sam: failed to connect to SAMR pipe for "
1696 "domain %s using schannel. Error was %s\n",
1697 domain->name, nt_errstr(result) ));
1700 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for domain %s using "
1701 "schannel.\n", domain->name ));
1703 result = rpccli_samr_connect(conn->samr_pipe, mem_ctx,
1704 SEC_RIGHTS_MAXIMUM_ALLOWED,
1705 &conn->sam_connect_handle);
1706 if (NT_STATUS_IS_OK(result)) {
1709 DEBUG(10,("cm_connect_sam: schannel-sealed rpccli_samr_connect failed "
1710 "for domain %s, error was %s. Trying anonymous\n",
1711 domain->name, nt_errstr(result) ));
1712 cli_rpc_pipe_close(conn->samr_pipe);
1716 /* Finally fall back to anonymous. */
1717 conn->samr_pipe = cli_rpc_pipe_open_noauth(conn->cli, PI_SAMR,
1720 if (conn->samr_pipe == NULL) {
1721 result = NT_STATUS_PIPE_NOT_AVAILABLE;
1725 result = rpccli_samr_connect(conn->samr_pipe, mem_ctx,
1726 SEC_RIGHTS_MAXIMUM_ALLOWED,
1727 &conn->sam_connect_handle);
1728 if (!NT_STATUS_IS_OK(result)) {
1729 DEBUG(10,("cm_connect_sam: rpccli_samr_connect failed "
1730 "for domain %s Error was %s\n",
1731 domain->name, nt_errstr(result) ));
1736 result = rpccli_samr_open_domain(conn->samr_pipe,
1738 &conn->sam_connect_handle,
1739 SEC_RIGHTS_MAXIMUM_ALLOWED,
1741 &conn->sam_domain_handle);
1745 if (!NT_STATUS_IS_OK(result)) {
1746 invalidate_cm_connection(conn);
1750 *cli = conn->samr_pipe;
1751 *sam_handle = conn->sam_domain_handle;
1755 NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
1756 struct rpc_pipe_client **cli, POLICY_HND *lsa_policy)
1758 struct winbindd_cm_conn *conn;
1761 struct dcinfo *p_dcinfo;
1763 result = init_dc_connection(domain);
1764 if (!NT_STATUS_IS_OK(result))
1767 conn = &domain->conn;
1769 if (conn->lsa_pipe != NULL) {
1773 pwd_get_cleartext(&conn->cli->pwd, conn_pwd);
1774 if ((conn->cli->user_name[0] == '\0') ||
1775 (conn->cli->domain[0] == '\0') ||
1776 (conn_pwd[0] == '\0')) {
1777 DEBUG(10, ("cm_connect_lsa: No no user available for "
1778 "domain %s, trying schannel\n", conn->cli->domain));
1782 /* We have an authenticated connection. Use a NTLMSSP SPNEGO
1783 * authenticated LSA pipe with sign & seal. */
1784 conn->lsa_pipe = cli_rpc_pipe_open_spnego_ntlmssp
1785 (conn->cli, PI_LSARPC, PIPE_AUTH_LEVEL_PRIVACY,
1786 conn->cli->domain, conn->cli->user_name, conn_pwd, &result);
1788 if (conn->lsa_pipe == NULL) {
1789 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
1790 "domain %s using NTLMSSP authenticated pipe: user "
1791 "%s\\%s. Error was %s. Trying schannel.\n",
1792 domain->name, conn->cli->domain,
1793 conn->cli->user_name, nt_errstr(result)));
1797 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
1798 "NTLMSSP authenticated pipe: user %s\\%s\n",
1799 domain->name, conn->cli->domain, conn->cli->user_name ));
1801 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
1802 SEC_RIGHTS_MAXIMUM_ALLOWED,
1804 if (NT_STATUS_IS_OK(result)) {
1808 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
1811 cli_rpc_pipe_close(conn->lsa_pipe);
1815 /* Fall back to schannel if it's a W2K pre-SP1 box. */
1817 if (!cm_get_schannel_dcinfo(domain, &p_dcinfo)) {
1818 DEBUG(10, ("cm_connect_lsa: Could not get schannel auth info "
1819 "for domain %s, trying anon\n", conn->cli->domain));
1822 conn->lsa_pipe = cli_rpc_pipe_open_schannel_with_key
1823 (conn->cli, PI_LSARPC, PIPE_AUTH_LEVEL_PRIVACY,
1824 domain->name, p_dcinfo, &result);
1826 if (conn->lsa_pipe == NULL) {
1827 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
1828 "domain %s using schannel. Error was %s\n",
1829 domain->name, nt_errstr(result) ));
1832 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
1833 "schannel.\n", domain->name ));
1835 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
1836 SEC_RIGHTS_MAXIMUM_ALLOWED,
1838 if (NT_STATUS_IS_OK(result)) {
1842 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
1845 cli_rpc_pipe_close(conn->lsa_pipe);
1849 conn->lsa_pipe = cli_rpc_pipe_open_noauth(conn->cli, PI_LSARPC,
1851 if (conn->lsa_pipe == NULL) {
1852 result = NT_STATUS_PIPE_NOT_AVAILABLE;
1856 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
1857 SEC_RIGHTS_MAXIMUM_ALLOWED,
1860 if (!NT_STATUS_IS_OK(result)) {
1861 invalidate_cm_connection(conn);
1862 return NT_STATUS_UNSUCCESSFUL;
1865 *cli = conn->lsa_pipe;
1866 *lsa_policy = conn->lsa_policy;
1870 /****************************************************************************
1871 Open the netlogon pipe to this DC. Use schannel if specified in client conf.
1872 session key stored in conn->netlogon_pipe->dc->sess_key.
1873 ****************************************************************************/
1875 NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
1876 struct rpc_pipe_client **cli)
1878 struct winbindd_cm_conn *conn;
1881 uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
1883 uint32 sec_chan_type;
1884 const char *account_name;
1885 struct rpc_pipe_client *netlogon_pipe = NULL;
1889 result = init_dc_connection(domain);
1890 if (!NT_STATUS_IS_OK(result)) {
1894 conn = &domain->conn;
1896 if (conn->netlogon_pipe != NULL) {
1897 *cli = conn->netlogon_pipe;
1898 return NT_STATUS_OK;
1901 if (!get_trust_pw(domain->name, mach_pwd, &sec_chan_type)) {
1902 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1905 netlogon_pipe = cli_rpc_pipe_open_noauth(conn->cli, PI_NETLOGON,
1907 if (netlogon_pipe == NULL) {
1911 if (lp_client_schannel() != False) {
1912 neg_flags |= NETLOGON_NEG_SCHANNEL;
1915 /* if we are a DC and this is a trusted domain, then we need to use our
1916 domain name in the net_req_auth2() request */
1919 && !strequal(domain->name, lp_workgroup())
1920 && lp_allow_trusted_domains() )
1922 account_name = lp_workgroup();
1924 account_name = domain->primary ?
1925 global_myname() : domain->name;
1928 if (account_name == NULL) {
1929 cli_rpc_pipe_close(netlogon_pipe);
1930 return NT_STATUS_NO_MEMORY;
1933 result = rpccli_netlogon_setup_creds(
1935 domain->dcname, /* server name. */
1936 domain->name, /* domain name */
1937 global_myname(), /* client name */
1938 account_name, /* machine account */
1939 mach_pwd, /* machine password */
1940 sec_chan_type, /* from get_trust_pw */
1943 if (!NT_STATUS_IS_OK(result)) {
1944 cli_rpc_pipe_close(netlogon_pipe);
1948 if ((lp_client_schannel() == True) &&
1949 ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
1950 DEBUG(3, ("Server did not offer schannel\n"));
1951 cli_rpc_pipe_close(netlogon_pipe);
1952 return NT_STATUS_ACCESS_DENIED;
1955 if ((lp_client_schannel() == False) ||
1956 ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
1957 /* We're done - just keep the existing connection to NETLOGON
1959 conn->netlogon_pipe = netlogon_pipe;
1960 *cli = conn->netlogon_pipe;
1961 return NT_STATUS_OK;
1964 /* Using the credentials from the first pipe, open a signed and sealed
1965 second netlogon pipe. The session key is stored in the schannel
1966 part of the new pipe auth struct.
1969 conn->netlogon_pipe =
1970 cli_rpc_pipe_open_schannel_with_key(conn->cli,
1972 PIPE_AUTH_LEVEL_PRIVACY,
1977 /* We can now close the initial netlogon pipe. */
1978 cli_rpc_pipe_close(netlogon_pipe);
1980 if (conn->netlogon_pipe == NULL) {
1981 DEBUG(3, ("Could not open schannel'ed NETLOGON pipe. Error "
1982 "was %s\n", nt_errstr(result)));
1984 /* make sure we return something besides OK */
1985 return !NT_STATUS_IS_OK(result) ? result : NT_STATUS_PIPE_NOT_AVAILABLE;
1988 *cli = conn->netlogon_pipe;
1989 return NT_STATUS_OK;