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/clidgram.h"
75 #include "../libcli/security/security.h"
80 #define DBGC_CLASS DBGC_WINBIND
84 struct sockaddr_storage ss;
87 extern struct winbindd_methods reconnect_methods;
88 extern bool override_logfile;
90 static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain);
91 static void set_dc_type_and_flags( struct winbindd_domain *domain );
92 static bool get_dcs(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
93 struct dc_name_ip **dcs, int *num_dcs);
95 /****************************************************************
96 Child failed to find DC's. Reschedule check.
97 ****************************************************************/
99 static void msg_failed_to_go_online(struct messaging_context *msg,
102 struct server_id server_id,
105 struct winbindd_domain *domain;
106 const char *domainname = (const char *)data->data;
108 if (data->data == NULL || data->length == 0) {
112 DEBUG(5,("msg_fail_to_go_online: received for domain %s.\n", domainname));
114 for (domain = domain_list(); domain; domain = domain->next) {
115 if (domain->internal) {
119 if (strequal(domain->name, domainname)) {
120 if (domain->online) {
121 /* We're already online, ignore. */
122 DEBUG(5,("msg_fail_to_go_online: domain %s "
123 "already online.\n", domainname));
127 /* Reschedule the online check. */
128 set_domain_offline(domain);
134 /****************************************************************
135 Actually cause a reconnect from a message.
136 ****************************************************************/
138 static void msg_try_to_go_online(struct messaging_context *msg,
141 struct server_id server_id,
144 struct winbindd_domain *domain;
145 const char *domainname = (const char *)data->data;
147 if (data->data == NULL || data->length == 0) {
151 DEBUG(5,("msg_try_to_go_online: received for domain %s.\n", domainname));
153 for (domain = domain_list(); domain; domain = domain->next) {
154 if (domain->internal) {
158 if (strequal(domain->name, domainname)) {
160 if (domain->online) {
161 /* We're already online, ignore. */
162 DEBUG(5,("msg_try_to_go_online: domain %s "
163 "already online.\n", domainname));
167 /* This call takes care of setting the online
168 flag to true if we connected, or re-adding
169 the offline handler if false. Bypasses online
170 check so always does network calls. */
172 init_dc_connection_network(domain);
178 /****************************************************************
179 Fork a child to try and contact a DC. Do this as contacting a
180 DC requires blocking lookups and we don't want to block our
182 ****************************************************************/
184 static bool fork_child_dc_connect(struct winbindd_domain *domain)
186 struct dc_name_ip *dcs = NULL;
188 TALLOC_CTX *mem_ctx = NULL;
189 pid_t parent_pid = sys_getpid();
193 if (domain->dc_probe_pid != (pid_t)-1) {
195 * We might already have a DC probe
196 * child working, check.
198 if (process_exists_by_pid(domain->dc_probe_pid)) {
199 DEBUG(10,("fork_child_dc_connect: pid %u already "
200 "checking for DC's.\n",
201 (unsigned int)domain->dc_probe_pid));
204 domain->dc_probe_pid = (pid_t)-1;
207 domain->dc_probe_pid = sys_fork();
209 if (domain->dc_probe_pid == (pid_t)-1) {
210 DEBUG(0, ("fork_child_dc_connect: Could not fork: %s\n", strerror(errno)));
214 if (domain->dc_probe_pid != (pid_t)0) {
216 messaging_register(winbind_messaging_context(), NULL,
217 MSG_WINBIND_TRY_TO_GO_ONLINE,
218 msg_try_to_go_online);
219 messaging_register(winbind_messaging_context(), NULL,
220 MSG_WINBIND_FAILED_TO_GO_ONLINE,
221 msg_failed_to_go_online);
227 /* Leave messages blocked - we will never process one. */
229 if (!override_logfile) {
230 if (asprintf(&lfile, "%s/log.winbindd-dc-connect", get_dyn_LOGFILEBASE()) == -1) {
231 DEBUG(0, ("fork_child_dc_connect: out of memory.\n"));
236 status = winbindd_reinit_after_fork(NULL, lfile);
237 if (!NT_STATUS_IS_OK(status)) {
238 DEBUG(1, ("winbindd_reinit_after_fork failed: %s\n",
240 messaging_send_buf(winbind_messaging_context(),
241 pid_to_procid(parent_pid),
242 MSG_WINBIND_FAILED_TO_GO_ONLINE,
243 (uint8 *)domain->name,
244 strlen(domain->name)+1);
249 mem_ctx = talloc_init("fork_child_dc_connect");
251 DEBUG(0,("talloc_init failed.\n"));
252 messaging_send_buf(winbind_messaging_context(),
253 pid_to_procid(parent_pid),
254 MSG_WINBIND_FAILED_TO_GO_ONLINE,
255 (uint8 *)domain->name,
256 strlen(domain->name)+1);
260 if ((!get_dcs(mem_ctx, domain, &dcs, &num_dcs)) || (num_dcs == 0)) {
261 /* Still offline ? Can't find DC's. */
262 messaging_send_buf(winbind_messaging_context(),
263 pid_to_procid(parent_pid),
264 MSG_WINBIND_FAILED_TO_GO_ONLINE,
265 (uint8 *)domain->name,
266 strlen(domain->name)+1);
270 /* We got a DC. Send a message to our parent to get it to
271 try and do the same. */
273 messaging_send_buf(winbind_messaging_context(),
274 pid_to_procid(parent_pid),
275 MSG_WINBIND_TRY_TO_GO_ONLINE,
276 (uint8 *)domain->name,
277 strlen(domain->name)+1);
281 /****************************************************************
282 Handler triggered if we're offline to try and detect a DC.
283 ****************************************************************/
285 static void check_domain_online_handler(struct event_context *ctx,
286 struct timed_event *te,
290 struct winbindd_domain *domain =
291 (struct winbindd_domain *)private_data;
293 DEBUG(10,("check_domain_online_handler: called for domain "
294 "%s (online = %s)\n", domain->name,
295 domain->online ? "True" : "False" ));
297 TALLOC_FREE(domain->check_online_event);
299 /* Are we still in "startup" mode ? */
301 if (domain->startup && (time_mono(NULL) > domain->startup_time + 30)) {
302 /* No longer in "startup" mode. */
303 DEBUG(10,("check_domain_online_handler: domain %s no longer in 'startup' mode.\n",
305 domain->startup = False;
308 /* We've been told to stay offline, so stay
311 if (get_global_winbindd_state_offline()) {
312 DEBUG(10,("check_domain_online_handler: domain %s remaining globally offline\n",
317 /* Fork a child to test if it can contact a DC.
318 If it can then send ourselves a message to
319 cause a reconnect. */
321 fork_child_dc_connect(domain);
324 /****************************************************************
325 If we're still offline setup the timeout check.
326 ****************************************************************/
328 static void calc_new_online_timeout_check(struct winbindd_domain *domain)
330 int wbr = lp_winbind_reconnect_delay();
332 if (domain->startup) {
333 domain->check_online_timeout = 10;
334 } else if (domain->check_online_timeout < wbr) {
335 domain->check_online_timeout = wbr;
339 /****************************************************************
340 Set domain offline and also add handler to put us back online
342 ****************************************************************/
344 void set_domain_offline(struct winbindd_domain *domain)
346 DEBUG(10,("set_domain_offline: called for domain %s\n",
349 TALLOC_FREE(domain->check_online_event);
351 if (domain->internal) {
352 DEBUG(3,("set_domain_offline: domain %s is internal - logic error.\n",
357 domain->online = False;
359 /* Offline domains are always initialized. They're
360 re-initialized when they go back online. */
362 domain->initialized = True;
364 /* We only add the timeout handler that checks and
365 allows us to go back online when we've not
366 been told to remain offline. */
368 if (get_global_winbindd_state_offline()) {
369 DEBUG(10,("set_domain_offline: domain %s remaining globally offline\n",
374 /* If we're in startup mode, check again in 10 seconds, not in
375 lp_winbind_reconnect_delay() seconds (which is 30 seconds by default). */
377 calc_new_online_timeout_check(domain);
379 domain->check_online_event = event_add_timed(winbind_event_context(),
381 timeval_current_ofs(domain->check_online_timeout,0),
382 check_domain_online_handler,
385 /* The above *has* to succeed for winbindd to work. */
386 if (!domain->check_online_event) {
387 smb_panic("set_domain_offline: failed to add online handler");
390 DEBUG(10,("set_domain_offline: added event handler for domain %s\n",
393 /* Send an offline message to the idmap child when our
394 primary domain goes offline */
396 if ( domain->primary ) {
397 struct winbindd_child *idmap = idmap_child();
399 if ( idmap->pid != 0 ) {
400 messaging_send_buf(winbind_messaging_context(),
401 pid_to_procid(idmap->pid),
403 (uint8 *)domain->name,
404 strlen(domain->name)+1);
411 /****************************************************************
412 Set domain online - if allowed.
413 ****************************************************************/
415 static void set_domain_online(struct winbindd_domain *domain)
417 DEBUG(10,("set_domain_online: called for domain %s\n",
420 if (domain->internal) {
421 DEBUG(3,("set_domain_online: domain %s is internal - logic error.\n",
426 if (get_global_winbindd_state_offline()) {
427 DEBUG(10,("set_domain_online: domain %s remaining globally offline\n",
432 winbindd_set_locator_kdc_envs(domain);
434 /* If we are waiting to get a krb5 ticket, trigger immediately. */
435 ccache_regain_all_now();
437 /* Ok, we're out of any startup mode now... */
438 domain->startup = False;
440 if (domain->online == False) {
441 /* We were offline - now we're online. We default to
442 using the MS-RPC backend if we started offline,
443 and if we're going online for the first time we
444 should really re-initialize the backends and the
445 checks to see if we're talking to an AD or NT domain.
448 domain->initialized = False;
450 /* 'reconnect_methods' is the MS-RPC backend. */
451 if (domain->backend == &reconnect_methods) {
452 domain->backend = NULL;
456 /* Ensure we have no online timeout checks. */
457 domain->check_online_timeout = 0;
458 TALLOC_FREE(domain->check_online_event);
460 /* Ensure we ignore any pending child messages. */
461 messaging_deregister(winbind_messaging_context(),
462 MSG_WINBIND_TRY_TO_GO_ONLINE, NULL);
463 messaging_deregister(winbind_messaging_context(),
464 MSG_WINBIND_FAILED_TO_GO_ONLINE, NULL);
466 domain->online = True;
468 /* Send an online message to the idmap child when our
469 primary domain comes online */
471 if ( domain->primary ) {
472 struct winbindd_child *idmap = idmap_child();
474 if ( idmap->pid != 0 ) {
475 messaging_send_buf(winbind_messaging_context(),
476 pid_to_procid(idmap->pid),
478 (uint8 *)domain->name,
479 strlen(domain->name)+1);
486 /****************************************************************
487 Requested to set a domain online.
488 ****************************************************************/
490 void set_domain_online_request(struct winbindd_domain *domain)
494 DEBUG(10,("set_domain_online_request: called for domain %s\n",
497 if (get_global_winbindd_state_offline()) {
498 DEBUG(10,("set_domain_online_request: domain %s remaining globally offline\n",
503 if (domain->internal) {
504 DEBUG(10, ("set_domain_online_request: Internal domains are "
509 /* We've been told it's safe to go online and
510 try and connect to a DC. But I don't believe it
511 because network manager seems to lie.
512 Wait at least 5 seconds. Heuristics suck... */
517 /* Go into "startup" mode again. */
518 domain->startup_time = time_mono(NULL);
519 domain->startup = True;
523 if (!domain->check_online_event) {
524 /* If we've come from being globally offline we
525 don't have a check online event handler set.
526 We need to add one now we're trying to go
529 DEBUG(10,("set_domain_online_request: domain %s was globally offline.\n",
533 TALLOC_FREE(domain->check_online_event);
535 domain->check_online_event = event_add_timed(winbind_event_context(),
538 check_domain_online_handler,
541 /* The above *has* to succeed for winbindd to work. */
542 if (!domain->check_online_event) {
543 smb_panic("set_domain_online_request: failed to add online handler");
547 /****************************************************************
548 Add -ve connection cache entries for domain and realm.
549 ****************************************************************/
551 static void winbind_add_failed_connection_entry(
552 const struct winbindd_domain *domain,
556 add_failed_connection_entry(domain->name, server, result);
557 /* If this was the saf name for the last thing we talked to,
559 saf_delete(domain->name);
560 if (*domain->alt_name) {
561 add_failed_connection_entry(domain->alt_name, server, result);
562 saf_delete(domain->alt_name);
564 winbindd_unset_locator_kdc_env(domain);
567 /* Choose between anonymous or authenticated connections. We need to use
568 an authenticated connection if DCs have the RestrictAnonymous registry
569 entry set > 0, or the "Additional restrictions for anonymous
570 connections" set in the win2k Local Security Policy.
572 Caller to free() result in domain, username, password
575 static void cm_get_ipc_userpass(char **username, char **domain, char **password)
577 *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
578 *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
579 *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
581 if (*username && **username) {
583 if (!*domain || !**domain)
584 *domain = smb_xstrdup(lp_workgroup());
586 if (!*password || !**password)
587 *password = smb_xstrdup("");
589 DEBUG(3, ("cm_get_ipc_userpass: Retrieved auth-user from secrets.tdb [%s\\%s]\n",
590 *domain, *username));
593 DEBUG(3, ("cm_get_ipc_userpass: No auth-user defined\n"));
594 *username = smb_xstrdup("");
595 *domain = smb_xstrdup("");
596 *password = smb_xstrdup("");
600 static bool get_dc_name_via_netlogon(struct winbindd_domain *domain,
602 struct sockaddr_storage *dc_ss)
604 struct winbindd_domain *our_domain = NULL;
605 struct rpc_pipe_client *netlogon_pipe = NULL;
609 unsigned int orig_timeout;
610 const char *tmp = NULL;
612 struct dcerpc_binding_handle *b;
614 /* Hmmmm. We can only open one connection to the NETLOGON pipe at the
621 if (domain->primary) {
625 our_domain = find_our_domain();
627 if ((mem_ctx = talloc_init("get_dc_name_via_netlogon")) == NULL) {
631 result = cm_connect_netlogon(our_domain, &netlogon_pipe);
632 if (!NT_STATUS_IS_OK(result)) {
633 talloc_destroy(mem_ctx);
637 b = netlogon_pipe->binding_handle;
639 /* This call can take a long time - allow the server to time out.
640 35 seconds should do it. */
642 orig_timeout = rpccli_set_timeout(netlogon_pipe, 35000);
644 if (our_domain->active_directory) {
645 struct netr_DsRGetDCNameInfo *domain_info = NULL;
647 result = dcerpc_netr_DsRGetDCName(b,
656 if (NT_STATUS_IS_OK(result) && W_ERROR_IS_OK(werr)) {
658 mem_ctx, domain_info->dc_unc);
660 DEBUG(0, ("talloc_strdup failed\n"));
661 talloc_destroy(mem_ctx);
664 if (strlen(domain->alt_name) == 0) {
665 fstrcpy(domain->alt_name,
666 domain_info->domain_name);
668 if (strlen(domain->forest_name) == 0) {
669 fstrcpy(domain->forest_name,
670 domain_info->forest_name);
674 result = dcerpc_netr_GetAnyDCName(b, mem_ctx,
681 /* And restore our original timeout. */
682 rpccli_set_timeout(netlogon_pipe, orig_timeout);
684 if (!NT_STATUS_IS_OK(result)) {
685 DEBUG(10,("dcerpc_netr_GetAnyDCName failed: %s\n",
687 talloc_destroy(mem_ctx);
691 if (!W_ERROR_IS_OK(werr)) {
692 DEBUG(10,("dcerpc_netr_GetAnyDCName failed: %s\n",
694 talloc_destroy(mem_ctx);
698 /* dcerpc_netr_GetAnyDCName gives us a name with \\ */
699 p = strip_hostname(tmp);
703 talloc_destroy(mem_ctx);
705 DEBUG(10,("dcerpc_netr_GetAnyDCName returned %s\n", dcname));
707 if (!resolve_name(dcname, dc_ss, 0x20, true)) {
715 * Helper function to assemble trust password and account name
717 static NTSTATUS get_trust_creds(const struct winbindd_domain *domain,
718 char **machine_password,
719 char **machine_account,
720 char **machine_krb5_principal)
722 const char *account_name;
723 const char *name = NULL;
725 /* If we are a DC and this is not our own domain */
730 struct winbindd_domain *our_domain = find_our_domain();
733 return NT_STATUS_INVALID_SERVER_STATE;
735 name = our_domain->name;
738 if (!get_trust_pw_clear(name, machine_password,
739 &account_name, NULL))
741 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
744 if ((machine_account != NULL) &&
745 (asprintf(machine_account, "%s$", account_name) == -1))
747 return NT_STATUS_NO_MEMORY;
750 /* For now assume our machine account only exists in our domain */
752 if (machine_krb5_principal != NULL)
754 struct winbindd_domain *our_domain = find_our_domain();
757 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
760 if (asprintf(machine_krb5_principal, "%s$@%s",
761 account_name, our_domain->alt_name) == -1)
763 return NT_STATUS_NO_MEMORY;
766 strupper_m(*machine_krb5_principal);
772 /************************************************************************
773 Given a fd with a just-connected TCP connection to a DC, open a connection
775 ************************************************************************/
777 static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
779 const char *controller,
780 struct cli_state **cli,
783 char *machine_password = NULL;
784 char *machine_krb5_principal = NULL;
785 char *machine_account = NULL;
786 char *ipc_username = NULL;
787 char *ipc_domain = NULL;
788 char *ipc_password = NULL;
790 struct named_mutex *mutex;
792 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
794 struct sockaddr peeraddr;
795 socklen_t peeraddr_len;
797 struct sockaddr_in *peeraddr_in =
798 (struct sockaddr_in *)(void *)&peeraddr;
800 DEBUG(10,("cm_prepare_connection: connecting to DC %s for domain %s\n",
801 controller, domain->name ));
805 mutex = grab_named_mutex(talloc_tos(), controller,
806 WINBIND_SERVER_MUTEX_WAIT_TIME);
808 DEBUG(0,("cm_prepare_connection: mutex grab failed for %s\n",
810 result = NT_STATUS_POSSIBLE_DEADLOCK;
814 if ((*cli = cli_initialise()) == NULL) {
815 DEBUG(1, ("Could not cli_initialize\n"));
816 result = NT_STATUS_NO_MEMORY;
820 (*cli)->timeout = 10000; /* 10 seconds */
822 (*cli)->desthost = talloc_strdup((*cli), controller);
823 if ((*cli)->desthost == NULL) {
824 result = NT_STATUS_NO_MEMORY;
828 (*cli)->use_kerberos = True;
830 peeraddr_len = sizeof(peeraddr);
832 if ((getpeername((*cli)->fd, &peeraddr, &peeraddr_len) != 0)) {
833 DEBUG(0,("cm_prepare_connection: getpeername failed with: %s\n",
835 result = NT_STATUS_UNSUCCESSFUL;
839 if ((peeraddr_len != sizeof(struct sockaddr_in))
841 && (peeraddr_len != sizeof(struct sockaddr_in6))
844 DEBUG(0,("cm_prepare_connection: got unexpected peeraddr len %d\n",
846 result = NT_STATUS_UNSUCCESSFUL;
850 if ((peeraddr_in->sin_family != PF_INET)
852 && (peeraddr_in->sin_family != PF_INET6)
855 DEBUG(0,("cm_prepare_connection: got unexpected family %d\n",
856 peeraddr_in->sin_family));
857 result = NT_STATUS_UNSUCCESSFUL;
861 result = cli_negprot(*cli);
863 if (!NT_STATUS_IS_OK(result)) {
864 DEBUG(1, ("cli_negprot failed: %s\n", nt_errstr(result)));
868 if (!is_dc_trusted_domain_situation(domain->name) &&
869 (*cli)->protocol >= PROTOCOL_NT1 &&
870 (*cli)->capabilities & CAP_EXTENDED_SECURITY)
872 ADS_STATUS ads_status;
874 result = get_trust_creds(domain, &machine_password,
876 &machine_krb5_principal);
877 if (!NT_STATUS_IS_OK(result)) {
881 if (lp_security() == SEC_ADS) {
883 /* Try a krb5 session */
885 (*cli)->use_kerberos = True;
886 DEBUG(5, ("connecting to %s from %s with kerberos principal "
887 "[%s] and realm [%s]\n", controller, global_myname(),
888 machine_krb5_principal, domain->alt_name));
890 winbindd_set_locator_kdc_envs(domain);
892 ads_status = cli_session_setup_spnego(*cli,
893 machine_krb5_principal,
898 if (!ADS_ERR_OK(ads_status)) {
899 DEBUG(4,("failed kerberos session setup with %s\n",
900 ads_errstr(ads_status)));
903 result = ads_ntstatus(ads_status);
904 if (NT_STATUS_IS_OK(result)) {
905 /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
906 result = cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
907 if (!NT_STATUS_IS_OK(result)) {
910 goto session_setup_done;
914 /* Fall back to non-kerberos session setup using NTLMSSP SPNEGO with the machine account. */
915 (*cli)->use_kerberos = False;
917 DEBUG(5, ("connecting to %s from %s with username "
918 "[%s]\\[%s]\n", controller, global_myname(),
919 lp_workgroup(), machine_account));
921 ads_status = cli_session_setup_spnego(*cli,
926 if (!ADS_ERR_OK(ads_status)) {
927 DEBUG(4, ("authenticated session setup failed with %s\n",
928 ads_errstr(ads_status)));
931 result = ads_ntstatus(ads_status);
932 if (NT_STATUS_IS_OK(result)) {
933 /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
934 result = cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
935 if (!NT_STATUS_IS_OK(result)) {
938 goto session_setup_done;
942 /* Fall back to non-kerberos session setup with auth_user */
944 (*cli)->use_kerberos = False;
946 cm_get_ipc_userpass(&ipc_username, &ipc_domain, &ipc_password);
948 if ((((*cli)->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) != 0) &&
949 (strlen(ipc_username) > 0)) {
951 /* Only try authenticated if we have a username */
953 DEBUG(5, ("connecting to %s from %s with username "
954 "[%s]\\[%s]\n", controller, global_myname(),
955 ipc_domain, ipc_username));
957 if (NT_STATUS_IS_OK(cli_session_setup(
959 ipc_password, strlen(ipc_password)+1,
960 ipc_password, strlen(ipc_password)+1,
962 /* Successful logon with given username. */
963 result = cli_init_creds(*cli, ipc_username, ipc_domain, ipc_password);
964 if (!NT_STATUS_IS_OK(result)) {
967 goto session_setup_done;
969 DEBUG(4, ("authenticated session setup with user %s\\%s failed.\n",
970 ipc_domain, ipc_username ));
976 /* Fall back to anonymous connection, this might fail later */
977 DEBUG(10,("cm_prepare_connection: falling back to anonymous "
978 "connection for DC %s\n",
981 if (NT_STATUS_IS_OK(cli_session_setup(*cli, "", NULL, 0,
983 DEBUG(5, ("Connected anonymously\n"));
984 result = cli_init_creds(*cli, "", "", "");
985 if (!NT_STATUS_IS_OK(result)) {
988 goto session_setup_done;
991 result = cli_nt_error(*cli);
993 if (NT_STATUS_IS_OK(result))
994 result = NT_STATUS_UNSUCCESSFUL;
996 /* We can't session setup */
1002 /* cache the server name for later connections */
1004 saf_store( domain->name, (*cli)->desthost );
1005 if (domain->alt_name && (*cli)->use_kerberos) {
1006 saf_store( domain->alt_name, (*cli)->desthost );
1009 winbindd_set_locator_kdc_envs(domain);
1011 result = cli_tcon_andx(*cli, "IPC$", "IPC", "", 0);
1013 if (!NT_STATUS_IS_OK(result)) {
1014 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(result)));
1021 /* set the domain if empty; needed for schannel connections */
1022 if ( !(*cli)->domain[0] ) {
1023 result = cli_set_domain((*cli), domain->name);
1024 if (!NT_STATUS_IS_OK(result)) {
1029 result = NT_STATUS_OK;
1033 SAFE_FREE(machine_account);
1034 SAFE_FREE(machine_password);
1035 SAFE_FREE(machine_krb5_principal);
1036 SAFE_FREE(ipc_username);
1037 SAFE_FREE(ipc_domain);
1038 SAFE_FREE(ipc_password);
1040 if (!NT_STATUS_IS_OK(result)) {
1041 winbind_add_failed_connection_entry(domain, controller, result);
1042 if ((*cli) != NULL) {
1051 /*******************************************************************
1052 Add a dcname and sockaddr_storage pair to the end of a dc_name_ip
1055 Keeps the list unique by not adding duplicate entries.
1057 @param[in] mem_ctx talloc memory context to allocate from
1058 @param[in] domain_name domain of the DC
1059 @param[in] dcname name of the DC to add to the list
1060 @param[in] pss Internet address and port pair to add to the list
1061 @param[in,out] dcs array of dc_name_ip structures to add to
1062 @param[in,out] num_dcs number of dcs returned in the dcs array
1063 @return true if the list was added to, false otherwise
1064 *******************************************************************/
1066 static bool add_one_dc_unique(TALLOC_CTX *mem_ctx, const char *domain_name,
1067 const char *dcname, struct sockaddr_storage *pss,
1068 struct dc_name_ip **dcs, int *num)
1072 if (!NT_STATUS_IS_OK(check_negative_conn_cache(domain_name, dcname))) {
1073 DEBUG(10, ("DC %s was in the negative conn cache\n", dcname));
1077 /* Make sure there's no duplicates in the list */
1078 for (i=0; i<*num; i++)
1080 (struct sockaddr *)(void *)&(*dcs)[i].ss,
1081 (struct sockaddr *)(void *)pss))
1084 *dcs = TALLOC_REALLOC_ARRAY(mem_ctx, *dcs, struct dc_name_ip, (*num)+1);
1089 fstrcpy((*dcs)[*num].name, dcname);
1090 (*dcs)[*num].ss = *pss;
1095 static bool add_sockaddr_to_array(TALLOC_CTX *mem_ctx,
1096 struct sockaddr_storage *pss, uint16 port,
1097 struct sockaddr_storage **addrs, int *num)
1099 *addrs = TALLOC_REALLOC_ARRAY(mem_ctx, *addrs, struct sockaddr_storage, (*num)+1);
1101 if (*addrs == NULL) {
1106 (*addrs)[*num] = *pss;
1107 set_sockaddr_port((struct sockaddr *)&(*addrs)[*num], port);
1113 /*******************************************************************
1114 convert an ip to a name
1115 *******************************************************************/
1117 static bool dcip_to_name(TALLOC_CTX *mem_ctx,
1118 const struct winbindd_domain *domain,
1119 struct sockaddr_storage *pss,
1122 struct ip_service ip_list;
1123 uint32_t nt_version = NETLOGON_NT_VERSION_1;
1125 const char *dc_name;
1131 /* For active directory servers, try to get the ldap server name.
1132 None of these failures should be considered critical for now */
1134 if (lp_security() == SEC_ADS) {
1136 ADS_STATUS ads_status;
1137 char addr[INET6_ADDRSTRLEN];
1139 print_sockaddr(addr, sizeof(addr), pss);
1141 ads = ads_init(domain->alt_name, domain->name, addr);
1142 ads->auth.flags |= ADS_AUTH_NO_BIND;
1144 ads_status = ads_connect(ads);
1145 if (ADS_ERR_OK(ads_status)) {
1146 /* We got a cldap packet. */
1147 fstrcpy(name, ads->config.ldap_server_name);
1148 namecache_store(name, 0x20, 1, &ip_list);
1150 DEBUG(10,("dcip_to_name: flags = 0x%x\n", (unsigned int)ads->config.flags));
1152 if (domain->primary && (ads->config.flags & NBT_SERVER_KDC)) {
1153 if (ads_closest_dc(ads)) {
1154 char *sitename = sitename_fetch(ads->config.realm);
1156 /* We're going to use this KDC for this realm/domain.
1157 If we are using sites, then force the krb5 libs
1160 create_local_private_krb5_conf_for_domain(domain->alt_name,
1166 SAFE_FREE(sitename);
1168 /* use an off site KDC */
1169 create_local_private_krb5_conf_for_domain(domain->alt_name,
1175 winbindd_set_locator_kdc_envs(domain);
1177 /* Ensure we contact this DC also. */
1178 saf_store( domain->name, name);
1179 saf_store( domain->alt_name, name);
1182 ads_destroy( &ads );
1186 ads_destroy( &ads );
1190 status = nbt_getdc(winbind_messaging_context(), pss, domain->name,
1191 &domain->sid, nt_version, mem_ctx, &nt_version,
1193 if (NT_STATUS_IS_OK(status)) {
1194 fstrcpy(name, dc_name);
1195 namecache_store(name, 0x20, 1, &ip_list);
1199 /* try node status request */
1201 if ( name_status_find(domain->name, 0x1c, 0x20, pss, name) ) {
1202 namecache_store(name, 0x20, 1, &ip_list);
1208 /*******************************************************************
1209 Retrieve a list of IP addresses for domain controllers.
1211 The array is sorted in the preferred connection order.
1213 @param[in] mem_ctx talloc memory context to allocate from
1214 @param[in] domain domain to retrieve DCs for
1215 @param[out] dcs array of dcs that will be returned
1216 @param[out] num_dcs number of dcs returned in the dcs array
1218 *******************************************************************/
1220 static bool get_dcs(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
1221 struct dc_name_ip **dcs, int *num_dcs)
1224 struct sockaddr_storage ss;
1225 struct ip_service *ip_list = NULL;
1226 int iplist_size = 0;
1229 enum security_types sec = (enum security_types)lp_security();
1231 is_our_domain = strequal(domain->name, lp_workgroup());
1233 /* If not our domain, get the preferred DC, by asking our primary DC */
1235 && get_dc_name_via_netlogon(domain, dcname, &ss)
1236 && add_one_dc_unique(mem_ctx, domain->name, dcname, &ss, dcs,
1239 char addr[INET6_ADDRSTRLEN];
1240 print_sockaddr(addr, sizeof(addr), &ss);
1241 DEBUG(10, ("Retrieved DC %s at %s via netlogon\n",
1246 if (sec == SEC_ADS) {
1247 char *sitename = NULL;
1249 /* We need to make sure we know the local site before
1250 doing any DNS queries, as this will restrict the
1251 get_sorted_dc_list() call below to only fetching
1252 DNS records for the correct site. */
1254 /* Find any DC to get the site record.
1255 We deliberately don't care about the
1258 get_dc_name(domain->name, domain->alt_name, dcname, &ss);
1260 sitename = sitename_fetch(domain->alt_name);
1263 /* Do the site-specific AD dns lookup first. */
1264 get_sorted_dc_list(domain->alt_name, sitename, &ip_list,
1265 &iplist_size, True);
1267 /* Add ips to the DC array. We don't look up the name
1268 of the DC in this function, but we fill in the char*
1269 of the ip now to make the failed connection cache
1271 for ( i=0; i<iplist_size; i++ ) {
1272 char addr[INET6_ADDRSTRLEN];
1273 print_sockaddr(addr, sizeof(addr),
1275 add_one_dc_unique(mem_ctx,
1284 SAFE_FREE(sitename);
1288 /* Now we add DCs from the main AD DNS lookup. */
1289 get_sorted_dc_list(domain->alt_name, NULL, &ip_list,
1290 &iplist_size, True);
1292 for ( i=0; i<iplist_size; i++ ) {
1293 char addr[INET6_ADDRSTRLEN];
1294 print_sockaddr(addr, sizeof(addr),
1296 add_one_dc_unique(mem_ctx,
1308 /* Try standard netbios queries if no ADS */
1309 if (*num_dcs == 0) {
1310 get_sorted_dc_list(domain->name, NULL, &ip_list, &iplist_size,
1313 for ( i=0; i<iplist_size; i++ ) {
1314 char addr[INET6_ADDRSTRLEN];
1315 print_sockaddr(addr, sizeof(addr),
1317 add_one_dc_unique(mem_ctx,
1332 /*******************************************************************
1333 Find and make a connection to a DC in the given domain.
1335 @param[in] mem_ctx talloc memory context to allocate from
1336 @param[in] domain domain to find a dc in
1337 @param[out] dcname NetBIOS or FQDN of DC that's connected to
1338 @param[out] pss DC Internet address and port
1339 @param[out] fd fd of the open socket connected to the newly found dc
1340 @return true when a DC connection is made, false otherwise
1341 *******************************************************************/
1343 static bool find_new_dc(TALLOC_CTX *mem_ctx,
1344 struct winbindd_domain *domain,
1345 fstring dcname, struct sockaddr_storage *pss, int *fd)
1347 struct dc_name_ip *dcs = NULL;
1350 const char **dcnames = NULL;
1351 int num_dcnames = 0;
1353 struct sockaddr_storage *addrs = NULL;
1364 if (!get_dcs(mem_ctx, domain, &dcs, &num_dcs) || (num_dcs == 0))
1367 for (i=0; i<num_dcs; i++) {
1369 if (!add_string_to_array(mem_ctx, dcs[i].name,
1370 &dcnames, &num_dcnames)) {
1373 if (!add_sockaddr_to_array(mem_ctx, &dcs[i].ss, 445,
1374 &addrs, &num_addrs)) {
1379 if ((num_dcnames == 0) || (num_dcnames != num_addrs))
1382 if ((addrs == NULL) || (dcnames == NULL))
1385 status = smbsock_any_connect(addrs, dcnames, NULL, NULL, NULL,
1386 num_addrs, 0, 10, fd, &fd_index, NULL);
1387 if (!NT_STATUS_IS_OK(status)) {
1388 for (i=0; i<num_dcs; i++) {
1389 char ab[INET6_ADDRSTRLEN];
1390 print_sockaddr(ab, sizeof(ab), &dcs[i].ss);
1391 DEBUG(10, ("find_new_dc: smbsock_any_connect failed for "
1392 "domain %s address %s. Error was %s\n",
1393 domain->name, ab, nt_errstr(status) ));
1394 winbind_add_failed_connection_entry(domain,
1395 dcs[i].name, NT_STATUS_UNSUCCESSFUL);
1400 *pss = addrs[fd_index];
1402 if (*dcnames[fd_index] != '\0' && !is_ipaddress(dcnames[fd_index])) {
1403 /* Ok, we've got a name for the DC */
1404 fstrcpy(dcname, dcnames[fd_index]);
1408 /* Try to figure out the name */
1409 if (dcip_to_name(mem_ctx, domain, pss, dcname)) {
1413 /* We can not continue without the DC's name */
1414 winbind_add_failed_connection_entry(domain, dcs[fd_index].name,
1415 NT_STATUS_UNSUCCESSFUL);
1417 /* Throw away all arrays as we're doing this again. */
1421 TALLOC_FREE(dcnames);
1433 static char *current_dc_key(TALLOC_CTX *mem_ctx, const char *domain_name)
1435 return talloc_asprintf_strupper_m(mem_ctx, "CURRENT_DCNAME/%s",
1439 static void store_current_dc_in_gencache(const char *domain_name,
1440 const char *dc_name,
1441 struct cli_state *cli)
1443 char addr[INET6_ADDRSTRLEN];
1450 if (cli->fd == -1) {
1453 get_peer_addr(cli->fd, addr, sizeof(addr));
1455 key = current_dc_key(talloc_tos(), domain_name);
1460 value = talloc_asprintf(talloc_tos(), "%s %s", addr, dc_name);
1461 if (value == NULL) {
1465 gencache_set(key, value, 0x7fffffff);
1471 bool fetch_current_dc_from_gencache(TALLOC_CTX *mem_ctx,
1472 const char *domain_name,
1473 char **p_dc_name, char **p_dc_ip)
1475 char *key, *value, *p;
1477 char *dc_name = NULL;
1480 key = current_dc_key(talloc_tos(), domain_name);
1484 if (!gencache_get(key, &value, NULL)) {
1487 p = strchr(value, ' ');
1491 dc_ip = talloc_strndup(mem_ctx, value, p - value);
1492 if (dc_ip == NULL) {
1495 dc_name = talloc_strdup(mem_ctx, p+1);
1496 if (dc_name == NULL) {
1500 if (p_dc_ip != NULL) {
1504 if (p_dc_name != NULL) {
1505 *p_dc_name = dc_name;
1510 TALLOC_FREE(dc_name);
1516 static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
1517 struct winbindd_cm_conn *new_conn)
1519 TALLOC_CTX *mem_ctx;
1521 char *saf_servername = saf_fetch( domain->name );
1524 if ((mem_ctx = talloc_init("cm_open_connection")) == NULL) {
1525 SAFE_FREE(saf_servername);
1526 set_domain_offline(domain);
1527 return NT_STATUS_NO_MEMORY;
1530 /* we have to check the server affinity cache here since
1531 later we select a DC based on response time and not preference */
1533 /* Check the negative connection cache
1534 before talking to it. It going down may have
1535 triggered the reconnection. */
1537 if ( saf_servername && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, saf_servername))) {
1539 DEBUG(10,("cm_open_connection: saf_servername is '%s' for domain %s\n",
1540 saf_servername, domain->name ));
1542 /* convert an ip address to a name */
1543 if (is_ipaddress( saf_servername ) ) {
1545 struct sockaddr_storage ss;
1547 if (!interpret_string_addr(&ss, saf_servername,
1549 return NT_STATUS_UNSUCCESSFUL;
1551 if (dcip_to_name(mem_ctx, domain, &ss, saf_name )) {
1552 strlcpy(domain->dcname, saf_name, sizeof(domain->dcname));
1554 winbind_add_failed_connection_entry(
1555 domain, saf_servername,
1556 NT_STATUS_UNSUCCESSFUL);
1559 fstrcpy( domain->dcname, saf_servername );
1562 SAFE_FREE( saf_servername );
1565 for (retries = 0; retries < 3; retries++) {
1569 result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1571 DEBUG(10,("cm_open_connection: dcname is '%s' for domain %s\n",
1572 domain->dcname, domain->name ));
1575 && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, domain->dcname))
1576 && (resolve_name(domain->dcname, &domain->dcaddr, 0x20, true)))
1580 status = smbsock_connect(&domain->dcaddr, 0,
1583 if (!NT_STATUS_IS_OK(status)) {
1589 && !find_new_dc(mem_ctx, domain, domain->dcname, &domain->dcaddr, &fd))
1591 /* This is the one place where we will
1592 set the global winbindd offline state
1593 to true, if a "WINBINDD_OFFLINE" entry
1594 is found in the winbindd cache. */
1595 set_global_winbindd_state_offline();
1599 new_conn->cli = NULL;
1601 result = cm_prepare_connection(domain, fd, domain->dcname,
1602 &new_conn->cli, &retry);
1608 if (NT_STATUS_IS_OK(result)) {
1610 winbindd_set_locator_kdc_envs(domain);
1612 if (domain->online == False) {
1613 /* We're changing state from offline to online. */
1614 set_global_winbindd_state_online();
1616 set_domain_online(domain);
1619 * Much as I hate global state, this seems to be the point
1620 * where we can be certain that we have a proper connection to
1621 * a DC. wbinfo --dc-info needs that information, store it in
1622 * gencache with a looong timeout. This will need revisiting
1623 * once we start to connect to multiple DCs, wbcDcInfo is
1624 * already prepared for that.
1626 store_current_dc_in_gencache(domain->name, domain->dcname,
1629 /* Ensure we setup the retry handler. */
1630 set_domain_offline(domain);
1633 talloc_destroy(mem_ctx);
1637 /* Close down all open pipes on a connection. */
1639 void invalidate_cm_connection(struct winbindd_cm_conn *conn)
1643 /* We're closing down a possibly dead
1644 connection. Don't have impossibly long (10s) timeouts. */
1647 cli_set_timeout(conn->cli, 1000); /* 1 second. */
1650 if (conn->samr_pipe != NULL) {
1651 if (is_valid_policy_hnd(&conn->sam_connect_handle)) {
1652 dcerpc_samr_Close(conn->samr_pipe->binding_handle,
1654 &conn->sam_connect_handle,
1657 TALLOC_FREE(conn->samr_pipe);
1658 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1660 cli_set_timeout(conn->cli, 500);
1664 if (conn->lsa_pipe != NULL) {
1665 if (is_valid_policy_hnd(&conn->lsa_policy)) {
1666 dcerpc_lsa_Close(conn->lsa_pipe->binding_handle,
1671 TALLOC_FREE(conn->lsa_pipe);
1672 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1674 cli_set_timeout(conn->cli, 500);
1678 if (conn->lsa_pipe_tcp != NULL) {
1679 if (is_valid_policy_hnd(&conn->lsa_policy)) {
1680 dcerpc_lsa_Close(conn->lsa_pipe_tcp->binding_handle,
1685 TALLOC_FREE(conn->lsa_pipe_tcp);
1686 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1688 cli_set_timeout(conn->cli, 500);
1692 if (conn->netlogon_pipe != NULL) {
1693 TALLOC_FREE(conn->netlogon_pipe);
1694 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1696 cli_set_timeout(conn->cli, 500);
1701 cli_shutdown(conn->cli);
1707 void close_conns_after_fork(void)
1709 struct winbindd_domain *domain;
1710 struct winbindd_cli_state *cli_state;
1712 for (domain = domain_list(); domain; domain = domain->next) {
1713 struct cli_state *cli = domain->conn.cli;
1716 * first close the low level SMB TCP connection
1717 * so that we don't generate any SMBclose
1718 * requests in invalidate_cm_connection()
1720 if (cli && cli->fd != -1) {
1721 close(domain->conn.cli->fd);
1722 domain->conn.cli->fd = -1;
1725 invalidate_cm_connection(&domain->conn);
1728 for (cli_state = winbindd_client_list();
1730 cli_state = cli_state->next) {
1731 if (cli_state->sock >= 0) {
1732 close(cli_state->sock);
1733 cli_state->sock = -1;
1738 static bool connection_ok(struct winbindd_domain *domain)
1742 ok = cli_state_is_connected(domain->conn.cli);
1744 DEBUG(3, ("connection_ok: Connection to %s for domain %s is not connected\n",
1745 domain->dcname, domain->name));
1749 if (domain->online == False) {
1750 DEBUG(3, ("connection_ok: Domain %s is offline\n", domain->name));
1757 /* Initialize a new connection up to the RPC BIND.
1758 Bypass online status check so always does network calls. */
1760 static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain)
1764 /* Internal connections never use the network. */
1765 if (domain->internal) {
1766 domain->initialized = True;
1767 return NT_STATUS_OK;
1770 if (!winbindd_can_contact_domain(domain)) {
1771 invalidate_cm_connection(&domain->conn);
1772 domain->initialized = True;
1773 return NT_STATUS_OK;
1776 if (connection_ok(domain)) {
1777 if (!domain->initialized) {
1778 set_dc_type_and_flags(domain);
1780 return NT_STATUS_OK;
1783 invalidate_cm_connection(&domain->conn);
1785 result = cm_open_connection(domain, &domain->conn);
1787 if (NT_STATUS_IS_OK(result) && !domain->initialized) {
1788 set_dc_type_and_flags(domain);
1794 NTSTATUS init_dc_connection(struct winbindd_domain *domain)
1796 if (domain->internal) {
1797 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1800 if (domain->initialized && !domain->online) {
1801 /* We check for online status elsewhere. */
1802 return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1805 return init_dc_connection_network(domain);
1808 static NTSTATUS init_dc_connection_rpc(struct winbindd_domain *domain)
1812 status = init_dc_connection(domain);
1813 if (!NT_STATUS_IS_OK(status)) {
1817 if (!domain->internal && domain->conn.cli == NULL) {
1818 /* happens for trusted domains without inbound trust */
1819 return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
1822 return NT_STATUS_OK;
1825 /******************************************************************************
1826 Set the trust flags (direction and forest location) for a domain
1827 ******************************************************************************/
1829 static bool set_dc_type_and_flags_trustinfo( struct winbindd_domain *domain )
1831 struct winbindd_domain *our_domain;
1832 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1834 struct netr_DomainTrustList trusts;
1836 uint32 flags = (NETR_TRUST_FLAG_IN_FOREST |
1837 NETR_TRUST_FLAG_OUTBOUND |
1838 NETR_TRUST_FLAG_INBOUND);
1839 struct rpc_pipe_client *cli;
1840 TALLOC_CTX *mem_ctx = NULL;
1841 struct dcerpc_binding_handle *b;
1843 DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s\n", domain->name ));
1845 /* Our primary domain doesn't need to worry about trust flags.
1846 Force it to go through the network setup */
1847 if ( domain->primary ) {
1851 our_domain = find_our_domain();
1853 if ( !connection_ok(our_domain) ) {
1854 DEBUG(3,("set_dc_type_and_flags_trustinfo: No connection to our domain!\n"));
1858 /* This won't work unless our domain is AD */
1860 if ( !our_domain->active_directory ) {
1864 /* Use DsEnumerateDomainTrusts to get us the trust direction
1867 result = cm_connect_netlogon(our_domain, &cli);
1869 if (!NT_STATUS_IS_OK(result)) {
1870 DEBUG(5, ("set_dc_type_and_flags_trustinfo: Could not open "
1871 "a connection to %s for PIPE_NETLOGON (%s)\n",
1872 domain->name, nt_errstr(result)));
1876 b = cli->binding_handle;
1878 if ( (mem_ctx = talloc_init("set_dc_type_and_flags_trustinfo")) == NULL ) {
1879 DEBUG(0,("set_dc_type_and_flags_trustinfo: talloc_init() failed!\n"));
1883 result = dcerpc_netr_DsrEnumerateDomainTrusts(b, mem_ctx,
1888 if (!NT_STATUS_IS_OK(result)) {
1889 DEBUG(0,("set_dc_type_and_flags_trustinfo: "
1890 "failed to query trusted domain list: %s\n",
1891 nt_errstr(result)));
1892 talloc_destroy(mem_ctx);
1895 if (!W_ERROR_IS_OK(werr)) {
1896 DEBUG(0,("set_dc_type_and_flags_trustinfo: "
1897 "failed to query trusted domain list: %s\n",
1899 talloc_destroy(mem_ctx);
1903 /* Now find the domain name and get the flags */
1905 for ( i=0; i<trusts.count; i++ ) {
1906 if ( strequal( domain->name, trusts.array[i].netbios_name) ) {
1907 domain->domain_flags = trusts.array[i].trust_flags;
1908 domain->domain_type = trusts.array[i].trust_type;
1909 domain->domain_trust_attribs = trusts.array[i].trust_attributes;
1911 if ( domain->domain_type == NETR_TRUST_TYPE_UPLEVEL )
1912 domain->active_directory = True;
1914 /* This flag is only set if the domain is *our*
1915 primary domain and the primary domain is in
1918 domain->native_mode = (domain->domain_flags & NETR_TRUST_FLAG_NATIVE);
1920 DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s is %sin "
1921 "native mode.\n", domain->name,
1922 domain->native_mode ? "" : "NOT "));
1924 DEBUG(5,("set_dc_type_and_flags_trustinfo: domain %s is %s"
1925 "running active directory.\n", domain->name,
1926 domain->active_directory ? "" : "NOT "));
1929 domain->initialized = True;
1935 talloc_destroy( mem_ctx );
1937 return domain->initialized;
1940 /******************************************************************************
1941 We can 'sense' certain things about the DC by it's replies to certain
1944 This tells us if this particular remote server is Active Directory, and if it
1946 ******************************************************************************/
1948 static void set_dc_type_and_flags_connect( struct winbindd_domain *domain )
1950 NTSTATUS status, result;
1952 TALLOC_CTX *mem_ctx = NULL;
1953 struct rpc_pipe_client *cli = NULL;
1954 struct policy_handle pol;
1955 union dssetup_DsRoleInfo info;
1956 union lsa_PolicyInformation *lsa_info = NULL;
1958 if (!connection_ok(domain)) {
1962 mem_ctx = talloc_init("set_dc_type_and_flags on domain %s\n",
1965 DEBUG(1, ("set_dc_type_and_flags_connect: talloc_init() failed\n"));
1969 DEBUG(5, ("set_dc_type_and_flags_connect: domain %s\n", domain->name ));
1971 status = cli_rpc_pipe_open_noauth(domain->conn.cli,
1972 &ndr_table_dssetup.syntax_id,
1975 if (!NT_STATUS_IS_OK(status)) {
1976 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
1977 "PI_DSSETUP on domain %s: (%s)\n",
1978 domain->name, nt_errstr(status)));
1980 /* if this is just a non-AD domain we need to continue
1981 * identifying so that we can in the end return with
1982 * domain->initialized = True - gd */
1987 status = dcerpc_dssetup_DsRoleGetPrimaryDomainInformation(cli->binding_handle, mem_ctx,
1988 DS_ROLE_BASIC_INFORMATION,
1993 if (NT_STATUS_IS_OK(status)) {
1994 result = werror_to_ntstatus(werr);
1996 if (!NT_STATUS_IS_OK(status)) {
1997 DEBUG(5, ("set_dc_type_and_flags_connect: rpccli_ds_getprimarydominfo "
1998 "on domain %s failed: (%s)\n",
1999 domain->name, nt_errstr(status)));
2001 /* older samba3 DCs will return DCERPC_FAULT_OP_RNG_ERROR for
2002 * every opcode on the DSSETUP pipe, continue with
2003 * no_dssetup mode here as well to get domain->initialized
2006 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
2010 TALLOC_FREE(mem_ctx);
2014 if ((info.basic.flags & DS_ROLE_PRIMARY_DS_RUNNING) &&
2015 !(info.basic.flags & DS_ROLE_PRIMARY_DS_MIXED_MODE)) {
2016 domain->native_mode = True;
2018 domain->native_mode = False;
2022 status = cli_rpc_pipe_open_noauth(domain->conn.cli,
2023 &ndr_table_lsarpc.syntax_id, &cli);
2025 if (!NT_STATUS_IS_OK(status)) {
2026 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
2027 "PI_LSARPC on domain %s: (%s)\n",
2028 domain->name, nt_errstr(status)));
2030 TALLOC_FREE(mem_ctx);
2034 status = rpccli_lsa_open_policy2(cli, mem_ctx, True,
2035 SEC_FLAG_MAXIMUM_ALLOWED, &pol);
2037 if (NT_STATUS_IS_OK(status)) {
2038 /* This particular query is exactly what Win2k clients use
2039 to determine that the DC is active directory */
2040 status = dcerpc_lsa_QueryInfoPolicy2(cli->binding_handle, mem_ctx,
2042 LSA_POLICY_INFO_DNS,
2047 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2048 domain->active_directory = True;
2050 if (lsa_info->dns.name.string) {
2051 fstrcpy(domain->name, lsa_info->dns.name.string);
2054 if (lsa_info->dns.dns_domain.string) {
2055 fstrcpy(domain->alt_name,
2056 lsa_info->dns.dns_domain.string);
2059 /* See if we can set some domain trust flags about
2062 if (lsa_info->dns.dns_forest.string) {
2063 fstrcpy(domain->forest_name,
2064 lsa_info->dns.dns_forest.string);
2066 if (strequal(domain->forest_name, domain->alt_name)) {
2067 domain->domain_flags |= NETR_TRUST_FLAG_TREEROOT;
2071 if (lsa_info->dns.sid) {
2072 sid_copy(&domain->sid, lsa_info->dns.sid);
2075 domain->active_directory = False;
2077 status = rpccli_lsa_open_policy(cli, mem_ctx, True,
2078 SEC_FLAG_MAXIMUM_ALLOWED,
2081 if (!NT_STATUS_IS_OK(status)) {
2085 status = dcerpc_lsa_QueryInfoPolicy(cli->binding_handle, mem_ctx,
2087 LSA_POLICY_INFO_ACCOUNT_DOMAIN,
2090 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2092 if (lsa_info->account_domain.name.string) {
2093 fstrcpy(domain->name,
2094 lsa_info->account_domain.name.string);
2097 if (lsa_info->account_domain.sid) {
2098 sid_copy(&domain->sid, lsa_info->account_domain.sid);
2104 DEBUG(5, ("set_dc_type_and_flags_connect: domain %s is %sin native mode.\n",
2105 domain->name, domain->native_mode ? "" : "NOT "));
2107 DEBUG(5,("set_dc_type_and_flags_connect: domain %s is %srunning active directory.\n",
2108 domain->name, domain->active_directory ? "" : "NOT "));
2110 domain->can_do_ncacn_ip_tcp = domain->active_directory;
2111 domain->can_do_validation6 = domain->active_directory;
2115 TALLOC_FREE(mem_ctx);
2117 domain->initialized = True;
2120 /**********************************************************************
2121 Set the domain_flags (trust attributes, domain operating modes, etc...
2122 ***********************************************************************/
2124 static void set_dc_type_and_flags( struct winbindd_domain *domain )
2126 /* we always have to contact our primary domain */
2128 if ( domain->primary ) {
2129 DEBUG(10,("set_dc_type_and_flags: setting up flags for "
2130 "primary domain\n"));
2131 set_dc_type_and_flags_connect( domain );
2135 /* Use our DC to get the information if possible */
2137 if ( !set_dc_type_and_flags_trustinfo( domain ) ) {
2138 /* Otherwise, fallback to contacting the
2140 set_dc_type_and_flags_connect( domain );
2148 /**********************************************************************
2149 ***********************************************************************/
2151 static NTSTATUS cm_get_schannel_creds(struct winbindd_domain *domain,
2152 struct netlogon_creds_CredentialState **ppdc)
2154 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2155 struct rpc_pipe_client *netlogon_pipe;
2157 if (lp_client_schannel() == False) {
2158 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2161 result = cm_connect_netlogon(domain, &netlogon_pipe);
2162 if (!NT_STATUS_IS_OK(result)) {
2166 /* Return a pointer to the struct netlogon_creds_CredentialState from the
2169 if (!domain->conn.netlogon_pipe->dc) {
2170 return NT_STATUS_INTERNAL_ERROR; /* This shouldn't happen. */
2173 *ppdc = domain->conn.netlogon_pipe->dc;
2174 return NT_STATUS_OK;
2177 NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
2178 struct rpc_pipe_client **cli, struct policy_handle *sam_handle)
2180 struct winbindd_cm_conn *conn;
2181 NTSTATUS status, result;
2182 struct netlogon_creds_CredentialState *p_creds;
2183 char *machine_password = NULL;
2184 char *machine_account = NULL;
2185 char *domain_name = NULL;
2187 if (sid_check_is_domain(&domain->sid)) {
2188 return open_internal_samr_conn(mem_ctx, domain, cli, sam_handle);
2191 status = init_dc_connection_rpc(domain);
2192 if (!NT_STATUS_IS_OK(status)) {
2196 conn = &domain->conn;
2198 if (rpccli_is_connected(conn->samr_pipe)) {
2202 TALLOC_FREE(conn->samr_pipe);
2205 * No SAMR pipe yet. Attempt to get an NTLMSSP SPNEGO authenticated
2206 * sign and sealed pipe using the machine account password by
2207 * preference. If we can't - try schannel, if that fails, try
2211 if ((conn->cli->user_name[0] == '\0') ||
2212 (conn->cli->domain[0] == '\0') ||
2213 (conn->cli->password == NULL || conn->cli->password[0] == '\0'))
2215 status = get_trust_creds(domain, &machine_password,
2216 &machine_account, NULL);
2217 if (!NT_STATUS_IS_OK(status)) {
2218 DEBUG(10, ("cm_connect_sam: No no user available for "
2219 "domain %s, trying schannel\n", conn->cli->domain));
2222 domain_name = domain->name;
2224 machine_password = SMB_STRDUP(conn->cli->password);
2225 machine_account = SMB_STRDUP(conn->cli->user_name);
2226 domain_name = conn->cli->domain;
2229 if (!machine_password || !machine_account) {
2230 status = NT_STATUS_NO_MEMORY;
2234 /* We have an authenticated connection. Use a NTLMSSP SPNEGO
2235 authenticated SAMR pipe with sign & seal. */
2236 status = cli_rpc_pipe_open_spnego_ntlmssp(conn->cli,
2237 &ndr_table_samr.syntax_id,
2239 DCERPC_AUTH_LEVEL_PRIVACY,
2245 if (!NT_STATUS_IS_OK(status)) {
2246 DEBUG(10,("cm_connect_sam: failed to connect to SAMR "
2247 "pipe for domain %s using NTLMSSP "
2248 "authenticated pipe: user %s\\%s. Error was "
2249 "%s\n", domain->name, domain_name,
2250 machine_account, nt_errstr(status)));
2254 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for "
2255 "domain %s using NTLMSSP authenticated "
2256 "pipe: user %s\\%s\n", domain->name,
2257 domain_name, machine_account));
2259 status = dcerpc_samr_Connect2(conn->samr_pipe->binding_handle, mem_ctx,
2260 conn->samr_pipe->desthost,
2261 SEC_FLAG_MAXIMUM_ALLOWED,
2262 &conn->sam_connect_handle,
2264 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2267 if (NT_STATUS_IS_OK(status)) {
2271 DEBUG(10,("cm_connect_sam: ntlmssp-sealed dcerpc_samr_Connect2 "
2272 "failed for domain %s, error was %s. Trying schannel\n",
2273 domain->name, nt_errstr(status) ));
2274 TALLOC_FREE(conn->samr_pipe);
2278 /* Fall back to schannel if it's a W2K pre-SP1 box. */
2280 status = cm_get_schannel_creds(domain, &p_creds);
2281 if (!NT_STATUS_IS_OK(status)) {
2282 /* If this call fails - conn->cli can now be NULL ! */
2283 DEBUG(10, ("cm_connect_sam: Could not get schannel auth info "
2284 "for domain %s (error %s), trying anon\n",
2286 nt_errstr(status) ));
2289 status = cli_rpc_pipe_open_schannel_with_key
2290 (conn->cli, &ndr_table_samr.syntax_id, NCACN_NP,
2291 DCERPC_AUTH_LEVEL_PRIVACY,
2292 domain->name, &p_creds, &conn->samr_pipe);
2294 if (!NT_STATUS_IS_OK(status)) {
2295 DEBUG(10,("cm_connect_sam: failed to connect to SAMR pipe for "
2296 "domain %s using schannel. Error was %s\n",
2297 domain->name, nt_errstr(status) ));
2300 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for domain %s using "
2301 "schannel.\n", domain->name ));
2303 status = dcerpc_samr_Connect2(conn->samr_pipe->binding_handle, mem_ctx,
2304 conn->samr_pipe->desthost,
2305 SEC_FLAG_MAXIMUM_ALLOWED,
2306 &conn->sam_connect_handle,
2308 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2311 if (NT_STATUS_IS_OK(status)) {
2314 DEBUG(10,("cm_connect_sam: schannel-sealed dcerpc_samr_Connect2 failed "
2315 "for domain %s, error was %s. Trying anonymous\n",
2316 domain->name, nt_errstr(status) ));
2317 TALLOC_FREE(conn->samr_pipe);
2321 /* Finally fall back to anonymous. */
2322 status = cli_rpc_pipe_open_noauth(conn->cli, &ndr_table_samr.syntax_id,
2325 if (!NT_STATUS_IS_OK(status)) {
2329 status = dcerpc_samr_Connect2(conn->samr_pipe->binding_handle, mem_ctx,
2330 conn->samr_pipe->desthost,
2331 SEC_FLAG_MAXIMUM_ALLOWED,
2332 &conn->sam_connect_handle,
2334 if (!NT_STATUS_IS_OK(status)) {
2335 DEBUG(10,("cm_connect_sam: rpccli_samr_Connect2 failed "
2336 "for domain %s Error was %s\n",
2337 domain->name, nt_errstr(status) ));
2340 if (!NT_STATUS_IS_OK(result)) {
2342 DEBUG(10,("cm_connect_sam: dcerpc_samr_Connect2 failed "
2343 "for domain %s Error was %s\n",
2344 domain->name, nt_errstr(result)));
2349 status = dcerpc_samr_OpenDomain(conn->samr_pipe->binding_handle,
2351 &conn->sam_connect_handle,
2352 SEC_FLAG_MAXIMUM_ALLOWED,
2354 &conn->sam_domain_handle,
2356 if (!NT_STATUS_IS_OK(status)) {
2363 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2365 * if we got access denied, we might just have no access rights
2366 * to talk to the remote samr server server (e.g. when we are a
2367 * PDC and we are connecting a w2k8 pdc via an interdomain
2368 * trust). In that case do not invalidate the whole connection
2371 TALLOC_FREE(conn->samr_pipe);
2372 ZERO_STRUCT(conn->sam_domain_handle);
2374 } else if (!NT_STATUS_IS_OK(status)) {
2375 invalidate_cm_connection(conn);
2379 *cli = conn->samr_pipe;
2380 *sam_handle = conn->sam_domain_handle;
2381 SAFE_FREE(machine_password);
2382 SAFE_FREE(machine_account);
2386 /**********************************************************************
2387 open an schanneld ncacn_ip_tcp connection to LSA
2388 ***********************************************************************/
2390 NTSTATUS cm_connect_lsa_tcp(struct winbindd_domain *domain,
2391 TALLOC_CTX *mem_ctx,
2392 struct rpc_pipe_client **cli)
2394 struct winbindd_cm_conn *conn;
2395 struct netlogon_creds_CredentialState *creds;
2398 DEBUG(10,("cm_connect_lsa_tcp\n"));
2400 status = init_dc_connection_rpc(domain);
2401 if (!NT_STATUS_IS_OK(status)) {
2405 conn = &domain->conn;
2407 if (conn->lsa_pipe_tcp &&
2408 conn->lsa_pipe_tcp->transport->transport == NCACN_IP_TCP &&
2409 conn->lsa_pipe_tcp->auth->auth_level == DCERPC_AUTH_LEVEL_PRIVACY &&
2410 rpccli_is_connected(conn->lsa_pipe_tcp)) {
2414 TALLOC_FREE(conn->lsa_pipe_tcp);
2416 status = cm_get_schannel_creds(domain, &creds);
2417 if (!NT_STATUS_IS_OK(status)) {
2421 status = cli_rpc_pipe_open_schannel_with_key(conn->cli,
2422 &ndr_table_lsarpc.syntax_id,
2424 DCERPC_AUTH_LEVEL_PRIVACY,
2427 &conn->lsa_pipe_tcp);
2428 if (!NT_STATUS_IS_OK(status)) {
2429 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key failed: %s\n",
2430 nt_errstr(status)));
2435 if (!NT_STATUS_IS_OK(status)) {
2436 TALLOC_FREE(conn->lsa_pipe_tcp);
2440 *cli = conn->lsa_pipe_tcp;
2445 NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
2446 struct rpc_pipe_client **cli, struct policy_handle *lsa_policy)
2448 struct winbindd_cm_conn *conn;
2449 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2450 struct netlogon_creds_CredentialState *p_creds;
2452 result = init_dc_connection_rpc(domain);
2453 if (!NT_STATUS_IS_OK(result))
2456 conn = &domain->conn;
2458 if (rpccli_is_connected(conn->lsa_pipe)) {
2462 TALLOC_FREE(conn->lsa_pipe);
2464 if ((conn->cli->user_name[0] == '\0') ||
2465 (conn->cli->domain[0] == '\0') ||
2466 (conn->cli->password == NULL || conn->cli->password[0] == '\0')) {
2467 DEBUG(10, ("cm_connect_lsa: No no user available for "
2468 "domain %s, trying schannel\n", conn->cli->domain));
2472 /* We have an authenticated connection. Use a NTLMSSP SPNEGO
2473 * authenticated LSA pipe with sign & seal. */
2474 result = cli_rpc_pipe_open_spnego_ntlmssp
2475 (conn->cli, &ndr_table_lsarpc.syntax_id, NCACN_NP,
2476 DCERPC_AUTH_LEVEL_PRIVACY,
2477 conn->cli->domain, conn->cli->user_name, conn->cli->password,
2480 if (!NT_STATUS_IS_OK(result)) {
2481 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
2482 "domain %s using NTLMSSP authenticated pipe: user "
2483 "%s\\%s. Error was %s. Trying schannel.\n",
2484 domain->name, conn->cli->domain,
2485 conn->cli->user_name, nt_errstr(result)));
2489 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
2490 "NTLMSSP authenticated pipe: user %s\\%s\n",
2491 domain->name, conn->cli->domain, conn->cli->user_name ));
2493 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2494 SEC_FLAG_MAXIMUM_ALLOWED,
2496 if (NT_STATUS_IS_OK(result)) {
2500 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
2503 TALLOC_FREE(conn->lsa_pipe);
2507 /* Fall back to schannel if it's a W2K pre-SP1 box. */
2509 result = cm_get_schannel_creds(domain, &p_creds);
2510 if (!NT_STATUS_IS_OK(result)) {
2511 /* If this call fails - conn->cli can now be NULL ! */
2512 DEBUG(10, ("cm_connect_lsa: Could not get schannel auth info "
2513 "for domain %s (error %s), trying anon\n",
2515 nt_errstr(result) ));
2518 result = cli_rpc_pipe_open_schannel_with_key
2519 (conn->cli, &ndr_table_lsarpc.syntax_id, NCACN_NP,
2520 DCERPC_AUTH_LEVEL_PRIVACY,
2521 domain->name, &p_creds, &conn->lsa_pipe);
2523 if (!NT_STATUS_IS_OK(result)) {
2524 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
2525 "domain %s using schannel. Error was %s\n",
2526 domain->name, nt_errstr(result) ));
2529 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
2530 "schannel.\n", domain->name ));
2532 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2533 SEC_FLAG_MAXIMUM_ALLOWED,
2535 if (NT_STATUS_IS_OK(result)) {
2539 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
2542 TALLOC_FREE(conn->lsa_pipe);
2546 result = cli_rpc_pipe_open_noauth(conn->cli,
2547 &ndr_table_lsarpc.syntax_id,
2549 if (!NT_STATUS_IS_OK(result)) {
2550 result = NT_STATUS_PIPE_NOT_AVAILABLE;
2554 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2555 SEC_FLAG_MAXIMUM_ALLOWED,
2558 if (!NT_STATUS_IS_OK(result)) {
2559 invalidate_cm_connection(conn);
2563 *cli = conn->lsa_pipe;
2564 *lsa_policy = conn->lsa_policy;
2568 /****************************************************************************
2569 Open the netlogon pipe to this DC. Use schannel if specified in client conf.
2570 session key stored in conn->netlogon_pipe->dc->sess_key.
2571 ****************************************************************************/
2573 NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
2574 struct rpc_pipe_client **cli)
2576 struct winbindd_cm_conn *conn;
2579 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
2581 enum netr_SchannelType sec_chan_type;
2582 const char *account_name;
2583 struct rpc_pipe_client *netlogon_pipe = NULL;
2587 result = init_dc_connection_rpc(domain);
2588 if (!NT_STATUS_IS_OK(result)) {
2592 conn = &domain->conn;
2594 if (rpccli_is_connected(conn->netlogon_pipe)) {
2595 *cli = conn->netlogon_pipe;
2596 return NT_STATUS_OK;
2599 TALLOC_FREE(conn->netlogon_pipe);
2601 result = cli_rpc_pipe_open_noauth(conn->cli,
2602 &ndr_table_netlogon.syntax_id,
2604 if (!NT_STATUS_IS_OK(result)) {
2608 if ((!IS_DC) && (!domain->primary)) {
2609 /* Clear the schannel request bit and drop down */
2610 neg_flags &= ~NETLOGON_NEG_SCHANNEL;
2614 if (lp_client_schannel() != False) {
2615 neg_flags |= NETLOGON_NEG_SCHANNEL;
2618 if (!get_trust_pw_hash(domain->name, mach_pwd, &account_name,
2621 TALLOC_FREE(netlogon_pipe);
2622 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2625 result = rpccli_netlogon_setup_creds(
2627 domain->dcname, /* server name. */
2628 domain->name, /* domain name */
2629 global_myname(), /* client name */
2630 account_name, /* machine account */
2631 mach_pwd, /* machine password */
2632 sec_chan_type, /* from get_trust_pw */
2635 if (!NT_STATUS_IS_OK(result)) {
2636 TALLOC_FREE(netlogon_pipe);
2640 if ((lp_client_schannel() == True) &&
2641 ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
2642 DEBUG(3, ("Server did not offer schannel\n"));
2643 TALLOC_FREE(netlogon_pipe);
2644 return NT_STATUS_ACCESS_DENIED;
2648 if ((lp_client_schannel() == False) ||
2649 ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
2651 * NetSamLogonEx only works for schannel
2653 domain->can_do_samlogon_ex = False;
2655 /* We're done - just keep the existing connection to NETLOGON
2657 conn->netlogon_pipe = netlogon_pipe;
2658 *cli = conn->netlogon_pipe;
2659 return NT_STATUS_OK;
2662 /* Using the credentials from the first pipe, open a signed and sealed
2663 second netlogon pipe. The session key is stored in the schannel
2664 part of the new pipe auth struct.
2667 result = cli_rpc_pipe_open_schannel_with_key(
2668 conn->cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
2669 DCERPC_AUTH_LEVEL_PRIVACY, domain->name, &netlogon_pipe->dc,
2670 &conn->netlogon_pipe);
2672 /* We can now close the initial netlogon pipe. */
2673 TALLOC_FREE(netlogon_pipe);
2675 if (!NT_STATUS_IS_OK(result)) {
2676 DEBUG(3, ("Could not open schannel'ed NETLOGON pipe. Error "
2677 "was %s\n", nt_errstr(result)));
2679 invalidate_cm_connection(conn);
2684 * Always try netr_LogonSamLogonEx. We will fall back for NT4
2685 * which gives DCERPC_FAULT_OP_RNG_ERROR (function not
2686 * supported). We used to only try SamLogonEx for AD, but
2687 * Samba DCs can also do it. And because we don't distinguish
2688 * between Samba and NT4, always try it once.
2690 domain->can_do_samlogon_ex = true;
2692 *cli = conn->netlogon_pipe;
2693 return NT_STATUS_OK;
2696 void winbind_msg_ip_dropped(struct messaging_context *msg_ctx,
2699 struct server_id server_id,
2702 struct winbindd_domain *domain;
2703 char *freeit = NULL;
2707 || (data->data == NULL)
2708 || (data->length == 0)
2709 || (data->data[data->length-1] != '\0')) {
2710 DEBUG(1, ("invalid msg_ip_dropped message: not a valid "
2715 addr = (char *)data->data;
2716 DEBUG(10, ("IP %s dropped\n", addr));
2718 if (!is_ipaddress(addr)) {
2721 * Some code sends us ip addresses with the /netmask
2724 slash = strchr(addr, '/');
2725 if (slash == NULL) {
2726 DEBUG(1, ("invalid msg_ip_dropped message: %s",
2730 freeit = talloc_strndup(talloc_tos(), addr, slash-addr);
2731 if (freeit == NULL) {
2732 DEBUG(1, ("talloc failed\n"));
2736 DEBUG(10, ("Stripped /netmask to IP %s\n", addr));
2739 for (domain = domain_list(); domain != NULL; domain = domain->next) {
2740 char sockaddr[INET6_ADDRSTRLEN];
2741 if (domain->conn.cli == NULL) {
2744 if (domain->conn.cli->fd == -1) {
2747 client_socket_addr(domain->conn.cli->fd, sockaddr,
2749 if (strequal(sockaddr, addr)) {
2750 close(domain->conn.cli->fd);
2751 domain->conn.cli->fd = -1;
2754 TALLOC_FREE(freeit);