1 /*- 2 * Copyright (c) 1999, 2000, 20001 Robert N. M. Watson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD$ 27 */ 28 /* 29 * acl_to_text - return a text string with a text representation of the acl 30 * in it. 31 */ 32 33 #include <sys/types.h> 34 #include "namespace.h" 35 #include <sys/acl.h> 36 #include "un-namespace.h" 37 #include <sys/errno.h> 38 #include <stdio.h> 39 #include <stdlib.h> 40 #include <string.h> 41 #include <utmp.h> 42 43 #include "acl_support.h" 44 45 /* 46 * acl_to_text - generate a text form of an acl 47 * spec says nothing about output ordering, so leave in acl order 48 * 49 * This function will not produce nice results if it is called with 50 * a non-POSIX.1e semantics ACL. 51 */ 52 char * 53 acl_to_text(acl_t acl, ssize_t *len_p) 54 { 55 char *buf, *tmpbuf; 56 char name_buf[UT_NAMESIZE+1]; 57 char perm_buf[_POSIX1E_ACL_STRING_PERM_MAXSIZE+1], 58 effective_perm_buf[_POSIX1E_ACL_STRING_PERM_MAXSIZE+1]; 59 int i, error, len; 60 uid_t ae_id; 61 acl_tag_t ae_tag; 62 acl_perm_t ae_perm, effective_perm, mask_perm; 63 64 buf = strdup(""); 65 if (!buf) 66 return(NULL); 67 68 mask_perm = ACL_PERM_BITS; /* effective is regular if no mask */ 69 for (i = 0; i < acl->acl_cnt; i++) 70 if (acl->acl_entry[i].ae_tag == ACL_MASK) 71 mask_perm = acl->acl_entry[i].ae_perm; 72 73 for (i = 0; i < acl->acl_cnt; i++) { 74 ae_tag = acl->acl_entry[i].ae_tag; 75 ae_id = acl->acl_entry[i].ae_id; 76 ae_perm = acl->acl_entry[i].ae_perm; 77 78 switch(ae_tag) { 79 case ACL_USER_OBJ: 80 error = _posix1e_acl_perm_to_string(ae_perm, 81 _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 82 if (error) 83 goto error_label; 84 len = asprintf(&tmpbuf, "%suser::%s\n", buf, 85 perm_buf); 86 if (len == -1) 87 goto error_label; 88 free(buf); 89 buf = tmpbuf; 90 break; 91 92 case ACL_USER: 93 error = _posix1e_acl_perm_to_string(ae_perm, 94 _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 95 if (error) 96 goto error_label; 97 98 error = _posix1e_acl_id_to_name(ae_tag, ae_id, 99 UT_NAMESIZE+1, name_buf); 100 if (error) 101 goto error_label; 102 103 effective_perm = ae_perm & mask_perm; 104 if (effective_perm != ae_perm) { 105 error = _posix1e_acl_perm_to_string( 106 effective_perm, 107 _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, 108 effective_perm_buf); 109 if (error) 110 goto error_label; 111 len = asprintf(&tmpbuf, "%suser:%s:%s\t\t# " 112 "effective: %s\n", 113 buf, name_buf, perm_buf, 114 effective_perm_buf); 115 } else { 116 len = asprintf(&tmpbuf, "%suser:%s:%s\n", buf, 117 name_buf, perm_buf); 118 } 119 if (len == -1) 120 goto error_label; 121 free(buf); 122 buf = tmpbuf; 123 break; 124 125 case ACL_GROUP_OBJ: 126 error = _posix1e_acl_perm_to_string(ae_perm, 127 _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 128 if (error) 129 goto error_label; 130 131 effective_perm = ae_perm & mask_perm; 132 if (effective_perm != ae_perm) { 133 error = _posix1e_acl_perm_to_string( 134 effective_perm, 135 _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, 136 effective_perm_buf); 137 if (error) 138 goto error_label; 139 len = asprintf(&tmpbuf, "%sgroup::%s\t\t# " 140 "effective: %s\n", 141 buf, perm_buf, effective_perm_buf); 142 } else { 143 len = asprintf(&tmpbuf, "%sgroup::%s\n", buf, 144 perm_buf); 145 } 146 if (len == -1) 147 goto error_label; 148 free(buf); 149 buf = tmpbuf; 150 break; 151 152 case ACL_GROUP: 153 error = _posix1e_acl_perm_to_string(ae_perm, 154 _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 155 if (error) 156 goto error_label; 157 158 error = _posix1e_acl_id_to_name(ae_tag, ae_id, 159 UT_NAMESIZE+1, name_buf); 160 if (error) 161 goto error_label; 162 163 effective_perm = ae_perm & mask_perm; 164 if (effective_perm != ae_perm) { 165 error = _posix1e_acl_perm_to_string( 166 effective_perm, 167 _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, 168 effective_perm_buf); 169 if (error) 170 goto error_label; 171 len = asprintf(&tmpbuf, "%sgroup::%s\t\t# " 172 "effective: %s\n", 173 buf, perm_buf, effective_perm_buf); 174 } else { 175 len = asprintf(&tmpbuf, "%sgroup:%s:%s\n", buf, 176 name_buf, perm_buf); 177 } 178 if (len == -1) 179 goto error_label; 180 free(buf); 181 buf = tmpbuf; 182 break; 183 184 case ACL_MASK: 185 error = _posix1e_acl_perm_to_string(ae_perm, 186 _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 187 if (error) 188 goto error_label; 189 190 len = asprintf(&tmpbuf, "%smask::%s\n", buf, 191 perm_buf); 192 if (len == -1) 193 goto error_label; 194 free(buf); 195 buf = tmpbuf; 196 break; 197 198 case ACL_OTHER: 199 error = _posix1e_acl_perm_to_string(ae_perm, 200 _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 201 if (error) 202 goto error_label; 203 204 len = asprintf(&tmpbuf, "%sother::%s\n", buf, 205 perm_buf); 206 if (len == -1) 207 goto error_label; 208 free(buf); 209 buf = tmpbuf; 210 break; 211 212 default: 213 errno = EINVAL; 214 goto error_label; 215 } 216 } 217 218 if (len_p) { 219 *len_p = strlen(buf); 220 } 221 return (buf); 222 223 error_label: 224 /* jump to here sets errno already, we just clean up */ 225 if (buf) free(buf); 226 return (NULL); 227 } 228