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