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