2 Unix SMB/CIFS implementation.
4 Winbind daemon connection manager
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
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.
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.
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.
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:
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
35 - manage re-entrancy for when winbindd becomes able to handle
36 multiple outstanding rpc requests
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.
45 The TNG design is quite good but I disagree with some aspects of the
53 - I'm pretty annoyed by all the make_nmb_name() stuff. It should be
54 moved down into another function.
56 - Take care when destroying cli_structs as they can be shared between
65 #define DBGC_CLASS DBGC_WINBIND
68 /* Choose between anonymous or authenticated connections. We need to use
69 an authenticated connection if DCs have the RestrictAnonymous registry
70 entry set > 0, or the "Additional restrictions for anonymous
71 connections" set in the win2k Local Security Policy.
73 Caller to free() result in domain, username, password
76 static void cm_get_ipc_userpass(char **username, char **domain, char **password)
78 *username = secrets_fetch(SECRETS_AUTH_USER, NULL);
79 *domain = secrets_fetch(SECRETS_AUTH_DOMAIN, NULL);
80 *password = secrets_fetch(SECRETS_AUTH_PASSWORD, NULL);
82 if (*username && **username) {
84 if (!*domain || !**domain)
85 *domain = smb_xstrdup(lp_workgroup());
87 if (!*password || !**password)
88 *password = smb_xstrdup("");
90 DEBUG(3, ("cm_get_ipc_userpass: Retrieved auth-user from secrets.tdb [%s\\%s]\n",
94 DEBUG(3, ("cm_get_ipc_userpass: No auth-user defined\n"));
95 *username = smb_xstrdup("");
96 *domain = smb_xstrdup("");
97 *password = smb_xstrdup("");
101 static BOOL get_dc_name_via_netlogon(const struct winbindd_domain *domain,
102 fstring dcname, struct in_addr *dc_ip)
104 struct winbindd_domain *our_domain = NULL;
105 struct rpc_pipe_client *netlogon_pipe = NULL;
112 /* Hmmmm. We can only open one connection to the NETLOGON pipe at the
119 if (domain->primary) {
123 our_domain = find_our_domain();
125 if ((mem_ctx = talloc_init("get_dc_name_via_netlogon")) == NULL) {
129 result = cm_connect_netlogon(our_domain, &netlogon_pipe);
130 if (!NT_STATUS_IS_OK(result)) {
134 result = rpccli_netlogon_getdcname(netlogon_pipe, mem_ctx, our_domain->dcname,
137 talloc_destroy(mem_ctx);
139 if (!NT_STATUS_IS_OK(result)) {
140 DEBUG(10, ("rpccli_netlogon_getdcname failed: %s\n",
145 /* cli_netlogon_getdcname gives us a name with \\ */
156 DEBUG(10, ("rpccli_netlogon_getdcname returned %s\n", dcname));
158 if (!resolve_name(dcname, dc_ip, 0x20)) {
165 /************************************************************************
166 Given a fd with a just-connected TCP connection to a DC, open a connection
168 ************************************************************************/
170 static NTSTATUS cm_prepare_connection(const struct winbindd_domain *domain,
172 const char *controller,
173 struct cli_state **cli,
176 char *machine_password, *machine_krb5_principal, *machine_account;
177 char *ipc_username, *ipc_domain, *ipc_password;
180 BOOL add_failed_connection = True;
182 NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
184 struct sockaddr peeraddr;
185 socklen_t peeraddr_len;
187 struct sockaddr_in *peeraddr_in = (struct sockaddr_in *)&peeraddr;
189 machine_password = secrets_fetch_machine_password(lp_workgroup(), NULL,
192 if (asprintf(&machine_account, "%s$", global_myname()) == -1) {
193 SAFE_FREE(machine_password);
194 return NT_STATUS_NO_MEMORY;
197 if (asprintf(&machine_krb5_principal, "%s$@%s", global_myname(),
199 SAFE_FREE(machine_account);
200 SAFE_FREE(machine_password);
201 return NT_STATUS_NO_MEMORY;
204 cm_get_ipc_userpass(&ipc_username, &ipc_domain, &ipc_password);
208 got_mutex = secrets_named_mutex(controller,
209 WINBIND_SERVER_MUTEX_WAIT_TIME);
212 DEBUG(0,("cm_prepare_connection: mutex grab failed for %s\n",
214 result = NT_STATUS_POSSIBLE_DEADLOCK;
218 if ((*cli = cli_initialise(NULL)) == NULL) {
219 DEBUG(1, ("Could not cli_initialize\n"));
220 result = NT_STATUS_NO_MEMORY;
224 (*cli)->timeout = 10000; /* 10 seconds */
226 fstrcpy((*cli)->desthost, controller);
227 (*cli)->use_kerberos = True;
229 peeraddr_len = sizeof(peeraddr);
231 if ((getpeername((*cli)->fd, &peeraddr, &peeraddr_len) != 0) ||
232 (peeraddr_len != sizeof(struct sockaddr_in)) ||
233 (peeraddr_in->sin_family != PF_INET))
235 DEBUG(0,("cm_prepare_connection: %s\n", strerror(errno)));
239 if (ntohs(peeraddr_in->sin_port) == 139) {
240 struct nmb_name calling;
241 struct nmb_name called;
243 make_nmb_name(&calling, global_myname(), 0x0);
244 make_nmb_name(&called, "*SMBSERVER", 0x20);
246 if (!cli_session_request(*cli, &calling, &called)) {
247 DEBUG(8, ("cli_session_request failed for %s\n",
253 cli_setup_signing_state(*cli, Undefined);
255 if (!cli_negprot(*cli)) {
256 DEBUG(1, ("cli_negprot failed\n"));
262 if ((*cli)->protocol >= PROTOCOL_NT1 && (*cli)->capabilities & CAP_EXTENDED_SECURITY) {
263 ADS_STATUS ads_status;
265 if (lp_security() == SEC_ADS) {
267 /* Try a krb5 session */
269 (*cli)->use_kerberos = True;
270 DEBUG(5, ("connecting to %s from %s with kerberos principal "
271 "[%s]\n", controller, global_myname(),
272 machine_krb5_principal));
274 ads_status = cli_session_setup_spnego(*cli,
275 machine_krb5_principal,
279 if (!ADS_ERR_OK(ads_status)) {
280 DEBUG(4,("failed kerberos session setup with %s\n",
281 ads_errstr(ads_status)));
284 result = ads_ntstatus(ads_status);
285 if (NT_STATUS_IS_OK(result)) {
286 /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
287 cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
288 goto session_setup_done;
292 /* Fall back to non-kerberos session setup using NTLMSSP SPNEGO with the machine account. */
293 (*cli)->use_kerberos = False;
295 DEBUG(5, ("connecting to %s from %s with username "
296 "[%s]\\[%s]\n", controller, global_myname(),
297 machine_account, machine_password));
299 ads_status = cli_session_setup_spnego(*cli,
303 if (!ADS_ERR_OK(ads_status)) {
304 DEBUG(4, ("authenticated session setup failed with %s\n",
305 ads_errstr(ads_status)));
308 result = ads_ntstatus(ads_status);
309 if (NT_STATUS_IS_OK(result)) {
310 /* Ensure creds are stored for NTLMSSP authenticated pipe access. */
311 cli_init_creds(*cli, machine_account, lp_workgroup(), machine_password);
312 goto session_setup_done;
316 /* Fall back to non-kerberos session setup */
318 (*cli)->use_kerberos = False;
320 if ((((*cli)->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) != 0) &&
321 (strlen(ipc_username) > 0)) {
323 /* Only try authenticated if we have a username */
325 DEBUG(5, ("connecting to %s from %s with username "
326 "[%s]\\[%s]\n", controller, global_myname(),
327 ipc_domain, ipc_username));
329 if (cli_session_setup(*cli, ipc_username,
330 ipc_password, strlen(ipc_password)+1,
331 ipc_password, strlen(ipc_password)+1,
333 /* Successful logon with given username. */
334 cli_init_creds(*cli, ipc_username, ipc_domain, ipc_password);
335 goto session_setup_done;
337 DEBUG(4, ("authenticated session setup with user %s\\%s failed.\n",
338 ipc_domain, ipc_username ));
342 /* Fall back to anonymous connection, this might fail later */
344 if (cli_session_setup(*cli, "", NULL, 0, NULL, 0, "")) {
345 DEBUG(5, ("Connected anonymously\n"));
346 cli_init_creds(*cli, "", "", "");
347 goto session_setup_done;
350 result = cli_nt_error(*cli);
352 if (NT_STATUS_IS_OK(result))
353 result = NT_STATUS_UNSUCCESSFUL;
355 /* We can't session setup */
361 /* cache the server name for later connections */
363 saf_store( (*cli)->domain, (*cli)->desthost );
365 if (!cli_send_tconX(*cli, "IPC$", "IPC", "", 0)) {
367 result = cli_nt_error(*cli);
369 DEBUG(1,("failed tcon_X with %s\n", nt_errstr(result)));
371 if (NT_STATUS_IS_OK(result))
372 result = NT_STATUS_UNSUCCESSFUL;
378 secrets_named_mutex_release(controller);
382 /* set the domain if empty; needed for schannel connections */
383 if ( !*(*cli)->domain ) {
384 fstrcpy( (*cli)->domain, domain->name );
387 result = NT_STATUS_OK;
388 add_failed_connection = False;
392 secrets_named_mutex_release(controller);
395 SAFE_FREE(machine_account);
396 SAFE_FREE(machine_password);
397 SAFE_FREE(machine_krb5_principal);
398 SAFE_FREE(ipc_username);
399 SAFE_FREE(ipc_domain);
400 SAFE_FREE(ipc_password);
402 if (add_failed_connection) {
403 add_failed_connection_entry(domain->name, controller, result);
414 static BOOL add_one_dc_unique(TALLOC_CTX *mem_ctx, const char *domain_name,
415 const char *dcname, struct in_addr ip,
416 struct dc_name_ip **dcs, int *num)
418 if (!NT_STATUS_IS_OK(check_negative_conn_cache(domain_name, dcname))) {
419 DEBUG(10, ("DC %s was in the negative conn cache\n", dcname));
423 *dcs = TALLOC_REALLOC_ARRAY(mem_ctx, *dcs, struct dc_name_ip, (*num)+1);
428 fstrcpy((*dcs)[*num].name, dcname);
429 (*dcs)[*num].ip = ip;
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)
438 *addrs = TALLOC_REALLOC_ARRAY(mem_ctx, *addrs, struct sockaddr_in, (*num)+1);
443 (*addrs)[*num].sin_family = PF_INET;
444 putip((char *)&((*addrs)[*num].sin_addr), (char *)&ip);
445 (*addrs)[*num].sin_port = htons(port);
451 static void mailslot_name(struct in_addr dc_ip, fstring name)
453 fstr_sprintf(name, "\\MAILSLOT\\NET\\GETDC%X", dc_ip.s_addr);
456 static BOOL send_getdc_request(struct in_addr dc_ip,
457 const char *domain_name,
462 fstring my_acct_name;
465 mailslot_name(dc_ip, my_mailslot);
467 memset(outbuf, '\0', sizeof(outbuf));
471 SCVAL(p, 0, SAMLOGON);
474 SCVAL(p, 0, 0); /* Count pointer ... */
477 SIVAL(p, 0, 0); /* The sender's token ... */
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);
484 memcpy(p, my_mailslot, strlen(my_mailslot)+1);
485 p += strlen(my_mailslot)+1;
490 SIVAL(p, 0, sid_size(sid));
493 p = ALIGN4(p, outbuf);
495 sid_linearize(p, sid_size(sid), sid);
503 return cli_send_mailslot(False, "\\MAILSLOT\\NET\\NTLOGON", 0,
504 outbuf, PTR_DIFF(p, outbuf),
505 global_myname(), 0, domain_name, 0x1c,
509 static BOOL receive_getdc_response(struct in_addr dc_ip,
510 const char *domain_name,
513 struct packet_struct *packet;
516 fstring dcname, user, domain;
519 mailslot_name(dc_ip, my_mailslot);
521 packet = receive_unexpected(DGRAM_PACKET, 0, my_mailslot);
523 if (packet == NULL) {
524 DEBUG(5, ("Did not receive packet for %s\n", my_mailslot));
528 DEBUG(5, ("Received packet for %s\n", my_mailslot));
530 buf = packet->packet.dgram.data;
531 len = packet->packet.dgram.datasize;
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"));
540 /* This should be (buf-4)+SVAL(buf-4, smb_vwv12)... */
541 p = buf+SVAL(buf, smb_vwv10);
543 if (CVAL(p,0) != SAMLOGON_R) {
544 DEBUG(8, ("GetDC got invalid response type %d\n", CVAL(p, 0)));
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));
559 if (!strequal(domain, domain_name)) {
560 DEBUG(3, ("GetDC: Expected domain %s, got %s\n",
561 domain_name, domain));
566 if (*p == '\\') p += 1;
567 if (*p == '\\') p += 1;
571 DEBUG(10, ("GetDC gave name %s for domain %s\n",
577 /*******************************************************************
578 convert an ip to a name
579 *******************************************************************/
581 static void dcip_to_name( const char *domainname, const char *realm,
582 const DOM_SID *sid, struct in_addr ip, fstring name )
585 /* try GETDC requests first */
587 if (send_getdc_request(ip, domainname, sid)) {
590 for (i=0; i<5; i++) {
591 if (receive_getdc_response(ip, domainname, name))
597 /* try node status request */
599 if ( name_status_find(domainname, 0x1c, 0x20, ip, name) )
602 /* backup in case the netbios stuff fails */
604 fstrcpy( name, inet_ntoa(ip) );
607 /* for active directory servers, try to get the ldap server name.
608 None of these failure should be considered critical for now */
610 if ( lp_security() == SEC_ADS )
615 ads = ads_init( realm, domainname, NULL );
616 ads->auth.flags |= ADS_AUTH_NO_BIND;
618 if ( !ads_try_connect( ads, inet_ntoa(ip), LDAP_PORT ) ) {
623 status = ads_server_info(ads);
624 if ( !ADS_ERR_OK(status) ) {
629 fstrcpy(name, ads->config.ldap_server_name);
638 /*******************************************************************
639 Retreive a list of IP address for domain controllers. Fill in
640 the dcs[] with results.
641 *******************************************************************/
643 static BOOL get_dcs(TALLOC_CTX *mem_ctx, const struct winbindd_domain *domain,
644 struct dc_name_ip **dcs, int *num_dcs)
648 struct ip_service *ip_list = NULL;
654 is_our_domain = strequal(domain->name, lp_workgroup());
657 && get_dc_name_via_netlogon(domain, dcname, &ip)
658 && add_one_dc_unique(mem_ctx, domain->name, dcname, ip, dcs, num_dcs) )
660 DEBUG(10, ("Retrieved DC %s at %s via netlogon\n",
661 dcname, inet_ntoa(ip)));
665 /* try standard netbios queries first */
667 get_sorted_dc_list(domain->name, &ip_list, &iplist_size, False);
669 /* check for security = ads and use DNS if we can */
671 if ( iplist_size==0 && lp_security() == SEC_ADS )
672 get_sorted_dc_list(domain->alt_name, &ip_list, &iplist_size, True);
674 /* FIXME!! this is where we should re-insert the GETDC requests --jerry */
676 /* now add to the dc array. We'll wait until the last minute
677 to look up the name of the DC. But we fill in the char* for
678 the ip now in to make the failed connection cache work */
680 for ( i=0; i<iplist_size; i++ ) {
681 add_one_dc_unique(mem_ctx, domain->name, inet_ntoa(ip_list[i].ip),
682 ip_list[i].ip, dcs, num_dcs);
685 SAFE_FREE( ip_list );
690 static BOOL find_new_dc(TALLOC_CTX *mem_ctx,
691 const struct winbindd_domain *domain,
692 fstring dcname, struct sockaddr_in *addr, int *fd)
694 struct dc_name_ip *dcs = NULL;
697 const char **dcnames = NULL;
700 struct sockaddr_in *addrs = NULL;
705 if (!get_dcs(mem_ctx, domain, &dcs, &num_dcs) || (num_dcs == 0))
708 for (i=0; i<num_dcs; i++) {
710 add_string_to_array(mem_ctx, dcs[i].name,
711 &dcnames, &num_dcnames);
712 add_sockaddr_to_array(mem_ctx, dcs[i].ip, 445,
715 add_string_to_array(mem_ctx, dcs[i].name,
716 &dcnames, &num_dcnames);
717 add_sockaddr_to_array(mem_ctx, dcs[i].ip, 139,
721 if ((num_dcnames == 0) || (num_dcnames != num_addrs))
724 if ( !open_any_socket_out(addrs, num_addrs, 10000, &fd_index, fd) )
726 for (i=0; i<num_dcs; i++) {
727 add_failed_connection_entry(domain->name,
728 dcs[i].name, NT_STATUS_UNSUCCESSFUL);
733 *addr = addrs[fd_index];
735 /* if we have no name on the server or just an IP address for
736 the name, now try to get the name */
738 if ( is_ipaddress(dcnames[fd_index]) || *dcnames[fd_index] == '\0' )
739 dcip_to_name( domain->name, domain->alt_name, &domain->sid, addr->sin_addr, dcname );
741 fstrcpy(dcname, dcnames[fd_index]);
746 static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
747 struct winbindd_cm_conn *new_conn)
751 char *saf_servername = saf_fetch( domain->name );
754 if ((mem_ctx = talloc_init("cm_open_connection")) == NULL)
755 return NT_STATUS_NO_MEMORY;
757 /* we have to check the server affinity cache here since
758 later we selecte a DC based on response time and not preference */
760 if ( saf_servername )
762 /* convert an ip address to a name */
763 if ( is_ipaddress( saf_servername ) )
768 ip = *interpret_addr2( saf_servername );
769 dcip_to_name( domain->name, domain->alt_name, &domain->sid, ip, saf_name );
770 fstrcpy( domain->dcname, saf_name );
774 fstrcpy( domain->dcname, saf_servername );
777 SAFE_FREE( saf_servername );
780 for (retries = 0; retries < 3; retries++) {
785 result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
787 if ((strlen(domain->dcname) > 0)
788 && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, domain->dcname))
789 && (resolve_name(domain->dcname, &domain->dcaddr.sin_addr, 0x20)))
791 struct sockaddr_in *addrs = NULL;
795 add_sockaddr_to_array(mem_ctx, domain->dcaddr.sin_addr, 445, &addrs, &num_addrs);
796 add_sockaddr_to_array(mem_ctx, domain->dcaddr.sin_addr, 139, &addrs, &num_addrs);
798 if (!open_any_socket_out(addrs, num_addrs, 10000, &dummy, &fd)) {
799 domain->online = False;
805 && !find_new_dc(mem_ctx, domain, domain->dcname, &domain->dcaddr, &fd))
807 /* This is the one place where we will
808 set the global winbindd offline state
809 to true, if a "WINBINDD_OFFLINE" entry
810 is found in the winbindd cache. */
811 set_global_winbindd_state_offline();
812 domain->online = False;
816 new_conn->cli = NULL;
818 result = cm_prepare_connection(domain, fd, domain->dcname,
819 &new_conn->cli, &retry);
825 if (NT_STATUS_IS_OK(result)) {
826 if (domain->online == False) {
827 /* We're changing state from offline to online. */
828 set_global_winbindd_state_online();
830 domain->online = True;
833 talloc_destroy(mem_ctx);
837 /* Close down all open pipes on a connection. */
839 void invalidate_cm_connection(struct winbindd_cm_conn *conn)
841 if (conn->samr_pipe != NULL) {
842 cli_rpc_pipe_close(conn->samr_pipe);
843 conn->samr_pipe = NULL;
846 if (conn->lsa_pipe != NULL) {
847 cli_rpc_pipe_close(conn->lsa_pipe);
848 conn->lsa_pipe = NULL;
851 if (conn->netlogon_pipe != NULL) {
852 cli_rpc_pipe_close(conn->netlogon_pipe);
853 conn->netlogon_pipe = NULL;
857 cli_shutdown(conn->cli);
863 void close_conns_after_fork(void)
865 struct winbindd_domain *domain;
867 for (domain = domain_list(); domain; domain = domain->next) {
868 if (domain->conn.cli == NULL)
871 if (domain->conn.cli->fd == -1)
874 close(domain->conn.cli->fd);
875 domain->conn.cli->fd = -1;
879 static BOOL connection_ok(struct winbindd_domain *domain)
881 if (domain->conn.cli == NULL) {
882 DEBUG(8, ("Connection to %s for domain %s has NULL "
883 "cli!\n", domain->dcname, domain->name));
887 if (!domain->conn.cli->initialised) {
888 DEBUG(3, ("Connection to %s for domain %s was never "
889 "initialised!\n", domain->dcname, domain->name));
893 if (domain->conn.cli->fd == -1) {
894 DEBUG(3, ("Connection to %s for domain %s has died or was "
895 "never started (fd == -1)\n",
896 domain->dcname, domain->name));
903 /* Initialize a new connection up to the RPC BIND. */
905 static NTSTATUS init_dc_connection(struct winbindd_domain *domain)
907 if (connection_ok(domain))
910 invalidate_cm_connection(&domain->conn);
912 return cm_open_connection(domain, &domain->conn);
915 /******************************************************************************
916 We can 'sense' certain things about the DC by it's replies to certain
919 This tells us if this particular remote server is Active Directory, and if it
921 ******************************************************************************/
923 void set_dc_type_and_flags( struct winbindd_domain *domain )
927 TALLOC_CTX *mem_ctx = NULL;
928 struct rpc_pipe_client *cli;
931 char *domain_name = NULL;
932 char *dns_name = NULL;
933 DOM_SID *dom_sid = NULL;
937 domain->native_mode = False;
938 domain->active_directory = False;
940 if (domain->internal) {
941 domain->initialized = True;
945 result = init_dc_connection(domain);
946 if (!NT_STATUS_IS_OK(result)) {
947 DEBUG(5, ("set_dc_type_and_flags: Could not open a connection "
948 "to %s: (%s)\n", domain->name, nt_errstr(result)));
949 domain->initialized = True;
953 cli = cli_rpc_pipe_open_noauth(domain->conn.cli, PI_LSARPC_DS,
957 DEBUG(5, ("set_dc_type_and_flags: Could not bind to "
958 "PI_LSARPC_DS on domain %s: (%s)\n",
959 domain->name, nt_errstr(result)));
960 domain->initialized = True;
964 result = rpccli_ds_getprimarydominfo(cli, cli->cli->mem_ctx,
965 DsRolePrimaryDomainInfoBasic,
967 cli_rpc_pipe_close(cli);
969 if (!NT_STATUS_IS_OK(result)) {
970 domain->initialized = True;
974 if ((ctr.basic->flags & DSROLE_PRIMARY_DS_RUNNING) &&
975 !(ctr.basic->flags & DSROLE_PRIMARY_DS_MIXED_MODE) )
976 domain->native_mode = True;
978 cli = cli_rpc_pipe_open_noauth(domain->conn.cli, PI_LSARPC, &result);
981 domain->initialized = True;
985 mem_ctx = talloc_init("set_dc_type_and_flags on domain %s\n",
988 DEBUG(1, ("set_dc_type_and_flags: talloc_init() failed\n"));
989 cli_rpc_pipe_close(cli);
993 result = rpccli_lsa_open_policy2(cli, mem_ctx, True,
994 SEC_RIGHTS_MAXIMUM_ALLOWED, &pol);
996 if (NT_STATUS_IS_OK(result)) {
997 /* This particular query is exactly what Win2k clients use
998 to determine that the DC is active directory */
999 result = rpccli_lsa_query_info_policy2(cli, mem_ctx, &pol,
1005 if (NT_STATUS_IS_OK(result)) {
1007 fstrcpy(domain->name, domain_name);
1010 fstrcpy(domain->alt_name, dns_name);
1013 sid_copy(&domain->sid, dom_sid);
1015 domain->active_directory = True;
1018 result = rpccli_lsa_open_policy(cli, mem_ctx, True,
1019 SEC_RIGHTS_MAXIMUM_ALLOWED,
1022 if (!NT_STATUS_IS_OK(result))
1025 result = rpccli_lsa_query_info_policy(cli, mem_ctx,
1026 &pol, 5, &domain_name,
1029 if (NT_STATUS_IS_OK(result)) {
1031 fstrcpy(domain->name, domain_name);
1034 sid_copy(&domain->sid, dom_sid);
1039 cli_rpc_pipe_close(cli);
1041 talloc_destroy(mem_ctx);
1043 domain->initialized = True;
1048 static BOOL cm_get_schannel_dcinfo(struct winbindd_domain *domain,
1049 struct dcinfo **ppdc)
1052 struct rpc_pipe_client *netlogon_pipe;
1054 if (lp_client_schannel() == False) {
1058 result = cm_connect_netlogon(domain, &netlogon_pipe);
1059 if (!NT_STATUS_IS_OK(result)) {
1063 /* Return a pointer to the struct dcinfo from the
1066 *ppdc = domain->conn.netlogon_pipe->dc;
1070 NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
1071 struct rpc_pipe_client **cli, POLICY_HND *sam_handle)
1073 struct winbindd_cm_conn *conn;
1076 struct dcinfo *p_dcinfo;
1078 result = init_dc_connection(domain);
1079 if (!NT_STATUS_IS_OK(result)) {
1083 conn = &domain->conn;
1085 if (conn->samr_pipe != NULL) {
1090 * No SAMR pipe yet. Attempt to get an NTLMSSP SPNEGO authenticated
1091 * sign and sealed pipe using the machine account password by
1092 * preference. If we can't - try schannel, if that fails, try
1096 pwd_get_cleartext(&conn->cli->pwd, conn_pwd);
1097 if ((conn->cli->user_name[0] == '\0') ||
1098 (conn->cli->domain[0] == '\0') ||
1099 (conn_pwd[0] == '\0')) {
1100 DEBUG(10, ("cm_connect_sam: No no user available for "
1101 "domain %s, trying schannel\n", conn->cli->domain));
1105 /* We have an authenticated connection. Use a NTLMSSP SPNEGO
1106 authenticated SAMR pipe with sign & seal. */
1108 cli_rpc_pipe_open_spnego_ntlmssp(conn->cli, PI_SAMR,
1109 PIPE_AUTH_LEVEL_PRIVACY,
1111 conn->cli->user_name,
1114 if (conn->samr_pipe == NULL) {
1115 DEBUG(10,("cm_connect_sam: failed to connect to SAMR "
1116 "pipe for domain %s using NTLMSSP "
1117 "authenticated pipe: user %s\\%s. Error was "
1118 "%s\n", domain->name, conn->cli->domain,
1119 conn->cli->user_name, nt_errstr(result)));
1123 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for "
1124 "domain %s using NTLMSSP authenticated "
1125 "pipe: user %s\\%s\n", domain->name,
1126 conn->cli->domain, conn->cli->user_name ));
1128 result = rpccli_samr_connect(conn->samr_pipe, mem_ctx,
1129 SEC_RIGHTS_MAXIMUM_ALLOWED,
1130 &conn->sam_connect_handle);
1131 if (NT_STATUS_IS_OK(result)) {
1134 DEBUG(10,("cm_connect_sam: ntlmssp-sealed rpccli_samr_connect "
1135 "failed for domain %s, error was %s. Trying schannel\n",
1136 domain->name, nt_errstr(result) ));
1137 cli_rpc_pipe_close(conn->samr_pipe);
1141 /* Fall back to schannel if it's a W2K pre-SP1 box. */
1143 if (!cm_get_schannel_dcinfo(domain, &p_dcinfo)) {
1144 DEBUG(10, ("cm_connect_sam: Could not get schannel auth info "
1145 "for domain %s, trying anon\n", conn->cli->domain));
1148 conn->samr_pipe = cli_rpc_pipe_open_schannel_with_key
1149 (conn->cli, PI_SAMR, PIPE_AUTH_LEVEL_PRIVACY,
1150 domain->name, p_dcinfo, &result);
1152 if (conn->samr_pipe == NULL) {
1153 DEBUG(10,("cm_connect_sam: failed to connect to SAMR pipe for "
1154 "domain %s using schannel. Error was %s\n",
1155 domain->name, nt_errstr(result) ));
1158 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for domain %s using "
1159 "schannel.\n", domain->name ));
1161 result = rpccli_samr_connect(conn->samr_pipe, mem_ctx,
1162 SEC_RIGHTS_MAXIMUM_ALLOWED,
1163 &conn->sam_connect_handle);
1164 if (NT_STATUS_IS_OK(result)) {
1167 DEBUG(10,("cm_connect_sam: schannel-sealed rpccli_samr_connect failed "
1168 "for domain %s, error was %s. Trying anonymous\n",
1169 domain->name, nt_errstr(result) ));
1170 cli_rpc_pipe_close(conn->samr_pipe);
1174 /* Finally fall back to anonymous. */
1175 conn->samr_pipe = cli_rpc_pipe_open_noauth(conn->cli, PI_SAMR,
1178 if (conn->samr_pipe == NULL) {
1179 result = NT_STATUS_PIPE_NOT_AVAILABLE;
1183 result = rpccli_samr_connect(conn->samr_pipe, mem_ctx,
1184 SEC_RIGHTS_MAXIMUM_ALLOWED,
1185 &conn->sam_connect_handle);
1186 if (!NT_STATUS_IS_OK(result)) {
1187 DEBUG(10,("cm_connect_sam: rpccli_samr_connect failed "
1188 "for domain %s Error was %s\n",
1189 domain->name, nt_errstr(result) ));
1194 result = rpccli_samr_open_domain(conn->samr_pipe,
1196 &conn->sam_connect_handle,
1197 SEC_RIGHTS_MAXIMUM_ALLOWED,
1199 &conn->sam_domain_handle);
1203 if (!NT_STATUS_IS_OK(result)) {
1204 invalidate_cm_connection(conn);
1208 *cli = conn->samr_pipe;
1209 *sam_handle = conn->sam_domain_handle;
1213 NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
1214 struct rpc_pipe_client **cli, POLICY_HND *lsa_policy)
1216 struct winbindd_cm_conn *conn;
1219 struct dcinfo *p_dcinfo;
1221 result = init_dc_connection(domain);
1222 if (!NT_STATUS_IS_OK(result))
1225 conn = &domain->conn;
1227 if (conn->lsa_pipe != NULL) {
1231 pwd_get_cleartext(&conn->cli->pwd, conn_pwd);
1232 if ((conn->cli->user_name[0] == '\0') ||
1233 (conn->cli->domain[0] == '\0') ||
1234 (conn_pwd[0] == '\0')) {
1235 DEBUG(10, ("cm_connect_lsa: No no user available for "
1236 "domain %s, trying schannel\n", conn->cli->domain));
1240 /* We have an authenticated connection. Use a NTLMSSP SPNEGO
1241 * authenticated LSA pipe with sign & seal. */
1242 conn->lsa_pipe = cli_rpc_pipe_open_spnego_ntlmssp
1243 (conn->cli, PI_LSARPC, PIPE_AUTH_LEVEL_PRIVACY,
1244 conn->cli->domain, conn->cli->user_name, conn_pwd, &result);
1246 if (conn->lsa_pipe == NULL) {
1247 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
1248 "domain %s using NTLMSSP authenticated pipe: user "
1249 "%s\\%s. Error was %s. Trying schannel.\n",
1250 domain->name, conn->cli->domain,
1251 conn->cli->user_name, nt_errstr(result)));
1255 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
1256 "NTLMSSP authenticated pipe: user %s\\%s\n",
1257 domain->name, conn->cli->domain, conn->cli->user_name ));
1259 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
1260 SEC_RIGHTS_MAXIMUM_ALLOWED,
1262 if (NT_STATUS_IS_OK(result)) {
1266 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
1269 cli_rpc_pipe_close(conn->lsa_pipe);
1273 /* Fall back to schannel if it's a W2K pre-SP1 box. */
1275 if (!cm_get_schannel_dcinfo(domain, &p_dcinfo)) {
1276 DEBUG(10, ("cm_connect_lsa: Could not get schannel auth info "
1277 "for domain %s, trying anon\n", conn->cli->domain));
1280 conn->lsa_pipe = cli_rpc_pipe_open_schannel_with_key
1281 (conn->cli, PI_LSARPC, PIPE_AUTH_LEVEL_PRIVACY,
1282 domain->name, p_dcinfo, &result);
1284 if (conn->lsa_pipe == NULL) {
1285 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
1286 "domain %s using schannel. Error was %s\n",
1287 domain->name, nt_errstr(result) ));
1290 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
1291 "schannel.\n", domain->name ));
1293 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
1294 SEC_RIGHTS_MAXIMUM_ALLOWED,
1296 if (NT_STATUS_IS_OK(result)) {
1300 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
1303 cli_rpc_pipe_close(conn->lsa_pipe);
1307 conn->lsa_pipe = cli_rpc_pipe_open_noauth(conn->cli, PI_LSARPC,
1309 if (conn->lsa_pipe == NULL) {
1310 result = NT_STATUS_PIPE_NOT_AVAILABLE;
1314 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
1315 SEC_RIGHTS_MAXIMUM_ALLOWED,
1318 if (!NT_STATUS_IS_OK(result)) {
1319 invalidate_cm_connection(conn);
1320 return NT_STATUS_UNSUCCESSFUL;
1323 *cli = conn->lsa_pipe;
1324 *lsa_policy = conn->lsa_policy;
1328 /****************************************************************************
1329 Open the netlogon pipe to this DC. Use schannel if specified in client conf.
1330 session key stored in conn->netlogon_pipe->dc->sess_key.
1331 ****************************************************************************/
1333 NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
1334 struct rpc_pipe_client **cli)
1336 struct winbindd_cm_conn *conn;
1339 uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
1341 uint32 sec_chan_type;
1342 const char *account_name;
1343 struct rpc_pipe_client *netlogon_pipe = NULL;
1347 result = init_dc_connection(domain);
1348 if (!NT_STATUS_IS_OK(result)) {
1352 conn = &domain->conn;
1354 if (conn->netlogon_pipe != NULL) {
1355 *cli = conn->netlogon_pipe;
1356 return NT_STATUS_OK;
1359 if (!get_trust_pw(domain->name, mach_pwd, &sec_chan_type)) {
1360 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1363 netlogon_pipe = cli_rpc_pipe_open_noauth(conn->cli, PI_NETLOGON,
1365 if (netlogon_pipe == NULL) {
1369 if (lp_client_schannel() != False) {
1370 neg_flags |= NETLOGON_NEG_SCHANNEL;
1373 /* if we are a DC and this is a trusted domain, then we need to use our
1374 domain name in the net_req_auth2() request */
1377 && !strequal(domain->name, lp_workgroup())
1378 && lp_allow_trusted_domains() )
1380 account_name = lp_workgroup();
1382 account_name = domain->primary ?
1383 global_myname() : domain->name;
1386 if (account_name == NULL) {
1387 cli_rpc_pipe_close(netlogon_pipe);
1388 return NT_STATUS_NO_MEMORY;
1391 result = rpccli_netlogon_setup_creds(
1393 domain->dcname, /* server name. */
1394 domain->name, /* domain name */
1395 global_myname(), /* client name */
1396 account_name, /* machine account */
1397 mach_pwd, /* machine password */
1398 sec_chan_type, /* from get_trust_pw */
1401 if (!NT_STATUS_IS_OK(result)) {
1402 cli_rpc_pipe_close(netlogon_pipe);
1406 if ((lp_client_schannel() == True) &&
1407 ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
1408 DEBUG(3, ("Server did not offer schannel\n"));
1409 cli_rpc_pipe_close(netlogon_pipe);
1410 return NT_STATUS_ACCESS_DENIED;
1413 if ((lp_client_schannel() == False) ||
1414 ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
1415 /* We're done - just keep the existing connection to NETLOGON
1417 conn->netlogon_pipe = netlogon_pipe;
1418 *cli = conn->netlogon_pipe;
1419 return NT_STATUS_OK;
1422 /* Using the credentials from the first pipe, open a signed and sealed
1423 second netlogon pipe. The session key is stored in the schannel
1424 part of the new pipe auth struct.
1427 conn->netlogon_pipe =
1428 cli_rpc_pipe_open_schannel_with_key(conn->cli,
1430 PIPE_AUTH_LEVEL_PRIVACY,
1435 /* We can now close the initial netlogon pipe. */
1436 cli_rpc_pipe_close(netlogon_pipe);
1438 if (conn->netlogon_pipe == NULL) {
1439 DEBUG(3, ("Could not open schannel'ed NETLOGON pipe. Error "
1440 "was %s\n", nt_errstr(result)));
1444 *cli = conn->netlogon_pipe;
1445 return NT_STATUS_OK;