1 /*
2 * ProFTPD - FTP server daemon
3 * Copyright (c) 2008-2020 The ProFTPD Project team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
18 *
19 * As a special exemption, The ProFTPD Project team and other respective
20 * copyright holders give permission to link this program with OpenSSL, and
21 * distribute the resulting executable, without including the source code for
22 * OpenSSL in the source distribution.
23 */
24
25 /* Expression API implementation */
26
27 #include "conf.h"
28
pr_expr_create(pool * p,unsigned int * argc,char ** argv)29 array_header *pr_expr_create(pool *p, unsigned int *argc, char **argv) {
30 array_header *acl = NULL;
31 unsigned int cnt;
32 char *s, *ent;
33
34 if (p == NULL ||
35 argc == NULL ||
36 argv == NULL ||
37 *argv == NULL) {
38 errno = EINVAL;
39 return NULL;
40 }
41
42 cnt = *argc;
43
44 if (cnt > 0) {
45 acl = make_array(p, cnt, sizeof(char *));
46
47 /* Skip past the first string in argv, as this is usually the directive. */
48 while (cnt-- && *(++argv)) {
49 char *sep = ",";
50
51 s = pstrdup(p, *argv);
52
53 if (strstr(s, sep) != NULL) {
54 while ((ent = pr_str_get_token(&s, sep)) != NULL) {
55 pr_signals_handle();
56
57 if (*ent) {
58 *((char **) push_array(acl)) = ent;
59 }
60 }
61
62 } else {
63 *((char **) push_array(acl)) = s;
64 }
65 }
66
67 *argc = acl->nelts;
68
69 } else {
70 acl = make_array(p, 0, sizeof(char *));
71 *argc = 0;
72 }
73
74 return acl;
75 }
76
77 /* Boolean "class-expression" AND matching, returns TRUE if the expression
78 * evaluates to TRUE.
79 */
pr_expr_eval_class_and(char ** expr)80 int pr_expr_eval_class_and(char **expr) {
81 int found;
82 char *class;
83
84 if (expr == NULL ||
85 *expr == NULL) {
86 errno = EINVAL;
87 return -1;
88 }
89
90 for (; *expr; expr++) {
91 class = *expr;
92 found = FALSE;
93
94 if (*class == '!') {
95 found = !found;
96 class++;
97 }
98
99 if (session.conn_class == NULL &&
100 !found) {
101 return FALSE;
102 }
103
104 if (session.conn_class != NULL &&
105 strcmp(session.conn_class->cls_name, class) == 0) {
106 found = !found;
107 }
108
109 if (!found) {
110 return FALSE;
111 }
112 }
113
114 return TRUE;
115 }
116
117 /* Boolean "class-expression" OR matching, returns TRUE if the expression
118 * evaluates to TRUE.
119 */
pr_expr_eval_class_or(char ** expr)120 int pr_expr_eval_class_or(char **expr) {
121 int found;
122 char *class;
123
124 if (expr == NULL ||
125 *expr == NULL) {
126 errno = EINVAL;
127 return -1;
128 }
129
130 for (; *expr; expr++) {
131 class = *expr;
132 found = FALSE;
133
134 if (*class == '!') {
135 found = !found;
136 class++;
137 }
138
139 if (session.conn_class == NULL)
140 return found;
141
142 if (strcmp(session.conn_class->cls_name, class) == 0)
143 found = !found;
144
145 if (found)
146 return TRUE;
147 }
148
149 return FALSE;
150 }
151
152 /* Boolean "group-expression" AND matching, returns TRUE if the expression
153 * evaluates to TRUE.
154 */
pr_expr_eval_group_and(char ** expr)155 int pr_expr_eval_group_and(char **expr) {
156 int found;
157 char *grp;
158
159 if (expr == NULL ||
160 *expr == NULL) {
161 errno = EINVAL;
162 return -1;
163 }
164
165 for (; *expr; expr++) {
166 grp = *expr;
167 found = FALSE;
168
169 if (*grp == '!') {
170 found = !found;
171 grp++;
172 }
173
174 if (session.group &&
175 strcmp(session.group, grp) == 0) {
176 found = !found;
177
178 } else if (session.groups) {
179 register unsigned int i = 0;
180 char **elts = session.groups->elts;
181
182 for (i = 0; i < session.groups->nelts; i++) {
183 if (elts[i] != NULL &&
184 strcmp(elts[i], grp) == 0) {
185 found = !found;
186 break;
187 }
188 }
189 }
190
191 if (!found)
192 return FALSE;
193 }
194
195 return TRUE;
196 }
197
198 /* Boolean "group-expression" OR matching, returns TRUE if the expression
199 * evaluates to TRUE.
200 */
pr_expr_eval_group_or(char ** expr)201 int pr_expr_eval_group_or(char **expr) {
202 int found;
203 char *grp;
204
205 if (expr == NULL ||
206 *expr == NULL) {
207 errno = EINVAL;
208 return -1;
209 }
210
211 for (; *expr; expr++) {
212 grp = *expr;
213 found = FALSE;
214
215 if (*grp == '!') {
216 found = !found;
217 grp++;
218 }
219
220 if (session.group &&
221 strcmp(session.group, grp) == 0) {
222 found = !found;
223
224 } else if (session.groups) {
225 register unsigned int i = 0;
226 char **elts = session.groups->elts;
227
228 for (i = 0; i < session.groups->nelts; i++) {
229 if (elts[i] != NULL &&
230 strcmp(elts[i], grp) == 0) {
231 found = !found;
232 break;
233 }
234 }
235 }
236
237 if (found)
238 return TRUE;
239 }
240
241 return FALSE;
242 }
243
244 /* Boolean "user-expression" AND matching, returns TRUE if the expression
245 * evaluates to TRUE.
246 */
pr_expr_eval_user_and(char ** expr)247 int pr_expr_eval_user_and(char **expr) {
248 int found;
249 char *user;
250
251 if (expr == NULL ||
252 *expr == NULL) {
253 errno = EINVAL;
254 return -1;
255 }
256
257 for (; *expr; expr++) {
258 user = *expr;
259 found = FALSE;
260
261 if (*user == '!') {
262 found = !found;
263 user++;
264 }
265
266 if (session.user &&
267 strcmp(session.user, user) == 0)
268 found = !found;
269
270 if (!found)
271 return FALSE;
272 }
273
274 return TRUE;
275 }
276
277 /* Boolean "user-expression" OR matching, returns TRUE if the expression
278 * evaluates to TRUE.
279 */
pr_expr_eval_user_or(char ** expr)280 int pr_expr_eval_user_or(char **expr) {
281 char *user;
282
283 if (expr == NULL ||
284 *expr == NULL) {
285 errno = EINVAL;
286 return -1;
287 }
288
289 for (; *expr; expr++) {
290 int found = FALSE;
291
292 user = *expr;
293 if (*user == '!') {
294 found = !found;
295 user++;
296 }
297
298 if (session.user != NULL &&
299 strcmp(session.user, user) == 0) {
300 found = !found;
301 }
302
303 if (found) {
304 return TRUE;
305 }
306 }
307
308 return FALSE;
309 }
310