drsuapi.idl: fix source_dsa spelling
[samba4-gss.git] / source3 / winbindd / winbindd_cm.c
blobb59e46430da92871612101d4ddb83e9e452f759a
1 /*
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
34 selection etc
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
46 implementation. -tpot
51 TODO:
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
57 various sam handles.
61 #include "includes.h"
62 #include "winbindd.h"
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"
75 #include "ads.h"
76 #include "secrets.h"
77 #include "../libcli/security/security.h"
78 #include "passdb.h"
79 #include "messages.h"
80 #include "auth/gensec/gensec.h"
81 #include "../libcli/smb/smbXcli_base.h"
82 #include "libcli/auth/netlogon_creds_cli.h"
83 #include "auth.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"
92 #undef DBGC_CLASS
93 #define DBGC_CLASS DBGC_WINBIND
95 struct dc_name_ip {
96 fstring name;
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,
110 void *private_data,
111 uint32_t msg_type,
112 struct server_id server_id,
113 DATA_BLOB *data)
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);
121 return;
124 DBG_DEBUG("Domain %s was %s, change to offline now.\n",
125 domain_name,
126 domain->online ? "online" : "offline");
128 domain->online = false;
131 void winbind_msg_domain_online(struct messaging_context *msg_ctx,
132 void *private_data,
133 uint32_t msg_type,
134 struct server_id server_id,
135 DATA_BLOB *data)
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) {
142 return;
145 SMB_ASSERT(wb_child_domain() == NULL);
147 DBG_DEBUG("Domain %s was %s, marking as online now!\n",
148 domain_name,
149 domain->online ? "online" : "offline");
151 domain->online = true;
154 /****************************************************************
155 Set domain offline and also add handler to put us back online
156 if we detect a DC.
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",
164 domain->name ));
166 if (domain->internal) {
167 DEBUG(3,("set_domain_offline: domain %s is internal - logic error.\n",
168 domain->name ));
169 return;
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),
196 MSG_WINBIND_OFFLINE,
197 (const uint8_t *)domain->name,
198 strlen(domain->name)+1);
202 return;
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",
214 domain->name ));
216 if (domain->internal) {
217 DEBUG(3,("set_domain_online: domain %s is internal - logic error.\n",
218 domain->name ));
219 return;
222 if (get_global_winbindd_state_offline()) {
223 DEBUG(10,("set_domain_online: domain %s remaining globally offline\n",
224 domain->name ));
225 return;
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),
272 MSG_WINBIND_ONLINE,
273 (const uint8_t *)domain->name,
274 strlen(domain->name)+1);
278 return;
281 /****************************************************************
282 Requested to set a domain online.
283 ****************************************************************/
285 void set_domain_online_request(struct winbindd_domain *domain)
287 NTSTATUS status;
289 SMB_ASSERT(wb_child_domain() || idmap_child());
291 DEBUG(10,("set_domain_online_request: called for domain %s\n",
292 domain->name ));
294 if (get_global_winbindd_state_offline()) {
295 DEBUG(10,("set_domain_online_request: domain %s remaining globally offline\n",
296 domain->name ));
297 return;
300 if (domain->internal) {
301 DEBUG(10, ("set_domain_online_request: Internal domains are "
302 "always online\n"));
303 return;
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",
314 nt_errstr(status),
315 domain->name,
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,
325 const char *server,
326 NTSTATUS result)
328 add_failed_connection_entry(domain->name, server, result);
329 /* If this was the saf name for the last thing we talked to,
330 remove it. */
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));
364 } else {
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;
383 bool ok;
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;
391 goto fail;
394 creds = cli_credentials_init(mem_ctx);
395 if (creds == NULL) {
396 status = NT_STATUS_NO_MEMORY;
397 goto fail;
400 ok = cli_credentials_set_conf(creds, lp_ctx);
401 if (!ok) {
402 status = NT_STATUS_INTERNAL_ERROR;
403 goto fail;
406 cli_credentials_set_kerberos_state(creds,
407 CRED_USE_KERBEROS_DISABLED,
408 CRED_SPECIFIED);
410 ok = cli_credentials_set_domain(creds, netbios_domain, CRED_SPECIFIED);
411 if (!ok) {
412 status = NT_STATUS_NO_MEMORY;
413 goto fail;
416 ok = cli_credentials_set_username(creds, username, CRED_SPECIFIED);
417 if (!ok) {
418 status = NT_STATUS_NO_MEMORY;
419 goto fail;
422 ok = cli_credentials_set_password(creds, password, CRED_SPECIFIED);
423 if (!ok) {
424 status = NT_STATUS_NO_MEMORY;
425 goto fail;
428 *_creds = creds;
429 creds = NULL;
430 status = NT_STATUS_OK;
431 fail:
432 TALLOC_FREE(creds);
433 SAFE_FREE(username);
434 SAFE_FREE(netbios_domain);
435 SAFE_FREE(password);
436 TALLOC_FREE(frame);
437 return status;
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;
449 bool ret = false;
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)) {
458 goto done;
461 if (!strequal(ipc_account, creds_account)) {
462 goto done;
465 if (!strcsequal(ipc_password, creds_password)) {
466 goto done;
469 ret = true;
470 done:
471 SAFE_FREE(ipc_account);
472 SAFE_FREE(ipc_domain);
473 SAFE_FREE(ipc_password);
474 TALLOC_FREE(frame);
475 return ret;
478 static bool get_dc_name_via_netlogon(struct winbindd_domain *domain,
479 fstring dcname,
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;
485 NTSTATUS result;
486 WERROR werr;
487 TALLOC_CTX *mem_ctx;
488 unsigned int orig_timeout;
489 const char *tmp = NULL;
490 const char *p;
491 struct dcerpc_binding_handle *b;
493 /* Hmmmm. We can only open one connection to the NETLOGON pipe at the
494 * moment.... */
496 if (IS_DC) {
497 return False;
500 if (domain->primary) {
501 return False;
504 our_domain = find_our_domain();
506 if ((mem_ctx = talloc_init("get_dc_name_via_netlogon")) == NULL) {
507 return False;
510 result = cm_connect_netlogon(our_domain, &netlogon_pipe);
511 if (!NT_STATUS_IS_OK(result)) {
512 talloc_destroy(mem_ctx);
513 return False;
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,
531 mem_ctx,
532 our_domain->dcname,
533 domain->name,
534 NULL,
535 NULL,
536 request_flags|DS_RETURN_DNS_NAME,
537 &domain_info,
538 &werr);
539 if (NT_STATUS_IS_OK(result) && W_ERROR_IS_OK(werr)) {
540 tmp = talloc_strdup(
541 mem_ctx, domain_info->dc_unc);
542 if (tmp == NULL) {
543 DBG_ERR("talloc_strdup failed for dc_unc[%s]\n",
544 domain_info->dc_unc);
545 talloc_destroy(mem_ctx);
546 return false;
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);
556 return false;
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);
567 return false;
571 } else {
572 result = dcerpc_netr_GetAnyDCName(b, mem_ctx,
573 our_domain->dcname,
574 domain->name,
575 &tmp,
576 &werr);
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",
584 nt_errstr(result)));
585 talloc_destroy(mem_ctx);
586 return false;
589 if (!W_ERROR_IS_OK(werr)) {
590 DEBUG(10,("dcerpc_netr_GetAnyDCName failed: %s\n",
591 win_errstr(werr)));
592 talloc_destroy(mem_ctx);
593 return false;
596 /* dcerpc_netr_GetAnyDCName gives us a name with \\ */
597 p = strip_hostname(tmp);
599 fstrcpy(dcname, p);
601 talloc_destroy(mem_ctx);
603 DEBUG(10,("dcerpc_netr_GetAnyDCName returned %s\n", dcname));
605 if (!resolve_name(dcname, dc_ss, 0x20, true)) {
606 return False;
609 return True;
613 * Helper function to assemble trust password and account name
615 NTSTATUS winbindd_get_trust_credentials(struct winbindd_domain *domain,
616 TALLOC_CTX *mem_ctx,
617 bool netlogon,
618 bool allow_ipc_fallback,
619 struct cli_credentials **_creds)
621 const struct winbindd_domain *creds_domain = NULL;
622 struct cli_credentials *creds;
623 NTSTATUS status;
624 bool force_machine_account = false;
626 /* If we are a DC and this is not our own domain */
628 if (!domain->active_directory) {
629 if (!netlogon) {
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;
643 } else {
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,
652 mem_ctx,
653 &creds);
654 if (!NT_STATUS_IS_OK(status)) {
655 goto ipc_fallback;
658 if (netlogon) {
659 cli_credentials_add_gensec_features(creds,
660 GENSEC_FEATURE_NO_DELEGATION,
661 CRED_SPECIFIED);
664 if (creds_domain != domain) {
666 * We can only use schannel against a direct trust
668 cli_credentials_set_secure_channel_type(creds,
669 SEC_CHAN_NULL);
672 *_creds = creds;
673 return NT_STATUS_OK;
675 ipc_fallback:
676 if (netlogon) {
677 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
680 if (!allow_ipc_fallback) {
681 return status;
684 status = cm_get_ipc_credentials(mem_ctx, &creds);
685 if (!NT_STATUS_IS_OK(status)) {
686 return status;
689 *_creds = creds;
690 return NT_STATUS_OK;
693 /************************************************************************
694 Given a fd with a just-connected TCP connection to a DC, open a connection
695 to the pipe.
696 ************************************************************************/
698 static NTSTATUS cm_prepare_connection(struct winbindd_domain *domain,
699 const int sockfd,
700 const char *controller,
701 struct cli_state **cli,
702 bool *retry)
704 bool try_ipc_auth = false;
705 const char *machine_principal = NULL;
706 const char *machine_realm = NULL;
707 const char *machine_account = NULL;
708 const char *machine_domain = NULL;
709 int flags = 0;
710 struct cli_credentials *creds = NULL;
712 struct named_mutex *mutex;
714 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
715 NTSTATUS tmp_status;
716 NTSTATUS tcon_status = NT_STATUS_NETWORK_NAME_DELETED;
718 enum smb_signing_setting smb_sign_client_connections = lp_client_ipc_signing();
720 if (IS_DC) {
721 if (domain->secure_channel_type == SEC_CHAN_NULL) {
723 * Make sure we don't even try to
724 * connect to a foreign domain
725 * without a direct outbound trust.
727 close(sockfd);
728 return NT_STATUS_NO_TRUST_LSA_SECRET;
732 * As AD DC we only use netlogon and lsa
733 * using schannel over an anonymous transport
734 * (ncacn_ip_tcp or ncacn_np).
736 * Currently we always establish the SMB connection,
737 * even if we don't use it, because we later use ncacn_ip_tcp.
739 * As we won't use the SMB connection there's no
740 * need to try kerberos. And NT4 domains expect
741 * an anonymous IPC$ connection anyway.
743 smb_sign_client_connections = SMB_SIGNING_OFF;
746 if (smb_sign_client_connections == SMB_SIGNING_DEFAULT) {
748 * If we are connecting to our own AD domain, require
749 * smb signing to disrupt MITM attacks
751 if (domain->primary && lp_security() == SEC_ADS) {
752 smb_sign_client_connections = SMB_SIGNING_REQUIRED;
754 * If we are in or are an AD domain and connecting to another
755 * AD domain in our forest
756 * then require smb signing to disrupt MITM attacks
758 } else if ((lp_security() == SEC_ADS)
759 && domain->active_directory
760 && (domain->domain_trust_attribs
761 & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST)) {
762 smb_sign_client_connections = SMB_SIGNING_REQUIRED;
766 DEBUG(10,("cm_prepare_connection: connecting to DC %s for domain %s\n",
767 controller, domain->name ));
769 *retry = True;
771 mutex = grab_named_mutex(talloc_tos(), controller,
772 WINBIND_SERVER_MUTEX_WAIT_TIME);
773 if (mutex == NULL) {
774 close(sockfd);
775 DEBUG(0,("cm_prepare_connection: mutex grab failed for %s\n",
776 controller));
777 result = NT_STATUS_POSSIBLE_DEADLOCK;
778 goto done;
782 * cm_prepare_connection() is responsible that sockfd does not leak.
783 * Once cli_state_create() returns with success, the
784 * smbXcli_conn_destructor() makes sure that close(sockfd) is finally
785 * called. Till that, close(sockfd) must be called on every unsuccessful
786 * return.
788 *cli = cli_state_create(NULL, sockfd, controller,
789 smb_sign_client_connections, flags);
790 if (*cli == NULL) {
791 close(sockfd);
792 DEBUG(1, ("Could not cli_initialize\n"));
793 result = NT_STATUS_NO_MEMORY;
794 goto done;
797 cli_set_timeout(*cli, 10000); /* 10 seconds */
799 set_socket_options(sockfd, lp_socket_options());
801 result = smbXcli_negprot((*cli)->conn,
802 (*cli)->timeout,
803 lp_client_ipc_min_protocol(),
804 lp_client_ipc_max_protocol(),
805 NULL,
806 NULL,
807 NULL);
809 if (!NT_STATUS_IS_OK(result)) {
810 DEBUG(1, ("cli_negprot failed: %s\n", nt_errstr(result)));
811 goto done;
814 if (smbXcli_conn_protocol((*cli)->conn) >= PROTOCOL_NT1 &&
815 smb1cli_conn_capabilities((*cli)->conn) & CAP_EXTENDED_SECURITY) {
816 try_ipc_auth = true;
817 } else if (smbXcli_conn_protocol((*cli)->conn) >= PROTOCOL_SMB2_02) {
818 try_ipc_auth = true;
819 } else if (smb_sign_client_connections == SMB_SIGNING_REQUIRED) {
821 * If we are forcing on SMB signing, then we must
822 * require authentication unless this is a one-way
823 * trust, and we have no stored user/password
825 try_ipc_auth = true;
828 if (IS_DC) {
830 * As AD DC we only use netlogon and lsa
831 * using schannel over an anonymous transport
832 * (ncacn_ip_tcp or ncacn_np).
834 * Currently we always establish the SMB connection,
835 * even if we don't use it, because we later use ncacn_ip_tcp.
837 * As we won't use the SMB connection there's no
838 * need to try kerberos. And NT4 domains expect
839 * an anonymous IPC$ connection anyway.
841 try_ipc_auth = false;
844 if (try_ipc_auth) {
845 result = winbindd_get_trust_credentials(domain,
846 talloc_tos(),
847 false, /* netlogon */
848 true, /* ipc_fallback */
849 &creds);
850 if (!NT_STATUS_IS_OK(result)) {
851 DBG_WARNING("winbindd_get_trust_credentials(%s) "
852 "failed: %s\n",
853 domain->name,
854 nt_errstr(result));
855 goto done;
857 } else {
859 * Without SPNEGO or NTLMSSP (perhaps via SMB2) we
860 * would try and authentication with our machine
861 * account password and fail. This is very rare in
862 * the modern world however
864 creds = cli_credentials_init_anon(talloc_tos());
865 if (creds == NULL) {
866 result = NT_STATUS_NO_MEMORY;
867 DEBUG(1, ("cli_credentials_init_anon(%s) failed: %s\n",
868 domain->name, nt_errstr(result)));
869 goto done;
873 machine_principal = cli_credentials_get_principal(creds,
874 talloc_tos());
875 machine_realm = cli_credentials_get_realm(creds);
876 machine_account = cli_credentials_get_username(creds);
877 machine_domain = cli_credentials_get_domain(creds);
879 DEBUG(5, ("connecting to %s (%s, %s) with account [%s\\%s] principal "
880 "[%s] and realm [%s]\n",
881 controller, domain->name, domain->alt_name,
882 machine_domain, machine_account,
883 machine_principal, machine_realm));
885 if (cli_credentials_is_anonymous(creds)) {
886 goto anon_fallback;
889 winbindd_set_locator_kdc_envs(domain);
891 result = cli_session_setup_creds(*cli, creds);
892 if (NT_STATUS_IS_OK(result)) {
893 goto session_setup_done;
896 DEBUG(1, ("authenticated session setup to %s using %s failed with %s\n",
897 controller,
898 cli_credentials_get_unparsed_name(creds, talloc_tos()),
899 nt_errstr(result)));
902 * If we are not going to validate the connection
903 * with SMB signing, then allow us to fall back to
904 * anonymous
906 if (NT_STATUS_EQUAL(result, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT)
907 || NT_STATUS_EQUAL(result, NT_STATUS_TRUSTED_DOMAIN_FAILURE)
908 || NT_STATUS_EQUAL(result, NT_STATUS_INVALID_ACCOUNT_NAME)
909 || NT_STATUS_EQUAL(result, NT_STATUS_INVALID_COMPUTER_NAME)
910 || NT_STATUS_EQUAL(result, NT_STATUS_NO_SUCH_DOMAIN)
911 || NT_STATUS_EQUAL(result, NT_STATUS_NO_LOGON_SERVERS)
912 || NT_STATUS_EQUAL(result, NT_STATUS_LOGON_FAILURE))
914 if (!cm_is_ipc_credentials(creds)) {
915 goto ipc_fallback;
918 if (smb_sign_client_connections == SMB_SIGNING_REQUIRED) {
919 goto done;
922 goto anon_fallback;
925 goto done;
927 ipc_fallback:
928 TALLOC_FREE(creds);
929 tmp_status = cm_get_ipc_credentials(talloc_tos(), &creds);
930 if (!NT_STATUS_IS_OK(tmp_status)) {
931 result = tmp_status;
932 goto done;
935 if (cli_credentials_is_anonymous(creds)) {
936 goto anon_fallback;
939 machine_account = cli_credentials_get_username(creds);
940 machine_domain = cli_credentials_get_domain(creds);
942 DEBUG(5, ("connecting to %s from %s using NTLMSSP with username "
943 "[%s]\\[%s]\n", controller, lp_netbios_name(),
944 machine_domain, machine_account));
946 result = cli_session_setup_creds(*cli, creds);
947 if (NT_STATUS_IS_OK(result)) {
948 goto session_setup_done;
951 DEBUG(1, ("authenticated session setup to %s using %s failed with %s\n",
952 controller,
953 cli_credentials_get_unparsed_name(creds, talloc_tos()),
954 nt_errstr(result)));
957 * If we are not going to validate the connection
958 * with SMB signing, then allow us to fall back to
959 * anonymous
961 if (NT_STATUS_EQUAL(result, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT)
962 || NT_STATUS_EQUAL(result, NT_STATUS_TRUSTED_DOMAIN_FAILURE)
963 || NT_STATUS_EQUAL(result, NT_STATUS_INVALID_ACCOUNT_NAME)
964 || NT_STATUS_EQUAL(result, NT_STATUS_INVALID_COMPUTER_NAME)
965 || NT_STATUS_EQUAL(result, NT_STATUS_NO_SUCH_DOMAIN)
966 || NT_STATUS_EQUAL(result, NT_STATUS_NO_LOGON_SERVERS)
967 || NT_STATUS_EQUAL(result, NT_STATUS_LOGON_FAILURE))
969 goto anon_fallback;
972 goto done;
974 anon_fallback:
975 TALLOC_FREE(creds);
977 if (smb_sign_client_connections == SMB_SIGNING_REQUIRED) {
978 goto done;
981 /* Fall back to anonymous connection, this might fail later */
982 DEBUG(5,("cm_prepare_connection: falling back to anonymous "
983 "connection for DC %s\n",
984 controller ));
986 result = cli_session_setup_anon(*cli);
987 if (NT_STATUS_IS_OK(result)) {
988 DEBUG(5, ("Connected anonymously\n"));
989 goto session_setup_done;
992 DEBUG(1, ("anonymous session setup to %s failed with %s\n",
993 controller, nt_errstr(result)));
995 /* We can't session setup */
996 goto done;
998 session_setup_done:
999 TALLOC_FREE(creds);
1002 * This should be a short term hack until
1003 * dynamic re-authentication is implemented.
1005 * See Bug 9175 - winbindd doesn't recover from
1006 * NT_STATUS_NETWORK_SESSION_EXPIRED
1008 if (smbXcli_conn_protocol((*cli)->conn) >= PROTOCOL_SMB2_02) {
1009 smbXcli_session_set_disconnect_expired((*cli)->smb2.session);
1012 result = cli_tree_connect(*cli, "IPC$", "IPC", NULL);
1013 if (!NT_STATUS_IS_OK(result)) {
1014 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(result)));
1015 goto done;
1017 tcon_status = result;
1019 /* cache the server name for later connections */
1021 saf_store(domain->name, controller);
1022 if (domain->alt_name) {
1023 saf_store(domain->alt_name, controller);
1026 winbindd_set_locator_kdc_envs(domain);
1028 TALLOC_FREE(mutex);
1029 *retry = False;
1031 result = NT_STATUS_OK;
1033 done:
1034 TALLOC_FREE(mutex);
1035 TALLOC_FREE(creds);
1037 if (NT_STATUS_IS_OK(result)) {
1038 result = tcon_status;
1041 if (!NT_STATUS_IS_OK(result)) {
1042 DEBUG(1, ("Failed to prepare SMB connection to %s: %s\n",
1043 controller, nt_errstr(result)));
1044 winbind_add_failed_connection_entry(domain, controller, result);
1045 if ((*cli) != NULL) {
1046 cli_shutdown(*cli);
1047 *cli = NULL;
1051 return result;
1054 /*******************************************************************
1055 Add a dcname and sockaddr_storage pair to the end of a dc_name_ip
1056 array.
1058 Keeps the list unique by not adding duplicate entries.
1060 @param[in] mem_ctx talloc memory context to allocate from
1061 @param[in] domain_name domain of the DC
1062 @param[in] dcname name of the DC to add to the list
1063 @param[in] pss Internet address and port pair to add to the list
1064 @param[in,out] dcs array of dc_name_ip structures to add to
1065 @param[in,out] num_dcs number of dcs returned in the dcs array
1066 @return true if the list was added to, false otherwise
1067 *******************************************************************/
1069 static bool add_one_dc_unique(TALLOC_CTX *mem_ctx, const char *domain_name,
1070 const char *dcname, struct sockaddr_storage *pss,
1071 struct dc_name_ip **dcs, int *num)
1073 int i = 0;
1075 if (!NT_STATUS_IS_OK(check_negative_conn_cache(domain_name, dcname))) {
1076 DEBUG(10, ("DC %s was in the negative conn cache\n", dcname));
1077 return False;
1080 /* Make sure there's no duplicates in the list */
1081 for (i=0; i<*num; i++) {
1082 struct samba_sockaddr ss1 = { .u = { .ss = (*dcs)[i].ss, }};
1083 struct samba_sockaddr ss2 = { .u = { .ss = *pss, }};
1085 if (sockaddr_equal(&ss1.u.sa, &ss2.u.sa)) {
1086 return False;
1090 *dcs = talloc_realloc(mem_ctx, *dcs, struct dc_name_ip, (*num)+1);
1092 if (*dcs == NULL)
1093 return False;
1095 fstrcpy((*dcs)[*num].name, dcname);
1096 (*dcs)[*num].ss = *pss;
1097 *num += 1;
1098 return True;
1101 static bool add_sockaddr_to_array(TALLOC_CTX *mem_ctx,
1102 struct sockaddr_storage *pss, uint16_t port,
1103 struct sockaddr_storage **addrs, int *num)
1105 *addrs = talloc_realloc(mem_ctx, *addrs, struct sockaddr_storage, (*num)+1);
1107 if (*addrs == NULL) {
1108 *num = 0;
1109 return False;
1112 (*addrs)[*num] = *pss;
1113 set_sockaddr_port((struct sockaddr *)&(*addrs)[*num], port);
1115 *num += 1;
1116 return True;
1119 #ifdef HAVE_ADS
1120 static bool dcip_check_name_ads(const struct winbindd_domain *domain,
1121 struct samba_sockaddr *sa,
1122 uint32_t request_flags,
1123 TALLOC_CTX *mem_ctx,
1124 char **namep)
1126 TALLOC_CTX *tmp_ctx = talloc_stackframe();
1127 char *name = NULL;
1128 ADS_STRUCT *ads = NULL;
1129 ADS_STATUS ads_status;
1130 char addr[INET6_ADDRSTRLEN];
1132 print_sockaddr(addr, sizeof(addr), &sa->u.ss);
1133 D_DEBUG("Trying to figure out the DC name for domain '%s' at IP '%s'.\n",
1134 domain->name,
1135 addr);
1137 ads = ads_init(tmp_ctx,
1138 domain->alt_name,
1139 domain->name,
1140 addr,
1141 ADS_SASL_PLAIN);
1142 if (ads == NULL) {
1143 ads_status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1144 goto out;
1146 ads->config.flags |= request_flags;
1147 ads->server.no_fallback = true;
1149 ads_status = ads_connect_cldap_only(ads);
1150 if (!ADS_ERR_OK(ads_status)) {
1151 goto out;
1154 /* We got a cldap packet. */
1155 name = talloc_strdup(tmp_ctx, ads->config.ldap_server_name);
1156 if (name == NULL) {
1157 ads_status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
1158 goto out;
1160 namecache_store(name, 0x20, 1, sa);
1162 DBG_DEBUG("CLDAP flags = 0x%"PRIx32"\n", ads->config.flags);
1164 if (domain->primary && (ads->config.flags & NBT_SERVER_KDC)) {
1165 if (ads_closest_dc(ads)) {
1166 char *sitename = sitename_fetch(tmp_ctx,
1167 ads->config.realm);
1169 /* We're going to use this KDC for this realm/domain.
1170 If we are using sites, then force the krb5 libs
1171 to use this KDC. */
1173 create_local_private_krb5_conf_for_domain(domain->alt_name,
1174 domain->name,
1175 sitename,
1176 &sa->u.ss);
1178 TALLOC_FREE(sitename);
1179 } else {
1180 /* use an off site KDC */
1181 create_local_private_krb5_conf_for_domain(domain->alt_name,
1182 domain->name,
1183 NULL,
1184 &sa->u.ss);
1186 winbindd_set_locator_kdc_envs(domain);
1188 /* Ensure we contact this DC also. */
1189 saf_store(domain->name, name);
1190 saf_store(domain->alt_name, name);
1193 D_DEBUG("DC name for domain '%s' at IP '%s' is '%s'\n",
1194 domain->name,
1195 addr,
1196 name);
1197 *namep = talloc_move(mem_ctx, &name);
1199 out:
1200 TALLOC_FREE(tmp_ctx);
1202 return ADS_ERR_OK(ads_status) ? true : false;
1204 #endif
1206 /*******************************************************************
1207 convert an ip to a name
1208 For an AD Domain, it checks the requirements of the request flags.
1209 *******************************************************************/
1211 static bool dcip_check_name(TALLOC_CTX *mem_ctx,
1212 const struct winbindd_domain *domain,
1213 const struct sockaddr_storage *pss,
1214 char **name, uint32_t request_flags)
1216 struct samba_sockaddr sa = {0};
1217 uint32_t nt_version = NETLOGON_NT_VERSION_1;
1218 NTSTATUS status;
1219 const char *dc_name;
1220 fstring nbtname;
1221 #ifdef HAVE_ADS
1222 bool is_ad_domain = false;
1223 #endif
1224 bool ok = sockaddr_storage_to_samba_sockaddr(&sa, pss);
1225 if (!ok) {
1226 return false;
1229 #ifdef HAVE_ADS
1230 /* For active directory servers, try to get the ldap server name.
1231 None of these failures should be considered critical for now */
1233 if ((lp_security() == SEC_ADS) && (domain->alt_name != NULL)) {
1234 is_ad_domain = true;
1235 } else if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
1236 is_ad_domain = domain->active_directory;
1239 if (is_ad_domain) {
1240 return dcip_check_name_ads(domain,
1241 &sa,
1242 request_flags,
1243 mem_ctx,
1244 name);
1246 #endif
1249 size_t len = strlen(lp_netbios_name());
1250 char my_acct_name[len+2];
1252 snprintf(my_acct_name,
1253 sizeof(my_acct_name),
1254 "%s$",
1255 lp_netbios_name());
1257 status = nbt_getdc(global_messaging_context(), 10, &sa.u.ss,
1258 domain->name, &domain->sid,
1259 my_acct_name, ACB_WSTRUST,
1260 nt_version, mem_ctx, &nt_version,
1261 &dc_name, NULL);
1263 if (NT_STATUS_IS_OK(status)) {
1264 *name = talloc_strdup(mem_ctx, dc_name);
1265 if (*name == NULL) {
1266 return false;
1268 namecache_store(*name, 0x20, 1, &sa);
1269 return True;
1272 /* try node status request */
1274 if (name_status_find(domain->name, 0x1c, 0x20, &sa.u.ss, nbtname) ) {
1275 namecache_store(nbtname, 0x20, 1, &sa);
1277 if (name != NULL) {
1278 *name = talloc_strdup(mem_ctx, nbtname);
1279 if (*name == NULL) {
1280 return false;
1284 return true;
1286 return False;
1289 /*******************************************************************
1290 Retrieve a list of IP addresses for domain controllers.
1292 The array is sorted in the preferred connection order.
1294 @param[in] mem_ctx talloc memory context to allocate from
1295 @param[in] domain domain to retrieve DCs for
1296 @param[out] dcs array of dcs that will be returned
1297 @param[out] num_dcs number of dcs returned in the dcs array
1298 @return always true
1299 *******************************************************************/
1301 static bool get_dcs(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
1302 struct dc_name_ip **dcs, int *num_dcs,
1303 uint32_t request_flags)
1305 fstring dcname;
1306 struct sockaddr_storage ss;
1307 struct samba_sockaddr *sa_list = NULL;
1308 size_t salist_size = 0;
1309 size_t i;
1310 bool is_our_domain;
1311 enum security_types sec = (enum security_types)lp_security();
1313 is_our_domain = strequal(domain->name, lp_workgroup());
1315 /* If not our domain, get the preferred DC, by asking our primary DC */
1316 if ( !is_our_domain
1317 && get_dc_name_via_netlogon(domain, dcname, &ss, request_flags)
1318 && add_one_dc_unique(mem_ctx, domain->name, dcname, &ss, dcs,
1319 num_dcs) )
1321 char addr[INET6_ADDRSTRLEN];
1322 print_sockaddr(addr, sizeof(addr), &ss);
1323 DEBUG(10, ("Retrieved DC %s at %s via netlogon\n",
1324 dcname, addr));
1325 return True;
1328 if ((sec == SEC_ADS) && (domain->alt_name != NULL)) {
1329 char *sitename = NULL;
1331 /* We need to make sure we know the local site before
1332 doing any DNS queries, as this will restrict the
1333 get_sorted_dc_list() call below to only fetching
1334 DNS records for the correct site. */
1336 /* Find any DC to get the site record.
1337 We deliberately don't care about the
1338 return here. */
1340 get_dc_name(domain->name, domain->alt_name, dcname, &ss);
1342 sitename = sitename_fetch(mem_ctx, domain->alt_name);
1343 if (sitename) {
1345 /* Do the site-specific AD dns lookup first. */
1346 (void)get_sorted_dc_list(mem_ctx,
1347 domain->alt_name,
1348 sitename,
1349 &sa_list,
1350 &salist_size,
1351 true);
1353 /* Add ips to the DC array. We don't look up the name
1354 of the DC in this function, but we fill in the char*
1355 of the ip now to make the failed connection cache
1356 work */
1357 for ( i=0; i<salist_size; i++ ) {
1358 char addr[INET6_ADDRSTRLEN];
1359 print_sockaddr(addr, sizeof(addr),
1360 &sa_list[i].u.ss);
1361 add_one_dc_unique(mem_ctx,
1362 domain->name,
1363 addr,
1364 &sa_list[i].u.ss,
1365 dcs,
1366 num_dcs);
1369 TALLOC_FREE(sa_list);
1370 TALLOC_FREE(sitename);
1371 salist_size = 0;
1374 /* Now we add DCs from the main AD DNS lookup. */
1375 (void)get_sorted_dc_list(mem_ctx,
1376 domain->alt_name,
1377 NULL,
1378 &sa_list,
1379 &salist_size,
1380 true);
1382 for ( i=0; i<salist_size; i++ ) {
1383 char addr[INET6_ADDRSTRLEN];
1384 print_sockaddr(addr, sizeof(addr),
1385 &sa_list[i].u.ss);
1386 add_one_dc_unique(mem_ctx,
1387 domain->name,
1388 addr,
1389 &sa_list[i].u.ss,
1390 dcs,
1391 num_dcs);
1394 TALLOC_FREE(sa_list);
1395 salist_size = 0;
1398 /* Try standard netbios queries if no ADS and fall back to DNS queries
1399 * if alt_name is available */
1400 if (*num_dcs == 0) {
1401 (void)get_sorted_dc_list(mem_ctx,
1402 domain->name,
1403 NULL,
1404 &sa_list,
1405 &salist_size,
1406 false);
1407 if (salist_size == 0) {
1408 if (domain->alt_name != NULL) {
1409 (void)get_sorted_dc_list(mem_ctx,
1410 domain->alt_name,
1411 NULL,
1412 &sa_list,
1413 &salist_size,
1414 true);
1418 for ( i=0; i<salist_size; i++ ) {
1419 char addr[INET6_ADDRSTRLEN];
1420 print_sockaddr(addr, sizeof(addr),
1421 &sa_list[i].u.ss);
1422 add_one_dc_unique(mem_ctx,
1423 domain->name,
1424 addr,
1425 &sa_list[i].u.ss,
1426 dcs,
1427 num_dcs);
1430 TALLOC_FREE(sa_list);
1431 salist_size = 0;
1434 return True;
1437 static bool connect_preferred_dc(TALLOC_CTX *mem_ctx,
1438 struct winbindd_domain *domain,
1439 uint32_t request_flags,
1440 int *fd)
1442 char *saf_servername = NULL;
1443 NTSTATUS status;
1444 bool ok;
1447 * We have to check the server affinity cache here since later we select
1448 * a DC based on response time and not preference.
1450 if (domain->force_dc) {
1451 saf_servername = domain->dcname;
1452 } else {
1453 saf_servername = saf_fetch(mem_ctx, domain->name);
1457 * Check the negative connection cache before talking to it. It going
1458 * down may have triggered the reconnection.
1460 if (saf_servername != NULL) {
1461 status = check_negative_conn_cache(domain->name,
1462 saf_servername);
1463 if (!NT_STATUS_IS_OK(status)) {
1464 saf_servername = NULL;
1468 if (saf_servername != NULL) {
1469 DBG_DEBUG("saf_servername is '%s' for domain %s\n",
1470 saf_servername, domain->name);
1472 /* convert an ip address to a name */
1473 if (is_ipaddress(saf_servername)) {
1474 ok = interpret_string_addr(&domain->dcaddr,
1475 saf_servername,
1476 AI_NUMERICHOST);
1477 if (!ok) {
1478 return false;
1480 } else {
1481 ok = resolve_name(saf_servername,
1482 &domain->dcaddr,
1483 0x20,
1484 true);
1485 if (!ok) {
1486 goto fail;
1490 TALLOC_FREE(domain->dcname);
1491 ok = dcip_check_name(domain,
1492 domain,
1493 &domain->dcaddr,
1494 &domain->dcname,
1495 request_flags);
1496 if (!ok) {
1497 goto fail;
1501 if (domain->dcname == NULL) {
1502 return false;
1505 status = check_negative_conn_cache(domain->name, domain->dcname);
1506 if (!NT_STATUS_IS_OK(status)) {
1507 return false;
1510 status = smbsock_connect(&domain->dcaddr, 0,
1511 domain->dcname, -1, NULL, -1,
1512 fd, NULL, 10);
1513 if (!NT_STATUS_IS_OK(status)) {
1514 winbind_add_failed_connection_entry(domain,
1515 domain->dcname,
1516 NT_STATUS_UNSUCCESSFUL);
1517 return false;
1519 return true;
1521 fail:
1522 winbind_add_failed_connection_entry(domain,
1523 saf_servername,
1524 NT_STATUS_UNSUCCESSFUL);
1525 return false;
1529 /*******************************************************************
1530 Find and make a connection to a DC in the given domain.
1532 @param[in] mem_ctx talloc memory context to allocate from
1533 @param[in] domain domain to find a dc in
1534 @param[out] fd fd of the open socket connected to the newly found dc
1535 @return true when a DC connection is made, false otherwise
1536 *******************************************************************/
1538 static bool find_dc(TALLOC_CTX *mem_ctx,
1539 struct winbindd_domain *domain,
1540 uint32_t request_flags,
1541 int *fd)
1543 struct dc_name_ip *dcs = NULL;
1544 int num_dcs = 0;
1546 const char **dcnames = NULL;
1547 size_t num_dcnames = 0;
1549 struct sockaddr_storage *addrs = NULL;
1550 int num_addrs = 0;
1552 int i;
1553 size_t fd_index;
1555 NTSTATUS status;
1556 bool ok;
1558 *fd = -1;
1560 D_NOTICE("First try to connect to the closest DC (using server "
1561 "affinity cache). If this fails, try to lookup the DC using "
1562 "DNS afterwards.\n");
1563 ok = connect_preferred_dc(mem_ctx, domain, request_flags, fd);
1564 if (ok) {
1565 return true;
1568 if (domain->force_dc) {
1569 return false;
1572 again:
1573 D_DEBUG("Retrieving a list of IP addresses for DCs.\n");
1574 if (!get_dcs(mem_ctx, domain, &dcs, &num_dcs, request_flags) || (num_dcs == 0))
1575 return False;
1577 D_DEBUG("Retrieved IP addresses for %d DCs.\n", num_dcs);
1578 for (i=0; i<num_dcs; i++) {
1580 if (!add_string_to_array(mem_ctx, dcs[i].name,
1581 &dcnames, &num_dcnames)) {
1582 return False;
1584 if (!add_sockaddr_to_array(mem_ctx, &dcs[i].ss, TCP_SMB_PORT,
1585 &addrs, &num_addrs)) {
1586 return False;
1590 if ((num_dcnames == 0) || (num_dcnames != num_addrs))
1591 return False;
1593 if ((addrs == NULL) || (dcnames == NULL))
1594 return False;
1596 D_DEBUG("Trying to establish a connection to one of the %d DCs "
1597 "(timeout of 10 sec for each DC).\n",
1598 num_dcs);
1599 status = smbsock_any_connect(addrs, dcnames, NULL, NULL, NULL,
1600 num_addrs, 0, 10, fd, &fd_index, NULL);
1601 if (!NT_STATUS_IS_OK(status)) {
1602 for (i=0; i<num_dcs; i++) {
1603 char ab[INET6_ADDRSTRLEN];
1604 print_sockaddr(ab, sizeof(ab), &dcs[i].ss);
1605 DBG_DEBUG("smbsock_any_connect failed for "
1606 "domain %s address %s. Error was %s\n",
1607 domain->name, ab, nt_errstr(status));
1608 winbind_add_failed_connection_entry(domain,
1609 dcs[i].name, NT_STATUS_UNSUCCESSFUL);
1611 return False;
1613 D_NOTICE("Successfully connected to DC '%s'.\n", dcs[fd_index].name);
1615 domain->dcaddr = addrs[fd_index];
1617 if (*dcnames[fd_index] != '\0' && !is_ipaddress(dcnames[fd_index])) {
1618 /* Ok, we've got a name for the DC */
1619 TALLOC_FREE(domain->dcname);
1620 domain->dcname = talloc_strdup(domain, dcnames[fd_index]);
1621 if (domain->dcname == NULL) {
1622 return false;
1624 return true;
1627 /* Try to figure out the name */
1628 TALLOC_FREE(domain->dcname);
1629 ok = dcip_check_name(domain,
1630 domain,
1631 &domain->dcaddr,
1632 &domain->dcname,
1633 request_flags);
1634 if (ok) {
1635 return true;
1638 /* We can not continue without the DC's name */
1639 winbind_add_failed_connection_entry(domain, dcs[fd_index].name,
1640 NT_STATUS_UNSUCCESSFUL);
1642 /* Throw away all arrays as we're doing this again. */
1643 TALLOC_FREE(dcs);
1644 num_dcs = 0;
1646 TALLOC_FREE(dcnames);
1647 num_dcnames = 0;
1649 TALLOC_FREE(addrs);
1650 num_addrs = 0;
1652 if (*fd != -1) {
1653 close(*fd);
1654 *fd = -1;
1658 * This should not be an infinite loop, since get_dcs() will not return
1659 * the DC added to the negative connection cache in the above
1660 * winbind_add_failed_connection_entry() call.
1662 goto again;
1665 static char *current_dc_key(TALLOC_CTX *mem_ctx, const char *domain_name)
1667 return talloc_asprintf_strupper_m(mem_ctx, "CURRENT_DCNAME/%s",
1668 domain_name);
1671 static void store_current_dc_in_gencache(const char *domain_name,
1672 const char *dc_name,
1673 const struct sockaddr_storage *dc_addr)
1675 char addr[INET6_ADDRSTRLEN];
1676 char *key = NULL;
1677 char *value = NULL;
1679 print_sockaddr(addr, sizeof(addr), dc_addr);
1681 key = current_dc_key(talloc_tos(), domain_name);
1682 if (key == NULL) {
1683 goto done;
1686 value = talloc_asprintf(talloc_tos(), "%s %s", addr, dc_name);
1687 if (value == NULL) {
1688 goto done;
1691 gencache_set(key, value, 0x7fffffff);
1692 done:
1693 TALLOC_FREE(value);
1694 TALLOC_FREE(key);
1697 bool fetch_current_dc_from_gencache(TALLOC_CTX *mem_ctx,
1698 const char *domain_name,
1699 char **p_dc_name, char **p_dc_ip)
1701 char *key, *p;
1702 char *value = NULL;
1703 bool ret = false;
1704 char *dc_name = NULL;
1705 char *dc_ip = NULL;
1707 key = current_dc_key(talloc_tos(), domain_name);
1708 if (key == NULL) {
1709 goto done;
1711 if (!gencache_get(key, mem_ctx, &value, NULL)) {
1712 goto done;
1714 p = strchr(value, ' ');
1715 if (p == NULL) {
1716 goto done;
1718 dc_ip = talloc_strndup(mem_ctx, value, p - value);
1719 if (dc_ip == NULL) {
1720 goto done;
1722 dc_name = talloc_strdup(mem_ctx, p+1);
1723 if (dc_name == NULL) {
1724 goto done;
1727 if (p_dc_ip != NULL) {
1728 *p_dc_ip = dc_ip;
1729 dc_ip = NULL;
1731 if (p_dc_name != NULL) {
1732 *p_dc_name = dc_name;
1733 dc_name = NULL;
1735 ret = true;
1736 done:
1737 TALLOC_FREE(dc_name);
1738 TALLOC_FREE(dc_ip);
1739 TALLOC_FREE(key);
1740 TALLOC_FREE(value);
1741 return ret;
1744 NTSTATUS wb_open_internal_pipe(TALLOC_CTX *mem_ctx,
1745 const struct ndr_interface_table *table,
1746 struct rpc_pipe_client **ret_pipe)
1748 struct rpc_pipe_client *cli = NULL;
1749 const struct auth_session_info *session_info = NULL;
1750 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1753 session_info = get_session_info_system();
1754 SMB_ASSERT(session_info != NULL);
1756 status = rpc_pipe_open_local_np(
1757 mem_ctx, table, NULL, NULL, NULL, NULL, session_info, &cli);
1758 if (!NT_STATUS_IS_OK(status)) {
1759 return status;
1762 if (ret_pipe) {
1763 *ret_pipe = cli;
1766 return NT_STATUS_OK;
1769 static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
1770 struct winbindd_cm_conn *new_conn,
1771 bool need_rw_dc)
1773 TALLOC_CTX *mem_ctx;
1774 NTSTATUS result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1775 int retries;
1776 uint32_t request_flags = need_rw_dc ? DS_WRITABLE_REQUIRED : 0;
1777 int fd = -1;
1778 bool retry = false;
1779 bool seal_pipes = true;
1781 if ((mem_ctx = talloc_init("cm_open_connection")) == NULL) {
1782 set_domain_offline(domain);
1783 return NT_STATUS_NO_MEMORY;
1786 D_NOTICE("Creating connection to domain controller. This is a start of "
1787 "a new connection or a DC failover. The failover only happens "
1788 "if the domain has more than one DC. We will try to connect 3 "
1789 "times at most.\n");
1790 for (retries = 0; retries < 3; retries++) {
1791 bool found_dc;
1793 D_DEBUG("Attempt %d/3: DC '%s' of domain '%s'.\n",
1794 retries,
1795 domain->dcname ? domain->dcname : "",
1796 domain->name);
1798 found_dc = find_dc(mem_ctx, domain, request_flags, &fd);
1799 if (!found_dc) {
1800 /* This is the one place where we will
1801 set the global winbindd offline state
1802 to true, if a "WINBINDD_OFFLINE" entry
1803 is found in the winbindd cache. */
1804 set_global_winbindd_state_offline();
1805 result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1806 break;
1809 new_conn->cli = NULL;
1811 result = cm_prepare_connection(domain, fd, domain->dcname,
1812 &new_conn->cli, &retry);
1813 if (NT_STATUS_IS_OK(result)) {
1814 break;
1816 if (!retry) {
1817 break;
1821 if (!NT_STATUS_IS_OK(result)) {
1822 /* Ensure we setup the retry handler. */
1823 set_domain_offline(domain);
1824 goto out;
1827 winbindd_set_locator_kdc_envs(domain);
1829 if (domain->online == False) {
1830 /* We're changing state from offline to online. */
1831 set_global_winbindd_state_online();
1833 set_domain_online(domain);
1836 * Much as I hate global state, this seems to be the point
1837 * where we can be certain that we have a proper connection to
1838 * a DC. wbinfo --dc-info needs that information, store it in
1839 * gencache with a looong timeout. This will need revisiting
1840 * once we start to connect to multiple DCs, wbcDcInfo is
1841 * already prepared for that.
1843 store_current_dc_in_gencache(domain->name,
1844 domain->dcname,
1845 &domain->dcaddr);
1847 seal_pipes = lp_winbind_sealed_pipes();
1848 seal_pipes = lp_parm_bool(-1, "winbind sealed pipes",
1849 domain->name,
1850 seal_pipes);
1852 if (seal_pipes) {
1853 new_conn->auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
1854 } else {
1855 new_conn->auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
1858 out:
1859 talloc_destroy(mem_ctx);
1860 return result;
1863 /* Close down all open pipes on a connection. */
1865 void invalidate_cm_connection(struct winbindd_domain *domain)
1867 NTSTATUS result;
1868 struct winbindd_cm_conn *conn = &domain->conn;
1870 domain->sequence_number = DOM_SEQUENCE_NONE;
1871 domain->last_seq_check = 0;
1872 domain->last_status = NT_STATUS_SERVER_DISABLED;
1874 /* We're closing down a possibly dead
1875 connection. Don't have impossibly long (10s) timeouts. */
1877 if (conn->cli) {
1878 cli_set_timeout(conn->cli, 1000); /* 1 second. */
1881 if (conn->samr_pipe != NULL) {
1882 if (is_valid_policy_hnd(&conn->sam_connect_handle)) {
1883 dcerpc_samr_Close(conn->samr_pipe->binding_handle,
1884 talloc_tos(),
1885 &conn->sam_connect_handle,
1886 &result);
1888 TALLOC_FREE(conn->samr_pipe);
1889 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1890 if (conn->cli) {
1891 cli_set_timeout(conn->cli, 500);
1895 if (conn->lsa_pipe != NULL) {
1896 if (is_valid_policy_hnd(&conn->lsa_policy)) {
1897 dcerpc_lsa_Close(conn->lsa_pipe->binding_handle,
1898 talloc_tos(),
1899 &conn->lsa_policy,
1900 &result);
1902 TALLOC_FREE(conn->lsa_pipe);
1903 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1904 if (conn->cli) {
1905 cli_set_timeout(conn->cli, 500);
1909 if (conn->lsa_pipe_tcp != NULL) {
1910 if (is_valid_policy_hnd(&conn->lsa_policy)) {
1911 dcerpc_lsa_Close(conn->lsa_pipe_tcp->binding_handle,
1912 talloc_tos(),
1913 &conn->lsa_policy,
1914 &result);
1916 TALLOC_FREE(conn->lsa_pipe_tcp);
1917 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1918 if (conn->cli) {
1919 cli_set_timeout(conn->cli, 500);
1923 if (conn->netlogon_pipe != NULL) {
1924 TALLOC_FREE(conn->netlogon_pipe);
1925 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1926 if (conn->cli) {
1927 cli_set_timeout(conn->cli, 500);
1931 conn->auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
1932 TALLOC_FREE(conn->netlogon_creds_ctx);
1934 if (conn->cli) {
1935 cli_shutdown(conn->cli);
1938 conn->cli = NULL;
1941 void close_conns_after_fork(void)
1943 struct winbindd_domain *domain;
1944 struct winbindd_cli_state *cli_state;
1946 for (domain = domain_list(); domain; domain = domain->next) {
1948 * first close the low level SMB TCP connection
1949 * so that we don't generate any SMBclose
1950 * requests in invalidate_cm_connection()
1952 if (cli_state_is_connected(domain->conn.cli)) {
1953 smbXcli_conn_disconnect(domain->conn.cli->conn, NT_STATUS_OK);
1956 invalidate_cm_connection(domain);
1959 for (cli_state = winbindd_client_list();
1960 cli_state != NULL;
1961 cli_state = cli_state->next) {
1962 if (cli_state->sock >= 0) {
1963 close(cli_state->sock);
1964 cli_state->sock = -1;
1969 static bool connection_ok(struct winbindd_domain *domain)
1971 bool ok;
1973 ok = cli_state_is_connected(domain->conn.cli);
1974 if (!ok) {
1975 DEBUG(3, ("connection_ok: Connection to %s for domain %s is not connected\n",
1976 domain->dcname, domain->name));
1977 return False;
1980 if (!domain->online) {
1981 DEBUG(3, ("connection_ok: Domain %s is offline\n", domain->name));
1982 return False;
1985 return True;
1988 /* Initialize a new connection up to the RPC BIND.
1989 Bypass online status check so always does network calls. */
1991 static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain, bool need_rw_dc)
1993 NTSTATUS result;
1994 bool skip_connection = domain->internal;
1995 if (need_rw_dc && domain->rodc) {
1996 skip_connection = false;
1999 /* Internal connections never use the network. */
2000 if (dom_sid_equal(&domain->sid, &global_sid_Builtin)) {
2001 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2004 /* Still ask the internal LSA and SAMR server about the local domain */
2005 if (skip_connection || connection_ok(domain)) {
2006 if (!domain->initialized) {
2007 set_dc_type_and_flags(domain);
2009 return NT_STATUS_OK;
2012 invalidate_cm_connection(domain);
2014 if (!domain->primary && !domain->initialized) {
2016 * Before we connect to a trust, work out if it is an
2017 * AD domain by asking our own domain.
2019 set_dc_type_and_flags_trustinfo(domain);
2022 result = cm_open_connection(domain, &domain->conn, need_rw_dc);
2024 if (NT_STATUS_IS_OK(result) && !domain->initialized) {
2025 set_dc_type_and_flags(domain);
2028 return result;
2031 NTSTATUS init_dc_connection(struct winbindd_domain *domain, bool need_rw_dc)
2033 if (dom_sid_equal(&domain->sid, &global_sid_Builtin)) {
2034 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2037 SMB_ASSERT(wb_child_domain() || idmap_child());
2039 return init_dc_connection_network(domain, need_rw_dc);
2042 static NTSTATUS init_dc_connection_rpc(struct winbindd_domain *domain, bool need_rw_dc)
2044 NTSTATUS status;
2046 status = init_dc_connection(domain, need_rw_dc);
2047 if (!NT_STATUS_IS_OK(status)) {
2048 return status;
2051 if (!domain->internal && domain->conn.cli == NULL) {
2052 /* happens for trusted domains without inbound trust */
2053 return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
2056 return NT_STATUS_OK;
2059 /******************************************************************************
2060 Set the trust flags (direction and forest location) for a domain
2061 ******************************************************************************/
2063 static bool set_dc_type_and_flags_trustinfo( struct winbindd_domain *domain )
2065 struct winbindd_domain *our_domain;
2066 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2067 WERROR werr;
2068 struct netr_DomainTrustList trusts;
2069 int i;
2070 uint32_t flags = (NETR_TRUST_FLAG_IN_FOREST |
2071 NETR_TRUST_FLAG_OUTBOUND |
2072 NETR_TRUST_FLAG_INBOUND);
2073 struct rpc_pipe_client *cli;
2074 TALLOC_CTX *mem_ctx = NULL;
2075 struct dcerpc_binding_handle *b;
2077 if (IS_DC) {
2079 * On a DC we loaded all trusts
2080 * from configuration and never learn
2081 * new domains.
2083 return true;
2086 DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s\n", domain->name ));
2088 /* Our primary domain doesn't need to worry about trust flags.
2089 Force it to go through the network setup */
2090 if ( domain->primary ) {
2091 return False;
2094 mem_ctx = talloc_stackframe();
2095 our_domain = find_our_domain();
2096 if (our_domain->internal) {
2097 result = init_dc_connection(our_domain, false);
2098 if (!NT_STATUS_IS_OK(result)) {
2099 DEBUG(3,("set_dc_type_and_flags_trustinfo: "
2100 "Not able to make a connection to our domain: %s\n",
2101 nt_errstr(result)));
2102 TALLOC_FREE(mem_ctx);
2103 return false;
2107 /* This won't work unless our domain is AD */
2108 if ( !our_domain->active_directory ) {
2109 TALLOC_FREE(mem_ctx);
2110 return False;
2113 if (our_domain->internal) {
2114 result = wb_open_internal_pipe(mem_ctx, &ndr_table_netlogon, &cli);
2115 } else if (!connection_ok(our_domain)) {
2116 DEBUG(3,("set_dc_type_and_flags_trustinfo: "
2117 "No connection to our domain!\n"));
2118 TALLOC_FREE(mem_ctx);
2119 return False;
2120 } else {
2121 result = cm_connect_netlogon(our_domain, &cli);
2124 if (!NT_STATUS_IS_OK(result)) {
2125 DEBUG(5, ("set_dc_type_and_flags_trustinfo: Could not open "
2126 "a connection to %s for PIPE_NETLOGON (%s)\n",
2127 domain->name, nt_errstr(result)));
2128 TALLOC_FREE(mem_ctx);
2129 return False;
2131 b = cli->binding_handle;
2133 /* Use DsEnumerateDomainTrusts to get us the trust direction and type. */
2134 result = dcerpc_netr_DsrEnumerateDomainTrusts(b, mem_ctx,
2135 cli->desthost,
2136 flags,
2137 &trusts,
2138 &werr);
2139 if (!NT_STATUS_IS_OK(result)) {
2140 DEBUG(0,("set_dc_type_and_flags_trustinfo: "
2141 "failed to query trusted domain list: %s\n",
2142 nt_errstr(result)));
2143 TALLOC_FREE(mem_ctx);
2144 return false;
2146 if (!W_ERROR_IS_OK(werr)) {
2147 DEBUG(0,("set_dc_type_and_flags_trustinfo: "
2148 "failed to query trusted domain list: %s\n",
2149 win_errstr(werr)));
2150 TALLOC_FREE(mem_ctx);
2151 return false;
2154 /* Now find the domain name and get the flags */
2156 for ( i=0; i<trusts.count; i++ ) {
2157 if ( strequal( domain->name, trusts.array[i].netbios_name) ) {
2158 domain->domain_flags = trusts.array[i].trust_flags;
2159 domain->domain_type = trusts.array[i].trust_type;
2160 domain->domain_trust_attribs = trusts.array[i].trust_attributes;
2162 if ( domain->domain_type == LSA_TRUST_TYPE_UPLEVEL )
2163 domain->active_directory = True;
2165 DEBUG(5,("set_dc_type_and_flags_trustinfo: domain %s is %s"
2166 "running active directory.\n", domain->name,
2167 domain->active_directory ? "" : "NOT "));
2169 domain->can_do_ncacn_ip_tcp = domain->active_directory;
2171 domain->initialized = True;
2173 break;
2177 TALLOC_FREE(mem_ctx);
2179 return domain->initialized;
2182 /******************************************************************************
2183 We can 'sense' certain things about the DC by it's replies to certain
2184 questions.
2186 This tells us if this particular remote server is Active Directory, and if it
2187 is native mode.
2188 ******************************************************************************/
2190 static void set_dc_type_and_flags_connect( struct winbindd_domain *domain )
2192 NTSTATUS status, result;
2193 NTSTATUS close_status = NT_STATUS_UNSUCCESSFUL;
2194 TALLOC_CTX *mem_ctx = NULL;
2195 struct rpc_pipe_client *cli = NULL;
2196 struct policy_handle pol = { .handle_type = 0 };
2197 union lsa_PolicyInformation *lsa_info = NULL;
2198 union lsa_revision_info out_revision_info = {
2199 .info1 = {
2200 .revision = 0,
2203 uint32_t out_version = 0;
2205 if (!domain->internal && !connection_ok(domain)) {
2206 return;
2209 mem_ctx = talloc_init("set_dc_type_and_flags on domain %s\n",
2210 domain->name);
2211 if (!mem_ctx) {
2212 DEBUG(1, ("set_dc_type_and_flags_connect: talloc_init() failed\n"));
2213 return;
2216 DEBUG(5, ("set_dc_type_and_flags_connect: domain %s\n", domain->name ));
2218 if (domain->internal) {
2219 status = wb_open_internal_pipe(mem_ctx,
2220 &ndr_table_lsarpc,
2221 &cli);
2222 } else {
2223 status = cli_rpc_pipe_open_noauth(domain->conn.cli,
2224 &ndr_table_lsarpc, &cli);
2226 if (!NT_STATUS_IS_OK(status)) {
2227 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
2228 "PI_LSARPC on domain %s: (%s)\n",
2229 domain->name, nt_errstr(status)));
2230 TALLOC_FREE(cli);
2231 TALLOC_FREE(mem_ctx);
2232 return;
2235 status = dcerpc_lsa_open_policy_fallback(cli->binding_handle,
2236 mem_ctx,
2237 cli->srv_name_slash,
2238 true,
2239 SEC_FLAG_MAXIMUM_ALLOWED,
2240 &out_version,
2241 &out_revision_info,
2242 &pol,
2243 &result);
2245 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2246 /* This particular query is exactly what Win2k clients use
2247 to determine that the DC is active directory */
2248 status = dcerpc_lsa_QueryInfoPolicy2(cli->binding_handle, mem_ctx,
2249 &pol,
2250 LSA_POLICY_INFO_DNS,
2251 &lsa_info,
2252 &result);
2256 * If the status and result will not be OK we will fallback to
2257 * OpenPolicy.
2259 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2260 domain->active_directory = True;
2262 if (lsa_info->dns.name.string) {
2263 if (!strequal(domain->name, lsa_info->dns.name.string))
2265 DEBUG(1, ("set_dc_type_and_flags_connect: DC "
2266 "for domain %s claimed it was a DC "
2267 "for domain %s, refusing to "
2268 "initialize\n",
2269 domain->name,
2270 lsa_info->dns.name.string));
2271 TALLOC_FREE(cli);
2272 TALLOC_FREE(mem_ctx);
2273 return;
2275 talloc_free(domain->name);
2276 domain->name = talloc_strdup(domain,
2277 lsa_info->dns.name.string);
2278 if (domain->name == NULL) {
2279 goto done;
2283 if (lsa_info->dns.dns_domain.string) {
2284 if (domain->alt_name != NULL &&
2285 !strequal(domain->alt_name,
2286 lsa_info->dns.dns_domain.string))
2288 DEBUG(1, ("set_dc_type_and_flags_connect: DC "
2289 "for domain %s (%s) claimed it was "
2290 "a DC for domain %s, refusing to "
2291 "initialize\n",
2292 domain->alt_name, domain->name,
2293 lsa_info->dns.dns_domain.string));
2294 TALLOC_FREE(cli);
2295 TALLOC_FREE(mem_ctx);
2296 return;
2298 talloc_free(domain->alt_name);
2299 domain->alt_name =
2300 talloc_strdup(domain,
2301 lsa_info->dns.dns_domain.string);
2302 if (domain->alt_name == NULL) {
2303 goto done;
2307 /* See if we can set some domain trust flags about
2308 ourself */
2310 if (lsa_info->dns.dns_forest.string) {
2311 talloc_free(domain->forest_name);
2312 domain->forest_name =
2313 talloc_strdup(domain,
2314 lsa_info->dns.dns_forest.string);
2315 if (domain->forest_name == NULL) {
2316 goto done;
2319 if (strequal(domain->forest_name, domain->alt_name)) {
2320 domain->domain_flags |= NETR_TRUST_FLAG_TREEROOT;
2324 if (lsa_info->dns.sid) {
2325 if (!is_null_sid(&domain->sid) &&
2326 !dom_sid_equal(&domain->sid,
2327 lsa_info->dns.sid))
2329 struct dom_sid_buf buf1, buf2;
2330 DEBUG(1, ("set_dc_type_and_flags_connect: DC "
2331 "for domain %s (%s) claimed it was "
2332 "a DC for domain %s, refusing to "
2333 "initialize\n",
2334 dom_sid_str_buf(&domain->sid, &buf1),
2335 domain->name,
2336 dom_sid_str_buf(lsa_info->dns.sid,
2337 &buf2)));
2338 TALLOC_FREE(cli);
2339 TALLOC_FREE(mem_ctx);
2340 return;
2342 sid_copy(&domain->sid, lsa_info->dns.sid);
2344 } else {
2345 domain->active_directory = False;
2347 status = rpccli_lsa_open_policy(cli, mem_ctx, True,
2348 SEC_FLAG_MAXIMUM_ALLOWED,
2349 &pol);
2351 if (!NT_STATUS_IS_OK(status)) {
2352 goto done;
2355 status = dcerpc_lsa_QueryInfoPolicy(cli->binding_handle, mem_ctx,
2356 &pol,
2357 LSA_POLICY_INFO_ACCOUNT_DOMAIN,
2358 &lsa_info,
2359 &result);
2360 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2362 if (lsa_info->account_domain.name.string) {
2363 if (!strequal(domain->name,
2364 lsa_info->account_domain.name.string))
2366 DEBUG(1,
2367 ("set_dc_type_and_flags_connect: "
2368 "DC for domain %s claimed it was"
2369 " a DC for domain %s, refusing "
2370 "to initialize\n", domain->name,
2371 lsa_info->
2372 account_domain.name.string));
2373 TALLOC_FREE(cli);
2374 TALLOC_FREE(mem_ctx);
2375 return;
2377 talloc_free(domain->name);
2378 domain->name =
2379 talloc_strdup(domain,
2380 lsa_info->account_domain.name.string);
2383 if (lsa_info->account_domain.sid) {
2384 if (!is_null_sid(&domain->sid) &&
2385 !dom_sid_equal(&domain->sid,
2386 lsa_info->account_domain.sid))
2388 struct dom_sid_buf buf1, buf2;
2389 DEBUG(1,
2390 ("set_dc_type_and_flags_connect: "
2391 "DC for domain %s (%s) claimed "
2392 "it was a DC for domain %s, "
2393 "refusing to initialize\n",
2394 dom_sid_str_buf(
2395 &domain->sid, &buf1),
2396 domain->name,
2397 dom_sid_str_buf(
2398 lsa_info->account_domain.sid,
2399 &buf2)));
2400 TALLOC_FREE(cli);
2401 TALLOC_FREE(mem_ctx);
2402 return;
2404 sid_copy(&domain->sid, lsa_info->account_domain.sid);
2408 done:
2409 if (is_valid_policy_hnd(&pol)) {
2410 dcerpc_lsa_Close(cli->binding_handle,
2411 mem_ctx,
2412 &pol,
2413 &close_status);
2416 DEBUG(5,("set_dc_type_and_flags_connect: domain %s is %srunning active directory.\n",
2417 domain->name, domain->active_directory ? "" : "NOT "));
2419 domain->can_do_ncacn_ip_tcp = domain->active_directory;
2421 TALLOC_FREE(cli);
2423 TALLOC_FREE(mem_ctx);
2425 domain->initialized = True;
2428 /**********************************************************************
2429 Set the domain_flags (trust attributes, domain operating modes, etc...
2430 ***********************************************************************/
2432 static void set_dc_type_and_flags( struct winbindd_domain *domain )
2434 if (IS_DC) {
2436 * On a DC we loaded all trusts
2437 * from configuration and never learn
2438 * new domains.
2440 return;
2443 /* we always have to contact our primary domain */
2444 if (domain->primary || domain->internal) {
2446 * primary and internal domains are
2447 * are already completely
2448 * setup via init_domain_list()
2449 * calling add_trusted_domain()
2451 * There's no need to ask the
2452 * server again, if it hosts an AD
2453 * domain...
2455 domain->initialized = true;
2456 return;
2459 /* Use our DC to get the information if possible */
2461 if ( !set_dc_type_and_flags_trustinfo( domain ) ) {
2462 /* Otherwise, fallback to contacting the
2463 domain directly */
2464 set_dc_type_and_flags_connect( domain );
2467 return;
2472 /**********************************************************************
2473 ***********************************************************************/
2475 static NTSTATUS cm_get_schannel_creds(struct winbindd_domain *domain,
2476 struct netlogon_creds_cli_context **ppdc)
2478 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2479 struct rpc_pipe_client *netlogon_pipe;
2481 *ppdc = NULL;
2483 if ((!IS_DC) && (!domain->primary)) {
2484 return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
2487 if (domain->conn.netlogon_creds_ctx != NULL) {
2488 *ppdc = domain->conn.netlogon_creds_ctx;
2489 return NT_STATUS_OK;
2492 result = cm_connect_netlogon_secure(domain, &netlogon_pipe, ppdc);
2493 if (!NT_STATUS_IS_OK(result)) {
2494 return result;
2497 return NT_STATUS_OK;
2500 static NTSTATUS cm_connect_schannel_or_krb5(struct cli_state *cli,
2501 const struct ndr_interface_table *table,
2502 enum dcerpc_transport_t transport,
2503 struct cli_credentials *cli_creds,
2504 struct netlogon_creds_cli_context *netlogon_creds,
2505 const char *remote_name,
2506 const struct sockaddr_storage *remote_sockaddr,
2507 struct rpc_pipe_client **_rpccli)
2509 TALLOC_CTX *frame = talloc_stackframe();
2510 enum netr_SchannelType sec_chan_type;
2511 struct netlogon_creds_CredentialState *creds = NULL;
2512 bool authenticate_kerberos;
2513 NTSTATUS status;
2515 if (cli_credentials_is_anonymous(cli_creds)) {
2516 DBG_WARNING("anonymous credentials "
2517 "unable to make secure connection to %s\n",
2518 remote_name);
2519 TALLOC_FREE(frame);
2520 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2523 sec_chan_type = cli_credentials_get_secure_channel_type(cli_creds);
2524 if (sec_chan_type == SEC_CHAN_NULL) {
2525 DBG_WARNING("SEC_CHAN_NULL credentials "
2526 "unable to make secure connection to %s\n",
2527 remote_name);
2528 TALLOC_FREE(frame);
2529 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2532 status = netlogon_creds_cli_get(netlogon_creds, frame, &creds);
2533 if (!NT_STATUS_IS_OK(status)) {
2534 TALLOC_FREE(frame);
2535 return status;
2537 authenticate_kerberos = creds->authenticate_kerberos;
2538 TALLOC_FREE(creds);
2540 if (authenticate_kerberos) {
2541 status = cli_rpc_pipe_open_with_creds(cli,
2542 table,
2543 transport,
2544 DCERPC_AUTH_TYPE_KRB5,
2545 DCERPC_AUTH_LEVEL_PRIVACY,
2546 "netlogon",
2547 remote_name,
2548 remote_sockaddr,
2549 cli_creds,
2550 _rpccli);
2551 if (!NT_STATUS_IS_OK(status)) {
2552 TALLOC_FREE(frame);
2553 return status;
2555 TALLOC_FREE(frame);
2556 return NT_STATUS_OK;
2559 status = cli_rpc_pipe_open_schannel_with_creds(cli,
2560 table,
2561 transport,
2562 netlogon_creds,
2563 remote_name,
2564 remote_sockaddr,
2565 _rpccli);
2566 if (!NT_STATUS_IS_OK(status)) {
2567 TALLOC_FREE(frame);
2568 return status;
2570 TALLOC_FREE(frame);
2571 return NT_STATUS_OK;
2574 NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
2575 bool need_rw_dc,
2576 struct rpc_pipe_client **cli, struct policy_handle *sam_handle)
2578 struct winbindd_cm_conn *conn;
2579 NTSTATUS status, result;
2580 struct netlogon_creds_cli_context *p_creds;
2581 struct cli_credentials *creds = NULL;
2582 bool retry = false; /* allow one retry attempt for expired session */
2583 const char *remote_name = NULL;
2584 const struct sockaddr_storage *remote_sockaddr = NULL;
2585 bool sealed_pipes = true;
2586 bool strong_key = true;
2588 if (sid_check_is_our_sam(&domain->sid)) {
2589 if (domain->rodc == false || need_rw_dc == false) {
2590 return open_internal_samr_conn(mem_ctx, domain, cli, sam_handle);
2594 if (IS_AD_DC) {
2596 * In theory we should not use SAMR within
2597 * winbindd at all, but that's a larger task to
2598 * remove this and avoid breaking existing
2599 * setups.
2601 * At least as AD DC we have the restriction
2602 * to avoid SAMR against trusted domains,
2603 * as there're no existing setups.
2605 return NT_STATUS_REQUEST_NOT_ACCEPTED;
2608 retry:
2609 status = init_dc_connection_rpc(domain, need_rw_dc);
2610 if (!NT_STATUS_IS_OK(status)) {
2611 return status;
2614 conn = &domain->conn;
2616 if (rpccli_is_connected(conn->samr_pipe)) {
2617 goto done;
2620 TALLOC_FREE(conn->samr_pipe);
2623 * No SAMR pipe yet. Attempt to get an NTLMSSP SPNEGO authenticated
2624 * sign and sealed pipe using the machine account password by
2625 * preference. If we can't - try schannel, if that fails, try
2626 * anonymous.
2629 result = winbindd_get_trust_credentials(domain,
2630 talloc_tos(),
2631 false, /* netlogon */
2632 true, /* ipc_fallback */
2633 &creds);
2634 if (!NT_STATUS_IS_OK(result)) {
2635 DEBUG(10, ("cm_connect_sam: No user available for "
2636 "domain %s, trying schannel\n", domain->name));
2637 goto schannel;
2640 if (cli_credentials_is_anonymous(creds)) {
2641 goto anonymous;
2644 remote_name = smbXcli_conn_remote_name(conn->cli->conn);
2645 remote_sockaddr = smbXcli_conn_remote_sockaddr(conn->cli->conn);
2648 * We have an authenticated connection. Use a SPNEGO
2649 * authenticated SAMR pipe with sign & seal.
2651 status = cli_rpc_pipe_open_with_creds(conn->cli,
2652 &ndr_table_samr,
2653 NCACN_NP,
2654 DCERPC_AUTH_TYPE_SPNEGO,
2655 conn->auth_level,
2656 NULL, /* target_service */
2657 remote_name,
2658 remote_sockaddr,
2659 creds,
2660 &conn->samr_pipe);
2662 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)
2663 && !retry) {
2664 invalidate_cm_connection(domain);
2665 retry = true;
2666 goto retry;
2669 if (!NT_STATUS_IS_OK(status)) {
2670 DEBUG(10,("cm_connect_sam: failed to connect to SAMR "
2671 "pipe for domain %s using NTLMSSP "
2672 "authenticated pipe: user %s. Error was "
2673 "%s\n", domain->name,
2674 cli_credentials_get_unparsed_name(creds, talloc_tos()),
2675 nt_errstr(status)));
2676 goto schannel;
2679 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for "
2680 "domain %s using NTLMSSP authenticated "
2681 "pipe: user %s\n", domain->name,
2682 cli_credentials_get_unparsed_name(creds, talloc_tos())));
2684 status = dcerpc_samr_Connect2(conn->samr_pipe->binding_handle, mem_ctx,
2685 conn->samr_pipe->desthost,
2686 SEC_FLAG_MAXIMUM_ALLOWED,
2687 &conn->sam_connect_handle,
2688 &result);
2690 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_DEVICE_ERROR) && !retry) {
2691 invalidate_cm_connection(domain);
2692 TALLOC_FREE(conn->samr_pipe);
2693 retry = true;
2694 goto retry;
2697 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2698 goto open_domain;
2700 if (NT_STATUS_IS_OK(status)) {
2701 status = result;
2704 DEBUG(10,("cm_connect_sam: ntlmssp-sealed dcerpc_samr_Connect2 "
2705 "failed for domain %s, error was %s. Trying schannel\n",
2706 domain->name, nt_errstr(status) ));
2707 TALLOC_FREE(conn->samr_pipe);
2709 schannel:
2711 /* Fall back to schannel if it's a W2K pre-SP1 box. */
2713 status = cm_get_schannel_creds(domain, &p_creds);
2714 if (!NT_STATUS_IS_OK(status)) {
2715 /* If this call fails - conn->cli can now be NULL ! */
2716 DEBUG(10, ("cm_connect_sam: Could not get schannel auth info "
2717 "for domain %s (error %s), trying anon\n",
2718 domain->name,
2719 nt_errstr(status) ));
2720 goto anonymous;
2722 TALLOC_FREE(creds);
2723 result = winbindd_get_trust_credentials(domain,
2724 talloc_tos(),
2725 true, /* netlogon */
2726 false, /* ipc_fallback */
2727 &creds);
2728 if (!NT_STATUS_IS_OK(result)) {
2729 goto done;
2732 status = cm_connect_schannel_or_krb5(
2733 conn->cli,
2734 &ndr_table_samr,
2735 NCACN_NP,
2736 creds,
2737 p_creds,
2738 remote_name,
2739 remote_sockaddr,
2740 &conn->samr_pipe);
2742 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)
2743 && !retry) {
2744 invalidate_cm_connection(domain);
2745 retry = true;
2746 goto retry;
2749 if (!NT_STATUS_IS_OK(status)) {
2750 DEBUG(10,("cm_connect_sam: failed to connect to SAMR pipe for "
2751 "domain %s using schannel. Error was %s\n",
2752 domain->name, nt_errstr(status) ));
2753 goto anonymous;
2755 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for domain %s using "
2756 "schannel.\n", domain->name ));
2758 status = dcerpc_samr_Connect2(conn->samr_pipe->binding_handle, mem_ctx,
2759 conn->samr_pipe->desthost,
2760 SEC_FLAG_MAXIMUM_ALLOWED,
2761 &conn->sam_connect_handle,
2762 &result);
2764 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_DEVICE_ERROR) && !retry) {
2765 invalidate_cm_connection(domain);
2766 TALLOC_FREE(conn->samr_pipe);
2767 retry = true;
2768 goto retry;
2771 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2772 goto open_domain;
2774 if (NT_STATUS_IS_OK(status)) {
2775 status = result;
2777 DEBUG(10,("cm_connect_sam: schannel-sealed dcerpc_samr_Connect2 failed "
2778 "for domain %s, error was %s. Trying anonymous\n",
2779 domain->name, nt_errstr(status) ));
2780 TALLOC_FREE(conn->samr_pipe);
2782 anonymous:
2784 sealed_pipes = lp_winbind_sealed_pipes();
2785 sealed_pipes = lp_parm_bool(-1, "winbind sealed pipes",
2786 domain->name,
2787 sealed_pipes);
2788 strong_key = lp_require_strong_key();
2789 strong_key = lp_parm_bool(-1, "require strong key",
2790 domain->name,
2791 strong_key);
2793 /* Finally fall back to anonymous. */
2794 if (sealed_pipes || strong_key) {
2795 status = NT_STATUS_DOWNGRADE_DETECTED;
2796 DEBUG(1, ("Unwilling to make SAMR connection to domain %s "
2797 "without connection level security, "
2798 "must set 'winbind sealed pipes:%s = false' and "
2799 "'require strong key:%s = false' to proceed: %s\n",
2800 domain->name, domain->name, domain->name,
2801 nt_errstr(status)));
2802 goto done;
2804 status = cli_rpc_pipe_open_noauth(conn->cli, &ndr_table_samr,
2805 &conn->samr_pipe);
2807 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)
2808 && !retry) {
2809 invalidate_cm_connection(domain);
2810 retry = true;
2811 goto retry;
2814 if (!NT_STATUS_IS_OK(status)) {
2815 goto done;
2818 status = dcerpc_samr_Connect2(conn->samr_pipe->binding_handle, mem_ctx,
2819 conn->samr_pipe->desthost,
2820 SEC_FLAG_MAXIMUM_ALLOWED,
2821 &conn->sam_connect_handle,
2822 &result);
2824 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_DEVICE_ERROR) && !retry) {
2825 invalidate_cm_connection(domain);
2826 TALLOC_FREE(conn->samr_pipe);
2827 retry = true;
2828 goto retry;
2831 if (!NT_STATUS_IS_OK(status)) {
2832 DEBUG(10,("cm_connect_sam: rpccli_samr_Connect2 failed "
2833 "for domain %s Error was %s\n",
2834 domain->name, nt_errstr(status) ));
2835 goto done;
2837 if (!NT_STATUS_IS_OK(result)) {
2838 status = result;
2839 DEBUG(10,("cm_connect_sam: dcerpc_samr_Connect2 failed "
2840 "for domain %s Error was %s\n",
2841 domain->name, nt_errstr(result)));
2842 goto done;
2845 open_domain:
2846 status = dcerpc_samr_OpenDomain(conn->samr_pipe->binding_handle,
2847 mem_ctx,
2848 &conn->sam_connect_handle,
2849 SEC_FLAG_MAXIMUM_ALLOWED,
2850 &domain->sid,
2851 &conn->sam_domain_handle,
2852 &result);
2853 if (!NT_STATUS_IS_OK(status)) {
2854 goto done;
2857 status = result;
2858 done:
2860 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2862 * if we got access denied, we might just have no access rights
2863 * to talk to the remote samr server server (e.g. when we are a
2864 * PDC and we are connecting a w2k8 pdc via an interdomain
2865 * trust). In that case do not invalidate the whole connection
2866 * stack
2868 TALLOC_FREE(conn->samr_pipe);
2869 ZERO_STRUCT(conn->sam_domain_handle);
2870 return status;
2871 } else if (!NT_STATUS_IS_OK(status)) {
2872 invalidate_cm_connection(domain);
2873 return status;
2876 *cli = conn->samr_pipe;
2877 *sam_handle = conn->sam_domain_handle;
2878 return status;
2881 /**********************************************************************
2882 open an schanneld ncacn_ip_tcp connection to LSA
2883 ***********************************************************************/
2885 static NTSTATUS cm_connect_lsa_tcp(struct winbindd_domain *domain,
2886 TALLOC_CTX *mem_ctx,
2887 struct rpc_pipe_client **cli)
2889 struct winbindd_cm_conn *conn;
2890 struct cli_credentials *cli_creds = NULL;
2891 struct netlogon_creds_cli_context *p_creds = NULL;
2892 NTSTATUS status;
2893 const char *remote_name = NULL;
2894 const struct sockaddr_storage *remote_sockaddr = NULL;
2896 DEBUG(10,("cm_connect_lsa_tcp\n"));
2898 status = init_dc_connection_rpc(domain, false);
2899 if (!NT_STATUS_IS_OK(status)) {
2900 return status;
2903 conn = &domain->conn;
2906 * rpccli_is_connected handles more error cases
2908 if (rpccli_is_connected(conn->lsa_pipe_tcp)) {
2909 goto done;
2912 TALLOC_FREE(conn->lsa_pipe_tcp);
2914 status = cm_get_schannel_creds(domain, &p_creds);
2915 if (!NT_STATUS_IS_OK(status)) {
2916 goto done;
2919 remote_name = smbXcli_conn_remote_name(conn->cli->conn);
2920 remote_sockaddr = smbXcli_conn_remote_sockaddr(conn->cli->conn);
2922 status = winbindd_get_trust_credentials(domain,
2923 talloc_tos(),
2924 true, /* netlogon */
2925 false, /* ipc_fallback */
2926 &cli_creds);
2927 if (!NT_STATUS_IS_OK(status)) {
2928 goto done;
2931 status = cm_connect_schannel_or_krb5(
2932 conn->cli,
2933 &ndr_table_lsarpc,
2934 NCACN_IP_TCP,
2935 cli_creds,
2936 p_creds,
2937 remote_name,
2938 remote_sockaddr,
2939 &conn->lsa_pipe_tcp);
2940 if (!NT_STATUS_IS_OK(status)) {
2941 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key failed: %s\n",
2942 nt_errstr(status)));
2943 goto done;
2946 done:
2947 if (!NT_STATUS_IS_OK(status)) {
2948 TALLOC_FREE(conn->lsa_pipe_tcp);
2949 return status;
2952 *cli = conn->lsa_pipe_tcp;
2954 return status;
2957 NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
2958 struct rpc_pipe_client **cli, struct policy_handle *lsa_policy)
2960 struct winbindd_cm_conn *conn;
2961 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2962 struct netlogon_creds_cli_context *p_creds;
2963 struct cli_credentials *creds = NULL;
2964 bool retry = false; /* allow one retry attempt for expired session */
2965 const char *remote_name = NULL;
2966 const struct sockaddr_storage *remote_sockaddr = NULL;
2967 bool sealed_pipes = true;
2968 bool strong_key = true;
2969 bool require_schannel = false;
2971 retry:
2972 result = init_dc_connection_rpc(domain, false);
2973 if (!NT_STATUS_IS_OK(result))
2974 return result;
2976 conn = &domain->conn;
2978 if (rpccli_is_connected(conn->lsa_pipe)) {
2979 goto done;
2982 TALLOC_FREE(conn->lsa_pipe);
2984 if (IS_DC ||
2985 domain->secure_channel_type != SEC_CHAN_NULL)
2988 * Make sure we only use schannel as DC
2989 * or with a direct trust
2991 require_schannel = true;
2992 goto schannel;
2995 result = winbindd_get_trust_credentials(domain,
2996 talloc_tos(),
2997 false, /* netlogon */
2998 true, /* ipc_fallback */
2999 &creds);
3000 if (!NT_STATUS_IS_OK(result)) {
3001 DEBUG(10, ("cm_connect_lsa: No user available for "
3002 "domain %s, trying schannel\n", domain->name));
3003 goto schannel;
3006 if (cli_credentials_is_anonymous(creds)) {
3007 goto anonymous;
3010 remote_name = smbXcli_conn_remote_name(conn->cli->conn);
3011 remote_sockaddr = smbXcli_conn_remote_sockaddr(conn->cli->conn);
3014 * We have an authenticated connection. Use a SPNEGO
3015 * authenticated LSA pipe with sign & seal.
3017 result = cli_rpc_pipe_open_with_creds
3018 (conn->cli, &ndr_table_lsarpc, NCACN_NP,
3019 DCERPC_AUTH_TYPE_SPNEGO,
3020 conn->auth_level,
3021 NULL, /* target_service */
3022 remote_name,
3023 remote_sockaddr,
3024 creds,
3025 &conn->lsa_pipe);
3027 if (NT_STATUS_EQUAL(result, NT_STATUS_NETWORK_SESSION_EXPIRED)
3028 && !retry) {
3029 invalidate_cm_connection(domain);
3030 retry = true;
3031 goto retry;
3034 if (!NT_STATUS_IS_OK(result)) {
3035 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
3036 "domain %s using NTLMSSP authenticated pipe: user "
3037 "%s. Error was %s. Trying schannel.\n",
3038 domain->name,
3039 cli_credentials_get_unparsed_name(creds, talloc_tos()),
3040 nt_errstr(result)));
3041 goto schannel;
3044 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
3045 "NTLMSSP authenticated pipe: user %s\n",
3046 domain->name, cli_credentials_get_unparsed_name(creds, talloc_tos())));
3048 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
3049 SEC_FLAG_MAXIMUM_ALLOWED,
3050 &conn->lsa_policy);
3051 if (NT_STATUS_EQUAL(result, NT_STATUS_IO_DEVICE_ERROR) && !retry) {
3052 invalidate_cm_connection(domain);
3053 TALLOC_FREE(conn->lsa_pipe);
3054 retry = true;
3055 goto retry;
3058 if (NT_STATUS_IS_OK(result)) {
3059 goto done;
3062 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
3063 "schannel\n"));
3065 TALLOC_FREE(conn->lsa_pipe);
3067 schannel:
3069 /* Fall back to schannel if it's a W2K pre-SP1 box. */
3071 result = cm_get_schannel_creds(domain, &p_creds);
3072 if (!NT_STATUS_IS_OK(result)) {
3073 /* If this call fails - conn->cli can now be NULL ! */
3074 DEBUG(10, ("cm_connect_lsa: Could not get schannel auth info "
3075 "for domain %s (error %s), trying anon\n",
3076 domain->name,
3077 nt_errstr(result) ));
3078 goto anonymous;
3081 TALLOC_FREE(creds);
3082 result = winbindd_get_trust_credentials(domain,
3083 talloc_tos(),
3084 true, /* netlogon */
3085 false, /* ipc_fallback */
3086 &creds);
3087 if (!NT_STATUS_IS_OK(result)) {
3088 goto done;
3091 result = cm_connect_schannel_or_krb5(
3092 conn->cli,
3093 &ndr_table_lsarpc,
3094 NCACN_NP,
3095 creds,
3096 p_creds,
3097 remote_name,
3098 remote_sockaddr,
3099 &conn->lsa_pipe);
3101 if (NT_STATUS_EQUAL(result, NT_STATUS_NETWORK_SESSION_EXPIRED)
3102 && !retry) {
3103 invalidate_cm_connection(domain);
3104 retry = true;
3105 goto retry;
3108 if (!NT_STATUS_IS_OK(result)) {
3109 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
3110 "domain %s using schannel. Error was %s\n",
3111 domain->name, nt_errstr(result) ));
3112 goto anonymous;
3114 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
3115 "schannel.\n", domain->name ));
3117 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
3118 SEC_FLAG_MAXIMUM_ALLOWED,
3119 &conn->lsa_policy);
3121 if (NT_STATUS_EQUAL(result, NT_STATUS_IO_DEVICE_ERROR) && !retry) {
3122 invalidate_cm_connection(domain);
3123 TALLOC_FREE(conn->lsa_pipe);
3124 retry = true;
3125 goto retry;
3128 if (NT_STATUS_IS_OK(result)) {
3129 goto done;
3132 if (require_schannel) {
3134 * Make sure we only use schannel as DC
3135 * or with a direct trust
3137 goto done;
3140 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
3141 "anonymous\n"));
3143 TALLOC_FREE(conn->lsa_pipe);
3145 anonymous:
3147 if (require_schannel) {
3149 * Make sure we only use schannel as DC
3150 * or with a direct trust
3152 goto done;
3155 sealed_pipes = lp_winbind_sealed_pipes();
3156 sealed_pipes = lp_parm_bool(-1, "winbind sealed pipes",
3157 domain->name,
3158 sealed_pipes);
3159 strong_key = lp_require_strong_key();
3160 strong_key = lp_parm_bool(-1, "require strong key",
3161 domain->name,
3162 strong_key);
3164 /* Finally fall back to anonymous. */
3165 if (sealed_pipes || strong_key) {
3166 result = NT_STATUS_DOWNGRADE_DETECTED;
3167 DEBUG(1, ("Unwilling to make LSA connection to domain %s "
3168 "without connection level security, "
3169 "must set 'winbind sealed pipes:%s = false' and "
3170 "'require strong key:%s = false' to proceed: %s\n",
3171 domain->name, domain->name, domain->name,
3172 nt_errstr(result)));
3173 goto done;
3176 result = cli_rpc_pipe_open_noauth(conn->cli,
3177 &ndr_table_lsarpc,
3178 &conn->lsa_pipe);
3180 if (NT_STATUS_EQUAL(result, NT_STATUS_NETWORK_SESSION_EXPIRED)
3181 && !retry) {
3182 invalidate_cm_connection(domain);
3183 retry = true;
3184 goto retry;
3187 if (!NT_STATUS_IS_OK(result)) {
3188 goto done;
3191 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
3192 SEC_FLAG_MAXIMUM_ALLOWED,
3193 &conn->lsa_policy);
3195 if (NT_STATUS_EQUAL(result, NT_STATUS_IO_DEVICE_ERROR) && !retry) {
3196 invalidate_cm_connection(domain);
3197 TALLOC_FREE(conn->lsa_pipe);
3198 retry = true;
3199 goto retry;
3202 done:
3203 if (!NT_STATUS_IS_OK(result)) {
3204 invalidate_cm_connection(domain);
3205 return result;
3208 *cli = conn->lsa_pipe;
3209 *lsa_policy = conn->lsa_policy;
3210 return result;
3213 /****************************************************************************
3214 Open a LSA connection to a DC, suitable for LSA lookup calls.
3215 ****************************************************************************/
3217 NTSTATUS cm_connect_lsat(struct winbindd_domain *domain,
3218 TALLOC_CTX *mem_ctx,
3219 struct rpc_pipe_client **cli,
3220 struct policy_handle *lsa_policy)
3222 NTSTATUS status;
3224 if (domain->can_do_ncacn_ip_tcp) {
3225 status = cm_connect_lsa_tcp(domain, mem_ctx, cli);
3226 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
3227 NT_STATUS_EQUAL(status, NT_STATUS_RPC_SEC_PKG_ERROR) ||
3228 NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
3229 invalidate_cm_connection(domain);
3230 status = cm_connect_lsa_tcp(domain, mem_ctx, cli);
3232 if (NT_STATUS_IS_OK(status)) {
3233 return status;
3237 * we tried twice to connect via ncan_ip_tcp and schannel and
3238 * failed - maybe it is a trusted domain we can't connect to ?
3239 * do not try tcp next time - gd
3241 * This also prevents NETLOGON over TCP
3243 domain->can_do_ncacn_ip_tcp = false;
3246 status = cm_connect_lsa(domain, mem_ctx, cli, lsa_policy);
3248 return status;
3251 /****************************************************************************
3252 Open the netlogon pipe to this DC.
3253 ****************************************************************************/
3255 static NTSTATUS cm_connect_netlogon_transport(struct winbindd_domain *domain,
3256 enum dcerpc_transport_t transport,
3257 struct rpc_pipe_client **cli)
3259 struct messaging_context *msg_ctx = global_messaging_context();
3260 struct winbindd_cm_conn *conn;
3261 NTSTATUS result;
3262 enum netr_SchannelType sec_chan_type;
3263 struct cli_credentials *creds = NULL;
3264 const char *remote_name = NULL;
3265 const struct sockaddr_storage *remote_sockaddr = NULL;
3267 *cli = NULL;
3269 if (IS_DC) {
3270 if (domain->secure_channel_type == SEC_CHAN_NULL) {
3272 * Make sure we don't even try to
3273 * connect to a foreign domain
3274 * without a direct outbound trust.
3276 return NT_STATUS_NO_TRUST_LSA_SECRET;
3280 result = init_dc_connection_rpc(domain, domain->rodc);
3281 if (!NT_STATUS_IS_OK(result)) {
3282 return result;
3285 conn = &domain->conn;
3287 if (rpccli_is_connected(conn->netlogon_pipe)) {
3288 *cli = conn->netlogon_pipe;
3289 return NT_STATUS_OK;
3292 TALLOC_FREE(conn->netlogon_pipe);
3293 TALLOC_FREE(conn->netlogon_creds_ctx);
3295 remote_name = smbXcli_conn_remote_name(conn->cli->conn);
3296 remote_sockaddr = smbXcli_conn_remote_sockaddr(conn->cli->conn);
3298 result = winbindd_get_trust_credentials(domain,
3299 talloc_tos(),
3300 true, /* netlogon */
3301 false, /* ipc_fallback */
3302 &creds);
3303 if (!NT_STATUS_IS_OK(result)) {
3304 DBG_DEBUG("No user available for domain %s when trying "
3305 "schannel\n", domain->name);
3306 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3309 if (cli_credentials_is_anonymous(creds)) {
3310 DBG_WARNING("get_trust_credential only gave anonymous for %s, "
3311 "unable to make get NETLOGON credentials\n",
3312 domain->name);
3313 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3316 sec_chan_type = cli_credentials_get_secure_channel_type(creds);
3317 if (sec_chan_type == SEC_CHAN_NULL) {
3318 if (transport == NCACN_IP_TCP) {
3319 DBG_NOTICE("get_secure_channel_type gave SEC_CHAN_NULL "
3320 "for %s, deny NCACN_IP_TCP and let the "
3321 "caller fallback to NCACN_NP.\n",
3322 domain->name);
3323 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3326 DBG_NOTICE("get_secure_channel_type gave SEC_CHAN_NULL for %s, "
3327 "fallback to noauth on NCACN_NP.\n",
3328 domain->name);
3330 result = cli_rpc_pipe_open_noauth_transport(
3331 conn->cli,
3332 transport,
3333 &ndr_table_netlogon,
3334 remote_name,
3335 remote_sockaddr,
3336 &conn->netlogon_pipe);
3337 if (!NT_STATUS_IS_OK(result)) {
3338 invalidate_cm_connection(domain);
3339 return result;
3342 *cli = conn->netlogon_pipe;
3343 return NT_STATUS_OK;
3346 result = rpccli_create_netlogon_creds_ctx(creds,
3347 domain->dcname,
3348 msg_ctx,
3349 domain,
3350 &conn->netlogon_creds_ctx);
3351 if (!NT_STATUS_IS_OK(result)) {
3352 DEBUG(1, ("rpccli_create_netlogon_creds failed for %s, "
3353 "unable to create NETLOGON credentials: %s\n",
3354 domain->name, nt_errstr(result)));
3355 return result;
3358 result = rpccli_connect_netlogon(conn->cli,
3359 transport,
3360 remote_name,
3361 remote_sockaddr,
3362 conn->netlogon_creds_ctx,
3363 conn->netlogon_force_reauth, creds,
3364 &conn->netlogon_pipe);
3365 conn->netlogon_force_reauth = false;
3366 if (!NT_STATUS_IS_OK(result)) {
3367 DBG_DEBUG("rpccli_connect_netlogon failed: %s\n",
3368 nt_errstr(result));
3369 return result;
3372 *cli = conn->netlogon_pipe;
3373 return NT_STATUS_OK;
3376 /****************************************************************************
3377 Open a NETLOGON connection to a DC, suitable for SamLogon calls.
3378 ****************************************************************************/
3380 NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
3381 struct rpc_pipe_client **cli)
3383 NTSTATUS status;
3385 status = init_dc_connection_rpc(domain, domain->rodc);
3386 if (!NT_STATUS_IS_OK(status)) {
3387 return status;
3390 if (domain->active_directory && domain->can_do_ncacn_ip_tcp) {
3391 status = cm_connect_netlogon_transport(domain, NCACN_IP_TCP, cli);
3392 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
3393 NT_STATUS_EQUAL(status, NT_STATUS_RPC_SEC_PKG_ERROR) ||
3394 NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
3395 invalidate_cm_connection(domain);
3396 status = cm_connect_netlogon_transport(domain, NCACN_IP_TCP, cli);
3398 if (NT_STATUS_IS_OK(status)) {
3399 return status;
3403 * we tried twice to connect via ncan_ip_tcp and schannel and
3404 * failed - maybe it is a trusted domain we can't connect to ?
3405 * do not try tcp next time - gd
3407 * This also prevents LSA over TCP
3409 domain->can_do_ncacn_ip_tcp = false;
3412 status = cm_connect_netlogon_transport(domain, NCACN_NP, cli);
3413 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
3415 * SMB2 session expired, needs reauthentication. Drop
3416 * connection and retry.
3418 invalidate_cm_connection(domain);
3419 status = cm_connect_netlogon_transport(domain, NCACN_NP, cli);
3422 return status;
3425 NTSTATUS cm_connect_netlogon_secure(struct winbindd_domain *domain,
3426 struct rpc_pipe_client **cli,
3427 struct netlogon_creds_cli_context **ppdc)
3429 NTSTATUS status;
3431 if (domain->secure_channel_type == SEC_CHAN_NULL) {
3432 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3435 status = cm_connect_netlogon(domain, cli);
3436 if (!NT_STATUS_IS_OK(status)) {
3437 return status;
3440 if (domain->conn.netlogon_creds_ctx == NULL) {
3441 return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
3444 *ppdc = domain->conn.netlogon_creds_ctx;
3445 return NT_STATUS_OK;
3448 void winbind_msg_ip_dropped(struct messaging_context *msg_ctx,
3449 void *private_data,
3450 uint32_t msg_type,
3451 struct server_id server_id,
3452 DATA_BLOB *data)
3454 struct winbindd_domain *domain;
3455 char *freeit = NULL;
3456 char *addr;
3458 if ((data == NULL)
3459 || (data->data == NULL)
3460 || (data->length == 0)
3461 || (data->data[data->length-1] != '\0')) {
3462 DEBUG(1, ("invalid msg_ip_dropped message: not a valid "
3463 "string\n"));
3464 return;
3467 addr = (char *)data->data;
3468 DEBUG(10, ("IP %s dropped\n", addr));
3470 if (!is_ipaddress(addr)) {
3471 char *slash;
3473 * Some code sends us ip addresses with the /netmask
3474 * suffix
3476 slash = strchr(addr, '/');
3477 if (slash == NULL) {
3478 DEBUG(1, ("invalid msg_ip_dropped message: %s\n",
3479 addr));
3480 return;
3482 freeit = talloc_strndup(talloc_tos(), addr, slash-addr);
3483 if (freeit == NULL) {
3484 DEBUG(1, ("talloc failed\n"));
3485 return;
3487 addr = freeit;
3488 DEBUG(10, ("Stripped /netmask to IP %s\n", addr));
3491 for (domain = domain_list(); domain != NULL; domain = domain->next) {
3492 char sockaddr[INET6_ADDRSTRLEN];
3494 if (!cli_state_is_connected(domain->conn.cli)) {
3495 continue;
3498 print_sockaddr(sockaddr, sizeof(sockaddr),
3499 smbXcli_conn_local_sockaddr(domain->conn.cli->conn));
3501 if (strequal(sockaddr, addr)) {
3502 smbXcli_conn_disconnect(domain->conn.cli->conn, NT_STATUS_OK);
3505 TALLOC_FREE(freeit);
3508 void winbind_msg_disconnect_dc(struct messaging_context *msg_ctx,
3509 void *private_data,
3510 uint32_t msg_type,
3511 struct server_id server_id,
3512 DATA_BLOB *data)
3514 struct winbindd_domain *domain;
3516 for (domain = domain_list(); domain; domain = domain->next) {
3517 if (domain->internal) {
3518 continue;
3520 invalidate_cm_connection(domain);