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"
85 #define DBGC_CLASS DBGC_WINBIND
89 struct sockaddr_storage ss;
92 extern struct winbindd_methods reconnect_methods;
93 extern bool override_logfile;
95 static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain);
96 static void set_dc_type_and_flags( struct winbindd_domain *domain );
97 static bool get_dcs(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
98 struct dc_name_ip **dcs, int *num_dcs);
100 /****************************************************************
101 Child failed to find DC's. Reschedule check.
102 ****************************************************************/
104 static void msg_failed_to_go_online(struct messaging_context *msg,
107 struct server_id server_id,
110 struct winbindd_domain *domain;
111 const char *domainname = (const char *)data->data;
113 if (data->data == NULL || data->length == 0) {
117 DEBUG(5,("msg_fail_to_go_online: received for domain %s.\n", domainname));
119 for (domain = domain_list(); domain; domain = domain->next) {
120 if (domain->internal) {
124 if (strequal(domain->name, domainname)) {
125 if (domain->online) {
126 /* We're already online, ignore. */
127 DEBUG(5,("msg_fail_to_go_online: domain %s "
128 "already online.\n", domainname));
132 /* Reschedule the online check. */
133 set_domain_offline(domain);
139 /****************************************************************
140 Actually cause a reconnect from a message.
141 ****************************************************************/
143 static void msg_try_to_go_online(struct messaging_context *msg,
146 struct server_id server_id,
149 struct winbindd_domain *domain;
150 const char *domainname = (const char *)data->data;
152 if (data->data == NULL || data->length == 0) {
156 DEBUG(5,("msg_try_to_go_online: received for domain %s.\n", domainname));
158 for (domain = domain_list(); domain; domain = domain->next) {
159 if (domain->internal) {
163 if (strequal(domain->name, domainname)) {
165 if (domain->online) {
166 /* We're already online, ignore. */
167 DEBUG(5,("msg_try_to_go_online: domain %s "
168 "already online.\n", domainname));
172 /* This call takes care of setting the online
173 flag to true if we connected, or re-adding
174 the offline handler if false. Bypasses online
175 check so always does network calls. */
177 init_dc_connection_network(domain);
183 /****************************************************************
184 Fork a child to try and contact a DC. Do this as contacting a
185 DC requires blocking lookups and we don't want to block our
187 ****************************************************************/
189 static bool fork_child_dc_connect(struct winbindd_domain *domain)
191 struct dc_name_ip *dcs = NULL;
193 TALLOC_CTX *mem_ctx = NULL;
194 pid_t parent_pid = getpid();
198 if (domain->dc_probe_pid != (pid_t)-1) {
200 * We might already have a DC probe
201 * child working, check.
203 if (process_exists_by_pid(domain->dc_probe_pid)) {
204 DEBUG(10,("fork_child_dc_connect: pid %u already "
205 "checking for DC's.\n",
206 (unsigned int)domain->dc_probe_pid));
209 domain->dc_probe_pid = (pid_t)-1;
212 domain->dc_probe_pid = fork();
214 if (domain->dc_probe_pid == (pid_t)-1) {
215 DEBUG(0, ("fork_child_dc_connect: Could not fork: %s\n", strerror(errno)));
219 if (domain->dc_probe_pid != (pid_t)0) {
221 messaging_register(winbind_messaging_context(), NULL,
222 MSG_WINBIND_TRY_TO_GO_ONLINE,
223 msg_try_to_go_online);
224 messaging_register(winbind_messaging_context(), NULL,
225 MSG_WINBIND_FAILED_TO_GO_ONLINE,
226 msg_failed_to_go_online);
232 /* Leave messages blocked - we will never process one. */
234 if (!override_logfile) {
235 if (asprintf(&lfile, "%s/log.winbindd-dc-connect", get_dyn_LOGFILEBASE()) == -1) {
236 DEBUG(0, ("fork_child_dc_connect: out of memory.\n"));
241 status = winbindd_reinit_after_fork(NULL, lfile);
242 if (!NT_STATUS_IS_OK(status)) {
243 DEBUG(1, ("winbindd_reinit_after_fork failed: %s\n",
245 messaging_send_buf(winbind_messaging_context(),
246 pid_to_procid(parent_pid),
247 MSG_WINBIND_FAILED_TO_GO_ONLINE,
248 (const uint8_t *)domain->name,
249 strlen(domain->name)+1);
254 mem_ctx = talloc_init("fork_child_dc_connect");
256 DEBUG(0,("talloc_init failed.\n"));
257 messaging_send_buf(winbind_messaging_context(),
258 pid_to_procid(parent_pid),
259 MSG_WINBIND_FAILED_TO_GO_ONLINE,
260 (const uint8_t *)domain->name,
261 strlen(domain->name)+1);
265 if ((!get_dcs(mem_ctx, domain, &dcs, &num_dcs)) || (num_dcs == 0)) {
266 /* Still offline ? Can't find DC's. */
267 messaging_send_buf(winbind_messaging_context(),
268 pid_to_procid(parent_pid),
269 MSG_WINBIND_FAILED_TO_GO_ONLINE,
270 (const uint8_t *)domain->name,
271 strlen(domain->name)+1);
275 /* We got a DC. Send a message to our parent to get it to
276 try and do the same. */
278 messaging_send_buf(winbind_messaging_context(),
279 pid_to_procid(parent_pid),
280 MSG_WINBIND_TRY_TO_GO_ONLINE,
281 (const uint8_t *)domain->name,
282 strlen(domain->name)+1);
286 /****************************************************************
287 Handler triggered if we're offline to try and detect a DC.
288 ****************************************************************/
290 static void check_domain_online_handler(struct tevent_context *ctx,
291 struct tevent_timer *te,
295 struct winbindd_domain *domain =
296 (struct winbindd_domain *)private_data;
298 DEBUG(10,("check_domain_online_handler: called for domain "
299 "%s (online = %s)\n", domain->name,
300 domain->online ? "True" : "False" ));
302 TALLOC_FREE(domain->check_online_event);
304 /* Are we still in "startup" mode ? */
306 if (domain->startup && (time_mono(NULL) > domain->startup_time + 30)) {
307 /* No longer in "startup" mode. */
308 DEBUG(10,("check_domain_online_handler: domain %s no longer in 'startup' mode.\n",
310 domain->startup = False;
313 /* We've been told to stay offline, so stay
316 if (get_global_winbindd_state_offline()) {
317 DEBUG(10,("check_domain_online_handler: domain %s remaining globally offline\n",
322 /* Fork a child to test if it can contact a DC.
323 If it can then send ourselves a message to
324 cause a reconnect. */
326 fork_child_dc_connect(domain);
329 /****************************************************************
330 If we're still offline setup the timeout check.
331 ****************************************************************/
333 static void calc_new_online_timeout_check(struct winbindd_domain *domain)
335 int wbr = lp_winbind_reconnect_delay();
337 if (domain->startup) {
338 domain->check_online_timeout = 10;
339 } else if (domain->check_online_timeout < wbr) {
340 domain->check_online_timeout = wbr;
344 void winbind_msg_domain_offline(struct messaging_context *msg_ctx,
347 struct server_id server_id,
350 const char *domain_name = (const char *)data->data;
351 struct winbindd_domain *domain;
353 domain = find_domain_from_name_noinit(domain_name);
354 if (domain == NULL) {
358 domain->online = false;
360 DEBUG(10, ("Domain %s is marked as offline now.\n",
364 void winbind_msg_domain_online(struct messaging_context *msg_ctx,
367 struct server_id server_id,
370 const char *domain_name = (const char *)data->data;
371 struct winbindd_domain *domain;
373 domain = find_domain_from_name_noinit(domain_name);
374 if (domain == NULL) {
378 domain->online = true;
380 DEBUG(10, ("Domain %s is marked as online now.\n",
384 /****************************************************************
385 Set domain offline and also add handler to put us back online
387 ****************************************************************/
389 void set_domain_offline(struct winbindd_domain *domain)
391 pid_t parent_pid = getppid();
393 DEBUG(10,("set_domain_offline: called for domain %s\n",
396 TALLOC_FREE(domain->check_online_event);
398 if (domain->internal) {
399 DEBUG(3,("set_domain_offline: domain %s is internal - logic error.\n",
404 domain->online = False;
406 /* Offline domains are always initialized. They're
407 re-initialized when they go back online. */
409 domain->initialized = True;
411 /* We only add the timeout handler that checks and
412 allows us to go back online when we've not
413 been told to remain offline. */
415 if (get_global_winbindd_state_offline()) {
416 DEBUG(10,("set_domain_offline: domain %s remaining globally offline\n",
421 /* If we're in startup mode, check again in 10 seconds, not in
422 lp_winbind_reconnect_delay() seconds (which is 30 seconds by default). */
424 calc_new_online_timeout_check(domain);
426 domain->check_online_event = tevent_add_timer(winbind_event_context(),
428 timeval_current_ofs(domain->check_online_timeout,0),
429 check_domain_online_handler,
432 /* The above *has* to succeed for winbindd to work. */
433 if (!domain->check_online_event) {
434 smb_panic("set_domain_offline: failed to add online handler");
437 DEBUG(10,("set_domain_offline: added event handler for domain %s\n",
440 /* Send a message to the parent that the domain is offline. */
441 if (parent_pid > 1 && !domain->internal) {
442 messaging_send_buf(winbind_messaging_context(),
443 pid_to_procid(parent_pid),
444 MSG_WINBIND_DOMAIN_OFFLINE,
445 (uint8 *)domain->name,
446 strlen(domain->name) + 1);
449 /* Send an offline message to the idmap child when our
450 primary domain goes offline */
452 if ( domain->primary ) {
453 struct winbindd_child *idmap = idmap_child();
455 if ( idmap->pid != 0 ) {
456 messaging_send_buf(winbind_messaging_context(),
457 pid_to_procid(idmap->pid),
459 (const uint8_t *)domain->name,
460 strlen(domain->name)+1);
467 /****************************************************************
468 Set domain online - if allowed.
469 ****************************************************************/
471 static void set_domain_online(struct winbindd_domain *domain)
473 pid_t parent_pid = getppid();
475 DEBUG(10,("set_domain_online: called for domain %s\n",
478 if (domain->internal) {
479 DEBUG(3,("set_domain_online: domain %s is internal - logic error.\n",
484 if (get_global_winbindd_state_offline()) {
485 DEBUG(10,("set_domain_online: domain %s remaining globally offline\n",
490 winbindd_set_locator_kdc_envs(domain);
492 /* If we are waiting to get a krb5 ticket, trigger immediately. */
493 ccache_regain_all_now();
495 /* Ok, we're out of any startup mode now... */
496 domain->startup = False;
498 if (domain->online == False) {
499 /* We were offline - now we're online. We default to
500 using the MS-RPC backend if we started offline,
501 and if we're going online for the first time we
502 should really re-initialize the backends and the
503 checks to see if we're talking to an AD or NT domain.
506 domain->initialized = False;
508 /* 'reconnect_methods' is the MS-RPC backend. */
509 if (domain->backend == &reconnect_methods) {
510 domain->backend = NULL;
514 /* Ensure we have no online timeout checks. */
515 domain->check_online_timeout = 0;
516 TALLOC_FREE(domain->check_online_event);
518 /* Ensure we ignore any pending child messages. */
519 messaging_deregister(winbind_messaging_context(),
520 MSG_WINBIND_TRY_TO_GO_ONLINE, NULL);
521 messaging_deregister(winbind_messaging_context(),
522 MSG_WINBIND_FAILED_TO_GO_ONLINE, NULL);
524 domain->online = True;
526 /* Send a message to the parent that the domain is online. */
527 if (parent_pid > 1 && !domain->internal) {
528 messaging_send_buf(winbind_messaging_context(),
529 pid_to_procid(parent_pid),
530 MSG_WINBIND_DOMAIN_ONLINE,
531 (uint8 *)domain->name,
532 strlen(domain->name) + 1);
535 /* Send an online message to the idmap child when our
536 primary domain comes online */
538 if ( domain->primary ) {
539 struct winbindd_child *idmap = idmap_child();
541 if ( idmap->pid != 0 ) {
542 messaging_send_buf(winbind_messaging_context(),
543 pid_to_procid(idmap->pid),
545 (const uint8_t *)domain->name,
546 strlen(domain->name)+1);
553 /****************************************************************
554 Requested to set a domain online.
555 ****************************************************************/
557 void set_domain_online_request(struct winbindd_domain *domain)
561 DEBUG(10,("set_domain_online_request: called for domain %s\n",
564 if (get_global_winbindd_state_offline()) {
565 DEBUG(10,("set_domain_online_request: domain %s remaining globally offline\n",
570 if (domain->internal) {
571 DEBUG(10, ("set_domain_online_request: Internal domains are "
576 /* We've been told it's safe to go online and
577 try and connect to a DC. But I don't believe it
578 because network manager seems to lie.
579 Wait at least 5 seconds. Heuristics suck... */
584 /* Go into "startup" mode again. */
585 domain->startup_time = time_mono(NULL);
586 domain->startup = True;
590 if (!domain->check_online_event) {
591 /* If we've come from being globally offline we
592 don't have a check online event handler set.
593 We need to add one now we're trying to go
596 DEBUG(10,("set_domain_online_request: domain %s was globally offline.\n",
600 TALLOC_FREE(domain->check_online_event);
602 domain->check_online_event = tevent_add_timer(winbind_event_context(),
605 check_domain_online_handler,
608 /* The above *has* to succeed for winbindd to work. */
609 if (!domain->check_online_event) {
610 smb_panic("set_domain_online_request: failed to add online handler");
614 /****************************************************************
615 Add -ve connection cache entries for domain and realm.
616 ****************************************************************/
618 static void winbind_add_failed_connection_entry(
619 const struct winbindd_domain *domain,
623 add_failed_connection_entry(domain->name, server, result);
624 /* If this was the saf name for the last thing we talked to,
626 saf_delete(domain->name);
627 if (domain->alt_name != NULL) {
628 add_failed_connection_entry(domain->alt_name, server, result);
629 saf_delete(domain->alt_name);
631 winbindd_unset_locator_kdc_env(domain);
634 /* Choose between anonymous or authenticated connections. We need to use
635 an authenticated connection if DCs have the RestrictAnonymous registry
636 entry set > 0, or the "Additional restrictions for anonymous
637 connections" set in the win2k Local Security Policy.
639 Caller to free() result in domain, username, password
642 static void cm_get_ipc_userpass(char **username, char **domain, char **password)
644 *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
645 *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
646 *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
648 if (*username && **username) {
650 if (!*domain || !**domain)
651 *domain = smb_xstrdup(lp_workgroup());
653 if (!*password || !**password)
654 *password = smb_xstrdup("");
656 DEBUG(3, ("cm_get_ipc_userpass: Retrieved auth-user from secrets.tdb [%s\\%s]\n",
657 *domain, *username));
660 DEBUG(3, ("cm_get_ipc_userpass: No auth-user defined\n"));
661 *username = smb_xstrdup("");
662 *domain = smb_xstrdup("");
663 *password = smb_xstrdup("");
667 static bool get_dc_name_via_netlogon(struct winbindd_domain *domain,
669 struct sockaddr_storage *dc_ss)
671 struct winbindd_domain *our_domain = NULL;
672 struct rpc_pipe_client *netlogon_pipe = NULL;
676 unsigned int orig_timeout;
677 const char *tmp = NULL;
679 struct dcerpc_binding_handle *b;
681 /* Hmmmm. We can only open one connection to the NETLOGON pipe at the
688 if (domain->primary) {
692 our_domain = find_our_domain();
694 if ((mem_ctx = talloc_init("get_dc_name_via_netlogon")) == NULL) {
698 result = cm_connect_netlogon(our_domain, &netlogon_pipe);
699 if (!NT_STATUS_IS_OK(result)) {
700 talloc_destroy(mem_ctx);
704 b = netlogon_pipe->binding_handle;
706 /* This call can take a long time - allow the server to time out.
707 35 seconds should do it. */
709 orig_timeout = rpccli_set_timeout(netlogon_pipe, 35000);
711 if (our_domain->active_directory) {
712 struct netr_DsRGetDCNameInfo *domain_info = NULL;
714 result = dcerpc_netr_DsRGetDCName(b,
723 if (NT_STATUS_IS_OK(result) && W_ERROR_IS_OK(werr)) {
725 mem_ctx, domain_info->dc_unc);
727 DEBUG(0, ("talloc_strdup failed\n"));
728 talloc_destroy(mem_ctx);
731 if (domain->alt_name == NULL) {
732 domain->alt_name = talloc_strdup(domain,
733 domain_info->domain_name);
734 if (domain->alt_name == NULL) {
735 DEBUG(0, ("talloc_strdup failed\n"));
736 talloc_destroy(mem_ctx);
740 if (domain->forest_name == NULL) {
741 domain->forest_name = talloc_strdup(domain,
742 domain_info->forest_name);
743 if (domain->forest_name == NULL) {
744 DEBUG(0, ("talloc_strdup failed\n"));
745 talloc_destroy(mem_ctx);
751 result = dcerpc_netr_GetAnyDCName(b, mem_ctx,
758 /* And restore our original timeout. */
759 rpccli_set_timeout(netlogon_pipe, orig_timeout);
761 if (!NT_STATUS_IS_OK(result)) {
762 DEBUG(10,("dcerpc_netr_GetAnyDCName failed: %s\n",
764 talloc_destroy(mem_ctx);
768 if (!W_ERROR_IS_OK(werr)) {
769 DEBUG(10,("dcerpc_netr_GetAnyDCName failed: %s\n",
771 talloc_destroy(mem_ctx);
775 /* dcerpc_netr_GetAnyDCName gives us a name with \\ */
776 p = strip_hostname(tmp);
780 talloc_destroy(mem_ctx);
782 DEBUG(10,("dcerpc_netr_GetAnyDCName returned %s\n", dcname));
784 if (!resolve_name(dcname, dc_ss, 0x20, true)) {
792 * Helper function to assemble trust password and account name
794 static NTSTATUS get_trust_creds(const struct winbindd_domain *domain,
795 char **machine_password,
796 char **machine_account,
797 char **machine_krb5_principal)
799 const char *account_name;
800 const char *name = NULL;
802 /* If we are a DC and this is not our own domain */
807 struct winbindd_domain *our_domain = find_our_domain();
810 return NT_STATUS_INVALID_SERVER_STATE;
812 name = our_domain->name;
815 if (!get_trust_pw_clear(name, machine_password,
816 &account_name, NULL))
818 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
821 if ((machine_account != NULL) &&
822 (asprintf(machine_account, "%s$", account_name) == -1))
824 return NT_STATUS_NO_MEMORY;
827 /* For now assume our machine account only exists in our domain */
829 if (machine_krb5_principal != NULL)
831 struct winbindd_domain *our_domain = find_our_domain();
834 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
837 if (asprintf(machine_krb5_principal, "%s$@%s",
838 account_name, our_domain->alt_name) == -1)
840 return NT_STATUS_NO_MEMORY;
843 if (!strupper_m(*machine_krb5_principal)) {
844 SAFE_FREE(*machine_krb5_principal);
845 return NT_STATUS_INVALID_PARAMETER;
852 /************************************************************************
853 Given a fd with a just-connected TCP connection to a DC, open a connection
855 ************************************************************************/
857 static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
859 const char *controller,
860 struct cli_state **cli,
863 bool try_spnego = false;
864 bool try_ipc_auth = false;
865 char *machine_password = NULL;
866 char *machine_krb5_principal = NULL;
867 char *machine_account = NULL;
868 char *ipc_username = NULL;
869 char *ipc_domain = NULL;
870 char *ipc_password = NULL;
872 uint16_t sec_mode = 0;
874 struct named_mutex *mutex;
876 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
878 DEBUG(10,("cm_prepare_connection: connecting to DC %s for domain %s\n",
879 controller, domain->name ));
883 mutex = grab_named_mutex(talloc_tos(), controller,
884 WINBIND_SERVER_MUTEX_WAIT_TIME);
887 DEBUG(0,("cm_prepare_connection: mutex grab failed for %s\n",
889 result = NT_STATUS_POSSIBLE_DEADLOCK;
893 flags |= CLI_FULL_CONNECTION_USE_KERBEROS;
895 *cli = cli_state_create(NULL, sockfd,
896 controller, domain->alt_name,
897 SMB_SIGNING_DEFAULT, flags);
900 DEBUG(1, ("Could not cli_initialize\n"));
901 result = NT_STATUS_NO_MEMORY;
905 cli_set_timeout(*cli, 10000); /* 10 seconds */
907 result = smbXcli_negprot((*cli)->conn, (*cli)->timeout,
908 lp_client_min_protocol(),
909 lp_client_max_protocol());
911 if (!NT_STATUS_IS_OK(result)) {
912 DEBUG(1, ("cli_negprot failed: %s\n", nt_errstr(result)));
916 if (smbXcli_conn_protocol((*cli)->conn) >= PROTOCOL_NT1 &&
917 smb1cli_conn_capabilities((*cli)->conn) & CAP_EXTENDED_SECURITY) {
919 } else if (smbXcli_conn_protocol((*cli)->conn) >= PROTOCOL_SMB2_02) {
923 if (!is_dc_trusted_domain_situation(domain->name) && try_spnego) {
924 result = get_trust_creds(domain, &machine_password,
926 &machine_krb5_principal);
927 if (!NT_STATUS_IS_OK(result)) {
931 if (lp_security() == SEC_ADS) {
933 /* Try a krb5 session */
935 (*cli)->use_kerberos = True;
936 DEBUG(5, ("connecting to %s from %s with kerberos principal "
937 "[%s] and realm [%s]\n", controller, lp_netbios_name(),
938 machine_krb5_principal, domain->alt_name));
940 winbindd_set_locator_kdc_envs(domain);
942 result = cli_session_setup(*cli,
943 machine_krb5_principal,
945 strlen(machine_password)+1,
947 strlen(machine_password)+1,
950 if (!NT_STATUS_IS_OK(result)) {
951 DEBUG(4,("failed kerberos session setup with %s\n",
955 if (NT_STATUS_IS_OK(result)) {
956 /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
957 result = cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
958 if (!NT_STATUS_IS_OK(result)) {
961 goto session_setup_done;
965 /* Fall back to non-kerberos session setup using NTLMSSP SPNEGO with the machine account. */
966 (*cli)->use_kerberos = False;
968 DEBUG(5, ("connecting to %s from %s with username "
969 "[%s]\\[%s]\n", controller, lp_netbios_name(),
970 lp_workgroup(), machine_account));
972 result = cli_session_setup(*cli,
975 strlen(machine_password)+1,
977 strlen(machine_password)+1,
979 if (!NT_STATUS_IS_OK(result)) {
980 DEBUG(4, ("authenticated session setup failed with %s\n",
984 if (NT_STATUS_IS_OK(result)) {
985 /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
986 result = cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
987 if (!NT_STATUS_IS_OK(result)) {
990 goto session_setup_done;
994 /* Fall back to non-kerberos session setup with auth_user */
996 (*cli)->use_kerberos = False;
998 cm_get_ipc_userpass(&ipc_username, &ipc_domain, &ipc_password);
1000 sec_mode = smb1cli_conn_server_security_mode((*cli)->conn);
1002 try_ipc_auth = false;
1004 try_ipc_auth = true;
1005 } else if (sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) {
1006 try_ipc_auth = true;
1009 if (try_ipc_auth && (strlen(ipc_username) > 0)) {
1011 /* Only try authenticated if we have a username */
1013 DEBUG(5, ("connecting to %s from %s with username "
1014 "[%s]\\[%s]\n", controller, lp_netbios_name(),
1015 ipc_domain, ipc_username));
1017 if (NT_STATUS_IS_OK(cli_session_setup(
1019 ipc_password, strlen(ipc_password)+1,
1020 ipc_password, strlen(ipc_password)+1,
1022 /* Successful logon with given username. */
1023 result = cli_init_creds(*cli, ipc_username, ipc_domain, ipc_password);
1024 if (!NT_STATUS_IS_OK(result)) {
1027 goto session_setup_done;
1029 DEBUG(4, ("authenticated session setup with user %s\\%s failed.\n",
1030 ipc_domain, ipc_username ));
1036 /* Fall back to anonymous connection, this might fail later */
1037 DEBUG(10,("cm_prepare_connection: falling back to anonymous "
1038 "connection for DC %s\n",
1041 result = cli_session_setup(*cli, "", NULL, 0, NULL, 0, "");
1042 if (NT_STATUS_IS_OK(result)) {
1043 DEBUG(5, ("Connected anonymously\n"));
1044 result = cli_init_creds(*cli, "", "", "");
1045 if (!NT_STATUS_IS_OK(result)) {
1048 goto session_setup_done;
1051 /* We can't session setup */
1057 * This should be a short term hack until
1058 * dynamic re-authentication is implemented.
1060 * See Bug 9175 - winbindd doesn't recover from
1061 * NT_STATUS_NETWORK_SESSION_EXPIRED
1063 if (smbXcli_conn_protocol((*cli)->conn) >= PROTOCOL_SMB2_02) {
1064 smbXcli_session_set_disconnect_expired((*cli)->smb2.session);
1067 /* cache the server name for later connections */
1069 saf_store(domain->name, controller);
1070 if (domain->alt_name && (*cli)->use_kerberos) {
1071 saf_store(domain->alt_name, controller);
1074 winbindd_set_locator_kdc_envs(domain);
1076 result = cli_tree_connect(*cli, "IPC$", "IPC", "", 0);
1078 if (!NT_STATUS_IS_OK(result)) {
1079 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(result)));
1086 /* set the domain if empty; needed for schannel connections */
1087 if ( !(*cli)->domain[0] ) {
1088 result = cli_set_domain((*cli), domain->name);
1089 if (!NT_STATUS_IS_OK(result)) {
1090 SAFE_FREE(ipc_username);
1091 SAFE_FREE(ipc_domain);
1092 SAFE_FREE(ipc_password);
1097 result = NT_STATUS_OK;
1101 SAFE_FREE(machine_account);
1102 SAFE_FREE(machine_password);
1103 SAFE_FREE(machine_krb5_principal);
1104 SAFE_FREE(ipc_username);
1105 SAFE_FREE(ipc_domain);
1106 SAFE_FREE(ipc_password);
1108 if (!NT_STATUS_IS_OK(result)) {
1109 winbind_add_failed_connection_entry(domain, controller, result);
1110 if ((*cli) != NULL) {
1119 /*******************************************************************
1120 Add a dcname and sockaddr_storage pair to the end of a dc_name_ip
1123 Keeps the list unique by not adding duplicate entries.
1125 @param[in] mem_ctx talloc memory context to allocate from
1126 @param[in] domain_name domain of the DC
1127 @param[in] dcname name of the DC to add to the list
1128 @param[in] pss Internet address and port pair to add to the list
1129 @param[in,out] dcs array of dc_name_ip structures to add to
1130 @param[in,out] num_dcs number of dcs returned in the dcs array
1131 @return true if the list was added to, false otherwise
1132 *******************************************************************/
1134 static bool add_one_dc_unique(TALLOC_CTX *mem_ctx, const char *domain_name,
1135 const char *dcname, struct sockaddr_storage *pss,
1136 struct dc_name_ip **dcs, int *num)
1140 if (!NT_STATUS_IS_OK(check_negative_conn_cache(domain_name, dcname))) {
1141 DEBUG(10, ("DC %s was in the negative conn cache\n", dcname));
1145 /* Make sure there's no duplicates in the list */
1146 for (i=0; i<*num; i++)
1148 (struct sockaddr *)(void *)&(*dcs)[i].ss,
1149 (struct sockaddr *)(void *)pss))
1152 *dcs = talloc_realloc(mem_ctx, *dcs, struct dc_name_ip, (*num)+1);
1157 fstrcpy((*dcs)[*num].name, dcname);
1158 (*dcs)[*num].ss = *pss;
1163 static bool add_sockaddr_to_array(TALLOC_CTX *mem_ctx,
1164 struct sockaddr_storage *pss, uint16 port,
1165 struct sockaddr_storage **addrs, int *num)
1167 *addrs = talloc_realloc(mem_ctx, *addrs, struct sockaddr_storage, (*num)+1);
1169 if (*addrs == NULL) {
1174 (*addrs)[*num] = *pss;
1175 set_sockaddr_port((struct sockaddr *)&(*addrs)[*num], port);
1181 /*******************************************************************
1182 convert an ip to a name
1183 *******************************************************************/
1185 static bool dcip_to_name(TALLOC_CTX *mem_ctx,
1186 const struct winbindd_domain *domain,
1187 struct sockaddr_storage *pss,
1190 struct ip_service ip_list;
1191 uint32_t nt_version = NETLOGON_NT_VERSION_1;
1193 const char *dc_name;
1200 /* For active directory servers, try to get the ldap server name.
1201 None of these failures should be considered critical for now */
1203 if (lp_security() == SEC_ADS) {
1205 ADS_STATUS ads_status;
1206 char addr[INET6_ADDRSTRLEN];
1208 print_sockaddr(addr, sizeof(addr), pss);
1210 ads = ads_init(domain->alt_name, domain->name, addr);
1211 ads->auth.flags |= ADS_AUTH_NO_BIND;
1213 ads_status = ads_connect(ads);
1214 if (ADS_ERR_OK(ads_status)) {
1215 /* We got a cldap packet. */
1216 *name = talloc_strdup(mem_ctx,
1217 ads->config.ldap_server_name);
1218 if (*name == NULL) {
1221 namecache_store(*name, 0x20, 1, &ip_list);
1223 DEBUG(10,("dcip_to_name: flags = 0x%x\n", (unsigned int)ads->config.flags));
1225 if (domain->primary && (ads->config.flags & NBT_SERVER_KDC)) {
1226 if (ads_closest_dc(ads)) {
1227 char *sitename = sitename_fetch(mem_ctx, ads->config.realm);
1229 /* We're going to use this KDC for this realm/domain.
1230 If we are using sites, then force the krb5 libs
1233 create_local_private_krb5_conf_for_domain(domain->alt_name,
1238 TALLOC_FREE(sitename);
1240 /* use an off site KDC */
1241 create_local_private_krb5_conf_for_domain(domain->alt_name,
1246 winbindd_set_locator_kdc_envs(domain);
1248 /* Ensure we contact this DC also. */
1249 saf_store(domain->name, *name);
1250 saf_store(domain->alt_name, *name);
1253 ads_destroy( &ads );
1257 ads_destroy( &ads );
1262 status = nbt_getdc(winbind_messaging_context(), 10, pss, domain->name,
1263 &domain->sid, nt_version, mem_ctx, &nt_version,
1265 if (NT_STATUS_IS_OK(status)) {
1266 *name = talloc_strdup(mem_ctx, dc_name);
1267 if (*name == NULL) {
1270 namecache_store(*name, 0x20, 1, &ip_list);
1274 /* try node status request */
1276 if (name_status_find(domain->name, 0x1c, 0x20, pss, nbtname) ) {
1277 namecache_store(nbtname, 0x20, 1, &ip_list);
1280 *name = talloc_strdup(mem_ctx, nbtname);
1281 if (*name == NULL) {
1291 /*******************************************************************
1292 Retrieve a list of IP addresses for domain controllers.
1294 The array is sorted in the preferred connection order.
1296 @param[in] mem_ctx talloc memory context to allocate from
1297 @param[in] domain domain to retrieve DCs for
1298 @param[out] dcs array of dcs that will be returned
1299 @param[out] num_dcs number of dcs returned in the dcs array
1301 *******************************************************************/
1303 static bool get_dcs(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
1304 struct dc_name_ip **dcs, int *num_dcs)
1307 struct sockaddr_storage ss;
1308 struct ip_service *ip_list = NULL;
1309 int iplist_size = 0;
1312 enum security_types sec = (enum security_types)lp_security();
1314 is_our_domain = strequal(domain->name, lp_workgroup());
1316 /* If not our domain, get the preferred DC, by asking our primary DC */
1318 && get_dc_name_via_netlogon(domain, dcname, &ss)
1319 && add_one_dc_unique(mem_ctx, domain->name, dcname, &ss, dcs,
1322 char addr[INET6_ADDRSTRLEN];
1323 print_sockaddr(addr, sizeof(addr), &ss);
1324 DEBUG(10, ("Retrieved DC %s at %s via netlogon\n",
1329 if (sec == SEC_ADS) {
1330 char *sitename = NULL;
1332 /* We need to make sure we know the local site before
1333 doing any DNS queries, as this will restrict the
1334 get_sorted_dc_list() call below to only fetching
1335 DNS records for the correct site. */
1337 /* Find any DC to get the site record.
1338 We deliberately don't care about the
1341 get_dc_name(domain->name, domain->alt_name, dcname, &ss);
1343 sitename = sitename_fetch(mem_ctx, domain->alt_name);
1346 /* Do the site-specific AD dns lookup first. */
1347 get_sorted_dc_list(domain->alt_name, sitename, &ip_list,
1348 &iplist_size, True);
1350 /* Add ips to the DC array. We don't look up the name
1351 of the DC in this function, but we fill in the char*
1352 of the ip now to make the failed connection cache
1354 for ( i=0; i<iplist_size; i++ ) {
1355 char addr[INET6_ADDRSTRLEN];
1356 print_sockaddr(addr, sizeof(addr),
1358 add_one_dc_unique(mem_ctx,
1367 TALLOC_FREE(sitename);
1371 /* Now we add DCs from the main AD DNS lookup. */
1372 get_sorted_dc_list(domain->alt_name, NULL, &ip_list,
1373 &iplist_size, True);
1375 for ( i=0; i<iplist_size; i++ ) {
1376 char addr[INET6_ADDRSTRLEN];
1377 print_sockaddr(addr, sizeof(addr),
1379 add_one_dc_unique(mem_ctx,
1391 /* Try standard netbios queries if no ADS and fall back to DNS queries
1392 * if alt_name is available */
1393 if (*num_dcs == 0) {
1394 get_sorted_dc_list(domain->name, NULL, &ip_list, &iplist_size,
1396 if (iplist_size == 0) {
1397 if (domain->alt_name != NULL) {
1398 get_sorted_dc_list(domain->alt_name, NULL, &ip_list,
1399 &iplist_size, true);
1403 for ( i=0; i<iplist_size; i++ ) {
1404 char addr[INET6_ADDRSTRLEN];
1405 print_sockaddr(addr, sizeof(addr),
1407 add_one_dc_unique(mem_ctx,
1422 /*******************************************************************
1423 Find and make a connection to a DC in the given domain.
1425 @param[in] mem_ctx talloc memory context to allocate from
1426 @param[in] domain domain to find a dc in
1427 @param[out] dcname NetBIOS or FQDN of DC that's connected to
1428 @param[out] pss DC Internet address and port
1429 @param[out] fd fd of the open socket connected to the newly found dc
1430 @return true when a DC connection is made, false otherwise
1431 *******************************************************************/
1433 static bool find_new_dc(TALLOC_CTX *mem_ctx,
1434 struct winbindd_domain *domain,
1435 char **dcname, struct sockaddr_storage *pss, int *fd)
1437 struct dc_name_ip *dcs = NULL;
1440 const char **dcnames = NULL;
1441 int num_dcnames = 0;
1443 struct sockaddr_storage *addrs = NULL;
1454 if (!get_dcs(mem_ctx, domain, &dcs, &num_dcs) || (num_dcs == 0))
1457 for (i=0; i<num_dcs; i++) {
1459 if (!add_string_to_array(mem_ctx, dcs[i].name,
1460 &dcnames, &num_dcnames)) {
1463 if (!add_sockaddr_to_array(mem_ctx, &dcs[i].ss, TCP_SMB_PORT,
1464 &addrs, &num_addrs)) {
1469 if ((num_dcnames == 0) || (num_dcnames != num_addrs))
1472 if ((addrs == NULL) || (dcnames == NULL))
1475 status = smbsock_any_connect(addrs, dcnames, NULL, NULL, NULL,
1476 num_addrs, 0, 10, fd, &fd_index, NULL);
1477 if (!NT_STATUS_IS_OK(status)) {
1478 for (i=0; i<num_dcs; i++) {
1479 char ab[INET6_ADDRSTRLEN];
1480 print_sockaddr(ab, sizeof(ab), &dcs[i].ss);
1481 DEBUG(10, ("find_new_dc: smbsock_any_connect failed for "
1482 "domain %s address %s. Error was %s\n",
1483 domain->name, ab, nt_errstr(status) ));
1484 winbind_add_failed_connection_entry(domain,
1485 dcs[i].name, NT_STATUS_UNSUCCESSFUL);
1490 *pss = addrs[fd_index];
1492 if (*dcnames[fd_index] != '\0' && !is_ipaddress(dcnames[fd_index])) {
1493 /* Ok, we've got a name for the DC */
1494 *dcname = talloc_strdup(mem_ctx, dcnames[fd_index]);
1495 if (*dcname == NULL) {
1501 /* Try to figure out the name */
1502 if (dcip_to_name(mem_ctx, domain, pss, dcname)) {
1506 /* We can not continue without the DC's name */
1507 winbind_add_failed_connection_entry(domain, dcs[fd_index].name,
1508 NT_STATUS_UNSUCCESSFUL);
1510 /* Throw away all arrays as we're doing this again. */
1514 TALLOC_FREE(dcnames);
1526 static char *current_dc_key(TALLOC_CTX *mem_ctx, const char *domain_name)
1528 return talloc_asprintf_strupper_m(mem_ctx, "CURRENT_DCNAME/%s",
1532 static void store_current_dc_in_gencache(const char *domain_name,
1533 const char *dc_name,
1534 struct cli_state *cli)
1536 char addr[INET6_ADDRSTRLEN];
1540 if (!cli_state_is_connected(cli)) {
1544 print_sockaddr(addr, sizeof(addr),
1545 smbXcli_conn_remote_sockaddr(cli->conn));
1547 key = current_dc_key(talloc_tos(), domain_name);
1552 value = talloc_asprintf(talloc_tos(), "%s %s", addr, dc_name);
1553 if (value == NULL) {
1557 gencache_set(key, value, 0x7fffffff);
1563 bool fetch_current_dc_from_gencache(TALLOC_CTX *mem_ctx,
1564 const char *domain_name,
1565 char **p_dc_name, char **p_dc_ip)
1570 char *dc_name = NULL;
1573 key = current_dc_key(talloc_tos(), domain_name);
1577 if (!gencache_get(key, mem_ctx, &value, NULL)) {
1580 p = strchr(value, ' ');
1584 dc_ip = talloc_strndup(mem_ctx, value, p - value);
1585 if (dc_ip == NULL) {
1588 dc_name = talloc_strdup(mem_ctx, p+1);
1589 if (dc_name == NULL) {
1593 if (p_dc_ip != NULL) {
1597 if (p_dc_name != NULL) {
1598 *p_dc_name = dc_name;
1603 TALLOC_FREE(dc_name);
1610 static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
1611 struct winbindd_cm_conn *new_conn)
1613 TALLOC_CTX *mem_ctx;
1615 char *saf_servername;
1618 if ((mem_ctx = talloc_init("cm_open_connection")) == NULL) {
1619 set_domain_offline(domain);
1620 return NT_STATUS_NO_MEMORY;
1623 saf_servername = saf_fetch(mem_ctx, domain->name );
1625 /* we have to check the server affinity cache here since
1626 later we select a DC based on response time and not preference */
1628 /* Check the negative connection cache
1629 before talking to it. It going down may have
1630 triggered the reconnection. */
1632 if ( saf_servername && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, saf_servername))) {
1634 DEBUG(10,("cm_open_connection: saf_servername is '%s' for domain %s\n",
1635 saf_servername, domain->name ));
1637 /* convert an ip address to a name */
1638 if (is_ipaddress( saf_servername ) ) {
1639 char *dcname = NULL;
1640 struct sockaddr_storage ss;
1642 if (!interpret_string_addr(&ss, saf_servername,
1644 TALLOC_FREE(mem_ctx);
1645 return NT_STATUS_UNSUCCESSFUL;
1647 if (dcip_to_name(mem_ctx, domain, &ss, &dcname)) {
1648 domain->dcname = talloc_strdup(domain,
1650 if (domain->dcname == NULL) {
1651 TALLOC_FREE(mem_ctx);
1652 return NT_STATUS_NO_MEMORY;
1655 winbind_add_failed_connection_entry(
1656 domain, saf_servername,
1657 NT_STATUS_UNSUCCESSFUL);
1660 domain->dcname = talloc_strdup(domain, saf_servername);
1661 if (domain->dcname == NULL) {
1662 TALLOC_FREE(mem_ctx);
1663 return NT_STATUS_NO_MEMORY;
1668 for (retries = 0; retries < 3; retries++) {
1671 char *dcname = NULL;
1673 result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1675 DEBUG(10,("cm_open_connection: dcname is '%s' for domain %s\n",
1676 domain->dcname ? domain->dcname : "", domain->name ));
1678 if (domain->dcname != NULL
1679 && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, domain->dcname))
1680 && (resolve_name(domain->dcname, &domain->dcaddr, 0x20, true)))
1684 status = smbsock_connect(&domain->dcaddr, 0,
1687 if (!NT_STATUS_IS_OK(status)) {
1693 !find_new_dc(mem_ctx, domain, &dcname, &domain->dcaddr, &fd))
1695 /* This is the one place where we will
1696 set the global winbindd offline state
1697 to true, if a "WINBINDD_OFFLINE" entry
1698 is found in the winbindd cache. */
1699 set_global_winbindd_state_offline();
1702 if (dcname != NULL) {
1703 talloc_free(domain->dcname);
1705 domain->dcname = talloc_move(domain, &dcname);
1706 if (domain->dcname == NULL) {
1707 result = NT_STATUS_NO_MEMORY;
1712 new_conn->cli = NULL;
1714 result = cm_prepare_connection(domain, fd, domain->dcname,
1715 &new_conn->cli, &retry);
1716 if (!NT_STATUS_IS_OK(result)) {
1717 /* Don't leak the smb connection socket */
1725 if (NT_STATUS_IS_OK(result)) {
1726 bool seal_pipes = true;
1728 winbindd_set_locator_kdc_envs(domain);
1730 if (domain->online == False) {
1731 /* We're changing state from offline to online. */
1732 set_global_winbindd_state_online();
1734 set_domain_online(domain);
1737 * Much as I hate global state, this seems to be the point
1738 * where we can be certain that we have a proper connection to
1739 * a DC. wbinfo --dc-info needs that information, store it in
1740 * gencache with a looong timeout. This will need revisiting
1741 * once we start to connect to multiple DCs, wbcDcInfo is
1742 * already prepared for that.
1744 store_current_dc_in_gencache(domain->name, domain->dcname,
1747 seal_pipes = lp_winbind_sealed_pipes();
1748 seal_pipes = lp_parm_bool(-1, "winbind sealed pipes",
1753 new_conn->auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
1755 new_conn->auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
1758 /* Ensure we setup the retry handler. */
1759 set_domain_offline(domain);
1762 talloc_destroy(mem_ctx);
1766 /* Close down all open pipes on a connection. */
1768 void invalidate_cm_connection(struct winbindd_cm_conn *conn)
1772 /* We're closing down a possibly dead
1773 connection. Don't have impossibly long (10s) timeouts. */
1776 cli_set_timeout(conn->cli, 1000); /* 1 second. */
1779 if (conn->samr_pipe != NULL) {
1780 if (is_valid_policy_hnd(&conn->sam_connect_handle)) {
1781 dcerpc_samr_Close(conn->samr_pipe->binding_handle,
1783 &conn->sam_connect_handle,
1786 TALLOC_FREE(conn->samr_pipe);
1787 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1789 cli_set_timeout(conn->cli, 500);
1793 if (conn->lsa_pipe != NULL) {
1794 if (is_valid_policy_hnd(&conn->lsa_policy)) {
1795 dcerpc_lsa_Close(conn->lsa_pipe->binding_handle,
1800 TALLOC_FREE(conn->lsa_pipe);
1801 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1803 cli_set_timeout(conn->cli, 500);
1807 if (conn->lsa_pipe_tcp != NULL) {
1808 if (is_valid_policy_hnd(&conn->lsa_policy)) {
1809 dcerpc_lsa_Close(conn->lsa_pipe_tcp->binding_handle,
1814 TALLOC_FREE(conn->lsa_pipe_tcp);
1815 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1817 cli_set_timeout(conn->cli, 500);
1821 if (conn->netlogon_pipe != NULL) {
1822 TALLOC_FREE(conn->netlogon_pipe);
1823 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1825 cli_set_timeout(conn->cli, 500);
1829 conn->auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
1830 conn->netlogon_force_reauth = false;
1831 conn->netlogon_flags = 0;
1832 TALLOC_FREE(conn->netlogon_creds);
1835 cli_shutdown(conn->cli);
1841 void close_conns_after_fork(void)
1843 struct winbindd_domain *domain;
1844 struct winbindd_cli_state *cli_state;
1846 for (domain = domain_list(); domain; domain = domain->next) {
1848 * first close the low level SMB TCP connection
1849 * so that we don't generate any SMBclose
1850 * requests in invalidate_cm_connection()
1852 if (cli_state_is_connected(domain->conn.cli)) {
1853 smbXcli_conn_disconnect(domain->conn.cli->conn, NT_STATUS_OK);
1856 invalidate_cm_connection(&domain->conn);
1859 for (cli_state = winbindd_client_list();
1861 cli_state = cli_state->next) {
1862 if (cli_state->sock >= 0) {
1863 close(cli_state->sock);
1864 cli_state->sock = -1;
1869 static bool connection_ok(struct winbindd_domain *domain)
1873 ok = cli_state_is_connected(domain->conn.cli);
1875 DEBUG(3, ("connection_ok: Connection to %s for domain %s is not connected\n",
1876 domain->dcname, domain->name));
1880 if (domain->online == False) {
1881 DEBUG(3, ("connection_ok: Domain %s is offline\n", domain->name));
1888 /* Initialize a new connection up to the RPC BIND.
1889 Bypass online status check so always does network calls. */
1891 static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain)
1895 /* Internal connections never use the network. */
1896 if (domain->internal) {
1897 domain->initialized = True;
1898 return NT_STATUS_OK;
1901 if (connection_ok(domain)) {
1902 if (!domain->initialized) {
1903 set_dc_type_and_flags(domain);
1905 return NT_STATUS_OK;
1908 invalidate_cm_connection(&domain->conn);
1910 result = cm_open_connection(domain, &domain->conn);
1912 if (NT_STATUS_IS_OK(result) && !domain->initialized) {
1913 set_dc_type_and_flags(domain);
1919 NTSTATUS init_dc_connection(struct winbindd_domain *domain)
1921 if (domain->internal) {
1922 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1925 if (domain->initialized && !domain->online) {
1926 /* We check for online status elsewhere. */
1927 return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1930 return init_dc_connection_network(domain);
1933 static NTSTATUS init_dc_connection_rpc(struct winbindd_domain *domain)
1937 status = init_dc_connection(domain);
1938 if (!NT_STATUS_IS_OK(status)) {
1942 if (!domain->internal && domain->conn.cli == NULL) {
1943 /* happens for trusted domains without inbound trust */
1944 return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
1947 return NT_STATUS_OK;
1950 /******************************************************************************
1951 Set the trust flags (direction and forest location) for a domain
1952 ******************************************************************************/
1954 static bool set_dc_type_and_flags_trustinfo( struct winbindd_domain *domain )
1956 struct winbindd_domain *our_domain;
1957 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1959 struct netr_DomainTrustList trusts;
1961 uint32 flags = (NETR_TRUST_FLAG_IN_FOREST |
1962 NETR_TRUST_FLAG_OUTBOUND |
1963 NETR_TRUST_FLAG_INBOUND);
1964 struct rpc_pipe_client *cli;
1965 TALLOC_CTX *mem_ctx = NULL;
1966 struct dcerpc_binding_handle *b;
1968 DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s\n", domain->name ));
1970 /* Our primary domain doesn't need to worry about trust flags.
1971 Force it to go through the network setup */
1972 if ( domain->primary ) {
1976 our_domain = find_our_domain();
1978 if ( !connection_ok(our_domain) ) {
1979 DEBUG(3,("set_dc_type_and_flags_trustinfo: No connection to our domain!\n"));
1983 /* This won't work unless our domain is AD */
1985 if ( !our_domain->active_directory ) {
1989 /* Use DsEnumerateDomainTrusts to get us the trust direction
1992 result = cm_connect_netlogon(our_domain, &cli);
1994 if (!NT_STATUS_IS_OK(result)) {
1995 DEBUG(5, ("set_dc_type_and_flags_trustinfo: Could not open "
1996 "a connection to %s for PIPE_NETLOGON (%s)\n",
1997 domain->name, nt_errstr(result)));
2001 b = cli->binding_handle;
2003 if ( (mem_ctx = talloc_init("set_dc_type_and_flags_trustinfo")) == NULL ) {
2004 DEBUG(0,("set_dc_type_and_flags_trustinfo: talloc_init() failed!\n"));
2008 result = dcerpc_netr_DsrEnumerateDomainTrusts(b, mem_ctx,
2013 if (!NT_STATUS_IS_OK(result)) {
2014 DEBUG(0,("set_dc_type_and_flags_trustinfo: "
2015 "failed to query trusted domain list: %s\n",
2016 nt_errstr(result)));
2017 talloc_destroy(mem_ctx);
2020 if (!W_ERROR_IS_OK(werr)) {
2021 DEBUG(0,("set_dc_type_and_flags_trustinfo: "
2022 "failed to query trusted domain list: %s\n",
2024 talloc_destroy(mem_ctx);
2028 /* Now find the domain name and get the flags */
2030 for ( i=0; i<trusts.count; i++ ) {
2031 if ( strequal( domain->name, trusts.array[i].netbios_name) ) {
2032 domain->domain_flags = trusts.array[i].trust_flags;
2033 domain->domain_type = trusts.array[i].trust_type;
2034 domain->domain_trust_attribs = trusts.array[i].trust_attributes;
2036 if ( domain->domain_type == NETR_TRUST_TYPE_UPLEVEL )
2037 domain->active_directory = True;
2039 /* This flag is only set if the domain is *our*
2040 primary domain and the primary domain is in
2043 domain->native_mode = (domain->domain_flags & NETR_TRUST_FLAG_NATIVE);
2045 DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s is %sin "
2046 "native mode.\n", domain->name,
2047 domain->native_mode ? "" : "NOT "));
2049 DEBUG(5,("set_dc_type_and_flags_trustinfo: domain %s is %s"
2050 "running active directory.\n", domain->name,
2051 domain->active_directory ? "" : "NOT "));
2053 domain->can_do_ncacn_ip_tcp = domain->active_directory;
2055 domain->initialized = True;
2061 talloc_destroy( mem_ctx );
2063 return domain->initialized;
2066 /******************************************************************************
2067 We can 'sense' certain things about the DC by it's replies to certain
2070 This tells us if this particular remote server is Active Directory, and if it
2072 ******************************************************************************/
2074 static void set_dc_type_and_flags_connect( struct winbindd_domain *domain )
2076 NTSTATUS status, result;
2078 TALLOC_CTX *mem_ctx = NULL;
2079 struct rpc_pipe_client *cli = NULL;
2080 struct policy_handle pol;
2081 union dssetup_DsRoleInfo info;
2082 union lsa_PolicyInformation *lsa_info = NULL;
2084 if (!connection_ok(domain)) {
2088 mem_ctx = talloc_init("set_dc_type_and_flags on domain %s\n",
2091 DEBUG(1, ("set_dc_type_and_flags_connect: talloc_init() failed\n"));
2095 DEBUG(5, ("set_dc_type_and_flags_connect: domain %s\n", domain->name ));
2097 status = cli_rpc_pipe_open_noauth(domain->conn.cli,
2101 if (!NT_STATUS_IS_OK(status)) {
2102 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
2103 "PI_DSSETUP on domain %s: (%s)\n",
2104 domain->name, nt_errstr(status)));
2106 /* if this is just a non-AD domain we need to continue
2107 * identifying so that we can in the end return with
2108 * domain->initialized = True - gd */
2113 status = dcerpc_dssetup_DsRoleGetPrimaryDomainInformation(cli->binding_handle, mem_ctx,
2114 DS_ROLE_BASIC_INFORMATION,
2119 if (NT_STATUS_IS_OK(status)) {
2120 result = werror_to_ntstatus(werr);
2122 if (!NT_STATUS_IS_OK(status)) {
2123 DEBUG(5, ("set_dc_type_and_flags_connect: rpccli_ds_getprimarydominfo "
2124 "on domain %s failed: (%s)\n",
2125 domain->name, nt_errstr(status)));
2127 /* older samba3 DCs will return DCERPC_FAULT_OP_RNG_ERROR for
2128 * every opcode on the DSSETUP pipe, continue with
2129 * no_dssetup mode here as well to get domain->initialized
2132 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
2136 TALLOC_FREE(mem_ctx);
2140 if ((info.basic.flags & DS_ROLE_PRIMARY_DS_RUNNING) &&
2141 !(info.basic.flags & DS_ROLE_PRIMARY_DS_MIXED_MODE)) {
2142 domain->native_mode = True;
2144 domain->native_mode = False;
2148 status = cli_rpc_pipe_open_noauth(domain->conn.cli,
2149 &ndr_table_lsarpc, &cli);
2151 if (!NT_STATUS_IS_OK(status)) {
2152 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
2153 "PI_LSARPC on domain %s: (%s)\n",
2154 domain->name, nt_errstr(status)));
2156 TALLOC_FREE(mem_ctx);
2160 status = rpccli_lsa_open_policy2(cli, mem_ctx, True,
2161 SEC_FLAG_MAXIMUM_ALLOWED, &pol);
2163 if (NT_STATUS_IS_OK(status)) {
2164 /* This particular query is exactly what Win2k clients use
2165 to determine that the DC is active directory */
2166 status = dcerpc_lsa_QueryInfoPolicy2(cli->binding_handle, mem_ctx,
2168 LSA_POLICY_INFO_DNS,
2173 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2174 domain->active_directory = True;
2176 if (lsa_info->dns.name.string) {
2177 talloc_free(domain->name);
2178 domain->name = talloc_strdup(domain,
2179 lsa_info->dns.name.string);
2180 if (domain->name == NULL) {
2185 if (lsa_info->dns.dns_domain.string) {
2186 talloc_free(domain->alt_name);
2188 talloc_strdup(domain,
2189 lsa_info->dns.dns_domain.string);
2190 if (domain->alt_name == NULL) {
2195 /* See if we can set some domain trust flags about
2198 if (lsa_info->dns.dns_forest.string) {
2199 talloc_free(domain->forest_name);
2200 domain->forest_name =
2201 talloc_strdup(domain,
2202 lsa_info->dns.dns_forest.string);
2203 if (domain->forest_name == NULL) {
2207 if (strequal(domain->forest_name, domain->alt_name)) {
2208 domain->domain_flags |= NETR_TRUST_FLAG_TREEROOT;
2212 if (lsa_info->dns.sid) {
2213 sid_copy(&domain->sid, lsa_info->dns.sid);
2216 domain->active_directory = False;
2218 status = rpccli_lsa_open_policy(cli, mem_ctx, True,
2219 SEC_FLAG_MAXIMUM_ALLOWED,
2222 if (!NT_STATUS_IS_OK(status)) {
2226 status = dcerpc_lsa_QueryInfoPolicy(cli->binding_handle, mem_ctx,
2228 LSA_POLICY_INFO_ACCOUNT_DOMAIN,
2231 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2233 if (lsa_info->account_domain.name.string) {
2234 talloc_free(domain->name);
2236 talloc_strdup(domain,
2237 lsa_info->account_domain.name.string);
2240 if (lsa_info->account_domain.sid) {
2241 sid_copy(&domain->sid, lsa_info->account_domain.sid);
2247 DEBUG(5, ("set_dc_type_and_flags_connect: domain %s is %sin native mode.\n",
2248 domain->name, domain->native_mode ? "" : "NOT "));
2250 DEBUG(5,("set_dc_type_and_flags_connect: domain %s is %srunning active directory.\n",
2251 domain->name, domain->active_directory ? "" : "NOT "));
2253 domain->can_do_ncacn_ip_tcp = domain->active_directory;
2257 TALLOC_FREE(mem_ctx);
2259 domain->initialized = True;
2262 /**********************************************************************
2263 Set the domain_flags (trust attributes, domain operating modes, etc...
2264 ***********************************************************************/
2266 static void set_dc_type_and_flags( struct winbindd_domain *domain )
2268 /* we always have to contact our primary domain */
2270 if ( domain->primary ) {
2271 DEBUG(10,("set_dc_type_and_flags: setting up flags for "
2272 "primary domain\n"));
2273 set_dc_type_and_flags_connect( domain );
2277 /* Use our DC to get the information if possible */
2279 if ( !set_dc_type_and_flags_trustinfo( domain ) ) {
2280 /* Otherwise, fallback to contacting the
2282 set_dc_type_and_flags_connect( domain );
2290 /**********************************************************************
2291 ***********************************************************************/
2293 static NTSTATUS cm_get_schannel_creds(struct winbindd_domain *domain,
2294 struct netlogon_creds_cli_context **ppdc)
2296 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2297 struct rpc_pipe_client *netlogon_pipe;
2301 if ((!IS_DC) && (!domain->primary)) {
2302 return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
2305 if (domain->conn.netlogon_creds != NULL) {
2306 if (!(domain->conn.netlogon_flags & NETLOGON_NEG_AUTHENTICATED_RPC)) {
2307 return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
2309 *ppdc = domain->conn.netlogon_creds;
2310 return NT_STATUS_OK;
2313 result = cm_connect_netlogon(domain, &netlogon_pipe);
2314 if (!NT_STATUS_IS_OK(result)) {
2318 if (domain->conn.netlogon_creds == NULL) {
2319 return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
2322 if (!(domain->conn.netlogon_flags & NETLOGON_NEG_AUTHENTICATED_RPC)) {
2323 return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
2326 *ppdc = domain->conn.netlogon_creds;
2327 return NT_STATUS_OK;
2330 NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
2331 struct rpc_pipe_client **cli, struct policy_handle *sam_handle)
2333 struct winbindd_cm_conn *conn;
2334 NTSTATUS status, result;
2335 struct netlogon_creds_cli_context *p_creds;
2336 char *machine_password = NULL;
2337 char *machine_account = NULL;
2338 const char *domain_name = NULL;
2340 if (sid_check_is_our_sam(&domain->sid)) {
2341 return open_internal_samr_conn(mem_ctx, domain, cli, sam_handle);
2344 status = init_dc_connection_rpc(domain);
2345 if (!NT_STATUS_IS_OK(status)) {
2349 conn = &domain->conn;
2351 if (rpccli_is_connected(conn->samr_pipe)) {
2355 TALLOC_FREE(conn->samr_pipe);
2358 * No SAMR pipe yet. Attempt to get an NTLMSSP SPNEGO authenticated
2359 * sign and sealed pipe using the machine account password by
2360 * preference. If we can't - try schannel, if that fails, try
2364 if ((conn->cli->user_name[0] == '\0') ||
2365 (conn->cli->domain[0] == '\0') ||
2366 (conn->cli->password == NULL || conn->cli->password[0] == '\0'))
2368 status = get_trust_creds(domain, &machine_password,
2369 &machine_account, NULL);
2370 if (!NT_STATUS_IS_OK(status)) {
2371 DEBUG(10, ("cm_connect_sam: No no user available for "
2372 "domain %s, trying schannel\n", conn->cli->domain));
2375 domain_name = domain->name;
2377 machine_password = SMB_STRDUP(conn->cli->password);
2378 machine_account = SMB_STRDUP(conn->cli->user_name);
2379 domain_name = conn->cli->domain;
2382 if (!machine_password || !machine_account) {
2383 status = NT_STATUS_NO_MEMORY;
2387 /* We have an authenticated connection. Use a NTLMSSP SPNEGO
2388 authenticated SAMR pipe with sign & seal. */
2389 status = cli_rpc_pipe_open_spnego(conn->cli,
2394 smbXcli_conn_remote_name(conn->cli->conn),
2400 if (!NT_STATUS_IS_OK(status)) {
2401 DEBUG(10,("cm_connect_sam: failed to connect to SAMR "
2402 "pipe for domain %s using NTLMSSP "
2403 "authenticated pipe: user %s\\%s. Error was "
2404 "%s\n", domain->name, domain_name,
2405 machine_account, nt_errstr(status)));
2409 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for "
2410 "domain %s using NTLMSSP authenticated "
2411 "pipe: user %s\\%s\n", domain->name,
2412 domain_name, machine_account));
2414 status = dcerpc_samr_Connect2(conn->samr_pipe->binding_handle, mem_ctx,
2415 conn->samr_pipe->desthost,
2416 SEC_FLAG_MAXIMUM_ALLOWED,
2417 &conn->sam_connect_handle,
2419 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2422 if (NT_STATUS_IS_OK(status)) {
2426 DEBUG(10,("cm_connect_sam: ntlmssp-sealed dcerpc_samr_Connect2 "
2427 "failed for domain %s, error was %s. Trying schannel\n",
2428 domain->name, nt_errstr(status) ));
2429 TALLOC_FREE(conn->samr_pipe);
2433 /* Fall back to schannel if it's a W2K pre-SP1 box. */
2435 status = cm_get_schannel_creds(domain, &p_creds);
2436 if (!NT_STATUS_IS_OK(status)) {
2437 /* If this call fails - conn->cli can now be NULL ! */
2438 DEBUG(10, ("cm_connect_sam: Could not get schannel auth info "
2439 "for domain %s (error %s), trying anon\n",
2441 nt_errstr(status) ));
2444 status = cli_rpc_pipe_open_schannel_with_key
2445 (conn->cli, &ndr_table_samr, NCACN_NP,
2446 domain->name, p_creds, &conn->samr_pipe);
2448 if (!NT_STATUS_IS_OK(status)) {
2449 DEBUG(10,("cm_connect_sam: failed to connect to SAMR pipe for "
2450 "domain %s using schannel. Error was %s\n",
2451 domain->name, nt_errstr(status) ));
2454 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for domain %s using "
2455 "schannel.\n", domain->name ));
2457 status = dcerpc_samr_Connect2(conn->samr_pipe->binding_handle, mem_ctx,
2458 conn->samr_pipe->desthost,
2459 SEC_FLAG_MAXIMUM_ALLOWED,
2460 &conn->sam_connect_handle,
2462 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2465 if (NT_STATUS_IS_OK(status)) {
2468 DEBUG(10,("cm_connect_sam: schannel-sealed dcerpc_samr_Connect2 failed "
2469 "for domain %s, error was %s. Trying anonymous\n",
2470 domain->name, nt_errstr(status) ));
2471 TALLOC_FREE(conn->samr_pipe);
2475 /* Finally fall back to anonymous. */
2476 status = cli_rpc_pipe_open_noauth(conn->cli, &ndr_table_samr,
2479 if (!NT_STATUS_IS_OK(status)) {
2483 status = dcerpc_samr_Connect2(conn->samr_pipe->binding_handle, mem_ctx,
2484 conn->samr_pipe->desthost,
2485 SEC_FLAG_MAXIMUM_ALLOWED,
2486 &conn->sam_connect_handle,
2488 if (!NT_STATUS_IS_OK(status)) {
2489 DEBUG(10,("cm_connect_sam: rpccli_samr_Connect2 failed "
2490 "for domain %s Error was %s\n",
2491 domain->name, nt_errstr(status) ));
2494 if (!NT_STATUS_IS_OK(result)) {
2496 DEBUG(10,("cm_connect_sam: dcerpc_samr_Connect2 failed "
2497 "for domain %s Error was %s\n",
2498 domain->name, nt_errstr(result)));
2503 status = dcerpc_samr_OpenDomain(conn->samr_pipe->binding_handle,
2505 &conn->sam_connect_handle,
2506 SEC_FLAG_MAXIMUM_ALLOWED,
2508 &conn->sam_domain_handle,
2510 if (!NT_STATUS_IS_OK(status)) {
2517 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2519 * if we got access denied, we might just have no access rights
2520 * to talk to the remote samr server server (e.g. when we are a
2521 * PDC and we are connecting a w2k8 pdc via an interdomain
2522 * trust). In that case do not invalidate the whole connection
2525 TALLOC_FREE(conn->samr_pipe);
2526 ZERO_STRUCT(conn->sam_domain_handle);
2528 } else if (!NT_STATUS_IS_OK(status)) {
2529 invalidate_cm_connection(conn);
2533 *cli = conn->samr_pipe;
2534 *sam_handle = conn->sam_domain_handle;
2535 SAFE_FREE(machine_password);
2536 SAFE_FREE(machine_account);
2540 /**********************************************************************
2541 open an schanneld ncacn_ip_tcp connection to LSA
2542 ***********************************************************************/
2544 NTSTATUS cm_connect_lsa_tcp(struct winbindd_domain *domain,
2545 TALLOC_CTX *mem_ctx,
2546 struct rpc_pipe_client **cli)
2548 struct winbindd_cm_conn *conn;
2549 struct netlogon_creds_cli_context *creds;
2552 DEBUG(10,("cm_connect_lsa_tcp\n"));
2554 status = init_dc_connection_rpc(domain);
2555 if (!NT_STATUS_IS_OK(status)) {
2559 conn = &domain->conn;
2561 if (conn->lsa_pipe_tcp &&
2562 conn->lsa_pipe_tcp->transport->transport == NCACN_IP_TCP &&
2563 conn->lsa_pipe_tcp->auth->auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY &&
2564 rpccli_is_connected(conn->lsa_pipe_tcp)) {
2568 TALLOC_FREE(conn->lsa_pipe_tcp);
2570 status = cm_get_schannel_creds(domain, &creds);
2571 if (!NT_STATUS_IS_OK(status)) {
2575 status = cli_rpc_pipe_open_schannel_with_key(conn->cli,
2580 &conn->lsa_pipe_tcp);
2581 if (!NT_STATUS_IS_OK(status)) {
2582 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key failed: %s\n",
2583 nt_errstr(status)));
2588 if (!NT_STATUS_IS_OK(status)) {
2589 TALLOC_FREE(conn->lsa_pipe_tcp);
2593 *cli = conn->lsa_pipe_tcp;
2598 NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
2599 struct rpc_pipe_client **cli, struct policy_handle *lsa_policy)
2601 struct winbindd_cm_conn *conn;
2602 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2603 struct netlogon_creds_cli_context *p_creds;
2605 result = init_dc_connection_rpc(domain);
2606 if (!NT_STATUS_IS_OK(result))
2609 conn = &domain->conn;
2611 if (rpccli_is_connected(conn->lsa_pipe)) {
2615 TALLOC_FREE(conn->lsa_pipe);
2617 if ((conn->cli->user_name[0] == '\0') ||
2618 (conn->cli->domain[0] == '\0') ||
2619 (conn->cli->password == NULL || conn->cli->password[0] == '\0')) {
2620 DEBUG(10, ("cm_connect_lsa: No no user available for "
2621 "domain %s, trying schannel\n", conn->cli->domain));
2625 /* We have an authenticated connection. Use a NTLMSSP SPNEGO
2626 * authenticated LSA pipe with sign & seal. */
2627 result = cli_rpc_pipe_open_spnego
2628 (conn->cli, &ndr_table_lsarpc, NCACN_NP,
2631 smbXcli_conn_remote_name(conn->cli->conn),
2632 conn->cli->domain, conn->cli->user_name, conn->cli->password,
2635 if (!NT_STATUS_IS_OK(result)) {
2636 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
2637 "domain %s using NTLMSSP authenticated pipe: user "
2638 "%s\\%s. Error was %s. Trying schannel.\n",
2639 domain->name, conn->cli->domain,
2640 conn->cli->user_name, nt_errstr(result)));
2644 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
2645 "NTLMSSP authenticated pipe: user %s\\%s\n",
2646 domain->name, conn->cli->domain, conn->cli->user_name ));
2648 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2649 SEC_FLAG_MAXIMUM_ALLOWED,
2651 if (NT_STATUS_IS_OK(result)) {
2655 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
2658 TALLOC_FREE(conn->lsa_pipe);
2662 /* Fall back to schannel if it's a W2K pre-SP1 box. */
2664 result = cm_get_schannel_creds(domain, &p_creds);
2665 if (!NT_STATUS_IS_OK(result)) {
2666 /* If this call fails - conn->cli can now be NULL ! */
2667 DEBUG(10, ("cm_connect_lsa: Could not get schannel auth info "
2668 "for domain %s (error %s), trying anon\n",
2670 nt_errstr(result) ));
2673 result = cli_rpc_pipe_open_schannel_with_key
2674 (conn->cli, &ndr_table_lsarpc, NCACN_NP,
2675 domain->name, p_creds, &conn->lsa_pipe);
2677 if (!NT_STATUS_IS_OK(result)) {
2678 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
2679 "domain %s using schannel. Error was %s\n",
2680 domain->name, nt_errstr(result) ));
2683 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
2684 "schannel.\n", domain->name ));
2686 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2687 SEC_FLAG_MAXIMUM_ALLOWED,
2689 if (NT_STATUS_IS_OK(result)) {
2693 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
2696 TALLOC_FREE(conn->lsa_pipe);
2700 result = cli_rpc_pipe_open_noauth(conn->cli,
2703 if (!NT_STATUS_IS_OK(result)) {
2707 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2708 SEC_FLAG_MAXIMUM_ALLOWED,
2711 if (!NT_STATUS_IS_OK(result)) {
2712 invalidate_cm_connection(conn);
2716 *cli = conn->lsa_pipe;
2717 *lsa_policy = conn->lsa_policy;
2721 /****************************************************************************
2722 Open a LSA connection to a DC, suiteable for LSA lookup calls.
2723 ****************************************************************************/
2725 NTSTATUS cm_connect_lsat(struct winbindd_domain *domain,
2726 TALLOC_CTX *mem_ctx,
2727 struct rpc_pipe_client **cli,
2728 struct policy_handle *lsa_policy)
2732 if (domain->can_do_ncacn_ip_tcp) {
2733 status = cm_connect_lsa_tcp(domain, mem_ctx, cli);
2734 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
2735 NT_STATUS_EQUAL(status, NT_STATUS_RPC_SEC_PKG_ERROR) ||
2736 NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
2737 invalidate_cm_connection(&domain->conn);
2738 status = cm_connect_lsa_tcp(domain, mem_ctx, cli);
2740 if (NT_STATUS_IS_OK(status)) {
2745 * we tried twice to connect via ncan_ip_tcp and schannel and
2746 * failed - maybe it is a trusted domain we can't connect to ?
2747 * do not try tcp next time - gd
2749 domain->can_do_ncacn_ip_tcp = false;
2752 status = cm_connect_lsa(domain, mem_ctx, cli, lsa_policy);
2757 /****************************************************************************
2758 Open the netlogon pipe to this DC. Use schannel if specified in client conf.
2759 session key stored in conn->netlogon_pipe->dc->sess_key.
2760 ****************************************************************************/
2762 NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
2763 struct rpc_pipe_client **cli)
2765 struct messaging_context *msg_ctx = winbind_messaging_context();
2766 struct winbindd_cm_conn *conn;
2768 enum netr_SchannelType sec_chan_type;
2769 const char *_account_name;
2770 const char *account_name;
2771 struct samr_Password current_nt_hash;
2772 struct samr_Password *previous_nt_hash = NULL;
2773 struct netlogon_creds_CredentialState *creds = NULL;
2778 result = init_dc_connection_rpc(domain);
2779 if (!NT_STATUS_IS_OK(result)) {
2783 conn = &domain->conn;
2785 if (rpccli_is_connected(conn->netlogon_pipe)) {
2786 *cli = conn->netlogon_pipe;
2787 return NT_STATUS_OK;
2790 TALLOC_FREE(conn->netlogon_pipe);
2791 conn->netlogon_flags = 0;
2792 TALLOC_FREE(conn->netlogon_creds);
2794 if ((!IS_DC) && (!domain->primary)) {
2798 ok = get_trust_pw_hash(domain->name,
2799 current_nt_hash.hash,
2803 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2806 account_name = talloc_asprintf(talloc_tos(), "%s$", _account_name);
2807 if (account_name == NULL) {
2808 return NT_STATUS_NO_MEMORY;
2811 result = rpccli_create_netlogon_creds(domain->dcname,
2817 &conn->netlogon_creds);
2818 if (!NT_STATUS_IS_OK(result)) {
2819 SAFE_FREE(previous_nt_hash);
2823 result = rpccli_setup_netlogon_creds(conn->cli,
2824 conn->netlogon_creds,
2825 conn->netlogon_force_reauth,
2828 conn->netlogon_force_reauth = false;
2829 SAFE_FREE(previous_nt_hash);
2830 if (!NT_STATUS_IS_OK(result)) {
2834 result = netlogon_creds_cli_get(conn->netlogon_creds,
2837 if (!NT_STATUS_IS_OK(result)) {
2840 conn->netlogon_flags = creds->negotiate_flags;
2844 if (!(conn->netlogon_flags & NETLOGON_NEG_AUTHENTICATED_RPC)) {
2845 result = cli_rpc_pipe_open_noauth(conn->cli,
2846 &ndr_table_netlogon,
2847 &conn->netlogon_pipe);
2848 if (!NT_STATUS_IS_OK(result)) {
2849 invalidate_cm_connection(conn);
2853 *cli = conn->netlogon_pipe;
2854 return NT_STATUS_OK;
2857 /* Using the credentials from the first pipe, open a signed and sealed
2858 second netlogon pipe. The session key is stored in the schannel
2859 part of the new pipe auth struct.
2862 result = cli_rpc_pipe_open_schannel_with_key(
2863 conn->cli, &ndr_table_netlogon, NCACN_NP,
2865 conn->netlogon_creds,
2866 &conn->netlogon_pipe);
2867 if (!NT_STATUS_IS_OK(result)) {
2868 DEBUG(3, ("Could not open schannel'ed NETLOGON pipe. Error "
2869 "was %s\n", nt_errstr(result)));
2871 invalidate_cm_connection(conn);
2875 *cli = conn->netlogon_pipe;
2876 return NT_STATUS_OK;
2879 void winbind_msg_ip_dropped(struct messaging_context *msg_ctx,
2882 struct server_id server_id,
2885 struct winbindd_domain *domain;
2886 char *freeit = NULL;
2890 || (data->data == NULL)
2891 || (data->length == 0)
2892 || (data->data[data->length-1] != '\0')) {
2893 DEBUG(1, ("invalid msg_ip_dropped message: not a valid "
2898 addr = (char *)data->data;
2899 DEBUG(10, ("IP %s dropped\n", addr));
2901 if (!is_ipaddress(addr)) {
2904 * Some code sends us ip addresses with the /netmask
2907 slash = strchr(addr, '/');
2908 if (slash == NULL) {
2909 DEBUG(1, ("invalid msg_ip_dropped message: %s",
2913 freeit = talloc_strndup(talloc_tos(), addr, slash-addr);
2914 if (freeit == NULL) {
2915 DEBUG(1, ("talloc failed\n"));
2919 DEBUG(10, ("Stripped /netmask to IP %s\n", addr));
2922 for (domain = domain_list(); domain != NULL; domain = domain->next) {
2923 char sockaddr[INET6_ADDRSTRLEN];
2925 if (!cli_state_is_connected(domain->conn.cli)) {
2929 print_sockaddr(sockaddr, sizeof(sockaddr),
2930 smbXcli_conn_local_sockaddr(domain->conn.cli->conn));
2932 if (strequal(sockaddr, addr)) {
2933 smbXcli_conn_disconnect(domain->conn.cli->conn, NT_STATUS_OK);
2936 TALLOC_FREE(freeit);