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 static NTSTATUS
get_trust_credentials(struct winbindd_domain
*domain
,
618 struct cli_credentials
**_creds
)
620 const struct winbindd_domain
*creds_domain
= NULL
;
621 struct cli_credentials
*creds
;
623 bool force_machine_account
= false;
625 /* If we are a DC and this is not our own domain */
627 if (!domain
->active_directory
) {
630 * For non active directory domains
631 * we can only use NTLMSSP for SMB.
633 * But the trust account is not allowed
634 * to use SMB with NTLMSSP.
636 force_machine_account
= true;
640 if (IS_DC
&& !force_machine_account
) {
641 creds_domain
= domain
;
643 creds_domain
= find_our_domain();
644 if (creds_domain
== NULL
) {
645 return NT_STATUS_INVALID_SERVER_STATE
;
649 status
= pdb_get_trust_credentials(creds_domain
->name
,
650 creds_domain
->alt_name
,
653 if (!NT_STATUS_IS_OK(status
)) {
657 if (creds_domain
!= domain
) {
659 * We can only use schannel against a direct trust
661 cli_credentials_set_secure_channel_type(creds
,
670 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
673 status
= cm_get_ipc_credentials(mem_ctx
, &creds
);
674 if (!NT_STATUS_IS_OK(status
)) {
682 /************************************************************************
683 Given a fd with a just-connected TCP connection to a DC, open a connection
685 ************************************************************************/
687 static NTSTATUS
cm_prepare_connection(struct winbindd_domain
*domain
,
689 const char *controller
,
690 struct cli_state
**cli
,
693 bool try_ipc_auth
= false;
694 const char *machine_principal
= NULL
;
695 const char *machine_realm
= NULL
;
696 const char *machine_account
= NULL
;
697 const char *machine_domain
= NULL
;
699 struct cli_credentials
*creds
= NULL
;
701 struct named_mutex
*mutex
;
703 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
705 NTSTATUS tcon_status
= NT_STATUS_NETWORK_NAME_DELETED
;
707 enum smb_signing_setting smb_sign_client_connections
= lp_client_ipc_signing();
710 if (domain
->secure_channel_type
== SEC_CHAN_NULL
) {
712 * Make sure we don't even try to
713 * connect to a foreign domain
714 * without a direct outbound trust.
717 return NT_STATUS_NO_TRUST_LSA_SECRET
;
721 * As AD DC we only use netlogon and lsa
722 * using schannel over an anonymous transport
723 * (ncacn_ip_tcp or ncacn_np).
725 * Currently we always establish the SMB connection,
726 * even if we don't use it, because we later use ncacn_ip_tcp.
728 * As we won't use the SMB connection there's no
729 * need to try kerberos. And NT4 domains expect
730 * an anonymous IPC$ connection anyway.
732 smb_sign_client_connections
= SMB_SIGNING_OFF
;
735 if (smb_sign_client_connections
== SMB_SIGNING_DEFAULT
) {
737 * If we are connecting to our own AD domain, require
738 * smb signing to disrupt MITM attacks
740 if (domain
->primary
&& lp_security() == SEC_ADS
) {
741 smb_sign_client_connections
= SMB_SIGNING_REQUIRED
;
743 * If we are in or are an AD domain and connecting to another
744 * AD domain in our forest
745 * then require smb signing to disrupt MITM attacks
747 } else if ((lp_security() == SEC_ADS
)
748 && domain
->active_directory
749 && (domain
->domain_trust_attribs
750 & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST
)) {
751 smb_sign_client_connections
= SMB_SIGNING_REQUIRED
;
755 DEBUG(10,("cm_prepare_connection: connecting to DC %s for domain %s\n",
756 controller
, domain
->name
));
760 mutex
= grab_named_mutex(talloc_tos(), controller
,
761 WINBIND_SERVER_MUTEX_WAIT_TIME
);
764 DEBUG(0,("cm_prepare_connection: mutex grab failed for %s\n",
766 result
= NT_STATUS_POSSIBLE_DEADLOCK
;
771 * cm_prepare_connection() is responsible that sockfd does not leak.
772 * Once cli_state_create() returns with success, the
773 * smbXcli_conn_destructor() makes sure that close(sockfd) is finally
774 * called. Till that, close(sockfd) must be called on every unsuccessful
777 *cli
= cli_state_create(NULL
, sockfd
, controller
,
778 smb_sign_client_connections
, flags
);
781 DEBUG(1, ("Could not cli_initialize\n"));
782 result
= NT_STATUS_NO_MEMORY
;
786 cli_set_timeout(*cli
, 10000); /* 10 seconds */
788 set_socket_options(sockfd
, lp_socket_options());
790 result
= smbXcli_negprot((*cli
)->conn
,
792 lp_client_ipc_min_protocol(),
793 lp_client_ipc_max_protocol(),
798 if (!NT_STATUS_IS_OK(result
)) {
799 DEBUG(1, ("cli_negprot failed: %s\n", nt_errstr(result
)));
803 if (smbXcli_conn_protocol((*cli
)->conn
) >= PROTOCOL_NT1
&&
804 smb1cli_conn_capabilities((*cli
)->conn
) & CAP_EXTENDED_SECURITY
) {
806 } else if (smbXcli_conn_protocol((*cli
)->conn
) >= PROTOCOL_SMB2_02
) {
808 } else if (smb_sign_client_connections
== SMB_SIGNING_REQUIRED
) {
810 * If we are forcing on SMB signing, then we must
811 * require authentication unless this is a one-way
812 * trust, and we have no stored user/password
819 * As AD DC we only use netlogon and lsa
820 * using schannel over an anonymous transport
821 * (ncacn_ip_tcp or ncacn_np).
823 * Currently we always establish the SMB connection,
824 * even if we don't use it, because we later use ncacn_ip_tcp.
826 * As we won't use the SMB connection there's no
827 * need to try kerberos. And NT4 domains expect
828 * an anonymous IPC$ connection anyway.
830 try_ipc_auth
= false;
834 result
= get_trust_credentials(domain
, talloc_tos(), false, &creds
);
835 if (!NT_STATUS_IS_OK(result
)) {
836 DEBUG(1, ("get_trust_credentials(%s) failed: %s\n",
837 domain
->name
, nt_errstr(result
)));
842 * Without SPNEGO or NTLMSSP (perhaps via SMB2) we
843 * would try and authentication with our machine
844 * account password and fail. This is very rare in
845 * the modern world however
847 creds
= cli_credentials_init_anon(talloc_tos());
849 result
= NT_STATUS_NO_MEMORY
;
850 DEBUG(1, ("cli_credentials_init_anon(%s) failed: %s\n",
851 domain
->name
, nt_errstr(result
)));
856 machine_principal
= cli_credentials_get_principal(creds
,
858 machine_realm
= cli_credentials_get_realm(creds
);
859 machine_account
= cli_credentials_get_username(creds
);
860 machine_domain
= cli_credentials_get_domain(creds
);
862 DEBUG(5, ("connecting to %s (%s, %s) with account [%s\\%s] principal "
863 "[%s] and realm [%s]\n",
864 controller
, domain
->name
, domain
->alt_name
,
865 machine_domain
, machine_account
,
866 machine_principal
, machine_realm
));
868 if (cli_credentials_is_anonymous(creds
)) {
872 winbindd_set_locator_kdc_envs(domain
);
874 result
= cli_session_setup_creds(*cli
, creds
);
875 if (NT_STATUS_IS_OK(result
)) {
876 goto session_setup_done
;
879 DEBUG(1, ("authenticated session setup to %s using %s failed with %s\n",
881 cli_credentials_get_unparsed_name(creds
, talloc_tos()),
885 * If we are not going to validate the connection
886 * with SMB signing, then allow us to fall back to
889 if (NT_STATUS_EQUAL(result
, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT
)
890 || NT_STATUS_EQUAL(result
, NT_STATUS_TRUSTED_DOMAIN_FAILURE
)
891 || NT_STATUS_EQUAL(result
, NT_STATUS_INVALID_ACCOUNT_NAME
)
892 || NT_STATUS_EQUAL(result
, NT_STATUS_INVALID_COMPUTER_NAME
)
893 || NT_STATUS_EQUAL(result
, NT_STATUS_NO_SUCH_DOMAIN
)
894 || NT_STATUS_EQUAL(result
, NT_STATUS_NO_LOGON_SERVERS
)
895 || NT_STATUS_EQUAL(result
, NT_STATUS_LOGON_FAILURE
))
897 if (!cm_is_ipc_credentials(creds
)) {
901 if (smb_sign_client_connections
== SMB_SIGNING_REQUIRED
) {
912 tmp_status
= cm_get_ipc_credentials(talloc_tos(), &creds
);
913 if (!NT_STATUS_IS_OK(tmp_status
)) {
918 if (cli_credentials_is_anonymous(creds
)) {
922 machine_account
= cli_credentials_get_username(creds
);
923 machine_domain
= cli_credentials_get_domain(creds
);
925 DEBUG(5, ("connecting to %s from %s using NTLMSSP with username "
926 "[%s]\\[%s]\n", controller
, lp_netbios_name(),
927 machine_domain
, machine_account
));
929 result
= cli_session_setup_creds(*cli
, creds
);
930 if (NT_STATUS_IS_OK(result
)) {
931 goto session_setup_done
;
934 DEBUG(1, ("authenticated session setup to %s using %s failed with %s\n",
936 cli_credentials_get_unparsed_name(creds
, talloc_tos()),
940 * If we are not going to validate the connection
941 * with SMB signing, then allow us to fall back to
944 if (NT_STATUS_EQUAL(result
, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT
)
945 || NT_STATUS_EQUAL(result
, NT_STATUS_TRUSTED_DOMAIN_FAILURE
)
946 || NT_STATUS_EQUAL(result
, NT_STATUS_INVALID_ACCOUNT_NAME
)
947 || NT_STATUS_EQUAL(result
, NT_STATUS_INVALID_COMPUTER_NAME
)
948 || NT_STATUS_EQUAL(result
, NT_STATUS_NO_SUCH_DOMAIN
)
949 || NT_STATUS_EQUAL(result
, NT_STATUS_NO_LOGON_SERVERS
)
950 || NT_STATUS_EQUAL(result
, NT_STATUS_LOGON_FAILURE
))
960 if (smb_sign_client_connections
== SMB_SIGNING_REQUIRED
) {
964 /* Fall back to anonymous connection, this might fail later */
965 DEBUG(5,("cm_prepare_connection: falling back to anonymous "
966 "connection for DC %s\n",
969 result
= cli_session_setup_anon(*cli
);
970 if (NT_STATUS_IS_OK(result
)) {
971 DEBUG(5, ("Connected anonymously\n"));
972 goto session_setup_done
;
975 DEBUG(1, ("anonymous session setup to %s failed with %s\n",
976 controller
, nt_errstr(result
)));
978 /* We can't session setup */
985 * This should be a short term hack until
986 * dynamic re-authentication is implemented.
988 * See Bug 9175 - winbindd doesn't recover from
989 * NT_STATUS_NETWORK_SESSION_EXPIRED
991 if (smbXcli_conn_protocol((*cli
)->conn
) >= PROTOCOL_SMB2_02
) {
992 smbXcli_session_set_disconnect_expired((*cli
)->smb2
.session
);
995 result
= cli_tree_connect(*cli
, "IPC$", "IPC", NULL
);
996 if (!NT_STATUS_IS_OK(result
)) {
997 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(result
)));
1000 tcon_status
= result
;
1002 /* cache the server name for later connections */
1004 saf_store(domain
->name
, controller
);
1005 if (domain
->alt_name
) {
1006 saf_store(domain
->alt_name
, controller
);
1009 winbindd_set_locator_kdc_envs(domain
);
1014 result
= NT_STATUS_OK
;
1020 if (NT_STATUS_IS_OK(result
)) {
1021 result
= tcon_status
;
1024 if (!NT_STATUS_IS_OK(result
)) {
1025 DEBUG(1, ("Failed to prepare SMB connection to %s: %s\n",
1026 controller
, nt_errstr(result
)));
1027 winbind_add_failed_connection_entry(domain
, controller
, result
);
1028 if ((*cli
) != NULL
) {
1037 /*******************************************************************
1038 Add a dcname and sockaddr_storage pair to the end of a dc_name_ip
1041 Keeps the list unique by not adding duplicate entries.
1043 @param[in] mem_ctx talloc memory context to allocate from
1044 @param[in] domain_name domain of the DC
1045 @param[in] dcname name of the DC to add to the list
1046 @param[in] pss Internet address and port pair to add to the list
1047 @param[in,out] dcs array of dc_name_ip structures to add to
1048 @param[in,out] num_dcs number of dcs returned in the dcs array
1049 @return true if the list was added to, false otherwise
1050 *******************************************************************/
1052 static bool add_one_dc_unique(TALLOC_CTX
*mem_ctx
, const char *domain_name
,
1053 const char *dcname
, struct sockaddr_storage
*pss
,
1054 struct dc_name_ip
**dcs
, int *num
)
1058 if (!NT_STATUS_IS_OK(check_negative_conn_cache(domain_name
, dcname
))) {
1059 DEBUG(10, ("DC %s was in the negative conn cache\n", dcname
));
1063 /* Make sure there's no duplicates in the list */
1064 for (i
=0; i
<*num
; i
++)
1066 (struct sockaddr
*)(void *)&(*dcs
)[i
].ss
,
1067 (struct sockaddr
*)(void *)pss
))
1070 *dcs
= talloc_realloc(mem_ctx
, *dcs
, struct dc_name_ip
, (*num
)+1);
1075 fstrcpy((*dcs
)[*num
].name
, dcname
);
1076 (*dcs
)[*num
].ss
= *pss
;
1081 static bool add_sockaddr_to_array(TALLOC_CTX
*mem_ctx
,
1082 struct sockaddr_storage
*pss
, uint16_t port
,
1083 struct sockaddr_storage
**addrs
, int *num
)
1085 *addrs
= talloc_realloc(mem_ctx
, *addrs
, struct sockaddr_storage
, (*num
)+1);
1087 if (*addrs
== NULL
) {
1092 (*addrs
)[*num
] = *pss
;
1093 set_sockaddr_port((struct sockaddr
*)&(*addrs
)[*num
], port
);
1100 static bool dcip_check_name_ads(const struct winbindd_domain
*domain
,
1101 struct samba_sockaddr
*sa
,
1102 uint32_t request_flags
,
1103 TALLOC_CTX
*mem_ctx
,
1106 TALLOC_CTX
*tmp_ctx
= talloc_stackframe();
1108 ADS_STRUCT
*ads
= NULL
;
1109 ADS_STATUS ads_status
;
1110 char addr
[INET6_ADDRSTRLEN
];
1112 print_sockaddr(addr
, sizeof(addr
), &sa
->u
.ss
);
1113 D_DEBUG("Trying to figure out the DC name for domain '%s' at IP '%s'.\n",
1117 ads
= ads_init(tmp_ctx
,
1123 ads_status
= ADS_ERROR_NT(NT_STATUS_NO_MEMORY
);
1126 ads
->config
.flags
|= request_flags
;
1127 ads
->server
.no_fallback
= true;
1129 ads_status
= ads_connect_cldap_only(ads
);
1130 if (!ADS_ERR_OK(ads_status
)) {
1134 /* We got a cldap packet. */
1135 name
= talloc_strdup(tmp_ctx
, ads
->config
.ldap_server_name
);
1137 ads_status
= ADS_ERROR_NT(NT_STATUS_NO_MEMORY
);
1140 namecache_store(name
, 0x20, 1, sa
);
1142 DBG_DEBUG("CLDAP flags = 0x%"PRIx32
"\n", ads
->config
.flags
);
1144 if (domain
->primary
&& (ads
->config
.flags
& NBT_SERVER_KDC
)) {
1145 if (ads_closest_dc(ads
)) {
1146 char *sitename
= sitename_fetch(tmp_ctx
,
1149 /* We're going to use this KDC for this realm/domain.
1150 If we are using sites, then force the krb5 libs
1153 create_local_private_krb5_conf_for_domain(domain
->alt_name
,
1158 TALLOC_FREE(sitename
);
1160 /* use an off site KDC */
1161 create_local_private_krb5_conf_for_domain(domain
->alt_name
,
1166 winbindd_set_locator_kdc_envs(domain
);
1168 /* Ensure we contact this DC also. */
1169 saf_store(domain
->name
, name
);
1170 saf_store(domain
->alt_name
, name
);
1173 D_DEBUG("DC name for domain '%s' at IP '%s' is '%s'\n",
1177 *namep
= talloc_move(mem_ctx
, &name
);
1180 TALLOC_FREE(tmp_ctx
);
1182 return ADS_ERR_OK(ads_status
) ? true : false;
1186 /*******************************************************************
1187 convert an ip to a name
1188 For an AD Domain, it checks the requirements of the request flags.
1189 *******************************************************************/
1191 static bool dcip_check_name(TALLOC_CTX
*mem_ctx
,
1192 const struct winbindd_domain
*domain
,
1193 struct sockaddr_storage
*pss
,
1194 char **name
, uint32_t request_flags
)
1196 struct samba_sockaddr sa
= {0};
1197 uint32_t nt_version
= NETLOGON_NT_VERSION_1
;
1199 const char *dc_name
;
1202 bool is_ad_domain
= false;
1204 bool ok
= sockaddr_storage_to_samba_sockaddr(&sa
, pss
);
1210 /* For active directory servers, try to get the ldap server name.
1211 None of these failures should be considered critical for now */
1213 if ((lp_security() == SEC_ADS
) && (domain
->alt_name
!= NULL
)) {
1214 is_ad_domain
= true;
1215 } else if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC
) {
1216 is_ad_domain
= domain
->active_directory
;
1220 return dcip_check_name_ads(domain
,
1229 size_t len
= strlen(lp_netbios_name());
1230 char my_acct_name
[len
+2];
1232 snprintf(my_acct_name
,
1233 sizeof(my_acct_name
),
1237 status
= nbt_getdc(global_messaging_context(), 10, &sa
.u
.ss
,
1238 domain
->name
, &domain
->sid
,
1239 my_acct_name
, ACB_WSTRUST
,
1240 nt_version
, mem_ctx
, &nt_version
,
1243 if (NT_STATUS_IS_OK(status
)) {
1244 *name
= talloc_strdup(mem_ctx
, dc_name
);
1245 if (*name
== NULL
) {
1248 namecache_store(*name
, 0x20, 1, &sa
);
1252 /* try node status request */
1254 if (name_status_find(domain
->name
, 0x1c, 0x20, &sa
.u
.ss
, nbtname
) ) {
1255 namecache_store(nbtname
, 0x20, 1, &sa
);
1258 *name
= talloc_strdup(mem_ctx
, nbtname
);
1259 if (*name
== NULL
) {
1269 /*******************************************************************
1270 Retrieve a list of IP addresses for domain controllers.
1272 The array is sorted in the preferred connection order.
1274 @param[in] mem_ctx talloc memory context to allocate from
1275 @param[in] domain domain to retrieve DCs for
1276 @param[out] dcs array of dcs that will be returned
1277 @param[out] num_dcs number of dcs returned in the dcs array
1279 *******************************************************************/
1281 static bool get_dcs(TALLOC_CTX
*mem_ctx
, struct winbindd_domain
*domain
,
1282 struct dc_name_ip
**dcs
, int *num_dcs
,
1283 uint32_t request_flags
)
1286 struct sockaddr_storage ss
;
1287 struct samba_sockaddr
*sa_list
= NULL
;
1288 size_t salist_size
= 0;
1291 enum security_types sec
= (enum security_types
)lp_security();
1293 is_our_domain
= strequal(domain
->name
, lp_workgroup());
1295 /* If not our domain, get the preferred DC, by asking our primary DC */
1297 && get_dc_name_via_netlogon(domain
, dcname
, &ss
, request_flags
)
1298 && add_one_dc_unique(mem_ctx
, domain
->name
, dcname
, &ss
, dcs
,
1301 char addr
[INET6_ADDRSTRLEN
];
1302 print_sockaddr(addr
, sizeof(addr
), &ss
);
1303 DEBUG(10, ("Retrieved DC %s at %s via netlogon\n",
1308 if ((sec
== SEC_ADS
) && (domain
->alt_name
!= NULL
)) {
1309 char *sitename
= NULL
;
1311 /* We need to make sure we know the local site before
1312 doing any DNS queries, as this will restrict the
1313 get_sorted_dc_list() call below to only fetching
1314 DNS records for the correct site. */
1316 /* Find any DC to get the site record.
1317 We deliberately don't care about the
1320 get_dc_name(domain
->name
, domain
->alt_name
, dcname
, &ss
);
1322 sitename
= sitename_fetch(mem_ctx
, domain
->alt_name
);
1325 /* Do the site-specific AD dns lookup first. */
1326 (void)get_sorted_dc_list(mem_ctx
,
1333 /* Add ips to the DC array. We don't look up the name
1334 of the DC in this function, but we fill in the char*
1335 of the ip now to make the failed connection cache
1337 for ( i
=0; i
<salist_size
; i
++ ) {
1338 char addr
[INET6_ADDRSTRLEN
];
1339 print_sockaddr(addr
, sizeof(addr
),
1341 add_one_dc_unique(mem_ctx
,
1349 TALLOC_FREE(sa_list
);
1350 TALLOC_FREE(sitename
);
1354 /* Now we add DCs from the main AD DNS lookup. */
1355 (void)get_sorted_dc_list(mem_ctx
,
1362 for ( i
=0; i
<salist_size
; i
++ ) {
1363 char addr
[INET6_ADDRSTRLEN
];
1364 print_sockaddr(addr
, sizeof(addr
),
1366 add_one_dc_unique(mem_ctx
,
1374 TALLOC_FREE(sa_list
);
1378 /* Try standard netbios queries if no ADS and fall back to DNS queries
1379 * if alt_name is available */
1380 if (*num_dcs
== 0) {
1381 (void)get_sorted_dc_list(mem_ctx
,
1387 if (salist_size
== 0) {
1388 if (domain
->alt_name
!= NULL
) {
1389 (void)get_sorted_dc_list(mem_ctx
,
1398 for ( i
=0; i
<salist_size
; i
++ ) {
1399 char addr
[INET6_ADDRSTRLEN
];
1400 print_sockaddr(addr
, sizeof(addr
),
1402 add_one_dc_unique(mem_ctx
,
1410 TALLOC_FREE(sa_list
);
1417 static bool connect_preferred_dc(TALLOC_CTX
*mem_ctx
,
1418 struct winbindd_domain
*domain
,
1419 uint32_t request_flags
,
1422 char *saf_servername
= NULL
;
1427 * We have to check the server affinity cache here since later we select
1428 * a DC based on response time and not preference.
1430 if (domain
->force_dc
) {
1431 saf_servername
= domain
->dcname
;
1433 saf_servername
= saf_fetch(mem_ctx
, domain
->name
);
1437 * Check the negative connection cache before talking to it. It going
1438 * down may have triggered the reconnection.
1440 if (saf_servername
!= NULL
) {
1441 status
= check_negative_conn_cache(domain
->name
,
1443 if (!NT_STATUS_IS_OK(status
)) {
1444 saf_servername
= NULL
;
1448 if (saf_servername
!= NULL
) {
1449 DBG_DEBUG("saf_servername is '%s' for domain %s\n",
1450 saf_servername
, domain
->name
);
1452 /* convert an ip address to a name */
1453 if (is_ipaddress(saf_servername
)) {
1454 ok
= interpret_string_addr(&domain
->dcaddr
,
1461 ok
= resolve_name(saf_servername
,
1470 TALLOC_FREE(domain
->dcname
);
1471 ok
= dcip_check_name(domain
,
1481 if (domain
->dcname
== NULL
) {
1485 status
= check_negative_conn_cache(domain
->name
, domain
->dcname
);
1486 if (!NT_STATUS_IS_OK(status
)) {
1490 status
= smbsock_connect(&domain
->dcaddr
, 0,
1493 if (!NT_STATUS_IS_OK(status
)) {
1494 winbind_add_failed_connection_entry(domain
,
1496 NT_STATUS_UNSUCCESSFUL
);
1502 winbind_add_failed_connection_entry(domain
,
1504 NT_STATUS_UNSUCCESSFUL
);
1509 /*******************************************************************
1510 Find and make a connection to a DC in the given domain.
1512 @param[in] mem_ctx talloc memory context to allocate from
1513 @param[in] domain domain to find a dc in
1514 @param[out] fd fd of the open socket connected to the newly found dc
1515 @return true when a DC connection is made, false otherwise
1516 *******************************************************************/
1518 static bool find_dc(TALLOC_CTX
*mem_ctx
,
1519 struct winbindd_domain
*domain
,
1520 uint32_t request_flags
,
1523 struct dc_name_ip
*dcs
= NULL
;
1526 const char **dcnames
= NULL
;
1527 size_t num_dcnames
= 0;
1529 struct sockaddr_storage
*addrs
= NULL
;
1540 D_NOTICE("First try to connect to the closest DC (using server "
1541 "affinity cache). If this fails, try to lookup the DC using "
1542 "DNS afterwards.\n");
1543 ok
= connect_preferred_dc(mem_ctx
, domain
, request_flags
, fd
);
1548 if (domain
->force_dc
) {
1553 D_DEBUG("Retrieving a list of IP addresses for DCs.\n");
1554 if (!get_dcs(mem_ctx
, domain
, &dcs
, &num_dcs
, request_flags
) || (num_dcs
== 0))
1557 D_DEBUG("Retrieved IP addresses for %d DCs.\n", num_dcs
);
1558 for (i
=0; i
<num_dcs
; i
++) {
1560 if (!add_string_to_array(mem_ctx
, dcs
[i
].name
,
1561 &dcnames
, &num_dcnames
)) {
1564 if (!add_sockaddr_to_array(mem_ctx
, &dcs
[i
].ss
, TCP_SMB_PORT
,
1565 &addrs
, &num_addrs
)) {
1570 if ((num_dcnames
== 0) || (num_dcnames
!= num_addrs
))
1573 if ((addrs
== NULL
) || (dcnames
== NULL
))
1576 D_DEBUG("Trying to establish a connection to one of the %d DCs "
1577 "(timeout of 10 sec for each DC).\n",
1579 status
= smbsock_any_connect(addrs
, dcnames
, NULL
, NULL
, NULL
,
1580 num_addrs
, 0, 10, fd
, &fd_index
, NULL
);
1581 if (!NT_STATUS_IS_OK(status
)) {
1582 for (i
=0; i
<num_dcs
; i
++) {
1583 char ab
[INET6_ADDRSTRLEN
];
1584 print_sockaddr(ab
, sizeof(ab
), &dcs
[i
].ss
);
1585 DBG_DEBUG("smbsock_any_connect failed for "
1586 "domain %s address %s. Error was %s\n",
1587 domain
->name
, ab
, nt_errstr(status
));
1588 winbind_add_failed_connection_entry(domain
,
1589 dcs
[i
].name
, NT_STATUS_UNSUCCESSFUL
);
1593 D_NOTICE("Successfully connected to DC '%s'.\n", dcs
[fd_index
].name
);
1595 domain
->dcaddr
= addrs
[fd_index
];
1597 if (*dcnames
[fd_index
] != '\0' && !is_ipaddress(dcnames
[fd_index
])) {
1598 /* Ok, we've got a name for the DC */
1599 TALLOC_FREE(domain
->dcname
);
1600 domain
->dcname
= talloc_strdup(domain
, dcnames
[fd_index
]);
1601 if (domain
->dcname
== NULL
) {
1607 /* Try to figure out the name */
1608 TALLOC_FREE(domain
->dcname
);
1609 ok
= dcip_check_name(domain
,
1618 /* We can not continue without the DC's name */
1619 winbind_add_failed_connection_entry(domain
, dcs
[fd_index
].name
,
1620 NT_STATUS_UNSUCCESSFUL
);
1622 /* Throw away all arrays as we're doing this again. */
1626 TALLOC_FREE(dcnames
);
1638 * This should not be an infinite loop, since get_dcs() will not return
1639 * the DC added to the negative connection cache in the above
1640 * winbind_add_failed_connection_entry() call.
1645 static char *current_dc_key(TALLOC_CTX
*mem_ctx
, const char *domain_name
)
1647 return talloc_asprintf_strupper_m(mem_ctx
, "CURRENT_DCNAME/%s",
1651 static void store_current_dc_in_gencache(const char *domain_name
,
1652 const char *dc_name
,
1653 struct cli_state
*cli
)
1655 char addr
[INET6_ADDRSTRLEN
];
1659 if (!cli_state_is_connected(cli
)) {
1663 print_sockaddr(addr
, sizeof(addr
),
1664 smbXcli_conn_remote_sockaddr(cli
->conn
));
1666 key
= current_dc_key(talloc_tos(), domain_name
);
1671 value
= talloc_asprintf(talloc_tos(), "%s %s", addr
, dc_name
);
1672 if (value
== NULL
) {
1676 gencache_set(key
, value
, 0x7fffffff);
1682 bool fetch_current_dc_from_gencache(TALLOC_CTX
*mem_ctx
,
1683 const char *domain_name
,
1684 char **p_dc_name
, char **p_dc_ip
)
1689 char *dc_name
= NULL
;
1692 key
= current_dc_key(talloc_tos(), domain_name
);
1696 if (!gencache_get(key
, mem_ctx
, &value
, NULL
)) {
1699 p
= strchr(value
, ' ');
1703 dc_ip
= talloc_strndup(mem_ctx
, value
, p
- value
);
1704 if (dc_ip
== NULL
) {
1707 dc_name
= talloc_strdup(mem_ctx
, p
+1);
1708 if (dc_name
== NULL
) {
1712 if (p_dc_ip
!= NULL
) {
1716 if (p_dc_name
!= NULL
) {
1717 *p_dc_name
= dc_name
;
1722 TALLOC_FREE(dc_name
);
1729 NTSTATUS
wb_open_internal_pipe(TALLOC_CTX
*mem_ctx
,
1730 const struct ndr_interface_table
*table
,
1731 struct rpc_pipe_client
**ret_pipe
)
1733 struct rpc_pipe_client
*cli
= NULL
;
1734 const struct auth_session_info
*session_info
= NULL
;
1735 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
1738 session_info
= get_session_info_system();
1739 SMB_ASSERT(session_info
!= NULL
);
1741 status
= rpc_pipe_open_local_np(
1742 mem_ctx
, table
, NULL
, NULL
, NULL
, NULL
, session_info
, &cli
);
1743 if (!NT_STATUS_IS_OK(status
)) {
1751 return NT_STATUS_OK
;
1754 static NTSTATUS
cm_open_connection(struct winbindd_domain
*domain
,
1755 struct winbindd_cm_conn
*new_conn
,
1758 TALLOC_CTX
*mem_ctx
;
1759 NTSTATUS result
= NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND
;
1761 uint32_t request_flags
= need_rw_dc
? DS_WRITABLE_REQUIRED
: 0;
1764 bool seal_pipes
= true;
1766 if ((mem_ctx
= talloc_init("cm_open_connection")) == NULL
) {
1767 set_domain_offline(domain
);
1768 return NT_STATUS_NO_MEMORY
;
1771 D_NOTICE("Creating connection to domain controller. This is a start of "
1772 "a new connection or a DC failover. The failover only happens "
1773 "if the domain has more than one DC. We will try to connect 3 "
1774 "times at most.\n");
1775 for (retries
= 0; retries
< 3; retries
++) {
1778 D_DEBUG("Attempt %d/3: DC '%s' of domain '%s'.\n",
1780 domain
->dcname
? domain
->dcname
: "",
1783 found_dc
= find_dc(mem_ctx
, domain
, request_flags
, &fd
);
1785 /* This is the one place where we will
1786 set the global winbindd offline state
1787 to true, if a "WINBINDD_OFFLINE" entry
1788 is found in the winbindd cache. */
1789 set_global_winbindd_state_offline();
1790 result
= NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND
;
1794 new_conn
->cli
= NULL
;
1796 result
= cm_prepare_connection(domain
, fd
, domain
->dcname
,
1797 &new_conn
->cli
, &retry
);
1798 if (NT_STATUS_IS_OK(result
)) {
1806 if (!NT_STATUS_IS_OK(result
)) {
1807 /* Ensure we setup the retry handler. */
1808 set_domain_offline(domain
);
1812 winbindd_set_locator_kdc_envs(domain
);
1814 if (domain
->online
== False
) {
1815 /* We're changing state from offline to online. */
1816 set_global_winbindd_state_online();
1818 set_domain_online(domain
);
1821 * Much as I hate global state, this seems to be the point
1822 * where we can be certain that we have a proper connection to
1823 * a DC. wbinfo --dc-info needs that information, store it in
1824 * gencache with a looong timeout. This will need revisiting
1825 * once we start to connect to multiple DCs, wbcDcInfo is
1826 * already prepared for that.
1828 store_current_dc_in_gencache(domain
->name
, domain
->dcname
,
1831 seal_pipes
= lp_winbind_sealed_pipes();
1832 seal_pipes
= lp_parm_bool(-1, "winbind sealed pipes",
1837 new_conn
->auth_level
= DCERPC_AUTH_LEVEL_PRIVACY
;
1839 new_conn
->auth_level
= DCERPC_AUTH_LEVEL_INTEGRITY
;
1843 talloc_destroy(mem_ctx
);
1847 /* Close down all open pipes on a connection. */
1849 void invalidate_cm_connection(struct winbindd_domain
*domain
)
1852 struct winbindd_cm_conn
*conn
= &domain
->conn
;
1854 domain
->sequence_number
= DOM_SEQUENCE_NONE
;
1855 domain
->last_seq_check
= 0;
1856 domain
->last_status
= NT_STATUS_SERVER_DISABLED
;
1858 /* We're closing down a possibly dead
1859 connection. Don't have impossibly long (10s) timeouts. */
1862 cli_set_timeout(conn
->cli
, 1000); /* 1 second. */
1865 if (conn
->samr_pipe
!= NULL
) {
1866 if (is_valid_policy_hnd(&conn
->sam_connect_handle
)) {
1867 dcerpc_samr_Close(conn
->samr_pipe
->binding_handle
,
1869 &conn
->sam_connect_handle
,
1872 TALLOC_FREE(conn
->samr_pipe
);
1873 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1875 cli_set_timeout(conn
->cli
, 500);
1879 if (conn
->lsa_pipe
!= NULL
) {
1880 if (is_valid_policy_hnd(&conn
->lsa_policy
)) {
1881 dcerpc_lsa_Close(conn
->lsa_pipe
->binding_handle
,
1886 TALLOC_FREE(conn
->lsa_pipe
);
1887 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1889 cli_set_timeout(conn
->cli
, 500);
1893 if (conn
->lsa_pipe_tcp
!= NULL
) {
1894 if (is_valid_policy_hnd(&conn
->lsa_policy
)) {
1895 dcerpc_lsa_Close(conn
->lsa_pipe_tcp
->binding_handle
,
1900 TALLOC_FREE(conn
->lsa_pipe_tcp
);
1901 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1903 cli_set_timeout(conn
->cli
, 500);
1907 if (conn
->netlogon_pipe
!= NULL
) {
1908 TALLOC_FREE(conn
->netlogon_pipe
);
1909 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1911 cli_set_timeout(conn
->cli
, 500);
1915 conn
->auth_level
= DCERPC_AUTH_LEVEL_PRIVACY
;
1916 TALLOC_FREE(conn
->netlogon_creds_ctx
);
1919 cli_shutdown(conn
->cli
);
1925 void close_conns_after_fork(void)
1927 struct winbindd_domain
*domain
;
1928 struct winbindd_cli_state
*cli_state
;
1930 for (domain
= domain_list(); domain
; domain
= domain
->next
) {
1932 * first close the low level SMB TCP connection
1933 * so that we don't generate any SMBclose
1934 * requests in invalidate_cm_connection()
1936 if (cli_state_is_connected(domain
->conn
.cli
)) {
1937 smbXcli_conn_disconnect(domain
->conn
.cli
->conn
, NT_STATUS_OK
);
1940 invalidate_cm_connection(domain
);
1943 for (cli_state
= winbindd_client_list();
1945 cli_state
= cli_state
->next
) {
1946 if (cli_state
->sock
>= 0) {
1947 close(cli_state
->sock
);
1948 cli_state
->sock
= -1;
1953 static bool connection_ok(struct winbindd_domain
*domain
)
1957 ok
= cli_state_is_connected(domain
->conn
.cli
);
1959 DEBUG(3, ("connection_ok: Connection to %s for domain %s is not connected\n",
1960 domain
->dcname
, domain
->name
));
1964 if (!domain
->online
) {
1965 DEBUG(3, ("connection_ok: Domain %s is offline\n", domain
->name
));
1972 /* Initialize a new connection up to the RPC BIND.
1973 Bypass online status check so always does network calls. */
1975 static NTSTATUS
init_dc_connection_network(struct winbindd_domain
*domain
, bool need_rw_dc
)
1978 bool skip_connection
= domain
->internal
;
1979 if (need_rw_dc
&& domain
->rodc
) {
1980 skip_connection
= false;
1983 /* Internal connections never use the network. */
1984 if (dom_sid_equal(&domain
->sid
, &global_sid_Builtin
)) {
1985 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
1988 /* Still ask the internal LSA and SAMR server about the local domain */
1989 if (skip_connection
|| connection_ok(domain
)) {
1990 if (!domain
->initialized
) {
1991 set_dc_type_and_flags(domain
);
1993 return NT_STATUS_OK
;
1996 invalidate_cm_connection(domain
);
1998 if (!domain
->primary
&& !domain
->initialized
) {
2000 * Before we connect to a trust, work out if it is an
2001 * AD domain by asking our own domain.
2003 set_dc_type_and_flags_trustinfo(domain
);
2006 result
= cm_open_connection(domain
, &domain
->conn
, need_rw_dc
);
2008 if (NT_STATUS_IS_OK(result
) && !domain
->initialized
) {
2009 set_dc_type_and_flags(domain
);
2015 NTSTATUS
init_dc_connection(struct winbindd_domain
*domain
, bool need_rw_dc
)
2017 if (dom_sid_equal(&domain
->sid
, &global_sid_Builtin
)) {
2018 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
2021 SMB_ASSERT(wb_child_domain() || idmap_child());
2023 return init_dc_connection_network(domain
, need_rw_dc
);
2026 static NTSTATUS
init_dc_connection_rpc(struct winbindd_domain
*domain
, bool need_rw_dc
)
2030 status
= init_dc_connection(domain
, need_rw_dc
);
2031 if (!NT_STATUS_IS_OK(status
)) {
2035 if (!domain
->internal
&& domain
->conn
.cli
== NULL
) {
2036 /* happens for trusted domains without inbound trust */
2037 return NT_STATUS_TRUSTED_DOMAIN_FAILURE
;
2040 return NT_STATUS_OK
;
2043 /******************************************************************************
2044 Set the trust flags (direction and forest location) for a domain
2045 ******************************************************************************/
2047 static bool set_dc_type_and_flags_trustinfo( struct winbindd_domain
*domain
)
2049 struct winbindd_domain
*our_domain
;
2050 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
2052 struct netr_DomainTrustList trusts
;
2054 uint32_t flags
= (NETR_TRUST_FLAG_IN_FOREST
|
2055 NETR_TRUST_FLAG_OUTBOUND
|
2056 NETR_TRUST_FLAG_INBOUND
);
2057 struct rpc_pipe_client
*cli
;
2058 TALLOC_CTX
*mem_ctx
= NULL
;
2059 struct dcerpc_binding_handle
*b
;
2063 * On a DC we loaded all trusts
2064 * from configuration and never learn
2070 DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s\n", domain
->name
));
2072 /* Our primary domain doesn't need to worry about trust flags.
2073 Force it to go through the network setup */
2074 if ( domain
->primary
) {
2078 mem_ctx
= talloc_stackframe();
2079 our_domain
= find_our_domain();
2080 if (our_domain
->internal
) {
2081 result
= init_dc_connection(our_domain
, false);
2082 if (!NT_STATUS_IS_OK(result
)) {
2083 DEBUG(3,("set_dc_type_and_flags_trustinfo: "
2084 "Not able to make a connection to our domain: %s\n",
2085 nt_errstr(result
)));
2086 TALLOC_FREE(mem_ctx
);
2091 /* This won't work unless our domain is AD */
2092 if ( !our_domain
->active_directory
) {
2093 TALLOC_FREE(mem_ctx
);
2097 if (our_domain
->internal
) {
2098 result
= wb_open_internal_pipe(mem_ctx
, &ndr_table_netlogon
, &cli
);
2099 } else if (!connection_ok(our_domain
)) {
2100 DEBUG(3,("set_dc_type_and_flags_trustinfo: "
2101 "No connection to our domain!\n"));
2102 TALLOC_FREE(mem_ctx
);
2105 result
= cm_connect_netlogon(our_domain
, &cli
);
2108 if (!NT_STATUS_IS_OK(result
)) {
2109 DEBUG(5, ("set_dc_type_and_flags_trustinfo: Could not open "
2110 "a connection to %s for PIPE_NETLOGON (%s)\n",
2111 domain
->name
, nt_errstr(result
)));
2112 TALLOC_FREE(mem_ctx
);
2115 b
= cli
->binding_handle
;
2117 /* Use DsEnumerateDomainTrusts to get us the trust direction and type. */
2118 result
= dcerpc_netr_DsrEnumerateDomainTrusts(b
, mem_ctx
,
2123 if (!NT_STATUS_IS_OK(result
)) {
2124 DEBUG(0,("set_dc_type_and_flags_trustinfo: "
2125 "failed to query trusted domain list: %s\n",
2126 nt_errstr(result
)));
2127 TALLOC_FREE(mem_ctx
);
2130 if (!W_ERROR_IS_OK(werr
)) {
2131 DEBUG(0,("set_dc_type_and_flags_trustinfo: "
2132 "failed to query trusted domain list: %s\n",
2134 TALLOC_FREE(mem_ctx
);
2138 /* Now find the domain name and get the flags */
2140 for ( i
=0; i
<trusts
.count
; i
++ ) {
2141 if ( strequal( domain
->name
, trusts
.array
[i
].netbios_name
) ) {
2142 domain
->domain_flags
= trusts
.array
[i
].trust_flags
;
2143 domain
->domain_type
= trusts
.array
[i
].trust_type
;
2144 domain
->domain_trust_attribs
= trusts
.array
[i
].trust_attributes
;
2146 if ( domain
->domain_type
== LSA_TRUST_TYPE_UPLEVEL
)
2147 domain
->active_directory
= True
;
2149 /* This flag is only set if the domain is *our*
2150 primary domain and the primary domain is in
2153 domain
->native_mode
= (domain
->domain_flags
& NETR_TRUST_FLAG_NATIVE
);
2155 DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s is %sin "
2156 "native mode.\n", domain
->name
,
2157 domain
->native_mode
? "" : "NOT "));
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
;
2189 TALLOC_CTX
*mem_ctx
= NULL
;
2190 struct rpc_pipe_client
*cli
= NULL
;
2191 struct policy_handle pol
= { .handle_type
= 0 };
2192 union dssetup_DsRoleInfo info
;
2193 union lsa_PolicyInformation
*lsa_info
= NULL
;
2194 union lsa_revision_info out_revision_info
= {
2199 uint32_t out_version
= 0;
2201 if (!domain
->internal
&& !connection_ok(domain
)) {
2205 mem_ctx
= talloc_init("set_dc_type_and_flags on domain %s\n",
2208 DEBUG(1, ("set_dc_type_and_flags_connect: talloc_init() failed\n"));
2212 DEBUG(5, ("set_dc_type_and_flags_connect: domain %s\n", domain
->name
));
2214 if (domain
->internal
) {
2215 status
= wb_open_internal_pipe(mem_ctx
,
2219 status
= cli_rpc_pipe_open_noauth(domain
->conn
.cli
,
2224 if (!NT_STATUS_IS_OK(status
)) {
2225 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
2226 "PI_DSSETUP on domain %s: (%s)\n",
2227 domain
->name
, nt_errstr(status
)));
2229 /* if this is just a non-AD domain we need to continue
2230 * identifying so that we can in the end return with
2231 * domain->initialized = True - gd */
2236 status
= dcerpc_dssetup_DsRoleGetPrimaryDomainInformation(cli
->binding_handle
, mem_ctx
,
2237 DS_ROLE_BASIC_INFORMATION
,
2242 if (NT_STATUS_IS_OK(status
)) {
2243 result
= werror_to_ntstatus(werr
);
2245 if (!NT_STATUS_IS_OK(status
)) {
2246 DEBUG(5, ("set_dc_type_and_flags_connect: rpccli_ds_getprimarydominfo "
2247 "on domain %s failed: (%s)\n",
2248 domain
->name
, nt_errstr(status
)));
2250 /* older samba3 DCs will return DCERPC_FAULT_OP_RNG_ERROR for
2251 * every opcode on the DSSETUP pipe, continue with
2252 * no_dssetup mode here as well to get domain->initialized
2255 if (NT_STATUS_EQUAL(status
, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE
)) {
2259 TALLOC_FREE(mem_ctx
);
2263 if ((info
.basic
.flags
& DS_ROLE_PRIMARY_DS_RUNNING
) &&
2264 !(info
.basic
.flags
& DS_ROLE_PRIMARY_DS_MIXED_MODE
)) {
2265 domain
->native_mode
= True
;
2267 domain
->native_mode
= False
;
2271 if (domain
->internal
) {
2272 status
= wb_open_internal_pipe(mem_ctx
,
2276 status
= cli_rpc_pipe_open_noauth(domain
->conn
.cli
,
2277 &ndr_table_lsarpc
, &cli
);
2279 if (!NT_STATUS_IS_OK(status
)) {
2280 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
2281 "PI_LSARPC on domain %s: (%s)\n",
2282 domain
->name
, nt_errstr(status
)));
2284 TALLOC_FREE(mem_ctx
);
2288 status
= dcerpc_lsa_open_policy_fallback(cli
->binding_handle
,
2290 cli
->srv_name_slash
,
2292 SEC_FLAG_MAXIMUM_ALLOWED
,
2298 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(result
)) {
2299 /* This particular query is exactly what Win2k clients use
2300 to determine that the DC is active directory */
2301 status
= dcerpc_lsa_QueryInfoPolicy2(cli
->binding_handle
, mem_ctx
,
2303 LSA_POLICY_INFO_DNS
,
2309 * If the status and result will not be OK we will fallback to
2312 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(result
)) {
2313 domain
->active_directory
= True
;
2315 if (lsa_info
->dns
.name
.string
) {
2316 if (!strequal(domain
->name
, lsa_info
->dns
.name
.string
))
2318 DEBUG(1, ("set_dc_type_and_flags_connect: DC "
2319 "for domain %s claimed it was a DC "
2320 "for domain %s, refusing to "
2323 lsa_info
->dns
.name
.string
));
2325 TALLOC_FREE(mem_ctx
);
2328 talloc_free(domain
->name
);
2329 domain
->name
= talloc_strdup(domain
,
2330 lsa_info
->dns
.name
.string
);
2331 if (domain
->name
== NULL
) {
2336 if (lsa_info
->dns
.dns_domain
.string
) {
2337 if (domain
->alt_name
!= NULL
&&
2338 !strequal(domain
->alt_name
,
2339 lsa_info
->dns
.dns_domain
.string
))
2341 DEBUG(1, ("set_dc_type_and_flags_connect: DC "
2342 "for domain %s (%s) claimed it was "
2343 "a DC for domain %s, refusing to "
2345 domain
->alt_name
, domain
->name
,
2346 lsa_info
->dns
.dns_domain
.string
));
2348 TALLOC_FREE(mem_ctx
);
2351 talloc_free(domain
->alt_name
);
2353 talloc_strdup(domain
,
2354 lsa_info
->dns
.dns_domain
.string
);
2355 if (domain
->alt_name
== NULL
) {
2360 /* See if we can set some domain trust flags about
2363 if (lsa_info
->dns
.dns_forest
.string
) {
2364 talloc_free(domain
->forest_name
);
2365 domain
->forest_name
=
2366 talloc_strdup(domain
,
2367 lsa_info
->dns
.dns_forest
.string
);
2368 if (domain
->forest_name
== NULL
) {
2372 if (strequal(domain
->forest_name
, domain
->alt_name
)) {
2373 domain
->domain_flags
|= NETR_TRUST_FLAG_TREEROOT
;
2377 if (lsa_info
->dns
.sid
) {
2378 if (!is_null_sid(&domain
->sid
) &&
2379 !dom_sid_equal(&domain
->sid
,
2382 struct dom_sid_buf buf1
, buf2
;
2383 DEBUG(1, ("set_dc_type_and_flags_connect: DC "
2384 "for domain %s (%s) claimed it was "
2385 "a DC for domain %s, refusing to "
2387 dom_sid_str_buf(&domain
->sid
, &buf1
),
2389 dom_sid_str_buf(lsa_info
->dns
.sid
,
2392 TALLOC_FREE(mem_ctx
);
2395 sid_copy(&domain
->sid
, lsa_info
->dns
.sid
);
2398 domain
->active_directory
= False
;
2400 status
= rpccli_lsa_open_policy(cli
, mem_ctx
, True
,
2401 SEC_FLAG_MAXIMUM_ALLOWED
,
2404 if (!NT_STATUS_IS_OK(status
)) {
2408 status
= dcerpc_lsa_QueryInfoPolicy(cli
->binding_handle
, mem_ctx
,
2410 LSA_POLICY_INFO_ACCOUNT_DOMAIN
,
2413 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(result
)) {
2415 if (lsa_info
->account_domain
.name
.string
) {
2416 if (!strequal(domain
->name
,
2417 lsa_info
->account_domain
.name
.string
))
2420 ("set_dc_type_and_flags_connect: "
2421 "DC for domain %s claimed it was"
2422 " a DC for domain %s, refusing "
2423 "to initialize\n", domain
->name
,
2425 account_domain
.name
.string
));
2427 TALLOC_FREE(mem_ctx
);
2430 talloc_free(domain
->name
);
2432 talloc_strdup(domain
,
2433 lsa_info
->account_domain
.name
.string
);
2436 if (lsa_info
->account_domain
.sid
) {
2437 if (!is_null_sid(&domain
->sid
) &&
2438 !dom_sid_equal(&domain
->sid
,
2439 lsa_info
->account_domain
.sid
))
2441 struct dom_sid_buf buf1
, buf2
;
2443 ("set_dc_type_and_flags_connect: "
2444 "DC for domain %s (%s) claimed "
2445 "it was a DC for domain %s, "
2446 "refusing to initialize\n",
2448 &domain
->sid
, &buf1
),
2451 lsa_info
->account_domain
.sid
,
2454 TALLOC_FREE(mem_ctx
);
2457 sid_copy(&domain
->sid
, lsa_info
->account_domain
.sid
);
2462 if (is_valid_policy_hnd(&pol
)) {
2463 dcerpc_lsa_Close(cli
->binding_handle
,
2469 DEBUG(5, ("set_dc_type_and_flags_connect: domain %s is %sin native mode.\n",
2470 domain
->name
, domain
->native_mode
? "" : "NOT "));
2472 DEBUG(5,("set_dc_type_and_flags_connect: domain %s is %srunning active directory.\n",
2473 domain
->name
, domain
->active_directory
? "" : "NOT "));
2475 domain
->can_do_ncacn_ip_tcp
= domain
->active_directory
;
2479 TALLOC_FREE(mem_ctx
);
2481 domain
->initialized
= True
;
2484 /**********************************************************************
2485 Set the domain_flags (trust attributes, domain operating modes, etc...
2486 ***********************************************************************/
2488 static void set_dc_type_and_flags( struct winbindd_domain
*domain
)
2492 * On a DC we loaded all trusts
2493 * from configuration and never learn
2499 /* we always have to contact our primary domain */
2501 if ( domain
->primary
|| domain
->internal
) {
2502 DEBUG(10,("set_dc_type_and_flags: setting up flags for "
2503 "primary or internal domain\n"));
2504 set_dc_type_and_flags_connect( domain
);
2508 /* Use our DC to get the information if possible */
2510 if ( !set_dc_type_and_flags_trustinfo( domain
) ) {
2511 /* Otherwise, fallback to contacting the
2513 set_dc_type_and_flags_connect( domain
);
2521 /**********************************************************************
2522 ***********************************************************************/
2524 static NTSTATUS
cm_get_schannel_creds(struct winbindd_domain
*domain
,
2525 struct netlogon_creds_cli_context
**ppdc
)
2527 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
2528 struct rpc_pipe_client
*netlogon_pipe
;
2532 if ((!IS_DC
) && (!domain
->primary
)) {
2533 return NT_STATUS_TRUSTED_DOMAIN_FAILURE
;
2536 if (domain
->conn
.netlogon_creds_ctx
!= NULL
) {
2537 *ppdc
= domain
->conn
.netlogon_creds_ctx
;
2538 return NT_STATUS_OK
;
2541 result
= cm_connect_netlogon_secure(domain
, &netlogon_pipe
, ppdc
);
2542 if (!NT_STATUS_IS_OK(result
)) {
2546 return NT_STATUS_OK
;
2549 NTSTATUS
cm_connect_sam(struct winbindd_domain
*domain
, TALLOC_CTX
*mem_ctx
,
2551 struct rpc_pipe_client
**cli
, struct policy_handle
*sam_handle
)
2553 struct winbindd_cm_conn
*conn
;
2554 NTSTATUS status
, result
;
2555 struct netlogon_creds_cli_context
*p_creds
;
2556 struct cli_credentials
*creds
= NULL
;
2557 bool retry
= false; /* allow one retry attempt for expired session */
2558 const char *remote_name
= NULL
;
2559 const struct sockaddr_storage
*remote_sockaddr
= NULL
;
2560 bool sealed_pipes
= true;
2561 bool strong_key
= true;
2563 if (sid_check_is_our_sam(&domain
->sid
)) {
2564 if (domain
->rodc
== false || need_rw_dc
== false) {
2565 return open_internal_samr_conn(mem_ctx
, domain
, cli
, sam_handle
);
2571 * In theory we should not use SAMR within
2572 * winbindd at all, but that's a larger task to
2573 * remove this and avoid breaking existing
2576 * At least as AD DC we have the restriction
2577 * to avoid SAMR against trusted domains,
2578 * as there're no existing setups.
2580 return NT_STATUS_REQUEST_NOT_ACCEPTED
;
2584 status
= init_dc_connection_rpc(domain
, need_rw_dc
);
2585 if (!NT_STATUS_IS_OK(status
)) {
2589 conn
= &domain
->conn
;
2591 if (rpccli_is_connected(conn
->samr_pipe
)) {
2595 TALLOC_FREE(conn
->samr_pipe
);
2598 * No SAMR pipe yet. Attempt to get an NTLMSSP SPNEGO authenticated
2599 * sign and sealed pipe using the machine account password by
2600 * preference. If we can't - try schannel, if that fails, try
2604 result
= get_trust_credentials(domain
, talloc_tos(), false, &creds
);
2605 if (!NT_STATUS_IS_OK(result
)) {
2606 DEBUG(10, ("cm_connect_sam: No user available for "
2607 "domain %s, trying schannel\n", domain
->name
));
2611 if (cli_credentials_is_anonymous(creds
)) {
2615 remote_name
= smbXcli_conn_remote_name(conn
->cli
->conn
);
2616 remote_sockaddr
= smbXcli_conn_remote_sockaddr(conn
->cli
->conn
);
2619 * We have an authenticated connection. Use a SPNEGO
2620 * authenticated SAMR pipe with sign & seal.
2622 status
= cli_rpc_pipe_open_with_creds(conn
->cli
,
2625 DCERPC_AUTH_TYPE_SPNEGO
,
2632 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)
2634 invalidate_cm_connection(domain
);
2639 if (!NT_STATUS_IS_OK(status
)) {
2640 DEBUG(10,("cm_connect_sam: failed to connect to SAMR "
2641 "pipe for domain %s using NTLMSSP "
2642 "authenticated pipe: user %s. Error was "
2643 "%s\n", domain
->name
,
2644 cli_credentials_get_unparsed_name(creds
, talloc_tos()),
2645 nt_errstr(status
)));
2649 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for "
2650 "domain %s using NTLMSSP authenticated "
2651 "pipe: user %s\n", domain
->name
,
2652 cli_credentials_get_unparsed_name(creds
, talloc_tos())));
2654 status
= dcerpc_samr_Connect2(conn
->samr_pipe
->binding_handle
, mem_ctx
,
2655 conn
->samr_pipe
->desthost
,
2656 SEC_FLAG_MAXIMUM_ALLOWED
,
2657 &conn
->sam_connect_handle
,
2660 if (NT_STATUS_EQUAL(status
, NT_STATUS_IO_DEVICE_ERROR
) && !retry
) {
2661 invalidate_cm_connection(domain
);
2662 TALLOC_FREE(conn
->samr_pipe
);
2667 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(result
)) {
2670 if (NT_STATUS_IS_OK(status
)) {
2674 DEBUG(10,("cm_connect_sam: ntlmssp-sealed dcerpc_samr_Connect2 "
2675 "failed for domain %s, error was %s. Trying schannel\n",
2676 domain
->name
, nt_errstr(status
) ));
2677 TALLOC_FREE(conn
->samr_pipe
);
2681 /* Fall back to schannel if it's a W2K pre-SP1 box. */
2683 status
= cm_get_schannel_creds(domain
, &p_creds
);
2684 if (!NT_STATUS_IS_OK(status
)) {
2685 /* If this call fails - conn->cli can now be NULL ! */
2686 DEBUG(10, ("cm_connect_sam: Could not get schannel auth info "
2687 "for domain %s (error %s), trying anon\n",
2689 nt_errstr(status
) ));
2693 status
= cli_rpc_pipe_open_schannel_with_creds(
2694 conn
->cli
, &ndr_table_samr
, NCACN_NP
, p_creds
,
2699 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)
2701 invalidate_cm_connection(domain
);
2706 if (!NT_STATUS_IS_OK(status
)) {
2707 DEBUG(10,("cm_connect_sam: failed to connect to SAMR pipe for "
2708 "domain %s using schannel. Error was %s\n",
2709 domain
->name
, nt_errstr(status
) ));
2712 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for domain %s using "
2713 "schannel.\n", domain
->name
));
2715 status
= dcerpc_samr_Connect2(conn
->samr_pipe
->binding_handle
, mem_ctx
,
2716 conn
->samr_pipe
->desthost
,
2717 SEC_FLAG_MAXIMUM_ALLOWED
,
2718 &conn
->sam_connect_handle
,
2721 if (NT_STATUS_EQUAL(status
, NT_STATUS_IO_DEVICE_ERROR
) && !retry
) {
2722 invalidate_cm_connection(domain
);
2723 TALLOC_FREE(conn
->samr_pipe
);
2728 if (NT_STATUS_IS_OK(status
) && NT_STATUS_IS_OK(result
)) {
2731 if (NT_STATUS_IS_OK(status
)) {
2734 DEBUG(10,("cm_connect_sam: schannel-sealed dcerpc_samr_Connect2 failed "
2735 "for domain %s, error was %s. Trying anonymous\n",
2736 domain
->name
, nt_errstr(status
) ));
2737 TALLOC_FREE(conn
->samr_pipe
);
2741 sealed_pipes
= lp_winbind_sealed_pipes();
2742 sealed_pipes
= lp_parm_bool(-1, "winbind sealed pipes",
2745 strong_key
= lp_require_strong_key();
2746 strong_key
= lp_parm_bool(-1, "require strong key",
2750 /* Finally fall back to anonymous. */
2751 if (sealed_pipes
|| strong_key
) {
2752 status
= NT_STATUS_DOWNGRADE_DETECTED
;
2753 DEBUG(1, ("Unwilling to make SAMR connection to domain %s "
2754 "without connection level security, "
2755 "must set 'winbind sealed pipes:%s = false' and "
2756 "'require strong key:%s = false' to proceed: %s\n",
2757 domain
->name
, domain
->name
, domain
->name
,
2758 nt_errstr(status
)));
2761 status
= cli_rpc_pipe_open_noauth(conn
->cli
, &ndr_table_samr
,
2764 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)
2766 invalidate_cm_connection(domain
);
2771 if (!NT_STATUS_IS_OK(status
)) {
2775 status
= dcerpc_samr_Connect2(conn
->samr_pipe
->binding_handle
, mem_ctx
,
2776 conn
->samr_pipe
->desthost
,
2777 SEC_FLAG_MAXIMUM_ALLOWED
,
2778 &conn
->sam_connect_handle
,
2781 if (NT_STATUS_EQUAL(status
, NT_STATUS_IO_DEVICE_ERROR
) && !retry
) {
2782 invalidate_cm_connection(domain
);
2783 TALLOC_FREE(conn
->samr_pipe
);
2788 if (!NT_STATUS_IS_OK(status
)) {
2789 DEBUG(10,("cm_connect_sam: rpccli_samr_Connect2 failed "
2790 "for domain %s Error was %s\n",
2791 domain
->name
, nt_errstr(status
) ));
2794 if (!NT_STATUS_IS_OK(result
)) {
2796 DEBUG(10,("cm_connect_sam: dcerpc_samr_Connect2 failed "
2797 "for domain %s Error was %s\n",
2798 domain
->name
, nt_errstr(result
)));
2803 status
= dcerpc_samr_OpenDomain(conn
->samr_pipe
->binding_handle
,
2805 &conn
->sam_connect_handle
,
2806 SEC_FLAG_MAXIMUM_ALLOWED
,
2808 &conn
->sam_domain_handle
,
2810 if (!NT_STATUS_IS_OK(status
)) {
2817 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
2819 * if we got access denied, we might just have no access rights
2820 * to talk to the remote samr server server (e.g. when we are a
2821 * PDC and we are connecting a w2k8 pdc via an interdomain
2822 * trust). In that case do not invalidate the whole connection
2825 TALLOC_FREE(conn
->samr_pipe
);
2826 ZERO_STRUCT(conn
->sam_domain_handle
);
2828 } else if (!NT_STATUS_IS_OK(status
)) {
2829 invalidate_cm_connection(domain
);
2833 *cli
= conn
->samr_pipe
;
2834 *sam_handle
= conn
->sam_domain_handle
;
2838 /**********************************************************************
2839 open an schanneld ncacn_ip_tcp connection to LSA
2840 ***********************************************************************/
2842 static NTSTATUS
cm_connect_lsa_tcp(struct winbindd_domain
*domain
,
2843 TALLOC_CTX
*mem_ctx
,
2844 struct rpc_pipe_client
**cli
)
2846 struct winbindd_cm_conn
*conn
;
2847 struct netlogon_creds_cli_context
*p_creds
= NULL
;
2849 const char *remote_name
= NULL
;
2850 const struct sockaddr_storage
*remote_sockaddr
= NULL
;
2852 DEBUG(10,("cm_connect_lsa_tcp\n"));
2854 status
= init_dc_connection_rpc(domain
, false);
2855 if (!NT_STATUS_IS_OK(status
)) {
2859 conn
= &domain
->conn
;
2862 * rpccli_is_connected handles more error cases
2864 if (rpccli_is_connected(conn
->lsa_pipe_tcp
) &&
2865 conn
->lsa_pipe_tcp
->transport
->transport
== NCACN_IP_TCP
&&
2866 conn
->lsa_pipe_tcp
->auth
->auth_level
>= DCERPC_AUTH_LEVEL_INTEGRITY
) {
2870 TALLOC_FREE(conn
->lsa_pipe_tcp
);
2872 status
= cm_get_schannel_creds(domain
, &p_creds
);
2873 if (!NT_STATUS_IS_OK(status
)) {
2877 remote_name
= smbXcli_conn_remote_name(conn
->cli
->conn
);
2878 remote_sockaddr
= smbXcli_conn_remote_sockaddr(conn
->cli
->conn
);
2880 status
= cli_rpc_pipe_open_schannel_with_creds(
2887 &conn
->lsa_pipe_tcp
);
2888 if (!NT_STATUS_IS_OK(status
)) {
2889 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key failed: %s\n",
2890 nt_errstr(status
)));
2895 if (!NT_STATUS_IS_OK(status
)) {
2896 TALLOC_FREE(conn
->lsa_pipe_tcp
);
2900 *cli
= conn
->lsa_pipe_tcp
;
2905 NTSTATUS
cm_connect_lsa(struct winbindd_domain
*domain
, TALLOC_CTX
*mem_ctx
,
2906 struct rpc_pipe_client
**cli
, struct policy_handle
*lsa_policy
)
2908 struct winbindd_cm_conn
*conn
;
2909 NTSTATUS result
= NT_STATUS_UNSUCCESSFUL
;
2910 struct netlogon_creds_cli_context
*p_creds
;
2911 struct cli_credentials
*creds
= NULL
;
2912 bool retry
= false; /* allow one retry attempt for expired session */
2913 const char *remote_name
= NULL
;
2914 const struct sockaddr_storage
*remote_sockaddr
= NULL
;
2915 bool sealed_pipes
= true;
2916 bool strong_key
= true;
2919 result
= init_dc_connection_rpc(domain
, false);
2920 if (!NT_STATUS_IS_OK(result
))
2923 conn
= &domain
->conn
;
2925 if (rpccli_is_connected(conn
->lsa_pipe
)) {
2929 TALLOC_FREE(conn
->lsa_pipe
);
2933 * Make sure we only use schannel as AD DC.
2938 result
= get_trust_credentials(domain
, talloc_tos(), false, &creds
);
2939 if (!NT_STATUS_IS_OK(result
)) {
2940 DEBUG(10, ("cm_connect_lsa: No user available for "
2941 "domain %s, trying schannel\n", domain
->name
));
2945 if (cli_credentials_is_anonymous(creds
)) {
2949 remote_name
= smbXcli_conn_remote_name(conn
->cli
->conn
);
2950 remote_sockaddr
= smbXcli_conn_remote_sockaddr(conn
->cli
->conn
);
2953 * We have an authenticated connection. Use a SPNEGO
2954 * authenticated LSA pipe with sign & seal.
2956 result
= cli_rpc_pipe_open_with_creds
2957 (conn
->cli
, &ndr_table_lsarpc
, NCACN_NP
,
2958 DCERPC_AUTH_TYPE_SPNEGO
,
2965 if (NT_STATUS_EQUAL(result
, NT_STATUS_NETWORK_SESSION_EXPIRED
)
2967 invalidate_cm_connection(domain
);
2972 if (!NT_STATUS_IS_OK(result
)) {
2973 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
2974 "domain %s using NTLMSSP authenticated pipe: user "
2975 "%s. Error was %s. Trying schannel.\n",
2977 cli_credentials_get_unparsed_name(creds
, talloc_tos()),
2978 nt_errstr(result
)));
2982 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
2983 "NTLMSSP authenticated pipe: user %s\n",
2984 domain
->name
, cli_credentials_get_unparsed_name(creds
, talloc_tos())));
2986 result
= rpccli_lsa_open_policy(conn
->lsa_pipe
, mem_ctx
, True
,
2987 SEC_FLAG_MAXIMUM_ALLOWED
,
2989 if (NT_STATUS_EQUAL(result
, NT_STATUS_IO_DEVICE_ERROR
) && !retry
) {
2990 invalidate_cm_connection(domain
);
2991 TALLOC_FREE(conn
->lsa_pipe
);
2996 if (NT_STATUS_IS_OK(result
)) {
3000 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
3003 TALLOC_FREE(conn
->lsa_pipe
);
3007 /* Fall back to schannel if it's a W2K pre-SP1 box. */
3009 result
= cm_get_schannel_creds(domain
, &p_creds
);
3010 if (!NT_STATUS_IS_OK(result
)) {
3011 /* If this call fails - conn->cli can now be NULL ! */
3012 DEBUG(10, ("cm_connect_lsa: Could not get schannel auth info "
3013 "for domain %s (error %s), trying anon\n",
3015 nt_errstr(result
) ));
3020 result
= cli_rpc_pipe_open_schannel_with_creds(
3021 conn
->cli
, &ndr_table_lsarpc
, NCACN_NP
, p_creds
,
3026 if (NT_STATUS_EQUAL(result
, NT_STATUS_NETWORK_SESSION_EXPIRED
)
3028 invalidate_cm_connection(domain
);
3033 if (!NT_STATUS_IS_OK(result
)) {
3034 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
3035 "domain %s using schannel. Error was %s\n",
3036 domain
->name
, nt_errstr(result
) ));
3039 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
3040 "schannel.\n", domain
->name
));
3042 result
= rpccli_lsa_open_policy(conn
->lsa_pipe
, mem_ctx
, True
,
3043 SEC_FLAG_MAXIMUM_ALLOWED
,
3046 if (NT_STATUS_EQUAL(result
, NT_STATUS_IO_DEVICE_ERROR
) && !retry
) {
3047 invalidate_cm_connection(domain
);
3048 TALLOC_FREE(conn
->lsa_pipe
);
3053 if (NT_STATUS_IS_OK(result
)) {
3059 * Make sure we only use schannel as AD DC.
3064 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
3067 TALLOC_FREE(conn
->lsa_pipe
);
3073 * Make sure we only use schannel as AD DC.
3078 sealed_pipes
= lp_winbind_sealed_pipes();
3079 sealed_pipes
= lp_parm_bool(-1, "winbind sealed pipes",
3082 strong_key
= lp_require_strong_key();
3083 strong_key
= lp_parm_bool(-1, "require strong key",
3087 /* Finally fall back to anonymous. */
3088 if (sealed_pipes
|| strong_key
) {
3089 result
= NT_STATUS_DOWNGRADE_DETECTED
;
3090 DEBUG(1, ("Unwilling to make LSA connection to domain %s "
3091 "without connection level security, "
3092 "must set 'winbind sealed pipes:%s = false' and "
3093 "'require strong key:%s = false' to proceed: %s\n",
3094 domain
->name
, domain
->name
, domain
->name
,
3095 nt_errstr(result
)));
3099 result
= cli_rpc_pipe_open_noauth(conn
->cli
,
3103 if (NT_STATUS_EQUAL(result
, NT_STATUS_NETWORK_SESSION_EXPIRED
)
3105 invalidate_cm_connection(domain
);
3110 if (!NT_STATUS_IS_OK(result
)) {
3114 result
= rpccli_lsa_open_policy(conn
->lsa_pipe
, mem_ctx
, True
,
3115 SEC_FLAG_MAXIMUM_ALLOWED
,
3118 if (NT_STATUS_EQUAL(result
, NT_STATUS_IO_DEVICE_ERROR
) && !retry
) {
3119 invalidate_cm_connection(domain
);
3120 TALLOC_FREE(conn
->lsa_pipe
);
3126 if (!NT_STATUS_IS_OK(result
)) {
3127 invalidate_cm_connection(domain
);
3131 *cli
= conn
->lsa_pipe
;
3132 *lsa_policy
= conn
->lsa_policy
;
3136 /****************************************************************************
3137 Open a LSA connection to a DC, suitable for LSA lookup calls.
3138 ****************************************************************************/
3140 NTSTATUS
cm_connect_lsat(struct winbindd_domain
*domain
,
3141 TALLOC_CTX
*mem_ctx
,
3142 struct rpc_pipe_client
**cli
,
3143 struct policy_handle
*lsa_policy
)
3147 if (domain
->can_do_ncacn_ip_tcp
) {
3148 status
= cm_connect_lsa_tcp(domain
, mem_ctx
, cli
);
3149 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
) ||
3150 NT_STATUS_EQUAL(status
, NT_STATUS_RPC_SEC_PKG_ERROR
) ||
3151 NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_ACCESS_DENIED
)) {
3152 invalidate_cm_connection(domain
);
3153 status
= cm_connect_lsa_tcp(domain
, mem_ctx
, cli
);
3155 if (NT_STATUS_IS_OK(status
)) {
3160 * we tried twice to connect via ncan_ip_tcp and schannel and
3161 * failed - maybe it is a trusted domain we can't connect to ?
3162 * do not try tcp next time - gd
3164 * This also prevents NETLOGON over TCP
3166 domain
->can_do_ncacn_ip_tcp
= false;
3169 status
= cm_connect_lsa(domain
, mem_ctx
, cli
, lsa_policy
);
3174 /****************************************************************************
3175 Open the netlogon pipe to this DC.
3176 ****************************************************************************/
3178 static NTSTATUS
cm_connect_netlogon_transport(struct winbindd_domain
*domain
,
3179 enum dcerpc_transport_t transport
,
3180 struct rpc_pipe_client
**cli
)
3182 struct messaging_context
*msg_ctx
= global_messaging_context();
3183 struct winbindd_cm_conn
*conn
;
3185 enum netr_SchannelType sec_chan_type
;
3186 struct cli_credentials
*creds
= NULL
;
3191 if (domain
->secure_channel_type
== SEC_CHAN_NULL
) {
3193 * Make sure we don't even try to
3194 * connect to a foreign domain
3195 * without a direct outbound trust.
3197 return NT_STATUS_NO_TRUST_LSA_SECRET
;
3201 result
= init_dc_connection_rpc(domain
, domain
->rodc
);
3202 if (!NT_STATUS_IS_OK(result
)) {
3206 conn
= &domain
->conn
;
3208 if (rpccli_is_connected(conn
->netlogon_pipe
)) {
3209 *cli
= conn
->netlogon_pipe
;
3210 return NT_STATUS_OK
;
3213 TALLOC_FREE(conn
->netlogon_pipe
);
3214 TALLOC_FREE(conn
->netlogon_creds_ctx
);
3216 result
= get_trust_credentials(domain
, talloc_tos(), true, &creds
);
3217 if (!NT_STATUS_IS_OK(result
)) {
3218 DBG_DEBUG("No user available for domain %s when trying "
3219 "schannel\n", domain
->name
);
3220 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
3223 if (cli_credentials_is_anonymous(creds
)) {
3224 DBG_WARNING("get_trust_credential only gave anonymous for %s, "
3225 "unable to make get NETLOGON credentials\n",
3227 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
3230 sec_chan_type
= cli_credentials_get_secure_channel_type(creds
);
3231 if (sec_chan_type
== SEC_CHAN_NULL
) {
3232 const char *remote_name
=
3233 smbXcli_conn_remote_name(conn
->cli
->conn
);
3234 const struct sockaddr_storage
*remote_sockaddr
=
3235 smbXcli_conn_remote_sockaddr(conn
->cli
->conn
);
3237 if (transport
== NCACN_IP_TCP
) {
3238 DBG_NOTICE("get_secure_channel_type gave SEC_CHAN_NULL "
3239 "for %s, deny NCACN_IP_TCP and let the "
3240 "caller fallback to NCACN_NP.\n",
3242 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
3245 DBG_NOTICE("get_secure_channel_type gave SEC_CHAN_NULL for %s, "
3246 "fallback to noauth on NCACN_NP.\n",
3249 result
= cli_rpc_pipe_open_noauth_transport(
3252 &ndr_table_netlogon
,
3255 &conn
->netlogon_pipe
);
3256 if (!NT_STATUS_IS_OK(result
)) {
3257 invalidate_cm_connection(domain
);
3261 *cli
= conn
->netlogon_pipe
;
3262 return NT_STATUS_OK
;
3265 result
= rpccli_create_netlogon_creds_ctx(creds
,
3269 &conn
->netlogon_creds_ctx
);
3270 if (!NT_STATUS_IS_OK(result
)) {
3271 DEBUG(1, ("rpccli_create_netlogon_creds failed for %s, "
3272 "unable to create NETLOGON credentials: %s\n",
3273 domain
->name
, nt_errstr(result
)));
3277 result
= rpccli_connect_netlogon(
3278 conn
->cli
, transport
,
3279 conn
->netlogon_creds_ctx
, conn
->netlogon_force_reauth
, creds
,
3280 &conn
->netlogon_pipe
);
3281 conn
->netlogon_force_reauth
= false;
3282 if (!NT_STATUS_IS_OK(result
)) {
3283 DBG_DEBUG("rpccli_connect_netlogon failed: %s\n",
3288 *cli
= conn
->netlogon_pipe
;
3289 return NT_STATUS_OK
;
3292 /****************************************************************************
3293 Open a NETLOGON connection to a DC, suitable for SamLogon calls.
3294 ****************************************************************************/
3296 NTSTATUS
cm_connect_netlogon(struct winbindd_domain
*domain
,
3297 struct rpc_pipe_client
**cli
)
3301 status
= init_dc_connection_rpc(domain
, domain
->rodc
);
3302 if (!NT_STATUS_IS_OK(status
)) {
3306 if (domain
->active_directory
&& domain
->can_do_ncacn_ip_tcp
) {
3307 status
= cm_connect_netlogon_transport(domain
, NCACN_IP_TCP
, cli
);
3308 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
) ||
3309 NT_STATUS_EQUAL(status
, NT_STATUS_RPC_SEC_PKG_ERROR
) ||
3310 NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_ACCESS_DENIED
)) {
3311 invalidate_cm_connection(domain
);
3312 status
= cm_connect_netlogon_transport(domain
, NCACN_IP_TCP
, cli
);
3314 if (NT_STATUS_IS_OK(status
)) {
3319 * we tried twice to connect via ncan_ip_tcp and schannel and
3320 * failed - maybe it is a trusted domain we can't connect to ?
3321 * do not try tcp next time - gd
3323 * This also prevents LSA over TCP
3325 domain
->can_do_ncacn_ip_tcp
= false;
3328 status
= cm_connect_netlogon_transport(domain
, NCACN_NP
, cli
);
3329 if (NT_STATUS_EQUAL(status
, NT_STATUS_NETWORK_SESSION_EXPIRED
)) {
3331 * SMB2 session expired, needs reauthentication. Drop
3332 * connection and retry.
3334 invalidate_cm_connection(domain
);
3335 status
= cm_connect_netlogon_transport(domain
, NCACN_NP
, cli
);
3341 NTSTATUS
cm_connect_netlogon_secure(struct winbindd_domain
*domain
,
3342 struct rpc_pipe_client
**cli
,
3343 struct netlogon_creds_cli_context
**ppdc
)
3347 if (domain
->secure_channel_type
== SEC_CHAN_NULL
) {
3348 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
3351 status
= cm_connect_netlogon(domain
, cli
);
3352 if (!NT_STATUS_IS_OK(status
)) {
3356 if (domain
->conn
.netlogon_creds_ctx
== NULL
) {
3357 return NT_STATUS_TRUSTED_DOMAIN_FAILURE
;
3360 *ppdc
= domain
->conn
.netlogon_creds_ctx
;
3361 return NT_STATUS_OK
;
3364 void winbind_msg_ip_dropped(struct messaging_context
*msg_ctx
,
3367 struct server_id server_id
,
3370 struct winbindd_domain
*domain
;
3371 char *freeit
= NULL
;
3375 || (data
->data
== NULL
)
3376 || (data
->length
== 0)
3377 || (data
->data
[data
->length
-1] != '\0')) {
3378 DEBUG(1, ("invalid msg_ip_dropped message: not a valid "
3383 addr
= (char *)data
->data
;
3384 DEBUG(10, ("IP %s dropped\n", addr
));
3386 if (!is_ipaddress(addr
)) {
3389 * Some code sends us ip addresses with the /netmask
3392 slash
= strchr(addr
, '/');
3393 if (slash
== NULL
) {
3394 DEBUG(1, ("invalid msg_ip_dropped message: %s\n",
3398 freeit
= talloc_strndup(talloc_tos(), addr
, slash
-addr
);
3399 if (freeit
== NULL
) {
3400 DEBUG(1, ("talloc failed\n"));
3404 DEBUG(10, ("Stripped /netmask to IP %s\n", addr
));
3407 for (domain
= domain_list(); domain
!= NULL
; domain
= domain
->next
) {
3408 char sockaddr
[INET6_ADDRSTRLEN
];
3410 if (!cli_state_is_connected(domain
->conn
.cli
)) {
3414 print_sockaddr(sockaddr
, sizeof(sockaddr
),
3415 smbXcli_conn_local_sockaddr(domain
->conn
.cli
->conn
));
3417 if (strequal(sockaddr
, addr
)) {
3418 smbXcli_conn_disconnect(domain
->conn
.cli
->conn
, NT_STATUS_OK
);
3421 TALLOC_FREE(freeit
);
3424 void winbind_msg_disconnect_dc(struct messaging_context
*msg_ctx
,
3427 struct server_id server_id
,
3430 struct winbindd_domain
*domain
;
3432 for (domain
= domain_list(); domain
; domain
= domain
->next
) {
3433 if (domain
->internal
) {
3436 invalidate_cm_connection(domain
);