s3:winbindd: remove useless ';'
[ira/wip.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         result = cli_negprot(*cli);
848
849         if (!NT_STATUS_IS_OK(result)) {
850                 DEBUG(1, ("cli_negprot failed: %s\n", nt_errstr(result)));
851                 goto done;
852         }
853
854         if (!is_dc_trusted_domain_situation(domain->name) &&
855             (*cli)->protocol >= PROTOCOL_NT1 &&
856             (*cli)->capabilities & CAP_EXTENDED_SECURITY)
857         {
858                 ADS_STATUS ads_status;
859
860                 result = get_trust_creds(domain, &machine_password,
861                                          &machine_account,
862                                          &machine_krb5_principal);
863                 if (!NT_STATUS_IS_OK(result)) {
864                         goto anon_fallback;
865                 }
866
867                 if (lp_security() == SEC_ADS) {
868
869                         /* Try a krb5 session */
870
871                         (*cli)->use_kerberos = True;
872                         DEBUG(5, ("connecting to %s from %s with kerberos principal "
873                                   "[%s] and realm [%s]\n", controller, global_myname(),
874                                   machine_krb5_principal, domain->alt_name));
875
876                         winbindd_set_locator_kdc_envs(domain);
877
878                         ads_status = cli_session_setup_spnego(*cli,
879                                                               machine_krb5_principal, 
880                                                               machine_password,
881                                                               lp_workgroup(),
882                                                               domain->alt_name);
883
884                         if (!ADS_ERR_OK(ads_status)) {
885                                 DEBUG(4,("failed kerberos session setup with %s\n",
886                                          ads_errstr(ads_status)));
887                         }
888
889                         result = ads_ntstatus(ads_status);
890                         if (NT_STATUS_IS_OK(result)) {
891                                 /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
892                                 result = cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
893                                 if (!NT_STATUS_IS_OK(result)) {
894                                         goto done;
895                                 }
896                                 goto session_setup_done;
897                         }
898                 }
899
900                 /* Fall back to non-kerberos session setup using NTLMSSP SPNEGO with the machine account. */
901                 (*cli)->use_kerberos = False;
902
903                 DEBUG(5, ("connecting to %s from %s with username "
904                           "[%s]\\[%s]\n",  controller, global_myname(),
905                           lp_workgroup(), machine_account));
906
907                 ads_status = cli_session_setup_spnego(*cli,
908                                                       machine_account, 
909                                                       machine_password, 
910                                                       lp_workgroup(),
911                                                       NULL);
912                 if (!ADS_ERR_OK(ads_status)) {
913                         DEBUG(4, ("authenticated session setup failed with %s\n",
914                                 ads_errstr(ads_status)));
915                 }
916
917                 result = ads_ntstatus(ads_status);
918                 if (NT_STATUS_IS_OK(result)) {
919                         /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
920                         result = cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
921                         if (!NT_STATUS_IS_OK(result)) {
922                                 goto done;
923                         }
924                         goto session_setup_done;
925                 }
926         }
927
928         /* Fall back to non-kerberos session setup with auth_user */
929
930         (*cli)->use_kerberos = False;
931
932         cm_get_ipc_userpass(&ipc_username, &ipc_domain, &ipc_password);
933
934         if ((((*cli)->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) != 0) &&
935             (strlen(ipc_username) > 0)) {
936
937                 /* Only try authenticated if we have a username */
938
939                 DEBUG(5, ("connecting to %s from %s with username "
940                           "[%s]\\[%s]\n",  controller, global_myname(),
941                           ipc_domain, ipc_username));
942
943                 if (NT_STATUS_IS_OK(cli_session_setup(
944                                             *cli, ipc_username,
945                                             ipc_password, strlen(ipc_password)+1,
946                                             ipc_password, strlen(ipc_password)+1,
947                                             ipc_domain))) {
948                         /* Successful logon with given username. */
949                         result = cli_init_creds(*cli, ipc_username, ipc_domain, ipc_password);
950                         if (!NT_STATUS_IS_OK(result)) {
951                                 goto done;
952                         }
953                         goto session_setup_done;
954                 } else {
955                         DEBUG(4, ("authenticated session setup with user %s\\%s failed.\n",
956                                 ipc_domain, ipc_username ));
957                 }
958         }
959
960  anon_fallback:
961
962         /* Fall back to anonymous connection, this might fail later */
963         DEBUG(10,("cm_prepare_connection: falling back to anonymous "
964                 "connection for DC %s\n",
965                 controller ));
966
967         if (NT_STATUS_IS_OK(cli_session_setup(*cli, "", NULL, 0,
968                                               NULL, 0, ""))) {
969                 DEBUG(5, ("Connected anonymously\n"));
970                 result = cli_init_creds(*cli, "", "", "");
971                 if (!NT_STATUS_IS_OK(result)) {
972                         goto done;
973                 }
974                 goto session_setup_done;
975         }
976
977         result = cli_nt_error(*cli);
978
979         if (NT_STATUS_IS_OK(result))
980                 result = NT_STATUS_UNSUCCESSFUL;
981
982         /* We can't session setup */
983
984         goto done;
985
986  session_setup_done:
987
988         /* cache the server name for later connections */
989
990         saf_store( domain->name, (*cli)->desthost );
991         if (domain->alt_name && (*cli)->use_kerberos) {
992                 saf_store( domain->alt_name, (*cli)->desthost );
993         }
994
995         winbindd_set_locator_kdc_envs(domain);
996
997         result = cli_tcon_andx(*cli, "IPC$", "IPC", "", 0);
998
999         if (!NT_STATUS_IS_OK(result)) {
1000                 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(result)));
1001                 goto done;
1002         }
1003
1004         TALLOC_FREE(mutex);
1005         *retry = False;
1006
1007         /* set the domain if empty; needed for schannel connections */
1008         if ( !(*cli)->domain[0] ) {
1009                 result = cli_set_domain((*cli), domain->name);
1010                 if (!NT_STATUS_IS_OK(result)) {
1011                         return result;
1012                 }
1013         }
1014
1015         result = NT_STATUS_OK;
1016
1017  done:
1018         TALLOC_FREE(mutex);
1019         SAFE_FREE(machine_account);
1020         SAFE_FREE(machine_password);
1021         SAFE_FREE(machine_krb5_principal);
1022         SAFE_FREE(ipc_username);
1023         SAFE_FREE(ipc_domain);
1024         SAFE_FREE(ipc_password);
1025
1026         if (!NT_STATUS_IS_OK(result)) {
1027                 winbind_add_failed_connection_entry(domain, controller, result);
1028                 if ((*cli) != NULL) {
1029                         cli_shutdown(*cli);
1030                         *cli = NULL;
1031                 }
1032         }
1033
1034         return result;
1035 }
1036
1037 /*******************************************************************
1038  Add a dcname and sockaddr_storage pair to the end of a dc_name_ip
1039  array.
1040
1041  Keeps the list unique by not adding duplicate entries.
1042
1043  @param[in] mem_ctx talloc memory context to allocate from
1044  @param[in] domain_name domain of the DC
1045  @param[in] dcname name of the DC to add to the list
1046  @param[in] pss Internet address and port pair to add to the list
1047  @param[in,out] dcs array of dc_name_ip structures to add to
1048  @param[in,out] num_dcs number of dcs returned in the dcs array
1049  @return true if the list was added to, false otherwise
1050 *******************************************************************/
1051
1052 static bool add_one_dc_unique(TALLOC_CTX *mem_ctx, const char *domain_name,
1053                               const char *dcname, struct sockaddr_storage *pss,
1054                               struct dc_name_ip **dcs, int *num)
1055 {
1056         int i = 0;
1057
1058         if (!NT_STATUS_IS_OK(check_negative_conn_cache(domain_name, dcname))) {
1059                 DEBUG(10, ("DC %s was in the negative conn cache\n", dcname));
1060                 return False;
1061         }
1062
1063         /* Make sure there's no duplicates in the list */
1064         for (i=0; i<*num; i++)
1065                 if (sockaddr_equal(
1066                             (struct sockaddr *)(void *)&(*dcs)[i].ss,
1067                             (struct sockaddr *)(void *)pss))
1068                         return False;
1069
1070         *dcs = TALLOC_REALLOC_ARRAY(mem_ctx, *dcs, struct dc_name_ip, (*num)+1);
1071
1072         if (*dcs == NULL)
1073                 return False;
1074
1075         fstrcpy((*dcs)[*num].name, dcname);
1076         (*dcs)[*num].ss = *pss;
1077         *num += 1;
1078         return True;
1079 }
1080
1081 static bool add_sockaddr_to_array(TALLOC_CTX *mem_ctx,
1082                                   struct sockaddr_storage *pss, uint16 port,
1083                                   struct sockaddr_storage **addrs, int *num)
1084 {
1085         *addrs = TALLOC_REALLOC_ARRAY(mem_ctx, *addrs, struct sockaddr_storage, (*num)+1);
1086
1087         if (*addrs == NULL) {
1088                 *num = 0;
1089                 return False;
1090         }
1091
1092         (*addrs)[*num] = *pss;
1093         set_sockaddr_port((struct sockaddr *)&(*addrs)[*num], port);
1094
1095         *num += 1;
1096         return True;
1097 }
1098
1099 /*******************************************************************
1100  convert an ip to a name
1101 *******************************************************************/
1102
1103 static bool dcip_to_name(TALLOC_CTX *mem_ctx,
1104                 const struct winbindd_domain *domain,
1105                 struct sockaddr_storage *pss,
1106                 fstring name )
1107 {
1108         struct ip_service ip_list;
1109         uint32_t nt_version = NETLOGON_NT_VERSION_1;
1110         int dgm_id;
1111         uint16_t val;
1112
1113         ip_list.ss = *pss;
1114         ip_list.port = 0;
1115
1116 #ifdef WITH_ADS
1117         /* For active directory servers, try to get the ldap server name.
1118            None of these failures should be considered critical for now */
1119
1120         if (lp_security() == SEC_ADS) {
1121                 ADS_STRUCT *ads;
1122                 ADS_STATUS ads_status;
1123                 char addr[INET6_ADDRSTRLEN];
1124
1125                 print_sockaddr(addr, sizeof(addr), pss);
1126
1127                 ads = ads_init(domain->alt_name, domain->name, addr);
1128                 ads->auth.flags |= ADS_AUTH_NO_BIND;
1129
1130                 ads_status = ads_connect(ads);
1131                 if (ADS_ERR_OK(ads_status)) {
1132                         /* We got a cldap packet. */
1133                         fstrcpy(name, ads->config.ldap_server_name);
1134                         namecache_store(name, 0x20, 1, &ip_list);
1135
1136                         DEBUG(10,("dcip_to_name: flags = 0x%x\n", (unsigned int)ads->config.flags));
1137
1138                         if (domain->primary && (ads->config.flags & NBT_SERVER_KDC)) {
1139                                 if (ads_closest_dc(ads)) {
1140                                         char *sitename = sitename_fetch(ads->config.realm);
1141
1142                                         /* We're going to use this KDC for this realm/domain.
1143                                            If we are using sites, then force the krb5 libs
1144                                            to use this KDC. */
1145
1146                                         create_local_private_krb5_conf_for_domain(domain->alt_name,
1147                                                                         domain->name,
1148                                                                         sitename,
1149                                                                         pss,
1150                                                                         name);
1151
1152                                         SAFE_FREE(sitename);
1153                                 } else {
1154                                         /* use an off site KDC */
1155                                         create_local_private_krb5_conf_for_domain(domain->alt_name,
1156                                                                         domain->name,
1157                                                                         NULL,
1158                                                                         pss,
1159                                                                         name);
1160                                 }
1161                                 winbindd_set_locator_kdc_envs(domain);
1162
1163                                 /* Ensure we contact this DC also. */
1164                                 saf_store( domain->name, name);
1165                                 saf_store( domain->alt_name, name);
1166                         }
1167
1168                         ads_destroy( &ads );
1169                         return True;
1170                 }
1171
1172                 ads_destroy( &ads );
1173         }
1174 #endif
1175
1176         /* try GETDC requests next */
1177         generate_random_buffer((uint8_t *)&val, 2);
1178         dgm_id = val;
1179
1180         if (send_getdc_request(mem_ctx, winbind_messaging_context(),
1181                                pss, domain->name, &domain->sid,
1182                                nt_version, dgm_id)) {
1183                 const char *dc_name = NULL;
1184                 int i;
1185                 smb_msleep(100);
1186                 for (i=0; i<5; i++) {
1187                         if (receive_getdc_response(mem_ctx, pss, domain->name,
1188                                                    dgm_id,
1189                                                    &nt_version,
1190                                                    &dc_name, NULL)) {
1191                                 fstrcpy(name, dc_name);
1192                                 namecache_store(name, 0x20, 1, &ip_list);
1193                                 return True;
1194                         }
1195                         smb_msleep(500);
1196                 }
1197         }
1198
1199         /* try node status request */
1200
1201         if ( name_status_find(domain->name, 0x1c, 0x20, pss, name) ) {
1202                 namecache_store(name, 0x20, 1, &ip_list);
1203                 return True;
1204         }
1205         return False;
1206 }
1207
1208 /*******************************************************************
1209  Retrieve a list of IP addresses for domain controllers.
1210
1211  The array is sorted in the preferred connection order.
1212
1213  @param[in] mem_ctx talloc memory context to allocate from
1214  @param[in] domain domain to retrieve DCs for
1215  @param[out] dcs array of dcs that will be returned
1216  @param[out] num_dcs number of dcs returned in the dcs array
1217  @return always true
1218 *******************************************************************/
1219
1220 static bool get_dcs(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
1221                     struct dc_name_ip **dcs, int *num_dcs)
1222 {
1223         fstring dcname;
1224         struct  sockaddr_storage ss;
1225         struct  ip_service *ip_list = NULL;
1226         int     iplist_size = 0;
1227         int     i;
1228         bool    is_our_domain;
1229         enum security_types sec = (enum security_types)lp_security();
1230
1231         is_our_domain = strequal(domain->name, lp_workgroup());
1232
1233         /* If not our domain, get the preferred DC, by asking our primary DC */
1234         if ( !is_our_domain
1235                 && get_dc_name_via_netlogon(domain, dcname, &ss)
1236                 && add_one_dc_unique(mem_ctx, domain->name, dcname, &ss, dcs,
1237                        num_dcs) )
1238         {
1239                 char addr[INET6_ADDRSTRLEN];
1240                 print_sockaddr(addr, sizeof(addr), &ss);
1241                 DEBUG(10, ("Retrieved DC %s at %s via netlogon\n",
1242                            dcname, addr));
1243                 return True;
1244         }
1245
1246         if (sec == SEC_ADS) {
1247                 char *sitename = NULL;
1248
1249                 /* We need to make sure we know the local site before
1250                    doing any DNS queries, as this will restrict the
1251                    get_sorted_dc_list() call below to only fetching
1252                    DNS records for the correct site. */
1253
1254                 /* Find any DC to get the site record.
1255                    We deliberately don't care about the
1256                    return here. */
1257
1258                 get_dc_name(domain->name, domain->alt_name, dcname, &ss);
1259
1260                 sitename = sitename_fetch(domain->alt_name);
1261                 if (sitename) {
1262
1263                         /* Do the site-specific AD dns lookup first. */
1264                         get_sorted_dc_list(domain->alt_name, sitename, &ip_list,
1265                                &iplist_size, True);
1266
1267                         /* Add ips to the DC array.  We don't look up the name
1268                            of the DC in this function, but we fill in the char*
1269                            of the ip now to make the failed connection cache
1270                            work */
1271                         for ( i=0; i<iplist_size; i++ ) {
1272                                 char addr[INET6_ADDRSTRLEN];
1273                                 print_sockaddr(addr, sizeof(addr),
1274                                                 &ip_list[i].ss);
1275                                 add_one_dc_unique(mem_ctx,
1276                                                 domain->name,
1277                                                 addr,
1278                                                 &ip_list[i].ss,
1279                                                 dcs,
1280                                                 num_dcs);
1281                         }
1282
1283                         SAFE_FREE(ip_list);
1284                         SAFE_FREE(sitename);
1285                         iplist_size = 0;
1286                 }
1287
1288                 /* Now we add DCs from the main AD DNS lookup. */
1289                 get_sorted_dc_list(domain->alt_name, NULL, &ip_list,
1290                         &iplist_size, True);
1291
1292                 for ( i=0; i<iplist_size; i++ ) {
1293                         char addr[INET6_ADDRSTRLEN];
1294                         print_sockaddr(addr, sizeof(addr),
1295                                         &ip_list[i].ss);
1296                         add_one_dc_unique(mem_ctx,
1297                                         domain->name,
1298                                         addr,
1299                                         &ip_list[i].ss,
1300                                         dcs,
1301                                         num_dcs);
1302                 }
1303
1304                 SAFE_FREE(ip_list);
1305                 iplist_size = 0;
1306         }
1307
1308         /* Try standard netbios queries if no ADS */
1309         if (*num_dcs == 0) {
1310                 get_sorted_dc_list(domain->name, NULL, &ip_list, &iplist_size,
1311                        False);
1312
1313                 for ( i=0; i<iplist_size; i++ ) {
1314                         char addr[INET6_ADDRSTRLEN];
1315                         print_sockaddr(addr, sizeof(addr),
1316                                         &ip_list[i].ss);
1317                         add_one_dc_unique(mem_ctx,
1318                                         domain->name,
1319                                         addr,
1320                                         &ip_list[i].ss,
1321                                         dcs,
1322                                         num_dcs);
1323                 }
1324
1325                 SAFE_FREE(ip_list);
1326                 iplist_size = 0;
1327         }
1328
1329         return True;
1330 }
1331
1332 /*******************************************************************
1333  Find and make a connection to a DC in the given domain.
1334
1335  @param[in] mem_ctx talloc memory context to allocate from
1336  @param[in] domain domain to find a dc in
1337  @param[out] dcname NetBIOS or FQDN of DC that's connected to
1338  @param[out] pss DC Internet address and port
1339  @param[out] fd fd of the open socket connected to the newly found dc
1340  @return true when a DC connection is made, false otherwise
1341 *******************************************************************/
1342
1343 static bool find_new_dc(TALLOC_CTX *mem_ctx,
1344                         struct winbindd_domain *domain,
1345                         fstring dcname, struct sockaddr_storage *pss, int *fd)
1346 {
1347         struct dc_name_ip *dcs = NULL;
1348         int num_dcs = 0;
1349
1350         const char **dcnames = NULL;
1351         int num_dcnames = 0;
1352
1353         struct sockaddr_storage *addrs = NULL;
1354         int num_addrs = 0;
1355
1356         int i;
1357         size_t fd_index;
1358
1359         NTSTATUS status;
1360
1361         *fd = -1;
1362
1363  again:
1364         if (!get_dcs(mem_ctx, domain, &dcs, &num_dcs) || (num_dcs == 0))
1365                 return False;
1366
1367         for (i=0; i<num_dcs; i++) {
1368
1369                 if (!add_string_to_array(mem_ctx, dcs[i].name,
1370                                     &dcnames, &num_dcnames)) {
1371                         return False;
1372                 }
1373                 if (!add_sockaddr_to_array(mem_ctx, &dcs[i].ss, 445,
1374                                       &addrs, &num_addrs)) {
1375                         return False;
1376                 }
1377         }
1378
1379         if ((num_dcnames == 0) || (num_dcnames != num_addrs))
1380                 return False;
1381
1382         if ((addrs == NULL) || (dcnames == NULL))
1383                 return False;
1384
1385         status = smbsock_any_connect(addrs, dcnames, num_addrs,
1386                                      fd, &fd_index, NULL);
1387         if (!NT_STATUS_IS_OK(status)) {
1388                 for (i=0; i<num_dcs; i++) {
1389                         char ab[INET6_ADDRSTRLEN];
1390                         print_sockaddr(ab, sizeof(ab), &dcs[i].ss);
1391                         DEBUG(10, ("find_new_dc: smbsock_any_connect failed for "
1392                                 "domain %s address %s. Error was %s\n",
1393                                    domain->name, ab, nt_errstr(status) ));
1394                         winbind_add_failed_connection_entry(domain,
1395                                 dcs[i].name, NT_STATUS_UNSUCCESSFUL);
1396                 }
1397                 return False;
1398         }
1399
1400         *pss = addrs[fd_index];
1401
1402         if (*dcnames[fd_index] != '\0' && !is_ipaddress(dcnames[fd_index])) {
1403                 /* Ok, we've got a name for the DC */
1404                 fstrcpy(dcname, dcnames[fd_index]);
1405                 return True;
1406         }
1407
1408         /* Try to figure out the name */
1409         if (dcip_to_name(mem_ctx, domain, pss, dcname)) {
1410                 return True;
1411         }
1412
1413         /* We can not continue without the DC's name */
1414         winbind_add_failed_connection_entry(domain, dcs[fd_index].name,
1415                                     NT_STATUS_UNSUCCESSFUL);
1416
1417         /* Throw away all arrays as we're doing this again. */
1418         TALLOC_FREE(dcs);
1419         num_dcs = 0;
1420
1421         TALLOC_FREE(dcnames);
1422         num_dcnames = 0;
1423
1424         TALLOC_FREE(addrs);
1425         num_addrs = 0;
1426
1427         close(*fd);
1428         *fd = -1;
1429
1430         goto again;
1431 }
1432
1433 static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
1434                                    struct winbindd_cm_conn *new_conn)
1435 {
1436         TALLOC_CTX *mem_ctx;
1437         NTSTATUS result;
1438         char *saf_servername = saf_fetch( domain->name );
1439         int retries;
1440
1441         if ((mem_ctx = talloc_init("cm_open_connection")) == NULL) {
1442                 SAFE_FREE(saf_servername);
1443                 set_domain_offline(domain);
1444                 return NT_STATUS_NO_MEMORY;
1445         }
1446
1447         /* we have to check the server affinity cache here since 
1448            later we select a DC based on response time and not preference */
1449
1450         /* Check the negative connection cache
1451            before talking to it. It going down may have
1452            triggered the reconnection. */
1453
1454         if ( saf_servername && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, saf_servername))) {
1455
1456                 DEBUG(10,("cm_open_connection: saf_servername is '%s' for domain %s\n",
1457                         saf_servername, domain->name ));
1458
1459                 /* convert an ip address to a name */
1460                 if (is_ipaddress( saf_servername ) ) {
1461                         fstring saf_name;
1462                         struct sockaddr_storage ss;
1463
1464                         if (!interpret_string_addr(&ss, saf_servername,
1465                                                 AI_NUMERICHOST)) {
1466                                 return NT_STATUS_UNSUCCESSFUL;
1467                         }
1468                         if (dcip_to_name(mem_ctx, domain, &ss, saf_name )) {
1469                                 fstrcpy( domain->dcname, saf_name );
1470                         } else {
1471                                 winbind_add_failed_connection_entry(
1472                                         domain, saf_servername,
1473                                         NT_STATUS_UNSUCCESSFUL);
1474                         }
1475                 } else {
1476                         fstrcpy( domain->dcname, saf_servername );
1477                 }
1478
1479                 SAFE_FREE( saf_servername );
1480         }
1481
1482         for (retries = 0; retries < 3; retries++) {
1483                 int fd = -1;
1484                 bool retry = False;
1485
1486                 result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1487
1488                 DEBUG(10,("cm_open_connection: dcname is '%s' for domain %s\n",
1489                         domain->dcname, domain->name ));
1490
1491                 if (*domain->dcname 
1492                         && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, domain->dcname))
1493                         && (resolve_name(domain->dcname, &domain->dcaddr, 0x20, true)))
1494                 {
1495                         NTSTATUS status;
1496
1497                         status = smbsock_connect(&domain->dcaddr, NULL, NULL,
1498                                                  &fd, NULL);
1499                         if (!NT_STATUS_IS_OK(status)) {
1500                                 fd = -1;
1501                         }
1502                 }
1503
1504                 if ((fd == -1) 
1505                         && !find_new_dc(mem_ctx, domain, domain->dcname, &domain->dcaddr, &fd))
1506                 {
1507                         /* This is the one place where we will
1508                            set the global winbindd offline state
1509                            to true, if a "WINBINDD_OFFLINE" entry
1510                            is found in the winbindd cache. */
1511                         set_global_winbindd_state_offline();
1512                         break;
1513                 }
1514
1515                 new_conn->cli = NULL;
1516
1517                 result = cm_prepare_connection(domain, fd, domain->dcname,
1518                         &new_conn->cli, &retry);
1519
1520                 if (!retry)
1521                         break;
1522         }
1523
1524         if (NT_STATUS_IS_OK(result)) {
1525
1526                 winbindd_set_locator_kdc_envs(domain);
1527
1528                 if (domain->online == False) {
1529                         /* We're changing state from offline to online. */
1530                         set_global_winbindd_state_online();
1531                 }
1532                 set_domain_online(domain);
1533         } else {
1534                 /* Ensure we setup the retry handler. */
1535                 set_domain_offline(domain);
1536         }
1537
1538         talloc_destroy(mem_ctx);
1539         return result;
1540 }
1541
1542 /* Close down all open pipes on a connection. */
1543
1544 void invalidate_cm_connection(struct winbindd_cm_conn *conn)
1545 {
1546         /* We're closing down a possibly dead
1547            connection. Don't have impossibly long (10s) timeouts. */
1548
1549         if (conn->cli) {
1550                 cli_set_timeout(conn->cli, 1000); /* 1 second. */
1551         }
1552
1553         if (conn->samr_pipe != NULL) {
1554                 if (is_valid_policy_hnd(&conn->sam_connect_handle)) {
1555                         rpccli_samr_Close(conn->samr_pipe, talloc_tos(),
1556                                           &conn->sam_connect_handle);
1557                 }
1558                 TALLOC_FREE(conn->samr_pipe);
1559                 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1560                 if (conn->cli) {
1561                         cli_set_timeout(conn->cli, 500);
1562                 }
1563         }
1564
1565         if (conn->lsa_pipe != NULL) {
1566                 if (is_valid_policy_hnd(&conn->lsa_policy)) {
1567                         rpccli_lsa_Close(conn->lsa_pipe, talloc_tos(),
1568                                          &conn->lsa_policy);
1569                 }
1570                 TALLOC_FREE(conn->lsa_pipe);
1571                 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1572                 if (conn->cli) {
1573                         cli_set_timeout(conn->cli, 500);
1574                 }
1575         }
1576
1577         if (conn->lsa_pipe_tcp != NULL) {
1578                 if (is_valid_policy_hnd(&conn->lsa_policy)) {
1579                         rpccli_lsa_Close(conn->lsa_pipe, talloc_tos(),
1580                                          &conn->lsa_policy);
1581                 }
1582                 TALLOC_FREE(conn->lsa_pipe_tcp);
1583                 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1584                 if (conn->cli) {
1585                         cli_set_timeout(conn->cli, 500);
1586                 }
1587         }
1588
1589         if (conn->netlogon_pipe != NULL) {
1590                 TALLOC_FREE(conn->netlogon_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->cli) {
1598                 cli_shutdown(conn->cli);
1599         }
1600
1601         conn->cli = NULL;
1602 }
1603
1604 void close_conns_after_fork(void)
1605 {
1606         struct winbindd_domain *domain;
1607
1608         for (domain = domain_list(); domain; domain = domain->next) {
1609                 struct cli_state *cli = domain->conn.cli;
1610
1611                 /*
1612                  * first close the low level SMB TCP connection
1613                  * so that we don't generate any SMBclose
1614                  * requests in invalidate_cm_connection()
1615                  */
1616                 if (cli && cli->fd != -1) {
1617                         close(domain->conn.cli->fd);
1618                         domain->conn.cli->fd = -1;
1619                 }
1620
1621                 invalidate_cm_connection(&domain->conn);
1622         }
1623 }
1624
1625 static bool connection_ok(struct winbindd_domain *domain)
1626 {
1627         bool ok;
1628
1629         ok = cli_state_is_connected(domain->conn.cli);
1630         if (!ok) {
1631                 DEBUG(3, ("connection_ok: Connection to %s for domain %s is not connected\n",
1632                           domain->dcname, domain->name));
1633                 return False;
1634         }
1635
1636         if (domain->online == False) {
1637                 DEBUG(3, ("connection_ok: Domain %s is offline\n", domain->name));
1638                 return False;
1639         }
1640
1641         return True;
1642 }
1643
1644 /* Initialize a new connection up to the RPC BIND.
1645    Bypass online status check so always does network calls. */
1646
1647 static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain)
1648 {
1649         NTSTATUS result;
1650
1651         /* Internal connections never use the network. */
1652         if (domain->internal) {
1653                 domain->initialized = True;
1654                 return NT_STATUS_OK;
1655         }
1656
1657         if (!winbindd_can_contact_domain(domain)) {
1658                 invalidate_cm_connection(&domain->conn);
1659                 domain->initialized = True;
1660                 return NT_STATUS_OK;
1661         }
1662
1663         if (connection_ok(domain)) {
1664                 if (!domain->initialized) {
1665                         set_dc_type_and_flags(domain);
1666                 }
1667                 return NT_STATUS_OK;
1668         }
1669
1670         invalidate_cm_connection(&domain->conn);
1671
1672         result = cm_open_connection(domain, &domain->conn);
1673
1674         if (NT_STATUS_IS_OK(result) && !domain->initialized) {
1675                 set_dc_type_and_flags(domain);
1676         }
1677
1678         return result;
1679 }
1680
1681 NTSTATUS init_dc_connection(struct winbindd_domain *domain)
1682 {
1683         if (domain->internal) {
1684                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1685         }
1686
1687         if (domain->initialized && !domain->online) {
1688                 /* We check for online status elsewhere. */
1689                 return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1690         }
1691
1692         return init_dc_connection_network(domain);
1693 }
1694
1695 static NTSTATUS init_dc_connection_rpc(struct winbindd_domain *domain)
1696 {
1697         NTSTATUS status;
1698
1699         status = init_dc_connection(domain);
1700         if (!NT_STATUS_IS_OK(status)) {
1701                 return status;
1702         }
1703
1704         if (!domain->internal && domain->conn.cli == NULL) {
1705                 /* happens for trusted domains without inbound trust */
1706                 return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
1707         }
1708
1709         return NT_STATUS_OK;
1710 }
1711
1712 /******************************************************************************
1713  Set the trust flags (direction and forest location) for a domain
1714 ******************************************************************************/
1715
1716 static bool set_dc_type_and_flags_trustinfo( struct winbindd_domain *domain )
1717 {
1718         struct winbindd_domain *our_domain;
1719         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1720         struct netr_DomainTrustList trusts;
1721         int i;
1722         uint32 flags = (NETR_TRUST_FLAG_IN_FOREST |
1723                         NETR_TRUST_FLAG_OUTBOUND |
1724                         NETR_TRUST_FLAG_INBOUND);
1725         struct rpc_pipe_client *cli;
1726         TALLOC_CTX *mem_ctx = NULL;
1727
1728         DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s\n", domain->name ));
1729
1730         /* Our primary domain doesn't need to worry about trust flags.
1731            Force it to go through the network setup */
1732         if ( domain->primary ) {                
1733                 return False;           
1734         }
1735
1736         our_domain = find_our_domain();
1737
1738         if ( !connection_ok(our_domain) ) {
1739                 DEBUG(3,("set_dc_type_and_flags_trustinfo: No connection to our domain!\n"));           
1740                 return False;
1741         }
1742
1743         /* This won't work unless our domain is AD */
1744
1745         if ( !our_domain->active_directory ) {
1746                 return False;
1747         }
1748
1749         /* Use DsEnumerateDomainTrusts to get us the trust direction
1750            and type */
1751
1752         result = cm_connect_netlogon(our_domain, &cli);
1753
1754         if (!NT_STATUS_IS_OK(result)) {
1755                 DEBUG(5, ("set_dc_type_and_flags_trustinfo: Could not open "
1756                           "a connection to %s for PIPE_NETLOGON (%s)\n", 
1757                           domain->name, nt_errstr(result)));
1758                 return False;
1759         }
1760
1761         if ( (mem_ctx = talloc_init("set_dc_type_and_flags_trustinfo")) == NULL ) {
1762                 DEBUG(0,("set_dc_type_and_flags_trustinfo: talloc_init() failed!\n"));
1763                 return False;
1764         }       
1765
1766         result = rpccli_netr_DsrEnumerateDomainTrusts(cli, mem_ctx,
1767                                                       cli->desthost,
1768                                                       flags,
1769                                                       &trusts,
1770                                                       NULL);
1771         if (!NT_STATUS_IS_OK(result)) {
1772                 DEBUG(0,("set_dc_type_and_flags_trustinfo: "
1773                         "failed to query trusted domain list: %s\n",
1774                         nt_errstr(result)));
1775                 talloc_destroy(mem_ctx);
1776                 return false;
1777         }
1778
1779         /* Now find the domain name and get the flags */
1780
1781         for ( i=0; i<trusts.count; i++ ) {
1782                 if ( strequal( domain->name, trusts.array[i].netbios_name) ) {
1783                         domain->domain_flags          = trusts.array[i].trust_flags;
1784                         domain->domain_type           = trusts.array[i].trust_type;
1785                         domain->domain_trust_attribs  = trusts.array[i].trust_attributes;
1786
1787                         if ( domain->domain_type == NETR_TRUST_TYPE_UPLEVEL )
1788                                 domain->active_directory = True;
1789
1790                         /* This flag is only set if the domain is *our* 
1791                            primary domain and the primary domain is in
1792                            native mode */
1793
1794                         domain->native_mode = (domain->domain_flags & NETR_TRUST_FLAG_NATIVE);
1795
1796                         DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s is %sin "
1797                                   "native mode.\n", domain->name, 
1798                                   domain->native_mode ? "" : "NOT "));
1799
1800                         DEBUG(5,("set_dc_type_and_flags_trustinfo: domain %s is %s"
1801                                  "running active directory.\n", domain->name, 
1802                                  domain->active_directory ? "" : "NOT "));
1803
1804
1805                         domain->initialized = True;
1806
1807                         break;
1808                 }               
1809         }
1810
1811         talloc_destroy( mem_ctx );
1812
1813         return domain->initialized;     
1814 }
1815
1816 /******************************************************************************
1817  We can 'sense' certain things about the DC by it's replies to certain
1818  questions.
1819
1820  This tells us if this particular remote server is Active Directory, and if it
1821  is native mode.
1822 ******************************************************************************/
1823
1824 static void set_dc_type_and_flags_connect( struct winbindd_domain *domain )
1825 {
1826         NTSTATUS                result;
1827         WERROR werr;
1828         TALLOC_CTX              *mem_ctx = NULL;
1829         struct rpc_pipe_client  *cli = NULL;
1830         struct policy_handle pol;
1831         union dssetup_DsRoleInfo info;
1832         union lsa_PolicyInformation *lsa_info = NULL;
1833
1834         if (!connection_ok(domain)) {
1835                 return;
1836         }
1837
1838         mem_ctx = talloc_init("set_dc_type_and_flags on domain %s\n",
1839                               domain->name);
1840         if (!mem_ctx) {
1841                 DEBUG(1, ("set_dc_type_and_flags_connect: talloc_init() failed\n"));
1842                 return;
1843         }
1844
1845         DEBUG(5, ("set_dc_type_and_flags_connect: domain %s\n", domain->name ));
1846
1847         result = cli_rpc_pipe_open_noauth(domain->conn.cli,
1848                                           &ndr_table_dssetup.syntax_id,
1849                                           &cli);
1850
1851         if (!NT_STATUS_IS_OK(result)) {
1852                 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
1853                           "PI_DSSETUP on domain %s: (%s)\n",
1854                           domain->name, nt_errstr(result)));
1855
1856                 /* if this is just a non-AD domain we need to continue
1857                  * identifying so that we can in the end return with
1858                  * domain->initialized = True - gd */
1859
1860                 goto no_dssetup;
1861         }
1862
1863         result = rpccli_dssetup_DsRoleGetPrimaryDomainInformation(cli, mem_ctx,
1864                                                                   DS_ROLE_BASIC_INFORMATION,
1865                                                                   &info,
1866                                                                   &werr);
1867         TALLOC_FREE(cli);
1868
1869         if (!NT_STATUS_IS_OK(result)) {
1870                 DEBUG(5, ("set_dc_type_and_flags_connect: rpccli_ds_getprimarydominfo "
1871                           "on domain %s failed: (%s)\n",
1872                           domain->name, nt_errstr(result)));
1873
1874                 /* older samba3 DCs will return DCERPC_FAULT_OP_RNG_ERROR for
1875                  * every opcode on the DSSETUP pipe, continue with
1876                  * no_dssetup mode here as well to get domain->initialized
1877                  * set - gd */
1878
1879                 if (NT_STATUS_V(result) == DCERPC_FAULT_OP_RNG_ERROR) {
1880                         goto no_dssetup;
1881                 }
1882
1883                 TALLOC_FREE(mem_ctx);
1884                 return;
1885         }
1886
1887         if ((info.basic.flags & DS_ROLE_PRIMARY_DS_RUNNING) &&
1888             !(info.basic.flags & DS_ROLE_PRIMARY_DS_MIXED_MODE)) {
1889                 domain->native_mode = True;
1890         } else {
1891                 domain->native_mode = False;
1892         }
1893
1894 no_dssetup:
1895         result = cli_rpc_pipe_open_noauth(domain->conn.cli,
1896                                           &ndr_table_lsarpc.syntax_id, &cli);
1897
1898         if (!NT_STATUS_IS_OK(result)) {
1899                 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
1900                           "PI_LSARPC on domain %s: (%s)\n",
1901                           domain->name, nt_errstr(result)));
1902                 TALLOC_FREE(cli);
1903                 TALLOC_FREE(mem_ctx);
1904                 return;
1905         }
1906
1907         result = rpccli_lsa_open_policy2(cli, mem_ctx, True, 
1908                                          SEC_FLAG_MAXIMUM_ALLOWED, &pol);
1909
1910         if (NT_STATUS_IS_OK(result)) {
1911                 /* This particular query is exactly what Win2k clients use 
1912                    to determine that the DC is active directory */
1913                 result = rpccli_lsa_QueryInfoPolicy2(cli, mem_ctx,
1914                                                      &pol,
1915                                                      LSA_POLICY_INFO_DNS,
1916                                                      &lsa_info);
1917         }
1918
1919         if (NT_STATUS_IS_OK(result)) {
1920                 domain->active_directory = True;
1921
1922                 if (lsa_info->dns.name.string) {
1923                         fstrcpy(domain->name, lsa_info->dns.name.string);
1924                 }
1925
1926                 if (lsa_info->dns.dns_domain.string) {
1927                         fstrcpy(domain->alt_name,
1928                                 lsa_info->dns.dns_domain.string);
1929                 }
1930
1931                 /* See if we can set some domain trust flags about
1932                    ourself */
1933
1934                 if (lsa_info->dns.dns_forest.string) {
1935                         fstrcpy(domain->forest_name,
1936                                 lsa_info->dns.dns_forest.string);
1937
1938                         if (strequal(domain->forest_name, domain->alt_name)) {
1939                                 domain->domain_flags |= NETR_TRUST_FLAG_TREEROOT;
1940                         }
1941                 }
1942
1943                 if (lsa_info->dns.sid) {
1944                         sid_copy(&domain->sid, lsa_info->dns.sid);
1945                 }
1946         } else {
1947                 domain->active_directory = False;
1948
1949                 result = rpccli_lsa_open_policy(cli, mem_ctx, True, 
1950                                                 SEC_FLAG_MAXIMUM_ALLOWED,
1951                                                 &pol);
1952
1953                 if (!NT_STATUS_IS_OK(result)) {
1954                         goto done;
1955                 }
1956
1957                 result = rpccli_lsa_QueryInfoPolicy(cli, mem_ctx,
1958                                                     &pol,
1959                                                     LSA_POLICY_INFO_ACCOUNT_DOMAIN,
1960                                                     &lsa_info);
1961
1962                 if (NT_STATUS_IS_OK(result)) {
1963
1964                         if (lsa_info->account_domain.name.string) {
1965                                 fstrcpy(domain->name,
1966                                         lsa_info->account_domain.name.string);
1967                         }
1968
1969                         if (lsa_info->account_domain.sid) {
1970                                 sid_copy(&domain->sid, lsa_info->account_domain.sid);
1971                         }
1972                 }
1973         }
1974 done:
1975
1976         DEBUG(5, ("set_dc_type_and_flags_connect: domain %s is %sin native mode.\n",
1977                   domain->name, domain->native_mode ? "" : "NOT "));
1978
1979         DEBUG(5,("set_dc_type_and_flags_connect: domain %s is %srunning active directory.\n",
1980                   domain->name, domain->active_directory ? "" : "NOT "));
1981
1982         domain->can_do_ncacn_ip_tcp = domain->active_directory;
1983
1984         TALLOC_FREE(cli);
1985
1986         TALLOC_FREE(mem_ctx);
1987
1988         domain->initialized = True;
1989 }
1990
1991 /**********************************************************************
1992  Set the domain_flags (trust attributes, domain operating modes, etc... 
1993 ***********************************************************************/
1994
1995 static void set_dc_type_and_flags( struct winbindd_domain *domain )
1996 {
1997         /* we always have to contact our primary domain */
1998
1999         if ( domain->primary ) {
2000                 DEBUG(10,("set_dc_type_and_flags: setting up flags for "
2001                           "primary domain\n"));
2002                 set_dc_type_and_flags_connect( domain );
2003                 return;         
2004         }
2005
2006         /* Use our DC to get the information if possible */
2007
2008         if ( !set_dc_type_and_flags_trustinfo( domain ) ) {
2009                 /* Otherwise, fallback to contacting the 
2010                    domain directly */
2011                 set_dc_type_and_flags_connect( domain );
2012         }
2013
2014         return;
2015 }
2016
2017
2018
2019 /**********************************************************************
2020 ***********************************************************************/
2021
2022 static NTSTATUS cm_get_schannel_creds(struct winbindd_domain *domain,
2023                                    struct netlogon_creds_CredentialState **ppdc)
2024 {
2025         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2026         struct rpc_pipe_client *netlogon_pipe;
2027
2028         if (lp_client_schannel() == False) {
2029                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2030         }
2031
2032         result = cm_connect_netlogon(domain, &netlogon_pipe);
2033         if (!NT_STATUS_IS_OK(result)) {
2034                 return result;
2035         }
2036
2037         /* Return a pointer to the struct netlogon_creds_CredentialState from the
2038            netlogon pipe. */
2039
2040         if (!domain->conn.netlogon_pipe->dc) {
2041                 return NT_STATUS_INTERNAL_ERROR; /* This shouldn't happen. */
2042         }
2043
2044         *ppdc = domain->conn.netlogon_pipe->dc;
2045         return NT_STATUS_OK;
2046 }
2047
2048 NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
2049                         struct rpc_pipe_client **cli, struct policy_handle *sam_handle)
2050 {
2051         struct winbindd_cm_conn *conn;
2052         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2053         struct netlogon_creds_CredentialState *p_creds;
2054         char *machine_password = NULL;
2055         char *machine_account = NULL;
2056         char *domain_name = NULL;
2057
2058         if (sid_check_is_domain(&domain->sid)) {
2059                 return open_internal_samr_conn(mem_ctx, domain, cli, sam_handle);
2060         }
2061
2062         result = init_dc_connection_rpc(domain);
2063         if (!NT_STATUS_IS_OK(result)) {
2064                 return result;
2065         }
2066
2067         conn = &domain->conn;
2068
2069         if (rpccli_is_connected(conn->samr_pipe)) {
2070                 goto done;
2071         }
2072
2073         TALLOC_FREE(conn->samr_pipe);
2074
2075         /*
2076          * No SAMR pipe yet. Attempt to get an NTLMSSP SPNEGO authenticated
2077          * sign and sealed pipe using the machine account password by
2078          * preference. If we can't - try schannel, if that fails, try
2079          * anonymous.
2080          */
2081
2082         if ((conn->cli->user_name[0] == '\0') ||
2083             (conn->cli->domain[0] == '\0') || 
2084             (conn->cli->password == NULL || conn->cli->password[0] == '\0'))
2085         {
2086                 result = get_trust_creds(domain, &machine_password,
2087                                          &machine_account, NULL);
2088                 if (!NT_STATUS_IS_OK(result)) {
2089                         DEBUG(10, ("cm_connect_sam: No no user available for "
2090                                    "domain %s, trying schannel\n", conn->cli->domain));
2091                         goto schannel;
2092                 }
2093                 domain_name = domain->name;
2094         } else {
2095                 machine_password = SMB_STRDUP(conn->cli->password);
2096                 machine_account = SMB_STRDUP(conn->cli->user_name);
2097                 domain_name = conn->cli->domain;
2098         }
2099
2100         if (!machine_password || !machine_account) {
2101                 result = NT_STATUS_NO_MEMORY;
2102                 goto done;
2103         }
2104
2105         /* We have an authenticated connection. Use a NTLMSSP SPNEGO
2106            authenticated SAMR pipe with sign & seal. */
2107         result = cli_rpc_pipe_open_spnego_ntlmssp(conn->cli,
2108                                                   &ndr_table_samr.syntax_id,
2109                                                   NCACN_NP,
2110                                                   DCERPC_AUTH_LEVEL_PRIVACY,
2111                                                   domain_name,
2112                                                   machine_account,
2113                                                   machine_password,
2114                                                   &conn->samr_pipe);
2115
2116         if (!NT_STATUS_IS_OK(result)) {
2117                 DEBUG(10,("cm_connect_sam: failed to connect to SAMR "
2118                           "pipe for domain %s using NTLMSSP "
2119                           "authenticated pipe: user %s\\%s. Error was "
2120                           "%s\n", domain->name, domain_name,
2121                           machine_account, nt_errstr(result)));
2122                 goto schannel;
2123         }
2124
2125         DEBUG(10,("cm_connect_sam: connected to SAMR pipe for "
2126                   "domain %s using NTLMSSP authenticated "
2127                   "pipe: user %s\\%s\n", domain->name,
2128                   domain_name, machine_account));
2129
2130         result = rpccli_samr_Connect2(conn->samr_pipe, mem_ctx,
2131                                       conn->samr_pipe->desthost,
2132                                       SEC_FLAG_MAXIMUM_ALLOWED,
2133                                       &conn->sam_connect_handle);
2134         if (NT_STATUS_IS_OK(result)) {
2135                 goto open_domain;
2136         }
2137         DEBUG(10,("cm_connect_sam: ntlmssp-sealed rpccli_samr_Connect2 "
2138                   "failed for domain %s, error was %s. Trying schannel\n",
2139                   domain->name, nt_errstr(result) ));
2140         TALLOC_FREE(conn->samr_pipe);
2141
2142  schannel:
2143
2144         /* Fall back to schannel if it's a W2K pre-SP1 box. */
2145
2146         result = cm_get_schannel_creds(domain, &p_creds);
2147         if (!NT_STATUS_IS_OK(result)) {
2148                 /* If this call fails - conn->cli can now be NULL ! */
2149                 DEBUG(10, ("cm_connect_sam: Could not get schannel auth info "
2150                            "for domain %s (error %s), trying anon\n",
2151                         domain->name,
2152                         nt_errstr(result) ));
2153                 goto anonymous;
2154         }
2155         result = cli_rpc_pipe_open_schannel_with_key
2156                 (conn->cli, &ndr_table_samr.syntax_id, NCACN_NP,
2157                  DCERPC_AUTH_LEVEL_PRIVACY,
2158                  domain->name, &p_creds, &conn->samr_pipe);
2159
2160         if (!NT_STATUS_IS_OK(result)) {
2161                 DEBUG(10,("cm_connect_sam: failed to connect to SAMR pipe for "
2162                           "domain %s using schannel. Error was %s\n",
2163                           domain->name, nt_errstr(result) ));
2164                 goto anonymous;
2165         }
2166         DEBUG(10,("cm_connect_sam: connected to SAMR pipe for domain %s using "
2167                   "schannel.\n", domain->name ));
2168
2169         result = rpccli_samr_Connect2(conn->samr_pipe, mem_ctx,
2170                                       conn->samr_pipe->desthost,
2171                                       SEC_FLAG_MAXIMUM_ALLOWED,
2172                                       &conn->sam_connect_handle);
2173         if (NT_STATUS_IS_OK(result)) {
2174                 goto open_domain;
2175         }
2176         DEBUG(10,("cm_connect_sam: schannel-sealed rpccli_samr_Connect2 failed "
2177                   "for domain %s, error was %s. Trying anonymous\n",
2178                   domain->name, nt_errstr(result) ));
2179         TALLOC_FREE(conn->samr_pipe);
2180
2181  anonymous:
2182
2183         /* Finally fall back to anonymous. */
2184         result = cli_rpc_pipe_open_noauth(conn->cli, &ndr_table_samr.syntax_id,
2185                                           &conn->samr_pipe);
2186
2187         if (!NT_STATUS_IS_OK(result)) {
2188                 goto done;
2189         }
2190
2191         result = rpccli_samr_Connect2(conn->samr_pipe, mem_ctx,
2192                                       conn->samr_pipe->desthost,
2193                                       SEC_FLAG_MAXIMUM_ALLOWED,
2194                                       &conn->sam_connect_handle);
2195         if (!NT_STATUS_IS_OK(result)) {
2196                 DEBUG(10,("cm_connect_sam: rpccli_samr_Connect2 failed "
2197                           "for domain %s Error was %s\n",
2198                           domain->name, nt_errstr(result) ));
2199                 goto done;
2200         }
2201
2202  open_domain:
2203         result = rpccli_samr_OpenDomain(conn->samr_pipe,
2204                                         mem_ctx,
2205                                         &conn->sam_connect_handle,
2206                                         SEC_FLAG_MAXIMUM_ALLOWED,
2207                                         &domain->sid,
2208                                         &conn->sam_domain_handle);
2209
2210  done:
2211
2212         if (NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED)) {
2213                 /*
2214                  * if we got access denied, we might just have no access rights
2215                  * to talk to the remote samr server server (e.g. when we are a
2216                  * PDC and we are connecting a w2k8 pdc via an interdomain
2217                  * trust). In that case do not invalidate the whole connection
2218                  * stack
2219                  */
2220                 TALLOC_FREE(conn->samr_pipe);
2221                 ZERO_STRUCT(conn->sam_domain_handle);
2222                 return result;
2223         } else if (!NT_STATUS_IS_OK(result)) {
2224                 invalidate_cm_connection(conn);
2225                 return result;
2226         }
2227
2228         *cli = conn->samr_pipe;
2229         *sam_handle = conn->sam_domain_handle;
2230         SAFE_FREE(machine_password);
2231         SAFE_FREE(machine_account);
2232         return result;
2233 }
2234
2235 /**********************************************************************
2236  open an schanneld ncacn_ip_tcp connection to LSA
2237 ***********************************************************************/
2238
2239 NTSTATUS cm_connect_lsa_tcp(struct winbindd_domain *domain,
2240                             TALLOC_CTX *mem_ctx,
2241                             struct rpc_pipe_client **cli)
2242 {
2243         struct winbindd_cm_conn *conn;
2244         struct netlogon_creds_CredentialState *creds;
2245         NTSTATUS status;
2246
2247         DEBUG(10,("cm_connect_lsa_tcp\n"));
2248
2249         status = init_dc_connection_rpc(domain);
2250         if (!NT_STATUS_IS_OK(status)) {
2251                 return status;
2252         }
2253
2254         conn = &domain->conn;
2255
2256         if (conn->lsa_pipe_tcp &&
2257             conn->lsa_pipe_tcp->transport->transport == NCACN_IP_TCP &&
2258             conn->lsa_pipe_tcp->auth->auth_level == DCERPC_AUTH_LEVEL_PRIVACY &&
2259             rpccli_is_connected(conn->lsa_pipe_tcp)) {
2260                 goto done;
2261         }
2262
2263         TALLOC_FREE(conn->lsa_pipe_tcp);
2264
2265         status = cm_get_schannel_creds(domain, &creds);
2266         if (!NT_STATUS_IS_OK(status)) {
2267                 goto done;
2268         }
2269
2270         status = cli_rpc_pipe_open_schannel_with_key(conn->cli,
2271                                                      &ndr_table_lsarpc.syntax_id,
2272                                                      NCACN_IP_TCP,
2273                                                      DCERPC_AUTH_LEVEL_PRIVACY,
2274                                                      domain->name,
2275                                                      &creds,
2276                                                      &conn->lsa_pipe_tcp);
2277         if (!NT_STATUS_IS_OK(status)) {
2278                 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key failed: %s\n",
2279                         nt_errstr(status)));
2280                 goto done;
2281         }
2282
2283  done:
2284         if (!NT_STATUS_IS_OK(status)) {
2285                 TALLOC_FREE(conn->lsa_pipe_tcp);
2286                 return status;
2287         }
2288
2289         *cli = conn->lsa_pipe_tcp;
2290
2291         return status;
2292 }
2293
2294 NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
2295                         struct rpc_pipe_client **cli, struct policy_handle *lsa_policy)
2296 {
2297         struct winbindd_cm_conn *conn;
2298         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2299         struct netlogon_creds_CredentialState *p_creds;
2300
2301         result = init_dc_connection_rpc(domain);
2302         if (!NT_STATUS_IS_OK(result))
2303                 return result;
2304
2305         conn = &domain->conn;
2306
2307         if (rpccli_is_connected(conn->lsa_pipe)) {
2308                 goto done;
2309         }
2310
2311         TALLOC_FREE(conn->lsa_pipe);
2312
2313         if ((conn->cli->user_name[0] == '\0') ||
2314             (conn->cli->domain[0] == '\0') || 
2315             (conn->cli->password == NULL || conn->cli->password[0] == '\0')) {
2316                 DEBUG(10, ("cm_connect_lsa: No no user available for "
2317                            "domain %s, trying schannel\n", conn->cli->domain));
2318                 goto schannel;
2319         }
2320
2321         /* We have an authenticated connection. Use a NTLMSSP SPNEGO
2322          * authenticated LSA pipe with sign & seal. */
2323         result = cli_rpc_pipe_open_spnego_ntlmssp
2324                 (conn->cli, &ndr_table_lsarpc.syntax_id, NCACN_NP,
2325                  DCERPC_AUTH_LEVEL_PRIVACY,
2326                  conn->cli->domain, conn->cli->user_name, conn->cli->password,
2327                  &conn->lsa_pipe);
2328
2329         if (!NT_STATUS_IS_OK(result)) {
2330                 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
2331                           "domain %s using NTLMSSP authenticated pipe: user "
2332                           "%s\\%s. Error was %s. Trying schannel.\n",
2333                           domain->name, conn->cli->domain,
2334                           conn->cli->user_name, nt_errstr(result)));
2335                 goto schannel;
2336         }
2337
2338         DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
2339                   "NTLMSSP authenticated pipe: user %s\\%s\n",
2340                   domain->name, conn->cli->domain, conn->cli->user_name ));
2341
2342         result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2343                                         SEC_FLAG_MAXIMUM_ALLOWED,
2344                                         &conn->lsa_policy);
2345         if (NT_STATUS_IS_OK(result)) {
2346                 goto done;
2347         }
2348
2349         DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
2350                   "schannel\n"));
2351
2352         TALLOC_FREE(conn->lsa_pipe);
2353
2354  schannel:
2355
2356         /* Fall back to schannel if it's a W2K pre-SP1 box. */
2357
2358         result = cm_get_schannel_creds(domain, &p_creds);
2359         if (!NT_STATUS_IS_OK(result)) {
2360                 /* If this call fails - conn->cli can now be NULL ! */
2361                 DEBUG(10, ("cm_connect_lsa: Could not get schannel auth info "
2362                            "for domain %s (error %s), trying anon\n",
2363                         domain->name,
2364                         nt_errstr(result) ));
2365                 goto anonymous;
2366         }
2367         result = cli_rpc_pipe_open_schannel_with_key
2368                 (conn->cli, &ndr_table_lsarpc.syntax_id, NCACN_NP,
2369                  DCERPC_AUTH_LEVEL_PRIVACY,
2370                  domain->name, &p_creds, &conn->lsa_pipe);
2371
2372         if (!NT_STATUS_IS_OK(result)) {
2373                 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
2374                           "domain %s using schannel. Error was %s\n",
2375                           domain->name, nt_errstr(result) ));
2376                 goto anonymous;
2377         }
2378         DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
2379                   "schannel.\n", domain->name ));
2380
2381         result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2382                                         SEC_FLAG_MAXIMUM_ALLOWED,
2383                                         &conn->lsa_policy);
2384         if (NT_STATUS_IS_OK(result)) {
2385                 goto done;
2386         }
2387
2388         DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
2389                   "anonymous\n"));
2390
2391         TALLOC_FREE(conn->lsa_pipe);
2392
2393  anonymous:
2394
2395         result = cli_rpc_pipe_open_noauth(conn->cli,
2396                                           &ndr_table_lsarpc.syntax_id,
2397                                           &conn->lsa_pipe);
2398         if (!NT_STATUS_IS_OK(result)) {
2399                 result = NT_STATUS_PIPE_NOT_AVAILABLE;
2400                 goto done;
2401         }
2402
2403         result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2404                                         SEC_FLAG_MAXIMUM_ALLOWED,
2405                                         &conn->lsa_policy);
2406  done:
2407         if (!NT_STATUS_IS_OK(result)) {
2408                 invalidate_cm_connection(conn);
2409                 return result;
2410         }
2411
2412         *cli = conn->lsa_pipe;
2413         *lsa_policy = conn->lsa_policy;
2414         return result;
2415 }
2416
2417 /****************************************************************************
2418  Open the netlogon pipe to this DC. Use schannel if specified in client conf.
2419  session key stored in conn->netlogon_pipe->dc->sess_key.
2420 ****************************************************************************/
2421
2422 NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
2423                              struct rpc_pipe_client **cli)
2424 {
2425         struct winbindd_cm_conn *conn;
2426         NTSTATUS result;
2427
2428         uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
2429         uint8  mach_pwd[16];
2430         enum netr_SchannelType sec_chan_type;
2431         const char *account_name;
2432         struct rpc_pipe_client *netlogon_pipe = NULL;
2433
2434         *cli = NULL;
2435
2436         result = init_dc_connection_rpc(domain);
2437         if (!NT_STATUS_IS_OK(result)) {
2438                 return result;
2439         }
2440
2441         conn = &domain->conn;
2442
2443         if (rpccli_is_connected(conn->netlogon_pipe)) {
2444                 *cli = conn->netlogon_pipe;
2445                 return NT_STATUS_OK;
2446         }
2447
2448         TALLOC_FREE(conn->netlogon_pipe);
2449
2450         result = cli_rpc_pipe_open_noauth(conn->cli,
2451                                           &ndr_table_netlogon.syntax_id,
2452                                           &netlogon_pipe);
2453         if (!NT_STATUS_IS_OK(result)) {
2454                 return result;
2455         }
2456
2457         if ((!IS_DC) && (!domain->primary)) {
2458                 /* Clear the schannel request bit and drop down */
2459                 neg_flags &= ~NETLOGON_NEG_SCHANNEL;            
2460                 goto no_schannel;
2461         }
2462
2463         if (lp_client_schannel() != False) {
2464                 neg_flags |= NETLOGON_NEG_SCHANNEL;
2465         }
2466
2467         if (!get_trust_pw_hash(domain->name, mach_pwd, &account_name,
2468                                &sec_chan_type))
2469         {
2470                 TALLOC_FREE(netlogon_pipe);
2471                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2472         }
2473
2474         result = rpccli_netlogon_setup_creds(
2475                  netlogon_pipe,
2476                  domain->dcname, /* server name. */
2477                  domain->name,   /* domain name */
2478                  global_myname(), /* client name */
2479                  account_name,   /* machine account */
2480                  mach_pwd,       /* machine password */
2481                  sec_chan_type,  /* from get_trust_pw */
2482                  &neg_flags);
2483
2484         if (!NT_STATUS_IS_OK(result)) {
2485                 TALLOC_FREE(netlogon_pipe);
2486                 return result;
2487         }
2488
2489         if ((lp_client_schannel() == True) &&
2490                         ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
2491                 DEBUG(3, ("Server did not offer schannel\n"));
2492                 TALLOC_FREE(netlogon_pipe);
2493                 return NT_STATUS_ACCESS_DENIED;
2494         }
2495
2496  no_schannel:
2497         if ((lp_client_schannel() == False) ||
2498                         ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
2499                 /*
2500                  * NetSamLogonEx only works for schannel
2501                  */
2502                 domain->can_do_samlogon_ex = False;
2503
2504                 /* We're done - just keep the existing connection to NETLOGON
2505                  * open */
2506                 conn->netlogon_pipe = netlogon_pipe;
2507                 *cli = conn->netlogon_pipe;
2508                 return NT_STATUS_OK;
2509         }
2510
2511         /* Using the credentials from the first pipe, open a signed and sealed
2512            second netlogon pipe. The session key is stored in the schannel
2513            part of the new pipe auth struct.
2514         */
2515
2516         result = cli_rpc_pipe_open_schannel_with_key(
2517                 conn->cli, &ndr_table_netlogon.syntax_id, NCACN_NP,
2518                 DCERPC_AUTH_LEVEL_PRIVACY, domain->name, &netlogon_pipe->dc,
2519                 &conn->netlogon_pipe);
2520
2521         /* We can now close the initial netlogon pipe. */
2522         TALLOC_FREE(netlogon_pipe);
2523
2524         if (!NT_STATUS_IS_OK(result)) {
2525                 DEBUG(3, ("Could not open schannel'ed NETLOGON pipe. Error "
2526                           "was %s\n", nt_errstr(result)));
2527
2528                 invalidate_cm_connection(conn);
2529                 return result;
2530         }
2531
2532         /*
2533          * Always try netr_LogonSamLogonEx. We will fall back for NT4
2534          * which gives DCERPC_FAULT_OP_RNG_ERROR (function not
2535          * supported). We used to only try SamLogonEx for AD, but
2536          * Samba DCs can also do it. And because we don't distinguish
2537          * between Samba and NT4, always try it once.
2538          */
2539         domain->can_do_samlogon_ex = true;
2540
2541         *cli = conn->netlogon_pipe;
2542         return NT_STATUS_OK;
2543 }
2544
2545 void winbind_msg_ip_dropped(struct messaging_context *msg_ctx,
2546                             void *private_data,
2547                             uint32_t msg_type,
2548                             struct server_id server_id,
2549                             DATA_BLOB *data)
2550 {
2551         struct winbindd_domain *domain;
2552
2553         if ((data == NULL)
2554             || (data->data == NULL)
2555             || (data->length == 0)
2556             || (data->data[data->length-1] != '\0')
2557             || !is_ipaddress((char *)data->data)) {
2558                 DEBUG(1, ("invalid msg_ip_dropped message\n"));
2559                 return;
2560         }
2561         for (domain = domain_list(); domain != NULL; domain = domain->next) {
2562                 char sockaddr[INET6_ADDRSTRLEN];
2563                 if (domain->conn.cli == NULL) {
2564                         continue;
2565                 }
2566                 if (domain->conn.cli->fd == -1) {
2567                         continue;
2568                 }
2569                 client_socket_addr(domain->conn.cli->fd, sockaddr,
2570                                    sizeof(sockaddr));
2571                 if (strequal(sockaddr, (char *)data->data)) {
2572                         close(domain->conn.cli->fd);
2573                         domain->conn.cli->fd = -1;
2574                 }
2575         }
2576 }