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