156055Srwatson/*- 289831Sjedgar * Copyright (c) 1999-2002 Robert N. M. Watson 356055Srwatson * All rights reserved. 456055Srwatson * 556055Srwatson * Redistribution and use in source and binary forms, with or without 656055Srwatson * modification, are permitted provided that the following conditions 756055Srwatson * are met: 856055Srwatson * 1. Redistributions of source code must retain the above copyright 956055Srwatson * notice, this list of conditions and the following disclaimer. 1056055Srwatson * 2. Redistributions in binary form must reproduce the above copyright 1156055Srwatson * notice, this list of conditions and the following disclaimer in the 1256055Srwatson * documentation and/or other materials provided with the distribution. 1356055Srwatson * 1456055Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1556055Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1656055Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1756055Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1856055Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1956055Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2056055Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2156055Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2256055Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2356055Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2456055Srwatson * SUCH DAMAGE. 2556055Srwatson */ 2656055Srwatson/* 2756055Srwatson * acl_to_text - return a text string with a text representation of the acl 2856055Srwatson * in it. 2956055Srwatson */ 3056055Srwatson 3192986Sobrien#include <sys/cdefs.h> 3292986Sobrien__FBSDID("$FreeBSD$"); 3392986Sobrien 3456055Srwatson#include <sys/types.h> 3575185Stmm#include "namespace.h" 3656055Srwatson#include <sys/acl.h> 3775185Stmm#include "un-namespace.h" 3856055Srwatson#include <sys/errno.h> 3956055Srwatson#include <stdio.h> 4056055Srwatson#include <stdlib.h> 4156055Srwatson#include <string.h> 4256055Srwatson 4356055Srwatson#include "acl_support.h" 4456055Srwatson 4556055Srwatson/* 4656055Srwatson * acl_to_text - generate a text form of an acl 4756055Srwatson * spec says nothing about output ordering, so leave in acl order 4856055Srwatson * 4956625Srwatson * This function will not produce nice results if it is called with 5056625Srwatson * a non-POSIX.1e semantics ACL. 5156055Srwatson */ 52194955Strasz 53194955Straszchar *_nfs4_acl_to_text_np(const acl_t acl, ssize_t *len_p, int flags); 54194955Strasz 55194955Straszstatic char * 56194955Strasz_posix1e_acl_to_text(acl_t acl, ssize_t *len_p, int flags) 5756055Srwatson{ 5875928Sjedgar struct acl *acl_int; 5975928Sjedgar char *buf, *tmpbuf; 60200142Sed char name_buf[MAXLOGNAME]; 6175928Sjedgar char perm_buf[_POSIX1E_ACL_STRING_PERM_MAXSIZE+1], 6275928Sjedgar effective_perm_buf[_POSIX1E_ACL_STRING_PERM_MAXSIZE+1]; 6375928Sjedgar int i, error, len; 6475928Sjedgar uid_t ae_id; 6575928Sjedgar acl_tag_t ae_tag; 6675928Sjedgar acl_perm_t ae_perm, effective_perm, mask_perm; 6756055Srwatson 6856055Srwatson buf = strdup(""); 6991034Sjedgar if (buf == NULL) 7071142Srwatson return(NULL); 7156055Srwatson 7275928Sjedgar acl_int = &acl->ats_acl; 7375928Sjedgar 7456055Srwatson mask_perm = ACL_PERM_BITS; /* effective is regular if no mask */ 7575928Sjedgar for (i = 0; i < acl_int->acl_cnt; i++) 7675928Sjedgar if (acl_int->acl_entry[i].ae_tag == ACL_MASK) 7775928Sjedgar mask_perm = acl_int->acl_entry[i].ae_perm; 7856055Srwatson 7975928Sjedgar for (i = 0; i < acl_int->acl_cnt; i++) { 8075928Sjedgar ae_tag = acl_int->acl_entry[i].ae_tag; 8175928Sjedgar ae_id = acl_int->acl_entry[i].ae_id; 8275928Sjedgar ae_perm = acl_int->acl_entry[i].ae_perm; 8356055Srwatson 8456055Srwatson switch(ae_tag) { 8556055Srwatson case ACL_USER_OBJ: 8674191Srwatson error = _posix1e_acl_perm_to_string(ae_perm, 8774191Srwatson _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 8856055Srwatson if (error) 8956055Srwatson goto error_label; 9056055Srwatson len = asprintf(&tmpbuf, "%suser::%s\n", buf, 9156055Srwatson perm_buf); 9270841Srwatson if (len == -1) 9356055Srwatson goto error_label; 9456055Srwatson free(buf); 9556055Srwatson buf = tmpbuf; 9656055Srwatson break; 9756055Srwatson 9856055Srwatson case ACL_USER: 9974191Srwatson error = _posix1e_acl_perm_to_string(ae_perm, 10074191Srwatson _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 10156055Srwatson if (error) 10256055Srwatson goto error_label; 10356055Srwatson 10474191Srwatson error = _posix1e_acl_id_to_name(ae_tag, ae_id, 105200142Sed MAXLOGNAME, name_buf, flags); 10656055Srwatson if (error) 10756055Srwatson goto error_label; 10856055Srwatson 10956055Srwatson effective_perm = ae_perm & mask_perm; 11056055Srwatson if (effective_perm != ae_perm) { 11174191Srwatson error = _posix1e_acl_perm_to_string( 11274191Srwatson effective_perm, 11374191Srwatson _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, 11456055Srwatson effective_perm_buf); 11556055Srwatson if (error) 11656055Srwatson goto error_label; 11756055Srwatson len = asprintf(&tmpbuf, "%suser:%s:%s\t\t# " 11856055Srwatson "effective: %s\n", 11956055Srwatson buf, name_buf, perm_buf, 12056055Srwatson effective_perm_buf); 12156055Srwatson } else { 12256055Srwatson len = asprintf(&tmpbuf, "%suser:%s:%s\n", buf, 12356055Srwatson name_buf, perm_buf); 12456055Srwatson } 12570841Srwatson if (len == -1) 12656055Srwatson goto error_label; 12756055Srwatson free(buf); 12856055Srwatson buf = tmpbuf; 12956055Srwatson break; 13056055Srwatson 13156055Srwatson case ACL_GROUP_OBJ: 13274191Srwatson error = _posix1e_acl_perm_to_string(ae_perm, 13374191Srwatson _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 13456055Srwatson if (error) 13556055Srwatson goto error_label; 13656055Srwatson 13756055Srwatson effective_perm = ae_perm & mask_perm; 13856055Srwatson if (effective_perm != ae_perm) { 13974191Srwatson error = _posix1e_acl_perm_to_string( 14074191Srwatson effective_perm, 14174191Srwatson _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, 14256055Srwatson effective_perm_buf); 14356055Srwatson if (error) 14456055Srwatson goto error_label; 14556055Srwatson len = asprintf(&tmpbuf, "%sgroup::%s\t\t# " 14656055Srwatson "effective: %s\n", 14756055Srwatson buf, perm_buf, effective_perm_buf); 14856055Srwatson } else { 14956055Srwatson len = asprintf(&tmpbuf, "%sgroup::%s\n", buf, 15056055Srwatson perm_buf); 15156055Srwatson } 15270841Srwatson if (len == -1) 15356055Srwatson goto error_label; 15456055Srwatson free(buf); 15556055Srwatson buf = tmpbuf; 15656055Srwatson break; 15756055Srwatson 15856055Srwatson case ACL_GROUP: 15974191Srwatson error = _posix1e_acl_perm_to_string(ae_perm, 16074191Srwatson _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 16156055Srwatson if (error) 16256055Srwatson goto error_label; 16356055Srwatson 16474191Srwatson error = _posix1e_acl_id_to_name(ae_tag, ae_id, 165200142Sed MAXLOGNAME, name_buf, flags); 16656055Srwatson if (error) 16756055Srwatson goto error_label; 16856055Srwatson 16956055Srwatson effective_perm = ae_perm & mask_perm; 17056055Srwatson if (effective_perm != ae_perm) { 17174191Srwatson error = _posix1e_acl_perm_to_string( 17274191Srwatson effective_perm, 17374191Srwatson _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, 17456055Srwatson effective_perm_buf); 17556055Srwatson if (error) 17656055Srwatson goto error_label; 177117982Srwatson len = asprintf(&tmpbuf, "%sgroup:%s:%s\t\t# " 17856055Srwatson "effective: %s\n", 179117982Srwatson buf, name_buf, perm_buf, 180117982Srwatson effective_perm_buf); 18156055Srwatson } else { 18256055Srwatson len = asprintf(&tmpbuf, "%sgroup:%s:%s\n", buf, 18356055Srwatson name_buf, perm_buf); 18456055Srwatson } 18570841Srwatson if (len == -1) 18656055Srwatson goto error_label; 18756055Srwatson free(buf); 18856055Srwatson buf = tmpbuf; 18956055Srwatson break; 19056055Srwatson 19156055Srwatson case ACL_MASK: 19274191Srwatson error = _posix1e_acl_perm_to_string(ae_perm, 19374191Srwatson _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 19456055Srwatson if (error) 19556055Srwatson goto error_label; 19656055Srwatson 19756055Srwatson len = asprintf(&tmpbuf, "%smask::%s\n", buf, 19856055Srwatson perm_buf); 19970841Srwatson if (len == -1) 20056055Srwatson goto error_label; 20156055Srwatson free(buf); 20256055Srwatson buf = tmpbuf; 20356055Srwatson break; 20456055Srwatson 20556055Srwatson case ACL_OTHER: 20674191Srwatson error = _posix1e_acl_perm_to_string(ae_perm, 20774191Srwatson _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 20856055Srwatson if (error) 20956055Srwatson goto error_label; 21056055Srwatson 21156055Srwatson len = asprintf(&tmpbuf, "%sother::%s\n", buf, 21256055Srwatson perm_buf); 21370841Srwatson if (len == -1) 21456055Srwatson goto error_label; 21556055Srwatson free(buf); 21656055Srwatson buf = tmpbuf; 21756055Srwatson break; 21856055Srwatson 21956055Srwatson default: 22056055Srwatson errno = EINVAL; 22170841Srwatson goto error_label; 22256055Srwatson } 22356055Srwatson } 22456055Srwatson 22556055Srwatson if (len_p) { 22656055Srwatson *len_p = strlen(buf); 22756055Srwatson } 22856055Srwatson return (buf); 22956055Srwatson 23056055Srwatsonerror_label: 23156055Srwatson /* jump to here sets errno already, we just clean up */ 23256055Srwatson if (buf) free(buf); 23371142Srwatson return (NULL); 23456055Srwatson} 235194955Strasz 236194955Straszchar * 237194955Straszacl_to_text_np(acl_t acl, ssize_t *len_p, int flags) 238194955Strasz{ 239194955Strasz 240196740Strasz if (acl == NULL) { 241196740Strasz errno = EINVAL; 242196740Strasz return(NULL); 243196740Strasz } 244196740Strasz 245194955Strasz switch (_acl_brand(acl)) { 246194955Strasz case ACL_BRAND_POSIX: 247194955Strasz return (_posix1e_acl_to_text(acl, len_p, flags)); 248194955Strasz case ACL_BRAND_NFS4: 249194955Strasz return (_nfs4_acl_to_text_np(acl, len_p, flags)); 250194955Strasz default: 251194955Strasz errno = EINVAL; 252194955Strasz return (NULL); 253194955Strasz } 254194955Strasz} 255194955Strasz 256194955Straszchar * 257194955Straszacl_to_text(acl_t acl, ssize_t *len_p) 258194955Strasz{ 259194955Strasz 260194955Strasz return (acl_to_text_np(acl, len_p, 0)); 261194955Strasz} 262