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