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
smb_domain_init(uint32_t secmode)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
smb_domain_fini(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
smb_domain_add(smb_domain_type_t type,smb_domain_t * di)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
smb_domain_lookup_name(char * name,smb_domain_t * di)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
smb_domain_lookup_sid(smb_sid_t * sid,smb_domain_t * di)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
smb_domain_lookup_type(smb_domain_type_t type,smb_domain_t * di)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
smb_domain_getinfo(smb_domainex_t * dxi)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
smb_domain_start_update(void)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
smb_domain_end_update(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
smb_domain_update(smb_domainex_t * dxi)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
smb_domain_save(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
smb_domain_show(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
smb_domain_set_basic_info(char * sid,char * nb_domain,char * fq_domain,smb_domain_t * di)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
smb_domain_set_dns_info(char * sid,char * nb_domain,char * fq_domain,char * forest,char * guid,smb_domain_t * di)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
smb_domain_set_trust_info(char * sid,char * nb_domain,char * fq_domain,uint32_t trust_dir,uint32_t trust_type,uint32_t trust_attrs,smb_domain_t * di)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
smb_domain_unlink(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
smb_domain_add_local(void)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
smb_domain_add_primary(uint32_t secmode)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
smb_dcache_create(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
smb_dcache_flush(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
smb_dcache_destroy(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
smb_dcache_lock(int mode)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
smb_dcache_unlock(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
smb_dcache_add(smb_domain_t * di)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
smb_dcache_remove(smb_domain_t * di)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
smb_dcache_setdc(char * dc)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
smb_dcache_getdc(char * buf,size_t buflen)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
smb_dcache_wait(void)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
smb_dcache_updating(void)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
smb_dcache_ready(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