acl_to_text.c revision 71142
133965Sjdp/*-
289857Sobrien * Copyright (c) 1999 Robert N. M. Watson
3218822Sdim * All rights reserved.
460484Sobrien *
533965Sjdp * Redistribution and use in source and binary forms, with or without
633965Sjdp * modification, are permitted provided that the following conditions
7130561Sobrien * are met:
833965Sjdp * 1. Redistributions of source code must retain the above copyright
9130561Sobrien *    notice, this list of conditions and the following disclaimer.
10130561Sobrien * 2. Redistributions in binary form must reproduce the above copyright
11130561Sobrien *    notice, this list of conditions and the following disclaimer in the
12130561Sobrien *    documentation and/or other materials provided with the distribution.
1333965Sjdp *
14130561Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15130561Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16130561Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17130561Sobrien * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1833965Sjdp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19130561Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20130561Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21218822Sdim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2233965Sjdp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2333965Sjdp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2433965Sjdp * SUCH DAMAGE.
2533965Sjdp *
2633965Sjdp *	$FreeBSD: head/lib/libc/posix1e/acl_to_text.c 71142 2001-01-17 02:40:39Z rwatson $
2733965Sjdp */
2833965Sjdp/*
2933965Sjdp * acl_to_text - return a text string with a text representation of the acl
3033965Sjdp * in it.
3133965Sjdp */
3289857Sobrien
3389857Sobrien#include <sys/types.h>
3433965Sjdp#include <sys/acl.h>
3533965Sjdp#include <sys/errno.h>
3633965Sjdp#include <stdio.h>
3789857Sobrien#include <stdlib.h>
3889857Sobrien#include <string.h>
3933965Sjdp#include <utmp.h>
4033965Sjdp
4133965Sjdp#include "acl_support.h"
4289857Sobrien
4389857Sobrien/*
4433965Sjdp * acl_to_text - generate a text form of an acl
4533965Sjdp * spec says nothing about output ordering, so leave in acl order
4689857Sobrien *
4789857Sobrien * This function will not produce nice results if it is called with
4833965Sjdp * a non-POSIX.1e semantics ACL.
4933965Sjdp */
5089857Sobrienchar *
5189857Sobrienacl_to_text(acl_t acl, ssize_t *len_p)
5233965Sjdp{
5333965Sjdp	char	*buf, *tmpbuf;
5489857Sobrien	char	name_buf[UT_NAMESIZE+1];
5589857Sobrien	char	perm_buf[ACL_STRING_PERM_MAXSIZE+1],
5633965Sjdp		effective_perm_buf[ACL_STRING_PERM_MAXSIZE+1];
5733965Sjdp	int	i, error, len;
5889857Sobrien	uid_t	ae_id;
5989857Sobrien	acl_tag_t	ae_tag;
6033965Sjdp	acl_perm_t	ae_perm, effective_perm, mask_perm;
6133965Sjdp
6289857Sobrien	buf = strdup("");
6389857Sobrien	if (!buf)
6433965Sjdp		return(NULL);
6533965Sjdp
6689857Sobrien	mask_perm = ACL_PERM_BITS;	/* effective is regular if no mask */
6789857Sobrien	for (i = 0; i < acl->acl_cnt; i++)
6833965Sjdp		if (acl->acl_entry[i].ae_tag == ACL_MASK)
6933965Sjdp			mask_perm = acl->acl_entry[i].ae_perm;
7089857Sobrien
7189857Sobrien	for (i = 0; i < acl->acl_cnt; i++) {
7233965Sjdp		ae_tag = acl->acl_entry[i].ae_tag;
7333965Sjdp		ae_id = acl->acl_entry[i].ae_id;
7489857Sobrien		ae_perm = acl->acl_entry[i].ae_perm;
7589857Sobrien
7633965Sjdp		switch(ae_tag) {
7733965Sjdp		case ACL_USER_OBJ:
7889857Sobrien			error = acl_perm_to_string(ae_perm,
7989857Sobrien			    ACL_STRING_PERM_MAXSIZE+1, perm_buf);
8033965Sjdp			if (error)
8133965Sjdp				goto error_label;
8289857Sobrien			len = asprintf(&tmpbuf, "%suser::%s\n", buf,
8389857Sobrien			    perm_buf);
8433965Sjdp			if (len == -1)
8533965Sjdp				goto error_label;
8689857Sobrien			free(buf);
8789857Sobrien			buf = tmpbuf;
8833965Sjdp			break;
8933965Sjdp
9089857Sobrien		case ACL_USER:
9189857Sobrien			error = acl_perm_to_string(ae_perm,
9233965Sjdp			    ACL_STRING_PERM_MAXSIZE+1, perm_buf);
9333965Sjdp			if (error)
9489857Sobrien				goto error_label;
9589857Sobrien
9633965Sjdp			error = acl_id_to_name(ae_tag, ae_id, UT_NAMESIZE+1,
9733965Sjdp			    name_buf);
9833965Sjdp			if (error)
9933965Sjdp				goto error_label;
10089857Sobrien
10133965Sjdp			effective_perm = ae_perm & mask_perm;
10233965Sjdp			if (effective_perm != ae_perm) {
10389857Sobrien				error = acl_perm_to_string(effective_perm,
10433965Sjdp				    ACL_STRING_PERM_MAXSIZE+1,
10533965Sjdp				    effective_perm_buf);
10633965Sjdp				if (error)
10733965Sjdp					goto error_label;
10889857Sobrien				len = asprintf(&tmpbuf, "%suser:%s:%s\t\t# "
10933965Sjdp				    "effective: %s\n",
11033965Sjdp				    buf, name_buf, perm_buf,
11189857Sobrien				    effective_perm_buf);
11233965Sjdp			} else {
11333965Sjdp				len = asprintf(&tmpbuf, "%suser:%s:%s\n", buf,
11489857Sobrien				    name_buf, perm_buf);
11533965Sjdp			}
11633965Sjdp			if (len == -1)
11789857Sobrien				goto error_label;
11833965Sjdp			free(buf);
11933965Sjdp			buf = tmpbuf;
12089857Sobrien			break;
12133965Sjdp
12233965Sjdp		case ACL_GROUP_OBJ:
12389857Sobrien			error = acl_perm_to_string(ae_perm,
12433965Sjdp			    ACL_STRING_PERM_MAXSIZE+1, perm_buf);
12533965Sjdp			if (error)
12689857Sobrien				goto error_label;
12733965Sjdp
12833965Sjdp			effective_perm = ae_perm & mask_perm;
12989857Sobrien			if (effective_perm != ae_perm) {
13033965Sjdp				error = acl_perm_to_string(effective_perm,
13133965Sjdp				    ACL_STRING_PERM_MAXSIZE+1,
13289857Sobrien				    effective_perm_buf);
13333965Sjdp				if (error)
13433965Sjdp					goto error_label;
13589857Sobrien				len = asprintf(&tmpbuf, "%sgroup::%s\t\t# "
13633965Sjdp				    "effective: %s\n",
13733965Sjdp				    buf, perm_buf, effective_perm_buf);
13889857Sobrien			} else {
13933965Sjdp				len = asprintf(&tmpbuf, "%sgroup::%s\n", buf,
14033965Sjdp				    perm_buf);
14189857Sobrien			}
14233965Sjdp			if (len == -1)
14333965Sjdp				goto error_label;
14433965Sjdp			free(buf);
14533965Sjdp			buf = tmpbuf;
14689857Sobrien			break;
14733965Sjdp
14833965Sjdp		case ACL_GROUP:
14989857Sobrien			error = acl_perm_to_string(ae_perm,
15033965Sjdp			    ACL_STRING_PERM_MAXSIZE+1, perm_buf);
15133965Sjdp			if (error)
15289857Sobrien				goto error_label;
15333965Sjdp
15433965Sjdp			error = acl_id_to_name(ae_tag, ae_id, UT_NAMESIZE+1,
15589857Sobrien			    name_buf);
15633965Sjdp			if (error)
15733965Sjdp				goto error_label;
15889857Sobrien
15933965Sjdp			effective_perm = ae_perm & mask_perm;
16033965Sjdp			if (effective_perm != ae_perm) {
16189857Sobrien				error = acl_perm_to_string(effective_perm,
16233965Sjdp				    ACL_STRING_PERM_MAXSIZE+1,
16333965Sjdp				    effective_perm_buf);
16489857Sobrien				if (error)
16533965Sjdp					goto error_label;
16633965Sjdp				len = asprintf(&tmpbuf, "%sgroup::%s\t\t# "
16789857Sobrien				    "effective: %s\n",
16833965Sjdp				    buf, perm_buf, effective_perm_buf);
16933965Sjdp			} else {
17089857Sobrien				len = asprintf(&tmpbuf, "%sgroup:%s:%s\n", buf,
17133965Sjdp				    name_buf, perm_buf);
17233965Sjdp			}
17389857Sobrien			if (len == -1)
17433965Sjdp				goto error_label;
17533965Sjdp			free(buf);
17689857Sobrien			buf = tmpbuf;
17733965Sjdp			break;
17833965Sjdp
17989857Sobrien		case ACL_MASK:
18033965Sjdp			error = acl_perm_to_string(ae_perm,
18138889Sjdp			    ACL_STRING_PERM_MAXSIZE+1, perm_buf);
18289857Sobrien			if (error)
18338889Sjdp				goto error_label;
18477298Sobrien
18577298Sobrien			len = asprintf(&tmpbuf, "%smask::%s\n", buf,
18677298Sobrien			    perm_buf);
18738889Sjdp			if (len == -1)
18889857Sobrien				goto error_label;
18938889Sjdp			free(buf);
19038889Sjdp			buf = tmpbuf;
19189857Sobrien			break;
19238889Sjdp
19377298Sobrien		case ACL_OTHER:
19477298Sobrien			error = acl_perm_to_string(ae_perm,
19577298Sobrien			    ACL_STRING_PERM_MAXSIZE+1, perm_buf);
19638889Sjdp			if (error)
19789857Sobrien				goto error_label;
19838889Sjdp
19938889Sjdp			len = asprintf(&tmpbuf, "%sother::%s\n", buf,
20089857Sobrien			    perm_buf);
20138889Sjdp			if (len == -1)
20238889Sjdp				goto error_label;
20389857Sobrien			free(buf);
20438889Sjdp			buf = tmpbuf;
20533965Sjdp			break;
20677298Sobrien
20789857Sobrien		default:
20877298Sobrien			errno = EINVAL;
20977298Sobrien			goto error_label;
21089857Sobrien		}
21177298Sobrien	}
21238889Sjdp
21333965Sjdp	if (len_p) {
21433965Sjdp		*len_p = strlen(buf);
21533965Sjdp	}
216218822Sdim	return (buf);
21733965Sjdp
21833965Sjdperror_label:
21933965Sjdp	/* jump to here sets errno already, we just clean up */
22033965Sjdp	if (buf) free(buf);
221218822Sdim	return (NULL);
22289857Sobrien}
223218822Sdim