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