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 * 25a90cf9f2SGordon Ross * Copyright 2015 Nexenta Systems, Inc. All rights reserved. 26da6c28aaSamw */ 27da6c28aaSamw 28da6c28aaSamw 29da6c28aaSamw /* 30da6c28aaSamw * This module provides functions for TRANS2_FIND_FIRST2 and 31da6c28aaSamw * TRANS2_FIND_NEXT2 requests. The requests allow the client to search 32da6c28aaSamw * for the file(s) which match the file specification. The search is 33da6c28aaSamw * started with TRANS2_FIND_FIRST2 and can be continued if necessary with 34da6c28aaSamw * TRANS2_FIND_NEXT2. There are numerous levels of information which may be 35da6c28aaSamw * obtained for the returned files, the desired level is specified in the 36da6c28aaSamw * InformationLevel field of the requests. 37da6c28aaSamw * 38da6c28aaSamw * InformationLevel Name Value 39da6c28aaSamw * ================================= ================ 40da6c28aaSamw * 41da6c28aaSamw * SMB_INFO_STANDARD 1 42da6c28aaSamw * SMB_INFO_QUERY_EA_SIZE 2 43da6c28aaSamw * SMB_INFO_QUERY_EAS_FROM_LIST 3 44da6c28aaSamw * SMB_FIND_FILE_DIRECTORY_INFO 0x101 45da6c28aaSamw * SMB_FIND_FILE_FULL_DIRECTORY_INFO 0x102 46da6c28aaSamw * SMB_FIND_FILE_NAMES_INFO 0x103 47da6c28aaSamw * SMB_FIND_FILE_BOTH_DIRECTORY_INFO 0x104 48b89a8333Snatalie li - Sun Microsystems - Irvine United States * SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO 0x105 49b89a8333Snatalie li - Sun Microsystems - Irvine United States * SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO 0x106 50da6c28aaSamw * 51da6c28aaSamw * The following sections detail the data returned for each 52da6c28aaSamw * InformationLevel. The requested information is placed in the Data 53da6c28aaSamw * portion of the transaction response. Note: a client which does not 54da6c28aaSamw * support long names can only request SMB_INFO_STANDARD. 55da6c28aaSamw * 56da6c28aaSamw * A four-byte resume key precedes each data item (described below) if bit 57da6c28aaSamw * 2 in the Flags field is set, i.e. if the request indicates the server 58da6c28aaSamw * should return resume keys. Note: it is not always the case. If the 59da6c28aaSamw * data item already includes the resume key, the resume key should not be 60da6c28aaSamw * added again. 61da6c28aaSamw * 62da6c28aaSamw * 4.3.4.1 SMB_INFO_STANDARD 63da6c28aaSamw * 64da6c28aaSamw * Response Field Description 65da6c28aaSamw * ================================ ================================== 66da6c28aaSamw * 67da6c28aaSamw * SMB_DATE CreationDate; Date when file was created 68da6c28aaSamw * SMB_TIME CreationTime; Time when file was created 69da6c28aaSamw * SMB_DATE LastAccessDate; Date of last file access 70da6c28aaSamw * SMB_TIME LastAccessTime; Time of last file access 71da6c28aaSamw * SMB_DATE LastWriteDate; Date of last write to the file 72da6c28aaSamw * SMB_TIME LastWriteTime; Time of last write to the file 73da6c28aaSamw * ULONG DataSize; File Size 74da6c28aaSamw * ULONG AllocationSize; Size of filesystem allocation unit 75da6c28aaSamw * USHORT Attributes; File Attributes 76da6c28aaSamw * UCHAR FileNameLength; Length of filename in bytes 77da6c28aaSamw * STRING FileName; Name of found file 78da6c28aaSamw * 79da6c28aaSamw * 4.3.4.2 SMB_INFO_QUERY_EA_SIZE 80da6c28aaSamw * 81da6c28aaSamw * Response Field Description 82da6c28aaSamw * ================================= ================================== 83da6c28aaSamw * 84da6c28aaSamw * SMB_DATE CreationDate; Date when file was created 85da6c28aaSamw * SMB_TIME CreationTime; Time when file was created 86da6c28aaSamw * SMB_DATE LastAccessDate; Date of last file access 87da6c28aaSamw * SMB_TIME LastAccessTime; Time of last file access 88da6c28aaSamw * SMB_DATE LastWriteDate; Date of last write to the file 89da6c28aaSamw * SMB_TIME LastWriteTime; Time of last write to the file 90da6c28aaSamw * ULONG DataSize; File Size 91da6c28aaSamw * ULONG AllocationSize; Size of filesystem allocation unit 92da6c28aaSamw * USHORT Attributes; File Attributes 93da6c28aaSamw * ULONG EaSize; Size of file's EA information 94da6c28aaSamw * UCHAR FileNameLength; Length of filename in bytes 95da6c28aaSamw * STRING FileName; Name of found file 96da6c28aaSamw * 97da6c28aaSamw * 4.3.4.3 SMB_INFO_QUERY_EAS_FROM_LIST 98da6c28aaSamw * 99da6c28aaSamw * This request returns the same information as SMB_INFO_QUERY_EA_SIZE, but 100da6c28aaSamw * only for files which have an EA list which match the EA information in 101da6c28aaSamw * the Data part of the request. 102da6c28aaSamw * 103da6c28aaSamw * 4.3.4.4 SMB_FIND_FILE_DIRECTORY_INFO 104da6c28aaSamw * 105da6c28aaSamw * Response Field Description 106da6c28aaSamw * ================================= ================================== 107da6c28aaSamw * 108da6c28aaSamw * ULONG NextEntryOffset; Offset from this structure to 109da6c28aaSamw * beginning of next one 110da6c28aaSamw * ULONG FileIndex; 111da6c28aaSamw * LARGE_INTEGER CreationTime; file creation time 112da6c28aaSamw * LARGE_INTEGER LastAccessTime; last access time 113da6c28aaSamw * LARGE_INTEGER LastWriteTime; last write time 114da6c28aaSamw * LARGE_INTEGER ChangeTime; last attribute change time 115da6c28aaSamw * LARGE_INTEGER EndOfFile; file size 116da6c28aaSamw * LARGE_INTEGER AllocationSize; size of filesystem allocation information 117da6c28aaSamw * ULONG ExtFileAttributes; Extended file attributes 118da6c28aaSamw * (see section 3.11) 119da6c28aaSamw * ULONG FileNameLength; Length of filename in bytes 120da6c28aaSamw * STRING FileName; Name of the file 121da6c28aaSamw * 122da6c28aaSamw * 4.3.4.5 SMB_FIND_FILE_FULL_DIRECTORY_INFO 123da6c28aaSamw * 124da6c28aaSamw * Response Field Description 125da6c28aaSamw * ================================= ================================== 126da6c28aaSamw * 127da6c28aaSamw * ULONG NextEntryOffset; Offset from this structure to 128da6c28aaSamw * beginning of next one 129da6c28aaSamw * ULONG FileIndex; 130da6c28aaSamw * LARGE_INTEGER CreationTime; file creation time 131da6c28aaSamw * LARGE_INTEGER LastAccessTime; last access time 132da6c28aaSamw * LARGE_INTEGER LastWriteTime; last write time 133da6c28aaSamw * LARGE_INTEGER ChangeTime; last attribute change time 134da6c28aaSamw * LARGE_INTEGER EndOfFile; file size 135da6c28aaSamw * LARGE_INTEGER AllocationSize; size of filesystem allocation information 136da6c28aaSamw * ULONG ExtFileAttributes; Extended file attributes 137da6c28aaSamw * (see section 3.11) 138da6c28aaSamw * ULONG FileNameLength; Length of filename in bytes 139da6c28aaSamw * ULONG EaSize; Size of file's extended attributes 140da6c28aaSamw * STRING FileName; Name of the file 141da6c28aaSamw * 142b89a8333Snatalie li - Sun Microsystems - Irvine United States * 143b89a8333Snatalie li - Sun Microsystems - Irvine United States * SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO 144b89a8333Snatalie li - Sun Microsystems - Irvine United States * 145b89a8333Snatalie li - Sun Microsystems - Irvine United States * This is the same as SMB_FIND_FILE_FULL_DIRECTORY_INFO but with 146b89a8333Snatalie li - Sun Microsystems - Irvine United States * FileId inserted after EaSize. FileId is preceded by a 4 byte 147b89a8333Snatalie li - Sun Microsystems - Irvine United States * alignment padding. 148b89a8333Snatalie li - Sun Microsystems - Irvine United States * 149b89a8333Snatalie li - Sun Microsystems - Irvine United States * Response Field Description 150b89a8333Snatalie li - Sun Microsystems - Irvine United States * ================================= ================================== 151b89a8333Snatalie li - Sun Microsystems - Irvine United States * ... 152b89a8333Snatalie li - Sun Microsystems - Irvine United States * ULONG EaSize; Size of file's extended attributes 153b89a8333Snatalie li - Sun Microsystems - Irvine United States * UCHAR Reserved[4] 154b89a8333Snatalie li - Sun Microsystems - Irvine United States * LARGE_INTEGER FileId Internal file system unique id. 155b89a8333Snatalie li - Sun Microsystems - Irvine United States * STRING FileName; Name of the file 156b89a8333Snatalie li - Sun Microsystems - Irvine United States * 157da6c28aaSamw * 4.3.4.6 SMB_FIND_FILE_BOTH_DIRECTORY_INFO 158da6c28aaSamw * 159da6c28aaSamw * Response Field Description 160da6c28aaSamw * ================================= ================================== 161da6c28aaSamw * 162da6c28aaSamw * ULONG NextEntryOffset; Offset from this structure to 163da6c28aaSamw * beginning of next one 164da6c28aaSamw * ULONG FileIndex; 165da6c28aaSamw * LARGE_INTEGER CreationTime; file creation time 166da6c28aaSamw * LARGE_INTEGER LastAccessTime; last access time 167da6c28aaSamw * LARGE_INTEGER LastWriteTime; last write time 168da6c28aaSamw * LARGE_INTEGER ChangeTime; last attribute change time 169da6c28aaSamw * LARGE_INTEGER EndOfFile; file size 170da6c28aaSamw * LARGE_INTEGER AllocationSize; size of filesystem allocation information 171da6c28aaSamw * ULONG ExtFileAttributes; Extended file attributes 172da6c28aaSamw * (see section 3.11) 173da6c28aaSamw * ULONG FileNameLength; Length of FileName in bytes 174da6c28aaSamw * ULONG EaSize; Size of file's extended attributes 175da6c28aaSamw * UCHAR ShortNameLength; Length of file's short name in bytes 176da6c28aaSamw * UCHAR Reserved 177da6c28aaSamw * WCHAR ShortName[12]; File's 8.3 conformant name in Unicode 178da6c28aaSamw * STRING FileName; Files full length name 179da6c28aaSamw * 180b89a8333Snatalie li - Sun Microsystems - Irvine United States * 181b89a8333Snatalie li - Sun Microsystems - Irvine United States * SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO 182b89a8333Snatalie li - Sun Microsystems - Irvine United States * 183b89a8333Snatalie li - Sun Microsystems - Irvine United States * This is the same as SMB_FIND_FILE_BOTH_DIRECTORY_INFO but with 184b89a8333Snatalie li - Sun Microsystems - Irvine United States * FileId inserted after ShortName. FileId is preceded by a 2 byte 185b89a8333Snatalie li - Sun Microsystems - Irvine United States * alignment pad. 186b89a8333Snatalie li - Sun Microsystems - Irvine United States * 187b89a8333Snatalie li - Sun Microsystems - Irvine United States * Response Field Description 188b89a8333Snatalie li - Sun Microsystems - Irvine United States * ================================= ================================== 189b89a8333Snatalie li - Sun Microsystems - Irvine United States * ... 190b89a8333Snatalie li - Sun Microsystems - Irvine United States * WCHAR ShortName[12]; File's 8.3 conformant name in Unicode 191b89a8333Snatalie li - Sun Microsystems - Irvine United States * UCHAR Reserved[2] 192b89a8333Snatalie li - Sun Microsystems - Irvine United States * LARGE_INTEGER FileId Internal file system unique id. 193b89a8333Snatalie li - Sun Microsystems - Irvine United States * STRING FileName; Files full length name 194b89a8333Snatalie li - Sun Microsystems - Irvine United States * 195da6c28aaSamw * 4.3.4.7 SMB_FIND_FILE_NAMES_INFO 196da6c28aaSamw * 197da6c28aaSamw * Response Field Description 198da6c28aaSamw * ================================= ================================== 199da6c28aaSamw * 200da6c28aaSamw * ULONG NextEntryOffset; Offset from this structure to 201da6c28aaSamw * beginning of next one 202da6c28aaSamw * ULONG FileIndex; 203da6c28aaSamw * ULONG FileNameLength; Length of FileName in bytes 204da6c28aaSamw * STRING FileName; Files full length name 205da6c28aaSamw */ 206da6c28aaSamw 207bbf6f00cSJordan Brown #include <smbsrv/smb_kproto.h> 208da6c28aaSamw #include <smbsrv/msgbuf.h> 209da6c28aaSamw #include <smbsrv/smb_fsops.h> 210da6c28aaSamw 211bfbce3c1SGordon Ross /* 212bfbce3c1SGordon Ross * Args (and other state) that we carry around among the 213bfbce3c1SGordon Ross * various functions involved in FindFirst, FindNext. 214bfbce3c1SGordon Ross */ 2157f667e74Sjose borrego typedef struct smb_find_args { 216*07a6ae61SGordon 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; 2257f667e74Sjose borrego 2267f667e74Sjose borrego static int smb_trans2_find_entries(smb_request_t *, smb_xa_t *, 227bfbce3c1SGordon Ross smb_odir_t *, smb_find_args_t *); 228*07a6ae61SGordon 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 /* 233dc20a302Sas200622 * Tunable parameter to limit the maximum 234dc20a302Sas200622 * number of entries to be returned. 235da6c28aaSamw */ 236dc20a302Sas200622 uint16_t smb_trans2_find_max = 128; 237da6c28aaSamw 238da6c28aaSamw /* 239da6c28aaSamw * smb_com_trans2_find_first2 240da6c28aaSamw * 241da6c28aaSamw * Client Request Value 242da6c28aaSamw * ============================ ================================== 243da6c28aaSamw * 244da6c28aaSamw * UCHAR WordCount 15 245da6c28aaSamw * UCHAR TotalDataCount Total size of extended attribute list 246da6c28aaSamw * UCHAR SetupCount 1 247da6c28aaSamw * UCHAR Setup[0] TRANS2_FIND_FIRST2 248da6c28aaSamw * 249da6c28aaSamw * Parameter Block Encoding Description 250da6c28aaSamw * ============================ ================================== 251da6c28aaSamw * USHORT SearchAttributes; 252da6c28aaSamw * USHORT SearchCount; Maximum number of entries to return 253da6c28aaSamw * USHORT Flags; Additional information: 254da6c28aaSamw * Bit 0 - close search after this request 255da6c28aaSamw * Bit 1 - close search if end of search 256da6c28aaSamw * reached 257da6c28aaSamw * Bit 2 - return resume keys for each 258da6c28aaSamw * entry found 259da6c28aaSamw * Bit 3 - continue search from previous 260da6c28aaSamw * ending place 261da6c28aaSamw * Bit 4 - find with backup intent 262da6c28aaSamw * USHORT InformationLevel; See below 263da6c28aaSamw * ULONG SearchStorageType; 264da6c28aaSamw * STRING FileName; Pattern for the search 265da6c28aaSamw * UCHAR Data[ TotalDataCount ] FEAList if InformationLevel is 266da6c28aaSamw * QUERY_EAS_FROM_LIST 267da6c28aaSamw * 268da6c28aaSamw * Response Parameter Block Description 269da6c28aaSamw * ============================ ================================== 270da6c28aaSamw * 271da6c28aaSamw * USHORT Sid; Search handle 272da6c28aaSamw * USHORT SearchCount; Number of entries returned 273da6c28aaSamw * USHORT EndOfSearch; Was last entry returned? 274da6c28aaSamw * USHORT EaErrorOffset; Offset into EA list if EA error 275da6c28aaSamw * USHORT LastNameOffset; Offset into data to file name of last 276da6c28aaSamw * entry, if server needs it to resume 277da6c28aaSamw * search; else 0 278da6c28aaSamw * UCHAR Data[ TotalDataCount ] Level dependent info about the matches 279da6c28aaSamw * found in the search 280da6c28aaSamw */ 2817b59d02dSjb150015 smb_sdrc_t 282dc20a302Sas200622 smb_com_trans2_find_first2(smb_request_t *sr, smb_xa_t *xa) 283da6c28aaSamw { 2847f667e74Sjose borrego int count; 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)) { 295dc20a302Sas200622 smbsr_error(sr, NT_STATUS_ACCESS_DENIED, 296da6c28aaSamw ERRDOS, ERROR_ACCESS_DENIED); 297faa1795aSjb150015 return (SDRC_ERROR); 298da6c28aaSamw } 299da6c28aaSamw 3009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States pn = &sr->arg.dirop.fqi.fq_path; 3019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 3027f667e74Sjose borrego if (smb_mbc_decodef(&xa->req_param_mb, "%wwww4.u", sr, &sattr, 3039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States &args.fa_maxcount, &args.fa_fflag, &args.fa_infolev, 3049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States &pn->pn_path) != 0) { 305faa1795aSjb150015 return (SDRC_ERROR); 306da6c28aaSamw } 307da6c28aaSamw 3089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_pathname_init(sr, pn, pn->pn_path); 3099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (!smb_pathname_validate(sr, pn)) 3109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (-1); 3119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 3129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (smb_is_stream_name(pn->pn_path)) { 313b89a8333Snatalie li - Sun Microsystems - Irvine United States smbsr_error(sr, NT_STATUS_OBJECT_NAME_INVALID, 314b89a8333Snatalie li - Sun Microsystems - Irvine United States ERRDOS, ERROR_INVALID_NAME); 315b89a8333Snatalie li - Sun Microsystems - Irvine United States return (SDRC_ERROR); 316b89a8333Snatalie li - Sun Microsystems - Irvine United States } 317b89a8333Snatalie li - Sun Microsystems - Irvine United States 318eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States if (args.fa_fflag & SMB_FIND_WITH_BACKUP_INTENT) { 319b89a8333Snatalie li - Sun Microsystems - Irvine United States sr->user_cr = smb_user_getprivcred(sr->uid_user); 320eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States odir_flags = SMB_ODIR_OPENF_BACKUP_INTENT; 321eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States } 322b89a8333Snatalie li - Sun Microsystems - Irvine United States 323*07a6ae61SGordon Ross args.fa_fixedsize = 324*07a6ae61SGordon Ross smb_trans2_find_get_fixedsize(sr, args.fa_infolev, args.fa_fflag); 325*07a6ae61SGordon Ross if (args.fa_fixedsize == 0) 326faa1795aSjb150015 return (SDRC_ERROR); 327dc20a302Sas200622 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); 331faa1795aSjb150015 return (SDRC_ERROR); 3329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 3337f667e74Sjose borrego if (od == NULL) 3347f667e74Sjose borrego return (SDRC_ERROR); 335bfbce3c1SGordon Ross 336bfbce3c1SGordon Ross count = smb_trans2_find_entries(sr, xa, od, &args); 337dc20a302Sas200622 3387f667e74Sjose borrego if (count == -1) { 3397f667e74Sjose borrego smb_odir_close(od); 340a1511e6bSjoyce mcintosh smb_odir_release(od); 341faa1795aSjb150015 return (SDRC_ERROR); 342da6c28aaSamw } 343da6c28aaSamw 3447f667e74Sjose borrego if (count == 0) { 3457f667e74Sjose borrego smb_odir_close(od); 346a1511e6bSjoyce mcintosh smb_odir_release(od); 3477f667e74Sjose borrego smbsr_errno(sr, ENOENT); 3487f667e74Sjose borrego return (SDRC_ERROR); 349da6c28aaSamw } 350da6c28aaSamw 3517f667e74Sjose borrego if ((args.fa_fflag & SMB_FIND_CLOSE_AFTER_REQUEST) || 352bfbce3c1SGordon Ross (args.fa_eos && (args.fa_fflag & SMB_FIND_CLOSE_AT_EOS))) { 3537f667e74Sjose borrego smb_odir_close(od); 3547f667e74Sjose borrego } /* else leave odir open for trans2_find_next2 */ 3557f667e74Sjose borrego 3563db3f65cSamw (void) smb_mbc_encodef(&xa->rep_param_mb, "wwwww", 357a90cf9f2SGordon Ross od->d_odid, /* Search ID */ 358bfbce3c1SGordon Ross count, /* Search Count */ 359bfbce3c1SGordon Ross args.fa_eos, /* End Of Search */ 360bfbce3c1SGordon Ross 0, /* EA Error Offset */ 361bfbce3c1SGordon Ross args.fa_lno); /* Last Name Offset */ 362da6c28aaSamw 363a90cf9f2SGordon Ross smb_odir_release(od); 364a90cf9f2SGordon Ross 365faa1795aSjb150015 return (SDRC_SUCCESS); 366da6c28aaSamw } 367da6c28aaSamw 368da6c28aaSamw /* 369da6c28aaSamw * smb_com_trans2_find_next2 370da6c28aaSamw * 371da6c28aaSamw * Client Request Value 372da6c28aaSamw * ================================== ================================= 373da6c28aaSamw * 374da6c28aaSamw * WordCount 15 375da6c28aaSamw * SetupCount 1 376da6c28aaSamw * Setup[0] TRANS2_FIND_NEXT2 377da6c28aaSamw * 378da6c28aaSamw * Parameter Block Encoding Description 379da6c28aaSamw * ================================== ================================= 380da6c28aaSamw * 381da6c28aaSamw * USHORT Sid; Search handle 382da6c28aaSamw * USHORT SearchCount; Maximum number of entries to 383da6c28aaSamw * return 384da6c28aaSamw * USHORT InformationLevel; Levels described in 385da6c28aaSamw * TRANS2_FIND_FIRST2 request 386da6c28aaSamw * ULONG ResumeKey; Value returned by previous find2 387da6c28aaSamw * call 388da6c28aaSamw * USHORT Flags; Additional information: bit set- 389da6c28aaSamw * 0 - close search after this 390da6c28aaSamw * request 391da6c28aaSamw * 1 - close search if end of search 392da6c28aaSamw * reached 393da6c28aaSamw * 2 - return resume keys for each 394da6c28aaSamw * entry found 395da6c28aaSamw * 3 - resume/continue from previous 396da6c28aaSamw * ending place 397da6c28aaSamw * 4 - find with backup intent 398da6c28aaSamw * STRING FileName; Resume file name 399da6c28aaSamw * 400da6c28aaSamw * Sid is the value returned by a previous successful TRANS2_FIND_FIRST2 401da6c28aaSamw * call. If Bit3 of Flags is set, then FileName may be the NULL string, 402da6c28aaSamw * since the search is continued from the previous TRANS2_FIND request. 403da6c28aaSamw * Otherwise, FileName must not be more than 256 characters long. 404da6c28aaSamw * 405da6c28aaSamw * Response Field Description 406da6c28aaSamw * ================================== ================================= 407da6c28aaSamw * 408da6c28aaSamw * USHORT SearchCount; Number of entries returned 409da6c28aaSamw * USHORT EndOfSearch; Was last entry returned? 410da6c28aaSamw * USHORT EaErrorOffset; Offset into EA list if EA error 411da6c28aaSamw * USHORT LastNameOffset; Offset into data to file name of 412da6c28aaSamw * last entry, if server needs it to 413da6c28aaSamw * resume search; else 0 414da6c28aaSamw * UCHAR Data[TotalDataCount] Level dependent info about the 415da6c28aaSamw * matches found in the search 416b89a8333Snatalie li - Sun Microsystems - Irvine United States * 417b89a8333Snatalie li - Sun Microsystems - Irvine United States * 418b89a8333Snatalie li - Sun Microsystems - Irvine United States * The last parameter in the request is a filename, which is a 419b89a8333Snatalie li - Sun Microsystems - Irvine United States * null-terminated unicode string. 420b89a8333Snatalie li - Sun Microsystems - Irvine United States * 421b89a8333Snatalie li - Sun Microsystems - Irvine United States * smb_mbc_decodef(&xa->req_param_mb, "%www lwu", sr, 4227f667e74Sjose borrego * &odid, &fa_maxcount, &fa_infolev, &cookie, &fa_fflag, &fname) 423b89a8333Snatalie li - Sun Microsystems - Irvine United States * 4247f667e74Sjose borrego * The filename parameter is not currently decoded because we 4257f667e74Sjose borrego * expect a 2-byte null but Mac OS 10 clients send a 1-byte null, 426b89a8333Snatalie li - Sun Microsystems - Irvine United States * which leads to a decode error. 427b89a8333Snatalie li - Sun Microsystems - Irvine United States * Thus, we do not support resume by filename. We treat a request 428b89a8333Snatalie li - Sun Microsystems - Irvine United States * to resume by filename as SMB_FIND_CONTINUE_FROM_LAST. 429da6c28aaSamw */ 4307b59d02dSjb150015 smb_sdrc_t 431dc20a302Sas200622 smb_com_trans2_find_next2(smb_request_t *sr, smb_xa_t *xa) 432da6c28aaSamw { 4337f667e74Sjose borrego int count; 4347f667e74Sjose borrego uint16_t odid; 4357f667e74Sjose borrego smb_odir_t *od; 4367f667e74Sjose borrego smb_find_args_t args; 4377f667e74Sjose borrego smb_odir_resume_t odir_resume; 438da6c28aaSamw 439bfbce3c1SGordon Ross bzero(&args, sizeof (args)); 440bfbce3c1SGordon Ross bzero(&odir_resume, sizeof (odir_resume)); 4417f667e74Sjose borrego 442bfbce3c1SGordon Ross if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) { 443bfbce3c1SGordon Ross smbsr_error(sr, NT_STATUS_ACCESS_DENIED, 444bfbce3c1SGordon Ross ERRDOS, ERROR_ACCESS_DENIED); 445faa1795aSjb150015 return (SDRC_ERROR); 446da6c28aaSamw } 447da6c28aaSamw 448bfbce3c1SGordon Ross if (smb_mbc_decodef(&xa->req_param_mb, "%wwwlwu", sr, 449bfbce3c1SGordon Ross &odid, &args.fa_maxcount, &args.fa_infolev, 450bfbce3c1SGordon Ross &odir_resume.or_cookie, &args.fa_fflag, 451bfbce3c1SGordon Ross &odir_resume.or_fname) != 0) { 452bfbce3c1SGordon Ross return (SDRC_ERROR); 4537f667e74Sjose borrego } 454b89a8333Snatalie li - Sun Microsystems - Irvine United States 4557f667e74Sjose borrego if (args.fa_fflag & SMB_FIND_WITH_BACKUP_INTENT) 456b89a8333Snatalie li - Sun Microsystems - Irvine United States sr->user_cr = smb_user_getprivcred(sr->uid_user); 457b89a8333Snatalie li - Sun Microsystems - Irvine United States 458*07a6ae61SGordon Ross args.fa_fixedsize = 459*07a6ae61SGordon Ross smb_trans2_find_get_fixedsize(sr, args.fa_infolev, args.fa_fflag); 460*07a6ae61SGordon Ross if (args.fa_fixedsize == 0) 4617f667e74Sjose borrego return (SDRC_ERROR); 4627f667e74Sjose borrego 4633b13a1efSThomas Keiser od = smb_tree_lookup_odir(sr, odid); 4647f667e74Sjose borrego if (od == NULL) { 4657f667e74Sjose borrego smbsr_error(sr, NT_STATUS_INVALID_HANDLE, 4667f667e74Sjose borrego ERRDOS, ERROR_INVALID_HANDLE); 4677f667e74Sjose borrego return (SDRC_ERROR); 4687f667e74Sjose borrego } 4697f667e74Sjose borrego 470bfbce3c1SGordon Ross /* 471bfbce3c1SGordon Ross * Set the correct position in the directory. 472bfbce3c1SGordon Ross * 473bfbce3c1SGordon Ross * "Continue from last" is easy, but due to a history of 474bfbce3c1SGordon Ross * buggy server implementations, most clients don't use 475bfbce3c1SGordon Ross * that method. The most widely used (and reliable) is 476bfbce3c1SGordon Ross * resume by file name. Unfortunately, that can't really 477bfbce3c1SGordon Ross * be fully supported unless your file system stores all 478bfbce3c1SGordon Ross * directory entries in some sorted order (like NTFS). 479bfbce3c1SGordon Ross * We can partially support resume by name, where the only 480bfbce3c1SGordon Ross * name we're ever asked to resume on is the same as the 481bfbce3c1SGordon Ross * most recent we returned. That's always what the client 482bfbce3c1SGordon Ross * gives us as the resume name, so we can simply remember 483bfbce3c1SGordon Ross * the last name/offset pair and use that to position on 484bfbce3c1SGordon Ross * the following FindNext call. In the unlikely event 485bfbce3c1SGordon Ross * that the client asks to resume somewhere else, we'll 486bfbce3c1SGordon Ross * use the numeric resume key, and hope the client gives 487bfbce3c1SGordon Ross * correctly uses one of the resume keys we provided. 488bfbce3c1SGordon Ross */ 489bfbce3c1SGordon Ross if (args.fa_fflag & SMB_FIND_CONTINUE_FROM_LAST) { 490bfbce3c1SGordon Ross odir_resume.or_type = SMB_ODIR_RESUME_CONT; 491bfbce3c1SGordon Ross } else { 492bfbce3c1SGordon Ross odir_resume.or_type = SMB_ODIR_RESUME_FNAME; 493bfbce3c1SGordon Ross } 494bfbce3c1SGordon Ross smb_odir_resume_at(od, &odir_resume); 495bfbce3c1SGordon Ross 496bfbce3c1SGordon Ross count = smb_trans2_find_entries(sr, xa, od, &args); 4977f667e74Sjose borrego if (count == -1) { 4987f667e74Sjose borrego smb_odir_close(od); 499a1511e6bSjoyce mcintosh smb_odir_release(od); 500faa1795aSjb150015 return (SDRC_ERROR); 501da6c28aaSamw } 502da6c28aaSamw 5037f667e74Sjose borrego if ((args.fa_fflag & SMB_FIND_CLOSE_AFTER_REQUEST) || 504bfbce3c1SGordon Ross (args.fa_eos && (args.fa_fflag & SMB_FIND_CLOSE_AT_EOS))) { 5057f667e74Sjose borrego smb_odir_close(od); 5067f667e74Sjose borrego } /* else leave odir open for trans2_find_next2 */ 5077f667e74Sjose borrego 508a1511e6bSjoyce mcintosh smb_odir_release(od); 509bfbce3c1SGordon Ross 5107f667e74Sjose borrego (void) smb_mbc_encodef(&xa->rep_param_mb, "wwww", 511bfbce3c1SGordon Ross count, /* Search Count */ 512bfbce3c1SGordon Ross args.fa_eos, /* End Of Search */ 513bfbce3c1SGordon Ross 0, /* EA Error Offset */ 514bfbce3c1SGordon Ross args.fa_lno); /* Last Name Offset */ 5157f667e74Sjose borrego 5167f667e74Sjose borrego return (SDRC_SUCCESS); 517da6c28aaSamw } 518da6c28aaSamw 5197f667e74Sjose borrego 520da6c28aaSamw /* 5217f667e74Sjose borrego * smb_trans2_find_entries 5227f667e74Sjose borrego * 5237f667e74Sjose borrego * Find and encode up to args->fa_maxcount directory entries. 5247f667e74Sjose borrego * For compatibilty with Windows, if args->fa_maxcount is zero treat it as 1. 5257f667e74Sjose borrego * 5267f667e74Sjose borrego * Returns: 5277f667e74Sjose borrego * count - count of entries encoded 5287f667e74Sjose borrego * *eos = B_TRUE if no more directory entries 5297f667e74Sjose borrego * -1 - error 530dc20a302Sas200622 */ 5317f667e74Sjose borrego static int 5327f667e74Sjose borrego smb_trans2_find_entries(smb_request_t *sr, smb_xa_t *xa, smb_odir_t *od, 533bfbce3c1SGordon Ross smb_find_args_t *args) 5347f667e74Sjose borrego { 5357f667e74Sjose borrego smb_fileinfo_t fileinfo; 536bfbce3c1SGordon Ross smb_odir_resume_t odir_resume; 537b819cea2SGordon Ross uint16_t count, maxcount; 538b819cea2SGordon Ross int rc = -1; 539*07a6ae61SGordon Ross int LastEntryOffset = 0; 540a90cf9f2SGordon Ross boolean_t need_rewind = B_FALSE; 5417f667e74Sjose borrego 5423bd40d98SGordon Ross /* 5433bd40d98SGordon Ross * EAs are not current supported, so a search for level 5443bd40d98SGordon Ross * SMB_INFO_QUERY_EAS_FROM_LIST should always return an 5453bd40d98SGordon Ross * empty list. Returning zero for this case gives the 5463bd40d98SGordon Ross * client an empty response, which is better than an 5473bd40d98SGordon Ross * NT_STATUS_INVALID_LEVEL return (and test failures). 5483bd40d98SGordon Ross * 5493bd40d98SGordon Ross * If and when we do support EAs, this level will modify 5503bd40d98SGordon Ross * the search here, and then return results just like 5513bd40d98SGordon Ross * SMB_INFO_QUERY_EA_SIZE, but only including files 5523bd40d98SGordon Ross * that have an EA in the provided list. 5533bd40d98SGordon Ross */ 5543bd40d98SGordon Ross if (args->fa_infolev == SMB_INFO_QUERY_EAS_FROM_LIST) 5553bd40d98SGordon Ross return (0); 5563bd40d98SGordon Ross 5577f667e74Sjose borrego if ((maxcount = args->fa_maxcount) == 0) 558dc20a302Sas200622 maxcount = 1; 559dc20a302Sas200622 560dc20a302Sas200622 if ((smb_trans2_find_max != 0) && (maxcount > smb_trans2_find_max)) 561dc20a302Sas200622 maxcount = smb_trans2_find_max; 562dc20a302Sas200622 5637f667e74Sjose borrego count = 0; 5647f667e74Sjose borrego while (count < maxcount) { 565a90cf9f2SGordon Ross rc = smb_odir_read_fileinfo(sr, od, &fileinfo, &args->fa_eos); 566a90cf9f2SGordon Ross if (rc != 0 || args->fa_eos != 0) 5677f667e74Sjose borrego break; 5687f667e74Sjose borrego 569*07a6ae61SGordon Ross LastEntryOffset = xa->rep_data_mb.chain_offset; 5707f667e74Sjose borrego rc = smb_trans2_find_mbc_encode(sr, xa, &fileinfo, args); 5717f667e74Sjose borrego if (rc == -1) 572a90cf9f2SGordon Ross return (-1); /* fatal encoding error */ 573a90cf9f2SGordon Ross if (rc == 1) { 574a90cf9f2SGordon Ross need_rewind = B_TRUE; 575a90cf9f2SGordon Ross break; /* output space exhausted */ 576a90cf9f2SGordon Ross } 5777f667e74Sjose borrego 578bfbce3c1SGordon Ross /* 579bfbce3c1SGordon Ross * Save the info about the last file returned. 580bfbce3c1SGordon Ross */ 581bfbce3c1SGordon Ross args->fa_lastkey = fileinfo.fi_cookie; 582bfbce3c1SGordon Ross bcopy(fileinfo.fi_name, args->fa_lastname, MAXNAMELEN); 583bfbce3c1SGordon Ross 5847f667e74Sjose borrego ++count; 585da6c28aaSamw } 586a90cf9f2SGordon Ross if (args->fa_eos != 0 && rc == ENOENT) 587a90cf9f2SGordon Ross rc = 0; 588da6c28aaSamw 589*07a6ae61SGordon Ross /* 590*07a6ae61SGordon Ross * All but the ancient info levels start with NextEntryOffset. 591*07a6ae61SGordon Ross * That's supposed to be zero in the last entry returned. 592*07a6ae61SGordon Ross */ 593*07a6ae61SGordon Ross if (args->fa_infolev >= SMB_FIND_FILE_DIRECTORY_INFO) { 594*07a6ae61SGordon Ross (void) smb_mbc_poke(&xa->rep_data_mb, 595*07a6ae61SGordon Ross LastEntryOffset, "l", 0); 596*07a6ae61SGordon Ross } 597*07a6ae61SGordon Ross 5987f667e74Sjose borrego /* save the last cookie returned to client */ 5997f667e74Sjose borrego if (count != 0) 600bfbce3c1SGordon Ross smb_odir_save_fname(od, args->fa_lastkey, args->fa_lastname); 601da6c28aaSamw 6021fcced4cSJordan Brown /* 6031fcced4cSJordan Brown * If all retrieved entries have been successfully encoded 6041fcced4cSJordan Brown * and eos has not already been detected, check if there are 6051fcced4cSJordan Brown * any more entries. eos will be set if there are no more. 6061fcced4cSJordan Brown */ 607a90cf9f2SGordon Ross if ((rc == 0) && (args->fa_eos == 0)) { 608a90cf9f2SGordon Ross rc = smb_odir_read_fileinfo(sr, od, &fileinfo, &args->fa_eos); 609a90cf9f2SGordon Ross /* 610a90cf9f2SGordon Ross * If rc == ENOENT, we did not read any additional data. 611a90cf9f2SGordon Ross * if rc != 0, there's no need to rewind. 612a90cf9f2SGordon Ross */ 613a90cf9f2SGordon Ross if (rc == 0) 614a90cf9f2SGordon Ross need_rewind = B_TRUE; 615a90cf9f2SGordon Ross } 616bfbce3c1SGordon Ross 617bfbce3c1SGordon Ross /* 618bfbce3c1SGordon Ross * When the last entry we read from the directory did not 619bfbce3c1SGordon Ross * fit in the return buffer, we will have read one entry 620bfbce3c1SGordon Ross * that will not be returned in this call. That, and the 621bfbce3c1SGordon Ross * check for EOS just above both can leave the directory 622bfbce3c1SGordon Ross * position incorrect for the next call. Fix that now. 623bfbce3c1SGordon Ross */ 624a90cf9f2SGordon Ross if (need_rewind) { 625bfbce3c1SGordon Ross bzero(&odir_resume, sizeof (odir_resume)); 626bfbce3c1SGordon Ross odir_resume.or_type = SMB_ODIR_RESUME_COOKIE; 627bfbce3c1SGordon Ross odir_resume.or_cookie = args->fa_lastkey; 628bfbce3c1SGordon Ross smb_odir_resume_at(od, &odir_resume); 629a90cf9f2SGordon Ross } 630da6c28aaSamw 6317f667e74Sjose borrego return (count); 632da6c28aaSamw } 633da6c28aaSamw 634da6c28aaSamw /* 635*07a6ae61SGordon Ross * smb_trans2_find_get_fixedsize 636da6c28aaSamw * 637*07a6ae61SGordon Ross * Calculate the sizeof the fixed part of the response for the 638*07a6ae61SGordon Ross * specified information level. 639da6c28aaSamw * 640*07a6ae61SGordon Ross * A non-zero return value provides the fixed size. 641dc20a302Sas200622 * A return value of zero indicates an unknown information level. 642da6c28aaSamw */ 643dc20a302Sas200622 static int 644*07a6ae61SGordon Ross smb_trans2_find_get_fixedsize(smb_request_t *sr, uint16_t infolev, 645*07a6ae61SGordon Ross uint16_t fflag) 646da6c28aaSamw { 647*07a6ae61SGordon Ross int maxdata = 0; 648da6c28aaSamw 649da6c28aaSamw switch (infolev) { 650da6c28aaSamw case SMB_INFO_STANDARD : 651da6c28aaSamw if (fflag & SMB_FIND_RETURN_RESUME_KEYS) 652da6c28aaSamw maxdata += sizeof (int32_t); 653da6c28aaSamw maxdata += 2 + 2 + 2 + 4 + 4 + 2 + 1; 654da6c28aaSamw break; 655da6c28aaSamw 656da6c28aaSamw case SMB_INFO_QUERY_EA_SIZE: 6573bd40d98SGordon Ross case SMB_INFO_QUERY_EAS_FROM_LIST: 658da6c28aaSamw if (fflag & SMB_FIND_RETURN_RESUME_KEYS) 659da6c28aaSamw maxdata += sizeof (int32_t); 660da6c28aaSamw maxdata += 2 + 2 + 2 + 4 + 4 + 2 + 4 + 1; 661da6c28aaSamw break; 662da6c28aaSamw 663da6c28aaSamw case SMB_FIND_FILE_DIRECTORY_INFO: 664da6c28aaSamw maxdata += 4 + 4 + 8 + 8 + 8 + 8 + 8 + 8 + 4 + 4; 665da6c28aaSamw break; 666da6c28aaSamw 667b89a8333Snatalie li - Sun Microsystems - Irvine United States case SMB_FIND_FILE_FULL_DIRECTORY_INFO: 668b89a8333Snatalie li - Sun Microsystems - Irvine United States maxdata += 4 + 4 + 8 + 8 + 8 + 8 + 8 + 8 + 4 + 4 + 4; 669b89a8333Snatalie li - Sun Microsystems - Irvine United States break; 670b89a8333Snatalie li - Sun Microsystems - Irvine United States 671b89a8333Snatalie li - Sun Microsystems - Irvine United States case SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO: 672b89a8333Snatalie li - Sun Microsystems - Irvine United States maxdata += 4 + 4 + 8 + 8 + 8 + 8 + 8 + 8 + 4 + 4 + 4 + 4 + 8; 673b89a8333Snatalie li - Sun Microsystems - Irvine United States break; 674b89a8333Snatalie li - Sun Microsystems - Irvine United States 675da6c28aaSamw case SMB_FIND_FILE_BOTH_DIRECTORY_INFO: 676da6c28aaSamw maxdata += 4 + 4 + 8 + 8 + 8 + 8 + 8 + 8 + 4 + 4 + 4 + 2 + 24; 677da6c28aaSamw break; 678da6c28aaSamw 679b89a8333Snatalie li - Sun Microsystems - Irvine United States case SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO: 680b89a8333Snatalie li - Sun Microsystems - Irvine United States maxdata += 4 + 4 + 8 + 8 + 8 + 8 + 8 + 8 + 4 + 4 + 4 + 2 + 24 681b89a8333Snatalie li - Sun Microsystems - Irvine United States + 2 + 8; 682b89a8333Snatalie li - Sun Microsystems - Irvine United States break; 683b89a8333Snatalie li - Sun Microsystems - Irvine United States 684da6c28aaSamw case SMB_FIND_FILE_NAMES_INFO: 685da6c28aaSamw maxdata += 4 + 4 + 4; 686da6c28aaSamw break; 687da6c28aaSamw 688da6c28aaSamw case SMB_MAC_FIND_BOTH_HFS_INFO: 689da6c28aaSamw maxdata += 4 + 4 + 8 + 8 + 8 + 8 + 8 + 8 + 8 + 4 + 1 + 1 + 2 + 690da6c28aaSamw 4 + 32 + 4 + 1 + 1 + 24 + 4; 691da6c28aaSamw break; 692da6c28aaSamw 693da6c28aaSamw default: 694da6c28aaSamw maxdata = 0; 6957f667e74Sjose borrego smbsr_error(sr, NT_STATUS_INVALID_LEVEL, 6967f667e74Sjose borrego ERRDOS, ERROR_INVALID_LEVEL); 697da6c28aaSamw } 698da6c28aaSamw 699da6c28aaSamw return (maxdata); 700da6c28aaSamw } 701da6c28aaSamw 702da6c28aaSamw /* 703bfbce3c1SGordon Ross * This is an experimental feature that allows us to return zero 704bfbce3c1SGordon Ross * for all numeric resume keys, to match Windows behavior with an 705bfbce3c1SGordon Ross * NTFS share. Setting this variable to zero does that. 706bfbce3c1SGordon Ross * 707bfbce3c1SGordon Ross * It's possible we could remove this variable and always set 708bfbce3c1SGordon Ross * numeric resume keys to zero, but that would leave us unable 709bfbce3c1SGordon Ross * to handle a FindNext call with an arbitrary start position. 710bfbce3c1SGordon Ross * In practice we never see these, but in theory we could. 711bfbce3c1SGordon Ross * 712bfbce3c1SGordon Ross * See the long comment above smb_com_trans2_find_next2() for 713bfbce3c1SGordon Ross * more details about resume key / resume name handling. 714bfbce3c1SGordon Ross */ 715bfbce3c1SGordon Ross int smbd_use_resume_keys = 1; 716bfbce3c1SGordon Ross 717bfbce3c1SGordon Ross /* 7187f667e74Sjose borrego * smb_trans2_mbc_encode 719da6c28aaSamw * 720da6c28aaSamw * This function encodes the mbc for one directory entry. 721da6c28aaSamw * 722da6c28aaSamw * The function returns -1 when the max data requested by client 723da6c28aaSamw * is reached. If the entry is valid and successful encoded, 0 724da6c28aaSamw * will be returned; otherwise, 1 will be returned. 725b89a8333Snatalie li - Sun Microsystems - Irvine United States * 726b89a8333Snatalie li - Sun Microsystems - Irvine United States * We always null terminate the filename. The space for the null 727b89a8333Snatalie li - Sun Microsystems - Irvine United States * is included in the maxdata calculation and is therefore included 728b89a8333Snatalie li - Sun Microsystems - Irvine United States * in the next_entry_offset. namelen is the unterminated length of 729b89a8333Snatalie li - Sun Microsystems - Irvine United States * the filename. For levels except STANDARD and EA_SIZE, if the 730b89a8333Snatalie li - Sun Microsystems - Irvine United States * filename is ascii the name length returned to the client should 731b89a8333Snatalie li - Sun Microsystems - Irvine United States * include the null terminator. Otherwise the length returned to 732b89a8333Snatalie li - Sun Microsystems - Irvine United States * the client should not include the terminator. 7337f667e74Sjose borrego * 7347f667e74Sjose borrego * Returns: 0 - data successfully encoded 7357f667e74Sjose borrego * 1 - client request's maxdata limit reached 7367f667e74Sjose borrego * -1 - error 737da6c28aaSamw */ 7387f667e74Sjose borrego static int 7397f667e74Sjose borrego smb_trans2_find_mbc_encode(smb_request_t *sr, smb_xa_t *xa, 7407f667e74Sjose borrego smb_fileinfo_t *fileinfo, smb_find_args_t *args) 741da6c28aaSamw { 742bfbce3c1SGordon Ross int namelen, shortlen; 743dc20a302Sas200622 uint32_t next_entry_offset; 7447f667e74Sjose borrego uint32_t dsize32, asize32; 7457f667e74Sjose borrego uint32_t mb_flags = 0; 746bfbce3c1SGordon Ross uint32_t resume_key; 747da6c28aaSamw char buf83[26]; 748da6c28aaSamw smb_msgbuf_t mb; 749*07a6ae61SGordon Ross int pad = 0; 750da6c28aaSamw 7517f667e74Sjose borrego namelen = smb_ascii_or_unicode_strlen(sr, fileinfo->fi_name); 752b89a8333Snatalie li - Sun Microsystems - Irvine United States if (namelen == -1) 753da6c28aaSamw return (-1); 754da6c28aaSamw 755*07a6ae61SGordon Ross if (args->fa_infolev < SMB_FIND_FILE_DIRECTORY_INFO) { 756b89a8333Snatalie li - Sun Microsystems - Irvine United States /* 757*07a6ae61SGordon Ross * Ancient info levels don't have a NextEntryOffset 758*07a6ae61SGordon Ross * field, so there's no padding for alignment. 759*07a6ae61SGordon Ross * The client expects a null after the file name, 760*07a6ae61SGordon Ross * and then the next entry. The namelength field 761*07a6ae61SGordon Ross * never includes the null for these old levels. 762*07a6ae61SGordon Ross * Using the pad value to write the null because 763*07a6ae61SGordon Ross * we don't want to add that to namelen. 764*07a6ae61SGordon Ross * [MS-CIFS] sec. 2.8.1.{1-3} 765b89a8333Snatalie li - Sun Microsystems - Irvine United States */ 766*07a6ae61SGordon Ross if ((sr->smb_flg2 & SMB_FLAGS2_UNICODE) != 0) 767*07a6ae61SGordon Ross pad = 2; /* Unicode null */ 768*07a6ae61SGordon Ross else 769*07a6ae61SGordon Ross pad = 1; /* ascii null */ 770*07a6ae61SGordon Ross next_entry_offset = args->fa_fixedsize + namelen + pad; 771*07a6ae61SGordon Ross if (!MBC_ROOM_FOR(&xa->rep_data_mb, next_entry_offset)) 772bfbce3c1SGordon Ross return (1); 773*07a6ae61SGordon Ross } else { 774*07a6ae61SGordon Ross /* 775*07a6ae61SGordon Ross * Later info levels: The file name is written WITH 776*07a6ae61SGordon Ross * null termination, and the size of that null _is_ 777*07a6ae61SGordon Ross * included in the namelen field. There may also 778*07a6ae61SGordon Ross * be padding, and we pad to align(4) like Windows. 779*07a6ae61SGordon Ross * Don't include the padding in the "room for" test 780*07a6ae61SGordon Ross * because we want to ignore any error writing the 781*07a6ae61SGordon Ross * pad bytes after the last element. 782*07a6ae61SGordon Ross */ 783*07a6ae61SGordon Ross if ((sr->smb_flg2 & SMB_FLAGS2_UNICODE) != 0) 784*07a6ae61SGordon Ross namelen += 2; 785*07a6ae61SGordon Ross else 786*07a6ae61SGordon Ross namelen += 1; 787*07a6ae61SGordon Ross next_entry_offset = args->fa_fixedsize + namelen; 788*07a6ae61SGordon Ross if (!MBC_ROOM_FOR(&xa->rep_data_mb, next_entry_offset)) 789*07a6ae61SGordon Ross return (1); 790*07a6ae61SGordon Ross if ((next_entry_offset & 3) != 0) { 791*07a6ae61SGordon Ross pad = 4 - (next_entry_offset & 3); 792*07a6ae61SGordon Ross next_entry_offset += pad; 793*07a6ae61SGordon Ross } 794*07a6ae61SGordon Ross } 795bfbce3c1SGordon Ross 7967f667e74Sjose borrego mb_flags = (sr->smb_flg2 & SMB_FLAGS2_UNICODE) ? SMB_MSGBUF_UNICODE : 0; 7977f667e74Sjose borrego dsize32 = (fileinfo->fi_size > UINT_MAX) ? 7987f667e74Sjose borrego UINT_MAX : (uint32_t)fileinfo->fi_size; 7997f667e74Sjose borrego asize32 = (fileinfo->fi_alloc_size > UINT_MAX) ? 8007f667e74Sjose borrego UINT_MAX : (uint32_t)fileinfo->fi_alloc_size; 801da6c28aaSamw 802bfbce3c1SGordon Ross resume_key = fileinfo->fi_cookie; 803bfbce3c1SGordon Ross if (smbd_use_resume_keys == 0) 804bfbce3c1SGordon Ross resume_key = 0; 805bfbce3c1SGordon Ross 806bfbce3c1SGordon Ross /* 807bfbce3c1SGordon Ross * This switch handles all the "information levels" (formats) 808bfbce3c1SGordon Ross * that we support. Note that all formats have the file name 809bfbce3c1SGordon Ross * placed after some fixed-size data, and the code to write 810bfbce3c1SGordon Ross * the file name is factored out at the end of this switch. 811bfbce3c1SGordon Ross */ 8127f667e74Sjose borrego switch (args->fa_infolev) { 813da6c28aaSamw case SMB_INFO_STANDARD: 8147f667e74Sjose borrego if (args->fa_fflag & SMB_FIND_RETURN_RESUME_KEYS) 8153db3f65cSamw (void) smb_mbc_encodef(&xa->rep_data_mb, "l", 816bfbce3c1SGordon Ross resume_key); 817da6c28aaSamw 818bfbce3c1SGordon Ross (void) smb_mbc_encodef(&xa->rep_data_mb, "%yyyllwb", sr, 819e3f2c991SKeyur Desai smb_time_gmt_to_local(sr, fileinfo->fi_crtime.tv_sec), 820e3f2c991SKeyur Desai smb_time_gmt_to_local(sr, fileinfo->fi_atime.tv_sec), 821e3f2c991SKeyur Desai smb_time_gmt_to_local(sr, fileinfo->fi_mtime.tv_sec), 8226537f381Sas200622 dsize32, 8236537f381Sas200622 asize32, 8247f667e74Sjose borrego fileinfo->fi_dosattr, 825bfbce3c1SGordon Ross namelen); 826da6c28aaSamw break; 827da6c28aaSamw 828da6c28aaSamw case SMB_INFO_QUERY_EA_SIZE: 8293bd40d98SGordon Ross case SMB_INFO_QUERY_EAS_FROM_LIST: 8307f667e74Sjose borrego if (args->fa_fflag & SMB_FIND_RETURN_RESUME_KEYS) 8313db3f65cSamw (void) smb_mbc_encodef(&xa->rep_data_mb, "l", 832bfbce3c1SGordon Ross resume_key); 833da6c28aaSamw 834bfbce3c1SGordon Ross (void) smb_mbc_encodef(&xa->rep_data_mb, "%yyyllwlb", sr, 835e3f2c991SKeyur Desai smb_time_gmt_to_local(sr, fileinfo->fi_crtime.tv_sec), 836e3f2c991SKeyur Desai smb_time_gmt_to_local(sr, fileinfo->fi_atime.tv_sec), 837e3f2c991SKeyur Desai smb_time_gmt_to_local(sr, fileinfo->fi_mtime.tv_sec), 8386537f381Sas200622 dsize32, 8396537f381Sas200622 asize32, 8407f667e74Sjose borrego fileinfo->fi_dosattr, 841da6c28aaSamw 0L, /* EA Size */ 842bfbce3c1SGordon Ross namelen); 843da6c28aaSamw break; 844da6c28aaSamw 845da6c28aaSamw case SMB_FIND_FILE_DIRECTORY_INFO: 846bfbce3c1SGordon Ross (void) smb_mbc_encodef(&xa->rep_data_mb, "%llTTTTqqll", sr, 847dc20a302Sas200622 next_entry_offset, 848bfbce3c1SGordon Ross resume_key, 8497f667e74Sjose borrego &fileinfo->fi_crtime, 8507f667e74Sjose borrego &fileinfo->fi_atime, 8517f667e74Sjose borrego &fileinfo->fi_mtime, 8527f667e74Sjose borrego &fileinfo->fi_ctime, 8537f667e74Sjose borrego fileinfo->fi_size, 8547f667e74Sjose borrego fileinfo->fi_alloc_size, 8557f667e74Sjose borrego fileinfo->fi_dosattr, 856bfbce3c1SGordon Ross namelen); 857b89a8333Snatalie li - Sun Microsystems - Irvine United States break; 858b89a8333Snatalie li - Sun Microsystems - Irvine United States 859b89a8333Snatalie li - Sun Microsystems - Irvine United States case SMB_FIND_FILE_FULL_DIRECTORY_INFO: 860bfbce3c1SGordon Ross (void) smb_mbc_encodef(&xa->rep_data_mb, "%llTTTTqqlll", sr, 861b89a8333Snatalie li - Sun Microsystems - Irvine United States next_entry_offset, 862bfbce3c1SGordon Ross resume_key, 8637f667e74Sjose borrego &fileinfo->fi_crtime, 8647f667e74Sjose borrego &fileinfo->fi_atime, 8657f667e74Sjose borrego &fileinfo->fi_mtime, 8667f667e74Sjose borrego &fileinfo->fi_ctime, 8677f667e74Sjose borrego fileinfo->fi_size, 8687f667e74Sjose borrego fileinfo->fi_alloc_size, 8697f667e74Sjose borrego fileinfo->fi_dosattr, 870b89a8333Snatalie li - Sun Microsystems - Irvine United States namelen, 871bfbce3c1SGordon Ross 0L); 872b89a8333Snatalie li - Sun Microsystems - Irvine United States break; 873b89a8333Snatalie li - Sun Microsystems - Irvine United States 874b89a8333Snatalie li - Sun Microsystems - Irvine United States case SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO: 875bfbce3c1SGordon Ross (void) smb_mbc_encodef(&xa->rep_data_mb, "%llTTTTqqlll4.q", sr, 876b89a8333Snatalie li - Sun Microsystems - Irvine United States next_entry_offset, 877bfbce3c1SGordon Ross resume_key, 8787f667e74Sjose borrego &fileinfo->fi_crtime, 8797f667e74Sjose borrego &fileinfo->fi_atime, 8807f667e74Sjose borrego &fileinfo->fi_mtime, 8817f667e74Sjose borrego &fileinfo->fi_ctime, 8827f667e74Sjose borrego fileinfo->fi_size, 8837f667e74Sjose borrego fileinfo->fi_alloc_size, 8847f667e74Sjose borrego fileinfo->fi_dosattr, 885b89a8333Snatalie li - Sun Microsystems - Irvine United States namelen, 886b89a8333Snatalie li - Sun Microsystems - Irvine United States 0L, 887bfbce3c1SGordon Ross fileinfo->fi_nodeid); 888da6c28aaSamw break; 889da6c28aaSamw 890da6c28aaSamw case SMB_FIND_FILE_BOTH_DIRECTORY_INFO: 891da6c28aaSamw bzero(buf83, sizeof (buf83)); 892dc20a302Sas200622 smb_msgbuf_init(&mb, (uint8_t *)buf83, sizeof (buf83), 893da6c28aaSamw mb_flags); 8947f667e74Sjose borrego if (smb_msgbuf_encode(&mb, "U", fileinfo->fi_shortname) < 0) { 895da6c28aaSamw smb_msgbuf_term(&mb); 896da6c28aaSamw return (-1); 897da6c28aaSamw } 898bbf6f00cSJordan Brown shortlen = smb_wcequiv_strlen(fileinfo->fi_shortname); 899da6c28aaSamw 900bfbce3c1SGordon Ross (void) smb_mbc_encodef(&xa->rep_data_mb, "%llTTTTqqlllb.24c", 901dc20a302Sas200622 sr, 902dc20a302Sas200622 next_entry_offset, 903bfbce3c1SGordon Ross resume_key, 9047f667e74Sjose borrego &fileinfo->fi_crtime, 9057f667e74Sjose borrego &fileinfo->fi_atime, 9067f667e74Sjose borrego &fileinfo->fi_mtime, 9077f667e74Sjose borrego &fileinfo->fi_ctime, 9087f667e74Sjose borrego fileinfo->fi_size, 9097f667e74Sjose borrego fileinfo->fi_alloc_size, 9107f667e74Sjose borrego fileinfo->fi_dosattr, 911b89a8333Snatalie li - Sun Microsystems - Irvine United States namelen, 912da6c28aaSamw 0L, 913dc20a302Sas200622 shortlen, 914bfbce3c1SGordon Ross buf83); 915da6c28aaSamw 916da6c28aaSamw smb_msgbuf_term(&mb); 917da6c28aaSamw break; 918da6c28aaSamw 919b89a8333Snatalie li - Sun Microsystems - Irvine United States case SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO: 920b89a8333Snatalie li - Sun Microsystems - Irvine United States bzero(buf83, sizeof (buf83)); 921b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_msgbuf_init(&mb, (uint8_t *)buf83, sizeof (buf83), 922b89a8333Snatalie li - Sun Microsystems - Irvine United States mb_flags); 9237f667e74Sjose borrego if (smb_msgbuf_encode(&mb, "u", fileinfo->fi_shortname) < 0) { 924b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_msgbuf_term(&mb); 925b89a8333Snatalie li - Sun Microsystems - Irvine United States return (-1); 926b89a8333Snatalie li - Sun Microsystems - Irvine United States } 9277f667e74Sjose borrego shortlen = smb_ascii_or_unicode_strlen(sr, 9287f667e74Sjose borrego fileinfo->fi_shortname); 929b89a8333Snatalie li - Sun Microsystems - Irvine United States 930b89a8333Snatalie li - Sun Microsystems - Irvine United States (void) smb_mbc_encodef(&xa->rep_data_mb, 931bfbce3c1SGordon Ross "%llTTTTqqlllb.24c2.q", 932b89a8333Snatalie li - Sun Microsystems - Irvine United States sr, 933b89a8333Snatalie li - Sun Microsystems - Irvine United States next_entry_offset, 934bfbce3c1SGordon Ross resume_key, 9357f667e74Sjose borrego &fileinfo->fi_crtime, 9367f667e74Sjose borrego &fileinfo->fi_atime, 9377f667e74Sjose borrego &fileinfo->fi_mtime, 9387f667e74Sjose borrego &fileinfo->fi_ctime, 9397f667e74Sjose borrego fileinfo->fi_size, 9407f667e74Sjose borrego fileinfo->fi_alloc_size, 9417f667e74Sjose borrego fileinfo->fi_dosattr, 942b89a8333Snatalie li - Sun Microsystems - Irvine United States namelen, 943b89a8333Snatalie li - Sun Microsystems - Irvine United States 0L, 944b89a8333Snatalie li - Sun Microsystems - Irvine United States shortlen, 945b89a8333Snatalie li - Sun Microsystems - Irvine United States buf83, 946bfbce3c1SGordon Ross fileinfo->fi_nodeid); 947b89a8333Snatalie li - Sun Microsystems - Irvine United States 948b89a8333Snatalie li - Sun Microsystems - Irvine United States smb_msgbuf_term(&mb); 949b89a8333Snatalie li - Sun Microsystems - Irvine United States break; 950b89a8333Snatalie li - Sun Microsystems - Irvine United States 951da6c28aaSamw case SMB_FIND_FILE_NAMES_INFO: 952bfbce3c1SGordon Ross (void) smb_mbc_encodef(&xa->rep_data_mb, "%lll", sr, 953dc20a302Sas200622 next_entry_offset, 954bfbce3c1SGordon Ross resume_key, 955bfbce3c1SGordon Ross namelen); 956da6c28aaSamw break; 957bfbce3c1SGordon Ross 958bfbce3c1SGordon Ross default: 959bfbce3c1SGordon Ross /* invalid info. level */ 960bfbce3c1SGordon Ross return (-1); 961da6c28aaSamw } 962da6c28aaSamw 963bfbce3c1SGordon Ross /* 964bfbce3c1SGordon Ross * At this point we have written all the fixed-size data 965bfbce3c1SGordon Ross * for the specified info. level, and we're about to put 966bfbce3c1SGordon Ross * the file name string in the message. We may later 967bfbce3c1SGordon Ross * need the offset in the trans2 data where this string 968bfbce3c1SGordon Ross * is placed, so save the message position now. Note: 969bfbce3c1SGordon Ross * We also need to account for the alignment padding 970bfbce3c1SGordon Ross * that may precede the unicode string. 971bfbce3c1SGordon Ross */ 972bfbce3c1SGordon Ross args->fa_lno = xa->rep_data_mb.chain_offset; 973bfbce3c1SGordon Ross if ((sr->smb_flg2 & SMB_FLAGS2_UNICODE) != 0 && 974bfbce3c1SGordon Ross (args->fa_lno & 1) != 0) 975bfbce3c1SGordon Ross args->fa_lno++; 976bfbce3c1SGordon Ross 977*07a6ae61SGordon Ross (void) smb_mbc_encodef(&xa->rep_data_mb, "%#u", sr, 978*07a6ae61SGordon Ross namelen, fileinfo->fi_name); 979*07a6ae61SGordon Ross 980*07a6ae61SGordon Ross if (pad) 981*07a6ae61SGordon Ross (void) smb_mbc_encodef(&xa->rep_data_mb, "#.", pad); 982bfbce3c1SGordon Ross 983da6c28aaSamw return (0); 984da6c28aaSamw } 985da6c28aaSamw 986da6c28aaSamw /* 987da6c28aaSamw * Close a search started by a Trans2FindFirst2 request. 988da6c28aaSamw */ 9897b59d02dSjb150015 smb_sdrc_t 990faa1795aSjb150015 smb_pre_find_close2(smb_request_t *sr) 991faa1795aSjb150015 { 992faa1795aSjb150015 DTRACE_SMB_1(op__FindClose2__start, smb_request_t *, sr); 9937f667e74Sjose borrego return (SDRC_SUCCESS); 994faa1795aSjb150015 } 995faa1795aSjb150015 996faa1795aSjb150015 void 997faa1795aSjb150015 smb_post_find_close2(smb_request_t *sr) 998faa1795aSjb150015 { 999faa1795aSjb150015 DTRACE_SMB_1(op__FindClose2__done, smb_request_t *, sr); 1000faa1795aSjb150015 } 1001faa1795aSjb150015 1002faa1795aSjb150015 smb_sdrc_t 1003dc20a302Sas200622 smb_com_find_close2(smb_request_t *sr) 1004da6c28aaSamw { 10057f667e74Sjose borrego uint16_t odid; 10067f667e74Sjose borrego smb_odir_t *od; 10077f667e74Sjose borrego 10087f667e74Sjose borrego if (smbsr_decode_vwv(sr, "w", &odid) != 0) 10097f667e74Sjose borrego return (SDRC_ERROR); 10107f667e74Sjose borrego 10113b13a1efSThomas Keiser od = smb_tree_lookup_odir(sr, odid); 10127f667e74Sjose borrego if (od == NULL) { 10137f667e74Sjose borrego smbsr_error(sr, NT_STATUS_INVALID_HANDLE, 10147f667e74Sjose borrego ERRDOS, ERROR_INVALID_HANDLE); 1015faa1795aSjb150015 return (SDRC_ERROR); 1016da6c28aaSamw } 1017da6c28aaSamw 10187f667e74Sjose borrego smb_odir_close(od); 10197f667e74Sjose borrego smb_odir_release(od); 10207b59d02dSjb150015 10217b59d02dSjb150015 if (smbsr_encode_empty_result(sr)) 1022faa1795aSjb150015 return (SDRC_ERROR); 10237b59d02dSjb150015 1024faa1795aSjb150015 return (SDRC_SUCCESS); 1025da6c28aaSamw } 1026