15331Samw /* 25331Samw * CDDL HEADER START 35331Samw * 45331Samw * The contents of this file are subject to the terms of the 55331Samw * Common Development and Distribution License (the "License"). 65331Samw * You may not use this file except in compliance with the License. 75331Samw * 85331Samw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 95331Samw * or http://www.opensolaris.org/os/licensing. 105331Samw * See the License for the specific language governing permissions 115331Samw * and limitations under the License. 125331Samw * 135331Samw * When distributing Covered Code, include this CDDL HEADER in each 145331Samw * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 155331Samw * If applicable, add the following below this CDDL HEADER, with the 165331Samw * fields enclosed by brackets "[]" replaced with your own identifying 175331Samw * information: Portions Copyright [yyyy] [name of copyright owner] 185331Samw * 195331Samw * CDDL HEADER END 205331Samw */ 215331Samw /* 228474SJose.Borrego@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 235331Samw * Use is subject to license terms. 245331Samw */ 255331Samw 265331Samw /* 279832Samw@Sun.COM * This file defines the domain environment values and the domain 285331Samw * database interface. The database is a single linked list of 295331Samw * structures containing domain type, name and SID information. 305331Samw */ 315331Samw 328474SJose.Borrego@Sun.COM #include <sys/types.h> 338474SJose.Borrego@Sun.COM #include <sys/stat.h> 349832Samw@Sun.COM #include <sys/list.h> 358474SJose.Borrego@Sun.COM #include <stdio.h> 365331Samw #include <strings.h> 378474SJose.Borrego@Sun.COM #include <string.h> 385331Samw #include <unistd.h> 398474SJose.Borrego@Sun.COM #include <stdlib.h> 405331Samw #include <synch.h> 418474SJose.Borrego@Sun.COM #include <pwd.h> 428474SJose.Borrego@Sun.COM #include <grp.h> 439832Samw@Sun.COM #include <assert.h> 445331Samw 455331Samw #include <smbsrv/smbinfo.h> 465331Samw #include <smbsrv/string.h> 476432Sas200622 #include <smbsrv/smb_sid.h> 485331Samw #include <smbsrv/libsmb.h> 495331Samw 508474SJose.Borrego@Sun.COM #define SMB_DOMAINS_FILE "domains" 515331Samw 529832Samw@Sun.COM #define SMB_DCACHE_UPDATE_WAIT 45 /* seconds */ 539832Samw@Sun.COM 549832Samw@Sun.COM /* 559832Samw@Sun.COM * Domain cache states 569832Samw@Sun.COM */ 579832Samw@Sun.COM #define SMB_DCACHE_STATE_NONE 0 589832Samw@Sun.COM #define SMB_DCACHE_STATE_READY 1 599832Samw@Sun.COM #define SMB_DCACHE_STATE_UPDATING 2 609832Samw@Sun.COM #define SMB_DCACHE_STATE_DESTROYING 3 615331Samw 625331Samw /* 639832Samw@Sun.COM * Cache lock modes 645331Samw */ 659832Samw@Sun.COM #define SMB_DCACHE_RDLOCK 0 669832Samw@Sun.COM #define SMB_DCACHE_WRLOCK 1 679832Samw@Sun.COM 689832Samw@Sun.COM typedef struct smb_domain_cache { 699832Samw@Sun.COM list_t dc_cache; 709832Samw@Sun.COM rwlock_t dc_cache_lck; 719832Samw@Sun.COM mutex_t dc_mtx; 729832Samw@Sun.COM cond_t dc_cv; 739832Samw@Sun.COM uint32_t dc_state; 749832Samw@Sun.COM uint32_t dc_nops; 759832Samw@Sun.COM char dc_server[MAXHOSTNAMELEN]; 769832Samw@Sun.COM } smb_domain_cache_t; 779832Samw@Sun.COM 789832Samw@Sun.COM static smb_domain_cache_t smb_dcache; 795331Samw 8010717Samw@Sun.COM static uint32_t smb_domain_add(smb_domain_type_t, smb_domain_t *); 8110717Samw@Sun.COM static uint32_t smb_domain_add_local(void); 8210717Samw@Sun.COM static uint32_t smb_domain_add_primary(uint32_t); 8310717Samw@Sun.COM static void smb_domain_unlink(void); 845331Samw 859832Samw@Sun.COM static void smb_dcache_create(void); 869832Samw@Sun.COM static void smb_dcache_destroy(void); 879832Samw@Sun.COM static uint32_t smb_dcache_lock(int); 889832Samw@Sun.COM static void smb_dcache_unlock(void); 8910717Samw@Sun.COM static void smb_dcache_remove(smb_domain_t *); 9010717Samw@Sun.COM static uint32_t smb_dcache_add(smb_domain_t *); 919832Samw@Sun.COM static void smb_dcache_getdc(char *, size_t); 929832Samw@Sun.COM static void smb_dcache_setdc(char *); 939832Samw@Sun.COM static boolean_t smb_dcache_wait(void); 9410717Samw@Sun.COM static uint32_t smb_dcache_updating(void); 959832Samw@Sun.COM static void smb_dcache_ready(void); 965331Samw 975331Samw /* 989832Samw@Sun.COM * domain cache one time initialization. This function should 999832Samw@Sun.COM * only be called during service startup. 1005331Samw * 1019832Samw@Sun.COM * Returns 0 on success and an error code on failure. 1025331Samw */ 1035331Samw int 10410717Samw@Sun.COM smb_domain_init(uint32_t secmode) 1055331Samw { 10610717Samw@Sun.COM smb_domain_t di; 1075772Sas200622 int rc; 1085331Samw 1099832Samw@Sun.COM smb_dcache_create(); 1105331Samw 11110717Samw@Sun.COM if ((rc = smb_domain_add_local()) != 0) 1129832Samw@Sun.COM return (rc); 1135331Samw 11410717Samw@Sun.COM smb_domain_set_basic_info(NT_BUILTIN_DOMAIN_SIDSTR, "BUILTIN", "", &di); 11510717Samw@Sun.COM (void) smb_domain_add(SMB_DOMAIN_BUILTIN, &di); 1165331Samw 11710717Samw@Sun.COM return (smb_domain_add_primary(secmode)); 1185331Samw } 1195331Samw 1205331Samw /* 1219832Samw@Sun.COM * Destroys the cache upon service termination 1225331Samw */ 1239832Samw@Sun.COM void 12410717Samw@Sun.COM smb_domain_fini(void) 1255331Samw { 1269832Samw@Sun.COM smb_dcache_destroy(); 12710717Samw@Sun.COM smb_domain_unlink(); 1289832Samw@Sun.COM } 1295331Samw 1309832Samw@Sun.COM /* 1319832Samw@Sun.COM * Add a domain structure to domain cache. There is no checking 1329832Samw@Sun.COM * for duplicates. 1339832Samw@Sun.COM */ 1349832Samw@Sun.COM static uint32_t 13510717Samw@Sun.COM smb_domain_add(smb_domain_type_t type, smb_domain_t *di) 1369832Samw@Sun.COM { 1379832Samw@Sun.COM uint32_t res; 1385331Samw 1399832Samw@Sun.COM if ((di == NULL) || (di->di_sid == NULL)) 1409832Samw@Sun.COM return (SMB_DOMAIN_INVALID_ARG); 1415331Samw 1429832Samw@Sun.COM if ((res = smb_dcache_lock(SMB_DCACHE_WRLOCK)) == SMB_DOMAIN_SUCCESS) { 1439832Samw@Sun.COM di->di_type = type; 1449832Samw@Sun.COM res = smb_dcache_add(di); 1459832Samw@Sun.COM smb_dcache_unlock(); 1469832Samw@Sun.COM } 1479832Samw@Sun.COM 1489832Samw@Sun.COM return (res); 1495331Samw } 1505331Samw 1515331Samw /* 1529832Samw@Sun.COM * Lookup a domain by its name. The passed name is the NETBIOS or fully 1539832Samw@Sun.COM * qualified DNS name or non-qualified DNS name. 1545331Samw * 1559832Samw@Sun.COM * If the requested domain is found and given 'di' pointer is not NULL 1569832Samw@Sun.COM * it'll be filled with the domain information and B_TRUE is returned. 1579832Samw@Sun.COM * If the caller only needs to check a domain existence it can pass 1589832Samw@Sun.COM * NULL for 'di' and just check the return value. 1599832Samw@Sun.COM * 1609832Samw@Sun.COM * If the domain is not in the cache B_FALSE is returned. 1615331Samw */ 1629832Samw@Sun.COM boolean_t 16310717Samw@Sun.COM smb_domain_lookup_name(char *name, smb_domain_t *di) 1645331Samw { 1659832Samw@Sun.COM boolean_t found = B_FALSE; 16610717Samw@Sun.COM smb_domain_t *dcnode; 1679832Samw@Sun.COM char *p; 1689832Samw@Sun.COM 16910717Samw@Sun.COM bzero(di, sizeof (smb_domain_t)); 1709832Samw@Sun.COM 1719832Samw@Sun.COM if (name == NULL || *name == '\0') 1729832Samw@Sun.COM return (B_FALSE); 1739832Samw@Sun.COM 1749832Samw@Sun.COM if (smb_dcache_lock(SMB_DCACHE_RDLOCK) != SMB_DOMAIN_SUCCESS) 1759832Samw@Sun.COM return (B_FALSE); 1769832Samw@Sun.COM 1779832Samw@Sun.COM dcnode = list_head(&smb_dcache.dc_cache); 1789832Samw@Sun.COM while (dcnode) { 179*10966SJordan.Brown@Sun.COM found = (smb_strcasecmp(dcnode->di_nbname, name, 0) == 0) || 180*10966SJordan.Brown@Sun.COM (smb_strcasecmp(dcnode->di_fqname, name, 0) == 0); 1819832Samw@Sun.COM 1829832Samw@Sun.COM if (found) { 1839832Samw@Sun.COM if (di) 1849832Samw@Sun.COM *di = *dcnode; 1859832Samw@Sun.COM break; 1869832Samw@Sun.COM } 1879832Samw@Sun.COM 1889832Samw@Sun.COM if ((p = strchr(dcnode->di_fqname, '.')) != NULL) { 1899832Samw@Sun.COM *p = '\0'; 190*10966SJordan.Brown@Sun.COM found = (smb_strcasecmp(dcnode->di_fqname, name, 191*10966SJordan.Brown@Sun.COM 0) == 0); 1929832Samw@Sun.COM *p = '.'; 1939832Samw@Sun.COM if (found) { 1949832Samw@Sun.COM if (di) 1959832Samw@Sun.COM *di = *dcnode; 1969832Samw@Sun.COM break; 1979832Samw@Sun.COM } 1989832Samw@Sun.COM } 1999832Samw@Sun.COM 2009832Samw@Sun.COM dcnode = list_next(&smb_dcache.dc_cache, dcnode); 2015331Samw } 2029832Samw@Sun.COM 2039832Samw@Sun.COM smb_dcache_unlock(); 2049832Samw@Sun.COM return (found); 2055331Samw } 2065331Samw 2075331Samw /* 2089832Samw@Sun.COM * Lookup a domain by its SID. 2099832Samw@Sun.COM * 2109832Samw@Sun.COM * If the requested domain is found and given 'di' pointer is not NULL 2119832Samw@Sun.COM * it'll be filled with the domain information and B_TRUE is returned. 2129832Samw@Sun.COM * If the caller only needs to check a domain existence it can pass 2139832Samw@Sun.COM * NULL for 'di' and just check the return value. 2145331Samw * 2159832Samw@Sun.COM * If the domain is not in the cache B_FALSE is returned. 2165331Samw */ 2179832Samw@Sun.COM boolean_t 21810717Samw@Sun.COM smb_domain_lookup_sid(smb_sid_t *sid, smb_domain_t *di) 2195331Samw { 2209832Samw@Sun.COM boolean_t found = B_FALSE; 22110717Samw@Sun.COM smb_domain_t *dcnode; 2226432Sas200622 char sidstr[SMB_SID_STRSZ]; 2235331Samw 22410717Samw@Sun.COM bzero(di, sizeof (smb_domain_t)); 2255331Samw 2269832Samw@Sun.COM if (sid == NULL) 2279832Samw@Sun.COM return (B_FALSE); 2285331Samw 2299832Samw@Sun.COM smb_sid_tostr(sid, sidstr); 2305331Samw 2319832Samw@Sun.COM if (smb_dcache_lock(SMB_DCACHE_RDLOCK) != SMB_DOMAIN_SUCCESS) 2329832Samw@Sun.COM return (B_FALSE); 2335331Samw 2349832Samw@Sun.COM dcnode = list_head(&smb_dcache.dc_cache); 2359832Samw@Sun.COM while (dcnode) { 2369832Samw@Sun.COM found = (strcmp(dcnode->di_sid, sidstr) == 0); 2379832Samw@Sun.COM if (found) { 2389832Samw@Sun.COM if (di) 2399832Samw@Sun.COM *di = *dcnode; 2409832Samw@Sun.COM break; 2419832Samw@Sun.COM } 2425331Samw 2439832Samw@Sun.COM dcnode = list_next(&smb_dcache.dc_cache, dcnode); 2449832Samw@Sun.COM } 2455331Samw 2469832Samw@Sun.COM smb_dcache_unlock(); 2479832Samw@Sun.COM return (found); 2485331Samw } 2495331Samw 2505331Samw /* 2519832Samw@Sun.COM * Lookup a domain by its type. 2525331Samw * 2539832Samw@Sun.COM * If the requested domain is found and given 'di' pointer is not NULL 2549832Samw@Sun.COM * it'll be filled with the domain information and B_TRUE is returned. 2559832Samw@Sun.COM * If the caller only needs to check a domain existence it can pass 2569832Samw@Sun.COM * NULL for 'di' and just check the return value. 2579832Samw@Sun.COM * 2589832Samw@Sun.COM * If the domain is not in the cache B_FALSE is returned. 2595331Samw */ 2609832Samw@Sun.COM boolean_t 26110717Samw@Sun.COM smb_domain_lookup_type(smb_domain_type_t type, smb_domain_t *di) 2625331Samw { 2639832Samw@Sun.COM boolean_t found = B_FALSE; 26410717Samw@Sun.COM smb_domain_t *dcnode; 2655331Samw 26610717Samw@Sun.COM bzero(di, sizeof (smb_domain_t)); 2675331Samw 2689832Samw@Sun.COM if (smb_dcache_lock(SMB_DCACHE_RDLOCK) != SMB_DOMAIN_SUCCESS) 2699832Samw@Sun.COM return (B_FALSE); 2705331Samw 2719832Samw@Sun.COM dcnode = list_head(&smb_dcache.dc_cache); 2729832Samw@Sun.COM while (dcnode) { 2739832Samw@Sun.COM if (dcnode->di_type == type) { 2749832Samw@Sun.COM found = B_TRUE; 2759832Samw@Sun.COM if (di) 2769832Samw@Sun.COM *di = *dcnode; 2779832Samw@Sun.COM break; 2789832Samw@Sun.COM } 2795331Samw 2809832Samw@Sun.COM dcnode = list_next(&smb_dcache.dc_cache, dcnode); 2819832Samw@Sun.COM } 2829832Samw@Sun.COM 2839832Samw@Sun.COM smb_dcache_unlock(); 2849832Samw@Sun.COM return (found); 2855331Samw } 2865331Samw 2875331Samw /* 2889832Samw@Sun.COM * Returns primary domain information plus the name of 2899832Samw@Sun.COM * the selected domain controller. 2905331Samw */ 2919832Samw@Sun.COM boolean_t 29210717Samw@Sun.COM smb_domain_getinfo(smb_domainex_t *dxi) 2935331Samw { 2949832Samw@Sun.COM boolean_t success; 2958670SJose.Borrego@Sun.COM 29610717Samw@Sun.COM success = smb_domain_lookup_type(SMB_DOMAIN_PRIMARY, &dxi->d_primary); 2979832Samw@Sun.COM if (success) 29810717Samw@Sun.COM smb_dcache_getdc(dxi->d_dc, sizeof (dxi->d_dc)); 2995331Samw 3009832Samw@Sun.COM return (success); 3015331Samw } 3025331Samw 3035331Samw /* 3049832Samw@Sun.COM * Transfer the cache to updating state. 3059832Samw@Sun.COM * In this state any request for reading the cache would 3069832Samw@Sun.COM * be blocked until the update is finished. 3075331Samw */ 30810717Samw@Sun.COM uint32_t 30910717Samw@Sun.COM smb_domain_start_update(void) 3105331Samw { 31110717Samw@Sun.COM return (smb_dcache_updating()); 3125331Samw } 3135331Samw 3149832Samw@Sun.COM /* 3159832Samw@Sun.COM * Transfer the cache from updating to ready state. 3169832Samw@Sun.COM */ 3179832Samw@Sun.COM void 31810717Samw@Sun.COM smb_domain_end_update(void) 3199832Samw@Sun.COM { 3209832Samw@Sun.COM smb_dcache_ready(); 3219832Samw@Sun.COM } 3225331Samw 3235331Samw /* 3249832Samw@Sun.COM * Updates the cache with given information for the primary 3259832Samw@Sun.COM * domain, possible trusted domains and the selected domain 3269832Samw@Sun.COM * controller. 3275331Samw * 3289832Samw@Sun.COM * Before adding the new entries existing entries of type 3299832Samw@Sun.COM * primary and trusted will be removed from cache. 3305331Samw */ 3319832Samw@Sun.COM void 33210717Samw@Sun.COM smb_domain_update(smb_domainex_t *dxi) 3335331Samw { 33410717Samw@Sun.COM smb_domain_t *dcnode; 3359832Samw@Sun.COM int i; 3365331Samw 3379832Samw@Sun.COM if (smb_dcache_lock(SMB_DCACHE_WRLOCK) != SMB_DOMAIN_SUCCESS) 3389832Samw@Sun.COM return; 3395331Samw 3409832Samw@Sun.COM dcnode = list_head(&smb_dcache.dc_cache); 3419832Samw@Sun.COM while (dcnode) { 34210717Samw@Sun.COM if ((dcnode->di_type == SMB_DOMAIN_PRIMARY) || 34310717Samw@Sun.COM (dcnode->di_type == SMB_DOMAIN_TRUSTED)) { 3449832Samw@Sun.COM smb_dcache_remove(dcnode); 3459832Samw@Sun.COM dcnode = list_head(&smb_dcache.dc_cache); 3469832Samw@Sun.COM } else { 3479832Samw@Sun.COM dcnode = list_next(&smb_dcache.dc_cache, dcnode); 3489832Samw@Sun.COM } 3499832Samw@Sun.COM } 3505331Samw 35110717Samw@Sun.COM if (smb_dcache_add(&dxi->d_primary) == SMB_DOMAIN_SUCCESS) { 35210717Samw@Sun.COM for (i = 0; i < dxi->d_trusted.td_num; i++) 35310717Samw@Sun.COM (void) smb_dcache_add(&dxi->d_trusted.td_domains[i]); 3549832Samw@Sun.COM 35510717Samw@Sun.COM smb_dcache_setdc(dxi->d_dc); 3565331Samw } 3579832Samw@Sun.COM 3589832Samw@Sun.COM smb_dcache_unlock(); 3595331Samw } 3608474SJose.Borrego@Sun.COM 3618474SJose.Borrego@Sun.COM /* 3628474SJose.Borrego@Sun.COM * Write the list of domains to /var/run/smb/domains. 3638474SJose.Borrego@Sun.COM */ 3648474SJose.Borrego@Sun.COM void 36510717Samw@Sun.COM smb_domain_save(void) 3668474SJose.Borrego@Sun.COM { 3678474SJose.Borrego@Sun.COM char fname[MAXPATHLEN]; 3688474SJose.Borrego@Sun.COM char tag; 36910717Samw@Sun.COM smb_domain_t *domain; 3708474SJose.Borrego@Sun.COM FILE *fp; 3718474SJose.Borrego@Sun.COM struct passwd *pwd; 3728474SJose.Borrego@Sun.COM struct group *grp; 3738474SJose.Borrego@Sun.COM uid_t uid; 3748474SJose.Borrego@Sun.COM gid_t gid; 3758474SJose.Borrego@Sun.COM 3768474SJose.Borrego@Sun.COM (void) snprintf(fname, MAXPATHLEN, "%s/%s", 3778474SJose.Borrego@Sun.COM SMB_VARRUN_DIR, SMB_DOMAINS_FILE); 3788474SJose.Borrego@Sun.COM 3798474SJose.Borrego@Sun.COM if ((fp = fopen(fname, "w")) == NULL) 3808474SJose.Borrego@Sun.COM return; 3818474SJose.Borrego@Sun.COM 3828474SJose.Borrego@Sun.COM pwd = getpwnam("root"); 3838474SJose.Borrego@Sun.COM grp = getgrnam("sys"); 3848474SJose.Borrego@Sun.COM uid = (pwd == NULL) ? 0 : pwd->pw_uid; 3858474SJose.Borrego@Sun.COM gid = (grp == NULL) ? 3 : grp->gr_gid; 3868474SJose.Borrego@Sun.COM 3878474SJose.Borrego@Sun.COM (void) lockf(fileno(fp), F_LOCK, 0); 3888474SJose.Borrego@Sun.COM (void) fchmod(fileno(fp), 0600); 3898474SJose.Borrego@Sun.COM (void) fchown(fileno(fp), uid, gid); 3908474SJose.Borrego@Sun.COM 3919832Samw@Sun.COM if (smb_dcache_lock(SMB_DCACHE_RDLOCK) != SMB_DOMAIN_SUCCESS) 3929832Samw@Sun.COM return; 3938474SJose.Borrego@Sun.COM 3949832Samw@Sun.COM domain = list_head(&smb_dcache.dc_cache); 3958474SJose.Borrego@Sun.COM while (domain) { 3969832Samw@Sun.COM switch (domain->di_type) { 39710717Samw@Sun.COM case SMB_DOMAIN_PRIMARY: 3988474SJose.Borrego@Sun.COM tag = '*'; 3998474SJose.Borrego@Sun.COM break; 4008474SJose.Borrego@Sun.COM 40110717Samw@Sun.COM case SMB_DOMAIN_TRUSTED: 40210717Samw@Sun.COM case SMB_DOMAIN_UNTRUSTED: 4038474SJose.Borrego@Sun.COM tag = '-'; 4048474SJose.Borrego@Sun.COM break; 4058474SJose.Borrego@Sun.COM 40610717Samw@Sun.COM case SMB_DOMAIN_LOCAL: 4078474SJose.Borrego@Sun.COM tag = '.'; 4088474SJose.Borrego@Sun.COM break; 4098474SJose.Borrego@Sun.COM default: 4109832Samw@Sun.COM domain = list_next(&smb_dcache.dc_cache, domain); 4118474SJose.Borrego@Sun.COM continue; 4128474SJose.Borrego@Sun.COM } 4138474SJose.Borrego@Sun.COM 4148474SJose.Borrego@Sun.COM (void) fprintf(fp, "[%c] [%s] [%s]\n", 4159832Samw@Sun.COM tag, domain->di_nbname, domain->di_sid); 4168474SJose.Borrego@Sun.COM 4179832Samw@Sun.COM domain = list_next(&smb_dcache.dc_cache, domain); 4188474SJose.Borrego@Sun.COM } 4198474SJose.Borrego@Sun.COM 4209832Samw@Sun.COM smb_dcache_unlock(); 4218474SJose.Borrego@Sun.COM (void) lockf(fileno(fp), F_ULOCK, 0); 4228474SJose.Borrego@Sun.COM (void) fclose(fp); 4238474SJose.Borrego@Sun.COM } 4248474SJose.Borrego@Sun.COM 4258474SJose.Borrego@Sun.COM /* 4268474SJose.Borrego@Sun.COM * List the domains in /var/run/smb/domains. 4278474SJose.Borrego@Sun.COM */ 4288474SJose.Borrego@Sun.COM void 42910717Samw@Sun.COM smb_domain_show(void) 4308474SJose.Borrego@Sun.COM { 4318474SJose.Borrego@Sun.COM char buf[MAXPATHLEN]; 4328474SJose.Borrego@Sun.COM char *p; 4338474SJose.Borrego@Sun.COM FILE *fp; 4348474SJose.Borrego@Sun.COM 4358474SJose.Borrego@Sun.COM (void) snprintf(buf, MAXPATHLEN, "%s/%s", 4368474SJose.Borrego@Sun.COM SMB_VARRUN_DIR, SMB_DOMAINS_FILE); 4378474SJose.Borrego@Sun.COM 4388474SJose.Borrego@Sun.COM if ((fp = fopen(buf, "r")) != NULL) { 4398474SJose.Borrego@Sun.COM (void) lockf(fileno(fp), F_LOCK, 0); 4408474SJose.Borrego@Sun.COM 4418474SJose.Borrego@Sun.COM while (fgets(buf, MAXPATHLEN, fp) != NULL) { 4428474SJose.Borrego@Sun.COM if ((p = strchr(buf, '\n')) != NULL) 4438474SJose.Borrego@Sun.COM *p = '\0'; 4448474SJose.Borrego@Sun.COM (void) printf("%s\n", buf); 4458474SJose.Borrego@Sun.COM } 4468474SJose.Borrego@Sun.COM 4478474SJose.Borrego@Sun.COM (void) lockf(fileno(fp), F_ULOCK, 0); 4488474SJose.Borrego@Sun.COM (void) fclose(fp); 4498474SJose.Borrego@Sun.COM } 4508474SJose.Borrego@Sun.COM } 4518474SJose.Borrego@Sun.COM 4529832Samw@Sun.COM void 45310717Samw@Sun.COM smb_domain_set_basic_info(char *sid, char *nb_domain, char *fq_domain, 45410717Samw@Sun.COM smb_domain_t *di) 4559832Samw@Sun.COM { 4569832Samw@Sun.COM if (sid == NULL || nb_domain == NULL || fq_domain == NULL || 4579832Samw@Sun.COM di == NULL) 4589832Samw@Sun.COM return; 4599832Samw@Sun.COM 4609832Samw@Sun.COM (void) strlcpy(di->di_sid, sid, SMB_SID_STRSZ); 4619832Samw@Sun.COM (void) strlcpy(di->di_nbname, nb_domain, NETBIOS_NAME_SZ); 462*10966SJordan.Brown@Sun.COM (void) smb_strupr(di->di_nbname); 4639832Samw@Sun.COM (void) strlcpy(di->di_fqname, fq_domain, MAXHOSTNAMELEN); 4649832Samw@Sun.COM di->di_binsid = NULL; 4659832Samw@Sun.COM } 4669832Samw@Sun.COM 4679832Samw@Sun.COM void 46810717Samw@Sun.COM smb_domain_set_dns_info(char *sid, char *nb_domain, char *fq_domain, 46910717Samw@Sun.COM char *forest, char *guid, smb_domain_t *di) 4709832Samw@Sun.COM { 4719832Samw@Sun.COM if (di == NULL || forest == NULL || guid == NULL) 4729832Samw@Sun.COM return; 4739832Samw@Sun.COM 47410717Samw@Sun.COM smb_domain_set_basic_info(sid, nb_domain, fq_domain, di); 4759832Samw@Sun.COM (void) strlcpy(di->di_u.di_dns.ddi_forest, forest, MAXHOSTNAMELEN); 4769832Samw@Sun.COM (void) strlcpy(di->di_u.di_dns.ddi_guid, guid, 4779832Samw@Sun.COM UUID_PRINTABLE_STRING_LENGTH); 4789832Samw@Sun.COM } 4799832Samw@Sun.COM 4809832Samw@Sun.COM void 48110717Samw@Sun.COM smb_domain_set_trust_info(char *sid, char *nb_domain, char *fq_domain, 4829832Samw@Sun.COM uint32_t trust_dir, uint32_t trust_type, uint32_t trust_attrs, 48310717Samw@Sun.COM smb_domain_t *di) 4849832Samw@Sun.COM { 4859832Samw@Sun.COM smb_domain_trust_t *ti; 4869832Samw@Sun.COM 4879832Samw@Sun.COM if (di == NULL) 4889832Samw@Sun.COM return; 4899832Samw@Sun.COM 49010717Samw@Sun.COM di->di_type = SMB_DOMAIN_TRUSTED; 4919832Samw@Sun.COM ti = &di->di_u.di_trust; 49210717Samw@Sun.COM smb_domain_set_basic_info(sid, nb_domain, fq_domain, di); 4939832Samw@Sun.COM ti->dti_trust_direction = trust_dir; 4949832Samw@Sun.COM ti->dti_trust_type = trust_type; 4959832Samw@Sun.COM ti->dti_trust_attrs = trust_attrs; 4969832Samw@Sun.COM } 4979832Samw@Sun.COM 4988474SJose.Borrego@Sun.COM /* 4998474SJose.Borrego@Sun.COM * Remove the /var/run/smb/domains file. 5008474SJose.Borrego@Sun.COM */ 5019832Samw@Sun.COM static void 50210717Samw@Sun.COM smb_domain_unlink(void) 5038474SJose.Borrego@Sun.COM { 5048474SJose.Borrego@Sun.COM char fname[MAXPATHLEN]; 5058474SJose.Borrego@Sun.COM 5068474SJose.Borrego@Sun.COM (void) snprintf(fname, MAXPATHLEN, "%s/%s", 5078474SJose.Borrego@Sun.COM SMB_VARRUN_DIR, SMB_DOMAINS_FILE); 5088474SJose.Borrego@Sun.COM (void) unlink(fname); 5098474SJose.Borrego@Sun.COM } 5109832Samw@Sun.COM 5119832Samw@Sun.COM /* 5129832Samw@Sun.COM * Add an entry for the local domain to the domain cache 5139832Samw@Sun.COM */ 5149832Samw@Sun.COM static uint32_t 51510717Samw@Sun.COM smb_domain_add_local(void) 5169832Samw@Sun.COM { 5179832Samw@Sun.COM char *lsidstr; 5189832Samw@Sun.COM char hostname[NETBIOS_NAME_SZ]; 5199832Samw@Sun.COM char fq_name[MAXHOSTNAMELEN]; 52010717Samw@Sun.COM smb_domain_t di; 5219832Samw@Sun.COM 5229832Samw@Sun.COM if ((lsidstr = smb_config_get_localsid()) == NULL) 5239832Samw@Sun.COM return (SMB_DOMAIN_NOMACHINE_SID); 5249832Samw@Sun.COM 5259832Samw@Sun.COM if (smb_getnetbiosname(hostname, NETBIOS_NAME_SZ) != 0) { 5269832Samw@Sun.COM free(lsidstr); 5279832Samw@Sun.COM return (SMB_DOMAIN_NOMACHINE_SID); 5289832Samw@Sun.COM } 5299832Samw@Sun.COM 5309832Samw@Sun.COM *fq_name = '\0'; 5319832Samw@Sun.COM (void) smb_getfqhostname(fq_name, MAXHOSTNAMELEN); 53210717Samw@Sun.COM smb_domain_set_basic_info(lsidstr, hostname, fq_name, &di); 53310717Samw@Sun.COM (void) smb_domain_add(SMB_DOMAIN_LOCAL, &di); 5349832Samw@Sun.COM 5359832Samw@Sun.COM free(lsidstr); 5369832Samw@Sun.COM return (SMB_DOMAIN_SUCCESS); 5379832Samw@Sun.COM } 5389832Samw@Sun.COM 5399832Samw@Sun.COM /* 5409832Samw@Sun.COM * Add an entry for the primary domain to the domain cache 5419832Samw@Sun.COM */ 5429832Samw@Sun.COM static uint32_t 54310717Samw@Sun.COM smb_domain_add_primary(uint32_t secmode) 5449832Samw@Sun.COM { 5459832Samw@Sun.COM char sidstr[SMB_SID_STRSZ]; 5469832Samw@Sun.COM char fq_name[MAXHOSTNAMELEN]; 5479832Samw@Sun.COM char nb_name[NETBIOS_NAME_SZ]; 54810717Samw@Sun.COM smb_domain_t di; 5499832Samw@Sun.COM int rc; 5509832Samw@Sun.COM 5519832Samw@Sun.COM if (secmode != SMB_SECMODE_DOMAIN) 5529832Samw@Sun.COM return (SMB_DOMAIN_SUCCESS); 5539832Samw@Sun.COM 5549832Samw@Sun.COM rc = smb_config_getstr(SMB_CI_DOMAIN_SID, sidstr, sizeof (sidstr)); 5559832Samw@Sun.COM if (rc != SMBD_SMF_OK) 5569832Samw@Sun.COM return (SMB_DOMAIN_NODOMAIN_SID); 5579832Samw@Sun.COM 5589832Samw@Sun.COM rc = smb_config_getstr(SMB_CI_DOMAIN_NAME, nb_name, NETBIOS_NAME_SZ); 5599832Samw@Sun.COM if ((rc != SMBD_SMF_OK) || (*nb_name == '\0')) 5609832Samw@Sun.COM return (SMB_DOMAIN_NODOMAIN_NAME); 5619832Samw@Sun.COM 5629832Samw@Sun.COM (void) smb_getfqdomainname(fq_name, MAXHOSTNAMELEN); 56310717Samw@Sun.COM smb_domain_set_basic_info(sidstr, nb_name, fq_name, &di); 56410717Samw@Sun.COM (void) smb_domain_add(SMB_DOMAIN_PRIMARY, &di); 5659832Samw@Sun.COM return (SMB_DOMAIN_SUCCESS); 5669832Samw@Sun.COM } 5679832Samw@Sun.COM 5689832Samw@Sun.COM /* 5699832Samw@Sun.COM * Initialize the domain cache. 5709832Samw@Sun.COM * This function does not populate the cache. 5719832Samw@Sun.COM */ 5729832Samw@Sun.COM static void 5739832Samw@Sun.COM smb_dcache_create(void) 5749832Samw@Sun.COM { 5759832Samw@Sun.COM (void) mutex_lock(&smb_dcache.dc_mtx); 5769832Samw@Sun.COM if (smb_dcache.dc_state != SMB_DCACHE_STATE_NONE) { 5779832Samw@Sun.COM (void) mutex_unlock(&smb_dcache.dc_mtx); 5789832Samw@Sun.COM return; 5799832Samw@Sun.COM } 5809832Samw@Sun.COM 58110717Samw@Sun.COM list_create(&smb_dcache.dc_cache, sizeof (smb_domain_t), 58210717Samw@Sun.COM offsetof(smb_domain_t, di_lnd)); 5839832Samw@Sun.COM 5849832Samw@Sun.COM smb_dcache.dc_nops = 0; 5859832Samw@Sun.COM *smb_dcache.dc_server = '\0'; 5869832Samw@Sun.COM smb_dcache.dc_state = SMB_DCACHE_STATE_READY; 5879832Samw@Sun.COM (void) mutex_unlock(&smb_dcache.dc_mtx); 5889832Samw@Sun.COM } 5899832Samw@Sun.COM 5909832Samw@Sun.COM /* 5919832Samw@Sun.COM * Removes and frees all the cache entries 5929832Samw@Sun.COM */ 5939832Samw@Sun.COM static void 5949832Samw@Sun.COM smb_dcache_flush(void) 5959832Samw@Sun.COM { 59610717Samw@Sun.COM smb_domain_t *di; 5979832Samw@Sun.COM 5989832Samw@Sun.COM (void) rw_wrlock(&smb_dcache.dc_cache_lck); 5999832Samw@Sun.COM while ((di = list_head(&smb_dcache.dc_cache)) != NULL) 6009832Samw@Sun.COM smb_dcache_remove(di); 6019832Samw@Sun.COM (void) rw_unlock(&smb_dcache.dc_cache_lck); 6029832Samw@Sun.COM } 6039832Samw@Sun.COM 6049832Samw@Sun.COM /* 6059832Samw@Sun.COM * Destroys the cache. 6069832Samw@Sun.COM */ 6079832Samw@Sun.COM static void 6089832Samw@Sun.COM smb_dcache_destroy(void) 6099832Samw@Sun.COM { 6109832Samw@Sun.COM (void) mutex_lock(&smb_dcache.dc_mtx); 6119832Samw@Sun.COM if ((smb_dcache.dc_state == SMB_DCACHE_STATE_READY) || 6129832Samw@Sun.COM (smb_dcache.dc_state == SMB_DCACHE_STATE_UPDATING)) { 6139832Samw@Sun.COM smb_dcache.dc_state = SMB_DCACHE_STATE_DESTROYING; 6149832Samw@Sun.COM while (smb_dcache.dc_nops > 0) 6159832Samw@Sun.COM (void) cond_wait(&smb_dcache.dc_cv, 6169832Samw@Sun.COM &smb_dcache.dc_mtx); 6179832Samw@Sun.COM 6189832Samw@Sun.COM smb_dcache_flush(); 6199832Samw@Sun.COM list_destroy(&smb_dcache.dc_cache); 6209832Samw@Sun.COM 6219832Samw@Sun.COM smb_dcache.dc_state = SMB_DCACHE_STATE_NONE; 6229832Samw@Sun.COM } 6239832Samw@Sun.COM (void) mutex_unlock(&smb_dcache.dc_mtx); 6249832Samw@Sun.COM } 6259832Samw@Sun.COM 6269832Samw@Sun.COM /* 6279832Samw@Sun.COM * Lock the cache with the specified mode. 6289832Samw@Sun.COM * If the cache is in updating state and a read lock is 6299832Samw@Sun.COM * requested, the lock won't be granted until either the 6309832Samw@Sun.COM * update is finished or SMB_DCACHE_UPDATE_WAIT has passed. 6319832Samw@Sun.COM * 6329832Samw@Sun.COM * Whenever a lock is granted, the number of inflight cache 6339832Samw@Sun.COM * operations is incremented. 6349832Samw@Sun.COM */ 6359832Samw@Sun.COM static uint32_t 6369832Samw@Sun.COM smb_dcache_lock(int mode) 6379832Samw@Sun.COM { 6389832Samw@Sun.COM (void) mutex_lock(&smb_dcache.dc_mtx); 6399832Samw@Sun.COM switch (smb_dcache.dc_state) { 6409832Samw@Sun.COM case SMB_DCACHE_STATE_NONE: 6419832Samw@Sun.COM case SMB_DCACHE_STATE_DESTROYING: 6429832Samw@Sun.COM (void) mutex_unlock(&smb_dcache.dc_mtx); 6439832Samw@Sun.COM return (SMB_DOMAIN_INTERNAL_ERR); 6449832Samw@Sun.COM 6459832Samw@Sun.COM case SMB_DCACHE_STATE_UPDATING: 6469832Samw@Sun.COM if (mode == SMB_DCACHE_RDLOCK) { 6479832Samw@Sun.COM /* 6489832Samw@Sun.COM * Read operations should wait until the update 6499832Samw@Sun.COM * is completed. 6509832Samw@Sun.COM */ 6519832Samw@Sun.COM if (!smb_dcache_wait()) { 6529832Samw@Sun.COM (void) mutex_unlock(&smb_dcache.dc_mtx); 6539832Samw@Sun.COM return (SMB_DOMAIN_INTERNAL_ERR); 6549832Samw@Sun.COM } 6559832Samw@Sun.COM } 6569832Samw@Sun.COM 6579832Samw@Sun.COM default: 6589832Samw@Sun.COM smb_dcache.dc_nops++; 6599832Samw@Sun.COM break; 6609832Samw@Sun.COM } 6619832Samw@Sun.COM (void) mutex_unlock(&smb_dcache.dc_mtx); 6629832Samw@Sun.COM 6639832Samw@Sun.COM /* 6649832Samw@Sun.COM * Lock has to be taken outside the mutex otherwise 6659832Samw@Sun.COM * there could be a deadlock 6669832Samw@Sun.COM */ 6679832Samw@Sun.COM if (mode == SMB_DCACHE_RDLOCK) 6689832Samw@Sun.COM (void) rw_rdlock(&smb_dcache.dc_cache_lck); 6699832Samw@Sun.COM else 6709832Samw@Sun.COM (void) rw_wrlock(&smb_dcache.dc_cache_lck); 6719832Samw@Sun.COM 6729832Samw@Sun.COM return (SMB_DOMAIN_SUCCESS); 6739832Samw@Sun.COM } 6749832Samw@Sun.COM 6759832Samw@Sun.COM /* 6769832Samw@Sun.COM * Decrement the number of inflight operations and then unlock. 6779832Samw@Sun.COM */ 6789832Samw@Sun.COM static void 6799832Samw@Sun.COM smb_dcache_unlock(void) 6809832Samw@Sun.COM { 6819832Samw@Sun.COM (void) mutex_lock(&smb_dcache.dc_mtx); 6829832Samw@Sun.COM assert(smb_dcache.dc_nops > 0); 6839832Samw@Sun.COM smb_dcache.dc_nops--; 6849832Samw@Sun.COM (void) cond_broadcast(&smb_dcache.dc_cv); 6859832Samw@Sun.COM (void) mutex_unlock(&smb_dcache.dc_mtx); 6869832Samw@Sun.COM 6879832Samw@Sun.COM (void) rw_unlock(&smb_dcache.dc_cache_lck); 6889832Samw@Sun.COM } 6899832Samw@Sun.COM 6909832Samw@Sun.COM static uint32_t 69110717Samw@Sun.COM smb_dcache_add(smb_domain_t *di) 6929832Samw@Sun.COM { 69310717Samw@Sun.COM smb_domain_t *dcnode; 6949832Samw@Sun.COM 69510717Samw@Sun.COM if ((dcnode = malloc(sizeof (smb_domain_t))) == NULL) 6969832Samw@Sun.COM return (SMB_DOMAIN_NO_MEMORY); 6979832Samw@Sun.COM 6989832Samw@Sun.COM *dcnode = *di; 6999832Samw@Sun.COM dcnode->di_binsid = smb_sid_fromstr(dcnode->di_sid); 7009832Samw@Sun.COM if (dcnode->di_binsid == NULL) { 7019832Samw@Sun.COM free(dcnode); 7029832Samw@Sun.COM return (SMB_DOMAIN_NO_MEMORY); 7039832Samw@Sun.COM } 7049832Samw@Sun.COM 7059832Samw@Sun.COM list_insert_tail(&smb_dcache.dc_cache, dcnode); 7069832Samw@Sun.COM return (SMB_DOMAIN_SUCCESS); 7079832Samw@Sun.COM } 7089832Samw@Sun.COM 7099832Samw@Sun.COM static void 71010717Samw@Sun.COM smb_dcache_remove(smb_domain_t *di) 7119832Samw@Sun.COM { 7129832Samw@Sun.COM list_remove(&smb_dcache.dc_cache, di); 7139832Samw@Sun.COM smb_sid_free(di->di_binsid); 7149832Samw@Sun.COM free(di); 7159832Samw@Sun.COM } 7169832Samw@Sun.COM 7179832Samw@Sun.COM static void 7189832Samw@Sun.COM smb_dcache_setdc(char *dc) 7199832Samw@Sun.COM { 7209832Samw@Sun.COM (void) mutex_lock(&smb_dcache.dc_mtx); 7219832Samw@Sun.COM (void) strlcpy(smb_dcache.dc_server, dc, sizeof (smb_dcache.dc_server)); 7229832Samw@Sun.COM (void) mutex_unlock(&smb_dcache.dc_mtx); 7239832Samw@Sun.COM } 7249832Samw@Sun.COM 7259832Samw@Sun.COM static void 7269832Samw@Sun.COM smb_dcache_getdc(char *buf, size_t buflen) 7279832Samw@Sun.COM { 7289832Samw@Sun.COM (void) mutex_lock(&smb_dcache.dc_mtx); 7299832Samw@Sun.COM (void) strlcpy(buf, smb_dcache.dc_server, buflen); 7309832Samw@Sun.COM (void) mutex_unlock(&smb_dcache.dc_mtx); 7319832Samw@Sun.COM } 7329832Samw@Sun.COM 73310717Samw@Sun.COM /* 73410717Samw@Sun.COM * Waits for SMB_DCACHE_UPDATE_WAIT seconds if cache is in 73510717Samw@Sun.COM * UPDATING state. Upon wake up returns true if cache is 73610717Samw@Sun.COM * ready to be used, otherwise it returns false. 73710717Samw@Sun.COM */ 7389832Samw@Sun.COM static boolean_t 7399832Samw@Sun.COM smb_dcache_wait(void) 7409832Samw@Sun.COM { 7419832Samw@Sun.COM timestruc_t to; 7429832Samw@Sun.COM int err; 7439832Samw@Sun.COM 7449832Samw@Sun.COM to.tv_sec = SMB_DCACHE_UPDATE_WAIT; 7459832Samw@Sun.COM to.tv_nsec = 0; 7469832Samw@Sun.COM while (smb_dcache.dc_state == SMB_DCACHE_STATE_UPDATING) { 7479832Samw@Sun.COM err = cond_reltimedwait(&smb_dcache.dc_cv, 7489832Samw@Sun.COM &smb_dcache.dc_mtx, &to); 7499832Samw@Sun.COM if (err == ETIME) 7509832Samw@Sun.COM break; 7519832Samw@Sun.COM } 7529832Samw@Sun.COM 7539832Samw@Sun.COM return (smb_dcache.dc_state == SMB_DCACHE_STATE_READY); 7549832Samw@Sun.COM } 7559832Samw@Sun.COM 75610717Samw@Sun.COM /* 75710717Samw@Sun.COM * Transfers the cache into UPDATING state, this will ensure 75810717Samw@Sun.COM * any read access to the cache will be stalled until the 75910717Samw@Sun.COM * update is finished. This is to avoid providing incomplete, 76010717Samw@Sun.COM * inconsistent or stale information. 76110717Samw@Sun.COM * 76210717Samw@Sun.COM * If another thread is already updating the cache, other 76310717Samw@Sun.COM * callers will wait until cache is no longer in UPDATING 76410717Samw@Sun.COM * state. The return code is decided based on the new 76510717Samw@Sun.COM * state of the cache. 76610717Samw@Sun.COM */ 76710717Samw@Sun.COM static uint32_t 7689832Samw@Sun.COM smb_dcache_updating(void) 7699832Samw@Sun.COM { 77010717Samw@Sun.COM uint32_t rc; 77110717Samw@Sun.COM 7729832Samw@Sun.COM (void) mutex_lock(&smb_dcache.dc_mtx); 77310717Samw@Sun.COM switch (smb_dcache.dc_state) { 77410717Samw@Sun.COM case SMB_DCACHE_STATE_READY: 7759832Samw@Sun.COM smb_dcache.dc_state = SMB_DCACHE_STATE_UPDATING; 77610717Samw@Sun.COM rc = SMB_DOMAIN_SUCCESS; 77710717Samw@Sun.COM break; 77810717Samw@Sun.COM 77910717Samw@Sun.COM case SMB_DCACHE_STATE_UPDATING: 78010717Samw@Sun.COM while (smb_dcache.dc_state == SMB_DCACHE_STATE_UPDATING) 78110717Samw@Sun.COM (void) cond_wait(&smb_dcache.dc_cv, 78210717Samw@Sun.COM &smb_dcache.dc_mtx); 78310717Samw@Sun.COM 78410717Samw@Sun.COM if (smb_dcache.dc_state == SMB_DCACHE_STATE_READY) { 78510717Samw@Sun.COM smb_dcache.dc_state = SMB_DCACHE_STATE_UPDATING; 78610717Samw@Sun.COM rc = SMB_DOMAIN_SUCCESS; 78710717Samw@Sun.COM } else { 78810717Samw@Sun.COM rc = SMB_DOMAIN_NO_CACHE; 78910717Samw@Sun.COM } 79010717Samw@Sun.COM break; 79110717Samw@Sun.COM 79210717Samw@Sun.COM case SMB_DCACHE_STATE_NONE: 79310717Samw@Sun.COM case SMB_DCACHE_STATE_DESTROYING: 79410717Samw@Sun.COM rc = SMB_DOMAIN_NO_CACHE; 79510717Samw@Sun.COM break; 79610717Samw@Sun.COM 79710717Samw@Sun.COM default: 79810717Samw@Sun.COM break; 79910717Samw@Sun.COM } 80010717Samw@Sun.COM 8019832Samw@Sun.COM (void) mutex_unlock(&smb_dcache.dc_mtx); 80210717Samw@Sun.COM return (rc); 8039832Samw@Sun.COM } 8049832Samw@Sun.COM 80510717Samw@Sun.COM /* 80610717Samw@Sun.COM * Transfers the cache from UPDATING to READY state. 80710717Samw@Sun.COM * 80810717Samw@Sun.COM * Nothing will happen if the cache is no longer available 80910717Samw@Sun.COM * or it is being destroyed. 81010717Samw@Sun.COM */ 8119832Samw@Sun.COM static void 8129832Samw@Sun.COM smb_dcache_ready(void) 8139832Samw@Sun.COM { 8149832Samw@Sun.COM (void) mutex_lock(&smb_dcache.dc_mtx); 81510717Samw@Sun.COM switch (smb_dcache.dc_state) { 81610717Samw@Sun.COM case SMB_DCACHE_STATE_UPDATING: 8179832Samw@Sun.COM smb_dcache.dc_state = SMB_DCACHE_STATE_READY; 81810717Samw@Sun.COM (void) cond_broadcast(&smb_dcache.dc_cv); 81910717Samw@Sun.COM break; 82010717Samw@Sun.COM 82110717Samw@Sun.COM case SMB_DCACHE_STATE_NONE: 82210717Samw@Sun.COM case SMB_DCACHE_STATE_DESTROYING: 82310717Samw@Sun.COM break; 82410717Samw@Sun.COM 82510717Samw@Sun.COM default: 8269832Samw@Sun.COM assert(0); 82710717Samw@Sun.COM } 8289832Samw@Sun.COM (void) mutex_unlock(&smb_dcache.dc_mtx); 8299832Samw@Sun.COM } 830