1 /*- 2 * Copyright (c) 1999 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 <sys/acl.h> 35 #include <sys/errno.h> 36 #include <stdio.h> 37 #include <stdlib.h> 38 #include <string.h> 39 #include <utmp.h> 40 41 #include "acl_support.h" 42 43 /* 44 * acl_to_text - generate a text form of an acl 45 * spec says nothing about output ordering, so leave in acl order 46 * 47 * This function will not produce nice results if it is called with 48 * a non-POSIX.1e semantics ACL. 49 */ 50 char * 51 acl_to_text(acl_t acl, ssize_t *len_p) 52 { 53 char *buf, *tmpbuf; 54 char name_buf[UT_NAMESIZE+1]; 55 char perm_buf[ACL_STRING_PERM_MAXSIZE+1], 56 effective_perm_buf[ACL_STRING_PERM_MAXSIZE+1]; 57 int i, error, len; 58 uid_t ae_id; 59 acl_tag_t ae_tag; 60 acl_perm_t ae_perm, effective_perm, mask_perm; 61 62 buf = strdup(""); 63 64 mask_perm = ACL_PERM_BITS; /* effective is regular if no mask */ 65 for (i = 0; i < acl->acl_cnt; i++) 66 if (acl->acl_entry[i].ae_tag == ACL_MASK) 67 mask_perm = acl->acl_entry[i].ae_perm; 68 69 for (i = 0; i < acl->acl_cnt; i++) { 70 ae_tag = acl->acl_entry[i].ae_tag; 71 ae_id = acl->acl_entry[i].ae_id; 72 ae_perm = acl->acl_entry[i].ae_perm; 73 74 switch(ae_tag) { 75 case ACL_USER_OBJ: 76 error = acl_perm_to_string(ae_perm, 77 ACL_STRING_PERM_MAXSIZE+1, perm_buf); 78 if (error) 79 goto error_label; 80 len = asprintf(&tmpbuf, "%suser::%s\n", buf, 81 perm_buf); 82 if (len == -1) { 83 errno = ENOMEM; 84 goto error_label; 85 } 86 free(buf); 87 buf = tmpbuf; 88 break; 89 90 case ACL_USER: 91 error = acl_perm_to_string(ae_perm, 92 ACL_STRING_PERM_MAXSIZE+1, perm_buf); 93 if (error) 94 goto error_label; 95 96 error = acl_id_to_name(ae_tag, ae_id, UT_NAMESIZE+1, 97 name_buf); 98 if (error) 99 goto error_label; 100 101 effective_perm = ae_perm & mask_perm; 102 if (effective_perm != ae_perm) { 103 error = acl_perm_to_string(effective_perm, 104 ACL_STRING_PERM_MAXSIZE+1, 105 effective_perm_buf); 106 if (error) 107 goto error_label; 108 len = asprintf(&tmpbuf, "%suser:%s:%s\t\t# " 109 "effective: %s\n", 110 buf, name_buf, perm_buf, 111 effective_perm_buf); 112 } else { 113 len = asprintf(&tmpbuf, "%suser:%s:%s\n", buf, 114 name_buf, perm_buf); 115 } 116 if (len == -1) { 117 errno = ENOMEM; 118 goto error_label; 119 } 120 free(buf); 121 buf = tmpbuf; 122 break; 123 124 case ACL_GROUP_OBJ: 125 error = acl_perm_to_string(ae_perm, 126 ACL_STRING_PERM_MAXSIZE+1, perm_buf); 127 if (error) 128 goto error_label; 129 130 effective_perm = ae_perm & mask_perm; 131 if (effective_perm != ae_perm) { 132 error = acl_perm_to_string(effective_perm, 133 ACL_STRING_PERM_MAXSIZE+1, 134 effective_perm_buf); 135 if (error) 136 goto error_label; 137 len = asprintf(&tmpbuf, "%sgroup::%s\t\t# " 138 "effective: %s\n", 139 buf, perm_buf, effective_perm_buf); 140 } else { 141 len = asprintf(&tmpbuf, "%sgroup::%s\n", buf, 142 perm_buf); 143 } 144 if (len == -1) { 145 errno = ENOMEM; 146 goto error_label; 147 } 148 free(buf); 149 buf = tmpbuf; 150 break; 151 152 case ACL_GROUP: 153 error = acl_perm_to_string(ae_perm, 154 ACL_STRING_PERM_MAXSIZE+1, perm_buf); 155 if (error) 156 goto error_label; 157 158 error = acl_id_to_name(ae_tag, ae_id, UT_NAMESIZE+1, 159 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 = acl_perm_to_string(effective_perm, 166 ACL_STRING_PERM_MAXSIZE+1, 167 effective_perm_buf); 168 if (error) 169 goto error_label; 170 len = asprintf(&tmpbuf, "%sgroup::%s\t\t# " 171 "effective: %s\n", 172 buf, perm_buf, effective_perm_buf); 173 } else { 174 len = asprintf(&tmpbuf, "%sgroup:%s:%s\n", buf, 175 name_buf, perm_buf); 176 } 177 if (len == -1) { 178 errno = ENOMEM; 179 goto error_label; 180 } 181 free(buf); 182 buf = tmpbuf; 183 break; 184 185 case ACL_MASK: 186 error = acl_perm_to_string(ae_perm, 187 ACL_STRING_PERM_MAXSIZE+1, perm_buf); 188 if (error) 189 goto error_label; 190 191 len = asprintf(&tmpbuf, "%smask::%s\n", buf, 192 perm_buf); 193 if (len == -1) { 194 errno = ENOMEM; 195 goto error_label; 196 } 197 free(buf); 198 buf = tmpbuf; 199 break; 200 201 case ACL_OTHER: 202 error = acl_perm_to_string(ae_perm, 203 ACL_STRING_PERM_MAXSIZE+1, perm_buf); 204 if (error) 205 goto error_label; 206 207 len = asprintf(&tmpbuf, "%sother::%s\n", buf, 208 perm_buf); 209 if (len == -1) { 210 errno = ENOMEM; 211 goto error_label; 212 } 213 free(buf); 214 buf = tmpbuf; 215 break; 216 217 default: 218 free(buf); 219 errno = EINVAL; 220 return (0); 221 } 222 } 223 224 if (len_p) { 225 *len_p = strlen(buf); 226 } 227 return (buf); 228 229 error_label: 230 /* jump to here sets errno already, we just clean up */ 231 if (buf) free(buf); 232 return (0); 233 } 234