18334SJose.Borrego@Sun.COM /* 28334SJose.Borrego@Sun.COM * CDDL HEADER START 38334SJose.Borrego@Sun.COM * 48334SJose.Borrego@Sun.COM * The contents of this file are subject to the terms of the 58334SJose.Borrego@Sun.COM * Common Development and Distribution License (the "License"). 68334SJose.Borrego@Sun.COM * You may not use this file except in compliance with the License. 78334SJose.Borrego@Sun.COM * 88334SJose.Borrego@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 98334SJose.Borrego@Sun.COM * or http://www.opensolaris.org/os/licensing. 108334SJose.Borrego@Sun.COM * See the License for the specific language governing permissions 118334SJose.Borrego@Sun.COM * and limitations under the License. 128334SJose.Borrego@Sun.COM * 138334SJose.Borrego@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 148334SJose.Borrego@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 158334SJose.Borrego@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 168334SJose.Borrego@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 178334SJose.Borrego@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 188334SJose.Borrego@Sun.COM * 198334SJose.Borrego@Sun.COM * CDDL HEADER END 208334SJose.Borrego@Sun.COM */ 218334SJose.Borrego@Sun.COM /* 228474SJose.Borrego@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 238334SJose.Borrego@Sun.COM * Use is subject to license terms. 248334SJose.Borrego@Sun.COM */ 258334SJose.Borrego@Sun.COM 268334SJose.Borrego@Sun.COM #include <syslog.h> 278334SJose.Borrego@Sun.COM #include <synch.h> 288334SJose.Borrego@Sun.COM #include <pthread.h> 298334SJose.Borrego@Sun.COM #include <unistd.h> 308334SJose.Borrego@Sun.COM #include <string.h> 318334SJose.Borrego@Sun.COM #include <strings.h> 328334SJose.Borrego@Sun.COM #include <sys/errno.h> 338334SJose.Borrego@Sun.COM #include <sys/types.h> 348334SJose.Borrego@Sun.COM #include <netinet/in.h> 358334SJose.Borrego@Sun.COM #include <arpa/nameser.h> 368334SJose.Borrego@Sun.COM #include <resolv.h> 378334SJose.Borrego@Sun.COM #include <netdb.h> 388334SJose.Borrego@Sun.COM #include <assert.h> 398334SJose.Borrego@Sun.COM 408334SJose.Borrego@Sun.COM #include <smbsrv/libsmb.h> 418334SJose.Borrego@Sun.COM #include <smbsrv/libsmbrdr.h> 428334SJose.Borrego@Sun.COM #include <smbsrv/libsmbns.h> 438334SJose.Borrego@Sun.COM #include <smbsrv/libmlsvc.h> 448334SJose.Borrego@Sun.COM 458334SJose.Borrego@Sun.COM #include <smbsrv/smbinfo.h> 468334SJose.Borrego@Sun.COM #include <smbsrv/ntstatus.h> 478334SJose.Borrego@Sun.COM #include <lsalib.h> 488334SJose.Borrego@Sun.COM 498334SJose.Borrego@Sun.COM /* 508334SJose.Borrego@Sun.COM * DC Locator 518334SJose.Borrego@Sun.COM */ 528334SJose.Borrego@Sun.COM #define SMB_DCLOCATOR_TIMEOUT 45 538334SJose.Borrego@Sun.COM #define SMB_IS_FQDN(domain) (strchr(domain, '.') != NULL) 548334SJose.Borrego@Sun.COM 558334SJose.Borrego@Sun.COM typedef struct smb_dclocator { 56*9832Samw@Sun.COM char sdl_domain[SMB_PI_MAX_DOMAIN]; 57*9832Samw@Sun.COM char sdl_dc[MAXHOSTNAMELEN]; 58*9832Samw@Sun.COM boolean_t sdl_locate; 59*9832Samw@Sun.COM mutex_t sdl_mtx; 60*9832Samw@Sun.COM cond_t sdl_cv; 61*9832Samw@Sun.COM uint32_t sdl_status; 628334SJose.Borrego@Sun.COM } smb_dclocator_t; 638334SJose.Borrego@Sun.COM 648334SJose.Borrego@Sun.COM static smb_dclocator_t smb_dclocator; 658334SJose.Borrego@Sun.COM static pthread_t smb_dclocator_thr; 668334SJose.Borrego@Sun.COM 678334SJose.Borrego@Sun.COM static void *smb_dclocator_main(void *); 68*9832Samw@Sun.COM static void smb_domain_update(char *, char *); 69*9832Samw@Sun.COM static boolean_t smb_domain_query_dns(char *, char *, smb_domain_t *); 70*9832Samw@Sun.COM static boolean_t smb_domain_query_nbt(char *, char *, smb_domain_t *); 71*9832Samw@Sun.COM static boolean_t smb_domain_match(char *, char *, uint32_t); 728334SJose.Borrego@Sun.COM static uint32_t smb_domain_query(char *, char *, smb_domain_t *); 73*9832Samw@Sun.COM static void smb_domain_enum_trusted(char *, char *, smb_trusted_domains_t *); 74*9832Samw@Sun.COM static uint32_t smb_domain_use_config(char *, nt_domain_t *); 75*9832Samw@Sun.COM static void smb_domain_free(smb_domain_t *di); 768334SJose.Borrego@Sun.COM 778334SJose.Borrego@Sun.COM /* 788334SJose.Borrego@Sun.COM * =================================================================== 798334SJose.Borrego@Sun.COM * API to initialize DC locator thread, trigger DC discovery, and 808334SJose.Borrego@Sun.COM * get the discovered DC and/or domain information. 818334SJose.Borrego@Sun.COM * =================================================================== 828334SJose.Borrego@Sun.COM */ 838334SJose.Borrego@Sun.COM 848334SJose.Borrego@Sun.COM /* 858334SJose.Borrego@Sun.COM * smb_dclocator_init 868334SJose.Borrego@Sun.COM * 878334SJose.Borrego@Sun.COM * Initialization of the DC locator thread. 888334SJose.Borrego@Sun.COM * Returns 0 on success, an error number if thread creation fails. 898334SJose.Borrego@Sun.COM */ 908334SJose.Borrego@Sun.COM int 918334SJose.Borrego@Sun.COM smb_dclocator_init(void) 928334SJose.Borrego@Sun.COM { 938334SJose.Borrego@Sun.COM pthread_attr_t tattr; 948334SJose.Borrego@Sun.COM int rc; 958334SJose.Borrego@Sun.COM 968334SJose.Borrego@Sun.COM (void) pthread_attr_init(&tattr); 978334SJose.Borrego@Sun.COM (void) pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED); 988334SJose.Borrego@Sun.COM rc = pthread_create(&smb_dclocator_thr, &tattr, 998334SJose.Borrego@Sun.COM smb_dclocator_main, 0); 1008334SJose.Borrego@Sun.COM (void) pthread_attr_destroy(&tattr); 1018334SJose.Borrego@Sun.COM return (rc); 1028334SJose.Borrego@Sun.COM } 1038334SJose.Borrego@Sun.COM 1048334SJose.Borrego@Sun.COM /* 1058334SJose.Borrego@Sun.COM * smb_locate_dc 1068334SJose.Borrego@Sun.COM * 1078334SJose.Borrego@Sun.COM * This is the entry point for discovering a domain controller for the 1088334SJose.Borrego@Sun.COM * specified domain. 1098334SJose.Borrego@Sun.COM * 1108334SJose.Borrego@Sun.COM * The actual work of discovering a DC is handled by DC locator thread. 1118334SJose.Borrego@Sun.COM * All we do here is signal the request and wait for a DC or a timeout. 1128334SJose.Borrego@Sun.COM * 1138334SJose.Borrego@Sun.COM * Input parameters: 1148334SJose.Borrego@Sun.COM * domain - domain to be discovered (can either be NetBIOS or DNS domain) 1158334SJose.Borrego@Sun.COM * dc - preferred DC. If the preferred DC is set to empty string, it 1168334SJose.Borrego@Sun.COM * will attempt to discover any DC in the specified domain. 1178334SJose.Borrego@Sun.COM * 1188334SJose.Borrego@Sun.COM * Output parameter: 1198334SJose.Borrego@Sun.COM * dp - on success, dp will be filled with the discovered DC and domain 1208334SJose.Borrego@Sun.COM * information. 1218334SJose.Borrego@Sun.COM * Returns B_TRUE if the DC/domain info is available. 1228334SJose.Borrego@Sun.COM */ 1238334SJose.Borrego@Sun.COM boolean_t 1248334SJose.Borrego@Sun.COM smb_locate_dc(char *domain, char *dc, smb_domain_t *dp) 1258334SJose.Borrego@Sun.COM { 1268334SJose.Borrego@Sun.COM int rc; 1278334SJose.Borrego@Sun.COM timestruc_t to; 1288334SJose.Borrego@Sun.COM smb_domain_t domain_info; 1298334SJose.Borrego@Sun.COM 1308334SJose.Borrego@Sun.COM if (domain == NULL || *domain == '\0') 1318334SJose.Borrego@Sun.COM return (B_FALSE); 1328334SJose.Borrego@Sun.COM 1338334SJose.Borrego@Sun.COM (void) mutex_lock(&smb_dclocator.sdl_mtx); 1348334SJose.Borrego@Sun.COM 1358334SJose.Borrego@Sun.COM if (!smb_dclocator.sdl_locate) { 1368334SJose.Borrego@Sun.COM smb_dclocator.sdl_locate = B_TRUE; 1378334SJose.Borrego@Sun.COM (void) strlcpy(smb_dclocator.sdl_domain, domain, 1388334SJose.Borrego@Sun.COM SMB_PI_MAX_DOMAIN); 139*9832Samw@Sun.COM (void) strlcpy(smb_dclocator.sdl_dc, dc, MAXHOSTNAMELEN); 1408334SJose.Borrego@Sun.COM (void) cond_broadcast(&smb_dclocator.sdl_cv); 1418334SJose.Borrego@Sun.COM } 1428334SJose.Borrego@Sun.COM 1438334SJose.Borrego@Sun.COM while (smb_dclocator.sdl_locate) { 1448334SJose.Borrego@Sun.COM to.tv_sec = SMB_DCLOCATOR_TIMEOUT; 1458334SJose.Borrego@Sun.COM to.tv_nsec = 0; 1468334SJose.Borrego@Sun.COM rc = cond_reltimedwait(&smb_dclocator.sdl_cv, 1478334SJose.Borrego@Sun.COM &smb_dclocator.sdl_mtx, &to); 1488334SJose.Borrego@Sun.COM 1498334SJose.Borrego@Sun.COM if (rc == ETIME) 1508334SJose.Borrego@Sun.COM break; 1518334SJose.Borrego@Sun.COM } 1528334SJose.Borrego@Sun.COM 1538334SJose.Borrego@Sun.COM if (dp == NULL) 1548334SJose.Borrego@Sun.COM dp = &domain_info; 1558334SJose.Borrego@Sun.COM rc = smb_domain_getinfo(dp); 156*9832Samw@Sun.COM 1578334SJose.Borrego@Sun.COM (void) mutex_unlock(&smb_dclocator.sdl_mtx); 1588334SJose.Borrego@Sun.COM 1598334SJose.Borrego@Sun.COM return (rc); 1608334SJose.Borrego@Sun.COM } 1618334SJose.Borrego@Sun.COM 1628334SJose.Borrego@Sun.COM /* 163*9832Samw@Sun.COM * Returns a copy of primary domain information plus 164*9832Samw@Sun.COM * the selected domain controller 1658334SJose.Borrego@Sun.COM */ 1668334SJose.Borrego@Sun.COM boolean_t 1678334SJose.Borrego@Sun.COM smb_domain_getinfo(smb_domain_t *dp) 1688334SJose.Borrego@Sun.COM { 169*9832Samw@Sun.COM return (nt_domain_get_primary(dp)); 1708334SJose.Borrego@Sun.COM } 1718334SJose.Borrego@Sun.COM 1728334SJose.Borrego@Sun.COM /* 1738334SJose.Borrego@Sun.COM * ========================================================== 1748334SJose.Borrego@Sun.COM * DC discovery functions 1758334SJose.Borrego@Sun.COM * ========================================================== 1768334SJose.Borrego@Sun.COM */ 1778334SJose.Borrego@Sun.COM 1788334SJose.Borrego@Sun.COM /* 1798334SJose.Borrego@Sun.COM * This is the DC discovery thread: it gets woken up whenever someone 1808334SJose.Borrego@Sun.COM * wants to locate a domain controller. 1818334SJose.Borrego@Sun.COM * 182*9832Samw@Sun.COM * Upon success, the SMB domain cache will be populated with the discovered 183*9832Samw@Sun.COM * DC and domain info. 1848334SJose.Borrego@Sun.COM */ 1858334SJose.Borrego@Sun.COM /*ARGSUSED*/ 1868334SJose.Borrego@Sun.COM static void * 1878334SJose.Borrego@Sun.COM smb_dclocator_main(void *arg) 1888334SJose.Borrego@Sun.COM { 1898334SJose.Borrego@Sun.COM char domain[SMB_PI_MAX_DOMAIN]; 1908334SJose.Borrego@Sun.COM char sought_dc[MAXHOSTNAMELEN]; 1918334SJose.Borrego@Sun.COM 1928334SJose.Borrego@Sun.COM for (;;) { 1938334SJose.Borrego@Sun.COM (void) mutex_lock(&smb_dclocator.sdl_mtx); 1948334SJose.Borrego@Sun.COM 1958334SJose.Borrego@Sun.COM while (!smb_dclocator.sdl_locate) 1968334SJose.Borrego@Sun.COM (void) cond_wait(&smb_dclocator.sdl_cv, 1978334SJose.Borrego@Sun.COM &smb_dclocator.sdl_mtx); 1988334SJose.Borrego@Sun.COM 1998334SJose.Borrego@Sun.COM (void) strlcpy(domain, smb_dclocator.sdl_domain, 2008334SJose.Borrego@Sun.COM SMB_PI_MAX_DOMAIN); 2018334SJose.Borrego@Sun.COM (void) strlcpy(sought_dc, smb_dclocator.sdl_dc, MAXHOSTNAMELEN); 2028334SJose.Borrego@Sun.COM (void) mutex_unlock(&smb_dclocator.sdl_mtx); 2038334SJose.Borrego@Sun.COM 204*9832Samw@Sun.COM smb_domain_update(domain, sought_dc); 2058334SJose.Borrego@Sun.COM 2068334SJose.Borrego@Sun.COM (void) mutex_lock(&smb_dclocator.sdl_mtx); 2078334SJose.Borrego@Sun.COM smb_dclocator.sdl_locate = B_FALSE; 2088334SJose.Borrego@Sun.COM (void) cond_broadcast(&smb_dclocator.sdl_cv); 2098334SJose.Borrego@Sun.COM (void) mutex_unlock(&smb_dclocator.sdl_mtx); 2108334SJose.Borrego@Sun.COM } 2118334SJose.Borrego@Sun.COM 2128334SJose.Borrego@Sun.COM /*NOTREACHED*/ 2138334SJose.Borrego@Sun.COM return (NULL); 2148334SJose.Borrego@Sun.COM } 2158334SJose.Borrego@Sun.COM 2168334SJose.Borrego@Sun.COM /* 217*9832Samw@Sun.COM * Discovers a domain controller for the specified domain either via 218*9832Samw@Sun.COM * DNS or NetBIOS. After the domain controller is discovered successfully 219*9832Samw@Sun.COM * primary and trusted domain infromation will be queried using RPC queries. 220*9832Samw@Sun.COM * If the RPC queries fail, the domain information stored in SMF might be used 221*9832Samw@Sun.COM * if the the discovered domain is the same as the previously joined domain. 222*9832Samw@Sun.COM * If everything is successful domain cache will be updated with all the 223*9832Samw@Sun.COM * obtained information. 224*9832Samw@Sun.COM */ 225*9832Samw@Sun.COM static void 226*9832Samw@Sun.COM smb_domain_update(char *domain, char *server) 227*9832Samw@Sun.COM { 228*9832Samw@Sun.COM smb_domain_t di; 229*9832Samw@Sun.COM boolean_t query_ok; 230*9832Samw@Sun.COM 231*9832Samw@Sun.COM bzero(&di, sizeof (smb_domain_t)); 232*9832Samw@Sun.COM 233*9832Samw@Sun.COM nt_domain_start_update(); 234*9832Samw@Sun.COM 235*9832Samw@Sun.COM if (SMB_IS_FQDN(domain)) 236*9832Samw@Sun.COM query_ok = smb_domain_query_dns(domain, server, &di); 237*9832Samw@Sun.COM else 238*9832Samw@Sun.COM query_ok = smb_domain_query_nbt(domain, server, &di); 239*9832Samw@Sun.COM 240*9832Samw@Sun.COM if (query_ok) 241*9832Samw@Sun.COM nt_domain_update(&di); 242*9832Samw@Sun.COM 243*9832Samw@Sun.COM nt_domain_end_update(); 244*9832Samw@Sun.COM 245*9832Samw@Sun.COM smb_domain_free(&di); 246*9832Samw@Sun.COM 247*9832Samw@Sun.COM if (query_ok) 248*9832Samw@Sun.COM nt_domain_save(); 249*9832Samw@Sun.COM } 250*9832Samw@Sun.COM 251*9832Samw@Sun.COM /* 252*9832Samw@Sun.COM * Discovers a DC for the specified domain via DNS. If a DC is found 253*9832Samw@Sun.COM * primary and trusted domains information will be queried. 254*9832Samw@Sun.COM */ 255*9832Samw@Sun.COM static boolean_t 256*9832Samw@Sun.COM smb_domain_query_dns(char *domain, char *server, smb_domain_t *di) 257*9832Samw@Sun.COM { 258*9832Samw@Sun.COM uint32_t status; 259*9832Samw@Sun.COM if (!smb_ads_lookup_msdcs(domain, server, di->d_dc, MAXHOSTNAMELEN)) 260*9832Samw@Sun.COM return (B_FALSE); 261*9832Samw@Sun.COM 262*9832Samw@Sun.COM status = smb_domain_query(domain, di->d_dc, di); 263*9832Samw@Sun.COM return (status == NT_STATUS_SUCCESS); 264*9832Samw@Sun.COM } 265*9832Samw@Sun.COM 266*9832Samw@Sun.COM /* 267*9832Samw@Sun.COM * Discovers a DC for the specified domain using NETLOGON protocol. 268*9832Samw@Sun.COM * If a DC cannot be found using NETLOGON then it will 2698334SJose.Borrego@Sun.COM * try to resolve it via DNS, i.e. find out if it is the first label 2708334SJose.Borrego@Sun.COM * of a DNS domain name. If the corresponding DNS name is found, DC 2718334SJose.Borrego@Sun.COM * discovery will be done via DNS query. 2728334SJose.Borrego@Sun.COM * 2738334SJose.Borrego@Sun.COM * If the fully-qualified domain name is derived from the DNS config 2748334SJose.Borrego@Sun.COM * file, the NetBIOS domain name specified by the user will be compared 2758334SJose.Borrego@Sun.COM * against the NetBIOS domain name obtained via LSA query. If there is 2768334SJose.Borrego@Sun.COM * a mismatch, the DC discovery will fail since the discovered DC is 2778334SJose.Borrego@Sun.COM * actually for another domain, whose first label of its FQDN somehow 2788334SJose.Borrego@Sun.COM * matches with the NetBIOS name of the domain we're interested in. 2798334SJose.Borrego@Sun.COM */ 280*9832Samw@Sun.COM 2818334SJose.Borrego@Sun.COM static boolean_t 282*9832Samw@Sun.COM smb_domain_query_nbt(char *domain, char *server, smb_domain_t *di) 2838334SJose.Borrego@Sun.COM { 284*9832Samw@Sun.COM char dnsdomain[MAXHOSTNAMELEN]; 285*9832Samw@Sun.COM uint32_t status; 2868334SJose.Borrego@Sun.COM 287*9832Samw@Sun.COM *dnsdomain = '\0'; 288*9832Samw@Sun.COM 289*9832Samw@Sun.COM if (!smb_browser_netlogon(domain, di->d_dc, MAXHOSTNAMELEN)) { 290*9832Samw@Sun.COM if (!smb_domain_match(domain, dnsdomain, MAXHOSTNAMELEN)) 291*9832Samw@Sun.COM return (B_FALSE); 292*9832Samw@Sun.COM 293*9832Samw@Sun.COM if (!smb_ads_lookup_msdcs(dnsdomain, server, di->d_dc, 2948334SJose.Borrego@Sun.COM MAXHOSTNAMELEN)) 2958334SJose.Borrego@Sun.COM return (B_FALSE); 2968334SJose.Borrego@Sun.COM } 2978334SJose.Borrego@Sun.COM 298*9832Samw@Sun.COM status = smb_domain_query(domain, di->d_dc, di); 299*9832Samw@Sun.COM if (status != NT_STATUS_SUCCESS) 3008334SJose.Borrego@Sun.COM return (B_FALSE); 3018334SJose.Borrego@Sun.COM 302*9832Samw@Sun.COM if ((*dnsdomain != '\0') && 303*9832Samw@Sun.COM utf8_strcasecmp(domain, di->d_info.di_nbname)) 3048334SJose.Borrego@Sun.COM return (B_FALSE); 3058334SJose.Borrego@Sun.COM 3068334SJose.Borrego@Sun.COM /* 3078334SJose.Borrego@Sun.COM * Now that we get the fully-qualified DNS name of the 3088334SJose.Borrego@Sun.COM * domain via LSA query. Verifies ADS configuration 3098334SJose.Borrego@Sun.COM * if we previously locate a DC via NetBIOS. On success, 3108334SJose.Borrego@Sun.COM * ADS cache will be populated. 3118334SJose.Borrego@Sun.COM */ 312*9832Samw@Sun.COM if (smb_ads_lookup_msdcs(di->d_info.di_fqname, server, 313*9832Samw@Sun.COM di->d_dc, MAXHOSTNAMELEN) == 0) 314*9832Samw@Sun.COM return (B_FALSE); 3158334SJose.Borrego@Sun.COM 3168334SJose.Borrego@Sun.COM return (B_TRUE); 3178334SJose.Borrego@Sun.COM } 3188334SJose.Borrego@Sun.COM 3198334SJose.Borrego@Sun.COM /* 3208334SJose.Borrego@Sun.COM * Tries to find a matching DNS domain for the given NetBIOS domain 3218334SJose.Borrego@Sun.COM * name by checking the first label of system's configured DNS domains. 3228334SJose.Borrego@Sun.COM * If a match is found, it'll be returned in the passed buffer. 3238334SJose.Borrego@Sun.COM */ 3248334SJose.Borrego@Sun.COM static boolean_t 325*9832Samw@Sun.COM smb_domain_match(char *nb_domain, char *buf, uint32_t len) 3268334SJose.Borrego@Sun.COM { 3278334SJose.Borrego@Sun.COM struct __res_state res_state; 3288334SJose.Borrego@Sun.COM int i; 3298334SJose.Borrego@Sun.COM char *entry, *p; 3308334SJose.Borrego@Sun.COM char first_label[MAXHOSTNAMELEN]; 3318334SJose.Borrego@Sun.COM boolean_t found; 3328334SJose.Borrego@Sun.COM 3338334SJose.Borrego@Sun.COM if (!nb_domain || !buf) 3348334SJose.Borrego@Sun.COM return (B_FALSE); 3358334SJose.Borrego@Sun.COM 3368334SJose.Borrego@Sun.COM *buf = '\0'; 3378334SJose.Borrego@Sun.COM bzero(&res_state, sizeof (struct __res_state)); 3388334SJose.Borrego@Sun.COM if (res_ninit(&res_state)) 3398334SJose.Borrego@Sun.COM return (B_FALSE); 3408334SJose.Borrego@Sun.COM 3418334SJose.Borrego@Sun.COM found = B_FALSE; 3428334SJose.Borrego@Sun.COM entry = res_state.defdname; 3438334SJose.Borrego@Sun.COM for (i = 0; entry != NULL; i++) { 3448334SJose.Borrego@Sun.COM (void) strlcpy(first_label, entry, MAXHOSTNAMELEN); 3458334SJose.Borrego@Sun.COM if ((p = strchr(first_label, '.')) != NULL) { 3468334SJose.Borrego@Sun.COM *p = '\0'; 3478334SJose.Borrego@Sun.COM if (strlen(first_label) > 15) 3488334SJose.Borrego@Sun.COM first_label[15] = '\0'; 3498334SJose.Borrego@Sun.COM } 3508334SJose.Borrego@Sun.COM 3518334SJose.Borrego@Sun.COM if (utf8_strcasecmp(nb_domain, first_label) == 0) { 3528334SJose.Borrego@Sun.COM found = B_TRUE; 3538334SJose.Borrego@Sun.COM (void) strlcpy(buf, entry, len); 3548334SJose.Borrego@Sun.COM break; 3558334SJose.Borrego@Sun.COM } 3568334SJose.Borrego@Sun.COM 3578334SJose.Borrego@Sun.COM entry = res_state.dnsrch[i]; 3588334SJose.Borrego@Sun.COM } 3598334SJose.Borrego@Sun.COM 3608334SJose.Borrego@Sun.COM 3618334SJose.Borrego@Sun.COM res_ndestroy(&res_state); 3628334SJose.Borrego@Sun.COM return (found); 3638334SJose.Borrego@Sun.COM } 3648334SJose.Borrego@Sun.COM 3658334SJose.Borrego@Sun.COM /* 366*9832Samw@Sun.COM * Obtain primary and trusted domain information using LSA queries. 3678334SJose.Borrego@Sun.COM * 368*9832Samw@Sun.COM * Disconnect any existing connection with the domain controller. 369*9832Samw@Sun.COM * This will ensure that no stale connection will be used, it will 370*9832Samw@Sun.COM * also pickup any configuration changes in either side by trying 371*9832Samw@Sun.COM * to establish a new connection. 3728334SJose.Borrego@Sun.COM * 3738334SJose.Borrego@Sun.COM * domain - either NetBIOS or fully-qualified domain name 3748334SJose.Borrego@Sun.COM */ 3758334SJose.Borrego@Sun.COM static uint32_t 376*9832Samw@Sun.COM smb_domain_query(char *domain, char *server, smb_domain_t *di) 3778334SJose.Borrego@Sun.COM { 378*9832Samw@Sun.COM uint32_t status; 379*9832Samw@Sun.COM 380*9832Samw@Sun.COM mlsvc_disconnect(server); 3818334SJose.Borrego@Sun.COM 382*9832Samw@Sun.COM status = lsa_query_dns_domain_info(server, domain, &di->d_info); 383*9832Samw@Sun.COM if (status != NT_STATUS_SUCCESS) { 384*9832Samw@Sun.COM status = smb_domain_use_config(domain, &di->d_info); 385*9832Samw@Sun.COM if (status != NT_STATUS_SUCCESS) 386*9832Samw@Sun.COM status = lsa_query_primary_domain_info(server, domain, 387*9832Samw@Sun.COM &di->d_info); 3888334SJose.Borrego@Sun.COM } 3898334SJose.Borrego@Sun.COM 390*9832Samw@Sun.COM if (status == NT_STATUS_SUCCESS) 391*9832Samw@Sun.COM smb_domain_enum_trusted(domain, server, &di->d_trusted); 392*9832Samw@Sun.COM 393*9832Samw@Sun.COM return (status); 3948334SJose.Borrego@Sun.COM } 3958334SJose.Borrego@Sun.COM 3968334SJose.Borrego@Sun.COM /* 397*9832Samw@Sun.COM * Obtain trusted domains information using LSA queries. 3988334SJose.Borrego@Sun.COM * 3998334SJose.Borrego@Sun.COM * domain - either NetBIOS or fully-qualified domain name. 4008334SJose.Borrego@Sun.COM */ 4018334SJose.Borrego@Sun.COM static void 402*9832Samw@Sun.COM smb_domain_enum_trusted(char *domain, char *server, smb_trusted_domains_t *list) 4038334SJose.Borrego@Sun.COM { 404*9832Samw@Sun.COM uint32_t status; 4058334SJose.Borrego@Sun.COM 406*9832Samw@Sun.COM status = lsa_enum_trusted_domains_ex(server, domain, list); 407*9832Samw@Sun.COM if (status != NT_STATUS_SUCCESS) 408*9832Samw@Sun.COM (void) lsa_enum_trusted_domains(server, domain, list); 4098334SJose.Borrego@Sun.COM } 4108334SJose.Borrego@Sun.COM 4118334SJose.Borrego@Sun.COM /* 4128334SJose.Borrego@Sun.COM * If the domain to be discovered matches the current domain (i.e the 4138334SJose.Borrego@Sun.COM * value of either domain or fqdn configuration), the output parameter 4148334SJose.Borrego@Sun.COM * 'dinfo' will be set to the information stored in SMF. 4158334SJose.Borrego@Sun.COM */ 416*9832Samw@Sun.COM static uint32_t 417*9832Samw@Sun.COM smb_domain_use_config(char *domain, nt_domain_t *dinfo) 4188334SJose.Borrego@Sun.COM { 4198334SJose.Borrego@Sun.COM boolean_t use; 4208334SJose.Borrego@Sun.COM 421*9832Samw@Sun.COM bzero(dinfo, sizeof (nt_domain_t)); 422*9832Samw@Sun.COM 4238334SJose.Borrego@Sun.COM if (smb_config_get_secmode() != SMB_SECMODE_DOMAIN) 424*9832Samw@Sun.COM return (NT_STATUS_UNSUCCESSFUL); 4258334SJose.Borrego@Sun.COM 426*9832Samw@Sun.COM smb_config_getdomaininfo(dinfo->di_nbname, dinfo->di_fqname, 427*9832Samw@Sun.COM NULL, NULL, NULL); 4288334SJose.Borrego@Sun.COM 429*9832Samw@Sun.COM if (SMB_IS_FQDN(domain)) 430*9832Samw@Sun.COM use = (utf8_strcasecmp(dinfo->di_fqname, domain) == 0); 431*9832Samw@Sun.COM else 432*9832Samw@Sun.COM use = (utf8_strcasecmp(dinfo->di_nbname, domain) == 0); 4338334SJose.Borrego@Sun.COM 434*9832Samw@Sun.COM if (use) 435*9832Samw@Sun.COM smb_config_getdomaininfo(NULL, NULL, dinfo->di_sid, 436*9832Samw@Sun.COM dinfo->di_u.di_dns.ddi_forest, 437*9832Samw@Sun.COM dinfo->di_u.di_dns.ddi_guid); 4388334SJose.Borrego@Sun.COM 439*9832Samw@Sun.COM return ((use) ? NT_STATUS_SUCCESS : NT_STATUS_UNSUCCESSFUL); 4408334SJose.Borrego@Sun.COM } 441*9832Samw@Sun.COM 442*9832Samw@Sun.COM static void 443*9832Samw@Sun.COM smb_domain_free(smb_domain_t *di) 444*9832Samw@Sun.COM { 445*9832Samw@Sun.COM free(di->d_trusted.td_domains); 446*9832Samw@Sun.COM } 447