s3:winbindd: also try SMB2 when connecting to "IPC$"
[mat/samba.git] / source3 / winbindd / winbindd_cm.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    Winbind daemon connection manager
5
6    Copyright (C) Tim Potter                2001
7    Copyright (C) Andrew Bartlett           2002
8    Copyright (C) Gerald (Jerry) Carter     2003-2005.
9    Copyright (C) Volker Lendecke           2004-2005
10    Copyright (C) Jeremy Allison            2006
11
12    This program is free software; you can redistribute it and/or modify
13    it under the terms of the GNU General Public License as published by
14    the Free Software Foundation; either version 3 of the License, or
15    (at your option) any later version.
16
17    This program is distributed in the hope that it will be useful,
18    but WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20    GNU General Public License for more details.
21
22    You should have received a copy of the GNU General Public License
23    along with this program.  If not, see <http://www.gnu.org/licenses/>.
24 */
25
26 /*
27    We need to manage connections to domain controllers without having to
28    mess up the main winbindd code with other issues.  The aim of the
29    connection manager is to:
30
31        - make connections to domain controllers and cache them
32        - re-establish connections when networks or servers go down
33        - centralise the policy on connection timeouts, domain controller
34          selection etc
35        - manage re-entrancy for when winbindd becomes able to handle
36          multiple outstanding rpc requests
37
38    Why not have connection management as part of the rpc layer like tng?
39    Good question.  This code may morph into libsmb/rpc_cache.c or something
40    like that but at the moment it's simply staying as part of winbind.  I
41    think the TNG architecture of forcing every user of the rpc layer to use
42    the connection caching system is a bad idea.  It should be an optional
43    method of using the routines.
44
45    The TNG design is quite good but I disagree with some aspects of the
46    implementation. -tpot
47
48  */
49
50 /*
51    TODO:
52
53      - I'm pretty annoyed by all the make_nmb_name() stuff.  It should be
54        moved down into another function.
55
56      - Take care when destroying cli_structs as they can be shared between
57        various sam handles.
58
59  */
60
61 #include "includes.h"
62 #include "winbindd.h"
63 #include "../libcli/auth/libcli_auth.h"
64 #include "../librpc/gen_ndr/ndr_netlogon_c.h"
65 #include "rpc_client/cli_pipe.h"
66 #include "rpc_client/cli_netlogon.h"
67 #include "../librpc/gen_ndr/ndr_samr_c.h"
68 #include "../librpc/gen_ndr/ndr_lsa_c.h"
69 #include "rpc_client/cli_lsarpc.h"
70 #include "../librpc/gen_ndr/ndr_dssetup_c.h"
71 #include "libads/sitename_cache.h"
72 #include "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         }
1162 #endif
1163
1164         status = nbt_getdc(winbind_messaging_context(), pss, domain->name,
1165                            &domain->sid, nt_version, mem_ctx, &nt_version,
1166                            &dc_name, NULL);
1167         if (NT_STATUS_IS_OK(status)) {
1168                 fstrcpy(name, dc_name);
1169                 namecache_store(name, 0x20, 1, &ip_list);
1170                 return True;
1171         }
1172
1173         /* try node status request */
1174
1175         if ( name_status_find(domain->name, 0x1c, 0x20, pss, name) ) {
1176                 namecache_store(name, 0x20, 1, &ip_list);
1177                 return True;
1178         }
1179         return False;
1180 }
1181
1182 /*******************************************************************
1183  Retrieve a list of IP addresses for domain controllers.
1184
1185  The array is sorted in the preferred connection order.
1186
1187  @param[in] mem_ctx talloc memory context to allocate from
1188  @param[in] domain domain to retrieve DCs for
1189  @param[out] dcs array of dcs that will be returned
1190  @param[out] num_dcs number of dcs returned in the dcs array
1191  @return always true
1192 *******************************************************************/
1193
1194 static bool get_dcs(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
1195                     struct dc_name_ip **dcs, int *num_dcs)
1196 {
1197         fstring dcname;
1198         struct  sockaddr_storage ss;
1199         struct  ip_service *ip_list = NULL;
1200         int     iplist_size = 0;
1201         int     i;
1202         bool    is_our_domain;
1203         enum security_types sec = (enum security_types)lp_security();
1204
1205         is_our_domain = strequal(domain->name, lp_workgroup());
1206
1207         /* If not our domain, get the preferred DC, by asking our primary DC */
1208         if ( !is_our_domain
1209                 && get_dc_name_via_netlogon(domain, dcname, &ss)
1210                 && add_one_dc_unique(mem_ctx, domain->name, dcname, &ss, dcs,
1211                        num_dcs) )
1212         {
1213                 char addr[INET6_ADDRSTRLEN];
1214                 print_sockaddr(addr, sizeof(addr), &ss);
1215                 DEBUG(10, ("Retrieved DC %s at %s via netlogon\n",
1216                            dcname, addr));
1217                 return True;
1218         }
1219
1220         if (sec == SEC_ADS) {
1221                 char *sitename = NULL;
1222
1223                 /* We need to make sure we know the local site before
1224                    doing any DNS queries, as this will restrict the
1225                    get_sorted_dc_list() call below to only fetching
1226                    DNS records for the correct site. */
1227
1228                 /* Find any DC to get the site record.
1229                    We deliberately don't care about the
1230                    return here. */
1231
1232                 get_dc_name(domain->name, domain->alt_name, dcname, &ss);
1233
1234                 sitename = sitename_fetch(domain->alt_name);
1235                 if (sitename) {
1236
1237                         /* Do the site-specific AD dns lookup first. */
1238                         get_sorted_dc_list(domain->alt_name, sitename, &ip_list,
1239                                &iplist_size, True);
1240
1241                         /* Add ips to the DC array.  We don't look up the name
1242                            of the DC in this function, but we fill in the char*
1243                            of the ip now to make the failed connection cache
1244                            work */
1245                         for ( i=0; i<iplist_size; i++ ) {
1246                                 char addr[INET6_ADDRSTRLEN];
1247                                 print_sockaddr(addr, sizeof(addr),
1248                                                 &ip_list[i].ss);
1249                                 add_one_dc_unique(mem_ctx,
1250                                                 domain->name,
1251                                                 addr,
1252                                                 &ip_list[i].ss,
1253                                                 dcs,
1254                                                 num_dcs);
1255                         }
1256
1257                         SAFE_FREE(ip_list);
1258                         SAFE_FREE(sitename);
1259                         iplist_size = 0;
1260                 }
1261
1262                 /* Now we add DCs from the main AD DNS lookup. */
1263                 get_sorted_dc_list(domain->alt_name, NULL, &ip_list,
1264                         &iplist_size, True);
1265
1266                 for ( i=0; i<iplist_size; i++ ) {
1267                         char addr[INET6_ADDRSTRLEN];
1268                         print_sockaddr(addr, sizeof(addr),
1269                                         &ip_list[i].ss);
1270                         add_one_dc_unique(mem_ctx,
1271                                         domain->name,
1272                                         addr,
1273                                         &ip_list[i].ss,
1274                                         dcs,
1275                                         num_dcs);
1276                 }
1277
1278                 SAFE_FREE(ip_list);
1279                 iplist_size = 0;
1280         }
1281
1282         /* Try standard netbios queries if no ADS */
1283         if (*num_dcs == 0) {
1284                 get_sorted_dc_list(domain->name, NULL, &ip_list, &iplist_size,
1285                        False);
1286
1287                 for ( i=0; i<iplist_size; i++ ) {
1288                         char addr[INET6_ADDRSTRLEN];
1289                         print_sockaddr(addr, sizeof(addr),
1290                                         &ip_list[i].ss);
1291                         add_one_dc_unique(mem_ctx,
1292                                         domain->name,
1293                                         addr,
1294                                         &ip_list[i].ss,
1295                                         dcs,
1296                                         num_dcs);
1297                 }
1298
1299                 SAFE_FREE(ip_list);
1300                 iplist_size = 0;
1301         }
1302
1303         return True;
1304 }
1305
1306 /*******************************************************************
1307  Find and make a connection to a DC in the given domain.
1308
1309  @param[in] mem_ctx talloc memory context to allocate from
1310  @param[in] domain domain to find a dc in
1311  @param[out] dcname NetBIOS or FQDN of DC that's connected to
1312  @param[out] pss DC Internet address and port
1313  @param[out] fd fd of the open socket connected to the newly found dc
1314  @return true when a DC connection is made, false otherwise
1315 *******************************************************************/
1316
1317 static bool find_new_dc(TALLOC_CTX *mem_ctx,
1318                         struct winbindd_domain *domain,
1319                         fstring dcname, struct sockaddr_storage *pss, int *fd)
1320 {
1321         struct dc_name_ip *dcs = NULL;
1322         int num_dcs = 0;
1323
1324         const char **dcnames = NULL;
1325         int num_dcnames = 0;
1326
1327         struct sockaddr_storage *addrs = NULL;
1328         int num_addrs = 0;
1329
1330         int i;
1331         size_t fd_index;
1332
1333         NTSTATUS status;
1334
1335         *fd = -1;
1336
1337  again:
1338         if (!get_dcs(mem_ctx, domain, &dcs, &num_dcs) || (num_dcs == 0))
1339                 return False;
1340
1341         for (i=0; i<num_dcs; i++) {
1342
1343                 if (!add_string_to_array(mem_ctx, dcs[i].name,
1344                                     &dcnames, &num_dcnames)) {
1345                         return False;
1346                 }
1347                 if (!add_sockaddr_to_array(mem_ctx, &dcs[i].ss, TCP_SMB_PORT,
1348                                       &addrs, &num_addrs)) {
1349                         return False;
1350                 }
1351         }
1352
1353         if ((num_dcnames == 0) || (num_dcnames != num_addrs))
1354                 return False;
1355
1356         if ((addrs == NULL) || (dcnames == NULL))
1357                 return False;
1358
1359         status = smbsock_any_connect(addrs, dcnames, NULL, NULL, NULL,
1360                                      num_addrs, 0, 10, fd, &fd_index, NULL);
1361         if (!NT_STATUS_IS_OK(status)) {
1362                 for (i=0; i<num_dcs; i++) {
1363                         char ab[INET6_ADDRSTRLEN];
1364                         print_sockaddr(ab, sizeof(ab), &dcs[i].ss);
1365                         DEBUG(10, ("find_new_dc: smbsock_any_connect failed for "
1366                                 "domain %s address %s. Error was %s\n",
1367                                    domain->name, ab, nt_errstr(status) ));
1368                         winbind_add_failed_connection_entry(domain,
1369                                 dcs[i].name, NT_STATUS_UNSUCCESSFUL);
1370                 }
1371                 return False;
1372         }
1373
1374         *pss = addrs[fd_index];
1375
1376         if (*dcnames[fd_index] != '\0' && !is_ipaddress(dcnames[fd_index])) {
1377                 /* Ok, we've got a name for the DC */
1378                 fstrcpy(dcname, dcnames[fd_index]);
1379                 return True;
1380         }
1381
1382         /* Try to figure out the name */
1383         if (dcip_to_name(mem_ctx, domain, pss, dcname)) {
1384                 return True;
1385         }
1386
1387         /* We can not continue without the DC's name */
1388         winbind_add_failed_connection_entry(domain, dcs[fd_index].name,
1389                                     NT_STATUS_UNSUCCESSFUL);
1390
1391         /* Throw away all arrays as we're doing this again. */
1392         TALLOC_FREE(dcs);
1393         num_dcs = 0;
1394
1395         TALLOC_FREE(dcnames);
1396         num_dcnames = 0;
1397
1398         TALLOC_FREE(addrs);
1399         num_addrs = 0;
1400
1401         close(*fd);
1402         *fd = -1;
1403
1404         goto again;
1405 }
1406
1407 static char *current_dc_key(TALLOC_CTX *mem_ctx, const char *domain_name)
1408 {
1409         return talloc_asprintf_strupper_m(mem_ctx, "CURRENT_DCNAME/%s",
1410                                           domain_name);
1411 }
1412
1413 static void store_current_dc_in_gencache(const char *domain_name,
1414                                          const char *dc_name,
1415                                          struct cli_state *cli)
1416 {
1417         char addr[INET6_ADDRSTRLEN];
1418         char *key = NULL;
1419         char *value = NULL;
1420
1421         if (!cli_state_is_connected(cli)) {
1422                 return;
1423         }
1424
1425         print_sockaddr(addr, sizeof(addr),
1426                        cli_state_remote_sockaddr(cli));
1427
1428         key = current_dc_key(talloc_tos(), domain_name);
1429         if (key == NULL) {
1430                 goto done;
1431         }
1432
1433         value = talloc_asprintf(talloc_tos(), "%s %s", addr, dc_name);
1434         if (value == NULL) {
1435                 goto done;
1436         }
1437
1438         gencache_set(key, value, 0x7fffffff);
1439 done:
1440         TALLOC_FREE(value);
1441         TALLOC_FREE(key);
1442 }
1443
1444 bool fetch_current_dc_from_gencache(TALLOC_CTX *mem_ctx,
1445                                     const char *domain_name,
1446                                     char **p_dc_name, char **p_dc_ip)
1447 {
1448         char *key, *value, *p;
1449         bool ret = false;
1450         char *dc_name = NULL;
1451         char *dc_ip = NULL;
1452
1453         key = current_dc_key(talloc_tos(), domain_name);
1454         if (key == NULL) {
1455                 goto done;
1456         }
1457         if (!gencache_get(key, &value, NULL)) {
1458                 goto done;
1459         }
1460         p = strchr(value, ' ');
1461         if (p == NULL) {
1462                 goto done;
1463         }
1464         dc_ip = talloc_strndup(mem_ctx, value, p - value);
1465         if (dc_ip == NULL) {
1466                 goto done;
1467         }
1468         dc_name = talloc_strdup(mem_ctx, p+1);
1469         if (dc_name == NULL) {
1470                 goto done;
1471         }
1472
1473         if (p_dc_ip != NULL) {
1474                 *p_dc_ip = dc_ip;
1475                 dc_ip = NULL;
1476         }
1477         if (p_dc_name != NULL) {
1478                 *p_dc_name = dc_name;
1479                 dc_name = NULL;
1480         }
1481         ret = true;
1482 done:
1483         TALLOC_FREE(dc_name);
1484         TALLOC_FREE(dc_ip);
1485         TALLOC_FREE(key);
1486         return ret;
1487 }
1488
1489 static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
1490                                    struct winbindd_cm_conn *new_conn)
1491 {
1492         TALLOC_CTX *mem_ctx;
1493         NTSTATUS result;
1494         char *saf_servername = saf_fetch( domain->name );
1495         int retries;
1496
1497         if ((mem_ctx = talloc_init("cm_open_connection")) == NULL) {
1498                 SAFE_FREE(saf_servername);
1499                 set_domain_offline(domain);
1500                 return NT_STATUS_NO_MEMORY;
1501         }
1502
1503         /* we have to check the server affinity cache here since 
1504            later we select a DC based on response time and not preference */
1505
1506         /* Check the negative connection cache
1507            before talking to it. It going down may have
1508            triggered the reconnection. */
1509
1510         if ( saf_servername && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, saf_servername))) {
1511
1512                 DEBUG(10,("cm_open_connection: saf_servername is '%s' for domain %s\n",
1513                         saf_servername, domain->name ));
1514
1515                 /* convert an ip address to a name */
1516                 if (is_ipaddress( saf_servername ) ) {
1517                         fstring saf_name;
1518                         struct sockaddr_storage ss;
1519
1520                         if (!interpret_string_addr(&ss, saf_servername,
1521                                                 AI_NUMERICHOST)) {
1522                                 return NT_STATUS_UNSUCCESSFUL;
1523                         }
1524                         if (dcip_to_name(mem_ctx, domain, &ss, saf_name )) {
1525                                 strlcpy(domain->dcname, saf_name, sizeof(domain->dcname));
1526                         } else {
1527                                 winbind_add_failed_connection_entry(
1528                                         domain, saf_servername,
1529                                         NT_STATUS_UNSUCCESSFUL);
1530                         }
1531                 } else {
1532                         fstrcpy( domain->dcname, saf_servername );
1533                 }
1534
1535                 SAFE_FREE( saf_servername );
1536         }
1537
1538         for (retries = 0; retries < 3; retries++) {
1539                 int fd = -1;
1540                 bool retry = False;
1541
1542                 result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1543
1544                 DEBUG(10,("cm_open_connection: dcname is '%s' for domain %s\n",
1545                         domain->dcname, domain->name ));
1546
1547                 if (*domain->dcname 
1548                         && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, domain->dcname))
1549                         && (resolve_name(domain->dcname, &domain->dcaddr, 0x20, true)))
1550                 {
1551                         NTSTATUS status;
1552
1553                         status = smbsock_connect(&domain->dcaddr, 0,
1554                                                  NULL, -1, NULL, -1,
1555                                                  &fd, NULL, 10);
1556                         if (!NT_STATUS_IS_OK(status)) {
1557                                 fd = -1;
1558                         }
1559                 }
1560
1561                 if ((fd == -1) 
1562                         && !find_new_dc(mem_ctx, domain, domain->dcname, &domain->dcaddr, &fd))
1563                 {
1564                         /* This is the one place where we will
1565                            set the global winbindd offline state
1566                            to true, if a "WINBINDD_OFFLINE" entry
1567                            is found in the winbindd cache. */
1568                         set_global_winbindd_state_offline();
1569                         break;
1570                 }
1571
1572                 new_conn->cli = NULL;
1573
1574                 result = cm_prepare_connection(domain, fd, domain->dcname,
1575                         &new_conn->cli, &retry);
1576
1577                 if (!retry)
1578                         break;
1579         }
1580
1581         if (NT_STATUS_IS_OK(result)) {
1582
1583                 winbindd_set_locator_kdc_envs(domain);
1584
1585                 if (domain->online == False) {
1586                         /* We're changing state from offline to online. */
1587                         set_global_winbindd_state_online();
1588                 }
1589                 set_domain_online(domain);
1590
1591                 /*
1592                  * Much as I hate global state, this seems to be the point
1593                  * where we can be certain that we have a proper connection to
1594                  * a DC. wbinfo --dc-info needs that information, store it in
1595                  * gencache with a looong timeout. This will need revisiting
1596                  * once we start to connect to multiple DCs, wbcDcInfo is
1597                  * already prepared for that.
1598                  */
1599                 store_current_dc_in_gencache(domain->name, domain->dcname,
1600                                              new_conn->cli);
1601         } else {
1602                 /* Ensure we setup the retry handler. */
1603                 set_domain_offline(domain);
1604         }
1605
1606         talloc_destroy(mem_ctx);
1607         return result;
1608 }
1609
1610 /* Close down all open pipes on a connection. */
1611
1612 void invalidate_cm_connection(struct winbindd_cm_conn *conn)
1613 {
1614         NTSTATUS result;
1615
1616         /* We're closing down a possibly dead
1617            connection. Don't have impossibly long (10s) timeouts. */
1618
1619         if (conn->cli) {
1620                 cli_set_timeout(conn->cli, 1000); /* 1 second. */
1621         }
1622
1623         if (conn->samr_pipe != NULL) {
1624                 if (is_valid_policy_hnd(&conn->sam_connect_handle)) {
1625                         dcerpc_samr_Close(conn->samr_pipe->binding_handle,
1626                                           talloc_tos(),
1627                                           &conn->sam_connect_handle,
1628                                           &result);
1629                 }
1630                 TALLOC_FREE(conn->samr_pipe);
1631                 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1632                 if (conn->cli) {
1633                         cli_set_timeout(conn->cli, 500);
1634                 }
1635         }
1636
1637         if (conn->lsa_pipe != NULL) {
1638                 if (is_valid_policy_hnd(&conn->lsa_policy)) {
1639                         dcerpc_lsa_Close(conn->lsa_pipe->binding_handle,
1640                                          talloc_tos(),
1641                                          &conn->lsa_policy,
1642                                          &result);
1643                 }
1644                 TALLOC_FREE(conn->lsa_pipe);
1645                 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1646                 if (conn->cli) {
1647                         cli_set_timeout(conn->cli, 500);
1648                 }
1649         }
1650
1651         if (conn->lsa_pipe_tcp != NULL) {
1652                 if (is_valid_policy_hnd(&conn->lsa_policy)) {
1653                         dcerpc_lsa_Close(conn->lsa_pipe_tcp->binding_handle,
1654                                          talloc_tos(),
1655                                          &conn->lsa_policy,
1656                                          &result);
1657                 }
1658                 TALLOC_FREE(conn->lsa_pipe_tcp);
1659                 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1660                 if (conn->cli) {
1661                         cli_set_timeout(conn->cli, 500);
1662                 }
1663         }
1664
1665         if (conn->netlogon_pipe != NULL) {
1666                 TALLOC_FREE(conn->netlogon_pipe);
1667                 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1668                 if (conn->cli) {
1669                         cli_set_timeout(conn->cli, 500);
1670                 }
1671         }
1672
1673         if (conn->cli) {
1674                 cli_shutdown(conn->cli);
1675         }
1676
1677         conn->cli = NULL;
1678 }
1679
1680 void close_conns_after_fork(void)
1681 {
1682         struct winbindd_domain *domain;
1683         struct winbindd_cli_state *cli_state;
1684
1685         for (domain = domain_list(); domain; domain = domain->next) {
1686                 /*
1687                  * first close the low level SMB TCP connection
1688                  * so that we don't generate any SMBclose
1689                  * requests in invalidate_cm_connection()
1690                  */
1691                 if (cli_state_is_connected(domain->conn.cli)) {
1692                         cli_state_disconnect(domain->conn.cli);
1693                 }
1694
1695                 invalidate_cm_connection(&domain->conn);
1696         }
1697
1698         for (cli_state = winbindd_client_list();
1699              cli_state != NULL;
1700              cli_state = cli_state->next) {
1701                 if (cli_state->sock >= 0) {
1702                         close(cli_state->sock);
1703                         cli_state->sock = -1;
1704                 }
1705         }
1706 }
1707
1708 static bool connection_ok(struct winbindd_domain *domain)
1709 {
1710         bool ok;
1711
1712         ok = cli_state_is_connected(domain->conn.cli);
1713         if (!ok) {
1714                 DEBUG(3, ("connection_ok: Connection to %s for domain %s is not connected\n",
1715                           domain->dcname, domain->name));
1716                 return False;
1717         }
1718
1719         if (domain->online == False) {
1720                 DEBUG(3, ("connection_ok: Domain %s is offline\n", domain->name));
1721                 return False;
1722         }
1723
1724         return True;
1725 }
1726
1727 /* Initialize a new connection up to the RPC BIND.
1728    Bypass online status check so always does network calls. */
1729
1730 static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain)
1731 {
1732         NTSTATUS result;
1733
1734         /* Internal connections never use the network. */
1735         if (domain->internal) {
1736                 domain->initialized = True;
1737                 return NT_STATUS_OK;
1738         }
1739
1740         if (!winbindd_can_contact_domain(domain)) {
1741                 invalidate_cm_connection(&domain->conn);
1742                 domain->initialized = True;
1743                 return NT_STATUS_OK;
1744         }
1745
1746         if (connection_ok(domain)) {
1747                 if (!domain->initialized) {
1748                         set_dc_type_and_flags(domain);
1749                 }
1750                 return NT_STATUS_OK;
1751         }
1752
1753         invalidate_cm_connection(&domain->conn);
1754
1755         result = cm_open_connection(domain, &domain->conn);
1756
1757         if (NT_STATUS_IS_OK(result) && !domain->initialized) {
1758                 set_dc_type_and_flags(domain);
1759         }
1760
1761         return result;
1762 }
1763
1764 NTSTATUS init_dc_connection(struct winbindd_domain *domain)
1765 {
1766         if (domain->internal) {
1767                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1768         }
1769
1770         if (domain->initialized && !domain->online) {
1771                 /* We check for online status elsewhere. */
1772                 return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1773         }
1774
1775         return init_dc_connection_network(domain);
1776 }
1777
1778 static NTSTATUS init_dc_connection_rpc(struct winbindd_domain *domain)
1779 {
1780         NTSTATUS status;
1781
1782         status = init_dc_connection(domain);
1783         if (!NT_STATUS_IS_OK(status)) {
1784                 return status;
1785         }
1786
1787         if (!domain->internal && domain->conn.cli == NULL) {
1788                 /* happens for trusted domains without inbound trust */
1789                 return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
1790         }
1791
1792         return NT_STATUS_OK;
1793 }
1794
1795 /******************************************************************************
1796  Set the trust flags (direction and forest location) for a domain
1797 ******************************************************************************/
1798
1799 static bool set_dc_type_and_flags_trustinfo( struct winbindd_domain *domain )
1800 {
1801         struct winbindd_domain *our_domain;
1802         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1803         WERROR werr;
1804         struct netr_DomainTrustList trusts;
1805         int i;
1806         uint32 flags = (NETR_TRUST_FLAG_IN_FOREST |
1807                         NETR_TRUST_FLAG_OUTBOUND |
1808                         NETR_TRUST_FLAG_INBOUND);
1809         struct rpc_pipe_client *cli;
1810         TALLOC_CTX *mem_ctx = NULL;
1811         struct dcerpc_binding_handle *b;
1812
1813         DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s\n", domain->name ));
1814
1815         /* Our primary domain doesn't need to worry about trust flags.
1816            Force it to go through the network setup */
1817         if ( domain->primary ) {                
1818                 return False;           
1819         }
1820
1821         our_domain = find_our_domain();
1822
1823         if ( !connection_ok(our_domain) ) {
1824                 DEBUG(3,("set_dc_type_and_flags_trustinfo: No connection to our domain!\n"));           
1825                 return False;
1826         }
1827
1828         /* This won't work unless our domain is AD */
1829
1830         if ( !our_domain->active_directory ) {
1831                 return False;
1832         }
1833
1834         /* Use DsEnumerateDomainTrusts to get us the trust direction
1835            and type */
1836
1837         result = cm_connect_netlogon(our_domain, &cli);
1838
1839         if (!NT_STATUS_IS_OK(result)) {
1840                 DEBUG(5, ("set_dc_type_and_flags_trustinfo: Could not open "
1841                           "a connection to %s for PIPE_NETLOGON (%s)\n", 
1842                           domain->name, nt_errstr(result)));
1843                 return False;
1844         }
1845
1846         b = cli->binding_handle;
1847
1848         if ( (mem_ctx = talloc_init("set_dc_type_and_flags_trustinfo")) == NULL ) {
1849                 DEBUG(0,("set_dc_type_and_flags_trustinfo: talloc_init() failed!\n"));
1850                 return False;
1851         }       
1852
1853         result = dcerpc_netr_DsrEnumerateDomainTrusts(b, mem_ctx,
1854                                                       cli->desthost,
1855                                                       flags,
1856                                                       &trusts,
1857                                                       &werr);
1858         if (!NT_STATUS_IS_OK(result)) {
1859                 DEBUG(0,("set_dc_type_and_flags_trustinfo: "
1860                         "failed to query trusted domain list: %s\n",
1861                         nt_errstr(result)));
1862                 talloc_destroy(mem_ctx);
1863                 return false;
1864         }
1865         if (!W_ERROR_IS_OK(werr)) {
1866                 DEBUG(0,("set_dc_type_and_flags_trustinfo: "
1867                         "failed to query trusted domain list: %s\n",
1868                         win_errstr(werr)));
1869                 talloc_destroy(mem_ctx);
1870                 return false;
1871         }
1872
1873         /* Now find the domain name and get the flags */
1874
1875         for ( i=0; i<trusts.count; i++ ) {
1876                 if ( strequal( domain->name, trusts.array[i].netbios_name) ) {
1877                         domain->domain_flags          = trusts.array[i].trust_flags;
1878                         domain->domain_type           = trusts.array[i].trust_type;
1879                         domain->domain_trust_attribs  = trusts.array[i].trust_attributes;
1880
1881                         if ( domain->domain_type == NETR_TRUST_TYPE_UPLEVEL )
1882                                 domain->active_directory = True;
1883
1884                         /* This flag is only set if the domain is *our* 
1885                            primary domain and the primary domain is in
1886                            native mode */
1887
1888                         domain->native_mode = (domain->domain_flags & NETR_TRUST_FLAG_NATIVE);
1889
1890                         DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s is %sin "
1891                                   "native mode.\n", domain->name, 
1892                                   domain->native_mode ? "" : "NOT "));
1893
1894                         DEBUG(5,("set_dc_type_and_flags_trustinfo: domain %s is %s"
1895                                  "running active directory.\n", domain->name, 
1896                                  domain->active_directory ? "" : "NOT "));
1897
1898                         domain->can_do_ncacn_ip_tcp = domain->active_directory;
1899                         domain->can_do_validation6 = domain->active_directory;
1900
1901                         domain->initialized = True;
1902
1903                         break;
1904                 }               
1905         }
1906
1907         talloc_destroy( mem_ctx );
1908
1909         return domain->initialized;     
1910 }
1911
1912 /******************************************************************************
1913  We can 'sense' certain things about the DC by it's replies to certain
1914  questions.
1915
1916  This tells us if this particular remote server is Active Directory, and if it
1917  is native mode.
1918 ******************************************************************************/
1919
1920 static void set_dc_type_and_flags_connect( struct winbindd_domain *domain )
1921 {
1922         NTSTATUS status, result;
1923         WERROR werr;
1924         TALLOC_CTX              *mem_ctx = NULL;
1925         struct rpc_pipe_client  *cli = NULL;
1926         struct policy_handle pol;
1927         union dssetup_DsRoleInfo info;
1928         union lsa_PolicyInformation *lsa_info = NULL;
1929
1930         if (!connection_ok(domain)) {
1931                 return;
1932         }
1933
1934         mem_ctx = talloc_init("set_dc_type_and_flags on domain %s\n",
1935                               domain->name);
1936         if (!mem_ctx) {
1937                 DEBUG(1, ("set_dc_type_and_flags_connect: talloc_init() failed\n"));
1938                 return;
1939         }
1940
1941         DEBUG(5, ("set_dc_type_and_flags_connect: domain %s\n", domain->name ));
1942
1943         status = cli_rpc_pipe_open_noauth(domain->conn.cli,
1944                                           &ndr_table_dssetup.syntax_id,
1945                                           &cli);
1946
1947         if (!NT_STATUS_IS_OK(status)) {
1948                 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
1949                           "PI_DSSETUP on domain %s: (%s)\n",
1950                           domain->name, nt_errstr(status)));
1951
1952                 /* if this is just a non-AD domain we need to continue
1953                  * identifying so that we can in the end return with
1954                  * domain->initialized = True - gd */
1955
1956                 goto no_dssetup;
1957         }
1958
1959         status = dcerpc_dssetup_DsRoleGetPrimaryDomainInformation(cli->binding_handle, mem_ctx,
1960                                                                   DS_ROLE_BASIC_INFORMATION,
1961                                                                   &info,
1962                                                                   &werr);
1963         TALLOC_FREE(cli);
1964
1965         if (NT_STATUS_IS_OK(status)) {
1966                 result = werror_to_ntstatus(werr);
1967         }
1968         if (!NT_STATUS_IS_OK(status)) {
1969                 DEBUG(5, ("set_dc_type_and_flags_connect: rpccli_ds_getprimarydominfo "
1970                           "on domain %s failed: (%s)\n",
1971                           domain->name, nt_errstr(status)));
1972
1973                 /* older samba3 DCs will return DCERPC_FAULT_OP_RNG_ERROR for
1974                  * every opcode on the DSSETUP pipe, continue with
1975                  * no_dssetup mode here as well to get domain->initialized
1976                  * set - gd */
1977
1978                 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
1979                         goto no_dssetup;
1980                 }
1981
1982                 TALLOC_FREE(mem_ctx);
1983                 return;
1984         }
1985
1986         if ((info.basic.flags & DS_ROLE_PRIMARY_DS_RUNNING) &&
1987             !(info.basic.flags & DS_ROLE_PRIMARY_DS_MIXED_MODE)) {
1988                 domain->native_mode = True;
1989         } else {
1990                 domain->native_mode = False;
1991         }
1992
1993 no_dssetup:
1994         status = cli_rpc_pipe_open_noauth(domain->conn.cli,
1995                                           &ndr_table_lsarpc.syntax_id, &cli);
1996
1997         if (!NT_STATUS_IS_OK(status)) {
1998                 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
1999                           "PI_LSARPC on domain %s: (%s)\n",
2000                           domain->name, nt_errstr(status)));
2001                 TALLOC_FREE(cli);
2002                 TALLOC_FREE(mem_ctx);
2003                 return;
2004         }
2005
2006         status = rpccli_lsa_open_policy2(cli, mem_ctx, True,
2007                                          SEC_FLAG_MAXIMUM_ALLOWED, &pol);
2008
2009         if (NT_STATUS_IS_OK(status)) {
2010                 /* This particular query is exactly what Win2k clients use 
2011                    to determine that the DC is active directory */
2012                 status = dcerpc_lsa_QueryInfoPolicy2(cli->binding_handle, mem_ctx,
2013                                                      &pol,
2014                                                      LSA_POLICY_INFO_DNS,
2015                                                      &lsa_info,
2016                                                      &result);
2017         }
2018
2019         if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2020                 domain->active_directory = True;
2021
2022                 if (lsa_info->dns.name.string) {
2023                         fstrcpy(domain->name, lsa_info->dns.name.string);
2024                 }
2025
2026                 if (lsa_info->dns.dns_domain.string) {
2027                         fstrcpy(domain->alt_name,
2028                                 lsa_info->dns.dns_domain.string);
2029                 }
2030
2031                 /* See if we can set some domain trust flags about
2032                    ourself */
2033
2034                 if (lsa_info->dns.dns_forest.string) {
2035                         fstrcpy(domain->forest_name,
2036                                 lsa_info->dns.dns_forest.string);
2037
2038                         if (strequal(domain->forest_name, domain->alt_name)) {
2039                                 domain->domain_flags |= NETR_TRUST_FLAG_TREEROOT;
2040                         }
2041                 }
2042
2043                 if (lsa_info->dns.sid) {
2044                         sid_copy(&domain->sid, lsa_info->dns.sid);
2045                 }
2046         } else {
2047                 domain->active_directory = False;
2048
2049                 status = rpccli_lsa_open_policy(cli, mem_ctx, True,
2050                                                 SEC_FLAG_MAXIMUM_ALLOWED,
2051                                                 &pol);
2052
2053                 if (!NT_STATUS_IS_OK(status)) {
2054                         goto done;
2055                 }
2056
2057                 status = dcerpc_lsa_QueryInfoPolicy(cli->binding_handle, mem_ctx,
2058                                                     &pol,
2059                                                     LSA_POLICY_INFO_ACCOUNT_DOMAIN,
2060                                                     &lsa_info,
2061                                                     &result);
2062                 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2063
2064                         if (lsa_info->account_domain.name.string) {
2065                                 fstrcpy(domain->name,
2066                                         lsa_info->account_domain.name.string);
2067                         }
2068
2069                         if (lsa_info->account_domain.sid) {
2070                                 sid_copy(&domain->sid, lsa_info->account_domain.sid);
2071                         }
2072                 }
2073         }
2074 done:
2075
2076         DEBUG(5, ("set_dc_type_and_flags_connect: domain %s is %sin native mode.\n",
2077                   domain->name, domain->native_mode ? "" : "NOT "));
2078
2079         DEBUG(5,("set_dc_type_and_flags_connect: domain %s is %srunning active directory.\n",
2080                   domain->name, domain->active_directory ? "" : "NOT "));
2081
2082         domain->can_do_ncacn_ip_tcp = domain->active_directory;
2083         domain->can_do_validation6 = domain->active_directory;
2084
2085         TALLOC_FREE(cli);
2086
2087         TALLOC_FREE(mem_ctx);
2088
2089         domain->initialized = True;
2090 }
2091
2092 /**********************************************************************
2093  Set the domain_flags (trust attributes, domain operating modes, etc... 
2094 ***********************************************************************/
2095
2096 static void set_dc_type_and_flags( struct winbindd_domain *domain )
2097 {
2098         /* we always have to contact our primary domain */
2099
2100         if ( domain->primary ) {
2101                 DEBUG(10,("set_dc_type_and_flags: setting up flags for "
2102                           "primary domain\n"));
2103                 set_dc_type_and_flags_connect( domain );
2104                 return;         
2105         }
2106
2107         /* Use our DC to get the information if possible */
2108
2109         if ( !set_dc_type_and_flags_trustinfo( domain ) ) {
2110                 /* Otherwise, fallback to contacting the 
2111                    domain directly */
2112                 set_dc_type_and_flags_connect( domain );
2113         }
2114
2115         return;
2116 }
2117
2118
2119
2120 /**********************************************************************
2121 ***********************************************************************/
2122
2123 static NTSTATUS cm_get_schannel_creds(struct winbindd_domain *domain,
2124                                    struct netlogon_creds_CredentialState **ppdc)
2125 {
2126         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2127         struct rpc_pipe_client *netlogon_pipe;
2128
2129         if (lp_client_schannel() == False) {
2130                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2131         }
2132
2133         result = cm_connect_netlogon(domain, &netlogon_pipe);
2134         if (!NT_STATUS_IS_OK(result)) {
2135                 return result;
2136         }
2137
2138         /* Return a pointer to the struct netlogon_creds_CredentialState from the
2139            netlogon pipe. */
2140
2141         if (!domain->conn.netlogon_pipe->dc) {
2142                 return NT_STATUS_INTERNAL_ERROR; /* This shouldn't happen. */
2143         }
2144
2145         *ppdc = domain->conn.netlogon_pipe->dc;
2146         return NT_STATUS_OK;
2147 }
2148
2149 NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
2150                         struct rpc_pipe_client **cli, struct policy_handle *sam_handle)
2151 {
2152         struct winbindd_cm_conn *conn;
2153         NTSTATUS status, result;
2154         struct netlogon_creds_CredentialState *p_creds;
2155         char *machine_password = NULL;
2156         char *machine_account = NULL;
2157         char *domain_name = NULL;
2158
2159         if (sid_check_is_domain(&domain->sid)) {
2160                 return open_internal_samr_conn(mem_ctx, domain, cli, sam_handle);
2161         }
2162
2163         status = init_dc_connection_rpc(domain);
2164         if (!NT_STATUS_IS_OK(status)) {
2165                 return status;
2166         }
2167
2168         conn = &domain->conn;
2169
2170         if (rpccli_is_connected(conn->samr_pipe)) {
2171                 goto done;
2172         }
2173
2174         TALLOC_FREE(conn->samr_pipe);
2175
2176         /*
2177          * No SAMR pipe yet. Attempt to get an NTLMSSP SPNEGO authenticated
2178          * sign and sealed pipe using the machine account password by
2179          * preference. If we can't - try schannel, if that fails, try
2180          * anonymous.
2181          */
2182
2183         if ((conn->cli->user_name[0] == '\0') ||
2184             (conn->cli->domain[0] == '\0') || 
2185             (conn->cli->password == NULL || conn->cli->password[0] == '\0'))
2186         {
2187                 status = get_trust_creds(domain, &machine_password,
2188                                          &machine_account, NULL);
2189                 if (!NT_STATUS_IS_OK(status)) {
2190                         DEBUG(10, ("cm_connect_sam: No no user available for "
2191                                    "domain %s, trying schannel\n", conn->cli->domain));
2192                         goto schannel;
2193                 }
2194                 domain_name = domain->name;
2195         } else {
2196                 machine_password = SMB_STRDUP(conn->cli->password);
2197                 machine_account = SMB_STRDUP(conn->cli->user_name);
2198                 domain_name = conn->cli->domain;
2199         }
2200
2201         if (!machine_password || !machine_account) {
2202                 status = NT_STATUS_NO_MEMORY;
2203                 goto done;
2204         }
2205
2206         /* We have an authenticated connection. Use a NTLMSSP SPNEGO
2207            authenticated SAMR pipe with sign & seal. */
2208         status = cli_rpc_pipe_open_spnego(conn->cli,
2209                                           &ndr_table_samr,
2210                                           NCACN_NP,
2211                                           GENSEC_OID_NTLMSSP,
2212                                           DCERPC_AUTH_LEVEL_PRIVACY,
2213                                           cli_state_remote_name(conn->cli),
2214                                           domain_name,
2215                                           machine_account,
2216                                           machine_password,
2217                                           &conn->samr_pipe);
2218
2219         if (!NT_STATUS_IS_OK(status)) {
2220                 DEBUG(10,("cm_connect_sam: failed to connect to SAMR "
2221                           "pipe for domain %s using NTLMSSP "
2222                           "authenticated pipe: user %s\\%s. Error was "
2223                           "%s\n", domain->name, domain_name,
2224                           machine_account, nt_errstr(status)));
2225                 goto schannel;
2226         }
2227
2228         DEBUG(10,("cm_connect_sam: connected to SAMR pipe for "
2229                   "domain %s using NTLMSSP authenticated "
2230                   "pipe: user %s\\%s\n", domain->name,
2231                   domain_name, machine_account));
2232
2233         status = dcerpc_samr_Connect2(conn->samr_pipe->binding_handle, mem_ctx,
2234                                       conn->samr_pipe->desthost,
2235                                       SEC_FLAG_MAXIMUM_ALLOWED,
2236                                       &conn->sam_connect_handle,
2237                                       &result);
2238         if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2239                 goto open_domain;
2240         }
2241         if (NT_STATUS_IS_OK(status)) {
2242                 status = result;
2243         }
2244
2245         DEBUG(10,("cm_connect_sam: ntlmssp-sealed dcerpc_samr_Connect2 "
2246                   "failed for domain %s, error was %s. Trying schannel\n",
2247                   domain->name, nt_errstr(status) ));
2248         TALLOC_FREE(conn->samr_pipe);
2249
2250  schannel:
2251
2252         /* Fall back to schannel if it's a W2K pre-SP1 box. */
2253
2254         status = cm_get_schannel_creds(domain, &p_creds);
2255         if (!NT_STATUS_IS_OK(status)) {
2256                 /* If this call fails - conn->cli can now be NULL ! */
2257                 DEBUG(10, ("cm_connect_sam: Could not get schannel auth info "
2258                            "for domain %s (error %s), trying anon\n",
2259                         domain->name,
2260                         nt_errstr(status) ));
2261                 goto anonymous;
2262         }
2263         status = cli_rpc_pipe_open_schannel_with_key
2264                 (conn->cli, &ndr_table_samr.syntax_id, NCACN_NP,
2265                  DCERPC_AUTH_LEVEL_PRIVACY,
2266                  domain->name, &p_creds, &conn->samr_pipe);
2267
2268         if (!NT_STATUS_IS_OK(status)) {
2269                 DEBUG(10,("cm_connect_sam: failed to connect to SAMR pipe for "
2270                           "domain %s using schannel. Error was %s\n",
2271                           domain->name, nt_errstr(status) ));
2272                 goto anonymous;
2273         }
2274         DEBUG(10,("cm_connect_sam: connected to SAMR pipe for domain %s using "
2275                   "schannel.\n", domain->name ));
2276
2277         status = dcerpc_samr_Connect2(conn->samr_pipe->binding_handle, mem_ctx,
2278                                       conn->samr_pipe->desthost,
2279                                       SEC_FLAG_MAXIMUM_ALLOWED,
2280                                       &conn->sam_connect_handle,
2281                                       &result);
2282         if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2283                 goto open_domain;
2284         }
2285         if (NT_STATUS_IS_OK(status)) {
2286                 status = result;
2287         }
2288         DEBUG(10,("cm_connect_sam: schannel-sealed dcerpc_samr_Connect2 failed "
2289                   "for domain %s, error was %s. Trying anonymous\n",
2290                   domain->name, nt_errstr(status) ));
2291         TALLOC_FREE(conn->samr_pipe);
2292
2293  anonymous:
2294
2295         /* Finally fall back to anonymous. */
2296         status = cli_rpc_pipe_open_noauth(conn->cli, &ndr_table_samr.syntax_id,
2297                                           &conn->samr_pipe);
2298
2299         if (!NT_STATUS_IS_OK(status)) {
2300                 goto done;
2301         }
2302
2303         status = dcerpc_samr_Connect2(conn->samr_pipe->binding_handle, mem_ctx,
2304                                       conn->samr_pipe->desthost,
2305                                       SEC_FLAG_MAXIMUM_ALLOWED,
2306                                       &conn->sam_connect_handle,
2307                                       &result);
2308         if (!NT_STATUS_IS_OK(status)) {
2309                 DEBUG(10,("cm_connect_sam: rpccli_samr_Connect2 failed "
2310                           "for domain %s Error was %s\n",
2311                           domain->name, nt_errstr(status) ));
2312                 goto done;
2313         }
2314         if (!NT_STATUS_IS_OK(result)) {
2315                 status = result;
2316                 DEBUG(10,("cm_connect_sam: dcerpc_samr_Connect2 failed "
2317                           "for domain %s Error was %s\n",
2318                           domain->name, nt_errstr(result)));
2319                 goto done;
2320         }
2321
2322  open_domain:
2323         status = dcerpc_samr_OpenDomain(conn->samr_pipe->binding_handle,
2324                                         mem_ctx,
2325                                         &conn->sam_connect_handle,
2326                                         SEC_FLAG_MAXIMUM_ALLOWED,
2327                                         &domain->sid,
2328                                         &conn->sam_domain_handle,
2329                                         &result);
2330         if (!NT_STATUS_IS_OK(status)) {
2331                 goto done;
2332         }
2333
2334         status = result;
2335  done:
2336
2337         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2338                 /*
2339                  * if we got access denied, we might just have no access rights
2340                  * to talk to the remote samr server server (e.g. when we are a
2341                  * PDC and we are connecting a w2k8 pdc via an interdomain
2342                  * trust). In that case do not invalidate the whole connection
2343                  * stack
2344                  */
2345                 TALLOC_FREE(conn->samr_pipe);
2346                 ZERO_STRUCT(conn->sam_domain_handle);
2347                 return status;
2348         } else if (!NT_STATUS_IS_OK(status)) {
2349                 invalidate_cm_connection(conn);
2350                 return status;
2351         }
2352
2353         *cli = conn->samr_pipe;
2354         *sam_handle = conn->sam_domain_handle;
2355         SAFE_FREE(machine_password);
2356         SAFE_FREE(machine_account);
2357         return status;
2358 }
2359
2360 /**********************************************************************
2361  open an schanneld ncacn_ip_tcp connection to LSA
2362 ***********************************************************************/
2363
2364 NTSTATUS cm_connect_lsa_tcp(struct winbindd_domain *domain,
2365                             TALLOC_CTX *mem_ctx,
2366                             struct rpc_pipe_client **cli)
2367 {
2368         struct winbindd_cm_conn *conn;
2369         struct netlogon_creds_CredentialState *creds;
2370         NTSTATUS status;
2371
2372         DEBUG(10,("cm_connect_lsa_tcp\n"));
2373
2374         status = init_dc_connection_rpc(domain);
2375         if (!NT_STATUS_IS_OK(status)) {
2376                 return status;
2377         }
2378
2379         conn = &domain->conn;
2380
2381         if (conn->lsa_pipe_tcp &&
2382             conn->lsa_pipe_tcp->transport->transport == NCACN_IP_TCP &&
2383             conn->lsa_pipe_tcp->auth->auth_level == DCERPC_AUTH_LEVEL_PRIVACY &&
2384             rpccli_is_connected(conn->lsa_pipe_tcp)) {
2385                 goto done;
2386         }
2387
2388         TALLOC_FREE(conn->lsa_pipe_tcp);
2389
2390         status = cm_get_schannel_creds(domain, &creds);
2391         if (!NT_STATUS_IS_OK(status)) {
2392                 goto done;
2393         }
2394
2395         status = cli_rpc_pipe_open_schannel_with_key(conn->cli,
2396                                                      &ndr_table_lsarpc.syntax_id,
2397                                                      NCACN_IP_TCP,
2398                                                      DCERPC_AUTH_LEVEL_PRIVACY,
2399                                                      domain->name,
2400                                                      &creds,
2401                                                      &conn->lsa_pipe_tcp);
2402         if (!NT_STATUS_IS_OK(status)) {
2403                 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key failed: %s\n",
2404                         nt_errstr(status)));
2405                 goto done;
2406         }
2407
2408  done:
2409         if (!NT_STATUS_IS_OK(status)) {
2410                 TALLOC_FREE(conn->lsa_pipe_tcp);
2411                 return status;
2412         }
2413
2414         *cli = conn->lsa_pipe_tcp;
2415
2416         return status;
2417 }
2418
2419 NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
2420                         struct rpc_pipe_client **cli, struct policy_handle *lsa_policy)
2421 {
2422         struct winbindd_cm_conn *conn;
2423         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2424         struct netlogon_creds_CredentialState *p_creds;
2425
2426         result = init_dc_connection_rpc(domain);
2427         if (!NT_STATUS_IS_OK(result))
2428                 return result;
2429
2430         conn = &domain->conn;
2431
2432         if (rpccli_is_connected(conn->lsa_pipe)) {
2433                 goto done;
2434         }
2435
2436         TALLOC_FREE(conn->lsa_pipe);
2437
2438         if ((conn->cli->user_name[0] == '\0') ||
2439             (conn->cli->domain[0] == '\0') || 
2440             (conn->cli->password == NULL || conn->cli->password[0] == '\0')) {
2441                 DEBUG(10, ("cm_connect_lsa: No no user available for "
2442                            "domain %s, trying schannel\n", conn->cli->domain));
2443                 goto schannel;
2444         }
2445
2446         /* We have an authenticated connection. Use a NTLMSSP SPNEGO
2447          * authenticated LSA pipe with sign & seal. */
2448         result = cli_rpc_pipe_open_spnego
2449                 (conn->cli, &ndr_table_lsarpc, NCACN_NP,
2450                  GENSEC_OID_NTLMSSP,
2451                  DCERPC_AUTH_LEVEL_PRIVACY,
2452                  cli_state_remote_name(conn->cli),
2453                  conn->cli->domain, conn->cli->user_name, conn->cli->password,
2454                  &conn->lsa_pipe);
2455
2456         if (!NT_STATUS_IS_OK(result)) {
2457                 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
2458                           "domain %s using NTLMSSP authenticated pipe: user "
2459                           "%s\\%s. Error was %s. Trying schannel.\n",
2460                           domain->name, conn->cli->domain,
2461                           conn->cli->user_name, nt_errstr(result)));
2462                 goto schannel;
2463         }
2464
2465         DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
2466                   "NTLMSSP authenticated pipe: user %s\\%s\n",
2467                   domain->name, conn->cli->domain, conn->cli->user_name ));
2468
2469         result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2470                                         SEC_FLAG_MAXIMUM_ALLOWED,
2471                                         &conn->lsa_policy);
2472         if (NT_STATUS_IS_OK(result)) {
2473                 goto done;
2474         }
2475
2476         DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
2477                   "schannel\n"));
2478
2479         TALLOC_FREE(conn->lsa_pipe);
2480
2481  schannel:
2482
2483         /* Fall back to schannel if it's a W2K pre-SP1 box. */
2484
2485         result = cm_get_schannel_creds(domain, &p_creds);
2486         if (!NT_STATUS_IS_OK(result)) {
2487                 /* If this call fails - conn->cli can now be NULL ! */
2488                 DEBUG(10, ("cm_connect_lsa: Could not get schannel auth info "
2489                            "for domain %s (error %s), trying anon\n",
2490                         domain->name,
2491                         nt_errstr(result) ));
2492                 goto anonymous;
2493         }
2494         result = cli_rpc_pipe_open_schannel_with_key
2495                 (conn->cli, &ndr_table_lsarpc.syntax_id, NCACN_NP,
2496                  DCERPC_AUTH_LEVEL_PRIVACY,
2497                  domain->name, &p_creds, &conn->lsa_pipe);
2498
2499         if (!NT_STATUS_IS_OK(result)) {
2500                 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
2501                           "domain %s using schannel. Error was %s\n",
2502                           domain->name, nt_errstr(result) ));
2503                 goto anonymous;
2504         }
2505         DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
2506                   "schannel.\n", domain->name ));
2507
2508         result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2509                                         SEC_FLAG_MAXIMUM_ALLOWED,
2510                                         &conn->lsa_policy);
2511         if (NT_STATUS_IS_OK(result)) {
2512                 goto done;
2513         }
2514
2515         DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
2516                   "anonymous\n"));
2517
2518         TALLOC_FREE(conn->lsa_pipe);
2519
2520  anonymous:
2521
2522         result = cli_rpc_pipe_open_noauth(conn->cli,
2523                                           &ndr_table_lsarpc.syntax_id,
2524                                           &conn->lsa_pipe);
2525         if (!NT_STATUS_IS_OK(result)) {
2526                 result = NT_STATUS_PIPE_NOT_AVAILABLE;
2527                 goto done;
2528         }
2529
2530         result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2531                                         SEC_FLAG_MAXIMUM_ALLOWED,
2532                                         &conn->lsa_policy);
2533  done:
2534         if (!NT_STATUS_IS_OK(result)) {
2535                 invalidate_cm_connection(conn);
2536                 return result;
2537         }
2538
2539         *cli = conn->lsa_pipe;
2540         *lsa_policy = conn->lsa_policy;
2541         return result;
2542 }
2543
2544 /****************************************************************************
2545  Open the netlogon pipe to this DC. Use schannel if specified in client conf.
2546  session key stored in conn->netlogon_pipe->dc->sess_key.
2547 ****************************************************************************/
2548
2549 NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
2550                              struct rpc_pipe_client **cli)
2551 {
2552         struct winbindd_cm_conn *conn;
2553         NTSTATUS result;
2554
2555         uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
2556         uint8  mach_pwd[16];
2557         enum netr_SchannelType sec_chan_type;
2558         const char *account_name;
2559         struct rpc_pipe_client *netlogon_pipe = NULL;
2560
2561         *cli = NULL;
2562
2563         result = init_dc_connection_rpc(domain);
2564         if (!NT_STATUS_IS_OK(result)) {
2565                 return result;
2566         }
2567
2568         conn = &domain->conn;
2569
2570         if (rpccli_is_connected(conn->netlogon_pipe)) {
2571                 *cli = conn->netlogon_pipe;
2572                 return NT_STATUS_OK;
2573         }
2574
2575         TALLOC_FREE(conn->netlogon_pipe);
2576
2577         result = cli_rpc_pipe_open_noauth(conn->cli,
2578                                           &ndr_table_netlogon.syntax_id,
2579                                           &netlogon_pipe);
2580         if (!NT_STATUS_IS_OK(result)) {
2581                 return result;
2582         }
2583
2584         if ((!IS_DC) && (!domain->primary)) {
2585                 /* Clear the schannel request bit and drop down */
2586                 neg_flags &= ~NETLOGON_NEG_SCHANNEL;            
2587                 goto no_schannel;
2588         }
2589
2590         if (lp_client_schannel() != False) {
2591                 neg_flags |= NETLOGON_NEG_SCHANNEL;
2592         }
2593
2594         if (!get_trust_pw_hash(domain->name, mach_pwd, &account_name,
2595                                &sec_chan_type))
2596         {
2597                 TALLOC_FREE(netlogon_pipe);
2598                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2599         }
2600
2601         result = rpccli_netlogon_setup_creds(
2602                  netlogon_pipe,
2603                  domain->dcname, /* server name. */
2604                  domain->name,   /* domain name */
2605                  lp_netbios_name(), /* client name */
2606                  account_name,   /* machine account */
2607                  mach_pwd,       /* machine password */
2608                  sec_chan_type,  /* from get_trust_pw */
2609                  &neg_flags);
2610
2611         if (!NT_STATUS_IS_OK(result)) {
2612                 TALLOC_FREE(netlogon_pipe);
2613                 return result;
2614         }
2615
2616         if ((lp_client_schannel() == True) &&
2617                         ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
2618                 DEBUG(3, ("Server did not offer schannel\n"));
2619                 TALLOC_FREE(netlogon_pipe);
2620                 return NT_STATUS_ACCESS_DENIED;
2621         }
2622
2623  no_schannel:
2624         if ((lp_client_schannel() == False) ||
2625                         ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
2626                 /*
2627                  * NetSamLogonEx only works for schannel
2628                  */
2629                 domain->can_do_samlogon_ex = False;
2630
2631                 /* We're done - just keep the existing connection to NETLOGON
2632                  * open */
2633                 conn->netlogon_pipe = netlogon_pipe;
2634                 *cli = conn->netlogon_pipe;
2635                 return NT_STATUS_OK;
2636         }
2637
2638         /* Using the credentials from the first pipe, open a signed and sealed
2639            second netlogon pipe. The session key is stored in the schannel
2640            part of the new pipe auth struct.
2641         */
2642
2643         result = cli_rpc_pipe_open_schannel_with_key(
2644                 conn->cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
2645                 DCERPC_AUTH_LEVEL_PRIVACY, domain->name, &netlogon_pipe->dc,
2646                 &conn->netlogon_pipe);
2647
2648         /* We can now close the initial netlogon pipe. */
2649         TALLOC_FREE(netlogon_pipe);
2650
2651         if (!NT_STATUS_IS_OK(result)) {
2652                 DEBUG(3, ("Could not open schannel'ed NETLOGON pipe. Error "
2653                           "was %s\n", nt_errstr(result)));
2654
2655                 invalidate_cm_connection(conn);
2656                 return result;
2657         }
2658
2659         /*
2660          * Always try netr_LogonSamLogonEx. We will fall back for NT4
2661          * which gives DCERPC_FAULT_OP_RNG_ERROR (function not
2662          * supported). We used to only try SamLogonEx for AD, but
2663          * Samba DCs can also do it. And because we don't distinguish
2664          * between Samba and NT4, always try it once.
2665          */
2666         domain->can_do_samlogon_ex = true;
2667
2668         *cli = conn->netlogon_pipe;
2669         return NT_STATUS_OK;
2670 }
2671
2672 void winbind_msg_ip_dropped(struct messaging_context *msg_ctx,
2673                             void *private_data,
2674                             uint32_t msg_type,
2675                             struct server_id server_id,
2676                             DATA_BLOB *data)
2677 {
2678         struct winbindd_domain *domain;
2679         char *freeit = NULL;
2680         char *addr;
2681
2682         if ((data == NULL)
2683             || (data->data == NULL)
2684             || (data->length == 0)
2685             || (data->data[data->length-1] != '\0')) {
2686                 DEBUG(1, ("invalid msg_ip_dropped message: not a valid "
2687                           "string\n"));
2688                 return;
2689         }
2690
2691         addr = (char *)data->data;
2692         DEBUG(10, ("IP %s dropped\n", addr));
2693
2694         if (!is_ipaddress(addr)) {
2695                 char *slash;
2696                 /*
2697                  * Some code sends us ip addresses with the /netmask
2698                  * suffix
2699                  */
2700                 slash = strchr(addr, '/');
2701                 if (slash == NULL) {
2702                         DEBUG(1, ("invalid msg_ip_dropped message: %s",
2703                                   addr));
2704                         return;
2705                 }
2706                 freeit = talloc_strndup(talloc_tos(), addr, slash-addr);
2707                 if (freeit == NULL) {
2708                         DEBUG(1, ("talloc failed\n"));
2709                         return;
2710                 }
2711                 addr = freeit;
2712                 DEBUG(10, ("Stripped /netmask to IP %s\n", addr));
2713         }
2714
2715         for (domain = domain_list(); domain != NULL; domain = domain->next) {
2716                 char sockaddr[INET6_ADDRSTRLEN];
2717
2718                 if (!cli_state_is_connected(domain->conn.cli)) {
2719                         continue;
2720                 }
2721
2722                 print_sockaddr(sockaddr, sizeof(sockaddr),
2723                                cli_state_local_sockaddr(domain->conn.cli));
2724
2725                 if (strequal(sockaddr, addr)) {
2726                         cli_state_disconnect(domain->conn.cli);
2727                 }
2728         }
2729         TALLOC_FREE(freeit);
2730 }