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