/*
 * smb_vop_stream_lookup()
 *
 * The name returned in od_name is the on-disk name of the stream with the
 * SMB_STREAM_PREFIX stripped off.  od_name should be allocated to MAXNAMELEN
 * by the caller.
 */
int
smb_vop_stream_lookup(
    vnode_t		*fvp,
    char		*stream_name,
    vnode_t		**vpp,
    char		*od_name,
    vnode_t		**xattrdirvpp,
    int			flags,
    vnode_t		*rootvp,
    cred_t		*cr)
{
	char *solaris_stream_name;
	char *name;
	int error, tmpflgs;

	if ((error = smb_vop_lookup_xattrdir(fvp, xattrdirvpp,
	    LOOKUP_XATTR | CREATE_XATTR_DIR, cr)) != 0)
		return (error);

	/*
	 * Prepend SMB_STREAM_PREFIX to stream name
	 */

	solaris_stream_name = kmem_alloc(MAXNAMELEN, KM_SLEEP);
	(void) sprintf(solaris_stream_name, "%s%s", SMB_STREAM_PREFIX,
	    stream_name);

	/*
	 * "name" will hold the on-disk name returned from smb_vop_lookup
	 * for the stream, including the SMB_STREAM_PREFIX.
	 */

	name = kmem_zalloc(MAXNAMELEN, KM_SLEEP);

	if ((error = smb_vop_lookup(*xattrdirvpp, solaris_stream_name, vpp,
	    name, flags, &tmpflgs, rootvp, cr)) != 0) {
		VN_RELE(*xattrdirvpp);
	} else {
		(void) strlcpy(od_name, &(name[SMB_STREAM_PREFIX_LEN]),
		    MAXNAMELEN);
	}

	kmem_free(solaris_stream_name, MAXNAMELEN);
	kmem_free(name, MAXNAMELEN);

	return (error);
}
Example #2
0
/*
 * smb_odir_single_fileinfo
 *
 * Lookup the file identified by od->d_pattern.
 *
 * If the looked up file is a link, we attempt to lookup the link target
 * to use its attributes in place of those of the files's.
 * If we fail to lookup the target of the link we use the original
 * file's attributes.
 * Check if the attributes match the search attributes.
 *
 * Returns: 0 - success
 *     ENOENT - no match
 *      errno - error
 */
static int
smb_odir_single_fileinfo(smb_request_t *sr, smb_odir_t *od,
    smb_fileinfo_t *fileinfo)
{
	int		rc;
	smb_node_t	*fnode, *tgt_node;
	smb_attr_t	attr;
	ino64_t		fid;
	char		*name;
	boolean_t	case_conflict = B_FALSE;
	int		lookup_flags, flags = 0;
	vnode_t		*vp;

	ASSERT(sr);
	ASSERT(sr->sr_magic == SMB_REQ_MAGIC);
	ASSERT(od);
	ASSERT(od->d_magic == SMB_ODIR_MAGIC);

	ASSERT(MUTEX_HELD(&od->d_mutex));
	bzero(fileinfo, sizeof (smb_fileinfo_t));

	rc = smb_fsop_lookup(sr, od->d_cred, 0, od->d_tree->t_snode,
	    od->d_dnode, od->d_pattern, &fnode);
	if (rc != 0)
		return (rc);

	/*
	 * If case sensitive, do a case insensitive smb_vop_lookup to
	 * check for case conflict
	 */
	if (od->d_flags & SMB_ODIR_FLAG_IGNORE_CASE) {
		lookup_flags = SMB_IGNORE_CASE;
		if (od->d_flags & SMB_ODIR_FLAG_CATIA)
			lookup_flags |= SMB_CATIA;

		rc = smb_vop_lookup(od->d_dnode->vp, fnode->od_name, &vp,
		    NULL, lookup_flags, &flags, od->d_tree->t_snode->vp,
		    NULL, od->d_cred);
		if (rc != 0)
			return (rc);
		VN_RELE(vp);

		if (flags & ED_CASE_CONFLICT)
			case_conflict = B_TRUE;
	}

	bzero(&attr, sizeof (attr));
	attr.sa_mask = SMB_AT_ALL;
	rc = smb_node_getattr(sr, fnode, zone_kcred(), NULL, &attr);
	if (rc != 0) {
		smb_node_release(fnode);
		return (rc);
	}


	/* follow link to get target node & attr */
	if (smb_node_is_symlink(fnode) &&
	    smb_odir_lookup_link(sr, od, fnode->od_name, &tgt_node)) {
		smb_node_release(fnode);
		fnode = tgt_node;
		attr.sa_mask = SMB_AT_ALL;
		rc = smb_node_getattr(sr, fnode, zone_kcred(), NULL, &attr);
		if (rc != 0) {
			smb_node_release(fnode);
			return (rc);
		}
	}

	/* check search attributes */
	if (!smb_sattr_check(attr.sa_dosattr, od->d_sattr)) {
		smb_node_release(fnode);
		return (ENOENT);
	}

	name = fnode->od_name;
	if (od->d_flags & SMB_ODIR_FLAG_SHORTNAMES) {
		fid = attr.sa_vattr.va_nodeid;
		if (case_conflict || smb_needs_mangled(name)) {
			smb_mangle(name, fid, fileinfo->fi_shortname,
			    SMB_SHORTNAMELEN);
		}
		if (case_conflict)
			name = fileinfo->fi_shortname;
	}

	(void) strlcpy(fileinfo->fi_name, name, sizeof (fileinfo->fi_name));

	fileinfo->fi_dosattr = attr.sa_dosattr;
	fileinfo->fi_nodeid = attr.sa_vattr.va_nodeid;
	fileinfo->fi_size = attr.sa_vattr.va_size;
	fileinfo->fi_alloc_size = attr.sa_allocsz;
	fileinfo->fi_atime = attr.sa_vattr.va_atime;
	fileinfo->fi_mtime = attr.sa_vattr.va_mtime;
	fileinfo->fi_ctime = attr.sa_vattr.va_ctime;
	if (attr.sa_crtime.tv_sec)
		fileinfo->fi_crtime = attr.sa_crtime;
	else
		fileinfo->fi_crtime = attr.sa_vattr.va_mtime;

	smb_node_release(fnode);
	return (0);
}