1515d7c92SRobert Watson /*- 2d5af31a2SChris D. Faulhaber * Copyright (c) 1999-2002 Robert N. M. Watson 3515d7c92SRobert Watson * All rights reserved. 4515d7c92SRobert Watson * 5515d7c92SRobert Watson * Redistribution and use in source and binary forms, with or without 6515d7c92SRobert Watson * modification, are permitted provided that the following conditions 7515d7c92SRobert Watson * are met: 8515d7c92SRobert Watson * 1. Redistributions of source code must retain the above copyright 9515d7c92SRobert Watson * notice, this list of conditions and the following disclaimer. 10515d7c92SRobert Watson * 2. Redistributions in binary form must reproduce the above copyright 11515d7c92SRobert Watson * notice, this list of conditions and the following disclaimer in the 12515d7c92SRobert Watson * documentation and/or other materials provided with the distribution. 13515d7c92SRobert Watson * 14515d7c92SRobert Watson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15515d7c92SRobert Watson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16515d7c92SRobert Watson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17515d7c92SRobert Watson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18515d7c92SRobert Watson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19515d7c92SRobert Watson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20515d7c92SRobert Watson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21515d7c92SRobert Watson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22515d7c92SRobert Watson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23515d7c92SRobert Watson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24515d7c92SRobert Watson * SUCH DAMAGE. 25515d7c92SRobert Watson */ 26515d7c92SRobert Watson /* 27515d7c92SRobert Watson * acl_to_text - return a text string with a text representation of the acl 28515d7c92SRobert Watson * in it. 29515d7c92SRobert Watson */ 30515d7c92SRobert Watson 31333fc21eSDavid E. O'Brien #include <sys/cdefs.h> 32333fc21eSDavid E. O'Brien __FBSDID("$FreeBSD$"); 33333fc21eSDavid E. O'Brien 34515d7c92SRobert Watson #include <sys/types.h> 357bd44e92SThomas Moestl #include "namespace.h" 36515d7c92SRobert Watson #include <sys/acl.h> 377bd44e92SThomas Moestl #include "un-namespace.h" 38515d7c92SRobert Watson #include <sys/errno.h> 39515d7c92SRobert Watson #include <stdio.h> 40515d7c92SRobert Watson #include <stdlib.h> 41515d7c92SRobert Watson #include <string.h> 42515d7c92SRobert Watson #include <utmp.h> 43515d7c92SRobert Watson 44515d7c92SRobert Watson #include "acl_support.h" 45515d7c92SRobert Watson 46515d7c92SRobert Watson /* 47515d7c92SRobert Watson * acl_to_text - generate a text form of an acl 48515d7c92SRobert Watson * spec says nothing about output ordering, so leave in acl order 49515d7c92SRobert Watson * 508f45e8c0SRobert Watson * This function will not produce nice results if it is called with 518f45e8c0SRobert Watson * a non-POSIX.1e semantics ACL. 52515d7c92SRobert Watson */ 53515d7c92SRobert Watson char * 54515d7c92SRobert Watson acl_to_text(acl_t acl, ssize_t *len_p) 55515d7c92SRobert Watson { 560f626307SChris D. Faulhaber struct acl *acl_int; 57515d7c92SRobert Watson char *buf, *tmpbuf; 58515d7c92SRobert Watson char name_buf[UT_NAMESIZE+1]; 592de14c39SRobert Watson char perm_buf[_POSIX1E_ACL_STRING_PERM_MAXSIZE+1], 602de14c39SRobert Watson effective_perm_buf[_POSIX1E_ACL_STRING_PERM_MAXSIZE+1]; 61515d7c92SRobert Watson int i, error, len; 62515d7c92SRobert Watson uid_t ae_id; 63515d7c92SRobert Watson acl_tag_t ae_tag; 64515d7c92SRobert Watson acl_perm_t ae_perm, effective_perm, mask_perm; 65515d7c92SRobert Watson 66515d7c92SRobert Watson buf = strdup(""); 679fd46b02SChris D. Faulhaber if (buf == NULL) 68f0078215SRobert Watson return(NULL); 69515d7c92SRobert Watson 70d5af31a2SChris D. Faulhaber if (acl == NULL) { 71d5af31a2SChris D. Faulhaber errno = EINVAL; 72d5af31a2SChris D. Faulhaber return(NULL); 73d5af31a2SChris D. Faulhaber } 74d5af31a2SChris D. Faulhaber 750f626307SChris D. Faulhaber acl_int = &acl->ats_acl; 76515d7c92SRobert Watson 770f626307SChris D. Faulhaber mask_perm = ACL_PERM_BITS; /* effective is regular if no mask */ 780f626307SChris D. Faulhaber for (i = 0; i < acl_int->acl_cnt; i++) 790f626307SChris D. Faulhaber if (acl_int->acl_entry[i].ae_tag == ACL_MASK) 800f626307SChris D. Faulhaber mask_perm = acl_int->acl_entry[i].ae_perm; 810f626307SChris D. Faulhaber 820f626307SChris D. Faulhaber for (i = 0; i < acl_int->acl_cnt; i++) { 830f626307SChris D. Faulhaber ae_tag = acl_int->acl_entry[i].ae_tag; 840f626307SChris D. Faulhaber ae_id = acl_int->acl_entry[i].ae_id; 850f626307SChris D. Faulhaber ae_perm = acl_int->acl_entry[i].ae_perm; 86515d7c92SRobert Watson 87515d7c92SRobert Watson switch(ae_tag) { 88515d7c92SRobert Watson case ACL_USER_OBJ: 892de14c39SRobert Watson error = _posix1e_acl_perm_to_string(ae_perm, 902de14c39SRobert Watson _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 91515d7c92SRobert Watson if (error) 92515d7c92SRobert Watson goto error_label; 93515d7c92SRobert Watson len = asprintf(&tmpbuf, "%suser::%s\n", buf, 94515d7c92SRobert Watson perm_buf); 952137646aSRobert Watson if (len == -1) 96515d7c92SRobert Watson goto error_label; 97515d7c92SRobert Watson free(buf); 98515d7c92SRobert Watson buf = tmpbuf; 99515d7c92SRobert Watson break; 100515d7c92SRobert Watson 101515d7c92SRobert Watson case ACL_USER: 1022de14c39SRobert Watson error = _posix1e_acl_perm_to_string(ae_perm, 1032de14c39SRobert Watson _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 104515d7c92SRobert Watson if (error) 105515d7c92SRobert Watson goto error_label; 106515d7c92SRobert Watson 1072de14c39SRobert Watson error = _posix1e_acl_id_to_name(ae_tag, ae_id, 1082de14c39SRobert Watson UT_NAMESIZE+1, name_buf); 109515d7c92SRobert Watson if (error) 110515d7c92SRobert Watson goto error_label; 111515d7c92SRobert Watson 112515d7c92SRobert Watson effective_perm = ae_perm & mask_perm; 113515d7c92SRobert Watson if (effective_perm != ae_perm) { 1142de14c39SRobert Watson error = _posix1e_acl_perm_to_string( 1152de14c39SRobert Watson effective_perm, 1162de14c39SRobert Watson _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, 117515d7c92SRobert Watson effective_perm_buf); 118515d7c92SRobert Watson if (error) 119515d7c92SRobert Watson goto error_label; 120515d7c92SRobert Watson len = asprintf(&tmpbuf, "%suser:%s:%s\t\t# " 121515d7c92SRobert Watson "effective: %s\n", 122515d7c92SRobert Watson buf, name_buf, perm_buf, 123515d7c92SRobert Watson effective_perm_buf); 124515d7c92SRobert Watson } else { 125515d7c92SRobert Watson len = asprintf(&tmpbuf, "%suser:%s:%s\n", buf, 126515d7c92SRobert Watson name_buf, perm_buf); 127515d7c92SRobert Watson } 1282137646aSRobert Watson if (len == -1) 129515d7c92SRobert Watson goto error_label; 130515d7c92SRobert Watson free(buf); 131515d7c92SRobert Watson buf = tmpbuf; 132515d7c92SRobert Watson break; 133515d7c92SRobert Watson 134515d7c92SRobert Watson case ACL_GROUP_OBJ: 1352de14c39SRobert Watson error = _posix1e_acl_perm_to_string(ae_perm, 1362de14c39SRobert Watson _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 137515d7c92SRobert Watson if (error) 138515d7c92SRobert Watson goto error_label; 139515d7c92SRobert Watson 140515d7c92SRobert Watson effective_perm = ae_perm & mask_perm; 141515d7c92SRobert Watson if (effective_perm != ae_perm) { 1422de14c39SRobert Watson error = _posix1e_acl_perm_to_string( 1432de14c39SRobert Watson effective_perm, 1442de14c39SRobert Watson _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, 145515d7c92SRobert Watson effective_perm_buf); 146515d7c92SRobert Watson if (error) 147515d7c92SRobert Watson goto error_label; 148515d7c92SRobert Watson len = asprintf(&tmpbuf, "%sgroup::%s\t\t# " 149515d7c92SRobert Watson "effective: %s\n", 150515d7c92SRobert Watson buf, perm_buf, effective_perm_buf); 151515d7c92SRobert Watson } else { 152515d7c92SRobert Watson len = asprintf(&tmpbuf, "%sgroup::%s\n", buf, 153515d7c92SRobert Watson perm_buf); 154515d7c92SRobert Watson } 1552137646aSRobert Watson if (len == -1) 156515d7c92SRobert Watson goto error_label; 157515d7c92SRobert Watson free(buf); 158515d7c92SRobert Watson buf = tmpbuf; 159515d7c92SRobert Watson break; 160515d7c92SRobert Watson 161515d7c92SRobert Watson case ACL_GROUP: 1622de14c39SRobert Watson error = _posix1e_acl_perm_to_string(ae_perm, 1632de14c39SRobert Watson _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 164515d7c92SRobert Watson if (error) 165515d7c92SRobert Watson goto error_label; 166515d7c92SRobert Watson 1672de14c39SRobert Watson error = _posix1e_acl_id_to_name(ae_tag, ae_id, 1682de14c39SRobert Watson UT_NAMESIZE+1, name_buf); 169515d7c92SRobert Watson if (error) 170515d7c92SRobert Watson goto error_label; 171515d7c92SRobert Watson 172515d7c92SRobert Watson effective_perm = ae_perm & mask_perm; 173515d7c92SRobert Watson if (effective_perm != ae_perm) { 1742de14c39SRobert Watson error = _posix1e_acl_perm_to_string( 1752de14c39SRobert Watson effective_perm, 1762de14c39SRobert Watson _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, 177515d7c92SRobert Watson effective_perm_buf); 178515d7c92SRobert Watson if (error) 179515d7c92SRobert Watson goto error_label; 18082fefadaSRobert Watson len = asprintf(&tmpbuf, "%sgroup:%s:%s\t\t# " 181515d7c92SRobert Watson "effective: %s\n", 18282fefadaSRobert Watson buf, name_buf, perm_buf, 18382fefadaSRobert Watson effective_perm_buf); 184515d7c92SRobert Watson } else { 185515d7c92SRobert Watson len = asprintf(&tmpbuf, "%sgroup:%s:%s\n", buf, 186515d7c92SRobert Watson name_buf, perm_buf); 187515d7c92SRobert Watson } 1882137646aSRobert Watson if (len == -1) 189515d7c92SRobert Watson goto error_label; 190515d7c92SRobert Watson free(buf); 191515d7c92SRobert Watson buf = tmpbuf; 192515d7c92SRobert Watson break; 193515d7c92SRobert Watson 194515d7c92SRobert Watson case ACL_MASK: 1952de14c39SRobert Watson error = _posix1e_acl_perm_to_string(ae_perm, 1962de14c39SRobert Watson _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 197515d7c92SRobert Watson if (error) 198515d7c92SRobert Watson goto error_label; 199515d7c92SRobert Watson 200515d7c92SRobert Watson len = asprintf(&tmpbuf, "%smask::%s\n", buf, 201515d7c92SRobert Watson perm_buf); 2022137646aSRobert Watson if (len == -1) 203515d7c92SRobert Watson goto error_label; 204515d7c92SRobert Watson free(buf); 205515d7c92SRobert Watson buf = tmpbuf; 206515d7c92SRobert Watson break; 207515d7c92SRobert Watson 208515d7c92SRobert Watson case ACL_OTHER: 2092de14c39SRobert Watson error = _posix1e_acl_perm_to_string(ae_perm, 2102de14c39SRobert Watson _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 211515d7c92SRobert Watson if (error) 212515d7c92SRobert Watson goto error_label; 213515d7c92SRobert Watson 214515d7c92SRobert Watson len = asprintf(&tmpbuf, "%sother::%s\n", buf, 215515d7c92SRobert Watson perm_buf); 2162137646aSRobert Watson if (len == -1) 217515d7c92SRobert Watson goto error_label; 218515d7c92SRobert Watson free(buf); 219515d7c92SRobert Watson buf = tmpbuf; 220515d7c92SRobert Watson break; 221515d7c92SRobert Watson 222515d7c92SRobert Watson default: 223515d7c92SRobert Watson errno = EINVAL; 2242137646aSRobert Watson goto error_label; 225515d7c92SRobert Watson } 226515d7c92SRobert Watson } 227515d7c92SRobert Watson 228515d7c92SRobert Watson if (len_p) { 229515d7c92SRobert Watson *len_p = strlen(buf); 230515d7c92SRobert Watson } 231515d7c92SRobert Watson return (buf); 232515d7c92SRobert Watson 233515d7c92SRobert Watson error_label: 234515d7c92SRobert Watson /* jump to here sets errno already, we just clean up */ 235515d7c92SRobert Watson if (buf) free(buf); 236f0078215SRobert Watson return (NULL); 237515d7c92SRobert Watson } 238