Пример #1
0
/*
 * smb_com_trans2_find_first2
 *
 *  Client Request                Value
 *  ============================  ==================================
 *
 *  UCHAR  WordCount              15
 *  UCHAR  TotalDataCount         Total size of extended attribute list
 *  UCHAR  SetupCount             1
 *  UCHAR  Setup[0]               TRANS2_FIND_FIRST2
 *
 *  Parameter Block Encoding      Description
 *  ============================  ==================================
 *  USHORT SearchAttributes;
 *  USHORT SearchCount;           Maximum number of entries to return
 *  USHORT Flags;                 Additional information:
 *                                Bit 0 - close search after this request
 *                                Bit 1 - close search if end of search
 *                                reached
 *                                Bit 2 - return resume keys for each
 *                                entry found
 *                                Bit 3 - continue search from previous
 *                                ending place
 *                                Bit 4 - find with backup intent
 *  USHORT InformationLevel;      See below
 *  ULONG SearchStorageType;
 *  STRING FileName;              Pattern for the search
 *  UCHAR Data[ TotalDataCount ]  FEAList if InformationLevel is
 *                                QUERY_EAS_FROM_LIST
 *
 *  Response Parameter Block      Description
 *  ============================  ==================================
 *
 *  USHORT Sid;                   Search handle
 *  USHORT SearchCount;           Number of entries returned
 *  USHORT EndOfSearch;           Was last entry returned?
 *  USHORT EaErrorOffset;         Offset into EA list if EA error
 *  USHORT LastNameOffset;        Offset into data to file name of last
 *                                entry, if server needs it to resume
 *                                search; else 0
 *  UCHAR Data[ TotalDataCount ]  Level dependent info about the matches
 *                                found in the search
 */
smb_sdrc_t
smb_com_trans2_find_first2(smb_request_t *sr, smb_xa_t *xa)
{
	int		count;
	uint16_t	sattr, odid;
	smb_pathname_t	*pn;
	smb_odir_t	*od;
	smb_find_args_t	args;
	uint32_t	odir_flags = 0;

	bzero(&args, sizeof (smb_find_args_t));

	if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) {
		smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
		    ERRDOS, ERROR_ACCESS_DENIED);
		return (SDRC_ERROR);
	}

	pn = &sr->arg.dirop.fqi.fq_path;

	if (smb_mbc_decodef(&xa->req_param_mb, "%wwww4.u", sr, &sattr,
	    &args.fa_maxcount, &args.fa_fflag, &args.fa_infolev,
	    &pn->pn_path) != 0) {
		return (SDRC_ERROR);
	}

	smb_pathname_init(sr, pn, pn->pn_path);
	if (!smb_pathname_validate(sr, pn))
		return (-1);

	if (smb_is_stream_name(pn->pn_path)) {
		smbsr_error(sr, NT_STATUS_OBJECT_NAME_INVALID,
		    ERRDOS, ERROR_INVALID_NAME);
		return (SDRC_ERROR);
	}

	if (args.fa_fflag & SMB_FIND_WITH_BACKUP_INTENT) {
		sr->user_cr = smb_user_getprivcred(sr->uid_user);
		odir_flags = SMB_ODIR_OPENF_BACKUP_INTENT;
	}

	args.fa_maxdata =
	    smb_trans2_find_get_maxdata(sr, args.fa_infolev, args.fa_fflag);
	if (args.fa_maxdata == 0)
		return (SDRC_ERROR);

	odid = smb_odir_open(sr, pn->pn_path, sattr, odir_flags);
	if (odid == 0) {
		if (sr->smb_error.status == NT_STATUS_OBJECT_PATH_NOT_FOUND) {
			smbsr_error(sr, NT_STATUS_OBJECT_NAME_NOT_FOUND,
			    ERRDOS, ERROR_FILE_NOT_FOUND);
		}
		return (SDRC_ERROR);
	}

	od = smb_tree_lookup_odir(sr->tid_tree, odid);
	if (od == NULL)
		return (SDRC_ERROR);

	count = smb_trans2_find_entries(sr, xa, od, &args);

	if (count == -1) {
		smb_odir_close(od);
		smb_odir_release(od);
		return (SDRC_ERROR);
	}

	if (count == 0) {
		smb_odir_close(od);
		smb_odir_release(od);
		smbsr_errno(sr, ENOENT);
		return (SDRC_ERROR);
	}

	if ((args.fa_fflag & SMB_FIND_CLOSE_AFTER_REQUEST) ||
	    (args.fa_eos && (args.fa_fflag & SMB_FIND_CLOSE_AT_EOS))) {
		smb_odir_close(od);
	} /* else leave odir open for trans2_find_next2 */

	smb_odir_release(od);

	(void) smb_mbc_encodef(&xa->rep_param_mb, "wwwww",
	    odid,	/* Search ID */
	    count,	/* Search Count */
	    args.fa_eos, /* End Of Search */
	    0,		/* EA Error Offset */
	    args.fa_lno); /* Last Name Offset */

	return (SDRC_SUCCESS);
}
/*
 * smb_com_trans2_find_first2
 *
 *  Client Request                Value
 *  ============================  ==================================
 *
 *  UCHAR  WordCount              15
 *  UCHAR  TotalDataCount         Total size of extended attribute list
 *  UCHAR  SetupCount             1
 *  UCHAR  Setup[0]               TRANS2_FIND_FIRST2
 *
 *  Parameter Block Encoding      Description
 *  ============================  ==================================
 *  USHORT SearchAttributes;
 *  USHORT SearchCount;           Maximum number of entries to return
 *  USHORT Flags;                 Additional information:
 *                                Bit 0 - close search after this request
 *                                Bit 1 - close search if end of search
 *                                reached
 *                                Bit 2 - return resume keys for each
 *                                entry found
 *                                Bit 3 - continue search from previous
 *                                ending place
 *                                Bit 4 - find with backup intent
 *  USHORT InformationLevel;      See below
 *  ULONG SearchStorageType;
 *  STRING FileName;              Pattern for the search
 *  UCHAR Data[ TotalDataCount ]  FEAList if InformationLevel is
 *                                QUERY_EAS_FROM_LIST
 *
 *  Response Parameter Block      Description
 *  ============================  ==================================
 *
 *  USHORT Sid;                   Search handle
 *  USHORT SearchCount;           Number of entries returned
 *  USHORT EndOfSearch;           Was last entry returned?
 *  USHORT EaErrorOffset;         Offset into EA list if EA error
 *  USHORT LastNameOffset;        Offset into data to file name of last
 *                                entry, if server needs it to resume
 *                                search; else 0
 *  UCHAR Data[ TotalDataCount ]  Level dependent info about the matches
 *                                found in the search
 */
smb_sdrc_t
smb_com_trans2_find_first2(smb_request_t *sr, smb_xa_t *xa)
{
	int		count;
	uint16_t	sattr, odid;
	char		*path;
	smb_odir_t	*od;
	smb_find_args_t	args;
	boolean_t	eos;
	uint32_t	odir_flags = 0;

	bzero(&args, sizeof (smb_find_args_t));

	if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) {
		smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
		    ERRDOS, ERROR_ACCESS_DENIED);
		return (SDRC_ERROR);
	}

	if (smb_mbc_decodef(&xa->req_param_mb, "%wwww4.u", sr, &sattr,
	    &args.fa_maxcount, &args.fa_fflag, &args.fa_infolev, &path) != 0) {
		return (SDRC_ERROR);
	}

	if (smb_is_stream_name(path)) {
		smbsr_error(sr, NT_STATUS_OBJECT_NAME_INVALID,
		    ERRDOS, ERROR_INVALID_NAME);
		return (SDRC_ERROR);
	}

	if (args.fa_fflag & SMB_FIND_WITH_BACKUP_INTENT) {
		sr->user_cr = smb_user_getprivcred(sr->uid_user);
		odir_flags = SMB_ODIR_OPENF_BACKUP_INTENT;
	}

	args.fa_maxdata =
	    smb_trans2_find_get_maxdata(sr, args.fa_infolev, args.fa_fflag);
	if (args.fa_maxdata == 0)
		return (SDRC_ERROR);

	if (sr->smb_flg2 & SMB_FLAGS2_UNICODE)
		(void) smb_convert_wildcards(path);

	odid = smb_odir_open(sr, path, sattr, odir_flags);
	if (odid == 0)
		return (SDRC_ERROR);

	od = smb_tree_lookup_odir(sr->tid_tree, odid);
	if (od == NULL)
		return (SDRC_ERROR);
	count = smb_trans2_find_entries(sr, xa, od, &args, &eos);

	if (count == -1) {
		smb_odir_close(od);
		smb_odir_release(od);
		return (SDRC_ERROR);
	}

	if (count == 0) {
		smb_odir_close(od);
		smb_odir_release(od);
		smbsr_errno(sr, ENOENT);
		return (SDRC_ERROR);
	}

	if ((args.fa_fflag & SMB_FIND_CLOSE_AFTER_REQUEST) ||
	    (eos && (args.fa_fflag & SMB_FIND_CLOSE_AT_EOS))) {
		smb_odir_close(od);
	} /* else leave odir open for trans2_find_next2 */

	smb_odir_release(od);

	(void) smb_mbc_encodef(&xa->rep_param_mb, "wwwww",
	    odid, count, (eos) ? 1 : 0, 0, 0);

	return (SDRC_SUCCESS);
}