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