1515d7c92SRobert Watson /*- 2515d7c92SRobert Watson * Copyright (c) 1999 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 * $FreeBSD$ 27515d7c92SRobert Watson */ 28515d7c92SRobert Watson /* 29515d7c92SRobert Watson * acl_to_text - return a text string with a text representation of the acl 30515d7c92SRobert Watson * in it. 31515d7c92SRobert Watson */ 32515d7c92SRobert Watson 33515d7c92SRobert Watson #include <sys/types.h> 34515d7c92SRobert Watson #include <sys/acl.h> 35515d7c92SRobert Watson #include <sys/errno.h> 36515d7c92SRobert Watson #include <stdio.h> 37515d7c92SRobert Watson #include <stdlib.h> 38515d7c92SRobert Watson #include <string.h> 39515d7c92SRobert Watson #include <utmp.h> 40515d7c92SRobert Watson 41515d7c92SRobert Watson #include "acl_support.h" 42515d7c92SRobert Watson 43515d7c92SRobert Watson 44515d7c92SRobert Watson /* 45515d7c92SRobert Watson * acl_to_text - generate a text form of an acl 46515d7c92SRobert Watson * spec says nothing about output ordering, so leave in acl order 47515d7c92SRobert Watson * 48515d7c92SRobert Watson * For the time-being, reject the printing of ACLs that aren't an 49515d7c92SRobert Watson * understood semantic. Later on, we might want to try and have a 50515d7c92SRobert Watson * generic printing mechanism... 51515d7c92SRobert Watson */ 52515d7c92SRobert Watson char * 53515d7c92SRobert Watson acl_to_text(acl_t acl, ssize_t *len_p) 54515d7c92SRobert Watson { 55515d7c92SRobert Watson char *buf, *tmpbuf; 56515d7c92SRobert Watson char name_buf[UT_NAMESIZE+1]; 57515d7c92SRobert Watson char perm_buf[ACL_STRING_PERM_MAXSIZE+1], 58515d7c92SRobert Watson effective_perm_buf[ACL_STRING_PERM_MAXSIZE+1]; 59515d7c92SRobert Watson int i, error, len; 60515d7c92SRobert Watson uid_t ae_id; 61515d7c92SRobert Watson acl_tag_t ae_tag; 62515d7c92SRobert Watson acl_perm_t ae_perm, effective_perm, mask_perm; 63515d7c92SRobert Watson 64515d7c92SRobert Watson if (!acl_posix1e(acl)) { 65515d7c92SRobert Watson errno = EINVAL; 66515d7c92SRobert Watson return (0); 67515d7c92SRobert Watson } 68515d7c92SRobert Watson 69515d7c92SRobert Watson buf = strdup(""); 70515d7c92SRobert Watson 71515d7c92SRobert Watson mask_perm = ACL_PERM_BITS; /* effective is regular if no mask */ 72515d7c92SRobert Watson for (i = 0; i < acl->acl_cnt; i++) 73515d7c92SRobert Watson if (acl->acl_entry[i].ae_tag == ACL_MASK) 74515d7c92SRobert Watson mask_perm = acl->acl_entry[i].ae_perm; 75515d7c92SRobert Watson 76515d7c92SRobert Watson for (i = 0; i < acl->acl_cnt; i++) { 77515d7c92SRobert Watson ae_tag = acl->acl_entry[i].ae_tag; 78515d7c92SRobert Watson ae_id = acl->acl_entry[i].ae_id; 79515d7c92SRobert Watson ae_perm = acl->acl_entry[i].ae_perm; 80515d7c92SRobert Watson 81515d7c92SRobert Watson switch(ae_tag) { 82515d7c92SRobert Watson case ACL_USER_OBJ: 83515d7c92SRobert Watson error = acl_perm_to_string(ae_perm, 84515d7c92SRobert Watson ACL_STRING_PERM_MAXSIZE+1, perm_buf); 85515d7c92SRobert Watson if (error) 86515d7c92SRobert Watson goto error_label; 87515d7c92SRobert Watson len = asprintf(&tmpbuf, "%suser::%s\n", buf, 88515d7c92SRobert Watson perm_buf); 89515d7c92SRobert Watson if (len == -1) { 90515d7c92SRobert Watson errno = ENOMEM; 91515d7c92SRobert Watson goto error_label; 92515d7c92SRobert Watson } 93515d7c92SRobert Watson free(buf); 94515d7c92SRobert Watson buf = tmpbuf; 95515d7c92SRobert Watson break; 96515d7c92SRobert Watson 97515d7c92SRobert Watson case ACL_USER: 98515d7c92SRobert Watson error = acl_perm_to_string(ae_perm, 99515d7c92SRobert Watson ACL_STRING_PERM_MAXSIZE+1, perm_buf); 100515d7c92SRobert Watson if (error) 101515d7c92SRobert Watson goto error_label; 102515d7c92SRobert Watson 103515d7c92SRobert Watson error = acl_id_to_name(ae_tag, ae_id, UT_NAMESIZE+1, 104515d7c92SRobert Watson name_buf); 105515d7c92SRobert Watson if (error) 106515d7c92SRobert Watson goto error_label; 107515d7c92SRobert Watson 108515d7c92SRobert Watson effective_perm = ae_perm & mask_perm; 109515d7c92SRobert Watson if (effective_perm != ae_perm) { 110515d7c92SRobert Watson error = acl_perm_to_string(effective_perm, 111515d7c92SRobert Watson ACL_STRING_PERM_MAXSIZE+1, 112515d7c92SRobert Watson effective_perm_buf); 113515d7c92SRobert Watson if (error) 114515d7c92SRobert Watson goto error_label; 115515d7c92SRobert Watson len = asprintf(&tmpbuf, "%suser:%s:%s\t\t# " 116515d7c92SRobert Watson "effective: %s\n", 117515d7c92SRobert Watson buf, name_buf, perm_buf, 118515d7c92SRobert Watson effective_perm_buf); 119515d7c92SRobert Watson } else { 120515d7c92SRobert Watson len = asprintf(&tmpbuf, "%suser:%s:%s\n", buf, 121515d7c92SRobert Watson name_buf, perm_buf); 122515d7c92SRobert Watson } 123515d7c92SRobert Watson if (len == -1) { 124515d7c92SRobert Watson errno = ENOMEM; 125515d7c92SRobert Watson goto error_label; 126515d7c92SRobert Watson } 127515d7c92SRobert Watson free(buf); 128515d7c92SRobert Watson buf = tmpbuf; 129515d7c92SRobert Watson break; 130515d7c92SRobert Watson 131515d7c92SRobert Watson case ACL_GROUP_OBJ: 132515d7c92SRobert Watson error = acl_perm_to_string(ae_perm, 133515d7c92SRobert Watson ACL_STRING_PERM_MAXSIZE+1, perm_buf); 134515d7c92SRobert Watson if (error) 135515d7c92SRobert Watson goto error_label; 136515d7c92SRobert Watson 137515d7c92SRobert Watson effective_perm = ae_perm & mask_perm; 138515d7c92SRobert Watson if (effective_perm != ae_perm) { 139515d7c92SRobert Watson error = acl_perm_to_string(effective_perm, 140515d7c92SRobert Watson ACL_STRING_PERM_MAXSIZE+1, 141515d7c92SRobert Watson effective_perm_buf); 142515d7c92SRobert Watson if (error) 143515d7c92SRobert Watson goto error_label; 144515d7c92SRobert Watson len = asprintf(&tmpbuf, "%sgroup::%s\t\t# " 145515d7c92SRobert Watson "effective: %s\n", 146515d7c92SRobert Watson buf, perm_buf, effective_perm_buf); 147515d7c92SRobert Watson } else { 148515d7c92SRobert Watson len = asprintf(&tmpbuf, "%sgroup::%s\n", buf, 149515d7c92SRobert Watson perm_buf); 150515d7c92SRobert Watson } 151515d7c92SRobert Watson if (len == -1) { 152515d7c92SRobert Watson errno = ENOMEM; 153515d7c92SRobert Watson goto error_label; 154515d7c92SRobert Watson } 155515d7c92SRobert Watson free(buf); 156515d7c92SRobert Watson buf = tmpbuf; 157515d7c92SRobert Watson break; 158515d7c92SRobert Watson 159515d7c92SRobert Watson case ACL_GROUP: 160515d7c92SRobert Watson error = acl_perm_to_string(ae_perm, 161515d7c92SRobert Watson ACL_STRING_PERM_MAXSIZE+1, perm_buf); 162515d7c92SRobert Watson if (error) 163515d7c92SRobert Watson goto error_label; 164515d7c92SRobert Watson 165515d7c92SRobert Watson error = acl_id_to_name(ae_tag, ae_id, UT_NAMESIZE+1, 166515d7c92SRobert Watson name_buf); 167515d7c92SRobert Watson if (error) 168515d7c92SRobert Watson goto error_label; 169515d7c92SRobert Watson 170515d7c92SRobert Watson effective_perm = ae_perm & mask_perm; 171515d7c92SRobert Watson if (effective_perm != ae_perm) { 172515d7c92SRobert Watson error = acl_perm_to_string(effective_perm, 173515d7c92SRobert Watson ACL_STRING_PERM_MAXSIZE+1, 174515d7c92SRobert Watson effective_perm_buf); 175515d7c92SRobert Watson if (error) 176515d7c92SRobert Watson goto error_label; 177515d7c92SRobert Watson len = asprintf(&tmpbuf, "%sgroup::%s\t\t# " 178515d7c92SRobert Watson "effective: %s\n", 179515d7c92SRobert Watson buf, perm_buf, effective_perm_buf); 180515d7c92SRobert Watson } else { 181515d7c92SRobert Watson len = asprintf(&tmpbuf, "%sgroup:%s:%s\n", buf, 182515d7c92SRobert Watson name_buf, perm_buf); 183515d7c92SRobert Watson } 184515d7c92SRobert Watson if (len == -1) { 185515d7c92SRobert Watson errno = ENOMEM; 186515d7c92SRobert Watson goto error_label; 187515d7c92SRobert Watson } 188515d7c92SRobert Watson free(buf); 189515d7c92SRobert Watson buf = tmpbuf; 190515d7c92SRobert Watson break; 191515d7c92SRobert Watson 192515d7c92SRobert Watson case ACL_MASK: 193515d7c92SRobert Watson error = acl_perm_to_string(ae_perm, 194515d7c92SRobert Watson ACL_STRING_PERM_MAXSIZE+1, perm_buf); 195515d7c92SRobert Watson if (error) 196515d7c92SRobert Watson goto error_label; 197515d7c92SRobert Watson 198515d7c92SRobert Watson len = asprintf(&tmpbuf, "%smask::%s\n", buf, 199515d7c92SRobert Watson perm_buf); 200515d7c92SRobert Watson if (len == -1) { 201515d7c92SRobert Watson errno = ENOMEM; 202515d7c92SRobert Watson goto error_label; 203515d7c92SRobert Watson } 204515d7c92SRobert Watson free(buf); 205515d7c92SRobert Watson buf = tmpbuf; 206515d7c92SRobert Watson break; 207515d7c92SRobert Watson 208515d7c92SRobert Watson case ACL_OTHER: 209515d7c92SRobert Watson error = acl_perm_to_string(ae_perm, 210515d7c92SRobert Watson 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); 216515d7c92SRobert Watson if (len == -1) { 217515d7c92SRobert Watson errno = ENOMEM; 218515d7c92SRobert Watson goto error_label; 219515d7c92SRobert Watson } 220515d7c92SRobert Watson free(buf); 221515d7c92SRobert Watson buf = tmpbuf; 222515d7c92SRobert Watson break; 223515d7c92SRobert Watson 224515d7c92SRobert Watson default: 225515d7c92SRobert Watson free(buf); 226515d7c92SRobert Watson errno = EINVAL; 227515d7c92SRobert Watson return (0); 228515d7c92SRobert Watson } 229515d7c92SRobert Watson } 230515d7c92SRobert Watson 231515d7c92SRobert Watson if (len_p) { 232515d7c92SRobert Watson *len_p = strlen(buf); 233515d7c92SRobert Watson } 234515d7c92SRobert Watson return (buf); 235515d7c92SRobert Watson 236515d7c92SRobert Watson error_label: 237515d7c92SRobert Watson /* jump to here sets errno already, we just clean up */ 238515d7c92SRobert Watson if (buf) free(buf); 239515d7c92SRobert Watson return (0); 240515d7c92SRobert Watson } 241515d7c92SRobert Watson 242515d7c92SRobert Watson 243515d7c92SRobert Watson 244515d7c92SRobert Watson 245