Example #1
0
struct object_tree * insert_in_object_tree(TALLOC_CTX *mem_ctx,
					   const struct GUID *schemaGUIDID,
					   const struct GUID *attributeSecurityGUID,
					   uint32_t init_access,
					   struct object_tree *root)
{
	struct object_tree * parent = NULL;
	struct object_tree * new_node;

	new_node = talloc(mem_ctx, struct object_tree);
	if (!new_node)
		return NULL;
	memset(new_node, 0, sizeof(struct object_tree));
	new_node->remaining_access = init_access;

	if (!root){
		memcpy(&new_node->guid, schemaGUIDID, sizeof(struct GUID));
		return new_node;
	}

	if (attributeSecurityGUID && !GUID_all_zero(attributeSecurityGUID)){
		parent = get_object_tree_by_GUID(root, attributeSecurityGUID);
		memcpy(&new_node->guid, attributeSecurityGUID, sizeof(struct GUID));
	}
	else
		memcpy(&new_node->guid, schemaGUIDID, sizeof(struct GUID));

	if (!parent)
		parent = root;

	new_node->remaining_access = init_access;
	DLIST_ADD(parent, new_node);
	return new_node;
}
Example #2
0
/* search by GUID */
struct object_tree * get_object_tree_by_GUID(struct object_tree *root,
					     const struct GUID *guid)
{
	struct object_tree *p;
	struct object_tree *result = NULL;

	if (!root || GUID_equal(&root->guid, guid))
		result = root;
	else{
	for (p = root->children; p != NULL; p = p->next)
		if ((result = get_object_tree_by_GUID(p, guid)))
			break;
	}

	return result;
}
NTSTATUS sec_access_check_ds(const struct security_descriptor *sd,
			     const struct security_token *token,
			     uint32_t access_desired,
			     uint32_t *access_granted,
			     struct object_tree *tree,
			     struct dom_sid *replace_sid)
{
	uint32_t i;
	uint32_t bits_remaining;
	struct object_tree *node;
	const struct GUID *type;
	struct dom_sid self_sid;

	dom_sid_parse(SID_NT_SELF, &self_sid);

	*access_granted = access_desired;
	bits_remaining = access_desired;

	/* handle the maximum allowed flag */
	if (access_desired & SEC_FLAG_MAXIMUM_ALLOWED) {
		access_desired |= access_check_max_allowed(sd, token);
		access_desired &= ~SEC_FLAG_MAXIMUM_ALLOWED;
		*access_granted = access_desired;
		bits_remaining = access_desired;
	}

	if (access_desired & SEC_FLAG_SYSTEM_SECURITY) {
		if (security_token_has_privilege(token, SEC_PRIV_SECURITY)) {
			bits_remaining &= ~SEC_FLAG_SYSTEM_SECURITY;
		} else {
			return NT_STATUS_PRIVILEGE_NOT_HELD;
		}
	}

	/* the owner always gets SEC_STD_WRITE_DAC and SEC_STD_READ_CONTROL */
	if ((bits_remaining & (SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL)) &&
	    security_token_has_sid(token, sd->owner_sid)) {
		bits_remaining &= ~(SEC_STD_WRITE_DAC|SEC_STD_READ_CONTROL);
	}

	/* TODO: remove this, as it is file server specific */
	if ((bits_remaining & SEC_RIGHTS_PRIV_RESTORE) &&
	    security_token_has_privilege(token, SEC_PRIV_RESTORE)) {
		bits_remaining &= ~(SEC_RIGHTS_PRIV_RESTORE);
	}
	if ((bits_remaining & SEC_RIGHTS_PRIV_BACKUP) &&
	    security_token_has_privilege(token, SEC_PRIV_BACKUP)) {
		bits_remaining &= ~(SEC_RIGHTS_PRIV_BACKUP);
	}

	/* a NULL dacl allows access */
	if ((sd->type & SEC_DESC_DACL_PRESENT) && sd->dacl == NULL) {
		*access_granted = access_desired;
		return NT_STATUS_OK;
	}

	if (sd->dacl == NULL) {
		goto done;
	}

	/* check each ace in turn. */
	for (i=0; bits_remaining && i < sd->dacl->num_aces; i++) {
		struct dom_sid *trustee;
		struct security_ace *ace = &sd->dacl->aces[i];

		if (ace->flags & SEC_ACE_FLAG_INHERIT_ONLY) {
			continue;
		}

		if (dom_sid_equal(&ace->trustee, &self_sid) && replace_sid) {
			trustee = replace_sid;
		} else {
			trustee = &ace->trustee;
		}

		if (!security_token_has_sid(token, trustee)) {
			continue;
		}

		switch (ace->type) {
		case SEC_ACE_TYPE_ACCESS_ALLOWED:
			if (tree) {
				object_tree_modify_access(tree, ace->access_mask);
			}

			bits_remaining &= ~ace->access_mask;
			break;
		case SEC_ACE_TYPE_ACCESS_DENIED:
			if (bits_remaining & ace->access_mask) {
				return NT_STATUS_ACCESS_DENIED;
			}
			break;
		case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
		case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT:
			/*
			 * check only in case we have provided a tree,
			 * the ACE has an object type and that type
			 * is in the tree
			 */
			type = get_ace_object_type(ace);

			if (!tree) {
				continue;
			}

			if (!type) {
				node = tree;
			} else {
				if (!(node = get_object_tree_by_GUID(tree, type))) {
					continue;
				}
			}

			if (ace->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT) {
				object_tree_modify_access(node, ace->access_mask);
				if (node->remaining_access == 0) {
					return NT_STATUS_OK;
				}
			} else {
				if (node->remaining_access & ace->access_mask){
					return NT_STATUS_ACCESS_DENIED;
				}
			}
			break;
		default:	/* Other ACE types not handled/supported */
			break;
		}
	}

done:
	if (bits_remaining != 0) {
		return NT_STATUS_ACCESS_DENIED;
	}

	return NT_STATUS_OK;
}