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