1da6c28aaSamw /*
2da6c28aaSamw  * CDDL HEADER START
3da6c28aaSamw  *
4da6c28aaSamw  * The contents of this file are subject to the terms of the
5da6c28aaSamw  * Common Development and Distribution License (the "License").
6da6c28aaSamw  * You may not use this file except in compliance with the License.
7da6c28aaSamw  *
8da6c28aaSamw  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9da6c28aaSamw  * or http://www.opensolaris.org/os/licensing.
10da6c28aaSamw  * See the License for the specific language governing permissions
11da6c28aaSamw  * and limitations under the License.
12da6c28aaSamw  *
13da6c28aaSamw  * When distributing Covered Code, include this CDDL HEADER in each
14da6c28aaSamw  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15da6c28aaSamw  * If applicable, add the following below this CDDL HEADER, with the
16da6c28aaSamw  * fields enclosed by brackets "[]" replaced with your own identifying
17da6c28aaSamw  * information: Portions Copyright [yyyy] [name of copyright owner]
18da6c28aaSamw  *
19da6c28aaSamw  * CDDL HEADER END
209b241b4eSYuri Pankov  *
21c5866007SKeyur Desai  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
2287b81758SJoyce McIntosh  * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
230237b699SAndrew Stormont  * Copyright 2019 RackTop Systems.
24da6c28aaSamw  */
25da6c28aaSamw 
26da6c28aaSamw /*
27b89a8333Snatalie li - Sun Microsystems - Irvine United States  * SMB/CIFS share cache implementation.
28da6c28aaSamw  */
29da6c28aaSamw 
30da6c28aaSamw #include <errno.h>
31da6c28aaSamw #include <synch.h>
32da6c28aaSamw #include <stdlib.h>
33da6c28aaSamw #include <strings.h>
34da6c28aaSamw #include <syslog.h>
35da6c28aaSamw #include <thread.h>
36da6c28aaSamw #include <pthread.h>
37c8ec8eeaSjose borrego #include <assert.h>
38b89a8333Snatalie li - Sun Microsystems - Irvine United States #include <libshare.h>
39743a77edSAlan Wright #include <libzfs.h>
4029bd2886SAlan Wright #include <priv_utils.h>
4129bd2886SAlan Wright #include <sys/types.h>
4229bd2886SAlan Wright #include <sys/wait.h>
4329bd2886SAlan Wright #include <unistd.h>
4429bd2886SAlan Wright #include <pwd.h>
4529bd2886SAlan Wright #include <signal.h>
46c5866007SKeyur Desai #include <dirent.h>
47cb174861Sjoyce mcintosh #include <dlfcn.h>
48da6c28aaSamw 
49da6c28aaSamw #include <smbsrv/libsmb.h>
50da6c28aaSamw #include <smbsrv/libsmbns.h>
518d96b23eSAlan Wright #include <smbsrv/libmlsvc.h>
523db3f65cSamw #include <smbsrv/smb_share.h>
53bbf6f00cSJordan Brown #include <smbsrv/smb.h>
54e3f2c991SKeyur Desai #include <mlsvc.h>
559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <dfs.h>
56da6c28aaSamw 
57b89a8333Snatalie li - Sun Microsystems - Irvine United States #define	SMB_SHR_ERROR_THRESHOLD		3
588d7e4166Sjose borrego #define	SMB_SHR_CSC_BUFSZ		64
598d7e4166Sjose borrego 
60c5866007SKeyur Desai typedef struct smb_transient {
61c5866007SKeyur Desai 	char		*name;
62c5866007SKeyur Desai 	char		*cmnt;
63c5866007SKeyur Desai 	char		*path;
64c5866007SKeyur Desai 	char		drive;
65c5866007SKeyur Desai 	boolean_t	check;
66c5866007SKeyur Desai } smb_transient_t;
67c5866007SKeyur Desai 
68c5866007SKeyur Desai static smb_transient_t tshare[] = {
69c5866007SKeyur Desai 	{ "IPC$", "Remote IPC",		NULL,		'\0', B_FALSE },
70c5866007SKeyur Desai 	{ "c$",   "Default Share",	SMB_CVOL,	'C',  B_FALSE },
71c5866007SKeyur Desai 	{ "vss$", "VSS",		SMB_VSS,	'V',  B_TRUE }
72c5866007SKeyur Desai };
73c5866007SKeyur Desai 
7429bd2886SAlan Wright static struct {
7529bd2886SAlan Wright 	char *value;
7629bd2886SAlan Wright 	uint32_t flag;
7729bd2886SAlan Wright } cscopt[] = {
7829bd2886SAlan Wright 	{ "disabled",	SMB_SHRF_CSC_DISABLED },
7929bd2886SAlan Wright 	{ "manual",	SMB_SHRF_CSC_MANUAL },
8029bd2886SAlan Wright 	{ "auto",	SMB_SHRF_CSC_AUTO },
8129bd2886SAlan Wright 	{ "vdo",	SMB_SHRF_CSC_VDO }
8229bd2886SAlan Wright };
8329bd2886SAlan Wright 
84c8ec8eeaSjose borrego /*
85c8ec8eeaSjose borrego  * Cache functions and vars
86c8ec8eeaSjose borrego  */
87b89a8333Snatalie li - Sun Microsystems - Irvine United States #define	SMB_SHR_HTAB_SZ			1024
88b89a8333Snatalie li - Sun Microsystems - Irvine United States 
89b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
90b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Cache handle
91b89a8333Snatalie li - Sun Microsystems - Irvine United States  *
92b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Shares cache is a hash table.
93b89a8333Snatalie li - Sun Microsystems - Irvine United States  *
94b89a8333Snatalie li - Sun Microsystems - Irvine United States  * sc_cache		pointer to hash table handle
95b89a8333Snatalie li - Sun Microsystems - Irvine United States  * sc_cache_lck		synchronize cache read/write accesses
96b89a8333Snatalie li - Sun Microsystems - Irvine United States  * sc_state		cache state machine values
97b89a8333Snatalie li - Sun Microsystems - Irvine United States  * sc_nops		number of inflight/pending cache operations
98b89a8333Snatalie li - Sun Microsystems - Irvine United States  * sc_mtx		protects handle fields
99b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
100b89a8333Snatalie li - Sun Microsystems - Irvine United States typedef struct smb_shr_cache {
101b89a8333Snatalie li - Sun Microsystems - Irvine United States 	HT_HANDLE	*sc_cache;
102b89a8333Snatalie li - Sun Microsystems - Irvine United States 	rwlock_t	sc_cache_lck;
103b89a8333Snatalie li - Sun Microsystems - Irvine United States 	mutex_t		sc_mtx;
104b89a8333Snatalie li - Sun Microsystems - Irvine United States 	cond_t		sc_cv;
105b89a8333Snatalie li - Sun Microsystems - Irvine United States 	uint32_t	sc_state;
106b89a8333Snatalie li - Sun Microsystems - Irvine United States 	uint32_t	sc_nops;
107b89a8333Snatalie li - Sun Microsystems - Irvine United States } smb_shr_cache_t;
108b89a8333Snatalie li - Sun Microsystems - Irvine United States 
109b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
110b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Cache states
111b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
112b89a8333Snatalie li - Sun Microsystems - Irvine United States #define	SMB_SHR_CACHE_STATE_NONE	0
113b89a8333Snatalie li - Sun Microsystems - Irvine United States #define	SMB_SHR_CACHE_STATE_CREATED	1
114b89a8333Snatalie li - Sun Microsystems - Irvine United States #define	SMB_SHR_CACHE_STATE_DESTROYING	2
115b89a8333Snatalie li - Sun Microsystems - Irvine United States 
116b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
117b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Cache lock modes
118b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
119b89a8333Snatalie li - Sun Microsystems - Irvine United States #define	SMB_SHR_CACHE_RDLOCK	0
120b89a8333Snatalie li - Sun Microsystems - Irvine United States #define	SMB_SHR_CACHE_WRLOCK	1
121da6c28aaSamw 
122b89a8333Snatalie li - Sun Microsystems - Irvine United States static smb_shr_cache_t smb_shr_cache;
123da6c28aaSamw 
1243db3f65cSamw static uint32_t smb_shr_cache_create(void);
125c8ec8eeaSjose borrego static void smb_shr_cache_destroy(void);
126b89a8333Snatalie li - Sun Microsystems - Irvine United States static uint32_t smb_shr_cache_lock(int);
127b89a8333Snatalie li - Sun Microsystems - Irvine United States static void smb_shr_cache_unlock(void);
128b89a8333Snatalie li - Sun Microsystems - Irvine United States static int smb_shr_cache_count(void);
129b89a8333Snatalie li - Sun Microsystems - Irvine United States static smb_share_t *smb_shr_cache_iterate(smb_shriter_t *);
130b89a8333Snatalie li - Sun Microsystems - Irvine United States 
131b89a8333Snatalie li - Sun Microsystems - Irvine United States static smb_share_t *smb_shr_cache_findent(char *);
132c8ec8eeaSjose borrego static uint32_t smb_shr_cache_addent(smb_share_t *);
133c8ec8eeaSjose borrego static void smb_shr_cache_delent(char *);
134c8ec8eeaSjose borrego static void smb_shr_cache_freent(HT_ITEM *);
135da6c28aaSamw 
136c5866007SKeyur Desai static boolean_t smb_shr_is_empty(const char *);
137c5866007SKeyur Desai static boolean_t smb_shr_is_dot_or_dotdot(const char *);
138c5866007SKeyur Desai 
139da6c28aaSamw /*
140c8ec8eeaSjose borrego  * sharemgr functions
141cbfb650aScp  */
142b89a8333Snatalie li - Sun Microsystems - Irvine United States static void smb_shr_sa_loadgrp(sa_group_t);
143b89a8333Snatalie li - Sun Microsystems - Irvine United States static uint32_t smb_shr_sa_load(sa_share_t, sa_resource_t);
1448d7e4166Sjose borrego static uint32_t smb_shr_sa_loadbyname(char *);
145b89a8333Snatalie li - Sun Microsystems - Irvine United States static uint32_t smb_shr_sa_get(sa_share_t, sa_resource_t, smb_share_t *);
146cbfb650aScp 
147743a77edSAlan Wright /*
148743a77edSAlan Wright  * .ZFS management functions
149743a77edSAlan Wright  */
150743a77edSAlan Wright static void smb_shr_zfs_add(smb_share_t *);
151743a77edSAlan Wright static void smb_shr_zfs_remove(smb_share_t *);
152743a77edSAlan Wright static void smb_shr_zfs_rename(smb_share_t *, smb_share_t *);
153743a77edSAlan Wright 
154cbfb650aScp /*
155c8ec8eeaSjose borrego  * share publishing
156da6c28aaSamw  */
157c8ec8eeaSjose borrego #define	SMB_SHR_PUBLISH		0
158c8ec8eeaSjose borrego #define	SMB_SHR_UNPUBLISH	1
159cbfb650aScp 
160c8ec8eeaSjose borrego typedef struct smb_shr_pitem {
161c8ec8eeaSjose borrego 	list_node_t	spi_lnd;
162c8ec8eeaSjose borrego 	char		spi_name[MAXNAMELEN];
163c8ec8eeaSjose borrego 	char		spi_container[MAXPATHLEN];
164c8ec8eeaSjose borrego 	char		spi_op;
165c8ec8eeaSjose borrego } smb_shr_pitem_t;
166da6c28aaSamw 
167da6c28aaSamw /*
168c8ec8eeaSjose borrego  * publish queue states
169da6c28aaSamw  */
170c8ec8eeaSjose borrego #define	SMB_SHR_PQS_NOQUEUE	0
171c8ec8eeaSjose borrego #define	SMB_SHR_PQS_READY	1	/* the queue is ready */
172c8ec8eeaSjose borrego #define	SMB_SHR_PQS_PUBLISHING	2	/* publisher thread is running */
173c8ec8eeaSjose borrego #define	SMB_SHR_PQS_STOPPING	3
174da6c28aaSamw 
175da6c28aaSamw /*
176c8ec8eeaSjose borrego  * share publishing queue
177da6c28aaSamw  */
178c8ec8eeaSjose borrego typedef struct smb_shr_pqueue {
179c8ec8eeaSjose borrego 	list_t		spq_list;
180c8ec8eeaSjose borrego 	mutex_t		spq_mtx;
181c8ec8eeaSjose borrego 	cond_t		spq_cv;
182c8ec8eeaSjose borrego 	uint32_t	spq_state;
183c8ec8eeaSjose borrego } smb_shr_pqueue_t;
184c8ec8eeaSjose borrego 
185c8ec8eeaSjose borrego static smb_shr_pqueue_t ad_queue;
186da6c28aaSamw 
187c8ec8eeaSjose borrego static int smb_shr_publisher_start(void);
188c8ec8eeaSjose borrego static void smb_shr_publisher_stop(void);
189c8ec8eeaSjose borrego static void smb_shr_publisher_send(smb_ads_handle_t *, list_t *, const char *);
190b89a8333Snatalie li - Sun Microsystems - Irvine United States static void smb_shr_publisher_queue(const char *, const char *, char);
191c8ec8eeaSjose borrego static void *smb_shr_publisher(void *);
192b89a8333Snatalie li - Sun Microsystems - Irvine United States static void smb_shr_publisher_flush(list_t *);
193b89a8333Snatalie li - Sun Microsystems - Irvine United States static void smb_shr_publish(const char *, const char *);
194b89a8333Snatalie li - Sun Microsystems - Irvine United States static void smb_shr_unpublish(const char *, const char *);
195da6c28aaSamw 
196b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
197b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Utility/helper functions
198b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
1998d7e4166Sjose borrego static uint32_t smb_shr_lookup(char *, smb_share_t *);
2009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static uint32_t smb_shr_add_transient(char *, char *, char *);
20129bd2886SAlan Wright static int smb_shr_enable_all_privs(void);
202148c5f43SAlan Wright static int smb_shr_expand_subs(char **, smb_share_t *, smb_shr_execinfo_t *);
20329bd2886SAlan Wright static char **smb_shr_tokenize_cmd(char *);
20429bd2886SAlan Wright static void smb_shr_sig_abnormal_term(int);
20529bd2886SAlan Wright static void smb_shr_sig_child(int);
206148c5f43SAlan Wright static int smb_shr_encode(smb_share_t *, nvlist_t **);
20789dc44ceSjose borrego 
20889dc44ceSjose borrego /*
20989dc44ceSjose borrego  * libshare handle and synchronization
21089dc44ceSjose borrego  */
21189dc44ceSjose borrego typedef struct smb_sa_handle {
21289dc44ceSjose borrego 	sa_handle_t	sa_handle;
21389dc44ceSjose borrego 	mutex_t		sa_mtx;
21489dc44ceSjose borrego 	boolean_t	sa_in_service;
21589dc44ceSjose borrego } smb_sa_handle_t;
21689dc44ceSjose borrego 
21789dc44ceSjose borrego static smb_sa_handle_t smb_sa_handle;
21889dc44ceSjose borrego 
21929bd2886SAlan Wright static char smb_shr_exec_map[MAXPATHLEN];
22029bd2886SAlan Wright static char smb_shr_exec_unmap[MAXPATHLEN];
22129bd2886SAlan Wright static mutex_t smb_shr_exec_mtx;
22229bd2886SAlan Wright 
223e3f2c991SKeyur Desai /*
224e3f2c991SKeyur Desai  * Semaphore held during temporary, process-wide changes
225e3f2c991SKeyur Desai  * such as process privileges.  It is a seamaphore and
226e3f2c991SKeyur Desai  * not a mutex so a child of fork can reset it.
227e3f2c991SKeyur Desai  */
228e3f2c991SKeyur Desai static sema_t smb_proc_sem = DEFAULTSEMA;
229e3f2c991SKeyur Desai 
230da6c28aaSamw /*
2318d7e4166Sjose borrego  * Creates and initializes the cache and starts the publisher
2328d7e4166Sjose borrego  * thread.
233da6c28aaSamw  */
234c8ec8eeaSjose borrego int
smb_shr_start(void)235c8ec8eeaSjose borrego smb_shr_start(void)
236da6c28aaSamw {
237c5866007SKeyur Desai 	smb_transient_t	*ts;
238c5866007SKeyur Desai 	uint32_t	nerr;
239c5866007SKeyur Desai 	int		i;
2409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
24189dc44ceSjose borrego 	(void) mutex_lock(&smb_sa_handle.sa_mtx);
24289dc44ceSjose borrego 	smb_sa_handle.sa_in_service = B_TRUE;
24389dc44ceSjose borrego 	(void) mutex_unlock(&smb_sa_handle.sa_mtx);
24489dc44ceSjose borrego 
245b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (smb_shr_cache_create() != NERR_Success)
246b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (ENOMEM);
247b89a8333Snatalie li - Sun Microsystems - Irvine United States 
2489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	for (i = 0; i < sizeof (tshare)/sizeof (tshare[0]); ++i) {
249c5866007SKeyur Desai 		ts = &tshare[i];
250c5866007SKeyur Desai 
251c5866007SKeyur Desai 		if (ts->check && smb_shr_is_empty(ts->path))
252c5866007SKeyur Desai 			continue;
253c5866007SKeyur Desai 
254c5866007SKeyur Desai 		nerr = smb_shr_add_transient(ts->name, ts->cmnt, ts->path);
255c5866007SKeyur Desai 		if (nerr != NERR_Success)
2569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			return (ENOMEM);
2579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
258b89a8333Snatalie li - Sun Microsystems - Irvine United States 
2598d7e4166Sjose borrego 	return (smb_shr_publisher_start());
260da6c28aaSamw }
261da6c28aaSamw 
262c8ec8eeaSjose borrego void
smb_shr_stop(void)263c8ec8eeaSjose borrego smb_shr_stop(void)
264c8ec8eeaSjose borrego {
265c8ec8eeaSjose borrego 	smb_shr_cache_destroy();
266c8ec8eeaSjose borrego 	smb_shr_publisher_stop();
26789dc44ceSjose borrego 
26889dc44ceSjose borrego 	(void) mutex_lock(&smb_sa_handle.sa_mtx);
26989dc44ceSjose borrego 	smb_sa_handle.sa_in_service = B_FALSE;
27089dc44ceSjose borrego 
27189dc44ceSjose borrego 	if (smb_sa_handle.sa_handle != NULL) {
27289dc44ceSjose borrego 		sa_fini(smb_sa_handle.sa_handle);
27389dc44ceSjose borrego 		smb_sa_handle.sa_handle = NULL;
27489dc44ceSjose borrego 	}
27589dc44ceSjose borrego 
27689dc44ceSjose borrego 	(void) mutex_unlock(&smb_sa_handle.sa_mtx);
27789dc44ceSjose borrego }
27889dc44ceSjose borrego 
27989dc44ceSjose borrego /*
28089dc44ceSjose borrego  * Get a handle and exclusive access to the libshare API.
28189dc44ceSjose borrego  */
28289dc44ceSjose borrego sa_handle_t
smb_shr_sa_enter(void)28389dc44ceSjose borrego smb_shr_sa_enter(void)
28489dc44ceSjose borrego {
28589dc44ceSjose borrego 	(void) mutex_lock(&smb_sa_handle.sa_mtx);
28689dc44ceSjose borrego 	if (!smb_sa_handle.sa_in_service) {
28789dc44ceSjose borrego 		(void) mutex_unlock(&smb_sa_handle.sa_mtx);
28889dc44ceSjose borrego 		return (NULL);
28989dc44ceSjose borrego 	}
29089dc44ceSjose borrego 
291a851ffc8SGordon Ross 	if (smb_sa_handle.sa_handle != NULL &&
292a851ffc8SGordon Ross 	    sa_needs_refresh(smb_sa_handle.sa_handle)) {
293a851ffc8SGordon Ross 		sa_fini(smb_sa_handle.sa_handle);
294a851ffc8SGordon Ross 		smb_sa_handle.sa_handle = NULL;
295a851ffc8SGordon Ross 	}
296a851ffc8SGordon Ross 
29789dc44ceSjose borrego 	if (smb_sa_handle.sa_handle == NULL) {
29889dc44ceSjose borrego 		smb_sa_handle.sa_handle = sa_init(SA_INIT_SHARE_API);
29989dc44ceSjose borrego 		if (smb_sa_handle.sa_handle == NULL) {
30089dc44ceSjose borrego 			syslog(LOG_ERR, "share: failed to get libshare handle");
30189dc44ceSjose borrego 			(void) mutex_unlock(&smb_sa_handle.sa_mtx);
30289dc44ceSjose borrego 			return (NULL);
30389dc44ceSjose borrego 		}
30489dc44ceSjose borrego 	}
30589dc44ceSjose borrego 
30689dc44ceSjose borrego 	return (smb_sa_handle.sa_handle);
30789dc44ceSjose borrego }
30889dc44ceSjose borrego 
30989dc44ceSjose borrego /*
31089dc44ceSjose borrego  * Release exclusive access to the libshare API.
31189dc44ceSjose borrego  */
31289dc44ceSjose borrego void
smb_shr_sa_exit(void)31389dc44ceSjose borrego smb_shr_sa_exit(void)
31489dc44ceSjose borrego {
31589dc44ceSjose borrego 	(void) mutex_unlock(&smb_sa_handle.sa_mtx);
316c8ec8eeaSjose borrego }
317c8ec8eeaSjose borrego 
318da6c28aaSamw /*
319c8ec8eeaSjose borrego  * Return the total number of shares
320da6c28aaSamw  */
321da6c28aaSamw int
smb_shr_count(void)3223db3f65cSamw smb_shr_count(void)
323da6c28aaSamw {
324b89a8333Snatalie li - Sun Microsystems - Irvine United States 	int n_shares = 0;
325da6c28aaSamw 
326b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (smb_shr_cache_lock(SMB_SHR_CACHE_RDLOCK) == NERR_Success) {
327b89a8333Snatalie li - Sun Microsystems - Irvine United States 		n_shares = smb_shr_cache_count();
328b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache_unlock();
329b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
330da6c28aaSamw 
331da6c28aaSamw 	return (n_shares);
332da6c28aaSamw }
333da6c28aaSamw 
334da6c28aaSamw /*
3353db3f65cSamw  * smb_shr_iterinit
336da6c28aaSamw  *
337c8ec8eeaSjose borrego  * Initialize given iterator for traversing hash table.
338da6c28aaSamw  */
339da6c28aaSamw void
smb_shr_iterinit(smb_shriter_t * shi)340c8ec8eeaSjose borrego smb_shr_iterinit(smb_shriter_t *shi)
341da6c28aaSamw {
3423db3f65cSamw 	bzero(shi, sizeof (smb_shriter_t));
343c8ec8eeaSjose borrego 	shi->si_first = B_TRUE;
344da6c28aaSamw }
345da6c28aaSamw 
346da6c28aaSamw /*
3473db3f65cSamw  * smb_shr_iterate
348da6c28aaSamw  *
3493ad684d6Sjb  * Iterate on the shares in the hash table. The iterator must be initialized
350da6c28aaSamw  * before the first iteration. On subsequent calls, the iterator must be
351da6c28aaSamw  * passed unchanged.
352da6c28aaSamw  *
353da6c28aaSamw  * Returns NULL on failure or when all shares are visited, otherwise
354da6c28aaSamw  * returns information of visited share.
355da6c28aaSamw  */
3563db3f65cSamw smb_share_t *
smb_shr_iterate(smb_shriter_t * shi)3573db3f65cSamw smb_shr_iterate(smb_shriter_t *shi)
358da6c28aaSamw {
359c8ec8eeaSjose borrego 	smb_share_t *share = NULL;
360b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_share_t *cached_si;
361da6c28aaSamw 
362b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (shi == NULL)
363da6c28aaSamw 		return (NULL);
364da6c28aaSamw 
365b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (smb_shr_cache_lock(SMB_SHR_CACHE_RDLOCK) == NERR_Success) {
366b89a8333Snatalie li - Sun Microsystems - Irvine United States 		if ((cached_si = smb_shr_cache_iterate(shi)) != NULL) {
367b89a8333Snatalie li - Sun Microsystems - Irvine United States 			share = &shi->si_share;
368b89a8333Snatalie li - Sun Microsystems - Irvine United States 			bcopy(cached_si, share, sizeof (smb_share_t));
369b89a8333Snatalie li - Sun Microsystems - Irvine United States 		}
370b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache_unlock();
371da6c28aaSamw 	}
372da6c28aaSamw 
373c8ec8eeaSjose borrego 	return (share);
374da6c28aaSamw }
375da6c28aaSamw 
376da6c28aaSamw /*
377b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Adds the given share to cache, publishes the share in ADS
378b89a8333Snatalie li - Sun Microsystems - Irvine United States  * if it has an AD container, calls kernel to take a hold on
379b89a8333Snatalie li - Sun Microsystems - Irvine United States  * the shared file system. If it can't take a hold on the
380b89a8333Snatalie li - Sun Microsystems - Irvine United States  * shared file system, it's either because shared directory
381b89a8333Snatalie li - Sun Microsystems - Irvine United States  * does not exist or some other error has occurred, in any
382b89a8333Snatalie li - Sun Microsystems - Irvine United States  * case the share is removed from the cache.
383da6c28aaSamw  *
384b89a8333Snatalie li - Sun Microsystems - Irvine United States  * If the specified share is an autohome share which already
385b89a8333Snatalie li - Sun Microsystems - Irvine United States  * exists in the cache, just increments the reference count.
386da6c28aaSamw  */
3873db3f65cSamw uint32_t
smb_shr_add(smb_share_t * si)388b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_add(smb_share_t *si)
389da6c28aaSamw {
39029e6af5cSAlek Pinchuk 	struct stat st;
391b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_share_t *cached_si;
392148c5f43SAlan Wright 	nvlist_t *shrlist;
393db46347bSGordon Ross 	boolean_t created_zfs = B_FALSE;
394b89a8333Snatalie li - Sun Microsystems - Irvine United States 	uint32_t status;
395c8ec8eeaSjose borrego 	int rc;
396da6c28aaSamw 
397c8ec8eeaSjose borrego 	assert(si != NULL);
398da6c28aaSamw 
399fe1c642dSBill Krier 	if (smb_name_validate_share(si->shr_name) != ERROR_SUCCESS)
400c8ec8eeaSjose borrego 		return (ERROR_INVALID_NAME);
401da6c28aaSamw 
402b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (smb_shr_cache_lock(SMB_SHR_CACHE_WRLOCK) != NERR_Success)
403b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (NERR_InternalError);
404c8ec8eeaSjose borrego 
405b89a8333Snatalie li - Sun Microsystems - Irvine United States 	cached_si = smb_shr_cache_findent(si->shr_name);
406b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (cached_si) {
407b89a8333Snatalie li - Sun Microsystems - Irvine United States 		if (si->shr_flags & SMB_SHRF_AUTOHOME) {
408b89a8333Snatalie li - Sun Microsystems - Irvine United States 			cached_si->shr_refcnt++;
409b89a8333Snatalie li - Sun Microsystems - Irvine United States 			status = NERR_Success;
410b89a8333Snatalie li - Sun Microsystems - Irvine United States 		} else {
411b89a8333Snatalie li - Sun Microsystems - Irvine United States 			status = NERR_DuplicateShare;
412b89a8333Snatalie li - Sun Microsystems - Irvine United States 		}
413b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache_unlock();
414c8ec8eeaSjose borrego 		return (status);
415b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
416da6c28aaSamw 
41729e6af5cSAlek Pinchuk 	if (STYPE_ISDSK(si->shr_type)) {
41829e6af5cSAlek Pinchuk 		/*
41929e6af5cSAlek Pinchuk 		 * If share type is STYPE_DISKTREE then the path to the
42029e6af5cSAlek Pinchuk 		 * share should exist so that we can add the share to cache.
421db46347bSGordon Ross 		 * If path is ZFS, add the .zfs/shares/<share> entry.
422db46347bSGordon Ross 		 *
423db46347bSGordon Ross 		 * Both actions may require privileges that main dropped,
424db46347bSGordon Ross 		 * so we need to temporarily make those effective.
42529e6af5cSAlek Pinchuk 		 */
426db46347bSGordon Ross 		if (smb_proc_takesem() == 0) {
427db46347bSGordon Ross 
428db46347bSGordon Ross 			(void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
429db46347bSGordon Ross 			    PRIV_FILE_DAC_READ,
430db46347bSGordon Ross 			    PRIV_FILE_DAC_SEARCH,
431db46347bSGordon Ross 			    PRIV_FILE_DAC_WRITE,
432db46347bSGordon Ross 			    NULL);
433db46347bSGordon Ross 
434db46347bSGordon Ross 			rc = stat(si->shr_path, &st);
435db46347bSGordon Ross 			if (rc == 0) {
436db46347bSGordon Ross 				smb_shr_zfs_add(si);
437db46347bSGordon Ross 				created_zfs = B_TRUE;
438db46347bSGordon Ross 			}
439db46347bSGordon Ross 
440db46347bSGordon Ross 			(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
441db46347bSGordon Ross 			    PRIV_FILE_DAC_READ,
442db46347bSGordon Ross 			    PRIV_FILE_DAC_SEARCH,
443db46347bSGordon Ross 			    PRIV_FILE_DAC_WRITE,
444db46347bSGordon Ross 			    NULL);
445db46347bSGordon Ross 			smb_proc_givesem();
446db46347bSGordon Ross 		} else {
447db46347bSGordon Ross 			rc = NERR_InternalError;
448db46347bSGordon Ross 		}
44929e6af5cSAlek Pinchuk 		if (rc != 0) {
45029e6af5cSAlek Pinchuk 			smb_shr_cache_unlock();
45129e6af5cSAlek Pinchuk 			return (NERR_ItemNotFound);
45229e6af5cSAlek Pinchuk 		}
45329e6af5cSAlek Pinchuk 	}
45429e6af5cSAlek Pinchuk 
455b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if ((status = smb_shr_cache_addent(si)) != NERR_Success) {
456db46347bSGordon Ross 		/* This error should be impossible after findent above. */
457b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache_unlock();
458b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (status);
459da6c28aaSamw 	}
460da6c28aaSamw 
461b89a8333Snatalie li - Sun Microsystems - Irvine United States 	/* don't hold the lock across door call */
462b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_shr_cache_unlock();
463b89a8333Snatalie li - Sun Microsystems - Irvine United States 
464148c5f43SAlan Wright 	if ((rc = smb_shr_encode(si, &shrlist)) == 0) {
465148c5f43SAlan Wright 		/* send the share to kernel */
466148c5f43SAlan Wright 		rc = smb_kmod_share(shrlist);
467148c5f43SAlan Wright 		nvlist_free(shrlist);
468c8ec8eeaSjose borrego 
469148c5f43SAlan Wright 		if (rc == 0) {
470148c5f43SAlan Wright 			smb_shr_publish(si->shr_name, si->shr_container);
471743a77edSAlan Wright 
472cb174861Sjoyce mcintosh 			if ((si->shr_flags & SMB_SHRF_DFSROOT) != 0)
473cb174861Sjoyce mcintosh 				dfs_namespace_load(si->shr_name);
474cb174861Sjoyce mcintosh 
475148c5f43SAlan Wright 			return (NERR_Success);
476148c5f43SAlan Wright 		}
477c8ec8eeaSjose borrego 	}
478c8ec8eeaSjose borrego 
479db46347bSGordon Ross 	/*
480db46347bSGordon Ross 	 * Error code path, i.e. when the kernel could not accept
481db46347bSGordon Ross 	 * the new share for some reason.
482db46347bSGordon Ross 	 */
483b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (smb_shr_cache_lock(SMB_SHR_CACHE_WRLOCK) == NERR_Success) {
484b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache_delent(si->shr_name);
485b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache_unlock();
486b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
487da6c28aaSamw 
488db46347bSGordon Ross 	if (created_zfs && smb_proc_takesem() == 0) {
489db46347bSGordon Ross 
490db46347bSGordon Ross 		(void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
491db46347bSGordon Ross 		    PRIV_FILE_DAC_READ,
492db46347bSGordon Ross 		    PRIV_FILE_DAC_SEARCH,
493db46347bSGordon Ross 		    PRIV_FILE_DAC_WRITE,
494db46347bSGordon Ross 		    NULL);
495db46347bSGordon Ross 
496db46347bSGordon Ross 		smb_shr_zfs_remove(si);
497db46347bSGordon Ross 
498db46347bSGordon Ross 		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
499db46347bSGordon Ross 		    PRIV_FILE_DAC_READ,
500db46347bSGordon Ross 		    PRIV_FILE_DAC_SEARCH,
501db46347bSGordon Ross 		    PRIV_FILE_DAC_WRITE,
502db46347bSGordon Ross 		    NULL);
503db46347bSGordon Ross 
504db46347bSGordon Ross 		smb_proc_givesem();
505db46347bSGordon Ross 	}
506db46347bSGordon Ross 
507c8ec8eeaSjose borrego 	/*
508c8ec8eeaSjose borrego 	 * rc == ENOENT means the shared directory doesn't exist
509c8ec8eeaSjose borrego 	 */
510c8ec8eeaSjose borrego 	return ((rc == ENOENT) ? NERR_UnknownDevDir : NERR_InternalError);
511da6c28aaSamw }
512da6c28aaSamw 
513da6c28aaSamw /*
514b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Removes the specified share from cache, removes it from AD
515b89a8333Snatalie li - Sun Microsystems - Irvine United States  * if it has an AD container, and calls the kernel to release
516b89a8333Snatalie li - Sun Microsystems - Irvine United States  * the hold on the shared file system.
517da6c28aaSamw  *
518b89a8333Snatalie li - Sun Microsystems - Irvine United States  * If this is an autohome share then decrement the reference
519b89a8333Snatalie li - Sun Microsystems - Irvine United States  * count. If it reaches 0 then it proceeds with removing steps.
520da6c28aaSamw  */
5213db3f65cSamw uint32_t
smb_shr_remove(char * sharename)522b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_remove(char *sharename)
523da6c28aaSamw {
524b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_share_t *si;
525b89a8333Snatalie li - Sun Microsystems - Irvine United States 	char container[MAXPATHLEN];
5269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	boolean_t dfsroot;
527148c5f43SAlan Wright 	nvlist_t *shrlist;
528da6c28aaSamw 
529c8ec8eeaSjose borrego 	assert(sharename != NULL);
530da6c28aaSamw 
531fe1c642dSBill Krier 	if (smb_name_validate_share(sharename) != ERROR_SUCCESS)
532b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (ERROR_INVALID_NAME);
533b89a8333Snatalie li - Sun Microsystems - Irvine United States 
534b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (smb_shr_cache_lock(SMB_SHR_CACHE_WRLOCK) != NERR_Success)
535b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (NERR_InternalError);
536b89a8333Snatalie li - Sun Microsystems - Irvine United States 
537b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if ((si = smb_shr_cache_findent(sharename)) == NULL) {
538b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache_unlock();
539b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (NERR_NetNameNotFound);
540b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
541da6c28aaSamw 
54229e6af5cSAlek Pinchuk 	if (STYPE_ISIPC(si->shr_type)) {
543b89a8333Snatalie li - Sun Microsystems - Irvine United States 		/* IPC$ share cannot be removed */
544b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache_unlock();
545c8ec8eeaSjose borrego 		return (ERROR_ACCESS_DENIED);
546b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
547da6c28aaSamw 
548b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (si->shr_flags & SMB_SHRF_AUTOHOME) {
549b89a8333Snatalie li - Sun Microsystems - Irvine United States 		if ((--si->shr_refcnt) > 0) {
550b89a8333Snatalie li - Sun Microsystems - Irvine United States 			smb_shr_cache_unlock();
551b89a8333Snatalie li - Sun Microsystems - Irvine United States 			return (NERR_Success);
552da6c28aaSamw 		}
553da6c28aaSamw 	}
554da6c28aaSamw 
555743a77edSAlan Wright 	/*
556743a77edSAlan Wright 	 * If path is ZFS, remove the .zfs/shares/<share> entry.  Need
557db46347bSGordon Ross 	 * to remove before cleanup of cache occurs.  These actions
558db46347bSGordon Ross 	 * require temporary elevation of privileges.
559743a77edSAlan Wright 	 */
560db46347bSGordon Ross 	if (smb_proc_takesem() == 0) {
561db46347bSGordon Ross 
562db46347bSGordon Ross 		(void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
563db46347bSGordon Ross 		    PRIV_FILE_DAC_READ,
564db46347bSGordon Ross 		    PRIV_FILE_DAC_SEARCH,
565db46347bSGordon Ross 		    PRIV_FILE_DAC_WRITE,
566db46347bSGordon Ross 		    NULL);
567db46347bSGordon Ross 
568db46347bSGordon Ross 		smb_shr_zfs_remove(si);
569db46347bSGordon Ross 
570db46347bSGordon Ross 		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
571db46347bSGordon Ross 		    PRIV_FILE_DAC_READ,
572db46347bSGordon Ross 		    PRIV_FILE_DAC_SEARCH,
573db46347bSGordon Ross 		    PRIV_FILE_DAC_WRITE,
574db46347bSGordon Ross 		    NULL);
575db46347bSGordon Ross 
576db46347bSGordon Ross 		smb_proc_givesem();
577db46347bSGordon Ross 	}
578db46347bSGordon Ross 
579148c5f43SAlan Wright 	(void) smb_shr_encode(si, &shrlist);
580743a77edSAlan Wright 
581b89a8333Snatalie li - Sun Microsystems - Irvine United States 	(void) strlcpy(container, si->shr_container, sizeof (container));
5829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	dfsroot = ((si->shr_flags & SMB_SHRF_DFSROOT) != 0);
583b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_shr_cache_delent(sharename);
584b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_shr_cache_unlock();
585da6c28aaSamw 
586b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_shr_unpublish(sharename, container);
587b89a8333Snatalie li - Sun Microsystems - Irvine United States 
588b89a8333Snatalie li - Sun Microsystems - Irvine United States 	/* call kernel to release the hold on the shared file system */
589148c5f43SAlan Wright 	if (shrlist != NULL) {
590148c5f43SAlan Wright 		(void) smb_kmod_unshare(shrlist);
591148c5f43SAlan Wright 		nvlist_free(shrlist);
592148c5f43SAlan Wright 	}
593da6c28aaSamw 
5949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (dfsroot)
5959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		dfs_namespace_unload(sharename);
5969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
597da6c28aaSamw 	return (NERR_Success);
598da6c28aaSamw }
599da6c28aaSamw 
600da6c28aaSamw /*
601da6c28aaSamw  * Rename a share. Check that the current name exists and the new name
602da6c28aaSamw  * doesn't exist. The rename is performed by deleting the current share
603da6c28aaSamw  * definition and creating a new share with the new name.
604da6c28aaSamw  */
6053db3f65cSamw uint32_t
smb_shr_rename(char * from_name,char * to_name)606c8ec8eeaSjose borrego smb_shr_rename(char *from_name, char *to_name)
607da6c28aaSamw {
608b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_share_t *from_si;
609b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_share_t to_si;
610c8ec8eeaSjose borrego 	uint32_t status;
611148c5f43SAlan Wright 	nvlist_t *shrlist;
612da6c28aaSamw 
613c8ec8eeaSjose borrego 	assert((from_name != NULL) && (to_name != NULL));
614da6c28aaSamw 
615fe1c642dSBill Krier 	if (smb_name_validate_share(from_name) != ERROR_SUCCESS ||
616fe1c642dSBill Krier 	    smb_name_validate_share(to_name) != ERROR_SUCCESS)
617c8ec8eeaSjose borrego 		return (ERROR_INVALID_NAME);
618da6c28aaSamw 
619b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (smb_shr_cache_lock(SMB_SHR_CACHE_WRLOCK) != NERR_Success)
620b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (NERR_InternalError);
621b89a8333Snatalie li - Sun Microsystems - Irvine United States 
622b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if ((from_si = smb_shr_cache_findent(from_name)) == NULL) {
623b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache_unlock();
624da6c28aaSamw 		return (NERR_NetNameNotFound);
625b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
626da6c28aaSamw 
62729e6af5cSAlek Pinchuk 	if (STYPE_ISIPC(from_si->shr_type)) {
628b89a8333Snatalie li - Sun Microsystems - Irvine United States 		/* IPC$ share cannot be renamed */
629b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache_unlock();
630b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (ERROR_ACCESS_DENIED);
631b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
632da6c28aaSamw 
633b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (smb_shr_cache_findent(to_name) != NULL) {
634b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache_unlock();
635b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (NERR_DuplicateShare);
636b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
637c8ec8eeaSjose borrego 
638b89a8333Snatalie li - Sun Microsystems - Irvine United States 	bcopy(from_si, &to_si, sizeof (smb_share_t));
639b89a8333Snatalie li - Sun Microsystems - Irvine United States 	(void) strlcpy(to_si.shr_name, to_name, sizeof (to_si.shr_name));
640da6c28aaSamw 
641743a77edSAlan Wright 	/* If path is ZFS, rename the .zfs/shares/<share> entry. */
642db46347bSGordon Ross 	if (smb_proc_takesem() == 0) {
643db46347bSGordon Ross 
644db46347bSGordon Ross 		(void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
645db46347bSGordon Ross 		    PRIV_FILE_DAC_READ,
646db46347bSGordon Ross 		    PRIV_FILE_DAC_SEARCH,
647db46347bSGordon Ross 		    PRIV_FILE_DAC_WRITE,
648db46347bSGordon Ross 		    NULL);
649db46347bSGordon Ross 
650db46347bSGordon Ross 		smb_shr_zfs_rename(from_si, &to_si);
651db46347bSGordon Ross 
652db46347bSGordon Ross 		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
653db46347bSGordon Ross 		    PRIV_FILE_DAC_READ,
654db46347bSGordon Ross 		    PRIV_FILE_DAC_SEARCH,
655db46347bSGordon Ross 		    PRIV_FILE_DAC_WRITE,
656db46347bSGordon Ross 		    NULL);
657db46347bSGordon Ross 
658db46347bSGordon Ross 		smb_proc_givesem();
659db46347bSGordon Ross 	}
660743a77edSAlan Wright 
661b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if ((status = smb_shr_cache_addent(&to_si)) != NERR_Success) {
662b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache_unlock();
663c8ec8eeaSjose borrego 		return (status);
664b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
665c8ec8eeaSjose borrego 
666c8ec8eeaSjose borrego 	smb_shr_cache_delent(from_name);
667b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_shr_cache_unlock();
668b89a8333Snatalie li - Sun Microsystems - Irvine United States 
669148c5f43SAlan Wright 	if (smb_shr_encode(from_si, &shrlist) == 0) {
670148c5f43SAlan Wright 		(void) smb_kmod_unshare(shrlist);
671148c5f43SAlan Wright 		nvlist_free(shrlist);
672148c5f43SAlan Wright 
673148c5f43SAlan Wright 		if (smb_shr_encode(&to_si, &shrlist) == 0) {
674148c5f43SAlan Wright 			(void) smb_kmod_share(shrlist);
675148c5f43SAlan Wright 			nvlist_free(shrlist);
676148c5f43SAlan Wright 		}
677148c5f43SAlan Wright 	}
678148c5f43SAlan Wright 
679b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_shr_unpublish(from_name, to_si.shr_container);
680b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_shr_publish(to_name, to_si.shr_container);
681da6c28aaSamw 
682c8ec8eeaSjose borrego 	return (NERR_Success);
683da6c28aaSamw }
684da6c28aaSamw 
685da6c28aaSamw /*
686c8ec8eeaSjose borrego  * Load the information for the specified share into the supplied share
687c8ec8eeaSjose borrego  * info structure.
6888d7e4166Sjose borrego  *
6898d7e4166Sjose borrego  * First looks up the cache to see if the specified share exists, if there
6908d7e4166Sjose borrego  * is a miss then it looks up sharemgr.
691da6c28aaSamw  */
692c8ec8eeaSjose borrego uint32_t
smb_shr_get(char * sharename,smb_share_t * si)693c8ec8eeaSjose borrego smb_shr_get(char *sharename, smb_share_t *si)
694da6c28aaSamw {
6958d7e4166Sjose borrego 	uint32_t status;
696c8ec8eeaSjose borrego 
697b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (sharename == NULL || *sharename == '\0')
698c8ec8eeaSjose borrego 		return (NERR_NetNameNotFound);
699c8ec8eeaSjose borrego 
7008d7e4166Sjose borrego 	if ((status = smb_shr_lookup(sharename, si)) == NERR_Success)
7018d7e4166Sjose borrego 		return (status);
702b89a8333Snatalie li - Sun Microsystems - Irvine United States 
7038d7e4166Sjose borrego 	if ((status = smb_shr_sa_loadbyname(sharename)) == NERR_Success)
7048d7e4166Sjose borrego 		status = smb_shr_lookup(sharename, si);
705c8ec8eeaSjose borrego 
706b89a8333Snatalie li - Sun Microsystems - Irvine United States 	return (status);
707da6c28aaSamw }
708da6c28aaSamw 
709da6c28aaSamw /*
710c8ec8eeaSjose borrego  * Modifies an existing share. Properties that can be modified are:
711da6c28aaSamw  *
712c8ec8eeaSjose borrego  *   o comment
713c8ec8eeaSjose borrego  *   o AD container
714b89a8333Snatalie li - Sun Microsystems - Irvine United States  *   o host access
715ca5fb90aSGordon Ross  *   o flags
716da6c28aaSamw  */
717c8ec8eeaSjose borrego uint32_t
smb_shr_modify(smb_share_t * new_si)718b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_modify(smb_share_t *new_si)
719da6c28aaSamw {
720ca5fb90aSGordon Ross 	smb_share_t old_si;
721b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_share_t *si;
722c8ec8eeaSjose borrego 	boolean_t adc_changed = B_FALSE;
723ca5fb90aSGordon Ross 	boolean_t quota_flag_changed = B_FALSE;
7249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	uint32_t access, flag;
725148c5f43SAlan Wright 	nvlist_t *shrlist;
726da6c28aaSamw 
727b89a8333Snatalie li - Sun Microsystems - Irvine United States 	assert(new_si != NULL);
728da6c28aaSamw 
729b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (smb_shr_cache_lock(SMB_SHR_CACHE_WRLOCK) != NERR_Success)
730b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (NERR_InternalError);
731c8ec8eeaSjose borrego 
732b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if ((si = smb_shr_cache_findent(new_si->shr_name)) == NULL) {
733b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache_unlock();
734b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (NERR_NetNameNotFound);
735c8ec8eeaSjose borrego 	}
736c8ec8eeaSjose borrego 
73729e6af5cSAlek Pinchuk 	if (STYPE_ISIPC(si->shr_type)) {
738b89a8333Snatalie li - Sun Microsystems - Irvine United States 		/* IPC$ share cannot be modified */
739b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache_unlock();
740b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (ERROR_ACCESS_DENIED);
741c8ec8eeaSjose borrego 	}
742c8ec8eeaSjose borrego 
743ca5fb90aSGordon Ross 	/*
744ca5fb90aSGordon Ross 	 * Keep a copy of what the share entry looks like before we
745ca5fb90aSGordon Ross 	 * modify it.  We need this for things like unpublishing
746ca5fb90aSGordon Ross 	 * from the old share container, removing the quota dir.
747ca5fb90aSGordon Ross 	 */
748ca5fb90aSGordon Ross 	bcopy(si, &old_si, sizeof (old_si));
749ca5fb90aSGordon Ross 
750ca5fb90aSGordon Ross 	/* Share comment */
75189dc44ceSjose borrego 	(void) strlcpy(si->shr_cmnt, new_si->shr_cmnt, sizeof (si->shr_cmnt));
752c8ec8eeaSjose borrego 
753ca5fb90aSGordon Ross 	/* Container */
754ca5fb90aSGordon Ross 	(void) strlcpy(si->shr_container, new_si->shr_container,
755ca5fb90aSGordon Ross 	    sizeof (si->shr_container));
756ca5fb90aSGordon Ross 	adc_changed = (strcmp(old_si.shr_container, si->shr_container) != 0);
757c8ec8eeaSjose borrego 
7589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	flag = (new_si->shr_flags & SMB_SHRF_ABE);
759e3f2c991SKeyur Desai 	si->shr_flags &= ~SMB_SHRF_ABE;
7609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	si->shr_flags |= flag;
761e3f2c991SKeyur Desai 
7629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	flag = (new_si->shr_flags & SMB_SHRF_CATIA);
7638b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	si->shr_flags &= ~SMB_SHRF_CATIA;
7649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	si->shr_flags |= flag;
7658b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 
7669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	flag = (new_si->shr_flags & SMB_SHRF_GUEST_OK);
7679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	si->shr_flags &= ~SMB_SHRF_GUEST_OK;
7689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	si->shr_flags |= flag;
76929bd2886SAlan Wright 
7709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	flag = (new_si->shr_flags & SMB_SHRF_DFSROOT);
7719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	si->shr_flags &= ~SMB_SHRF_DFSROOT;
7729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	si->shr_flags |= flag;
7739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
7748d94f651SGordon Ross 	flag = (new_si->shr_flags & SMB_SHRF_CA);
7758d94f651SGordon Ross 	si->shr_flags &= ~SMB_SHRF_CA;
7768d94f651SGordon Ross 	si->shr_flags |= flag;
7778d94f651SGordon Ross 
77894047d49SGordon Ross 	flag = (new_si->shr_flags & SMB_SHRF_FSO);
77994047d49SGordon Ross 	si->shr_flags &= ~SMB_SHRF_FSO;
78094047d49SGordon Ross 	si->shr_flags |= flag;
78194047d49SGordon Ross 
782ca5fb90aSGordon Ross 	flag = (new_si->shr_flags & SMB_SHRF_QUOTAS);
783ca5fb90aSGordon Ross 	si->shr_flags &= ~SMB_SHRF_QUOTAS;
784ca5fb90aSGordon Ross 	si->shr_flags |= flag;
785ca5fb90aSGordon Ross 	if ((old_si.shr_flags ^ si->shr_flags) & SMB_SHRF_QUOTAS)
786ca5fb90aSGordon Ross 		quota_flag_changed = B_TRUE;
787ca5fb90aSGordon Ross 
7889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	flag = (new_si->shr_flags & SMB_SHRF_CSC_MASK);
7899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	si->shr_flags &= ~SMB_SHRF_CSC_MASK;
7909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	si->shr_flags |= flag;
7918d7e4166Sjose borrego 
792b89a8333Snatalie li - Sun Microsystems - Irvine United States 	access = (new_si->shr_flags & SMB_SHRF_ACC_ALL);
79389dc44ceSjose borrego 	si->shr_flags &= ~SMB_SHRF_ACC_ALL;
794b89a8333Snatalie li - Sun Microsystems - Irvine United States 	si->shr_flags |= access;
795c8ec8eeaSjose borrego 
7961160dcf7SMatt Barden 	si->shr_encrypt = new_si->shr_encrypt;
7971160dcf7SMatt Barden 
798b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (access & SMB_SHRF_ACC_NONE)
799b89a8333Snatalie li - Sun Microsystems - Irvine United States 		(void) strlcpy(si->shr_access_none, new_si->shr_access_none,
800b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    sizeof (si->shr_access_none));
801c8ec8eeaSjose borrego 
802b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (access & SMB_SHRF_ACC_RO)
803b89a8333Snatalie li - Sun Microsystems - Irvine United States 		(void) strlcpy(si->shr_access_ro, new_si->shr_access_ro,
804b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    sizeof (si->shr_access_ro));
805c8ec8eeaSjose borrego 
806b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (access & SMB_SHRF_ACC_RW)
807b89a8333Snatalie li - Sun Microsystems - Irvine United States 		(void) strlcpy(si->shr_access_rw, new_si->shr_access_rw,
808b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    sizeof (si->shr_access_rw));
809c8ec8eeaSjose borrego 
810b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_shr_cache_unlock();
811b89a8333Snatalie li - Sun Microsystems - Irvine United States 
812148c5f43SAlan Wright 	if (smb_shr_encode(si, &shrlist) == 0) {
813148c5f43SAlan Wright 		(void) smb_kmod_unshare(shrlist);
814148c5f43SAlan Wright 		nvlist_free(shrlist);
815148c5f43SAlan Wright 
816148c5f43SAlan Wright 		if (smb_shr_encode(new_si, &shrlist) == 0) {
817148c5f43SAlan Wright 			(void) smb_kmod_share(shrlist);
818148c5f43SAlan Wright 			nvlist_free(shrlist);
819148c5f43SAlan Wright 		}
820148c5f43SAlan Wright 	}
821148c5f43SAlan Wright 
822b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (adc_changed) {
823ca5fb90aSGordon Ross 		smb_shr_unpublish(old_si.shr_name, old_si.shr_container);
824b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_publish(new_si->shr_name, new_si->shr_container);
825c8ec8eeaSjose borrego 	}
826c8ec8eeaSjose borrego 
827db46347bSGordon Ross 	/* The following required privileges we dropped. */
828db46347bSGordon Ross 	if (quota_flag_changed && smb_proc_takesem() == 0) {
829db46347bSGordon Ross 
830db46347bSGordon Ross 		(void) priv_set(PRIV_ON, PRIV_EFFECTIVE,
831db46347bSGordon Ross 		    PRIV_FILE_DAC_READ,
832db46347bSGordon Ross 		    PRIV_FILE_DAC_SEARCH,
833db46347bSGordon Ross 		    PRIV_FILE_DAC_WRITE,
834db46347bSGordon Ross 		    NULL);
835db46347bSGordon Ross 
836ca5fb90aSGordon Ross 		smb_shr_zfs_remove(&old_si);
837ca5fb90aSGordon Ross 		smb_shr_zfs_add(si);
838db46347bSGordon Ross 
839db46347bSGordon Ross 		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE,
840db46347bSGordon Ross 		    PRIV_FILE_DAC_READ,
841db46347bSGordon Ross 		    PRIV_FILE_DAC_SEARCH,
842db46347bSGordon Ross 		    PRIV_FILE_DAC_WRITE,
843db46347bSGordon Ross 		    NULL);
844db46347bSGordon Ross 
845db46347bSGordon Ross 		smb_proc_givesem();
846ca5fb90aSGordon Ross 	}
847ca5fb90aSGordon Ross 
848b89a8333Snatalie li - Sun Microsystems - Irvine United States 	return (NERR_Success);
849c8ec8eeaSjose borrego }
850c8ec8eeaSjose borrego 
851c8ec8eeaSjose borrego /*
852c8ec8eeaSjose borrego  * smb_shr_exists
853c8ec8eeaSjose borrego  *
854c8ec8eeaSjose borrego  * Returns B_TRUE if the share exists. Otherwise returns B_FALSE
855c8ec8eeaSjose borrego  */
856c8ec8eeaSjose borrego boolean_t
smb_shr_exists(char * sharename)857c8ec8eeaSjose borrego smb_shr_exists(char *sharename)
858c8ec8eeaSjose borrego {
859b89a8333Snatalie li - Sun Microsystems - Irvine United States 	boolean_t exists = B_FALSE;
860c8ec8eeaSjose borrego 
861c8ec8eeaSjose borrego 	if (sharename == NULL || *sharename == '\0')
862c8ec8eeaSjose borrego 		return (B_FALSE);
863c8ec8eeaSjose borrego 
864b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (smb_shr_cache_lock(SMB_SHR_CACHE_RDLOCK) == NERR_Success) {
865b89a8333Snatalie li - Sun Microsystems - Irvine United States 		exists = (smb_shr_cache_findent(sharename) != NULL);
866b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache_unlock();
867b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
868c8ec8eeaSjose borrego 
869c8ec8eeaSjose borrego 	return (exists);
870c8ec8eeaSjose borrego }
871c8ec8eeaSjose borrego 
872b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
873b89a8333Snatalie li - Sun Microsystems - Irvine United States  * If the shared directory does not begin with a /, one will be
874b89a8333Snatalie li - Sun Microsystems - Irvine United States  * inserted as a prefix. If ipaddr is not zero, then also return
875b89a8333Snatalie li - Sun Microsystems - Irvine United States  * information about access based on the host level access lists, if
876b89a8333Snatalie li - Sun Microsystems - Irvine United States  * present. Also return access check if there is an IP address and
877b89a8333Snatalie li - Sun Microsystems - Irvine United States  * shr_accflags.
878b89a8333Snatalie li - Sun Microsystems - Irvine United States  *
879b89a8333Snatalie li - Sun Microsystems - Irvine United States  * The value of smb_chk_hostaccess is checked for an access match.
880b89a8333Snatalie li - Sun Microsystems - Irvine United States  * -1 is wildcard match
881b89a8333Snatalie li - Sun Microsystems - Irvine United States  * 0 is no match
882b89a8333Snatalie li - Sun Microsystems - Irvine United States  * 1 is match
883b89a8333Snatalie li - Sun Microsystems - Irvine United States  *
884b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Precedence is none is checked first followed by ro then rw if
885b89a8333Snatalie li - Sun Microsystems - Irvine United States  * needed.  If x is wildcard (< 0) then check to see if the other
886b89a8333Snatalie li - Sun Microsystems - Irvine United States  * values are a match. If a match, that wins.
887b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
888148c5f43SAlan Wright uint32_t
smb_shr_hostaccess(smb_inaddr_t * ipaddr,char * none_list,char * ro_list,char * rw_list,uint32_t flag)889148c5f43SAlan Wright smb_shr_hostaccess(smb_inaddr_t *ipaddr, char *none_list, char *ro_list,
890148c5f43SAlan Wright     char *rw_list, uint32_t flag)
891b89a8333Snatalie li - Sun Microsystems - Irvine United States {
892148c5f43SAlan Wright 	uint32_t acc = SMB_SHRF_ACC_NONE;
893148c5f43SAlan Wright 	int none = 0;
894148c5f43SAlan Wright 	int ro = 0;
895148c5f43SAlan Wright 	int rw = 0;
896148c5f43SAlan Wright 
897148c5f43SAlan Wright 	if (!smb_inet_iszero(ipaddr)) {
898148c5f43SAlan Wright 		if ((flag & SMB_SHRF_ACC_NONE) != 0)
899148c5f43SAlan Wright 			none = smb_chk_hostaccess(ipaddr, none_list);
900148c5f43SAlan Wright 		if ((flag & SMB_SHRF_ACC_RO) != 0)
901148c5f43SAlan Wright 			ro = smb_chk_hostaccess(ipaddr, ro_list);
902148c5f43SAlan Wright 		if ((flag & SMB_SHRF_ACC_RW) != 0)
903148c5f43SAlan Wright 			rw = smb_chk_hostaccess(ipaddr, rw_list);
904b89a8333Snatalie li - Sun Microsystems - Irvine United States 
905b89a8333Snatalie li - Sun Microsystems - Irvine United States 		/* make first pass to get basic value */
906b89a8333Snatalie li - Sun Microsystems - Irvine United States 		if (none != 0)
907b89a8333Snatalie li - Sun Microsystems - Irvine United States 			acc = SMB_SHRF_ACC_NONE;
908b89a8333Snatalie li - Sun Microsystems - Irvine United States 		else if (ro != 0)
909b89a8333Snatalie li - Sun Microsystems - Irvine United States 			acc = SMB_SHRF_ACC_RO;
910b89a8333Snatalie li - Sun Microsystems - Irvine United States 		else if (rw != 0)
911b89a8333Snatalie li - Sun Microsystems - Irvine United States 			acc = SMB_SHRF_ACC_RW;
912b89a8333Snatalie li - Sun Microsystems - Irvine United States 
913b89a8333Snatalie li - Sun Microsystems - Irvine United States 		/* make second pass to handle '*' case */
914b89a8333Snatalie li - Sun Microsystems - Irvine United States 		if (none < 0) {
915b89a8333Snatalie li - Sun Microsystems - Irvine United States 			acc = SMB_SHRF_ACC_NONE;
916b89a8333Snatalie li - Sun Microsystems - Irvine United States 			if (ro > 0)
917b89a8333Snatalie li - Sun Microsystems - Irvine United States 				acc = SMB_SHRF_ACC_RO;
918b89a8333Snatalie li - Sun Microsystems - Irvine United States 			else if (rw > 0)
919b89a8333Snatalie li - Sun Microsystems - Irvine United States 				acc = SMB_SHRF_ACC_RW;
920b89a8333Snatalie li - Sun Microsystems - Irvine United States 		} else if (ro < 0) {
921b89a8333Snatalie li - Sun Microsystems - Irvine United States 			acc = SMB_SHRF_ACC_RO;
922b89a8333Snatalie li - Sun Microsystems - Irvine United States 			if (none > 0)
923b89a8333Snatalie li - Sun Microsystems - Irvine United States 				acc = SMB_SHRF_ACC_NONE;
924b89a8333Snatalie li - Sun Microsystems - Irvine United States 			else if (rw > 0)
925b89a8333Snatalie li - Sun Microsystems - Irvine United States 				acc = SMB_SHRF_ACC_RW;
926b89a8333Snatalie li - Sun Microsystems - Irvine United States 		} else if (rw < 0) {
927b89a8333Snatalie li - Sun Microsystems - Irvine United States 			acc = SMB_SHRF_ACC_RW;
928b89a8333Snatalie li - Sun Microsystems - Irvine United States 			if (none > 0)
929b89a8333Snatalie li - Sun Microsystems - Irvine United States 				acc = SMB_SHRF_ACC_NONE;
930b89a8333Snatalie li - Sun Microsystems - Irvine United States 			else if (ro > 0)
931b89a8333Snatalie li - Sun Microsystems - Irvine United States 				acc = SMB_SHRF_ACC_RO;
932b89a8333Snatalie li - Sun Microsystems - Irvine United States 		}
933b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
934148c5f43SAlan Wright 
935148c5f43SAlan Wright 	return (acc);
936b89a8333Snatalie li - Sun Microsystems - Irvine United States }
937b89a8333Snatalie li - Sun Microsystems - Irvine United States 
938c8ec8eeaSjose borrego /*
939c8ec8eeaSjose borrego  * smb_shr_is_special
940c8ec8eeaSjose borrego  *
941c8ec8eeaSjose borrego  * Special share reserved for interprocess communication (IPC$) or
942c8ec8eeaSjose borrego  * remote administration of the server (ADMIN$). Can also refer to
943c8ec8eeaSjose borrego  * administrative shares such as C$, D$, E$, and so forth.
944c8ec8eeaSjose borrego  */
945c8ec8eeaSjose borrego int
smb_shr_is_special(char * sharename)946c8ec8eeaSjose borrego smb_shr_is_special(char *sharename)
947c8ec8eeaSjose borrego {
948c8ec8eeaSjose borrego 	int len;
949c8ec8eeaSjose borrego 
950c8ec8eeaSjose borrego 	if (sharename == NULL)
951c8ec8eeaSjose borrego 		return (0);
952c8ec8eeaSjose borrego 
953c8ec8eeaSjose borrego 	if ((len = strlen(sharename)) == 0)
954c8ec8eeaSjose borrego 		return (0);
955c8ec8eeaSjose borrego 
956c8ec8eeaSjose borrego 	if (sharename[len - 1] == '$')
957c8ec8eeaSjose borrego 		return (STYPE_SPECIAL);
958c8ec8eeaSjose borrego 
959c8ec8eeaSjose borrego 	return (0);
960c8ec8eeaSjose borrego }
961c8ec8eeaSjose borrego 
962c8ec8eeaSjose borrego /*
963c8ec8eeaSjose borrego  * smb_shr_is_restricted
964c8ec8eeaSjose borrego  *
965da6c28aaSamw  * Check whether or not there is a restriction on a share. Restricted
966da6c28aaSamw  * shares are generally STYPE_SPECIAL, for example, IPC$. All the
967c8ec8eeaSjose borrego  * administration share names are restricted: C$, D$ etc. Returns B_TRUE
968c8ec8eeaSjose borrego  * if the share is restricted. Otherwise B_FALSE is returned to indicate
969da6c28aaSamw  * that there are no restrictions.
970da6c28aaSamw  */
971c8ec8eeaSjose borrego boolean_t
smb_shr_is_restricted(char * sharename)972c8ec8eeaSjose borrego smb_shr_is_restricted(char *sharename)
973da6c28aaSamw {
974da6c28aaSamw 	static char *restricted[] = {
975da6c28aaSamw 		"IPC$"
976da6c28aaSamw 	};
977da6c28aaSamw 
978da6c28aaSamw 	int i;
979da6c28aaSamw 
980c8ec8eeaSjose borrego 	if (sharename == NULL)
981c8ec8eeaSjose borrego 		return (B_FALSE);
982c8ec8eeaSjose borrego 
983da6c28aaSamw 	for (i = 0; i < sizeof (restricted)/sizeof (restricted[0]); i++) {
984bbf6f00cSJordan Brown 		if (smb_strcasecmp(restricted[i], sharename, 0) == 0)
985c8ec8eeaSjose borrego 			return (B_TRUE);
986da6c28aaSamw 	}
987da6c28aaSamw 
988c8ec8eeaSjose borrego 	return (smb_shr_is_admin(sharename));
989da6c28aaSamw }
990da6c28aaSamw 
991da6c28aaSamw /*
9923db3f65cSamw  * smb_shr_is_admin
993da6c28aaSamw  *
994da6c28aaSamw  * Check whether or not access to the share should be restricted to
995da6c28aaSamw  * administrators. This is a bit of a hack because what we're doing
996da6c28aaSamw  * is checking for the default admin shares: C$, D$ etc.. There are
9973db3f65cSamw  * other shares that have restrictions: see smb_shr_is_restricted().
998da6c28aaSamw  *
999c8ec8eeaSjose borrego  * Returns B_TRUE if the shares is an admin share. Otherwise B_FALSE
1000c8ec8eeaSjose borrego  * is returned to indicate that there are no restrictions.
1001da6c28aaSamw  */
1002c8ec8eeaSjose borrego boolean_t
smb_shr_is_admin(char * sharename)1003c8ec8eeaSjose borrego smb_shr_is_admin(char *sharename)
1004da6c28aaSamw {
1005c8ec8eeaSjose borrego 	if (sharename == NULL)
1006c8ec8eeaSjose borrego 		return (B_FALSE);
1007da6c28aaSamw 
1008c8ec8eeaSjose borrego 	if (strlen(sharename) == 2 &&
1009bbf6f00cSJordan Brown 	    smb_isalpha(sharename[0]) && sharename[1] == '$') {
1010c8ec8eeaSjose borrego 		return (B_TRUE);
1011da6c28aaSamw 	}
1012da6c28aaSamw 
1013c8ec8eeaSjose borrego 	return (B_FALSE);
1014da6c28aaSamw }
1015da6c28aaSamw 
1016c5866007SKeyur Desai char
smb_shr_drive_letter(const char * path)1017c5866007SKeyur Desai smb_shr_drive_letter(const char *path)
1018c5866007SKeyur Desai {
1019c5866007SKeyur Desai 	smb_transient_t	*ts;
1020c5866007SKeyur Desai 	int i;
1021c5866007SKeyur Desai 
1022c5866007SKeyur Desai 	if (path == NULL)
1023c5866007SKeyur Desai 		return ('\0');
1024c5866007SKeyur Desai 
1025c5866007SKeyur Desai 	for (i = 0; i < sizeof (tshare)/sizeof (tshare[0]); ++i) {
1026c5866007SKeyur Desai 		ts = &tshare[i];
1027c5866007SKeyur Desai 
1028c5866007SKeyur Desai 		if (ts->path == NULL)
1029c5866007SKeyur Desai 			continue;
1030c5866007SKeyur Desai 
1031c5866007SKeyur Desai 		if (strcasecmp(ts->path, path) == 0)
1032c5866007SKeyur Desai 			return (ts->drive);
1033c5866007SKeyur Desai 	}
1034c5866007SKeyur Desai 
1035c5866007SKeyur Desai 	return ('\0');
1036c5866007SKeyur Desai }
1037c5866007SKeyur Desai 
1038c5866007SKeyur Desai /*
1039c5866007SKeyur Desai  * Returns true if the specified directory is empty,
1040c5866007SKeyur Desai  * otherwise returns false.
1041c5866007SKeyur Desai  */
1042c5866007SKeyur Desai static boolean_t
smb_shr_is_empty(const char * path)1043c5866007SKeyur Desai smb_shr_is_empty(const char *path)
1044c5866007SKeyur Desai {
1045c5866007SKeyur Desai 	DIR *dirp;
1046c5866007SKeyur Desai 	struct dirent *dp;
1047c5866007SKeyur Desai 
1048c5866007SKeyur Desai 	if (path == NULL)
1049c5866007SKeyur Desai 		return (B_TRUE);
1050c5866007SKeyur Desai 
1051c5866007SKeyur Desai 	if ((dirp = opendir(path)) == NULL)
1052c5866007SKeyur Desai 		return (B_TRUE);
1053c5866007SKeyur Desai 
1054c5866007SKeyur Desai 	while ((dp = readdir(dirp)) != NULL) {
1055c5866007SKeyur Desai 		if (!smb_shr_is_dot_or_dotdot(dp->d_name))
1056c5866007SKeyur Desai 			return (B_FALSE);
1057c5866007SKeyur Desai 	}
1058c5866007SKeyur Desai 
1059c5866007SKeyur Desai 	(void) closedir(dirp);
1060c5866007SKeyur Desai 	return (B_TRUE);
1061c5866007SKeyur Desai }
1062c5866007SKeyur Desai 
1063c5866007SKeyur Desai /*
1064c5866007SKeyur Desai  * Returns true if name is "." or "..", otherwise returns false.
1065c5866007SKeyur Desai  */
1066c5866007SKeyur Desai static boolean_t
smb_shr_is_dot_or_dotdot(const char * name)1067c5866007SKeyur Desai smb_shr_is_dot_or_dotdot(const char *name)
1068c5866007SKeyur Desai {
1069c5866007SKeyur Desai 	if (*name != '.')
1070c5866007SKeyur Desai 		return (B_FALSE);
1071c5866007SKeyur Desai 
1072c5866007SKeyur Desai 	if ((name[1] == '\0') || (name[1] == '.' && name[2] == '\0'))
1073c5866007SKeyur Desai 		return (B_TRUE);
1074c5866007SKeyur Desai 
1075c5866007SKeyur Desai 	return (B_FALSE);
1076c5866007SKeyur Desai }
1077c5866007SKeyur Desai 
1078da6c28aaSamw /*
1079c8ec8eeaSjose borrego  * smb_shr_get_realpath
1080c8ec8eeaSjose borrego  *
1081b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Derive the real path for a share from the path provided by a client.
1082b89a8333Snatalie li - Sun Microsystems - Irvine United States  * For instance, the real path of C:\ may be /cvol or the real path of
1083b89a8333Snatalie li - Sun Microsystems - Irvine United States  * F:\home may be /vol1/home.
1084da6c28aaSamw  *
1085b89a8333Snatalie li - Sun Microsystems - Irvine United States  * clntpath - path provided by the Windows client is in the
1086c8ec8eeaSjose borrego  *            format of <drive letter>:\<dir>
1087c8ec8eeaSjose borrego  * realpath - path that will be stored as the directory field of
1088c8ec8eeaSjose borrego  *            the smb_share_t structure of the share.
1089b89a8333Snatalie li - Sun Microsystems - Irvine United States  * maxlen   - maximum length of the realpath buffer
1090da6c28aaSamw  *
1091c8ec8eeaSjose borrego  * Return LAN Manager network error code.
1092da6c28aaSamw  */
1093c8ec8eeaSjose borrego uint32_t
smb_shr_get_realpath(const char * clntpath,char * realpath,int maxlen)1094b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_get_realpath(const char *clntpath, char *realpath, int maxlen)
1095da6c28aaSamw {
1096b89a8333Snatalie li - Sun Microsystems - Irvine United States 	const char *p;
1097b89a8333Snatalie li - Sun Microsystems - Irvine United States 	int len;
1098b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1099b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if ((p = strchr(clntpath, ':')) != NULL)
1100b89a8333Snatalie li - Sun Microsystems - Irvine United States 		++p;
1101b89a8333Snatalie li - Sun Microsystems - Irvine United States 	else
1102b89a8333Snatalie li - Sun Microsystems - Irvine United States 		p = clntpath;
1103b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1104b89a8333Snatalie li - Sun Microsystems - Irvine United States 	(void) strlcpy(realpath, p, maxlen);
1105b89a8333Snatalie li - Sun Microsystems - Irvine United States 	(void) strcanon(realpath, "/\\");
1106b89a8333Snatalie li - Sun Microsystems - Irvine United States 	(void) strsubst(realpath, '\\', '/');
1107b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1108b89a8333Snatalie li - Sun Microsystems - Irvine United States 	len = strlen(realpath);
1109b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if ((len > 1) && (realpath[len - 1] == '/'))
1110b89a8333Snatalie li - Sun Microsystems - Irvine United States 		realpath[len - 1] = '\0';
1111b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1112c8ec8eeaSjose borrego 	return (NERR_Success);
1113c8ec8eeaSjose borrego }
1114da6c28aaSamw 
1115b89a8333Snatalie li - Sun Microsystems - Irvine United States void
smb_shr_list(int offset,smb_shrlist_t * list)1116b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_list(int offset, smb_shrlist_t *list)
1117b89a8333Snatalie li - Sun Microsystems - Irvine United States {
1118b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_shriter_t iterator;
1119b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_share_t *si;
1120b89a8333Snatalie li - Sun Microsystems - Irvine United States 	int n = 0;
1121b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1122b89a8333Snatalie li - Sun Microsystems - Irvine United States 	bzero(list, sizeof (smb_shrlist_t));
1123b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_shr_iterinit(&iterator);
1124b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1125b89a8333Snatalie li - Sun Microsystems - Irvine United States 	while ((si = smb_shr_iterate(&iterator)) != NULL) {
1126b89a8333Snatalie li - Sun Microsystems - Irvine United States 		if (--offset > 0)
1127b89a8333Snatalie li - Sun Microsystems - Irvine United States 			continue;
1128b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1129b89a8333Snatalie li - Sun Microsystems - Irvine United States 		if ((si->shr_flags & SMB_SHRF_TRANS) &&
113029e6af5cSAlek Pinchuk 		    (!STYPE_ISIPC(si->shr_type))) {
1131b89a8333Snatalie li - Sun Microsystems - Irvine United States 			bcopy(si, &list->sl_shares[n], sizeof (smb_share_t));
1132b89a8333Snatalie li - Sun Microsystems - Irvine United States 			if (++n == LMSHARES_PER_REQUEST)
1133b89a8333Snatalie li - Sun Microsystems - Irvine United States 				break;
1134b89a8333Snatalie li - Sun Microsystems - Irvine United States 		}
1135b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
1136b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1137b89a8333Snatalie li - Sun Microsystems - Irvine United States 	list->sl_cnt = n;
1138b89a8333Snatalie li - Sun Microsystems - Irvine United States }
1139b89a8333Snatalie li - Sun Microsystems - Irvine United States 
114029bd2886SAlan Wright /*
114129bd2886SAlan Wright  * Executes the map/unmap command associated with a share.
114229bd2886SAlan Wright  *
114329bd2886SAlan Wright  * Returns 0 on success.  Otherwise non-zero for errors.
114429bd2886SAlan Wright  */
114529bd2886SAlan Wright int
smb_shr_exec(smb_shr_execinfo_t * subs)1146148c5f43SAlan Wright smb_shr_exec(smb_shr_execinfo_t *subs)
114729bd2886SAlan Wright {
114829bd2886SAlan Wright 	char cmd[MAXPATHLEN], **cmd_tokens, *path, *ptr;
114929bd2886SAlan Wright 	pid_t child_pid;
115029bd2886SAlan Wright 	int child_status;
115129bd2886SAlan Wright 	struct sigaction pact, cact;
115229bd2886SAlan Wright 	smb_share_t si;
115329bd2886SAlan Wright 
1154148c5f43SAlan Wright 	if (smb_shr_get(subs->e_sharename, &si) != 0)
115529bd2886SAlan Wright 		return (-1);
115629bd2886SAlan Wright 
115729bd2886SAlan Wright 	*cmd = '\0';
115829bd2886SAlan Wright 
115929bd2886SAlan Wright 	(void) mutex_lock(&smb_shr_exec_mtx);
116029bd2886SAlan Wright 
1161148c5f43SAlan Wright 	switch (subs->e_type) {
1162148c5f43SAlan Wright 	case SMB_EXEC_MAP:
116329bd2886SAlan Wright 		(void) strlcpy(cmd, smb_shr_exec_map, sizeof (cmd));
116429bd2886SAlan Wright 		break;
1165148c5f43SAlan Wright 	case SMB_EXEC_UNMAP:
116629bd2886SAlan Wright 		(void) strlcpy(cmd, smb_shr_exec_unmap, sizeof (cmd));
116729bd2886SAlan Wright 		break;
116829bd2886SAlan Wright 	default:
116929bd2886SAlan Wright 		(void) mutex_unlock(&smb_shr_exec_mtx);
117029bd2886SAlan Wright 		return (-1);
117129bd2886SAlan Wright 	}
117229bd2886SAlan Wright 
117329bd2886SAlan Wright 	(void) mutex_unlock(&smb_shr_exec_mtx);
117429bd2886SAlan Wright 
117529bd2886SAlan Wright 	if (*cmd == '\0')
117629bd2886SAlan Wright 		return (0);
117729bd2886SAlan Wright 
1178e3f2c991SKeyur Desai 	if (smb_proc_takesem() != 0)
1179e3f2c991SKeyur Desai 		return (-1);
1180e3f2c991SKeyur Desai 
118129bd2886SAlan Wright 	pact.sa_handler = smb_shr_sig_child;
118229bd2886SAlan Wright 	pact.sa_flags = 0;
118329bd2886SAlan Wright 	(void) sigemptyset(&pact.sa_mask);
118429bd2886SAlan Wright 	sigaction(SIGCHLD, &pact, NULL);
118529bd2886SAlan Wright 
118629bd2886SAlan Wright 	(void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_PROC_FORK, NULL);
118729bd2886SAlan Wright 
118829bd2886SAlan Wright 	if ((child_pid = fork()) == -1) {
118929bd2886SAlan Wright 		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_PROC_FORK, NULL);
1190e3f2c991SKeyur Desai 		smb_proc_givesem();
119129bd2886SAlan Wright 		return (-1);
119229bd2886SAlan Wright 	}
119329bd2886SAlan Wright 
119429bd2886SAlan Wright 	if (child_pid == 0) {
119529bd2886SAlan Wright 
119629bd2886SAlan Wright 		/* child process */
119729bd2886SAlan Wright 
119829bd2886SAlan Wright 		cact.sa_handler = smb_shr_sig_abnormal_term;
119929bd2886SAlan Wright 		cact.sa_flags = 0;
120029bd2886SAlan Wright 		(void) sigemptyset(&cact.sa_mask);
120129bd2886SAlan Wright 		sigaction(SIGTERM, &cact, NULL);
120229bd2886SAlan Wright 		sigaction(SIGABRT, &cact, NULL);
120329bd2886SAlan Wright 		sigaction(SIGSEGV, &cact, NULL);
120429bd2886SAlan Wright 
120529bd2886SAlan Wright 		if (priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_PROC_EXEC,
120629bd2886SAlan Wright 		    PRIV_FILE_DAC_EXECUTE, NULL))
120729bd2886SAlan Wright 			_exit(-1);
120829bd2886SAlan Wright 
120929bd2886SAlan Wright 		if (smb_shr_enable_all_privs())
121029bd2886SAlan Wright 			_exit(-1);
121129bd2886SAlan Wright 
1212e3f2c991SKeyur Desai 		smb_proc_initsem();
1213e3f2c991SKeyur Desai 
121429bd2886SAlan Wright 		(void) trim_whitespace(cmd);
121529bd2886SAlan Wright 		(void) strcanon(cmd, " ");
121629bd2886SAlan Wright 
121729bd2886SAlan Wright 		if ((cmd_tokens = smb_shr_tokenize_cmd(cmd)) != NULL) {
121829bd2886SAlan Wright 
121929bd2886SAlan Wright 			if (smb_shr_expand_subs(cmd_tokens, &si, subs) != 0) {
122029bd2886SAlan Wright 				free(cmd_tokens[0]);
122129bd2886SAlan Wright 				free(cmd_tokens);
122229bd2886SAlan Wright 				_exit(-1);
122329bd2886SAlan Wright 			}
122429bd2886SAlan Wright 
122529bd2886SAlan Wright 			ptr = cmd;
122629bd2886SAlan Wright 			path = strsep(&ptr, " ");
122729bd2886SAlan Wright 
122829bd2886SAlan Wright 			(void) execv(path, cmd_tokens);
122929bd2886SAlan Wright 		}
123029bd2886SAlan Wright 
123129bd2886SAlan Wright 		_exit(-1);
123229bd2886SAlan Wright 	}
123329bd2886SAlan Wright 
1234e3f2c991SKeyur Desai 	(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_PROC_FORK, NULL);
1235e3f2c991SKeyur Desai 	smb_proc_givesem();
1236e3f2c991SKeyur Desai 
123729bd2886SAlan Wright 	/* parent process */
123829bd2886SAlan Wright 
123929bd2886SAlan Wright 	while (waitpid(child_pid, &child_status, 0) < 0) {
124029bd2886SAlan Wright 		if (errno != EINTR)
124129bd2886SAlan Wright 			break;
124229bd2886SAlan Wright 
124329bd2886SAlan Wright 		/* continue if waitpid got interrupted by a signal */
124429bd2886SAlan Wright 		errno = 0;
124529bd2886SAlan Wright 		continue;
124629bd2886SAlan Wright 	}
124729bd2886SAlan Wright 
124829bd2886SAlan Wright 	if (WIFEXITED(child_status))
124929bd2886SAlan Wright 		return (WEXITSTATUS(child_status));
125029bd2886SAlan Wright 
125129bd2886SAlan Wright 	return (child_status);
125229bd2886SAlan Wright }
125329bd2886SAlan Wright 
1254e3f2c991SKeyur Desai /*
1255e3f2c991SKeyur Desai  * Locking for process-wide settings (i.e. privileges)
1256e3f2c991SKeyur Desai  */
1257e3f2c991SKeyur Desai void
smb_proc_initsem(void)1258e3f2c991SKeyur Desai smb_proc_initsem(void)
1259e3f2c991SKeyur Desai {
1260e3f2c991SKeyur Desai 	(void) sema_init(&smb_proc_sem, 1, USYNC_THREAD, NULL);
1261e3f2c991SKeyur Desai }
1262e3f2c991SKeyur Desai 
1263e3f2c991SKeyur Desai int
smb_proc_takesem(void)1264e3f2c991SKeyur Desai smb_proc_takesem(void)
1265e3f2c991SKeyur Desai {
1266e3f2c991SKeyur Desai 	return (sema_wait(&smb_proc_sem));
1267e3f2c991SKeyur Desai }
1268e3f2c991SKeyur Desai 
1269e3f2c991SKeyur Desai void
smb_proc_givesem(void)1270e3f2c991SKeyur Desai smb_proc_givesem(void)
1271e3f2c991SKeyur Desai {
1272e3f2c991SKeyur Desai 	(void) sema_post(&smb_proc_sem);
1273e3f2c991SKeyur Desai }
1274e3f2c991SKeyur Desai 
1275c8ec8eeaSjose borrego /*
1276c8ec8eeaSjose borrego  * ============================================
1277b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Private helper/utility functions
1278c8ec8eeaSjose borrego  * ============================================
1279c8ec8eeaSjose borrego  */
1280da6c28aaSamw 
12818d7e4166Sjose borrego /*
12828d7e4166Sjose borrego  * Looks up the given share in the cache and return
12838d7e4166Sjose borrego  * the info in 'si'
12848d7e4166Sjose borrego  */
12858d7e4166Sjose borrego static uint32_t
smb_shr_lookup(char * sharename,smb_share_t * si)12868d7e4166Sjose borrego smb_shr_lookup(char *sharename, smb_share_t *si)
12878d7e4166Sjose borrego {
12888d7e4166Sjose borrego 	smb_share_t *cached_si;
12898d7e4166Sjose borrego 	uint32_t status = NERR_NetNameNotFound;
12908d7e4166Sjose borrego 
12918d7e4166Sjose borrego 	if (sharename == NULL || *sharename == '\0')
12928d7e4166Sjose borrego 		return (NERR_NetNameNotFound);
12938d7e4166Sjose borrego 	if (smb_shr_cache_lock(SMB_SHR_CACHE_RDLOCK) == NERR_Success) {
12948d7e4166Sjose borrego 		cached_si = smb_shr_cache_findent(sharename);
12958d7e4166Sjose borrego 		if (cached_si != NULL) {
12968d7e4166Sjose borrego 			bcopy(cached_si, si, sizeof (smb_share_t));
12978d7e4166Sjose borrego 			status = NERR_Success;
12988d7e4166Sjose borrego 		}
12998d7e4166Sjose borrego 
13008d7e4166Sjose borrego 		smb_shr_cache_unlock();
13018d7e4166Sjose borrego 	}
13028d7e4166Sjose borrego 	return (status);
13038d7e4166Sjose borrego }
13048d7e4166Sjose borrego 
1305c8ec8eeaSjose borrego /*
13069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Add IPC$ or Admin shares to the cache upon startup.
1307c8ec8eeaSjose borrego  */
1308c8ec8eeaSjose borrego static uint32_t
smb_shr_add_transient(char * name,char * cmnt,char * path)13099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_shr_add_transient(char *name, char *cmnt, char *path)
1310c8ec8eeaSjose borrego {
13119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_share_t trans;
1312b89a8333Snatalie li - Sun Microsystems - Irvine United States 	uint32_t status = NERR_InternalError;
1313c8ec8eeaSjose borrego 
13149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (name == NULL)
13159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (status);
13169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
13179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	bzero(&trans, sizeof (smb_share_t));
13189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) strlcpy(trans.shr_name, name, MAXNAMELEN);
13199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (cmnt)
13209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		(void) strlcpy(trans.shr_cmnt, cmnt, SMB_SHARE_CMNT_MAX);
13219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
13229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (path)
13239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		(void) strlcpy(trans.shr_path, path, MAXPATHLEN);
13249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
13259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (strcasecmp(name, "IPC$") == 0)
13269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		trans.shr_type = STYPE_IPC;
13279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
13289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	trans.shr_flags = SMB_SHRF_TRANS;
1329c8ec8eeaSjose borrego 
1330b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (smb_shr_cache_lock(SMB_SHR_CACHE_WRLOCK) == NERR_Success) {
13319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		status = smb_shr_cache_addent(&trans);
1332b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache_unlock();
1333c8ec8eeaSjose borrego 	}
1334c8ec8eeaSjose borrego 
1335b89a8333Snatalie li - Sun Microsystems - Irvine United States 	return (status);
1336c8ec8eeaSjose borrego }
1337c8ec8eeaSjose borrego 
1338b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
1339b89a8333Snatalie li - Sun Microsystems - Irvine United States  * ============================================
1340b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Cache management functions
1341b89a8333Snatalie li - Sun Microsystems - Irvine United States  *
1342b89a8333Snatalie li - Sun Microsystems - Irvine United States  * All cache functions are private
1343b89a8333Snatalie li - Sun Microsystems - Irvine United States  * ============================================
1344b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
1345b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1346b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
1347b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Create the share cache (hash table).
1348b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
1349b89a8333Snatalie li - Sun Microsystems - Irvine United States static uint32_t
smb_shr_cache_create(void)1350b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_cache_create(void)
1351c8ec8eeaSjose borrego {
1352c8ec8eeaSjose borrego 	uint32_t status = NERR_Success;
1353c8ec8eeaSjose borrego 
1354b89a8333Snatalie li - Sun Microsystems - Irvine United States 	(void) mutex_lock(&smb_shr_cache.sc_mtx);
1355b89a8333Snatalie li - Sun Microsystems - Irvine United States 	switch (smb_shr_cache.sc_state) {
1356b89a8333Snatalie li - Sun Microsystems - Irvine United States 	case SMB_SHR_CACHE_STATE_NONE:
1357b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache.sc_cache = ht_create_table(SMB_SHR_HTAB_SZ,
1358b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    MAXNAMELEN, 0);
1359b89a8333Snatalie li - Sun Microsystems - Irvine United States 		if (smb_shr_cache.sc_cache == NULL) {
1360b89a8333Snatalie li - Sun Microsystems - Irvine United States 			status = NERR_InternalError;
1361b89a8333Snatalie li - Sun Microsystems - Irvine United States 			break;
1362b89a8333Snatalie li - Sun Microsystems - Irvine United States 		}
1363c8ec8eeaSjose borrego 
13640237b699SAndrew Stormont 		(void) ht_set_cmpfn(smb_shr_cache.sc_cache,
13650237b699SAndrew Stormont 		    (HT_CMP)smb_strcasecmp);
1366b89a8333Snatalie li - Sun Microsystems - Irvine United States 		(void) ht_register_callback(smb_shr_cache.sc_cache,
1367b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    smb_shr_cache_freent);
1368b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache.sc_nops = 0;
1369b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache.sc_state = SMB_SHR_CACHE_STATE_CREATED;
1370b89a8333Snatalie li - Sun Microsystems - Irvine United States 		break;
1371c8ec8eeaSjose borrego 
1372b89a8333Snatalie li - Sun Microsystems - Irvine United States 	default:
1373b89a8333Snatalie li - Sun Microsystems - Irvine United States 		assert(0);
1374c8ec8eeaSjose borrego 		status = NERR_InternalError;
1375b89a8333Snatalie li - Sun Microsystems - Irvine United States 		break;
1376c8ec8eeaSjose borrego 	}
1377b89a8333Snatalie li - Sun Microsystems - Irvine United States 	(void) mutex_unlock(&smb_shr_cache.sc_mtx);
1378c8ec8eeaSjose borrego 
1379c8ec8eeaSjose borrego 	return (status);
1380c8ec8eeaSjose borrego }
1381c8ec8eeaSjose borrego 
1382b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
1383b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Destroy the share cache (hash table).
1384b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Wait for inflight/pending operations to finish or abort before
1385b89a8333Snatalie li - Sun Microsystems - Irvine United States  * destroying the cache.
1386b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
1387c8ec8eeaSjose borrego static void
smb_shr_cache_destroy(void)1388b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_cache_destroy(void)
1389c8ec8eeaSjose borrego {
1390b89a8333Snatalie li - Sun Microsystems - Irvine United States 	(void) mutex_lock(&smb_shr_cache.sc_mtx);
1391b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (smb_shr_cache.sc_state == SMB_SHR_CACHE_STATE_CREATED) {
1392b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache.sc_state = SMB_SHR_CACHE_STATE_DESTROYING;
1393b89a8333Snatalie li - Sun Microsystems - Irvine United States 		while (smb_shr_cache.sc_nops > 0)
1394b89a8333Snatalie li - Sun Microsystems - Irvine United States 			(void) cond_wait(&smb_shr_cache.sc_cv,
1395b89a8333Snatalie li - Sun Microsystems - Irvine United States 			    &smb_shr_cache.sc_mtx);
1396b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1397b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache.sc_cache = NULL;
1398b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_cache.sc_state = SMB_SHR_CACHE_STATE_NONE;
1399b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
1400b89a8333Snatalie li - Sun Microsystems - Irvine United States 	(void) mutex_unlock(&smb_shr_cache.sc_mtx);
1401c8ec8eeaSjose borrego }
1402c8ec8eeaSjose borrego 
1403b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
1404b89a8333Snatalie li - Sun Microsystems - Irvine United States  * If the cache is in "created" state, lock the cache for read
1405b89a8333Snatalie li - Sun Microsystems - Irvine United States  * or read/write based on the specified mode.
1406b89a8333Snatalie li - Sun Microsystems - Irvine United States  *
1407b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Whenever a lock is granted, the number of inflight cache
1408b89a8333Snatalie li - Sun Microsystems - Irvine United States  * operations is incremented.
1409b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
1410c8ec8eeaSjose borrego static uint32_t
smb_shr_cache_lock(int mode)1411b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_cache_lock(int mode)
1412c8ec8eeaSjose borrego {
1413b89a8333Snatalie li - Sun Microsystems - Irvine United States 	(void) mutex_lock(&smb_shr_cache.sc_mtx);
14148d7e4166Sjose borrego 	if (smb_shr_cache.sc_state != SMB_SHR_CACHE_STATE_CREATED) {
1415b89a8333Snatalie li - Sun Microsystems - Irvine United States 		(void) mutex_unlock(&smb_shr_cache.sc_mtx);
1416b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (NERR_InternalError);
1417c8ec8eeaSjose borrego 	}
14188d7e4166Sjose borrego 	smb_shr_cache.sc_nops++;
1419b89a8333Snatalie li - Sun Microsystems - Irvine United States 	(void) mutex_unlock(&smb_shr_cache.sc_mtx);
1420c8ec8eeaSjose borrego 
1421b89a8333Snatalie li - Sun Microsystems - Irvine United States 	/*
1422b89a8333Snatalie li - Sun Microsystems - Irvine United States 	 * Lock has to be taken outside the mutex otherwise
1423b89a8333Snatalie li - Sun Microsystems - Irvine United States 	 * there could be a deadlock
1424b89a8333Snatalie li - Sun Microsystems - Irvine United States 	 */
1425b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (mode == SMB_SHR_CACHE_RDLOCK)
1426b89a8333Snatalie li - Sun Microsystems - Irvine United States 		(void) rw_rdlock(&smb_shr_cache.sc_cache_lck);
1427b89a8333Snatalie li - Sun Microsystems - Irvine United States 	else
1428b89a8333Snatalie li - Sun Microsystems - Irvine United States 		(void) rw_wrlock(&smb_shr_cache.sc_cache_lck);
1429b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1430b89a8333Snatalie li - Sun Microsystems - Irvine United States 	return (NERR_Success);
1431c8ec8eeaSjose borrego }
1432c8ec8eeaSjose borrego 
1433b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
1434b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Decrement the number of inflight operations and then unlock.
1435b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
1436b89a8333Snatalie li - Sun Microsystems - Irvine United States static void
smb_shr_cache_unlock(void)1437b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_cache_unlock(void)
1438c8ec8eeaSjose borrego {
1439b89a8333Snatalie li - Sun Microsystems - Irvine United States 	(void) mutex_lock(&smb_shr_cache.sc_mtx);
1440b89a8333Snatalie li - Sun Microsystems - Irvine United States 	assert(smb_shr_cache.sc_nops > 0);
1441b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_shr_cache.sc_nops--;
1442b89a8333Snatalie li - Sun Microsystems - Irvine United States 	(void) cond_broadcast(&smb_shr_cache.sc_cv);
1443b89a8333Snatalie li - Sun Microsystems - Irvine United States 	(void) mutex_unlock(&smb_shr_cache.sc_mtx);
1444c8ec8eeaSjose borrego 
1445b89a8333Snatalie li - Sun Microsystems - Irvine United States 	(void) rw_unlock(&smb_shr_cache.sc_cache_lck);
1446b89a8333Snatalie li - Sun Microsystems - Irvine United States }
1447c8ec8eeaSjose borrego 
1448b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
1449b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Return the total number of shares
1450b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
1451b89a8333Snatalie li - Sun Microsystems - Irvine United States static int
smb_shr_cache_count(void)1452b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_cache_count(void)
1453b89a8333Snatalie li - Sun Microsystems - Irvine United States {
1454b89a8333Snatalie li - Sun Microsystems - Irvine United States 	return (ht_get_total_items(smb_shr_cache.sc_cache));
1455b89a8333Snatalie li - Sun Microsystems - Irvine United States }
1456c8ec8eeaSjose borrego 
1457b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
1458b89a8333Snatalie li - Sun Microsystems - Irvine United States  * looks up the given share name in the cache and if it
1459b89a8333Snatalie li - Sun Microsystems - Irvine United States  * finds a match returns a pointer to the cached entry.
1460b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Note that since a pointer is returned this function
1461b89a8333Snatalie li - Sun Microsystems - Irvine United States  * MUST be protected by smb_shr_cache_lock/unlock pair
1462b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
1463b89a8333Snatalie li - Sun Microsystems - Irvine United States static smb_share_t *
smb_shr_cache_findent(char * sharename)1464b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_cache_findent(char *sharename)
1465b89a8333Snatalie li - Sun Microsystems - Irvine United States {
1466b89a8333Snatalie li - Sun Microsystems - Irvine United States 	HT_ITEM *item;
1467c8ec8eeaSjose borrego 
1468b89a8333Snatalie li - Sun Microsystems - Irvine United States 	item = ht_find_item(smb_shr_cache.sc_cache, sharename);
1469b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (item && item->hi_data)
1470b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return ((smb_share_t *)item->hi_data);
1471c8ec8eeaSjose borrego 
1472b89a8333Snatalie li - Sun Microsystems - Irvine United States 	return (NULL);
1473c8ec8eeaSjose borrego }
1474c8ec8eeaSjose borrego 
1475b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
1476b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Return a pointer to the first/next entry in
1477b89a8333Snatalie li - Sun Microsystems - Irvine United States  * the cache based on the given iterator.
1478b89a8333Snatalie li - Sun Microsystems - Irvine United States  *
1479b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Calls to this function MUST be protected by
1480b89a8333Snatalie li - Sun Microsystems - Irvine United States  * smb_shr_cache_lock/unlock.
1481b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
1482b89a8333Snatalie li - Sun Microsystems - Irvine United States static smb_share_t *
smb_shr_cache_iterate(smb_shriter_t * shi)1483b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_cache_iterate(smb_shriter_t *shi)
1484c8ec8eeaSjose borrego {
1485b89a8333Snatalie li - Sun Microsystems - Irvine United States 	HT_ITEM *item;
1486c8ec8eeaSjose borrego 
1487b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (shi->si_first) {
1488b89a8333Snatalie li - Sun Microsystems - Irvine United States 		item = ht_findfirst(smb_shr_cache.sc_cache, &shi->si_hashiter);
1489b89a8333Snatalie li - Sun Microsystems - Irvine United States 		shi->si_first = B_FALSE;
1490b89a8333Snatalie li - Sun Microsystems - Irvine United States 	} else {
1491b89a8333Snatalie li - Sun Microsystems - Irvine United States 		item = ht_findnext(&shi->si_hashiter);
1492b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
1493b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1494b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (item && item->hi_data)
1495b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return ((smb_share_t *)item->hi_data);
1496b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1497b89a8333Snatalie li - Sun Microsystems - Irvine United States 	return (NULL);
1498c8ec8eeaSjose borrego }
1499c8ec8eeaSjose borrego 
1500c8ec8eeaSjose borrego /*
1501b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Add the specified share to the cache.  Memory needs to be allocated
1502b89a8333Snatalie li - Sun Microsystems - Irvine United States  * for the cache entry and the passed information is copied to the
1503b89a8333Snatalie li - Sun Microsystems - Irvine United States  * allocated space.
1504*c7abf329SGordon Ross  *
1505*c7abf329SGordon Ross  * Note: This modifies *si (an intentional side-effect), adding bits
1506*c7abf329SGordon Ross  * to shr_type and shr_flags, which the caller expects, eg. so that
1507*c7abf329SGordon Ross  * smb_shr_add() and smb_shr_rename() use the updated smb_share_t
1508*c7abf329SGordon Ross  * when they call smb_kmod_share().
1509c8ec8eeaSjose borrego  */
1510c8ec8eeaSjose borrego static uint32_t
smb_shr_cache_addent(smb_share_t * si)1511b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_cache_addent(smb_share_t *si)
1512c8ec8eeaSjose borrego {
1513b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_share_t *cache_ent;
1514b89a8333Snatalie li - Sun Microsystems - Irvine United States 	uint32_t status = NERR_Success;
1515c8ec8eeaSjose borrego 
1516b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if ((cache_ent = malloc(sizeof (smb_share_t))) == NULL)
1517b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (ERROR_NOT_ENOUGH_MEMORY);
1518c8ec8eeaSjose borrego 
1519*c7abf329SGordon Ross 	si->shr_type |= smb_shr_is_special(si->shr_name);
1520b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1521*c7abf329SGordon Ross 	if (smb_shr_is_admin(si->shr_name))
1522148c5f43SAlan Wright 		si->shr_flags |= SMB_SHRF_ADMIN;
1523148c5f43SAlan Wright 
1524148c5f43SAlan Wright 	bcopy(si, cache_ent, sizeof (smb_share_t));
1525b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1526b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (si->shr_flags & SMB_SHRF_AUTOHOME)
1527b89a8333Snatalie li - Sun Microsystems - Irvine United States 		cache_ent->shr_refcnt = 1;
1528b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1529b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (ht_add_item(smb_shr_cache.sc_cache, cache_ent->shr_name, cache_ent)
1530b89a8333Snatalie li - Sun Microsystems - Irvine United States 	    == NULL) {
1531b89a8333Snatalie li - Sun Microsystems - Irvine United States 		syslog(LOG_DEBUG, "share: %s: cache update failed",
1532b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    cache_ent->shr_name);
1533b89a8333Snatalie li - Sun Microsystems - Irvine United States 		free(cache_ent);
1534b89a8333Snatalie li - Sun Microsystems - Irvine United States 		status = NERR_InternalError;
1535c8ec8eeaSjose borrego 	}
1536c8ec8eeaSjose borrego 
1537c8ec8eeaSjose borrego 	return (status);
1538c8ec8eeaSjose borrego }
1539c8ec8eeaSjose borrego 
1540c8ec8eeaSjose borrego /*
1541b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Delete the specified share from the cache.
1542c8ec8eeaSjose borrego  */
1543c8ec8eeaSjose borrego static void
smb_shr_cache_delent(char * sharename)1544b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_cache_delent(char *sharename)
1545c8ec8eeaSjose borrego {
1546b89a8333Snatalie li - Sun Microsystems - Irvine United States 	(void) ht_remove_item(smb_shr_cache.sc_cache, sharename);
1547c8ec8eeaSjose borrego }
1548c8ec8eeaSjose borrego 
1549c8ec8eeaSjose borrego /*
1550b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Call back to free the given cache entry.
1551c8ec8eeaSjose borrego  */
1552c8ec8eeaSjose borrego static void
smb_shr_cache_freent(HT_ITEM * item)1553c8ec8eeaSjose borrego smb_shr_cache_freent(HT_ITEM *item)
1554c8ec8eeaSjose borrego {
1555c8ec8eeaSjose borrego 	if (item && item->hi_data)
1556c8ec8eeaSjose borrego 		free(item->hi_data);
1557c8ec8eeaSjose borrego }
1558c8ec8eeaSjose borrego 
1559c8ec8eeaSjose borrego /*
1560b89a8333Snatalie li - Sun Microsystems - Irvine United States  * ============================================
1561b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Interfaces to sharemgr
1562c8ec8eeaSjose borrego  *
1563b89a8333Snatalie li - Sun Microsystems - Irvine United States  * All functions in this section are private
1564b89a8333Snatalie li - Sun Microsystems - Irvine United States  * ============================================
1565c8ec8eeaSjose borrego  */
1566da6c28aaSamw 
1567da6c28aaSamw /*
1568c7bda764SEvan Layton  * Loads the SMB shares, from sharemgr, then:
1569c7bda764SEvan Layton  *     - calls smb_shr_add which:
1570c7bda764SEvan Layton  *         - adds the share into the share cache
1571c7bda764SEvan Layton  *         - adds the share into in-kernel kshare table
1572c7bda764SEvan Layton  *         - publishes the share in ADS
1573c7bda764SEvan Layton  *     - updates the share list in sharefs/sharetab
1574da6c28aaSamw  */
1575b89a8333Snatalie li - Sun Microsystems - Irvine United States /*ARGSUSED*/
1576fd9ee8b5Sjoyce mcintosh void *
smb_shr_load(void * args)1577fd9ee8b5Sjoyce mcintosh smb_shr_load(void *args)
1578da6c28aaSamw {
1579b89a8333Snatalie li - Sun Microsystems - Irvine United States 	sa_handle_t handle;
1580b89a8333Snatalie li - Sun Microsystems - Irvine United States 	sa_group_t group, subgroup;
1581b89a8333Snatalie li - Sun Microsystems - Irvine United States 	char *gstate;
1582b89a8333Snatalie li - Sun Microsystems - Irvine United States 	boolean_t gdisabled;
1583fd9ee8b5Sjoyce mcintosh 
1584c720f3a7SJoyce McIntosh 	smb_shr_load_execinfo();
1585da6c28aaSamw 
1586cb174861Sjoyce mcintosh 	if ((handle = smb_shr_sa_enter()) == NULL) {
1587fd9ee8b5Sjoyce mcintosh 		syslog(LOG_ERR, "smb_shr_load: load failed");
1588b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (NULL);
1589cb174861Sjoyce mcintosh 	}
1590da6c28aaSamw 
1591b89a8333Snatalie li - Sun Microsystems - Irvine United States 	for (group = sa_get_group(handle, NULL);
1592b89a8333Snatalie li - Sun Microsystems - Irvine United States 	    group != NULL; group = sa_get_next_group(group)) {
1593b89a8333Snatalie li - Sun Microsystems - Irvine United States 		gstate = sa_get_group_attr(group, "state");
1594b89a8333Snatalie li - Sun Microsystems - Irvine United States 		if (gstate == NULL)
1595b89a8333Snatalie li - Sun Microsystems - Irvine United States 			continue;
1596da6c28aaSamw 
1597b89a8333Snatalie li - Sun Microsystems - Irvine United States 		gdisabled = (strcasecmp(gstate, "disabled") == 0);
1598b89a8333Snatalie li - Sun Microsystems - Irvine United States 		sa_free_attr_string(gstate);
1599b89a8333Snatalie li - Sun Microsystems - Irvine United States 		if (gdisabled)
1600b89a8333Snatalie li - Sun Microsystems - Irvine United States 			continue;
1601c8ec8eeaSjose borrego 
1602b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_shr_sa_loadgrp(group);
1603b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1604b89a8333Snatalie li - Sun Microsystems - Irvine United States 		for (subgroup = sa_get_sub_group(group);
1605b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    subgroup != NULL;
1606b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    subgroup = sa_get_next_group(subgroup)) {
1607b89a8333Snatalie li - Sun Microsystems - Irvine United States 			smb_shr_sa_loadgrp(subgroup);
1608b89a8333Snatalie li - Sun Microsystems - Irvine United States 		}
1609da6c28aaSamw 
1610da6c28aaSamw 	}
161189dc44ceSjose borrego 	smb_shr_sa_exit();
1612b89a8333Snatalie li - Sun Microsystems - Irvine United States 	return (NULL);
1613da6c28aaSamw }
1614da6c28aaSamw 
1615c720f3a7SJoyce McIntosh void
smb_shr_load_execinfo()1616c720f3a7SJoyce McIntosh smb_shr_load_execinfo()
1617c720f3a7SJoyce McIntosh {
1618c720f3a7SJoyce McIntosh 	(void) mutex_lock(&smb_shr_exec_mtx);
1619c720f3a7SJoyce McIntosh 	(void) smb_config_get_execinfo(smb_shr_exec_map, smb_shr_exec_unmap,
1620c720f3a7SJoyce McIntosh 	    MAXPATHLEN);
1621c720f3a7SJoyce McIntosh 	(void) mutex_unlock(&smb_shr_exec_mtx);
1622c720f3a7SJoyce McIntosh }
1623c720f3a7SJoyce McIntosh 
1624c7bda764SEvan Layton /*
1625c7bda764SEvan Layton  * Handles disabling shares in sharefs when stoping smbd
1626c7bda764SEvan Layton  */
1627c7bda764SEvan Layton void
smb_shr_unload()1628c7bda764SEvan Layton smb_shr_unload()
1629c7bda764SEvan Layton {
1630c7bda764SEvan Layton 	smb_shriter_t iterator;
1631c7bda764SEvan Layton 	smb_share_t *si;
1632c7bda764SEvan Layton 	sa_handle_t handle;
1633c7bda764SEvan Layton 	int rc;
1634c7bda764SEvan Layton 
1635c7bda764SEvan Layton 	if ((handle = smb_shr_sa_enter()) == NULL) {
1636c7bda764SEvan Layton 		syslog(LOG_ERR, "smb_shr_unload: failed");
1637c7bda764SEvan Layton 		return;
1638c7bda764SEvan Layton 	}
1639c7bda764SEvan Layton 
1640c7bda764SEvan Layton 	smb_shr_iterinit(&iterator);
1641c7bda764SEvan Layton 
1642c7bda764SEvan Layton 	while ((si = smb_shr_iterate(&iterator)) != NULL) {
1643c7bda764SEvan Layton 
1644c7bda764SEvan Layton 		/* Skip transient shares, IPC$, ... */
1645c7bda764SEvan Layton 		if ((si->shr_flags & SMB_SHRF_TRANS) ||
1646c7bda764SEvan Layton 		    STYPE_ISIPC(si->shr_type))
1647c7bda764SEvan Layton 			continue;
1648c7bda764SEvan Layton 
1649c7bda764SEvan Layton 		rc = sa_delete_sharetab(handle, si->shr_path, "smb");
1650c7bda764SEvan Layton 		if (rc) {
1651c7bda764SEvan Layton 			syslog(LOG_ERR,
1652c7bda764SEvan Layton 			    "sharefs remove %s failed, rc=%d, err=%d",
1653c7bda764SEvan Layton 			    si->shr_path, rc, errno);
1654c7bda764SEvan Layton 		}
1655c7bda764SEvan Layton 	}
1656c7bda764SEvan Layton 	smb_shr_sa_exit();
1657c7bda764SEvan Layton }
1658c7bda764SEvan Layton 
1659da6c28aaSamw /*
1660b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Load the shares contained in the specified group.
1661b89a8333Snatalie li - Sun Microsystems - Irvine United States  *
1662b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Don't process groups on which the smb protocol is disabled.
1663b89a8333Snatalie li - Sun Microsystems - Irvine United States  * The top level ZFS group won't have the smb protocol enabled
1664b89a8333Snatalie li - Sun Microsystems - Irvine United States  * but sub-groups will.
1665b89a8333Snatalie li - Sun Microsystems - Irvine United States  *
1666b89a8333Snatalie li - Sun Microsystems - Irvine United States  * We will tolerate a limited number of errors and then give
1667b89a8333Snatalie li - Sun Microsystems - Irvine United States  * up on the current group.  A typical error might be that the
1668b89a8333Snatalie li - Sun Microsystems - Irvine United States  * shared directory no longer exists.
1669c8ec8eeaSjose borrego  */
1670b89a8333Snatalie li - Sun Microsystems - Irvine United States static void
smb_shr_sa_loadgrp(sa_group_t group)1671b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_sa_loadgrp(sa_group_t group)
1672da6c28aaSamw {
1673da6c28aaSamw 	sa_share_t share;
1674da6c28aaSamw 	sa_resource_t resource;
1675b89a8333Snatalie li - Sun Microsystems - Irvine United States 	int error_count = 0;
1676da6c28aaSamw 
1677b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (sa_get_optionset(group, SMB_PROTOCOL_NAME) == NULL)
1678b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return;
1679c8ec8eeaSjose borrego 
1680b89a8333Snatalie li - Sun Microsystems - Irvine United States 	for (share = sa_get_share(group, NULL);
1681b89a8333Snatalie li - Sun Microsystems - Irvine United States 	    share != NULL;
1682b89a8333Snatalie li - Sun Microsystems - Irvine United States 	    share = sa_get_next_share(share)) {
1683b89a8333Snatalie li - Sun Microsystems - Irvine United States 		for (resource = sa_get_share_resource(share, NULL);
1684b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    resource != NULL;
1685b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    resource = sa_get_next_resource(resource)) {
1686b89a8333Snatalie li - Sun Microsystems - Irvine United States 			if (smb_shr_sa_load(share, resource))
1687b89a8333Snatalie li - Sun Microsystems - Irvine United States 				++error_count;
1688c8ec8eeaSjose borrego 
1689b89a8333Snatalie li - Sun Microsystems - Irvine United States 			if (error_count > SMB_SHR_ERROR_THRESHOLD)
1690b89a8333Snatalie li - Sun Microsystems - Irvine United States 				break;
1691da6c28aaSamw 		}
1692c8ec8eeaSjose borrego 
1693b89a8333Snatalie li - Sun Microsystems - Irvine United States 		if (error_count > SMB_SHR_ERROR_THRESHOLD)
1694b89a8333Snatalie li - Sun Microsystems - Irvine United States 			break;
1695da6c28aaSamw 	}
1696b89a8333Snatalie li - Sun Microsystems - Irvine United States }
1697c8ec8eeaSjose borrego 
1698b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
1699b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Load a share definition from sharemgr and add it to the cache.
17008d7e4166Sjose borrego  * If the share is already in the cache then it doesn't do anything.
17018d7e4166Sjose borrego  *
17028d7e4166Sjose borrego  * This function does not report duplicate shares as error since
17038d7e4166Sjose borrego  * a share might have been added by smb_shr_get() while load is
17048d7e4166Sjose borrego  * in progress.
1705b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
1706b89a8333Snatalie li - Sun Microsystems - Irvine United States static uint32_t
smb_shr_sa_load(sa_share_t share,sa_resource_t resource)1707b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_sa_load(sa_share_t share, sa_resource_t resource)
1708b89a8333Snatalie li - Sun Microsystems - Irvine United States {
1709b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_share_t si;
17108d7e4166Sjose borrego 	char *sharename;
1711b89a8333Snatalie li - Sun Microsystems - Irvine United States 	uint32_t status;
17128d7e4166Sjose borrego 	boolean_t loaded;
1713c7bda764SEvan Layton 	int rc;
17148d7e4166Sjose borrego 
17158d7e4166Sjose borrego 	if ((sharename = sa_get_resource_attr(resource, "name")) == NULL)
17168d7e4166Sjose borrego 		return (NERR_InternalError);
17178d7e4166Sjose borrego 
17188d7e4166Sjose borrego 	loaded = smb_shr_exists(sharename);
17198d7e4166Sjose borrego 	sa_free_attr_string(sharename);
17208d7e4166Sjose borrego 
17218d7e4166Sjose borrego 	if (loaded)
17228d7e4166Sjose borrego 		return (NERR_Success);
1723b89a8333Snatalie li - Sun Microsystems - Irvine United States 
1724b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if ((status = smb_shr_sa_get(share, resource, &si)) != NERR_Success) {
1725b89a8333Snatalie li - Sun Microsystems - Irvine United States 		syslog(LOG_DEBUG, "share: failed to load %s (%d)",
1726b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    si.shr_name, status);
1727b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (status);
1728da6c28aaSamw 	}
1729c8ec8eeaSjose borrego 
17308d7e4166Sjose borrego 	status = smb_shr_add(&si);
17318d7e4166Sjose borrego 	if ((status != NERR_Success) && (status != NERR_DuplicateShare)) {
1732b89a8333Snatalie li - Sun Microsystems - Irvine United States 		syslog(LOG_DEBUG, "share: failed to cache %s (%d)",
1733b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    si.shr_name, status);
1734b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (status);
1735da6c28aaSamw 	}
1736da6c28aaSamw 
1737c7bda764SEvan Layton 	rc = sa_update_sharetab(share, "smb");
1738c7bda764SEvan Layton 	if (rc) {
1739c7bda764SEvan Layton 		syslog(LOG_ERR, "sharefs add %s failed, rc=%d, err=%d",
1740c7bda764SEvan Layton 		    sharename, rc, errno);
1741c7bda764SEvan Layton 	}
1742c7bda764SEvan Layton 
1743c8ec8eeaSjose borrego 	return (NERR_Success);
1744da6c28aaSamw }
1745da6c28aaSamw 
17469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static char *
smb_shr_sa_getprop(sa_optionset_t opts,char * propname)17479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_shr_sa_getprop(sa_optionset_t opts, char *propname)
17489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
17499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	sa_property_t prop;
17509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	char *val = NULL;
17519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
17529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	prop = sa_get_property(opts, propname);
17539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (prop != NULL)
17549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		val = sa_get_property_attr(prop, "value");
17559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
17569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (val);
17579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
17589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1759b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
1760b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Read the specified share information from sharemgr and return
1761b89a8333Snatalie li - Sun Microsystems - Irvine United States  * it in the given smb_share_t structure.
1762b89a8333Snatalie li - Sun Microsystems - Irvine United States  *
1763b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Shares read from sharemgr are marked as permanent/persistent.
1764b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
17653db3f65cSamw static uint32_t
smb_shr_sa_get(sa_share_t share,sa_resource_t resource,smb_share_t * si)1766b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_sa_get(sa_share_t share, sa_resource_t resource, smb_share_t *si)
1767da6c28aaSamw {
1768c8ec8eeaSjose borrego 	sa_optionset_t opts;
1769c8ec8eeaSjose borrego 	char *val = NULL;
1770c8ec8eeaSjose borrego 	char *path;
1771c8ec8eeaSjose borrego 	char *rname;
1772da6c28aaSamw 
1773c8ec8eeaSjose borrego 	if ((path = sa_get_share_attr(share, "path")) == NULL)
1774c8ec8eeaSjose borrego 		return (NERR_InternalError);
1775da6c28aaSamw 
1776c8ec8eeaSjose borrego 	if ((rname = sa_get_resource_attr(resource, "name")) == NULL) {
1777c8ec8eeaSjose borrego 		sa_free_attr_string(path);
1778c8ec8eeaSjose borrego 		return (NERR_InternalError);
1779da6c28aaSamw 	}
1780da6c28aaSamw 
1781c8ec8eeaSjose borrego 	bzero(si, sizeof (smb_share_t));
1782c8ec8eeaSjose borrego 	si->shr_flags = SMB_SHRF_PERM;
1783da6c28aaSamw 
1784c8ec8eeaSjose borrego 	(void) strlcpy(si->shr_path, path, sizeof (si->shr_path));
1785c8ec8eeaSjose borrego 	(void) strlcpy(si->shr_name, rname, sizeof (si->shr_name));
1786c8ec8eeaSjose borrego 	sa_free_attr_string(path);
1787c8ec8eeaSjose borrego 	sa_free_attr_string(rname);
1788da6c28aaSamw 
1789c8ec8eeaSjose borrego 	val = sa_get_resource_description(resource);
1790c8ec8eeaSjose borrego 	if (val == NULL)
1791c8ec8eeaSjose borrego 		val = sa_get_share_description(share);
1792da6c28aaSamw 
1793c8ec8eeaSjose borrego 	if (val != NULL) {
1794c8ec8eeaSjose borrego 		(void) strlcpy(si->shr_cmnt, val, sizeof (si->shr_cmnt));
1795c8ec8eeaSjose borrego 		sa_free_share_description(val);
1796da6c28aaSamw 	}
1797da6c28aaSamw 
1798c8ec8eeaSjose borrego 	opts = sa_get_derived_optionset(resource, SMB_PROTOCOL_NAME, 1);
1799c8ec8eeaSjose borrego 	if (opts == NULL)
1800c8ec8eeaSjose borrego 		return (NERR_Success);
1801da6c28aaSamw 
18029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	val = smb_shr_sa_getprop(opts, SHOPT_AD_CONTAINER);
18039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (val != NULL) {
18049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		(void) strlcpy(si->shr_container, val,
18059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    sizeof (si->shr_container));
18069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		free(val);
1807da6c28aaSamw 	}
1808da6c28aaSamw 
18099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	val = smb_shr_sa_getprop(opts, SHOPT_CATIA);
18109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (val != NULL) {
18119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_shr_sa_setflag(val, si, SMB_SHRF_CATIA);
18129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		free(val);
18138b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	}
18148b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 
18159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	val = smb_shr_sa_getprop(opts, SHOPT_ABE);
18169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (val != NULL) {
18179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_shr_sa_setflag(val, si, SMB_SHRF_ABE);
18189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		free(val);
1819e3f2c991SKeyur Desai 	}
1820e3f2c991SKeyur Desai 
18219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	val = smb_shr_sa_getprop(opts, SHOPT_GUEST);
18229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (val != NULL) {
18239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_shr_sa_setflag(val, si, SMB_SHRF_GUEST_OK);
18249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		free(val);
18258d7e4166Sjose borrego 	}
18268d7e4166Sjose borrego 
18279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	val = smb_shr_sa_getprop(opts, SHOPT_DFSROOT);
18289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (val != NULL) {
18299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_shr_sa_setflag(val, si, SMB_SHRF_DFSROOT);
18309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		free(val);
183129bd2886SAlan Wright 	}
183229bd2886SAlan Wright 
18338d94f651SGordon Ross 	val = smb_shr_sa_getprop(opts, SHOPT_CA);
18348d94f651SGordon Ross 	if (val != NULL) {
18358d94f651SGordon Ross 		smb_shr_sa_setflag(val, si, SMB_SHRF_CA);
18368d94f651SGordon Ross 		free(val);
18378d94f651SGordon Ross 	}
18388d94f651SGordon Ross 
183994047d49SGordon Ross 	val = smb_shr_sa_getprop(opts, SHOPT_FSO);
184094047d49SGordon Ross 	if (val != NULL) {
184194047d49SGordon Ross 		smb_shr_sa_setflag(val, si, SMB_SHRF_FSO);
184294047d49SGordon Ross 		free(val);
184394047d49SGordon Ross 	}
184494047d49SGordon Ross 
1845ca5fb90aSGordon Ross 	val = smb_shr_sa_getprop(opts, SHOPT_QUOTAS);
1846ca5fb90aSGordon Ross 	if (val != NULL) {
1847ca5fb90aSGordon Ross 		/* Turn the flag on or off */
1848ca5fb90aSGordon Ross 		smb_shr_sa_setflag(val, si, SMB_SHRF_QUOTAS);
1849ca5fb90aSGordon Ross 		free(val);
1850ca5fb90aSGordon Ross 	} else {
1851ca5fb90aSGordon Ross 		/* Default for this is enabled. */
1852ca5fb90aSGordon Ross 		si->shr_flags |= SMB_SHRF_QUOTAS;
1853ca5fb90aSGordon Ross 	}
1854ca5fb90aSGordon Ross 
18551160dcf7SMatt Barden 	val = smb_shr_sa_getprop(opts, SHOPT_ENCRYPT);
18561160dcf7SMatt Barden 	if (val != NULL) {
18571160dcf7SMatt Barden 		smb_cfg_set_require(val, &si->shr_encrypt);
18581160dcf7SMatt Barden 		free(val);
18591160dcf7SMatt Barden 	}
18601160dcf7SMatt Barden 
18619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	val = smb_shr_sa_getprop(opts, SHOPT_CSC);
18629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (val != NULL) {
18639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_shr_sa_csc_option(val, si);
18649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		free(val);
1865c8ec8eeaSjose borrego 	}
1866da6c28aaSamw 
18679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	val = smb_shr_sa_getprop(opts, SHOPT_NONE);
18689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (val != NULL) {
18699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		(void) strlcpy(si->shr_access_none, val,
18709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    sizeof (si->shr_access_none));
18719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		free(val);
18729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		si->shr_flags |= SMB_SHRF_ACC_NONE;
1873da6c28aaSamw 	}
1874da6c28aaSamw 
18759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	val = smb_shr_sa_getprop(opts, SHOPT_RO);
18769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (val != NULL) {
18779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		(void) strlcpy(si->shr_access_ro, val,
18789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    sizeof (si->shr_access_ro));
18799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		free(val);
18809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		si->shr_flags |= SMB_SHRF_ACC_RO;
18819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
18829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
18839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	val = smb_shr_sa_getprop(opts, SHOPT_RW);
18849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (val != NULL) {
18859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		(void) strlcpy(si->shr_access_rw, val,
18869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    sizeof (si->shr_access_rw));
18879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		free(val);
18889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		si->shr_flags |= SMB_SHRF_ACC_RW;
1889da6c28aaSamw 	}
1890da6c28aaSamw 
1891b89a8333Snatalie li - Sun Microsystems - Irvine United States 	sa_free_derived_optionset(opts);
1892c8ec8eeaSjose borrego 	return (NERR_Success);
1893da6c28aaSamw }
1894da6c28aaSamw 
18958d7e4166Sjose borrego /*
18968d7e4166Sjose borrego  * Map a client-side caching (CSC) option to the appropriate share
18978d7e4166Sjose borrego  * flag.  Only one option is allowed; an error will be logged if
18988d7e4166Sjose borrego  * multiple options have been specified.  We don't need to do anything
18998d7e4166Sjose borrego  * about multiple values here because the SRVSVC will not recognize
19008d7e4166Sjose borrego  * a value containing multiple flags and will return the default value.
19018d7e4166Sjose borrego  *
19028d7e4166Sjose borrego  * If the option value is not recognized, it will be ignored: invalid
19038d7e4166Sjose borrego  * values will typically be caught and rejected by sharemgr.
19048d7e4166Sjose borrego  */
190589dc44ceSjose borrego void
smb_shr_sa_csc_option(const char * value,smb_share_t * si)19068d7e4166Sjose borrego smb_shr_sa_csc_option(const char *value, smb_share_t *si)
19078d7e4166Sjose borrego {
19088d7e4166Sjose borrego 	int i;
19098d7e4166Sjose borrego 
19108d7e4166Sjose borrego 	for (i = 0; i < (sizeof (cscopt) / sizeof (cscopt[0])); ++i) {
19118d7e4166Sjose borrego 		if (strcasecmp(value, cscopt[i].value) == 0) {
19128d7e4166Sjose borrego 			si->shr_flags |= cscopt[i].flag;
19138d7e4166Sjose borrego 			break;
19148d7e4166Sjose borrego 		}
19158d7e4166Sjose borrego 	}
19168d7e4166Sjose borrego 
19178d7e4166Sjose borrego 	switch (si->shr_flags & SMB_SHRF_CSC_MASK) {
19188d7e4166Sjose borrego 	case 0:
19198d7e4166Sjose borrego 	case SMB_SHRF_CSC_DISABLED:
19208d7e4166Sjose borrego 	case SMB_SHRF_CSC_MANUAL:
19218d7e4166Sjose borrego 	case SMB_SHRF_CSC_AUTO:
19228d7e4166Sjose borrego 	case SMB_SHRF_CSC_VDO:
19238d7e4166Sjose borrego 		break;
19248d7e4166Sjose borrego 
19258d7e4166Sjose borrego 	default:
192689dc44ceSjose borrego 		syslog(LOG_INFO, "csc option conflict: 0x%08x",
192789dc44ceSjose borrego 		    si->shr_flags & SMB_SHRF_CSC_MASK);
19288d7e4166Sjose borrego 		break;
19298d7e4166Sjose borrego 	}
19308d7e4166Sjose borrego }
19318d7e4166Sjose borrego 
193229bd2886SAlan Wright /*
193329bd2886SAlan Wright  * Return the option name for the first CSC flag (there should be only
193429bd2886SAlan Wright  * one) encountered in the share flags.
193529bd2886SAlan Wright  */
193629bd2886SAlan Wright char *
smb_shr_sa_csc_name(const smb_share_t * si)193729bd2886SAlan Wright smb_shr_sa_csc_name(const smb_share_t *si)
193829bd2886SAlan Wright {
193929bd2886SAlan Wright 	int i;
194029bd2886SAlan Wright 
194129bd2886SAlan Wright 	for (i = 0; i < (sizeof (cscopt) / sizeof (cscopt[0])); ++i) {
194229bd2886SAlan Wright 		if (si->shr_flags & cscopt[i].flag)
194329bd2886SAlan Wright 			return (cscopt[i].value);
194429bd2886SAlan Wright 	}
194529bd2886SAlan Wright 
194629bd2886SAlan Wright 	return (NULL);
194729bd2886SAlan Wright }
194829bd2886SAlan Wright 
19498b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States /*
19509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Takes the value of a boolean share property and set/clear the
19519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * specified flag based on the property's value.
19528b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States  */
19538b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States void
smb_shr_sa_setflag(const char * value,smb_share_t * si,uint32_t flag)19549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_shr_sa_setflag(const char *value, smb_share_t *si, uint32_t flag)
19558b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States {
19569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((strcasecmp(value, "true") == 0) || (strcmp(value, "1") == 0))
19579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		si->shr_flags |= flag;
19589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	else
19599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		si->shr_flags &= ~flag;
196029bd2886SAlan Wright }
196129bd2886SAlan Wright 
19628d7e4166Sjose borrego /*
19638d7e4166Sjose borrego  * looks up sharemgr for the given share (resource) and loads
19648d7e4166Sjose borrego  * the definition into cache if lookup is successful
19658d7e4166Sjose borrego  */
19668d7e4166Sjose borrego static uint32_t
smb_shr_sa_loadbyname(char * sharename)19678d7e4166Sjose borrego smb_shr_sa_loadbyname(char *sharename)
19688d7e4166Sjose borrego {
19698d7e4166Sjose borrego 	sa_handle_t handle;
19708d7e4166Sjose borrego 	sa_share_t share;
19718d7e4166Sjose borrego 	sa_resource_t resource;
19728d7e4166Sjose borrego 	uint32_t status;
19738d7e4166Sjose borrego 
197489dc44ceSjose borrego 	if ((handle = smb_shr_sa_enter()) == NULL)
19758d7e4166Sjose borrego 		return (NERR_InternalError);
19768d7e4166Sjose borrego 
19778d7e4166Sjose borrego 	resource = sa_find_resource(handle, sharename);
19788d7e4166Sjose borrego 	if (resource == NULL) {
197989dc44ceSjose borrego 		smb_shr_sa_exit();
19808d7e4166Sjose borrego 		return (NERR_NetNameNotFound);
19818d7e4166Sjose borrego 	}
19828d7e4166Sjose borrego 
19838d7e4166Sjose borrego 	share = sa_get_resource_parent(resource);
19848d7e4166Sjose borrego 	if (share == NULL) {
198589dc44ceSjose borrego 		smb_shr_sa_exit();
19868d7e4166Sjose borrego 		return (NERR_InternalError);
19878d7e4166Sjose borrego 	}
19888d7e4166Sjose borrego 
19898d7e4166Sjose borrego 	status = smb_shr_sa_load(share, resource);
19908d7e4166Sjose borrego 
199189dc44ceSjose borrego 	smb_shr_sa_exit();
19928d7e4166Sjose borrego 	return (status);
19938d7e4166Sjose borrego }
19948d7e4166Sjose borrego 
1995c8ec8eeaSjose borrego /*
1996b89a8333Snatalie li - Sun Microsystems - Irvine United States  * ============================================
1997b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Share publishing functions
1998c8ec8eeaSjose borrego  *
1999b89a8333Snatalie li - Sun Microsystems - Irvine United States  * All the functions are private
2000b89a8333Snatalie li - Sun Microsystems - Irvine United States  * ============================================
2001c8ec8eeaSjose borrego  */
2002da6c28aaSamw 
2003b89a8333Snatalie li - Sun Microsystems - Irvine United States static void
smb_shr_publish(const char * sharename,const char * container)2004b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_publish(const char *sharename, const char *container)
2005b89a8333Snatalie li - Sun Microsystems - Irvine United States {
2006b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_shr_publisher_queue(sharename, container, SMB_SHR_PUBLISH);
2007da6c28aaSamw }
2008da6c28aaSamw 
2009b89a8333Snatalie li - Sun Microsystems - Irvine United States static void
smb_shr_unpublish(const char * sharename,const char * container)2010b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_unpublish(const char *sharename, const char *container)
2011b89a8333Snatalie li - Sun Microsystems - Irvine United States {
2012b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_shr_publisher_queue(sharename, container, SMB_SHR_UNPUBLISH);
2013b89a8333Snatalie li - Sun Microsystems - Irvine United States }
2014c8ec8eeaSjose borrego 
2015da6c28aaSamw /*
2016b89a8333Snatalie li - Sun Microsystems - Irvine United States  * In domain mode, put a share on the publisher queue.
2017b89a8333Snatalie li - Sun Microsystems - Irvine United States  * This is a no-op if the smb service is in Workgroup mode.
2018da6c28aaSamw  */
20193db3f65cSamw static void
smb_shr_publisher_queue(const char * sharename,const char * container,char op)2020b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_publisher_queue(const char *sharename, const char *container, char op)
2021da6c28aaSamw {
2022c8ec8eeaSjose borrego 	smb_shr_pitem_t *item = NULL;
2023da6c28aaSamw 
2024c8ec8eeaSjose borrego 	if (container == NULL || *container == '\0')
2025da6c28aaSamw 		return;
20263ad684d6Sjb 
2027b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (smb_config_get_secmode() != SMB_SECMODE_DOMAIN)
2028b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return;
2029b89a8333Snatalie li - Sun Microsystems - Irvine United States 
2030c8ec8eeaSjose borrego 	(void) mutex_lock(&ad_queue.spq_mtx);
2031c8ec8eeaSjose borrego 	switch (ad_queue.spq_state) {
2032c8ec8eeaSjose borrego 	case SMB_SHR_PQS_READY:
2033c8ec8eeaSjose borrego 	case SMB_SHR_PQS_PUBLISHING:
2034c8ec8eeaSjose borrego 		break;
2035c8ec8eeaSjose borrego 	default:
2036c8ec8eeaSjose borrego 		(void) mutex_unlock(&ad_queue.spq_mtx);
2037da6c28aaSamw 		return;
2038c8ec8eeaSjose borrego 	}
2039c8ec8eeaSjose borrego 	(void) mutex_unlock(&ad_queue.spq_mtx);
20403ad684d6Sjb 
2041b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if ((item = malloc(sizeof (smb_shr_pitem_t))) == NULL)
2042da6c28aaSamw 		return;
2043c8ec8eeaSjose borrego 
2044c8ec8eeaSjose borrego 	item->spi_op = op;
2045c8ec8eeaSjose borrego 	(void) strlcpy(item->spi_name, sharename, sizeof (item->spi_name));
2046c8ec8eeaSjose borrego 	(void) strlcpy(item->spi_container, container,
2047c8ec8eeaSjose borrego 	    sizeof (item->spi_container));
2048c8ec8eeaSjose borrego 
2049c8ec8eeaSjose borrego 	(void) mutex_lock(&ad_queue.spq_mtx);
2050c8ec8eeaSjose borrego 	list_insert_tail(&ad_queue.spq_list, item);
2051c8ec8eeaSjose borrego 	(void) cond_signal(&ad_queue.spq_cv);
2052c8ec8eeaSjose borrego 	(void) mutex_unlock(&ad_queue.spq_mtx);
2053da6c28aaSamw }
2054da6c28aaSamw 
2055b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
2056b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Publishing won't be activated if the smb service is running in
2057b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Workgroup mode.
2058b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
2059c8ec8eeaSjose borrego static int
smb_shr_publisher_start(void)2060c8ec8eeaSjose borrego smb_shr_publisher_start(void)
2061da6c28aaSamw {
2062b89a8333Snatalie li - Sun Microsystems - Irvine United States 	pthread_t publish_thr;
2063c8ec8eeaSjose borrego 	pthread_attr_t tattr;
2064c8ec8eeaSjose borrego 	int rc;
2065c8ec8eeaSjose borrego 
2066b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (smb_config_get_secmode() != SMB_SECMODE_DOMAIN)
2067b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (0);
2068b89a8333Snatalie li - Sun Microsystems - Irvine United States 
2069c8ec8eeaSjose borrego 	(void) mutex_lock(&ad_queue.spq_mtx);
2070c8ec8eeaSjose borrego 	if (ad_queue.spq_state != SMB_SHR_PQS_NOQUEUE) {
2071c8ec8eeaSjose borrego 		(void) mutex_unlock(&ad_queue.spq_mtx);
2072c8ec8eeaSjose borrego 		errno = EINVAL;
2073c8ec8eeaSjose borrego 		return (-1);
2074c8ec8eeaSjose borrego 	}
2075c8ec8eeaSjose borrego 
2076c8ec8eeaSjose borrego 	list_create(&ad_queue.spq_list, sizeof (smb_shr_pitem_t),
2077c8ec8eeaSjose borrego 	    offsetof(smb_shr_pitem_t, spi_lnd));
2078c8ec8eeaSjose borrego 	ad_queue.spq_state = SMB_SHR_PQS_READY;
2079c8ec8eeaSjose borrego 	(void) mutex_unlock(&ad_queue.spq_mtx);
2080c8ec8eeaSjose borrego 
2081c8ec8eeaSjose borrego 	(void) pthread_attr_init(&tattr);
2082c8ec8eeaSjose borrego 	(void) pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
2083b89a8333Snatalie li - Sun Microsystems - Irvine United States 	rc = pthread_create(&publish_thr, &tattr, smb_shr_publisher, 0);
2084c8ec8eeaSjose borrego 	(void) pthread_attr_destroy(&tattr);
2085c8ec8eeaSjose borrego 
2086c8ec8eeaSjose borrego 	return (rc);
2087c8ec8eeaSjose borrego }
2088c8ec8eeaSjose borrego 
2089c8ec8eeaSjose borrego static void
smb_shr_publisher_stop(void)2090c8ec8eeaSjose borrego smb_shr_publisher_stop(void)
2091c8ec8eeaSjose borrego {
2092b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (smb_config_get_secmode() != SMB_SECMODE_DOMAIN)
2093b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return;
2094b89a8333Snatalie li - Sun Microsystems - Irvine United States 
2095c8ec8eeaSjose borrego 	(void) mutex_lock(&ad_queue.spq_mtx);
2096c8ec8eeaSjose borrego 	switch (ad_queue.spq_state) {
2097c8ec8eeaSjose borrego 	case SMB_SHR_PQS_READY:
2098c8ec8eeaSjose borrego 	case SMB_SHR_PQS_PUBLISHING:
2099c8ec8eeaSjose borrego 		ad_queue.spq_state = SMB_SHR_PQS_STOPPING;
2100c8ec8eeaSjose borrego 		(void) cond_signal(&ad_queue.spq_cv);
2101c8ec8eeaSjose borrego 		break;
2102c8ec8eeaSjose borrego 	default:
2103c8ec8eeaSjose borrego 		break;
2104c8ec8eeaSjose borrego 	}
2105c8ec8eeaSjose borrego 	(void) mutex_unlock(&ad_queue.spq_mtx);
2106da6c28aaSamw }
2107da6c28aaSamw 
2108da6c28aaSamw /*
2109b89a8333Snatalie li - Sun Microsystems - Irvine United States  * This is the publisher daemon thread.  While running, the thread waits
2110b89a8333Snatalie li - Sun Microsystems - Irvine United States  * on a conditional variable until notified that a share needs to be
2111b89a8333Snatalie li - Sun Microsystems - Irvine United States  * [un]published or that the thread should be terminated.
2112b89a8333Snatalie li - Sun Microsystems - Irvine United States  *
2113b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Entries may remain in the outgoing queue if the Active Directory
2114b89a8333Snatalie li - Sun Microsystems - Irvine United States  * service is inaccessible, in which case the thread wakes up every 60
2115b89a8333Snatalie li - Sun Microsystems - Irvine United States  * seconds to retry.
2116da6c28aaSamw  */
2117da6c28aaSamw /*ARGSUSED*/
2118da6c28aaSamw static void *
smb_shr_publisher(void * arg)21193db3f65cSamw smb_shr_publisher(void *arg)
2120da6c28aaSamw {
21213db3f65cSamw 	smb_ads_handle_t *ah;
2122c8ec8eeaSjose borrego 	smb_shr_pitem_t *shr;
2123c8ec8eeaSjose borrego 	list_t publist;
2124b89a8333Snatalie li - Sun Microsystems - Irvine United States 	timestruc_t pubretry;
2125da6c28aaSamw 	char hostname[MAXHOSTNAMELEN];
2126da6c28aaSamw 
2127c8ec8eeaSjose borrego 	(void) mutex_lock(&ad_queue.spq_mtx);
2128b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (ad_queue.spq_state != SMB_SHR_PQS_READY) {
2129c8ec8eeaSjose borrego 		(void) mutex_unlock(&ad_queue.spq_mtx);
2130c8ec8eeaSjose borrego 		return (NULL);
2131c8ec8eeaSjose borrego 	}
2132b89a8333Snatalie li - Sun Microsystems - Irvine United States 	ad_queue.spq_state = SMB_SHR_PQS_PUBLISHING;
2133c8ec8eeaSjose borrego 	(void) mutex_unlock(&ad_queue.spq_mtx);
2134c8ec8eeaSjose borrego 
21359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) smb_gethostname(hostname, MAXHOSTNAMELEN,
21369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    SMB_CASE_PRESERVE);
2137b89a8333Snatalie li - Sun Microsystems - Irvine United States 
2138c8ec8eeaSjose borrego 	list_create(&publist, sizeof (smb_shr_pitem_t),
2139c8ec8eeaSjose borrego 	    offsetof(smb_shr_pitem_t, spi_lnd));
2140da6c28aaSamw 
2141da6c28aaSamw 	for (;;) {
2142c8ec8eeaSjose borrego 		(void) mutex_lock(&ad_queue.spq_mtx);
2143da6c28aaSamw 
2144b89a8333Snatalie li - Sun Microsystems - Irvine United States 		while (list_is_empty(&ad_queue.spq_list) &&
2145b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    (ad_queue.spq_state == SMB_SHR_PQS_PUBLISHING)) {
2146b89a8333Snatalie li - Sun Microsystems - Irvine United States 			if (list_is_empty(&publist)) {
2147b89a8333Snatalie li - Sun Microsystems - Irvine United States 				(void) cond_wait(&ad_queue.spq_cv,
2148b89a8333Snatalie li - Sun Microsystems - Irvine United States 				    &ad_queue.spq_mtx);
2149b89a8333Snatalie li - Sun Microsystems - Irvine United States 			} else {
2150b89a8333Snatalie li - Sun Microsystems - Irvine United States 				pubretry.tv_sec = 60;
2151b89a8333Snatalie li - Sun Microsystems - Irvine United States 				pubretry.tv_nsec = 0;
2152b89a8333Snatalie li - Sun Microsystems - Irvine United States 				(void) cond_reltimedwait(&ad_queue.spq_cv,
2153b89a8333Snatalie li - Sun Microsystems - Irvine United States 				    &ad_queue.spq_mtx, &pubretry);
2154b89a8333Snatalie li - Sun Microsystems - Irvine United States 				break;
2155b89a8333Snatalie li - Sun Microsystems - Irvine United States 			}
2156da6c28aaSamw 		}
2157c8ec8eeaSjose borrego 
2158b89a8333Snatalie li - Sun Microsystems - Irvine United States 		if (ad_queue.spq_state != SMB_SHR_PQS_PUBLISHING) {
2159c8ec8eeaSjose borrego 			(void) mutex_unlock(&ad_queue.spq_mtx);
2160b89a8333Snatalie li - Sun Microsystems - Irvine United States 			break;
2161da6c28aaSamw 		}
2162c8ec8eeaSjose borrego 
2163c8ec8eeaSjose borrego 		/*
2164b89a8333Snatalie li - Sun Microsystems - Irvine United States 		 * Transfer queued items to the local list so that
2165b89a8333Snatalie li - Sun Microsystems - Irvine United States 		 * the mutex can be released.
2166c8ec8eeaSjose borrego 		 */
2167c8ec8eeaSjose borrego 		while ((shr = list_head(&ad_queue.spq_list)) != NULL) {
2168c8ec8eeaSjose borrego 			list_remove(&ad_queue.spq_list, shr);
2169c8ec8eeaSjose borrego 			list_insert_tail(&publist, shr);
2170da6c28aaSamw 		}
2171b89a8333Snatalie li - Sun Microsystems - Irvine United States 
2172c8ec8eeaSjose borrego 		(void) mutex_unlock(&ad_queue.spq_mtx);
2173c8ec8eeaSjose borrego 
2174b89a8333Snatalie li - Sun Microsystems - Irvine United States 		if ((ah = smb_ads_open()) != NULL) {
2175b89a8333Snatalie li - Sun Microsystems - Irvine United States 			smb_shr_publisher_send(ah, &publist, hostname);
2176b89a8333Snatalie li - Sun Microsystems - Irvine United States 			smb_ads_close(ah);
2177b89a8333Snatalie li - Sun Microsystems - Irvine United States 		}
2178da6c28aaSamw 	}
2179da6c28aaSamw 
2180c8ec8eeaSjose borrego 	(void) mutex_lock(&ad_queue.spq_mtx);
2181b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_shr_publisher_flush(&ad_queue.spq_list);
2182c8ec8eeaSjose borrego 	list_destroy(&ad_queue.spq_list);
2183c8ec8eeaSjose borrego 	ad_queue.spq_state = SMB_SHR_PQS_NOQUEUE;
2184c8ec8eeaSjose borrego 	(void) mutex_unlock(&ad_queue.spq_mtx);
2185da6c28aaSamw 
2186b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_shr_publisher_flush(&publist);
2187c8ec8eeaSjose borrego 	list_destroy(&publist);
2188c8ec8eeaSjose borrego 	return (NULL);
2189da6c28aaSamw }
21903ad684d6Sjb 
21913ad684d6Sjb /*
2192b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Remove items from the specified queue and [un]publish them.
21933ad684d6Sjb  */
21943ad684d6Sjb static void
smb_shr_publisher_send(smb_ads_handle_t * ah,list_t * publist,const char * host)2195c8ec8eeaSjose borrego smb_shr_publisher_send(smb_ads_handle_t *ah, list_t *publist, const char *host)
21963ad684d6Sjb {
2197c8ec8eeaSjose borrego 	smb_shr_pitem_t *shr;
2198c8ec8eeaSjose borrego 
2199c8ec8eeaSjose borrego 	while ((shr = list_head(publist)) != NULL) {
2200b89a8333Snatalie li - Sun Microsystems - Irvine United States 		(void) mutex_lock(&ad_queue.spq_mtx);
2201b89a8333Snatalie li - Sun Microsystems - Irvine United States 		if (ad_queue.spq_state != SMB_SHR_PQS_PUBLISHING) {
2202c8ec8eeaSjose borrego 			(void) mutex_unlock(&ad_queue.spq_mtx);
2203b89a8333Snatalie li - Sun Microsystems - Irvine United States 			return;
2204c8ec8eeaSjose borrego 		}
2205b89a8333Snatalie li - Sun Microsystems - Irvine United States 		(void) mutex_unlock(&ad_queue.spq_mtx);
2206b89a8333Snatalie li - Sun Microsystems - Irvine United States 
2207b89a8333Snatalie li - Sun Microsystems - Irvine United States 		list_remove(publist, shr);
2208b89a8333Snatalie li - Sun Microsystems - Irvine United States 
2209b89a8333Snatalie li - Sun Microsystems - Irvine United States 		if (shr->spi_op == SMB_SHR_PUBLISH)
2210b89a8333Snatalie li - Sun Microsystems - Irvine United States 			(void) smb_ads_publish_share(ah, shr->spi_name,
2211b89a8333Snatalie li - Sun Microsystems - Irvine United States 			    NULL, shr->spi_container, host);
2212b89a8333Snatalie li - Sun Microsystems - Irvine United States 		else
2213b89a8333Snatalie li - Sun Microsystems - Irvine United States 			(void) smb_ads_remove_share(ah, shr->spi_name,
2214b89a8333Snatalie li - Sun Microsystems - Irvine United States 			    NULL, shr->spi_container, host);
2215b89a8333Snatalie li - Sun Microsystems - Irvine United States 
2216b89a8333Snatalie li - Sun Microsystems - Irvine United States 		free(shr);
2217b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
2218b89a8333Snatalie li - Sun Microsystems - Irvine United States }
2219b89a8333Snatalie li - Sun Microsystems - Irvine United States 
2220b89a8333Snatalie li - Sun Microsystems - Irvine United States /*
2221b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Flush all remaining items from the specified list/queue.
2222b89a8333Snatalie li - Sun Microsystems - Irvine United States  */
2223b89a8333Snatalie li - Sun Microsystems - Irvine United States static void
smb_shr_publisher_flush(list_t * lst)2224b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_shr_publisher_flush(list_t *lst)
2225b89a8333Snatalie li - Sun Microsystems - Irvine United States {
2226b89a8333Snatalie li - Sun Microsystems - Irvine United States 	smb_shr_pitem_t *shr;
2227b89a8333Snatalie li - Sun Microsystems - Irvine United States 
2228b89a8333Snatalie li - Sun Microsystems - Irvine United States 	while ((shr = list_head(lst)) != NULL) {
2229b89a8333Snatalie li - Sun Microsystems - Irvine United States 		list_remove(lst, shr);
2230c8ec8eeaSjose borrego 		free(shr);
22313ad684d6Sjb 	}
22323ad684d6Sjb }
2233743a77edSAlan Wright 
2234743a77edSAlan Wright /*
22356d57f833SAlan Wright  * If the share path refers to a ZFS file system, add the
2236db46347bSGordon Ross  * .zfs/shares/<share> object and add or remove the special
2237db46347bSGordon Ross  * directory and file telling clients about quota support.
2238743a77edSAlan Wright  */
2239743a77edSAlan Wright static void
smb_shr_zfs_add(smb_share_t * si)22406d57f833SAlan Wright smb_shr_zfs_add(smb_share_t *si)
2241743a77edSAlan Wright {
22426d57f833SAlan Wright 	libzfs_handle_t *libhd;
22436d57f833SAlan Wright 	zfs_handle_t *zfshd;
22446d57f833SAlan Wright 	int ret;
22459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	char buf[MAXPATHLEN];	/* dataset or mountpoint */
2246743a77edSAlan Wright 
224787b81758SJoyce McIntosh 	if ((libhd = libzfs_init()) == NULL)
2248743a77edSAlan Wright 		return;
2249743a77edSAlan Wright 
225087b81758SJoyce McIntosh 	if (smb_getdataset(libhd, si->shr_path, buf, MAXPATHLEN) != 0) {
225187b81758SJoyce McIntosh 		libzfs_fini(libhd);
22526d57f833SAlan Wright 		return;
225387b81758SJoyce McIntosh 	}
2254743a77edSAlan Wright 
22559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((zfshd = zfs_open(libhd, buf, ZFS_TYPE_FILESYSTEM)) == NULL) {
22566d57f833SAlan Wright 		libzfs_fini(libhd);
22576d57f833SAlan Wright 		return;
22586d57f833SAlan Wright 	}
2259743a77edSAlan Wright 
22606d57f833SAlan Wright 	errno = 0;
22619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ret = zfs_smb_acl_add(libhd, buf, si->shr_path, si->shr_name);
22626d57f833SAlan Wright 	if (ret != 0 && errno != EAGAIN && errno != EEXIST)
22636d57f833SAlan Wright 		syslog(LOG_INFO, "share: failed to add ACL object: %s: %s\n",
22646d57f833SAlan Wright 		    si->shr_name, strerror(errno));
2265743a77edSAlan Wright 
2266db46347bSGordon Ross 	ret = zfs_prop_get(zfshd, ZFS_PROP_MOUNTPOINT,
2267db46347bSGordon Ross 	    buf, MAXPATHLEN, NULL, NULL, 0, B_FALSE);
2268db46347bSGordon Ross 	if (ret != 0) {
2269db46347bSGordon Ross 		syslog(LOG_INFO, "share: failed to get mountpoint: "
2270db46347bSGordon Ross 		    "%s\n", si->shr_name);
2271db46347bSGordon Ross 	} else {
2272db46347bSGordon Ross 		if ((si->shr_flags & SMB_SHRF_QUOTAS) != 0) {
2273ca5fb90aSGordon Ross 			smb_quota_add_fs(buf);
2274db46347bSGordon Ross 		} else {
2275db46347bSGordon Ross 			smb_quota_remove_fs(buf);
2276ca5fb90aSGordon Ross 		}
22779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
22789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
22796d57f833SAlan Wright 	zfs_close(zfshd);
22806d57f833SAlan Wright 	libzfs_fini(libhd);
2281743a77edSAlan Wright }
2282743a77edSAlan Wright 
2283743a77edSAlan Wright /*
22846d57f833SAlan Wright  * If the share path refers to a ZFS file system, remove the
2285db46347bSGordon Ross  * .zfs/shares/<share> object.
2286743a77edSAlan Wright  */
2287743a77edSAlan Wright static void
smb_shr_zfs_remove(smb_share_t * si)2288743a77edSAlan Wright smb_shr_zfs_remove(smb_share_t *si)
2289743a77edSAlan Wright {
22906d57f833SAlan Wright 	libzfs_handle_t *libhd;
22916d57f833SAlan Wright 	int ret;
22929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	char buf[MAXPATHLEN];	/* dataset or mountpoint */
2293743a77edSAlan Wright 
229487b81758SJoyce McIntosh 	if ((libhd = libzfs_init()) == NULL)
22956d57f833SAlan Wright 		return;
22966d57f833SAlan Wright 
229787b81758SJoyce McIntosh 	if (smb_getdataset(libhd, si->shr_path, buf, MAXPATHLEN) != 0) {
229887b81758SJoyce McIntosh 		libzfs_fini(libhd);
22996d57f833SAlan Wright 		return;
230087b81758SJoyce McIntosh 	}
23016d57f833SAlan Wright 
23026d57f833SAlan Wright 	errno = 0;
23039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ret = zfs_smb_acl_remove(libhd, buf, si->shr_path, si->shr_name);
23046d57f833SAlan Wright 	if (ret != 0 && errno != EAGAIN)
23056d57f833SAlan Wright 		syslog(LOG_INFO, "share: failed to remove ACL object: %s: %s\n",
23066d57f833SAlan Wright 		    si->shr_name, strerror(errno));
23076d57f833SAlan Wright 
2308db46347bSGordon Ross 	/*
2309db46347bSGordon Ross 	 * We could remove the quotas directory here, but that adds
2310db46347bSGordon Ross 	 * significantly to the time required for a zpool export,
2311db46347bSGordon Ross 	 * so just leave it here and fixup when we share next.
2312db46347bSGordon Ross 	 */
23139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
23146d57f833SAlan Wright 	libzfs_fini(libhd);
2315743a77edSAlan Wright }
2316743a77edSAlan Wright 
2317743a77edSAlan Wright /*
23186d57f833SAlan Wright  * If the share path refers to a ZFS file system, rename the
2319743a77edSAlan Wright  * .zfs/shares/<share> object.
2320743a77edSAlan Wright  */
2321743a77edSAlan Wright static void
smb_shr_zfs_rename(smb_share_t * from,smb_share_t * to)2322743a77edSAlan Wright smb_shr_zfs_rename(smb_share_t *from, smb_share_t *to)
2323743a77edSAlan Wright {
23246d57f833SAlan Wright 	libzfs_handle_t *libhd;
23256d57f833SAlan Wright 	zfs_handle_t *zfshd;
23266d57f833SAlan Wright 	int ret;
2327743a77edSAlan Wright 	char dataset[MAXPATHLEN];
2328743a77edSAlan Wright 
232987b81758SJoyce McIntosh 	if ((libhd = libzfs_init()) == NULL)
23306d57f833SAlan Wright 		return;
23316d57f833SAlan Wright 
233287b81758SJoyce McIntosh 	if (smb_getdataset(libhd, from->shr_path, dataset, MAXPATHLEN) != 0) {
233387b81758SJoyce McIntosh 		libzfs_fini(libhd);
23346d57f833SAlan Wright 		return;
233587b81758SJoyce McIntosh 	}
23366d57f833SAlan Wright 
23376d57f833SAlan Wright 	if ((zfshd = zfs_open(libhd, dataset, ZFS_TYPE_FILESYSTEM)) == NULL) {
23386d57f833SAlan Wright 		libzfs_fini(libhd);
23396d57f833SAlan Wright 		return;
2340743a77edSAlan Wright 	}
23416d57f833SAlan Wright 
23426d57f833SAlan Wright 	errno = 0;
23436d57f833SAlan Wright 	ret = zfs_smb_acl_rename(libhd, dataset, from->shr_path,
23446d57f833SAlan Wright 	    from->shr_name, to->shr_name);
23456d57f833SAlan Wright 	if (ret != 0 && errno != EAGAIN)
23466d57f833SAlan Wright 		syslog(LOG_INFO, "share: failed to rename ACL object: %s: %s\n",
23476d57f833SAlan Wright 		    from->shr_name, strerror(errno));
23486d57f833SAlan Wright 
23496d57f833SAlan Wright 	zfs_close(zfshd);
23506d57f833SAlan Wright 	libzfs_fini(libhd);
2351743a77edSAlan Wright }
235229bd2886SAlan Wright 
235329bd2886SAlan Wright /*
235429bd2886SAlan Wright  * Enable all privileges in the inheritable set to execute command.
235529bd2886SAlan Wright  */
235629bd2886SAlan Wright static int
smb_shr_enable_all_privs(void)235729bd2886SAlan Wright smb_shr_enable_all_privs(void)
235829bd2886SAlan Wright {
235929bd2886SAlan Wright 	priv_set_t *pset;
236029bd2886SAlan Wright 
236129bd2886SAlan Wright 	pset = priv_allocset();
236229bd2886SAlan Wright 	if (pset == NULL)
236329bd2886SAlan Wright 		return (-1);
236429bd2886SAlan Wright 
236529bd2886SAlan Wright 	if (getppriv(PRIV_LIMIT, pset)) {
236629bd2886SAlan Wright 		priv_freeset(pset);
236729bd2886SAlan Wright 		return (-1);
236829bd2886SAlan Wright 	}
236929bd2886SAlan Wright 
237029bd2886SAlan Wright 	if (setppriv(PRIV_ON, PRIV_INHERITABLE, pset)) {
237129bd2886SAlan Wright 		priv_freeset(pset);
237229bd2886SAlan Wright 		return (-1);
237329bd2886SAlan Wright 	}
237429bd2886SAlan Wright 
237529bd2886SAlan Wright 	priv_freeset(pset);
237629bd2886SAlan Wright 	return (0);
237729bd2886SAlan Wright }
237829bd2886SAlan Wright 
237929bd2886SAlan Wright /*
238029bd2886SAlan Wright  * Tokenizes the command string and returns the list of tokens in an array.
238129bd2886SAlan Wright  *
238229bd2886SAlan Wright  * Returns NULL if there are no tokens.
238329bd2886SAlan Wright  */
238429bd2886SAlan Wright static char **
smb_shr_tokenize_cmd(char * cmdstr)238529bd2886SAlan Wright smb_shr_tokenize_cmd(char *cmdstr)
238629bd2886SAlan Wright {
238729bd2886SAlan Wright 	char *cmd, *buf, *bp, *value;
238829bd2886SAlan Wright 	char **argv, **ap;
238929bd2886SAlan Wright 	int argc, i;
239029bd2886SAlan Wright 
239129bd2886SAlan Wright 	if (cmdstr == NULL || *cmdstr == '\0')
239229bd2886SAlan Wright 		return (NULL);
239329bd2886SAlan Wright 
239429bd2886SAlan Wright 	if ((buf = malloc(MAXPATHLEN)) == NULL)
239529bd2886SAlan Wright 		return (NULL);
239629bd2886SAlan Wright 
239729bd2886SAlan Wright 	(void) strlcpy(buf, cmdstr, MAXPATHLEN);
239829bd2886SAlan Wright 
239929bd2886SAlan Wright 	for (argc = 2, bp = cmdstr; *bp != '\0'; ++bp)
240029bd2886SAlan Wright 		if (*bp == ' ')
240129bd2886SAlan Wright 			++argc;
240229bd2886SAlan Wright 
240329bd2886SAlan Wright 	if ((argv = calloc(argc, sizeof (char *))) == NULL) {
240429bd2886SAlan Wright 		free(buf);
240529bd2886SAlan Wright 		return (NULL);
240629bd2886SAlan Wright 	}
240729bd2886SAlan Wright 
240829bd2886SAlan Wright 	ap = argv;
240929bd2886SAlan Wright 	for (bp = buf, i = 0; i < argc; ++i) {
241029bd2886SAlan Wright 		do {
241129bd2886SAlan Wright 			if ((value = strsep(&bp, " ")) == NULL)
241229bd2886SAlan Wright 				break;
241329bd2886SAlan Wright 		} while (*value == '\0');
241429bd2886SAlan Wright 
241529bd2886SAlan Wright 		if (value == NULL)
241629bd2886SAlan Wright 			break;
241729bd2886SAlan Wright 
241829bd2886SAlan Wright 		*ap++ = value;
241929bd2886SAlan Wright 	}
242029bd2886SAlan Wright 
242129bd2886SAlan Wright 	/* get the filename of the command from the path */
242229bd2886SAlan Wright 	if ((cmd = strrchr(argv[0], '/')) != NULL)
242329bd2886SAlan Wright 		(void) strlcpy(argv[0], ++cmd, strlen(argv[0]));
242429bd2886SAlan Wright 
242529bd2886SAlan Wright 	return (argv);
242629bd2886SAlan Wright }
242729bd2886SAlan Wright 
242829bd2886SAlan Wright /*
242929bd2886SAlan Wright  * Expands the command string for the following substitution tokens:
243029bd2886SAlan Wright  *
243129bd2886SAlan Wright  * %U - Windows username
243229bd2886SAlan Wright  * %D - Name of the domain or workgroup of %U
243329bd2886SAlan Wright  * %h - The server hostname
243429bd2886SAlan Wright  * %M - The client hostname
243529bd2886SAlan Wright  * %L - The server NetBIOS name
243629bd2886SAlan Wright  * %m - The client NetBIOS name. This option is only valid for NetBIOS
243729bd2886SAlan Wright  *      connections (port 139).
243829bd2886SAlan Wright  * %I - The IP address of the client machine
243929bd2886SAlan Wright  * %i - The local IP address to which the client is connected
244029bd2886SAlan Wright  * %S - The name of the share
244129bd2886SAlan Wright  * %P - The root directory of the share
244229bd2886SAlan Wright  * %u - The UID of the Unix user
244329bd2886SAlan Wright  *
244429bd2886SAlan Wright  * Returns 0 on success.  Otherwise -1.
244529bd2886SAlan Wright  */
244629bd2886SAlan Wright static int
smb_shr_expand_subs(char ** cmd_toks,smb_share_t * si,smb_shr_execinfo_t * subs)2447148c5f43SAlan Wright smb_shr_expand_subs(char **cmd_toks, smb_share_t *si, smb_shr_execinfo_t *subs)
244829bd2886SAlan Wright {
244929bd2886SAlan Wright 	char *fmt, *sub_chr, *ptr;
245029bd2886SAlan Wright 	boolean_t unknown;
245129bd2886SAlan Wright 	char hostname[MAXHOSTNAMELEN];
245229bd2886SAlan Wright 	char ip_str[INET6_ADDRSTRLEN];
245329bd2886SAlan Wright 	char name[SMB_PI_MAX_HOST];
2454bbf6f00cSJordan Brown 	smb_wchar_t wbuf[SMB_PI_MAX_HOST];
245529bd2886SAlan Wright 	int i;
245629bd2886SAlan Wright 
245729bd2886SAlan Wright 	if (cmd_toks == NULL || *cmd_toks == NULL)
245829bd2886SAlan Wright 		return (-1);
245929bd2886SAlan Wright 
246029bd2886SAlan Wright 	for (i = 1; cmd_toks[i]; i++) {
246129bd2886SAlan Wright 		fmt = cmd_toks[i];
246229bd2886SAlan Wright 		if (*fmt == '%') {
246329bd2886SAlan Wright 			sub_chr = fmt + 1;
246429bd2886SAlan Wright 			unknown = B_FALSE;
246529bd2886SAlan Wright 
246629bd2886SAlan Wright 			switch (*sub_chr) {
246729bd2886SAlan Wright 			case 'U':
246829bd2886SAlan Wright 				ptr = strdup(subs->e_winname);
246929bd2886SAlan Wright 				break;
247029bd2886SAlan Wright 			case 'D':
247129bd2886SAlan Wright 				ptr = strdup(subs->e_userdom);
247229bd2886SAlan Wright 				break;
247329bd2886SAlan Wright 			case 'h':
247429bd2886SAlan Wright 				if (gethostname(hostname, MAXHOSTNAMELEN) != 0)
247529bd2886SAlan Wright 					unknown = B_TRUE;
247629bd2886SAlan Wright 				else
247729bd2886SAlan Wright 					ptr = strdup(hostname);
247829bd2886SAlan Wright 				break;
247929bd2886SAlan Wright 			case 'M':
248029bd2886SAlan Wright 				if (smb_getnameinfo(&subs->e_cli_ipaddr,
248129bd2886SAlan Wright 				    hostname, sizeof (hostname), 0) != 0)
248229bd2886SAlan Wright 					unknown = B_TRUE;
248329bd2886SAlan Wright 				else
248429bd2886SAlan Wright 					ptr = strdup(hostname);
248529bd2886SAlan Wright 				break;
248629bd2886SAlan Wright 			case 'L':
248729bd2886SAlan Wright 				if (smb_getnetbiosname(hostname,
248829bd2886SAlan Wright 				    NETBIOS_NAME_SZ) != 0)
248929bd2886SAlan Wright 					unknown = B_TRUE;
249029bd2886SAlan Wright 				else
249129bd2886SAlan Wright 					ptr = strdup(hostname);
249229bd2886SAlan Wright 				break;
249329bd2886SAlan Wright 			case 'm':
249429bd2886SAlan Wright 				if (*subs->e_cli_netbiosname == '\0')
249529bd2886SAlan Wright 					unknown = B_TRUE;
249629bd2886SAlan Wright 				else {
2497bbf6f00cSJordan Brown 					(void) smb_mbstowcs(wbuf,
249829bd2886SAlan Wright 					    subs->e_cli_netbiosname,
249929bd2886SAlan Wright 					    SMB_PI_MAX_HOST - 1);
250029bd2886SAlan Wright 
2501bbf6f00cSJordan Brown 					if (ucstooem(name, wbuf,
2502bbf6f00cSJordan Brown 					    SMB_PI_MAX_HOST, OEM_CPG_850) == 0)
250329bd2886SAlan Wright 						(void) strlcpy(name,
250429bd2886SAlan Wright 						    subs->e_cli_netbiosname,
250529bd2886SAlan Wright 						    SMB_PI_MAX_HOST);
250629bd2886SAlan Wright 
250729bd2886SAlan Wright 					ptr = strdup(name);
250829bd2886SAlan Wright 				}
250929bd2886SAlan Wright 				break;
251029bd2886SAlan Wright 			case 'I':
251129bd2886SAlan Wright 				if (smb_inet_ntop(&subs->e_cli_ipaddr, ip_str,
251229bd2886SAlan Wright 				    SMB_IPSTRLEN(subs->e_cli_ipaddr.a_family))
251329bd2886SAlan Wright 				    != NULL)
251429bd2886SAlan Wright 					ptr = strdup(ip_str);
251529bd2886SAlan Wright 				else
251629bd2886SAlan Wright 					unknown = B_TRUE;
251729bd2886SAlan Wright 				break;
251829bd2886SAlan Wright 			case 'i':
251929bd2886SAlan Wright 				if (smb_inet_ntop(&subs->e_srv_ipaddr, ip_str,
252029bd2886SAlan Wright 				    SMB_IPSTRLEN(subs->e_srv_ipaddr.a_family))
252129bd2886SAlan Wright 				    != NULL)
252229bd2886SAlan Wright 					ptr = strdup(ip_str);
252329bd2886SAlan Wright 				else
252429bd2886SAlan Wright 					unknown = B_TRUE;
252529bd2886SAlan Wright 				break;
252629bd2886SAlan Wright 			case 'S':
252729bd2886SAlan Wright 				ptr = strdup(si->shr_name);
252829bd2886SAlan Wright 				break;
252929bd2886SAlan Wright 			case 'P':
253029bd2886SAlan Wright 				ptr = strdup(si->shr_path);
253129bd2886SAlan Wright 				break;
253229bd2886SAlan Wright 			case 'u':
253329bd2886SAlan Wright 				(void) snprintf(name, sizeof (name), "%u",
253429bd2886SAlan Wright 				    subs->e_uid);
253529bd2886SAlan Wright 				ptr = strdup(name);
253629bd2886SAlan Wright 				break;
253729bd2886SAlan Wright 			default:
253829bd2886SAlan Wright 				/* unknown sub char */
253929bd2886SAlan Wright 				unknown = B_TRUE;
254029bd2886SAlan Wright 				break;
254129bd2886SAlan Wright 			}
254229bd2886SAlan Wright 
254329bd2886SAlan Wright 			if (unknown)
254429bd2886SAlan Wright 				ptr = strdup("");
254529bd2886SAlan Wright 
254629bd2886SAlan Wright 		} else  /* first char of cmd's arg is not '%' char */
254729bd2886SAlan Wright 			ptr = strdup("");
254829bd2886SAlan Wright 
254929bd2886SAlan Wright 		cmd_toks[i] = ptr;
255029bd2886SAlan Wright 
255129bd2886SAlan Wright 		if (ptr == NULL) {
255229bd2886SAlan Wright 			for (i = 1; cmd_toks[i]; i++)
255329bd2886SAlan Wright 				free(cmd_toks[i]);
255429bd2886SAlan Wright 
255529bd2886SAlan Wright 			return (-1);
255629bd2886SAlan Wright 		}
255729bd2886SAlan Wright 	}
255829bd2886SAlan Wright 
255929bd2886SAlan Wright 	return (0);
256029bd2886SAlan Wright }
256129bd2886SAlan Wright 
256229bd2886SAlan Wright /*ARGSUSED*/
256329bd2886SAlan Wright static void
smb_shr_sig_abnormal_term(int sig_val)256429bd2886SAlan Wright smb_shr_sig_abnormal_term(int sig_val)
256529bd2886SAlan Wright {
256629bd2886SAlan Wright 	/*
256729bd2886SAlan Wright 	 * Calling _exit() prevents parent process from getting SIGTERM/SIGINT
256829bd2886SAlan Wright 	 * signal.
256929bd2886SAlan Wright 	 */
257029bd2886SAlan Wright 	_exit(-1);
257129bd2886SAlan Wright }
257229bd2886SAlan Wright 
257329bd2886SAlan Wright /*ARGSUSED*/
257429bd2886SAlan Wright static void
smb_shr_sig_child(int sig_val)257529bd2886SAlan Wright smb_shr_sig_child(int sig_val)
257629bd2886SAlan Wright {
257729bd2886SAlan Wright 	/*
257829bd2886SAlan Wright 	 * Catch the signal and allow the exit status of the child process
257929bd2886SAlan Wright 	 * to be available for reaping.
258029bd2886SAlan Wright 	 */
258129bd2886SAlan Wright }
258229bd2886SAlan Wright 
258329bd2886SAlan Wright /*
2584148c5f43SAlan Wright  * This is a temporary function which converts the given smb_share_t
2585148c5f43SAlan Wright  * structure to the nvlist format that will be provided by libsharev2
258629bd2886SAlan Wright  */
2587148c5f43SAlan Wright static int
smb_shr_encode(smb_share_t * si,nvlist_t ** nvlist)2588148c5f43SAlan Wright smb_shr_encode(smb_share_t *si, nvlist_t **nvlist)
258929bd2886SAlan Wright {
2590148c5f43SAlan Wright 	nvlist_t *list;
2591148c5f43SAlan Wright 	nvlist_t *share;
2592148c5f43SAlan Wright 	nvlist_t *smb;
2593148c5f43SAlan Wright 	char *csc;
2594148c5f43SAlan Wright 	int rc = 0;
259529bd2886SAlan Wright 
2596148c5f43SAlan Wright 	*nvlist = NULL;
259729bd2886SAlan Wright 
2598148c5f43SAlan Wright 	if ((rc = nvlist_alloc(&list, NV_UNIQUE_NAME, 0)) != 0)
2599148c5f43SAlan Wright 		return (rc);
260029bd2886SAlan Wright 
2601148c5f43SAlan Wright 	if ((rc = nvlist_alloc(&share, NV_UNIQUE_NAME, 0)) != 0) {
2602148c5f43SAlan Wright 		nvlist_free(list);
2603148c5f43SAlan Wright 		return (rc);
2604148c5f43SAlan Wright 	}
260529bd2886SAlan Wright 
2606148c5f43SAlan Wright 	if ((rc = nvlist_alloc(&smb, NV_UNIQUE_NAME, 0)) != 0) {
2607148c5f43SAlan Wright 		nvlist_free(share);
2608148c5f43SAlan Wright 		nvlist_free(list);
2609148c5f43SAlan Wright 		return (rc);
2610148c5f43SAlan Wright 	}
261129bd2886SAlan Wright 
2612148c5f43SAlan Wright 	/* global share properties */
2613148c5f43SAlan Wright 	rc |= nvlist_add_string(share, "name", si->shr_name);
2614148c5f43SAlan Wright 	rc |= nvlist_add_string(share, "path", si->shr_path);
2615148c5f43SAlan Wright 	rc |= nvlist_add_string(share, "desc", si->shr_cmnt);
261629bd2886SAlan Wright 
2617148c5f43SAlan Wright 	/* smb protocol properties */
2618148c5f43SAlan Wright 	rc = nvlist_add_string(smb, SHOPT_AD_CONTAINER, si->shr_container);
2619148c5f43SAlan Wright 	if ((si->shr_flags & SMB_SHRF_ACC_NONE) != 0)
2620148c5f43SAlan Wright 		rc |= nvlist_add_string(smb, SHOPT_NONE, si->shr_access_none);
2621148c5f43SAlan Wright 	if ((si->shr_flags & SMB_SHRF_ACC_RO) != 0)
2622148c5f43SAlan Wright 		rc |= nvlist_add_string(smb, SHOPT_RO, si->shr_access_ro);
2623148c5f43SAlan Wright 	if ((si->shr_flags & SMB_SHRF_ACC_RW) != 0)
2624148c5f43SAlan Wright 		rc |= nvlist_add_string(smb, SHOPT_RW, si->shr_access_rw);
262529bd2886SAlan Wright 
2626148c5f43SAlan Wright 	if ((si->shr_flags & SMB_SHRF_ABE) != 0)
2627148c5f43SAlan Wright 		rc |= nvlist_add_string(smb, SHOPT_ABE, "true");
2628148c5f43SAlan Wright 	if ((si->shr_flags & SMB_SHRF_CATIA) != 0)
2629148c5f43SAlan Wright 		rc |= nvlist_add_string(smb, SHOPT_CATIA, "true");
2630148c5f43SAlan Wright 	if ((si->shr_flags & SMB_SHRF_GUEST_OK) != 0)
2631148c5f43SAlan Wright 		rc |= nvlist_add_string(smb, SHOPT_GUEST, "true");
2632148c5f43SAlan Wright 	if ((si->shr_flags & SMB_SHRF_DFSROOT) != 0)
2633148c5f43SAlan Wright 		rc |= nvlist_add_string(smb, SHOPT_DFSROOT, "true");
26348d94f651SGordon Ross 	if ((si->shr_flags & SMB_SHRF_CA) != 0)
26358d94f651SGordon Ross 		rc |= nvlist_add_string(smb, SHOPT_CA, "true");
263694047d49SGordon Ross 	if ((si->shr_flags & SMB_SHRF_FSO) != 0)
263794047d49SGordon Ross 		rc |= nvlist_add_string(smb, SHOPT_FSO, "true");
2638ca5fb90aSGordon Ross 	if ((si->shr_flags & SMB_SHRF_QUOTAS) != 0)
2639ca5fb90aSGordon Ross 		rc |= nvlist_add_string(smb, SHOPT_QUOTAS, "true");
2640148c5f43SAlan Wright 
26411160dcf7SMatt Barden 	if (si->shr_encrypt == SMB_CONFIG_REQUIRED)
26421160dcf7SMatt Barden 		rc |= nvlist_add_string(smb, SHOPT_ENCRYPT, "required");
26431160dcf7SMatt Barden 	else if (si->shr_encrypt == SMB_CONFIG_ENABLED)
26441160dcf7SMatt Barden 		rc |= nvlist_add_string(smb, SHOPT_ENCRYPT, "enabled");
26451160dcf7SMatt Barden 	else
26461160dcf7SMatt Barden 		rc |= nvlist_add_string(smb, SHOPT_ENCRYPT, "disabled");
26471160dcf7SMatt Barden 
2648148c5f43SAlan Wright 	if ((si->shr_flags & SMB_SHRF_AUTOHOME) != 0) {
2649ca5fb90aSGordon Ross 		rc |= nvlist_add_string(smb, SHOPT_AUTOHOME, "true");
2650148c5f43SAlan Wright 		rc |= nvlist_add_uint32(smb, "uid", si->shr_uid);
2651148c5f43SAlan Wright 		rc |= nvlist_add_uint32(smb, "gid", si->shr_gid);
2652148c5f43SAlan Wright 	}
2653148c5f43SAlan Wright 
2654148c5f43SAlan Wright 	if ((csc = smb_shr_sa_csc_name(si)) != NULL)
2655148c5f43SAlan Wright 		rc |= nvlist_add_string(smb, SHOPT_CSC, csc);
2656148c5f43SAlan Wright 
2657cb174861Sjoyce mcintosh 	rc |= nvlist_add_uint32(smb, "type", si->shr_type);
2658cb174861Sjoyce mcintosh 
2659148c5f43SAlan Wright 	rc |= nvlist_add_nvlist(share, "smb", smb);
2660148c5f43SAlan Wright 	rc |= nvlist_add_nvlist(list, si->shr_name, share);
2661148c5f43SAlan Wright 
2662148c5f43SAlan Wright 	nvlist_free(share);
2663148c5f43SAlan Wright 	nvlist_free(smb);
2664148c5f43SAlan Wright 
2665148c5f43SAlan Wright 	if (rc != 0)
2666148c5f43SAlan Wright 		nvlist_free(list);
2667148c5f43SAlan Wright 	else
2668148c5f43SAlan Wright 		*nvlist = list;
2669148c5f43SAlan Wright 
2670148c5f43SAlan Wright 	return (rc);
267129bd2886SAlan Wright }
2672