xref: /illumos-gate/usr/src/uts/common/fs/smbsrv/smb_find.c (revision d2488fe8c5950495aef5404c8d98081be7d43487)
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 /*
22148c5f43SAlan Wright  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
2393bc28dbSGordon Ross  * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
24da6c28aaSamw  */
25da6c28aaSamw 
26bbf6f00cSJordan Brown #include <smbsrv/smb_kproto.h>
27da6c28aaSamw 
28da6c28aaSamw /*
297f667e74Sjose borrego  * smb_com_search
307f667e74Sjose borrego  * smb_com_find, smb_com_find_close
317f667e74Sjose borrego  * smb_find_unique
32da6c28aaSamw  *
337f667e74Sjose borrego  * These commands are used for directory searching. They share the same
347f667e74Sjose borrego  * message formats, defined below:
35da6c28aaSamw  *
36da6c28aaSamw  * Client Request                     Description
377f667e74Sjose borrego  * ---------------------------------- ---------------------------------
38da6c28aaSamw  *
397f667e74Sjose borrego  * UCHAR WordCount;                   Count of parameter words = 2
407f667e74Sjose borrego  * USHORT MaxCount;                   Number of dir. entries to return
417f667e74Sjose borrego  * USHORT SearchAttributes;
427f667e74Sjose borrego  * USHORT ByteCount;                  Count of data bytes;  min = 5
437f667e74Sjose borrego  * UCHAR BufferFormat1;               0x04 -- ASCII
447f667e74Sjose borrego  * UCHAR FileName[];                  File name, may be null
457f667e74Sjose borrego  * UCHAR BufferFormat2;               0x05 -- Variable block
467f667e74Sjose borrego  * USHORT ResumeKeyLength;            Length of resume key, may be 0
477f667e74Sjose borrego  * UCHAR ResumeKey[];                 Resume key
48da6c28aaSamw  *
497f667e74Sjose borrego  * FileName specifies the file to be sought.  SearchAttributes indicates
507f667e74Sjose borrego  * the attributes that the file must have.  If  SearchAttributes is
517f667e74Sjose borrego  * zero then only normal files are returned.  If the system file, hidden or
527f667e74Sjose borrego  * directory attributes are specified then the search is inclusive - both the
537f667e74Sjose borrego  * specified type(s) of files and normal files are returned.  If the volume
547f667e74Sjose borrego  * label attribute is specified then the search is exclusive, and only the
557f667e74Sjose borrego  * volume label entry is returned.
567f667e74Sjose borrego  *
577f667e74Sjose borrego  * MaxCount specifies the number of directory entries to be returned.
58da6c28aaSamw  *
59da6c28aaSamw  * Server Response                    Description
607f667e74Sjose borrego  * ---------------------------------- ---------------------------------
61da6c28aaSamw  *
627f667e74Sjose borrego  * UCHAR WordCount;                   Count of parameter words = 1
637f667e74Sjose borrego  * USHORT Count;                      Number of entries returned
647f667e74Sjose borrego  * USHORT ByteCount;                  Count of data bytes;  min = 3
657f667e74Sjose borrego  * UCHAR BufferFormat;                0x05 -- Variable block
667f667e74Sjose borrego  * USHORT DataLength;                 Length of data
677f667e74Sjose borrego  * UCHAR DirectoryInformationData[];  Data
68da6c28aaSamw  *
697f667e74Sjose borrego  * The response will contain one or more directory entries as determined by
707f667e74Sjose borrego  * the Count field.  No more than MaxCount entries will be returned.  Only
717f667e74Sjose borrego  * entries that match the sought FileName and SearchAttributes combination
727f667e74Sjose borrego  * will be returned.
73da6c28aaSamw  *
747f667e74Sjose borrego  * ResumeKey must be null (length = 0) on the initial search request.
757f667e74Sjose borrego  * Subsequent search requests intended to continue a search must contain
767f667e74Sjose borrego  * the ResumeKey field extracted from the last directory entry of the
777f667e74Sjose borrego  * previous response.  ResumeKey is self-contained, for calls containing
787f667e74Sjose borrego  * a non-zero ResumeKey neither the SearchAttributes or FileName fields
797f667e74Sjose borrego  * will be valid in the request.  ResumeKey has the following format:
80da6c28aaSamw  *
817f667e74Sjose borrego  * Resume Key Field                   Description
827f667e74Sjose borrego  * ---------------------------------- ---------------------------------
837f667e74Sjose borrego  *
847f667e74Sjose borrego  * UCHAR Reserved;                    bit 7 - consumer use
857f667e74Sjose borrego  *                                    bits 5,6 - system use (must preserve)
867f667e74Sjose borrego  *                                    bits 0-4 - server use (must preserve)
877f667e74Sjose borrego  * UCHAR FileName[11];                Name of the returned file
887f667e74Sjose borrego  * UCHAR ReservedForServer[5];        Client must not modify
897f667e74Sjose borrego  *                                    byte 0 - uniquely identifies find
907f667e74Sjose borrego  *                                    through find_close
917f667e74Sjose borrego  *                                    bytes 1-4 - available for server use
92da6c28aaSamw  *                                    (must be non-zero)
937f667e74Sjose borrego  * UCHAR ReservedForConsumer[4];      Server must not modify
94da6c28aaSamw  *
957f667e74Sjose borrego  * FileName is 8.3 format, with the three character extension left
967f667e74Sjose borrego  * justified into FileName[9-11].
97da6c28aaSamw  *
987f667e74Sjose borrego  * There may be multiple matching entries in response to a single request
997f667e74Sjose borrego  * as wildcards are supported in the last component of FileName of the
1007f667e74Sjose borrego  * initial request.
101da6c28aaSamw  *
1027f667e74Sjose borrego  * Returned directory entries in the DirectoryInformationData field of the
1037f667e74Sjose borrego  * response each have the following format:
104da6c28aaSamw  *
1057f667e74Sjose borrego  * Directory Information Field        Description
1067f667e74Sjose borrego  * ---------------------------------- ---------------------------------
107da6c28aaSamw  *
1087f667e74Sjose borrego  * SMB_RESUME_KEY ResumeKey;          Described above
1097f667e74Sjose borrego  * UCHAR FileAttributes;              Attributes of the found file
1107f667e74Sjose borrego  * SMB_TIME LastWriteTime;            Time file was last written
1117f667e74Sjose borrego  * SMB_DATE LastWriteDate;            Date file was last written
1127f667e74Sjose borrego  * ULONG FileSize;                    Size of the file
1137f667e74Sjose borrego  * UCHAR FileName[13];                ASCII, space-filled null terminated
1147f667e74Sjose borrego  *
1157f667e74Sjose borrego  * FileName must conform to 8.3 rules, and is padded after the extension
1167f667e74Sjose borrego  * with 0x20 characters if necessary.
1177f667e74Sjose borrego  *
1187f667e74Sjose borrego  * As can be seen from the above structure, these commands cannot return
1197f667e74Sjose borrego  * long filenames, and cannot return UNICODE filenames.
1207f667e74Sjose borrego  *
1217f667e74Sjose borrego  * Files which have a size greater than 2^32 bytes should have the least
1227f667e74Sjose borrego  * significant 32 bits of their size returned in FileSize.
1237f667e74Sjose borrego  *
1247f667e74Sjose borrego  * smb_com_search
1257f667e74Sjose borrego  * --------------
1267f667e74Sjose borrego  *
1277f667e74Sjose borrego  * If the client is prior to the LANMAN1.0 dialect, the returned FileName
1287f667e74Sjose borrego  * should be uppercased.
1297f667e74Sjose borrego  * If the client has negotiated a dialect prior to the LANMAN1.0 dialect,
1307f667e74Sjose borrego  * or if bit0 of the Flags2 SMB header field of the request is clear,
1317f667e74Sjose borrego  * the returned FileName should be uppercased.
1327f667e74Sjose borrego  *
1337f667e74Sjose borrego  * SMB_COM_SEARCH terminates when either the requested maximum number of
1347f667e74Sjose borrego  * entries that match the named file are found, or the end of directory is
1357f667e74Sjose borrego  * reached without the maximum number of matches being found.  A response
1367f667e74Sjose borrego  * containing no entries indicates that no matching entries were found
1377f667e74Sjose borrego  * between the starting point of the search and the end of directory.
1387f667e74Sjose borrego  *
1397f667e74Sjose borrego  *
1407f667e74Sjose borrego  * The find, find_close and find_unique protocols may be used in place of
1417f667e74Sjose borrego  * the core "search" protocol when LANMAN 1.0 dialect has been negotiated.
1427f667e74Sjose borrego  *
1437f667e74Sjose borrego  * smb_com_find
1447f667e74Sjose borrego  * ------------
1457f667e74Sjose borrego  *
1467f667e74Sjose borrego  * The find protocol is used to match the find OS/2 system call.
1477f667e74Sjose borrego  *
1487f667e74Sjose borrego  * The format of the find protocol is the same as the core "search" protocol.
1497f667e74Sjose borrego  * The difference is that the directory is logically Opened with a find protocol
1507f667e74Sjose borrego  * and logically closed with the find close protocol.
1517f667e74Sjose borrego  * As is true of a failing open, if a find request (find "first" request where
152da6c28aaSamw  * resume_key is null) fails (no entries are found), no find close protocol is
153da6c28aaSamw  * expected.
154da6c28aaSamw  *
1557f667e74Sjose borrego  * If no global characters are present, a "find unique" protocol should be used
156da6c28aaSamw  * (only one entry is expected and find close need not be sent).
157da6c28aaSamw  *
1587f667e74Sjose borrego  * A find request will terminate when either the requested maximum number of
1597f667e74Sjose borrego  * entries that match the named file are found, or the end of directory is
1607f667e74Sjose borrego  * reached without the maximum number of matches being found. A response
1617f667e74Sjose borrego  * containing no entries indicates that no matching entries were found between
1627f667e74Sjose borrego  * the starting point of the search and the end of directory.
163da6c28aaSamw  *
1647f667e74Sjose borrego  * If a find requests more data than can be placed in a message of the
165da6c28aaSamw  * max-xmit-size for the TID specified, the server will return only the number
166da6c28aaSamw  * of entries which will fit.
167da6c28aaSamw  *
168da6c28aaSamw  *
1697f667e74Sjose borrego  * smb_com_find_close
1707f667e74Sjose borrego  * ------------------
171da6c28aaSamw  *
1727f667e74Sjose borrego  * The find close protocol is used to match the find close OS/2 system call.
173da6c28aaSamw  *
1747f667e74Sjose borrego  * Whereas the first find protocol logically opens the directory, subsequent
1757f667e74Sjose borrego  * find  protocols presenting a resume_key further "read" the directory, the
1767f667e74Sjose borrego  * find close  protocol "closes" the  directory allowing the server to free any
1777f667e74Sjose borrego  * resources held in support of the directory search.
178da6c28aaSamw  *
1797f667e74Sjose borrego  * In our implementation this translates to closing the odir.
180da6c28aaSamw  *
1817f667e74Sjose borrego  *
1827f667e74Sjose borrego  * smb_com_find_unique
1837f667e74Sjose borrego  * -------------------
1847f667e74Sjose borrego  *
1857f667e74Sjose borrego  * The format of the find unique protocol is the same as the core "search"
1867f667e74Sjose borrego  * protocol. The difference is that the directory is logically opened, any
1877f667e74Sjose borrego  * matching entries returned, and then the directory is logically closed.
1887f667e74Sjose borrego  *
1897f667e74Sjose borrego  * The resume search key key will be returned as in the find protocol and
1907f667e74Sjose borrego  * search protocol however it may NOT be returned to continue the search.
1917f667e74Sjose borrego  * Only one buffer of entries is expected and find close need not be sent.
1927f667e74Sjose borrego  *
1937f667e74Sjose borrego  * If a find unique requests more data than can be placed in a message of the
1947f667e74Sjose borrego  * max-xmit-size for the TID specified, the server will abort the virtual
1957f667e74Sjose borrego  * circuit to the consumer.
196da6c28aaSamw  */
1977f667e74Sjose borrego 
198148c5f43SAlan Wright #define	SMB_NAME83_BUFLEN	12
199148c5f43SAlan Wright static void smb_name83(const char *, char *, size_t);
200148c5f43SAlan Wright 
2017f667e74Sjose borrego /* *** smb_com_search *** */
2027f667e74Sjose borrego 
2037f667e74Sjose borrego smb_sdrc_t
smb_pre_search(smb_request_t * sr)2047f667e74Sjose borrego smb_pre_search(smb_request_t *sr)
2057f667e74Sjose borrego {
20693bc28dbSGordon Ross 	DTRACE_SMB_START(op__Search, smb_request_t *, sr);
2077f667e74Sjose borrego 	return (SDRC_SUCCESS);
2087f667e74Sjose borrego }
2097f667e74Sjose borrego 
2107f667e74Sjose borrego void
smb_post_search(smb_request_t * sr)2117f667e74Sjose borrego smb_post_search(smb_request_t *sr)
2127f667e74Sjose borrego {
21393bc28dbSGordon Ross 	DTRACE_SMB_DONE(op__Search, smb_request_t *, sr);
2147f667e74Sjose borrego }
2157f667e74Sjose borrego 
2167f667e74Sjose borrego smb_sdrc_t
smb_com_search(smb_request_t * sr)2177f667e74Sjose borrego smb_com_search(smb_request_t *sr)
2187f667e74Sjose borrego {
2197f667e74Sjose borrego 	int			rc;
2207f667e74Sjose borrego 	uint16_t		count, maxcount, index;
2217f667e74Sjose borrego 	uint16_t		sattr, odid;
2227f667e74Sjose borrego 	uint16_t		key_len;
2237f667e74Sjose borrego 	uint32_t		client_key;
2247f667e74Sjose borrego 	char			name[SMB_SHORTNAMELEN];
225148c5f43SAlan Wright 	char			name83[SMB_SHORTNAMELEN];
2269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_pathname_t		*pn;
2277f667e74Sjose borrego 	unsigned char		resume_char;
2287f667e74Sjose borrego 	unsigned char		type;
2297f667e74Sjose borrego 	boolean_t		find_first, to_upper;
2307f667e74Sjose borrego 	smb_tree_t		*tree;
2317f667e74Sjose borrego 	smb_odir_t		*od;
2327f667e74Sjose borrego 	smb_fileinfo_t		fileinfo;
2337f667e74Sjose borrego 	smb_odir_resume_t	odir_resume;
234a90cf9f2SGordon Ross 	uint32_t		status;
235bfbce3c1SGordon Ross 	uint16_t		eos;
2367f667e74Sjose borrego 
2377f667e74Sjose borrego 	to_upper = B_FALSE;
2387f667e74Sjose borrego 	if ((sr->session->dialect <= LANMAN1_0) ||
2397f667e74Sjose borrego 	    ((sr->smb_flg2 & SMB_FLAGS2_KNOWS_LONG_NAMES) == 0)) {
2407f667e74Sjose borrego 		to_upper = B_TRUE;
2417f667e74Sjose borrego 	}
2427f667e74Sjose borrego 
2437f667e74Sjose borrego 	/* We only handle 8.3 name here */
2447f667e74Sjose borrego 	sr->smb_flg2 &= ~SMB_FLAGS2_KNOWS_LONG_NAMES;
2457f667e74Sjose borrego 	sr->smb_flg &= ~SMB_FLAGS_CASE_INSENSITIVE;
2467f667e74Sjose borrego 
2477f667e74Sjose borrego 	if (smbsr_decode_vwv(sr, "ww", &maxcount, &sattr) != 0)
2487f667e74Sjose borrego 		return (SDRC_ERROR);
2497f667e74Sjose borrego 
2509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	pn = &sr->arg.dirop.fqi.fq_path;
2519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	rc = smbsr_decode_data(sr, "%Abw", sr, &pn->pn_path, &type, &key_len);
2527f667e74Sjose borrego 	if ((rc != 0) || (type != 0x05))
2537f667e74Sjose borrego 		return (SDRC_ERROR);
2547f667e74Sjose borrego 
2559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_pathname_init(sr, pn, pn->pn_path);
2569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_pathname_validate(sr, pn) ||
2579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    smb_is_stream_name(pn->pn_path)) {
2589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smbsr_warn(sr, NT_STATUS_NO_MORE_FILES,
2599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    ERRDOS, ERROR_NO_MORE_FILES);
2609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SDRC_ERROR);
2619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
2629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2637f667e74Sjose borrego 	tree = sr->tid_tree;
2647f667e74Sjose borrego 
2657f667e74Sjose borrego 	/* Volume information only */
2667f667e74Sjose borrego 	if ((sattr == FILE_ATTRIBUTE_VOLUME) && (key_len != 21)) {
2677f667e74Sjose borrego 		(void) memset(name, ' ', sizeof (name));
2687f667e74Sjose borrego 		(void) strncpy(name, tree->t_volume, sizeof (name));
2697f667e74Sjose borrego 
2707f667e74Sjose borrego 		if (key_len >= 21) {
2717f667e74Sjose borrego 			(void) smb_mbc_decodef(&sr->smb_data, "17.l",
2727f667e74Sjose borrego 			    &client_key);
2737f667e74Sjose borrego 		} else {
2747f667e74Sjose borrego 			client_key = 0;
2757f667e74Sjose borrego 		}
2767f667e74Sjose borrego 
2777f667e74Sjose borrego 		(void) smb_mbc_encodef(&sr->reply, "bwwbwb11c5.lb8.13c",
2789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    1, 0, VAR_BCC, 5, 0, 0, pn->pn_path+1,
2797f667e74Sjose borrego 		    client_key, sattr, name);
2807f667e74Sjose borrego 
2817f667e74Sjose borrego 		rc = (sr->reply.chain_offset - sr->cur_reply_offset) - 8;
2827f667e74Sjose borrego 		(void) smb_mbc_poke(&sr->reply, sr->cur_reply_offset, "bwwbw",
2837f667e74Sjose borrego 		    1, 1, rc+3, 5, rc);
2847f667e74Sjose borrego 
2857f667e74Sjose borrego 		return (SDRC_SUCCESS);
2867f667e74Sjose borrego 	}
2877f667e74Sjose borrego 
2887f667e74Sjose borrego 	if ((key_len != 0) && (key_len != 21))
2897f667e74Sjose borrego 		return (SDRC_ERROR);
2907f667e74Sjose borrego 
2917f667e74Sjose borrego 	find_first = (key_len == 0);
2927f667e74Sjose borrego 	resume_char = 0;
2937f667e74Sjose borrego 	client_key = 0;
2947f667e74Sjose borrego 
2957f667e74Sjose borrego 	if (find_first) {
296a90cf9f2SGordon Ross 		status = smb_odir_openpath(sr, pn->pn_path, sattr, 0, &od);
297a90cf9f2SGordon Ross 		if (status != 0) {
298a90cf9f2SGordon Ross 			if (status == NT_STATUS_ACCESS_DENIED)
2997f667e74Sjose borrego 				smbsr_warn(sr, NT_STATUS_NO_MORE_FILES,
3007f667e74Sjose borrego 				    ERRDOS, ERROR_NO_MORE_FILES);
3017f667e74Sjose borrego 			return (SDRC_ERROR);
3027f667e74Sjose borrego 		}
303*d2488fe8SGordon Ross 		odid = od->d_odid;
3047f667e74Sjose borrego 	} else {
3057f667e74Sjose borrego 		if (smb_mbc_decodef(&sr->smb_data, "b12.wwl",
3067f667e74Sjose borrego 		    &resume_char, &index, &odid, &client_key) != 0) {
3077f667e74Sjose borrego 			return (SDRC_ERROR);
3087f667e74Sjose borrego 		}
309a90cf9f2SGordon Ross 		od = smb_tree_lookup_odir(sr, odid);
3107f667e74Sjose borrego 	}
3117f667e74Sjose borrego 
3127f667e74Sjose borrego 	if (od == NULL) {
3137f667e74Sjose borrego 		smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
3147f667e74Sjose borrego 		    ERRDOS, ERROR_INVALID_HANDLE);
3157f667e74Sjose borrego 		return (SDRC_ERROR);
3167f667e74Sjose borrego 	}
3177f667e74Sjose borrego 
3187f667e74Sjose borrego 	if (!find_first) {
319a90cf9f2SGordon Ross 		if ((od->d_flags & SMB_ODIR_FLAG_WILDCARDS) == 0) {
320a90cf9f2SGordon Ross 			od->d_eof = B_TRUE;
321a90cf9f2SGordon Ross 		} else {
3227f667e74Sjose borrego 			odir_resume.or_type = SMB_ODIR_RESUME_IDX;
3237f667e74Sjose borrego 			odir_resume.or_idx = index;
3247f667e74Sjose borrego 			smb_odir_resume_at(od, &odir_resume);
3257f667e74Sjose borrego 		}
326a90cf9f2SGordon Ross 	}
3277f667e74Sjose borrego 
3287f667e74Sjose borrego 	(void) smb_mbc_encodef(&sr->reply, "bwwbw", 1, 0, VAR_BCC, 5, 0);
3297f667e74Sjose borrego 
3307f667e74Sjose borrego 	rc = 0;
3317f667e74Sjose borrego 	index = 0;
3327f667e74Sjose borrego 	count = 0;
3337f667e74Sjose borrego 	if (maxcount > SMB_MAX_SEARCH)
3347f667e74Sjose borrego 		maxcount = SMB_MAX_SEARCH;
3357f667e74Sjose borrego 
3367f667e74Sjose borrego 	while (count < maxcount) {
3377f667e74Sjose borrego 		rc = smb_odir_read_fileinfo(sr, od, &fileinfo, &eos);
338bfbce3c1SGordon Ross 		if (rc != 0 || eos != 0)
3397f667e74Sjose borrego 			break;
3407f667e74Sjose borrego 
341743a77edSAlan Wright 		if (*fileinfo.fi_shortname == '\0') {
342cb174861Sjoyce mcintosh 			if (smb_needs_mangled(fileinfo.fi_name))
343cb174861Sjoyce mcintosh 				continue;
344148c5f43SAlan Wright 			(void) strlcpy(fileinfo.fi_shortname, fileinfo.fi_name,
345743a77edSAlan Wright 			    SMB_SHORTNAMELEN - 1);
3467f667e74Sjose borrego 			if (to_upper)
347148c5f43SAlan Wright 				(void) smb_strupr(fileinfo.fi_shortname);
3487f667e74Sjose borrego 		}
349148c5f43SAlan Wright 		smb_name83(fileinfo.fi_shortname, name83, SMB_SHORTNAMELEN);
3507f667e74Sjose borrego 
351148c5f43SAlan Wright 		(void) smb_mbc_encodef(&sr->reply, "b11c.wwlbYl13c",
352148c5f43SAlan Wright 		    resume_char, name83, index, odid, client_key,
3537f667e74Sjose borrego 		    fileinfo.fi_dosattr & 0xff,
354e3f2c991SKeyur Desai 		    smb_time_gmt_to_local(sr, fileinfo.fi_mtime.tv_sec),
3557f667e74Sjose borrego 		    (int32_t)fileinfo.fi_size,
356148c5f43SAlan Wright 		    fileinfo.fi_shortname);
3577f667e74Sjose borrego 
3587f667e74Sjose borrego 		smb_odir_save_cookie(od, index, fileinfo.fi_cookie);
3597f667e74Sjose borrego 
3607f667e74Sjose borrego 		count++;
3617f667e74Sjose borrego 		index++;
3627f667e74Sjose borrego 	}
363a90cf9f2SGordon Ross 	if (eos && rc == ENOENT)
364a90cf9f2SGordon Ross 		rc = 0;
3657f667e74Sjose borrego 
3667f667e74Sjose borrego 	if (rc != 0) {
3677f667e74Sjose borrego 		smb_odir_close(od);
368a1511e6bSjoyce mcintosh 		smb_odir_release(od);
3697f667e74Sjose borrego 		return (SDRC_ERROR);
3707f667e74Sjose borrego 	}
3717f667e74Sjose borrego 
3727f667e74Sjose borrego 	if (count == 0 && find_first) {
3737f667e74Sjose borrego 		smb_odir_close(od);
374a1511e6bSjoyce mcintosh 		smb_odir_release(od);
3757f667e74Sjose borrego 		smbsr_warn(sr, NT_STATUS_NO_MORE_FILES,
3767f667e74Sjose borrego 		    ERRDOS, ERROR_NO_MORE_FILES);
3777f667e74Sjose borrego 		return (SDRC_ERROR);
3787f667e74Sjose borrego 	}
3797f667e74Sjose borrego 
3807f667e74Sjose borrego 	rc = (sr->reply.chain_offset - sr->cur_reply_offset) - 8;
3817f667e74Sjose borrego 	if (smb_mbc_poke(&sr->reply, sr->cur_reply_offset, "bwwbw",
3827f667e74Sjose borrego 	    1, count, rc+3, 5, rc) < 0) {
3837f667e74Sjose borrego 		smb_odir_close(od);
384a1511e6bSjoyce mcintosh 		smb_odir_release(od);
3857f667e74Sjose borrego 		return (SDRC_ERROR);
3867f667e74Sjose borrego 	}
3877f667e74Sjose borrego 
388a1511e6bSjoyce mcintosh 	smb_odir_release(od);
3897f667e74Sjose borrego 	return (SDRC_SUCCESS);
3907f667e74Sjose borrego }
3917f667e74Sjose borrego 
3927f667e74Sjose borrego 
3937f667e74Sjose borrego /* *** smb_com_find *** */
3947f667e74Sjose borrego 
3957b59d02dSjb150015 smb_sdrc_t
smb_pre_find(smb_request_t * sr)396faa1795aSjb150015 smb_pre_find(smb_request_t *sr)
397faa1795aSjb150015 {
39893bc28dbSGordon Ross 	DTRACE_SMB_START(op__Find, smb_request_t *, sr);
399faa1795aSjb150015 	return (SDRC_SUCCESS);
400faa1795aSjb150015 }
401faa1795aSjb150015 
402faa1795aSjb150015 void
smb_post_find(smb_request_t * sr)403faa1795aSjb150015 smb_post_find(smb_request_t *sr)
404faa1795aSjb150015 {
40593bc28dbSGordon Ross 	DTRACE_SMB_DONE(op__Find, smb_request_t *, sr);
406faa1795aSjb150015 }
407faa1795aSjb150015 
408faa1795aSjb150015 smb_sdrc_t
smb_com_find(smb_request_t * sr)409faa1795aSjb150015 smb_com_find(smb_request_t *sr)
410da6c28aaSamw {
411da6c28aaSamw 	int			rc;
4127f667e74Sjose borrego 	uint16_t		count, maxcount, index;
4137f667e74Sjose borrego 	uint16_t		sattr, odid;
4147f667e74Sjose borrego 	uint16_t		key_len;
4157f667e74Sjose borrego 	uint32_t		client_key;
416148c5f43SAlan Wright 	char			name83[SMB_SHORTNAMELEN];
4177f667e74Sjose borrego 	smb_odir_t		*od;
4187f667e74Sjose borrego 	smb_fileinfo_t		fileinfo;
419a90cf9f2SGordon Ross 	uint32_t		status;
420bfbce3c1SGordon Ross 	uint16_t		eos;
4217f667e74Sjose borrego 
4229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_pathname_t		*pn;
423c8ec8eeaSjose borrego 	unsigned char		resume_char;
424da6c28aaSamw 	unsigned char		type;
425c8ec8eeaSjose borrego 	boolean_t		find_first = B_TRUE;
4267f667e74Sjose borrego 	smb_odir_resume_t	odir_resume;
427da6c28aaSamw 
4287b59d02dSjb150015 	if (smbsr_decode_vwv(sr, "ww", &maxcount, &sattr) != 0)
429faa1795aSjb150015 		return (SDRC_ERROR);
430da6c28aaSamw 
4319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	pn = &sr->arg.dirop.fqi.fq_path;
4329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	rc = smbsr_decode_data(sr, "%Abw", sr, &pn->pn_path, &type, &key_len);
4337b59d02dSjb150015 	if ((rc != 0) || (type != 0x05))
434faa1795aSjb150015 		return (SDRC_ERROR);
435da6c28aaSamw 
4367f667e74Sjose borrego 	if ((key_len != 0) && (key_len != 21))
437faa1795aSjb150015 		return (SDRC_ERROR);
438da6c28aaSamw 
4399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_pathname_init(sr, pn, pn->pn_path);
4409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_pathname_validate(sr, pn))
4419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SDRC_ERROR);
4429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
4439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (smb_is_stream_name(pn->pn_path)) {
4449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smbsr_error(sr, NT_STATUS_OBJECT_NAME_INVALID,
4459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    ERRDOS, ERROR_INVALID_NAME);
4469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SDRC_ERROR);
4479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
4489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
4497f667e74Sjose borrego 	find_first = (key_len == 0);
4507f667e74Sjose borrego 	resume_char = 0;
4517f667e74Sjose borrego 	client_key = 0;
452da6c28aaSamw 
4537f667e74Sjose borrego 	if (find_first) {
454a90cf9f2SGordon Ross 		status = smb_odir_openpath(sr, pn->pn_path, sattr, 0, &od);
455a90cf9f2SGordon Ross 		if (status != 0) {
456a90cf9f2SGordon Ross 			smbsr_error(sr, status, 0, 0);
4577f667e74Sjose borrego 			return (SDRC_ERROR);
458a90cf9f2SGordon Ross 		}
459*d2488fe8SGordon Ross 		odid = od->d_odid;
460da6c28aaSamw 	} else {
4617f667e74Sjose borrego 		if (smb_mbc_decodef(&sr->smb_data, "b12.wwl",
4627f667e74Sjose borrego 		    &resume_char, &index, &odid, &client_key) != 0) {
463faa1795aSjb150015 			return (SDRC_ERROR);
464da6c28aaSamw 		}
465a90cf9f2SGordon Ross 		od = smb_tree_lookup_odir(sr, odid);
4667f667e74Sjose borrego 	}
4677f667e74Sjose borrego 
4687f667e74Sjose borrego 	if (od == NULL) {
4697f667e74Sjose borrego 		smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
4707f667e74Sjose borrego 		    ERRDOS, ERROR_INVALID_HANDLE);
4717f667e74Sjose borrego 		return (SDRC_ERROR);
4727f667e74Sjose borrego 	}
4737f667e74Sjose borrego 
4747f667e74Sjose borrego 	if (!find_first) {
475a90cf9f2SGordon Ross 		if ((od->d_flags & SMB_ODIR_FLAG_WILDCARDS) == 0) {
476a90cf9f2SGordon Ross 			od->d_eof = B_TRUE;
477a90cf9f2SGordon Ross 		} else {
4787f667e74Sjose borrego 			odir_resume.or_type = SMB_ODIR_RESUME_IDX;
4797f667e74Sjose borrego 			odir_resume.or_idx = index;
4807f667e74Sjose borrego 			smb_odir_resume_at(od, &odir_resume);
4817f667e74Sjose borrego 		}
482a90cf9f2SGordon Ross 	}
483da6c28aaSamw 
4843db3f65cSamw 	(void) smb_mbc_encodef(&sr->reply, "bwwbw", 1, 0, VAR_BCC, 5, 0);
485da6c28aaSamw 
4867f667e74Sjose borrego 	rc = 0;
487c8ec8eeaSjose borrego 	index = 0;
488da6c28aaSamw 	count = 0;
489c8ec8eeaSjose borrego 	if (maxcount > SMB_MAX_SEARCH)
490c8ec8eeaSjose borrego 		maxcount = SMB_MAX_SEARCH;
491c8ec8eeaSjose borrego 
492da6c28aaSamw 	while (count < maxcount) {
4937f667e74Sjose borrego 		rc = smb_odir_read_fileinfo(sr, od, &fileinfo, &eos);
494bfbce3c1SGordon Ross 		if (rc != 0 || eos != 0)
495da6c28aaSamw 			break;
496da6c28aaSamw 
497743a77edSAlan Wright 		if (*fileinfo.fi_shortname == '\0') {
498cb174861Sjoyce mcintosh 			if (smb_needs_mangled(fileinfo.fi_name))
499cb174861Sjoyce mcintosh 				continue;
500148c5f43SAlan Wright 			(void) strlcpy(fileinfo.fi_shortname, fileinfo.fi_name,
501743a77edSAlan Wright 			    SMB_SHORTNAMELEN - 1);
5027f667e74Sjose borrego 		}
503148c5f43SAlan Wright 		smb_name83(fileinfo.fi_shortname, name83, SMB_SHORTNAMELEN);
5047f667e74Sjose borrego 
505148c5f43SAlan Wright 		(void) smb_mbc_encodef(&sr->reply, "b11c.wwlbYl13c",
506148c5f43SAlan Wright 		    resume_char, name83, index, odid, client_key,
5077f667e74Sjose borrego 		    fileinfo.fi_dosattr & 0xff,
508e3f2c991SKeyur Desai 		    smb_time_gmt_to_local(sr, fileinfo.fi_mtime.tv_sec),
5097f667e74Sjose borrego 		    (int32_t)fileinfo.fi_size,
510148c5f43SAlan Wright 		    fileinfo.fi_shortname);
511c8ec8eeaSjose borrego 
5127f667e74Sjose borrego 		smb_odir_save_cookie(od, index, fileinfo.fi_cookie);
5137f667e74Sjose borrego 
514da6c28aaSamw 		count++;
515c8ec8eeaSjose borrego 		index++;
516da6c28aaSamw 	}
517a90cf9f2SGordon Ross 	if (eos && rc == ENOENT)
518a90cf9f2SGordon Ross 		rc = 0;
5196537f381Sas200622 
5207f667e74Sjose borrego 	if (rc != 0) {
5217f667e74Sjose borrego 		smb_odir_close(od);
522a1511e6bSjoyce mcintosh 		smb_odir_release(od);
523faa1795aSjb150015 		return (SDRC_ERROR);
524da6c28aaSamw 	}
525da6c28aaSamw 
526c8ec8eeaSjose borrego 	if (count == 0 && find_first) {
5277f667e74Sjose borrego 		smb_odir_close(od);
528a1511e6bSjoyce mcintosh 		smb_odir_release(od);
529c8ec8eeaSjose borrego 		smbsr_warn(sr, NT_STATUS_NO_MORE_FILES,
530c8ec8eeaSjose borrego 		    ERRDOS, ERROR_NO_MORE_FILES);
531faa1795aSjb150015 		return (SDRC_ERROR);
532da6c28aaSamw 	}
533da6c28aaSamw 
534da6c28aaSamw 	rc = (MBC_LENGTH(&sr->reply) - sr->cur_reply_offset) - 8;
5353db3f65cSamw 	if (smb_mbc_poke(&sr->reply, sr->cur_reply_offset, "bwwbw",
5367b59d02dSjb150015 	    1, count, rc+3, 5, rc) < 0) {
5377f667e74Sjose borrego 		smb_odir_close(od);
538a1511e6bSjoyce mcintosh 		smb_odir_release(od);
539faa1795aSjb150015 		return (SDRC_ERROR);
540da6c28aaSamw 	}
541da6c28aaSamw 
542a1511e6bSjoyce mcintosh 	smb_odir_release(od);
543faa1795aSjb150015 	return (SDRC_SUCCESS);
544da6c28aaSamw }
545da6c28aaSamw 
5467f667e74Sjose borrego 
5477f667e74Sjose borrego /* *** smb_com_find_close *** */
5487f667e74Sjose borrego 
5497b59d02dSjb150015 smb_sdrc_t
smb_pre_find_close(smb_request_t * sr)550faa1795aSjb150015 smb_pre_find_close(smb_request_t *sr)
551faa1795aSjb150015 {
55293bc28dbSGordon Ross 	DTRACE_SMB_START(op__FindClose, smb_request_t *, sr);
553faa1795aSjb150015 	return (SDRC_SUCCESS);
554faa1795aSjb150015 }
555faa1795aSjb150015 
556faa1795aSjb150015 void
smb_post_find_close(smb_request_t * sr)557faa1795aSjb150015 smb_post_find_close(smb_request_t *sr)
558faa1795aSjb150015 {
55993bc28dbSGordon Ross 	DTRACE_SMB_DONE(op__FindClose, smb_request_t *, sr);
560faa1795aSjb150015 }
561faa1795aSjb150015 
562faa1795aSjb150015 smb_sdrc_t
smb_com_find_close(smb_request_t * sr)563faa1795aSjb150015 smb_com_find_close(smb_request_t *sr)
564da6c28aaSamw {
5657f667e74Sjose borrego 	int		rc;
5667f667e74Sjose borrego 	uint16_t	maxcount, index;
5677f667e74Sjose borrego 	uint16_t	sattr, odid;
5687f667e74Sjose borrego 	uint16_t	key_len;
5697f667e74Sjose borrego 	uint32_t	client_key;
570da6c28aaSamw 	char		*path;
571c8ec8eeaSjose borrego 	unsigned char	resume_char;
572da6c28aaSamw 	unsigned char	type;
5737f667e74Sjose borrego 	smb_odir_t	*od;
574da6c28aaSamw 
5757b59d02dSjb150015 	if (smbsr_decode_vwv(sr, "ww", &maxcount, &sattr) != 0)
576faa1795aSjb150015 		return (SDRC_ERROR);
577da6c28aaSamw 
578da6c28aaSamw 	rc = smbsr_decode_data(sr, "%Abw", sr, &path, &type, &key_len);
5797b59d02dSjb150015 	if ((rc != 0) || (type != 0x05))
580faa1795aSjb150015 		return (SDRC_ERROR);
581da6c28aaSamw 
5827f667e74Sjose borrego 	if (key_len == 0) {
583dc20a302Sas200622 		smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
5847f667e74Sjose borrego 		    ERRDOS, ERROR_INVALID_HANDLE);
585faa1795aSjb150015 		return (SDRC_ERROR);
5867f667e74Sjose borrego 	} else if (key_len != 21) {
587faa1795aSjb150015 		return (SDRC_ERROR);
588da6c28aaSamw 	}
589da6c28aaSamw 
5907f667e74Sjose borrego 	odid = 0;
5917f667e74Sjose borrego 	if (smb_mbc_decodef(&sr->smb_data, "b12.wwl",
5927f667e74Sjose borrego 	    &resume_char, &index, &odid, &client_key) != 0) {
5937f667e74Sjose borrego 		return (SDRC_ERROR);
5947f667e74Sjose borrego 	}
5957f667e74Sjose borrego 
5963b13a1efSThomas Keiser 	od = smb_tree_lookup_odir(sr, odid);
5977f667e74Sjose borrego 	if (od == NULL) {
5987f667e74Sjose borrego 		smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
5997f667e74Sjose borrego 		    ERRDOS, ERROR_INVALID_HANDLE);
6007f667e74Sjose borrego 		return (SDRC_ERROR);
6017f667e74Sjose borrego 	}
6027f667e74Sjose borrego 
6037f667e74Sjose borrego 	smb_odir_close(od);
604a1511e6bSjoyce mcintosh 	smb_odir_release(od);
6057f667e74Sjose borrego 
6067b59d02dSjb150015 	if (smbsr_encode_result(sr, 1, 3, "bwwbw", 1, 0, 3, 5, 0))
607faa1795aSjb150015 		return (SDRC_ERROR);
6087f667e74Sjose borrego 
6097f667e74Sjose borrego 	return (SDRC_SUCCESS);
6107f667e74Sjose borrego }
6117f667e74Sjose borrego 
6127f667e74Sjose borrego 
6137f667e74Sjose borrego /* *** smb_com_find_unique *** */
6147f667e74Sjose borrego 
6157f667e74Sjose borrego smb_sdrc_t
smb_pre_find_unique(smb_request_t * sr)6167f667e74Sjose borrego smb_pre_find_unique(smb_request_t *sr)
6177f667e74Sjose borrego {
61893bc28dbSGordon Ross 	DTRACE_SMB_START(op__FindUnique, smb_request_t *, sr);
6197f667e74Sjose borrego 	return (SDRC_SUCCESS);
6207f667e74Sjose borrego }
6217f667e74Sjose borrego 
6227f667e74Sjose borrego void
smb_post_find_unique(smb_request_t * sr)6237f667e74Sjose borrego smb_post_find_unique(smb_request_t *sr)
6247f667e74Sjose borrego {
62593bc28dbSGordon Ross 	DTRACE_SMB_DONE(op__FindUnique, smb_request_t *, sr);
6267f667e74Sjose borrego }
6277f667e74Sjose borrego 
6287f667e74Sjose borrego smb_sdrc_t
smb_com_find_unique(struct smb_request * sr)6297f667e74Sjose borrego smb_com_find_unique(struct smb_request *sr)
6307f667e74Sjose borrego {
6317f667e74Sjose borrego 	int			rc;
6327f667e74Sjose borrego 	uint16_t		count, maxcount, index;
633a90cf9f2SGordon Ross 	uint16_t		sattr;
6349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_pathname_t		*pn;
6357f667e74Sjose borrego 	unsigned char		resume_char = '\0';
6367f667e74Sjose borrego 	uint32_t		client_key = 0;
637148c5f43SAlan Wright 	char			name83[SMB_SHORTNAMELEN];
6387f667e74Sjose borrego 	smb_odir_t		*od;
6397f667e74Sjose borrego 	smb_fileinfo_t		fileinfo;
640a90cf9f2SGordon Ross 	uint32_t		status;
641bfbce3c1SGordon Ross 	uint16_t		eos;
6422c2961f8Sjose borrego 	smb_vdb_t		*vdb;
6437f667e74Sjose borrego 
6447f667e74Sjose borrego 	if (smbsr_decode_vwv(sr, "ww", &maxcount, &sattr) != 0)
6457f667e74Sjose borrego 		return (SDRC_ERROR);
6467f667e74Sjose borrego 
6479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	pn = &sr->arg.dirop.fqi.fq_path;
6482c2961f8Sjose borrego 	vdb = kmem_alloc(sizeof (smb_vdb_t), KM_SLEEP);
6499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((smbsr_decode_data(sr, "%AV", sr, &pn->pn_path, vdb) != 0) ||
6502c2961f8Sjose borrego 	    (vdb->vdb_len != 0)) {
6512c2961f8Sjose borrego 		kmem_free(vdb, sizeof (smb_vdb_t));
6527f667e74Sjose borrego 		return (SDRC_ERROR);
6537f667e74Sjose borrego 	}
6542c2961f8Sjose borrego 	kmem_free(vdb, sizeof (smb_vdb_t));
6557f667e74Sjose borrego 
6569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_pathname_init(sr, pn, pn->pn_path);
6579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_pathname_validate(sr, pn))
6589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SDRC_ERROR);
6599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
6609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (smb_is_stream_name(pn->pn_path)) {
6619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smbsr_error(sr, NT_STATUS_OBJECT_NAME_INVALID,
6629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    ERRDOS, ERROR_INVALID_NAME);
6639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SDRC_ERROR);
6649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
6659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
6667f667e74Sjose borrego 	(void) smb_mbc_encodef(&sr->reply, "bwwbw", 1, 0, VAR_BCC, 5, 0);
6677f667e74Sjose borrego 
668a90cf9f2SGordon Ross 	status = smb_odir_openpath(sr, pn->pn_path, sattr, 0, &od);
669a90cf9f2SGordon Ross 	if (status != 0) {
670a90cf9f2SGordon Ross 		smbsr_error(sr, status, 0, 0);
6717f667e74Sjose borrego 		return (SDRC_ERROR);
672a90cf9f2SGordon Ross 	}
6737f667e74Sjose borrego 	if (od == NULL)
6747f667e74Sjose borrego 		return (SDRC_ERROR);
6757f667e74Sjose borrego 
6767f667e74Sjose borrego 	rc = 0;
6777f667e74Sjose borrego 	count = 0;
6787f667e74Sjose borrego 	index = 0;
6797f667e74Sjose borrego 	if (maxcount > SMB_MAX_SEARCH)
6807f667e74Sjose borrego 		maxcount = SMB_MAX_SEARCH;
6817f667e74Sjose borrego 
6827f667e74Sjose borrego 	while (count < maxcount) {
6837f667e74Sjose borrego 		rc = smb_odir_read_fileinfo(sr, od, &fileinfo, &eos);
684bfbce3c1SGordon Ross 		if (rc != 0 || eos != 0)
6857f667e74Sjose borrego 			break;
6867f667e74Sjose borrego 
687743a77edSAlan Wright 		if (*fileinfo.fi_shortname == '\0') {
688cb174861Sjoyce mcintosh 			if (smb_needs_mangled(fileinfo.fi_name))
689cb174861Sjoyce mcintosh 				continue;
690148c5f43SAlan Wright 			(void) strlcpy(fileinfo.fi_shortname, fileinfo.fi_name,
691743a77edSAlan Wright 			    SMB_SHORTNAMELEN - 1);
6927f667e74Sjose borrego 		}
693148c5f43SAlan Wright 		smb_name83(fileinfo.fi_shortname, name83, SMB_SHORTNAMELEN);
6947f667e74Sjose borrego 
695148c5f43SAlan Wright 		(void) smb_mbc_encodef(&sr->reply, "b11c.wwlbYl13c",
696*d2488fe8SGordon Ross 		    resume_char, name83, index, od->d_odid, client_key,
697*d2488fe8SGordon Ross 		    fileinfo.fi_dosattr & 0xff,
698e3f2c991SKeyur Desai 		    smb_time_gmt_to_local(sr, fileinfo.fi_mtime.tv_sec),
6997f667e74Sjose borrego 		    (int32_t)fileinfo.fi_size,
700148c5f43SAlan Wright 		    fileinfo.fi_shortname);
7017f667e74Sjose borrego 
7027f667e74Sjose borrego 		count++;
7037f667e74Sjose borrego 		index++;
7047f667e74Sjose borrego 	}
705a90cf9f2SGordon Ross 	if (eos && rc == ENOENT)
706a90cf9f2SGordon Ross 		rc = 0;
7077f667e74Sjose borrego 
7087f667e74Sjose borrego 	smb_odir_close(od);
709a1511e6bSjoyce mcintosh 	smb_odir_release(od);
7107f667e74Sjose borrego 
7117f667e74Sjose borrego 	if (rc != 0)
7127f667e74Sjose borrego 		return (SDRC_ERROR);
7137f667e74Sjose borrego 
7147f667e74Sjose borrego 	if (count == 0) {
7157f667e74Sjose borrego 		smbsr_warn(sr, NT_STATUS_NO_MORE_FILES,
7167f667e74Sjose borrego 		    ERRDOS, ERROR_NO_MORE_FILES);
7177f667e74Sjose borrego 		return (SDRC_ERROR);
7187f667e74Sjose borrego 	}
7197f667e74Sjose borrego 
7207f667e74Sjose borrego 	rc = (MBC_LENGTH(&sr->reply) - sr->cur_reply_offset) - 8;
7217f667e74Sjose borrego 	if (smb_mbc_poke(&sr->reply, sr->cur_reply_offset,
7227f667e74Sjose borrego 	    "bwwbw", 1, count, rc+3, 5, rc) < 0) {
7237f667e74Sjose borrego 		return (SDRC_ERROR);
7247f667e74Sjose borrego 	}
7257f667e74Sjose borrego 
726faa1795aSjb150015 	return (SDRC_SUCCESS);
727da6c28aaSamw }
728148c5f43SAlan Wright 
729148c5f43SAlan Wright /*
730148c5f43SAlan Wright  * smb_name83
731148c5f43SAlan Wright  *
732148c5f43SAlan Wright  * Format the filename for inclusion in the resume key. The filename
733148c5f43SAlan Wright  * returned in the resume key is 11 bytes:
734148c5f43SAlan Wright  * - up to 8 bytes of filename, space padded to 8 bytes
735148c5f43SAlan Wright  * - up to 3 bytes of ext, space padded to 3 bytes
736148c5f43SAlan Wright  *
737148c5f43SAlan Wright  * The name passed to smb_name83 should be a shortname or a name that
738148c5f43SAlan Wright  * doesn't require mangling.
739148c5f43SAlan Wright  *
740148c5f43SAlan Wright  * Examples:
741148c5f43SAlan Wright  *	"fname.txt"    -> "FNAME   TXT"
742148c5f43SAlan Wright  *	"fname.tx"     -> "FNAME   TX "
743148c5f43SAlan Wright  *	"filename"     -> "FILENAME   "
744148c5f43SAlan Wright  *	"filename.txt" -> "FILENAMETXT"
745148c5f43SAlan Wright  *	"FILE~1.TXT"   -> "FILE~1  TXT"
746148c5f43SAlan Wright  */
747148c5f43SAlan Wright static void
smb_name83(const char * name,char * buf,size_t buflen)748148c5f43SAlan Wright smb_name83(const char *name, char *buf, size_t buflen)
749148c5f43SAlan Wright {
750148c5f43SAlan Wright 	const char *p;
751148c5f43SAlan Wright 	char *pbuf;
752148c5f43SAlan Wright 	int i;
753148c5f43SAlan Wright 
754148c5f43SAlan Wright 	ASSERT(name && buf && (buflen >= SMB_NAME83_BUFLEN));
755148c5f43SAlan Wright 
756148c5f43SAlan Wright 	(void) strlcpy(buf, "           ", SMB_NAME83_BUFLEN);
757148c5f43SAlan Wright 
758148c5f43SAlan Wright 	/* Process "." and ".." up front */
759148c5f43SAlan Wright 	if ((strcmp(name, ".") == 0) || (strcmp(name, "..") == 0)) {
760148c5f43SAlan Wright 		(void) strncpy(buf, name, strlen(name));
761148c5f43SAlan Wright 		return;
762148c5f43SAlan Wright 	}
763148c5f43SAlan Wright 
764148c5f43SAlan Wright 	ASSERT(smb_needs_mangled(name) == B_FALSE);
765148c5f43SAlan Wright 
766148c5f43SAlan Wright 	/* Process basename */
767148c5f43SAlan Wright 	for (i = 0, p = name, pbuf = buf;
768148c5f43SAlan Wright 	    (i < SMB_NAME83_BASELEN) && (*p != '\0') && (*p != '.'); ++i)
769148c5f43SAlan Wright 		*pbuf++ = *p++;
770148c5f43SAlan Wright 
771148c5f43SAlan Wright 	/* Process the extension from the last dot in name */
772148c5f43SAlan Wright 	if ((p = strchr(name, '.')) != NULL) {
773148c5f43SAlan Wright 		++p;
774148c5f43SAlan Wright 		pbuf = &buf[SMB_NAME83_BASELEN];
775148c5f43SAlan Wright 		for (i = 0; (i < SMB_NAME83_EXTLEN) && (*p != '\0'); ++i)
776148c5f43SAlan Wright 			*pbuf++ = *p++;
777148c5f43SAlan Wright 	}
778148c5f43SAlan Wright 
779148c5f43SAlan Wright 	(void) smb_strupr(buf);
780148c5f43SAlan Wright }
781