]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libc/posix1e/acl_to_text.c
MFV 364467:
[FreeBSD/FreeBSD.git] / lib / libc / posix1e / acl_to_text.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 1999-2002 Robert N. M. Watson
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 /*
29  * acl_to_text - return a text string with a text representation of the acl
30  * in it.
31  */
32
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
35
36 #include <sys/types.h>
37 #include "namespace.h"
38 #include <sys/acl.h>
39 #include "un-namespace.h"
40 #include <sys/errno.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44
45 #include "acl_support.h"
46
47 /*
48  * acl_to_text - generate a text form of an acl
49  * spec says nothing about output ordering, so leave in acl order
50  *
51  * This function will not produce nice results if it is called with
52  * a non-POSIX.1e semantics ACL.
53  */
54
55 char *_nfs4_acl_to_text_np(const acl_t acl, ssize_t *len_p, int flags);
56
57 static char *
58 _posix1e_acl_to_text(acl_t acl, ssize_t *len_p, int flags)
59 {
60         struct acl      *acl_int;
61         char            *buf, *tmpbuf;
62         char             name_buf[MAXLOGNAME];
63         char             perm_buf[_POSIX1E_ACL_STRING_PERM_MAXSIZE+1],
64                          effective_perm_buf[_POSIX1E_ACL_STRING_PERM_MAXSIZE+1];
65         int              i, error, len;
66         uid_t            ae_id;
67         acl_tag_t        ae_tag;
68         acl_perm_t       ae_perm, effective_perm, mask_perm;
69
70         buf = strdup("");
71         if (buf == NULL)
72                 return(NULL);
73
74         acl_int = &acl->ats_acl;
75
76         mask_perm = ACL_PERM_BITS;      /* effective is regular if no mask */
77         for (i = 0; i < acl_int->acl_cnt; i++)
78                 if (acl_int->acl_entry[i].ae_tag == ACL_MASK) 
79                         mask_perm = acl_int->acl_entry[i].ae_perm;
80
81         for (i = 0; i < acl_int->acl_cnt; i++) {
82                 ae_tag = acl_int->acl_entry[i].ae_tag;
83                 ae_id = acl_int->acl_entry[i].ae_id;
84                 ae_perm = acl_int->acl_entry[i].ae_perm;
85
86                 switch(ae_tag) {
87                 case ACL_USER_OBJ:
88                         error = _posix1e_acl_perm_to_string(ae_perm,
89                             _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf);
90                         if (error)
91                                 goto error_label;
92                         len = asprintf(&tmpbuf, "%suser::%s\n", buf,
93                             perm_buf);
94                         if (len == -1)
95                                 goto error_label;
96                         free(buf);
97                         buf = tmpbuf;
98                         break;
99
100                 case ACL_USER:
101                         error = _posix1e_acl_perm_to_string(ae_perm,
102                             _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf);
103                         if (error)
104                                 goto error_label;
105
106                         error = _posix1e_acl_id_to_name(ae_tag, ae_id,
107                             MAXLOGNAME, name_buf, flags);
108                         if (error)
109                                 goto error_label;
110
111                         effective_perm = ae_perm & mask_perm;
112                         if (effective_perm != ae_perm) {
113                                 error = _posix1e_acl_perm_to_string(
114                                     effective_perm,
115                                     _POSIX1E_ACL_STRING_PERM_MAXSIZE+1,
116                                     effective_perm_buf);
117                                 if (error)
118                                         goto error_label;
119                                 len = asprintf(&tmpbuf, "%suser:%s:%s\t\t# "
120                                     "effective: %s\n",
121                                     buf, name_buf, perm_buf,
122                                     effective_perm_buf);
123                         } else {
124                                 len = asprintf(&tmpbuf, "%suser:%s:%s\n", buf,
125                                     name_buf, perm_buf);
126                         }
127                         if (len == -1)
128                                 goto error_label;
129                         free(buf);
130                         buf = tmpbuf;
131                         break;
132
133                 case ACL_GROUP_OBJ:
134                         error = _posix1e_acl_perm_to_string(ae_perm,
135                             _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf);
136                         if (error)
137                                 goto error_label;
138
139                         effective_perm = ae_perm & mask_perm;
140                         if (effective_perm != ae_perm) {
141                                 error = _posix1e_acl_perm_to_string(
142                                     effective_perm,
143                                     _POSIX1E_ACL_STRING_PERM_MAXSIZE+1,
144                                     effective_perm_buf);
145                                 if (error)
146                                         goto error_label;
147                                 len = asprintf(&tmpbuf, "%sgroup::%s\t\t# "
148                                     "effective: %s\n",
149                                     buf, perm_buf, effective_perm_buf);
150                         } else {
151                                 len = asprintf(&tmpbuf, "%sgroup::%s\n", buf,
152                                     perm_buf);
153                         }
154                         if (len == -1)
155                                 goto error_label;
156                         free(buf);
157                         buf = tmpbuf;
158                         break;
159
160                 case ACL_GROUP:
161                         error = _posix1e_acl_perm_to_string(ae_perm,
162                             _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf);
163                         if (error)
164                                 goto error_label;
165
166                         error = _posix1e_acl_id_to_name(ae_tag, ae_id,
167                             MAXLOGNAME, name_buf, flags);
168                         if (error)
169                                 goto error_label;
170
171                         effective_perm = ae_perm & mask_perm;
172                         if (effective_perm != ae_perm) {
173                                 error = _posix1e_acl_perm_to_string(
174                                     effective_perm,
175                                     _POSIX1E_ACL_STRING_PERM_MAXSIZE+1,
176                                     effective_perm_buf);
177                                 if (error)
178                                         goto error_label;
179                                 len = asprintf(&tmpbuf, "%sgroup:%s:%s\t\t# "
180                                     "effective: %s\n",
181                                     buf, name_buf, perm_buf,
182                                     effective_perm_buf);
183                         } else {
184                                 len = asprintf(&tmpbuf, "%sgroup:%s:%s\n", buf,
185                                     name_buf, perm_buf);
186                         }
187                         if (len == -1)
188                                 goto error_label;
189                         free(buf);
190                         buf = tmpbuf;
191                         break;
192
193                 case ACL_MASK:
194                         error = _posix1e_acl_perm_to_string(ae_perm,
195                             _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf);
196                         if (error)
197                                 goto error_label;
198
199                         len = asprintf(&tmpbuf, "%smask::%s\n", buf,
200                             perm_buf);
201                         if (len == -1)
202                                 goto error_label;
203                         free(buf);
204                         buf = tmpbuf;
205                         break;
206
207                 case ACL_OTHER:
208                         error = _posix1e_acl_perm_to_string(ae_perm,
209                             _POSIX1E_ACL_STRING_PERM_MAXSIZE+1, perm_buf);
210                         if (error)
211                                 goto error_label;
212
213                         len = asprintf(&tmpbuf, "%sother::%s\n", buf,
214                             perm_buf);
215                         if (len == -1)
216                                 goto error_label;
217                         free(buf);
218                         buf = tmpbuf;
219                         break;
220
221                 default:
222                         errno = EINVAL;
223                         goto error_label;
224                 }
225         }
226
227         if (len_p) {
228                 *len_p = strlen(buf);
229         }
230         return (buf);
231
232 error_label:
233         /* jump to here sets errno already, we just clean up */
234         if (buf) free(buf);
235         return (NULL);
236 }
237
238 char *
239 acl_to_text_np(acl_t acl, ssize_t *len_p, int flags)
240 {
241
242         if (acl == NULL) {
243                 errno = EINVAL;
244                 return(NULL);
245         }
246
247         switch (_acl_brand(acl)) {
248         case ACL_BRAND_POSIX:
249                 return (_posix1e_acl_to_text(acl, len_p, flags));
250         case ACL_BRAND_NFS4:
251                 return (_nfs4_acl_to_text_np(acl, len_p, flags));
252         default:
253                 errno = EINVAL;
254                 return (NULL);
255         }
256 }
257
258 char *
259 acl_to_text(acl_t acl, ssize_t *len_p)
260 {
261
262         return (acl_to_text_np(acl, len_p, 0));
263 }