/* This file is part of the Project Athena Zephyr Notification System. * It contains functions for dealing with acl's. * * Created by: John T. Kohl * * $Id$ * * Copyright (c) 1987 by the Massachusetts Institute of Technology. * For copying and distribution information, see the file * "mit-copyright.h". */ #include #include "zserver.h" #if !defined (lint) && !defined (SABER) static const char rcsid_access_c[] = "$Id$"; #endif /* * * External routines: * * int access_check(sender, who, acl, accesstype) * char *sender; * struct sockaddr_in *who; * Acl *acl; * Access accesstype; * * int opstaff_check(sender) * char *sender; * * void access_init(); * * void access_reinit(); */ /* * Each restricted class has four ACL's associated with it, * governing subscriptions, transmission, and instance restrictions. * This module provides the 'glue' between the standard Athena ACL * routines and the support needed by the Zephyr server. */ /* * Our private types for the acl_types field in the Acl structure. * -TYT 8/14/90 */ #define ACL_XMT 1 #define ACL_SUB 2 #define ACL_IWS 4 #define ACL_IUI 8 static void check_acl(Acl *acl); static void check_acl_type(Acl *acl, Access accesstype, int typeflag); static void access_setup(int first); /* * check access. return 1 if ok, 0 if not ok. */ int access_check(char *sender, struct sockaddr_in *who, Acl *acl, Access accesstype) { char buf[1024]; /* holds the real acl name */ char *prefix; int flag; int retval; switch (accesstype) { case TRANSMIT: prefix = "xmt"; flag = ACL_XMT; break; case SUBSCRIBE: prefix = "sub"; flag = ACL_SUB; break; case INSTWILD: prefix = "iws"; flag = ACL_IWS; break; case INSTUID: prefix = "iui"; flag = ACL_IUI; break; default: syslog(LOG_ERR, "unknown access type %d", (int) accesstype); return 0; } if (!(acl->acl_types & flag)) /* no acl ==> no restriction */ return 1; snprintf(buf, sizeof buf, "%s/%s-%s.acl", acl_dir, prefix, acl->acl_filename); /* * If we can't load it (because it probably doesn't exist), * we deny access. */ retval = acl_load(buf); if (retval < 0) { syslog(LOG_DEBUG, "Error in acl_load of %s for %s", buf, sender ? sender : "unauth client"); return 0; } return acl_check(buf, sender, who); } int opstaff_check(char *sender) { char buf[1024]; /* holds the real acl name */ int retval; snprintf(buf, sizeof buf, "%s/opstaff.acl", acl_dir); /* * If we can't load it (because it probably doesn't exist), * we deny access. */ retval = acl_load(buf); if (retval < 0) { syslog(LOG_DEBUG, "Error in acl_load of %s for %s", buf, sender ? sender : "unauth client"); return 0; } return acl_check(buf, sender, NULL); } static void check_acl(Acl *acl) { acl->acl_types = 0; check_acl_type(acl, TRANSMIT, ACL_XMT); check_acl_type(acl, SUBSCRIBE, ACL_SUB); check_acl_type(acl, INSTWILD, ACL_IWS); check_acl_type(acl, INSTUID, ACL_IUI); } static void check_acl_type(Acl *acl, Access accesstype, int typeflag) { char buf[1024]; /* holds the real acl name */ char *prefix; switch (accesstype) { case TRANSMIT: prefix = "xmt"; break; case SUBSCRIBE: prefix = "sub"; break; case INSTWILD: prefix = "iws"; break; case INSTUID: prefix = "iui"; break; default: syslog(LOG_ERR, "unknown access type %d", (int) accesstype); return; } snprintf(buf, sizeof buf, "%s/%s-%s.acl", acl_dir, prefix, acl->acl_filename); if (!access(buf, F_OK)) acl->acl_types |= typeflag; } /* * Re-init code written by TYT, 8/14/90. * * General plan of action; we reread the registry list, and add any * new restricted classes. If any restricted classes disappear (this * should be rarely) the Acl structure is not deallocated; rather, * the acl_types field will be left at zero, since there will be no * acl files for the (non-)restricted class. */ static void access_setup(int first) { char buf[1024]; char class_name[512]; /* assume class names <= 511 bytes */ FILE *registry; Acl *acl; int len; char *colon_idx; Code_t retval = 0; snprintf(buf, sizeof buf, "%s/%s", acl_dir, ZEPHYR_CLASS_REGISTRY); registry = fopen(buf, "r"); if (!registry) { syslog(LOG_ERR, "no registry available, all classes are free"); return; } while (fgets(class_name, 512, registry)) { colon_idx = strchr(class_name, ':'); if (colon_idx != NULL) *colon_idx = '\0'; else if ((len = strlen(class_name)) != 0) class_name[len - 1] = '\0'; acl = 0; if (!first) { String *z; z = make_string(class_name,1); acl = class_get_acl(z); free_string(z); } if (!acl) { acl = (Acl *) malloc(sizeof(Acl)); if (!acl) { syslog(LOG_ERR, "no mem acl alloc"); abort(); } acl->acl_filename = strsave(class_name); check_acl(acl); if (!first) { /* Try to restrict already existing class */ retval = class_restrict(class_name, acl); if (retval == ZSRV_NOCLASS) retval = class_setup_restricted(class_name, acl); } else { retval = class_setup_restricted(class_name, acl); } } if (retval) { syslog(LOG_ERR, "can't restrict %s: %s", class_name, error_message(retval)); continue; } zdbug((LOG_DEBUG, "restricted %s", class_name)); } fclose(registry); } void access_init(void) { access_setup(1); } void access_reinit(void) { acl_cache_reset(); access_setup(0); }