r10656: BIG merge from trunk. Features not copied over
[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    
11    This program is free software; you can redistribute it and/or modify
12    it under the terms of the GNU General Public License as published by
13    the Free Software Foundation; either version 2 of the License, or
14    (at your option) any later version.
15    
16    This program is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19    GNU General Public License for more details.
20    
21    You should have received a copy of the GNU General Public License
22    along with this program; if not, write to the Free Software
23    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26 /*
27    We need to manage connections to domain controllers without having to
28    mess up the main winbindd code with other issues.  The aim of the
29    connection manager is to:
30   
31        - make connections to domain controllers and cache them
32        - re-establish connections when networks or servers go down
33        - centralise the policy on connection timeouts, domain controller
34          selection etc
35        - manage re-entrancy for when winbindd becomes able to handle
36          multiple outstanding rpc requests
37   
38    Why not have connection management as part of the rpc layer like tng?
39    Good question.  This code may morph into libsmb/rpc_cache.c or something
40    like that but at the moment it's simply staying as part of winbind.  I
41    think the TNG architecture of forcing every user of the rpc layer to use
42    the connection caching system is a bad idea.  It should be an optional
43    method of using the routines.
44
45    The TNG design is quite good but I disagree with some aspects of the
46    implementation. -tpot
47
48  */
49
50 /*
51    TODO:
52
53      - I'm pretty annoyed by all the make_nmb_name() stuff.  It should be
54        moved down into another function.
55
56      - Take care when destroying cli_structs as they can be shared between
57        various sam handles.
58
59  */
60
61 #include "includes.h"
62 #include "winbindd.h"
63
64 #undef DBGC_CLASS
65 #define DBGC_CLASS DBGC_WINBIND
66
67
68 /****************************************************************** 
69    Disabling schannl on the LSA pipe for now since 
70    both Win2K-SP4 SR1 & Win2K3-SP1 fail the open_policy() 
71    call (return codes 0xc0020042 and 0xc0020041 respectively).
72    We really need to fix this soon.  Had to disable on the 
73    SAMR pipe as well for now.   --jerry
74 ******************************************************************/
75
76 /* #define DISABLE_SCHANNEL_WIN2K3_SP1  1 */
77
78
79 /* Choose between anonymous or authenticated connections.  We need to use
80    an authenticated connection if DCs have the RestrictAnonymous registry
81    entry set > 0, or the "Additional restrictions for anonymous
82    connections" set in the win2k Local Security Policy. 
83    
84    Caller to free() result in domain, username, password
85 */
86
87 static void cm_get_ipc_userpass(char **username, char **domain, char **password)
88 {
89         *username = secrets_fetch(SECRETS_AUTH_USER, NULL);
90         *domain = secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
91         *password = secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
92         
93         if (*username && **username) {
94
95                 if (!*domain || !**domain)
96                         *domain = smb_xstrdup(lp_workgroup());
97                 
98                 if (!*password || !**password)
99                         *password = smb_xstrdup("");
100
101                 DEBUG(3, ("cm_get_ipc_userpass: Retrieved auth-user from secrets.tdb [%s\\%s]\n", 
102                           *domain, *username));
103
104         } else {
105                 DEBUG(3, ("cm_get_ipc_userpass: No auth-user defined\n"));
106                 *username = smb_xstrdup("");
107                 *domain = smb_xstrdup("");
108                 *password = smb_xstrdup("");
109         }
110 }
111
112 static BOOL get_dc_name_via_netlogon(const struct winbindd_domain *domain,
113                                      fstring dcname, struct in_addr *dc_ip)
114 {
115         struct winbindd_domain *our_domain;
116         struct rpc_pipe_client *netlogon_pipe;
117         NTSTATUS result;
118         TALLOC_CTX *mem_ctx;
119
120         fstring tmp;
121         char *p;
122
123         /* Hmmmm. We can only open one connection to the NETLOGON pipe at the
124          * moment.... */
125
126         if (IS_DC) {
127                 return False;
128         }
129
130         if (domain->primary) {
131                 return False;
132         }
133
134         our_domain = find_our_domain();
135
136         if ((mem_ctx = talloc_init("get_dc_name_via_netlogon")) == NULL) {
137                 return False;
138         }
139
140         result = cm_connect_netlogon(our_domain, &netlogon_pipe);
141         if (!NT_STATUS_IS_OK(result)) {
142                 return False;
143         }
144
145         result = rpccli_netlogon_getdcname(netlogon_pipe, mem_ctx, domain->dcname,
146                                            domain->name, tmp);
147
148         talloc_destroy(mem_ctx);
149
150         if (!NT_STATUS_IS_OK(result))
151                 return False;
152
153         /* cli_netlogon_getdcname gives us a name with \\ */
154         p = tmp;
155         if (*p == '\\') {
156                 p+=1;
157         }
158         if (*p == '\\') {
159                 p+=1;
160         }
161
162         fstrcpy(dcname, p);
163
164         if (!resolve_name(dcname, dc_ip, 0x20)) {
165                 return False;
166         }
167
168         return True;
169 }
170
171 /************************************************************************
172  Given a fd with a just-connected TCP connection to a DC, open a connection
173  to the pipe.
174 ************************************************************************/
175
176 static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
177                                       const int sockfd,
178                                       const char *controller,
179                                       struct cli_state **cli,
180                                       BOOL *retry)
181 {
182         char *machine_password, *machine_krb5_principal, *machine_account;
183         char *ipc_username, *ipc_domain, *ipc_password;
184
185         BOOL got_mutex;
186         BOOL add_failed_connection = True;
187
188         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
189
190         struct sockaddr peeraddr;
191         socklen_t peeraddr_len;
192
193         struct sockaddr_in *peeraddr_in = (struct sockaddr_in *)&peeraddr;
194
195         machine_password = secrets_fetch_machine_password(lp_workgroup(), NULL,
196                                                           NULL);
197         
198         if (asprintf(&machine_account, "%s$", global_myname()) == -1) {
199                 SAFE_FREE(machine_password);
200                 return NT_STATUS_NO_MEMORY;
201         }
202
203         if (asprintf(&machine_krb5_principal, "%s$@%s", global_myname(),
204                      lp_realm()) == -1) {
205                 SAFE_FREE(machine_account);
206                 SAFE_FREE(machine_password);
207                 return NT_STATUS_NO_MEMORY;
208         }
209
210         cm_get_ipc_userpass(&ipc_username, &ipc_domain, &ipc_password);
211
212         *retry = True;
213
214         got_mutex = secrets_named_mutex(controller,
215                                         WINBIND_SERVER_MUTEX_WAIT_TIME);
216
217         if (!got_mutex) {
218                 DEBUG(0,("cm_open_connection: mutex grab failed for %s\n",
219                          controller));
220                 result = NT_STATUS_POSSIBLE_DEADLOCK;
221                 goto done;
222         }
223
224         if ((*cli = cli_initialise(NULL)) == NULL) {
225                 DEBUG(1, ("Could not cli_initialize\n"));
226                 result = NT_STATUS_NO_MEMORY;
227                 goto done;
228         }
229
230         (*cli)->timeout = 10000;        /* 10 seconds */
231         (*cli)->fd = sockfd;
232         fstrcpy((*cli)->desthost, controller);
233         (*cli)->use_kerberos = True;
234
235         peeraddr_len = sizeof(peeraddr);
236
237         if ((getpeername((*cli)->fd, &peeraddr, &peeraddr_len) != 0) ||
238             (peeraddr_len != sizeof(struct sockaddr_in)) ||
239             (peeraddr_in->sin_family != PF_INET))
240         {
241                 DEBUG(0,("cm_prepare_connection: %s\n", strerror(errno)));
242                 goto done;
243         }
244
245         if (ntohs(peeraddr_in->sin_port) == 139) {
246                 struct nmb_name calling;
247                 struct nmb_name called;
248
249                 make_nmb_name(&calling, global_myname(), 0x0);
250                 make_nmb_name(&called, "*SMBSERVER", 0x20);
251
252                 if (!cli_session_request(*cli, &calling, &called)) {
253                         DEBUG(8, ("cli_session_request failed for %s\n",
254                                   controller));
255                         goto done;
256                 }
257         }
258
259         cli_setup_signing_state(*cli, Undefined);
260
261         if (!cli_negprot(*cli)) {
262                 DEBUG(1, ("cli_negprot failed\n"));
263                 cli_shutdown(*cli);
264                 goto done;
265         }
266
267                         
268         if ((*cli)->protocol >= PROTOCOL_NT1 && (*cli)->capabilities & CAP_EXTENDED_SECURITY) {
269                 ADS_STATUS ads_status;
270
271                 if (lp_security() == SEC_ADS) {
272
273                         /* Try a krb5 session */
274
275                         (*cli)->use_kerberos = True;
276                         DEBUG(5, ("connecting to %s from %s with kerberos principal "
277                                   "[%s]\n", controller, global_myname(),
278                                   machine_krb5_principal));
279
280                         ads_status = cli_session_setup_spnego(*cli,
281                                                               machine_krb5_principal, 
282                                                               machine_password, 
283                                                               lp_workgroup());
284
285                         if (!ADS_ERR_OK(ads_status)) {
286                                 DEBUG(4,("failed kerberos session setup with %s\n",
287                                          ads_errstr(ads_status)));
288                         }
289
290                         result = ads_ntstatus(ads_status);
291                         if (NT_STATUS_IS_OK(result)) {
292                                 /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
293                                 cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
294                                 goto session_setup_done;
295                         }
296                 }
297
298                 /* Fall back to non-kerberos session setup using NTLMSSP SPNEGO with the machine account. */
299                 (*cli)->use_kerberos = False;
300
301                 DEBUG(5, ("connecting to %s from %s with username "
302                           "[%s]\\[%s]\n",  controller, global_myname(),
303                           machine_account, machine_password));
304
305                 ads_status = cli_session_setup_spnego(*cli,
306                                                       machine_account, 
307                                                       machine_password, 
308                                                       lp_workgroup());
309                 if (!ADS_ERR_OK(ads_status)) {
310                         DEBUG(4, ("authenticated session setup failed with %s\n",
311                                 ads_errstr(ads_status)));
312                 }
313
314                 result = ads_ntstatus(ads_status);
315                 if (NT_STATUS_IS_OK(result)) {
316                         /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
317                         cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
318                         goto session_setup_done;
319                 }
320         }
321
322         /* Fall back to non-kerberos session setup */
323
324         (*cli)->use_kerberos = False;
325
326         if ((((*cli)->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) != 0) &&
327             (strlen(ipc_username) > 0)) {
328
329                 /* Only try authenticated if we have a username */
330
331                 DEBUG(5, ("connecting to %s from %s with username "
332                           "[%s]\\[%s]\n",  controller, global_myname(),
333                           ipc_domain, ipc_username));
334
335                 if (cli_session_setup(*cli, ipc_username,
336                                       ipc_password, strlen(ipc_password)+1,
337                                       ipc_password, strlen(ipc_password)+1,
338                                       ipc_domain)) {
339                         /* Successful logon with given username. */
340                         cli_init_creds(*cli, ipc_username, ipc_domain, ipc_password);
341                         goto session_setup_done;
342                 } else {
343                         DEBUG(4, ("authenticated session setup with user %s\\%s failed.\n",
344                                 ipc_domain, ipc_username ));
345                 }
346         }
347
348         /* Fall back to anonymous connection, this might fail later */
349
350         if (cli_session_setup(*cli, "", NULL, 0, NULL, 0, "")) {
351                 DEBUG(5, ("Connected anonymously\n"));
352                 cli_init_creds(*cli, "", "", "");
353                 goto session_setup_done;
354         }
355
356         result = cli_nt_error(*cli);
357
358         if (NT_STATUS_IS_OK(result))
359                 result = NT_STATUS_UNSUCCESSFUL;
360
361         /* We can't session setup */
362
363         goto done;
364
365  session_setup_done:
366
367         if (!cli_send_tconX(*cli, "IPC$", "IPC", "", 0)) {
368
369                 result = cli_nt_error(*cli);
370
371                 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(result)));
372
373                 if (NT_STATUS_IS_OK(result))
374                         result = NT_STATUS_UNSUCCESSFUL;
375
376                 cli_shutdown(*cli);
377                 goto done;
378         }
379
380         secrets_named_mutex_release(controller);
381         got_mutex = False;
382         *retry = False;
383
384         /* set the domain if empty; needed for schannel connections */
385         if ( !*(*cli)->domain ) {
386                 fstrcpy( (*cli)->domain, domain->name );
387         }
388
389         result = NT_STATUS_OK;
390         add_failed_connection = False;
391
392  done:
393         if (got_mutex) {
394                 secrets_named_mutex_release(controller);
395         }
396
397         SAFE_FREE(machine_account);
398         SAFE_FREE(machine_password);
399         SAFE_FREE(machine_krb5_principal);
400         SAFE_FREE(ipc_username);
401         SAFE_FREE(ipc_domain);
402         SAFE_FREE(ipc_password);
403
404         if (add_failed_connection) {
405                 add_failed_connection_entry(domain->name, controller, result);
406         }
407
408         return result;
409 }
410
411 struct dc_name_ip {
412         fstring name;
413         struct in_addr ip;
414 };
415
416 static BOOL add_one_dc_unique(TALLOC_CTX *mem_ctx, const char *domain_name,
417                               const char *dcname, struct in_addr ip,
418                               struct dc_name_ip **dcs, int *num)
419 {
420         if (!NT_STATUS_IS_OK(check_negative_conn_cache(domain_name, dcname)))
421                 return False;
422
423         *dcs = TALLOC_REALLOC_ARRAY(mem_ctx, *dcs, struct dc_name_ip, (*num)+1);
424
425         if (*dcs == NULL)
426                 return False;
427
428         fstrcpy((*dcs)[*num].name, dcname);
429         (*dcs)[*num].ip = ip;
430         *num += 1;
431         return True;
432 }
433
434 static BOOL add_sockaddr_to_array(TALLOC_CTX *mem_ctx,
435                                   struct in_addr ip, uint16 port,
436                                   struct sockaddr_in **addrs, int *num)
437 {
438         *addrs = TALLOC_REALLOC_ARRAY(mem_ctx, *addrs, struct sockaddr_in, (*num)+1);
439
440         if (*addrs == NULL)
441                 return False;
442
443         (*addrs)[*num].sin_family = PF_INET;
444         putip((char *)&((*addrs)[*num].sin_addr), (char *)&ip);
445         (*addrs)[*num].sin_port = htons(port);
446
447         *num += 1;
448         return True;
449 }
450
451 static void mailslot_name(struct in_addr dc_ip, fstring name)
452 {
453         fstr_sprintf(name, "\\MAILSLOT\\NET\\GETDC%X", dc_ip.s_addr);
454 }
455
456 static BOOL send_getdc_request(struct in_addr dc_ip,
457                                const char *domain_name,
458                                const DOM_SID *sid)
459 {
460         pstring outbuf;
461         char *p;
462         fstring my_acct_name;
463         fstring my_mailslot;
464
465         mailslot_name(dc_ip, my_mailslot);
466
467         memset(outbuf, '\0', sizeof(outbuf));
468
469         p = outbuf;
470
471         SCVAL(p, 0, SAMLOGON);
472         p++;
473
474         SCVAL(p, 0, 0); /* Count pointer ... */
475         p++;
476
477         SIVAL(p, 0, 0); /* The sender's token ... */
478         p += 2;
479
480         p += dos_PutUniCode(p, global_myname(), sizeof(pstring), True);
481         fstr_sprintf(my_acct_name, "%s$", global_myname());
482         p += dos_PutUniCode(p, my_acct_name, sizeof(pstring), True);
483
484         memcpy(p, my_mailslot, strlen(my_mailslot)+1);
485         p += strlen(my_mailslot)+1;
486
487         SIVAL(p, 0, 0x80);
488         p+=4;
489
490         SIVAL(p, 0, sid_size(sid));
491         p+=4;
492
493         p = ALIGN4(p, outbuf);
494
495         sid_linearize(p, sid_size(sid), sid);
496         p += sid_size(sid);
497
498         SIVAL(p, 0, 1);
499         SSVAL(p, 4, 0xffff);
500         SSVAL(p, 6, 0xffff);
501         p+=8;
502
503         return cli_send_mailslot(False, "\\MAILSLOT\\NET\\NTLOGON", 0,
504                                  outbuf, PTR_DIFF(p, outbuf),
505                                  global_myname(), 0, domain_name, 0x1c,
506                                  dc_ip);
507 }
508
509 static BOOL receive_getdc_response(struct in_addr dc_ip,
510                                    const char *domain_name,
511                                    fstring dc_name)
512 {
513         struct packet_struct *packet;
514         fstring my_mailslot;
515         char *buf, *p;
516         fstring dcname, user, domain;
517         int len;
518
519         mailslot_name(dc_ip, my_mailslot);
520
521         packet = receive_unexpected(DGRAM_PACKET, 0, my_mailslot);
522
523         if (packet == NULL) {
524                 DEBUG(5, ("Did not receive packet for %s\n", my_mailslot));
525                 return False;
526         }
527
528         DEBUG(5, ("Received packet for %s\n", my_mailslot));
529
530         buf = packet->packet.dgram.data;
531         len = packet->packet.dgram.datasize;
532
533         if (len < 70) {
534                 /* 70 is a completely arbitrary value to make sure
535                    the SVAL below does not read uninitialized memory */
536                 DEBUG(3, ("GetDC got short response\n"));
537                 return False;
538         }
539
540         /* This should be (buf-4)+SVAL(buf-4, smb_vwv12)... */
541         p = buf+SVAL(buf, smb_vwv10);
542
543         if (CVAL(p,0) != SAMLOGON_R) {
544                 DEBUG(8, ("GetDC got invalid response type %d\n", CVAL(p, 0)));
545                 return False;
546         }
547
548         p+=2;
549         pull_ucs2(buf, dcname, p, sizeof(dcname), PTR_DIFF(buf+len, p),
550                   STR_TERMINATE|STR_NOALIGN);
551         p = skip_unibuf(p, PTR_DIFF(buf+len, p));
552         pull_ucs2(buf, user, p, sizeof(dcname), PTR_DIFF(buf+len, p),
553                   STR_TERMINATE|STR_NOALIGN);
554         p = skip_unibuf(p, PTR_DIFF(buf+len, p));
555         pull_ucs2(buf, domain, p, sizeof(dcname), PTR_DIFF(buf+len, p),
556                   STR_TERMINATE|STR_NOALIGN);
557         p = skip_unibuf(p, PTR_DIFF(buf+len, p));
558
559         if (!strequal(domain, domain_name)) {
560                 DEBUG(3, ("GetDC: Expected domain %s, got %s\n",
561                           domain_name, domain));
562                 return False;
563         }
564
565         p = dcname;
566         if (*p == '\\') p += 1;
567         if (*p == '\\') p += 1;
568
569         fstrcpy(dc_name, p);
570
571         DEBUG(10, ("GetDC gave name %s for domain %s\n",
572                    dc_name, domain));
573
574         return True;
575 }
576
577 /*******************************************************************
578  convert an ip to a name
579 *******************************************************************/
580
581 static void dcip_to_name( const char *domainname, const char *realm, 
582                           const DOM_SID *sid, struct in_addr ip, fstring name )
583 {
584         int i;
585
586         /* try GETDC requests first */
587         
588         send_getdc_request(ip, domainname, sid);
589         smb_msleep(100);
590
591         for (i=0; i<5; i++) {
592                 if (receive_getdc_response(ip, domainname, name))
593                         return;
594                 smb_msleep(500);
595         }
596
597         /* try node status request */
598
599         if ( name_status_find(domainname, 0x1c, 0x20, ip, name) )
600                 return;
601
602         /* backup in case the netbios stuff fails */
603
604         fstrcpy( name, inet_ntoa(ip) );
605
606 #ifdef WITH_ADS
607         /* for active directory servers, try to get the ldap server name.
608            None of these failure should be considered critical for now */
609
610         if ( lp_security() == SEC_ADS ) 
611         {
612                 ADS_STRUCT *ads;
613                 ADS_STATUS status;
614
615                 ads = ads_init( realm, domainname, NULL );
616                 ads->auth.flags |= ADS_AUTH_NO_BIND;
617
618                 if ( !ads_try_connect( ads, inet_ntoa(ip), LDAP_PORT ) )  {
619                         ads_destroy( &ads );
620                         return;
621                 }
622
623                 status = ads_server_info(ads);
624                 if ( !ADS_ERR_OK(status) ) {
625                         ads_destroy( &ads );
626                         return;
627                 }
628
629                 fstrcpy(name, ads->config.ldap_server_name);
630
631                 ads_destroy( &ads );
632         }
633 #endif
634
635         return;
636 }
637
638 /*******************************************************************
639  Retreive a list of IP address for domain controllers.  Fill in 
640  the dcs[]  with results.
641 *******************************************************************/
642
643 static BOOL get_dcs(TALLOC_CTX *mem_ctx, const struct winbindd_domain *domain,
644                     struct dc_name_ip **dcs, int *num_dcs)
645 {
646         fstring dcname;
647         struct  in_addr ip;
648         struct  ip_service *ip_list = NULL;
649         int     iplist_size = 0;
650         int     i;
651         BOOL    is_our_domain;
652
653
654         is_our_domain = strequal(domain->name, lp_workgroup());
655
656         if ( !is_our_domain 
657                 && get_dc_name_via_netlogon(domain, dcname, &ip) 
658                 && add_one_dc_unique(mem_ctx, domain->name, dcname, ip, dcs, num_dcs) )
659         {
660                 return True;
661         }
662
663         if ( is_our_domain 
664                 && must_use_pdc(domain->name) 
665                 && get_pdc_ip(domain->name, &ip)) 
666         {
667                 if (add_one_dc_unique(mem_ctx, domain->name, inet_ntoa(ip), ip, dcs, num_dcs)) 
668                         return True;
669         }
670
671         /* try standard netbios queries first */
672
673         get_sorted_dc_list(domain->name, &ip_list, &iplist_size, False);
674
675         /* check for security = ads and use DNS if we can */
676
677         if ( iplist_size==0 && lp_security() == SEC_ADS ) 
678                 get_sorted_dc_list(domain->alt_name, &ip_list, &iplist_size, True);
679
680         /* FIXME!! this is where we should re-insert the GETDC requests --jerry */
681
682         /* now add to the dc array.  We'll wait until the last minute 
683            to look up the name of the DC.  But we fill in the char* for 
684            the ip now in to make the failed connection cache work */
685
686         for ( i=0; i<iplist_size; i++ ) {
687                 add_one_dc_unique(mem_ctx, domain->name, inet_ntoa(ip_list[i].ip), 
688                         ip_list[i].ip, dcs, num_dcs);
689         }
690
691         SAFE_FREE( ip_list );
692
693         return True;
694 }
695
696 static BOOL find_new_dc(TALLOC_CTX *mem_ctx,
697                         const struct winbindd_domain *domain,
698                         fstring dcname, struct sockaddr_in *addr, int *fd)
699 {
700         struct dc_name_ip *dcs = NULL;
701         int num_dcs = 0;
702
703         const char **dcnames = NULL;
704         int num_dcnames = 0;
705
706         struct sockaddr_in *addrs = NULL;
707         int num_addrs = 0;
708
709         int i, fd_index;
710
711         if (!get_dcs(mem_ctx, domain, &dcs, &num_dcs) || (num_dcs == 0))
712                 return False;
713
714         for (i=0; i<num_dcs; i++) {
715
716                 add_string_to_array(mem_ctx, dcs[i].name,
717                                     &dcnames, &num_dcnames);
718                 add_sockaddr_to_array(mem_ctx, dcs[i].ip, 445,
719                                       &addrs, &num_addrs);
720
721                 add_string_to_array(mem_ctx, dcs[i].name,
722                                     &dcnames, &num_dcnames);
723                 add_sockaddr_to_array(mem_ctx, dcs[i].ip, 139,
724                                       &addrs, &num_addrs);
725         }
726
727         if ((num_dcnames == 0) || (num_dcnames != num_addrs))
728                 return False;
729
730         if ( !open_any_socket_out(addrs, num_addrs, 10000, &fd_index, fd) ) 
731         {
732                 for (i=0; i<num_dcs; i++) {
733                         add_failed_connection_entry(domain->name,
734                                 dcs[i].name, NT_STATUS_UNSUCCESSFUL);
735                 }
736                 return False;
737         }
738
739         *addr = addrs[fd_index];
740
741         /* if we have no name on the server or just an IP address for 
742            the name, now try to get the name */
743
744         if ( is_ipaddress(dcnames[fd_index]) || *dcnames[fd_index] == '\0' )
745                 dcip_to_name( domain->name, domain->alt_name, &domain->sid, addr->sin_addr, dcname );
746         else
747                 fstrcpy(dcname, dcnames[fd_index]);
748
749         return True;
750 }
751
752 static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
753                                    struct winbindd_cm_conn *new_conn)
754 {
755         TALLOC_CTX *mem_ctx;
756         NTSTATUS result;
757
758         int retries;
759
760         if ((mem_ctx = talloc_init("cm_open_connection")) == NULL)
761                 return NT_STATUS_NO_MEMORY;
762
763         for (retries = 0; retries < 3; retries++) {
764
765                 int fd = -1;
766                 BOOL retry = False;
767
768                 result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
769
770                 if ((strlen(domain->dcname) > 0) &&
771                     NT_STATUS_IS_OK(check_negative_conn_cache(domain->name,
772                                                               domain->dcname))) {
773                         int dummy;
774                         if (!open_any_socket_out(&domain->dcaddr, 1, 10000,
775                                                  &dummy, &fd)) {
776                                 fd = -1;
777                         }
778                 }
779
780                 if ((fd == -1) &&
781                     !find_new_dc(mem_ctx, domain, domain->dcname,
782                                  &domain->dcaddr, &fd))
783                         break;
784
785                 new_conn->cli = NULL;
786
787                 result = cm_prepare_connection(domain, fd, domain->dcname,
788                         &new_conn->cli, &retry);
789
790                 if (!retry)
791                         break;
792         }
793
794         talloc_destroy(mem_ctx);
795         return result;
796 }
797
798 /* Return true if a connection is still alive */
799
800 void invalidate_cm_connection(struct winbindd_cm_conn *conn)
801 {
802         if (conn->samr_pipe != NULL) {
803                 cli_rpc_pipe_close(conn->samr_pipe);
804                 conn->samr_pipe = NULL;
805         }
806
807         if (conn->lsa_pipe != NULL) {
808                 cli_rpc_pipe_close(conn->lsa_pipe);
809                 conn->lsa_pipe = NULL;
810         }
811
812         if (conn->netlogon_pipe != NULL) {
813                 cli_rpc_pipe_close(conn->netlogon_pipe);
814                 conn->netlogon_pipe = NULL;
815         }
816
817         if (conn->cli) {
818                 cli_shutdown(conn->cli);
819         }
820
821         conn->cli = NULL;
822 }
823
824 void close_conns_after_fork(void)
825 {
826         struct winbindd_domain *domain;
827
828         for (domain = domain_list(); domain; domain = domain->next) {
829                 if (domain->conn.cli == NULL)
830                         continue;
831
832                 if (domain->conn.cli->fd == -1)
833                         continue;
834
835                 close(domain->conn.cli->fd);
836                 domain->conn.cli->fd = -1;
837         }
838 }
839
840 static BOOL connection_ok(struct winbindd_domain *domain)
841 {
842         if (domain->conn.cli == NULL) {
843                 DEBUG(8, ("Connection to %s for domain %s has NULL "
844                           "cli!\n", domain->dcname, domain->name));
845                 return False;
846         }
847
848         if (!domain->conn.cli->initialised) {
849                 DEBUG(3, ("Connection to %s for domain %s was never "
850                           "initialised!\n", domain->dcname, domain->name));
851                 return False;
852         }
853
854         if (domain->conn.cli->fd == -1) {
855                 DEBUG(3, ("Connection to %s for domain %s has died or was "
856                           "never started (fd == -1)\n", 
857                           domain->dcname, domain->name));
858                 return False;
859         }
860
861         return True;
862 }
863         
864 /* Initialize a new connection up to the RPC BIND. */
865
866 static NTSTATUS init_dc_connection(struct winbindd_domain *domain)
867 {
868         if (connection_ok(domain))
869                 return NT_STATUS_OK;
870
871         invalidate_cm_connection(&domain->conn);
872
873         return cm_open_connection(domain, &domain->conn);
874 }
875
876 /**********************************************************************************
877  We can 'sense' certain things about the DC by it's replies to certain questions.
878
879  This tells us if this particular remote server is Active Directory, and if it is
880  native mode.
881 **********************************************************************************/
882
883 void set_dc_type_and_flags( struct winbindd_domain *domain )
884 {
885         NTSTATUS                result;
886         DS_DOMINFO_CTR          ctr;
887         TALLOC_CTX              *mem_ctx = NULL;
888         struct rpc_pipe_client  *cli;
889         POLICY_HND pol;
890         
891         char *domain_name = NULL;
892         char *dns_name = NULL;
893         DOM_SID *dom_sid = NULL;
894
895         ZERO_STRUCT( ctr );
896         
897         domain->native_mode = False;
898         domain->active_directory = False;
899
900         if (domain->internal) {
901                 domain->initialized = True;
902                 return;
903         }
904
905         result = init_dc_connection(domain);
906         if (!NT_STATUS_IS_OK(result)) {
907                 DEBUG(5, ("set_dc_type_and_flags: Could not open a connection "
908                           "to %s: (%s)\n", domain->name, nt_errstr(result)));
909                 domain->initialized = True;
910                 return;
911         }
912
913         cli = cli_rpc_pipe_open_noauth(domain->conn.cli, PI_LSARPC_DS, &result);
914
915         if (cli == NULL) {
916                 DEBUG(5, ("set_dc_type_and_flags: Could not bind to "
917                           "PI_LSARPC_DS on domain %s: (%s)\n",
918                           domain->name, nt_errstr(result)));
919                 domain->initialized = True;
920                 return;
921         }
922
923         result = rpccli_ds_getprimarydominfo(cli, cli->cli->mem_ctx,
924                                              DsRolePrimaryDomainInfoBasic,
925                                              &ctr);
926         cli_rpc_pipe_close(cli);
927
928         if (!NT_STATUS_IS_OK(result)) {
929                 domain->initialized = True;
930                 return;
931         }
932         
933         if ((ctr.basic->flags & DSROLE_PRIMARY_DS_RUNNING) &&
934             !(ctr.basic->flags & DSROLE_PRIMARY_DS_MIXED_MODE) )
935                 domain->native_mode = True;
936
937         cli = cli_rpc_pipe_open_noauth(domain->conn.cli, PI_LSARPC, &result);
938
939         if (cli == NULL) {
940                 domain->initialized = True;
941                 return;
942         }
943
944         mem_ctx = talloc_init("set_dc_type_and_flags on domain %s\n",
945                               domain->name);
946         if (!mem_ctx) {
947                 DEBUG(1, ("set_dc_type_and_flags: talloc_init() failed\n"));
948                 cli_rpc_pipe_close(cli);
949                 return;
950         }
951
952         result = rpccli_lsa_open_policy2(cli, mem_ctx, True, 
953                                          SEC_RIGHTS_MAXIMUM_ALLOWED, &pol);
954                 
955         if (NT_STATUS_IS_OK(result)) {
956                 /* This particular query is exactly what Win2k clients use 
957                    to determine that the DC is active directory */
958                 result = rpccli_lsa_query_info_policy2(cli, mem_ctx, &pol,
959                                                        12, &domain_name,
960                                                        &dns_name, NULL,
961                                                        NULL, &dom_sid);
962         }
963
964         if (NT_STATUS_IS_OK(result)) {
965                 if (domain_name)
966                         fstrcpy(domain->name, domain_name);
967
968                 if (dns_name)
969                         fstrcpy(domain->alt_name, dns_name);
970
971                 if (dom_sid) 
972                         sid_copy(&domain->sid, dom_sid);
973
974                 domain->active_directory = True;
975         } else {
976                 
977                 result = rpccli_lsa_open_policy(cli, mem_ctx, True, 
978                                                 SEC_RIGHTS_MAXIMUM_ALLOWED,
979                                                 &pol);
980                         
981                 if (!NT_STATUS_IS_OK(result))
982                         goto done;
983                         
984                 result = rpccli_lsa_query_info_policy(cli, mem_ctx, 
985                                                       &pol, 5, &domain_name, 
986                                                       &dom_sid);
987                         
988                 if (NT_STATUS_IS_OK(result)) {
989                         if (domain_name)
990                                 fstrcpy(domain->name, domain_name);
991
992                         if (dom_sid) 
993                                 sid_copy(&domain->sid, dom_sid);
994                 }
995         }
996 done:
997
998         cli_rpc_pipe_close(cli);
999         
1000         talloc_destroy(mem_ctx);
1001
1002         domain->initialized = True;
1003         
1004         return;
1005 }
1006
1007 #ifndef DISABLE_SCHANNEL_WIN2K3_SP1
1008 static BOOL cm_get_schannel_dcinfo(struct winbindd_domain *domain, struct dcinfo **ppdc)
1009 {
1010         NTSTATUS result;
1011         struct rpc_pipe_client *netlogon_pipe;
1012
1013         if (lp_client_schannel() == False) {
1014                 return False;
1015         }
1016
1017         result = cm_connect_netlogon(domain, &netlogon_pipe);
1018         if (!NT_STATUS_IS_OK(result)) {
1019                 return False;
1020         }
1021
1022         /* Return a pointer to the struct dcinfo from the
1023            netlogon pipe. */
1024
1025         *ppdc = domain->conn.netlogon_pipe->dc;
1026         return True;
1027 }
1028 #endif
1029
1030 NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
1031                         struct rpc_pipe_client **cli, POLICY_HND *sam_handle)
1032 {
1033         struct winbindd_cm_conn *conn;
1034         NTSTATUS result;
1035
1036         result = init_dc_connection(domain);
1037         if (!NT_STATUS_IS_OK(result)) {
1038                 return result;
1039         }
1040
1041         conn = &domain->conn;
1042
1043         if (conn->samr_pipe == NULL) {
1044                 /*
1045                  * No SAMR pipe yet. Attempt to get an NTLMSSP SPNEGO
1046                  * authenticated sign and sealed pipe using the machine
1047                  * account password by preference. If we can't - try schannel,
1048                  * if that fails, try anonymous.
1049                  */
1050
1051                 fstring conn_pwd;
1052                 pwd_get_cleartext(&conn->cli->pwd, conn_pwd);
1053                 if (conn->cli->user_name[0] && conn->cli->domain[0] &&
1054                     conn_pwd[0]) {
1055                         /* We have an authenticated connection. Use
1056                            a NTLMSSP SPNEGO authenticated SAMR pipe with
1057                            sign & seal. */
1058                         conn->samr_pipe =
1059                                 cli_rpc_pipe_open_spnego_ntlmssp(conn->cli,
1060                                                                  PI_SAMR,
1061                                                                  PIPE_AUTH_LEVEL_PRIVACY,
1062                                                                  conn->cli->domain,
1063                                                                  conn->cli->user_name,
1064                                                                  conn_pwd,
1065                                                                  &result);
1066                         if (conn->samr_pipe == NULL) {
1067                                 DEBUG(10,("cm_connect_sam: failed to connect "
1068                                           "to SAMR pipe for domain %s using "
1069                                           "NTLMSSP authenticated pipe: user "
1070                                           "%s\\%s. Error was %s\n",
1071                                           domain->name, conn->cli->domain,
1072                                           conn->cli->user_name,
1073                                           nt_errstr(result)));
1074                         } else {
1075                                 DEBUG(10,("cm_connect_sam: connected to SAMR "
1076                                           "pipe for domain %s using NTLMSSP "
1077                                           "authenticated pipe: user %s\\%s\n",
1078                                           domain->name, conn->cli->domain,
1079                                           conn->cli->user_name ));
1080                         }
1081                 }
1082
1083 #ifndef DISABLE_SCHANNEL_WIN2K3_SP1
1084                 /* Fall back to schannel if it's a W2K pre-SP1 box. */
1085                 if (conn->samr_pipe == NULL) {
1086                         struct dcinfo *p_dcinfo;
1087
1088                         if (cm_get_schannel_dcinfo(domain, &p_dcinfo)) {
1089                                 conn->samr_pipe =
1090                                         cli_rpc_pipe_open_schannel_with_key(conn->cli,
1091                                                                             PI_SAMR,
1092                                                                             PIPE_AUTH_LEVEL_PRIVACY,
1093                                                                             domain->name,
1094                                                                             p_dcinfo,
1095                                                                             &result);
1096                         }
1097                         if (conn->samr_pipe == NULL) {
1098                                 DEBUG(10,("cm_connect_sam: failed to connect "
1099                                           "to SAMR pipe for domain %s using "
1100                                           "schannel authenticated. Error "
1101                                           "was %s\n", domain->name,
1102                                           nt_errstr(result) ));
1103                         } else {
1104                                 DEBUG(10,("cm_connect_sam: connected to SAMR "
1105                                           "pipe for domain %s using schannel.\n",
1106                                           domain->name ));
1107                         }
1108                 }
1109 #endif  /* DISABLE_SCHANNEL_WIN2K3_SP1 */
1110
1111                 /* Finally fall back to anonymous. */
1112                 if (conn->samr_pipe == NULL) {
1113                         conn->samr_pipe =
1114                                 cli_rpc_pipe_open_noauth(conn->cli, PI_SAMR, &result);
1115                 }
1116
1117                 if (conn->samr_pipe == NULL) {
1118                         result = NT_STATUS_PIPE_NOT_AVAILABLE;
1119                         goto done;
1120                 }
1121
1122                 result = rpccli_samr_connect(conn->samr_pipe, mem_ctx,
1123                                              SEC_RIGHTS_MAXIMUM_ALLOWED,
1124                                              &conn->sam_connect_handle);
1125                 if (!NT_STATUS_IS_OK(result)) {
1126                         DEBUG(10,("cm_connect_sam: rpccli_samr_connect failed "
1127                                   "for domain %s Error was %s\n",
1128                                   domain->name, nt_errstr(result) ));
1129                         goto done;
1130                 }
1131
1132                 result = rpccli_samr_open_domain(conn->samr_pipe,
1133                                                  mem_ctx,
1134                                                  &conn->sam_connect_handle,
1135                                                  SEC_RIGHTS_MAXIMUM_ALLOWED,
1136                                                  &domain->sid,
1137                                                  &conn->sam_domain_handle);
1138         }
1139
1140  done:
1141
1142         if (!NT_STATUS_IS_OK(result)) {
1143                 invalidate_cm_connection(conn);
1144                 return result;
1145         }
1146
1147         *cli = conn->samr_pipe;
1148         *sam_handle = conn->sam_domain_handle;
1149         return result;
1150 }
1151
1152 NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
1153                         struct rpc_pipe_client **cli, POLICY_HND *lsa_policy)
1154 {
1155         struct winbindd_cm_conn *conn;
1156         NTSTATUS result;
1157
1158         result = init_dc_connection(domain);
1159         if (!NT_STATUS_IS_OK(result))
1160                 return result;
1161
1162         conn = &domain->conn;
1163
1164         if (conn->lsa_pipe == NULL) {
1165                 fstring conn_pwd;
1166                 pwd_get_cleartext(&conn->cli->pwd, conn_pwd);
1167                 if (conn->cli->user_name[0] && conn->cli->domain[0] &&
1168                     conn_pwd[0]) {
1169                         /* We have an authenticated connection. Use
1170                            a NTLMSSP SPNEGO authenticated LSA pipe with
1171                            sign & seal. */
1172                         conn->lsa_pipe = 
1173                                 cli_rpc_pipe_open_spnego_ntlmssp(conn->cli,
1174                                                                  PI_LSARPC,
1175                                                                  PIPE_AUTH_LEVEL_PRIVACY,
1176                                                                  conn->cli->domain,
1177                                                                  conn->cli->user_name,
1178                                                                  conn_pwd,
1179                                                                  &result);
1180                         if (conn->lsa_pipe == NULL) {
1181                                 DEBUG(10,("cm_connect_lsa: failed to connect "
1182                                           "to LSA pipe for domain %s using "
1183                                           "NTLMSSP authenticated pipe: user "
1184                                           "%s\\%s. Error was %s\n",
1185                                           domain->name, conn->cli->domain,
1186                                           conn->cli->user_name,
1187                                           nt_errstr(result)));
1188                         } else {
1189                                 DEBUG(10,("cm_connect_lsa: connected to LSA "
1190                                           "pipe for domain %s using NTLMSSP "
1191                                           "authenticated pipe: user %s\\%s\n",
1192                                           domain->name, conn->cli->domain,
1193                                           conn->cli->user_name ));
1194                         }
1195                 }
1196                 
1197 #ifndef DISABLE_SCHANNEL_WIN2K3_SP1
1198                 /* Fall back to schannel if it's a W2K pre-SP1 box. */
1199                 if (conn->lsa_pipe == NULL) {
1200                         struct dcinfo *p_dcinfo;
1201
1202                         if (cm_get_schannel_dcinfo(domain, &p_dcinfo)) {
1203                                 conn->lsa_pipe =
1204                                         cli_rpc_pipe_open_schannel_with_key(conn->cli,
1205                                                                             PI_LSARPC,
1206                                                                             PIPE_AUTH_LEVEL_PRIVACY,
1207                                                                             domain->name,
1208                                                                             p_dcinfo,
1209                                                                             &result);
1210                         }
1211                         if (conn->lsa_pipe == NULL) {
1212                                 DEBUG(10,("cm_connect_lsa: failed to connect "
1213                                           "to LSA pipe for domain %s using "
1214                                           "schannel authenticated. Error "
1215                                           "was %s\n", domain->name,
1216                                           nt_errstr(result) ));
1217                         } else {
1218                                 DEBUG(10,("cm_connect_lsa: connected to LSA "
1219                                           "pipe for domain %s using schannel.\n",
1220                                           domain->name ));
1221                         }
1222                 }
1223 #endif  /* DISABLE_SCHANNEL_WIN2K3_SP1 */
1224
1225                 /* Finally fall back to anonymous. */
1226                 if (conn->lsa_pipe == NULL) {
1227                         conn->lsa_pipe = cli_rpc_pipe_open_noauth(conn->cli,
1228                                                                 PI_LSARPC,
1229                                                                 &result);
1230                 }
1231
1232                 if (conn->lsa_pipe == NULL) {
1233                         result = NT_STATUS_PIPE_NOT_AVAILABLE;
1234                         goto done;
1235                 }
1236
1237                 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
1238                                                 SEC_RIGHTS_MAXIMUM_ALLOWED,
1239                                                 &conn->lsa_policy);
1240         }
1241
1242  done:
1243         if (!NT_STATUS_IS_OK(result)) {
1244                 invalidate_cm_connection(conn);
1245                 return NT_STATUS_UNSUCCESSFUL;
1246         }
1247
1248         *cli = conn->lsa_pipe;
1249         *lsa_policy = conn->lsa_policy;
1250         return result;
1251 }
1252
1253 /****************************************************************************
1254  Open the netlogon pipe to this DC. Use schannel if specified in client conf.
1255  session key stored in conn->netlogon_pipe->dc->sess_key.
1256 ****************************************************************************/
1257
1258 NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain, struct rpc_pipe_client **cli)
1259 {
1260         struct winbindd_cm_conn *conn;
1261         NTSTATUS result;
1262
1263         uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
1264         uint8  mach_pwd[16];
1265         uint32  sec_chan_type;
1266         const char *account_name;
1267         struct rpc_pipe_client *netlogon_pipe;
1268
1269         result = init_dc_connection(domain);
1270         if (!NT_STATUS_IS_OK(result)) {
1271                 return result;
1272         }
1273
1274         conn = &domain->conn;
1275
1276         if (conn->netlogon_pipe != NULL) {
1277                 *cli = conn->netlogon_pipe;
1278                 return NT_STATUS_OK;
1279         }
1280
1281         if (!get_trust_pw(domain->name, mach_pwd, &sec_chan_type)) {
1282                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1283         }
1284
1285         netlogon_pipe = cli_rpc_pipe_open_noauth(conn->cli, PI_NETLOGON, &result);
1286         if (netlogon_pipe == NULL) {
1287                 return result;
1288         }
1289
1290         if (lp_client_schannel() != False) {
1291                 neg_flags |= NETLOGON_NEG_SCHANNEL;
1292         }
1293
1294         /* if we are a DC and this is a trusted domain, then we need to use our
1295            domain name in the net_req_auth2() request */
1296
1297         if ( IS_DC
1298                 && !strequal(domain->name, lp_workgroup())
1299                 && lp_allow_trusted_domains() ) 
1300         {
1301                 account_name = lp_workgroup();
1302         } else {
1303                 account_name = domain->primary ? global_myname() : domain->name;
1304         }
1305
1306         if (account_name == NULL) {
1307                 cli_rpc_pipe_close(netlogon_pipe);
1308                 return NT_STATUS_NO_MEMORY;
1309         }
1310
1311         result = rpccli_netlogon_setup_creds(netlogon_pipe,
1312                                                 domain->dcname, /* server name. */
1313                                                 domain->name,   /* domain name */
1314                                                 account_name,   /* machine account */
1315                                                 mach_pwd,       /* machine password */
1316                                                 sec_chan_type,  /* from get_trust_pw */
1317                                                 &neg_flags);
1318
1319         if (!NT_STATUS_IS_OK(result)) {
1320                 cli_rpc_pipe_close(netlogon_pipe);
1321                 return result;
1322         }
1323
1324         if ((lp_client_schannel() == True) &&
1325                         ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
1326                 DEBUG(3, ("Server did not offer schannel\n"));
1327                 cli_rpc_pipe_close(netlogon_pipe);
1328                 return NT_STATUS_ACCESS_DENIED;
1329         }
1330
1331         if ((lp_client_schannel() == False) ||
1332                         ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
1333                 /* We're done - just keep the existing connection to NETLOGON open */
1334                 conn->netlogon_pipe = netlogon_pipe;
1335                 *cli = conn->netlogon_pipe;
1336                 return NT_STATUS_OK;
1337         }
1338
1339         /* Using the credentials from the first pipe, open a signed and sealed
1340            second netlogon pipe. The session key is stored in the schannel
1341            part of the new pipe auth struct.
1342         */
1343
1344         conn->netlogon_pipe = cli_rpc_pipe_open_schannel_with_key(conn->cli,
1345                                                 PI_NETLOGON,
1346                                                 PIPE_AUTH_LEVEL_PRIVACY,
1347                                                 domain->name,
1348                                                 netlogon_pipe->dc,
1349                                                 &result);
1350
1351         /* We can now close the initial netlogon pipe. */
1352         cli_rpc_pipe_close(netlogon_pipe);
1353
1354         if (conn->netlogon_pipe == NULL) {
1355                 DEBUG(3, ("Could not open schannel'ed NETLOGON pipe. Error was %s\n",
1356                         nt_errstr(result)));
1357                 return result;
1358         }
1359
1360         *cli = conn->netlogon_pipe;
1361         return NT_STATUS_OK;
1362 }