diff options
| author | Robert Watson <rwatson@FreeBSD.org> | 2000-01-15 19:44:27 +0000 | 
|---|---|---|
| committer | Robert Watson <rwatson@FreeBSD.org> | 2000-01-15 19:44:27 +0000 | 
| commit | 515d7c92d3d615e260c93049e2b046aee9be39e8 (patch) | |
| tree | 500090bbf12bfaafe1b7f118e2e6162ac38a47b1 /lib/libc/posix1e/acl_to_text.c | |
| parent | ee32b1da10fef2f876383f2d62c97785b54be8f9 (diff) | |
Notes
Diffstat (limited to 'lib/libc/posix1e/acl_to_text.c')
| -rw-r--r-- | lib/libc/posix1e/acl_to_text.c | 244 | 
1 files changed, 244 insertions, 0 deletions
| diff --git a/lib/libc/posix1e/acl_to_text.c b/lib/libc/posix1e/acl_to_text.c new file mode 100644 index 000000000000..566a5073c28f --- /dev/null +++ b/lib/libc/posix1e/acl_to_text.c @@ -0,0 +1,244 @@ +/*- + * Copyright (c) 1999 Robert N. M. Watson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + *    notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + *    notice, this list of conditions and the following disclaimer in the + *    documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + *	$FreeBSD$ + */ +/* + * acl_to_text - return a text string with a text representation of the acl + * in it. + */ + +#include <sys/types.h> +#include <sys/acl.h> +#include <sys/errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <utmp.h> + +#include "acl_support.h" + + +/* + * acl_to_text - generate a text form of an acl + * spec says nothing about output ordering, so leave in acl order + * + * For the time-being, reject the printing of ACLs that aren't an + * understood semantic.  Later on, we might want to try and have a + * generic printing mechanism... + */ +char * +acl_to_text(acl_t acl, ssize_t *len_p) +{ +	char	*buf, *tmpbuf; +	char	name_buf[UT_NAMESIZE+1]; +	char	perm_buf[ACL_STRING_PERM_MAXSIZE+1], +		effective_perm_buf[ACL_STRING_PERM_MAXSIZE+1]; +	int	i, error, len; +	uid_t	ae_id; +	acl_tag_t	ae_tag; +	acl_perm_t	ae_perm, effective_perm, mask_perm; + +	if (!acl_posix1e(acl)) { +		errno = EINVAL; +		return (0); +	} + +	buf = strdup(""); + +	mask_perm = ACL_PERM_BITS;	/* effective is regular if no mask */ +	for (i = 0; i < acl->acl_cnt; i++) +		if (acl->acl_entry[i].ae_tag == ACL_MASK)  +			mask_perm = acl->acl_entry[i].ae_perm; + +	for (i = 0; i < acl->acl_cnt; i++) { +		ae_tag = acl->acl_entry[i].ae_tag; +		ae_id = acl->acl_entry[i].ae_id; +		ae_perm = acl->acl_entry[i].ae_perm; + +		switch(ae_tag) { +		case ACL_USER_OBJ: +			error = acl_perm_to_string(ae_perm, +			    ACL_STRING_PERM_MAXSIZE+1, perm_buf); +			if (error) +				goto error_label; +			len = asprintf(&tmpbuf, "%suser::%s\n", buf, +			    perm_buf); +			if (len == -1) { +				errno = ENOMEM; +				goto error_label; +			} +			free(buf); +			buf = tmpbuf; +			break; + +		case ACL_USER: +			error = acl_perm_to_string(ae_perm, +			    ACL_STRING_PERM_MAXSIZE+1, perm_buf); +			if (error) +				goto error_label; + +			error = acl_id_to_name(ae_tag, ae_id, UT_NAMESIZE+1, +			    name_buf); +			if (error) +				goto error_label; + +			effective_perm = ae_perm & mask_perm; +			if (effective_perm != ae_perm) { +				error = acl_perm_to_string(effective_perm, +				    ACL_STRING_PERM_MAXSIZE+1, +				    effective_perm_buf); +				if (error) +					goto error_label; +				len = asprintf(&tmpbuf, "%suser:%s:%s\t\t# " +				    "effective: %s\n", +				    buf, name_buf, perm_buf, +				    effective_perm_buf); +			} else { +				len = asprintf(&tmpbuf, "%suser:%s:%s\n", buf, +				    name_buf, perm_buf); +			} +			if (len == -1) { +				errno = ENOMEM; +				goto error_label; +			} +			free(buf); +			buf = tmpbuf; +			break; + +		case ACL_GROUP_OBJ: +			error = acl_perm_to_string(ae_perm, +			    ACL_STRING_PERM_MAXSIZE+1, perm_buf); +			if (error) +				goto error_label; + +			effective_perm = ae_perm & mask_perm; +			if (effective_perm != ae_perm) { +				error = acl_perm_to_string(effective_perm, +				    ACL_STRING_PERM_MAXSIZE+1, +				    effective_perm_buf); +				if (error) +					goto error_label; +				len = asprintf(&tmpbuf, "%sgroup::%s\t\t# " +				    "effective: %s\n", +				    buf, perm_buf, effective_perm_buf); +			} else { +				len = asprintf(&tmpbuf, "%sgroup::%s\n", buf, +				    perm_buf); +			} +			if (len == -1) { +				errno = ENOMEM; +				goto error_label; +			} +			free(buf); +			buf = tmpbuf; +			break; + +		case ACL_GROUP: +			error = acl_perm_to_string(ae_perm, +			    ACL_STRING_PERM_MAXSIZE+1, perm_buf); +			if (error) +				goto error_label; + +			error = acl_id_to_name(ae_tag, ae_id, UT_NAMESIZE+1, +			    name_buf); +			if (error) +				goto error_label; + +			effective_perm = ae_perm & mask_perm; +			if (effective_perm != ae_perm) { +				error = acl_perm_to_string(effective_perm, +				    ACL_STRING_PERM_MAXSIZE+1, +				    effective_perm_buf); +				if (error) +					goto error_label; +				len = asprintf(&tmpbuf, "%sgroup::%s\t\t# " +				    "effective: %s\n", +				    buf, perm_buf, effective_perm_buf); +			} else { +				len = asprintf(&tmpbuf, "%sgroup:%s:%s\n", buf, +				    name_buf, perm_buf); +			} +			if (len == -1) { +				errno = ENOMEM; +				goto error_label; +			} +			free(buf); +			buf = tmpbuf; +			break; + +		case ACL_MASK: +			error = acl_perm_to_string(ae_perm, +			    ACL_STRING_PERM_MAXSIZE+1, perm_buf); +			if (error) +				goto error_label; + +			len = asprintf(&tmpbuf, "%smask::%s\n", buf, +			    perm_buf); +			if (len == -1) { +				errno = ENOMEM; +				goto error_label; +			} +			free(buf); +			buf = tmpbuf; +			break; + +		case ACL_OTHER: +			error = acl_perm_to_string(ae_perm, +			    ACL_STRING_PERM_MAXSIZE+1, perm_buf); +			if (error) +				goto error_label; + +			len = asprintf(&tmpbuf, "%sother::%s\n", buf, +			    perm_buf); +			if (len == -1) { +				errno = ENOMEM; +				goto error_label; +			} +			free(buf); +			buf = tmpbuf; +			break; + +		default: +			free(buf); +			errno = EINVAL; +			return (0); +		} +	} + +	if (len_p) { +		*len_p = strlen(buf); +	} +	return (buf); + +error_label: +	/* jump to here sets errno already, we just clean up */ +	if (buf) free(buf); +	return (0); +} + + + + | 
