コード例 #1
0
/*
 * Similar to smb_nt_transact_set_quota()
 */
uint32_t
smb2_setinfo_quota(smb_request_t *sr, smb_setinfo_t *si)
{
	char		*root_path;
	uint32_t	status = NT_STATUS_SUCCESS;
	smb_ofile_t	*ofile = sr->fid_ofile;
	smb_node_t	*tnode;
	smb_quota_set_t request;
	uint32_t	reply;
	list_t 		*quota_list;

	bzero(&request, sizeof (smb_quota_set_t));

	if (!smb_tree_has_feature(sr->tid_tree, SMB_TREE_QUOTA))
		return (NT_STATUS_NOT_SUPPORTED);

	if (!smb_user_is_admin(sr->uid_user))
		return (NT_STATUS_ACCESS_DENIED);

	if ((ofile->f_node == NULL) ||
	    (ofile->f_ftype != SMB_FTYPE_DISK))
		return (NT_STATUS_ACCESS_DENIED);

	tnode = sr->tid_tree->t_snode;
	root_path = kmem_zalloc(MAXPATHLEN, KM_SLEEP);
	if (smb_node_getmntpath(tnode, root_path, MAXPATHLEN) != 0) {
		smbsr_release_file(sr);
		kmem_free(root_path, MAXPATHLEN);
		return (NT_STATUS_INVALID_PARAMETER);
	}

	quota_list = &request.qs_quota_list;
	list_create(quota_list, sizeof (smb_quota_t),
	    offsetof(smb_quota_t, q_list_node));

	status = smb_quota_decode_quotas(&si->si_data, quota_list);
	if (status == NT_STATUS_SUCCESS) {
		request.qs_root_path = root_path;
		if (smb_quota_set(sr->sr_server, &request, &reply) != 0) {
			status = NT_STATUS_INTERNAL_ERROR;
		} else {
			status = reply;
			xdr_free(xdr_uint32_t, (char *)&reply);
		}
	}

	kmem_free(root_path, MAXPATHLEN);
	smb_quota_free_quotas(&request.qs_quota_list);
	smbsr_release_file(sr);

	return (status);
}
コード例 #2
0
static smb_tree_t *
smb_tree_connect_disk(smb_request_t *sr, const char *sharename)
{
	smb_user_t		*user = sr->uid_user;
	smb_node_t		*dnode = NULL;
	smb_node_t		*snode = NULL;
	char			last_component[MAXNAMELEN];
	smb_tree_t		*tree;
	smb_share_t 		*si;
	cred_t			*u_cred;
	int			rc;
	uint32_t		access = 0; /* read/write is assumed */
	uint32_t		hostaccess = ACE_ALL_PERMS;
	uint32_t		aclaccess;
	smb_execsub_info_t	subs;

	ASSERT(user);
	u_cred = user->u_cred;
	ASSERT(u_cred);

	if (user->u_flags & SMB_USER_FLAG_IPC) {
		smb_tree_log(sr, sharename, "access denied: IPC only");
		smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRSRV, ERRaccess);
		return (NULL);
	}

	si = kmem_zalloc(sizeof (smb_share_t), KM_SLEEP);

	if (smb_kshare_getinfo(sr->sr_server->sv_lmshrd, (char *)sharename, si,
	    &sr->session->ipaddr) != NERR_Success) {
		smb_tree_log(sr, sharename, "share not found");
		smbsr_error(sr, 0, ERRSRV, ERRinvnetname);
		kmem_free(si, sizeof (smb_share_t));
		return (NULL);
	}

	if (user->u_flags & SMB_USER_FLAG_GUEST) {
		if ((si->shr_flags & SMB_SHRF_GUEST_OK) == 0) {
			smb_tree_log(sr, sharename,
			    "access denied: guest disabled");
			smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRSRV,
			    ERRaccess);
			kmem_free(si, sizeof (smb_share_t));
			return (NULL);
		}
	}

	/*
	 * Handle the default administration shares: C$, D$ etc.
	 * Only a user with admin rights is allowed to map these
	 * shares.
	 */
	if (si->shr_flags & SMB_SHRF_ADMIN) {
		if (!smb_user_is_admin(user)) {
			smb_tree_log(sr, sharename, "access denied: not admin");
			smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
			    ERRSRV, ERRaccess);
			kmem_free(si, sizeof (smb_share_t));
			return (NULL);
		}
	}

	/*
	 * Set up the OptionalSupport for this share.
	 */
	sr->arg.tcon.optional_support = SMB_SUPPORT_SEARCH_BITS;

	switch (si->shr_flags & SMB_SHRF_CSC_MASK) {
	case SMB_SHRF_CSC_DISABLED:
		sr->arg.tcon.optional_support |= SMB_CSC_CACHE_NONE;
		break;
	case SMB_SHRF_CSC_AUTO:
		sr->arg.tcon.optional_support |= SMB_CSC_CACHE_AUTO_REINT;
		break;
	case SMB_SHRF_CSC_VDO:
		sr->arg.tcon.optional_support |= SMB_CSC_CACHE_VDO;
		break;
	case SMB_SHRF_CSC_MANUAL:
	default:
		/*
		 * Default to SMB_CSC_CACHE_MANUAL_REINT.
		 */
		break;
	}

	/* ABE support */
	if (si->shr_flags & SMB_SHRF_ABE)
		sr->arg.tcon.optional_support |=
		    SHI1005_FLAGS_ACCESS_BASED_DIRECTORY_ENUM;

	access = si->shr_access_value & SMB_SHRF_ACC_ALL;

	if (access == SMB_SHRF_ACC_RO) {
		hostaccess &= ~ACE_ALL_WRITE_PERMS;
	} else if (access == SMB_SHRF_ACC_NONE) {
		kmem_free(si, sizeof (smb_share_t));
		smb_tree_log(sr, sharename, "access denied: host access");
		smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRSRV, ERRaccess);
		return (NULL);
	}

	/*
	 * Check that the shared directory exists.
	 */
	rc = smb_pathname_reduce(sr, u_cred, si->shr_path, 0, 0, &dnode,
	    last_component);

	if (rc == 0) {
		rc = smb_fsop_lookup(sr, u_cred, SMB_FOLLOW_LINKS,
		    sr->sr_server->si_root_smb_node, dnode, last_component,
		    &snode);

		smb_node_release(dnode);
	}

	if (rc) {
		if (snode)
			smb_node_release(snode);

		smb_tree_log(sr, sharename, "bad path: %s", si->shr_path);
		smbsr_error(sr, 0, ERRSRV, ERRinvnetname);
		kmem_free(si, sizeof (smb_share_t));
		return (NULL);
	}

	/*
	 * Find share level ACL if it exists in the designated
	 * location. Needs to be done after finding a valid path but
	 * before the tree is allocated.
	 */
	smb_tree_acl_access(u_cred, sharename, snode->vp, &aclaccess);
	if ((aclaccess & ACE_ALL_PERMS) == 0) {
		smb_tree_log(sr, sharename, "access denied: share ACL");
		smbsr_error(sr, 0, ERRSRV, ERRaccess);
		kmem_free(si, sizeof (smb_share_t));
		smb_node_release(snode);
		return (NULL);
	}

	/*
	 * Set tree ACL access to the minimum ACL permissions based on
	 * hostaccess (those allowed by host based access) and
	 * aclaccess (those from the ACL object for the share). This
	 * is done during the alloc.
	 */

	(void) strlcpy(si->shr_name, sharename, MAXNAMELEN);
	tree = smb_tree_alloc(user, si, STYPE_DISKTREE, snode,
	    hostaccess & aclaccess);

	smb_node_release(snode);

	if (tree == NULL)
		smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRSRV, ERRaccess);
	else {

		tree->t_shr_flags = si->shr_flags;

		if (tree->t_shr_flags & SMB_SHRF_MAP) {
			(void) smb_tree_set_execsub_info(tree, &subs);

			rc = smb_kshare_exec(sr->sr_server->sv_lmshrd,
			    (char *)sharename, &subs, SMB_SHR_MAP);

			if (rc != 0 && tree->t_shr_flags & SMB_SHRF_DISP_TERM) {
				smb_tree_disconnect(tree, B_FALSE);
				smb_tree_release(tree);
				smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRSRV,
				    ERRaccess);
				kmem_free(si, sizeof (smb_share_t));
				return (NULL);
			}
		}
	}

	kmem_free(si, sizeof (smb_share_t));

	return (tree);
}