acl_to_text.c revision 196740
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: head/lib/libc/posix1e/acl_to_text.c 196740 2009-09-01 18:30:17Z trasz $"); 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#include <utmp.h> 4356055Srwatson 4456055Srwatson#include "acl_support.h" 4556055Srwatson 4656055Srwatson/* 4756055Srwatson * acl_to_text - generate a text form of an acl 4856055Srwatson * spec says nothing about output ordering, so leave in acl order 4956055Srwatson * 5056625Srwatson * This function will not produce nice results if it is called with 5156625Srwatson * a non-POSIX.1e semantics ACL. 5256055Srwatson */ 53194955Strasz 54194955Straszchar *_nfs4_acl_to_text_np(const acl_t acl, ssize_t *len_p, int flags); 55194955Strasz 56194955Straszstatic char * 57194955Strasz_posix1e_acl_to_text(acl_t acl, ssize_t *len_p, int flags) 5856055Srwatson{ 5975928Sjedgar struct acl *acl_int; 6075928Sjedgar char *buf, *tmpbuf; 6175928Sjedgar char name_buf[UT_NAMESIZE+1]; 6275928Sjedgar char perm_buf[_POSIX1E_ACL_STRING_PERM_MAXSIZE+1], 6375928Sjedgar effective_perm_buf[_POSIX1E_ACL_STRING_PERM_MAXSIZE+1]; 6475928Sjedgar int i, error, len; 6575928Sjedgar uid_t ae_id; 6675928Sjedgar acl_tag_t ae_tag; 6775928Sjedgar acl_perm_t ae_perm, effective_perm, mask_perm; 6856055Srwatson 6956055Srwatson buf = strdup(""); 7091034Sjedgar if (buf == NULL) 7171142Srwatson return(NULL); 7256055Srwatson 7375928Sjedgar acl_int = &acl->ats_acl; 7475928Sjedgar 7556055Srwatson mask_perm = ACL_PERM_BITS; /* effective is regular if no mask */ 7675928Sjedgar for (i = 0; i < acl_int->acl_cnt; i++) 7775928Sjedgar if (acl_int->acl_entry[i].ae_tag == ACL_MASK) 7875928Sjedgar mask_perm = acl_int->acl_entry[i].ae_perm; 7956055Srwatson 8075928Sjedgar for (i = 0; i < acl_int->acl_cnt; i++) { 8175928Sjedgar ae_tag = acl_int->acl_entry[i].ae_tag; 8275928Sjedgar ae_id = acl_int->acl_entry[i].ae_id; 8375928Sjedgar ae_perm = acl_int->acl_entry[i].ae_perm; 8456055Srwatson 8556055Srwatson switch(ae_tag) { 8656055Srwatson case ACL_USER_OBJ: 8774191Srwatson error = _posix1e_acl_perm_to_string(ae_perm, 8874191Srwatson _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 8956055Srwatson if (error) 9056055Srwatson goto error_label; 9156055Srwatson len = asprintf(&tmpbuf, "%suser::%s\n", buf, 9256055Srwatson perm_buf); 9370841Srwatson if (len == -1) 9456055Srwatson goto error_label; 9556055Srwatson free(buf); 9656055Srwatson buf = tmpbuf; 9756055Srwatson break; 9856055Srwatson 9956055Srwatson case ACL_USER: 10074191Srwatson error = _posix1e_acl_perm_to_string(ae_perm, 10174191Srwatson _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 10256055Srwatson if (error) 10356055Srwatson goto error_label; 10456055Srwatson 10574191Srwatson error = _posix1e_acl_id_to_name(ae_tag, ae_id, 106194955Strasz UT_NAMESIZE+1, name_buf, flags); 10756055Srwatson if (error) 10856055Srwatson goto error_label; 10956055Srwatson 11056055Srwatson effective_perm = ae_perm & mask_perm; 11156055Srwatson if (effective_perm != ae_perm) { 11274191Srwatson error = _posix1e_acl_perm_to_string( 11374191Srwatson effective_perm, 11474191Srwatson _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, 11556055Srwatson effective_perm_buf); 11656055Srwatson if (error) 11756055Srwatson goto error_label; 11856055Srwatson len = asprintf(&tmpbuf, "%suser:%s:%s\t\t# " 11956055Srwatson "effective: %s\n", 12056055Srwatson buf, name_buf, perm_buf, 12156055Srwatson effective_perm_buf); 12256055Srwatson } else { 12356055Srwatson len = asprintf(&tmpbuf, "%suser:%s:%s\n", buf, 12456055Srwatson name_buf, perm_buf); 12556055Srwatson } 12670841Srwatson if (len == -1) 12756055Srwatson goto error_label; 12856055Srwatson free(buf); 12956055Srwatson buf = tmpbuf; 13056055Srwatson break; 13156055Srwatson 13256055Srwatson case ACL_GROUP_OBJ: 13374191Srwatson error = _posix1e_acl_perm_to_string(ae_perm, 13474191Srwatson _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 13556055Srwatson if (error) 13656055Srwatson goto error_label; 13756055Srwatson 13856055Srwatson effective_perm = ae_perm & mask_perm; 13956055Srwatson if (effective_perm != ae_perm) { 14074191Srwatson error = _posix1e_acl_perm_to_string( 14174191Srwatson effective_perm, 14274191Srwatson _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, 14356055Srwatson effective_perm_buf); 14456055Srwatson if (error) 14556055Srwatson goto error_label; 14656055Srwatson len = asprintf(&tmpbuf, "%sgroup::%s\t\t# " 14756055Srwatson "effective: %s\n", 14856055Srwatson buf, perm_buf, effective_perm_buf); 14956055Srwatson } else { 15056055Srwatson len = asprintf(&tmpbuf, "%sgroup::%s\n", buf, 15156055Srwatson perm_buf); 15256055Srwatson } 15370841Srwatson if (len == -1) 15456055Srwatson goto error_label; 15556055Srwatson free(buf); 15656055Srwatson buf = tmpbuf; 15756055Srwatson break; 15856055Srwatson 15956055Srwatson case ACL_GROUP: 16074191Srwatson error = _posix1e_acl_perm_to_string(ae_perm, 16174191Srwatson _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 16256055Srwatson if (error) 16356055Srwatson goto error_label; 16456055Srwatson 16574191Srwatson error = _posix1e_acl_id_to_name(ae_tag, ae_id, 166194955Strasz UT_NAMESIZE+1, name_buf, flags); 16756055Srwatson if (error) 16856055Srwatson goto error_label; 16956055Srwatson 17056055Srwatson effective_perm = ae_perm & mask_perm; 17156055Srwatson if (effective_perm != ae_perm) { 17274191Srwatson error = _posix1e_acl_perm_to_string( 17374191Srwatson effective_perm, 17474191Srwatson _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, 17556055Srwatson effective_perm_buf); 17656055Srwatson if (error) 17756055Srwatson goto error_label; 178117982Srwatson len = asprintf(&tmpbuf, "%sgroup:%s:%s\t\t# " 17956055Srwatson "effective: %s\n", 180117982Srwatson buf, name_buf, perm_buf, 181117982Srwatson effective_perm_buf); 18256055Srwatson } else { 18356055Srwatson len = asprintf(&tmpbuf, "%sgroup:%s:%s\n", buf, 18456055Srwatson name_buf, perm_buf); 18556055Srwatson } 18670841Srwatson if (len == -1) 18756055Srwatson goto error_label; 18856055Srwatson free(buf); 18956055Srwatson buf = tmpbuf; 19056055Srwatson break; 19156055Srwatson 19256055Srwatson case ACL_MASK: 19374191Srwatson error = _posix1e_acl_perm_to_string(ae_perm, 19474191Srwatson _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 19556055Srwatson if (error) 19656055Srwatson goto error_label; 19756055Srwatson 19856055Srwatson len = asprintf(&tmpbuf, "%smask::%s\n", buf, 19956055Srwatson perm_buf); 20070841Srwatson if (len == -1) 20156055Srwatson goto error_label; 20256055Srwatson free(buf); 20356055Srwatson buf = tmpbuf; 20456055Srwatson break; 20556055Srwatson 20656055Srwatson case ACL_OTHER: 20774191Srwatson error = _posix1e_acl_perm_to_string(ae_perm, 20874191Srwatson _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 20956055Srwatson if (error) 21056055Srwatson goto error_label; 21156055Srwatson 21256055Srwatson len = asprintf(&tmpbuf, "%sother::%s\n", buf, 21356055Srwatson perm_buf); 21470841Srwatson if (len == -1) 21556055Srwatson goto error_label; 21656055Srwatson free(buf); 21756055Srwatson buf = tmpbuf; 21856055Srwatson break; 21956055Srwatson 22056055Srwatson default: 22156055Srwatson errno = EINVAL; 22270841Srwatson goto error_label; 22356055Srwatson } 22456055Srwatson } 22556055Srwatson 22656055Srwatson if (len_p) { 22756055Srwatson *len_p = strlen(buf); 22856055Srwatson } 22956055Srwatson return (buf); 23056055Srwatson 23156055Srwatsonerror_label: 23256055Srwatson /* jump to here sets errno already, we just clean up */ 23356055Srwatson if (buf) free(buf); 23471142Srwatson return (NULL); 23556055Srwatson} 236194955Strasz 237194955Straszchar * 238194955Straszacl_to_text_np(acl_t acl, ssize_t *len_p, int flags) 239194955Strasz{ 240194955Strasz 241196740Strasz if (acl == NULL) { 242196740Strasz errno = EINVAL; 243196740Strasz return(NULL); 244196740Strasz } 245196740Strasz 246194955Strasz switch (_acl_brand(acl)) { 247194955Strasz case ACL_BRAND_POSIX: 248194955Strasz return (_posix1e_acl_to_text(acl, len_p, flags)); 249194955Strasz case ACL_BRAND_NFS4: 250194955Strasz return (_nfs4_acl_to_text_np(acl, len_p, flags)); 251194955Strasz default: 252194955Strasz errno = EINVAL; 253194955Strasz return (NULL); 254194955Strasz } 255194955Strasz} 256194955Strasz 257194955Straszchar * 258194955Straszacl_to_text(acl_t acl, ssize_t *len_p) 259194955Strasz{ 260194955Strasz 261194955Strasz return (acl_to_text_np(acl, len_p, 0)); 262194955Strasz} 263