r20489: Missed patch ofthe forest_name patch for lookupname
[abartlet/samba.git/.git] / source3 / nsswitch / 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 2 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, write to the Free Software
24    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27 /*
28    We need to manage connections to domain controllers without having to
29    mess up the main winbindd code with other issues.  The aim of the
30    connection manager is to:
31   
32        - make connections to domain controllers and cache them
33        - re-establish connections when networks or servers go down
34        - centralise the policy on connection timeouts, domain controller
35          selection etc
36        - manage re-entrancy for when winbindd becomes able to handle
37          multiple outstanding rpc requests
38   
39    Why not have connection management as part of the rpc layer like tng?
40    Good question.  This code may morph into libsmb/rpc_cache.c or something
41    like that but at the moment it's simply staying as part of winbind.  I
42    think the TNG architecture of forcing every user of the rpc layer to use
43    the connection caching system is a bad idea.  It should be an optional
44    method of using the routines.
45
46    The TNG design is quite good but I disagree with some aspects of the
47    implementation. -tpot
48
49  */
50
51 /*
52    TODO:
53
54      - I'm pretty annoyed by all the make_nmb_name() stuff.  It should be
55        moved down into another function.
56
57      - Take care when destroying cli_structs as they can be shared between
58        various sam handles.
59
60  */
61
62 #include "includes.h"
63 #include "winbindd.h"
64
65 #undef DBGC_CLASS
66 #define DBGC_CLASS DBGC_WINBIND
67
68 struct dc_name_ip {
69         fstring name;
70         struct in_addr ip;
71 };
72
73 extern struct winbindd_methods reconnect_methods;
74 extern BOOL override_logfile;
75
76 static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain);
77 static void set_dc_type_and_flags( struct winbindd_domain *domain );
78 static BOOL get_dcs(TALLOC_CTX *mem_ctx, const struct winbindd_domain *domain,
79                     struct dc_name_ip **dcs, int *num_dcs);
80
81 /****************************************************************
82  Child failed to find DC's. Reschedule check.
83 ****************************************************************/
84
85 static void msg_failed_to_go_online(int msg_type, struct process_id src, void *buf, size_t len)
86 {
87         struct winbindd_domain *domain;
88         const char *domainname = (const char *)buf;
89
90         if (buf == NULL || len == 0) {
91                 return;
92         }
93
94         DEBUG(5,("msg_fail_to_go_online: received for domain %s.\n", domainname));
95
96         for (domain = domain_list(); domain; domain = domain->next) {
97                 if (domain->internal) {
98                         continue;
99                 }
100
101                 if (strequal(domain->name, domainname)) {
102                         if (domain->online) {
103                                 /* We're already online, ignore. */
104                                 DEBUG(5,("msg_fail_to_go_online: domain %s "
105                                         "already online.\n", domainname));
106                                 continue;
107                         }
108
109                         /* Reschedule the online check. */
110                         set_domain_offline(domain);
111                         break;
112                 }
113         }
114 }
115
116 /****************************************************************
117  Actually cause a reconnect from a message.
118 ****************************************************************/
119
120 static void msg_try_to_go_online(int msg_type, struct process_id src, void *buf, size_t len)
121 {
122         struct winbindd_domain *domain;
123         const char *domainname = (const char *)buf;
124
125         if (buf == NULL || len == 0) {
126                 return;
127         }
128
129         DEBUG(5,("msg_try_to_go_online: received for domain %s.\n", domainname));
130
131         for (domain = domain_list(); domain; domain = domain->next) {
132                 if (domain->internal) {
133                         continue;
134                 }
135
136                 if (strequal(domain->name, domainname)) {
137
138                         if (domain->online) {
139                                 /* We're already online, ignore. */
140                                 DEBUG(5,("msg_try_to_go_online: domain %s "
141                                         "already online.\n", domainname));
142                                 continue;
143                         }
144
145                         /* This call takes care of setting the online
146                            flag to true if we connected, or re-adding
147                            the offline handler if false. Bypasses online
148                            check so always does network calls. */
149
150                         init_dc_connection_network(domain);
151                         break;
152                 }
153         }
154 }
155
156 /****************************************************************
157  Fork a child to try and contact a DC. Do this as contacting a
158  DC requires blocking lookups and we don't want to block our
159  parent.
160 ****************************************************************/
161
162 static BOOL fork_child_dc_connect(struct winbindd_domain *domain)
163 {
164         struct dc_name_ip *dcs = NULL;
165         int num_dcs = 0;
166         TALLOC_CTX *mem_ctx = NULL;
167         pid_t child_pid;
168         pid_t parent_pid = sys_getpid();
169
170         /* Stop zombies */
171         CatchChild();
172
173         message_block();
174
175         child_pid = sys_fork();
176
177         if (child_pid == -1) {
178                 DEBUG(0, ("fork_child_dc_connect: Could not fork: %s\n", strerror(errno)));
179                 message_unblock();
180                 return False;
181         }
182
183         if (child_pid != 0) {
184                 /* Parent */
185                 message_register(MSG_WINBIND_TRY_TO_GO_ONLINE,msg_try_to_go_online);
186                 message_register(MSG_WINBIND_FAILED_TO_GO_ONLINE,msg_failed_to_go_online);
187                 message_unblock();
188                 return True;
189         }
190
191         /* Child. */
192
193         /* Leave messages blocked - we will never process one. */
194
195         /* tdb needs special fork handling */
196         if (tdb_reopen_all(1) == -1) {
197                 DEBUG(0,("tdb_reopen_all failed.\n"));
198                 _exit(0);
199         }
200
201         close_conns_after_fork();
202
203         if (!override_logfile) {
204                 reopen_logs();
205         }
206
207         mem_ctx = talloc_init("fork_child_dc_connect");
208         if (!mem_ctx) {
209                 DEBUG(0,("talloc_init failed.\n"));
210                 _exit(0);
211         }
212
213         if ((!get_dcs(mem_ctx, domain, &dcs, &num_dcs)) || (num_dcs == 0)) {
214                 /* Still offline ? Can't find DC's. */
215                 message_send_pid(pid_to_procid(parent_pid), MSG_WINBIND_FAILED_TO_GO_ONLINE,
216                                 domain->name,
217                                 strlen(domain->name)+1, False);
218                 _exit(0);
219         }
220
221         /* We got a DC. Send a message to our parent to get it to
222            try and do the same. */
223
224         message_send_pid(pid_to_procid(parent_pid), MSG_WINBIND_TRY_TO_GO_ONLINE,
225                                 domain->name,
226                                 strlen(domain->name)+1, False);
227         _exit(0);
228 }
229
230 /****************************************************************
231  Handler triggered if we're offline to try and detect a DC.
232 ****************************************************************/
233
234 static void check_domain_online_handler(struct timed_event *te,
235                                         const struct timeval *now,
236                                         void *private_data)
237 {
238         struct winbindd_domain *domain =
239                 (struct winbindd_domain *)private_data;
240
241         DEBUG(10,("check_domain_online_handler: called for domain %s\n",
242                 domain->name ));
243
244         if (domain->check_online_event) {
245                 TALLOC_FREE(domain->check_online_event);
246         }
247
248         /* Are we still in "startup" mode ? */
249
250         if (domain->startup && (now->tv_sec > domain->startup_time + 30)) {
251                 /* No longer in "startup" mode. */
252                 DEBUG(10,("check_domain_online_handler: domain %s no longer in 'startup' mode.\n",
253                         domain->name ));
254                 domain->startup = False;
255         }
256
257         /* We've been told to stay offline, so stay
258            that way. */
259
260         if (get_global_winbindd_state_offline()) {
261                 DEBUG(10,("check_domain_online_handler: domain %s remaining globally offline\n",
262                         domain->name ));
263                 return;
264         }
265
266         /* Fork a child to test if it can contact a DC. 
267            If it can then send ourselves a message to
268            cause a reconnect. */
269
270         fork_child_dc_connect(domain);
271 }
272
273 /****************************************************************
274  If we're still offline setup the timeout check.
275 ****************************************************************/
276
277 static void calc_new_online_timeout_check(struct winbindd_domain *domain)
278 {
279         int wbc = lp_winbind_cache_time();
280
281         if (domain->startup) {
282                 domain->check_online_timeout = 10;
283         } else if (domain->check_online_timeout < wbc) {
284                 domain->check_online_timeout = wbc;
285         }
286 }
287
288 /****************************************************************
289  Set domain offline and also add handler to put us back online
290  if we detect a DC.
291 ****************************************************************/
292
293 void set_domain_offline(struct winbindd_domain *domain)
294 {
295         DEBUG(10,("set_domain_offline: called for domain %s\n",
296                 domain->name ));
297
298         if (domain->check_online_event) {
299                 TALLOC_FREE(domain->check_online_event);
300         }
301
302         if (domain->internal) {
303                 DEBUG(3,("set_domain_offline: domain %s is internal - logic error.\n",
304                         domain->name ));
305                 return;
306         }
307
308         domain->online = False;
309
310         /* Offline domains are always initialized. They're
311            re-initialized when they go back online. */
312
313         domain->initialized = True;
314
315         /* We only add the timeout handler that checks and
316            allows us to go back online when we've not
317            been told to remain offline. */
318
319         if (get_global_winbindd_state_offline()) {
320                 DEBUG(10,("set_domain_offline: domain %s remaining globally offline\n",
321                         domain->name ));
322                 return;
323         }
324
325         /* If we're in statup mode, check again in 10 seconds, not in
326            lp_winbind_cache_time() seconds (which is 5 mins by default). */
327
328         calc_new_online_timeout_check(domain);
329
330         domain->check_online_event = add_timed_event( NULL,
331                                                 timeval_current_ofs(domain->check_online_timeout,0),
332                                                 "check_domain_online_handler",
333                                                 check_domain_online_handler,
334                                                 domain);
335
336         /* The above *has* to succeed for winbindd to work. */
337         if (!domain->check_online_event) {
338                 smb_panic("set_domain_offline: failed to add online handler.\n");
339         }
340
341         DEBUG(10,("set_domain_offline: added event handler for domain %s\n",
342                 domain->name ));
343 }
344
345 /****************************************************************
346  Set domain online - if allowed.
347 ****************************************************************/
348
349 static void set_domain_online(struct winbindd_domain *domain)
350 {
351         struct timeval now;
352
353         DEBUG(10,("set_domain_online: called for domain %s\n",
354                 domain->name ));
355
356         if (domain->internal) {
357                 DEBUG(3,("set_domain_offline: domain %s is internal - logic error.\n",
358                         domain->name ));
359                 return;
360         }
361
362         if (get_global_winbindd_state_offline()) {
363                 DEBUG(10,("set_domain_online: domain %s remaining globally offline\n",
364                         domain->name ));
365                 return;
366         }
367
368         /* If we are waiting to get a krb5 ticket, trigger immediately. */
369         GetTimeOfDay(&now);
370         set_event_dispatch_time("krb5_ticket_gain_handler", now);
371
372         /* Ok, we're out of any startup mode now... */
373         domain->startup = False;
374
375         if (domain->online == False) {
376                 /* We were offline - now we're online. We default to
377                    using the MS-RPC backend if we started offline,
378                    and if we're going online for the first time we
379                    should really re-initialize the backends and the
380                    checks to see if we're talking to an AD or NT domain.
381                 */
382
383                 domain->initialized = False;
384
385                 /* 'reconnect_methods' is the MS-RPC backend. */
386                 if (domain->backend == &reconnect_methods) {
387                         domain->backend = NULL;
388                 }
389         }
390
391         /* Ensure we have no online timeout checks. */
392         domain->check_online_timeout = 0;
393         if (domain->check_online_event) {
394                 TALLOC_FREE(domain->check_online_event);
395         }
396
397         /* Ensure we ignore any pending child messages. */
398         message_deregister(MSG_WINBIND_TRY_TO_GO_ONLINE);
399         message_deregister(MSG_WINBIND_FAILED_TO_GO_ONLINE);
400
401         domain->online = True;
402 }
403
404 /****************************************************************
405  Requested to set a domain online.
406 ****************************************************************/
407
408 void set_domain_online_request(struct winbindd_domain *domain)
409 {
410         struct timeval tev;
411
412         DEBUG(10,("set_domain_online_request: called for domain %s\n",
413                 domain->name ));
414
415         if (get_global_winbindd_state_offline()) {
416                 DEBUG(10,("set_domain_online_request: domain %s remaining globally offline\n",
417                         domain->name ));
418                 return;
419         }
420
421         /* We've been told it's safe to go online and
422            try and connect to a DC. But I don't believe it
423            because network manager seems to lie.
424            Wait at least 5 seconds. Heuristics suck... */
425
426         if (!domain->check_online_event) {
427                 /* If we've come from being globally offline we
428                    don't have a check online event handler set.
429                    We need to add one now we're trying to go
430                    back online. */
431
432                 DEBUG(10,("set_domain_online_request: domain %s was globally offline.\n",
433                         domain->name ));
434
435                 domain->check_online_event = add_timed_event( NULL,
436                                                 timeval_current_ofs(5, 0),
437                                                 "check_domain_online_handler",
438                                                 check_domain_online_handler,
439                                                 domain);
440
441                 /* The above *has* to succeed for winbindd to work. */
442                 if (!domain->check_online_event) {
443                         smb_panic("set_domain_online_request: failed to add online handler.\n");
444                 }
445         }
446
447         GetTimeOfDay(&tev);
448
449         /* Go into "startup" mode again. */
450         domain->startup_time = tev.tv_sec;
451         domain->startup = True;
452
453         tev.tv_sec += 5;
454         set_event_dispatch_time("check_domain_online_handler", tev);
455 }
456
457 /****************************************************************
458  Add -ve connection cache entries for domain and realm.
459 ****************************************************************/
460
461 void winbind_add_failed_connection_entry(const struct winbindd_domain *domain,
462                                         const char *server,
463                                         NTSTATUS result)
464 {
465         add_failed_connection_entry(domain->name, server, result);
466         /* If this was the saf name for the last thing we talked to,
467            remove it. */
468         saf_delete(domain->name);
469         if (*domain->alt_name) {
470                 add_failed_connection_entry(domain->alt_name, server, result);
471                 saf_delete(domain->alt_name);
472         }
473 }
474
475 /* Choose between anonymous or authenticated connections.  We need to use
476    an authenticated connection if DCs have the RestrictAnonymous registry
477    entry set > 0, or the "Additional restrictions for anonymous
478    connections" set in the win2k Local Security Policy. 
479    
480    Caller to free() result in domain, username, password
481 */
482
483 static void cm_get_ipc_userpass(char **username, char **domain, char **password)
484 {
485         *username = (char *)secrets_fetch(SECRETS_AUTH_USER, NULL);
486         *domain = (char *)secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
487         *password = (char *)secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
488         
489         if (*username && **username) {
490
491                 if (!*domain || !**domain)
492                         *domain = smb_xstrdup(lp_workgroup());
493                 
494                 if (!*password || !**password)
495                         *password = smb_xstrdup("");
496
497                 DEBUG(3, ("cm_get_ipc_userpass: Retrieved auth-user from secrets.tdb [%s\\%s]\n", 
498                           *domain, *username));
499
500         } else {
501                 DEBUG(3, ("cm_get_ipc_userpass: No auth-user defined\n"));
502                 *username = smb_xstrdup("");
503                 *domain = smb_xstrdup("");
504                 *password = smb_xstrdup("");
505         }
506 }
507
508 static BOOL get_dc_name_via_netlogon(const struct winbindd_domain *domain,
509                                      fstring dcname, struct in_addr *dc_ip)
510 {
511         struct winbindd_domain *our_domain = NULL;
512         struct rpc_pipe_client *netlogon_pipe = NULL;
513         NTSTATUS result;
514         WERROR werr;
515         TALLOC_CTX *mem_ctx;
516         unsigned int orig_timeout;
517         fstring tmp;
518         char *p;
519
520         /* Hmmmm. We can only open one connection to the NETLOGON pipe at the
521          * moment.... */
522
523         if (IS_DC) {
524                 return False;
525         }
526
527         if (domain->primary) {
528                 return False;
529         }
530
531         our_domain = find_our_domain();
532
533         if ((mem_ctx = talloc_init("get_dc_name_via_netlogon")) == NULL) {
534                 return False;
535         }
536
537         result = cm_connect_netlogon(our_domain, &netlogon_pipe);
538         if (!NT_STATUS_IS_OK(result)) {
539                 talloc_destroy(mem_ctx);
540                 return False;
541         }
542
543         /* This call can take a long time - allow the server to time out.
544            35 seconds should do it. */
545
546         orig_timeout = cli_set_timeout(netlogon_pipe->cli, 35000);
547         
548         werr = rpccli_netlogon_getdcname(netlogon_pipe, mem_ctx, our_domain->dcname,
549                                            domain->name, tmp);
550
551         /* And restore our original timeout. */
552         cli_set_timeout(netlogon_pipe->cli, orig_timeout);
553
554         talloc_destroy(mem_ctx);
555
556         if (!W_ERROR_IS_OK(werr)) {
557                 DEBUG(10, ("rpccli_netlogon_getdcname failed: %s\n",
558                            dos_errstr(werr)));
559                 return False;
560         }
561
562         /* cli_netlogon_getdcname gives us a name with \\ */
563         p = tmp;
564         if (*p == '\\') {
565                 p+=1;
566         }
567         if (*p == '\\') {
568                 p+=1;
569         }
570
571         fstrcpy(dcname, p);
572
573         DEBUG(10, ("rpccli_netlogon_getdcname returned %s\n", dcname));
574
575         if (!resolve_name(dcname, dc_ip, 0x20)) {
576                 return False;
577         }
578
579         return True;
580 }
581
582 /************************************************************************
583  Given a fd with a just-connected TCP connection to a DC, open a connection
584  to the pipe.
585 ************************************************************************/
586
587 static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
588                                       const int sockfd,
589                                       const char *controller,
590                                       struct cli_state **cli,
591                                       BOOL *retry)
592 {
593         char *machine_password, *machine_krb5_principal, *machine_account;
594         char *ipc_username, *ipc_domain, *ipc_password;
595
596         BOOL got_mutex;
597
598         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
599
600         struct sockaddr peeraddr;
601         socklen_t peeraddr_len;
602
603         struct sockaddr_in *peeraddr_in = (struct sockaddr_in *)&peeraddr;
604
605         DEBUG(10,("cm_prepare_connection: connecting to DC %s for domain %s\n",
606                 controller, domain->name ));
607
608         machine_password = secrets_fetch_machine_password(lp_workgroup(), NULL,
609                                                           NULL);
610         
611         if (asprintf(&machine_account, "%s$", global_myname()) == -1) {
612                 SAFE_FREE(machine_password);
613                 return NT_STATUS_NO_MEMORY;
614         }
615
616         if (asprintf(&machine_krb5_principal, "%s$@%s", global_myname(),
617                      lp_realm()) == -1) {
618                 SAFE_FREE(machine_account);
619                 SAFE_FREE(machine_password);
620                 return NT_STATUS_NO_MEMORY;
621         }
622
623         cm_get_ipc_userpass(&ipc_username, &ipc_domain, &ipc_password);
624
625         *retry = True;
626
627         got_mutex = secrets_named_mutex(controller,
628                                         WINBIND_SERVER_MUTEX_WAIT_TIME);
629
630         if (!got_mutex) {
631                 DEBUG(0,("cm_prepare_connection: mutex grab failed for %s\n",
632                          controller));
633                 result = NT_STATUS_POSSIBLE_DEADLOCK;
634                 goto done;
635         }
636
637         if ((*cli = cli_initialise()) == NULL) {
638                 DEBUG(1, ("Could not cli_initialize\n"));
639                 result = NT_STATUS_NO_MEMORY;
640                 goto done;
641         }
642
643         (*cli)->timeout = 10000;        /* 10 seconds */
644         (*cli)->fd = sockfd;
645         fstrcpy((*cli)->desthost, controller);
646         (*cli)->use_kerberos = True;
647
648         peeraddr_len = sizeof(peeraddr);
649
650         if ((getpeername((*cli)->fd, &peeraddr, &peeraddr_len) != 0) ||
651             (peeraddr_len != sizeof(struct sockaddr_in)) ||
652             (peeraddr_in->sin_family != PF_INET))
653         {
654                 DEBUG(0,("cm_prepare_connection: %s\n", strerror(errno)));
655                 result = NT_STATUS_UNSUCCESSFUL;
656                 goto done;
657         }
658
659         if (ntohs(peeraddr_in->sin_port) == 139) {
660                 struct nmb_name calling;
661                 struct nmb_name called;
662
663                 make_nmb_name(&calling, global_myname(), 0x0);
664                 make_nmb_name(&called, "*SMBSERVER", 0x20);
665
666                 if (!cli_session_request(*cli, &calling, &called)) {
667                         DEBUG(8, ("cli_session_request failed for %s\n",
668                                   controller));
669                         result = NT_STATUS_UNSUCCESSFUL;
670                         goto done;
671                 }
672         }
673
674         cli_setup_signing_state(*cli, Undefined);
675
676         if (!cli_negprot(*cli)) {
677                 DEBUG(1, ("cli_negprot failed\n"));
678                 result = NT_STATUS_UNSUCCESSFUL;
679                 goto done;
680         }
681                         
682         if ((*cli)->protocol >= PROTOCOL_NT1 && (*cli)->capabilities & CAP_EXTENDED_SECURITY) {
683                 ADS_STATUS ads_status;
684
685                 if (lp_security() == SEC_ADS) {
686
687                         /* Try a krb5 session */
688
689                         (*cli)->use_kerberos = True;
690                         DEBUG(5, ("connecting to %s from %s with kerberos principal "
691                                   "[%s]\n", controller, global_myname(),
692                                   machine_krb5_principal));
693
694                         ads_status = cli_session_setup_spnego(*cli,
695                                                               machine_krb5_principal, 
696                                                               machine_password, 
697                                                               lp_workgroup());
698
699                         if (!ADS_ERR_OK(ads_status)) {
700                                 DEBUG(4,("failed kerberos session setup with %s\n",
701                                          ads_errstr(ads_status)));
702                         }
703
704                         result = ads_ntstatus(ads_status);
705                         if (NT_STATUS_IS_OK(result)) {
706                                 /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
707                                 cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
708                                 goto session_setup_done;
709                         }
710                 }
711
712                 /* Fall back to non-kerberos session setup using NTLMSSP SPNEGO with the machine account. */
713                 (*cli)->use_kerberos = False;
714
715                 DEBUG(5, ("connecting to %s from %s with username "
716                           "[%s]\\[%s]\n",  controller, global_myname(),
717                           lp_workgroup(), machine_account));
718
719                 ads_status = cli_session_setup_spnego(*cli,
720                                                       machine_account, 
721                                                       machine_password, 
722                                                       lp_workgroup());
723                 if (!ADS_ERR_OK(ads_status)) {
724                         DEBUG(4, ("authenticated session setup failed with %s\n",
725                                 ads_errstr(ads_status)));
726                 }
727
728                 result = ads_ntstatus(ads_status);
729                 if (NT_STATUS_IS_OK(result)) {
730                         /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
731                         cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
732                         goto session_setup_done;
733                 }
734         }
735
736         /* Fall back to non-kerberos session setup */
737
738         (*cli)->use_kerberos = False;
739
740         if ((((*cli)->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) != 0) &&
741             (strlen(ipc_username) > 0)) {
742
743                 /* Only try authenticated if we have a username */
744
745                 DEBUG(5, ("connecting to %s from %s with username "
746                           "[%s]\\[%s]\n",  controller, global_myname(),
747                           ipc_domain, ipc_username));
748
749                 if (NT_STATUS_IS_OK(cli_session_setup(
750                                             *cli, ipc_username,
751                                             ipc_password, strlen(ipc_password)+1,
752                                             ipc_password, strlen(ipc_password)+1,
753                                             ipc_domain))) {
754                         /* Successful logon with given username. */
755                         cli_init_creds(*cli, ipc_username, ipc_domain, ipc_password);
756                         goto session_setup_done;
757                 } else {
758                         DEBUG(4, ("authenticated session setup with user %s\\%s failed.\n",
759                                 ipc_domain, ipc_username ));
760                 }
761         }
762
763         /* Fall back to anonymous connection, this might fail later */
764
765         if (NT_STATUS_IS_OK(cli_session_setup(*cli, "", NULL, 0,
766                                               NULL, 0, ""))) {
767                 DEBUG(5, ("Connected anonymously\n"));
768                 cli_init_creds(*cli, "", "", "");
769                 goto session_setup_done;
770         }
771
772         result = cli_nt_error(*cli);
773
774         if (NT_STATUS_IS_OK(result))
775                 result = NT_STATUS_UNSUCCESSFUL;
776
777         /* We can't session setup */
778
779         goto done;
780
781  session_setup_done:
782
783         /* cache the server name for later connections */
784
785         saf_store( domain->name, (*cli)->desthost );
786         if (domain->alt_name && (*cli)->use_kerberos) {
787                 saf_store( domain->alt_name, (*cli)->desthost );
788         }
789
790         if (!cli_send_tconX(*cli, "IPC$", "IPC", "", 0)) {
791
792                 result = cli_nt_error(*cli);
793
794                 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(result)));
795
796                 if (NT_STATUS_IS_OK(result))
797                         result = NT_STATUS_UNSUCCESSFUL;
798
799                 goto done;
800         }
801
802         secrets_named_mutex_release(controller);
803         got_mutex = False;
804         *retry = False;
805
806         /* set the domain if empty; needed for schannel connections */
807         if ( !*(*cli)->domain ) {
808                 fstrcpy( (*cli)->domain, domain->name );
809         }
810
811         result = NT_STATUS_OK;
812
813  done:
814         if (got_mutex) {
815                 secrets_named_mutex_release(controller);
816         }
817
818         SAFE_FREE(machine_account);
819         SAFE_FREE(machine_password);
820         SAFE_FREE(machine_krb5_principal);
821         SAFE_FREE(ipc_username);
822         SAFE_FREE(ipc_domain);
823         SAFE_FREE(ipc_password);
824
825         if (!NT_STATUS_IS_OK(result)) {
826                 winbind_add_failed_connection_entry(domain, controller, result);
827                 if ((*cli) != NULL) {
828                         cli_shutdown(*cli);
829                         *cli = NULL;
830                 }
831         }
832
833         return result;
834 }
835
836 static BOOL add_one_dc_unique(TALLOC_CTX *mem_ctx, const char *domain_name,
837                               const char *dcname, struct in_addr ip,
838                               struct dc_name_ip **dcs, int *num)
839 {
840         if (!NT_STATUS_IS_OK(check_negative_conn_cache(domain_name, dcname))) {
841                 DEBUG(10, ("DC %s was in the negative conn cache\n", dcname));
842                 return False;
843         }
844
845         *dcs = TALLOC_REALLOC_ARRAY(mem_ctx, *dcs, struct dc_name_ip, (*num)+1);
846
847         if (*dcs == NULL)
848                 return False;
849
850         fstrcpy((*dcs)[*num].name, dcname);
851         (*dcs)[*num].ip = ip;
852         *num += 1;
853         return True;
854 }
855
856 static BOOL add_sockaddr_to_array(TALLOC_CTX *mem_ctx,
857                                   struct in_addr ip, uint16 port,
858                                   struct sockaddr_in **addrs, int *num)
859 {
860         *addrs = TALLOC_REALLOC_ARRAY(mem_ctx, *addrs, struct sockaddr_in, (*num)+1);
861
862         if (*addrs == NULL) {
863                 *num = 0;
864                 return False;
865         }
866
867         (*addrs)[*num].sin_family = PF_INET;
868         putip((char *)&((*addrs)[*num].sin_addr), (char *)&ip);
869         (*addrs)[*num].sin_port = htons(port);
870
871         *num += 1;
872         return True;
873 }
874
875 static void mailslot_name(struct in_addr dc_ip, fstring name)
876 {
877         fstr_sprintf(name, "\\MAILSLOT\\NET\\GETDC%X", dc_ip.s_addr);
878 }
879
880 static BOOL send_getdc_request(struct in_addr dc_ip,
881                                const char *domain_name,
882                                const DOM_SID *sid)
883 {
884         pstring outbuf;
885         char *p;
886         fstring my_acct_name;
887         fstring my_mailslot;
888
889         mailslot_name(dc_ip, my_mailslot);
890
891         memset(outbuf, '\0', sizeof(outbuf));
892
893         p = outbuf;
894
895         SCVAL(p, 0, SAMLOGON);
896         p++;
897
898         SCVAL(p, 0, 0); /* Count pointer ... */
899         p++;
900
901         SIVAL(p, 0, 0); /* The sender's token ... */
902         p += 2;
903
904         p += dos_PutUniCode(p, global_myname(), sizeof(pstring), True);
905         fstr_sprintf(my_acct_name, "%s$", global_myname());
906         p += dos_PutUniCode(p, my_acct_name, sizeof(pstring), True);
907
908         memcpy(p, my_mailslot, strlen(my_mailslot)+1);
909         p += strlen(my_mailslot)+1;
910
911         SIVAL(p, 0, 0x80);
912         p+=4;
913
914         SIVAL(p, 0, sid_size(sid));
915         p+=4;
916
917         p = ALIGN4(p, outbuf);
918
919         sid_linearize(p, sid_size(sid), sid);
920         p += sid_size(sid);
921
922         SIVAL(p, 0, 1);
923         SSVAL(p, 4, 0xffff);
924         SSVAL(p, 6, 0xffff);
925         p+=8;
926
927         return cli_send_mailslot(False, "\\MAILSLOT\\NET\\NTLOGON", 0,
928                                  outbuf, PTR_DIFF(p, outbuf),
929                                  global_myname(), 0, domain_name, 0x1c,
930                                  dc_ip);
931 }
932
933 static BOOL receive_getdc_response(struct in_addr dc_ip,
934                                    const char *domain_name,
935                                    fstring dc_name)
936 {
937         struct packet_struct *packet;
938         fstring my_mailslot;
939         char *buf, *p;
940         fstring dcname, user, domain;
941         int len;
942
943         mailslot_name(dc_ip, my_mailslot);
944
945         packet = receive_unexpected(DGRAM_PACKET, 0, my_mailslot);
946
947         if (packet == NULL) {
948                 DEBUG(5, ("Did not receive packet for %s\n", my_mailslot));
949                 return False;
950         }
951
952         DEBUG(5, ("Received packet for %s\n", my_mailslot));
953
954         buf = packet->packet.dgram.data;
955         len = packet->packet.dgram.datasize;
956
957         if (len < 70) {
958                 /* 70 is a completely arbitrary value to make sure
959                    the SVAL below does not read uninitialized memory */
960                 DEBUG(3, ("GetDC got short response\n"));
961                 return False;
962         }
963
964         /* This should be (buf-4)+SVAL(buf-4, smb_vwv12)... */
965         p = buf+SVAL(buf, smb_vwv10);
966
967         if (CVAL(p,0) != SAMLOGON_R) {
968                 DEBUG(8, ("GetDC got invalid response type %d\n", CVAL(p, 0)));
969                 return False;
970         }
971
972         p+=2;
973         pull_ucs2(buf, dcname, p, sizeof(dcname), PTR_DIFF(buf+len, p),
974                   STR_TERMINATE|STR_NOALIGN);
975         p = skip_unibuf(p, PTR_DIFF(buf+len, p));
976         pull_ucs2(buf, user, p, sizeof(dcname), PTR_DIFF(buf+len, p),
977                   STR_TERMINATE|STR_NOALIGN);
978         p = skip_unibuf(p, PTR_DIFF(buf+len, p));
979         pull_ucs2(buf, domain, p, sizeof(dcname), PTR_DIFF(buf+len, p),
980                   STR_TERMINATE|STR_NOALIGN);
981         p = skip_unibuf(p, PTR_DIFF(buf+len, p));
982
983         if (!strequal(domain, domain_name)) {
984                 DEBUG(3, ("GetDC: Expected domain %s, got %s\n",
985                           domain_name, domain));
986                 return False;
987         }
988
989         p = dcname;
990         if (*p == '\\') p += 1;
991         if (*p == '\\') p += 1;
992
993         fstrcpy(dc_name, p);
994
995         DEBUG(10, ("GetDC gave name %s for domain %s\n",
996                    dc_name, domain));
997
998         return True;
999 }
1000
1001 /*******************************************************************
1002  convert an ip to a name
1003 *******************************************************************/
1004
1005 static BOOL dcip_to_name(const struct winbindd_domain *domain, struct in_addr ip, fstring name )
1006 {
1007         struct ip_service ip_list;
1008
1009         ip_list.ip = ip;
1010         ip_list.port = 0;
1011
1012 #ifdef WITH_ADS
1013         /* For active directory servers, try to get the ldap server name.
1014            None of these failures should be considered critical for now */
1015
1016         if (lp_security() == SEC_ADS) {
1017                 ADS_STRUCT *ads;
1018
1019                 ads = ads_init(domain->alt_name, domain->name, NULL);
1020                 ads->auth.flags |= ADS_AUTH_NO_BIND;
1021
1022                 if (ads_try_connect( ads, inet_ntoa(ip) ) )  {
1023                         /* We got a cldap packet. */
1024                         fstrcpy(name, ads->config.ldap_server_name);
1025                         namecache_store(name, 0x20, 1, &ip_list);
1026
1027                         DEBUG(10,("dcip_to_name: flags = 0x%x\n", (unsigned int)ads->config.flags));
1028
1029                         if (domain->primary && (ads->config.flags & ADS_KDC) && ads_closest_dc(ads)) {
1030                                 /* We're going to use this KDC for this realm/domain.
1031                                    If we are using sites, then force the krb5 libs
1032                                    to use this KDC. */
1033
1034                                 create_local_private_krb5_conf_for_domain(domain->alt_name,
1035                                                                 domain->name,
1036                                                                 ip);
1037
1038                                 /* Ensure we contact this DC also. */
1039                                 saf_store( domain->name, name);
1040                                 saf_store( domain->alt_name, name);
1041                         }
1042
1043                         ads_destroy( &ads );
1044                         return True;
1045                 }
1046
1047                 ads_destroy( &ads );
1048         }
1049 #endif
1050
1051         /* try GETDC requests next */
1052         
1053         if (send_getdc_request(ip, domain->name, &domain->sid)) {
1054                 int i;
1055                 smb_msleep(100);
1056                 for (i=0; i<5; i++) {
1057                         if (receive_getdc_response(ip, domain->name, name)) {
1058                                 namecache_store(name, 0x20, 1, &ip_list);
1059                                 return True;
1060                         }
1061                         smb_msleep(500);
1062                 }
1063         }
1064
1065         /* try node status request */
1066
1067         if ( name_status_find(domain->name, 0x1c, 0x20, ip, name) ) {
1068                 namecache_store(name, 0x20, 1, &ip_list);
1069                 return True;
1070         }
1071         return False;
1072 }
1073
1074 /*******************************************************************
1075  Retreive a list of IP address for domain controllers.  Fill in 
1076  the dcs[]  with results.
1077 *******************************************************************/
1078
1079 static BOOL get_dcs(TALLOC_CTX *mem_ctx, const struct winbindd_domain *domain,
1080                     struct dc_name_ip **dcs, int *num_dcs)
1081 {
1082         fstring dcname;
1083         struct  in_addr ip;
1084         struct  ip_service *ip_list = NULL;
1085         int     iplist_size = 0;
1086         int     i;
1087         BOOL    is_our_domain;
1088         enum security_types sec = (enum security_types)lp_security();
1089
1090         is_our_domain = strequal(domain->name, lp_workgroup());
1091
1092         if ( !is_our_domain 
1093                 && get_dc_name_via_netlogon(domain, dcname, &ip) 
1094                 && add_one_dc_unique(mem_ctx, domain->name, dcname, ip, dcs, num_dcs) )
1095         {
1096                 DEBUG(10, ("Retrieved DC %s at %s via netlogon\n",
1097                            dcname, inet_ntoa(ip)));
1098                 return True;
1099         }
1100
1101         if (sec == SEC_ADS) {
1102                 /* We need to make sure we know the local site before
1103                    doing any DNS queries, as this will restrict the
1104                    get_sorted_dc_list() call below to only fetching
1105                    DNS records for the correct site. */
1106
1107                 /* Find any DC to get the site record.
1108                    We deliberately don't care about the
1109                    return here. */
1110                 get_dc_name(domain->name, lp_realm(), dcname, &ip);
1111
1112                 /* Now do the site-specific AD dns lookup. */
1113                 get_sorted_dc_list(domain->alt_name, &ip_list, &iplist_size, True);
1114         }
1115
1116         /* try standard netbios queries if no ADS */
1117
1118         if (iplist_size==0) 
1119                 get_sorted_dc_list(domain->name, &ip_list, &iplist_size, False);
1120
1121         /* FIXME!! this is where we should re-insert the GETDC requests --jerry */
1122
1123         /* now add to the dc array.  We'll wait until the last minute 
1124            to look up the name of the DC.  But we fill in the char* for 
1125            the ip now in to make the failed connection cache work */
1126
1127         for ( i=0; i<iplist_size; i++ ) {
1128                 add_one_dc_unique(mem_ctx, domain->name, inet_ntoa(ip_list[i].ip), 
1129                         ip_list[i].ip, dcs, num_dcs);
1130         }
1131
1132         SAFE_FREE( ip_list );
1133
1134         return True;
1135 }
1136
1137 static BOOL find_new_dc(TALLOC_CTX *mem_ctx,
1138                         const struct winbindd_domain *domain,
1139                         fstring dcname, struct sockaddr_in *addr, int *fd)
1140 {
1141         struct dc_name_ip *dcs = NULL;
1142         int num_dcs = 0;
1143
1144         const char **dcnames = NULL;
1145         int num_dcnames = 0;
1146
1147         struct sockaddr_in *addrs = NULL;
1148         int num_addrs = 0;
1149
1150         int i, fd_index;
1151
1152  again:
1153         if (!get_dcs(mem_ctx, domain, &dcs, &num_dcs) || (num_dcs == 0))
1154                 return False;
1155
1156         for (i=0; i<num_dcs; i++) {
1157
1158                 if (!add_string_to_array(mem_ctx, dcs[i].name,
1159                                     &dcnames, &num_dcnames)) {
1160                         return False;
1161                 }
1162                 if (!add_sockaddr_to_array(mem_ctx, dcs[i].ip, 445,
1163                                       &addrs, &num_addrs)) {
1164                         return False;
1165                 }
1166
1167                 if (!add_string_to_array(mem_ctx, dcs[i].name,
1168                                     &dcnames, &num_dcnames)) {
1169                         return False;
1170                 }
1171                 if (!add_sockaddr_to_array(mem_ctx, dcs[i].ip, 139,
1172                                       &addrs, &num_addrs)) {
1173                         return False;
1174                 }
1175         }
1176
1177         if ((num_dcnames == 0) || (num_dcnames != num_addrs))
1178                 return False;
1179
1180         if ((addrs == NULL) || (dcnames == NULL))
1181                 return False;
1182
1183         /* 5 second timeout. */
1184         if ( !open_any_socket_out(addrs, num_addrs, 5000, &fd_index, fd) ) 
1185         {
1186                 for (i=0; i<num_dcs; i++) {
1187                         DEBUG(10, ("find_new_dc: open_any_socket_out failed for "
1188                                 "domain %s address %s. Error was %s\n",
1189                                 domain->name, inet_ntoa(dcs[i].ip), strerror(errno) ));
1190                         winbind_add_failed_connection_entry(domain,
1191                                 dcs[i].name, NT_STATUS_UNSUCCESSFUL);
1192                 }
1193                 return False;
1194         }
1195
1196         *addr = addrs[fd_index];
1197
1198         if (*dcnames[fd_index] != '\0' && !is_ipaddress(dcnames[fd_index])) {
1199                 /* Ok, we've got a name for the DC */
1200                 fstrcpy(dcname, dcnames[fd_index]);
1201                 return True;
1202         }
1203
1204         /* Try to figure out the name */
1205         if (dcip_to_name( domain, addr->sin_addr, dcname )) {
1206                 return True;
1207         }
1208
1209         /* We can not continue without the DC's name */
1210         winbind_add_failed_connection_entry(domain, dcs[fd_index].name,
1211                                     NT_STATUS_UNSUCCESSFUL);
1212         goto again;
1213 }
1214
1215 static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
1216                                    struct winbindd_cm_conn *new_conn)
1217 {
1218         TALLOC_CTX *mem_ctx;
1219         NTSTATUS result;
1220         char *saf_servername = saf_fetch( domain->name );
1221         int retries;
1222
1223         if ((mem_ctx = talloc_init("cm_open_connection")) == NULL) {
1224                 SAFE_FREE(saf_servername);
1225                 set_domain_offline(domain);
1226                 return NT_STATUS_NO_MEMORY;
1227         }
1228
1229         /* we have to check the server affinity cache here since 
1230            later we selecte a DC based on response time and not preference */
1231            
1232         /* Check the negative connection cache
1233            before talking to it. It going down may have
1234            triggered the reconnection. */
1235
1236         if ( saf_servername && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, saf_servername))) {
1237
1238                 DEBUG(10,("cm_open_connection: saf_servername is '%s' for domain %s\n",
1239                         saf_servername, domain->name ));
1240
1241                 /* convert an ip address to a name */
1242                 if ( is_ipaddress( saf_servername ) ) {
1243                         fstring saf_name;
1244                         struct in_addr ip;
1245
1246                         ip = *interpret_addr2( saf_servername );
1247                         if (dcip_to_name( domain, ip, saf_name )) {
1248                                 fstrcpy( domain->dcname, saf_name );
1249                         } else {
1250                                 winbind_add_failed_connection_entry(
1251                                         domain, saf_servername,
1252                                         NT_STATUS_UNSUCCESSFUL);
1253                         }
1254                 } else {
1255                         fstrcpy( domain->dcname, saf_servername );
1256                 }
1257
1258                 SAFE_FREE( saf_servername );
1259         }
1260
1261         for (retries = 0; retries < 3; retries++) {
1262
1263                 int fd = -1;
1264                 BOOL retry = False;
1265
1266                 result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1267
1268                 DEBUG(10,("cm_open_connection: dcname is '%s' for domain %s\n",
1269                         domain->dcname, domain->name ));
1270
1271                 if (*domain->dcname 
1272                         && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, domain->dcname))
1273                         && (resolve_name(domain->dcname, &domain->dcaddr.sin_addr, 0x20)))
1274                 {
1275                         struct sockaddr_in *addrs = NULL;
1276                         int num_addrs = 0;
1277                         int dummy = 0;
1278
1279                         if (!add_sockaddr_to_array(mem_ctx, domain->dcaddr.sin_addr, 445, &addrs, &num_addrs)) {
1280                                 set_domain_offline(domain);
1281                                 talloc_destroy(mem_ctx);
1282                                 return NT_STATUS_NO_MEMORY;
1283                         }
1284                         if (!add_sockaddr_to_array(mem_ctx, domain->dcaddr.sin_addr, 139, &addrs, &num_addrs)) {
1285                                 set_domain_offline(domain);
1286                                 talloc_destroy(mem_ctx);
1287                                 return NT_STATUS_NO_MEMORY;
1288                         }
1289
1290                         /* 5 second timeout. */
1291                         if (!open_any_socket_out(addrs, num_addrs, 5000, &dummy, &fd)) {
1292                                 fd = -1;
1293                         }
1294                 }
1295
1296                 if ((fd == -1) 
1297                         && !find_new_dc(mem_ctx, domain, domain->dcname, &domain->dcaddr, &fd))
1298                 {
1299                         /* This is the one place where we will
1300                            set the global winbindd offline state
1301                            to true, if a "WINBINDD_OFFLINE" entry
1302                            is found in the winbindd cache. */
1303                         set_global_winbindd_state_offline();
1304                         break;
1305                 }
1306
1307                 new_conn->cli = NULL;
1308
1309                 result = cm_prepare_connection(domain, fd, domain->dcname,
1310                         &new_conn->cli, &retry);
1311
1312                 if (!retry)
1313                         break;
1314         }
1315
1316         if (NT_STATUS_IS_OK(result)) {
1317                 if (domain->online == False) {
1318                         /* We're changing state from offline to online. */
1319                         set_global_winbindd_state_online();
1320                 }
1321                 set_domain_online(domain);
1322         } else {
1323                 /* Ensure we setup the retry handler. */
1324                 set_domain_offline(domain);
1325         }
1326
1327         talloc_destroy(mem_ctx);
1328         return result;
1329 }
1330
1331 /* Close down all open pipes on a connection. */
1332
1333 void invalidate_cm_connection(struct winbindd_cm_conn *conn)
1334 {
1335         /* We're closing down a possibly dead
1336            connection. Don't have impossibly long (10s) timeouts. */
1337
1338         if (conn->cli) {
1339                 cli_set_timeout(conn->cli, 1000); /* 1 second. */
1340         }
1341
1342         if (conn->samr_pipe != NULL) {
1343                 if (!cli_rpc_pipe_close(conn->samr_pipe)) {
1344                         /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1345                         if (conn->cli) {
1346                                 cli_set_timeout(conn->cli, 500);
1347                         }
1348                 }
1349                 conn->samr_pipe = NULL;
1350         }
1351
1352         if (conn->lsa_pipe != NULL) {
1353                 if (!cli_rpc_pipe_close(conn->lsa_pipe)) {
1354                         /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1355                         if (conn->cli) {
1356                                 cli_set_timeout(conn->cli, 500);
1357                         }
1358                 }
1359                 conn->lsa_pipe = NULL;
1360         }
1361
1362         if (conn->netlogon_pipe != NULL) {
1363                 if (!cli_rpc_pipe_close(conn->netlogon_pipe)) {
1364                         /* Ok, it must be dead. Drop timeout to 0.5 sec. */
1365                         if (conn->cli) {
1366                                 cli_set_timeout(conn->cli, 500);
1367                         }
1368                 }
1369                 conn->netlogon_pipe = NULL;
1370         }
1371
1372         if (conn->cli) {
1373                 cli_shutdown(conn->cli);
1374         }
1375
1376         conn->cli = NULL;
1377 }
1378
1379 void close_conns_after_fork(void)
1380 {
1381         struct winbindd_domain *domain;
1382
1383         for (domain = domain_list(); domain; domain = domain->next) {
1384                 if (domain->conn.cli == NULL)
1385                         continue;
1386
1387                 if (domain->conn.cli->fd == -1)
1388                         continue;
1389
1390                 close(domain->conn.cli->fd);
1391                 domain->conn.cli->fd = -1;
1392         }
1393 }
1394
1395 static BOOL connection_ok(struct winbindd_domain *domain)
1396 {
1397         if (domain->conn.cli == NULL) {
1398                 DEBUG(8, ("connection_ok: Connection to %s for domain %s has NULL "
1399                           "cli!\n", domain->dcname, domain->name));
1400                 return False;
1401         }
1402
1403         if (!domain->conn.cli->initialised) {
1404                 DEBUG(3, ("connection_ok: Connection to %s for domain %s was never "
1405                           "initialised!\n", domain->dcname, domain->name));
1406                 return False;
1407         }
1408
1409         if (domain->conn.cli->fd == -1) {
1410                 DEBUG(3, ("connection_ok: Connection to %s for domain %s has died or was "
1411                           "never started (fd == -1)\n", 
1412                           domain->dcname, domain->name));
1413                 return False;
1414         }
1415
1416         if (domain->online == False) {
1417                 DEBUG(3, ("connection_ok: Domain %s is offline\n", domain->name));
1418                 return False;
1419         }
1420
1421         return True;
1422 }
1423
1424 /* Initialize a new connection up to the RPC BIND.
1425    Bypass online status check so always does network calls. */
1426
1427 static NTSTATUS init_dc_connection_network(struct winbindd_domain *domain)
1428 {
1429         NTSTATUS result;
1430
1431         /* Internal connections never use the network. */
1432         if (domain->internal) {
1433                 domain->initialized = True;
1434                 return NT_STATUS_OK;
1435         }
1436
1437         if (connection_ok(domain)) {
1438                 if (!domain->initialized) {
1439                         set_dc_type_and_flags(domain);
1440                 }
1441                 return NT_STATUS_OK;
1442         }
1443
1444         invalidate_cm_connection(&domain->conn);
1445
1446         result = cm_open_connection(domain, &domain->conn);
1447
1448         if (NT_STATUS_IS_OK(result) && !domain->initialized) {
1449                 set_dc_type_and_flags(domain);
1450         }
1451
1452         return result;
1453 }
1454
1455 NTSTATUS init_dc_connection(struct winbindd_domain *domain)
1456 {
1457         if (domain->initialized && !domain->online) {
1458                 /* We check for online status elsewhere. */
1459                 return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
1460         }
1461
1462         return init_dc_connection_network(domain);
1463 }
1464
1465 /******************************************************************************
1466  We can 'sense' certain things about the DC by it's replies to certain
1467  questions.
1468
1469  This tells us if this particular remote server is Active Directory, and if it
1470  is native mode.
1471 ******************************************************************************/
1472
1473 static void set_dc_type_and_flags( struct winbindd_domain *domain )
1474 {
1475         NTSTATUS                result;
1476         DS_DOMINFO_CTR          ctr;
1477         TALLOC_CTX              *mem_ctx = NULL;
1478         struct rpc_pipe_client  *cli;
1479         POLICY_HND pol;
1480
1481         char *domain_name = NULL;
1482         char *dns_name = NULL;
1483         char *forest_name = NULL;       
1484         DOM_SID *dom_sid = NULL;        
1485
1486         ZERO_STRUCT( ctr );
1487         
1488         if (!connection_ok(domain)) {
1489                 return;
1490         }
1491
1492         DEBUG(5, ("set_dc_type_and_flags: domain %s\n", domain->name ));
1493
1494         cli = cli_rpc_pipe_open_noauth(domain->conn.cli, PI_LSARPC_DS,
1495                                        &result);
1496
1497         if (cli == NULL) {
1498                 DEBUG(5, ("set_dc_type_and_flags: Could not bind to "
1499                           "PI_LSARPC_DS on domain %s: (%s)\n",
1500                           domain->name, nt_errstr(result)));
1501                 return;
1502         }
1503
1504         result = rpccli_ds_getprimarydominfo(cli, cli->cli->mem_ctx,
1505                                              DsRolePrimaryDomainInfoBasic,
1506                                              &ctr);
1507         cli_rpc_pipe_close(cli);
1508
1509         if (!NT_STATUS_IS_OK(result)) {
1510                 DEBUG(5, ("set_dc_type_and_flags: rpccli_ds_getprimarydominfo "
1511                           "on domain %s failed: (%s)\n",
1512                           domain->name, nt_errstr(result)));
1513                 return;
1514         }
1515         
1516         if ((ctr.basic->flags & DSROLE_PRIMARY_DS_RUNNING) &&
1517             !(ctr.basic->flags & DSROLE_PRIMARY_DS_MIXED_MODE)) {
1518                 domain->native_mode = True;
1519         } else {
1520                 domain->native_mode = False;
1521         }
1522
1523         cli = cli_rpc_pipe_open_noauth(domain->conn.cli, PI_LSARPC, &result);
1524
1525         if (cli == NULL) {
1526                 DEBUG(5, ("set_dc_type_and_flags: Could not bind to "
1527                           "PI_LSARPC on domain %s: (%s)\n",
1528                           domain->name, nt_errstr(result)));
1529                 cli_rpc_pipe_close(cli);
1530                 return;
1531         }
1532
1533         mem_ctx = talloc_init("set_dc_type_and_flags on domain %s\n",
1534                               domain->name);
1535         if (!mem_ctx) {
1536                 DEBUG(1, ("set_dc_type_and_flags: talloc_init() failed\n"));
1537                 cli_rpc_pipe_close(cli);
1538                 return;
1539         }
1540
1541         result = rpccli_lsa_open_policy2(cli, mem_ctx, True, 
1542                                          SEC_RIGHTS_MAXIMUM_ALLOWED, &pol);
1543                 
1544         if (NT_STATUS_IS_OK(result)) {
1545                 /* This particular query is exactly what Win2k clients use 
1546                    to determine that the DC is active directory */
1547                 result = rpccli_lsa_query_info_policy2(cli, mem_ctx, &pol,
1548                                                        12, &domain_name,
1549                                                        &dns_name, &forest_name,
1550                                                        NULL, &dom_sid);
1551         }
1552
1553         if (NT_STATUS_IS_OK(result)) {
1554                 domain->active_directory = True;
1555
1556                 if (domain_name)
1557                         fstrcpy(domain->name, domain_name);
1558
1559                 if (dns_name)
1560                         fstrcpy(domain->alt_name, dns_name);
1561
1562                 if ( forest_name )
1563                         fstrcpy(domain->forest_name, forest_name);              
1564
1565                 if (dom_sid) 
1566                         sid_copy(&domain->sid, dom_sid);
1567         } else {
1568                 domain->active_directory = False;
1569
1570                 result = rpccli_lsa_open_policy(cli, mem_ctx, True, 
1571                                                 SEC_RIGHTS_MAXIMUM_ALLOWED,
1572                                                 &pol);
1573                         
1574                 if (!NT_STATUS_IS_OK(result))
1575                         goto done;
1576                         
1577                 result = rpccli_lsa_query_info_policy(cli, mem_ctx, 
1578                                                       &pol, 5, &domain_name, 
1579                                                       &dom_sid);
1580                         
1581                 if (NT_STATUS_IS_OK(result)) {
1582                         if (domain_name)
1583                                 fstrcpy(domain->name, domain_name);
1584
1585                         if (dom_sid) 
1586                                 sid_copy(&domain->sid, dom_sid);
1587                 }
1588         }
1589 done:
1590
1591         DEBUG(5, ("set_dc_type_and_flags: domain %s is %sin native mode.\n",
1592                   domain->name, domain->native_mode ? "" : "NOT "));
1593
1594         DEBUG(5,("set_dc_type_and_flags: domain %s is %srunning active directory.\n",
1595                   domain->name, domain->active_directory ? "" : "NOT "));
1596
1597         cli_rpc_pipe_close(cli);
1598         
1599         talloc_destroy(mem_ctx);
1600
1601         domain->initialized = True;
1602 }
1603
1604 static BOOL cm_get_schannel_dcinfo(struct winbindd_domain *domain,
1605                                    struct dcinfo **ppdc)
1606 {
1607         NTSTATUS result;
1608         struct rpc_pipe_client *netlogon_pipe;
1609
1610         if (lp_client_schannel() == False) {
1611                 return False;
1612         }
1613
1614         result = cm_connect_netlogon(domain, &netlogon_pipe);
1615         if (!NT_STATUS_IS_OK(result)) {
1616                 return False;
1617         }
1618
1619         /* Return a pointer to the struct dcinfo from the
1620            netlogon pipe. */
1621
1622         *ppdc = domain->conn.netlogon_pipe->dc;
1623         return True;
1624 }
1625
1626 NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
1627                         struct rpc_pipe_client **cli, POLICY_HND *sam_handle)
1628 {
1629         struct winbindd_cm_conn *conn;
1630         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1631         fstring conn_pwd;
1632         struct dcinfo *p_dcinfo;
1633
1634         result = init_dc_connection(domain);
1635         if (!NT_STATUS_IS_OK(result)) {
1636                 return result;
1637         }
1638
1639         conn = &domain->conn;
1640
1641         if (conn->samr_pipe != NULL) {
1642                 goto done;
1643         }
1644
1645         /*
1646          * No SAMR pipe yet. Attempt to get an NTLMSSP SPNEGO authenticated
1647          * sign and sealed pipe using the machine account password by
1648          * preference. If we can't - try schannel, if that fails, try
1649          * anonymous.
1650          */
1651
1652         pwd_get_cleartext(&conn->cli->pwd, conn_pwd);
1653         if ((conn->cli->user_name[0] == '\0') ||
1654             (conn->cli->domain[0] == '\0') || 
1655             (conn_pwd[0] == '\0')) {
1656                 DEBUG(10, ("cm_connect_sam: No no user available for "
1657                            "domain %s, trying schannel\n", conn->cli->domain));
1658                 goto schannel;
1659         }
1660
1661         /* We have an authenticated connection. Use a NTLMSSP SPNEGO
1662            authenticated SAMR pipe with sign & seal. */
1663         conn->samr_pipe =
1664                 cli_rpc_pipe_open_spnego_ntlmssp(conn->cli, PI_SAMR,
1665                                                  PIPE_AUTH_LEVEL_PRIVACY,
1666                                                  conn->cli->domain,
1667                                                  conn->cli->user_name,
1668                                                  conn_pwd, &result);
1669
1670         if (conn->samr_pipe == NULL) {
1671                 DEBUG(10,("cm_connect_sam: failed to connect to SAMR "
1672                           "pipe for domain %s using NTLMSSP "
1673                           "authenticated pipe: user %s\\%s. Error was "
1674                           "%s\n", domain->name, conn->cli->domain,
1675                           conn->cli->user_name, nt_errstr(result)));
1676                 goto schannel;
1677         }
1678
1679         DEBUG(10,("cm_connect_sam: connected to SAMR pipe for "
1680                   "domain %s using NTLMSSP authenticated "
1681                   "pipe: user %s\\%s\n", domain->name,
1682                   conn->cli->domain, conn->cli->user_name ));
1683
1684         result = rpccli_samr_connect(conn->samr_pipe, mem_ctx,
1685                                      SEC_RIGHTS_MAXIMUM_ALLOWED,
1686                                      &conn->sam_connect_handle);
1687         if (NT_STATUS_IS_OK(result)) {
1688                 goto open_domain;
1689         }
1690         DEBUG(10,("cm_connect_sam: ntlmssp-sealed rpccli_samr_connect "
1691                   "failed for domain %s, error was %s. Trying schannel\n",
1692                   domain->name, nt_errstr(result) ));
1693         cli_rpc_pipe_close(conn->samr_pipe);
1694
1695  schannel:
1696
1697         /* Fall back to schannel if it's a W2K pre-SP1 box. */
1698
1699         if (!cm_get_schannel_dcinfo(domain, &p_dcinfo)) {
1700                 /* If this call fails - conn->cli can now be NULL ! */
1701                 DEBUG(10, ("cm_connect_sam: Could not get schannel auth info "
1702                            "for domain %s, trying anon\n", domain->name));
1703                 goto anonymous;
1704         }
1705         conn->samr_pipe = cli_rpc_pipe_open_schannel_with_key
1706                 (conn->cli, PI_SAMR, PIPE_AUTH_LEVEL_PRIVACY,
1707                  domain->name, p_dcinfo, &result);
1708
1709         if (conn->samr_pipe == NULL) {
1710                 DEBUG(10,("cm_connect_sam: failed to connect to SAMR pipe for "
1711                           "domain %s using schannel. Error was %s\n",
1712                           domain->name, nt_errstr(result) ));
1713                 goto anonymous;
1714         }
1715         DEBUG(10,("cm_connect_sam: connected to SAMR pipe for domain %s using "
1716                   "schannel.\n", domain->name ));
1717
1718         result = rpccli_samr_connect(conn->samr_pipe, mem_ctx,
1719                                      SEC_RIGHTS_MAXIMUM_ALLOWED,
1720                                      &conn->sam_connect_handle);
1721         if (NT_STATUS_IS_OK(result)) {
1722                 goto open_domain;
1723         }
1724         DEBUG(10,("cm_connect_sam: schannel-sealed rpccli_samr_connect failed "
1725                   "for domain %s, error was %s. Trying anonymous\n",
1726                   domain->name, nt_errstr(result) ));
1727         cli_rpc_pipe_close(conn->samr_pipe);
1728
1729  anonymous:
1730
1731         /* Finally fall back to anonymous. */
1732         conn->samr_pipe = cli_rpc_pipe_open_noauth(conn->cli, PI_SAMR,
1733                                                    &result);
1734
1735         if (conn->samr_pipe == NULL) {
1736                 result = NT_STATUS_PIPE_NOT_AVAILABLE;
1737                 goto done;
1738         }
1739
1740         result = rpccli_samr_connect(conn->samr_pipe, mem_ctx,
1741                                      SEC_RIGHTS_MAXIMUM_ALLOWED,
1742                                      &conn->sam_connect_handle);
1743         if (!NT_STATUS_IS_OK(result)) {
1744                 DEBUG(10,("cm_connect_sam: rpccli_samr_connect failed "
1745                           "for domain %s Error was %s\n",
1746                           domain->name, nt_errstr(result) ));
1747                 goto done;
1748         }
1749
1750  open_domain:
1751         result = rpccli_samr_open_domain(conn->samr_pipe,
1752                                          mem_ctx,
1753                                          &conn->sam_connect_handle,
1754                                          SEC_RIGHTS_MAXIMUM_ALLOWED,
1755                                          &domain->sid,
1756                                          &conn->sam_domain_handle);
1757
1758  done:
1759
1760         if (!NT_STATUS_IS_OK(result)) {
1761                 invalidate_cm_connection(conn);
1762                 return result;
1763         }
1764
1765         *cli = conn->samr_pipe;
1766         *sam_handle = conn->sam_domain_handle;
1767         return result;
1768 }
1769
1770 NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
1771                         struct rpc_pipe_client **cli, POLICY_HND *lsa_policy)
1772 {
1773         struct winbindd_cm_conn *conn;
1774         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1775         fstring conn_pwd;
1776         struct dcinfo *p_dcinfo;
1777
1778         result = init_dc_connection(domain);
1779         if (!NT_STATUS_IS_OK(result))
1780                 return result;
1781
1782         conn = &domain->conn;
1783
1784         if (conn->lsa_pipe != NULL) {
1785                 goto done;
1786         }
1787
1788         pwd_get_cleartext(&conn->cli->pwd, conn_pwd);
1789         if ((conn->cli->user_name[0] == '\0') ||
1790             (conn->cli->domain[0] == '\0') || 
1791             (conn_pwd[0] == '\0')) {
1792                 DEBUG(10, ("cm_connect_lsa: No no user available for "
1793                            "domain %s, trying schannel\n", conn->cli->domain));
1794                 goto schannel;
1795         }
1796
1797         /* We have an authenticated connection. Use a NTLMSSP SPNEGO
1798          * authenticated LSA pipe with sign & seal. */
1799         conn->lsa_pipe = cli_rpc_pipe_open_spnego_ntlmssp
1800                 (conn->cli, PI_LSARPC, PIPE_AUTH_LEVEL_PRIVACY,
1801                  conn->cli->domain, conn->cli->user_name, conn_pwd, &result);
1802
1803         if (conn->lsa_pipe == NULL) {
1804                 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
1805                           "domain %s using NTLMSSP authenticated pipe: user "
1806                           "%s\\%s. Error was %s. Trying schannel.\n",
1807                           domain->name, conn->cli->domain,
1808                           conn->cli->user_name, nt_errstr(result)));
1809                 goto schannel;
1810         }
1811
1812         DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
1813                   "NTLMSSP authenticated pipe: user %s\\%s\n",
1814                   domain->name, conn->cli->domain, conn->cli->user_name ));
1815
1816         result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
1817                                         SEC_RIGHTS_MAXIMUM_ALLOWED,
1818                                         &conn->lsa_policy);
1819         if (NT_STATUS_IS_OK(result)) {
1820                 goto done;
1821         }
1822
1823         DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
1824                   "schannel\n"));
1825
1826         cli_rpc_pipe_close(conn->lsa_pipe);
1827
1828  schannel:
1829
1830         /* Fall back to schannel if it's a W2K pre-SP1 box. */
1831
1832         if (!cm_get_schannel_dcinfo(domain, &p_dcinfo)) {
1833                 /* If this call fails - conn->cli can now be NULL ! */
1834                 DEBUG(10, ("cm_connect_lsa: Could not get schannel auth info "
1835                            "for domain %s, trying anon\n", domain->name));
1836                 goto anonymous;
1837         }
1838         conn->lsa_pipe = cli_rpc_pipe_open_schannel_with_key
1839                 (conn->cli, PI_LSARPC, PIPE_AUTH_LEVEL_PRIVACY,
1840                  domain->name, p_dcinfo, &result);
1841
1842         if (conn->lsa_pipe == NULL) {
1843                 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
1844                           "domain %s using schannel. Error was %s\n",
1845                           domain->name, nt_errstr(result) ));
1846                 goto anonymous;
1847         }
1848         DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
1849                   "schannel.\n", domain->name ));
1850
1851         result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
1852                                         SEC_RIGHTS_MAXIMUM_ALLOWED,
1853                                         &conn->lsa_policy);
1854         if (NT_STATUS_IS_OK(result)) {
1855                 goto done;
1856         }
1857
1858         DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
1859                   "anonymous\n"));
1860
1861         cli_rpc_pipe_close(conn->lsa_pipe);
1862
1863  anonymous:
1864
1865         conn->lsa_pipe = cli_rpc_pipe_open_noauth(conn->cli, PI_LSARPC,
1866                                                   &result);
1867         if (conn->lsa_pipe == NULL) {
1868                 result = NT_STATUS_PIPE_NOT_AVAILABLE;
1869                 goto done;
1870         }
1871
1872         result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
1873                                         SEC_RIGHTS_MAXIMUM_ALLOWED,
1874                                         &conn->lsa_policy);
1875  done:
1876         if (!NT_STATUS_IS_OK(result)) {
1877                 invalidate_cm_connection(conn);
1878                 return result;
1879         }
1880
1881         *cli = conn->lsa_pipe;
1882         *lsa_policy = conn->lsa_policy;
1883         return result;
1884 }
1885
1886 /****************************************************************************
1887  Open the netlogon pipe to this DC. Use schannel if specified in client conf.
1888  session key stored in conn->netlogon_pipe->dc->sess_key.
1889 ****************************************************************************/
1890
1891 NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
1892                              struct rpc_pipe_client **cli)
1893 {
1894         struct winbindd_cm_conn *conn;
1895         NTSTATUS result;
1896
1897         uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
1898         uint8  mach_pwd[16];
1899         uint32  sec_chan_type;
1900         const char *account_name;
1901         struct rpc_pipe_client *netlogon_pipe = NULL;
1902
1903         *cli = NULL;
1904
1905         result = init_dc_connection(domain);
1906         if (!NT_STATUS_IS_OK(result)) {
1907                 return result;
1908         }
1909
1910         conn = &domain->conn;
1911
1912         if (conn->netlogon_pipe != NULL) {
1913                 *cli = conn->netlogon_pipe;
1914                 return NT_STATUS_OK;
1915         }
1916
1917         if (!get_trust_pw(domain->name, mach_pwd, &sec_chan_type)) {
1918                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1919         }
1920
1921         netlogon_pipe = cli_rpc_pipe_open_noauth(conn->cli, PI_NETLOGON,
1922                                                  &result);
1923         if (netlogon_pipe == NULL) {
1924                 return result;
1925         }
1926
1927         if (lp_client_schannel() != False) {
1928                 neg_flags |= NETLOGON_NEG_SCHANNEL;
1929         }
1930
1931         /* if we are a DC and this is a trusted domain, then we need to use our
1932            domain name in the net_req_auth2() request */
1933
1934         if ( IS_DC
1935                 && !strequal(domain->name, lp_workgroup())
1936                 && lp_allow_trusted_domains() ) 
1937         {
1938                 account_name = lp_workgroup();
1939         } else {
1940                 account_name = domain->primary ?
1941                         global_myname() : domain->name;
1942         }
1943
1944         if (account_name == NULL) {
1945                 cli_rpc_pipe_close(netlogon_pipe);
1946                 return NT_STATUS_NO_MEMORY;
1947         }
1948
1949         result = rpccli_netlogon_setup_creds(
1950                  netlogon_pipe,
1951                  domain->dcname, /* server name. */
1952                  domain->name,   /* domain name */
1953                  global_myname(), /* client name */
1954                  account_name,   /* machine account */
1955                  mach_pwd,       /* machine password */
1956                  sec_chan_type,  /* from get_trust_pw */
1957                  &neg_flags);
1958
1959         if (!NT_STATUS_IS_OK(result)) {
1960                 cli_rpc_pipe_close(netlogon_pipe);
1961                 return result;
1962         }
1963
1964         if ((lp_client_schannel() == True) &&
1965                         ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
1966                 DEBUG(3, ("Server did not offer schannel\n"));
1967                 cli_rpc_pipe_close(netlogon_pipe);
1968                 return NT_STATUS_ACCESS_DENIED;
1969         }
1970
1971         if ((lp_client_schannel() == False) ||
1972                         ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
1973                 /* We're done - just keep the existing connection to NETLOGON
1974                  * open */
1975                 conn->netlogon_pipe = netlogon_pipe;
1976                 *cli = conn->netlogon_pipe;
1977                 return NT_STATUS_OK;
1978         }
1979
1980         /* Using the credentials from the first pipe, open a signed and sealed
1981            second netlogon pipe. The session key is stored in the schannel
1982            part of the new pipe auth struct.
1983         */
1984
1985         conn->netlogon_pipe =
1986                 cli_rpc_pipe_open_schannel_with_key(conn->cli,
1987                                                     PI_NETLOGON,
1988                                                     PIPE_AUTH_LEVEL_PRIVACY,
1989                                                     domain->name,
1990                                                     netlogon_pipe->dc,
1991                                                     &result);
1992
1993         /* We can now close the initial netlogon pipe. */
1994         cli_rpc_pipe_close(netlogon_pipe);
1995
1996         if (conn->netlogon_pipe == NULL) {
1997                 DEBUG(3, ("Could not open schannel'ed NETLOGON pipe. Error "
1998                           "was %s\n", nt_errstr(result)));
1999                           
2000                 /* make sure we return something besides OK */
2001                 return !NT_STATUS_IS_OK(result) ? result : NT_STATUS_PIPE_NOT_AVAILABLE;
2002         }
2003
2004         *cli = conn->netlogon_pipe;
2005         return NT_STATUS_OK;
2006 }