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