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