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 /*
22cbfb650aScp160787  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23da6c28aaSamw  * Use is subject to license terms.
24da6c28aaSamw  */
25da6c28aaSamw 
26da6c28aaSamw #pragma ident	"%Z%%M%	%I%	%E% SMI"
27da6c28aaSamw 
28da6c28aaSamw /*
29da6c28aaSamw  * LanMan share door server
30da6c28aaSamw  */
31da6c28aaSamw 
32da6c28aaSamw #include <door.h>
33da6c28aaSamw #include <unistd.h>
34da6c28aaSamw #include <sys/types.h>
35da6c28aaSamw #include <sys/stat.h>
36da6c28aaSamw #include <fcntl.h>
37da6c28aaSamw #include <errno.h>
38da6c28aaSamw #include <syslog.h>
39da6c28aaSamw #include <string.h>
403ad684d6Sjb150015 #include <strings.h>
41da6c28aaSamw #include <pthread.h>
42da6c28aaSamw 
43da6c28aaSamw #include <smbsrv/libsmb.h>
44da6c28aaSamw 
45*3db3f65cSamw #include <smbsrv/smb_share.h>
46da6c28aaSamw #include <smbsrv/smbinfo.h>
47da6c28aaSamw 
48*3db3f65cSamw #define	SMB_SHARE_DSRV_VERSION	1
49*3db3f65cSamw #define	SMB_SHARE_DSRV_COOKIE	((void*)(0xdeadbeef^SMB_SHARE_DSRV_VERSION))
50*3db3f65cSamw 
513ad684d6Sjb150015 static int smb_share_dsrv_fd = -1;
523ad684d6Sjb150015 static pthread_mutex_t smb_share_dsrv_mtx = PTHREAD_MUTEX_INITIALIZER;
53da6c28aaSamw 
543ad684d6Sjb150015 static void smb_share_dsrv_dispatch(void *, char *, size_t, door_desc_t *,
553ad684d6Sjb150015     uint_t);
563ad684d6Sjb150015 static int smb_share_dsrv_enum(smb_enumshare_info_t *esi);
57da6c28aaSamw 
58da6c28aaSamw /*
593ad684d6Sjb150015  * smb_share_dsrv_start
60da6c28aaSamw  *
61da6c28aaSamw  * Start the LanMan share door service.
62da6c28aaSamw  * Returns 0 on success. Otherwise, -1.
63da6c28aaSamw  */
64da6c28aaSamw int
653ad684d6Sjb150015 smb_share_dsrv_start(void)
66da6c28aaSamw {
67da6c28aaSamw 	int	newfd;
68da6c28aaSamw 
693ad684d6Sjb150015 	(void) pthread_mutex_lock(&smb_share_dsrv_mtx);
70da6c28aaSamw 
713ad684d6Sjb150015 	if (smb_share_dsrv_fd != -1) {
723ad684d6Sjb150015 		syslog(LOG_ERR, "smb_share_dsrv_start: duplicate");
733ad684d6Sjb150015 		(void) pthread_mutex_unlock(&smb_share_dsrv_mtx);
743ad684d6Sjb150015 		return (smb_share_dsrv_fd);
75da6c28aaSamw 	}
76da6c28aaSamw 
773ad684d6Sjb150015 	if ((smb_share_dsrv_fd = door_create(smb_share_dsrv_dispatch,
78*3db3f65cSamw 	    SMB_SHARE_DSRV_COOKIE, (DOOR_UNREF | DOOR_REFUSE_DESC))) < 0) {
793ad684d6Sjb150015 		syslog(LOG_ERR, "smb_share_dsrv_start: door_create: %s",
80da6c28aaSamw 		    strerror(errno));
813ad684d6Sjb150015 		(void) pthread_mutex_unlock(&smb_share_dsrv_mtx);
82da6c28aaSamw 		return (-1);
83da6c28aaSamw 	}
84da6c28aaSamw 
85*3db3f65cSamw 	(void) unlink(SMB_SHARE_DNAME);
86da6c28aaSamw 
87*3db3f65cSamw 	if ((newfd = creat(SMB_SHARE_DNAME, 0644)) < 0) {
883ad684d6Sjb150015 		syslog(LOG_ERR, "smb_share_dsrv_start: open: %s",
89da6c28aaSamw 		    strerror(errno));
903ad684d6Sjb150015 		(void) door_revoke(smb_share_dsrv_fd);
913ad684d6Sjb150015 		smb_share_dsrv_fd = -1;
923ad684d6Sjb150015 		(void) pthread_mutex_unlock(&smb_share_dsrv_mtx);
93da6c28aaSamw 		return (-1);
94da6c28aaSamw 	}
95da6c28aaSamw 
96da6c28aaSamw 	(void) close(newfd);
97*3db3f65cSamw 	(void) fdetach(SMB_SHARE_DNAME);
98da6c28aaSamw 
99*3db3f65cSamw 	if (fattach(smb_share_dsrv_fd, SMB_SHARE_DNAME) < 0) {
1003ad684d6Sjb150015 		syslog(LOG_ERR, "smb_share_dsrv_start: fattach: %s",
101da6c28aaSamw 		    strerror(errno));
1023ad684d6Sjb150015 		(void) door_revoke(smb_share_dsrv_fd);
1033ad684d6Sjb150015 		smb_share_dsrv_fd = -1;
1043ad684d6Sjb150015 		(void) pthread_mutex_unlock(&smb_share_dsrv_mtx);
105da6c28aaSamw 		return (-1);
106da6c28aaSamw 	}
107da6c28aaSamw 
1083ad684d6Sjb150015 	(void) pthread_mutex_unlock(&smb_share_dsrv_mtx);
1093ad684d6Sjb150015 	return (smb_share_dsrv_fd);
110da6c28aaSamw }
111da6c28aaSamw 
112da6c28aaSamw /*
1133ad684d6Sjb150015  * smb_share_dsrv_stop
114da6c28aaSamw  *
115da6c28aaSamw  * Stop the LanMan share door service.
116da6c28aaSamw  */
117da6c28aaSamw void
1183ad684d6Sjb150015 smb_share_dsrv_stop(void)
119da6c28aaSamw {
1203ad684d6Sjb150015 	(void) pthread_mutex_lock(&smb_share_dsrv_mtx);
121da6c28aaSamw 
1223ad684d6Sjb150015 	if (smb_share_dsrv_fd != -1) {
123*3db3f65cSamw 		(void) fdetach(SMB_SHARE_DNAME);
1243ad684d6Sjb150015 		(void) door_revoke(smb_share_dsrv_fd);
1253ad684d6Sjb150015 		smb_share_dsrv_fd = -1;
126da6c28aaSamw 	}
127da6c28aaSamw 
1283ad684d6Sjb150015 	(void) pthread_mutex_unlock(&smb_share_dsrv_mtx);
129da6c28aaSamw }
130da6c28aaSamw 
131da6c28aaSamw /*
1323ad684d6Sjb150015  * smb_share_dsrv_dispatch
133da6c28aaSamw  *
134da6c28aaSamw  * This function with which the LMSHARE door is associated
135da6c28aaSamw  * will invoke the appropriate CIFS share management function
136da6c28aaSamw  * based on the request type of the door call.
137da6c28aaSamw  */
138da6c28aaSamw /*ARGSUSED*/
1393ad684d6Sjb150015 static void
1403ad684d6Sjb150015 smb_share_dsrv_dispatch(void *cookie, char *ptr, size_t size, door_desc_t *dp,
141da6c28aaSamw     uint_t n_desc)
142da6c28aaSamw {
143*3db3f65cSamw 	uint32_t rc;
144*3db3f65cSamw 	int req_type;
145*3db3f65cSamw 	char buf[SMB_SHARE_DSIZE];
146da6c28aaSamw 	unsigned int used;
1473ad684d6Sjb150015 	smb_dr_ctx_t *dec_ctx;
1483ad684d6Sjb150015 	smb_dr_ctx_t *enc_ctx;
149da6c28aaSamw 	unsigned int dec_status;
150da6c28aaSamw 	unsigned int enc_status;
151da6c28aaSamw 	char *sharename, *sharename2;
152*3db3f65cSamw 	smb_share_t lmshr_info;
153*3db3f65cSamw 	smb_shrlist_t lmshr_list;
1543ad684d6Sjb150015 	smb_enumshare_info_t esi;
1553ad684d6Sjb150015 	int offset;
156da6c28aaSamw 
157*3db3f65cSamw 	if ((cookie != SMB_SHARE_DSRV_COOKIE) || (ptr == NULL) ||
1583ad684d6Sjb150015 	    (size < sizeof (uint32_t))) {
1593ad684d6Sjb150015 		(void) door_return(NULL, 0, NULL, 0);
1603ad684d6Sjb150015 	}
1613ad684d6Sjb150015 
1623ad684d6Sjb150015 	dec_ctx = smb_dr_decode_start(ptr, size);
1633ad684d6Sjb150015 	enc_ctx = smb_dr_encode_start(buf, sizeof (buf));
164da6c28aaSamw 	req_type = smb_dr_get_uint32(dec_ctx);
165da6c28aaSamw 
166da6c28aaSamw 	switch (req_type) {
167*3db3f65cSamw 	case SMB_SHROP_NUM_SHARES:
168da6c28aaSamw 		if ((dec_status = smb_dr_decode_finish(dec_ctx)) != 0)
169da6c28aaSamw 			goto decode_error;
170da6c28aaSamw 
171*3db3f65cSamw 		rc = smb_shr_count();
172*3db3f65cSamw 		smb_dr_put_int32(enc_ctx, SMB_SHARE_DSUCCESS);
173da6c28aaSamw 		smb_dr_put_uint32(enc_ctx, rc);
174da6c28aaSamw 		break;
175da6c28aaSamw 
176*3db3f65cSamw 	case SMB_SHROP_DELETE:
177da6c28aaSamw 		sharename = smb_dr_get_string(dec_ctx);
178da6c28aaSamw 
179da6c28aaSamw 		if ((dec_status = smb_dr_decode_finish(dec_ctx)) != 0) {
180da6c28aaSamw 			smb_dr_free_string(sharename);
181da6c28aaSamw 			goto decode_error;
182da6c28aaSamw 		}
183da6c28aaSamw 
184*3db3f65cSamw 		rc = smb_shr_del(sharename, 0);
185*3db3f65cSamw 		smb_dr_put_int32(enc_ctx, SMB_SHARE_DSUCCESS);
186da6c28aaSamw 		smb_dr_put_uint32(enc_ctx, rc);
187da6c28aaSamw 		smb_dr_free_string(sharename);
188da6c28aaSamw 		break;
189da6c28aaSamw 
190*3db3f65cSamw 	case SMB_SHROP_RENAME:
191da6c28aaSamw 		sharename = smb_dr_get_string(dec_ctx);
192da6c28aaSamw 		sharename2 = smb_dr_get_string(dec_ctx);
193da6c28aaSamw 
194da6c28aaSamw 		if ((dec_status = smb_dr_decode_finish(dec_ctx)) != 0) {
195da6c28aaSamw 			smb_dr_free_string(sharename);
196da6c28aaSamw 			smb_dr_free_string(sharename2);
197da6c28aaSamw 			goto decode_error;
198da6c28aaSamw 		}
199da6c28aaSamw 
200*3db3f65cSamw 		rc = smb_shr_ren(sharename, sharename2, 0);
201*3db3f65cSamw 		smb_dr_put_int32(enc_ctx, SMB_SHARE_DSUCCESS);
202da6c28aaSamw 		smb_dr_put_uint32(enc_ctx, rc);
203da6c28aaSamw 		smb_dr_free_string(sharename);
204da6c28aaSamw 		smb_dr_free_string(sharename2);
205da6c28aaSamw 		break;
206da6c28aaSamw 
207*3db3f65cSamw 	case SMB_SHROP_GETINFO:
208da6c28aaSamw 		sharename = smb_dr_get_string(dec_ctx);
209da6c28aaSamw 		if ((dec_status = smb_dr_decode_finish(dec_ctx)) != 0) {
210da6c28aaSamw 			smb_dr_free_string(sharename);
211da6c28aaSamw 			goto decode_error;
212da6c28aaSamw 		}
213da6c28aaSamw 
214*3db3f65cSamw 		rc = smb_shr_get(sharename, &lmshr_info);
215*3db3f65cSamw 		smb_dr_put_int32(enc_ctx, SMB_SHARE_DSUCCESS);
216da6c28aaSamw 		smb_dr_put_uint32(enc_ctx, rc);
217*3db3f65cSamw 		smb_dr_put_share(enc_ctx, &lmshr_info);
218da6c28aaSamw 		smb_dr_free_string(sharename);
219da6c28aaSamw 		break;
220da6c28aaSamw 
221*3db3f65cSamw 	case SMB_SHROP_ADD:
222*3db3f65cSamw 		smb_dr_get_share(dec_ctx, &lmshr_info);
223da6c28aaSamw 		if ((dec_status = smb_dr_decode_finish(dec_ctx)) != 0)
224da6c28aaSamw 			goto decode_error;
225da6c28aaSamw 
226*3db3f65cSamw 		rc = smb_shr_add(&lmshr_info, 0);
227*3db3f65cSamw 		smb_dr_put_int32(enc_ctx, SMB_SHARE_DSUCCESS);
228da6c28aaSamw 		smb_dr_put_uint32(enc_ctx, rc);
229*3db3f65cSamw 		smb_dr_put_share(enc_ctx, &lmshr_info);
230da6c28aaSamw 		break;
231da6c28aaSamw 
232*3db3f65cSamw 	case SMB_SHROP_SETINFO:
233*3db3f65cSamw 		smb_dr_get_share(dec_ctx, &lmshr_info);
234da6c28aaSamw 		if ((dec_status = smb_dr_decode_finish(dec_ctx)) != 0)
235da6c28aaSamw 			goto decode_error;
236da6c28aaSamw 
237*3db3f65cSamw 		rc = smb_shr_set(&lmshr_info, 0);
238*3db3f65cSamw 		smb_dr_put_int32(enc_ctx, SMB_SHARE_DSUCCESS);
239da6c28aaSamw 		smb_dr_put_uint32(enc_ctx, rc);
240da6c28aaSamw 		break;
241da6c28aaSamw 
242*3db3f65cSamw 	case SMB_SHROP_LIST:
243da6c28aaSamw 		offset = smb_dr_get_int32(dec_ctx);
244da6c28aaSamw 		if ((dec_status = smb_dr_decode_finish(dec_ctx)) != 0)
245da6c28aaSamw 			goto decode_error;
246da6c28aaSamw 
247*3db3f65cSamw 		smb_shr_list(offset, &lmshr_list);
248*3db3f65cSamw 		smb_dr_put_int32(enc_ctx, SMB_SHARE_DSUCCESS);
249*3db3f65cSamw 		smb_dr_put_shrlist(enc_ctx, &lmshr_list);
250da6c28aaSamw 		break;
251da6c28aaSamw 
252*3db3f65cSamw 	case SMB_SHROP_ENUM:
2533ad684d6Sjb150015 		esi.es_bufsize = smb_dr_get_ushort(dec_ctx);
2543ad684d6Sjb150015 		esi.es_username = smb_dr_get_string(dec_ctx);
2553ad684d6Sjb150015 		if ((dec_status = smb_dr_decode_finish(dec_ctx)) != 0) {
2563ad684d6Sjb150015 			smb_dr_free_string(esi.es_username);
257cbfb650aScp160787 			goto decode_error;
2583ad684d6Sjb150015 		}
259cbfb650aScp160787 
2603ad684d6Sjb150015 		rc = smb_share_dsrv_enum(&esi);
2613ad684d6Sjb150015 
2623ad684d6Sjb150015 		smb_dr_free_string(esi.es_username);
2633ad684d6Sjb150015 
264*3db3f65cSamw 		smb_dr_put_int32(enc_ctx, SMB_SHARE_DSUCCESS);
2653ad684d6Sjb150015 		smb_dr_put_uint32(enc_ctx, rc);
2663ad684d6Sjb150015 		if (rc == NERR_Success) {
2673ad684d6Sjb150015 			smb_dr_put_ushort(enc_ctx, esi.es_ntotal);
2683ad684d6Sjb150015 			smb_dr_put_ushort(enc_ctx, esi.es_nsent);
2693ad684d6Sjb150015 			smb_dr_put_ushort(enc_ctx, esi.es_datasize);
2703ad684d6Sjb150015 			smb_dr_put_buf(enc_ctx,
2713ad684d6Sjb150015 			    (unsigned char *)esi.es_buf, esi.es_bufsize);
2723ad684d6Sjb150015 			free(esi.es_buf);
2733ad684d6Sjb150015 		}
274da6c28aaSamw 		break;
275da6c28aaSamw 
276da6c28aaSamw 	default:
277cbfb650aScp160787 		dec_status = smb_dr_decode_finish(dec_ctx);
278da6c28aaSamw 		goto decode_error;
279da6c28aaSamw 	}
280da6c28aaSamw 
2813ad684d6Sjb150015 	if ((enc_status = smb_dr_encode_finish(enc_ctx, &used)) != 0) {
2823ad684d6Sjb150015 		enc_ctx = smb_dr_encode_start(buf, sizeof (buf));
283*3db3f65cSamw 		smb_dr_put_int32(enc_ctx, SMB_SHARE_DERROR);
2843ad684d6Sjb150015 		smb_dr_put_uint32(enc_ctx, enc_status);
2853ad684d6Sjb150015 		(void) smb_dr_encode_finish(enc_ctx, &used);
2863ad684d6Sjb150015 	}
287da6c28aaSamw 
288da6c28aaSamw 	(void) door_return(buf, used, NULL, 0);
289da6c28aaSamw 	return;
290da6c28aaSamw 
291da6c28aaSamw decode_error:
292*3db3f65cSamw 	smb_dr_put_int32(enc_ctx, SMB_SHARE_DERROR);
293da6c28aaSamw 	smb_dr_put_uint32(enc_ctx, dec_status);
294da6c28aaSamw 	(void) smb_dr_encode_finish(enc_ctx, &used);
295da6c28aaSamw 	(void) door_return(buf, used, NULL, 0);
296da6c28aaSamw }
297da6c28aaSamw 
298da6c28aaSamw /*
2993ad684d6Sjb150015  * smb_share_dsrv_enum
3003ad684d6Sjb150015  *
3013ad684d6Sjb150015  * This function builds a response for a NetShareEnum RAP request which
3023ad684d6Sjb150015  * originates from smbsrv kernel module. A response buffer is allocated
3033ad684d6Sjb150015  * with the specified size in esi->es_bufsize. List of shares is scanned
3043ad684d6Sjb150015  * twice. In the first round the total number of shares which their OEM
3053ad684d6Sjb150015  * name is shorter than 13 chars (esi->es_ntotal) and also the number of
3063ad684d6Sjb150015  * shares that fit in the given buffer are calculated. In the second
3073ad684d6Sjb150015  * round the shares data are encoded in the buffer.
3083ad684d6Sjb150015  *
3093ad684d6Sjb150015  * The data associated with each share has two parts, a fixed size part and
3103ad684d6Sjb150015  * a variable size part which is share's comment. The outline of the response
3113ad684d6Sjb150015  * buffer is so that fixed part for all the shares will appear first and follows
3123ad684d6Sjb150015  * with the comments for all those shares and that's why the data cannot be
3133ad684d6Sjb150015  * encoded in one round without unnecessarily complicating the code.
3143ad684d6Sjb150015  */
3153ad684d6Sjb150015 static int
3163ad684d6Sjb150015 smb_share_dsrv_enum(smb_enumshare_info_t *esi)
3173ad684d6Sjb150015 {
318*3db3f65cSamw 	smb_shriter_t shi;
319*3db3f65cSamw 	smb_share_t *si;
3203ad684d6Sjb150015 	int remained;
3213ad684d6Sjb150015 	uint16_t infolen = 0;
3223ad684d6Sjb150015 	uint16_t cmntlen = 0;
3233ad684d6Sjb150015 	uint16_t sharelen;
3243ad684d6Sjb150015 	uint16_t clen;
3253ad684d6Sjb150015 	uint32_t cmnt_offs;
3263ad684d6Sjb150015 	smb_msgbuf_t info_mb;
3273ad684d6Sjb150015 	smb_msgbuf_t cmnt_mb;
3283ad684d6Sjb150015 	boolean_t autohome_added = B_FALSE;
3293ad684d6Sjb150015 
3303ad684d6Sjb150015 	esi->es_ntotal = esi->es_nsent = 0;
3313ad684d6Sjb150015 
3323ad684d6Sjb150015 	if ((esi->es_buf = malloc(esi->es_bufsize)) == NULL)
3333ad684d6Sjb150015 		return (NERR_InternalError);
3343ad684d6Sjb150015 
3353ad684d6Sjb150015 	bzero(esi->es_buf, esi->es_bufsize);
3363ad684d6Sjb150015 	remained = esi->es_bufsize;
3373ad684d6Sjb150015 
3383ad684d6Sjb150015 	/* Do the necessary calculations in the first round */
339*3db3f65cSamw 	smb_shr_iterinit(&shi, SMB_SHRF_ALL);
3403ad684d6Sjb150015 
341*3db3f65cSamw 	while ((si = smb_shr_iterate(&shi)) != NULL) {
342*3db3f65cSamw 		if (si->shr_flags & SMB_SHRF_LONGNAME)
3433ad684d6Sjb150015 			continue;
3443ad684d6Sjb150015 
345*3db3f65cSamw 		if ((si->shr_flags & SMB_SHRF_AUTOHOME) && !autohome_added) {
346*3db3f65cSamw 			if (strcasecmp(esi->es_username, si->shr_name) == 0)
3473ad684d6Sjb150015 				autohome_added = B_TRUE;
3483ad684d6Sjb150015 			else
3493ad684d6Sjb150015 				continue;
3503ad684d6Sjb150015 		}
3513ad684d6Sjb150015 
3523ad684d6Sjb150015 		esi->es_ntotal++;
3533ad684d6Sjb150015 
3543ad684d6Sjb150015 		if (remained <= 0)
3553ad684d6Sjb150015 			continue;
3563ad684d6Sjb150015 
357*3db3f65cSamw 		clen = strlen(si->shr_cmnt) + 1;
3583ad684d6Sjb150015 		sharelen = SHARE_INFO_1_SIZE + clen;
3593ad684d6Sjb150015 
3603ad684d6Sjb150015 		if (sharelen <= remained) {
3613ad684d6Sjb150015 			infolen += SHARE_INFO_1_SIZE;
3623ad684d6Sjb150015 			cmntlen += clen;
3633ad684d6Sjb150015 		}
3643ad684d6Sjb150015 
3653ad684d6Sjb150015 		remained -= sharelen;
3663ad684d6Sjb150015 	}
3673ad684d6Sjb150015 
3683ad684d6Sjb150015 	esi->es_datasize = infolen + cmntlen;
3693ad684d6Sjb150015 
3703ad684d6Sjb150015 	smb_msgbuf_init(&info_mb, (uint8_t *)esi->es_buf, infolen, 0);
3713ad684d6Sjb150015 	smb_msgbuf_init(&cmnt_mb, (uint8_t *)esi->es_buf + infolen, cmntlen, 0);
3723ad684d6Sjb150015 	cmnt_offs = infolen;
3733ad684d6Sjb150015 
3743ad684d6Sjb150015 	/* Encode the data in the second round */
375*3db3f65cSamw 	smb_shr_iterinit(&shi, SMB_SHRF_ALL);
3763ad684d6Sjb150015 	autohome_added = B_FALSE;
3773ad684d6Sjb150015 
378*3db3f65cSamw 	while ((si = smb_shr_iterate(&shi)) != NULL) {
379*3db3f65cSamw 		if (si->shr_flags & SMB_SHRF_LONGNAME)
3803ad684d6Sjb150015 			continue;
3813ad684d6Sjb150015 
382*3db3f65cSamw 		if ((si->shr_flags & SMB_SHRF_AUTOHOME) && !autohome_added) {
383*3db3f65cSamw 			if (strcasecmp(esi->es_username, si->shr_name) == 0)
3843ad684d6Sjb150015 				autohome_added = B_TRUE;
3853ad684d6Sjb150015 			else
3863ad684d6Sjb150015 				continue;
3873ad684d6Sjb150015 		}
3883ad684d6Sjb150015 
3893ad684d6Sjb150015 		if (smb_msgbuf_encode(&info_mb, "13c.wl",
390*3db3f65cSamw 		    si->shr_oemname, si->shr_type, cmnt_offs) < 0)
3913ad684d6Sjb150015 			break;
3923ad684d6Sjb150015 
393*3db3f65cSamw 		if (smb_msgbuf_encode(&cmnt_mb, "s", si->shr_cmnt) < 0)
3943ad684d6Sjb150015 			break;
3953ad684d6Sjb150015 
396*3db3f65cSamw 		cmnt_offs += strlen(si->shr_cmnt) + 1;
3973ad684d6Sjb150015 		esi->es_nsent++;
3983ad684d6Sjb150015 	}
3993ad684d6Sjb150015 
4003ad684d6Sjb150015 	smb_msgbuf_term(&info_mb);
4013ad684d6Sjb150015 	smb_msgbuf_term(&cmnt_mb);
4023ad684d6Sjb150015 
4033ad684d6Sjb150015 	return (NERR_Success);
4043ad684d6Sjb150015 }
405