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