acl_to_text.c revision 91034
119370Spst/*- 2130803Smarcel * Copyright (c) 1999-2002 Robert N. M. Watson 398944Sobrien * All rights reserved. 419370Spst * 519370Spst * Redistribution and use in source and binary forms, with or without 619370Spst * modification, are permitted provided that the following conditions 798944Sobrien * are met: 819370Spst * 1. Redistributions of source code must retain the above copyright 998944Sobrien * notice, this list of conditions and the following disclaimer. 1098944Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1198944Sobrien * notice, this list of conditions and the following disclaimer in the 1298944Sobrien * documentation and/or other materials provided with the distribution. 1319370Spst * 1498944Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1598944Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1698944Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1798944Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1819370Spst * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1998944Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2098944Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2198944Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2298944Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2319370Spst * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2419370Spst * SUCH DAMAGE. 2519370Spst * 2619370Spst * $FreeBSD: head/lib/libc/posix1e/acl_to_text.c 91034 2002-02-21 23:17:19Z jedgar $ 2719370Spst */ 2819370Spst/* 2919370Spst * acl_to_text - return a text string with a text representation of the acl 3019370Spst * in it. 3119370Spst */ 3298944Sobrien 3319370Spst#include <sys/types.h> 3419370Spst#include "namespace.h" 3519370Spst#include <sys/acl.h> 36130803Smarcel#include "un-namespace.h" 3719370Spst#include <sys/errno.h> 3846283Sdfr#include <stdio.h> 3998944Sobrien#include <stdlib.h> 4046283Sdfr#include <string.h> 4119370Spst#include <utmp.h> 4298944Sobrien 4398944Sobrien#include "acl_support.h" 4498944Sobrien 4598944Sobrien/* 4698944Sobrien * acl_to_text - generate a text form of an acl 4798944Sobrien * spec says nothing about output ordering, so leave in acl order 4898944Sobrien * 4998944Sobrien * This function will not produce nice results if it is called with 50130803Smarcel * a non-POSIX.1e semantics ACL. 51130803Smarcel */ 5298944Sobrienchar * 5398944Sobrienacl_to_text(acl_t acl, ssize_t *len_p) 5498944Sobrien{ 5519370Spst struct acl *acl_int; 5698944Sobrien char *buf, *tmpbuf; 5719370Spst char name_buf[UT_NAMESIZE+1]; 5819370Spst char perm_buf[_POSIX1E_ACL_STRING_PERM_MAXSIZE+1], 5919370Spst effective_perm_buf[_POSIX1E_ACL_STRING_PERM_MAXSIZE+1]; 6019370Spst int i, error, len; 6119370Spst uid_t ae_id; 6298944Sobrien acl_tag_t ae_tag; 6319370Spst acl_perm_t ae_perm, effective_perm, mask_perm; 6419370Spst 6519370Spst buf = strdup(""); 6698944Sobrien if (buf == NULL) 6719370Spst return(NULL); 6819370Spst 6919370Spst if (acl == NULL) { 7098944Sobrien errno = EINVAL; 7198944Sobrien return(NULL); 7219370Spst } 7398944Sobrien 7498944Sobrien acl_int = &acl->ats_acl; 7598944Sobrien 7619370Spst mask_perm = ACL_PERM_BITS; /* effective is regular if no mask */ 7719370Spst for (i = 0; i < acl_int->acl_cnt; i++) 7819370Spst if (acl_int->acl_entry[i].ae_tag == ACL_MASK) 79130803Smarcel mask_perm = acl_int->acl_entry[i].ae_perm; 8098944Sobrien 8119370Spst for (i = 0; i < acl_int->acl_cnt; i++) { 8298944Sobrien ae_tag = acl_int->acl_entry[i].ae_tag; 8398944Sobrien ae_id = acl_int->acl_entry[i].ae_id; 8419370Spst ae_perm = acl_int->acl_entry[i].ae_perm; 8519370Spst 8619370Spst switch(ae_tag) { 8719370Spst case ACL_USER_OBJ: 8819370Spst error = _posix1e_acl_perm_to_string(ae_perm, 8998944Sobrien _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 9098944Sobrien if (error) 9119370Spst goto error_label; 9298944Sobrien len = asprintf(&tmpbuf, "%suser::%s\n", buf, 9398944Sobrien perm_buf); 9419370Spst if (len == -1) 9519370Spst goto error_label; 9698944Sobrien free(buf); 9798944Sobrien buf = tmpbuf; 9898944Sobrien break; 9998944Sobrien 10098944Sobrien case ACL_USER: 10198944Sobrien error = _posix1e_acl_perm_to_string(ae_perm, 10219370Spst _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 103130803Smarcel if (error) 10498944Sobrien goto error_label; 10519370Spst 10698944Sobrien error = _posix1e_acl_id_to_name(ae_tag, ae_id, 107130803Smarcel UT_NAMESIZE+1, name_buf); 108130803Smarcel if (error) 109130803Smarcel goto error_label; 11098944Sobrien 11119370Spst effective_perm = ae_perm & mask_perm; 11219370Spst if (effective_perm != ae_perm) { 11319370Spst error = _posix1e_acl_perm_to_string( 11498944Sobrien effective_perm, 11598944Sobrien _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, 11619370Spst effective_perm_buf); 11798944Sobrien if (error) 11898944Sobrien goto error_label; 11998944Sobrien len = asprintf(&tmpbuf, "%suser:%s:%s\t\t# " 12098944Sobrien "effective: %s\n", 12198944Sobrien buf, name_buf, perm_buf, 12219370Spst effective_perm_buf); 12398944Sobrien } else { 12419370Spst len = asprintf(&tmpbuf, "%suser:%s:%s\n", buf, 12519370Spst name_buf, perm_buf); 12619370Spst } 12719370Spst if (len == -1) 12898944Sobrien goto error_label; 12998944Sobrien free(buf); 13019370Spst buf = tmpbuf; 13119370Spst break; 13298944Sobrien 13398944Sobrien case ACL_GROUP_OBJ: 13419370Spst error = _posix1e_acl_perm_to_string(ae_perm, 13519370Spst _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 13619370Spst if (error) 137130803Smarcel goto error_label; 13898944Sobrien 13919370Spst effective_perm = ae_perm & mask_perm; 14098944Sobrien if (effective_perm != ae_perm) { 14198944Sobrien error = _posix1e_acl_perm_to_string( 14219370Spst effective_perm, 14319370Spst _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, 14419370Spst effective_perm_buf); 14519370Spst if (error) 14619370Spst goto error_label; 14798944Sobrien len = asprintf(&tmpbuf, "%sgroup::%s\t\t# " 14898944Sobrien "effective: %s\n", 14919370Spst buf, perm_buf, effective_perm_buf); 15098944Sobrien } else { 15198944Sobrien len = asprintf(&tmpbuf, "%sgroup::%s\n", buf, 15219370Spst perm_buf); 15319370Spst } 15498944Sobrien if (len == -1) 15598944Sobrien goto error_label; 15698944Sobrien free(buf); 15719370Spst buf = tmpbuf; 15898944Sobrien break; 15998944Sobrien 16098944Sobrien case ACL_GROUP: 16198944Sobrien error = _posix1e_acl_perm_to_string(ae_perm, 16219370Spst _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 16398944Sobrien if (error) 16498944Sobrien goto error_label; 16519370Spst 166130803Smarcel error = _posix1e_acl_id_to_name(ae_tag, ae_id, 16798944Sobrien UT_NAMESIZE+1, name_buf); 16819370Spst if (error) 16998944Sobrien goto error_label; 170130803Smarcel 171130803Smarcel effective_perm = ae_perm & mask_perm; 172130803Smarcel if (effective_perm != ae_perm) { 17398944Sobrien error = _posix1e_acl_perm_to_string( 17419370Spst effective_perm, 17519370Spst _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, 17619370Spst effective_perm_buf); 17798944Sobrien if (error) 17819370Spst goto error_label; 17919370Spst len = asprintf(&tmpbuf, "%sgroup::%s\t\t# " 18098944Sobrien "effective: %s\n", 18198944Sobrien buf, perm_buf, effective_perm_buf); 18298944Sobrien } else { 18398944Sobrien len = asprintf(&tmpbuf, "%sgroup:%s:%s\n", buf, 18498944Sobrien name_buf, perm_buf); 18519370Spst } 18698944Sobrien if (len == -1) 18719370Spst goto error_label; 18819370Spst free(buf); 18919370Spst buf = tmpbuf; 19019370Spst break; 19198944Sobrien 19219370Spst case ACL_MASK: 19346283Sdfr error = _posix1e_acl_perm_to_string(ae_perm, 19498944Sobrien _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 19519370Spst if (error) 19619370Spst goto error_label; 19798944Sobrien 19898944Sobrien len = asprintf(&tmpbuf, "%smask::%s\n", buf, 19998944Sobrien perm_buf); 20019370Spst if (len == -1) 20119370Spst goto error_label; 20219370Spst free(buf); 20319370Spst buf = tmpbuf; 20419370Spst break; 20598944Sobrien 20619370Spst case ACL_OTHER: 20798944Sobrien error = _posix1e_acl_perm_to_string(ae_perm, 20898944Sobrien _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf); 20998944Sobrien if (error) 21098944Sobrien goto error_label; 21119370Spst 21298944Sobrien len = asprintf(&tmpbuf, "%sother::%s\n", buf, 21398944Sobrien perm_buf); 21498944Sobrien if (len == -1) 21519370Spst goto error_label; 21698944Sobrien free(buf); 21798944Sobrien buf = tmpbuf; 21898944Sobrien break; 21919370Spst 22098944Sobrien default: 22198944Sobrien errno = EINVAL; 22298944Sobrien goto error_label; 22398944Sobrien } 22419370Spst } 22519370Spst 22698944Sobrien if (len_p) { 22719370Spst *len_p = strlen(buf); 22819370Spst } 22998944Sobrien return (buf); 23019370Spst 23198944Sobrienerror_label: 23298944Sobrien /* jump to here sets errno already, we just clean up */ 23319370Spst if (buf) free(buf); 23419370Spst return (NULL); 23519370Spst} 23619370Spst