/* * ProFTPD - FTP server daemon * Copyright (c) 2008-2020 The ProFTPD Project team * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * * As a special exemption, The ProFTPD Project team and other respective * copyright holders give permission to link this program with OpenSSL, and * distribute the resulting executable, without including the source code for * OpenSSL in the source distribution. */ /* Expression API implementation */ #include "conf.h" array_header *pr_expr_create(pool *p, unsigned int *argc, char **argv) { array_header *acl = NULL; unsigned int cnt; char *s, *ent; if (p == NULL || argc == NULL || argv == NULL || *argv == NULL) { errno = EINVAL; return NULL; } cnt = *argc; if (cnt > 0) { acl = make_array(p, cnt, sizeof(char *)); /* Skip past the first string in argv, as this is usually the directive. */ while (cnt-- && *(++argv)) { char *sep = ","; s = pstrdup(p, *argv); if (strstr(s, sep) != NULL) { while ((ent = pr_str_get_token(&s, sep)) != NULL) { pr_signals_handle(); if (*ent) { *((char **) push_array(acl)) = ent; } } } else { *((char **) push_array(acl)) = s; } } *argc = acl->nelts; } else { acl = make_array(p, 0, sizeof(char *)); *argc = 0; } return acl; } /* Boolean "class-expression" AND matching, returns TRUE if the expression * evaluates to TRUE. */ int pr_expr_eval_class_and(char **expr) { int found; char *class; if (expr == NULL || *expr == NULL) { errno = EINVAL; return -1; } for (; *expr; expr++) { class = *expr; found = FALSE; if (*class == '!') { found = !found; class++; } if (session.conn_class == NULL && !found) { return FALSE; } if (session.conn_class != NULL && strcmp(session.conn_class->cls_name, class) == 0) { found = !found; } if (!found) { return FALSE; } } return TRUE; } /* Boolean "class-expression" OR matching, returns TRUE if the expression * evaluates to TRUE. */ int pr_expr_eval_class_or(char **expr) { int found; char *class; if (expr == NULL || *expr == NULL) { errno = EINVAL; return -1; } for (; *expr; expr++) { class = *expr; found = FALSE; if (*class == '!') { found = !found; class++; } if (session.conn_class == NULL) return found; if (strcmp(session.conn_class->cls_name, class) == 0) found = !found; if (found) return TRUE; } return FALSE; } /* Boolean "group-expression" AND matching, returns TRUE if the expression * evaluates to TRUE. */ int pr_expr_eval_group_and(char **expr) { int found; char *grp; if (expr == NULL || *expr == NULL) { errno = EINVAL; return -1; } for (; *expr; expr++) { grp = *expr; found = FALSE; if (*grp == '!') { found = !found; grp++; } if (session.group && strcmp(session.group, grp) == 0) { found = !found; } else if (session.groups) { register unsigned int i = 0; char **elts = session.groups->elts; for (i = 0; i < session.groups->nelts; i++) { if (elts[i] != NULL && strcmp(elts[i], grp) == 0) { found = !found; break; } } } if (!found) return FALSE; } return TRUE; } /* Boolean "group-expression" OR matching, returns TRUE if the expression * evaluates to TRUE. */ int pr_expr_eval_group_or(char **expr) { int found; char *grp; if (expr == NULL || *expr == NULL) { errno = EINVAL; return -1; } for (; *expr; expr++) { grp = *expr; found = FALSE; if (*grp == '!') { found = !found; grp++; } if (session.group && strcmp(session.group, grp) == 0) { found = !found; } else if (session.groups) { register unsigned int i = 0; char **elts = session.groups->elts; for (i = 0; i < session.groups->nelts; i++) { if (elts[i] != NULL && strcmp(elts[i], grp) == 0) { found = !found; break; } } } if (found) return TRUE; } return FALSE; } /* Boolean "user-expression" AND matching, returns TRUE if the expression * evaluates to TRUE. */ int pr_expr_eval_user_and(char **expr) { int found; char *user; if (expr == NULL || *expr == NULL) { errno = EINVAL; return -1; } for (; *expr; expr++) { user = *expr; found = FALSE; if (*user == '!') { found = !found; user++; } if (session.user && strcmp(session.user, user) == 0) found = !found; if (!found) return FALSE; } return TRUE; } /* Boolean "user-expression" OR matching, returns TRUE if the expression * evaluates to TRUE. */ int pr_expr_eval_user_or(char **expr) { char *user; if (expr == NULL || *expr == NULL) { errno = EINVAL; return -1; } for (; *expr; expr++) { int found = FALSE; user = *expr; if (*user == '!') { found = !found; user++; } if (session.user != NULL && strcmp(session.user, user) == 0) { found = !found; } if (found) { return TRUE; } } return FALSE; }