]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - lib/libc/posix1e/acl_to_text.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / lib / libc / posix1e / acl_to_text.c
1 /*-
2  * Copyright (c) 1999-2002 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 /*
27  * acl_to_text - return a text string with a text representation of the acl
28  * in it.
29  */
30
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33
34 #include <sys/types.h>
35 #include "namespace.h"
36 #include <sys/acl.h>
37 #include "un-namespace.h"
38 #include <sys/errno.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <utmp.h>
43
44 #include "acl_support.h"
45
46 /*
47  * acl_to_text - generate a text form of an acl
48  * spec says nothing about output ordering, so leave in acl order
49  *
50  * This function will not produce nice results if it is called with
51  * a non-POSIX.1e semantics ACL.
52  */
53 char *
54 acl_to_text(acl_t acl, ssize_t *len_p)
55 {
56         struct acl      *acl_int;
57         char            *buf, *tmpbuf;
58         char             name_buf[UT_NAMESIZE+1];
59         char             perm_buf[_POSIX1E_ACL_STRING_PERM_MAXSIZE+1],
60                          effective_perm_buf[_POSIX1E_ACL_STRING_PERM_MAXSIZE+1];
61         int              i, error, len;
62         uid_t            ae_id;
63         acl_tag_t        ae_tag;
64         acl_perm_t       ae_perm, effective_perm, mask_perm;
65
66         buf = strdup("");
67         if (buf == NULL)
68                 return(NULL);
69
70         if (acl == NULL) {
71                 errno = EINVAL;
72                 return(NULL);
73         }
74
75         acl_int = &acl->ats_acl;
76
77         mask_perm = ACL_PERM_BITS;      /* effective is regular if no mask */
78         for (i = 0; i < acl_int->acl_cnt; i++)
79                 if (acl_int->acl_entry[i].ae_tag == ACL_MASK) 
80                         mask_perm = acl_int->acl_entry[i].ae_perm;
81
82         for (i = 0; i < acl_int->acl_cnt; i++) {
83                 ae_tag = acl_int->acl_entry[i].ae_tag;
84                 ae_id = acl_int->acl_entry[i].ae_id;
85                 ae_perm = acl_int->acl_entry[i].ae_perm;
86
87                 switch(ae_tag) {
88                 case ACL_USER_OBJ:
89                         error = _posix1e_acl_perm_to_string(ae_perm,
90                             _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf);
91                         if (error)
92                                 goto error_label;
93                         len = asprintf(&tmpbuf, "%suser::%s\n", buf,
94                             perm_buf);
95                         if (len == -1)
96                                 goto error_label;
97                         free(buf);
98                         buf = tmpbuf;
99                         break;
100
101                 case ACL_USER:
102                         error = _posix1e_acl_perm_to_string(ae_perm,
103                             _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf);
104                         if (error)
105                                 goto error_label;
106
107                         error = _posix1e_acl_id_to_name(ae_tag, ae_id,
108                             UT_NAMESIZE+1, name_buf);
109                         if (error)
110                                 goto error_label;
111
112                         effective_perm = ae_perm & mask_perm;
113                         if (effective_perm != ae_perm) {
114                                 error = _posix1e_acl_perm_to_string(
115                                     effective_perm,
116                                     _POSIX1E_ACL_STRING_PERM_MAXSIZE+1,
117                                     effective_perm_buf);
118                                 if (error)
119                                         goto error_label;
120                                 len = asprintf(&tmpbuf, "%suser:%s:%s\t\t# "
121                                     "effective: %s\n",
122                                     buf, name_buf, perm_buf,
123                                     effective_perm_buf);
124                         } else {
125                                 len = asprintf(&tmpbuf, "%suser:%s:%s\n", buf,
126                                     name_buf, perm_buf);
127                         }
128                         if (len == -1)
129                                 goto error_label;
130                         free(buf);
131                         buf = tmpbuf;
132                         break;
133
134                 case ACL_GROUP_OBJ:
135                         error = _posix1e_acl_perm_to_string(ae_perm,
136                             _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf);
137                         if (error)
138                                 goto error_label;
139
140                         effective_perm = ae_perm & mask_perm;
141                         if (effective_perm != ae_perm) {
142                                 error = _posix1e_acl_perm_to_string(
143                                     effective_perm,
144                                     _POSIX1E_ACL_STRING_PERM_MAXSIZE+1,
145                                     effective_perm_buf);
146                                 if (error)
147                                         goto error_label;
148                                 len = asprintf(&tmpbuf, "%sgroup::%s\t\t# "
149                                     "effective: %s\n",
150                                     buf, perm_buf, effective_perm_buf);
151                         } else {
152                                 len = asprintf(&tmpbuf, "%sgroup::%s\n", buf,
153                                     perm_buf);
154                         }
155                         if (len == -1)
156                                 goto error_label;
157                         free(buf);
158                         buf = tmpbuf;
159                         break;
160
161                 case ACL_GROUP:
162                         error = _posix1e_acl_perm_to_string(ae_perm,
163                             _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf);
164                         if (error)
165                                 goto error_label;
166
167                         error = _posix1e_acl_id_to_name(ae_tag, ae_id,
168                             UT_NAMESIZE+1, name_buf);
169                         if (error)
170                                 goto error_label;
171
172                         effective_perm = ae_perm & mask_perm;
173                         if (effective_perm != ae_perm) {
174                                 error = _posix1e_acl_perm_to_string(
175                                     effective_perm,
176                                     _POSIX1E_ACL_STRING_PERM_MAXSIZE+1,
177                                     effective_perm_buf);
178                                 if (error)
179                                         goto error_label;
180                                 len = asprintf(&tmpbuf, "%sgroup:%s:%s\t\t# "
181                                     "effective: %s\n",
182                                     buf, name_buf, perm_buf,
183                                     effective_perm_buf);
184                         } else {
185                                 len = asprintf(&tmpbuf, "%sgroup:%s:%s\n", buf,
186                                     name_buf, perm_buf);
187                         }
188                         if (len == -1)
189                                 goto error_label;
190                         free(buf);
191                         buf = tmpbuf;
192                         break;
193
194                 case ACL_MASK:
195                         error = _posix1e_acl_perm_to_string(ae_perm,
196                             _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf);
197                         if (error)
198                                 goto error_label;
199
200                         len = asprintf(&tmpbuf, "%smask::%s\n", buf,
201                             perm_buf);
202                         if (len == -1)
203                                 goto error_label;
204                         free(buf);
205                         buf = tmpbuf;
206                         break;
207
208                 case ACL_OTHER:
209                         error = _posix1e_acl_perm_to_string(ae_perm,
210                             _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf);
211                         if (error)
212                                 goto error_label;
213
214                         len = asprintf(&tmpbuf, "%sother::%s\n", buf,
215                             perm_buf);
216                         if (len == -1)
217                                 goto error_label;
218                         free(buf);
219                         buf = tmpbuf;
220                         break;
221
222                 default:
223                         errno = EINVAL;
224                         goto error_label;
225                 }
226         }
227
228         if (len_p) {
229                 *len_p = strlen(buf);
230         }
231         return (buf);
232
233 error_label:
234         /* jump to here sets errno already, we just clean up */
235         if (buf) free(buf);
236         return (NULL);
237 }