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