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"
75 #include "../libcli/security/security.h"
78 #define DBGC_CLASS DBGC_WINBIND
82 struct sockaddr_storage ss;
85 extern struct winbindd_methods reconnect_methods;
86 extern bool override_logfile;
88 static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain);
89 static void set_dc_type_and_flags( struct winbindd_domain *domain );
90 static bool get_dcs(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
91 struct dc_name_ip **dcs, int *num_dcs);
93 /****************************************************************
94 Child failed to find DC's. Reschedule check.
95 ****************************************************************/
97 static void msg_failed_to_go_online(struct messaging_context *msg,
100 struct server_id server_id,
103 struct winbindd_domain *domain;
104 const char *domainname = (const char *)data->data;
106 if (data->data == NULL || data->length == 0) {
110 DEBUG(5,("msg_fail_to_go_online: received for domain %s.\n", domainname));
112 for (domain = domain_list(); domain; domain = domain->next) {
113 if (domain->internal) {
117 if (strequal(domain->name, domainname)) {
118 if (domain->online) {
119 /* We're already online, ignore. */
120 DEBUG(5,("msg_fail_to_go_online: domain %s "
121 "already online.\n", domainname));
125 /* Reschedule the online check. */
126 set_domain_offline(domain);
132 /****************************************************************
133 Actually cause a reconnect from a message.
134 ****************************************************************/
136 static void msg_try_to_go_online(struct messaging_context *msg,
139 struct server_id server_id,
142 struct winbindd_domain *domain;
143 const char *domainname = (const char *)data->data;
145 if (data->data == NULL || data->length == 0) {
149 DEBUG(5,("msg_try_to_go_online: received for domain %s.\n", domainname));
151 for (domain = domain_list(); domain; domain = domain->next) {
152 if (domain->internal) {
156 if (strequal(domain->name, domainname)) {
158 if (domain->online) {
159 /* We're already online, ignore. */
160 DEBUG(5,("msg_try_to_go_online: domain %s "
161 "already online.\n", domainname));
165 /* This call takes care of setting the online
166 flag to true if we connected, or re-adding
167 the offline handler if false. Bypasses online
168 check so always does network calls. */
170 init_dc_connection_network(domain);
176 /****************************************************************
177 Fork a child to try and contact a DC. Do this as contacting a
178 DC requires blocking lookups and we don't want to block our
180 ****************************************************************/
182 static bool fork_child_dc_connect(struct winbindd_domain *domain)
184 struct dc_name_ip *dcs = NULL;
186 TALLOC_CTX *mem_ctx = NULL;
187 pid_t parent_pid = sys_getpid();
190 if (domain->dc_probe_pid != (pid_t)-1) {
192 * We might already have a DC probe
193 * child working, check.
195 if (process_exists_by_pid(domain->dc_probe_pid)) {
196 DEBUG(10,("fork_child_dc_connect: pid %u already "
197 "checking for DC's.\n",
198 (unsigned int)domain->dc_probe_pid));
201 domain->dc_probe_pid = (pid_t)-1;
204 domain->dc_probe_pid = sys_fork();
206 if (domain->dc_probe_pid == (pid_t)-1) {
207 DEBUG(0, ("fork_child_dc_connect: Could not fork: %s\n", strerror(errno)));
211 if (domain->dc_probe_pid != (pid_t)0) {
213 messaging_register(winbind_messaging_context(), NULL,
214 MSG_WINBIND_TRY_TO_GO_ONLINE,
215 msg_try_to_go_online);
216 messaging_register(winbind_messaging_context(), NULL,
217 MSG_WINBIND_FAILED_TO_GO_ONLINE,
218 msg_failed_to_go_online);
224 /* Leave messages blocked - we will never process one. */
226 if (!override_logfile) {
227 if (asprintf(&lfile, "%s/log.winbindd-dc-connect", get_dyn_LOGFILEBASE()) == -1) {
228 DEBUG(0, ("fork_child_dc_connect: out of memory.\n"));
233 if (!winbindd_reinit_after_fork(lfile)) {
234 messaging_send_buf(winbind_messaging_context(),
235 pid_to_procid(parent_pid),
236 MSG_WINBIND_FAILED_TO_GO_ONLINE,
237 (uint8 *)domain->name,
238 strlen(domain->name)+1);
243 mem_ctx = talloc_init("fork_child_dc_connect");
245 DEBUG(0,("talloc_init failed.\n"));
246 messaging_send_buf(winbind_messaging_context(),
247 pid_to_procid(parent_pid),
248 MSG_WINBIND_FAILED_TO_GO_ONLINE,
249 (uint8 *)domain->name,
250 strlen(domain->name)+1);
254 if ((!get_dcs(mem_ctx, domain, &dcs, &num_dcs)) || (num_dcs == 0)) {
255 /* Still offline ? Can't find DC's. */
256 messaging_send_buf(winbind_messaging_context(),
257 pid_to_procid(parent_pid),
258 MSG_WINBIND_FAILED_TO_GO_ONLINE,
259 (uint8 *)domain->name,
260 strlen(domain->name)+1);
264 /* We got a DC. Send a message to our parent to get it to
265 try and do the same. */
267 messaging_send_buf(winbind_messaging_context(),
268 pid_to_procid(parent_pid),
269 MSG_WINBIND_TRY_TO_GO_ONLINE,
270 (uint8 *)domain->name,
271 strlen(domain->name)+1);
275 /****************************************************************
276 Handler triggered if we're offline to try and detect a DC.
277 ****************************************************************/
279 static void check_domain_online_handler(struct event_context *ctx,
280 struct timed_event *te,
284 struct winbindd_domain *domain =
285 (struct winbindd_domain *)private_data;
287 DEBUG(10,("check_domain_online_handler: called for domain "
288 "%s (online = %s)\n", domain->name,
289 domain->online ? "True" : "False" ));
291 TALLOC_FREE(domain->check_online_event);
293 /* Are we still in "startup" mode ? */
295 if (domain->startup && (time_mono(NULL) > domain->startup_time + 30)) {
296 /* No longer in "startup" mode. */
297 DEBUG(10,("check_domain_online_handler: domain %s no longer in 'startup' mode.\n",
299 domain->startup = False;
302 /* We've been told to stay offline, so stay
305 if (get_global_winbindd_state_offline()) {
306 DEBUG(10,("check_domain_online_handler: domain %s remaining globally offline\n",
311 /* Fork a child to test if it can contact a DC.
312 If it can then send ourselves a message to
313 cause a reconnect. */
315 fork_child_dc_connect(domain);
318 /****************************************************************
319 If we're still offline setup the timeout check.
320 ****************************************************************/
322 static void calc_new_online_timeout_check(struct winbindd_domain *domain)
324 int wbr = lp_winbind_reconnect_delay();
326 if (domain->startup) {
327 domain->check_online_timeout = 10;
328 } else if (domain->check_online_timeout < wbr) {
329 domain->check_online_timeout = wbr;
333 /****************************************************************
334 Set domain offline and also add handler to put us back online
336 ****************************************************************/
338 void set_domain_offline(struct winbindd_domain *domain)
340 DEBUG(10,("set_domain_offline: called for domain %s\n",
343 TALLOC_FREE(domain->check_online_event);
345 if (domain->internal) {
346 DEBUG(3,("set_domain_offline: domain %s is internal - logic error.\n",
351 domain->online = False;
353 /* Offline domains are always initialized. They're
354 re-initialized when they go back online. */
356 domain->initialized = True;
358 /* We only add the timeout handler that checks and
359 allows us to go back online when we've not
360 been told to remain offline. */
362 if (get_global_winbindd_state_offline()) {
363 DEBUG(10,("set_domain_offline: domain %s remaining globally offline\n",
368 /* If we're in startup mode, check again in 10 seconds, not in
369 lp_winbind_reconnect_delay() seconds (which is 30 seconds by default). */
371 calc_new_online_timeout_check(domain);
373 domain->check_online_event = event_add_timed(winbind_event_context(),
375 timeval_current_ofs(domain->check_online_timeout,0),
376 check_domain_online_handler,
379 /* The above *has* to succeed for winbindd to work. */
380 if (!domain->check_online_event) {
381 smb_panic("set_domain_offline: failed to add online handler");
384 DEBUG(10,("set_domain_offline: added event handler for domain %s\n",
387 /* Send an offline message to the idmap child when our
388 primary domain goes offline */
390 if ( domain->primary ) {
391 struct winbindd_child *idmap = idmap_child();
393 if ( idmap->pid != 0 ) {
394 messaging_send_buf(winbind_messaging_context(),
395 pid_to_procid(idmap->pid),
397 (uint8 *)domain->name,
398 strlen(domain->name)+1);
405 /****************************************************************
406 Set domain online - if allowed.
407 ****************************************************************/
409 static void set_domain_online(struct winbindd_domain *domain)
411 DEBUG(10,("set_domain_online: called for domain %s\n",
414 if (domain->internal) {
415 DEBUG(3,("set_domain_online: domain %s is internal - logic error.\n",
420 if (get_global_winbindd_state_offline()) {
421 DEBUG(10,("set_domain_online: domain %s remaining globally offline\n",
426 winbindd_set_locator_kdc_envs(domain);
428 /* If we are waiting to get a krb5 ticket, trigger immediately. */
429 ccache_regain_all_now();
431 /* Ok, we're out of any startup mode now... */
432 domain->startup = False;
434 if (domain->online == False) {
435 /* We were offline - now we're online. We default to
436 using the MS-RPC backend if we started offline,
437 and if we're going online for the first time we
438 should really re-initialize the backends and the
439 checks to see if we're talking to an AD or NT domain.
442 domain->initialized = False;
444 /* 'reconnect_methods' is the MS-RPC backend. */
445 if (domain->backend == &reconnect_methods) {
446 domain->backend = NULL;
450 /* Ensure we have no online timeout checks. */
451 domain->check_online_timeout = 0;
452 TALLOC_FREE(domain->check_online_event);
454 /* Ensure we ignore any pending child messages. */
455 messaging_deregister(winbind_messaging_context(),
456 MSG_WINBIND_TRY_TO_GO_ONLINE, NULL);
457 messaging_deregister(winbind_messaging_context(),
458 MSG_WINBIND_FAILED_TO_GO_ONLINE, NULL);
460 domain->online = True;
462 /* Send an online message to the idmap child when our
463 primary domain comes online */
465 if ( domain->primary ) {
466 struct winbindd_child *idmap = idmap_child();
468 if ( idmap->pid != 0 ) {
469 messaging_send_buf(winbind_messaging_context(),
470 pid_to_procid(idmap->pid),
472 (uint8 *)domain->name,
473 strlen(domain->name)+1);
480 /****************************************************************
481 Requested to set a domain online.
482 ****************************************************************/
484 void set_domain_online_request(struct winbindd_domain *domain)
488 DEBUG(10,("set_domain_online_request: called for domain %s\n",
491 if (get_global_winbindd_state_offline()) {
492 DEBUG(10,("set_domain_online_request: domain %s remaining globally offline\n",
497 if (domain->internal) {
498 DEBUG(10, ("set_domain_online_request: Internal domains are "
503 /* We've been told it's safe to go online and
504 try and connect to a DC. But I don't believe it
505 because network manager seems to lie.
506 Wait at least 5 seconds. Heuristics suck... */
511 /* Go into "startup" mode again. */
512 domain->startup_time = time_mono(NULL);
513 domain->startup = True;
517 if (!domain->check_online_event) {
518 /* If we've come from being globally offline we
519 don't have a check online event handler set.
520 We need to add one now we're trying to go
523 DEBUG(10,("set_domain_online_request: domain %s was globally offline.\n",
527 TALLOC_FREE(domain->check_online_event);
529 domain->check_online_event = event_add_timed(winbind_event_context(),
532 check_domain_online_handler,
535 /* The above *has* to succeed for winbindd to work. */
536 if (!domain->check_online_event) {
537 smb_panic("set_domain_online_request: failed to add online handler");
541 /****************************************************************
542 Add -ve connection cache entries for domain and realm.
543 ****************************************************************/
545 static void winbind_add_failed_connection_entry(
546 const struct winbindd_domain *domain,
550 add_failed_connection_entry(domain->name, server, result);
551 /* If this was the saf name for the last thing we talked to,
553 saf_delete(domain->name);
554 if (*domain->alt_name) {
555 add_failed_connection_entry(domain->alt_name, server, result);
556 saf_delete(domain->alt_name);
558 winbindd_unset_locator_kdc_env(domain);
561 /* Choose between anonymous or authenticated connections. We need to use
562 an authenticated connection if DCs have the RestrictAnonymous registry
563 entry set > 0, or the "Additional restrictions for anonymous
564 connections" set in the win2k Local Security Policy.
566 Caller to free() result in domain, username, password
569 static void cm_get_ipc_userpass(char **username, char **domain, char **password)
571 *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
572 *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
573 *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
575 if (*username && **username) {
577 if (!*domain || !**domain)
578 *domain = smb_xstrdup(lp_workgroup());
580 if (!*password || !**password)
581 *password = smb_xstrdup("");
583 DEBUG(3, ("cm_get_ipc_userpass: Retrieved auth-user from secrets.tdb [%s\\%s]\n",
584 *domain, *username));
587 DEBUG(3, ("cm_get_ipc_userpass: No auth-user defined\n"));
588 *username = smb_xstrdup("");
589 *domain = smb_xstrdup("");
590 *password = smb_xstrdup("");
594 static bool get_dc_name_via_netlogon(struct winbindd_domain *domain,
596 struct sockaddr_storage *dc_ss)
598 struct winbindd_domain *our_domain = NULL;
599 struct rpc_pipe_client *netlogon_pipe = NULL;
603 unsigned int orig_timeout;
604 const char *tmp = NULL;
607 /* Hmmmm. We can only open one connection to the NETLOGON pipe at the
614 if (domain->primary) {
618 our_domain = find_our_domain();
620 if ((mem_ctx = talloc_init("get_dc_name_via_netlogon")) == NULL) {
624 result = cm_connect_netlogon(our_domain, &netlogon_pipe);
625 if (!NT_STATUS_IS_OK(result)) {
626 talloc_destroy(mem_ctx);
630 /* This call can take a long time - allow the server to time out.
631 35 seconds should do it. */
633 orig_timeout = rpccli_set_timeout(netlogon_pipe, 35000);
635 if (our_domain->active_directory) {
636 struct netr_DsRGetDCNameInfo *domain_info = NULL;
638 result = rpccli_netr_DsRGetDCName(netlogon_pipe,
647 if (NT_STATUS_IS_OK(result) && W_ERROR_IS_OK(werr)) {
649 mem_ctx, domain_info->dc_unc);
651 DEBUG(0, ("talloc_strdup failed\n"));
652 talloc_destroy(mem_ctx);
655 if (strlen(domain->alt_name) == 0) {
656 fstrcpy(domain->alt_name,
657 domain_info->domain_name);
659 if (strlen(domain->forest_name) == 0) {
660 fstrcpy(domain->forest_name,
661 domain_info->forest_name);
665 result = rpccli_netr_GetAnyDCName(netlogon_pipe, mem_ctx,
672 /* And restore our original timeout. */
673 rpccli_set_timeout(netlogon_pipe, orig_timeout);
675 if (!NT_STATUS_IS_OK(result)) {
676 DEBUG(10,("rpccli_netr_GetAnyDCName failed: %s\n",
678 talloc_destroy(mem_ctx);
682 if (!W_ERROR_IS_OK(werr)) {
683 DEBUG(10,("rpccli_netr_GetAnyDCName failed: %s\n",
685 talloc_destroy(mem_ctx);
689 /* rpccli_netr_GetAnyDCName gives us a name with \\ */
690 p = strip_hostname(tmp);
694 talloc_destroy(mem_ctx);
696 DEBUG(10,("rpccli_netr_GetAnyDCName returned %s\n", dcname));
698 if (!resolve_name(dcname, dc_ss, 0x20, true)) {
706 * Helper function to assemble trust password and account name
708 static NTSTATUS get_trust_creds(const struct winbindd_domain *domain,
709 char **machine_password,
710 char **machine_account,
711 char **machine_krb5_principal)
713 const char *account_name;
714 const char *name = NULL;
716 /* If we are a DC and this is not our own domain */
721 struct winbindd_domain *our_domain = find_our_domain();
724 return NT_STATUS_INVALID_SERVER_STATE;
726 name = our_domain->name;
729 if (!get_trust_pw_clear(name, machine_password,
730 &account_name, NULL))
732 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
735 if ((machine_account != NULL) &&
736 (asprintf(machine_account, "%s$", account_name) == -1))
738 return NT_STATUS_NO_MEMORY;
741 /* For now assume our machine account only exists in our domain */
743 if (machine_krb5_principal != NULL)
745 struct winbindd_domain *our_domain = find_our_domain();
748 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
751 if (asprintf(machine_krb5_principal, "%s$@%s",
752 account_name, our_domain->alt_name) == -1)
754 return NT_STATUS_NO_MEMORY;
757 strupper_m(*machine_krb5_principal);
763 /************************************************************************
764 Given a fd with a just-connected TCP connection to a DC, open a connection
766 ************************************************************************/
768 static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
770 const char *controller,
771 struct cli_state **cli,
774 char *machine_password = NULL;
775 char *machine_krb5_principal = NULL;
776 char *machine_account = NULL;
777 char *ipc_username = NULL;
778 char *ipc_domain = NULL;
779 char *ipc_password = NULL;
781 struct named_mutex *mutex;
783 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
785 struct sockaddr peeraddr;
786 socklen_t peeraddr_len;
788 struct sockaddr_in *peeraddr_in =
789 (struct sockaddr_in *)(void *)&peeraddr;
791 DEBUG(10,("cm_prepare_connection: connecting to DC %s for domain %s\n",
792 controller, domain->name ));
796 mutex = grab_named_mutex(talloc_tos(), controller,
797 WINBIND_SERVER_MUTEX_WAIT_TIME);
799 DEBUG(0,("cm_prepare_connection: mutex grab failed for %s\n",
801 result = NT_STATUS_POSSIBLE_DEADLOCK;
805 if ((*cli = cli_initialise()) == NULL) {
806 DEBUG(1, ("Could not cli_initialize\n"));
807 result = NT_STATUS_NO_MEMORY;
811 (*cli)->timeout = 10000; /* 10 seconds */
813 fstrcpy((*cli)->desthost, controller);
814 (*cli)->use_kerberos = True;
816 peeraddr_len = sizeof(peeraddr);
818 if ((getpeername((*cli)->fd, &peeraddr, &peeraddr_len) != 0)) {
819 DEBUG(0,("cm_prepare_connection: getpeername failed with: %s\n",
821 result = NT_STATUS_UNSUCCESSFUL;
825 if ((peeraddr_len != sizeof(struct sockaddr_in))
827 && (peeraddr_len != sizeof(struct sockaddr_in6))
830 DEBUG(0,("cm_prepare_connection: got unexpected peeraddr len %d\n",
832 result = NT_STATUS_UNSUCCESSFUL;
836 if ((peeraddr_in->sin_family != PF_INET)
838 && (peeraddr_in->sin_family != PF_INET6)
841 DEBUG(0,("cm_prepare_connection: got unexpected family %d\n",
842 peeraddr_in->sin_family));
843 result = NT_STATUS_UNSUCCESSFUL;
847 result = cli_negprot(*cli);
849 if (!NT_STATUS_IS_OK(result)) {
850 DEBUG(1, ("cli_negprot failed: %s\n", nt_errstr(result)));
854 if (!is_dc_trusted_domain_situation(domain->name) &&
855 (*cli)->protocol >= PROTOCOL_NT1 &&
856 (*cli)->capabilities & CAP_EXTENDED_SECURITY)
858 ADS_STATUS ads_status;
860 result = get_trust_creds(domain, &machine_password,
862 &machine_krb5_principal);
863 if (!NT_STATUS_IS_OK(result)) {
867 if (lp_security() == SEC_ADS) {
869 /* Try a krb5 session */
871 (*cli)->use_kerberos = True;
872 DEBUG(5, ("connecting to %s from %s with kerberos principal "
873 "[%s] and realm [%s]\n", controller, global_myname(),
874 machine_krb5_principal, domain->alt_name));
876 winbindd_set_locator_kdc_envs(domain);
878 ads_status = cli_session_setup_spnego(*cli,
879 machine_krb5_principal,
884 if (!ADS_ERR_OK(ads_status)) {
885 DEBUG(4,("failed kerberos session setup with %s\n",
886 ads_errstr(ads_status)));
889 result = ads_ntstatus(ads_status);
890 if (NT_STATUS_IS_OK(result)) {
891 /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
892 result = cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
893 if (!NT_STATUS_IS_OK(result)) {
896 goto session_setup_done;
900 /* Fall back to non-kerberos session setup using NTLMSSP SPNEGO with the machine account. */
901 (*cli)->use_kerberos = False;
903 DEBUG(5, ("connecting to %s from %s with username "
904 "[%s]\\[%s]\n", controller, global_myname(),
905 lp_workgroup(), machine_account));
907 ads_status = cli_session_setup_spnego(*cli,
912 if (!ADS_ERR_OK(ads_status)) {
913 DEBUG(4, ("authenticated session setup failed with %s\n",
914 ads_errstr(ads_status)));
917 result = ads_ntstatus(ads_status);
918 if (NT_STATUS_IS_OK(result)) {
919 /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
920 result = cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
921 if (!NT_STATUS_IS_OK(result)) {
924 goto session_setup_done;
928 /* Fall back to non-kerberos session setup with auth_user */
930 (*cli)->use_kerberos = False;
932 cm_get_ipc_userpass(&ipc_username, &ipc_domain, &ipc_password);
934 if ((((*cli)->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) != 0) &&
935 (strlen(ipc_username) > 0)) {
937 /* Only try authenticated if we have a username */
939 DEBUG(5, ("connecting to %s from %s with username "
940 "[%s]\\[%s]\n", controller, global_myname(),
941 ipc_domain, ipc_username));
943 if (NT_STATUS_IS_OK(cli_session_setup(
945 ipc_password, strlen(ipc_password)+1,
946 ipc_password, strlen(ipc_password)+1,
948 /* Successful logon with given username. */
949 result = cli_init_creds(*cli, ipc_username, ipc_domain, ipc_password);
950 if (!NT_STATUS_IS_OK(result)) {
953 goto session_setup_done;
955 DEBUG(4, ("authenticated session setup with user %s\\%s failed.\n",
956 ipc_domain, ipc_username ));
962 /* Fall back to anonymous connection, this might fail later */
963 DEBUG(10,("cm_prepare_connection: falling back to anonymous "
964 "connection for DC %s\n",
967 if (NT_STATUS_IS_OK(cli_session_setup(*cli, "", NULL, 0,
969 DEBUG(5, ("Connected anonymously\n"));
970 result = cli_init_creds(*cli, "", "", "");
971 if (!NT_STATUS_IS_OK(result)) {
974 goto session_setup_done;
977 result = cli_nt_error(*cli);
979 if (NT_STATUS_IS_OK(result))
980 result = NT_STATUS_UNSUCCESSFUL;
982 /* We can't session setup */
988 /* cache the server name for later connections */
990 saf_store( domain->name, (*cli)->desthost );
991 if (domain->alt_name && (*cli)->use_kerberos) {
992 saf_store( domain->alt_name, (*cli)->desthost );
995 winbindd_set_locator_kdc_envs(domain);
997 result = cli_tcon_andx(*cli, "IPC$", "IPC", "", 0);
999 if (!NT_STATUS_IS_OK(result)) {
1000 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(result)));
1007 /* set the domain if empty; needed for schannel connections */
1008 if ( !(*cli)->domain[0] ) {
1009 result = cli_set_domain((*cli), domain->name);
1010 if (!NT_STATUS_IS_OK(result)) {
1015 result = NT_STATUS_OK;
1019 SAFE_FREE(machine_account);
1020 SAFE_FREE(machine_password);
1021 SAFE_FREE(machine_krb5_principal);
1022 SAFE_FREE(ipc_username);
1023 SAFE_FREE(ipc_domain);
1024 SAFE_FREE(ipc_password);
1026 if (!NT_STATUS_IS_OK(result)) {
1027 winbind_add_failed_connection_entry(domain, controller, result);
1028 if ((*cli) != NULL) {
1037 /*******************************************************************
1038 Add a dcname and sockaddr_storage pair to the end of a dc_name_ip
1041 Keeps the list unique by not adding duplicate entries.
1043 @param[in] mem_ctx talloc memory context to allocate from
1044 @param[in] domain_name domain of the DC
1045 @param[in] dcname name of the DC to add to the list
1046 @param[in] pss Internet address and port pair to add to the list
1047 @param[in,out] dcs array of dc_name_ip structures to add to
1048 @param[in,out] num_dcs number of dcs returned in the dcs array
1049 @return true if the list was added to, false otherwise
1050 *******************************************************************/
1052 static bool add_one_dc_unique(TALLOC_CTX *mem_ctx, const char *domain_name,
1053 const char *dcname, struct sockaddr_storage *pss,
1054 struct dc_name_ip **dcs, int *num)
1058 if (!NT_STATUS_IS_OK(check_negative_conn_cache(domain_name, dcname))) {
1059 DEBUG(10, ("DC %s was in the negative conn cache\n", dcname));
1063 /* Make sure there's no duplicates in the list */
1064 for (i=0; i<*num; i++)
1066 (struct sockaddr *)(void *)&(*dcs)[i].ss,
1067 (struct sockaddr *)(void *)pss))
1070 *dcs = TALLOC_REALLOC_ARRAY(mem_ctx, *dcs, struct dc_name_ip, (*num)+1);
1075 fstrcpy((*dcs)[*num].name, dcname);
1076 (*dcs)[*num].ss = *pss;
1081 static bool add_sockaddr_to_array(TALLOC_CTX *mem_ctx,
1082 struct sockaddr_storage *pss, uint16 port,
1083 struct sockaddr_storage **addrs, int *num)
1085 *addrs = TALLOC_REALLOC_ARRAY(mem_ctx, *addrs, struct sockaddr_storage, (*num)+1);
1087 if (*addrs == NULL) {
1092 (*addrs)[*num] = *pss;
1093 set_sockaddr_port((struct sockaddr *)&(*addrs)[*num], port);
1099 /*******************************************************************
1100 convert an ip to a name
1101 *******************************************************************/
1103 static bool dcip_to_name(TALLOC_CTX *mem_ctx,
1104 const struct winbindd_domain *domain,
1105 struct sockaddr_storage *pss,
1108 struct ip_service ip_list;
1109 uint32_t nt_version = NETLOGON_NT_VERSION_1;
1117 /* For active directory servers, try to get the ldap server name.
1118 None of these failures should be considered critical for now */
1120 if (lp_security() == SEC_ADS) {
1122 ADS_STATUS ads_status;
1123 char addr[INET6_ADDRSTRLEN];
1125 print_sockaddr(addr, sizeof(addr), pss);
1127 ads = ads_init(domain->alt_name, domain->name, addr);
1128 ads->auth.flags |= ADS_AUTH_NO_BIND;
1130 ads_status = ads_connect(ads);
1131 if (ADS_ERR_OK(ads_status)) {
1132 /* We got a cldap packet. */
1133 fstrcpy(name, ads->config.ldap_server_name);
1134 namecache_store(name, 0x20, 1, &ip_list);
1136 DEBUG(10,("dcip_to_name: flags = 0x%x\n", (unsigned int)ads->config.flags));
1138 if (domain->primary && (ads->config.flags & NBT_SERVER_KDC)) {
1139 if (ads_closest_dc(ads)) {
1140 char *sitename = sitename_fetch(ads->config.realm);
1142 /* We're going to use this KDC for this realm/domain.
1143 If we are using sites, then force the krb5 libs
1146 create_local_private_krb5_conf_for_domain(domain->alt_name,
1152 SAFE_FREE(sitename);
1154 /* use an off site KDC */
1155 create_local_private_krb5_conf_for_domain(domain->alt_name,
1161 winbindd_set_locator_kdc_envs(domain);
1163 /* Ensure we contact this DC also. */
1164 saf_store( domain->name, name);
1165 saf_store( domain->alt_name, name);
1168 ads_destroy( &ads );
1172 ads_destroy( &ads );
1176 /* try GETDC requests next */
1177 generate_random_buffer((uint8_t *)&val, 2);
1180 if (send_getdc_request(mem_ctx, winbind_messaging_context(),
1181 pss, domain->name, &domain->sid,
1182 nt_version, dgm_id)) {
1183 const char *dc_name = NULL;
1186 for (i=0; i<5; i++) {
1187 if (receive_getdc_response(mem_ctx, pss, domain->name,
1191 fstrcpy(name, dc_name);
1192 namecache_store(name, 0x20, 1, &ip_list);
1199 /* try node status request */
1201 if ( name_status_find(domain->name, 0x1c, 0x20, pss, name) ) {
1202 namecache_store(name, 0x20, 1, &ip_list);
1208 /*******************************************************************
1209 Retrieve a list of IP addresses for domain controllers.
1211 The array is sorted in the preferred connection order.
1213 @param[in] mem_ctx talloc memory context to allocate from
1214 @param[in] domain domain to retrieve DCs for
1215 @param[out] dcs array of dcs that will be returned
1216 @param[out] num_dcs number of dcs returned in the dcs array
1218 *******************************************************************/
1220 static bool get_dcs(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
1221 struct dc_name_ip **dcs, int *num_dcs)
1224 struct sockaddr_storage ss;
1225 struct ip_service *ip_list = NULL;
1226 int iplist_size = 0;
1229 enum security_types sec = (enum security_types)lp_security();
1231 is_our_domain = strequal(domain->name, lp_workgroup());
1233 /* If not our domain, get the preferred DC, by asking our primary DC */
1235 && get_dc_name_via_netlogon(domain, dcname, &ss)
1236 && add_one_dc_unique(mem_ctx, domain->name, dcname, &ss, dcs,
1239 char addr[INET6_ADDRSTRLEN];
1240 print_sockaddr(addr, sizeof(addr), &ss);
1241 DEBUG(10, ("Retrieved DC %s at %s via netlogon\n",
1246 if (sec == SEC_ADS) {
1247 char *sitename = NULL;
1249 /* We need to make sure we know the local site before
1250 doing any DNS queries, as this will restrict the
1251 get_sorted_dc_list() call below to only fetching
1252 DNS records for the correct site. */
1254 /* Find any DC to get the site record.
1255 We deliberately don't care about the
1258 get_dc_name(domain->name, domain->alt_name, dcname, &ss);
1260 sitename = sitename_fetch(domain->alt_name);
1263 /* Do the site-specific AD dns lookup first. */
1264 get_sorted_dc_list(domain->alt_name, sitename, &ip_list,
1265 &iplist_size, True);
1267 /* Add ips to the DC array. We don't look up the name
1268 of the DC in this function, but we fill in the char*
1269 of the ip now to make the failed connection cache
1271 for ( i=0; i<iplist_size; i++ ) {
1272 char addr[INET6_ADDRSTRLEN];
1273 print_sockaddr(addr, sizeof(addr),
1275 add_one_dc_unique(mem_ctx,
1284 SAFE_FREE(sitename);
1288 /* Now we add DCs from the main AD DNS lookup. */
1289 get_sorted_dc_list(domain->alt_name, NULL, &ip_list,
1290 &iplist_size, True);
1292 for ( i=0; i<iplist_size; i++ ) {
1293 char addr[INET6_ADDRSTRLEN];
1294 print_sockaddr(addr, sizeof(addr),
1296 add_one_dc_unique(mem_ctx,
1308 /* Try standard netbios queries if no ADS */
1309 if (*num_dcs == 0) {
1310 get_sorted_dc_list(domain->name, NULL, &ip_list, &iplist_size,
1313 for ( i=0; i<iplist_size; i++ ) {
1314 char addr[INET6_ADDRSTRLEN];
1315 print_sockaddr(addr, sizeof(addr),
1317 add_one_dc_unique(mem_ctx,
1332 /*******************************************************************
1333 Find and make a connection to a DC in the given domain.
1335 @param[in] mem_ctx talloc memory context to allocate from
1336 @param[in] domain domain to find a dc in
1337 @param[out] dcname NetBIOS or FQDN of DC that's connected to
1338 @param[out] pss DC Internet address and port
1339 @param[out] fd fd of the open socket connected to the newly found dc
1340 @return true when a DC connection is made, false otherwise
1341 *******************************************************************/
1343 static bool find_new_dc(TALLOC_CTX *mem_ctx,
1344 struct winbindd_domain *domain,
1345 fstring dcname, struct sockaddr_storage *pss, int *fd)
1347 struct dc_name_ip *dcs = NULL;
1350 const char **dcnames = NULL;
1351 int num_dcnames = 0;
1353 struct sockaddr_storage *addrs = NULL;
1364 if (!get_dcs(mem_ctx, domain, &dcs, &num_dcs) || (num_dcs == 0))
1367 for (i=0; i<num_dcs; i++) {
1369 if (!add_string_to_array(mem_ctx, dcs[i].name,
1370 &dcnames, &num_dcnames)) {
1373 if (!add_sockaddr_to_array(mem_ctx, &dcs[i].ss, 445,
1374 &addrs, &num_addrs)) {
1379 if ((num_dcnames == 0) || (num_dcnames != num_addrs))
1382 if ((addrs == NULL) || (dcnames == NULL))
1385 status = smbsock_any_connect(addrs, dcnames, num_addrs,
1386 fd, &fd_index, NULL);
1387 if (!NT_STATUS_IS_OK(status)) {
1388 for (i=0; i<num_dcs; i++) {
1389 char ab[INET6_ADDRSTRLEN];
1390 print_sockaddr(ab, sizeof(ab), &dcs[i].ss);
1391 DEBUG(10, ("find_new_dc: smbsock_any_connect failed for "
1392 "domain %s address %s. Error was %s\n",
1393 domain->name, ab, nt_errstr(status) ));
1394 winbind_add_failed_connection_entry(domain,
1395 dcs[i].name, NT_STATUS_UNSUCCESSFUL);
1400 *pss = addrs[fd_index];
1402 if (*dcnames[fd_index] != '\0' && !is_ipaddress(dcnames[fd_index])) {
1403 /* Ok, we've got a name for the DC */
1404 fstrcpy(dcname, dcnames[fd_index]);
1408 /* Try to figure out the name */
1409 if (dcip_to_name(mem_ctx, domain, pss, dcname)) {
1413 /* We can not continue without the DC's name */
1414 winbind_add_failed_connection_entry(domain, dcs[fd_index].name,
1415 NT_STATUS_UNSUCCESSFUL);
1417 /* Throw away all arrays as we're doing this again. */
1421 TALLOC_FREE(dcnames);
1433 static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
1434 struct winbindd_cm_conn *new_conn)
1436 TALLOC_CTX *mem_ctx;
1438 char *saf_servername = saf_fetch( domain->name );
1441 if ((mem_ctx = talloc_init("cm_open_connection")) == NULL) {
1442 SAFE_FREE(saf_servername);
1443 set_domain_offline(domain);
1444 return NT_STATUS_NO_MEMORY;
1447 /* we have to check the server affinity cache here since
1448 later we select a DC based on response time and not preference */
1450 /* Check the negative connection cache
1451 before talking to it. It going down may have
1452 triggered the reconnection. */
1454 if ( saf_servername && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, saf_servername))) {
1456 DEBUG(10,("cm_open_connection: saf_servername is '%s' for domain %s\n",
1457 saf_servername, domain->name ));
1459 /* convert an ip address to a name */
1460 if (is_ipaddress( saf_servername ) ) {
1462 struct sockaddr_storage ss;
1464 if (!interpret_string_addr(&ss, saf_servername,
1466 return NT_STATUS_UNSUCCESSFUL;
1468 if (dcip_to_name(mem_ctx, domain, &ss, saf_name )) {
1469 fstrcpy( domain->dcname, saf_name );
1471 winbind_add_failed_connection_entry(
1472 domain, saf_servername,
1473 NT_STATUS_UNSUCCESSFUL);
1476 fstrcpy( domain->dcname, saf_servername );
1479 SAFE_FREE( saf_servername );
1482 for (retries = 0; retries < 3; retries++) {
1486 result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1488 DEBUG(10,("cm_open_connection: dcname is '%s' for domain %s\n",
1489 domain->dcname, domain->name ));
1492 && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, domain->dcname))
1493 && (resolve_name(domain->dcname, &domain->dcaddr, 0x20, true)))
1497 status = smbsock_connect(&domain->dcaddr, NULL, NULL,
1499 if (!NT_STATUS_IS_OK(status)) {
1505 && !find_new_dc(mem_ctx, domain, domain->dcname, &domain->dcaddr, &fd))
1507 /* This is the one place where we will
1508 set the global winbindd offline state
1509 to true, if a "WINBINDD_OFFLINE" entry
1510 is found in the winbindd cache. */
1511 set_global_winbindd_state_offline();
1515 new_conn->cli = NULL;
1517 result = cm_prepare_connection(domain, fd, domain->dcname,
1518 &new_conn->cli, &retry);
1524 if (NT_STATUS_IS_OK(result)) {
1526 winbindd_set_locator_kdc_envs(domain);
1528 if (domain->online == False) {
1529 /* We're changing state from offline to online. */
1530 set_global_winbindd_state_online();
1532 set_domain_online(domain);
1534 /* Ensure we setup the retry handler. */
1535 set_domain_offline(domain);
1538 talloc_destroy(mem_ctx);
1542 /* Close down all open pipes on a connection. */
1544 void invalidate_cm_connection(struct winbindd_cm_conn *conn)
1546 /* We're closing down a possibly dead
1547 connection. Don't have impossibly long (10s) timeouts. */
1550 cli_set_timeout(conn->cli, 1000); /* 1 second. */
1553 if (conn->samr_pipe != NULL) {
1554 if (is_valid_policy_hnd(&conn->sam_connect_handle)) {
1555 rpccli_samr_Close(conn->samr_pipe, talloc_tos(),
1556 &conn->sam_connect_handle);
1558 TALLOC_FREE(conn->samr_pipe);
1559 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1561 cli_set_timeout(conn->cli, 500);
1565 if (conn->lsa_pipe != NULL) {
1566 if (is_valid_policy_hnd(&conn->lsa_policy)) {
1567 rpccli_lsa_Close(conn->lsa_pipe, talloc_tos(),
1570 TALLOC_FREE(conn->lsa_pipe);
1571 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1573 cli_set_timeout(conn->cli, 500);
1577 if (conn->lsa_pipe_tcp != NULL) {
1578 if (is_valid_policy_hnd(&conn->lsa_policy)) {
1579 rpccli_lsa_Close(conn->lsa_pipe, talloc_tos(),
1582 TALLOC_FREE(conn->lsa_pipe_tcp);
1583 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1585 cli_set_timeout(conn->cli, 500);
1589 if (conn->netlogon_pipe != NULL) {
1590 TALLOC_FREE(conn->netlogon_pipe);
1591 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1593 cli_set_timeout(conn->cli, 500);
1598 cli_shutdown(conn->cli);
1604 void close_conns_after_fork(void)
1606 struct winbindd_domain *domain;
1608 for (domain = domain_list(); domain; domain = domain->next) {
1609 struct cli_state *cli = domain->conn.cli;
1612 * first close the low level SMB TCP connection
1613 * so that we don't generate any SMBclose
1614 * requests in invalidate_cm_connection()
1616 if (cli && cli->fd != -1) {
1617 close(domain->conn.cli->fd);
1618 domain->conn.cli->fd = -1;
1621 invalidate_cm_connection(&domain->conn);
1625 static bool connection_ok(struct winbindd_domain *domain)
1629 ok = cli_state_is_connected(domain->conn.cli);
1631 DEBUG(3, ("connection_ok: Connection to %s for domain %s is not connected\n",
1632 domain->dcname, domain->name));
1636 if (domain->online == False) {
1637 DEBUG(3, ("connection_ok: Domain %s is offline\n", domain->name));
1644 /* Initialize a new connection up to the RPC BIND.
1645 Bypass online status check so always does network calls. */
1647 static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain)
1651 /* Internal connections never use the network. */
1652 if (domain->internal) {
1653 domain->initialized = True;
1654 return NT_STATUS_OK;
1657 if (!winbindd_can_contact_domain(domain)) {
1658 invalidate_cm_connection(&domain->conn);
1659 domain->initialized = True;
1660 return NT_STATUS_OK;
1663 if (connection_ok(domain)) {
1664 if (!domain->initialized) {
1665 set_dc_type_and_flags(domain);
1667 return NT_STATUS_OK;
1670 invalidate_cm_connection(&domain->conn);
1672 result = cm_open_connection(domain, &domain->conn);
1674 if (NT_STATUS_IS_OK(result) && !domain->initialized) {
1675 set_dc_type_and_flags(domain);
1681 NTSTATUS init_dc_connection(struct winbindd_domain *domain)
1683 if (domain->internal) {
1684 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1687 if (domain->initialized && !domain->online) {
1688 /* We check for online status elsewhere. */
1689 return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1692 return init_dc_connection_network(domain);
1695 static NTSTATUS init_dc_connection_rpc(struct winbindd_domain *domain)
1699 status = init_dc_connection(domain);
1700 if (!NT_STATUS_IS_OK(status)) {
1704 if (!domain->internal && domain->conn.cli == NULL) {
1705 /* happens for trusted domains without inbound trust */
1706 return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
1709 return NT_STATUS_OK;
1712 /******************************************************************************
1713 Set the trust flags (direction and forest location) for a domain
1714 ******************************************************************************/
1716 static bool set_dc_type_and_flags_trustinfo( struct winbindd_domain *domain )
1718 struct winbindd_domain *our_domain;
1719 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1720 struct netr_DomainTrustList trusts;
1722 uint32 flags = (NETR_TRUST_FLAG_IN_FOREST |
1723 NETR_TRUST_FLAG_OUTBOUND |
1724 NETR_TRUST_FLAG_INBOUND);
1725 struct rpc_pipe_client *cli;
1726 TALLOC_CTX *mem_ctx = NULL;
1728 DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s\n", domain->name ));
1730 /* Our primary domain doesn't need to worry about trust flags.
1731 Force it to go through the network setup */
1732 if ( domain->primary ) {
1736 our_domain = find_our_domain();
1738 if ( !connection_ok(our_domain) ) {
1739 DEBUG(3,("set_dc_type_and_flags_trustinfo: No connection to our domain!\n"));
1743 /* This won't work unless our domain is AD */
1745 if ( !our_domain->active_directory ) {
1749 /* Use DsEnumerateDomainTrusts to get us the trust direction
1752 result = cm_connect_netlogon(our_domain, &cli);
1754 if (!NT_STATUS_IS_OK(result)) {
1755 DEBUG(5, ("set_dc_type_and_flags_trustinfo: Could not open "
1756 "a connection to %s for PIPE_NETLOGON (%s)\n",
1757 domain->name, nt_errstr(result)));
1761 if ( (mem_ctx = talloc_init("set_dc_type_and_flags_trustinfo")) == NULL ) {
1762 DEBUG(0,("set_dc_type_and_flags_trustinfo: talloc_init() failed!\n"));
1766 result = rpccli_netr_DsrEnumerateDomainTrusts(cli, mem_ctx,
1771 if (!NT_STATUS_IS_OK(result)) {
1772 DEBUG(0,("set_dc_type_and_flags_trustinfo: "
1773 "failed to query trusted domain list: %s\n",
1774 nt_errstr(result)));
1775 talloc_destroy(mem_ctx);
1779 /* Now find the domain name and get the flags */
1781 for ( i=0; i<trusts.count; i++ ) {
1782 if ( strequal( domain->name, trusts.array[i].netbios_name) ) {
1783 domain->domain_flags = trusts.array[i].trust_flags;
1784 domain->domain_type = trusts.array[i].trust_type;
1785 domain->domain_trust_attribs = trusts.array[i].trust_attributes;
1787 if ( domain->domain_type == NETR_TRUST_TYPE_UPLEVEL )
1788 domain->active_directory = True;
1790 /* This flag is only set if the domain is *our*
1791 primary domain and the primary domain is in
1794 domain->native_mode = (domain->domain_flags & NETR_TRUST_FLAG_NATIVE);
1796 DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s is %sin "
1797 "native mode.\n", domain->name,
1798 domain->native_mode ? "" : "NOT "));
1800 DEBUG(5,("set_dc_type_and_flags_trustinfo: domain %s is %s"
1801 "running active directory.\n", domain->name,
1802 domain->active_directory ? "" : "NOT "));
1805 domain->initialized = True;
1811 talloc_destroy( mem_ctx );
1813 return domain->initialized;
1816 /******************************************************************************
1817 We can 'sense' certain things about the DC by it's replies to certain
1820 This tells us if this particular remote server is Active Directory, and if it
1822 ******************************************************************************/
1824 static void set_dc_type_and_flags_connect( struct winbindd_domain *domain )
1828 TALLOC_CTX *mem_ctx = NULL;
1829 struct rpc_pipe_client *cli = NULL;
1830 struct policy_handle pol;
1831 union dssetup_DsRoleInfo info;
1832 union lsa_PolicyInformation *lsa_info = NULL;
1834 if (!connection_ok(domain)) {
1838 mem_ctx = talloc_init("set_dc_type_and_flags on domain %s\n",
1841 DEBUG(1, ("set_dc_type_and_flags_connect: talloc_init() failed\n"));
1845 DEBUG(5, ("set_dc_type_and_flags_connect: domain %s\n", domain->name ));
1847 result = cli_rpc_pipe_open_noauth(domain->conn.cli,
1848 &ndr_table_dssetup.syntax_id,
1851 if (!NT_STATUS_IS_OK(result)) {
1852 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
1853 "PI_DSSETUP on domain %s: (%s)\n",
1854 domain->name, nt_errstr(result)));
1856 /* if this is just a non-AD domain we need to continue
1857 * identifying so that we can in the end return with
1858 * domain->initialized = True - gd */
1863 result = rpccli_dssetup_DsRoleGetPrimaryDomainInformation(cli, mem_ctx,
1864 DS_ROLE_BASIC_INFORMATION,
1869 if (!NT_STATUS_IS_OK(result)) {
1870 DEBUG(5, ("set_dc_type_and_flags_connect: rpccli_ds_getprimarydominfo "
1871 "on domain %s failed: (%s)\n",
1872 domain->name, nt_errstr(result)));
1874 /* older samba3 DCs will return DCERPC_FAULT_OP_RNG_ERROR for
1875 * every opcode on the DSSETUP pipe, continue with
1876 * no_dssetup mode here as well to get domain->initialized
1879 if (NT_STATUS_V(result) == DCERPC_FAULT_OP_RNG_ERROR) {
1883 TALLOC_FREE(mem_ctx);
1887 if ((info.basic.flags & DS_ROLE_PRIMARY_DS_RUNNING) &&
1888 !(info.basic.flags & DS_ROLE_PRIMARY_DS_MIXED_MODE)) {
1889 domain->native_mode = True;
1891 domain->native_mode = False;
1895 result = cli_rpc_pipe_open_noauth(domain->conn.cli,
1896 &ndr_table_lsarpc.syntax_id, &cli);
1898 if (!NT_STATUS_IS_OK(result)) {
1899 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
1900 "PI_LSARPC on domain %s: (%s)\n",
1901 domain->name, nt_errstr(result)));
1903 TALLOC_FREE(mem_ctx);
1907 result = rpccli_lsa_open_policy2(cli, mem_ctx, True,
1908 SEC_FLAG_MAXIMUM_ALLOWED, &pol);
1910 if (NT_STATUS_IS_OK(result)) {
1911 /* This particular query is exactly what Win2k clients use
1912 to determine that the DC is active directory */
1913 result = rpccli_lsa_QueryInfoPolicy2(cli, mem_ctx,
1915 LSA_POLICY_INFO_DNS,
1919 if (NT_STATUS_IS_OK(result)) {
1920 domain->active_directory = True;
1922 if (lsa_info->dns.name.string) {
1923 fstrcpy(domain->name, lsa_info->dns.name.string);
1926 if (lsa_info->dns.dns_domain.string) {
1927 fstrcpy(domain->alt_name,
1928 lsa_info->dns.dns_domain.string);
1931 /* See if we can set some domain trust flags about
1934 if (lsa_info->dns.dns_forest.string) {
1935 fstrcpy(domain->forest_name,
1936 lsa_info->dns.dns_forest.string);
1938 if (strequal(domain->forest_name, domain->alt_name)) {
1939 domain->domain_flags |= NETR_TRUST_FLAG_TREEROOT;
1943 if (lsa_info->dns.sid) {
1944 sid_copy(&domain->sid, lsa_info->dns.sid);
1947 domain->active_directory = False;
1949 result = rpccli_lsa_open_policy(cli, mem_ctx, True,
1950 SEC_FLAG_MAXIMUM_ALLOWED,
1953 if (!NT_STATUS_IS_OK(result)) {
1957 result = rpccli_lsa_QueryInfoPolicy(cli, mem_ctx,
1959 LSA_POLICY_INFO_ACCOUNT_DOMAIN,
1962 if (NT_STATUS_IS_OK(result)) {
1964 if (lsa_info->account_domain.name.string) {
1965 fstrcpy(domain->name,
1966 lsa_info->account_domain.name.string);
1969 if (lsa_info->account_domain.sid) {
1970 sid_copy(&domain->sid, lsa_info->account_domain.sid);
1976 DEBUG(5, ("set_dc_type_and_flags_connect: domain %s is %sin native mode.\n",
1977 domain->name, domain->native_mode ? "" : "NOT "));
1979 DEBUG(5,("set_dc_type_and_flags_connect: domain %s is %srunning active directory.\n",
1980 domain->name, domain->active_directory ? "" : "NOT "));
1982 domain->can_do_ncacn_ip_tcp = domain->active_directory;
1986 TALLOC_FREE(mem_ctx);
1988 domain->initialized = True;
1991 /**********************************************************************
1992 Set the domain_flags (trust attributes, domain operating modes, etc...
1993 ***********************************************************************/
1995 static void set_dc_type_and_flags( struct winbindd_domain *domain )
1997 /* we always have to contact our primary domain */
1999 if ( domain->primary ) {
2000 DEBUG(10,("set_dc_type_and_flags: setting up flags for "
2001 "primary domain\n"));
2002 set_dc_type_and_flags_connect( domain );
2006 /* Use our DC to get the information if possible */
2008 if ( !set_dc_type_and_flags_trustinfo( domain ) ) {
2009 /* Otherwise, fallback to contacting the
2011 set_dc_type_and_flags_connect( domain );
2019 /**********************************************************************
2020 ***********************************************************************/
2022 static NTSTATUS cm_get_schannel_creds(struct winbindd_domain *domain,
2023 struct netlogon_creds_CredentialState **ppdc)
2025 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2026 struct rpc_pipe_client *netlogon_pipe;
2028 if (lp_client_schannel() == False) {
2029 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;;
2032 result = cm_connect_netlogon(domain, &netlogon_pipe);
2033 if (!NT_STATUS_IS_OK(result)) {
2037 /* Return a pointer to the struct netlogon_creds_CredentialState from the
2040 if (!domain->conn.netlogon_pipe->dc) {
2041 return NT_STATUS_INTERNAL_ERROR; /* This shouldn't happen. */
2044 *ppdc = domain->conn.netlogon_pipe->dc;
2045 return NT_STATUS_OK;
2048 NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
2049 struct rpc_pipe_client **cli, struct policy_handle *sam_handle)
2051 struct winbindd_cm_conn *conn;
2052 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2053 struct netlogon_creds_CredentialState *p_creds;
2054 char *machine_password = NULL;
2055 char *machine_account = NULL;
2056 char *domain_name = NULL;
2058 if (sid_check_is_domain(&domain->sid)) {
2059 return open_internal_samr_conn(mem_ctx, domain, cli, sam_handle);
2062 result = init_dc_connection_rpc(domain);
2063 if (!NT_STATUS_IS_OK(result)) {
2067 conn = &domain->conn;
2069 if (rpccli_is_connected(conn->samr_pipe)) {
2073 TALLOC_FREE(conn->samr_pipe);
2076 * No SAMR pipe yet. Attempt to get an NTLMSSP SPNEGO authenticated
2077 * sign and sealed pipe using the machine account password by
2078 * preference. If we can't - try schannel, if that fails, try
2082 if ((conn->cli->user_name[0] == '\0') ||
2083 (conn->cli->domain[0] == '\0') ||
2084 (conn->cli->password == NULL || conn->cli->password[0] == '\0'))
2086 result = get_trust_creds(domain, &machine_password,
2087 &machine_account, NULL);
2088 if (!NT_STATUS_IS_OK(result)) {
2089 DEBUG(10, ("cm_connect_sam: No no user available for "
2090 "domain %s, trying schannel\n", conn->cli->domain));
2093 domain_name = domain->name;
2095 machine_password = SMB_STRDUP(conn->cli->password);
2096 machine_account = SMB_STRDUP(conn->cli->user_name);
2097 domain_name = conn->cli->domain;
2100 if (!machine_password || !machine_account) {
2101 result = NT_STATUS_NO_MEMORY;
2105 /* We have an authenticated connection. Use a NTLMSSP SPNEGO
2106 authenticated SAMR pipe with sign & seal. */
2107 result = cli_rpc_pipe_open_spnego_ntlmssp(conn->cli,
2108 &ndr_table_samr.syntax_id,
2110 DCERPC_AUTH_LEVEL_PRIVACY,
2116 if (!NT_STATUS_IS_OK(result)) {
2117 DEBUG(10,("cm_connect_sam: failed to connect to SAMR "
2118 "pipe for domain %s using NTLMSSP "
2119 "authenticated pipe: user %s\\%s. Error was "
2120 "%s\n", domain->name, domain_name,
2121 machine_account, nt_errstr(result)));
2125 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for "
2126 "domain %s using NTLMSSP authenticated "
2127 "pipe: user %s\\%s\n", domain->name,
2128 domain_name, machine_account));
2130 result = rpccli_samr_Connect2(conn->samr_pipe, mem_ctx,
2131 conn->samr_pipe->desthost,
2132 SEC_FLAG_MAXIMUM_ALLOWED,
2133 &conn->sam_connect_handle);
2134 if (NT_STATUS_IS_OK(result)) {
2137 DEBUG(10,("cm_connect_sam: ntlmssp-sealed rpccli_samr_Connect2 "
2138 "failed for domain %s, error was %s. Trying schannel\n",
2139 domain->name, nt_errstr(result) ));
2140 TALLOC_FREE(conn->samr_pipe);
2144 /* Fall back to schannel if it's a W2K pre-SP1 box. */
2146 result = cm_get_schannel_creds(domain, &p_creds);
2147 if (!NT_STATUS_IS_OK(result)) {
2148 /* If this call fails - conn->cli can now be NULL ! */
2149 DEBUG(10, ("cm_connect_sam: Could not get schannel auth info "
2150 "for domain %s (error %s), trying anon\n",
2152 nt_errstr(result) ));
2155 result = cli_rpc_pipe_open_schannel_with_key
2156 (conn->cli, &ndr_table_samr.syntax_id, NCACN_NP,
2157 DCERPC_AUTH_LEVEL_PRIVACY,
2158 domain->name, &p_creds, &conn->samr_pipe);
2160 if (!NT_STATUS_IS_OK(result)) {
2161 DEBUG(10,("cm_connect_sam: failed to connect to SAMR pipe for "
2162 "domain %s using schannel. Error was %s\n",
2163 domain->name, nt_errstr(result) ));
2166 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for domain %s using "
2167 "schannel.\n", domain->name ));
2169 result = rpccli_samr_Connect2(conn->samr_pipe, mem_ctx,
2170 conn->samr_pipe->desthost,
2171 SEC_FLAG_MAXIMUM_ALLOWED,
2172 &conn->sam_connect_handle);
2173 if (NT_STATUS_IS_OK(result)) {
2176 DEBUG(10,("cm_connect_sam: schannel-sealed rpccli_samr_Connect2 failed "
2177 "for domain %s, error was %s. Trying anonymous\n",
2178 domain->name, nt_errstr(result) ));
2179 TALLOC_FREE(conn->samr_pipe);
2183 /* Finally fall back to anonymous. */
2184 result = cli_rpc_pipe_open_noauth(conn->cli, &ndr_table_samr.syntax_id,
2187 if (!NT_STATUS_IS_OK(result)) {
2191 result = rpccli_samr_Connect2(conn->samr_pipe, mem_ctx,
2192 conn->samr_pipe->desthost,
2193 SEC_FLAG_MAXIMUM_ALLOWED,
2194 &conn->sam_connect_handle);
2195 if (!NT_STATUS_IS_OK(result)) {
2196 DEBUG(10,("cm_connect_sam: rpccli_samr_Connect2 failed "
2197 "for domain %s Error was %s\n",
2198 domain->name, nt_errstr(result) ));
2203 result = rpccli_samr_OpenDomain(conn->samr_pipe,
2205 &conn->sam_connect_handle,
2206 SEC_FLAG_MAXIMUM_ALLOWED,
2208 &conn->sam_domain_handle);
2212 if (NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED)) {
2214 * if we got access denied, we might just have no access rights
2215 * to talk to the remote samr server server (e.g. when we are a
2216 * PDC and we are connecting a w2k8 pdc via an interdomain
2217 * trust). In that case do not invalidate the whole connection
2220 TALLOC_FREE(conn->samr_pipe);
2221 ZERO_STRUCT(conn->sam_domain_handle);
2223 } else if (!NT_STATUS_IS_OK(result)) {
2224 invalidate_cm_connection(conn);
2228 *cli = conn->samr_pipe;
2229 *sam_handle = conn->sam_domain_handle;
2230 SAFE_FREE(machine_password);
2231 SAFE_FREE(machine_account);
2235 /**********************************************************************
2236 open an schanneld ncacn_ip_tcp connection to LSA
2237 ***********************************************************************/
2239 NTSTATUS cm_connect_lsa_tcp(struct winbindd_domain *domain,
2240 TALLOC_CTX *mem_ctx,
2241 struct rpc_pipe_client **cli)
2243 struct winbindd_cm_conn *conn;
2244 struct netlogon_creds_CredentialState *creds;
2247 DEBUG(10,("cm_connect_lsa_tcp\n"));
2249 status = init_dc_connection_rpc(domain);
2250 if (!NT_STATUS_IS_OK(status)) {
2254 conn = &domain->conn;
2256 if (conn->lsa_pipe_tcp &&
2257 conn->lsa_pipe_tcp->transport->transport == NCACN_IP_TCP &&
2258 conn->lsa_pipe_tcp->auth->auth_level == DCERPC_AUTH_LEVEL_PRIVACY &&
2259 rpccli_is_connected(conn->lsa_pipe_tcp)) {
2263 TALLOC_FREE(conn->lsa_pipe_tcp);
2265 status = cm_get_schannel_creds(domain, &creds);
2266 if (!NT_STATUS_IS_OK(status)) {
2270 status = cli_rpc_pipe_open_schannel_with_key(conn->cli,
2271 &ndr_table_lsarpc.syntax_id,
2273 DCERPC_AUTH_LEVEL_PRIVACY,
2276 &conn->lsa_pipe_tcp);
2277 if (!NT_STATUS_IS_OK(status)) {
2278 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key failed: %s\n",
2279 nt_errstr(status)));
2284 if (!NT_STATUS_IS_OK(status)) {
2285 TALLOC_FREE(conn->lsa_pipe_tcp);
2289 *cli = conn->lsa_pipe_tcp;
2294 NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
2295 struct rpc_pipe_client **cli, struct policy_handle *lsa_policy)
2297 struct winbindd_cm_conn *conn;
2298 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2299 struct netlogon_creds_CredentialState *p_creds;
2301 result = init_dc_connection_rpc(domain);
2302 if (!NT_STATUS_IS_OK(result))
2305 conn = &domain->conn;
2307 if (rpccli_is_connected(conn->lsa_pipe)) {
2311 TALLOC_FREE(conn->lsa_pipe);
2313 if ((conn->cli->user_name[0] == '\0') ||
2314 (conn->cli->domain[0] == '\0') ||
2315 (conn->cli->password == NULL || conn->cli->password[0] == '\0')) {
2316 DEBUG(10, ("cm_connect_lsa: No no user available for "
2317 "domain %s, trying schannel\n", conn->cli->domain));
2321 /* We have an authenticated connection. Use a NTLMSSP SPNEGO
2322 * authenticated LSA pipe with sign & seal. */
2323 result = cli_rpc_pipe_open_spnego_ntlmssp
2324 (conn->cli, &ndr_table_lsarpc.syntax_id, NCACN_NP,
2325 DCERPC_AUTH_LEVEL_PRIVACY,
2326 conn->cli->domain, conn->cli->user_name, conn->cli->password,
2329 if (!NT_STATUS_IS_OK(result)) {
2330 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
2331 "domain %s using NTLMSSP authenticated pipe: user "
2332 "%s\\%s. Error was %s. Trying schannel.\n",
2333 domain->name, conn->cli->domain,
2334 conn->cli->user_name, nt_errstr(result)));
2338 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
2339 "NTLMSSP authenticated pipe: user %s\\%s\n",
2340 domain->name, conn->cli->domain, conn->cli->user_name ));
2342 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2343 SEC_FLAG_MAXIMUM_ALLOWED,
2345 if (NT_STATUS_IS_OK(result)) {
2349 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
2352 TALLOC_FREE(conn->lsa_pipe);
2356 /* Fall back to schannel if it's a W2K pre-SP1 box. */
2358 result = cm_get_schannel_creds(domain, &p_creds);
2359 if (!NT_STATUS_IS_OK(result)) {
2360 /* If this call fails - conn->cli can now be NULL ! */
2361 DEBUG(10, ("cm_connect_lsa: Could not get schannel auth info "
2362 "for domain %s (error %s), trying anon\n",
2364 nt_errstr(result) ));
2367 result = cli_rpc_pipe_open_schannel_with_key
2368 (conn->cli, &ndr_table_lsarpc.syntax_id, NCACN_NP,
2369 DCERPC_AUTH_LEVEL_PRIVACY,
2370 domain->name, &p_creds, &conn->lsa_pipe);
2372 if (!NT_STATUS_IS_OK(result)) {
2373 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
2374 "domain %s using schannel. Error was %s\n",
2375 domain->name, nt_errstr(result) ));
2378 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
2379 "schannel.\n", domain->name ));
2381 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2382 SEC_FLAG_MAXIMUM_ALLOWED,
2384 if (NT_STATUS_IS_OK(result)) {
2388 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
2391 TALLOC_FREE(conn->lsa_pipe);
2395 result = cli_rpc_pipe_open_noauth(conn->cli,
2396 &ndr_table_lsarpc.syntax_id,
2398 if (!NT_STATUS_IS_OK(result)) {
2399 result = NT_STATUS_PIPE_NOT_AVAILABLE;
2403 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2404 SEC_FLAG_MAXIMUM_ALLOWED,
2407 if (!NT_STATUS_IS_OK(result)) {
2408 invalidate_cm_connection(conn);
2412 *cli = conn->lsa_pipe;
2413 *lsa_policy = conn->lsa_policy;
2417 /****************************************************************************
2418 Open the netlogon pipe to this DC. Use schannel if specified in client conf.
2419 session key stored in conn->netlogon_pipe->dc->sess_key.
2420 ****************************************************************************/
2422 NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
2423 struct rpc_pipe_client **cli)
2425 struct winbindd_cm_conn *conn;
2428 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
2430 enum netr_SchannelType sec_chan_type;
2431 const char *account_name;
2432 struct rpc_pipe_client *netlogon_pipe = NULL;
2436 result = init_dc_connection_rpc(domain);
2437 if (!NT_STATUS_IS_OK(result)) {
2441 conn = &domain->conn;
2443 if (rpccli_is_connected(conn->netlogon_pipe)) {
2444 *cli = conn->netlogon_pipe;
2445 return NT_STATUS_OK;
2448 TALLOC_FREE(conn->netlogon_pipe);
2450 result = cli_rpc_pipe_open_noauth(conn->cli,
2451 &ndr_table_netlogon.syntax_id,
2453 if (!NT_STATUS_IS_OK(result)) {
2457 if ((!IS_DC) && (!domain->primary)) {
2458 /* Clear the schannel request bit and drop down */
2459 neg_flags &= ~NETLOGON_NEG_SCHANNEL;
2463 if (lp_client_schannel() != False) {
2464 neg_flags |= NETLOGON_NEG_SCHANNEL;
2467 if (!get_trust_pw_hash(domain->name, mach_pwd, &account_name,
2470 TALLOC_FREE(netlogon_pipe);
2471 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2474 result = rpccli_netlogon_setup_creds(
2476 domain->dcname, /* server name. */
2477 domain->name, /* domain name */
2478 global_myname(), /* client name */
2479 account_name, /* machine account */
2480 mach_pwd, /* machine password */
2481 sec_chan_type, /* from get_trust_pw */
2484 if (!NT_STATUS_IS_OK(result)) {
2485 TALLOC_FREE(netlogon_pipe);
2489 if ((lp_client_schannel() == True) &&
2490 ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
2491 DEBUG(3, ("Server did not offer schannel\n"));
2492 TALLOC_FREE(netlogon_pipe);
2493 return NT_STATUS_ACCESS_DENIED;
2497 if ((lp_client_schannel() == False) ||
2498 ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
2500 * NetSamLogonEx only works for schannel
2502 domain->can_do_samlogon_ex = False;
2504 /* We're done - just keep the existing connection to NETLOGON
2506 conn->netlogon_pipe = netlogon_pipe;
2507 *cli = conn->netlogon_pipe;
2508 return NT_STATUS_OK;
2511 /* Using the credentials from the first pipe, open a signed and sealed
2512 second netlogon pipe. The session key is stored in the schannel
2513 part of the new pipe auth struct.
2516 result = cli_rpc_pipe_open_schannel_with_key(
2517 conn->cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
2518 DCERPC_AUTH_LEVEL_PRIVACY, domain->name, &netlogon_pipe->dc,
2519 &conn->netlogon_pipe);
2521 /* We can now close the initial netlogon pipe. */
2522 TALLOC_FREE(netlogon_pipe);
2524 if (!NT_STATUS_IS_OK(result)) {
2525 DEBUG(3, ("Could not open schannel'ed NETLOGON pipe. Error "
2526 "was %s\n", nt_errstr(result)));
2528 invalidate_cm_connection(conn);
2533 * Always try netr_LogonSamLogonEx. We will fall back for NT4
2534 * which gives DCERPC_FAULT_OP_RNG_ERROR (function not
2535 * supported). We used to only try SamLogonEx for AD, but
2536 * Samba DCs can also do it. And because we don't distinguish
2537 * between Samba and NT4, always try it once.
2539 domain->can_do_samlogon_ex = true;
2541 *cli = conn->netlogon_pipe;
2542 return NT_STATUS_OK;
2545 void winbind_msg_ip_dropped(struct messaging_context *msg_ctx,
2548 struct server_id server_id,
2551 struct winbindd_domain *domain;
2554 || (data->data == NULL)
2555 || (data->length == 0)
2556 || (data->data[data->length-1] != '\0')
2557 || !is_ipaddress((char *)data->data)) {
2558 DEBUG(1, ("invalid msg_ip_dropped message\n"));
2561 for (domain = domain_list(); domain != NULL; domain = domain->next) {
2562 char sockaddr[INET6_ADDRSTRLEN];
2563 if (domain->conn.cli == NULL) {
2566 if (domain->conn.cli->fd == -1) {
2569 client_socket_addr(domain->conn.cli->fd, sockaddr,
2571 if (strequal(sockaddr, (char *)data->data)) {
2572 close(domain->conn.cli->fd);
2573 domain->conn.cli->fd = -1;