]> asedeno.scripts.mit.edu Git - 1ts-debian.git/blobdiff - zephyr/server/access.c
Initial revision
[1ts-debian.git] / zephyr / server / access.c
diff --git a/zephyr/server/access.c b/zephyr/server/access.c
new file mode 100644 (file)
index 0000000..d9e3d81
--- /dev/null
@@ -0,0 +1,234 @@
+/* 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);
+}