summaryrefslogtreecommitdiffstats
path: root/crypto/heimdal/lib/kadm5/acl.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/heimdal/lib/kadm5/acl.c')
-rw-r--r--crypto/heimdal/lib/kadm5/acl.c139
1 files changed, 108 insertions, 31 deletions
diff --git a/crypto/heimdal/lib/kadm5/acl.c b/crypto/heimdal/lib/kadm5/acl.c
index 3f42c60..c963171 100644
--- a/crypto/heimdal/lib/kadm5/acl.c
+++ b/crypto/heimdal/lib/kadm5/acl.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 1999 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -33,7 +33,7 @@
#include "kadm5_locl.h"
-RCSID("$Id: acl.c,v 1.10 1999/12/02 17:05:05 joda Exp $");
+RCSID("$Id: acl.c,v 1.12 2000/08/10 19:24:08 assar Exp $");
static struct units acl_units[] = {
{ "all", KADM5_PRIV_ALL },
@@ -68,58 +68,112 @@ _kadm5_privs_to_string(u_int32_t privs, char *string, size_t len)
return 0;
}
-kadm5_ret_t
-_kadm5_acl_init(kadm5_server_context *context)
+/*
+ * retrieve the right for the current caller on `princ' (NULL means all)
+ * and store them in `ret_flags'
+ * return 0 or an error.
+ */
+
+static kadm5_ret_t
+fetch_acl (kadm5_server_context *context,
+ krb5_const_principal princ,
+ unsigned *ret_flags)
{
- FILE *f;
- char buf[128];
- krb5_principal princ;
- int flags;
- krb5_error_code ret;
-
- krb5_parse_name(context->context, KADM5_ADMIN_SERVICE, &princ);
- ret = krb5_principal_compare(context->context, context->caller, princ);
- krb5_free_principal(context->context, princ);
- if(ret != 0){
- context->acl_flags = KADM5_PRIV_ALL;
- return 0;
- }
+ unsigned flags = -1;
+ FILE *f = fopen(context->config.acl_file, "r");
+ krb5_error_code ret = 0;
+
+ if(f != NULL) {
+ char buf[256];
- flags = -1;
- f = fopen(context->config.acl_file, "r");
- if(f){
- while(fgets(buf, sizeof(buf), f)){
+ while(fgets(buf, sizeof(buf), f) != NULL){
char *foo = NULL, *p;
+ krb5_principal this_princ;
+
+ flags = -1;
p = strtok_r(buf, " \t\n", &foo);
if(p == NULL)
continue;
- ret = krb5_parse_name(context->context, p, &princ);
+ ret = krb5_parse_name(context->context, p, &this_princ);
if(ret)
continue;
if(!krb5_principal_compare(context->context,
- context->caller, princ)){
- krb5_free_principal(context->context, princ);
+ context->caller, this_princ)) {
+ krb5_free_principal(context->context, this_princ);
continue;
}
- krb5_free_principal(context->context, princ);
- p = strtok_r(NULL, "\n", &foo);
+ krb5_free_principal(context->context, this_princ);
+ p = strtok_r(NULL, " \t\n", &foo);
if(p == NULL)
continue;
ret = _kadm5_string_to_privs(p, &flags);
- break;
+ if (ret)
+ break;
+ p = strtok_r(NULL, "\n", &foo);
+ if (p == NULL) {
+ ret = 0;
+ break;
+ }
+ if (princ != NULL) {
+ krb5_principal pattern_princ;
+ krb5_boolean tmp;
+
+ ret = krb5_parse_name (context->context, p, &pattern_princ);
+ if (ret)
+ break;
+ tmp = krb5_principal_match (context->context,
+ princ, pattern_princ);
+ krb5_free_principal (context->context, pattern_princ);
+ if (tmp) {
+ ret = 0;
+ break;
+ }
+ }
}
fclose(f);
}
if(flags == -1)
flags = 0;
- context->acl_flags = flags;
- return 0;
+ if (ret == 0)
+ *ret_flags = flags;
+ return ret;
}
+/*
+ * set global acl flags in `context' for the current caller.
+ * return 0 on success or an error
+ */
+
kadm5_ret_t
-_kadm5_acl_check_permission(kadm5_server_context *context, unsigned op)
+_kadm5_acl_init(kadm5_server_context *context)
{
- unsigned res = ~context->acl_flags & op;
+ krb5_principal princ;
+ krb5_error_code ret;
+
+ ret = krb5_parse_name(context->context, KADM5_ADMIN_SERVICE, &princ);
+ if (ret)
+ return ret;
+ ret = krb5_principal_compare(context->context, context->caller, princ);
+ krb5_free_principal(context->context, princ);
+ if(ret != 0) {
+ context->acl_flags = KADM5_PRIV_ALL;
+ return 0;
+ }
+
+ return fetch_acl (context, NULL, &context->acl_flags);
+}
+
+/*
+ * check if `flags' allows `op'
+ * return 0 if OK or an error
+ */
+
+static kadm5_ret_t
+check_flags (unsigned op,
+ unsigned flags)
+{
+ unsigned res = ~flags & op;
+
if(res & KADM5_PRIV_GET)
return KADM5_AUTH_GET;
if(res & KADM5_PRIV_ADD)
@@ -136,3 +190,26 @@ _kadm5_acl_check_permission(kadm5_server_context *context, unsigned op)
return KADM5_AUTH_INSUFFICIENT;
return 0;
}
+
+/*
+ * return 0 if the current caller in `context' is allowed to perform
+ * `op' on `princ' and otherwise an error
+ * princ == NULL if it's not relevant.
+ */
+
+kadm5_ret_t
+_kadm5_acl_check_permission(kadm5_server_context *context,
+ unsigned op,
+ krb5_const_principal princ)
+{
+ kadm5_ret_t ret;
+ unsigned princ_flags;
+
+ ret = check_flags (op, context->acl_flags);
+ if (ret == 0)
+ return ret;
+ ret = fetch_acl (context, princ, &princ_flags);
+ if (ret)
+ return ret;
+ return check_flags (op, princ_flags);
+}
OpenPOWER on IntegriCloud