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