archie/prospero/lib/pfs/in_acl.c
2024-05-27 16:13:40 +02:00

130 lines
4.0 KiB
C

/*
* Copyright (c) 1992 by the University of Southern California
*
* For copying and distribution information, please see the file <usc-copyr.h>
*/
#include <usc-copyr.h>
#include <pfs.h>
#include <pparse.h>
#include <pprot.h>
#include <perrno.h>
static int
in_acl_data(INPUT in, char *command, char *next_word, ACL value);
int in_ge1_acl(INPUT in, char *command, char *next_word, ACL *aclp)
{
ACL nacl = acalloc();
int retval;
if (!nacl) out_of_memory();
if(retval = in_acl_data(in, command, next_word, nacl)) {
acfree(nacl);
return perrno = retval;
}
if(retval = in_acl(in, &nacl->next)) {
acfree(nacl);
return perrno = retval;
}
/* now need to correct the doubly-linked list. */
if (nacl->next) {
nacl->previous = nacl->next->previous;
nacl->next->previous = nacl;
}
*aclp = nacl;
return PSUCCESS;
}
/* This function is called with in_nextline() referring to the first line that
might contain ACL data. It sets perrno and p_err_string if bad data is
found, and ALSO returns an error code. */
/* Reads in a string of ACL lines. */
int
in_acl(INPUT in, ACL *aclp)
{
ACL list = NULL; /* head of a linked list of new acls. */
char *command, *next_word;
while(in_nextline(in) && strnequal(in_nextline(in), "ACL", 3)) {
ACL nacl = acalloc();
int retval; /* return code from function calls. */
if (!nacl) {
aclfree(list);
out_of_memory();
}
APPEND_ITEM(nacl, list);
if(retval = in_line(in, &command, &next_word)) {
aclfree(list);
return perrno = retval;
}
if(retval = in_acl_data(in, command, next_word, nacl)) {
aclfree(list);
return perrno = retval;
}
/* We just safely read in the rest of the line. */
/* Read in additional lines to skip over any RESTRICTION lines. */
while (in_nextline(in)
&& strnequal(in_nextline(in), "RESTRICTION ", 12)) {
extern int p__server;
if(retval = in_line(in, &command, &next_word)) {
aclfree(list);
return perrno = retval;
}
if (p__server) {
aclfree(list);
p_err_string = qsprintf_stcopyr(p_err_string,
"UNIMPLEMENTED This server cannot handle RESTRICTIONS \
yet: %s", command);
return perrno = retval;
} else {
pwarn = PWARNING;
p_warn_string = qsprintf_stcopyr(p_warn_string,
"The server sent an ACL with a RESTRICTION, but we \
don't know what it means: %s", command);
/* just go on; it's only a warning. */
}
}
}
*aclp = list; /* safe & done. */
return PSUCCESS;
}
static int
in_acl_data(INPUT in, char *command, char *next_word, ACL value)
{
AUTOSTAT_CHARPP(t_acetypep);
AUTOSTAT_CHARPP(t_atypep);
AUTOSTAT_CHARPP(t_rightsp);
char *p_principals;
extern char *acltypes[];
p_principals = NULL;
if(qsscanf(next_word, "%'&s %'&s %'&s %r",
&*t_acetypep, &*t_atypep, &*t_rightsp, &p_principals) < 3) {
p_err_string = qsprintf_stcopyr(p_err_string,
"Malformed ACL line: %'s", command);
return PARSE_ERROR;
}
for(value->acetype = 0;acltypes[value->acetype];
(value->acetype)++) {
if(strequal(acltypes[value->acetype],*t_acetypep))
break;
}
if(acltypes[value->acetype] == NULL) {
p_err_string = qsprintf_stcopyr(p_err_string,
"Unknown ACL type: %'s", command);
return PARSE_ERROR;
}
/* We stcopy() twice; this is not necessary. */
value->atype = stcopyr((**t_atypep ? *t_atypep : NULL), value->atype);
value->rights = stcopyr((**t_rightsp ? *t_rightsp : NULL), value->rights);
value->principals = (p_principals ? qtokenize(p_principals) : NULL);
return PSUCCESS;
}