/* Copyright (C) 1999 Beau Kuiper 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "ftpd.h" int checknamelist(CONFIGFILECACHE *cf, int section, char *username) { int occur; char *setting; occur = 1; while ((setting = getconfigdata(cf, section, "nameacl", occur))) { char *name = strchr(setting, ':'); if (name) { name++; if (my_fnmatch(name, username, 0) == 0) return((*setting == 'A') || (*setting == 'a')); } occur++; } return(FALSE); } IPACLLIST *ipacllist_new(CONFIGFILECACHE *cf, int section, char *name) { int occur; char *setting; IPACLLIST *new = mallocwrapper(sizeof(IPACLLIST)); occur = 1; new->count = 0; new->list = NULL; while ((setting = getconfigdata(cf, section, name, occur))) { char *settingt = strdupwrapper(setting); char *netmask, *ipaddr; strtrimspace(settingt); ipaddr = strchr(settingt, ':'); if (ipaddr) { ipaddr++; netmask = strchr(ipaddr, '/'); reallocwrapper(sizeof(IPACL) * (new->count + 1), (void *)&(new->list)); new->list[new->count].accept = (*settingt == 'A') || (*settingt == 'a'); if ((*ipaddr == '(') && (ipaddr[strlen(ipaddr)-1] == ')')) { /* hostname-pattern type IPACL */ memmove(settingt, ipaddr + 1, strlen(ipaddr)); settingt[strlen(settingt)-1] = 0; new->list[new->count].fnstr = settingt; new->list[new->count].type = 0; } else if (!netmask) { /* IP-pattern type IPACL */ memmove(settingt, ipaddr, strlen(ipaddr)+1); new->list[new->count].fnstr = settingt; new->list[new->count].type = 1; } else { *netmask = 0; netmask++; getnetworkint(ipaddr, &(new->list[new->count].ipaddr)); getnetworkint(netmask, &(new->list[new->count].netmask)); new->list[new->count].fnstr = NULL; freewrapper(settingt); new->list[new->count].type = 2; } new->count++; } else { log_addentry(MYLOG_INFO, NULL, "Error decoding ipacl directive, data missing ':'. Skipping entry."); freewrapper(settingt); } occur++; } return(new); } void ipacllist_destroy(IPACLLIST *list) { int count; if (list->count > 0) { for (count = 0; count < list->count; count++) freeifnotnull(list->list[count].fnstr); freewrapper(list->list); } freewrapper(list); } int user_allowed(IPACLLIST *list, int ip, char *hostname) { int pos = 0; int mip, mip2; char *ipstr = (char *)getipstr(ip); for (pos = 0; pos < list->count; pos++) { switch(list->list[pos].type) { case 0: if (my_fnmatch(list->list[pos].fnstr, hostname, 0) == 0) return(list->list[pos].accept); break; case 1: if (my_fnmatch(list->list[pos].fnstr, ipstr, 0) == 0) return(list->list[pos].accept); break; case 2: mip = ip & list->list[pos].netmask; mip2 = list->list[pos].ipaddr & list->list[pos].netmask; if (mip == mip2) return(list->list[pos].accept); break; } } return(FALSE); }