s3:libsmb: store the remote_realm on the cli_state
[samba.git] / source3 / winbindd / winbindd_cm.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    Winbind daemon connection manager
5
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
11
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.
16
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.
21
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/>.
24 */
25
26 /*
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:
30
31        - make connections to domain controllers and cache them
32        - re-establish connections when networks or servers go down
33        - centralise the policy on connection timeouts, domain controller
34          selection etc
35        - manage re-entrancy for when winbindd becomes able to handle
36          multiple outstanding rpc requests
37
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.
44
45    The TNG design is quite good but I disagree with some aspects of the
46    implementation. -tpot
47
48  */
49
50 /*
51    TODO:
52
53      - I'm pretty annoyed by all the make_nmb_name() stuff.  It should be
54        moved down into another function.
55
56      - Take care when destroying cli_structs as they can be shared between
57        various sam handles.
58
59  */
60
61 #include "includes.h"
62 #include "winbindd.h"
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"
74 #include "ads.h"
75 #include "secrets.h"
76 #include "../libcli/security/security.h"
77 #include "passdb.h"
78 #include "messages.h"
79
80 #undef DBGC_CLASS
81 #define DBGC_CLASS DBGC_WINBIND
82
83 struct dc_name_ip {
84         fstring name;
85         struct sockaddr_storage ss;
86 };
87
88 extern struct winbindd_methods reconnect_methods;
89 extern bool override_logfile;
90
91 static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain);
92 static void set_dc_type_and_flags( struct winbindd_domain *domain );
93 static bool get_dcs(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
94                     struct dc_name_ip **dcs, int *num_dcs);
95
96 /****************************************************************
97  Child failed to find DC's. Reschedule check.
98 ****************************************************************/
99
100 static void msg_failed_to_go_online(struct messaging_context *msg,
101                                     void *private_data,
102                                     uint32_t msg_type,
103                                     struct server_id server_id,
104                                     DATA_BLOB *data)
105 {
106         struct winbindd_domain *domain;
107         const char *domainname = (const char *)data->data;
108
109         if (data->data == NULL || data->length == 0) {
110                 return;
111         }
112
113         DEBUG(5,("msg_fail_to_go_online: received for domain %s.\n", domainname));
114
115         for (domain = domain_list(); domain; domain = domain->next) {
116                 if (domain->internal) {
117                         continue;
118                 }
119
120                 if (strequal(domain->name, domainname)) {
121                         if (domain->online) {
122                                 /* We're already online, ignore. */
123                                 DEBUG(5,("msg_fail_to_go_online: domain %s "
124                                         "already online.\n", domainname));
125                                 continue;
126                         }
127
128                         /* Reschedule the online check. */
129                         set_domain_offline(domain);
130                         break;
131                 }
132         }
133 }
134
135 /****************************************************************
136  Actually cause a reconnect from a message.
137 ****************************************************************/
138
139 static void msg_try_to_go_online(struct messaging_context *msg,
140                                  void *private_data,
141                                  uint32_t msg_type,
142                                  struct server_id server_id,
143                                  DATA_BLOB *data)
144 {
145         struct winbindd_domain *domain;
146         const char *domainname = (const char *)data->data;
147
148         if (data->data == NULL || data->length == 0) {
149                 return;
150         }
151
152         DEBUG(5,("msg_try_to_go_online: received for domain %s.\n", domainname));
153
154         for (domain = domain_list(); domain; domain = domain->next) {
155                 if (domain->internal) {
156                         continue;
157                 }
158
159                 if (strequal(domain->name, domainname)) {
160
161                         if (domain->online) {
162                                 /* We're already online, ignore. */
163                                 DEBUG(5,("msg_try_to_go_online: domain %s "
164                                         "already online.\n", domainname));
165                                 continue;
166                         }
167
168                         /* This call takes care of setting the online
169                            flag to true if we connected, or re-adding
170                            the offline handler if false. Bypasses online
171                            check so always does network calls. */
172
173                         init_dc_connection_network(domain);
174                         break;
175                 }
176         }
177 }
178
179 /****************************************************************
180  Fork a child to try and contact a DC. Do this as contacting a
181  DC requires blocking lookups and we don't want to block our
182  parent.
183 ****************************************************************/
184
185 static bool fork_child_dc_connect(struct winbindd_domain *domain)
186 {
187         struct dc_name_ip *dcs = NULL;
188         int num_dcs = 0;
189         TALLOC_CTX *mem_ctx = NULL;
190         pid_t parent_pid = sys_getpid();
191         char *lfile = NULL;
192         NTSTATUS status;
193
194         if (domain->dc_probe_pid != (pid_t)-1) {
195                 /*
196                  * We might already have a DC probe
197                  * child working, check.
198                  */
199                 if (process_exists_by_pid(domain->dc_probe_pid)) {
200                         DEBUG(10,("fork_child_dc_connect: pid %u already "
201                                 "checking for DC's.\n",
202                                 (unsigned int)domain->dc_probe_pid));
203                         return true;
204                 }
205                 domain->dc_probe_pid = (pid_t)-1;
206         }
207
208         domain->dc_probe_pid = sys_fork();
209
210         if (domain->dc_probe_pid == (pid_t)-1) {
211                 DEBUG(0, ("fork_child_dc_connect: Could not fork: %s\n", strerror(errno)));
212                 return False;
213         }
214
215         if (domain->dc_probe_pid != (pid_t)0) {
216                 /* Parent */
217                 messaging_register(winbind_messaging_context(), NULL,
218                                    MSG_WINBIND_TRY_TO_GO_ONLINE,
219                                    msg_try_to_go_online);
220                 messaging_register(winbind_messaging_context(), NULL,
221                                    MSG_WINBIND_FAILED_TO_GO_ONLINE,
222                                    msg_failed_to_go_online);
223                 return True;
224         }
225
226         /* Child. */
227
228         /* Leave messages blocked - we will never process one. */
229
230         if (!override_logfile) {
231                 if (asprintf(&lfile, "%s/log.winbindd-dc-connect", get_dyn_LOGFILEBASE()) == -1) {
232                         DEBUG(0, ("fork_child_dc_connect: out of memory.\n"));
233                         _exit(1);
234                 }
235         }
236
237         status = winbindd_reinit_after_fork(NULL, lfile);
238         if (!NT_STATUS_IS_OK(status)) {
239                 DEBUG(1, ("winbindd_reinit_after_fork failed: %s\n",
240                           nt_errstr(status)));
241                 messaging_send_buf(winbind_messaging_context(),
242                                    pid_to_procid(parent_pid),
243                                    MSG_WINBIND_FAILED_TO_GO_ONLINE,
244                                    (uint8 *)domain->name,
245                                    strlen(domain->name)+1);
246                 _exit(1);
247         }
248         SAFE_FREE(lfile);
249
250         mem_ctx = talloc_init("fork_child_dc_connect");
251         if (!mem_ctx) {
252                 DEBUG(0,("talloc_init failed.\n"));
253                 messaging_send_buf(winbind_messaging_context(),
254                                    pid_to_procid(parent_pid),
255                                    MSG_WINBIND_FAILED_TO_GO_ONLINE,
256                                    (uint8 *)domain->name,
257                                    strlen(domain->name)+1);
258                 _exit(1);
259         }
260
261         if ((!get_dcs(mem_ctx, domain, &dcs, &num_dcs)) || (num_dcs == 0)) {
262                 /* Still offline ? Can't find DC's. */
263                 messaging_send_buf(winbind_messaging_context(),
264                                    pid_to_procid(parent_pid),
265                                    MSG_WINBIND_FAILED_TO_GO_ONLINE,
266                                    (uint8 *)domain->name,
267                                    strlen(domain->name)+1);
268                 _exit(0);
269         }
270
271         /* We got a DC. Send a message to our parent to get it to
272            try and do the same. */
273
274         messaging_send_buf(winbind_messaging_context(),
275                            pid_to_procid(parent_pid),
276                            MSG_WINBIND_TRY_TO_GO_ONLINE,
277                            (uint8 *)domain->name,
278                            strlen(domain->name)+1);
279         _exit(0);
280 }
281
282 /****************************************************************
283  Handler triggered if we're offline to try and detect a DC.
284 ****************************************************************/
285
286 static void check_domain_online_handler(struct event_context *ctx,
287                                         struct timed_event *te,
288                                         struct timeval now,
289                                         void *private_data)
290 {
291         struct winbindd_domain *domain =
292                 (struct winbindd_domain *)private_data;
293
294         DEBUG(10,("check_domain_online_handler: called for domain "
295                   "%s (online = %s)\n", domain->name, 
296                   domain->online ? "True" : "False" ));
297
298         TALLOC_FREE(domain->check_online_event);
299
300         /* Are we still in "startup" mode ? */
301
302         if (domain->startup && (time_mono(NULL) > domain->startup_time + 30)) {
303                 /* No longer in "startup" mode. */
304                 DEBUG(10,("check_domain_online_handler: domain %s no longer in 'startup' mode.\n",
305                         domain->name ));
306                 domain->startup = False;
307         }
308
309         /* We've been told to stay offline, so stay
310            that way. */
311
312         if (get_global_winbindd_state_offline()) {
313                 DEBUG(10,("check_domain_online_handler: domain %s remaining globally offline\n",
314                         domain->name ));
315                 return;
316         }
317
318         /* Fork a child to test if it can contact a DC. 
319            If it can then send ourselves a message to
320            cause a reconnect. */
321
322         fork_child_dc_connect(domain);
323 }
324
325 /****************************************************************
326  If we're still offline setup the timeout check.
327 ****************************************************************/
328
329 static void calc_new_online_timeout_check(struct winbindd_domain *domain)
330 {
331         int wbr = lp_winbind_reconnect_delay();
332
333         if (domain->startup) {
334                 domain->check_online_timeout = 10;
335         } else if (domain->check_online_timeout < wbr) {
336                 domain->check_online_timeout = wbr;
337         }
338 }
339
340 /****************************************************************
341  Set domain offline and also add handler to put us back online
342  if we detect a DC.
343 ****************************************************************/
344
345 void set_domain_offline(struct winbindd_domain *domain)
346 {
347         DEBUG(10,("set_domain_offline: called for domain %s\n",
348                 domain->name ));
349
350         TALLOC_FREE(domain->check_online_event);
351
352         if (domain->internal) {
353                 DEBUG(3,("set_domain_offline: domain %s is internal - logic error.\n",
354                         domain->name ));
355                 return;
356         }
357
358         domain->online = False;
359
360         /* Offline domains are always initialized. They're
361            re-initialized when they go back online. */
362
363         domain->initialized = True;
364
365         /* We only add the timeout handler that checks and
366            allows us to go back online when we've not
367            been told to remain offline. */
368
369         if (get_global_winbindd_state_offline()) {
370                 DEBUG(10,("set_domain_offline: domain %s remaining globally offline\n",
371                         domain->name ));
372                 return;
373         }
374
375         /* If we're in startup mode, check again in 10 seconds, not in
376            lp_winbind_reconnect_delay() seconds (which is 30 seconds by default). */
377
378         calc_new_online_timeout_check(domain);
379
380         domain->check_online_event = event_add_timed(winbind_event_context(),
381                                                 NULL,
382                                                 timeval_current_ofs(domain->check_online_timeout,0),
383                                                 check_domain_online_handler,
384                                                 domain);
385
386         /* The above *has* to succeed for winbindd to work. */
387         if (!domain->check_online_event) {
388                 smb_panic("set_domain_offline: failed to add online handler");
389         }
390
391         DEBUG(10,("set_domain_offline: added event handler for domain %s\n",
392                 domain->name ));
393
394         /* Send an offline message to the idmap child when our
395            primary domain goes offline */
396
397         if ( domain->primary ) {
398                 struct winbindd_child *idmap = idmap_child();
399
400                 if ( idmap->pid != 0 ) {
401                         messaging_send_buf(winbind_messaging_context(),
402                                            pid_to_procid(idmap->pid), 
403                                            MSG_WINBIND_OFFLINE, 
404                                            (uint8 *)domain->name, 
405                                            strlen(domain->name)+1);
406                 }                       
407         }
408
409         return; 
410 }
411
412 /****************************************************************
413  Set domain online - if allowed.
414 ****************************************************************/
415
416 static void set_domain_online(struct winbindd_domain *domain)
417 {
418         DEBUG(10,("set_domain_online: called for domain %s\n",
419                 domain->name ));
420
421         if (domain->internal) {
422                 DEBUG(3,("set_domain_online: domain %s is internal - logic error.\n",
423                         domain->name ));
424                 return;
425         }
426
427         if (get_global_winbindd_state_offline()) {
428                 DEBUG(10,("set_domain_online: domain %s remaining globally offline\n",
429                         domain->name ));
430                 return;
431         }
432
433         winbindd_set_locator_kdc_envs(domain);
434
435         /* If we are waiting to get a krb5 ticket, trigger immediately. */
436         ccache_regain_all_now();
437
438         /* Ok, we're out of any startup mode now... */
439         domain->startup = False;
440
441         if (domain->online == False) {
442                 /* We were offline - now we're online. We default to
443                    using the MS-RPC backend if we started offline,
444                    and if we're going online for the first time we
445                    should really re-initialize the backends and the
446                    checks to see if we're talking to an AD or NT domain.
447                 */
448
449                 domain->initialized = False;
450
451                 /* 'reconnect_methods' is the MS-RPC backend. */
452                 if (domain->backend == &reconnect_methods) {
453                         domain->backend = NULL;
454                 }
455         }
456
457         /* Ensure we have no online timeout checks. */
458         domain->check_online_timeout = 0;
459         TALLOC_FREE(domain->check_online_event);
460
461         /* Ensure we ignore any pending child messages. */
462         messaging_deregister(winbind_messaging_context(),
463                              MSG_WINBIND_TRY_TO_GO_ONLINE, NULL);
464         messaging_deregister(winbind_messaging_context(),
465                              MSG_WINBIND_FAILED_TO_GO_ONLINE, NULL);
466
467         domain->online = True;
468
469         /* Send an online message to the idmap child when our
470            primary domain comes online */
471
472         if ( domain->primary ) {
473                 struct winbindd_child *idmap = idmap_child();
474
475                 if ( idmap->pid != 0 ) {
476                         messaging_send_buf(winbind_messaging_context(),
477                                            pid_to_procid(idmap->pid), 
478                                            MSG_WINBIND_ONLINE, 
479                                            (uint8 *)domain->name, 
480                                            strlen(domain->name)+1);
481                 }                       
482         }
483
484         return; 
485 }
486
487 /****************************************************************
488  Requested to set a domain online.
489 ****************************************************************/
490
491 void set_domain_online_request(struct winbindd_domain *domain)
492 {
493         struct timeval tev;
494
495         DEBUG(10,("set_domain_online_request: called for domain %s\n",
496                 domain->name ));
497
498         if (get_global_winbindd_state_offline()) {
499                 DEBUG(10,("set_domain_online_request: domain %s remaining globally offline\n",
500                         domain->name ));
501                 return;
502         }
503
504         if (domain->internal) {
505                 DEBUG(10, ("set_domain_online_request: Internal domains are "
506                            "always online\n"));
507                 return;
508         }
509
510         /* We've been told it's safe to go online and
511            try and connect to a DC. But I don't believe it
512            because network manager seems to lie.
513            Wait at least 5 seconds. Heuristics suck... */
514
515
516         GetTimeOfDay(&tev);
517
518         /* Go into "startup" mode again. */
519         domain->startup_time = time_mono(NULL);
520         domain->startup = True;
521
522         tev.tv_sec += 5;
523
524         if (!domain->check_online_event) {
525                 /* If we've come from being globally offline we
526                    don't have a check online event handler set.
527                    We need to add one now we're trying to go
528                    back online. */
529
530                 DEBUG(10,("set_domain_online_request: domain %s was globally offline.\n",
531                         domain->name ));
532         }
533
534         TALLOC_FREE(domain->check_online_event);
535
536         domain->check_online_event = event_add_timed(winbind_event_context(),
537                                                      NULL,
538                                                      tev,
539                                                      check_domain_online_handler,
540                                                      domain);
541
542         /* The above *has* to succeed for winbindd to work. */
543         if (!domain->check_online_event) {
544                 smb_panic("set_domain_online_request: failed to add online handler");
545         }
546 }
547
548 /****************************************************************
549  Add -ve connection cache entries for domain and realm.
550 ****************************************************************/
551
552 static void winbind_add_failed_connection_entry(
553         const struct winbindd_domain *domain,
554         const char *server,
555         NTSTATUS result)
556 {
557         add_failed_connection_entry(domain->name, server, result);
558         /* If this was the saf name for the last thing we talked to,
559            remove it. */
560         saf_delete(domain->name);
561         if (*domain->alt_name) {
562                 add_failed_connection_entry(domain->alt_name, server, result);
563                 saf_delete(domain->alt_name);
564         }
565         winbindd_unset_locator_kdc_env(domain);
566 }
567
568 /* Choose between anonymous or authenticated connections.  We need to use
569    an authenticated connection if DCs have the RestrictAnonymous registry
570    entry set > 0, or the "Additional restrictions for anonymous
571    connections" set in the win2k Local Security Policy. 
572
573    Caller to free() result in domain, username, password
574 */
575
576 static void cm_get_ipc_userpass(char **username, char **domain, char **password)
577 {
578         *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
579         *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
580         *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
581
582         if (*username && **username) {
583
584                 if (!*domain || !**domain)
585                         *domain = smb_xstrdup(lp_workgroup());
586
587                 if (!*password || !**password)
588                         *password = smb_xstrdup("");
589
590                 DEBUG(3, ("cm_get_ipc_userpass: Retrieved auth-user from secrets.tdb [%s\\%s]\n", 
591                           *domain, *username));
592
593         } else {
594                 DEBUG(3, ("cm_get_ipc_userpass: No auth-user defined\n"));
595                 *username = smb_xstrdup("");
596                 *domain = smb_xstrdup("");
597                 *password = smb_xstrdup("");
598         }
599 }
600
601 static bool get_dc_name_via_netlogon(struct winbindd_domain *domain,
602                                      fstring dcname,
603                                      struct sockaddr_storage *dc_ss)
604 {
605         struct winbindd_domain *our_domain = NULL;
606         struct rpc_pipe_client *netlogon_pipe = NULL;
607         NTSTATUS result;
608         WERROR werr;
609         TALLOC_CTX *mem_ctx;
610         unsigned int orig_timeout;
611         const char *tmp = NULL;
612         const char *p;
613         struct dcerpc_binding_handle *b;
614
615         /* Hmmmm. We can only open one connection to the NETLOGON pipe at the
616          * moment.... */
617
618         if (IS_DC) {
619                 return False;
620         }
621
622         if (domain->primary) {
623                 return False;
624         }
625
626         our_domain = find_our_domain();
627
628         if ((mem_ctx = talloc_init("get_dc_name_via_netlogon")) == NULL) {
629                 return False;
630         }
631
632         result = cm_connect_netlogon(our_domain, &netlogon_pipe);
633         if (!NT_STATUS_IS_OK(result)) {
634                 talloc_destroy(mem_ctx);
635                 return False;
636         }
637
638         b = netlogon_pipe->binding_handle;
639
640         /* This call can take a long time - allow the server to time out.
641            35 seconds should do it. */
642
643         orig_timeout = rpccli_set_timeout(netlogon_pipe, 35000);
644
645         if (our_domain->active_directory) {
646                 struct netr_DsRGetDCNameInfo *domain_info = NULL;
647
648                 result = dcerpc_netr_DsRGetDCName(b,
649                                                   mem_ctx,
650                                                   our_domain->dcname,
651                                                   domain->name,
652                                                   NULL,
653                                                   NULL,
654                                                   DS_RETURN_DNS_NAME,
655                                                   &domain_info,
656                                                   &werr);
657                 if (NT_STATUS_IS_OK(result) && W_ERROR_IS_OK(werr)) {
658                         tmp = talloc_strdup(
659                                 mem_ctx, domain_info->dc_unc);
660                         if (tmp == NULL) {
661                                 DEBUG(0, ("talloc_strdup failed\n"));
662                                 talloc_destroy(mem_ctx);
663                                 return false;
664                         }
665                         if (strlen(domain->alt_name) == 0) {
666                                 fstrcpy(domain->alt_name,
667                                         domain_info->domain_name);
668                         }
669                         if (strlen(domain->forest_name) == 0) {
670                                 fstrcpy(domain->forest_name,
671                                         domain_info->forest_name);
672                         }
673                 }
674         } else {
675                 result = dcerpc_netr_GetAnyDCName(b, mem_ctx,
676                                                   our_domain->dcname,
677                                                   domain->name,
678                                                   &tmp,
679                                                   &werr);
680         }
681
682         /* And restore our original timeout. */
683         rpccli_set_timeout(netlogon_pipe, orig_timeout);
684
685         if (!NT_STATUS_IS_OK(result)) {
686                 DEBUG(10,("dcerpc_netr_GetAnyDCName failed: %s\n",
687                         nt_errstr(result)));
688                 talloc_destroy(mem_ctx);
689                 return false;
690         }
691
692         if (!W_ERROR_IS_OK(werr)) {
693                 DEBUG(10,("dcerpc_netr_GetAnyDCName failed: %s\n",
694                            win_errstr(werr)));
695                 talloc_destroy(mem_ctx);
696                 return false;
697         }
698
699         /* dcerpc_netr_GetAnyDCName gives us a name with \\ */
700         p = strip_hostname(tmp);
701
702         fstrcpy(dcname, p);
703
704         talloc_destroy(mem_ctx);
705
706         DEBUG(10,("dcerpc_netr_GetAnyDCName returned %s\n", dcname));
707
708         if (!resolve_name(dcname, dc_ss, 0x20, true)) {
709                 return False;
710         }
711
712         return True;
713 }
714
715 /**
716  * Helper function to assemble trust password and account name
717  */
718 static NTSTATUS get_trust_creds(const struct winbindd_domain *domain,
719                                 char **machine_password,
720                                 char **machine_account,
721                                 char **machine_krb5_principal)
722 {
723         const char *account_name;
724         const char *name = NULL;
725
726         /* If we are a DC and this is not our own domain */
727
728         if (IS_DC) {
729                 name = domain->name;
730         } else {
731                 struct winbindd_domain *our_domain = find_our_domain();
732
733                 if (!our_domain)
734                         return NT_STATUS_INVALID_SERVER_STATE;          
735
736                 name = our_domain->name;                
737         }       
738
739         if (!get_trust_pw_clear(name, machine_password,
740                                 &account_name, NULL))
741         {
742                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
743         }
744
745         if ((machine_account != NULL) &&
746             (asprintf(machine_account, "%s$", account_name) == -1))
747         {
748                 return NT_STATUS_NO_MEMORY;
749         }
750
751         /* For now assume our machine account only exists in our domain */
752
753         if (machine_krb5_principal != NULL)
754         {
755                 struct winbindd_domain *our_domain = find_our_domain();
756
757                 if (!our_domain) {
758                         return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;                       
759                 }
760
761                 if (asprintf(machine_krb5_principal, "%s$@%s",
762                              account_name, our_domain->alt_name) == -1)
763                 {
764                         return NT_STATUS_NO_MEMORY;
765                 }
766
767                 strupper_m(*machine_krb5_principal);
768         }
769
770         return NT_STATUS_OK;
771 }
772
773 /************************************************************************
774  Given a fd with a just-connected TCP connection to a DC, open a connection
775  to the pipe.
776 ************************************************************************/
777
778 static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
779                                       const int sockfd,
780                                       const char *controller,
781                                       struct cli_state **cli,
782                                       bool *retry)
783 {
784         char *machine_password = NULL;
785         char *machine_krb5_principal = NULL;
786         char *machine_account = NULL;
787         char *ipc_username = NULL;
788         char *ipc_domain = NULL;
789         char *ipc_password = NULL;
790
791         struct named_mutex *mutex;
792
793         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
794
795         DEBUG(10,("cm_prepare_connection: connecting to DC %s for domain %s\n",
796                 controller, domain->name ));
797
798         *retry = True;
799
800         mutex = grab_named_mutex(talloc_tos(), controller,
801                                  WINBIND_SERVER_MUTEX_WAIT_TIME);
802         if (mutex == NULL) {
803                 DEBUG(0,("cm_prepare_connection: mutex grab failed for %s\n",
804                          controller));
805                 result = NT_STATUS_POSSIBLE_DEADLOCK;
806                 goto done;
807         }
808
809         *cli = cli_state_create(NULL, sockfd,
810                                 controller, domain->alt_name,
811                                 Undefined);
812         if (*cli == NULL) {
813                 DEBUG(1, ("Could not cli_initialize\n"));
814                 result = NT_STATUS_NO_MEMORY;
815                 goto done;
816         }
817
818         cli_set_timeout(*cli, 10000); /* 10 seconds */
819
820         (*cli)->use_kerberos = True;
821
822         result = cli_negprot(*cli);
823
824         if (!NT_STATUS_IS_OK(result)) {
825                 DEBUG(1, ("cli_negprot failed: %s\n", nt_errstr(result)));
826                 goto done;
827         }
828
829         if (!is_dc_trusted_domain_situation(domain->name) &&
830             cli_state_protocol(*cli) >= PROTOCOL_NT1 &&
831             cli_state_capabilities(*cli) & CAP_EXTENDED_SECURITY)
832         {
833                 ADS_STATUS ads_status;
834
835                 result = get_trust_creds(domain, &machine_password,
836                                          &machine_account,
837                                          &machine_krb5_principal);
838                 if (!NT_STATUS_IS_OK(result)) {
839                         goto anon_fallback;
840                 }
841
842                 if (lp_security() == SEC_ADS) {
843
844                         /* Try a krb5 session */
845
846                         (*cli)->use_kerberos = True;
847                         DEBUG(5, ("connecting to %s from %s with kerberos principal "
848                                   "[%s] and realm [%s]\n", controller, lp_netbios_name(),
849                                   machine_krb5_principal, domain->alt_name));
850
851                         winbindd_set_locator_kdc_envs(domain);
852
853                         ads_status = cli_session_setup_spnego(*cli,
854                                                               machine_krb5_principal, 
855                                                               machine_password,
856                                                               lp_workgroup(),
857                                                               domain->alt_name);
858
859                         if (!ADS_ERR_OK(ads_status)) {
860                                 DEBUG(4,("failed kerberos session setup with %s\n",
861                                          ads_errstr(ads_status)));
862                         }
863
864                         result = ads_ntstatus(ads_status);
865                         if (NT_STATUS_IS_OK(result)) {
866                                 /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
867                                 result = cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
868                                 if (!NT_STATUS_IS_OK(result)) {
869                                         goto done;
870                                 }
871                                 goto session_setup_done;
872                         }
873                 }
874
875                 /* Fall back to non-kerberos session setup using NTLMSSP SPNEGO with the machine account. */
876                 (*cli)->use_kerberos = False;
877
878                 DEBUG(5, ("connecting to %s from %s with username "
879                           "[%s]\\[%s]\n",  controller, lp_netbios_name(),
880                           lp_workgroup(), machine_account));
881
882                 ads_status = cli_session_setup_spnego(*cli,
883                                                       machine_account, 
884                                                       machine_password, 
885                                                       lp_workgroup(),
886                                                       NULL);
887                 if (!ADS_ERR_OK(ads_status)) {
888                         DEBUG(4, ("authenticated session setup failed with %s\n",
889                                 ads_errstr(ads_status)));
890                 }
891
892                 result = ads_ntstatus(ads_status);
893                 if (NT_STATUS_IS_OK(result)) {
894                         /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
895                         result = cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
896                         if (!NT_STATUS_IS_OK(result)) {
897                                 goto done;
898                         }
899                         goto session_setup_done;
900                 }
901         }
902
903         /* Fall back to non-kerberos session setup with auth_user */
904
905         (*cli)->use_kerberos = False;
906
907         cm_get_ipc_userpass(&ipc_username, &ipc_domain, &ipc_password);
908
909         if ((((*cli)->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) != 0) &&
910             (strlen(ipc_username) > 0)) {
911
912                 /* Only try authenticated if we have a username */
913
914                 DEBUG(5, ("connecting to %s from %s with username "
915                           "[%s]\\[%s]\n",  controller, lp_netbios_name(),
916                           ipc_domain, ipc_username));
917
918                 if (NT_STATUS_IS_OK(cli_session_setup(
919                                             *cli, ipc_username,
920                                             ipc_password, strlen(ipc_password)+1,
921                                             ipc_password, strlen(ipc_password)+1,
922                                             ipc_domain))) {
923                         /* Successful logon with given username. */
924                         result = cli_init_creds(*cli, ipc_username, ipc_domain, ipc_password);
925                         if (!NT_STATUS_IS_OK(result)) {
926                                 goto done;
927                         }
928                         goto session_setup_done;
929                 } else {
930                         DEBUG(4, ("authenticated session setup with user %s\\%s failed.\n",
931                                 ipc_domain, ipc_username ));
932                 }
933         }
934
935  anon_fallback:
936
937         /* Fall back to anonymous connection, this might fail later */
938         DEBUG(10,("cm_prepare_connection: falling back to anonymous "
939                 "connection for DC %s\n",
940                 controller ));
941
942         if (NT_STATUS_IS_OK(cli_session_setup(*cli, "", NULL, 0,
943                                               NULL, 0, ""))) {
944                 DEBUG(5, ("Connected anonymously\n"));
945                 result = cli_init_creds(*cli, "", "", "");
946                 if (!NT_STATUS_IS_OK(result)) {
947                         goto done;
948                 }
949                 goto session_setup_done;
950         }
951
952         result = cli_nt_error(*cli);
953
954         if (NT_STATUS_IS_OK(result))
955                 result = NT_STATUS_UNSUCCESSFUL;
956
957         /* We can't session setup */
958
959         goto done;
960
961  session_setup_done:
962
963         /* cache the server name for later connections */
964
965         saf_store(domain->name, controller);
966         if (domain->alt_name && (*cli)->use_kerberos) {
967                 saf_store(domain->alt_name, controller);
968         }
969
970         winbindd_set_locator_kdc_envs(domain);
971
972         result = cli_tcon_andx(*cli, "IPC$", "IPC", "", 0);
973
974         if (!NT_STATUS_IS_OK(result)) {
975                 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(result)));
976                 goto done;
977         }
978
979         TALLOC_FREE(mutex);
980         *retry = False;
981
982         /* set the domain if empty; needed for schannel connections */
983         if ( !(*cli)->domain[0] ) {
984                 result = cli_set_domain((*cli), domain->name);
985                 if (!NT_STATUS_IS_OK(result)) {
986                         return result;
987                 }
988         }
989
990         result = NT_STATUS_OK;
991
992  done:
993         TALLOC_FREE(mutex);
994         SAFE_FREE(machine_account);
995         SAFE_FREE(machine_password);
996         SAFE_FREE(machine_krb5_principal);
997         SAFE_FREE(ipc_username);
998         SAFE_FREE(ipc_domain);
999         SAFE_FREE(ipc_password);
1000
1001         if (!NT_STATUS_IS_OK(result)) {
1002                 winbind_add_failed_connection_entry(domain, controller, result);
1003                 if ((*cli) != NULL) {
1004                         cli_shutdown(*cli);
1005                         *cli = NULL;
1006                 }
1007         }
1008
1009         return result;
1010 }
1011
1012 /*******************************************************************
1013  Add a dcname and sockaddr_storage pair to the end of a dc_name_ip
1014  array.
1015
1016  Keeps the list unique by not adding duplicate entries.
1017
1018  @param[in] mem_ctx talloc memory context to allocate from
1019  @param[in] domain_name domain of the DC
1020  @param[in] dcname name of the DC to add to the list
1021  @param[in] pss Internet address and port pair to add to the list
1022  @param[in,out] dcs array of dc_name_ip structures to add to
1023  @param[in,out] num_dcs number of dcs returned in the dcs array
1024  @return true if the list was added to, false otherwise
1025 *******************************************************************/
1026
1027 static bool add_one_dc_unique(TALLOC_CTX *mem_ctx, const char *domain_name,
1028                               const char *dcname, struct sockaddr_storage *pss,
1029                               struct dc_name_ip **dcs, int *num)
1030 {
1031         int i = 0;
1032
1033         if (!NT_STATUS_IS_OK(check_negative_conn_cache(domain_name, dcname))) {
1034                 DEBUG(10, ("DC %s was in the negative conn cache\n", dcname));
1035                 return False;
1036         }
1037
1038         /* Make sure there's no duplicates in the list */
1039         for (i=0; i<*num; i++)
1040                 if (sockaddr_equal(
1041                             (struct sockaddr *)(void *)&(*dcs)[i].ss,
1042                             (struct sockaddr *)(void *)pss))
1043                         return False;
1044
1045         *dcs = talloc_realloc(mem_ctx, *dcs, struct dc_name_ip, (*num)+1);
1046
1047         if (*dcs == NULL)
1048                 return False;
1049
1050         fstrcpy((*dcs)[*num].name, dcname);
1051         (*dcs)[*num].ss = *pss;
1052         *num += 1;
1053         return True;
1054 }
1055
1056 static bool add_sockaddr_to_array(TALLOC_CTX *mem_ctx,
1057                                   struct sockaddr_storage *pss, uint16 port,
1058                                   struct sockaddr_storage **addrs, int *num)
1059 {
1060         *addrs = talloc_realloc(mem_ctx, *addrs, struct sockaddr_storage, (*num)+1);
1061
1062         if (*addrs == NULL) {
1063                 *num = 0;
1064                 return False;
1065         }
1066
1067         (*addrs)[*num] = *pss;
1068         set_sockaddr_port((struct sockaddr *)&(*addrs)[*num], port);
1069
1070         *num += 1;
1071         return True;
1072 }
1073
1074 /*******************************************************************
1075  convert an ip to a name
1076 *******************************************************************/
1077
1078 static bool dcip_to_name(TALLOC_CTX *mem_ctx,
1079                 const struct winbindd_domain *domain,
1080                 struct sockaddr_storage *pss,
1081                 fstring name )
1082 {
1083         struct ip_service ip_list;
1084         uint32_t nt_version = NETLOGON_NT_VERSION_1;
1085         NTSTATUS status;
1086         const char *dc_name;
1087
1088         ip_list.ss = *pss;
1089         ip_list.port = 0;
1090
1091 #ifdef HAVE_ADS
1092         /* For active directory servers, try to get the ldap server name.
1093            None of these failures should be considered critical for now */
1094
1095         if (lp_security() == SEC_ADS) {
1096                 ADS_STRUCT *ads;
1097                 ADS_STATUS ads_status;
1098                 char addr[INET6_ADDRSTRLEN];
1099
1100                 print_sockaddr(addr, sizeof(addr), pss);
1101
1102                 ads = ads_init(domain->alt_name, domain->name, addr);
1103                 ads->auth.flags |= ADS_AUTH_NO_BIND;
1104
1105                 ads_status = ads_connect(ads);
1106                 if (ADS_ERR_OK(ads_status)) {
1107                         /* We got a cldap packet. */
1108                         fstrcpy(name, ads->config.ldap_server_name);
1109                         namecache_store(name, 0x20, 1, &ip_list);
1110
1111                         DEBUG(10,("dcip_to_name: flags = 0x%x\n", (unsigned int)ads->config.flags));
1112
1113                         if (domain->primary && (ads->config.flags & NBT_SERVER_KDC)) {
1114                                 if (ads_closest_dc(ads)) {
1115                                         char *sitename = sitename_fetch(ads->config.realm);
1116
1117                                         /* We're going to use this KDC for this realm/domain.
1118                                            If we are using sites, then force the krb5 libs
1119                                            to use this KDC. */
1120
1121                                         create_local_private_krb5_conf_for_domain(domain->alt_name,
1122                                                                         domain->name,
1123                                                                         sitename,
1124                                                                         pss,
1125                                                                         name);
1126
1127                                         SAFE_FREE(sitename);
1128                                 } else {
1129                                         /* use an off site KDC */
1130                                         create_local_private_krb5_conf_for_domain(domain->alt_name,
1131                                                                         domain->name,
1132                                                                         NULL,
1133                                                                         pss,
1134                                                                         name);
1135                                 }
1136                                 winbindd_set_locator_kdc_envs(domain);
1137
1138                                 /* Ensure we contact this DC also. */
1139                                 saf_store( domain->name, name);
1140                                 saf_store( domain->alt_name, name);
1141                         }
1142
1143                         ads_destroy( &ads );
1144                         return True;
1145                 }
1146
1147                 ads_destroy( &ads );
1148         }
1149 #endif
1150
1151         status = nbt_getdc(winbind_messaging_context(), pss, domain->name,
1152                            &domain->sid, nt_version, mem_ctx, &nt_version,
1153                            &dc_name, NULL);
1154         if (NT_STATUS_IS_OK(status)) {
1155                 fstrcpy(name, dc_name);
1156                 namecache_store(name, 0x20, 1, &ip_list);
1157                 return True;
1158         }
1159
1160         /* try node status request */
1161
1162         if ( name_status_find(domain->name, 0x1c, 0x20, pss, name) ) {
1163                 namecache_store(name, 0x20, 1, &ip_list);
1164                 return True;
1165         }
1166         return False;
1167 }
1168
1169 /*******************************************************************
1170  Retrieve a list of IP addresses for domain controllers.
1171
1172  The array is sorted in the preferred connection order.
1173
1174  @param[in] mem_ctx talloc memory context to allocate from
1175  @param[in] domain domain to retrieve DCs for
1176  @param[out] dcs array of dcs that will be returned
1177  @param[out] num_dcs number of dcs returned in the dcs array
1178  @return always true
1179 *******************************************************************/
1180
1181 static bool get_dcs(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
1182                     struct dc_name_ip **dcs, int *num_dcs)
1183 {
1184         fstring dcname;
1185         struct  sockaddr_storage ss;
1186         struct  ip_service *ip_list = NULL;
1187         int     iplist_size = 0;
1188         int     i;
1189         bool    is_our_domain;
1190         enum security_types sec = (enum security_types)lp_security();
1191
1192         is_our_domain = strequal(domain->name, lp_workgroup());
1193
1194         /* If not our domain, get the preferred DC, by asking our primary DC */
1195         if ( !is_our_domain
1196                 && get_dc_name_via_netlogon(domain, dcname, &ss)
1197                 && add_one_dc_unique(mem_ctx, domain->name, dcname, &ss, dcs,
1198                        num_dcs) )
1199         {
1200                 char addr[INET6_ADDRSTRLEN];
1201                 print_sockaddr(addr, sizeof(addr), &ss);
1202                 DEBUG(10, ("Retrieved DC %s at %s via netlogon\n",
1203                            dcname, addr));
1204                 return True;
1205         }
1206
1207         if (sec == SEC_ADS) {
1208                 char *sitename = NULL;
1209
1210                 /* We need to make sure we know the local site before
1211                    doing any DNS queries, as this will restrict the
1212                    get_sorted_dc_list() call below to only fetching
1213                    DNS records for the correct site. */
1214
1215                 /* Find any DC to get the site record.
1216                    We deliberately don't care about the
1217                    return here. */
1218
1219                 get_dc_name(domain->name, domain->alt_name, dcname, &ss);
1220
1221                 sitename = sitename_fetch(domain->alt_name);
1222                 if (sitename) {
1223
1224                         /* Do the site-specific AD dns lookup first. */
1225                         get_sorted_dc_list(domain->alt_name, sitename, &ip_list,
1226                                &iplist_size, True);
1227
1228                         /* Add ips to the DC array.  We don't look up the name
1229                            of the DC in this function, but we fill in the char*
1230                            of the ip now to make the failed connection cache
1231                            work */
1232                         for ( i=0; i<iplist_size; i++ ) {
1233                                 char addr[INET6_ADDRSTRLEN];
1234                                 print_sockaddr(addr, sizeof(addr),
1235                                                 &ip_list[i].ss);
1236                                 add_one_dc_unique(mem_ctx,
1237                                                 domain->name,
1238                                                 addr,
1239                                                 &ip_list[i].ss,
1240                                                 dcs,
1241                                                 num_dcs);
1242                         }
1243
1244                         SAFE_FREE(ip_list);
1245                         SAFE_FREE(sitename);
1246                         iplist_size = 0;
1247                 }
1248
1249                 /* Now we add DCs from the main AD DNS lookup. */
1250                 get_sorted_dc_list(domain->alt_name, NULL, &ip_list,
1251                         &iplist_size, True);
1252
1253                 for ( i=0; i<iplist_size; i++ ) {
1254                         char addr[INET6_ADDRSTRLEN];
1255                         print_sockaddr(addr, sizeof(addr),
1256                                         &ip_list[i].ss);
1257                         add_one_dc_unique(mem_ctx,
1258                                         domain->name,
1259                                         addr,
1260                                         &ip_list[i].ss,
1261                                         dcs,
1262                                         num_dcs);
1263                 }
1264
1265                 SAFE_FREE(ip_list);
1266                 iplist_size = 0;
1267         }
1268
1269         /* Try standard netbios queries if no ADS */
1270         if (*num_dcs == 0) {
1271                 get_sorted_dc_list(domain->name, NULL, &ip_list, &iplist_size,
1272                        False);
1273
1274                 for ( i=0; i<iplist_size; i++ ) {
1275                         char addr[INET6_ADDRSTRLEN];
1276                         print_sockaddr(addr, sizeof(addr),
1277                                         &ip_list[i].ss);
1278                         add_one_dc_unique(mem_ctx,
1279                                         domain->name,
1280                                         addr,
1281                                         &ip_list[i].ss,
1282                                         dcs,
1283                                         num_dcs);
1284                 }
1285
1286                 SAFE_FREE(ip_list);
1287                 iplist_size = 0;
1288         }
1289
1290         return True;
1291 }
1292
1293 /*******************************************************************
1294  Find and make a connection to a DC in the given domain.
1295
1296  @param[in] mem_ctx talloc memory context to allocate from
1297  @param[in] domain domain to find a dc in
1298  @param[out] dcname NetBIOS or FQDN of DC that's connected to
1299  @param[out] pss DC Internet address and port
1300  @param[out] fd fd of the open socket connected to the newly found dc
1301  @return true when a DC connection is made, false otherwise
1302 *******************************************************************/
1303
1304 static bool find_new_dc(TALLOC_CTX *mem_ctx,
1305                         struct winbindd_domain *domain,
1306                         fstring dcname, struct sockaddr_storage *pss, int *fd)
1307 {
1308         struct dc_name_ip *dcs = NULL;
1309         int num_dcs = 0;
1310
1311         const char **dcnames = NULL;
1312         int num_dcnames = 0;
1313
1314         struct sockaddr_storage *addrs = NULL;
1315         int num_addrs = 0;
1316
1317         int i;
1318         size_t fd_index;
1319
1320         NTSTATUS status;
1321
1322         *fd = -1;
1323
1324  again:
1325         if (!get_dcs(mem_ctx, domain, &dcs, &num_dcs) || (num_dcs == 0))
1326                 return False;
1327
1328         for (i=0; i<num_dcs; i++) {
1329
1330                 if (!add_string_to_array(mem_ctx, dcs[i].name,
1331                                     &dcnames, &num_dcnames)) {
1332                         return False;
1333                 }
1334                 if (!add_sockaddr_to_array(mem_ctx, &dcs[i].ss, 445,
1335                                       &addrs, &num_addrs)) {
1336                         return False;
1337                 }
1338         }
1339
1340         if ((num_dcnames == 0) || (num_dcnames != num_addrs))
1341                 return False;
1342
1343         if ((addrs == NULL) || (dcnames == NULL))
1344                 return False;
1345
1346         status = smbsock_any_connect(addrs, dcnames, NULL, NULL, NULL,
1347                                      num_addrs, 0, 10, fd, &fd_index, NULL);
1348         if (!NT_STATUS_IS_OK(status)) {
1349                 for (i=0; i<num_dcs; i++) {
1350                         char ab[INET6_ADDRSTRLEN];
1351                         print_sockaddr(ab, sizeof(ab), &dcs[i].ss);
1352                         DEBUG(10, ("find_new_dc: smbsock_any_connect failed for "
1353                                 "domain %s address %s. Error was %s\n",
1354                                    domain->name, ab, nt_errstr(status) ));
1355                         winbind_add_failed_connection_entry(domain,
1356                                 dcs[i].name, NT_STATUS_UNSUCCESSFUL);
1357                 }
1358                 return False;
1359         }
1360
1361         *pss = addrs[fd_index];
1362
1363         if (*dcnames[fd_index] != '\0' && !is_ipaddress(dcnames[fd_index])) {
1364                 /* Ok, we've got a name for the DC */
1365                 fstrcpy(dcname, dcnames[fd_index]);
1366                 return True;
1367         }
1368
1369         /* Try to figure out the name */
1370         if (dcip_to_name(mem_ctx, domain, pss, dcname)) {
1371                 return True;
1372         }
1373
1374         /* We can not continue without the DC's name */
1375         winbind_add_failed_connection_entry(domain, dcs[fd_index].name,
1376                                     NT_STATUS_UNSUCCESSFUL);
1377
1378         /* Throw away all arrays as we're doing this again. */
1379         TALLOC_FREE(dcs);
1380         num_dcs = 0;
1381
1382         TALLOC_FREE(dcnames);
1383         num_dcnames = 0;
1384
1385         TALLOC_FREE(addrs);
1386         num_addrs = 0;
1387
1388         close(*fd);
1389         *fd = -1;
1390
1391         goto again;
1392 }
1393
1394 static char *current_dc_key(TALLOC_CTX *mem_ctx, const char *domain_name)
1395 {
1396         return talloc_asprintf_strupper_m(mem_ctx, "CURRENT_DCNAME/%s",
1397                                           domain_name);
1398 }
1399
1400 static void store_current_dc_in_gencache(const char *domain_name,
1401                                          const char *dc_name,
1402                                          struct cli_state *cli)
1403 {
1404         char addr[INET6_ADDRSTRLEN];
1405         char *key = NULL;
1406         char *value = NULL;
1407
1408         if (!cli_state_is_connected(cli)) {
1409                 return;
1410         }
1411
1412         print_sockaddr(addr, sizeof(addr),
1413                        cli_state_remote_sockaddr(cli));
1414
1415         key = current_dc_key(talloc_tos(), domain_name);
1416         if (key == NULL) {
1417                 goto done;
1418         }
1419
1420         value = talloc_asprintf(talloc_tos(), "%s %s", addr, dc_name);
1421         if (value == NULL) {
1422                 goto done;
1423         }
1424
1425         gencache_set(key, value, 0x7fffffff);
1426 done:
1427         TALLOC_FREE(value);
1428         TALLOC_FREE(key);
1429 }
1430
1431 bool fetch_current_dc_from_gencache(TALLOC_CTX *mem_ctx,
1432                                     const char *domain_name,
1433                                     char **p_dc_name, char **p_dc_ip)
1434 {
1435         char *key, *value, *p;
1436         bool ret = false;
1437         char *dc_name = NULL;
1438         char *dc_ip = NULL;
1439
1440         key = current_dc_key(talloc_tos(), domain_name);
1441         if (key == NULL) {
1442                 goto done;
1443         }
1444         if (!gencache_get(key, &value, NULL)) {
1445                 goto done;
1446         }
1447         p = strchr(value, ' ');
1448         if (p == NULL) {
1449                 goto done;
1450         }
1451         dc_ip = talloc_strndup(mem_ctx, value, p - value);
1452         if (dc_ip == NULL) {
1453                 goto done;
1454         }
1455         dc_name = talloc_strdup(mem_ctx, p+1);
1456         if (dc_name == NULL) {
1457                 goto done;
1458         }
1459
1460         if (p_dc_ip != NULL) {
1461                 *p_dc_ip = dc_ip;
1462                 dc_ip = NULL;
1463         }
1464         if (p_dc_name != NULL) {
1465                 *p_dc_name = dc_name;
1466                 dc_name = NULL;
1467         }
1468         ret = true;
1469 done:
1470         TALLOC_FREE(dc_name);
1471         TALLOC_FREE(dc_ip);
1472         TALLOC_FREE(key);
1473         return ret;
1474 }
1475
1476 static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
1477                                    struct winbindd_cm_conn *new_conn)
1478 {
1479         TALLOC_CTX *mem_ctx;
1480         NTSTATUS result;
1481         char *saf_servername = saf_fetch( domain->name );
1482         int retries;
1483
1484         if ((mem_ctx = talloc_init("cm_open_connection")) == NULL) {
1485                 SAFE_FREE(saf_servername);
1486                 set_domain_offline(domain);
1487                 return NT_STATUS_NO_MEMORY;
1488         }
1489
1490         /* we have to check the server affinity cache here since 
1491            later we select a DC based on response time and not preference */
1492
1493         /* Check the negative connection cache
1494            before talking to it. It going down may have
1495            triggered the reconnection. */
1496
1497         if ( saf_servername && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, saf_servername))) {
1498
1499                 DEBUG(10,("cm_open_connection: saf_servername is '%s' for domain %s\n",
1500                         saf_servername, domain->name ));
1501
1502                 /* convert an ip address to a name */
1503                 if (is_ipaddress( saf_servername ) ) {
1504                         fstring saf_name;
1505                         struct sockaddr_storage ss;
1506
1507                         if (!interpret_string_addr(&ss, saf_servername,
1508                                                 AI_NUMERICHOST)) {
1509                                 return NT_STATUS_UNSUCCESSFUL;
1510                         }
1511                         if (dcip_to_name(mem_ctx, domain, &ss, saf_name )) {
1512                                 strlcpy(domain->dcname, saf_name, sizeof(domain->dcname));
1513                         } else {
1514                                 winbind_add_failed_connection_entry(
1515                                         domain, saf_servername,
1516                                         NT_STATUS_UNSUCCESSFUL);
1517                         }
1518                 } else {
1519                         fstrcpy( domain->dcname, saf_servername );
1520                 }
1521
1522                 SAFE_FREE( saf_servername );
1523         }
1524
1525         for (retries = 0; retries < 3; retries++) {
1526                 int fd = -1;
1527                 bool retry = False;
1528
1529                 result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1530
1531                 DEBUG(10,("cm_open_connection: dcname is '%s' for domain %s\n",
1532                         domain->dcname, domain->name ));
1533
1534                 if (*domain->dcname 
1535                         && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, domain->dcname))
1536                         && (resolve_name(domain->dcname, &domain->dcaddr, 0x20, true)))
1537                 {
1538                         NTSTATUS status;
1539
1540                         status = smbsock_connect(&domain->dcaddr, 0,
1541                                                  NULL, -1, NULL, -1,
1542                                                  &fd, NULL, 10);
1543                         if (!NT_STATUS_IS_OK(status)) {
1544                                 fd = -1;
1545                         }
1546                 }
1547
1548                 if ((fd == -1) 
1549                         && !find_new_dc(mem_ctx, domain, domain->dcname, &domain->dcaddr, &fd))
1550                 {
1551                         /* This is the one place where we will
1552                            set the global winbindd offline state
1553                            to true, if a "WINBINDD_OFFLINE" entry
1554                            is found in the winbindd cache. */
1555                         set_global_winbindd_state_offline();
1556                         break;
1557                 }
1558
1559                 new_conn->cli = NULL;
1560
1561                 result = cm_prepare_connection(domain, fd, domain->dcname,
1562                         &new_conn->cli, &retry);
1563
1564                 if (!retry)
1565                         break;
1566         }
1567
1568         if (NT_STATUS_IS_OK(result)) {
1569
1570                 winbindd_set_locator_kdc_envs(domain);
1571
1572                 if (domain->online == False) {
1573                         /* We're changing state from offline to online. */
1574                         set_global_winbindd_state_online();
1575                 }
1576                 set_domain_online(domain);
1577
1578                 /*
1579                  * Much as I hate global state, this seems to be the point
1580                  * where we can be certain that we have a proper connection to
1581                  * a DC. wbinfo --dc-info needs that information, store it in
1582                  * gencache with a looong timeout. This will need revisiting
1583                  * once we start to connect to multiple DCs, wbcDcInfo is
1584                  * already prepared for that.
1585                  */
1586                 store_current_dc_in_gencache(domain->name, domain->dcname,
1587                                              new_conn->cli);
1588         } else {
1589                 /* Ensure we setup the retry handler. */
1590                 set_domain_offline(domain);
1591         }
1592
1593         talloc_destroy(mem_ctx);
1594         return result;
1595 }
1596
1597 /* Close down all open pipes on a connection. */
1598
1599 void invalidate_cm_connection(struct winbindd_cm_conn *conn)
1600 {
1601         NTSTATUS result;
1602
1603         /* We're closing down a possibly dead
1604            connection. Don't have impossibly long (10s) timeouts. */
1605
1606         if (conn->cli) {
1607                 cli_set_timeout(conn->cli, 1000); /* 1 second. */
1608         }
1609
1610         if (conn->samr_pipe != NULL) {
1611                 if (is_valid_policy_hnd(&conn->sam_connect_handle)) {
1612                         dcerpc_samr_Close(conn->samr_pipe->binding_handle,
1613                                           talloc_tos(),
1614                                           &conn->sam_connect_handle,
1615                                           &result);
1616                 }
1617                 TALLOC_FREE(conn->samr_pipe);
1618                 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1619                 if (conn->cli) {
1620                         cli_set_timeout(conn->cli, 500);
1621                 }
1622         }
1623
1624         if (conn->lsa_pipe != NULL) {
1625                 if (is_valid_policy_hnd(&conn->lsa_policy)) {
1626                         dcerpc_lsa_Close(conn->lsa_pipe->binding_handle,
1627                                          talloc_tos(),
1628                                          &conn->lsa_policy,
1629                                          &result);
1630                 }
1631                 TALLOC_FREE(conn->lsa_pipe);
1632                 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1633                 if (conn->cli) {
1634                         cli_set_timeout(conn->cli, 500);
1635                 }
1636         }
1637
1638         if (conn->lsa_pipe_tcp != NULL) {
1639                 if (is_valid_policy_hnd(&conn->lsa_policy)) {
1640                         dcerpc_lsa_Close(conn->lsa_pipe_tcp->binding_handle,
1641                                          talloc_tos(),
1642                                          &conn->lsa_policy,
1643                                          &result);
1644                 }
1645                 TALLOC_FREE(conn->lsa_pipe_tcp);
1646                 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1647                 if (conn->cli) {
1648                         cli_set_timeout(conn->cli, 500);
1649                 }
1650         }
1651
1652         if (conn->netlogon_pipe != NULL) {
1653                 TALLOC_FREE(conn->netlogon_pipe);
1654                 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1655                 if (conn->cli) {
1656                         cli_set_timeout(conn->cli, 500);
1657                 }
1658         }
1659
1660         if (conn->cli) {
1661                 cli_shutdown(conn->cli);
1662         }
1663
1664         conn->cli = NULL;
1665 }
1666
1667 void close_conns_after_fork(void)
1668 {
1669         struct winbindd_domain *domain;
1670         struct winbindd_cli_state *cli_state;
1671
1672         for (domain = domain_list(); domain; domain = domain->next) {
1673                 /*
1674                  * first close the low level SMB TCP connection
1675                  * so that we don't generate any SMBclose
1676                  * requests in invalidate_cm_connection()
1677                  */
1678                 if (cli_state_is_connected(domain->conn.cli)) {
1679                         cli_state_disconnect(domain->conn.cli);
1680                 }
1681
1682                 invalidate_cm_connection(&domain->conn);
1683         }
1684
1685         for (cli_state = winbindd_client_list();
1686              cli_state != NULL;
1687              cli_state = cli_state->next) {
1688                 if (cli_state->sock >= 0) {
1689                         close(cli_state->sock);
1690                         cli_state->sock = -1;
1691                 }
1692         }
1693 }
1694
1695 static bool connection_ok(struct winbindd_domain *domain)
1696 {
1697         bool ok;
1698
1699         ok = cli_state_is_connected(domain->conn.cli);
1700         if (!ok) {
1701                 DEBUG(3, ("connection_ok: Connection to %s for domain %s is not connected\n",
1702                           domain->dcname, domain->name));
1703                 return False;
1704         }
1705
1706         if (domain->online == False) {
1707                 DEBUG(3, ("connection_ok: Domain %s is offline\n", domain->name));
1708                 return False;
1709         }
1710
1711         return True;
1712 }
1713
1714 /* Initialize a new connection up to the RPC BIND.
1715    Bypass online status check so always does network calls. */
1716
1717 static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain)
1718 {
1719         NTSTATUS result;
1720
1721         /* Internal connections never use the network. */
1722         if (domain->internal) {
1723                 domain->initialized = True;
1724                 return NT_STATUS_OK;
1725         }
1726
1727         if (!winbindd_can_contact_domain(domain)) {
1728                 invalidate_cm_connection(&domain->conn);
1729                 domain->initialized = True;
1730                 return NT_STATUS_OK;
1731         }
1732
1733         if (connection_ok(domain)) {
1734                 if (!domain->initialized) {
1735                         set_dc_type_and_flags(domain);
1736                 }
1737                 return NT_STATUS_OK;
1738         }
1739
1740         invalidate_cm_connection(&domain->conn);
1741
1742         result = cm_open_connection(domain, &domain->conn);
1743
1744         if (NT_STATUS_IS_OK(result) && !domain->initialized) {
1745                 set_dc_type_and_flags(domain);
1746         }
1747
1748         return result;
1749 }
1750
1751 NTSTATUS init_dc_connection(struct winbindd_domain *domain)
1752 {
1753         if (domain->internal) {
1754                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1755         }
1756
1757         if (domain->initialized && !domain->online) {
1758                 /* We check for online status elsewhere. */
1759                 return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1760         }
1761
1762         return init_dc_connection_network(domain);
1763 }
1764
1765 static NTSTATUS init_dc_connection_rpc(struct winbindd_domain *domain)
1766 {
1767         NTSTATUS status;
1768
1769         status = init_dc_connection(domain);
1770         if (!NT_STATUS_IS_OK(status)) {
1771                 return status;
1772         }
1773
1774         if (!domain->internal && domain->conn.cli == NULL) {
1775                 /* happens for trusted domains without inbound trust */
1776                 return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
1777         }
1778
1779         return NT_STATUS_OK;
1780 }
1781
1782 /******************************************************************************
1783  Set the trust flags (direction and forest location) for a domain
1784 ******************************************************************************/
1785
1786 static bool set_dc_type_and_flags_trustinfo( struct winbindd_domain *domain )
1787 {
1788         struct winbindd_domain *our_domain;
1789         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1790         WERROR werr;
1791         struct netr_DomainTrustList trusts;
1792         int i;
1793         uint32 flags = (NETR_TRUST_FLAG_IN_FOREST |
1794                         NETR_TRUST_FLAG_OUTBOUND |
1795                         NETR_TRUST_FLAG_INBOUND);
1796         struct rpc_pipe_client *cli;
1797         TALLOC_CTX *mem_ctx = NULL;
1798         struct dcerpc_binding_handle *b;
1799
1800         DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s\n", domain->name ));
1801
1802         /* Our primary domain doesn't need to worry about trust flags.
1803            Force it to go through the network setup */
1804         if ( domain->primary ) {                
1805                 return False;           
1806         }
1807
1808         our_domain = find_our_domain();
1809
1810         if ( !connection_ok(our_domain) ) {
1811                 DEBUG(3,("set_dc_type_and_flags_trustinfo: No connection to our domain!\n"));           
1812                 return False;
1813         }
1814
1815         /* This won't work unless our domain is AD */
1816
1817         if ( !our_domain->active_directory ) {
1818                 return False;
1819         }
1820
1821         /* Use DsEnumerateDomainTrusts to get us the trust direction
1822            and type */
1823
1824         result = cm_connect_netlogon(our_domain, &cli);
1825
1826         if (!NT_STATUS_IS_OK(result)) {
1827                 DEBUG(5, ("set_dc_type_and_flags_trustinfo: Could not open "
1828                           "a connection to %s for PIPE_NETLOGON (%s)\n", 
1829                           domain->name, nt_errstr(result)));
1830                 return False;
1831         }
1832
1833         b = cli->binding_handle;
1834
1835         if ( (mem_ctx = talloc_init("set_dc_type_and_flags_trustinfo")) == NULL ) {
1836                 DEBUG(0,("set_dc_type_and_flags_trustinfo: talloc_init() failed!\n"));
1837                 return False;
1838         }       
1839
1840         result = dcerpc_netr_DsrEnumerateDomainTrusts(b, mem_ctx,
1841                                                       cli->desthost,
1842                                                       flags,
1843                                                       &trusts,
1844                                                       &werr);
1845         if (!NT_STATUS_IS_OK(result)) {
1846                 DEBUG(0,("set_dc_type_and_flags_trustinfo: "
1847                         "failed to query trusted domain list: %s\n",
1848                         nt_errstr(result)));
1849                 talloc_destroy(mem_ctx);
1850                 return false;
1851         }
1852         if (!W_ERROR_IS_OK(werr)) {
1853                 DEBUG(0,("set_dc_type_and_flags_trustinfo: "
1854                         "failed to query trusted domain list: %s\n",
1855                         win_errstr(werr)));
1856                 talloc_destroy(mem_ctx);
1857                 return false;
1858         }
1859
1860         /* Now find the domain name and get the flags */
1861
1862         for ( i=0; i<trusts.count; i++ ) {
1863                 if ( strequal( domain->name, trusts.array[i].netbios_name) ) {
1864                         domain->domain_flags          = trusts.array[i].trust_flags;
1865                         domain->domain_type           = trusts.array[i].trust_type;
1866                         domain->domain_trust_attribs  = trusts.array[i].trust_attributes;
1867
1868                         if ( domain->domain_type == NETR_TRUST_TYPE_UPLEVEL )
1869                                 domain->active_directory = True;
1870
1871                         /* This flag is only set if the domain is *our* 
1872                            primary domain and the primary domain is in
1873                            native mode */
1874
1875                         domain->native_mode = (domain->domain_flags & NETR_TRUST_FLAG_NATIVE);
1876
1877                         DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s is %sin "
1878                                   "native mode.\n", domain->name, 
1879                                   domain->native_mode ? "" : "NOT "));
1880
1881                         DEBUG(5,("set_dc_type_and_flags_trustinfo: domain %s is %s"
1882                                  "running active directory.\n", domain->name, 
1883                                  domain->active_directory ? "" : "NOT "));
1884
1885
1886                         domain->initialized = True;
1887
1888                         break;
1889                 }               
1890         }
1891
1892         talloc_destroy( mem_ctx );
1893
1894         return domain->initialized;     
1895 }
1896
1897 /******************************************************************************
1898  We can 'sense' certain things about the DC by it's replies to certain
1899  questions.
1900
1901  This tells us if this particular remote server is Active Directory, and if it
1902  is native mode.
1903 ******************************************************************************/
1904
1905 static void set_dc_type_and_flags_connect( struct winbindd_domain *domain )
1906 {
1907         NTSTATUS status, result;
1908         WERROR werr;
1909         TALLOC_CTX              *mem_ctx = NULL;
1910         struct rpc_pipe_client  *cli = NULL;
1911         struct policy_handle pol;
1912         union dssetup_DsRoleInfo info;
1913         union lsa_PolicyInformation *lsa_info = NULL;
1914
1915         if (!connection_ok(domain)) {
1916                 return;
1917         }
1918
1919         mem_ctx = talloc_init("set_dc_type_and_flags on domain %s\n",
1920                               domain->name);
1921         if (!mem_ctx) {
1922                 DEBUG(1, ("set_dc_type_and_flags_connect: talloc_init() failed\n"));
1923                 return;
1924         }
1925
1926         DEBUG(5, ("set_dc_type_and_flags_connect: domain %s\n", domain->name ));
1927
1928         status = cli_rpc_pipe_open_noauth(domain->conn.cli,
1929                                           &ndr_table_dssetup.syntax_id,
1930                                           &cli);
1931
1932         if (!NT_STATUS_IS_OK(status)) {
1933                 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
1934                           "PI_DSSETUP on domain %s: (%s)\n",
1935                           domain->name, nt_errstr(status)));
1936
1937                 /* if this is just a non-AD domain we need to continue
1938                  * identifying so that we can in the end return with
1939                  * domain->initialized = True - gd */
1940
1941                 goto no_dssetup;
1942         }
1943
1944         status = dcerpc_dssetup_DsRoleGetPrimaryDomainInformation(cli->binding_handle, mem_ctx,
1945                                                                   DS_ROLE_BASIC_INFORMATION,
1946                                                                   &info,
1947                                                                   &werr);
1948         TALLOC_FREE(cli);
1949
1950         if (NT_STATUS_IS_OK(status)) {
1951                 result = werror_to_ntstatus(werr);
1952         }
1953         if (!NT_STATUS_IS_OK(status)) {
1954                 DEBUG(5, ("set_dc_type_and_flags_connect: rpccli_ds_getprimarydominfo "
1955                           "on domain %s failed: (%s)\n",
1956                           domain->name, nt_errstr(status)));
1957
1958                 /* older samba3 DCs will return DCERPC_FAULT_OP_RNG_ERROR for
1959                  * every opcode on the DSSETUP pipe, continue with
1960                  * no_dssetup mode here as well to get domain->initialized
1961                  * set - gd */
1962
1963                 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
1964                         goto no_dssetup;
1965                 }
1966
1967                 TALLOC_FREE(mem_ctx);
1968                 return;
1969         }
1970
1971         if ((info.basic.flags & DS_ROLE_PRIMARY_DS_RUNNING) &&
1972             !(info.basic.flags & DS_ROLE_PRIMARY_DS_MIXED_MODE)) {
1973                 domain->native_mode = True;
1974         } else {
1975                 domain->native_mode = False;
1976         }
1977
1978 no_dssetup:
1979         status = cli_rpc_pipe_open_noauth(domain->conn.cli,
1980                                           &ndr_table_lsarpc.syntax_id, &cli);
1981
1982         if (!NT_STATUS_IS_OK(status)) {
1983                 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
1984                           "PI_LSARPC on domain %s: (%s)\n",
1985                           domain->name, nt_errstr(status)));
1986                 TALLOC_FREE(cli);
1987                 TALLOC_FREE(mem_ctx);
1988                 return;
1989         }
1990
1991         status = rpccli_lsa_open_policy2(cli, mem_ctx, True,
1992                                          SEC_FLAG_MAXIMUM_ALLOWED, &pol);
1993
1994         if (NT_STATUS_IS_OK(status)) {
1995                 /* This particular query is exactly what Win2k clients use 
1996                    to determine that the DC is active directory */
1997                 status = dcerpc_lsa_QueryInfoPolicy2(cli->binding_handle, mem_ctx,
1998                                                      &pol,
1999                                                      LSA_POLICY_INFO_DNS,
2000                                                      &lsa_info,
2001                                                      &result);
2002         }
2003
2004         if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2005                 domain->active_directory = True;
2006
2007                 if (lsa_info->dns.name.string) {
2008                         fstrcpy(domain->name, lsa_info->dns.name.string);
2009                 }
2010
2011                 if (lsa_info->dns.dns_domain.string) {
2012                         fstrcpy(domain->alt_name,
2013                                 lsa_info->dns.dns_domain.string);
2014                 }
2015
2016                 /* See if we can set some domain trust flags about
2017                    ourself */
2018
2019                 if (lsa_info->dns.dns_forest.string) {
2020                         fstrcpy(domain->forest_name,
2021                                 lsa_info->dns.dns_forest.string);
2022
2023                         if (strequal(domain->forest_name, domain->alt_name)) {
2024                                 domain->domain_flags |= NETR_TRUST_FLAG_TREEROOT;
2025                         }
2026                 }
2027
2028                 if (lsa_info->dns.sid) {
2029                         sid_copy(&domain->sid, lsa_info->dns.sid);
2030                 }
2031         } else {
2032                 domain->active_directory = False;
2033
2034                 status = rpccli_lsa_open_policy(cli, mem_ctx, True,
2035                                                 SEC_FLAG_MAXIMUM_ALLOWED,
2036                                                 &pol);
2037
2038                 if (!NT_STATUS_IS_OK(status)) {
2039                         goto done;
2040                 }
2041
2042                 status = dcerpc_lsa_QueryInfoPolicy(cli->binding_handle, mem_ctx,
2043                                                     &pol,
2044                                                     LSA_POLICY_INFO_ACCOUNT_DOMAIN,
2045                                                     &lsa_info,
2046                                                     &result);
2047                 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2048
2049                         if (lsa_info->account_domain.name.string) {
2050                                 fstrcpy(domain->name,
2051                                         lsa_info->account_domain.name.string);
2052                         }
2053
2054                         if (lsa_info->account_domain.sid) {
2055                                 sid_copy(&domain->sid, lsa_info->account_domain.sid);
2056                         }
2057                 }
2058         }
2059 done:
2060
2061         DEBUG(5, ("set_dc_type_and_flags_connect: domain %s is %sin native mode.\n",
2062                   domain->name, domain->native_mode ? "" : "NOT "));
2063
2064         DEBUG(5,("set_dc_type_and_flags_connect: domain %s is %srunning active directory.\n",
2065                   domain->name, domain->active_directory ? "" : "NOT "));
2066
2067         domain->can_do_ncacn_ip_tcp = domain->active_directory;
2068         domain->can_do_validation6 = domain->active_directory;
2069
2070         TALLOC_FREE(cli);
2071
2072         TALLOC_FREE(mem_ctx);
2073
2074         domain->initialized = True;
2075 }
2076
2077 /**********************************************************************
2078  Set the domain_flags (trust attributes, domain operating modes, etc... 
2079 ***********************************************************************/
2080
2081 static void set_dc_type_and_flags( struct winbindd_domain *domain )
2082 {
2083         /* we always have to contact our primary domain */
2084
2085         if ( domain->primary ) {
2086                 DEBUG(10,("set_dc_type_and_flags: setting up flags for "
2087                           "primary domain\n"));
2088                 set_dc_type_and_flags_connect( domain );
2089                 return;         
2090         }
2091
2092         /* Use our DC to get the information if possible */
2093
2094         if ( !set_dc_type_and_flags_trustinfo( domain ) ) {
2095                 /* Otherwise, fallback to contacting the 
2096                    domain directly */
2097                 set_dc_type_and_flags_connect( domain );
2098         }
2099
2100         return;
2101 }
2102
2103
2104
2105 /**********************************************************************
2106 ***********************************************************************/
2107
2108 static NTSTATUS cm_get_schannel_creds(struct winbindd_domain *domain,
2109                                    struct netlogon_creds_CredentialState **ppdc)
2110 {
2111         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2112         struct rpc_pipe_client *netlogon_pipe;
2113
2114         if (lp_client_schannel() == False) {
2115                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2116         }
2117
2118         result = cm_connect_netlogon(domain, &netlogon_pipe);
2119         if (!NT_STATUS_IS_OK(result)) {
2120                 return result;
2121         }
2122
2123         /* Return a pointer to the struct netlogon_creds_CredentialState from the
2124            netlogon pipe. */
2125
2126         if (!domain->conn.netlogon_pipe->dc) {
2127                 return NT_STATUS_INTERNAL_ERROR; /* This shouldn't happen. */
2128         }
2129
2130         *ppdc = domain->conn.netlogon_pipe->dc;
2131         return NT_STATUS_OK;
2132 }
2133
2134 NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
2135                         struct rpc_pipe_client **cli, struct policy_handle *sam_handle)
2136 {
2137         struct winbindd_cm_conn *conn;
2138         NTSTATUS status, result;
2139         struct netlogon_creds_CredentialState *p_creds;
2140         char *machine_password = NULL;
2141         char *machine_account = NULL;
2142         char *domain_name = NULL;
2143
2144         if (sid_check_is_domain(&domain->sid)) {
2145                 return open_internal_samr_conn(mem_ctx, domain, cli, sam_handle);
2146         }
2147
2148         status = init_dc_connection_rpc(domain);
2149         if (!NT_STATUS_IS_OK(status)) {
2150                 return status;
2151         }
2152
2153         conn = &domain->conn;
2154
2155         if (rpccli_is_connected(conn->samr_pipe)) {
2156                 goto done;
2157         }
2158
2159         TALLOC_FREE(conn->samr_pipe);
2160
2161         /*
2162          * No SAMR pipe yet. Attempt to get an NTLMSSP SPNEGO authenticated
2163          * sign and sealed pipe using the machine account password by
2164          * preference. If we can't - try schannel, if that fails, try
2165          * anonymous.
2166          */
2167
2168         if ((conn->cli->user_name[0] == '\0') ||
2169             (conn->cli->domain[0] == '\0') || 
2170             (conn->cli->password == NULL || conn->cli->password[0] == '\0'))
2171         {
2172                 status = get_trust_creds(domain, &machine_password,
2173                                          &machine_account, NULL);
2174                 if (!NT_STATUS_IS_OK(status)) {
2175                         DEBUG(10, ("cm_connect_sam: No no user available for "
2176                                    "domain %s, trying schannel\n", conn->cli->domain));
2177                         goto schannel;
2178                 }
2179                 domain_name = domain->name;
2180         } else {
2181                 machine_password = SMB_STRDUP(conn->cli->password);
2182                 machine_account = SMB_STRDUP(conn->cli->user_name);
2183                 domain_name = conn->cli->domain;
2184         }
2185
2186         if (!machine_password || !machine_account) {
2187                 status = NT_STATUS_NO_MEMORY;
2188                 goto done;
2189         }
2190
2191         /* We have an authenticated connection. Use a NTLMSSP SPNEGO
2192            authenticated SAMR pipe with sign & seal. */
2193         status = cli_rpc_pipe_open_spnego_ntlmssp(conn->cli,
2194                                                   &ndr_table_samr.syntax_id,
2195                                                   NCACN_NP,
2196                                                   DCERPC_AUTH_LEVEL_PRIVACY,
2197                                                   domain_name,
2198                                                   machine_account,
2199                                                   machine_password,
2200                                                   &conn->samr_pipe);
2201
2202         if (!NT_STATUS_IS_OK(status)) {
2203                 DEBUG(10,("cm_connect_sam: failed to connect to SAMR "
2204                           "pipe for domain %s using NTLMSSP "
2205                           "authenticated pipe: user %s\\%s. Error was "
2206                           "%s\n", domain->name, domain_name,
2207                           machine_account, nt_errstr(status)));
2208                 goto schannel;
2209         }
2210
2211         DEBUG(10,("cm_connect_sam: connected to SAMR pipe for "
2212                   "domain %s using NTLMSSP authenticated "
2213                   "pipe: user %s\\%s\n", domain->name,
2214                   domain_name, machine_account));
2215
2216         status = dcerpc_samr_Connect2(conn->samr_pipe->binding_handle, mem_ctx,
2217                                       conn->samr_pipe->desthost,
2218                                       SEC_FLAG_MAXIMUM_ALLOWED,
2219                                       &conn->sam_connect_handle,
2220                                       &result);
2221         if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2222                 goto open_domain;
2223         }
2224         if (NT_STATUS_IS_OK(status)) {
2225                 status = result;
2226         }
2227
2228         DEBUG(10,("cm_connect_sam: ntlmssp-sealed dcerpc_samr_Connect2 "
2229                   "failed for domain %s, error was %s. Trying schannel\n",
2230                   domain->name, nt_errstr(status) ));
2231         TALLOC_FREE(conn->samr_pipe);
2232
2233  schannel:
2234
2235         /* Fall back to schannel if it's a W2K pre-SP1 box. */
2236
2237         status = cm_get_schannel_creds(domain, &p_creds);
2238         if (!NT_STATUS_IS_OK(status)) {
2239                 /* If this call fails - conn->cli can now be NULL ! */
2240                 DEBUG(10, ("cm_connect_sam: Could not get schannel auth info "
2241                            "for domain %s (error %s), trying anon\n",
2242                         domain->name,
2243                         nt_errstr(status) ));
2244                 goto anonymous;
2245         }
2246         status = cli_rpc_pipe_open_schannel_with_key
2247                 (conn->cli, &ndr_table_samr.syntax_id, NCACN_NP,
2248                  DCERPC_AUTH_LEVEL_PRIVACY,
2249                  domain->name, &p_creds, &conn->samr_pipe);
2250
2251         if (!NT_STATUS_IS_OK(status)) {
2252                 DEBUG(10,("cm_connect_sam: failed to connect to SAMR pipe for "
2253                           "domain %s using schannel. Error was %s\n",
2254                           domain->name, nt_errstr(status) ));
2255                 goto anonymous;
2256         }
2257         DEBUG(10,("cm_connect_sam: connected to SAMR pipe for domain %s using "
2258                   "schannel.\n", domain->name ));
2259
2260         status = dcerpc_samr_Connect2(conn->samr_pipe->binding_handle, mem_ctx,
2261                                       conn->samr_pipe->desthost,
2262                                       SEC_FLAG_MAXIMUM_ALLOWED,
2263                                       &conn->sam_connect_handle,
2264                                       &result);
2265         if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2266                 goto open_domain;
2267         }
2268         if (NT_STATUS_IS_OK(status)) {
2269                 status = result;
2270         }
2271         DEBUG(10,("cm_connect_sam: schannel-sealed dcerpc_samr_Connect2 failed "
2272                   "for domain %s, error was %s. Trying anonymous\n",
2273                   domain->name, nt_errstr(status) ));
2274         TALLOC_FREE(conn->samr_pipe);
2275
2276  anonymous:
2277
2278         /* Finally fall back to anonymous. */
2279         status = cli_rpc_pipe_open_noauth(conn->cli, &ndr_table_samr.syntax_id,
2280                                           &conn->samr_pipe);
2281
2282         if (!NT_STATUS_IS_OK(status)) {
2283                 goto done;
2284         }
2285
2286         status = dcerpc_samr_Connect2(conn->samr_pipe->binding_handle, mem_ctx,
2287                                       conn->samr_pipe->desthost,
2288                                       SEC_FLAG_MAXIMUM_ALLOWED,
2289                                       &conn->sam_connect_handle,
2290                                       &result);
2291         if (!NT_STATUS_IS_OK(status)) {
2292                 DEBUG(10,("cm_connect_sam: rpccli_samr_Connect2 failed "
2293                           "for domain %s Error was %s\n",
2294                           domain->name, nt_errstr(status) ));
2295                 goto done;
2296         }
2297         if (!NT_STATUS_IS_OK(result)) {
2298                 status = result;
2299                 DEBUG(10,("cm_connect_sam: dcerpc_samr_Connect2 failed "
2300                           "for domain %s Error was %s\n",
2301                           domain->name, nt_errstr(result)));
2302                 goto done;
2303         }
2304
2305  open_domain:
2306         status = dcerpc_samr_OpenDomain(conn->samr_pipe->binding_handle,
2307                                         mem_ctx,
2308                                         &conn->sam_connect_handle,
2309                                         SEC_FLAG_MAXIMUM_ALLOWED,
2310                                         &domain->sid,
2311                                         &conn->sam_domain_handle,
2312                                         &result);
2313         if (!NT_STATUS_IS_OK(status)) {
2314                 goto done;
2315         }
2316
2317         status = result;
2318  done:
2319
2320         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2321                 /*
2322                  * if we got access denied, we might just have no access rights
2323                  * to talk to the remote samr server server (e.g. when we are a
2324                  * PDC and we are connecting a w2k8 pdc via an interdomain
2325                  * trust). In that case do not invalidate the whole connection
2326                  * stack
2327                  */
2328                 TALLOC_FREE(conn->samr_pipe);
2329                 ZERO_STRUCT(conn->sam_domain_handle);
2330                 return status;
2331         } else if (!NT_STATUS_IS_OK(status)) {
2332                 invalidate_cm_connection(conn);
2333                 return status;
2334         }
2335
2336         *cli = conn->samr_pipe;
2337         *sam_handle = conn->sam_domain_handle;
2338         SAFE_FREE(machine_password);
2339         SAFE_FREE(machine_account);
2340         return status;
2341 }
2342
2343 /**********************************************************************
2344  open an schanneld ncacn_ip_tcp connection to LSA
2345 ***********************************************************************/
2346
2347 NTSTATUS cm_connect_lsa_tcp(struct winbindd_domain *domain,
2348                             TALLOC_CTX *mem_ctx,
2349                             struct rpc_pipe_client **cli)
2350 {
2351         struct winbindd_cm_conn *conn;
2352         struct netlogon_creds_CredentialState *creds;
2353         NTSTATUS status;
2354
2355         DEBUG(10,("cm_connect_lsa_tcp\n"));
2356
2357         status = init_dc_connection_rpc(domain);
2358         if (!NT_STATUS_IS_OK(status)) {
2359                 return status;
2360         }
2361
2362         conn = &domain->conn;
2363
2364         if (conn->lsa_pipe_tcp &&
2365             conn->lsa_pipe_tcp->transport->transport == NCACN_IP_TCP &&
2366             conn->lsa_pipe_tcp->auth->auth_level == DCERPC_AUTH_LEVEL_PRIVACY &&
2367             rpccli_is_connected(conn->lsa_pipe_tcp)) {
2368                 goto done;
2369         }
2370
2371         TALLOC_FREE(conn->lsa_pipe_tcp);
2372
2373         status = cm_get_schannel_creds(domain, &creds);
2374         if (!NT_STATUS_IS_OK(status)) {
2375                 goto done;
2376         }
2377
2378         status = cli_rpc_pipe_open_schannel_with_key(conn->cli,
2379                                                      &ndr_table_lsarpc.syntax_id,
2380                                                      NCACN_IP_TCP,
2381                                                      DCERPC_AUTH_LEVEL_PRIVACY,
2382                                                      domain->name,
2383                                                      &creds,
2384                                                      &conn->lsa_pipe_tcp);
2385         if (!NT_STATUS_IS_OK(status)) {
2386                 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key failed: %s\n",
2387                         nt_errstr(status)));
2388                 goto done;
2389         }
2390
2391  done:
2392         if (!NT_STATUS_IS_OK(status)) {
2393                 TALLOC_FREE(conn->lsa_pipe_tcp);
2394                 return status;
2395         }
2396
2397         *cli = conn->lsa_pipe_tcp;
2398
2399         return status;
2400 }
2401
2402 NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
2403                         struct rpc_pipe_client **cli, struct policy_handle *lsa_policy)
2404 {
2405         struct winbindd_cm_conn *conn;
2406         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2407         struct netlogon_creds_CredentialState *p_creds;
2408
2409         result = init_dc_connection_rpc(domain);
2410         if (!NT_STATUS_IS_OK(result))
2411                 return result;
2412
2413         conn = &domain->conn;
2414
2415         if (rpccli_is_connected(conn->lsa_pipe)) {
2416                 goto done;
2417         }
2418
2419         TALLOC_FREE(conn->lsa_pipe);
2420
2421         if ((conn->cli->user_name[0] == '\0') ||
2422             (conn->cli->domain[0] == '\0') || 
2423             (conn->cli->password == NULL || conn->cli->password[0] == '\0')) {
2424                 DEBUG(10, ("cm_connect_lsa: No no user available for "
2425                            "domain %s, trying schannel\n", conn->cli->domain));
2426                 goto schannel;
2427         }
2428
2429         /* We have an authenticated connection. Use a NTLMSSP SPNEGO
2430          * authenticated LSA pipe with sign & seal. */
2431         result = cli_rpc_pipe_open_spnego_ntlmssp
2432                 (conn->cli, &ndr_table_lsarpc.syntax_id, NCACN_NP,
2433                  DCERPC_AUTH_LEVEL_PRIVACY,
2434                  conn->cli->domain, conn->cli->user_name, conn->cli->password,
2435                  &conn->lsa_pipe);
2436
2437         if (!NT_STATUS_IS_OK(result)) {
2438                 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
2439                           "domain %s using NTLMSSP authenticated pipe: user "
2440                           "%s\\%s. Error was %s. Trying schannel.\n",
2441                           domain->name, conn->cli->domain,
2442                           conn->cli->user_name, nt_errstr(result)));
2443                 goto schannel;
2444         }
2445
2446         DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
2447                   "NTLMSSP authenticated pipe: user %s\\%s\n",
2448                   domain->name, conn->cli->domain, conn->cli->user_name ));
2449
2450         result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2451                                         SEC_FLAG_MAXIMUM_ALLOWED,
2452                                         &conn->lsa_policy);
2453         if (NT_STATUS_IS_OK(result)) {
2454                 goto done;
2455         }
2456
2457         DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
2458                   "schannel\n"));
2459
2460         TALLOC_FREE(conn->lsa_pipe);
2461
2462  schannel:
2463
2464         /* Fall back to schannel if it's a W2K pre-SP1 box. */
2465
2466         result = cm_get_schannel_creds(domain, &p_creds);
2467         if (!NT_STATUS_IS_OK(result)) {
2468                 /* If this call fails - conn->cli can now be NULL ! */
2469                 DEBUG(10, ("cm_connect_lsa: Could not get schannel auth info "
2470                            "for domain %s (error %s), trying anon\n",
2471                         domain->name,
2472                         nt_errstr(result) ));
2473                 goto anonymous;
2474         }
2475         result = cli_rpc_pipe_open_schannel_with_key
2476                 (conn->cli, &ndr_table_lsarpc.syntax_id, NCACN_NP,
2477                  DCERPC_AUTH_LEVEL_PRIVACY,
2478                  domain->name, &p_creds, &conn->lsa_pipe);
2479
2480         if (!NT_STATUS_IS_OK(result)) {
2481                 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
2482                           "domain %s using schannel. Error was %s\n",
2483                           domain->name, nt_errstr(result) ));
2484                 goto anonymous;
2485         }
2486         DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
2487                   "schannel.\n", domain->name ));
2488
2489         result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2490                                         SEC_FLAG_MAXIMUM_ALLOWED,
2491                                         &conn->lsa_policy);
2492         if (NT_STATUS_IS_OK(result)) {
2493                 goto done;
2494         }
2495
2496         DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
2497                   "anonymous\n"));
2498
2499         TALLOC_FREE(conn->lsa_pipe);
2500
2501  anonymous:
2502
2503         result = cli_rpc_pipe_open_noauth(conn->cli,
2504                                           &ndr_table_lsarpc.syntax_id,
2505                                           &conn->lsa_pipe);
2506         if (!NT_STATUS_IS_OK(result)) {
2507                 result = NT_STATUS_PIPE_NOT_AVAILABLE;
2508                 goto done;
2509         }
2510
2511         result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2512                                         SEC_FLAG_MAXIMUM_ALLOWED,
2513                                         &conn->lsa_policy);
2514  done:
2515         if (!NT_STATUS_IS_OK(result)) {
2516                 invalidate_cm_connection(conn);
2517                 return result;
2518         }
2519
2520         *cli = conn->lsa_pipe;
2521         *lsa_policy = conn->lsa_policy;
2522         return result;
2523 }
2524
2525 /****************************************************************************
2526  Open the netlogon pipe to this DC. Use schannel if specified in client conf.
2527  session key stored in conn->netlogon_pipe->dc->sess_key.
2528 ****************************************************************************/
2529
2530 NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
2531                              struct rpc_pipe_client **cli)
2532 {
2533         struct winbindd_cm_conn *conn;
2534         NTSTATUS result;
2535
2536         uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
2537         uint8  mach_pwd[16];
2538         enum netr_SchannelType sec_chan_type;
2539         const char *account_name;
2540         struct rpc_pipe_client *netlogon_pipe = NULL;
2541
2542         *cli = NULL;
2543
2544         result = init_dc_connection_rpc(domain);
2545         if (!NT_STATUS_IS_OK(result)) {
2546                 return result;
2547         }
2548
2549         conn = &domain->conn;
2550
2551         if (rpccli_is_connected(conn->netlogon_pipe)) {
2552                 *cli = conn->netlogon_pipe;
2553                 return NT_STATUS_OK;
2554         }
2555
2556         TALLOC_FREE(conn->netlogon_pipe);
2557
2558         result = cli_rpc_pipe_open_noauth(conn->cli,
2559                                           &ndr_table_netlogon.syntax_id,
2560                                           &netlogon_pipe);
2561         if (!NT_STATUS_IS_OK(result)) {
2562                 return result;
2563         }
2564
2565         if ((!IS_DC) && (!domain->primary)) {
2566                 /* Clear the schannel request bit and drop down */
2567                 neg_flags &= ~NETLOGON_NEG_SCHANNEL;            
2568                 goto no_schannel;
2569         }
2570
2571         if (lp_client_schannel() != False) {
2572                 neg_flags |= NETLOGON_NEG_SCHANNEL;
2573         }
2574
2575         if (!get_trust_pw_hash(domain->name, mach_pwd, &account_name,
2576                                &sec_chan_type))
2577         {
2578                 TALLOC_FREE(netlogon_pipe);
2579                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2580         }
2581
2582         result = rpccli_netlogon_setup_creds(
2583                  netlogon_pipe,
2584                  domain->dcname, /* server name. */
2585                  domain->name,   /* domain name */
2586                  lp_netbios_name(), /* client name */
2587                  account_name,   /* machine account */
2588                  mach_pwd,       /* machine password */
2589                  sec_chan_type,  /* from get_trust_pw */
2590                  &neg_flags);
2591
2592         if (!NT_STATUS_IS_OK(result)) {
2593                 TALLOC_FREE(netlogon_pipe);
2594                 return result;
2595         }
2596
2597         if ((lp_client_schannel() == True) &&
2598                         ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
2599                 DEBUG(3, ("Server did not offer schannel\n"));
2600                 TALLOC_FREE(netlogon_pipe);
2601                 return NT_STATUS_ACCESS_DENIED;
2602         }
2603
2604  no_schannel:
2605         if ((lp_client_schannel() == False) ||
2606                         ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
2607                 /*
2608                  * NetSamLogonEx only works for schannel
2609                  */
2610                 domain->can_do_samlogon_ex = False;
2611
2612                 /* We're done - just keep the existing connection to NETLOGON
2613                  * open */
2614                 conn->netlogon_pipe = netlogon_pipe;
2615                 *cli = conn->netlogon_pipe;
2616                 return NT_STATUS_OK;
2617         }
2618
2619         /* Using the credentials from the first pipe, open a signed and sealed
2620            second netlogon pipe. The session key is stored in the schannel
2621            part of the new pipe auth struct.
2622         */
2623
2624         result = cli_rpc_pipe_open_schannel_with_key(
2625                 conn->cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
2626                 DCERPC_AUTH_LEVEL_PRIVACY, domain->name, &netlogon_pipe->dc,
2627                 &conn->netlogon_pipe);
2628
2629         /* We can now close the initial netlogon pipe. */
2630         TALLOC_FREE(netlogon_pipe);
2631
2632         if (!NT_STATUS_IS_OK(result)) {
2633                 DEBUG(3, ("Could not open schannel'ed NETLOGON pipe. Error "
2634                           "was %s\n", nt_errstr(result)));
2635
2636                 invalidate_cm_connection(conn);
2637                 return result;
2638         }
2639
2640         /*
2641          * Always try netr_LogonSamLogonEx. We will fall back for NT4
2642          * which gives DCERPC_FAULT_OP_RNG_ERROR (function not
2643          * supported). We used to only try SamLogonEx for AD, but
2644          * Samba DCs can also do it. And because we don't distinguish
2645          * between Samba and NT4, always try it once.
2646          */
2647         domain->can_do_samlogon_ex = true;
2648
2649         *cli = conn->netlogon_pipe;
2650         return NT_STATUS_OK;
2651 }
2652
2653 void winbind_msg_ip_dropped(struct messaging_context *msg_ctx,
2654                             void *private_data,
2655                             uint32_t msg_type,
2656                             struct server_id server_id,
2657                             DATA_BLOB *data)
2658 {
2659         struct winbindd_domain *domain;
2660         char *freeit = NULL;
2661         char *addr;
2662
2663         if ((data == NULL)
2664             || (data->data == NULL)
2665             || (data->length == 0)
2666             || (data->data[data->length-1] != '\0')) {
2667                 DEBUG(1, ("invalid msg_ip_dropped message: not a valid "
2668                           "string\n"));
2669                 return;
2670         }
2671
2672         addr = (char *)data->data;
2673         DEBUG(10, ("IP %s dropped\n", addr));
2674
2675         if (!is_ipaddress(addr)) {
2676                 char *slash;
2677                 /*
2678                  * Some code sends us ip addresses with the /netmask
2679                  * suffix
2680                  */
2681                 slash = strchr(addr, '/');
2682                 if (slash == NULL) {
2683                         DEBUG(1, ("invalid msg_ip_dropped message: %s",
2684                                   addr));
2685                         return;
2686                 }
2687                 freeit = talloc_strndup(talloc_tos(), addr, slash-addr);
2688                 if (freeit == NULL) {
2689                         DEBUG(1, ("talloc failed\n"));
2690                         return;
2691                 }
2692                 addr = freeit;
2693                 DEBUG(10, ("Stripped /netmask to IP %s\n", addr));
2694         }
2695
2696         for (domain = domain_list(); domain != NULL; domain = domain->next) {
2697                 char sockaddr[INET6_ADDRSTRLEN];
2698
2699                 if (!cli_state_is_connected(domain->conn.cli)) {
2700                         continue;
2701                 }
2702
2703                 print_sockaddr(sockaddr, sizeof(sockaddr),
2704                                cli_state_local_sockaddr(domain->conn.cli));
2705
2706                 if (strequal(sockaddr, addr)) {
2707                         cli_state_disconnect(domain->conn.cli);
2708                 }
2709         }
2710         TALLOC_FREE(freeit);
2711 }