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/ndr_netlogon_c.h"
65 #include "rpc_client/cli_pipe.h"
66 #include "rpc_client/cli_netlogon.h"
67 #include "../librpc/gen_ndr/ndr_samr_c.h"
68 #include "../librpc/gen_ndr/ndr_lsa_c.h"
69 #include "rpc_client/cli_lsarpc.h"
70 #include "../librpc/gen_ndr/ndr_dssetup_c.h"
71 #include "libads/sitename_cache.h"
72 #include "libsmb/libsmb.h"
73 #include "libsmb/clidgram.h"
76 #include "../libcli/security/security.h"
79 #include "auth/gensec/gensec.h"
80 #include "../libcli/smb/smbXcli_base.h"
81 #include "lib/param/loadparm.h"
82 #include "libcli/auth/netlogon_creds_cli.h"
84 #include "rpc_server/rpc_ncacn_np.h"
87 #define DBGC_CLASS DBGC_WINBIND
91 struct sockaddr_storage ss;
94 extern struct winbindd_methods reconnect_methods;
95 extern bool override_logfile;
97 static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain, bool need_rw_dc);
98 static void set_dc_type_and_flags( struct winbindd_domain *domain );
99 static bool get_dcs(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
100 struct dc_name_ip **dcs, int *num_dcs);
102 /****************************************************************
103 Child failed to find DC's. Reschedule check.
104 ****************************************************************/
106 static void msg_failed_to_go_online(struct messaging_context *msg,
109 struct server_id server_id,
112 struct winbindd_domain *domain;
113 const char *domainname = (const char *)data->data;
115 if (data->data == NULL || data->length == 0) {
119 DEBUG(5,("msg_fail_to_go_online: received for domain %s.\n", domainname));
121 for (domain = domain_list(); domain; domain = domain->next) {
122 if (domain->internal) {
126 if (strequal(domain->name, domainname)) {
127 if (domain->online) {
128 /* We're already online, ignore. */
129 DEBUG(5,("msg_fail_to_go_online: domain %s "
130 "already online.\n", domainname));
134 /* Reschedule the online check. */
135 set_domain_offline(domain);
141 /****************************************************************
142 Actually cause a reconnect from a message.
143 ****************************************************************/
145 static void msg_try_to_go_online(struct messaging_context *msg,
148 struct server_id server_id,
151 struct winbindd_domain *domain;
152 const char *domainname = (const char *)data->data;
154 if (data->data == NULL || data->length == 0) {
158 DEBUG(5,("msg_try_to_go_online: received for domain %s.\n", domainname));
160 for (domain = domain_list(); domain; domain = domain->next) {
161 if (domain->internal) {
165 if (strequal(domain->name, domainname)) {
167 if (domain->online) {
168 /* We're already online, ignore. */
169 DEBUG(5,("msg_try_to_go_online: domain %s "
170 "already online.\n", domainname));
174 /* This call takes care of setting the online
175 flag to true if we connected, or re-adding
176 the offline handler if false. Bypasses online
177 check so always does network calls. */
179 init_dc_connection_network(domain, true);
185 /****************************************************************
186 Fork a child to try and contact a DC. Do this as contacting a
187 DC requires blocking lookups and we don't want to block our
189 ****************************************************************/
191 static bool fork_child_dc_connect(struct winbindd_domain *domain)
193 struct dc_name_ip *dcs = NULL;
195 TALLOC_CTX *mem_ctx = NULL;
196 pid_t parent_pid = getpid();
200 if (domain->dc_probe_pid != (pid_t)-1) {
202 * We might already have a DC probe
203 * child working, check.
205 if (process_exists_by_pid(domain->dc_probe_pid)) {
206 DEBUG(10,("fork_child_dc_connect: pid %u already "
207 "checking for DC's.\n",
208 (unsigned int)domain->dc_probe_pid));
211 domain->dc_probe_pid = (pid_t)-1;
214 domain->dc_probe_pid = fork();
216 if (domain->dc_probe_pid == (pid_t)-1) {
217 DEBUG(0, ("fork_child_dc_connect: Could not fork: %s\n", strerror(errno)));
221 if (domain->dc_probe_pid != (pid_t)0) {
223 messaging_register(winbind_messaging_context(), NULL,
224 MSG_WINBIND_TRY_TO_GO_ONLINE,
225 msg_try_to_go_online);
226 messaging_register(winbind_messaging_context(), NULL,
227 MSG_WINBIND_FAILED_TO_GO_ONLINE,
228 msg_failed_to_go_online);
234 /* Leave messages blocked - we will never process one. */
236 if (!override_logfile) {
237 if (asprintf(&lfile, "%s/log.winbindd-dc-connect", get_dyn_LOGFILEBASE()) == -1) {
238 DEBUG(0, ("fork_child_dc_connect: out of memory.\n"));
243 status = winbindd_reinit_after_fork(NULL, lfile);
244 if (!NT_STATUS_IS_OK(status)) {
245 DEBUG(1, ("winbindd_reinit_after_fork failed: %s\n",
247 messaging_send_buf(winbind_messaging_context(),
248 pid_to_procid(parent_pid),
249 MSG_WINBIND_FAILED_TO_GO_ONLINE,
250 (const uint8_t *)domain->name,
251 strlen(domain->name)+1);
256 mem_ctx = talloc_init("fork_child_dc_connect");
258 DEBUG(0,("talloc_init failed.\n"));
259 messaging_send_buf(winbind_messaging_context(),
260 pid_to_procid(parent_pid),
261 MSG_WINBIND_FAILED_TO_GO_ONLINE,
262 (const uint8_t *)domain->name,
263 strlen(domain->name)+1);
267 if ((!get_dcs(mem_ctx, domain, &dcs, &num_dcs)) || (num_dcs == 0)) {
268 /* Still offline ? Can't find DC's. */
269 messaging_send_buf(winbind_messaging_context(),
270 pid_to_procid(parent_pid),
271 MSG_WINBIND_FAILED_TO_GO_ONLINE,
272 (const uint8_t *)domain->name,
273 strlen(domain->name)+1);
277 /* We got a DC. Send a message to our parent to get it to
278 try and do the same. */
280 messaging_send_buf(winbind_messaging_context(),
281 pid_to_procid(parent_pid),
282 MSG_WINBIND_TRY_TO_GO_ONLINE,
283 (const uint8_t *)domain->name,
284 strlen(domain->name)+1);
288 /****************************************************************
289 Handler triggered if we're offline to try and detect a DC.
290 ****************************************************************/
292 static void check_domain_online_handler(struct tevent_context *ctx,
293 struct tevent_timer *te,
297 struct winbindd_domain *domain =
298 (struct winbindd_domain *)private_data;
300 DEBUG(10,("check_domain_online_handler: called for domain "
301 "%s (online = %s)\n", domain->name,
302 domain->online ? "True" : "False" ));
304 TALLOC_FREE(domain->check_online_event);
306 /* Are we still in "startup" mode ? */
308 if (domain->startup && (time_mono(NULL) > domain->startup_time + 30)) {
309 /* No longer in "startup" mode. */
310 DEBUG(10,("check_domain_online_handler: domain %s no longer in 'startup' mode.\n",
312 domain->startup = False;
315 /* We've been told to stay offline, so stay
318 if (get_global_winbindd_state_offline()) {
319 DEBUG(10,("check_domain_online_handler: domain %s remaining globally offline\n",
324 /* Fork a child to test if it can contact a DC.
325 If it can then send ourselves a message to
326 cause a reconnect. */
328 fork_child_dc_connect(domain);
331 /****************************************************************
332 If we're still offline setup the timeout check.
333 ****************************************************************/
335 static void calc_new_online_timeout_check(struct winbindd_domain *domain)
337 int wbr = lp_winbind_reconnect_delay();
339 if (domain->startup) {
340 domain->check_online_timeout = 10;
341 } else if (domain->check_online_timeout < wbr) {
342 domain->check_online_timeout = wbr;
346 void winbind_msg_domain_offline(struct messaging_context *msg_ctx,
349 struct server_id server_id,
352 const char *domain_name = (const char *)data->data;
353 struct winbindd_domain *domain;
355 domain = find_domain_from_name_noinit(domain_name);
356 if (domain == NULL) {
360 domain->online = false;
362 DEBUG(10, ("Domain %s is marked as offline now.\n",
366 void winbind_msg_domain_online(struct messaging_context *msg_ctx,
369 struct server_id server_id,
372 const char *domain_name = (const char *)data->data;
373 struct winbindd_domain *domain;
375 domain = find_domain_from_name_noinit(domain_name);
376 if (domain == NULL) {
380 domain->online = true;
382 DEBUG(10, ("Domain %s is marked as online now.\n",
386 /****************************************************************
387 Set domain offline and also add handler to put us back online
389 ****************************************************************/
391 void set_domain_offline(struct winbindd_domain *domain)
393 pid_t parent_pid = getppid();
395 DEBUG(10,("set_domain_offline: called for domain %s\n",
398 TALLOC_FREE(domain->check_online_event);
400 if (domain->internal) {
401 DEBUG(3,("set_domain_offline: domain %s is internal - logic error.\n",
406 domain->online = False;
408 /* Offline domains are always initialized. They're
409 re-initialized when they go back online. */
411 domain->initialized = True;
413 /* We only add the timeout handler that checks and
414 allows us to go back online when we've not
415 been told to remain offline. */
417 if (get_global_winbindd_state_offline()) {
418 DEBUG(10,("set_domain_offline: domain %s remaining globally offline\n",
423 /* If we're in startup mode, check again in 10 seconds, not in
424 lp_winbind_reconnect_delay() seconds (which is 30 seconds by default). */
426 calc_new_online_timeout_check(domain);
428 domain->check_online_event = tevent_add_timer(winbind_event_context(),
430 timeval_current_ofs(domain->check_online_timeout,0),
431 check_domain_online_handler,
434 /* The above *has* to succeed for winbindd to work. */
435 if (!domain->check_online_event) {
436 smb_panic("set_domain_offline: failed to add online handler");
439 DEBUG(10,("set_domain_offline: added event handler for domain %s\n",
442 /* Send a message to the parent that the domain is offline. */
443 if (parent_pid > 1 && !domain->internal) {
444 messaging_send_buf(winbind_messaging_context(),
445 pid_to_procid(parent_pid),
446 MSG_WINBIND_DOMAIN_OFFLINE,
447 (uint8 *)domain->name,
448 strlen(domain->name) + 1);
451 /* Send an offline message to the idmap child when our
452 primary domain goes offline */
454 if ( domain->primary ) {
455 struct winbindd_child *idmap = idmap_child();
457 if ( idmap->pid != 0 ) {
458 messaging_send_buf(winbind_messaging_context(),
459 pid_to_procid(idmap->pid),
461 (const uint8_t *)domain->name,
462 strlen(domain->name)+1);
469 /****************************************************************
470 Set domain online - if allowed.
471 ****************************************************************/
473 static void set_domain_online(struct winbindd_domain *domain)
475 pid_t parent_pid = getppid();
477 DEBUG(10,("set_domain_online: called for domain %s\n",
480 if (domain->internal) {
481 DEBUG(3,("set_domain_online: domain %s is internal - logic error.\n",
486 if (get_global_winbindd_state_offline()) {
487 DEBUG(10,("set_domain_online: domain %s remaining globally offline\n",
492 winbindd_set_locator_kdc_envs(domain);
494 /* If we are waiting to get a krb5 ticket, trigger immediately. */
495 ccache_regain_all_now();
497 /* Ok, we're out of any startup mode now... */
498 domain->startup = False;
500 if (domain->online == False) {
501 /* We were offline - now we're online. We default to
502 using the MS-RPC backend if we started offline,
503 and if we're going online for the first time we
504 should really re-initialize the backends and the
505 checks to see if we're talking to an AD or NT domain.
508 domain->initialized = False;
510 /* 'reconnect_methods' is the MS-RPC backend. */
511 if (domain->backend == &reconnect_methods) {
512 domain->backend = NULL;
516 /* Ensure we have no online timeout checks. */
517 domain->check_online_timeout = 0;
518 TALLOC_FREE(domain->check_online_event);
520 /* Ensure we ignore any pending child messages. */
521 messaging_deregister(winbind_messaging_context(),
522 MSG_WINBIND_TRY_TO_GO_ONLINE, NULL);
523 messaging_deregister(winbind_messaging_context(),
524 MSG_WINBIND_FAILED_TO_GO_ONLINE, NULL);
526 domain->online = True;
528 /* Send a message to the parent that the domain is online. */
529 if (parent_pid > 1 && !domain->internal) {
530 messaging_send_buf(winbind_messaging_context(),
531 pid_to_procid(parent_pid),
532 MSG_WINBIND_DOMAIN_ONLINE,
533 (uint8 *)domain->name,
534 strlen(domain->name) + 1);
537 /* Send an online message to the idmap child when our
538 primary domain comes online */
540 if ( domain->primary ) {
541 struct winbindd_child *idmap = idmap_child();
543 if ( idmap->pid != 0 ) {
544 messaging_send_buf(winbind_messaging_context(),
545 pid_to_procid(idmap->pid),
547 (const uint8_t *)domain->name,
548 strlen(domain->name)+1);
555 /****************************************************************
556 Requested to set a domain online.
557 ****************************************************************/
559 void set_domain_online_request(struct winbindd_domain *domain)
563 DEBUG(10,("set_domain_online_request: called for domain %s\n",
566 if (get_global_winbindd_state_offline()) {
567 DEBUG(10,("set_domain_online_request: domain %s remaining globally offline\n",
572 if (domain->internal) {
573 DEBUG(10, ("set_domain_online_request: Internal domains are "
578 /* We've been told it's safe to go online and
579 try and connect to a DC. But I don't believe it
580 because network manager seems to lie.
581 Wait at least 5 seconds. Heuristics suck... */
586 /* Go into "startup" mode again. */
587 domain->startup_time = time_mono(NULL);
588 domain->startup = True;
592 if (!domain->check_online_event) {
593 /* If we've come from being globally offline we
594 don't have a check online event handler set.
595 We need to add one now we're trying to go
598 DEBUG(10,("set_domain_online_request: domain %s was globally offline.\n",
602 TALLOC_FREE(domain->check_online_event);
604 domain->check_online_event = tevent_add_timer(winbind_event_context(),
607 check_domain_online_handler,
610 /* The above *has* to succeed for winbindd to work. */
611 if (!domain->check_online_event) {
612 smb_panic("set_domain_online_request: failed to add online handler");
616 /****************************************************************
617 Add -ve connection cache entries for domain and realm.
618 ****************************************************************/
620 static void winbind_add_failed_connection_entry(
621 const struct winbindd_domain *domain,
625 add_failed_connection_entry(domain->name, server, result);
626 /* If this was the saf name for the last thing we talked to,
628 saf_delete(domain->name);
629 if (domain->alt_name != NULL) {
630 add_failed_connection_entry(domain->alt_name, server, result);
631 saf_delete(domain->alt_name);
633 winbindd_unset_locator_kdc_env(domain);
636 /* Choose between anonymous or authenticated connections. We need to use
637 an authenticated connection if DCs have the RestrictAnonymous registry
638 entry set > 0, or the "Additional restrictions for anonymous
639 connections" set in the win2k Local Security Policy.
641 Caller to free() result in domain, username, password
644 static void cm_get_ipc_userpass(char **username, char **domain, char **password)
646 *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
647 *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
648 *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
650 if (*username && **username) {
652 if (!*domain || !**domain)
653 *domain = smb_xstrdup(lp_workgroup());
655 if (!*password || !**password)
656 *password = smb_xstrdup("");
658 DEBUG(3, ("cm_get_ipc_userpass: Retrieved auth-user from secrets.tdb [%s\\%s]\n",
659 *domain, *username));
662 DEBUG(3, ("cm_get_ipc_userpass: No auth-user defined\n"));
663 *username = smb_xstrdup("");
664 *domain = smb_xstrdup("");
665 *password = smb_xstrdup("");
669 static bool get_dc_name_via_netlogon(struct winbindd_domain *domain,
671 struct sockaddr_storage *dc_ss)
673 struct winbindd_domain *our_domain = NULL;
674 struct rpc_pipe_client *netlogon_pipe = NULL;
678 unsigned int orig_timeout;
679 const char *tmp = NULL;
681 struct dcerpc_binding_handle *b;
683 /* Hmmmm. We can only open one connection to the NETLOGON pipe at the
690 if (domain->primary) {
694 our_domain = find_our_domain();
696 if ((mem_ctx = talloc_init("get_dc_name_via_netlogon")) == NULL) {
700 result = cm_connect_netlogon(our_domain, &netlogon_pipe);
701 if (!NT_STATUS_IS_OK(result)) {
702 talloc_destroy(mem_ctx);
706 b = netlogon_pipe->binding_handle;
708 /* This call can take a long time - allow the server to time out.
709 35 seconds should do it. */
711 orig_timeout = rpccli_set_timeout(netlogon_pipe, 35000);
713 if (our_domain->active_directory) {
714 struct netr_DsRGetDCNameInfo *domain_info = NULL;
716 result = dcerpc_netr_DsRGetDCName(b,
725 if (NT_STATUS_IS_OK(result) && W_ERROR_IS_OK(werr)) {
727 mem_ctx, domain_info->dc_unc);
729 DEBUG(0, ("talloc_strdup failed\n"));
730 talloc_destroy(mem_ctx);
733 if (domain->alt_name == NULL) {
734 domain->alt_name = talloc_strdup(domain,
735 domain_info->domain_name);
736 if (domain->alt_name == NULL) {
737 DEBUG(0, ("talloc_strdup failed\n"));
738 talloc_destroy(mem_ctx);
742 if (domain->forest_name == NULL) {
743 domain->forest_name = talloc_strdup(domain,
744 domain_info->forest_name);
745 if (domain->forest_name == NULL) {
746 DEBUG(0, ("talloc_strdup failed\n"));
747 talloc_destroy(mem_ctx);
753 result = dcerpc_netr_GetAnyDCName(b, mem_ctx,
760 /* And restore our original timeout. */
761 rpccli_set_timeout(netlogon_pipe, orig_timeout);
763 if (!NT_STATUS_IS_OK(result)) {
764 DEBUG(10,("dcerpc_netr_GetAnyDCName failed: %s\n",
766 talloc_destroy(mem_ctx);
770 if (!W_ERROR_IS_OK(werr)) {
771 DEBUG(10,("dcerpc_netr_GetAnyDCName failed: %s\n",
773 talloc_destroy(mem_ctx);
777 /* dcerpc_netr_GetAnyDCName gives us a name with \\ */
778 p = strip_hostname(tmp);
782 talloc_destroy(mem_ctx);
784 DEBUG(10,("dcerpc_netr_GetAnyDCName returned %s\n", dcname));
786 if (!resolve_name(dcname, dc_ss, 0x20, true)) {
794 * Helper function to assemble trust password and account name
796 static NTSTATUS get_trust_creds(const struct winbindd_domain *domain,
797 char **machine_password,
798 char **machine_account,
799 char **machine_krb5_principal)
801 const char *account_name;
802 const char *name = NULL;
804 /* If we are a DC and this is not our own domain */
809 struct winbindd_domain *our_domain = find_our_domain();
812 return NT_STATUS_INVALID_SERVER_STATE;
814 name = our_domain->name;
817 if (!get_trust_pw_clear(name, machine_password,
818 &account_name, NULL))
820 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
823 if ((machine_account != NULL) &&
824 (asprintf(machine_account, "%s$", account_name) == -1))
826 return NT_STATUS_NO_MEMORY;
829 /* For now assume our machine account only exists in our domain */
831 if (machine_krb5_principal != NULL)
833 struct winbindd_domain *our_domain = find_our_domain();
836 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
839 if (our_domain->alt_name == NULL) {
840 return NT_STATUS_INVALID_PARAMETER;
843 if (asprintf(machine_krb5_principal, "%s$@%s",
844 account_name, our_domain->alt_name) == -1)
846 return NT_STATUS_NO_MEMORY;
849 if (!strupper_m(*machine_krb5_principal)) {
850 SAFE_FREE(*machine_krb5_principal);
851 return NT_STATUS_INVALID_PARAMETER;
858 /************************************************************************
859 Given a fd with a just-connected TCP connection to a DC, open a connection
861 ************************************************************************/
863 static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
865 const char *controller,
866 struct cli_state **cli,
869 bool try_spnego = false;
870 bool try_ipc_auth = false;
871 char *machine_password = NULL;
872 char *machine_krb5_principal = NULL;
873 char *machine_account = NULL;
874 char *ipc_username = NULL;
875 char *ipc_domain = NULL;
876 char *ipc_password = NULL;
878 uint16_t sec_mode = 0;
880 struct named_mutex *mutex;
882 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
884 DEBUG(10,("cm_prepare_connection: connecting to DC %s for domain %s\n",
885 controller, domain->name ));
889 mutex = grab_named_mutex(talloc_tos(), controller,
890 WINBIND_SERVER_MUTEX_WAIT_TIME);
893 DEBUG(0,("cm_prepare_connection: mutex grab failed for %s\n",
895 result = NT_STATUS_POSSIBLE_DEADLOCK;
899 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
901 *cli = cli_state_create(NULL, sockfd,
902 controller, domain->alt_name,
903 SMB_SIGNING_DEFAULT, flags);
906 DEBUG(1, ("Could not cli_initialize\n"));
907 result = NT_STATUS_NO_MEMORY;
911 cli_set_timeout(*cli, 10000); /* 10 seconds */
913 result = smbXcli_negprot((*cli)->conn, (*cli)->timeout,
914 lp_client_min_protocol(),
915 lp_client_max_protocol());
917 if (!NT_STATUS_IS_OK(result)) {
918 DEBUG(1, ("cli_negprot failed: %s\n", nt_errstr(result)));
922 if (smbXcli_conn_protocol((*cli)->conn) >= PROTOCOL_NT1 &&
923 smb1cli_conn_capabilities((*cli)->conn) & CAP_EXTENDED_SECURITY) {
925 } else if (smbXcli_conn_protocol((*cli)->conn) >= PROTOCOL_SMB2_02) {
929 if (!is_dc_trusted_domain_situation(domain->name) && try_spnego) {
930 result = get_trust_creds(domain, &machine_password,
932 &machine_krb5_principal);
933 if (!NT_STATUS_IS_OK(result)) {
937 if (lp_security() == SEC_ADS) {
939 /* Try a krb5 session */
941 (*cli)->use_kerberos = True;
942 DEBUG(5, ("connecting to %s from %s with kerberos principal "
943 "[%s] and realm [%s]\n", controller, lp_netbios_name(),
944 machine_krb5_principal, domain->alt_name));
946 winbindd_set_locator_kdc_envs(domain);
948 result = cli_session_setup(*cli,
949 machine_krb5_principal,
951 strlen(machine_password)+1,
953 strlen(machine_password)+1,
956 if (!NT_STATUS_IS_OK(result)) {
957 DEBUG(4,("failed kerberos session setup with %s\n",
961 if (NT_STATUS_IS_OK(result)) {
962 /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
963 result = cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
964 if (!NT_STATUS_IS_OK(result)) {
967 goto session_setup_done;
971 /* Fall back to non-kerberos session setup using NTLMSSP SPNEGO with the machine account. */
972 (*cli)->use_kerberos = False;
974 DEBUG(5, ("connecting to %s from %s with username "
975 "[%s]\\[%s]\n", controller, lp_netbios_name(),
976 lp_workgroup(), machine_account));
978 result = cli_session_setup(*cli,
981 strlen(machine_password)+1,
983 strlen(machine_password)+1,
985 if (!NT_STATUS_IS_OK(result)) {
986 DEBUG(4, ("authenticated session setup failed with %s\n",
990 if (NT_STATUS_IS_OK(result)) {
991 /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
992 result = cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
993 if (!NT_STATUS_IS_OK(result)) {
996 goto session_setup_done;
1000 /* Fall back to non-kerberos session setup with auth_user */
1002 (*cli)->use_kerberos = False;
1004 cm_get_ipc_userpass(&ipc_username, &ipc_domain, &ipc_password);
1006 sec_mode = smb1cli_conn_server_security_mode((*cli)->conn);
1008 try_ipc_auth = false;
1010 try_ipc_auth = true;
1011 } else if (sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) {
1012 try_ipc_auth = true;
1015 if (try_ipc_auth && (strlen(ipc_username) > 0)) {
1017 /* Only try authenticated if we have a username */
1019 DEBUG(5, ("connecting to %s from %s with username "
1020 "[%s]\\[%s]\n", controller, lp_netbios_name(),
1021 ipc_domain, ipc_username));
1023 if (NT_STATUS_IS_OK(cli_session_setup(
1025 ipc_password, strlen(ipc_password)+1,
1026 ipc_password, strlen(ipc_password)+1,
1028 /* Successful logon with given username. */
1029 result = cli_init_creds(*cli, ipc_username, ipc_domain, ipc_password);
1030 if (!NT_STATUS_IS_OK(result)) {
1033 goto session_setup_done;
1035 DEBUG(4, ("authenticated session setup with user %s\\%s failed.\n",
1036 ipc_domain, ipc_username ));
1042 /* Fall back to anonymous connection, this might fail later */
1043 DEBUG(10,("cm_prepare_connection: falling back to anonymous "
1044 "connection for DC %s\n",
1047 result = cli_session_setup(*cli, "", NULL, 0, NULL, 0, "");
1048 if (NT_STATUS_IS_OK(result)) {
1049 DEBUG(5, ("Connected anonymously\n"));
1050 result = cli_init_creds(*cli, "", "", "");
1051 if (!NT_STATUS_IS_OK(result)) {
1054 goto session_setup_done;
1057 /* We can't session setup */
1063 * This should be a short term hack until
1064 * dynamic re-authentication is implemented.
1066 * See Bug 9175 - winbindd doesn't recover from
1067 * NT_STATUS_NETWORK_SESSION_EXPIRED
1069 if (smbXcli_conn_protocol((*cli)->conn) >= PROTOCOL_SMB2_02) {
1070 smbXcli_session_set_disconnect_expired((*cli)->smb2.session);
1073 /* cache the server name for later connections */
1075 saf_store(domain->name, controller);
1076 if (domain->alt_name && (*cli)->use_kerberos) {
1077 saf_store(domain->alt_name, controller);
1080 winbindd_set_locator_kdc_envs(domain);
1082 result = cli_tree_connect(*cli, "IPC$", "IPC", "", 0);
1084 if (!NT_STATUS_IS_OK(result)) {
1085 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(result)));
1092 /* set the domain if empty; needed for schannel connections */
1093 if ( !(*cli)->domain[0] ) {
1094 result = cli_set_domain((*cli), domain->name);
1095 if (!NT_STATUS_IS_OK(result)) {
1096 SAFE_FREE(ipc_username);
1097 SAFE_FREE(ipc_domain);
1098 SAFE_FREE(ipc_password);
1103 result = NT_STATUS_OK;
1107 SAFE_FREE(machine_account);
1108 SAFE_FREE(machine_password);
1109 SAFE_FREE(machine_krb5_principal);
1110 SAFE_FREE(ipc_username);
1111 SAFE_FREE(ipc_domain);
1112 SAFE_FREE(ipc_password);
1114 if (!NT_STATUS_IS_OK(result)) {
1115 winbind_add_failed_connection_entry(domain, controller, result);
1116 if ((*cli) != NULL) {
1125 /*******************************************************************
1126 Add a dcname and sockaddr_storage pair to the end of a dc_name_ip
1129 Keeps the list unique by not adding duplicate entries.
1131 @param[in] mem_ctx talloc memory context to allocate from
1132 @param[in] domain_name domain of the DC
1133 @param[in] dcname name of the DC to add to the list
1134 @param[in] pss Internet address and port pair to add to the list
1135 @param[in,out] dcs array of dc_name_ip structures to add to
1136 @param[in,out] num_dcs number of dcs returned in the dcs array
1137 @return true if the list was added to, false otherwise
1138 *******************************************************************/
1140 static bool add_one_dc_unique(TALLOC_CTX *mem_ctx, const char *domain_name,
1141 const char *dcname, struct sockaddr_storage *pss,
1142 struct dc_name_ip **dcs, int *num)
1146 if (!NT_STATUS_IS_OK(check_negative_conn_cache(domain_name, dcname))) {
1147 DEBUG(10, ("DC %s was in the negative conn cache\n", dcname));
1151 /* Make sure there's no duplicates in the list */
1152 for (i=0; i<*num; i++)
1154 (struct sockaddr *)(void *)&(*dcs)[i].ss,
1155 (struct sockaddr *)(void *)pss))
1158 *dcs = talloc_realloc(mem_ctx, *dcs, struct dc_name_ip, (*num)+1);
1163 fstrcpy((*dcs)[*num].name, dcname);
1164 (*dcs)[*num].ss = *pss;
1169 static bool add_sockaddr_to_array(TALLOC_CTX *mem_ctx,
1170 struct sockaddr_storage *pss, uint16 port,
1171 struct sockaddr_storage **addrs, int *num)
1173 *addrs = talloc_realloc(mem_ctx, *addrs, struct sockaddr_storage, (*num)+1);
1175 if (*addrs == NULL) {
1180 (*addrs)[*num] = *pss;
1181 set_sockaddr_port((struct sockaddr *)&(*addrs)[*num], port);
1187 /*******************************************************************
1188 convert an ip to a name
1189 *******************************************************************/
1191 static bool dcip_to_name(TALLOC_CTX *mem_ctx,
1192 const struct winbindd_domain *domain,
1193 struct sockaddr_storage *pss,
1196 struct ip_service ip_list;
1197 uint32_t nt_version = NETLOGON_NT_VERSION_1;
1199 const char *dc_name;
1206 /* For active directory servers, try to get the ldap server name.
1207 None of these failures should be considered critical for now */
1209 if ((lp_security() == SEC_ADS) && (domain->alt_name != NULL)) {
1211 ADS_STATUS ads_status;
1212 char addr[INET6_ADDRSTRLEN];
1214 print_sockaddr(addr, sizeof(addr), pss);
1216 ads = ads_init(domain->alt_name, domain->name, addr);
1217 ads->auth.flags |= ADS_AUTH_NO_BIND;
1219 ads_status = ads_connect(ads);
1220 if (ADS_ERR_OK(ads_status)) {
1221 /* We got a cldap packet. */
1222 *name = talloc_strdup(mem_ctx,
1223 ads->config.ldap_server_name);
1224 if (*name == NULL) {
1227 namecache_store(*name, 0x20, 1, &ip_list);
1229 DEBUG(10,("dcip_to_name: flags = 0x%x\n", (unsigned int)ads->config.flags));
1231 if (domain->primary && (ads->config.flags & NBT_SERVER_KDC)) {
1232 if (ads_closest_dc(ads)) {
1233 char *sitename = sitename_fetch(mem_ctx, ads->config.realm);
1235 /* We're going to use this KDC for this realm/domain.
1236 If we are using sites, then force the krb5 libs
1239 create_local_private_krb5_conf_for_domain(domain->alt_name,
1244 TALLOC_FREE(sitename);
1246 /* use an off site KDC */
1247 create_local_private_krb5_conf_for_domain(domain->alt_name,
1252 winbindd_set_locator_kdc_envs(domain);
1254 /* Ensure we contact this DC also. */
1255 saf_store(domain->name, *name);
1256 saf_store(domain->alt_name, *name);
1259 ads_destroy( &ads );
1263 ads_destroy( &ads );
1268 status = nbt_getdc(winbind_messaging_context(), 10, pss, domain->name,
1269 &domain->sid, nt_version, mem_ctx, &nt_version,
1271 if (NT_STATUS_IS_OK(status)) {
1272 *name = talloc_strdup(mem_ctx, dc_name);
1273 if (*name == NULL) {
1276 namecache_store(*name, 0x20, 1, &ip_list);
1280 /* try node status request */
1282 if (name_status_find(domain->name, 0x1c, 0x20, pss, nbtname) ) {
1283 namecache_store(nbtname, 0x20, 1, &ip_list);
1286 *name = talloc_strdup(mem_ctx, nbtname);
1287 if (*name == NULL) {
1297 /*******************************************************************
1298 Retrieve a list of IP addresses for domain controllers.
1300 The array is sorted in the preferred connection order.
1302 @param[in] mem_ctx talloc memory context to allocate from
1303 @param[in] domain domain to retrieve DCs for
1304 @param[out] dcs array of dcs that will be returned
1305 @param[out] num_dcs number of dcs returned in the dcs array
1307 *******************************************************************/
1309 static bool get_dcs(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
1310 struct dc_name_ip **dcs, int *num_dcs)
1313 struct sockaddr_storage ss;
1314 struct ip_service *ip_list = NULL;
1315 int iplist_size = 0;
1318 enum security_types sec = (enum security_types)lp_security();
1320 is_our_domain = strequal(domain->name, lp_workgroup());
1322 /* If not our domain, get the preferred DC, by asking our primary DC */
1324 && get_dc_name_via_netlogon(domain, dcname, &ss)
1325 && add_one_dc_unique(mem_ctx, domain->name, dcname, &ss, dcs,
1328 char addr[INET6_ADDRSTRLEN];
1329 print_sockaddr(addr, sizeof(addr), &ss);
1330 DEBUG(10, ("Retrieved DC %s at %s via netlogon\n",
1335 if ((sec == SEC_ADS) && (domain->alt_name != NULL)) {
1336 char *sitename = NULL;
1338 /* We need to make sure we know the local site before
1339 doing any DNS queries, as this will restrict the
1340 get_sorted_dc_list() call below to only fetching
1341 DNS records for the correct site. */
1343 /* Find any DC to get the site record.
1344 We deliberately don't care about the
1347 get_dc_name(domain->name, domain->alt_name, dcname, &ss);
1349 sitename = sitename_fetch(mem_ctx, domain->alt_name);
1352 /* Do the site-specific AD dns lookup first. */
1353 get_sorted_dc_list(domain->alt_name, sitename, &ip_list,
1354 &iplist_size, True);
1356 /* Add ips to the DC array. We don't look up the name
1357 of the DC in this function, but we fill in the char*
1358 of the ip now to make the failed connection cache
1360 for ( i=0; i<iplist_size; i++ ) {
1361 char addr[INET6_ADDRSTRLEN];
1362 print_sockaddr(addr, sizeof(addr),
1364 add_one_dc_unique(mem_ctx,
1373 TALLOC_FREE(sitename);
1377 /* Now we add DCs from the main AD DNS lookup. */
1378 get_sorted_dc_list(domain->alt_name, NULL, &ip_list,
1379 &iplist_size, True);
1381 for ( i=0; i<iplist_size; i++ ) {
1382 char addr[INET6_ADDRSTRLEN];
1383 print_sockaddr(addr, sizeof(addr),
1385 add_one_dc_unique(mem_ctx,
1397 /* Try standard netbios queries if no ADS and fall back to DNS queries
1398 * if alt_name is available */
1399 if (*num_dcs == 0) {
1400 get_sorted_dc_list(domain->name, NULL, &ip_list, &iplist_size,
1402 if (iplist_size == 0) {
1403 if (domain->alt_name != NULL) {
1404 get_sorted_dc_list(domain->alt_name, NULL, &ip_list,
1405 &iplist_size, true);
1409 for ( i=0; i<iplist_size; i++ ) {
1410 char addr[INET6_ADDRSTRLEN];
1411 print_sockaddr(addr, sizeof(addr),
1413 add_one_dc_unique(mem_ctx,
1428 /*******************************************************************
1429 Find and make a connection to a DC in the given domain.
1431 @param[in] mem_ctx talloc memory context to allocate from
1432 @param[in] domain domain to find a dc in
1433 @param[out] dcname NetBIOS or FQDN of DC that's connected to
1434 @param[out] pss DC Internet address and port
1435 @param[out] fd fd of the open socket connected to the newly found dc
1436 @return true when a DC connection is made, false otherwise
1437 *******************************************************************/
1439 static bool find_new_dc(TALLOC_CTX *mem_ctx,
1440 struct winbindd_domain *domain,
1441 char **dcname, struct sockaddr_storage *pss, int *fd)
1443 struct dc_name_ip *dcs = NULL;
1446 const char **dcnames = NULL;
1447 int num_dcnames = 0;
1449 struct sockaddr_storage *addrs = NULL;
1460 if (!get_dcs(mem_ctx, domain, &dcs, &num_dcs) || (num_dcs == 0))
1463 for (i=0; i<num_dcs; i++) {
1465 if (!add_string_to_array(mem_ctx, dcs[i].name,
1466 &dcnames, &num_dcnames)) {
1469 if (!add_sockaddr_to_array(mem_ctx, &dcs[i].ss, TCP_SMB_PORT,
1470 &addrs, &num_addrs)) {
1475 if ((num_dcnames == 0) || (num_dcnames != num_addrs))
1478 if ((addrs == NULL) || (dcnames == NULL))
1481 status = smbsock_any_connect(addrs, dcnames, NULL, NULL, NULL,
1482 num_addrs, 0, 10, fd, &fd_index, NULL);
1483 if (!NT_STATUS_IS_OK(status)) {
1484 for (i=0; i<num_dcs; i++) {
1485 char ab[INET6_ADDRSTRLEN];
1486 print_sockaddr(ab, sizeof(ab), &dcs[i].ss);
1487 DEBUG(10, ("find_new_dc: smbsock_any_connect failed for "
1488 "domain %s address %s. Error was %s\n",
1489 domain->name, ab, nt_errstr(status) ));
1490 winbind_add_failed_connection_entry(domain,
1491 dcs[i].name, NT_STATUS_UNSUCCESSFUL);
1496 *pss = addrs[fd_index];
1498 if (*dcnames[fd_index] != '\0' && !is_ipaddress(dcnames[fd_index])) {
1499 /* Ok, we've got a name for the DC */
1500 *dcname = talloc_strdup(mem_ctx, dcnames[fd_index]);
1501 if (*dcname == NULL) {
1507 /* Try to figure out the name */
1508 if (dcip_to_name(mem_ctx, domain, pss, dcname)) {
1512 /* We can not continue without the DC's name */
1513 winbind_add_failed_connection_entry(domain, dcs[fd_index].name,
1514 NT_STATUS_UNSUCCESSFUL);
1516 /* Throw away all arrays as we're doing this again. */
1520 TALLOC_FREE(dcnames);
1532 static char *current_dc_key(TALLOC_CTX *mem_ctx, const char *domain_name)
1534 return talloc_asprintf_strupper_m(mem_ctx, "CURRENT_DCNAME/%s",
1538 static void store_current_dc_in_gencache(const char *domain_name,
1539 const char *dc_name,
1540 struct cli_state *cli)
1542 char addr[INET6_ADDRSTRLEN];
1546 if (!cli_state_is_connected(cli)) {
1550 print_sockaddr(addr, sizeof(addr),
1551 smbXcli_conn_remote_sockaddr(cli->conn));
1553 key = current_dc_key(talloc_tos(), domain_name);
1558 value = talloc_asprintf(talloc_tos(), "%s %s", addr, dc_name);
1559 if (value == NULL) {
1563 gencache_set(key, value, 0x7fffffff);
1569 bool fetch_current_dc_from_gencache(TALLOC_CTX *mem_ctx,
1570 const char *domain_name,
1571 char **p_dc_name, char **p_dc_ip)
1576 char *dc_name = NULL;
1579 key = current_dc_key(talloc_tos(), domain_name);
1583 if (!gencache_get(key, mem_ctx, &value, NULL)) {
1586 p = strchr(value, ' ');
1590 dc_ip = talloc_strndup(mem_ctx, value, p - value);
1591 if (dc_ip == NULL) {
1594 dc_name = talloc_strdup(mem_ctx, p+1);
1595 if (dc_name == NULL) {
1599 if (p_dc_ip != NULL) {
1603 if (p_dc_name != NULL) {
1604 *p_dc_name = dc_name;
1609 TALLOC_FREE(dc_name);
1616 NTSTATUS wb_open_internal_pipe(TALLOC_CTX *mem_ctx,
1617 const struct ndr_interface_table *table,
1618 struct rpc_pipe_client **ret_pipe)
1620 struct rpc_pipe_client *cli = NULL;
1621 const struct auth_session_info *session_info;
1622 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1625 session_info = get_session_info_system();
1626 SMB_ASSERT(session_info != NULL);
1628 /* create a connection to the specified pipe */
1629 if (lp_parm_bool(-1, "winbindd", "use external pipes", false)) {
1630 status = rpc_pipe_open_interface(mem_ctx,
1634 winbind_messaging_context(),
1637 status = rpc_pipe_open_internal(mem_ctx,
1641 winbind_messaging_context(),
1644 if (!NT_STATUS_IS_OK(status)) {
1645 DEBUG(0, ("open_internal_pipe: Could not connect to %s pipe: %s\n",
1646 table->name, nt_errstr(status)));
1654 return NT_STATUS_OK;
1657 static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
1658 struct winbindd_cm_conn *new_conn)
1660 TALLOC_CTX *mem_ctx;
1662 char *saf_servername;
1665 if ((mem_ctx = talloc_init("cm_open_connection")) == NULL) {
1666 set_domain_offline(domain);
1667 return NT_STATUS_NO_MEMORY;
1670 saf_servername = saf_fetch(mem_ctx, domain->name );
1672 /* we have to check the server affinity cache here since
1673 later we select a DC based on response time and not preference */
1675 /* Check the negative connection cache
1676 before talking to it. It going down may have
1677 triggered the reconnection. */
1679 if ( saf_servername && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, saf_servername))) {
1681 DEBUG(10,("cm_open_connection: saf_servername is '%s' for domain %s\n",
1682 saf_servername, domain->name ));
1684 /* convert an ip address to a name */
1685 if (is_ipaddress( saf_servername ) ) {
1686 char *dcname = NULL;
1687 struct sockaddr_storage ss;
1689 if (!interpret_string_addr(&ss, saf_servername,
1691 TALLOC_FREE(mem_ctx);
1692 return NT_STATUS_UNSUCCESSFUL;
1694 if (dcip_to_name(mem_ctx, domain, &ss, &dcname)) {
1695 domain->dcname = talloc_strdup(domain,
1697 if (domain->dcname == NULL) {
1698 TALLOC_FREE(mem_ctx);
1699 return NT_STATUS_NO_MEMORY;
1702 winbind_add_failed_connection_entry(
1703 domain, saf_servername,
1704 NT_STATUS_UNSUCCESSFUL);
1707 domain->dcname = talloc_strdup(domain, saf_servername);
1708 if (domain->dcname == NULL) {
1709 TALLOC_FREE(mem_ctx);
1710 return NT_STATUS_NO_MEMORY;
1715 for (retries = 0; retries < 3; retries++) {
1718 char *dcname = NULL;
1720 result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1722 DEBUG(10,("cm_open_connection: dcname is '%s' for domain %s\n",
1723 domain->dcname ? domain->dcname : "", domain->name ));
1725 if (domain->dcname != NULL
1726 && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, domain->dcname))
1727 && (resolve_name(domain->dcname, &domain->dcaddr, 0x20, true)))
1731 status = smbsock_connect(&domain->dcaddr, 0,
1734 if (!NT_STATUS_IS_OK(status)) {
1740 !find_new_dc(mem_ctx, domain, &dcname, &domain->dcaddr, &fd))
1742 /* This is the one place where we will
1743 set the global winbindd offline state
1744 to true, if a "WINBINDD_OFFLINE" entry
1745 is found in the winbindd cache. */
1746 set_global_winbindd_state_offline();
1749 if (dcname != NULL) {
1750 talloc_free(domain->dcname);
1752 domain->dcname = talloc_move(domain, &dcname);
1753 if (domain->dcname == NULL) {
1754 result = NT_STATUS_NO_MEMORY;
1759 new_conn->cli = NULL;
1761 result = cm_prepare_connection(domain, fd, domain->dcname,
1762 &new_conn->cli, &retry);
1763 if (!NT_STATUS_IS_OK(result)) {
1764 /* Don't leak the smb connection socket */
1772 if (NT_STATUS_IS_OK(result)) {
1773 bool seal_pipes = true;
1775 winbindd_set_locator_kdc_envs(domain);
1777 if (domain->online == False) {
1778 /* We're changing state from offline to online. */
1779 set_global_winbindd_state_online();
1781 set_domain_online(domain);
1784 * Much as I hate global state, this seems to be the point
1785 * where we can be certain that we have a proper connection to
1786 * a DC. wbinfo --dc-info needs that information, store it in
1787 * gencache with a looong timeout. This will need revisiting
1788 * once we start to connect to multiple DCs, wbcDcInfo is
1789 * already prepared for that.
1791 store_current_dc_in_gencache(domain->name, domain->dcname,
1794 seal_pipes = lp_winbind_sealed_pipes();
1795 seal_pipes = lp_parm_bool(-1, "winbind sealed pipes",
1800 new_conn->auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
1802 new_conn->auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
1805 /* Ensure we setup the retry handler. */
1806 set_domain_offline(domain);
1809 talloc_destroy(mem_ctx);
1813 /* Close down all open pipes on a connection. */
1815 void invalidate_cm_connection(struct winbindd_cm_conn *conn)
1819 /* We're closing down a possibly dead
1820 connection. Don't have impossibly long (10s) timeouts. */
1823 cli_set_timeout(conn->cli, 1000); /* 1 second. */
1826 if (conn->samr_pipe != NULL) {
1827 if (is_valid_policy_hnd(&conn->sam_connect_handle)) {
1828 dcerpc_samr_Close(conn->samr_pipe->binding_handle,
1830 &conn->sam_connect_handle,
1833 TALLOC_FREE(conn->samr_pipe);
1834 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1836 cli_set_timeout(conn->cli, 500);
1840 if (conn->lsa_pipe != NULL) {
1841 if (is_valid_policy_hnd(&conn->lsa_policy)) {
1842 dcerpc_lsa_Close(conn->lsa_pipe->binding_handle,
1847 TALLOC_FREE(conn->lsa_pipe);
1848 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1850 cli_set_timeout(conn->cli, 500);
1854 if (conn->lsa_pipe_tcp != NULL) {
1855 if (is_valid_policy_hnd(&conn->lsa_policy)) {
1856 dcerpc_lsa_Close(conn->lsa_pipe_tcp->binding_handle,
1861 TALLOC_FREE(conn->lsa_pipe_tcp);
1862 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1864 cli_set_timeout(conn->cli, 500);
1868 if (conn->netlogon_pipe != NULL) {
1869 TALLOC_FREE(conn->netlogon_pipe);
1870 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1872 cli_set_timeout(conn->cli, 500);
1876 conn->auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
1877 conn->netlogon_force_reauth = false;
1878 conn->netlogon_flags = 0;
1879 TALLOC_FREE(conn->netlogon_creds);
1882 cli_shutdown(conn->cli);
1888 void close_conns_after_fork(void)
1890 struct winbindd_domain *domain;
1891 struct winbindd_cli_state *cli_state;
1893 for (domain = domain_list(); domain; domain = domain->next) {
1895 * first close the low level SMB TCP connection
1896 * so that we don't generate any SMBclose
1897 * requests in invalidate_cm_connection()
1899 if (cli_state_is_connected(domain->conn.cli)) {
1900 smbXcli_conn_disconnect(domain->conn.cli->conn, NT_STATUS_OK);
1903 invalidate_cm_connection(&domain->conn);
1906 for (cli_state = winbindd_client_list();
1908 cli_state = cli_state->next) {
1909 if (cli_state->sock >= 0) {
1910 close(cli_state->sock);
1911 cli_state->sock = -1;
1916 static bool connection_ok(struct winbindd_domain *domain)
1920 ok = cli_state_is_connected(domain->conn.cli);
1922 DEBUG(3, ("connection_ok: Connection to %s for domain %s is not connected\n",
1923 domain->dcname, domain->name));
1927 if (domain->online == False) {
1928 DEBUG(3, ("connection_ok: Domain %s is offline\n", domain->name));
1935 /* Initialize a new connection up to the RPC BIND.
1936 Bypass online status check so always does network calls. */
1938 static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain, bool need_rw_dc)
1941 bool skip_connection = domain->internal;
1942 if (need_rw_dc && domain->rodc) {
1943 skip_connection = false;
1946 /* Internal connections never use the network. */
1947 if (dom_sid_equal(&domain->sid, &global_sid_Builtin)) {
1948 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1951 /* Still ask the internal LSA and SAMR server about the local domain */
1952 if (skip_connection || connection_ok(domain)) {
1953 if (!domain->initialized) {
1954 set_dc_type_and_flags(domain);
1956 return NT_STATUS_OK;
1959 invalidate_cm_connection(&domain->conn);
1961 result = cm_open_connection(domain, &domain->conn);
1963 if (NT_STATUS_IS_OK(result) && !domain->initialized) {
1964 set_dc_type_and_flags(domain);
1970 NTSTATUS init_dc_connection(struct winbindd_domain *domain, bool need_rw_dc)
1972 if (dom_sid_equal(&domain->sid, &global_sid_Builtin)) {
1973 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1976 if (domain->initialized && !domain->online) {
1977 /* We check for online status elsewhere. */
1978 return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1981 return init_dc_connection_network(domain, need_rw_dc);
1984 static NTSTATUS init_dc_connection_rpc(struct winbindd_domain *domain, bool need_rw_dc)
1988 status = init_dc_connection(domain, need_rw_dc);
1989 if (!NT_STATUS_IS_OK(status)) {
1993 if (!domain->internal && domain->conn.cli == NULL) {
1994 /* happens for trusted domains without inbound trust */
1995 return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
1998 return NT_STATUS_OK;
2001 /******************************************************************************
2002 Set the trust flags (direction and forest location) for a domain
2003 ******************************************************************************/
2005 static bool set_dc_type_and_flags_trustinfo( struct winbindd_domain *domain )
2007 struct winbindd_domain *our_domain;
2008 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2010 struct netr_DomainTrustList trusts;
2012 uint32 flags = (NETR_TRUST_FLAG_IN_FOREST |
2013 NETR_TRUST_FLAG_OUTBOUND |
2014 NETR_TRUST_FLAG_INBOUND);
2015 struct rpc_pipe_client *cli;
2016 TALLOC_CTX *mem_ctx = NULL;
2017 struct dcerpc_binding_handle *b;
2019 DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s\n", domain->name ));
2021 /* Our primary domain doesn't need to worry about trust flags.
2022 Force it to go through the network setup */
2023 if ( domain->primary ) {
2027 mem_ctx = talloc_stackframe();
2028 our_domain = find_our_domain();
2029 if (our_domain->internal) {
2030 result = init_dc_connection(our_domain, false);
2031 if (!NT_STATUS_IS_OK(result)) {
2032 DEBUG(3,("set_dc_type_and_flags_trustinfo: "
2033 "Not able to make a connection to our domain: %s\n",
2034 nt_errstr(result)));
2035 TALLOC_FREE(mem_ctx);
2040 /* This won't work unless our domain is AD */
2041 if ( !our_domain->active_directory ) {
2042 TALLOC_FREE(mem_ctx);
2046 if (our_domain->internal) {
2047 result = wb_open_internal_pipe(mem_ctx, &ndr_table_netlogon, &cli);
2048 } else if (!connection_ok(our_domain)) {
2049 DEBUG(3,("set_dc_type_and_flags_trustinfo: "
2050 "No connection to our domain!\n"));
2051 TALLOC_FREE(mem_ctx);
2054 result = cm_connect_netlogon(our_domain, &cli);
2057 if (!NT_STATUS_IS_OK(result)) {
2058 DEBUG(5, ("set_dc_type_and_flags_trustinfo: Could not open "
2059 "a connection to %s for PIPE_NETLOGON (%s)\n",
2060 domain->name, nt_errstr(result)));
2061 TALLOC_FREE(mem_ctx);
2064 b = cli->binding_handle;
2066 /* Use DsEnumerateDomainTrusts to get us the trust direction and type. */
2067 result = dcerpc_netr_DsrEnumerateDomainTrusts(b, mem_ctx,
2072 if (!NT_STATUS_IS_OK(result)) {
2073 DEBUG(0,("set_dc_type_and_flags_trustinfo: "
2074 "failed to query trusted domain list: %s\n",
2075 nt_errstr(result)));
2076 TALLOC_FREE(mem_ctx);
2079 if (!W_ERROR_IS_OK(werr)) {
2080 DEBUG(0,("set_dc_type_and_flags_trustinfo: "
2081 "failed to query trusted domain list: %s\n",
2083 TALLOC_FREE(mem_ctx);
2087 /* Now find the domain name and get the flags */
2089 for ( i=0; i<trusts.count; i++ ) {
2090 if ( strequal( domain->name, trusts.array[i].netbios_name) ) {
2091 domain->domain_flags = trusts.array[i].trust_flags;
2092 domain->domain_type = trusts.array[i].trust_type;
2093 domain->domain_trust_attribs = trusts.array[i].trust_attributes;
2095 if ( domain->domain_type == LSA_TRUST_TYPE_UPLEVEL )
2096 domain->active_directory = True;
2098 /* This flag is only set if the domain is *our*
2099 primary domain and the primary domain is in
2102 domain->native_mode = (domain->domain_flags & NETR_TRUST_FLAG_NATIVE);
2104 DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s is %sin "
2105 "native mode.\n", domain->name,
2106 domain->native_mode ? "" : "NOT "));
2108 DEBUG(5,("set_dc_type_and_flags_trustinfo: domain %s is %s"
2109 "running active directory.\n", domain->name,
2110 domain->active_directory ? "" : "NOT "));
2112 domain->can_do_ncacn_ip_tcp = domain->active_directory;
2114 domain->initialized = True;
2120 TALLOC_FREE(mem_ctx);
2122 return domain->initialized;
2125 /******************************************************************************
2126 We can 'sense' certain things about the DC by it's replies to certain
2129 This tells us if this particular remote server is Active Directory, and if it
2131 ******************************************************************************/
2133 static void set_dc_type_and_flags_connect( struct winbindd_domain *domain )
2135 NTSTATUS status, result;
2137 TALLOC_CTX *mem_ctx = NULL;
2138 struct rpc_pipe_client *cli = NULL;
2139 struct policy_handle pol;
2140 union dssetup_DsRoleInfo info;
2141 union lsa_PolicyInformation *lsa_info = NULL;
2143 if (!domain->internal && !connection_ok(domain)) {
2147 mem_ctx = talloc_init("set_dc_type_and_flags on domain %s\n",
2150 DEBUG(1, ("set_dc_type_and_flags_connect: talloc_init() failed\n"));
2154 DEBUG(5, ("set_dc_type_and_flags_connect: domain %s\n", domain->name ));
2156 if (domain->internal) {
2157 status = wb_open_internal_pipe(mem_ctx,
2161 status = cli_rpc_pipe_open_noauth(domain->conn.cli,
2166 if (!NT_STATUS_IS_OK(status)) {
2167 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
2168 "PI_DSSETUP on domain %s: (%s)\n",
2169 domain->name, nt_errstr(status)));
2171 /* if this is just a non-AD domain we need to continue
2172 * identifying so that we can in the end return with
2173 * domain->initialized = True - gd */
2178 status = dcerpc_dssetup_DsRoleGetPrimaryDomainInformation(cli->binding_handle, mem_ctx,
2179 DS_ROLE_BASIC_INFORMATION,
2184 if (NT_STATUS_IS_OK(status)) {
2185 result = werror_to_ntstatus(werr);
2187 if (!NT_STATUS_IS_OK(status)) {
2188 DEBUG(5, ("set_dc_type_and_flags_connect: rpccli_ds_getprimarydominfo "
2189 "on domain %s failed: (%s)\n",
2190 domain->name, nt_errstr(status)));
2192 /* older samba3 DCs will return DCERPC_FAULT_OP_RNG_ERROR for
2193 * every opcode on the DSSETUP pipe, continue with
2194 * no_dssetup mode here as well to get domain->initialized
2197 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
2201 TALLOC_FREE(mem_ctx);
2205 if ((info.basic.flags & DS_ROLE_PRIMARY_DS_RUNNING) &&
2206 !(info.basic.flags & DS_ROLE_PRIMARY_DS_MIXED_MODE)) {
2207 domain->native_mode = True;
2209 domain->native_mode = False;
2213 if (domain->internal) {
2214 status = wb_open_internal_pipe(mem_ctx,
2218 status = cli_rpc_pipe_open_noauth(domain->conn.cli,
2219 &ndr_table_lsarpc, &cli);
2221 if (!NT_STATUS_IS_OK(status)) {
2222 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
2223 "PI_LSARPC on domain %s: (%s)\n",
2224 domain->name, nt_errstr(status)));
2226 TALLOC_FREE(mem_ctx);
2230 status = rpccli_lsa_open_policy2(cli, mem_ctx, True,
2231 SEC_FLAG_MAXIMUM_ALLOWED, &pol);
2233 if (NT_STATUS_IS_OK(status)) {
2234 /* This particular query is exactly what Win2k clients use
2235 to determine that the DC is active directory */
2236 status = dcerpc_lsa_QueryInfoPolicy2(cli->binding_handle, mem_ctx,
2238 LSA_POLICY_INFO_DNS,
2243 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2244 domain->active_directory = True;
2246 if (lsa_info->dns.name.string) {
2247 talloc_free(domain->name);
2248 domain->name = talloc_strdup(domain,
2249 lsa_info->dns.name.string);
2250 if (domain->name == NULL) {
2255 if (lsa_info->dns.dns_domain.string) {
2256 talloc_free(domain->alt_name);
2258 talloc_strdup(domain,
2259 lsa_info->dns.dns_domain.string);
2260 if (domain->alt_name == NULL) {
2265 /* See if we can set some domain trust flags about
2268 if (lsa_info->dns.dns_forest.string) {
2269 talloc_free(domain->forest_name);
2270 domain->forest_name =
2271 talloc_strdup(domain,
2272 lsa_info->dns.dns_forest.string);
2273 if (domain->forest_name == NULL) {
2277 if (strequal(domain->forest_name, domain->alt_name)) {
2278 domain->domain_flags |= NETR_TRUST_FLAG_TREEROOT;
2282 if (lsa_info->dns.sid) {
2283 sid_copy(&domain->sid, lsa_info->dns.sid);
2286 domain->active_directory = False;
2288 status = rpccli_lsa_open_policy(cli, mem_ctx, True,
2289 SEC_FLAG_MAXIMUM_ALLOWED,
2292 if (!NT_STATUS_IS_OK(status)) {
2296 status = dcerpc_lsa_QueryInfoPolicy(cli->binding_handle, mem_ctx,
2298 LSA_POLICY_INFO_ACCOUNT_DOMAIN,
2301 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2303 if (lsa_info->account_domain.name.string) {
2304 talloc_free(domain->name);
2306 talloc_strdup(domain,
2307 lsa_info->account_domain.name.string);
2310 if (lsa_info->account_domain.sid) {
2311 sid_copy(&domain->sid, lsa_info->account_domain.sid);
2317 DEBUG(5, ("set_dc_type_and_flags_connect: domain %s is %sin native mode.\n",
2318 domain->name, domain->native_mode ? "" : "NOT "));
2320 DEBUG(5,("set_dc_type_and_flags_connect: domain %s is %srunning active directory.\n",
2321 domain->name, domain->active_directory ? "" : "NOT "));
2323 domain->can_do_ncacn_ip_tcp = domain->active_directory;
2327 TALLOC_FREE(mem_ctx);
2329 domain->initialized = True;
2332 /**********************************************************************
2333 Set the domain_flags (trust attributes, domain operating modes, etc...
2334 ***********************************************************************/
2336 static void set_dc_type_and_flags( struct winbindd_domain *domain )
2338 /* we always have to contact our primary domain */
2340 if ( domain->primary || domain->internal) {
2341 DEBUG(10,("set_dc_type_and_flags: setting up flags for "
2342 "primary or internal domain\n"));
2343 set_dc_type_and_flags_connect( domain );
2347 /* Use our DC to get the information if possible */
2349 if ( !set_dc_type_and_flags_trustinfo( domain ) ) {
2350 /* Otherwise, fallback to contacting the
2352 set_dc_type_and_flags_connect( domain );
2360 /**********************************************************************
2361 ***********************************************************************/
2363 static NTSTATUS cm_get_schannel_creds(struct winbindd_domain *domain,
2364 struct netlogon_creds_cli_context **ppdc)
2366 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2367 struct rpc_pipe_client *netlogon_pipe;
2371 if ((!IS_DC) && (!domain->primary)) {
2372 return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
2375 if (domain->conn.netlogon_creds != NULL) {
2376 if (!(domain->conn.netlogon_flags & NETLOGON_NEG_AUTHENTICATED_RPC)) {
2377 return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
2379 *ppdc = domain->conn.netlogon_creds;
2380 return NT_STATUS_OK;
2383 result = cm_connect_netlogon(domain, &netlogon_pipe);
2384 if (!NT_STATUS_IS_OK(result)) {
2388 if (domain->conn.netlogon_creds == NULL) {
2389 return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
2392 if (!(domain->conn.netlogon_flags & NETLOGON_NEG_AUTHENTICATED_RPC)) {
2393 return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
2396 *ppdc = domain->conn.netlogon_creds;
2397 return NT_STATUS_OK;
2400 NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
2402 struct rpc_pipe_client **cli, struct policy_handle *sam_handle)
2404 struct winbindd_cm_conn *conn;
2405 NTSTATUS status, result;
2406 struct netlogon_creds_cli_context *p_creds;
2407 char *machine_password = NULL;
2408 char *machine_account = NULL;
2409 const char *domain_name = NULL;
2411 if (sid_check_is_our_sam(&domain->sid)) {
2412 if (domain->rodc == false || need_rw_dc == false) {
2413 return open_internal_samr_conn(mem_ctx, domain, cli, sam_handle);
2417 status = init_dc_connection_rpc(domain, need_rw_dc);
2418 if (!NT_STATUS_IS_OK(status)) {
2422 conn = &domain->conn;
2424 if (rpccli_is_connected(conn->samr_pipe)) {
2428 TALLOC_FREE(conn->samr_pipe);
2431 * No SAMR pipe yet. Attempt to get an NTLMSSP SPNEGO authenticated
2432 * sign and sealed pipe using the machine account password by
2433 * preference. If we can't - try schannel, if that fails, try
2437 if ((conn->cli->user_name[0] == '\0') ||
2438 (conn->cli->domain[0] == '\0') ||
2439 (conn->cli->password == NULL || conn->cli->password[0] == '\0'))
2441 status = get_trust_creds(domain, &machine_password,
2442 &machine_account, NULL);
2443 if (!NT_STATUS_IS_OK(status)) {
2444 DEBUG(10, ("cm_connect_sam: No no user available for "
2445 "domain %s, trying schannel\n", conn->cli->domain));
2448 domain_name = domain->name;
2450 machine_password = SMB_STRDUP(conn->cli->password);
2451 machine_account = SMB_STRDUP(conn->cli->user_name);
2452 domain_name = conn->cli->domain;
2455 if (!machine_password || !machine_account) {
2456 status = NT_STATUS_NO_MEMORY;
2460 /* We have an authenticated connection. Use a NTLMSSP SPNEGO
2461 authenticated SAMR pipe with sign & seal. */
2462 status = cli_rpc_pipe_open_spnego(conn->cli,
2467 smbXcli_conn_remote_name(conn->cli->conn),
2473 if (!NT_STATUS_IS_OK(status)) {
2474 DEBUG(10,("cm_connect_sam: failed to connect to SAMR "
2475 "pipe for domain %s using NTLMSSP "
2476 "authenticated pipe: user %s\\%s. Error was "
2477 "%s\n", domain->name, domain_name,
2478 machine_account, nt_errstr(status)));
2482 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for "
2483 "domain %s using NTLMSSP authenticated "
2484 "pipe: user %s\\%s\n", domain->name,
2485 domain_name, machine_account));
2487 status = dcerpc_samr_Connect2(conn->samr_pipe->binding_handle, mem_ctx,
2488 conn->samr_pipe->desthost,
2489 SEC_FLAG_MAXIMUM_ALLOWED,
2490 &conn->sam_connect_handle,
2492 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2495 if (NT_STATUS_IS_OK(status)) {
2499 DEBUG(10,("cm_connect_sam: ntlmssp-sealed dcerpc_samr_Connect2 "
2500 "failed for domain %s, error was %s. Trying schannel\n",
2501 domain->name, nt_errstr(status) ));
2502 TALLOC_FREE(conn->samr_pipe);
2506 /* Fall back to schannel if it's a W2K pre-SP1 box. */
2508 status = cm_get_schannel_creds(domain, &p_creds);
2509 if (!NT_STATUS_IS_OK(status)) {
2510 /* If this call fails - conn->cli can now be NULL ! */
2511 DEBUG(10, ("cm_connect_sam: Could not get schannel auth info "
2512 "for domain %s (error %s), trying anon\n",
2514 nt_errstr(status) ));
2517 status = cli_rpc_pipe_open_schannel_with_key
2518 (conn->cli, &ndr_table_samr, NCACN_NP,
2519 domain->name, p_creds, &conn->samr_pipe);
2521 if (!NT_STATUS_IS_OK(status)) {
2522 DEBUG(10,("cm_connect_sam: failed to connect to SAMR pipe for "
2523 "domain %s using schannel. Error was %s\n",
2524 domain->name, nt_errstr(status) ));
2527 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for domain %s using "
2528 "schannel.\n", domain->name ));
2530 status = dcerpc_samr_Connect2(conn->samr_pipe->binding_handle, mem_ctx,
2531 conn->samr_pipe->desthost,
2532 SEC_FLAG_MAXIMUM_ALLOWED,
2533 &conn->sam_connect_handle,
2535 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2538 if (NT_STATUS_IS_OK(status)) {
2541 DEBUG(10,("cm_connect_sam: schannel-sealed dcerpc_samr_Connect2 failed "
2542 "for domain %s, error was %s. Trying anonymous\n",
2543 domain->name, nt_errstr(status) ));
2544 TALLOC_FREE(conn->samr_pipe);
2548 /* Finally fall back to anonymous. */
2549 status = cli_rpc_pipe_open_noauth(conn->cli, &ndr_table_samr,
2552 if (!NT_STATUS_IS_OK(status)) {
2556 status = dcerpc_samr_Connect2(conn->samr_pipe->binding_handle, mem_ctx,
2557 conn->samr_pipe->desthost,
2558 SEC_FLAG_MAXIMUM_ALLOWED,
2559 &conn->sam_connect_handle,
2561 if (!NT_STATUS_IS_OK(status)) {
2562 DEBUG(10,("cm_connect_sam: rpccli_samr_Connect2 failed "
2563 "for domain %s Error was %s\n",
2564 domain->name, nt_errstr(status) ));
2567 if (!NT_STATUS_IS_OK(result)) {
2569 DEBUG(10,("cm_connect_sam: dcerpc_samr_Connect2 failed "
2570 "for domain %s Error was %s\n",
2571 domain->name, nt_errstr(result)));
2576 status = dcerpc_samr_OpenDomain(conn->samr_pipe->binding_handle,
2578 &conn->sam_connect_handle,
2579 SEC_FLAG_MAXIMUM_ALLOWED,
2581 &conn->sam_domain_handle,
2583 if (!NT_STATUS_IS_OK(status)) {
2590 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2592 * if we got access denied, we might just have no access rights
2593 * to talk to the remote samr server server (e.g. when we are a
2594 * PDC and we are connecting a w2k8 pdc via an interdomain
2595 * trust). In that case do not invalidate the whole connection
2598 TALLOC_FREE(conn->samr_pipe);
2599 ZERO_STRUCT(conn->sam_domain_handle);
2601 } else if (!NT_STATUS_IS_OK(status)) {
2602 invalidate_cm_connection(conn);
2606 *cli = conn->samr_pipe;
2607 *sam_handle = conn->sam_domain_handle;
2608 SAFE_FREE(machine_password);
2609 SAFE_FREE(machine_account);
2613 /**********************************************************************
2614 open an schanneld ncacn_ip_tcp connection to LSA
2615 ***********************************************************************/
2617 NTSTATUS cm_connect_lsa_tcp(struct winbindd_domain *domain,
2618 TALLOC_CTX *mem_ctx,
2619 struct rpc_pipe_client **cli)
2621 struct winbindd_cm_conn *conn;
2622 struct netlogon_creds_cli_context *creds;
2625 DEBUG(10,("cm_connect_lsa_tcp\n"));
2627 status = init_dc_connection_rpc(domain, false);
2628 if (!NT_STATUS_IS_OK(status)) {
2632 conn = &domain->conn;
2634 if (conn->lsa_pipe_tcp &&
2635 conn->lsa_pipe_tcp->transport->transport == NCACN_IP_TCP &&
2636 conn->lsa_pipe_tcp->auth->auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY &&
2637 rpccli_is_connected(conn->lsa_pipe_tcp)) {
2641 TALLOC_FREE(conn->lsa_pipe_tcp);
2643 status = cm_get_schannel_creds(domain, &creds);
2644 if (!NT_STATUS_IS_OK(status)) {
2648 status = cli_rpc_pipe_open_schannel_with_key(conn->cli,
2653 &conn->lsa_pipe_tcp);
2654 if (!NT_STATUS_IS_OK(status)) {
2655 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key failed: %s\n",
2656 nt_errstr(status)));
2661 if (!NT_STATUS_IS_OK(status)) {
2662 TALLOC_FREE(conn->lsa_pipe_tcp);
2666 *cli = conn->lsa_pipe_tcp;
2671 NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
2672 struct rpc_pipe_client **cli, struct policy_handle *lsa_policy)
2674 struct winbindd_cm_conn *conn;
2675 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2676 struct netlogon_creds_cli_context *p_creds;
2678 result = init_dc_connection_rpc(domain, false);
2679 if (!NT_STATUS_IS_OK(result))
2682 conn = &domain->conn;
2684 if (rpccli_is_connected(conn->lsa_pipe)) {
2688 TALLOC_FREE(conn->lsa_pipe);
2690 if ((conn->cli->user_name[0] == '\0') ||
2691 (conn->cli->domain[0] == '\0') ||
2692 (conn->cli->password == NULL || conn->cli->password[0] == '\0')) {
2693 DEBUG(10, ("cm_connect_lsa: No no user available for "
2694 "domain %s, trying schannel\n", conn->cli->domain));
2698 /* We have an authenticated connection. Use a NTLMSSP SPNEGO
2699 * authenticated LSA pipe with sign & seal. */
2700 result = cli_rpc_pipe_open_spnego
2701 (conn->cli, &ndr_table_lsarpc, NCACN_NP,
2704 smbXcli_conn_remote_name(conn->cli->conn),
2705 conn->cli->domain, conn->cli->user_name, conn->cli->password,
2708 if (!NT_STATUS_IS_OK(result)) {
2709 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
2710 "domain %s using NTLMSSP authenticated pipe: user "
2711 "%s\\%s. Error was %s. Trying schannel.\n",
2712 domain->name, conn->cli->domain,
2713 conn->cli->user_name, nt_errstr(result)));
2717 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
2718 "NTLMSSP authenticated pipe: user %s\\%s\n",
2719 domain->name, conn->cli->domain, conn->cli->user_name ));
2721 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2722 SEC_FLAG_MAXIMUM_ALLOWED,
2724 if (NT_STATUS_IS_OK(result)) {
2728 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
2731 TALLOC_FREE(conn->lsa_pipe);
2735 /* Fall back to schannel if it's a W2K pre-SP1 box. */
2737 result = cm_get_schannel_creds(domain, &p_creds);
2738 if (!NT_STATUS_IS_OK(result)) {
2739 /* If this call fails - conn->cli can now be NULL ! */
2740 DEBUG(10, ("cm_connect_lsa: Could not get schannel auth info "
2741 "for domain %s (error %s), trying anon\n",
2743 nt_errstr(result) ));
2746 result = cli_rpc_pipe_open_schannel_with_key
2747 (conn->cli, &ndr_table_lsarpc, NCACN_NP,
2748 domain->name, p_creds, &conn->lsa_pipe);
2750 if (!NT_STATUS_IS_OK(result)) {
2751 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
2752 "domain %s using schannel. Error was %s\n",
2753 domain->name, nt_errstr(result) ));
2756 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
2757 "schannel.\n", domain->name ));
2759 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2760 SEC_FLAG_MAXIMUM_ALLOWED,
2762 if (NT_STATUS_IS_OK(result)) {
2766 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
2769 TALLOC_FREE(conn->lsa_pipe);
2773 result = cli_rpc_pipe_open_noauth(conn->cli,
2776 if (!NT_STATUS_IS_OK(result)) {
2780 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2781 SEC_FLAG_MAXIMUM_ALLOWED,
2784 if (!NT_STATUS_IS_OK(result)) {
2785 invalidate_cm_connection(conn);
2789 *cli = conn->lsa_pipe;
2790 *lsa_policy = conn->lsa_policy;
2794 /****************************************************************************
2795 Open a LSA connection to a DC, suiteable for LSA lookup calls.
2796 ****************************************************************************/
2798 NTSTATUS cm_connect_lsat(struct winbindd_domain *domain,
2799 TALLOC_CTX *mem_ctx,
2800 struct rpc_pipe_client **cli,
2801 struct policy_handle *lsa_policy)
2805 if (domain->can_do_ncacn_ip_tcp) {
2806 status = cm_connect_lsa_tcp(domain, mem_ctx, cli);
2807 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
2808 NT_STATUS_EQUAL(status, NT_STATUS_RPC_SEC_PKG_ERROR) ||
2809 NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
2810 invalidate_cm_connection(&domain->conn);
2811 status = cm_connect_lsa_tcp(domain, mem_ctx, cli);
2813 if (NT_STATUS_IS_OK(status)) {
2818 * we tried twice to connect via ncan_ip_tcp and schannel and
2819 * failed - maybe it is a trusted domain we can't connect to ?
2820 * do not try tcp next time - gd
2822 domain->can_do_ncacn_ip_tcp = false;
2825 status = cm_connect_lsa(domain, mem_ctx, cli, lsa_policy);
2830 /****************************************************************************
2831 Open the netlogon pipe to this DC. Use schannel if specified in client conf.
2832 session key stored in conn->netlogon_pipe->dc->sess_key.
2833 ****************************************************************************/
2835 NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
2836 struct rpc_pipe_client **cli)
2838 struct messaging_context *msg_ctx = winbind_messaging_context();
2839 struct winbindd_cm_conn *conn;
2841 enum netr_SchannelType sec_chan_type;
2842 const char *_account_name;
2843 const char *account_name;
2844 struct samr_Password current_nt_hash;
2845 struct samr_Password *previous_nt_hash = NULL;
2846 struct netlogon_creds_CredentialState *creds = NULL;
2851 result = init_dc_connection_rpc(domain, true);
2852 if (!NT_STATUS_IS_OK(result)) {
2856 conn = &domain->conn;
2858 if (rpccli_is_connected(conn->netlogon_pipe)) {
2859 *cli = conn->netlogon_pipe;
2860 return NT_STATUS_OK;
2863 TALLOC_FREE(conn->netlogon_pipe);
2864 conn->netlogon_flags = 0;
2865 TALLOC_FREE(conn->netlogon_creds);
2867 if ((!IS_DC) && (!domain->primary)) {
2871 ok = get_trust_pw_hash(domain->name,
2872 current_nt_hash.hash,
2876 DEBUG(1, ("get_trust_pw_hash failed for %s, "
2877 "unable to get NETLOGON credentials\n",
2879 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2882 account_name = talloc_asprintf(talloc_tos(), "%s$", _account_name);
2883 if (account_name == NULL) {
2884 return NT_STATUS_NO_MEMORY;
2887 result = rpccli_create_netlogon_creds(domain->dcname,
2893 &conn->netlogon_creds);
2894 if (!NT_STATUS_IS_OK(result)) {
2895 DEBUG(1, ("rpccli_create_netlogon_creds failed for %s, "
2896 "unable to create NETLOGON credentials: %s\n",
2897 domain->name, nt_errstr(result)));
2898 SAFE_FREE(previous_nt_hash);
2902 result = rpccli_setup_netlogon_creds(conn->cli,
2903 conn->netlogon_creds,
2904 conn->netlogon_force_reauth,
2907 conn->netlogon_force_reauth = false;
2908 SAFE_FREE(previous_nt_hash);
2909 if (!NT_STATUS_IS_OK(result)) {
2910 DEBUG(1, ("rpccli_setup_netlogon_creds failed for %s, "
2911 "unable to setup NETLOGON credentials: %s\n",
2912 domain->name, nt_errstr(result)));
2916 result = netlogon_creds_cli_get(conn->netlogon_creds,
2919 if (!NT_STATUS_IS_OK(result)) {
2920 DEBUG(1, ("netlogon_creds_cli_get failed for %s, "
2921 "unable to get NETLOGON credentials: %s\n",
2922 domain->name, nt_errstr(result)));
2925 conn->netlogon_flags = creds->negotiate_flags;
2929 if (!(conn->netlogon_flags & NETLOGON_NEG_AUTHENTICATED_RPC)) {
2930 result = cli_rpc_pipe_open_noauth(conn->cli,
2931 &ndr_table_netlogon,
2932 &conn->netlogon_pipe);
2933 if (!NT_STATUS_IS_OK(result)) {
2934 invalidate_cm_connection(conn);
2938 *cli = conn->netlogon_pipe;
2939 return NT_STATUS_OK;
2942 /* Using the credentials from the first pipe, open a signed and sealed
2943 second netlogon pipe. The session key is stored in the schannel
2944 part of the new pipe auth struct.
2947 result = cli_rpc_pipe_open_schannel_with_key(
2948 conn->cli, &ndr_table_netlogon, NCACN_NP,
2950 conn->netlogon_creds,
2951 &conn->netlogon_pipe);
2952 if (!NT_STATUS_IS_OK(result)) {
2953 DEBUG(3, ("Could not open schannel'ed NETLOGON pipe. Error "
2954 "was %s\n", nt_errstr(result)));
2956 invalidate_cm_connection(conn);
2960 *cli = conn->netlogon_pipe;
2961 return NT_STATUS_OK;
2964 void winbind_msg_ip_dropped(struct messaging_context *msg_ctx,
2967 struct server_id server_id,
2970 struct winbindd_domain *domain;
2971 char *freeit = NULL;
2975 || (data->data == NULL)
2976 || (data->length == 0)
2977 || (data->data[data->length-1] != '\0')) {
2978 DEBUG(1, ("invalid msg_ip_dropped message: not a valid "
2983 addr = (char *)data->data;
2984 DEBUG(10, ("IP %s dropped\n", addr));
2986 if (!is_ipaddress(addr)) {
2989 * Some code sends us ip addresses with the /netmask
2992 slash = strchr(addr, '/');
2993 if (slash == NULL) {
2994 DEBUG(1, ("invalid msg_ip_dropped message: %s",
2998 freeit = talloc_strndup(talloc_tos(), addr, slash-addr);
2999 if (freeit == NULL) {
3000 DEBUG(1, ("talloc failed\n"));
3004 DEBUG(10, ("Stripped /netmask to IP %s\n", addr));
3007 for (domain = domain_list(); domain != NULL; domain = domain->next) {
3008 char sockaddr[INET6_ADDRSTRLEN];
3010 if (!cli_state_is_connected(domain->conn.cli)) {
3014 print_sockaddr(sockaddr, sizeof(sockaddr),
3015 smbXcli_conn_local_sockaddr(domain->conn.cli->conn));
3017 if (strequal(sockaddr, addr)) {
3018 smbXcli_conn_disconnect(domain->conn.cli->conn, NT_STATUS_OK);
3021 TALLOC_FREE(freeit);