2 Unix SMB/CIFS implementation.
4 Winbind daemon connection manager
6 Copyright (C) Tim Potter 2001
7 Copyright (C) Andrew Bartlett 2002
8 Copyright (C) Gerald (Jerry) Carter 2003-2005.
9 Copyright (C) Volker Lendecke 2004-2005
10 Copyright (C) Jeremy Allison 2006
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 3 of the License, or
15 (at your option) any later version.
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program. If not, see <http://www.gnu.org/licenses/>.
27 We need to manage connections to domain controllers without having to
28 mess up the main winbindd code with other issues. The aim of the
29 connection manager is to:
31 - make connections to domain controllers and cache them
32 - re-establish connections when networks or servers go down
33 - centralise the policy on connection timeouts, domain controller
35 - manage re-entrancy for when winbindd becomes able to handle
36 multiple outstanding rpc requests
38 Why not have connection management as part of the rpc layer like tng?
39 Good question. This code may morph into libsmb/rpc_cache.c or something
40 like that but at the moment it's simply staying as part of winbind. I
41 think the TNG architecture of forcing every user of the rpc layer to use
42 the connection caching system is a bad idea. It should be an optional
43 method of using the routines.
45 The TNG design is quite good but I disagree with some aspects of the
53 - I'm pretty annoyed by all the make_nmb_name() stuff. It should be
54 moved down into another function.
56 - Take care when destroying cli_structs as they can be shared between
63 #include "../libcli/auth/libcli_auth.h"
64 #include "../librpc/gen_ndr/ndr_netlogon_c.h"
65 #include "rpc_client/cli_pipe.h"
66 #include "rpc_client/cli_netlogon.h"
67 #include "../librpc/gen_ndr/ndr_samr_c.h"
68 #include "../librpc/gen_ndr/ndr_lsa_c.h"
69 #include "rpc_client/cli_lsarpc.h"
70 #include "../librpc/gen_ndr/ndr_dssetup_c.h"
71 #include "libads/sitename_cache.h"
72 #include "libsmb/libsmb.h"
73 #include "libsmb/clidgram.h"
76 #include "../libcli/security/security.h"
79 #include "auth/gensec/gensec.h"
80 #include "../libcli/smb/smbXcli_base.h"
81 #include "libcli/auth/netlogon_creds_cli.h"
83 #include "rpc_server/rpc_ncacn_np.h"
84 #include "auth/credentials/credentials.h"
85 #include "lib/param/param.h"
88 #define DBGC_CLASS DBGC_WINBIND
92 struct sockaddr_storage ss;
95 extern struct winbindd_methods reconnect_methods;
96 extern bool override_logfile;
98 static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain, bool need_rw_dc);
99 static void set_dc_type_and_flags( struct winbindd_domain *domain );
100 static bool set_dc_type_and_flags_trustinfo( struct winbindd_domain *domain );
101 static bool get_dcs(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
102 struct dc_name_ip **dcs, int *num_dcs,
103 uint32_t request_flags);
105 /****************************************************************
106 Child failed to find DC's. Reschedule check.
107 ****************************************************************/
109 static void msg_failed_to_go_online(struct messaging_context *msg,
112 struct server_id server_id,
115 struct winbindd_domain *domain;
116 const char *domainname = (const char *)data->data;
118 if (data->data == NULL || data->length == 0) {
122 DEBUG(5,("msg_fail_to_go_online: received for domain %s.\n", domainname));
124 for (domain = domain_list(); domain; domain = domain->next) {
125 if (domain->internal) {
129 if (strequal(domain->name, domainname)) {
130 if (domain->online) {
131 /* We're already online, ignore. */
132 DEBUG(5,("msg_fail_to_go_online: domain %s "
133 "already online.\n", domainname));
137 /* Reschedule the online check. */
138 set_domain_offline(domain);
144 /****************************************************************
145 Actually cause a reconnect from a message.
146 ****************************************************************/
148 static void msg_try_to_go_online(struct messaging_context *msg,
151 struct server_id server_id,
154 struct winbindd_domain *domain;
155 const char *domainname = (const char *)data->data;
157 if (data->data == NULL || data->length == 0) {
161 DEBUG(5,("msg_try_to_go_online: received for domain %s.\n", domainname));
163 for (domain = domain_list(); domain; domain = domain->next) {
164 if (domain->internal) {
168 if (strequal(domain->name, domainname)) {
170 if (domain->online) {
171 /* We're already online, ignore. */
172 DEBUG(5,("msg_try_to_go_online: domain %s "
173 "already online.\n", domainname));
177 /* This call takes care of setting the online
178 flag to true if we connected, or re-adding
179 the offline handler if false. Bypasses online
180 check so always does network calls. */
182 init_dc_connection_network(domain, true);
188 /****************************************************************
189 Fork a child to try and contact a DC. Do this as contacting a
190 DC requires blocking lookups and we don't want to block our
192 ****************************************************************/
194 static bool fork_child_dc_connect(struct winbindd_domain *domain)
196 struct dc_name_ip *dcs = NULL;
198 TALLOC_CTX *mem_ctx = NULL;
199 pid_t parent_pid = getpid();
203 if (domain->dc_probe_pid != (pid_t)-1) {
205 * We might already have a DC probe
206 * child working, check.
208 if (process_exists_by_pid(domain->dc_probe_pid)) {
209 DEBUG(10,("fork_child_dc_connect: pid %u already "
210 "checking for DC's.\n",
211 (unsigned int)domain->dc_probe_pid));
214 domain->dc_probe_pid = (pid_t)-1;
217 domain->dc_probe_pid = fork();
219 if (domain->dc_probe_pid == (pid_t)-1) {
220 DEBUG(0, ("fork_child_dc_connect: Could not fork: %s\n", strerror(errno)));
224 if (domain->dc_probe_pid != (pid_t)0) {
226 messaging_register(winbind_messaging_context(), NULL,
227 MSG_WINBIND_TRY_TO_GO_ONLINE,
228 msg_try_to_go_online);
229 messaging_register(winbind_messaging_context(), NULL,
230 MSG_WINBIND_FAILED_TO_GO_ONLINE,
231 msg_failed_to_go_online);
237 /* Leave messages blocked - we will never process one. */
239 if (!override_logfile) {
240 if (asprintf(&lfile, "%s/log.winbindd-dc-connect", get_dyn_LOGFILEBASE()) == -1) {
241 DEBUG(0, ("fork_child_dc_connect: out of memory.\n"));
246 status = winbindd_reinit_after_fork(NULL, lfile);
247 if (!NT_STATUS_IS_OK(status)) {
248 DEBUG(1, ("winbindd_reinit_after_fork failed: %s\n",
250 messaging_send_buf(winbind_messaging_context(),
251 pid_to_procid(parent_pid),
252 MSG_WINBIND_FAILED_TO_GO_ONLINE,
253 (const uint8_t *)domain->name,
254 strlen(domain->name)+1);
259 mem_ctx = talloc_init("fork_child_dc_connect");
261 DEBUG(0,("talloc_init failed.\n"));
262 messaging_send_buf(winbind_messaging_context(),
263 pid_to_procid(parent_pid),
264 MSG_WINBIND_FAILED_TO_GO_ONLINE,
265 (const uint8_t *)domain->name,
266 strlen(domain->name)+1);
270 if ((!get_dcs(mem_ctx, domain, &dcs, &num_dcs, 0)) || (num_dcs == 0)) {
271 /* Still offline ? Can't find DC's. */
272 messaging_send_buf(winbind_messaging_context(),
273 pid_to_procid(parent_pid),
274 MSG_WINBIND_FAILED_TO_GO_ONLINE,
275 (const uint8_t *)domain->name,
276 strlen(domain->name)+1);
280 /* We got a DC. Send a message to our parent to get it to
281 try and do the same. */
283 messaging_send_buf(winbind_messaging_context(),
284 pid_to_procid(parent_pid),
285 MSG_WINBIND_TRY_TO_GO_ONLINE,
286 (const uint8_t *)domain->name,
287 strlen(domain->name)+1);
291 /****************************************************************
292 Handler triggered if we're offline to try and detect a DC.
293 ****************************************************************/
295 static void check_domain_online_handler(struct tevent_context *ctx,
296 struct tevent_timer *te,
300 struct winbindd_domain *domain =
301 (struct winbindd_domain *)private_data;
303 DEBUG(10,("check_domain_online_handler: called for domain "
304 "%s (online = %s)\n", domain->name,
305 domain->online ? "True" : "False" ));
307 TALLOC_FREE(domain->check_online_event);
309 /* Are we still in "startup" mode ? */
311 if (domain->startup && (time_mono(NULL) > domain->startup_time + 30)) {
312 /* No longer in "startup" mode. */
313 DEBUG(10,("check_domain_online_handler: domain %s no longer in 'startup' mode.\n",
315 domain->startup = False;
318 /* We've been told to stay offline, so stay
321 if (get_global_winbindd_state_offline()) {
322 DEBUG(10,("check_domain_online_handler: domain %s remaining globally offline\n",
327 /* Fork a child to test if it can contact a DC.
328 If it can then send ourselves a message to
329 cause a reconnect. */
331 fork_child_dc_connect(domain);
334 /****************************************************************
335 If we're still offline setup the timeout check.
336 ****************************************************************/
338 static void calc_new_online_timeout_check(struct winbindd_domain *domain)
340 int wbr = lp_winbind_reconnect_delay();
342 if (domain->startup) {
343 domain->check_online_timeout = 10;
344 } else if (domain->check_online_timeout < wbr) {
345 domain->check_online_timeout = wbr;
349 void winbind_msg_domain_offline(struct messaging_context *msg_ctx,
352 struct server_id server_id,
355 const char *domain_name = (const char *)data->data;
356 struct winbindd_domain *domain;
358 domain = find_domain_from_name_noinit(domain_name);
359 if (domain == NULL) {
363 domain->online = false;
365 DEBUG(10, ("Domain %s is marked as offline now.\n",
369 void winbind_msg_domain_online(struct messaging_context *msg_ctx,
372 struct server_id server_id,
375 const char *domain_name = (const char *)data->data;
376 struct winbindd_domain *domain;
378 domain = find_domain_from_name_noinit(domain_name);
379 if (domain == NULL) {
383 domain->online = true;
385 DEBUG(10, ("Domain %s is marked as online now.\n",
389 /****************************************************************
390 Set domain offline and also add handler to put us back online
392 ****************************************************************/
394 void set_domain_offline(struct winbindd_domain *domain)
396 pid_t parent_pid = getppid();
398 DEBUG(10,("set_domain_offline: called for domain %s\n",
401 TALLOC_FREE(domain->check_online_event);
403 if (domain->internal) {
404 DEBUG(3,("set_domain_offline: domain %s is internal - logic error.\n",
409 domain->online = False;
411 /* Offline domains are always initialized. They're
412 re-initialized when they go back online. */
414 domain->initialized = True;
416 /* We only add the timeout handler that checks and
417 allows us to go back online when we've not
418 been told to remain offline. */
420 if (get_global_winbindd_state_offline()) {
421 DEBUG(10,("set_domain_offline: domain %s remaining globally offline\n",
426 /* If we're in startup mode, check again in 10 seconds, not in
427 lp_winbind_reconnect_delay() seconds (which is 30 seconds by default). */
429 calc_new_online_timeout_check(domain);
431 domain->check_online_event = tevent_add_timer(winbind_event_context(),
433 timeval_current_ofs(domain->check_online_timeout,0),
434 check_domain_online_handler,
437 /* The above *has* to succeed for winbindd to work. */
438 if (!domain->check_online_event) {
439 smb_panic("set_domain_offline: failed to add online handler");
442 DEBUG(10,("set_domain_offline: added event handler for domain %s\n",
445 /* Send a message to the parent that the domain is offline. */
446 if (parent_pid > 1 && !domain->internal) {
447 messaging_send_buf(winbind_messaging_context(),
448 pid_to_procid(parent_pid),
449 MSG_WINBIND_DOMAIN_OFFLINE,
450 (uint8_t *)domain->name,
451 strlen(domain->name) + 1);
454 /* Send an offline message to the idmap child when our
455 primary domain goes offline */
457 if ( domain->primary ) {
458 struct winbindd_child *idmap = idmap_child();
460 if ( idmap->pid != 0 ) {
461 messaging_send_buf(winbind_messaging_context(),
462 pid_to_procid(idmap->pid),
464 (const uint8_t *)domain->name,
465 strlen(domain->name)+1);
472 /****************************************************************
473 Set domain online - if allowed.
474 ****************************************************************/
476 static void set_domain_online(struct winbindd_domain *domain)
478 pid_t parent_pid = getppid();
480 DEBUG(10,("set_domain_online: called for domain %s\n",
483 if (domain->internal) {
484 DEBUG(3,("set_domain_online: domain %s is internal - logic error.\n",
489 if (get_global_winbindd_state_offline()) {
490 DEBUG(10,("set_domain_online: domain %s remaining globally offline\n",
495 winbindd_set_locator_kdc_envs(domain);
497 /* If we are waiting to get a krb5 ticket, trigger immediately. */
498 ccache_regain_all_now();
500 /* Ok, we're out of any startup mode now... */
501 domain->startup = False;
503 if (domain->online == False) {
504 /* We were offline - now we're online. We default to
505 using the MS-RPC backend if we started offline,
506 and if we're going online for the first time we
507 should really re-initialize the backends and the
508 checks to see if we're talking to an AD or NT domain.
511 domain->initialized = False;
513 /* 'reconnect_methods' is the MS-RPC backend. */
514 if (domain->backend == &reconnect_methods) {
515 domain->backend = NULL;
519 /* Ensure we have no online timeout checks. */
520 domain->check_online_timeout = 0;
521 TALLOC_FREE(domain->check_online_event);
523 /* Ensure we ignore any pending child messages. */
524 messaging_deregister(winbind_messaging_context(),
525 MSG_WINBIND_TRY_TO_GO_ONLINE, NULL);
526 messaging_deregister(winbind_messaging_context(),
527 MSG_WINBIND_FAILED_TO_GO_ONLINE, NULL);
529 domain->online = True;
531 /* Send a message to the parent that the domain is online. */
532 if (parent_pid > 1 && !domain->internal) {
533 messaging_send_buf(winbind_messaging_context(),
534 pid_to_procid(parent_pid),
535 MSG_WINBIND_DOMAIN_ONLINE,
536 (uint8_t *)domain->name,
537 strlen(domain->name) + 1);
540 /* Send an online message to the idmap child when our
541 primary domain comes online */
543 if ( domain->primary ) {
544 struct winbindd_child *idmap = idmap_child();
546 if ( idmap->pid != 0 ) {
547 messaging_send_buf(winbind_messaging_context(),
548 pid_to_procid(idmap->pid),
550 (const uint8_t *)domain->name,
551 strlen(domain->name)+1);
558 /****************************************************************
559 Requested to set a domain online.
560 ****************************************************************/
562 void set_domain_online_request(struct winbindd_domain *domain)
566 DEBUG(10,("set_domain_online_request: called for domain %s\n",
569 if (get_global_winbindd_state_offline()) {
570 DEBUG(10,("set_domain_online_request: domain %s remaining globally offline\n",
575 if (domain->internal) {
576 DEBUG(10, ("set_domain_online_request: Internal domains are "
581 /* We've been told it's safe to go online and
582 try and connect to a DC. But I don't believe it
583 because network manager seems to lie.
584 Wait at least 5 seconds. Heuristics suck... */
589 /* Go into "startup" mode again. */
590 domain->startup_time = time_mono(NULL);
591 domain->startup = True;
595 if (!domain->check_online_event) {
596 /* If we've come from being globally offline we
597 don't have a check online event handler set.
598 We need to add one now we're trying to go
601 DEBUG(10,("set_domain_online_request: domain %s was globally offline.\n",
605 TALLOC_FREE(domain->check_online_event);
607 domain->check_online_event = tevent_add_timer(winbind_event_context(),
610 check_domain_online_handler,
613 /* The above *has* to succeed for winbindd to work. */
614 if (!domain->check_online_event) {
615 smb_panic("set_domain_online_request: failed to add online handler");
619 /****************************************************************
620 Add -ve connection cache entries for domain and realm.
621 ****************************************************************/
623 static void winbind_add_failed_connection_entry(
624 const struct winbindd_domain *domain,
628 add_failed_connection_entry(domain->name, server, result);
629 /* If this was the saf name for the last thing we talked to,
631 saf_delete(domain->name);
632 if (domain->alt_name != NULL) {
633 add_failed_connection_entry(domain->alt_name, server, result);
634 saf_delete(domain->alt_name);
636 winbindd_unset_locator_kdc_env(domain);
639 /* Choose between anonymous or authenticated connections. We need to use
640 an authenticated connection if DCs have the RestrictAnonymous registry
641 entry set > 0, or the "Additional restrictions for anonymous
642 connections" set in the win2k Local Security Policy.
644 Caller to free() result in domain, username, password
647 static void cm_get_ipc_userpass(char **username, char **domain, char **password)
649 *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
650 *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
651 *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
653 if (*username && **username) {
655 if (!*domain || !**domain)
656 *domain = smb_xstrdup(lp_workgroup());
658 if (!*password || !**password)
659 *password = smb_xstrdup("");
661 DEBUG(3, ("cm_get_ipc_userpass: Retrieved auth-user from secrets.tdb [%s\\%s]\n",
662 *domain, *username));
665 DEBUG(3, ("cm_get_ipc_userpass: No auth-user defined\n"));
666 *username = smb_xstrdup("");
667 *domain = smb_xstrdup("");
668 *password = smb_xstrdup("");
672 static NTSTATUS cm_get_ipc_credentials(TALLOC_CTX *mem_ctx,
673 struct cli_credentials **_creds)
676 TALLOC_CTX *frame = talloc_stackframe();
677 NTSTATUS status = NT_STATUS_INTERNAL_ERROR;
678 struct loadparm_context *lp_ctx;
679 char *username = NULL;
680 char *netbios_domain = NULL;
681 char *password = NULL;
682 struct cli_credentials *creds = NULL;
685 cm_get_ipc_userpass(&username, &netbios_domain, &password);
687 lp_ctx = loadparm_init_s3(frame, loadparm_s3_helpers());
688 if (lp_ctx == NULL) {
689 DEBUG(1, ("loadparm_init_s3 failed\n"));
690 status = NT_STATUS_INTERNAL_ERROR;
694 creds = cli_credentials_init(mem_ctx);
696 status = NT_STATUS_NO_MEMORY;
700 cli_credentials_set_conf(creds, lp_ctx);
701 cli_credentials_set_kerberos_state(creds, CRED_DONT_USE_KERBEROS);
703 ok = cli_credentials_set_domain(creds, netbios_domain, CRED_SPECIFIED);
705 status = NT_STATUS_NO_MEMORY;
709 ok = cli_credentials_set_username(creds, username, CRED_SPECIFIED);
711 status = NT_STATUS_NO_MEMORY;
715 ok = cli_credentials_set_password(creds, password, CRED_SPECIFIED);
717 status = NT_STATUS_NO_MEMORY;
723 status = NT_STATUS_OK;
727 SAFE_FREE(netbios_domain);
733 static bool cm_is_ipc_credentials(struct cli_credentials *creds)
735 TALLOC_CTX *frame = talloc_stackframe();
736 char *ipc_account = NULL;
737 char *ipc_domain = NULL;
738 char *ipc_password = NULL;
739 const char *creds_account = NULL;
740 const char *creds_domain = NULL;
741 const char *creds_password = NULL;
744 cm_get_ipc_userpass(&ipc_account, &ipc_domain, &ipc_password);
746 creds_account = cli_credentials_get_username(creds);
747 creds_domain = cli_credentials_get_domain(creds);
748 creds_password = cli_credentials_get_password(creds);
750 if (!strequal(ipc_domain, creds_domain)) {
754 if (!strequal(ipc_account, creds_account)) {
758 if (!strcsequal(ipc_password, creds_password)) {
764 SAFE_FREE(ipc_account);
765 SAFE_FREE(ipc_domain);
766 SAFE_FREE(ipc_password);
771 static bool get_dc_name_via_netlogon(struct winbindd_domain *domain,
773 struct sockaddr_storage *dc_ss,
774 uint32_t request_flags)
776 struct winbindd_domain *our_domain = NULL;
777 struct rpc_pipe_client *netlogon_pipe = NULL;
781 unsigned int orig_timeout;
782 const char *tmp = NULL;
784 struct dcerpc_binding_handle *b;
786 /* Hmmmm. We can only open one connection to the NETLOGON pipe at the
793 if (domain->primary) {
797 our_domain = find_our_domain();
799 if ((mem_ctx = talloc_init("get_dc_name_via_netlogon")) == NULL) {
803 result = cm_connect_netlogon(our_domain, &netlogon_pipe);
804 if (!NT_STATUS_IS_OK(result)) {
805 talloc_destroy(mem_ctx);
809 b = netlogon_pipe->binding_handle;
811 /* This call can take a long time - allow the server to time out.
812 35 seconds should do it. */
814 orig_timeout = rpccli_set_timeout(netlogon_pipe, 35000);
816 if (our_domain->active_directory) {
817 struct netr_DsRGetDCNameInfo *domain_info = NULL;
820 * TODO request flags are not respected in the server
821 * (and in some cases, like REQUIRE_PDC, causes an error)
823 result = dcerpc_netr_DsRGetDCName(b,
829 request_flags|DS_RETURN_DNS_NAME,
832 if (NT_STATUS_IS_OK(result) && W_ERROR_IS_OK(werr)) {
834 mem_ctx, domain_info->dc_unc);
836 DEBUG(0, ("talloc_strdup failed\n"));
837 talloc_destroy(mem_ctx);
840 if (domain->alt_name == NULL) {
841 domain->alt_name = talloc_strdup(domain,
842 domain_info->domain_name);
843 if (domain->alt_name == NULL) {
844 DEBUG(0, ("talloc_strdup failed\n"));
845 talloc_destroy(mem_ctx);
849 if (domain->forest_name == NULL) {
850 domain->forest_name = talloc_strdup(domain,
851 domain_info->forest_name);
852 if (domain->forest_name == NULL) {
853 DEBUG(0, ("talloc_strdup failed\n"));
854 talloc_destroy(mem_ctx);
860 result = dcerpc_netr_GetAnyDCName(b, mem_ctx,
867 /* And restore our original timeout. */
868 rpccli_set_timeout(netlogon_pipe, orig_timeout);
870 if (!NT_STATUS_IS_OK(result)) {
871 DEBUG(10,("dcerpc_netr_GetAnyDCName failed: %s\n",
873 talloc_destroy(mem_ctx);
877 if (!W_ERROR_IS_OK(werr)) {
878 DEBUG(10,("dcerpc_netr_GetAnyDCName failed: %s\n",
880 talloc_destroy(mem_ctx);
884 /* dcerpc_netr_GetAnyDCName gives us a name with \\ */
885 p = strip_hostname(tmp);
889 talloc_destroy(mem_ctx);
891 DEBUG(10,("dcerpc_netr_GetAnyDCName returned %s\n", dcname));
893 if (!resolve_name(dcname, dc_ss, 0x20, true)) {
901 * Helper function to assemble trust password and account name
903 static NTSTATUS get_trust_credentials(struct winbindd_domain *domain,
906 struct cli_credentials **_creds)
908 const struct winbindd_domain *creds_domain = NULL;
909 struct cli_credentials *creds;
911 bool force_machine_account = false;
913 /* If we are a DC and this is not our own domain */
915 if (!domain->active_directory) {
918 * For non active directory domains
919 * we can only use NTLMSSP for SMB.
921 * But the trust account is not allowed
922 * to use SMB with NTLMSSP.
924 force_machine_account = true;
928 if (IS_DC && !force_machine_account) {
929 creds_domain = domain;
931 creds_domain = find_our_domain();
932 if (creds_domain == NULL) {
933 return NT_STATUS_INVALID_SERVER_STATE;
937 status = pdb_get_trust_credentials(creds_domain->name,
938 creds_domain->alt_name,
941 if (!NT_STATUS_IS_OK(status)) {
945 if (creds_domain != domain) {
947 * We can only use schannel against a direct trust
949 cli_credentials_set_secure_channel_type(creds,
958 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
961 status = cm_get_ipc_credentials(mem_ctx, &creds);
962 if (!NT_STATUS_IS_OK(status)) {
970 /************************************************************************
971 Given a fd with a just-connected TCP connection to a DC, open a connection
973 ************************************************************************/
975 static NTSTATUS cm_prepare_connection(struct winbindd_domain *domain,
977 const char *controller,
978 struct cli_state **cli,
981 bool try_ipc_auth = false;
982 const char *machine_principal = NULL;
983 const char *machine_realm = NULL;
984 const char *machine_account = NULL;
985 const char *machine_domain = NULL;
987 struct cli_credentials *creds = NULL;
989 struct named_mutex *mutex;
991 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
993 NTSTATUS tcon_status = NT_STATUS_NETWORK_NAME_DELETED;
995 enum smb_signing_setting smb_sign_client_connections = lp_client_ipc_signing();
997 if (smb_sign_client_connections == SMB_SIGNING_DEFAULT) {
999 * If we are connecting to our own AD domain, require
1000 * smb signing to disrupt MITM attacks
1002 if (domain->primary && lp_security() == SEC_ADS) {
1003 smb_sign_client_connections = SMB_SIGNING_REQUIRED;
1005 * If we are in or are an AD domain and connecting to another
1006 * AD domain in our forest
1007 * then require smb signing to disrupt MITM attacks
1009 } else if ((lp_security() == SEC_ADS ||
1010 lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC)
1011 && domain->active_directory
1012 && (domain->domain_trust_attribs
1013 & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST)) {
1014 smb_sign_client_connections = SMB_SIGNING_REQUIRED;
1018 DEBUG(10,("cm_prepare_connection: connecting to DC %s for domain %s\n",
1019 controller, domain->name ));
1023 mutex = grab_named_mutex(talloc_tos(), controller,
1024 WINBIND_SERVER_MUTEX_WAIT_TIME);
1025 if (mutex == NULL) {
1027 DEBUG(0,("cm_prepare_connection: mutex grab failed for %s\n",
1029 result = NT_STATUS_POSSIBLE_DEADLOCK;
1033 *cli = cli_state_create(NULL, sockfd,
1034 controller, domain->alt_name,
1035 smb_sign_client_connections, flags);
1038 DEBUG(1, ("Could not cli_initialize\n"));
1039 result = NT_STATUS_NO_MEMORY;
1043 cli_set_timeout(*cli, 10000); /* 10 seconds */
1045 set_socket_options(sockfd, lp_socket_options());
1047 result = smbXcli_negprot((*cli)->conn, (*cli)->timeout,
1048 lp_client_ipc_min_protocol(),
1049 lp_client_ipc_max_protocol());
1051 if (!NT_STATUS_IS_OK(result)) {
1052 DEBUG(1, ("cli_negprot failed: %s\n", nt_errstr(result)));
1056 if (smbXcli_conn_protocol((*cli)->conn) >= PROTOCOL_NT1 &&
1057 smb1cli_conn_capabilities((*cli)->conn) & CAP_EXTENDED_SECURITY) {
1058 try_ipc_auth = true;
1059 } else if (smbXcli_conn_protocol((*cli)->conn) >= PROTOCOL_SMB2_02) {
1060 try_ipc_auth = true;
1061 } else if (smb_sign_client_connections == SMB_SIGNING_REQUIRED) {
1063 * If we are forcing on SMB signing, then we must
1064 * require authentication unless this is a one-way
1065 * trust, and we have no stored user/password
1067 try_ipc_auth = true;
1071 result = get_trust_credentials(domain, talloc_tos(), false, &creds);
1072 if (!NT_STATUS_IS_OK(result)) {
1073 DEBUG(1, ("get_trust_credentials(%s) failed: %s\n",
1074 domain->name, nt_errstr(result)));
1079 * Without SPNEGO or NTLMSSP (perhaps via SMB2) we
1080 * would try and authentication with our machine
1081 * account password and fail. This is very rare in
1082 * the modern world however
1084 creds = cli_credentials_init_anon(talloc_tos());
1085 if (creds == NULL) {
1086 result = NT_STATUS_NO_MEMORY;
1087 DEBUG(1, ("cli_credentials_init_anon(%s) failed: %s\n",
1088 domain->name, nt_errstr(result)));
1093 machine_principal = cli_credentials_get_principal(creds,
1095 machine_realm = cli_credentials_get_realm(creds);
1096 machine_account = cli_credentials_get_username(creds);
1097 machine_domain = cli_credentials_get_domain(creds);
1099 DEBUG(5, ("connecting to %s (%s, %s) with account [%s\\%s] principal "
1100 "[%s] and realm [%s]\n",
1101 controller, domain->name, domain->alt_name,
1102 machine_domain, machine_account,
1103 machine_principal, machine_realm));
1105 if (cli_credentials_is_anonymous(creds)) {
1109 winbindd_set_locator_kdc_envs(domain);
1111 result = cli_session_setup_creds(*cli, creds);
1112 if (NT_STATUS_IS_OK(result)) {
1113 goto session_setup_done;
1116 DEBUG(1, ("authenticated session setup to %s using %s failed with %s\n",
1118 cli_credentials_get_unparsed_name(creds, talloc_tos()),
1119 nt_errstr(result)));
1122 * If we are not going to validiate the conneciton
1123 * with SMB signing, then allow us to fall back to
1126 if (NT_STATUS_EQUAL(result, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT)
1127 || NT_STATUS_EQUAL(result, NT_STATUS_TRUSTED_DOMAIN_FAILURE)
1128 || NT_STATUS_EQUAL(result, NT_STATUS_INVALID_ACCOUNT_NAME)
1129 || NT_STATUS_EQUAL(result, NT_STATUS_NO_LOGON_SERVERS)
1130 || NT_STATUS_EQUAL(result, NT_STATUS_LOGON_FAILURE))
1132 if (!cm_is_ipc_credentials(creds)) {
1136 if (smb_sign_client_connections == SMB_SIGNING_REQUIRED) {
1147 tmp_status = cm_get_ipc_credentials(talloc_tos(), &creds);
1148 if (!NT_STATUS_IS_OK(tmp_status)) {
1149 result = tmp_status;
1153 if (cli_credentials_is_anonymous(creds)) {
1157 machine_account = cli_credentials_get_username(creds);
1158 machine_domain = cli_credentials_get_domain(creds);
1160 DEBUG(5, ("connecting to %s from %s using NTLMSSP with username "
1161 "[%s]\\[%s]\n", controller, lp_netbios_name(),
1162 machine_domain, machine_account));
1164 result = cli_session_setup_creds(*cli, creds);
1165 if (NT_STATUS_IS_OK(result)) {
1166 goto session_setup_done;
1169 DEBUG(1, ("authenticated session setup to %s using %s failed with %s\n",
1171 cli_credentials_get_unparsed_name(creds, talloc_tos()),
1172 nt_errstr(result)));
1175 * If we are not going to validiate the conneciton
1176 * with SMB signing, then allow us to fall back to
1179 if (NT_STATUS_EQUAL(result, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT)
1180 || NT_STATUS_EQUAL(result, NT_STATUS_TRUSTED_DOMAIN_FAILURE)
1181 || NT_STATUS_EQUAL(result, NT_STATUS_INVALID_ACCOUNT_NAME)
1182 || NT_STATUS_EQUAL(result, NT_STATUS_NO_LOGON_SERVERS)
1183 || NT_STATUS_EQUAL(result, NT_STATUS_LOGON_FAILURE))
1193 if (smb_sign_client_connections == SMB_SIGNING_REQUIRED) {
1197 /* Fall back to anonymous connection, this might fail later */
1198 DEBUG(5,("cm_prepare_connection: falling back to anonymous "
1199 "connection for DC %s\n",
1202 result = cli_session_setup_anon(*cli);
1203 if (NT_STATUS_IS_OK(result)) {
1204 DEBUG(5, ("Connected anonymously\n"));
1205 goto session_setup_done;
1208 DEBUG(1, ("anonymous session setup to %s failed with %s\n",
1209 controller, nt_errstr(result)));
1211 /* We can't session setup */
1218 * This should be a short term hack until
1219 * dynamic re-authentication is implemented.
1221 * See Bug 9175 - winbindd doesn't recover from
1222 * NT_STATUS_NETWORK_SESSION_EXPIRED
1224 if (smbXcli_conn_protocol((*cli)->conn) >= PROTOCOL_SMB2_02) {
1225 smbXcli_session_set_disconnect_expired((*cli)->smb2.session);
1228 result = cli_tree_connect(*cli, "IPC$", "IPC", NULL);
1229 if (!NT_STATUS_IS_OK(result)) {
1230 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(result)));
1233 tcon_status = result;
1235 /* cache the server name for later connections */
1237 saf_store(domain->name, controller);
1238 if (domain->alt_name) {
1239 saf_store(domain->alt_name, controller);
1242 winbindd_set_locator_kdc_envs(domain);
1247 result = NT_STATUS_OK;
1253 if (NT_STATUS_IS_OK(result)) {
1254 result = tcon_status;
1257 if (!NT_STATUS_IS_OK(result)) {
1258 DEBUG(1, ("Failed to prepare SMB connection to %s: %s\n",
1259 controller, nt_errstr(result)));
1260 winbind_add_failed_connection_entry(domain, controller, result);
1261 if ((*cli) != NULL) {
1270 /*******************************************************************
1271 Add a dcname and sockaddr_storage pair to the end of a dc_name_ip
1274 Keeps the list unique by not adding duplicate entries.
1276 @param[in] mem_ctx talloc memory context to allocate from
1277 @param[in] domain_name domain of the DC
1278 @param[in] dcname name of the DC to add to the list
1279 @param[in] pss Internet address and port pair to add to the list
1280 @param[in,out] dcs array of dc_name_ip structures to add to
1281 @param[in,out] num_dcs number of dcs returned in the dcs array
1282 @return true if the list was added to, false otherwise
1283 *******************************************************************/
1285 static bool add_one_dc_unique(TALLOC_CTX *mem_ctx, const char *domain_name,
1286 const char *dcname, struct sockaddr_storage *pss,
1287 struct dc_name_ip **dcs, int *num)
1291 if (!NT_STATUS_IS_OK(check_negative_conn_cache(domain_name, dcname))) {
1292 DEBUG(10, ("DC %s was in the negative conn cache\n", dcname));
1296 /* Make sure there's no duplicates in the list */
1297 for (i=0; i<*num; i++)
1299 (struct sockaddr *)(void *)&(*dcs)[i].ss,
1300 (struct sockaddr *)(void *)pss))
1303 *dcs = talloc_realloc(mem_ctx, *dcs, struct dc_name_ip, (*num)+1);
1308 fstrcpy((*dcs)[*num].name, dcname);
1309 (*dcs)[*num].ss = *pss;
1314 static bool add_sockaddr_to_array(TALLOC_CTX *mem_ctx,
1315 struct sockaddr_storage *pss, uint16_t port,
1316 struct sockaddr_storage **addrs, int *num)
1318 *addrs = talloc_realloc(mem_ctx, *addrs, struct sockaddr_storage, (*num)+1);
1320 if (*addrs == NULL) {
1325 (*addrs)[*num] = *pss;
1326 set_sockaddr_port((struct sockaddr *)&(*addrs)[*num], port);
1332 /*******************************************************************
1333 convert an ip to a name
1334 For an AD Domain, it checks the requirements of the request flags.
1335 *******************************************************************/
1337 static bool dcip_check_name(TALLOC_CTX *mem_ctx,
1338 const struct winbindd_domain *domain,
1339 struct sockaddr_storage *pss,
1340 char **name, uint32_t request_flags)
1342 struct ip_service ip_list;
1343 uint32_t nt_version = NETLOGON_NT_VERSION_1;
1345 const char *dc_name;
1348 bool is_ad_domain = false;
1354 /* For active directory servers, try to get the ldap server name.
1355 None of these failures should be considered critical for now */
1357 if ((lp_security() == SEC_ADS) && (domain->alt_name != NULL)) {
1358 is_ad_domain = true;
1359 } else if (lp_server_role() == ROLE_ACTIVE_DIRECTORY_DC) {
1360 is_ad_domain = domain->active_directory;
1365 ADS_STATUS ads_status;
1366 char addr[INET6_ADDRSTRLEN];
1368 print_sockaddr(addr, sizeof(addr), pss);
1370 ads = ads_init(domain->alt_name, domain->name, addr);
1371 ads->auth.flags |= ADS_AUTH_NO_BIND;
1372 ads->config.flags |= request_flags;
1374 ads_status = ads_connect(ads);
1375 if (ADS_ERR_OK(ads_status)) {
1376 /* We got a cldap packet. */
1377 *name = talloc_strdup(mem_ctx,
1378 ads->config.ldap_server_name);
1379 if (*name == NULL) {
1382 namecache_store(*name, 0x20, 1, &ip_list);
1384 DEBUG(10,("dcip_check_name: flags = 0x%x\n", (unsigned int)ads->config.flags));
1386 if (domain->primary && (ads->config.flags & NBT_SERVER_KDC)) {
1387 if (ads_closest_dc(ads)) {
1388 char *sitename = sitename_fetch(mem_ctx, ads->config.realm);
1390 /* We're going to use this KDC for this realm/domain.
1391 If we are using sites, then force the krb5 libs
1394 create_local_private_krb5_conf_for_domain(domain->alt_name,
1399 TALLOC_FREE(sitename);
1401 /* use an off site KDC */
1402 create_local_private_krb5_conf_for_domain(domain->alt_name,
1407 winbindd_set_locator_kdc_envs(domain);
1409 /* Ensure we contact this DC also. */
1410 saf_store(domain->name, *name);
1411 saf_store(domain->alt_name, *name);
1414 ads_destroy( &ads );
1418 ads_destroy( &ads );
1423 status = nbt_getdc(winbind_messaging_context(), 10, pss, domain->name,
1424 &domain->sid, nt_version, mem_ctx, &nt_version,
1426 if (NT_STATUS_IS_OK(status)) {
1427 *name = talloc_strdup(mem_ctx, dc_name);
1428 if (*name == NULL) {
1431 namecache_store(*name, 0x20, 1, &ip_list);
1435 /* try node status request */
1437 if (name_status_find(domain->name, 0x1c, 0x20, pss, nbtname) ) {
1438 namecache_store(nbtname, 0x20, 1, &ip_list);
1441 *name = talloc_strdup(mem_ctx, nbtname);
1442 if (*name == NULL) {
1452 /*******************************************************************
1453 Retrieve a list of IP addresses for domain controllers.
1455 The array is sorted in the preferred connection order.
1457 @param[in] mem_ctx talloc memory context to allocate from
1458 @param[in] domain domain to retrieve DCs for
1459 @param[out] dcs array of dcs that will be returned
1460 @param[out] num_dcs number of dcs returned in the dcs array
1462 *******************************************************************/
1464 static bool get_dcs(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
1465 struct dc_name_ip **dcs, int *num_dcs,
1466 uint32_t request_flags)
1469 struct sockaddr_storage ss;
1470 struct ip_service *ip_list = NULL;
1471 int iplist_size = 0;
1474 enum security_types sec = (enum security_types)lp_security();
1476 is_our_domain = strequal(domain->name, lp_workgroup());
1478 /* If not our domain, get the preferred DC, by asking our primary DC */
1480 && get_dc_name_via_netlogon(domain, dcname, &ss, request_flags)
1481 && add_one_dc_unique(mem_ctx, domain->name, dcname, &ss, dcs,
1484 char addr[INET6_ADDRSTRLEN];
1485 print_sockaddr(addr, sizeof(addr), &ss);
1486 DEBUG(10, ("Retrieved DC %s at %s via netlogon\n",
1491 if ((sec == SEC_ADS) && (domain->alt_name != NULL)) {
1492 char *sitename = NULL;
1494 /* We need to make sure we know the local site before
1495 doing any DNS queries, as this will restrict the
1496 get_sorted_dc_list() call below to only fetching
1497 DNS records for the correct site. */
1499 /* Find any DC to get the site record.
1500 We deliberately don't care about the
1503 get_dc_name(domain->name, domain->alt_name, dcname, &ss);
1505 sitename = sitename_fetch(mem_ctx, domain->alt_name);
1508 /* Do the site-specific AD dns lookup first. */
1509 get_sorted_dc_list(domain->alt_name, sitename, &ip_list,
1510 &iplist_size, True);
1512 /* Add ips to the DC array. We don't look up the name
1513 of the DC in this function, but we fill in the char*
1514 of the ip now to make the failed connection cache
1516 for ( i=0; i<iplist_size; i++ ) {
1517 char addr[INET6_ADDRSTRLEN];
1518 print_sockaddr(addr, sizeof(addr),
1520 add_one_dc_unique(mem_ctx,
1529 TALLOC_FREE(sitename);
1533 /* Now we add DCs from the main AD DNS lookup. */
1534 get_sorted_dc_list(domain->alt_name, NULL, &ip_list,
1535 &iplist_size, True);
1537 for ( i=0; i<iplist_size; i++ ) {
1538 char addr[INET6_ADDRSTRLEN];
1539 print_sockaddr(addr, sizeof(addr),
1541 add_one_dc_unique(mem_ctx,
1553 /* Try standard netbios queries if no ADS and fall back to DNS queries
1554 * if alt_name is available */
1555 if (*num_dcs == 0) {
1556 get_sorted_dc_list(domain->name, NULL, &ip_list, &iplist_size,
1558 if (iplist_size == 0) {
1559 if (domain->alt_name != NULL) {
1560 get_sorted_dc_list(domain->alt_name, NULL, &ip_list,
1561 &iplist_size, true);
1565 for ( i=0; i<iplist_size; i++ ) {
1566 char addr[INET6_ADDRSTRLEN];
1567 print_sockaddr(addr, sizeof(addr),
1569 add_one_dc_unique(mem_ctx,
1584 /*******************************************************************
1585 Find and make a connection to a DC in the given domain.
1587 @param[in] mem_ctx talloc memory context to allocate from
1588 @param[in] domain domain to find a dc in
1589 @param[out] dcname NetBIOS or FQDN of DC that's connected to
1590 @param[out] pss DC Internet address and port
1591 @param[out] fd fd of the open socket connected to the newly found dc
1592 @return true when a DC connection is made, false otherwise
1593 *******************************************************************/
1595 static bool find_new_dc(TALLOC_CTX *mem_ctx,
1596 struct winbindd_domain *domain,
1597 char **dcname, struct sockaddr_storage *pss, int *fd,
1598 uint32_t request_flags)
1600 struct dc_name_ip *dcs = NULL;
1603 const char **dcnames = NULL;
1604 size_t num_dcnames = 0;
1606 struct sockaddr_storage *addrs = NULL;
1617 if (!get_dcs(mem_ctx, domain, &dcs, &num_dcs, request_flags) || (num_dcs == 0))
1620 for (i=0; i<num_dcs; i++) {
1622 if (!add_string_to_array(mem_ctx, dcs[i].name,
1623 &dcnames, &num_dcnames)) {
1626 if (!add_sockaddr_to_array(mem_ctx, &dcs[i].ss, TCP_SMB_PORT,
1627 &addrs, &num_addrs)) {
1632 if ((num_dcnames == 0) || (num_dcnames != num_addrs))
1635 if ((addrs == NULL) || (dcnames == NULL))
1638 status = smbsock_any_connect(addrs, dcnames, NULL, NULL, NULL,
1639 num_addrs, 0, 10, fd, &fd_index, NULL);
1640 if (!NT_STATUS_IS_OK(status)) {
1641 for (i=0; i<num_dcs; i++) {
1642 char ab[INET6_ADDRSTRLEN];
1643 print_sockaddr(ab, sizeof(ab), &dcs[i].ss);
1644 DEBUG(10, ("find_new_dc: smbsock_any_connect failed for "
1645 "domain %s address %s. Error was %s\n",
1646 domain->name, ab, nt_errstr(status) ));
1647 winbind_add_failed_connection_entry(domain,
1648 dcs[i].name, NT_STATUS_UNSUCCESSFUL);
1653 *pss = addrs[fd_index];
1655 if (*dcnames[fd_index] != '\0' && !is_ipaddress(dcnames[fd_index])) {
1656 /* Ok, we've got a name for the DC */
1657 *dcname = talloc_strdup(mem_ctx, dcnames[fd_index]);
1658 if (*dcname == NULL) {
1664 /* Try to figure out the name */
1665 if (dcip_check_name(mem_ctx, domain, pss, dcname, request_flags)) {
1669 /* We can not continue without the DC's name */
1670 winbind_add_failed_connection_entry(domain, dcs[fd_index].name,
1671 NT_STATUS_UNSUCCESSFUL);
1673 /* Throw away all arrays as we're doing this again. */
1677 TALLOC_FREE(dcnames);
1689 static char *current_dc_key(TALLOC_CTX *mem_ctx, const char *domain_name)
1691 return talloc_asprintf_strupper_m(mem_ctx, "CURRENT_DCNAME/%s",
1695 static void store_current_dc_in_gencache(const char *domain_name,
1696 const char *dc_name,
1697 struct cli_state *cli)
1699 char addr[INET6_ADDRSTRLEN];
1703 if (!cli_state_is_connected(cli)) {
1707 print_sockaddr(addr, sizeof(addr),
1708 smbXcli_conn_remote_sockaddr(cli->conn));
1710 key = current_dc_key(talloc_tos(), domain_name);
1715 value = talloc_asprintf(talloc_tos(), "%s %s", addr, dc_name);
1716 if (value == NULL) {
1720 gencache_set(key, value, 0x7fffffff);
1726 bool fetch_current_dc_from_gencache(TALLOC_CTX *mem_ctx,
1727 const char *domain_name,
1728 char **p_dc_name, char **p_dc_ip)
1733 char *dc_name = NULL;
1736 key = current_dc_key(talloc_tos(), domain_name);
1740 if (!gencache_get(key, mem_ctx, &value, NULL)) {
1743 p = strchr(value, ' ');
1747 dc_ip = talloc_strndup(mem_ctx, value, p - value);
1748 if (dc_ip == NULL) {
1751 dc_name = talloc_strdup(mem_ctx, p+1);
1752 if (dc_name == NULL) {
1756 if (p_dc_ip != NULL) {
1760 if (p_dc_name != NULL) {
1761 *p_dc_name = dc_name;
1766 TALLOC_FREE(dc_name);
1773 NTSTATUS wb_open_internal_pipe(TALLOC_CTX *mem_ctx,
1774 const struct ndr_interface_table *table,
1775 struct rpc_pipe_client **ret_pipe)
1777 struct rpc_pipe_client *cli = NULL;
1778 const struct auth_session_info *session_info;
1779 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1782 session_info = get_session_info_system();
1783 SMB_ASSERT(session_info != NULL);
1785 /* create a connection to the specified pipe */
1786 if (lp_parm_bool(-1, "winbindd", "use external pipes", false)) {
1787 status = rpc_pipe_open_interface(mem_ctx,
1792 winbind_messaging_context(),
1795 status = rpc_pipe_open_internal(mem_ctx,
1800 winbind_messaging_context(),
1803 if (!NT_STATUS_IS_OK(status)) {
1804 DEBUG(0, ("open_internal_pipe: Could not connect to %s pipe: %s\n",
1805 table->name, nt_errstr(status)));
1813 return NT_STATUS_OK;
1816 static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
1817 struct winbindd_cm_conn *new_conn)
1819 TALLOC_CTX *mem_ctx;
1821 char *saf_servername;
1823 uint32_t request_flags = 0;
1825 if ((mem_ctx = talloc_init("cm_open_connection")) == NULL) {
1826 set_domain_offline(domain);
1827 return NT_STATUS_NO_MEMORY;
1830 saf_servername = saf_fetch(mem_ctx, domain->name );
1832 /* we have to check the server affinity cache here since
1833 later we select a DC based on response time and not preference */
1835 /* Check the negative connection cache
1836 before talking to it. It going down may have
1837 triggered the reconnection. */
1839 if ( saf_servername && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, saf_servername))) {
1841 DEBUG(10,("cm_open_connection: saf_servername is '%s' for domain %s\n",
1842 saf_servername, domain->name ));
1844 /* convert an ip address to a name */
1845 if (is_ipaddress( saf_servername ) ) {
1846 char *dcname = NULL;
1847 struct sockaddr_storage ss;
1849 if (!interpret_string_addr(&ss, saf_servername,
1851 TALLOC_FREE(mem_ctx);
1852 return NT_STATUS_UNSUCCESSFUL;
1854 if (dcip_check_name(mem_ctx, domain, &ss, &dcname, request_flags)) {
1855 domain->dcname = talloc_strdup(domain,
1857 if (domain->dcname == NULL) {
1858 TALLOC_FREE(mem_ctx);
1859 return NT_STATUS_NO_MEMORY;
1862 winbind_add_failed_connection_entry(
1863 domain, saf_servername,
1864 NT_STATUS_UNSUCCESSFUL);
1867 domain->dcname = talloc_strdup(domain, saf_servername);
1868 if (domain->dcname == NULL) {
1869 TALLOC_FREE(mem_ctx);
1870 return NT_STATUS_NO_MEMORY;
1875 for (retries = 0; retries < 3; retries++) {
1878 char *dcname = NULL;
1880 result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1882 DEBUG(10,("cm_open_connection: dcname is '%s' for domain %s\n",
1883 domain->dcname ? domain->dcname : "", domain->name ));
1885 if (domain->dcname != NULL
1886 && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, domain->dcname))
1887 && (resolve_name(domain->dcname, &domain->dcaddr, 0x20, true)))
1891 status = smbsock_connect(&domain->dcaddr, 0,
1894 if (!NT_STATUS_IS_OK(status)) {
1900 !find_new_dc(mem_ctx, domain, &dcname, &domain->dcaddr, &fd, request_flags))
1902 /* This is the one place where we will
1903 set the global winbindd offline state
1904 to true, if a "WINBINDD_OFFLINE" entry
1905 is found in the winbindd cache. */
1906 set_global_winbindd_state_offline();
1909 if (dcname != NULL) {
1910 talloc_free(domain->dcname);
1912 domain->dcname = talloc_move(domain, &dcname);
1913 if (domain->dcname == NULL) {
1914 result = NT_STATUS_NO_MEMORY;
1919 new_conn->cli = NULL;
1921 result = cm_prepare_connection(domain, fd, domain->dcname,
1922 &new_conn->cli, &retry);
1923 if (!NT_STATUS_IS_OK(result)) {
1924 /* Don't leak the smb connection socket */
1932 if (NT_STATUS_IS_OK(result)) {
1933 bool seal_pipes = true;
1935 winbindd_set_locator_kdc_envs(domain);
1937 if (domain->online == False) {
1938 /* We're changing state from offline to online. */
1939 set_global_winbindd_state_online();
1941 set_domain_online(domain);
1944 * Much as I hate global state, this seems to be the point
1945 * where we can be certain that we have a proper connection to
1946 * a DC. wbinfo --dc-info needs that information, store it in
1947 * gencache with a looong timeout. This will need revisiting
1948 * once we start to connect to multiple DCs, wbcDcInfo is
1949 * already prepared for that.
1951 store_current_dc_in_gencache(domain->name, domain->dcname,
1954 seal_pipes = lp_winbind_sealed_pipes();
1955 seal_pipes = lp_parm_bool(-1, "winbind sealed pipes",
1960 new_conn->auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
1962 new_conn->auth_level = DCERPC_AUTH_LEVEL_INTEGRITY;
1965 /* Ensure we setup the retry handler. */
1966 set_domain_offline(domain);
1969 talloc_destroy(mem_ctx);
1973 /* Close down all open pipes on a connection. */
1975 void invalidate_cm_connection(struct winbindd_domain *domain)
1978 struct winbindd_cm_conn *conn = &domain->conn;
1980 /* We're closing down a possibly dead
1981 connection. Don't have impossibly long (10s) timeouts. */
1984 cli_set_timeout(conn->cli, 1000); /* 1 second. */
1987 if (conn->samr_pipe != NULL) {
1988 if (is_valid_policy_hnd(&conn->sam_connect_handle)) {
1989 dcerpc_samr_Close(conn->samr_pipe->binding_handle,
1991 &conn->sam_connect_handle,
1994 TALLOC_FREE(conn->samr_pipe);
1995 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1997 cli_set_timeout(conn->cli, 500);
2001 if (conn->lsa_pipe != NULL) {
2002 if (is_valid_policy_hnd(&conn->lsa_policy)) {
2003 dcerpc_lsa_Close(conn->lsa_pipe->binding_handle,
2008 TALLOC_FREE(conn->lsa_pipe);
2009 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
2011 cli_set_timeout(conn->cli, 500);
2015 if (conn->lsa_pipe_tcp != NULL) {
2016 if (is_valid_policy_hnd(&conn->lsa_policy)) {
2017 dcerpc_lsa_Close(conn->lsa_pipe_tcp->binding_handle,
2022 TALLOC_FREE(conn->lsa_pipe_tcp);
2023 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
2025 cli_set_timeout(conn->cli, 500);
2029 if (conn->netlogon_pipe != NULL) {
2030 TALLOC_FREE(conn->netlogon_pipe);
2031 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
2033 cli_set_timeout(conn->cli, 500);
2037 conn->auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
2038 conn->netlogon_force_reauth = false;
2039 conn->netlogon_flags = 0;
2040 TALLOC_FREE(conn->netlogon_creds);
2043 cli_shutdown(conn->cli);
2049 void close_conns_after_fork(void)
2051 struct winbindd_domain *domain;
2052 struct winbindd_cli_state *cli_state;
2054 for (domain = domain_list(); domain; domain = domain->next) {
2056 * first close the low level SMB TCP connection
2057 * so that we don't generate any SMBclose
2058 * requests in invalidate_cm_connection()
2060 if (cli_state_is_connected(domain->conn.cli)) {
2061 smbXcli_conn_disconnect(domain->conn.cli->conn, NT_STATUS_OK);
2064 invalidate_cm_connection(domain);
2067 for (cli_state = winbindd_client_list();
2069 cli_state = cli_state->next) {
2070 if (cli_state->sock >= 0) {
2071 close(cli_state->sock);
2072 cli_state->sock = -1;
2077 static bool connection_ok(struct winbindd_domain *domain)
2081 ok = cli_state_is_connected(domain->conn.cli);
2083 DEBUG(3, ("connection_ok: Connection to %s for domain %s is not connected\n",
2084 domain->dcname, domain->name));
2088 if (domain->online == False) {
2089 DEBUG(3, ("connection_ok: Domain %s is offline\n", domain->name));
2096 /* Initialize a new connection up to the RPC BIND.
2097 Bypass online status check so always does network calls. */
2099 static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain, bool need_rw_dc)
2102 bool skip_connection = domain->internal;
2103 if (need_rw_dc && domain->rodc) {
2104 skip_connection = false;
2107 /* Internal connections never use the network. */
2108 if (dom_sid_equal(&domain->sid, &global_sid_Builtin)) {
2109 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2112 /* Still ask the internal LSA and SAMR server about the local domain */
2113 if (skip_connection || connection_ok(domain)) {
2114 if (!domain->initialized) {
2115 set_dc_type_and_flags(domain);
2117 return NT_STATUS_OK;
2120 invalidate_cm_connection(domain);
2122 if (!domain->primary && !domain->initialized) {
2124 * Before we connect to a trust, work out if it is an
2125 * AD domain by asking our own domain.
2127 set_dc_type_and_flags_trustinfo(domain);
2130 result = cm_open_connection(domain, &domain->conn);
2132 if (NT_STATUS_IS_OK(result) && !domain->initialized) {
2133 set_dc_type_and_flags(domain);
2139 NTSTATUS init_dc_connection(struct winbindd_domain *domain, bool need_rw_dc)
2141 if (dom_sid_equal(&domain->sid, &global_sid_Builtin)) {
2142 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2145 if (domain->initialized && !domain->online) {
2146 /* We check for online status elsewhere. */
2147 return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
2150 return init_dc_connection_network(domain, need_rw_dc);
2153 static NTSTATUS init_dc_connection_rpc(struct winbindd_domain *domain, bool need_rw_dc)
2157 status = init_dc_connection(domain, need_rw_dc);
2158 if (!NT_STATUS_IS_OK(status)) {
2162 if (!domain->internal && domain->conn.cli == NULL) {
2163 /* happens for trusted domains without inbound trust */
2164 return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
2167 return NT_STATUS_OK;
2170 /******************************************************************************
2171 Set the trust flags (direction and forest location) for a domain
2172 ******************************************************************************/
2174 static bool set_dc_type_and_flags_trustinfo( struct winbindd_domain *domain )
2176 struct winbindd_domain *our_domain;
2177 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2179 struct netr_DomainTrustList trusts;
2181 uint32_t flags = (NETR_TRUST_FLAG_IN_FOREST |
2182 NETR_TRUST_FLAG_OUTBOUND |
2183 NETR_TRUST_FLAG_INBOUND);
2184 struct rpc_pipe_client *cli;
2185 TALLOC_CTX *mem_ctx = NULL;
2186 struct dcerpc_binding_handle *b;
2188 DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s\n", domain->name ));
2190 /* Our primary domain doesn't need to worry about trust flags.
2191 Force it to go through the network setup */
2192 if ( domain->primary ) {
2196 mem_ctx = talloc_stackframe();
2197 our_domain = find_our_domain();
2198 if (our_domain->internal) {
2199 result = init_dc_connection(our_domain, false);
2200 if (!NT_STATUS_IS_OK(result)) {
2201 DEBUG(3,("set_dc_type_and_flags_trustinfo: "
2202 "Not able to make a connection to our domain: %s\n",
2203 nt_errstr(result)));
2204 TALLOC_FREE(mem_ctx);
2209 /* This won't work unless our domain is AD */
2210 if ( !our_domain->active_directory ) {
2211 TALLOC_FREE(mem_ctx);
2215 if (our_domain->internal) {
2216 result = wb_open_internal_pipe(mem_ctx, &ndr_table_netlogon, &cli);
2217 } else if (!connection_ok(our_domain)) {
2218 DEBUG(3,("set_dc_type_and_flags_trustinfo: "
2219 "No connection to our domain!\n"));
2220 TALLOC_FREE(mem_ctx);
2223 result = cm_connect_netlogon(our_domain, &cli);
2226 if (!NT_STATUS_IS_OK(result)) {
2227 DEBUG(5, ("set_dc_type_and_flags_trustinfo: Could not open "
2228 "a connection to %s for PIPE_NETLOGON (%s)\n",
2229 domain->name, nt_errstr(result)));
2230 TALLOC_FREE(mem_ctx);
2233 b = cli->binding_handle;
2235 /* Use DsEnumerateDomainTrusts to get us the trust direction and type. */
2236 result = dcerpc_netr_DsrEnumerateDomainTrusts(b, mem_ctx,
2241 if (!NT_STATUS_IS_OK(result)) {
2242 DEBUG(0,("set_dc_type_and_flags_trustinfo: "
2243 "failed to query trusted domain list: %s\n",
2244 nt_errstr(result)));
2245 TALLOC_FREE(mem_ctx);
2248 if (!W_ERROR_IS_OK(werr)) {
2249 DEBUG(0,("set_dc_type_and_flags_trustinfo: "
2250 "failed to query trusted domain list: %s\n",
2252 TALLOC_FREE(mem_ctx);
2256 /* Now find the domain name and get the flags */
2258 for ( i=0; i<trusts.count; i++ ) {
2259 if ( strequal( domain->name, trusts.array[i].netbios_name) ) {
2260 domain->domain_flags = trusts.array[i].trust_flags;
2261 domain->domain_type = trusts.array[i].trust_type;
2262 domain->domain_trust_attribs = trusts.array[i].trust_attributes;
2264 if ( domain->domain_type == LSA_TRUST_TYPE_UPLEVEL )
2265 domain->active_directory = True;
2267 /* This flag is only set if the domain is *our*
2268 primary domain and the primary domain is in
2271 domain->native_mode = (domain->domain_flags & NETR_TRUST_FLAG_NATIVE);
2273 DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s is %sin "
2274 "native mode.\n", domain->name,
2275 domain->native_mode ? "" : "NOT "));
2277 DEBUG(5,("set_dc_type_and_flags_trustinfo: domain %s is %s"
2278 "running active directory.\n", domain->name,
2279 domain->active_directory ? "" : "NOT "));
2281 domain->can_do_ncacn_ip_tcp = domain->active_directory;
2283 domain->initialized = True;
2289 TALLOC_FREE(mem_ctx);
2291 return domain->initialized;
2294 /******************************************************************************
2295 We can 'sense' certain things about the DC by it's replies to certain
2298 This tells us if this particular remote server is Active Directory, and if it
2300 ******************************************************************************/
2302 static void set_dc_type_and_flags_connect( struct winbindd_domain *domain )
2304 NTSTATUS status, result;
2306 TALLOC_CTX *mem_ctx = NULL;
2307 struct rpc_pipe_client *cli = NULL;
2308 struct policy_handle pol;
2309 union dssetup_DsRoleInfo info;
2310 union lsa_PolicyInformation *lsa_info = NULL;
2312 if (!domain->internal && !connection_ok(domain)) {
2316 mem_ctx = talloc_init("set_dc_type_and_flags on domain %s\n",
2319 DEBUG(1, ("set_dc_type_and_flags_connect: talloc_init() failed\n"));
2323 DEBUG(5, ("set_dc_type_and_flags_connect: domain %s\n", domain->name ));
2325 if (domain->internal) {
2326 status = wb_open_internal_pipe(mem_ctx,
2330 status = cli_rpc_pipe_open_noauth(domain->conn.cli,
2335 if (!NT_STATUS_IS_OK(status)) {
2336 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
2337 "PI_DSSETUP on domain %s: (%s)\n",
2338 domain->name, nt_errstr(status)));
2340 /* if this is just a non-AD domain we need to continue
2341 * identifying so that we can in the end return with
2342 * domain->initialized = True - gd */
2347 status = dcerpc_dssetup_DsRoleGetPrimaryDomainInformation(cli->binding_handle, mem_ctx,
2348 DS_ROLE_BASIC_INFORMATION,
2353 if (NT_STATUS_IS_OK(status)) {
2354 result = werror_to_ntstatus(werr);
2356 if (!NT_STATUS_IS_OK(status)) {
2357 DEBUG(5, ("set_dc_type_and_flags_connect: rpccli_ds_getprimarydominfo "
2358 "on domain %s failed: (%s)\n",
2359 domain->name, nt_errstr(status)));
2361 /* older samba3 DCs will return DCERPC_FAULT_OP_RNG_ERROR for
2362 * every opcode on the DSSETUP pipe, continue with
2363 * no_dssetup mode here as well to get domain->initialized
2366 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
2370 TALLOC_FREE(mem_ctx);
2374 if ((info.basic.flags & DS_ROLE_PRIMARY_DS_RUNNING) &&
2375 !(info.basic.flags & DS_ROLE_PRIMARY_DS_MIXED_MODE)) {
2376 domain->native_mode = True;
2378 domain->native_mode = False;
2382 if (domain->internal) {
2383 status = wb_open_internal_pipe(mem_ctx,
2387 status = cli_rpc_pipe_open_noauth(domain->conn.cli,
2388 &ndr_table_lsarpc, &cli);
2390 if (!NT_STATUS_IS_OK(status)) {
2391 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
2392 "PI_LSARPC on domain %s: (%s)\n",
2393 domain->name, nt_errstr(status)));
2395 TALLOC_FREE(mem_ctx);
2399 status = rpccli_lsa_open_policy2(cli, mem_ctx, True,
2400 SEC_FLAG_MAXIMUM_ALLOWED, &pol);
2402 if (NT_STATUS_IS_OK(status)) {
2403 /* This particular query is exactly what Win2k clients use
2404 to determine that the DC is active directory */
2405 status = dcerpc_lsa_QueryInfoPolicy2(cli->binding_handle, mem_ctx,
2407 LSA_POLICY_INFO_DNS,
2412 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2413 domain->active_directory = True;
2415 if (lsa_info->dns.name.string) {
2416 if (!strequal(domain->name, lsa_info->dns.name.string))
2418 DEBUG(1, ("set_dc_type_and_flags_connect: DC "
2419 "for domain %s claimed it was a DC "
2420 "for domain %s, refusing to "
2423 lsa_info->dns.name.string));
2425 TALLOC_FREE(mem_ctx);
2428 talloc_free(domain->name);
2429 domain->name = talloc_strdup(domain,
2430 lsa_info->dns.name.string);
2431 if (domain->name == NULL) {
2436 if (lsa_info->dns.dns_domain.string) {
2437 if (domain->alt_name != NULL &&
2438 !strequal(domain->alt_name,
2439 lsa_info->dns.dns_domain.string))
2441 DEBUG(1, ("set_dc_type_and_flags_connect: DC "
2442 "for domain %s (%s) claimed it was "
2443 "a DC for domain %s, refusing to "
2445 domain->alt_name, domain->name,
2446 lsa_info->dns.dns_domain.string));
2448 TALLOC_FREE(mem_ctx);
2451 talloc_free(domain->alt_name);
2453 talloc_strdup(domain,
2454 lsa_info->dns.dns_domain.string);
2455 if (domain->alt_name == NULL) {
2460 /* See if we can set some domain trust flags about
2463 if (lsa_info->dns.dns_forest.string) {
2464 talloc_free(domain->forest_name);
2465 domain->forest_name =
2466 talloc_strdup(domain,
2467 lsa_info->dns.dns_forest.string);
2468 if (domain->forest_name == NULL) {
2472 if (strequal(domain->forest_name, domain->alt_name)) {
2473 domain->domain_flags |= NETR_TRUST_FLAG_TREEROOT;
2477 if (lsa_info->dns.sid) {
2478 if (!is_null_sid(&domain->sid) &&
2479 !dom_sid_equal(&domain->sid,
2482 DEBUG(1, ("set_dc_type_and_flags_connect: DC "
2483 "for domain %s (%s) claimed it was "
2484 "a DC for domain %s, refusing to "
2486 dom_sid_string(talloc_tos(),
2489 dom_sid_string(talloc_tos(),
2490 lsa_info->dns.sid)));
2492 TALLOC_FREE(mem_ctx);
2495 sid_copy(&domain->sid, lsa_info->dns.sid);
2498 domain->active_directory = False;
2500 status = rpccli_lsa_open_policy(cli, mem_ctx, True,
2501 SEC_FLAG_MAXIMUM_ALLOWED,
2504 if (!NT_STATUS_IS_OK(status)) {
2508 status = dcerpc_lsa_QueryInfoPolicy(cli->binding_handle, mem_ctx,
2510 LSA_POLICY_INFO_ACCOUNT_DOMAIN,
2513 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2515 if (lsa_info->account_domain.name.string) {
2516 if (!strequal(domain->name,
2517 lsa_info->account_domain.name.string))
2520 ("set_dc_type_and_flags_connect: "
2521 "DC for domain %s claimed it was"
2522 " a DC for domain %s, refusing "
2523 "to initialize\n", domain->name,
2525 account_domain.name.string));
2527 TALLOC_FREE(mem_ctx);
2530 talloc_free(domain->name);
2532 talloc_strdup(domain,
2533 lsa_info->account_domain.name.string);
2536 if (lsa_info->account_domain.sid) {
2537 if (!is_null_sid(&domain->sid) &&
2538 !dom_sid_equal(&domain->sid,
2539 lsa_info->account_domain.sid))
2542 ("set_dc_type_and_flags_connect: "
2543 "DC for domain %s (%s) claimed "
2544 "it was a DC for domain %s, "
2545 "refusing to initialize\n",
2546 dom_sid_string(talloc_tos(),
2549 dom_sid_string(talloc_tos(),
2550 lsa_info->account_domain.sid)));
2552 TALLOC_FREE(mem_ctx);
2555 sid_copy(&domain->sid, lsa_info->account_domain.sid);
2561 DEBUG(5, ("set_dc_type_and_flags_connect: domain %s is %sin native mode.\n",
2562 domain->name, domain->native_mode ? "" : "NOT "));
2564 DEBUG(5,("set_dc_type_and_flags_connect: domain %s is %srunning active directory.\n",
2565 domain->name, domain->active_directory ? "" : "NOT "));
2567 domain->can_do_ncacn_ip_tcp = domain->active_directory;
2571 TALLOC_FREE(mem_ctx);
2573 domain->initialized = True;
2576 /**********************************************************************
2577 Set the domain_flags (trust attributes, domain operating modes, etc...
2578 ***********************************************************************/
2580 static void set_dc_type_and_flags( struct winbindd_domain *domain )
2582 /* we always have to contact our primary domain */
2584 if ( domain->primary || domain->internal) {
2585 DEBUG(10,("set_dc_type_and_flags: setting up flags for "
2586 "primary or internal domain\n"));
2587 set_dc_type_and_flags_connect( domain );
2591 /* Use our DC to get the information if possible */
2593 if ( !set_dc_type_and_flags_trustinfo( domain ) ) {
2594 /* Otherwise, fallback to contacting the
2596 set_dc_type_and_flags_connect( domain );
2604 /**********************************************************************
2605 ***********************************************************************/
2607 static NTSTATUS cm_get_schannel_creds(struct winbindd_domain *domain,
2608 struct netlogon_creds_cli_context **ppdc)
2610 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2611 struct rpc_pipe_client *netlogon_pipe;
2615 if ((!IS_DC) && (!domain->primary)) {
2616 return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
2619 if (domain->conn.netlogon_creds != NULL) {
2620 if (!(domain->conn.netlogon_flags & NETLOGON_NEG_AUTHENTICATED_RPC)) {
2621 return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
2623 *ppdc = domain->conn.netlogon_creds;
2624 return NT_STATUS_OK;
2627 result = cm_connect_netlogon(domain, &netlogon_pipe);
2628 if (!NT_STATUS_IS_OK(result)) {
2632 if (domain->conn.netlogon_creds == NULL) {
2633 return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
2636 if (!(domain->conn.netlogon_flags & NETLOGON_NEG_AUTHENTICATED_RPC)) {
2637 return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
2640 *ppdc = domain->conn.netlogon_creds;
2641 return NT_STATUS_OK;
2644 NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
2646 struct rpc_pipe_client **cli, struct policy_handle *sam_handle)
2648 struct winbindd_cm_conn *conn;
2649 NTSTATUS status, result;
2650 struct netlogon_creds_cli_context *p_creds;
2651 struct cli_credentials *creds = NULL;
2652 bool retry = false; /* allow one retry attempt for expired session */
2654 if (sid_check_is_our_sam(&domain->sid)) {
2655 if (domain->rodc == false || need_rw_dc == false) {
2656 return open_internal_samr_conn(mem_ctx, domain, cli, sam_handle);
2661 status = init_dc_connection_rpc(domain, need_rw_dc);
2662 if (!NT_STATUS_IS_OK(status)) {
2666 conn = &domain->conn;
2668 if (rpccli_is_connected(conn->samr_pipe)) {
2672 TALLOC_FREE(conn->samr_pipe);
2675 * No SAMR pipe yet. Attempt to get an NTLMSSP SPNEGO authenticated
2676 * sign and sealed pipe using the machine account password by
2677 * preference. If we can't - try schannel, if that fails, try
2681 result = get_trust_credentials(domain, talloc_tos(), false, &creds);
2682 if (!NT_STATUS_IS_OK(result)) {
2683 DEBUG(10, ("cm_connect_sam: No user available for "
2684 "domain %s, trying schannel\n", domain->name));
2688 if (cli_credentials_is_anonymous(creds)) {
2693 * We have an authenticated connection. Use a SPNEGO
2694 * authenticated SAMR pipe with sign & seal.
2696 status = cli_rpc_pipe_open_with_creds(conn->cli,
2699 DCERPC_AUTH_TYPE_SPNEGO,
2701 smbXcli_conn_remote_name(conn->cli->conn),
2705 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)
2707 invalidate_cm_connection(domain);
2712 if (!NT_STATUS_IS_OK(status)) {
2713 DEBUG(10,("cm_connect_sam: failed to connect to SAMR "
2714 "pipe for domain %s using NTLMSSP "
2715 "authenticated pipe: user %s. Error was "
2716 "%s\n", domain->name,
2717 cli_credentials_get_unparsed_name(creds, talloc_tos()),
2718 nt_errstr(status)));
2722 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for "
2723 "domain %s using NTLMSSP authenticated "
2724 "pipe: user %s\n", domain->name,
2725 cli_credentials_get_unparsed_name(creds, talloc_tos())));
2727 status = dcerpc_samr_Connect2(conn->samr_pipe->binding_handle, mem_ctx,
2728 conn->samr_pipe->desthost,
2729 SEC_FLAG_MAXIMUM_ALLOWED,
2730 &conn->sam_connect_handle,
2733 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_DEVICE_ERROR) && !retry) {
2734 invalidate_cm_connection(domain);
2735 TALLOC_FREE(conn->samr_pipe);
2740 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2743 if (NT_STATUS_IS_OK(status)) {
2747 DEBUG(10,("cm_connect_sam: ntlmssp-sealed dcerpc_samr_Connect2 "
2748 "failed for domain %s, error was %s. Trying schannel\n",
2749 domain->name, nt_errstr(status) ));
2750 TALLOC_FREE(conn->samr_pipe);
2754 /* Fall back to schannel if it's a W2K pre-SP1 box. */
2756 status = cm_get_schannel_creds(domain, &p_creds);
2757 if (!NT_STATUS_IS_OK(status)) {
2758 /* If this call fails - conn->cli can now be NULL ! */
2759 DEBUG(10, ("cm_connect_sam: Could not get schannel auth info "
2760 "for domain %s (error %s), trying anon\n",
2762 nt_errstr(status) ));
2766 result = get_trust_credentials(domain, talloc_tos(), true, &creds);
2767 if (!NT_STATUS_IS_OK(result)) {
2768 DEBUG(10, ("cm_connect_sam: No user available for "
2769 "domain %s (error %s), trying anon\n", domain->name,
2770 nt_errstr(result)));
2773 status = cli_rpc_pipe_open_schannel_with_creds
2774 (conn->cli, &ndr_table_samr, NCACN_NP,
2775 creds, p_creds, &conn->samr_pipe);
2777 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)
2779 invalidate_cm_connection(domain);
2784 if (!NT_STATUS_IS_OK(status)) {
2785 DEBUG(10,("cm_connect_sam: failed to connect to SAMR pipe for "
2786 "domain %s using schannel. Error was %s\n",
2787 domain->name, nt_errstr(status) ));
2790 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for domain %s using "
2791 "schannel.\n", domain->name ));
2793 status = dcerpc_samr_Connect2(conn->samr_pipe->binding_handle, mem_ctx,
2794 conn->samr_pipe->desthost,
2795 SEC_FLAG_MAXIMUM_ALLOWED,
2796 &conn->sam_connect_handle,
2799 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_DEVICE_ERROR) && !retry) {
2800 invalidate_cm_connection(domain);
2801 TALLOC_FREE(conn->samr_pipe);
2806 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2809 if (NT_STATUS_IS_OK(status)) {
2812 DEBUG(10,("cm_connect_sam: schannel-sealed dcerpc_samr_Connect2 failed "
2813 "for domain %s, error was %s. Trying anonymous\n",
2814 domain->name, nt_errstr(status) ));
2815 TALLOC_FREE(conn->samr_pipe);
2819 /* Finally fall back to anonymous. */
2820 if (lp_winbind_sealed_pipes() || lp_require_strong_key()) {
2821 status = NT_STATUS_DOWNGRADE_DETECTED;
2822 DEBUG(1, ("Unwilling to make SAMR connection to domain %s "
2823 "without connection level security, "
2824 "must set 'winbind sealed pipes = false' and "
2825 "'require strong key = false' to proceed: %s\n",
2826 domain->name, nt_errstr(status)));
2829 status = cli_rpc_pipe_open_noauth(conn->cli, &ndr_table_samr,
2832 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)
2834 invalidate_cm_connection(domain);
2839 if (!NT_STATUS_IS_OK(status)) {
2843 status = dcerpc_samr_Connect2(conn->samr_pipe->binding_handle, mem_ctx,
2844 conn->samr_pipe->desthost,
2845 SEC_FLAG_MAXIMUM_ALLOWED,
2846 &conn->sam_connect_handle,
2849 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_DEVICE_ERROR) && !retry) {
2850 invalidate_cm_connection(domain);
2851 TALLOC_FREE(conn->samr_pipe);
2856 if (!NT_STATUS_IS_OK(status)) {
2857 DEBUG(10,("cm_connect_sam: rpccli_samr_Connect2 failed "
2858 "for domain %s Error was %s\n",
2859 domain->name, nt_errstr(status) ));
2862 if (!NT_STATUS_IS_OK(result)) {
2864 DEBUG(10,("cm_connect_sam: dcerpc_samr_Connect2 failed "
2865 "for domain %s Error was %s\n",
2866 domain->name, nt_errstr(result)));
2871 status = dcerpc_samr_OpenDomain(conn->samr_pipe->binding_handle,
2873 &conn->sam_connect_handle,
2874 SEC_FLAG_MAXIMUM_ALLOWED,
2876 &conn->sam_domain_handle,
2878 if (!NT_STATUS_IS_OK(status)) {
2885 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2887 * if we got access denied, we might just have no access rights
2888 * to talk to the remote samr server server (e.g. when we are a
2889 * PDC and we are connecting a w2k8 pdc via an interdomain
2890 * trust). In that case do not invalidate the whole connection
2893 TALLOC_FREE(conn->samr_pipe);
2894 ZERO_STRUCT(conn->sam_domain_handle);
2896 } else if (!NT_STATUS_IS_OK(status)) {
2897 invalidate_cm_connection(domain);
2901 *cli = conn->samr_pipe;
2902 *sam_handle = conn->sam_domain_handle;
2906 /**********************************************************************
2907 open an schanneld ncacn_ip_tcp connection to LSA
2908 ***********************************************************************/
2910 static NTSTATUS cm_connect_lsa_tcp(struct winbindd_domain *domain,
2911 TALLOC_CTX *mem_ctx,
2912 struct rpc_pipe_client **cli)
2914 struct winbindd_cm_conn *conn;
2915 struct netlogon_creds_cli_context *p_creds = NULL;
2916 struct cli_credentials *creds = NULL;
2919 DEBUG(10,("cm_connect_lsa_tcp\n"));
2921 status = init_dc_connection_rpc(domain, false);
2922 if (!NT_STATUS_IS_OK(status)) {
2926 conn = &domain->conn;
2928 if (conn->lsa_pipe_tcp &&
2929 conn->lsa_pipe_tcp->transport->transport == NCACN_IP_TCP &&
2930 conn->lsa_pipe_tcp->auth->auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY &&
2931 rpccli_is_connected(conn->lsa_pipe_tcp)) {
2935 TALLOC_FREE(conn->lsa_pipe_tcp);
2937 status = cm_get_schannel_creds(domain, &p_creds);
2938 if (!NT_STATUS_IS_OK(status)) {
2942 status = get_trust_credentials(domain, talloc_tos(), true, &creds);
2943 if (!NT_STATUS_IS_OK(status)) {
2947 status = cli_rpc_pipe_open_schannel_with_creds(conn->cli,
2952 &conn->lsa_pipe_tcp);
2953 if (!NT_STATUS_IS_OK(status)) {
2954 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key failed: %s\n",
2955 nt_errstr(status)));
2960 if (!NT_STATUS_IS_OK(status)) {
2961 TALLOC_FREE(conn->lsa_pipe_tcp);
2965 *cli = conn->lsa_pipe_tcp;
2970 NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
2971 struct rpc_pipe_client **cli, struct policy_handle *lsa_policy)
2973 struct winbindd_cm_conn *conn;
2974 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2975 struct netlogon_creds_cli_context *p_creds;
2976 struct cli_credentials *creds = NULL;
2977 bool retry = false; /* allow one retry attempt for expired session */
2980 result = init_dc_connection_rpc(domain, false);
2981 if (!NT_STATUS_IS_OK(result))
2984 conn = &domain->conn;
2986 if (rpccli_is_connected(conn->lsa_pipe)) {
2990 TALLOC_FREE(conn->lsa_pipe);
2992 result = get_trust_credentials(domain, talloc_tos(), false, &creds);
2993 if (!NT_STATUS_IS_OK(result)) {
2994 DEBUG(10, ("cm_connect_lsa: No user available for "
2995 "domain %s, trying schannel\n", domain->name));
2999 if (cli_credentials_is_anonymous(creds)) {
3004 * We have an authenticated connection. Use a SPNEGO
3005 * authenticated LSA pipe with sign & seal.
3007 result = cli_rpc_pipe_open_with_creds
3008 (conn->cli, &ndr_table_lsarpc, NCACN_NP,
3009 DCERPC_AUTH_TYPE_SPNEGO,
3011 smbXcli_conn_remote_name(conn->cli->conn),
3015 if (NT_STATUS_EQUAL(result, NT_STATUS_NETWORK_SESSION_EXPIRED)
3017 invalidate_cm_connection(domain);
3022 if (!NT_STATUS_IS_OK(result)) {
3023 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
3024 "domain %s using NTLMSSP authenticated pipe: user "
3025 "%s. Error was %s. Trying schannel.\n",
3027 cli_credentials_get_unparsed_name(creds, talloc_tos()),
3028 nt_errstr(result)));
3032 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
3033 "NTLMSSP authenticated pipe: user %s\n",
3034 domain->name, cli_credentials_get_unparsed_name(creds, talloc_tos())));
3036 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
3037 SEC_FLAG_MAXIMUM_ALLOWED,
3039 if (NT_STATUS_EQUAL(result, NT_STATUS_IO_DEVICE_ERROR) && !retry) {
3040 invalidate_cm_connection(domain);
3041 TALLOC_FREE(conn->lsa_pipe);
3046 if (NT_STATUS_IS_OK(result)) {
3050 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
3053 TALLOC_FREE(conn->lsa_pipe);
3057 /* Fall back to schannel if it's a W2K pre-SP1 box. */
3059 result = cm_get_schannel_creds(domain, &p_creds);
3060 if (!NT_STATUS_IS_OK(result)) {
3061 /* If this call fails - conn->cli can now be NULL ! */
3062 DEBUG(10, ("cm_connect_lsa: Could not get schannel auth info "
3063 "for domain %s (error %s), trying anon\n",
3065 nt_errstr(result) ));
3070 result = get_trust_credentials(domain, talloc_tos(), true, &creds);
3071 if (!NT_STATUS_IS_OK(result)) {
3072 DEBUG(10, ("cm_connect_lsa: No user available for "
3073 "domain %s (error %s), trying anon\n", domain->name,
3074 nt_errstr(result)));
3077 result = cli_rpc_pipe_open_schannel_with_creds
3078 (conn->cli, &ndr_table_lsarpc, NCACN_NP,
3079 creds, p_creds, &conn->lsa_pipe);
3081 if (NT_STATUS_EQUAL(result, NT_STATUS_NETWORK_SESSION_EXPIRED)
3083 invalidate_cm_connection(domain);
3088 if (!NT_STATUS_IS_OK(result)) {
3089 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
3090 "domain %s using schannel. Error was %s\n",
3091 domain->name, nt_errstr(result) ));
3094 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
3095 "schannel.\n", domain->name ));
3097 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
3098 SEC_FLAG_MAXIMUM_ALLOWED,
3101 if (NT_STATUS_EQUAL(result, NT_STATUS_IO_DEVICE_ERROR) && !retry) {
3102 invalidate_cm_connection(domain);
3103 TALLOC_FREE(conn->lsa_pipe);
3108 if (NT_STATUS_IS_OK(result)) {
3112 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
3115 TALLOC_FREE(conn->lsa_pipe);
3119 if (lp_winbind_sealed_pipes() || lp_require_strong_key()) {
3120 result = NT_STATUS_DOWNGRADE_DETECTED;
3121 DEBUG(1, ("Unwilling to make LSA connection to domain %s "
3122 "without connection level security, "
3123 "must set 'winbind sealed pipes = false' and "
3124 "'require strong key = false' to proceed: %s\n",
3125 domain->name, nt_errstr(result)));
3129 result = cli_rpc_pipe_open_noauth(conn->cli,
3133 if (NT_STATUS_EQUAL(result, NT_STATUS_NETWORK_SESSION_EXPIRED)
3135 invalidate_cm_connection(domain);
3140 if (!NT_STATUS_IS_OK(result)) {
3144 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
3145 SEC_FLAG_MAXIMUM_ALLOWED,
3148 if (NT_STATUS_EQUAL(result, NT_STATUS_IO_DEVICE_ERROR) && !retry) {
3149 invalidate_cm_connection(domain);
3150 TALLOC_FREE(conn->lsa_pipe);
3156 if (!NT_STATUS_IS_OK(result)) {
3157 invalidate_cm_connection(domain);
3161 *cli = conn->lsa_pipe;
3162 *lsa_policy = conn->lsa_policy;
3166 /****************************************************************************
3167 Open a LSA connection to a DC, suiteable for LSA lookup calls.
3168 ****************************************************************************/
3170 NTSTATUS cm_connect_lsat(struct winbindd_domain *domain,
3171 TALLOC_CTX *mem_ctx,
3172 struct rpc_pipe_client **cli,
3173 struct policy_handle *lsa_policy)
3177 if (domain->can_do_ncacn_ip_tcp) {
3178 status = cm_connect_lsa_tcp(domain, mem_ctx, cli);
3179 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
3180 NT_STATUS_EQUAL(status, NT_STATUS_RPC_SEC_PKG_ERROR) ||
3181 NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
3182 invalidate_cm_connection(domain);
3183 status = cm_connect_lsa_tcp(domain, mem_ctx, cli);
3185 if (NT_STATUS_IS_OK(status)) {
3190 * we tried twice to connect via ncan_ip_tcp and schannel and
3191 * failed - maybe it is a trusted domain we can't connect to ?
3192 * do not try tcp next time - gd
3194 * This also prevents NETLOGON over TCP
3196 domain->can_do_ncacn_ip_tcp = false;
3199 status = cm_connect_lsa(domain, mem_ctx, cli, lsa_policy);
3204 /****************************************************************************
3205 Open the netlogon pipe to this DC. Use schannel if specified in client conf.
3206 session key stored in conn->netlogon_pipe->dc->sess_key.
3207 ****************************************************************************/
3209 static NTSTATUS cm_connect_netlogon_transport(struct winbindd_domain *domain,
3210 enum dcerpc_transport_t transport,
3211 struct rpc_pipe_client **cli)
3213 struct messaging_context *msg_ctx = winbind_messaging_context();
3214 struct winbindd_cm_conn *conn;
3216 enum netr_SchannelType sec_chan_type;
3217 struct netlogon_creds_CredentialState *netlogon_creds = NULL;
3218 struct cli_credentials *creds = NULL;
3222 result = init_dc_connection_rpc(domain, domain->rodc);
3223 if (!NT_STATUS_IS_OK(result)) {
3227 conn = &domain->conn;
3229 if (rpccli_is_connected(conn->netlogon_pipe)) {
3230 *cli = conn->netlogon_pipe;
3231 return NT_STATUS_OK;
3234 TALLOC_FREE(conn->netlogon_pipe);
3235 conn->netlogon_flags = 0;
3236 TALLOC_FREE(conn->netlogon_creds);
3238 result = get_trust_credentials(domain, talloc_tos(), true, &creds);
3239 if (!NT_STATUS_IS_OK(result)) {
3240 DBG_DEBUG("No user available for domain %s when trying "
3241 "schannel\n", domain->name);
3242 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3245 if (cli_credentials_is_anonymous(creds)) {
3246 DEBUG(1, ("get_trust_credential only gave anonymous for %s, unable to make get NETLOGON credentials\n",
3248 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3251 sec_chan_type = cli_credentials_get_secure_channel_type(creds);
3252 if (sec_chan_type == SEC_CHAN_NULL) {
3253 if (transport == NCACN_IP_TCP) {
3254 DBG_NOTICE("get_secure_channel_type gave SEC_CHAN_NULL for %s, "
3255 " deny NCACN_IP_TCP and let the caller fallback to NCACN_NP.\n",
3257 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3260 DBG_NOTICE("get_secure_channel_type gave SEC_CHAN_NULL for %s, "
3261 "fallback to noauth on NCACN_NP.\n",
3264 result = cli_rpc_pipe_open_noauth_transport(conn->cli,
3266 &ndr_table_netlogon,
3267 &conn->netlogon_pipe);
3268 if (!NT_STATUS_IS_OK(result)) {
3269 invalidate_cm_connection(domain);
3273 *cli = conn->netlogon_pipe;
3274 return NT_STATUS_OK;
3277 result = rpccli_create_netlogon_creds_with_creds(creds,
3281 &conn->netlogon_creds);
3282 if (!NT_STATUS_IS_OK(result)) {
3283 DEBUG(1, ("rpccli_create_netlogon_creds failed for %s, "
3284 "unable to create NETLOGON credentials: %s\n",
3285 domain->name, nt_errstr(result)));
3289 result = rpccli_setup_netlogon_creds_with_creds(conn->cli, transport,
3290 conn->netlogon_creds,
3291 conn->netlogon_force_reauth,
3293 conn->netlogon_force_reauth = false;
3294 if (!NT_STATUS_IS_OK(result)) {
3295 DEBUG(1, ("rpccli_setup_netlogon_creds failed for %s, "
3296 "unable to setup NETLOGON credentials: %s\n",
3297 domain->name, nt_errstr(result)));
3301 result = netlogon_creds_cli_get(conn->netlogon_creds,
3304 if (!NT_STATUS_IS_OK(result)) {
3305 DEBUG(1, ("netlogon_creds_cli_get failed for %s, "
3306 "unable to get NETLOGON credentials: %s\n",
3307 domain->name, nt_errstr(result)));
3310 conn->netlogon_flags = netlogon_creds->negotiate_flags;
3311 TALLOC_FREE(netlogon_creds);
3313 if (!(conn->netlogon_flags & NETLOGON_NEG_AUTHENTICATED_RPC)) {
3314 if (lp_winbind_sealed_pipes() || lp_require_strong_key()) {
3315 result = NT_STATUS_DOWNGRADE_DETECTED;
3316 DEBUG(1, ("Unwilling to make connection to domain %s"
3317 "without connection level security, "
3318 "must set 'winbind sealed pipes = false' and "
3319 "'require strong key = false' to proceed: %s\n",
3320 domain->name, nt_errstr(result)));
3321 invalidate_cm_connection(domain);
3324 result = cli_rpc_pipe_open_noauth_transport(conn->cli,
3326 &ndr_table_netlogon,
3327 &conn->netlogon_pipe);
3328 if (!NT_STATUS_IS_OK(result)) {
3329 invalidate_cm_connection(domain);
3333 *cli = conn->netlogon_pipe;
3334 return NT_STATUS_OK;
3337 /* Using the credentials from the first pipe, open a signed and sealed
3338 second netlogon pipe. The session key is stored in the schannel
3339 part of the new pipe auth struct.
3342 result = cli_rpc_pipe_open_schannel_with_creds(
3343 conn->cli, &ndr_table_netlogon, transport,
3345 conn->netlogon_creds,
3346 &conn->netlogon_pipe);
3347 if (!NT_STATUS_IS_OK(result)) {
3348 DEBUG(3, ("Could not open schannel'ed NETLOGON pipe. Error "
3349 "was %s\n", nt_errstr(result)));
3351 invalidate_cm_connection(domain);
3355 *cli = conn->netlogon_pipe;
3356 return NT_STATUS_OK;
3359 /****************************************************************************
3360 Open a NETLOGON connection to a DC, suiteable for SamLogon calls.
3361 ****************************************************************************/
3363 NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
3364 struct rpc_pipe_client **cli)
3368 status = init_dc_connection_rpc(domain, domain->rodc);
3369 if (!NT_STATUS_IS_OK(status)) {
3373 if (domain->active_directory && domain->can_do_ncacn_ip_tcp) {
3374 status = cm_connect_netlogon_transport(domain, NCACN_IP_TCP, cli);
3375 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
3376 NT_STATUS_EQUAL(status, NT_STATUS_RPC_SEC_PKG_ERROR) ||
3377 NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
3378 invalidate_cm_connection(domain);
3379 status = cm_connect_netlogon_transport(domain, NCACN_IP_TCP, cli);
3381 if (NT_STATUS_IS_OK(status)) {
3386 * we tried twice to connect via ncan_ip_tcp and schannel and
3387 * failed - maybe it is a trusted domain we can't connect to ?
3388 * do not try tcp next time - gd
3390 * This also prevents LSA over TCP
3392 domain->can_do_ncacn_ip_tcp = false;
3395 status = cm_connect_netlogon_transport(domain, NCACN_NP, cli);
3396 if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
3398 * SMB2 session expired, needs reauthentication. Drop
3399 * connection and retry.
3401 invalidate_cm_connection(domain);
3402 status = cm_connect_netlogon_transport(domain, NCACN_NP, cli);
3408 void winbind_msg_ip_dropped(struct messaging_context *msg_ctx,
3411 struct server_id server_id,
3414 struct winbindd_domain *domain;
3415 char *freeit = NULL;
3419 || (data->data == NULL)
3420 || (data->length == 0)
3421 || (data->data[data->length-1] != '\0')) {
3422 DEBUG(1, ("invalid msg_ip_dropped message: not a valid "
3427 addr = (char *)data->data;
3428 DEBUG(10, ("IP %s dropped\n", addr));
3430 if (!is_ipaddress(addr)) {
3433 * Some code sends us ip addresses with the /netmask
3436 slash = strchr(addr, '/');
3437 if (slash == NULL) {
3438 DEBUG(1, ("invalid msg_ip_dropped message: %s",
3442 freeit = talloc_strndup(talloc_tos(), addr, slash-addr);
3443 if (freeit == NULL) {
3444 DEBUG(1, ("talloc failed\n"));
3448 DEBUG(10, ("Stripped /netmask to IP %s\n", addr));
3451 for (domain = domain_list(); domain != NULL; domain = domain->next) {
3452 char sockaddr[INET6_ADDRSTRLEN];
3454 if (!cli_state_is_connected(domain->conn.cli)) {
3458 print_sockaddr(sockaddr, sizeof(sockaddr),
3459 smbXcli_conn_local_sockaddr(domain->conn.cli->conn));
3461 if (strequal(sockaddr, addr)) {
3462 smbXcli_conn_disconnect(domain->conn.cli->conn, NT_STATUS_OK);
3465 TALLOC_FREE(freeit);