getfacl.c revision 75491
1/*- 2 * Copyright (c) 1999-2001 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: head/bin/getfacl/getfacl.c 75491 2001-04-13 19:24:28Z jedgar $ 27 */ 28/* 29 * getfacl -- POSIX.1e utility to extract ACLs from files and directories 30 * and send the results to stdout 31 */ 32 33#include <sys/types.h> 34#include <sys/param.h> 35#include <sys/acl.h> 36#include <sys/stat.h> 37#include <err.h> 38#include <errno.h> 39#include <stdio.h> 40#include <stdlib.h> 41#include <unistd.h> 42 43int more_than_one = 0; 44 45static void 46usage(void) 47{ 48 49 fprintf(stderr, "getfacl [-d] [files ...]\n"); 50} 51 52/* 53 * return an ACL corresponding to the permissions 54 * contained in struct stat 55 */ 56static acl_t 57acl_from_stat(struct stat sb) 58{ 59 acl_t acl; 60 acl_entry_t entry; 61 acl_permset_t perms; 62 63 /* create the ACL */ 64 acl = acl_init(3); 65 if (!acl) 66 return NULL; 67 68 /* First entry: ACL_USER_OBJ */ 69 if (acl_create_entry(&acl, &entry) == -1) 70 return NULL; 71 if (acl_set_tag_type(entry, ACL_USER_OBJ) == -1) 72 return NULL; 73 74 if (acl_get_permset(entry, &perms) == -1) 75 return NULL; 76 if (acl_clear_perms(perms) == -1) 77 return NULL; 78 79 /* calculate user mode */ 80 if (sb.st_mode & S_IRUSR) 81 if (acl_add_perm(perms, ACL_READ) == -1) 82 return NULL; 83 if (sb.st_mode & S_IWUSR) 84 if (acl_add_perm(perms, ACL_WRITE) == -1) 85 return NULL; 86 if (sb.st_mode & S_IXUSR) 87 if (acl_add_perm(perms, ACL_EXECUTE) == -1) 88 return NULL; 89 if (acl_set_permset(entry, perms) == -1) 90 return NULL; 91 92 /* Second entry: ACL_GROUP_OBJ */ 93 if (acl_create_entry(&acl, &entry) == -1) 94 return NULL; 95 if (acl_set_tag_type(entry, ACL_GROUP_OBJ) == -1) 96 return NULL; 97 98 if (acl_get_permset(entry, &perms) == -1) 99 return NULL; 100 if (acl_clear_perms(perms) == -1) 101 return NULL; 102 103 /* calculate group mode */ 104 if (sb.st_mode & S_IRGRP) 105 if (acl_add_perm(perms, ACL_READ) == -1) 106 return NULL; 107 if (sb.st_mode & S_IWGRP) 108 if (acl_add_perm(perms, ACL_WRITE) == -1) 109 return NULL; 110 if (sb.st_mode & S_IXGRP) 111 if (acl_add_perm(perms, ACL_EXECUTE) == -1) 112 return NULL; 113 if (acl_set_permset(entry, perms) == -1) 114 return NULL; 115 116 /* Third entry: ACL_OTHER */ 117 if (acl_create_entry(&acl, &entry) == -1) 118 return NULL; 119 if (acl_set_tag_type(entry, ACL_OTHER) == -1) 120 return NULL; 121 122 if (acl_get_permset(entry, &perms) == -1) 123 return NULL; 124 if (acl_clear_perms(perms) == -1) 125 return NULL; 126 127 /* calculate other mode */ 128 if (sb.st_mode & S_IROTH) 129 if (acl_add_perm(perms, ACL_READ) == -1) 130 return NULL; 131 if (sb.st_mode & S_IWOTH) 132 if (acl_add_perm(perms, ACL_WRITE) == -1) 133 return NULL; 134 if (sb.st_mode & S_IXOTH) 135 if (acl_add_perm(perms, ACL_EXECUTE) == -1) 136 return NULL; 137 if (acl_set_permset(entry, perms) == -1) 138 return NULL; 139 140 return(acl); 141} 142 143static int 144print_acl(char *path, acl_type_t type) 145{ 146 struct stat sb; 147 acl_t acl; 148 char *acl_text; 149 int error; 150 151 error = stat(path, &sb); 152 if (error == -1) { 153 perror(path); 154 return(-1); 155 } 156 157 if (more_than_one) 158 printf("\n"); 159 else 160 more_than_one++; 161 162 printf("#file:%s\n#owner:%d\n#group:%d\n", path, sb.st_uid, sb.st_gid); 163 164 acl = acl_get_file(path, type); 165 if (!acl) { 166 if (errno != EOPNOTSUPP) { 167 warn("%s", path); 168 return(-1); 169 } 170 errno = 0; 171 if (type != ACL_TYPE_ACCESS) 172 return(0); 173 acl = acl_from_stat(sb); 174 if (!acl) { 175 perror("acl_from_stat()"); 176 return(-1); 177 } 178 } 179 180 acl_text = acl_to_text(acl, 0); 181 if (!acl_text) { 182 perror(path); 183 return(-1); 184 } 185 186 printf("%s", acl_text); 187 188 acl_free(acl); 189 acl_free(acl_text); 190 191 return(0); 192} 193 194static int 195print_acl_from_stdin(acl_type_t type) 196{ 197 char pathname[PATH_MAX]; 198 int carried_error = 0; 199 200 pathname[sizeof(pathname) - 1] = '\0'; 201 while (fgets(pathname, sizeof(pathname), stdin)) { 202 /* remove the \n */ 203 pathname[strlen(pathname) - 1] = '\0'; 204 if (print_acl(pathname, type) == -1) { 205 carried_error = -1; 206 } 207 } 208 209 return(carried_error); 210} 211 212int 213main(int argc, char *argv[]) 214{ 215 acl_type_t type = ACL_TYPE_ACCESS; 216 int carried_error = 0; 217 int ch, error, i; 218 219 while ((ch = getopt(argc, argv, "d")) != -1) 220 switch(ch) { 221 case 'd': 222 type = ACL_TYPE_DEFAULT; 223 break; 224 default: 225 usage(); 226 return(-1); 227 } 228 argc -= optind; 229 argv += optind; 230 231 if (argc == 0) { 232 error = print_acl_from_stdin(type); 233 return(error); 234 } 235 236 for (i = 0; i < argc; i++) { 237 if (!strcmp(argv[i], "-")) { 238 error = print_acl_from_stdin(type); 239 if (error == -1) 240 carried_error = -1; 241 } else { 242 error = print_acl(argv[i], type); 243 if (error == -1) 244 carried_error = -1; 245 } 246 } 247 248 return(carried_error); 249} 250