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