1*da6c28aaSamw /*
2*da6c28aaSamw  * CDDL HEADER START
3*da6c28aaSamw  *
4*da6c28aaSamw  * The contents of this file are subject to the terms of the
5*da6c28aaSamw  * Common Development and Distribution License (the "License").
6*da6c28aaSamw  * You may not use this file except in compliance with the License.
7*da6c28aaSamw  *
8*da6c28aaSamw  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*da6c28aaSamw  * or http://www.opensolaris.org/os/licensing.
10*da6c28aaSamw  * See the License for the specific language governing permissions
11*da6c28aaSamw  * and limitations under the License.
12*da6c28aaSamw  *
13*da6c28aaSamw  * When distributing Covered Code, include this CDDL HEADER in each
14*da6c28aaSamw  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*da6c28aaSamw  * If applicable, add the following below this CDDL HEADER, with the
16*da6c28aaSamw  * fields enclosed by brackets "[]" replaced with your own identifying
17*da6c28aaSamw  * information: Portions Copyright [yyyy] [name of copyright owner]
18*da6c28aaSamw  *
19*da6c28aaSamw  * CDDL HEADER END
20*da6c28aaSamw  */
21*da6c28aaSamw 
22*da6c28aaSamw /*
23*da6c28aaSamw  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24*da6c28aaSamw  * Use is subject to license terms.
25*da6c28aaSamw  */
26*da6c28aaSamw 
27*da6c28aaSamw #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*da6c28aaSamw 
29*da6c28aaSamw /*
30*da6c28aaSamw  * User-space door client for LanMan share management.
31*da6c28aaSamw  */
32*da6c28aaSamw 
33*da6c28aaSamw #include <syslog.h>
34*da6c28aaSamw #include <door.h>
35*da6c28aaSamw #include <fcntl.h>
36*da6c28aaSamw #include <stdarg.h>
37*da6c28aaSamw #include <errno.h>
38*da6c28aaSamw #include <string.h>
39*da6c28aaSamw #include <strings.h>
40*da6c28aaSamw 
41*da6c28aaSamw #include <smbsrv/libsmb.h>
42*da6c28aaSamw 
43*da6c28aaSamw #include <smbsrv/lmshare.h>
44*da6c28aaSamw #include <smbsrv/lmerr.h>
45*da6c28aaSamw #include <smbsrv/lmshare_door.h>
46*da6c28aaSamw #include <smbsrv/cifs.h>
47*da6c28aaSamw 
48*da6c28aaSamw int lmshrd_fildes = -1;
49*da6c28aaSamw 
50*da6c28aaSamw char *lmshrd_desc[] = {
51*da6c28aaSamw 	"",
52*da6c28aaSamw 	"LmshrdOpenIter",
53*da6c28aaSamw 	"LmshrdCloseIter",
54*da6c28aaSamw 	"LmshrdIterate",
55*da6c28aaSamw 	"LmshrdNumShares",
56*da6c28aaSamw 	"LmshrdDelete",
57*da6c28aaSamw 	"LmshrdRename",
58*da6c28aaSamw 	"LmshrdGetinfo",
59*da6c28aaSamw 	"LmshrdAdd",
60*da6c28aaSamw 	"LmshrdSetinfo",
61*da6c28aaSamw 	"LmshrdExists",
62*da6c28aaSamw 	"LmshrdIsSpecial",
63*da6c28aaSamw 	"LmshrdIsRestricted",
64*da6c28aaSamw 	"LmshrdIsAdmin",
65*da6c28aaSamw 	"LmshrdIsValid",
66*da6c28aaSamw 	"LmshrdIsDir",
67*da6c28aaSamw 	"LmshrdList",
68*da6c28aaSamw 	"LmshrdListTrans",
69*da6c28aaSamw 	"LmshrdNumTrans",
70*da6c28aaSamw 	"N/A",
71*da6c28aaSamw 	0
72*da6c28aaSamw };
73*da6c28aaSamw 
74*da6c28aaSamw /*
75*da6c28aaSamw  * Returns 0 on success. Otherwise, -1.
76*da6c28aaSamw  */
77*da6c28aaSamw static int
78*da6c28aaSamw lmshrd_door_open(int opcode)
79*da6c28aaSamw {
80*da6c28aaSamw 	int rc = 0;
81*da6c28aaSamw 
82*da6c28aaSamw 	if (lmshrd_fildes == -1 &&
83*da6c28aaSamw 	    (lmshrd_fildes = open(LMSHR_DOOR_NAME, O_RDONLY)) < 0) {
84*da6c28aaSamw 		syslog(LOG_DEBUG, "%s: open %s failed %s", lmshrd_desc[opcode],
85*da6c28aaSamw 		    LMSHR_DOOR_NAME, strerror(errno));
86*da6c28aaSamw 		rc = -1;
87*da6c28aaSamw 	}
88*da6c28aaSamw 	return (rc);
89*da6c28aaSamw }
90*da6c28aaSamw 
91*da6c28aaSamw /*
92*da6c28aaSamw  * Return 0 upon success. Otherwise, -1.
93*da6c28aaSamw  */
94*da6c28aaSamw static int
95*da6c28aaSamw lmshrd_door_check_srv_status(int opcode, smb_dr_ctx_t *dec_ctx)
96*da6c28aaSamw {
97*da6c28aaSamw 	int status = smb_dr_get_int32(dec_ctx);
98*da6c28aaSamw 	int err;
99*da6c28aaSamw 	int rc = -1;
100*da6c28aaSamw 
101*da6c28aaSamw 	switch (status) {
102*da6c28aaSamw 	case LMSHR_DOOR_SRV_SUCCESS:
103*da6c28aaSamw 		rc = 0;
104*da6c28aaSamw 		break;
105*da6c28aaSamw 
106*da6c28aaSamw 	case LMSHR_DOOR_SRV_ERROR:
107*da6c28aaSamw 		err = smb_dr_get_uint32(dec_ctx);
108*da6c28aaSamw 		syslog(LOG_ERR, "%s: Encountered door server error %s",
109*da6c28aaSamw 		    lmshrd_desc[opcode], strerror(err));
110*da6c28aaSamw 		break;
111*da6c28aaSamw 
112*da6c28aaSamw 	default:
113*da6c28aaSamw 		syslog(LOG_ERR, "%s: Unknown door server status",
114*da6c28aaSamw 		    lmshrd_desc[opcode]);
115*da6c28aaSamw 	}
116*da6c28aaSamw 
117*da6c28aaSamw 	if (rc != 0) {
118*da6c28aaSamw 		if ((err = smb_dr_decode_finish(dec_ctx)) != 0)
119*da6c28aaSamw 			syslog(LOG_ERR, "%s: Decode error %s",
120*da6c28aaSamw 			    lmshrd_desc[opcode], strerror(err));
121*da6c28aaSamw 	}
122*da6c28aaSamw 
123*da6c28aaSamw 	return (rc);
124*da6c28aaSamw }
125*da6c28aaSamw 
126*da6c28aaSamw uint64_t
127*da6c28aaSamw lmshrd_open_iterator(int mode)
128*da6c28aaSamw {
129*da6c28aaSamw 	door_arg_t arg;
130*da6c28aaSamw 	char *buf;
131*da6c28aaSamw 	unsigned int used;
132*da6c28aaSamw 	smb_dr_ctx_t *dec_ctx;
133*da6c28aaSamw 	smb_dr_ctx_t *enc_ctx;
134*da6c28aaSamw 	unsigned int status = 0;
135*da6c28aaSamw 	uint64_t lmshr_iter = 0;
136*da6c28aaSamw 	int opcode = LMSHR_DOOR_OPEN_ITERATOR;
137*da6c28aaSamw 
138*da6c28aaSamw 	if (lmshrd_door_open(opcode) == -1)
139*da6c28aaSamw 		return (lmshr_iter);
140*da6c28aaSamw 
141*da6c28aaSamw 	buf = malloc(LMSHR_DOOR_SIZE);
142*da6c28aaSamw 	if (!buf)
143*da6c28aaSamw 		return (lmshr_iter);
144*da6c28aaSamw 
145*da6c28aaSamw 	enc_ctx = smb_dr_encode_start(buf, LMSHR_DOOR_SIZE);
146*da6c28aaSamw 	smb_dr_put_uint32(enc_ctx, opcode);
147*da6c28aaSamw 	smb_dr_put_int32(enc_ctx, mode);
148*da6c28aaSamw 	if ((status = smb_dr_encode_finish(enc_ctx, &used)) != 0) {
149*da6c28aaSamw 		syslog(LOG_ERR, "%s: Encode error %s",
150*da6c28aaSamw 		    lmshrd_desc[opcode], strerror(status));
151*da6c28aaSamw 		(void) free(buf);
152*da6c28aaSamw 		return (lmshr_iter);
153*da6c28aaSamw 	}
154*da6c28aaSamw 
155*da6c28aaSamw 	arg.data_ptr = buf;
156*da6c28aaSamw 	arg.data_size = used;
157*da6c28aaSamw 	arg.desc_ptr = NULL;
158*da6c28aaSamw 	arg.desc_num = 0;
159*da6c28aaSamw 	arg.rbuf = buf;
160*da6c28aaSamw 	arg.rsize = LMSHR_DOOR_SIZE;
161*da6c28aaSamw 
162*da6c28aaSamw 	if (door_call(lmshrd_fildes, &arg) < 0) {
163*da6c28aaSamw 		syslog(LOG_DEBUG, "%s: Door call failed %s",
164*da6c28aaSamw 		    lmshrd_desc[opcode], strerror(errno));
165*da6c28aaSamw 		(void) free(buf);
166*da6c28aaSamw 		lmshrd_fildes = -1;
167*da6c28aaSamw 		return (lmshr_iter);
168*da6c28aaSamw 	}
169*da6c28aaSamw 
170*da6c28aaSamw 	dec_ctx = smb_dr_decode_start(arg.data_ptr, arg.data_size);
171*da6c28aaSamw 	if (lmshrd_door_check_srv_status(opcode, dec_ctx) != 0) {
172*da6c28aaSamw 		(void) free(buf);
173*da6c28aaSamw 		return (lmshr_iter);
174*da6c28aaSamw 	}
175*da6c28aaSamw 
176*da6c28aaSamw 	lmshr_iter = smb_dr_get_lmshr_iterator(dec_ctx);
177*da6c28aaSamw 	if ((status = smb_dr_decode_finish(dec_ctx)) != 0) {
178*da6c28aaSamw 		syslog(LOG_ERR, "%s: Decode error %s",
179*da6c28aaSamw 		    lmshrd_desc[opcode], strerror(status));
180*da6c28aaSamw 		(void) free(buf);
181*da6c28aaSamw 		return (lmshr_iter);
182*da6c28aaSamw 	}
183*da6c28aaSamw 
184*da6c28aaSamw 	(void) free(buf);
185*da6c28aaSamw 	return (lmshr_iter);
186*da6c28aaSamw }
187*da6c28aaSamw 
188*da6c28aaSamw 
189*da6c28aaSamw DWORD
190*da6c28aaSamw lmshrd_close_iterator(uint64_t iterator)
191*da6c28aaSamw {
192*da6c28aaSamw 	door_arg_t arg;
193*da6c28aaSamw 	char *buf;
194*da6c28aaSamw 	unsigned int used;
195*da6c28aaSamw 	smb_dr_ctx_t *dec_ctx;
196*da6c28aaSamw 	smb_dr_ctx_t *enc_ctx;
197*da6c28aaSamw 	unsigned int status = 0;
198*da6c28aaSamw 	int opcode = LMSHR_DOOR_CLOSE_ITERATOR;
199*da6c28aaSamw 
200*da6c28aaSamw 	if (lmshrd_door_open(opcode) == -1)
201*da6c28aaSamw 		return (NERR_InternalError);
202*da6c28aaSamw 
203*da6c28aaSamw 	buf = malloc(LMSHR_DOOR_SIZE);
204*da6c28aaSamw 	if (!buf)
205*da6c28aaSamw 		return (NERR_InternalError);
206*da6c28aaSamw 
207*da6c28aaSamw 	enc_ctx = smb_dr_encode_start(buf, LMSHR_DOOR_SIZE);
208*da6c28aaSamw 	smb_dr_put_uint32(enc_ctx, opcode);
209*da6c28aaSamw 	smb_dr_put_lmshr_iterator(enc_ctx, iterator);
210*da6c28aaSamw 	if ((status = smb_dr_encode_finish(enc_ctx, &used)) != 0) {
211*da6c28aaSamw 		syslog(LOG_ERR, "%s: Encode error %s",
212*da6c28aaSamw 		    lmshrd_desc[opcode], strerror(status));
213*da6c28aaSamw 		(void) free(buf);
214*da6c28aaSamw 		return (NERR_InternalError);
215*da6c28aaSamw 	}
216*da6c28aaSamw 
217*da6c28aaSamw 	arg.data_ptr = buf;
218*da6c28aaSamw 	arg.data_size = used;
219*da6c28aaSamw 	arg.desc_ptr = NULL;
220*da6c28aaSamw 	arg.desc_num = 0;
221*da6c28aaSamw 	arg.rbuf = buf;
222*da6c28aaSamw 	arg.rsize = LMSHR_DOOR_SIZE;
223*da6c28aaSamw 
224*da6c28aaSamw 	if (door_call(lmshrd_fildes, &arg) < 0) {
225*da6c28aaSamw 		syslog(LOG_DEBUG, "%s: Door call failed %s",
226*da6c28aaSamw 		    lmshrd_desc[opcode], strerror(errno));
227*da6c28aaSamw 		(void) free(buf);
228*da6c28aaSamw 		lmshrd_fildes = -1;
229*da6c28aaSamw 		return (NERR_InternalError);
230*da6c28aaSamw 	}
231*da6c28aaSamw 
232*da6c28aaSamw 	dec_ctx = smb_dr_decode_start(arg.data_ptr, arg.data_size);
233*da6c28aaSamw 	if (lmshrd_door_check_srv_status(opcode, dec_ctx) != 0) {
234*da6c28aaSamw 		(void) free(buf);
235*da6c28aaSamw 		return (NERR_InternalError);
236*da6c28aaSamw 	}
237*da6c28aaSamw 
238*da6c28aaSamw 	if ((status = smb_dr_decode_finish(dec_ctx)) != 0) {
239*da6c28aaSamw 		syslog(LOG_ERR, "%s: Decode error %s",
240*da6c28aaSamw 		    lmshrd_desc[opcode], strerror(status));
241*da6c28aaSamw 		(void) free(buf);
242*da6c28aaSamw 		return (NERR_InternalError);
243*da6c28aaSamw 	}
244*da6c28aaSamw 
245*da6c28aaSamw 	(void) free(buf);
246*da6c28aaSamw 	return (NERR_Success);
247*da6c28aaSamw }
248*da6c28aaSamw 
249*da6c28aaSamw DWORD
250*da6c28aaSamw lmshrd_iterate(uint64_t iterator, lmshare_info_t *si)
251*da6c28aaSamw {
252*da6c28aaSamw 	door_arg_t arg;
253*da6c28aaSamw 	char *buf;
254*da6c28aaSamw 	unsigned int used;
255*da6c28aaSamw 	smb_dr_ctx_t *dec_ctx;
256*da6c28aaSamw 	smb_dr_ctx_t *enc_ctx;
257*da6c28aaSamw 	unsigned int status = 0;
258*da6c28aaSamw 	int opcode = LMSHR_DOOR_ITERATE;
259*da6c28aaSamw 
260*da6c28aaSamw 	if (lmshrd_door_open(opcode) == -1)
261*da6c28aaSamw 		return (NERR_InternalError);
262*da6c28aaSamw 
263*da6c28aaSamw 	buf = malloc(LMSHR_DOOR_SIZE);
264*da6c28aaSamw 	if (!buf)
265*da6c28aaSamw 		return (NERR_InternalError);
266*da6c28aaSamw 
267*da6c28aaSamw 	bzero(si, sizeof (lmshare_info_t));
268*da6c28aaSamw 	enc_ctx = smb_dr_encode_start(buf, LMSHR_DOOR_SIZE);
269*da6c28aaSamw 	smb_dr_put_uint32(enc_ctx, opcode);
270*da6c28aaSamw 	smb_dr_put_lmshr_iterator(enc_ctx, iterator);
271*da6c28aaSamw 	if ((status = smb_dr_encode_finish(enc_ctx, &used)) != 0) {
272*da6c28aaSamw 		syslog(LOG_ERR, "%s: Encode error %s",
273*da6c28aaSamw 		    lmshrd_desc[opcode], strerror(status));
274*da6c28aaSamw 		(void) free(buf);
275*da6c28aaSamw 		return (NERR_InternalError);
276*da6c28aaSamw 	}
277*da6c28aaSamw 
278*da6c28aaSamw 	arg.data_ptr = buf;
279*da6c28aaSamw 	arg.data_size = used;
280*da6c28aaSamw 	arg.desc_ptr = NULL;
281*da6c28aaSamw 	arg.desc_num = 0;
282*da6c28aaSamw 	arg.rbuf = buf;
283*da6c28aaSamw 	arg.rsize = LMSHR_DOOR_SIZE;
284*da6c28aaSamw 
285*da6c28aaSamw 	if (door_call(lmshrd_fildes, &arg) < 0) {
286*da6c28aaSamw 		syslog(LOG_DEBUG, "%s: Door call failed %s",
287*da6c28aaSamw 		    lmshrd_desc[opcode], strerror(errno));
288*da6c28aaSamw 		(void) free(buf);
289*da6c28aaSamw 		lmshrd_fildes = -1;
290*da6c28aaSamw 		return (NERR_InternalError);
291*da6c28aaSamw 	}
292*da6c28aaSamw 
293*da6c28aaSamw 	dec_ctx = smb_dr_decode_start(arg.data_ptr, arg.data_size);
294*da6c28aaSamw 	if (lmshrd_door_check_srv_status(opcode, dec_ctx) != 0) {
295*da6c28aaSamw 		(void) free(buf);
296*da6c28aaSamw 		return (NERR_InternalError);
297*da6c28aaSamw 	}
298*da6c28aaSamw 
299*da6c28aaSamw 	smb_dr_get_lmshare(dec_ctx, si);
300*da6c28aaSamw 	if ((status = smb_dr_decode_finish(dec_ctx)) != 0) {
301*da6c28aaSamw 		syslog(LOG_ERR, "%s: Decode error %s",
302*da6c28aaSamw 		    lmshrd_desc[opcode], strerror(status));
303*da6c28aaSamw 		(void) free(buf);
304*da6c28aaSamw 		return (NERR_InternalError);
305*da6c28aaSamw 	}
306*da6c28aaSamw 
307*da6c28aaSamw 	(void) free(buf);
308*da6c28aaSamw 	return (NERR_Success);
309*da6c28aaSamw }
310*da6c28aaSamw 
311*da6c28aaSamw DWORD
312*da6c28aaSamw lmshrd_list(int offset, lmshare_list_t *list)
313*da6c28aaSamw {
314*da6c28aaSamw 	door_arg_t arg;
315*da6c28aaSamw 	char *buf;
316*da6c28aaSamw 	unsigned int used;
317*da6c28aaSamw 	smb_dr_ctx_t *dec_ctx;
318*da6c28aaSamw 	smb_dr_ctx_t *enc_ctx;
319*da6c28aaSamw 	int status;
320*da6c28aaSamw 	DWORD rc;
321*da6c28aaSamw 	int opcode = LMSHR_DOOR_LIST;
322*da6c28aaSamw 
323*da6c28aaSamw 	if (lmshrd_door_open(opcode) == -1)
324*da6c28aaSamw 		return (NERR_InternalError);
325*da6c28aaSamw 
326*da6c28aaSamw 	buf = malloc(LMSHR_DOOR_SIZE);
327*da6c28aaSamw 
328*da6c28aaSamw 	if (!buf)
329*da6c28aaSamw 		return (NERR_InternalError);
330*da6c28aaSamw 
331*da6c28aaSamw 	enc_ctx = smb_dr_encode_start(buf, LMSHR_DOOR_SIZE);
332*da6c28aaSamw 	smb_dr_put_uint32(enc_ctx, opcode);
333*da6c28aaSamw 	smb_dr_put_int32(enc_ctx, offset);
334*da6c28aaSamw 
335*da6c28aaSamw 	if ((status = smb_dr_encode_finish(enc_ctx, &used)) != 0) {
336*da6c28aaSamw 		syslog(LOG_ERR, "%s: Encode error %s",
337*da6c28aaSamw 		    lmshrd_desc[opcode], strerror(status));
338*da6c28aaSamw 		(void) free(buf);
339*da6c28aaSamw 		return (NERR_InternalError);
340*da6c28aaSamw 	}
341*da6c28aaSamw 
342*da6c28aaSamw 	arg.data_ptr = buf;
343*da6c28aaSamw 	arg.data_size = used;
344*da6c28aaSamw 	arg.desc_ptr = NULL;
345*da6c28aaSamw 	arg.desc_num = 0;
346*da6c28aaSamw 	arg.rbuf = buf;
347*da6c28aaSamw 	arg.rsize = LMSHR_DOOR_SIZE;
348*da6c28aaSamw 
349*da6c28aaSamw 	if (door_call(lmshrd_fildes, &arg) < 0) {
350*da6c28aaSamw 		syslog(LOG_DEBUG, "%s: Door call failed %s",
351*da6c28aaSamw 		    lmshrd_desc[opcode], strerror(errno));
352*da6c28aaSamw 		(void) free(buf);
353*da6c28aaSamw 		lmshrd_fildes = -1;
354*da6c28aaSamw 		return (NERR_InternalError);
355*da6c28aaSamw 	}
356*da6c28aaSamw 
357*da6c28aaSamw 	dec_ctx = smb_dr_decode_start(arg.data_ptr, arg.data_size);
358*da6c28aaSamw 	if (lmshrd_door_check_srv_status(opcode, dec_ctx) != 0) {
359*da6c28aaSamw 		(void) free(buf);
360*da6c28aaSamw 		return (NERR_InternalError);
361*da6c28aaSamw 	}
362*da6c28aaSamw 
363*da6c28aaSamw 	rc = smb_dr_get_uint32(dec_ctx);
364*da6c28aaSamw 	smb_dr_get_lmshr_list(dec_ctx, list);
365*da6c28aaSamw 	if ((status = smb_dr_decode_finish(dec_ctx)) != 0) {
366*da6c28aaSamw 		syslog(LOG_ERR, "%s: Decode error %s",
367*da6c28aaSamw 		    lmshrd_desc[opcode], strerror(status));
368*da6c28aaSamw 		(void) free(buf);
369*da6c28aaSamw 		return (NERR_InternalError);
370*da6c28aaSamw 	}
371*da6c28aaSamw 
372*da6c28aaSamw 	(void) free(buf);
373*da6c28aaSamw 
374*da6c28aaSamw 	return (rc);
375*da6c28aaSamw }
376*da6c28aaSamw 
377*da6c28aaSamw int
378*da6c28aaSamw lmshrd_num_shares(void)
379*da6c28aaSamw {
380*da6c28aaSamw 	door_arg_t arg;
381*da6c28aaSamw 	char *buf;
382*da6c28aaSamw 	unsigned int used;
383*da6c28aaSamw 	smb_dr_ctx_t *dec_ctx;
384*da6c28aaSamw 	smb_dr_ctx_t *enc_ctx;
385*da6c28aaSamw 	unsigned int status = 0;
386*da6c28aaSamw 	DWORD num_shares;
387*da6c28aaSamw 	int opcode = LMSHR_DOOR_NUM_SHARES;
388*da6c28aaSamw 
389*da6c28aaSamw 	if (lmshrd_door_open(opcode) == -1)
390*da6c28aaSamw 		return (-1);
391*da6c28aaSamw 
392*da6c28aaSamw 	buf = malloc(LMSHR_DOOR_SIZE);
393*da6c28aaSamw 	if (!buf)
394*da6c28aaSamw 		return (-1);
395*da6c28aaSamw 
396*da6c28aaSamw 	enc_ctx = smb_dr_encode_start(buf, LMSHR_DOOR_SIZE);
397*da6c28aaSamw 	smb_dr_put_uint32(enc_ctx, LMSHR_DOOR_NUM_SHARES);
398*da6c28aaSamw 	if ((status = smb_dr_encode_finish(enc_ctx, &used)) != 0) {
399*da6c28aaSamw 		syslog(LOG_ERR, "%s: Encode error %s",
400*da6c28aaSamw 		    lmshrd_desc[opcode], strerror(status));
401*da6c28aaSamw 		(void) free(buf);
402*da6c28aaSamw 		return (-1);
403*da6c28aaSamw 	}
404*da6c28aaSamw 
405*da6c28aaSamw 	arg.data_ptr = buf;
406*da6c28aaSamw 	arg.data_size = used;
407*da6c28aaSamw 	arg.desc_ptr = NULL;
408*da6c28aaSamw 	arg.desc_num = 0;
409*da6c28aaSamw 	arg.rbuf = buf;
410*da6c28aaSamw 	arg.rsize = LMSHR_DOOR_SIZE;
411*da6c28aaSamw 
412*da6c28aaSamw 	if (door_call(lmshrd_fildes, &arg) < 0) {
413*da6c28aaSamw 		syslog(LOG_DEBUG, "%s: Door call failed %s",
414*da6c28aaSamw 		    lmshrd_desc[opcode], strerror(errno));
415*da6c28aaSamw 		(void) free(buf);
416*da6c28aaSamw 		lmshrd_fildes = -1;
417*da6c28aaSamw 		return (-1);
418*da6c28aaSamw 	}
419*da6c28aaSamw 
420*da6c28aaSamw 	dec_ctx = smb_dr_decode_start(arg.data_ptr, arg.data_size);
421*da6c28aaSamw 	if (lmshrd_door_check_srv_status(opcode, dec_ctx) != 0) {
422*da6c28aaSamw 		(void) free(buf);
423*da6c28aaSamw 		return (-1);
424*da6c28aaSamw 	}
425*da6c28aaSamw 
426*da6c28aaSamw 	num_shares = smb_dr_get_uint32(dec_ctx);
427*da6c28aaSamw 	if ((status = smb_dr_decode_finish(dec_ctx)) != 0) {
428*da6c28aaSamw 		syslog(LOG_ERR, "%s: Decode error %s",
429*da6c28aaSamw 		    lmshrd_desc[opcode], strerror(status));
430*da6c28aaSamw 		(void) free(buf);
431*da6c28aaSamw 		return (-1);
432*da6c28aaSamw 	}
433*da6c28aaSamw 
434*da6c28aaSamw 	(void) free(buf);
435*da6c28aaSamw 	return (num_shares);
436*da6c28aaSamw }
437*da6c28aaSamw 
438*da6c28aaSamw DWORD
439*da6c28aaSamw lmshrd_delete(char *share_name)
440*da6c28aaSamw {
441*da6c28aaSamw 	door_arg_t arg;
442*da6c28aaSamw 	char *buf;
443*da6c28aaSamw 	unsigned int used;
444*da6c28aaSamw 	smb_dr_ctx_t *dec_ctx;
445*da6c28aaSamw 	smb_dr_ctx_t *enc_ctx;
446*da6c28aaSamw 	int status;
447*da6c28aaSamw 	DWORD rc;
448*da6c28aaSamw 	int opcode = LMSHR_DOOR_DELETE;
449*da6c28aaSamw 
450*da6c28aaSamw 	if (lmshrd_door_open(opcode) == -1)
451*da6c28aaSamw 		return (NERR_InternalError);
452*da6c28aaSamw 
453*da6c28aaSamw 	buf = malloc(LMSHR_DOOR_SIZE);
454*da6c28aaSamw 	if (!buf)
455*da6c28aaSamw 		return (NERR_InternalError);
456*da6c28aaSamw 
457*da6c28aaSamw 	enc_ctx = smb_dr_encode_start(buf, LMSHR_DOOR_SIZE);
458*da6c28aaSamw 	smb_dr_put_uint32(enc_ctx, LMSHR_DOOR_DELETE);
459*da6c28aaSamw 	smb_dr_put_string(enc_ctx, share_name);
460*da6c28aaSamw 
461*da6c28aaSamw 	if ((status = smb_dr_encode_finish(enc_ctx, &used)) != 0) {
462*da6c28aaSamw 		syslog(LOG_ERR, "%s: Encode error %s",
463*da6c28aaSamw 		    lmshrd_desc[opcode], strerror(status));
464*da6c28aaSamw 		(void) free(buf);
465*da6c28aaSamw 		return (NERR_InternalError);
466*da6c28aaSamw 	}
467*da6c28aaSamw 
468*da6c28aaSamw 	arg.data_ptr = buf;
469*da6c28aaSamw 	arg.data_size = used;
470*da6c28aaSamw 	arg.desc_ptr = NULL;
471*da6c28aaSamw 	arg.desc_num = 0;
472*da6c28aaSamw 	arg.rbuf = buf;
473*da6c28aaSamw 	arg.rsize = LMSHR_DOOR_SIZE;
474*da6c28aaSamw 
475*da6c28aaSamw 	if (door_call(lmshrd_fildes, &arg) < 0) {
476*da6c28aaSamw 		syslog(LOG_DEBUG, "%s: Door call failed %s",
477*da6c28aaSamw 		    lmshrd_desc[opcode], strerror(errno));
478*da6c28aaSamw 		(void) free(buf);
479*da6c28aaSamw 		lmshrd_fildes = -1;
480*da6c28aaSamw 		return (NERR_InternalError);
481*da6c28aaSamw 	}
482*da6c28aaSamw 
483*da6c28aaSamw 	dec_ctx = smb_dr_decode_start(arg.data_ptr, arg.data_size);
484*da6c28aaSamw 	if (lmshrd_door_check_srv_status(opcode, dec_ctx) != 0) {
485*da6c28aaSamw 		(void) free(buf);
486*da6c28aaSamw 		return (NERR_InternalError);
487*da6c28aaSamw 	}
488*da6c28aaSamw 
489*da6c28aaSamw 	rc = smb_dr_get_uint32(dec_ctx);
490*da6c28aaSamw 	if ((status = smb_dr_decode_finish(dec_ctx)) != 0) {
491*da6c28aaSamw 		syslog(LOG_ERR, "%s: Decode error %s",
492*da6c28aaSamw 		    lmshrd_desc[opcode], strerror(status));
493*da6c28aaSamw 		(void) free(buf);
494*da6c28aaSamw 		return (NERR_InternalError);
495*da6c28aaSamw 	}
496*da6c28aaSamw 
497*da6c28aaSamw 	(void) free(buf);
498*da6c28aaSamw 	return (rc);
499*da6c28aaSamw 
500*da6c28aaSamw }
501*da6c28aaSamw 
502*da6c28aaSamw DWORD
503*da6c28aaSamw lmshrd_rename(char *from, char *to)
504*da6c28aaSamw {
505*da6c28aaSamw 	door_arg_t arg;
506*da6c28aaSamw 	char *buf;
507*da6c28aaSamw 	unsigned int used;
508*da6c28aaSamw 	smb_dr_ctx_t *dec_ctx;
509*da6c28aaSamw 	smb_dr_ctx_t *enc_ctx;
510*da6c28aaSamw 	int status;
511*da6c28aaSamw 	DWORD rc;
512*da6c28aaSamw 	int opcode = LMSHR_DOOR_RENAME;
513*da6c28aaSamw 
514*da6c28aaSamw 	if (lmshrd_door_open(opcode) == -1)
515*da6c28aaSamw 		return (NERR_InternalError);
516*da6c28aaSamw 
517*da6c28aaSamw 	buf = malloc(LMSHR_DOOR_SIZE);
518*da6c28aaSamw 	if (!buf)
519*da6c28aaSamw 		return (NERR_InternalError);
520*da6c28aaSamw 
521*da6c28aaSamw 	enc_ctx = smb_dr_encode_start(buf, LMSHR_DOOR_SIZE);
522*da6c28aaSamw 	smb_dr_put_uint32(enc_ctx, LMSHR_DOOR_RENAME);
523*da6c28aaSamw 	smb_dr_put_string(enc_ctx, from);
524*da6c28aaSamw 	smb_dr_put_string(enc_ctx, to);
525*da6c28aaSamw 
526*da6c28aaSamw 	if ((status = smb_dr_encode_finish(enc_ctx, &used)) != 0) {
527*da6c28aaSamw 		syslog(LOG_ERR, "%s: Encode error %s",
528*da6c28aaSamw 		    lmshrd_desc[opcode], strerror(status));
529*da6c28aaSamw 		(void) free(buf);
530*da6c28aaSamw 		return (NERR_InternalError);
531*da6c28aaSamw 	}
532*da6c28aaSamw 
533*da6c28aaSamw 	arg.data_ptr = buf;
534*da6c28aaSamw 	arg.data_size = used;
535*da6c28aaSamw 	arg.desc_ptr = NULL;
536*da6c28aaSamw 	arg.desc_num = 0;
537*da6c28aaSamw 	arg.rbuf = buf;
538*da6c28aaSamw 	arg.rsize = LMSHR_DOOR_SIZE;
539*da6c28aaSamw 
540*da6c28aaSamw 	if (door_call(lmshrd_fildes, &arg) < 0) {
541*da6c28aaSamw 		syslog(LOG_DEBUG, "%s: Door call failed %s",
542*da6c28aaSamw 		    lmshrd_desc[opcode], strerror(errno));
543*da6c28aaSamw 		(void) free(buf);
544*da6c28aaSamw 		lmshrd_fildes = -1;
545*da6c28aaSamw 		return (NERR_InternalError);
546*da6c28aaSamw 	}
547*da6c28aaSamw 
548*da6c28aaSamw 	dec_ctx = smb_dr_decode_start(arg.data_ptr, arg.data_size);
549*da6c28aaSamw 	if (lmshrd_door_check_srv_status(opcode, dec_ctx) != 0) {
550*da6c28aaSamw 		(void) free(buf);
551*da6c28aaSamw 		return (NERR_InternalError);
552*da6c28aaSamw 	}
553*da6c28aaSamw 
554*da6c28aaSamw 	rc = smb_dr_get_uint32(dec_ctx);
555*da6c28aaSamw 	if ((status = smb_dr_decode_finish(dec_ctx)) != 0) {
556*da6c28aaSamw 		syslog(LOG_ERR, "%s: Decode error %s",
557*da6c28aaSamw 		    lmshrd_desc[opcode], strerror(status));
558*da6c28aaSamw 		(void) free(buf);
559*da6c28aaSamw 		return (NERR_InternalError);
560*da6c28aaSamw 	}
561*da6c28aaSamw 
562*da6c28aaSamw 	(void) free(buf);
563*da6c28aaSamw 	return (rc);
564*da6c28aaSamw }
565*da6c28aaSamw 
566*da6c28aaSamw DWORD
567*da6c28aaSamw lmshrd_getinfo(char *share_name, lmshare_info_t *si)
568*da6c28aaSamw {
569*da6c28aaSamw 	door_arg_t arg;
570*da6c28aaSamw 	char *buf;
571*da6c28aaSamw 	unsigned int used;
572*da6c28aaSamw 	smb_dr_ctx_t *dec_ctx;
573*da6c28aaSamw 	smb_dr_ctx_t *enc_ctx;
574*da6c28aaSamw 	int status;
575*da6c28aaSamw 	DWORD rc;
576*da6c28aaSamw 	int opcode = LMSHR_DOOR_GETINFO;
577*da6c28aaSamw 
578*da6c28aaSamw 	if (lmshrd_door_open(opcode) == -1)
579*da6c28aaSamw 		return (NERR_InternalError);
580*da6c28aaSamw 
581*da6c28aaSamw 	buf = malloc(LMSHR_DOOR_SIZE);
582*da6c28aaSamw 	if (!buf)
583*da6c28aaSamw 		return (NERR_InternalError);
584*da6c28aaSamw 
585*da6c28aaSamw 	enc_ctx = smb_dr_encode_start(buf, LMSHR_DOOR_SIZE);
586*da6c28aaSamw 	smb_dr_put_uint32(enc_ctx, LMSHR_DOOR_GETINFO);
587*da6c28aaSamw 	smb_dr_put_string(enc_ctx, share_name);
588*da6c28aaSamw 
589*da6c28aaSamw 	if ((status = smb_dr_encode_finish(enc_ctx, &used)) != 0) {
590*da6c28aaSamw 		syslog(LOG_ERR, "%s: Encode error %s",
591*da6c28aaSamw 		    lmshrd_desc[opcode], strerror(status));
592*da6c28aaSamw 		(void) free(buf);
593*da6c28aaSamw 		return (NERR_InternalError);
594*da6c28aaSamw 	}
595*da6c28aaSamw 
596*da6c28aaSamw 	arg.data_ptr = buf;
597*da6c28aaSamw 	arg.data_size = used;
598*da6c28aaSamw 	arg.desc_ptr = NULL;
599*da6c28aaSamw 	arg.desc_num = 0;
600*da6c28aaSamw 	arg.rbuf = buf;
601*da6c28aaSamw 	arg.rsize = LMSHR_DOOR_SIZE;
602*da6c28aaSamw 
603*da6c28aaSamw 	if (door_call(lmshrd_fildes, &arg) < 0) {
604*da6c28aaSamw 		syslog(LOG_DEBUG, "%s: Door call failed %s",
605*da6c28aaSamw 		    lmshrd_desc[opcode], strerror(errno));
606*da6c28aaSamw 		(void) free(buf);
607*da6c28aaSamw 		lmshrd_fildes = -1;
608*da6c28aaSamw 		return (NERR_InternalError);
609*da6c28aaSamw 	}
610*da6c28aaSamw 
611*da6c28aaSamw 	dec_ctx = smb_dr_decode_start(arg.data_ptr, arg.data_size);
612*da6c28aaSamw 	if (lmshrd_door_check_srv_status(opcode, dec_ctx) != 0) {
613*da6c28aaSamw 		(void) free(buf);
614*da6c28aaSamw 		return (NERR_InternalError);
615*da6c28aaSamw 	}
616*da6c28aaSamw 
617*da6c28aaSamw 	rc = smb_dr_get_uint32(dec_ctx);
618*da6c28aaSamw 	smb_dr_get_lmshare(dec_ctx, si);
619*da6c28aaSamw 	if ((status = smb_dr_decode_finish(dec_ctx)) != 0) {
620*da6c28aaSamw 		syslog(LOG_ERR, "%s: Decode error %s",
621*da6c28aaSamw 		    lmshrd_desc[opcode], strerror(status));
622*da6c28aaSamw 		(void) free(buf);
623*da6c28aaSamw 		return (NERR_InternalError);
624*da6c28aaSamw 	}
625*da6c28aaSamw 
626*da6c28aaSamw 	(void) free(buf);
627*da6c28aaSamw 	return (rc);
628*da6c28aaSamw }
629*da6c28aaSamw 
630*da6c28aaSamw DWORD
631*da6c28aaSamw lmshrd_add(lmshare_info_t *si)
632*da6c28aaSamw {
633*da6c28aaSamw 	door_arg_t arg;
634*da6c28aaSamw 	char *buf;
635*da6c28aaSamw 	unsigned int used;
636*da6c28aaSamw 	smb_dr_ctx_t *dec_ctx;
637*da6c28aaSamw 	smb_dr_ctx_t *enc_ctx;
638*da6c28aaSamw 	int status;
639*da6c28aaSamw 	DWORD rc;
640*da6c28aaSamw 	int opcode = LMSHR_DOOR_ADD;
641*da6c28aaSamw 
642*da6c28aaSamw 	if (lmshrd_door_open(opcode) == -1)
643*da6c28aaSamw 		return (NERR_InternalError);
644*da6c28aaSamw 
645*da6c28aaSamw 	buf = malloc(LMSHR_DOOR_SIZE);
646*da6c28aaSamw 	if (!buf)
647*da6c28aaSamw 		return (NERR_InternalError);
648*da6c28aaSamw 
649*da6c28aaSamw 	enc_ctx = smb_dr_encode_start(buf, LMSHR_DOOR_SIZE);
650*da6c28aaSamw 	smb_dr_put_uint32(enc_ctx, opcode);
651*da6c28aaSamw 	smb_dr_put_lmshare(enc_ctx, si);
652*da6c28aaSamw 
653*da6c28aaSamw 	if ((status = smb_dr_encode_finish(enc_ctx, &used)) != 0) {
654*da6c28aaSamw 		syslog(LOG_ERR, "%s: Encode error %s",
655*da6c28aaSamw 		    lmshrd_desc[opcode], strerror(status));
656*da6c28aaSamw 		(void) free(buf);
657*da6c28aaSamw 		return (NERR_InternalError);
658*da6c28aaSamw 	}
659*da6c28aaSamw 
660*da6c28aaSamw 	arg.data_ptr = buf;
661*da6c28aaSamw 	arg.data_size = used;
662*da6c28aaSamw 	arg.desc_ptr = NULL;
663*da6c28aaSamw 	arg.desc_num = 0;
664*da6c28aaSamw 	arg.rbuf = buf;
665*da6c28aaSamw 	arg.rsize = LMSHR_DOOR_SIZE;
666*da6c28aaSamw 
667*da6c28aaSamw 	if (door_call(lmshrd_fildes, &arg) < 0) {
668*da6c28aaSamw 		syslog(LOG_DEBUG, "%s: Door call failed %s",
669*da6c28aaSamw 		    lmshrd_desc[opcode], strerror(errno));
670*da6c28aaSamw 		(void) free(buf);
671*da6c28aaSamw 		lmshrd_fildes = -1;
672*da6c28aaSamw 		return (NERR_InternalError);
673*da6c28aaSamw 	}
674*da6c28aaSamw 
675*da6c28aaSamw 	dec_ctx = smb_dr_decode_start(arg.data_ptr, arg.data_size);
676*da6c28aaSamw 	if (lmshrd_door_check_srv_status(opcode, dec_ctx) != 0) {
677*da6c28aaSamw 		(void) free(buf);
678*da6c28aaSamw 		return (NERR_InternalError);
679*da6c28aaSamw 	}
680*da6c28aaSamw 
681*da6c28aaSamw 	rc = smb_dr_get_uint32(dec_ctx);
682*da6c28aaSamw 	smb_dr_get_lmshare(dec_ctx, si);
683*da6c28aaSamw 	if ((status = smb_dr_decode_finish(dec_ctx)) != 0) {
684*da6c28aaSamw 		syslog(LOG_ERR, "%s: Decode error %s",
685*da6c28aaSamw 		    lmshrd_desc[opcode], strerror(status));
686*da6c28aaSamw 		(void) free(buf);
687*da6c28aaSamw 		return (NERR_InternalError);
688*da6c28aaSamw 	}
689*da6c28aaSamw 
690*da6c28aaSamw 	(void) free(buf);
691*da6c28aaSamw 	return (rc);
692*da6c28aaSamw }
693*da6c28aaSamw 
694*da6c28aaSamw DWORD
695*da6c28aaSamw lmshrd_setinfo(lmshare_info_t *si)
696*da6c28aaSamw {
697*da6c28aaSamw 	door_arg_t arg;
698*da6c28aaSamw 	char *buf;
699*da6c28aaSamw 	unsigned int used;
700*da6c28aaSamw 	smb_dr_ctx_t *dec_ctx;
701*da6c28aaSamw 	smb_dr_ctx_t *enc_ctx;
702*da6c28aaSamw 	int status;
703*da6c28aaSamw 	DWORD rc;
704*da6c28aaSamw 	int opcode = LMSHR_DOOR_SETINFO;
705*da6c28aaSamw 
706*da6c28aaSamw 	if (lmshrd_door_open(opcode) == -1)
707*da6c28aaSamw 		return (NERR_InternalError);
708*da6c28aaSamw 
709*da6c28aaSamw 	buf = malloc(LMSHR_DOOR_SIZE);
710*da6c28aaSamw 	if (!buf)
711*da6c28aaSamw 		return (NERR_InternalError);
712*da6c28aaSamw 
713*da6c28aaSamw 	enc_ctx = smb_dr_encode_start(buf, LMSHR_DOOR_SIZE);
714*da6c28aaSamw 	smb_dr_put_uint32(enc_ctx, opcode);
715*da6c28aaSamw 	smb_dr_put_lmshare(enc_ctx, si);
716*da6c28aaSamw 
717*da6c28aaSamw 	if ((status = smb_dr_encode_finish(enc_ctx, &used)) != 0) {
718*da6c28aaSamw 		syslog(LOG_ERR, "%s: Encode error %s",
719*da6c28aaSamw 		    lmshrd_desc[opcode], strerror(status));
720*da6c28aaSamw 		(void) free(buf);
721*da6c28aaSamw 		return (NERR_InternalError);
722*da6c28aaSamw 	}
723*da6c28aaSamw 
724*da6c28aaSamw 	arg.data_ptr = buf;
725*da6c28aaSamw 	arg.data_size = used;
726*da6c28aaSamw 	arg.desc_ptr = NULL;
727*da6c28aaSamw 	arg.desc_num = 0;
728*da6c28aaSamw 	arg.rbuf = buf;
729*da6c28aaSamw 	arg.rsize = LMSHR_DOOR_SIZE;
730*da6c28aaSamw 
731*da6c28aaSamw 	if (door_call(lmshrd_fildes, &arg) < 0) {
732*da6c28aaSamw 		syslog(LOG_DEBUG, "%s: Door call failed %s",
733*da6c28aaSamw 		    lmshrd_desc[opcode], strerror(errno));
734*da6c28aaSamw 		(void) free(buf);
735*da6c28aaSamw 		lmshrd_fildes = -1;
736*da6c28aaSamw 		return (NERR_InternalError);
737*da6c28aaSamw 	}
738*da6c28aaSamw 
739*da6c28aaSamw 	dec_ctx = smb_dr_decode_start(arg.data_ptr, arg.data_size);
740*da6c28aaSamw 	if (lmshrd_door_check_srv_status(opcode, dec_ctx) != 0) {
741*da6c28aaSamw 		(void) free(buf);
742*da6c28aaSamw 		return (NERR_InternalError);
743*da6c28aaSamw 	}
744*da6c28aaSamw 
745*da6c28aaSamw 	rc = smb_dr_get_uint32(dec_ctx);
746*da6c28aaSamw 	if ((status = smb_dr_decode_finish(dec_ctx)) != 0) {
747*da6c28aaSamw 		syslog(LOG_ERR, "%s: Decode error %s",
748*da6c28aaSamw 		    lmshrd_desc[opcode], strerror(status));
749*da6c28aaSamw 		(void) free(buf);
750*da6c28aaSamw 		return (NERR_InternalError);
751*da6c28aaSamw 	}
752*da6c28aaSamw 
753*da6c28aaSamw 	(void) free(buf);
754*da6c28aaSamw 	return (rc);
755*da6c28aaSamw }
756*da6c28aaSamw 
757*da6c28aaSamw static int
758*da6c28aaSamw lmshrd_check(char *share_name, int opcode)
759*da6c28aaSamw {
760*da6c28aaSamw 	door_arg_t arg;
761*da6c28aaSamw 	char *buf;
762*da6c28aaSamw 	unsigned int used;
763*da6c28aaSamw 	smb_dr_ctx_t *dec_ctx;
764*da6c28aaSamw 	smb_dr_ctx_t *enc_ctx;
765*da6c28aaSamw 	int status, rc;
766*da6c28aaSamw 
767*da6c28aaSamw 	if (lmshrd_door_open(opcode) == -1)
768*da6c28aaSamw 		return (NERR_InternalError);
769*da6c28aaSamw 
770*da6c28aaSamw 	buf = malloc(LMSHR_DOOR_SIZE);
771*da6c28aaSamw 	if (!buf)
772*da6c28aaSamw 		return (NERR_InternalError);
773*da6c28aaSamw 
774*da6c28aaSamw 	enc_ctx = smb_dr_encode_start(buf, LMSHR_DOOR_SIZE);
775*da6c28aaSamw 	smb_dr_put_uint32(enc_ctx, opcode);
776*da6c28aaSamw 	smb_dr_put_string(enc_ctx, share_name);
777*da6c28aaSamw 
778*da6c28aaSamw 	if ((status = smb_dr_encode_finish(enc_ctx, &used)) != 0) {
779*da6c28aaSamw 		syslog(LOG_ERR, "%s: Encode error %s",
780*da6c28aaSamw 		    lmshrd_desc[opcode], strerror(status));
781*da6c28aaSamw 		(void) free(buf);
782*da6c28aaSamw 		return (NERR_InternalError);
783*da6c28aaSamw 	}
784*da6c28aaSamw 
785*da6c28aaSamw 	arg.data_ptr = buf;
786*da6c28aaSamw 	arg.data_size = used;
787*da6c28aaSamw 	arg.desc_ptr = NULL;
788*da6c28aaSamw 	arg.desc_num = 0;
789*da6c28aaSamw 	arg.rbuf = buf;
790*da6c28aaSamw 	arg.rsize = LMSHR_DOOR_SIZE;
791*da6c28aaSamw 
792*da6c28aaSamw 	if (door_call(lmshrd_fildes, &arg) < 0) {
793*da6c28aaSamw 		syslog(LOG_DEBUG, "%s: Door call failed %s",
794*da6c28aaSamw 		    lmshrd_desc[opcode], strerror(errno));
795*da6c28aaSamw 		(void) free(buf);
796*da6c28aaSamw 		lmshrd_fildes = -1;
797*da6c28aaSamw 		return (NERR_InternalError);
798*da6c28aaSamw 	}
799*da6c28aaSamw 
800*da6c28aaSamw 	dec_ctx = smb_dr_decode_start(arg.data_ptr, arg.data_size);
801*da6c28aaSamw 	if (lmshrd_door_check_srv_status(opcode, dec_ctx) != 0) {
802*da6c28aaSamw 		(void) free(buf);
803*da6c28aaSamw 		return (NERR_InternalError);
804*da6c28aaSamw 	}
805*da6c28aaSamw 
806*da6c28aaSamw 	rc = smb_dr_get_int32(dec_ctx);
807*da6c28aaSamw 	if ((status = smb_dr_decode_finish(dec_ctx)) != 0) {
808*da6c28aaSamw 		syslog(LOG_ERR, "%s: Decode error %s",
809*da6c28aaSamw 		    lmshrd_desc[opcode], strerror(status));
810*da6c28aaSamw 		(void) free(buf);
811*da6c28aaSamw 		return (NERR_InternalError);
812*da6c28aaSamw 	}
813*da6c28aaSamw 
814*da6c28aaSamw 	(void) free(buf);
815*da6c28aaSamw 	return (rc);
816*da6c28aaSamw }
817*da6c28aaSamw 
818*da6c28aaSamw int
819*da6c28aaSamw lmshrd_exists(char *share_name)
820*da6c28aaSamw {
821*da6c28aaSamw 	return (lmshrd_check(share_name, LMSHR_DOOR_EXISTS));
822*da6c28aaSamw }
823*da6c28aaSamw 
824*da6c28aaSamw int
825*da6c28aaSamw lmshrd_is_special(char *share_name)
826*da6c28aaSamw {
827*da6c28aaSamw 	return (lmshrd_check(share_name, LMSHR_DOOR_IS_SPECIAL));
828*da6c28aaSamw }
829*da6c28aaSamw 
830*da6c28aaSamw int
831*da6c28aaSamw lmshrd_is_restricted(char *share_name)
832*da6c28aaSamw {
833*da6c28aaSamw 	return (lmshrd_check(share_name, LMSHR_DOOR_IS_RESTRICTED));
834*da6c28aaSamw }
835*da6c28aaSamw 
836*da6c28aaSamw int
837*da6c28aaSamw lmshrd_is_admin(char *share_name)
838*da6c28aaSamw {
839*da6c28aaSamw 	return (lmshrd_check(share_name, LMSHR_DOOR_IS_ADMIN));
840*da6c28aaSamw }
841*da6c28aaSamw 
842*da6c28aaSamw int
843*da6c28aaSamw lmshrd_is_valid(char *share_name)
844*da6c28aaSamw {
845*da6c28aaSamw 	return (lmshrd_check(share_name, LMSHR_DOOR_IS_VALID));
846*da6c28aaSamw }
847*da6c28aaSamw 
848*da6c28aaSamw int
849*da6c28aaSamw lmshrd_is_dir(char *path)
850*da6c28aaSamw {
851*da6c28aaSamw 	return (lmshrd_check(path, LMSHR_DOOR_IS_DIR));
852*da6c28aaSamw }
853*da6c28aaSamw 
854*da6c28aaSamw static char *
855*da6c28aaSamw lmshare_decode_type(unsigned int stype)
856*da6c28aaSamw {
857*da6c28aaSamw 	switch (stype) {
858*da6c28aaSamw 	case STYPE_DISKTREE:
859*da6c28aaSamw 		return ("Disk");
860*da6c28aaSamw 	case STYPE_PRINTQ:
861*da6c28aaSamw 		return ("Print Queue");
862*da6c28aaSamw 	case STYPE_DEVICE:
863*da6c28aaSamw 		return ("Device");
864*da6c28aaSamw 	case STYPE_IPC:
865*da6c28aaSamw 		return ("IPC");
866*da6c28aaSamw 	case STYPE_DFS:
867*da6c28aaSamw 		return ("DFS");
868*da6c28aaSamw 	case STYPE_SPECIAL:
869*da6c28aaSamw 		return ("Special");
870*da6c28aaSamw 	default:
871*da6c28aaSamw 		return ("Unknown");
872*da6c28aaSamw 	};
873*da6c28aaSamw }
874*da6c28aaSamw 
875*da6c28aaSamw 
876*da6c28aaSamw static void
877*da6c28aaSamw lmshare_loginfo(FILE *fp, lmshare_info_t *si)
878*da6c28aaSamw {
879*da6c28aaSamw 	if (!si) {
880*da6c28aaSamw 		return;
881*da6c28aaSamw 	}
882*da6c28aaSamw 
883*da6c28aaSamw 	(void) fprintf(fp, "\n%s Information:\n", si->share_name);
884*da6c28aaSamw 	(void) fprintf(fp, "\tFolder: %s\n", si->directory);
885*da6c28aaSamw 	(void) fprintf(fp, "\tType: %s\n", lmshare_decode_type(si->stype));
886*da6c28aaSamw 	(void) fprintf(fp, "\tComment: %s\n", si->comment);
887*da6c28aaSamw 
888*da6c28aaSamw 	(void) fprintf(fp, "\tStatus: %s\n",
889*da6c28aaSamw 	    ((si->mode & LMSHRM_TRANS) ? "Transient" : "Permanent"));
890*da6c28aaSamw 
891*da6c28aaSamw 	(void) fprintf(fp, "\tContainer: %s\n", si->container);
892*da6c28aaSamw }
893*da6c28aaSamw 
894*da6c28aaSamw int
895*da6c28aaSamw lmshrd_dump_hash(char *logfname)
896*da6c28aaSamw {
897*da6c28aaSamw 	lmshare_info_t si;
898*da6c28aaSamw 	uint64_t it;
899*da6c28aaSamw 	FILE *fp;
900*da6c28aaSamw 
901*da6c28aaSamw 	if ((logfname == 0) || (*logfname == 0))
902*da6c28aaSamw 		fp = stdout;
903*da6c28aaSamw 	else {
904*da6c28aaSamw 		fp = fopen(logfname, "w");
905*da6c28aaSamw 		if (fp == 0) {
906*da6c28aaSamw 			syslog(LOG_WARNING, "LmshareDump [%s]:"
907*da6c28aaSamw 			    " cannot create logfile", logfname);
908*da6c28aaSamw 			syslog(LOG_WARNING, "LmshareDump:"
909*da6c28aaSamw 			    " output will be written on screen");
910*da6c28aaSamw 		}
911*da6c28aaSamw 	}
912*da6c28aaSamw 
913*da6c28aaSamw 	it = lmshrd_open_iterator(LMSHRM_PERM);
914*da6c28aaSamw 	if (it == NULL) {
915*da6c28aaSamw 		syslog(LOG_ERR, "LmshareDump: resource shortage");
916*da6c28aaSamw 		if (fp && fp != stdout) {
917*da6c28aaSamw 			(void) fclose(fp);
918*da6c28aaSamw 		}
919*da6c28aaSamw 		return (1);
920*da6c28aaSamw 	}
921*da6c28aaSamw 
922*da6c28aaSamw 	if (lmshrd_iterate(it, &si) != NERR_Success) {
923*da6c28aaSamw 		syslog(LOG_ERR, "LmshareDump: Iterator iterate failed");
924*da6c28aaSamw 		if (fp && fp != stdout) {
925*da6c28aaSamw 			(void) fclose(fp);
926*da6c28aaSamw 		}
927*da6c28aaSamw 		return (1);
928*da6c28aaSamw 	}
929*da6c28aaSamw 	while (*si.share_name != 0) {
930*da6c28aaSamw 		lmshare_loginfo(fp, &si);
931*da6c28aaSamw 		if (lmshrd_iterate(it, &si) != NERR_Success) {
932*da6c28aaSamw 			syslog(LOG_ERR, "LmshareDump: Iterator iterate failed");
933*da6c28aaSamw 			if (fp && fp != stdout) {
934*da6c28aaSamw 				(void) fclose(fp);
935*da6c28aaSamw 			}
936*da6c28aaSamw 			return (1);
937*da6c28aaSamw 		}
938*da6c28aaSamw 	}
939*da6c28aaSamw 
940*da6c28aaSamw 	if (lmshrd_close_iterator(it) != NERR_Success) {
941*da6c28aaSamw 		syslog(LOG_ERR, "LmshareDump: Iterator close failed");
942*da6c28aaSamw 		if (fp && fp != stdout) {
943*da6c28aaSamw 			(void) fclose(fp);
944*da6c28aaSamw 		}
945*da6c28aaSamw 		return (1);
946*da6c28aaSamw 	}
947*da6c28aaSamw 	if (fp && fp != stdout) {
948*da6c28aaSamw 		(void) fclose(fp);
949*da6c28aaSamw 	}
950*da6c28aaSamw 	return (0);
951*da6c28aaSamw }
952