Ejemplo n.º 1
0
/*
 * smb_vop_rename()
 *
 * The rename is for files in the same tree (identical TID) only.
 */
int
smb_vop_rename(vnode_t *from_dvp, char *from_name, vnode_t *to_dvp,
    char *to_name, int flags, cred_t *cr)
{
	int error;
	int option_flags = 0;
	char *from, *to, *fbuf, *tbuf;

	if (flags & SMB_IGNORE_CASE)
		option_flags = FIGNORECASE;

	if (flags & SMB_CATIA) {
		tbuf = kmem_zalloc(MAXNAMELEN, KM_SLEEP);
		to = smb_vop_catia_v5tov4(to_name, tbuf, MAXNAMELEN);
		if (strchr(to, '/') != NULL) {
			kmem_free(tbuf, MAXNAMELEN);
			return (EILSEQ);
		}

		fbuf = kmem_zalloc(MAXNAMELEN, KM_SLEEP);
		from = smb_vop_catia_v5tov4(from_name, fbuf, MAXNAMELEN);

		error = VOP_RENAME(from_dvp, from, to_dvp, to, cr,
		    &smb_ct, option_flags);

		kmem_free(tbuf, MAXNAMELEN);
		kmem_free(fbuf, MAXNAMELEN);
		return (error);
	}

	error = VOP_RENAME(from_dvp, from_name, to_dvp, to_name, cr,
	    &smb_ct, option_flags);

	return (error);
}
Ejemplo n.º 2
0
int
smb_vop_mkdir(vnode_t *dvp, char *name, smb_attr_t *attr, vnode_t **vpp,
    int flags, cred_t *cr, vsecattr_t *vsap)
{
	int error;
	int option_flags = 0;
	xvattr_t xvattr;
	vattr_t *vap;
	char *np = name;
	char namebuf[MAXNAMELEN];

	if (flags & SMB_IGNORE_CASE)
		option_flags = FIGNORECASE;

	attr->sa_vattr.va_mask = 0;

	if (vfs_has_feature(dvp->v_vfsp, VFSFT_XVATTR)) {
		smb_vop_setup_xvattr(attr, &xvattr);
		vap = &xvattr.xva_vattr;
	} else {
		smb_sa_to_va_mask(attr->sa_mask, &attr->sa_vattr.va_mask);
		vap = &attr->sa_vattr;
	}

	if (flags & SMB_CATIA) {
		np = smb_vop_catia_v5tov4(name, namebuf, sizeof (namebuf));
		if (strchr(np, '/') != NULL)
			return (EILSEQ);
	}

	error = VOP_MKDIR(dvp, np, vap, vpp, cr, &smb_ct, option_flags, vsap);

	return (error);
}
Ejemplo n.º 3
0
/*
 * smb_vop_link(target-dir-vp, source-file-vp, target-name)
 *
 * Create a link - same tree (identical TID) only.
 */
int
smb_vop_link(vnode_t *to_dvp, vnode_t *from_vp, char *to_name,
    int flags, cred_t *cr)
{
	int option_flags = 0;
	char *np, *buf;
	int rc;

	if (flags & SMB_IGNORE_CASE)
		option_flags = FIGNORECASE;

	if (flags & SMB_CATIA) {
		buf = kmem_zalloc(MAXNAMELEN, KM_SLEEP);
		np = smb_vop_catia_v5tov4(to_name, buf, MAXNAMELEN);
		if (strchr(np, '/') != NULL) {
			kmem_free(buf, MAXNAMELEN);
			return (EILSEQ);
		}

		rc = VOP_LINK(to_dvp, from_vp, np, cr, &smb_ct, option_flags);
		kmem_free(buf, MAXNAMELEN);
		return (rc);
	}

	rc = VOP_LINK(to_dvp, from_vp, to_name, cr, &smb_ct, option_flags);
	return (rc);
}
Ejemplo n.º 4
0
/*
 * CATIA Translation of a pathname component prior to passing it to lookuppnvp
 *
 * If the translated component name contains a '/' NULL is returned.
 * The caller should treat this as error EILSEQ. It is not valid to
 * have a directory name with a '/'.
 */
static char *
smb_pathname_catia_v5tov4(smb_request_t *sr, char *name,
    char *namebuf, int buflen)
{
	char *namep;

	if (SMB_TREE_SUPPORTS_CATIA(sr)) {
		namep = smb_vop_catia_v5tov4(name, namebuf, buflen);
		if (strchr(namep, '/') != NULL)
			return (NULL);
		return (namep);
	}

	return (name);
}
Ejemplo n.º 5
0
/*
 * smb_vop_rmdir()
 *
 * Only simple rmdir supported, consistent with NT semantics
 * (can only remove an empty directory).
 *
 * The third argument to VOP_RMDIR  is the current directory of
 * the process.  It allows rmdir wants to EINVAL if one tries to
 * remove ".".  Since SMB servers do not know what their clients'
 * current directories are, we fake it by supplying a vnode known
 * to exist and illegal to remove (rootdir).
 */
int
smb_vop_rmdir(vnode_t *dvp, char *name, int flags, cred_t *cr)
{
	int error;
	int option_flags = 0;
	char *np = name;
	char namebuf[MAXNAMELEN];

	if (flags & SMB_IGNORE_CASE)
		option_flags = FIGNORECASE;

	if (flags & SMB_CATIA)
		np = smb_vop_catia_v5tov4(name, namebuf, sizeof (namebuf));

	error = VOP_RMDIR(dvp, np, rootdir, cr, &smb_ct, option_flags);
	return (error);
}
Ejemplo n.º 6
0
/*
 * smb_vop_lookup
 *
 * dvp:		directory vnode (in)
 * name:	name of file to be looked up (in)
 * vpp:		looked-up vnode (out)
 * od_name:	on-disk name of file (out).
 *		This parameter is optional.  If a pointer is passed in, it
 * 		must be allocated with MAXNAMELEN bytes
 * rootvp:	vnode of the tree root (in)
 *		This parameter is always passed in non-NULL except at the time
 *		of share set up.
 * direntflags:	dirent flags returned from VOP_LOOKUP
 */
int
smb_vop_lookup(
    vnode_t		*dvp,
    char		*name,
    vnode_t		**vpp,
    char		*od_name,
    int			flags,
    int			*direntflags,
    vnode_t		*rootvp,
    cred_t		*cr)
{
	int error = 0;
	int option_flags = 0;
	pathname_t rpn;
	char *np = name;
	char namebuf[MAXNAMELEN];

	if (*name == '\0')
		return (EINVAL);

	ASSERT(vpp);
	*vpp = NULL;
	*direntflags = 0;

	if ((name[0] == '.') && (name[1] == '.') && (name[2] == 0)) {
		if (rootvp && (dvp == rootvp)) {
			VN_HOLD(dvp);
			*vpp = dvp;
			return (0);
		}

		if (dvp->v_flag & VROOT) {
			vfs_t *vfsp;
			vnode_t *cvp = dvp;

			/*
			 * Set dvp and check for races with forced unmount
			 * (see lookuppnvp())
			 */

			vfsp = cvp->v_vfsp;
			vfs_rlock_wait(vfsp);
			if (((dvp = cvp->v_vfsp->vfs_vnodecovered) == NULL) ||
			    (cvp->v_vfsp->vfs_flag & VFS_UNMOUNTED)) {
				vfs_unlock(vfsp);
				return (EIO);
			}
			vfs_unlock(vfsp);
		}
	}

	if (flags & SMB_IGNORE_CASE)
		option_flags = FIGNORECASE;

	if (flags & SMB_CATIA)
		np = smb_vop_catia_v5tov4(name, namebuf, sizeof (namebuf));

	pn_alloc(&rpn);

	error = VOP_LOOKUP(dvp, np, vpp, NULL, option_flags, NULL, cr,
	    &smb_ct, direntflags, &rpn);

	if ((error == 0) && od_name) {
		bzero(od_name, MAXNAMELEN);
		np = (option_flags == FIGNORECASE) ? rpn.pn_buf : name;

		if (flags & SMB_CATIA)
			smb_vop_catia_v4tov5(np, od_name, MAXNAMELEN);
		else
			(void) strlcpy(od_name, np, MAXNAMELEN);
	}

	pn_free(&rpn);
	return (error);
}