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
65 #define DBGC_CLASS DBGC_WINBIND
69 struct sockaddr_storage ss;
72 extern struct winbindd_methods reconnect_methods;
73 extern bool override_logfile;
75 static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain);
76 static void set_dc_type_and_flags( struct winbindd_domain *domain );
77 static bool get_dcs(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
78 struct dc_name_ip **dcs, int *num_dcs);
80 /****************************************************************
81 Child failed to find DC's. Reschedule check.
82 ****************************************************************/
84 static void msg_failed_to_go_online(struct messaging_context *msg,
87 struct server_id server_id,
90 struct winbindd_domain *domain;
91 const char *domainname = (const char *)data->data;
93 if (data->data == NULL || data->length == 0) {
97 DEBUG(5,("msg_fail_to_go_online: received for domain %s.\n", domainname));
99 for (domain = domain_list(); domain; domain = domain->next) {
100 if (domain->internal) {
104 if (strequal(domain->name, domainname)) {
105 if (domain->online) {
106 /* We're already online, ignore. */
107 DEBUG(5,("msg_fail_to_go_online: domain %s "
108 "already online.\n", domainname));
112 /* Reschedule the online check. */
113 set_domain_offline(domain);
119 /****************************************************************
120 Actually cause a reconnect from a message.
121 ****************************************************************/
123 static void msg_try_to_go_online(struct messaging_context *msg,
126 struct server_id server_id,
129 struct winbindd_domain *domain;
130 const char *domainname = (const char *)data->data;
132 if (data->data == NULL || data->length == 0) {
136 DEBUG(5,("msg_try_to_go_online: received for domain %s.\n", domainname));
138 for (domain = domain_list(); domain; domain = domain->next) {
139 if (domain->internal) {
143 if (strequal(domain->name, domainname)) {
145 if (domain->online) {
146 /* We're already online, ignore. */
147 DEBUG(5,("msg_try_to_go_online: domain %s "
148 "already online.\n", domainname));
152 /* This call takes care of setting the online
153 flag to true if we connected, or re-adding
154 the offline handler if false. Bypasses online
155 check so always does network calls. */
157 init_dc_connection_network(domain);
163 /****************************************************************
164 Fork a child to try and contact a DC. Do this as contacting a
165 DC requires blocking lookups and we don't want to block our
167 ****************************************************************/
169 static bool fork_child_dc_connect(struct winbindd_domain *domain)
171 struct dc_name_ip *dcs = NULL;
173 TALLOC_CTX *mem_ctx = NULL;
174 pid_t parent_pid = sys_getpid();
179 if (domain->dc_probe_pid != (pid_t)-1) {
181 * We might already have a DC probe
182 * child working, check.
184 if (process_exists_by_pid(domain->dc_probe_pid)) {
185 DEBUG(10,("fork_child_dc_connect: pid %u already "
186 "checking for DC's.\n",
187 (unsigned int)domain->dc_probe_pid));
190 domain->dc_probe_pid = (pid_t)-1;
193 domain->dc_probe_pid = sys_fork();
195 if (domain->dc_probe_pid == (pid_t)-1) {
196 DEBUG(0, ("fork_child_dc_connect: Could not fork: %s\n", strerror(errno)));
200 if (domain->dc_probe_pid != (pid_t)0) {
202 messaging_register(winbind_messaging_context(), NULL,
203 MSG_WINBIND_TRY_TO_GO_ONLINE,
204 msg_try_to_go_online);
205 messaging_register(winbind_messaging_context(), NULL,
206 MSG_WINBIND_FAILED_TO_GO_ONLINE,
207 msg_failed_to_go_online);
213 /* Leave messages blocked - we will never process one. */
215 if (!reinit_after_fork(winbind_messaging_context(),
216 winbind_event_context(), true)) {
217 DEBUG(0,("reinit_after_fork() failed\n"));
218 messaging_send_buf(winbind_messaging_context(),
219 pid_to_procid(parent_pid),
220 MSG_WINBIND_FAILED_TO_GO_ONLINE,
221 (uint8 *)domain->name,
222 strlen(domain->name)+1);
226 close_conns_after_fork();
228 if (!override_logfile) {
230 if (asprintf(&lfile, "%s/log.winbindd-dc-connect", get_dyn_LOGFILEBASE()) > 0) {
231 lp_set_logfile(lfile);
237 mem_ctx = talloc_init("fork_child_dc_connect");
239 DEBUG(0,("talloc_init failed.\n"));
240 messaging_send_buf(winbind_messaging_context(),
241 pid_to_procid(parent_pid),
242 MSG_WINBIND_FAILED_TO_GO_ONLINE,
243 (uint8 *)domain->name,
244 strlen(domain->name)+1);
248 if ((!get_dcs(mem_ctx, domain, &dcs, &num_dcs)) || (num_dcs == 0)) {
249 /* Still offline ? Can't find DC's. */
250 messaging_send_buf(winbind_messaging_context(),
251 pid_to_procid(parent_pid),
252 MSG_WINBIND_FAILED_TO_GO_ONLINE,
253 (uint8 *)domain->name,
254 strlen(domain->name)+1);
258 /* We got a DC. Send a message to our parent to get it to
259 try and do the same. */
261 messaging_send_buf(winbind_messaging_context(),
262 pid_to_procid(parent_pid),
263 MSG_WINBIND_TRY_TO_GO_ONLINE,
264 (uint8 *)domain->name,
265 strlen(domain->name)+1);
269 /****************************************************************
270 Handler triggered if we're offline to try and detect a DC.
271 ****************************************************************/
273 static void check_domain_online_handler(struct event_context *ctx,
274 struct timed_event *te,
278 struct winbindd_domain *domain =
279 (struct winbindd_domain *)private_data;
281 DEBUG(10,("check_domain_online_handler: called for domain "
282 "%s (online = %s)\n", domain->name,
283 domain->online ? "True" : "False" ));
285 TALLOC_FREE(domain->check_online_event);
287 /* Are we still in "startup" mode ? */
289 if (domain->startup && (now.tv_sec > domain->startup_time + 30)) {
290 /* No longer in "startup" mode. */
291 DEBUG(10,("check_domain_online_handler: domain %s no longer in 'startup' mode.\n",
293 domain->startup = False;
296 /* We've been told to stay offline, so stay
299 if (get_global_winbindd_state_offline()) {
300 DEBUG(10,("check_domain_online_handler: domain %s remaining globally offline\n",
305 /* Fork a child to test if it can contact a DC.
306 If it can then send ourselves a message to
307 cause a reconnect. */
309 fork_child_dc_connect(domain);
312 /****************************************************************
313 If we're still offline setup the timeout check.
314 ****************************************************************/
316 static void calc_new_online_timeout_check(struct winbindd_domain *domain)
318 int wbr = lp_winbind_reconnect_delay();
320 if (domain->startup) {
321 domain->check_online_timeout = 10;
322 } else if (domain->check_online_timeout < wbr) {
323 domain->check_online_timeout = wbr;
327 /****************************************************************
328 Set domain offline and also add handler to put us back online
330 ****************************************************************/
332 void set_domain_offline(struct winbindd_domain *domain)
334 DEBUG(10,("set_domain_offline: called for domain %s\n",
337 TALLOC_FREE(domain->check_online_event);
339 if (domain->internal) {
340 DEBUG(3,("set_domain_offline: domain %s is internal - logic error.\n",
345 domain->online = False;
347 /* Offline domains are always initialized. They're
348 re-initialized when they go back online. */
350 domain->initialized = True;
352 /* We only add the timeout handler that checks and
353 allows us to go back online when we've not
354 been told to remain offline. */
356 if (get_global_winbindd_state_offline()) {
357 DEBUG(10,("set_domain_offline: domain %s remaining globally offline\n",
362 /* If we're in statup mode, check again in 10 seconds, not in
363 lp_winbind_reconnect_delay() seconds (which is 30 seconds by default). */
365 calc_new_online_timeout_check(domain);
367 domain->check_online_event = event_add_timed(winbind_event_context(),
369 timeval_current_ofs(domain->check_online_timeout,0),
370 check_domain_online_handler,
373 /* The above *has* to succeed for winbindd to work. */
374 if (!domain->check_online_event) {
375 smb_panic("set_domain_offline: failed to add online handler");
378 DEBUG(10,("set_domain_offline: added event handler for domain %s\n",
381 /* Send an offline message to the idmap child when our
382 primary domain goes offline */
384 if ( domain->primary ) {
385 struct winbindd_child *idmap = idmap_child();
387 if ( idmap->pid != 0 ) {
388 messaging_send_buf(winbind_messaging_context(),
389 pid_to_procid(idmap->pid),
391 (uint8 *)domain->name,
392 strlen(domain->name)+1);
399 /****************************************************************
400 Set domain online - if allowed.
401 ****************************************************************/
403 static void set_domain_online(struct winbindd_domain *domain)
405 DEBUG(10,("set_domain_online: called for domain %s\n",
408 if (domain->internal) {
409 DEBUG(3,("set_domain_online: domain %s is internal - logic error.\n",
414 if (get_global_winbindd_state_offline()) {
415 DEBUG(10,("set_domain_online: domain %s remaining globally offline\n",
420 winbindd_set_locator_kdc_envs(domain);
422 /* If we are waiting to get a krb5 ticket, trigger immediately. */
423 ccache_regain_all_now();
425 /* Ok, we're out of any startup mode now... */
426 domain->startup = False;
428 if (domain->online == False) {
429 /* We were offline - now we're online. We default to
430 using the MS-RPC backend if we started offline,
431 and if we're going online for the first time we
432 should really re-initialize the backends and the
433 checks to see if we're talking to an AD or NT domain.
436 domain->initialized = False;
438 /* 'reconnect_methods' is the MS-RPC backend. */
439 if (domain->backend == &reconnect_methods) {
440 domain->backend = NULL;
444 /* Ensure we have no online timeout checks. */
445 domain->check_online_timeout = 0;
446 TALLOC_FREE(domain->check_online_event);
448 /* Ensure we ignore any pending child messages. */
449 messaging_deregister(winbind_messaging_context(),
450 MSG_WINBIND_TRY_TO_GO_ONLINE, NULL);
451 messaging_deregister(winbind_messaging_context(),
452 MSG_WINBIND_FAILED_TO_GO_ONLINE, NULL);
454 domain->online = True;
456 /* Send an online message to the idmap child when our
457 primary domain comes online */
459 if ( domain->primary ) {
460 struct winbindd_child *idmap = idmap_child();
462 if ( idmap->pid != 0 ) {
463 messaging_send_buf(winbind_messaging_context(),
464 pid_to_procid(idmap->pid),
466 (uint8 *)domain->name,
467 strlen(domain->name)+1);
474 /****************************************************************
475 Requested to set a domain online.
476 ****************************************************************/
478 void set_domain_online_request(struct winbindd_domain *domain)
482 DEBUG(10,("set_domain_online_request: called for domain %s\n",
485 if (get_global_winbindd_state_offline()) {
486 DEBUG(10,("set_domain_online_request: domain %s remaining globally offline\n",
491 /* We've been told it's safe to go online and
492 try and connect to a DC. But I don't believe it
493 because network manager seems to lie.
494 Wait at least 5 seconds. Heuristics suck... */
499 /* Go into "startup" mode again. */
500 domain->startup_time = tev.tv_sec;
501 domain->startup = True;
505 if (!domain->check_online_event) {
506 /* If we've come from being globally offline we
507 don't have a check online event handler set.
508 We need to add one now we're trying to go
511 DEBUG(10,("set_domain_online_request: domain %s was globally offline.\n",
515 TALLOC_FREE(domain->check_online_event);
517 domain->check_online_event = event_add_timed(winbind_event_context(),
520 check_domain_online_handler,
523 /* The above *has* to succeed for winbindd to work. */
524 if (!domain->check_online_event) {
525 smb_panic("set_domain_online_request: failed to add online handler");
529 /****************************************************************
530 Add -ve connection cache entries for domain and realm.
531 ****************************************************************/
533 void winbind_add_failed_connection_entry(const struct winbindd_domain *domain,
537 add_failed_connection_entry(domain->name, server, result);
538 /* If this was the saf name for the last thing we talked to,
540 saf_delete(domain->name);
541 if (*domain->alt_name) {
542 add_failed_connection_entry(domain->alt_name, server, result);
543 saf_delete(domain->alt_name);
545 winbindd_unset_locator_kdc_env(domain);
548 /* Choose between anonymous or authenticated connections. We need to use
549 an authenticated connection if DCs have the RestrictAnonymous registry
550 entry set > 0, or the "Additional restrictions for anonymous
551 connections" set in the win2k Local Security Policy.
553 Caller to free() result in domain, username, password
556 static void cm_get_ipc_userpass(char **username, char **domain, char **password)
558 *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
559 *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
560 *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
562 if (*username && **username) {
564 if (!*domain || !**domain)
565 *domain = smb_xstrdup(lp_workgroup());
567 if (!*password || !**password)
568 *password = smb_xstrdup("");
570 DEBUG(3, ("cm_get_ipc_userpass: Retrieved auth-user from secrets.tdb [%s\\%s]\n",
571 *domain, *username));
574 DEBUG(3, ("cm_get_ipc_userpass: No auth-user defined\n"));
575 *username = smb_xstrdup("");
576 *domain = smb_xstrdup("");
577 *password = smb_xstrdup("");
581 static bool get_dc_name_via_netlogon(struct winbindd_domain *domain,
583 struct sockaddr_storage *dc_ss)
585 struct winbindd_domain *our_domain = NULL;
586 struct rpc_pipe_client *netlogon_pipe = NULL;
590 unsigned int orig_timeout;
591 const char *tmp = NULL;
594 /* Hmmmm. We can only open one connection to the NETLOGON pipe at the
601 if (domain->primary) {
605 our_domain = find_our_domain();
607 if ((mem_ctx = talloc_init("get_dc_name_via_netlogon")) == NULL) {
611 result = cm_connect_netlogon(our_domain, &netlogon_pipe);
612 if (!NT_STATUS_IS_OK(result)) {
613 talloc_destroy(mem_ctx);
617 /* This call can take a long time - allow the server to time out.
618 35 seconds should do it. */
620 orig_timeout = rpccli_set_timeout(netlogon_pipe, 35000);
622 if (our_domain->active_directory) {
623 struct netr_DsRGetDCNameInfo *domain_info = NULL;
625 result = rpccli_netr_DsRGetDCName(netlogon_pipe,
634 if (W_ERROR_IS_OK(werr)) {
636 mem_ctx, domain_info->dc_unc);
638 DEBUG(0, ("talloc_strdup failed\n"));
639 talloc_destroy(mem_ctx);
642 if (strlen(domain->alt_name) == 0) {
643 fstrcpy(domain->alt_name,
644 domain_info->domain_name);
646 if (strlen(domain->forest_name) == 0) {
647 fstrcpy(domain->forest_name,
648 domain_info->forest_name);
652 result = rpccli_netr_GetAnyDCName(netlogon_pipe, mem_ctx,
659 /* And restore our original timeout. */
660 rpccli_set_timeout(netlogon_pipe, orig_timeout);
662 if (!NT_STATUS_IS_OK(result)) {
663 DEBUG(10,("rpccli_netr_GetAnyDCName failed: %s\n",
665 talloc_destroy(mem_ctx);
669 if (!W_ERROR_IS_OK(werr)) {
670 DEBUG(10,("rpccli_netr_GetAnyDCName failed: %s\n",
672 talloc_destroy(mem_ctx);
676 /* rpccli_netr_GetAnyDCName gives us a name with \\ */
677 p = strip_hostname(tmp);
681 talloc_destroy(mem_ctx);
683 DEBUG(10,("rpccli_netr_GetAnyDCName returned %s\n", dcname));
685 if (!resolve_name(dcname, dc_ss, 0x20)) {
693 * Helper function to assemble trust password and account name
695 static NTSTATUS get_trust_creds(const struct winbindd_domain *domain,
696 char **machine_password,
697 char **machine_account,
698 char **machine_krb5_principal)
700 const char *account_name;
701 const char *name = NULL;
703 /* If we are a DC and this is not our own domain */
708 struct winbindd_domain *our_domain = find_our_domain();
711 return NT_STATUS_INVALID_SERVER_STATE;
713 name = our_domain->name;
716 if (!get_trust_pw_clear(name, machine_password,
717 &account_name, NULL))
719 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
722 if ((machine_account != NULL) &&
723 (asprintf(machine_account, "%s$", account_name) == -1))
725 return NT_STATUS_NO_MEMORY;
728 /* For now assume our machine account only exists in our domain */
730 if (machine_krb5_principal != NULL)
732 struct winbindd_domain *our_domain = find_our_domain();
735 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
738 if (asprintf(machine_krb5_principal, "%s$@%s",
739 account_name, our_domain->alt_name) == -1)
741 return NT_STATUS_NO_MEMORY;
744 strupper_m(*machine_krb5_principal);
750 /************************************************************************
751 Given a fd with a just-connected TCP connection to a DC, open a connection
753 ************************************************************************/
755 static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
757 const char *controller,
758 struct cli_state **cli,
761 char *machine_password = NULL;
762 char *machine_krb5_principal = NULL;
763 char *machine_account = NULL;
764 char *ipc_username = NULL;
765 char *ipc_domain = NULL;
766 char *ipc_password = NULL;
768 struct named_mutex *mutex;
770 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
772 struct sockaddr peeraddr;
773 socklen_t peeraddr_len;
775 struct sockaddr_in *peeraddr_in = (struct sockaddr_in *)&peeraddr;
777 DEBUG(10,("cm_prepare_connection: connecting to DC %s for domain %s\n",
778 controller, domain->name ));
782 mutex = grab_named_mutex(talloc_tos(), controller,
783 WINBIND_SERVER_MUTEX_WAIT_TIME);
785 DEBUG(0,("cm_prepare_connection: mutex grab failed for %s\n",
787 result = NT_STATUS_POSSIBLE_DEADLOCK;
791 if ((*cli = cli_initialise()) == NULL) {
792 DEBUG(1, ("Could not cli_initialize\n"));
793 result = NT_STATUS_NO_MEMORY;
797 (*cli)->timeout = 10000; /* 10 seconds */
799 fstrcpy((*cli)->desthost, controller);
800 (*cli)->use_kerberos = True;
802 peeraddr_len = sizeof(peeraddr);
804 if ((getpeername((*cli)->fd, &peeraddr, &peeraddr_len) != 0) ||
805 (peeraddr_len != sizeof(struct sockaddr_in)) ||
806 (peeraddr_in->sin_family != PF_INET))
808 DEBUG(0,("cm_prepare_connection: %s\n", strerror(errno)));
809 result = NT_STATUS_UNSUCCESSFUL;
813 if (ntohs(peeraddr_in->sin_port) == 139) {
814 struct nmb_name calling;
815 struct nmb_name called;
817 make_nmb_name(&calling, global_myname(), 0x0);
818 make_nmb_name(&called, "*SMBSERVER", 0x20);
820 if (!cli_session_request(*cli, &calling, &called)) {
821 DEBUG(8, ("cli_session_request failed for %s\n",
823 result = NT_STATUS_UNSUCCESSFUL;
828 cli_setup_signing_state(*cli, Undefined);
830 result = cli_negprot(*cli);
832 if (!NT_STATUS_IS_OK(result)) {
833 DEBUG(1, ("cli_negprot failed: %s\n", nt_errstr(result)));
837 if (!is_dc_trusted_domain_situation(domain->name) &&
838 (*cli)->protocol >= PROTOCOL_NT1 &&
839 (*cli)->capabilities & CAP_EXTENDED_SECURITY)
841 ADS_STATUS ads_status;
843 result = get_trust_creds(domain, &machine_password,
845 &machine_krb5_principal);
846 if (!NT_STATUS_IS_OK(result)) {
850 if (lp_security() == SEC_ADS) {
852 /* Try a krb5 session */
854 (*cli)->use_kerberos = True;
855 DEBUG(5, ("connecting to %s from %s with kerberos principal "
856 "[%s] and realm [%s]\n", controller, global_myname(),
857 machine_krb5_principal, domain->alt_name));
859 winbindd_set_locator_kdc_envs(domain);
861 ads_status = cli_session_setup_spnego(*cli,
862 machine_krb5_principal,
867 if (!ADS_ERR_OK(ads_status)) {
868 DEBUG(4,("failed kerberos session setup with %s\n",
869 ads_errstr(ads_status)));
872 result = ads_ntstatus(ads_status);
873 if (NT_STATUS_IS_OK(result)) {
874 /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
875 cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
876 goto session_setup_done;
880 /* Fall back to non-kerberos session setup using NTLMSSP SPNEGO with the machine account. */
881 (*cli)->use_kerberos = False;
883 DEBUG(5, ("connecting to %s from %s with username "
884 "[%s]\\[%s]\n", controller, global_myname(),
885 lp_workgroup(), machine_account));
887 ads_status = cli_session_setup_spnego(*cli,
892 if (!ADS_ERR_OK(ads_status)) {
893 DEBUG(4, ("authenticated session setup failed with %s\n",
894 ads_errstr(ads_status)));
897 result = ads_ntstatus(ads_status);
898 if (NT_STATUS_IS_OK(result)) {
899 /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
900 cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
901 goto session_setup_done;
905 /* Fall back to non-kerberos session setup with auth_user */
907 (*cli)->use_kerberos = False;
909 cm_get_ipc_userpass(&ipc_username, &ipc_domain, &ipc_password);
911 if ((((*cli)->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) != 0) &&
912 (strlen(ipc_username) > 0)) {
914 /* Only try authenticated if we have a username */
916 DEBUG(5, ("connecting to %s from %s with username "
917 "[%s]\\[%s]\n", controller, global_myname(),
918 ipc_domain, ipc_username));
920 if (NT_STATUS_IS_OK(cli_session_setup(
922 ipc_password, strlen(ipc_password)+1,
923 ipc_password, strlen(ipc_password)+1,
925 /* Successful logon with given username. */
926 cli_init_creds(*cli, ipc_username, ipc_domain, ipc_password);
927 goto session_setup_done;
929 DEBUG(4, ("authenticated session setup with user %s\\%s failed.\n",
930 ipc_domain, ipc_username ));
936 /* Fall back to anonymous connection, this might fail later */
937 DEBUG(10,("cm_prepare_connection: falling back to anonymous "
938 "connection for DC %s\n",
941 if (NT_STATUS_IS_OK(cli_session_setup(*cli, "", NULL, 0,
943 DEBUG(5, ("Connected anonymously\n"));
944 cli_init_creds(*cli, "", "", "");
945 goto session_setup_done;
948 result = cli_nt_error(*cli);
950 if (NT_STATUS_IS_OK(result))
951 result = NT_STATUS_UNSUCCESSFUL;
953 /* We can't session setup */
959 /* cache the server name for later connections */
961 saf_store( domain->name, (*cli)->desthost );
962 if (domain->alt_name && (*cli)->use_kerberos) {
963 saf_store( domain->alt_name, (*cli)->desthost );
966 winbindd_set_locator_kdc_envs(domain);
968 if (!cli_send_tconX(*cli, "IPC$", "IPC", "", 0)) {
970 result = cli_nt_error(*cli);
972 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(result)));
974 if (NT_STATUS_IS_OK(result))
975 result = NT_STATUS_UNSUCCESSFUL;
983 /* set the domain if empty; needed for schannel connections */
984 if ( !*(*cli)->domain ) {
985 fstrcpy( (*cli)->domain, domain->name );
988 result = NT_STATUS_OK;
992 SAFE_FREE(machine_account);
993 SAFE_FREE(machine_password);
994 SAFE_FREE(machine_krb5_principal);
995 SAFE_FREE(ipc_username);
996 SAFE_FREE(ipc_domain);
997 SAFE_FREE(ipc_password);
999 if (!NT_STATUS_IS_OK(result)) {
1000 winbind_add_failed_connection_entry(domain, controller, result);
1001 if ((*cli) != NULL) {
1010 /*******************************************************************
1011 Add a dcname and sockaddr_storage pair to the end of a dc_name_ip
1014 Keeps the list unique by not adding duplicate entries.
1016 @param[in] mem_ctx talloc memory context to allocate from
1017 @param[in] domain_name domain of the DC
1018 @param[in] dcname name of the DC to add to the list
1019 @param[in] pss Internet address and port pair to add to the list
1020 @param[in,out] dcs array of dc_name_ip structures to add to
1021 @param[in,out] num_dcs number of dcs returned in the dcs array
1022 @return true if the list was added to, false otherwise
1023 *******************************************************************/
1025 static bool add_one_dc_unique(TALLOC_CTX *mem_ctx, const char *domain_name,
1026 const char *dcname, struct sockaddr_storage *pss,
1027 struct dc_name_ip **dcs, int *num)
1031 if (!NT_STATUS_IS_OK(check_negative_conn_cache(domain_name, dcname))) {
1032 DEBUG(10, ("DC %s was in the negative conn cache\n", dcname));
1036 /* Make sure there's no duplicates in the list */
1037 for (i=0; i<*num; i++)
1038 if (sockaddr_equal((struct sockaddr *)&(*dcs)[i].ss, (struct sockaddr *)pss))
1041 *dcs = TALLOC_REALLOC_ARRAY(mem_ctx, *dcs, struct dc_name_ip, (*num)+1);
1046 fstrcpy((*dcs)[*num].name, dcname);
1047 (*dcs)[*num].ss = *pss;
1052 static bool add_sockaddr_to_array(TALLOC_CTX *mem_ctx,
1053 struct sockaddr_storage *pss, uint16 port,
1054 struct sockaddr_storage **addrs, int *num)
1056 *addrs = TALLOC_REALLOC_ARRAY(mem_ctx, *addrs, struct sockaddr_storage, (*num)+1);
1058 if (*addrs == NULL) {
1063 (*addrs)[*num] = *pss;
1064 set_sockaddr_port((struct sockaddr *)&(*addrs)[*num], port);
1070 /*******************************************************************
1071 convert an ip to a name
1072 *******************************************************************/
1074 static bool dcip_to_name(TALLOC_CTX *mem_ctx,
1075 const struct winbindd_domain *domain,
1076 struct sockaddr_storage *pss,
1079 struct ip_service ip_list;
1080 uint32_t nt_version = NETLOGON_NT_VERSION_1;
1086 /* For active directory servers, try to get the ldap server name.
1087 None of these failures should be considered critical for now */
1089 if (lp_security() == SEC_ADS) {
1091 ADS_STATUS ads_status;
1092 char addr[INET6_ADDRSTRLEN];
1094 print_sockaddr(addr, sizeof(addr), pss);
1096 ads = ads_init(domain->alt_name, domain->name, addr);
1097 ads->auth.flags |= ADS_AUTH_NO_BIND;
1099 ads_status = ads_connect(ads);
1100 if (ADS_ERR_OK(ads_status)) {
1101 /* We got a cldap packet. */
1102 fstrcpy(name, ads->config.ldap_server_name);
1103 namecache_store(name, 0x20, 1, &ip_list);
1105 DEBUG(10,("dcip_to_name: flags = 0x%x\n", (unsigned int)ads->config.flags));
1107 if (domain->primary && (ads->config.flags & NBT_SERVER_KDC)) {
1108 if (ads_closest_dc(ads)) {
1109 char *sitename = sitename_fetch(ads->config.realm);
1111 /* We're going to use this KDC for this realm/domain.
1112 If we are using sites, then force the krb5 libs
1115 create_local_private_krb5_conf_for_domain(domain->alt_name,
1120 SAFE_FREE(sitename);
1122 /* use an off site KDC */
1123 create_local_private_krb5_conf_for_domain(domain->alt_name,
1128 winbindd_set_locator_kdc_envs(domain);
1130 /* Ensure we contact this DC also. */
1131 saf_store( domain->name, name);
1132 saf_store( domain->alt_name, name);
1135 ads_destroy( &ads );
1139 ads_destroy( &ads );
1143 /* try GETDC requests next */
1145 if (send_getdc_request(mem_ctx, winbind_messaging_context(),
1146 pss, domain->name, &domain->sid,
1148 const char *dc_name = NULL;
1151 for (i=0; i<5; i++) {
1152 if (receive_getdc_response(mem_ctx, pss, domain->name,
1155 fstrcpy(name, dc_name);
1156 namecache_store(name, 0x20, 1, &ip_list);
1163 /* try node status request */
1165 if ( name_status_find(domain->name, 0x1c, 0x20, pss, name) ) {
1166 namecache_store(name, 0x20, 1, &ip_list);
1172 /*******************************************************************
1173 Retrieve a list of IP addresses for domain controllers.
1175 The array is sorted in the preferred connection order.
1177 @param[in] mem_ctx talloc memory context to allocate from
1178 @param[in] domain domain to retrieve DCs for
1179 @param[out] dcs array of dcs that will be returned
1180 @param[out] num_dcs number of dcs returned in the dcs array
1182 *******************************************************************/
1184 static bool get_dcs(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
1185 struct dc_name_ip **dcs, int *num_dcs)
1188 struct sockaddr_storage ss;
1189 struct ip_service *ip_list = NULL;
1190 int iplist_size = 0;
1193 enum security_types sec = (enum security_types)lp_security();
1195 is_our_domain = strequal(domain->name, lp_workgroup());
1197 /* If not our domain, get the preferred DC, by asking our primary DC */
1199 && get_dc_name_via_netlogon(domain, dcname, &ss)
1200 && add_one_dc_unique(mem_ctx, domain->name, dcname, &ss, dcs,
1203 char addr[INET6_ADDRSTRLEN];
1204 print_sockaddr(addr, sizeof(addr), &ss);
1205 DEBUG(10, ("Retrieved DC %s at %s via netlogon\n",
1210 if (sec == SEC_ADS) {
1211 char *sitename = NULL;
1213 /* We need to make sure we know the local site before
1214 doing any DNS queries, as this will restrict the
1215 get_sorted_dc_list() call below to only fetching
1216 DNS records for the correct site. */
1218 /* Find any DC to get the site record.
1219 We deliberately don't care about the
1222 get_dc_name(domain->name, domain->alt_name, dcname, &ss);
1224 sitename = sitename_fetch(domain->alt_name);
1227 /* Do the site-specific AD dns lookup first. */
1228 get_sorted_dc_list(domain->alt_name, sitename, &ip_list,
1229 &iplist_size, True);
1231 /* Add ips to the DC array. We don't look up the name
1232 of the DC in this function, but we fill in the char*
1233 of the ip now to make the failed connection cache
1235 for ( i=0; i<iplist_size; i++ ) {
1236 char addr[INET6_ADDRSTRLEN];
1237 print_sockaddr(addr, sizeof(addr),
1239 add_one_dc_unique(mem_ctx,
1248 SAFE_FREE(sitename);
1252 /* Now we add DCs from the main AD DNS lookup. */
1253 get_sorted_dc_list(domain->alt_name, NULL, &ip_list,
1254 &iplist_size, True);
1256 for ( i=0; i<iplist_size; i++ ) {
1257 char addr[INET6_ADDRSTRLEN];
1258 print_sockaddr(addr, sizeof(addr),
1260 add_one_dc_unique(mem_ctx,
1272 /* Try standard netbios queries if no ADS */
1273 if (*num_dcs == 0) {
1274 get_sorted_dc_list(domain->name, NULL, &ip_list, &iplist_size,
1277 for ( i=0; i<iplist_size; i++ ) {
1278 char addr[INET6_ADDRSTRLEN];
1279 print_sockaddr(addr, sizeof(addr),
1281 add_one_dc_unique(mem_ctx,
1296 /*******************************************************************
1297 Find and make a connection to a DC in the given domain.
1299 @param[in] mem_ctx talloc memory context to allocate from
1300 @param[in] domain domain to find a dc in
1301 @param[out] dcname NetBIOS or FQDN of DC that's connected to
1302 @param[out] pss DC Internet address and port
1303 @param[out] fd fd of the open socket connected to the newly found dc
1304 @return true when a DC connection is made, false otherwise
1305 *******************************************************************/
1307 static bool find_new_dc(TALLOC_CTX *mem_ctx,
1308 struct winbindd_domain *domain,
1309 fstring dcname, struct sockaddr_storage *pss, int *fd)
1311 struct dc_name_ip *dcs = NULL;
1314 const char **dcnames = NULL;
1315 int num_dcnames = 0;
1317 struct sockaddr_storage *addrs = NULL;
1325 if (!get_dcs(mem_ctx, domain, &dcs, &num_dcs) || (num_dcs == 0))
1328 for (i=0; i<num_dcs; i++) {
1330 if (!add_string_to_array(mem_ctx, dcs[i].name,
1331 &dcnames, &num_dcnames)) {
1334 if (!add_sockaddr_to_array(mem_ctx, &dcs[i].ss, 445,
1335 &addrs, &num_addrs)) {
1339 if (!add_string_to_array(mem_ctx, dcs[i].name,
1340 &dcnames, &num_dcnames)) {
1343 if (!add_sockaddr_to_array(mem_ctx, &dcs[i].ss, 139,
1344 &addrs, &num_addrs)) {
1349 if ((num_dcnames == 0) || (num_dcnames != num_addrs))
1352 if ((addrs == NULL) || (dcnames == NULL))
1355 /* 5 second timeout. */
1356 if (!open_any_socket_out(addrs, num_addrs, 5000, &fd_index, fd) ) {
1357 for (i=0; i<num_dcs; i++) {
1358 char ab[INET6_ADDRSTRLEN];
1359 print_sockaddr(ab, sizeof(ab), &dcs[i].ss);
1360 DEBUG(10, ("find_new_dc: open_any_socket_out failed for "
1361 "domain %s address %s. Error was %s\n",
1362 domain->name, ab, strerror(errno) ));
1363 winbind_add_failed_connection_entry(domain,
1364 dcs[i].name, NT_STATUS_UNSUCCESSFUL);
1369 *pss = addrs[fd_index];
1371 if (*dcnames[fd_index] != '\0' && !is_ipaddress(dcnames[fd_index])) {
1372 /* Ok, we've got a name for the DC */
1373 fstrcpy(dcname, dcnames[fd_index]);
1377 /* Try to figure out the name */
1378 if (dcip_to_name(mem_ctx, domain, pss, dcname)) {
1382 /* We can not continue without the DC's name */
1383 winbind_add_failed_connection_entry(domain, dcs[fd_index].name,
1384 NT_STATUS_UNSUCCESSFUL);
1386 /* Throw away all arrays as we're doing this again. */
1390 TALLOC_FREE(dcnames);
1402 static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
1403 struct winbindd_cm_conn *new_conn)
1405 TALLOC_CTX *mem_ctx;
1407 char *saf_servername = saf_fetch( domain->name );
1410 if ((mem_ctx = talloc_init("cm_open_connection")) == NULL) {
1411 SAFE_FREE(saf_servername);
1412 set_domain_offline(domain);
1413 return NT_STATUS_NO_MEMORY;
1416 /* we have to check the server affinity cache here since
1417 later we selecte a DC based on response time and not preference */
1419 /* Check the negative connection cache
1420 before talking to it. It going down may have
1421 triggered the reconnection. */
1423 if ( saf_servername && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, saf_servername))) {
1425 DEBUG(10,("cm_open_connection: saf_servername is '%s' for domain %s\n",
1426 saf_servername, domain->name ));
1428 /* convert an ip address to a name */
1429 if (is_ipaddress( saf_servername ) ) {
1431 struct sockaddr_storage ss;
1433 if (!interpret_string_addr(&ss, saf_servername,
1435 return NT_STATUS_UNSUCCESSFUL;
1437 if (dcip_to_name(mem_ctx, domain, &ss, saf_name )) {
1438 fstrcpy( domain->dcname, saf_name );
1440 winbind_add_failed_connection_entry(
1441 domain, saf_servername,
1442 NT_STATUS_UNSUCCESSFUL);
1445 fstrcpy( domain->dcname, saf_servername );
1448 SAFE_FREE( saf_servername );
1451 for (retries = 0; retries < 3; retries++) {
1455 result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1457 DEBUG(10,("cm_open_connection: dcname is '%s' for domain %s\n",
1458 domain->dcname, domain->name ));
1461 && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, domain->dcname))
1462 && (resolve_name(domain->dcname, &domain->dcaddr, 0x20)))
1464 struct sockaddr_storage *addrs = NULL;
1468 if (!add_sockaddr_to_array(mem_ctx, &domain->dcaddr, 445, &addrs, &num_addrs)) {
1469 set_domain_offline(domain);
1470 talloc_destroy(mem_ctx);
1471 return NT_STATUS_NO_MEMORY;
1473 if (!add_sockaddr_to_array(mem_ctx, &domain->dcaddr, 139, &addrs, &num_addrs)) {
1474 set_domain_offline(domain);
1475 talloc_destroy(mem_ctx);
1476 return NT_STATUS_NO_MEMORY;
1479 /* 5 second timeout. */
1480 if (!open_any_socket_out(addrs, num_addrs, 5000, &dummy, &fd)) {
1486 && !find_new_dc(mem_ctx, domain, domain->dcname, &domain->dcaddr, &fd))
1488 /* This is the one place where we will
1489 set the global winbindd offline state
1490 to true, if a "WINBINDD_OFFLINE" entry
1491 is found in the winbindd cache. */
1492 set_global_winbindd_state_offline();
1496 new_conn->cli = NULL;
1498 result = cm_prepare_connection(domain, fd, domain->dcname,
1499 &new_conn->cli, &retry);
1505 if (NT_STATUS_IS_OK(result)) {
1507 winbindd_set_locator_kdc_envs(domain);
1509 if (domain->online == False) {
1510 /* We're changing state from offline to online. */
1511 set_global_winbindd_state_online();
1513 set_domain_online(domain);
1515 /* Ensure we setup the retry handler. */
1516 set_domain_offline(domain);
1519 talloc_destroy(mem_ctx);
1523 /* Close down all open pipes on a connection. */
1525 void invalidate_cm_connection(struct winbindd_cm_conn *conn)
1527 /* We're closing down a possibly dead
1528 connection. Don't have impossibly long (10s) timeouts. */
1531 cli_set_timeout(conn->cli, 1000); /* 1 second. */
1534 if (conn->samr_pipe != NULL) {
1535 TALLOC_FREE(conn->samr_pipe);
1536 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1538 cli_set_timeout(conn->cli, 500);
1542 if (conn->lsa_pipe != NULL) {
1543 TALLOC_FREE(conn->lsa_pipe);
1544 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1546 cli_set_timeout(conn->cli, 500);
1550 if (conn->netlogon_pipe != NULL) {
1551 TALLOC_FREE(conn->netlogon_pipe);
1552 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1554 cli_set_timeout(conn->cli, 500);
1559 cli_shutdown(conn->cli);
1565 void close_conns_after_fork(void)
1567 struct winbindd_domain *domain;
1569 for (domain = domain_list(); domain; domain = domain->next) {
1570 if (domain->conn.cli == NULL)
1573 if (domain->conn.cli->fd == -1)
1576 close(domain->conn.cli->fd);
1577 domain->conn.cli->fd = -1;
1581 static bool connection_ok(struct winbindd_domain *domain)
1583 if (domain->conn.cli == NULL) {
1584 DEBUG(8, ("connection_ok: Connection to %s for domain %s has NULL "
1585 "cli!\n", domain->dcname, domain->name));
1589 if (!domain->conn.cli->initialised) {
1590 DEBUG(3, ("connection_ok: Connection to %s for domain %s was never "
1591 "initialised!\n", domain->dcname, domain->name));
1595 if (domain->conn.cli->fd == -1) {
1596 DEBUG(3, ("connection_ok: Connection to %s for domain %s has died or was "
1597 "never started (fd == -1)\n",
1598 domain->dcname, domain->name));
1602 if (domain->online == False) {
1603 DEBUG(3, ("connection_ok: Domain %s is offline\n", domain->name));
1610 /* Initialize a new connection up to the RPC BIND.
1611 Bypass online status check so always does network calls. */
1613 static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain)
1617 /* Internal connections never use the network. */
1618 if (domain->internal) {
1619 domain->initialized = True;
1620 return NT_STATUS_OK;
1623 if (connection_ok(domain)) {
1624 if (!domain->initialized) {
1625 set_dc_type_and_flags(domain);
1627 return NT_STATUS_OK;
1630 invalidate_cm_connection(&domain->conn);
1632 result = cm_open_connection(domain, &domain->conn);
1634 if (NT_STATUS_IS_OK(result) && !domain->initialized) {
1635 set_dc_type_and_flags(domain);
1641 NTSTATUS init_dc_connection(struct winbindd_domain *domain)
1643 if (domain->initialized && !domain->online) {
1644 /* We check for online status elsewhere. */
1645 return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1648 return init_dc_connection_network(domain);
1651 /******************************************************************************
1652 Set the trust flags (direction and forest location) for a domain
1653 ******************************************************************************/
1655 static bool set_dc_type_and_flags_trustinfo( struct winbindd_domain *domain )
1657 struct winbindd_domain *our_domain;
1658 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1659 struct netr_DomainTrustList trusts;
1661 uint32 flags = (NETR_TRUST_FLAG_IN_FOREST |
1662 NETR_TRUST_FLAG_OUTBOUND |
1663 NETR_TRUST_FLAG_INBOUND);
1664 struct rpc_pipe_client *cli;
1665 TALLOC_CTX *mem_ctx = NULL;
1667 DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s\n", domain->name ));
1669 /* Our primary domain doesn't need to worry about trust flags.
1670 Force it to go through the network setup */
1671 if ( domain->primary ) {
1675 our_domain = find_our_domain();
1677 if ( !connection_ok(our_domain) ) {
1678 DEBUG(3,("set_dc_type_and_flags_trustinfo: No connection to our domain!\n"));
1682 /* This won't work unless our domain is AD */
1684 if ( !our_domain->active_directory ) {
1688 /* Use DsEnumerateDomainTrusts to get us the trust direction
1691 result = cm_connect_netlogon(our_domain, &cli);
1693 if (!NT_STATUS_IS_OK(result)) {
1694 DEBUG(5, ("set_dc_type_and_flags_trustinfo: Could not open "
1695 "a connection to %s for PIPE_NETLOGON (%s)\n",
1696 domain->name, nt_errstr(result)));
1700 if ( (mem_ctx = talloc_init("set_dc_type_and_flags_trustinfo")) == NULL ) {
1701 DEBUG(0,("set_dc_type_and_flags_trustinfo: talloc_init() failed!\n"));
1705 result = rpccli_netr_DsrEnumerateDomainTrusts(cli, mem_ctx,
1710 if (!NT_STATUS_IS_OK(result)) {
1711 DEBUG(0,("set_dc_type_and_flags_trustinfo: "
1712 "failed to query trusted domain list: %s\n",
1713 nt_errstr(result)));
1714 talloc_destroy(mem_ctx);
1718 /* Now find the domain name and get the flags */
1720 for ( i=0; i<trusts.count; i++ ) {
1721 if ( strequal( domain->name, trusts.array[i].netbios_name) ) {
1722 domain->domain_flags = trusts.array[i].trust_flags;
1723 domain->domain_type = trusts.array[i].trust_type;
1724 domain->domain_trust_attribs = trusts.array[i].trust_attributes;
1726 if ( domain->domain_type == NETR_TRUST_TYPE_UPLEVEL )
1727 domain->active_directory = True;
1729 /* This flag is only set if the domain is *our*
1730 primary domain and the primary domain is in
1733 domain->native_mode = (domain->domain_flags & NETR_TRUST_FLAG_NATIVE);
1735 DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s is %sin "
1736 "native mode.\n", domain->name,
1737 domain->native_mode ? "" : "NOT "));
1739 DEBUG(5,("set_dc_type_and_flags_trustinfo: domain %s is %s"
1740 "running active directory.\n", domain->name,
1741 domain->active_directory ? "" : "NOT "));
1744 domain->initialized = True;
1746 if ( !winbindd_can_contact_domain( domain) )
1747 domain->internal = True;
1753 talloc_destroy( mem_ctx );
1755 return domain->initialized;
1758 /******************************************************************************
1759 We can 'sense' certain things about the DC by it's replies to certain
1762 This tells us if this particular remote server is Active Directory, and if it
1764 ******************************************************************************/
1766 static void set_dc_type_and_flags_connect( struct winbindd_domain *domain )
1770 TALLOC_CTX *mem_ctx = NULL;
1771 struct rpc_pipe_client *cli;
1773 union dssetup_DsRoleInfo info;
1774 union lsa_PolicyInformation *lsa_info = NULL;
1776 if (!connection_ok(domain)) {
1780 mem_ctx = talloc_init("set_dc_type_and_flags on domain %s\n",
1783 DEBUG(1, ("set_dc_type_and_flags_connect: talloc_init() failed\n"));
1787 DEBUG(5, ("set_dc_type_and_flags_connect: domain %s\n", domain->name ));
1789 result = cli_rpc_pipe_open_noauth(domain->conn.cli,
1790 &ndr_table_dssetup.syntax_id,
1793 if (!NT_STATUS_IS_OK(result)) {
1794 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
1795 "PI_DSSETUP on domain %s: (%s)\n",
1796 domain->name, nt_errstr(result)));
1798 /* if this is just a non-AD domain we need to continue
1799 * identifying so that we can in the end return with
1800 * domain->initialized = True - gd */
1805 result = rpccli_dssetup_DsRoleGetPrimaryDomainInformation(cli, mem_ctx,
1806 DS_ROLE_BASIC_INFORMATION,
1811 if (!NT_STATUS_IS_OK(result)) {
1812 DEBUG(5, ("set_dc_type_and_flags_connect: rpccli_ds_getprimarydominfo "
1813 "on domain %s failed: (%s)\n",
1814 domain->name, nt_errstr(result)));
1816 /* older samba3 DCs will return DCERPC_FAULT_OP_RNG_ERROR for
1817 * every opcode on the DSSETUP pipe, continue with
1818 * no_dssetup mode here as well to get domain->initialized
1821 if (NT_STATUS_V(result) == DCERPC_FAULT_OP_RNG_ERROR) {
1825 TALLOC_FREE(mem_ctx);
1829 if ((info.basic.flags & DS_ROLE_PRIMARY_DS_RUNNING) &&
1830 !(info.basic.flags & DS_ROLE_PRIMARY_DS_MIXED_MODE)) {
1831 domain->native_mode = True;
1833 domain->native_mode = False;
1837 result = cli_rpc_pipe_open_noauth(domain->conn.cli,
1838 &ndr_table_lsarpc.syntax_id, &cli);
1840 if (!NT_STATUS_IS_OK(result)) {
1841 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
1842 "PI_LSARPC on domain %s: (%s)\n",
1843 domain->name, nt_errstr(result)));
1845 TALLOC_FREE(mem_ctx);
1849 result = rpccli_lsa_open_policy2(cli, mem_ctx, True,
1850 SEC_RIGHTS_MAXIMUM_ALLOWED, &pol);
1852 if (NT_STATUS_IS_OK(result)) {
1853 /* This particular query is exactly what Win2k clients use
1854 to determine that the DC is active directory */
1855 result = rpccli_lsa_QueryInfoPolicy2(cli, mem_ctx,
1857 LSA_POLICY_INFO_DNS,
1861 if (NT_STATUS_IS_OK(result)) {
1862 domain->active_directory = True;
1864 if (lsa_info->dns.name.string) {
1865 fstrcpy(domain->name, lsa_info->dns.name.string);
1868 if (lsa_info->dns.dns_domain.string) {
1869 fstrcpy(domain->alt_name,
1870 lsa_info->dns.dns_domain.string);
1873 /* See if we can set some domain trust flags about
1876 if (lsa_info->dns.dns_forest.string) {
1877 fstrcpy(domain->forest_name,
1878 lsa_info->dns.dns_forest.string);
1880 if (strequal(domain->forest_name, domain->alt_name)) {
1881 domain->domain_flags |= NETR_TRUST_FLAG_TREEROOT;
1885 if (lsa_info->dns.sid) {
1886 sid_copy(&domain->sid, lsa_info->dns.sid);
1889 domain->active_directory = False;
1891 result = rpccli_lsa_open_policy(cli, mem_ctx, True,
1892 SEC_RIGHTS_MAXIMUM_ALLOWED,
1895 if (!NT_STATUS_IS_OK(result)) {
1899 result = rpccli_lsa_QueryInfoPolicy(cli, mem_ctx,
1901 LSA_POLICY_INFO_ACCOUNT_DOMAIN,
1904 if (NT_STATUS_IS_OK(result)) {
1906 if (lsa_info->account_domain.name.string) {
1907 fstrcpy(domain->name,
1908 lsa_info->account_domain.name.string);
1911 if (lsa_info->account_domain.sid) {
1912 sid_copy(&domain->sid, lsa_info->account_domain.sid);
1918 DEBUG(5, ("set_dc_type_and_flags_connect: domain %s is %sin native mode.\n",
1919 domain->name, domain->native_mode ? "" : "NOT "));
1921 DEBUG(5,("set_dc_type_and_flags_connect: domain %s is %srunning active directory.\n",
1922 domain->name, domain->active_directory ? "" : "NOT "));
1926 TALLOC_FREE(mem_ctx);
1928 domain->initialized = True;
1931 /**********************************************************************
1932 Set the domain_flags (trust attributes, domain operating modes, etc...
1933 ***********************************************************************/
1935 static void set_dc_type_and_flags( struct winbindd_domain *domain )
1937 /* we always have to contact our primary domain */
1939 if ( domain->primary ) {
1940 DEBUG(10,("set_dc_type_and_flags: setting up flags for "
1941 "primary domain\n"));
1942 set_dc_type_and_flags_connect( domain );
1946 /* Use our DC to get the information if possible */
1948 if ( !set_dc_type_and_flags_trustinfo( domain ) ) {
1949 /* Otherwise, fallback to contacting the
1951 set_dc_type_and_flags_connect( domain );
1959 /**********************************************************************
1960 ***********************************************************************/
1962 static bool cm_get_schannel_dcinfo(struct winbindd_domain *domain,
1963 struct dcinfo **ppdc)
1966 struct rpc_pipe_client *netlogon_pipe;
1968 if (lp_client_schannel() == False) {
1972 result = cm_connect_netlogon(domain, &netlogon_pipe);
1973 if (!NT_STATUS_IS_OK(result)) {
1977 /* Return a pointer to the struct dcinfo from the
1980 if (!domain->conn.netlogon_pipe->dc) {
1984 *ppdc = domain->conn.netlogon_pipe->dc;
1988 NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
1989 struct rpc_pipe_client **cli, POLICY_HND *sam_handle)
1991 struct winbindd_cm_conn *conn;
1992 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1994 struct dcinfo *p_dcinfo;
1995 char *machine_password = NULL;
1996 char *machine_account = NULL;
1997 char *domain_name = NULL;
1999 result = init_dc_connection(domain);
2000 if (!NT_STATUS_IS_OK(result)) {
2004 conn = &domain->conn;
2006 if (conn->samr_pipe != NULL) {
2012 * No SAMR pipe yet. Attempt to get an NTLMSSP SPNEGO authenticated
2013 * sign and sealed pipe using the machine account password by
2014 * preference. If we can't - try schannel, if that fails, try
2018 pwd_get_cleartext(&conn->cli->pwd, conn_pwd);
2019 if ((conn->cli->user_name[0] == '\0') ||
2020 (conn->cli->domain[0] == '\0') ||
2021 (conn_pwd[0] == '\0'))
2023 result = get_trust_creds(domain, &machine_password,
2024 &machine_account, NULL);
2025 if (!NT_STATUS_IS_OK(result)) {
2026 DEBUG(10, ("cm_connect_sam: No no user available for "
2027 "domain %s, trying schannel\n", conn->cli->domain));
2030 domain_name = domain->name;
2032 machine_password = SMB_STRDUP(conn_pwd);
2033 machine_account = SMB_STRDUP(conn->cli->user_name);
2034 domain_name = conn->cli->domain;
2037 if (!machine_password || !machine_account) {
2038 result = NT_STATUS_NO_MEMORY;
2042 /* We have an authenticated connection. Use a NTLMSSP SPNEGO
2043 authenticated SAMR pipe with sign & seal. */
2044 result = cli_rpc_pipe_open_spnego_ntlmssp(conn->cli,
2045 &ndr_table_samr.syntax_id,
2046 PIPE_AUTH_LEVEL_PRIVACY,
2052 if (!NT_STATUS_IS_OK(result)) {
2053 DEBUG(10,("cm_connect_sam: failed to connect to SAMR "
2054 "pipe for domain %s using NTLMSSP "
2055 "authenticated pipe: user %s\\%s. Error was "
2056 "%s\n", domain->name, domain_name,
2057 machine_account, nt_errstr(result)));
2061 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for "
2062 "domain %s using NTLMSSP authenticated "
2063 "pipe: user %s\\%s\n", domain->name,
2064 domain_name, machine_account));
2066 result = rpccli_samr_Connect2(conn->samr_pipe, mem_ctx,
2067 conn->samr_pipe->desthost,
2068 SEC_RIGHTS_MAXIMUM_ALLOWED,
2069 &conn->sam_connect_handle);
2070 if (NT_STATUS_IS_OK(result)) {
2073 DEBUG(10,("cm_connect_sam: ntlmssp-sealed rpccli_samr_Connect2 "
2074 "failed for domain %s, error was %s. Trying schannel\n",
2075 domain->name, nt_errstr(result) ));
2076 TALLOC_FREE(conn->samr_pipe);
2080 /* Fall back to schannel if it's a W2K pre-SP1 box. */
2082 if (!cm_get_schannel_dcinfo(domain, &p_dcinfo)) {
2083 /* If this call fails - conn->cli can now be NULL ! */
2084 DEBUG(10, ("cm_connect_sam: Could not get schannel auth info "
2085 "for domain %s, trying anon\n", domain->name));
2088 result = cli_rpc_pipe_open_schannel_with_key
2089 (conn->cli, &ndr_table_samr.syntax_id, PIPE_AUTH_LEVEL_PRIVACY,
2090 domain->name, p_dcinfo, &conn->samr_pipe);
2092 if (!NT_STATUS_IS_OK(result)) {
2093 DEBUG(10,("cm_connect_sam: failed to connect to SAMR pipe for "
2094 "domain %s using schannel. Error was %s\n",
2095 domain->name, nt_errstr(result) ));
2098 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for domain %s using "
2099 "schannel.\n", domain->name ));
2101 result = rpccli_samr_Connect2(conn->samr_pipe, mem_ctx,
2102 conn->samr_pipe->desthost,
2103 SEC_RIGHTS_MAXIMUM_ALLOWED,
2104 &conn->sam_connect_handle);
2105 if (NT_STATUS_IS_OK(result)) {
2108 DEBUG(10,("cm_connect_sam: schannel-sealed rpccli_samr_Connect2 failed "
2109 "for domain %s, error was %s. Trying anonymous\n",
2110 domain->name, nt_errstr(result) ));
2111 TALLOC_FREE(conn->samr_pipe);
2115 /* Finally fall back to anonymous. */
2116 result = cli_rpc_pipe_open_noauth(conn->cli, &ndr_table_samr.syntax_id,
2119 if (!NT_STATUS_IS_OK(result)) {
2123 result = rpccli_samr_Connect2(conn->samr_pipe, mem_ctx,
2124 conn->samr_pipe->desthost,
2125 SEC_RIGHTS_MAXIMUM_ALLOWED,
2126 &conn->sam_connect_handle);
2127 if (!NT_STATUS_IS_OK(result)) {
2128 DEBUG(10,("cm_connect_sam: rpccli_samr_Connect2 failed "
2129 "for domain %s Error was %s\n",
2130 domain->name, nt_errstr(result) ));
2135 result = rpccli_samr_OpenDomain(conn->samr_pipe,
2137 &conn->sam_connect_handle,
2138 SEC_RIGHTS_MAXIMUM_ALLOWED,
2140 &conn->sam_domain_handle);
2144 if (!NT_STATUS_IS_OK(result)) {
2145 invalidate_cm_connection(conn);
2149 *cli = conn->samr_pipe;
2150 *sam_handle = conn->sam_domain_handle;
2151 SAFE_FREE(machine_password);
2152 SAFE_FREE(machine_account);
2156 NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
2157 struct rpc_pipe_client **cli, POLICY_HND *lsa_policy)
2159 struct winbindd_cm_conn *conn;
2160 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2162 struct dcinfo *p_dcinfo;
2164 result = init_dc_connection(domain);
2165 if (!NT_STATUS_IS_OK(result))
2168 conn = &domain->conn;
2170 if (conn->lsa_pipe != NULL) {
2174 pwd_get_cleartext(&conn->cli->pwd, conn_pwd);
2175 if ((conn->cli->user_name[0] == '\0') ||
2176 (conn->cli->domain[0] == '\0') ||
2177 (conn_pwd[0] == '\0')) {
2178 DEBUG(10, ("cm_connect_lsa: No no user available for "
2179 "domain %s, trying schannel\n", conn->cli->domain));
2183 /* We have an authenticated connection. Use a NTLMSSP SPNEGO
2184 * authenticated LSA pipe with sign & seal. */
2185 result = cli_rpc_pipe_open_spnego_ntlmssp
2186 (conn->cli, &ndr_table_lsarpc.syntax_id,
2187 PIPE_AUTH_LEVEL_PRIVACY,
2188 conn->cli->domain, conn->cli->user_name, conn_pwd,
2191 if (!NT_STATUS_IS_OK(result)) {
2192 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
2193 "domain %s using NTLMSSP authenticated pipe: user "
2194 "%s\\%s. Error was %s. Trying schannel.\n",
2195 domain->name, conn->cli->domain,
2196 conn->cli->user_name, nt_errstr(result)));
2200 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
2201 "NTLMSSP authenticated pipe: user %s\\%s\n",
2202 domain->name, conn->cli->domain, conn->cli->user_name ));
2204 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2205 SEC_RIGHTS_MAXIMUM_ALLOWED,
2207 if (NT_STATUS_IS_OK(result)) {
2211 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
2214 TALLOC_FREE(conn->lsa_pipe);
2218 /* Fall back to schannel if it's a W2K pre-SP1 box. */
2220 if (!cm_get_schannel_dcinfo(domain, &p_dcinfo)) {
2221 /* If this call fails - conn->cli can now be NULL ! */
2222 DEBUG(10, ("cm_connect_lsa: Could not get schannel auth info "
2223 "for domain %s, trying anon\n", domain->name));
2226 result = cli_rpc_pipe_open_schannel_with_key
2227 (conn->cli, &ndr_table_lsarpc.syntax_id,
2228 PIPE_AUTH_LEVEL_PRIVACY,
2229 domain->name, p_dcinfo, &conn->lsa_pipe);
2231 if (!NT_STATUS_IS_OK(result)) {
2232 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
2233 "domain %s using schannel. Error was %s\n",
2234 domain->name, nt_errstr(result) ));
2237 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
2238 "schannel.\n", domain->name ));
2240 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2241 SEC_RIGHTS_MAXIMUM_ALLOWED,
2243 if (NT_STATUS_IS_OK(result)) {
2247 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
2250 TALLOC_FREE(conn->lsa_pipe);
2254 result = cli_rpc_pipe_open_noauth(conn->cli,
2255 &ndr_table_lsarpc.syntax_id,
2257 if (!NT_STATUS_IS_OK(result)) {
2258 result = NT_STATUS_PIPE_NOT_AVAILABLE;
2262 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2263 SEC_RIGHTS_MAXIMUM_ALLOWED,
2266 if (!NT_STATUS_IS_OK(result)) {
2267 invalidate_cm_connection(conn);
2271 *cli = conn->lsa_pipe;
2272 *lsa_policy = conn->lsa_policy;
2276 /****************************************************************************
2277 Open the netlogon pipe to this DC. Use schannel if specified in client conf.
2278 session key stored in conn->netlogon_pipe->dc->sess_key.
2279 ****************************************************************************/
2281 NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
2282 struct rpc_pipe_client **cli)
2284 struct winbindd_cm_conn *conn;
2287 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
2289 uint32 sec_chan_type;
2290 const char *account_name;
2291 struct rpc_pipe_client *netlogon_pipe = NULL;
2295 result = init_dc_connection(domain);
2296 if (!NT_STATUS_IS_OK(result)) {
2300 conn = &domain->conn;
2302 if (conn->netlogon_pipe != NULL) {
2303 *cli = conn->netlogon_pipe;
2304 return NT_STATUS_OK;
2307 result = cli_rpc_pipe_open_noauth(conn->cli,
2308 &ndr_table_netlogon.syntax_id,
2310 if (!NT_STATUS_IS_OK(result)) {
2314 if ((!IS_DC) && (!domain->primary)) {
2315 /* Clear the schannel request bit and drop down */
2316 neg_flags &= ~NETLOGON_NEG_SCHANNEL;
2320 if (lp_client_schannel() != False) {
2321 neg_flags |= NETLOGON_NEG_SCHANNEL;
2324 if (!get_trust_pw_hash(domain->name, mach_pwd, &account_name,
2327 TALLOC_FREE(netlogon_pipe);
2328 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2331 result = rpccli_netlogon_setup_creds(
2333 domain->dcname, /* server name. */
2334 domain->name, /* domain name */
2335 global_myname(), /* client name */
2336 account_name, /* machine account */
2337 mach_pwd, /* machine password */
2338 sec_chan_type, /* from get_trust_pw */
2341 if (!NT_STATUS_IS_OK(result)) {
2342 TALLOC_FREE(netlogon_pipe);
2346 if ((lp_client_schannel() == True) &&
2347 ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
2348 DEBUG(3, ("Server did not offer schannel\n"));
2349 TALLOC_FREE(netlogon_pipe);
2350 return NT_STATUS_ACCESS_DENIED;
2354 if ((lp_client_schannel() == False) ||
2355 ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
2357 * NetSamLogonEx only works for schannel
2359 domain->can_do_samlogon_ex = False;
2361 /* We're done - just keep the existing connection to NETLOGON
2363 conn->netlogon_pipe = netlogon_pipe;
2364 *cli = conn->netlogon_pipe;
2365 return NT_STATUS_OK;
2368 /* Using the credentials from the first pipe, open a signed and sealed
2369 second netlogon pipe. The session key is stored in the schannel
2370 part of the new pipe auth struct.
2373 result = cli_rpc_pipe_open_schannel_with_key(
2374 conn->cli, &ndr_table_netlogon.syntax_id,
2375 PIPE_AUTH_LEVEL_PRIVACY, domain->name, netlogon_pipe->dc,
2376 &conn->netlogon_pipe);
2378 /* We can now close the initial netlogon pipe. */
2379 TALLOC_FREE(netlogon_pipe);
2381 if (!NT_STATUS_IS_OK(result)) {
2382 DEBUG(3, ("Could not open schannel'ed NETLOGON pipe. Error "
2383 "was %s\n", nt_errstr(result)));
2385 /* make sure we return something besides OK */
2386 return !NT_STATUS_IS_OK(result) ? result : NT_STATUS_PIPE_NOT_AVAILABLE;
2390 * Try NetSamLogonEx for AD domains
2392 domain->can_do_samlogon_ex = domain->active_directory;
2394 *cli = conn->netlogon_pipe;
2395 return NT_STATUS_OK;