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"
88 #include "lib/util/string_wrappers.h"
89 #include "lib/global_contexts.h"
90 #include "librpc/gen_ndr/ndr_winbind_c.h"
93 #define DBGC_CLASS DBGC_WINBIND
97 struct sockaddr_storage ss
;
100 extern struct winbindd_methods reconnect_methods
;
102 static NTSTATUS
init_dc_connection_network(struct winbindd_domain
*domain
, bool need_rw_dc
);
103 static void set_dc_type_and_flags( struct winbindd_domain
*domain
);
104 static bool set_dc_type_and_flags_trustinfo( struct winbindd_domain
*domain
);
105 static bool get_dcs(TALLOC_CTX
*mem_ctx
, struct winbindd_domain
*domain
,
106 struct dc_name_ip
**dcs
, int *num_dcs
,
107 uint32_t request_flags
);
109 void winbind_msg_domain_offline(struct messaging_context
*msg_ctx
,
112 struct server_id server_id
,
115 const char *domain_name
= (const char *)data
->data
;
116 struct winbindd_domain
*domain
;
118 domain
= find_domain_from_name_noinit(domain_name
);
119 if (domain
== NULL
) {
120 DBG_DEBUG("Domain %s not found!\n", domain_name
);
124 DBG_DEBUG("Domain %s was %s, change to offline now.\n",
126 domain
->online
? "online" : "offline");
128 domain
->online
= false;
131 void winbind_msg_domain_online(struct messaging_context
*msg_ctx
,
134 struct server_id server_id
,
137 const char *domain_name
= (const char *)data
->data
;
138 struct winbindd_domain
*domain
;
140 domain
= find_domain_from_name_noinit(domain_name
);
141 if (domain
== NULL
) {
145 SMB_ASSERT(wb_child_domain() == NULL
);
147 DBG_DEBUG("Domain %s was %s, marking as online now!\n",
149 domain
->online
? "online" : "offline");
151 domain
->online
= true;
154 /****************************************************************
155 Set domain offline and also add handler to put us back online
157 ****************************************************************/
159 void set_domain_offline(struct winbindd_domain
*domain
)
161 pid_t parent_pid
= getppid();
163 DEBUG(10,("set_domain_offline: called for domain %s\n",
166 if (domain
->internal
) {
167 DEBUG(3,("set_domain_offline: domain %s is internal - logic error.\n",
172 domain
->online
= False
;
174 /* Offline domains are always initialized. They're
175 re-initialized when they go back online. */
177 domain
->initialized
= True
;
179 /* Send a message to the parent that the domain is offline. */
180 if (parent_pid
> 1 && !domain
->internal
) {
181 messaging_send_buf(global_messaging_context(),
182 pid_to_procid(parent_pid
),
183 MSG_WINBIND_DOMAIN_OFFLINE
,
184 (uint8_t *)domain
->name
,
185 strlen(domain
->name
) + 1);
188 /* Send an offline message to the idmap child when our
189 primary domain goes offline */
190 if ( domain
->primary
) {
191 pid_t idmap_pid
= idmap_child_pid();
193 if (idmap_pid
!= 0) {
194 messaging_send_buf(global_messaging_context(),
195 pid_to_procid(idmap_pid
),
197 (const uint8_t *)domain
->name
,
198 strlen(domain
->name
)+1);
205 /****************************************************************
206 Set domain online - if allowed.
207 ****************************************************************/
209 static void set_domain_online(struct winbindd_domain
*domain
)
211 pid_t parent_pid
= getppid();
213 DEBUG(10,("set_domain_online: called for domain %s\n",
216 if (domain
->internal
) {
217 DEBUG(3,("set_domain_online: domain %s is internal - logic error.\n",
222 if (get_global_winbindd_state_offline()) {
223 DEBUG(10,("set_domain_online: domain %s remaining globally offline\n",
228 winbindd_set_locator_kdc_envs(domain
);
230 /* If we are waiting to get a krb5 ticket, trigger immediately. */
231 ccache_regain_all_now();
233 /* Ok, we're out of any startup mode now... */
234 domain
->startup
= False
;
236 if (domain
->online
== False
) {
237 /* We were offline - now we're online. We default to
238 using the MS-RPC backend if we started offline,
239 and if we're going online for the first time we
240 should really re-initialize the backends and the
241 checks to see if we're talking to an AD or NT domain.
244 domain
->initialized
= False
;
246 /* 'reconnect_methods' is the MS-RPC backend. */
247 if (domain
->backend
== &reconnect_methods
) {
248 domain
->backend
= NULL
;
252 domain
->online
= True
;
254 /* Send a message to the parent that the domain is online. */
255 if (parent_pid
> 1 && !domain
->internal
) {
256 messaging_send_buf(global_messaging_context(),
257 pid_to_procid(parent_pid
),
258 MSG_WINBIND_DOMAIN_ONLINE
,
259 (uint8_t *)domain
->name
,
260 strlen(domain
->name
) + 1);
263 /* Send an online message to the idmap child when our
264 primary domain comes online */
266 if ( domain
->primary
) {
267 pid_t idmap_pid
= idmap_child_pid();
269 if (idmap_pid
!= 0) {
270 messaging_send_buf(global_messaging_context(),
271 pid_to_procid(idmap_pid
),
273 (const uint8_t *)domain
->name
,
274 strlen(domain
->name
)+1);
281 /****************************************************************
282 Requested to set a domain online.
283 ****************************************************************/
285 void set_domain_online_request(struct winbindd_domain
*domain
)
289 SMB_ASSERT(wb_child_domain() || idmap_child());
291 DEBUG(10,("set_domain_online_request: called for domain %s\n",
294 if (get_global_winbindd_state_offline()) {
295 DEBUG(10,("set_domain_online_request: domain %s remaining globally offline\n",
300 if (domain
->internal
) {
301 DEBUG(10, ("set_domain_online_request: Internal domains are "
307 * This call takes care of setting the online flag to true if we
308 * connected, or tell the parent to ping us back if false. Bypasses
309 * online check so always does network calls.
311 status
= init_dc_connection_network(domain
, true);
312 DBG_DEBUG("init_dc_connection_network(), returned %s, called for "
313 "domain %s (online = %s)\n",
316 domain
->online
? "true" : "false");
319 /****************************************************************
320 Add -ve connection cache entries for domain and realm.
321 ****************************************************************/
323 static void winbind_add_failed_connection_entry(
324 const struct winbindd_domain
*domain
,
328 add_failed_connection_entry(domain
->name
, server
, result
);
329 /* If this was the saf name for the last thing we talked to,
331 saf_delete(domain
->name
);
332 if (domain
->alt_name
!= NULL
) {
333 add_failed_connection_entry(domain
->alt_name
, server
, result
);
334 saf_delete(domain
->alt_name
);
336 winbindd_unset_locator_kdc_env(domain
);
339 /* Choose between anonymous or authenticated connections. We need to use
340 an authenticated connection if DCs have the RestrictAnonymous registry
341 entry set > 0, or the "Additional restrictions for anonymous
342 connections" set in the win2k Local Security Policy.
344 Caller to free() result in domain, username, password
347 static void cm_get_ipc_userpass(char **username
, char **domain
, char **password
)
349 *username
= (char *)secrets_fetch(SECRETS_AUTH_USER
, NULL
);
350 *domain
= (char *)secrets_fetch(SECRETS_AUTH_DOMAIN
, NULL
);
351 *password
= (char *)secrets_fetch(SECRETS_AUTH_PASSWORD
, NULL
);
353 if (*username
&& **username
) {
355 if (!*domain
|| !**domain
)
356 *domain
= smb_xstrdup(lp_workgroup());
358 if (!*password
|| !**password
)
359 *password
= smb_xstrdup("");
361 DEBUG(3, ("cm_get_ipc_userpass: Retrieved auth-user from secrets.tdb [%s\\%s]\n",
362 *domain
, *username
));
365 DEBUG(3, ("cm_get_ipc_userpass: No auth-user defined\n"));
366 *username
= smb_xstrdup("");
367 *domain
= smb_xstrdup("");
368 *password
= smb_xstrdup("");
372 static NTSTATUS
cm_get_ipc_credentials(TALLOC_CTX
*mem_ctx
,
373 struct cli_credentials
**_creds
)
376 TALLOC_CTX
*frame
= talloc_stackframe();
377 NTSTATUS status
= NT_STATUS_INTERNAL_ERROR
;
378 struct loadparm_context
*lp_ctx
;
379 char *username
= NULL
;
380 char *netbios_domain
= NULL
;
381 char *password
= NULL
;
382 struct cli_credentials
*creds
= NULL
;
385 cm_get_ipc_userpass(&username
, &netbios_domain
, &password
);
387 lp_ctx
= loadparm_init_s3(frame
, loadparm_s3_helpers());
388 if (lp_ctx
== NULL
) {
389 DEBUG(1, ("loadparm_init_s3 failed\n"));
390 status
= NT_STATUS_INTERNAL_ERROR
;
394 creds
= cli_credentials_init(mem_ctx
);
396 status
= NT_STATUS_NO_MEMORY
;
400 ok
= cli_credentials_set_conf(creds
, lp_ctx
);
402 status
= NT_STATUS_INTERNAL_ERROR
;
406 cli_credentials_set_kerberos_state(creds
,
407 CRED_USE_KERBEROS_DISABLED
,
410 ok
= cli_credentials_set_domain(creds
, netbios_domain
, CRED_SPECIFIED
);
412 status
= NT_STATUS_NO_MEMORY
;
416 ok
= cli_credentials_set_username(creds
, username
, CRED_SPECIFIED
);
418 status
= NT_STATUS_NO_MEMORY
;
422 ok
= cli_credentials_set_password(creds
, password
, CRED_SPECIFIED
);
424 status
= NT_STATUS_NO_MEMORY
;
430 status
= NT_STATUS_OK
;
434 SAFE_FREE(netbios_domain
);
440 static bool cm_is_ipc_credentials(struct cli_credentials
*creds
)
442 TALLOC_CTX
*frame
= talloc_stackframe();
443 char *ipc_account
= NULL
;
444 char *ipc_domain
= NULL
;
445 char *ipc_password
= NULL
;
446 const char *creds_account
= NULL
;
447 const char *creds_domain
= NULL
;
448 const char *creds_password
= NULL
;
451 cm_get_ipc_userpass(&ipc_account
, &ipc_domain
, &ipc_password
);
453 creds_account
= cli_credentials_get_username(creds
);
454 creds_domain
= cli_credentials_get_domain(creds
);
455 creds_password
= cli_credentials_get_password(creds
);
457 if (!strequal(ipc_domain
, creds_domain
)) {
461 if (!strequal(ipc_account
, creds_account
)) {
465 if (!strcsequal(ipc_password
, creds_password
)) {
471 SAFE_FREE(ipc_account
);
472 SAFE_FREE(ipc_domain
);
473 SAFE_FREE(ipc_password
);
478 static bool get_dc_name_via_netlogon(struct winbindd_domain
*domain
,
480 struct sockaddr_storage
*dc_ss
,
481 uint32_t request_flags
)
483 struct winbindd_domain
*our_domain
= NULL
;
484 struct rpc_pipe_client
*netlogon_pipe
= NULL
;
488 unsigned int orig_timeout
;
489 const char *tmp
= NULL
;
491 struct dcerpc_binding_handle
*b
;
493 /* Hmmmm. We can only open one connection to the NETLOGON pipe at the
500 if (domain
->primary
) {
504 our_domain
= find_our_domain();
506 if ((mem_ctx
= talloc_init("get_dc_name_via_netlogon")) == NULL
) {
510 result
= cm_connect_netlogon(our_domain
, &netlogon_pipe
);
511 if (!NT_STATUS_IS_OK(result
)) {
512 talloc_destroy(mem_ctx
);
516 b
= netlogon_pipe
->binding_handle
;
518 /* This call can take a long time - allow the server to time out.
519 35 seconds should do it. */
521 orig_timeout
= rpccli_set_timeout(netlogon_pipe
, 35000);
523 if (our_domain
->active_directory
) {
524 struct netr_DsRGetDCNameInfo
*domain_info
= NULL
;
527 * TODO request flags are not respected in the server
528 * (and in some cases, like REQUIRE_PDC, causes an error)
530 result
= dcerpc_netr_DsRGetDCName(b
,
536 request_flags
|DS_RETURN_DNS_NAME
,
539 if (NT_STATUS_IS_OK(result
) && W_ERROR_IS_OK(werr
)) {
541 mem_ctx
, domain_info
->dc_unc
);
543 DBG_ERR("talloc_strdup failed for dc_unc[%s]\n",
544 domain_info
->dc_unc
);
545 talloc_destroy(mem_ctx
);
548 if (domain
->alt_name
== NULL
) {
549 domain
->alt_name
= talloc_strdup(domain
,
550 domain_info
->domain_name
);
551 if (domain
->alt_name
== NULL
) {
552 DBG_ERR("talloc_strdup failed for "
553 "domain_info->domain_name[%s]\n",
554 domain_info
->domain_name
);
555 talloc_destroy(mem_ctx
);
559 if (domain
->forest_name
== NULL
) {
560 domain
->forest_name
= talloc_strdup(domain
,
561 domain_info
->forest_name
);
562 if (domain
->forest_name
== NULL
) {
563 DBG_ERR("talloc_strdup failed for "
564 "domain_info->forest_name[%s]\n",
565 domain_info
->forest_name
);
566 talloc_destroy(mem_ctx
);
572 result
= dcerpc_netr_GetAnyDCName(b
, mem_ctx
,
579 /* And restore our original timeout. */
580 rpccli_set_timeout(netlogon_pipe
, orig_timeout
);
582 if (!NT_STATUS_IS_OK(result
)) {
583 DEBUG(10,("dcerpc_netr_GetAnyDCName failed: %s\n",
585 talloc_destroy(mem_ctx
);
589 if (!W_ERROR_IS_OK(werr
)) {
590 DEBUG(10,("dcerpc_netr_GetAnyDCName failed: %s\n",
592 talloc_destroy(mem_ctx
);
596 /* dcerpc_netr_GetAnyDCName gives us a name with \\ */
597 p
= strip_hostname(tmp
);
601 talloc_destroy(mem_ctx
);
603 DEBUG(10,("dcerpc_netr_GetAnyDCName returned %s\n", dcname
));
605 if (!resolve_name(dcname
, dc_ss
, 0x20, true)) {
613 * Helper function to assemble trust password and account name
615 NTSTATUS
winbindd_get_trust_credentials(struct winbindd_domain
*domain
,
618 bool allow_ipc_fallback
,
619 struct cli_credentials
**_creds
)
621 const struct winbindd_domain
*creds_domain
= NULL
;
622 struct cli_credentials
*creds
;
624 bool force_machine_account
= false;
626 /* If we are a DC and this is not our own domain */
628 if (!domain
->active_directory
) {
631 * For non active directory domains
632 * we can only use NTLMSSP for SMB.
634 * But the trust account is not allowed
635 * to use SMB with NTLMSSP.
637 force_machine_account
= true;
641 if (IS_DC
&& !force_machine_account
) {
642 creds_domain
= domain
;
644 creds_domain
= find_our_domain();
645 if (creds_domain
== NULL
) {
646 return NT_STATUS_INVALID_SERVER_STATE
;
650 status
= pdb_get_trust_credentials(creds_domain
->name
,
651 creds_domain
->alt_name
,
654 if (!NT_STATUS_IS_OK(status
)) {
658 if (creds_domain
!= domain
) {
660 * We can only use schannel against a direct trust
662 cli_credentials_set_secure_channel_type(creds
,
671 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
674 if (!allow_ipc_fallback
) {
678 status
= cm_get_ipc_credentials(mem_ctx
, &creds
);
679 if (!NT_STATUS_IS_OK(status
)) {
687 /************************************************************************
688 Given a fd with a just-connected TCP connection to a DC, open a connection
690 ************************************************************************/
692 static NTSTATUS
cm_prepare_connection(struct winbindd_domain
*domain
,
694 const char *controller
,
695 struct cli_state
**cli
,
698 bool try_ipc_auth
= false;
699 const char *machine_principal
= NULL
;
700 const char *machine_realm
= NULL
;
701 const char *machine_account
= NULL
;
702 const char *machine_domain
= NULL
;
704 struct cli_credentials
*creds
= NULL
;
706 struct named_mutex
*mutex
;
708 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
710 NTSTATUS tcon_status
= NT_STATUS_NETWORK_NAME_DELETED
;
712 enum smb_signing_setting smb_sign_client_connections
= lp_client_ipc_signing();
715 if (domain
->secure_channel_type
== SEC_CHAN_NULL
) {
717 * Make sure we don't even try to
718 * connect to a foreign domain
719 * without a direct outbound trust.
722 return NT_STATUS_NO_TRUST_LSA_SECRET
;
726 * As AD DC we only use netlogon and lsa
727 * using schannel over an anonymous transport
728 * (ncacn_ip_tcp or ncacn_np).
730 * Currently we always establish the SMB connection,
731 * even if we don't use it, because we later use ncacn_ip_tcp.
733 * As we won't use the SMB connection there's no
734 * need to try kerberos. And NT4 domains expect
735 * an anonymous IPC$ connection anyway.
737 smb_sign_client_connections
= SMB_SIGNING_OFF
;
740 if (smb_sign_client_connections
== SMB_SIGNING_DEFAULT
) {
742 * If we are connecting to our own AD domain, require
743 * smb signing to disrupt MITM attacks
745 if (domain
->primary
&& lp_security() == SEC_ADS
) {
746 smb_sign_client_connections
= SMB_SIGNING_REQUIRED
;
748 * If we are in or are an AD domain and connecting to another
749 * AD domain in our forest
750 * then require smb signing to disrupt MITM attacks
752 } else if ((lp_security() == SEC_ADS
)
753 && domain
->active_directory
754 && (domain
->domain_trust_attribs
755 & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST
)) {
756 smb_sign_client_connections
= SMB_SIGNING_REQUIRED
;
760 DEBUG(10,("cm_prepare_connection: connecting to DC %s for domain %s\n",
761 controller
, domain
->name
));
765 mutex
= grab_named_mutex(talloc_tos(), controller
,
766 WINBIND_SERVER_MUTEX_WAIT_TIME
);
769 DEBUG(0,("cm_prepare_connection: mutex grab failed for %s\n",
771 result
= NT_STATUS_POSSIBLE_DEADLOCK
;
776 * cm_prepare_connection() is responsible that sockfd does not leak.
777 * Once cli_state_create() returns with success, the
778 * smbXcli_conn_destructor() makes sure that close(sockfd) is finally
779 * called. Till that, close(sockfd) must be called on every unsuccessful
782 *cli
= cli_state_create(NULL
, sockfd
, controller
,
783 smb_sign_client_connections
, flags
);
786 DEBUG(1, ("Could not cli_initialize\n"));
787 result
= NT_STATUS_NO_MEMORY
;
791 cli_set_timeout(*cli
, 10000); /* 10 seconds */
793 set_socket_options(sockfd
, lp_socket_options());
795 result
= smbXcli_negprot((*cli
)->conn
,
797 lp_client_ipc_min_protocol(),
798 lp_client_ipc_max_protocol(),
803 if (!NT_STATUS_IS_OK(result
)) {
804 DEBUG(1, ("cli_negprot failed: %s\n", nt_errstr(result
)));
808 if (smbXcli_conn_protocol((*cli
)->conn
) >= PROTOCOL_NT1
&&
809 smb1cli_conn_capabilities((*cli
)->conn
) & CAP_EXTENDED_SECURITY
) {
811 } else if (smbXcli_conn_protocol((*cli
)->conn
) >= PROTOCOL_SMB2_02
) {
813 } else if (smb_sign_client_connections
== SMB_SIGNING_REQUIRED
) {
815 * If we are forcing on SMB signing, then we must
816 * require authentication unless this is a one-way
817 * trust, and we have no stored user/password
824 * As AD DC we only use netlogon and lsa
825 * using schannel over an anonymous transport
826 * (ncacn_ip_tcp or ncacn_np).
828 * Currently we always establish the SMB connection,
829 * even if we don't use it, because we later use ncacn_ip_tcp.
831 * As we won't use the SMB connection there's no
832 * need to try kerberos. And NT4 domains expect
833 * an anonymous IPC$ connection anyway.
835 try_ipc_auth
= false;
839 result
= winbindd_get_trust_credentials(domain
,
841 false, /* netlogon */
842 true, /* ipc_fallback */
844 if (!NT_STATUS_IS_OK(result
)) {
845 DBG_WARNING("winbindd_get_trust_credentials(%s) "
853 * Without SPNEGO or NTLMSSP (perhaps via SMB2) we
854 * would try and authentication with our machine
855 * account password and fail. This is very rare in
856 * the modern world however
858 creds
= cli_credentials_init_anon(talloc_tos());
860 result
= NT_STATUS_NO_MEMORY
;
861 DEBUG(1, ("cli_credentials_init_anon(%s) failed: %s\n",
862 domain
->name
, nt_errstr(result
)));
867 machine_principal
= cli_credentials_get_principal(creds
,
869 machine_realm
= cli_credentials_get_realm(creds
);
870 machine_account
= cli_credentials_get_username(creds
);
871 machine_domain
= cli_credentials_get_domain(creds
);
873 DEBUG(5, ("connecting to %s (%s, %s) with account [%s\\%s] principal "
874 "[%s] and realm [%s]\n",
875 controller
, domain
->name
, domain
->alt_name
,
876 machine_domain
, machine_account
,
877 machine_principal
, machine_realm
));
879 if (cli_credentials_is_anonymous(creds
)) {
883 winbindd_set_locator_kdc_envs(domain
);
885 result
= cli_session_setup_creds(*cli
, creds
);
886 if (NT_STATUS_IS_OK(result
)) {
887 goto session_setup_done
;
890 DEBUG(1, ("authenticated session setup to %s using %s failed with %s\n",
892 cli_credentials_get_unparsed_name(creds
, talloc_tos()),
896 * If we are not going to validate the connection
897 * with SMB signing, then allow us to fall back to
900 if (NT_STATUS_EQUAL(result
, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT
)
901 || NT_STATUS_EQUAL(result
, NT_STATUS_TRUSTED_DOMAIN_FAILURE
)
902 || NT_STATUS_EQUAL(result
, NT_STATUS_INVALID_ACCOUNT_NAME
)
903 || NT_STATUS_EQUAL(result
, NT_STATUS_INVALID_COMPUTER_NAME
)
904 || NT_STATUS_EQUAL(result
, NT_STATUS_NO_SUCH_DOMAIN
)
905 || NT_STATUS_EQUAL(result
, NT_STATUS_NO_LOGON_SERVERS
)
906 || NT_STATUS_EQUAL(result
, NT_STATUS_LOGON_FAILURE
))
908 if (!cm_is_ipc_credentials(creds
)) {
912 if (smb_sign_client_connections
== SMB_SIGNING_REQUIRED
) {
923 tmp_status
= cm_get_ipc_credentials(talloc_tos(), &creds
);
924 if (!NT_STATUS_IS_OK(tmp_status
)) {
929 if (cli_credentials_is_anonymous(creds
)) {
933 machine_account
= cli_credentials_get_username(creds
);
934 machine_domain
= cli_credentials_get_domain(creds
);
936 DEBUG(5, ("connecting to %s from %s using NTLMSSP with username "
937 "[%s]\\[%s]\n", controller
, lp_netbios_name(),
938 machine_domain
, machine_account
));
940 result
= cli_session_setup_creds(*cli
, creds
);
941 if (NT_STATUS_IS_OK(result
)) {
942 goto session_setup_done
;
945 DEBUG(1, ("authenticated session setup to %s using %s failed with %s\n",
947 cli_credentials_get_unparsed_name(creds
, talloc_tos()),
951 * If we are not going to validate the connection
952 * with SMB signing, then allow us to fall back to
955 if (NT_STATUS_EQUAL(result
, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT
)
956 || NT_STATUS_EQUAL(result
, NT_STATUS_TRUSTED_DOMAIN_FAILURE
)
957 || NT_STATUS_EQUAL(result
, NT_STATUS_INVALID_ACCOUNT_NAME
)
958 || NT_STATUS_EQUAL(result
, NT_STATUS_INVALID_COMPUTER_NAME
)
959 || NT_STATUS_EQUAL(result
, NT_STATUS_NO_SUCH_DOMAIN
)
960 || NT_STATUS_EQUAL(result
, NT_STATUS_NO_LOGON_SERVERS
)
961 || NT_STATUS_EQUAL(result
, NT_STATUS_LOGON_FAILURE
))
971 if (smb_sign_client_connections
== SMB_SIGNING_REQUIRED
) {
975 /* Fall back to anonymous connection, this might fail later */
976 DEBUG(5,("cm_prepare_connection: falling back to anonymous "
977 "connection for DC %s\n",
980 result
= cli_session_setup_anon(*cli
);
981 if (NT_STATUS_IS_OK(result
)) {
982 DEBUG(5, ("Connected anonymously\n"));
983 goto session_setup_done
;
986 DEBUG(1, ("anonymous session setup to %s failed with %s\n",
987 controller
, nt_errstr(result
)));
989 /* We can't session setup */
996 * This should be a short term hack until
997 * dynamic re-authentication is implemented.
999 * See Bug 9175 - winbindd doesn't recover from
1000 * NT_STATUS_NETWORK_SESSION_EXPIRED
1002 if (smbXcli_conn_protocol((*cli
)->conn
) >= PROTOCOL_SMB2_02
) {
1003 smbXcli_session_set_disconnect_expired((*cli
)->smb2
.session
);
1006 result
= cli_tree_connect(*cli
, "IPC$", "IPC", NULL
);
1007 if (!NT_STATUS_IS_OK(result
)) {
1008 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(result
)));
1011 tcon_status
= result
;
1013 /* cache the server name for later connections */
1015 saf_store(domain
->name
, controller
);
1016 if (domain
->alt_name
) {
1017 saf_store(domain
->alt_name
, controller
);
1020 winbindd_set_locator_kdc_envs(domain
);
1025 result
= NT_STATUS_OK
;
1031 if (NT_STATUS_IS_OK(result
)) {
1032 result
= tcon_status
;
1035 if (!NT_STATUS_IS_OK(result
)) {
1036 DEBUG(1, ("Failed to prepare SMB connection to %s: %s\n",
1037 controller
, nt_errstr(result
)));
1038 winbind_add_failed_connection_entry(domain
, controller
, result
);
1039 if ((*cli
) != NULL
) {
1048 /*******************************************************************
1049 Add a dcname and sockaddr_storage pair to the end of a dc_name_ip
1052 Keeps the list unique by not adding duplicate entries.
1054 @param[in] mem_ctx talloc memory context to allocate from
1055 @param[in] domain_name domain of the DC
1056 @param[in] dcname name of the DC to add to the list
1057 @param[in] pss Internet address and port pair to add to the list
1058 @param[in,out] dcs array of dc_name_ip structures to add to
1059 @param[in,out] num_dcs number of dcs returned in the dcs array
1060 @return true if the list was added to, false otherwise
1061 *******************************************************************/
1063 static bool add_one_dc_unique(TALLOC_CTX
*mem_ctx
, const char *domain_name
,
1064 const char *dcname
, struct sockaddr_storage
*pss
,
1065 struct dc_name_ip
**dcs
, int *num
)
1069 if (!NT_STATUS_IS_OK(check_negative_conn_cache(domain_name
, dcname
))) {
1070 DEBUG(10, ("DC %s was in the negative conn cache\n", dcname
));
1074 /* Make sure there's no duplicates in the list */
1075 for (i
=0; i
<*num
; i
++)
1077 (struct sockaddr
*)(void *)&(*dcs
)[i
].ss
,
1078 (struct sockaddr
*)(void *)pss
))
1081 *dcs
= talloc_realloc(mem_ctx
, *dcs
, struct dc_name_ip
, (*num
)+1);
1086 fstrcpy((*dcs
)[*num
].name
, dcname
);
1087 (*dcs
)[*num
].ss
= *pss
;
1092 static bool add_sockaddr_to_array(TALLOC_CTX
*mem_ctx
,
1093 struct sockaddr_storage
*pss
, uint16_t port
,
1094 struct sockaddr_storage
**addrs
, int *num
)
1096 *addrs
= talloc_realloc(mem_ctx
, *addrs
, struct sockaddr_storage
, (*num
)+1);
1098 if (*addrs
== NULL
) {
1103 (*addrs
)[*num
] = *pss
;
1104 set_sockaddr_port((struct sockaddr
*)&(*addrs
)[*num
], port
);
1111 static bool dcip_check_name_ads(const struct winbindd_domain
*domain
,
1112 struct samba_sockaddr
*sa
,
1113 uint32_t request_flags
,
1114 TALLOC_CTX
*mem_ctx
,
1117 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
1119 ADS_STRUCT
*ads
= NULL
;
1120 ADS_STATUS ads_status
;
1121 char addr
[INET6_ADDRSTRLEN
];
1123 print_sockaddr(addr
, sizeof(addr
), &sa
->u
.ss
);
1124 D_DEBUG("Trying to figure out the DC name for domain '%s' at IP '%s'.\n",
1128 ads
= ads_init(tmp_ctx
,
1134 ads_status
= ADS_ERROR_NT(NT_STATUS_NO_MEMORY
);
1137 ads
->config
.flags
|= request_flags
;
1138 ads
->server
.no_fallback
= true;
1140 ads_status
= ads_connect_cldap_only(ads
);
1141 if (!ADS_ERR_OK(ads_status
)) {
1145 /* We got a cldap packet. */
1146 name
= talloc_strdup(tmp_ctx
, ads
->config
.ldap_server_name
);
1148 ads_status
= ADS_ERROR_NT(NT_STATUS_NO_MEMORY
);
1151 namecache_store(name
, 0x20, 1, sa
);
1153 DBG_DEBUG("CLDAP flags = 0x%"PRIx32
"\n", ads
->config
.flags
);
1155 if (domain
->primary
&& (ads
->config
.flags
& NBT_SERVER_KDC
)) {
1156 if (ads_closest_dc(ads
)) {
1157 char *sitename
= sitename_fetch(tmp_ctx
,
1160 /* We're going to use this KDC for this realm/domain.
1161 If we are using sites, then force the krb5 libs
1164 create_local_private_krb5_conf_for_domain(domain
->alt_name
,
1169 TALLOC_FREE(sitename
);
1171 /* use an off site KDC */
1172 create_local_private_krb5_conf_for_domain(domain
->alt_name
,
1177 winbindd_set_locator_kdc_envs(domain
);
1179 /* Ensure we contact this DC also. */
1180 saf_store(domain
->name
, name
);
1181 saf_store(domain
->alt_name
, name
);
1184 D_DEBUG("DC name for domain '%s' at IP '%s' is '%s'\n",
1188 *namep
= talloc_move(mem_ctx
, &name
);
1191 TALLOC_FREE(tmp_ctx
);
1193 return ADS_ERR_OK(ads_status
) ? true : false;
1197 /*******************************************************************
1198 convert an ip to a name
1199 For an AD Domain, it checks the requirements of the request flags.
1200 *******************************************************************/
1202 static bool dcip_check_name(TALLOC_CTX
*mem_ctx
,
1203 const struct winbindd_domain
*domain
,
1204 const struct sockaddr_storage
*pss
,
1205 char **name
, uint32_t request_flags
)
1207 struct samba_sockaddr sa
= {0};
1208 uint32_t nt_version
= NETLOGON_NT_VERSION_1
;
1210 const char *dc_name
;
1213 bool is_ad_domain
= false;
1215 bool ok
= sockaddr_storage_to_samba_sockaddr(&sa
, pss
);
1221 /* For active directory servers, try to get the ldap server name.
1222 None of these failures should be considered critical for now */
1224 if ((lp_security() == SEC_ADS
) && (domain
->alt_name
!= NULL
)) {
1225 is_ad_domain
= true;
1226 } else if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
) {
1227 is_ad_domain
= domain
->active_directory
;
1231 return dcip_check_name_ads(domain
,
1240 size_t len
= strlen(lp_netbios_name());
1241 char my_acct_name
[len
+2];
1243 snprintf(my_acct_name
,
1244 sizeof(my_acct_name
),
1248 status
= nbt_getdc(global_messaging_context(), 10, &sa
.u
.ss
,
1249 domain
->name
, &domain
->sid
,
1250 my_acct_name
, ACB_WSTRUST
,
1251 nt_version
, mem_ctx
, &nt_version
,
1254 if (NT_STATUS_IS_OK(status
)) {
1255 *name
= talloc_strdup(mem_ctx
, dc_name
);
1256 if (*name
== NULL
) {
1259 namecache_store(*name
, 0x20, 1, &sa
);
1263 /* try node status request */
1265 if (name_status_find(domain
->name
, 0x1c, 0x20, &sa
.u
.ss
, nbtname
) ) {
1266 namecache_store(nbtname
, 0x20, 1, &sa
);
1269 *name
= talloc_strdup(mem_ctx
, nbtname
);
1270 if (*name
== NULL
) {
1280 /*******************************************************************
1281 Retrieve a list of IP addresses for domain controllers.
1283 The array is sorted in the preferred connection order.
1285 @param[in] mem_ctx talloc memory context to allocate from
1286 @param[in] domain domain to retrieve DCs for
1287 @param[out] dcs array of dcs that will be returned
1288 @param[out] num_dcs number of dcs returned in the dcs array
1290 *******************************************************************/
1292 static bool get_dcs(TALLOC_CTX
*mem_ctx
, struct winbindd_domain
*domain
,
1293 struct dc_name_ip
**dcs
, int *num_dcs
,
1294 uint32_t request_flags
)
1297 struct sockaddr_storage ss
;
1298 struct samba_sockaddr
*sa_list
= NULL
;
1299 size_t salist_size
= 0;
1302 enum security_types sec
= (enum security_types
)lp_security();
1304 is_our_domain
= strequal(domain
->name
, lp_workgroup());
1306 /* If not our domain, get the preferred DC, by asking our primary DC */
1308 && get_dc_name_via_netlogon(domain
, dcname
, &ss
, request_flags
)
1309 && add_one_dc_unique(mem_ctx
, domain
->name
, dcname
, &ss
, dcs
,
1312 char addr
[INET6_ADDRSTRLEN
];
1313 print_sockaddr(addr
, sizeof(addr
), &ss
);
1314 DEBUG(10, ("Retrieved DC %s at %s via netlogon\n",
1319 if ((sec
== SEC_ADS
) && (domain
->alt_name
!= NULL
)) {
1320 char *sitename
= NULL
;
1322 /* We need to make sure we know the local site before
1323 doing any DNS queries, as this will restrict the
1324 get_sorted_dc_list() call below to only fetching
1325 DNS records for the correct site. */
1327 /* Find any DC to get the site record.
1328 We deliberately don't care about the
1331 get_dc_name(domain
->name
, domain
->alt_name
, dcname
, &ss
);
1333 sitename
= sitename_fetch(mem_ctx
, domain
->alt_name
);
1336 /* Do the site-specific AD dns lookup first. */
1337 (void)get_sorted_dc_list(mem_ctx
,
1344 /* Add ips to the DC array. We don't look up the name
1345 of the DC in this function, but we fill in the char*
1346 of the ip now to make the failed connection cache
1348 for ( i
=0; i
<salist_size
; i
++ ) {
1349 char addr
[INET6_ADDRSTRLEN
];
1350 print_sockaddr(addr
, sizeof(addr
),
1352 add_one_dc_unique(mem_ctx
,
1360 TALLOC_FREE(sa_list
);
1361 TALLOC_FREE(sitename
);
1365 /* Now we add DCs from the main AD DNS lookup. */
1366 (void)get_sorted_dc_list(mem_ctx
,
1373 for ( i
=0; i
<salist_size
; i
++ ) {
1374 char addr
[INET6_ADDRSTRLEN
];
1375 print_sockaddr(addr
, sizeof(addr
),
1377 add_one_dc_unique(mem_ctx
,
1385 TALLOC_FREE(sa_list
);
1389 /* Try standard netbios queries if no ADS and fall back to DNS queries
1390 * if alt_name is available */
1391 if (*num_dcs
== 0) {
1392 (void)get_sorted_dc_list(mem_ctx
,
1398 if (salist_size
== 0) {
1399 if (domain
->alt_name
!= NULL
) {
1400 (void)get_sorted_dc_list(mem_ctx
,
1409 for ( i
=0; i
<salist_size
; i
++ ) {
1410 char addr
[INET6_ADDRSTRLEN
];
1411 print_sockaddr(addr
, sizeof(addr
),
1413 add_one_dc_unique(mem_ctx
,
1421 TALLOC_FREE(sa_list
);
1428 static bool connect_preferred_dc(TALLOC_CTX
*mem_ctx
,
1429 struct winbindd_domain
*domain
,
1430 uint32_t request_flags
,
1433 char *saf_servername
= NULL
;
1438 * We have to check the server affinity cache here since later we select
1439 * a DC based on response time and not preference.
1441 if (domain
->force_dc
) {
1442 saf_servername
= domain
->dcname
;
1444 saf_servername
= saf_fetch(mem_ctx
, domain
->name
);
1448 * Check the negative connection cache before talking to it. It going
1449 * down may have triggered the reconnection.
1451 if (saf_servername
!= NULL
) {
1452 status
= check_negative_conn_cache(domain
->name
,
1454 if (!NT_STATUS_IS_OK(status
)) {
1455 saf_servername
= NULL
;
1459 if (saf_servername
!= NULL
) {
1460 DBG_DEBUG("saf_servername is '%s' for domain %s\n",
1461 saf_servername
, domain
->name
);
1463 /* convert an ip address to a name */
1464 if (is_ipaddress(saf_servername
)) {
1465 ok
= interpret_string_addr(&domain
->dcaddr
,
1472 ok
= resolve_name(saf_servername
,
1481 TALLOC_FREE(domain
->dcname
);
1482 ok
= dcip_check_name(domain
,
1492 if (domain
->dcname
== NULL
) {
1496 status
= check_negative_conn_cache(domain
->name
, domain
->dcname
);
1497 if (!NT_STATUS_IS_OK(status
)) {
1501 status
= smbsock_connect(&domain
->dcaddr
, 0,
1502 domain
->dcname
, -1, NULL
, -1,
1504 if (!NT_STATUS_IS_OK(status
)) {
1505 winbind_add_failed_connection_entry(domain
,
1507 NT_STATUS_UNSUCCESSFUL
);
1513 winbind_add_failed_connection_entry(domain
,
1515 NT_STATUS_UNSUCCESSFUL
);
1520 /*******************************************************************
1521 Find and make a connection to a DC in the given domain.
1523 @param[in] mem_ctx talloc memory context to allocate from
1524 @param[in] domain domain to find a dc in
1525 @param[out] fd fd of the open socket connected to the newly found dc
1526 @return true when a DC connection is made, false otherwise
1527 *******************************************************************/
1529 static bool find_dc(TALLOC_CTX
*mem_ctx
,
1530 struct winbindd_domain
*domain
,
1531 uint32_t request_flags
,
1534 struct dc_name_ip
*dcs
= NULL
;
1537 const char **dcnames
= NULL
;
1538 size_t num_dcnames
= 0;
1540 struct sockaddr_storage
*addrs
= NULL
;
1551 D_NOTICE("First try to connect to the closest DC (using server "
1552 "affinity cache). If this fails, try to lookup the DC using "
1553 "DNS afterwards.\n");
1554 ok
= connect_preferred_dc(mem_ctx
, domain
, request_flags
, fd
);
1559 if (domain
->force_dc
) {
1564 D_DEBUG("Retrieving a list of IP addresses for DCs.\n");
1565 if (!get_dcs(mem_ctx
, domain
, &dcs
, &num_dcs
, request_flags
) || (num_dcs
== 0))
1568 D_DEBUG("Retrieved IP addresses for %d DCs.\n", num_dcs
);
1569 for (i
=0; i
<num_dcs
; i
++) {
1571 if (!add_string_to_array(mem_ctx
, dcs
[i
].name
,
1572 &dcnames
, &num_dcnames
)) {
1575 if (!add_sockaddr_to_array(mem_ctx
, &dcs
[i
].ss
, TCP_SMB_PORT
,
1576 &addrs
, &num_addrs
)) {
1581 if ((num_dcnames
== 0) || (num_dcnames
!= num_addrs
))
1584 if ((addrs
== NULL
) || (dcnames
== NULL
))
1587 D_DEBUG("Trying to establish a connection to one of the %d DCs "
1588 "(timeout of 10 sec for each DC).\n",
1590 status
= smbsock_any_connect(addrs
, dcnames
, NULL
, NULL
, NULL
,
1591 num_addrs
, 0, 10, fd
, &fd_index
, NULL
);
1592 if (!NT_STATUS_IS_OK(status
)) {
1593 for (i
=0; i
<num_dcs
; i
++) {
1594 char ab
[INET6_ADDRSTRLEN
];
1595 print_sockaddr(ab
, sizeof(ab
), &dcs
[i
].ss
);
1596 DBG_DEBUG("smbsock_any_connect failed for "
1597 "domain %s address %s. Error was %s\n",
1598 domain
->name
, ab
, nt_errstr(status
));
1599 winbind_add_failed_connection_entry(domain
,
1600 dcs
[i
].name
, NT_STATUS_UNSUCCESSFUL
);
1604 D_NOTICE("Successfully connected to DC '%s'.\n", dcs
[fd_index
].name
);
1606 domain
->dcaddr
= addrs
[fd_index
];
1608 if (*dcnames
[fd_index
] != '\0' && !is_ipaddress(dcnames
[fd_index
])) {
1609 /* Ok, we've got a name for the DC */
1610 TALLOC_FREE(domain
->dcname
);
1611 domain
->dcname
= talloc_strdup(domain
, dcnames
[fd_index
]);
1612 if (domain
->dcname
== NULL
) {
1618 /* Try to figure out the name */
1619 TALLOC_FREE(domain
->dcname
);
1620 ok
= dcip_check_name(domain
,
1629 /* We can not continue without the DC's name */
1630 winbind_add_failed_connection_entry(domain
, dcs
[fd_index
].name
,
1631 NT_STATUS_UNSUCCESSFUL
);
1633 /* Throw away all arrays as we're doing this again. */
1637 TALLOC_FREE(dcnames
);
1649 * This should not be an infinite loop, since get_dcs() will not return
1650 * the DC added to the negative connection cache in the above
1651 * winbind_add_failed_connection_entry() call.
1656 static char *current_dc_key(TALLOC_CTX
*mem_ctx
, const char *domain_name
)
1658 return talloc_asprintf_strupper_m(mem_ctx
, "CURRENT_DCNAME/%s",
1662 static void store_current_dc_in_gencache(const char *domain_name
,
1663 const char *dc_name
,
1664 const struct sockaddr_storage
*dc_addr
)
1666 char addr
[INET6_ADDRSTRLEN
];
1670 print_sockaddr(addr
, sizeof(addr
), dc_addr
);
1672 key
= current_dc_key(talloc_tos(), domain_name
);
1677 value
= talloc_asprintf(talloc_tos(), "%s %s", addr
, dc_name
);
1678 if (value
== NULL
) {
1682 gencache_set(key
, value
, 0x7fffffff);
1688 bool fetch_current_dc_from_gencache(TALLOC_CTX
*mem_ctx
,
1689 const char *domain_name
,
1690 char **p_dc_name
, char **p_dc_ip
)
1695 char *dc_name
= NULL
;
1698 key
= current_dc_key(talloc_tos(), domain_name
);
1702 if (!gencache_get(key
, mem_ctx
, &value
, NULL
)) {
1705 p
= strchr(value
, ' ');
1709 dc_ip
= talloc_strndup(mem_ctx
, value
, p
- value
);
1710 if (dc_ip
== NULL
) {
1713 dc_name
= talloc_strdup(mem_ctx
, p
+1);
1714 if (dc_name
== NULL
) {
1718 if (p_dc_ip
!= NULL
) {
1722 if (p_dc_name
!= NULL
) {
1723 *p_dc_name
= dc_name
;
1728 TALLOC_FREE(dc_name
);
1735 NTSTATUS
wb_open_internal_pipe(TALLOC_CTX
*mem_ctx
,
1736 const struct ndr_interface_table
*table
,
1737 struct rpc_pipe_client
**ret_pipe
)
1739 struct rpc_pipe_client
*cli
= NULL
;
1740 const struct auth_session_info
*session_info
= NULL
;
1741 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
1744 session_info
= get_session_info_system();
1745 SMB_ASSERT(session_info
!= NULL
);
1747 status
= rpc_pipe_open_local_np(
1748 mem_ctx
, table
, NULL
, NULL
, NULL
, NULL
, session_info
, &cli
);
1749 if (!NT_STATUS_IS_OK(status
)) {
1757 return NT_STATUS_OK
;
1760 static NTSTATUS
cm_open_connection(struct winbindd_domain
*domain
,
1761 struct winbindd_cm_conn
*new_conn
,
1764 TALLOC_CTX
*mem_ctx
;
1765 NTSTATUS result
= NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND
;
1767 uint32_t request_flags
= need_rw_dc
? DS_WRITABLE_REQUIRED
: 0;
1770 bool seal_pipes
= true;
1772 if ((mem_ctx
= talloc_init("cm_open_connection")) == NULL
) {
1773 set_domain_offline(domain
);
1774 return NT_STATUS_NO_MEMORY
;
1777 D_NOTICE("Creating connection to domain controller. This is a start of "
1778 "a new connection or a DC failover. The failover only happens "
1779 "if the domain has more than one DC. We will try to connect 3 "
1780 "times at most.\n");
1781 for (retries
= 0; retries
< 3; retries
++) {
1784 D_DEBUG("Attempt %d/3: DC '%s' of domain '%s'.\n",
1786 domain
->dcname
? domain
->dcname
: "",
1789 found_dc
= find_dc(mem_ctx
, domain
, request_flags
, &fd
);
1791 /* This is the one place where we will
1792 set the global winbindd offline state
1793 to true, if a "WINBINDD_OFFLINE" entry
1794 is found in the winbindd cache. */
1795 set_global_winbindd_state_offline();
1796 result
= NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND
;
1800 new_conn
->cli
= NULL
;
1802 result
= cm_prepare_connection(domain
, fd
, domain
->dcname
,
1803 &new_conn
->cli
, &retry
);
1804 if (NT_STATUS_IS_OK(result
)) {
1812 if (!NT_STATUS_IS_OK(result
)) {
1813 /* Ensure we setup the retry handler. */
1814 set_domain_offline(domain
);
1818 winbindd_set_locator_kdc_envs(domain
);
1820 if (domain
->online
== False
) {
1821 /* We're changing state from offline to online. */
1822 set_global_winbindd_state_online();
1824 set_domain_online(domain
);
1827 * Much as I hate global state, this seems to be the point
1828 * where we can be certain that we have a proper connection to
1829 * a DC. wbinfo --dc-info needs that information, store it in
1830 * gencache with a looong timeout. This will need revisiting
1831 * once we start to connect to multiple DCs, wbcDcInfo is
1832 * already prepared for that.
1834 store_current_dc_in_gencache(domain
->name
,
1838 seal_pipes
= lp_winbind_sealed_pipes();
1839 seal_pipes
= lp_parm_bool(-1, "winbind sealed pipes",
1844 new_conn
->auth_level
= DCERPC_AUTH_LEVEL_PRIVACY
;
1846 new_conn
->auth_level
= DCERPC_AUTH_LEVEL_INTEGRITY
;
1850 talloc_destroy(mem_ctx
);
1854 /* Close down all open pipes on a connection. */
1856 void invalidate_cm_connection(struct winbindd_domain
*domain
)
1859 struct winbindd_cm_conn
*conn
= &domain
->conn
;
1861 domain
->sequence_number
= DOM_SEQUENCE_NONE
;
1862 domain
->last_seq_check
= 0;
1863 domain
->last_status
= NT_STATUS_SERVER_DISABLED
;
1865 /* We're closing down a possibly dead
1866 connection. Don't have impossibly long (10s) timeouts. */
1869 cli_set_timeout(conn
->cli
, 1000); /* 1 second. */
1872 if (conn
->samr_pipe
!= NULL
) {
1873 if (is_valid_policy_hnd(&conn
->sam_connect_handle
)) {
1874 dcerpc_samr_Close(conn
->samr_pipe
->binding_handle
,
1876 &conn
->sam_connect_handle
,
1879 TALLOC_FREE(conn
->samr_pipe
);
1880 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1882 cli_set_timeout(conn
->cli
, 500);
1886 if (conn
->lsa_pipe
!= NULL
) {
1887 if (is_valid_policy_hnd(&conn
->lsa_policy
)) {
1888 dcerpc_lsa_Close(conn
->lsa_pipe
->binding_handle
,
1893 TALLOC_FREE(conn
->lsa_pipe
);
1894 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1896 cli_set_timeout(conn
->cli
, 500);
1900 if (conn
->lsa_pipe_tcp
!= NULL
) {
1901 if (is_valid_policy_hnd(&conn
->lsa_policy
)) {
1902 dcerpc_lsa_Close(conn
->lsa_pipe_tcp
->binding_handle
,
1907 TALLOC_FREE(conn
->lsa_pipe_tcp
);
1908 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1910 cli_set_timeout(conn
->cli
, 500);
1914 if (conn
->netlogon_pipe
!= NULL
) {
1915 TALLOC_FREE(conn
->netlogon_pipe
);
1916 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1918 cli_set_timeout(conn
->cli
, 500);
1922 conn
->auth_level
= DCERPC_AUTH_LEVEL_PRIVACY
;
1923 TALLOC_FREE(conn
->netlogon_creds_ctx
);
1926 cli_shutdown(conn
->cli
);
1932 void close_conns_after_fork(void)
1934 struct winbindd_domain
*domain
;
1935 struct winbindd_cli_state
*cli_state
;
1937 for (domain
= domain_list(); domain
; domain
= domain
->next
) {
1939 * first close the low level SMB TCP connection
1940 * so that we don't generate any SMBclose
1941 * requests in invalidate_cm_connection()
1943 if (cli_state_is_connected(domain
->conn
.cli
)) {
1944 smbXcli_conn_disconnect(domain
->conn
.cli
->conn
, NT_STATUS_OK
);
1947 invalidate_cm_connection(domain
);
1950 for (cli_state
= winbindd_client_list();
1952 cli_state
= cli_state
->next
) {
1953 if (cli_state
->sock
>= 0) {
1954 close(cli_state
->sock
);
1955 cli_state
->sock
= -1;
1960 static bool connection_ok(struct winbindd_domain
*domain
)
1964 ok
= cli_state_is_connected(domain
->conn
.cli
);
1966 DEBUG(3, ("connection_ok: Connection to %s for domain %s is not connected\n",
1967 domain
->dcname
, domain
->name
));
1971 if (!domain
->online
) {
1972 DEBUG(3, ("connection_ok: Domain %s is offline\n", domain
->name
));
1979 /* Initialize a new connection up to the RPC BIND.
1980 Bypass online status check so always does network calls. */
1982 static NTSTATUS
init_dc_connection_network(struct winbindd_domain
*domain
, bool need_rw_dc
)
1985 bool skip_connection
= domain
->internal
;
1986 if (need_rw_dc
&& domain
->rodc
) {
1987 skip_connection
= false;
1990 /* Internal connections never use the network. */
1991 if (dom_sid_equal(&domain
->sid
, &global_sid_Builtin
)) {
1992 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
1995 /* Still ask the internal LSA and SAMR server about the local domain */
1996 if (skip_connection
|| connection_ok(domain
)) {
1997 if (!domain
->initialized
) {
1998 set_dc_type_and_flags(domain
);
2000 return NT_STATUS_OK
;
2003 invalidate_cm_connection(domain
);
2005 if (!domain
->primary
&& !domain
->initialized
) {
2007 * Before we connect to a trust, work out if it is an
2008 * AD domain by asking our own domain.
2010 set_dc_type_and_flags_trustinfo(domain
);
2013 result
= cm_open_connection(domain
, &domain
->conn
, need_rw_dc
);
2015 if (NT_STATUS_IS_OK(result
) && !domain
->initialized
) {
2016 set_dc_type_and_flags(domain
);
2022 NTSTATUS
init_dc_connection(struct winbindd_domain
*domain
, bool need_rw_dc
)
2024 if (dom_sid_equal(&domain
->sid
, &global_sid_Builtin
)) {
2025 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
2028 SMB_ASSERT(wb_child_domain() || idmap_child());
2030 return init_dc_connection_network(domain
, need_rw_dc
);
2033 static NTSTATUS
init_dc_connection_rpc(struct winbindd_domain
*domain
, bool need_rw_dc
)
2037 status
= init_dc_connection(domain
, need_rw_dc
);
2038 if (!NT_STATUS_IS_OK(status
)) {
2042 if (!domain
->internal
&& domain
->conn
.cli
== NULL
) {
2043 /* happens for trusted domains without inbound trust */
2044 return NT_STATUS_TRUSTED_DOMAIN_FAILURE
;
2047 return NT_STATUS_OK
;
2050 /******************************************************************************
2051 Set the trust flags (direction and forest location) for a domain
2052 ******************************************************************************/
2054 static bool set_dc_type_and_flags_trustinfo( struct winbindd_domain
*domain
)
2056 struct winbindd_domain
*our_domain
;
2057 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
2059 struct netr_DomainTrustList trusts
;
2061 uint32_t flags
= (NETR_TRUST_FLAG_IN_FOREST
|
2062 NETR_TRUST_FLAG_OUTBOUND
|
2063 NETR_TRUST_FLAG_INBOUND
);
2064 struct rpc_pipe_client
*cli
;
2065 TALLOC_CTX
*mem_ctx
= NULL
;
2066 struct dcerpc_binding_handle
*b
;
2070 * On a DC we loaded all trusts
2071 * from configuration and never learn
2077 DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s\n", domain
->name
));
2079 /* Our primary domain doesn't need to worry about trust flags.
2080 Force it to go through the network setup */
2081 if ( domain
->primary
) {
2085 mem_ctx
= talloc_stackframe();
2086 our_domain
= find_our_domain();
2087 if (our_domain
->internal
) {
2088 result
= init_dc_connection(our_domain
, false);
2089 if (!NT_STATUS_IS_OK(result
)) {
2090 DEBUG(3,("set_dc_type_and_flags_trustinfo: "
2091 "Not able to make a connection to our domain: %s\n",
2092 nt_errstr(result
)));
2093 TALLOC_FREE(mem_ctx
);
2098 /* This won't work unless our domain is AD */
2099 if ( !our_domain
->active_directory
) {
2100 TALLOC_FREE(mem_ctx
);
2104 if (our_domain
->internal
) {
2105 result
= wb_open_internal_pipe(mem_ctx
, &ndr_table_netlogon
, &cli
);
2106 } else if (!connection_ok(our_domain
)) {
2107 DEBUG(3,("set_dc_type_and_flags_trustinfo: "
2108 "No connection to our domain!\n"));
2109 TALLOC_FREE(mem_ctx
);
2112 result
= cm_connect_netlogon(our_domain
, &cli
);
2115 if (!NT_STATUS_IS_OK(result
)) {
2116 DEBUG(5, ("set_dc_type_and_flags_trustinfo: Could not open "
2117 "a connection to %s for PIPE_NETLOGON (%s)\n",
2118 domain
->name
, nt_errstr(result
)));
2119 TALLOC_FREE(mem_ctx
);
2122 b
= cli
->binding_handle
;
2124 /* Use DsEnumerateDomainTrusts to get us the trust direction and type. */
2125 result
= dcerpc_netr_DsrEnumerateDomainTrusts(b
, mem_ctx
,
2130 if (!NT_STATUS_IS_OK(result
)) {
2131 DEBUG(0,("set_dc_type_and_flags_trustinfo: "
2132 "failed to query trusted domain list: %s\n",
2133 nt_errstr(result
)));
2134 TALLOC_FREE(mem_ctx
);
2137 if (!W_ERROR_IS_OK(werr
)) {
2138 DEBUG(0,("set_dc_type_and_flags_trustinfo: "
2139 "failed to query trusted domain list: %s\n",
2141 TALLOC_FREE(mem_ctx
);
2145 /* Now find the domain name and get the flags */
2147 for ( i
=0; i
<trusts
.count
; i
++ ) {
2148 if ( strequal( domain
->name
, trusts
.array
[i
].netbios_name
) ) {
2149 domain
->domain_flags
= trusts
.array
[i
].trust_flags
;
2150 domain
->domain_type
= trusts
.array
[i
].trust_type
;
2151 domain
->domain_trust_attribs
= trusts
.array
[i
].trust_attributes
;
2153 if ( domain
->domain_type
== LSA_TRUST_TYPE_UPLEVEL
)
2154 domain
->active_directory
= True
;
2156 DEBUG(5,("set_dc_type_and_flags_trustinfo: domain %s is %s"
2157 "running active directory.\n", domain
->name
,
2158 domain
->active_directory
? "" : "NOT "));
2160 domain
->can_do_ncacn_ip_tcp
= domain
->active_directory
;
2162 domain
->initialized
= True
;
2168 TALLOC_FREE(mem_ctx
);
2170 return domain
->initialized
;
2173 /******************************************************************************
2174 We can 'sense' certain things about the DC by it's replies to certain
2177 This tells us if this particular remote server is Active Directory, and if it
2179 ******************************************************************************/
2181 static void set_dc_type_and_flags_connect( struct winbindd_domain
*domain
)
2183 NTSTATUS status
, result
;
2184 NTSTATUS close_status
= NT_STATUS_UNSUCCESSFUL
;
2185 TALLOC_CTX
*mem_ctx
= NULL
;
2186 struct rpc_pipe_client
*cli
= NULL
;
2187 struct policy_handle pol
= { .handle_type
= 0 };
2188 union lsa_PolicyInformation
*lsa_info
= NULL
;
2189 union lsa_revision_info out_revision_info
= {
2194 uint32_t out_version
= 0;
2196 if (!domain
->internal
&& !connection_ok(domain
)) {
2200 mem_ctx
= talloc_init("set_dc_type_and_flags on domain %s\n",
2203 DEBUG(1, ("set_dc_type_and_flags_connect: talloc_init() failed\n"));
2207 DEBUG(5, ("set_dc_type_and_flags_connect: domain %s\n", domain
->name
));
2209 if (domain
->internal
) {
2210 status
= wb_open_internal_pipe(mem_ctx
,
2214 status
= cli_rpc_pipe_open_noauth(domain
->conn
.cli
,
2215 &ndr_table_lsarpc
, &cli
);
2217 if (!NT_STATUS_IS_OK(status
)) {
2218 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
2219 "PI_LSARPC on domain %s: (%s)\n",
2220 domain
->name
, nt_errstr(status
)));
2222 TALLOC_FREE(mem_ctx
);
2226 status
= dcerpc_lsa_open_policy_fallback(cli
->binding_handle
,
2228 cli
->srv_name_slash
,
2230 SEC_FLAG_MAXIMUM_ALLOWED
,
2236 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(result
)) {
2237 /* This particular query is exactly what Win2k clients use
2238 to determine that the DC is active directory */
2239 status
= dcerpc_lsa_QueryInfoPolicy2(cli
->binding_handle
, mem_ctx
,
2241 LSA_POLICY_INFO_DNS
,
2247 * If the status and result will not be OK we will fallback to
2250 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(result
)) {
2251 domain
->active_directory
= True
;
2253 if (lsa_info
->dns
.name
.string
) {
2254 if (!strequal(domain
->name
, lsa_info
->dns
.name
.string
))
2256 DEBUG(1, ("set_dc_type_and_flags_connect: DC "
2257 "for domain %s claimed it was a DC "
2258 "for domain %s, refusing to "
2261 lsa_info
->dns
.name
.string
));
2263 TALLOC_FREE(mem_ctx
);
2266 talloc_free(domain
->name
);
2267 domain
->name
= talloc_strdup(domain
,
2268 lsa_info
->dns
.name
.string
);
2269 if (domain
->name
== NULL
) {
2274 if (lsa_info
->dns
.dns_domain
.string
) {
2275 if (domain
->alt_name
!= NULL
&&
2276 !strequal(domain
->alt_name
,
2277 lsa_info
->dns
.dns_domain
.string
))
2279 DEBUG(1, ("set_dc_type_and_flags_connect: DC "
2280 "for domain %s (%s) claimed it was "
2281 "a DC for domain %s, refusing to "
2283 domain
->alt_name
, domain
->name
,
2284 lsa_info
->dns
.dns_domain
.string
));
2286 TALLOC_FREE(mem_ctx
);
2289 talloc_free(domain
->alt_name
);
2291 talloc_strdup(domain
,
2292 lsa_info
->dns
.dns_domain
.string
);
2293 if (domain
->alt_name
== NULL
) {
2298 /* See if we can set some domain trust flags about
2301 if (lsa_info
->dns
.dns_forest
.string
) {
2302 talloc_free(domain
->forest_name
);
2303 domain
->forest_name
=
2304 talloc_strdup(domain
,
2305 lsa_info
->dns
.dns_forest
.string
);
2306 if (domain
->forest_name
== NULL
) {
2310 if (strequal(domain
->forest_name
, domain
->alt_name
)) {
2311 domain
->domain_flags
|= NETR_TRUST_FLAG_TREEROOT
;
2315 if (lsa_info
->dns
.sid
) {
2316 if (!is_null_sid(&domain
->sid
) &&
2317 !dom_sid_equal(&domain
->sid
,
2320 struct dom_sid_buf buf1
, buf2
;
2321 DEBUG(1, ("set_dc_type_and_flags_connect: DC "
2322 "for domain %s (%s) claimed it was "
2323 "a DC for domain %s, refusing to "
2325 dom_sid_str_buf(&domain
->sid
, &buf1
),
2327 dom_sid_str_buf(lsa_info
->dns
.sid
,
2330 TALLOC_FREE(mem_ctx
);
2333 sid_copy(&domain
->sid
, lsa_info
->dns
.sid
);
2336 domain
->active_directory
= False
;
2338 status
= rpccli_lsa_open_policy(cli
, mem_ctx
, True
,
2339 SEC_FLAG_MAXIMUM_ALLOWED
,
2342 if (!NT_STATUS_IS_OK(status
)) {
2346 status
= dcerpc_lsa_QueryInfoPolicy(cli
->binding_handle
, mem_ctx
,
2348 LSA_POLICY_INFO_ACCOUNT_DOMAIN
,
2351 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(result
)) {
2353 if (lsa_info
->account_domain
.name
.string
) {
2354 if (!strequal(domain
->name
,
2355 lsa_info
->account_domain
.name
.string
))
2358 ("set_dc_type_and_flags_connect: "
2359 "DC for domain %s claimed it was"
2360 " a DC for domain %s, refusing "
2361 "to initialize\n", domain
->name
,
2363 account_domain
.name
.string
));
2365 TALLOC_FREE(mem_ctx
);
2368 talloc_free(domain
->name
);
2370 talloc_strdup(domain
,
2371 lsa_info
->account_domain
.name
.string
);
2374 if (lsa_info
->account_domain
.sid
) {
2375 if (!is_null_sid(&domain
->sid
) &&
2376 !dom_sid_equal(&domain
->sid
,
2377 lsa_info
->account_domain
.sid
))
2379 struct dom_sid_buf buf1
, buf2
;
2381 ("set_dc_type_and_flags_connect: "
2382 "DC for domain %s (%s) claimed "
2383 "it was a DC for domain %s, "
2384 "refusing to initialize\n",
2386 &domain
->sid
, &buf1
),
2389 lsa_info
->account_domain
.sid
,
2392 TALLOC_FREE(mem_ctx
);
2395 sid_copy(&domain
->sid
, lsa_info
->account_domain
.sid
);
2400 if (is_valid_policy_hnd(&pol
)) {
2401 dcerpc_lsa_Close(cli
->binding_handle
,
2407 DEBUG(5,("set_dc_type_and_flags_connect: domain %s is %srunning active directory.\n",
2408 domain
->name
, domain
->active_directory
? "" : "NOT "));
2410 domain
->can_do_ncacn_ip_tcp
= domain
->active_directory
;
2414 TALLOC_FREE(mem_ctx
);
2416 domain
->initialized
= True
;
2419 /**********************************************************************
2420 Set the domain_flags (trust attributes, domain operating modes, etc...
2421 ***********************************************************************/
2423 static void set_dc_type_and_flags( struct winbindd_domain
*domain
)
2427 * On a DC we loaded all trusts
2428 * from configuration and never learn
2434 /* we always have to contact our primary domain */
2435 if (domain
->primary
|| domain
->internal
) {
2437 * primary and internal domains are
2438 * are already completely
2439 * setup via init_domain_list()
2440 * calling add_trusted_domain()
2442 * There's no need to ask the
2443 * server again, if it hosts an AD
2446 domain
->initialized
= true;
2450 /* Use our DC to get the information if possible */
2452 if ( !set_dc_type_and_flags_trustinfo( domain
) ) {
2453 /* Otherwise, fallback to contacting the
2455 set_dc_type_and_flags_connect( domain
);
2463 /**********************************************************************
2464 ***********************************************************************/
2466 static NTSTATUS
cm_get_schannel_creds(struct winbindd_domain
*domain
,
2467 struct netlogon_creds_cli_context
**ppdc
)
2469 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
2470 struct rpc_pipe_client
*netlogon_pipe
;
2474 if ((!IS_DC
) && (!domain
->primary
)) {
2475 return NT_STATUS_TRUSTED_DOMAIN_FAILURE
;
2478 if (domain
->conn
.netlogon_creds_ctx
!= NULL
) {
2479 *ppdc
= domain
->conn
.netlogon_creds_ctx
;
2480 return NT_STATUS_OK
;
2483 result
= cm_connect_netlogon_secure(domain
, &netlogon_pipe
, ppdc
);
2484 if (!NT_STATUS_IS_OK(result
)) {
2488 return NT_STATUS_OK
;
2491 NTSTATUS
cm_connect_sam(struct winbindd_domain
*domain
, TALLOC_CTX
*mem_ctx
,
2493 struct rpc_pipe_client
**cli
, struct policy_handle
*sam_handle
)
2495 struct winbindd_cm_conn
*conn
;
2496 NTSTATUS status
, result
;
2497 struct netlogon_creds_cli_context
*p_creds
;
2498 struct cli_credentials
*creds
= NULL
;
2499 bool retry
= false; /* allow one retry attempt for expired session */
2500 const char *remote_name
= NULL
;
2501 const struct sockaddr_storage
*remote_sockaddr
= NULL
;
2502 bool sealed_pipes
= true;
2503 bool strong_key
= true;
2505 if (sid_check_is_our_sam(&domain
->sid
)) {
2506 if (domain
->rodc
== false || need_rw_dc
== false) {
2507 return open_internal_samr_conn(mem_ctx
, domain
, cli
, sam_handle
);
2513 * In theory we should not use SAMR within
2514 * winbindd at all, but that's a larger task to
2515 * remove this and avoid breaking existing
2518 * At least as AD DC we have the restriction
2519 * to avoid SAMR against trusted domains,
2520 * as there're no existing setups.
2522 return NT_STATUS_REQUEST_NOT_ACCEPTED
;
2526 status
= init_dc_connection_rpc(domain
, need_rw_dc
);
2527 if (!NT_STATUS_IS_OK(status
)) {
2531 conn
= &domain
->conn
;
2533 if (rpccli_is_connected(conn
->samr_pipe
)) {
2537 TALLOC_FREE(conn
->samr_pipe
);
2540 * No SAMR pipe yet. Attempt to get an NTLMSSP SPNEGO authenticated
2541 * sign and sealed pipe using the machine account password by
2542 * preference. If we can't - try schannel, if that fails, try
2546 result
= winbindd_get_trust_credentials(domain
,
2548 false, /* netlogon */
2549 true, /* ipc_fallback */
2551 if (!NT_STATUS_IS_OK(result
)) {
2552 DEBUG(10, ("cm_connect_sam: No user available for "
2553 "domain %s, trying schannel\n", domain
->name
));
2557 if (cli_credentials_is_anonymous(creds
)) {
2561 remote_name
= smbXcli_conn_remote_name(conn
->cli
->conn
);
2562 remote_sockaddr
= smbXcli_conn_remote_sockaddr(conn
->cli
->conn
);
2565 * We have an authenticated connection. Use a SPNEGO
2566 * authenticated SAMR pipe with sign & seal.
2568 status
= cli_rpc_pipe_open_with_creds(conn
->cli
,
2571 DCERPC_AUTH_TYPE_SPNEGO
,
2578 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)
2580 invalidate_cm_connection(domain
);
2585 if (!NT_STATUS_IS_OK(status
)) {
2586 DEBUG(10,("cm_connect_sam: failed to connect to SAMR "
2587 "pipe for domain %s using NTLMSSP "
2588 "authenticated pipe: user %s. Error was "
2589 "%s\n", domain
->name
,
2590 cli_credentials_get_unparsed_name(creds
, talloc_tos()),
2591 nt_errstr(status
)));
2595 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for "
2596 "domain %s using NTLMSSP authenticated "
2597 "pipe: user %s\n", domain
->name
,
2598 cli_credentials_get_unparsed_name(creds
, talloc_tos())));
2600 status
= dcerpc_samr_Connect2(conn
->samr_pipe
->binding_handle
, mem_ctx
,
2601 conn
->samr_pipe
->desthost
,
2602 SEC_FLAG_MAXIMUM_ALLOWED
,
2603 &conn
->sam_connect_handle
,
2606 if (NT_STATUS_EQUAL(status
, NT_STATUS_IO_DEVICE_ERROR
) && !retry
) {
2607 invalidate_cm_connection(domain
);
2608 TALLOC_FREE(conn
->samr_pipe
);
2613 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(result
)) {
2616 if (NT_STATUS_IS_OK(status
)) {
2620 DEBUG(10,("cm_connect_sam: ntlmssp-sealed dcerpc_samr_Connect2 "
2621 "failed for domain %s, error was %s. Trying schannel\n",
2622 domain
->name
, nt_errstr(status
) ));
2623 TALLOC_FREE(conn
->samr_pipe
);
2627 /* Fall back to schannel if it's a W2K pre-SP1 box. */
2629 status
= cm_get_schannel_creds(domain
, &p_creds
);
2630 if (!NT_STATUS_IS_OK(status
)) {
2631 /* If this call fails - conn->cli can now be NULL ! */
2632 DEBUG(10, ("cm_connect_sam: Could not get schannel auth info "
2633 "for domain %s (error %s), trying anon\n",
2635 nt_errstr(status
) ));
2639 status
= cli_rpc_pipe_open_schannel_with_creds(
2640 conn
->cli
, &ndr_table_samr
, NCACN_NP
, p_creds
,
2645 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)
2647 invalidate_cm_connection(domain
);
2652 if (!NT_STATUS_IS_OK(status
)) {
2653 DEBUG(10,("cm_connect_sam: failed to connect to SAMR pipe for "
2654 "domain %s using schannel. Error was %s\n",
2655 domain
->name
, nt_errstr(status
) ));
2658 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for domain %s using "
2659 "schannel.\n", domain
->name
));
2661 status
= dcerpc_samr_Connect2(conn
->samr_pipe
->binding_handle
, mem_ctx
,
2662 conn
->samr_pipe
->desthost
,
2663 SEC_FLAG_MAXIMUM_ALLOWED
,
2664 &conn
->sam_connect_handle
,
2667 if (NT_STATUS_EQUAL(status
, NT_STATUS_IO_DEVICE_ERROR
) && !retry
) {
2668 invalidate_cm_connection(domain
);
2669 TALLOC_FREE(conn
->samr_pipe
);
2674 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(result
)) {
2677 if (NT_STATUS_IS_OK(status
)) {
2680 DEBUG(10,("cm_connect_sam: schannel-sealed dcerpc_samr_Connect2 failed "
2681 "for domain %s, error was %s. Trying anonymous\n",
2682 domain
->name
, nt_errstr(status
) ));
2683 TALLOC_FREE(conn
->samr_pipe
);
2687 sealed_pipes
= lp_winbind_sealed_pipes();
2688 sealed_pipes
= lp_parm_bool(-1, "winbind sealed pipes",
2691 strong_key
= lp_require_strong_key();
2692 strong_key
= lp_parm_bool(-1, "require strong key",
2696 /* Finally fall back to anonymous. */
2697 if (sealed_pipes
|| strong_key
) {
2698 status
= NT_STATUS_DOWNGRADE_DETECTED
;
2699 DEBUG(1, ("Unwilling to make SAMR connection to domain %s "
2700 "without connection level security, "
2701 "must set 'winbind sealed pipes:%s = false' and "
2702 "'require strong key:%s = false' to proceed: %s\n",
2703 domain
->name
, domain
->name
, domain
->name
,
2704 nt_errstr(status
)));
2707 status
= cli_rpc_pipe_open_noauth(conn
->cli
, &ndr_table_samr
,
2710 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)
2712 invalidate_cm_connection(domain
);
2717 if (!NT_STATUS_IS_OK(status
)) {
2721 status
= dcerpc_samr_Connect2(conn
->samr_pipe
->binding_handle
, mem_ctx
,
2722 conn
->samr_pipe
->desthost
,
2723 SEC_FLAG_MAXIMUM_ALLOWED
,
2724 &conn
->sam_connect_handle
,
2727 if (NT_STATUS_EQUAL(status
, NT_STATUS_IO_DEVICE_ERROR
) && !retry
) {
2728 invalidate_cm_connection(domain
);
2729 TALLOC_FREE(conn
->samr_pipe
);
2734 if (!NT_STATUS_IS_OK(status
)) {
2735 DEBUG(10,("cm_connect_sam: rpccli_samr_Connect2 failed "
2736 "for domain %s Error was %s\n",
2737 domain
->name
, nt_errstr(status
) ));
2740 if (!NT_STATUS_IS_OK(result
)) {
2742 DEBUG(10,("cm_connect_sam: dcerpc_samr_Connect2 failed "
2743 "for domain %s Error was %s\n",
2744 domain
->name
, nt_errstr(result
)));
2749 status
= dcerpc_samr_OpenDomain(conn
->samr_pipe
->binding_handle
,
2751 &conn
->sam_connect_handle
,
2752 SEC_FLAG_MAXIMUM_ALLOWED
,
2754 &conn
->sam_domain_handle
,
2756 if (!NT_STATUS_IS_OK(status
)) {
2763 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
2765 * if we got access denied, we might just have no access rights
2766 * to talk to the remote samr server server (e.g. when we are a
2767 * PDC and we are connecting a w2k8 pdc via an interdomain
2768 * trust). In that case do not invalidate the whole connection
2771 TALLOC_FREE(conn
->samr_pipe
);
2772 ZERO_STRUCT(conn
->sam_domain_handle
);
2774 } else if (!NT_STATUS_IS_OK(status
)) {
2775 invalidate_cm_connection(domain
);
2779 *cli
= conn
->samr_pipe
;
2780 *sam_handle
= conn
->sam_domain_handle
;
2784 /**********************************************************************
2785 open an schanneld ncacn_ip_tcp connection to LSA
2786 ***********************************************************************/
2788 static NTSTATUS
cm_connect_lsa_tcp(struct winbindd_domain
*domain
,
2789 TALLOC_CTX
*mem_ctx
,
2790 struct rpc_pipe_client
**cli
)
2792 struct winbindd_cm_conn
*conn
;
2793 struct netlogon_creds_cli_context
*p_creds
= NULL
;
2795 const char *remote_name
= NULL
;
2796 const struct sockaddr_storage
*remote_sockaddr
= NULL
;
2798 DEBUG(10,("cm_connect_lsa_tcp\n"));
2800 status
= init_dc_connection_rpc(domain
, false);
2801 if (!NT_STATUS_IS_OK(status
)) {
2805 conn
= &domain
->conn
;
2808 * rpccli_is_connected handles more error cases
2810 if (rpccli_is_connected(conn
->lsa_pipe_tcp
)) {
2814 TALLOC_FREE(conn
->lsa_pipe_tcp
);
2816 status
= cm_get_schannel_creds(domain
, &p_creds
);
2817 if (!NT_STATUS_IS_OK(status
)) {
2821 remote_name
= smbXcli_conn_remote_name(conn
->cli
->conn
);
2822 remote_sockaddr
= smbXcli_conn_remote_sockaddr(conn
->cli
->conn
);
2824 status
= cli_rpc_pipe_open_schannel_with_creds(
2831 &conn
->lsa_pipe_tcp
);
2832 if (!NT_STATUS_IS_OK(status
)) {
2833 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key failed: %s\n",
2834 nt_errstr(status
)));
2839 if (!NT_STATUS_IS_OK(status
)) {
2840 TALLOC_FREE(conn
->lsa_pipe_tcp
);
2844 *cli
= conn
->lsa_pipe_tcp
;
2849 NTSTATUS
cm_connect_lsa(struct winbindd_domain
*domain
, TALLOC_CTX
*mem_ctx
,
2850 struct rpc_pipe_client
**cli
, struct policy_handle
*lsa_policy
)
2852 struct winbindd_cm_conn
*conn
;
2853 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
2854 struct netlogon_creds_cli_context
*p_creds
;
2855 struct cli_credentials
*creds
= NULL
;
2856 bool retry
= false; /* allow one retry attempt for expired session */
2857 const char *remote_name
= NULL
;
2858 const struct sockaddr_storage
*remote_sockaddr
= NULL
;
2859 bool sealed_pipes
= true;
2860 bool strong_key
= true;
2861 bool require_schannel
= false;
2864 result
= init_dc_connection_rpc(domain
, false);
2865 if (!NT_STATUS_IS_OK(result
))
2868 conn
= &domain
->conn
;
2870 if (rpccli_is_connected(conn
->lsa_pipe
)) {
2874 TALLOC_FREE(conn
->lsa_pipe
);
2877 domain
->secure_channel_type
!= SEC_CHAN_NULL
)
2880 * Make sure we only use schannel as DC
2881 * or with a direct trust
2883 require_schannel
= true;
2887 result
= winbindd_get_trust_credentials(domain
,
2889 false, /* netlogon */
2890 true, /* ipc_fallback */
2892 if (!NT_STATUS_IS_OK(result
)) {
2893 DEBUG(10, ("cm_connect_lsa: No user available for "
2894 "domain %s, trying schannel\n", domain
->name
));
2898 if (cli_credentials_is_anonymous(creds
)) {
2902 remote_name
= smbXcli_conn_remote_name(conn
->cli
->conn
);
2903 remote_sockaddr
= smbXcli_conn_remote_sockaddr(conn
->cli
->conn
);
2906 * We have an authenticated connection. Use a SPNEGO
2907 * authenticated LSA pipe with sign & seal.
2909 result
= cli_rpc_pipe_open_with_creds
2910 (conn
->cli
, &ndr_table_lsarpc
, NCACN_NP
,
2911 DCERPC_AUTH_TYPE_SPNEGO
,
2918 if (NT_STATUS_EQUAL(result
, NT_STATUS_NETWORK_SESSION_EXPIRED
)
2920 invalidate_cm_connection(domain
);
2925 if (!NT_STATUS_IS_OK(result
)) {
2926 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
2927 "domain %s using NTLMSSP authenticated pipe: user "
2928 "%s. Error was %s. Trying schannel.\n",
2930 cli_credentials_get_unparsed_name(creds
, talloc_tos()),
2931 nt_errstr(result
)));
2935 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
2936 "NTLMSSP authenticated pipe: user %s\n",
2937 domain
->name
, cli_credentials_get_unparsed_name(creds
, talloc_tos())));
2939 result
= rpccli_lsa_open_policy(conn
->lsa_pipe
, mem_ctx
, True
,
2940 SEC_FLAG_MAXIMUM_ALLOWED
,
2942 if (NT_STATUS_EQUAL(result
, NT_STATUS_IO_DEVICE_ERROR
) && !retry
) {
2943 invalidate_cm_connection(domain
);
2944 TALLOC_FREE(conn
->lsa_pipe
);
2949 if (NT_STATUS_IS_OK(result
)) {
2953 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
2956 TALLOC_FREE(conn
->lsa_pipe
);
2960 /* Fall back to schannel if it's a W2K pre-SP1 box. */
2962 result
= cm_get_schannel_creds(domain
, &p_creds
);
2963 if (!NT_STATUS_IS_OK(result
)) {
2964 /* If this call fails - conn->cli can now be NULL ! */
2965 DEBUG(10, ("cm_connect_lsa: Could not get schannel auth info "
2966 "for domain %s (error %s), trying anon\n",
2968 nt_errstr(result
) ));
2973 result
= cli_rpc_pipe_open_schannel_with_creds(
2974 conn
->cli
, &ndr_table_lsarpc
, NCACN_NP
, p_creds
,
2979 if (NT_STATUS_EQUAL(result
, NT_STATUS_NETWORK_SESSION_EXPIRED
)
2981 invalidate_cm_connection(domain
);
2986 if (!NT_STATUS_IS_OK(result
)) {
2987 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
2988 "domain %s using schannel. Error was %s\n",
2989 domain
->name
, nt_errstr(result
) ));
2992 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
2993 "schannel.\n", domain
->name
));
2995 result
= rpccli_lsa_open_policy(conn
->lsa_pipe
, mem_ctx
, True
,
2996 SEC_FLAG_MAXIMUM_ALLOWED
,
2999 if (NT_STATUS_EQUAL(result
, NT_STATUS_IO_DEVICE_ERROR
) && !retry
) {
3000 invalidate_cm_connection(domain
);
3001 TALLOC_FREE(conn
->lsa_pipe
);
3006 if (NT_STATUS_IS_OK(result
)) {
3010 if (require_schannel
) {
3012 * Make sure we only use schannel as DC
3013 * or with a direct trust
3018 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
3021 TALLOC_FREE(conn
->lsa_pipe
);
3025 if (require_schannel
) {
3027 * Make sure we only use schannel as DC
3028 * or with a direct trust
3033 sealed_pipes
= lp_winbind_sealed_pipes();
3034 sealed_pipes
= lp_parm_bool(-1, "winbind sealed pipes",
3037 strong_key
= lp_require_strong_key();
3038 strong_key
= lp_parm_bool(-1, "require strong key",
3042 /* Finally fall back to anonymous. */
3043 if (sealed_pipes
|| strong_key
) {
3044 result
= NT_STATUS_DOWNGRADE_DETECTED
;
3045 DEBUG(1, ("Unwilling to make LSA connection to domain %s "
3046 "without connection level security, "
3047 "must set 'winbind sealed pipes:%s = false' and "
3048 "'require strong key:%s = false' to proceed: %s\n",
3049 domain
->name
, domain
->name
, domain
->name
,
3050 nt_errstr(result
)));
3054 result
= cli_rpc_pipe_open_noauth(conn
->cli
,
3058 if (NT_STATUS_EQUAL(result
, NT_STATUS_NETWORK_SESSION_EXPIRED
)
3060 invalidate_cm_connection(domain
);
3065 if (!NT_STATUS_IS_OK(result
)) {
3069 result
= rpccli_lsa_open_policy(conn
->lsa_pipe
, mem_ctx
, True
,
3070 SEC_FLAG_MAXIMUM_ALLOWED
,
3073 if (NT_STATUS_EQUAL(result
, NT_STATUS_IO_DEVICE_ERROR
) && !retry
) {
3074 invalidate_cm_connection(domain
);
3075 TALLOC_FREE(conn
->lsa_pipe
);
3081 if (!NT_STATUS_IS_OK(result
)) {
3082 invalidate_cm_connection(domain
);
3086 *cli
= conn
->lsa_pipe
;
3087 *lsa_policy
= conn
->lsa_policy
;
3091 /****************************************************************************
3092 Open a LSA connection to a DC, suitable for LSA lookup calls.
3093 ****************************************************************************/
3095 NTSTATUS
cm_connect_lsat(struct winbindd_domain
*domain
,
3096 TALLOC_CTX
*mem_ctx
,
3097 struct rpc_pipe_client
**cli
,
3098 struct policy_handle
*lsa_policy
)
3102 if (domain
->can_do_ncacn_ip_tcp
) {
3103 status
= cm_connect_lsa_tcp(domain
, mem_ctx
, cli
);
3104 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
) ||
3105 NT_STATUS_EQUAL(status
, NT_STATUS_RPC_SEC_PKG_ERROR
) ||
3106 NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_ACCESS_DENIED
)) {
3107 invalidate_cm_connection(domain
);
3108 status
= cm_connect_lsa_tcp(domain
, mem_ctx
, cli
);
3110 if (NT_STATUS_IS_OK(status
)) {
3115 * we tried twice to connect via ncan_ip_tcp and schannel and
3116 * failed - maybe it is a trusted domain we can't connect to ?
3117 * do not try tcp next time - gd
3119 * This also prevents NETLOGON over TCP
3121 domain
->can_do_ncacn_ip_tcp
= false;
3124 status
= cm_connect_lsa(domain
, mem_ctx
, cli
, lsa_policy
);
3129 /****************************************************************************
3130 Open the netlogon pipe to this DC.
3131 ****************************************************************************/
3133 static NTSTATUS
cm_connect_netlogon_transport(struct winbindd_domain
*domain
,
3134 enum dcerpc_transport_t transport
,
3135 struct rpc_pipe_client
**cli
)
3137 struct messaging_context
*msg_ctx
= global_messaging_context();
3138 struct winbindd_cm_conn
*conn
;
3140 enum netr_SchannelType sec_chan_type
;
3141 struct cli_credentials
*creds
= NULL
;
3142 const char *remote_name
= NULL
;
3143 const struct sockaddr_storage
*remote_sockaddr
= NULL
;
3148 if (domain
->secure_channel_type
== SEC_CHAN_NULL
) {
3150 * Make sure we don't even try to
3151 * connect to a foreign domain
3152 * without a direct outbound trust.
3154 return NT_STATUS_NO_TRUST_LSA_SECRET
;
3158 result
= init_dc_connection_rpc(domain
, domain
->rodc
);
3159 if (!NT_STATUS_IS_OK(result
)) {
3163 conn
= &domain
->conn
;
3165 if (rpccli_is_connected(conn
->netlogon_pipe
)) {
3166 *cli
= conn
->netlogon_pipe
;
3167 return NT_STATUS_OK
;
3170 TALLOC_FREE(conn
->netlogon_pipe
);
3171 TALLOC_FREE(conn
->netlogon_creds_ctx
);
3173 remote_name
= smbXcli_conn_remote_name(conn
->cli
->conn
);
3174 remote_sockaddr
= smbXcli_conn_remote_sockaddr(conn
->cli
->conn
);
3176 result
= winbindd_get_trust_credentials(domain
,
3178 true, /* netlogon */
3179 false, /* ipc_fallback */
3181 if (!NT_STATUS_IS_OK(result
)) {
3182 DBG_DEBUG("No user available for domain %s when trying "
3183 "schannel\n", domain
->name
);
3184 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
3187 if (cli_credentials_is_anonymous(creds
)) {
3188 DBG_WARNING("get_trust_credential only gave anonymous for %s, "
3189 "unable to make get NETLOGON credentials\n",
3191 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
3194 sec_chan_type
= cli_credentials_get_secure_channel_type(creds
);
3195 if (sec_chan_type
== SEC_CHAN_NULL
) {
3196 if (transport
== NCACN_IP_TCP
) {
3197 DBG_NOTICE("get_secure_channel_type gave SEC_CHAN_NULL "
3198 "for %s, deny NCACN_IP_TCP and let the "
3199 "caller fallback to NCACN_NP.\n",
3201 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
3204 DBG_NOTICE("get_secure_channel_type gave SEC_CHAN_NULL for %s, "
3205 "fallback to noauth on NCACN_NP.\n",
3208 result
= cli_rpc_pipe_open_noauth_transport(
3211 &ndr_table_netlogon
,
3214 &conn
->netlogon_pipe
);
3215 if (!NT_STATUS_IS_OK(result
)) {
3216 invalidate_cm_connection(domain
);
3220 *cli
= conn
->netlogon_pipe
;
3221 return NT_STATUS_OK
;
3224 result
= rpccli_create_netlogon_creds_ctx(creds
,
3228 &conn
->netlogon_creds_ctx
);
3229 if (!NT_STATUS_IS_OK(result
)) {
3230 DEBUG(1, ("rpccli_create_netlogon_creds failed for %s, "
3231 "unable to create NETLOGON credentials: %s\n",
3232 domain
->name
, nt_errstr(result
)));
3236 result
= rpccli_connect_netlogon(conn
->cli
,
3240 conn
->netlogon_creds_ctx
,
3241 conn
->netlogon_force_reauth
, creds
,
3242 &conn
->netlogon_pipe
);
3243 conn
->netlogon_force_reauth
= false;
3244 if (!NT_STATUS_IS_OK(result
)) {
3245 DBG_DEBUG("rpccli_connect_netlogon failed: %s\n",
3250 *cli
= conn
->netlogon_pipe
;
3251 return NT_STATUS_OK
;
3254 /****************************************************************************
3255 Open a NETLOGON connection to a DC, suitable for SamLogon calls.
3256 ****************************************************************************/
3258 NTSTATUS
cm_connect_netlogon(struct winbindd_domain
*domain
,
3259 struct rpc_pipe_client
**cli
)
3263 status
= init_dc_connection_rpc(domain
, domain
->rodc
);
3264 if (!NT_STATUS_IS_OK(status
)) {
3268 if (domain
->active_directory
&& domain
->can_do_ncacn_ip_tcp
) {
3269 status
= cm_connect_netlogon_transport(domain
, NCACN_IP_TCP
, cli
);
3270 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
) ||
3271 NT_STATUS_EQUAL(status
, NT_STATUS_RPC_SEC_PKG_ERROR
) ||
3272 NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_ACCESS_DENIED
)) {
3273 invalidate_cm_connection(domain
);
3274 status
= cm_connect_netlogon_transport(domain
, NCACN_IP_TCP
, cli
);
3276 if (NT_STATUS_IS_OK(status
)) {
3281 * we tried twice to connect via ncan_ip_tcp and schannel and
3282 * failed - maybe it is a trusted domain we can't connect to ?
3283 * do not try tcp next time - gd
3285 * This also prevents LSA over TCP
3287 domain
->can_do_ncacn_ip_tcp
= false;
3290 status
= cm_connect_netlogon_transport(domain
, NCACN_NP
, cli
);
3291 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)) {
3293 * SMB2 session expired, needs reauthentication. Drop
3294 * connection and retry.
3296 invalidate_cm_connection(domain
);
3297 status
= cm_connect_netlogon_transport(domain
, NCACN_NP
, cli
);
3303 NTSTATUS
cm_connect_netlogon_secure(struct winbindd_domain
*domain
,
3304 struct rpc_pipe_client
**cli
,
3305 struct netlogon_creds_cli_context
**ppdc
)
3309 if (domain
->secure_channel_type
== SEC_CHAN_NULL
) {
3310 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
3313 status
= cm_connect_netlogon(domain
, cli
);
3314 if (!NT_STATUS_IS_OK(status
)) {
3318 if (domain
->conn
.netlogon_creds_ctx
== NULL
) {
3319 return NT_STATUS_TRUSTED_DOMAIN_FAILURE
;
3322 *ppdc
= domain
->conn
.netlogon_creds_ctx
;
3323 return NT_STATUS_OK
;
3326 void winbind_msg_ip_dropped(struct messaging_context
*msg_ctx
,
3329 struct server_id server_id
,
3332 struct winbindd_domain
*domain
;
3333 char *freeit
= NULL
;
3337 || (data
->data
== NULL
)
3338 || (data
->length
== 0)
3339 || (data
->data
[data
->length
-1] != '\0')) {
3340 DEBUG(1, ("invalid msg_ip_dropped message: not a valid "
3345 addr
= (char *)data
->data
;
3346 DEBUG(10, ("IP %s dropped\n", addr
));
3348 if (!is_ipaddress(addr
)) {
3351 * Some code sends us ip addresses with the /netmask
3354 slash
= strchr(addr
, '/');
3355 if (slash
== NULL
) {
3356 DEBUG(1, ("invalid msg_ip_dropped message: %s\n",
3360 freeit
= talloc_strndup(talloc_tos(), addr
, slash
-addr
);
3361 if (freeit
== NULL
) {
3362 DEBUG(1, ("talloc failed\n"));
3366 DEBUG(10, ("Stripped /netmask to IP %s\n", addr
));
3369 for (domain
= domain_list(); domain
!= NULL
; domain
= domain
->next
) {
3370 char sockaddr
[INET6_ADDRSTRLEN
];
3372 if (!cli_state_is_connected(domain
->conn
.cli
)) {
3376 print_sockaddr(sockaddr
, sizeof(sockaddr
),
3377 smbXcli_conn_local_sockaddr(domain
->conn
.cli
->conn
));
3379 if (strequal(sockaddr
, addr
)) {
3380 smbXcli_conn_disconnect(domain
->conn
.cli
->conn
, NT_STATUS_OK
);
3383 TALLOC_FREE(freeit
);
3386 void winbind_msg_disconnect_dc(struct messaging_context
*msg_ctx
,
3389 struct server_id server_id
,
3392 struct winbindd_domain
*domain
;
3394 for (domain
= domain_list(); domain
; domain
= domain
->next
) {
3395 if (domain
->internal
) {
3398 invalidate_cm_connection(domain
);