s3:winbindd_cm: use controller instead of cli->desthost
[gd/samba-autobuild/.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, controller, Undefined);
810         if (*cli == NULL) {
811                 DEBUG(1, ("Could not cli_initialize\n"));
812                 result = NT_STATUS_NO_MEMORY;
813                 goto done;
814         }
815
816         (*cli)->timeout = 10000;        /* 10 seconds */
817
818         (*cli)->use_kerberos = True;
819
820         result = cli_negprot(*cli);
821
822         if (!NT_STATUS_IS_OK(result)) {
823                 DEBUG(1, ("cli_negprot failed: %s\n", nt_errstr(result)));
824                 goto done;
825         }
826
827         if (!is_dc_trusted_domain_situation(domain->name) &&
828             (*cli)->protocol >= PROTOCOL_NT1 &&
829             (*cli)->capabilities & CAP_EXTENDED_SECURITY)
830         {
831                 ADS_STATUS ads_status;
832
833                 result = get_trust_creds(domain, &machine_password,
834                                          &machine_account,
835                                          &machine_krb5_principal);
836                 if (!NT_STATUS_IS_OK(result)) {
837                         goto anon_fallback;
838                 }
839
840                 if (lp_security() == SEC_ADS) {
841
842                         /* Try a krb5 session */
843
844                         (*cli)->use_kerberos = True;
845                         DEBUG(5, ("connecting to %s from %s with kerberos principal "
846                                   "[%s] and realm [%s]\n", controller, lp_netbios_name(),
847                                   machine_krb5_principal, domain->alt_name));
848
849                         winbindd_set_locator_kdc_envs(domain);
850
851                         ads_status = cli_session_setup_spnego(*cli,
852                                                               machine_krb5_principal, 
853                                                               machine_password,
854                                                               lp_workgroup(),
855                                                               domain->alt_name);
856
857                         if (!ADS_ERR_OK(ads_status)) {
858                                 DEBUG(4,("failed kerberos session setup with %s\n",
859                                          ads_errstr(ads_status)));
860                         }
861
862                         result = ads_ntstatus(ads_status);
863                         if (NT_STATUS_IS_OK(result)) {
864                                 /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
865                                 result = cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
866                                 if (!NT_STATUS_IS_OK(result)) {
867                                         goto done;
868                                 }
869                                 goto session_setup_done;
870                         }
871                 }
872
873                 /* Fall back to non-kerberos session setup using NTLMSSP SPNEGO with the machine account. */
874                 (*cli)->use_kerberos = False;
875
876                 DEBUG(5, ("connecting to %s from %s with username "
877                           "[%s]\\[%s]\n",  controller, lp_netbios_name(),
878                           lp_workgroup(), machine_account));
879
880                 ads_status = cli_session_setup_spnego(*cli,
881                                                       machine_account, 
882                                                       machine_password, 
883                                                       lp_workgroup(),
884                                                       NULL);
885                 if (!ADS_ERR_OK(ads_status)) {
886                         DEBUG(4, ("authenticated session setup failed with %s\n",
887                                 ads_errstr(ads_status)));
888                 }
889
890                 result = ads_ntstatus(ads_status);
891                 if (NT_STATUS_IS_OK(result)) {
892                         /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
893                         result = cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
894                         if (!NT_STATUS_IS_OK(result)) {
895                                 goto done;
896                         }
897                         goto session_setup_done;
898                 }
899         }
900
901         /* Fall back to non-kerberos session setup with auth_user */
902
903         (*cli)->use_kerberos = False;
904
905         cm_get_ipc_userpass(&ipc_username, &ipc_domain, &ipc_password);
906
907         if ((((*cli)->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) != 0) &&
908             (strlen(ipc_username) > 0)) {
909
910                 /* Only try authenticated if we have a username */
911
912                 DEBUG(5, ("connecting to %s from %s with username "
913                           "[%s]\\[%s]\n",  controller, lp_netbios_name(),
914                           ipc_domain, ipc_username));
915
916                 if (NT_STATUS_IS_OK(cli_session_setup(
917                                             *cli, ipc_username,
918                                             ipc_password, strlen(ipc_password)+1,
919                                             ipc_password, strlen(ipc_password)+1,
920                                             ipc_domain))) {
921                         /* Successful logon with given username. */
922                         result = cli_init_creds(*cli, ipc_username, ipc_domain, ipc_password);
923                         if (!NT_STATUS_IS_OK(result)) {
924                                 goto done;
925                         }
926                         goto session_setup_done;
927                 } else {
928                         DEBUG(4, ("authenticated session setup with user %s\\%s failed.\n",
929                                 ipc_domain, ipc_username ));
930                 }
931         }
932
933  anon_fallback:
934
935         /* Fall back to anonymous connection, this might fail later */
936         DEBUG(10,("cm_prepare_connection: falling back to anonymous "
937                 "connection for DC %s\n",
938                 controller ));
939
940         if (NT_STATUS_IS_OK(cli_session_setup(*cli, "", NULL, 0,
941                                               NULL, 0, ""))) {
942                 DEBUG(5, ("Connected anonymously\n"));
943                 result = cli_init_creds(*cli, "", "", "");
944                 if (!NT_STATUS_IS_OK(result)) {
945                         goto done;
946                 }
947                 goto session_setup_done;
948         }
949
950         result = cli_nt_error(*cli);
951
952         if (NT_STATUS_IS_OK(result))
953                 result = NT_STATUS_UNSUCCESSFUL;
954
955         /* We can't session setup */
956
957         goto done;
958
959  session_setup_done:
960
961         /* cache the server name for later connections */
962
963         saf_store(domain->name, controller);
964         if (domain->alt_name && (*cli)->use_kerberos) {
965                 saf_store(domain->alt_name, controller);
966         }
967
968         winbindd_set_locator_kdc_envs(domain);
969
970         result = cli_tcon_andx(*cli, "IPC$", "IPC", "", 0);
971
972         if (!NT_STATUS_IS_OK(result)) {
973                 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(result)));
974                 goto done;
975         }
976
977         TALLOC_FREE(mutex);
978         *retry = False;
979
980         /* set the domain if empty; needed for schannel connections */
981         if ( !(*cli)->domain[0] ) {
982                 result = cli_set_domain((*cli), domain->name);
983                 if (!NT_STATUS_IS_OK(result)) {
984                         return result;
985                 }
986         }
987
988         result = NT_STATUS_OK;
989
990  done:
991         TALLOC_FREE(mutex);
992         SAFE_FREE(machine_account);
993         SAFE_FREE(machine_password);
994         SAFE_FREE(machine_krb5_principal);
995         SAFE_FREE(ipc_username);
996         SAFE_FREE(ipc_domain);
997         SAFE_FREE(ipc_password);
998
999         if (!NT_STATUS_IS_OK(result)) {
1000                 winbind_add_failed_connection_entry(domain, controller, result);
1001                 if ((*cli) != NULL) {
1002                         cli_shutdown(*cli);
1003                         *cli = NULL;
1004                 }
1005         }
1006
1007         return result;
1008 }
1009
1010 /*******************************************************************
1011  Add a dcname and sockaddr_storage pair to the end of a dc_name_ip
1012  array.
1013
1014  Keeps the list unique by not adding duplicate entries.
1015
1016  @param[in] mem_ctx talloc memory context to allocate from
1017  @param[in] domain_name domain of the DC
1018  @param[in] dcname name of the DC to add to the list
1019  @param[in] pss Internet address and port pair to add to the list
1020  @param[in,out] dcs array of dc_name_ip structures to add to
1021  @param[in,out] num_dcs number of dcs returned in the dcs array
1022  @return true if the list was added to, false otherwise
1023 *******************************************************************/
1024
1025 static bool add_one_dc_unique(TALLOC_CTX *mem_ctx, const char *domain_name,
1026                               const char *dcname, struct sockaddr_storage *pss,
1027                               struct dc_name_ip **dcs, int *num)
1028 {
1029         int i = 0;
1030
1031         if (!NT_STATUS_IS_OK(check_negative_conn_cache(domain_name, dcname))) {
1032                 DEBUG(10, ("DC %s was in the negative conn cache\n", dcname));
1033                 return False;
1034         }
1035
1036         /* Make sure there's no duplicates in the list */
1037         for (i=0; i<*num; i++)
1038                 if (sockaddr_equal(
1039                             (struct sockaddr *)(void *)&(*dcs)[i].ss,
1040                             (struct sockaddr *)(void *)pss))
1041                         return False;
1042
1043         *dcs = talloc_realloc(mem_ctx, *dcs, struct dc_name_ip, (*num)+1);
1044
1045         if (*dcs == NULL)
1046                 return False;
1047
1048         fstrcpy((*dcs)[*num].name, dcname);
1049         (*dcs)[*num].ss = *pss;
1050         *num += 1;
1051         return True;
1052 }
1053
1054 static bool add_sockaddr_to_array(TALLOC_CTX *mem_ctx,
1055                                   struct sockaddr_storage *pss, uint16 port,
1056                                   struct sockaddr_storage **addrs, int *num)
1057 {
1058         *addrs = talloc_realloc(mem_ctx, *addrs, struct sockaddr_storage, (*num)+1);
1059
1060         if (*addrs == NULL) {
1061                 *num = 0;
1062                 return False;
1063         }
1064
1065         (*addrs)[*num] = *pss;
1066         set_sockaddr_port((struct sockaddr *)&(*addrs)[*num], port);
1067
1068         *num += 1;
1069         return True;
1070 }
1071
1072 /*******************************************************************
1073  convert an ip to a name
1074 *******************************************************************/
1075
1076 static bool dcip_to_name(TALLOC_CTX *mem_ctx,
1077                 const struct winbindd_domain *domain,
1078                 struct sockaddr_storage *pss,
1079                 fstring name )
1080 {
1081         struct ip_service ip_list;
1082         uint32_t nt_version = NETLOGON_NT_VERSION_1;
1083         NTSTATUS status;
1084         const char *dc_name;
1085
1086         ip_list.ss = *pss;
1087         ip_list.port = 0;
1088
1089 #ifdef HAVE_ADS
1090         /* For active directory servers, try to get the ldap server name.
1091            None of these failures should be considered critical for now */
1092
1093         if (lp_security() == SEC_ADS) {
1094                 ADS_STRUCT *ads;
1095                 ADS_STATUS ads_status;
1096                 char addr[INET6_ADDRSTRLEN];
1097
1098                 print_sockaddr(addr, sizeof(addr), pss);
1099
1100                 ads = ads_init(domain->alt_name, domain->name, addr);
1101                 ads->auth.flags |= ADS_AUTH_NO_BIND;
1102
1103                 ads_status = ads_connect(ads);
1104                 if (ADS_ERR_OK(ads_status)) {
1105                         /* We got a cldap packet. */
1106                         fstrcpy(name, ads->config.ldap_server_name);
1107                         namecache_store(name, 0x20, 1, &ip_list);
1108
1109                         DEBUG(10,("dcip_to_name: flags = 0x%x\n", (unsigned int)ads->config.flags));
1110
1111                         if (domain->primary && (ads->config.flags & NBT_SERVER_KDC)) {
1112                                 if (ads_closest_dc(ads)) {
1113                                         char *sitename = sitename_fetch(ads->config.realm);
1114
1115                                         /* We're going to use this KDC for this realm/domain.
1116                                            If we are using sites, then force the krb5 libs
1117                                            to use this KDC. */
1118
1119                                         create_local_private_krb5_conf_for_domain(domain->alt_name,
1120                                                                         domain->name,
1121                                                                         sitename,
1122                                                                         pss,
1123                                                                         name);
1124
1125                                         SAFE_FREE(sitename);
1126                                 } else {
1127                                         /* use an off site KDC */
1128                                         create_local_private_krb5_conf_for_domain(domain->alt_name,
1129                                                                         domain->name,
1130                                                                         NULL,
1131                                                                         pss,
1132                                                                         name);
1133                                 }
1134                                 winbindd_set_locator_kdc_envs(domain);
1135
1136                                 /* Ensure we contact this DC also. */
1137                                 saf_store( domain->name, name);
1138                                 saf_store( domain->alt_name, name);
1139                         }
1140
1141                         ads_destroy( &ads );
1142                         return True;
1143                 }
1144
1145                 ads_destroy( &ads );
1146         }
1147 #endif
1148
1149         status = nbt_getdc(winbind_messaging_context(), pss, domain->name,
1150                            &domain->sid, nt_version, mem_ctx, &nt_version,
1151                            &dc_name, NULL);
1152         if (NT_STATUS_IS_OK(status)) {
1153                 fstrcpy(name, dc_name);
1154                 namecache_store(name, 0x20, 1, &ip_list);
1155                 return True;
1156         }
1157
1158         /* try node status request */
1159
1160         if ( name_status_find(domain->name, 0x1c, 0x20, pss, name) ) {
1161                 namecache_store(name, 0x20, 1, &ip_list);
1162                 return True;
1163         }
1164         return False;
1165 }
1166
1167 /*******************************************************************
1168  Retrieve a list of IP addresses for domain controllers.
1169
1170  The array is sorted in the preferred connection order.
1171
1172  @param[in] mem_ctx talloc memory context to allocate from
1173  @param[in] domain domain to retrieve DCs for
1174  @param[out] dcs array of dcs that will be returned
1175  @param[out] num_dcs number of dcs returned in the dcs array
1176  @return always true
1177 *******************************************************************/
1178
1179 static bool get_dcs(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
1180                     struct dc_name_ip **dcs, int *num_dcs)
1181 {
1182         fstring dcname;
1183         struct  sockaddr_storage ss;
1184         struct  ip_service *ip_list = NULL;
1185         int     iplist_size = 0;
1186         int     i;
1187         bool    is_our_domain;
1188         enum security_types sec = (enum security_types)lp_security();
1189
1190         is_our_domain = strequal(domain->name, lp_workgroup());
1191
1192         /* If not our domain, get the preferred DC, by asking our primary DC */
1193         if ( !is_our_domain
1194                 && get_dc_name_via_netlogon(domain, dcname, &ss)
1195                 && add_one_dc_unique(mem_ctx, domain->name, dcname, &ss, dcs,
1196                        num_dcs) )
1197         {
1198                 char addr[INET6_ADDRSTRLEN];
1199                 print_sockaddr(addr, sizeof(addr), &ss);
1200                 DEBUG(10, ("Retrieved DC %s at %s via netlogon\n",
1201                            dcname, addr));
1202                 return True;
1203         }
1204
1205         if (sec == SEC_ADS) {
1206                 char *sitename = NULL;
1207
1208                 /* We need to make sure we know the local site before
1209                    doing any DNS queries, as this will restrict the
1210                    get_sorted_dc_list() call below to only fetching
1211                    DNS records for the correct site. */
1212
1213                 /* Find any DC to get the site record.
1214                    We deliberately don't care about the
1215                    return here. */
1216
1217                 get_dc_name(domain->name, domain->alt_name, dcname, &ss);
1218
1219                 sitename = sitename_fetch(domain->alt_name);
1220                 if (sitename) {
1221
1222                         /* Do the site-specific AD dns lookup first. */
1223                         get_sorted_dc_list(domain->alt_name, sitename, &ip_list,
1224                                &iplist_size, True);
1225
1226                         /* Add ips to the DC array.  We don't look up the name
1227                            of the DC in this function, but we fill in the char*
1228                            of the ip now to make the failed connection cache
1229                            work */
1230                         for ( i=0; i<iplist_size; i++ ) {
1231                                 char addr[INET6_ADDRSTRLEN];
1232                                 print_sockaddr(addr, sizeof(addr),
1233                                                 &ip_list[i].ss);
1234                                 add_one_dc_unique(mem_ctx,
1235                                                 domain->name,
1236                                                 addr,
1237                                                 &ip_list[i].ss,
1238                                                 dcs,
1239                                                 num_dcs);
1240                         }
1241
1242                         SAFE_FREE(ip_list);
1243                         SAFE_FREE(sitename);
1244                         iplist_size = 0;
1245                 }
1246
1247                 /* Now we add DCs from the main AD DNS lookup. */
1248                 get_sorted_dc_list(domain->alt_name, NULL, &ip_list,
1249                         &iplist_size, True);
1250
1251                 for ( i=0; i<iplist_size; i++ ) {
1252                         char addr[INET6_ADDRSTRLEN];
1253                         print_sockaddr(addr, sizeof(addr),
1254                                         &ip_list[i].ss);
1255                         add_one_dc_unique(mem_ctx,
1256                                         domain->name,
1257                                         addr,
1258                                         &ip_list[i].ss,
1259                                         dcs,
1260                                         num_dcs);
1261                 }
1262
1263                 SAFE_FREE(ip_list);
1264                 iplist_size = 0;
1265         }
1266
1267         /* Try standard netbios queries if no ADS */
1268         if (*num_dcs == 0) {
1269                 get_sorted_dc_list(domain->name, NULL, &ip_list, &iplist_size,
1270                        False);
1271
1272                 for ( i=0; i<iplist_size; i++ ) {
1273                         char addr[INET6_ADDRSTRLEN];
1274                         print_sockaddr(addr, sizeof(addr),
1275                                         &ip_list[i].ss);
1276                         add_one_dc_unique(mem_ctx,
1277                                         domain->name,
1278                                         addr,
1279                                         &ip_list[i].ss,
1280                                         dcs,
1281                                         num_dcs);
1282                 }
1283
1284                 SAFE_FREE(ip_list);
1285                 iplist_size = 0;
1286         }
1287
1288         return True;
1289 }
1290
1291 /*******************************************************************
1292  Find and make a connection to a DC in the given domain.
1293
1294  @param[in] mem_ctx talloc memory context to allocate from
1295  @param[in] domain domain to find a dc in
1296  @param[out] dcname NetBIOS or FQDN of DC that's connected to
1297  @param[out] pss DC Internet address and port
1298  @param[out] fd fd of the open socket connected to the newly found dc
1299  @return true when a DC connection is made, false otherwise
1300 *******************************************************************/
1301
1302 static bool find_new_dc(TALLOC_CTX *mem_ctx,
1303                         struct winbindd_domain *domain,
1304                         fstring dcname, struct sockaddr_storage *pss, int *fd)
1305 {
1306         struct dc_name_ip *dcs = NULL;
1307         int num_dcs = 0;
1308
1309         const char **dcnames = NULL;
1310         int num_dcnames = 0;
1311
1312         struct sockaddr_storage *addrs = NULL;
1313         int num_addrs = 0;
1314
1315         int i;
1316         size_t fd_index;
1317
1318         NTSTATUS status;
1319
1320         *fd = -1;
1321
1322  again:
1323         if (!get_dcs(mem_ctx, domain, &dcs, &num_dcs) || (num_dcs == 0))
1324                 return False;
1325
1326         for (i=0; i<num_dcs; i++) {
1327
1328                 if (!add_string_to_array(mem_ctx, dcs[i].name,
1329                                     &dcnames, &num_dcnames)) {
1330                         return False;
1331                 }
1332                 if (!add_sockaddr_to_array(mem_ctx, &dcs[i].ss, 445,
1333                                       &addrs, &num_addrs)) {
1334                         return False;
1335                 }
1336         }
1337
1338         if ((num_dcnames == 0) || (num_dcnames != num_addrs))
1339                 return False;
1340
1341         if ((addrs == NULL) || (dcnames == NULL))
1342                 return False;
1343
1344         status = smbsock_any_connect(addrs, dcnames, NULL, NULL, NULL,
1345                                      num_addrs, 0, 10, fd, &fd_index, NULL);
1346         if (!NT_STATUS_IS_OK(status)) {
1347                 for (i=0; i<num_dcs; i++) {
1348                         char ab[INET6_ADDRSTRLEN];
1349                         print_sockaddr(ab, sizeof(ab), &dcs[i].ss);
1350                         DEBUG(10, ("find_new_dc: smbsock_any_connect failed for "
1351                                 "domain %s address %s. Error was %s\n",
1352                                    domain->name, ab, nt_errstr(status) ));
1353                         winbind_add_failed_connection_entry(domain,
1354                                 dcs[i].name, NT_STATUS_UNSUCCESSFUL);
1355                 }
1356                 return False;
1357         }
1358
1359         *pss = addrs[fd_index];
1360
1361         if (*dcnames[fd_index] != '\0' && !is_ipaddress(dcnames[fd_index])) {
1362                 /* Ok, we've got a name for the DC */
1363                 fstrcpy(dcname, dcnames[fd_index]);
1364                 return True;
1365         }
1366
1367         /* Try to figure out the name */
1368         if (dcip_to_name(mem_ctx, domain, pss, dcname)) {
1369                 return True;
1370         }
1371
1372         /* We can not continue without the DC's name */
1373         winbind_add_failed_connection_entry(domain, dcs[fd_index].name,
1374                                     NT_STATUS_UNSUCCESSFUL);
1375
1376         /* Throw away all arrays as we're doing this again. */
1377         TALLOC_FREE(dcs);
1378         num_dcs = 0;
1379
1380         TALLOC_FREE(dcnames);
1381         num_dcnames = 0;
1382
1383         TALLOC_FREE(addrs);
1384         num_addrs = 0;
1385
1386         close(*fd);
1387         *fd = -1;
1388
1389         goto again;
1390 }
1391
1392 static char *current_dc_key(TALLOC_CTX *mem_ctx, const char *domain_name)
1393 {
1394         return talloc_asprintf_strupper_m(mem_ctx, "CURRENT_DCNAME/%s",
1395                                           domain_name);
1396 }
1397
1398 static void store_current_dc_in_gencache(const char *domain_name,
1399                                          const char *dc_name,
1400                                          struct cli_state *cli)
1401 {
1402         char addr[INET6_ADDRSTRLEN];
1403         char *key = NULL;
1404         char *value = NULL;
1405
1406         if (!cli_state_is_connected(cli)) {
1407                 return;
1408         }
1409
1410         print_sockaddr(addr, sizeof(addr),
1411                        cli_state_remote_sockaddr(cli));
1412
1413         key = current_dc_key(talloc_tos(), domain_name);
1414         if (key == NULL) {
1415                 goto done;
1416         }
1417
1418         value = talloc_asprintf(talloc_tos(), "%s %s", addr, dc_name);
1419         if (value == NULL) {
1420                 goto done;
1421         }
1422
1423         gencache_set(key, value, 0x7fffffff);
1424 done:
1425         TALLOC_FREE(value);
1426         TALLOC_FREE(key);
1427 }
1428
1429 bool fetch_current_dc_from_gencache(TALLOC_CTX *mem_ctx,
1430                                     const char *domain_name,
1431                                     char **p_dc_name, char **p_dc_ip)
1432 {
1433         char *key, *value, *p;
1434         bool ret = false;
1435         char *dc_name = NULL;
1436         char *dc_ip = NULL;
1437
1438         key = current_dc_key(talloc_tos(), domain_name);
1439         if (key == NULL) {
1440                 goto done;
1441         }
1442         if (!gencache_get(key, &value, NULL)) {
1443                 goto done;
1444         }
1445         p = strchr(value, ' ');
1446         if (p == NULL) {
1447                 goto done;
1448         }
1449         dc_ip = talloc_strndup(mem_ctx, value, p - value);
1450         if (dc_ip == NULL) {
1451                 goto done;
1452         }
1453         dc_name = talloc_strdup(mem_ctx, p+1);
1454         if (dc_name == NULL) {
1455                 goto done;
1456         }
1457
1458         if (p_dc_ip != NULL) {
1459                 *p_dc_ip = dc_ip;
1460                 dc_ip = NULL;
1461         }
1462         if (p_dc_name != NULL) {
1463                 *p_dc_name = dc_name;
1464                 dc_name = NULL;
1465         }
1466         ret = true;
1467 done:
1468         TALLOC_FREE(dc_name);
1469         TALLOC_FREE(dc_ip);
1470         TALLOC_FREE(key);
1471         return ret;
1472 }
1473
1474 static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
1475                                    struct winbindd_cm_conn *new_conn)
1476 {
1477         TALLOC_CTX *mem_ctx;
1478         NTSTATUS result;
1479         char *saf_servername = saf_fetch( domain->name );
1480         int retries;
1481
1482         if ((mem_ctx = talloc_init("cm_open_connection")) == NULL) {
1483                 SAFE_FREE(saf_servername);
1484                 set_domain_offline(domain);
1485                 return NT_STATUS_NO_MEMORY;
1486         }
1487
1488         /* we have to check the server affinity cache here since 
1489            later we select a DC based on response time and not preference */
1490
1491         /* Check the negative connection cache
1492            before talking to it. It going down may have
1493            triggered the reconnection. */
1494
1495         if ( saf_servername && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, saf_servername))) {
1496
1497                 DEBUG(10,("cm_open_connection: saf_servername is '%s' for domain %s\n",
1498                         saf_servername, domain->name ));
1499
1500                 /* convert an ip address to a name */
1501                 if (is_ipaddress( saf_servername ) ) {
1502                         fstring saf_name;
1503                         struct sockaddr_storage ss;
1504
1505                         if (!interpret_string_addr(&ss, saf_servername,
1506                                                 AI_NUMERICHOST)) {
1507                                 return NT_STATUS_UNSUCCESSFUL;
1508                         }
1509                         if (dcip_to_name(mem_ctx, domain, &ss, saf_name )) {
1510                                 strlcpy(domain->dcname, saf_name, sizeof(domain->dcname));
1511                         } else {
1512                                 winbind_add_failed_connection_entry(
1513                                         domain, saf_servername,
1514                                         NT_STATUS_UNSUCCESSFUL);
1515                         }
1516                 } else {
1517                         fstrcpy( domain->dcname, saf_servername );
1518                 }
1519
1520                 SAFE_FREE( saf_servername );
1521         }
1522
1523         for (retries = 0; retries < 3; retries++) {
1524                 int fd = -1;
1525                 bool retry = False;
1526
1527                 result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1528
1529                 DEBUG(10,("cm_open_connection: dcname is '%s' for domain %s\n",
1530                         domain->dcname, domain->name ));
1531
1532                 if (*domain->dcname 
1533                         && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, domain->dcname))
1534                         && (resolve_name(domain->dcname, &domain->dcaddr, 0x20, true)))
1535                 {
1536                         NTSTATUS status;
1537
1538                         status = smbsock_connect(&domain->dcaddr, 0,
1539                                                  NULL, -1, NULL, -1,
1540                                                  &fd, NULL, 10);
1541                         if (!NT_STATUS_IS_OK(status)) {
1542                                 fd = -1;
1543                         }
1544                 }
1545
1546                 if ((fd == -1) 
1547                         && !find_new_dc(mem_ctx, domain, domain->dcname, &domain->dcaddr, &fd))
1548                 {
1549                         /* This is the one place where we will
1550                            set the global winbindd offline state
1551                            to true, if a "WINBINDD_OFFLINE" entry
1552                            is found in the winbindd cache. */
1553                         set_global_winbindd_state_offline();
1554                         break;
1555                 }
1556
1557                 new_conn->cli = NULL;
1558
1559                 result = cm_prepare_connection(domain, fd, domain->dcname,
1560                         &new_conn->cli, &retry);
1561
1562                 if (!retry)
1563                         break;
1564         }
1565
1566         if (NT_STATUS_IS_OK(result)) {
1567
1568                 winbindd_set_locator_kdc_envs(domain);
1569
1570                 if (domain->online == False) {
1571                         /* We're changing state from offline to online. */
1572                         set_global_winbindd_state_online();
1573                 }
1574                 set_domain_online(domain);
1575
1576                 /*
1577                  * Much as I hate global state, this seems to be the point
1578                  * where we can be certain that we have a proper connection to
1579                  * a DC. wbinfo --dc-info needs that information, store it in
1580                  * gencache with a looong timeout. This will need revisiting
1581                  * once we start to connect to multiple DCs, wbcDcInfo is
1582                  * already prepared for that.
1583                  */
1584                 store_current_dc_in_gencache(domain->name, domain->dcname,
1585                                              new_conn->cli);
1586         } else {
1587                 /* Ensure we setup the retry handler. */
1588                 set_domain_offline(domain);
1589         }
1590
1591         talloc_destroy(mem_ctx);
1592         return result;
1593 }
1594
1595 /* Close down all open pipes on a connection. */
1596
1597 void invalidate_cm_connection(struct winbindd_cm_conn *conn)
1598 {
1599         NTSTATUS result;
1600
1601         /* We're closing down a possibly dead
1602            connection. Don't have impossibly long (10s) timeouts. */
1603
1604         if (conn->cli) {
1605                 cli_set_timeout(conn->cli, 1000); /* 1 second. */
1606         }
1607
1608         if (conn->samr_pipe != NULL) {
1609                 if (is_valid_policy_hnd(&conn->sam_connect_handle)) {
1610                         dcerpc_samr_Close(conn->samr_pipe->binding_handle,
1611                                           talloc_tos(),
1612                                           &conn->sam_connect_handle,
1613                                           &result);
1614                 }
1615                 TALLOC_FREE(conn->samr_pipe);
1616                 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1617                 if (conn->cli) {
1618                         cli_set_timeout(conn->cli, 500);
1619                 }
1620         }
1621
1622         if (conn->lsa_pipe != NULL) {
1623                 if (is_valid_policy_hnd(&conn->lsa_policy)) {
1624                         dcerpc_lsa_Close(conn->lsa_pipe->binding_handle,
1625                                          talloc_tos(),
1626                                          &conn->lsa_policy,
1627                                          &result);
1628                 }
1629                 TALLOC_FREE(conn->lsa_pipe);
1630                 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1631                 if (conn->cli) {
1632                         cli_set_timeout(conn->cli, 500);
1633                 }
1634         }
1635
1636         if (conn->lsa_pipe_tcp != NULL) {
1637                 if (is_valid_policy_hnd(&conn->lsa_policy)) {
1638                         dcerpc_lsa_Close(conn->lsa_pipe_tcp->binding_handle,
1639                                          talloc_tos(),
1640                                          &conn->lsa_policy,
1641                                          &result);
1642                 }
1643                 TALLOC_FREE(conn->lsa_pipe_tcp);
1644                 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1645                 if (conn->cli) {
1646                         cli_set_timeout(conn->cli, 500);
1647                 }
1648         }
1649
1650         if (conn->netlogon_pipe != NULL) {
1651                 TALLOC_FREE(conn->netlogon_pipe);
1652                 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1653                 if (conn->cli) {
1654                         cli_set_timeout(conn->cli, 500);
1655                 }
1656         }
1657
1658         if (conn->cli) {
1659                 cli_shutdown(conn->cli);
1660         }
1661
1662         conn->cli = NULL;
1663 }
1664
1665 void close_conns_after_fork(void)
1666 {
1667         struct winbindd_domain *domain;
1668         struct winbindd_cli_state *cli_state;
1669
1670         for (domain = domain_list(); domain; domain = domain->next) {
1671                 /*
1672                  * first close the low level SMB TCP connection
1673                  * so that we don't generate any SMBclose
1674                  * requests in invalidate_cm_connection()
1675                  */
1676                 if (cli_state_is_connected(domain->conn.cli)) {
1677                         cli_state_disconnect(domain->conn.cli);
1678                 }
1679
1680                 invalidate_cm_connection(&domain->conn);
1681         }
1682
1683         for (cli_state = winbindd_client_list();
1684              cli_state != NULL;
1685              cli_state = cli_state->next) {
1686                 if (cli_state->sock >= 0) {
1687                         close(cli_state->sock);
1688                         cli_state->sock = -1;
1689                 }
1690         }
1691 }
1692
1693 static bool connection_ok(struct winbindd_domain *domain)
1694 {
1695         bool ok;
1696
1697         ok = cli_state_is_connected(domain->conn.cli);
1698         if (!ok) {
1699                 DEBUG(3, ("connection_ok: Connection to %s for domain %s is not connected\n",
1700                           domain->dcname, domain->name));
1701                 return False;
1702         }
1703
1704         if (domain->online == False) {
1705                 DEBUG(3, ("connection_ok: Domain %s is offline\n", domain->name));
1706                 return False;
1707         }
1708
1709         return True;
1710 }
1711
1712 /* Initialize a new connection up to the RPC BIND.
1713    Bypass online status check so always does network calls. */
1714
1715 static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain)
1716 {
1717         NTSTATUS result;
1718
1719         /* Internal connections never use the network. */
1720         if (domain->internal) {
1721                 domain->initialized = True;
1722                 return NT_STATUS_OK;
1723         }
1724
1725         if (!winbindd_can_contact_domain(domain)) {
1726                 invalidate_cm_connection(&domain->conn);
1727                 domain->initialized = True;
1728                 return NT_STATUS_OK;
1729         }
1730
1731         if (connection_ok(domain)) {
1732                 if (!domain->initialized) {
1733                         set_dc_type_and_flags(domain);
1734                 }
1735                 return NT_STATUS_OK;
1736         }
1737
1738         invalidate_cm_connection(&domain->conn);
1739
1740         result = cm_open_connection(domain, &domain->conn);
1741
1742         if (NT_STATUS_IS_OK(result) && !domain->initialized) {
1743                 set_dc_type_and_flags(domain);
1744         }
1745
1746         return result;
1747 }
1748
1749 NTSTATUS init_dc_connection(struct winbindd_domain *domain)
1750 {
1751         if (domain->internal) {
1752                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1753         }
1754
1755         if (domain->initialized && !domain->online) {
1756                 /* We check for online status elsewhere. */
1757                 return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1758         }
1759
1760         return init_dc_connection_network(domain);
1761 }
1762
1763 static NTSTATUS init_dc_connection_rpc(struct winbindd_domain *domain)
1764 {
1765         NTSTATUS status;
1766
1767         status = init_dc_connection(domain);
1768         if (!NT_STATUS_IS_OK(status)) {
1769                 return status;
1770         }
1771
1772         if (!domain->internal && domain->conn.cli == NULL) {
1773                 /* happens for trusted domains without inbound trust */
1774                 return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
1775         }
1776
1777         return NT_STATUS_OK;
1778 }
1779
1780 /******************************************************************************
1781  Set the trust flags (direction and forest location) for a domain
1782 ******************************************************************************/
1783
1784 static bool set_dc_type_and_flags_trustinfo( struct winbindd_domain *domain )
1785 {
1786         struct winbindd_domain *our_domain;
1787         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1788         WERROR werr;
1789         struct netr_DomainTrustList trusts;
1790         int i;
1791         uint32 flags = (NETR_TRUST_FLAG_IN_FOREST |
1792                         NETR_TRUST_FLAG_OUTBOUND |
1793                         NETR_TRUST_FLAG_INBOUND);
1794         struct rpc_pipe_client *cli;
1795         TALLOC_CTX *mem_ctx = NULL;
1796         struct dcerpc_binding_handle *b;
1797
1798         DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s\n", domain->name ));
1799
1800         /* Our primary domain doesn't need to worry about trust flags.
1801            Force it to go through the network setup */
1802         if ( domain->primary ) {                
1803                 return False;           
1804         }
1805
1806         our_domain = find_our_domain();
1807
1808         if ( !connection_ok(our_domain) ) {
1809                 DEBUG(3,("set_dc_type_and_flags_trustinfo: No connection to our domain!\n"));           
1810                 return False;
1811         }
1812
1813         /* This won't work unless our domain is AD */
1814
1815         if ( !our_domain->active_directory ) {
1816                 return False;
1817         }
1818
1819         /* Use DsEnumerateDomainTrusts to get us the trust direction
1820            and type */
1821
1822         result = cm_connect_netlogon(our_domain, &cli);
1823
1824         if (!NT_STATUS_IS_OK(result)) {
1825                 DEBUG(5, ("set_dc_type_and_flags_trustinfo: Could not open "
1826                           "a connection to %s for PIPE_NETLOGON (%s)\n", 
1827                           domain->name, nt_errstr(result)));
1828                 return False;
1829         }
1830
1831         b = cli->binding_handle;
1832
1833         if ( (mem_ctx = talloc_init("set_dc_type_and_flags_trustinfo")) == NULL ) {
1834                 DEBUG(0,("set_dc_type_and_flags_trustinfo: talloc_init() failed!\n"));
1835                 return False;
1836         }       
1837
1838         result = dcerpc_netr_DsrEnumerateDomainTrusts(b, mem_ctx,
1839                                                       cli->desthost,
1840                                                       flags,
1841                                                       &trusts,
1842                                                       &werr);
1843         if (!NT_STATUS_IS_OK(result)) {
1844                 DEBUG(0,("set_dc_type_and_flags_trustinfo: "
1845                         "failed to query trusted domain list: %s\n",
1846                         nt_errstr(result)));
1847                 talloc_destroy(mem_ctx);
1848                 return false;
1849         }
1850         if (!W_ERROR_IS_OK(werr)) {
1851                 DEBUG(0,("set_dc_type_and_flags_trustinfo: "
1852                         "failed to query trusted domain list: %s\n",
1853                         win_errstr(werr)));
1854                 talloc_destroy(mem_ctx);
1855                 return false;
1856         }
1857
1858         /* Now find the domain name and get the flags */
1859
1860         for ( i=0; i<trusts.count; i++ ) {
1861                 if ( strequal( domain->name, trusts.array[i].netbios_name) ) {
1862                         domain->domain_flags          = trusts.array[i].trust_flags;
1863                         domain->domain_type           = trusts.array[i].trust_type;
1864                         domain->domain_trust_attribs  = trusts.array[i].trust_attributes;
1865
1866                         if ( domain->domain_type == NETR_TRUST_TYPE_UPLEVEL )
1867                                 domain->active_directory = True;
1868
1869                         /* This flag is only set if the domain is *our* 
1870                            primary domain and the primary domain is in
1871                            native mode */
1872
1873                         domain->native_mode = (domain->domain_flags & NETR_TRUST_FLAG_NATIVE);
1874
1875                         DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s is %sin "
1876                                   "native mode.\n", domain->name, 
1877                                   domain->native_mode ? "" : "NOT "));
1878
1879                         DEBUG(5,("set_dc_type_and_flags_trustinfo: domain %s is %s"
1880                                  "running active directory.\n", domain->name, 
1881                                  domain->active_directory ? "" : "NOT "));
1882
1883
1884                         domain->initialized = True;
1885
1886                         break;
1887                 }               
1888         }
1889
1890         talloc_destroy( mem_ctx );
1891
1892         return domain->initialized;     
1893 }
1894
1895 /******************************************************************************
1896  We can 'sense' certain things about the DC by it's replies to certain
1897  questions.
1898
1899  This tells us if this particular remote server is Active Directory, and if it
1900  is native mode.
1901 ******************************************************************************/
1902
1903 static void set_dc_type_and_flags_connect( struct winbindd_domain *domain )
1904 {
1905         NTSTATUS status, result;
1906         WERROR werr;
1907         TALLOC_CTX              *mem_ctx = NULL;
1908         struct rpc_pipe_client  *cli = NULL;
1909         struct policy_handle pol;
1910         union dssetup_DsRoleInfo info;
1911         union lsa_PolicyInformation *lsa_info = NULL;
1912
1913         if (!connection_ok(domain)) {
1914                 return;
1915         }
1916
1917         mem_ctx = talloc_init("set_dc_type_and_flags on domain %s\n",
1918                               domain->name);
1919         if (!mem_ctx) {
1920                 DEBUG(1, ("set_dc_type_and_flags_connect: talloc_init() failed\n"));
1921                 return;
1922         }
1923
1924         DEBUG(5, ("set_dc_type_and_flags_connect: domain %s\n", domain->name ));
1925
1926         status = cli_rpc_pipe_open_noauth(domain->conn.cli,
1927                                           &ndr_table_dssetup.syntax_id,
1928                                           &cli);
1929
1930         if (!NT_STATUS_IS_OK(status)) {
1931                 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
1932                           "PI_DSSETUP on domain %s: (%s)\n",
1933                           domain->name, nt_errstr(status)));
1934
1935                 /* if this is just a non-AD domain we need to continue
1936                  * identifying so that we can in the end return with
1937                  * domain->initialized = True - gd */
1938
1939                 goto no_dssetup;
1940         }
1941
1942         status = dcerpc_dssetup_DsRoleGetPrimaryDomainInformation(cli->binding_handle, mem_ctx,
1943                                                                   DS_ROLE_BASIC_INFORMATION,
1944                                                                   &info,
1945                                                                   &werr);
1946         TALLOC_FREE(cli);
1947
1948         if (NT_STATUS_IS_OK(status)) {
1949                 result = werror_to_ntstatus(werr);
1950         }
1951         if (!NT_STATUS_IS_OK(status)) {
1952                 DEBUG(5, ("set_dc_type_and_flags_connect: rpccli_ds_getprimarydominfo "
1953                           "on domain %s failed: (%s)\n",
1954                           domain->name, nt_errstr(status)));
1955
1956                 /* older samba3 DCs will return DCERPC_FAULT_OP_RNG_ERROR for
1957                  * every opcode on the DSSETUP pipe, continue with
1958                  * no_dssetup mode here as well to get domain->initialized
1959                  * set - gd */
1960
1961                 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
1962                         goto no_dssetup;
1963                 }
1964
1965                 TALLOC_FREE(mem_ctx);
1966                 return;
1967         }
1968
1969         if ((info.basic.flags & DS_ROLE_PRIMARY_DS_RUNNING) &&
1970             !(info.basic.flags & DS_ROLE_PRIMARY_DS_MIXED_MODE)) {
1971                 domain->native_mode = True;
1972         } else {
1973                 domain->native_mode = False;
1974         }
1975
1976 no_dssetup:
1977         status = cli_rpc_pipe_open_noauth(domain->conn.cli,
1978                                           &ndr_table_lsarpc.syntax_id, &cli);
1979
1980         if (!NT_STATUS_IS_OK(status)) {
1981                 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
1982                           "PI_LSARPC on domain %s: (%s)\n",
1983                           domain->name, nt_errstr(status)));
1984                 TALLOC_FREE(cli);
1985                 TALLOC_FREE(mem_ctx);
1986                 return;
1987         }
1988
1989         status = rpccli_lsa_open_policy2(cli, mem_ctx, True,
1990                                          SEC_FLAG_MAXIMUM_ALLOWED, &pol);
1991
1992         if (NT_STATUS_IS_OK(status)) {
1993                 /* This particular query is exactly what Win2k clients use 
1994                    to determine that the DC is active directory */
1995                 status = dcerpc_lsa_QueryInfoPolicy2(cli->binding_handle, mem_ctx,
1996                                                      &pol,
1997                                                      LSA_POLICY_INFO_DNS,
1998                                                      &lsa_info,
1999                                                      &result);
2000         }
2001
2002         if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2003                 domain->active_directory = True;
2004
2005                 if (lsa_info->dns.name.string) {
2006                         fstrcpy(domain->name, lsa_info->dns.name.string);
2007                 }
2008
2009                 if (lsa_info->dns.dns_domain.string) {
2010                         fstrcpy(domain->alt_name,
2011                                 lsa_info->dns.dns_domain.string);
2012                 }
2013
2014                 /* See if we can set some domain trust flags about
2015                    ourself */
2016
2017                 if (lsa_info->dns.dns_forest.string) {
2018                         fstrcpy(domain->forest_name,
2019                                 lsa_info->dns.dns_forest.string);
2020
2021                         if (strequal(domain->forest_name, domain->alt_name)) {
2022                                 domain->domain_flags |= NETR_TRUST_FLAG_TREEROOT;
2023                         }
2024                 }
2025
2026                 if (lsa_info->dns.sid) {
2027                         sid_copy(&domain->sid, lsa_info->dns.sid);
2028                 }
2029         } else {
2030                 domain->active_directory = False;
2031
2032                 status = rpccli_lsa_open_policy(cli, mem_ctx, True,
2033                                                 SEC_FLAG_MAXIMUM_ALLOWED,
2034                                                 &pol);
2035
2036                 if (!NT_STATUS_IS_OK(status)) {
2037                         goto done;
2038                 }
2039
2040                 status = dcerpc_lsa_QueryInfoPolicy(cli->binding_handle, mem_ctx,
2041                                                     &pol,
2042                                                     LSA_POLICY_INFO_ACCOUNT_DOMAIN,
2043                                                     &lsa_info,
2044                                                     &result);
2045                 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2046
2047                         if (lsa_info->account_domain.name.string) {
2048                                 fstrcpy(domain->name,
2049                                         lsa_info->account_domain.name.string);
2050                         }
2051
2052                         if (lsa_info->account_domain.sid) {
2053                                 sid_copy(&domain->sid, lsa_info->account_domain.sid);
2054                         }
2055                 }
2056         }
2057 done:
2058
2059         DEBUG(5, ("set_dc_type_and_flags_connect: domain %s is %sin native mode.\n",
2060                   domain->name, domain->native_mode ? "" : "NOT "));
2061
2062         DEBUG(5,("set_dc_type_and_flags_connect: domain %s is %srunning active directory.\n",
2063                   domain->name, domain->active_directory ? "" : "NOT "));
2064
2065         domain->can_do_ncacn_ip_tcp = domain->active_directory;
2066         domain->can_do_validation6 = domain->active_directory;
2067
2068         TALLOC_FREE(cli);
2069
2070         TALLOC_FREE(mem_ctx);
2071
2072         domain->initialized = True;
2073 }
2074
2075 /**********************************************************************
2076  Set the domain_flags (trust attributes, domain operating modes, etc... 
2077 ***********************************************************************/
2078
2079 static void set_dc_type_and_flags( struct winbindd_domain *domain )
2080 {
2081         /* we always have to contact our primary domain */
2082
2083         if ( domain->primary ) {
2084                 DEBUG(10,("set_dc_type_and_flags: setting up flags for "
2085                           "primary domain\n"));
2086                 set_dc_type_and_flags_connect( domain );
2087                 return;         
2088         }
2089
2090         /* Use our DC to get the information if possible */
2091
2092         if ( !set_dc_type_and_flags_trustinfo( domain ) ) {
2093                 /* Otherwise, fallback to contacting the 
2094                    domain directly */
2095                 set_dc_type_and_flags_connect( domain );
2096         }
2097
2098         return;
2099 }
2100
2101
2102
2103 /**********************************************************************
2104 ***********************************************************************/
2105
2106 static NTSTATUS cm_get_schannel_creds(struct winbindd_domain *domain,
2107                                    struct netlogon_creds_CredentialState **ppdc)
2108 {
2109         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2110         struct rpc_pipe_client *netlogon_pipe;
2111
2112         if (lp_client_schannel() == False) {
2113                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2114         }
2115
2116         result = cm_connect_netlogon(domain, &netlogon_pipe);
2117         if (!NT_STATUS_IS_OK(result)) {
2118                 return result;
2119         }
2120
2121         /* Return a pointer to the struct netlogon_creds_CredentialState from the
2122            netlogon pipe. */
2123
2124         if (!domain->conn.netlogon_pipe->dc) {
2125                 return NT_STATUS_INTERNAL_ERROR; /* This shouldn't happen. */
2126         }
2127
2128         *ppdc = domain->conn.netlogon_pipe->dc;
2129         return NT_STATUS_OK;
2130 }
2131
2132 NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
2133                         struct rpc_pipe_client **cli, struct policy_handle *sam_handle)
2134 {
2135         struct winbindd_cm_conn *conn;
2136         NTSTATUS status, result;
2137         struct netlogon_creds_CredentialState *p_creds;
2138         char *machine_password = NULL;
2139         char *machine_account = NULL;
2140         char *domain_name = NULL;
2141
2142         if (sid_check_is_domain(&domain->sid)) {
2143                 return open_internal_samr_conn(mem_ctx, domain, cli, sam_handle);
2144         }
2145
2146         status = init_dc_connection_rpc(domain);
2147         if (!NT_STATUS_IS_OK(status)) {
2148                 return status;
2149         }
2150
2151         conn = &domain->conn;
2152
2153         if (rpccli_is_connected(conn->samr_pipe)) {
2154                 goto done;
2155         }
2156
2157         TALLOC_FREE(conn->samr_pipe);
2158
2159         /*
2160          * No SAMR pipe yet. Attempt to get an NTLMSSP SPNEGO authenticated
2161          * sign and sealed pipe using the machine account password by
2162          * preference. If we can't - try schannel, if that fails, try
2163          * anonymous.
2164          */
2165
2166         if ((conn->cli->user_name[0] == '\0') ||
2167             (conn->cli->domain[0] == '\0') || 
2168             (conn->cli->password == NULL || conn->cli->password[0] == '\0'))
2169         {
2170                 status = get_trust_creds(domain, &machine_password,
2171                                          &machine_account, NULL);
2172                 if (!NT_STATUS_IS_OK(status)) {
2173                         DEBUG(10, ("cm_connect_sam: No no user available for "
2174                                    "domain %s, trying schannel\n", conn->cli->domain));
2175                         goto schannel;
2176                 }
2177                 domain_name = domain->name;
2178         } else {
2179                 machine_password = SMB_STRDUP(conn->cli->password);
2180                 machine_account = SMB_STRDUP(conn->cli->user_name);
2181                 domain_name = conn->cli->domain;
2182         }
2183
2184         if (!machine_password || !machine_account) {
2185                 status = NT_STATUS_NO_MEMORY;
2186                 goto done;
2187         }
2188
2189         /* We have an authenticated connection. Use a NTLMSSP SPNEGO
2190            authenticated SAMR pipe with sign & seal. */
2191         status = cli_rpc_pipe_open_spnego_ntlmssp(conn->cli,
2192                                                   &ndr_table_samr.syntax_id,
2193                                                   NCACN_NP,
2194                                                   DCERPC_AUTH_LEVEL_PRIVACY,
2195                                                   domain_name,
2196                                                   machine_account,
2197                                                   machine_password,
2198                                                   &conn->samr_pipe);
2199
2200         if (!NT_STATUS_IS_OK(status)) {
2201                 DEBUG(10,("cm_connect_sam: failed to connect to SAMR "
2202                           "pipe for domain %s using NTLMSSP "
2203                           "authenticated pipe: user %s\\%s. Error was "
2204                           "%s\n", domain->name, domain_name,
2205                           machine_account, nt_errstr(status)));
2206                 goto schannel;
2207         }
2208
2209         DEBUG(10,("cm_connect_sam: connected to SAMR pipe for "
2210                   "domain %s using NTLMSSP authenticated "
2211                   "pipe: user %s\\%s\n", domain->name,
2212                   domain_name, machine_account));
2213
2214         status = dcerpc_samr_Connect2(conn->samr_pipe->binding_handle, mem_ctx,
2215                                       conn->samr_pipe->desthost,
2216                                       SEC_FLAG_MAXIMUM_ALLOWED,
2217                                       &conn->sam_connect_handle,
2218                                       &result);
2219         if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2220                 goto open_domain;
2221         }
2222         if (NT_STATUS_IS_OK(status)) {
2223                 status = result;
2224         }
2225
2226         DEBUG(10,("cm_connect_sam: ntlmssp-sealed dcerpc_samr_Connect2 "
2227                   "failed for domain %s, error was %s. Trying schannel\n",
2228                   domain->name, nt_errstr(status) ));
2229         TALLOC_FREE(conn->samr_pipe);
2230
2231  schannel:
2232
2233         /* Fall back to schannel if it's a W2K pre-SP1 box. */
2234
2235         status = cm_get_schannel_creds(domain, &p_creds);
2236         if (!NT_STATUS_IS_OK(status)) {
2237                 /* If this call fails - conn->cli can now be NULL ! */
2238                 DEBUG(10, ("cm_connect_sam: Could not get schannel auth info "
2239                            "for domain %s (error %s), trying anon\n",
2240                         domain->name,
2241                         nt_errstr(status) ));
2242                 goto anonymous;
2243         }
2244         status = cli_rpc_pipe_open_schannel_with_key
2245                 (conn->cli, &ndr_table_samr.syntax_id, NCACN_NP,
2246                  DCERPC_AUTH_LEVEL_PRIVACY,
2247                  domain->name, &p_creds, &conn->samr_pipe);
2248
2249         if (!NT_STATUS_IS_OK(status)) {
2250                 DEBUG(10,("cm_connect_sam: failed to connect to SAMR pipe for "
2251                           "domain %s using schannel. Error was %s\n",
2252                           domain->name, nt_errstr(status) ));
2253                 goto anonymous;
2254         }
2255         DEBUG(10,("cm_connect_sam: connected to SAMR pipe for domain %s using "
2256                   "schannel.\n", domain->name ));
2257
2258         status = dcerpc_samr_Connect2(conn->samr_pipe->binding_handle, mem_ctx,
2259                                       conn->samr_pipe->desthost,
2260                                       SEC_FLAG_MAXIMUM_ALLOWED,
2261                                       &conn->sam_connect_handle,
2262                                       &result);
2263         if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2264                 goto open_domain;
2265         }
2266         if (NT_STATUS_IS_OK(status)) {
2267                 status = result;
2268         }
2269         DEBUG(10,("cm_connect_sam: schannel-sealed dcerpc_samr_Connect2 failed "
2270                   "for domain %s, error was %s. Trying anonymous\n",
2271                   domain->name, nt_errstr(status) ));
2272         TALLOC_FREE(conn->samr_pipe);
2273
2274  anonymous:
2275
2276         /* Finally fall back to anonymous. */
2277         status = cli_rpc_pipe_open_noauth(conn->cli, &ndr_table_samr.syntax_id,
2278                                           &conn->samr_pipe);
2279
2280         if (!NT_STATUS_IS_OK(status)) {
2281                 goto done;
2282         }
2283
2284         status = dcerpc_samr_Connect2(conn->samr_pipe->binding_handle, mem_ctx,
2285                                       conn->samr_pipe->desthost,
2286                                       SEC_FLAG_MAXIMUM_ALLOWED,
2287                                       &conn->sam_connect_handle,
2288                                       &result);
2289         if (!NT_STATUS_IS_OK(status)) {
2290                 DEBUG(10,("cm_connect_sam: rpccli_samr_Connect2 failed "
2291                           "for domain %s Error was %s\n",
2292                           domain->name, nt_errstr(status) ));
2293                 goto done;
2294         }
2295         if (!NT_STATUS_IS_OK(result)) {
2296                 status = result;
2297                 DEBUG(10,("cm_connect_sam: dcerpc_samr_Connect2 failed "
2298                           "for domain %s Error was %s\n",
2299                           domain->name, nt_errstr(result)));
2300                 goto done;
2301         }
2302
2303  open_domain:
2304         status = dcerpc_samr_OpenDomain(conn->samr_pipe->binding_handle,
2305                                         mem_ctx,
2306                                         &conn->sam_connect_handle,
2307                                         SEC_FLAG_MAXIMUM_ALLOWED,
2308                                         &domain->sid,
2309                                         &conn->sam_domain_handle,
2310                                         &result);
2311         if (!NT_STATUS_IS_OK(status)) {
2312                 goto done;
2313         }
2314
2315         status = result;
2316  done:
2317
2318         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2319                 /*
2320                  * if we got access denied, we might just have no access rights
2321                  * to talk to the remote samr server server (e.g. when we are a
2322                  * PDC and we are connecting a w2k8 pdc via an interdomain
2323                  * trust). In that case do not invalidate the whole connection
2324                  * stack
2325                  */
2326                 TALLOC_FREE(conn->samr_pipe);
2327                 ZERO_STRUCT(conn->sam_domain_handle);
2328                 return status;
2329         } else if (!NT_STATUS_IS_OK(status)) {
2330                 invalidate_cm_connection(conn);
2331                 return status;
2332         }
2333
2334         *cli = conn->samr_pipe;
2335         *sam_handle = conn->sam_domain_handle;
2336         SAFE_FREE(machine_password);
2337         SAFE_FREE(machine_account);
2338         return status;
2339 }
2340
2341 /**********************************************************************
2342  open an schanneld ncacn_ip_tcp connection to LSA
2343 ***********************************************************************/
2344
2345 NTSTATUS cm_connect_lsa_tcp(struct winbindd_domain *domain,
2346                             TALLOC_CTX *mem_ctx,
2347                             struct rpc_pipe_client **cli)
2348 {
2349         struct winbindd_cm_conn *conn;
2350         struct netlogon_creds_CredentialState *creds;
2351         NTSTATUS status;
2352
2353         DEBUG(10,("cm_connect_lsa_tcp\n"));
2354
2355         status = init_dc_connection_rpc(domain);
2356         if (!NT_STATUS_IS_OK(status)) {
2357                 return status;
2358         }
2359
2360         conn = &domain->conn;
2361
2362         if (conn->lsa_pipe_tcp &&
2363             conn->lsa_pipe_tcp->transport->transport == NCACN_IP_TCP &&
2364             conn->lsa_pipe_tcp->auth->auth_level == DCERPC_AUTH_LEVEL_PRIVACY &&
2365             rpccli_is_connected(conn->lsa_pipe_tcp)) {
2366                 goto done;
2367         }
2368
2369         TALLOC_FREE(conn->lsa_pipe_tcp);
2370
2371         status = cm_get_schannel_creds(domain, &creds);
2372         if (!NT_STATUS_IS_OK(status)) {
2373                 goto done;
2374         }
2375
2376         status = cli_rpc_pipe_open_schannel_with_key(conn->cli,
2377                                                      &ndr_table_lsarpc.syntax_id,
2378                                                      NCACN_IP_TCP,
2379                                                      DCERPC_AUTH_LEVEL_PRIVACY,
2380                                                      domain->name,
2381                                                      &creds,
2382                                                      &conn->lsa_pipe_tcp);
2383         if (!NT_STATUS_IS_OK(status)) {
2384                 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key failed: %s\n",
2385                         nt_errstr(status)));
2386                 goto done;
2387         }
2388
2389  done:
2390         if (!NT_STATUS_IS_OK(status)) {
2391                 TALLOC_FREE(conn->lsa_pipe_tcp);
2392                 return status;
2393         }
2394
2395         *cli = conn->lsa_pipe_tcp;
2396
2397         return status;
2398 }
2399
2400 NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
2401                         struct rpc_pipe_client **cli, struct policy_handle *lsa_policy)
2402 {
2403         struct winbindd_cm_conn *conn;
2404         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2405         struct netlogon_creds_CredentialState *p_creds;
2406
2407         result = init_dc_connection_rpc(domain);
2408         if (!NT_STATUS_IS_OK(result))
2409                 return result;
2410
2411         conn = &domain->conn;
2412
2413         if (rpccli_is_connected(conn->lsa_pipe)) {
2414                 goto done;
2415         }
2416
2417         TALLOC_FREE(conn->lsa_pipe);
2418
2419         if ((conn->cli->user_name[0] == '\0') ||
2420             (conn->cli->domain[0] == '\0') || 
2421             (conn->cli->password == NULL || conn->cli->password[0] == '\0')) {
2422                 DEBUG(10, ("cm_connect_lsa: No no user available for "
2423                            "domain %s, trying schannel\n", conn->cli->domain));
2424                 goto schannel;
2425         }
2426
2427         /* We have an authenticated connection. Use a NTLMSSP SPNEGO
2428          * authenticated LSA pipe with sign & seal. */
2429         result = cli_rpc_pipe_open_spnego_ntlmssp
2430                 (conn->cli, &ndr_table_lsarpc.syntax_id, NCACN_NP,
2431                  DCERPC_AUTH_LEVEL_PRIVACY,
2432                  conn->cli->domain, conn->cli->user_name, conn->cli->password,
2433                  &conn->lsa_pipe);
2434
2435         if (!NT_STATUS_IS_OK(result)) {
2436                 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
2437                           "domain %s using NTLMSSP authenticated pipe: user "
2438                           "%s\\%s. Error was %s. Trying schannel.\n",
2439                           domain->name, conn->cli->domain,
2440                           conn->cli->user_name, nt_errstr(result)));
2441                 goto schannel;
2442         }
2443
2444         DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
2445                   "NTLMSSP authenticated pipe: user %s\\%s\n",
2446                   domain->name, conn->cli->domain, conn->cli->user_name ));
2447
2448         result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2449                                         SEC_FLAG_MAXIMUM_ALLOWED,
2450                                         &conn->lsa_policy);
2451         if (NT_STATUS_IS_OK(result)) {
2452                 goto done;
2453         }
2454
2455         DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
2456                   "schannel\n"));
2457
2458         TALLOC_FREE(conn->lsa_pipe);
2459
2460  schannel:
2461
2462         /* Fall back to schannel if it's a W2K pre-SP1 box. */
2463
2464         result = cm_get_schannel_creds(domain, &p_creds);
2465         if (!NT_STATUS_IS_OK(result)) {
2466                 /* If this call fails - conn->cli can now be NULL ! */
2467                 DEBUG(10, ("cm_connect_lsa: Could not get schannel auth info "
2468                            "for domain %s (error %s), trying anon\n",
2469                         domain->name,
2470                         nt_errstr(result) ));
2471                 goto anonymous;
2472         }
2473         result = cli_rpc_pipe_open_schannel_with_key
2474                 (conn->cli, &ndr_table_lsarpc.syntax_id, NCACN_NP,
2475                  DCERPC_AUTH_LEVEL_PRIVACY,
2476                  domain->name, &p_creds, &conn->lsa_pipe);
2477
2478         if (!NT_STATUS_IS_OK(result)) {
2479                 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
2480                           "domain %s using schannel. Error was %s\n",
2481                           domain->name, nt_errstr(result) ));
2482                 goto anonymous;
2483         }
2484         DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
2485                   "schannel.\n", domain->name ));
2486
2487         result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2488                                         SEC_FLAG_MAXIMUM_ALLOWED,
2489                                         &conn->lsa_policy);
2490         if (NT_STATUS_IS_OK(result)) {
2491                 goto done;
2492         }
2493
2494         DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
2495                   "anonymous\n"));
2496
2497         TALLOC_FREE(conn->lsa_pipe);
2498
2499  anonymous:
2500
2501         result = cli_rpc_pipe_open_noauth(conn->cli,
2502                                           &ndr_table_lsarpc.syntax_id,
2503                                           &conn->lsa_pipe);
2504         if (!NT_STATUS_IS_OK(result)) {
2505                 result = NT_STATUS_PIPE_NOT_AVAILABLE;
2506                 goto done;
2507         }
2508
2509         result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2510                                         SEC_FLAG_MAXIMUM_ALLOWED,
2511                                         &conn->lsa_policy);
2512  done:
2513         if (!NT_STATUS_IS_OK(result)) {
2514                 invalidate_cm_connection(conn);
2515                 return result;
2516         }
2517
2518         *cli = conn->lsa_pipe;
2519         *lsa_policy = conn->lsa_policy;
2520         return result;
2521 }
2522
2523 /****************************************************************************
2524  Open the netlogon pipe to this DC. Use schannel if specified in client conf.
2525  session key stored in conn->netlogon_pipe->dc->sess_key.
2526 ****************************************************************************/
2527
2528 NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
2529                              struct rpc_pipe_client **cli)
2530 {
2531         struct winbindd_cm_conn *conn;
2532         NTSTATUS result;
2533
2534         uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
2535         uint8  mach_pwd[16];
2536         enum netr_SchannelType sec_chan_type;
2537         const char *account_name;
2538         struct rpc_pipe_client *netlogon_pipe = NULL;
2539
2540         *cli = NULL;
2541
2542         result = init_dc_connection_rpc(domain);
2543         if (!NT_STATUS_IS_OK(result)) {
2544                 return result;
2545         }
2546
2547         conn = &domain->conn;
2548
2549         if (rpccli_is_connected(conn->netlogon_pipe)) {
2550                 *cli = conn->netlogon_pipe;
2551                 return NT_STATUS_OK;
2552         }
2553
2554         TALLOC_FREE(conn->netlogon_pipe);
2555
2556         result = cli_rpc_pipe_open_noauth(conn->cli,
2557                                           &ndr_table_netlogon.syntax_id,
2558                                           &netlogon_pipe);
2559         if (!NT_STATUS_IS_OK(result)) {
2560                 return result;
2561         }
2562
2563         if ((!IS_DC) && (!domain->primary)) {
2564                 /* Clear the schannel request bit and drop down */
2565                 neg_flags &= ~NETLOGON_NEG_SCHANNEL;            
2566                 goto no_schannel;
2567         }
2568
2569         if (lp_client_schannel() != False) {
2570                 neg_flags |= NETLOGON_NEG_SCHANNEL;
2571         }
2572
2573         if (!get_trust_pw_hash(domain->name, mach_pwd, &account_name,
2574                                &sec_chan_type))
2575         {
2576                 TALLOC_FREE(netlogon_pipe);
2577                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2578         }
2579
2580         result = rpccli_netlogon_setup_creds(
2581                  netlogon_pipe,
2582                  domain->dcname, /* server name. */
2583                  domain->name,   /* domain name */
2584                  lp_netbios_name(), /* client name */
2585                  account_name,   /* machine account */
2586                  mach_pwd,       /* machine password */
2587                  sec_chan_type,  /* from get_trust_pw */
2588                  &neg_flags);
2589
2590         if (!NT_STATUS_IS_OK(result)) {
2591                 TALLOC_FREE(netlogon_pipe);
2592                 return result;
2593         }
2594
2595         if ((lp_client_schannel() == True) &&
2596                         ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
2597                 DEBUG(3, ("Server did not offer schannel\n"));
2598                 TALLOC_FREE(netlogon_pipe);
2599                 return NT_STATUS_ACCESS_DENIED;
2600         }
2601
2602  no_schannel:
2603         if ((lp_client_schannel() == False) ||
2604                         ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
2605                 /*
2606                  * NetSamLogonEx only works for schannel
2607                  */
2608                 domain->can_do_samlogon_ex = False;
2609
2610                 /* We're done - just keep the existing connection to NETLOGON
2611                  * open */
2612                 conn->netlogon_pipe = netlogon_pipe;
2613                 *cli = conn->netlogon_pipe;
2614                 return NT_STATUS_OK;
2615         }
2616
2617         /* Using the credentials from the first pipe, open a signed and sealed
2618            second netlogon pipe. The session key is stored in the schannel
2619            part of the new pipe auth struct.
2620         */
2621
2622         result = cli_rpc_pipe_open_schannel_with_key(
2623                 conn->cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
2624                 DCERPC_AUTH_LEVEL_PRIVACY, domain->name, &netlogon_pipe->dc,
2625                 &conn->netlogon_pipe);
2626
2627         /* We can now close the initial netlogon pipe. */
2628         TALLOC_FREE(netlogon_pipe);
2629
2630         if (!NT_STATUS_IS_OK(result)) {
2631                 DEBUG(3, ("Could not open schannel'ed NETLOGON pipe. Error "
2632                           "was %s\n", nt_errstr(result)));
2633
2634                 invalidate_cm_connection(conn);
2635                 return result;
2636         }
2637
2638         /*
2639          * Always try netr_LogonSamLogonEx. We will fall back for NT4
2640          * which gives DCERPC_FAULT_OP_RNG_ERROR (function not
2641          * supported). We used to only try SamLogonEx for AD, but
2642          * Samba DCs can also do it. And because we don't distinguish
2643          * between Samba and NT4, always try it once.
2644          */
2645         domain->can_do_samlogon_ex = true;
2646
2647         *cli = conn->netlogon_pipe;
2648         return NT_STATUS_OK;
2649 }
2650
2651 void winbind_msg_ip_dropped(struct messaging_context *msg_ctx,
2652                             void *private_data,
2653                             uint32_t msg_type,
2654                             struct server_id server_id,
2655                             DATA_BLOB *data)
2656 {
2657         struct winbindd_domain *domain;
2658         char *freeit = NULL;
2659         char *addr;
2660
2661         if ((data == NULL)
2662             || (data->data == NULL)
2663             || (data->length == 0)
2664             || (data->data[data->length-1] != '\0')) {
2665                 DEBUG(1, ("invalid msg_ip_dropped message: not a valid "
2666                           "string\n"));
2667                 return;
2668         }
2669
2670         addr = (char *)data->data;
2671         DEBUG(10, ("IP %s dropped\n", addr));
2672
2673         if (!is_ipaddress(addr)) {
2674                 char *slash;
2675                 /*
2676                  * Some code sends us ip addresses with the /netmask
2677                  * suffix
2678                  */
2679                 slash = strchr(addr, '/');
2680                 if (slash == NULL) {
2681                         DEBUG(1, ("invalid msg_ip_dropped message: %s",
2682                                   addr));
2683                         return;
2684                 }
2685                 freeit = talloc_strndup(talloc_tos(), addr, slash-addr);
2686                 if (freeit == NULL) {
2687                         DEBUG(1, ("talloc failed\n"));
2688                         return;
2689                 }
2690                 addr = freeit;
2691                 DEBUG(10, ("Stripped /netmask to IP %s\n", addr));
2692         }
2693
2694         for (domain = domain_list(); domain != NULL; domain = domain->next) {
2695                 char sockaddr[INET6_ADDRSTRLEN];
2696
2697                 if (!cli_state_is_connected(domain->conn.cli)) {
2698                         continue;
2699                 }
2700
2701                 print_sockaddr(sockaddr, sizeof(sockaddr),
2702                                cli_state_local_sockaddr(domain->conn.cli));
2703
2704                 if (strequal(sockaddr, addr)) {
2705                         cli_state_disconnect(domain->conn.cli);
2706                 }
2707         }
2708         TALLOC_FREE(freeit);
2709 }