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 "libsmb/namequery.h"
64 #include "../libcli/auth/libcli_auth.h"
65 #include "../librpc/gen_ndr/ndr_netlogon_c.h"
66 #include "rpc_client/cli_pipe.h"
67 #include "rpc_client/cli_netlogon.h"
68 #include "../librpc/gen_ndr/ndr_samr_c.h"
69 #include "../librpc/gen_ndr/ndr_lsa_c.h"
70 #include "rpc_client/cli_lsarpc.h"
71 #include "../librpc/gen_ndr/ndr_dssetup_c.h"
72 #include "libads/sitename_cache.h"
73 #include "libsmb/libsmb.h"
74 #include "libsmb/clidgram.h"
77 #include "../libcli/security/security.h"
80 #include "auth/gensec/gensec.h"
81 #include "../libcli/smb/smbXcli_base.h"
82 #include "libcli/auth/netlogon_creds_cli.h"
84 #include "rpc_server/rpc_ncacn_np.h"
85 #include "auth/credentials/credentials.h"
86 #include "lib/param/param.h"
87 #include "lib/gencache.h"
90 #define DBGC_CLASS DBGC_WINBIND
94 struct sockaddr_storage ss
;
97 extern struct winbindd_methods reconnect_methods
;
98 extern bool override_logfile
;
100 static NTSTATUS
init_dc_connection_network(struct winbindd_domain
*domain
, bool need_rw_dc
);
101 static void set_dc_type_and_flags( struct winbindd_domain
*domain
);
102 static bool set_dc_type_and_flags_trustinfo( struct winbindd_domain
*domain
);
103 static bool get_dcs(TALLOC_CTX
*mem_ctx
, struct winbindd_domain
*domain
,
104 struct dc_name_ip
**dcs
, int *num_dcs
,
105 uint32_t request_flags
);
107 /****************************************************************
108 Child failed to find DC's. Reschedule check.
109 ****************************************************************/
111 static void msg_failed_to_go_online(struct messaging_context
*msg
,
114 struct server_id server_id
,
117 struct winbindd_domain
*domain
;
118 const char *domainname
= (const char *)data
->data
;
120 if (data
->data
== NULL
|| data
->length
== 0) {
124 DEBUG(5,("msg_fail_to_go_online: received for domain %s.\n", domainname
));
126 for (domain
= domain_list(); domain
; domain
= domain
->next
) {
127 if (domain
->internal
) {
131 if (strequal(domain
->name
, domainname
)) {
132 if (domain
->online
) {
133 /* We're already online, ignore. */
134 DEBUG(5,("msg_fail_to_go_online: domain %s "
135 "already online.\n", domainname
));
139 /* Reschedule the online check. */
140 set_domain_offline(domain
);
146 /****************************************************************
147 Actually cause a reconnect from a message.
148 ****************************************************************/
150 static void msg_try_to_go_online(struct messaging_context
*msg
,
153 struct server_id server_id
,
156 struct winbindd_domain
*domain
;
157 const char *domainname
= (const char *)data
->data
;
159 if (data
->data
== NULL
|| data
->length
== 0) {
163 DEBUG(5,("msg_try_to_go_online: received for domain %s.\n", domainname
));
165 for (domain
= domain_list(); domain
; domain
= domain
->next
) {
166 if (domain
->internal
) {
170 if (strequal(domain
->name
, domainname
)) {
172 if (domain
->online
) {
173 /* We're already online, ignore. */
174 DEBUG(5,("msg_try_to_go_online: domain %s "
175 "already online.\n", domainname
));
179 /* This call takes care of setting the online
180 flag to true if we connected, or re-adding
181 the offline handler if false. Bypasses online
182 check so always does network calls. */
184 init_dc_connection_network(domain
, true);
190 /****************************************************************
191 Fork a child to try and contact a DC. Do this as contacting a
192 DC requires blocking lookups and we don't want to block our
194 ****************************************************************/
196 static bool fork_child_dc_connect(struct winbindd_domain
*domain
)
198 struct dc_name_ip
*dcs
= NULL
;
200 TALLOC_CTX
*mem_ctx
= NULL
;
201 pid_t parent_pid
= getpid();
206 if (domain
->dc_probe_pid
!= (pid_t
)-1) {
208 * We might already have a DC probe
209 * child working, check.
211 if (process_exists_by_pid(domain
->dc_probe_pid
)) {
212 DEBUG(10,("fork_child_dc_connect: pid %u already "
213 "checking for DC's.\n",
214 (unsigned int)domain
->dc_probe_pid
));
217 domain
->dc_probe_pid
= (pid_t
)-1;
220 domain
->dc_probe_pid
= fork();
222 if (domain
->dc_probe_pid
== (pid_t
)-1) {
223 DEBUG(0, ("fork_child_dc_connect: Could not fork: %s\n", strerror(errno
)));
227 if (domain
->dc_probe_pid
!= (pid_t
)0) {
229 messaging_register(global_messaging_context(), NULL
,
230 MSG_WINBIND_TRY_TO_GO_ONLINE
,
231 msg_try_to_go_online
);
232 messaging_register(global_messaging_context(), NULL
,
233 MSG_WINBIND_FAILED_TO_GO_ONLINE
,
234 msg_failed_to_go_online
);
240 /* Leave messages blocked - we will never process one. */
242 if (!override_logfile
) {
243 if (asprintf(&lfile
, "%s/log.winbindd-dc-connect", get_dyn_LOGFILEBASE()) == -1) {
244 DBG_ERR("fork_child_dc_connect: "
245 "out of memory in asprintf().\n");
250 status
= winbindd_reinit_after_fork(NULL
, lfile
);
251 if (!NT_STATUS_IS_OK(status
)) {
252 DEBUG(1, ("winbindd_reinit_after_fork failed: %s\n",
254 messaging_send_buf(global_messaging_context(),
255 pid_to_procid(parent_pid
),
256 MSG_WINBIND_FAILED_TO_GO_ONLINE
,
257 (const uint8_t *)domain
->name
,
258 strlen(domain
->name
)+1);
263 setproctitle("dc-connect child");
265 mem_ctx
= talloc_init("fork_child_dc_connect");
267 DEBUG(0,("talloc_init failed.\n"));
268 messaging_send_buf(global_messaging_context(),
269 pid_to_procid(parent_pid
),
270 MSG_WINBIND_FAILED_TO_GO_ONLINE
,
271 (const uint8_t *)domain
->name
,
272 strlen(domain
->name
)+1);
276 ok
= get_dcs(mem_ctx
, domain
, &dcs
, &num_dcs
, 0);
277 TALLOC_FREE(mem_ctx
);
278 if (!ok
|| (num_dcs
== 0)) {
279 /* Still offline ? Can't find DC's. */
280 messaging_send_buf(global_messaging_context(),
281 pid_to_procid(parent_pid
),
282 MSG_WINBIND_FAILED_TO_GO_ONLINE
,
283 (const uint8_t *)domain
->name
,
284 strlen(domain
->name
)+1);
288 /* We got a DC. Send a message to our parent to get it to
289 try and do the same. */
291 messaging_send_buf(global_messaging_context(),
292 pid_to_procid(parent_pid
),
293 MSG_WINBIND_TRY_TO_GO_ONLINE
,
294 (const uint8_t *)domain
->name
,
295 strlen(domain
->name
)+1);
299 /****************************************************************
300 Handler triggered if we're offline to try and detect a DC.
301 ****************************************************************/
303 static void check_domain_online_handler(struct tevent_context
*ctx
,
304 struct tevent_timer
*te
,
308 struct winbindd_domain
*domain
=
309 (struct winbindd_domain
*)private_data
;
311 DEBUG(10,("check_domain_online_handler: called for domain "
312 "%s (online = %s)\n", domain
->name
,
313 domain
->online
? "True" : "False" ));
315 TALLOC_FREE(domain
->check_online_event
);
317 /* Are we still in "startup" mode ? */
319 if (domain
->startup
&& (time_mono(NULL
) > domain
->startup_time
+ 30)) {
320 /* No longer in "startup" mode. */
321 DEBUG(10,("check_domain_online_handler: domain %s no longer in 'startup' mode.\n",
323 domain
->startup
= False
;
326 /* We've been told to stay offline, so stay
329 if (get_global_winbindd_state_offline()) {
330 DEBUG(10,("check_domain_online_handler: domain %s remaining globally offline\n",
335 /* Fork a child to test if it can contact a DC.
336 If it can then send ourselves a message to
337 cause a reconnect. */
339 fork_child_dc_connect(domain
);
342 /****************************************************************
343 If we're still offline setup the timeout check.
344 ****************************************************************/
346 static void calc_new_online_timeout_check(struct winbindd_domain
*domain
)
348 int wbr
= lp_winbind_reconnect_delay();
350 if (domain
->startup
) {
351 domain
->check_online_timeout
= 10;
352 } else if (domain
->check_online_timeout
< wbr
) {
353 domain
->check_online_timeout
= wbr
;
357 void winbind_msg_domain_offline(struct messaging_context
*msg_ctx
,
360 struct server_id server_id
,
363 const char *domain_name
= (const char *)data
->data
;
364 struct winbindd_domain
*domain
;
366 domain
= find_domain_from_name_noinit(domain_name
);
367 if (domain
== NULL
) {
371 domain
->online
= false;
373 DEBUG(10, ("Domain %s is marked as offline now.\n",
377 void winbind_msg_domain_online(struct messaging_context
*msg_ctx
,
380 struct server_id server_id
,
383 const char *domain_name
= (const char *)data
->data
;
384 struct winbindd_domain
*domain
;
386 domain
= find_domain_from_name_noinit(domain_name
);
387 if (domain
== NULL
) {
391 domain
->online
= true;
393 DEBUG(10, ("Domain %s is marked as online now.\n",
397 /****************************************************************
398 Set domain offline and also add handler to put us back online
400 ****************************************************************/
402 void set_domain_offline(struct winbindd_domain
*domain
)
404 pid_t parent_pid
= getppid();
406 DEBUG(10,("set_domain_offline: called for domain %s\n",
409 TALLOC_FREE(domain
->check_online_event
);
411 if (domain
->internal
) {
412 DEBUG(3,("set_domain_offline: domain %s is internal - logic error.\n",
417 domain
->online
= False
;
419 /* Offline domains are always initialized. They're
420 re-initialized when they go back online. */
422 domain
->initialized
= True
;
424 /* We only add the timeout handler that checks and
425 allows us to go back online when we've not
426 been told to remain offline. */
428 if (get_global_winbindd_state_offline()) {
429 DEBUG(10,("set_domain_offline: domain %s remaining globally offline\n",
434 /* If we're in startup mode, check again in 10 seconds, not in
435 lp_winbind_reconnect_delay() seconds (which is 30 seconds by default). */
437 calc_new_online_timeout_check(domain
);
439 domain
->check_online_event
= tevent_add_timer(global_event_context(),
441 timeval_current_ofs(domain
->check_online_timeout
,0),
442 check_domain_online_handler
,
445 /* The above *has* to succeed for winbindd to work. */
446 if (!domain
->check_online_event
) {
447 smb_panic("set_domain_offline: failed to add online handler");
450 DEBUG(10,("set_domain_offline: added event handler for domain %s\n",
453 /* Send a message to the parent that the domain is offline. */
454 if (parent_pid
> 1 && !domain
->internal
) {
455 messaging_send_buf(global_messaging_context(),
456 pid_to_procid(parent_pid
),
457 MSG_WINBIND_DOMAIN_OFFLINE
,
458 (uint8_t *)domain
->name
,
459 strlen(domain
->name
) + 1);
462 /* Send an offline message to the idmap child when our
463 primary domain goes offline */
465 if ( domain
->primary
) {
466 struct winbindd_child
*idmap
= idmap_child();
468 if ( idmap
->pid
!= 0 ) {
469 messaging_send_buf(global_messaging_context(),
470 pid_to_procid(idmap
->pid
),
472 (const uint8_t *)domain
->name
,
473 strlen(domain
->name
)+1);
480 /****************************************************************
481 Set domain online - if allowed.
482 ****************************************************************/
484 static void set_domain_online(struct winbindd_domain
*domain
)
486 pid_t parent_pid
= getppid();
488 DEBUG(10,("set_domain_online: called for domain %s\n",
491 if (domain
->internal
) {
492 DEBUG(3,("set_domain_online: domain %s is internal - logic error.\n",
497 if (get_global_winbindd_state_offline()) {
498 DEBUG(10,("set_domain_online: domain %s remaining globally offline\n",
503 winbindd_set_locator_kdc_envs(domain
);
505 /* If we are waiting to get a krb5 ticket, trigger immediately. */
506 ccache_regain_all_now();
508 /* Ok, we're out of any startup mode now... */
509 domain
->startup
= False
;
511 if (domain
->online
== False
) {
512 /* We were offline - now we're online. We default to
513 using the MS-RPC backend if we started offline,
514 and if we're going online for the first time we
515 should really re-initialize the backends and the
516 checks to see if we're talking to an AD or NT domain.
519 domain
->initialized
= False
;
521 /* 'reconnect_methods' is the MS-RPC backend. */
522 if (domain
->backend
== &reconnect_methods
) {
523 domain
->backend
= NULL
;
527 /* Ensure we have no online timeout checks. */
528 domain
->check_online_timeout
= 0;
529 TALLOC_FREE(domain
->check_online_event
);
531 /* Ensure we ignore any pending child messages. */
532 messaging_deregister(global_messaging_context(),
533 MSG_WINBIND_TRY_TO_GO_ONLINE
, NULL
);
534 messaging_deregister(global_messaging_context(),
535 MSG_WINBIND_FAILED_TO_GO_ONLINE
, NULL
);
537 domain
->online
= True
;
539 /* Send a message to the parent that the domain is online. */
540 if (parent_pid
> 1 && !domain
->internal
) {
541 messaging_send_buf(global_messaging_context(),
542 pid_to_procid(parent_pid
),
543 MSG_WINBIND_DOMAIN_ONLINE
,
544 (uint8_t *)domain
->name
,
545 strlen(domain
->name
) + 1);
548 /* Send an online message to the idmap child when our
549 primary domain comes online */
551 if ( domain
->primary
) {
552 struct winbindd_child
*idmap
= idmap_child();
554 if ( idmap
->pid
!= 0 ) {
555 messaging_send_buf(global_messaging_context(),
556 pid_to_procid(idmap
->pid
),
558 (const uint8_t *)domain
->name
,
559 strlen(domain
->name
)+1);
566 /****************************************************************
567 Requested to set a domain online.
568 ****************************************************************/
570 void set_domain_online_request(struct winbindd_domain
*domain
)
574 DEBUG(10,("set_domain_online_request: called for domain %s\n",
577 if (get_global_winbindd_state_offline()) {
578 DEBUG(10,("set_domain_online_request: domain %s remaining globally offline\n",
583 if (domain
->internal
) {
584 DEBUG(10, ("set_domain_online_request: Internal domains are "
589 /* We've been told it's safe to go online and
590 try and connect to a DC. But I don't believe it
591 because network manager seems to lie.
592 Wait at least 5 seconds. Heuristics suck... */
597 /* Go into "startup" mode again. */
598 domain
->startup_time
= time_mono(NULL
);
599 domain
->startup
= True
;
603 if (!domain
->check_online_event
) {
604 /* If we've come from being globally offline we
605 don't have a check online event handler set.
606 We need to add one now we're trying to go
609 DEBUG(10,("set_domain_online_request: domain %s was globally offline.\n",
613 TALLOC_FREE(domain
->check_online_event
);
615 domain
->check_online_event
= tevent_add_timer(global_event_context(),
618 check_domain_online_handler
,
621 /* The above *has* to succeed for winbindd to work. */
622 if (!domain
->check_online_event
) {
623 smb_panic("set_domain_online_request: failed to add online handler");
627 /****************************************************************
628 Add -ve connection cache entries for domain and realm.
629 ****************************************************************/
631 static void winbind_add_failed_connection_entry(
632 const struct winbindd_domain
*domain
,
636 add_failed_connection_entry(domain
->name
, server
, result
);
637 /* If this was the saf name for the last thing we talked to,
639 saf_delete(domain
->name
);
640 if (domain
->alt_name
!= NULL
) {
641 add_failed_connection_entry(domain
->alt_name
, server
, result
);
642 saf_delete(domain
->alt_name
);
644 winbindd_unset_locator_kdc_env(domain
);
647 /* Choose between anonymous or authenticated connections. We need to use
648 an authenticated connection if DCs have the RestrictAnonymous registry
649 entry set > 0, or the "Additional restrictions for anonymous
650 connections" set in the win2k Local Security Policy.
652 Caller to free() result in domain, username, password
655 static void cm_get_ipc_userpass(char **username
, char **domain
, char **password
)
657 *username
= (char *)secrets_fetch(SECRETS_AUTH_USER
, NULL
);
658 *domain
= (char *)secrets_fetch(SECRETS_AUTH_DOMAIN
, NULL
);
659 *password
= (char *)secrets_fetch(SECRETS_AUTH_PASSWORD
, NULL
);
661 if (*username
&& **username
) {
663 if (!*domain
|| !**domain
)
664 *domain
= smb_xstrdup(lp_workgroup());
666 if (!*password
|| !**password
)
667 *password
= smb_xstrdup("");
669 DEBUG(3, ("cm_get_ipc_userpass: Retrieved auth-user from secrets.tdb [%s\\%s]\n",
670 *domain
, *username
));
673 DEBUG(3, ("cm_get_ipc_userpass: No auth-user defined\n"));
674 *username
= smb_xstrdup("");
675 *domain
= smb_xstrdup("");
676 *password
= smb_xstrdup("");
680 static NTSTATUS
cm_get_ipc_credentials(TALLOC_CTX
*mem_ctx
,
681 struct cli_credentials
**_creds
)
684 TALLOC_CTX
*frame
= talloc_stackframe();
685 NTSTATUS status
= NT_STATUS_INTERNAL_ERROR
;
686 struct loadparm_context
*lp_ctx
;
687 char *username
= NULL
;
688 char *netbios_domain
= NULL
;
689 char *password
= NULL
;
690 struct cli_credentials
*creds
= NULL
;
693 cm_get_ipc_userpass(&username
, &netbios_domain
, &password
);
695 lp_ctx
= loadparm_init_s3(frame
, loadparm_s3_helpers());
696 if (lp_ctx
== NULL
) {
697 DEBUG(1, ("loadparm_init_s3 failed\n"));
698 status
= NT_STATUS_INTERNAL_ERROR
;
702 creds
= cli_credentials_init(mem_ctx
);
704 status
= NT_STATUS_NO_MEMORY
;
708 cli_credentials_set_conf(creds
, lp_ctx
);
709 cli_credentials_set_kerberos_state(creds
, CRED_DONT_USE_KERBEROS
);
711 ok
= cli_credentials_set_domain(creds
, netbios_domain
, CRED_SPECIFIED
);
713 status
= NT_STATUS_NO_MEMORY
;
717 ok
= cli_credentials_set_username(creds
, username
, CRED_SPECIFIED
);
719 status
= NT_STATUS_NO_MEMORY
;
723 ok
= cli_credentials_set_password(creds
, password
, CRED_SPECIFIED
);
725 status
= NT_STATUS_NO_MEMORY
;
731 status
= NT_STATUS_OK
;
735 SAFE_FREE(netbios_domain
);
741 static bool cm_is_ipc_credentials(struct cli_credentials
*creds
)
743 TALLOC_CTX
*frame
= talloc_stackframe();
744 char *ipc_account
= NULL
;
745 char *ipc_domain
= NULL
;
746 char *ipc_password
= NULL
;
747 const char *creds_account
= NULL
;
748 const char *creds_domain
= NULL
;
749 const char *creds_password
= NULL
;
752 cm_get_ipc_userpass(&ipc_account
, &ipc_domain
, &ipc_password
);
754 creds_account
= cli_credentials_get_username(creds
);
755 creds_domain
= cli_credentials_get_domain(creds
);
756 creds_password
= cli_credentials_get_password(creds
);
758 if (!strequal(ipc_domain
, creds_domain
)) {
762 if (!strequal(ipc_account
, creds_account
)) {
766 if (!strcsequal(ipc_password
, creds_password
)) {
772 SAFE_FREE(ipc_account
);
773 SAFE_FREE(ipc_domain
);
774 SAFE_FREE(ipc_password
);
779 static bool get_dc_name_via_netlogon(struct winbindd_domain
*domain
,
781 struct sockaddr_storage
*dc_ss
,
782 uint32_t request_flags
)
784 struct winbindd_domain
*our_domain
= NULL
;
785 struct rpc_pipe_client
*netlogon_pipe
= NULL
;
789 unsigned int orig_timeout
;
790 const char *tmp
= NULL
;
792 struct dcerpc_binding_handle
*b
;
794 /* Hmmmm. We can only open one connection to the NETLOGON pipe at the
801 if (domain
->primary
) {
805 our_domain
= find_our_domain();
807 if ((mem_ctx
= talloc_init("get_dc_name_via_netlogon")) == NULL
) {
811 result
= cm_connect_netlogon(our_domain
, &netlogon_pipe
);
812 if (!NT_STATUS_IS_OK(result
)) {
813 talloc_destroy(mem_ctx
);
817 b
= netlogon_pipe
->binding_handle
;
819 /* This call can take a long time - allow the server to time out.
820 35 seconds should do it. */
822 orig_timeout
= rpccli_set_timeout(netlogon_pipe
, 35000);
824 if (our_domain
->active_directory
) {
825 struct netr_DsRGetDCNameInfo
*domain_info
= NULL
;
828 * TODO request flags are not respected in the server
829 * (and in some cases, like REQUIRE_PDC, causes an error)
831 result
= dcerpc_netr_DsRGetDCName(b
,
837 request_flags
|DS_RETURN_DNS_NAME
,
840 if (NT_STATUS_IS_OK(result
) && W_ERROR_IS_OK(werr
)) {
842 mem_ctx
, domain_info
->dc_unc
);
844 DEBUG(0, ("talloc_strdup failed\n"));
845 talloc_destroy(mem_ctx
);
848 if (domain
->alt_name
== NULL
) {
849 domain
->alt_name
= talloc_strdup(domain
,
850 domain_info
->domain_name
);
851 if (domain
->alt_name
== NULL
) {
852 DEBUG(0, ("talloc_strdup failed\n"));
853 talloc_destroy(mem_ctx
);
857 if (domain
->forest_name
== NULL
) {
858 domain
->forest_name
= talloc_strdup(domain
,
859 domain_info
->forest_name
);
860 if (domain
->forest_name
== NULL
) {
861 DEBUG(0, ("talloc_strdup failed\n"));
862 talloc_destroy(mem_ctx
);
868 result
= dcerpc_netr_GetAnyDCName(b
, mem_ctx
,
875 /* And restore our original timeout. */
876 rpccli_set_timeout(netlogon_pipe
, orig_timeout
);
878 if (!NT_STATUS_IS_OK(result
)) {
879 DEBUG(10,("dcerpc_netr_GetAnyDCName failed: %s\n",
881 talloc_destroy(mem_ctx
);
885 if (!W_ERROR_IS_OK(werr
)) {
886 DEBUG(10,("dcerpc_netr_GetAnyDCName failed: %s\n",
888 talloc_destroy(mem_ctx
);
892 /* dcerpc_netr_GetAnyDCName gives us a name with \\ */
893 p
= strip_hostname(tmp
);
897 talloc_destroy(mem_ctx
);
899 DEBUG(10,("dcerpc_netr_GetAnyDCName returned %s\n", dcname
));
901 if (!resolve_name(dcname
, dc_ss
, 0x20, true)) {
909 * Helper function to assemble trust password and account name
911 static NTSTATUS
get_trust_credentials(struct winbindd_domain
*domain
,
914 struct cli_credentials
**_creds
)
916 const struct winbindd_domain
*creds_domain
= NULL
;
917 struct cli_credentials
*creds
;
919 bool force_machine_account
= false;
921 /* If we are a DC and this is not our own domain */
923 if (!domain
->active_directory
) {
926 * For non active directory domains
927 * we can only use NTLMSSP for SMB.
929 * But the trust account is not allowed
930 * to use SMB with NTLMSSP.
932 force_machine_account
= true;
936 if (IS_DC
&& !force_machine_account
) {
937 creds_domain
= domain
;
939 creds_domain
= find_our_domain();
940 if (creds_domain
== NULL
) {
941 return NT_STATUS_INVALID_SERVER_STATE
;
945 status
= pdb_get_trust_credentials(creds_domain
->name
,
946 creds_domain
->alt_name
,
949 if (!NT_STATUS_IS_OK(status
)) {
953 if (creds_domain
!= domain
) {
955 * We can only use schannel against a direct trust
957 cli_credentials_set_secure_channel_type(creds
,
966 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
969 status
= cm_get_ipc_credentials(mem_ctx
, &creds
);
970 if (!NT_STATUS_IS_OK(status
)) {
978 /************************************************************************
979 Given a fd with a just-connected TCP connection to a DC, open a connection
981 ************************************************************************/
983 static NTSTATUS
cm_prepare_connection(struct winbindd_domain
*domain
,
985 const char *controller
,
986 struct cli_state
**cli
,
989 bool try_ipc_auth
= false;
990 const char *machine_principal
= NULL
;
991 const char *machine_realm
= NULL
;
992 const char *machine_account
= NULL
;
993 const char *machine_domain
= NULL
;
995 struct cli_credentials
*creds
= NULL
;
997 struct named_mutex
*mutex
;
999 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
1000 NTSTATUS tmp_status
;
1001 NTSTATUS tcon_status
= NT_STATUS_NETWORK_NAME_DELETED
;
1003 enum smb_signing_setting smb_sign_client_connections
= lp_client_ipc_signing();
1006 if (domain
->secure_channel_type
== SEC_CHAN_NULL
) {
1008 * Make sure we don't even try to
1009 * connect to a foreign domain
1010 * without a direct outbound trust.
1012 return NT_STATUS_NO_TRUST_LSA_SECRET
;
1016 * As AD DC we only use netlogon and lsa
1017 * using schannel over an anonymous transport
1018 * (ncacn_ip_tcp or ncacn_np).
1020 * Currently we always establish the SMB connection,
1021 * even if we don't use it, because we later use ncacn_ip_tcp.
1023 * As we won't use the SMB connection there's no
1024 * need to try kerberos. And NT4 domains expect
1025 * an anonymous IPC$ connection anyway.
1027 smb_sign_client_connections
= SMB_SIGNING_OFF
;
1030 if (smb_sign_client_connections
== SMB_SIGNING_DEFAULT
) {
1032 * If we are connecting to our own AD domain, require
1033 * smb signing to disrupt MITM attacks
1035 if (domain
->primary
&& lp_security() == SEC_ADS
) {
1036 smb_sign_client_connections
= SMB_SIGNING_REQUIRED
;
1038 * If we are in or are an AD domain and connecting to another
1039 * AD domain in our forest
1040 * then require smb signing to disrupt MITM attacks
1042 } else if ((lp_security() == SEC_ADS
)
1043 && domain
->active_directory
1044 && (domain
->domain_trust_attribs
1045 & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST
)) {
1046 smb_sign_client_connections
= SMB_SIGNING_REQUIRED
;
1050 DEBUG(10,("cm_prepare_connection: connecting to DC %s for domain %s\n",
1051 controller
, domain
->name
));
1055 mutex
= grab_named_mutex(talloc_tos(), controller
,
1056 WINBIND_SERVER_MUTEX_WAIT_TIME
);
1057 if (mutex
== NULL
) {
1059 DEBUG(0,("cm_prepare_connection: mutex grab failed for %s\n",
1061 result
= NT_STATUS_POSSIBLE_DEADLOCK
;
1065 *cli
= cli_state_create(NULL
, sockfd
, controller
,
1066 smb_sign_client_connections
, flags
);
1069 DEBUG(1, ("Could not cli_initialize\n"));
1070 result
= NT_STATUS_NO_MEMORY
;
1074 cli_set_timeout(*cli
, 10000); /* 10 seconds */
1076 set_socket_options(sockfd
, lp_socket_options());
1078 result
= smbXcli_negprot((*cli
)->conn
, (*cli
)->timeout
,
1079 lp_client_ipc_min_protocol(),
1080 lp_client_ipc_max_protocol());
1082 if (!NT_STATUS_IS_OK(result
)) {
1083 DEBUG(1, ("cli_negprot failed: %s\n", nt_errstr(result
)));
1087 if (smbXcli_conn_protocol((*cli
)->conn
) >= PROTOCOL_NT1
&&
1088 smb1cli_conn_capabilities((*cli
)->conn
) & CAP_EXTENDED_SECURITY
) {
1089 try_ipc_auth
= true;
1090 } else if (smbXcli_conn_protocol((*cli
)->conn
) >= PROTOCOL_SMB2_02
) {
1091 try_ipc_auth
= true;
1092 } else if (smb_sign_client_connections
== SMB_SIGNING_REQUIRED
) {
1094 * If we are forcing on SMB signing, then we must
1095 * require authentication unless this is a one-way
1096 * trust, and we have no stored user/password
1098 try_ipc_auth
= true;
1103 * As AD DC we only use netlogon and lsa
1104 * using schannel over an anonymous transport
1105 * (ncacn_ip_tcp or ncacn_np).
1107 * Currently we always establish the SMB connection,
1108 * even if we don't use it, because we later use ncacn_ip_tcp.
1110 * As we won't use the SMB connection there's no
1111 * need to try kerberos. And NT4 domains expect
1112 * an anonymous IPC$ connection anyway.
1114 try_ipc_auth
= false;
1118 result
= get_trust_credentials(domain
, talloc_tos(), false, &creds
);
1119 if (!NT_STATUS_IS_OK(result
)) {
1120 DEBUG(1, ("get_trust_credentials(%s) failed: %s\n",
1121 domain
->name
, nt_errstr(result
)));
1126 * Without SPNEGO or NTLMSSP (perhaps via SMB2) we
1127 * would try and authentication with our machine
1128 * account password and fail. This is very rare in
1129 * the modern world however
1131 creds
= cli_credentials_init_anon(talloc_tos());
1132 if (creds
== NULL
) {
1133 result
= NT_STATUS_NO_MEMORY
;
1134 DEBUG(1, ("cli_credentials_init_anon(%s) failed: %s\n",
1135 domain
->name
, nt_errstr(result
)));
1140 machine_principal
= cli_credentials_get_principal(creds
,
1142 machine_realm
= cli_credentials_get_realm(creds
);
1143 machine_account
= cli_credentials_get_username(creds
);
1144 machine_domain
= cli_credentials_get_domain(creds
);
1146 DEBUG(5, ("connecting to %s (%s, %s) with account [%s\\%s] principal "
1147 "[%s] and realm [%s]\n",
1148 controller
, domain
->name
, domain
->alt_name
,
1149 machine_domain
, machine_account
,
1150 machine_principal
, machine_realm
));
1152 if (cli_credentials_is_anonymous(creds
)) {
1156 winbindd_set_locator_kdc_envs(domain
);
1158 result
= cli_session_setup_creds(*cli
, creds
);
1159 if (NT_STATUS_IS_OK(result
)) {
1160 goto session_setup_done
;
1163 DEBUG(1, ("authenticated session setup to %s using %s failed with %s\n",
1165 cli_credentials_get_unparsed_name(creds
, talloc_tos()),
1166 nt_errstr(result
)));
1169 * If we are not going to validiate the conneciton
1170 * with SMB signing, then allow us to fall back to
1173 if (NT_STATUS_EQUAL(result
, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT
)
1174 || NT_STATUS_EQUAL(result
, NT_STATUS_TRUSTED_DOMAIN_FAILURE
)
1175 || NT_STATUS_EQUAL(result
, NT_STATUS_INVALID_ACCOUNT_NAME
)
1176 || NT_STATUS_EQUAL(result
, NT_STATUS_NO_LOGON_SERVERS
)
1177 || NT_STATUS_EQUAL(result
, NT_STATUS_LOGON_FAILURE
))
1179 if (!cm_is_ipc_credentials(creds
)) {
1183 if (smb_sign_client_connections
== SMB_SIGNING_REQUIRED
) {
1194 tmp_status
= cm_get_ipc_credentials(talloc_tos(), &creds
);
1195 if (!NT_STATUS_IS_OK(tmp_status
)) {
1196 result
= tmp_status
;
1200 if (cli_credentials_is_anonymous(creds
)) {
1204 machine_account
= cli_credentials_get_username(creds
);
1205 machine_domain
= cli_credentials_get_domain(creds
);
1207 DEBUG(5, ("connecting to %s from %s using NTLMSSP with username "
1208 "[%s]\\[%s]\n", controller
, lp_netbios_name(),
1209 machine_domain
, machine_account
));
1211 result
= cli_session_setup_creds(*cli
, creds
);
1212 if (NT_STATUS_IS_OK(result
)) {
1213 goto session_setup_done
;
1216 DEBUG(1, ("authenticated session setup to %s using %s failed with %s\n",
1218 cli_credentials_get_unparsed_name(creds
, talloc_tos()),
1219 nt_errstr(result
)));
1222 * If we are not going to validiate the conneciton
1223 * with SMB signing, then allow us to fall back to
1226 if (NT_STATUS_EQUAL(result
, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT
)
1227 || NT_STATUS_EQUAL(result
, NT_STATUS_TRUSTED_DOMAIN_FAILURE
)
1228 || NT_STATUS_EQUAL(result
, NT_STATUS_INVALID_ACCOUNT_NAME
)
1229 || NT_STATUS_EQUAL(result
, NT_STATUS_NO_LOGON_SERVERS
)
1230 || NT_STATUS_EQUAL(result
, NT_STATUS_LOGON_FAILURE
))
1240 if (smb_sign_client_connections
== SMB_SIGNING_REQUIRED
) {
1244 /* Fall back to anonymous connection, this might fail later */
1245 DEBUG(5,("cm_prepare_connection: falling back to anonymous "
1246 "connection for DC %s\n",
1249 result
= cli_session_setup_anon(*cli
);
1250 if (NT_STATUS_IS_OK(result
)) {
1251 DEBUG(5, ("Connected anonymously\n"));
1252 goto session_setup_done
;
1255 DEBUG(1, ("anonymous session setup to %s failed with %s\n",
1256 controller
, nt_errstr(result
)));
1258 /* We can't session setup */
1265 * This should be a short term hack until
1266 * dynamic re-authentication is implemented.
1268 * See Bug 9175 - winbindd doesn't recover from
1269 * NT_STATUS_NETWORK_SESSION_EXPIRED
1271 if (smbXcli_conn_protocol((*cli
)->conn
) >= PROTOCOL_SMB2_02
) {
1272 smbXcli_session_set_disconnect_expired((*cli
)->smb2
.session
);
1275 result
= cli_tree_connect(*cli
, "IPC$", "IPC", NULL
);
1276 if (!NT_STATUS_IS_OK(result
)) {
1277 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(result
)));
1280 tcon_status
= result
;
1282 /* cache the server name for later connections */
1284 saf_store(domain
->name
, controller
);
1285 if (domain
->alt_name
) {
1286 saf_store(domain
->alt_name
, controller
);
1289 winbindd_set_locator_kdc_envs(domain
);
1294 result
= NT_STATUS_OK
;
1300 if (NT_STATUS_IS_OK(result
)) {
1301 result
= tcon_status
;
1304 if (!NT_STATUS_IS_OK(result
)) {
1305 DEBUG(1, ("Failed to prepare SMB connection to %s: %s\n",
1306 controller
, nt_errstr(result
)));
1307 winbind_add_failed_connection_entry(domain
, controller
, result
);
1308 if ((*cli
) != NULL
) {
1317 /*******************************************************************
1318 Add a dcname and sockaddr_storage pair to the end of a dc_name_ip
1321 Keeps the list unique by not adding duplicate entries.
1323 @param[in] mem_ctx talloc memory context to allocate from
1324 @param[in] domain_name domain of the DC
1325 @param[in] dcname name of the DC to add to the list
1326 @param[in] pss Internet address and port pair to add to the list
1327 @param[in,out] dcs array of dc_name_ip structures to add to
1328 @param[in,out] num_dcs number of dcs returned in the dcs array
1329 @return true if the list was added to, false otherwise
1330 *******************************************************************/
1332 static bool add_one_dc_unique(TALLOC_CTX
*mem_ctx
, const char *domain_name
,
1333 const char *dcname
, struct sockaddr_storage
*pss
,
1334 struct dc_name_ip
**dcs
, int *num
)
1338 if (!NT_STATUS_IS_OK(check_negative_conn_cache(domain_name
, dcname
))) {
1339 DEBUG(10, ("DC %s was in the negative conn cache\n", dcname
));
1343 /* Make sure there's no duplicates in the list */
1344 for (i
=0; i
<*num
; i
++)
1346 (struct sockaddr
*)(void *)&(*dcs
)[i
].ss
,
1347 (struct sockaddr
*)(void *)pss
))
1350 *dcs
= talloc_realloc(mem_ctx
, *dcs
, struct dc_name_ip
, (*num
)+1);
1355 fstrcpy((*dcs
)[*num
].name
, dcname
);
1356 (*dcs
)[*num
].ss
= *pss
;
1361 static bool add_sockaddr_to_array(TALLOC_CTX
*mem_ctx
,
1362 struct sockaddr_storage
*pss
, uint16_t port
,
1363 struct sockaddr_storage
**addrs
, int *num
)
1365 *addrs
= talloc_realloc(mem_ctx
, *addrs
, struct sockaddr_storage
, (*num
)+1);
1367 if (*addrs
== NULL
) {
1372 (*addrs
)[*num
] = *pss
;
1373 set_sockaddr_port((struct sockaddr
*)&(*addrs
)[*num
], port
);
1379 /*******************************************************************
1380 convert an ip to a name
1381 For an AD Domain, it checks the requirements of the request flags.
1382 *******************************************************************/
1384 static bool dcip_check_name(TALLOC_CTX
*mem_ctx
,
1385 const struct winbindd_domain
*domain
,
1386 struct sockaddr_storage
*pss
,
1387 char **name
, uint32_t request_flags
)
1389 struct ip_service ip_list
;
1390 uint32_t nt_version
= NETLOGON_NT_VERSION_1
;
1392 const char *dc_name
;
1395 bool is_ad_domain
= false;
1401 /* For active directory servers, try to get the ldap server name.
1402 None of these failures should be considered critical for now */
1404 if ((lp_security() == SEC_ADS
) && (domain
->alt_name
!= NULL
)) {
1405 is_ad_domain
= true;
1406 } else if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
) {
1407 is_ad_domain
= domain
->active_directory
;
1412 ADS_STATUS ads_status
;
1413 char addr
[INET6_ADDRSTRLEN
];
1415 print_sockaddr(addr
, sizeof(addr
), pss
);
1417 ads
= ads_init(domain
->alt_name
, domain
->name
, addr
);
1418 ads
->auth
.flags
|= ADS_AUTH_NO_BIND
;
1419 ads
->config
.flags
|= request_flags
;
1420 ads
->server
.no_fallback
= true;
1422 ads_status
= ads_connect(ads
);
1423 if (ADS_ERR_OK(ads_status
)) {
1424 /* We got a cldap packet. */
1425 *name
= talloc_strdup(mem_ctx
,
1426 ads
->config
.ldap_server_name
);
1427 if (*name
== NULL
) {
1430 namecache_store(*name
, 0x20, 1, &ip_list
);
1432 DEBUG(10,("dcip_check_name: flags = 0x%x\n", (unsigned int)ads
->config
.flags
));
1434 if (domain
->primary
&& (ads
->config
.flags
& NBT_SERVER_KDC
)) {
1435 if (ads_closest_dc(ads
)) {
1436 char *sitename
= sitename_fetch(mem_ctx
, ads
->config
.realm
);
1438 /* We're going to use this KDC for this realm/domain.
1439 If we are using sites, then force the krb5 libs
1442 create_local_private_krb5_conf_for_domain(domain
->alt_name
,
1447 TALLOC_FREE(sitename
);
1449 /* use an off site KDC */
1450 create_local_private_krb5_conf_for_domain(domain
->alt_name
,
1455 winbindd_set_locator_kdc_envs(domain
);
1457 /* Ensure we contact this DC also. */
1458 saf_store(domain
->name
, *name
);
1459 saf_store(domain
->alt_name
, *name
);
1462 ads_destroy( &ads
);
1466 ads_destroy( &ads
);
1472 size_t len
= strlen(lp_netbios_name());
1473 char my_acct_name
[len
+2];
1475 snprintf(my_acct_name
,
1476 sizeof(my_acct_name
),
1480 status
= nbt_getdc(global_messaging_context(), 10, pss
,
1481 domain
->name
, &domain
->sid
,
1482 my_acct_name
, ACB_WSTRUST
,
1483 nt_version
, mem_ctx
, &nt_version
,
1486 if (NT_STATUS_IS_OK(status
)) {
1487 *name
= talloc_strdup(mem_ctx
, dc_name
);
1488 if (*name
== NULL
) {
1491 namecache_store(*name
, 0x20, 1, &ip_list
);
1495 /* try node status request */
1497 if (name_status_find(domain
->name
, 0x1c, 0x20, pss
, nbtname
) ) {
1498 namecache_store(nbtname
, 0x20, 1, &ip_list
);
1501 *name
= talloc_strdup(mem_ctx
, nbtname
);
1502 if (*name
== NULL
) {
1512 /*******************************************************************
1513 Retrieve a list of IP addresses for domain controllers.
1515 The array is sorted in the preferred connection order.
1517 @param[in] mem_ctx talloc memory context to allocate from
1518 @param[in] domain domain to retrieve DCs for
1519 @param[out] dcs array of dcs that will be returned
1520 @param[out] num_dcs number of dcs returned in the dcs array
1522 *******************************************************************/
1524 static bool get_dcs(TALLOC_CTX
*mem_ctx
, struct winbindd_domain
*domain
,
1525 struct dc_name_ip
**dcs
, int *num_dcs
,
1526 uint32_t request_flags
)
1529 struct sockaddr_storage ss
;
1530 struct ip_service
*ip_list
= NULL
;
1531 int iplist_size
= 0;
1534 enum security_types sec
= (enum security_types
)lp_security();
1536 is_our_domain
= strequal(domain
->name
, lp_workgroup());
1538 /* If not our domain, get the preferred DC, by asking our primary DC */
1540 && get_dc_name_via_netlogon(domain
, dcname
, &ss
, request_flags
)
1541 && add_one_dc_unique(mem_ctx
, domain
->name
, dcname
, &ss
, dcs
,
1544 char addr
[INET6_ADDRSTRLEN
];
1545 print_sockaddr(addr
, sizeof(addr
), &ss
);
1546 DEBUG(10, ("Retrieved DC %s at %s via netlogon\n",
1551 if ((sec
== SEC_ADS
) && (domain
->alt_name
!= NULL
)) {
1552 char *sitename
= NULL
;
1554 /* We need to make sure we know the local site before
1555 doing any DNS queries, as this will restrict the
1556 get_sorted_dc_list() call below to only fetching
1557 DNS records for the correct site. */
1559 /* Find any DC to get the site record.
1560 We deliberately don't care about the
1563 get_dc_name(domain
->name
, domain
->alt_name
, dcname
, &ss
);
1565 sitename
= sitename_fetch(mem_ctx
, domain
->alt_name
);
1568 /* Do the site-specific AD dns lookup first. */
1569 get_sorted_dc_list(domain
->alt_name
, sitename
, &ip_list
,
1570 &iplist_size
, True
);
1572 /* Add ips to the DC array. We don't look up the name
1573 of the DC in this function, but we fill in the char*
1574 of the ip now to make the failed connection cache
1576 for ( i
=0; i
<iplist_size
; i
++ ) {
1577 char addr
[INET6_ADDRSTRLEN
];
1578 print_sockaddr(addr
, sizeof(addr
),
1580 add_one_dc_unique(mem_ctx
,
1589 TALLOC_FREE(sitename
);
1593 /* Now we add DCs from the main AD DNS lookup. */
1594 get_sorted_dc_list(domain
->alt_name
, NULL
, &ip_list
,
1595 &iplist_size
, True
);
1597 for ( i
=0; i
<iplist_size
; i
++ ) {
1598 char addr
[INET6_ADDRSTRLEN
];
1599 print_sockaddr(addr
, sizeof(addr
),
1601 add_one_dc_unique(mem_ctx
,
1613 /* Try standard netbios queries if no ADS and fall back to DNS queries
1614 * if alt_name is available */
1615 if (*num_dcs
== 0) {
1616 get_sorted_dc_list(domain
->name
, NULL
, &ip_list
, &iplist_size
,
1618 if (iplist_size
== 0) {
1619 if (domain
->alt_name
!= NULL
) {
1620 get_sorted_dc_list(domain
->alt_name
, NULL
, &ip_list
,
1621 &iplist_size
, true);
1625 for ( i
=0; i
<iplist_size
; i
++ ) {
1626 char addr
[INET6_ADDRSTRLEN
];
1627 print_sockaddr(addr
, sizeof(addr
),
1629 add_one_dc_unique(mem_ctx
,
1644 /*******************************************************************
1645 Find and make a connection to a DC in the given domain.
1647 @param[in] mem_ctx talloc memory context to allocate from
1648 @param[in] domain domain to find a dc in
1649 @param[out] dcname NetBIOS or FQDN of DC that's connected to
1650 @param[out] pss DC Internet address and port
1651 @param[out] fd fd of the open socket connected to the newly found dc
1652 @return true when a DC connection is made, false otherwise
1653 *******************************************************************/
1655 static bool find_new_dc(TALLOC_CTX
*mem_ctx
,
1656 struct winbindd_domain
*domain
,
1657 char **dcname
, struct sockaddr_storage
*pss
, int *fd
,
1658 uint32_t request_flags
)
1660 struct dc_name_ip
*dcs
= NULL
;
1663 const char **dcnames
= NULL
;
1664 size_t num_dcnames
= 0;
1666 struct sockaddr_storage
*addrs
= NULL
;
1677 if (!get_dcs(mem_ctx
, domain
, &dcs
, &num_dcs
, request_flags
) || (num_dcs
== 0))
1680 for (i
=0; i
<num_dcs
; i
++) {
1682 if (!add_string_to_array(mem_ctx
, dcs
[i
].name
,
1683 &dcnames
, &num_dcnames
)) {
1686 if (!add_sockaddr_to_array(mem_ctx
, &dcs
[i
].ss
, TCP_SMB_PORT
,
1687 &addrs
, &num_addrs
)) {
1692 if ((num_dcnames
== 0) || (num_dcnames
!= num_addrs
))
1695 if ((addrs
== NULL
) || (dcnames
== NULL
))
1698 status
= smbsock_any_connect(addrs
, dcnames
, NULL
, NULL
, NULL
,
1699 num_addrs
, 0, 10, fd
, &fd_index
, NULL
);
1700 if (!NT_STATUS_IS_OK(status
)) {
1701 for (i
=0; i
<num_dcs
; i
++) {
1702 char ab
[INET6_ADDRSTRLEN
];
1703 print_sockaddr(ab
, sizeof(ab
), &dcs
[i
].ss
);
1704 DEBUG(10, ("find_new_dc: smbsock_any_connect failed for "
1705 "domain %s address %s. Error was %s\n",
1706 domain
->name
, ab
, nt_errstr(status
) ));
1707 winbind_add_failed_connection_entry(domain
,
1708 dcs
[i
].name
, NT_STATUS_UNSUCCESSFUL
);
1713 *pss
= addrs
[fd_index
];
1715 if (*dcnames
[fd_index
] != '\0' && !is_ipaddress(dcnames
[fd_index
])) {
1716 /* Ok, we've got a name for the DC */
1717 *dcname
= talloc_strdup(mem_ctx
, dcnames
[fd_index
]);
1718 if (*dcname
== NULL
) {
1724 /* Try to figure out the name */
1725 if (dcip_check_name(mem_ctx
, domain
, pss
, dcname
, request_flags
)) {
1729 /* We can not continue without the DC's name */
1730 winbind_add_failed_connection_entry(domain
, dcs
[fd_index
].name
,
1731 NT_STATUS_UNSUCCESSFUL
);
1733 /* Throw away all arrays as we're doing this again. */
1737 TALLOC_FREE(dcnames
);
1751 static char *current_dc_key(TALLOC_CTX
*mem_ctx
, const char *domain_name
)
1753 return talloc_asprintf_strupper_m(mem_ctx
, "CURRENT_DCNAME/%s",
1757 static void store_current_dc_in_gencache(const char *domain_name
,
1758 const char *dc_name
,
1759 struct cli_state
*cli
)
1761 char addr
[INET6_ADDRSTRLEN
];
1765 if (!cli_state_is_connected(cli
)) {
1769 print_sockaddr(addr
, sizeof(addr
),
1770 smbXcli_conn_remote_sockaddr(cli
->conn
));
1772 key
= current_dc_key(talloc_tos(), domain_name
);
1777 value
= talloc_asprintf(talloc_tos(), "%s %s", addr
, dc_name
);
1778 if (value
== NULL
) {
1782 gencache_set(key
, value
, 0x7fffffff);
1788 bool fetch_current_dc_from_gencache(TALLOC_CTX
*mem_ctx
,
1789 const char *domain_name
,
1790 char **p_dc_name
, char **p_dc_ip
)
1795 char *dc_name
= NULL
;
1798 key
= current_dc_key(talloc_tos(), domain_name
);
1802 if (!gencache_get(key
, mem_ctx
, &value
, NULL
)) {
1805 p
= strchr(value
, ' ');
1809 dc_ip
= talloc_strndup(mem_ctx
, value
, p
- value
);
1810 if (dc_ip
== NULL
) {
1813 dc_name
= talloc_strdup(mem_ctx
, p
+1);
1814 if (dc_name
== NULL
) {
1818 if (p_dc_ip
!= NULL
) {
1822 if (p_dc_name
!= NULL
) {
1823 *p_dc_name
= dc_name
;
1828 TALLOC_FREE(dc_name
);
1835 NTSTATUS
wb_open_internal_pipe(TALLOC_CTX
*mem_ctx
,
1836 const struct ndr_interface_table
*table
,
1837 struct rpc_pipe_client
**ret_pipe
)
1839 struct rpc_pipe_client
*cli
= NULL
;
1840 const struct auth_session_info
*session_info
;
1841 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
1844 session_info
= get_session_info_system();
1845 SMB_ASSERT(session_info
!= NULL
);
1847 /* create a connection to the specified pipe */
1848 if (lp_parm_bool(-1, "winbindd", "use external pipes", false)) {
1849 status
= rpc_pipe_open_interface(mem_ctx
,
1854 global_messaging_context(),
1857 status
= rpc_pipe_open_internal(mem_ctx
,
1862 global_messaging_context(),
1865 if (!NT_STATUS_IS_OK(status
)) {
1866 DEBUG(0, ("open_internal_pipe: Could not connect to %s pipe: %s\n",
1867 table
->name
, nt_errstr(status
)));
1875 return NT_STATUS_OK
;
1878 static NTSTATUS
cm_open_connection(struct winbindd_domain
*domain
,
1879 struct winbindd_cm_conn
*new_conn
,
1882 TALLOC_CTX
*mem_ctx
;
1884 char *saf_servername
;
1886 uint32_t request_flags
= need_rw_dc
? DS_WRITABLE_REQUIRED
: 0;
1888 if ((mem_ctx
= talloc_init("cm_open_connection")) == NULL
) {
1889 set_domain_offline(domain
);
1890 return NT_STATUS_NO_MEMORY
;
1893 saf_servername
= saf_fetch(mem_ctx
, domain
->name
);
1895 /* we have to check the server affinity cache here since
1896 later we select a DC based on response time and not preference */
1898 /* Check the negative connection cache
1899 before talking to it. It going down may have
1900 triggered the reconnection. */
1902 if (saf_servername
&& NT_STATUS_IS_OK(check_negative_conn_cache(domain
->name
, saf_servername
))) {
1903 struct sockaddr_storage ss
;
1904 char *dcname
= NULL
;
1905 bool resolved
= true;
1907 DEBUG(10, ("cm_open_connection: saf_servername is '%s' for domain %s\n",
1908 saf_servername
, domain
->name
));
1910 /* convert an ip address to a name */
1911 if (is_ipaddress(saf_servername
)) {
1912 if (!interpret_string_addr(&ss
, saf_servername
,
1914 TALLOC_FREE(mem_ctx
);
1915 return NT_STATUS_UNSUCCESSFUL
;
1918 if (!resolve_name(saf_servername
, &ss
, 0x20, true)) {
1923 if (resolved
&& dcip_check_name(mem_ctx
, domain
, &ss
, &dcname
, request_flags
)) {
1924 domain
->dcname
= talloc_strdup(domain
,
1926 if (domain
->dcname
== NULL
) {
1927 TALLOC_FREE(mem_ctx
);
1928 return NT_STATUS_NO_MEMORY
;
1931 domain
->dcaddr
= ss
;
1933 winbind_add_failed_connection_entry(domain
, saf_servername
,
1934 NT_STATUS_UNSUCCESSFUL
);
1938 for (retries
= 0; retries
< 3; retries
++) {
1941 char *dcname
= NULL
;
1943 result
= NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND
;
1945 DEBUG(10, ("cm_open_connection: dcname is '%s' for domain %s\n",
1946 domain
->dcname
? domain
->dcname
: "", domain
->name
));
1948 if (domain
->dcname
!= NULL
&&
1949 NT_STATUS_IS_OK(check_negative_conn_cache(domain
->name
,
1954 status
= smbsock_connect(&domain
->dcaddr
, 0,
1957 if (!NT_STATUS_IS_OK(status
)) {
1963 !find_new_dc(mem_ctx
, domain
, &dcname
, &domain
->dcaddr
, &fd
, request_flags
))
1965 /* This is the one place where we will
1966 set the global winbindd offline state
1967 to true, if a "WINBINDD_OFFLINE" entry
1968 is found in the winbindd cache. */
1969 set_global_winbindd_state_offline();
1972 if (dcname
!= NULL
) {
1973 talloc_free(domain
->dcname
);
1975 domain
->dcname
= talloc_move(domain
, &dcname
);
1976 if (domain
->dcname
== NULL
) {
1977 result
= NT_STATUS_NO_MEMORY
;
1982 new_conn
->cli
= NULL
;
1984 result
= cm_prepare_connection(domain
, fd
, domain
->dcname
,
1985 &new_conn
->cli
, &retry
);
1986 if (!NT_STATUS_IS_OK(result
)) {
1987 /* Don't leak the smb connection socket */
1998 if (NT_STATUS_IS_OK(result
)) {
1999 bool seal_pipes
= true;
2001 winbindd_set_locator_kdc_envs(domain
);
2003 if (domain
->online
== False
) {
2004 /* We're changing state from offline to online. */
2005 set_global_winbindd_state_online();
2007 set_domain_online(domain
);
2010 * Much as I hate global state, this seems to be the point
2011 * where we can be certain that we have a proper connection to
2012 * a DC. wbinfo --dc-info needs that information, store it in
2013 * gencache with a looong timeout. This will need revisiting
2014 * once we start to connect to multiple DCs, wbcDcInfo is
2015 * already prepared for that.
2017 store_current_dc_in_gencache(domain
->name
, domain
->dcname
,
2020 seal_pipes
= lp_winbind_sealed_pipes();
2021 seal_pipes
= lp_parm_bool(-1, "winbind sealed pipes",
2026 new_conn
->auth_level
= DCERPC_AUTH_LEVEL_PRIVACY
;
2028 new_conn
->auth_level
= DCERPC_AUTH_LEVEL_INTEGRITY
;
2031 /* Ensure we setup the retry handler. */
2032 set_domain_offline(domain
);
2035 talloc_destroy(mem_ctx
);
2039 /* Close down all open pipes on a connection. */
2041 void invalidate_cm_connection(struct winbindd_domain
*domain
)
2044 struct winbindd_cm_conn
*conn
= &domain
->conn
;
2046 /* We're closing down a possibly dead
2047 connection. Don't have impossibly long (10s) timeouts. */
2050 cli_set_timeout(conn
->cli
, 1000); /* 1 second. */
2053 if (conn
->samr_pipe
!= NULL
) {
2054 if (is_valid_policy_hnd(&conn
->sam_connect_handle
)) {
2055 dcerpc_samr_Close(conn
->samr_pipe
->binding_handle
,
2057 &conn
->sam_connect_handle
,
2060 TALLOC_FREE(conn
->samr_pipe
);
2061 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
2063 cli_set_timeout(conn
->cli
, 500);
2067 if (conn
->lsa_pipe
!= NULL
) {
2068 if (is_valid_policy_hnd(&conn
->lsa_policy
)) {
2069 dcerpc_lsa_Close(conn
->lsa_pipe
->binding_handle
,
2074 TALLOC_FREE(conn
->lsa_pipe
);
2075 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
2077 cli_set_timeout(conn
->cli
, 500);
2081 if (conn
->lsa_pipe_tcp
!= NULL
) {
2082 if (is_valid_policy_hnd(&conn
->lsa_policy
)) {
2083 dcerpc_lsa_Close(conn
->lsa_pipe_tcp
->binding_handle
,
2088 TALLOC_FREE(conn
->lsa_pipe_tcp
);
2089 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
2091 cli_set_timeout(conn
->cli
, 500);
2095 if (conn
->netlogon_pipe
!= NULL
) {
2096 TALLOC_FREE(conn
->netlogon_pipe
);
2097 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
2099 cli_set_timeout(conn
->cli
, 500);
2103 conn
->auth_level
= DCERPC_AUTH_LEVEL_PRIVACY
;
2104 TALLOC_FREE(conn
->netlogon_creds_ctx
);
2107 cli_shutdown(conn
->cli
);
2113 void close_conns_after_fork(void)
2115 struct winbindd_domain
*domain
;
2116 struct winbindd_cli_state
*cli_state
;
2118 for (domain
= domain_list(); domain
; domain
= domain
->next
) {
2120 * first close the low level SMB TCP connection
2121 * so that we don't generate any SMBclose
2122 * requests in invalidate_cm_connection()
2124 if (cli_state_is_connected(domain
->conn
.cli
)) {
2125 smbXcli_conn_disconnect(domain
->conn
.cli
->conn
, NT_STATUS_OK
);
2128 invalidate_cm_connection(domain
);
2131 for (cli_state
= winbindd_client_list();
2133 cli_state
= cli_state
->next
) {
2134 if (cli_state
->sock
>= 0) {
2135 close(cli_state
->sock
);
2136 cli_state
->sock
= -1;
2141 static bool connection_ok(struct winbindd_domain
*domain
)
2145 ok
= cli_state_is_connected(domain
->conn
.cli
);
2147 DEBUG(3, ("connection_ok: Connection to %s for domain %s is not connected\n",
2148 domain
->dcname
, domain
->name
));
2152 if (domain
->online
== False
) {
2153 DEBUG(3, ("connection_ok: Domain %s is offline\n", domain
->name
));
2160 /* Initialize a new connection up to the RPC BIND.
2161 Bypass online status check so always does network calls. */
2163 static NTSTATUS
init_dc_connection_network(struct winbindd_domain
*domain
, bool need_rw_dc
)
2166 bool skip_connection
= domain
->internal
;
2167 if (need_rw_dc
&& domain
->rodc
) {
2168 skip_connection
= false;
2171 /* Internal connections never use the network. */
2172 if (dom_sid_equal(&domain
->sid
, &global_sid_Builtin
)) {
2173 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
2176 /* Still ask the internal LSA and SAMR server about the local domain */
2177 if (skip_connection
|| connection_ok(domain
)) {
2178 if (!domain
->initialized
) {
2179 set_dc_type_and_flags(domain
);
2181 return NT_STATUS_OK
;
2184 invalidate_cm_connection(domain
);
2186 if (!domain
->primary
&& !domain
->initialized
) {
2188 * Before we connect to a trust, work out if it is an
2189 * AD domain by asking our own domain.
2191 set_dc_type_and_flags_trustinfo(domain
);
2194 result
= cm_open_connection(domain
, &domain
->conn
, need_rw_dc
);
2196 if (NT_STATUS_IS_OK(result
) && !domain
->initialized
) {
2197 set_dc_type_and_flags(domain
);
2203 NTSTATUS
init_dc_connection(struct winbindd_domain
*domain
, bool need_rw_dc
)
2205 if (dom_sid_equal(&domain
->sid
, &global_sid_Builtin
)) {
2206 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
2209 if (domain
->initialized
&& !domain
->online
) {
2210 /* We check for online status elsewhere. */
2211 return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND
;
2214 return init_dc_connection_network(domain
, need_rw_dc
);
2217 static NTSTATUS
init_dc_connection_rpc(struct winbindd_domain
*domain
, bool need_rw_dc
)
2221 status
= init_dc_connection(domain
, need_rw_dc
);
2222 if (!NT_STATUS_IS_OK(status
)) {
2226 if (!domain
->internal
&& domain
->conn
.cli
== NULL
) {
2227 /* happens for trusted domains without inbound trust */
2228 return NT_STATUS_TRUSTED_DOMAIN_FAILURE
;
2231 return NT_STATUS_OK
;
2234 /******************************************************************************
2235 Set the trust flags (direction and forest location) for a domain
2236 ******************************************************************************/
2238 static bool set_dc_type_and_flags_trustinfo( struct winbindd_domain
*domain
)
2240 struct winbindd_domain
*our_domain
;
2241 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
2243 struct netr_DomainTrustList trusts
;
2245 uint32_t flags
= (NETR_TRUST_FLAG_IN_FOREST
|
2246 NETR_TRUST_FLAG_OUTBOUND
|
2247 NETR_TRUST_FLAG_INBOUND
);
2248 struct rpc_pipe_client
*cli
;
2249 TALLOC_CTX
*mem_ctx
= NULL
;
2250 struct dcerpc_binding_handle
*b
;
2254 * On a DC we loaded all trusts
2255 * from configuration and never learn
2261 DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s\n", domain
->name
));
2263 /* Our primary domain doesn't need to worry about trust flags.
2264 Force it to go through the network setup */
2265 if ( domain
->primary
) {
2269 mem_ctx
= talloc_stackframe();
2270 our_domain
= find_our_domain();
2271 if (our_domain
->internal
) {
2272 result
= init_dc_connection(our_domain
, false);
2273 if (!NT_STATUS_IS_OK(result
)) {
2274 DEBUG(3,("set_dc_type_and_flags_trustinfo: "
2275 "Not able to make a connection to our domain: %s\n",
2276 nt_errstr(result
)));
2277 TALLOC_FREE(mem_ctx
);
2282 /* This won't work unless our domain is AD */
2283 if ( !our_domain
->active_directory
) {
2284 TALLOC_FREE(mem_ctx
);
2288 if (our_domain
->internal
) {
2289 result
= wb_open_internal_pipe(mem_ctx
, &ndr_table_netlogon
, &cli
);
2290 } else if (!connection_ok(our_domain
)) {
2291 DEBUG(3,("set_dc_type_and_flags_trustinfo: "
2292 "No connection to our domain!\n"));
2293 TALLOC_FREE(mem_ctx
);
2296 result
= cm_connect_netlogon(our_domain
, &cli
);
2299 if (!NT_STATUS_IS_OK(result
)) {
2300 DEBUG(5, ("set_dc_type_and_flags_trustinfo: Could not open "
2301 "a connection to %s for PIPE_NETLOGON (%s)\n",
2302 domain
->name
, nt_errstr(result
)));
2303 TALLOC_FREE(mem_ctx
);
2306 b
= cli
->binding_handle
;
2308 /* Use DsEnumerateDomainTrusts to get us the trust direction and type. */
2309 result
= dcerpc_netr_DsrEnumerateDomainTrusts(b
, mem_ctx
,
2314 if (!NT_STATUS_IS_OK(result
)) {
2315 DEBUG(0,("set_dc_type_and_flags_trustinfo: "
2316 "failed to query trusted domain list: %s\n",
2317 nt_errstr(result
)));
2318 TALLOC_FREE(mem_ctx
);
2321 if (!W_ERROR_IS_OK(werr
)) {
2322 DEBUG(0,("set_dc_type_and_flags_trustinfo: "
2323 "failed to query trusted domain list: %s\n",
2325 TALLOC_FREE(mem_ctx
);
2329 /* Now find the domain name and get the flags */
2331 for ( i
=0; i
<trusts
.count
; i
++ ) {
2332 if ( strequal( domain
->name
, trusts
.array
[i
].netbios_name
) ) {
2333 domain
->domain_flags
= trusts
.array
[i
].trust_flags
;
2334 domain
->domain_type
= trusts
.array
[i
].trust_type
;
2335 domain
->domain_trust_attribs
= trusts
.array
[i
].trust_attributes
;
2337 if ( domain
->domain_type
== LSA_TRUST_TYPE_UPLEVEL
)
2338 domain
->active_directory
= True
;
2340 /* This flag is only set if the domain is *our*
2341 primary domain and the primary domain is in
2344 domain
->native_mode
= (domain
->domain_flags
& NETR_TRUST_FLAG_NATIVE
);
2346 DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s is %sin "
2347 "native mode.\n", domain
->name
,
2348 domain
->native_mode
? "" : "NOT "));
2350 DEBUG(5,("set_dc_type_and_flags_trustinfo: domain %s is %s"
2351 "running active directory.\n", domain
->name
,
2352 domain
->active_directory
? "" : "NOT "));
2354 domain
->can_do_ncacn_ip_tcp
= domain
->active_directory
;
2356 domain
->initialized
= True
;
2362 TALLOC_FREE(mem_ctx
);
2364 return domain
->initialized
;
2367 /******************************************************************************
2368 We can 'sense' certain things about the DC by it's replies to certain
2371 This tells us if this particular remote server is Active Directory, and if it
2373 ******************************************************************************/
2375 static void set_dc_type_and_flags_connect( struct winbindd_domain
*domain
)
2377 NTSTATUS status
, result
;
2379 TALLOC_CTX
*mem_ctx
= NULL
;
2380 struct rpc_pipe_client
*cli
= NULL
;
2381 struct policy_handle pol
;
2382 union dssetup_DsRoleInfo info
;
2383 union lsa_PolicyInformation
*lsa_info
= NULL
;
2385 if (!domain
->internal
&& !connection_ok(domain
)) {
2389 mem_ctx
= talloc_init("set_dc_type_and_flags on domain %s\n",
2392 DEBUG(1, ("set_dc_type_and_flags_connect: talloc_init() failed\n"));
2396 DEBUG(5, ("set_dc_type_and_flags_connect: domain %s\n", domain
->name
));
2398 if (domain
->internal
) {
2399 status
= wb_open_internal_pipe(mem_ctx
,
2403 status
= cli_rpc_pipe_open_noauth(domain
->conn
.cli
,
2408 if (!NT_STATUS_IS_OK(status
)) {
2409 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
2410 "PI_DSSETUP on domain %s: (%s)\n",
2411 domain
->name
, nt_errstr(status
)));
2413 /* if this is just a non-AD domain we need to continue
2414 * identifying so that we can in the end return with
2415 * domain->initialized = True - gd */
2420 status
= dcerpc_dssetup_DsRoleGetPrimaryDomainInformation(cli
->binding_handle
, mem_ctx
,
2421 DS_ROLE_BASIC_INFORMATION
,
2426 if (NT_STATUS_IS_OK(status
)) {
2427 result
= werror_to_ntstatus(werr
);
2429 if (!NT_STATUS_IS_OK(status
)) {
2430 DEBUG(5, ("set_dc_type_and_flags_connect: rpccli_ds_getprimarydominfo "
2431 "on domain %s failed: (%s)\n",
2432 domain
->name
, nt_errstr(status
)));
2434 /* older samba3 DCs will return DCERPC_FAULT_OP_RNG_ERROR for
2435 * every opcode on the DSSETUP pipe, continue with
2436 * no_dssetup mode here as well to get domain->initialized
2439 if (NT_STATUS_EQUAL(status
, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE
)) {
2443 TALLOC_FREE(mem_ctx
);
2447 if ((info
.basic
.flags
& DS_ROLE_PRIMARY_DS_RUNNING
) &&
2448 !(info
.basic
.flags
& DS_ROLE_PRIMARY_DS_MIXED_MODE
)) {
2449 domain
->native_mode
= True
;
2451 domain
->native_mode
= False
;
2455 if (domain
->internal
) {
2456 status
= wb_open_internal_pipe(mem_ctx
,
2460 status
= cli_rpc_pipe_open_noauth(domain
->conn
.cli
,
2461 &ndr_table_lsarpc
, &cli
);
2463 if (!NT_STATUS_IS_OK(status
)) {
2464 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
2465 "PI_LSARPC on domain %s: (%s)\n",
2466 domain
->name
, nt_errstr(status
)));
2468 TALLOC_FREE(mem_ctx
);
2472 status
= rpccli_lsa_open_policy2(cli
, mem_ctx
, True
,
2473 SEC_FLAG_MAXIMUM_ALLOWED
, &pol
);
2475 if (NT_STATUS_IS_OK(status
)) {
2476 /* This particular query is exactly what Win2k clients use
2477 to determine that the DC is active directory */
2478 status
= dcerpc_lsa_QueryInfoPolicy2(cli
->binding_handle
, mem_ctx
,
2480 LSA_POLICY_INFO_DNS
,
2485 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(result
)) {
2486 domain
->active_directory
= True
;
2488 if (lsa_info
->dns
.name
.string
) {
2489 if (!strequal(domain
->name
, lsa_info
->dns
.name
.string
))
2491 DEBUG(1, ("set_dc_type_and_flags_connect: DC "
2492 "for domain %s claimed it was a DC "
2493 "for domain %s, refusing to "
2496 lsa_info
->dns
.name
.string
));
2498 TALLOC_FREE(mem_ctx
);
2501 talloc_free(domain
->name
);
2502 domain
->name
= talloc_strdup(domain
,
2503 lsa_info
->dns
.name
.string
);
2504 if (domain
->name
== NULL
) {
2509 if (lsa_info
->dns
.dns_domain
.string
) {
2510 if (domain
->alt_name
!= NULL
&&
2511 !strequal(domain
->alt_name
,
2512 lsa_info
->dns
.dns_domain
.string
))
2514 DEBUG(1, ("set_dc_type_and_flags_connect: DC "
2515 "for domain %s (%s) claimed it was "
2516 "a DC for domain %s, refusing to "
2518 domain
->alt_name
, domain
->name
,
2519 lsa_info
->dns
.dns_domain
.string
));
2521 TALLOC_FREE(mem_ctx
);
2524 talloc_free(domain
->alt_name
);
2526 talloc_strdup(domain
,
2527 lsa_info
->dns
.dns_domain
.string
);
2528 if (domain
->alt_name
== NULL
) {
2533 /* See if we can set some domain trust flags about
2536 if (lsa_info
->dns
.dns_forest
.string
) {
2537 talloc_free(domain
->forest_name
);
2538 domain
->forest_name
=
2539 talloc_strdup(domain
,
2540 lsa_info
->dns
.dns_forest
.string
);
2541 if (domain
->forest_name
== NULL
) {
2545 if (strequal(domain
->forest_name
, domain
->alt_name
)) {
2546 domain
->domain_flags
|= NETR_TRUST_FLAG_TREEROOT
;
2550 if (lsa_info
->dns
.sid
) {
2551 if (!is_null_sid(&domain
->sid
) &&
2552 !dom_sid_equal(&domain
->sid
,
2555 DEBUG(1, ("set_dc_type_and_flags_connect: DC "
2556 "for domain %s (%s) claimed it was "
2557 "a DC for domain %s, refusing to "
2559 dom_sid_string(talloc_tos(),
2562 dom_sid_string(talloc_tos(),
2563 lsa_info
->dns
.sid
)));
2565 TALLOC_FREE(mem_ctx
);
2568 sid_copy(&domain
->sid
, lsa_info
->dns
.sid
);
2571 domain
->active_directory
= False
;
2573 status
= rpccli_lsa_open_policy(cli
, mem_ctx
, True
,
2574 SEC_FLAG_MAXIMUM_ALLOWED
,
2577 if (!NT_STATUS_IS_OK(status
)) {
2581 status
= dcerpc_lsa_QueryInfoPolicy(cli
->binding_handle
, mem_ctx
,
2583 LSA_POLICY_INFO_ACCOUNT_DOMAIN
,
2586 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(result
)) {
2588 if (lsa_info
->account_domain
.name
.string
) {
2589 if (!strequal(domain
->name
,
2590 lsa_info
->account_domain
.name
.string
))
2593 ("set_dc_type_and_flags_connect: "
2594 "DC for domain %s claimed it was"
2595 " a DC for domain %s, refusing "
2596 "to initialize\n", domain
->name
,
2598 account_domain
.name
.string
));
2600 TALLOC_FREE(mem_ctx
);
2603 talloc_free(domain
->name
);
2605 talloc_strdup(domain
,
2606 lsa_info
->account_domain
.name
.string
);
2609 if (lsa_info
->account_domain
.sid
) {
2610 if (!is_null_sid(&domain
->sid
) &&
2611 !dom_sid_equal(&domain
->sid
,
2612 lsa_info
->account_domain
.sid
))
2615 ("set_dc_type_and_flags_connect: "
2616 "DC for domain %s (%s) claimed "
2617 "it was a DC for domain %s, "
2618 "refusing to initialize\n",
2619 dom_sid_string(talloc_tos(),
2622 dom_sid_string(talloc_tos(),
2623 lsa_info
->account_domain
.sid
)));
2625 TALLOC_FREE(mem_ctx
);
2628 sid_copy(&domain
->sid
, lsa_info
->account_domain
.sid
);
2634 DEBUG(5, ("set_dc_type_and_flags_connect: domain %s is %sin native mode.\n",
2635 domain
->name
, domain
->native_mode
? "" : "NOT "));
2637 DEBUG(5,("set_dc_type_and_flags_connect: domain %s is %srunning active directory.\n",
2638 domain
->name
, domain
->active_directory
? "" : "NOT "));
2640 domain
->can_do_ncacn_ip_tcp
= domain
->active_directory
;
2644 TALLOC_FREE(mem_ctx
);
2646 domain
->initialized
= True
;
2649 /**********************************************************************
2650 Set the domain_flags (trust attributes, domain operating modes, etc...
2651 ***********************************************************************/
2653 static void set_dc_type_and_flags( struct winbindd_domain
*domain
)
2657 * On a DC we loaded all trusts
2658 * from configuration and never learn
2664 /* we always have to contact our primary domain */
2666 if ( domain
->primary
|| domain
->internal
) {
2667 DEBUG(10,("set_dc_type_and_flags: setting up flags for "
2668 "primary or internal domain\n"));
2669 set_dc_type_and_flags_connect( domain
);
2673 /* Use our DC to get the information if possible */
2675 if ( !set_dc_type_and_flags_trustinfo( domain
) ) {
2676 /* Otherwise, fallback to contacting the
2678 set_dc_type_and_flags_connect( domain
);
2686 /**********************************************************************
2687 ***********************************************************************/
2689 static NTSTATUS
cm_get_schannel_creds(struct winbindd_domain
*domain
,
2690 struct netlogon_creds_cli_context
**ppdc
)
2692 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
2693 struct rpc_pipe_client
*netlogon_pipe
;
2697 if ((!IS_DC
) && (!domain
->primary
)) {
2698 return NT_STATUS_TRUSTED_DOMAIN_FAILURE
;
2701 if (domain
->conn
.netlogon_creds_ctx
!= NULL
) {
2702 *ppdc
= domain
->conn
.netlogon_creds_ctx
;
2703 return NT_STATUS_OK
;
2706 result
= cm_connect_netlogon_secure(domain
, &netlogon_pipe
, ppdc
);
2707 if (!NT_STATUS_IS_OK(result
)) {
2711 return NT_STATUS_OK
;
2714 NTSTATUS
cm_connect_sam(struct winbindd_domain
*domain
, TALLOC_CTX
*mem_ctx
,
2716 struct rpc_pipe_client
**cli
, struct policy_handle
*sam_handle
)
2718 struct winbindd_cm_conn
*conn
;
2719 NTSTATUS status
, result
;
2720 struct netlogon_creds_cli_context
*p_creds
;
2721 struct cli_credentials
*creds
= NULL
;
2722 bool retry
= false; /* allow one retry attempt for expired session */
2724 if (sid_check_is_our_sam(&domain
->sid
)) {
2725 if (domain
->rodc
== false || need_rw_dc
== false) {
2726 return open_internal_samr_conn(mem_ctx
, domain
, cli
, sam_handle
);
2732 * In theory we should not use SAMR within
2733 * winbindd at all, but that's a larger task to
2734 * remove this and avoid breaking existing
2737 * At least as AD DC we have the restriction
2738 * to avoid SAMR against trusted domains,
2739 * as there're no existing setups.
2741 return NT_STATUS_REQUEST_NOT_ACCEPTED
;
2745 status
= init_dc_connection_rpc(domain
, need_rw_dc
);
2746 if (!NT_STATUS_IS_OK(status
)) {
2750 conn
= &domain
->conn
;
2752 if (rpccli_is_connected(conn
->samr_pipe
)) {
2756 TALLOC_FREE(conn
->samr_pipe
);
2759 * No SAMR pipe yet. Attempt to get an NTLMSSP SPNEGO authenticated
2760 * sign and sealed pipe using the machine account password by
2761 * preference. If we can't - try schannel, if that fails, try
2765 result
= get_trust_credentials(domain
, talloc_tos(), false, &creds
);
2766 if (!NT_STATUS_IS_OK(result
)) {
2767 DEBUG(10, ("cm_connect_sam: No user available for "
2768 "domain %s, trying schannel\n", domain
->name
));
2772 if (cli_credentials_is_anonymous(creds
)) {
2777 * We have an authenticated connection. Use a SPNEGO
2778 * authenticated SAMR pipe with sign & seal.
2780 status
= cli_rpc_pipe_open_with_creds(conn
->cli
,
2783 DCERPC_AUTH_TYPE_SPNEGO
,
2785 smbXcli_conn_remote_name(conn
->cli
->conn
),
2789 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)
2791 invalidate_cm_connection(domain
);
2796 if (!NT_STATUS_IS_OK(status
)) {
2797 DEBUG(10,("cm_connect_sam: failed to connect to SAMR "
2798 "pipe for domain %s using NTLMSSP "
2799 "authenticated pipe: user %s. Error was "
2800 "%s\n", domain
->name
,
2801 cli_credentials_get_unparsed_name(creds
, talloc_tos()),
2802 nt_errstr(status
)));
2806 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for "
2807 "domain %s using NTLMSSP authenticated "
2808 "pipe: user %s\n", domain
->name
,
2809 cli_credentials_get_unparsed_name(creds
, talloc_tos())));
2811 status
= dcerpc_samr_Connect2(conn
->samr_pipe
->binding_handle
, mem_ctx
,
2812 conn
->samr_pipe
->desthost
,
2813 SEC_FLAG_MAXIMUM_ALLOWED
,
2814 &conn
->sam_connect_handle
,
2817 if (NT_STATUS_EQUAL(status
, NT_STATUS_IO_DEVICE_ERROR
) && !retry
) {
2818 invalidate_cm_connection(domain
);
2819 TALLOC_FREE(conn
->samr_pipe
);
2824 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(result
)) {
2827 if (NT_STATUS_IS_OK(status
)) {
2831 DEBUG(10,("cm_connect_sam: ntlmssp-sealed dcerpc_samr_Connect2 "
2832 "failed for domain %s, error was %s. Trying schannel\n",
2833 domain
->name
, nt_errstr(status
) ));
2834 TALLOC_FREE(conn
->samr_pipe
);
2838 /* Fall back to schannel if it's a W2K pre-SP1 box. */
2840 status
= cm_get_schannel_creds(domain
, &p_creds
);
2841 if (!NT_STATUS_IS_OK(status
)) {
2842 /* If this call fails - conn->cli can now be NULL ! */
2843 DEBUG(10, ("cm_connect_sam: Could not get schannel auth info "
2844 "for domain %s (error %s), trying anon\n",
2846 nt_errstr(status
) ));
2850 status
= cli_rpc_pipe_open_schannel_with_creds(
2851 conn
->cli
, &ndr_table_samr
, NCACN_NP
, p_creds
,
2854 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)
2856 invalidate_cm_connection(domain
);
2861 if (!NT_STATUS_IS_OK(status
)) {
2862 DEBUG(10,("cm_connect_sam: failed to connect to SAMR pipe for "
2863 "domain %s using schannel. Error was %s\n",
2864 domain
->name
, nt_errstr(status
) ));
2867 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for domain %s using "
2868 "schannel.\n", domain
->name
));
2870 status
= dcerpc_samr_Connect2(conn
->samr_pipe
->binding_handle
, mem_ctx
,
2871 conn
->samr_pipe
->desthost
,
2872 SEC_FLAG_MAXIMUM_ALLOWED
,
2873 &conn
->sam_connect_handle
,
2876 if (NT_STATUS_EQUAL(status
, NT_STATUS_IO_DEVICE_ERROR
) && !retry
) {
2877 invalidate_cm_connection(domain
);
2878 TALLOC_FREE(conn
->samr_pipe
);
2883 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(result
)) {
2886 if (NT_STATUS_IS_OK(status
)) {
2889 DEBUG(10,("cm_connect_sam: schannel-sealed dcerpc_samr_Connect2 failed "
2890 "for domain %s, error was %s. Trying anonymous\n",
2891 domain
->name
, nt_errstr(status
) ));
2892 TALLOC_FREE(conn
->samr_pipe
);
2896 /* Finally fall back to anonymous. */
2897 if (lp_winbind_sealed_pipes() || lp_require_strong_key()) {
2898 status
= NT_STATUS_DOWNGRADE_DETECTED
;
2899 DEBUG(1, ("Unwilling to make SAMR connection to domain %s "
2900 "without connection level security, "
2901 "must set 'winbind sealed pipes = false' and "
2902 "'require strong key = false' to proceed: %s\n",
2903 domain
->name
, nt_errstr(status
)));
2906 status
= cli_rpc_pipe_open_noauth(conn
->cli
, &ndr_table_samr
,
2909 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)
2911 invalidate_cm_connection(domain
);
2916 if (!NT_STATUS_IS_OK(status
)) {
2920 status
= dcerpc_samr_Connect2(conn
->samr_pipe
->binding_handle
, mem_ctx
,
2921 conn
->samr_pipe
->desthost
,
2922 SEC_FLAG_MAXIMUM_ALLOWED
,
2923 &conn
->sam_connect_handle
,
2926 if (NT_STATUS_EQUAL(status
, NT_STATUS_IO_DEVICE_ERROR
) && !retry
) {
2927 invalidate_cm_connection(domain
);
2928 TALLOC_FREE(conn
->samr_pipe
);
2933 if (!NT_STATUS_IS_OK(status
)) {
2934 DEBUG(10,("cm_connect_sam: rpccli_samr_Connect2 failed "
2935 "for domain %s Error was %s\n",
2936 domain
->name
, nt_errstr(status
) ));
2939 if (!NT_STATUS_IS_OK(result
)) {
2941 DEBUG(10,("cm_connect_sam: dcerpc_samr_Connect2 failed "
2942 "for domain %s Error was %s\n",
2943 domain
->name
, nt_errstr(result
)));
2948 status
= dcerpc_samr_OpenDomain(conn
->samr_pipe
->binding_handle
,
2950 &conn
->sam_connect_handle
,
2951 SEC_FLAG_MAXIMUM_ALLOWED
,
2953 &conn
->sam_domain_handle
,
2955 if (!NT_STATUS_IS_OK(status
)) {
2962 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
2964 * if we got access denied, we might just have no access rights
2965 * to talk to the remote samr server server (e.g. when we are a
2966 * PDC and we are connecting a w2k8 pdc via an interdomain
2967 * trust). In that case do not invalidate the whole connection
2970 TALLOC_FREE(conn
->samr_pipe
);
2971 ZERO_STRUCT(conn
->sam_domain_handle
);
2973 } else if (!NT_STATUS_IS_OK(status
)) {
2974 invalidate_cm_connection(domain
);
2978 *cli
= conn
->samr_pipe
;
2979 *sam_handle
= conn
->sam_domain_handle
;
2983 /**********************************************************************
2984 open an schanneld ncacn_ip_tcp connection to LSA
2985 ***********************************************************************/
2987 static NTSTATUS
cm_connect_lsa_tcp(struct winbindd_domain
*domain
,
2988 TALLOC_CTX
*mem_ctx
,
2989 struct rpc_pipe_client
**cli
)
2991 struct winbindd_cm_conn
*conn
;
2992 struct netlogon_creds_cli_context
*p_creds
= NULL
;
2995 DEBUG(10,("cm_connect_lsa_tcp\n"));
2997 status
= init_dc_connection_rpc(domain
, false);
2998 if (!NT_STATUS_IS_OK(status
)) {
3002 conn
= &domain
->conn
;
3005 * rpccli_is_connected handles more error cases
3007 if (rpccli_is_connected(conn
->lsa_pipe_tcp
) &&
3008 conn
->lsa_pipe_tcp
->transport
->transport
== NCACN_IP_TCP
&&
3009 conn
->lsa_pipe_tcp
->auth
->auth_level
>= DCERPC_AUTH_LEVEL_INTEGRITY
) {
3013 TALLOC_FREE(conn
->lsa_pipe_tcp
);
3015 status
= cm_get_schannel_creds(domain
, &p_creds
);
3016 if (!NT_STATUS_IS_OK(status
)) {
3020 status
= cli_rpc_pipe_open_schannel_with_creds(conn
->cli
,
3024 &conn
->lsa_pipe_tcp
);
3025 if (!NT_STATUS_IS_OK(status
)) {
3026 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key failed: %s\n",
3027 nt_errstr(status
)));
3032 if (!NT_STATUS_IS_OK(status
)) {
3033 TALLOC_FREE(conn
->lsa_pipe_tcp
);
3037 *cli
= conn
->lsa_pipe_tcp
;
3042 NTSTATUS
cm_connect_lsa(struct winbindd_domain
*domain
, TALLOC_CTX
*mem_ctx
,
3043 struct rpc_pipe_client
**cli
, struct policy_handle
*lsa_policy
)
3045 struct winbindd_cm_conn
*conn
;
3046 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
3047 struct netlogon_creds_cli_context
*p_creds
;
3048 struct cli_credentials
*creds
= NULL
;
3049 bool retry
= false; /* allow one retry attempt for expired session */
3052 result
= init_dc_connection_rpc(domain
, false);
3053 if (!NT_STATUS_IS_OK(result
))
3056 conn
= &domain
->conn
;
3058 if (rpccli_is_connected(conn
->lsa_pipe
)) {
3062 TALLOC_FREE(conn
->lsa_pipe
);
3066 * Make sure we only use schannel as AD DC.
3071 result
= get_trust_credentials(domain
, talloc_tos(), false, &creds
);
3072 if (!NT_STATUS_IS_OK(result
)) {
3073 DEBUG(10, ("cm_connect_lsa: No user available for "
3074 "domain %s, trying schannel\n", domain
->name
));
3078 if (cli_credentials_is_anonymous(creds
)) {
3083 * We have an authenticated connection. Use a SPNEGO
3084 * authenticated LSA pipe with sign & seal.
3086 result
= cli_rpc_pipe_open_with_creds
3087 (conn
->cli
, &ndr_table_lsarpc
, NCACN_NP
,
3088 DCERPC_AUTH_TYPE_SPNEGO
,
3090 smbXcli_conn_remote_name(conn
->cli
->conn
),
3094 if (NT_STATUS_EQUAL(result
, NT_STATUS_NETWORK_SESSION_EXPIRED
)
3096 invalidate_cm_connection(domain
);
3101 if (!NT_STATUS_IS_OK(result
)) {
3102 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
3103 "domain %s using NTLMSSP authenticated pipe: user "
3104 "%s. Error was %s. Trying schannel.\n",
3106 cli_credentials_get_unparsed_name(creds
, talloc_tos()),
3107 nt_errstr(result
)));
3111 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
3112 "NTLMSSP authenticated pipe: user %s\n",
3113 domain
->name
, cli_credentials_get_unparsed_name(creds
, talloc_tos())));
3115 result
= rpccli_lsa_open_policy(conn
->lsa_pipe
, mem_ctx
, True
,
3116 SEC_FLAG_MAXIMUM_ALLOWED
,
3118 if (NT_STATUS_EQUAL(result
, NT_STATUS_IO_DEVICE_ERROR
) && !retry
) {
3119 invalidate_cm_connection(domain
);
3120 TALLOC_FREE(conn
->lsa_pipe
);
3125 if (NT_STATUS_IS_OK(result
)) {
3129 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
3132 TALLOC_FREE(conn
->lsa_pipe
);
3136 /* Fall back to schannel if it's a W2K pre-SP1 box. */
3138 result
= cm_get_schannel_creds(domain
, &p_creds
);
3139 if (!NT_STATUS_IS_OK(result
)) {
3140 /* If this call fails - conn->cli can now be NULL ! */
3141 DEBUG(10, ("cm_connect_lsa: Could not get schannel auth info "
3142 "for domain %s (error %s), trying anon\n",
3144 nt_errstr(result
) ));
3149 result
= cli_rpc_pipe_open_schannel_with_creds(
3150 conn
->cli
, &ndr_table_lsarpc
, NCACN_NP
, p_creds
,
3153 if (NT_STATUS_EQUAL(result
, NT_STATUS_NETWORK_SESSION_EXPIRED
)
3155 invalidate_cm_connection(domain
);
3160 if (!NT_STATUS_IS_OK(result
)) {
3161 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
3162 "domain %s using schannel. Error was %s\n",
3163 domain
->name
, nt_errstr(result
) ));
3166 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
3167 "schannel.\n", domain
->name
));
3169 result
= rpccli_lsa_open_policy(conn
->lsa_pipe
, mem_ctx
, True
,
3170 SEC_FLAG_MAXIMUM_ALLOWED
,
3173 if (NT_STATUS_EQUAL(result
, NT_STATUS_IO_DEVICE_ERROR
) && !retry
) {
3174 invalidate_cm_connection(domain
);
3175 TALLOC_FREE(conn
->lsa_pipe
);
3180 if (NT_STATUS_IS_OK(result
)) {
3186 * Make sure we only use schannel as AD DC.
3191 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
3194 TALLOC_FREE(conn
->lsa_pipe
);
3200 * Make sure we only use schannel as AD DC.
3205 if (lp_winbind_sealed_pipes() || lp_require_strong_key()) {
3206 result
= NT_STATUS_DOWNGRADE_DETECTED
;
3207 DEBUG(1, ("Unwilling to make LSA connection to domain %s "
3208 "without connection level security, "
3209 "must set 'winbind sealed pipes = false' and "
3210 "'require strong key = false' to proceed: %s\n",
3211 domain
->name
, nt_errstr(result
)));
3215 result
= cli_rpc_pipe_open_noauth(conn
->cli
,
3219 if (NT_STATUS_EQUAL(result
, NT_STATUS_NETWORK_SESSION_EXPIRED
)
3221 invalidate_cm_connection(domain
);
3226 if (!NT_STATUS_IS_OK(result
)) {
3230 result
= rpccli_lsa_open_policy(conn
->lsa_pipe
, mem_ctx
, True
,
3231 SEC_FLAG_MAXIMUM_ALLOWED
,
3234 if (NT_STATUS_EQUAL(result
, NT_STATUS_IO_DEVICE_ERROR
) && !retry
) {
3235 invalidate_cm_connection(domain
);
3236 TALLOC_FREE(conn
->lsa_pipe
);
3242 if (!NT_STATUS_IS_OK(result
)) {
3243 invalidate_cm_connection(domain
);
3247 *cli
= conn
->lsa_pipe
;
3248 *lsa_policy
= conn
->lsa_policy
;
3252 /****************************************************************************
3253 Open a LSA connection to a DC, suiteable for LSA lookup calls.
3254 ****************************************************************************/
3256 NTSTATUS
cm_connect_lsat(struct winbindd_domain
*domain
,
3257 TALLOC_CTX
*mem_ctx
,
3258 struct rpc_pipe_client
**cli
,
3259 struct policy_handle
*lsa_policy
)
3263 if (domain
->can_do_ncacn_ip_tcp
) {
3264 status
= cm_connect_lsa_tcp(domain
, mem_ctx
, cli
);
3265 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
) ||
3266 NT_STATUS_EQUAL(status
, NT_STATUS_RPC_SEC_PKG_ERROR
) ||
3267 NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_ACCESS_DENIED
)) {
3268 invalidate_cm_connection(domain
);
3269 status
= cm_connect_lsa_tcp(domain
, mem_ctx
, cli
);
3271 if (NT_STATUS_IS_OK(status
)) {
3276 * we tried twice to connect via ncan_ip_tcp and schannel and
3277 * failed - maybe it is a trusted domain we can't connect to ?
3278 * do not try tcp next time - gd
3280 * This also prevents NETLOGON over TCP
3282 domain
->can_do_ncacn_ip_tcp
= false;
3285 status
= cm_connect_lsa(domain
, mem_ctx
, cli
, lsa_policy
);
3290 /****************************************************************************
3291 Open the netlogon pipe to this DC.
3292 ****************************************************************************/
3294 static NTSTATUS
cm_connect_netlogon_transport(struct winbindd_domain
*domain
,
3295 enum dcerpc_transport_t transport
,
3296 struct rpc_pipe_client
**cli
)
3298 struct messaging_context
*msg_ctx
= global_messaging_context();
3299 struct winbindd_cm_conn
*conn
;
3301 enum netr_SchannelType sec_chan_type
;
3302 struct cli_credentials
*creds
= NULL
;
3307 if (domain
->secure_channel_type
== SEC_CHAN_NULL
) {
3309 * Make sure we don't even try to
3310 * connect to a foreign domain
3311 * without a direct outbound trust.
3313 return NT_STATUS_NO_TRUST_LSA_SECRET
;
3317 result
= init_dc_connection_rpc(domain
, domain
->rodc
);
3318 if (!NT_STATUS_IS_OK(result
)) {
3322 conn
= &domain
->conn
;
3324 if (rpccli_is_connected(conn
->netlogon_pipe
)) {
3325 *cli
= conn
->netlogon_pipe
;
3326 return NT_STATUS_OK
;
3329 TALLOC_FREE(conn
->netlogon_pipe
);
3330 TALLOC_FREE(conn
->netlogon_creds_ctx
);
3332 result
= get_trust_credentials(domain
, talloc_tos(), true, &creds
);
3333 if (!NT_STATUS_IS_OK(result
)) {
3334 DBG_DEBUG("No user available for domain %s when trying "
3335 "schannel\n", domain
->name
);
3336 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
3339 if (cli_credentials_is_anonymous(creds
)) {
3340 DBG_WARNING("get_trust_credential only gave anonymous for %s, "
3341 "unable to make get NETLOGON credentials\n",
3343 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
3346 sec_chan_type
= cli_credentials_get_secure_channel_type(creds
);
3347 if (sec_chan_type
== SEC_CHAN_NULL
) {
3348 if (transport
== NCACN_IP_TCP
) {
3349 DBG_NOTICE("get_secure_channel_type gave SEC_CHAN_NULL "
3350 "for %s, deny NCACN_IP_TCP and let the "
3351 "caller fallback to NCACN_NP.\n",
3353 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
3356 DBG_NOTICE("get_secure_channel_type gave SEC_CHAN_NULL for %s, "
3357 "fallback to noauth on NCACN_NP.\n",
3360 result
= cli_rpc_pipe_open_noauth_transport(
3363 &ndr_table_netlogon
,
3364 &conn
->netlogon_pipe
);
3365 if (!NT_STATUS_IS_OK(result
)) {
3366 invalidate_cm_connection(domain
);
3370 *cli
= conn
->netlogon_pipe
;
3371 return NT_STATUS_OK
;
3374 result
= rpccli_create_netlogon_creds_ctx(creds
,
3378 &conn
->netlogon_creds_ctx
);
3379 if (!NT_STATUS_IS_OK(result
)) {
3380 DEBUG(1, ("rpccli_create_netlogon_creds failed for %s, "
3381 "unable to create NETLOGON credentials: %s\n",
3382 domain
->name
, nt_errstr(result
)));
3386 result
= rpccli_connect_netlogon(
3387 conn
->cli
, transport
,
3388 conn
->netlogon_creds_ctx
, conn
->netlogon_force_reauth
, creds
,
3389 &conn
->netlogon_pipe
);
3390 conn
->netlogon_force_reauth
= false;
3391 if (!NT_STATUS_IS_OK(result
)) {
3392 DBG_DEBUG("rpccli_connect_netlogon failed: %s\n",
3397 *cli
= conn
->netlogon_pipe
;
3398 return NT_STATUS_OK
;
3401 /****************************************************************************
3402 Open a NETLOGON connection to a DC, suiteable for SamLogon calls.
3403 ****************************************************************************/
3405 NTSTATUS
cm_connect_netlogon(struct winbindd_domain
*domain
,
3406 struct rpc_pipe_client
**cli
)
3410 status
= init_dc_connection_rpc(domain
, domain
->rodc
);
3411 if (!NT_STATUS_IS_OK(status
)) {
3415 if (domain
->active_directory
&& domain
->can_do_ncacn_ip_tcp
) {
3416 status
= cm_connect_netlogon_transport(domain
, NCACN_IP_TCP
, cli
);
3417 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
) ||
3418 NT_STATUS_EQUAL(status
, NT_STATUS_RPC_SEC_PKG_ERROR
) ||
3419 NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_ACCESS_DENIED
)) {
3420 invalidate_cm_connection(domain
);
3421 status
= cm_connect_netlogon_transport(domain
, NCACN_IP_TCP
, cli
);
3423 if (NT_STATUS_IS_OK(status
)) {
3428 * we tried twice to connect via ncan_ip_tcp and schannel and
3429 * failed - maybe it is a trusted domain we can't connect to ?
3430 * do not try tcp next time - gd
3432 * This also prevents LSA over TCP
3434 domain
->can_do_ncacn_ip_tcp
= false;
3437 status
= cm_connect_netlogon_transport(domain
, NCACN_NP
, cli
);
3438 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)) {
3440 * SMB2 session expired, needs reauthentication. Drop
3441 * connection and retry.
3443 invalidate_cm_connection(domain
);
3444 status
= cm_connect_netlogon_transport(domain
, NCACN_NP
, cli
);
3450 NTSTATUS
cm_connect_netlogon_secure(struct winbindd_domain
*domain
,
3451 struct rpc_pipe_client
**cli
,
3452 struct netlogon_creds_cli_context
**ppdc
)
3456 if (domain
->secure_channel_type
== SEC_CHAN_NULL
) {
3457 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
3460 status
= cm_connect_netlogon(domain
, cli
);
3461 if (!NT_STATUS_IS_OK(status
)) {
3465 if (domain
->conn
.netlogon_creds_ctx
== NULL
) {
3466 return NT_STATUS_TRUSTED_DOMAIN_FAILURE
;
3469 *ppdc
= domain
->conn
.netlogon_creds_ctx
;
3470 return NT_STATUS_OK
;
3473 void winbind_msg_ip_dropped(struct messaging_context
*msg_ctx
,
3476 struct server_id server_id
,
3479 struct winbindd_domain
*domain
;
3480 char *freeit
= NULL
;
3484 || (data
->data
== NULL
)
3485 || (data
->length
== 0)
3486 || (data
->data
[data
->length
-1] != '\0')) {
3487 DEBUG(1, ("invalid msg_ip_dropped message: not a valid "
3492 addr
= (char *)data
->data
;
3493 DEBUG(10, ("IP %s dropped\n", addr
));
3495 if (!is_ipaddress(addr
)) {
3498 * Some code sends us ip addresses with the /netmask
3501 slash
= strchr(addr
, '/');
3502 if (slash
== NULL
) {
3503 DEBUG(1, ("invalid msg_ip_dropped message: %s",
3507 freeit
= talloc_strndup(talloc_tos(), addr
, slash
-addr
);
3508 if (freeit
== NULL
) {
3509 DEBUG(1, ("talloc failed\n"));
3513 DEBUG(10, ("Stripped /netmask to IP %s\n", addr
));
3516 for (domain
= domain_list(); domain
!= NULL
; domain
= domain
->next
) {
3517 char sockaddr
[INET6_ADDRSTRLEN
];
3519 if (!cli_state_is_connected(domain
->conn
.cli
)) {
3523 print_sockaddr(sockaddr
, sizeof(sockaddr
),
3524 smbXcli_conn_local_sockaddr(domain
->conn
.cli
->conn
));
3526 if (strequal(sockaddr
, addr
)) {
3527 smbXcli_conn_disconnect(domain
->conn
.cli
->conn
, NT_STATUS_OK
);
3530 TALLOC_FREE(freeit
);
3533 void winbind_msg_disconnect_dc(struct messaging_context
*msg_ctx
,
3536 struct server_id server_id
,
3539 struct winbindd_domain
*domain
;
3541 for (domain
= domain_list(); domain
; domain
= domain
->next
) {
3542 if (domain
->internal
) {
3545 invalidate_cm_connection(domain
);