Deleted Added
full compact
acl_from_text.c (167006) acl_from_text.c (194955)
1/*-
2 * Copyright (c) 1999, 2000, 2001 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

--- 14 unchanged lines hidden (view full) ---

23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26/*
27 * acl_from_text: Convert a text-form ACL from a string to an acl_t.
28 */
29
30#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 1999, 2000, 2001 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

--- 14 unchanged lines hidden (view full) ---

23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26/*
27 * acl_from_text: Convert a text-form ACL from a string to an acl_t.
28 */
29
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD: head/lib/libc/posix1e/acl_from_text.c 167006 2007-02-26 02:07:02Z kientzle $");
31__FBSDID("$FreeBSD: head/lib/libc/posix1e/acl_from_text.c 194955 2009-06-25 12:46:59Z trasz $");
32
33#include <sys/types.h>
34#include "namespace.h"
35#include <sys/acl.h>
36#include "un-namespace.h"
37#include <sys/errno.h>
38#include <grp.h>
39#include <pwd.h>
40#include <stdio.h>
41#include <stdlib.h>
42#include <string.h>
32
33#include <sys/types.h>
34#include "namespace.h"
35#include <sys/acl.h>
36#include "un-namespace.h"
37#include <sys/errno.h>
38#include <grp.h>
39#include <pwd.h>
40#include <stdio.h>
41#include <stdlib.h>
42#include <string.h>
43#include <assert.h>
43
44#include "acl_support.h"
45
46static int _posix1e_acl_name_to_id(acl_tag_t tag, char *name, uid_t *id);
47static acl_tag_t acl_string_to_tag(char *tag, char *qualifier);
44
45#include "acl_support.h"
46
47static int _posix1e_acl_name_to_id(acl_tag_t tag, char *name, uid_t *id);
48static acl_tag_t acl_string_to_tag(char *tag, char *qualifier);
48static char *string_skip_whitespace(char *string);
49static void string_trim_trailing_whitespace(char *string);
50
49
51static char *
52string_skip_whitespace(char *string)
53{
50int _nfs4_acl_entry_from_text(acl_t aclp, char *entry);
51int _text_could_be_nfs4_acl(const char *entry);
54
52
55 while (*string && ((*string == ' ') || (*string == '\t'))) {
56 string++;
57 }
58 return (string);
59}
60
61static void
62string_trim_trailing_whitespace(char *string)
63{
64 char *end;
65
66 if (*string == '\0')
67 return;
68
69 end = string + strlen(string) - 1;
70
71 while (end != string) {
72 if ((*end == ' ') || (*end == '\t')) {
73 *end = '\0';
74 end--;
75 } else {
76 return;
77 }
78 }
79
80 return;
81}
82
83static acl_tag_t
84acl_string_to_tag(char *tag, char *qualifier)
85{
86
87 if (*qualifier == '\0') {
88 if ((!strcmp(tag, "user")) || (!strcmp(tag, "u"))) {
89 return (ACL_USER_OBJ);
90 } else

--- 13 unchanged lines hidden (view full) ---

104 } else
105 if ((!strcmp(tag, "group")) || (!strcmp(tag, "g"))) {
106 return(ACL_GROUP);
107 } else
108 return(-1);
109 }
110}
111
53static acl_tag_t
54acl_string_to_tag(char *tag, char *qualifier)
55{
56
57 if (*qualifier == '\0') {
58 if ((!strcmp(tag, "user")) || (!strcmp(tag, "u"))) {
59 return (ACL_USER_OBJ);
60 } else

--- 13 unchanged lines hidden (view full) ---

74 } else
75 if ((!strcmp(tag, "group")) || (!strcmp(tag, "g"))) {
76 return(ACL_GROUP);
77 } else
78 return(-1);
79 }
80}
81
82static int
83_posix1e_acl_entry_from_text(acl_t aclp, char *entry)
84{
85 acl_tag_t t;
86 acl_perm_t p;
87 char *tag, *qualifier, *permission;
88 uid_t id;
89 int error;
90
91 assert(_acl_brand(aclp) == ACL_BRAND_POSIX);
92
93 /* Split into three ':' delimited fields. */
94 tag = strsep(&entry, ":");
95 if (tag == NULL) {
96 errno = EINVAL;
97 return (-1);
98 }
99 tag = string_skip_whitespace(tag);
100 if ((*tag == '\0') && (!entry)) {
101 /*
102 * Is an entirely comment line, skip to next
103 * comma.
104 */
105 return (0);
106 }
107 string_trim_trailing_whitespace(tag);
108
109 qualifier = strsep(&entry, ":");
110 if (qualifier == NULL) {
111 errno = EINVAL;
112 return (-1);
113 }
114 qualifier = string_skip_whitespace(qualifier);
115 string_trim_trailing_whitespace(qualifier);
116
117 permission = strsep(&entry, ":");
118 if (permission == NULL || entry) {
119 errno = EINVAL;
120 return (-1);
121 }
122 permission = string_skip_whitespace(permission);
123 string_trim_trailing_whitespace(permission);
124
125 t = acl_string_to_tag(tag, qualifier);
126 if (t == -1) {
127 errno = EINVAL;
128 return (-1);
129 }
130
131 error = _posix1e_acl_string_to_perm(permission, &p);
132 if (error == -1) {
133 errno = EINVAL;
134 return (-1);
135 }
136
137 switch(t) {
138 case ACL_USER_OBJ:
139 case ACL_GROUP_OBJ:
140 case ACL_MASK:
141 case ACL_OTHER:
142 if (*qualifier != '\0') {
143 errno = EINVAL;
144 return (-1);
145 }
146 id = 0;
147 break;
148
149 case ACL_USER:
150 case ACL_GROUP:
151 error = _posix1e_acl_name_to_id(t, qualifier,
152 &id);
153 if (error == -1)
154 return (-1);
155 break;
156
157 default:
158 errno = EINVAL;
159 return (-1);
160 }
161
162 error = _posix1e_acl_add_entry(aclp, t, id, p);
163 if (error == -1)
164 return (-1);
165
166 return (0);
167}
168
169static int
170_text_is_nfs4_entry(const char *entry)
171{
172 int count = 0;
173
174 assert(strlen(entry) > 0);
175
176 while (*entry != '\0') {
177 if (*entry == ':' || *entry == '@')
178 count++;
179 entry++;
180 }
181
182 if (count <= 2)
183 return (0);
184
185 return (1);
186}
187
112/*
113 * acl_from_text -- Convert a string into an ACL.
114 * Postpone most validity checking until the end and call acl_valid() to do
115 * that.
116 */
117acl_t
118acl_from_text(const char *buf_p)
119{
188/*
189 * acl_from_text -- Convert a string into an ACL.
190 * Postpone most validity checking until the end and call acl_valid() to do
191 * that.
192 */
193acl_t
194acl_from_text(const char *buf_p)
195{
120 acl_tag_t t;
121 acl_perm_t p;
122 acl_t acl;
123 char *mybuf_p, *line, *cur, *notcomment, *comment, *entry;
196 acl_t acl;
197 char *mybuf_p, *line, *cur, *notcomment, *comment, *entry;
124 char *tag, *qualifier, *permission;
125 int error;
198 int error;
126 uid_t id;
127
128 /* Local copy we can mess up. */
129 mybuf_p = strdup(buf_p);
130 if (mybuf_p == NULL)
131 return(NULL);
132
199
200 /* Local copy we can mess up. */
201 mybuf_p = strdup(buf_p);
202 if (mybuf_p == NULL)
203 return(NULL);
204
133 acl = acl_init(3);
205 acl = acl_init(3); /* XXX: WTF, 3? */
134 if (acl == NULL) {
135 free(mybuf_p);
136 return(NULL);
137 }
138
139 /* Outer loop: delimit at \n boundaries. */
140 cur = mybuf_p;
141 while ((line = strsep(&cur, "\n"))) {
142 /* Now split the line on the first # to strip out comments. */
143 comment = line;
144 notcomment = strsep(&comment, "#");
145
146 /* Inner loop: delimit at ',' boundaries. */
147 while ((entry = strsep(&notcomment, ","))) {
206 if (acl == NULL) {
207 free(mybuf_p);
208 return(NULL);
209 }
210
211 /* Outer loop: delimit at \n boundaries. */
212 cur = mybuf_p;
213 while ((line = strsep(&cur, "\n"))) {
214 /* Now split the line on the first # to strip out comments. */
215 comment = line;
216 notcomment = strsep(&comment, "#");
217
218 /* Inner loop: delimit at ',' boundaries. */
219 while ((entry = strsep(&notcomment, ","))) {
148 /* Now split into three ':' delimited fields. */
149 tag = strsep(&entry, ":");
150 if (tag == NULL) {
151 errno = EINVAL;
152 goto error_label;
153 }
154 tag = string_skip_whitespace(tag);
155 if ((*tag == '\0') && (!entry)) {
156 /*
157 * Is an entirely comment line, skip to next
158 * comma.
159 */
220
221 /* Skip empty lines. */
222 if (strlen(string_skip_whitespace(entry)) == 0)
160 continue;
223 continue;
161 }
162 string_trim_trailing_whitespace(tag);
163
224
164 qualifier = strsep(&entry, ":");
165 if (qualifier == NULL) {
166 errno = EINVAL;
167 goto error_label;
225 if (_acl_brand(acl) == ACL_BRAND_UNKNOWN) {
226 if (_text_is_nfs4_entry(entry))
227 _acl_brand_as(acl, ACL_BRAND_NFS4);
228 else
229 _acl_brand_as(acl, ACL_BRAND_POSIX);
168 }
230 }
169 qualifier = string_skip_whitespace(qualifier);
170 string_trim_trailing_whitespace(qualifier);
171
231
172 permission = strsep(&entry, ":");
173 if (permission == NULL || entry) {
174 errno = EINVAL;
175 goto error_label;
176 }
177 permission = string_skip_whitespace(permission);
178 string_trim_trailing_whitespace(permission);
179
180 t = acl_string_to_tag(tag, qualifier);
181 if (t == -1) {
182 errno = EINVAL;
183 goto error_label;
184 }
185
186 error = _posix1e_acl_string_to_perm(permission, &p);
187 if (error == -1) {
188 errno = EINVAL;
189 goto error_label;
190 }
191
192 switch(t) {
193 case ACL_USER_OBJ:
194 case ACL_GROUP_OBJ:
195 case ACL_MASK:
196 case ACL_OTHER:
197 if (*qualifier != '\0') {
198 errno = EINVAL;
199 goto error_label;
200 }
201 id = 0;
232 switch (_acl_brand(acl)) {
233 case ACL_BRAND_NFS4:
234 error = _nfs4_acl_entry_from_text(acl, entry);
202 break;
203
235 break;
236
204 case ACL_USER:
205 case ACL_GROUP:
206 error = _posix1e_acl_name_to_id(t, qualifier,
207 &id);
208 if (error == -1)
209 goto error_label;
237 case ACL_BRAND_POSIX:
238 error = _posix1e_acl_entry_from_text(acl, entry);
210 break;
211
212 default:
239 break;
240
241 default:
213 errno = EINVAL;
214 goto error_label;
242 error = EINVAL;
243 break;
215 }
216
244 }
245
217 error = _posix1e_acl_add_entry(acl, t, id, p);
218 if (error == -1)
246 if (error)
219 goto error_label;
220 }
221 }
222
223#if 0
224 /* XXX Should we only return ACLs valid according to acl_valid? */
225 /* Verify validity of the ACL we read in. */
226 if (acl_valid(acl) == -1) {

--- 63 unchanged lines hidden ---
247 goto error_label;
248 }
249 }
250
251#if 0
252 /* XXX Should we only return ACLs valid according to acl_valid? */
253 /* Verify validity of the ACL we read in. */
254 if (acl_valid(acl) == -1) {

--- 63 unchanged lines hidden ---