1
0
Files
irix-657m-src/eoe/cmd/mklbldb/mls_init.c
2022-09-29 17:59:04 +03:00

579 lines
14 KiB
C

/**************************************************************************
* *
* Copyright (C) 1990, Silicon Graphics, Inc. *
* *
* These coded instructions, statements, and computer programs contain *
* unpublished proprietary information of Silicon Graphics, Inc., and *
* are protected by Federal copyright law. They may not be disclosed *
* to third parties or copied or duplicated in any form, in whole or *
* in part, without the prior written consent of Silicon Graphics, Inc. *
* *
**************************************************************************/
#ident "$Revision"
/*LINTLIBRARY*/
#include <sys/mac_label.h>
#include <mls.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <malloc.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <ctype.h>
static void __insert_lbldblist( char *, char * );
static void __insert_dblist( int, char *, int );
static int __strip_whitespace( char * );
static int _chkfield_value( int, int );
static int __is_text( char * );
static int __pack_db( void );
#define NAMES_PATH "/etc/mac_label/"
#ifdef DEBUG
/* constant define for secadm data base file path */
#define LABELS "labels.tmp"
#define MSEN_TYPES "msentypes.tmp"
#define LEVELS "levels.tmp"
#define CATEGORIES "categorys.tmp"
#define MINT_TYPES "minttypes.tmp"
#define GRADES "grades.tmp"
#define DIVISIONS "divisions.tmp"
#else
/* constant define for secadm data base file path */
#define LABELS "labelnames"
#define MSEN_TYPES "msentypenames"
#define LEVELS "levelnames"
#define CATEGORIES "categorynames"
#define MINT_TYPES "minttypenames"
#define GRADES "gradenames"
#define DIVISIONS "divisionnames"
#endif
/*
* global variables used for Truested IRIX/B library functions
*/
char *__mac_mlsfile[MAX_MLSFILES] = { /* array of database file path */
LABELS,
MSEN_TYPES,
LEVELS,
CATEGORIES,
MINT_TYPES,
GRADES,
DIVISIONS};
int __mls_entry_total[] = {
0, /* total entry count for labels database */
0, /* total entry entry for msentypes database */
0, /* total entry count for levels database */
0,
0,
0,
0};
DBENT *__mac_mdblist[MAX_MLSFILES]; /* array of ptr to entity db list */
LBLDBINFO *__mac_bin_lbldblist=0; /* pointer to binary label db list */
DBINFO *__mac_bin_mdblist[MAX_MLSFILES]; /* pointer to binary entity db list */
LBLDB_BIN_HDR __mac_lhead; /* header for labelnames binary file */
DB_BIN_HDR __mac_dhead[MAX_MLSFILES]; /* header for entity binary file */
int __mac_mls_init_inprocess; /* indicate mls_init is in_process */
int __mac_bad_label_entry=0; /* any bad labelname entry exist */
int __mac_db_error=0;
char mlsfile[MAXPATHLEN];
extern char *newroot;
/* constant define for warning message */
#define OPEN_FAIL 0
#define NAME_FAIL OPEN_FAIL+1
#define VALUE_FAIL NAME_FAIL+1
#define SYNTAX_FAIL VALUE_FAIL+1
#define UNIQUE_FAIL SYNTAX_FAIL+1
#define LBLWRITE_FAIL UNIQUE_FAIL+1
#define LABEL_FAIL LBLWRITE_FAIL+1
#define INIT_FAIL LABEL_FAIL+1
#define PACK_FAIL INIT_FAIL+1
#define READ_FAIL PACK_FAIL+1
extern void __inform_user( int, char * );
/*
* mls_init()
* initialize the mls database file, open the file, read in the data entry
* store into the entry list and packed in binary file format for mls_mkdb()
* This function will be performed only by the action of system adminstrator.
*/
int
mls_init()
{
FILE *fp;
int i,ftype,field_value;
char line[MAX_MLS_LINE_LEN];
static char saveline[MAX_MLS_LINE_LEN];
char *namestr, *valuestr;
char *colonp, *backslashp, *lastchar, *compstr, *endchar;
int more_line;
/*
* a flag indicate mls_init is in process
*/
__mac_mls_init_inprocess = 1;
/*
* read in labels,msentypes, levels, categorys, minttypes, grades and
* divisions files, stored the entry to link list
*/
more_line = 0;
saveline[0] = '\0';
for (ftype=0; ftype< MAX_MLSFILES; ftype++) {
if (newroot != NULL)
strcpy(mlsfile, newroot);
else
strcpy(mlsfile, NAMES_PATH);
i = strlen(mlsfile);
if (mlsfile[i-1] != '/')
strcat(mlsfile, "/");
strcat(mlsfile, __mac_mlsfile[ftype]);
if ( (fp = fopen(mlsfile,"r")) == NULL) {
__inform_user(OPEN_FAIL, mlsfile);
continue;
}
while (fgets(line, MAX_MLS_LINE_LEN, fp) != NULL) {
/*
* if the end of line contains backslash char,
* treats it as continuation mark for next line
*/
if ((backslashp = index(line, '\\')) != NULL) {
if (strlen(backslashp) > 2) {
continue;
}
*backslashp = '\0';
strcat(saveline,line);
for (i=0; i<strlen(line); i++)
line[i] = '\0';
more_line = 1;
continue;
}
if (more_line == 1) {
strcat(saveline, line);
strcpy(line,saveline);
more_line = 0;
for (i=0; i<strlen(saveline); i++)
saveline[i] = '\0';
}
/*
* NULL the newline character. If there
* is none go on.
*/
if ((endchar = index(line, '\n')) == NULL)
continue;
*endchar = '\0';
/*
* ignore empty line
*/
if (strlen(line) == 0)
continue;
/*
* if the line contains space or tab chars at the
* beginning or end of line, strip them
*/
if (index(line, ' ') != NULL ||
index(line, TAB_CHAR) != NULL) {
if (__strip_whitespace(&line[0]) < 0) {
__inform_user(SYNTAX_FAIL,line);
continue;
}
}
/*
* If the first char is pound sign, it is a
* comment line, ignore it
*/
if (line[0] == '#')
continue;
/*
* if the line contains double quote or does not
* colon, report syntax error and go to next line
*/
if ( (colonp = index(line, ':')) == NULL ||
index(line, '"') != NULL ) {
__inform_user(SYNTAX_FAIL, line);
continue;
}
*colonp = '\0';
namestr = line;
/*
* The name length should be within range, and the
* name must leading with a ASCII character A to Z
* or a to z and the name can not contains slash
* character.
*/
if ((strlen(namestr) >= MAX_MLS_NAME_LEN) ||
(__is_text(namestr) < 0) ||
(index(namestr, '/') != NULL) ) {
__inform_user(NAME_FAIL, namestr);
continue;
}
if (ftype == MAC_LABEL) {
compstr = colonp + 1;
if (!__mac_lbldblist) {
__mac_lbldblist = (LBLDBLIST *)
malloc(sizeof(LBLDBLIST));
__mac_lbldblist->head = NULL;
__mac_lbldblist->tail = NULL;
}
__insert_lbldblist(namestr, compstr);
} else {
/* check field value validity */
valuestr = colonp + 1;
field_value = strtol(valuestr, NULL,0);
if (_chkfield_value(ftype, field_value) < 0) {
__inform_user(VALUE_FAIL, valuestr);
continue;
}
__insert_dblist(ftype, namestr, field_value);
}
}
}
/*
* if the mls database has error entry, report init fail
*/
if (__mac_db_error == 1)
return(1);
__pack_db();
__mac_mls_init_inprocess =0;
}
/*
* __insert_lbldblist(name, comp)
* insert each label/component name string entry into linear linked list
* also calculate the total entry count and totol byte size for later
* usage
*/
static void
__insert_lbldblist(char *name, char *comp)
{
LBLDBENT *ptr, *vptr;
LBLDBLIST *vlist;
ptr = (LBLDBENT *) malloc(sizeof(LBLDBENT));
ptr->name = strdup(name);
ptr->comp = strdup(comp);
ptr->next = NULL;
if (__mac_lbldblist->head == NULL) {
__mac_lbldblist->head = __mac_lbldblist->tail = ptr;
}
else {
__mac_lbldblist->tail->next = ptr;
__mac_lbldblist->tail = ptr;
}
__mls_entry_total[MAC_LABEL]++;
}
/*
* __insert_dblist(ftype, name, value)
* insert each data entry into the entry list, the list is sorted by value
* the list is a circular link list structure. The data base entry include
* the name & value information for msentypes, levels, categorys, minttypes
* grades or divisions entity
*/
static void
__insert_dblist(int ftype, char *name, int value)
{
DBENT *vptr, *vlist;
DBENT *p, *ptr;
int i, strsize;
vptr = (struct dbent *) malloc(sizeof(DBENT));
vptr->name = strdup(name);
vptr->value = value;
if ( __mac_mdblist[ftype] == NULL) {
vlist =__mac_mdblist[ftype] = malloc(sizeof(DBENT));
vlist->next = vlist->prev = vlist;
vlist->value = INVALID_ENTRY_VALUE;
vlist->name = '\0';
}
vlist = __mac_mdblist[ftype];
p = vlist->prev;
while (value < p->value && p->prev != vlist) {
p = p->prev;
}
/*
* We want to insert vptr after of p.
* That is, we want to insert vptr between p and p-next.
* insert p into the list
*/
vptr->prev = p;
vptr->next = p->next;
p->next->prev = vptr;
p->next = vptr;
__mls_entry_total[ftype]++;
vptr = vlist->next;
}
/*
* __strip_whitespace(line)
* strip leading or trailing space key and tab key from a line
*/
static int
__strip_whitespace(char *line)
{
char *s, *p, *t, *newstr;
int charcnt=0;
int i;
s = line;
p = newstr = malloc(strlen(line));
while (*s != '\0') {
if (*s == ' ' || *s == TAB_CHAR) {
if (charcnt > 0) {
t = s+1;
while (*t++ != '\0') {
if (*t != ' ' && *t != TAB_CHAR)
return(-1);
}
}
}
else {
charcnt++;
*p++ = *s;
if (charcnt == 1 && *s == '#')
break;
}
s++;
}
*p = '\0';
strcpy(line, newstr);
free(newstr);
}
/*
* _chkfield_value(ftype,value)
* check the field value validity, the field includes msentype, level,
* category, minttype, grade & division.
*/
static int
_chkfield_value(int ftype, int value)
{
extern const char __mac_type_info[];
switch (ftype) {
case MAC_MSEN_TYPE:
switch (value) {
case MSEN_ADMIN_LABEL:
case MSEN_EQUAL_LABEL:
case MSEN_HIGH_LABEL:
case MSEN_MLD_HIGH_LABEL:
case MSEN_LOW_LABEL:
case MSEN_MLD_LABEL:
case MSEN_MLD_LOW_LABEL:
case MSEN_TCSEC_LABEL:
return(0);
default:
break;
}
break;
case MAC_MINT_TYPE:
switch (value) {
case MINT_BIBA_LABEL:
case MINT_EQUAL_LABEL:
case MINT_HIGH_LABEL:
case MINT_LOW_LABEL:
return(0);
default:
break;
}
break;
case MAC_LEVEL:
if (value >= MSEN_MIN_LEVEL && value <= MSEN_MAX_LEVEL)
return(0);
break;
case MAC_GRADE:
if (value >= MINT_MIN_GRADE && value <= MINT_MAX_GRADE)
return(0);
break;
case MAC_CATEGORY:
if (value >= MSEN_MIN_CATEGORY && value <= MSEN_MAX_CATEGORY)
return(0);
break;
case MAC_DIVISION:
if (value >= MINT_MIN_DIVISION && value <= MINT_MAX_DIVISION )
return(0);
break;
default:
break;
}
return(-1);
}
/*
* pack_db()
* collect the information from the linked list, allocate memory to
* store the information in an array format, prepare for loading
* information into binary file format
*/
static int
__pack_db(void)
{
LBLDB_BIN_ENT *llist;
DB_BIN_ENT *dlist;
LBLDBENT *pl;
DBENT *pd;
int i,j;
mac_label *lp;
int lblsize=0;
int ftype;
/*
* get the data from linked list and pack the labels information
*/
__mac_bin_lbldblist = (LBLDBINFO *) malloc(sizeof(LBLDBINFO));
llist = __mac_bin_lbldblist->list = (LBLDB_BIN_ENT *)
malloc( __mls_entry_total[MAC_LABEL] * sizeof(LBLDB_BIN_ENT) );
__mac_lhead.entry_total = __mls_entry_total[MAC_LABEL];
__mac_lhead.entries_bytes = __mls_entry_total[MAC_LABEL] * sizeof(LBLDB_BIN_ENT);
if (__mac_lbldblist) {
pl = __mac_lbldblist->head;
for (i=0; i<__mls_entry_total[MAC_LABEL]; i++) {
llist->strlen = (unsigned short) strlen(pl->name);
strcpy(llist->name, pl->name);
llist->lblsize = 0;
#ifdef DEBUG
printf("\ndatabase -- name: %s, comp : %s\n", pl->name, pl->comp);
#endif
if ( (lp = (mac_label *) mac_strtolabel(pl->comp)) != NULL){
__dump_maclabel(lp);
if ((lblsize = mac_size(lp)) > 0) {
llist->lblsize = (unsigned short) lblsize;
mac_copy(&llist->label,lp);
#ifdef DEBUG
__dump_maclabel(&llist->label);
#endif
}
else
__inform_user(LABEL_FAIL, llist->name);
}
else {
/*
* if bad label name or label component is
* defined in the database file, inform the
* system adminstrator and don't generate
* binary file
*/
__mac_bad_label_entry = 1;
__inform_user(LABEL_FAIL, llist->name);
}
llist++;
pl = pl->next;
}
}
/*
* If there is any bad label defined, don't rebuild binary file
* don't process any further
*/
if (__mac_bad_label_entry == 1)
return(-1);
for (ftype=MAC_MSEN_TYPE; ftype<MAX_MLSFILES; ftype++) {
__mac_bin_mdblist[ftype] = (DBINFO *) malloc(sizeof(DBINFO));
dlist = __mac_bin_mdblist[ftype]->list = (DB_BIN_ENT *) malloc
(sizeof(DB_BIN_ENT) * __mls_entry_total[ftype]);
__mac_dhead[ftype].db_type = ftype;
__mac_dhead[ftype].entry_total = __mls_entry_total[ftype];
#ifdef DEBUG
printf("__mac_dhead[%d].entry_total = %d\n", ftype, __mac_dhead[ftype].entry_total);
#endif
__mac_dhead[ftype].entries_bytes = __mac_dhead[ftype].entry_total * sizeof(DB_BIN_ENT);
/*
* go through the circular link list and get the value
* and name string, load them into binary entry buffer
*/
if (__mac_mdblist[ftype]) {
pd = __mac_mdblist[ftype]->next;
for (j=0; (j<__mls_entry_total[ftype]) && pd->value != 65535; j++) {
dlist->value = (unsigned short) pd->value;
dlist->strlen = (unsigned short) strlen(pd->name);
strcpy(dlist->name, pd->name);
pd = pd->next;
dlist++;
}
}
#ifdef DEBUG
/* __dump_list(ftype); */
#endif
}
return(0);
}
/*
* __is_text(str)
* check whether the input string is a text string
*/
static int
__is_text(char *str)
{
if ( (str[0] >= 'A' && str[0] <= 'Z') ||
(str[0] >= 'a' && str[0] <= 'z') )
return(0);
else
return(-1);
}
/*
* __inform_user(err_type, ftype, info)
* inform the user erring messages for mls library function
*/
void
__inform_user(int err_type, char *info)
{
static char *err_msg[] = {
"** Error: can not open file",
"** Error: invalid field name",
"** Error: invalid field value",
"** Error: syntax error for string",
"** Error: non-unique field name",
"** Error: can not write to binary file",
"** Error: invalid mac label for label string",
"** Error: mls_init must be invoked in order to perform mls_unqiue",
"** Error: can not pack mls database info into binary file",
"** Error: can not read from file"};
printf("%s ", err_msg[err_type]);
if (info)
printf("%s\n", info);
}