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
20da6c28aaSamw  */
21da6c28aaSamw 
22da6c28aaSamw /*
23*dc20a302Sas200622  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
24da6c28aaSamw  * Use is subject to license terms.
25da6c28aaSamw  */
26da6c28aaSamw 
27da6c28aaSamw #pragma ident	"%Z%%M%	%I%	%E% SMI"
28da6c28aaSamw 
29da6c28aaSamw /*
30da6c28aaSamw  * User-space door client for LanMan share management.
31da6c28aaSamw  */
32da6c28aaSamw 
33da6c28aaSamw #include <syslog.h>
34da6c28aaSamw #include <door.h>
35da6c28aaSamw #include <fcntl.h>
36da6c28aaSamw #include <stdarg.h>
37da6c28aaSamw #include <errno.h>
38da6c28aaSamw #include <string.h>
39da6c28aaSamw #include <strings.h>
40*dc20a302Sas200622 #include <unistd.h>
41*dc20a302Sas200622 #include <thread.h>
42*dc20a302Sas200622 #include <synch.h>
43da6c28aaSamw 
44da6c28aaSamw #include <smbsrv/libsmb.h>
45da6c28aaSamw #include <smbsrv/lmshare.h>
46da6c28aaSamw #include <smbsrv/lmerr.h>
47da6c28aaSamw #include <smbsrv/lmshare_door.h>
48da6c28aaSamw #include <smbsrv/cifs.h>
49da6c28aaSamw 
50*dc20a302Sas200622 static int lmshrd_fildes = -1;
51*dc20a302Sas200622 static uint64_t lmshrd_door_ncall = 0;
52*dc20a302Sas200622 static mutex_t lmshrd_mutex;
53*dc20a302Sas200622 static cond_t lmshrd_cv;
54da6c28aaSamw 
55da6c28aaSamw char *lmshrd_desc[] = {
56da6c28aaSamw 	"",
57da6c28aaSamw 	"LmshrdOpenIter",
58da6c28aaSamw 	"LmshrdCloseIter",
59da6c28aaSamw 	"LmshrdIterate",
60da6c28aaSamw 	"LmshrdNumShares",
61da6c28aaSamw 	"LmshrdDelete",
62da6c28aaSamw 	"LmshrdRename",
63da6c28aaSamw 	"LmshrdGetinfo",
64da6c28aaSamw 	"LmshrdAdd",
65da6c28aaSamw 	"LmshrdSetinfo",
66da6c28aaSamw 	"LmshrdExists",
67da6c28aaSamw 	"LmshrdIsSpecial",
68da6c28aaSamw 	"LmshrdIsRestricted",
69da6c28aaSamw 	"LmshrdIsAdmin",
70da6c28aaSamw 	"LmshrdIsValid",
71da6c28aaSamw 	"LmshrdIsDir",
72da6c28aaSamw 	"LmshrdList",
73da6c28aaSamw 	"LmshrdListTrans",
74da6c28aaSamw 	"LmshrdNumTrans",
75da6c28aaSamw 	"N/A",
76da6c28aaSamw 	0
77da6c28aaSamw };
78da6c28aaSamw 
79da6c28aaSamw /*
80*dc20a302Sas200622  * Open the lmshrd door.  This is a private call for use by
81*dc20a302Sas200622  * lmshrd_door_enter() and must be called with lmshrd_mutex held.
82*dc20a302Sas200622  *
83*dc20a302Sas200622  * Returns the door fd on success.  Otherwise, -1.
84da6c28aaSamw  */
85da6c28aaSamw static int
86*dc20a302Sas200622 lmshrd_door_open(void)
87da6c28aaSamw {
88*dc20a302Sas200622 	if (lmshrd_fildes == -1) {
89*dc20a302Sas200622 		if ((lmshrd_fildes = open(LMSHR_DOOR_NAME, O_RDONLY)) < 0)
90*dc20a302Sas200622 			lmshrd_fildes = -1;
91*dc20a302Sas200622 		else
92*dc20a302Sas200622 			lmshrd_door_ncall = 0;
93da6c28aaSamw 	}
94*dc20a302Sas200622 
95*dc20a302Sas200622 	return (lmshrd_fildes);
96*dc20a302Sas200622 }
97*dc20a302Sas200622 
98*dc20a302Sas200622 /*
99*dc20a302Sas200622  * Close the lmshrd door.
100*dc20a302Sas200622  */
101*dc20a302Sas200622 void
102*dc20a302Sas200622 lmshrd_door_close(void)
103*dc20a302Sas200622 {
104*dc20a302Sas200622 	(void) mutex_lock(&lmshrd_mutex);
105*dc20a302Sas200622 
106*dc20a302Sas200622 	if (lmshrd_fildes != -1) {
107*dc20a302Sas200622 		while (lmshrd_door_ncall > 0)
108*dc20a302Sas200622 			(void) cond_wait(&lmshrd_cv, &lmshrd_mutex);
109*dc20a302Sas200622 
110*dc20a302Sas200622 		if (lmshrd_fildes != -1) {
111*dc20a302Sas200622 			(void) close(lmshrd_fildes);
112*dc20a302Sas200622 			lmshrd_fildes = -1;
113*dc20a302Sas200622 		}
114*dc20a302Sas200622 	}
115*dc20a302Sas200622 
116*dc20a302Sas200622 	(void) mutex_unlock(&lmshrd_mutex);
117*dc20a302Sas200622 }
118*dc20a302Sas200622 
119*dc20a302Sas200622 /*
120*dc20a302Sas200622  * Entry handler for lmshrd door calls.
121*dc20a302Sas200622  */
122*dc20a302Sas200622 static door_arg_t *
123*dc20a302Sas200622 lmshrd_door_enter(void)
124*dc20a302Sas200622 {
125*dc20a302Sas200622 	door_arg_t *arg;
126*dc20a302Sas200622 	char *buf;
127*dc20a302Sas200622 
128*dc20a302Sas200622 	(void) mutex_lock(&lmshrd_mutex);
129*dc20a302Sas200622 
130*dc20a302Sas200622 	if (lmshrd_door_open() == -1) {
131*dc20a302Sas200622 		(void) mutex_unlock(&lmshrd_mutex);
132*dc20a302Sas200622 		return (NULL);
133*dc20a302Sas200622 	}
134*dc20a302Sas200622 
135*dc20a302Sas200622 	if ((arg = malloc(sizeof (door_arg_t) + LMSHR_DOOR_SIZE)) != NULL) {
136*dc20a302Sas200622 		buf = ((char *)arg) + sizeof (door_arg_t);
137*dc20a302Sas200622 		bzero(arg, sizeof (door_arg_t));
138*dc20a302Sas200622 		arg->data_ptr = buf;
139*dc20a302Sas200622 		arg->rbuf = buf;
140*dc20a302Sas200622 		arg->rsize = LMSHR_DOOR_SIZE;
141*dc20a302Sas200622 
142*dc20a302Sas200622 		++lmshrd_door_ncall;
143*dc20a302Sas200622 	}
144*dc20a302Sas200622 
145*dc20a302Sas200622 	(void) mutex_unlock(&lmshrd_mutex);
146*dc20a302Sas200622 	return (arg);
147*dc20a302Sas200622 }
148*dc20a302Sas200622 
149*dc20a302Sas200622 /*
150*dc20a302Sas200622  * Exit handler for lmshrd door calls.
151*dc20a302Sas200622  */
152*dc20a302Sas200622 static void
153*dc20a302Sas200622 lmshrd_door_exit(door_arg_t *arg, char *errmsg)
154*dc20a302Sas200622 {
155*dc20a302Sas200622 	if (errmsg)
156*dc20a302Sas200622 		syslog(LOG_DEBUG, "lmshrd_door: %s", errmsg);
157*dc20a302Sas200622 
158*dc20a302Sas200622 	(void) mutex_lock(&lmshrd_mutex);
159*dc20a302Sas200622 	free(arg);
160*dc20a302Sas200622 	--lmshrd_door_ncall;
161*dc20a302Sas200622 	(void) cond_signal(&lmshrd_cv);
162*dc20a302Sas200622 	(void) mutex_unlock(&lmshrd_mutex);
163da6c28aaSamw }
164da6c28aaSamw 
165da6c28aaSamw /*
166da6c28aaSamw  * Return 0 upon success. Otherwise, -1.
167da6c28aaSamw  */
168da6c28aaSamw static int
169*dc20a302Sas200622 lmshrd_door_check_status(smb_dr_ctx_t *dec_ctx)
170da6c28aaSamw {
171da6c28aaSamw 	int status = smb_dr_get_int32(dec_ctx);
172da6c28aaSamw 
173*dc20a302Sas200622 	if (status != LMSHR_DOOR_SRV_SUCCESS) {
174*dc20a302Sas200622 		if (status == LMSHR_DOOR_SRV_ERROR)
175*dc20a302Sas200622 			(void) smb_dr_get_uint32(dec_ctx);
176*dc20a302Sas200622 		return (-1);
177da6c28aaSamw 	}
178da6c28aaSamw 
179*dc20a302Sas200622 	return (0);
180da6c28aaSamw }
181da6c28aaSamw 
182da6c28aaSamw uint64_t
183da6c28aaSamw lmshrd_open_iterator(int mode)
184da6c28aaSamw {
185*dc20a302Sas200622 	door_arg_t *arg;
186da6c28aaSamw 	smb_dr_ctx_t *dec_ctx;
187da6c28aaSamw 	smb_dr_ctx_t *enc_ctx;
188da6c28aaSamw 	uint64_t lmshr_iter = 0;
189*dc20a302Sas200622 	int rc;
190da6c28aaSamw 
191*dc20a302Sas200622 	if ((arg = lmshrd_door_enter()) == NULL)
192da6c28aaSamw 		return (lmshr_iter);
193da6c28aaSamw 
194*dc20a302Sas200622 	enc_ctx = smb_dr_encode_start(arg->data_ptr, LMSHR_DOOR_SIZE);
195*dc20a302Sas200622 	smb_dr_put_uint32(enc_ctx, LMSHR_DOOR_OPEN_ITERATOR);
196da6c28aaSamw 	smb_dr_put_int32(enc_ctx, mode);
197*dc20a302Sas200622 
198*dc20a302Sas200622 	rc = smb_dr_encode_finish(enc_ctx, (unsigned int *)&arg->data_size);
199*dc20a302Sas200622 	if (rc != 0) {
200*dc20a302Sas200622 		lmshrd_door_exit(arg, "encode error");
201da6c28aaSamw 		return (lmshr_iter);
202da6c28aaSamw 	}
203da6c28aaSamw 
204*dc20a302Sas200622 	if (door_call(lmshrd_fildes, arg) < 0) {
205*dc20a302Sas200622 		lmshrd_door_exit(arg, "door call error");
206*dc20a302Sas200622 		lmshrd_door_close();
207da6c28aaSamw 		return (lmshr_iter);
208da6c28aaSamw 	}
209da6c28aaSamw 
210*dc20a302Sas200622 	dec_ctx = smb_dr_decode_start(arg->data_ptr, arg->data_size);
211*dc20a302Sas200622 	if (lmshrd_door_check_status(dec_ctx) != 0) {
212*dc20a302Sas200622 		(void) smb_dr_decode_finish(dec_ctx);
213*dc20a302Sas200622 		lmshrd_door_exit(arg, "decode error");
214da6c28aaSamw 		return (lmshr_iter);
215da6c28aaSamw 	}
216da6c28aaSamw 
217da6c28aaSamw 	lmshr_iter = smb_dr_get_lmshr_iterator(dec_ctx);
218*dc20a302Sas200622 	if (smb_dr_decode_finish(dec_ctx) != 0) {
219*dc20a302Sas200622 		lmshrd_door_exit(arg, "decode error");
220da6c28aaSamw 		return (lmshr_iter);
221da6c28aaSamw 	}
222da6c28aaSamw 
223*dc20a302Sas200622 	lmshrd_door_exit(arg, NULL);
224da6c28aaSamw 	return (lmshr_iter);
225da6c28aaSamw }
226da6c28aaSamw 
227da6c28aaSamw 
228da6c28aaSamw DWORD
229da6c28aaSamw lmshrd_close_iterator(uint64_t iterator)
230da6c28aaSamw {
231*dc20a302Sas200622 	door_arg_t *arg;
232da6c28aaSamw 	smb_dr_ctx_t *dec_ctx;
233da6c28aaSamw 	smb_dr_ctx_t *enc_ctx;
234*dc20a302Sas200622 	int rc;
235da6c28aaSamw 
236*dc20a302Sas200622 	if ((arg = lmshrd_door_enter()) == NULL)
237da6c28aaSamw 		return (NERR_InternalError);
238da6c28aaSamw 
239*dc20a302Sas200622 	enc_ctx = smb_dr_encode_start(arg->data_ptr, LMSHR_DOOR_SIZE);
240*dc20a302Sas200622 	smb_dr_put_uint32(enc_ctx, LMSHR_DOOR_CLOSE_ITERATOR);
241da6c28aaSamw 	smb_dr_put_lmshr_iterator(enc_ctx, iterator);
242*dc20a302Sas200622 
243*dc20a302Sas200622 	rc = smb_dr_encode_finish(enc_ctx, (unsigned int *)&arg->data_size);
244*dc20a302Sas200622 	if (rc != 0) {
245*dc20a302Sas200622 		lmshrd_door_exit(arg, "encode error");
246da6c28aaSamw 		return (NERR_InternalError);
247da6c28aaSamw 	}
248da6c28aaSamw 
249*dc20a302Sas200622 	if (door_call(lmshrd_fildes, arg) < 0) {
250*dc20a302Sas200622 		lmshrd_door_exit(arg, "door call error");
251*dc20a302Sas200622 		lmshrd_door_close();
252da6c28aaSamw 		return (NERR_InternalError);
253da6c28aaSamw 	}
254da6c28aaSamw 
255*dc20a302Sas200622 	dec_ctx = smb_dr_decode_start(arg->data_ptr, arg->data_size);
256*dc20a302Sas200622 	if (lmshrd_door_check_status(dec_ctx) != 0) {
257*dc20a302Sas200622 		(void) smb_dr_decode_finish(dec_ctx);
258*dc20a302Sas200622 		lmshrd_door_exit(arg, "decode error");
259da6c28aaSamw 		return (NERR_InternalError);
260da6c28aaSamw 	}
261da6c28aaSamw 
262*dc20a302Sas200622 	if (smb_dr_decode_finish(dec_ctx) != 0) {
263*dc20a302Sas200622 		lmshrd_door_exit(arg, "decode error");
264da6c28aaSamw 		return (NERR_InternalError);
265da6c28aaSamw 	}
266da6c28aaSamw 
267*dc20a302Sas200622 	lmshrd_door_exit(arg, NULL);
268da6c28aaSamw 	return (NERR_Success);
269da6c28aaSamw }
270da6c28aaSamw 
271da6c28aaSamw DWORD
272da6c28aaSamw lmshrd_iterate(uint64_t iterator, lmshare_info_t *si)
273da6c28aaSamw {
274*dc20a302Sas200622 	door_arg_t *arg;
275da6c28aaSamw 	smb_dr_ctx_t *dec_ctx;
276da6c28aaSamw 	smb_dr_ctx_t *enc_ctx;
277*dc20a302Sas200622 	int rc;
278da6c28aaSamw 
279*dc20a302Sas200622 	if ((arg = lmshrd_door_enter()) == NULL)
280da6c28aaSamw 		return (NERR_InternalError);
281da6c28aaSamw 
282da6c28aaSamw 	bzero(si, sizeof (lmshare_info_t));
283*dc20a302Sas200622 	enc_ctx = smb_dr_encode_start(arg->data_ptr, LMSHR_DOOR_SIZE);
284*dc20a302Sas200622 	smb_dr_put_uint32(enc_ctx, LMSHR_DOOR_ITERATE);
285da6c28aaSamw 	smb_dr_put_lmshr_iterator(enc_ctx, iterator);
286*dc20a302Sas200622 
287*dc20a302Sas200622 	rc = smb_dr_encode_finish(enc_ctx, (unsigned int *)&arg->data_size);
288*dc20a302Sas200622 	if (rc != 0) {
289*dc20a302Sas200622 		lmshrd_door_exit(arg, "encode error");
290da6c28aaSamw 		return (NERR_InternalError);
291da6c28aaSamw 	}
292da6c28aaSamw 
293*dc20a302Sas200622 	if (door_call(lmshrd_fildes, arg) < 0) {
294*dc20a302Sas200622 		lmshrd_door_exit(arg, "door call error");
295*dc20a302Sas200622 		lmshrd_door_close();
296da6c28aaSamw 		return (NERR_InternalError);
297da6c28aaSamw 	}
298da6c28aaSamw 
299*dc20a302Sas200622 	dec_ctx = smb_dr_decode_start(arg->data_ptr, arg->data_size);
300*dc20a302Sas200622 	if (lmshrd_door_check_status(dec_ctx) != 0) {
301*dc20a302Sas200622 		(void) smb_dr_decode_finish(dec_ctx);
302*dc20a302Sas200622 		lmshrd_door_exit(arg, "decode error");
303da6c28aaSamw 		return (NERR_InternalError);
304da6c28aaSamw 	}
305da6c28aaSamw 
306da6c28aaSamw 	smb_dr_get_lmshare(dec_ctx, si);
307*dc20a302Sas200622 	if (smb_dr_decode_finish(dec_ctx) != 0) {
308*dc20a302Sas200622 		lmshrd_door_exit(arg, "decode error");
309da6c28aaSamw 		return (NERR_InternalError);
310da6c28aaSamw 	}
311da6c28aaSamw 
312*dc20a302Sas200622 	lmshrd_door_exit(arg, NULL);
313da6c28aaSamw 	return (NERR_Success);
314da6c28aaSamw }
315da6c28aaSamw 
316da6c28aaSamw DWORD
317da6c28aaSamw lmshrd_list(int offset, lmshare_list_t *list)
318da6c28aaSamw {
319*dc20a302Sas200622 	door_arg_t *arg;
320da6c28aaSamw 	smb_dr_ctx_t *dec_ctx;
321da6c28aaSamw 	smb_dr_ctx_t *enc_ctx;
322da6c28aaSamw 	DWORD rc;
323da6c28aaSamw 
324*dc20a302Sas200622 	if ((arg = lmshrd_door_enter()) == NULL)
325da6c28aaSamw 		return (NERR_InternalError);
326da6c28aaSamw 
327*dc20a302Sas200622 	enc_ctx = smb_dr_encode_start(arg->data_ptr, LMSHR_DOOR_SIZE);
328*dc20a302Sas200622 	smb_dr_put_uint32(enc_ctx, LMSHR_DOOR_LIST);
329da6c28aaSamw 	smb_dr_put_int32(enc_ctx, offset);
330da6c28aaSamw 
331*dc20a302Sas200622 	rc = smb_dr_encode_finish(enc_ctx, (unsigned int *)&arg->data_size);
332*dc20a302Sas200622 	if (rc != 0) {
333*dc20a302Sas200622 		lmshrd_door_exit(arg, "encode error");
334da6c28aaSamw 		return (NERR_InternalError);
335da6c28aaSamw 	}
336da6c28aaSamw 
337*dc20a302Sas200622 	if (door_call(lmshrd_fildes, arg) < 0) {
338*dc20a302Sas200622 		lmshrd_door_exit(arg, "door call error");
339*dc20a302Sas200622 		lmshrd_door_close();
340da6c28aaSamw 		return (NERR_InternalError);
341da6c28aaSamw 	}
342da6c28aaSamw 
343*dc20a302Sas200622 	dec_ctx = smb_dr_decode_start(arg->data_ptr, arg->data_size);
344*dc20a302Sas200622 	if (lmshrd_door_check_status(dec_ctx) != 0) {
345*dc20a302Sas200622 		(void) smb_dr_decode_finish(dec_ctx);
346*dc20a302Sas200622 		lmshrd_door_exit(arg, "decode error");
347da6c28aaSamw 		return (NERR_InternalError);
348da6c28aaSamw 	}
349da6c28aaSamw 
350da6c28aaSamw 	rc = smb_dr_get_uint32(dec_ctx);
351da6c28aaSamw 	smb_dr_get_lmshr_list(dec_ctx, list);
352*dc20a302Sas200622 	if (smb_dr_decode_finish(dec_ctx) != 0) {
353*dc20a302Sas200622 		lmshrd_door_exit(arg, "decode error");
354da6c28aaSamw 		return (NERR_InternalError);
355da6c28aaSamw 	}
356da6c28aaSamw 
357*dc20a302Sas200622 	lmshrd_door_exit(arg, NULL);
358da6c28aaSamw 	return (rc);
359da6c28aaSamw }
360da6c28aaSamw 
361da6c28aaSamw int
362da6c28aaSamw lmshrd_num_shares(void)
363da6c28aaSamw {
364*dc20a302Sas200622 	door_arg_t *arg;
365da6c28aaSamw 	smb_dr_ctx_t *dec_ctx;
366da6c28aaSamw 	smb_dr_ctx_t *enc_ctx;
367da6c28aaSamw 	DWORD num_shares;
368*dc20a302Sas200622 	int rc;
369da6c28aaSamw 
370*dc20a302Sas200622 	if ((arg = lmshrd_door_enter()) == NULL)
371da6c28aaSamw 		return (-1);
372da6c28aaSamw 
373*dc20a302Sas200622 	enc_ctx = smb_dr_encode_start(arg->data_ptr, LMSHR_DOOR_SIZE);
374da6c28aaSamw 	smb_dr_put_uint32(enc_ctx, LMSHR_DOOR_NUM_SHARES);
375*dc20a302Sas200622 
376*dc20a302Sas200622 	rc = smb_dr_encode_finish(enc_ctx, (unsigned int *)&arg->data_size);
377*dc20a302Sas200622 	if (rc != 0) {
378*dc20a302Sas200622 		lmshrd_door_exit(arg, "encode error");
379da6c28aaSamw 		return (-1);
380da6c28aaSamw 	}
381da6c28aaSamw 
382*dc20a302Sas200622 	if (door_call(lmshrd_fildes, arg) < 0) {
383*dc20a302Sas200622 		lmshrd_door_exit(arg, "door call error");
384*dc20a302Sas200622 		lmshrd_door_close();
385da6c28aaSamw 		return (-1);
386da6c28aaSamw 	}
387da6c28aaSamw 
388*dc20a302Sas200622 	dec_ctx = smb_dr_decode_start(arg->data_ptr, arg->data_size);
389*dc20a302Sas200622 	if (lmshrd_door_check_status(dec_ctx) != 0) {
390*dc20a302Sas200622 		(void) smb_dr_decode_finish(dec_ctx);
391*dc20a302Sas200622 		lmshrd_door_exit(arg, "decode error");
392da6c28aaSamw 		return (-1);
393da6c28aaSamw 	}
394da6c28aaSamw 
395da6c28aaSamw 	num_shares = smb_dr_get_uint32(dec_ctx);
396*dc20a302Sas200622 	if (smb_dr_decode_finish(dec_ctx) != 0) {
397*dc20a302Sas200622 		lmshrd_door_exit(arg, "decode error");
398da6c28aaSamw 		return (-1);
399da6c28aaSamw 	}
400da6c28aaSamw 
401*dc20a302Sas200622 	lmshrd_door_exit(arg, NULL);
402da6c28aaSamw 	return (num_shares);
403da6c28aaSamw }
404da6c28aaSamw 
405da6c28aaSamw DWORD
406da6c28aaSamw lmshrd_delete(char *share_name)
407da6c28aaSamw {
408*dc20a302Sas200622 	door_arg_t *arg;
409da6c28aaSamw 	smb_dr_ctx_t *dec_ctx;
410da6c28aaSamw 	smb_dr_ctx_t *enc_ctx;
411da6c28aaSamw 	DWORD rc;
412da6c28aaSamw 
413*dc20a302Sas200622 	if ((arg = lmshrd_door_enter()) == NULL)
414da6c28aaSamw 		return (NERR_InternalError);
415da6c28aaSamw 
416*dc20a302Sas200622 	enc_ctx = smb_dr_encode_start(arg->data_ptr, LMSHR_DOOR_SIZE);
417da6c28aaSamw 	smb_dr_put_uint32(enc_ctx, LMSHR_DOOR_DELETE);
418da6c28aaSamw 	smb_dr_put_string(enc_ctx, share_name);
419da6c28aaSamw 
420*dc20a302Sas200622 	rc = smb_dr_encode_finish(enc_ctx, (unsigned int *)&arg->data_size);
421*dc20a302Sas200622 	if (rc != 0) {
422*dc20a302Sas200622 		lmshrd_door_exit(arg, "encode error");
423da6c28aaSamw 		return (NERR_InternalError);
424da6c28aaSamw 	}
425da6c28aaSamw 
426*dc20a302Sas200622 	if (door_call(lmshrd_fildes, arg) < 0) {
427*dc20a302Sas200622 		lmshrd_door_exit(arg, "door call error");
428*dc20a302Sas200622 		lmshrd_door_close();
429da6c28aaSamw 		return (NERR_InternalError);
430da6c28aaSamw 	}
431da6c28aaSamw 
432*dc20a302Sas200622 	dec_ctx = smb_dr_decode_start(arg->data_ptr, arg->data_size);
433*dc20a302Sas200622 	if (lmshrd_door_check_status(dec_ctx) != 0) {
434*dc20a302Sas200622 		(void) smb_dr_decode_finish(dec_ctx);
435*dc20a302Sas200622 		lmshrd_door_exit(arg, "decode error");
436da6c28aaSamw 		return (NERR_InternalError);
437da6c28aaSamw 	}
438da6c28aaSamw 
439da6c28aaSamw 	rc = smb_dr_get_uint32(dec_ctx);
440*dc20a302Sas200622 	if (smb_dr_decode_finish(dec_ctx) != 0) {
441*dc20a302Sas200622 		lmshrd_door_exit(arg, "decode error");
442da6c28aaSamw 		return (NERR_InternalError);
443da6c28aaSamw 	}
444da6c28aaSamw 
445*dc20a302Sas200622 	lmshrd_door_exit(arg, NULL);
446da6c28aaSamw 	return (rc);
447da6c28aaSamw 
448da6c28aaSamw }
449da6c28aaSamw 
450da6c28aaSamw DWORD
451da6c28aaSamw lmshrd_rename(char *from, char *to)
452da6c28aaSamw {
453*dc20a302Sas200622 	door_arg_t *arg;
454da6c28aaSamw 	smb_dr_ctx_t *dec_ctx;
455da6c28aaSamw 	smb_dr_ctx_t *enc_ctx;
456da6c28aaSamw 	DWORD rc;
457da6c28aaSamw 
458*dc20a302Sas200622 	if ((arg = lmshrd_door_enter()) == NULL)
459da6c28aaSamw 		return (NERR_InternalError);
460da6c28aaSamw 
461*dc20a302Sas200622 	enc_ctx = smb_dr_encode_start(arg->data_ptr, LMSHR_DOOR_SIZE);
462da6c28aaSamw 	smb_dr_put_uint32(enc_ctx, LMSHR_DOOR_RENAME);
463da6c28aaSamw 	smb_dr_put_string(enc_ctx, from);
464da6c28aaSamw 	smb_dr_put_string(enc_ctx, to);
465da6c28aaSamw 
466*dc20a302Sas200622 	rc = smb_dr_encode_finish(enc_ctx, (unsigned int *)&arg->data_size);
467*dc20a302Sas200622 	if (rc != 0) {
468*dc20a302Sas200622 		lmshrd_door_exit(arg, "encode error");
469da6c28aaSamw 		return (NERR_InternalError);
470da6c28aaSamw 	}
471da6c28aaSamw 
472*dc20a302Sas200622 	if (door_call(lmshrd_fildes, arg) < 0) {
473*dc20a302Sas200622 		lmshrd_door_exit(arg, "door call error");
474*dc20a302Sas200622 		lmshrd_door_close();
475da6c28aaSamw 		return (NERR_InternalError);
476da6c28aaSamw 	}
477da6c28aaSamw 
478*dc20a302Sas200622 	dec_ctx = smb_dr_decode_start(arg->data_ptr, arg->data_size);
479*dc20a302Sas200622 	if (lmshrd_door_check_status(dec_ctx) != 0) {
480*dc20a302Sas200622 		(void) smb_dr_decode_finish(dec_ctx);
481*dc20a302Sas200622 		lmshrd_door_exit(arg, "decode error");
482da6c28aaSamw 		return (NERR_InternalError);
483da6c28aaSamw 	}
484da6c28aaSamw 
485da6c28aaSamw 	rc = smb_dr_get_uint32(dec_ctx);
486*dc20a302Sas200622 	if (smb_dr_decode_finish(dec_ctx) != 0) {
487*dc20a302Sas200622 		lmshrd_door_exit(arg, "decode error");
488da6c28aaSamw 		return (NERR_InternalError);
489da6c28aaSamw 	}
490da6c28aaSamw 
491*dc20a302Sas200622 	lmshrd_door_exit(arg, NULL);
492da6c28aaSamw 	return (rc);
493da6c28aaSamw }
494da6c28aaSamw 
495da6c28aaSamw DWORD
496da6c28aaSamw lmshrd_getinfo(char *share_name, lmshare_info_t *si)
497da6c28aaSamw {
498*dc20a302Sas200622 	door_arg_t *arg;
499da6c28aaSamw 	smb_dr_ctx_t *dec_ctx;
500da6c28aaSamw 	smb_dr_ctx_t *enc_ctx;
501da6c28aaSamw 	DWORD rc;
502da6c28aaSamw 
503*dc20a302Sas200622 	if ((arg = lmshrd_door_enter()) == NULL)
504da6c28aaSamw 		return (NERR_InternalError);
505da6c28aaSamw 
506*dc20a302Sas200622 	enc_ctx = smb_dr_encode_start(arg->data_ptr, LMSHR_DOOR_SIZE);
507da6c28aaSamw 	smb_dr_put_uint32(enc_ctx, LMSHR_DOOR_GETINFO);
508da6c28aaSamw 	smb_dr_put_string(enc_ctx, share_name);
509da6c28aaSamw 
510*dc20a302Sas200622 	rc = smb_dr_encode_finish(enc_ctx, (unsigned int *)&arg->data_size);
511*dc20a302Sas200622 	if (rc != 0) {
512*dc20a302Sas200622 		lmshrd_door_exit(arg, "encode error");
513da6c28aaSamw 		return (NERR_InternalError);
514da6c28aaSamw 	}
515da6c28aaSamw 
516*dc20a302Sas200622 	if (door_call(lmshrd_fildes, arg) < 0) {
517*dc20a302Sas200622 		lmshrd_door_exit(arg, "door call error");
518*dc20a302Sas200622 		lmshrd_door_close();
519da6c28aaSamw 		return (NERR_InternalError);
520da6c28aaSamw 	}
521da6c28aaSamw 
522*dc20a302Sas200622 	dec_ctx = smb_dr_decode_start(arg->data_ptr, arg->data_size);
523*dc20a302Sas200622 	if (lmshrd_door_check_status(dec_ctx) != 0) {
524*dc20a302Sas200622 		(void) smb_dr_decode_finish(dec_ctx);
525*dc20a302Sas200622 		lmshrd_door_exit(arg, "decode error");
526da6c28aaSamw 		return (NERR_InternalError);
527da6c28aaSamw 	}
528da6c28aaSamw 
529da6c28aaSamw 	rc = smb_dr_get_uint32(dec_ctx);
530da6c28aaSamw 	smb_dr_get_lmshare(dec_ctx, si);
531*dc20a302Sas200622 	if (smb_dr_decode_finish(dec_ctx) != 0) {
532*dc20a302Sas200622 		lmshrd_door_exit(arg, "decode error");
533da6c28aaSamw 		return (NERR_InternalError);
534da6c28aaSamw 	}
535da6c28aaSamw 
536*dc20a302Sas200622 	lmshrd_door_exit(arg, NULL);
537da6c28aaSamw 	return (rc);
538da6c28aaSamw }
539da6c28aaSamw 
540da6c28aaSamw DWORD
541da6c28aaSamw lmshrd_add(lmshare_info_t *si)
542da6c28aaSamw {
543*dc20a302Sas200622 	door_arg_t *arg;
544da6c28aaSamw 	smb_dr_ctx_t *dec_ctx;
545da6c28aaSamw 	smb_dr_ctx_t *enc_ctx;
546da6c28aaSamw 	DWORD rc;
547da6c28aaSamw 
548*dc20a302Sas200622 	if ((arg = lmshrd_door_enter()) == NULL)
549da6c28aaSamw 		return (NERR_InternalError);
550da6c28aaSamw 
551*dc20a302Sas200622 	enc_ctx = smb_dr_encode_start(arg->data_ptr, LMSHR_DOOR_SIZE);
552*dc20a302Sas200622 	smb_dr_put_uint32(enc_ctx, LMSHR_DOOR_ADD);
553da6c28aaSamw 	smb_dr_put_lmshare(enc_ctx, si);
554da6c28aaSamw 
555*dc20a302Sas200622 	rc = smb_dr_encode_finish(enc_ctx, (unsigned int *)&arg->data_size);
556*dc20a302Sas200622 	if (rc != 0) {
557*dc20a302Sas200622 		lmshrd_door_exit(arg, "encode error");
558da6c28aaSamw 		return (NERR_InternalError);
559da6c28aaSamw 	}
560da6c28aaSamw 
561*dc20a302Sas200622 	if (door_call(lmshrd_fildes, arg) < 0) {
562*dc20a302Sas200622 		lmshrd_door_exit(arg, "door call error");
563*dc20a302Sas200622 		lmshrd_door_close();
564da6c28aaSamw 		return (NERR_InternalError);
565da6c28aaSamw 	}
566da6c28aaSamw 
567*dc20a302Sas200622 	dec_ctx = smb_dr_decode_start(arg->data_ptr, arg->data_size);
568*dc20a302Sas200622 	if (lmshrd_door_check_status(dec_ctx) != 0) {
569*dc20a302Sas200622 		(void) smb_dr_decode_finish(dec_ctx);
570*dc20a302Sas200622 		lmshrd_door_exit(arg, "decode error");
571da6c28aaSamw 		return (NERR_InternalError);
572da6c28aaSamw 	}
573da6c28aaSamw 
574da6c28aaSamw 	rc = smb_dr_get_uint32(dec_ctx);
575da6c28aaSamw 	smb_dr_get_lmshare(dec_ctx, si);
576*dc20a302Sas200622 	if (smb_dr_decode_finish(dec_ctx) != 0) {
577*dc20a302Sas200622 		lmshrd_door_exit(arg, "decode error");
578da6c28aaSamw 		return (NERR_InternalError);
579da6c28aaSamw 	}
580da6c28aaSamw 
581*dc20a302Sas200622 	lmshrd_door_exit(arg, NULL);
582da6c28aaSamw 	return (rc);
583da6c28aaSamw }
584da6c28aaSamw 
585da6c28aaSamw DWORD
586da6c28aaSamw lmshrd_setinfo(lmshare_info_t *si)
587da6c28aaSamw {
588*dc20a302Sas200622 	door_arg_t *arg;
589da6c28aaSamw 	smb_dr_ctx_t *dec_ctx;
590da6c28aaSamw 	smb_dr_ctx_t *enc_ctx;
591da6c28aaSamw 	DWORD rc;
592da6c28aaSamw 
593*dc20a302Sas200622 	if ((arg = lmshrd_door_enter()) == NULL)
594da6c28aaSamw 		return (NERR_InternalError);
595da6c28aaSamw 
596*dc20a302Sas200622 	enc_ctx = smb_dr_encode_start(arg->data_ptr, LMSHR_DOOR_SIZE);
597*dc20a302Sas200622 	smb_dr_put_uint32(enc_ctx, LMSHR_DOOR_SETINFO);
598da6c28aaSamw 	smb_dr_put_lmshare(enc_ctx, si);
599da6c28aaSamw 
600*dc20a302Sas200622 	rc = smb_dr_encode_finish(enc_ctx, (unsigned int *)&arg->data_size);
601*dc20a302Sas200622 	if (rc != 0) {
602*dc20a302Sas200622 		lmshrd_door_exit(arg, "encode error");
603da6c28aaSamw 		return (NERR_InternalError);
604da6c28aaSamw 	}
605da6c28aaSamw 
606*dc20a302Sas200622 	if (door_call(lmshrd_fildes, arg) < 0) {
607*dc20a302Sas200622 		lmshrd_door_exit(arg, "door call error");
608*dc20a302Sas200622 		lmshrd_door_close();
609da6c28aaSamw 		return (NERR_InternalError);
610da6c28aaSamw 	}
611da6c28aaSamw 
612*dc20a302Sas200622 	dec_ctx = smb_dr_decode_start(arg->data_ptr, arg->data_size);
613*dc20a302Sas200622 	if (lmshrd_door_check_status(dec_ctx) != 0) {
614*dc20a302Sas200622 		(void) smb_dr_decode_finish(dec_ctx);
615*dc20a302Sas200622 		lmshrd_door_exit(arg, "decode error");
616da6c28aaSamw 		return (NERR_InternalError);
617da6c28aaSamw 	}
618da6c28aaSamw 
619da6c28aaSamw 	rc = smb_dr_get_uint32(dec_ctx);
620*dc20a302Sas200622 	if (smb_dr_decode_finish(dec_ctx) != 0) {
621*dc20a302Sas200622 		lmshrd_door_exit(arg, "decode error");
622da6c28aaSamw 		return (NERR_InternalError);
623da6c28aaSamw 	}
624da6c28aaSamw 
625*dc20a302Sas200622 	lmshrd_door_exit(arg, NULL);
626da6c28aaSamw 	return (rc);
627da6c28aaSamw }
628da6c28aaSamw 
629da6c28aaSamw static int
630da6c28aaSamw lmshrd_check(char *share_name, int opcode)
631da6c28aaSamw {
632*dc20a302Sas200622 	door_arg_t *arg;
633da6c28aaSamw 	smb_dr_ctx_t *dec_ctx;
634da6c28aaSamw 	smb_dr_ctx_t *enc_ctx;
635*dc20a302Sas200622 	int rc;
636da6c28aaSamw 
637*dc20a302Sas200622 	if ((arg = lmshrd_door_enter()) == NULL)
638da6c28aaSamw 		return (NERR_InternalError);
639da6c28aaSamw 
640*dc20a302Sas200622 	enc_ctx = smb_dr_encode_start(arg->data_ptr, LMSHR_DOOR_SIZE);
641da6c28aaSamw 	smb_dr_put_uint32(enc_ctx, opcode);
642da6c28aaSamw 	smb_dr_put_string(enc_ctx, share_name);
643da6c28aaSamw 
644*dc20a302Sas200622 	rc = smb_dr_encode_finish(enc_ctx, (unsigned int *)&arg->data_size);
645*dc20a302Sas200622 	if (rc != 0) {
646*dc20a302Sas200622 		lmshrd_door_exit(arg, "encode error");
647da6c28aaSamw 		return (NERR_InternalError);
648da6c28aaSamw 	}
649da6c28aaSamw 
650*dc20a302Sas200622 	if (door_call(lmshrd_fildes, arg) < 0) {
651*dc20a302Sas200622 		lmshrd_door_exit(arg, "door call error");
652*dc20a302Sas200622 		lmshrd_door_close();
653da6c28aaSamw 		return (NERR_InternalError);
654da6c28aaSamw 	}
655da6c28aaSamw 
656*dc20a302Sas200622 	dec_ctx = smb_dr_decode_start(arg->data_ptr, arg->data_size);
657*dc20a302Sas200622 	if (lmshrd_door_check_status(dec_ctx) != 0) {
658*dc20a302Sas200622 		(void) smb_dr_decode_finish(dec_ctx);
659*dc20a302Sas200622 		lmshrd_door_exit(arg, "decode error");
660da6c28aaSamw 		return (NERR_InternalError);
661da6c28aaSamw 	}
662da6c28aaSamw 
663da6c28aaSamw 	rc = smb_dr_get_int32(dec_ctx);
664*dc20a302Sas200622 	if (smb_dr_decode_finish(dec_ctx) != 0) {
665*dc20a302Sas200622 		lmshrd_door_exit(arg, "decode error");
666da6c28aaSamw 		return (NERR_InternalError);
667da6c28aaSamw 	}
668da6c28aaSamw 
669*dc20a302Sas200622 	lmshrd_door_exit(arg, NULL);
670da6c28aaSamw 	return (rc);
671da6c28aaSamw }
672da6c28aaSamw 
673da6c28aaSamw int
674da6c28aaSamw lmshrd_exists(char *share_name)
675da6c28aaSamw {
676da6c28aaSamw 	return (lmshrd_check(share_name, LMSHR_DOOR_EXISTS));
677da6c28aaSamw }
678da6c28aaSamw 
679da6c28aaSamw int
680da6c28aaSamw lmshrd_is_special(char *share_name)
681da6c28aaSamw {
682da6c28aaSamw 	return (lmshrd_check(share_name, LMSHR_DOOR_IS_SPECIAL));
683da6c28aaSamw }
684da6c28aaSamw 
685da6c28aaSamw int
686da6c28aaSamw lmshrd_is_restricted(char *share_name)
687da6c28aaSamw {
688da6c28aaSamw 	return (lmshrd_check(share_name, LMSHR_DOOR_IS_RESTRICTED));
689da6c28aaSamw }
690da6c28aaSamw 
691da6c28aaSamw int
692da6c28aaSamw lmshrd_is_admin(char *share_name)
693da6c28aaSamw {
694da6c28aaSamw 	return (lmshrd_check(share_name, LMSHR_DOOR_IS_ADMIN));
695da6c28aaSamw }
696da6c28aaSamw 
697da6c28aaSamw int
698da6c28aaSamw lmshrd_is_valid(char *share_name)
699da6c28aaSamw {
700da6c28aaSamw 	return (lmshrd_check(share_name, LMSHR_DOOR_IS_VALID));
701da6c28aaSamw }
702da6c28aaSamw 
703da6c28aaSamw int
704da6c28aaSamw lmshrd_is_dir(char *path)
705da6c28aaSamw {
706da6c28aaSamw 	return (lmshrd_check(path, LMSHR_DOOR_IS_DIR));
707da6c28aaSamw }
708