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