Пример #1
0
/*
 * smb_pathname_preprocess
 *
 * Perform common pre-processing of pn->pn_path:
 * - if the pn_path is blank, set it to '\\'
 * - perform unicode wildcard converstion.
 * - convert any '/' to '\\'
 * - eliminate duplicate slashes
 * - remove trailing slashes
 * - quota directory specific pre-processing
 */
static void
smb_pathname_preprocess(smb_request_t *sr, smb_pathname_t *pn)
{
	char *p;

	/* treat empty path as "\\" */
	if (strlen(pn->pn_path) == 0) {
		pn->pn_path = smb_pathname_strdup(sr, "\\");
		return;
	}

	if (sr->session->dialect < NT_LM_0_12)
		smb_convert_wildcards(pn->pn_path);

	/* treat '/' as '\\' */
	(void) strsubst(pn->pn_path, '/', '\\');

	(void) strcanon(pn->pn_path, "\\");

	/* remove trailing '\\' */
	p = pn->pn_path + strlen(pn->pn_path) - 1;
	if ((p != pn->pn_path) && (*p == '\\'))
		*p = '\0';

	smb_pathname_preprocess_quota(sr, pn);
	smb_pathname_preprocess_adminshare(sr, pn);
}
Пример #2
0
/*
 * smb_odir_open
 *
 * Create an odir representing the directory specified in pathname.
 *
 * Returns:
 * odid - Unique identifier of newly created odir.
 *    0 - error, error details set in sr.
 */
uint16_t
smb_odir_open(smb_request_t *sr, char *path, uint16_t sattr, uint32_t flags)
{
	int		rc;
	smb_tree_t	*tree;
	smb_node_t	*dnode;
	char		pattern[MAXNAMELEN];
	uint16_t 	odid;
	cred_t		*cr;

	ASSERT(sr);
	ASSERT(sr->sr_magic == SMB_REQ_MAGIC);
	ASSERT(sr->tid_tree);
	ASSERT(sr->tid_tree->t_magic == SMB_TREE_MAGIC);

	tree = sr->tid_tree;

	if (sr->session->dialect < NT_LM_0_12)
		smb_convert_wildcards(path);

	rc = smb_pathname_reduce(sr, sr->user_cr, path,
	    tree->t_snode, tree->t_snode, &dnode, pattern);
	if (rc != 0) {
		smbsr_errno(sr, rc);
		return (0);
	}

	if (!smb_node_is_dir(dnode)) {
		smbsr_error(sr, NT_STATUS_OBJECT_PATH_NOT_FOUND,
		    ERRDOS, ERROR_PATH_NOT_FOUND);
		smb_node_release(dnode);
		return (0);
	}

	if (smb_fsop_access(sr, sr->user_cr, dnode, FILE_LIST_DIRECTORY) != 0) {
		smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
		    ERRDOS, ERROR_ACCESS_DENIED);
		smb_node_release(dnode);
		return (0);
	}

	if (flags & SMB_ODIR_OPENF_BACKUP_INTENT)
		cr = smb_user_getprivcred(sr->uid_user);
	else
		cr = sr->uid_user->u_cred;

	odid = smb_odir_create(sr, dnode, pattern, sattr, cr);
	smb_node_release(dnode);
	return (odid);
}
/*
 * 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);
}