Beispiel #1
0
/*
 * smb_pathname_validate
 *
 * Perform basic validation of pn:
 * - If first component of pn->path is ".." -> PATH_SYNTAX_BAD
 * - If there are wildcards in pn->pn_pname -> OBJECT_NAME_INVALID
 * - If fname is "." -> INVALID_OBJECT_NAME
 *
 * On unix .. at the root of a file system links to the root. Thus
 * an attempt to lookup "/../../.." will be the same as looking up "/"
 * CIFs clients expect the above to result in
 * NT_STATUS_OBJECT_PATH_SYNTAX_BAD. It is currently not possible
 * (and questionable if it's desirable) to deal with all cases
 * but paths beginning with \\.. are handled.
 *
 * Returns: B_TRUE if pn is valid,
 *          otherwise returns B_FALSE and sets error status in sr.
 */
boolean_t
smb_pathname_validate(smb_request_t *sr, smb_pathname_t *pn)
{
	char *path = pn->pn_path;

	/* ignore any initial "\\" */
	path += strspn(path, "\\");

	/* If first component of path is ".." -> PATH_SYNTAX_BAD */
	if ((strcmp(path, "..") == 0) || (strncmp(path, "..\\", 3) == 0)) {
		smbsr_error(sr, NT_STATUS_OBJECT_PATH_SYNTAX_BAD,
		    ERRDOS, ERROR_BAD_PATHNAME);
		return (B_FALSE);
	}

	/* If there are wildcards in pn->pn_pname -> OBJECT_NAME_INVALID */
	if (pn->pn_pname && smb_contains_wildcards(pn->pn_pname)) {
		smbsr_error(sr, NT_STATUS_OBJECT_NAME_INVALID,
		    ERRDOS, ERROR_INVALID_NAME);
		return (B_FALSE);
	}

	/* If fname is "." -> INVALID_OBJECT_NAME */
	if (pn->pn_fname && (strcmp(pn->pn_fname, ".") == 0)) {
		smbsr_error(sr, NT_STATUS_OBJECT_NAME_INVALID,
		    ERRDOS, ERROR_PATH_NOT_FOUND);
		return (B_FALSE);
	}

	return (B_TRUE);
}
Beispiel #2
0
/*
 * smb_odir_create
 * Allocate and populate an odir obect and add it to the tree's list.
 */
static uint16_t
smb_odir_create(smb_request_t *sr, smb_node_t *dnode,
    char *pattern, uint16_t sattr, cred_t *cr)
{
	smb_odir_t	*od;
	smb_tree_t	*tree;
	uint16_t	odid;

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

	tree = sr->tid_tree;

	if (smb_idpool_alloc(&tree->t_odid_pool, &odid)) {
		smbsr_error(sr, NT_STATUS_TOO_MANY_OPENED_FILES,
		    ERRDOS, ERROR_TOO_MANY_OPEN_FILES);
		return (0);
	}

	od = kmem_cache_alloc(smb_cache_odir, KM_SLEEP);
	bzero(od, sizeof (smb_odir_t));

	mutex_init(&od->d_mutex, NULL, MUTEX_DEFAULT, NULL);
	od->d_refcnt = 0;
	od->d_state = SMB_ODIR_STATE_OPEN;
	od->d_magic = SMB_ODIR_MAGIC;
	od->d_opened_by_pid = sr->smb_pid;
	od->d_session = tree->t_session;
	od->d_cred = cr;
	/*
	 * grab a ref for od->d_user
	 * released in  smb_odir_delete()
	 */
	smb_user_hold_internal(sr->uid_user);
	od->d_user = sr->uid_user;
	od->d_tree = tree;
	od->d_dnode = dnode;
	smb_node_ref(dnode);
	od->d_odid = odid;
	od->d_sattr = sattr;
	(void) strlcpy(od->d_pattern, pattern, sizeof (od->d_pattern));
	od->d_flags = 0;
	if (smb_contains_wildcards(od->d_pattern))
		od->d_flags |= SMB_ODIR_FLAG_WILDCARDS;
	if (vfs_has_feature(dnode->vp->v_vfsp, VFSFT_DIRENTFLAGS))
		od->d_flags |= SMB_ODIR_FLAG_EDIRENT;
	if (smb_tree_has_feature(tree, SMB_TREE_CASEINSENSITIVE))
		od->d_flags |= SMB_ODIR_FLAG_IGNORE_CASE;
	if (smb_tree_has_feature(tree, SMB_TREE_SHORTNAMES))
		od->d_flags |= SMB_ODIR_FLAG_SHORTNAMES;
	if (SMB_TREE_SUPPORTS_CATIA(sr))
		od->d_flags |= SMB_ODIR_FLAG_CATIA;
	if (SMB_TREE_SUPPORTS_ABE(sr))
		od->d_flags |= SMB_ODIR_FLAG_ABE;
	if (dnode->flags & NODE_XATTR_DIR)
		od->d_flags |= SMB_ODIR_FLAG_XATTR;
	od->d_eof = B_FALSE;

	smb_llist_enter(&tree->t_odir_list, RW_WRITER);
	smb_llist_insert_tail(&tree->t_odir_list, od);
	smb_llist_exit(&tree->t_odir_list);

	atomic_inc_32(&tree->t_session->s_dir_cnt);
	return (odid);
}