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