xref: /illumos-gate/usr/src/uts/common/fs/smbsrv/smb_trans2_find.c (revision a90cf9f29973990687fa61de9f1f6ea22e924e40)
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 /*
229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23da6c28aaSamw  * Use is subject to license terms.
24b819cea2SGordon Ross  *
25*a90cf9f2SGordon Ross  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
26da6c28aaSamw  */
27da6c28aaSamw 
28da6c28aaSamw 
29da6c28aaSamw /*
30da6c28aaSamw  * This module provides functions for TRANS2_FIND_FIRST2 and
31da6c28aaSamw  * TRANS2_FIND_NEXT2 requests. The requests allow the client to search
32da6c28aaSamw  * for the file(s) which match the file specification.  The search is
33da6c28aaSamw  * started with TRANS2_FIND_FIRST2 and can be continued if necessary with
34da6c28aaSamw  * TRANS2_FIND_NEXT2. There are numerous levels of information which may be
35da6c28aaSamw  * obtained for the returned files, the desired level is specified in the
36da6c28aaSamw  * InformationLevel field of the requests.
37da6c28aaSamw  *
38da6c28aaSamw  *  InformationLevel Name              Value
39da6c28aaSamw  *  =================================  ================
40da6c28aaSamw  *
41da6c28aaSamw  *  SMB_INFO_STANDARD                  1
42da6c28aaSamw  *  SMB_INFO_QUERY_EA_SIZE             2
43da6c28aaSamw  *  SMB_INFO_QUERY_EAS_FROM_LIST       3
44da6c28aaSamw  *  SMB_FIND_FILE_DIRECTORY_INFO       0x101
45da6c28aaSamw  *  SMB_FIND_FILE_FULL_DIRECTORY_INFO  0x102
46da6c28aaSamw  *  SMB_FIND_FILE_NAMES_INFO           0x103
47da6c28aaSamw  *  SMB_FIND_FILE_BOTH_DIRECTORY_INFO  0x104
48b89a8333Snatalie li - Sun Microsystems - Irvine United States  *  SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO  0x105
49b89a8333Snatalie li - Sun Microsystems - Irvine United States  *  SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO  0x106
50da6c28aaSamw  *
51da6c28aaSamw  * The following sections detail the data returned for each
52da6c28aaSamw  * InformationLevel. The requested information is placed in the Data
53da6c28aaSamw  * portion of the transaction response. Note: a client which does not
54da6c28aaSamw  * support long names can only request SMB_INFO_STANDARD.
55da6c28aaSamw  *
56da6c28aaSamw  * A four-byte resume key precedes each data item (described below) if bit
57da6c28aaSamw  * 2 in the Flags field is set, i.e. if the request indicates the server
58da6c28aaSamw  * should return resume keys. Note: it is not always the case. If the
59da6c28aaSamw  * data item already includes the resume key, the resume key should not be
60da6c28aaSamw  * added again.
61da6c28aaSamw  *
62da6c28aaSamw  * 4.3.4.1   SMB_INFO_STANDARD
63da6c28aaSamw  *
64da6c28aaSamw  *  Response Field                    Description
65da6c28aaSamw  *  ================================  ==================================
66da6c28aaSamw  *
67da6c28aaSamw  *  SMB_DATE CreationDate;            Date when file was created
68da6c28aaSamw  *  SMB_TIME CreationTime;            Time when file was created
69da6c28aaSamw  *  SMB_DATE LastAccessDate;          Date of last file access
70da6c28aaSamw  *  SMB_TIME LastAccessTime;          Time of last file access
71da6c28aaSamw  *  SMB_DATE LastWriteDate;           Date of last write to the file
72da6c28aaSamw  *  SMB_TIME LastWriteTime;           Time of last write to the file
73da6c28aaSamw  *  ULONG  DataSize;                  File Size
74da6c28aaSamw  *  ULONG AllocationSize;             Size of filesystem allocation unit
75da6c28aaSamw  *  USHORT Attributes;                File Attributes
76da6c28aaSamw  *  UCHAR FileNameLength;             Length of filename in bytes
77da6c28aaSamw  *  STRING FileName;                  Name of found file
78da6c28aaSamw  *
79da6c28aaSamw  * 4.3.4.2   SMB_INFO_QUERY_EA_SIZE
80da6c28aaSamw  *
81da6c28aaSamw  *  Response Field                     Description
82da6c28aaSamw  *  =================================  ==================================
83da6c28aaSamw  *
84da6c28aaSamw  *   SMB_DATE CreationDate;            Date when file was created
85da6c28aaSamw  *   SMB_TIME CreationTime;            Time when file was created
86da6c28aaSamw  *   SMB_DATE LastAccessDate;          Date of last file access
87da6c28aaSamw  *   SMB_TIME LastAccessTime;          Time of last file access
88da6c28aaSamw  *   SMB_DATE LastWriteDate;           Date of last write to the file
89da6c28aaSamw  *   SMB_TIME LastWriteTime;           Time of last write to the file
90da6c28aaSamw  *   ULONG DataSize;                   File Size
91da6c28aaSamw  *   ULONG AllocationSize;             Size of filesystem allocation unit
92da6c28aaSamw  *   USHORT Attributes;                File Attributes
93da6c28aaSamw  *   ULONG EaSize;                     Size of file's EA information
94da6c28aaSamw  *   UCHAR FileNameLength;             Length of filename in bytes
95da6c28aaSamw  *   STRING FileName;                  Name of found file
96da6c28aaSamw  *
97da6c28aaSamw  * 4.3.4.3   SMB_INFO_QUERY_EAS_FROM_LIST
98da6c28aaSamw  *
99da6c28aaSamw  * This request returns the same information as SMB_INFO_QUERY_EA_SIZE, but
100da6c28aaSamw  * only for files which have an EA list which match the EA information in
101da6c28aaSamw  * the Data part of the request.
102da6c28aaSamw  *
103da6c28aaSamw  * 4.3.4.4   SMB_FIND_FILE_DIRECTORY_INFO
104da6c28aaSamw  *
105da6c28aaSamw  *  Response Field                     Description
106da6c28aaSamw  *  =================================  ==================================
107da6c28aaSamw  *
108da6c28aaSamw  *  ULONG NextEntryOffset;             Offset from this structure to
109da6c28aaSamw  *					beginning of next one
110da6c28aaSamw  *  ULONG FileIndex;
111da6c28aaSamw  *  LARGE_INTEGER CreationTime;        file creation time
112da6c28aaSamw  *  LARGE_INTEGER LastAccessTime;      last access time
113da6c28aaSamw  *  LARGE_INTEGER LastWriteTime;       last write time
114da6c28aaSamw  *  LARGE_INTEGER ChangeTime;          last attribute change time
115da6c28aaSamw  *  LARGE_INTEGER EndOfFile;           file size
116da6c28aaSamw  *  LARGE_INTEGER AllocationSize;      size of filesystem allocation information
117da6c28aaSamw  *  ULONG ExtFileAttributes;           Extended file attributes
118da6c28aaSamw  *					(see section 3.11)
119da6c28aaSamw  *  ULONG FileNameLength;              Length of filename in bytes
120da6c28aaSamw  *  STRING FileName;                   Name of the file
121da6c28aaSamw  *
122da6c28aaSamw  * 4.3.4.5   SMB_FIND_FILE_FULL_DIRECTORY_INFO
123da6c28aaSamw  *
124da6c28aaSamw  *  Response Field                     Description
125da6c28aaSamw  *  =================================  ==================================
126da6c28aaSamw  *
127da6c28aaSamw  *  ULONG NextEntryOffset;             Offset from this structure to
128da6c28aaSamw  *					beginning of next one
129da6c28aaSamw  *  ULONG FileIndex;
130da6c28aaSamw  *  LARGE_INTEGER CreationTime;        file creation time
131da6c28aaSamw  *  LARGE_INTEGER LastAccessTime;      last access time
132da6c28aaSamw  *  LARGE_INTEGER LastWriteTime;       last write time
133da6c28aaSamw  *  LARGE_INTEGER ChangeTime;          last attribute change time
134da6c28aaSamw  *  LARGE_INTEGER EndOfFile;           file size
135da6c28aaSamw  *  LARGE_INTEGER AllocationSize;      size of filesystem allocation information
136da6c28aaSamw  *  ULONG ExtFileAttributes;           Extended file attributes
137da6c28aaSamw  *					(see section 3.11)
138da6c28aaSamw  *  ULONG FileNameLength;              Length of filename in bytes
139da6c28aaSamw  *  ULONG EaSize;                      Size of file's extended attributes
140da6c28aaSamw  *  STRING FileName;                   Name of the file
141da6c28aaSamw  *
142b89a8333Snatalie li - Sun Microsystems - Irvine United States  *
143b89a8333Snatalie li - Sun Microsystems - Irvine United States  *  SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO
144b89a8333Snatalie li - Sun Microsystems - Irvine United States  *
145b89a8333Snatalie li - Sun Microsystems - Irvine United States  *  This is the same as SMB_FIND_FILE_FULL_DIRECTORY_INFO but with
146b89a8333Snatalie li - Sun Microsystems - Irvine United States  *  FileId inserted after EaSize. FileId is preceded by a 4 byte
147b89a8333Snatalie li - Sun Microsystems - Irvine United States  *  alignment padding.
148b89a8333Snatalie li - Sun Microsystems - Irvine United States  *
149b89a8333Snatalie li - Sun Microsystems - Irvine United States  *  Response Field                     Description
150b89a8333Snatalie li - Sun Microsystems - Irvine United States  *  =================================  ==================================
151b89a8333Snatalie li - Sun Microsystems - Irvine United States  *  ...
152b89a8333Snatalie li - Sun Microsystems - Irvine United States  *  ULONG EaSize;                      Size of file's extended attributes
153b89a8333Snatalie li - Sun Microsystems - Irvine United States  *  UCHAR Reserved[4]
154b89a8333Snatalie li - Sun Microsystems - Irvine United States  *  LARGE_INTEGER FileId               Internal file system unique id.
155b89a8333Snatalie li - Sun Microsystems - Irvine United States  *  STRING FileName;                   Name of the file
156b89a8333Snatalie li - Sun Microsystems - Irvine United States  *
157da6c28aaSamw  * 4.3.4.6   SMB_FIND_FILE_BOTH_DIRECTORY_INFO
158da6c28aaSamw  *
159da6c28aaSamw  *  Response Field                     Description
160da6c28aaSamw  *  =================================  ==================================
161da6c28aaSamw  *
162da6c28aaSamw  *  ULONG NextEntryOffset;             Offset from this structure to
163da6c28aaSamw  *					beginning of next one
164da6c28aaSamw  *  ULONG FileIndex;
165da6c28aaSamw  *  LARGE_INTEGER CreationTime;        file creation time
166da6c28aaSamw  *  LARGE_INTEGER LastAccessTime;      last access time
167da6c28aaSamw  *  LARGE_INTEGER LastWriteTime;       last write time
168da6c28aaSamw  *  LARGE_INTEGER ChangeTime;          last attribute change time
169da6c28aaSamw  *  LARGE_INTEGER EndOfFile;           file size
170da6c28aaSamw  *  LARGE_INTEGER AllocationSize;      size of filesystem allocation information
171da6c28aaSamw  *  ULONG ExtFileAttributes;           Extended file attributes
172da6c28aaSamw  *					(see section 3.11)
173da6c28aaSamw  *  ULONG FileNameLength;              Length of FileName in bytes
174da6c28aaSamw  *  ULONG EaSize;                      Size of file's extended attributes
175da6c28aaSamw  *  UCHAR ShortNameLength;             Length of file's short name in bytes
176da6c28aaSamw  *  UCHAR Reserved
177da6c28aaSamw  *  WCHAR ShortName[12];               File's 8.3 conformant name in Unicode
178da6c28aaSamw  *  STRING FileName;                   Files full length name
179da6c28aaSamw  *
180b89a8333Snatalie li - Sun Microsystems - Irvine United States  *
181b89a8333Snatalie li - Sun Microsystems - Irvine United States  *  SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO
182b89a8333Snatalie li - Sun Microsystems - Irvine United States  *
183b89a8333Snatalie li - Sun Microsystems - Irvine United States  *  This is the same as SMB_FIND_FILE_BOTH_DIRECTORY_INFO but with
184b89a8333Snatalie li - Sun Microsystems - Irvine United States  *  FileId inserted after ShortName. FileId is preceded by a 2 byte
185b89a8333Snatalie li - Sun Microsystems - Irvine United States  *  alignment pad.
186b89a8333Snatalie li - Sun Microsystems - Irvine United States  *
187b89a8333Snatalie li - Sun Microsystems - Irvine United States  *  Response Field                     Description
188b89a8333Snatalie li - Sun Microsystems - Irvine United States  *  =================================  ==================================
189b89a8333Snatalie li - Sun Microsystems - Irvine United States  *  ...
190b89a8333Snatalie li - Sun Microsystems - Irvine United States  *  WCHAR ShortName[12];               File's 8.3 conformant name in Unicode
191b89a8333Snatalie li - Sun Microsystems - Irvine United States  *  UCHAR Reserved[2]
192b89a8333Snatalie li - Sun Microsystems - Irvine United States  *  LARGE_INTEGER FileId               Internal file system unique id.
193b89a8333Snatalie li - Sun Microsystems - Irvine United States  *  STRING FileName;                   Files full length name
194b89a8333Snatalie li - Sun Microsystems - Irvine United States  *
195da6c28aaSamw  * 4.3.4.7   SMB_FIND_FILE_NAMES_INFO
196da6c28aaSamw  *
197da6c28aaSamw  *  Response Field                     Description
198da6c28aaSamw  *  =================================  ==================================
199da6c28aaSamw  *
200da6c28aaSamw  *  ULONG NextEntryOffset;             Offset from this structure to
201da6c28aaSamw  *                                     beginning of next one
202da6c28aaSamw  *  ULONG FileIndex;
203da6c28aaSamw  *  ULONG FileNameLength;              Length of FileName in bytes
204da6c28aaSamw  *  STRING FileName;                   Files full length name
205da6c28aaSamw  */
206da6c28aaSamw 
207bbf6f00cSJordan Brown #include <smbsrv/smb_kproto.h>
208da6c28aaSamw #include <smbsrv/msgbuf.h>
209da6c28aaSamw #include <smbsrv/smb_fsops.h>
210da6c28aaSamw 
211bfbce3c1SGordon Ross /*
212bfbce3c1SGordon Ross  * Args (and other state) that we carry around among the
213bfbce3c1SGordon Ross  * various functions involved in FindFirst, FindNext.
214bfbce3c1SGordon Ross  */
2157f667e74Sjose borrego typedef struct smb_find_args {
216bfbce3c1SGordon Ross 	uint32_t fa_maxdata;
2177f667e74Sjose borrego 	uint16_t fa_infolev;
2187f667e74Sjose borrego 	uint16_t fa_maxcount;
2197f667e74Sjose borrego 	uint16_t fa_fflag;
220bfbce3c1SGordon Ross 	uint16_t fa_eos;	/* End Of Search */
221bfbce3c1SGordon Ross 	uint16_t fa_lno;	/* Last Name Offset */
222bfbce3c1SGordon Ross 	uint32_t fa_lastkey;	/* Last resume key */
223bfbce3c1SGordon Ross 	char fa_lastname[MAXNAMELEN]; /* and name */
2247f667e74Sjose borrego } smb_find_args_t;
2257f667e74Sjose borrego 
2267f667e74Sjose borrego static int smb_trans2_find_entries(smb_request_t *, smb_xa_t *,
227bfbce3c1SGordon Ross     smb_odir_t *, smb_find_args_t *);
228dc20a302Sas200622 static int smb_trans2_find_get_maxdata(smb_request_t *, uint16_t, uint16_t);
2297f667e74Sjose borrego static int smb_trans2_find_mbc_encode(smb_request_t *, smb_xa_t *,
2307f667e74Sjose borrego     smb_fileinfo_t *, smb_find_args_t *);
231da6c28aaSamw 
232da6c28aaSamw /*
233dc20a302Sas200622  * Tunable parameter to limit the maximum
234dc20a302Sas200622  * number of entries to be returned.
235da6c28aaSamw  */
236dc20a302Sas200622 uint16_t smb_trans2_find_max = 128;
237da6c28aaSamw 
238da6c28aaSamw /*
239da6c28aaSamw  * smb_com_trans2_find_first2
240da6c28aaSamw  *
241da6c28aaSamw  *  Client Request                Value
242da6c28aaSamw  *  ============================  ==================================
243da6c28aaSamw  *
244da6c28aaSamw  *  UCHAR  WordCount              15
245da6c28aaSamw  *  UCHAR  TotalDataCount         Total size of extended attribute list
246da6c28aaSamw  *  UCHAR  SetupCount             1
247da6c28aaSamw  *  UCHAR  Setup[0]               TRANS2_FIND_FIRST2
248da6c28aaSamw  *
249da6c28aaSamw  *  Parameter Block Encoding      Description
250da6c28aaSamw  *  ============================  ==================================
251da6c28aaSamw  *  USHORT SearchAttributes;
252da6c28aaSamw  *  USHORT SearchCount;           Maximum number of entries to return
253da6c28aaSamw  *  USHORT Flags;                 Additional information:
254da6c28aaSamw  *                                Bit 0 - close search after this request
255da6c28aaSamw  *                                Bit 1 - close search if end of search
256da6c28aaSamw  *                                reached
257da6c28aaSamw  *                                Bit 2 - return resume keys for each
258da6c28aaSamw  *                                entry found
259da6c28aaSamw  *                                Bit 3 - continue search from previous
260da6c28aaSamw  *                                ending place
261da6c28aaSamw  *                                Bit 4 - find with backup intent
262da6c28aaSamw  *  USHORT InformationLevel;      See below
263da6c28aaSamw  *  ULONG SearchStorageType;
264da6c28aaSamw  *  STRING FileName;              Pattern for the search
265da6c28aaSamw  *  UCHAR Data[ TotalDataCount ]  FEAList if InformationLevel is
266da6c28aaSamw  *                                QUERY_EAS_FROM_LIST
267da6c28aaSamw  *
268da6c28aaSamw  *  Response Parameter Block      Description
269da6c28aaSamw  *  ============================  ==================================
270da6c28aaSamw  *
271da6c28aaSamw  *  USHORT Sid;                   Search handle
272da6c28aaSamw  *  USHORT SearchCount;           Number of entries returned
273da6c28aaSamw  *  USHORT EndOfSearch;           Was last entry returned?
274da6c28aaSamw  *  USHORT EaErrorOffset;         Offset into EA list if EA error
275da6c28aaSamw  *  USHORT LastNameOffset;        Offset into data to file name of last
276da6c28aaSamw  *                                entry, if server needs it to resume
277da6c28aaSamw  *                                search; else 0
278da6c28aaSamw  *  UCHAR Data[ TotalDataCount ]  Level dependent info about the matches
279da6c28aaSamw  *                                found in the search
280da6c28aaSamw  */
2817b59d02dSjb150015 smb_sdrc_t
282dc20a302Sas200622 smb_com_trans2_find_first2(smb_request_t *sr, smb_xa_t *xa)
283da6c28aaSamw {
2847f667e74Sjose borrego 	int		count;
285*a90cf9f2SGordon Ross 	uint16_t	sattr;
2869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_pathname_t	*pn;
2877f667e74Sjose borrego 	smb_odir_t	*od;
2887f667e74Sjose borrego 	smb_find_args_t	args;
289*a90cf9f2SGordon Ross 	uint32_t	status;
290eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	uint32_t	odir_flags = 0;
2917f667e74Sjose borrego 
2927f667e74Sjose borrego 	bzero(&args, sizeof (smb_find_args_t));
293da6c28aaSamw 
294da6c28aaSamw 	if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) {
295dc20a302Sas200622 		smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
296da6c28aaSamw 		    ERRDOS, ERROR_ACCESS_DENIED);
297faa1795aSjb150015 		return (SDRC_ERROR);
298da6c28aaSamw 	}
299da6c28aaSamw 
3009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	pn = &sr->arg.dirop.fqi.fq_path;
3019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3027f667e74Sjose borrego 	if (smb_mbc_decodef(&xa->req_param_mb, "%wwww4.u", sr, &sattr,
3039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    &args.fa_maxcount, &args.fa_fflag, &args.fa_infolev,
3049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    &pn->pn_path) != 0) {
305faa1795aSjb150015 		return (SDRC_ERROR);
306da6c28aaSamw 	}
307da6c28aaSamw 
3089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_pathname_init(sr, pn, pn->pn_path);
3099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_pathname_validate(sr, pn))
3109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (-1);
3119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
3129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (smb_is_stream_name(pn->pn_path)) {
313b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smbsr_error(sr, NT_STATUS_OBJECT_NAME_INVALID,
314b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    ERRDOS, ERROR_INVALID_NAME);
315b89a8333Snatalie li - Sun Microsystems - Irvine United States 		return (SDRC_ERROR);
316b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
317b89a8333Snatalie li - Sun Microsystems - Irvine United States 
318eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	if (args.fa_fflag & SMB_FIND_WITH_BACKUP_INTENT) {
319b89a8333Snatalie li - Sun Microsystems - Irvine United States 		sr->user_cr = smb_user_getprivcred(sr->uid_user);
320eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 		odir_flags = SMB_ODIR_OPENF_BACKUP_INTENT;
321eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	}
322b89a8333Snatalie li - Sun Microsystems - Irvine United States 
3237f667e74Sjose borrego 	args.fa_maxdata =
3247f667e74Sjose borrego 	    smb_trans2_find_get_maxdata(sr, args.fa_infolev, args.fa_fflag);
3257f667e74Sjose borrego 	if (args.fa_maxdata == 0)
326faa1795aSjb150015 		return (SDRC_ERROR);
327dc20a302Sas200622 
328*a90cf9f2SGordon Ross 	status = smb_odir_openpath(sr, pn->pn_path, sattr, odir_flags, &od);
329*a90cf9f2SGordon Ross 	if (status != 0) {
330*a90cf9f2SGordon Ross 		smbsr_error(sr, status, 0, 0);
331faa1795aSjb150015 		return (SDRC_ERROR);
3329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
3337f667e74Sjose borrego 	if (od == NULL)
3347f667e74Sjose borrego 		return (SDRC_ERROR);
335bfbce3c1SGordon Ross 
336bfbce3c1SGordon Ross 	count = smb_trans2_find_entries(sr, xa, od, &args);
337dc20a302Sas200622 
3387f667e74Sjose borrego 	if (count == -1) {
3397f667e74Sjose borrego 		smb_odir_close(od);
340a1511e6bSjoyce mcintosh 		smb_odir_release(od);
341faa1795aSjb150015 		return (SDRC_ERROR);
342da6c28aaSamw 	}
343da6c28aaSamw 
3447f667e74Sjose borrego 	if (count == 0) {
3457f667e74Sjose borrego 		smb_odir_close(od);
346a1511e6bSjoyce mcintosh 		smb_odir_release(od);
3477f667e74Sjose borrego 		smbsr_errno(sr, ENOENT);
3487f667e74Sjose borrego 		return (SDRC_ERROR);
349da6c28aaSamw 	}
350da6c28aaSamw 
3517f667e74Sjose borrego 	if ((args.fa_fflag & SMB_FIND_CLOSE_AFTER_REQUEST) ||
352bfbce3c1SGordon Ross 	    (args.fa_eos && (args.fa_fflag & SMB_FIND_CLOSE_AT_EOS))) {
3537f667e74Sjose borrego 		smb_odir_close(od);
3547f667e74Sjose borrego 	} /* else leave odir open for trans2_find_next2 */
3557f667e74Sjose borrego 
3563db3f65cSamw 	(void) smb_mbc_encodef(&xa->rep_param_mb, "wwwww",
357*a90cf9f2SGordon Ross 	    od->d_odid,	/* Search ID */
358bfbce3c1SGordon Ross 	    count,	/* Search Count */
359bfbce3c1SGordon Ross 	    args.fa_eos, /* End Of Search */
360bfbce3c1SGordon Ross 	    0,		/* EA Error Offset */
361bfbce3c1SGordon Ross 	    args.fa_lno); /* Last Name Offset */
362da6c28aaSamw 
363*a90cf9f2SGordon Ross 	smb_odir_release(od);
364*a90cf9f2SGordon Ross 
365faa1795aSjb150015 	return (SDRC_SUCCESS);
366da6c28aaSamw }
367da6c28aaSamw 
368da6c28aaSamw /*
369da6c28aaSamw  * smb_com_trans2_find_next2
370da6c28aaSamw  *
371da6c28aaSamw  *  Client Request                     Value
372da6c28aaSamw  *  ================================== =================================
373da6c28aaSamw  *
374da6c28aaSamw  *  WordCount                          15
375da6c28aaSamw  *  SetupCount                         1
376da6c28aaSamw  *  Setup[0]                           TRANS2_FIND_NEXT2
377da6c28aaSamw  *
378da6c28aaSamw  *  Parameter Block Encoding           Description
379da6c28aaSamw  *  ================================== =================================
380da6c28aaSamw  *
381da6c28aaSamw  *  USHORT Sid;                        Search handle
382da6c28aaSamw  *  USHORT SearchCount;                Maximum number of entries to
383da6c28aaSamw  *                                      return
384da6c28aaSamw  *  USHORT InformationLevel;           Levels described in
385da6c28aaSamw  *                                      TRANS2_FIND_FIRST2 request
386da6c28aaSamw  *  ULONG ResumeKey;                   Value returned by previous find2
387da6c28aaSamw  *                                      call
388da6c28aaSamw  *  USHORT Flags;                      Additional information: bit set-
389da6c28aaSamw  *                                      0 - close search after this
390da6c28aaSamw  *                                      request
391da6c28aaSamw  *                                      1 - close search if end of search
392da6c28aaSamw  *                                      reached
393da6c28aaSamw  *                                      2 - return resume keys for each
394da6c28aaSamw  *                                      entry found
395da6c28aaSamw  *                                      3 - resume/continue from previous
396da6c28aaSamw  *                                      ending place
397da6c28aaSamw  *                                      4 - find with backup intent
398da6c28aaSamw  *  STRING FileName;                   Resume file name
399da6c28aaSamw  *
400da6c28aaSamw  * Sid is the value returned by a previous successful TRANS2_FIND_FIRST2
401da6c28aaSamw  * call.  If Bit3 of Flags is set, then FileName may be the NULL string,
402da6c28aaSamw  * since the search is continued from the previous TRANS2_FIND request.
403da6c28aaSamw  * Otherwise, FileName must not be more than 256 characters long.
404da6c28aaSamw  *
405da6c28aaSamw  *  Response Field                     Description
406da6c28aaSamw  *  ================================== =================================
407da6c28aaSamw  *
408da6c28aaSamw  *  USHORT SearchCount;                Number of entries returned
409da6c28aaSamw  *  USHORT EndOfSearch;                Was last entry returned?
410da6c28aaSamw  *  USHORT EaErrorOffset;              Offset into EA list if EA error
411da6c28aaSamw  *  USHORT LastNameOffset;             Offset into data to file name of
412da6c28aaSamw  *                                      last entry, if server needs it to
413da6c28aaSamw  *                                      resume search; else 0
414da6c28aaSamw  *  UCHAR Data[TotalDataCount]         Level dependent info about the
415da6c28aaSamw  *                                      matches found in the search
416b89a8333Snatalie li - Sun Microsystems - Irvine United States  *
417b89a8333Snatalie li - Sun Microsystems - Irvine United States  *
418b89a8333Snatalie li - Sun Microsystems - Irvine United States  * The last parameter in the request is a filename, which is a
419b89a8333Snatalie li - Sun Microsystems - Irvine United States  * null-terminated unicode string.
420b89a8333Snatalie li - Sun Microsystems - Irvine United States  *
421b89a8333Snatalie li - Sun Microsystems - Irvine United States  * smb_mbc_decodef(&xa->req_param_mb, "%www lwu", sr,
4227f667e74Sjose borrego  *    &odid, &fa_maxcount, &fa_infolev, &cookie, &fa_fflag, &fname)
423b89a8333Snatalie li - Sun Microsystems - Irvine United States  *
4247f667e74Sjose borrego  * The filename parameter is not currently decoded because we
4257f667e74Sjose borrego  * expect a 2-byte null but Mac OS 10 clients send a 1-byte null,
426b89a8333Snatalie li - Sun Microsystems - Irvine United States  * which leads to a decode error.
427b89a8333Snatalie li - Sun Microsystems - Irvine United States  * Thus, we do not support resume by filename.  We treat a request
428b89a8333Snatalie li - Sun Microsystems - Irvine United States  * to resume by filename as SMB_FIND_CONTINUE_FROM_LAST.
429da6c28aaSamw  */
4307b59d02dSjb150015 smb_sdrc_t
431dc20a302Sas200622 smb_com_trans2_find_next2(smb_request_t *sr, smb_xa_t *xa)
432da6c28aaSamw {
4337f667e74Sjose borrego 	int			count;
4347f667e74Sjose borrego 	uint16_t		odid;
4357f667e74Sjose borrego 	smb_odir_t		*od;
4367f667e74Sjose borrego 	smb_find_args_t		args;
4377f667e74Sjose borrego 	smb_odir_resume_t	odir_resume;
438da6c28aaSamw 
439bfbce3c1SGordon Ross 	bzero(&args, sizeof (args));
440bfbce3c1SGordon Ross 	bzero(&odir_resume, sizeof (odir_resume));
4417f667e74Sjose borrego 
442bfbce3c1SGordon Ross 	if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) {
443bfbce3c1SGordon Ross 		smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
444bfbce3c1SGordon Ross 		    ERRDOS, ERROR_ACCESS_DENIED);
445faa1795aSjb150015 		return (SDRC_ERROR);
446da6c28aaSamw 	}
447da6c28aaSamw 
448bfbce3c1SGordon Ross 	if (smb_mbc_decodef(&xa->req_param_mb, "%wwwlwu", sr,
449bfbce3c1SGordon Ross 	    &odid, &args.fa_maxcount, &args.fa_infolev,
450bfbce3c1SGordon Ross 	    &odir_resume.or_cookie, &args.fa_fflag,
451bfbce3c1SGordon Ross 	    &odir_resume.or_fname) != 0) {
452bfbce3c1SGordon Ross 		return (SDRC_ERROR);
4537f667e74Sjose borrego 	}
454b89a8333Snatalie li - Sun Microsystems - Irvine United States 
4557f667e74Sjose borrego 	if (args.fa_fflag & SMB_FIND_WITH_BACKUP_INTENT)
456b89a8333Snatalie li - Sun Microsystems - Irvine United States 		sr->user_cr = smb_user_getprivcred(sr->uid_user);
457b89a8333Snatalie li - Sun Microsystems - Irvine United States 
4587f667e74Sjose borrego 	args.fa_maxdata =
4597f667e74Sjose borrego 	    smb_trans2_find_get_maxdata(sr, args.fa_infolev, args.fa_fflag);
4607f667e74Sjose borrego 	if (args.fa_maxdata == 0)
4617f667e74Sjose borrego 		return (SDRC_ERROR);
4627f667e74Sjose borrego 
4633b13a1efSThomas Keiser 	od = smb_tree_lookup_odir(sr, odid);
4647f667e74Sjose borrego 	if (od == NULL) {
4657f667e74Sjose borrego 		smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
4667f667e74Sjose borrego 		    ERRDOS, ERROR_INVALID_HANDLE);
4677f667e74Sjose borrego 		return (SDRC_ERROR);
4687f667e74Sjose borrego 	}
4697f667e74Sjose borrego 
470bfbce3c1SGordon Ross 	/*
471bfbce3c1SGordon Ross 	 * Set the correct position in the directory.
472bfbce3c1SGordon Ross 	 *
473bfbce3c1SGordon Ross 	 * "Continue from last" is easy, but due to a history of
474bfbce3c1SGordon Ross 	 * buggy server implementations, most clients don't use
475bfbce3c1SGordon Ross 	 * that method.  The most widely used (and reliable) is
476bfbce3c1SGordon Ross 	 * resume by file name.  Unfortunately, that can't really
477bfbce3c1SGordon Ross 	 * be fully supported unless your file system stores all
478bfbce3c1SGordon Ross 	 * directory entries in some sorted order (like NTFS).
479bfbce3c1SGordon Ross 	 * We can partially support resume by name, where the only
480bfbce3c1SGordon Ross 	 * name we're ever asked to resume on is the same as the
481bfbce3c1SGordon Ross 	 * most recent we returned.  That's always what the client
482bfbce3c1SGordon Ross 	 * gives us as the resume name, so we can simply remember
483bfbce3c1SGordon Ross 	 * the last name/offset pair and use that to position on
484bfbce3c1SGordon Ross 	 * the following FindNext call.  In the unlikely event
485bfbce3c1SGordon Ross 	 * that the client asks to resume somewhere else, we'll
486bfbce3c1SGordon Ross 	 * use the numeric resume key, and hope the client gives
487bfbce3c1SGordon Ross 	 * correctly uses one of the resume keys we provided.
488bfbce3c1SGordon Ross 	 */
489bfbce3c1SGordon Ross 	if (args.fa_fflag & SMB_FIND_CONTINUE_FROM_LAST) {
490bfbce3c1SGordon Ross 		odir_resume.or_type = SMB_ODIR_RESUME_CONT;
491bfbce3c1SGordon Ross 	} else {
492bfbce3c1SGordon Ross 		odir_resume.or_type = SMB_ODIR_RESUME_FNAME;
493bfbce3c1SGordon Ross 	}
494bfbce3c1SGordon Ross 	smb_odir_resume_at(od, &odir_resume);
495bfbce3c1SGordon Ross 
496bfbce3c1SGordon Ross 	count = smb_trans2_find_entries(sr, xa, od, &args);
4977f667e74Sjose borrego 	if (count == -1) {
4987f667e74Sjose borrego 		smb_odir_close(od);
499a1511e6bSjoyce mcintosh 		smb_odir_release(od);
500faa1795aSjb150015 		return (SDRC_ERROR);
501da6c28aaSamw 	}
502da6c28aaSamw 
5037f667e74Sjose borrego 	if ((args.fa_fflag & SMB_FIND_CLOSE_AFTER_REQUEST) ||
504bfbce3c1SGordon Ross 	    (args.fa_eos && (args.fa_fflag & SMB_FIND_CLOSE_AT_EOS))) {
5057f667e74Sjose borrego 		smb_odir_close(od);
5067f667e74Sjose borrego 	} /* else leave odir open for trans2_find_next2 */
5077f667e74Sjose borrego 
508a1511e6bSjoyce mcintosh 	smb_odir_release(od);
509bfbce3c1SGordon Ross 
5107f667e74Sjose borrego 	(void) smb_mbc_encodef(&xa->rep_param_mb, "wwww",
511bfbce3c1SGordon Ross 	    count,	/* Search Count */
512bfbce3c1SGordon Ross 	    args.fa_eos, /* End Of Search */
513bfbce3c1SGordon Ross 	    0,		/* EA Error Offset */
514bfbce3c1SGordon Ross 	    args.fa_lno); /* Last Name Offset */
5157f667e74Sjose borrego 
5167f667e74Sjose borrego 	return (SDRC_SUCCESS);
517da6c28aaSamw }
518da6c28aaSamw 
5197f667e74Sjose borrego 
520da6c28aaSamw /*
5217f667e74Sjose borrego  * smb_trans2_find_entries
5227f667e74Sjose borrego  *
5237f667e74Sjose borrego  * Find and encode up to args->fa_maxcount directory entries.
5247f667e74Sjose borrego  * For compatibilty with Windows, if args->fa_maxcount is zero treat it as 1.
5257f667e74Sjose borrego  *
5267f667e74Sjose borrego  * Returns:
5277f667e74Sjose borrego  *   count - count of entries encoded
5287f667e74Sjose borrego  *           *eos = B_TRUE if no more directory entries
5297f667e74Sjose borrego  *      -1 - error
530dc20a302Sas200622  */
5317f667e74Sjose borrego static int
5327f667e74Sjose borrego smb_trans2_find_entries(smb_request_t *sr, smb_xa_t *xa, smb_odir_t *od,
533bfbce3c1SGordon Ross     smb_find_args_t *args)
5347f667e74Sjose borrego {
5357f667e74Sjose borrego 	smb_fileinfo_t	fileinfo;
536bfbce3c1SGordon Ross 	smb_odir_resume_t odir_resume;
537b819cea2SGordon Ross 	uint16_t	count, maxcount;
538b819cea2SGordon Ross 	int		rc = -1;
539*a90cf9f2SGordon Ross 	boolean_t	need_rewind = B_FALSE;
5407f667e74Sjose borrego 
5417f667e74Sjose borrego 	if ((maxcount = args->fa_maxcount) == 0)
542dc20a302Sas200622 		maxcount = 1;
543dc20a302Sas200622 
544dc20a302Sas200622 	if ((smb_trans2_find_max != 0) && (maxcount > smb_trans2_find_max))
545dc20a302Sas200622 		maxcount = smb_trans2_find_max;
546dc20a302Sas200622 
5477f667e74Sjose borrego 	count = 0;
5487f667e74Sjose borrego 	while (count < maxcount) {
549*a90cf9f2SGordon Ross 		rc = smb_odir_read_fileinfo(sr, od, &fileinfo, &args->fa_eos);
550*a90cf9f2SGordon Ross 		if (rc != 0 || args->fa_eos != 0)
5517f667e74Sjose borrego 			break;
5527f667e74Sjose borrego 
5537f667e74Sjose borrego 		rc = smb_trans2_find_mbc_encode(sr, xa, &fileinfo, args);
5547f667e74Sjose borrego 		if (rc == -1)
555*a90cf9f2SGordon Ross 			return (-1); /* fatal encoding error */
556*a90cf9f2SGordon Ross 		if (rc == 1) {
557*a90cf9f2SGordon Ross 			need_rewind = B_TRUE;
558*a90cf9f2SGordon Ross 			break; /* output space exhausted */
559*a90cf9f2SGordon Ross 		}
5607f667e74Sjose borrego 
561bfbce3c1SGordon Ross 		/*
562bfbce3c1SGordon Ross 		 * Save the info about the last file returned.
563bfbce3c1SGordon Ross 		 */
564bfbce3c1SGordon Ross 		args->fa_lastkey = fileinfo.fi_cookie;
565bfbce3c1SGordon Ross 		bcopy(fileinfo.fi_name, args->fa_lastname, MAXNAMELEN);
566bfbce3c1SGordon Ross 
5677f667e74Sjose borrego 		++count;
568da6c28aaSamw 	}
569*a90cf9f2SGordon Ross 	if (args->fa_eos != 0 && rc == ENOENT)
570*a90cf9f2SGordon Ross 		rc = 0;
571da6c28aaSamw 
5727f667e74Sjose borrego 	/* save the last cookie returned to client */
5737f667e74Sjose borrego 	if (count != 0)
574bfbce3c1SGordon Ross 		smb_odir_save_fname(od, args->fa_lastkey, args->fa_lastname);
575da6c28aaSamw 
5761fcced4cSJordan Brown 	/*
5771fcced4cSJordan Brown 	 * If all retrieved entries have been successfully encoded
5781fcced4cSJordan Brown 	 * and eos has not already been detected, check if there are
5791fcced4cSJordan Brown 	 * any more entries. eos will be set if there are no more.
5801fcced4cSJordan Brown 	 */
581*a90cf9f2SGordon Ross 	if ((rc == 0) && (args->fa_eos == 0)) {
582*a90cf9f2SGordon Ross 		rc = smb_odir_read_fileinfo(sr, od, &fileinfo, &args->fa_eos);
583*a90cf9f2SGordon Ross 		/*
584*a90cf9f2SGordon Ross 		 * If rc == ENOENT, we did not read any additional data.
585*a90cf9f2SGordon Ross 		 * if rc != 0, there's no need to rewind.
586*a90cf9f2SGordon Ross 		 */
587*a90cf9f2SGordon Ross 		if (rc == 0)
588*a90cf9f2SGordon Ross 			need_rewind = B_TRUE;
589*a90cf9f2SGordon Ross 	}
590bfbce3c1SGordon Ross 
591bfbce3c1SGordon Ross 	/*
592bfbce3c1SGordon Ross 	 * When the last entry we read from the directory did not
593bfbce3c1SGordon Ross 	 * fit in the return buffer, we will have read one entry
594bfbce3c1SGordon Ross 	 * that will not be returned in this call.  That, and the
595bfbce3c1SGordon Ross 	 * check for EOS just above both can leave the directory
596bfbce3c1SGordon Ross 	 * position incorrect for the next call.  Fix that now.
597bfbce3c1SGordon Ross 	 */
598*a90cf9f2SGordon Ross 	if (need_rewind) {
599bfbce3c1SGordon Ross 		bzero(&odir_resume, sizeof (odir_resume));
600bfbce3c1SGordon Ross 		odir_resume.or_type = SMB_ODIR_RESUME_COOKIE;
601bfbce3c1SGordon Ross 		odir_resume.or_cookie = args->fa_lastkey;
602bfbce3c1SGordon Ross 		smb_odir_resume_at(od, &odir_resume);
603*a90cf9f2SGordon Ross 	}
604da6c28aaSamw 
6057f667e74Sjose borrego 	return (count);
606da6c28aaSamw }
607da6c28aaSamw 
608da6c28aaSamw /*
609da6c28aaSamw  * smb_trans2_find_get_maxdata
610da6c28aaSamw  *
611dc20a302Sas200622  * Calculate the minimum response space required for the specified
612dc20a302Sas200622  * information level.
613da6c28aaSamw  *
614dc20a302Sas200622  * A non-zero return value provides the minimum space required.
615dc20a302Sas200622  * A return value of zero indicates an unknown information level.
616da6c28aaSamw  */
617dc20a302Sas200622 static int
618dc20a302Sas200622 smb_trans2_find_get_maxdata(smb_request_t *sr, uint16_t infolev, uint16_t fflag)
619da6c28aaSamw {
620da6c28aaSamw 	int maxdata;
621da6c28aaSamw 
622da6c28aaSamw 	maxdata = smb_ascii_or_unicode_null_len(sr);
623da6c28aaSamw 
624da6c28aaSamw 	switch (infolev) {
625da6c28aaSamw 	case SMB_INFO_STANDARD :
626da6c28aaSamw 		if (fflag & SMB_FIND_RETURN_RESUME_KEYS)
627da6c28aaSamw 			maxdata += sizeof (int32_t);
628da6c28aaSamw 		maxdata += 2 + 2 + 2 + 4 + 4 + 2 + 1;
629da6c28aaSamw 		break;
630da6c28aaSamw 
631da6c28aaSamw 	case SMB_INFO_QUERY_EA_SIZE:
632da6c28aaSamw 		if (fflag & SMB_FIND_RETURN_RESUME_KEYS)
633da6c28aaSamw 			maxdata += sizeof (int32_t);
634da6c28aaSamw 		maxdata += 2 + 2 + 2 + 4 + 4 + 2 + 4 + 1;
635da6c28aaSamw 		break;
636da6c28aaSamw 
637da6c28aaSamw 	case SMB_FIND_FILE_DIRECTORY_INFO:
638da6c28aaSamw 		maxdata += 4 + 4 + 8 + 8 + 8 + 8 + 8 + 8 + 4 + 4;
639da6c28aaSamw 		break;
640da6c28aaSamw 
641b89a8333Snatalie li - Sun Microsystems - Irvine United States 	case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
642b89a8333Snatalie li - Sun Microsystems - Irvine United States 		maxdata += 4 + 4 + 8 + 8 + 8 + 8 + 8 + 8 + 4 + 4 + 4;
643b89a8333Snatalie li - Sun Microsystems - Irvine United States 		break;
644b89a8333Snatalie li - Sun Microsystems - Irvine United States 
645b89a8333Snatalie li - Sun Microsystems - Irvine United States 	case SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO:
646b89a8333Snatalie li - Sun Microsystems - Irvine United States 		maxdata += 4 + 4 + 8 + 8 + 8 + 8 + 8 + 8 + 4 + 4 + 4 + 4 + 8;
647b89a8333Snatalie li - Sun Microsystems - Irvine United States 		break;
648b89a8333Snatalie li - Sun Microsystems - Irvine United States 
649da6c28aaSamw 	case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
650da6c28aaSamw 		maxdata += 4 + 4 + 8 + 8 + 8 + 8 + 8 + 8 + 4 + 4 + 4 + 2 + 24;
651da6c28aaSamw 		break;
652da6c28aaSamw 
653b89a8333Snatalie li - Sun Microsystems - Irvine United States 	case SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO:
654b89a8333Snatalie li - Sun Microsystems - Irvine United States 		maxdata += 4 + 4 + 8 + 8 + 8 + 8 + 8 + 8 + 4 + 4 + 4 + 2 + 24
655b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    + 2 + 8;
656b89a8333Snatalie li - Sun Microsystems - Irvine United States 		break;
657b89a8333Snatalie li - Sun Microsystems - Irvine United States 
658da6c28aaSamw 	case SMB_FIND_FILE_NAMES_INFO:
659da6c28aaSamw 		maxdata += 4 + 4 + 4;
660da6c28aaSamw 		break;
661da6c28aaSamw 
662da6c28aaSamw 	case SMB_MAC_FIND_BOTH_HFS_INFO:
663da6c28aaSamw 		maxdata += 4 + 4 + 8 + 8 + 8 + 8 + 8 + 8 + 8 + 4 + 1 + 1 + 2 +
664da6c28aaSamw 		    4 + 32 + 4 + 1 + 1 + 24 + 4;
665da6c28aaSamw 		break;
666da6c28aaSamw 
667da6c28aaSamw 	default:
668da6c28aaSamw 		maxdata = 0;
6697f667e74Sjose borrego 		smbsr_error(sr, NT_STATUS_INVALID_LEVEL,
6707f667e74Sjose borrego 		    ERRDOS, ERROR_INVALID_LEVEL);
671da6c28aaSamw 	}
672da6c28aaSamw 
673da6c28aaSamw 	return (maxdata);
674da6c28aaSamw }
675da6c28aaSamw 
676da6c28aaSamw /*
677bfbce3c1SGordon Ross  * This is an experimental feature that allows us to return zero
678bfbce3c1SGordon Ross  * for all numeric resume keys, to match Windows behavior with an
679bfbce3c1SGordon Ross  * NTFS share.  Setting this variable to zero does that.
680bfbce3c1SGordon Ross  *
681bfbce3c1SGordon Ross  * It's possible we could remove this variable and always set
682bfbce3c1SGordon Ross  * numeric resume keys to zero, but that would leave us unable
683bfbce3c1SGordon Ross  * to handle a FindNext call with an arbitrary start position.
684bfbce3c1SGordon Ross  * In practice we never see these, but in theory we could.
685bfbce3c1SGordon Ross  *
686bfbce3c1SGordon Ross  * See the long comment above smb_com_trans2_find_next2() for
687bfbce3c1SGordon Ross  * more details about resume key / resume name handling.
688bfbce3c1SGordon Ross  */
689bfbce3c1SGordon Ross int smbd_use_resume_keys = 1;
690bfbce3c1SGordon Ross 
691bfbce3c1SGordon Ross /*
6927f667e74Sjose borrego  * smb_trans2_mbc_encode
693da6c28aaSamw  *
694da6c28aaSamw  * This function encodes the mbc for one directory entry.
695da6c28aaSamw  *
696da6c28aaSamw  * The function returns -1 when the max data requested by client
697da6c28aaSamw  * is reached. If the entry is valid and successful encoded, 0
698da6c28aaSamw  * will be returned; otherwise, 1 will be returned.
699b89a8333Snatalie li - Sun Microsystems - Irvine United States  *
700b89a8333Snatalie li - Sun Microsystems - Irvine United States  * We always null terminate the filename. The space for the null
701b89a8333Snatalie li - Sun Microsystems - Irvine United States  * is included in the maxdata calculation and is therefore included
702b89a8333Snatalie li - Sun Microsystems - Irvine United States  * in the next_entry_offset. namelen is the unterminated length of
703b89a8333Snatalie li - Sun Microsystems - Irvine United States  * the filename. For levels except STANDARD and EA_SIZE, if the
704b89a8333Snatalie li - Sun Microsystems - Irvine United States  * filename is ascii the name length returned to the client should
705b89a8333Snatalie li - Sun Microsystems - Irvine United States  * include the null terminator. Otherwise the length returned to
706b89a8333Snatalie li - Sun Microsystems - Irvine United States  * the client should not include the terminator.
7077f667e74Sjose borrego  *
7087f667e74Sjose borrego  * Returns: 0 - data successfully encoded
7097f667e74Sjose borrego  *          1 - client request's maxdata limit reached
7107f667e74Sjose borrego  *	   -1 - error
711da6c28aaSamw  */
7127f667e74Sjose borrego static int
7137f667e74Sjose borrego smb_trans2_find_mbc_encode(smb_request_t *sr, smb_xa_t *xa,
7147f667e74Sjose borrego     smb_fileinfo_t *fileinfo, smb_find_args_t *args)
715da6c28aaSamw {
716bfbce3c1SGordon Ross 	int		namelen, shortlen;
717dc20a302Sas200622 	uint32_t	next_entry_offset;
7187f667e74Sjose borrego 	uint32_t	dsize32, asize32;
7197f667e74Sjose borrego 	uint32_t	mb_flags = 0;
720bfbce3c1SGordon Ross 	uint32_t	resume_key;
721da6c28aaSamw 	char		buf83[26];
722da6c28aaSamw 	smb_msgbuf_t	mb;
723da6c28aaSamw 
7247f667e74Sjose borrego 	namelen = smb_ascii_or_unicode_strlen(sr, fileinfo->fi_name);
725b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (namelen == -1)
726da6c28aaSamw 		return (-1);
727da6c28aaSamw 
728b89a8333Snatalie li - Sun Microsystems - Irvine United States 	/*
729b89a8333Snatalie li - Sun Microsystems - Irvine United States 	 * If ascii the filename length returned to the client should
730b89a8333Snatalie li - Sun Microsystems - Irvine United States 	 * include the null terminator for levels except STANDARD and
731b89a8333Snatalie li - Sun Microsystems - Irvine United States 	 * EASIZE.
732b89a8333Snatalie li - Sun Microsystems - Irvine United States 	 */
733b89a8333Snatalie li - Sun Microsystems - Irvine United States 	if (!(sr->smb_flg2 & SMB_FLAGS2_UNICODE)) {
7347f667e74Sjose borrego 		if ((args->fa_infolev != SMB_INFO_STANDARD) &&
7357f667e74Sjose borrego 		    (args->fa_infolev != SMB_INFO_QUERY_EA_SIZE))
736b89a8333Snatalie li - Sun Microsystems - Irvine United States 			namelen += 1;
737b89a8333Snatalie li - Sun Microsystems - Irvine United States 	}
738b89a8333Snatalie li - Sun Microsystems - Irvine United States 
739bfbce3c1SGordon Ross 	next_entry_offset = args->fa_maxdata + namelen;
740bfbce3c1SGordon Ross 
741bfbce3c1SGordon Ross 	if (MBC_ROOM_FOR(&xa->rep_data_mb, (args->fa_maxdata + namelen)) == 0)
742bfbce3c1SGordon Ross 		return (1);
743bfbce3c1SGordon Ross 
7447f667e74Sjose borrego 	mb_flags = (sr->smb_flg2 & SMB_FLAGS2_UNICODE) ? SMB_MSGBUF_UNICODE : 0;
7457f667e74Sjose borrego 	dsize32 = (fileinfo->fi_size > UINT_MAX) ?
7467f667e74Sjose borrego 	    UINT_MAX : (uint32_t)fileinfo->fi_size;
7477f667e74Sjose borrego 	asize32 = (fileinfo->fi_alloc_size > UINT_MAX) ?
7487f667e74Sjose borrego 	    UINT_MAX : (uint32_t)fileinfo->fi_alloc_size;
749da6c28aaSamw 
750bfbce3c1SGordon Ross 	resume_key = fileinfo->fi_cookie;
751bfbce3c1SGordon Ross 	if (smbd_use_resume_keys == 0)
752bfbce3c1SGordon Ross 		resume_key = 0;
753bfbce3c1SGordon Ross 
754bfbce3c1SGordon Ross 	/*
755bfbce3c1SGordon Ross 	 * This switch handles all the "information levels" (formats)
756bfbce3c1SGordon Ross 	 * that we support.  Note that all formats have the file name
757bfbce3c1SGordon Ross 	 * placed after some fixed-size data, and the code to write
758bfbce3c1SGordon Ross 	 * the file name is factored out at the end of this switch.
759bfbce3c1SGordon Ross 	 */
7607f667e74Sjose borrego 	switch (args->fa_infolev) {
761da6c28aaSamw 	case SMB_INFO_STANDARD:
7627f667e74Sjose borrego 		if (args->fa_fflag & SMB_FIND_RETURN_RESUME_KEYS)
7633db3f65cSamw 			(void) smb_mbc_encodef(&xa->rep_data_mb, "l",
764bfbce3c1SGordon Ross 			    resume_key);
765da6c28aaSamw 
766bfbce3c1SGordon Ross 		(void) smb_mbc_encodef(&xa->rep_data_mb, "%yyyllwb", sr,
767e3f2c991SKeyur Desai 		    smb_time_gmt_to_local(sr, fileinfo->fi_crtime.tv_sec),
768e3f2c991SKeyur Desai 		    smb_time_gmt_to_local(sr, fileinfo->fi_atime.tv_sec),
769e3f2c991SKeyur Desai 		    smb_time_gmt_to_local(sr, fileinfo->fi_mtime.tv_sec),
7706537f381Sas200622 		    dsize32,
7716537f381Sas200622 		    asize32,
7727f667e74Sjose borrego 		    fileinfo->fi_dosattr,
773bfbce3c1SGordon Ross 		    namelen);
774da6c28aaSamw 		break;
775da6c28aaSamw 
776da6c28aaSamw 	case SMB_INFO_QUERY_EA_SIZE:
7777f667e74Sjose borrego 		if (args->fa_fflag & SMB_FIND_RETURN_RESUME_KEYS)
7783db3f65cSamw 			(void) smb_mbc_encodef(&xa->rep_data_mb, "l",
779bfbce3c1SGordon Ross 			    resume_key);
780da6c28aaSamw 
781bfbce3c1SGordon Ross 		(void) smb_mbc_encodef(&xa->rep_data_mb, "%yyyllwlb", sr,
782e3f2c991SKeyur Desai 		    smb_time_gmt_to_local(sr, fileinfo->fi_crtime.tv_sec),
783e3f2c991SKeyur Desai 		    smb_time_gmt_to_local(sr, fileinfo->fi_atime.tv_sec),
784e3f2c991SKeyur Desai 		    smb_time_gmt_to_local(sr, fileinfo->fi_mtime.tv_sec),
7856537f381Sas200622 		    dsize32,
7866537f381Sas200622 		    asize32,
7877f667e74Sjose borrego 		    fileinfo->fi_dosattr,
788da6c28aaSamw 		    0L,		/* EA Size */
789bfbce3c1SGordon Ross 		    namelen);
790da6c28aaSamw 		break;
791da6c28aaSamw 
792da6c28aaSamw 	case SMB_FIND_FILE_DIRECTORY_INFO:
793bfbce3c1SGordon Ross 		(void) smb_mbc_encodef(&xa->rep_data_mb, "%llTTTTqqll", sr,
794dc20a302Sas200622 		    next_entry_offset,
795bfbce3c1SGordon Ross 		    resume_key,
7967f667e74Sjose borrego 		    &fileinfo->fi_crtime,
7977f667e74Sjose borrego 		    &fileinfo->fi_atime,
7987f667e74Sjose borrego 		    &fileinfo->fi_mtime,
7997f667e74Sjose borrego 		    &fileinfo->fi_ctime,
8007f667e74Sjose borrego 		    fileinfo->fi_size,
8017f667e74Sjose borrego 		    fileinfo->fi_alloc_size,
8027f667e74Sjose borrego 		    fileinfo->fi_dosattr,
803bfbce3c1SGordon Ross 		    namelen);
804b89a8333Snatalie li - Sun Microsystems - Irvine United States 		break;
805b89a8333Snatalie li - Sun Microsystems - Irvine United States 
806b89a8333Snatalie li - Sun Microsystems - Irvine United States 	case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
807bfbce3c1SGordon Ross 		(void) smb_mbc_encodef(&xa->rep_data_mb, "%llTTTTqqlll", sr,
808b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    next_entry_offset,
809bfbce3c1SGordon Ross 		    resume_key,
8107f667e74Sjose borrego 		    &fileinfo->fi_crtime,
8117f667e74Sjose borrego 		    &fileinfo->fi_atime,
8127f667e74Sjose borrego 		    &fileinfo->fi_mtime,
8137f667e74Sjose borrego 		    &fileinfo->fi_ctime,
8147f667e74Sjose borrego 		    fileinfo->fi_size,
8157f667e74Sjose borrego 		    fileinfo->fi_alloc_size,
8167f667e74Sjose borrego 		    fileinfo->fi_dosattr,
817b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    namelen,
818bfbce3c1SGordon Ross 		    0L);
819b89a8333Snatalie li - Sun Microsystems - Irvine United States 		break;
820b89a8333Snatalie li - Sun Microsystems - Irvine United States 
821b89a8333Snatalie li - Sun Microsystems - Irvine United States 	case SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO:
822bfbce3c1SGordon Ross 		(void) smb_mbc_encodef(&xa->rep_data_mb, "%llTTTTqqlll4.q", sr,
823b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    next_entry_offset,
824bfbce3c1SGordon Ross 		    resume_key,
8257f667e74Sjose borrego 		    &fileinfo->fi_crtime,
8267f667e74Sjose borrego 		    &fileinfo->fi_atime,
8277f667e74Sjose borrego 		    &fileinfo->fi_mtime,
8287f667e74Sjose borrego 		    &fileinfo->fi_ctime,
8297f667e74Sjose borrego 		    fileinfo->fi_size,
8307f667e74Sjose borrego 		    fileinfo->fi_alloc_size,
8317f667e74Sjose borrego 		    fileinfo->fi_dosattr,
832b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    namelen,
833b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    0L,
834bfbce3c1SGordon Ross 		    fileinfo->fi_nodeid);
835da6c28aaSamw 		break;
836da6c28aaSamw 
837da6c28aaSamw 	case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
838da6c28aaSamw 		bzero(buf83, sizeof (buf83));
839dc20a302Sas200622 		smb_msgbuf_init(&mb, (uint8_t *)buf83, sizeof (buf83),
840da6c28aaSamw 		    mb_flags);
8417f667e74Sjose borrego 		if (smb_msgbuf_encode(&mb, "U", fileinfo->fi_shortname) < 0) {
842da6c28aaSamw 			smb_msgbuf_term(&mb);
843da6c28aaSamw 			return (-1);
844da6c28aaSamw 		}
845bbf6f00cSJordan Brown 		shortlen = smb_wcequiv_strlen(fileinfo->fi_shortname);
846da6c28aaSamw 
847bfbce3c1SGordon Ross 		(void) smb_mbc_encodef(&xa->rep_data_mb, "%llTTTTqqlllb.24c",
848dc20a302Sas200622 		    sr,
849dc20a302Sas200622 		    next_entry_offset,
850bfbce3c1SGordon Ross 		    resume_key,
8517f667e74Sjose borrego 		    &fileinfo->fi_crtime,
8527f667e74Sjose borrego 		    &fileinfo->fi_atime,
8537f667e74Sjose borrego 		    &fileinfo->fi_mtime,
8547f667e74Sjose borrego 		    &fileinfo->fi_ctime,
8557f667e74Sjose borrego 		    fileinfo->fi_size,
8567f667e74Sjose borrego 		    fileinfo->fi_alloc_size,
8577f667e74Sjose borrego 		    fileinfo->fi_dosattr,
858b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    namelen,
859da6c28aaSamw 		    0L,
860dc20a302Sas200622 		    shortlen,
861bfbce3c1SGordon Ross 		    buf83);
862da6c28aaSamw 
863da6c28aaSamw 		smb_msgbuf_term(&mb);
864da6c28aaSamw 		break;
865da6c28aaSamw 
866b89a8333Snatalie li - Sun Microsystems - Irvine United States 	case SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO:
867b89a8333Snatalie li - Sun Microsystems - Irvine United States 		bzero(buf83, sizeof (buf83));
868b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_msgbuf_init(&mb, (uint8_t *)buf83, sizeof (buf83),
869b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    mb_flags);
8707f667e74Sjose borrego 		if (smb_msgbuf_encode(&mb, "u", fileinfo->fi_shortname) < 0) {
871b89a8333Snatalie li - Sun Microsystems - Irvine United States 			smb_msgbuf_term(&mb);
872b89a8333Snatalie li - Sun Microsystems - Irvine United States 			return (-1);
873b89a8333Snatalie li - Sun Microsystems - Irvine United States 		}
8747f667e74Sjose borrego 		shortlen = smb_ascii_or_unicode_strlen(sr,
8757f667e74Sjose borrego 		    fileinfo->fi_shortname);
876b89a8333Snatalie li - Sun Microsystems - Irvine United States 
877b89a8333Snatalie li - Sun Microsystems - Irvine United States 		(void) smb_mbc_encodef(&xa->rep_data_mb,
878bfbce3c1SGordon Ross 		    "%llTTTTqqlllb.24c2.q",
879b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    sr,
880b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    next_entry_offset,
881bfbce3c1SGordon Ross 		    resume_key,
8827f667e74Sjose borrego 		    &fileinfo->fi_crtime,
8837f667e74Sjose borrego 		    &fileinfo->fi_atime,
8847f667e74Sjose borrego 		    &fileinfo->fi_mtime,
8857f667e74Sjose borrego 		    &fileinfo->fi_ctime,
8867f667e74Sjose borrego 		    fileinfo->fi_size,
8877f667e74Sjose borrego 		    fileinfo->fi_alloc_size,
8887f667e74Sjose borrego 		    fileinfo->fi_dosattr,
889b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    namelen,
890b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    0L,
891b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    shortlen,
892b89a8333Snatalie li - Sun Microsystems - Irvine United States 		    buf83,
893bfbce3c1SGordon Ross 		    fileinfo->fi_nodeid);
894b89a8333Snatalie li - Sun Microsystems - Irvine United States 
895b89a8333Snatalie li - Sun Microsystems - Irvine United States 		smb_msgbuf_term(&mb);
896b89a8333Snatalie li - Sun Microsystems - Irvine United States 		break;
897b89a8333Snatalie li - Sun Microsystems - Irvine United States 
898da6c28aaSamw 	case SMB_FIND_FILE_NAMES_INFO:
899bfbce3c1SGordon Ross 		(void) smb_mbc_encodef(&xa->rep_data_mb, "%lll", sr,
900dc20a302Sas200622 		    next_entry_offset,
901bfbce3c1SGordon Ross 		    resume_key,
902bfbce3c1SGordon Ross 		    namelen);
903da6c28aaSamw 		break;
904bfbce3c1SGordon Ross 
905bfbce3c1SGordon Ross 	default:
906bfbce3c1SGordon Ross 		/* invalid info. level */
907bfbce3c1SGordon Ross 		return (-1);
908da6c28aaSamw 	}
909da6c28aaSamw 
910bfbce3c1SGordon Ross 	/*
911bfbce3c1SGordon Ross 	 * At this point we have written all the fixed-size data
912bfbce3c1SGordon Ross 	 * for the specified info. level, and we're about to put
913bfbce3c1SGordon Ross 	 * the file name string in the message.  We may later
914bfbce3c1SGordon Ross 	 * need the offset in the trans2 data where this string
915bfbce3c1SGordon Ross 	 * is placed, so save the message position now.  Note:
916bfbce3c1SGordon Ross 	 * We also need to account for the alignment padding
917bfbce3c1SGordon Ross 	 * that may precede the unicode string.
918bfbce3c1SGordon Ross 	 */
919bfbce3c1SGordon Ross 	args->fa_lno = xa->rep_data_mb.chain_offset;
920bfbce3c1SGordon Ross 	if ((sr->smb_flg2 & SMB_FLAGS2_UNICODE) != 0 &&
921bfbce3c1SGordon Ross 	    (args->fa_lno & 1) != 0)
922bfbce3c1SGordon Ross 		args->fa_lno++;
923bfbce3c1SGordon Ross 
924bfbce3c1SGordon Ross 	(void) smb_mbc_encodef(&xa->rep_data_mb, "%u", sr,
925bfbce3c1SGordon Ross 	    fileinfo->fi_name);
926bfbce3c1SGordon Ross 
927da6c28aaSamw 	return (0);
928da6c28aaSamw }
929da6c28aaSamw 
930da6c28aaSamw /*
931da6c28aaSamw  * Close a search started by a Trans2FindFirst2 request.
932da6c28aaSamw  */
9337b59d02dSjb150015 smb_sdrc_t
934faa1795aSjb150015 smb_pre_find_close2(smb_request_t *sr)
935faa1795aSjb150015 {
936faa1795aSjb150015 	DTRACE_SMB_1(op__FindClose2__start, smb_request_t *, sr);
9377f667e74Sjose borrego 	return (SDRC_SUCCESS);
938faa1795aSjb150015 }
939faa1795aSjb150015 
940faa1795aSjb150015 void
941faa1795aSjb150015 smb_post_find_close2(smb_request_t *sr)
942faa1795aSjb150015 {
943faa1795aSjb150015 	DTRACE_SMB_1(op__FindClose2__done, smb_request_t *, sr);
944faa1795aSjb150015 }
945faa1795aSjb150015 
946faa1795aSjb150015 smb_sdrc_t
947dc20a302Sas200622 smb_com_find_close2(smb_request_t *sr)
948da6c28aaSamw {
9497f667e74Sjose borrego 	uint16_t	odid;
9507f667e74Sjose borrego 	smb_odir_t	*od;
9517f667e74Sjose borrego 
9527f667e74Sjose borrego 	if (smbsr_decode_vwv(sr, "w", &odid) != 0)
9537f667e74Sjose borrego 		return (SDRC_ERROR);
9547f667e74Sjose borrego 
9553b13a1efSThomas Keiser 	od = smb_tree_lookup_odir(sr, odid);
9567f667e74Sjose borrego 	if (od == NULL) {
9577f667e74Sjose borrego 		smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
9587f667e74Sjose borrego 		    ERRDOS, ERROR_INVALID_HANDLE);
959faa1795aSjb150015 		return (SDRC_ERROR);
960da6c28aaSamw 	}
961da6c28aaSamw 
9627f667e74Sjose borrego 	smb_odir_close(od);
9637f667e74Sjose borrego 	smb_odir_release(od);
9647b59d02dSjb150015 
9657b59d02dSjb150015 	if (smbsr_encode_empty_result(sr))
966faa1795aSjb150015 		return (SDRC_ERROR);
9677b59d02dSjb150015 
968faa1795aSjb150015 	return (SDRC_SUCCESS);
969da6c28aaSamw }
970