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