/******************************************************************** * 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 #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 .