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
++) {
1076 struct samba_sockaddr ss1
= { .u
= { .ss
= (*dcs
)[i
].ss
, }};
1077 struct samba_sockaddr ss2
= { .u
= { .ss
= *pss
, }};
1079 if (sockaddr_equal(&ss1
.u
.sa
, &ss2
.u
.sa
)) {
1084 *dcs
= talloc_realloc(mem_ctx
, *dcs
, struct dc_name_ip
, (*num
)+1);
1089 fstrcpy((*dcs
)[*num
].name
, dcname
);
1090 (*dcs
)[*num
].ss
= *pss
;
1095 static bool add_sockaddr_to_array(TALLOC_CTX
*mem_ctx
,
1096 struct sockaddr_storage
*pss
, uint16_t port
,
1097 struct sockaddr_storage
**addrs
, int *num
)
1099 *addrs
= talloc_realloc(mem_ctx
, *addrs
, struct sockaddr_storage
, (*num
)+1);
1101 if (*addrs
== NULL
) {
1106 (*addrs
)[*num
] = *pss
;
1107 set_sockaddr_port((struct sockaddr
*)&(*addrs
)[*num
], port
);
1114 static bool dcip_check_name_ads(const struct winbindd_domain
*domain
,
1115 struct samba_sockaddr
*sa
,
1116 uint32_t request_flags
,
1117 TALLOC_CTX
*mem_ctx
,
1120 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
1122 ADS_STRUCT
*ads
= NULL
;
1123 ADS_STATUS ads_status
;
1124 char addr
[INET6_ADDRSTRLEN
];
1126 print_sockaddr(addr
, sizeof(addr
), &sa
->u
.ss
);
1127 D_DEBUG("Trying to figure out the DC name for domain '%s' at IP '%s'.\n",
1131 ads
= ads_init(tmp_ctx
,
1137 ads_status
= ADS_ERROR_NT(NT_STATUS_NO_MEMORY
);
1140 ads
->config
.flags
|= request_flags
;
1141 ads
->server
.no_fallback
= true;
1143 ads_status
= ads_connect_cldap_only(ads
);
1144 if (!ADS_ERR_OK(ads_status
)) {
1148 /* We got a cldap packet. */
1149 name
= talloc_strdup(tmp_ctx
, ads
->config
.ldap_server_name
);
1151 ads_status
= ADS_ERROR_NT(NT_STATUS_NO_MEMORY
);
1154 namecache_store(name
, 0x20, 1, sa
);
1156 DBG_DEBUG("CLDAP flags = 0x%"PRIx32
"\n", ads
->config
.flags
);
1158 if (domain
->primary
&& (ads
->config
.flags
& NBT_SERVER_KDC
)) {
1159 if (ads_closest_dc(ads
)) {
1160 char *sitename
= sitename_fetch(tmp_ctx
,
1163 /* We're going to use this KDC for this realm/domain.
1164 If we are using sites, then force the krb5 libs
1167 create_local_private_krb5_conf_for_domain(domain
->alt_name
,
1172 TALLOC_FREE(sitename
);
1174 /* use an off site KDC */
1175 create_local_private_krb5_conf_for_domain(domain
->alt_name
,
1180 winbindd_set_locator_kdc_envs(domain
);
1182 /* Ensure we contact this DC also. */
1183 saf_store(domain
->name
, name
);
1184 saf_store(domain
->alt_name
, name
);
1187 D_DEBUG("DC name for domain '%s' at IP '%s' is '%s'\n",
1191 *namep
= talloc_move(mem_ctx
, &name
);
1194 TALLOC_FREE(tmp_ctx
);
1196 return ADS_ERR_OK(ads_status
) ? true : false;
1200 /*******************************************************************
1201 convert an ip to a name
1202 For an AD Domain, it checks the requirements of the request flags.
1203 *******************************************************************/
1205 static bool dcip_check_name(TALLOC_CTX
*mem_ctx
,
1206 const struct winbindd_domain
*domain
,
1207 const struct sockaddr_storage
*pss
,
1208 char **name
, uint32_t request_flags
)
1210 struct samba_sockaddr sa
= {0};
1211 uint32_t nt_version
= NETLOGON_NT_VERSION_1
;
1213 const char *dc_name
;
1216 bool is_ad_domain
= false;
1218 bool ok
= sockaddr_storage_to_samba_sockaddr(&sa
, pss
);
1224 /* For active directory servers, try to get the ldap server name.
1225 None of these failures should be considered critical for now */
1227 if ((lp_security() == SEC_ADS
) && (domain
->alt_name
!= NULL
)) {
1228 is_ad_domain
= true;
1229 } else if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
) {
1230 is_ad_domain
= domain
->active_directory
;
1234 return dcip_check_name_ads(domain
,
1243 size_t len
= strlen(lp_netbios_name());
1244 char my_acct_name
[len
+2];
1246 snprintf(my_acct_name
,
1247 sizeof(my_acct_name
),
1251 status
= nbt_getdc(global_messaging_context(), 10, &sa
.u
.ss
,
1252 domain
->name
, &domain
->sid
,
1253 my_acct_name
, ACB_WSTRUST
,
1254 nt_version
, mem_ctx
, &nt_version
,
1257 if (NT_STATUS_IS_OK(status
)) {
1258 *name
= talloc_strdup(mem_ctx
, dc_name
);
1259 if (*name
== NULL
) {
1262 namecache_store(*name
, 0x20, 1, &sa
);
1266 /* try node status request */
1268 if (name_status_find(domain
->name
, 0x1c, 0x20, &sa
.u
.ss
, nbtname
) ) {
1269 namecache_store(nbtname
, 0x20, 1, &sa
);
1272 *name
= talloc_strdup(mem_ctx
, nbtname
);
1273 if (*name
== NULL
) {
1283 /*******************************************************************
1284 Retrieve a list of IP addresses for domain controllers.
1286 The array is sorted in the preferred connection order.
1288 @param[in] mem_ctx talloc memory context to allocate from
1289 @param[in] domain domain to retrieve DCs for
1290 @param[out] dcs array of dcs that will be returned
1291 @param[out] num_dcs number of dcs returned in the dcs array
1293 *******************************************************************/
1295 static bool get_dcs(TALLOC_CTX
*mem_ctx
, struct winbindd_domain
*domain
,
1296 struct dc_name_ip
**dcs
, int *num_dcs
,
1297 uint32_t request_flags
)
1300 struct sockaddr_storage ss
;
1301 struct samba_sockaddr
*sa_list
= NULL
;
1302 size_t salist_size
= 0;
1305 enum security_types sec
= (enum security_types
)lp_security();
1307 is_our_domain
= strequal(domain
->name
, lp_workgroup());
1309 /* If not our domain, get the preferred DC, by asking our primary DC */
1311 && get_dc_name_via_netlogon(domain
, dcname
, &ss
, request_flags
)
1312 && add_one_dc_unique(mem_ctx
, domain
->name
, dcname
, &ss
, dcs
,
1315 char addr
[INET6_ADDRSTRLEN
];
1316 print_sockaddr(addr
, sizeof(addr
), &ss
);
1317 DEBUG(10, ("Retrieved DC %s at %s via netlogon\n",
1322 if ((sec
== SEC_ADS
) && (domain
->alt_name
!= NULL
)) {
1323 char *sitename
= NULL
;
1325 /* We need to make sure we know the local site before
1326 doing any DNS queries, as this will restrict the
1327 get_sorted_dc_list() call below to only fetching
1328 DNS records for the correct site. */
1330 /* Find any DC to get the site record.
1331 We deliberately don't care about the
1334 get_dc_name(domain
->name
, domain
->alt_name
, dcname
, &ss
);
1336 sitename
= sitename_fetch(mem_ctx
, domain
->alt_name
);
1339 /* Do the site-specific AD dns lookup first. */
1340 (void)get_sorted_dc_list(mem_ctx
,
1347 /* Add ips to the DC array. We don't look up the name
1348 of the DC in this function, but we fill in the char*
1349 of the ip now to make the failed connection cache
1351 for ( i
=0; i
<salist_size
; i
++ ) {
1352 char addr
[INET6_ADDRSTRLEN
];
1353 print_sockaddr(addr
, sizeof(addr
),
1355 add_one_dc_unique(mem_ctx
,
1363 TALLOC_FREE(sa_list
);
1364 TALLOC_FREE(sitename
);
1368 /* Now we add DCs from the main AD DNS lookup. */
1369 (void)get_sorted_dc_list(mem_ctx
,
1376 for ( i
=0; i
<salist_size
; i
++ ) {
1377 char addr
[INET6_ADDRSTRLEN
];
1378 print_sockaddr(addr
, sizeof(addr
),
1380 add_one_dc_unique(mem_ctx
,
1388 TALLOC_FREE(sa_list
);
1392 /* Try standard netbios queries if no ADS and fall back to DNS queries
1393 * if alt_name is available */
1394 if (*num_dcs
== 0) {
1395 (void)get_sorted_dc_list(mem_ctx
,
1401 if (salist_size
== 0) {
1402 if (domain
->alt_name
!= NULL
) {
1403 (void)get_sorted_dc_list(mem_ctx
,
1412 for ( i
=0; i
<salist_size
; i
++ ) {
1413 char addr
[INET6_ADDRSTRLEN
];
1414 print_sockaddr(addr
, sizeof(addr
),
1416 add_one_dc_unique(mem_ctx
,
1424 TALLOC_FREE(sa_list
);
1431 static bool connect_preferred_dc(TALLOC_CTX
*mem_ctx
,
1432 struct winbindd_domain
*domain
,
1433 uint32_t request_flags
,
1436 char *saf_servername
= NULL
;
1441 * We have to check the server affinity cache here since later we select
1442 * a DC based on response time and not preference.
1444 if (domain
->force_dc
) {
1445 saf_servername
= domain
->dcname
;
1447 saf_servername
= saf_fetch(mem_ctx
, domain
->name
);
1451 * Check the negative connection cache before talking to it. It going
1452 * down may have triggered the reconnection.
1454 if (saf_servername
!= NULL
) {
1455 status
= check_negative_conn_cache(domain
->name
,
1457 if (!NT_STATUS_IS_OK(status
)) {
1458 saf_servername
= NULL
;
1462 if (saf_servername
!= NULL
) {
1463 DBG_DEBUG("saf_servername is '%s' for domain %s\n",
1464 saf_servername
, domain
->name
);
1466 /* convert an ip address to a name */
1467 if (is_ipaddress(saf_servername
)) {
1468 ok
= interpret_string_addr(&domain
->dcaddr
,
1475 ok
= resolve_name(saf_servername
,
1484 TALLOC_FREE(domain
->dcname
);
1485 ok
= dcip_check_name(domain
,
1495 if (domain
->dcname
== NULL
) {
1499 status
= check_negative_conn_cache(domain
->name
, domain
->dcname
);
1500 if (!NT_STATUS_IS_OK(status
)) {
1504 status
= smbsock_connect(&domain
->dcaddr
, 0,
1505 domain
->dcname
, -1, NULL
, -1,
1507 if (!NT_STATUS_IS_OK(status
)) {
1508 winbind_add_failed_connection_entry(domain
,
1510 NT_STATUS_UNSUCCESSFUL
);
1516 winbind_add_failed_connection_entry(domain
,
1518 NT_STATUS_UNSUCCESSFUL
);
1523 /*******************************************************************
1524 Find and make a connection to a DC in the given domain.
1526 @param[in] mem_ctx talloc memory context to allocate from
1527 @param[in] domain domain to find a dc in
1528 @param[out] fd fd of the open socket connected to the newly found dc
1529 @return true when a DC connection is made, false otherwise
1530 *******************************************************************/
1532 static bool find_dc(TALLOC_CTX
*mem_ctx
,
1533 struct winbindd_domain
*domain
,
1534 uint32_t request_flags
,
1537 struct dc_name_ip
*dcs
= NULL
;
1540 const char **dcnames
= NULL
;
1541 size_t num_dcnames
= 0;
1543 struct sockaddr_storage
*addrs
= NULL
;
1554 D_NOTICE("First try to connect to the closest DC (using server "
1555 "affinity cache). If this fails, try to lookup the DC using "
1556 "DNS afterwards.\n");
1557 ok
= connect_preferred_dc(mem_ctx
, domain
, request_flags
, fd
);
1562 if (domain
->force_dc
) {
1567 D_DEBUG("Retrieving a list of IP addresses for DCs.\n");
1568 if (!get_dcs(mem_ctx
, domain
, &dcs
, &num_dcs
, request_flags
) || (num_dcs
== 0))
1571 D_DEBUG("Retrieved IP addresses for %d DCs.\n", num_dcs
);
1572 for (i
=0; i
<num_dcs
; i
++) {
1574 if (!add_string_to_array(mem_ctx
, dcs
[i
].name
,
1575 &dcnames
, &num_dcnames
)) {
1578 if (!add_sockaddr_to_array(mem_ctx
, &dcs
[i
].ss
, TCP_SMB_PORT
,
1579 &addrs
, &num_addrs
)) {
1584 if ((num_dcnames
== 0) || (num_dcnames
!= num_addrs
))
1587 if ((addrs
== NULL
) || (dcnames
== NULL
))
1590 D_DEBUG("Trying to establish a connection to one of the %d DCs "
1591 "(timeout of 10 sec for each DC).\n",
1593 status
= smbsock_any_connect(addrs
, dcnames
, NULL
, NULL
, NULL
,
1594 num_addrs
, 0, 10, fd
, &fd_index
, NULL
);
1595 if (!NT_STATUS_IS_OK(status
)) {
1596 for (i
=0; i
<num_dcs
; i
++) {
1597 char ab
[INET6_ADDRSTRLEN
];
1598 print_sockaddr(ab
, sizeof(ab
), &dcs
[i
].ss
);
1599 DBG_DEBUG("smbsock_any_connect failed for "
1600 "domain %s address %s. Error was %s\n",
1601 domain
->name
, ab
, nt_errstr(status
));
1602 winbind_add_failed_connection_entry(domain
,
1603 dcs
[i
].name
, NT_STATUS_UNSUCCESSFUL
);
1607 D_NOTICE("Successfully connected to DC '%s'.\n", dcs
[fd_index
].name
);
1609 domain
->dcaddr
= addrs
[fd_index
];
1611 if (*dcnames
[fd_index
] != '\0' && !is_ipaddress(dcnames
[fd_index
])) {
1612 /* Ok, we've got a name for the DC */
1613 TALLOC_FREE(domain
->dcname
);
1614 domain
->dcname
= talloc_strdup(domain
, dcnames
[fd_index
]);
1615 if (domain
->dcname
== NULL
) {
1621 /* Try to figure out the name */
1622 TALLOC_FREE(domain
->dcname
);
1623 ok
= dcip_check_name(domain
,
1632 /* We can not continue without the DC's name */
1633 winbind_add_failed_connection_entry(domain
, dcs
[fd_index
].name
,
1634 NT_STATUS_UNSUCCESSFUL
);
1636 /* Throw away all arrays as we're doing this again. */
1640 TALLOC_FREE(dcnames
);
1652 * This should not be an infinite loop, since get_dcs() will not return
1653 * the DC added to the negative connection cache in the above
1654 * winbind_add_failed_connection_entry() call.
1659 static char *current_dc_key(TALLOC_CTX
*mem_ctx
, const char *domain_name
)
1661 return talloc_asprintf_strupper_m(mem_ctx
, "CURRENT_DCNAME/%s",
1665 static void store_current_dc_in_gencache(const char *domain_name
,
1666 const char *dc_name
,
1667 const struct sockaddr_storage
*dc_addr
)
1669 char addr
[INET6_ADDRSTRLEN
];
1673 print_sockaddr(addr
, sizeof(addr
), dc_addr
);
1675 key
= current_dc_key(talloc_tos(), domain_name
);
1680 value
= talloc_asprintf(talloc_tos(), "%s %s", addr
, dc_name
);
1681 if (value
== NULL
) {
1685 gencache_set(key
, value
, 0x7fffffff);
1691 bool fetch_current_dc_from_gencache(TALLOC_CTX
*mem_ctx
,
1692 const char *domain_name
,
1693 char **p_dc_name
, char **p_dc_ip
)
1698 char *dc_name
= NULL
;
1701 key
= current_dc_key(talloc_tos(), domain_name
);
1705 if (!gencache_get(key
, mem_ctx
, &value
, NULL
)) {
1708 p
= strchr(value
, ' ');
1712 dc_ip
= talloc_strndup(mem_ctx
, value
, p
- value
);
1713 if (dc_ip
== NULL
) {
1716 dc_name
= talloc_strdup(mem_ctx
, p
+1);
1717 if (dc_name
== NULL
) {
1721 if (p_dc_ip
!= NULL
) {
1725 if (p_dc_name
!= NULL
) {
1726 *p_dc_name
= dc_name
;
1731 TALLOC_FREE(dc_name
);
1738 NTSTATUS
wb_open_internal_pipe(TALLOC_CTX
*mem_ctx
,
1739 const struct ndr_interface_table
*table
,
1740 struct rpc_pipe_client
**ret_pipe
)
1742 struct rpc_pipe_client
*cli
= NULL
;
1743 const struct auth_session_info
*session_info
= NULL
;
1744 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
1747 session_info
= get_session_info_system();
1748 SMB_ASSERT(session_info
!= NULL
);
1750 status
= rpc_pipe_open_local_np(
1751 mem_ctx
, table
, NULL
, NULL
, NULL
, NULL
, session_info
, &cli
);
1752 if (!NT_STATUS_IS_OK(status
)) {
1760 return NT_STATUS_OK
;
1763 static NTSTATUS
cm_open_connection(struct winbindd_domain
*domain
,
1764 struct winbindd_cm_conn
*new_conn
,
1767 TALLOC_CTX
*mem_ctx
;
1768 NTSTATUS result
= NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND
;
1770 uint32_t request_flags
= need_rw_dc
? DS_WRITABLE_REQUIRED
: 0;
1773 bool seal_pipes
= true;
1775 if ((mem_ctx
= talloc_init("cm_open_connection")) == NULL
) {
1776 set_domain_offline(domain
);
1777 return NT_STATUS_NO_MEMORY
;
1780 D_NOTICE("Creating connection to domain controller. This is a start of "
1781 "a new connection or a DC failover. The failover only happens "
1782 "if the domain has more than one DC. We will try to connect 3 "
1783 "times at most.\n");
1784 for (retries
= 0; retries
< 3; retries
++) {
1787 D_DEBUG("Attempt %d/3: DC '%s' of domain '%s'.\n",
1789 domain
->dcname
? domain
->dcname
: "",
1792 found_dc
= find_dc(mem_ctx
, domain
, request_flags
, &fd
);
1794 /* This is the one place where we will
1795 set the global winbindd offline state
1796 to true, if a "WINBINDD_OFFLINE" entry
1797 is found in the winbindd cache. */
1798 set_global_winbindd_state_offline();
1799 result
= NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND
;
1803 new_conn
->cli
= NULL
;
1805 result
= cm_prepare_connection(domain
, fd
, domain
->dcname
,
1806 &new_conn
->cli
, &retry
);
1807 if (NT_STATUS_IS_OK(result
)) {
1815 if (!NT_STATUS_IS_OK(result
)) {
1816 /* Ensure we setup the retry handler. */
1817 set_domain_offline(domain
);
1821 winbindd_set_locator_kdc_envs(domain
);
1823 if (domain
->online
== False
) {
1824 /* We're changing state from offline to online. */
1825 set_global_winbindd_state_online();
1827 set_domain_online(domain
);
1830 * Much as I hate global state, this seems to be the point
1831 * where we can be certain that we have a proper connection to
1832 * a DC. wbinfo --dc-info needs that information, store it in
1833 * gencache with a looong timeout. This will need revisiting
1834 * once we start to connect to multiple DCs, wbcDcInfo is
1835 * already prepared for that.
1837 store_current_dc_in_gencache(domain
->name
,
1841 seal_pipes
= lp_winbind_sealed_pipes();
1842 seal_pipes
= lp_parm_bool(-1, "winbind sealed pipes",
1847 new_conn
->auth_level
= DCERPC_AUTH_LEVEL_PRIVACY
;
1849 new_conn
->auth_level
= DCERPC_AUTH_LEVEL_INTEGRITY
;
1853 talloc_destroy(mem_ctx
);
1857 /* Close down all open pipes on a connection. */
1859 void invalidate_cm_connection(struct winbindd_domain
*domain
)
1862 struct winbindd_cm_conn
*conn
= &domain
->conn
;
1864 domain
->sequence_number
= DOM_SEQUENCE_NONE
;
1865 domain
->last_seq_check
= 0;
1866 domain
->last_status
= NT_STATUS_SERVER_DISABLED
;
1868 /* We're closing down a possibly dead
1869 connection. Don't have impossibly long (10s) timeouts. */
1872 cli_set_timeout(conn
->cli
, 1000); /* 1 second. */
1875 if (conn
->samr_pipe
!= NULL
) {
1876 if (is_valid_policy_hnd(&conn
->sam_connect_handle
)) {
1877 dcerpc_samr_Close(conn
->samr_pipe
->binding_handle
,
1879 &conn
->sam_connect_handle
,
1882 TALLOC_FREE(conn
->samr_pipe
);
1883 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1885 cli_set_timeout(conn
->cli
, 500);
1889 if (conn
->lsa_pipe
!= NULL
) {
1890 if (is_valid_policy_hnd(&conn
->lsa_policy
)) {
1891 dcerpc_lsa_Close(conn
->lsa_pipe
->binding_handle
,
1896 TALLOC_FREE(conn
->lsa_pipe
);
1897 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1899 cli_set_timeout(conn
->cli
, 500);
1903 if (conn
->lsa_pipe_tcp
!= NULL
) {
1904 if (is_valid_policy_hnd(&conn
->lsa_policy
)) {
1905 dcerpc_lsa_Close(conn
->lsa_pipe_tcp
->binding_handle
,
1910 TALLOC_FREE(conn
->lsa_pipe_tcp
);
1911 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1913 cli_set_timeout(conn
->cli
, 500);
1917 if (conn
->netlogon_pipe
!= NULL
) {
1918 TALLOC_FREE(conn
->netlogon_pipe
);
1919 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1921 cli_set_timeout(conn
->cli
, 500);
1925 conn
->auth_level
= DCERPC_AUTH_LEVEL_PRIVACY
;
1926 TALLOC_FREE(conn
->netlogon_creds_ctx
);
1929 cli_shutdown(conn
->cli
);
1935 void close_conns_after_fork(void)
1937 struct winbindd_domain
*domain
;
1938 struct winbindd_cli_state
*cli_state
;
1940 for (domain
= domain_list(); domain
; domain
= domain
->next
) {
1942 * first close the low level SMB TCP connection
1943 * so that we don't generate any SMBclose
1944 * requests in invalidate_cm_connection()
1946 if (cli_state_is_connected(domain
->conn
.cli
)) {
1947 smbXcli_conn_disconnect(domain
->conn
.cli
->conn
, NT_STATUS_OK
);
1950 invalidate_cm_connection(domain
);
1953 for (cli_state
= winbindd_client_list();
1955 cli_state
= cli_state
->next
) {
1956 if (cli_state
->sock
>= 0) {
1957 close(cli_state
->sock
);
1958 cli_state
->sock
= -1;
1963 static bool connection_ok(struct winbindd_domain
*domain
)
1967 ok
= cli_state_is_connected(domain
->conn
.cli
);
1969 DEBUG(3, ("connection_ok: Connection to %s for domain %s is not connected\n",
1970 domain
->dcname
, domain
->name
));
1974 if (!domain
->online
) {
1975 DEBUG(3, ("connection_ok: Domain %s is offline\n", domain
->name
));
1982 /* Initialize a new connection up to the RPC BIND.
1983 Bypass online status check so always does network calls. */
1985 static NTSTATUS
init_dc_connection_network(struct winbindd_domain
*domain
, bool need_rw_dc
)
1988 bool skip_connection
= domain
->internal
;
1989 if (need_rw_dc
&& domain
->rodc
) {
1990 skip_connection
= false;
1993 /* Internal connections never use the network. */
1994 if (dom_sid_equal(&domain
->sid
, &global_sid_Builtin
)) {
1995 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
1998 /* Still ask the internal LSA and SAMR server about the local domain */
1999 if (skip_connection
|| connection_ok(domain
)) {
2000 if (!domain
->initialized
) {
2001 set_dc_type_and_flags(domain
);
2003 return NT_STATUS_OK
;
2006 invalidate_cm_connection(domain
);
2008 if (!domain
->primary
&& !domain
->initialized
) {
2010 * Before we connect to a trust, work out if it is an
2011 * AD domain by asking our own domain.
2013 set_dc_type_and_flags_trustinfo(domain
);
2016 result
= cm_open_connection(domain
, &domain
->conn
, need_rw_dc
);
2018 if (NT_STATUS_IS_OK(result
) && !domain
->initialized
) {
2019 set_dc_type_and_flags(domain
);
2025 NTSTATUS
init_dc_connection(struct winbindd_domain
*domain
, bool need_rw_dc
)
2027 if (dom_sid_equal(&domain
->sid
, &global_sid_Builtin
)) {
2028 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
2031 SMB_ASSERT(wb_child_domain() || idmap_child());
2033 return init_dc_connection_network(domain
, need_rw_dc
);
2036 static NTSTATUS
init_dc_connection_rpc(struct winbindd_domain
*domain
, bool need_rw_dc
)
2040 status
= init_dc_connection(domain
, need_rw_dc
);
2041 if (!NT_STATUS_IS_OK(status
)) {
2045 if (!domain
->internal
&& domain
->conn
.cli
== NULL
) {
2046 /* happens for trusted domains without inbound trust */
2047 return NT_STATUS_TRUSTED_DOMAIN_FAILURE
;
2050 return NT_STATUS_OK
;
2053 /******************************************************************************
2054 Set the trust flags (direction and forest location) for a domain
2055 ******************************************************************************/
2057 static bool set_dc_type_and_flags_trustinfo( struct winbindd_domain
*domain
)
2059 struct winbindd_domain
*our_domain
;
2060 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
2062 struct netr_DomainTrustList trusts
;
2064 uint32_t flags
= (NETR_TRUST_FLAG_IN_FOREST
|
2065 NETR_TRUST_FLAG_OUTBOUND
|
2066 NETR_TRUST_FLAG_INBOUND
);
2067 struct rpc_pipe_client
*cli
;
2068 TALLOC_CTX
*mem_ctx
= NULL
;
2069 struct dcerpc_binding_handle
*b
;
2073 * On a DC we loaded all trusts
2074 * from configuration and never learn
2080 DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s\n", domain
->name
));
2082 /* Our primary domain doesn't need to worry about trust flags.
2083 Force it to go through the network setup */
2084 if ( domain
->primary
) {
2088 mem_ctx
= talloc_stackframe();
2089 our_domain
= find_our_domain();
2090 if (our_domain
->internal
) {
2091 result
= init_dc_connection(our_domain
, false);
2092 if (!NT_STATUS_IS_OK(result
)) {
2093 DEBUG(3,("set_dc_type_and_flags_trustinfo: "
2094 "Not able to make a connection to our domain: %s\n",
2095 nt_errstr(result
)));
2096 TALLOC_FREE(mem_ctx
);
2101 /* This won't work unless our domain is AD */
2102 if ( !our_domain
->active_directory
) {
2103 TALLOC_FREE(mem_ctx
);
2107 if (our_domain
->internal
) {
2108 result
= wb_open_internal_pipe(mem_ctx
, &ndr_table_netlogon
, &cli
);
2109 } else if (!connection_ok(our_domain
)) {
2110 DEBUG(3,("set_dc_type_and_flags_trustinfo: "
2111 "No connection to our domain!\n"));
2112 TALLOC_FREE(mem_ctx
);
2115 result
= cm_connect_netlogon(our_domain
, &cli
);
2118 if (!NT_STATUS_IS_OK(result
)) {
2119 DEBUG(5, ("set_dc_type_and_flags_trustinfo: Could not open "
2120 "a connection to %s for PIPE_NETLOGON (%s)\n",
2121 domain
->name
, nt_errstr(result
)));
2122 TALLOC_FREE(mem_ctx
);
2125 b
= cli
->binding_handle
;
2127 /* Use DsEnumerateDomainTrusts to get us the trust direction and type. */
2128 result
= dcerpc_netr_DsrEnumerateDomainTrusts(b
, mem_ctx
,
2133 if (!NT_STATUS_IS_OK(result
)) {
2134 DEBUG(0,("set_dc_type_and_flags_trustinfo: "
2135 "failed to query trusted domain list: %s\n",
2136 nt_errstr(result
)));
2137 TALLOC_FREE(mem_ctx
);
2140 if (!W_ERROR_IS_OK(werr
)) {
2141 DEBUG(0,("set_dc_type_and_flags_trustinfo: "
2142 "failed to query trusted domain list: %s\n",
2144 TALLOC_FREE(mem_ctx
);
2148 /* Now find the domain name and get the flags */
2150 for ( i
=0; i
<trusts
.count
; i
++ ) {
2151 if ( strequal( domain
->name
, trusts
.array
[i
].netbios_name
) ) {
2152 domain
->domain_flags
= trusts
.array
[i
].trust_flags
;
2153 domain
->domain_type
= trusts
.array
[i
].trust_type
;
2154 domain
->domain_trust_attribs
= trusts
.array
[i
].trust_attributes
;
2156 if ( domain
->domain_type
== LSA_TRUST_TYPE_UPLEVEL
)
2157 domain
->active_directory
= True
;
2159 DEBUG(5,("set_dc_type_and_flags_trustinfo: domain %s is %s"
2160 "running active directory.\n", domain
->name
,
2161 domain
->active_directory
? "" : "NOT "));
2163 domain
->can_do_ncacn_ip_tcp
= domain
->active_directory
;
2165 domain
->initialized
= True
;
2171 TALLOC_FREE(mem_ctx
);
2173 return domain
->initialized
;
2176 /******************************************************************************
2177 We can 'sense' certain things about the DC by it's replies to certain
2180 This tells us if this particular remote server is Active Directory, and if it
2182 ******************************************************************************/
2184 static void set_dc_type_and_flags_connect( struct winbindd_domain
*domain
)
2186 NTSTATUS status
, result
;
2187 NTSTATUS close_status
= NT_STATUS_UNSUCCESSFUL
;
2188 TALLOC_CTX
*mem_ctx
= NULL
;
2189 struct rpc_pipe_client
*cli
= NULL
;
2190 struct policy_handle pol
= { .handle_type
= 0 };
2191 union lsa_PolicyInformation
*lsa_info
= NULL
;
2192 union lsa_revision_info out_revision_info
= {
2197 uint32_t out_version
= 0;
2199 if (!domain
->internal
&& !connection_ok(domain
)) {
2203 mem_ctx
= talloc_init("set_dc_type_and_flags on domain %s\n",
2206 DEBUG(1, ("set_dc_type_and_flags_connect: talloc_init() failed\n"));
2210 DEBUG(5, ("set_dc_type_and_flags_connect: domain %s\n", domain
->name
));
2212 if (domain
->internal
) {
2213 status
= wb_open_internal_pipe(mem_ctx
,
2217 status
= cli_rpc_pipe_open_noauth(domain
->conn
.cli
,
2218 &ndr_table_lsarpc
, &cli
);
2220 if (!NT_STATUS_IS_OK(status
)) {
2221 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
2222 "PI_LSARPC on domain %s: (%s)\n",
2223 domain
->name
, nt_errstr(status
)));
2225 TALLOC_FREE(mem_ctx
);
2229 status
= dcerpc_lsa_open_policy_fallback(cli
->binding_handle
,
2231 cli
->srv_name_slash
,
2233 SEC_FLAG_MAXIMUM_ALLOWED
,
2239 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(result
)) {
2240 /* This particular query is exactly what Win2k clients use
2241 to determine that the DC is active directory */
2242 status
= dcerpc_lsa_QueryInfoPolicy2(cli
->binding_handle
, mem_ctx
,
2244 LSA_POLICY_INFO_DNS
,
2250 * If the status and result will not be OK we will fallback to
2253 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(result
)) {
2254 domain
->active_directory
= True
;
2256 if (lsa_info
->dns
.name
.string
) {
2257 if (!strequal(domain
->name
, lsa_info
->dns
.name
.string
))
2259 DEBUG(1, ("set_dc_type_and_flags_connect: DC "
2260 "for domain %s claimed it was a DC "
2261 "for domain %s, refusing to "
2264 lsa_info
->dns
.name
.string
));
2266 TALLOC_FREE(mem_ctx
);
2269 talloc_free(domain
->name
);
2270 domain
->name
= talloc_strdup(domain
,
2271 lsa_info
->dns
.name
.string
);
2272 if (domain
->name
== NULL
) {
2277 if (lsa_info
->dns
.dns_domain
.string
) {
2278 if (domain
->alt_name
!= NULL
&&
2279 !strequal(domain
->alt_name
,
2280 lsa_info
->dns
.dns_domain
.string
))
2282 DEBUG(1, ("set_dc_type_and_flags_connect: DC "
2283 "for domain %s (%s) claimed it was "
2284 "a DC for domain %s, refusing to "
2286 domain
->alt_name
, domain
->name
,
2287 lsa_info
->dns
.dns_domain
.string
));
2289 TALLOC_FREE(mem_ctx
);
2292 talloc_free(domain
->alt_name
);
2294 talloc_strdup(domain
,
2295 lsa_info
->dns
.dns_domain
.string
);
2296 if (domain
->alt_name
== NULL
) {
2301 /* See if we can set some domain trust flags about
2304 if (lsa_info
->dns
.dns_forest
.string
) {
2305 talloc_free(domain
->forest_name
);
2306 domain
->forest_name
=
2307 talloc_strdup(domain
,
2308 lsa_info
->dns
.dns_forest
.string
);
2309 if (domain
->forest_name
== NULL
) {
2313 if (strequal(domain
->forest_name
, domain
->alt_name
)) {
2314 domain
->domain_flags
|= NETR_TRUST_FLAG_TREEROOT
;
2318 if (lsa_info
->dns
.sid
) {
2319 if (!is_null_sid(&domain
->sid
) &&
2320 !dom_sid_equal(&domain
->sid
,
2323 struct dom_sid_buf buf1
, buf2
;
2324 DEBUG(1, ("set_dc_type_and_flags_connect: DC "
2325 "for domain %s (%s) claimed it was "
2326 "a DC for domain %s, refusing to "
2328 dom_sid_str_buf(&domain
->sid
, &buf1
),
2330 dom_sid_str_buf(lsa_info
->dns
.sid
,
2333 TALLOC_FREE(mem_ctx
);
2336 sid_copy(&domain
->sid
, lsa_info
->dns
.sid
);
2339 domain
->active_directory
= False
;
2341 status
= rpccli_lsa_open_policy(cli
, mem_ctx
, True
,
2342 SEC_FLAG_MAXIMUM_ALLOWED
,
2345 if (!NT_STATUS_IS_OK(status
)) {
2349 status
= dcerpc_lsa_QueryInfoPolicy(cli
->binding_handle
, mem_ctx
,
2351 LSA_POLICY_INFO_ACCOUNT_DOMAIN
,
2354 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(result
)) {
2356 if (lsa_info
->account_domain
.name
.string
) {
2357 if (!strequal(domain
->name
,
2358 lsa_info
->account_domain
.name
.string
))
2361 ("set_dc_type_and_flags_connect: "
2362 "DC for domain %s claimed it was"
2363 " a DC for domain %s, refusing "
2364 "to initialize\n", domain
->name
,
2366 account_domain
.name
.string
));
2368 TALLOC_FREE(mem_ctx
);
2371 talloc_free(domain
->name
);
2373 talloc_strdup(domain
,
2374 lsa_info
->account_domain
.name
.string
);
2377 if (lsa_info
->account_domain
.sid
) {
2378 if (!is_null_sid(&domain
->sid
) &&
2379 !dom_sid_equal(&domain
->sid
,
2380 lsa_info
->account_domain
.sid
))
2382 struct dom_sid_buf buf1
, buf2
;
2384 ("set_dc_type_and_flags_connect: "
2385 "DC for domain %s (%s) claimed "
2386 "it was a DC for domain %s, "
2387 "refusing to initialize\n",
2389 &domain
->sid
, &buf1
),
2392 lsa_info
->account_domain
.sid
,
2395 TALLOC_FREE(mem_ctx
);
2398 sid_copy(&domain
->sid
, lsa_info
->account_domain
.sid
);
2403 if (is_valid_policy_hnd(&pol
)) {
2404 dcerpc_lsa_Close(cli
->binding_handle
,
2410 DEBUG(5,("set_dc_type_and_flags_connect: domain %s is %srunning active directory.\n",
2411 domain
->name
, domain
->active_directory
? "" : "NOT "));
2413 domain
->can_do_ncacn_ip_tcp
= domain
->active_directory
;
2417 TALLOC_FREE(mem_ctx
);
2419 domain
->initialized
= True
;
2422 /**********************************************************************
2423 Set the domain_flags (trust attributes, domain operating modes, etc...
2424 ***********************************************************************/
2426 static void set_dc_type_and_flags( struct winbindd_domain
*domain
)
2430 * On a DC we loaded all trusts
2431 * from configuration and never learn
2437 /* we always have to contact our primary domain */
2438 if (domain
->primary
|| domain
->internal
) {
2440 * primary and internal domains are
2441 * are already completely
2442 * setup via init_domain_list()
2443 * calling add_trusted_domain()
2445 * There's no need to ask the
2446 * server again, if it hosts an AD
2449 domain
->initialized
= true;
2453 /* Use our DC to get the information if possible */
2455 if ( !set_dc_type_and_flags_trustinfo( domain
) ) {
2456 /* Otherwise, fallback to contacting the
2458 set_dc_type_and_flags_connect( domain
);
2466 /**********************************************************************
2467 ***********************************************************************/
2469 static NTSTATUS
cm_get_schannel_creds(struct winbindd_domain
*domain
,
2470 struct netlogon_creds_cli_context
**ppdc
)
2472 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
2473 struct rpc_pipe_client
*netlogon_pipe
;
2477 if ((!IS_DC
) && (!domain
->primary
)) {
2478 return NT_STATUS_TRUSTED_DOMAIN_FAILURE
;
2481 if (domain
->conn
.netlogon_creds_ctx
!= NULL
) {
2482 *ppdc
= domain
->conn
.netlogon_creds_ctx
;
2483 return NT_STATUS_OK
;
2486 result
= cm_connect_netlogon_secure(domain
, &netlogon_pipe
, ppdc
);
2487 if (!NT_STATUS_IS_OK(result
)) {
2491 return NT_STATUS_OK
;
2494 NTSTATUS
cm_connect_sam(struct winbindd_domain
*domain
, TALLOC_CTX
*mem_ctx
,
2496 struct rpc_pipe_client
**cli
, struct policy_handle
*sam_handle
)
2498 struct winbindd_cm_conn
*conn
;
2499 NTSTATUS status
, result
;
2500 struct netlogon_creds_cli_context
*p_creds
;
2501 struct cli_credentials
*creds
= NULL
;
2502 bool retry
= false; /* allow one retry attempt for expired session */
2503 const char *remote_name
= NULL
;
2504 const struct sockaddr_storage
*remote_sockaddr
= NULL
;
2505 bool sealed_pipes
= true;
2506 bool strong_key
= true;
2508 if (sid_check_is_our_sam(&domain
->sid
)) {
2509 if (domain
->rodc
== false || need_rw_dc
== false) {
2510 return open_internal_samr_conn(mem_ctx
, domain
, cli
, sam_handle
);
2516 * In theory we should not use SAMR within
2517 * winbindd at all, but that's a larger task to
2518 * remove this and avoid breaking existing
2521 * At least as AD DC we have the restriction
2522 * to avoid SAMR against trusted domains,
2523 * as there're no existing setups.
2525 return NT_STATUS_REQUEST_NOT_ACCEPTED
;
2529 status
= init_dc_connection_rpc(domain
, need_rw_dc
);
2530 if (!NT_STATUS_IS_OK(status
)) {
2534 conn
= &domain
->conn
;
2536 if (rpccli_is_connected(conn
->samr_pipe
)) {
2540 TALLOC_FREE(conn
->samr_pipe
);
2543 * No SAMR pipe yet. Attempt to get an NTLMSSP SPNEGO authenticated
2544 * sign and sealed pipe using the machine account password by
2545 * preference. If we can't - try schannel, if that fails, try
2549 result
= winbindd_get_trust_credentials(domain
,
2551 false, /* netlogon */
2552 true, /* ipc_fallback */
2554 if (!NT_STATUS_IS_OK(result
)) {
2555 DEBUG(10, ("cm_connect_sam: No user available for "
2556 "domain %s, trying schannel\n", domain
->name
));
2560 if (cli_credentials_is_anonymous(creds
)) {
2564 remote_name
= smbXcli_conn_remote_name(conn
->cli
->conn
);
2565 remote_sockaddr
= smbXcli_conn_remote_sockaddr(conn
->cli
->conn
);
2568 * We have an authenticated connection. Use a SPNEGO
2569 * authenticated SAMR pipe with sign & seal.
2571 status
= cli_rpc_pipe_open_with_creds(conn
->cli
,
2574 DCERPC_AUTH_TYPE_SPNEGO
,
2576 NULL
, /* target_service */
2582 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)
2584 invalidate_cm_connection(domain
);
2589 if (!NT_STATUS_IS_OK(status
)) {
2590 DEBUG(10,("cm_connect_sam: failed to connect to SAMR "
2591 "pipe for domain %s using NTLMSSP "
2592 "authenticated pipe: user %s. Error was "
2593 "%s\n", domain
->name
,
2594 cli_credentials_get_unparsed_name(creds
, talloc_tos()),
2595 nt_errstr(status
)));
2599 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for "
2600 "domain %s using NTLMSSP authenticated "
2601 "pipe: user %s\n", domain
->name
,
2602 cli_credentials_get_unparsed_name(creds
, talloc_tos())));
2604 status
= dcerpc_samr_Connect2(conn
->samr_pipe
->binding_handle
, mem_ctx
,
2605 conn
->samr_pipe
->desthost
,
2606 SEC_FLAG_MAXIMUM_ALLOWED
,
2607 &conn
->sam_connect_handle
,
2610 if (NT_STATUS_EQUAL(status
, NT_STATUS_IO_DEVICE_ERROR
) && !retry
) {
2611 invalidate_cm_connection(domain
);
2612 TALLOC_FREE(conn
->samr_pipe
);
2617 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(result
)) {
2620 if (NT_STATUS_IS_OK(status
)) {
2624 DEBUG(10,("cm_connect_sam: ntlmssp-sealed dcerpc_samr_Connect2 "
2625 "failed for domain %s, error was %s. Trying schannel\n",
2626 domain
->name
, nt_errstr(status
) ));
2627 TALLOC_FREE(conn
->samr_pipe
);
2631 /* Fall back to schannel if it's a W2K pre-SP1 box. */
2633 status
= cm_get_schannel_creds(domain
, &p_creds
);
2634 if (!NT_STATUS_IS_OK(status
)) {
2635 /* If this call fails - conn->cli can now be NULL ! */
2636 DEBUG(10, ("cm_connect_sam: Could not get schannel auth info "
2637 "for domain %s (error %s), trying anon\n",
2639 nt_errstr(status
) ));
2643 status
= cli_rpc_pipe_open_schannel_with_creds(
2644 conn
->cli
, &ndr_table_samr
, NCACN_NP
, p_creds
,
2649 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)
2651 invalidate_cm_connection(domain
);
2656 if (!NT_STATUS_IS_OK(status
)) {
2657 DEBUG(10,("cm_connect_sam: failed to connect to SAMR pipe for "
2658 "domain %s using schannel. Error was %s\n",
2659 domain
->name
, nt_errstr(status
) ));
2662 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for domain %s using "
2663 "schannel.\n", domain
->name
));
2665 status
= dcerpc_samr_Connect2(conn
->samr_pipe
->binding_handle
, mem_ctx
,
2666 conn
->samr_pipe
->desthost
,
2667 SEC_FLAG_MAXIMUM_ALLOWED
,
2668 &conn
->sam_connect_handle
,
2671 if (NT_STATUS_EQUAL(status
, NT_STATUS_IO_DEVICE_ERROR
) && !retry
) {
2672 invalidate_cm_connection(domain
);
2673 TALLOC_FREE(conn
->samr_pipe
);
2678 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(result
)) {
2681 if (NT_STATUS_IS_OK(status
)) {
2684 DEBUG(10,("cm_connect_sam: schannel-sealed dcerpc_samr_Connect2 failed "
2685 "for domain %s, error was %s. Trying anonymous\n",
2686 domain
->name
, nt_errstr(status
) ));
2687 TALLOC_FREE(conn
->samr_pipe
);
2691 sealed_pipes
= lp_winbind_sealed_pipes();
2692 sealed_pipes
= lp_parm_bool(-1, "winbind sealed pipes",
2695 strong_key
= lp_require_strong_key();
2696 strong_key
= lp_parm_bool(-1, "require strong key",
2700 /* Finally fall back to anonymous. */
2701 if (sealed_pipes
|| strong_key
) {
2702 status
= NT_STATUS_DOWNGRADE_DETECTED
;
2703 DEBUG(1, ("Unwilling to make SAMR connection to domain %s "
2704 "without connection level security, "
2705 "must set 'winbind sealed pipes:%s = false' and "
2706 "'require strong key:%s = false' to proceed: %s\n",
2707 domain
->name
, domain
->name
, domain
->name
,
2708 nt_errstr(status
)));
2711 status
= cli_rpc_pipe_open_noauth(conn
->cli
, &ndr_table_samr
,
2714 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)
2716 invalidate_cm_connection(domain
);
2721 if (!NT_STATUS_IS_OK(status
)) {
2725 status
= dcerpc_samr_Connect2(conn
->samr_pipe
->binding_handle
, mem_ctx
,
2726 conn
->samr_pipe
->desthost
,
2727 SEC_FLAG_MAXIMUM_ALLOWED
,
2728 &conn
->sam_connect_handle
,
2731 if (NT_STATUS_EQUAL(status
, NT_STATUS_IO_DEVICE_ERROR
) && !retry
) {
2732 invalidate_cm_connection(domain
);
2733 TALLOC_FREE(conn
->samr_pipe
);
2738 if (!NT_STATUS_IS_OK(status
)) {
2739 DEBUG(10,("cm_connect_sam: rpccli_samr_Connect2 failed "
2740 "for domain %s Error was %s\n",
2741 domain
->name
, nt_errstr(status
) ));
2744 if (!NT_STATUS_IS_OK(result
)) {
2746 DEBUG(10,("cm_connect_sam: dcerpc_samr_Connect2 failed "
2747 "for domain %s Error was %s\n",
2748 domain
->name
, nt_errstr(result
)));
2753 status
= dcerpc_samr_OpenDomain(conn
->samr_pipe
->binding_handle
,
2755 &conn
->sam_connect_handle
,
2756 SEC_FLAG_MAXIMUM_ALLOWED
,
2758 &conn
->sam_domain_handle
,
2760 if (!NT_STATUS_IS_OK(status
)) {
2767 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
2769 * if we got access denied, we might just have no access rights
2770 * to talk to the remote samr server server (e.g. when we are a
2771 * PDC and we are connecting a w2k8 pdc via an interdomain
2772 * trust). In that case do not invalidate the whole connection
2775 TALLOC_FREE(conn
->samr_pipe
);
2776 ZERO_STRUCT(conn
->sam_domain_handle
);
2778 } else if (!NT_STATUS_IS_OK(status
)) {
2779 invalidate_cm_connection(domain
);
2783 *cli
= conn
->samr_pipe
;
2784 *sam_handle
= conn
->sam_domain_handle
;
2788 /**********************************************************************
2789 open an schanneld ncacn_ip_tcp connection to LSA
2790 ***********************************************************************/
2792 static NTSTATUS
cm_connect_lsa_tcp(struct winbindd_domain
*domain
,
2793 TALLOC_CTX
*mem_ctx
,
2794 struct rpc_pipe_client
**cli
)
2796 struct winbindd_cm_conn
*conn
;
2797 struct netlogon_creds_cli_context
*p_creds
= NULL
;
2799 const char *remote_name
= NULL
;
2800 const struct sockaddr_storage
*remote_sockaddr
= NULL
;
2802 DEBUG(10,("cm_connect_lsa_tcp\n"));
2804 status
= init_dc_connection_rpc(domain
, false);
2805 if (!NT_STATUS_IS_OK(status
)) {
2809 conn
= &domain
->conn
;
2812 * rpccli_is_connected handles more error cases
2814 if (rpccli_is_connected(conn
->lsa_pipe_tcp
)) {
2818 TALLOC_FREE(conn
->lsa_pipe_tcp
);
2820 status
= cm_get_schannel_creds(domain
, &p_creds
);
2821 if (!NT_STATUS_IS_OK(status
)) {
2825 remote_name
= smbXcli_conn_remote_name(conn
->cli
->conn
);
2826 remote_sockaddr
= smbXcli_conn_remote_sockaddr(conn
->cli
->conn
);
2828 status
= cli_rpc_pipe_open_schannel_with_creds(
2835 &conn
->lsa_pipe_tcp
);
2836 if (!NT_STATUS_IS_OK(status
)) {
2837 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key failed: %s\n",
2838 nt_errstr(status
)));
2843 if (!NT_STATUS_IS_OK(status
)) {
2844 TALLOC_FREE(conn
->lsa_pipe_tcp
);
2848 *cli
= conn
->lsa_pipe_tcp
;
2853 NTSTATUS
cm_connect_lsa(struct winbindd_domain
*domain
, TALLOC_CTX
*mem_ctx
,
2854 struct rpc_pipe_client
**cli
, struct policy_handle
*lsa_policy
)
2856 struct winbindd_cm_conn
*conn
;
2857 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
2858 struct netlogon_creds_cli_context
*p_creds
;
2859 struct cli_credentials
*creds
= NULL
;
2860 bool retry
= false; /* allow one retry attempt for expired session */
2861 const char *remote_name
= NULL
;
2862 const struct sockaddr_storage
*remote_sockaddr
= NULL
;
2863 bool sealed_pipes
= true;
2864 bool strong_key
= true;
2865 bool require_schannel
= false;
2868 result
= init_dc_connection_rpc(domain
, false);
2869 if (!NT_STATUS_IS_OK(result
))
2872 conn
= &domain
->conn
;
2874 if (rpccli_is_connected(conn
->lsa_pipe
)) {
2878 TALLOC_FREE(conn
->lsa_pipe
);
2881 domain
->secure_channel_type
!= SEC_CHAN_NULL
)
2884 * Make sure we only use schannel as DC
2885 * or with a direct trust
2887 require_schannel
= true;
2891 result
= winbindd_get_trust_credentials(domain
,
2893 false, /* netlogon */
2894 true, /* ipc_fallback */
2896 if (!NT_STATUS_IS_OK(result
)) {
2897 DEBUG(10, ("cm_connect_lsa: No user available for "
2898 "domain %s, trying schannel\n", domain
->name
));
2902 if (cli_credentials_is_anonymous(creds
)) {
2906 remote_name
= smbXcli_conn_remote_name(conn
->cli
->conn
);
2907 remote_sockaddr
= smbXcli_conn_remote_sockaddr(conn
->cli
->conn
);
2910 * We have an authenticated connection. Use a SPNEGO
2911 * authenticated LSA pipe with sign & seal.
2913 result
= cli_rpc_pipe_open_with_creds
2914 (conn
->cli
, &ndr_table_lsarpc
, NCACN_NP
,
2915 DCERPC_AUTH_TYPE_SPNEGO
,
2917 NULL
, /* target_service */
2923 if (NT_STATUS_EQUAL(result
, NT_STATUS_NETWORK_SESSION_EXPIRED
)
2925 invalidate_cm_connection(domain
);
2930 if (!NT_STATUS_IS_OK(result
)) {
2931 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
2932 "domain %s using NTLMSSP authenticated pipe: user "
2933 "%s. Error was %s. Trying schannel.\n",
2935 cli_credentials_get_unparsed_name(creds
, talloc_tos()),
2936 nt_errstr(result
)));
2940 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
2941 "NTLMSSP authenticated pipe: user %s\n",
2942 domain
->name
, cli_credentials_get_unparsed_name(creds
, talloc_tos())));
2944 result
= rpccli_lsa_open_policy(conn
->lsa_pipe
, mem_ctx
, True
,
2945 SEC_FLAG_MAXIMUM_ALLOWED
,
2947 if (NT_STATUS_EQUAL(result
, NT_STATUS_IO_DEVICE_ERROR
) && !retry
) {
2948 invalidate_cm_connection(domain
);
2949 TALLOC_FREE(conn
->lsa_pipe
);
2954 if (NT_STATUS_IS_OK(result
)) {
2958 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
2961 TALLOC_FREE(conn
->lsa_pipe
);
2965 /* Fall back to schannel if it's a W2K pre-SP1 box. */
2967 result
= cm_get_schannel_creds(domain
, &p_creds
);
2968 if (!NT_STATUS_IS_OK(result
)) {
2969 /* If this call fails - conn->cli can now be NULL ! */
2970 DEBUG(10, ("cm_connect_lsa: Could not get schannel auth info "
2971 "for domain %s (error %s), trying anon\n",
2973 nt_errstr(result
) ));
2978 result
= cli_rpc_pipe_open_schannel_with_creds(
2979 conn
->cli
, &ndr_table_lsarpc
, NCACN_NP
, p_creds
,
2984 if (NT_STATUS_EQUAL(result
, NT_STATUS_NETWORK_SESSION_EXPIRED
)
2986 invalidate_cm_connection(domain
);
2991 if (!NT_STATUS_IS_OK(result
)) {
2992 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
2993 "domain %s using schannel. Error was %s\n",
2994 domain
->name
, nt_errstr(result
) ));
2997 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
2998 "schannel.\n", domain
->name
));
3000 result
= rpccli_lsa_open_policy(conn
->lsa_pipe
, mem_ctx
, True
,
3001 SEC_FLAG_MAXIMUM_ALLOWED
,
3004 if (NT_STATUS_EQUAL(result
, NT_STATUS_IO_DEVICE_ERROR
) && !retry
) {
3005 invalidate_cm_connection(domain
);
3006 TALLOC_FREE(conn
->lsa_pipe
);
3011 if (NT_STATUS_IS_OK(result
)) {
3015 if (require_schannel
) {
3017 * Make sure we only use schannel as DC
3018 * or with a direct trust
3023 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
3026 TALLOC_FREE(conn
->lsa_pipe
);
3030 if (require_schannel
) {
3032 * Make sure we only use schannel as DC
3033 * or with a direct trust
3038 sealed_pipes
= lp_winbind_sealed_pipes();
3039 sealed_pipes
= lp_parm_bool(-1, "winbind sealed pipes",
3042 strong_key
= lp_require_strong_key();
3043 strong_key
= lp_parm_bool(-1, "require strong key",
3047 /* Finally fall back to anonymous. */
3048 if (sealed_pipes
|| strong_key
) {
3049 result
= NT_STATUS_DOWNGRADE_DETECTED
;
3050 DEBUG(1, ("Unwilling to make LSA connection to domain %s "
3051 "without connection level security, "
3052 "must set 'winbind sealed pipes:%s = false' and "
3053 "'require strong key:%s = false' to proceed: %s\n",
3054 domain
->name
, domain
->name
, domain
->name
,
3055 nt_errstr(result
)));
3059 result
= cli_rpc_pipe_open_noauth(conn
->cli
,
3063 if (NT_STATUS_EQUAL(result
, NT_STATUS_NETWORK_SESSION_EXPIRED
)
3065 invalidate_cm_connection(domain
);
3070 if (!NT_STATUS_IS_OK(result
)) {
3074 result
= rpccli_lsa_open_policy(conn
->lsa_pipe
, mem_ctx
, True
,
3075 SEC_FLAG_MAXIMUM_ALLOWED
,
3078 if (NT_STATUS_EQUAL(result
, NT_STATUS_IO_DEVICE_ERROR
) && !retry
) {
3079 invalidate_cm_connection(domain
);
3080 TALLOC_FREE(conn
->lsa_pipe
);
3086 if (!NT_STATUS_IS_OK(result
)) {
3087 invalidate_cm_connection(domain
);
3091 *cli
= conn
->lsa_pipe
;
3092 *lsa_policy
= conn
->lsa_policy
;
3096 /****************************************************************************
3097 Open a LSA connection to a DC, suitable for LSA lookup calls.
3098 ****************************************************************************/
3100 NTSTATUS
cm_connect_lsat(struct winbindd_domain
*domain
,
3101 TALLOC_CTX
*mem_ctx
,
3102 struct rpc_pipe_client
**cli
,
3103 struct policy_handle
*lsa_policy
)
3107 if (domain
->can_do_ncacn_ip_tcp
) {
3108 status
= cm_connect_lsa_tcp(domain
, mem_ctx
, cli
);
3109 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
) ||
3110 NT_STATUS_EQUAL(status
, NT_STATUS_RPC_SEC_PKG_ERROR
) ||
3111 NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_ACCESS_DENIED
)) {
3112 invalidate_cm_connection(domain
);
3113 status
= cm_connect_lsa_tcp(domain
, mem_ctx
, cli
);
3115 if (NT_STATUS_IS_OK(status
)) {
3120 * we tried twice to connect via ncan_ip_tcp and schannel and
3121 * failed - maybe it is a trusted domain we can't connect to ?
3122 * do not try tcp next time - gd
3124 * This also prevents NETLOGON over TCP
3126 domain
->can_do_ncacn_ip_tcp
= false;
3129 status
= cm_connect_lsa(domain
, mem_ctx
, cli
, lsa_policy
);
3134 /****************************************************************************
3135 Open the netlogon pipe to this DC.
3136 ****************************************************************************/
3138 static NTSTATUS
cm_connect_netlogon_transport(struct winbindd_domain
*domain
,
3139 enum dcerpc_transport_t transport
,
3140 struct rpc_pipe_client
**cli
)
3142 struct messaging_context
*msg_ctx
= global_messaging_context();
3143 struct winbindd_cm_conn
*conn
;
3145 enum netr_SchannelType sec_chan_type
;
3146 struct cli_credentials
*creds
= NULL
;
3147 const char *remote_name
= NULL
;
3148 const struct sockaddr_storage
*remote_sockaddr
= NULL
;
3153 if (domain
->secure_channel_type
== SEC_CHAN_NULL
) {
3155 * Make sure we don't even try to
3156 * connect to a foreign domain
3157 * without a direct outbound trust.
3159 return NT_STATUS_NO_TRUST_LSA_SECRET
;
3163 result
= init_dc_connection_rpc(domain
, domain
->rodc
);
3164 if (!NT_STATUS_IS_OK(result
)) {
3168 conn
= &domain
->conn
;
3170 if (rpccli_is_connected(conn
->netlogon_pipe
)) {
3171 *cli
= conn
->netlogon_pipe
;
3172 return NT_STATUS_OK
;
3175 TALLOC_FREE(conn
->netlogon_pipe
);
3176 TALLOC_FREE(conn
->netlogon_creds_ctx
);
3178 remote_name
= smbXcli_conn_remote_name(conn
->cli
->conn
);
3179 remote_sockaddr
= smbXcli_conn_remote_sockaddr(conn
->cli
->conn
);
3181 result
= winbindd_get_trust_credentials(domain
,
3183 true, /* netlogon */
3184 false, /* ipc_fallback */
3186 if (!NT_STATUS_IS_OK(result
)) {
3187 DBG_DEBUG("No user available for domain %s when trying "
3188 "schannel\n", domain
->name
);
3189 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
3192 if (cli_credentials_is_anonymous(creds
)) {
3193 DBG_WARNING("get_trust_credential only gave anonymous for %s, "
3194 "unable to make get NETLOGON credentials\n",
3196 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
3199 sec_chan_type
= cli_credentials_get_secure_channel_type(creds
);
3200 if (sec_chan_type
== SEC_CHAN_NULL
) {
3201 if (transport
== NCACN_IP_TCP
) {
3202 DBG_NOTICE("get_secure_channel_type gave SEC_CHAN_NULL "
3203 "for %s, deny NCACN_IP_TCP and let the "
3204 "caller fallback to NCACN_NP.\n",
3206 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
3209 DBG_NOTICE("get_secure_channel_type gave SEC_CHAN_NULL for %s, "
3210 "fallback to noauth on NCACN_NP.\n",
3213 result
= cli_rpc_pipe_open_noauth_transport(
3216 &ndr_table_netlogon
,
3219 &conn
->netlogon_pipe
);
3220 if (!NT_STATUS_IS_OK(result
)) {
3221 invalidate_cm_connection(domain
);
3225 *cli
= conn
->netlogon_pipe
;
3226 return NT_STATUS_OK
;
3229 result
= rpccli_create_netlogon_creds_ctx(creds
,
3233 &conn
->netlogon_creds_ctx
);
3234 if (!NT_STATUS_IS_OK(result
)) {
3235 DEBUG(1, ("rpccli_create_netlogon_creds failed for %s, "
3236 "unable to create NETLOGON credentials: %s\n",
3237 domain
->name
, nt_errstr(result
)));
3241 result
= rpccli_connect_netlogon(conn
->cli
,
3245 conn
->netlogon_creds_ctx
,
3246 conn
->netlogon_force_reauth
, creds
,
3247 &conn
->netlogon_pipe
);
3248 conn
->netlogon_force_reauth
= false;
3249 if (!NT_STATUS_IS_OK(result
)) {
3250 DBG_DEBUG("rpccli_connect_netlogon failed: %s\n",
3255 *cli
= conn
->netlogon_pipe
;
3256 return NT_STATUS_OK
;
3259 /****************************************************************************
3260 Open a NETLOGON connection to a DC, suitable for SamLogon calls.
3261 ****************************************************************************/
3263 NTSTATUS
cm_connect_netlogon(struct winbindd_domain
*domain
,
3264 struct rpc_pipe_client
**cli
)
3268 status
= init_dc_connection_rpc(domain
, domain
->rodc
);
3269 if (!NT_STATUS_IS_OK(status
)) {
3273 if (domain
->active_directory
&& domain
->can_do_ncacn_ip_tcp
) {
3274 status
= cm_connect_netlogon_transport(domain
, NCACN_IP_TCP
, cli
);
3275 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
) ||
3276 NT_STATUS_EQUAL(status
, NT_STATUS_RPC_SEC_PKG_ERROR
) ||
3277 NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_ACCESS_DENIED
)) {
3278 invalidate_cm_connection(domain
);
3279 status
= cm_connect_netlogon_transport(domain
, NCACN_IP_TCP
, cli
);
3281 if (NT_STATUS_IS_OK(status
)) {
3286 * we tried twice to connect via ncan_ip_tcp and schannel and
3287 * failed - maybe it is a trusted domain we can't connect to ?
3288 * do not try tcp next time - gd
3290 * This also prevents LSA over TCP
3292 domain
->can_do_ncacn_ip_tcp
= false;
3295 status
= cm_connect_netlogon_transport(domain
, NCACN_NP
, cli
);
3296 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)) {
3298 * SMB2 session expired, needs reauthentication. Drop
3299 * connection and retry.
3301 invalidate_cm_connection(domain
);
3302 status
= cm_connect_netlogon_transport(domain
, NCACN_NP
, cli
);
3308 NTSTATUS
cm_connect_netlogon_secure(struct winbindd_domain
*domain
,
3309 struct rpc_pipe_client
**cli
,
3310 struct netlogon_creds_cli_context
**ppdc
)
3314 if (domain
->secure_channel_type
== SEC_CHAN_NULL
) {
3315 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
3318 status
= cm_connect_netlogon(domain
, cli
);
3319 if (!NT_STATUS_IS_OK(status
)) {
3323 if (domain
->conn
.netlogon_creds_ctx
== NULL
) {
3324 return NT_STATUS_TRUSTED_DOMAIN_FAILURE
;
3327 *ppdc
= domain
->conn
.netlogon_creds_ctx
;
3328 return NT_STATUS_OK
;
3331 void winbind_msg_ip_dropped(struct messaging_context
*msg_ctx
,
3334 struct server_id server_id
,
3337 struct winbindd_domain
*domain
;
3338 char *freeit
= NULL
;
3342 || (data
->data
== NULL
)
3343 || (data
->length
== 0)
3344 || (data
->data
[data
->length
-1] != '\0')) {
3345 DEBUG(1, ("invalid msg_ip_dropped message: not a valid "
3350 addr
= (char *)data
->data
;
3351 DEBUG(10, ("IP %s dropped\n", addr
));
3353 if (!is_ipaddress(addr
)) {
3356 * Some code sends us ip addresses with the /netmask
3359 slash
= strchr(addr
, '/');
3360 if (slash
== NULL
) {
3361 DEBUG(1, ("invalid msg_ip_dropped message: %s\n",
3365 freeit
= talloc_strndup(talloc_tos(), addr
, slash
-addr
);
3366 if (freeit
== NULL
) {
3367 DEBUG(1, ("talloc failed\n"));
3371 DEBUG(10, ("Stripped /netmask to IP %s\n", addr
));
3374 for (domain
= domain_list(); domain
!= NULL
; domain
= domain
->next
) {
3375 char sockaddr
[INET6_ADDRSTRLEN
];
3377 if (!cli_state_is_connected(domain
->conn
.cli
)) {
3381 print_sockaddr(sockaddr
, sizeof(sockaddr
),
3382 smbXcli_conn_local_sockaddr(domain
->conn
.cli
->conn
));
3384 if (strequal(sockaddr
, addr
)) {
3385 smbXcli_conn_disconnect(domain
->conn
.cli
->conn
, NT_STATUS_OK
);
3388 TALLOC_FREE(freeit
);
3391 void winbind_msg_disconnect_dc(struct messaging_context
*msg_ctx
,
3394 struct server_id server_id
,
3397 struct winbindd_domain
*domain
;
3399 for (domain
= domain_list(); domain
; domain
= domain
->next
) {
3400 if (domain
->internal
) {
3403 invalidate_cm_connection(domain
);