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 struct acl *acl_int; 56 char *buf, *tmpbuf; 57 char name_buf[UT_NAMESIZE+1]; 58 char perm_buf[_POSIX1E_ACL_STRING_PERM_MAXSIZE+1], 59 effective_perm_buf[_POSIX1E_ACL_STRING_PERM_MAXSIZE+1]; 60 int i, error, len; 61 uid_t ae_id; 62 acl_tag_t ae_tag; 63 acl_perm_t ae_perm, effective_perm, mask_perm; 64 65 buf = strdup(""); 66 if (!buf) 67 return(NULL); 68 69 acl_int = &acl->ats_acl; 70 71 mask_perm = ACL_PERM_BITS; /* effective is regular if no mask */ 72 for (i = 0; i < acl_int->acl_cnt; i++) 73 if (acl_int->acl_entry[i].ae_tag == ACL_MASK) 74 mask_perm = acl_int->acl_entry[i].ae_perm; 75 76 for (i = 0; i < acl_int->acl_cnt; i++) { 77 ae_tag = acl_int->acl_entry[i].ae_tag; 78 ae_id = acl_int->acl_entry[i].ae_id; 79 ae_perm = acl_int->acl_entry[i].ae_perm; 80 81 switch(ae_tag) { 82 case ACL_USER_OBJ: 83 error = _posix1e_acl_perm_to_string(ae_perm, 84 _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 85 if (error) 86 goto error_label; 87 len = asprintf(&tmpbuf, "%suser::%s\n", buf, 88 perm_buf); 89 if (len == -1) 90 goto error_label; 91 free(buf); 92 buf = tmpbuf; 93 break; 94 95 case ACL_USER: 96 error = _posix1e_acl_perm_to_string(ae_perm, 97 _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 98 if (error) 99 goto error_label; 100 101 error = _posix1e_acl_id_to_name(ae_tag, ae_id, 102 UT_NAMESIZE+1, name_buf); 103 if (error) 104 goto error_label; 105 106 effective_perm = ae_perm & mask_perm; 107 if (effective_perm != ae_perm) { 108 error = _posix1e_acl_perm_to_string( 109 effective_perm, 110 _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, 111 effective_perm_buf); 112 if (error) 113 goto error_label; 114 len = asprintf(&tmpbuf, "%suser:%s:%s\t\t# " 115 "effective: %s\n", 116 buf, name_buf, perm_buf, 117 effective_perm_buf); 118 } else { 119 len = asprintf(&tmpbuf, "%suser:%s:%s\n", buf, 120 name_buf, perm_buf); 121 } 122 if (len == -1) 123 goto error_label; 124 free(buf); 125 buf = tmpbuf; 126 break; 127 128 case ACL_GROUP_OBJ: 129 error = _posix1e_acl_perm_to_string(ae_perm, 130 _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 131 if (error) 132 goto error_label; 133 134 effective_perm = ae_perm & mask_perm; 135 if (effective_perm != ae_perm) { 136 error = _posix1e_acl_perm_to_string( 137 effective_perm, 138 _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, 139 effective_perm_buf); 140 if (error) 141 goto error_label; 142 len = asprintf(&tmpbuf, "%sgroup::%s\t\t# " 143 "effective: %s\n", 144 buf, perm_buf, effective_perm_buf); 145 } else { 146 len = asprintf(&tmpbuf, "%sgroup::%s\n", buf, 147 perm_buf); 148 } 149 if (len == -1) 150 goto error_label; 151 free(buf); 152 buf = tmpbuf; 153 break; 154 155 case ACL_GROUP: 156 error = _posix1e_acl_perm_to_string(ae_perm, 157 _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 158 if (error) 159 goto error_label; 160 161 error = _posix1e_acl_id_to_name(ae_tag, ae_id, 162 UT_NAMESIZE+1, name_buf); 163 if (error) 164 goto error_label; 165 166 effective_perm = ae_perm & mask_perm; 167 if (effective_perm != ae_perm) { 168 error = _posix1e_acl_perm_to_string( 169 effective_perm, 170 _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, 171 effective_perm_buf); 172 if (error) 173 goto error_label; 174 len = asprintf(&tmpbuf, "%sgroup::%s\t\t# " 175 "effective: %s\n", 176 buf, perm_buf, effective_perm_buf); 177 } else { 178 len = asprintf(&tmpbuf, "%sgroup:%s:%s\n", buf, 179 name_buf, perm_buf); 180 } 181 if (len == -1) 182 goto error_label; 183 free(buf); 184 buf = tmpbuf; 185 break; 186 187 case ACL_MASK: 188 error = _posix1e_acl_perm_to_string(ae_perm, 189 _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 190 if (error) 191 goto error_label; 192 193 len = asprintf(&tmpbuf, "%smask::%s\n", buf, 194 perm_buf); 195 if (len == -1) 196 goto error_label; 197 free(buf); 198 buf = tmpbuf; 199 break; 200 201 case ACL_OTHER: 202 error = _posix1e_acl_perm_to_string(ae_perm, 203 _POSIX1E_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 goto error_label; 211 free(buf); 212 buf = tmpbuf; 213 break; 214 215 default: 216 errno = EINVAL; 217 goto error_label; 218 } 219 } 220 221 if (len_p) { 222 *len_p = strlen(buf); 223 } 224 return (buf); 225 226 error_label: 227 /* jump to here sets errno already, we just clean up */ 228 if (buf) free(buf); 229 return (NULL); 230 } 231