/* 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);
}
syntax highlighted by Code2HTML, v. 0.9.1