|
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 |
}
|