acl_branding.c revision 272461
162587Sitojun/*-
262587Sitojun * Copyright (c) 2008, 2009 Edward Tomasz Napiera��a <trasz@FreeBSD.org>
362587Sitojun * All rights reserved.
452904Sshin *
552904Sshin * Redistribution and use in source and binary forms, with or without
652904Sshin * modification, are permitted provided that the following conditions
753541Sshin * are met:
852904Sshin * 1. Redistributions of source code must retain the above copyright
952904Sshin *    notice, this list of conditions and the following disclaimer.
1052904Sshin * 2. Redistributions in binary form must reproduce the above copyright
1152904Sshin *    notice, this list of conditions and the following disclaimer in the
1252904Sshin *    documentation and/or other materials provided with the distribution.
1352904Sshin *
1452904Sshin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1552904Sshin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1652904Sshin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1752904Sshin * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1852904Sshin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1953541Sshin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2052904Sshin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2152904Sshin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2252904Sshin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2352904Sshin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2452904Sshin * SUCH DAMAGE.
2552904Sshin */
2652904Sshin
2752904Sshin#include <sys/cdefs.h>
2852904Sshin__FBSDID("$FreeBSD: releng/10.1/lib/libc/posix1e/acl_branding.c 208034 2010-05-13 16:44:27Z trasz $");
2952904Sshin
3052904Sshin#include <assert.h>
3152904Sshin#include <errno.h>
3252904Sshin#include <sys/acl.h>
3352904Sshin
3452904Sshin#include "acl_support.h"
3552904Sshin
3652904Sshin/*
3752904Sshin * An ugly detail of the implementation - fortunately not visible
3852904Sshin * to the API users - is the "branding": libc needs to keep track
3952904Sshin * of what "brand" ACL is: NFSv4, POSIX.1e or unknown.  It happens
4052904Sshin * automatically - for example, during acl_get_file(3) ACL gets
4152904Sshin * branded according to the "type" argument; during acl_set_permset
4252904Sshin * ACL, if its brand is unknown it gets branded as NFSv4 if any of the
4352904Sshin * NFSv4 permissions that are not valid for POSIX.1e ACL are set etc.
4452904Sshin * Branding information is used for printing out the ACL (acl_to_text(3)),
4552904Sshin * veryfying acl_set_whatever arguments (checking against setting
4652904Sshin * bits that are valid only for NFSv4 in ACL branded as POSIX.1e) etc.
4752904Sshin */
4852904Sshin
4952904Sshinstatic acl_t
5052904Sshinentry2acl(acl_entry_t entry)
5152904Sshin{
5252904Sshin	acl_t aclp;
5352904Sshin
5452904Sshin	aclp = (acl_t)(((long)entry >> _ACL_T_ALIGNMENT_BITS) << _ACL_T_ALIGNMENT_BITS);
5552904Sshin
5652904Sshin	return (aclp);
5752904Sshin}
5852904Sshin
5952904Sshin/*
6052904Sshin * Return brand of an ACL.
6152904Sshin */
6252904Sshinint
6352904Sshin_acl_brand(const acl_t acl)
6452904Sshin{
6552904Sshin
6652904Sshin	return (acl->ats_brand);
6752904Sshin}
6862587Sitojun
6957120Sshinint
7057120Sshin_entry_brand(const acl_entry_t entry)
7157120Sshin{
7262587Sitojun
7362587Sitojun	return (_acl_brand(entry2acl(entry)));
7462587Sitojun}
7562587Sitojun
7652904Sshin/*
7752904Sshin * Return 1, iff branding ACL as "brand" is ok.
7852904Sshin */
7952904Sshinint
8052904Sshin_acl_brand_may_be(const acl_t acl, int brand)
8152904Sshin{
8262587Sitojun
8362587Sitojun	if (_acl_brand(acl) == ACL_BRAND_UNKNOWN)
8452904Sshin		return (1);
8552904Sshin
8652904Sshin	if (_acl_brand(acl) == brand)
8752904Sshin		return (1);
8852904Sshin
8952904Sshin	return (0);
9052904Sshin}
9152904Sshin
9252904Sshinint
9352904Sshin_entry_brand_may_be(const acl_entry_t entry, int brand)
9462587Sitojun{
9552904Sshin
9652904Sshin	return (_acl_brand_may_be(entry2acl(entry), brand));
9752904Sshin}
9852904Sshin
9952904Sshin/*
10052904Sshin * Brand ACL as "brand".
10152904Sshin */
10252904Sshinvoid
10352904Sshin_acl_brand_as(acl_t acl, int brand)
10452904Sshin{
10552904Sshin
10652904Sshin	assert(_acl_brand_may_be(acl, brand));
10752904Sshin
10852904Sshin	acl->ats_brand = brand;
10952904Sshin}
11052904Sshin
11152904Sshinvoid
11252904Sshin_entry_brand_as(const acl_entry_t entry, int brand)
11352904Sshin{
11452904Sshin
11552904Sshin	_acl_brand_as(entry2acl(entry), brand);
11652904Sshin}
11752904Sshin
11852904Sshinint
11952904Sshin_acl_type_not_valid_for_acl(const acl_t acl, acl_type_t type)
12052904Sshin{
12152904Sshin
12252904Sshin	switch (_acl_brand(acl)) {
12352904Sshin	case ACL_BRAND_NFS4:
12462587Sitojun		if (type == ACL_TYPE_NFS4)
12562587Sitojun			return (0);
12662587Sitojun		break;
12752904Sshin
12852904Sshin	case ACL_BRAND_POSIX:
12952904Sshin		if (type == ACL_TYPE_ACCESS || type == ACL_TYPE_DEFAULT)
13062587Sitojun			return (0);
13152904Sshin		break;
13262587Sitojun
13362587Sitojun	case ACL_BRAND_UNKNOWN:
13462587Sitojun		return (0);
13552904Sshin	}
13652904Sshin
13762587Sitojun	return (-1);
13852904Sshin}
13952904Sshin
14052904Sshinvoid
14152904Sshin_acl_brand_from_type(acl_t acl, acl_type_t type)
14262587Sitojun{
14362587Sitojun
14452904Sshin	switch (type) {
14552904Sshin	case ACL_TYPE_NFS4:
14662587Sitojun		_acl_brand_as(acl, ACL_BRAND_NFS4);
14762587Sitojun		break;
14852904Sshin	case ACL_TYPE_ACCESS:
14952904Sshin	case ACL_TYPE_DEFAULT:
15062587Sitojun		_acl_brand_as(acl, ACL_BRAND_POSIX);
15152904Sshin		break;
15252904Sshin	default:
15352904Sshin		/* XXX: What to do here? */
15452904Sshin		break;
15552904Sshin	}
15652904Sshin}
15752904Sshin
15862587Sitojunint
15962587Sitojunacl_get_brand_np(acl_t acl, int *brand_p)
16052904Sshin{
16162587Sitojun
16252904Sshin	if (acl == NULL || brand_p == NULL) {
16362587Sitojun		errno = EINVAL;
16452904Sshin		return (-1);
16562587Sitojun	}
16652904Sshin	*brand_p = _acl_brand(acl);
16752904Sshin
16852904Sshin	return (0);
16952904Sshin}
17052904Sshin