xref: /titanic_44/usr/src/lib/smbsrv/libmlsvc/common/smb_share.c (revision ac88567a7a5bb7f01cf22cf366bc9d6203e24d7a)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23  */
24 
25 /*
26  * SMB/CIFS share cache implementation.
27  */
28 
29 #include <errno.h>
30 #include <synch.h>
31 #include <stdlib.h>
32 #include <strings.h>
33 #include <syslog.h>
34 #include <thread.h>
35 #include <pthread.h>
36 #include <assert.h>
37 #include <libshare.h>
38 #include <libzfs.h>
39 #include <priv_utils.h>
40 #include <sys/types.h>
41 #include <sys/wait.h>
42 #include <unistd.h>
43 #include <pwd.h>
44 #include <signal.h>
45 #include <dirent.h>
46 
47 #include <smbsrv/libsmb.h>
48 #include <smbsrv/libsmbns.h>
49 #include <smbsrv/libmlsvc.h>
50 #include <smbsrv/smb_share.h>
51 #include <smbsrv/smb.h>
52 #include <mlsvc.h>
53 #include <dfs.h>
54 
55 #define	SMB_SHR_ERROR_THRESHOLD		3
56 #define	SMB_SHR_CSC_BUFSZ		64
57 
58 typedef struct smb_transient {
59 	char		*name;
60 	char		*cmnt;
61 	char		*path;
62 	char		drive;
63 	boolean_t	check;
64 } smb_transient_t;
65 
66 static smb_transient_t tshare[] = {
67 	{ "IPC$", "Remote IPC",		NULL,		'\0', B_FALSE },
68 	{ "c$",   "Default Share",	SMB_CVOL,	'C',  B_FALSE },
69 	{ "vss$", "VSS",		SMB_VSS,	'V',  B_TRUE }
70 };
71 
72 static struct {
73 	char *value;
74 	uint32_t flag;
75 } cscopt[] = {
76 	{ "disabled",	SMB_SHRF_CSC_DISABLED },
77 	{ "manual",	SMB_SHRF_CSC_MANUAL },
78 	{ "auto",	SMB_SHRF_CSC_AUTO },
79 	{ "vdo",	SMB_SHRF_CSC_VDO }
80 };
81 
82 /*
83  * Cache functions and vars
84  */
85 #define	SMB_SHR_HTAB_SZ			1024
86 
87 /*
88  * Cache handle
89  *
90  * Shares cache is a hash table.
91  *
92  * sc_cache		pointer to hash table handle
93  * sc_cache_lck		synchronize cache read/write accesses
94  * sc_state		cache state machine values
95  * sc_nops		number of inflight/pending cache operations
96  * sc_mtx		protects handle fields
97  */
98 typedef struct smb_shr_cache {
99 	HT_HANDLE	*sc_cache;
100 	rwlock_t	sc_cache_lck;
101 	mutex_t		sc_mtx;
102 	cond_t		sc_cv;
103 	uint32_t	sc_state;
104 	uint32_t	sc_nops;
105 } smb_shr_cache_t;
106 
107 /*
108  * Cache states
109  */
110 #define	SMB_SHR_CACHE_STATE_NONE	0
111 #define	SMB_SHR_CACHE_STATE_CREATED	1
112 #define	SMB_SHR_CACHE_STATE_DESTROYING	2
113 
114 /*
115  * Cache lock modes
116  */
117 #define	SMB_SHR_CACHE_RDLOCK	0
118 #define	SMB_SHR_CACHE_WRLOCK	1
119 
120 static smb_shr_cache_t smb_shr_cache;
121 
122 static uint32_t smb_shr_cache_create(void);
123 static void smb_shr_cache_destroy(void);
124 static uint32_t smb_shr_cache_lock(int);
125 static void smb_shr_cache_unlock(void);
126 static int smb_shr_cache_count(void);
127 static smb_share_t *smb_shr_cache_iterate(smb_shriter_t *);
128 
129 static smb_share_t *smb_shr_cache_findent(char *);
130 static uint32_t smb_shr_cache_addent(smb_share_t *);
131 static void smb_shr_cache_delent(char *);
132 static void smb_shr_cache_freent(HT_ITEM *);
133 
134 static boolean_t smb_shr_is_empty(const char *);
135 static boolean_t smb_shr_is_dot_or_dotdot(const char *);
136 
137 /*
138  * sharemgr functions
139  */
140 static void *smb_shr_sa_loadall(void *);
141 static void smb_shr_sa_loadgrp(sa_group_t);
142 static uint32_t smb_shr_sa_load(sa_share_t, sa_resource_t);
143 static uint32_t smb_shr_sa_loadbyname(char *);
144 static uint32_t smb_shr_sa_get(sa_share_t, sa_resource_t, smb_share_t *);
145 
146 /*
147  * .ZFS management functions
148  */
149 static void smb_shr_zfs_add(smb_share_t *);
150 static void smb_shr_zfs_remove(smb_share_t *);
151 static void smb_shr_zfs_rename(smb_share_t *, smb_share_t *);
152 
153 /*
154  * share publishing
155  */
156 #define	SMB_SHR_PUBLISH		0
157 #define	SMB_SHR_UNPUBLISH	1
158 
159 typedef struct smb_shr_pitem {
160 	list_node_t	spi_lnd;
161 	char		spi_name[MAXNAMELEN];
162 	char		spi_container[MAXPATHLEN];
163 	char		spi_op;
164 } smb_shr_pitem_t;
165 
166 /*
167  * publish queue states
168  */
169 #define	SMB_SHR_PQS_NOQUEUE	0
170 #define	SMB_SHR_PQS_READY	1	/* the queue is ready */
171 #define	SMB_SHR_PQS_PUBLISHING	2	/* publisher thread is running */
172 #define	SMB_SHR_PQS_STOPPING	3
173 
174 /*
175  * share publishing queue
176  */
177 typedef struct smb_shr_pqueue {
178 	list_t		spq_list;
179 	mutex_t		spq_mtx;
180 	cond_t		spq_cv;
181 	uint32_t	spq_state;
182 } smb_shr_pqueue_t;
183 
184 static smb_shr_pqueue_t ad_queue;
185 
186 static int smb_shr_publisher_start(void);
187 static void smb_shr_publisher_stop(void);
188 static void smb_shr_publisher_send(smb_ads_handle_t *, list_t *, const char *);
189 static void smb_shr_publisher_queue(const char *, const char *, char);
190 static void *smb_shr_publisher(void *);
191 static void smb_shr_publisher_flush(list_t *);
192 static void smb_shr_publish(const char *, const char *);
193 static void smb_shr_unpublish(const char *, const char *);
194 
195 /*
196  * Utility/helper functions
197  */
198 static uint32_t smb_shr_lookup(char *, smb_share_t *);
199 static uint32_t smb_shr_add_transient(char *, char *, char *);
200 static void smb_shr_set_oemname(smb_share_t *);
201 static int smb_shr_enable_all_privs(void);
202 static int smb_shr_expand_subs(char **, smb_share_t *, smb_execsub_info_t *);
203 static char **smb_shr_tokenize_cmd(char *);
204 static void smb_shr_sig_abnormal_term(int);
205 static void smb_shr_sig_child(int);
206 static void smb_shr_get_exec_info(void);
207 static void smb_shr_set_exec_flags(smb_share_t *);
208 
209 /*
210  * libshare handle and synchronization
211  */
212 typedef struct smb_sa_handle {
213 	sa_handle_t	sa_handle;
214 	mutex_t		sa_mtx;
215 	boolean_t	sa_in_service;
216 } smb_sa_handle_t;
217 
218 static smb_sa_handle_t smb_sa_handle;
219 
220 static int smb_shr_exec_flags;
221 static char smb_shr_exec_map[MAXPATHLEN];
222 static char smb_shr_exec_unmap[MAXPATHLEN];
223 static mutex_t smb_shr_exec_mtx;
224 
225 /*
226  * Semaphore held during temporary, process-wide changes
227  * such as process privileges.  It is a seamaphore and
228  * not a mutex so a child of fork can reset it.
229  */
230 static sema_t smb_proc_sem = DEFAULTSEMA;
231 
232 /*
233  * Creates and initializes the cache and starts the publisher
234  * thread.
235  */
236 int
237 smb_shr_start(void)
238 {
239 	smb_transient_t	*ts;
240 	uint32_t	nerr;
241 	int		i;
242 
243 	(void) mutex_lock(&smb_sa_handle.sa_mtx);
244 	smb_sa_handle.sa_in_service = B_TRUE;
245 	(void) mutex_unlock(&smb_sa_handle.sa_mtx);
246 
247 	if (smb_shr_cache_create() != NERR_Success)
248 		return (ENOMEM);
249 
250 	for (i = 0; i < sizeof (tshare)/sizeof (tshare[0]); ++i) {
251 		ts = &tshare[i];
252 
253 		if (ts->check && smb_shr_is_empty(ts->path))
254 			continue;
255 
256 		nerr = smb_shr_add_transient(ts->name, ts->cmnt, ts->path);
257 		if (nerr != NERR_Success)
258 			return (ENOMEM);
259 	}
260 
261 	return (smb_shr_publisher_start());
262 }
263 
264 void
265 smb_shr_stop(void)
266 {
267 	smb_shr_cache_destroy();
268 	smb_shr_publisher_stop();
269 
270 	(void) mutex_lock(&smb_sa_handle.sa_mtx);
271 	smb_sa_handle.sa_in_service = B_FALSE;
272 
273 	if (smb_sa_handle.sa_handle != NULL) {
274 		sa_fini(smb_sa_handle.sa_handle);
275 		smb_sa_handle.sa_handle = NULL;
276 	}
277 
278 	(void) mutex_unlock(&smb_sa_handle.sa_mtx);
279 }
280 
281 /*
282  * Get a handle and exclusive access to the libshare API.
283  */
284 sa_handle_t
285 smb_shr_sa_enter(void)
286 {
287 	(void) mutex_lock(&smb_sa_handle.sa_mtx);
288 	if (!smb_sa_handle.sa_in_service) {
289 		(void) mutex_unlock(&smb_sa_handle.sa_mtx);
290 		return (NULL);
291 	}
292 
293 	if (smb_sa_handle.sa_handle == NULL) {
294 		smb_sa_handle.sa_handle = sa_init(SA_INIT_SHARE_API);
295 		if (smb_sa_handle.sa_handle == NULL) {
296 			syslog(LOG_ERR, "share: failed to get libshare handle");
297 			(void) mutex_unlock(&smb_sa_handle.sa_mtx);
298 			return (NULL);
299 		}
300 	}
301 
302 	return (smb_sa_handle.sa_handle);
303 }
304 
305 /*
306  * Release exclusive access to the libshare API.
307  */
308 void
309 smb_shr_sa_exit(void)
310 {
311 	(void) mutex_unlock(&smb_sa_handle.sa_mtx);
312 }
313 
314 /*
315  * Launches a thread to populate the share cache by share information
316  * stored in sharemgr
317  */
318 int
319 smb_shr_load(void)
320 {
321 	pthread_t load_thr;
322 	pthread_attr_t tattr;
323 	int rc;
324 
325 	(void) pthread_attr_init(&tattr);
326 	(void) pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
327 	rc = pthread_create(&load_thr, &tattr, smb_shr_sa_loadall, 0);
328 	(void) pthread_attr_destroy(&tattr);
329 
330 	smb_shr_get_exec_info();
331 
332 	return (rc);
333 }
334 
335 /*
336  * Return the total number of shares
337  */
338 int
339 smb_shr_count(void)
340 {
341 	int n_shares = 0;
342 
343 	if (smb_shr_cache_lock(SMB_SHR_CACHE_RDLOCK) == NERR_Success) {
344 		n_shares = smb_shr_cache_count();
345 		smb_shr_cache_unlock();
346 	}
347 
348 	return (n_shares);
349 }
350 
351 /*
352  * smb_shr_iterinit
353  *
354  * Initialize given iterator for traversing hash table.
355  */
356 void
357 smb_shr_iterinit(smb_shriter_t *shi)
358 {
359 	bzero(shi, sizeof (smb_shriter_t));
360 	shi->si_first = B_TRUE;
361 }
362 
363 /*
364  * smb_shr_iterate
365  *
366  * Iterate on the shares in the hash table. The iterator must be initialized
367  * before the first iteration. On subsequent calls, the iterator must be
368  * passed unchanged.
369  *
370  * Returns NULL on failure or when all shares are visited, otherwise
371  * returns information of visited share.
372  */
373 smb_share_t *
374 smb_shr_iterate(smb_shriter_t *shi)
375 {
376 	smb_share_t *share = NULL;
377 	smb_share_t *cached_si;
378 
379 	if (shi == NULL)
380 		return (NULL);
381 
382 	if (smb_shr_cache_lock(SMB_SHR_CACHE_RDLOCK) == NERR_Success) {
383 		if ((cached_si = smb_shr_cache_iterate(shi)) != NULL) {
384 			share = &shi->si_share;
385 			bcopy(cached_si, share, sizeof (smb_share_t));
386 			smb_shr_set_exec_flags(share);
387 		}
388 		smb_shr_cache_unlock();
389 	}
390 
391 	return (share);
392 }
393 
394 /*
395  * Adds the given share to cache, publishes the share in ADS
396  * if it has an AD container, calls kernel to take a hold on
397  * the shared file system. If it can't take a hold on the
398  * shared file system, it's either because shared directory
399  * does not exist or some other error has occurred, in any
400  * case the share is removed from the cache.
401  *
402  * If the specified share is an autohome share which already
403  * exists in the cache, just increments the reference count.
404  */
405 uint32_t
406 smb_shr_add(smb_share_t *si)
407 {
408 	smb_share_t *cached_si;
409 	uint32_t status;
410 	int rc;
411 
412 	assert(si != NULL);
413 
414 	if (smb_name_validate_share(si->shr_name) != ERROR_SUCCESS)
415 		return (ERROR_INVALID_NAME);
416 
417 	if (smb_shr_cache_lock(SMB_SHR_CACHE_WRLOCK) != NERR_Success)
418 		return (NERR_InternalError);
419 
420 	cached_si = smb_shr_cache_findent(si->shr_name);
421 	if (cached_si) {
422 		if (si->shr_flags & SMB_SHRF_AUTOHOME) {
423 			cached_si->shr_refcnt++;
424 			status = NERR_Success;
425 		} else {
426 			status = NERR_DuplicateShare;
427 		}
428 		smb_shr_cache_unlock();
429 		return (status);
430 	}
431 
432 	if ((status = smb_shr_cache_addent(si)) != NERR_Success) {
433 		smb_shr_cache_unlock();
434 		return (status);
435 	}
436 
437 	/* don't hold the lock across door call */
438 	smb_shr_cache_unlock();
439 
440 	/* call kernel to take a hold on the shared file system */
441 	rc = smb_kmod_share(si->shr_path, si->shr_name);
442 
443 	if (rc == 0) {
444 		smb_shr_publish(si->shr_name, si->shr_container);
445 
446 		/* If path is ZFS, add the .zfs/shares/<share> entry. */
447 		smb_shr_zfs_add(si);
448 
449 		return (NERR_Success);
450 	}
451 
452 	if (smb_shr_cache_lock(SMB_SHR_CACHE_WRLOCK) == NERR_Success) {
453 		smb_shr_cache_delent(si->shr_name);
454 		smb_shr_cache_unlock();
455 	}
456 
457 	/*
458 	 * rc == ENOENT means the shared directory doesn't exist
459 	 */
460 	return ((rc == ENOENT) ? NERR_UnknownDevDir : NERR_InternalError);
461 }
462 
463 /*
464  * Removes the specified share from cache, removes it from AD
465  * if it has an AD container, and calls the kernel to release
466  * the hold on the shared file system.
467  *
468  * If this is an autohome share then decrement the reference
469  * count. If it reaches 0 then it proceeds with removing steps.
470  */
471 uint32_t
472 smb_shr_remove(char *sharename)
473 {
474 	smb_share_t *si;
475 	char path[MAXPATHLEN];
476 	char container[MAXPATHLEN];
477 	boolean_t dfsroot;
478 
479 	assert(sharename != NULL);
480 
481 	if (smb_name_validate_share(sharename) != ERROR_SUCCESS)
482 		return (ERROR_INVALID_NAME);
483 
484 	if (smb_shr_cache_lock(SMB_SHR_CACHE_WRLOCK) != NERR_Success)
485 		return (NERR_InternalError);
486 
487 	if ((si = smb_shr_cache_findent(sharename)) == NULL) {
488 		smb_shr_cache_unlock();
489 		return (NERR_NetNameNotFound);
490 	}
491 
492 	if (si->shr_type & STYPE_IPC) {
493 		/* IPC$ share cannot be removed */
494 		smb_shr_cache_unlock();
495 		return (ERROR_ACCESS_DENIED);
496 	}
497 
498 	if (si->shr_flags & SMB_SHRF_AUTOHOME) {
499 		if ((--si->shr_refcnt) > 0) {
500 			smb_shr_cache_unlock();
501 			return (NERR_Success);
502 		}
503 	}
504 
505 	/*
506 	 * If path is ZFS, remove the .zfs/shares/<share> entry.  Need
507 	 * to remove before cleanup of cache occurs.
508 	 */
509 	smb_shr_zfs_remove(si);
510 
511 	(void) strlcpy(path, si->shr_path, sizeof (path));
512 	(void) strlcpy(container, si->shr_container, sizeof (container));
513 	dfsroot = ((si->shr_flags & SMB_SHRF_DFSROOT) != 0);
514 	smb_shr_cache_delent(sharename);
515 	smb_shr_cache_unlock();
516 
517 	smb_shr_unpublish(sharename, container);
518 
519 	/* call kernel to release the hold on the shared file system */
520 	(void) smb_kmod_unshare(path, sharename);
521 
522 	if (dfsroot)
523 		dfs_namespace_unload(sharename);
524 
525 	return (NERR_Success);
526 }
527 
528 /*
529  * Rename a share. Check that the current name exists and the new name
530  * doesn't exist. The rename is performed by deleting the current share
531  * definition and creating a new share with the new name.
532  */
533 uint32_t
534 smb_shr_rename(char *from_name, char *to_name)
535 {
536 	smb_share_t *from_si;
537 	smb_share_t to_si;
538 	uint32_t status;
539 
540 	assert((from_name != NULL) && (to_name != NULL));
541 
542 	if (smb_name_validate_share(from_name) != ERROR_SUCCESS ||
543 	    smb_name_validate_share(to_name) != ERROR_SUCCESS)
544 		return (ERROR_INVALID_NAME);
545 
546 	if (smb_shr_cache_lock(SMB_SHR_CACHE_WRLOCK) != NERR_Success)
547 		return (NERR_InternalError);
548 
549 	if ((from_si = smb_shr_cache_findent(from_name)) == NULL) {
550 		smb_shr_cache_unlock();
551 		return (NERR_NetNameNotFound);
552 	}
553 
554 	if (from_si->shr_type & STYPE_IPC) {
555 		/* IPC$ share cannot be renamed */
556 		smb_shr_cache_unlock();
557 		return (ERROR_ACCESS_DENIED);
558 	}
559 
560 	if (smb_shr_cache_findent(to_name) != NULL) {
561 		smb_shr_cache_unlock();
562 		return (NERR_DuplicateShare);
563 	}
564 
565 	bcopy(from_si, &to_si, sizeof (smb_share_t));
566 	(void) strlcpy(to_si.shr_name, to_name, sizeof (to_si.shr_name));
567 
568 	/* If path is ZFS, rename the .zfs/shares/<share> entry. */
569 	smb_shr_zfs_rename(from_si, &to_si);
570 
571 	if ((status = smb_shr_cache_addent(&to_si)) != NERR_Success) {
572 		smb_shr_cache_unlock();
573 		return (status);
574 	}
575 
576 	smb_shr_cache_delent(from_name);
577 	smb_shr_cache_unlock();
578 
579 	smb_shr_unpublish(from_name, to_si.shr_container);
580 	smb_shr_publish(to_name, to_si.shr_container);
581 
582 	return (NERR_Success);
583 }
584 
585 /*
586  * Load the information for the specified share into the supplied share
587  * info structure.
588  *
589  * First looks up the cache to see if the specified share exists, if there
590  * is a miss then it looks up sharemgr.
591  */
592 uint32_t
593 smb_shr_get(char *sharename, smb_share_t *si)
594 {
595 	uint32_t status;
596 
597 	if (sharename == NULL || *sharename == '\0')
598 		return (NERR_NetNameNotFound);
599 
600 	if ((status = smb_shr_lookup(sharename, si)) == NERR_Success)
601 		return (status);
602 
603 	if ((status = smb_shr_sa_loadbyname(sharename)) == NERR_Success)
604 		status = smb_shr_lookup(sharename, si);
605 
606 	return (status);
607 }
608 
609 /*
610  * Modifies an existing share. Properties that can be modified are:
611  *
612  *   o comment
613  *   o AD container
614  *   o host access
615  *   o abe
616  */
617 uint32_t
618 smb_shr_modify(smb_share_t *new_si)
619 {
620 	smb_share_t *si;
621 	boolean_t adc_changed = B_FALSE;
622 	char old_container[MAXPATHLEN];
623 	uint32_t access, flag;
624 
625 	assert(new_si != NULL);
626 
627 	if (smb_shr_cache_lock(SMB_SHR_CACHE_WRLOCK) != NERR_Success)
628 		return (NERR_InternalError);
629 
630 	if ((si = smb_shr_cache_findent(new_si->shr_name)) == NULL) {
631 		smb_shr_cache_unlock();
632 		return (NERR_NetNameNotFound);
633 	}
634 
635 	if (si->shr_type & STYPE_IPC) {
636 		/* IPC$ share cannot be modified */
637 		smb_shr_cache_unlock();
638 		return (ERROR_ACCESS_DENIED);
639 	}
640 
641 	(void) strlcpy(si->shr_cmnt, new_si->shr_cmnt, sizeof (si->shr_cmnt));
642 
643 	adc_changed = (strcmp(new_si->shr_container, si->shr_container) != 0);
644 	if (adc_changed) {
645 		/* save current container - needed for unpublishing */
646 		(void) strlcpy(old_container, si->shr_container,
647 		    sizeof (old_container));
648 		(void) strlcpy(si->shr_container, new_si->shr_container,
649 		    sizeof (si->shr_container));
650 	}
651 
652 	flag = (new_si->shr_flags & SMB_SHRF_ABE);
653 	si->shr_flags &= ~SMB_SHRF_ABE;
654 	si->shr_flags |= flag;
655 
656 	flag = (new_si->shr_flags & SMB_SHRF_CATIA);
657 	si->shr_flags &= ~SMB_SHRF_CATIA;
658 	si->shr_flags |= flag;
659 
660 	flag = (new_si->shr_flags & SMB_SHRF_GUEST_OK);
661 	si->shr_flags &= ~SMB_SHRF_GUEST_OK;
662 	si->shr_flags |= flag;
663 
664 	flag = (new_si->shr_flags & SMB_SHRF_DFSROOT);
665 	si->shr_flags &= ~SMB_SHRF_DFSROOT;
666 	si->shr_flags |= flag;
667 
668 	flag = (new_si->shr_flags & SMB_SHRF_CSC_MASK);
669 	si->shr_flags &= ~SMB_SHRF_CSC_MASK;
670 	si->shr_flags |= flag;
671 
672 	access = (new_si->shr_flags & SMB_SHRF_ACC_ALL);
673 	si->shr_flags &= ~SMB_SHRF_ACC_ALL;
674 	si->shr_flags |= access;
675 
676 	if (access & SMB_SHRF_ACC_NONE)
677 		(void) strlcpy(si->shr_access_none, new_si->shr_access_none,
678 		    sizeof (si->shr_access_none));
679 
680 	if (access & SMB_SHRF_ACC_RO)
681 		(void) strlcpy(si->shr_access_ro, new_si->shr_access_ro,
682 		    sizeof (si->shr_access_ro));
683 
684 	if (access & SMB_SHRF_ACC_RW)
685 		(void) strlcpy(si->shr_access_rw, new_si->shr_access_rw,
686 		    sizeof (si->shr_access_rw));
687 
688 	smb_shr_cache_unlock();
689 
690 	if (adc_changed) {
691 		smb_shr_unpublish(new_si->shr_name, old_container);
692 		smb_shr_publish(new_si->shr_name, new_si->shr_container);
693 	}
694 
695 	return (NERR_Success);
696 }
697 
698 /*
699  * smb_shr_exists
700  *
701  * Returns B_TRUE if the share exists. Otherwise returns B_FALSE
702  */
703 boolean_t
704 smb_shr_exists(char *sharename)
705 {
706 	boolean_t exists = B_FALSE;
707 
708 	if (sharename == NULL || *sharename == '\0')
709 		return (B_FALSE);
710 
711 	if (smb_shr_cache_lock(SMB_SHR_CACHE_RDLOCK) == NERR_Success) {
712 		exists = (smb_shr_cache_findent(sharename) != NULL);
713 		smb_shr_cache_unlock();
714 	}
715 
716 	return (exists);
717 }
718 
719 /*
720  * If the shared directory does not begin with a /, one will be
721  * inserted as a prefix. If ipaddr is not zero, then also return
722  * information about access based on the host level access lists, if
723  * present. Also return access check if there is an IP address and
724  * shr_accflags.
725  *
726  * The value of smb_chk_hostaccess is checked for an access match.
727  * -1 is wildcard match
728  * 0 is no match
729  * 1 is match
730  *
731  * Precedence is none is checked first followed by ro then rw if
732  * needed.  If x is wildcard (< 0) then check to see if the other
733  * values are a match. If a match, that wins.
734  *
735  * ipv6 is wide open for now, see smb_chk_hostaccess
736  */
737 void
738 smb_shr_hostaccess(smb_share_t *si, smb_inaddr_t *ipaddr)
739 {
740 	int acc = SMB_SHRF_ACC_OPEN;
741 
742 	/*
743 	 * Check to see if there area any share level access
744 	 * restrictions.
745 	 */
746 	if ((!smb_inet_iszero(ipaddr)) &&
747 	    (si->shr_flags & SMB_SHRF_ACC_ALL) != 0) {
748 		int none = SMB_SHRF_ACC_OPEN;
749 		int rw = SMB_SHRF_ACC_OPEN;
750 		int ro = SMB_SHRF_ACC_OPEN;
751 
752 		if (si->shr_flags & SMB_SHRF_ACC_NONE)
753 			none = smb_chk_hostaccess(ipaddr, si->shr_access_none);
754 		if (si->shr_flags & SMB_SHRF_ACC_RW)
755 			rw = smb_chk_hostaccess(ipaddr, si->shr_access_rw);
756 		if (si->shr_flags & SMB_SHRF_ACC_RO)
757 			ro = smb_chk_hostaccess(ipaddr, si->shr_access_ro);
758 		/* make first pass to get basic value */
759 		if (none != 0)
760 			acc = SMB_SHRF_ACC_NONE;
761 		else if (ro != 0)
762 			acc = SMB_SHRF_ACC_RO;
763 		else if (rw != 0)
764 			acc = SMB_SHRF_ACC_RW;
765 
766 		/* make second pass to handle '*' case */
767 		if (none < 0) {
768 			acc = SMB_SHRF_ACC_NONE;
769 			if (ro > 0)
770 				acc = SMB_SHRF_ACC_RO;
771 			else if (rw > 0)
772 				acc = SMB_SHRF_ACC_RW;
773 		} else if (ro < 0) {
774 			acc = SMB_SHRF_ACC_RO;
775 			if (none > 0)
776 				acc = SMB_SHRF_ACC_NONE;
777 			else if (rw > 0)
778 				acc = SMB_SHRF_ACC_RW;
779 		} else if (rw < 0) {
780 			acc = SMB_SHRF_ACC_RW;
781 			if (none > 0)
782 				acc = SMB_SHRF_ACC_NONE;
783 			else if (ro > 0)
784 				acc = SMB_SHRF_ACC_RO;
785 		}
786 	}
787 	si->shr_access_value = acc;	/* return access here */
788 }
789 
790 /*
791  * smb_shr_is_special
792  *
793  * Special share reserved for interprocess communication (IPC$) or
794  * remote administration of the server (ADMIN$). Can also refer to
795  * administrative shares such as C$, D$, E$, and so forth.
796  */
797 int
798 smb_shr_is_special(char *sharename)
799 {
800 	int len;
801 
802 	if (sharename == NULL)
803 		return (0);
804 
805 	if ((len = strlen(sharename)) == 0)
806 		return (0);
807 
808 	if (sharename[len - 1] == '$')
809 		return (STYPE_SPECIAL);
810 
811 	return (0);
812 }
813 
814 /*
815  * smb_shr_is_restricted
816  *
817  * Check whether or not there is a restriction on a share. Restricted
818  * shares are generally STYPE_SPECIAL, for example, IPC$. All the
819  * administration share names are restricted: C$, D$ etc. Returns B_TRUE
820  * if the share is restricted. Otherwise B_FALSE is returned to indicate
821  * that there are no restrictions.
822  */
823 boolean_t
824 smb_shr_is_restricted(char *sharename)
825 {
826 	static char *restricted[] = {
827 		"IPC$"
828 	};
829 
830 	int i;
831 
832 	if (sharename == NULL)
833 		return (B_FALSE);
834 
835 	for (i = 0; i < sizeof (restricted)/sizeof (restricted[0]); i++) {
836 		if (smb_strcasecmp(restricted[i], sharename, 0) == 0)
837 			return (B_TRUE);
838 	}
839 
840 	return (smb_shr_is_admin(sharename));
841 }
842 
843 /*
844  * smb_shr_is_admin
845  *
846  * Check whether or not access to the share should be restricted to
847  * administrators. This is a bit of a hack because what we're doing
848  * is checking for the default admin shares: C$, D$ etc.. There are
849  * other shares that have restrictions: see smb_shr_is_restricted().
850  *
851  * Returns B_TRUE if the shares is an admin share. Otherwise B_FALSE
852  * is returned to indicate that there are no restrictions.
853  */
854 boolean_t
855 smb_shr_is_admin(char *sharename)
856 {
857 	if (sharename == NULL)
858 		return (B_FALSE);
859 
860 	if (strlen(sharename) == 2 &&
861 	    smb_isalpha(sharename[0]) && sharename[1] == '$') {
862 		return (B_TRUE);
863 	}
864 
865 	return (B_FALSE);
866 }
867 
868 char
869 smb_shr_drive_letter(const char *path)
870 {
871 	smb_transient_t	*ts;
872 	int i;
873 
874 	if (path == NULL)
875 		return ('\0');
876 
877 	for (i = 0; i < sizeof (tshare)/sizeof (tshare[0]); ++i) {
878 		ts = &tshare[i];
879 
880 		if (ts->path == NULL)
881 			continue;
882 
883 		if (strcasecmp(ts->path, path) == 0)
884 			return (ts->drive);
885 	}
886 
887 	return ('\0');
888 }
889 
890 /*
891  * Returns true if the specified directory is empty,
892  * otherwise returns false.
893  */
894 static boolean_t
895 smb_shr_is_empty(const char *path)
896 {
897 	DIR *dirp;
898 	struct dirent *dp;
899 
900 	if (path == NULL)
901 		return (B_TRUE);
902 
903 	if ((dirp = opendir(path)) == NULL)
904 		return (B_TRUE);
905 
906 	while ((dp = readdir(dirp)) != NULL) {
907 		if (!smb_shr_is_dot_or_dotdot(dp->d_name))
908 			return (B_FALSE);
909 	}
910 
911 	(void) closedir(dirp);
912 	return (B_TRUE);
913 }
914 
915 /*
916  * Returns true if name is "." or "..", otherwise returns false.
917  */
918 static boolean_t
919 smb_shr_is_dot_or_dotdot(const char *name)
920 {
921 	if (*name != '.')
922 		return (B_FALSE);
923 
924 	if ((name[1] == '\0') || (name[1] == '.' && name[2] == '\0'))
925 		return (B_TRUE);
926 
927 	return (B_FALSE);
928 }
929 
930 /*
931  * smb_shr_get_realpath
932  *
933  * Derive the real path for a share from the path provided by a client.
934  * For instance, the real path of C:\ may be /cvol or the real path of
935  * F:\home may be /vol1/home.
936  *
937  * clntpath - path provided by the Windows client is in the
938  *            format of <drive letter>:\<dir>
939  * realpath - path that will be stored as the directory field of
940  *            the smb_share_t structure of the share.
941  * maxlen   - maximum length of the realpath buffer
942  *
943  * Return LAN Manager network error code.
944  */
945 uint32_t
946 smb_shr_get_realpath(const char *clntpath, char *realpath, int maxlen)
947 {
948 	const char *p;
949 	int len;
950 
951 	if ((p = strchr(clntpath, ':')) != NULL)
952 		++p;
953 	else
954 		p = clntpath;
955 
956 	(void) strlcpy(realpath, p, maxlen);
957 	(void) strcanon(realpath, "/\\");
958 	(void) strsubst(realpath, '\\', '/');
959 
960 	len = strlen(realpath);
961 	if ((len > 1) && (realpath[len - 1] == '/'))
962 		realpath[len - 1] = '\0';
963 
964 	return (NERR_Success);
965 }
966 
967 void
968 smb_shr_list(int offset, smb_shrlist_t *list)
969 {
970 	smb_shriter_t iterator;
971 	smb_share_t *si;
972 	int n = 0;
973 
974 	bzero(list, sizeof (smb_shrlist_t));
975 	smb_shr_iterinit(&iterator);
976 
977 	while ((si = smb_shr_iterate(&iterator)) != NULL) {
978 		if (--offset > 0)
979 			continue;
980 
981 		if ((si->shr_flags & SMB_SHRF_TRANS) &&
982 		    ((si->shr_type & STYPE_IPC) == 0)) {
983 			bcopy(si, &list->sl_shares[n], sizeof (smb_share_t));
984 			if (++n == LMSHARES_PER_REQUEST)
985 				break;
986 		}
987 	}
988 
989 	list->sl_cnt = n;
990 }
991 
992 /*
993  * Executes the map/unmap command associated with a share.
994  *
995  * Returns 0 on success.  Otherwise non-zero for errors.
996  */
997 int
998 smb_shr_exec(char *share, smb_execsub_info_t *subs, int exec_type)
999 {
1000 	char cmd[MAXPATHLEN], **cmd_tokens, *path, *ptr;
1001 	pid_t child_pid;
1002 	int child_status;
1003 	struct sigaction pact, cact;
1004 	smb_share_t si;
1005 
1006 	if (smb_shr_get(share, &si) != 0)
1007 		return (-1);
1008 
1009 	*cmd = '\0';
1010 
1011 	(void) mutex_lock(&smb_shr_exec_mtx);
1012 
1013 	switch (exec_type) {
1014 	case SMB_SHR_MAP:
1015 		(void) strlcpy(cmd, smb_shr_exec_map, sizeof (cmd));
1016 		break;
1017 	case SMB_SHR_UNMAP:
1018 		(void) strlcpy(cmd, smb_shr_exec_unmap, sizeof (cmd));
1019 		break;
1020 	default:
1021 		(void) mutex_unlock(&smb_shr_exec_mtx);
1022 		return (-1);
1023 	}
1024 
1025 	(void) mutex_unlock(&smb_shr_exec_mtx);
1026 
1027 	if (*cmd == '\0')
1028 		return (0);
1029 
1030 	if (smb_proc_takesem() != 0)
1031 		return (-1);
1032 
1033 	pact.sa_handler = smb_shr_sig_child;
1034 	pact.sa_flags = 0;
1035 	(void) sigemptyset(&pact.sa_mask);
1036 	sigaction(SIGCHLD, &pact, NULL);
1037 
1038 	(void) priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_PROC_FORK, NULL);
1039 
1040 	if ((child_pid = fork()) == -1) {
1041 		(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_PROC_FORK, NULL);
1042 		smb_proc_givesem();
1043 		return (-1);
1044 	}
1045 
1046 	if (child_pid == 0) {
1047 
1048 		/* child process */
1049 
1050 		cact.sa_handler = smb_shr_sig_abnormal_term;
1051 		cact.sa_flags = 0;
1052 		(void) sigemptyset(&cact.sa_mask);
1053 		sigaction(SIGTERM, &cact, NULL);
1054 		sigaction(SIGABRT, &cact, NULL);
1055 		sigaction(SIGSEGV, &cact, NULL);
1056 
1057 		if (priv_set(PRIV_ON, PRIV_EFFECTIVE, PRIV_PROC_EXEC,
1058 		    PRIV_FILE_DAC_EXECUTE, NULL))
1059 			_exit(-1);
1060 
1061 		if (smb_shr_enable_all_privs())
1062 			_exit(-1);
1063 
1064 		smb_proc_initsem();
1065 
1066 		(void) trim_whitespace(cmd);
1067 		(void) strcanon(cmd, " ");
1068 
1069 		if ((cmd_tokens = smb_shr_tokenize_cmd(cmd)) != NULL) {
1070 
1071 			if (smb_shr_expand_subs(cmd_tokens, &si, subs) != 0) {
1072 				free(cmd_tokens[0]);
1073 				free(cmd_tokens);
1074 				_exit(-1);
1075 			}
1076 
1077 			ptr = cmd;
1078 			path = strsep(&ptr, " ");
1079 
1080 			(void) execv(path, cmd_tokens);
1081 		}
1082 
1083 		_exit(-1);
1084 	}
1085 
1086 	(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_PROC_FORK, NULL);
1087 	smb_proc_givesem();
1088 
1089 	/* parent process */
1090 
1091 	while (waitpid(child_pid, &child_status, 0) < 0) {
1092 		if (errno != EINTR)
1093 			break;
1094 
1095 		/* continue if waitpid got interrupted by a signal */
1096 		errno = 0;
1097 		continue;
1098 	}
1099 
1100 	if (WIFEXITED(child_status))
1101 		return (WEXITSTATUS(child_status));
1102 
1103 	return (child_status);
1104 }
1105 
1106 /*
1107  * Locking for process-wide settings (i.e. privileges)
1108  */
1109 void
1110 smb_proc_initsem(void)
1111 {
1112 	(void) sema_init(&smb_proc_sem, 1, USYNC_THREAD, NULL);
1113 }
1114 
1115 int
1116 smb_proc_takesem(void)
1117 {
1118 	return (sema_wait(&smb_proc_sem));
1119 }
1120 
1121 void
1122 smb_proc_givesem(void)
1123 {
1124 	(void) sema_post(&smb_proc_sem);
1125 }
1126 
1127 /*
1128  * ============================================
1129  * Private helper/utility functions
1130  * ============================================
1131  */
1132 
1133 /*
1134  * Looks up the given share in the cache and return
1135  * the info in 'si'
1136  */
1137 static uint32_t
1138 smb_shr_lookup(char *sharename, smb_share_t *si)
1139 {
1140 	smb_share_t *cached_si;
1141 	uint32_t status = NERR_NetNameNotFound;
1142 
1143 	if (sharename == NULL || *sharename == '\0')
1144 		return (NERR_NetNameNotFound);
1145 	if (smb_shr_cache_lock(SMB_SHR_CACHE_RDLOCK) == NERR_Success) {
1146 		cached_si = smb_shr_cache_findent(sharename);
1147 		if (cached_si != NULL) {
1148 			bcopy(cached_si, si, sizeof (smb_share_t));
1149 			smb_shr_set_exec_flags(si);
1150 			status = NERR_Success;
1151 		}
1152 
1153 		smb_shr_cache_unlock();
1154 	}
1155 	return (status);
1156 }
1157 
1158 /*
1159  * Add IPC$ or Admin shares to the cache upon startup.
1160  */
1161 static uint32_t
1162 smb_shr_add_transient(char *name, char *cmnt, char *path)
1163 {
1164 	smb_share_t trans;
1165 	uint32_t status = NERR_InternalError;
1166 
1167 	if (name == NULL)
1168 		return (status);
1169 
1170 	bzero(&trans, sizeof (smb_share_t));
1171 	(void) strlcpy(trans.shr_name, name, MAXNAMELEN);
1172 	if (cmnt)
1173 		(void) strlcpy(trans.shr_cmnt, cmnt, SMB_SHARE_CMNT_MAX);
1174 
1175 	if (path)
1176 		(void) strlcpy(trans.shr_path, path, MAXPATHLEN);
1177 
1178 	if (strcasecmp(name, "IPC$") == 0)
1179 		trans.shr_type = STYPE_IPC;
1180 
1181 	trans.shr_flags = SMB_SHRF_TRANS;
1182 
1183 	if (smb_shr_cache_lock(SMB_SHR_CACHE_WRLOCK) == NERR_Success) {
1184 		status = smb_shr_cache_addent(&trans);
1185 		smb_shr_cache_unlock();
1186 	}
1187 
1188 	return (status);
1189 }
1190 
1191 /*
1192  * smb_shr_set_oemname
1193  *
1194  * Generate the OEM name for the specified share.  If the name is
1195  * shorter than 13 bytes the oemname will be saved in si->shr_oemname.
1196  * Otherwise si->shr_oemname will be empty and SMB_SHRF_LONGNAME will
1197  * be set in si->shr_flags.
1198  */
1199 static void
1200 smb_shr_set_oemname(smb_share_t *si)
1201 {
1202 	smb_wchar_t *unibuf;
1203 	char *oem_name;
1204 	int length;
1205 
1206 	length = strlen(si->shr_name) + 1;
1207 
1208 	oem_name = malloc(length);
1209 	unibuf = malloc(length * sizeof (smb_wchar_t));
1210 	if ((oem_name == NULL) || (unibuf == NULL)) {
1211 		free(oem_name);
1212 		free(unibuf);
1213 		return;
1214 	}
1215 
1216 	(void) smb_mbstowcs(unibuf, si->shr_name, length);
1217 
1218 	if (ucstooem(oem_name, unibuf, length, OEM_CPG_850) == 0)
1219 		(void) strcpy(oem_name, si->shr_name);
1220 
1221 	free(unibuf);
1222 
1223 	if (strlen(oem_name) + 1 > SMB_SHARE_OEMNAME_MAX) {
1224 		si->shr_flags |= SMB_SHRF_LONGNAME;
1225 		*si->shr_oemname = '\0';
1226 	} else {
1227 		si->shr_flags &= ~SMB_SHRF_LONGNAME;
1228 		(void) strlcpy(si->shr_oemname, oem_name,
1229 		    SMB_SHARE_OEMNAME_MAX);
1230 	}
1231 
1232 	free(oem_name);
1233 }
1234 
1235 /*
1236  * ============================================
1237  * Cache management functions
1238  *
1239  * All cache functions are private
1240  * ============================================
1241  */
1242 
1243 /*
1244  * Create the share cache (hash table).
1245  */
1246 static uint32_t
1247 smb_shr_cache_create(void)
1248 {
1249 	uint32_t status = NERR_Success;
1250 
1251 	(void) mutex_lock(&smb_shr_cache.sc_mtx);
1252 	switch (smb_shr_cache.sc_state) {
1253 	case SMB_SHR_CACHE_STATE_NONE:
1254 		smb_shr_cache.sc_cache = ht_create_table(SMB_SHR_HTAB_SZ,
1255 		    MAXNAMELEN, 0);
1256 		if (smb_shr_cache.sc_cache == NULL) {
1257 			status = NERR_InternalError;
1258 			break;
1259 		}
1260 
1261 		(void) ht_register_callback(smb_shr_cache.sc_cache,
1262 		    smb_shr_cache_freent);
1263 		smb_shr_cache.sc_nops = 0;
1264 		smb_shr_cache.sc_state = SMB_SHR_CACHE_STATE_CREATED;
1265 		break;
1266 
1267 	default:
1268 		assert(0);
1269 		status = NERR_InternalError;
1270 		break;
1271 	}
1272 	(void) mutex_unlock(&smb_shr_cache.sc_mtx);
1273 
1274 	return (status);
1275 }
1276 
1277 /*
1278  * Destroy the share cache (hash table).
1279  * Wait for inflight/pending operations to finish or abort before
1280  * destroying the cache.
1281  */
1282 static void
1283 smb_shr_cache_destroy(void)
1284 {
1285 	(void) mutex_lock(&smb_shr_cache.sc_mtx);
1286 	if (smb_shr_cache.sc_state == SMB_SHR_CACHE_STATE_CREATED) {
1287 		smb_shr_cache.sc_state = SMB_SHR_CACHE_STATE_DESTROYING;
1288 		while (smb_shr_cache.sc_nops > 0)
1289 			(void) cond_wait(&smb_shr_cache.sc_cv,
1290 			    &smb_shr_cache.sc_mtx);
1291 
1292 		smb_shr_cache.sc_cache = NULL;
1293 		smb_shr_cache.sc_state = SMB_SHR_CACHE_STATE_NONE;
1294 	}
1295 	(void) mutex_unlock(&smb_shr_cache.sc_mtx);
1296 }
1297 
1298 /*
1299  * If the cache is in "created" state, lock the cache for read
1300  * or read/write based on the specified mode.
1301  *
1302  * Whenever a lock is granted, the number of inflight cache
1303  * operations is incremented.
1304  */
1305 static uint32_t
1306 smb_shr_cache_lock(int mode)
1307 {
1308 	(void) mutex_lock(&smb_shr_cache.sc_mtx);
1309 	if (smb_shr_cache.sc_state != SMB_SHR_CACHE_STATE_CREATED) {
1310 		(void) mutex_unlock(&smb_shr_cache.sc_mtx);
1311 		return (NERR_InternalError);
1312 	}
1313 	smb_shr_cache.sc_nops++;
1314 	(void) mutex_unlock(&smb_shr_cache.sc_mtx);
1315 
1316 	/*
1317 	 * Lock has to be taken outside the mutex otherwise
1318 	 * there could be a deadlock
1319 	 */
1320 	if (mode == SMB_SHR_CACHE_RDLOCK)
1321 		(void) rw_rdlock(&smb_shr_cache.sc_cache_lck);
1322 	else
1323 		(void) rw_wrlock(&smb_shr_cache.sc_cache_lck);
1324 
1325 	return (NERR_Success);
1326 }
1327 
1328 /*
1329  * Decrement the number of inflight operations and then unlock.
1330  */
1331 static void
1332 smb_shr_cache_unlock(void)
1333 {
1334 	(void) mutex_lock(&smb_shr_cache.sc_mtx);
1335 	assert(smb_shr_cache.sc_nops > 0);
1336 	smb_shr_cache.sc_nops--;
1337 	(void) cond_broadcast(&smb_shr_cache.sc_cv);
1338 	(void) mutex_unlock(&smb_shr_cache.sc_mtx);
1339 
1340 	(void) rw_unlock(&smb_shr_cache.sc_cache_lck);
1341 }
1342 
1343 /*
1344  * Return the total number of shares
1345  */
1346 static int
1347 smb_shr_cache_count(void)
1348 {
1349 	return (ht_get_total_items(smb_shr_cache.sc_cache));
1350 }
1351 
1352 /*
1353  * looks up the given share name in the cache and if it
1354  * finds a match returns a pointer to the cached entry.
1355  * Note that since a pointer is returned this function
1356  * MUST be protected by smb_shr_cache_lock/unlock pair
1357  */
1358 static smb_share_t *
1359 smb_shr_cache_findent(char *sharename)
1360 {
1361 	HT_ITEM *item;
1362 
1363 	(void) smb_strlwr(sharename);
1364 	item = ht_find_item(smb_shr_cache.sc_cache, sharename);
1365 	if (item && item->hi_data)
1366 		return ((smb_share_t *)item->hi_data);
1367 
1368 	return (NULL);
1369 }
1370 
1371 /*
1372  * Return a pointer to the first/next entry in
1373  * the cache based on the given iterator.
1374  *
1375  * Calls to this function MUST be protected by
1376  * smb_shr_cache_lock/unlock.
1377  */
1378 static smb_share_t *
1379 smb_shr_cache_iterate(smb_shriter_t *shi)
1380 {
1381 	HT_ITEM *item;
1382 
1383 	if (shi->si_first) {
1384 		item = ht_findfirst(smb_shr_cache.sc_cache, &shi->si_hashiter);
1385 		shi->si_first = B_FALSE;
1386 	} else {
1387 		item = ht_findnext(&shi->si_hashiter);
1388 	}
1389 
1390 	if (item && item->hi_data)
1391 		return ((smb_share_t *)item->hi_data);
1392 
1393 	return (NULL);
1394 }
1395 
1396 /*
1397  * Add the specified share to the cache.  Memory needs to be allocated
1398  * for the cache entry and the passed information is copied to the
1399  * allocated space.
1400  */
1401 static uint32_t
1402 smb_shr_cache_addent(smb_share_t *si)
1403 {
1404 	smb_share_t *cache_ent;
1405 	uint32_t status = NERR_Success;
1406 
1407 	if ((cache_ent = malloc(sizeof (smb_share_t))) == NULL)
1408 		return (ERROR_NOT_ENOUGH_MEMORY);
1409 
1410 	bcopy(si, cache_ent, sizeof (smb_share_t));
1411 
1412 	(void) smb_strlwr(cache_ent->shr_name);
1413 	smb_shr_set_oemname(cache_ent);
1414 
1415 	if ((si->shr_type & STYPE_IPC) == 0)
1416 		cache_ent->shr_type = STYPE_DISKTREE;
1417 	cache_ent->shr_type |= smb_shr_is_special(cache_ent->shr_name);
1418 
1419 	if (smb_shr_is_admin(cache_ent->shr_name))
1420 		cache_ent->shr_flags |= SMB_SHRF_ADMIN;
1421 
1422 	if (si->shr_flags & SMB_SHRF_AUTOHOME)
1423 		cache_ent->shr_refcnt = 1;
1424 
1425 	if (ht_add_item(smb_shr_cache.sc_cache, cache_ent->shr_name, cache_ent)
1426 	    == NULL) {
1427 		syslog(LOG_DEBUG, "share: %s: cache update failed",
1428 		    cache_ent->shr_name);
1429 		free(cache_ent);
1430 		status = NERR_InternalError;
1431 	}
1432 
1433 	return (status);
1434 }
1435 
1436 /*
1437  * Delete the specified share from the cache.
1438  */
1439 static void
1440 smb_shr_cache_delent(char *sharename)
1441 {
1442 	(void) smb_strlwr(sharename);
1443 	(void) ht_remove_item(smb_shr_cache.sc_cache, sharename);
1444 }
1445 
1446 /*
1447  * Call back to free the given cache entry.
1448  */
1449 static void
1450 smb_shr_cache_freent(HT_ITEM *item)
1451 {
1452 	if (item && item->hi_data)
1453 		free(item->hi_data);
1454 }
1455 
1456 /*
1457  * ============================================
1458  * Interfaces to sharemgr
1459  *
1460  * All functions in this section are private
1461  * ============================================
1462  */
1463 
1464 /*
1465  * Load shares from sharemgr
1466  */
1467 /*ARGSUSED*/
1468 static void *
1469 smb_shr_sa_loadall(void *args)
1470 {
1471 	sa_handle_t handle;
1472 	sa_group_t group, subgroup;
1473 	char *gstate;
1474 	boolean_t gdisabled;
1475 
1476 	if ((handle = smb_shr_sa_enter()) == NULL)
1477 		return (NULL);
1478 
1479 	for (group = sa_get_group(handle, NULL);
1480 	    group != NULL; group = sa_get_next_group(group)) {
1481 		gstate = sa_get_group_attr(group, "state");
1482 		if (gstate == NULL)
1483 			continue;
1484 
1485 		gdisabled = (strcasecmp(gstate, "disabled") == 0);
1486 		sa_free_attr_string(gstate);
1487 		if (gdisabled)
1488 			continue;
1489 
1490 		smb_shr_sa_loadgrp(group);
1491 
1492 		for (subgroup = sa_get_sub_group(group);
1493 		    subgroup != NULL;
1494 		    subgroup = sa_get_next_group(subgroup)) {
1495 			smb_shr_sa_loadgrp(subgroup);
1496 		}
1497 
1498 	}
1499 
1500 	smb_shr_sa_exit();
1501 	return (NULL);
1502 }
1503 
1504 /*
1505  * Load the shares contained in the specified group.
1506  *
1507  * Don't process groups on which the smb protocol is disabled.
1508  * The top level ZFS group won't have the smb protocol enabled
1509  * but sub-groups will.
1510  *
1511  * We will tolerate a limited number of errors and then give
1512  * up on the current group.  A typical error might be that the
1513  * shared directory no longer exists.
1514  */
1515 static void
1516 smb_shr_sa_loadgrp(sa_group_t group)
1517 {
1518 	sa_share_t share;
1519 	sa_resource_t resource;
1520 	int error_count = 0;
1521 
1522 	if (sa_get_optionset(group, SMB_PROTOCOL_NAME) == NULL)
1523 		return;
1524 
1525 	for (share = sa_get_share(group, NULL);
1526 	    share != NULL;
1527 	    share = sa_get_next_share(share)) {
1528 		for (resource = sa_get_share_resource(share, NULL);
1529 		    resource != NULL;
1530 		    resource = sa_get_next_resource(resource)) {
1531 			if (smb_shr_sa_load(share, resource))
1532 				++error_count;
1533 
1534 			if (error_count > SMB_SHR_ERROR_THRESHOLD)
1535 				break;
1536 		}
1537 
1538 		if (error_count > SMB_SHR_ERROR_THRESHOLD)
1539 			break;
1540 	}
1541 }
1542 
1543 /*
1544  * Load a share definition from sharemgr and add it to the cache.
1545  * If the share is already in the cache then it doesn't do anything.
1546  *
1547  * This function does not report duplicate shares as error since
1548  * a share might have been added by smb_shr_get() while load is
1549  * in progress.
1550  */
1551 static uint32_t
1552 smb_shr_sa_load(sa_share_t share, sa_resource_t resource)
1553 {
1554 	smb_share_t si;
1555 	char *sharename;
1556 	uint32_t status;
1557 	boolean_t loaded;
1558 
1559 	if ((sharename = sa_get_resource_attr(resource, "name")) == NULL)
1560 		return (NERR_InternalError);
1561 
1562 	loaded = smb_shr_exists(sharename);
1563 	sa_free_attr_string(sharename);
1564 
1565 	if (loaded)
1566 		return (NERR_Success);
1567 
1568 	if ((status = smb_shr_sa_get(share, resource, &si)) != NERR_Success) {
1569 		syslog(LOG_DEBUG, "share: failed to load %s (%d)",
1570 		    si.shr_name, status);
1571 		return (status);
1572 	}
1573 
1574 	status = smb_shr_add(&si);
1575 	if ((status != NERR_Success) && (status != NERR_DuplicateShare)) {
1576 		syslog(LOG_DEBUG, "share: failed to cache %s (%d)",
1577 		    si.shr_name, status);
1578 		return (status);
1579 	}
1580 
1581 	if ((si.shr_flags & SMB_SHRF_DFSROOT) != 0)
1582 		dfs_namespace_load(si.shr_name);
1583 
1584 	return (NERR_Success);
1585 }
1586 
1587 static char *
1588 smb_shr_sa_getprop(sa_optionset_t opts, char *propname)
1589 {
1590 	sa_property_t prop;
1591 	char *val = NULL;
1592 
1593 	prop = sa_get_property(opts, propname);
1594 	if (prop != NULL)
1595 		val = sa_get_property_attr(prop, "value");
1596 
1597 	return (val);
1598 }
1599 
1600 /*
1601  * Read the specified share information from sharemgr and return
1602  * it in the given smb_share_t structure.
1603  *
1604  * Shares read from sharemgr are marked as permanent/persistent.
1605  */
1606 static uint32_t
1607 smb_shr_sa_get(sa_share_t share, sa_resource_t resource, smb_share_t *si)
1608 {
1609 	sa_optionset_t opts;
1610 	char *val = NULL;
1611 	char *path;
1612 	char *rname;
1613 
1614 	if ((path = sa_get_share_attr(share, "path")) == NULL)
1615 		return (NERR_InternalError);
1616 
1617 	if ((rname = sa_get_resource_attr(resource, "name")) == NULL) {
1618 		sa_free_attr_string(path);
1619 		return (NERR_InternalError);
1620 	}
1621 
1622 	bzero(si, sizeof (smb_share_t));
1623 	si->shr_flags = SMB_SHRF_PERM;
1624 
1625 	(void) strlcpy(si->shr_path, path, sizeof (si->shr_path));
1626 	(void) strlcpy(si->shr_name, rname, sizeof (si->shr_name));
1627 	sa_free_attr_string(path);
1628 	sa_free_attr_string(rname);
1629 
1630 	val = sa_get_resource_description(resource);
1631 	if (val == NULL)
1632 		val = sa_get_share_description(share);
1633 
1634 	if (val != NULL) {
1635 		(void) strlcpy(si->shr_cmnt, val, sizeof (si->shr_cmnt));
1636 		sa_free_share_description(val);
1637 	}
1638 
1639 	opts = sa_get_derived_optionset(resource, SMB_PROTOCOL_NAME, 1);
1640 	if (opts == NULL)
1641 		return (NERR_Success);
1642 
1643 	val = smb_shr_sa_getprop(opts, SHOPT_AD_CONTAINER);
1644 	if (val != NULL) {
1645 		(void) strlcpy(si->shr_container, val,
1646 		    sizeof (si->shr_container));
1647 		free(val);
1648 	}
1649 
1650 	val = smb_shr_sa_getprop(opts, SHOPT_CATIA);
1651 	if (val != NULL) {
1652 		smb_shr_sa_setflag(val, si, SMB_SHRF_CATIA);
1653 		free(val);
1654 	}
1655 
1656 	val = smb_shr_sa_getprop(opts, SHOPT_ABE);
1657 	if (val != NULL) {
1658 		smb_shr_sa_setflag(val, si, SMB_SHRF_ABE);
1659 		free(val);
1660 	}
1661 
1662 	val = smb_shr_sa_getprop(opts, SHOPT_GUEST);
1663 	if (val != NULL) {
1664 		smb_shr_sa_setflag(val, si, SMB_SHRF_GUEST_OK);
1665 		free(val);
1666 	}
1667 
1668 	val = smb_shr_sa_getprop(opts, SHOPT_DFSROOT);
1669 	if (val != NULL) {
1670 		smb_shr_sa_setflag(val, si, SMB_SHRF_DFSROOT);
1671 		free(val);
1672 	}
1673 
1674 	val = smb_shr_sa_getprop(opts, SHOPT_CSC);
1675 	if (val != NULL) {
1676 		smb_shr_sa_csc_option(val, si);
1677 		free(val);
1678 	}
1679 
1680 	val = smb_shr_sa_getprop(opts, SHOPT_NONE);
1681 	if (val != NULL) {
1682 		(void) strlcpy(si->shr_access_none, val,
1683 		    sizeof (si->shr_access_none));
1684 		free(val);
1685 		si->shr_flags |= SMB_SHRF_ACC_NONE;
1686 	}
1687 
1688 	val = smb_shr_sa_getprop(opts, SHOPT_RO);
1689 	if (val != NULL) {
1690 		(void) strlcpy(si->shr_access_ro, val,
1691 		    sizeof (si->shr_access_ro));
1692 		free(val);
1693 		si->shr_flags |= SMB_SHRF_ACC_RO;
1694 	}
1695 
1696 	val = smb_shr_sa_getprop(opts, SHOPT_RW);
1697 	if (val != NULL) {
1698 		(void) strlcpy(si->shr_access_rw, val,
1699 		    sizeof (si->shr_access_rw));
1700 		free(val);
1701 		si->shr_flags |= SMB_SHRF_ACC_RW;
1702 	}
1703 
1704 	sa_free_derived_optionset(opts);
1705 	return (NERR_Success);
1706 }
1707 
1708 /*
1709  * Map a client-side caching (CSC) option to the appropriate share
1710  * flag.  Only one option is allowed; an error will be logged if
1711  * multiple options have been specified.  We don't need to do anything
1712  * about multiple values here because the SRVSVC will not recognize
1713  * a value containing multiple flags and will return the default value.
1714  *
1715  * If the option value is not recognized, it will be ignored: invalid
1716  * values will typically be caught and rejected by sharemgr.
1717  */
1718 void
1719 smb_shr_sa_csc_option(const char *value, smb_share_t *si)
1720 {
1721 	int i;
1722 
1723 	for (i = 0; i < (sizeof (cscopt) / sizeof (cscopt[0])); ++i) {
1724 		if (strcasecmp(value, cscopt[i].value) == 0) {
1725 			si->shr_flags |= cscopt[i].flag;
1726 			break;
1727 		}
1728 	}
1729 
1730 	switch (si->shr_flags & SMB_SHRF_CSC_MASK) {
1731 	case 0:
1732 	case SMB_SHRF_CSC_DISABLED:
1733 	case SMB_SHRF_CSC_MANUAL:
1734 	case SMB_SHRF_CSC_AUTO:
1735 	case SMB_SHRF_CSC_VDO:
1736 		break;
1737 
1738 	default:
1739 		syslog(LOG_INFO, "csc option conflict: 0x%08x",
1740 		    si->shr_flags & SMB_SHRF_CSC_MASK);
1741 		break;
1742 	}
1743 }
1744 
1745 /*
1746  * Return the option name for the first CSC flag (there should be only
1747  * one) encountered in the share flags.
1748  */
1749 char *
1750 smb_shr_sa_csc_name(const smb_share_t *si)
1751 {
1752 	int i;
1753 
1754 	for (i = 0; i < (sizeof (cscopt) / sizeof (cscopt[0])); ++i) {
1755 		if (si->shr_flags & cscopt[i].flag)
1756 			return (cscopt[i].value);
1757 	}
1758 
1759 	return (NULL);
1760 }
1761 
1762 /*
1763  * Takes the value of a boolean share property and set/clear the
1764  * specified flag based on the property's value.
1765  */
1766 void
1767 smb_shr_sa_setflag(const char *value, smb_share_t *si, uint32_t flag)
1768 {
1769 	if ((strcasecmp(value, "true") == 0) || (strcmp(value, "1") == 0))
1770 		si->shr_flags |= flag;
1771 	else
1772 		si->shr_flags &= ~flag;
1773 }
1774 
1775 /*
1776  * looks up sharemgr for the given share (resource) and loads
1777  * the definition into cache if lookup is successful
1778  */
1779 static uint32_t
1780 smb_shr_sa_loadbyname(char *sharename)
1781 {
1782 	sa_handle_t handle;
1783 	sa_share_t share;
1784 	sa_resource_t resource;
1785 	uint32_t status;
1786 
1787 	if ((handle = smb_shr_sa_enter()) == NULL)
1788 		return (NERR_InternalError);
1789 
1790 	resource = sa_find_resource(handle, sharename);
1791 	if (resource == NULL) {
1792 		smb_shr_sa_exit();
1793 		return (NERR_NetNameNotFound);
1794 	}
1795 
1796 	share = sa_get_resource_parent(resource);
1797 	if (share == NULL) {
1798 		smb_shr_sa_exit();
1799 		return (NERR_InternalError);
1800 	}
1801 
1802 	status = smb_shr_sa_load(share, resource);
1803 
1804 	smb_shr_sa_exit();
1805 	return (status);
1806 }
1807 
1808 /*
1809  * ============================================
1810  * Share publishing functions
1811  *
1812  * All the functions are private
1813  * ============================================
1814  */
1815 
1816 static void
1817 smb_shr_publish(const char *sharename, const char *container)
1818 {
1819 	smb_shr_publisher_queue(sharename, container, SMB_SHR_PUBLISH);
1820 }
1821 
1822 static void
1823 smb_shr_unpublish(const char *sharename, const char *container)
1824 {
1825 	smb_shr_publisher_queue(sharename, container, SMB_SHR_UNPUBLISH);
1826 }
1827 
1828 /*
1829  * In domain mode, put a share on the publisher queue.
1830  * This is a no-op if the smb service is in Workgroup mode.
1831  */
1832 static void
1833 smb_shr_publisher_queue(const char *sharename, const char *container, char op)
1834 {
1835 	smb_shr_pitem_t *item = NULL;
1836 
1837 	if (container == NULL || *container == '\0')
1838 		return;
1839 
1840 	if (smb_config_get_secmode() != SMB_SECMODE_DOMAIN)
1841 		return;
1842 
1843 	(void) mutex_lock(&ad_queue.spq_mtx);
1844 	switch (ad_queue.spq_state) {
1845 	case SMB_SHR_PQS_READY:
1846 	case SMB_SHR_PQS_PUBLISHING:
1847 		break;
1848 	default:
1849 		(void) mutex_unlock(&ad_queue.spq_mtx);
1850 		return;
1851 	}
1852 	(void) mutex_unlock(&ad_queue.spq_mtx);
1853 
1854 	if ((item = malloc(sizeof (smb_shr_pitem_t))) == NULL)
1855 		return;
1856 
1857 	item->spi_op = op;
1858 	(void) strlcpy(item->spi_name, sharename, sizeof (item->spi_name));
1859 	(void) strlcpy(item->spi_container, container,
1860 	    sizeof (item->spi_container));
1861 
1862 	(void) mutex_lock(&ad_queue.spq_mtx);
1863 	list_insert_tail(&ad_queue.spq_list, item);
1864 	(void) cond_signal(&ad_queue.spq_cv);
1865 	(void) mutex_unlock(&ad_queue.spq_mtx);
1866 }
1867 
1868 /*
1869  * Publishing won't be activated if the smb service is running in
1870  * Workgroup mode.
1871  */
1872 static int
1873 smb_shr_publisher_start(void)
1874 {
1875 	pthread_t publish_thr;
1876 	pthread_attr_t tattr;
1877 	int rc;
1878 
1879 	if (smb_config_get_secmode() != SMB_SECMODE_DOMAIN)
1880 		return (0);
1881 
1882 	(void) mutex_lock(&ad_queue.spq_mtx);
1883 	if (ad_queue.spq_state != SMB_SHR_PQS_NOQUEUE) {
1884 		(void) mutex_unlock(&ad_queue.spq_mtx);
1885 		errno = EINVAL;
1886 		return (-1);
1887 	}
1888 
1889 	list_create(&ad_queue.spq_list, sizeof (smb_shr_pitem_t),
1890 	    offsetof(smb_shr_pitem_t, spi_lnd));
1891 	ad_queue.spq_state = SMB_SHR_PQS_READY;
1892 	(void) mutex_unlock(&ad_queue.spq_mtx);
1893 
1894 	(void) pthread_attr_init(&tattr);
1895 	(void) pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
1896 	rc = pthread_create(&publish_thr, &tattr, smb_shr_publisher, 0);
1897 	(void) pthread_attr_destroy(&tattr);
1898 
1899 	return (rc);
1900 }
1901 
1902 static void
1903 smb_shr_publisher_stop(void)
1904 {
1905 	if (smb_config_get_secmode() != SMB_SECMODE_DOMAIN)
1906 		return;
1907 
1908 	(void) mutex_lock(&ad_queue.spq_mtx);
1909 	switch (ad_queue.spq_state) {
1910 	case SMB_SHR_PQS_READY:
1911 	case SMB_SHR_PQS_PUBLISHING:
1912 		ad_queue.spq_state = SMB_SHR_PQS_STOPPING;
1913 		(void) cond_signal(&ad_queue.spq_cv);
1914 		break;
1915 	default:
1916 		break;
1917 	}
1918 	(void) mutex_unlock(&ad_queue.spq_mtx);
1919 }
1920 
1921 /*
1922  * This is the publisher daemon thread.  While running, the thread waits
1923  * on a conditional variable until notified that a share needs to be
1924  * [un]published or that the thread should be terminated.
1925  *
1926  * Entries may remain in the outgoing queue if the Active Directory
1927  * service is inaccessible, in which case the thread wakes up every 60
1928  * seconds to retry.
1929  */
1930 /*ARGSUSED*/
1931 static void *
1932 smb_shr_publisher(void *arg)
1933 {
1934 	smb_ads_handle_t *ah;
1935 	smb_shr_pitem_t *shr;
1936 	list_t publist;
1937 	timestruc_t pubretry;
1938 	char hostname[MAXHOSTNAMELEN];
1939 
1940 	(void) mutex_lock(&ad_queue.spq_mtx);
1941 	if (ad_queue.spq_state != SMB_SHR_PQS_READY) {
1942 		(void) mutex_unlock(&ad_queue.spq_mtx);
1943 		return (NULL);
1944 	}
1945 	ad_queue.spq_state = SMB_SHR_PQS_PUBLISHING;
1946 	(void) mutex_unlock(&ad_queue.spq_mtx);
1947 
1948 	(void) smb_gethostname(hostname, MAXHOSTNAMELEN,
1949 	    SMB_CASE_PRESERVE);
1950 
1951 	list_create(&publist, sizeof (smb_shr_pitem_t),
1952 	    offsetof(smb_shr_pitem_t, spi_lnd));
1953 
1954 	for (;;) {
1955 		(void) mutex_lock(&ad_queue.spq_mtx);
1956 
1957 		while (list_is_empty(&ad_queue.spq_list) &&
1958 		    (ad_queue.spq_state == SMB_SHR_PQS_PUBLISHING)) {
1959 			if (list_is_empty(&publist)) {
1960 				(void) cond_wait(&ad_queue.spq_cv,
1961 				    &ad_queue.spq_mtx);
1962 			} else {
1963 				pubretry.tv_sec = 60;
1964 				pubretry.tv_nsec = 0;
1965 				(void) cond_reltimedwait(&ad_queue.spq_cv,
1966 				    &ad_queue.spq_mtx, &pubretry);
1967 				break;
1968 			}
1969 		}
1970 
1971 		if (ad_queue.spq_state != SMB_SHR_PQS_PUBLISHING) {
1972 			(void) mutex_unlock(&ad_queue.spq_mtx);
1973 			break;
1974 		}
1975 
1976 		/*
1977 		 * Transfer queued items to the local list so that
1978 		 * the mutex can be released.
1979 		 */
1980 		while ((shr = list_head(&ad_queue.spq_list)) != NULL) {
1981 			list_remove(&ad_queue.spq_list, shr);
1982 			list_insert_tail(&publist, shr);
1983 		}
1984 
1985 		(void) mutex_unlock(&ad_queue.spq_mtx);
1986 
1987 		if ((ah = smb_ads_open()) != NULL) {
1988 			smb_shr_publisher_send(ah, &publist, hostname);
1989 			smb_ads_close(ah);
1990 		}
1991 	}
1992 
1993 	(void) mutex_lock(&ad_queue.spq_mtx);
1994 	smb_shr_publisher_flush(&ad_queue.spq_list);
1995 	list_destroy(&ad_queue.spq_list);
1996 	ad_queue.spq_state = SMB_SHR_PQS_NOQUEUE;
1997 	(void) mutex_unlock(&ad_queue.spq_mtx);
1998 
1999 	smb_shr_publisher_flush(&publist);
2000 	list_destroy(&publist);
2001 	return (NULL);
2002 }
2003 
2004 /*
2005  * Remove items from the specified queue and [un]publish them.
2006  */
2007 static void
2008 smb_shr_publisher_send(smb_ads_handle_t *ah, list_t *publist, const char *host)
2009 {
2010 	smb_shr_pitem_t *shr;
2011 
2012 	while ((shr = list_head(publist)) != NULL) {
2013 		(void) mutex_lock(&ad_queue.spq_mtx);
2014 		if (ad_queue.spq_state != SMB_SHR_PQS_PUBLISHING) {
2015 			(void) mutex_unlock(&ad_queue.spq_mtx);
2016 			return;
2017 		}
2018 		(void) mutex_unlock(&ad_queue.spq_mtx);
2019 
2020 		list_remove(publist, shr);
2021 
2022 		if (shr->spi_op == SMB_SHR_PUBLISH)
2023 			(void) smb_ads_publish_share(ah, shr->spi_name,
2024 			    NULL, shr->spi_container, host);
2025 		else
2026 			(void) smb_ads_remove_share(ah, shr->spi_name,
2027 			    NULL, shr->spi_container, host);
2028 
2029 		free(shr);
2030 	}
2031 }
2032 
2033 /*
2034  * Flush all remaining items from the specified list/queue.
2035  */
2036 static void
2037 smb_shr_publisher_flush(list_t *lst)
2038 {
2039 	smb_shr_pitem_t *shr;
2040 
2041 	while ((shr = list_head(lst)) != NULL) {
2042 		list_remove(lst, shr);
2043 		free(shr);
2044 	}
2045 }
2046 
2047 /*
2048  * If the share path refers to a ZFS file system, add the
2049  * .zfs/shares/<share> object and call smb_quota_add_fs()
2050  * to initialize quota support for the share.
2051  */
2052 static void
2053 smb_shr_zfs_add(smb_share_t *si)
2054 {
2055 	libzfs_handle_t *libhd;
2056 	zfs_handle_t *zfshd;
2057 	int ret;
2058 	char buf[MAXPATHLEN];	/* dataset or mountpoint */
2059 
2060 	if (smb_getdataset(si->shr_path, buf, MAXPATHLEN) != 0)
2061 		return;
2062 
2063 	if ((libhd = libzfs_init()) == NULL)
2064 		return;
2065 
2066 	if ((zfshd = zfs_open(libhd, buf, ZFS_TYPE_FILESYSTEM)) == NULL) {
2067 		libzfs_fini(libhd);
2068 		return;
2069 	}
2070 
2071 	errno = 0;
2072 	ret = zfs_smb_acl_add(libhd, buf, si->shr_path, si->shr_name);
2073 	if (ret != 0 && errno != EAGAIN && errno != EEXIST)
2074 		syslog(LOG_INFO, "share: failed to add ACL object: %s: %s\n",
2075 		    si->shr_name, strerror(errno));
2076 
2077 	if (zfs_prop_get(zfshd, ZFS_PROP_MOUNTPOINT, buf, MAXPATHLEN,
2078 	    NULL, NULL, 0, B_FALSE) == 0) {
2079 		smb_quota_add_fs(buf);
2080 	}
2081 
2082 
2083 	zfs_close(zfshd);
2084 	libzfs_fini(libhd);
2085 }
2086 
2087 /*
2088  * If the share path refers to a ZFS file system, remove the
2089  * .zfs/shares/<share> object, and call smb_quota_remove_fs()
2090  * to end quota support for the share.
2091  */
2092 static void
2093 smb_shr_zfs_remove(smb_share_t *si)
2094 {
2095 	libzfs_handle_t *libhd;
2096 	zfs_handle_t *zfshd;
2097 	int ret;
2098 	char buf[MAXPATHLEN];	/* dataset or mountpoint */
2099 
2100 	if (smb_getdataset(si->shr_path, buf, MAXPATHLEN) != 0)
2101 		return;
2102 
2103 	if ((libhd = libzfs_init()) == NULL)
2104 		return;
2105 
2106 	if ((zfshd = zfs_open(libhd, buf, ZFS_TYPE_FILESYSTEM)) == NULL) {
2107 		libzfs_fini(libhd);
2108 		return;
2109 	}
2110 
2111 	errno = 0;
2112 	ret = zfs_smb_acl_remove(libhd, buf, si->shr_path, si->shr_name);
2113 	if (ret != 0 && errno != EAGAIN)
2114 		syslog(LOG_INFO, "share: failed to remove ACL object: %s: %s\n",
2115 		    si->shr_name, strerror(errno));
2116 
2117 	if (zfs_prop_get(zfshd, ZFS_PROP_MOUNTPOINT, buf, MAXPATHLEN,
2118 	    NULL, NULL, 0, B_FALSE) == 0) {
2119 		smb_quota_remove_fs(buf);
2120 	}
2121 
2122 	zfs_close(zfshd);
2123 	libzfs_fini(libhd);
2124 }
2125 
2126 /*
2127  * If the share path refers to a ZFS file system, rename the
2128  * .zfs/shares/<share> object.
2129  */
2130 static void
2131 smb_shr_zfs_rename(smb_share_t *from, smb_share_t *to)
2132 {
2133 	libzfs_handle_t *libhd;
2134 	zfs_handle_t *zfshd;
2135 	int ret;
2136 	char dataset[MAXPATHLEN];
2137 
2138 	if (smb_getdataset(from->shr_path, dataset, MAXPATHLEN) != 0)
2139 		return;
2140 
2141 	if ((libhd = libzfs_init()) == NULL)
2142 		return;
2143 
2144 	if ((zfshd = zfs_open(libhd, dataset, ZFS_TYPE_FILESYSTEM)) == NULL) {
2145 		libzfs_fini(libhd);
2146 		return;
2147 	}
2148 
2149 	errno = 0;
2150 	ret = zfs_smb_acl_rename(libhd, dataset, from->shr_path,
2151 	    from->shr_name, to->shr_name);
2152 	if (ret != 0 && errno != EAGAIN)
2153 		syslog(LOG_INFO, "share: failed to rename ACL object: %s: %s\n",
2154 		    from->shr_name, strerror(errno));
2155 
2156 	zfs_close(zfshd);
2157 	libzfs_fini(libhd);
2158 }
2159 
2160 /*
2161  * Enable all privileges in the inheritable set to execute command.
2162  */
2163 static int
2164 smb_shr_enable_all_privs(void)
2165 {
2166 	priv_set_t *pset;
2167 
2168 	pset = priv_allocset();
2169 	if (pset == NULL)
2170 		return (-1);
2171 
2172 	if (getppriv(PRIV_LIMIT, pset)) {
2173 		priv_freeset(pset);
2174 		return (-1);
2175 	}
2176 
2177 	if (setppriv(PRIV_ON, PRIV_INHERITABLE, pset)) {
2178 		priv_freeset(pset);
2179 		return (-1);
2180 	}
2181 
2182 	priv_freeset(pset);
2183 	return (0);
2184 }
2185 
2186 /*
2187  * Tokenizes the command string and returns the list of tokens in an array.
2188  *
2189  * Returns NULL if there are no tokens.
2190  */
2191 static char **
2192 smb_shr_tokenize_cmd(char *cmdstr)
2193 {
2194 	char *cmd, *buf, *bp, *value;
2195 	char **argv, **ap;
2196 	int argc, i;
2197 
2198 	if (cmdstr == NULL || *cmdstr == '\0')
2199 		return (NULL);
2200 
2201 	if ((buf = malloc(MAXPATHLEN)) == NULL)
2202 		return (NULL);
2203 
2204 	(void) strlcpy(buf, cmdstr, MAXPATHLEN);
2205 
2206 	for (argc = 2, bp = cmdstr; *bp != '\0'; ++bp)
2207 		if (*bp == ' ')
2208 			++argc;
2209 
2210 	if ((argv = calloc(argc, sizeof (char *))) == NULL) {
2211 		free(buf);
2212 		return (NULL);
2213 	}
2214 
2215 	ap = argv;
2216 	for (bp = buf, i = 0; i < argc; ++i) {
2217 		do {
2218 			if ((value = strsep(&bp, " ")) == NULL)
2219 				break;
2220 		} while (*value == '\0');
2221 
2222 		if (value == NULL)
2223 			break;
2224 
2225 		*ap++ = value;
2226 	}
2227 
2228 	/* get the filename of the command from the path */
2229 	if ((cmd = strrchr(argv[0], '/')) != NULL)
2230 		(void) strlcpy(argv[0], ++cmd, strlen(argv[0]));
2231 
2232 	return (argv);
2233 }
2234 
2235 /*
2236  * Expands the command string for the following substitution tokens:
2237  *
2238  * %U - Windows username
2239  * %D - Name of the domain or workgroup of %U
2240  * %h - The server hostname
2241  * %M - The client hostname
2242  * %L - The server NetBIOS name
2243  * %m - The client NetBIOS name. This option is only valid for NetBIOS
2244  *      connections (port 139).
2245  * %I - The IP address of the client machine
2246  * %i - The local IP address to which the client is connected
2247  * %S - The name of the share
2248  * %P - The root directory of the share
2249  * %u - The UID of the Unix user
2250  *
2251  * Returns 0 on success.  Otherwise -1.
2252  */
2253 static int
2254 smb_shr_expand_subs(char **cmd_toks, smb_share_t *si, smb_execsub_info_t *subs)
2255 {
2256 	char *fmt, *sub_chr, *ptr;
2257 	boolean_t unknown;
2258 	char hostname[MAXHOSTNAMELEN];
2259 	char ip_str[INET6_ADDRSTRLEN];
2260 	char name[SMB_PI_MAX_HOST];
2261 	smb_wchar_t wbuf[SMB_PI_MAX_HOST];
2262 	int i;
2263 
2264 	if (cmd_toks == NULL || *cmd_toks == NULL)
2265 		return (-1);
2266 
2267 	for (i = 1; cmd_toks[i]; i++) {
2268 		fmt = cmd_toks[i];
2269 		if (*fmt == '%') {
2270 			sub_chr = fmt + 1;
2271 			unknown = B_FALSE;
2272 
2273 			switch (*sub_chr) {
2274 			case 'U':
2275 				ptr = strdup(subs->e_winname);
2276 				break;
2277 			case 'D':
2278 				ptr = strdup(subs->e_userdom);
2279 				break;
2280 			case 'h':
2281 				if (gethostname(hostname, MAXHOSTNAMELEN) != 0)
2282 					unknown = B_TRUE;
2283 				else
2284 					ptr = strdup(hostname);
2285 				break;
2286 			case 'M':
2287 				if (smb_getnameinfo(&subs->e_cli_ipaddr,
2288 				    hostname, sizeof (hostname), 0) != 0)
2289 					unknown = B_TRUE;
2290 				else
2291 					ptr = strdup(hostname);
2292 				break;
2293 			case 'L':
2294 				if (smb_getnetbiosname(hostname,
2295 				    NETBIOS_NAME_SZ) != 0)
2296 					unknown = B_TRUE;
2297 				else
2298 					ptr = strdup(hostname);
2299 				break;
2300 			case 'm':
2301 				if (*subs->e_cli_netbiosname == '\0')
2302 					unknown = B_TRUE;
2303 				else {
2304 					(void) smb_mbstowcs(wbuf,
2305 					    subs->e_cli_netbiosname,
2306 					    SMB_PI_MAX_HOST - 1);
2307 
2308 					if (ucstooem(name, wbuf,
2309 					    SMB_PI_MAX_HOST, OEM_CPG_850) == 0)
2310 						(void) strlcpy(name,
2311 						    subs->e_cli_netbiosname,
2312 						    SMB_PI_MAX_HOST);
2313 
2314 					ptr = strdup(name);
2315 				}
2316 				break;
2317 			case 'I':
2318 				if (smb_inet_ntop(&subs->e_cli_ipaddr, ip_str,
2319 				    SMB_IPSTRLEN(subs->e_cli_ipaddr.a_family))
2320 				    != NULL)
2321 					ptr = strdup(ip_str);
2322 				else
2323 					unknown = B_TRUE;
2324 				break;
2325 			case 'i':
2326 				if (smb_inet_ntop(&subs->e_srv_ipaddr, ip_str,
2327 				    SMB_IPSTRLEN(subs->e_srv_ipaddr.a_family))
2328 				    != NULL)
2329 					ptr = strdup(ip_str);
2330 				else
2331 					unknown = B_TRUE;
2332 				break;
2333 			case 'S':
2334 				ptr = strdup(si->shr_name);
2335 				break;
2336 			case 'P':
2337 				ptr = strdup(si->shr_path);
2338 				break;
2339 			case 'u':
2340 				(void) snprintf(name, sizeof (name), "%u",
2341 				    subs->e_uid);
2342 				ptr = strdup(name);
2343 				break;
2344 			default:
2345 				/* unknown sub char */
2346 				unknown = B_TRUE;
2347 				break;
2348 			}
2349 
2350 			if (unknown)
2351 				ptr = strdup("");
2352 
2353 		} else  /* first char of cmd's arg is not '%' char */
2354 			ptr = strdup("");
2355 
2356 		cmd_toks[i] = ptr;
2357 
2358 		if (ptr == NULL) {
2359 			for (i = 1; cmd_toks[i]; i++)
2360 				free(cmd_toks[i]);
2361 
2362 			return (-1);
2363 		}
2364 	}
2365 
2366 	return (0);
2367 }
2368 
2369 /*ARGSUSED*/
2370 static void
2371 smb_shr_sig_abnormal_term(int sig_val)
2372 {
2373 	/*
2374 	 * Calling _exit() prevents parent process from getting SIGTERM/SIGINT
2375 	 * signal.
2376 	 */
2377 	_exit(-1);
2378 }
2379 
2380 /*ARGSUSED*/
2381 static void
2382 smb_shr_sig_child(int sig_val)
2383 {
2384 	/*
2385 	 * Catch the signal and allow the exit status of the child process
2386 	 * to be available for reaping.
2387 	 */
2388 }
2389 
2390 /*
2391  *  Gets the exec bit flags for each share.
2392  */
2393 static void
2394 smb_shr_get_exec_info(void)
2395 {
2396 	char buf[MAXPATHLEN];
2397 
2398 	(void) mutex_lock(&smb_shr_exec_mtx);
2399 
2400 	smb_shr_exec_flags = 0;
2401 
2402 	*smb_shr_exec_map = '\0';
2403 	(void) smb_config_getstr(SMB_CI_MAP, smb_shr_exec_map,
2404 	    sizeof (smb_shr_exec_map));
2405 	if (*smb_shr_exec_map != '\0')
2406 		smb_shr_exec_flags |= SMB_SHRF_MAP;
2407 
2408 	*smb_shr_exec_unmap = '\0';
2409 	(void) smb_config_getstr(SMB_CI_UNMAP, smb_shr_exec_unmap,
2410 	    sizeof (smb_shr_exec_unmap));
2411 	if (*smb_shr_exec_unmap != '\0')
2412 		smb_shr_exec_flags |= SMB_SHRF_UNMAP;
2413 
2414 	*buf = '\0';
2415 	(void) smb_config_getstr(SMB_CI_DISPOSITION, buf, sizeof (buf));
2416 	if (*buf != '\0')
2417 		if (strcasecmp(buf, SMB_SHR_DISP_TERM_STR) == 0)
2418 			smb_shr_exec_flags |= SMB_SHRF_DISP_TERM;
2419 
2420 	(void) mutex_unlock(&smb_shr_exec_mtx);
2421 }
2422 
2423 /*
2424  *  Sets the exec bit flags for each share.
2425  */
2426 static void
2427 smb_shr_set_exec_flags(smb_share_t *si)
2428 {
2429 	(void) mutex_lock(&smb_shr_exec_mtx);
2430 	si->shr_flags &= ~SMB_SHRF_EXEC_MASK;
2431 	si->shr_flags |= smb_shr_exec_flags;
2432 	(void) mutex_unlock(&smb_shr_exec_mtx);
2433 }
2434