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