xref: /titanic_50/usr/src/lib/smbsrv/libmlsvc/common/smb_share.c (revision a851ffc82d02870137b4065c395d79bec1172c32)
13db3f65cSamw /*
23db3f65cSamw  * CDDL HEADER START
33db3f65cSamw  *
43db3f65cSamw  * The contents of this file are subject to the terms of the
53db3f65cSamw  * Common Development and Distribution License (the "License").
63db3f65cSamw  * You may not use this file except in compliance with the License.
73db3f65cSamw  *
83db3f65cSamw  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
93db3f65cSamw  * or http://www.opensolaris.org/os/licensing.
103db3f65cSamw  * See the License for the specific language governing permissions
113db3f65cSamw  * and limitations under the License.
123db3f65cSamw  *
133db3f65cSamw  * When distributing Covered Code, include this CDDL HEADER in each
143db3f65cSamw  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
153db3f65cSamw  * If applicable, add the following below this CDDL HEADER, with the
163db3f65cSamw  * fields enclosed by brackets "[]" replaced with your own identifying
173db3f65cSamw  * information: Portions Copyright [yyyy] [name of copyright owner]
183db3f65cSamw  *
193db3f65cSamw  * CDDL HEADER END
209b241b4eSYuri Pankov  *
21c5866007SKeyur Desai  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
22*a851ffc8SGordon Ross  * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
233db3f65cSamw  */
243db3f65cSamw 
253db3f65cSamw /*
26b89a8333Snatalie li - Sun Microsystems - Irvine United States  * SMB/CIFS share cache implementation.
273db3f65cSamw  */
283db3f65cSamw 
293db3f65cSamw #include <errno.h>
303db3f65cSamw #include <synch.h>
313db3f65cSamw #include <stdlib.h>
323db3f65cSamw #include <strings.h>
333db3f65cSamw #include <syslog.h>
343db3f65cSamw #include <thread.h>
353db3f65cSamw #include <pthread.h>
36c8ec8eeaSjose borrego #include <assert.h>
37b89a8333Snatalie li - Sun Microsystems - Irvine United States #include <libshare.h>
38743a77edSAlan Wright #include <libzfs.h>
3929bd2886SAlan Wright #include <priv_utils.h>
4029bd2886SAlan Wright #include <sys/types.h>
4129bd2886SAlan Wright #include <sys/wait.h>
4229bd2886SAlan Wright #include <unistd.h>
4329bd2886SAlan Wright #include <pwd.h>
4429bd2886SAlan Wright #include <signal.h>
45c5866007SKeyur Desai #include <dirent.h>
46cb174861Sjoyce mcintosh #include <dlfcn.h>
473db3f65cSamw 
483db3f65cSamw #include <smbsrv/libsmb.h>
493db3f65cSamw #include <smbsrv/libsmbns.h>
508d96b23eSAlan Wright #include <smbsrv/libmlsvc.h>
513db3f65cSamw #include <smbsrv/smb_share.h>
52bbf6f00cSJordan Brown #include <smbsrv/smb.h>
53e3f2c991SKeyur Desai #include <mlsvc.h>
549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <dfs.h>
553db3f65cSamw 
56b89a8333Snatalie li - Sun Microsystems - Irvine United States #define	SMB_SHR_ERROR_THRESHOLD		3
578d7e4166Sjose borrego #define	SMB_SHR_CSC_BUFSZ		64
588d7e4166Sjose borrego 
59c5866007SKeyur Desai typedef struct smb_transient {
60c5866007SKeyur Desai 	char		*name;
61c5866007SKeyur Desai 	char		*cmnt;
62c5866007SKeyur Desai 	char		*path;
63c5866007SKeyur Desai 	char		drive;
64c5866007SKeyur Desai 	boolean_t	check;
65c5866007SKeyur Desai } smb_transient_t;
66c5866007SKeyur Desai 
67c5866007SKeyur Desai static smb_transient_t tshare[] = {
68c5866007SKeyur Desai 	{ "IPC$", "Remote IPC",		NULL,		'\0', B_FALSE },
69c5866007SKeyur Desai 	{ "c$",   "Default Share",	SMB_CVOL,	'C',  B_FALSE },
70c5866007SKeyur Desai 	{ "vss$", "VSS",		SMB_VSS,	'V',  B_TRUE }
71c5866007SKeyur Desai };
72c5866007SKeyur Desai 
7329bd2886SAlan Wright static struct {
7429bd2886SAlan Wright 	char *value;
7529bd2886SAlan Wright 	uint32_t flag;
7629bd2886SAlan Wright } cscopt[] = {
7729bd2886SAlan Wright 	{ "disabled",	SMB_SHRF_CSC_DISABLED },
7829bd2886SAlan Wright 	{ "manual",	SMB_SHRF_CSC_MANUAL },
7929bd2886SAlan Wright 	{ "auto",	SMB_SHRF_CSC_AUTO },
8029bd2886SAlan Wright 	{ "vdo",	SMB_SHRF_CSC_VDO }
8129bd2886SAlan Wright };
8229bd2886SAlan Wright 
83c8ec8eeaSjose borrego /*
84c8ec8eeaSjose borrego  * Cache functions and vars
85c8ec8eeaSjose borrego  */
86b89a8333Snatalie li - Sun Microsystems - Irvine United States #define	SMB_SHR_HTAB_SZ			1024
873db3f65cSamw 
88b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
89b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Cache handle
90b89a8333Snatalie li - Sun Microsystems - Irvine United States  *
91b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Shares cache is a hash table.
92b89a8333Snatalie li - Sun Microsystems - Irvine United States  *
93b89a8333Snatalie li - Sun Microsystems - Irvine United States  * sc_cache		pointer to hash table handle
94b89a8333Snatalie li - Sun Microsystems - Irvine United States  * sc_cache_lck		synchronize cache read/write accesses
95b89a8333Snatalie li - Sun Microsystems - Irvine United States  * sc_state		cache state machine values
96b89a8333Snatalie li - Sun Microsystems - Irvine United States  * sc_nops		number of inflight/pending cache operations
97b89a8333Snatalie li - Sun Microsystems - Irvine United States  * sc_mtx		protects handle fields
98b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
99b89a8333Snatalie li - Sun Microsystems - Irvine United States typedef struct smb_shr_cache {
100b89a8333Snatalie li - Sun Microsystems - Irvine United States 	HT_HANDLE	*sc_cache;
101b89a8333Snatalie li - Sun Microsystems - Irvine United States 	rwlock_t	sc_cache_lck;
102b89a8333Snatalie li - Sun Microsystems - Irvine United States 	mutex_t		sc_mtx;
103b89a8333Snatalie li - Sun Microsystems - Irvine United States 	cond_t		sc_cv;
104b89a8333Snatalie li - Sun Microsystems - Irvine United States 	uint32_t	sc_state;
105b89a8333Snatalie li - Sun Microsystems - Irvine United States 	uint32_t	sc_nops;
106b89a8333Snatalie li - Sun Microsystems - Irvine United States } smb_shr_cache_t;
107b89a8333Snatalie li - Sun Microsystems - Irvine United States 
108b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
109b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Cache states
110b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
111b89a8333Snatalie li - Sun Microsystems - Irvine United States #define	SMB_SHR_CACHE_STATE_NONE	0
112b89a8333Snatalie li - Sun Microsystems - Irvine United States #define	SMB_SHR_CACHE_STATE_CREATED	1
113b89a8333Snatalie li - Sun Microsystems - Irvine United States #define	SMB_SHR_CACHE_STATE_DESTROYING	2
114b89a8333Snatalie li - Sun Microsystems - Irvine United States 
115b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
116b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Cache lock modes
117b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
118b89a8333Snatalie li - Sun Microsystems - Irvine United States #define	SMB_SHR_CACHE_RDLOCK	0
119b89a8333Snatalie li - Sun Microsystems - Irvine United States #define	SMB_SHR_CACHE_WRLOCK	1
120b89a8333Snatalie li - Sun Microsystems - Irvine United States 
121b89a8333Snatalie li - Sun Microsystems - Irvine United States static smb_shr_cache_t smb_shr_cache;
1223db3f65cSamw 
1233db3f65cSamw static uint32_t smb_shr_cache_create(void);
124c8ec8eeaSjose borrego static void smb_shr_cache_destroy(void);
125b89a8333Snatalie li - Sun Microsystems - Irvine United States static uint32_t smb_shr_cache_lock(int);
126b89a8333Snatalie li - Sun Microsystems - Irvine United States static void smb_shr_cache_unlock(void);
127b89a8333Snatalie li - Sun Microsystems - Irvine United States static int smb_shr_cache_count(void);
128b89a8333Snatalie li - Sun Microsystems - Irvine United States static smb_share_t *smb_shr_cache_iterate(smb_shriter_t *);
129b89a8333Snatalie li - Sun Microsystems - Irvine United States 
130b89a8333Snatalie li - Sun Microsystems - Irvine United States static smb_share_t *smb_shr_cache_findent(char *);
131c8ec8eeaSjose borrego static uint32_t smb_shr_cache_addent(smb_share_t *);
132c8ec8eeaSjose borrego static void smb_shr_cache_delent(char *);
133c8ec8eeaSjose borrego static void smb_shr_cache_freent(HT_ITEM *);
1343db3f65cSamw 
135c5866007SKeyur Desai static boolean_t smb_shr_is_empty(const char *);
136c5866007SKeyur Desai static boolean_t smb_shr_is_dot_or_dotdot(const char *);
137c5866007SKeyur Desai 
1383db3f65cSamw /*
139c8ec8eeaSjose borrego  * sharemgr functions
140c8ec8eeaSjose borrego  */
141b89a8333Snatalie li - Sun Microsystems - Irvine United States static void smb_shr_sa_loadgrp(sa_group_t);
142b89a8333Snatalie li - Sun Microsystems - Irvine United States static uint32_t smb_shr_sa_load(sa_share_t, sa_resource_t);
1438d7e4166Sjose borrego static uint32_t smb_shr_sa_loadbyname(char *);
144b89a8333Snatalie li - Sun Microsystems - Irvine United States static uint32_t smb_shr_sa_get(sa_share_t, sa_resource_t, smb_share_t *);
145c8ec8eeaSjose borrego 
146c8ec8eeaSjose borrego /*
147743a77edSAlan Wright  * .ZFS management functions
148743a77edSAlan Wright  */
149743a77edSAlan Wright static void smb_shr_zfs_add(smb_share_t *);
150743a77edSAlan Wright static void smb_shr_zfs_remove(smb_share_t *);
151743a77edSAlan Wright static void smb_shr_zfs_rename(smb_share_t *, smb_share_t *);
152743a77edSAlan Wright 
153743a77edSAlan Wright /*
154c8ec8eeaSjose borrego  * share publishing
155c8ec8eeaSjose borrego  */
156c8ec8eeaSjose borrego #define	SMB_SHR_PUBLISH		0
157c8ec8eeaSjose borrego #define	SMB_SHR_UNPUBLISH	1
158c8ec8eeaSjose borrego 
159c8ec8eeaSjose borrego typedef struct smb_shr_pitem {
160c8ec8eeaSjose borrego 	list_node_t	spi_lnd;
161c8ec8eeaSjose borrego 	char		spi_name[MAXNAMELEN];
162c8ec8eeaSjose borrego 	char		spi_container[MAXPATHLEN];
163c8ec8eeaSjose borrego 	char		spi_op;
164c8ec8eeaSjose borrego } smb_shr_pitem_t;
165c8ec8eeaSjose borrego 
166c8ec8eeaSjose borrego /*
167c8ec8eeaSjose borrego  * publish queue states
168c8ec8eeaSjose borrego  */
169c8ec8eeaSjose borrego #define	SMB_SHR_PQS_NOQUEUE	0
170c8ec8eeaSjose borrego #define	SMB_SHR_PQS_READY	1	/* the queue is ready */
171c8ec8eeaSjose borrego #define	SMB_SHR_PQS_PUBLISHING	2	/* publisher thread is running */
172c8ec8eeaSjose borrego #define	SMB_SHR_PQS_STOPPING	3
173c8ec8eeaSjose borrego 
174c8ec8eeaSjose borrego /*
175c8ec8eeaSjose borrego  * share publishing queue
176c8ec8eeaSjose borrego  */
177c8ec8eeaSjose borrego typedef struct smb_shr_pqueue {
178c8ec8eeaSjose borrego 	list_t		spq_list;
179c8ec8eeaSjose borrego 	mutex_t		spq_mtx;
180c8ec8eeaSjose borrego 	cond_t		spq_cv;
181c8ec8eeaSjose borrego 	uint32_t	spq_state;
182c8ec8eeaSjose borrego } smb_shr_pqueue_t;
183c8ec8eeaSjose borrego 
184c8ec8eeaSjose borrego static smb_shr_pqueue_t ad_queue;
185c8ec8eeaSjose borrego 
186c8ec8eeaSjose borrego static int smb_shr_publisher_start(void);
187c8ec8eeaSjose borrego static void smb_shr_publisher_stop(void);
188c8ec8eeaSjose borrego static void smb_shr_publisher_send(smb_ads_handle_t *, list_t *, const char *);
189b89a8333Snatalie li - Sun Microsystems - Irvine United States static void smb_shr_publisher_queue(const char *, const char *, char);
190c8ec8eeaSjose borrego static void *smb_shr_publisher(void *);
191b89a8333Snatalie li - Sun Microsystems - Irvine United States static void smb_shr_publisher_flush(list_t *);
192b89a8333Snatalie li - Sun Microsystems - Irvine United States static void smb_shr_publish(const char *, const char *);
193b89a8333Snatalie li - Sun Microsystems - Irvine United States static void smb_shr_unpublish(const char *, const char *);
194c8ec8eeaSjose borrego 
195c8ec8eeaSjose borrego /*
196b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Utility/helper functions
197b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
1988d7e4166Sjose borrego static uint32_t smb_shr_lookup(char *, smb_share_t *);
1999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static uint32_t smb_shr_add_transient(char *, char *, char *);
20029bd2886SAlan Wright static int smb_shr_enable_all_privs(void);
201148c5f43SAlan Wright static int smb_shr_expand_subs(char **, smb_share_t *, smb_shr_execinfo_t *);
20229bd2886SAlan Wright static char **smb_shr_tokenize_cmd(char *);
20329bd2886SAlan Wright static void smb_shr_sig_abnormal_term(int);
20429bd2886SAlan Wright static void smb_shr_sig_child(int);
205148c5f43SAlan Wright static int smb_shr_encode(smb_share_t *, nvlist_t **);
20689dc44ceSjose borrego 
20789dc44ceSjose borrego /*
20889dc44ceSjose borrego  * libshare handle and synchronization
20989dc44ceSjose borrego  */
21089dc44ceSjose borrego typedef struct smb_sa_handle {
21189dc44ceSjose borrego 	sa_handle_t	sa_handle;
21289dc44ceSjose borrego 	mutex_t		sa_mtx;
21389dc44ceSjose borrego 	boolean_t	sa_in_service;
21489dc44ceSjose borrego } smb_sa_handle_t;
21589dc44ceSjose borrego 
21689dc44ceSjose borrego static smb_sa_handle_t smb_sa_handle;
21789dc44ceSjose borrego 
21829bd2886SAlan Wright static char smb_shr_exec_map[MAXPATHLEN];
21929bd2886SAlan Wright static char smb_shr_exec_unmap[MAXPATHLEN];
22029bd2886SAlan Wright static mutex_t smb_shr_exec_mtx;
22129bd2886SAlan Wright 
222b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
223e3f2c991SKeyur Desai  * Semaphore held during temporary, process-wide changes
224e3f2c991SKeyur Desai  * such as process privileges.  It is a seamaphore and
225e3f2c991SKeyur Desai  * not a mutex so a child of fork can reset it.
226e3f2c991SKeyur Desai  */
227e3f2c991SKeyur Desai static sema_t smb_proc_sem = DEFAULTSEMA;
228e3f2c991SKeyur Desai 
229e3f2c991SKeyur Desai /*
2308d7e4166Sjose borrego  * Creates and initializes the cache and starts the publisher
2318d7e4166Sjose borrego  * thread.
2323db3f65cSamw  */
2333db3f65cSamw int
smb_shr_start(void)2343db3f65cSamw smb_shr_start(void)
2353db3f65cSamw {
236c5866007SKeyur Desai 	smb_transient_t	*ts;
237c5866007SKeyur Desai 	uint32_t	nerr;
2389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	int		i;
2399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
24089dc44ceSjose borrego 	(void) mutex_lock(&smb_sa_handle.sa_mtx);
24189dc44ceSjose borrego 	smb_sa_handle.sa_in_service = B_TRUE;
24289dc44ceSjose borrego 	(void) mutex_unlock(&smb_sa_handle.sa_mtx);
24389dc44ceSjose borrego 
244b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (smb_shr_cache_create() != NERR_Success)
245b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (ENOMEM);
246b89a8333Snatalie li - Sun Microsystems - Irvine United States 
2479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	for (i = 0; i < sizeof (tshare)/sizeof (tshare[0]); ++i) {
248c5866007SKeyur Desai 		ts = &tshare[i];
249c5866007SKeyur Desai 
250c5866007SKeyur Desai 		if (ts->check && smb_shr_is_empty(ts->path))
251c5866007SKeyur Desai 			continue;
252c5866007SKeyur Desai 
253c5866007SKeyur Desai 		nerr = smb_shr_add_transient(ts->name, ts->cmnt, ts->path);
254c5866007SKeyur Desai 		if (nerr != NERR_Success)
255b89a8333Snatalie li - Sun Microsystems - Irvine United States 			return (ENOMEM);
2569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
257b89a8333Snatalie li - Sun Microsystems - Irvine United States 
2588d7e4166Sjose borrego 	return (smb_shr_publisher_start());
2593db3f65cSamw }
2603db3f65cSamw 
2613db3f65cSamw void
smb_shr_stop(void)2623db3f65cSamw smb_shr_stop(void)
2633db3f65cSamw {
264c8ec8eeaSjose borrego 	smb_shr_cache_destroy();
265c8ec8eeaSjose borrego 	smb_shr_publisher_stop();
26689dc44ceSjose borrego 
26789dc44ceSjose borrego 	(void) mutex_lock(&smb_sa_handle.sa_mtx);
26889dc44ceSjose borrego 	smb_sa_handle.sa_in_service = B_FALSE;
26989dc44ceSjose borrego 
27089dc44ceSjose borrego 	if (smb_sa_handle.sa_handle != NULL) {
27189dc44ceSjose borrego 		sa_fini(smb_sa_handle.sa_handle);
27289dc44ceSjose borrego 		smb_sa_handle.sa_handle = NULL;
27389dc44ceSjose borrego 	}
27489dc44ceSjose borrego 
27589dc44ceSjose borrego 	(void) mutex_unlock(&smb_sa_handle.sa_mtx);
27689dc44ceSjose borrego }
27789dc44ceSjose borrego 
27889dc44ceSjose borrego /*
27989dc44ceSjose borrego  * Get a handle and exclusive access to the libshare API.
28089dc44ceSjose borrego  */
28189dc44ceSjose borrego sa_handle_t
smb_shr_sa_enter(void)28289dc44ceSjose borrego smb_shr_sa_enter(void)
28389dc44ceSjose borrego {
28489dc44ceSjose borrego 	(void) mutex_lock(&smb_sa_handle.sa_mtx);
28589dc44ceSjose borrego 	if (!smb_sa_handle.sa_in_service) {
28689dc44ceSjose borrego 		(void) mutex_unlock(&smb_sa_handle.sa_mtx);
28789dc44ceSjose borrego 		return (NULL);
28889dc44ceSjose borrego 	}
28989dc44ceSjose borrego 
290*a851ffc8SGordon Ross 	if (smb_sa_handle.sa_handle != NULL &&
291*a851ffc8SGordon Ross 	    sa_needs_refresh(smb_sa_handle.sa_handle)) {
292*a851ffc8SGordon Ross 		sa_fini(smb_sa_handle.sa_handle);
293*a851ffc8SGordon Ross 		smb_sa_handle.sa_handle = NULL;
294*a851ffc8SGordon Ross 	}
295*a851ffc8SGordon Ross 
29689dc44ceSjose borrego 	if (smb_sa_handle.sa_handle == NULL) {
29789dc44ceSjose borrego 		smb_sa_handle.sa_handle = sa_init(SA_INIT_SHARE_API);
29889dc44ceSjose borrego 		if (smb_sa_handle.sa_handle == NULL) {
29989dc44ceSjose borrego 			syslog(LOG_ERR, "share: failed to get libshare handle");
30089dc44ceSjose borrego 			(void) mutex_unlock(&smb_sa_handle.sa_mtx);
30189dc44ceSjose borrego 			return (NULL);
30289dc44ceSjose borrego 		}
30389dc44ceSjose borrego 	}
30489dc44ceSjose borrego 
30589dc44ceSjose borrego 	return (smb_sa_handle.sa_handle);
30689dc44ceSjose borrego }
30789dc44ceSjose borrego 
30889dc44ceSjose borrego /*
30989dc44ceSjose borrego  * Release exclusive access to the libshare API.
31089dc44ceSjose borrego  */
31189dc44ceSjose borrego void
smb_shr_sa_exit(void)31289dc44ceSjose borrego smb_shr_sa_exit(void)
31389dc44ceSjose borrego {
31489dc44ceSjose borrego 	(void) mutex_unlock(&smb_sa_handle.sa_mtx);
3153db3f65cSamw }
3163db3f65cSamw 
3173db3f65cSamw /*
318c8ec8eeaSjose borrego  * Return the total number of shares
3193db3f65cSamw  */
3203db3f65cSamw int
smb_shr_count(void)3213db3f65cSamw smb_shr_count(void)
3223db3f65cSamw {
323b89a8333Snatalie li - Sun Microsystems - Irvine United States 	int n_shares = 0;
3243db3f65cSamw 
325b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (smb_shr_cache_lock(SMB_SHR_CACHE_RDLOCK) == NERR_Success) {
326b89a8333Snatalie li - Sun Microsystems - Irvine United States 		n_shares = smb_shr_cache_count();
327b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache_unlock();
328b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
3293db3f65cSamw 
3303db3f65cSamw 	return (n_shares);
3313db3f65cSamw }
3323db3f65cSamw 
3333db3f65cSamw /*
3343db3f65cSamw  * smb_shr_iterinit
3353db3f65cSamw  *
336c8ec8eeaSjose borrego  * Initialize given iterator for traversing hash table.
3373db3f65cSamw  */
3383db3f65cSamw void
smb_shr_iterinit(smb_shriter_t * shi)339c8ec8eeaSjose borrego smb_shr_iterinit(smb_shriter_t *shi)
3403db3f65cSamw {
3413db3f65cSamw 	bzero(shi, sizeof (smb_shriter_t));
342c8ec8eeaSjose borrego 	shi->si_first = B_TRUE;
3433db3f65cSamw }
3443db3f65cSamw 
3453db3f65cSamw /*
3463db3f65cSamw  * smb_shr_iterate
3473db3f65cSamw  *
3483db3f65cSamw  * Iterate on the shares in the hash table. The iterator must be initialized
3493db3f65cSamw  * before the first iteration. On subsequent calls, the iterator must be
3503db3f65cSamw  * passed unchanged.
3513db3f65cSamw  *
3523db3f65cSamw  * Returns NULL on failure or when all shares are visited, otherwise
3533db3f65cSamw  * returns information of visited share.
3543db3f65cSamw  */
3553db3f65cSamw smb_share_t *
smb_shr_iterate(smb_shriter_t * shi)3563db3f65cSamw smb_shr_iterate(smb_shriter_t *shi)
3573db3f65cSamw {
358c8ec8eeaSjose borrego 	smb_share_t *share = NULL;
359b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_share_t *cached_si;
3603db3f65cSamw 
361b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (shi == NULL)
3623db3f65cSamw 		return (NULL);
3633db3f65cSamw 
364b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (smb_shr_cache_lock(SMB_SHR_CACHE_RDLOCK) == NERR_Success) {
365b89a8333Snatalie li - Sun Microsystems - Irvine United States 		if ((cached_si = smb_shr_cache_iterate(shi)) != NULL) {
366c8ec8eeaSjose borrego 			share = &shi->si_share;
367b89a8333Snatalie li - Sun Microsystems - Irvine United States 			bcopy(cached_si, share, sizeof (smb_share_t));
3683db3f65cSamw 		}
369b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache_unlock();
370b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
3713db3f65cSamw 
372c8ec8eeaSjose borrego 	return (share);
3733db3f65cSamw }
3743db3f65cSamw 
3753db3f65cSamw /*
376b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Adds the given share to cache, publishes the share in ADS
377b89a8333Snatalie li - Sun Microsystems - Irvine United States  * if it has an AD container, calls kernel to take a hold on
378b89a8333Snatalie li - Sun Microsystems - Irvine United States  * the shared file system. If it can't take a hold on the
379b89a8333Snatalie li - Sun Microsystems - Irvine United States  * shared file system, it's either because shared directory
380b89a8333Snatalie li - Sun Microsystems - Irvine United States  * does not exist or some other error has occurred, in any
381b89a8333Snatalie li - Sun Microsystems - Irvine United States  * case the share is removed from the cache.
3823db3f65cSamw  *
383b89a8333Snatalie li - Sun Microsystems - Irvine United States  * If the specified share is an autohome share which already
384b89a8333Snatalie li - Sun Microsystems - Irvine United States  * exists in the cache, just increments the reference count.
3853db3f65cSamw  */
3863db3f65cSamw uint32_t
smb_shr_add(smb_share_t * si)387b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_add(smb_share_t *si)
3883db3f65cSamw {
38929e6af5cSAlek Pinchuk 	struct stat st;
390b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_share_t *cached_si;
391148c5f43SAlan Wright 	nvlist_t *shrlist;
392b89a8333Snatalie li - Sun Microsystems - Irvine United States 	uint32_t status;
393c8ec8eeaSjose borrego 	int rc;
3943db3f65cSamw 
395c8ec8eeaSjose borrego 	assert(si != NULL);
3963db3f65cSamw 
397fe1c642dSBill Krier 	if (smb_name_validate_share(si->shr_name) != ERROR_SUCCESS)
398c8ec8eeaSjose borrego 		return (ERROR_INVALID_NAME);
3993db3f65cSamw 
400b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (smb_shr_cache_lock(SMB_SHR_CACHE_WRLOCK) != NERR_Success)
401b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (NERR_InternalError);
402c8ec8eeaSjose borrego 
403b89a8333Snatalie li - Sun Microsystems - Irvine United States 	cached_si = smb_shr_cache_findent(si->shr_name);
404b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (cached_si) {
405b89a8333Snatalie li - Sun Microsystems - Irvine United States 		if (si->shr_flags & SMB_SHRF_AUTOHOME) {
406b89a8333Snatalie li - Sun Microsystems - Irvine United States 			cached_si->shr_refcnt++;
407b89a8333Snatalie li - Sun Microsystems - Irvine United States 			status = NERR_Success;
408b89a8333Snatalie li - Sun Microsystems - Irvine United States 		} else {
409b89a8333Snatalie li - Sun Microsystems - Irvine United States 			status = NERR_DuplicateShare;
410b89a8333Snatalie li - Sun Microsystems - Irvine United States 		}
411b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache_unlock();
412c8ec8eeaSjose borrego 		return (status);
413c8ec8eeaSjose borrego 	}
414b89a8333Snatalie li - Sun Microsystems - Irvine United States 
41529e6af5cSAlek Pinchuk 	if (STYPE_ISDSK(si->shr_type)) {
41629e6af5cSAlek Pinchuk 		/*
41729e6af5cSAlek Pinchuk 		 * If share type is STYPE_DISKTREE then the path to the
41829e6af5cSAlek Pinchuk 		 * share should exist so that we can add the share to cache.
41929e6af5cSAlek Pinchuk 		 */
42029e6af5cSAlek Pinchuk 		rc = stat(si->shr_path, &st);
42129e6af5cSAlek Pinchuk 		if (rc != 0) {
42229e6af5cSAlek Pinchuk 			smb_shr_cache_unlock();
42329e6af5cSAlek Pinchuk 			return (NERR_ItemNotFound);
42429e6af5cSAlek Pinchuk 		}
42529e6af5cSAlek Pinchuk 	}
42629e6af5cSAlek Pinchuk 
427b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if ((status = smb_shr_cache_addent(si)) != NERR_Success) {
428b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache_unlock();
429b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (status);
430c8ec8eeaSjose borrego 	}
431c8ec8eeaSjose borrego 
432b89a8333Snatalie li - Sun Microsystems - Irvine United States 	/* don't hold the lock across door call */
433b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_shr_cache_unlock();
434b89a8333Snatalie li - Sun Microsystems - Irvine United States 
435148c5f43SAlan Wright 	if ((rc = smb_shr_encode(si, &shrlist)) == 0) {
436148c5f43SAlan Wright 		/* send the share to kernel */
437148c5f43SAlan Wright 		rc = smb_kmod_share(shrlist);
438148c5f43SAlan Wright 		nvlist_free(shrlist);
439c8ec8eeaSjose borrego 
440c8ec8eeaSjose borrego 		if (rc == 0) {
441b89a8333Snatalie li - Sun Microsystems - Irvine United States 			smb_shr_publish(si->shr_name, si->shr_container);
442743a77edSAlan Wright 
443743a77edSAlan Wright 			/* If path is ZFS, add the .zfs/shares/<share> entry. */
444743a77edSAlan Wright 			smb_shr_zfs_add(si);
445743a77edSAlan Wright 
446cb174861Sjoyce mcintosh 			if ((si->shr_flags & SMB_SHRF_DFSROOT) != 0)
447cb174861Sjoyce mcintosh 				dfs_namespace_load(si->shr_name);
448cb174861Sjoyce mcintosh 
449b89a8333Snatalie li - Sun Microsystems - Irvine United States 			return (NERR_Success);
450c8ec8eeaSjose borrego 		}
451148c5f43SAlan Wright 	}
452c8ec8eeaSjose borrego 
453b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (smb_shr_cache_lock(SMB_SHR_CACHE_WRLOCK) == NERR_Success) {
454c8ec8eeaSjose borrego 		smb_shr_cache_delent(si->shr_name);
455b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache_unlock();
456b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
457c8ec8eeaSjose borrego 
458c8ec8eeaSjose borrego 	/*
459c8ec8eeaSjose borrego 	 * rc == ENOENT means the shared directory doesn't exist
460c8ec8eeaSjose borrego 	 */
461c8ec8eeaSjose borrego 	return ((rc == ENOENT) ? NERR_UnknownDevDir : NERR_InternalError);
4623db3f65cSamw }
4633db3f65cSamw 
4643db3f65cSamw /*
465b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Removes the specified share from cache, removes it from AD
466b89a8333Snatalie li - Sun Microsystems - Irvine United States  * if it has an AD container, and calls the kernel to release
467b89a8333Snatalie li - Sun Microsystems - Irvine United States  * the hold on the shared file system.
4683db3f65cSamw  *
469b89a8333Snatalie li - Sun Microsystems - Irvine United States  * If this is an autohome share then decrement the reference
470b89a8333Snatalie li - Sun Microsystems - Irvine United States  * count. If it reaches 0 then it proceeds with removing steps.
4713db3f65cSamw  */
4723db3f65cSamw uint32_t
smb_shr_remove(char * sharename)473b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_remove(char *sharename)
4743db3f65cSamw {
475b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_share_t *si;
476b89a8333Snatalie li - Sun Microsystems - Irvine United States 	char container[MAXPATHLEN];
4779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	boolean_t dfsroot;
478148c5f43SAlan Wright 	nvlist_t *shrlist;
4793db3f65cSamw 
480c8ec8eeaSjose borrego 	assert(sharename != NULL);
4813db3f65cSamw 
482fe1c642dSBill Krier 	if (smb_name_validate_share(sharename) != ERROR_SUCCESS)
483b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (ERROR_INVALID_NAME);
4843db3f65cSamw 
485b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (smb_shr_cache_lock(SMB_SHR_CACHE_WRLOCK) != NERR_Success)
4863db3f65cSamw 		return (NERR_InternalError);
487b89a8333Snatalie li - Sun Microsystems - Irvine United States 
488b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if ((si = smb_shr_cache_findent(sharename)) == NULL) {
489b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache_unlock();
490b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (NERR_NetNameNotFound);
4913db3f65cSamw 	}
4923db3f65cSamw 
49329e6af5cSAlek Pinchuk 	if (STYPE_ISIPC(si->shr_type)) {
494b89a8333Snatalie li - Sun Microsystems - Irvine United States 		/* IPC$ share cannot be removed */
495b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache_unlock();
496b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (ERROR_ACCESS_DENIED);
497b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
498b89a8333Snatalie li - Sun Microsystems - Irvine United States 
499b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (si->shr_flags & SMB_SHRF_AUTOHOME) {
500b89a8333Snatalie li - Sun Microsystems - Irvine United States 		if ((--si->shr_refcnt) > 0) {
501b89a8333Snatalie li - Sun Microsystems - Irvine United States 			smb_shr_cache_unlock();
502b89a8333Snatalie li - Sun Microsystems - Irvine United States 			return (NERR_Success);
503b89a8333Snatalie li - Sun Microsystems - Irvine United States 		}
504b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
505b89a8333Snatalie li - Sun Microsystems - Irvine United States 
506743a77edSAlan Wright 	/*
507743a77edSAlan Wright 	 * If path is ZFS, remove the .zfs/shares/<share> entry.  Need
508743a77edSAlan Wright 	 * to remove before cleanup of cache occurs.
509743a77edSAlan Wright 	 */
510743a77edSAlan Wright 	smb_shr_zfs_remove(si);
511148c5f43SAlan Wright 	(void) smb_shr_encode(si, &shrlist);
512743a77edSAlan Wright 
513b89a8333Snatalie li - Sun Microsystems - Irvine United States 	(void) strlcpy(container, si->shr_container, sizeof (container));
5149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	dfsroot = ((si->shr_flags & SMB_SHRF_DFSROOT) != 0);
515b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_shr_cache_delent(sharename);
516b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_shr_cache_unlock();
517b89a8333Snatalie li - Sun Microsystems - Irvine United States 
518b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_shr_unpublish(sharename, container);
519b89a8333Snatalie li - Sun Microsystems - Irvine United States 
520b89a8333Snatalie li - Sun Microsystems - Irvine United States 	/* call kernel to release the hold on the shared file system */
521148c5f43SAlan Wright 	if (shrlist != NULL) {
522148c5f43SAlan Wright 		(void) smb_kmod_unshare(shrlist);
523148c5f43SAlan Wright 		nvlist_free(shrlist);
524148c5f43SAlan Wright 	}
5253db3f65cSamw 
5269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (dfsroot)
5279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		dfs_namespace_unload(sharename);
5289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
5293db3f65cSamw 	return (NERR_Success);
5303db3f65cSamw }
5313db3f65cSamw 
5323db3f65cSamw /*
5333db3f65cSamw  * Rename a share. Check that the current name exists and the new name
5343db3f65cSamw  * doesn't exist. The rename is performed by deleting the current share
5353db3f65cSamw  * definition and creating a new share with the new name.
5363db3f65cSamw  */
5373db3f65cSamw uint32_t
smb_shr_rename(char * from_name,char * to_name)538c8ec8eeaSjose borrego smb_shr_rename(char *from_name, char *to_name)
5393db3f65cSamw {
540b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_share_t *from_si;
541b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_share_t to_si;
542c8ec8eeaSjose borrego 	uint32_t status;
543148c5f43SAlan Wright 	nvlist_t *shrlist;
5443db3f65cSamw 
545c8ec8eeaSjose borrego 	assert((from_name != NULL) && (to_name != NULL));
5463db3f65cSamw 
547fe1c642dSBill Krier 	if (smb_name_validate_share(from_name) != ERROR_SUCCESS ||
548fe1c642dSBill Krier 	    smb_name_validate_share(to_name) != ERROR_SUCCESS)
549c8ec8eeaSjose borrego 		return (ERROR_INVALID_NAME);
5503db3f65cSamw 
551b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (smb_shr_cache_lock(SMB_SHR_CACHE_WRLOCK) != NERR_Success)
552b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (NERR_InternalError);
553b89a8333Snatalie li - Sun Microsystems - Irvine United States 
554b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if ((from_si = smb_shr_cache_findent(from_name)) == NULL) {
555b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache_unlock();
5563db3f65cSamw 		return (NERR_NetNameNotFound);
557b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
5583db3f65cSamw 
55929e6af5cSAlek Pinchuk 	if (STYPE_ISIPC(from_si->shr_type)) {
560b89a8333Snatalie li - Sun Microsystems - Irvine United States 		/* IPC$ share cannot be renamed */
561b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache_unlock();
562c8ec8eeaSjose borrego 		return (ERROR_ACCESS_DENIED);
563b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
5643db3f65cSamw 
565b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (smb_shr_cache_findent(to_name) != NULL) {
566b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache_unlock();
567b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (NERR_DuplicateShare);
568b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
569b89a8333Snatalie li - Sun Microsystems - Irvine United States 
570b89a8333Snatalie li - Sun Microsystems - Irvine United States 	bcopy(from_si, &to_si, sizeof (smb_share_t));
571b89a8333Snatalie li - Sun Microsystems - Irvine United States 	(void) strlcpy(to_si.shr_name, to_name, sizeof (to_si.shr_name));
572b89a8333Snatalie li - Sun Microsystems - Irvine United States 
573cb174861Sjoyce mcintosh 
574743a77edSAlan Wright 	/* If path is ZFS, rename the .zfs/shares/<share> entry. */
575743a77edSAlan Wright 	smb_shr_zfs_rename(from_si, &to_si);
576743a77edSAlan Wright 
577b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if ((status = smb_shr_cache_addent(&to_si)) != NERR_Success) {
578b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache_unlock();
579c8ec8eeaSjose borrego 		return (status);
580b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
581c8ec8eeaSjose borrego 
582c8ec8eeaSjose borrego 	smb_shr_cache_delent(from_name);
583b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_shr_cache_unlock();
584b89a8333Snatalie li - Sun Microsystems - Irvine United States 
585148c5f43SAlan Wright 	if (smb_shr_encode(from_si, &shrlist) == 0) {
586148c5f43SAlan Wright 		(void) smb_kmod_unshare(shrlist);
587148c5f43SAlan Wright 		nvlist_free(shrlist);
588148c5f43SAlan Wright 
589148c5f43SAlan Wright 		if (smb_shr_encode(&to_si, &shrlist) == 0) {
590148c5f43SAlan Wright 			(void) smb_kmod_share(shrlist);
591148c5f43SAlan Wright 			nvlist_free(shrlist);
592148c5f43SAlan Wright 		}
593148c5f43SAlan Wright 	}
594148c5f43SAlan Wright 
595b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_shr_unpublish(from_name, to_si.shr_container);
596b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_shr_publish(to_name, to_si.shr_container);
597c8ec8eeaSjose borrego 
598c8ec8eeaSjose borrego 	return (NERR_Success);
5993db3f65cSamw }
6003db3f65cSamw 
6013db3f65cSamw /*
602c8ec8eeaSjose borrego  * Load the information for the specified share into the supplied share
603c8ec8eeaSjose borrego  * info structure.
6048d7e4166Sjose borrego  *
6058d7e4166Sjose borrego  * First looks up the cache to see if the specified share exists, if there
6068d7e4166Sjose borrego  * is a miss then it looks up sharemgr.
607c8ec8eeaSjose borrego  */
608c8ec8eeaSjose borrego uint32_t
smb_shr_get(char * sharename,smb_share_t * si)609c8ec8eeaSjose borrego smb_shr_get(char *sharename, smb_share_t *si)
610c8ec8eeaSjose borrego {
6118d7e4166Sjose borrego 	uint32_t status;
612c8ec8eeaSjose borrego 
613b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (sharename == NULL || *sharename == '\0')
614c8ec8eeaSjose borrego 		return (NERR_NetNameNotFound);
615b89a8333Snatalie li - Sun Microsystems - Irvine United States 
6168d7e4166Sjose borrego 	if ((status = smb_shr_lookup(sharename, si)) == NERR_Success)
6178d7e4166Sjose borrego 		return (status);
618c8ec8eeaSjose borrego 
6198d7e4166Sjose borrego 	if ((status = smb_shr_sa_loadbyname(sharename)) == NERR_Success)
6208d7e4166Sjose borrego 		status = smb_shr_lookup(sharename, si);
621c8ec8eeaSjose borrego 
622b89a8333Snatalie li - Sun Microsystems - Irvine United States 	return (status);
623c8ec8eeaSjose borrego }
624c8ec8eeaSjose borrego 
625c8ec8eeaSjose borrego /*
626c8ec8eeaSjose borrego  * Modifies an existing share. Properties that can be modified are:
627c8ec8eeaSjose borrego  *
628c8ec8eeaSjose borrego  *   o comment
629c8ec8eeaSjose borrego  *   o AD container
630b89a8333Snatalie li - Sun Microsystems - Irvine United States  *   o host access
631e3f2c991SKeyur Desai  *   o abe
632c8ec8eeaSjose borrego  */
633c8ec8eeaSjose borrego uint32_t
smb_shr_modify(smb_share_t * new_si)634b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_modify(smb_share_t *new_si)
635c8ec8eeaSjose borrego {
636c8ec8eeaSjose borrego 	smb_share_t *si;
637b89a8333Snatalie li - Sun Microsystems - Irvine United States 	boolean_t adc_changed = B_FALSE;
638b89a8333Snatalie li - Sun Microsystems - Irvine United States 	char old_container[MAXPATHLEN];
6399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	uint32_t access, flag;
640148c5f43SAlan Wright 	nvlist_t *shrlist;
641c8ec8eeaSjose borrego 
642b89a8333Snatalie li - Sun Microsystems - Irvine United States 	assert(new_si != NULL);
643c8ec8eeaSjose borrego 
644b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (smb_shr_cache_lock(SMB_SHR_CACHE_WRLOCK) != NERR_Success)
645b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (NERR_InternalError);
646c8ec8eeaSjose borrego 
647b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if ((si = smb_shr_cache_findent(new_si->shr_name)) == NULL) {
648b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache_unlock();
649b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (NERR_NetNameNotFound);
650c8ec8eeaSjose borrego 	}
651c8ec8eeaSjose borrego 
65229e6af5cSAlek Pinchuk 	if (STYPE_ISIPC(si->shr_type)) {
653b89a8333Snatalie li - Sun Microsystems - Irvine United States 		/* IPC$ share cannot be modified */
654b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache_unlock();
655b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (ERROR_ACCESS_DENIED);
656c8ec8eeaSjose borrego 	}
657c8ec8eeaSjose borrego 
65889dc44ceSjose borrego 	(void) strlcpy(si->shr_cmnt, new_si->shr_cmnt, sizeof (si->shr_cmnt));
659b89a8333Snatalie li - Sun Microsystems - Irvine United States 
660b89a8333Snatalie li - Sun Microsystems - Irvine United States 	adc_changed = (strcmp(new_si->shr_container, si->shr_container) != 0);
661b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (adc_changed) {
662b89a8333Snatalie li - Sun Microsystems - Irvine United States 		/* save current container - needed for unpublishing */
663b89a8333Snatalie li - Sun Microsystems - Irvine United States 		(void) strlcpy(old_container, si->shr_container,
664b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    sizeof (old_container));
665b89a8333Snatalie li - Sun Microsystems - Irvine United States 		(void) strlcpy(si->shr_container, new_si->shr_container,
666b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    sizeof (si->shr_container));
667b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
668b89a8333Snatalie li - Sun Microsystems - Irvine United States 
6699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	flag = (new_si->shr_flags & SMB_SHRF_ABE);
670e3f2c991SKeyur Desai 	si->shr_flags &= ~SMB_SHRF_ABE;
6719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	si->shr_flags |= flag;
672e3f2c991SKeyur Desai 
6739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	flag = (new_si->shr_flags & SMB_SHRF_CATIA);
6748b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	si->shr_flags &= ~SMB_SHRF_CATIA;
6759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	si->shr_flags |= flag;
6768b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 
6779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	flag = (new_si->shr_flags & SMB_SHRF_GUEST_OK);
67829bd2886SAlan Wright 	si->shr_flags &= ~SMB_SHRF_GUEST_OK;
6799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	si->shr_flags |= flag;
6809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
6819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	flag = (new_si->shr_flags & SMB_SHRF_DFSROOT);
6829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	si->shr_flags &= ~SMB_SHRF_DFSROOT;
6839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	si->shr_flags |= flag;
6849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
6859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	flag = (new_si->shr_flags & SMB_SHRF_CSC_MASK);
6869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	si->shr_flags &= ~SMB_SHRF_CSC_MASK;
6879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	si->shr_flags |= flag;
6888d7e4166Sjose borrego 
689b89a8333Snatalie li - Sun Microsystems - Irvine United States 	access = (new_si->shr_flags & SMB_SHRF_ACC_ALL);
69089dc44ceSjose borrego 	si->shr_flags &= ~SMB_SHRF_ACC_ALL;
691b89a8333Snatalie li - Sun Microsystems - Irvine United States 	si->shr_flags |= access;
692b89a8333Snatalie li - Sun Microsystems - Irvine United States 
693b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (access & SMB_SHRF_ACC_NONE)
694b89a8333Snatalie li - Sun Microsystems - Irvine United States 		(void) strlcpy(si->shr_access_none, new_si->shr_access_none,
695b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    sizeof (si->shr_access_none));
696b89a8333Snatalie li - Sun Microsystems - Irvine United States 
697b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (access & SMB_SHRF_ACC_RO)
698b89a8333Snatalie li - Sun Microsystems - Irvine United States 		(void) strlcpy(si->shr_access_ro, new_si->shr_access_ro,
699b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    sizeof (si->shr_access_ro));
700b89a8333Snatalie li - Sun Microsystems - Irvine United States 
701b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (access & SMB_SHRF_ACC_RW)
702b89a8333Snatalie li - Sun Microsystems - Irvine United States 		(void) strlcpy(si->shr_access_rw, new_si->shr_access_rw,
703b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    sizeof (si->shr_access_rw));
704b89a8333Snatalie li - Sun Microsystems - Irvine United States 
705b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_shr_cache_unlock();
706b89a8333Snatalie li - Sun Microsystems - Irvine United States 
707148c5f43SAlan Wright 	if (smb_shr_encode(si, &shrlist) == 0) {
708148c5f43SAlan Wright 		(void) smb_kmod_unshare(shrlist);
709148c5f43SAlan Wright 		nvlist_free(shrlist);
710148c5f43SAlan Wright 
711148c5f43SAlan Wright 		if (smb_shr_encode(new_si, &shrlist) == 0) {
712148c5f43SAlan Wright 			(void) smb_kmod_share(shrlist);
713148c5f43SAlan Wright 			nvlist_free(shrlist);
714148c5f43SAlan Wright 		}
715148c5f43SAlan Wright 	}
716148c5f43SAlan Wright 
717b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (adc_changed) {
718b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_unpublish(new_si->shr_name, old_container);
719b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_publish(new_si->shr_name, new_si->shr_container);
720b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
721b89a8333Snatalie li - Sun Microsystems - Irvine United States 
722b89a8333Snatalie li - Sun Microsystems - Irvine United States 	return (NERR_Success);
723b89a8333Snatalie li - Sun Microsystems - Irvine United States }
724c8ec8eeaSjose borrego 
725c8ec8eeaSjose borrego /*
7263db3f65cSamw  * smb_shr_exists
7273db3f65cSamw  *
728c8ec8eeaSjose borrego  * Returns B_TRUE if the share exists. Otherwise returns B_FALSE
7293db3f65cSamw  */
730c8ec8eeaSjose borrego boolean_t
smb_shr_exists(char * sharename)731c8ec8eeaSjose borrego smb_shr_exists(char *sharename)
7323db3f65cSamw {
733b89a8333Snatalie li - Sun Microsystems - Irvine United States 	boolean_t exists = B_FALSE;
7343db3f65cSamw 
735c8ec8eeaSjose borrego 	if (sharename == NULL || *sharename == '\0')
736c8ec8eeaSjose borrego 		return (B_FALSE);
737c8ec8eeaSjose borrego 
738b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (smb_shr_cache_lock(SMB_SHR_CACHE_RDLOCK) == NERR_Success) {
739b89a8333Snatalie li - Sun Microsystems - Irvine United States 		exists = (smb_shr_cache_findent(sharename) != NULL);
740b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache_unlock();
741b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
742c8ec8eeaSjose borrego 
743c8ec8eeaSjose borrego 	return (exists);
7443db3f65cSamw }
7453db3f65cSamw 
7463db3f65cSamw /*
747b89a8333Snatalie li - Sun Microsystems - Irvine United States  * If the shared directory does not begin with a /, one will be
748b89a8333Snatalie li - Sun Microsystems - Irvine United States  * inserted as a prefix. If ipaddr is not zero, then also return
749b89a8333Snatalie li - Sun Microsystems - Irvine United States  * information about access based on the host level access lists, if
750b89a8333Snatalie li - Sun Microsystems - Irvine United States  * present. Also return access check if there is an IP address and
751b89a8333Snatalie li - Sun Microsystems - Irvine United States  * shr_accflags.
752b89a8333Snatalie li - Sun Microsystems - Irvine United States  *
753b89a8333Snatalie li - Sun Microsystems - Irvine United States  * The value of smb_chk_hostaccess is checked for an access match.
754b89a8333Snatalie li - Sun Microsystems - Irvine United States  * -1 is wildcard match
755b89a8333Snatalie li - Sun Microsystems - Irvine United States  * 0 is no match
756b89a8333Snatalie li - Sun Microsystems - Irvine United States  * 1 is match
757b89a8333Snatalie li - Sun Microsystems - Irvine United States  *
758b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Precedence is none is checked first followed by ro then rw if
759b89a8333Snatalie li - Sun Microsystems - Irvine United States  * needed.  If x is wildcard (< 0) then check to see if the other
760b89a8333Snatalie li - Sun Microsystems - Irvine United States  * values are a match. If a match, that wins.
761b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
762148c5f43SAlan Wright uint32_t
smb_shr_hostaccess(smb_inaddr_t * ipaddr,char * none_list,char * ro_list,char * rw_list,uint32_t flag)763148c5f43SAlan Wright smb_shr_hostaccess(smb_inaddr_t *ipaddr, char *none_list, char *ro_list,
764148c5f43SAlan Wright     char *rw_list, uint32_t flag)
765b89a8333Snatalie li - Sun Microsystems - Irvine United States {
766148c5f43SAlan Wright 	uint32_t acc = SMB_SHRF_ACC_NONE;
767148c5f43SAlan Wright 	int none = 0;
768148c5f43SAlan Wright 	int ro = 0;
769148c5f43SAlan Wright 	int rw = 0;
770b89a8333Snatalie li - Sun Microsystems - Irvine United States 
771148c5f43SAlan Wright 	if (!smb_inet_iszero(ipaddr)) {
772148c5f43SAlan Wright 		if ((flag & SMB_SHRF_ACC_NONE) != 0)
773148c5f43SAlan Wright 			none = smb_chk_hostaccess(ipaddr, none_list);
774148c5f43SAlan Wright 		if ((flag & SMB_SHRF_ACC_RO) != 0)
775148c5f43SAlan Wright 			ro = smb_chk_hostaccess(ipaddr, ro_list);
776148c5f43SAlan Wright 		if ((flag & SMB_SHRF_ACC_RW) != 0)
777148c5f43SAlan Wright 			rw = smb_chk_hostaccess(ipaddr, rw_list);
778148c5f43SAlan Wright 
779b89a8333Snatalie li - Sun Microsystems - Irvine United States 		/* make first pass to get basic value */
780b89a8333Snatalie li - Sun Microsystems - Irvine United States 		if (none != 0)
781b89a8333Snatalie li - Sun Microsystems - Irvine United States 			acc = SMB_SHRF_ACC_NONE;
782b89a8333Snatalie li - Sun Microsystems - Irvine United States 		else if (ro != 0)
783b89a8333Snatalie li - Sun Microsystems - Irvine United States 			acc = SMB_SHRF_ACC_RO;
784b89a8333Snatalie li - Sun Microsystems - Irvine United States 		else if (rw != 0)
785b89a8333Snatalie li - Sun Microsystems - Irvine United States 			acc = SMB_SHRF_ACC_RW;
786b89a8333Snatalie li - Sun Microsystems - Irvine United States 
787b89a8333Snatalie li - Sun Microsystems - Irvine United States 		/* make second pass to handle '*' case */
788b89a8333Snatalie li - Sun Microsystems - Irvine United States 		if (none < 0) {
789b89a8333Snatalie li - Sun Microsystems - Irvine United States 			acc = SMB_SHRF_ACC_NONE;
790b89a8333Snatalie li - Sun Microsystems - Irvine United States 			if (ro > 0)
791b89a8333Snatalie li - Sun Microsystems - Irvine United States 				acc = SMB_SHRF_ACC_RO;
792b89a8333Snatalie li - Sun Microsystems - Irvine United States 			else if (rw > 0)
793b89a8333Snatalie li - Sun Microsystems - Irvine United States 				acc = SMB_SHRF_ACC_RW;
794b89a8333Snatalie li - Sun Microsystems - Irvine United States 		} else if (ro < 0) {
795b89a8333Snatalie li - Sun Microsystems - Irvine United States 			acc = SMB_SHRF_ACC_RO;
796b89a8333Snatalie li - Sun Microsystems - Irvine United States 			if (none > 0)
797b89a8333Snatalie li - Sun Microsystems - Irvine United States 				acc = SMB_SHRF_ACC_NONE;
798b89a8333Snatalie li - Sun Microsystems - Irvine United States 			else if (rw > 0)
799b89a8333Snatalie li - Sun Microsystems - Irvine United States 				acc = SMB_SHRF_ACC_RW;
800b89a8333Snatalie li - Sun Microsystems - Irvine United States 		} else if (rw < 0) {
801b89a8333Snatalie li - Sun Microsystems - Irvine United States 			acc = SMB_SHRF_ACC_RW;
802b89a8333Snatalie li - Sun Microsystems - Irvine United States 			if (none > 0)
803b89a8333Snatalie li - Sun Microsystems - Irvine United States 				acc = SMB_SHRF_ACC_NONE;
804b89a8333Snatalie li - Sun Microsystems - Irvine United States 			else if (ro > 0)
805b89a8333Snatalie li - Sun Microsystems - Irvine United States 				acc = SMB_SHRF_ACC_RO;
806b89a8333Snatalie li - Sun Microsystems - Irvine United States 		}
807b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
808148c5f43SAlan Wright 
809148c5f43SAlan Wright 	return (acc);
810b89a8333Snatalie li - Sun Microsystems - Irvine United States }
811b89a8333Snatalie li - Sun Microsystems - Irvine United States 
812b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
8133db3f65cSamw  * smb_shr_is_special
8143db3f65cSamw  *
815c8ec8eeaSjose borrego  * Special share reserved for interprocess communication (IPC$) or
816c8ec8eeaSjose borrego  * remote administration of the server (ADMIN$). Can also refer to
817c8ec8eeaSjose borrego  * administrative shares such as C$, D$, E$, and so forth.
8183db3f65cSamw  */
8193db3f65cSamw int
smb_shr_is_special(char * sharename)820c8ec8eeaSjose borrego smb_shr_is_special(char *sharename)
8213db3f65cSamw {
8223db3f65cSamw 	int len;
8233db3f65cSamw 
824c8ec8eeaSjose borrego 	if (sharename == NULL)
8253db3f65cSamw 		return (0);
8263db3f65cSamw 
827c8ec8eeaSjose borrego 	if ((len = strlen(sharename)) == 0)
8283db3f65cSamw 		return (0);
8293db3f65cSamw 
830c8ec8eeaSjose borrego 	if (sharename[len - 1] == '$')
8313db3f65cSamw 		return (STYPE_SPECIAL);
832c8ec8eeaSjose borrego 
8333db3f65cSamw 	return (0);
8343db3f65cSamw }
8353db3f65cSamw 
8363db3f65cSamw /*
8373db3f65cSamw  * smb_shr_is_restricted
8383db3f65cSamw  *
8393db3f65cSamw  * Check whether or not there is a restriction on a share. Restricted
8403db3f65cSamw  * shares are generally STYPE_SPECIAL, for example, IPC$. All the
841c8ec8eeaSjose borrego  * administration share names are restricted: C$, D$ etc. Returns B_TRUE
842c8ec8eeaSjose borrego  * if the share is restricted. Otherwise B_FALSE is returned to indicate
8433db3f65cSamw  * that there are no restrictions.
8443db3f65cSamw  */
845c8ec8eeaSjose borrego boolean_t
smb_shr_is_restricted(char * sharename)846c8ec8eeaSjose borrego smb_shr_is_restricted(char *sharename)
8473db3f65cSamw {
8483db3f65cSamw 	static char *restricted[] = {
8493db3f65cSamw 		"IPC$"
8503db3f65cSamw 	};
8513db3f65cSamw 
8523db3f65cSamw 	int i;
8533db3f65cSamw 
854c8ec8eeaSjose borrego 	if (sharename == NULL)
855c8ec8eeaSjose borrego 		return (B_FALSE);
856c8ec8eeaSjose borrego 
8573db3f65cSamw 	for (i = 0; i < sizeof (restricted)/sizeof (restricted[0]); i++) {
858bbf6f00cSJordan Brown 		if (smb_strcasecmp(restricted[i], sharename, 0) == 0)
859c8ec8eeaSjose borrego 			return (B_TRUE);
8603db3f65cSamw 	}
8613db3f65cSamw 
862c8ec8eeaSjose borrego 	return (smb_shr_is_admin(sharename));
8633db3f65cSamw }
8643db3f65cSamw 
8653db3f65cSamw /*
8663db3f65cSamw  * smb_shr_is_admin
8673db3f65cSamw  *
8683db3f65cSamw  * Check whether or not access to the share should be restricted to
8693db3f65cSamw  * administrators. This is a bit of a hack because what we're doing
8703db3f65cSamw  * is checking for the default admin shares: C$, D$ etc.. There are
8713db3f65cSamw  * other shares that have restrictions: see smb_shr_is_restricted().
8723db3f65cSamw  *
873c8ec8eeaSjose borrego  * Returns B_TRUE if the shares is an admin share. Otherwise B_FALSE
874c8ec8eeaSjose borrego  * is returned to indicate that there are no restrictions.
8753db3f65cSamw  */
876c8ec8eeaSjose borrego boolean_t
smb_shr_is_admin(char * sharename)877c8ec8eeaSjose borrego smb_shr_is_admin(char *sharename)
8783db3f65cSamw {
879c8ec8eeaSjose borrego 	if (sharename == NULL)
880c8ec8eeaSjose borrego 		return (B_FALSE);
8813db3f65cSamw 
882c8ec8eeaSjose borrego 	if (strlen(sharename) == 2 &&
883bbf6f00cSJordan Brown 	    smb_isalpha(sharename[0]) && sharename[1] == '$') {
884c8ec8eeaSjose borrego 		return (B_TRUE);
8853db3f65cSamw 	}
8863db3f65cSamw 
887c8ec8eeaSjose borrego 	return (B_FALSE);
8883db3f65cSamw }
8893db3f65cSamw 
890c5866007SKeyur Desai char
smb_shr_drive_letter(const char * path)891c5866007SKeyur Desai smb_shr_drive_letter(const char *path)
892c5866007SKeyur Desai {
893c5866007SKeyur Desai 	smb_transient_t	*ts;
894c5866007SKeyur Desai 	int i;
895c5866007SKeyur Desai 
896c5866007SKeyur Desai 	if (path == NULL)
897c5866007SKeyur Desai 		return ('\0');
898c5866007SKeyur Desai 
899c5866007SKeyur Desai 	for (i = 0; i < sizeof (tshare)/sizeof (tshare[0]); ++i) {
900c5866007SKeyur Desai 		ts = &tshare[i];
901c5866007SKeyur Desai 
902c5866007SKeyur Desai 		if (ts->path == NULL)
903c5866007SKeyur Desai 			continue;
904c5866007SKeyur Desai 
905c5866007SKeyur Desai 		if (strcasecmp(ts->path, path) == 0)
906c5866007SKeyur Desai 			return (ts->drive);
907c5866007SKeyur Desai 	}
908c5866007SKeyur Desai 
909c5866007SKeyur Desai 	return ('\0');
910c5866007SKeyur Desai }
911c5866007SKeyur Desai 
912c5866007SKeyur Desai /*
913c5866007SKeyur Desai  * Returns true if the specified directory is empty,
914c5866007SKeyur Desai  * otherwise returns false.
915c5866007SKeyur Desai  */
916c5866007SKeyur Desai static boolean_t
smb_shr_is_empty(const char * path)917c5866007SKeyur Desai smb_shr_is_empty(const char *path)
918c5866007SKeyur Desai {
919c5866007SKeyur Desai 	DIR *dirp;
920c5866007SKeyur Desai 	struct dirent *dp;
921c5866007SKeyur Desai 
922c5866007SKeyur Desai 	if (path == NULL)
923c5866007SKeyur Desai 		return (B_TRUE);
924c5866007SKeyur Desai 
925c5866007SKeyur Desai 	if ((dirp = opendir(path)) == NULL)
926c5866007SKeyur Desai 		return (B_TRUE);
927c5866007SKeyur Desai 
928c5866007SKeyur Desai 	while ((dp = readdir(dirp)) != NULL) {
929c5866007SKeyur Desai 		if (!smb_shr_is_dot_or_dotdot(dp->d_name))
930c5866007SKeyur Desai 			return (B_FALSE);
931c5866007SKeyur Desai 	}
932c5866007SKeyur Desai 
933c5866007SKeyur Desai 	(void) closedir(dirp);
934c5866007SKeyur Desai 	return (B_TRUE);
935c5866007SKeyur Desai }
936c5866007SKeyur Desai 
937c5866007SKeyur Desai /*
938c5866007SKeyur Desai  * Returns true if name is "." or "..", otherwise returns false.
939c5866007SKeyur Desai  */
940c5866007SKeyur Desai static boolean_t
smb_shr_is_dot_or_dotdot(const char * name)941c5866007SKeyur Desai smb_shr_is_dot_or_dotdot(const char *name)
942c5866007SKeyur Desai {
943c5866007SKeyur Desai 	if (*name != '.')
944c5866007SKeyur Desai 		return (B_FALSE);
945c5866007SKeyur Desai 
946c5866007SKeyur Desai 	if ((name[1] == '\0') || (name[1] == '.' && name[2] == '\0'))
947c5866007SKeyur Desai 		return (B_TRUE);
948c5866007SKeyur Desai 
949c5866007SKeyur Desai 	return (B_FALSE);
950c5866007SKeyur Desai }
951c5866007SKeyur Desai 
9523db3f65cSamw /*
9533db3f65cSamw  * smb_shr_get_realpath
9543db3f65cSamw  *
955b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Derive the real path for a share from the path provided by a client.
956b89a8333Snatalie li - Sun Microsystems - Irvine United States  * For instance, the real path of C:\ may be /cvol or the real path of
957b89a8333Snatalie li - Sun Microsystems - Irvine United States  * F:\home may be /vol1/home.
9583db3f65cSamw  *
959b89a8333Snatalie li - Sun Microsystems - Irvine United States  * clntpath - path provided by the Windows client is in the
9603db3f65cSamw  *            format of <drive letter>:\<dir>
9613db3f65cSamw  * realpath - path that will be stored as the directory field of
9623db3f65cSamw  *            the smb_share_t structure of the share.
963b89a8333Snatalie li - Sun Microsystems - Irvine United States  * maxlen   - maximum length of the realpath buffer
9643db3f65cSamw  *
9653db3f65cSamw  * Return LAN Manager network error code.
9663db3f65cSamw  */
9673db3f65cSamw uint32_t
smb_shr_get_realpath(const char * clntpath,char * realpath,int maxlen)968b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_get_realpath(const char *clntpath, char *realpath, int maxlen)
9693db3f65cSamw {
970b89a8333Snatalie li - Sun Microsystems - Irvine United States 	const char *p;
971b89a8333Snatalie li - Sun Microsystems - Irvine United States 	int len;
9723db3f65cSamw 
973b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if ((p = strchr(clntpath, ':')) != NULL)
974b89a8333Snatalie li - Sun Microsystems - Irvine United States 		++p;
975b89a8333Snatalie li - Sun Microsystems - Irvine United States 	else
976b89a8333Snatalie li - Sun Microsystems - Irvine United States 		p = clntpath;
977c8ec8eeaSjose borrego 
978b89a8333Snatalie li - Sun Microsystems - Irvine United States 	(void) strlcpy(realpath, p, maxlen);
979b89a8333Snatalie li - Sun Microsystems - Irvine United States 	(void) strcanon(realpath, "/\\");
980b89a8333Snatalie li - Sun Microsystems - Irvine United States 	(void) strsubst(realpath, '\\', '/');
981c8ec8eeaSjose borrego 
982b89a8333Snatalie li - Sun Microsystems - Irvine United States 	len = strlen(realpath);
983b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if ((len > 1) && (realpath[len - 1] == '/'))
984b89a8333Snatalie li - Sun Microsystems - Irvine United States 		realpath[len - 1] = '\0';
985c8ec8eeaSjose borrego 
986c8ec8eeaSjose borrego 	return (NERR_Success);
987c8ec8eeaSjose borrego }
988c8ec8eeaSjose borrego 
989b89a8333Snatalie li - Sun Microsystems - Irvine United States void
smb_shr_list(int offset,smb_shrlist_t * list)990b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_list(int offset, smb_shrlist_t *list)
991c8ec8eeaSjose borrego {
992b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_shriter_t iterator;
993b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_share_t *si;
994b89a8333Snatalie li - Sun Microsystems - Irvine United States 	int n = 0;
995c8ec8eeaSjose borrego 
996b89a8333Snatalie li - Sun Microsystems - Irvine United States 	bzero(list, sizeof (smb_shrlist_t));
997b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_shr_iterinit(&iterator);
998c8ec8eeaSjose borrego 
999b89a8333Snatalie li - Sun Microsystems - Irvine United States 	while ((si = smb_shr_iterate(&iterator)) != NULL) {
1000b89a8333Snatalie li - Sun Microsystems - Irvine United States 		if (--offset > 0)
1001c8ec8eeaSjose borrego 			continue;
1002c8ec8eeaSjose borrego 
1003b89a8333Snatalie li - Sun Microsystems - Irvine United States 		if ((si->shr_flags & SMB_SHRF_TRANS) &&
100429e6af5cSAlek Pinchuk 		    (!STYPE_ISIPC(si->shr_type))) {
1005b89a8333Snatalie li - Sun Microsystems - Irvine United States 			bcopy(si, &list->sl_shares[n], sizeof (smb_share_t));
1006b89a8333Snatalie li - Sun Microsystems - Irvine United States 			if (++n == LMSHARES_PER_REQUEST)
1007b89a8333Snatalie li - Sun Microsystems - Irvine United States 				break;
1008b89a8333Snatalie li - Sun Microsystems - Irvine United States 		}
1009c8ec8eeaSjose borrego 	}
1010c8ec8eeaSjose borrego 
1011b89a8333Snatalie li - Sun Microsystems - Irvine United States 	list->sl_cnt = n;
1012c8ec8eeaSjose borrego }
1013c8ec8eeaSjose borrego 
1014c8ec8eeaSjose borrego /*
101529bd2886SAlan Wright  * Executes the map/unmap command associated with a share.
101629bd2886SAlan Wright  *
101729bd2886SAlan Wright  * Returns 0 on success.  Otherwise non-zero for errors.
101829bd2886SAlan Wright  */
101929bd2886SAlan Wright int
smb_shr_exec(smb_shr_execinfo_t * subs)1020148c5f43SAlan Wright smb_shr_exec(smb_shr_execinfo_t *subs)
102129bd2886SAlan Wright {
102229bd2886SAlan Wright 	char cmd[MAXPATHLEN], **cmd_tokens, *path, *ptr;
102329bd2886SAlan Wright 	pid_t child_pid;
102429bd2886SAlan Wright 	int child_status;
102529bd2886SAlan Wright 	struct sigaction pact, cact;
102629bd2886SAlan Wright 	smb_share_t si;
102729bd2886SAlan Wright 
1028148c5f43SAlan Wright 	if (smb_shr_get(subs->e_sharename, &si) != 0)
102929bd2886SAlan Wright 		return (-1);
103029bd2886SAlan Wright 
103129bd2886SAlan Wright 	*cmd = '\0';
103229bd2886SAlan Wright 
103329bd2886SAlan Wright 	(void) mutex_lock(&smb_shr_exec_mtx);
103429bd2886SAlan Wright 
1035148c5f43SAlan Wright 	switch (subs->e_type) {
1036148c5f43SAlan Wright 	case SMB_EXEC_MAP:
103729bd2886SAlan Wright 		(void) strlcpy(cmd, smb_shr_exec_map, sizeof (cmd));
103829bd2886SAlan Wright 		break;
1039148c5f43SAlan Wright 	case SMB_EXEC_UNMAP:
104029bd2886SAlan Wright 		(void) strlcpy(cmd, smb_shr_exec_unmap, sizeof (cmd));
104129bd2886SAlan Wright 		break;
104229bd2886SAlan Wright 	default:
104329bd2886SAlan Wright 		(void) mutex_unlock(&smb_shr_exec_mtx);
104429bd2886SAlan Wright 		return (-1);
104529bd2886SAlan Wright 	}
104629bd2886SAlan Wright 
104729bd2886SAlan Wright 	(void) mutex_unlock(&smb_shr_exec_mtx);
104829bd2886SAlan Wright 
104929bd2886SAlan Wright 	if (*cmd == '\0')
105029bd2886SAlan Wright 		return (0);
105129bd2886SAlan Wright 
1052e3f2c991SKeyur Desai 	if (smb_proc_takesem() != 0)
1053e3f2c991SKeyur Desai 		return (-1);
1054e3f2c991SKeyur Desai 
105529bd2886SAlan Wright 	pact.sa_handler = smb_shr_sig_child;
105629bd2886SAlan Wright 	pact.sa_flags = 0;
105729bd2886SAlan Wright 	(void) sigemptyset(&pact.sa_mask);
105829bd2886SAlan Wright 	sigaction(SIGCHLD, &pact, NULL);
105929bd2886SAlan Wright 
106029bd2886SAlan Wright 	(void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_PROC_FORK, NULL);
106129bd2886SAlan Wright 
106229bd2886SAlan Wright 	if ((child_pid = fork()) == -1) {
106329bd2886SAlan Wright 		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_PROC_FORK, NULL);
1064e3f2c991SKeyur Desai 		smb_proc_givesem();
106529bd2886SAlan Wright 		return (-1);
106629bd2886SAlan Wright 	}
106729bd2886SAlan Wright 
106829bd2886SAlan Wright 	if (child_pid == 0) {
106929bd2886SAlan Wright 
107029bd2886SAlan Wright 		/* child process */
107129bd2886SAlan Wright 
107229bd2886SAlan Wright 		cact.sa_handler = smb_shr_sig_abnormal_term;
107329bd2886SAlan Wright 		cact.sa_flags = 0;
107429bd2886SAlan Wright 		(void) sigemptyset(&cact.sa_mask);
107529bd2886SAlan Wright 		sigaction(SIGTERM, &cact, NULL);
107629bd2886SAlan Wright 		sigaction(SIGABRT, &cact, NULL);
107729bd2886SAlan Wright 		sigaction(SIGSEGV, &cact, NULL);
107829bd2886SAlan Wright 
107929bd2886SAlan Wright 		if (priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_PROC_EXEC,
108029bd2886SAlan Wright 		    PRIV_FILE_DAC_EXECUTE, NULL))
108129bd2886SAlan Wright 			_exit(-1);
108229bd2886SAlan Wright 
108329bd2886SAlan Wright 		if (smb_shr_enable_all_privs())
108429bd2886SAlan Wright 			_exit(-1);
108529bd2886SAlan Wright 
1086e3f2c991SKeyur Desai 		smb_proc_initsem();
1087e3f2c991SKeyur Desai 
108829bd2886SAlan Wright 		(void) trim_whitespace(cmd);
108929bd2886SAlan Wright 		(void) strcanon(cmd, " ");
109029bd2886SAlan Wright 
109129bd2886SAlan Wright 		if ((cmd_tokens = smb_shr_tokenize_cmd(cmd)) != NULL) {
109229bd2886SAlan Wright 
109329bd2886SAlan Wright 			if (smb_shr_expand_subs(cmd_tokens, &si, subs) != 0) {
109429bd2886SAlan Wright 				free(cmd_tokens[0]);
109529bd2886SAlan Wright 				free(cmd_tokens);
109629bd2886SAlan Wright 				_exit(-1);
109729bd2886SAlan Wright 			}
109829bd2886SAlan Wright 
109929bd2886SAlan Wright 			ptr = cmd;
110029bd2886SAlan Wright 			path = strsep(&ptr, " ");
110129bd2886SAlan Wright 
110229bd2886SAlan Wright 			(void) execv(path, cmd_tokens);
110329bd2886SAlan Wright 		}
110429bd2886SAlan Wright 
110529bd2886SAlan Wright 		_exit(-1);
110629bd2886SAlan Wright 	}
110729bd2886SAlan Wright 
1108e3f2c991SKeyur Desai 	(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_PROC_FORK, NULL);
1109e3f2c991SKeyur Desai 	smb_proc_givesem();
1110e3f2c991SKeyur Desai 
111129bd2886SAlan Wright 	/* parent process */
111229bd2886SAlan Wright 
111329bd2886SAlan Wright 	while (waitpid(child_pid, &child_status, 0) < 0) {
111429bd2886SAlan Wright 		if (errno != EINTR)
111529bd2886SAlan Wright 			break;
111629bd2886SAlan Wright 
111729bd2886SAlan Wright 		/* continue if waitpid got interrupted by a signal */
111829bd2886SAlan Wright 		errno = 0;
111929bd2886SAlan Wright 		continue;
112029bd2886SAlan Wright 	}
112129bd2886SAlan Wright 
112229bd2886SAlan Wright 	if (WIFEXITED(child_status))
112329bd2886SAlan Wright 		return (WEXITSTATUS(child_status));
112429bd2886SAlan Wright 
112529bd2886SAlan Wright 	return (child_status);
112629bd2886SAlan Wright }
112729bd2886SAlan Wright 
112829bd2886SAlan Wright /*
1129e3f2c991SKeyur Desai  * Locking for process-wide settings (i.e. privileges)
1130e3f2c991SKeyur Desai  */
1131e3f2c991SKeyur Desai void
smb_proc_initsem(void)1132e3f2c991SKeyur Desai smb_proc_initsem(void)
1133e3f2c991SKeyur Desai {
1134e3f2c991SKeyur Desai 	(void) sema_init(&smb_proc_sem, 1, USYNC_THREAD, NULL);
1135e3f2c991SKeyur Desai }
1136e3f2c991SKeyur Desai 
1137e3f2c991SKeyur Desai int
smb_proc_takesem(void)1138e3f2c991SKeyur Desai smb_proc_takesem(void)
1139e3f2c991SKeyur Desai {
1140e3f2c991SKeyur Desai 	return (sema_wait(&smb_proc_sem));
1141e3f2c991SKeyur Desai }
1142e3f2c991SKeyur Desai 
1143e3f2c991SKeyur Desai void
smb_proc_givesem(void)1144e3f2c991SKeyur Desai smb_proc_givesem(void)
1145e3f2c991SKeyur Desai {
1146e3f2c991SKeyur Desai 	(void) sema_post(&smb_proc_sem);
1147e3f2c991SKeyur Desai }
1148e3f2c991SKeyur Desai 
1149e3f2c991SKeyur Desai /*
1150b89a8333Snatalie li - Sun Microsystems - Irvine United States  * ============================================
1151b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Private helper/utility functions
1152b89a8333Snatalie li - Sun Microsystems - Irvine United States  * ============================================
1153c8ec8eeaSjose borrego  */
1154c8ec8eeaSjose borrego 
1155c8ec8eeaSjose borrego /*
11568d7e4166Sjose borrego  * Looks up the given share in the cache and return
11578d7e4166Sjose borrego  * the info in 'si'
11588d7e4166Sjose borrego  */
11598d7e4166Sjose borrego static uint32_t
smb_shr_lookup(char * sharename,smb_share_t * si)11608d7e4166Sjose borrego smb_shr_lookup(char *sharename, smb_share_t *si)
11618d7e4166Sjose borrego {
11628d7e4166Sjose borrego 	smb_share_t *cached_si;
11638d7e4166Sjose borrego 	uint32_t status = NERR_NetNameNotFound;
11648d7e4166Sjose borrego 
11658d7e4166Sjose borrego 	if (sharename == NULL || *sharename == '\0')
11668d7e4166Sjose borrego 		return (NERR_NetNameNotFound);
11678d7e4166Sjose borrego 	if (smb_shr_cache_lock(SMB_SHR_CACHE_RDLOCK) == NERR_Success) {
11688d7e4166Sjose borrego 		cached_si = smb_shr_cache_findent(sharename);
11698d7e4166Sjose borrego 		if (cached_si != NULL) {
11708d7e4166Sjose borrego 			bcopy(cached_si, si, sizeof (smb_share_t));
11718d7e4166Sjose borrego 			status = NERR_Success;
11728d7e4166Sjose borrego 		}
11738d7e4166Sjose borrego 
11748d7e4166Sjose borrego 		smb_shr_cache_unlock();
11758d7e4166Sjose borrego 	}
11768d7e4166Sjose borrego 	return (status);
11778d7e4166Sjose borrego }
11788d7e4166Sjose borrego 
11798d7e4166Sjose borrego /*
11809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Add IPC$ or Admin shares to the cache upon startup.
1181c8ec8eeaSjose borrego  */
1182c8ec8eeaSjose borrego static uint32_t
smb_shr_add_transient(char * name,char * cmnt,char * path)11839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_shr_add_transient(char *name, char *cmnt, char *path)
1184c8ec8eeaSjose borrego {
11859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_share_t trans;
1186b89a8333Snatalie li - Sun Microsystems - Irvine United States 	uint32_t status = NERR_InternalError;
1187c8ec8eeaSjose borrego 
11889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (name == NULL)
11899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (status);
11909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	bzero(&trans, sizeof (smb_share_t));
11929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) strlcpy(trans.shr_name, name, MAXNAMELEN);
11939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (cmnt)
11949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		(void) strlcpy(trans.shr_cmnt, cmnt, SMB_SHARE_CMNT_MAX);
11959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (path)
11979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		(void) strlcpy(trans.shr_path, path, MAXPATHLEN);
11989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
11999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (strcasecmp(name, "IPC$") == 0)
12009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		trans.shr_type = STYPE_IPC;
12019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
12029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	trans.shr_flags = SMB_SHRF_TRANS;
1203c8ec8eeaSjose borrego 
1204b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (smb_shr_cache_lock(SMB_SHR_CACHE_WRLOCK) == NERR_Success) {
12059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		status = smb_shr_cache_addent(&trans);
1206b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache_unlock();
1207c8ec8eeaSjose borrego 	}
1208c8ec8eeaSjose borrego 
1209c8ec8eeaSjose borrego 	return (status);
1210c8ec8eeaSjose borrego }
1211c8ec8eeaSjose borrego 
1212c8ec8eeaSjose borrego /*
1213c8ec8eeaSjose borrego  * ============================================
1214b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Cache management functions
1215b89a8333Snatalie li - Sun Microsystems - Irvine United States  *
1216b89a8333Snatalie li - Sun Microsystems - Irvine United States  * All cache functions are private
1217c8ec8eeaSjose borrego  * ============================================
1218c8ec8eeaSjose borrego  */
1219c8ec8eeaSjose borrego 
1220c8ec8eeaSjose borrego /*
1221b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Create the share cache (hash table).
1222c8ec8eeaSjose borrego  */
1223c8ec8eeaSjose borrego static uint32_t
smb_shr_cache_create(void)1224b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_cache_create(void)
1225b89a8333Snatalie li - Sun Microsystems - Irvine United States {
1226b89a8333Snatalie li - Sun Microsystems - Irvine United States 	uint32_t status = NERR_Success;
1227b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1228b89a8333Snatalie li - Sun Microsystems - Irvine United States 	(void) mutex_lock(&smb_shr_cache.sc_mtx);
1229b89a8333Snatalie li - Sun Microsystems - Irvine United States 	switch (smb_shr_cache.sc_state) {
1230b89a8333Snatalie li - Sun Microsystems - Irvine United States 	case SMB_SHR_CACHE_STATE_NONE:
1231b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache.sc_cache = ht_create_table(SMB_SHR_HTAB_SZ,
1232b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    MAXNAMELEN, 0);
1233b89a8333Snatalie li - Sun Microsystems - Irvine United States 		if (smb_shr_cache.sc_cache == NULL) {
1234b89a8333Snatalie li - Sun Microsystems - Irvine United States 			status = NERR_InternalError;
1235b89a8333Snatalie li - Sun Microsystems - Irvine United States 			break;
1236b89a8333Snatalie li - Sun Microsystems - Irvine United States 		}
1237b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1238b89a8333Snatalie li - Sun Microsystems - Irvine United States 		(void) ht_register_callback(smb_shr_cache.sc_cache,
1239b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    smb_shr_cache_freent);
1240b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache.sc_nops = 0;
1241b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache.sc_state = SMB_SHR_CACHE_STATE_CREATED;
1242b89a8333Snatalie li - Sun Microsystems - Irvine United States 		break;
1243b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1244b89a8333Snatalie li - Sun Microsystems - Irvine United States 	default:
1245b89a8333Snatalie li - Sun Microsystems - Irvine United States 		assert(0);
1246b89a8333Snatalie li - Sun Microsystems - Irvine United States 		status = NERR_InternalError;
1247b89a8333Snatalie li - Sun Microsystems - Irvine United States 		break;
1248b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
1249b89a8333Snatalie li - Sun Microsystems - Irvine United States 	(void) mutex_unlock(&smb_shr_cache.sc_mtx);
1250b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1251b89a8333Snatalie li - Sun Microsystems - Irvine United States 	return (status);
1252b89a8333Snatalie li - Sun Microsystems - Irvine United States }
1253b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1254b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
1255b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Destroy the share cache (hash table).
1256b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Wait for inflight/pending operations to finish or abort before
1257b89a8333Snatalie li - Sun Microsystems - Irvine United States  * destroying the cache.
1258b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
1259b89a8333Snatalie li - Sun Microsystems - Irvine United States static void
smb_shr_cache_destroy(void)1260b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_cache_destroy(void)
1261b89a8333Snatalie li - Sun Microsystems - Irvine United States {
1262b89a8333Snatalie li - Sun Microsystems - Irvine United States 	(void) mutex_lock(&smb_shr_cache.sc_mtx);
1263b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (smb_shr_cache.sc_state == SMB_SHR_CACHE_STATE_CREATED) {
1264b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache.sc_state = SMB_SHR_CACHE_STATE_DESTROYING;
1265b89a8333Snatalie li - Sun Microsystems - Irvine United States 		while (smb_shr_cache.sc_nops > 0)
1266b89a8333Snatalie li - Sun Microsystems - Irvine United States 			(void) cond_wait(&smb_shr_cache.sc_cv,
1267b89a8333Snatalie li - Sun Microsystems - Irvine United States 			    &smb_shr_cache.sc_mtx);
1268b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1269b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache.sc_cache = NULL;
1270b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache.sc_state = SMB_SHR_CACHE_STATE_NONE;
1271b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
1272b89a8333Snatalie li - Sun Microsystems - Irvine United States 	(void) mutex_unlock(&smb_shr_cache.sc_mtx);
1273b89a8333Snatalie li - Sun Microsystems - Irvine United States }
1274b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1275b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
1276b89a8333Snatalie li - Sun Microsystems - Irvine United States  * If the cache is in "created" state, lock the cache for read
1277b89a8333Snatalie li - Sun Microsystems - Irvine United States  * or read/write based on the specified mode.
1278b89a8333Snatalie li - Sun Microsystems - Irvine United States  *
1279b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Whenever a lock is granted, the number of inflight cache
1280b89a8333Snatalie li - Sun Microsystems - Irvine United States  * operations is incremented.
1281b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
1282b89a8333Snatalie li - Sun Microsystems - Irvine United States static uint32_t
smb_shr_cache_lock(int mode)1283b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_cache_lock(int mode)
1284b89a8333Snatalie li - Sun Microsystems - Irvine United States {
1285b89a8333Snatalie li - Sun Microsystems - Irvine United States 	(void) mutex_lock(&smb_shr_cache.sc_mtx);
12868d7e4166Sjose borrego 	if (smb_shr_cache.sc_state != SMB_SHR_CACHE_STATE_CREATED) {
1287b89a8333Snatalie li - Sun Microsystems - Irvine United States 		(void) mutex_unlock(&smb_shr_cache.sc_mtx);
1288b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (NERR_InternalError);
1289b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
12908d7e4166Sjose borrego 	smb_shr_cache.sc_nops++;
1291b89a8333Snatalie li - Sun Microsystems - Irvine United States 	(void) mutex_unlock(&smb_shr_cache.sc_mtx);
1292b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1293b89a8333Snatalie li - Sun Microsystems - Irvine United States 	/*
1294b89a8333Snatalie li - Sun Microsystems - Irvine United States 	 * Lock has to be taken outside the mutex otherwise
1295b89a8333Snatalie li - Sun Microsystems - Irvine United States 	 * there could be a deadlock
1296b89a8333Snatalie li - Sun Microsystems - Irvine United States 	 */
1297b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (mode == SMB_SHR_CACHE_RDLOCK)
1298b89a8333Snatalie li - Sun Microsystems - Irvine United States 		(void) rw_rdlock(&smb_shr_cache.sc_cache_lck);
1299b89a8333Snatalie li - Sun Microsystems - Irvine United States 	else
1300b89a8333Snatalie li - Sun Microsystems - Irvine United States 		(void) rw_wrlock(&smb_shr_cache.sc_cache_lck);
1301b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1302b89a8333Snatalie li - Sun Microsystems - Irvine United States 	return (NERR_Success);
1303b89a8333Snatalie li - Sun Microsystems - Irvine United States }
1304b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1305b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
1306b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Decrement the number of inflight operations and then unlock.
1307b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
1308b89a8333Snatalie li - Sun Microsystems - Irvine United States static void
smb_shr_cache_unlock(void)1309b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_cache_unlock(void)
1310b89a8333Snatalie li - Sun Microsystems - Irvine United States {
1311b89a8333Snatalie li - Sun Microsystems - Irvine United States 	(void) mutex_lock(&smb_shr_cache.sc_mtx);
1312b89a8333Snatalie li - Sun Microsystems - Irvine United States 	assert(smb_shr_cache.sc_nops > 0);
1313b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_shr_cache.sc_nops--;
1314b89a8333Snatalie li - Sun Microsystems - Irvine United States 	(void) cond_broadcast(&smb_shr_cache.sc_cv);
1315b89a8333Snatalie li - Sun Microsystems - Irvine United States 	(void) mutex_unlock(&smb_shr_cache.sc_mtx);
1316b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1317b89a8333Snatalie li - Sun Microsystems - Irvine United States 	(void) rw_unlock(&smb_shr_cache.sc_cache_lck);
1318b89a8333Snatalie li - Sun Microsystems - Irvine United States }
1319b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1320b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
1321b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Return the total number of shares
1322b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
1323b89a8333Snatalie li - Sun Microsystems - Irvine United States static int
smb_shr_cache_count(void)1324b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_cache_count(void)
1325b89a8333Snatalie li - Sun Microsystems - Irvine United States {
1326b89a8333Snatalie li - Sun Microsystems - Irvine United States 	return (ht_get_total_items(smb_shr_cache.sc_cache));
1327b89a8333Snatalie li - Sun Microsystems - Irvine United States }
1328b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1329b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
1330b89a8333Snatalie li - Sun Microsystems - Irvine United States  * looks up the given share name in the cache and if it
1331b89a8333Snatalie li - Sun Microsystems - Irvine United States  * finds a match returns a pointer to the cached entry.
1332b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Note that since a pointer is returned this function
1333b89a8333Snatalie li - Sun Microsystems - Irvine United States  * MUST be protected by smb_shr_cache_lock/unlock pair
1334b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
1335b89a8333Snatalie li - Sun Microsystems - Irvine United States static smb_share_t *
smb_shr_cache_findent(char * sharename)1336b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_cache_findent(char *sharename)
1337b89a8333Snatalie li - Sun Microsystems - Irvine United States {
1338b89a8333Snatalie li - Sun Microsystems - Irvine United States 	HT_ITEM *item;
1339b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1340bbf6f00cSJordan Brown 	(void) smb_strlwr(sharename);
1341b89a8333Snatalie li - Sun Microsystems - Irvine United States 	item = ht_find_item(smb_shr_cache.sc_cache, sharename);
1342b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (item && item->hi_data)
1343b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return ((smb_share_t *)item->hi_data);
1344b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1345b89a8333Snatalie li - Sun Microsystems - Irvine United States 	return (NULL);
1346b89a8333Snatalie li - Sun Microsystems - Irvine United States }
1347b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1348b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
1349b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Return a pointer to the first/next entry in
1350b89a8333Snatalie li - Sun Microsystems - Irvine United States  * the cache based on the given iterator.
1351b89a8333Snatalie li - Sun Microsystems - Irvine United States  *
1352b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Calls to this function MUST be protected by
1353b89a8333Snatalie li - Sun Microsystems - Irvine United States  * smb_shr_cache_lock/unlock.
1354b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
1355b89a8333Snatalie li - Sun Microsystems - Irvine United States static smb_share_t *
smb_shr_cache_iterate(smb_shriter_t * shi)1356b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_cache_iterate(smb_shriter_t *shi)
1357b89a8333Snatalie li - Sun Microsystems - Irvine United States {
1358b89a8333Snatalie li - Sun Microsystems - Irvine United States 	HT_ITEM *item;
1359b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1360b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (shi->si_first) {
1361b89a8333Snatalie li - Sun Microsystems - Irvine United States 		item = ht_findfirst(smb_shr_cache.sc_cache, &shi->si_hashiter);
1362b89a8333Snatalie li - Sun Microsystems - Irvine United States 		shi->si_first = B_FALSE;
1363b89a8333Snatalie li - Sun Microsystems - Irvine United States 	} else {
1364b89a8333Snatalie li - Sun Microsystems - Irvine United States 		item = ht_findnext(&shi->si_hashiter);
1365b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
1366b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1367b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (item && item->hi_data)
1368b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return ((smb_share_t *)item->hi_data);
1369b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1370b89a8333Snatalie li - Sun Microsystems - Irvine United States 	return (NULL);
1371b89a8333Snatalie li - Sun Microsystems - Irvine United States }
1372b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1373b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
1374b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Add the specified share to the cache.  Memory needs to be allocated
1375b89a8333Snatalie li - Sun Microsystems - Irvine United States  * for the cache entry and the passed information is copied to the
1376b89a8333Snatalie li - Sun Microsystems - Irvine United States  * allocated space.
1377b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
1378b89a8333Snatalie li - Sun Microsystems - Irvine United States static uint32_t
smb_shr_cache_addent(smb_share_t * si)1379b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_cache_addent(smb_share_t *si)
1380b89a8333Snatalie li - Sun Microsystems - Irvine United States {
1381b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_share_t *cache_ent;
1382b89a8333Snatalie li - Sun Microsystems - Irvine United States 	uint32_t status = NERR_Success;
1383b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1384b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if ((cache_ent = malloc(sizeof (smb_share_t))) == NULL)
1385b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (ERROR_NOT_ENOUGH_MEMORY);
1386b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1387148c5f43SAlan Wright 	(void) smb_strlwr(si->shr_name);
1388b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1389148c5f43SAlan Wright 	si->shr_type |= smb_shr_is_special(cache_ent->shr_name);
1390b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1391b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (smb_shr_is_admin(cache_ent->shr_name))
1392148c5f43SAlan Wright 		si->shr_flags |= SMB_SHRF_ADMIN;
1393148c5f43SAlan Wright 
1394148c5f43SAlan Wright 	bcopy(si, cache_ent, sizeof (smb_share_t));
1395b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1396b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (si->shr_flags & SMB_SHRF_AUTOHOME)
1397b89a8333Snatalie li - Sun Microsystems - Irvine United States 		cache_ent->shr_refcnt = 1;
1398b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1399b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (ht_add_item(smb_shr_cache.sc_cache, cache_ent->shr_name, cache_ent)
1400b89a8333Snatalie li - Sun Microsystems - Irvine United States 	    == NULL) {
1401b89a8333Snatalie li - Sun Microsystems - Irvine United States 		syslog(LOG_DEBUG, "share: %s: cache update failed",
1402b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    cache_ent->shr_name);
1403b89a8333Snatalie li - Sun Microsystems - Irvine United States 		free(cache_ent);
1404b89a8333Snatalie li - Sun Microsystems - Irvine United States 		status = NERR_InternalError;
1405b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
1406b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1407b89a8333Snatalie li - Sun Microsystems - Irvine United States 	return (status);
1408b89a8333Snatalie li - Sun Microsystems - Irvine United States }
1409b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1410b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
1411b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Delete the specified share from the cache.
1412b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
1413b89a8333Snatalie li - Sun Microsystems - Irvine United States static void
smb_shr_cache_delent(char * sharename)1414b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_cache_delent(char *sharename)
1415b89a8333Snatalie li - Sun Microsystems - Irvine United States {
1416bbf6f00cSJordan Brown 	(void) smb_strlwr(sharename);
1417b89a8333Snatalie li - Sun Microsystems - Irvine United States 	(void) ht_remove_item(smb_shr_cache.sc_cache, sharename);
1418b89a8333Snatalie li - Sun Microsystems - Irvine United States }
1419b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1420b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
1421b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Call back to free the given cache entry.
1422b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
1423b89a8333Snatalie li - Sun Microsystems - Irvine United States static void
smb_shr_cache_freent(HT_ITEM * item)1424b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_cache_freent(HT_ITEM *item)
1425b89a8333Snatalie li - Sun Microsystems - Irvine United States {
1426b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (item && item->hi_data)
1427b89a8333Snatalie li - Sun Microsystems - Irvine United States 		free(item->hi_data);
1428b89a8333Snatalie li - Sun Microsystems - Irvine United States }
1429b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1430b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
1431b89a8333Snatalie li - Sun Microsystems - Irvine United States  * ============================================
1432b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Interfaces to sharemgr
1433b89a8333Snatalie li - Sun Microsystems - Irvine United States  *
1434b89a8333Snatalie li - Sun Microsystems - Irvine United States  * All functions in this section are private
1435b89a8333Snatalie li - Sun Microsystems - Irvine United States  * ============================================
1436b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
1437b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1438b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
1439b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Load shares from sharemgr
1440b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
1441b89a8333Snatalie li - Sun Microsystems - Irvine United States /*ARGSUSED*/
1442fd9ee8b5Sjoyce mcintosh void *
smb_shr_load(void * args)1443fd9ee8b5Sjoyce mcintosh smb_shr_load(void *args)
1444c8ec8eeaSjose borrego {
1445c8ec8eeaSjose borrego 	sa_handle_t handle;
1446b89a8333Snatalie li - Sun Microsystems - Irvine United States 	sa_group_t group, subgroup;
1447b89a8333Snatalie li - Sun Microsystems - Irvine United States 	char *gstate;
1448b89a8333Snatalie li - Sun Microsystems - Irvine United States 	boolean_t gdisabled;
1449fd9ee8b5Sjoyce mcintosh 
1450fd9ee8b5Sjoyce mcintosh 	(void) mutex_lock(&smb_shr_exec_mtx);
1451fd9ee8b5Sjoyce mcintosh 	(void) smb_config_get_execinfo(smb_shr_exec_map, smb_shr_exec_unmap,
1452fd9ee8b5Sjoyce mcintosh 	    MAXPATHLEN);
1453fd9ee8b5Sjoyce mcintosh 	(void) mutex_unlock(&smb_shr_exec_mtx);
1454b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1455cb174861Sjoyce mcintosh 	if ((handle = smb_shr_sa_enter()) == NULL) {
1456fd9ee8b5Sjoyce mcintosh 		syslog(LOG_ERR, "smb_shr_load: load failed");
1457b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (NULL);
1458cb174861Sjoyce mcintosh 	}
1459b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1460b89a8333Snatalie li - Sun Microsystems - Irvine United States 	for (group = sa_get_group(handle, NULL);
1461b89a8333Snatalie li - Sun Microsystems - Irvine United States 	    group != NULL; group = sa_get_next_group(group)) {
1462b89a8333Snatalie li - Sun Microsystems - Irvine United States 		gstate = sa_get_group_attr(group, "state");
1463b89a8333Snatalie li - Sun Microsystems - Irvine United States 		if (gstate == NULL)
1464b89a8333Snatalie li - Sun Microsystems - Irvine United States 			continue;
1465b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1466b89a8333Snatalie li - Sun Microsystems - Irvine United States 		gdisabled = (strcasecmp(gstate, "disabled") == 0);
1467b89a8333Snatalie li - Sun Microsystems - Irvine United States 		sa_free_attr_string(gstate);
1468b89a8333Snatalie li - Sun Microsystems - Irvine United States 		if (gdisabled)
1469b89a8333Snatalie li - Sun Microsystems - Irvine United States 			continue;
1470b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1471b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_sa_loadgrp(group);
1472b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1473b89a8333Snatalie li - Sun Microsystems - Irvine United States 		for (subgroup = sa_get_sub_group(group);
1474b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    subgroup != NULL;
1475b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    subgroup = sa_get_next_group(subgroup)) {
1476b89a8333Snatalie li - Sun Microsystems - Irvine United States 			smb_shr_sa_loadgrp(subgroup);
1477b89a8333Snatalie li - Sun Microsystems - Irvine United States 		}
1478b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1479b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
148089dc44ceSjose borrego 	smb_shr_sa_exit();
1481b89a8333Snatalie li - Sun Microsystems - Irvine United States 	return (NULL);
1482b89a8333Snatalie li - Sun Microsystems - Irvine United States }
1483b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1484b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
1485b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Load the shares contained in the specified group.
1486b89a8333Snatalie li - Sun Microsystems - Irvine United States  *
1487b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Don't process groups on which the smb protocol is disabled.
1488b89a8333Snatalie li - Sun Microsystems - Irvine United States  * The top level ZFS group won't have the smb protocol enabled
1489b89a8333Snatalie li - Sun Microsystems - Irvine United States  * but sub-groups will.
1490b89a8333Snatalie li - Sun Microsystems - Irvine United States  *
1491b89a8333Snatalie li - Sun Microsystems - Irvine United States  * We will tolerate a limited number of errors and then give
1492b89a8333Snatalie li - Sun Microsystems - Irvine United States  * up on the current group.  A typical error might be that the
1493b89a8333Snatalie li - Sun Microsystems - Irvine United States  * shared directory no longer exists.
1494b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
1495b89a8333Snatalie li - Sun Microsystems - Irvine United States static void
smb_shr_sa_loadgrp(sa_group_t group)1496b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_sa_loadgrp(sa_group_t group)
1497b89a8333Snatalie li - Sun Microsystems - Irvine United States {
1498c8ec8eeaSjose borrego 	sa_share_t share;
1499c8ec8eeaSjose borrego 	sa_resource_t resource;
1500b89a8333Snatalie li - Sun Microsystems - Irvine United States 	int error_count = 0;
1501c8ec8eeaSjose borrego 
1502b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (sa_get_optionset(group, SMB_PROTOCOL_NAME) == NULL)
1503b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return;
1504c8ec8eeaSjose borrego 
1505b89a8333Snatalie li - Sun Microsystems - Irvine United States 	for (share = sa_get_share(group, NULL);
1506b89a8333Snatalie li - Sun Microsystems - Irvine United States 	    share != NULL;
1507b89a8333Snatalie li - Sun Microsystems - Irvine United States 	    share = sa_get_next_share(share)) {
1508b89a8333Snatalie li - Sun Microsystems - Irvine United States 		for (resource = sa_get_share_resource(share, NULL);
1509b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    resource != NULL;
1510b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    resource = sa_get_next_resource(resource)) {
1511b89a8333Snatalie li - Sun Microsystems - Irvine United States 			if (smb_shr_sa_load(share, resource))
1512b89a8333Snatalie li - Sun Microsystems - Irvine United States 				++error_count;
1513b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1514b89a8333Snatalie li - Sun Microsystems - Irvine United States 			if (error_count > SMB_SHR_ERROR_THRESHOLD)
1515b89a8333Snatalie li - Sun Microsystems - Irvine United States 				break;
1516c8ec8eeaSjose borrego 		}
1517c8ec8eeaSjose borrego 
1518b89a8333Snatalie li - Sun Microsystems - Irvine United States 		if (error_count > SMB_SHR_ERROR_THRESHOLD)
1519b89a8333Snatalie li - Sun Microsystems - Irvine United States 			break;
1520c8ec8eeaSjose borrego 	}
1521c8ec8eeaSjose borrego }
1522c8ec8eeaSjose borrego 
1523b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
1524b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Load a share definition from sharemgr and add it to the cache.
15258d7e4166Sjose borrego  * If the share is already in the cache then it doesn't do anything.
15268d7e4166Sjose borrego  *
15278d7e4166Sjose borrego  * This function does not report duplicate shares as error since
15288d7e4166Sjose borrego  * a share might have been added by smb_shr_get() while load is
15298d7e4166Sjose borrego  * in progress.
1530b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
1531c8ec8eeaSjose borrego static uint32_t
smb_shr_sa_load(sa_share_t share,sa_resource_t resource)1532b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_sa_load(sa_share_t share, sa_resource_t resource)
1533b89a8333Snatalie li - Sun Microsystems - Irvine United States {
1534b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_share_t si;
15358d7e4166Sjose borrego 	char *sharename;
1536b89a8333Snatalie li - Sun Microsystems - Irvine United States 	uint32_t status;
15378d7e4166Sjose borrego 	boolean_t loaded;
15388d7e4166Sjose borrego 
15398d7e4166Sjose borrego 	if ((sharename = sa_get_resource_attr(resource, "name")) == NULL)
15408d7e4166Sjose borrego 		return (NERR_InternalError);
15418d7e4166Sjose borrego 
15428d7e4166Sjose borrego 	loaded = smb_shr_exists(sharename);
15438d7e4166Sjose borrego 	sa_free_attr_string(sharename);
15448d7e4166Sjose borrego 
15458d7e4166Sjose borrego 	if (loaded)
15468d7e4166Sjose borrego 		return (NERR_Success);
1547b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1548b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if ((status = smb_shr_sa_get(share, resource, &si)) != NERR_Success) {
1549b89a8333Snatalie li - Sun Microsystems - Irvine United States 		syslog(LOG_DEBUG, "share: failed to load %s (%d)",
1550b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    si.shr_name, status);
1551b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (status);
1552b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
1553b89a8333Snatalie li - Sun Microsystems - Irvine United States 
15548d7e4166Sjose borrego 	status = smb_shr_add(&si);
15558d7e4166Sjose borrego 	if ((status != NERR_Success) && (status != NERR_DuplicateShare)) {
1556b89a8333Snatalie li - Sun Microsystems - Irvine United States 		syslog(LOG_DEBUG, "share: failed to cache %s (%d)",
1557b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    si.shr_name, status);
1558b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (status);
1559b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
1560b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1561b89a8333Snatalie li - Sun Microsystems - Irvine United States 	return (NERR_Success);
1562b89a8333Snatalie li - Sun Microsystems - Irvine United States }
1563b89a8333Snatalie li - Sun Microsystems - Irvine United States 
15649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static char *
smb_shr_sa_getprop(sa_optionset_t opts,char * propname)15659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_shr_sa_getprop(sa_optionset_t opts, char *propname)
15669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
15679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	sa_property_t prop;
15689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	char *val = NULL;
15699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
15709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	prop = sa_get_property(opts, propname);
15719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (prop != NULL)
15729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		val = sa_get_property_attr(prop, "value");
15739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
15749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (val);
15759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
15769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1577b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
1578b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Read the specified share information from sharemgr and return
1579b89a8333Snatalie li - Sun Microsystems - Irvine United States  * it in the given smb_share_t structure.
1580b89a8333Snatalie li - Sun Microsystems - Irvine United States  *
1581b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Shares read from sharemgr are marked as permanent/persistent.
1582b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
1583b89a8333Snatalie li - Sun Microsystems - Irvine United States static uint32_t
smb_shr_sa_get(sa_share_t share,sa_resource_t resource,smb_share_t * si)1584b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_sa_get(sa_share_t share, sa_resource_t resource, smb_share_t *si)
1585c8ec8eeaSjose borrego {
1586c8ec8eeaSjose borrego 	sa_optionset_t opts;
1587c8ec8eeaSjose borrego 	char *val = NULL;
1588c8ec8eeaSjose borrego 	char *path;
1589c8ec8eeaSjose borrego 	char *rname;
1590c8ec8eeaSjose borrego 
1591c8ec8eeaSjose borrego 	if ((path = sa_get_share_attr(share, "path")) == NULL)
1592c8ec8eeaSjose borrego 		return (NERR_InternalError);
1593c8ec8eeaSjose borrego 
1594c8ec8eeaSjose borrego 	if ((rname = sa_get_resource_attr(resource, "name")) == NULL) {
1595c8ec8eeaSjose borrego 		sa_free_attr_string(path);
1596c8ec8eeaSjose borrego 		return (NERR_InternalError);
1597c8ec8eeaSjose borrego 	}
1598c8ec8eeaSjose borrego 
1599c8ec8eeaSjose borrego 	bzero(si, sizeof (smb_share_t));
1600c8ec8eeaSjose borrego 	si->shr_flags = SMB_SHRF_PERM;
1601c8ec8eeaSjose borrego 
1602c8ec8eeaSjose borrego 	(void) strlcpy(si->shr_path, path, sizeof (si->shr_path));
1603c8ec8eeaSjose borrego 	(void) strlcpy(si->shr_name, rname, sizeof (si->shr_name));
1604c8ec8eeaSjose borrego 	sa_free_attr_string(path);
1605c8ec8eeaSjose borrego 	sa_free_attr_string(rname);
1606c8ec8eeaSjose borrego 
1607c8ec8eeaSjose borrego 	val = sa_get_resource_description(resource);
1608c8ec8eeaSjose borrego 	if (val == NULL)
1609c8ec8eeaSjose borrego 		val = sa_get_share_description(share);
1610c8ec8eeaSjose borrego 
1611c8ec8eeaSjose borrego 	if (val != NULL) {
1612c8ec8eeaSjose borrego 		(void) strlcpy(si->shr_cmnt, val, sizeof (si->shr_cmnt));
1613c8ec8eeaSjose borrego 		sa_free_share_description(val);
1614c8ec8eeaSjose borrego 	}
1615c8ec8eeaSjose borrego 
1616c8ec8eeaSjose borrego 	opts = sa_get_derived_optionset(resource, SMB_PROTOCOL_NAME, 1);
1617c8ec8eeaSjose borrego 	if (opts == NULL)
1618c8ec8eeaSjose borrego 		return (NERR_Success);
1619c8ec8eeaSjose borrego 
16209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	val = smb_shr_sa_getprop(opts, SHOPT_AD_CONTAINER);
16219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (val != NULL) {
1622c8ec8eeaSjose borrego 		(void) strlcpy(si->shr_container, val,
1623c8ec8eeaSjose borrego 		    sizeof (si->shr_container));
1624c8ec8eeaSjose borrego 		free(val);
1625c8ec8eeaSjose borrego 	}
1626b89a8333Snatalie li - Sun Microsystems - Irvine United States 
16279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	val = smb_shr_sa_getprop(opts, SHOPT_CATIA);
16289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (val != NULL) {
16299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_shr_sa_setflag(val, si, SMB_SHRF_CATIA);
16308b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		free(val);
16318b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	}
16328b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 
16339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	val = smb_shr_sa_getprop(opts, SHOPT_ABE);
16349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (val != NULL) {
16359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_shr_sa_setflag(val, si, SMB_SHRF_ABE);
1636e3f2c991SKeyur Desai 		free(val);
1637e3f2c991SKeyur Desai 	}
16389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
16399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	val = smb_shr_sa_getprop(opts, SHOPT_GUEST);
16409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (val != NULL) {
16419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_shr_sa_setflag(val, si, SMB_SHRF_GUEST_OK);
16429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		free(val);
1643e3f2c991SKeyur Desai 	}
1644e3f2c991SKeyur Desai 
16459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	val = smb_shr_sa_getprop(opts, SHOPT_DFSROOT);
16469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (val != NULL) {
16479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_shr_sa_setflag(val, si, SMB_SHRF_DFSROOT);
16489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		free(val);
16499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
16509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
16519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	val = smb_shr_sa_getprop(opts, SHOPT_CSC);
16529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (val != NULL) {
16538d7e4166Sjose borrego 		smb_shr_sa_csc_option(val, si);
16548d7e4166Sjose borrego 		free(val);
16558d7e4166Sjose borrego 	}
16568d7e4166Sjose borrego 
16579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	val = smb_shr_sa_getprop(opts, SHOPT_NONE);
16589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (val != NULL) {
1659b89a8333Snatalie li - Sun Microsystems - Irvine United States 		(void) strlcpy(si->shr_access_none, val,
1660b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    sizeof (si->shr_access_none));
1661b89a8333Snatalie li - Sun Microsystems - Irvine United States 		free(val);
1662b89a8333Snatalie li - Sun Microsystems - Irvine United States 		si->shr_flags |= SMB_SHRF_ACC_NONE;
1663b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
1664b89a8333Snatalie li - Sun Microsystems - Irvine United States 
16659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	val = smb_shr_sa_getprop(opts, SHOPT_RO);
16669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (val != NULL) {
1667b89a8333Snatalie li - Sun Microsystems - Irvine United States 		(void) strlcpy(si->shr_access_ro, val,
1668b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    sizeof (si->shr_access_ro));
1669b89a8333Snatalie li - Sun Microsystems - Irvine United States 		free(val);
1670b89a8333Snatalie li - Sun Microsystems - Irvine United States 		si->shr_flags |= SMB_SHRF_ACC_RO;
1671b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
1672b89a8333Snatalie li - Sun Microsystems - Irvine United States 
16739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	val = smb_shr_sa_getprop(opts, SHOPT_RW);
16749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (val != NULL) {
1675b89a8333Snatalie li - Sun Microsystems - Irvine United States 		(void) strlcpy(si->shr_access_rw, val,
1676b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    sizeof (si->shr_access_rw));
1677b89a8333Snatalie li - Sun Microsystems - Irvine United States 		free(val);
1678b89a8333Snatalie li - Sun Microsystems - Irvine United States 		si->shr_flags |= SMB_SHRF_ACC_RW;
1679b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
1680b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1681c8ec8eeaSjose borrego 	sa_free_derived_optionset(opts);
1682c8ec8eeaSjose borrego 	return (NERR_Success);
1683c8ec8eeaSjose borrego }
1684c8ec8eeaSjose borrego 
1685c8ec8eeaSjose borrego /*
16868d7e4166Sjose borrego  * Map a client-side caching (CSC) option to the appropriate share
16878d7e4166Sjose borrego  * flag.  Only one option is allowed; an error will be logged if
16888d7e4166Sjose borrego  * multiple options have been specified.  We don't need to do anything
16898d7e4166Sjose borrego  * about multiple values here because the SRVSVC will not recognize
16908d7e4166Sjose borrego  * a value containing multiple flags and will return the default value.
16918d7e4166Sjose borrego  *
16928d7e4166Sjose borrego  * If the option value is not recognized, it will be ignored: invalid
16938d7e4166Sjose borrego  * values will typically be caught and rejected by sharemgr.
16948d7e4166Sjose borrego  */
169589dc44ceSjose borrego void
smb_shr_sa_csc_option(const char * value,smb_share_t * si)16968d7e4166Sjose borrego smb_shr_sa_csc_option(const char *value, smb_share_t *si)
16978d7e4166Sjose borrego {
16988d7e4166Sjose borrego 	int i;
16998d7e4166Sjose borrego 
17008d7e4166Sjose borrego 	for (i = 0; i < (sizeof (cscopt) / sizeof (cscopt[0])); ++i) {
17018d7e4166Sjose borrego 		if (strcasecmp(value, cscopt[i].value) == 0) {
17028d7e4166Sjose borrego 			si->shr_flags |= cscopt[i].flag;
17038d7e4166Sjose borrego 			break;
17048d7e4166Sjose borrego 		}
17058d7e4166Sjose borrego 	}
17068d7e4166Sjose borrego 
17078d7e4166Sjose borrego 	switch (si->shr_flags & SMB_SHRF_CSC_MASK) {
17088d7e4166Sjose borrego 	case 0:
17098d7e4166Sjose borrego 	case SMB_SHRF_CSC_DISABLED:
17108d7e4166Sjose borrego 	case SMB_SHRF_CSC_MANUAL:
17118d7e4166Sjose borrego 	case SMB_SHRF_CSC_AUTO:
17128d7e4166Sjose borrego 	case SMB_SHRF_CSC_VDO:
17138d7e4166Sjose borrego 		break;
17148d7e4166Sjose borrego 
17158d7e4166Sjose borrego 	default:
171689dc44ceSjose borrego 		syslog(LOG_INFO, "csc option conflict: 0x%08x",
171789dc44ceSjose borrego 		    si->shr_flags & SMB_SHRF_CSC_MASK);
17188d7e4166Sjose borrego 		break;
17198d7e4166Sjose borrego 	}
17208d7e4166Sjose borrego }
17218d7e4166Sjose borrego 
17228d7e4166Sjose borrego /*
172329bd2886SAlan Wright  * Return the option name for the first CSC flag (there should be only
172429bd2886SAlan Wright  * one) encountered in the share flags.
172529bd2886SAlan Wright  */
172629bd2886SAlan Wright char *
smb_shr_sa_csc_name(const smb_share_t * si)172729bd2886SAlan Wright smb_shr_sa_csc_name(const smb_share_t *si)
172829bd2886SAlan Wright {
172929bd2886SAlan Wright 	int i;
173029bd2886SAlan Wright 
173129bd2886SAlan Wright 	for (i = 0; i < (sizeof (cscopt) / sizeof (cscopt[0])); ++i) {
173229bd2886SAlan Wright 		if (si->shr_flags & cscopt[i].flag)
173329bd2886SAlan Wright 			return (cscopt[i].value);
173429bd2886SAlan Wright 	}
173529bd2886SAlan Wright 
173629bd2886SAlan Wright 	return (NULL);
173729bd2886SAlan Wright }
173829bd2886SAlan Wright 
173929bd2886SAlan Wright /*
17409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Takes the value of a boolean share property and set/clear the
17419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * specified flag based on the property's value.
17428b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  */
17438b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States void
smb_shr_sa_setflag(const char * value,smb_share_t * si,uint32_t flag)17449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_shr_sa_setflag(const char *value, smb_share_t *si, uint32_t flag)
17458b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States {
17469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((strcasecmp(value, "true") == 0) || (strcmp(value, "1") == 0))
17479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		si->shr_flags |= flag;
17489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	else
17499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		si->shr_flags &= ~flag;
175029bd2886SAlan Wright }
175129bd2886SAlan Wright 
175229bd2886SAlan Wright /*
17538d7e4166Sjose borrego  * looks up sharemgr for the given share (resource) and loads
17548d7e4166Sjose borrego  * the definition into cache if lookup is successful
17558d7e4166Sjose borrego  */
17568d7e4166Sjose borrego static uint32_t
smb_shr_sa_loadbyname(char * sharename)17578d7e4166Sjose borrego smb_shr_sa_loadbyname(char *sharename)
17588d7e4166Sjose borrego {
17598d7e4166Sjose borrego 	sa_handle_t handle;
17608d7e4166Sjose borrego 	sa_share_t share;
17618d7e4166Sjose borrego 	sa_resource_t resource;
17628d7e4166Sjose borrego 	uint32_t status;
17638d7e4166Sjose borrego 
176489dc44ceSjose borrego 	if ((handle = smb_shr_sa_enter()) == NULL)
17658d7e4166Sjose borrego 		return (NERR_InternalError);
17668d7e4166Sjose borrego 
17678d7e4166Sjose borrego 	resource = sa_find_resource(handle, sharename);
17688d7e4166Sjose borrego 	if (resource == NULL) {
176989dc44ceSjose borrego 		smb_shr_sa_exit();
17708d7e4166Sjose borrego 		return (NERR_NetNameNotFound);
17718d7e4166Sjose borrego 	}
17728d7e4166Sjose borrego 
17738d7e4166Sjose borrego 	share = sa_get_resource_parent(resource);
17748d7e4166Sjose borrego 	if (share == NULL) {
177589dc44ceSjose borrego 		smb_shr_sa_exit();
17768d7e4166Sjose borrego 		return (NERR_InternalError);
17778d7e4166Sjose borrego 	}
17788d7e4166Sjose borrego 
17798d7e4166Sjose borrego 	status = smb_shr_sa_load(share, resource);
17808d7e4166Sjose borrego 
178189dc44ceSjose borrego 	smb_shr_sa_exit();
17828d7e4166Sjose borrego 	return (status);
17838d7e4166Sjose borrego }
17848d7e4166Sjose borrego 
17858d7e4166Sjose borrego /*
1786c8ec8eeaSjose borrego  * ============================================
1787c8ec8eeaSjose borrego  * Share publishing functions
1788b89a8333Snatalie li - Sun Microsystems - Irvine United States  *
1789b89a8333Snatalie li - Sun Microsystems - Irvine United States  * All the functions are private
1790c8ec8eeaSjose borrego  * ============================================
1791c8ec8eeaSjose borrego  */
1792c8ec8eeaSjose borrego 
1793b89a8333Snatalie li - Sun Microsystems - Irvine United States static void
smb_shr_publish(const char * sharename,const char * container)1794b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_publish(const char *sharename, const char *container)
1795b89a8333Snatalie li - Sun Microsystems - Irvine United States {
1796b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_shr_publisher_queue(sharename, container, SMB_SHR_PUBLISH);
1797b89a8333Snatalie li - Sun Microsystems - Irvine United States }
1798b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1799b89a8333Snatalie li - Sun Microsystems - Irvine United States static void
smb_shr_unpublish(const char * sharename,const char * container)1800b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_unpublish(const char *sharename, const char *container)
1801b89a8333Snatalie li - Sun Microsystems - Irvine United States {
1802b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_shr_publisher_queue(sharename, container, SMB_SHR_UNPUBLISH);
1803b89a8333Snatalie li - Sun Microsystems - Irvine United States }
1804b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1805c8ec8eeaSjose borrego /*
1806b89a8333Snatalie li - Sun Microsystems - Irvine United States  * In domain mode, put a share on the publisher queue.
1807b89a8333Snatalie li - Sun Microsystems - Irvine United States  * This is a no-op if the smb service is in Workgroup mode.
1808c8ec8eeaSjose borrego  */
1809c8ec8eeaSjose borrego static void
smb_shr_publisher_queue(const char * sharename,const char * container,char op)1810b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_publisher_queue(const char *sharename, const char *container, char op)
1811c8ec8eeaSjose borrego {
1812c8ec8eeaSjose borrego 	smb_shr_pitem_t *item = NULL;
1813c8ec8eeaSjose borrego 
1814c8ec8eeaSjose borrego 	if (container == NULL || *container == '\0')
1815c8ec8eeaSjose borrego 		return;
1816c8ec8eeaSjose borrego 
1817b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (smb_config_get_secmode() != SMB_SECMODE_DOMAIN)
1818b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return;
1819b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1820c8ec8eeaSjose borrego 	(void) mutex_lock(&ad_queue.spq_mtx);
1821c8ec8eeaSjose borrego 	switch (ad_queue.spq_state) {
1822c8ec8eeaSjose borrego 	case SMB_SHR_PQS_READY:
1823c8ec8eeaSjose borrego 	case SMB_SHR_PQS_PUBLISHING:
1824c8ec8eeaSjose borrego 		break;
1825c8ec8eeaSjose borrego 	default:
1826c8ec8eeaSjose borrego 		(void) mutex_unlock(&ad_queue.spq_mtx);
1827c8ec8eeaSjose borrego 		return;
1828c8ec8eeaSjose borrego 	}
1829c8ec8eeaSjose borrego 	(void) mutex_unlock(&ad_queue.spq_mtx);
1830c8ec8eeaSjose borrego 
1831b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if ((item = malloc(sizeof (smb_shr_pitem_t))) == NULL)
1832c8ec8eeaSjose borrego 		return;
1833c8ec8eeaSjose borrego 
1834c8ec8eeaSjose borrego 	item->spi_op = op;
1835c8ec8eeaSjose borrego 	(void) strlcpy(item->spi_name, sharename, sizeof (item->spi_name));
1836c8ec8eeaSjose borrego 	(void) strlcpy(item->spi_container, container,
1837c8ec8eeaSjose borrego 	    sizeof (item->spi_container));
1838c8ec8eeaSjose borrego 
1839c8ec8eeaSjose borrego 	(void) mutex_lock(&ad_queue.spq_mtx);
1840c8ec8eeaSjose borrego 	list_insert_tail(&ad_queue.spq_list, item);
1841c8ec8eeaSjose borrego 	(void) cond_signal(&ad_queue.spq_cv);
1842c8ec8eeaSjose borrego 	(void) mutex_unlock(&ad_queue.spq_mtx);
1843c8ec8eeaSjose borrego }
1844c8ec8eeaSjose borrego 
1845b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
1846b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Publishing won't be activated if the smb service is running in
1847b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Workgroup mode.
1848b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
1849c8ec8eeaSjose borrego static int
smb_shr_publisher_start(void)1850c8ec8eeaSjose borrego smb_shr_publisher_start(void)
1851c8ec8eeaSjose borrego {
1852b89a8333Snatalie li - Sun Microsystems - Irvine United States 	pthread_t publish_thr;
1853c8ec8eeaSjose borrego 	pthread_attr_t tattr;
1854c8ec8eeaSjose borrego 	int rc;
1855c8ec8eeaSjose borrego 
1856b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (smb_config_get_secmode() != SMB_SECMODE_DOMAIN)
1857b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (0);
1858b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1859c8ec8eeaSjose borrego 	(void) mutex_lock(&ad_queue.spq_mtx);
1860c8ec8eeaSjose borrego 	if (ad_queue.spq_state != SMB_SHR_PQS_NOQUEUE) {
1861c8ec8eeaSjose borrego 		(void) mutex_unlock(&ad_queue.spq_mtx);
1862c8ec8eeaSjose borrego 		errno = EINVAL;
1863c8ec8eeaSjose borrego 		return (-1);
1864c8ec8eeaSjose borrego 	}
1865c8ec8eeaSjose borrego 
1866c8ec8eeaSjose borrego 	list_create(&ad_queue.spq_list, sizeof (smb_shr_pitem_t),
1867c8ec8eeaSjose borrego 	    offsetof(smb_shr_pitem_t, spi_lnd));
1868c8ec8eeaSjose borrego 	ad_queue.spq_state = SMB_SHR_PQS_READY;
1869c8ec8eeaSjose borrego 	(void) mutex_unlock(&ad_queue.spq_mtx);
1870c8ec8eeaSjose borrego 
1871c8ec8eeaSjose borrego 	(void) pthread_attr_init(&tattr);
1872c8ec8eeaSjose borrego 	(void) pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
1873b89a8333Snatalie li - Sun Microsystems - Irvine United States 	rc = pthread_create(&publish_thr, &tattr, smb_shr_publisher, 0);
1874c8ec8eeaSjose borrego 	(void) pthread_attr_destroy(&tattr);
1875c8ec8eeaSjose borrego 
1876c8ec8eeaSjose borrego 	return (rc);
1877c8ec8eeaSjose borrego }
1878c8ec8eeaSjose borrego 
1879c8ec8eeaSjose borrego static void
smb_shr_publisher_stop(void)1880c8ec8eeaSjose borrego smb_shr_publisher_stop(void)
1881c8ec8eeaSjose borrego {
1882b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (smb_config_get_secmode() != SMB_SECMODE_DOMAIN)
1883b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return;
1884b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1885c8ec8eeaSjose borrego 	(void) mutex_lock(&ad_queue.spq_mtx);
1886c8ec8eeaSjose borrego 	switch (ad_queue.spq_state) {
1887c8ec8eeaSjose borrego 	case SMB_SHR_PQS_READY:
1888c8ec8eeaSjose borrego 	case SMB_SHR_PQS_PUBLISHING:
1889c8ec8eeaSjose borrego 		ad_queue.spq_state = SMB_SHR_PQS_STOPPING;
1890c8ec8eeaSjose borrego 		(void) cond_signal(&ad_queue.spq_cv);
1891c8ec8eeaSjose borrego 		break;
1892c8ec8eeaSjose borrego 	default:
1893c8ec8eeaSjose borrego 		break;
1894c8ec8eeaSjose borrego 	}
1895c8ec8eeaSjose borrego 	(void) mutex_unlock(&ad_queue.spq_mtx);
1896c8ec8eeaSjose borrego }
1897c8ec8eeaSjose borrego 
1898c8ec8eeaSjose borrego /*
1899b89a8333Snatalie li - Sun Microsystems - Irvine United States  * This is the publisher daemon thread.  While running, the thread waits
1900b89a8333Snatalie li - Sun Microsystems - Irvine United States  * on a conditional variable until notified that a share needs to be
1901b89a8333Snatalie li - Sun Microsystems - Irvine United States  * [un]published or that the thread should be terminated.
1902b89a8333Snatalie li - Sun Microsystems - Irvine United States  *
1903b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Entries may remain in the outgoing queue if the Active Directory
1904b89a8333Snatalie li - Sun Microsystems - Irvine United States  * service is inaccessible, in which case the thread wakes up every 60
1905b89a8333Snatalie li - Sun Microsystems - Irvine United States  * seconds to retry.
1906c8ec8eeaSjose borrego  */
1907c8ec8eeaSjose borrego /*ARGSUSED*/
1908c8ec8eeaSjose borrego static void *
smb_shr_publisher(void * arg)1909c8ec8eeaSjose borrego smb_shr_publisher(void *arg)
1910c8ec8eeaSjose borrego {
1911c8ec8eeaSjose borrego 	smb_ads_handle_t *ah;
1912c8ec8eeaSjose borrego 	smb_shr_pitem_t *shr;
1913c8ec8eeaSjose borrego 	list_t publist;
1914b89a8333Snatalie li - Sun Microsystems - Irvine United States 	timestruc_t pubretry;
1915c8ec8eeaSjose borrego 	char hostname[MAXHOSTNAMELEN];
1916c8ec8eeaSjose borrego 
1917c8ec8eeaSjose borrego 	(void) mutex_lock(&ad_queue.spq_mtx);
1918b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (ad_queue.spq_state != SMB_SHR_PQS_READY) {
1919c8ec8eeaSjose borrego 		(void) mutex_unlock(&ad_queue.spq_mtx);
1920c8ec8eeaSjose borrego 		return (NULL);
1921c8ec8eeaSjose borrego 	}
1922b89a8333Snatalie li - Sun Microsystems - Irvine United States 	ad_queue.spq_state = SMB_SHR_PQS_PUBLISHING;
1923c8ec8eeaSjose borrego 	(void) mutex_unlock(&ad_queue.spq_mtx);
1924c8ec8eeaSjose borrego 
19259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) smb_gethostname(hostname, MAXHOSTNAMELEN,
19269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    SMB_CASE_PRESERVE);
1927b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1928c8ec8eeaSjose borrego 	list_create(&publist, sizeof (smb_shr_pitem_t),
1929c8ec8eeaSjose borrego 	    offsetof(smb_shr_pitem_t, spi_lnd));
1930c8ec8eeaSjose borrego 
1931c8ec8eeaSjose borrego 	for (;;) {
1932c8ec8eeaSjose borrego 		(void) mutex_lock(&ad_queue.spq_mtx);
1933b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1934b89a8333Snatalie li - Sun Microsystems - Irvine United States 		while (list_is_empty(&ad_queue.spq_list) &&
1935b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    (ad_queue.spq_state == SMB_SHR_PQS_PUBLISHING)) {
1936b89a8333Snatalie li - Sun Microsystems - Irvine United States 			if (list_is_empty(&publist)) {
1937b89a8333Snatalie li - Sun Microsystems - Irvine United States 				(void) cond_wait(&ad_queue.spq_cv,
1938b89a8333Snatalie li - Sun Microsystems - Irvine United States 				    &ad_queue.spq_mtx);
1939b89a8333Snatalie li - Sun Microsystems - Irvine United States 			} else {
1940b89a8333Snatalie li - Sun Microsystems - Irvine United States 				pubretry.tv_sec = 60;
1941b89a8333Snatalie li - Sun Microsystems - Irvine United States 				pubretry.tv_nsec = 0;
1942b89a8333Snatalie li - Sun Microsystems - Irvine United States 				(void) cond_reltimedwait(&ad_queue.spq_cv,
1943b89a8333Snatalie li - Sun Microsystems - Irvine United States 				    &ad_queue.spq_mtx, &pubretry);
1944b89a8333Snatalie li - Sun Microsystems - Irvine United States 				break;
1945b89a8333Snatalie li - Sun Microsystems - Irvine United States 			}
1946b89a8333Snatalie li - Sun Microsystems - Irvine United States 		}
1947c8ec8eeaSjose borrego 
1948c8ec8eeaSjose borrego 		if (ad_queue.spq_state != SMB_SHR_PQS_PUBLISHING) {
1949c8ec8eeaSjose borrego 			(void) mutex_unlock(&ad_queue.spq_mtx);
1950c8ec8eeaSjose borrego 			break;
1951c8ec8eeaSjose borrego 		}
1952c8ec8eeaSjose borrego 
1953c8ec8eeaSjose borrego 		/*
1954b89a8333Snatalie li - Sun Microsystems - Irvine United States 		 * Transfer queued items to the local list so that
1955b89a8333Snatalie li - Sun Microsystems - Irvine United States 		 * the mutex can be released.
1956c8ec8eeaSjose borrego 		 */
1957c8ec8eeaSjose borrego 		while ((shr = list_head(&ad_queue.spq_list)) != NULL) {
1958c8ec8eeaSjose borrego 			list_remove(&ad_queue.spq_list, shr);
1959c8ec8eeaSjose borrego 			list_insert_tail(&publist, shr);
1960c8ec8eeaSjose borrego 		}
1961b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1962c8ec8eeaSjose borrego 		(void) mutex_unlock(&ad_queue.spq_mtx);
1963c8ec8eeaSjose borrego 
1964b89a8333Snatalie li - Sun Microsystems - Irvine United States 		if ((ah = smb_ads_open()) != NULL) {
1965c8ec8eeaSjose borrego 			smb_shr_publisher_send(ah, &publist, hostname);
1966c8ec8eeaSjose borrego 			smb_ads_close(ah);
1967c8ec8eeaSjose borrego 		}
1968c8ec8eeaSjose borrego 	}
1969b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1970b89a8333Snatalie li - Sun Microsystems - Irvine United States 	(void) mutex_lock(&ad_queue.spq_mtx);
1971b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_shr_publisher_flush(&ad_queue.spq_list);
1972c8ec8eeaSjose borrego 	list_destroy(&ad_queue.spq_list);
1973c8ec8eeaSjose borrego 	ad_queue.spq_state = SMB_SHR_PQS_NOQUEUE;
1974c8ec8eeaSjose borrego 	(void) mutex_unlock(&ad_queue.spq_mtx);
1975c8ec8eeaSjose borrego 
1976b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_shr_publisher_flush(&publist);
1977c8ec8eeaSjose borrego 	list_destroy(&publist);
1978c8ec8eeaSjose borrego 	return (NULL);
1979c8ec8eeaSjose borrego }
1980c8ec8eeaSjose borrego 
1981c8ec8eeaSjose borrego /*
1982b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Remove items from the specified queue and [un]publish them.
1983c8ec8eeaSjose borrego  */
1984c8ec8eeaSjose borrego static void
smb_shr_publisher_send(smb_ads_handle_t * ah,list_t * publist,const char * host)1985c8ec8eeaSjose borrego smb_shr_publisher_send(smb_ads_handle_t *ah, list_t *publist, const char *host)
1986c8ec8eeaSjose borrego {
1987c8ec8eeaSjose borrego 	smb_shr_pitem_t *shr;
1988c8ec8eeaSjose borrego 
1989c8ec8eeaSjose borrego 	while ((shr = list_head(publist)) != NULL) {
1990b89a8333Snatalie li - Sun Microsystems - Irvine United States 		(void) mutex_lock(&ad_queue.spq_mtx);
1991b89a8333Snatalie li - Sun Microsystems - Irvine United States 		if (ad_queue.spq_state != SMB_SHR_PQS_PUBLISHING) {
1992b89a8333Snatalie li - Sun Microsystems - Irvine United States 			(void) mutex_unlock(&ad_queue.spq_mtx);
1993b89a8333Snatalie li - Sun Microsystems - Irvine United States 			return;
1994b89a8333Snatalie li - Sun Microsystems - Irvine United States 		}
1995b89a8333Snatalie li - Sun Microsystems - Irvine United States 		(void) mutex_unlock(&ad_queue.spq_mtx);
1996b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1997c8ec8eeaSjose borrego 		list_remove(publist, shr);
1998c8ec8eeaSjose borrego 
1999c8ec8eeaSjose borrego 		if (shr->spi_op == SMB_SHR_PUBLISH)
2000c8ec8eeaSjose borrego 			(void) smb_ads_publish_share(ah, shr->spi_name,
2001c8ec8eeaSjose borrego 			    NULL, shr->spi_container, host);
2002c8ec8eeaSjose borrego 		else
2003c8ec8eeaSjose borrego 			(void) smb_ads_remove_share(ah, shr->spi_name,
2004c8ec8eeaSjose borrego 			    NULL, shr->spi_container, host);
2005b89a8333Snatalie li - Sun Microsystems - Irvine United States 
2006b89a8333Snatalie li - Sun Microsystems - Irvine United States 		free(shr);
2007c8ec8eeaSjose borrego 	}
2008b89a8333Snatalie li - Sun Microsystems - Irvine United States }
2009b89a8333Snatalie li - Sun Microsystems - Irvine United States 
2010b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
2011b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Flush all remaining items from the specified list/queue.
2012b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
2013b89a8333Snatalie li - Sun Microsystems - Irvine United States static void
smb_shr_publisher_flush(list_t * lst)2014b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_publisher_flush(list_t *lst)
2015b89a8333Snatalie li - Sun Microsystems - Irvine United States {
2016b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_shr_pitem_t *shr;
2017b89a8333Snatalie li - Sun Microsystems - Irvine United States 
2018b89a8333Snatalie li - Sun Microsystems - Irvine United States 	while ((shr = list_head(lst)) != NULL) {
2019b89a8333Snatalie li - Sun Microsystems - Irvine United States 		list_remove(lst, shr);
2020c8ec8eeaSjose borrego 		free(shr);
2021c8ec8eeaSjose borrego 	}
2022c8ec8eeaSjose borrego }
2023743a77edSAlan Wright 
2024743a77edSAlan Wright /*
20256d57f833SAlan Wright  * If the share path refers to a ZFS file system, add the
20269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * .zfs/shares/<share> object and call smb_quota_add_fs()
20279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * to initialize quota support for the share.
2028743a77edSAlan Wright  */
2029743a77edSAlan Wright static void
smb_shr_zfs_add(smb_share_t * si)2030743a77edSAlan Wright smb_shr_zfs_add(smb_share_t *si)
2031743a77edSAlan Wright {
20326d57f833SAlan Wright 	libzfs_handle_t *libhd;
20336d57f833SAlan Wright 	zfs_handle_t *zfshd;
20346d57f833SAlan Wright 	int ret;
20359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	char buf[MAXPATHLEN];	/* dataset or mountpoint */
2036743a77edSAlan Wright 
20379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (smb_getdataset(si->shr_path, buf, MAXPATHLEN) != 0)
20386d57f833SAlan Wright 		return;
20396d57f833SAlan Wright 
20406d57f833SAlan Wright 	if ((libhd = libzfs_init()) == NULL)
20416d57f833SAlan Wright 		return;
20426d57f833SAlan Wright 
20439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((zfshd = zfs_open(libhd, buf, ZFS_TYPE_FILESYSTEM)) == NULL) {
20446d57f833SAlan Wright 		libzfs_fini(libhd);
20456d57f833SAlan Wright 		return;
2046743a77edSAlan Wright 	}
20476d57f833SAlan Wright 
20486d57f833SAlan Wright 	errno = 0;
20499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ret = zfs_smb_acl_add(libhd, buf, si->shr_path, si->shr_name);
20506d57f833SAlan Wright 	if (ret != 0 && errno != EAGAIN && errno != EEXIST)
20516d57f833SAlan Wright 		syslog(LOG_INFO, "share: failed to add ACL object: %s: %s\n",
20526d57f833SAlan Wright 		    si->shr_name, strerror(errno));
20536d57f833SAlan Wright 
20549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (zfs_prop_get(zfshd, ZFS_PROP_MOUNTPOINT, buf, MAXPATHLEN,
20559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    NULL, NULL, 0, B_FALSE) == 0) {
20569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_quota_add_fs(buf);
20579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
20589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
20599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
20606d57f833SAlan Wright 	zfs_close(zfshd);
20616d57f833SAlan Wright 	libzfs_fini(libhd);
2062743a77edSAlan Wright }
2063743a77edSAlan Wright 
2064743a77edSAlan Wright /*
20656d57f833SAlan Wright  * If the share path refers to a ZFS file system, remove the
20669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * .zfs/shares/<share> object, and call smb_quota_remove_fs()
20679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * to end quota support for the share.
2068743a77edSAlan Wright  */
2069743a77edSAlan Wright static void
smb_shr_zfs_remove(smb_share_t * si)2070743a77edSAlan Wright smb_shr_zfs_remove(smb_share_t *si)
2071743a77edSAlan Wright {
20726d57f833SAlan Wright 	libzfs_handle_t *libhd;
20736d57f833SAlan Wright 	zfs_handle_t *zfshd;
20746d57f833SAlan Wright 	int ret;
20759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	char buf[MAXPATHLEN];	/* dataset or mountpoint */
2076743a77edSAlan Wright 
20779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (smb_getdataset(si->shr_path, buf, MAXPATHLEN) != 0)
20786d57f833SAlan Wright 		return;
20796d57f833SAlan Wright 
20806d57f833SAlan Wright 	if ((libhd = libzfs_init()) == NULL)
20816d57f833SAlan Wright 		return;
20826d57f833SAlan Wright 
20839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((zfshd = zfs_open(libhd, buf, ZFS_TYPE_FILESYSTEM)) == NULL) {
20846d57f833SAlan Wright 		libzfs_fini(libhd);
20856d57f833SAlan Wright 		return;
2086743a77edSAlan Wright 	}
20876d57f833SAlan Wright 
20886d57f833SAlan Wright 	errno = 0;
20899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ret = zfs_smb_acl_remove(libhd, buf, si->shr_path, si->shr_name);
20906d57f833SAlan Wright 	if (ret != 0 && errno != EAGAIN)
20916d57f833SAlan Wright 		syslog(LOG_INFO, "share: failed to remove ACL object: %s: %s\n",
20926d57f833SAlan Wright 		    si->shr_name, strerror(errno));
20936d57f833SAlan Wright 
20949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (zfs_prop_get(zfshd, ZFS_PROP_MOUNTPOINT, buf, MAXPATHLEN,
20959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    NULL, NULL, 0, B_FALSE) == 0) {
20969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_quota_remove_fs(buf);
20979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
20989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
20996d57f833SAlan Wright 	zfs_close(zfshd);
21006d57f833SAlan Wright 	libzfs_fini(libhd);
2101743a77edSAlan Wright }
2102743a77edSAlan Wright 
2103743a77edSAlan Wright /*
21046d57f833SAlan Wright  * If the share path refers to a ZFS file system, rename the
2105743a77edSAlan Wright  * .zfs/shares/<share> object.
2106743a77edSAlan Wright  */
2107743a77edSAlan Wright static void
smb_shr_zfs_rename(smb_share_t * from,smb_share_t * to)2108743a77edSAlan Wright smb_shr_zfs_rename(smb_share_t *from, smb_share_t *to)
2109743a77edSAlan Wright {
21106d57f833SAlan Wright 	libzfs_handle_t *libhd;
21116d57f833SAlan Wright 	zfs_handle_t *zfshd;
21126d57f833SAlan Wright 	int ret;
2113743a77edSAlan Wright 	char dataset[MAXPATHLEN];
2114743a77edSAlan Wright 
21156d57f833SAlan Wright 	if (smb_getdataset(from->shr_path, dataset, MAXPATHLEN) != 0)
21166d57f833SAlan Wright 		return;
21176d57f833SAlan Wright 
21186d57f833SAlan Wright 	if ((libhd = libzfs_init()) == NULL)
21196d57f833SAlan Wright 		return;
21206d57f833SAlan Wright 
21216d57f833SAlan Wright 	if ((zfshd = zfs_open(libhd, dataset, ZFS_TYPE_FILESYSTEM)) == NULL) {
21226d57f833SAlan Wright 		libzfs_fini(libhd);
21236d57f833SAlan Wright 		return;
2124743a77edSAlan Wright 	}
21256d57f833SAlan Wright 
21266d57f833SAlan Wright 	errno = 0;
21276d57f833SAlan Wright 	ret = zfs_smb_acl_rename(libhd, dataset, from->shr_path,
21286d57f833SAlan Wright 	    from->shr_name, to->shr_name);
21296d57f833SAlan Wright 	if (ret != 0 && errno != EAGAIN)
21306d57f833SAlan Wright 		syslog(LOG_INFO, "share: failed to rename ACL object: %s: %s\n",
21316d57f833SAlan Wright 		    from->shr_name, strerror(errno));
21326d57f833SAlan Wright 
21336d57f833SAlan Wright 	zfs_close(zfshd);
21346d57f833SAlan Wright 	libzfs_fini(libhd);
2135743a77edSAlan Wright }
213629bd2886SAlan Wright 
213729bd2886SAlan Wright /*
213829bd2886SAlan Wright  * Enable all privileges in the inheritable set to execute command.
213929bd2886SAlan Wright  */
214029bd2886SAlan Wright static int
smb_shr_enable_all_privs(void)214129bd2886SAlan Wright smb_shr_enable_all_privs(void)
214229bd2886SAlan Wright {
214329bd2886SAlan Wright 	priv_set_t *pset;
214429bd2886SAlan Wright 
214529bd2886SAlan Wright 	pset = priv_allocset();
214629bd2886SAlan Wright 	if (pset == NULL)
214729bd2886SAlan Wright 		return (-1);
214829bd2886SAlan Wright 
214929bd2886SAlan Wright 	if (getppriv(PRIV_LIMIT, pset)) {
215029bd2886SAlan Wright 		priv_freeset(pset);
215129bd2886SAlan Wright 		return (-1);
215229bd2886SAlan Wright 	}
215329bd2886SAlan Wright 
215429bd2886SAlan Wright 	if (setppriv(PRIV_ON, PRIV_INHERITABLE, pset)) {
215529bd2886SAlan Wright 		priv_freeset(pset);
215629bd2886SAlan Wright 		return (-1);
215729bd2886SAlan Wright 	}
215829bd2886SAlan Wright 
215929bd2886SAlan Wright 	priv_freeset(pset);
216029bd2886SAlan Wright 	return (0);
216129bd2886SAlan Wright }
216229bd2886SAlan Wright 
216329bd2886SAlan Wright /*
216429bd2886SAlan Wright  * Tokenizes the command string and returns the list of tokens in an array.
216529bd2886SAlan Wright  *
216629bd2886SAlan Wright  * Returns NULL if there are no tokens.
216729bd2886SAlan Wright  */
216829bd2886SAlan Wright static char **
smb_shr_tokenize_cmd(char * cmdstr)216929bd2886SAlan Wright smb_shr_tokenize_cmd(char *cmdstr)
217029bd2886SAlan Wright {
217129bd2886SAlan Wright 	char *cmd, *buf, *bp, *value;
217229bd2886SAlan Wright 	char **argv, **ap;
217329bd2886SAlan Wright 	int argc, i;
217429bd2886SAlan Wright 
217529bd2886SAlan Wright 	if (cmdstr == NULL || *cmdstr == '\0')
217629bd2886SAlan Wright 		return (NULL);
217729bd2886SAlan Wright 
217829bd2886SAlan Wright 	if ((buf = malloc(MAXPATHLEN)) == NULL)
217929bd2886SAlan Wright 		return (NULL);
218029bd2886SAlan Wright 
218129bd2886SAlan Wright 	(void) strlcpy(buf, cmdstr, MAXPATHLEN);
218229bd2886SAlan Wright 
218329bd2886SAlan Wright 	for (argc = 2, bp = cmdstr; *bp != '\0'; ++bp)
218429bd2886SAlan Wright 		if (*bp == ' ')
218529bd2886SAlan Wright 			++argc;
218629bd2886SAlan Wright 
218729bd2886SAlan Wright 	if ((argv = calloc(argc, sizeof (char *))) == NULL) {
218829bd2886SAlan Wright 		free(buf);
218929bd2886SAlan Wright 		return (NULL);
219029bd2886SAlan Wright 	}
219129bd2886SAlan Wright 
219229bd2886SAlan Wright 	ap = argv;
219329bd2886SAlan Wright 	for (bp = buf, i = 0; i < argc; ++i) {
219429bd2886SAlan Wright 		do {
219529bd2886SAlan Wright 			if ((value = strsep(&bp, " ")) == NULL)
219629bd2886SAlan Wright 				break;
219729bd2886SAlan Wright 		} while (*value == '\0');
219829bd2886SAlan Wright 
219929bd2886SAlan Wright 		if (value == NULL)
220029bd2886SAlan Wright 			break;
220129bd2886SAlan Wright 
220229bd2886SAlan Wright 		*ap++ = value;
220329bd2886SAlan Wright 	}
220429bd2886SAlan Wright 
220529bd2886SAlan Wright 	/* get the filename of the command from the path */
220629bd2886SAlan Wright 	if ((cmd = strrchr(argv[0], '/')) != NULL)
220729bd2886SAlan Wright 		(void) strlcpy(argv[0], ++cmd, strlen(argv[0]));
220829bd2886SAlan Wright 
220929bd2886SAlan Wright 	return (argv);
221029bd2886SAlan Wright }
221129bd2886SAlan Wright 
221229bd2886SAlan Wright /*
221329bd2886SAlan Wright  * Expands the command string for the following substitution tokens:
221429bd2886SAlan Wright  *
221529bd2886SAlan Wright  * %U - Windows username
221629bd2886SAlan Wright  * %D - Name of the domain or workgroup of %U
221729bd2886SAlan Wright  * %h - The server hostname
221829bd2886SAlan Wright  * %M - The client hostname
221929bd2886SAlan Wright  * %L - The server NetBIOS name
222029bd2886SAlan Wright  * %m - The client NetBIOS name. This option is only valid for NetBIOS
222129bd2886SAlan Wright  *      connections (port 139).
222229bd2886SAlan Wright  * %I - The IP address of the client machine
222329bd2886SAlan Wright  * %i - The local IP address to which the client is connected
222429bd2886SAlan Wright  * %S - The name of the share
222529bd2886SAlan Wright  * %P - The root directory of the share
222629bd2886SAlan Wright  * %u - The UID of the Unix user
222729bd2886SAlan Wright  *
222829bd2886SAlan Wright  * Returns 0 on success.  Otherwise -1.
222929bd2886SAlan Wright  */
223029bd2886SAlan Wright static int
smb_shr_expand_subs(char ** cmd_toks,smb_share_t * si,smb_shr_execinfo_t * subs)2231148c5f43SAlan Wright smb_shr_expand_subs(char **cmd_toks, smb_share_t *si, smb_shr_execinfo_t *subs)
223229bd2886SAlan Wright {
223329bd2886SAlan Wright 	char *fmt, *sub_chr, *ptr;
223429bd2886SAlan Wright 	boolean_t unknown;
223529bd2886SAlan Wright 	char hostname[MAXHOSTNAMELEN];
223629bd2886SAlan Wright 	char ip_str[INET6_ADDRSTRLEN];
223729bd2886SAlan Wright 	char name[SMB_PI_MAX_HOST];
2238bbf6f00cSJordan Brown 	smb_wchar_t wbuf[SMB_PI_MAX_HOST];
223929bd2886SAlan Wright 	int i;
224029bd2886SAlan Wright 
224129bd2886SAlan Wright 	if (cmd_toks == NULL || *cmd_toks == NULL)
224229bd2886SAlan Wright 		return (-1);
224329bd2886SAlan Wright 
224429bd2886SAlan Wright 	for (i = 1; cmd_toks[i]; i++) {
224529bd2886SAlan Wright 		fmt = cmd_toks[i];
224629bd2886SAlan Wright 		if (*fmt == '%') {
224729bd2886SAlan Wright 			sub_chr = fmt + 1;
224829bd2886SAlan Wright 			unknown = B_FALSE;
224929bd2886SAlan Wright 
225029bd2886SAlan Wright 			switch (*sub_chr) {
225129bd2886SAlan Wright 			case 'U':
225229bd2886SAlan Wright 				ptr = strdup(subs->e_winname);
225329bd2886SAlan Wright 				break;
225429bd2886SAlan Wright 			case 'D':
225529bd2886SAlan Wright 				ptr = strdup(subs->e_userdom);
225629bd2886SAlan Wright 				break;
225729bd2886SAlan Wright 			case 'h':
225829bd2886SAlan Wright 				if (gethostname(hostname, MAXHOSTNAMELEN) != 0)
225929bd2886SAlan Wright 					unknown = B_TRUE;
226029bd2886SAlan Wright 				else
226129bd2886SAlan Wright 					ptr = strdup(hostname);
226229bd2886SAlan Wright 				break;
226329bd2886SAlan Wright 			case 'M':
226429bd2886SAlan Wright 				if (smb_getnameinfo(&subs->e_cli_ipaddr,
226529bd2886SAlan Wright 				    hostname, sizeof (hostname), 0) != 0)
226629bd2886SAlan Wright 					unknown = B_TRUE;
226729bd2886SAlan Wright 				else
226829bd2886SAlan Wright 					ptr = strdup(hostname);
226929bd2886SAlan Wright 				break;
227029bd2886SAlan Wright 			case 'L':
227129bd2886SAlan Wright 				if (smb_getnetbiosname(hostname,
227229bd2886SAlan Wright 				    NETBIOS_NAME_SZ) != 0)
227329bd2886SAlan Wright 					unknown = B_TRUE;
227429bd2886SAlan Wright 				else
227529bd2886SAlan Wright 					ptr = strdup(hostname);
227629bd2886SAlan Wright 				break;
227729bd2886SAlan Wright 			case 'm':
227829bd2886SAlan Wright 				if (*subs->e_cli_netbiosname == '\0')
227929bd2886SAlan Wright 					unknown = B_TRUE;
228029bd2886SAlan Wright 				else {
2281bbf6f00cSJordan Brown 					(void) smb_mbstowcs(wbuf,
228229bd2886SAlan Wright 					    subs->e_cli_netbiosname,
228329bd2886SAlan Wright 					    SMB_PI_MAX_HOST - 1);
228429bd2886SAlan Wright 
2285bbf6f00cSJordan Brown 					if (ucstooem(name, wbuf,
2286bbf6f00cSJordan Brown 					    SMB_PI_MAX_HOST, OEM_CPG_850) == 0)
228729bd2886SAlan Wright 						(void) strlcpy(name,
228829bd2886SAlan Wright 						    subs->e_cli_netbiosname,
228929bd2886SAlan Wright 						    SMB_PI_MAX_HOST);
229029bd2886SAlan Wright 
229129bd2886SAlan Wright 					ptr = strdup(name);
229229bd2886SAlan Wright 				}
229329bd2886SAlan Wright 				break;
229429bd2886SAlan Wright 			case 'I':
229529bd2886SAlan Wright 				if (smb_inet_ntop(&subs->e_cli_ipaddr, ip_str,
229629bd2886SAlan Wright 				    SMB_IPSTRLEN(subs->e_cli_ipaddr.a_family))
229729bd2886SAlan Wright 				    != NULL)
229829bd2886SAlan Wright 					ptr = strdup(ip_str);
229929bd2886SAlan Wright 				else
230029bd2886SAlan Wright 					unknown = B_TRUE;
230129bd2886SAlan Wright 				break;
230229bd2886SAlan Wright 			case 'i':
230329bd2886SAlan Wright 				if (smb_inet_ntop(&subs->e_srv_ipaddr, ip_str,
230429bd2886SAlan Wright 				    SMB_IPSTRLEN(subs->e_srv_ipaddr.a_family))
230529bd2886SAlan Wright 				    != NULL)
230629bd2886SAlan Wright 					ptr = strdup(ip_str);
230729bd2886SAlan Wright 				else
230829bd2886SAlan Wright 					unknown = B_TRUE;
230929bd2886SAlan Wright 				break;
231029bd2886SAlan Wright 			case 'S':
231129bd2886SAlan Wright 				ptr = strdup(si->shr_name);
231229bd2886SAlan Wright 				break;
231329bd2886SAlan Wright 			case 'P':
231429bd2886SAlan Wright 				ptr = strdup(si->shr_path);
231529bd2886SAlan Wright 				break;
231629bd2886SAlan Wright 			case 'u':
231729bd2886SAlan Wright 				(void) snprintf(name, sizeof (name), "%u",
231829bd2886SAlan Wright 				    subs->e_uid);
231929bd2886SAlan Wright 				ptr = strdup(name);
232029bd2886SAlan Wright 				break;
232129bd2886SAlan Wright 			default:
232229bd2886SAlan Wright 				/* unknown sub char */
232329bd2886SAlan Wright 				unknown = B_TRUE;
232429bd2886SAlan Wright 				break;
232529bd2886SAlan Wright 			}
232629bd2886SAlan Wright 
232729bd2886SAlan Wright 			if (unknown)
232829bd2886SAlan Wright 				ptr = strdup("");
232929bd2886SAlan Wright 
233029bd2886SAlan Wright 		} else  /* first char of cmd's arg is not '%' char */
233129bd2886SAlan Wright 			ptr = strdup("");
233229bd2886SAlan Wright 
233329bd2886SAlan Wright 		cmd_toks[i] = ptr;
233429bd2886SAlan Wright 
233529bd2886SAlan Wright 		if (ptr == NULL) {
233629bd2886SAlan Wright 			for (i = 1; cmd_toks[i]; i++)
233729bd2886SAlan Wright 				free(cmd_toks[i]);
233829bd2886SAlan Wright 
233929bd2886SAlan Wright 			return (-1);
234029bd2886SAlan Wright 		}
234129bd2886SAlan Wright 	}
234229bd2886SAlan Wright 
234329bd2886SAlan Wright 	return (0);
234429bd2886SAlan Wright }
234529bd2886SAlan Wright 
234629bd2886SAlan Wright /*ARGSUSED*/
234729bd2886SAlan Wright static void
smb_shr_sig_abnormal_term(int sig_val)234829bd2886SAlan Wright smb_shr_sig_abnormal_term(int sig_val)
234929bd2886SAlan Wright {
235029bd2886SAlan Wright 	/*
235129bd2886SAlan Wright 	 * Calling _exit() prevents parent process from getting SIGTERM/SIGINT
235229bd2886SAlan Wright 	 * signal.
235329bd2886SAlan Wright 	 */
235429bd2886SAlan Wright 	_exit(-1);
235529bd2886SAlan Wright }
235629bd2886SAlan Wright 
235729bd2886SAlan Wright /*ARGSUSED*/
235829bd2886SAlan Wright static void
smb_shr_sig_child(int sig_val)235929bd2886SAlan Wright smb_shr_sig_child(int sig_val)
236029bd2886SAlan Wright {
236129bd2886SAlan Wright 	/*
236229bd2886SAlan Wright 	 * Catch the signal and allow the exit status of the child process
236329bd2886SAlan Wright 	 * to be available for reaping.
236429bd2886SAlan Wright 	 */
236529bd2886SAlan Wright }
236629bd2886SAlan Wright 
236729bd2886SAlan Wright /*
2368148c5f43SAlan Wright  * This is a temporary function which converts the given smb_share_t
2369148c5f43SAlan Wright  * structure to the nvlist format that will be provided by libsharev2
237029bd2886SAlan Wright  */
2371148c5f43SAlan Wright static int
smb_shr_encode(smb_share_t * si,nvlist_t ** nvlist)2372148c5f43SAlan Wright smb_shr_encode(smb_share_t *si, nvlist_t **nvlist)
237329bd2886SAlan Wright {
2374148c5f43SAlan Wright 	nvlist_t *list;
2375148c5f43SAlan Wright 	nvlist_t *share;
2376148c5f43SAlan Wright 	nvlist_t *smb;
2377148c5f43SAlan Wright 	char *csc;
2378148c5f43SAlan Wright 	int rc = 0;
237929bd2886SAlan Wright 
2380148c5f43SAlan Wright 	*nvlist = NULL;
238129bd2886SAlan Wright 
2382148c5f43SAlan Wright 	if ((rc = nvlist_alloc(&list, NV_UNIQUE_NAME, 0)) != 0)
2383148c5f43SAlan Wright 		return (rc);
238429bd2886SAlan Wright 
2385148c5f43SAlan Wright 	if ((rc = nvlist_alloc(&share, NV_UNIQUE_NAME, 0)) != 0) {
2386148c5f43SAlan Wright 		nvlist_free(list);
2387148c5f43SAlan Wright 		return (rc);
238829bd2886SAlan Wright 	}
238929bd2886SAlan Wright 
2390148c5f43SAlan Wright 	if ((rc = nvlist_alloc(&smb, NV_UNIQUE_NAME, 0)) != 0) {
2391148c5f43SAlan Wright 		nvlist_free(share);
2392148c5f43SAlan Wright 		nvlist_free(list);
2393148c5f43SAlan Wright 		return (rc);
2394148c5f43SAlan Wright 	}
2395148c5f43SAlan Wright 
2396148c5f43SAlan Wright 	/* global share properties */
2397148c5f43SAlan Wright 	rc |= nvlist_add_string(share, "name", si->shr_name);
2398148c5f43SAlan Wright 	rc |= nvlist_add_string(share, "path", si->shr_path);
2399148c5f43SAlan Wright 	rc |= nvlist_add_string(share, "desc", si->shr_cmnt);
2400148c5f43SAlan Wright 
2401148c5f43SAlan Wright 	/* smb protocol properties */
2402148c5f43SAlan Wright 	rc = nvlist_add_string(smb, SHOPT_AD_CONTAINER, si->shr_container);
2403148c5f43SAlan Wright 	if ((si->shr_flags & SMB_SHRF_ACC_NONE) != 0)
2404148c5f43SAlan Wright 		rc |= nvlist_add_string(smb, SHOPT_NONE, si->shr_access_none);
2405148c5f43SAlan Wright 	if ((si->shr_flags & SMB_SHRF_ACC_RO) != 0)
2406148c5f43SAlan Wright 		rc |= nvlist_add_string(smb, SHOPT_RO, si->shr_access_ro);
2407148c5f43SAlan Wright 	if ((si->shr_flags & SMB_SHRF_ACC_RW) != 0)
2408148c5f43SAlan Wright 		rc |= nvlist_add_string(smb, SHOPT_RW, si->shr_access_rw);
2409148c5f43SAlan Wright 
2410148c5f43SAlan Wright 	if ((si->shr_flags & SMB_SHRF_ABE) != 0)
2411148c5f43SAlan Wright 		rc |= nvlist_add_string(smb, SHOPT_ABE, "true");
2412148c5f43SAlan Wright 	if ((si->shr_flags & SMB_SHRF_CATIA) != 0)
2413148c5f43SAlan Wright 		rc |= nvlist_add_string(smb, SHOPT_CATIA, "true");
2414148c5f43SAlan Wright 	if ((si->shr_flags & SMB_SHRF_GUEST_OK) != 0)
2415148c5f43SAlan Wright 		rc |= nvlist_add_string(smb, SHOPT_GUEST, "true");
2416148c5f43SAlan Wright 	if ((si->shr_flags & SMB_SHRF_DFSROOT) != 0)
2417148c5f43SAlan Wright 		rc |= nvlist_add_string(smb, SHOPT_DFSROOT, "true");
2418148c5f43SAlan Wright 
2419148c5f43SAlan Wright 	if ((si->shr_flags & SMB_SHRF_AUTOHOME) != 0) {
2420148c5f43SAlan Wright 		rc |= nvlist_add_string(smb, "Autohome", "true");
2421148c5f43SAlan Wright 		rc |= nvlist_add_uint32(smb, "uid", si->shr_uid);
2422148c5f43SAlan Wright 		rc |= nvlist_add_uint32(smb, "gid", si->shr_gid);
2423148c5f43SAlan Wright 	}
2424148c5f43SAlan Wright 
2425148c5f43SAlan Wright 	if ((csc = smb_shr_sa_csc_name(si)) != NULL)
2426148c5f43SAlan Wright 		rc |= nvlist_add_string(smb, SHOPT_CSC, csc);
2427148c5f43SAlan Wright 
2428cb174861Sjoyce mcintosh 	rc |= nvlist_add_uint32(smb, "type", si->shr_type);
2429cb174861Sjoyce mcintosh 
2430148c5f43SAlan Wright 	rc |= nvlist_add_nvlist(share, "smb", smb);
2431148c5f43SAlan Wright 	rc |= nvlist_add_nvlist(list, si->shr_name, share);
2432148c5f43SAlan Wright 
2433148c5f43SAlan Wright 	nvlist_free(share);
2434148c5f43SAlan Wright 	nvlist_free(smb);
2435148c5f43SAlan Wright 
2436148c5f43SAlan Wright 	if (rc != 0)
2437148c5f43SAlan Wright 		nvlist_free(list);
2438148c5f43SAlan Wright 	else
2439148c5f43SAlan Wright 		*nvlist = list;
2440148c5f43SAlan Wright 
2441148c5f43SAlan Wright 	return (rc);
244229bd2886SAlan Wright }
2443