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 *
2593bc28dbSGordon Ross * Copyright 2017 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 {
21607a6ae61SGordon Ross uint32_t fa_fixedsize;
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;
225da6c28aaSamw
2267f667e74Sjose borrego static int smb_trans2_find_entries(smb_request_t *, smb_xa_t *,
227bfbce3c1SGordon Ross smb_odir_t *, smb_find_args_t *);
22807a6ae61SGordon Ross static int smb_trans2_find_get_fixedsize(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 /*
233dc20a302Sas * Tunable parameter to limit the maximum
234dc20a302Sas * number of entries to be returned.
235da6c28aaSamw */
236dc20a302Sas 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 */
2817b59d02dSjb smb_sdrc_t
smb_com_trans2_find_first2(smb_request_t * sr,smb_xa_t * xa)282dc20a302Sas smb_com_trans2_find_first2(smb_request_t *sr, smb_xa_t *xa)
283da6c28aaSamw {
2847f667e74Sjose borrego int count;
285a90cf9f2SGordon 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;
289a90cf9f2SGordon 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)) {
295dc20a302Sas smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
296da6c28aaSamw ERRDOS, ERROR_ACCESS_DENIED);
297faa1795aSjb 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) {
305faa1795aSjb 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
32307a6ae61SGordon Ross args.fa_fixedsize =
32407a6ae61SGordon Ross smb_trans2_find_get_fixedsize(sr, args.fa_infolev, args.fa_fflag);
32507a6ae61SGordon Ross if (args.fa_fixedsize == 0)
326faa1795aSjb return (SDRC_ERROR);
327dc20a302Sas
328a90cf9f2SGordon Ross status = smb_odir_openpath(sr, pn->pn_path, sattr, odir_flags, &od);
329a90cf9f2SGordon Ross if (status != 0) {
330a90cf9f2SGordon Ross smbsr_error(sr, status, 0, 0);
331faa1795aSjb 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);
337da6c28aaSamw
3387f667e74Sjose borrego if (count == -1) {
3397f667e74Sjose borrego smb_odir_close(od);
340a1511e6bSjoyce mcintosh smb_odir_release(od);
341faa1795aSjb return (SDRC_ERROR);
342da6c28aaSamw }
343da6c28aaSamw
3447f667e74Sjose borrego if (count == 0) {
3457f667e74Sjose borrego smb_odir_close(od);
346a1511e6bSjoyce mcintosh smb_odir_release(od);
347*d2488fe8SGordon Ross smbsr_status(sr, NT_STATUS_NO_SUCH_FILE,
348*d2488fe8SGordon Ross ERRDOS, ERROR_FILE_NOT_FOUND);
3497f667e74Sjose borrego return (SDRC_ERROR);
350da6c28aaSamw }
351da6c28aaSamw
3527f667e74Sjose borrego if ((args.fa_fflag & SMB_FIND_CLOSE_AFTER_REQUEST) ||
353bfbce3c1SGordon Ross (args.fa_eos && (args.fa_fflag & SMB_FIND_CLOSE_AT_EOS))) {
3547f667e74Sjose borrego smb_odir_close(od);
3557f667e74Sjose borrego } /* else leave odir open for trans2_find_next2 */
3567f667e74Sjose borrego
3573db3f65cSamw (void) smb_mbc_encodef(&xa->rep_param_mb, "wwwww",
358a90cf9f2SGordon Ross od->d_odid, /* Search ID */
359bfbce3c1SGordon Ross count, /* Search Count */
360bfbce3c1SGordon Ross args.fa_eos, /* End Of Search */
361bfbce3c1SGordon Ross 0, /* EA Error Offset */
362bfbce3c1SGordon Ross args.fa_lno); /* Last Name Offset */
363da6c28aaSamw
364a90cf9f2SGordon Ross smb_odir_release(od);
365a90cf9f2SGordon Ross
366faa1795aSjb return (SDRC_SUCCESS);
367da6c28aaSamw }
368da6c28aaSamw
369da6c28aaSamw /*
370da6c28aaSamw * smb_com_trans2_find_next2
371da6c28aaSamw *
372da6c28aaSamw * Client Request Value
373da6c28aaSamw * ================================== =================================
374da6c28aaSamw *
375da6c28aaSamw * WordCount 15
376da6c28aaSamw * SetupCount 1
377da6c28aaSamw * Setup[0] TRANS2_FIND_NEXT2
378da6c28aaSamw *
379da6c28aaSamw * Parameter Block Encoding Description
380da6c28aaSamw * ================================== =================================
381da6c28aaSamw *
382da6c28aaSamw * USHORT Sid; Search handle
383da6c28aaSamw * USHORT SearchCount; Maximum number of entries to
384da6c28aaSamw * return
385da6c28aaSamw * USHORT InformationLevel; Levels described in
386da6c28aaSamw * TRANS2_FIND_FIRST2 request
387da6c28aaSamw * ULONG ResumeKey; Value returned by previous find2
388da6c28aaSamw * call
389da6c28aaSamw * USHORT Flags; Additional information: bit set-
390da6c28aaSamw * 0 - close search after this
391da6c28aaSamw * request
392da6c28aaSamw * 1 - close search if end of search
393da6c28aaSamw * reached
394da6c28aaSamw * 2 - return resume keys for each
395da6c28aaSamw * entry found
396da6c28aaSamw * 3 - resume/continue from previous
397da6c28aaSamw * ending place
398da6c28aaSamw * 4 - find with backup intent
399da6c28aaSamw * STRING FileName; Resume file name
400da6c28aaSamw *
401da6c28aaSamw * Sid is the value returned by a previous successful TRANS2_FIND_FIRST2
402da6c28aaSamw * call. If Bit3 of Flags is set, then FileName may be the NULL string,
403da6c28aaSamw * since the search is continued from the previous TRANS2_FIND request.
404da6c28aaSamw * Otherwise, FileName must not be more than 256 characters long.
405da6c28aaSamw *
406da6c28aaSamw * Response Field Description
407da6c28aaSamw * ================================== =================================
408da6c28aaSamw *
409da6c28aaSamw * USHORT SearchCount; Number of entries returned
410da6c28aaSamw * USHORT EndOfSearch; Was last entry returned?
411da6c28aaSamw * USHORT EaErrorOffset; Offset into EA list if EA error
412da6c28aaSamw * USHORT LastNameOffset; Offset into data to file name of
413da6c28aaSamw * last entry, if server needs it to
414da6c28aaSamw * resume search; else 0
415da6c28aaSamw * UCHAR Data[TotalDataCount] Level dependent info about the
416da6c28aaSamw * matches found in the search
417b89a8333Snatalie li - Sun Microsystems - Irvine United States *
418b89a8333Snatalie li - Sun Microsystems - Irvine United States *
419b89a8333Snatalie li - Sun Microsystems - Irvine United States * The last parameter in the request is a filename, which is a
420b89a8333Snatalie li - Sun Microsystems - Irvine United States * null-terminated unicode string.
421b89a8333Snatalie li - Sun Microsystems - Irvine United States *
422b89a8333Snatalie li - Sun Microsystems - Irvine United States * smb_mbc_decodef(&xa->req_param_mb, "%www lwu", sr,
4237f667e74Sjose borrego * &odid, &fa_maxcount, &fa_infolev, &cookie, &fa_fflag, &fname)
424b89a8333Snatalie li - Sun Microsystems - Irvine United States *
4257f667e74Sjose borrego * The filename parameter is not currently decoded because we
4267f667e74Sjose borrego * expect a 2-byte null but Mac OS 10 clients send a 1-byte null,
427b89a8333Snatalie li - Sun Microsystems - Irvine United States * which leads to a decode error.
428b89a8333Snatalie li - Sun Microsystems - Irvine United States * Thus, we do not support resume by filename. We treat a request
429b89a8333Snatalie li - Sun Microsystems - Irvine United States * to resume by filename as SMB_FIND_CONTINUE_FROM_LAST.
430da6c28aaSamw */
4317b59d02dSjb smb_sdrc_t
smb_com_trans2_find_next2(smb_request_t * sr,smb_xa_t * xa)432dc20a302Sas smb_com_trans2_find_next2(smb_request_t *sr, smb_xa_t *xa)
433da6c28aaSamw {
4347f667e74Sjose borrego int count;
4357f667e74Sjose borrego uint16_t odid;
4367f667e74Sjose borrego smb_odir_t *od;
4377f667e74Sjose borrego smb_find_args_t args;
4387f667e74Sjose borrego smb_odir_resume_t odir_resume;
4397f667e74Sjose borrego
440bfbce3c1SGordon Ross bzero(&args, sizeof (args));
441bfbce3c1SGordon Ross bzero(&odir_resume, sizeof (odir_resume));
4427f667e74Sjose borrego
443bfbce3c1SGordon Ross if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) {
444bfbce3c1SGordon Ross smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
445bfbce3c1SGordon Ross ERRDOS, ERROR_ACCESS_DENIED);
446faa1795aSjb return (SDRC_ERROR);
447da6c28aaSamw }
448da6c28aaSamw
449bfbce3c1SGordon Ross if (smb_mbc_decodef(&xa->req_param_mb, "%wwwlwu", sr,
450bfbce3c1SGordon Ross &odid, &args.fa_maxcount, &args.fa_infolev,
451bfbce3c1SGordon Ross &odir_resume.or_cookie, &args.fa_fflag,
452bfbce3c1SGordon Ross &odir_resume.or_fname) != 0) {
453bfbce3c1SGordon Ross return (SDRC_ERROR);
4547f667e74Sjose borrego }
455b89a8333Snatalie li - Sun Microsystems - Irvine United States
4567f667e74Sjose borrego if (args.fa_fflag & SMB_FIND_WITH_BACKUP_INTENT)
457b89a8333Snatalie li - Sun Microsystems - Irvine United States sr->user_cr = smb_user_getprivcred(sr->uid_user);
458b89a8333Snatalie li - Sun Microsystems - Irvine United States
45907a6ae61SGordon Ross args.fa_fixedsize =
46007a6ae61SGordon Ross smb_trans2_find_get_fixedsize(sr, args.fa_infolev, args.fa_fflag);
46107a6ae61SGordon Ross if (args.fa_fixedsize == 0)
4627f667e74Sjose borrego return (SDRC_ERROR);
4637f667e74Sjose borrego
4643b13a1efSThomas Keiser od = smb_tree_lookup_odir(sr, odid);
4657f667e74Sjose borrego if (od == NULL) {
4667f667e74Sjose borrego smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
4677f667e74Sjose borrego ERRDOS, ERROR_INVALID_HANDLE);
468faa1795aSjb return (SDRC_ERROR);
469da6c28aaSamw }
470bfbce3c1SGordon Ross
471bfbce3c1SGordon Ross /*
472bfbce3c1SGordon Ross * Set the correct position in the directory.
473bfbce3c1SGordon Ross *
474bfbce3c1SGordon Ross * "Continue from last" is easy, but due to a history of
475bfbce3c1SGordon Ross * buggy server implementations, most clients don't use
476bfbce3c1SGordon Ross * that method. The most widely used (and reliable) is
477bfbce3c1SGordon Ross * resume by file name. Unfortunately, that can't really
478bfbce3c1SGordon Ross * be fully supported unless your file system stores all
479bfbce3c1SGordon Ross * directory entries in some sorted order (like NTFS).
480bfbce3c1SGordon Ross * We can partially support resume by name, where the only
481bfbce3c1SGordon Ross * name we're ever asked to resume on is the same as the
482bfbce3c1SGordon Ross * most recent we returned. That's always what the client
483bfbce3c1SGordon Ross * gives us as the resume name, so we can simply remember
484bfbce3c1SGordon Ross * the last name/offset pair and use that to position on
485bfbce3c1SGordon Ross * the following FindNext call. In the unlikely event
486bfbce3c1SGordon Ross * that the client asks to resume somewhere else, we'll
487bfbce3c1SGordon Ross * use the numeric resume key, and hope the client gives
488bfbce3c1SGordon Ross * correctly uses one of the resume keys we provided.
489bfbce3c1SGordon Ross */
490bfbce3c1SGordon Ross if (args.fa_fflag & SMB_FIND_CONTINUE_FROM_LAST) {
491bfbce3c1SGordon Ross odir_resume.or_type = SMB_ODIR_RESUME_CONT;
492bfbce3c1SGordon Ross } else {
493bfbce3c1SGordon Ross odir_resume.or_type = SMB_ODIR_RESUME_FNAME;
494bfbce3c1SGordon Ross }
4957f667e74Sjose borrego smb_odir_resume_at(od, &odir_resume);
496da6c28aaSamw
497bfbce3c1SGordon Ross count = smb_trans2_find_entries(sr, xa, od, &args);
4987f667e74Sjose borrego if (count == -1) {
4997f667e74Sjose borrego smb_odir_close(od);
500a1511e6bSjoyce mcintosh smb_odir_release(od);
501faa1795aSjb return (SDRC_ERROR);
502da6c28aaSamw }
503da6c28aaSamw
5047f667e74Sjose borrego if ((args.fa_fflag & SMB_FIND_CLOSE_AFTER_REQUEST) ||
505bfbce3c1SGordon Ross (args.fa_eos && (args.fa_fflag & SMB_FIND_CLOSE_AT_EOS))) {
5067f667e74Sjose borrego smb_odir_close(od);
5077f667e74Sjose borrego } /* else leave odir open for trans2_find_next2 */
5087f667e74Sjose borrego
509a1511e6bSjoyce mcintosh smb_odir_release(od);
510bfbce3c1SGordon Ross
5117f667e74Sjose borrego (void) smb_mbc_encodef(&xa->rep_param_mb, "wwww",
512bfbce3c1SGordon Ross count, /* Search Count */
513bfbce3c1SGordon Ross args.fa_eos, /* End Of Search */
514bfbce3c1SGordon Ross 0, /* EA Error Offset */
515bfbce3c1SGordon Ross args.fa_lno); /* Last Name Offset */
5167f667e74Sjose borrego
5177f667e74Sjose borrego return (SDRC_SUCCESS);
5187f667e74Sjose borrego }
5197f667e74Sjose borrego
5207f667e74Sjose borrego
5217f667e74Sjose borrego /*
5227f667e74Sjose borrego * smb_trans2_find_entries
5237f667e74Sjose borrego *
5247f667e74Sjose borrego * Find and encode up to args->fa_maxcount directory entries.
5257f667e74Sjose borrego * For compatibilty with Windows, if args->fa_maxcount is zero treat it as 1.
5267f667e74Sjose borrego *
5277f667e74Sjose borrego * Returns:
5287f667e74Sjose borrego * count - count of entries encoded
5297f667e74Sjose borrego * *eos = B_TRUE if no more directory entries
5307f667e74Sjose borrego * -1 - error
5317f667e74Sjose borrego */
5327f667e74Sjose borrego static int
smb_trans2_find_entries(smb_request_t * sr,smb_xa_t * xa,smb_odir_t * od,smb_find_args_t * args)5337f667e74Sjose borrego smb_trans2_find_entries(smb_request_t *sr, smb_xa_t *xa, smb_odir_t *od,
534bfbce3c1SGordon Ross smb_find_args_t *args)
5357f667e74Sjose borrego {
5367f667e74Sjose borrego smb_fileinfo_t fileinfo;
537bfbce3c1SGordon Ross smb_odir_resume_t odir_resume;
538b819cea2SGordon Ross uint16_t count, maxcount;
539b819cea2SGordon Ross int rc = -1;
54007a6ae61SGordon Ross int LastEntryOffset = 0;
541a90cf9f2SGordon Ross boolean_t need_rewind = B_FALSE;
5427f667e74Sjose borrego
5433bd40d98SGordon Ross /*
5443bd40d98SGordon Ross * EAs are not current supported, so a search for level
5453bd40d98SGordon Ross * SMB_INFO_QUERY_EAS_FROM_LIST should always return an
5463bd40d98SGordon Ross * empty list. Returning zero for this case gives the
5473bd40d98SGordon Ross * client an empty response, which is better than an
5483bd40d98SGordon Ross * NT_STATUS_INVALID_LEVEL return (and test failures).
5493bd40d98SGordon Ross *
5503bd40d98SGordon Ross * If and when we do support EAs, this level will modify
5513bd40d98SGordon Ross * the search here, and then return results just like
5523bd40d98SGordon Ross * SMB_INFO_QUERY_EA_SIZE, but only including files
5533bd40d98SGordon Ross * that have an EA in the provided list.
5543bd40d98SGordon Ross */
5553bd40d98SGordon Ross if (args->fa_infolev == SMB_INFO_QUERY_EAS_FROM_LIST)
5563bd40d98SGordon Ross return (0);
5573bd40d98SGordon Ross
5587f667e74Sjose borrego if ((maxcount = args->fa_maxcount) == 0)
559dc20a302Sas maxcount = 1;
560dc20a302Sas
561dc20a302Sas if ((smb_trans2_find_max != 0) && (maxcount > smb_trans2_find_max))
562dc20a302Sas maxcount = smb_trans2_find_max;
563dc20a302Sas
5647f667e74Sjose borrego count = 0;
5657f667e74Sjose borrego while (count < maxcount) {
566a90cf9f2SGordon Ross rc = smb_odir_read_fileinfo(sr, od, &fileinfo, &args->fa_eos);
567a90cf9f2SGordon Ross if (rc != 0 || args->fa_eos != 0)
5687f667e74Sjose borrego break;
569da6c28aaSamw
57007a6ae61SGordon Ross LastEntryOffset = xa->rep_data_mb.chain_offset;
5717f667e74Sjose borrego rc = smb_trans2_find_mbc_encode(sr, xa, &fileinfo, args);
5727f667e74Sjose borrego if (rc == -1)
573a90cf9f2SGordon Ross return (-1); /* fatal encoding error */
574a90cf9f2SGordon Ross if (rc == 1) {
575a90cf9f2SGordon Ross need_rewind = B_TRUE;
576a90cf9f2SGordon Ross break; /* output space exhausted */
577a90cf9f2SGordon Ross }
578da6c28aaSamw
579bfbce3c1SGordon Ross /*
580bfbce3c1SGordon Ross * Save the info about the last file returned.
581bfbce3c1SGordon Ross */
582bfbce3c1SGordon Ross args->fa_lastkey = fileinfo.fi_cookie;
583bfbce3c1SGordon Ross bcopy(fileinfo.fi_name, args->fa_lastname, MAXNAMELEN);
584bfbce3c1SGordon Ross
5857f667e74Sjose borrego ++count;
586da6c28aaSamw }
587a90cf9f2SGordon Ross if (args->fa_eos != 0 && rc == ENOENT)
588a90cf9f2SGordon Ross rc = 0;
589da6c28aaSamw
59007a6ae61SGordon Ross /*
59107a6ae61SGordon Ross * All but the ancient info levels start with NextEntryOffset.
59207a6ae61SGordon Ross * That's supposed to be zero in the last entry returned.
59307a6ae61SGordon Ross */
59407a6ae61SGordon Ross if (args->fa_infolev >= SMB_FIND_FILE_DIRECTORY_INFO) {
59507a6ae61SGordon Ross (void) smb_mbc_poke(&xa->rep_data_mb,
59607a6ae61SGordon Ross LastEntryOffset, "l", 0);
59707a6ae61SGordon Ross }
59807a6ae61SGordon Ross
5997f667e74Sjose borrego /* save the last cookie returned to client */
6007f667e74Sjose borrego if (count != 0)
601bfbce3c1SGordon Ross smb_odir_save_fname(od, args->fa_lastkey, args->fa_lastname);
602da6c28aaSamw
6031fcced4cSJordan Brown /*
6041fcced4cSJordan Brown * If all retrieved entries have been successfully encoded
6051fcced4cSJordan Brown * and eos has not already been detected, check if there are
6061fcced4cSJordan Brown * any more entries. eos will be set if there are no more.
6071fcced4cSJordan Brown */
608a90cf9f2SGordon Ross if ((rc == 0) && (args->fa_eos == 0)) {
609a90cf9f2SGordon Ross rc = smb_odir_read_fileinfo(sr, od, &fileinfo, &args->fa_eos);
610a90cf9f2SGordon Ross /*
611a90cf9f2SGordon Ross * If rc == ENOENT, we did not read any additional data.
612a90cf9f2SGordon Ross * if rc != 0, there's no need to rewind.
613a90cf9f2SGordon Ross */
614a90cf9f2SGordon Ross if (rc == 0)
615a90cf9f2SGordon Ross need_rewind = B_TRUE;
616a90cf9f2SGordon Ross }
617bfbce3c1SGordon Ross
618bfbce3c1SGordon Ross /*
619bfbce3c1SGordon Ross * When the last entry we read from the directory did not
620bfbce3c1SGordon Ross * fit in the return buffer, we will have read one entry
621bfbce3c1SGordon Ross * that will not be returned in this call. That, and the
622bfbce3c1SGordon Ross * check for EOS just above both can leave the directory
623bfbce3c1SGordon Ross * position incorrect for the next call. Fix that now.
624bfbce3c1SGordon Ross */
625a90cf9f2SGordon Ross if (need_rewind) {
626a90cf9f2SGordon Ross bzero(&odir_resume, sizeof (odir_resume));
627a90cf9f2SGordon Ross odir_resume.or_type = SMB_ODIR_RESUME_COOKIE;
628a90cf9f2SGordon Ross odir_resume.or_cookie = args->fa_lastkey;
629a90cf9f2SGordon Ross smb_odir_resume_at(od, &odir_resume);
630a90cf9f2SGordon Ross }
631da6c28aaSamw
6327f667e74Sjose borrego return (count);
633da6c28aaSamw }
634da6c28aaSamw
635da6c28aaSamw /*
63607a6ae61SGordon Ross * smb_trans2_find_get_fixedsize
637da6c28aaSamw *
63807a6ae61SGordon Ross * Calculate the sizeof the fixed part of the response for the
63907a6ae61SGordon Ross * specified information level.
640da6c28aaSamw *
64107a6ae61SGordon Ross * A non-zero return value provides the fixed size.
642dc20a302Sas * A return value of zero indicates an unknown information level.
643da6c28aaSamw */
644dc20a302Sas static int
smb_trans2_find_get_fixedsize(smb_request_t * sr,uint16_t infolev,uint16_t fflag)64507a6ae61SGordon Ross smb_trans2_find_get_fixedsize(smb_request_t *sr, uint16_t infolev,
64607a6ae61SGordon Ross uint16_t fflag)
647da6c28aaSamw {
64807a6ae61SGordon Ross int maxdata = 0;
649da6c28aaSamw
650da6c28aaSamw switch (infolev) {
651da6c28aaSamw case SMB_INFO_STANDARD :
652da6c28aaSamw if (fflag & SMB_FIND_RETURN_RESUME_KEYS)
653da6c28aaSamw maxdata += sizeof (int32_t);
654da6c28aaSamw maxdata += 2 + 2 + 2 + 4 + 4 + 2 + 1;
655da6c28aaSamw break;
656da6c28aaSamw
657da6c28aaSamw case SMB_INFO_QUERY_EA_SIZE:
6583bd40d98SGordon Ross case SMB_INFO_QUERY_EAS_FROM_LIST:
659da6c28aaSamw if (fflag & SMB_FIND_RETURN_RESUME_KEYS)
660da6c28aaSamw maxdata += sizeof (int32_t);
661da6c28aaSamw maxdata += 2 + 2 + 2 + 4 + 4 + 2 + 4 + 1;
662da6c28aaSamw break;
663da6c28aaSamw
664da6c28aaSamw case SMB_FIND_FILE_DIRECTORY_INFO:
665da6c28aaSamw maxdata += 4 + 4 + 8 + 8 + 8 + 8 + 8 + 8 + 4 + 4;
666da6c28aaSamw break;
667da6c28aaSamw
668b89a8333Snatalie li - Sun Microsystems - Irvine United States case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
669b89a8333Snatalie li - Sun Microsystems - Irvine United States maxdata += 4 + 4 + 8 + 8 + 8 + 8 + 8 + 8 + 4 + 4 + 4;
670b89a8333Snatalie li - Sun Microsystems - Irvine United States break;
671b89a8333Snatalie li - Sun Microsystems - Irvine United States
672b89a8333Snatalie li - Sun Microsystems - Irvine United States case SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO:
673b89a8333Snatalie li - Sun Microsystems - Irvine United States maxdata += 4 + 4 + 8 + 8 + 8 + 8 + 8 + 8 + 4 + 4 + 4 + 4 + 8;
674b89a8333Snatalie li - Sun Microsystems - Irvine United States break;
675b89a8333Snatalie li - Sun Microsystems - Irvine United States
676da6c28aaSamw case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
677da6c28aaSamw maxdata += 4 + 4 + 8 + 8 + 8 + 8 + 8 + 8 + 4 + 4 + 4 + 2 + 24;
678da6c28aaSamw break;
679da6c28aaSamw
680b89a8333Snatalie li - Sun Microsystems - Irvine United States case SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO:
681b89a8333Snatalie li - Sun Microsystems - Irvine United States maxdata += 4 + 4 + 8 + 8 + 8 + 8 + 8 + 8 + 4 + 4 + 4 + 2 + 24
682b89a8333Snatalie li - Sun Microsystems - Irvine United States + 2 + 8;
683b89a8333Snatalie li - Sun Microsystems - Irvine United States break;
684b89a8333Snatalie li - Sun Microsystems - Irvine United States
685da6c28aaSamw case SMB_FIND_FILE_NAMES_INFO:
686da6c28aaSamw maxdata += 4 + 4 + 4;
687da6c28aaSamw break;
688da6c28aaSamw
689da6c28aaSamw case SMB_MAC_FIND_BOTH_HFS_INFO:
690da6c28aaSamw maxdata += 4 + 4 + 8 + 8 + 8 + 8 + 8 + 8 + 8 + 4 + 1 + 1 + 2 +
691da6c28aaSamw 4 + 32 + 4 + 1 + 1 + 24 + 4;
692da6c28aaSamw break;
693da6c28aaSamw
694da6c28aaSamw default:
695da6c28aaSamw maxdata = 0;
6967f667e74Sjose borrego smbsr_error(sr, NT_STATUS_INVALID_LEVEL,
6977f667e74Sjose borrego ERRDOS, ERROR_INVALID_LEVEL);
698da6c28aaSamw }
699da6c28aaSamw
700da6c28aaSamw return (maxdata);
701da6c28aaSamw }
702da6c28aaSamw
703bfbce3c1SGordon Ross /*
704bfbce3c1SGordon Ross * This is an experimental feature that allows us to return zero
705bfbce3c1SGordon Ross * for all numeric resume keys, to match Windows behavior with an
706bfbce3c1SGordon Ross * NTFS share. Setting this variable to zero does that.
707bfbce3c1SGordon Ross *
708bfbce3c1SGordon Ross * It's possible we could remove this variable and always set
709bfbce3c1SGordon Ross * numeric resume keys to zero, but that would leave us unable
710bfbce3c1SGordon Ross * to handle a FindNext call with an arbitrary start position.
711bfbce3c1SGordon Ross * In practice we never see these, but in theory we could.
712bfbce3c1SGordon Ross *
713bfbce3c1SGordon Ross * See the long comment above smb_com_trans2_find_next2() for
714bfbce3c1SGordon Ross * more details about resume key / resume name handling.
715bfbce3c1SGordon Ross */
716bfbce3c1SGordon Ross int smbd_use_resume_keys = 1;
717bfbce3c1SGordon Ross
718da6c28aaSamw /*
7197f667e74Sjose borrego * smb_trans2_mbc_encode
720da6c28aaSamw *
721da6c28aaSamw * This function encodes the mbc for one directory entry.
722da6c28aaSamw *
723da6c28aaSamw * The function returns -1 when the max data requested by client
724da6c28aaSamw * is reached. If the entry is valid and successful encoded, 0
725da6c28aaSamw * will be returned; otherwise, 1 will be returned.
726b89a8333Snatalie li - Sun Microsystems - Irvine United States *
727b89a8333Snatalie li - Sun Microsystems - Irvine United States * We always null terminate the filename. The space for the null
728b89a8333Snatalie li - Sun Microsystems - Irvine United States * is included in the maxdata calculation and is therefore included
729b89a8333Snatalie li - Sun Microsystems - Irvine United States * in the next_entry_offset. namelen is the unterminated length of
730b89a8333Snatalie li - Sun Microsystems - Irvine United States * the filename. For levels except STANDARD and EA_SIZE, if the
731b89a8333Snatalie li - Sun Microsystems - Irvine United States * filename is ascii the name length returned to the client should
732b89a8333Snatalie li - Sun Microsystems - Irvine United States * include the null terminator. Otherwise the length returned to
733b89a8333Snatalie li - Sun Microsystems - Irvine United States * the client should not include the terminator.
7347f667e74Sjose borrego *
7357f667e74Sjose borrego * Returns: 0 - data successfully encoded
7367f667e74Sjose borrego * 1 - client request's maxdata limit reached
7377f667e74Sjose borrego * -1 - error
738da6c28aaSamw */
7397f667e74Sjose borrego static int
smb_trans2_find_mbc_encode(smb_request_t * sr,smb_xa_t * xa,smb_fileinfo_t * fileinfo,smb_find_args_t * args)7407f667e74Sjose borrego smb_trans2_find_mbc_encode(smb_request_t *sr, smb_xa_t *xa,
7417f667e74Sjose borrego smb_fileinfo_t *fileinfo, smb_find_args_t *args)
742da6c28aaSamw {
743bfbce3c1SGordon Ross int namelen, shortlen;
7447f667e74Sjose borrego uint32_t next_entry_offset;
7457f667e74Sjose borrego uint32_t dsize32, asize32;
7467f667e74Sjose borrego uint32_t mb_flags = 0;
747bfbce3c1SGordon Ross uint32_t resume_key;
7487f667e74Sjose borrego char buf83[26];
7497f667e74Sjose borrego smb_msgbuf_t mb;
75007a6ae61SGordon Ross int pad = 0;
7517f667e74Sjose borrego
7527f667e74Sjose borrego namelen = smb_ascii_or_unicode_strlen(sr, fileinfo->fi_name);
753b89a8333Snatalie li - Sun Microsystems - Irvine United States if (namelen == -1)
7547f667e74Sjose borrego return (-1);
755da6c28aaSamw
75607a6ae61SGordon Ross if (args->fa_infolev < SMB_FIND_FILE_DIRECTORY_INFO) {
75707a6ae61SGordon Ross /*
75807a6ae61SGordon Ross * Ancient info levels don't have a NextEntryOffset
75907a6ae61SGordon Ross * field, so there's no padding for alignment.
76007a6ae61SGordon Ross * The client expects a null after the file name,
76107a6ae61SGordon Ross * and then the next entry. The namelength field
76207a6ae61SGordon Ross * never includes the null for these old levels.
76307a6ae61SGordon Ross * Using the pad value to write the null because
76407a6ae61SGordon Ross * we don't want to add that to namelen.
76507a6ae61SGordon Ross * [MS-CIFS] sec. 2.8.1.{1-3}
76607a6ae61SGordon Ross */
76707a6ae61SGordon Ross if ((sr->smb_flg2 & SMB_FLAGS2_UNICODE) != 0)
76807a6ae61SGordon Ross pad = 2; /* Unicode null */
76907a6ae61SGordon Ross else
77007a6ae61SGordon Ross pad = 1; /* ascii null */
77107a6ae61SGordon Ross next_entry_offset = args->fa_fixedsize + namelen + pad;
77207a6ae61SGordon Ross if (!MBC_ROOM_FOR(&xa->rep_data_mb, next_entry_offset))
77307a6ae61SGordon Ross return (1);
77407a6ae61SGordon Ross } else {
77507a6ae61SGordon Ross /*
77607a6ae61SGordon Ross * Later info levels: The file name is written WITH
77707a6ae61SGordon Ross * null termination, and the size of that null _is_
77807a6ae61SGordon Ross * included in the namelen field. There may also
77907a6ae61SGordon Ross * be padding, and we pad to align(4) like Windows.
78007a6ae61SGordon Ross * Don't include the padding in the "room for" test
78107a6ae61SGordon Ross * because we want to ignore any error writing the
78207a6ae61SGordon Ross * pad bytes after the last element.
78307a6ae61SGordon Ross */
78407a6ae61SGordon Ross if ((sr->smb_flg2 & SMB_FLAGS2_UNICODE) != 0)
78507a6ae61SGordon Ross namelen += 2;
78607a6ae61SGordon Ross else
787b89a8333Snatalie li - Sun Microsystems - Irvine United States namelen += 1;
78807a6ae61SGordon Ross next_entry_offset = args->fa_fixedsize + namelen;
78907a6ae61SGordon Ross if (!MBC_ROOM_FOR(&xa->rep_data_mb, next_entry_offset))
79007a6ae61SGordon Ross return (1);
79107a6ae61SGordon Ross if ((next_entry_offset & 3) != 0) {
79207a6ae61SGordon Ross pad = 4 - (next_entry_offset & 3);
79307a6ae61SGordon Ross next_entry_offset += pad;
79407a6ae61SGordon Ross }
795b89a8333Snatalie li - Sun Microsystems - Irvine United States }
796b89a8333Snatalie li - Sun Microsystems - Irvine United States
7977f667e74Sjose borrego mb_flags = (sr->smb_flg2 & SMB_FLAGS2_UNICODE) ? SMB_MSGBUF_UNICODE : 0;
7987f667e74Sjose borrego dsize32 = (fileinfo->fi_size > UINT_MAX) ?
7997f667e74Sjose borrego UINT_MAX : (uint32_t)fileinfo->fi_size;
8007f667e74Sjose borrego asize32 = (fileinfo->fi_alloc_size > UINT_MAX) ?
8017f667e74Sjose borrego UINT_MAX : (uint32_t)fileinfo->fi_alloc_size;
8026537f381Sas
803bfbce3c1SGordon Ross resume_key = fileinfo->fi_cookie;
804bfbce3c1SGordon Ross if (smbd_use_resume_keys == 0)
805bfbce3c1SGordon Ross resume_key = 0;
806bfbce3c1SGordon Ross
807bfbce3c1SGordon Ross /*
808bfbce3c1SGordon Ross * This switch handles all the "information levels" (formats)
809bfbce3c1SGordon Ross * that we support. Note that all formats have the file name
810bfbce3c1SGordon Ross * placed after some fixed-size data, and the code to write
811bfbce3c1SGordon Ross * the file name is factored out at the end of this switch.
812bfbce3c1SGordon Ross */
8137f667e74Sjose borrego switch (args->fa_infolev) {
814da6c28aaSamw case SMB_INFO_STANDARD:
8157f667e74Sjose borrego if (args->fa_fflag & SMB_FIND_RETURN_RESUME_KEYS)
8163db3f65cSamw (void) smb_mbc_encodef(&xa->rep_data_mb, "l",
817bfbce3c1SGordon Ross resume_key);
818da6c28aaSamw
819bfbce3c1SGordon Ross (void) smb_mbc_encodef(&xa->rep_data_mb, "%yyyllwb", sr,
820e3f2c991SKeyur Desai smb_time_gmt_to_local(sr, fileinfo->fi_crtime.tv_sec),
821e3f2c991SKeyur Desai smb_time_gmt_to_local(sr, fileinfo->fi_atime.tv_sec),
822e3f2c991SKeyur Desai smb_time_gmt_to_local(sr, fileinfo->fi_mtime.tv_sec),
8236537f381Sas dsize32,
8246537f381Sas asize32,
8257f667e74Sjose borrego fileinfo->fi_dosattr,
826bfbce3c1SGordon Ross namelen);
827da6c28aaSamw break;
828da6c28aaSamw
829da6c28aaSamw case SMB_INFO_QUERY_EA_SIZE:
8303bd40d98SGordon Ross case SMB_INFO_QUERY_EAS_FROM_LIST:
8317f667e74Sjose borrego if (args->fa_fflag & SMB_FIND_RETURN_RESUME_KEYS)
8323db3f65cSamw (void) smb_mbc_encodef(&xa->rep_data_mb, "l",
833bfbce3c1SGordon Ross resume_key);
834da6c28aaSamw
835bfbce3c1SGordon Ross (void) smb_mbc_encodef(&xa->rep_data_mb, "%yyyllwlb", sr,
836e3f2c991SKeyur Desai smb_time_gmt_to_local(sr, fileinfo->fi_crtime.tv_sec),
837e3f2c991SKeyur Desai smb_time_gmt_to_local(sr, fileinfo->fi_atime.tv_sec),
838e3f2c991SKeyur Desai smb_time_gmt_to_local(sr, fileinfo->fi_mtime.tv_sec),
8396537f381Sas dsize32,
8406537f381Sas asize32,
8417f667e74Sjose borrego fileinfo->fi_dosattr,
842da6c28aaSamw 0L, /* EA Size */
843bfbce3c1SGordon Ross namelen);
844da6c28aaSamw break;
845da6c28aaSamw
846da6c28aaSamw case SMB_FIND_FILE_DIRECTORY_INFO:
847bfbce3c1SGordon Ross (void) smb_mbc_encodef(&xa->rep_data_mb, "%llTTTTqqll", sr,
848dc20a302Sas next_entry_offset,
849bfbce3c1SGordon Ross resume_key,
8507f667e74Sjose borrego &fileinfo->fi_crtime,
8517f667e74Sjose borrego &fileinfo->fi_atime,
8527f667e74Sjose borrego &fileinfo->fi_mtime,
8537f667e74Sjose borrego &fileinfo->fi_ctime,
8547f667e74Sjose borrego fileinfo->fi_size,
8557f667e74Sjose borrego fileinfo->fi_alloc_size,
8567f667e74Sjose borrego fileinfo->fi_dosattr,
857bfbce3c1SGordon Ross namelen);
858b89a8333Snatalie li - Sun Microsystems - Irvine United States break;
859b89a8333Snatalie li - Sun Microsystems - Irvine United States
860b89a8333Snatalie li - Sun Microsystems - Irvine United States case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
861bfbce3c1SGordon Ross (void) smb_mbc_encodef(&xa->rep_data_mb, "%llTTTTqqlll", sr,
862b89a8333Snatalie li - Sun Microsystems - Irvine United States next_entry_offset,
863bfbce3c1SGordon Ross resume_key,
8647f667e74Sjose borrego &fileinfo->fi_crtime,
8657f667e74Sjose borrego &fileinfo->fi_atime,
8667f667e74Sjose borrego &fileinfo->fi_mtime,
8677f667e74Sjose borrego &fileinfo->fi_ctime,
8687f667e74Sjose borrego fileinfo->fi_size,
8697f667e74Sjose borrego fileinfo->fi_alloc_size,
8707f667e74Sjose borrego fileinfo->fi_dosattr,
871b89a8333Snatalie li - Sun Microsystems - Irvine United States namelen,
872bfbce3c1SGordon Ross 0L);
873b89a8333Snatalie li - Sun Microsystems - Irvine United States break;
874b89a8333Snatalie li - Sun Microsystems - Irvine United States
875b89a8333Snatalie li - Sun Microsystems - Irvine United States case SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO:
876bfbce3c1SGordon Ross (void) smb_mbc_encodef(&xa->rep_data_mb, "%llTTTTqqlll4.q", sr,
877b89a8333Snatalie li - Sun Microsystems - Irvine United States next_entry_offset,
878bfbce3c1SGordon Ross resume_key,
8797f667e74Sjose borrego &fileinfo->fi_crtime,
8807f667e74Sjose borrego &fileinfo->fi_atime,
8817f667e74Sjose borrego &fileinfo->fi_mtime,
8827f667e74Sjose borrego &fileinfo->fi_ctime,
8837f667e74Sjose borrego fileinfo->fi_size,
8847f667e74Sjose borrego fileinfo->fi_alloc_size,
8857f667e74Sjose borrego fileinfo->fi_dosattr,
886b89a8333Snatalie li - Sun Microsystems - Irvine United States namelen,
887b89a8333Snatalie li - Sun Microsystems - Irvine United States 0L,
888bfbce3c1SGordon Ross fileinfo->fi_nodeid);
889da6c28aaSamw break;
890da6c28aaSamw
891da6c28aaSamw case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
892b89a8333Snatalie li - Sun Microsystems - Irvine United States bzero(buf83, sizeof (buf83));
893b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_msgbuf_init(&mb, (uint8_t *)buf83, sizeof (buf83),
894b89a8333Snatalie li - Sun Microsystems - Irvine United States mb_flags);
8957f667e74Sjose borrego if (smb_msgbuf_encode(&mb, "U", fileinfo->fi_shortname) < 0) {
896b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_msgbuf_term(&mb);
897b89a8333Snatalie li - Sun Microsystems - Irvine United States return (-1);
898b89a8333Snatalie li - Sun Microsystems - Irvine United States }
899bbf6f00cSJordan Brown shortlen = smb_wcequiv_strlen(fileinfo->fi_shortname);
900b89a8333Snatalie li - Sun Microsystems - Irvine United States
901bfbce3c1SGordon Ross (void) smb_mbc_encodef(&xa->rep_data_mb, "%llTTTTqqlllb.24c",
902b89a8333Snatalie li - Sun Microsystems - Irvine United States sr,
903b89a8333Snatalie li - Sun Microsystems - Irvine United States next_entry_offset,
904bfbce3c1SGordon Ross resume_key,
9057f667e74Sjose borrego &fileinfo->fi_crtime,
9067f667e74Sjose borrego &fileinfo->fi_atime,
9077f667e74Sjose borrego &fileinfo->fi_mtime,
9087f667e74Sjose borrego &fileinfo->fi_ctime,
9097f667e74Sjose borrego fileinfo->fi_size,
9107f667e74Sjose borrego fileinfo->fi_alloc_size,
9117f667e74Sjose borrego fileinfo->fi_dosattr,
912b89a8333Snatalie li - Sun Microsystems - Irvine United States namelen,
913b89a8333Snatalie li - Sun Microsystems - Irvine United States 0L,
914b89a8333Snatalie li - Sun Microsystems - Irvine United States shortlen,
915bfbce3c1SGordon Ross buf83);
916b89a8333Snatalie li - Sun Microsystems - Irvine United States
917b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_msgbuf_term(&mb);
918b89a8333Snatalie li - Sun Microsystems - Irvine United States break;
919b89a8333Snatalie li - Sun Microsystems - Irvine United States
920b89a8333Snatalie li - Sun Microsystems - Irvine United States case SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO:
921da6c28aaSamw bzero(buf83, sizeof (buf83));
922dc20a302Sas smb_msgbuf_init(&mb, (uint8_t *)buf83, sizeof (buf83),
923da6c28aaSamw mb_flags);
9247f667e74Sjose borrego if (smb_msgbuf_encode(&mb, "u", fileinfo->fi_shortname) < 0) {
925da6c28aaSamw smb_msgbuf_term(&mb);
926da6c28aaSamw return (-1);
927da6c28aaSamw }
9287f667e74Sjose borrego shortlen = smb_ascii_or_unicode_strlen(sr,
9297f667e74Sjose borrego fileinfo->fi_shortname);
930da6c28aaSamw
931b89a8333Snatalie li - Sun Microsystems - Irvine United States (void) smb_mbc_encodef(&xa->rep_data_mb,
932bfbce3c1SGordon Ross "%llTTTTqqlllb.24c2.q",
933dc20a302Sas sr,
934dc20a302Sas next_entry_offset,
935bfbce3c1SGordon Ross resume_key,
9367f667e74Sjose borrego &fileinfo->fi_crtime,
9377f667e74Sjose borrego &fileinfo->fi_atime,
9387f667e74Sjose borrego &fileinfo->fi_mtime,
9397f667e74Sjose borrego &fileinfo->fi_ctime,
9407f667e74Sjose borrego fileinfo->fi_size,
9417f667e74Sjose borrego fileinfo->fi_alloc_size,
9427f667e74Sjose borrego fileinfo->fi_dosattr,
943b89a8333Snatalie li - Sun Microsystems - Irvine United States namelen,
944da6c28aaSamw 0L,
945dc20a302Sas shortlen,
946da6c28aaSamw buf83,
947bfbce3c1SGordon Ross fileinfo->fi_nodeid);
948da6c28aaSamw
949da6c28aaSamw smb_msgbuf_term(&mb);
950da6c28aaSamw break;
951da6c28aaSamw
952da6c28aaSamw case SMB_FIND_FILE_NAMES_INFO:
953bfbce3c1SGordon Ross (void) smb_mbc_encodef(&xa->rep_data_mb, "%lll", sr,
954dc20a302Sas next_entry_offset,
955bfbce3c1SGordon Ross resume_key,
956bfbce3c1SGordon Ross namelen);
957da6c28aaSamw break;
958bfbce3c1SGordon Ross
959bfbce3c1SGordon Ross default:
960bfbce3c1SGordon Ross /* invalid info. level */
961bfbce3c1SGordon Ross return (-1);
962da6c28aaSamw }
963da6c28aaSamw
964bfbce3c1SGordon Ross /*
965bfbce3c1SGordon Ross * At this point we have written all the fixed-size data
966bfbce3c1SGordon Ross * for the specified info. level, and we're about to put
967bfbce3c1SGordon Ross * the file name string in the message. We may later
968bfbce3c1SGordon Ross * need the offset in the trans2 data where this string
969bfbce3c1SGordon Ross * is placed, so save the message position now. Note:
970bfbce3c1SGordon Ross * We also need to account for the alignment padding
971bfbce3c1SGordon Ross * that may precede the unicode string.
972bfbce3c1SGordon Ross */
973bfbce3c1SGordon Ross args->fa_lno = xa->rep_data_mb.chain_offset;
974bfbce3c1SGordon Ross if ((sr->smb_flg2 & SMB_FLAGS2_UNICODE) != 0 &&
975bfbce3c1SGordon Ross (args->fa_lno & 1) != 0)
976bfbce3c1SGordon Ross args->fa_lno++;
977bfbce3c1SGordon Ross
97807a6ae61SGordon Ross (void) smb_mbc_encodef(&xa->rep_data_mb, "%#u", sr,
97907a6ae61SGordon Ross namelen, fileinfo->fi_name);
98007a6ae61SGordon Ross
98107a6ae61SGordon Ross if (pad)
98207a6ae61SGordon Ross (void) smb_mbc_encodef(&xa->rep_data_mb, "#.", pad);
983bfbce3c1SGordon Ross
984da6c28aaSamw return (0);
985da6c28aaSamw }
986da6c28aaSamw
987da6c28aaSamw /*
988da6c28aaSamw * Close a search started by a Trans2FindFirst2 request.
989da6c28aaSamw */
9907b59d02dSjb smb_sdrc_t
smb_pre_find_close2(smb_request_t * sr)991faa1795aSjb smb_pre_find_close2(smb_request_t *sr)
992faa1795aSjb {
99393bc28dbSGordon Ross DTRACE_SMB_START(op__FindClose2, smb_request_t *, sr);
9947f667e74Sjose borrego return (SDRC_SUCCESS);
995faa1795aSjb }
996faa1795aSjb
997faa1795aSjb void
smb_post_find_close2(smb_request_t * sr)998faa1795aSjb smb_post_find_close2(smb_request_t *sr)
999da6c28aaSamw {
100093bc28dbSGordon Ross DTRACE_SMB_DONE(op__FindClose2, smb_request_t *, sr);
1001faa1795aSjb }
1002da6c28aaSamw
1003faa1795aSjb smb_sdrc_t
smb_com_find_close2(smb_request_t * sr)1004faa1795aSjb smb_com_find_close2(smb_request_t *sr)
1005faa1795aSjb {
10067f667e74Sjose borrego uint16_t odid;
10077f667e74Sjose borrego smb_odir_t *od;
10087f667e74Sjose borrego
10097f667e74Sjose borrego if (smbsr_decode_vwv(sr, "w", &odid) != 0)
10107f667e74Sjose borrego return (SDRC_ERROR);
10117f667e74Sjose borrego
10123b13a1efSThomas Keiser od = smb_tree_lookup_odir(sr, odid);
10137f667e74Sjose borrego if (od == NULL) {
10147f667e74Sjose borrego smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
10157f667e74Sjose borrego ERRDOS, ERROR_INVALID_HANDLE);
1016faa1795aSjb return (SDRC_ERROR);
1017da6c28aaSamw }
1018da6c28aaSamw
10197f667e74Sjose borrego smb_odir_close(od);
10207f667e74Sjose borrego smb_odir_release(od);
10217b59d02dSjb
10227b59d02dSjb if (smbsr_encode_empty_result(sr))
1023faa1795aSjb return (SDRC_ERROR);
10247b59d02dSjb
1025faa1795aSjb return (SDRC_SUCCESS);
1026da6c28aaSamw }
1027