From 0415965d8fd7420417895e189c9c79f67cfaf0a6 Mon Sep 17 00:00:00 2001 From: Greg Hudson Date: Tue, 27 Aug 1996 12:28:13 +0000 Subject: This file was deleted in the 8.0 source tree --- server/acl_files.c | 593 ----------------------------------------------------- 1 file changed, 593 deletions(-) delete mode 100644 server/acl_files.c (limited to 'server/acl_files.c') diff --git a/server/acl_files.c b/server/acl_files.c deleted file mode 100644 index 3932e52..0000000 --- a/server/acl_files.c +++ /dev/null @@ -1,593 +0,0 @@ -/* This file is part of the Project Athena Zephyr Notification System. - * It contains functions for maintaining Access Control Lists. - * - * Created by: John T. Kohl - * - * $Source$ - * $Author$ - * - * Copyright (c) 1987,1988 by the Massachusetts Institute of Technology. - * For copying and distribution information, see the file - * "mit-copyright.h". - */ - -/* Define this if you really want the ACL-writing code included. */ -/* #define WRITE_ACL */ - -/* - * Stolen from lib/acl_files.c because acl_load needs to be externally - * declared and not statically declared. - */ - -#include - -#ifndef SABER -#ifndef lint -static char rcsid_acl_files_c[] = "$Id$"; -#endif /* lint */ -#endif /* SABER */ - -/*** Routines for manipulating access control list files ***/ - -#include -#include -#include -#include -#include -#include /* for MAXHOSTNAMELEN */ - -/* "aname.inst@realm" */ -#define MAX_PRINCIPAL_SIZE (ANAME_SZ + INST_SZ + REALM_SZ + 3) -#define INST_SEP '.' -#define REALM_SEP '@' - -#define LINESIZE 2048 /* Maximum line length in an acl file */ - -#define NEW_FILE "%s.~NEWACL~" /* Format for name of altered acl file */ -#define WAIT_TIME 300 /* Maximum time allowed write acl file */ - -#define CACHED_ACLS 64 /* How many acls to cache */ -#define ACL_LEN 256 /* Twice a reasonable acl length */ - -#define MAX(a,b) (((a)>(b))?(a):(b)) -#define MIN(a,b) (((a)<(b))?(a):(b)) - -#define COR(a,b) ((a!=NULL)?(a):(b)) - -extern int errno; - -extern time_t time(); - -/* Canonicalize a principal name */ -/* If instance is missing, it becomes "" */ -/* If realm is missing, it becomes the local realm */ -/* Canonicalized form is put in canon, which must be big enough to hold - MAX_PRINCIPAL_SIZE characters */ -acl_canonicalize_principal(principal, canon) - char *principal; - char *canon; -{ - char *end; - char *dot, *atsign; - int len; - - dot = (char *) strchr(principal, INST_SEP); - atsign = (char *) strchr(principal, REALM_SEP); - - /* Maybe we're done already */ - if(dot != NULL && atsign != NULL) { - if(dot < atsign) { - /* It's for real */ - /* Copy into canon */ - strncpy(canon, principal, MAX_PRINCIPAL_SIZE); - canon[MAX_PRINCIPAL_SIZE-1] = '\0'; - return; - } else { - /* Nope, it's part of the realm */ - dot = NULL; - } - } - - /* No such luck */ - end = principal + strlen(principal); - - /* Get the principal name */ - len = MIN(ANAME_SZ, COR(dot, COR(atsign, end)) - principal); - strncpy(canon, principal, len); - canon += len; - - /* Add INST_SEP */ - *canon++ = INST_SEP; - - /* Get the instance, if it exists */ - if(dot != NULL) { - ++dot; - len = MIN(INST_SZ, COR(atsign, end) - dot); - strncpy(canon, dot, len); - canon += len; - } - - /* Add REALM_SEP */ - *canon++ = REALM_SEP; - - /* Get the realm, if it exists */ - /* Otherwise, default to local realm */ - if(atsign != NULL) { - ++atsign; - len = MIN(REALM_SZ, end - atsign); - strncpy(canon, atsign, len); - canon += len; - *canon++ = '\0'; - } -#ifdef KERBEROS - else if(krb_get_lrealm(canon, 1) != KSUCCESS) { - strcpy(canon, KRB_REALM); - } -#endif -} - -#ifdef notdef -/* Get a lock to modify acl_file */ -/* Return new FILE pointer */ -/* or NULL if file cannot be modified */ -/* REQUIRES WRITE PERMISSION TO CONTAINING DIRECTORY */ -static FILE *acl_lock_file(acl_file) -char *acl_file; -{ - struct stat s; - char new[LINESIZE]; - int nfd; - FILE *nf; - int mode; - - if(stat(acl_file, &s) < 0) return(NULL); - mode = s.st_mode; - sprintf(new, NEW_FILE, acl_file); - for(;;) { - /* Open the new file */ - if((nfd = open(new, O_WRONLY|O_CREAT|O_EXCL, mode)) < 0) { - if(errno == EEXIST) { - /* Maybe somebody got here already, maybe it's just old */ - if(stat(new, &s) < 0) return(NULL); - if(time(0) - s.st_ctime > WAIT_TIME) { - /* File is stale, kill it */ - unlink(new); - continue; - } else { - /* Wait and try again */ - sleep(1); - continue; - } - } else { - /* Some other error, we lose */ - return(NULL); - } - } - - /* If we got to here, the lock file is ours and ok */ - /* Reopen it under stdio */ - if((nf = fdopen(nfd, "w")) == NULL) { - /* Oops, clean up */ - unlink(new); - } - return(nf); - } -} - -/* Commit changes to acl_file written onto FILE *f */ -/* Returns zero if successful */ -/* Returns > 0 if lock was broken */ -/* Returns < 0 if some other error occurs */ -/* Closes f */ -static int acl_commit(acl_file, f) -char *acl_file; -FILE *f; -{ -#ifdef WRITE_ACL - char new[LINESIZE]; - int ret; - struct stat s; - - sprintf(new, NEW_FILE, acl_file); - if(fflush(f) < 0 - || fstat(fileno(f), &s) < 0 - || s.st_nlink == 0) { - acl_abort(acl_file, f); - return(-1); - } - - ret = rename(new, acl_file); - fclose(f); - return(ret); -#else - abort (); -#endif -} - -/* Abort changes to acl_file written onto FILE *f */ -/* Returns 0 if successful, < 0 otherwise */ -/* Closes f */ -static int acl_abort(acl_file, f) -char *acl_file; -FILE *f; -{ -#ifdef WRITE_ACL - char new[LINESIZE]; - int ret; - struct stat s; - - /* make sure we aren't nuking someone else's file */ - if(fstat(fileno(f), &s) < 0 - || s.st_nlink == 0) { - fclose(f); - return(-1); - } else { - sprintf(new, NEW_FILE, acl_file); - ret = unlink(new); - fclose(f); - return(ret); - } -#else - abort (); -#endif -} - -/* Initialize an acl_file */ -/* Creates the file with permissions perm if it does not exist */ -/* Erases it if it does */ -/* Returns return value of acl_commit */ -int -acl_initialize(acl_file, perm) - char *acl_file; - int perm; -{ - FILE *new; - int fd; - - /* Check if the file exists already */ - if((new = acl_lock_file(acl_file)) != NULL) { - return(acl_commit(acl_file, new)); - } else { - /* File must be readable and writable by owner */ - if((fd = open(acl_file, O_CREAT|O_EXCL, perm|0600)) < 0) { - return(-1); - } else { - close(fd); - return(0); - } - } -} - -#endif /* notdef */ - -/* Eliminate all whitespace character in buf */ -/* Modifies its argument */ -static nuke_whitespace(buf) -char *buf; -{ - register char *pin, *pout; - - for(pin = pout = buf; *pin != '\0'; pin++) - if(!isspace(*pin)) *pout++ = *pin; - *pout = '\0'; /* Terminate the string */ -} - -/* Hash table stuff */ - -struct hashtbl { - int size; /* Max number of entries */ - int entries; /* Actual number of entries */ - char **tbl; /* Pointer to start of table */ -}; - -/* Make an empty hash table of size s */ -static struct hashtbl *make_hash(size) -int size; -{ - struct hashtbl *h; - - if(size < 1) size = 1; - h = (struct hashtbl *) malloc(sizeof(struct hashtbl)); - h->size = size; - h->entries = 0; - h->tbl = (char **) calloc(size, sizeof(char *)); - return(h); -} - -/* Destroy a hash table */ -static void -destroy_hash(h) - struct hashtbl *h; -{ - int i; - - for(i = 0; i < h->size; i++) { - if(h->tbl[i] != NULL) free(h->tbl[i]); - } - free(h->tbl); - free(h); -} - -/* Compute hash value for a string */ -static unsigned int -hashval(s) - char *s; -{ - register unsigned hv; - - for(hv = 0; *s != '\0'; s++) { - hv ^= ((hv << 3) ^ *s); - } - return(hv); -} - -/* Add an element to a hash table */ -static add_hash(h, el) -struct hashtbl *h; -char *el; -{ - unsigned hv; - char *s; - char **old; - int i; - -#if 0 - fprintf (stderr, "adding %s to acl hash %08X\n", el, h); -#endif - /* Make space if it isn't there already */ - if(h->entries + 1 > (h->size >> 1)) { - old = h->tbl; - h->tbl = (char **) calloc(h->size << 1, sizeof(char *)); - for(i = 0; i < h->size; i++) { - if(old[i] != NULL) { - hv = hashval(old[i]) % (h->size << 1); - while(h->tbl[hv] != NULL) hv = (hv+1) % (h->size << 1); - h->tbl[hv] = old[i]; - } - } - h->size = h->size << 1; - free(old); - } - - hv = hashval(el) % h->size; - while(h->tbl[hv] != NULL && strcmp(h->tbl[hv], el)) hv = (hv+1) % h->size; - s = (char *) malloc(strlen(el)+1); - strcpy(s, el); - h->tbl[hv] = s; - h->entries++; -} - -/* Returns nonzero if el is in h */ -static int -check_hash(h, el) - struct hashtbl *h; - char *el; -{ - unsigned hv; - -#if 0 - fprintf (stderr, "looking for %s in acl %08X\n", el, h); -#endif - for(hv = hashval(el) % h->size; h->tbl[hv]; hv = (hv + 1) % h->size) { -#if 0 - fprintf (stderr, "\tstrcmp (%s,...)\n", h->tbl[hv]); -#endif - if (!strcmp(h->tbl[hv], el)) { -#if 0 - fprintf (stderr, "success!\n"); -#endif - return 1; - } - } -#if 0 - fprintf (stderr, "failure\n"); -#endif - return 0; -} - -struct acl { - char filename[LINESIZE]; /* Name of acl file */ - struct hashtbl *acl; /* Acl entries */ -}; - -static struct acl acl_cache[CACHED_ACLS]; - -static int acl_cache_count = 0; -static int acl_cache_next = 0; - -/* Returns < 0 if unsuccessful in loading acl */ -/* Returns index into acl_cache otherwise */ -/* Note that if acl is already loaded, this is just a lookup */ -int acl_load(name) - char *name; -{ - int i; - FILE *f; - char buf[MAX_PRINCIPAL_SIZE]; - char canon[MAX_PRINCIPAL_SIZE]; - - /* See if it's there already */ - for(i = 0; i < acl_cache_count; i++) { - if (!strcmp(acl_cache[i].filename, name)) - goto got_it; - } - - /* It isn't, load it in */ - /* maybe there's still room */ - if(acl_cache_count < CACHED_ACLS) { - i = acl_cache_count++; - } else { - /* No room, clean one out */ - i = acl_cache_next; - acl_cache_next = (acl_cache_next + 1) % CACHED_ACLS; - if(acl_cache[i].acl) { - destroy_hash(acl_cache[i].acl); - acl_cache[i].acl = (struct hashtbl *) 0; - } - } - - /* Set up the acl */ - strcpy(acl_cache[i].filename, name); - /* Force reload */ - acl_cache[i].acl = (struct hashtbl *) 0; - - got_it: - /* - * See if we need to reload the ACL - */ - if (acl_cache[i].acl == (struct hashtbl *) 0) { - /* Gotta reload */ -#if 0 - fprintf (stderr, "attempting to load %s\n", name); -#endif - if ((f = fopen(name, "r")) == NULL) { -#if 0 - perror (name); -#endif - return -1; - } - if (acl_cache[i].acl) destroy_hash(acl_cache[i].acl); - acl_cache[i].acl = make_hash(ACL_LEN); - while(fgets(buf, sizeof(buf), f) != NULL) { - nuke_whitespace(buf); - acl_canonicalize_principal(buf, canon); - add_hash(acl_cache[i].acl, canon); - } - fclose(f); - } - return(i); -} - -/* - * This destroys all cached ACL's so that new ones will be loaded in - * the next time they are requested. - */ -void -acl_cache_reset() -{ - int i; - - /* See if it's there already */ - for(i = 0; i < acl_cache_count; i++) - if (acl_cache[i].acl) { - destroy_hash(acl_cache[i].acl); - acl_cache[i].acl = (struct hashtbl *) 0; - } - acl_cache_count = 0; - acl_cache_next = 0; -} - - -/* Returns nonzero if it can be determined that acl contains principal */ -/* Principal is not canonicalized, and no wildcarding is done */ -acl_exact_match(acl, principal) - char *acl; - char *principal; -{ - int idx; - -#if 0 - fprintf (stderr, "checking for %s in %s\n", principal, acl); -#endif - return((idx = acl_load(acl)) >= 0 - && check_hash(acl_cache[idx].acl, principal)); -} - -/* Returns nonzero if it can be determined that acl contains principal */ -/* Recognizes wildcards in acl of the form - name.*@realm, *.*@realm, and *.*@* */ -int -acl_check(acl, principal) - char *acl; - char *principal; -{ - char buf[MAX_PRINCIPAL_SIZE]; - char canon[MAX_PRINCIPAL_SIZE]; - char *realm; - - acl_canonicalize_principal(principal, canon); - - /* Is it there? */ - if (acl_exact_match(acl, canon)) - return 1; - - /* Try the wildcards */ - realm = (char *) strchr(canon, REALM_SEP); - *((char *)strchr(canon, INST_SEP)) = '\0'; /* Chuck the instance */ - - sprintf(buf, "%s.*%s", canon, realm); - if(acl_exact_match(acl, buf)) return 1; - - sprintf(buf, "*.*%s", realm); - if(acl_exact_match(acl, buf) || acl_exact_match(acl, "*.*@*")) return(1); - - return(0); -} - -#ifdef notdef -/* Adds principal to acl */ -/* Wildcards are interpreted literally */ -int -acl_add(acl, principal) - char *acl; - char *principal; -{ - int idx; - int i; - FILE *new; - char canon[MAX_PRINCIPAL_SIZE]; - - acl_canonicalize_principal(principal, canon); - - if((new = acl_lock_file(acl)) == NULL) return(-1); - if((acl_exact_match(acl, canon)) - || (idx = acl_load(acl)) < 0) { - acl_abort(acl, new); - return(-1); - } - /* It isn't there yet, copy the file and put it in */ - for(i = 0; i < acl_cache[idx].acl->size; i++) { - if(acl_cache[idx].acl->tbl[i] != NULL) { - if(fputs(acl_cache[idx].acl->tbl[i], new) == NULL - || putc('\n', new) != '\n') { - acl_abort(acl, new); - return(-1); - } - } - } - fputs(canon, new); - putc('\n', new); - return(acl_commit(acl, new)); -} - -/* Removes principal from acl */ -/* Wildcards are interpreted literally */ -int -acl_delete(acl, principal) - char *acl; - char *principal; -{ - int idx; - int i; - FILE *new; - char canon[MAX_PRINCIPAL_SIZE]; - - acl_canonicalize_principal(principal, canon); - - if((new = acl_lock_file(acl)) == NULL) return(-1); - if((!acl_exact_match(acl, canon)) - || (idx = acl_load(acl)) < 0) { - acl_abort(acl, new); - return(-1); - } - /* It isn't there yet, copy the file and put it in */ - for(i = 0; i < acl_cache[idx].acl->size; i++) { - if(acl_cache[idx].acl->tbl[i] != NULL - && strcmp(acl_cache[idx].acl->tbl[i], canon)) { - fputs(acl_cache[idx].acl->tbl[i], new); - putc('\n', new); - } - } - return(acl_commit(acl, new)); -} -#endif /* notdef */ -- cgit v1.2.3