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