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