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