Coverage Report

Created: 2026-02-26 07:11

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/proftpd/src/expr.c
Line
Count
Source
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
29
0
array_header *pr_expr_create(pool *p, unsigned int *argc, char **argv) {
30
0
  array_header *acl = NULL;
31
0
  unsigned int cnt;
32
0
  char *s, *ent;
33
34
0
  if (p == NULL ||
35
0
      argc == NULL ||
36
0
      argv == NULL ||
37
0
      *argv == NULL) {
38
0
    errno = EINVAL;
39
0
    return NULL;
40
0
  }
41
42
0
  cnt = *argc;
43
44
0
  if (cnt > 0) {
45
0
    acl = make_array(p, cnt, sizeof(char *));
46
47
    /* Skip past the first string in argv, as this is usually the directive. */
48
0
    while (cnt-- && *(++argv)) {
49
0
      char *sep = ",";
50
51
0
      s = pstrdup(p, *argv);
52
53
0
      if (strstr(s, sep) != NULL) {
54
0
        while ((ent = pr_str_get_token(&s, sep)) != NULL) {
55
0
          pr_signals_handle();
56
57
0
          if (*ent) {
58
0
            *((char **) push_array(acl)) = ent;
59
0
          }
60
0
        }
61
62
0
      } else {
63
0
        *((char **) push_array(acl)) = s;
64
0
      }
65
0
    }
66
67
0
    *argc = acl->nelts;
68
69
0
  } else {
70
0
    acl = make_array(p, 0, sizeof(char *));
71
0
    *argc = 0;
72
0
  }
73
74
0
  return acl;
75
0
}
76
77
/* Boolean "class-expression" AND matching, returns TRUE if the expression
78
 * evaluates to TRUE.
79
 */
80
0
int pr_expr_eval_class_and(char **expr) {
81
0
  if (expr == NULL ||
82
0
      *expr == NULL) {
83
0
    errno = EINVAL;
84
0
    return -1;
85
0
  }
86
87
0
  for (; *expr; expr++) {
88
0
    char *class;
89
0
    int found;
90
91
0
    class = *expr;
92
0
    found = FALSE;
93
94
0
    if (*class == '!') {
95
0
      found = !found;
96
0
      class++;
97
0
    }
98
99
0
    if (session.conn_class == NULL &&
100
0
        !found) {
101
0
      return FALSE;
102
0
    }
103
104
0
    if (session.conn_class != NULL &&
105
0
        strcmp(session.conn_class->cls_name, class) == 0) {
106
0
      found = !found;
107
0
    }
108
109
0
    if (!found) {
110
0
      return FALSE;
111
0
    }
112
0
  }
113
114
0
  return TRUE;
115
0
}
116
117
/* Boolean "class-expression" OR matching, returns TRUE if the expression
118
 * evaluates to TRUE.
119
 */
120
0
int pr_expr_eval_class_or(char **expr) {
121
0
  if (expr == NULL ||
122
0
      *expr == NULL) {
123
0
    errno = EINVAL;
124
0
    return -1;
125
0
  }
126
127
0
  for (; *expr; expr++) {
128
0
    char *class;
129
0
    int found;
130
131
0
    class = *expr;
132
0
    found = FALSE;
133
134
0
    if (*class == '!') {
135
0
      found = !found;
136
0
      class++;
137
0
    }
138
139
0
    if (session.conn_class == NULL) {
140
0
      return found;
141
0
    }
142
143
0
    if (strcmp(session.conn_class->cls_name, class) == 0) {
144
0
      found = !found;
145
0
    }
146
147
0
    if (found) {
148
0
      return TRUE;
149
0
    }
150
0
  }
151
152
0
  return FALSE;
153
0
}
154
155
/* Boolean "group-expression" AND matching, returns TRUE if the expression
156
 * evaluates to TRUE.
157
 */
158
0
int pr_expr_eval_group_and(char **expr) {
159
0
  if (expr == NULL ||
160
0
      *expr == NULL) {
161
0
    errno = EINVAL;
162
0
    return -1;
163
0
  }
164
165
0
  for (; *expr; expr++) {
166
0
    char *grp;
167
0
    int found;
168
169
0
    grp = *expr;
170
0
    found = FALSE;
171
172
0
    if (*grp == '!') {
173
0
      found = !found;
174
0
      grp++;
175
0
    }
176
177
0
    if (session.group &&
178
0
        strcmp(session.group, grp) == 0) {
179
0
      found = !found;
180
181
0
    } else if (session.groups) {
182
0
      register unsigned int i = 0;
183
0
      char **elts = session.groups->elts;
184
185
0
      for (i = 0; i < session.groups->nelts; i++) {
186
0
        if (elts[i] != NULL &&
187
0
            strcmp(elts[i], grp) == 0) {
188
0
          found = !found;
189
0
          break;
190
0
        }
191
0
      }
192
0
    }
193
194
0
    if (!found) {
195
0
      return FALSE;
196
0
    }
197
0
  }
198
199
0
  return TRUE;
200
0
}
201
202
/* Boolean "group-expression" OR matching, returns TRUE if the expression
203
 * evaluates to TRUE.
204
 */
205
0
int pr_expr_eval_group_or(char **expr) {
206
0
  if (expr == NULL ||
207
0
      *expr == NULL) {
208
0
    errno = EINVAL;
209
0
    return -1;
210
0
  }
211
212
0
  for (; *expr; expr++) {
213
0
    char *grp;
214
0
    int found;
215
216
0
    grp = *expr;
217
0
    found = FALSE;
218
219
0
    if (*grp == '!') {
220
0
      found = !found;
221
0
      grp++;
222
0
    }
223
224
0
    if (session.group &&
225
0
        strcmp(session.group, grp) == 0) {
226
0
      found = !found;
227
228
0
    } else if (session.groups) {
229
0
      register unsigned int i = 0;
230
0
      char **elts = session.groups->elts;
231
232
0
      for (i = 0; i < session.groups->nelts; i++) {
233
0
        if (elts[i] != NULL &&
234
0
            strcmp(elts[i], grp) == 0) {
235
0
          found = !found;
236
0
          break;
237
0
        }
238
0
      }
239
0
    }
240
241
0
    if (found) {
242
0
      return TRUE;
243
0
    }
244
0
  }
245
246
0
  return FALSE;
247
0
}
248
249
/* Boolean "user-expression" AND matching, returns TRUE if the expression
250
 * evaluates to TRUE.
251
 */
252
0
int pr_expr_eval_user_and(char **expr) {
253
0
  if (expr == NULL ||
254
0
      *expr == NULL) {
255
0
    errno = EINVAL;
256
0
    return -1;
257
0
  }
258
259
0
  for (; *expr; expr++) {
260
0
    char *user;
261
0
    int found;
262
263
0
    user = *expr;
264
0
    found = FALSE;
265
266
0
    if (*user == '!') {
267
0
      found = !found;
268
0
      user++;
269
0
    }
270
271
0
    if (session.user != NULL &&
272
0
        strcmp(session.user, user) == 0) {
273
0
      found = !found;
274
0
    }
275
276
0
    if (!found) {
277
0
      return FALSE;
278
0
    }
279
0
  }
280
281
0
  return TRUE;
282
0
}
283
284
/* Boolean "user-expression" OR matching, returns TRUE if the expression
285
 * evaluates to TRUE.
286
 */
287
0
int pr_expr_eval_user_or(char **expr) {
288
0
  if (expr == NULL ||
289
0
      *expr == NULL) {
290
0
    errno = EINVAL;
291
0
    return -1;
292
0
  }
293
294
0
  for (; *expr; expr++) {
295
0
    char *user;
296
0
    int found = FALSE;
297
298
0
    user = *expr;
299
0
    if (*user == '!') {
300
0
      found = !found;
301
0
      user++;
302
0
    }
303
304
0
    if (session.user != NULL &&
305
0
        strcmp(session.user, user) == 0) {
306
0
      found = !found;
307
0
    }
308
309
0
    if (found) {
310
0
      return TRUE;
311
0
    }
312
0
  }
313
314
0
  return FALSE;
315
0
}