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