/********************************************************************
* wilkinson
* 3.11VMS
* 1995/09/25 14:40
* gopher_root1:[gopher.g2.vms2_13.gopherd]site.c,v
* Exp
*
* Paul Lindner, University of Minnesota CIS.
*
* Copyright 1991, 1992 by the Regents of the University of Minnesota
* see the file "Copyright" in the distribution for conditions of use.
*********************************************************************
* MODULE: site.c
* Routines to build up a table of hostnames and access levels
*********************************************************************
* Revision History:
* site.c,v
* Revision 3.11VMS 1995/09/25 14:40 wilkinson
* Consolodate VMS/Unix source code for server as well as client
*
* Revision 3.11 1995/02/17 23:15:30 lindner
* Fix for access: lines
*
* Revision 3.10 1995/02/02 17:13:55 lindner
* Fix memory leaks
*
* Revision 3.9 1994/07/22 22:56:20 lindner
* More NO_AUTH stuff..
*
* Revision 3.8 1994/07/22 22:25:51 lindner
* NO_AUTHENTICATION mods
*
* Revision 3.7 1994/07/19 20:24:12 lindner
* Use local Locale.h
*
* Revision 3.6 1994/05/02 07:41:15 lindner
* Mods to use setlocale()
*
* Revision 3.5 1994/03/17 21:18:24 lindner
* Massive reworking of access limits
*
* Revision 3.4 1994/03/17 04:27:49 lindner
* Additions for maxsessions
*
* Revision 3.3 1993/08/20 18:03:14 lindner
* Mods to allow gopherd.conf files control ftp gateway access
*
* Revision 3.2 1993/07/27 05:27:57 lindner
* Mondo Debug overhaul from Mitra
*
* Revision 3.1.1.1 1993/02/11 18:02:53 lindner
* Gopher+1.2beta release
*
* Revision 1.2 1993/02/09 22:29:23 lindner
* added util.h to includes
*
* Revision 1.1 1992/12/10 23:13:27 lindner
* gopher 1.1 release
*
*
*********************************************************************/
#ifndef NO_AUTHENTICATION
#include "site.h"
#include "Malloc.h"
#include "Locale.h"
#include <ctype.h>
#include "util.h"
#include "Debug.h"
static Site *
SiteNew()
{
Site *temp;
temp = (Site *) malloc(sizeof(Site));
if (temp == NULL)
return(NULL);
temp->domain = STRnew();
STRinit(temp->domain);
SITEsetLevel(temp, ACC_FULL);
SITEsetisnum(temp, FALSE);
SITEsetmaxsessions(temp, -1);
return(temp);
}
static void
SiteDestroy(site)
Site *site;
{
STRdestroy(site->domain);
free(site);
}
static void
Sitecpy(site1, site2)
Site *site1, *site2;
{
STRcpy(site1->domain, site2->domain);
site1->Level = site2->Level;
site1->isnum = site2->isnum;
site1->maxsessions = site2->maxsessions;
}
static void
SiteSet(site, dom, access, maxsess)
Site *site;
char *dom;
Accesslevel access;
int maxsess;
{
STRset(site->domain, dom);
site->Level = access;
if (isdigit(*dom))
site->isnum = TRUE;
else
site->isnum = FALSE;
site->maxsessions = maxsess;
}
/******************************************************/
SiteArray *
SiteArrayNew()
{
SiteArray *temp;
temp = DAnew(20, SiteNew, NULL, SiteDestroy, Sitecpy);
return(temp);
}
void
SiteArrayAdd(sitearr, name, Level, sessions)
SiteArray *sitearr;
char *name;
Accesslevel Level;
int sessions;
{
Site *temp;
temp = SiteNew();
SiteSet(temp, name, Level, sessions);
SiteArrPush(sitearr, temp);
SiteDestroy(temp);
return;
}
/*
* Find the default access level
*/
Accesslevel
SiteDefAccess(sitearr)
SiteArray *sitearr;
{
int i;
Site *temp;
for (i=0; i< DAgetTop(sitearr); i++) {
temp = SiteArrgetEntry(sitearr, i);
if (strcmp(SITEgetDomain(temp), "default") == 0)
return(SITEgetLevel(temp));
}
return(ACC_UNKNOWN);
}
/*
* Tries to find a match in sitearr for "hostname" or ipnum, then tests the
* accesslevel against "mask".
*
* If it finds it, it returns the result of the search
*
* If it doesn't it tests agains the "default" item
*
*/
AccessResult
SiteAccess(sitearr, hostname, ipnum, mask, sessions)
SiteArray *sitearr;
char *hostname;
char *ipnum;
Accesslevel mask;
int sessions;
{
int i;
Site *temp;
Accesslevel defaccess = ACC_FULL, level;
int defmaxsess = -1;
int maxsess;
if (hostname == NULL && ipnum == NULL)
/*** ??? We need to compare *something* ***/
return(SITE_UNDEF);
for (i=0; i< DAgetTop(sitearr); i++) {
temp = SiteArrgetEntry(sitearr, i);
Debug("Testing for %s\n", STRget(temp->domain));
if (strcmp(SITEgetDomain(temp), "default") == 0) {
defaccess = SITEgetLevel(temp);
defmaxsess = SITEmaxsessions(temp);
} else if (SITEisnum(temp) == TRUE) {
/*** Check for a match with the domain name
from the beginning ***/
int iplen, domainlen;
iplen = strlen(ipnum);
domainlen = strlen(STRget(temp->domain));
if (iplen >domainlen)
iplen = domainlen;
if (strncmp(ipnum, SITEgetDomain(temp), iplen) == 0) {
break;
}
} else {
/*** Check for a match from the end ***/
/*** It's a domain name, not an ip number ***/
int namelen, domainlen;
namelen = strlen(hostname);
domainlen = strlen(SITEgetDomain(temp));
/*** don't compare if incoming name is shorter than domain ***/
if (domainlen <= namelen)
if (strcasecmp((hostname+namelen-domainlen),
SITEgetDomain(temp))==0)
break;
}
}
if (i == DAgetTop(sitearr)) {
/*** Hmmm, didn't find a match, return "default" val ***/
level = defaccess;
maxsess = defmaxsess;
} else {
/** Otherwise we found a match.. **/
level = SITEgetLevel(temp);
maxsess = SITEmaxsessions(temp);
}
if (sessions > 0) {
if (maxsess < sessions && maxsess > 0)
return(SITE_TOOBUSY);
}
if ((level & mask) == mask)
return(SITE_OK);
else
return(SITE_NOACCESS);
}
/*
* process a site description line.
*/
boolean
SiteProcessLine(sitearr, inputline, defaccess)
SiteArray *sitearr;
char *inputline;
Accesslevel defaccess;
{
char name[256];
char *namep = name;
Accesslevel level = defaccess;
int maxsess = 0;
/*** the first word is the domain/ip# ***/
while (*inputline == ' ' || *inputline == '\t')
inputline++;
while (*inputline != ' ' && *inputline != '\t') {
*namep = *inputline;
namep++;
inputline++;
}
*namep = '\0'; /*** Terminate it ***/
if (namep == name)
return(FALSE); /*** bad line ***/
while (*inputline != '\0') {
if (*inputline == ' ' || *inputline == '\t' || *inputline == ',') {
inputline++;
if (*inputline == '!')
inputline++;
switch (*inputline) {
case '0': case '1': case '2': case '3': case '4': case '5':
case '6': case '7': case '8': case '9':
/** Maxsessions **/
while (*inputline <= '9' && '0' <= *inputline) {
maxsess = maxsess * 10 + (*inputline - '0');
inputline++;
}
break;
case 'b':
/** Browse **/
if (*(inputline -1) == '!')
#ifndef VMS_SERVER
level &= (ACC_SEARCH | ACC_READ | ACC_FTP);
#else
level &= (ACC_SEARCH | ACC_READ | ACC_FTP | ACC_EXEC );
#endif
else
level |= ACC_BROWSE;
break;
case 'r':
/*** Read ***/
if (*(inputline -1) == '!')
#ifndef VMS_SERVER
level &= (ACC_BROWSE | ACC_SEARCH | ACC_FTP);
#else
level &= (ACC_BROWSE | ACC_SEARCH | ACC_FTP |
ACC_EXEC);
#endif
else
level |= ACC_READ;
break;
case 's':
/*** Search ***/
if (*(inputline -1) == '!')
#ifndef VMS_SERVER
level &= (ACC_BROWSE | ACC_READ | ACC_FTP);
#else
level &= (ACC_BROWSE | ACC_READ | ACC_FTP | ACC_EXEC);
#endif
else
level |= ACC_SEARCH;
break;
case 'f':
/*** FTP ***/
if (*(inputline -1) == '!')
#ifndef VMS_SERVER
level &= (ACC_BROWSE | ACC_READ | ACC_SEARCH);
#else
level &= (ACC_BROWSE | ACC_READ | ACC_SEARCH |
ACC_EXEC);
#endif
else
level |= ACC_FTP;
break;
#ifdef VMS_SERVER
case 'e':
/*** EXEC ***/
if (*(inputline -1) == '!')
level &= (ACC_BROWSE | ACC_READ | ACC_SEARCH |
ACC_FTP);
else
level |= ACC_EXEC;
break;
#endif
}
} else
inputline++;
}
SiteArrayAdd(sitearr, name, level, maxsess);
return(TRUE);
}
#ifdef VMS_SERVER
/*
* Translate the supplied AccessLevel into a text string
*/
char *
AccessLevelText(level, maxsess)
Accesslevel level;
int maxsess;
{
static
char text[12];
char *format;
if (maxsess)
format = "%s%s%s%s%s%d";
else
format = "%s%s%s%s%s";
sprintf(text,format, ((level && ACC_READ) == ACC_READ)?"r ":"",
((level && ACC_BROWSE) == ACC_BROWSE)?"b ":"",
((level && ACC_SEARCH) == ACC_SEARCH)?"s ":"",
((level && ACC_FTP) == ACC_FTP)?"f ":"",
((level && ACC_EXEC) == ACC_EXEC)?"e ":"",
maxsess);
return(text);
}
#endif
#else
#endif
.
Response:
text/plain