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