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