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 "libcli/auth/netlogon_creds_cli.h"
83 #include "rpc_server/rpc_ncacn_np.h"
84 #include "auth/credentials/credentials.h"
85 #include "lib/param/param.h"
88 #define DBGC_CLASS DBGC_WINBIND
92 struct sockaddr_storage ss
;
95 extern struct winbindd_methods reconnect_methods
;
96 extern bool override_logfile
;
98 static NTSTATUS
init_dc_connection_network(struct winbindd_domain
*domain
, bool need_rw_dc
);
99 static void set_dc_type_and_flags( struct winbindd_domain
*domain
);
100 static bool set_dc_type_and_flags_trustinfo( struct winbindd_domain
*domain
);
101 static bool get_dcs(TALLOC_CTX
*mem_ctx
, struct winbindd_domain
*domain
,
102 struct dc_name_ip
**dcs
, int *num_dcs
,
103 uint32_t request_flags
);
105 /****************************************************************
106 Child failed to find DC's. Reschedule check.
107 ****************************************************************/
109 static void msg_failed_to_go_online(struct messaging_context
*msg
,
112 struct server_id server_id
,
115 struct winbindd_domain
*domain
;
116 const char *domainname
= (const char *)data
->data
;
118 if (data
->data
== NULL
|| data
->length
== 0) {
122 DEBUG(5,("msg_fail_to_go_online: received for domain %s.\n", domainname
));
124 for (domain
= domain_list(); domain
; domain
= domain
->next
) {
125 if (domain
->internal
) {
129 if (strequal(domain
->name
, domainname
)) {
130 if (domain
->online
) {
131 /* We're already online, ignore. */
132 DEBUG(5,("msg_fail_to_go_online: domain %s "
133 "already online.\n", domainname
));
137 /* Reschedule the online check. */
138 set_domain_offline(domain
);
144 /****************************************************************
145 Actually cause a reconnect from a message.
146 ****************************************************************/
148 static void msg_try_to_go_online(struct messaging_context
*msg
,
151 struct server_id server_id
,
154 struct winbindd_domain
*domain
;
155 const char *domainname
= (const char *)data
->data
;
157 if (data
->data
== NULL
|| data
->length
== 0) {
161 DEBUG(5,("msg_try_to_go_online: received for domain %s.\n", domainname
));
163 for (domain
= domain_list(); domain
; domain
= domain
->next
) {
164 if (domain
->internal
) {
168 if (strequal(domain
->name
, domainname
)) {
170 if (domain
->online
) {
171 /* We're already online, ignore. */
172 DEBUG(5,("msg_try_to_go_online: domain %s "
173 "already online.\n", domainname
));
177 /* This call takes care of setting the online
178 flag to true if we connected, or re-adding
179 the offline handler if false. Bypasses online
180 check so always does network calls. */
182 init_dc_connection_network(domain
, true);
188 /****************************************************************
189 Fork a child to try and contact a DC. Do this as contacting a
190 DC requires blocking lookups and we don't want to block our
192 ****************************************************************/
194 static bool fork_child_dc_connect(struct winbindd_domain
*domain
)
196 struct dc_name_ip
*dcs
= NULL
;
198 TALLOC_CTX
*mem_ctx
= NULL
;
199 pid_t parent_pid
= getpid();
204 if (domain
->dc_probe_pid
!= (pid_t
)-1) {
206 * We might already have a DC probe
207 * child working, check.
209 if (process_exists_by_pid(domain
->dc_probe_pid
)) {
210 DEBUG(10,("fork_child_dc_connect: pid %u already "
211 "checking for DC's.\n",
212 (unsigned int)domain
->dc_probe_pid
));
215 domain
->dc_probe_pid
= (pid_t
)-1;
218 domain
->dc_probe_pid
= fork();
220 if (domain
->dc_probe_pid
== (pid_t
)-1) {
221 DEBUG(0, ("fork_child_dc_connect: Could not fork: %s\n", strerror(errno
)));
225 if (domain
->dc_probe_pid
!= (pid_t
)0) {
227 messaging_register(server_messaging_context(), NULL
,
228 MSG_WINBIND_TRY_TO_GO_ONLINE
,
229 msg_try_to_go_online
);
230 messaging_register(server_messaging_context(), NULL
,
231 MSG_WINBIND_FAILED_TO_GO_ONLINE
,
232 msg_failed_to_go_online
);
238 /* Leave messages blocked - we will never process one. */
240 if (!override_logfile
) {
241 if (asprintf(&lfile
, "%s/log.winbindd-dc-connect", get_dyn_LOGFILEBASE()) == -1) {
242 DEBUG(0, ("fork_child_dc_connect: out of memory.\n"));
247 status
= winbindd_reinit_after_fork(NULL
, lfile
);
248 if (!NT_STATUS_IS_OK(status
)) {
249 DEBUG(1, ("winbindd_reinit_after_fork failed: %s\n",
251 messaging_send_buf(server_messaging_context(),
252 pid_to_procid(parent_pid
),
253 MSG_WINBIND_FAILED_TO_GO_ONLINE
,
254 (const uint8_t *)domain
->name
,
255 strlen(domain
->name
)+1);
260 setproctitle("dc-connect child");
262 mem_ctx
= talloc_init("fork_child_dc_connect");
264 DEBUG(0,("talloc_init failed.\n"));
265 messaging_send_buf(server_messaging_context(),
266 pid_to_procid(parent_pid
),
267 MSG_WINBIND_FAILED_TO_GO_ONLINE
,
268 (const uint8_t *)domain
->name
,
269 strlen(domain
->name
)+1);
273 ok
= get_dcs(mem_ctx
, domain
, &dcs
, &num_dcs
, 0);
274 TALLOC_FREE(mem_ctx
);
275 if (!ok
|| (num_dcs
== 0)) {
276 /* Still offline ? Can't find DC's. */
277 messaging_send_buf(server_messaging_context(),
278 pid_to_procid(parent_pid
),
279 MSG_WINBIND_FAILED_TO_GO_ONLINE
,
280 (const uint8_t *)domain
->name
,
281 strlen(domain
->name
)+1);
285 /* We got a DC. Send a message to our parent to get it to
286 try and do the same. */
288 messaging_send_buf(server_messaging_context(),
289 pid_to_procid(parent_pid
),
290 MSG_WINBIND_TRY_TO_GO_ONLINE
,
291 (const uint8_t *)domain
->name
,
292 strlen(domain
->name
)+1);
296 /****************************************************************
297 Handler triggered if we're offline to try and detect a DC.
298 ****************************************************************/
300 static void check_domain_online_handler(struct tevent_context
*ctx
,
301 struct tevent_timer
*te
,
305 struct winbindd_domain
*domain
=
306 (struct winbindd_domain
*)private_data
;
308 DEBUG(10,("check_domain_online_handler: called for domain "
309 "%s (online = %s)\n", domain
->name
,
310 domain
->online
? "True" : "False" ));
312 TALLOC_FREE(domain
->check_online_event
);
314 /* Are we still in "startup" mode ? */
316 if (domain
->startup
&& (time_mono(NULL
) > domain
->startup_time
+ 30)) {
317 /* No longer in "startup" mode. */
318 DEBUG(10,("check_domain_online_handler: domain %s no longer in 'startup' mode.\n",
320 domain
->startup
= False
;
323 /* We've been told to stay offline, so stay
326 if (get_global_winbindd_state_offline()) {
327 DEBUG(10,("check_domain_online_handler: domain %s remaining globally offline\n",
332 /* Fork a child to test if it can contact a DC.
333 If it can then send ourselves a message to
334 cause a reconnect. */
336 fork_child_dc_connect(domain
);
339 /****************************************************************
340 If we're still offline setup the timeout check.
341 ****************************************************************/
343 static void calc_new_online_timeout_check(struct winbindd_domain
*domain
)
345 int wbr
= lp_winbind_reconnect_delay();
347 if (domain
->startup
) {
348 domain
->check_online_timeout
= 10;
349 } else if (domain
->check_online_timeout
< wbr
) {
350 domain
->check_online_timeout
= wbr
;
354 void winbind_msg_domain_offline(struct messaging_context
*msg_ctx
,
357 struct server_id server_id
,
360 const char *domain_name
= (const char *)data
->data
;
361 struct winbindd_domain
*domain
;
363 domain
= find_domain_from_name_noinit(domain_name
);
364 if (domain
== NULL
) {
368 domain
->online
= false;
370 DEBUG(10, ("Domain %s is marked as offline now.\n",
374 void winbind_msg_domain_online(struct messaging_context
*msg_ctx
,
377 struct server_id server_id
,
380 const char *domain_name
= (const char *)data
->data
;
381 struct winbindd_domain
*domain
;
383 domain
= find_domain_from_name_noinit(domain_name
);
384 if (domain
== NULL
) {
388 domain
->online
= true;
390 DEBUG(10, ("Domain %s is marked as online now.\n",
394 /****************************************************************
395 Set domain offline and also add handler to put us back online
397 ****************************************************************/
399 void set_domain_offline(struct winbindd_domain
*domain
)
401 pid_t parent_pid
= getppid();
403 DEBUG(10,("set_domain_offline: called for domain %s\n",
406 TALLOC_FREE(domain
->check_online_event
);
408 if (domain
->internal
) {
409 DEBUG(3,("set_domain_offline: domain %s is internal - logic error.\n",
414 domain
->online
= False
;
416 /* Offline domains are always initialized. They're
417 re-initialized when they go back online. */
419 domain
->initialized
= True
;
421 /* We only add the timeout handler that checks and
422 allows us to go back online when we've not
423 been told to remain offline. */
425 if (get_global_winbindd_state_offline()) {
426 DEBUG(10,("set_domain_offline: domain %s remaining globally offline\n",
431 /* If we're in startup mode, check again in 10 seconds, not in
432 lp_winbind_reconnect_delay() seconds (which is 30 seconds by default). */
434 calc_new_online_timeout_check(domain
);
436 domain
->check_online_event
= tevent_add_timer(server_event_context(),
438 timeval_current_ofs(domain
->check_online_timeout
,0),
439 check_domain_online_handler
,
442 /* The above *has* to succeed for winbindd to work. */
443 if (!domain
->check_online_event
) {
444 smb_panic("set_domain_offline: failed to add online handler");
447 DEBUG(10,("set_domain_offline: added event handler for domain %s\n",
450 /* Send a message to the parent that the domain is offline. */
451 if (parent_pid
> 1 && !domain
->internal
) {
452 messaging_send_buf(server_messaging_context(),
453 pid_to_procid(parent_pid
),
454 MSG_WINBIND_DOMAIN_OFFLINE
,
455 (uint8_t *)domain
->name
,
456 strlen(domain
->name
) + 1);
459 /* Send an offline message to the idmap child when our
460 primary domain goes offline */
462 if ( domain
->primary
) {
463 struct winbindd_child
*idmap
= idmap_child();
465 if ( idmap
->pid
!= 0 ) {
466 messaging_send_buf(server_messaging_context(),
467 pid_to_procid(idmap
->pid
),
469 (const uint8_t *)domain
->name
,
470 strlen(domain
->name
)+1);
477 /****************************************************************
478 Set domain online - if allowed.
479 ****************************************************************/
481 static void set_domain_online(struct winbindd_domain
*domain
)
483 pid_t parent_pid
= getppid();
485 DEBUG(10,("set_domain_online: called for domain %s\n",
488 if (domain
->internal
) {
489 DEBUG(3,("set_domain_online: domain %s is internal - logic error.\n",
494 if (get_global_winbindd_state_offline()) {
495 DEBUG(10,("set_domain_online: domain %s remaining globally offline\n",
500 winbindd_set_locator_kdc_envs(domain
);
502 /* If we are waiting to get a krb5 ticket, trigger immediately. */
503 ccache_regain_all_now();
505 /* Ok, we're out of any startup mode now... */
506 domain
->startup
= False
;
508 if (domain
->online
== False
) {
509 /* We were offline - now we're online. We default to
510 using the MS-RPC backend if we started offline,
511 and if we're going online for the first time we
512 should really re-initialize the backends and the
513 checks to see if we're talking to an AD or NT domain.
516 domain
->initialized
= False
;
518 /* 'reconnect_methods' is the MS-RPC backend. */
519 if (domain
->backend
== &reconnect_methods
) {
520 domain
->backend
= NULL
;
524 /* Ensure we have no online timeout checks. */
525 domain
->check_online_timeout
= 0;
526 TALLOC_FREE(domain
->check_online_event
);
528 /* Ensure we ignore any pending child messages. */
529 messaging_deregister(server_messaging_context(),
530 MSG_WINBIND_TRY_TO_GO_ONLINE
, NULL
);
531 messaging_deregister(server_messaging_context(),
532 MSG_WINBIND_FAILED_TO_GO_ONLINE
, NULL
);
534 domain
->online
= True
;
536 /* Send a message to the parent that the domain is online. */
537 if (parent_pid
> 1 && !domain
->internal
) {
538 messaging_send_buf(server_messaging_context(),
539 pid_to_procid(parent_pid
),
540 MSG_WINBIND_DOMAIN_ONLINE
,
541 (uint8_t *)domain
->name
,
542 strlen(domain
->name
) + 1);
545 /* Send an online message to the idmap child when our
546 primary domain comes online */
548 if ( domain
->primary
) {
549 struct winbindd_child
*idmap
= idmap_child();
551 if ( idmap
->pid
!= 0 ) {
552 messaging_send_buf(server_messaging_context(),
553 pid_to_procid(idmap
->pid
),
555 (const uint8_t *)domain
->name
,
556 strlen(domain
->name
)+1);
563 /****************************************************************
564 Requested to set a domain online.
565 ****************************************************************/
567 void set_domain_online_request(struct winbindd_domain
*domain
)
571 DEBUG(10,("set_domain_online_request: called for domain %s\n",
574 if (get_global_winbindd_state_offline()) {
575 DEBUG(10,("set_domain_online_request: domain %s remaining globally offline\n",
580 if (domain
->internal
) {
581 DEBUG(10, ("set_domain_online_request: Internal domains are "
586 /* We've been told it's safe to go online and
587 try and connect to a DC. But I don't believe it
588 because network manager seems to lie.
589 Wait at least 5 seconds. Heuristics suck... */
594 /* Go into "startup" mode again. */
595 domain
->startup_time
= time_mono(NULL
);
596 domain
->startup
= True
;
600 if (!domain
->check_online_event
) {
601 /* If we've come from being globally offline we
602 don't have a check online event handler set.
603 We need to add one now we're trying to go
606 DEBUG(10,("set_domain_online_request: domain %s was globally offline.\n",
610 TALLOC_FREE(domain
->check_online_event
);
612 domain
->check_online_event
= tevent_add_timer(server_event_context(),
615 check_domain_online_handler
,
618 /* The above *has* to succeed for winbindd to work. */
619 if (!domain
->check_online_event
) {
620 smb_panic("set_domain_online_request: failed to add online handler");
624 /****************************************************************
625 Add -ve connection cache entries for domain and realm.
626 ****************************************************************/
628 static void winbind_add_failed_connection_entry(
629 const struct winbindd_domain
*domain
,
633 add_failed_connection_entry(domain
->name
, server
, result
);
634 /* If this was the saf name for the last thing we talked to,
636 saf_delete(domain
->name
);
637 if (domain
->alt_name
!= NULL
) {
638 add_failed_connection_entry(domain
->alt_name
, server
, result
);
639 saf_delete(domain
->alt_name
);
641 winbindd_unset_locator_kdc_env(domain
);
644 /* Choose between anonymous or authenticated connections. We need to use
645 an authenticated connection if DCs have the RestrictAnonymous registry
646 entry set > 0, or the "Additional restrictions for anonymous
647 connections" set in the win2k Local Security Policy.
649 Caller to free() result in domain, username, password
652 static void cm_get_ipc_userpass(char **username
, char **domain
, char **password
)
654 *username
= (char *)secrets_fetch(SECRETS_AUTH_USER
, NULL
);
655 *domain
= (char *)secrets_fetch(SECRETS_AUTH_DOMAIN
, NULL
);
656 *password
= (char *)secrets_fetch(SECRETS_AUTH_PASSWORD
, NULL
);
658 if (*username
&& **username
) {
660 if (!*domain
|| !**domain
)
661 *domain
= smb_xstrdup(lp_workgroup());
663 if (!*password
|| !**password
)
664 *password
= smb_xstrdup("");
666 DEBUG(3, ("cm_get_ipc_userpass: Retrieved auth-user from secrets.tdb [%s\\%s]\n",
667 *domain
, *username
));
670 DEBUG(3, ("cm_get_ipc_userpass: No auth-user defined\n"));
671 *username
= smb_xstrdup("");
672 *domain
= smb_xstrdup("");
673 *password
= smb_xstrdup("");
677 static NTSTATUS
cm_get_ipc_credentials(TALLOC_CTX
*mem_ctx
,
678 struct cli_credentials
**_creds
)
681 TALLOC_CTX
*frame
= talloc_stackframe();
682 NTSTATUS status
= NT_STATUS_INTERNAL_ERROR
;
683 struct loadparm_context
*lp_ctx
;
684 char *username
= NULL
;
685 char *netbios_domain
= NULL
;
686 char *password
= NULL
;
687 struct cli_credentials
*creds
= NULL
;
690 cm_get_ipc_userpass(&username
, &netbios_domain
, &password
);
692 lp_ctx
= loadparm_init_s3(frame
, loadparm_s3_helpers());
693 if (lp_ctx
== NULL
) {
694 DEBUG(1, ("loadparm_init_s3 failed\n"));
695 status
= NT_STATUS_INTERNAL_ERROR
;
699 creds
= cli_credentials_init(mem_ctx
);
701 status
= NT_STATUS_NO_MEMORY
;
705 cli_credentials_set_conf(creds
, lp_ctx
);
706 cli_credentials_set_kerberos_state(creds
, CRED_DONT_USE_KERBEROS
);
708 ok
= cli_credentials_set_domain(creds
, netbios_domain
, CRED_SPECIFIED
);
710 status
= NT_STATUS_NO_MEMORY
;
714 ok
= cli_credentials_set_username(creds
, username
, CRED_SPECIFIED
);
716 status
= NT_STATUS_NO_MEMORY
;
720 ok
= cli_credentials_set_password(creds
, password
, CRED_SPECIFIED
);
722 status
= NT_STATUS_NO_MEMORY
;
728 status
= NT_STATUS_OK
;
732 SAFE_FREE(netbios_domain
);
738 static bool cm_is_ipc_credentials(struct cli_credentials
*creds
)
740 TALLOC_CTX
*frame
= talloc_stackframe();
741 char *ipc_account
= NULL
;
742 char *ipc_domain
= NULL
;
743 char *ipc_password
= NULL
;
744 const char *creds_account
= NULL
;
745 const char *creds_domain
= NULL
;
746 const char *creds_password
= NULL
;
749 cm_get_ipc_userpass(&ipc_account
, &ipc_domain
, &ipc_password
);
751 creds_account
= cli_credentials_get_username(creds
);
752 creds_domain
= cli_credentials_get_domain(creds
);
753 creds_password
= cli_credentials_get_password(creds
);
755 if (!strequal(ipc_domain
, creds_domain
)) {
759 if (!strequal(ipc_account
, creds_account
)) {
763 if (!strcsequal(ipc_password
, creds_password
)) {
769 SAFE_FREE(ipc_account
);
770 SAFE_FREE(ipc_domain
);
771 SAFE_FREE(ipc_password
);
776 static bool get_dc_name_via_netlogon(struct winbindd_domain
*domain
,
778 struct sockaddr_storage
*dc_ss
,
779 uint32_t request_flags
)
781 struct winbindd_domain
*our_domain
= NULL
;
782 struct rpc_pipe_client
*netlogon_pipe
= NULL
;
786 unsigned int orig_timeout
;
787 const char *tmp
= NULL
;
789 struct dcerpc_binding_handle
*b
;
791 /* Hmmmm. We can only open one connection to the NETLOGON pipe at the
798 if (domain
->primary
) {
802 our_domain
= find_our_domain();
804 if ((mem_ctx
= talloc_init("get_dc_name_via_netlogon")) == NULL
) {
808 result
= cm_connect_netlogon(our_domain
, &netlogon_pipe
);
809 if (!NT_STATUS_IS_OK(result
)) {
810 talloc_destroy(mem_ctx
);
814 b
= netlogon_pipe
->binding_handle
;
816 /* This call can take a long time - allow the server to time out.
817 35 seconds should do it. */
819 orig_timeout
= rpccli_set_timeout(netlogon_pipe
, 35000);
821 if (our_domain
->active_directory
) {
822 struct netr_DsRGetDCNameInfo
*domain_info
= NULL
;
825 * TODO request flags are not respected in the server
826 * (and in some cases, like REQUIRE_PDC, causes an error)
828 result
= dcerpc_netr_DsRGetDCName(b
,
834 request_flags
|DS_RETURN_DNS_NAME
,
837 if (NT_STATUS_IS_OK(result
) && W_ERROR_IS_OK(werr
)) {
839 mem_ctx
, domain_info
->dc_unc
);
841 DEBUG(0, ("talloc_strdup failed\n"));
842 talloc_destroy(mem_ctx
);
845 if (domain
->alt_name
== NULL
) {
846 domain
->alt_name
= talloc_strdup(domain
,
847 domain_info
->domain_name
);
848 if (domain
->alt_name
== NULL
) {
849 DEBUG(0, ("talloc_strdup failed\n"));
850 talloc_destroy(mem_ctx
);
854 if (domain
->forest_name
== NULL
) {
855 domain
->forest_name
= talloc_strdup(domain
,
856 domain_info
->forest_name
);
857 if (domain
->forest_name
== NULL
) {
858 DEBUG(0, ("talloc_strdup failed\n"));
859 talloc_destroy(mem_ctx
);
865 result
= dcerpc_netr_GetAnyDCName(b
, mem_ctx
,
872 /* And restore our original timeout. */
873 rpccli_set_timeout(netlogon_pipe
, orig_timeout
);
875 if (!NT_STATUS_IS_OK(result
)) {
876 DEBUG(10,("dcerpc_netr_GetAnyDCName failed: %s\n",
878 talloc_destroy(mem_ctx
);
882 if (!W_ERROR_IS_OK(werr
)) {
883 DEBUG(10,("dcerpc_netr_GetAnyDCName failed: %s\n",
885 talloc_destroy(mem_ctx
);
889 /* dcerpc_netr_GetAnyDCName gives us a name with \\ */
890 p
= strip_hostname(tmp
);
894 talloc_destroy(mem_ctx
);
896 DEBUG(10,("dcerpc_netr_GetAnyDCName returned %s\n", dcname
));
898 if (!resolve_name(dcname
, dc_ss
, 0x20, true)) {
906 * Helper function to assemble trust password and account name
908 static NTSTATUS
get_trust_credentials(struct winbindd_domain
*domain
,
911 struct cli_credentials
**_creds
)
913 const struct winbindd_domain
*creds_domain
= NULL
;
914 struct cli_credentials
*creds
;
916 bool force_machine_account
= false;
918 /* If we are a DC and this is not our own domain */
920 if (!domain
->active_directory
) {
923 * For non active directory domains
924 * we can only use NTLMSSP for SMB.
926 * But the trust account is not allowed
927 * to use SMB with NTLMSSP.
929 force_machine_account
= true;
933 if (IS_DC
&& !force_machine_account
) {
934 creds_domain
= domain
;
936 creds_domain
= find_our_domain();
937 if (creds_domain
== NULL
) {
938 return NT_STATUS_INVALID_SERVER_STATE
;
942 status
= pdb_get_trust_credentials(creds_domain
->name
,
943 creds_domain
->alt_name
,
946 if (!NT_STATUS_IS_OK(status
)) {
950 if (creds_domain
!= domain
) {
952 * We can only use schannel against a direct trust
954 cli_credentials_set_secure_channel_type(creds
,
963 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
966 status
= cm_get_ipc_credentials(mem_ctx
, &creds
);
967 if (!NT_STATUS_IS_OK(status
)) {
975 /************************************************************************
976 Given a fd with a just-connected TCP connection to a DC, open a connection
978 ************************************************************************/
980 static NTSTATUS
cm_prepare_connection(struct winbindd_domain
*domain
,
982 const char *controller
,
983 struct cli_state
**cli
,
986 bool try_ipc_auth
= false;
987 const char *machine_principal
= NULL
;
988 const char *machine_realm
= NULL
;
989 const char *machine_account
= NULL
;
990 const char *machine_domain
= NULL
;
992 struct cli_credentials
*creds
= NULL
;
994 struct named_mutex
*mutex
;
996 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
998 NTSTATUS tcon_status
= NT_STATUS_NETWORK_NAME_DELETED
;
1000 enum smb_signing_setting smb_sign_client_connections
= lp_client_ipc_signing();
1002 if (smb_sign_client_connections
== SMB_SIGNING_DEFAULT
) {
1004 * If we are connecting to our own AD domain, require
1005 * smb signing to disrupt MITM attacks
1007 if (domain
->primary
&& lp_security() == SEC_ADS
) {
1008 smb_sign_client_connections
= SMB_SIGNING_REQUIRED
;
1010 * If we are in or are an AD domain and connecting to another
1011 * AD domain in our forest
1012 * then require smb signing to disrupt MITM attacks
1014 } else if ((lp_security() == SEC_ADS
||
1015 lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
)
1016 && domain
->active_directory
1017 && (domain
->domain_trust_attribs
1018 & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST
)) {
1019 smb_sign_client_connections
= SMB_SIGNING_REQUIRED
;
1023 DEBUG(10,("cm_prepare_connection: connecting to DC %s for domain %s\n",
1024 controller
, domain
->name
));
1028 mutex
= grab_named_mutex(talloc_tos(), controller
,
1029 WINBIND_SERVER_MUTEX_WAIT_TIME
);
1030 if (mutex
== NULL
) {
1032 DEBUG(0,("cm_prepare_connection: mutex grab failed for %s\n",
1034 result
= NT_STATUS_POSSIBLE_DEADLOCK
;
1038 *cli
= cli_state_create(NULL
, sockfd
, controller
,
1039 smb_sign_client_connections
, flags
);
1042 DEBUG(1, ("Could not cli_initialize\n"));
1043 result
= NT_STATUS_NO_MEMORY
;
1047 cli_set_timeout(*cli
, 10000); /* 10 seconds */
1049 set_socket_options(sockfd
, lp_socket_options());
1051 result
= smbXcli_negprot((*cli
)->conn
, (*cli
)->timeout
,
1052 lp_client_ipc_min_protocol(),
1053 lp_client_ipc_max_protocol());
1055 if (!NT_STATUS_IS_OK(result
)) {
1056 DEBUG(1, ("cli_negprot failed: %s\n", nt_errstr(result
)));
1060 if (smbXcli_conn_protocol((*cli
)->conn
) >= PROTOCOL_NT1
&&
1061 smb1cli_conn_capabilities((*cli
)->conn
) & CAP_EXTENDED_SECURITY
) {
1062 try_ipc_auth
= true;
1063 } else if (smbXcli_conn_protocol((*cli
)->conn
) >= PROTOCOL_SMB2_02
) {
1064 try_ipc_auth
= true;
1065 } else if (smb_sign_client_connections
== SMB_SIGNING_REQUIRED
) {
1067 * If we are forcing on SMB signing, then we must
1068 * require authentication unless this is a one-way
1069 * trust, and we have no stored user/password
1071 try_ipc_auth
= true;
1075 result
= get_trust_credentials(domain
, talloc_tos(), false, &creds
);
1076 if (!NT_STATUS_IS_OK(result
)) {
1077 DEBUG(1, ("get_trust_credentials(%s) failed: %s\n",
1078 domain
->name
, nt_errstr(result
)));
1083 * Without SPNEGO or NTLMSSP (perhaps via SMB2) we
1084 * would try and authentication with our machine
1085 * account password and fail. This is very rare in
1086 * the modern world however
1088 creds
= cli_credentials_init_anon(talloc_tos());
1089 if (creds
== NULL
) {
1090 result
= NT_STATUS_NO_MEMORY
;
1091 DEBUG(1, ("cli_credentials_init_anon(%s) failed: %s\n",
1092 domain
->name
, nt_errstr(result
)));
1097 machine_principal
= cli_credentials_get_principal(creds
,
1099 machine_realm
= cli_credentials_get_realm(creds
);
1100 machine_account
= cli_credentials_get_username(creds
);
1101 machine_domain
= cli_credentials_get_domain(creds
);
1103 DEBUG(5, ("connecting to %s (%s, %s) with account [%s\\%s] principal "
1104 "[%s] and realm [%s]\n",
1105 controller
, domain
->name
, domain
->alt_name
,
1106 machine_domain
, machine_account
,
1107 machine_principal
, machine_realm
));
1109 if (cli_credentials_is_anonymous(creds
)) {
1113 winbindd_set_locator_kdc_envs(domain
);
1115 result
= cli_session_setup_creds(*cli
, creds
);
1116 if (NT_STATUS_IS_OK(result
)) {
1117 goto session_setup_done
;
1120 DEBUG(1, ("authenticated session setup to %s using %s failed with %s\n",
1122 cli_credentials_get_unparsed_name(creds
, talloc_tos()),
1123 nt_errstr(result
)));
1126 * If we are not going to validiate the conneciton
1127 * with SMB signing, then allow us to fall back to
1130 if (NT_STATUS_EQUAL(result
, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT
)
1131 || NT_STATUS_EQUAL(result
, NT_STATUS_TRUSTED_DOMAIN_FAILURE
)
1132 || NT_STATUS_EQUAL(result
, NT_STATUS_INVALID_ACCOUNT_NAME
)
1133 || NT_STATUS_EQUAL(result
, NT_STATUS_NO_LOGON_SERVERS
)
1134 || NT_STATUS_EQUAL(result
, NT_STATUS_LOGON_FAILURE
))
1136 if (!cm_is_ipc_credentials(creds
)) {
1140 if (smb_sign_client_connections
== SMB_SIGNING_REQUIRED
) {
1151 tmp_status
= cm_get_ipc_credentials(talloc_tos(), &creds
);
1152 if (!NT_STATUS_IS_OK(tmp_status
)) {
1153 result
= tmp_status
;
1157 if (cli_credentials_is_anonymous(creds
)) {
1161 machine_account
= cli_credentials_get_username(creds
);
1162 machine_domain
= cli_credentials_get_domain(creds
);
1164 DEBUG(5, ("connecting to %s from %s using NTLMSSP with username "
1165 "[%s]\\[%s]\n", controller
, lp_netbios_name(),
1166 machine_domain
, machine_account
));
1168 result
= cli_session_setup_creds(*cli
, creds
);
1169 if (NT_STATUS_IS_OK(result
)) {
1170 goto session_setup_done
;
1173 DEBUG(1, ("authenticated session setup to %s using %s failed with %s\n",
1175 cli_credentials_get_unparsed_name(creds
, talloc_tos()),
1176 nt_errstr(result
)));
1179 * If we are not going to validiate the conneciton
1180 * with SMB signing, then allow us to fall back to
1183 if (NT_STATUS_EQUAL(result
, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT
)
1184 || NT_STATUS_EQUAL(result
, NT_STATUS_TRUSTED_DOMAIN_FAILURE
)
1185 || NT_STATUS_EQUAL(result
, NT_STATUS_INVALID_ACCOUNT_NAME
)
1186 || NT_STATUS_EQUAL(result
, NT_STATUS_NO_LOGON_SERVERS
)
1187 || NT_STATUS_EQUAL(result
, NT_STATUS_LOGON_FAILURE
))
1197 if (smb_sign_client_connections
== SMB_SIGNING_REQUIRED
) {
1201 /* Fall back to anonymous connection, this might fail later */
1202 DEBUG(5,("cm_prepare_connection: falling back to anonymous "
1203 "connection for DC %s\n",
1206 result
= cli_session_setup_anon(*cli
);
1207 if (NT_STATUS_IS_OK(result
)) {
1208 DEBUG(5, ("Connected anonymously\n"));
1209 goto session_setup_done
;
1212 DEBUG(1, ("anonymous session setup to %s failed with %s\n",
1213 controller
, nt_errstr(result
)));
1215 /* We can't session setup */
1222 * This should be a short term hack until
1223 * dynamic re-authentication is implemented.
1225 * See Bug 9175 - winbindd doesn't recover from
1226 * NT_STATUS_NETWORK_SESSION_EXPIRED
1228 if (smbXcli_conn_protocol((*cli
)->conn
) >= PROTOCOL_SMB2_02
) {
1229 smbXcli_session_set_disconnect_expired((*cli
)->smb2
.session
);
1232 result
= cli_tree_connect(*cli
, "IPC$", "IPC", NULL
);
1233 if (!NT_STATUS_IS_OK(result
)) {
1234 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(result
)));
1237 tcon_status
= result
;
1239 /* cache the server name for later connections */
1241 saf_store(domain
->name
, controller
);
1242 if (domain
->alt_name
) {
1243 saf_store(domain
->alt_name
, controller
);
1246 winbindd_set_locator_kdc_envs(domain
);
1251 result
= NT_STATUS_OK
;
1257 if (NT_STATUS_IS_OK(result
)) {
1258 result
= tcon_status
;
1261 if (!NT_STATUS_IS_OK(result
)) {
1262 DEBUG(1, ("Failed to prepare SMB connection to %s: %s\n",
1263 controller
, nt_errstr(result
)));
1264 winbind_add_failed_connection_entry(domain
, controller
, result
);
1265 if ((*cli
) != NULL
) {
1274 /*******************************************************************
1275 Add a dcname and sockaddr_storage pair to the end of a dc_name_ip
1278 Keeps the list unique by not adding duplicate entries.
1280 @param[in] mem_ctx talloc memory context to allocate from
1281 @param[in] domain_name domain of the DC
1282 @param[in] dcname name of the DC to add to the list
1283 @param[in] pss Internet address and port pair to add to the list
1284 @param[in,out] dcs array of dc_name_ip structures to add to
1285 @param[in,out] num_dcs number of dcs returned in the dcs array
1286 @return true if the list was added to, false otherwise
1287 *******************************************************************/
1289 static bool add_one_dc_unique(TALLOC_CTX
*mem_ctx
, const char *domain_name
,
1290 const char *dcname
, struct sockaddr_storage
*pss
,
1291 struct dc_name_ip
**dcs
, int *num
)
1295 if (!NT_STATUS_IS_OK(check_negative_conn_cache(domain_name
, dcname
))) {
1296 DEBUG(10, ("DC %s was in the negative conn cache\n", dcname
));
1300 /* Make sure there's no duplicates in the list */
1301 for (i
=0; i
<*num
; i
++)
1303 (struct sockaddr
*)(void *)&(*dcs
)[i
].ss
,
1304 (struct sockaddr
*)(void *)pss
))
1307 *dcs
= talloc_realloc(mem_ctx
, *dcs
, struct dc_name_ip
, (*num
)+1);
1312 fstrcpy((*dcs
)[*num
].name
, dcname
);
1313 (*dcs
)[*num
].ss
= *pss
;
1318 static bool add_sockaddr_to_array(TALLOC_CTX
*mem_ctx
,
1319 struct sockaddr_storage
*pss
, uint16_t port
,
1320 struct sockaddr_storage
**addrs
, int *num
)
1322 *addrs
= talloc_realloc(mem_ctx
, *addrs
, struct sockaddr_storage
, (*num
)+1);
1324 if (*addrs
== NULL
) {
1329 (*addrs
)[*num
] = *pss
;
1330 set_sockaddr_port((struct sockaddr
*)&(*addrs
)[*num
], port
);
1336 /*******************************************************************
1337 convert an ip to a name
1338 For an AD Domain, it checks the requirements of the request flags.
1339 *******************************************************************/
1341 static bool dcip_check_name(TALLOC_CTX
*mem_ctx
,
1342 const struct winbindd_domain
*domain
,
1343 struct sockaddr_storage
*pss
,
1344 char **name
, uint32_t request_flags
)
1346 struct ip_service ip_list
;
1347 uint32_t nt_version
= NETLOGON_NT_VERSION_1
;
1349 const char *dc_name
;
1352 bool is_ad_domain
= false;
1358 /* For active directory servers, try to get the ldap server name.
1359 None of these failures should be considered critical for now */
1361 if ((lp_security() == SEC_ADS
) && (domain
->alt_name
!= NULL
)) {
1362 is_ad_domain
= true;
1363 } else if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
) {
1364 is_ad_domain
= domain
->active_directory
;
1369 ADS_STATUS ads_status
;
1370 char addr
[INET6_ADDRSTRLEN
];
1372 print_sockaddr(addr
, sizeof(addr
), pss
);
1374 ads
= ads_init(domain
->alt_name
, domain
->name
, addr
);
1375 ads
->auth
.flags
|= ADS_AUTH_NO_BIND
;
1376 ads
->config
.flags
|= request_flags
;
1377 ads
->server
.no_fallback
= true;
1379 ads_status
= ads_connect(ads
);
1380 if (ADS_ERR_OK(ads_status
)) {
1381 /* We got a cldap packet. */
1382 *name
= talloc_strdup(mem_ctx
,
1383 ads
->config
.ldap_server_name
);
1384 if (*name
== NULL
) {
1387 namecache_store(*name
, 0x20, 1, &ip_list
);
1389 DEBUG(10,("dcip_check_name: flags = 0x%x\n", (unsigned int)ads
->config
.flags
));
1391 if (domain
->primary
&& (ads
->config
.flags
& NBT_SERVER_KDC
)) {
1392 if (ads_closest_dc(ads
)) {
1393 char *sitename
= sitename_fetch(mem_ctx
, ads
->config
.realm
);
1395 /* We're going to use this KDC for this realm/domain.
1396 If we are using sites, then force the krb5 libs
1399 create_local_private_krb5_conf_for_domain(domain
->alt_name
,
1404 TALLOC_FREE(sitename
);
1406 /* use an off site KDC */
1407 create_local_private_krb5_conf_for_domain(domain
->alt_name
,
1412 winbindd_set_locator_kdc_envs(domain
);
1414 /* Ensure we contact this DC also. */
1415 saf_store(domain
->name
, *name
);
1416 saf_store(domain
->alt_name
, *name
);
1419 ads_destroy( &ads
);
1423 ads_destroy( &ads
);
1428 status
= nbt_getdc(server_messaging_context(), 10, pss
, domain
->name
,
1429 &domain
->sid
, nt_version
, mem_ctx
, &nt_version
,
1431 if (NT_STATUS_IS_OK(status
)) {
1432 *name
= talloc_strdup(mem_ctx
, dc_name
);
1433 if (*name
== NULL
) {
1436 namecache_store(*name
, 0x20, 1, &ip_list
);
1440 /* try node status request */
1442 if (name_status_find(domain
->name
, 0x1c, 0x20, pss
, nbtname
) ) {
1443 namecache_store(nbtname
, 0x20, 1, &ip_list
);
1446 *name
= talloc_strdup(mem_ctx
, nbtname
);
1447 if (*name
== NULL
) {
1457 /*******************************************************************
1458 Retrieve a list of IP addresses for domain controllers.
1460 The array is sorted in the preferred connection order.
1462 @param[in] mem_ctx talloc memory context to allocate from
1463 @param[in] domain domain to retrieve DCs for
1464 @param[out] dcs array of dcs that will be returned
1465 @param[out] num_dcs number of dcs returned in the dcs array
1467 *******************************************************************/
1469 static bool get_dcs(TALLOC_CTX
*mem_ctx
, struct winbindd_domain
*domain
,
1470 struct dc_name_ip
**dcs
, int *num_dcs
,
1471 uint32_t request_flags
)
1474 struct sockaddr_storage ss
;
1475 struct ip_service
*ip_list
= NULL
;
1476 int iplist_size
= 0;
1479 enum security_types sec
= (enum security_types
)lp_security();
1481 is_our_domain
= strequal(domain
->name
, lp_workgroup());
1483 /* If not our domain, get the preferred DC, by asking our primary DC */
1485 && get_dc_name_via_netlogon(domain
, dcname
, &ss
, request_flags
)
1486 && add_one_dc_unique(mem_ctx
, domain
->name
, dcname
, &ss
, dcs
,
1489 char addr
[INET6_ADDRSTRLEN
];
1490 print_sockaddr(addr
, sizeof(addr
), &ss
);
1491 DEBUG(10, ("Retrieved DC %s at %s via netlogon\n",
1496 if ((sec
== SEC_ADS
) && (domain
->alt_name
!= NULL
)) {
1497 char *sitename
= NULL
;
1499 /* We need to make sure we know the local site before
1500 doing any DNS queries, as this will restrict the
1501 get_sorted_dc_list() call below to only fetching
1502 DNS records for the correct site. */
1504 /* Find any DC to get the site record.
1505 We deliberately don't care about the
1508 get_dc_name(domain
->name
, domain
->alt_name
, dcname
, &ss
);
1510 sitename
= sitename_fetch(mem_ctx
, domain
->alt_name
);
1513 /* Do the site-specific AD dns lookup first. */
1514 get_sorted_dc_list(domain
->alt_name
, sitename
, &ip_list
,
1515 &iplist_size
, True
);
1517 /* Add ips to the DC array. We don't look up the name
1518 of the DC in this function, but we fill in the char*
1519 of the ip now to make the failed connection cache
1521 for ( i
=0; i
<iplist_size
; i
++ ) {
1522 char addr
[INET6_ADDRSTRLEN
];
1523 print_sockaddr(addr
, sizeof(addr
),
1525 add_one_dc_unique(mem_ctx
,
1534 TALLOC_FREE(sitename
);
1538 /* Now we add DCs from the main AD DNS lookup. */
1539 get_sorted_dc_list(domain
->alt_name
, NULL
, &ip_list
,
1540 &iplist_size
, True
);
1542 for ( i
=0; i
<iplist_size
; i
++ ) {
1543 char addr
[INET6_ADDRSTRLEN
];
1544 print_sockaddr(addr
, sizeof(addr
),
1546 add_one_dc_unique(mem_ctx
,
1558 /* Try standard netbios queries if no ADS and fall back to DNS queries
1559 * if alt_name is available */
1560 if (*num_dcs
== 0) {
1561 get_sorted_dc_list(domain
->name
, NULL
, &ip_list
, &iplist_size
,
1563 if (iplist_size
== 0) {
1564 if (domain
->alt_name
!= NULL
) {
1565 get_sorted_dc_list(domain
->alt_name
, NULL
, &ip_list
,
1566 &iplist_size
, true);
1570 for ( i
=0; i
<iplist_size
; i
++ ) {
1571 char addr
[INET6_ADDRSTRLEN
];
1572 print_sockaddr(addr
, sizeof(addr
),
1574 add_one_dc_unique(mem_ctx
,
1589 /*******************************************************************
1590 Find and make a connection to a DC in the given domain.
1592 @param[in] mem_ctx talloc memory context to allocate from
1593 @param[in] domain domain to find a dc in
1594 @param[out] dcname NetBIOS or FQDN of DC that's connected to
1595 @param[out] pss DC Internet address and port
1596 @param[out] fd fd of the open socket connected to the newly found dc
1597 @return true when a DC connection is made, false otherwise
1598 *******************************************************************/
1600 static bool find_new_dc(TALLOC_CTX
*mem_ctx
,
1601 struct winbindd_domain
*domain
,
1602 char **dcname
, struct sockaddr_storage
*pss
, int *fd
,
1603 uint32_t request_flags
)
1605 struct dc_name_ip
*dcs
= NULL
;
1608 const char **dcnames
= NULL
;
1609 size_t num_dcnames
= 0;
1611 struct sockaddr_storage
*addrs
= NULL
;
1622 if (!get_dcs(mem_ctx
, domain
, &dcs
, &num_dcs
, request_flags
) || (num_dcs
== 0))
1625 for (i
=0; i
<num_dcs
; i
++) {
1627 if (!add_string_to_array(mem_ctx
, dcs
[i
].name
,
1628 &dcnames
, &num_dcnames
)) {
1631 if (!add_sockaddr_to_array(mem_ctx
, &dcs
[i
].ss
, TCP_SMB_PORT
,
1632 &addrs
, &num_addrs
)) {
1637 if ((num_dcnames
== 0) || (num_dcnames
!= num_addrs
))
1640 if ((addrs
== NULL
) || (dcnames
== NULL
))
1643 status
= smbsock_any_connect(addrs
, dcnames
, NULL
, NULL
, NULL
,
1644 num_addrs
, 0, 10, fd
, &fd_index
, NULL
);
1645 if (!NT_STATUS_IS_OK(status
)) {
1646 for (i
=0; i
<num_dcs
; i
++) {
1647 char ab
[INET6_ADDRSTRLEN
];
1648 print_sockaddr(ab
, sizeof(ab
), &dcs
[i
].ss
);
1649 DEBUG(10, ("find_new_dc: smbsock_any_connect failed for "
1650 "domain %s address %s. Error was %s\n",
1651 domain
->name
, ab
, nt_errstr(status
) ));
1652 winbind_add_failed_connection_entry(domain
,
1653 dcs
[i
].name
, NT_STATUS_UNSUCCESSFUL
);
1658 *pss
= addrs
[fd_index
];
1660 if (*dcnames
[fd_index
] != '\0' && !is_ipaddress(dcnames
[fd_index
])) {
1661 /* Ok, we've got a name for the DC */
1662 *dcname
= talloc_strdup(mem_ctx
, dcnames
[fd_index
]);
1663 if (*dcname
== NULL
) {
1669 /* Try to figure out the name */
1670 if (dcip_check_name(mem_ctx
, domain
, pss
, dcname
, request_flags
)) {
1674 /* We can not continue without the DC's name */
1675 winbind_add_failed_connection_entry(domain
, dcs
[fd_index
].name
,
1676 NT_STATUS_UNSUCCESSFUL
);
1678 /* Throw away all arrays as we're doing this again. */
1682 TALLOC_FREE(dcnames
);
1694 static char *current_dc_key(TALLOC_CTX
*mem_ctx
, const char *domain_name
)
1696 return talloc_asprintf_strupper_m(mem_ctx
, "CURRENT_DCNAME/%s",
1700 static void store_current_dc_in_gencache(const char *domain_name
,
1701 const char *dc_name
,
1702 struct cli_state
*cli
)
1704 char addr
[INET6_ADDRSTRLEN
];
1708 if (!cli_state_is_connected(cli
)) {
1712 print_sockaddr(addr
, sizeof(addr
),
1713 smbXcli_conn_remote_sockaddr(cli
->conn
));
1715 key
= current_dc_key(talloc_tos(), domain_name
);
1720 value
= talloc_asprintf(talloc_tos(), "%s %s", addr
, dc_name
);
1721 if (value
== NULL
) {
1725 gencache_set(key
, value
, 0x7fffffff);
1731 bool fetch_current_dc_from_gencache(TALLOC_CTX
*mem_ctx
,
1732 const char *domain_name
,
1733 char **p_dc_name
, char **p_dc_ip
)
1738 char *dc_name
= NULL
;
1741 key
= current_dc_key(talloc_tos(), domain_name
);
1745 if (!gencache_get(key
, mem_ctx
, &value
, NULL
)) {
1748 p
= strchr(value
, ' ');
1752 dc_ip
= talloc_strndup(mem_ctx
, value
, p
- value
);
1753 if (dc_ip
== NULL
) {
1756 dc_name
= talloc_strdup(mem_ctx
, p
+1);
1757 if (dc_name
== NULL
) {
1761 if (p_dc_ip
!= NULL
) {
1765 if (p_dc_name
!= NULL
) {
1766 *p_dc_name
= dc_name
;
1771 TALLOC_FREE(dc_name
);
1778 NTSTATUS
wb_open_internal_pipe(TALLOC_CTX
*mem_ctx
,
1779 const struct ndr_interface_table
*table
,
1780 struct rpc_pipe_client
**ret_pipe
)
1782 struct rpc_pipe_client
*cli
= NULL
;
1783 const struct auth_session_info
*session_info
;
1784 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
1787 session_info
= get_session_info_system();
1788 SMB_ASSERT(session_info
!= NULL
);
1790 /* create a connection to the specified pipe */
1791 if (lp_parm_bool(-1, "winbindd", "use external pipes", false)) {
1792 status
= rpc_pipe_open_interface(mem_ctx
,
1797 server_messaging_context(),
1800 status
= rpc_pipe_open_internal(mem_ctx
,
1805 server_messaging_context(),
1808 if (!NT_STATUS_IS_OK(status
)) {
1809 DEBUG(0, ("open_internal_pipe: Could not connect to %s pipe: %s\n",
1810 table
->name
, nt_errstr(status
)));
1818 return NT_STATUS_OK
;
1821 static NTSTATUS
cm_open_connection(struct winbindd_domain
*domain
,
1822 struct winbindd_cm_conn
*new_conn
,
1825 TALLOC_CTX
*mem_ctx
;
1827 char *saf_servername
;
1829 uint32_t request_flags
= need_rw_dc
? DS_WRITABLE_REQUIRED
: 0;
1831 if ((mem_ctx
= talloc_init("cm_open_connection")) == NULL
) {
1832 set_domain_offline(domain
);
1833 return NT_STATUS_NO_MEMORY
;
1836 saf_servername
= saf_fetch(mem_ctx
, domain
->name
);
1838 /* we have to check the server affinity cache here since
1839 later we select a DC based on response time and not preference */
1841 /* Check the negative connection cache
1842 before talking to it. It going down may have
1843 triggered the reconnection. */
1845 if (saf_servername
&& NT_STATUS_IS_OK(check_negative_conn_cache(domain
->name
, saf_servername
))) {
1846 struct sockaddr_storage ss
;
1847 char *dcname
= NULL
;
1848 bool resolved
= true;
1850 DEBUG(10, ("cm_open_connection: saf_servername is '%s' for domain %s\n",
1851 saf_servername
, domain
->name
));
1853 /* convert an ip address to a name */
1854 if (is_ipaddress(saf_servername
)) {
1855 if (!interpret_string_addr(&ss
, saf_servername
,
1857 TALLOC_FREE(mem_ctx
);
1858 return NT_STATUS_UNSUCCESSFUL
;
1861 if (!resolve_name(saf_servername
, &ss
, 0x20, true)) {
1866 if (resolved
&& dcip_check_name(mem_ctx
, domain
, &ss
, &dcname
, request_flags
)) {
1867 domain
->dcname
= talloc_strdup(domain
,
1869 if (domain
->dcname
== NULL
) {
1870 TALLOC_FREE(mem_ctx
);
1871 return NT_STATUS_NO_MEMORY
;
1874 domain
->dcaddr
= ss
;
1876 winbind_add_failed_connection_entry(domain
, saf_servername
,
1877 NT_STATUS_UNSUCCESSFUL
);
1881 for (retries
= 0; retries
< 3; retries
++) {
1884 char *dcname
= NULL
;
1886 result
= NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND
;
1888 DEBUG(10, ("cm_open_connection: dcname is '%s' for domain %s\n",
1889 domain
->dcname
? domain
->dcname
: "", domain
->name
));
1891 if (domain
->dcname
!= NULL
&&
1892 NT_STATUS_IS_OK(check_negative_conn_cache(domain
->name
,
1897 status
= smbsock_connect(&domain
->dcaddr
, 0,
1900 if (!NT_STATUS_IS_OK(status
)) {
1906 !find_new_dc(mem_ctx
, domain
, &dcname
, &domain
->dcaddr
, &fd
, request_flags
))
1908 /* This is the one place where we will
1909 set the global winbindd offline state
1910 to true, if a "WINBINDD_OFFLINE" entry
1911 is found in the winbindd cache. */
1912 set_global_winbindd_state_offline();
1915 if (dcname
!= NULL
) {
1916 talloc_free(domain
->dcname
);
1918 domain
->dcname
= talloc_move(domain
, &dcname
);
1919 if (domain
->dcname
== NULL
) {
1920 result
= NT_STATUS_NO_MEMORY
;
1925 new_conn
->cli
= NULL
;
1927 result
= cm_prepare_connection(domain
, fd
, domain
->dcname
,
1928 &new_conn
->cli
, &retry
);
1929 if (!NT_STATUS_IS_OK(result
)) {
1930 /* Don't leak the smb connection socket */
1938 if (NT_STATUS_IS_OK(result
)) {
1939 bool seal_pipes
= true;
1941 winbindd_set_locator_kdc_envs(domain
);
1943 if (domain
->online
== False
) {
1944 /* We're changing state from offline to online. */
1945 set_global_winbindd_state_online();
1947 set_domain_online(domain
);
1950 * Much as I hate global state, this seems to be the point
1951 * where we can be certain that we have a proper connection to
1952 * a DC. wbinfo --dc-info needs that information, store it in
1953 * gencache with a looong timeout. This will need revisiting
1954 * once we start to connect to multiple DCs, wbcDcInfo is
1955 * already prepared for that.
1957 store_current_dc_in_gencache(domain
->name
, domain
->dcname
,
1960 seal_pipes
= lp_winbind_sealed_pipes();
1961 seal_pipes
= lp_parm_bool(-1, "winbind sealed pipes",
1966 new_conn
->auth_level
= DCERPC_AUTH_LEVEL_PRIVACY
;
1968 new_conn
->auth_level
= DCERPC_AUTH_LEVEL_INTEGRITY
;
1971 /* Ensure we setup the retry handler. */
1972 set_domain_offline(domain
);
1975 talloc_destroy(mem_ctx
);
1979 /* Close down all open pipes on a connection. */
1981 void invalidate_cm_connection(struct winbindd_domain
*domain
)
1984 struct winbindd_cm_conn
*conn
= &domain
->conn
;
1986 /* We're closing down a possibly dead
1987 connection. Don't have impossibly long (10s) timeouts. */
1990 cli_set_timeout(conn
->cli
, 1000); /* 1 second. */
1993 if (conn
->samr_pipe
!= NULL
) {
1994 if (is_valid_policy_hnd(&conn
->sam_connect_handle
)) {
1995 dcerpc_samr_Close(conn
->samr_pipe
->binding_handle
,
1997 &conn
->sam_connect_handle
,
2000 TALLOC_FREE(conn
->samr_pipe
);
2001 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
2003 cli_set_timeout(conn
->cli
, 500);
2007 if (conn
->lsa_pipe
!= NULL
) {
2008 if (is_valid_policy_hnd(&conn
->lsa_policy
)) {
2009 dcerpc_lsa_Close(conn
->lsa_pipe
->binding_handle
,
2014 TALLOC_FREE(conn
->lsa_pipe
);
2015 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
2017 cli_set_timeout(conn
->cli
, 500);
2021 if (conn
->lsa_pipe_tcp
!= NULL
) {
2022 if (is_valid_policy_hnd(&conn
->lsa_policy
)) {
2023 dcerpc_lsa_Close(conn
->lsa_pipe_tcp
->binding_handle
,
2028 TALLOC_FREE(conn
->lsa_pipe_tcp
);
2029 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
2031 cli_set_timeout(conn
->cli
, 500);
2035 if (conn
->netlogon_pipe
!= NULL
) {
2036 TALLOC_FREE(conn
->netlogon_pipe
);
2037 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
2039 cli_set_timeout(conn
->cli
, 500);
2043 conn
->auth_level
= DCERPC_AUTH_LEVEL_PRIVACY
;
2044 conn
->netlogon_force_reauth
= false;
2045 TALLOC_FREE(conn
->netlogon_creds_ctx
);
2048 cli_shutdown(conn
->cli
);
2054 void close_conns_after_fork(void)
2056 struct winbindd_domain
*domain
;
2057 struct winbindd_cli_state
*cli_state
;
2059 for (domain
= domain_list(); domain
; domain
= domain
->next
) {
2061 * first close the low level SMB TCP connection
2062 * so that we don't generate any SMBclose
2063 * requests in invalidate_cm_connection()
2065 if (cli_state_is_connected(domain
->conn
.cli
)) {
2066 smbXcli_conn_disconnect(domain
->conn
.cli
->conn
, NT_STATUS_OK
);
2069 invalidate_cm_connection(domain
);
2072 for (cli_state
= winbindd_client_list();
2074 cli_state
= cli_state
->next
) {
2075 if (cli_state
->sock
>= 0) {
2076 close(cli_state
->sock
);
2077 cli_state
->sock
= -1;
2082 static bool connection_ok(struct winbindd_domain
*domain
)
2086 ok
= cli_state_is_connected(domain
->conn
.cli
);
2088 DEBUG(3, ("connection_ok: Connection to %s for domain %s is not connected\n",
2089 domain
->dcname
, domain
->name
));
2093 if (domain
->online
== False
) {
2094 DEBUG(3, ("connection_ok: Domain %s is offline\n", domain
->name
));
2101 /* Initialize a new connection up to the RPC BIND.
2102 Bypass online status check so always does network calls. */
2104 static NTSTATUS
init_dc_connection_network(struct winbindd_domain
*domain
, bool need_rw_dc
)
2107 bool skip_connection
= domain
->internal
;
2108 if (need_rw_dc
&& domain
->rodc
) {
2109 skip_connection
= false;
2112 /* Internal connections never use the network. */
2113 if (dom_sid_equal(&domain
->sid
, &global_sid_Builtin
)) {
2114 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
2117 /* Still ask the internal LSA and SAMR server about the local domain */
2118 if (skip_connection
|| connection_ok(domain
)) {
2119 if (!domain
->initialized
) {
2120 set_dc_type_and_flags(domain
);
2122 return NT_STATUS_OK
;
2125 invalidate_cm_connection(domain
);
2127 if (!domain
->primary
&& !domain
->initialized
) {
2129 * Before we connect to a trust, work out if it is an
2130 * AD domain by asking our own domain.
2132 set_dc_type_and_flags_trustinfo(domain
);
2135 result
= cm_open_connection(domain
, &domain
->conn
, need_rw_dc
);
2137 if (NT_STATUS_IS_OK(result
) && !domain
->initialized
) {
2138 set_dc_type_and_flags(domain
);
2144 NTSTATUS
init_dc_connection(struct winbindd_domain
*domain
, bool need_rw_dc
)
2146 if (dom_sid_equal(&domain
->sid
, &global_sid_Builtin
)) {
2147 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
2150 if (domain
->initialized
&& !domain
->online
) {
2151 /* We check for online status elsewhere. */
2152 return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND
;
2155 return init_dc_connection_network(domain
, need_rw_dc
);
2158 static NTSTATUS
init_dc_connection_rpc(struct winbindd_domain
*domain
, bool need_rw_dc
)
2162 status
= init_dc_connection(domain
, need_rw_dc
);
2163 if (!NT_STATUS_IS_OK(status
)) {
2167 if (!domain
->internal
&& domain
->conn
.cli
== NULL
) {
2168 /* happens for trusted domains without inbound trust */
2169 return NT_STATUS_TRUSTED_DOMAIN_FAILURE
;
2172 return NT_STATUS_OK
;
2175 /******************************************************************************
2176 Set the trust flags (direction and forest location) for a domain
2177 ******************************************************************************/
2179 static bool set_dc_type_and_flags_trustinfo( struct winbindd_domain
*domain
)
2181 struct winbindd_domain
*our_domain
;
2182 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
2184 struct netr_DomainTrustList trusts
;
2186 uint32_t flags
= (NETR_TRUST_FLAG_IN_FOREST
|
2187 NETR_TRUST_FLAG_OUTBOUND
|
2188 NETR_TRUST_FLAG_INBOUND
);
2189 struct rpc_pipe_client
*cli
;
2190 TALLOC_CTX
*mem_ctx
= NULL
;
2191 struct dcerpc_binding_handle
*b
;
2193 DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s\n", domain
->name
));
2195 /* Our primary domain doesn't need to worry about trust flags.
2196 Force it to go through the network setup */
2197 if ( domain
->primary
) {
2201 mem_ctx
= talloc_stackframe();
2202 our_domain
= find_our_domain();
2203 if (our_domain
->internal
) {
2204 result
= init_dc_connection(our_domain
, false);
2205 if (!NT_STATUS_IS_OK(result
)) {
2206 DEBUG(3,("set_dc_type_and_flags_trustinfo: "
2207 "Not able to make a connection to our domain: %s\n",
2208 nt_errstr(result
)));
2209 TALLOC_FREE(mem_ctx
);
2214 /* This won't work unless our domain is AD */
2215 if ( !our_domain
->active_directory
) {
2216 TALLOC_FREE(mem_ctx
);
2220 if (our_domain
->internal
) {
2221 result
= wb_open_internal_pipe(mem_ctx
, &ndr_table_netlogon
, &cli
);
2222 } else if (!connection_ok(our_domain
)) {
2223 DEBUG(3,("set_dc_type_and_flags_trustinfo: "
2224 "No connection to our domain!\n"));
2225 TALLOC_FREE(mem_ctx
);
2228 result
= cm_connect_netlogon(our_domain
, &cli
);
2231 if (!NT_STATUS_IS_OK(result
)) {
2232 DEBUG(5, ("set_dc_type_and_flags_trustinfo: Could not open "
2233 "a connection to %s for PIPE_NETLOGON (%s)\n",
2234 domain
->name
, nt_errstr(result
)));
2235 TALLOC_FREE(mem_ctx
);
2238 b
= cli
->binding_handle
;
2240 /* Use DsEnumerateDomainTrusts to get us the trust direction and type. */
2241 result
= dcerpc_netr_DsrEnumerateDomainTrusts(b
, mem_ctx
,
2246 if (!NT_STATUS_IS_OK(result
)) {
2247 DEBUG(0,("set_dc_type_and_flags_trustinfo: "
2248 "failed to query trusted domain list: %s\n",
2249 nt_errstr(result
)));
2250 TALLOC_FREE(mem_ctx
);
2253 if (!W_ERROR_IS_OK(werr
)) {
2254 DEBUG(0,("set_dc_type_and_flags_trustinfo: "
2255 "failed to query trusted domain list: %s\n",
2257 TALLOC_FREE(mem_ctx
);
2261 /* Now find the domain name and get the flags */
2263 for ( i
=0; i
<trusts
.count
; i
++ ) {
2264 if ( strequal( domain
->name
, trusts
.array
[i
].netbios_name
) ) {
2265 domain
->domain_flags
= trusts
.array
[i
].trust_flags
;
2266 domain
->domain_type
= trusts
.array
[i
].trust_type
;
2267 domain
->domain_trust_attribs
= trusts
.array
[i
].trust_attributes
;
2269 if ( domain
->domain_type
== LSA_TRUST_TYPE_UPLEVEL
)
2270 domain
->active_directory
= True
;
2272 /* This flag is only set if the domain is *our*
2273 primary domain and the primary domain is in
2276 domain
->native_mode
= (domain
->domain_flags
& NETR_TRUST_FLAG_NATIVE
);
2278 DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s is %sin "
2279 "native mode.\n", domain
->name
,
2280 domain
->native_mode
? "" : "NOT "));
2282 DEBUG(5,("set_dc_type_and_flags_trustinfo: domain %s is %s"
2283 "running active directory.\n", domain
->name
,
2284 domain
->active_directory
? "" : "NOT "));
2286 domain
->can_do_ncacn_ip_tcp
= domain
->active_directory
;
2288 domain
->initialized
= True
;
2294 TALLOC_FREE(mem_ctx
);
2296 return domain
->initialized
;
2299 /******************************************************************************
2300 We can 'sense' certain things about the DC by it's replies to certain
2303 This tells us if this particular remote server is Active Directory, and if it
2305 ******************************************************************************/
2307 static void set_dc_type_and_flags_connect( struct winbindd_domain
*domain
)
2309 NTSTATUS status
, result
;
2311 TALLOC_CTX
*mem_ctx
= NULL
;
2312 struct rpc_pipe_client
*cli
= NULL
;
2313 struct policy_handle pol
;
2314 union dssetup_DsRoleInfo info
;
2315 union lsa_PolicyInformation
*lsa_info
= NULL
;
2317 if (!domain
->internal
&& !connection_ok(domain
)) {
2321 mem_ctx
= talloc_init("set_dc_type_and_flags on domain %s\n",
2324 DEBUG(1, ("set_dc_type_and_flags_connect: talloc_init() failed\n"));
2328 DEBUG(5, ("set_dc_type_and_flags_connect: domain %s\n", domain
->name
));
2330 if (domain
->internal
) {
2331 status
= wb_open_internal_pipe(mem_ctx
,
2335 status
= cli_rpc_pipe_open_noauth(domain
->conn
.cli
,
2340 if (!NT_STATUS_IS_OK(status
)) {
2341 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
2342 "PI_DSSETUP on domain %s: (%s)\n",
2343 domain
->name
, nt_errstr(status
)));
2345 /* if this is just a non-AD domain we need to continue
2346 * identifying so that we can in the end return with
2347 * domain->initialized = True - gd */
2352 status
= dcerpc_dssetup_DsRoleGetPrimaryDomainInformation(cli
->binding_handle
, mem_ctx
,
2353 DS_ROLE_BASIC_INFORMATION
,
2358 if (NT_STATUS_IS_OK(status
)) {
2359 result
= werror_to_ntstatus(werr
);
2361 if (!NT_STATUS_IS_OK(status
)) {
2362 DEBUG(5, ("set_dc_type_and_flags_connect: rpccli_ds_getprimarydominfo "
2363 "on domain %s failed: (%s)\n",
2364 domain
->name
, nt_errstr(status
)));
2366 /* older samba3 DCs will return DCERPC_FAULT_OP_RNG_ERROR for
2367 * every opcode on the DSSETUP pipe, continue with
2368 * no_dssetup mode here as well to get domain->initialized
2371 if (NT_STATUS_EQUAL(status
, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE
)) {
2375 TALLOC_FREE(mem_ctx
);
2379 if ((info
.basic
.flags
& DS_ROLE_PRIMARY_DS_RUNNING
) &&
2380 !(info
.basic
.flags
& DS_ROLE_PRIMARY_DS_MIXED_MODE
)) {
2381 domain
->native_mode
= True
;
2383 domain
->native_mode
= False
;
2387 if (domain
->internal
) {
2388 status
= wb_open_internal_pipe(mem_ctx
,
2392 status
= cli_rpc_pipe_open_noauth(domain
->conn
.cli
,
2393 &ndr_table_lsarpc
, &cli
);
2395 if (!NT_STATUS_IS_OK(status
)) {
2396 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
2397 "PI_LSARPC on domain %s: (%s)\n",
2398 domain
->name
, nt_errstr(status
)));
2400 TALLOC_FREE(mem_ctx
);
2404 status
= rpccli_lsa_open_policy2(cli
, mem_ctx
, True
,
2405 SEC_FLAG_MAXIMUM_ALLOWED
, &pol
);
2407 if (NT_STATUS_IS_OK(status
)) {
2408 /* This particular query is exactly what Win2k clients use
2409 to determine that the DC is active directory */
2410 status
= dcerpc_lsa_QueryInfoPolicy2(cli
->binding_handle
, mem_ctx
,
2412 LSA_POLICY_INFO_DNS
,
2417 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(result
)) {
2418 domain
->active_directory
= True
;
2420 if (lsa_info
->dns
.name
.string
) {
2421 if (!strequal(domain
->name
, lsa_info
->dns
.name
.string
))
2423 DEBUG(1, ("set_dc_type_and_flags_connect: DC "
2424 "for domain %s claimed it was a DC "
2425 "for domain %s, refusing to "
2428 lsa_info
->dns
.name
.string
));
2430 TALLOC_FREE(mem_ctx
);
2433 talloc_free(domain
->name
);
2434 domain
->name
= talloc_strdup(domain
,
2435 lsa_info
->dns
.name
.string
);
2436 if (domain
->name
== NULL
) {
2441 if (lsa_info
->dns
.dns_domain
.string
) {
2442 if (domain
->alt_name
!= NULL
&&
2443 !strequal(domain
->alt_name
,
2444 lsa_info
->dns
.dns_domain
.string
))
2446 DEBUG(1, ("set_dc_type_and_flags_connect: DC "
2447 "for domain %s (%s) claimed it was "
2448 "a DC for domain %s, refusing to "
2450 domain
->alt_name
, domain
->name
,
2451 lsa_info
->dns
.dns_domain
.string
));
2453 TALLOC_FREE(mem_ctx
);
2456 talloc_free(domain
->alt_name
);
2458 talloc_strdup(domain
,
2459 lsa_info
->dns
.dns_domain
.string
);
2460 if (domain
->alt_name
== NULL
) {
2465 /* See if we can set some domain trust flags about
2468 if (lsa_info
->dns
.dns_forest
.string
) {
2469 talloc_free(domain
->forest_name
);
2470 domain
->forest_name
=
2471 talloc_strdup(domain
,
2472 lsa_info
->dns
.dns_forest
.string
);
2473 if (domain
->forest_name
== NULL
) {
2477 if (strequal(domain
->forest_name
, domain
->alt_name
)) {
2478 domain
->domain_flags
|= NETR_TRUST_FLAG_TREEROOT
;
2482 if (lsa_info
->dns
.sid
) {
2483 if (!is_null_sid(&domain
->sid
) &&
2484 !dom_sid_equal(&domain
->sid
,
2487 DEBUG(1, ("set_dc_type_and_flags_connect: DC "
2488 "for domain %s (%s) claimed it was "
2489 "a DC for domain %s, refusing to "
2491 dom_sid_string(talloc_tos(),
2494 dom_sid_string(talloc_tos(),
2495 lsa_info
->dns
.sid
)));
2497 TALLOC_FREE(mem_ctx
);
2500 sid_copy(&domain
->sid
, lsa_info
->dns
.sid
);
2503 domain
->active_directory
= False
;
2505 status
= rpccli_lsa_open_policy(cli
, mem_ctx
, True
,
2506 SEC_FLAG_MAXIMUM_ALLOWED
,
2509 if (!NT_STATUS_IS_OK(status
)) {
2513 status
= dcerpc_lsa_QueryInfoPolicy(cli
->binding_handle
, mem_ctx
,
2515 LSA_POLICY_INFO_ACCOUNT_DOMAIN
,
2518 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(result
)) {
2520 if (lsa_info
->account_domain
.name
.string
) {
2521 if (!strequal(domain
->name
,
2522 lsa_info
->account_domain
.name
.string
))
2525 ("set_dc_type_and_flags_connect: "
2526 "DC for domain %s claimed it was"
2527 " a DC for domain %s, refusing "
2528 "to initialize\n", domain
->name
,
2530 account_domain
.name
.string
));
2532 TALLOC_FREE(mem_ctx
);
2535 talloc_free(domain
->name
);
2537 talloc_strdup(domain
,
2538 lsa_info
->account_domain
.name
.string
);
2541 if (lsa_info
->account_domain
.sid
) {
2542 if (!is_null_sid(&domain
->sid
) &&
2543 !dom_sid_equal(&domain
->sid
,
2544 lsa_info
->account_domain
.sid
))
2547 ("set_dc_type_and_flags_connect: "
2548 "DC for domain %s (%s) claimed "
2549 "it was a DC for domain %s, "
2550 "refusing to initialize\n",
2551 dom_sid_string(talloc_tos(),
2554 dom_sid_string(talloc_tos(),
2555 lsa_info
->account_domain
.sid
)));
2557 TALLOC_FREE(mem_ctx
);
2560 sid_copy(&domain
->sid
, lsa_info
->account_domain
.sid
);
2566 DEBUG(5, ("set_dc_type_and_flags_connect: domain %s is %sin native mode.\n",
2567 domain
->name
, domain
->native_mode
? "" : "NOT "));
2569 DEBUG(5,("set_dc_type_and_flags_connect: domain %s is %srunning active directory.\n",
2570 domain
->name
, domain
->active_directory
? "" : "NOT "));
2572 domain
->can_do_ncacn_ip_tcp
= domain
->active_directory
;
2576 TALLOC_FREE(mem_ctx
);
2578 domain
->initialized
= True
;
2581 /**********************************************************************
2582 Set the domain_flags (trust attributes, domain operating modes, etc...
2583 ***********************************************************************/
2585 static void set_dc_type_and_flags( struct winbindd_domain
*domain
)
2587 /* we always have to contact our primary domain */
2589 if ( domain
->primary
|| domain
->internal
) {
2590 DEBUG(10,("set_dc_type_and_flags: setting up flags for "
2591 "primary or internal domain\n"));
2592 set_dc_type_and_flags_connect( domain
);
2596 /* Use our DC to get the information if possible */
2598 if ( !set_dc_type_and_flags_trustinfo( domain
) ) {
2599 /* Otherwise, fallback to contacting the
2601 set_dc_type_and_flags_connect( domain
);
2609 /**********************************************************************
2610 ***********************************************************************/
2612 static NTSTATUS
cm_get_schannel_creds(struct winbindd_domain
*domain
,
2613 struct netlogon_creds_cli_context
**ppdc
)
2615 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
2616 struct rpc_pipe_client
*netlogon_pipe
;
2620 if ((!IS_DC
) && (!domain
->primary
)) {
2621 return NT_STATUS_TRUSTED_DOMAIN_FAILURE
;
2624 if (domain
->conn
.netlogon_creds_ctx
!= NULL
) {
2625 *ppdc
= domain
->conn
.netlogon_creds_ctx
;
2626 return NT_STATUS_OK
;
2629 result
= cm_connect_netlogon_secure(domain
, &netlogon_pipe
, ppdc
);
2630 if (!NT_STATUS_IS_OK(result
)) {
2634 return NT_STATUS_OK
;
2637 NTSTATUS
cm_connect_sam(struct winbindd_domain
*domain
, TALLOC_CTX
*mem_ctx
,
2639 struct rpc_pipe_client
**cli
, struct policy_handle
*sam_handle
)
2641 struct winbindd_cm_conn
*conn
;
2642 NTSTATUS status
, result
;
2643 struct netlogon_creds_cli_context
*p_creds
;
2644 struct cli_credentials
*creds
= NULL
;
2645 bool retry
= false; /* allow one retry attempt for expired session */
2647 if (sid_check_is_our_sam(&domain
->sid
)) {
2648 if (domain
->rodc
== false || need_rw_dc
== false) {
2649 return open_internal_samr_conn(mem_ctx
, domain
, cli
, sam_handle
);
2654 status
= init_dc_connection_rpc(domain
, need_rw_dc
);
2655 if (!NT_STATUS_IS_OK(status
)) {
2659 conn
= &domain
->conn
;
2661 if (rpccli_is_connected(conn
->samr_pipe
)) {
2665 TALLOC_FREE(conn
->samr_pipe
);
2668 * No SAMR pipe yet. Attempt to get an NTLMSSP SPNEGO authenticated
2669 * sign and sealed pipe using the machine account password by
2670 * preference. If we can't - try schannel, if that fails, try
2674 result
= get_trust_credentials(domain
, talloc_tos(), false, &creds
);
2675 if (!NT_STATUS_IS_OK(result
)) {
2676 DEBUG(10, ("cm_connect_sam: No user available for "
2677 "domain %s, trying schannel\n", domain
->name
));
2681 if (cli_credentials_is_anonymous(creds
)) {
2686 * We have an authenticated connection. Use a SPNEGO
2687 * authenticated SAMR pipe with sign & seal.
2689 status
= cli_rpc_pipe_open_with_creds(conn
->cli
,
2692 DCERPC_AUTH_TYPE_SPNEGO
,
2694 smbXcli_conn_remote_name(conn
->cli
->conn
),
2698 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)
2700 invalidate_cm_connection(domain
);
2705 if (!NT_STATUS_IS_OK(status
)) {
2706 DEBUG(10,("cm_connect_sam: failed to connect to SAMR "
2707 "pipe for domain %s using NTLMSSP "
2708 "authenticated pipe: user %s. Error was "
2709 "%s\n", domain
->name
,
2710 cli_credentials_get_unparsed_name(creds
, talloc_tos()),
2711 nt_errstr(status
)));
2715 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for "
2716 "domain %s using NTLMSSP authenticated "
2717 "pipe: user %s\n", domain
->name
,
2718 cli_credentials_get_unparsed_name(creds
, talloc_tos())));
2720 status
= dcerpc_samr_Connect2(conn
->samr_pipe
->binding_handle
, mem_ctx
,
2721 conn
->samr_pipe
->desthost
,
2722 SEC_FLAG_MAXIMUM_ALLOWED
,
2723 &conn
->sam_connect_handle
,
2726 if (NT_STATUS_EQUAL(status
, NT_STATUS_IO_DEVICE_ERROR
) && !retry
) {
2727 invalidate_cm_connection(domain
);
2728 TALLOC_FREE(conn
->samr_pipe
);
2733 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(result
)) {
2736 if (NT_STATUS_IS_OK(status
)) {
2740 DEBUG(10,("cm_connect_sam: ntlmssp-sealed dcerpc_samr_Connect2 "
2741 "failed for domain %s, error was %s. Trying schannel\n",
2742 domain
->name
, nt_errstr(status
) ));
2743 TALLOC_FREE(conn
->samr_pipe
);
2747 /* Fall back to schannel if it's a W2K pre-SP1 box. */
2749 status
= cm_get_schannel_creds(domain
, &p_creds
);
2750 if (!NT_STATUS_IS_OK(status
)) {
2751 /* If this call fails - conn->cli can now be NULL ! */
2752 DEBUG(10, ("cm_connect_sam: Could not get schannel auth info "
2753 "for domain %s (error %s), trying anon\n",
2755 nt_errstr(status
) ));
2759 status
= cli_rpc_pipe_open_schannel_with_creds(
2760 conn
->cli
, &ndr_table_samr
, NCACN_NP
, p_creds
,
2763 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)
2765 invalidate_cm_connection(domain
);
2770 if (!NT_STATUS_IS_OK(status
)) {
2771 DEBUG(10,("cm_connect_sam: failed to connect to SAMR pipe for "
2772 "domain %s using schannel. Error was %s\n",
2773 domain
->name
, nt_errstr(status
) ));
2776 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for domain %s using "
2777 "schannel.\n", domain
->name
));
2779 status
= dcerpc_samr_Connect2(conn
->samr_pipe
->binding_handle
, mem_ctx
,
2780 conn
->samr_pipe
->desthost
,
2781 SEC_FLAG_MAXIMUM_ALLOWED
,
2782 &conn
->sam_connect_handle
,
2785 if (NT_STATUS_EQUAL(status
, NT_STATUS_IO_DEVICE_ERROR
) && !retry
) {
2786 invalidate_cm_connection(domain
);
2787 TALLOC_FREE(conn
->samr_pipe
);
2792 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(result
)) {
2795 if (NT_STATUS_IS_OK(status
)) {
2798 DEBUG(10,("cm_connect_sam: schannel-sealed dcerpc_samr_Connect2 failed "
2799 "for domain %s, error was %s. Trying anonymous\n",
2800 domain
->name
, nt_errstr(status
) ));
2801 TALLOC_FREE(conn
->samr_pipe
);
2805 /* Finally fall back to anonymous. */
2806 if (lp_winbind_sealed_pipes() || lp_require_strong_key()) {
2807 status
= NT_STATUS_DOWNGRADE_DETECTED
;
2808 DEBUG(1, ("Unwilling to make SAMR connection to domain %s "
2809 "without connection level security, "
2810 "must set 'winbind sealed pipes = false' and "
2811 "'require strong key = false' to proceed: %s\n",
2812 domain
->name
, nt_errstr(status
)));
2815 status
= cli_rpc_pipe_open_noauth(conn
->cli
, &ndr_table_samr
,
2818 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)
2820 invalidate_cm_connection(domain
);
2825 if (!NT_STATUS_IS_OK(status
)) {
2829 status
= dcerpc_samr_Connect2(conn
->samr_pipe
->binding_handle
, mem_ctx
,
2830 conn
->samr_pipe
->desthost
,
2831 SEC_FLAG_MAXIMUM_ALLOWED
,
2832 &conn
->sam_connect_handle
,
2835 if (NT_STATUS_EQUAL(status
, NT_STATUS_IO_DEVICE_ERROR
) && !retry
) {
2836 invalidate_cm_connection(domain
);
2837 TALLOC_FREE(conn
->samr_pipe
);
2842 if (!NT_STATUS_IS_OK(status
)) {
2843 DEBUG(10,("cm_connect_sam: rpccli_samr_Connect2 failed "
2844 "for domain %s Error was %s\n",
2845 domain
->name
, nt_errstr(status
) ));
2848 if (!NT_STATUS_IS_OK(result
)) {
2850 DEBUG(10,("cm_connect_sam: dcerpc_samr_Connect2 failed "
2851 "for domain %s Error was %s\n",
2852 domain
->name
, nt_errstr(result
)));
2857 status
= dcerpc_samr_OpenDomain(conn
->samr_pipe
->binding_handle
,
2859 &conn
->sam_connect_handle
,
2860 SEC_FLAG_MAXIMUM_ALLOWED
,
2862 &conn
->sam_domain_handle
,
2864 if (!NT_STATUS_IS_OK(status
)) {
2871 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
2873 * if we got access denied, we might just have no access rights
2874 * to talk to the remote samr server server (e.g. when we are a
2875 * PDC and we are connecting a w2k8 pdc via an interdomain
2876 * trust). In that case do not invalidate the whole connection
2879 TALLOC_FREE(conn
->samr_pipe
);
2880 ZERO_STRUCT(conn
->sam_domain_handle
);
2882 } else if (!NT_STATUS_IS_OK(status
)) {
2883 invalidate_cm_connection(domain
);
2887 *cli
= conn
->samr_pipe
;
2888 *sam_handle
= conn
->sam_domain_handle
;
2892 /**********************************************************************
2893 open an schanneld ncacn_ip_tcp connection to LSA
2894 ***********************************************************************/
2896 static NTSTATUS
cm_connect_lsa_tcp(struct winbindd_domain
*domain
,
2897 TALLOC_CTX
*mem_ctx
,
2898 struct rpc_pipe_client
**cli
)
2900 struct winbindd_cm_conn
*conn
;
2901 struct netlogon_creds_cli_context
*p_creds
= NULL
;
2904 DEBUG(10,("cm_connect_lsa_tcp\n"));
2906 status
= init_dc_connection_rpc(domain
, false);
2907 if (!NT_STATUS_IS_OK(status
)) {
2911 conn
= &domain
->conn
;
2914 * rpccli_is_connected handles more error cases
2916 if (rpccli_is_connected(conn
->lsa_pipe_tcp
) &&
2917 conn
->lsa_pipe_tcp
->transport
->transport
== NCACN_IP_TCP
&&
2918 conn
->lsa_pipe_tcp
->auth
->auth_level
>= DCERPC_AUTH_LEVEL_INTEGRITY
) {
2922 TALLOC_FREE(conn
->lsa_pipe_tcp
);
2924 status
= cm_get_schannel_creds(domain
, &p_creds
);
2925 if (!NT_STATUS_IS_OK(status
)) {
2929 status
= cli_rpc_pipe_open_schannel_with_creds(conn
->cli
,
2933 &conn
->lsa_pipe_tcp
);
2934 if (!NT_STATUS_IS_OK(status
)) {
2935 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key failed: %s\n",
2936 nt_errstr(status
)));
2941 if (!NT_STATUS_IS_OK(status
)) {
2942 TALLOC_FREE(conn
->lsa_pipe_tcp
);
2946 *cli
= conn
->lsa_pipe_tcp
;
2951 NTSTATUS
cm_connect_lsa(struct winbindd_domain
*domain
, TALLOC_CTX
*mem_ctx
,
2952 struct rpc_pipe_client
**cli
, struct policy_handle
*lsa_policy
)
2954 struct winbindd_cm_conn
*conn
;
2955 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
2956 struct netlogon_creds_cli_context
*p_creds
;
2957 struct cli_credentials
*creds
= NULL
;
2958 bool retry
= false; /* allow one retry attempt for expired session */
2961 result
= init_dc_connection_rpc(domain
, false);
2962 if (!NT_STATUS_IS_OK(result
))
2965 conn
= &domain
->conn
;
2967 if (rpccli_is_connected(conn
->lsa_pipe
)) {
2971 TALLOC_FREE(conn
->lsa_pipe
);
2975 * Make sure we only use schannel as AD DC.
2980 result
= get_trust_credentials(domain
, talloc_tos(), false, &creds
);
2981 if (!NT_STATUS_IS_OK(result
)) {
2982 DEBUG(10, ("cm_connect_lsa: No user available for "
2983 "domain %s, trying schannel\n", domain
->name
));
2987 if (cli_credentials_is_anonymous(creds
)) {
2992 * We have an authenticated connection. Use a SPNEGO
2993 * authenticated LSA pipe with sign & seal.
2995 result
= cli_rpc_pipe_open_with_creds
2996 (conn
->cli
, &ndr_table_lsarpc
, NCACN_NP
,
2997 DCERPC_AUTH_TYPE_SPNEGO
,
2999 smbXcli_conn_remote_name(conn
->cli
->conn
),
3003 if (NT_STATUS_EQUAL(result
, NT_STATUS_NETWORK_SESSION_EXPIRED
)
3005 invalidate_cm_connection(domain
);
3010 if (!NT_STATUS_IS_OK(result
)) {
3011 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
3012 "domain %s using NTLMSSP authenticated pipe: user "
3013 "%s. Error was %s. Trying schannel.\n",
3015 cli_credentials_get_unparsed_name(creds
, talloc_tos()),
3016 nt_errstr(result
)));
3020 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
3021 "NTLMSSP authenticated pipe: user %s\n",
3022 domain
->name
, cli_credentials_get_unparsed_name(creds
, talloc_tos())));
3024 result
= rpccli_lsa_open_policy(conn
->lsa_pipe
, mem_ctx
, True
,
3025 SEC_FLAG_MAXIMUM_ALLOWED
,
3027 if (NT_STATUS_EQUAL(result
, NT_STATUS_IO_DEVICE_ERROR
) && !retry
) {
3028 invalidate_cm_connection(domain
);
3029 TALLOC_FREE(conn
->lsa_pipe
);
3034 if (NT_STATUS_IS_OK(result
)) {
3038 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
3041 TALLOC_FREE(conn
->lsa_pipe
);
3045 /* Fall back to schannel if it's a W2K pre-SP1 box. */
3047 result
= cm_get_schannel_creds(domain
, &p_creds
);
3048 if (!NT_STATUS_IS_OK(result
)) {
3049 /* If this call fails - conn->cli can now be NULL ! */
3050 DEBUG(10, ("cm_connect_lsa: Could not get schannel auth info "
3051 "for domain %s (error %s), trying anon\n",
3053 nt_errstr(result
) ));
3058 result
= cli_rpc_pipe_open_schannel_with_creds(
3059 conn
->cli
, &ndr_table_lsarpc
, NCACN_NP
, p_creds
,
3062 if (NT_STATUS_EQUAL(result
, NT_STATUS_NETWORK_SESSION_EXPIRED
)
3064 invalidate_cm_connection(domain
);
3069 if (!NT_STATUS_IS_OK(result
)) {
3070 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
3071 "domain %s using schannel. Error was %s\n",
3072 domain
->name
, nt_errstr(result
) ));
3075 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
3076 "schannel.\n", domain
->name
));
3078 result
= rpccli_lsa_open_policy(conn
->lsa_pipe
, mem_ctx
, True
,
3079 SEC_FLAG_MAXIMUM_ALLOWED
,
3082 if (NT_STATUS_EQUAL(result
, NT_STATUS_IO_DEVICE_ERROR
) && !retry
) {
3083 invalidate_cm_connection(domain
);
3084 TALLOC_FREE(conn
->lsa_pipe
);
3089 if (NT_STATUS_IS_OK(result
)) {
3095 * Make sure we only use schannel as AD DC.
3100 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
3103 TALLOC_FREE(conn
->lsa_pipe
);
3109 * Make sure we only use schannel as AD DC.
3114 if (lp_winbind_sealed_pipes() || lp_require_strong_key()) {
3115 result
= NT_STATUS_DOWNGRADE_DETECTED
;
3116 DEBUG(1, ("Unwilling to make LSA connection to domain %s "
3117 "without connection level security, "
3118 "must set 'winbind sealed pipes = false' and "
3119 "'require strong key = false' to proceed: %s\n",
3120 domain
->name
, nt_errstr(result
)));
3124 result
= cli_rpc_pipe_open_noauth(conn
->cli
,
3128 if (NT_STATUS_EQUAL(result
, NT_STATUS_NETWORK_SESSION_EXPIRED
)
3130 invalidate_cm_connection(domain
);
3135 if (!NT_STATUS_IS_OK(result
)) {
3139 result
= rpccli_lsa_open_policy(conn
->lsa_pipe
, mem_ctx
, True
,
3140 SEC_FLAG_MAXIMUM_ALLOWED
,
3143 if (NT_STATUS_EQUAL(result
, NT_STATUS_IO_DEVICE_ERROR
) && !retry
) {
3144 invalidate_cm_connection(domain
);
3145 TALLOC_FREE(conn
->lsa_pipe
);
3151 if (!NT_STATUS_IS_OK(result
)) {
3152 invalidate_cm_connection(domain
);
3156 *cli
= conn
->lsa_pipe
;
3157 *lsa_policy
= conn
->lsa_policy
;
3161 /****************************************************************************
3162 Open a LSA connection to a DC, suiteable for LSA lookup calls.
3163 ****************************************************************************/
3165 NTSTATUS
cm_connect_lsat(struct winbindd_domain
*domain
,
3166 TALLOC_CTX
*mem_ctx
,
3167 struct rpc_pipe_client
**cli
,
3168 struct policy_handle
*lsa_policy
)
3172 if (domain
->can_do_ncacn_ip_tcp
) {
3173 status
= cm_connect_lsa_tcp(domain
, mem_ctx
, cli
);
3174 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
) ||
3175 NT_STATUS_EQUAL(status
, NT_STATUS_RPC_SEC_PKG_ERROR
) ||
3176 NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_ACCESS_DENIED
)) {
3177 invalidate_cm_connection(domain
);
3178 status
= cm_connect_lsa_tcp(domain
, mem_ctx
, cli
);
3180 if (NT_STATUS_IS_OK(status
)) {
3185 * we tried twice to connect via ncan_ip_tcp and schannel and
3186 * failed - maybe it is a trusted domain we can't connect to ?
3187 * do not try tcp next time - gd
3189 * This also prevents NETLOGON over TCP
3191 domain
->can_do_ncacn_ip_tcp
= false;
3194 status
= cm_connect_lsa(domain
, mem_ctx
, cli
, lsa_policy
);
3199 /****************************************************************************
3200 Open the netlogon pipe to this DC.
3201 ****************************************************************************/
3203 static NTSTATUS
cm_connect_netlogon_transport(struct winbindd_domain
*domain
,
3204 enum dcerpc_transport_t transport
,
3205 struct rpc_pipe_client
**cli
)
3207 struct messaging_context
*msg_ctx
= server_messaging_context();
3208 struct winbindd_cm_conn
*conn
;
3210 enum netr_SchannelType sec_chan_type
;
3211 struct cli_credentials
*creds
= NULL
;
3216 if (domain
->secure_channel_type
== SEC_CHAN_NULL
) {
3218 * Make sure we don't even try to
3219 * connect to a foreign domain
3220 * without a direct outbound trust.
3222 return NT_STATUS_NO_TRUST_LSA_SECRET
;
3226 result
= init_dc_connection_rpc(domain
, domain
->rodc
);
3227 if (!NT_STATUS_IS_OK(result
)) {
3231 conn
= &domain
->conn
;
3233 if (rpccli_is_connected(conn
->netlogon_pipe
)) {
3234 *cli
= conn
->netlogon_pipe
;
3235 return NT_STATUS_OK
;
3238 TALLOC_FREE(conn
->netlogon_pipe
);
3239 TALLOC_FREE(conn
->netlogon_creds_ctx
);
3241 result
= get_trust_credentials(domain
, talloc_tos(), true, &creds
);
3242 if (!NT_STATUS_IS_OK(result
)) {
3243 DBG_DEBUG("No user available for domain %s when trying "
3244 "schannel\n", domain
->name
);
3245 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
3248 if (cli_credentials_is_anonymous(creds
)) {
3249 DBG_WARNING("get_trust_credential only gave anonymous for %s, "
3250 "unable to make get NETLOGON credentials\n",
3252 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
3255 sec_chan_type
= cli_credentials_get_secure_channel_type(creds
);
3256 if (sec_chan_type
== SEC_CHAN_NULL
) {
3257 if (transport
== NCACN_IP_TCP
) {
3258 DBG_NOTICE("get_secure_channel_type gave SEC_CHAN_NULL "
3259 "for %s, deny NCACN_IP_TCP and let the "
3260 "caller fallback to NCACN_NP.\n",
3262 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
3265 DBG_NOTICE("get_secure_channel_type gave SEC_CHAN_NULL for %s, "
3266 "fallback to noauth on NCACN_NP.\n",
3269 result
= cli_rpc_pipe_open_noauth_transport(
3272 &ndr_table_netlogon
,
3273 &conn
->netlogon_pipe
);
3274 if (!NT_STATUS_IS_OK(result
)) {
3275 invalidate_cm_connection(domain
);
3279 *cli
= conn
->netlogon_pipe
;
3280 return NT_STATUS_OK
;
3283 result
= rpccli_create_netlogon_creds_ctx(creds
,
3287 &conn
->netlogon_creds_ctx
);
3288 if (!NT_STATUS_IS_OK(result
)) {
3289 DEBUG(1, ("rpccli_create_netlogon_creds failed for %s, "
3290 "unable to create NETLOGON credentials: %s\n",
3291 domain
->name
, nt_errstr(result
)));
3295 result
= rpccli_connect_netlogon(
3296 conn
->cli
, transport
,
3297 conn
->netlogon_creds_ctx
, conn
->netlogon_force_reauth
, creds
,
3298 &conn
->netlogon_pipe
);
3299 if (!NT_STATUS_IS_OK(result
)) {
3300 DBG_DEBUG("rpccli_connect_netlogon failed: %s\n",
3305 *cli
= conn
->netlogon_pipe
;
3306 return NT_STATUS_OK
;
3309 /****************************************************************************
3310 Open a NETLOGON connection to a DC, suiteable for SamLogon calls.
3311 ****************************************************************************/
3313 NTSTATUS
cm_connect_netlogon(struct winbindd_domain
*domain
,
3314 struct rpc_pipe_client
**cli
)
3318 status
= init_dc_connection_rpc(domain
, domain
->rodc
);
3319 if (!NT_STATUS_IS_OK(status
)) {
3323 if (domain
->active_directory
&& domain
->can_do_ncacn_ip_tcp
) {
3324 status
= cm_connect_netlogon_transport(domain
, NCACN_IP_TCP
, cli
);
3325 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
) ||
3326 NT_STATUS_EQUAL(status
, NT_STATUS_RPC_SEC_PKG_ERROR
) ||
3327 NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_ACCESS_DENIED
)) {
3328 invalidate_cm_connection(domain
);
3329 status
= cm_connect_netlogon_transport(domain
, NCACN_IP_TCP
, cli
);
3331 if (NT_STATUS_IS_OK(status
)) {
3336 * we tried twice to connect via ncan_ip_tcp and schannel and
3337 * failed - maybe it is a trusted domain we can't connect to ?
3338 * do not try tcp next time - gd
3340 * This also prevents LSA over TCP
3342 domain
->can_do_ncacn_ip_tcp
= false;
3345 status
= cm_connect_netlogon_transport(domain
, NCACN_NP
, cli
);
3346 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)) {
3348 * SMB2 session expired, needs reauthentication. Drop
3349 * connection and retry.
3351 invalidate_cm_connection(domain
);
3352 status
= cm_connect_netlogon_transport(domain
, NCACN_NP
, cli
);
3358 NTSTATUS
cm_connect_netlogon_secure(struct winbindd_domain
*domain
,
3359 struct rpc_pipe_client
**cli
,
3360 struct netlogon_creds_cli_context
**ppdc
)
3364 if (domain
->secure_channel_type
== SEC_CHAN_NULL
) {
3365 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
3368 status
= cm_connect_netlogon(domain
, cli
);
3369 if (!NT_STATUS_IS_OK(status
)) {
3373 if (domain
->conn
.netlogon_creds_ctx
== NULL
) {
3374 return NT_STATUS_TRUSTED_DOMAIN_FAILURE
;
3377 *ppdc
= domain
->conn
.netlogon_creds_ctx
;
3378 return NT_STATUS_OK
;
3381 void winbind_msg_ip_dropped(struct messaging_context
*msg_ctx
,
3384 struct server_id server_id
,
3387 struct winbindd_domain
*domain
;
3388 char *freeit
= NULL
;
3392 || (data
->data
== NULL
)
3393 || (data
->length
== 0)
3394 || (data
->data
[data
->length
-1] != '\0')) {
3395 DEBUG(1, ("invalid msg_ip_dropped message: not a valid "
3400 addr
= (char *)data
->data
;
3401 DEBUG(10, ("IP %s dropped\n", addr
));
3403 if (!is_ipaddress(addr
)) {
3406 * Some code sends us ip addresses with the /netmask
3409 slash
= strchr(addr
, '/');
3410 if (slash
== NULL
) {
3411 DEBUG(1, ("invalid msg_ip_dropped message: %s",
3415 freeit
= talloc_strndup(talloc_tos(), addr
, slash
-addr
);
3416 if (freeit
== NULL
) {
3417 DEBUG(1, ("talloc failed\n"));
3421 DEBUG(10, ("Stripped /netmask to IP %s\n", addr
));
3424 for (domain
= domain_list(); domain
!= NULL
; domain
= domain
->next
) {
3425 char sockaddr
[INET6_ADDRSTRLEN
];
3427 if (!cli_state_is_connected(domain
->conn
.cli
)) {
3431 print_sockaddr(sockaddr
, sizeof(sockaddr
),
3432 smbXcli_conn_local_sockaddr(domain
->conn
.cli
->conn
));
3434 if (strequal(sockaddr
, addr
)) {
3435 smbXcli_conn_disconnect(domain
->conn
.cli
->conn
, NT_STATUS_OK
);
3438 TALLOC_FREE(freeit
);