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 lp_workgroup(), machine_account));
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( domain->name, (*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 )
584 struct ip_service ip_list;
589 /* try GETDC requests first */
591 if (send_getdc_request(ip, domainname, sid)) {
594 for (i=0; i<5; i++) {
595 if (receive_getdc_response(ip, domainname, name)) {
596 namecache_store(name, 0x20, 1, &ip_list);
603 /* try node status request */
605 if ( name_status_find(domainname, 0x1c, 0x20, ip, name) ) {
606 namecache_store(name, 0x20, 1, &ip_list);
610 /* backup in case the netbios stuff fails */
612 fstrcpy( name, inet_ntoa(ip) );
615 /* for active directory servers, try to get the ldap server name.
616 None of these failure should be considered critical for now */
618 if ( lp_security() == SEC_ADS )
622 ads = ads_init( realm, domainname, NULL );
623 ads->auth.flags |= ADS_AUTH_NO_BIND;
625 if ( !ads_try_connect( ads, inet_ntoa(ip) ) ) {
630 fstrcpy(name, ads->config.ldap_server_name);
631 namecache_store(name, 0x20, 1, &ip_list);
640 /*******************************************************************
641 Retreive a list of IP address for domain controllers. Fill in
642 the dcs[] with results.
643 *******************************************************************/
645 static BOOL get_dcs(TALLOC_CTX *mem_ctx, const struct winbindd_domain *domain,
646 struct dc_name_ip **dcs, int *num_dcs)
650 struct ip_service *ip_list = NULL;
656 is_our_domain = strequal(domain->name, lp_workgroup());
659 && get_dc_name_via_netlogon(domain, dcname, &ip)
660 && add_one_dc_unique(mem_ctx, domain->name, dcname, ip, dcs, num_dcs) )
662 DEBUG(10, ("Retrieved DC %s at %s via netlogon\n",
663 dcname, inet_ntoa(ip)));
667 /* try standard netbios queries first */
669 get_sorted_dc_list(domain->name, &ip_list, &iplist_size, False);
671 /* check for security = ads and use DNS if we can */
673 if ( iplist_size==0 && lp_security() == SEC_ADS )
674 get_sorted_dc_list(domain->alt_name, &ip_list, &iplist_size, True);
676 /* FIXME!! this is where we should re-insert the GETDC requests --jerry */
678 /* now add to the dc array. We'll wait until the last minute
679 to look up the name of the DC. But we fill in the char* for
680 the ip now in to make the failed connection cache work */
682 for ( i=0; i<iplist_size; i++ ) {
683 add_one_dc_unique(mem_ctx, domain->name, inet_ntoa(ip_list[i].ip),
684 ip_list[i].ip, dcs, num_dcs);
687 SAFE_FREE( ip_list );
692 static BOOL find_new_dc(TALLOC_CTX *mem_ctx,
693 const struct winbindd_domain *domain,
694 fstring dcname, struct sockaddr_in *addr, int *fd)
696 struct dc_name_ip *dcs = NULL;
699 const char **dcnames = NULL;
702 struct sockaddr_in *addrs = NULL;
707 if (!get_dcs(mem_ctx, domain, &dcs, &num_dcs) || (num_dcs == 0))
710 for (i=0; i<num_dcs; i++) {
712 add_string_to_array(mem_ctx, dcs[i].name,
713 &dcnames, &num_dcnames);
714 add_sockaddr_to_array(mem_ctx, dcs[i].ip, 445,
717 add_string_to_array(mem_ctx, dcs[i].name,
718 &dcnames, &num_dcnames);
719 add_sockaddr_to_array(mem_ctx, dcs[i].ip, 139,
723 if ((num_dcnames == 0) || (num_dcnames != num_addrs))
726 if ( !open_any_socket_out(addrs, num_addrs, 10000, &fd_index, fd) )
728 for (i=0; i<num_dcs; i++) {
729 add_failed_connection_entry(domain->name,
730 dcs[i].name, NT_STATUS_UNSUCCESSFUL);
735 *addr = addrs[fd_index];
737 /* if we have no name on the server or just an IP address for
738 the name, now try to get the name */
740 if ( is_ipaddress(dcnames[fd_index]) || *dcnames[fd_index] == '\0' )
741 dcip_to_name( domain->name, domain->alt_name, &domain->sid, addr->sin_addr, dcname );
743 fstrcpy(dcname, dcnames[fd_index]);
748 static NTSTATUS cm_open_connection(struct winbindd_domain *domain,
749 struct winbindd_cm_conn *new_conn)
753 char *saf_servername = saf_fetch( domain->name );
756 if ((mem_ctx = talloc_init("cm_open_connection")) == NULL)
757 return NT_STATUS_NO_MEMORY;
759 /* we have to check the server affinity cache here since
760 later we selecte a DC based on response time and not preference */
762 if ( saf_servername )
764 /* convert an ip address to a name */
765 if ( is_ipaddress( saf_servername ) )
770 ip = *interpret_addr2( saf_servername );
771 dcip_to_name( domain->name, domain->alt_name, &domain->sid, ip, saf_name );
772 fstrcpy( domain->dcname, saf_name );
776 fstrcpy( domain->dcname, saf_servername );
779 SAFE_FREE( saf_servername );
782 for (retries = 0; retries < 3; retries++) {
787 result = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND;
789 if ((strlen(domain->dcname) > 0)
790 && NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, domain->dcname))
791 && (resolve_name(domain->dcname, &domain->dcaddr.sin_addr, 0x20)))
793 struct sockaddr_in *addrs = NULL;
797 add_sockaddr_to_array(mem_ctx, domain->dcaddr.sin_addr, 445, &addrs, &num_addrs);
798 add_sockaddr_to_array(mem_ctx, domain->dcaddr.sin_addr, 139, &addrs, &num_addrs);
800 if (!open_any_socket_out(addrs, num_addrs, 10000, &dummy, &fd)) {
801 domain->online = False;
807 && !find_new_dc(mem_ctx, domain, domain->dcname, &domain->dcaddr, &fd))
809 /* This is the one place where we will
810 set the global winbindd offline state
811 to true, if a "WINBINDD_OFFLINE" entry
812 is found in the winbindd cache. */
813 set_global_winbindd_state_offline();
814 domain->online = False;
818 new_conn->cli = NULL;
820 result = cm_prepare_connection(domain, fd, domain->dcname,
821 &new_conn->cli, &retry);
827 if (NT_STATUS_IS_OK(result)) {
828 if (domain->online == False) {
829 /* We're changing state from offline to online. */
830 set_global_winbindd_state_online();
832 domain->online = True;
835 talloc_destroy(mem_ctx);
839 /* Close down all open pipes on a connection. */
841 void invalidate_cm_connection(struct winbindd_cm_conn *conn)
843 if (conn->samr_pipe != NULL) {
844 cli_rpc_pipe_close(conn->samr_pipe);
845 conn->samr_pipe = NULL;
848 if (conn->lsa_pipe != NULL) {
849 cli_rpc_pipe_close(conn->lsa_pipe);
850 conn->lsa_pipe = NULL;
853 if (conn->netlogon_pipe != NULL) {
854 cli_rpc_pipe_close(conn->netlogon_pipe);
855 conn->netlogon_pipe = NULL;
859 cli_shutdown(conn->cli);
865 void close_conns_after_fork(void)
867 struct winbindd_domain *domain;
869 for (domain = domain_list(); domain; domain = domain->next) {
870 if (domain->conn.cli == NULL)
873 if (domain->conn.cli->fd == -1)
876 close(domain->conn.cli->fd);
877 domain->conn.cli->fd = -1;
881 static BOOL connection_ok(struct winbindd_domain *domain)
883 if (domain->conn.cli == NULL) {
884 DEBUG(8, ("Connection to %s for domain %s has NULL "
885 "cli!\n", domain->dcname, domain->name));
889 if (!domain->conn.cli->initialised) {
890 DEBUG(3, ("Connection to %s for domain %s was never "
891 "initialised!\n", domain->dcname, domain->name));
895 if (domain->conn.cli->fd == -1) {
896 DEBUG(3, ("Connection to %s for domain %s has died or was "
897 "never started (fd == -1)\n",
898 domain->dcname, domain->name));
905 /* Initialize a new connection up to the RPC BIND. */
907 static NTSTATUS init_dc_connection(struct winbindd_domain *domain)
909 if (connection_ok(domain))
912 invalidate_cm_connection(&domain->conn);
914 return cm_open_connection(domain, &domain->conn);
917 /******************************************************************************
918 We can 'sense' certain things about the DC by it's replies to certain
921 This tells us if this particular remote server is Active Directory, and if it
923 ******************************************************************************/
925 void set_dc_type_and_flags( struct winbindd_domain *domain )
929 TALLOC_CTX *mem_ctx = NULL;
930 struct rpc_pipe_client *cli;
933 char *domain_name = NULL;
934 char *dns_name = NULL;
935 DOM_SID *dom_sid = NULL;
939 domain->native_mode = False;
940 domain->active_directory = False;
942 if (domain->internal) {
943 domain->initialized = True;
947 result = init_dc_connection(domain);
948 if (!NT_STATUS_IS_OK(result)) {
949 DEBUG(5, ("set_dc_type_and_flags: Could not open a connection "
950 "to %s: (%s)\n", domain->name, nt_errstr(result)));
951 domain->initialized = True;
955 cli = cli_rpc_pipe_open_noauth(domain->conn.cli, PI_LSARPC_DS,
959 DEBUG(5, ("set_dc_type_and_flags: Could not bind to "
960 "PI_LSARPC_DS on domain %s: (%s)\n",
961 domain->name, nt_errstr(result)));
962 domain->initialized = True;
966 result = rpccli_ds_getprimarydominfo(cli, cli->cli->mem_ctx,
967 DsRolePrimaryDomainInfoBasic,
969 cli_rpc_pipe_close(cli);
971 if (!NT_STATUS_IS_OK(result)) {
972 domain->initialized = True;
976 if ((ctr.basic->flags & DSROLE_PRIMARY_DS_RUNNING) &&
977 !(ctr.basic->flags & DSROLE_PRIMARY_DS_MIXED_MODE) )
978 domain->native_mode = True;
980 cli = cli_rpc_pipe_open_noauth(domain->conn.cli, PI_LSARPC, &result);
983 domain->initialized = True;
987 mem_ctx = talloc_init("set_dc_type_and_flags on domain %s\n",
990 DEBUG(1, ("set_dc_type_and_flags: talloc_init() failed\n"));
991 cli_rpc_pipe_close(cli);
995 result = rpccli_lsa_open_policy2(cli, mem_ctx, True,
996 SEC_RIGHTS_MAXIMUM_ALLOWED, &pol);
998 if (NT_STATUS_IS_OK(result)) {
999 /* This particular query is exactly what Win2k clients use
1000 to determine that the DC is active directory */
1001 result = rpccli_lsa_query_info_policy2(cli, mem_ctx, &pol,
1007 if (NT_STATUS_IS_OK(result)) {
1009 fstrcpy(domain->name, domain_name);
1012 fstrcpy(domain->alt_name, dns_name);
1015 sid_copy(&domain->sid, dom_sid);
1017 domain->active_directory = True;
1020 result = rpccli_lsa_open_policy(cli, mem_ctx, True,
1021 SEC_RIGHTS_MAXIMUM_ALLOWED,
1024 if (!NT_STATUS_IS_OK(result))
1027 result = rpccli_lsa_query_info_policy(cli, mem_ctx,
1028 &pol, 5, &domain_name,
1031 if (NT_STATUS_IS_OK(result)) {
1033 fstrcpy(domain->name, domain_name);
1036 sid_copy(&domain->sid, dom_sid);
1041 cli_rpc_pipe_close(cli);
1043 talloc_destroy(mem_ctx);
1045 domain->initialized = True;
1050 static BOOL cm_get_schannel_dcinfo(struct winbindd_domain *domain,
1051 struct dcinfo **ppdc)
1054 struct rpc_pipe_client *netlogon_pipe;
1056 if (lp_client_schannel() == False) {
1060 result = cm_connect_netlogon(domain, &netlogon_pipe);
1061 if (!NT_STATUS_IS_OK(result)) {
1065 /* Return a pointer to the struct dcinfo from the
1068 *ppdc = domain->conn.netlogon_pipe->dc;
1072 NTSTATUS cm_connect_sam(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
1073 struct rpc_pipe_client **cli, POLICY_HND *sam_handle)
1075 struct winbindd_cm_conn *conn;
1078 struct dcinfo *p_dcinfo;
1080 result = init_dc_connection(domain);
1081 if (!NT_STATUS_IS_OK(result)) {
1085 conn = &domain->conn;
1087 if (conn->samr_pipe != NULL) {
1092 * No SAMR pipe yet. Attempt to get an NTLMSSP SPNEGO authenticated
1093 * sign and sealed pipe using the machine account password by
1094 * preference. If we can't - try schannel, if that fails, try
1098 pwd_get_cleartext(&conn->cli->pwd, conn_pwd);
1099 if ((conn->cli->user_name[0] == '\0') ||
1100 (conn->cli->domain[0] == '\0') ||
1101 (conn_pwd[0] == '\0')) {
1102 DEBUG(10, ("cm_connect_sam: No no user available for "
1103 "domain %s, trying schannel\n", conn->cli->domain));
1107 /* We have an authenticated connection. Use a NTLMSSP SPNEGO
1108 authenticated SAMR pipe with sign & seal. */
1110 cli_rpc_pipe_open_spnego_ntlmssp(conn->cli, PI_SAMR,
1111 PIPE_AUTH_LEVEL_PRIVACY,
1113 conn->cli->user_name,
1116 if (conn->samr_pipe == NULL) {
1117 DEBUG(10,("cm_connect_sam: failed to connect to SAMR "
1118 "pipe for domain %s using NTLMSSP "
1119 "authenticated pipe: user %s\\%s. Error was "
1120 "%s\n", domain->name, conn->cli->domain,
1121 conn->cli->user_name, nt_errstr(result)));
1125 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for "
1126 "domain %s using NTLMSSP authenticated "
1127 "pipe: user %s\\%s\n", domain->name,
1128 conn->cli->domain, conn->cli->user_name ));
1130 result = rpccli_samr_connect(conn->samr_pipe, mem_ctx,
1131 SEC_RIGHTS_MAXIMUM_ALLOWED,
1132 &conn->sam_connect_handle);
1133 if (NT_STATUS_IS_OK(result)) {
1136 DEBUG(10,("cm_connect_sam: ntlmssp-sealed rpccli_samr_connect "
1137 "failed for domain %s, error was %s. Trying schannel\n",
1138 domain->name, nt_errstr(result) ));
1139 cli_rpc_pipe_close(conn->samr_pipe);
1143 /* Fall back to schannel if it's a W2K pre-SP1 box. */
1145 if (!cm_get_schannel_dcinfo(domain, &p_dcinfo)) {
1146 DEBUG(10, ("cm_connect_sam: Could not get schannel auth info "
1147 "for domain %s, trying anon\n", conn->cli->domain));
1150 conn->samr_pipe = cli_rpc_pipe_open_schannel_with_key
1151 (conn->cli, PI_SAMR, PIPE_AUTH_LEVEL_PRIVACY,
1152 domain->name, p_dcinfo, &result);
1154 if (conn->samr_pipe == NULL) {
1155 DEBUG(10,("cm_connect_sam: failed to connect to SAMR pipe for "
1156 "domain %s using schannel. Error was %s\n",
1157 domain->name, nt_errstr(result) ));
1160 DEBUG(10,("cm_connect_sam: connected to SAMR pipe for domain %s using "
1161 "schannel.\n", domain->name ));
1163 result = rpccli_samr_connect(conn->samr_pipe, mem_ctx,
1164 SEC_RIGHTS_MAXIMUM_ALLOWED,
1165 &conn->sam_connect_handle);
1166 if (NT_STATUS_IS_OK(result)) {
1169 DEBUG(10,("cm_connect_sam: schannel-sealed rpccli_samr_connect failed "
1170 "for domain %s, error was %s. Trying anonymous\n",
1171 domain->name, nt_errstr(result) ));
1172 cli_rpc_pipe_close(conn->samr_pipe);
1176 /* Finally fall back to anonymous. */
1177 conn->samr_pipe = cli_rpc_pipe_open_noauth(conn->cli, PI_SAMR,
1180 if (conn->samr_pipe == NULL) {
1181 result = NT_STATUS_PIPE_NOT_AVAILABLE;
1185 result = rpccli_samr_connect(conn->samr_pipe, mem_ctx,
1186 SEC_RIGHTS_MAXIMUM_ALLOWED,
1187 &conn->sam_connect_handle);
1188 if (!NT_STATUS_IS_OK(result)) {
1189 DEBUG(10,("cm_connect_sam: rpccli_samr_connect failed "
1190 "for domain %s Error was %s\n",
1191 domain->name, nt_errstr(result) ));
1196 result = rpccli_samr_open_domain(conn->samr_pipe,
1198 &conn->sam_connect_handle,
1199 SEC_RIGHTS_MAXIMUM_ALLOWED,
1201 &conn->sam_domain_handle);
1205 if (!NT_STATUS_IS_OK(result)) {
1206 invalidate_cm_connection(conn);
1210 *cli = conn->samr_pipe;
1211 *sam_handle = conn->sam_domain_handle;
1215 NTSTATUS cm_connect_lsa(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx,
1216 struct rpc_pipe_client **cli, POLICY_HND *lsa_policy)
1218 struct winbindd_cm_conn *conn;
1221 struct dcinfo *p_dcinfo;
1223 result = init_dc_connection(domain);
1224 if (!NT_STATUS_IS_OK(result))
1227 conn = &domain->conn;
1229 if (conn->lsa_pipe != NULL) {
1233 pwd_get_cleartext(&conn->cli->pwd, conn_pwd);
1234 if ((conn->cli->user_name[0] == '\0') ||
1235 (conn->cli->domain[0] == '\0') ||
1236 (conn_pwd[0] == '\0')) {
1237 DEBUG(10, ("cm_connect_lsa: No no user available for "
1238 "domain %s, trying schannel\n", conn->cli->domain));
1242 /* We have an authenticated connection. Use a NTLMSSP SPNEGO
1243 * authenticated LSA pipe with sign & seal. */
1244 conn->lsa_pipe = cli_rpc_pipe_open_spnego_ntlmssp
1245 (conn->cli, PI_LSARPC, PIPE_AUTH_LEVEL_PRIVACY,
1246 conn->cli->domain, conn->cli->user_name, conn_pwd, &result);
1248 if (conn->lsa_pipe == NULL) {
1249 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
1250 "domain %s using NTLMSSP authenticated pipe: user "
1251 "%s\\%s. Error was %s. Trying schannel.\n",
1252 domain->name, conn->cli->domain,
1253 conn->cli->user_name, nt_errstr(result)));
1257 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
1258 "NTLMSSP authenticated pipe: user %s\\%s\n",
1259 domain->name, conn->cli->domain, conn->cli->user_name ));
1261 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
1262 SEC_RIGHTS_MAXIMUM_ALLOWED,
1264 if (NT_STATUS_IS_OK(result)) {
1268 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
1271 cli_rpc_pipe_close(conn->lsa_pipe);
1275 /* Fall back to schannel if it's a W2K pre-SP1 box. */
1277 if (!cm_get_schannel_dcinfo(domain, &p_dcinfo)) {
1278 DEBUG(10, ("cm_connect_lsa: Could not get schannel auth info "
1279 "for domain %s, trying anon\n", conn->cli->domain));
1282 conn->lsa_pipe = cli_rpc_pipe_open_schannel_with_key
1283 (conn->cli, PI_LSARPC, PIPE_AUTH_LEVEL_PRIVACY,
1284 domain->name, p_dcinfo, &result);
1286 if (conn->lsa_pipe == NULL) {
1287 DEBUG(10,("cm_connect_lsa: failed to connect to LSA pipe for "
1288 "domain %s using schannel. Error was %s\n",
1289 domain->name, nt_errstr(result) ));
1292 DEBUG(10,("cm_connect_lsa: connected to LSA pipe for domain %s using "
1293 "schannel.\n", domain->name ));
1295 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
1296 SEC_RIGHTS_MAXIMUM_ALLOWED,
1298 if (NT_STATUS_IS_OK(result)) {
1302 DEBUG(10,("cm_connect_lsa: rpccli_lsa_open_policy failed, trying "
1305 cli_rpc_pipe_close(conn->lsa_pipe);
1309 conn->lsa_pipe = cli_rpc_pipe_open_noauth(conn->cli, PI_LSARPC,
1311 if (conn->lsa_pipe == NULL) {
1312 result = NT_STATUS_PIPE_NOT_AVAILABLE;
1316 result = rpccli_lsa_open_policy(conn->lsa_pipe, mem_ctx, True,
1317 SEC_RIGHTS_MAXIMUM_ALLOWED,
1320 if (!NT_STATUS_IS_OK(result)) {
1321 invalidate_cm_connection(conn);
1322 return NT_STATUS_UNSUCCESSFUL;
1325 *cli = conn->lsa_pipe;
1326 *lsa_policy = conn->lsa_policy;
1330 /****************************************************************************
1331 Open the netlogon pipe to this DC. Use schannel if specified in client conf.
1332 session key stored in conn->netlogon_pipe->dc->sess_key.
1333 ****************************************************************************/
1335 NTSTATUS cm_connect_netlogon(struct winbindd_domain *domain,
1336 struct rpc_pipe_client **cli)
1338 struct winbindd_cm_conn *conn;
1341 uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS;
1343 uint32 sec_chan_type;
1344 const char *account_name;
1345 struct rpc_pipe_client *netlogon_pipe = NULL;
1349 result = init_dc_connection(domain);
1350 if (!NT_STATUS_IS_OK(result)) {
1354 conn = &domain->conn;
1356 if (conn->netlogon_pipe != NULL) {
1357 *cli = conn->netlogon_pipe;
1358 return NT_STATUS_OK;
1361 if (!get_trust_pw(domain->name, mach_pwd, &sec_chan_type)) {
1362 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1365 netlogon_pipe = cli_rpc_pipe_open_noauth(conn->cli, PI_NETLOGON,
1367 if (netlogon_pipe == NULL) {
1371 if (lp_client_schannel() != False) {
1372 neg_flags |= NETLOGON_NEG_SCHANNEL;
1375 /* if we are a DC and this is a trusted domain, then we need to use our
1376 domain name in the net_req_auth2() request */
1379 && !strequal(domain->name, lp_workgroup())
1380 && lp_allow_trusted_domains() )
1382 account_name = lp_workgroup();
1384 account_name = domain->primary ?
1385 global_myname() : domain->name;
1388 if (account_name == NULL) {
1389 cli_rpc_pipe_close(netlogon_pipe);
1390 return NT_STATUS_NO_MEMORY;
1393 result = rpccli_netlogon_setup_creds(
1395 domain->dcname, /* server name. */
1396 domain->name, /* domain name */
1397 global_myname(), /* client name */
1398 account_name, /* machine account */
1399 mach_pwd, /* machine password */
1400 sec_chan_type, /* from get_trust_pw */
1403 if (!NT_STATUS_IS_OK(result)) {
1404 cli_rpc_pipe_close(netlogon_pipe);
1408 if ((lp_client_schannel() == True) &&
1409 ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
1410 DEBUG(3, ("Server did not offer schannel\n"));
1411 cli_rpc_pipe_close(netlogon_pipe);
1412 return NT_STATUS_ACCESS_DENIED;
1415 if ((lp_client_schannel() == False) ||
1416 ((neg_flags & NETLOGON_NEG_SCHANNEL) == 0)) {
1417 /* We're done - just keep the existing connection to NETLOGON
1419 conn->netlogon_pipe = netlogon_pipe;
1420 *cli = conn->netlogon_pipe;
1421 return NT_STATUS_OK;
1424 /* Using the credentials from the first pipe, open a signed and sealed
1425 second netlogon pipe. The session key is stored in the schannel
1426 part of the new pipe auth struct.
1429 conn->netlogon_pipe =
1430 cli_rpc_pipe_open_schannel_with_key(conn->cli,
1432 PIPE_AUTH_LEVEL_PRIVACY,
1437 /* We can now close the initial netlogon pipe. */
1438 cli_rpc_pipe_close(netlogon_pipe);
1440 if (conn->netlogon_pipe == NULL) {
1441 DEBUG(3, ("Could not open schannel'ed NETLOGON pipe. Error "
1442 "was %s\n", nt_errstr(result)));
1444 /* make sure we return something besides OK */
1445 return !NT_STATUS_IS_OK(result) ? result : NT_STATUS_PIPE_NOT_AVAILABLE;
1448 *cli = conn->netlogon_pipe;
1449 return NT_STATUS_OK;