1515d7c92SRobert Watson /*- 24d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 3d915a14eSPedro F. Giffuni * 4d5af31a2SChris D. Faulhaber * Copyright (c) 1999-2002 Robert N. M. Watson 5515d7c92SRobert Watson * All rights reserved. 6515d7c92SRobert Watson * 7515d7c92SRobert Watson * Redistribution and use in source and binary forms, with or without 8515d7c92SRobert Watson * modification, are permitted provided that the following conditions 9515d7c92SRobert Watson * are met: 10515d7c92SRobert Watson * 1. Redistributions of source code must retain the above copyright 11515d7c92SRobert Watson * notice, this list of conditions and the following disclaimer. 12515d7c92SRobert Watson * 2. Redistributions in binary form must reproduce the above copyright 13515d7c92SRobert Watson * notice, this list of conditions and the following disclaimer in the 14515d7c92SRobert Watson * documentation and/or other materials provided with the distribution. 15515d7c92SRobert Watson * 16515d7c92SRobert Watson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17515d7c92SRobert Watson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18515d7c92SRobert Watson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19515d7c92SRobert Watson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20515d7c92SRobert Watson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21515d7c92SRobert Watson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22515d7c92SRobert Watson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23515d7c92SRobert Watson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24515d7c92SRobert Watson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25515d7c92SRobert Watson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26515d7c92SRobert Watson * SUCH DAMAGE. 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 337bd44e92SThomas Moestl #include "namespace.h" 34*418b4c2aSBrooks Davis #include <sys/param.h> 35515d7c92SRobert Watson #include <sys/acl.h> 367bd44e92SThomas Moestl #include "un-namespace.h" 37515d7c92SRobert Watson #include <sys/errno.h> 38515d7c92SRobert Watson #include <stdio.h> 39515d7c92SRobert Watson #include <stdlib.h> 40515d7c92SRobert Watson #include <string.h> 41515d7c92SRobert Watson 42515d7c92SRobert Watson #include "acl_support.h" 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 * 488f45e8c0SRobert Watson * This function will not produce nice results if it is called with 498f45e8c0SRobert Watson * a non-POSIX.1e semantics ACL. 50515d7c92SRobert Watson */ 51aa015c8eSEdward Tomasz Napierala 52aa015c8eSEdward Tomasz Napierala char *_nfs4_acl_to_text_np(const acl_t acl, ssize_t *len_p, int flags); 53aa015c8eSEdward Tomasz Napierala 54aa015c8eSEdward Tomasz Napierala static char * 55aa015c8eSEdward Tomasz Napierala _posix1e_acl_to_text(acl_t acl, ssize_t *len_p, int flags) 56515d7c92SRobert Watson { 570f626307SChris D. Faulhaber struct acl *acl_int; 58515d7c92SRobert Watson char *buf, *tmpbuf; 59dc29acd1SEd Schouten char name_buf[MAXLOGNAME]; 602de14c39SRobert Watson char perm_buf[_POSIX1E_ACL_STRING_PERM_MAXSIZE+1], 612de14c39SRobert Watson effective_perm_buf[_POSIX1E_ACL_STRING_PERM_MAXSIZE+1]; 62515d7c92SRobert Watson int i, error, len; 63515d7c92SRobert Watson uid_t ae_id; 64515d7c92SRobert Watson acl_tag_t ae_tag; 65515d7c92SRobert Watson acl_perm_t ae_perm, effective_perm, mask_perm; 66515d7c92SRobert Watson 67515d7c92SRobert Watson buf = strdup(""); 689fd46b02SChris D. Faulhaber if (buf == NULL) 69f0078215SRobert Watson return(NULL); 70515d7c92SRobert Watson 710f626307SChris D. Faulhaber acl_int = &acl->ats_acl; 72515d7c92SRobert Watson 730f626307SChris D. Faulhaber mask_perm = ACL_PERM_BITS; /* effective is regular if no mask */ 740f626307SChris D. Faulhaber for (i = 0; i < acl_int->acl_cnt; i++) 750f626307SChris D. Faulhaber if (acl_int->acl_entry[i].ae_tag == ACL_MASK) 760f626307SChris D. Faulhaber mask_perm = acl_int->acl_entry[i].ae_perm; 770f626307SChris D. Faulhaber 780f626307SChris D. Faulhaber for (i = 0; i < acl_int->acl_cnt; i++) { 790f626307SChris D. Faulhaber ae_tag = acl_int->acl_entry[i].ae_tag; 800f626307SChris D. Faulhaber ae_id = acl_int->acl_entry[i].ae_id; 810f626307SChris D. Faulhaber ae_perm = acl_int->acl_entry[i].ae_perm; 82515d7c92SRobert Watson 83515d7c92SRobert Watson switch(ae_tag) { 84515d7c92SRobert Watson case ACL_USER_OBJ: 852de14c39SRobert Watson error = _posix1e_acl_perm_to_string(ae_perm, 862de14c39SRobert Watson _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 87515d7c92SRobert Watson if (error) 88515d7c92SRobert Watson goto error_label; 89515d7c92SRobert Watson len = asprintf(&tmpbuf, "%suser::%s\n", buf, 90515d7c92SRobert Watson perm_buf); 912137646aSRobert Watson if (len == -1) 92515d7c92SRobert Watson goto error_label; 93515d7c92SRobert Watson free(buf); 94515d7c92SRobert Watson buf = tmpbuf; 95515d7c92SRobert Watson break; 96515d7c92SRobert Watson 97515d7c92SRobert Watson case ACL_USER: 982de14c39SRobert Watson error = _posix1e_acl_perm_to_string(ae_perm, 992de14c39SRobert Watson _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 100515d7c92SRobert Watson if (error) 101515d7c92SRobert Watson goto error_label; 102515d7c92SRobert Watson 1032de14c39SRobert Watson error = _posix1e_acl_id_to_name(ae_tag, ae_id, 104dc29acd1SEd Schouten MAXLOGNAME, name_buf, flags); 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) { 1102de14c39SRobert Watson error = _posix1e_acl_perm_to_string( 1112de14c39SRobert Watson effective_perm, 1122de14c39SRobert Watson _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, 113515d7c92SRobert Watson effective_perm_buf); 114515d7c92SRobert Watson if (error) 115515d7c92SRobert Watson goto error_label; 116515d7c92SRobert Watson len = asprintf(&tmpbuf, "%suser:%s:%s\t\t# " 117515d7c92SRobert Watson "effective: %s\n", 118515d7c92SRobert Watson buf, name_buf, perm_buf, 119515d7c92SRobert Watson effective_perm_buf); 120515d7c92SRobert Watson } else { 121515d7c92SRobert Watson len = asprintf(&tmpbuf, "%suser:%s:%s\n", buf, 122515d7c92SRobert Watson name_buf, perm_buf); 123515d7c92SRobert Watson } 1242137646aSRobert Watson if (len == -1) 125515d7c92SRobert Watson goto error_label; 126515d7c92SRobert Watson free(buf); 127515d7c92SRobert Watson buf = tmpbuf; 128515d7c92SRobert Watson break; 129515d7c92SRobert Watson 130515d7c92SRobert Watson case ACL_GROUP_OBJ: 1312de14c39SRobert Watson error = _posix1e_acl_perm_to_string(ae_perm, 1322de14c39SRobert Watson _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 133515d7c92SRobert Watson if (error) 134515d7c92SRobert Watson goto error_label; 135515d7c92SRobert Watson 136515d7c92SRobert Watson effective_perm = ae_perm & mask_perm; 137515d7c92SRobert Watson if (effective_perm != ae_perm) { 1382de14c39SRobert Watson error = _posix1e_acl_perm_to_string( 1392de14c39SRobert Watson effective_perm, 1402de14c39SRobert Watson _POSIX1E_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 } 1512137646aSRobert Watson if (len == -1) 152515d7c92SRobert Watson goto error_label; 153515d7c92SRobert Watson free(buf); 154515d7c92SRobert Watson buf = tmpbuf; 155515d7c92SRobert Watson break; 156515d7c92SRobert Watson 157515d7c92SRobert Watson case ACL_GROUP: 1582de14c39SRobert Watson error = _posix1e_acl_perm_to_string(ae_perm, 1592de14c39SRobert Watson _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 160515d7c92SRobert Watson if (error) 161515d7c92SRobert Watson goto error_label; 162515d7c92SRobert Watson 1632de14c39SRobert Watson error = _posix1e_acl_id_to_name(ae_tag, ae_id, 164dc29acd1SEd Schouten MAXLOGNAME, name_buf, flags); 165515d7c92SRobert Watson if (error) 166515d7c92SRobert Watson goto error_label; 167515d7c92SRobert Watson 168515d7c92SRobert Watson effective_perm = ae_perm & mask_perm; 169515d7c92SRobert Watson if (effective_perm != ae_perm) { 1702de14c39SRobert Watson error = _posix1e_acl_perm_to_string( 1712de14c39SRobert Watson effective_perm, 1722de14c39SRobert Watson _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, 173515d7c92SRobert Watson effective_perm_buf); 174515d7c92SRobert Watson if (error) 175515d7c92SRobert Watson goto error_label; 17682fefadaSRobert Watson len = asprintf(&tmpbuf, "%sgroup:%s:%s\t\t# " 177515d7c92SRobert Watson "effective: %s\n", 17882fefadaSRobert Watson buf, name_buf, perm_buf, 17982fefadaSRobert Watson effective_perm_buf); 180515d7c92SRobert Watson } else { 181515d7c92SRobert Watson len = asprintf(&tmpbuf, "%sgroup:%s:%s\n", buf, 182515d7c92SRobert Watson name_buf, perm_buf); 183515d7c92SRobert Watson } 1842137646aSRobert Watson if (len == -1) 185515d7c92SRobert Watson goto error_label; 186515d7c92SRobert Watson free(buf); 187515d7c92SRobert Watson buf = tmpbuf; 188515d7c92SRobert Watson break; 189515d7c92SRobert Watson 190515d7c92SRobert Watson case ACL_MASK: 1912de14c39SRobert Watson error = _posix1e_acl_perm_to_string(ae_perm, 1922de14c39SRobert Watson _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 193515d7c92SRobert Watson if (error) 194515d7c92SRobert Watson goto error_label; 195515d7c92SRobert Watson 196515d7c92SRobert Watson len = asprintf(&tmpbuf, "%smask::%s\n", buf, 197515d7c92SRobert Watson perm_buf); 1982137646aSRobert Watson if (len == -1) 199515d7c92SRobert Watson goto error_label; 200515d7c92SRobert Watson free(buf); 201515d7c92SRobert Watson buf = tmpbuf; 202515d7c92SRobert Watson break; 203515d7c92SRobert Watson 204515d7c92SRobert Watson case ACL_OTHER: 2052de14c39SRobert Watson error = _posix1e_acl_perm_to_string(ae_perm, 2062de14c39SRobert Watson _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 207515d7c92SRobert Watson if (error) 208515d7c92SRobert Watson goto error_label; 209515d7c92SRobert Watson 210515d7c92SRobert Watson len = asprintf(&tmpbuf, "%sother::%s\n", buf, 211515d7c92SRobert Watson perm_buf); 2122137646aSRobert Watson if (len == -1) 213515d7c92SRobert Watson goto error_label; 214515d7c92SRobert Watson free(buf); 215515d7c92SRobert Watson buf = tmpbuf; 216515d7c92SRobert Watson break; 217515d7c92SRobert Watson 218515d7c92SRobert Watson default: 219515d7c92SRobert Watson errno = EINVAL; 2202137646aSRobert Watson goto error_label; 221515d7c92SRobert Watson } 222515d7c92SRobert Watson } 223515d7c92SRobert Watson 224515d7c92SRobert Watson if (len_p) { 225515d7c92SRobert Watson *len_p = strlen(buf); 226515d7c92SRobert Watson } 227515d7c92SRobert Watson return (buf); 228515d7c92SRobert Watson 229515d7c92SRobert Watson error_label: 230515d7c92SRobert Watson /* jump to here sets errno already, we just clean up */ 231515d7c92SRobert Watson if (buf) free(buf); 232f0078215SRobert Watson return (NULL); 233515d7c92SRobert Watson } 234aa015c8eSEdward Tomasz Napierala 235aa015c8eSEdward Tomasz Napierala char * 236aa015c8eSEdward Tomasz Napierala acl_to_text_np(acl_t acl, ssize_t *len_p, int flags) 237aa015c8eSEdward Tomasz Napierala { 238aa015c8eSEdward Tomasz Napierala 23959831d75SEdward Tomasz Napierala if (acl == NULL) { 24059831d75SEdward Tomasz Napierala errno = EINVAL; 24159831d75SEdward Tomasz Napierala return(NULL); 24259831d75SEdward Tomasz Napierala } 24359831d75SEdward Tomasz Napierala 244aa015c8eSEdward Tomasz Napierala switch (_acl_brand(acl)) { 245aa015c8eSEdward Tomasz Napierala case ACL_BRAND_POSIX: 246aa015c8eSEdward Tomasz Napierala return (_posix1e_acl_to_text(acl, len_p, flags)); 247aa015c8eSEdward Tomasz Napierala case ACL_BRAND_NFS4: 248aa015c8eSEdward Tomasz Napierala return (_nfs4_acl_to_text_np(acl, len_p, flags)); 249aa015c8eSEdward Tomasz Napierala default: 250aa015c8eSEdward Tomasz Napierala errno = EINVAL; 251aa015c8eSEdward Tomasz Napierala return (NULL); 252aa015c8eSEdward Tomasz Napierala } 253aa015c8eSEdward Tomasz Napierala } 254aa015c8eSEdward Tomasz Napierala 255aa015c8eSEdward Tomasz Napierala char * 256aa015c8eSEdward Tomasz Napierala acl_to_text(acl_t acl, ssize_t *len_p) 257aa015c8eSEdward Tomasz Napierala { 258aa015c8eSEdward Tomasz Napierala 259aa015c8eSEdward Tomasz Napierala return (acl_to_text_np(acl, len_p, 0)); 260aa015c8eSEdward Tomasz Napierala } 261