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 3 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, see <http://www.gnu.org/licenses/>.
27 We need to manage connections to domain controllers without having to
28 mess up the main winbindd code with other issues. The aim of the
29 connection manager is to:
31 - make connections to domain controllers and cache them
32 - re-establish connections when networks or servers go down
33 - centralise the policy on connection timeouts, domain controller
35 - manage re-entrancy for when winbindd becomes able to handle
36 multiple outstanding rpc requests
38 Why not have connection management as part of the rpc layer like tng?
39 Good question. This code may morph into libsmb/rpc_cache.c or something
40 like that but at the moment it's simply staying as part of winbind. I
41 think the TNG architecture of forcing every user of the rpc layer to use
42 the connection caching system is a bad idea. It should be an optional
43 method of using the routines.
45 The TNG design is quite good but I disagree with some aspects of the
53 - I'm pretty annoyed by all the make_nmb_name() stuff. It should be
54 moved down into another function.
56 - Take care when destroying cli_structs as they can be shared between
63 #include "../libcli/auth/libcli_auth.h"
64 #include "../librpc/gen_ndr/cli_netlogon.h"
65 #include "rpc_client/cli_netlogon.h"
66 #include "../librpc/gen_ndr/cli_samr.h"
67 #include "../librpc/gen_ndr/cli_lsa.h"
68 #include "rpc_client/cli_lsarpc.h"
69 #include "../librpc/gen_ndr/cli_dssetup.h"
70 #include "libads/sitename_cache.h"
71 #include "librpc/gen_ndr/messaging.h"
72 #include "libsmb/clidgram.h"
77 #define DBGC_CLASS DBGC_WINBIND
81 struct sockaddr_storage ss;
84 extern struct winbindd_methods reconnect_methods;
85 extern bool override_logfile;
87 static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain);
88 static void set_dc_type_and_flags( struct winbindd_domain *domain );
89 static bool get_dcs(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
90 struct dc_name_ip **dcs, int *num_dcs);
92 /****************************************************************
93 Child failed to find DC's. Reschedule check.
94 ****************************************************************/
96 static void msg_failed_to_go_online(struct messaging_context *msg,
99 struct server_id server_id,
102 struct winbindd_domain *domain;
103 const char *domainname = (const char *)data->data;
105 if (data->data == NULL || data->length == 0) {
109 DEBUG(5,("msg_fail_to_go_online: received for domain %s.\n", domainname));
111 for (domain = domain_list(); domain; domain = domain->next) {
112 if (domain->internal) {
116 if (strequal(domain->name, domainname)) {
117 if (domain->online) {
118 /* We're already online, ignore. */
119 DEBUG(5,("msg_fail_to_go_online: domain %s "
120 "already online.\n", domainname));
124 /* Reschedule the online check. */
125 set_domain_offline(domain);
131 /****************************************************************
132 Actually cause a reconnect from a message.
133 ****************************************************************/
135 static void msg_try_to_go_online(struct messaging_context *msg,
138 struct server_id server_id,
141 struct winbindd_domain *domain;
142 const char *domainname = (const char *)data->data;
144 if (data->data == NULL || data->length == 0) {
148 DEBUG(5,("msg_try_to_go_online: received for domain %s.\n", domainname));
150 for (domain = domain_list(); domain; domain = domain->next) {
151 if (domain->internal) {
155 if (strequal(domain->name, domainname)) {
157 if (domain->online) {
158 /* We're already online, ignore. */
159 DEBUG(5,("msg_try_to_go_online: domain %s "
160 "already online.\n", domainname));
164 /* This call takes care of setting the online
165 flag to true if we connected, or re-adding
166 the offline handler if false. Bypasses online
167 check so always does network calls. */
169 init_dc_connection_network(domain);
175 /****************************************************************
176 Fork a child to try and contact a DC. Do this as contacting a
177 DC requires blocking lookups and we don't want to block our
179 ****************************************************************/
181 static bool fork_child_dc_connect(struct winbindd_domain *domain)
183 struct dc_name_ip *dcs = NULL;
185 TALLOC_CTX *mem_ctx = NULL;
186 pid_t parent_pid = sys_getpid();
189 if (domain->dc_probe_pid != (pid_t)-1) {
191 * We might already have a DC probe
192 * child working, check.
194 if (process_exists_by_pid(domain->dc_probe_pid)) {
195 DEBUG(10,("fork_child_dc_connect: pid %u already "
196 "checking for DC's.\n",
197 (unsigned int)domain->dc_probe_pid));
200 domain->dc_probe_pid = (pid_t)-1;
203 domain->dc_probe_pid = sys_fork();
205 if (domain->dc_probe_pid == (pid_t)-1) {
206 DEBUG(0, ("fork_child_dc_connect: Could not fork: %s\n", strerror(errno)));
210 if (domain->dc_probe_pid != (pid_t)0) {
212 messaging_register(winbind_messaging_context(), NULL,
213 MSG_WINBIND_TRY_TO_GO_ONLINE,
214 msg_try_to_go_online);
215 messaging_register(winbind_messaging_context(), NULL,
216 MSG_WINBIND_FAILED_TO_GO_ONLINE,
217 msg_failed_to_go_online);
223 /* Leave messages blocked - we will never process one. */
225 if (!override_logfile) {
226 if (asprintf(&lfile, "%s/log.winbindd-dc-connect", get_dyn_LOGFILEBASE()) == -1) {
227 DEBUG(0, ("fork_child_dc_connect: out of memory.\n"));
232 if (!winbindd_reinit_after_fork(lfile)) {
233 messaging_send_buf(winbind_messaging_context(),
234 pid_to_procid(parent_pid),
235 MSG_WINBIND_FAILED_TO_GO_ONLINE,
236 (uint8 *)domain->name,
237 strlen(domain->name)+1);
242 mem_ctx = talloc_init("fork_child_dc_connect");
244 DEBUG(0,("talloc_init failed.\n"));
245 messaging_send_buf(winbind_messaging_context(),
246 pid_to_procid(parent_pid),
247 MSG_WINBIND_FAILED_TO_GO_ONLINE,
248 (uint8 *)domain->name,
249 strlen(domain->name)+1);
253 if ((!get_dcs(mem_ctx, domain, &dcs, &num_dcs)) || (num_dcs == 0)) {
254 /* Still offline ? Can't find DC's. */
255 messaging_send_buf(winbind_messaging_context(),
256 pid_to_procid(parent_pid),
257 MSG_WINBIND_FAILED_TO_GO_ONLINE,
258 (uint8 *)domain->name,
259 strlen(domain->name)+1);
263 /* We got a DC. Send a message to our parent to get it to
264 try and do the same. */
266 messaging_send_buf(winbind_messaging_context(),
267 pid_to_procid(parent_pid),
268 MSG_WINBIND_TRY_TO_GO_ONLINE,
269 (uint8 *)domain->name,
270 strlen(domain->name)+1);
274 /****************************************************************
275 Handler triggered if we're offline to try and detect a DC.
276 ****************************************************************/
278 static void check_domain_online_handler(struct event_context *ctx,
279 struct timed_event *te,
283 struct winbindd_domain *domain =
284 (struct winbindd_domain *)private_data;
286 DEBUG(10,("check_domain_online_handler: called for domain "
287 "%s (online = %s)\n", domain->name,
288 domain->online ? "True" : "False" ));
290 TALLOC_FREE(domain->check_online_event);
292 /* Are we still in "startup" mode ? */
294 if (domain->startup && (now.tv_sec > domain->startup_time + 30)) {
295 /* No longer in "startup" mode. */
296 DEBUG(10,("check_domain_online_handler: domain %s no longer in 'startup' mode.\n",
298 domain->startup = False;
301 /* We've been told to stay offline, so stay
304 if (get_global_winbindd_state_offline()) {
305 DEBUG(10,("check_domain_online_handler: domain %s remaining globally offline\n",
310 /* Fork a child to test if it can contact a DC.
311 If it can then send ourselves a message to
312 cause a reconnect. */
314 fork_child_dc_connect(domain);
317 /****************************************************************
318 If we're still offline setup the timeout check.
319 ****************************************************************/
321 static void calc_new_online_timeout_check(struct winbindd_domain *domain)
323 int wbr = lp_winbind_reconnect_delay();
325 if (domain->startup) {
326 domain->check_online_timeout = 10;
327 } else if (domain->check_online_timeout < wbr) {
328 domain->check_online_timeout = wbr;
332 /****************************************************************
333 Set domain offline and also add handler to put us back online
335 ****************************************************************/
337 void set_domain_offline(struct winbindd_domain *domain)
339 DEBUG(10,("set_domain_offline: called for domain %s\n",
342 TALLOC_FREE(domain->check_online_event);
344 if (domain->internal) {
345 DEBUG(3,("set_domain_offline: domain %s is internal - logic error.\n",
350 domain->online = False;
352 /* Offline domains are always initialized. They're
353 re-initialized when they go back online. */
355 domain->initialized = True;
357 /* We only add the timeout handler that checks and
358 allows us to go back online when we've not
359 been told to remain offline. */
361 if (get_global_winbindd_state_offline()) {
362 DEBUG(10,("set_domain_offline: domain %s remaining globally offline\n",
367 /* If we're in startup mode, check again in 10 seconds, not in
368 lp_winbind_reconnect_delay() seconds (which is 30 seconds by default). */
370 calc_new_online_timeout_check(domain);
372 domain->check_online_event = event_add_timed(winbind_event_context(),
374 timeval_current_ofs(domain->check_online_timeout,0),
375 check_domain_online_handler,
378 /* The above *has* to succeed for winbindd to work. */
379 if (!domain->check_online_event) {
380 smb_panic("set_domain_offline: failed to add online handler");
383 DEBUG(10,("set_domain_offline: added event handler for domain %s\n",
386 /* Send an offline message to the idmap child when our
387 primary domain goes offline */
389 if ( domain->primary ) {
390 struct winbindd_child *idmap = idmap_child();
392 if ( idmap->pid != 0 ) {
393 messaging_send_buf(winbind_messaging_context(),
394 pid_to_procid(idmap->pid),
396 (uint8 *)domain->name,
397 strlen(domain->name)+1);
404 /****************************************************************
405 Set domain online - if allowed.
406 ****************************************************************/
408 static void set_domain_online(struct winbindd_domain *domain)
410 DEBUG(10,("set_domain_online: called for domain %s\n",
413 if (domain->internal) {
414 DEBUG(3,("set_domain_online: domain %s is internal - logic error.\n",
419 if (get_global_winbindd_state_offline()) {
420 DEBUG(10,("set_domain_online: domain %s remaining globally offline\n",
425 winbindd_set_locator_kdc_envs(domain);
427 /* If we are waiting to get a krb5 ticket, trigger immediately. */
428 ccache_regain_all_now();
430 /* Ok, we're out of any startup mode now... */
431 domain->startup = False;
433 if (domain->online == False) {
434 /* We were offline - now we're online. We default to
435 using the MS-RPC backend if we started offline,
436 and if we're going online for the first time we
437 should really re-initialize the backends and the
438 checks to see if we're talking to an AD or NT domain.
441 domain->initialized = False;
443 /* 'reconnect_methods' is the MS-RPC backend. */
444 if (domain->backend == &reconnect_methods) {
445 domain->backend = NULL;
449 /* Ensure we have no online timeout checks. */
450 domain->check_online_timeout = 0;
451 TALLOC_FREE(domain->check_online_event);
453 /* Ensure we ignore any pending child messages. */
454 messaging_deregister(winbind_messaging_context(),
455 MSG_WINBIND_TRY_TO_GO_ONLINE, NULL);
456 messaging_deregister(winbind_messaging_context(),
457 MSG_WINBIND_FAILED_TO_GO_ONLINE, NULL);
459 domain->online = True;
461 /* Send an online message to the idmap child when our
462 primary domain comes online */
464 if ( domain->primary ) {
465 struct winbindd_child *idmap = idmap_child();
467 if ( idmap->pid != 0 ) {
468 messaging_send_buf(winbind_messaging_context(),
469 pid_to_procid(idmap->pid),
471 (uint8 *)domain->name,
472 strlen(domain->name)+1);
479 /****************************************************************
480 Requested to set a domain online.
481 ****************************************************************/
483 void set_domain_online_request(struct winbindd_domain *domain)
487 DEBUG(10,("set_domain_online_request: called for domain %s\n",
490 if (get_global_winbindd_state_offline()) {
491 DEBUG(10,("set_domain_online_request: domain %s remaining globally offline\n",
496 if (domain->internal) {
497 DEBUG(10, ("set_domain_online_request: Internal domains are "
502 /* We've been told it's safe to go online and
503 try and connect to a DC. But I don't believe it
504 because network manager seems to lie.
505 Wait at least 5 seconds. Heuristics suck... */
510 /* Go into "startup" mode again. */
511 domain->startup_time = tev.tv_sec;
512 domain->startup = True;
516 if (!domain->check_online_event) {
517 /* If we've come from being globally offline we
518 don't have a check online event handler set.
519 We need to add one now we're trying to go
522 DEBUG(10,("set_domain_online_request: domain %s was globally offline.\n",
526 TALLOC_FREE(domain->check_online_event);
528 domain->check_online_event = event_add_timed(winbind_event_context(),
531 check_domain_online_handler,
534 /* The above *has* to succeed for winbindd to work. */
535 if (!domain->check_online_event) {
536 smb_panic("set_domain_online_request: failed to add online handler");
540 /****************************************************************
541 Add -ve connection cache entries for domain and realm.
542 ****************************************************************/
544 void winbind_add_failed_connection_entry(const struct winbindd_domain *domain,
548 add_failed_connection_entry(domain->name, server, result);
549 /* If this was the saf name for the last thing we talked to,
551 saf_delete(domain->name);
552 if (*domain->alt_name) {
553 add_failed_connection_entry(domain->alt_name, server, result);
554 saf_delete(domain->alt_name);
556 winbindd_unset_locator_kdc_env(domain);
559 /* Choose between anonymous or authenticated connections. We need to use
560 an authenticated connection if DCs have the RestrictAnonymous registry
561 entry set > 0, or the "Additional restrictions for anonymous
562 connections" set in the win2k Local Security Policy.
564 Caller to free() result in domain, username, password
567 static void cm_get_ipc_userpass(char **username, char **domain, char **password)
569 *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
570 *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
571 *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
573 if (*username && **username) {
575 if (!*domain || !**domain)
576 *domain = smb_xstrdup(lp_workgroup());
578 if (!*password || !**password)
579 *password = smb_xstrdup("");
581 DEBUG(3, ("cm_get_ipc_userpass: Retrieved auth-user from secrets.tdb [%s\\%s]\n",
582 *domain, *username));
585 DEBUG(3, ("cm_get_ipc_userpass: No auth-user defined\n"));
586 *username = smb_xstrdup("");
587 *domain = smb_xstrdup("");
588 *password = smb_xstrdup("");
592 static bool get_dc_name_via_netlogon(struct winbindd_domain *domain,
594 struct sockaddr_storage *dc_ss)
596 struct winbindd_domain *our_domain = NULL;
597 struct rpc_pipe_client *netlogon_pipe = NULL;
601 unsigned int orig_timeout;
602 const char *tmp = NULL;
605 /* Hmmmm. We can only open one connection to the NETLOGON pipe at the
612 if (domain->primary) {
616 our_domain = find_our_domain();
618 if ((mem_ctx = talloc_init("get_dc_name_via_netlogon")) == NULL) {
622 result = cm_connect_netlogon(our_domain, &netlogon_pipe);
623 if (!NT_STATUS_IS_OK(result)) {
624 talloc_destroy(mem_ctx);
628 /* This call can take a long time - allow the server to time out.
629 35 seconds should do it. */
631 orig_timeout = rpccli_set_timeout(netlogon_pipe, 35000);
633 if (our_domain->active_directory) {
634 struct netr_DsRGetDCNameInfo *domain_info = NULL;
636 result = rpccli_netr_DsRGetDCName(netlogon_pipe,
645 if (NT_STATUS_IS_OK(result) && W_ERROR_IS_OK(werr)) {
647 mem_ctx, domain_info->dc_unc);
649 DEBUG(0, ("talloc_strdup failed\n"));
650 talloc_destroy(mem_ctx);
653 if (strlen(domain->alt_name) == 0) {
654 fstrcpy(domain->alt_name,
655 domain_info->domain_name);
657 if (strlen(domain->forest_name) == 0) {
658 fstrcpy(domain->forest_name,
659 domain_info->forest_name);
663 result = rpccli_netr_GetAnyDCName(netlogon_pipe, mem_ctx,
670 /* And restore our original timeout. */
671 rpccli_set_timeout(netlogon_pipe, orig_timeout);
673 if (!NT_STATUS_IS_OK(result)) {
674 DEBUG(10,("rpccli_netr_GetAnyDCName failed: %s\n",
676 talloc_destroy(mem_ctx);
680 if (!W_ERROR_IS_OK(werr)) {
681 DEBUG(10,("rpccli_netr_GetAnyDCName failed: %s\n",
683 talloc_destroy(mem_ctx);
687 /* rpccli_netr_GetAnyDCName gives us a name with \\ */
688 p = strip_hostname(tmp);
692 talloc_destroy(mem_ctx);
694 DEBUG(10,("rpccli_netr_GetAnyDCName returned %s\n", dcname));
696 if (!resolve_name(dcname, dc_ss, 0x20, true)) {
704 * Helper function to assemble trust password and account name
706 static NTSTATUS get_trust_creds(const struct winbindd_domain *domain,
707 char **machine_password,
708 char **machine_account,
709 char **machine_krb5_principal)
711 const char *account_name;
712 const char *name = NULL;
714 /* If we are a DC and this is not our own domain */
719 struct winbindd_domain *our_domain = find_our_domain();
722 return NT_STATUS_INVALID_SERVER_STATE;
724 name = our_domain->name;
727 if (!get_trust_pw_clear(name, machine_password,
728 &account_name, NULL))
730 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
733 if ((machine_account != NULL) &&
734 (asprintf(machine_account, "%s$", account_name) == -1))
736 return NT_STATUS_NO_MEMORY;
739 /* For now assume our machine account only exists in our domain */
741 if (machine_krb5_principal != NULL)
743 struct winbindd_domain *our_domain = find_our_domain();
746 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
749 if (asprintf(machine_krb5_principal, "%s$@%s",
750 account_name, our_domain->alt_name) == -1)
752 return NT_STATUS_NO_MEMORY;
755 strupper_m(*machine_krb5_principal);
761 /************************************************************************
762 Given a fd with a just-connected TCP connection to a DC, open a connection
764 ************************************************************************/
766 static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
768 const char *controller,
769 struct cli_state **cli,
772 char *machine_password = NULL;
773 char *machine_krb5_principal = NULL;
774 char *machine_account = NULL;
775 char *ipc_username = NULL;
776 char *ipc_domain = NULL;
777 char *ipc_password = NULL;
779 struct named_mutex *mutex;
781 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
783 struct sockaddr peeraddr;
784 socklen_t peeraddr_len;
786 struct sockaddr_in *peeraddr_in =
787 (struct sockaddr_in *)(void *)&peeraddr;
789 DEBUG(10,("cm_prepare_connection: connecting to DC %s for domain %s\n",
790 controller, domain->name ));
794 mutex = grab_named_mutex(talloc_tos(), controller,
795 WINBIND_SERVER_MUTEX_WAIT_TIME);
797 DEBUG(0,("cm_prepare_connection: mutex grab failed for %s\n",
799 result = NT_STATUS_POSSIBLE_DEADLOCK;
803 if ((*cli = cli_initialise()) == NULL) {
804 DEBUG(1, ("Could not cli_initialize\n"));
805 result = NT_STATUS_NO_MEMORY;
809 (*cli)->timeout = 10000; /* 10 seconds */
811 fstrcpy((*cli)->desthost, controller);
812 (*cli)->use_kerberos = True;
814 peeraddr_len = sizeof(peeraddr);
816 if ((getpeername((*cli)->fd, &peeraddr, &peeraddr_len) != 0)) {
817 DEBUG(0,("cm_prepare_connection: getpeername failed with: %s\n",
819 result = NT_STATUS_UNSUCCESSFUL;
823 if ((peeraddr_len != sizeof(struct sockaddr_in))
825 && (peeraddr_len != sizeof(struct sockaddr_in6))
828 DEBUG(0,("cm_prepare_connection: got unexpected peeraddr len %d\n",
830 result = NT_STATUS_UNSUCCESSFUL;
834 if ((peeraddr_in->sin_family != PF_INET)
836 && (peeraddr_in->sin_family != PF_INET6)
839 DEBUG(0,("cm_prepare_connection: got unexpected family %d\n",
840 peeraddr_in->sin_family));
841 result = NT_STATUS_UNSUCCESSFUL;
845 if (ntohs(peeraddr_in->sin_port) == 139) {
846 struct nmb_name calling;
847 struct nmb_name called;
849 make_nmb_name(&calling, global_myname(), 0x0);
850 make_nmb_name(&called, "*SMBSERVER", 0x20);
852 if (!cli_session_request(*cli, &calling, &called)) {
853 DEBUG(8, ("cli_session_request failed for %s\n",
855 result = NT_STATUS_UNSUCCESSFUL;
860 result = cli_negprot(*cli);
862 if (!NT_STATUS_IS_OK(result)) {
863 DEBUG(1, ("cli_negprot failed: %s\n", nt_errstr(result)));
867 if (!is_dc_trusted_domain_situation(domain->name) &&
868 (*cli)->protocol >= PROTOCOL_NT1 &&
869 (*cli)->capabilities & CAP_EXTENDED_SECURITY)
871 ADS_STATUS ads_status;
873 result = get_trust_creds(domain, &machine_password,
875 &machine_krb5_principal);
876 if (!NT_STATUS_IS_OK(result)) {
880 if (lp_security() == SEC_ADS) {
882 /* Try a krb5 session */
884 (*cli)->use_kerberos = True;
885 DEBUG(5, ("connecting to %s from %s with kerberos principal "
886 "[%s] and realm [%s]\n", controller, global_myname(),
887 machine_krb5_principal, domain->alt_name));
889 winbindd_set_locator_kdc_envs(domain);
891 ads_status = cli_session_setup_spnego(*cli,
892 machine_krb5_principal,
897 if (!ADS_ERR_OK(ads_status)) {
898 DEBUG(4,("failed kerberos session setup with %s\n",
899 ads_errstr(ads_status)));
902 result = ads_ntstatus(ads_status);
903 if (NT_STATUS_IS_OK(result)) {
904 /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
905 result = cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
906 if (!NT_STATUS_IS_OK(result)) {
909 goto session_setup_done;
913 /* Fall back to non-kerberos session setup using NTLMSSP SPNEGO with the machine account. */
914 (*cli)->use_kerberos = False;
916 DEBUG(5, ("connecting to %s from %s with username "
917 "[%s]\\[%s]\n", controller, global_myname(),
918 lp_workgroup(), machine_account));
920 ads_status = cli_session_setup_spnego(*cli,
925 if (!ADS_ERR_OK(ads_status)) {
926 DEBUG(4, ("authenticated session setup failed with %s\n",
927 ads_errstr(ads_status)));
930 result = ads_ntstatus(ads_status);
931 if (NT_STATUS_IS_OK(result)) {
932 /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
933 result = cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
934 if (!NT_STATUS_IS_OK(result)) {
937 goto session_setup_done;
941 /* Fall back to non-kerberos session setup with auth_user */
943 (*cli)->use_kerberos = False;
945 cm_get_ipc_userpass(&ipc_username, &ipc_domain, &ipc_password);
947 if ((((*cli)->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) != 0) &&
948 (strlen(ipc_username) > 0)) {
950 /* Only try authenticated if we have a username */
952 DEBUG(5, ("connecting to %s from %s with username "
953 "[%s]\\[%s]\n", controller, global_myname(),
954 ipc_domain, ipc_username));
956 if (NT_STATUS_IS_OK(cli_session_setup(
958 ipc_password, strlen(ipc_password)+1,
959 ipc_password, strlen(ipc_password)+1,
961 /* Successful logon with given username. */
962 result = cli_init_creds(*cli, ipc_username, ipc_domain, ipc_password);
963 if (!NT_STATUS_IS_OK(result)) {
966 goto session_setup_done;
968 DEBUG(4, ("authenticated session setup with user %s\\%s failed.\n",
969 ipc_domain, ipc_username ));
975 /* Fall back to anonymous connection, this might fail later */
976 DEBUG(10,("cm_prepare_connection: falling back to anonymous "
977 "connection for DC %s\n",
980 if (NT_STATUS_IS_OK(cli_session_setup(*cli, "", NULL, 0,
982 DEBUG(5, ("Connected anonymously\n"));
983 result = cli_init_creds(*cli, "", "", "");
984 if (!NT_STATUS_IS_OK(result)) {
987 goto session_setup_done;
990 result = cli_nt_error(*cli);
992 if (NT_STATUS_IS_OK(result))
993 result = NT_STATUS_UNSUCCESSFUL;
995 /* We can't session setup */
1001 /* cache the server name for later connections */
1003 saf_store( domain->name, (*cli)->desthost );
1004 if (domain->alt_name && (*cli)->use_kerberos) {
1005 saf_store( domain->alt_name, (*cli)->desthost );
1008 winbindd_set_locator_kdc_envs(domain);
1010 result = cli_tcon_andx(*cli, "IPC$", "IPC", "", 0);
1012 if (!NT_STATUS_IS_OK(result)) {
1013 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(result)));
1020 /* set the domain if empty; needed for schannel connections */
1021 if ( !(*cli)->domain[0] ) {
1022 result = cli_set_domain((*cli), domain->name);
1023 if (!NT_STATUS_IS_OK(result)) {
1028 result = NT_STATUS_OK;
1032 SAFE_FREE(machine_account);
1033 SAFE_FREE(machine_password);
1034 SAFE_FREE(machine_krb5_principal);
1035 SAFE_FREE(ipc_username);
1036 SAFE_FREE(ipc_domain);
1037 SAFE_FREE(ipc_password);
1039 if (!NT_STATUS_IS_OK(result)) {
1040 winbind_add_failed_connection_entry(domain, controller, result);
1041 if ((*cli) != NULL) {
1050 /*******************************************************************
1051 Add a dcname and sockaddr_storage pair to the end of a dc_name_ip
1054 Keeps the list unique by not adding duplicate entries.
1056 @param[in] mem_ctx talloc memory context to allocate from
1057 @param[in] domain_name domain of the DC
1058 @param[in] dcname name of the DC to add to the list
1059 @param[in] pss Internet address and port pair to add to the list
1060 @param[in,out] dcs array of dc_name_ip structures to add to
1061 @param[in,out] num_dcs number of dcs returned in the dcs array
1062 @return true if the list was added to, false otherwise
1063 *******************************************************************/
1065 static bool add_one_dc_unique(TALLOC_CTX *mem_ctx, const char *domain_name,
1066 const char *dcname, struct sockaddr_storage *pss,
1067 struct dc_name_ip **dcs, int *num)
1071 if (!NT_STATUS_IS_OK(check_negative_conn_cache(domain_name, dcname))) {
1072 DEBUG(10, ("DC %s was in the negative conn cache\n", dcname));
1076 /* Make sure there's no duplicates in the list */
1077 for (i=0; i<*num; i++)
1079 (struct sockaddr *)(void *)&(*dcs)[i].ss,
1080 (struct sockaddr *)(void *)pss))
1083 *dcs = TALLOC_REALLOC_ARRAY(mem_ctx, *dcs, struct dc_name_ip, (*num)+1);
1088 fstrcpy((*dcs)[*num].name, dcname);
1089 (*dcs)[*num].ss = *pss;
1094 static bool add_sockaddr_to_array(TALLOC_CTX *mem_ctx,
1095 struct sockaddr_storage *pss, uint16 port,
1096 struct sockaddr_storage **addrs, int *num)
1098 *addrs = TALLOC_REALLOC_ARRAY(mem_ctx, *addrs, struct sockaddr_storage, (*num)+1);
1100 if (*addrs == NULL) {
1105 (*addrs)[*num] = *pss;
1106 set_sockaddr_port((struct sockaddr *)&(*addrs)[*num], port);
1112 /*******************************************************************
1113 convert an ip to a name
1114 *******************************************************************/
1116 static bool dcip_to_name(TALLOC_CTX *mem_ctx,
1117 const struct winbindd_domain *domain,
1118 struct sockaddr_storage *pss,
1121 struct ip_service ip_list;
1122 uint32_t nt_version = NETLOGON_NT_VERSION_1;
1128 /* For active directory servers, try to get the ldap server name.
1129 None of these failures should be considered critical for now */
1131 if (lp_security() == SEC_ADS) {
1133 ADS_STATUS ads_status;
1134 char addr[INET6_ADDRSTRLEN];
1136 print_sockaddr(addr, sizeof(addr), pss);
1138 ads = ads_init(domain->alt_name, domain->name, addr);
1139 ads->auth.flags |= ADS_AUTH_NO_BIND;
1141 ads_status = ads_connect(ads);
1142 if (ADS_ERR_OK(ads_status)) {
1143 /* We got a cldap packet. */
1144 fstrcpy(name, ads->config.ldap_server_name);
1145 namecache_store(name, 0x20, 1, &ip_list);
1147 DEBUG(10,("dcip_to_name: flags = 0x%x\n", (unsigned int)ads->config.flags));
1149 if (domain->primary && (ads->config.flags & NBT_SERVER_KDC)) {
1150 if (ads_closest_dc(ads)) {
1151 char *sitename = sitename_fetch(ads->config.realm);
1153 /* We're going to use this KDC for this realm/domain.
1154 If we are using sites, then force the krb5 libs
1157 create_local_private_krb5_conf_for_domain(domain->alt_name,
1163 SAFE_FREE(sitename);
1165 /* use an off site KDC */
1166 create_local_private_krb5_conf_for_domain(domain->alt_name,
1172 winbindd_set_locator_kdc_envs(domain);
1174 /* Ensure we contact this DC also. */
1175 saf_store( domain->name, name);
1176 saf_store( domain->alt_name, name);
1179 ads_destroy( &ads );
1183 ads_destroy( &ads );
1187 /* try GETDC requests next */
1189 if (send_getdc_request(mem_ctx, winbind_messaging_context(),
1190 pss, domain->name, &domain->sid,
1192 const char *dc_name = NULL;
1195 for (i=0; i<5; i++) {
1196 if (receive_getdc_response(mem_ctx, pss, domain->name,
1199 fstrcpy(name, dc_name);
1200 namecache_store(name, 0x20, 1, &ip_list);
1207 /* try node status request */
1209 if ( name_status_find(domain->name, 0x1c, 0x20, pss, name) ) {
1210 namecache_store(name, 0x20, 1, &ip_list);
1216 /*******************************************************************
1217 Retrieve a list of IP addresses for domain controllers.
1219 The array is sorted in the preferred connection order.
1221 @param[in] mem_ctx talloc memory context to allocate from
1222 @param[in] domain domain to retrieve DCs for
1223 @param[out] dcs array of dcs that will be returned
1224 @param[out] num_dcs number of dcs returned in the dcs array
1226 *******************************************************************/
1228 static bool get_dcs(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
1229 struct dc_name_ip **dcs, int *num_dcs)
1232 struct sockaddr_storage ss;
1233 struct ip_service *ip_list = NULL;
1234 int iplist_size = 0;
1237 enum security_types sec = (enum security_types)lp_security();
1239 is_our_domain = strequal(domain->name, lp_workgroup());
1241 /* If not our domain, get the preferred DC, by asking our primary DC */
1243 && get_dc_name_via_netlogon(domain, dcname, &ss)
1244 && add_one_dc_unique(mem_ctx, domain->name, dcname, &ss, dcs,
1247 char addr[INET6_ADDRSTRLEN];
1248 print_sockaddr(addr, sizeof(addr), &ss);
1249 DEBUG(10, ("Retrieved DC %s at %s via netlogon\n",
1254 if (sec == SEC_ADS) {
1255 char *sitename = NULL;
1257 /* We need to make sure we know the local site before
1258 doing any DNS queries, as this will restrict the
1259 get_sorted_dc_list() call below to only fetching
1260 DNS records for the correct site. */
1262 /* Find any DC to get the site record.
1263 We deliberately don't care about the
1266 get_dc_name(domain->name, domain->alt_name, dcname, &ss);
1268 sitename = sitename_fetch(domain->alt_name);
1271 /* Do the site-specific AD dns lookup first. */
1272 get_sorted_dc_list(domain->alt_name, sitename, &ip_list,
1273 &iplist_size, True);
1275 /* Add ips to the DC array. We don't look up the name
1276 of the DC in this function, but we fill in the char*
1277 of the ip now to make the failed connection cache
1279 for ( i=0; i<iplist_size; i++ ) {
1280 char addr[INET6_ADDRSTRLEN];
1281 print_sockaddr(addr, sizeof(addr),
1283 add_one_dc_unique(mem_ctx,
1292 SAFE_FREE(sitename);
1296 /* Now we add DCs from the main AD DNS lookup. */
1297 get_sorted_dc_list(domain->alt_name, NULL, &ip_list,
1298 &iplist_size, True);
1300 for ( i=0; i<iplist_size; i++ ) {
1301 char addr[INET6_ADDRSTRLEN];
1302 print_sockaddr(addr, sizeof(addr),
1304 add_one_dc_unique(mem_ctx,
1316 /* Try standard netbios queries if no ADS */
1317 if (*num_dcs == 0) {
1318 get_sorted_dc_list(domain->name, NULL, &ip_list, &iplist_size,
1321 for ( i=0; i<iplist_size; i++ ) {
1322 char addr[INET6_ADDRSTRLEN];
1323 print_sockaddr(addr, sizeof(addr),
1325 add_one_dc_unique(mem_ctx,
1340 /*******************************************************************
1341 Find and make a connection to a DC in the given domain.
1343 @param[in] mem_ctx talloc memory context to allocate from
1344 @param[in] domain domain to find a dc in
1345 @param[out] dcname NetBIOS or FQDN of DC that's connected to
1346 @param[out] pss DC Internet address and port
1347 @param[out] fd fd of the open socket connected to the newly found dc
1348 @return true when a DC connection is made, false otherwise
1349 *******************************************************************/
1351 static bool find_new_dc(TALLOC_CTX *mem_ctx,
1352 struct winbindd_domain *domain,
1353 fstring dcname, struct sockaddr_storage *pss, int *fd)
1355 struct dc_name_ip *dcs = NULL;
1358 const char **dcnames = NULL;
1359 int num_dcnames = 0;
1361 struct sockaddr_storage *addrs = NULL;
1369 if (!get_dcs(mem_ctx, domain, &dcs, &num_dcs) || (num_dcs == 0))
1372 for (i=0; i<num_dcs; i++) {
1374 if (!add_string_to_array(mem_ctx, dcs[i].name,
1375 &dcnames, &num_dcnames)) {
1378 if (!add_sockaddr_to_array(mem_ctx, &dcs[i].ss, 445,
1379 &addrs, &num_addrs)) {
1383 if (!add_string_to_array(mem_ctx, dcs[i].name,
1384 &dcnames, &num_dcnames)) {
1387 if (!add_sockaddr_to_array(mem_ctx, &dcs[i].ss, 139,
1388 &addrs, &num_addrs)) {
1393 if ((num_dcnames == 0) || (num_dcnames != num_addrs))
1396 if ((addrs == NULL) || (dcnames == NULL))
1399 /* 5 second timeout. */
1400 if (!open_any_socket_out(addrs, num_addrs, 5000, &fd_index, fd) ) {
1401 for (i=0; i<num_dcs; i++) {
1402 char ab[INET6_ADDRSTRLEN];
1403 print_sockaddr(ab, sizeof(ab), &dcs[i].ss);
1404 DEBUG(10, ("find_new_dc: open_any_socket_out failed for "
1405 "domain %s address %s. Error was %s\n",
1406 domain->name, ab, strerror(errno) ));
1407 winbind_add_failed_connection_entry(domain,
1408 dcs[i].name, NT_STATUS_UNSUCCESSFUL);
1413 *pss = addrs[fd_index];
1415 if (*dcnames[fd_index] != '\0' && !is_ipaddress(dcnames[fd_index])) {
1416 /* Ok, we've got a name for the DC */
1417 fstrcpy(dcname, dcnames[fd_index]);
1421 /* Try to figure out the name */
1422 if (dcip_to_name(mem_ctx, domain, pss, dcname)) {
1426 /* We can not continue without the DC's name */
1427 winbind_add_failed_connection_entry(domain, dcs[fd_index].name,
1428 NT_STATUS_UNSUCCESSFUL);
1430 /* Throw away all arrays as we're doing this again. */
1434 TALLOC_FREE(dcnames);
1446 static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
1447 struct winbindd_cm_conn *new_conn)
1449 TALLOC_CTX *mem_ctx;
1451 char *saf_servername = saf_fetch( domain->name );
1454 if ((mem_ctx = talloc_init("cm_open_connection")) == NULL) {
1455 SAFE_FREE(saf_servername);
1456 set_domain_offline(domain);
1457 return NT_STATUS_NO_MEMORY;
1460 /* we have to check the server affinity cache here since
1461 later we selecte a DC based on response time and not preference */
1463 /* Check the negative connection cache
1464 before talking to it. It going down may have
1465 triggered the reconnection. */
1467 if ( saf_servername && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, saf_servername))) {
1469 DEBUG(10,("cm_open_connection: saf_servername is '%s' for domain %s\n",
1470 saf_servername, domain->name ));
1472 /* convert an ip address to a name */
1473 if (is_ipaddress( saf_servername ) ) {
1475 struct sockaddr_storage ss;
1477 if (!interpret_string_addr(&ss, saf_servername,
1479 return NT_STATUS_UNSUCCESSFUL;
1481 if (dcip_to_name(mem_ctx, domain, &ss, saf_name )) {
1482 fstrcpy( domain->dcname, saf_name );
1484 winbind_add_failed_connection_entry(
1485 domain, saf_servername,
1486 NT_STATUS_UNSUCCESSFUL);
1489 fstrcpy( domain->dcname, saf_servername );
1492 SAFE_FREE( saf_servername );
1495 for (retries = 0; retries < 3; retries++) {
1499 result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1501 DEBUG(10,("cm_open_connection: dcname is '%s' for domain %s\n",
1502 domain->dcname, domain->name ));
1505 && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, domain->dcname))
1506 && (resolve_name(domain->dcname, &domain->dcaddr, 0x20, true)))
1508 struct sockaddr_storage *addrs = NULL;
1512 if (!add_sockaddr_to_array(mem_ctx, &domain->dcaddr, 445, &addrs, &num_addrs)) {
1513 set_domain_offline(domain);
1514 talloc_destroy(mem_ctx);
1515 return NT_STATUS_NO_MEMORY;
1517 if (!add_sockaddr_to_array(mem_ctx, &domain->dcaddr, 139, &addrs, &num_addrs)) {
1518 set_domain_offline(domain);
1519 talloc_destroy(mem_ctx);
1520 return NT_STATUS_NO_MEMORY;
1523 /* 5 second timeout. */
1524 if (!open_any_socket_out(addrs, num_addrs, 5000, &dummy, &fd)) {
1530 && !find_new_dc(mem_ctx, domain, domain->dcname, &domain->dcaddr, &fd))
1532 /* This is the one place where we will
1533 set the global winbindd offline state
1534 to true, if a "WINBINDD_OFFLINE" entry
1535 is found in the winbindd cache. */
1536 set_global_winbindd_state_offline();
1540 new_conn->cli = NULL;
1542 result = cm_prepare_connection(domain, fd, domain->dcname,
1543 &new_conn->cli, &retry);
1549 if (NT_STATUS_IS_OK(result)) {
1551 winbindd_set_locator_kdc_envs(domain);
1553 if (domain->online == False) {
1554 /* We're changing state from offline to online. */
1555 set_global_winbindd_state_online();
1557 set_domain_online(domain);
1559 /* Ensure we setup the retry handler. */
1560 set_domain_offline(domain);
1563 talloc_destroy(mem_ctx);
1567 /* Close down all open pipes on a connection. */
1569 void invalidate_cm_connection(struct winbindd_cm_conn *conn)
1571 /* We're closing down a possibly dead
1572 connection. Don't have impossibly long (10s) timeouts. */
1575 cli_set_timeout(conn->cli, 1000); /* 1 second. */
1578 if (conn->samr_pipe != NULL) {
1579 if (is_valid_policy_hnd(&conn->sam_connect_handle)) {
1580 rpccli_samr_Close(conn->samr_pipe, talloc_tos(),
1581 &conn->sam_connect_handle);
1583 TALLOC_FREE(conn->samr_pipe);
1584 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1586 cli_set_timeout(conn->cli, 500);
1590 if (conn->lsa_pipe != NULL) {
1591 if (is_valid_policy_hnd(&conn->lsa_policy)) {
1592 rpccli_lsa_Close(conn->lsa_pipe, talloc_tos(),
1595 TALLOC_FREE(conn->lsa_pipe);
1596 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1598 cli_set_timeout(conn->cli, 500);
1602 if (conn->lsa_pipe_tcp != NULL) {
1603 if (is_valid_policy_hnd(&conn->lsa_policy)) {
1604 rpccli_lsa_Close(conn->lsa_pipe, talloc_tos(),
1607 TALLOC_FREE(conn->lsa_pipe_tcp);
1608 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1610 cli_set_timeout(conn->cli, 500);
1614 if (conn->netlogon_pipe != NULL) {
1615 TALLOC_FREE(conn->netlogon_pipe);
1616 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1618 cli_set_timeout(conn->cli, 500);
1623 cli_shutdown(conn->cli);
1629 void close_conns_after_fork(void)
1631 struct winbindd_domain *domain;
1633 for (domain = domain_list(); domain; domain = domain->next) {
1634 struct cli_state *cli = domain->conn.cli;
1637 * first close the low level SMB TCP connection
1638 * so that we don't generate any SMBclose
1639 * requests in invalidate_cm_connection()
1641 if (cli && cli->fd != -1) {
1642 close(domain->conn.cli->fd);
1643 domain->conn.cli->fd = -1;
1646 invalidate_cm_connection(&domain->conn);
1650 static bool connection_ok(struct winbindd_domain *domain)
1654 ok = cli_state_is_connected(domain->conn.cli);
1656 DEBUG(3, ("connection_ok: Connection to %s for domain %s is not connected\n",
1657 domain->dcname, domain->name));
1661 if (domain->online == False) {
1662 DEBUG(3, ("connection_ok: Domain %s is offline\n", domain->name));
1669 /* Initialize a new connection up to the RPC BIND.
1670 Bypass online status check so always does network calls. */
1672 static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain)
1676 /* Internal connections never use the network. */
1677 if (domain->internal) {
1678 domain->initialized = True;
1679 return NT_STATUS_OK;
1682 if (!winbindd_can_contact_domain(domain)) {
1683 invalidate_cm_connection(&domain->conn);
1684 domain->initialized = True;
1685 return NT_STATUS_OK;
1688 if (connection_ok(domain)) {
1689 if (!domain->initialized) {
1690 set_dc_type_and_flags(domain);
1692 return NT_STATUS_OK;
1695 invalidate_cm_connection(&domain->conn);
1697 result = cm_open_connection(domain, &domain->conn);
1699 if (NT_STATUS_IS_OK(result) && !domain->initialized) {
1700 set_dc_type_and_flags(domain);
1706 NTSTATUS init_dc_connection(struct winbindd_domain *domain)
1708 if (domain->internal) {
1709 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1712 if (domain->initialized && !domain->online) {
1713 /* We check for online status elsewhere. */
1714 return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1717 return init_dc_connection_network(domain);
1720 static NTSTATUS init_dc_connection_rpc(struct winbindd_domain *domain)
1724 status = init_dc_connection(domain);
1725 if (!NT_STATUS_IS_OK(status)) {
1729 if (!domain->internal && domain->conn.cli == NULL) {
1730 /* happens for trusted domains without inbound trust */
1731 return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
1734 return NT_STATUS_OK;
1737 /******************************************************************************
1738 Set the trust flags (direction and forest location) for a domain
1739 ******************************************************************************/
1741 static bool set_dc_type_and_flags_trustinfo( struct winbindd_domain *domain )
1743 struct winbindd_domain *our_domain;
1744 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1745 struct netr_DomainTrustList trusts;
1747 uint32 flags = (NETR_TRUST_FLAG_IN_FOREST |
1748 NETR_TRUST_FLAG_OUTBOUND |
1749 NETR_TRUST_FLAG_INBOUND);
1750 struct rpc_pipe_client *cli;
1751 TALLOC_CTX *mem_ctx = NULL;
1753 DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s\n", domain->name ));
1755 /* Our primary domain doesn't need to worry about trust flags.
1756 Force it to go through the network setup */
1757 if ( domain->primary ) {
1761 our_domain = find_our_domain();
1763 if ( !connection_ok(our_domain) ) {
1764 DEBUG(3,("set_dc_type_and_flags_trustinfo: No connection to our domain!\n"));
1768 /* This won't work unless our domain is AD */
1770 if ( !our_domain->active_directory ) {
1774 /* Use DsEnumerateDomainTrusts to get us the trust direction
1777 result = cm_connect_netlogon(our_domain, &cli);
1779 if (!NT_STATUS_IS_OK(result)) {
1780 DEBUG(5, ("set_dc_type_and_flags_trustinfo: Could not open "
1781 "a connection to %s for PIPE_NETLOGON (%s)\n",
1782 domain->name, nt_errstr(result)));
1786 if ( (mem_ctx = talloc_init("set_dc_type_and_flags_trustinfo")) == NULL ) {
1787 DEBUG(0,("set_dc_type_and_flags_trustinfo: talloc_init() failed!\n"));
1791 result = rpccli_netr_DsrEnumerateDomainTrusts(cli, mem_ctx,
1796 if (!NT_STATUS_IS_OK(result)) {
1797 DEBUG(0,("set_dc_type_and_flags_trustinfo: "
1798 "failed to query trusted domain list: %s\n",
1799 nt_errstr(result)));
1800 talloc_destroy(mem_ctx);
1804 /* Now find the domain name and get the flags */
1806 for ( i=0; i<trusts.count; i++ ) {
1807 if ( strequal( domain->name, trusts.array[i].netbios_name) ) {
1808 domain->domain_flags = trusts.array[i].trust_flags;
1809 domain->domain_type = trusts.array[i].trust_type;
1810 domain->domain_trust_attribs = trusts.array[i].trust_attributes;
1812 if ( domain->domain_type == NETR_TRUST_TYPE_UPLEVEL )
1813 domain->active_directory = True;
1815 /* This flag is only set if the domain is *our*
1816 primary domain and the primary domain is in
1819 domain->native_mode = (domain->domain_flags & NETR_TRUST_FLAG_NATIVE);
1821 DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s is %sin "
1822 "native mode.\n", domain->name,
1823 domain->native_mode ? "" : "NOT "));
1825 DEBUG(5,("set_dc_type_and_flags_trustinfo: domain %s is %s"
1826 "running active directory.\n", domain->name,
1827 domain->active_directory ? "" : "NOT "));
1830 domain->initialized = True;
1836 talloc_destroy( mem_ctx );
1838 return domain->initialized;
1841 /******************************************************************************
1842 We can 'sense' certain things about the DC by it's replies to certain
1845 This tells us if this particular remote server is Active Directory, and if it
1847 ******************************************************************************/
1849 static void set_dc_type_and_flags_connect( struct winbindd_domain *domain )
1853 TALLOC_CTX *mem_ctx = NULL;
1854 struct rpc_pipe_client *cli = NULL;
1855 struct policy_handle pol;
1856 union dssetup_DsRoleInfo info;
1857 union lsa_PolicyInformation *lsa_info = NULL;
1859 if (!connection_ok(domain)) {
1863 mem_ctx = talloc_init("set_dc_type_and_flags on domain %s\n",
1866 DEBUG(1, ("set_dc_type_and_flags_connect: talloc_init() failed\n"));
1870 DEBUG(5, ("set_dc_type_and_flags_connect: domain %s\n", domain->name ));
1872 result = cli_rpc_pipe_open_noauth(domain->conn.cli,
1873 &ndr_table_dssetup.syntax_id,
1876 if (!NT_STATUS_IS_OK(result)) {
1877 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
1878 "PI_DSSETUP on domain %s: (%s)\n",
1879 domain->name, nt_errstr(result)));
1881 /* if this is just a non-AD domain we need to continue
1882 * identifying so that we can in the end return with
1883 * domain->initialized = True - gd */
1888 result = rpccli_dssetup_DsRoleGetPrimaryDomainInformation(cli, mem_ctx,
1889 DS_ROLE_BASIC_INFORMATION,
1894 if (!NT_STATUS_IS_OK(result)) {
1895 DEBUG(5, ("set_dc_type_and_flags_connect: rpccli_ds_getprimarydominfo "
1896 "on domain %s failed: (%s)\n",
1897 domain->name, nt_errstr(result)));
1899 /* older samba3 DCs will return DCERPC_FAULT_OP_RNG_ERROR for
1900 * every opcode on the DSSETUP pipe, continue with
1901 * no_dssetup mode here as well to get domain->initialized
1904 if (NT_STATUS_V(result) == DCERPC_FAULT_OP_RNG_ERROR) {
1908 TALLOC_FREE(mem_ctx);
1912 if ((info.basic.flags & DS_ROLE_PRIMARY_DS_RUNNING) &&
1913 !(info.basic.flags & DS_ROLE_PRIMARY_DS_MIXED_MODE)) {
1914 domain->native_mode = True;
1916 domain->native_mode = False;
1920 result = cli_rpc_pipe_open_noauth(domain->conn.cli,
1921 &ndr_table_lsarpc.syntax_id, &cli);
1923 if (!NT_STATUS_IS_OK(result)) {
1924 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
1925 "PI_LSARPC on domain %s: (%s)\n",
1926 domain->name, nt_errstr(result)));
1928 TALLOC_FREE(mem_ctx);
1932 result = rpccli_lsa_open_policy2(cli, mem_ctx, True,
1933 SEC_FLAG_MAXIMUM_ALLOWED, &pol);
1935 if (NT_STATUS_IS_OK(result)) {
1936 /* This particular query is exactly what Win2k clients use
1937 to determine that the DC is active directory */
1938 result = rpccli_lsa_QueryInfoPolicy2(cli, mem_ctx,
1940 LSA_POLICY_INFO_DNS,
1944 if (NT_STATUS_IS_OK(result)) {
1945 domain->active_directory = True;
1947 if (lsa_info->dns.name.string) {
1948 fstrcpy(domain->name, lsa_info->dns.name.string);
1951 if (lsa_info->dns.dns_domain.string) {
1952 fstrcpy(domain->alt_name,
1953 lsa_info->dns.dns_domain.string);
1956 /* See if we can set some domain trust flags about
1959 if (lsa_info->dns.dns_forest.string) {
1960 fstrcpy(domain->forest_name,
1961 lsa_info->dns.dns_forest.string);
1963 if (strequal(domain->forest_name, domain->alt_name)) {
1964 domain->domain_flags |= NETR_TRUST_FLAG_TREEROOT;
1968 if (lsa_info->dns.sid) {
1969 sid_copy(&domain->sid, lsa_info->dns.sid);
1972 domain->active_directory = False;
1974 result = rpccli_lsa_open_policy(cli, mem_ctx, True,
1975 SEC_FLAG_MAXIMUM_ALLOWED,
1978 if (!NT_STATUS_IS_OK(result)) {
1982 result = rpccli_lsa_QueryInfoPolicy(cli, mem_ctx,
1984 LSA_POLICY_INFO_ACCOUNT_DOMAIN,
1987 if (NT_STATUS_IS_OK(result)) {
1989 if (lsa_info->account_domain.name.string) {
1990 fstrcpy(domain->name,
1991 lsa_info->account_domain.name.string);
1994 if (lsa_info->account_domain.sid) {
1995 sid_copy(&domain->sid, lsa_info->account_domain.sid);
2001 DEBUG(5, ("set_dc_type_and_flags_connect: domain %s is %sin native mode.\n",
2002 domain->name, domain->native_mode ? "" : "NOT "));
2004 DEBUG(5,("set_dc_type_and_flags_connect: domain %s is %srunning active directory.\n",
2005 domain->name, domain->active_directory ? "" : "NOT "));
2007 domain->can_do_ncacn_ip_tcp = domain->active_directory;
2011 TALLOC_FREE(mem_ctx);
2013 domain->initialized = True;
2016 /**********************************************************************
2017 Set the domain_flags (trust attributes, domain operating modes, etc...
2018 ***********************************************************************/
2020 static void set_dc_type_and_flags( struct winbindd_domain *domain )
2022 /* we always have to contact our primary domain */
2024 if ( domain->primary ) {
2025 DEBUG(10,("set_dc_type_and_flags: setting up flags for "
2026 "primary domain\n"));
2027 set_dc_type_and_flags_connect( domain );
2031 /* Use our DC to get the information if possible */
2033 if ( !set_dc_type_and_flags_trustinfo( domain ) ) {
2034 /* Otherwise, fallback to contacting the
2036 set_dc_type_and_flags_connect( domain );
2044 /**********************************************************************
2045 ***********************************************************************/
2047 static bool cm_get_schannel_creds(struct winbindd_domain *domain,
2048 struct netlogon_creds_CredentialState **ppdc)
2051 struct rpc_pipe_client *netlogon_pipe;
2053 if (lp_client_schannel() == False) {
2057 result = cm_connect_netlogon(domain, &netlogon_pipe);
2058 if (!NT_STATUS_IS_OK(result)) {
2062 /* Return a pointer to the struct netlogon_creds_CredentialState from the
2065 if (!domain->conn.netlogon_pipe->dc) {
2069 *ppdc = domain->conn.netlogon_pipe->dc;
2073 NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
2074 struct rpc_pipe_client **cli, struct policy_handle *sam_handle)
2076 struct winbindd_cm_conn *conn;
2077 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2078 struct netlogon_creds_CredentialState *p_creds;
2079 char *machine_password = NULL;
2080 char *machine_account = NULL;
2081 char *domain_name = NULL;
2083 if (strequal(domain->name, get_global_sam_name())) {
2084 result = open_internal_samr_conn(mem_ctx, domain, cli, sam_handle);
2085 if (!NT_STATUS_IS_OK(result)) {
2088 return NT_STATUS_OK;
2091 result = init_dc_connection_rpc(domain);
2092 if (!NT_STATUS_IS_OK(result)) {
2096 conn = &domain->conn;
2098 if (rpccli_is_connected(conn->samr_pipe)) {
2102 TALLOC_FREE(conn->samr_pipe);
2105 * No SAMR pipe yet. Attempt to get an NTLMSSP SPNEGO authenticated
2106 * sign and sealed pipe using the machine account password by
2107 * preference. If we can't - try schannel, if that fails, try
2111 if ((conn->cli->user_name[0] == '\0') ||
2112 (conn->cli->domain[0] == '\0') ||
2113 (conn->cli->password == NULL || conn->cli->password[0] == '\0'))
2115 result = get_trust_creds(domain, &machine_password,
2116 &machine_account, NULL);
2117 if (!NT_STATUS_IS_OK(result)) {
2118 DEBUG(10, ("cm_connect_sam: No no user available for "
2119 "domain %s, trying schannel\n", conn->cli->domain));
2122 domain_name = domain->name;
2124 machine_password = SMB_STRDUP(conn->cli->password);
2125 machine_account = SMB_STRDUP(conn->cli->user_name);
2126 domain_name = conn->cli->domain;
2129 if (!machine_password || !machine_account) {
2130 result = NT_STATUS_NO_MEMORY;
2134 /* We have an authenticated connection. Use a NTLMSSP SPNEGO
2135 authenticated SAMR pipe with sign & seal. */
2136 result = cli_rpc_pipe_open_spnego_ntlmssp(conn->cli,
2137 &ndr_table_samr.syntax_id,
2139 DCERPC_AUTH_LEVEL_PRIVACY,
2145 if (!NT_STATUS_IS_OK(result)) {
2146 DEBUG(10,("cm_connect_sam: failed to connect to SAMR "
2147 "pipe for domain %s using NTLMSSP "
2148 "authenticated pipe: user %s\\%s. Error was "
2149 "%s\n", domain->name, domain_name,
2150 machine_account, nt_errstr(result)));
2154 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for "
2155 "domain %s using NTLMSSP authenticated "
2156 "pipe: user %s\\%s\n", domain->name,
2157 domain_name, machine_account));
2159 result = rpccli_samr_Connect2(conn->samr_pipe, mem_ctx,
2160 conn->samr_pipe->desthost,
2161 SEC_FLAG_MAXIMUM_ALLOWED,
2162 &conn->sam_connect_handle);
2163 if (NT_STATUS_IS_OK(result)) {
2166 DEBUG(10,("cm_connect_sam: ntlmssp-sealed rpccli_samr_Connect2 "
2167 "failed for domain %s, error was %s. Trying schannel\n",
2168 domain->name, nt_errstr(result) ));
2169 TALLOC_FREE(conn->samr_pipe);
2173 /* Fall back to schannel if it's a W2K pre-SP1 box. */
2175 if (!cm_get_schannel_creds(domain, &p_creds)) {
2176 /* If this call fails - conn->cli can now be NULL ! */
2177 DEBUG(10, ("cm_connect_sam: Could not get schannel auth info "
2178 "for domain %s, trying anon\n", domain->name));
2181 result = cli_rpc_pipe_open_schannel_with_key
2182 (conn->cli, &ndr_table_samr.syntax_id, NCACN_NP,
2183 DCERPC_AUTH_LEVEL_PRIVACY,
2184 domain->name, &p_creds, &conn->samr_pipe);
2186 if (!NT_STATUS_IS_OK(result)) {
2187 DEBUG(10,("cm_connect_sam: failed to connect to SAMR pipe for "
2188 "domain %s using schannel. Error was %s\n",
2189 domain->name, nt_errstr(result) ));
2192 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for domain %s using "
2193 "schannel.\n", domain->name ));
2195 result = rpccli_samr_Connect2(conn->samr_pipe, mem_ctx,
2196 conn->samr_pipe->desthost,
2197 SEC_FLAG_MAXIMUM_ALLOWED,
2198 &conn->sam_connect_handle);
2199 if (NT_STATUS_IS_OK(result)) {
2202 DEBUG(10,("cm_connect_sam: schannel-sealed rpccli_samr_Connect2 failed "
2203 "for domain %s, error was %s. Trying anonymous\n",
2204 domain->name, nt_errstr(result) ));
2205 TALLOC_FREE(conn->samr_pipe);
2209 /* Finally fall back to anonymous. */
2210 result = cli_rpc_pipe_open_noauth(conn->cli, &ndr_table_samr.syntax_id,
2213 if (!NT_STATUS_IS_OK(result)) {
2217 result = rpccli_samr_Connect2(conn->samr_pipe, mem_ctx,
2218 conn->samr_pipe->desthost,
2219 SEC_FLAG_MAXIMUM_ALLOWED,
2220 &conn->sam_connect_handle);
2221 if (!NT_STATUS_IS_OK(result)) {
2222 DEBUG(10,("cm_connect_sam: rpccli_samr_Connect2 failed "
2223 "for domain %s Error was %s\n",
2224 domain->name, nt_errstr(result) ));
2229 result = rpccli_samr_OpenDomain(conn->samr_pipe,
2231 &conn->sam_connect_handle,
2232 SEC_FLAG_MAXIMUM_ALLOWED,
2234 &conn->sam_domain_handle);
2238 if (NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED)) {
2240 * if we got access denied, we might just have no access rights
2241 * to talk to the remote samr server server (e.g. when we are a
2242 * PDC and we are connecting a w2k8 pdc via an interdomain
2243 * trust). In that case do not invalidate the whole connection
2246 TALLOC_FREE(conn->samr_pipe);
2247 ZERO_STRUCT(conn->sam_domain_handle);
2249 } else if (!NT_STATUS_IS_OK(result)) {
2250 invalidate_cm_connection(conn);
2254 *cli = conn->samr_pipe;
2255 *sam_handle = conn->sam_domain_handle;
2256 SAFE_FREE(machine_password);
2257 SAFE_FREE(machine_account);
2261 /**********************************************************************
2262 open an schanneld ncacn_ip_tcp connection to LSA
2263 ***********************************************************************/
2265 NTSTATUS cm_connect_lsa_tcp(struct winbindd_domain *domain,
2266 TALLOC_CTX *mem_ctx,
2267 struct rpc_pipe_client **cli)
2269 struct winbindd_cm_conn *conn;
2270 struct netlogon_creds_CredentialState *creds;
2273 DEBUG(10,("cm_connect_lsa_tcp\n"));
2275 status = init_dc_connection_rpc(domain);
2276 if (!NT_STATUS_IS_OK(status)) {
2280 conn = &domain->conn;
2282 if (conn->lsa_pipe_tcp &&
2283 conn->lsa_pipe_tcp->transport->transport == NCACN_IP_TCP &&
2284 conn->lsa_pipe_tcp->auth->auth_level == DCERPC_AUTH_LEVEL_PRIVACY &&
2285 rpccli_is_connected(conn->lsa_pipe_tcp)) {
2289 TALLOC_FREE(conn->lsa_pipe_tcp);
2291 if (!cm_get_schannel_creds(domain, &creds)) {
2295 status = cli_rpc_pipe_open_schannel_with_key(conn->cli,
2296 &ndr_table_lsarpc.syntax_id,
2298 DCERPC_AUTH_LEVEL_PRIVACY,
2301 &conn->lsa_pipe_tcp);
2302 if (!NT_STATUS_IS_OK(status)) {
2303 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key failed: %s\n",
2304 nt_errstr(status)));
2309 if (!NT_STATUS_IS_OK(status)) {
2310 TALLOC_FREE(conn->lsa_pipe_tcp);
2314 *cli = conn->lsa_pipe_tcp;
2319 NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
2320 struct rpc_pipe_client **cli, struct policy_handle *lsa_policy)
2322 struct winbindd_cm_conn *conn;
2323 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2324 struct netlogon_creds_CredentialState *p_creds;
2326 result = init_dc_connection_rpc(domain);
2327 if (!NT_STATUS_IS_OK(result))
2330 conn = &domain->conn;
2332 if (rpccli_is_connected(conn->lsa_pipe)) {
2336 TALLOC_FREE(conn->lsa_pipe);
2338 if ((conn->cli->user_name[0] == '\0') ||
2339 (conn->cli->domain[0] == '\0') ||
2340 (conn->cli->password == NULL || conn->cli->password[0] == '\0')) {
2341 DEBUG(10, ("cm_connect_lsa: No no user available for "
2342 "domain %s, trying schannel\n", conn->cli->domain));
2346 /* We have an authenticated connection. Use a NTLMSSP SPNEGO
2347 * authenticated LSA pipe with sign & seal. */
2348 result = cli_rpc_pipe_open_spnego_ntlmssp
2349 (conn->cli, &ndr_table_lsarpc.syntax_id, NCACN_NP,
2350 DCERPC_AUTH_LEVEL_PRIVACY,
2351 conn->cli->domain, conn->cli->user_name, conn->cli->password,
2354 if (!NT_STATUS_IS_OK(result)) {
2355 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
2356 "domain %s using NTLMSSP authenticated pipe: user "
2357 "%s\\%s. Error was %s. Trying schannel.\n",
2358 domain->name, conn->cli->domain,
2359 conn->cli->user_name, nt_errstr(result)));
2363 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
2364 "NTLMSSP authenticated pipe: user %s\\%s\n",
2365 domain->name, conn->cli->domain, conn->cli->user_name ));
2367 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2368 SEC_FLAG_MAXIMUM_ALLOWED,
2370 if (NT_STATUS_IS_OK(result)) {
2374 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
2377 TALLOC_FREE(conn->lsa_pipe);
2381 /* Fall back to schannel if it's a W2K pre-SP1 box. */
2383 if (!cm_get_schannel_creds(domain, &p_creds)) {
2384 /* If this call fails - conn->cli can now be NULL ! */
2385 DEBUG(10, ("cm_connect_lsa: Could not get schannel auth info "
2386 "for domain %s, trying anon\n", domain->name));
2389 result = cli_rpc_pipe_open_schannel_with_key
2390 (conn->cli, &ndr_table_lsarpc.syntax_id, NCACN_NP,
2391 DCERPC_AUTH_LEVEL_PRIVACY,
2392 domain->name, &p_creds, &conn->lsa_pipe);
2394 if (!NT_STATUS_IS_OK(result)) {
2395 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
2396 "domain %s using schannel. Error was %s\n",
2397 domain->name, nt_errstr(result) ));
2400 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
2401 "schannel.\n", domain->name ));
2403 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2404 SEC_FLAG_MAXIMUM_ALLOWED,
2406 if (NT_STATUS_IS_OK(result)) {
2410 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
2413 TALLOC_FREE(conn->lsa_pipe);
2417 result = cli_rpc_pipe_open_noauth(conn->cli,
2418 &ndr_table_lsarpc.syntax_id,
2420 if (!NT_STATUS_IS_OK(result)) {
2421 result = NT_STATUS_PIPE_NOT_AVAILABLE;
2425 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2426 SEC_FLAG_MAXIMUM_ALLOWED,
2429 if (!NT_STATUS_IS_OK(result)) {
2430 invalidate_cm_connection(conn);
2434 *cli = conn->lsa_pipe;
2435 *lsa_policy = conn->lsa_policy;
2439 /****************************************************************************
2440 Open the netlogon pipe to this DC. Use schannel if specified in client conf.
2441 session key stored in conn->netlogon_pipe->dc->sess_key.
2442 ****************************************************************************/
2444 NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
2445 struct rpc_pipe_client **cli)
2447 struct winbindd_cm_conn *conn;
2450 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
2452 enum netr_SchannelType sec_chan_type;
2453 const char *account_name;
2454 struct rpc_pipe_client *netlogon_pipe = NULL;
2458 result = init_dc_connection_rpc(domain);
2459 if (!NT_STATUS_IS_OK(result)) {
2463 conn = &domain->conn;
2465 if (rpccli_is_connected(conn->netlogon_pipe)) {
2466 *cli = conn->netlogon_pipe;
2467 return NT_STATUS_OK;
2470 TALLOC_FREE(conn->netlogon_pipe);
2472 result = cli_rpc_pipe_open_noauth(conn->cli,
2473 &ndr_table_netlogon.syntax_id,
2475 if (!NT_STATUS_IS_OK(result)) {
2479 if ((!IS_DC) && (!domain->primary)) {
2480 /* Clear the schannel request bit and drop down */
2481 neg_flags &= ~NETLOGON_NEG_SCHANNEL;
2485 if (lp_client_schannel() != False) {
2486 neg_flags |= NETLOGON_NEG_SCHANNEL;
2489 if (!get_trust_pw_hash(domain->name, mach_pwd, &account_name,
2492 TALLOC_FREE(netlogon_pipe);
2493 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2496 result = rpccli_netlogon_setup_creds(
2498 domain->dcname, /* server name. */
2499 domain->name, /* domain name */
2500 global_myname(), /* client name */
2501 account_name, /* machine account */
2502 mach_pwd, /* machine password */
2503 sec_chan_type, /* from get_trust_pw */
2506 if (!NT_STATUS_IS_OK(result)) {
2507 TALLOC_FREE(netlogon_pipe);
2511 if ((lp_client_schannel() == True) &&
2512 ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
2513 DEBUG(3, ("Server did not offer schannel\n"));
2514 TALLOC_FREE(netlogon_pipe);
2515 return NT_STATUS_ACCESS_DENIED;
2519 if ((lp_client_schannel() == False) ||
2520 ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
2522 * NetSamLogonEx only works for schannel
2524 domain->can_do_samlogon_ex = False;
2526 /* We're done - just keep the existing connection to NETLOGON
2528 conn->netlogon_pipe = netlogon_pipe;
2529 *cli = conn->netlogon_pipe;
2530 return NT_STATUS_OK;
2533 /* Using the credentials from the first pipe, open a signed and sealed
2534 second netlogon pipe. The session key is stored in the schannel
2535 part of the new pipe auth struct.
2538 result = cli_rpc_pipe_open_schannel_with_key(
2539 conn->cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
2540 DCERPC_AUTH_LEVEL_PRIVACY, domain->name, &netlogon_pipe->dc,
2541 &conn->netlogon_pipe);
2543 /* We can now close the initial netlogon pipe. */
2544 TALLOC_FREE(netlogon_pipe);
2546 if (!NT_STATUS_IS_OK(result)) {
2547 DEBUG(3, ("Could not open schannel'ed NETLOGON pipe. Error "
2548 "was %s\n", nt_errstr(result)));
2550 invalidate_cm_connection(conn);
2555 * Always try netr_LogonSamLogonEx. We will fall back for NT4
2556 * which gives DCERPC_FAULT_OP_RNG_ERROR (function not
2557 * supported). We used to only try SamLogonEx for AD, but
2558 * Samba DCs can also do it. And because we don't distinguish
2559 * between Samba and NT4, always try it once.
2561 domain->can_do_samlogon_ex = true;
2563 *cli = conn->netlogon_pipe;
2564 return NT_STATUS_OK;