s3-winbindd: Allow winbindd to connect over SMB2 to servers
[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_winbindd_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_domain *domain)
1840 {
1841         NTSTATUS result;
1842         struct winbindd_cm_conn *conn = &domain->conn;
1843
1844         /* We're closing down a possibly dead
1845            connection. Don't have impossibly long (10s) timeouts. */
1846
1847         if (conn->cli) {
1848                 cli_set_timeout(conn->cli, 1000); /* 1 second. */
1849         }
1850
1851         if (conn->samr_pipe != NULL) {
1852                 if (is_valid_policy_hnd(&conn->sam_connect_handle)) {
1853                         dcerpc_samr_Close(conn->samr_pipe->binding_handle,
1854                                           talloc_tos(),
1855                                           &conn->sam_connect_handle,
1856                                           &result);
1857                 }
1858                 TALLOC_FREE(conn->samr_pipe);
1859                 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1860                 if (conn->cli) {
1861                         cli_set_timeout(conn->cli, 500);
1862                 }
1863         }
1864
1865         if (conn->lsa_pipe != NULL) {
1866                 if (is_valid_policy_hnd(&conn->lsa_policy)) {
1867                         dcerpc_lsa_Close(conn->lsa_pipe->binding_handle,
1868                                          talloc_tos(),
1869                                          &conn->lsa_policy,
1870                                          &result);
1871                 }
1872                 TALLOC_FREE(conn->lsa_pipe);
1873                 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1874                 if (conn->cli) {
1875                         cli_set_timeout(conn->cli, 500);
1876                 }
1877         }
1878
1879         if (conn->lsa_pipe_tcp != NULL) {
1880                 if (is_valid_policy_hnd(&conn->lsa_policy)) {
1881                         dcerpc_lsa_Close(conn->lsa_pipe_tcp->binding_handle,
1882                                          talloc_tos(),
1883                                          &conn->lsa_policy,
1884                                          &result);
1885                 }
1886                 TALLOC_FREE(conn->lsa_pipe_tcp);
1887                 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1888                 if (conn->cli) {
1889                         cli_set_timeout(conn->cli, 500);
1890                 }
1891         }
1892
1893         if (conn->netlogon_pipe != NULL) {
1894                 TALLOC_FREE(conn->netlogon_pipe);
1895                 /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1896                 if (conn->cli) {
1897                         cli_set_timeout(conn->cli, 500);
1898                 }
1899         }
1900
1901         conn->auth_level = DCERPC_AUTH_LEVEL_PRIVACY;
1902         conn->netlogon_force_reauth = false;
1903         conn->netlogon_flags = 0;
1904         TALLOC_FREE(conn->netlogon_creds);
1905
1906         if (conn->cli) {
1907                 cli_shutdown(conn->cli);
1908         }
1909
1910         conn->cli = NULL;
1911 }
1912
1913 void close_conns_after_fork(void)
1914 {
1915         struct winbindd_domain *domain;
1916         struct winbindd_cli_state *cli_state;
1917
1918         for (domain = domain_list(); domain; domain = domain->next) {
1919                 /*
1920                  * first close the low level SMB TCP connection
1921                  * so that we don't generate any SMBclose
1922                  * requests in invalidate_cm_connection()
1923                  */
1924                 if (cli_state_is_connected(domain->conn.cli)) {
1925                         smbXcli_conn_disconnect(domain->conn.cli->conn, NT_STATUS_OK);
1926                 }
1927
1928                 invalidate_cm_connection(domain);
1929         }
1930
1931         for (cli_state = winbindd_client_list();
1932              cli_state != NULL;
1933              cli_state = cli_state->next) {
1934                 if (cli_state->sock >= 0) {
1935                         close(cli_state->sock);
1936                         cli_state->sock = -1;
1937                 }
1938         }
1939 }
1940
1941 static bool connection_ok(struct winbindd_domain *domain)
1942 {
1943         bool ok;
1944
1945         ok = cli_state_is_connected(domain->conn.cli);
1946         if (!ok) {
1947                 DEBUG(3, ("connection_ok: Connection to %s for domain %s is not connected\n",
1948                           domain->dcname, domain->name));
1949                 return False;
1950         }
1951
1952         if (domain->online == False) {
1953                 DEBUG(3, ("connection_ok: Domain %s is offline\n", domain->name));
1954                 return False;
1955         }
1956
1957         return True;
1958 }
1959
1960 /* Initialize a new connection up to the RPC BIND.
1961    Bypass online status check so always does network calls. */
1962
1963 static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain, bool need_rw_dc)
1964 {
1965         NTSTATUS result;
1966         bool skip_connection = domain->internal;
1967         if (need_rw_dc && domain->rodc) {
1968                 skip_connection = false;
1969         }
1970
1971         /* Internal connections never use the network. */
1972         if (dom_sid_equal(&domain->sid, &global_sid_Builtin)) {
1973                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1974         }
1975
1976         /* Still ask the internal LSA and SAMR server about the local domain */
1977         if (skip_connection || connection_ok(domain)) {
1978                 if (!domain->initialized) {
1979                         set_dc_type_and_flags(domain);
1980                 }
1981                 return NT_STATUS_OK;
1982         }
1983
1984         invalidate_cm_connection(domain);
1985
1986         if (!domain->primary && !domain->initialized) {
1987                 /*
1988                  * Before we connect to a trust, work out if it is an
1989                  * AD domain by asking our own domain.
1990                  */
1991                 set_dc_type_and_flags_trustinfo(domain);
1992         }
1993
1994         result = cm_open_connection(domain, &domain->conn);
1995
1996         if (NT_STATUS_IS_OK(result) && !domain->initialized) {
1997                 set_dc_type_and_flags(domain);
1998         }
1999
2000         return result;
2001 }
2002
2003 NTSTATUS init_dc_connection(struct winbindd_domain *domain, bool need_rw_dc)
2004 {
2005         if (dom_sid_equal(&domain->sid, &global_sid_Builtin)) {
2006                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
2007         }
2008
2009         if (domain->initialized && !domain->online) {
2010                 /* We check for online status elsewhere. */
2011                 return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
2012         }
2013
2014         return init_dc_connection_network(domain, need_rw_dc);
2015 }
2016
2017 static NTSTATUS init_dc_connection_rpc(struct winbindd_domain *domain, bool need_rw_dc)
2018 {
2019         NTSTATUS status;
2020
2021         status = init_dc_connection(domain, need_rw_dc);
2022         if (!NT_STATUS_IS_OK(status)) {
2023                 return status;
2024         }
2025
2026         if (!domain->internal && domain->conn.cli == NULL) {
2027                 /* happens for trusted domains without inbound trust */
2028                 return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
2029         }
2030
2031         return NT_STATUS_OK;
2032 }
2033
2034 /******************************************************************************
2035  Set the trust flags (direction and forest location) for a domain
2036 ******************************************************************************/
2037
2038 static bool set_dc_type_and_flags_trustinfo( struct winbindd_domain *domain )
2039 {
2040         struct winbindd_domain *our_domain;
2041         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2042         WERROR werr;
2043         struct netr_DomainTrustList trusts;
2044         int i;
2045         uint32 flags = (NETR_TRUST_FLAG_IN_FOREST |
2046                         NETR_TRUST_FLAG_OUTBOUND |
2047                         NETR_TRUST_FLAG_INBOUND);
2048         struct rpc_pipe_client *cli;
2049         TALLOC_CTX *mem_ctx = NULL;
2050         struct dcerpc_binding_handle *b;
2051
2052         DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s\n", domain->name ));
2053
2054         /* Our primary domain doesn't need to worry about trust flags.
2055            Force it to go through the network setup */
2056         if ( domain->primary ) {                
2057                 return False;           
2058         }
2059
2060         mem_ctx = talloc_stackframe();
2061         our_domain = find_our_domain();
2062         if (our_domain->internal) {
2063                 result = init_dc_connection(our_domain, false);
2064                 if (!NT_STATUS_IS_OK(result)) {
2065                         DEBUG(3,("set_dc_type_and_flags_trustinfo: "
2066                                  "Not able to make a connection to our domain: %s\n",
2067                                   nt_errstr(result)));
2068                         TALLOC_FREE(mem_ctx);
2069                         return false;
2070                 }
2071         }
2072
2073         /* This won't work unless our domain is AD */
2074         if ( !our_domain->active_directory ) {
2075                 TALLOC_FREE(mem_ctx);
2076                 return False;
2077         }
2078
2079         if (our_domain->internal) {
2080                 result = wb_open_internal_pipe(mem_ctx, &ndr_table_netlogon, &cli);
2081         } else if (!connection_ok(our_domain)) {
2082                 DEBUG(3,("set_dc_type_and_flags_trustinfo: "
2083                          "No connection to our domain!\n"));
2084                 TALLOC_FREE(mem_ctx);
2085                 return False;
2086         } else {
2087                 result = cm_connect_netlogon(our_domain, &cli);
2088         }
2089
2090         if (!NT_STATUS_IS_OK(result)) {
2091                 DEBUG(5, ("set_dc_type_and_flags_trustinfo: Could not open "
2092                           "a connection to %s for PIPE_NETLOGON (%s)\n", 
2093                           domain->name, nt_errstr(result)));
2094                 TALLOC_FREE(mem_ctx);
2095                 return False;
2096         }
2097         b = cli->binding_handle;
2098
2099         /* Use DsEnumerateDomainTrusts to get us the trust direction and type. */
2100         result = dcerpc_netr_DsrEnumerateDomainTrusts(b, mem_ctx,
2101                                                       cli->desthost,
2102                                                       flags,
2103                                                       &trusts,
2104                                                       &werr);
2105         if (!NT_STATUS_IS_OK(result)) {
2106                 DEBUG(0,("set_dc_type_and_flags_trustinfo: "
2107                         "failed to query trusted domain list: %s\n",
2108                         nt_errstr(result)));
2109                 TALLOC_FREE(mem_ctx);
2110                 return false;
2111         }
2112         if (!W_ERROR_IS_OK(werr)) {
2113                 DEBUG(0,("set_dc_type_and_flags_trustinfo: "
2114                         "failed to query trusted domain list: %s\n",
2115                         win_errstr(werr)));
2116                 TALLOC_FREE(mem_ctx);
2117                 return false;
2118         }
2119
2120         /* Now find the domain name and get the flags */
2121
2122         for ( i=0; i<trusts.count; i++ ) {
2123                 if ( strequal( domain->name, trusts.array[i].netbios_name) ) {
2124                         domain->domain_flags          = trusts.array[i].trust_flags;
2125                         domain->domain_type           = trusts.array[i].trust_type;
2126                         domain->domain_trust_attribs  = trusts.array[i].trust_attributes;
2127
2128                         if ( domain->domain_type == LSA_TRUST_TYPE_UPLEVEL )
2129                                 domain->active_directory = True;
2130
2131                         /* This flag is only set if the domain is *our* 
2132                            primary domain and the primary domain is in
2133                            native mode */
2134
2135                         domain->native_mode = (domain->domain_flags & NETR_TRUST_FLAG_NATIVE);
2136
2137                         DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s is %sin "
2138                                   "native mode.\n", domain->name, 
2139                                   domain->native_mode ? "" : "NOT "));
2140
2141                         DEBUG(5,("set_dc_type_and_flags_trustinfo: domain %s is %s"
2142                                  "running active directory.\n", domain->name, 
2143                                  domain->active_directory ? "" : "NOT "));
2144
2145                         domain->can_do_ncacn_ip_tcp = domain->active_directory;
2146
2147                         domain->initialized = True;
2148
2149                         break;
2150                 }               
2151         }
2152
2153         TALLOC_FREE(mem_ctx);
2154
2155         return domain->initialized;     
2156 }
2157
2158 /******************************************************************************
2159  We can 'sense' certain things about the DC by it's replies to certain
2160  questions.
2161
2162  This tells us if this particular remote server is Active Directory, and if it
2163  is native mode.
2164 ******************************************************************************/
2165
2166 static void set_dc_type_and_flags_connect( struct winbindd_domain *domain )
2167 {
2168         NTSTATUS status, result;
2169         WERROR werr;
2170         TALLOC_CTX              *mem_ctx = NULL;
2171         struct rpc_pipe_client  *cli = NULL;
2172         struct policy_handle pol;
2173         union dssetup_DsRoleInfo info;
2174         union lsa_PolicyInformation *lsa_info = NULL;
2175
2176         if (!domain->internal && !connection_ok(domain)) {
2177                 return;
2178         }
2179
2180         mem_ctx = talloc_init("set_dc_type_and_flags on domain %s\n",
2181                               domain->name);
2182         if (!mem_ctx) {
2183                 DEBUG(1, ("set_dc_type_and_flags_connect: talloc_init() failed\n"));
2184                 return;
2185         }
2186
2187         DEBUG(5, ("set_dc_type_and_flags_connect: domain %s\n", domain->name ));
2188
2189         if (domain->internal) {
2190                 status = wb_open_internal_pipe(mem_ctx,
2191                                                &ndr_table_dssetup,
2192                                                &cli);
2193         } else {
2194                 status = cli_rpc_pipe_open_noauth(domain->conn.cli,
2195                                                   &ndr_table_dssetup,
2196                                                   &cli);
2197         }
2198
2199         if (!NT_STATUS_IS_OK(status)) {
2200                 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
2201                           "PI_DSSETUP on domain %s: (%s)\n",
2202                           domain->name, nt_errstr(status)));
2203
2204                 /* if this is just a non-AD domain we need to continue
2205                  * identifying so that we can in the end return with
2206                  * domain->initialized = True - gd */
2207
2208                 goto no_dssetup;
2209         }
2210
2211         status = dcerpc_dssetup_DsRoleGetPrimaryDomainInformation(cli->binding_handle, mem_ctx,
2212                                                                   DS_ROLE_BASIC_INFORMATION,
2213                                                                   &info,
2214                                                                   &werr);
2215         TALLOC_FREE(cli);
2216
2217         if (NT_STATUS_IS_OK(status)) {
2218                 result = werror_to_ntstatus(werr);
2219         }
2220         if (!NT_STATUS_IS_OK(status)) {
2221                 DEBUG(5, ("set_dc_type_and_flags_connect: rpccli_ds_getprimarydominfo "
2222                           "on domain %s failed: (%s)\n",
2223                           domain->name, nt_errstr(status)));
2224
2225                 /* older samba3 DCs will return DCERPC_FAULT_OP_RNG_ERROR for
2226                  * every opcode on the DSSETUP pipe, continue with
2227                  * no_dssetup mode here as well to get domain->initialized
2228                  * set - gd */
2229
2230                 if (NT_STATUS_EQUAL(status, NT_STATUS_RPC_PROCNUM_OUT_OF_RANGE)) {
2231                         goto no_dssetup;
2232                 }
2233
2234                 TALLOC_FREE(mem_ctx);
2235                 return;
2236         }
2237
2238         if ((info.basic.flags & DS_ROLE_PRIMARY_DS_RUNNING) &&
2239             !(info.basic.flags & DS_ROLE_PRIMARY_DS_MIXED_MODE)) {
2240                 domain->native_mode = True;
2241         } else {
2242                 domain->native_mode = False;
2243         }
2244
2245 no_dssetup:
2246         if (domain->internal) {
2247                 status = wb_open_internal_pipe(mem_ctx,
2248                                                &ndr_table_lsarpc,
2249                                                &cli);
2250         } else {
2251                 status = cli_rpc_pipe_open_noauth(domain->conn.cli,
2252                                                   &ndr_table_lsarpc, &cli);
2253         }
2254         if (!NT_STATUS_IS_OK(status)) {
2255                 DEBUG(5, ("set_dc_type_and_flags_connect: Could not bind to "
2256                           "PI_LSARPC on domain %s: (%s)\n",
2257                           domain->name, nt_errstr(status)));
2258                 TALLOC_FREE(cli);
2259                 TALLOC_FREE(mem_ctx);
2260                 return;
2261         }
2262
2263         status = rpccli_lsa_open_policy2(cli, mem_ctx, True,
2264                                          SEC_FLAG_MAXIMUM_ALLOWED, &pol);
2265
2266         if (NT_STATUS_IS_OK(status)) {
2267                 /* This particular query is exactly what Win2k clients use 
2268                    to determine that the DC is active directory */
2269                 status = dcerpc_lsa_QueryInfoPolicy2(cli->binding_handle, mem_ctx,
2270                                                      &pol,
2271                                                      LSA_POLICY_INFO_DNS,
2272                                                      &lsa_info,
2273                                                      &result);
2274         }
2275
2276         if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2277                 domain->active_directory = True;
2278
2279                 if (lsa_info->dns.name.string) {
2280                         if (!strequal(domain->name, lsa_info->dns.name.string))
2281                         {
2282                                 DEBUG(1, ("set_dc_type_and_flags_connect: DC "
2283                                           "for domain %s claimed it was a DC "
2284                                           "for domain %s, refusing to "
2285                                           "initialize\n",
2286                                           domain->name,
2287                                           lsa_info->dns.name.string));
2288                                 TALLOC_FREE(cli);
2289                                 TALLOC_FREE(mem_ctx);
2290                                 return;
2291                         }
2292                         talloc_free(domain->name);
2293                         domain->name = talloc_strdup(domain,
2294                                                      lsa_info->dns.name.string);
2295                         if (domain->name == NULL) {
2296                                 goto done;
2297                         }
2298                 }
2299
2300                 if (lsa_info->dns.dns_domain.string) {
2301                         if (domain->alt_name != NULL &&
2302                             !strequal(domain->alt_name,
2303                                       lsa_info->dns.dns_domain.string))
2304                         {
2305                                 DEBUG(1, ("set_dc_type_and_flags_connect: DC "
2306                                           "for domain %s (%s) claimed it was "
2307                                           "a DC for domain %s, refusing to "
2308                                           "initialize\n",
2309                                           domain->alt_name, domain->name,
2310                                           lsa_info->dns.dns_domain.string));
2311                                 TALLOC_FREE(cli);
2312                                 TALLOC_FREE(mem_ctx);
2313                                 return;
2314                         }
2315                         talloc_free(domain->alt_name);
2316                         domain->alt_name =
2317                                 talloc_strdup(domain,
2318                                               lsa_info->dns.dns_domain.string);
2319                         if (domain->alt_name == NULL) {
2320                                 goto done;
2321                         }
2322                 }
2323
2324                 /* See if we can set some domain trust flags about
2325                    ourself */
2326
2327                 if (lsa_info->dns.dns_forest.string) {
2328                         talloc_free(domain->forest_name);
2329                         domain->forest_name =
2330                                 talloc_strdup(domain,
2331                                               lsa_info->dns.dns_forest.string);
2332                         if (domain->forest_name == NULL) {
2333                                 goto done;
2334                         }
2335
2336                         if (strequal(domain->forest_name, domain->alt_name)) {
2337                                 domain->domain_flags |= NETR_TRUST_FLAG_TREEROOT;
2338                         }
2339                 }
2340
2341                 if (lsa_info->dns.sid) {
2342                         if (!is_null_sid(&domain->sid) &&
2343                             !dom_sid_equal(&domain->sid,
2344                                            lsa_info->dns.sid))
2345                         {
2346                                 DEBUG(1, ("set_dc_type_and_flags_connect: DC "
2347                                           "for domain %s (%s) claimed it was "
2348                                           "a DC for domain %s, refusing to "
2349                                           "initialize\n",
2350                                           dom_sid_string(talloc_tos(),
2351                                                          &domain->sid),
2352                                           domain->name,
2353                                           dom_sid_string(talloc_tos(),
2354                                                          lsa_info->dns.sid)));
2355                                 TALLOC_FREE(cli);
2356                                 TALLOC_FREE(mem_ctx);
2357                                 return;
2358                         }
2359                         sid_copy(&domain->sid, lsa_info->dns.sid);
2360                 }
2361         } else {
2362                 domain->active_directory = False;
2363
2364                 status = rpccli_lsa_open_policy(cli, mem_ctx, True,
2365                                                 SEC_FLAG_MAXIMUM_ALLOWED,
2366                                                 &pol);
2367
2368                 if (!NT_STATUS_IS_OK(status)) {
2369                         goto done;
2370                 }
2371
2372                 status = dcerpc_lsa_QueryInfoPolicy(cli->binding_handle, mem_ctx,
2373                                                     &pol,
2374                                                     LSA_POLICY_INFO_ACCOUNT_DOMAIN,
2375                                                     &lsa_info,
2376                                                     &result);
2377                 if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2378
2379                         if (lsa_info->account_domain.name.string) {
2380                                 if (!strequal(domain->name,
2381                                         lsa_info->account_domain.name.string))
2382                                 {
2383                                         DEBUG(1,
2384                                               ("set_dc_type_and_flags_connect: "
2385                                                "DC for domain %s claimed it was"
2386                                                " a DC for domain %s, refusing "
2387                                                "to initialize\n", domain->name,
2388                                                lsa_info->
2389                                                 account_domain.name.string));
2390                                         TALLOC_FREE(cli);
2391                                         TALLOC_FREE(mem_ctx);
2392                                         return;
2393                                 }
2394                                 talloc_free(domain->name);
2395                                 domain->name =
2396                                         talloc_strdup(domain,
2397                                                       lsa_info->account_domain.name.string);
2398                         }
2399
2400                         if (lsa_info->account_domain.sid) {
2401                                 if (!is_null_sid(&domain->sid) &&
2402                                     !dom_sid_equal(&domain->sid,
2403                                                 lsa_info->account_domain.sid))
2404                                 {
2405                                         DEBUG(1,
2406                                               ("set_dc_type_and_flags_connect: "
2407                                                "DC for domain %s (%s) claimed "
2408                                                "it was a DC for domain %s, "
2409                                                "refusing to initialize\n",
2410                                                dom_sid_string(talloc_tos(),
2411                                                               &domain->sid),
2412                                                domain->name,
2413                                                dom_sid_string(talloc_tos(),
2414                                                 lsa_info->account_domain.sid)));
2415                                         TALLOC_FREE(cli);
2416                                         TALLOC_FREE(mem_ctx);
2417                                         return;
2418                                 }
2419                                 sid_copy(&domain->sid, lsa_info->account_domain.sid);
2420                         }
2421                 }
2422         }
2423 done:
2424
2425         DEBUG(5, ("set_dc_type_and_flags_connect: domain %s is %sin native mode.\n",
2426                   domain->name, domain->native_mode ? "" : "NOT "));
2427
2428         DEBUG(5,("set_dc_type_and_flags_connect: domain %s is %srunning active directory.\n",
2429                   domain->name, domain->active_directory ? "" : "NOT "));
2430
2431         domain->can_do_ncacn_ip_tcp = domain->active_directory;
2432
2433         TALLOC_FREE(cli);
2434
2435         TALLOC_FREE(mem_ctx);
2436
2437         domain->initialized = True;
2438 }
2439
2440 /**********************************************************************
2441  Set the domain_flags (trust attributes, domain operating modes, etc... 
2442 ***********************************************************************/
2443
2444 static void set_dc_type_and_flags( struct winbindd_domain *domain )
2445 {
2446         /* we always have to contact our primary domain */
2447
2448         if ( domain->primary || domain->internal) {
2449                 DEBUG(10,("set_dc_type_and_flags: setting up flags for "
2450                           "primary or internal domain\n"));
2451                 set_dc_type_and_flags_connect( domain );
2452                 return;         
2453         }
2454
2455         /* Use our DC to get the information if possible */
2456
2457         if ( !set_dc_type_and_flags_trustinfo( domain ) ) {
2458                 /* Otherwise, fallback to contacting the 
2459                    domain directly */
2460                 set_dc_type_and_flags_connect( domain );
2461         }
2462
2463         return;
2464 }
2465
2466
2467
2468 /**********************************************************************
2469 ***********************************************************************/
2470
2471 static NTSTATUS cm_get_schannel_creds(struct winbindd_domain *domain,
2472                                    struct netlogon_creds_cli_context **ppdc)
2473 {
2474         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2475         struct rpc_pipe_client *netlogon_pipe;
2476
2477         *ppdc = NULL;
2478
2479         if ((!IS_DC) && (!domain->primary)) {
2480                 return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
2481         }
2482
2483         if (domain->conn.netlogon_creds != NULL) {
2484                 if (!(domain->conn.netlogon_flags & NETLOGON_NEG_AUTHENTICATED_RPC)) {
2485                         return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
2486                 }
2487                 *ppdc = domain->conn.netlogon_creds;
2488                 return NT_STATUS_OK;
2489         }
2490
2491         result = cm_connect_netlogon(domain, &netlogon_pipe);
2492         if (!NT_STATUS_IS_OK(result)) {
2493                 return result;
2494         }
2495
2496         if (domain->conn.netlogon_creds == NULL) {
2497                 return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
2498         }
2499
2500         if (!(domain->conn.netlogon_flags & NETLOGON_NEG_AUTHENTICATED_RPC)) {
2501                 return NT_STATUS_TRUSTED_DOMAIN_FAILURE;
2502         }
2503
2504         *ppdc = domain->conn.netlogon_creds;
2505         return NT_STATUS_OK;
2506 }
2507
2508 NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
2509                         bool need_rw_dc,
2510                         struct rpc_pipe_client **cli, struct policy_handle *sam_handle)
2511 {
2512         struct winbindd_cm_conn *conn;
2513         NTSTATUS status, result;
2514         struct netlogon_creds_cli_context *p_creds;
2515         char *machine_password = NULL;
2516         char *machine_account = NULL;
2517         const char *domain_name = NULL;
2518
2519         if (sid_check_is_our_sam(&domain->sid)) {
2520                 if (domain->rodc == false || need_rw_dc == false) {
2521                         return open_internal_samr_conn(mem_ctx, domain, cli, sam_handle);
2522                 }
2523         }
2524
2525         status = init_dc_connection_rpc(domain, need_rw_dc);
2526         if (!NT_STATUS_IS_OK(status)) {
2527                 return status;
2528         }
2529
2530         conn = &domain->conn;
2531
2532         if (rpccli_is_connected(conn->samr_pipe)) {
2533                 goto done;
2534         }
2535
2536         TALLOC_FREE(conn->samr_pipe);
2537
2538         /*
2539          * No SAMR pipe yet. Attempt to get an NTLMSSP SPNEGO authenticated
2540          * sign and sealed pipe using the machine account password by
2541          * preference. If we can't - try schannel, if that fails, try
2542          * anonymous.
2543          */
2544
2545         if ((conn->cli->user_name[0] == '\0') ||
2546             (conn->cli->domain[0] == '\0') || 
2547             (conn->cli->password == NULL || conn->cli->password[0] == '\0'))
2548         {
2549                 status = get_trust_creds(domain, &machine_password,
2550                                          &machine_account, NULL);
2551                 if (!NT_STATUS_IS_OK(status)) {
2552                         DEBUG(10, ("cm_connect_sam: No no user available for "
2553                                    "domain %s, trying schannel\n", conn->cli->domain));
2554                         goto schannel;
2555                 }
2556                 domain_name = domain->name;
2557         } else {
2558                 machine_password = SMB_STRDUP(conn->cli->password);
2559                 machine_account = SMB_STRDUP(conn->cli->user_name);
2560                 domain_name = conn->cli->domain;
2561         }
2562
2563         if (!machine_password || !machine_account) {
2564                 status = NT_STATUS_NO_MEMORY;
2565                 goto done;
2566         }
2567
2568         /* We have an authenticated connection. Use a NTLMSSP SPNEGO
2569            authenticated SAMR pipe with sign & seal. */
2570         status = cli_rpc_pipe_open_spnego(conn->cli,
2571                                           &ndr_table_samr,
2572                                           NCACN_NP,
2573                                           GENSEC_OID_NTLMSSP,
2574                                           conn->auth_level,
2575                                           smbXcli_conn_remote_name(conn->cli->conn),
2576                                           domain_name,
2577                                           machine_account,
2578                                           machine_password,
2579                                           &conn->samr_pipe);
2580
2581         if (!NT_STATUS_IS_OK(status)) {
2582                 DEBUG(10,("cm_connect_sam: failed to connect to SAMR "
2583                           "pipe for domain %s using NTLMSSP "
2584                           "authenticated pipe: user %s\\%s. Error was "
2585                           "%s\n", domain->name, domain_name,
2586                           machine_account, nt_errstr(status)));
2587                 goto schannel;
2588         }
2589
2590         DEBUG(10,("cm_connect_sam: connected to SAMR pipe for "
2591                   "domain %s using NTLMSSP authenticated "
2592                   "pipe: user %s\\%s\n", domain->name,
2593                   domain_name, machine_account));
2594
2595         status = dcerpc_samr_Connect2(conn->samr_pipe->binding_handle, mem_ctx,
2596                                       conn->samr_pipe->desthost,
2597                                       SEC_FLAG_MAXIMUM_ALLOWED,
2598                                       &conn->sam_connect_handle,
2599                                       &result);
2600         if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2601                 goto open_domain;
2602         }
2603         if (NT_STATUS_IS_OK(status)) {
2604                 status = result;
2605         }
2606
2607         DEBUG(10,("cm_connect_sam: ntlmssp-sealed dcerpc_samr_Connect2 "
2608                   "failed for domain %s, error was %s. Trying schannel\n",
2609                   domain->name, nt_errstr(status) ));
2610         TALLOC_FREE(conn->samr_pipe);
2611
2612  schannel:
2613
2614         /* Fall back to schannel if it's a W2K pre-SP1 box. */
2615
2616         status = cm_get_schannel_creds(domain, &p_creds);
2617         if (!NT_STATUS_IS_OK(status)) {
2618                 /* If this call fails - conn->cli can now be NULL ! */
2619                 DEBUG(10, ("cm_connect_sam: Could not get schannel auth info "
2620                            "for domain %s (error %s), trying anon\n",
2621                         domain->name,
2622                         nt_errstr(status) ));
2623                 goto anonymous;
2624         }
2625         status = cli_rpc_pipe_open_schannel_with_key
2626                 (conn->cli, &ndr_table_samr, NCACN_NP,
2627                  domain->name, p_creds, &conn->samr_pipe);
2628
2629         if (!NT_STATUS_IS_OK(status)) {
2630                 DEBUG(10,("cm_connect_sam: failed to connect to SAMR pipe for "
2631                           "domain %s using schannel. Error was %s\n",
2632                           domain->name, nt_errstr(status) ));
2633                 goto anonymous;
2634         }
2635         DEBUG(10,("cm_connect_sam: connected to SAMR pipe for domain %s using "
2636                   "schannel.\n", domain->name ));
2637
2638         status = dcerpc_samr_Connect2(conn->samr_pipe->binding_handle, mem_ctx,
2639                                       conn->samr_pipe->desthost,
2640                                       SEC_FLAG_MAXIMUM_ALLOWED,
2641                                       &conn->sam_connect_handle,
2642                                       &result);
2643         if (NT_STATUS_IS_OK(status) && NT_STATUS_IS_OK(result)) {
2644                 goto open_domain;
2645         }
2646         if (NT_STATUS_IS_OK(status)) {
2647                 status = result;
2648         }
2649         DEBUG(10,("cm_connect_sam: schannel-sealed dcerpc_samr_Connect2 failed "
2650                   "for domain %s, error was %s. Trying anonymous\n",
2651                   domain->name, nt_errstr(status) ));
2652         TALLOC_FREE(conn->samr_pipe);
2653
2654  anonymous:
2655
2656         /* Finally fall back to anonymous. */
2657         if (lp_winbind_sealed_pipes() || lp_require_strong_key()) {
2658                 status = NT_STATUS_DOWNGRADE_DETECTED;
2659                 DEBUG(1, ("Unwilling to make SAMR connection to domain %s"
2660                           "without connection level security, "
2661                           "must set 'winbind sealed pipes = false' and "
2662                           "'require strong key = false' to proceed: %s\n",
2663                           domain->name, nt_errstr(status)));
2664                 goto done;
2665         }
2666         status = cli_rpc_pipe_open_noauth(conn->cli, &ndr_table_samr,
2667                                           &conn->samr_pipe);
2668
2669         if (!NT_STATUS_IS_OK(status)) {
2670                 goto done;
2671         }
2672
2673         status = dcerpc_samr_Connect2(conn->samr_pipe->binding_handle, mem_ctx,
2674                                       conn->samr_pipe->desthost,
2675                                       SEC_FLAG_MAXIMUM_ALLOWED,
2676                                       &conn->sam_connect_handle,
2677                                       &result);
2678         if (!NT_STATUS_IS_OK(status)) {
2679                 DEBUG(10,("cm_connect_sam: rpccli_samr_Connect2 failed "
2680                           "for domain %s Error was %s\n",
2681                           domain->name, nt_errstr(status) ));
2682                 goto done;
2683         }
2684         if (!NT_STATUS_IS_OK(result)) {
2685                 status = result;
2686                 DEBUG(10,("cm_connect_sam: dcerpc_samr_Connect2 failed "
2687                           "for domain %s Error was %s\n",
2688                           domain->name, nt_errstr(result)));
2689                 goto done;
2690         }
2691
2692  open_domain:
2693         status = dcerpc_samr_OpenDomain(conn->samr_pipe->binding_handle,
2694                                         mem_ctx,
2695                                         &conn->sam_connect_handle,
2696                                         SEC_FLAG_MAXIMUM_ALLOWED,
2697                                         &domain->sid,
2698                                         &conn->sam_domain_handle,
2699                                         &result);
2700         if (!NT_STATUS_IS_OK(status)) {
2701                 goto done;
2702         }
2703
2704         status = result;
2705  done:
2706
2707         if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
2708                 /*
2709                  * if we got access denied, we might just have no access rights
2710                  * to talk to the remote samr server server (e.g. when we are a
2711                  * PDC and we are connecting a w2k8 pdc via an interdomain
2712                  * trust). In that case do not invalidate the whole connection
2713                  * stack
2714                  */
2715                 TALLOC_FREE(conn->samr_pipe);
2716                 ZERO_STRUCT(conn->sam_domain_handle);
2717                 return status;
2718         } else if (!NT_STATUS_IS_OK(status)) {
2719                 invalidate_cm_connection(domain);
2720                 return status;
2721         }
2722
2723         *cli = conn->samr_pipe;
2724         *sam_handle = conn->sam_domain_handle;
2725         SAFE_FREE(machine_password);
2726         SAFE_FREE(machine_account);
2727         return status;
2728 }
2729
2730 /**********************************************************************
2731  open an schanneld ncacn_ip_tcp connection to LSA
2732 ***********************************************************************/
2733
2734 static NTSTATUS cm_connect_lsa_tcp(struct winbindd_domain *domain,
2735                                    TALLOC_CTX *mem_ctx,
2736                                    struct rpc_pipe_client **cli)
2737 {
2738         struct winbindd_cm_conn *conn;
2739         struct netlogon_creds_cli_context *creds;
2740         NTSTATUS status;
2741
2742         DEBUG(10,("cm_connect_lsa_tcp\n"));
2743
2744         status = init_dc_connection_rpc(domain, false);
2745         if (!NT_STATUS_IS_OK(status)) {
2746                 return status;
2747         }
2748
2749         conn = &domain->conn;
2750
2751         if (conn->lsa_pipe_tcp &&
2752             conn->lsa_pipe_tcp->transport->transport == NCACN_IP_TCP &&
2753             conn->lsa_pipe_tcp->auth->auth_level >= DCERPC_AUTH_LEVEL_INTEGRITY &&
2754             rpccli_is_connected(conn->lsa_pipe_tcp)) {
2755                 goto done;
2756         }
2757
2758         TALLOC_FREE(conn->lsa_pipe_tcp);
2759
2760         status = cm_get_schannel_creds(domain, &creds);
2761         if (!NT_STATUS_IS_OK(status)) {
2762                 goto done;
2763         }
2764
2765         status = cli_rpc_pipe_open_schannel_with_key(conn->cli,
2766                                                      &ndr_table_lsarpc,
2767                                                      NCACN_IP_TCP,
2768                                                      domain->name,
2769                                                      creds,
2770                                                      &conn->lsa_pipe_tcp);
2771         if (!NT_STATUS_IS_OK(status)) {
2772                 DEBUG(10,("cli_rpc_pipe_open_schannel_with_key failed: %s\n",
2773                         nt_errstr(status)));
2774                 goto done;
2775         }
2776
2777  done:
2778         if (!NT_STATUS_IS_OK(status)) {
2779                 TALLOC_FREE(conn->lsa_pipe_tcp);
2780                 return status;
2781         }
2782
2783         *cli = conn->lsa_pipe_tcp;
2784
2785         return status;
2786 }
2787
2788 NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
2789                         struct rpc_pipe_client **cli, struct policy_handle *lsa_policy)
2790 {
2791         struct winbindd_cm_conn *conn;
2792         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2793         struct netlogon_creds_cli_context *p_creds;
2794
2795         result = init_dc_connection_rpc(domain, false);
2796         if (!NT_STATUS_IS_OK(result))
2797                 return result;
2798
2799         conn = &domain->conn;
2800
2801         if (rpccli_is_connected(conn->lsa_pipe)) {
2802                 goto done;
2803         }
2804
2805         TALLOC_FREE(conn->lsa_pipe);
2806
2807         if ((conn->cli->user_name[0] == '\0') ||
2808             (conn->cli->domain[0] == '\0') || 
2809             (conn->cli->password == NULL || conn->cli->password[0] == '\0')) {
2810                 DEBUG(10, ("cm_connect_lsa: No no user available for "
2811                            "domain %s, trying schannel\n", conn->cli->domain));
2812                 goto schannel;
2813         }
2814
2815         /* We have an authenticated connection. Use a NTLMSSP SPNEGO
2816          * authenticated LSA pipe with sign & seal. */
2817         result = cli_rpc_pipe_open_spnego
2818                 (conn->cli, &ndr_table_lsarpc, NCACN_NP,
2819                  GENSEC_OID_NTLMSSP,
2820                  conn->auth_level,
2821                  smbXcli_conn_remote_name(conn->cli->conn),
2822                  conn->cli->domain, conn->cli->user_name, conn->cli->password,
2823                  &conn->lsa_pipe);
2824
2825         if (!NT_STATUS_IS_OK(result)) {
2826                 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
2827                           "domain %s using NTLMSSP authenticated pipe: user "
2828                           "%s\\%s. Error was %s. Trying schannel.\n",
2829                           domain->name, conn->cli->domain,
2830                           conn->cli->user_name, nt_errstr(result)));
2831                 goto schannel;
2832         }
2833
2834         DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
2835                   "NTLMSSP authenticated pipe: user %s\\%s\n",
2836                   domain->name, conn->cli->domain, conn->cli->user_name ));
2837
2838         result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2839                                         SEC_FLAG_MAXIMUM_ALLOWED,
2840                                         &conn->lsa_policy);
2841         if (NT_STATUS_IS_OK(result)) {
2842                 goto done;
2843         }
2844
2845         DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
2846                   "schannel\n"));
2847
2848         TALLOC_FREE(conn->lsa_pipe);
2849
2850  schannel:
2851
2852         /* Fall back to schannel if it's a W2K pre-SP1 box. */
2853
2854         result = cm_get_schannel_creds(domain, &p_creds);
2855         if (!NT_STATUS_IS_OK(result)) {
2856                 /* If this call fails - conn->cli can now be NULL ! */
2857                 DEBUG(10, ("cm_connect_lsa: Could not get schannel auth info "
2858                            "for domain %s (error %s), trying anon\n",
2859                         domain->name,
2860                         nt_errstr(result) ));
2861                 goto anonymous;
2862         }
2863         result = cli_rpc_pipe_open_schannel_with_key
2864                 (conn->cli, &ndr_table_lsarpc, NCACN_NP,
2865                  domain->name, p_creds, &conn->lsa_pipe);
2866
2867         if (!NT_STATUS_IS_OK(result)) {
2868                 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
2869                           "domain %s using schannel. Error was %s\n",
2870                           domain->name, nt_errstr(result) ));
2871                 goto anonymous;
2872         }
2873         DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
2874                   "schannel.\n", domain->name ));
2875
2876         result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2877                                         SEC_FLAG_MAXIMUM_ALLOWED,
2878                                         &conn->lsa_policy);
2879         if (NT_STATUS_IS_OK(result)) {
2880                 goto done;
2881         }
2882
2883         DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
2884                   "anonymous\n"));
2885
2886         TALLOC_FREE(conn->lsa_pipe);
2887
2888  anonymous:
2889
2890         if (lp_winbind_sealed_pipes() || lp_require_strong_key()) {
2891                 result = NT_STATUS_DOWNGRADE_DETECTED;
2892                 DEBUG(1, ("Unwilling to make LSA connection to domain %s"
2893                           "without connection level security, "
2894                           "must set 'winbind sealed pipes = false' and "
2895                           "'require strong key = false' to proceed: %s\n",
2896                           domain->name, nt_errstr(result)));
2897                 goto done;
2898         }
2899
2900         result = cli_rpc_pipe_open_noauth(conn->cli,
2901                                           &ndr_table_lsarpc,
2902                                           &conn->lsa_pipe);
2903         if (!NT_STATUS_IS_OK(result)) {
2904                 goto done;
2905         }
2906
2907         result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
2908                                         SEC_FLAG_MAXIMUM_ALLOWED,
2909                                         &conn->lsa_policy);
2910  done:
2911         if (!NT_STATUS_IS_OK(result)) {
2912                 invalidate_cm_connection(domain);
2913                 return result;
2914         }
2915
2916         *cli = conn->lsa_pipe;
2917         *lsa_policy = conn->lsa_policy;
2918         return result;
2919 }
2920
2921 /****************************************************************************
2922 Open a LSA connection to a DC, suiteable for LSA lookup calls.
2923 ****************************************************************************/
2924
2925 NTSTATUS cm_connect_lsat(struct winbindd_domain *domain,
2926                          TALLOC_CTX *mem_ctx,
2927                          struct rpc_pipe_client **cli,
2928                          struct policy_handle *lsa_policy)
2929 {
2930         NTSTATUS status;
2931
2932         if (domain->can_do_ncacn_ip_tcp) {
2933                 status = cm_connect_lsa_tcp(domain, mem_ctx, cli);
2934                 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) ||
2935                     NT_STATUS_EQUAL(status, NT_STATUS_RPC_SEC_PKG_ERROR) ||
2936                     NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
2937                         invalidate_cm_connection(domain);
2938                         status = cm_connect_lsa_tcp(domain, mem_ctx, cli);
2939                 }
2940                 if (NT_STATUS_IS_OK(status)) {
2941                         return status;
2942                 }
2943
2944                 /*
2945                  * we tried twice to connect via ncan_ip_tcp and schannel and
2946                  * failed - maybe it is a trusted domain we can't connect to ?
2947                  * do not try tcp next time - gd
2948                  */
2949                 domain->can_do_ncacn_ip_tcp = false;
2950         }
2951
2952         status = cm_connect_lsa(domain, mem_ctx, cli, lsa_policy);
2953
2954         return status;
2955 }
2956
2957 /****************************************************************************
2958  Open the netlogon pipe to this DC. Use schannel if specified in client conf.
2959  session key stored in conn->netlogon_pipe->dc->sess_key.
2960 ****************************************************************************/
2961
2962 NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
2963                              struct rpc_pipe_client **cli)
2964 {
2965         struct messaging_context *msg_ctx = winbind_messaging_context();
2966         struct winbindd_cm_conn *conn;
2967         NTSTATUS result;
2968         enum netr_SchannelType sec_chan_type;
2969         const char *_account_name;
2970         const char *account_name;
2971         struct samr_Password current_nt_hash;
2972         struct samr_Password *previous_nt_hash = NULL;
2973         struct netlogon_creds_CredentialState *creds = NULL;
2974         bool ok;
2975
2976         *cli = NULL;
2977
2978         result = init_dc_connection_rpc(domain, true);
2979         if (!NT_STATUS_IS_OK(result)) {
2980                 return result;
2981         }
2982
2983         conn = &domain->conn;
2984
2985         if (rpccli_is_connected(conn->netlogon_pipe)) {
2986                 *cli = conn->netlogon_pipe;
2987                 return NT_STATUS_OK;
2988         }
2989
2990         TALLOC_FREE(conn->netlogon_pipe);
2991         conn->netlogon_flags = 0;
2992         TALLOC_FREE(conn->netlogon_creds);
2993
2994         if ((!IS_DC) && (!domain->primary)) {
2995                 goto no_schannel;
2996         }
2997
2998         ok = get_trust_pw_hash(domain->name,
2999                                current_nt_hash.hash,
3000                                &_account_name,
3001                                &sec_chan_type);
3002         if (!ok) {
3003                 DEBUG(1, ("get_trust_pw_hash failed for %s, "
3004                           "unable to get NETLOGON credentials\n",
3005                           domain->name));
3006                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
3007         }
3008
3009         account_name = talloc_asprintf(talloc_tos(), "%s$", _account_name);
3010         if (account_name == NULL) {
3011                 return NT_STATUS_NO_MEMORY;
3012         }
3013
3014         result = rpccli_create_netlogon_creds(domain->dcname,
3015                                               domain->name,
3016                                               account_name,
3017                                               sec_chan_type,
3018                                               msg_ctx,
3019                                               domain,
3020                                               &conn->netlogon_creds);
3021         if (!NT_STATUS_IS_OK(result)) {
3022                 DEBUG(1, ("rpccli_create_netlogon_creds failed for %s, "
3023                           "unable to create NETLOGON credentials: %s\n",
3024                           domain->name, nt_errstr(result)));
3025                 SAFE_FREE(previous_nt_hash);
3026                 return result;
3027         }
3028
3029         result = rpccli_setup_netlogon_creds(conn->cli,
3030                                              conn->netlogon_creds,
3031                                              conn->netlogon_force_reauth,
3032                                              current_nt_hash,
3033                                              previous_nt_hash);
3034         conn->netlogon_force_reauth = false;
3035         SAFE_FREE(previous_nt_hash);
3036         if (!NT_STATUS_IS_OK(result)) {
3037                 DEBUG(1, ("rpccli_setup_netlogon_creds failed for %s, "
3038                           "unable to setup NETLOGON credentials: %s\n",
3039                           domain->name, nt_errstr(result)));
3040                 return result;
3041         }
3042
3043         result = netlogon_creds_cli_get(conn->netlogon_creds,
3044                                         talloc_tos(),
3045                                         &creds);
3046         if (!NT_STATUS_IS_OK(result)) {
3047                 DEBUG(1, ("netlogon_creds_cli_get failed for %s, "
3048                           "unable to get NETLOGON credentials: %s\n",
3049                           domain->name, nt_errstr(result)));
3050                 return result;
3051         }
3052         conn->netlogon_flags = creds->negotiate_flags;
3053         TALLOC_FREE(creds);
3054
3055  no_schannel:
3056         if (!(conn->netlogon_flags & NETLOGON_NEG_AUTHENTICATED_RPC)) {
3057                 if (lp_winbind_sealed_pipes() || lp_require_strong_key()) {
3058                         result = NT_STATUS_DOWNGRADE_DETECTED;
3059                         DEBUG(1, ("Unwilling to make connection to domain %s"
3060                                   "without connection level security, "
3061                                   "must set 'winbind sealed pipes = false' and "
3062                                   "'require strong key = false' to proceed: %s\n",
3063                                   domain->name, nt_errstr(result)));
3064                         invalidate_cm_connection(domain);
3065                         return result;
3066                 }
3067                 result = cli_rpc_pipe_open_noauth(conn->cli,
3068                                         &ndr_table_netlogon,
3069                                         &conn->netlogon_pipe);
3070                 if (!NT_STATUS_IS_OK(result)) {
3071                         invalidate_cm_connection(domain);
3072                         return result;
3073                 }
3074
3075                 *cli = conn->netlogon_pipe;
3076                 return NT_STATUS_OK;
3077         }
3078
3079         /* Using the credentials from the first pipe, open a signed and sealed
3080            second netlogon pipe. The session key is stored in the schannel
3081            part of the new pipe auth struct.
3082         */
3083
3084         result = cli_rpc_pipe_open_schannel_with_key(
3085                 conn->cli, &ndr_table_netlogon, NCACN_NP,
3086                 domain->name,
3087                 conn->netlogon_creds,
3088                 &conn->netlogon_pipe);
3089         if (!NT_STATUS_IS_OK(result)) {
3090                 DEBUG(3, ("Could not open schannel'ed NETLOGON pipe. Error "
3091                           "was %s\n", nt_errstr(result)));
3092
3093                 invalidate_cm_connection(domain);
3094                 return result;
3095         }
3096
3097         *cli = conn->netlogon_pipe;
3098         return NT_STATUS_OK;
3099 }
3100
3101 void winbind_msg_ip_dropped(struct messaging_context *msg_ctx,
3102                             void *private_data,
3103                             uint32_t msg_type,
3104                             struct server_id server_id,
3105                             DATA_BLOB *data)
3106 {
3107         struct winbindd_domain *domain;
3108         char *freeit = NULL;
3109         char *addr;
3110
3111         if ((data == NULL)
3112             || (data->data == NULL)
3113             || (data->length == 0)
3114             || (data->data[data->length-1] != '\0')) {
3115                 DEBUG(1, ("invalid msg_ip_dropped message: not a valid "
3116                           "string\n"));
3117                 return;
3118         }
3119
3120         addr = (char *)data->data;
3121         DEBUG(10, ("IP %s dropped\n", addr));
3122
3123         if (!is_ipaddress(addr)) {
3124                 char *slash;
3125                 /*
3126                  * Some code sends us ip addresses with the /netmask
3127                  * suffix
3128                  */
3129                 slash = strchr(addr, '/');
3130                 if (slash == NULL) {
3131                         DEBUG(1, ("invalid msg_ip_dropped message: %s",
3132                                   addr));
3133                         return;
3134                 }
3135                 freeit = talloc_strndup(talloc_tos(), addr, slash-addr);
3136                 if (freeit == NULL) {
3137                         DEBUG(1, ("talloc failed\n"));
3138                         return;
3139                 }
3140                 addr = freeit;
3141                 DEBUG(10, ("Stripped /netmask to IP %s\n", addr));
3142         }
3143
3144         for (domain = domain_list(); domain != NULL; domain = domain->next) {
3145                 char sockaddr[INET6_ADDRSTRLEN];
3146
3147                 if (!cli_state_is_connected(domain->conn.cli)) {
3148                         continue;
3149                 }
3150
3151                 print_sockaddr(sockaddr, sizeof(sockaddr),
3152                                smbXcli_conn_local_sockaddr(domain->conn.cli->conn));
3153
3154                 if (strequal(sockaddr, addr)) {
3155                         smbXcli_conn_disconnect(domain->conn.cli->conn, NT_STATUS_OK);
3156                 }
3157         }
3158         TALLOC_FREE(freeit);
3159 }