Logo Search packages:      
Sourcecode: zephyr version File versions  Download package

access.c

/* 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: access.c,v 1.18 1999/01/22 23:19:36 ghudson Exp $
 *
 *    Copyright (c) 1987 by the Massachusetts Institute of Technology.
 *    For copying and distribution information, see the file
 *    "mit-copyright.h". 
 */

#include <zephyr/mit-copyright.h>
#include "zserver.h"
#include <com_err.h>

#if !defined (lint) && !defined (SABER)
static const char rcsid_access_c[] =
    "$Id: access.c,v 1.18 1999/01/22 23:19:36 ghudson Exp $";
#endif

/*
 *
 * External routines:
 *
 * int access_check(notice, acl, accesstype)
 *    ZNotice_t *notice;
 *    Acl *acl;
 *    Access accesstype;
 *
 * 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 __P((Acl *acl));
static void check_acl_type __P((Acl *acl, Access accesstype, int typeflag));
static void access_setup __P((int first));

/*
 * check access.  return 1 if ok, 0 if not ok.
 */

int
access_check(sender, acl, accesstype)
    char *sender;
    Acl *acl;
    Access accesstype;
{
    char buf[MAXPATHLEN];     /* 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;
    sprintf(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.
     */
#if 0
    zdbug ((LOG_DEBUG, "checking %s for %s", buf, sender));
#endif
      
    retval = acl_load(buf);
    if (retval < 0) {
      syslog(LOG_DEBUG, "Error in acl_load of %s for %s", buf, sender);
      return 0;
    }
    return acl_check(buf, sender);
}

static void
check_acl(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, accesstype, typeflag)
    Acl *acl;
    Access accesstype;
    int typeflag;
{
    char    buf[MAXPATHLEN]; /* 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;
    }
    sprintf(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(first)
    int first;
{
    char buf[MAXPATHLEN];
    char class_name[512];     /* assume class names <= 511 bytes */
    FILE *registry;
    Acl *acl;
    int len;
    char *colon_idx;
    Code_t retval = 0;

    sprintf(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()
{
    access_setup(1);
}

void
access_reinit()
{
    acl_cache_reset();
    access_setup(0);
}

Generated by  Doxygen 1.6.0   Back to index