Blame WWW/Library/Implementation/HTAAProt.c

Packit f574b8
/*
Packit f574b8
 * $LynxId: HTAAProt.c,v 1.34 2016/11/24 15:29:50 tom Exp $
Packit f574b8
 *
Packit f574b8
 * MODULE							HTAAProt.c
Packit f574b8
 *		PROTECTION FILE PARSING MODULE
Packit f574b8
 *
Packit f574b8
 * AUTHORS:
Packit f574b8
 *	AL	Ari Luotonen	luotonen@dxcern.cern.ch
Packit f574b8
 *	MD	Mark Donszelmann    duns@vxdeop.cern.ch
Packit f574b8
 *
Packit f574b8
 * HISTORY:
Packit f574b8
 *	20 Oct 93  AL	Now finds uid/gid for nobody/nogroup by name
Packit f574b8
 *			(doesn't use default 65534 right away).
Packit f574b8
 *			Also understands negative uids/gids.
Packit f574b8
 *	14 Nov 93  MD	Added VMS compatibility
Packit f574b8
 *
Packit f574b8
 * BUGS:
Packit f574b8
 *
Packit f574b8
 *
Packit f574b8
 */
Packit f574b8
Packit f574b8
#include <HTUtils.h>
Packit f574b8
Packit f574b8
#ifndef VMS
Packit f574b8
#ifndef NOUSERS
Packit f574b8
#include <pwd.h>		/* Unix password file routine: getpwnam()       */
Packit f574b8
#include <grp.h>		/* Unix group file routine: getgrnam()          */
Packit f574b8
#endif /* NOUSERS */
Packit f574b8
#endif /* not VMS */
Packit f574b8
Packit f574b8
#include <HTAAUtil.h>
Packit f574b8
#include <HTLex.h>		/* Lexical analysor     */
Packit f574b8
#include <HTAAProt.h>		/* Implemented here     */
Packit f574b8
Packit f574b8
#include <LYUtils.h>
Packit f574b8
#include <LYLeaks.h>
Packit f574b8
Packit f574b8
#define NOBODY    65534		/* -2 in 16-bit environment */
Packit f574b8
#define NONESUCH  65533		/* -3 in 16-bit environment */
Packit f574b8
Packit f574b8
/*
Packit f574b8
 * Protection setup caching
Packit f574b8
 */
Packit f574b8
typedef struct {
Packit f574b8
    char *prot_filename;
Packit f574b8
    HTAAProt *prot;
Packit f574b8
} HTAAProtCache;
Packit f574b8
Packit f574b8
static HTList *prot_cache = NULL;	/* Protection setup cache.      */
Packit f574b8
static HTAAProt *default_prot = NULL;	/* Default protection.          */
Packit f574b8
static HTAAProt *current_prot = NULL;	/* Current protection mode      */
Packit f574b8
Packit f574b8
					/* which is set up by callbacks */
Packit f574b8
					/* from the rule system when    */
Packit f574b8
					/* a "protect" rule is matched. */
Packit f574b8
Packit f574b8
#ifndef NOUSERS
Packit f574b8
/* static							isNumber()
Packit f574b8
 *		DOES A CHARACTER STRING REPRESENT A NUMBER
Packit f574b8
 */
Packit f574b8
static BOOL isNumber(const char *s)
Packit f574b8
{
Packit f574b8
    const char *cur = s;
Packit f574b8
Packit f574b8
    if (isEmpty(s))
Packit f574b8
	return NO;
Packit f574b8
Packit f574b8
    if (*cur == '-')
Packit f574b8
	cur++;			/* Allow initial minus sign in a number */
Packit f574b8
Packit f574b8
    while (*cur) {
Packit f574b8
	if (*cur < '0' || *cur > '9')
Packit f574b8
	    return NO;
Packit f574b8
	cur++;
Packit f574b8
    }
Packit f574b8
    return YES;
Packit f574b8
}
Packit f574b8
Packit f574b8
/* PUBLIC							HTAA_getUid()
Packit f574b8
 *		GET THE USER ID TO CHANGE THE PROCESS UID TO
Packit f574b8
 * ON ENTRY:
Packit f574b8
 *	No arguments.
Packit f574b8
 *
Packit f574b8
 * ON EXIT:
Packit f574b8
 *	returns	the uid number to give to setuid() system call.
Packit f574b8
 *		Default is 65534 (nobody).
Packit f574b8
 */
Packit f574b8
int HTAA_getUid(void)
Packit f574b8
{
Packit f574b8
    int uid;
Packit f574b8
Packit f574b8
    if (current_prot && current_prot->uid_name) {
Packit f574b8
	if (isNumber(current_prot->uid_name)) {
Packit f574b8
	    uid = atoi(current_prot->uid_name);
Packit f574b8
	    if ((*HTAA_UidToName(uid)) != '\0') {
Packit f574b8
		return uid;
Packit f574b8
	    }
Packit f574b8
	} else {		/* User name (not a number) */
Packit f574b8
	    if ((uid = HTAA_NameToUid(current_prot->uid_name)) != NONESUCH) {
Packit f574b8
		return uid;
Packit f574b8
	    }
Packit f574b8
	}
Packit f574b8
    }
Packit f574b8
    /*
Packit f574b8
     * Ok, then let's get uid for nobody.
Packit f574b8
     */
Packit f574b8
    if ((uid = HTAA_NameToUid("nobody")) != NONESUCH) {
Packit f574b8
	return uid;
Packit f574b8
    }
Packit f574b8
    /*
Packit f574b8
     * Ok, then use default.
Packit f574b8
     */
Packit f574b8
    return NOBODY;		/* nobody */
Packit f574b8
}
Packit f574b8
Packit f574b8
/* PUBLIC							HTAA_getGid()
Packit f574b8
 *		GET THE GROUP ID TO CHANGE THE PROCESS GID TO
Packit f574b8
 * ON ENTRY:
Packit f574b8
 *	No arguments.
Packit f574b8
 *
Packit f574b8
 * ON EXIT:
Packit f574b8
 *	returns	the uid number to give to setgid() system call.
Packit f574b8
 *		Default is 65534 (nogroup).
Packit f574b8
 */
Packit f574b8
int HTAA_getGid(void)
Packit f574b8
{
Packit f574b8
    int gid;
Packit f574b8
Packit f574b8
    if (current_prot && current_prot->gid_name) {
Packit f574b8
	if (isNumber(current_prot->gid_name)) {
Packit f574b8
	    gid = atoi(current_prot->gid_name);
Packit f574b8
	    if (*HTAA_GidToName(gid) != '\0') {
Packit f574b8
		return gid;
Packit f574b8
	    }
Packit f574b8
	} else {		/* Group name (not number) */
Packit f574b8
	    if ((gid = HTAA_NameToGid(current_prot->gid_name)) != NONESUCH) {
Packit f574b8
		return gid;
Packit f574b8
	    }
Packit f574b8
	}
Packit f574b8
    }
Packit f574b8
    /*
Packit f574b8
     * Ok, then let's get gid for nogroup.
Packit f574b8
     */
Packit f574b8
    if ((gid = HTAA_NameToGid("nogroup")) != NONESUCH) {
Packit f574b8
	return gid;
Packit f574b8
    }
Packit f574b8
    /*
Packit f574b8
     * Ok, then use default.
Packit f574b8
     */
Packit f574b8
    return NOBODY;		/* nogroup */
Packit f574b8
}
Packit f574b8
#endif /* !NOUSERS */
Packit f574b8
Packit f574b8
/* static							HTAA_setIds()
Packit f574b8
 *		SET UID AND GID (AS NAMES OR NUMBERS)
Packit f574b8
 *		TO HTAAProt STRUCTURE
Packit f574b8
 * ON ENTRY:
Packit f574b8
 *	prot		destination.
Packit f574b8
 *	ids		is a string like "james.www" or "1422.69" etc.
Packit f574b8
 *			giving uid and gid.
Packit f574b8
 *
Packit f574b8
 * ON EXIT:
Packit f574b8
 *	returns		nothing.
Packit f574b8
 */
Packit f574b8
static void HTAA_setIds(HTAAProt *prot, const char *ids)
Packit f574b8
{
Packit f574b8
    if (ids) {
Packit f574b8
	char *local_copy = NULL;
Packit f574b8
	char *point;
Packit f574b8
Packit f574b8
	StrAllocCopy(local_copy, ids);
Packit f574b8
	point = StrChr(local_copy, '.');
Packit f574b8
	if (point) {
Packit f574b8
	    *(point++) = (char) 0;
Packit f574b8
	    StrAllocCopy(prot->gid_name, point);
Packit f574b8
	} else {
Packit f574b8
	    StrAllocCopy(prot->gid_name, "nogroup");
Packit f574b8
	}
Packit f574b8
	StrAllocCopy(prot->uid_name, local_copy);
Packit f574b8
	FREE(local_copy);
Packit f574b8
    } else {
Packit f574b8
	StrAllocCopy(prot->uid_name, "nobody");
Packit f574b8
	StrAllocCopy(prot->gid_name, "nogroup");
Packit f574b8
    }
Packit f574b8
}
Packit f574b8
Packit f574b8
/* static						HTAA_parseProtFile()
Packit f574b8
 *		PARSE A PROTECTION SETUP FILE AND
Packit f574b8
 *		PUT THE RESULT IN A HTAAProt STRUCTURE
Packit f574b8
 * ON ENTRY:
Packit f574b8
 *	prot		destination structure.
Packit f574b8
 *	fp		open protection file.
Packit f574b8
 *
Packit f574b8
 * ON EXIT:
Packit f574b8
 *	returns		nothing.
Packit f574b8
 */
Packit f574b8
static void HTAA_parseProtFile(HTAAProt *prot, FILE *fp)
Packit f574b8
{
Packit f574b8
    if (prot && fp) {
Packit f574b8
	LexItem lex_item;
Packit f574b8
	char *fieldname = NULL;
Packit f574b8
Packit f574b8
	while (LEX_EOF != (lex_item = lex(fp))) {
Packit f574b8
Packit f574b8
	    while (lex_item == LEX_REC_SEP)	/* Ignore empty lines */
Packit f574b8
		lex_item = lex(fp);
Packit f574b8
Packit f574b8
	    if (lex_item == LEX_EOF)	/* End of file */
Packit f574b8
		break;
Packit f574b8
Packit f574b8
	    if (lex_item == LEX_ALPH_STR) {	/* Valid setup record */
Packit f574b8
Packit f574b8
		StrAllocCopy(fieldname, HTlex_buffer);
Packit f574b8
Packit f574b8
		if (LEX_FIELD_SEP != (lex_item = lex(fp)))
Packit f574b8
		    unlex(lex_item);	/* If someone wants to use colon */
Packit f574b8
		/* after field name it's ok, but */
Packit f574b8
		/* not required. Here we read it. */
Packit f574b8
Packit f574b8
		if (0 == strncasecomp(fieldname, "Auth", 4)) {
Packit f574b8
		    lex_item = lex(fp);
Packit f574b8
		    while (lex_item == LEX_ALPH_STR) {
Packit f574b8
			HTAAScheme scheme = HTAAScheme_enum(HTlex_buffer);
Packit f574b8
Packit f574b8
			if (scheme != HTAA_UNKNOWN) {
Packit f574b8
			    if (!prot->valid_schemes)
Packit f574b8
				prot->valid_schemes = HTList_new();
Packit f574b8
			    HTList_addObject(prot->valid_schemes, (void *) scheme);
Packit f574b8
			    CTRACE((tfp, "%s %s `%s'\n",
Packit f574b8
				    "HTAA_parseProtFile: valid",
Packit f574b8
				    "authentication scheme:",
Packit f574b8
				    HTAAScheme_name(scheme)));
Packit f574b8
			} else {
Packit f574b8
			    CTRACE((tfp, "%s %s `%s'\n",
Packit f574b8
				    "HTAA_parseProtFile: unknown",
Packit f574b8
				    "authentication scheme:",
Packit f574b8
				    HTlex_buffer));
Packit f574b8
			}
Packit f574b8
Packit f574b8
			if (LEX_ITEM_SEP != (lex_item = lex(fp)))
Packit f574b8
			    break;
Packit f574b8
			/*
Packit f574b8
			 * Here lex_item == LEX_ITEM_SEP; after item separator
Packit f574b8
			 * it is ok to have one or more newlines (LEX_REC_SEP)
Packit f574b8
			 * and they are ignored (continuation line).
Packit f574b8
			 */
Packit f574b8
			do {
Packit f574b8
			    lex_item = lex(fp);
Packit f574b8
			} while (lex_item == LEX_REC_SEP);
Packit f574b8
		    }		/* while items in list */
Packit f574b8
		}
Packit f574b8
		/* if "Authenticate" */
Packit f574b8
		else if (0 == strncasecomp(fieldname, "mask", 4)) {
Packit f574b8
		    prot->mask_group = HTAA_parseGroupDef(fp);
Packit f574b8
		    lex_item = LEX_REC_SEP;	/*groupdef parser read this already */
Packit f574b8
		    if (TRACE) {
Packit f574b8
			if (prot->mask_group) {
Packit f574b8
			    fprintf(tfp,
Packit f574b8
				    "HTAA_parseProtFile: Mask group:\n");
Packit f574b8
			    HTAA_printGroupDef(prot->mask_group);
Packit f574b8
			} else
Packit f574b8
			    fprintf(tfp,
Packit f574b8
				    "HTAA_parseProtFile: Mask group syntax error\n");
Packit f574b8
		    }
Packit f574b8
		}
Packit f574b8
		/* if "Mask" */
Packit f574b8
		else {		/* Just a name-value pair, put it to assoclist */
Packit f574b8
Packit f574b8
		    if (LEX_ALPH_STR == (lex_item = lex(fp))) {
Packit f574b8
			if (!prot->values)
Packit f574b8
			    prot->values = HTAssocList_new();
Packit f574b8
			HTAssocList_add(prot->values, fieldname, HTlex_buffer);
Packit f574b8
			lex_item = lex(fp);	/* Read record separator */
Packit f574b8
			CTRACE((tfp, "%s `%s' bound to value `%s'\n",
Packit f574b8
				"HTAA_parseProtFile: Name",
Packit f574b8
				fieldname, HTlex_buffer));
Packit f574b8
		    }
Packit f574b8
		}		/* else name-value pair */
Packit f574b8
Packit f574b8
	    }
Packit f574b8
	    /* if valid field */
Packit f574b8
	    if (lex_item != LEX_EOF && lex_item != LEX_REC_SEP) {
Packit f574b8
		CTRACE((tfp, "%s %s %d (that line ignored)\n",
Packit f574b8
			"HTAA_parseProtFile: Syntax error",
Packit f574b8
			"in protection setup file at line",
Packit f574b8
			HTlex_line));
Packit f574b8
		do {
Packit f574b8
		    lex_item = lex(fp);
Packit f574b8
		} while (lex_item != LEX_EOF && lex_item != LEX_REC_SEP);
Packit f574b8
	    }			/* if syntax error */
Packit f574b8
	}			/* while not end-of-file */
Packit f574b8
	FREE(fieldname);
Packit f574b8
    }				/* if valid parameters */
Packit f574b8
}
Packit f574b8
Packit f574b8
/* static						HTAAProt_new()
Packit f574b8
 *		ALLOCATE A NEW HTAAProt STRUCTURE AND
Packit f574b8
 *		INITIALIZE IT FROM PROTECTION SETUP FILE
Packit f574b8
 * ON ENTRY:
Packit f574b8
 *	cur_docname	current filename after rule translations.
Packit f574b8
 *	prot_filename	protection setup file name.
Packit f574b8
 *			If NULL, not an error.
Packit f574b8
 *	ids		Uid and gid names or numbers,
Packit f574b8
 *			examples:
Packit f574b8
 *				james	( <=> james.nogroup)
Packit f574b8
 *				.www	( <=> nobody.www)
Packit f574b8
 *				james.www
Packit f574b8
 *				james.69
Packit f574b8
 *				1422.69
Packit f574b8
 *				1422.www
Packit f574b8
 *
Packit f574b8
 *			May be NULL, defaults to nobody.nogroup.
Packit f574b8
 *			Should be NULL, if prot_file is NULL.
Packit f574b8
 *
Packit f574b8
 * ON EXIT:
Packit f574b8
 *	returns		returns a new and initialized protection
Packit f574b8
 *			setup structure.
Packit f574b8
 *			If setup file is already read in (found
Packit f574b8
 *			in cache), only sets uid_name and gid
Packit f574b8
 *			fields, and returns that.
Packit f574b8
 */
Packit f574b8
static HTAAProt *HTAAProt_new(const char *cur_docname,
Packit f574b8
			      const char *prot_filename,
Packit f574b8
			      const char *ids)
Packit f574b8
{
Packit f574b8
    HTList *cur = prot_cache;
Packit f574b8
    HTAAProtCache *cache_item = NULL;
Packit f574b8
    HTAAProt *prot;
Packit f574b8
    FILE *fp;
Packit f574b8
Packit f574b8
    if (!prot_cache)
Packit f574b8
	prot_cache = HTList_new();
Packit f574b8
Packit f574b8
    while (NULL != (cache_item = (HTAAProtCache *) HTList_nextObject(cur))) {
Packit f574b8
	if (!strcmp(cache_item->prot_filename, prot_filename))
Packit f574b8
	    break;
Packit f574b8
    }
Packit f574b8
    if (cache_item) {
Packit f574b8
	prot = cache_item->prot;
Packit f574b8
	CTRACE((tfp, "%s `%s' already in cache\n",
Packit f574b8
		"HTAAProt_new: Protection file", prot_filename));
Packit f574b8
    } else {
Packit f574b8
	CTRACE((tfp, "HTAAProt_new: Loading protection file `%s'\n",
Packit f574b8
		prot_filename));
Packit f574b8
Packit f574b8
	if ((prot = typecalloc(HTAAProt)) == 0)
Packit f574b8
	      outofmem(__FILE__, "HTAAProt_new");
Packit f574b8
Packit f574b8
	prot->ctemplate = NULL;
Packit f574b8
	prot->filename = NULL;
Packit f574b8
	prot->uid_name = NULL;
Packit f574b8
	prot->gid_name = NULL;
Packit f574b8
	prot->valid_schemes = HTList_new();
Packit f574b8
	prot->mask_group = NULL;	/* Masking disabled by defaults */
Packit f574b8
	prot->values = HTAssocList_new();
Packit f574b8
Packit f574b8
	if (prot_filename && NULL != (fp = fopen(prot_filename, TXT_R))) {
Packit f574b8
	    HTAA_parseProtFile(prot, fp);
Packit f574b8
	    fclose(fp);
Packit f574b8
	    if ((cache_item = typecalloc(HTAAProtCache)) == 0)
Packit f574b8
		outofmem(__FILE__, "HTAAProt_new");
Packit f574b8
Packit f574b8
	    cache_item->prot = prot;
Packit f574b8
	    cache_item->prot_filename = NULL;
Packit f574b8
	    StrAllocCopy(cache_item->prot_filename, prot_filename);
Packit f574b8
	    HTList_addObject(prot_cache, (void *) cache_item);
Packit f574b8
	} else {
Packit f574b8
	    CTRACE((tfp, "HTAAProt_new: %s `%s'\n",
Packit f574b8
		    "Unable to open protection setup file",
Packit f574b8
		    NONNULL(prot_filename)));
Packit f574b8
	}
Packit f574b8
    }
Packit f574b8
Packit f574b8
    if (cur_docname)
Packit f574b8
	StrAllocCopy(prot->filename, cur_docname);
Packit f574b8
    HTAA_setIds(prot, ids);
Packit f574b8
Packit f574b8
    return prot;
Packit f574b8
}
Packit f574b8
Packit f574b8
/* PUBLIC					HTAA_setDefaultProtection()
Packit f574b8
 *		SET THE DEFAULT PROTECTION MODE
Packit f574b8
 *		(called by rule system when a
Packit f574b8
 *		"defprot" rule is matched)
Packit f574b8
 * ON ENTRY:
Packit f574b8
 *	cur_docname	is the current result of rule translations.
Packit f574b8
 *	prot_filename	is the protection setup file (second argument
Packit f574b8
 *			for "defprot" rule, optional)
Packit f574b8
 *	ids		contains user and group names separated by
Packit f574b8
 *			a dot, corresponding to the uid
Packit f574b8
 *			gid under which the server should run,
Packit f574b8
 *			default is "nobody.nogroup" (third argument
Packit f574b8
 *			for "defprot" rule, optional; can be given
Packit f574b8
 *			only if protection setup file is also given).
Packit f574b8
 *
Packit f574b8
 * ON EXIT:
Packit f574b8
 *	returns		nothing.
Packit f574b8
 *			Sets the module-wide variable default_prot.
Packit f574b8
 */
Packit f574b8
void HTAA_setDefaultProtection(const char *cur_docname,
Packit f574b8
			       const char *prot_filename,
Packit f574b8
			       const char *ids)
Packit f574b8
{
Packit f574b8
    default_prot = NULL;	/* Not free()'d because this is in cache */
Packit f574b8
Packit f574b8
    if (prot_filename) {
Packit f574b8
	default_prot = HTAAProt_new(cur_docname, prot_filename, ids);
Packit f574b8
    } else {
Packit f574b8
	CTRACE((tfp, "%s %s\n",
Packit f574b8
		"HTAA_setDefaultProtection: ERROR: Protection file",
Packit f574b8
		"not specified (obligatory for DefProt rule)!!\n"));
Packit f574b8
    }
Packit f574b8
}
Packit f574b8
Packit f574b8
/* PUBLIC					HTAA_setCurrentProtection()
Packit f574b8
 *		SET THE CURRENT PROTECTION MODE
Packit f574b8
 *		(called by rule system when a
Packit f574b8
 *		"protect" rule is matched)
Packit f574b8
 * ON ENTRY:
Packit f574b8
 *	cur_docname	is the current result of rule translations.
Packit f574b8
 *	prot_filename	is the protection setup file (second argument
Packit f574b8
 *			for "protect" rule, optional)
Packit f574b8
 *	ids		contains user and group names separated by
Packit f574b8
 *			a dot, corresponding to the uid
Packit f574b8
 *			gid under which the server should run,
Packit f574b8
 *			default is "nobody.nogroup" (third argument
Packit f574b8
 *			for "protect" rule, optional; can be given
Packit f574b8
 *			only if protection setup file is also given).
Packit f574b8
 *
Packit f574b8
 * ON EXIT:
Packit f574b8
 *	returns		nothing.
Packit f574b8
 *			Sets the module-wide variable current_prot.
Packit f574b8
 */
Packit f574b8
void HTAA_setCurrentProtection(const char *cur_docname,
Packit f574b8
			       const char *prot_filename,
Packit f574b8
			       const char *ids)
Packit f574b8
{
Packit f574b8
    current_prot = NULL;	/* Not free()'d because this is in cache */
Packit f574b8
Packit f574b8
    if (prot_filename) {
Packit f574b8
	current_prot = HTAAProt_new(cur_docname, prot_filename, ids);
Packit f574b8
    } else {
Packit f574b8
	if (default_prot) {
Packit f574b8
	    current_prot = default_prot;
Packit f574b8
	    HTAA_setIds(current_prot, ids);
Packit f574b8
	    CTRACE((tfp, "%s %s %s\n",
Packit f574b8
		    "HTAA_setCurrentProtection: Protection file",
Packit f574b8
		    "not specified for Protect rule",
Packit f574b8
		    "-- using default protection"));
Packit f574b8
	} else {
Packit f574b8
	    CTRACE((tfp, "%s %s %s\n",
Packit f574b8
		    "HTAA_setCurrentProtection: ERROR: Protection",
Packit f574b8
		    "file not specified for Protect rule, and",
Packit f574b8
		    "default protection is not set!!"));
Packit f574b8
	}
Packit f574b8
    }
Packit f574b8
}
Packit f574b8
Packit f574b8
/* PUBLIC					HTAA_getCurrentProtection()
Packit f574b8
 *		GET CURRENT PROTECTION SETUP STRUCTURE
Packit f574b8
 *		(this is set up by callbacks made from
Packit f574b8
 *		 the rule system when matching "protect"
Packit f574b8
 *		 (and "defprot") rules)
Packit f574b8
 * ON ENTRY:
Packit f574b8
 *	HTTranslate() must have been called before calling
Packit f574b8
 *	this function.
Packit f574b8
 *
Packit f574b8
 * ON EXIT:
Packit f574b8
 *	returns	a HTAAProt structure representing the
Packit f574b8
 *		protection setup of the HTTranslate()'d file.
Packit f574b8
 *		This must not be free()'d.
Packit f574b8
 */
Packit f574b8
HTAAProt *HTAA_getCurrentProtection(void)
Packit f574b8
{
Packit f574b8
    return current_prot;
Packit f574b8
}
Packit f574b8
Packit f574b8
/* PUBLIC					HTAA_getDefaultProtection()
Packit f574b8
 *		GET DEFAULT PROTECTION SETUP STRUCTURE
Packit f574b8
 *		AND SET IT TO CURRENT PROTECTION
Packit f574b8
 *		(this is set up by callbacks made from
Packit f574b8
 *		 the rule system when matching "defprot"
Packit f574b8
 *		 rules)
Packit f574b8
 * ON ENTRY:
Packit f574b8
 *	HTTranslate() must have been called before calling
Packit f574b8
 *	this function.
Packit f574b8
 *
Packit f574b8
 * ON EXIT:
Packit f574b8
 *	returns	a HTAAProt structure representing the
Packit f574b8
 *		default protection setup of the HTTranslate()'d
Packit f574b8
 *		file (if HTAA_getCurrentProtection() returned
Packit f574b8
 *		NULL, i.e., if there is no "protect" rule
Packit f574b8
 *		but ACL exists, and we need to know default
Packit f574b8
 *		protection settings).
Packit f574b8
 *		This must not be free()'d.
Packit f574b8
 * IMPORTANT:
Packit f574b8
 *	As a side-effect this tells the protection system that
Packit f574b8
 *	the file is in fact protected and sets the current
Packit f574b8
 *	protection mode to default.
Packit f574b8
 */
Packit f574b8
HTAAProt *HTAA_getDefaultProtection(void)
Packit f574b8
{
Packit f574b8
    if (!current_prot) {
Packit f574b8
	current_prot = default_prot;
Packit f574b8
	default_prot = NULL;
Packit f574b8
    }
Packit f574b8
    return current_prot;
Packit f574b8
}
Packit f574b8
Packit f574b8
/* SERVER INTERNAL					HTAA_clearProtections()
Packit f574b8
 *		CLEAR DOCUMENT PROTECTION MODE
Packit f574b8
 *		(ALSO DEFAULT PROTECTION)
Packit f574b8
 *		(called by the rule system)
Packit f574b8
 * ON ENTRY:
Packit f574b8
 *	No arguments.
Packit f574b8
 *
Packit f574b8
 * ON EXIT:
Packit f574b8
 *	returns	nothing.
Packit f574b8
 *		Frees the memory used by protection information.
Packit f574b8
 */
Packit f574b8
void HTAA_clearProtections(void)
Packit f574b8
{
Packit f574b8
    current_prot = NULL;	/* These are not freed because  */
Packit f574b8
    default_prot = NULL;	/* they are actually in cache.  */
Packit f574b8
}
Packit f574b8
Packit f574b8
typedef struct {
Packit f574b8
    char *name;
Packit f574b8
    int user;
Packit f574b8
} USER_DATA;
Packit f574b8
Packit f574b8
#ifndef NOUSERS
Packit f574b8
static HTList *known_grp = NULL;
Packit f574b8
static HTList *known_pwd = NULL;
Packit f574b8
static BOOL uidgid_cache_inited = NO;
Packit f574b8
#endif
Packit f574b8
Packit f574b8
#ifdef LY_FIND_LEAKS
Packit f574b8
static void clear_uidgid_cache(void)
Packit f574b8
{
Packit f574b8
#ifndef NOUSERS
Packit f574b8
    USER_DATA *data;
Packit f574b8
Packit f574b8
    if (known_grp) {
Packit f574b8
	while ((data = HTList_removeLastObject(known_grp)) != NULL) {
Packit f574b8
	    FREE(data->name);
Packit f574b8
	    FREE(data);
Packit f574b8
	}
Packit f574b8
	FREE(known_grp);
Packit f574b8
    }
Packit f574b8
    if (known_pwd) {
Packit f574b8
	while ((data = HTList_removeLastObject(known_pwd)) != NULL) {
Packit f574b8
	    FREE(data->name);
Packit f574b8
	    FREE(data);
Packit f574b8
	}
Packit f574b8
	FREE(known_pwd);
Packit f574b8
    }
Packit f574b8
#endif
Packit f574b8
}
Packit f574b8
#endif /* LY_FIND_LEAKS */
Packit f574b8
Packit f574b8
#ifndef NOUSERS
Packit f574b8
static void save_gid_info(const char *name, int user)
Packit f574b8
{
Packit f574b8
    USER_DATA *data = typecalloc(USER_DATA);
Packit f574b8
Packit f574b8
    if (!data)
Packit f574b8
	return;
Packit f574b8
    if (!known_grp) {
Packit f574b8
	known_grp = HTList_new();
Packit f574b8
	if (!uidgid_cache_inited) {
Packit f574b8
#ifdef LY_FIND_LEAKS
Packit f574b8
	    atexit(clear_uidgid_cache);
Packit f574b8
#endif
Packit f574b8
	    uidgid_cache_inited = YES;
Packit f574b8
	}
Packit f574b8
    }
Packit f574b8
    StrAllocCopy(data->name, name);
Packit f574b8
    data->user = user;
Packit f574b8
    HTList_addObject(known_grp, data);
Packit f574b8
}
Packit f574b8
#endif /* NOUSERS */
Packit f574b8
Packit f574b8
#ifndef NOUSERS
Packit f574b8
static void save_uid_info(const char *name, int user)
Packit f574b8
{
Packit f574b8
    USER_DATA *data = typecalloc(USER_DATA);
Packit f574b8
Packit f574b8
    if (!data)
Packit f574b8
	return;
Packit f574b8
    if (!known_pwd) {
Packit f574b8
	known_pwd = HTList_new();
Packit f574b8
	if (!uidgid_cache_inited) {
Packit f574b8
#ifdef LY_FIND_LEAKS
Packit f574b8
	    atexit(clear_uidgid_cache);
Packit f574b8
#endif
Packit f574b8
	    uidgid_cache_inited = YES;
Packit f574b8
	}
Packit f574b8
    }
Packit f574b8
    StrAllocCopy(data->name, name);
Packit f574b8
    data->user = user;
Packit f574b8
    HTList_addObject(known_pwd, data);
Packit f574b8
}
Packit f574b8
#endif /* !NOUSERS */
Packit f574b8
Packit f574b8
/* PUBLIC							HTAA_UidToName
Packit f574b8
 *		GET THE USER NAME
Packit f574b8
 * ON ENTRY:
Packit f574b8
 *      The user-id
Packit f574b8
 *
Packit f574b8
 * ON EXIT:
Packit f574b8
 *      returns the user name, or an empty string if not found.
Packit f574b8
 */
Packit f574b8
const char *HTAA_UidToName(int uid GCC_UNUSED)
Packit f574b8
{
Packit f574b8
#ifndef NOUSERS
Packit f574b8
    struct passwd *pw;
Packit f574b8
    HTList *me = known_pwd;
Packit f574b8
Packit f574b8
    while (HTList_nextObject(me)) {
Packit f574b8
	USER_DATA *data = (USER_DATA *) (me->object);
Packit f574b8
Packit f574b8
	if (uid == data->user)
Packit f574b8
	    return data->name;
Packit f574b8
    }
Packit f574b8
Packit f574b8
    if ((pw = getpwuid((uid_t) uid)) != 0
Packit f574b8
	&& pw->pw_name != 0) {
Packit f574b8
	CTRACE((tfp, "%s(%d) returned (%s:%d:...)\n",
Packit f574b8
		"HTAA_UidToName: getpwuid",
Packit f574b8
		uid,
Packit f574b8
		pw->pw_name, (int) pw->pw_uid));
Packit f574b8
	save_uid_info(pw->pw_name, (int) pw->pw_uid);
Packit f574b8
	return pw->pw_name;
Packit f574b8
    }
Packit f574b8
#endif
Packit f574b8
    return "";
Packit f574b8
}
Packit f574b8
Packit f574b8
/* PUBLIC							HTAA_NameToUid
Packit f574b8
 *		GET THE USER ID
Packit f574b8
 * ON ENTRY:
Packit f574b8
 *      The user-name
Packit f574b8
 *
Packit f574b8
 * ON EXIT:
Packit f574b8
 *      returns the user id, or NONESUCH if not found.
Packit f574b8
 */
Packit f574b8
int HTAA_NameToUid(const char *name GCC_UNUSED)
Packit f574b8
{
Packit f574b8
#ifndef NOUSERS
Packit f574b8
    struct passwd *pw;
Packit f574b8
    HTList *me = known_pwd;
Packit f574b8
Packit f574b8
    while (HTList_nextObject(me)) {
Packit f574b8
	USER_DATA *data = (USER_DATA *) (me->object);
Packit f574b8
Packit f574b8
	if (!strcmp(name, data->name))
Packit f574b8
	    return data->user;
Packit f574b8
    }
Packit f574b8
Packit f574b8
    if ((pw = getpwnam(name)) != 0) {
Packit f574b8
	CTRACE((tfp, "%s(%s) returned (%s:%d:...)\n",
Packit f574b8
		"HTAA_NameToUid: getpwnam",
Packit f574b8
		name,
Packit f574b8
		pw->pw_name, (int) pw->pw_uid));
Packit f574b8
	save_uid_info(pw->pw_name, (int) pw->pw_uid);
Packit f574b8
	return (int) pw->pw_uid;
Packit f574b8
    }
Packit f574b8
#endif
Packit f574b8
    return NONESUCH;
Packit f574b8
}
Packit f574b8
Packit f574b8
/* PUBLIC							HTAA_GidToName
Packit f574b8
 *		GET THE GROUP NAME
Packit f574b8
 * ON ENTRY:
Packit f574b8
 *      The group-id
Packit f574b8
 *
Packit f574b8
 * ON EXIT:
Packit f574b8
 *      returns the group name, or an empty string if not found.
Packit f574b8
 */
Packit f574b8
const char *HTAA_GidToName(int gid GCC_UNUSED)
Packit f574b8
{
Packit f574b8
#ifndef NOUSERS
Packit f574b8
    struct group *gr;
Packit f574b8
    HTList *me = known_grp;
Packit f574b8
Packit f574b8
    while (HTList_nextObject(me)) {
Packit f574b8
	USER_DATA *data = (USER_DATA *) (me->object);
Packit f574b8
Packit f574b8
	if (gid == data->user)
Packit f574b8
	    return data->name;
Packit f574b8
    }
Packit f574b8
Packit f574b8
    if ((gr = getgrgid((gid_t) gid)) != 0
Packit f574b8
	&& gr->gr_name != 0) {
Packit f574b8
	CTRACE((tfp, "%s(%d) returned (%s:%d:...)\n",
Packit f574b8
		"HTAA_GidToName: getgrgid",
Packit f574b8
		gid,
Packit f574b8
		gr->gr_name, (int) gr->gr_gid));
Packit f574b8
	save_gid_info(gr->gr_name, (int) gr->gr_gid);
Packit f574b8
	return gr->gr_name;
Packit f574b8
    }
Packit f574b8
#endif
Packit f574b8
    return "";
Packit f574b8
}
Packit f574b8
Packit f574b8
/* PUBLIC							HTAA_NameToGid
Packit f574b8
 *		GET THE GROUP ID
Packit f574b8
 * ON ENTRY:
Packit f574b8
 *      The group-name
Packit f574b8
 *
Packit f574b8
 * ON EXIT:
Packit f574b8
 *      returns the group id, or NONESUCH if not found.
Packit f574b8
 */
Packit f574b8
int HTAA_NameToGid(const char *name GCC_UNUSED)
Packit f574b8
{
Packit f574b8
#ifndef NOUSERS
Packit f574b8
    struct group *gr;
Packit f574b8
    HTList *me = known_grp;
Packit f574b8
Packit f574b8
    while (HTList_nextObject(me)) {
Packit f574b8
	USER_DATA *data = (USER_DATA *) (me->object);
Packit f574b8
Packit f574b8
	if (!strcmp(name, data->name))
Packit f574b8
	    return data->user;
Packit f574b8
    }
Packit f574b8
Packit f574b8
    if ((gr = getgrnam(name)) != 0) {
Packit f574b8
	CTRACE((tfp, "%s(%s) returned (%s:%d:...)\n",
Packit f574b8
		"HTAA_NameToGid: getgrnam",
Packit f574b8
		name,
Packit f574b8
		gr->gr_name, (int) gr->gr_gid));
Packit f574b8
	save_gid_info(gr->gr_name, (int) gr->gr_gid);
Packit f574b8
	return (int) gr->gr_gid;
Packit f574b8
    }
Packit f574b8
#endif
Packit f574b8
    return NONESUCH;
Packit f574b8
}