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(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, NULL, NULL, NULL,
1386 num_addrs, 0, 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, 0,
1500 if (!NT_STATUS_IS_OK(status)) {
1506 && !find_new_dc(mem_ctx, domain, domain->dcname, &domain->dcaddr, &fd))
1508 /* This is the one place where we will
1509 set the global winbindd offline state
1510 to true, if a "WINBINDD_OFFLINE" entry
1511 is found in the winbindd cache. */
1512 set_global_winbindd_state_offline();
1516 new_conn->cli = NULL;
1518 result = cm_prepare_connection(domain, fd, domain->dcname,
1519 &new_conn->cli, &retry);
1525 if (NT_STATUS_IS_OK(result)) {
1527 winbindd_set_locator_kdc_envs(domain);
1529 if (domain->online == False) {
1530 /* We're changing state from offline to online. */
1531 set_global_winbindd_state_online();
1533 set_domain_online(domain);
1535 /* Ensure we setup the retry handler. */
1536 set_domain_offline(domain);
1539 talloc_destroy(mem_ctx);
1543 /* Close down all open pipes on a connection. */
1545 void invalidate_cm_connection(struct winbindd_cm_conn *conn)
1547 /* We're closing down a possibly dead
1548 connection. Don't have impossibly long (10s) timeouts. */
1551 cli_set_timeout(conn->cli, 1000); /* 1 second. */
1554 if (conn->samr_pipe != NULL) {
1555 if (is_valid_policy_hnd(&conn->sam_connect_handle)) {
1556 rpccli_samr_Close(conn->samr_pipe, talloc_tos(),
1557 &conn->sam_connect_handle);
1559 TALLOC_FREE(conn->samr_pipe);
1560 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1562 cli_set_timeout(conn->cli, 500);
1566 if (conn->lsa_pipe != NULL) {
1567 if (is_valid_policy_hnd(&conn->lsa_policy)) {
1568 rpccli_lsa_Close(conn->lsa_pipe, talloc_tos(),
1571 TALLOC_FREE(conn->lsa_pipe);
1572 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1574 cli_set_timeout(conn->cli, 500);
1578 if (conn->lsa_pipe_tcp != NULL) {
1579 if (is_valid_policy_hnd(&conn->lsa_policy)) {
1580 rpccli_lsa_Close(conn->lsa_pipe, talloc_tos(),
1583 TALLOC_FREE(conn->lsa_pipe_tcp);
1584 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1586 cli_set_timeout(conn->cli, 500);
1590 if (conn->netlogon_pipe != NULL) {
1591 TALLOC_FREE(conn->netlogon_pipe);
1592 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1594 cli_set_timeout(conn->cli, 500);
1599 cli_shutdown(conn->cli);
1605 void close_conns_after_fork(void)
1607 struct winbindd_domain *domain;
1609 for (domain = domain_list(); domain; domain = domain->next) {
1610 struct cli_state *cli = domain->conn.cli;
1613 * first close the low level SMB TCP connection
1614 * so that we don't generate any SMBclose
1615 * requests in invalidate_cm_connection()
1617 if (cli && cli->fd != -1) {
1618 close(domain->conn.cli->fd);
1619 domain->conn.cli->fd = -1;
1622 invalidate_cm_connection(&domain->conn);
1626 static bool connection_ok(struct winbindd_domain *domain)
1630 ok = cli_state_is_connected(domain->conn.cli);
1632 DEBUG(3, ("connection_ok: Connection to %s for domain %s is not connected\n",
1633 domain->dcname, domain->name));
1637 if (domain->online == False) {
1638 DEBUG(3, ("connection_ok: Domain %s is offline\n", domain->name));
1645 /* Initialize a new connection up to the RPC BIND.
1646 Bypass online status check so always does network calls. */
1648 static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain)
1652 /* Internal connections never use the network. */
1653 if (domain->internal) {
1654 domain->initialized = True;
1655 return NT_STATUS_OK;
1658 if (!winbindd_can_contact_domain(domain)) {
1659 invalidate_cm_connection(&domain->conn);
1660 domain->initialized = True;
1661 return NT_STATUS_OK;
1664 if (connection_ok(domain)) {
1665 if (!domain->initialized) {
1666 set_dc_type_and_flags(domain);
1668 return NT_STATUS_OK;
1671 invalidate_cm_connection(&domain->conn);
1673 result = cm_open_connection(domain, &domain->conn);
1675 if (NT_STATUS_IS_OK(result) && !domain->initialized) {
1676 set_dc_type_and_flags(domain);
1682 NTSTATUS init_dc_connection(struct winbindd_domain *domain)
1684 if (domain->internal) {
1685 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1688 if (domain->initialized && !domain->online) {
1689 /* We check for online status elsewhere. */
1690 return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1693 return init_dc_connection_network(domain);
1696 static NTSTATUS init_dc_connection_rpc(struct winbindd_domain *domain)
1700 status = init_dc_connection(domain);
1701 if (!NT_STATUS_IS_OK(status)) {
1705 if (!domain->internal && domain->conn.cli == NULL) {
1706 /* happens for trusted domains without inbound trust */
1707 return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
1710 return NT_STATUS_OK;
1713 /******************************************************************************
1714 Set the trust flags (direction and forest location) for a domain
1715 ******************************************************************************/
1717 static bool set_dc_type_and_flags_trustinfo( struct winbindd_domain *domain )
1719 struct winbindd_domain *our_domain;
1720 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1721 struct netr_DomainTrustList trusts;
1723 uint32 flags = (NETR_TRUST_FLAG_IN_FOREST |
1724 NETR_TRUST_FLAG_OUTBOUND |
1725 NETR_TRUST_FLAG_INBOUND);
1726 struct rpc_pipe_client *cli;
1727 TALLOC_CTX *mem_ctx = NULL;
1729 DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s\n", domain->name ));
1731 /* Our primary domain doesn't need to worry about trust flags.
1732 Force it to go through the network setup */
1733 if ( domain->primary ) {
1737 our_domain = find_our_domain();
1739 if ( !connection_ok(our_domain) ) {
1740 DEBUG(3,("set_dc_type_and_flags_trustinfo: No connection to our domain!\n"));
1744 /* This won't work unless our domain is AD */
1746 if ( !our_domain->active_directory ) {
1750 /* Use DsEnumerateDomainTrusts to get us the trust direction
1753 result = cm_connect_netlogon(our_domain, &cli);
1755 if (!NT_STATUS_IS_OK(result)) {
1756 DEBUG(5, ("set_dc_type_and_flags_trustinfo: Could not open "
1757 "a connection to %s for PIPE_NETLOGON (%s)\n",
1758 domain->name, nt_errstr(result)));
1762 if ( (mem_ctx = talloc_init("set_dc_type_and_flags_trustinfo")) == NULL ) {
1763 DEBUG(0,("set_dc_type_and_flags_trustinfo: talloc_init() failed!\n"));
1767 result = rpccli_netr_DsrEnumerateDomainTrusts(cli, mem_ctx,
1772 if (!NT_STATUS_IS_OK(result)) {
1773 DEBUG(0,("set_dc_type_and_flags_trustinfo: "
1774 "failed to query trusted domain list: %s\n",
1775 nt_errstr(result)));
1776 talloc_destroy(mem_ctx);
1780 /* Now find the domain name and get the flags */
1782 for ( i=0; i<trusts.count; i++ ) {
1783 if ( strequal( domain->name, trusts.array[i].netbios_name) ) {
1784 domain->domain_flags = trusts.array[i].trust_flags;
1785 domain->domain_type = trusts.array[i].trust_type;
1786 domain->domain_trust_attribs = trusts.array[i].trust_attributes;
1788 if ( domain->domain_type == NETR_TRUST_TYPE_UPLEVEL )
1789 domain->active_directory = True;
1791 /* This flag is only set if the domain is *our*
1792 primary domain and the primary domain is in
1795 domain->native_mode = (domain->domain_flags & NETR_TRUST_FLAG_NATIVE);
1797 DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s is %sin "
1798 "native mode.\n", domain->name,
1799 domain->native_mode ? "" : "NOT "));
1801 DEBUG(5,("set_dc_type_and_flags_trustinfo: domain %s is %s"
1802 "running active directory.\n", domain->name,
1803 domain->active_directory ? "" : "NOT "));
1806 domain->initialized = True;
1812 talloc_destroy( mem_ctx );
1814 return domain->initialized;
1817 /******************************************************************************
1818 We can 'sense' certain things about the DC by it's replies to certain
1821 This tells us if this particular remote server is Active Directory, and if it
1823 ******************************************************************************/
1825 static void set_dc_type_and_flags_connect( struct winbindd_domain *domain )
1829 TALLOC_CTX *mem_ctx = NULL;
1830 struct rpc_pipe_client *cli = NULL;
1831 struct policy_handle pol;
1832 union dssetup_DsRoleInfo info;
1833 union lsa_PolicyInformation *lsa_info = NULL;
1835 if (!connection_ok(domain)) {
1839 mem_ctx = talloc_init("set_dc_type_and_flags on domain %s\n",
1842 DEBUG(1, ("set_dc_type_and_flags_connect: talloc_init() failed\n"));
1846 DEBUG(5, ("set_dc_type_and_flags_connect: domain %s\n", domain->name ));
1848 result = cli_rpc_pipe_open_noauth(domain->conn.cli,
1849 &ndr_table_dssetup.syntax_id,
1852 if (!NT_STATUS_IS_OK(result)) {
1853 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
1854 "PI_DSSETUP on domain %s: (%s)\n",
1855 domain->name, nt_errstr(result)));
1857 /* if this is just a non-AD domain we need to continue
1858 * identifying so that we can in the end return with
1859 * domain->initialized = True - gd */
1864 result = dcerpc_dssetup_DsRoleGetPrimaryDomainInformation(cli->binding_handle, mem_ctx,
1865 DS_ROLE_BASIC_INFORMATION,
1870 if (NT_STATUS_IS_OK(result)) {
1871 result = werror_to_ntstatus(werr);
1873 if (!NT_STATUS_IS_OK(result)) {
1874 DEBUG(5, ("set_dc_type_and_flags_connect: rpccli_ds_getprimarydominfo "
1875 "on domain %s failed: (%s)\n",
1876 domain->name, nt_errstr(result)));
1878 /* older samba3 DCs will return DCERPC_FAULT_OP_RNG_ERROR for
1879 * every opcode on the DSSETUP pipe, continue with
1880 * no_dssetup mode here as well to get domain->initialized
1883 if (NT_STATUS_V(result) == DCERPC_FAULT_OP_RNG_ERROR) {
1887 TALLOC_FREE(mem_ctx);
1891 if ((info.basic.flags & DS_ROLE_PRIMARY_DS_RUNNING) &&
1892 !(info.basic.flags & DS_ROLE_PRIMARY_DS_MIXED_MODE)) {
1893 domain->native_mode = True;
1895 domain->native_mode = False;
1899 result = cli_rpc_pipe_open_noauth(domain->conn.cli,
1900 &ndr_table_lsarpc.syntax_id, &cli);
1902 if (!NT_STATUS_IS_OK(result)) {
1903 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
1904 "PI_LSARPC on domain %s: (%s)\n",
1905 domain->name, nt_errstr(result)));
1907 TALLOC_FREE(mem_ctx);
1911 result = rpccli_lsa_open_policy2(cli, mem_ctx, True,
1912 SEC_FLAG_MAXIMUM_ALLOWED, &pol);
1914 if (NT_STATUS_IS_OK(result)) {
1915 /* This particular query is exactly what Win2k clients use
1916 to determine that the DC is active directory */
1917 result = rpccli_lsa_QueryInfoPolicy2(cli, mem_ctx,
1919 LSA_POLICY_INFO_DNS,
1923 if (NT_STATUS_IS_OK(result)) {
1924 domain->active_directory = True;
1926 if (lsa_info->dns.name.string) {
1927 fstrcpy(domain->name, lsa_info->dns.name.string);
1930 if (lsa_info->dns.dns_domain.string) {
1931 fstrcpy(domain->alt_name,
1932 lsa_info->dns.dns_domain.string);
1935 /* See if we can set some domain trust flags about
1938 if (lsa_info->dns.dns_forest.string) {
1939 fstrcpy(domain->forest_name,
1940 lsa_info->dns.dns_forest.string);
1942 if (strequal(domain->forest_name, domain->alt_name)) {
1943 domain->domain_flags |= NETR_TRUST_FLAG_TREEROOT;
1947 if (lsa_info->dns.sid) {
1948 sid_copy(&domain->sid, lsa_info->dns.sid);
1951 domain->active_directory = False;
1953 result = rpccli_lsa_open_policy(cli, mem_ctx, True,
1954 SEC_FLAG_MAXIMUM_ALLOWED,
1957 if (!NT_STATUS_IS_OK(result)) {
1961 result = rpccli_lsa_QueryInfoPolicy(cli, mem_ctx,
1963 LSA_POLICY_INFO_ACCOUNT_DOMAIN,
1966 if (NT_STATUS_IS_OK(result)) {
1968 if (lsa_info->account_domain.name.string) {
1969 fstrcpy(domain->name,
1970 lsa_info->account_domain.name.string);
1973 if (lsa_info->account_domain.sid) {
1974 sid_copy(&domain->sid, lsa_info->account_domain.sid);
1980 DEBUG(5, ("set_dc_type_and_flags_connect: domain %s is %sin native mode.\n",
1981 domain->name, domain->native_mode ? "" : "NOT "));
1983 DEBUG(5,("set_dc_type_and_flags_connect: domain %s is %srunning active directory.\n",
1984 domain->name, domain->active_directory ? "" : "NOT "));
1986 domain->can_do_ncacn_ip_tcp = domain->active_directory;
1990 TALLOC_FREE(mem_ctx);
1992 domain->initialized = True;
1995 /**********************************************************************
1996 Set the domain_flags (trust attributes, domain operating modes, etc...
1997 ***********************************************************************/
1999 static void set_dc_type_and_flags( struct winbindd_domain *domain )
2001 /* we always have to contact our primary domain */
2003 if ( domain->primary ) {
2004 DEBUG(10,("set_dc_type_and_flags: setting up flags for "
2005 "primary domain\n"));
2006 set_dc_type_and_flags_connect( domain );
2010 /* Use our DC to get the information if possible */
2012 if ( !set_dc_type_and_flags_trustinfo( domain ) ) {
2013 /* Otherwise, fallback to contacting the
2015 set_dc_type_and_flags_connect( domain );
2023 /**********************************************************************
2024 ***********************************************************************/
2026 static NTSTATUS cm_get_schannel_creds(struct winbindd_domain *domain,
2027 struct netlogon_creds_CredentialState **ppdc)
2029 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2030 struct rpc_pipe_client *netlogon_pipe;
2032 if (lp_client_schannel() == False) {
2033 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2036 result = cm_connect_netlogon(domain, &netlogon_pipe);
2037 if (!NT_STATUS_IS_OK(result)) {
2041 /* Return a pointer to the struct netlogon_creds_CredentialState from the
2044 if (!domain->conn.netlogon_pipe->dc) {
2045 return NT_STATUS_INTERNAL_ERROR; /* This shouldn't happen. */
2048 *ppdc = domain->conn.netlogon_pipe->dc;
2049 return NT_STATUS_OK;
2052 NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
2053 struct rpc_pipe_client **cli, struct policy_handle *sam_handle)
2055 struct winbindd_cm_conn *conn;
2056 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2057 struct netlogon_creds_CredentialState *p_creds;
2058 char *machine_password = NULL;
2059 char *machine_account = NULL;
2060 char *domain_name = NULL;
2062 if (sid_check_is_domain(&domain->sid)) {
2063 return open_internal_samr_conn(mem_ctx, domain, cli, sam_handle);
2066 result = init_dc_connection_rpc(domain);
2067 if (!NT_STATUS_IS_OK(result)) {
2071 conn = &domain->conn;
2073 if (rpccli_is_connected(conn->samr_pipe)) {
2077 TALLOC_FREE(conn->samr_pipe);
2080 * No SAMR pipe yet. Attempt to get an NTLMSSP SPNEGO authenticated
2081 * sign and sealed pipe using the machine account password by
2082 * preference. If we can't - try schannel, if that fails, try
2086 if ((conn->cli->user_name[0] == '\0') ||
2087 (conn->cli->domain[0] == '\0') ||
2088 (conn->cli->password == NULL || conn->cli->password[0] == '\0'))
2090 result = get_trust_creds(domain, &machine_password,
2091 &machine_account, NULL);
2092 if (!NT_STATUS_IS_OK(result)) {
2093 DEBUG(10, ("cm_connect_sam: No no user available for "
2094 "domain %s, trying schannel\n", conn->cli->domain));
2097 domain_name = domain->name;
2099 machine_password = SMB_STRDUP(conn->cli->password);
2100 machine_account = SMB_STRDUP(conn->cli->user_name);
2101 domain_name = conn->cli->domain;
2104 if (!machine_password || !machine_account) {
2105 result = NT_STATUS_NO_MEMORY;
2109 /* We have an authenticated connection. Use a NTLMSSP SPNEGO
2110 authenticated SAMR pipe with sign & seal. */
2111 result = cli_rpc_pipe_open_spnego_ntlmssp(conn->cli,
2112 &ndr_table_samr.syntax_id,
2114 DCERPC_AUTH_LEVEL_PRIVACY,
2120 if (!NT_STATUS_IS_OK(result)) {
2121 DEBUG(10,("cm_connect_sam: failed to connect to SAMR "
2122 "pipe for domain %s using NTLMSSP "
2123 "authenticated pipe: user %s\\%s. Error was "
2124 "%s\n", domain->name, domain_name,
2125 machine_account, nt_errstr(result)));
2129 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for "
2130 "domain %s using NTLMSSP authenticated "
2131 "pipe: user %s\\%s\n", domain->name,
2132 domain_name, machine_account));
2134 result = rpccli_samr_Connect2(conn->samr_pipe, mem_ctx,
2135 conn->samr_pipe->desthost,
2136 SEC_FLAG_MAXIMUM_ALLOWED,
2137 &conn->sam_connect_handle);
2138 if (NT_STATUS_IS_OK(result)) {
2141 DEBUG(10,("cm_connect_sam: ntlmssp-sealed rpccli_samr_Connect2 "
2142 "failed for domain %s, error was %s. Trying schannel\n",
2143 domain->name, nt_errstr(result) ));
2144 TALLOC_FREE(conn->samr_pipe);
2148 /* Fall back to schannel if it's a W2K pre-SP1 box. */
2150 result = cm_get_schannel_creds(domain, &p_creds);
2151 if (!NT_STATUS_IS_OK(result)) {
2152 /* If this call fails - conn->cli can now be NULL ! */
2153 DEBUG(10, ("cm_connect_sam: Could not get schannel auth info "
2154 "for domain %s (error %s), trying anon\n",
2156 nt_errstr(result) ));
2159 result = cli_rpc_pipe_open_schannel_with_key
2160 (conn->cli, &ndr_table_samr.syntax_id, NCACN_NP,
2161 DCERPC_AUTH_LEVEL_PRIVACY,
2162 domain->name, &p_creds, &conn->samr_pipe);
2164 if (!NT_STATUS_IS_OK(result)) {
2165 DEBUG(10,("cm_connect_sam: failed to connect to SAMR pipe for "
2166 "domain %s using schannel. Error was %s\n",
2167 domain->name, nt_errstr(result) ));
2170 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for domain %s using "
2171 "schannel.\n", domain->name ));
2173 result = rpccli_samr_Connect2(conn->samr_pipe, mem_ctx,
2174 conn->samr_pipe->desthost,
2175 SEC_FLAG_MAXIMUM_ALLOWED,
2176 &conn->sam_connect_handle);
2177 if (NT_STATUS_IS_OK(result)) {
2180 DEBUG(10,("cm_connect_sam: schannel-sealed rpccli_samr_Connect2 failed "
2181 "for domain %s, error was %s. Trying anonymous\n",
2182 domain->name, nt_errstr(result) ));
2183 TALLOC_FREE(conn->samr_pipe);
2187 /* Finally fall back to anonymous. */
2188 result = cli_rpc_pipe_open_noauth(conn->cli, &ndr_table_samr.syntax_id,
2191 if (!NT_STATUS_IS_OK(result)) {
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)) {
2200 DEBUG(10,("cm_connect_sam: rpccli_samr_Connect2 failed "
2201 "for domain %s Error was %s\n",
2202 domain->name, nt_errstr(result) ));
2207 result = rpccli_samr_OpenDomain(conn->samr_pipe,
2209 &conn->sam_connect_handle,
2210 SEC_FLAG_MAXIMUM_ALLOWED,
2212 &conn->sam_domain_handle);
2216 if (NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED)) {
2218 * if we got access denied, we might just have no access rights
2219 * to talk to the remote samr server server (e.g. when we are a
2220 * PDC and we are connecting a w2k8 pdc via an interdomain
2221 * trust). In that case do not invalidate the whole connection
2224 TALLOC_FREE(conn->samr_pipe);
2225 ZERO_STRUCT(conn->sam_domain_handle);
2227 } else if (!NT_STATUS_IS_OK(result)) {
2228 invalidate_cm_connection(conn);
2232 *cli = conn->samr_pipe;
2233 *sam_handle = conn->sam_domain_handle;
2234 SAFE_FREE(machine_password);
2235 SAFE_FREE(machine_account);
2239 /**********************************************************************
2240 open an schanneld ncacn_ip_tcp connection to LSA
2241 ***********************************************************************/
2243 NTSTATUS cm_connect_lsa_tcp(struct winbindd_domain *domain,
2244 TALLOC_CTX *mem_ctx,
2245 struct rpc_pipe_client **cli)
2247 struct winbindd_cm_conn *conn;
2248 struct netlogon_creds_CredentialState *creds;
2251 DEBUG(10,("cm_connect_lsa_tcp\n"));
2253 status = init_dc_connection_rpc(domain);
2254 if (!NT_STATUS_IS_OK(status)) {
2258 conn = &domain->conn;
2260 if (conn->lsa_pipe_tcp &&
2261 conn->lsa_pipe_tcp->transport->transport == NCACN_IP_TCP &&
2262 conn->lsa_pipe_tcp->auth->auth_level == DCERPC_AUTH_LEVEL_PRIVACY &&
2263 rpccli_is_connected(conn->lsa_pipe_tcp)) {
2267 TALLOC_FREE(conn->lsa_pipe_tcp);
2269 status = cm_get_schannel_creds(domain, &creds);
2270 if (!NT_STATUS_IS_OK(status)) {
2274 status = cli_rpc_pipe_open_schannel_with_key(conn->cli,
2275 &ndr_table_lsarpc.syntax_id,
2277 DCERPC_AUTH_LEVEL_PRIVACY,
2280 &conn->lsa_pipe_tcp);
2281 if (!NT_STATUS_IS_OK(status)) {
2282 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key failed: %s\n",
2283 nt_errstr(status)));
2288 if (!NT_STATUS_IS_OK(status)) {
2289 TALLOC_FREE(conn->lsa_pipe_tcp);
2293 *cli = conn->lsa_pipe_tcp;
2298 NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
2299 struct rpc_pipe_client **cli, struct policy_handle *lsa_policy)
2301 struct winbindd_cm_conn *conn;
2302 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2303 struct netlogon_creds_CredentialState *p_creds;
2305 result = init_dc_connection_rpc(domain);
2306 if (!NT_STATUS_IS_OK(result))
2309 conn = &domain->conn;
2311 if (rpccli_is_connected(conn->lsa_pipe)) {
2315 TALLOC_FREE(conn->lsa_pipe);
2317 if ((conn->cli->user_name[0] == '\0') ||
2318 (conn->cli->domain[0] == '\0') ||
2319 (conn->cli->password == NULL || conn->cli->password[0] == '\0')) {
2320 DEBUG(10, ("cm_connect_lsa: No no user available for "
2321 "domain %s, trying schannel\n", conn->cli->domain));
2325 /* We have an authenticated connection. Use a NTLMSSP SPNEGO
2326 * authenticated LSA pipe with sign & seal. */
2327 result = cli_rpc_pipe_open_spnego_ntlmssp
2328 (conn->cli, &ndr_table_lsarpc.syntax_id, NCACN_NP,
2329 DCERPC_AUTH_LEVEL_PRIVACY,
2330 conn->cli->domain, conn->cli->user_name, conn->cli->password,
2333 if (!NT_STATUS_IS_OK(result)) {
2334 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
2335 "domain %s using NTLMSSP authenticated pipe: user "
2336 "%s\\%s. Error was %s. Trying schannel.\n",
2337 domain->name, conn->cli->domain,
2338 conn->cli->user_name, nt_errstr(result)));
2342 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
2343 "NTLMSSP authenticated pipe: user %s\\%s\n",
2344 domain->name, conn->cli->domain, conn->cli->user_name ));
2346 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2347 SEC_FLAG_MAXIMUM_ALLOWED,
2349 if (NT_STATUS_IS_OK(result)) {
2353 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
2356 TALLOC_FREE(conn->lsa_pipe);
2360 /* Fall back to schannel if it's a W2K pre-SP1 box. */
2362 result = cm_get_schannel_creds(domain, &p_creds);
2363 if (!NT_STATUS_IS_OK(result)) {
2364 /* If this call fails - conn->cli can now be NULL ! */
2365 DEBUG(10, ("cm_connect_lsa: Could not get schannel auth info "
2366 "for domain %s (error %s), trying anon\n",
2368 nt_errstr(result) ));
2371 result = cli_rpc_pipe_open_schannel_with_key
2372 (conn->cli, &ndr_table_lsarpc.syntax_id, NCACN_NP,
2373 DCERPC_AUTH_LEVEL_PRIVACY,
2374 domain->name, &p_creds, &conn->lsa_pipe);
2376 if (!NT_STATUS_IS_OK(result)) {
2377 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
2378 "domain %s using schannel. Error was %s\n",
2379 domain->name, nt_errstr(result) ));
2382 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
2383 "schannel.\n", domain->name ));
2385 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2386 SEC_FLAG_MAXIMUM_ALLOWED,
2388 if (NT_STATUS_IS_OK(result)) {
2392 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
2395 TALLOC_FREE(conn->lsa_pipe);
2399 result = cli_rpc_pipe_open_noauth(conn->cli,
2400 &ndr_table_lsarpc.syntax_id,
2402 if (!NT_STATUS_IS_OK(result)) {
2403 result = NT_STATUS_PIPE_NOT_AVAILABLE;
2407 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2408 SEC_FLAG_MAXIMUM_ALLOWED,
2411 if (!NT_STATUS_IS_OK(result)) {
2412 invalidate_cm_connection(conn);
2416 *cli = conn->lsa_pipe;
2417 *lsa_policy = conn->lsa_policy;
2421 /****************************************************************************
2422 Open the netlogon pipe to this DC. Use schannel if specified in client conf.
2423 session key stored in conn->netlogon_pipe->dc->sess_key.
2424 ****************************************************************************/
2426 NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
2427 struct rpc_pipe_client **cli)
2429 struct winbindd_cm_conn *conn;
2432 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
2434 enum netr_SchannelType sec_chan_type;
2435 const char *account_name;
2436 struct rpc_pipe_client *netlogon_pipe = NULL;
2440 result = init_dc_connection_rpc(domain);
2441 if (!NT_STATUS_IS_OK(result)) {
2445 conn = &domain->conn;
2447 if (rpccli_is_connected(conn->netlogon_pipe)) {
2448 *cli = conn->netlogon_pipe;
2449 return NT_STATUS_OK;
2452 TALLOC_FREE(conn->netlogon_pipe);
2454 result = cli_rpc_pipe_open_noauth(conn->cli,
2455 &ndr_table_netlogon.syntax_id,
2457 if (!NT_STATUS_IS_OK(result)) {
2461 if ((!IS_DC) && (!domain->primary)) {
2462 /* Clear the schannel request bit and drop down */
2463 neg_flags &= ~NETLOGON_NEG_SCHANNEL;
2467 if (lp_client_schannel() != False) {
2468 neg_flags |= NETLOGON_NEG_SCHANNEL;
2471 if (!get_trust_pw_hash(domain->name, mach_pwd, &account_name,
2474 TALLOC_FREE(netlogon_pipe);
2475 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2478 result = rpccli_netlogon_setup_creds(
2480 domain->dcname, /* server name. */
2481 domain->name, /* domain name */
2482 global_myname(), /* client name */
2483 account_name, /* machine account */
2484 mach_pwd, /* machine password */
2485 sec_chan_type, /* from get_trust_pw */
2488 if (!NT_STATUS_IS_OK(result)) {
2489 TALLOC_FREE(netlogon_pipe);
2493 if ((lp_client_schannel() == True) &&
2494 ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
2495 DEBUG(3, ("Server did not offer schannel\n"));
2496 TALLOC_FREE(netlogon_pipe);
2497 return NT_STATUS_ACCESS_DENIED;
2501 if ((lp_client_schannel() == False) ||
2502 ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
2504 * NetSamLogonEx only works for schannel
2506 domain->can_do_samlogon_ex = False;
2508 /* We're done - just keep the existing connection to NETLOGON
2510 conn->netlogon_pipe = netlogon_pipe;
2511 *cli = conn->netlogon_pipe;
2512 return NT_STATUS_OK;
2515 /* Using the credentials from the first pipe, open a signed and sealed
2516 second netlogon pipe. The session key is stored in the schannel
2517 part of the new pipe auth struct.
2520 result = cli_rpc_pipe_open_schannel_with_key(
2521 conn->cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
2522 DCERPC_AUTH_LEVEL_PRIVACY, domain->name, &netlogon_pipe->dc,
2523 &conn->netlogon_pipe);
2525 /* We can now close the initial netlogon pipe. */
2526 TALLOC_FREE(netlogon_pipe);
2528 if (!NT_STATUS_IS_OK(result)) {
2529 DEBUG(3, ("Could not open schannel'ed NETLOGON pipe. Error "
2530 "was %s\n", nt_errstr(result)));
2532 invalidate_cm_connection(conn);
2537 * Always try netr_LogonSamLogonEx. We will fall back for NT4
2538 * which gives DCERPC_FAULT_OP_RNG_ERROR (function not
2539 * supported). We used to only try SamLogonEx for AD, but
2540 * Samba DCs can also do it. And because we don't distinguish
2541 * between Samba and NT4, always try it once.
2543 domain->can_do_samlogon_ex = true;
2545 *cli = conn->netlogon_pipe;
2546 return NT_STATUS_OK;
2549 void winbind_msg_ip_dropped(struct messaging_context *msg_ctx,
2552 struct server_id server_id,
2555 struct winbindd_domain *domain;
2558 || (data->data == NULL)
2559 || (data->length == 0)
2560 || (data->data[data->length-1] != '\0')
2561 || !is_ipaddress((char *)data->data)) {
2562 DEBUG(1, ("invalid msg_ip_dropped message\n"));
2565 for (domain = domain_list(); domain != NULL; domain = domain->next) {
2566 char sockaddr[INET6_ADDRSTRLEN];
2567 if (domain->conn.cli == NULL) {
2570 if (domain->conn.cli->fd == -1) {
2573 client_socket_addr(domain->conn.cli->fd, sockaddr,
2575 if (strequal(sockaddr, (char *)data->data)) {
2576 close(domain->conn.cli->fd);
2577 domain->conn.cli->fd = -1;