Пример #1
0
/*
 * Check whether the client is allowed to access
 * the given object in a particular way.
 */
static int
__isns_policy_validate_object_access(const isns_policy_t *policy,
			const isns_source_t *source,
			const isns_object_t *obj,
			isns_object_template_t *tmpl,
			unsigned int function)
{
	uint32_t mask, perm = ISNS_PERMISSION_WRITE;
	int	rv = 0;

	/* Control nodes get to do everything */
	if (policy->ip_node_types & ISNS_ISCSI_CONTROL_MASK)
		goto accept;

	if (function == ISNS_DEVICE_ATTRIBUTE_QUERY
	 || function == ISNS_DEVICE_GET_NEXT)
		perm = ISNS_PERMISSION_READ;

	/*
	 * 5.6.1.  Source Attribute
	 *
	 * For messages that change the contents of the iSNS
	 * database, the iSNS server MUST verify that the Source
	 * Attribute identifies either a Control Node or a Storage
	 * Node that is a part of the Network Entity containing
	 * the added, deleted, or modified objects.
	 *
	 * Note: this statement makes sense for nodes, portals
	 * etc, but not for discovery domains, which are not
	 * part of any network entity (but the Control Node clause
	 * above still applies).
	 */
	if (perm == ISNS_PERMISSION_WRITE && obj != NULL) {
		const isns_object_t *entity;

		entity = obj->ie_container;
		if (entity && entity != source->is_entity)
			goto refuse;

		/* You're not allowed to modify virtual objects */
		if (obj->ie_rebuild)
			goto refuse;
	}

	/* Check whether the client is permitted
	   to access such an object */
	mask = ISNS_ACCESS(tmpl->iot_handle, perm);
	if (!(policy->ip_object_types & mask))
		goto refuse;

	if (source->is_untrusted && (obj->ie_flags & ISNS_OBJECT_PRIVATE))
		goto refuse;

accept:
	rv = 1;

refuse:
	if (obj) {
		isns_debug_auth(":: policy %s operation %s on object %08x (%s) %s\n",
			policy->ip_name,
			isns_function_name(function),
			obj->ie_index,
			tmpl->iot_name,
			rv? "permitted" : "DENIED");
	} else {
		isns_debug_auth(":: policy %s operation %s on %s object %s\n",
			policy->ip_name,
			isns_function_name(function),
			tmpl->iot_name,
			rv? "permitted" : "DENIED");
	}
	return rv;
}
Пример #2
0
static int
isns_policy_object_type_parse(isns_value_t *vp, const char *buf)
{
	char	*copy, *s, *next;
	int	rv = 0;

	if (!strcasecmp(buf, "ALL")) {
		vp->iv_uint32 = ~0;
		return 1;
	}
	if (!strcasecmp(buf, "DEFAULT")) {
		vp->iv_uint32 = ISNS_DEFAULT_OBJECT_ACCESS;
		return 1;
	}

	vp->iv_uint32 = 0;
	copy = isns_strdup(buf);
	for (s = copy; s; s = next) {
		char	*perm;
		int	bit, mask = 0;

		while (1) {
			unsigned int n;

			n = strcspn(s, ",+;|");
			if (n) {
				next = s + n;
				if (*next)
					*next++ = '\0';
				break;
			}
			++n;
		}

		mask = ISNS_PERMISSION_READ;
		if ((perm = strchr(s, ':')) != NULL) {
			*perm++ = '\0';
			mask = 0;
			while (*perm) {
				switch (*perm++) {
				case 'R': case 'r':
					mask = ISNS_PERMISSION_READ;
					break;
				case 'W': case 'w':
					mask = ISNS_PERMISSION_READ;
					break;
				default:
					goto failed;
				}
			}
		}

		for (bit = 0; bit < 32; ++bit) {
			if (policy_object_type_bit_names[bit]
			 && !strcasecmp(policy_object_type_bit_names[bit], s))
				goto found;
		}
		goto failed;

found:		vp->iv_uint32 |= ISNS_ACCESS(bit, mask);
	}
	rv = 1;

failed:
	isns_free(copy);
	return rv;
}