xref: /onnv-gate/usr/src/uts/common/fs/smbsrv/smb_trans2_find.c (revision 11963:061945695ce1)
15331Samw /*
25331Samw  * CDDL HEADER START
35331Samw  *
45331Samw  * The contents of this file are subject to the terms of the
55331Samw  * Common Development and Distribution License (the "License").
65331Samw  * You may not use this file except in compliance with the License.
75331Samw  *
85331Samw  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95331Samw  * or http://www.opensolaris.org/os/licensing.
105331Samw  * See the License for the specific language governing permissions
115331Samw  * and limitations under the License.
125331Samw  *
135331Samw  * When distributing Covered Code, include this CDDL HEADER in each
145331Samw  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155331Samw  * If applicable, add the following below this CDDL HEADER, with the
165331Samw  * fields enclosed by brackets "[]" replaced with your own identifying
175331Samw  * information: Portions Copyright [yyyy] [name of copyright owner]
185331Samw  *
195331Samw  * CDDL HEADER END
205331Samw  */
215331Samw /*
22*11963SAfshin.Ardakani@Sun.COM  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
235331Samw  * Use is subject to license terms.
245331Samw  */
255331Samw 
265331Samw 
275331Samw /*
285331Samw  * This module provides functions for TRANS2_FIND_FIRST2 and
295331Samw  * TRANS2_FIND_NEXT2 requests. The requests allow the client to search
305331Samw  * for the file(s) which match the file specification.  The search is
315331Samw  * started with TRANS2_FIND_FIRST2 and can be continued if necessary with
325331Samw  * TRANS2_FIND_NEXT2. There are numerous levels of information which may be
335331Samw  * obtained for the returned files, the desired level is specified in the
345331Samw  * InformationLevel field of the requests.
355331Samw  *
365331Samw  *  InformationLevel Name              Value
375331Samw  *  =================================  ================
385331Samw  *
395331Samw  *  SMB_INFO_STANDARD                  1
405331Samw  *  SMB_INFO_QUERY_EA_SIZE             2
415331Samw  *  SMB_INFO_QUERY_EAS_FROM_LIST       3
425331Samw  *  SMB_FIND_FILE_DIRECTORY_INFO       0x101
435331Samw  *  SMB_FIND_FILE_FULL_DIRECTORY_INFO  0x102
445331Samw  *  SMB_FIND_FILE_NAMES_INFO           0x103
455331Samw  *  SMB_FIND_FILE_BOTH_DIRECTORY_INFO  0x104
467961SNatalie.Li@Sun.COM  *  SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO  0x105
477961SNatalie.Li@Sun.COM  *  SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO  0x106
485331Samw  *
495331Samw  * The following sections detail the data returned for each
505331Samw  * InformationLevel. The requested information is placed in the Data
515331Samw  * portion of the transaction response. Note: a client which does not
525331Samw  * support long names can only request SMB_INFO_STANDARD.
535331Samw  *
545331Samw  * A four-byte resume key precedes each data item (described below) if bit
555331Samw  * 2 in the Flags field is set, i.e. if the request indicates the server
565331Samw  * should return resume keys. Note: it is not always the case. If the
575331Samw  * data item already includes the resume key, the resume key should not be
585331Samw  * added again.
595331Samw  *
605331Samw  * 4.3.4.1   SMB_INFO_STANDARD
615331Samw  *
625331Samw  *  Response Field                    Description
635331Samw  *  ================================  ==================================
645331Samw  *
655331Samw  *  SMB_DATE CreationDate;            Date when file was created
665331Samw  *  SMB_TIME CreationTime;            Time when file was created
675331Samw  *  SMB_DATE LastAccessDate;          Date of last file access
685331Samw  *  SMB_TIME LastAccessTime;          Time of last file access
695331Samw  *  SMB_DATE LastWriteDate;           Date of last write to the file
705331Samw  *  SMB_TIME LastWriteTime;           Time of last write to the file
715331Samw  *  ULONG  DataSize;                  File Size
725331Samw  *  ULONG AllocationSize;             Size of filesystem allocation unit
735331Samw  *  USHORT Attributes;                File Attributes
745331Samw  *  UCHAR FileNameLength;             Length of filename in bytes
755331Samw  *  STRING FileName;                  Name of found file
765331Samw  *
775331Samw  * 4.3.4.2   SMB_INFO_QUERY_EA_SIZE
785331Samw  *
795331Samw  *  Response Field                     Description
805331Samw  *  =================================  ==================================
815331Samw  *
825331Samw  *   SMB_DATE CreationDate;            Date when file was created
835331Samw  *   SMB_TIME CreationTime;            Time when file was created
845331Samw  *   SMB_DATE LastAccessDate;          Date of last file access
855331Samw  *   SMB_TIME LastAccessTime;          Time of last file access
865331Samw  *   SMB_DATE LastWriteDate;           Date of last write to the file
875331Samw  *   SMB_TIME LastWriteTime;           Time of last write to the file
885331Samw  *   ULONG DataSize;                   File Size
895331Samw  *   ULONG AllocationSize;             Size of filesystem allocation unit
905331Samw  *   USHORT Attributes;                File Attributes
915331Samw  *   ULONG EaSize;                     Size of file's EA information
925331Samw  *   UCHAR FileNameLength;             Length of filename in bytes
935331Samw  *   STRING FileName;                  Name of found file
945331Samw  *
955331Samw  * 4.3.4.3   SMB_INFO_QUERY_EAS_FROM_LIST
965331Samw  *
975331Samw  * This request returns the same information as SMB_INFO_QUERY_EA_SIZE, but
985331Samw  * only for files which have an EA list which match the EA information in
995331Samw  * the Data part of the request.
1005331Samw  *
1015331Samw  * 4.3.4.4   SMB_FIND_FILE_DIRECTORY_INFO
1025331Samw  *
1035331Samw  *  Response Field                     Description
1045331Samw  *  =================================  ==================================
1055331Samw  *
1065331Samw  *  ULONG NextEntryOffset;             Offset from this structure to
1075331Samw  *					beginning of next one
1085331Samw  *  ULONG FileIndex;
1095331Samw  *  LARGE_INTEGER CreationTime;        file creation time
1105331Samw  *  LARGE_INTEGER LastAccessTime;      last access time
1115331Samw  *  LARGE_INTEGER LastWriteTime;       last write time
1125331Samw  *  LARGE_INTEGER ChangeTime;          last attribute change time
1135331Samw  *  LARGE_INTEGER EndOfFile;           file size
1145331Samw  *  LARGE_INTEGER AllocationSize;      size of filesystem allocation information
1155331Samw  *  ULONG ExtFileAttributes;           Extended file attributes
1165331Samw  *					(see section 3.11)
1175331Samw  *  ULONG FileNameLength;              Length of filename in bytes
1185331Samw  *  STRING FileName;                   Name of the file
1195331Samw  *
1205331Samw  * 4.3.4.5   SMB_FIND_FILE_FULL_DIRECTORY_INFO
1215331Samw  *
1225331Samw  *  Response Field                     Description
1235331Samw  *  =================================  ==================================
1245331Samw  *
1255331Samw  *  ULONG NextEntryOffset;             Offset from this structure to
1265331Samw  *					beginning of next one
1275331Samw  *  ULONG FileIndex;
1285331Samw  *  LARGE_INTEGER CreationTime;        file creation time
1295331Samw  *  LARGE_INTEGER LastAccessTime;      last access time
1305331Samw  *  LARGE_INTEGER LastWriteTime;       last write time
1315331Samw  *  LARGE_INTEGER ChangeTime;          last attribute change time
1325331Samw  *  LARGE_INTEGER EndOfFile;           file size
1335331Samw  *  LARGE_INTEGER AllocationSize;      size of filesystem allocation information
1345331Samw  *  ULONG ExtFileAttributes;           Extended file attributes
1355331Samw  *					(see section 3.11)
1365331Samw  *  ULONG FileNameLength;              Length of filename in bytes
1375331Samw  *  ULONG EaSize;                      Size of file's extended attributes
1385331Samw  *  STRING FileName;                   Name of the file
1395331Samw  *
1407961SNatalie.Li@Sun.COM  *
1417961SNatalie.Li@Sun.COM  *  SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO
1427961SNatalie.Li@Sun.COM  *
1437961SNatalie.Li@Sun.COM  *  This is the same as SMB_FIND_FILE_FULL_DIRECTORY_INFO but with
1447961SNatalie.Li@Sun.COM  *  FileId inserted after EaSize. FileId is preceded by a 4 byte
1457961SNatalie.Li@Sun.COM  *  alignment padding.
1467961SNatalie.Li@Sun.COM  *
1477961SNatalie.Li@Sun.COM  *  Response Field                     Description
1487961SNatalie.Li@Sun.COM  *  =================================  ==================================
1497961SNatalie.Li@Sun.COM  *  ...
1507961SNatalie.Li@Sun.COM  *  ULONG EaSize;                      Size of file's extended attributes
1517961SNatalie.Li@Sun.COM  *  UCHAR Reserved[4]
1527961SNatalie.Li@Sun.COM  *  LARGE_INTEGER FileId               Internal file system unique id.
1537961SNatalie.Li@Sun.COM  *  STRING FileName;                   Name of the file
1547961SNatalie.Li@Sun.COM  *
1555331Samw  * 4.3.4.6   SMB_FIND_FILE_BOTH_DIRECTORY_INFO
1565331Samw  *
1575331Samw  *  Response Field                     Description
1585331Samw  *  =================================  ==================================
1595331Samw  *
1605331Samw  *  ULONG NextEntryOffset;             Offset from this structure to
1615331Samw  *					beginning of next one
1625331Samw  *  ULONG FileIndex;
1635331Samw  *  LARGE_INTEGER CreationTime;        file creation time
1645331Samw  *  LARGE_INTEGER LastAccessTime;      last access time
1655331Samw  *  LARGE_INTEGER LastWriteTime;       last write time
1665331Samw  *  LARGE_INTEGER ChangeTime;          last attribute change time
1675331Samw  *  LARGE_INTEGER EndOfFile;           file size
1685331Samw  *  LARGE_INTEGER AllocationSize;      size of filesystem allocation information
1695331Samw  *  ULONG ExtFileAttributes;           Extended file attributes
1705331Samw  *					(see section 3.11)
1715331Samw  *  ULONG FileNameLength;              Length of FileName in bytes
1725331Samw  *  ULONG EaSize;                      Size of file's extended attributes
1735331Samw  *  UCHAR ShortNameLength;             Length of file's short name in bytes
1745331Samw  *  UCHAR Reserved
1755331Samw  *  WCHAR ShortName[12];               File's 8.3 conformant name in Unicode
1765331Samw  *  STRING FileName;                   Files full length name
1775331Samw  *
1787961SNatalie.Li@Sun.COM  *
1797961SNatalie.Li@Sun.COM  *  SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO
1807961SNatalie.Li@Sun.COM  *
1817961SNatalie.Li@Sun.COM  *  This is the same as SMB_FIND_FILE_BOTH_DIRECTORY_INFO but with
1827961SNatalie.Li@Sun.COM  *  FileId inserted after ShortName. FileId is preceded by a 2 byte
1837961SNatalie.Li@Sun.COM  *  alignment pad.
1847961SNatalie.Li@Sun.COM  *
1857961SNatalie.Li@Sun.COM  *  Response Field                     Description
1867961SNatalie.Li@Sun.COM  *  =================================  ==================================
1877961SNatalie.Li@Sun.COM  *  ...
1887961SNatalie.Li@Sun.COM  *  WCHAR ShortName[12];               File's 8.3 conformant name in Unicode
1897961SNatalie.Li@Sun.COM  *  UCHAR Reserved[2]
1907961SNatalie.Li@Sun.COM  *  LARGE_INTEGER FileId               Internal file system unique id.
1917961SNatalie.Li@Sun.COM  *  STRING FileName;                   Files full length name
1927961SNatalie.Li@Sun.COM  *
1935331Samw  * 4.3.4.7   SMB_FIND_FILE_NAMES_INFO
1945331Samw  *
1955331Samw  *  Response Field                     Description
1965331Samw  *  =================================  ==================================
1975331Samw  *
1985331Samw  *  ULONG NextEntryOffset;             Offset from this structure to
1995331Samw  *                                     beginning of next one
2005331Samw  *  ULONG FileIndex;
2015331Samw  *  ULONG FileNameLength;              Length of FileName in bytes
2025331Samw  *  STRING FileName;                   Files full length name
2035331Samw  */
2045331Samw 
20510966SJordan.Brown@Sun.COM #include <smbsrv/smb_kproto.h>
2065331Samw #include <smbsrv/msgbuf.h>
2075331Samw #include <smbsrv/smb_fsops.h>
2085331Samw 
2098670SJose.Borrego@Sun.COM typedef struct smb_find_args {
2108670SJose.Borrego@Sun.COM 	uint16_t fa_infolev;
2118670SJose.Borrego@Sun.COM 	uint16_t fa_maxcount;
2128670SJose.Borrego@Sun.COM 	uint16_t fa_fflag;
2138670SJose.Borrego@Sun.COM 	uint32_t fa_maxdata;
2148670SJose.Borrego@Sun.COM } smb_find_args_t;
2155331Samw 
2168670SJose.Borrego@Sun.COM static int smb_trans2_find_entries(smb_request_t *, smb_xa_t *,
2178670SJose.Borrego@Sun.COM     smb_odir_t *, smb_find_args_t *, boolean_t *);
2188670SJose.Borrego@Sun.COM static int smb_trans2_find_get_maxdata(smb_request_t *, uint16_t, uint16_t);
2198670SJose.Borrego@Sun.COM static int smb_trans2_find_mbc_encode(smb_request_t *, smb_xa_t *,
2208670SJose.Borrego@Sun.COM     smb_fileinfo_t *, smb_find_args_t *);
2215331Samw 
2225331Samw /*
2235772Sas200622  * Tunable parameter to limit the maximum
2245772Sas200622  * number of entries to be returned.
2255331Samw  */
2265772Sas200622 uint16_t smb_trans2_find_max = 128;
2275331Samw 
2285331Samw /*
2295331Samw  * smb_com_trans2_find_first2
2305331Samw  *
2315331Samw  *  Client Request                Value
2325331Samw  *  ============================  ==================================
2335331Samw  *
2345331Samw  *  UCHAR  WordCount              15
2355331Samw  *  UCHAR  TotalDataCount         Total size of extended attribute list
2365331Samw  *  UCHAR  SetupCount             1
2375331Samw  *  UCHAR  Setup[0]               TRANS2_FIND_FIRST2
2385331Samw  *
2395331Samw  *  Parameter Block Encoding      Description
2405331Samw  *  ============================  ==================================
2415331Samw  *  USHORT SearchAttributes;
2425331Samw  *  USHORT SearchCount;           Maximum number of entries to return
2435331Samw  *  USHORT Flags;                 Additional information:
2445331Samw  *                                Bit 0 - close search after this request
2455331Samw  *                                Bit 1 - close search if end of search
2465331Samw  *                                reached
2475331Samw  *                                Bit 2 - return resume keys for each
2485331Samw  *                                entry found
2495331Samw  *                                Bit 3 - continue search from previous
2505331Samw  *                                ending place
2515331Samw  *                                Bit 4 - find with backup intent
2525331Samw  *  USHORT InformationLevel;      See below
2535331Samw  *  ULONG SearchStorageType;
2545331Samw  *  STRING FileName;              Pattern for the search
2555331Samw  *  UCHAR Data[ TotalDataCount ]  FEAList if InformationLevel is
2565331Samw  *                                QUERY_EAS_FROM_LIST
2575331Samw  *
2585331Samw  *  Response Parameter Block      Description
2595331Samw  *  ============================  ==================================
2605331Samw  *
2615331Samw  *  USHORT Sid;                   Search handle
2625331Samw  *  USHORT SearchCount;           Number of entries returned
2635331Samw  *  USHORT EndOfSearch;           Was last entry returned?
2645331Samw  *  USHORT EaErrorOffset;         Offset into EA list if EA error
2655331Samw  *  USHORT LastNameOffset;        Offset into data to file name of last
2665331Samw  *                                entry, if server needs it to resume
2675331Samw  *                                search; else 0
2685331Samw  *  UCHAR Data[ TotalDataCount ]  Level dependent info about the matches
2695331Samw  *                                found in the search
2705331Samw  */
2716030Sjb150015 smb_sdrc_t
smb_com_trans2_find_first2(smb_request_t * sr,smb_xa_t * xa)2725772Sas200622 smb_com_trans2_find_first2(smb_request_t *sr, smb_xa_t *xa)
2735331Samw {
2748670SJose.Borrego@Sun.COM 	int		count;
2758670SJose.Borrego@Sun.COM 	uint16_t	sattr, odid;
276*11963SAfshin.Ardakani@Sun.COM 	smb_pathname_t	*pn;
2778670SJose.Borrego@Sun.COM 	smb_odir_t	*od;
2788670SJose.Borrego@Sun.COM 	smb_find_args_t	args;
2798670SJose.Borrego@Sun.COM 	boolean_t	eos;
2809343SAfshin.Ardakani@Sun.COM 	uint32_t	odir_flags = 0;
2818670SJose.Borrego@Sun.COM 
2828670SJose.Borrego@Sun.COM 	bzero(&args, sizeof (smb_find_args_t));
2835331Samw 
2845331Samw 	if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) {
2855772Sas200622 		smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
2865331Samw 		    ERRDOS, ERROR_ACCESS_DENIED);
2876139Sjb150015 		return (SDRC_ERROR);
2885331Samw 	}
2895331Samw 
290*11963SAfshin.Ardakani@Sun.COM 	pn = &sr->arg.dirop.fqi.fq_path;
291*11963SAfshin.Ardakani@Sun.COM 
2928670SJose.Borrego@Sun.COM 	if (smb_mbc_decodef(&xa->req_param_mb, "%wwww4.u", sr, &sattr,
293*11963SAfshin.Ardakani@Sun.COM 	    &args.fa_maxcount, &args.fa_fflag, &args.fa_infolev,
294*11963SAfshin.Ardakani@Sun.COM 	    &pn->pn_path) != 0) {
2956139Sjb150015 		return (SDRC_ERROR);
2965331Samw 	}
2975331Samw 
298*11963SAfshin.Ardakani@Sun.COM 	smb_pathname_init(sr, pn, pn->pn_path);
299*11963SAfshin.Ardakani@Sun.COM 	if (!smb_pathname_validate(sr, pn))
300*11963SAfshin.Ardakani@Sun.COM 		return (-1);
301*11963SAfshin.Ardakani@Sun.COM 
302*11963SAfshin.Ardakani@Sun.COM 	if (smb_is_stream_name(pn->pn_path)) {
3037961SNatalie.Li@Sun.COM 		smbsr_error(sr, NT_STATUS_OBJECT_NAME_INVALID,
3047961SNatalie.Li@Sun.COM 		    ERRDOS, ERROR_INVALID_NAME);
3057961SNatalie.Li@Sun.COM 		return (SDRC_ERROR);
3067961SNatalie.Li@Sun.COM 	}
3077961SNatalie.Li@Sun.COM 
3089343SAfshin.Ardakani@Sun.COM 	if (args.fa_fflag & SMB_FIND_WITH_BACKUP_INTENT) {
3097961SNatalie.Li@Sun.COM 		sr->user_cr = smb_user_getprivcred(sr->uid_user);
3109343SAfshin.Ardakani@Sun.COM 		odir_flags = SMB_ODIR_OPENF_BACKUP_INTENT;
3119343SAfshin.Ardakani@Sun.COM 	}
3127961SNatalie.Li@Sun.COM 
3138670SJose.Borrego@Sun.COM 	args.fa_maxdata =
3148670SJose.Borrego@Sun.COM 	    smb_trans2_find_get_maxdata(sr, args.fa_infolev, args.fa_fflag);
3158670SJose.Borrego@Sun.COM 	if (args.fa_maxdata == 0)
3166139Sjb150015 		return (SDRC_ERROR);
3175772Sas200622 
318*11963SAfshin.Ardakani@Sun.COM 	odid = smb_odir_open(sr, pn->pn_path, sattr, odir_flags);
319*11963SAfshin.Ardakani@Sun.COM 	if (odid == 0) {
320*11963SAfshin.Ardakani@Sun.COM 		if (sr->smb_error.status == NT_STATUS_OBJECT_PATH_NOT_FOUND) {
321*11963SAfshin.Ardakani@Sun.COM 			smbsr_error(sr, NT_STATUS_OBJECT_NAME_NOT_FOUND,
322*11963SAfshin.Ardakani@Sun.COM 			    ERRDOS, ERROR_FILE_NOT_FOUND);
323*11963SAfshin.Ardakani@Sun.COM 		}
3246139Sjb150015 		return (SDRC_ERROR);
325*11963SAfshin.Ardakani@Sun.COM 	}
3265331Samw 
3278670SJose.Borrego@Sun.COM 	od = smb_tree_lookup_odir(sr->tid_tree, odid);
3288670SJose.Borrego@Sun.COM 	if (od == NULL)
3298670SJose.Borrego@Sun.COM 		return (SDRC_ERROR);
3308670SJose.Borrego@Sun.COM 	count = smb_trans2_find_entries(sr, xa, od, &args, &eos);
3315772Sas200622 
3328670SJose.Borrego@Sun.COM 	if (count == -1) {
3338670SJose.Borrego@Sun.COM 		smb_odir_close(od);
3349635SJoyce.McIntosh@Sun.COM 		smb_odir_release(od);
3356139Sjb150015 		return (SDRC_ERROR);
3365331Samw 	}
3375331Samw 
3388670SJose.Borrego@Sun.COM 	if (count == 0) {
3398670SJose.Borrego@Sun.COM 		smb_odir_close(od);
3409635SJoyce.McIntosh@Sun.COM 		smb_odir_release(od);
3418670SJose.Borrego@Sun.COM 		smbsr_errno(sr, ENOENT);
3428670SJose.Borrego@Sun.COM 		return (SDRC_ERROR);
3435331Samw 	}
3445331Samw 
3458670SJose.Borrego@Sun.COM 	if ((args.fa_fflag & SMB_FIND_CLOSE_AFTER_REQUEST) ||
3468670SJose.Borrego@Sun.COM 	    (eos && (args.fa_fflag & SMB_FIND_CLOSE_AT_EOS))) {
3478670SJose.Borrego@Sun.COM 		smb_odir_close(od);
3488670SJose.Borrego@Sun.COM 	} /* else leave odir open for trans2_find_next2 */
3498670SJose.Borrego@Sun.COM 
3509635SJoyce.McIntosh@Sun.COM 	smb_odir_release(od);
3519635SJoyce.McIntosh@Sun.COM 
3527052Samw 	(void) smb_mbc_encodef(&xa->rep_param_mb, "wwwww",
3538670SJose.Borrego@Sun.COM 	    odid, count, (eos) ? 1 : 0, 0, 0);
3545331Samw 
3556139Sjb150015 	return (SDRC_SUCCESS);
3565331Samw }
3575331Samw 
3585331Samw /*
3595331Samw  * smb_com_trans2_find_next2
3605331Samw  *
3615331Samw  *  Client Request                     Value
3625331Samw  *  ================================== =================================
3635331Samw  *
3645331Samw  *  WordCount                          15
3655331Samw  *  SetupCount                         1
3665331Samw  *  Setup[0]                           TRANS2_FIND_NEXT2
3675331Samw  *
3685331Samw  *  Parameter Block Encoding           Description
3695331Samw  *  ================================== =================================
3705331Samw  *
3715331Samw  *  USHORT Sid;                        Search handle
3725331Samw  *  USHORT SearchCount;                Maximum number of entries to
3735331Samw  *                                      return
3745331Samw  *  USHORT InformationLevel;           Levels described in
3755331Samw  *                                      TRANS2_FIND_FIRST2 request
3765331Samw  *  ULONG ResumeKey;                   Value returned by previous find2
3775331Samw  *                                      call
3785331Samw  *  USHORT Flags;                      Additional information: bit set-
3795331Samw  *                                      0 - close search after this
3805331Samw  *                                      request
3815331Samw  *                                      1 - close search if end of search
3825331Samw  *                                      reached
3835331Samw  *                                      2 - return resume keys for each
3845331Samw  *                                      entry found
3855331Samw  *                                      3 - resume/continue from previous
3865331Samw  *                                      ending place
3875331Samw  *                                      4 - find with backup intent
3885331Samw  *  STRING FileName;                   Resume file name
3895331Samw  *
3905331Samw  * Sid is the value returned by a previous successful TRANS2_FIND_FIRST2
3915331Samw  * call.  If Bit3 of Flags is set, then FileName may be the NULL string,
3925331Samw  * since the search is continued from the previous TRANS2_FIND request.
3935331Samw  * Otherwise, FileName must not be more than 256 characters long.
3945331Samw  *
3955331Samw  *  Response Field                     Description
3965331Samw  *  ================================== =================================
3975331Samw  *
3985331Samw  *  USHORT SearchCount;                Number of entries returned
3995331Samw  *  USHORT EndOfSearch;                Was last entry returned?
4005331Samw  *  USHORT EaErrorOffset;              Offset into EA list if EA error
4015331Samw  *  USHORT LastNameOffset;             Offset into data to file name of
4025331Samw  *                                      last entry, if server needs it to
4035331Samw  *                                      resume search; else 0
4045331Samw  *  UCHAR Data[TotalDataCount]         Level dependent info about the
4055331Samw  *                                      matches found in the search
4067961SNatalie.Li@Sun.COM  *
4077961SNatalie.Li@Sun.COM  *
4087961SNatalie.Li@Sun.COM  * The last parameter in the request is a filename, which is a
4097961SNatalie.Li@Sun.COM  * null-terminated unicode string.
4107961SNatalie.Li@Sun.COM  *
4117961SNatalie.Li@Sun.COM  * smb_mbc_decodef(&xa->req_param_mb, "%www lwu", sr,
4128670SJose.Borrego@Sun.COM  *    &odid, &fa_maxcount, &fa_infolev, &cookie, &fa_fflag, &fname)
4137961SNatalie.Li@Sun.COM  *
4148670SJose.Borrego@Sun.COM  * The filename parameter is not currently decoded because we
4158670SJose.Borrego@Sun.COM  * expect a 2-byte null but Mac OS 10 clients send a 1-byte null,
4167961SNatalie.Li@Sun.COM  * which leads to a decode error.
4177961SNatalie.Li@Sun.COM  * Thus, we do not support resume by filename.  We treat a request
4187961SNatalie.Li@Sun.COM  * to resume by filename as SMB_FIND_CONTINUE_FROM_LAST.
4195331Samw  */
4206030Sjb150015 smb_sdrc_t
smb_com_trans2_find_next2(smb_request_t * sr,smb_xa_t * xa)4215772Sas200622 smb_com_trans2_find_next2(smb_request_t *sr, smb_xa_t *xa)
4225331Samw {
4238670SJose.Borrego@Sun.COM 	int			count;
4248670SJose.Borrego@Sun.COM 	uint16_t		odid;
4258670SJose.Borrego@Sun.COM 	uint32_t		cookie;
4268670SJose.Borrego@Sun.COM 	smb_odir_t		*od;
4278670SJose.Borrego@Sun.COM 	smb_find_args_t		args;
4288670SJose.Borrego@Sun.COM 	boolean_t		eos;
4298670SJose.Borrego@Sun.COM 	smb_odir_resume_t	odir_resume;
4305331Samw 
4318670SJose.Borrego@Sun.COM 	bzero(&args, sizeof (smb_find_args_t));
4328670SJose.Borrego@Sun.COM 
4338670SJose.Borrego@Sun.COM 	if (smb_mbc_decodef(&xa->req_param_mb, "%wwwlw", sr, &odid,
4348670SJose.Borrego@Sun.COM 	    &args.fa_maxcount, &args.fa_infolev, &cookie, &args.fa_fflag)
4358670SJose.Borrego@Sun.COM 	    != 0) {
4366139Sjb150015 		return (SDRC_ERROR);
4375331Samw 	}
4385331Samw 
4397961SNatalie.Li@Sun.COM 	/* continuation by filename not supported */
4408670SJose.Borrego@Sun.COM 	if ((args.fa_fflag & SMB_FIND_CONTINUE_FROM_LAST) || (cookie == 0)) {
4418670SJose.Borrego@Sun.COM 		odir_resume.or_type = SMB_ODIR_RESUME_IDX;
4428670SJose.Borrego@Sun.COM 		odir_resume.or_idx = 0;
4438670SJose.Borrego@Sun.COM 	} else {
4448670SJose.Borrego@Sun.COM 		odir_resume.or_type = SMB_ODIR_RESUME_COOKIE;
4458670SJose.Borrego@Sun.COM 		odir_resume.or_cookie = cookie;
4468670SJose.Borrego@Sun.COM 	}
4477961SNatalie.Li@Sun.COM 
4488670SJose.Borrego@Sun.COM 	if (args.fa_fflag & SMB_FIND_WITH_BACKUP_INTENT)
4497961SNatalie.Li@Sun.COM 		sr->user_cr = smb_user_getprivcred(sr->uid_user);
4507961SNatalie.Li@Sun.COM 
4518670SJose.Borrego@Sun.COM 	args.fa_maxdata =
4528670SJose.Borrego@Sun.COM 	    smb_trans2_find_get_maxdata(sr, args.fa_infolev, args.fa_fflag);
4538670SJose.Borrego@Sun.COM 	if (args.fa_maxdata == 0)
4548670SJose.Borrego@Sun.COM 		return (SDRC_ERROR);
4558670SJose.Borrego@Sun.COM 
4568670SJose.Borrego@Sun.COM 	od = smb_tree_lookup_odir(sr->tid_tree, odid);
4578670SJose.Borrego@Sun.COM 	if (od == NULL) {
4588670SJose.Borrego@Sun.COM 		smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
4598670SJose.Borrego@Sun.COM 		    ERRDOS, ERROR_INVALID_HANDLE);
4608670SJose.Borrego@Sun.COM 		return (SDRC_ERROR);
4618670SJose.Borrego@Sun.COM 	}
4628670SJose.Borrego@Sun.COM 	smb_odir_resume_at(od, &odir_resume);
4638670SJose.Borrego@Sun.COM 	count = smb_trans2_find_entries(sr, xa, od, &args, &eos);
4648670SJose.Borrego@Sun.COM 
4658670SJose.Borrego@Sun.COM 	if (count == -1) {
4668670SJose.Borrego@Sun.COM 		smb_odir_close(od);
4679635SJoyce.McIntosh@Sun.COM 		smb_odir_release(od);
4686139Sjb150015 		return (SDRC_ERROR);
4695331Samw 	}
4705331Samw 
4718670SJose.Borrego@Sun.COM 	if ((args.fa_fflag & SMB_FIND_CLOSE_AFTER_REQUEST) ||
4728670SJose.Borrego@Sun.COM 	    (eos && (args.fa_fflag & SMB_FIND_CLOSE_AT_EOS))) {
4738670SJose.Borrego@Sun.COM 		smb_odir_close(od);
4748670SJose.Borrego@Sun.COM 	} /* else leave odir open for trans2_find_next2 */
4758670SJose.Borrego@Sun.COM 
4769635SJoyce.McIntosh@Sun.COM 	smb_odir_release(od);
4778670SJose.Borrego@Sun.COM 	(void) smb_mbc_encodef(&xa->rep_param_mb, "wwww",
4788670SJose.Borrego@Sun.COM 	    count, (eos) ? 1 : 0, 0, 0);
4798670SJose.Borrego@Sun.COM 
4808670SJose.Borrego@Sun.COM 	return (SDRC_SUCCESS);
4818670SJose.Borrego@Sun.COM }
4828670SJose.Borrego@Sun.COM 
4835331Samw 
4848670SJose.Borrego@Sun.COM /*
4858670SJose.Borrego@Sun.COM  * smb_trans2_find_entries
4868670SJose.Borrego@Sun.COM  *
4878670SJose.Borrego@Sun.COM  * Find and encode up to args->fa_maxcount directory entries.
4888670SJose.Borrego@Sun.COM  * For compatibilty with Windows, if args->fa_maxcount is zero treat it as 1.
4898670SJose.Borrego@Sun.COM  *
4908670SJose.Borrego@Sun.COM  * Returns:
4918670SJose.Borrego@Sun.COM  *   count - count of entries encoded
4928670SJose.Borrego@Sun.COM  *           *eos = B_TRUE if no more directory entries
4938670SJose.Borrego@Sun.COM  *      -1 - error
4948670SJose.Borrego@Sun.COM  */
4958670SJose.Borrego@Sun.COM static int
smb_trans2_find_entries(smb_request_t * sr,smb_xa_t * xa,smb_odir_t * od,smb_find_args_t * args,boolean_t * eos)4968670SJose.Borrego@Sun.COM smb_trans2_find_entries(smb_request_t *sr, smb_xa_t *xa, smb_odir_t *od,
4978670SJose.Borrego@Sun.COM     smb_find_args_t *args, boolean_t *eos)
4988670SJose.Borrego@Sun.COM {
4998670SJose.Borrego@Sun.COM 	int		rc;
5008670SJose.Borrego@Sun.COM 	uint16_t	count, maxcount;
5018670SJose.Borrego@Sun.COM 	uint32_t	cookie;
5028670SJose.Borrego@Sun.COM 	smb_fileinfo_t	fileinfo;
5038670SJose.Borrego@Sun.COM 
5048670SJose.Borrego@Sun.COM 	if ((maxcount = args->fa_maxcount) == 0)
5055772Sas200622 		maxcount = 1;
5065772Sas200622 
5075772Sas200622 	if ((smb_trans2_find_max != 0) && (maxcount > smb_trans2_find_max))
5085772Sas200622 		maxcount = smb_trans2_find_max;
5095772Sas200622 
5108670SJose.Borrego@Sun.COM 	count = 0;
5118670SJose.Borrego@Sun.COM 	while (count < maxcount) {
5128670SJose.Borrego@Sun.COM 		if (smb_odir_read_fileinfo(sr, od, &fileinfo, eos) != 0)
5138670SJose.Borrego@Sun.COM 			return (-1);
5148670SJose.Borrego@Sun.COM 		if (*eos == B_TRUE)
5158670SJose.Borrego@Sun.COM 			break;
5168670SJose.Borrego@Sun.COM 
5178670SJose.Borrego@Sun.COM 		rc = smb_trans2_find_mbc_encode(sr, xa, &fileinfo, args);
5188670SJose.Borrego@Sun.COM 		if (rc == -1)
5198670SJose.Borrego@Sun.COM 			return (-1);
5208670SJose.Borrego@Sun.COM 		if (rc == 1)
5218670SJose.Borrego@Sun.COM 			break;
5228670SJose.Borrego@Sun.COM 
5238670SJose.Borrego@Sun.COM 		cookie = fileinfo.fi_cookie;
5248670SJose.Borrego@Sun.COM 		++count;
5255331Samw 	}
5265331Samw 
5278670SJose.Borrego@Sun.COM 	/* save the last cookie returned to client */
5288670SJose.Borrego@Sun.COM 	if (count != 0)
5298670SJose.Borrego@Sun.COM 		smb_odir_save_cookie(od, 0, cookie);
5305331Samw 
53110122SJordan.Brown@Sun.COM 	/*
53210122SJordan.Brown@Sun.COM 	 * If all retrieved entries have been successfully encoded
53310122SJordan.Brown@Sun.COM 	 * and eos has not already been detected, check if there are
53410122SJordan.Brown@Sun.COM 	 * any more entries. eos will be set if there are no more.
53510122SJordan.Brown@Sun.COM 	 */
53610122SJordan.Brown@Sun.COM 	if ((rc == 0) && (!*eos))
5378670SJose.Borrego@Sun.COM 		(void) smb_odir_read_fileinfo(sr, od, &fileinfo, eos);
5385331Samw 
5398670SJose.Borrego@Sun.COM 	return (count);
5405331Samw }
5415331Samw 
5425331Samw /*
5435331Samw  * smb_trans2_find_get_maxdata
5445331Samw  *
5455772Sas200622  * Calculate the minimum response space required for the specified
5465772Sas200622  * information level.
5475331Samw  *
5485772Sas200622  * A non-zero return value provides the minimum space required.
5495772Sas200622  * A return value of zero indicates an unknown information level.
5505331Samw  */
5515772Sas200622 static int
smb_trans2_find_get_maxdata(smb_request_t * sr,uint16_t infolev,uint16_t fflag)5525772Sas200622 smb_trans2_find_get_maxdata(smb_request_t *sr, uint16_t infolev, uint16_t fflag)
5535331Samw {
5545331Samw 	int maxdata;
5555331Samw 
5565331Samw 	maxdata = smb_ascii_or_unicode_null_len(sr);
5575331Samw 
5585331Samw 	switch (infolev) {
5595331Samw 	case SMB_INFO_STANDARD :
5605331Samw 		if (fflag & SMB_FIND_RETURN_RESUME_KEYS)
5615331Samw 			maxdata += sizeof (int32_t);
5625331Samw 		maxdata += 2 + 2 + 2 + 4 + 4 + 2 + 1;
5635331Samw 		break;
5645331Samw 
5655331Samw 	case SMB_INFO_QUERY_EA_SIZE:
5665331Samw 		if (fflag & SMB_FIND_RETURN_RESUME_KEYS)
5675331Samw 			maxdata += sizeof (int32_t);
5685331Samw 		maxdata += 2 + 2 + 2 + 4 + 4 + 2 + 4 + 1;
5695331Samw 		break;
5705331Samw 
5715331Samw 	case SMB_FIND_FILE_DIRECTORY_INFO:
5725331Samw 		maxdata += 4 + 4 + 8 + 8 + 8 + 8 + 8 + 8 + 4 + 4;
5735331Samw 		break;
5745331Samw 
5757961SNatalie.Li@Sun.COM 	case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
5767961SNatalie.Li@Sun.COM 		maxdata += 4 + 4 + 8 + 8 + 8 + 8 + 8 + 8 + 4 + 4 + 4;
5777961SNatalie.Li@Sun.COM 		break;
5787961SNatalie.Li@Sun.COM 
5797961SNatalie.Li@Sun.COM 	case SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO:
5807961SNatalie.Li@Sun.COM 		maxdata += 4 + 4 + 8 + 8 + 8 + 8 + 8 + 8 + 4 + 4 + 4 + 4 + 8;
5817961SNatalie.Li@Sun.COM 		break;
5827961SNatalie.Li@Sun.COM 
5835331Samw 	case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
5845331Samw 		maxdata += 4 + 4 + 8 + 8 + 8 + 8 + 8 + 8 + 4 + 4 + 4 + 2 + 24;
5855331Samw 		break;
5865331Samw 
5877961SNatalie.Li@Sun.COM 	case SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO:
5887961SNatalie.Li@Sun.COM 		maxdata += 4 + 4 + 8 + 8 + 8 + 8 + 8 + 8 + 4 + 4 + 4 + 2 + 24
5897961SNatalie.Li@Sun.COM 		    + 2 + 8;
5907961SNatalie.Li@Sun.COM 		break;
5917961SNatalie.Li@Sun.COM 
5925331Samw 	case SMB_FIND_FILE_NAMES_INFO:
5935331Samw 		maxdata += 4 + 4 + 4;
5945331Samw 		break;
5955331Samw 
5965331Samw 	case SMB_MAC_FIND_BOTH_HFS_INFO:
5975331Samw 		maxdata += 4 + 4 + 8 + 8 + 8 + 8 + 8 + 8 + 8 + 4 + 1 + 1 + 2 +
5985331Samw 		    4 + 32 + 4 + 1 + 1 + 24 + 4;
5995331Samw 		break;
6005331Samw 
6015331Samw 	default:
6025331Samw 		maxdata = 0;
6038670SJose.Borrego@Sun.COM 		smbsr_error(sr, NT_STATUS_INVALID_LEVEL,
6048670SJose.Borrego@Sun.COM 		    ERRDOS, ERROR_INVALID_LEVEL);
6055331Samw 	}
6065331Samw 
6075331Samw 	return (maxdata);
6085331Samw }
6095331Samw 
6105331Samw /*
6118670SJose.Borrego@Sun.COM  * smb_trans2_mbc_encode
6125331Samw  *
6135331Samw  * This function encodes the mbc for one directory entry.
6145331Samw  *
6155331Samw  * The function returns -1 when the max data requested by client
6165331Samw  * is reached. If the entry is valid and successful encoded, 0
6175331Samw  * will be returned; otherwise, 1 will be returned.
6187961SNatalie.Li@Sun.COM  *
6197961SNatalie.Li@Sun.COM  * We always null terminate the filename. The space for the null
6207961SNatalie.Li@Sun.COM  * is included in the maxdata calculation and is therefore included
6217961SNatalie.Li@Sun.COM  * in the next_entry_offset. namelen is the unterminated length of
6227961SNatalie.Li@Sun.COM  * the filename. For levels except STANDARD and EA_SIZE, if the
6237961SNatalie.Li@Sun.COM  * filename is ascii the name length returned to the client should
6247961SNatalie.Li@Sun.COM  * include the null terminator. Otherwise the length returned to
6257961SNatalie.Li@Sun.COM  * the client should not include the terminator.
6268670SJose.Borrego@Sun.COM  *
6278670SJose.Borrego@Sun.COM  * Returns: 0 - data successfully encoded
6288670SJose.Borrego@Sun.COM  *          1 - client request's maxdata limit reached
6298670SJose.Borrego@Sun.COM  *	   -1 - error
6305331Samw  */
6318670SJose.Borrego@Sun.COM static int
smb_trans2_find_mbc_encode(smb_request_t * sr,smb_xa_t * xa,smb_fileinfo_t * fileinfo,smb_find_args_t * args)6328670SJose.Borrego@Sun.COM smb_trans2_find_mbc_encode(smb_request_t *sr, smb_xa_t *xa,
6338670SJose.Borrego@Sun.COM     smb_fileinfo_t *fileinfo, smb_find_args_t *args)
6345331Samw {
6358670SJose.Borrego@Sun.COM 	int		namelen, shortlen, buflen;
6368670SJose.Borrego@Sun.COM 	uint32_t	next_entry_offset;
6378670SJose.Borrego@Sun.COM 	uint32_t	dsize32, asize32;
6388670SJose.Borrego@Sun.COM 	uint32_t	mb_flags = 0;
6398670SJose.Borrego@Sun.COM 	char		buf83[26];
6408670SJose.Borrego@Sun.COM 	char		*tmpbuf;
6418670SJose.Borrego@Sun.COM 	smb_msgbuf_t	mb;
6425331Samw 
6438670SJose.Borrego@Sun.COM 	namelen = smb_ascii_or_unicode_strlen(sr, fileinfo->fi_name);
6447961SNatalie.Li@Sun.COM 	if (namelen == -1)
6458670SJose.Borrego@Sun.COM 		return (-1);
6465331Samw 
6478670SJose.Borrego@Sun.COM 	next_entry_offset = args->fa_maxdata + namelen;
6487961SNatalie.Li@Sun.COM 
6498670SJose.Borrego@Sun.COM 	if (MBC_ROOM_FOR(&xa->rep_data_mb, (args->fa_maxdata + namelen)) == 0)
6508670SJose.Borrego@Sun.COM 		return (1);
6515772Sas200622 
6527961SNatalie.Li@Sun.COM 	/*
6537961SNatalie.Li@Sun.COM 	 * If ascii the filename length returned to the client should
6547961SNatalie.Li@Sun.COM 	 * include the null terminator for levels except STANDARD and
6557961SNatalie.Li@Sun.COM 	 * EASIZE.
6567961SNatalie.Li@Sun.COM 	 */
6577961SNatalie.Li@Sun.COM 	if (!(sr->smb_flg2 & SMB_FLAGS2_UNICODE)) {
6588670SJose.Borrego@Sun.COM 		if ((args->fa_infolev != SMB_INFO_STANDARD) &&
6598670SJose.Borrego@Sun.COM 		    (args->fa_infolev != SMB_INFO_QUERY_EA_SIZE))
6607961SNatalie.Li@Sun.COM 			namelen += 1;
6617961SNatalie.Li@Sun.COM 	}
6625331Samw 
6638670SJose.Borrego@Sun.COM 	mb_flags = (sr->smb_flg2 & SMB_FLAGS2_UNICODE) ? SMB_MSGBUF_UNICODE : 0;
6648670SJose.Borrego@Sun.COM 	dsize32 = (fileinfo->fi_size > UINT_MAX) ?
6658670SJose.Borrego@Sun.COM 	    UINT_MAX : (uint32_t)fileinfo->fi_size;
6668670SJose.Borrego@Sun.COM 	asize32 = (fileinfo->fi_alloc_size > UINT_MAX) ?
6678670SJose.Borrego@Sun.COM 	    UINT_MAX : (uint32_t)fileinfo->fi_alloc_size;
6685331Samw 
6698670SJose.Borrego@Sun.COM 	switch (args->fa_infolev) {
6705331Samw 	case SMB_INFO_STANDARD:
6718670SJose.Borrego@Sun.COM 		if (args->fa_fflag & SMB_FIND_RETURN_RESUME_KEYS)
6727052Samw 			(void) smb_mbc_encodef(&xa->rep_data_mb, "l",
6738670SJose.Borrego@Sun.COM 			    fileinfo->fi_cookie);
6745331Samw 
6757052Samw 		(void) smb_mbc_encodef(&xa->rep_data_mb, "%yyyllwbu", sr,
67610504SKeyur.Desai@Sun.COM 		    smb_time_gmt_to_local(sr, fileinfo->fi_crtime.tv_sec),
67710504SKeyur.Desai@Sun.COM 		    smb_time_gmt_to_local(sr, fileinfo->fi_atime.tv_sec),
67810504SKeyur.Desai@Sun.COM 		    smb_time_gmt_to_local(sr, fileinfo->fi_mtime.tv_sec),
6796432Sas200622 		    dsize32,
6806432Sas200622 		    asize32,
6818670SJose.Borrego@Sun.COM 		    fileinfo->fi_dosattr,
6827961SNatalie.Li@Sun.COM 		    namelen,
6838670SJose.Borrego@Sun.COM 		    fileinfo->fi_name);
6845331Samw 		break;
6855331Samw 
6865331Samw 	case SMB_INFO_QUERY_EA_SIZE:
6878670SJose.Borrego@Sun.COM 		if (args->fa_fflag & SMB_FIND_RETURN_RESUME_KEYS)
6887052Samw 			(void) smb_mbc_encodef(&xa->rep_data_mb, "l",
6898670SJose.Borrego@Sun.COM 			    fileinfo->fi_cookie);
6905331Samw 
6917961SNatalie.Li@Sun.COM 		/*
6927961SNatalie.Li@Sun.COM 		 * Unicode filename should NOT be aligned. Encode ('u')
6937961SNatalie.Li@Sun.COM 		 * into a temporary buffer, then encode buffer as a
6947961SNatalie.Li@Sun.COM 		 * byte stream ('#c').
6957961SNatalie.Li@Sun.COM 		 * Regardless of whether unicode or ascii, a single
6967961SNatalie.Li@Sun.COM 		 * termination byte is used.
6977961SNatalie.Li@Sun.COM 		 */
69810966SJordan.Brown@Sun.COM 		buflen = namelen + sizeof (smb_wchar_t);
6997961SNatalie.Li@Sun.COM 		tmpbuf = kmem_zalloc(buflen, KM_SLEEP);
7007961SNatalie.Li@Sun.COM 		smb_msgbuf_init(&mb, (uint8_t *)tmpbuf, buflen, mb_flags);
7018670SJose.Borrego@Sun.COM 		if (smb_msgbuf_encode(&mb, "u", fileinfo->fi_name) < 0) {
7027961SNatalie.Li@Sun.COM 			smb_msgbuf_term(&mb);
7037961SNatalie.Li@Sun.COM 			kmem_free(tmpbuf, buflen);
7047961SNatalie.Li@Sun.COM 			return (-1);
7057961SNatalie.Li@Sun.COM 		}
7067961SNatalie.Li@Sun.COM 		tmpbuf[namelen] = '\0';
7077961SNatalie.Li@Sun.COM 
7087961SNatalie.Li@Sun.COM 		(void) smb_mbc_encodef(&xa->rep_data_mb, "%yyyllwlb#c", sr,
70910504SKeyur.Desai@Sun.COM 		    smb_time_gmt_to_local(sr, fileinfo->fi_crtime.tv_sec),
71010504SKeyur.Desai@Sun.COM 		    smb_time_gmt_to_local(sr, fileinfo->fi_atime.tv_sec),
71110504SKeyur.Desai@Sun.COM 		    smb_time_gmt_to_local(sr, fileinfo->fi_mtime.tv_sec),
7126432Sas200622 		    dsize32,
7136432Sas200622 		    asize32,
7148670SJose.Borrego@Sun.COM 		    fileinfo->fi_dosattr,
7155331Samw 		    0L,		/* EA Size */
7167961SNatalie.Li@Sun.COM 		    namelen,
7177961SNatalie.Li@Sun.COM 		    namelen + 1,
7187961SNatalie.Li@Sun.COM 		    tmpbuf);
7197961SNatalie.Li@Sun.COM 
7207961SNatalie.Li@Sun.COM 		smb_msgbuf_term(&mb);
7217961SNatalie.Li@Sun.COM 		kmem_free(tmpbuf, buflen);
7225331Samw 		break;
7235331Samw 
7245331Samw 	case SMB_FIND_FILE_DIRECTORY_INFO:
7257052Samw 		(void) smb_mbc_encodef(&xa->rep_data_mb, "%llTTTTqqllu", sr,
7265772Sas200622 		    next_entry_offset,
7278670SJose.Borrego@Sun.COM 		    fileinfo->fi_cookie,
7288670SJose.Borrego@Sun.COM 		    &fileinfo->fi_crtime,
7298670SJose.Borrego@Sun.COM 		    &fileinfo->fi_atime,
7308670SJose.Borrego@Sun.COM 		    &fileinfo->fi_mtime,
7318670SJose.Borrego@Sun.COM 		    &fileinfo->fi_ctime,
7328670SJose.Borrego@Sun.COM 		    fileinfo->fi_size,
7338670SJose.Borrego@Sun.COM 		    fileinfo->fi_alloc_size,
7348670SJose.Borrego@Sun.COM 		    fileinfo->fi_dosattr,
7357961SNatalie.Li@Sun.COM 		    namelen,
7368670SJose.Borrego@Sun.COM 		    fileinfo->fi_name);
7377961SNatalie.Li@Sun.COM 		break;
7387961SNatalie.Li@Sun.COM 
7397961SNatalie.Li@Sun.COM 	case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
7407961SNatalie.Li@Sun.COM 		(void) smb_mbc_encodef(&xa->rep_data_mb, "%llTTTTqqlllu", sr,
7417961SNatalie.Li@Sun.COM 		    next_entry_offset,
7428670SJose.Borrego@Sun.COM 		    fileinfo->fi_cookie,
7438670SJose.Borrego@Sun.COM 		    &fileinfo->fi_crtime,
7448670SJose.Borrego@Sun.COM 		    &fileinfo->fi_atime,
7458670SJose.Borrego@Sun.COM 		    &fileinfo->fi_mtime,
7468670SJose.Borrego@Sun.COM 		    &fileinfo->fi_ctime,
7478670SJose.Borrego@Sun.COM 		    fileinfo->fi_size,
7488670SJose.Borrego@Sun.COM 		    fileinfo->fi_alloc_size,
7498670SJose.Borrego@Sun.COM 		    fileinfo->fi_dosattr,
7507961SNatalie.Li@Sun.COM 		    namelen,
7517961SNatalie.Li@Sun.COM 		    0L,
7528670SJose.Borrego@Sun.COM 		    fileinfo->fi_name);
7537961SNatalie.Li@Sun.COM 		break;
7547961SNatalie.Li@Sun.COM 
7557961SNatalie.Li@Sun.COM 	case SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO:
7567961SNatalie.Li@Sun.COM 		(void) smb_mbc_encodef(&xa->rep_data_mb, "%llTTTTqqlll4.qu", sr,
7577961SNatalie.Li@Sun.COM 		    next_entry_offset,
7588670SJose.Borrego@Sun.COM 		    fileinfo->fi_cookie,
7598670SJose.Borrego@Sun.COM 		    &fileinfo->fi_crtime,
7608670SJose.Borrego@Sun.COM 		    &fileinfo->fi_atime,
7618670SJose.Borrego@Sun.COM 		    &fileinfo->fi_mtime,
7628670SJose.Borrego@Sun.COM 		    &fileinfo->fi_ctime,
7638670SJose.Borrego@Sun.COM 		    fileinfo->fi_size,
7648670SJose.Borrego@Sun.COM 		    fileinfo->fi_alloc_size,
7658670SJose.Borrego@Sun.COM 		    fileinfo->fi_dosattr,
7667961SNatalie.Li@Sun.COM 		    namelen,
7677961SNatalie.Li@Sun.COM 		    0L,
7688670SJose.Borrego@Sun.COM 		    fileinfo->fi_nodeid,
7698670SJose.Borrego@Sun.COM 		    fileinfo->fi_name);
7705331Samw 		break;
7715331Samw 
7725331Samw 	case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
7735331Samw 		bzero(buf83, sizeof (buf83));
7745772Sas200622 		smb_msgbuf_init(&mb, (uint8_t *)buf83, sizeof (buf83),
7755331Samw 		    mb_flags);
7768670SJose.Borrego@Sun.COM 		if (smb_msgbuf_encode(&mb, "U", fileinfo->fi_shortname) < 0) {
7775331Samw 			smb_msgbuf_term(&mb);
7785331Samw 			return (-1);
7795331Samw 		}
78010966SJordan.Brown@Sun.COM 		shortlen = smb_wcequiv_strlen(fileinfo->fi_shortname);
7815331Samw 
7827052Samw 		(void) smb_mbc_encodef(&xa->rep_data_mb, "%llTTTTqqlllb.24cu",
7835772Sas200622 		    sr,
7845772Sas200622 		    next_entry_offset,
7858670SJose.Borrego@Sun.COM 		    fileinfo->fi_cookie,
7868670SJose.Borrego@Sun.COM 		    &fileinfo->fi_crtime,
7878670SJose.Borrego@Sun.COM 		    &fileinfo->fi_atime,
7888670SJose.Borrego@Sun.COM 		    &fileinfo->fi_mtime,
7898670SJose.Borrego@Sun.COM 		    &fileinfo->fi_ctime,
7908670SJose.Borrego@Sun.COM 		    fileinfo->fi_size,
7918670SJose.Borrego@Sun.COM 		    fileinfo->fi_alloc_size,
7928670SJose.Borrego@Sun.COM 		    fileinfo->fi_dosattr,
7937961SNatalie.Li@Sun.COM 		    namelen,
7945331Samw 		    0L,
7955772Sas200622 		    shortlen,
7965331Samw 		    buf83,
7978670SJose.Borrego@Sun.COM 		    fileinfo->fi_name);
7985331Samw 
7995331Samw 		smb_msgbuf_term(&mb);
8005331Samw 		break;
8015331Samw 
8027961SNatalie.Li@Sun.COM 	case SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO:
8037961SNatalie.Li@Sun.COM 		bzero(buf83, sizeof (buf83));
8047961SNatalie.Li@Sun.COM 		smb_msgbuf_init(&mb, (uint8_t *)buf83, sizeof (buf83),
8057961SNatalie.Li@Sun.COM 		    mb_flags);
8068670SJose.Borrego@Sun.COM 		if (smb_msgbuf_encode(&mb, "u", fileinfo->fi_shortname) < 0) {
8077961SNatalie.Li@Sun.COM 			smb_msgbuf_term(&mb);
8087961SNatalie.Li@Sun.COM 			return (-1);
8097961SNatalie.Li@Sun.COM 		}
8108670SJose.Borrego@Sun.COM 		shortlen = smb_ascii_or_unicode_strlen(sr,
8118670SJose.Borrego@Sun.COM 		    fileinfo->fi_shortname);
8127961SNatalie.Li@Sun.COM 
8137961SNatalie.Li@Sun.COM 		(void) smb_mbc_encodef(&xa->rep_data_mb,
8147961SNatalie.Li@Sun.COM 		    "%llTTTTqqlllb.24c2.qu",
8157961SNatalie.Li@Sun.COM 		    sr,
8167961SNatalie.Li@Sun.COM 		    next_entry_offset,
8178670SJose.Borrego@Sun.COM 		    fileinfo->fi_cookie,
8188670SJose.Borrego@Sun.COM 		    &fileinfo->fi_crtime,
8198670SJose.Borrego@Sun.COM 		    &fileinfo->fi_atime,
8208670SJose.Borrego@Sun.COM 		    &fileinfo->fi_mtime,
8218670SJose.Borrego@Sun.COM 		    &fileinfo->fi_ctime,
8228670SJose.Borrego@Sun.COM 		    fileinfo->fi_size,
8238670SJose.Borrego@Sun.COM 		    fileinfo->fi_alloc_size,
8248670SJose.Borrego@Sun.COM 		    fileinfo->fi_dosattr,
8257961SNatalie.Li@Sun.COM 		    namelen,
8267961SNatalie.Li@Sun.COM 		    0L,
8277961SNatalie.Li@Sun.COM 		    shortlen,
8287961SNatalie.Li@Sun.COM 		    buf83,
8298670SJose.Borrego@Sun.COM 		    fileinfo->fi_nodeid,
8308670SJose.Borrego@Sun.COM 		    fileinfo->fi_name);
8317961SNatalie.Li@Sun.COM 
8327961SNatalie.Li@Sun.COM 		smb_msgbuf_term(&mb);
8337961SNatalie.Li@Sun.COM 		break;
8347961SNatalie.Li@Sun.COM 
8355331Samw 	case SMB_FIND_FILE_NAMES_INFO:
8367052Samw 		(void) smb_mbc_encodef(&xa->rep_data_mb, "%lllu", sr,
8375772Sas200622 		    next_entry_offset,
8388670SJose.Borrego@Sun.COM 		    fileinfo->fi_cookie,
8397961SNatalie.Li@Sun.COM 		    namelen,
8408670SJose.Borrego@Sun.COM 		    fileinfo->fi_name);
8415331Samw 		break;
8425331Samw 	}
8435331Samw 
8445331Samw 	return (0);
8455331Samw }
8465331Samw 
8475331Samw /*
8485331Samw  * Close a search started by a Trans2FindFirst2 request.
8495331Samw  */
8506030Sjb150015 smb_sdrc_t
smb_pre_find_close2(smb_request_t * sr)8516139Sjb150015 smb_pre_find_close2(smb_request_t *sr)
8526139Sjb150015 {
8536139Sjb150015 	DTRACE_SMB_1(op__FindClose2__start, smb_request_t *, sr);
8548670SJose.Borrego@Sun.COM 	return (SDRC_SUCCESS);
8556139Sjb150015 }
8566139Sjb150015 
8576139Sjb150015 void
smb_post_find_close2(smb_request_t * sr)8586139Sjb150015 smb_post_find_close2(smb_request_t *sr)
8596139Sjb150015 {
8606139Sjb150015 	DTRACE_SMB_1(op__FindClose2__done, smb_request_t *, sr);
8616139Sjb150015 }
8626139Sjb150015 
8636139Sjb150015 smb_sdrc_t
smb_com_find_close2(smb_request_t * sr)8645772Sas200622 smb_com_find_close2(smb_request_t *sr)
8655331Samw {
8668670SJose.Borrego@Sun.COM 	uint16_t	odid;
8678670SJose.Borrego@Sun.COM 	smb_odir_t	*od;
8688670SJose.Borrego@Sun.COM 
8698670SJose.Borrego@Sun.COM 	if (smbsr_decode_vwv(sr, "w", &odid) != 0)
8708670SJose.Borrego@Sun.COM 		return (SDRC_ERROR);
8718670SJose.Borrego@Sun.COM 
8728670SJose.Borrego@Sun.COM 	od = smb_tree_lookup_odir(sr->tid_tree, odid);
8738670SJose.Borrego@Sun.COM 	if (od == NULL) {
8748670SJose.Borrego@Sun.COM 		smbsr_error(sr, NT_STATUS_INVALID_HANDLE,
8758670SJose.Borrego@Sun.COM 		    ERRDOS, ERROR_INVALID_HANDLE);
8766139Sjb150015 		return (SDRC_ERROR);
8775331Samw 	}
8785331Samw 
8798670SJose.Borrego@Sun.COM 	smb_odir_close(od);
8808670SJose.Borrego@Sun.COM 	smb_odir_release(od);
8816030Sjb150015 
8826030Sjb150015 	if (smbsr_encode_empty_result(sr))
8836139Sjb150015 		return (SDRC_ERROR);
8846030Sjb150015 
8856139Sjb150015 	return (SDRC_SUCCESS);
8865331Samw }
887