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 /*
23dc20a302Sas200622  * 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>
40dc20a302Sas200622 #include <unistd.h>
41dc20a302Sas200622 #include <thread.h>
42dc20a302Sas200622 #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 
50dc20a302Sas200622 static int lmshrd_fildes = -1;
51dc20a302Sas200622 static uint64_t lmshrd_door_ncall = 0;
52dc20a302Sas200622 static mutex_t lmshrd_mutex;
53dc20a302Sas200622 static cond_t lmshrd_cv;
54da6c28aaSamw 
55da6c28aaSamw char *lmshrd_desc[] = {
56da6c28aaSamw 	"",
57da6c28aaSamw 	"LmshrdNumShares",
58da6c28aaSamw 	"LmshrdDelete",
59da6c28aaSamw 	"LmshrdRename",
60da6c28aaSamw 	"LmshrdGetinfo",
61da6c28aaSamw 	"LmshrdAdd",
62da6c28aaSamw 	"LmshrdSetinfo",
63da6c28aaSamw 	"LmshrdExists",
64da6c28aaSamw 	"LmshrdIsSpecial",
65da6c28aaSamw 	"LmshrdIsRestricted",
66da6c28aaSamw 	"LmshrdIsAdmin",
67da6c28aaSamw 	"LmshrdIsValid",
68da6c28aaSamw 	"LmshrdIsDir",
69da6c28aaSamw 	"LmshrdList",
70da6c28aaSamw 	"LmshrdNumTrans",
71da6c28aaSamw 	"N/A",
72da6c28aaSamw 	0
73da6c28aaSamw };
74da6c28aaSamw 
75da6c28aaSamw /*
76dc20a302Sas200622  * Open the lmshrd door.  This is a private call for use by
77dc20a302Sas200622  * lmshrd_door_enter() and must be called with lmshrd_mutex held.
78dc20a302Sas200622  *
79dc20a302Sas200622  * Returns the door fd on success.  Otherwise, -1.
80da6c28aaSamw  */
81da6c28aaSamw static int
82dc20a302Sas200622 lmshrd_door_open(void)
83da6c28aaSamw {
84dc20a302Sas200622 	if (lmshrd_fildes == -1) {
85dc20a302Sas200622 		if ((lmshrd_fildes = open(LMSHR_DOOR_NAME, O_RDONLY)) < 0)
86dc20a302Sas200622 			lmshrd_fildes = -1;
87dc20a302Sas200622 		else
88dc20a302Sas200622 			lmshrd_door_ncall = 0;
89da6c28aaSamw 	}
90dc20a302Sas200622 
91dc20a302Sas200622 	return (lmshrd_fildes);
92dc20a302Sas200622 }
93dc20a302Sas200622 
94dc20a302Sas200622 /*
95dc20a302Sas200622  * Close the lmshrd door.
96dc20a302Sas200622  */
97dc20a302Sas200622 void
98dc20a302Sas200622 lmshrd_door_close(void)
99dc20a302Sas200622 {
100dc20a302Sas200622 	(void) mutex_lock(&lmshrd_mutex);
101dc20a302Sas200622 
102dc20a302Sas200622 	if (lmshrd_fildes != -1) {
103dc20a302Sas200622 		while (lmshrd_door_ncall > 0)
104dc20a302Sas200622 			(void) cond_wait(&lmshrd_cv, &lmshrd_mutex);
105dc20a302Sas200622 
106dc20a302Sas200622 		if (lmshrd_fildes != -1) {
107dc20a302Sas200622 			(void) close(lmshrd_fildes);
108dc20a302Sas200622 			lmshrd_fildes = -1;
109dc20a302Sas200622 		}
110dc20a302Sas200622 	}
111dc20a302Sas200622 
112dc20a302Sas200622 	(void) mutex_unlock(&lmshrd_mutex);
113dc20a302Sas200622 }
114dc20a302Sas200622 
115dc20a302Sas200622 /*
116dc20a302Sas200622  * Entry handler for lmshrd door calls.
117dc20a302Sas200622  */
118dc20a302Sas200622 static door_arg_t *
119dc20a302Sas200622 lmshrd_door_enter(void)
120dc20a302Sas200622 {
121dc20a302Sas200622 	door_arg_t *arg;
122dc20a302Sas200622 	char *buf;
123dc20a302Sas200622 
124dc20a302Sas200622 	(void) mutex_lock(&lmshrd_mutex);
125dc20a302Sas200622 
126dc20a302Sas200622 	if (lmshrd_door_open() == -1) {
127dc20a302Sas200622 		(void) mutex_unlock(&lmshrd_mutex);
128dc20a302Sas200622 		return (NULL);
129dc20a302Sas200622 	}
130dc20a302Sas200622 
131dc20a302Sas200622 	if ((arg = malloc(sizeof (door_arg_t) + LMSHR_DOOR_SIZE)) != NULL) {
132dc20a302Sas200622 		buf = ((char *)arg) + sizeof (door_arg_t);
133dc20a302Sas200622 		bzero(arg, sizeof (door_arg_t));
134dc20a302Sas200622 		arg->data_ptr = buf;
135dc20a302Sas200622 		arg->rbuf = buf;
136dc20a302Sas200622 		arg->rsize = LMSHR_DOOR_SIZE;
137dc20a302Sas200622 
138dc20a302Sas200622 		++lmshrd_door_ncall;
139dc20a302Sas200622 	}
140dc20a302Sas200622 
141dc20a302Sas200622 	(void) mutex_unlock(&lmshrd_mutex);
142dc20a302Sas200622 	return (arg);
143dc20a302Sas200622 }
144dc20a302Sas200622 
145dc20a302Sas200622 /*
146dc20a302Sas200622  * Exit handler for lmshrd door calls.
147dc20a302Sas200622  */
148dc20a302Sas200622 static void
149dc20a302Sas200622 lmshrd_door_exit(door_arg_t *arg, char *errmsg)
150dc20a302Sas200622 {
151dc20a302Sas200622 	if (errmsg)
152dc20a302Sas200622 		syslog(LOG_DEBUG, "lmshrd_door: %s", errmsg);
153dc20a302Sas200622 
154dc20a302Sas200622 	(void) mutex_lock(&lmshrd_mutex);
155dc20a302Sas200622 	free(arg);
156dc20a302Sas200622 	--lmshrd_door_ncall;
157dc20a302Sas200622 	(void) cond_signal(&lmshrd_cv);
158dc20a302Sas200622 	(void) mutex_unlock(&lmshrd_mutex);
159da6c28aaSamw }
160da6c28aaSamw 
161da6c28aaSamw /*
162da6c28aaSamw  * Return 0 upon success. Otherwise, -1.
163da6c28aaSamw  */
164da6c28aaSamw static int
165dc20a302Sas200622 lmshrd_door_check_status(smb_dr_ctx_t *dec_ctx)
166da6c28aaSamw {
167da6c28aaSamw 	int status = smb_dr_get_int32(dec_ctx);
168da6c28aaSamw 
169dc20a302Sas200622 	if (status != LMSHR_DOOR_SRV_SUCCESS) {
170dc20a302Sas200622 		if (status == LMSHR_DOOR_SRV_ERROR)
171dc20a302Sas200622 			(void) smb_dr_get_uint32(dec_ctx);
172dc20a302Sas200622 		return (-1);
173da6c28aaSamw 	}
174da6c28aaSamw 
175dc20a302Sas200622 	return (0);
176da6c28aaSamw }
177da6c28aaSamw 
178da6c28aaSamw DWORD
179da6c28aaSamw lmshrd_list(int offset, lmshare_list_t *list)
180da6c28aaSamw {
181dc20a302Sas200622 	door_arg_t *arg;
182da6c28aaSamw 	smb_dr_ctx_t *dec_ctx;
183da6c28aaSamw 	smb_dr_ctx_t *enc_ctx;
184da6c28aaSamw 	DWORD rc;
185da6c28aaSamw 
186dc20a302Sas200622 	if ((arg = lmshrd_door_enter()) == NULL)
187da6c28aaSamw 		return (NERR_InternalError);
188da6c28aaSamw 
189dc20a302Sas200622 	enc_ctx = smb_dr_encode_start(arg->data_ptr, LMSHR_DOOR_SIZE);
190dc20a302Sas200622 	smb_dr_put_uint32(enc_ctx, LMSHR_DOOR_LIST);
191da6c28aaSamw 	smb_dr_put_int32(enc_ctx, offset);
192da6c28aaSamw 
193dc20a302Sas200622 	rc = smb_dr_encode_finish(enc_ctx, (unsigned int *)&arg->data_size);
194dc20a302Sas200622 	if (rc != 0) {
195dc20a302Sas200622 		lmshrd_door_exit(arg, "encode error");
196da6c28aaSamw 		return (NERR_InternalError);
197da6c28aaSamw 	}
198da6c28aaSamw 
199dc20a302Sas200622 	if (door_call(lmshrd_fildes, arg) < 0) {
200dc20a302Sas200622 		lmshrd_door_exit(arg, "door call error");
201dc20a302Sas200622 		lmshrd_door_close();
202da6c28aaSamw 		return (NERR_InternalError);
203da6c28aaSamw 	}
204da6c28aaSamw 
205dc20a302Sas200622 	dec_ctx = smb_dr_decode_start(arg->data_ptr, arg->data_size);
206dc20a302Sas200622 	if (lmshrd_door_check_status(dec_ctx) != 0) {
207dc20a302Sas200622 		(void) smb_dr_decode_finish(dec_ctx);
208dc20a302Sas200622 		lmshrd_door_exit(arg, "decode error");
209da6c28aaSamw 		return (NERR_InternalError);
210da6c28aaSamw 	}
211da6c28aaSamw 
212da6c28aaSamw 	smb_dr_get_lmshr_list(dec_ctx, list);
213dc20a302Sas200622 	if (smb_dr_decode_finish(dec_ctx) != 0) {
214dc20a302Sas200622 		lmshrd_door_exit(arg, "decode error");
215da6c28aaSamw 		return (NERR_InternalError);
216da6c28aaSamw 	}
217da6c28aaSamw 
218dc20a302Sas200622 	lmshrd_door_exit(arg, NULL);
219*3ad684d6Sjb150015 	return (NERR_Success);
220da6c28aaSamw }
221da6c28aaSamw 
222da6c28aaSamw int
223da6c28aaSamw lmshrd_num_shares(void)
224da6c28aaSamw {
225dc20a302Sas200622 	door_arg_t *arg;
226da6c28aaSamw 	smb_dr_ctx_t *dec_ctx;
227da6c28aaSamw 	smb_dr_ctx_t *enc_ctx;
228da6c28aaSamw 	DWORD num_shares;
229dc20a302Sas200622 	int rc;
230da6c28aaSamw 
231dc20a302Sas200622 	if ((arg = lmshrd_door_enter()) == NULL)
232da6c28aaSamw 		return (-1);
233da6c28aaSamw 
234dc20a302Sas200622 	enc_ctx = smb_dr_encode_start(arg->data_ptr, LMSHR_DOOR_SIZE);
235da6c28aaSamw 	smb_dr_put_uint32(enc_ctx, LMSHR_DOOR_NUM_SHARES);
236dc20a302Sas200622 
237dc20a302Sas200622 	rc = smb_dr_encode_finish(enc_ctx, (unsigned int *)&arg->data_size);
238dc20a302Sas200622 	if (rc != 0) {
239dc20a302Sas200622 		lmshrd_door_exit(arg, "encode error");
240da6c28aaSamw 		return (-1);
241da6c28aaSamw 	}
242da6c28aaSamw 
243dc20a302Sas200622 	if (door_call(lmshrd_fildes, arg) < 0) {
244dc20a302Sas200622 		lmshrd_door_exit(arg, "door call error");
245dc20a302Sas200622 		lmshrd_door_close();
246da6c28aaSamw 		return (-1);
247da6c28aaSamw 	}
248da6c28aaSamw 
249dc20a302Sas200622 	dec_ctx = smb_dr_decode_start(arg->data_ptr, arg->data_size);
250dc20a302Sas200622 	if (lmshrd_door_check_status(dec_ctx) != 0) {
251dc20a302Sas200622 		(void) smb_dr_decode_finish(dec_ctx);
252dc20a302Sas200622 		lmshrd_door_exit(arg, "decode error");
253da6c28aaSamw 		return (-1);
254da6c28aaSamw 	}
255da6c28aaSamw 
256da6c28aaSamw 	num_shares = smb_dr_get_uint32(dec_ctx);
257dc20a302Sas200622 	if (smb_dr_decode_finish(dec_ctx) != 0) {
258dc20a302Sas200622 		lmshrd_door_exit(arg, "decode error");
259da6c28aaSamw 		return (-1);
260da6c28aaSamw 	}
261da6c28aaSamw 
262dc20a302Sas200622 	lmshrd_door_exit(arg, NULL);
263da6c28aaSamw 	return (num_shares);
264da6c28aaSamw }
265da6c28aaSamw 
266da6c28aaSamw DWORD
267da6c28aaSamw lmshrd_delete(char *share_name)
268da6c28aaSamw {
269dc20a302Sas200622 	door_arg_t *arg;
270da6c28aaSamw 	smb_dr_ctx_t *dec_ctx;
271da6c28aaSamw 	smb_dr_ctx_t *enc_ctx;
272da6c28aaSamw 	DWORD rc;
273da6c28aaSamw 
274dc20a302Sas200622 	if ((arg = lmshrd_door_enter()) == NULL)
275da6c28aaSamw 		return (NERR_InternalError);
276da6c28aaSamw 
277dc20a302Sas200622 	enc_ctx = smb_dr_encode_start(arg->data_ptr, LMSHR_DOOR_SIZE);
278da6c28aaSamw 	smb_dr_put_uint32(enc_ctx, LMSHR_DOOR_DELETE);
279da6c28aaSamw 	smb_dr_put_string(enc_ctx, share_name);
280da6c28aaSamw 
281dc20a302Sas200622 	rc = smb_dr_encode_finish(enc_ctx, (unsigned int *)&arg->data_size);
282dc20a302Sas200622 	if (rc != 0) {
283dc20a302Sas200622 		lmshrd_door_exit(arg, "encode error");
284da6c28aaSamw 		return (NERR_InternalError);
285da6c28aaSamw 	}
286da6c28aaSamw 
287dc20a302Sas200622 	if (door_call(lmshrd_fildes, arg) < 0) {
288dc20a302Sas200622 		lmshrd_door_exit(arg, "door call error");
289dc20a302Sas200622 		lmshrd_door_close();
290da6c28aaSamw 		return (NERR_InternalError);
291da6c28aaSamw 	}
292da6c28aaSamw 
293dc20a302Sas200622 	dec_ctx = smb_dr_decode_start(arg->data_ptr, arg->data_size);
294dc20a302Sas200622 	if (lmshrd_door_check_status(dec_ctx) != 0) {
295dc20a302Sas200622 		(void) smb_dr_decode_finish(dec_ctx);
296dc20a302Sas200622 		lmshrd_door_exit(arg, "decode error");
297da6c28aaSamw 		return (NERR_InternalError);
298da6c28aaSamw 	}
299da6c28aaSamw 
300da6c28aaSamw 	rc = smb_dr_get_uint32(dec_ctx);
301dc20a302Sas200622 	if (smb_dr_decode_finish(dec_ctx) != 0) {
302dc20a302Sas200622 		lmshrd_door_exit(arg, "decode error");
303da6c28aaSamw 		return (NERR_InternalError);
304da6c28aaSamw 	}
305da6c28aaSamw 
306dc20a302Sas200622 	lmshrd_door_exit(arg, NULL);
307da6c28aaSamw 	return (rc);
308da6c28aaSamw 
309da6c28aaSamw }
310da6c28aaSamw 
311da6c28aaSamw DWORD
312da6c28aaSamw lmshrd_rename(char *from, char *to)
313da6c28aaSamw {
314dc20a302Sas200622 	door_arg_t *arg;
315da6c28aaSamw 	smb_dr_ctx_t *dec_ctx;
316da6c28aaSamw 	smb_dr_ctx_t *enc_ctx;
317da6c28aaSamw 	DWORD rc;
318da6c28aaSamw 
319dc20a302Sas200622 	if ((arg = lmshrd_door_enter()) == NULL)
320da6c28aaSamw 		return (NERR_InternalError);
321da6c28aaSamw 
322dc20a302Sas200622 	enc_ctx = smb_dr_encode_start(arg->data_ptr, LMSHR_DOOR_SIZE);
323da6c28aaSamw 	smb_dr_put_uint32(enc_ctx, LMSHR_DOOR_RENAME);
324da6c28aaSamw 	smb_dr_put_string(enc_ctx, from);
325da6c28aaSamw 	smb_dr_put_string(enc_ctx, to);
326da6c28aaSamw 
327dc20a302Sas200622 	rc = smb_dr_encode_finish(enc_ctx, (unsigned int *)&arg->data_size);
328dc20a302Sas200622 	if (rc != 0) {
329dc20a302Sas200622 		lmshrd_door_exit(arg, "encode error");
330da6c28aaSamw 		return (NERR_InternalError);
331da6c28aaSamw 	}
332da6c28aaSamw 
333dc20a302Sas200622 	if (door_call(lmshrd_fildes, arg) < 0) {
334dc20a302Sas200622 		lmshrd_door_exit(arg, "door call error");
335dc20a302Sas200622 		lmshrd_door_close();
336da6c28aaSamw 		return (NERR_InternalError);
337da6c28aaSamw 	}
338da6c28aaSamw 
339dc20a302Sas200622 	dec_ctx = smb_dr_decode_start(arg->data_ptr, arg->data_size);
340dc20a302Sas200622 	if (lmshrd_door_check_status(dec_ctx) != 0) {
341dc20a302Sas200622 		(void) smb_dr_decode_finish(dec_ctx);
342dc20a302Sas200622 		lmshrd_door_exit(arg, "decode error");
343da6c28aaSamw 		return (NERR_InternalError);
344da6c28aaSamw 	}
345da6c28aaSamw 
346da6c28aaSamw 	rc = smb_dr_get_uint32(dec_ctx);
347dc20a302Sas200622 	if (smb_dr_decode_finish(dec_ctx) != 0) {
348dc20a302Sas200622 		lmshrd_door_exit(arg, "decode error");
349da6c28aaSamw 		return (NERR_InternalError);
350da6c28aaSamw 	}
351da6c28aaSamw 
352dc20a302Sas200622 	lmshrd_door_exit(arg, NULL);
353da6c28aaSamw 	return (rc);
354da6c28aaSamw }
355da6c28aaSamw 
356da6c28aaSamw DWORD
357da6c28aaSamw lmshrd_getinfo(char *share_name, lmshare_info_t *si)
358da6c28aaSamw {
359dc20a302Sas200622 	door_arg_t *arg;
360da6c28aaSamw 	smb_dr_ctx_t *dec_ctx;
361da6c28aaSamw 	smb_dr_ctx_t *enc_ctx;
362da6c28aaSamw 	DWORD rc;
363da6c28aaSamw 
364dc20a302Sas200622 	if ((arg = lmshrd_door_enter()) == NULL)
365da6c28aaSamw 		return (NERR_InternalError);
366da6c28aaSamw 
367dc20a302Sas200622 	enc_ctx = smb_dr_encode_start(arg->data_ptr, LMSHR_DOOR_SIZE);
368da6c28aaSamw 	smb_dr_put_uint32(enc_ctx, LMSHR_DOOR_GETINFO);
369da6c28aaSamw 	smb_dr_put_string(enc_ctx, share_name);
370da6c28aaSamw 
371dc20a302Sas200622 	rc = smb_dr_encode_finish(enc_ctx, (unsigned int *)&arg->data_size);
372dc20a302Sas200622 	if (rc != 0) {
373dc20a302Sas200622 		lmshrd_door_exit(arg, "encode error");
374da6c28aaSamw 		return (NERR_InternalError);
375da6c28aaSamw 	}
376da6c28aaSamw 
377dc20a302Sas200622 	if (door_call(lmshrd_fildes, arg) < 0) {
378dc20a302Sas200622 		lmshrd_door_exit(arg, "door call error");
379dc20a302Sas200622 		lmshrd_door_close();
380da6c28aaSamw 		return (NERR_InternalError);
381da6c28aaSamw 	}
382da6c28aaSamw 
383dc20a302Sas200622 	dec_ctx = smb_dr_decode_start(arg->data_ptr, arg->data_size);
384dc20a302Sas200622 	if (lmshrd_door_check_status(dec_ctx) != 0) {
385dc20a302Sas200622 		(void) smb_dr_decode_finish(dec_ctx);
386dc20a302Sas200622 		lmshrd_door_exit(arg, "decode error");
387da6c28aaSamw 		return (NERR_InternalError);
388da6c28aaSamw 	}
389da6c28aaSamw 
390da6c28aaSamw 	rc = smb_dr_get_uint32(dec_ctx);
391da6c28aaSamw 	smb_dr_get_lmshare(dec_ctx, si);
392dc20a302Sas200622 	if (smb_dr_decode_finish(dec_ctx) != 0) {
393dc20a302Sas200622 		lmshrd_door_exit(arg, "decode error");
394da6c28aaSamw 		return (NERR_InternalError);
395da6c28aaSamw 	}
396da6c28aaSamw 
397dc20a302Sas200622 	lmshrd_door_exit(arg, NULL);
398da6c28aaSamw 	return (rc);
399da6c28aaSamw }
400da6c28aaSamw 
401da6c28aaSamw DWORD
402da6c28aaSamw lmshrd_add(lmshare_info_t *si)
403da6c28aaSamw {
404dc20a302Sas200622 	door_arg_t *arg;
405da6c28aaSamw 	smb_dr_ctx_t *dec_ctx;
406da6c28aaSamw 	smb_dr_ctx_t *enc_ctx;
407da6c28aaSamw 	DWORD rc;
408da6c28aaSamw 
409dc20a302Sas200622 	if ((arg = lmshrd_door_enter()) == NULL)
410da6c28aaSamw 		return (NERR_InternalError);
411da6c28aaSamw 
412dc20a302Sas200622 	enc_ctx = smb_dr_encode_start(arg->data_ptr, LMSHR_DOOR_SIZE);
413dc20a302Sas200622 	smb_dr_put_uint32(enc_ctx, LMSHR_DOOR_ADD);
414da6c28aaSamw 	smb_dr_put_lmshare(enc_ctx, si);
415da6c28aaSamw 
416dc20a302Sas200622 	rc = smb_dr_encode_finish(enc_ctx, (unsigned int *)&arg->data_size);
417dc20a302Sas200622 	if (rc != 0) {
418dc20a302Sas200622 		lmshrd_door_exit(arg, "encode error");
419da6c28aaSamw 		return (NERR_InternalError);
420da6c28aaSamw 	}
421da6c28aaSamw 
422dc20a302Sas200622 	if (door_call(lmshrd_fildes, arg) < 0) {
423dc20a302Sas200622 		lmshrd_door_exit(arg, "door call error");
424dc20a302Sas200622 		lmshrd_door_close();
425da6c28aaSamw 		return (NERR_InternalError);
426da6c28aaSamw 	}
427da6c28aaSamw 
428dc20a302Sas200622 	dec_ctx = smb_dr_decode_start(arg->data_ptr, arg->data_size);
429dc20a302Sas200622 	if (lmshrd_door_check_status(dec_ctx) != 0) {
430dc20a302Sas200622 		(void) smb_dr_decode_finish(dec_ctx);
431dc20a302Sas200622 		lmshrd_door_exit(arg, "decode error");
432da6c28aaSamw 		return (NERR_InternalError);
433da6c28aaSamw 	}
434da6c28aaSamw 
435da6c28aaSamw 	rc = smb_dr_get_uint32(dec_ctx);
436da6c28aaSamw 	smb_dr_get_lmshare(dec_ctx, si);
437dc20a302Sas200622 	if (smb_dr_decode_finish(dec_ctx) != 0) {
438dc20a302Sas200622 		lmshrd_door_exit(arg, "decode error");
439da6c28aaSamw 		return (NERR_InternalError);
440da6c28aaSamw 	}
441da6c28aaSamw 
442dc20a302Sas200622 	lmshrd_door_exit(arg, NULL);
443da6c28aaSamw 	return (rc);
444da6c28aaSamw }
445da6c28aaSamw 
446da6c28aaSamw DWORD
447da6c28aaSamw lmshrd_setinfo(lmshare_info_t *si)
448da6c28aaSamw {
449dc20a302Sas200622 	door_arg_t *arg;
450da6c28aaSamw 	smb_dr_ctx_t *dec_ctx;
451da6c28aaSamw 	smb_dr_ctx_t *enc_ctx;
452da6c28aaSamw 	DWORD rc;
453da6c28aaSamw 
454dc20a302Sas200622 	if ((arg = lmshrd_door_enter()) == NULL)
455da6c28aaSamw 		return (NERR_InternalError);
456da6c28aaSamw 
457dc20a302Sas200622 	enc_ctx = smb_dr_encode_start(arg->data_ptr, LMSHR_DOOR_SIZE);
458dc20a302Sas200622 	smb_dr_put_uint32(enc_ctx, LMSHR_DOOR_SETINFO);
459da6c28aaSamw 	smb_dr_put_lmshare(enc_ctx, si);
460da6c28aaSamw 
461dc20a302Sas200622 	rc = smb_dr_encode_finish(enc_ctx, (unsigned int *)&arg->data_size);
462dc20a302Sas200622 	if (rc != 0) {
463dc20a302Sas200622 		lmshrd_door_exit(arg, "encode error");
464da6c28aaSamw 		return (NERR_InternalError);
465da6c28aaSamw 	}
466da6c28aaSamw 
467dc20a302Sas200622 	if (door_call(lmshrd_fildes, arg) < 0) {
468dc20a302Sas200622 		lmshrd_door_exit(arg, "door call error");
469dc20a302Sas200622 		lmshrd_door_close();
470da6c28aaSamw 		return (NERR_InternalError);
471da6c28aaSamw 	}
472da6c28aaSamw 
473dc20a302Sas200622 	dec_ctx = smb_dr_decode_start(arg->data_ptr, arg->data_size);
474dc20a302Sas200622 	if (lmshrd_door_check_status(dec_ctx) != 0) {
475dc20a302Sas200622 		(void) smb_dr_decode_finish(dec_ctx);
476dc20a302Sas200622 		lmshrd_door_exit(arg, "decode error");
477da6c28aaSamw 		return (NERR_InternalError);
478da6c28aaSamw 	}
479da6c28aaSamw 
480da6c28aaSamw 	rc = smb_dr_get_uint32(dec_ctx);
481dc20a302Sas200622 	if (smb_dr_decode_finish(dec_ctx) != 0) {
482dc20a302Sas200622 		lmshrd_door_exit(arg, "decode error");
483da6c28aaSamw 		return (NERR_InternalError);
484da6c28aaSamw 	}
485da6c28aaSamw 
486dc20a302Sas200622 	lmshrd_door_exit(arg, NULL);
487da6c28aaSamw 	return (rc);
488da6c28aaSamw }
489da6c28aaSamw 
490da6c28aaSamw static int
491da6c28aaSamw lmshrd_check(char *share_name, int opcode)
492da6c28aaSamw {
493dc20a302Sas200622 	door_arg_t *arg;
494da6c28aaSamw 	smb_dr_ctx_t *dec_ctx;
495da6c28aaSamw 	smb_dr_ctx_t *enc_ctx;
496dc20a302Sas200622 	int rc;
497da6c28aaSamw 
498dc20a302Sas200622 	if ((arg = lmshrd_door_enter()) == NULL)
499da6c28aaSamw 		return (NERR_InternalError);
500da6c28aaSamw 
501dc20a302Sas200622 	enc_ctx = smb_dr_encode_start(arg->data_ptr, LMSHR_DOOR_SIZE);
502da6c28aaSamw 	smb_dr_put_uint32(enc_ctx, opcode);
503da6c28aaSamw 	smb_dr_put_string(enc_ctx, share_name);
504da6c28aaSamw 
505dc20a302Sas200622 	rc = smb_dr_encode_finish(enc_ctx, (unsigned int *)&arg->data_size);
506dc20a302Sas200622 	if (rc != 0) {
507dc20a302Sas200622 		lmshrd_door_exit(arg, "encode error");
508da6c28aaSamw 		return (NERR_InternalError);
509da6c28aaSamw 	}
510da6c28aaSamw 
511dc20a302Sas200622 	if (door_call(lmshrd_fildes, arg) < 0) {
512dc20a302Sas200622 		lmshrd_door_exit(arg, "door call error");
513dc20a302Sas200622 		lmshrd_door_close();
514da6c28aaSamw 		return (NERR_InternalError);
515da6c28aaSamw 	}
516da6c28aaSamw 
517dc20a302Sas200622 	dec_ctx = smb_dr_decode_start(arg->data_ptr, arg->data_size);
518dc20a302Sas200622 	if (lmshrd_door_check_status(dec_ctx) != 0) {
519dc20a302Sas200622 		(void) smb_dr_decode_finish(dec_ctx);
520dc20a302Sas200622 		lmshrd_door_exit(arg, "decode error");
521da6c28aaSamw 		return (NERR_InternalError);
522da6c28aaSamw 	}
523da6c28aaSamw 
524da6c28aaSamw 	rc = smb_dr_get_int32(dec_ctx);
525dc20a302Sas200622 	if (smb_dr_decode_finish(dec_ctx) != 0) {
526dc20a302Sas200622 		lmshrd_door_exit(arg, "decode error");
527da6c28aaSamw 		return (NERR_InternalError);
528da6c28aaSamw 	}
529da6c28aaSamw 
530dc20a302Sas200622 	lmshrd_door_exit(arg, NULL);
531da6c28aaSamw 	return (rc);
532da6c28aaSamw }
533da6c28aaSamw 
534da6c28aaSamw int
535da6c28aaSamw lmshrd_exists(char *share_name)
536da6c28aaSamw {
537da6c28aaSamw 	return (lmshrd_check(share_name, LMSHR_DOOR_EXISTS));
538da6c28aaSamw }
539da6c28aaSamw 
540da6c28aaSamw int
541da6c28aaSamw lmshrd_is_special(char *share_name)
542da6c28aaSamw {
543da6c28aaSamw 	return (lmshrd_check(share_name, LMSHR_DOOR_IS_SPECIAL));
544da6c28aaSamw }
545da6c28aaSamw 
546da6c28aaSamw int
547da6c28aaSamw lmshrd_is_restricted(char *share_name)
548da6c28aaSamw {
549da6c28aaSamw 	return (lmshrd_check(share_name, LMSHR_DOOR_IS_RESTRICTED));
550da6c28aaSamw }
551da6c28aaSamw 
552da6c28aaSamw int
553da6c28aaSamw lmshrd_is_admin(char *share_name)
554da6c28aaSamw {
555da6c28aaSamw 	return (lmshrd_check(share_name, LMSHR_DOOR_IS_ADMIN));
556da6c28aaSamw }
557da6c28aaSamw 
558da6c28aaSamw int
559da6c28aaSamw lmshrd_is_valid(char *share_name)
560da6c28aaSamw {
561da6c28aaSamw 	return (lmshrd_check(share_name, LMSHR_DOOR_IS_VALID));
562da6c28aaSamw }
563da6c28aaSamw 
564da6c28aaSamw int
565da6c28aaSamw lmshrd_is_dir(char *path)
566da6c28aaSamw {
567da6c28aaSamw 	return (lmshrd_check(path, LMSHR_DOOR_IS_DIR));
568da6c28aaSamw }
569