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