a63c3f553ea568e1dff85992fb44232b7e3f220e
[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 (!winbindd_can_contact_domain(domain)) {
1627                 invalidate_cm_connection(&domain->conn);
1628                 domain->initialized = True;
1629                 return NT_STATUS_OK;
1630         }
1631
1632         if (connection_ok(domain)) {
1633                 if (!domain->initialized) {
1634                         set_dc_type_and_flags(domain);
1635                 }
1636                 return NT_STATUS_OK;
1637         }
1638
1639         invalidate_cm_connection(&domain->conn);
1640
1641         result = cm_open_connection(domain, &domain->conn);
1642
1643         if (NT_STATUS_IS_OK(result) && !domain->initialized) {
1644                 set_dc_type_and_flags(domain);
1645         }
1646
1647         return result;
1648 }
1649
1650 NTSTATUS init_dc_connection(struct winbindd_domain *domain)
1651 {
1652         if (domain->initialized && !domain->online) {
1653                 /* We check for online status elsewhere. */
1654                 return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1655         }
1656
1657         return init_dc_connection_network(domain);
1658 }
1659
1660 static NTSTATUS init_dc_connection_rpc(struct winbindd_domain *domain)
1661 {
1662         NTSTATUS status;
1663
1664         status = init_dc_connection(domain);
1665         if (!NT_STATUS_IS_OK(status)) {
1666                 return status;
1667         }
1668
1669         if (!domain->internal && domain->conn.cli == NULL) {
1670                 /* happens for trusted domains without inbound trust */
1671                 return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
1672         }
1673
1674         return NT_STATUS_OK;
1675 }
1676
1677 /******************************************************************************
1678  Set the trust flags (direction and forest location) for a domain
1679 ******************************************************************************/
1680
1681 static bool set_dc_type_and_flags_trustinfo( struct winbindd_domain *domain )
1682 {
1683         struct winbindd_domain *our_domain;
1684         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1685         struct netr_DomainTrustList trusts;
1686         int i;
1687         uint32 flags = (NETR_TRUST_FLAG_IN_FOREST |
1688                         NETR_TRUST_FLAG_OUTBOUND |
1689                         NETR_TRUST_FLAG_INBOUND);
1690         struct rpc_pipe_client *cli;
1691         TALLOC_CTX *mem_ctx = NULL;
1692
1693         DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s\n", domain->name ));
1694
1695         /* Our primary domain doesn't need to worry about trust flags.
1696            Force it to go through the network setup */
1697         if ( domain->primary ) {                
1698                 return False;           
1699         }
1700
1701         our_domain = find_our_domain();
1702
1703         if ( !connection_ok(our_domain) ) {
1704                 DEBUG(3,("set_dc_type_and_flags_trustinfo: No connection to our domain!\n"));           
1705                 return False;
1706         }
1707
1708         /* This won't work unless our domain is AD */
1709
1710         if ( !our_domain->active_directory ) {
1711                 return False;
1712         }
1713
1714         /* Use DsEnumerateDomainTrusts to get us the trust direction
1715            and type */
1716
1717         result = cm_connect_netlogon(our_domain, &cli);
1718
1719         if (!NT_STATUS_IS_OK(result)) {
1720                 DEBUG(5, ("set_dc_type_and_flags_trustinfo: Could not open "
1721                           "a connection to %s for PIPE_NETLOGON (%s)\n", 
1722                           domain->name, nt_errstr(result)));
1723                 return False;
1724         }
1725
1726         if ( (mem_ctx = talloc_init("set_dc_type_and_flags_trustinfo")) == NULL ) {
1727                 DEBUG(0,("set_dc_type_and_flags_trustinfo: talloc_init() failed!\n"));
1728                 return False;
1729         }       
1730
1731         result = rpccli_netr_DsrEnumerateDomainTrusts(cli, mem_ctx,
1732                                                       cli->desthost,
1733                                                       flags,
1734                                                       &trusts,
1735                                                       NULL);
1736         if (!NT_STATUS_IS_OK(result)) {
1737                 DEBUG(0,("set_dc_type_and_flags_trustinfo: "
1738                         "failed to query trusted domain list: %s\n",
1739                         nt_errstr(result)));
1740                 talloc_destroy(mem_ctx);
1741                 return false;
1742         }
1743
1744         /* Now find the domain name and get the flags */
1745
1746         for ( i=0; i<trusts.count; i++ ) {
1747                 if ( strequal( domain->name, trusts.array[i].netbios_name) ) {
1748                         domain->domain_flags          = trusts.array[i].trust_flags;
1749                         domain->domain_type           = trusts.array[i].trust_type;
1750                         domain->domain_trust_attribs  = trusts.array[i].trust_attributes;
1751
1752                         if ( domain->domain_type == NETR_TRUST_TYPE_UPLEVEL )
1753                                 domain->active_directory = True;
1754
1755                         /* This flag is only set if the domain is *our* 
1756                            primary domain and the primary domain is in
1757                            native mode */
1758
1759                         domain->native_mode = (domain->domain_flags & NETR_TRUST_FLAG_NATIVE);
1760
1761                         DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s is %sin "
1762                                   "native mode.\n", domain->name, 
1763                                   domain->native_mode ? "" : "NOT "));
1764
1765                         DEBUG(5,("set_dc_type_and_flags_trustinfo: domain %s is %s"
1766                                  "running active directory.\n", domain->name, 
1767                                  domain->active_directory ? "" : "NOT "));
1768
1769                         domain->can_do_ncacn_ip_tcp = domain->active_directory;
1770                         domain->can_do_validation6 = domain->active_directory;
1771
1772                         domain->initialized = True;
1773
1774                         break;
1775                 }               
1776         }
1777
1778         talloc_destroy( mem_ctx );
1779
1780         return domain->initialized;     
1781 }
1782
1783 /******************************************************************************
1784  We can 'sense' certain things about the DC by it's replies to certain
1785  questions.
1786
1787  This tells us if this particular remote server is Active Directory, and if it
1788  is native mode.
1789 ******************************************************************************/
1790
1791 static void set_dc_type_and_flags_connect( struct winbindd_domain *domain )
1792 {
1793         NTSTATUS                result;
1794         WERROR werr;
1795         TALLOC_CTX              *mem_ctx = NULL;
1796         struct rpc_pipe_client  *cli = NULL;
1797         struct policy_handle pol;
1798         union dssetup_DsRoleInfo info;
1799         union lsa_PolicyInformation *lsa_info = NULL;
1800
1801         if (!connection_ok(domain)) {
1802                 return;
1803         }
1804
1805         mem_ctx = talloc_init("set_dc_type_and_flags on domain %s\n",
1806                               domain->name);
1807         if (!mem_ctx) {
1808                 DEBUG(1, ("set_dc_type_and_flags_connect: talloc_init() failed\n"));
1809                 return;
1810         }
1811
1812         DEBUG(5, ("set_dc_type_and_flags_connect: domain %s\n", domain->name ));
1813
1814         result = cli_rpc_pipe_open_noauth(domain->conn.cli,
1815                                           &ndr_table_dssetup.syntax_id,
1816                                           &cli);
1817
1818         if (!NT_STATUS_IS_OK(result)) {
1819                 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
1820                           "PI_DSSETUP on domain %s: (%s)\n",
1821                           domain->name, nt_errstr(result)));
1822
1823                 /* if this is just a non-AD domain we need to continue
1824                  * identifying so that we can in the end return with
1825                  * domain->initialized = True - gd */
1826
1827                 goto no_dssetup;
1828         }
1829
1830         result = rpccli_dssetup_DsRoleGetPrimaryDomainInformation(cli, mem_ctx,
1831                                                                   DS_ROLE_BASIC_INFORMATION,
1832                                                                   &info,
1833                                                                   &werr);
1834         TALLOC_FREE(cli);
1835
1836         if (!NT_STATUS_IS_OK(result)) {
1837                 DEBUG(5, ("set_dc_type_and_flags_connect: rpccli_ds_getprimarydominfo "
1838                           "on domain %s failed: (%s)\n",
1839                           domain->name, nt_errstr(result)));
1840
1841                 /* older samba3 DCs will return DCERPC_FAULT_OP_RNG_ERROR for
1842                  * every opcode on the DSSETUP pipe, continue with
1843                  * no_dssetup mode here as well to get domain->initialized
1844                  * set - gd */
1845
1846                 if (NT_STATUS_V(result) == DCERPC_FAULT_OP_RNG_ERROR) {
1847                         goto no_dssetup;
1848                 }
1849
1850                 TALLOC_FREE(mem_ctx);
1851                 return;
1852         }
1853
1854         if ((info.basic.flags & DS_ROLE_PRIMARY_DS_RUNNING) &&
1855             !(info.basic.flags & DS_ROLE_PRIMARY_DS_MIXED_MODE)) {
1856                 domain->native_mode = True;
1857         } else {
1858                 domain->native_mode = False;
1859         }
1860
1861 no_dssetup:
1862         result = cli_rpc_pipe_open_noauth(domain->conn.cli,
1863                                           &ndr_table_lsarpc.syntax_id, &cli);
1864
1865         if (!NT_STATUS_IS_OK(result)) {
1866                 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
1867                           "PI_LSARPC on domain %s: (%s)\n",
1868                           domain->name, nt_errstr(result)));
1869                 TALLOC_FREE(cli);
1870                 TALLOC_FREE(mem_ctx);
1871                 return;
1872         }
1873
1874         result = rpccli_lsa_open_policy2(cli, mem_ctx, True, 
1875                                          SEC_FLAG_MAXIMUM_ALLOWED, &pol);
1876
1877         if (NT_STATUS_IS_OK(result)) {
1878                 /* This particular query is exactly what Win2k clients use 
1879                    to determine that the DC is active directory */
1880                 result = rpccli_lsa_QueryInfoPolicy2(cli, mem_ctx,
1881                                                      &pol,
1882                                                      LSA_POLICY_INFO_DNS,
1883                                                      &lsa_info);
1884         }
1885
1886         if (NT_STATUS_IS_OK(result)) {
1887                 domain->active_directory = True;
1888
1889                 if (lsa_info->dns.name.string) {
1890                         fstrcpy(domain->name, lsa_info->dns.name.string);
1891                 }
1892
1893                 if (lsa_info->dns.dns_domain.string) {
1894                         fstrcpy(domain->alt_name,
1895                                 lsa_info->dns.dns_domain.string);
1896                 }
1897
1898                 /* See if we can set some domain trust flags about
1899                    ourself */
1900
1901                 if (lsa_info->dns.dns_forest.string) {
1902                         fstrcpy(domain->forest_name,
1903                                 lsa_info->dns.dns_forest.string);
1904
1905                         if (strequal(domain->forest_name, domain->alt_name)) {
1906                                 domain->domain_flags |= NETR_TRUST_FLAG_TREEROOT;
1907                         }
1908                 }
1909
1910                 if (lsa_info->dns.sid) {
1911                         sid_copy(&domain->sid, lsa_info->dns.sid);
1912                 }
1913         } else {
1914                 domain->active_directory = False;
1915
1916                 result = rpccli_lsa_open_policy(cli, mem_ctx, True, 
1917                                                 SEC_FLAG_MAXIMUM_ALLOWED,
1918                                                 &pol);
1919
1920                 if (!NT_STATUS_IS_OK(result)) {
1921                         goto done;
1922                 }
1923
1924                 result = rpccli_lsa_QueryInfoPolicy(cli, mem_ctx,
1925                                                     &pol,
1926                                                     LSA_POLICY_INFO_ACCOUNT_DOMAIN,
1927                                                     &lsa_info);
1928
1929                 if (NT_STATUS_IS_OK(result)) {
1930
1931                         if (lsa_info->account_domain.name.string) {
1932                                 fstrcpy(domain->name,
1933                                         lsa_info->account_domain.name.string);
1934                         }
1935
1936                         if (lsa_info->account_domain.sid) {
1937                                 sid_copy(&domain->sid, lsa_info->account_domain.sid);
1938                         }
1939                 }
1940         }
1941 done:
1942
1943         DEBUG(5, ("set_dc_type_and_flags_connect: domain %s is %sin native mode.\n",
1944                   domain->name, domain->native_mode ? "" : "NOT "));
1945
1946         DEBUG(5,("set_dc_type_and_flags_connect: domain %s is %srunning active directory.\n",
1947                   domain->name, domain->active_directory ? "" : "NOT "));
1948
1949         domain->can_do_ncacn_ip_tcp = domain->active_directory;
1950         domain->can_do_validation6 = domain->active_directory;
1951
1952         TALLOC_FREE(cli);
1953
1954         TALLOC_FREE(mem_ctx);
1955
1956         domain->initialized = True;
1957 }
1958
1959 /**********************************************************************
1960  Set the domain_flags (trust attributes, domain operating modes, etc... 
1961 ***********************************************************************/
1962
1963 static void set_dc_type_and_flags( struct winbindd_domain *domain )
1964 {
1965         /* we always have to contact our primary domain */
1966
1967         if ( domain->primary ) {
1968                 DEBUG(10,("set_dc_type_and_flags: setting up flags for "
1969                           "primary domain\n"));
1970                 set_dc_type_and_flags_connect( domain );
1971                 return;         
1972         }
1973
1974         /* Use our DC to get the information if possible */
1975
1976         if ( !set_dc_type_and_flags_trustinfo( domain ) ) {
1977                 /* Otherwise, fallback to contacting the 
1978                    domain directly */
1979                 set_dc_type_and_flags_connect( domain );
1980         }
1981
1982         return;
1983 }
1984
1985
1986
1987 /**********************************************************************
1988 ***********************************************************************/
1989
1990 static NTSTATUS cm_get_schannel_creds(struct winbindd_domain *domain,
1991                                    struct netlogon_creds_CredentialState **ppdc)
1992 {
1993         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1994         struct rpc_pipe_client *netlogon_pipe;
1995
1996         if (lp_client_schannel() == False) {
1997                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;;
1998         }
1999
2000         result = cm_connect_netlogon(domain, &netlogon_pipe);
2001         if (!NT_STATUS_IS_OK(result)) {
2002                 return result;
2003         }
2004
2005         /* Return a pointer to the struct netlogon_creds_CredentialState from the
2006            netlogon pipe. */
2007
2008         if (!domain->conn.netlogon_pipe->dc) {
2009                 return NT_STATUS_INTERNAL_ERROR; /* This shouldn't happen. */
2010         }
2011
2012         *ppdc = domain->conn.netlogon_pipe->dc;
2013         return NT_STATUS_OK;
2014 }
2015
2016 NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
2017                         struct rpc_pipe_client **cli, struct policy_handle *sam_handle)
2018 {
2019         struct winbindd_cm_conn *conn;
2020         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2021         struct netlogon_creds_CredentialState *p_creds;
2022         char *machine_password = NULL;
2023         char *machine_account = NULL;
2024         char *domain_name = NULL;
2025
2026         result = init_dc_connection_rpc(domain);
2027         if (!NT_STATUS_IS_OK(result)) {
2028                 return result;
2029         }
2030
2031         conn = &domain->conn;
2032
2033         if (rpccli_is_connected(conn->samr_pipe)) {
2034                 goto done;
2035         }
2036
2037         TALLOC_FREE(conn->samr_pipe);
2038
2039         /*
2040          * No SAMR pipe yet. Attempt to get an NTLMSSP SPNEGO authenticated
2041          * sign and sealed pipe using the machine account password by
2042          * preference. If we can't - try schannel, if that fails, try
2043          * anonymous.
2044          */
2045
2046         if ((conn->cli->user_name[0] == '\0') ||
2047             (conn->cli->domain[0] == '\0') || 
2048             (conn->cli->password == NULL || conn->cli->password[0] == '\0'))
2049         {
2050                 result = get_trust_creds(domain, &machine_password,
2051                                          &machine_account, NULL);
2052                 if (!NT_STATUS_IS_OK(result)) {
2053                         DEBUG(10, ("cm_connect_sam: No no user available for "
2054                                    "domain %s, trying schannel\n", conn->cli->domain));
2055                         goto schannel;
2056                 }
2057                 domain_name = domain->name;
2058         } else {
2059                 machine_password = SMB_STRDUP(conn->cli->password);
2060                 machine_account = SMB_STRDUP(conn->cli->user_name);
2061                 domain_name = conn->cli->domain;
2062         }
2063
2064         if (!machine_password || !machine_account) {
2065                 result = NT_STATUS_NO_MEMORY;
2066                 goto done;
2067         }
2068
2069         /* We have an authenticated connection. Use a NTLMSSP SPNEGO
2070            authenticated SAMR pipe with sign & seal. */
2071         result = cli_rpc_pipe_open_spnego_ntlmssp(conn->cli,
2072                                                   &ndr_table_samr.syntax_id,
2073                                                   NCACN_NP,
2074                                                   DCERPC_AUTH_LEVEL_PRIVACY,
2075                                                   domain_name,
2076                                                   machine_account,
2077                                                   machine_password,
2078                                                   &conn->samr_pipe);
2079
2080         if (!NT_STATUS_IS_OK(result)) {
2081                 DEBUG(10,("cm_connect_sam: failed to connect to SAMR "
2082                           "pipe for domain %s using NTLMSSP "
2083                           "authenticated pipe: user %s\\%s. Error was "
2084                           "%s\n", domain->name, domain_name,
2085                           machine_account, nt_errstr(result)));
2086                 goto schannel;
2087         }
2088
2089         DEBUG(10,("cm_connect_sam: connected to SAMR pipe for "
2090                   "domain %s using NTLMSSP authenticated "
2091                   "pipe: user %s\\%s\n", domain->name,
2092                   domain_name, machine_account));
2093
2094         result = rpccli_samr_Connect2(conn->samr_pipe, mem_ctx,
2095                                       conn->samr_pipe->desthost,
2096                                       SEC_FLAG_MAXIMUM_ALLOWED,
2097                                       &conn->sam_connect_handle);
2098         if (NT_STATUS_IS_OK(result)) {
2099                 goto open_domain;
2100         }
2101         DEBUG(10,("cm_connect_sam: ntlmssp-sealed rpccli_samr_Connect2 "
2102                   "failed for domain %s, error was %s. Trying schannel\n",
2103                   domain->name, nt_errstr(result) ));
2104         TALLOC_FREE(conn->samr_pipe);
2105
2106  schannel:
2107
2108         /* Fall back to schannel if it's a W2K pre-SP1 box. */
2109
2110         result = cm_get_schannel_creds(domain, &p_creds);
2111         if (!NT_STATUS_IS_OK(result)) {
2112                 /* If this call fails - conn->cli can now be NULL ! */
2113                 DEBUG(10, ("cm_connect_sam: Could not get schannel auth info "
2114                            "for domain %s (error %s), trying anon\n",
2115                         domain->name,
2116                         nt_errstr(result) ));
2117                 goto anonymous;
2118         }
2119         result = cli_rpc_pipe_open_schannel_with_key
2120                 (conn->cli, &ndr_table_samr.syntax_id, NCACN_NP,
2121                  DCERPC_AUTH_LEVEL_PRIVACY,
2122                  domain->name, &p_creds, &conn->samr_pipe);
2123
2124         if (!NT_STATUS_IS_OK(result)) {
2125                 DEBUG(10,("cm_connect_sam: failed to connect to SAMR pipe for "
2126                           "domain %s using schannel. Error was %s\n",
2127                           domain->name, nt_errstr(result) ));
2128                 goto anonymous;
2129         }
2130         DEBUG(10,("cm_connect_sam: connected to SAMR pipe for domain %s using "
2131                   "schannel.\n", domain->name ));
2132
2133         result = rpccli_samr_Connect2(conn->samr_pipe, mem_ctx,
2134                                       conn->samr_pipe->desthost,
2135                                       SEC_FLAG_MAXIMUM_ALLOWED,
2136                                       &conn->sam_connect_handle);
2137         if (NT_STATUS_IS_OK(result)) {
2138                 goto open_domain;
2139         }
2140         DEBUG(10,("cm_connect_sam: schannel-sealed rpccli_samr_Connect2 failed "
2141                   "for domain %s, error was %s. Trying anonymous\n",
2142                   domain->name, nt_errstr(result) ));
2143         TALLOC_FREE(conn->samr_pipe);
2144
2145  anonymous:
2146
2147         /* Finally fall back to anonymous. */
2148         result = cli_rpc_pipe_open_noauth(conn->cli, &ndr_table_samr.syntax_id,
2149                                           &conn->samr_pipe);
2150
2151         if (!NT_STATUS_IS_OK(result)) {
2152                 goto done;
2153         }
2154
2155         result = rpccli_samr_Connect2(conn->samr_pipe, mem_ctx,
2156                                       conn->samr_pipe->desthost,
2157                                       SEC_FLAG_MAXIMUM_ALLOWED,
2158                                       &conn->sam_connect_handle);
2159         if (!NT_STATUS_IS_OK(result)) {
2160                 DEBUG(10,("cm_connect_sam: rpccli_samr_Connect2 failed "
2161                           "for domain %s Error was %s\n",
2162                           domain->name, nt_errstr(result) ));
2163                 goto done;
2164         }
2165
2166  open_domain:
2167         result = rpccli_samr_OpenDomain(conn->samr_pipe,
2168                                         mem_ctx,
2169                                         &conn->sam_connect_handle,
2170                                         SEC_FLAG_MAXIMUM_ALLOWED,
2171                                         &domain->sid,
2172                                         &conn->sam_domain_handle);
2173
2174  done:
2175
2176         if (NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED)) {
2177                 /*
2178                  * if we got access denied, we might just have no access rights
2179                  * to talk to the remote samr server server (e.g. when we are a
2180                  * PDC and we are connecting a w2k8 pdc via an interdomain
2181                  * trust). In that case do not invalidate the whole connection
2182                  * stack
2183                  */
2184                 TALLOC_FREE(conn->samr_pipe);
2185                 ZERO_STRUCT(conn->sam_domain_handle);
2186                 return result;
2187         } else if (!NT_STATUS_IS_OK(result)) {
2188                 invalidate_cm_connection(conn);
2189                 return result;
2190         }
2191
2192         *cli = conn->samr_pipe;
2193         *sam_handle = conn->sam_domain_handle;
2194         SAFE_FREE(machine_password);
2195         SAFE_FREE(machine_account);
2196         return result;
2197 }
2198
2199 /**********************************************************************
2200  open an schanneld ncacn_ip_tcp connection to LSA
2201 ***********************************************************************/
2202
2203 NTSTATUS cm_connect_lsa_tcp(struct winbindd_domain *domain,
2204                             TALLOC_CTX *mem_ctx,
2205                             struct rpc_pipe_client **cli)
2206 {
2207         struct winbindd_cm_conn *conn;
2208         struct netlogon_creds_CredentialState *creds;
2209         NTSTATUS status;
2210
2211         DEBUG(10,("cm_connect_lsa_tcp\n"));
2212
2213         status = init_dc_connection_rpc(domain);
2214         if (!NT_STATUS_IS_OK(status)) {
2215                 return status;
2216         }
2217
2218         conn = &domain->conn;
2219
2220         if (conn->lsa_pipe_tcp &&
2221             conn->lsa_pipe_tcp->transport->transport == NCACN_IP_TCP &&
2222             conn->lsa_pipe_tcp->auth->auth_level == DCERPC_AUTH_LEVEL_PRIVACY &&
2223             rpccli_is_connected(conn->lsa_pipe_tcp)) {
2224                 goto done;
2225         }
2226
2227         TALLOC_FREE(conn->lsa_pipe_tcp);
2228
2229         status = cm_get_schannel_creds(domain, &creds);
2230         if (!NT_STATUS_IS_OK(status)) {
2231                 goto done;
2232         }
2233
2234         status = cli_rpc_pipe_open_schannel_with_key(conn->cli,
2235                                                      &ndr_table_lsarpc.syntax_id,
2236                                                      NCACN_IP_TCP,
2237                                                      DCERPC_AUTH_LEVEL_PRIVACY,
2238                                                      domain->name,
2239                                                      &creds,
2240                                                      &conn->lsa_pipe_tcp);
2241         if (!NT_STATUS_IS_OK(status)) {
2242                 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key failed: %s\n",
2243                         nt_errstr(status)));
2244                 goto done;
2245         }
2246
2247  done:
2248         if (!NT_STATUS_IS_OK(status)) {
2249                 TALLOC_FREE(conn->lsa_pipe_tcp);
2250                 return status;
2251         }
2252
2253         *cli = conn->lsa_pipe_tcp;
2254
2255         return status;
2256 }
2257
2258 NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
2259                         struct rpc_pipe_client **cli, struct policy_handle *lsa_policy)
2260 {
2261         struct winbindd_cm_conn *conn;
2262         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2263         struct netlogon_creds_CredentialState *p_creds;
2264
2265         result = init_dc_connection_rpc(domain);
2266         if (!NT_STATUS_IS_OK(result))
2267                 return result;
2268
2269         conn = &domain->conn;
2270
2271         if (rpccli_is_connected(conn->lsa_pipe)) {
2272                 goto done;
2273         }
2274
2275         TALLOC_FREE(conn->lsa_pipe);
2276
2277         if ((conn->cli->user_name[0] == '\0') ||
2278             (conn->cli->domain[0] == '\0') || 
2279             (conn->cli->password == NULL || conn->cli->password[0] == '\0')) {
2280                 DEBUG(10, ("cm_connect_lsa: No no user available for "
2281                            "domain %s, trying schannel\n", conn->cli->domain));
2282                 goto schannel;
2283         }
2284
2285         /* We have an authenticated connection. Use a NTLMSSP SPNEGO
2286          * authenticated LSA pipe with sign & seal. */
2287         result = cli_rpc_pipe_open_spnego_ntlmssp
2288                 (conn->cli, &ndr_table_lsarpc.syntax_id, NCACN_NP,
2289                  DCERPC_AUTH_LEVEL_PRIVACY,
2290                  conn->cli->domain, conn->cli->user_name, conn->cli->password,
2291                  &conn->lsa_pipe);
2292
2293         if (!NT_STATUS_IS_OK(result)) {
2294                 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
2295                           "domain %s using NTLMSSP authenticated pipe: user "
2296                           "%s\\%s. Error was %s. Trying schannel.\n",
2297                           domain->name, conn->cli->domain,
2298                           conn->cli->user_name, nt_errstr(result)));
2299                 goto schannel;
2300         }
2301
2302         DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
2303                   "NTLMSSP authenticated pipe: user %s\\%s\n",
2304                   domain->name, conn->cli->domain, conn->cli->user_name ));
2305
2306         result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2307                                         SEC_FLAG_MAXIMUM_ALLOWED,
2308                                         &conn->lsa_policy);
2309         if (NT_STATUS_IS_OK(result)) {
2310                 goto done;
2311         }
2312
2313         DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
2314                   "schannel\n"));
2315
2316         TALLOC_FREE(conn->lsa_pipe);
2317
2318  schannel:
2319
2320         /* Fall back to schannel if it's a W2K pre-SP1 box. */
2321
2322         result = cm_get_schannel_creds(domain, &p_creds);
2323         if (!NT_STATUS_IS_OK(result)) {
2324                 /* If this call fails - conn->cli can now be NULL ! */
2325                 DEBUG(10, ("cm_connect_lsa: Could not get schannel auth info "
2326                            "for domain %s (error %s), trying anon\n",
2327                         domain->name,
2328                         nt_errstr(result) ));
2329                 goto anonymous;
2330         }
2331         result = cli_rpc_pipe_open_schannel_with_key
2332                 (conn->cli, &ndr_table_lsarpc.syntax_id, NCACN_NP,
2333                  DCERPC_AUTH_LEVEL_PRIVACY,
2334                  domain->name, &p_creds, &conn->lsa_pipe);
2335
2336         if (!NT_STATUS_IS_OK(result)) {
2337                 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
2338                           "domain %s using schannel. Error was %s\n",
2339                           domain->name, nt_errstr(result) ));
2340                 goto anonymous;
2341         }
2342         DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
2343                   "schannel.\n", domain->name ));
2344
2345         result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2346                                         SEC_FLAG_MAXIMUM_ALLOWED,
2347                                         &conn->lsa_policy);
2348         if (NT_STATUS_IS_OK(result)) {
2349                 goto done;
2350         }
2351
2352         DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
2353                   "anonymous\n"));
2354
2355         TALLOC_FREE(conn->lsa_pipe);
2356
2357  anonymous:
2358
2359         result = cli_rpc_pipe_open_noauth(conn->cli,
2360                                           &ndr_table_lsarpc.syntax_id,
2361                                           &conn->lsa_pipe);
2362         if (!NT_STATUS_IS_OK(result)) {
2363                 result = NT_STATUS_PIPE_NOT_AVAILABLE;
2364                 goto done;
2365         }
2366
2367         result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2368                                         SEC_FLAG_MAXIMUM_ALLOWED,
2369                                         &conn->lsa_policy);
2370  done:
2371         if (!NT_STATUS_IS_OK(result)) {
2372                 invalidate_cm_connection(conn);
2373                 return result;
2374         }
2375
2376         *cli = conn->lsa_pipe;
2377         *lsa_policy = conn->lsa_policy;
2378         return result;
2379 }
2380
2381 /****************************************************************************
2382  Open the netlogon pipe to this DC. Use schannel if specified in client conf.
2383  session key stored in conn->netlogon_pipe->dc->sess_key.
2384 ****************************************************************************/
2385
2386 NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
2387                              struct rpc_pipe_client **cli)
2388 {
2389         struct winbindd_cm_conn *conn;
2390         NTSTATUS result;
2391
2392         uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
2393         uint8  mach_pwd[16];
2394         enum netr_SchannelType sec_chan_type;
2395         const char *account_name;
2396         struct rpc_pipe_client *netlogon_pipe = NULL;
2397
2398         *cli = NULL;
2399
2400         result = init_dc_connection_rpc(domain);
2401         if (!NT_STATUS_IS_OK(result)) {
2402                 return result;
2403         }
2404
2405         conn = &domain->conn;
2406
2407         if (rpccli_is_connected(conn->netlogon_pipe)) {
2408                 *cli = conn->netlogon_pipe;
2409                 return NT_STATUS_OK;
2410         }
2411
2412         TALLOC_FREE(conn->netlogon_pipe);
2413
2414         result = cli_rpc_pipe_open_noauth(conn->cli,
2415                                           &ndr_table_netlogon.syntax_id,
2416                                           &netlogon_pipe);
2417         if (!NT_STATUS_IS_OK(result)) {
2418                 return result;
2419         }
2420
2421         if ((!IS_DC) && (!domain->primary)) {
2422                 /* Clear the schannel request bit and drop down */
2423                 neg_flags &= ~NETLOGON_NEG_SCHANNEL;            
2424                 goto no_schannel;
2425         }
2426
2427         if (lp_client_schannel() != False) {
2428                 neg_flags |= NETLOGON_NEG_SCHANNEL;
2429         }
2430
2431         if (!get_trust_pw_hash(domain->name, mach_pwd, &account_name,
2432                                &sec_chan_type))
2433         {
2434                 TALLOC_FREE(netlogon_pipe);
2435                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2436         }
2437
2438         result = rpccli_netlogon_setup_creds(
2439                  netlogon_pipe,
2440                  domain->dcname, /* server name. */
2441                  domain->name,   /* domain name */
2442                  global_myname(), /* client name */
2443                  account_name,   /* machine account */
2444                  mach_pwd,       /* machine password */
2445                  sec_chan_type,  /* from get_trust_pw */
2446                  &neg_flags);
2447
2448         if (!NT_STATUS_IS_OK(result)) {
2449                 TALLOC_FREE(netlogon_pipe);
2450                 return result;
2451         }
2452
2453         if ((lp_client_schannel() == True) &&
2454                         ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
2455                 DEBUG(3, ("Server did not offer schannel\n"));
2456                 TALLOC_FREE(netlogon_pipe);
2457                 return NT_STATUS_ACCESS_DENIED;
2458         }
2459
2460  no_schannel:
2461         if ((lp_client_schannel() == False) ||
2462                         ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
2463                 /*
2464                  * NetSamLogonEx only works for schannel
2465                  */
2466                 domain->can_do_samlogon_ex = False;
2467
2468                 /* We're done - just keep the existing connection to NETLOGON
2469                  * open */
2470                 conn->netlogon_pipe = netlogon_pipe;
2471                 *cli = conn->netlogon_pipe;
2472                 return NT_STATUS_OK;
2473         }
2474
2475         /* Using the credentials from the first pipe, open a signed and sealed
2476            second netlogon pipe. The session key is stored in the schannel
2477            part of the new pipe auth struct.
2478         */
2479
2480         result = cli_rpc_pipe_open_schannel_with_key(
2481                 conn->cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
2482                 DCERPC_AUTH_LEVEL_PRIVACY, domain->name, &netlogon_pipe->dc,
2483                 &conn->netlogon_pipe);
2484
2485         /* We can now close the initial netlogon pipe. */
2486         TALLOC_FREE(netlogon_pipe);
2487
2488         if (!NT_STATUS_IS_OK(result)) {
2489                 DEBUG(3, ("Could not open schannel'ed NETLOGON pipe. Error "
2490                           "was %s\n", nt_errstr(result)));
2491
2492                 invalidate_cm_connection(conn);
2493                 return result;
2494         }
2495
2496         /*
2497          * Always try netr_LogonSamLogonEx. We will fall back for NT4
2498          * which gives DCERPC_FAULT_OP_RNG_ERROR (function not
2499          * supported). We used to only try SamLogonEx for AD, but
2500          * Samba DCs can also do it. And because we don't distinguish
2501          * between Samba and NT4, always try it once.
2502          */
2503         domain->can_do_samlogon_ex = true;
2504
2505         *cli = conn->netlogon_pipe;
2506         return NT_STATUS_OK;
2507 }