From 7b65d46b1baa8ceead8c580988be74c1caef7a4b Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Tue, 20 Apr 2004 00:08:44 +0000 Subject: [PATCH] add slapacl tool --- servers/slapd/Makefile.in | 6 +- servers/slapd/acl.c | 31 +++++++- servers/slapd/main.c | 3 +- servers/slapd/proto-slap.h | 6 +- servers/slapd/slapacl.c | 143 +++++++++++++++++++++++++++++++++++++ servers/slapd/slapauth.c | 24 +++---- servers/slapd/slapcommon.c | 22 ++++++ servers/slapd/slapcommon.h | 5 ++ 8 files changed, 220 insertions(+), 20 deletions(-) create mode 100644 servers/slapd/slapacl.c diff --git a/servers/slapd/Makefile.in b/servers/slapd/Makefile.in index a10736a6c3..57fee8be3f 100644 --- a/servers/slapd/Makefile.in +++ b/servers/slapd/Makefile.in @@ -13,7 +13,7 @@ ## top-level directory of the distribution or, alternatively, at ## . -SLAPTOOLS=slapadd slapcat slapdn slapindex slappasswd slaptest slapauth +SLAPTOOLS=slapadd slapcat slapdn slapindex slappasswd slaptest slapauth slapacl PROGRAMS=slapd $(SLAPTOOLS) XPROGRAMS=sslapd libbackends.a .backend liboverlays.a XSRCS=version.c @@ -37,7 +37,7 @@ SRCS = main.c globals.c config.c daemon.c \ backglue.c operational.c matchedValues.c cancel.c syncrepl.c \ backover.c ctxcsn.c ldapsync.c sessionlog.c \ slapadd.c slapcat.c slapcommon.c slapdn.c slapindex.c \ - slappasswd.c slaptest.c slapauth.c \ + slappasswd.c slaptest.c slapauth.c slapacl.c \ $(@PLAT@_SRCS) OBJS = main.o globals.o config.o daemon.o \ @@ -54,7 +54,7 @@ OBJS = main.o globals.o config.o daemon.o \ backglue.o operational.o matchedValues.o cancel.o syncrepl.o \ backover.o ctxcsn.o ldapsync.o sessionlog.o \ slapadd.o slapcat.o slapcommon.o slapdn.o slapindex.o \ - slappasswd.o slaptest.o slapauth.o \ + slappasswd.o slaptest.o slapauth.o slapacl.o \ $(@PLAT@_OBJS) LDAP_INCDIR= ../../include -I$(srcdir)/slapi diff --git a/servers/slapd/acl.c b/servers/slapd/acl.c index c337b8fe78..b001785eb8 100644 --- a/servers/slapd/acl.c +++ b/servers/slapd/acl.c @@ -135,13 +135,14 @@ static int aci_match_set ( struct berval *subj, Operation *op, */ int -access_allowed( +access_allowed_mask( Operation *op, Entry *e, AttributeDescription *desc, struct berval *val, slap_access_t access, - AccessControlState *state ) + AccessControlState *state, + slap_mask_t *maskp ) { int ret = 1; int count; @@ -162,6 +163,7 @@ access_allowed( assert( e != NULL ); assert( desc != NULL ); assert( access > ACL_NONE ); + if ( maskp ) ACL_INVALIDATE( *maskp ); attr = desc->ad_cname.bv_val; @@ -238,6 +240,10 @@ access_allowed( "<= root access granted\n", 0, 0, 0 ); #endif + if ( maskp ) { + mask = ACL_LVL_WRITE; + } + goto done; } @@ -278,6 +284,16 @@ access_allowed( op->o_dn.bv_val ? op->o_dn.bv_val : "(anonymous)" ); #endif ret = be->be_dfltaccess >= access; + + if ( maskp ) { + int i; + + mask = ACL_PRIV_LEVEL; + for ( i = ACL_NONE; i <= be->be_dfltaccess; i++ ) { + mask |= ACL_ACCESS2PRIV( i ); + } + } + goto done; #ifdef notdef @@ -297,6 +313,16 @@ access_allowed( global_default_access >= access ? "granted" : "denied", op->o_dn.bv_val ); #endif ret = global_default_access >= access; + + if ( maskp ) { + int i; + + mask = ACL_PRIV_LEVEL; + for ( i = ACL_NONE; i <= global_default_access; i++ ) { + mask |= ACL_ACCESS2PRIV( i ); + } + } + goto done; #endif } @@ -420,6 +446,7 @@ done: state->as_recorded |= ACL_STATE_RECORDED; } if (be_null) op->o_bd = NULL; + if ( maskp ) *maskp = mask; return ret; } diff --git a/servers/slapd/main.c b/servers/slapd/main.c index 91887448df..97ca93576e 100644 --- a/servers/slapd/main.c +++ b/servers/slapd/main.c @@ -66,7 +66,7 @@ static struct sockaddr_in bind_addr; typedef int (MainFunc) LDAP_P(( int argc, char *argv[] )); extern MainFunc slapadd, slapcat, slapdn, slapindex, slappasswd, - slaptest, slapauth; + slaptest, slapauth, slapacl; static struct { char *name; @@ -79,6 +79,7 @@ static struct { {"slappasswd", slappasswd}, {"slaptest", slaptest}, {"slapauth", slapauth}, + {"slapacl", slapacl}, /* NOTE: new tools must be added in chronological order, * not in alphabetical order, because for backwards * compatibility name[4] is used to identify the diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index b7c77caaff..0038438d62 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -34,11 +34,13 @@ LDAP_BEGIN_DECL /* * acl.c */ -LDAP_SLAPD_F (int) access_allowed LDAP_P(( +LDAP_SLAPD_F (int) access_allowed_mask LDAP_P(( Operation *op, Entry *e, AttributeDescription *desc, struct berval *val, slap_access_t access, - AccessControlState *state )); + AccessControlState *state, + slap_mask_t *mask )); +#define access_allowed(op,e,desc,val,access,state) access_allowed_mask(op,e,desc,val,access,state,NULL) LDAP_SLAPD_F (int) acl_check_modlist LDAP_P(( Operation *op, Entry *e, Modifications *ml )); diff --git a/servers/slapd/slapacl.c b/servers/slapd/slapacl.c new file mode 100644 index 0000000000..6caf938af5 --- /dev/null +++ b/servers/slapd/slapacl.c @@ -0,0 +1,143 @@ +/* This work is part of OpenLDAP Software . + * + * Copyright 2004 The OpenLDAP Foundation. + * Portions Copyright 2004 Pierangelo Masarati. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . + */ +/* ACKNOWLEDGEMENTS: + * This work was initially developed by Pierangelo Masarati for inclusion + * in OpenLDAP Software. + */ + +#include "portable.h" + +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "slapcommon.h" + +int +slapacl( int argc, char **argv ) +{ + int rc = EXIT_SUCCESS; + const char *progname = "slapacl"; + Connection conn; + Operation op; + Entry e = { 0 }; + +#ifdef NEW_LOGGING + lutil_log_initialize( argc, argv ); +#endif + slap_tool_init( progname, SLAPACL, argc, argv ); + + argv = &argv[ optind ]; + argc -= optind; + + memset( &conn, 0, sizeof( Connection ) ); + memset( &op, 0, sizeof( Operation ) ); + + connection_fake_init( &conn, &op, &conn ); + + assert( be != NULL ); + + if ( !BER_BVISNULL( &authcID ) ) { + rc = slap_sasl_getdn( &conn, &op, &authcID, NULL, &authcDN, SLAP_GETDN_AUTHCID ); + if ( rc != LDAP_SUCCESS ) { + fprintf( stderr, "ID: <%s> check failed %d (%s)\n", + authcID.bv_val, rc, + ldap_err2string( rc ) ); + rc = 1; + goto destroy; + } + } + + if ( !BER_BVISNULL( &authcDN ) ) { + fprintf( stderr, "DN: \"%s\"\n", authcDN.bv_val ); + } + + assert( !BER_BVISNULL( &baseDN ) ); + rc = dnPrettyNormal( NULL, &baseDN, &e.e_name, &e.e_nname, NULL ); + if ( rc != LDAP_SUCCESS ) { + fprintf( stderr, "base=\"%s\" normalization failed %d (%s)\n", + baseDN.bv_val, rc, + ldap_err2string( rc ) ); + rc = 1; + goto destroy; + } + + op.o_bd = be; + if ( !BER_BVISNULL( &authcDN ) ) { + op.o_dn = authcDN; + op.o_ndn = authcDN; + } + + for ( ; argc--; argv++ ) { + slap_mask_t mask; + AttributeDescription *desc = NULL; + int rc; + struct berval val; + const char *text; + char accessmaskbuf[ACCESSMASK_MAXLEN]; + char *accessstr; + slap_access_t access = ACL_AUTH; + + val.bv_val = strchr( argv[0], ':' ); + if ( val.bv_val != NULL ) { + val.bv_val[0] = '\0'; + val.bv_val++; + val.bv_len = strlen( val.bv_val ); + } + + accessstr = strchr( argv[0], '/' ); + if ( accessstr != NULL ) { + accessstr[0] = '\0'; + accessstr++; + access = str2access( accessstr ); + if ( access == ACL_INVALID_ACCESS ) { + fprintf( stderr, "unknown access \"%s\" for attribute \"%s\"\n", + accessstr, argv[0] ); + continue; + } + } + + rc = slap_str2ad( argv[0], &desc, &text ); + if ( rc != LDAP_SUCCESS ) { + fprintf( stderr, "slap_str2ad(%s) failed %d (%s)\n", + argv[0], rc, ldap_err2string( rc ) ); + continue; + } + + rc = access_allowed_mask( &op, &e, desc, &val, access, + NULL, &mask ); + + fprintf( stderr, "%s%s%s: %s\n", + desc->ad_cname.bv_val, + val.bv_val ? "=" : "", + val.bv_val ? val.bv_val : "", + accessmask2str( mask, accessmaskbuf ) ); + } + +destroy:; + slap_tool_destroy(); + + return rc; +} + diff --git a/servers/slapd/slapauth.c b/servers/slapd/slapauth.c index 8e998c5b0f..a01933b4b5 100644 --- a/servers/slapd/slapauth.c +++ b/servers/slapd/slapauth.c @@ -37,10 +37,10 @@ static int do_check( Connection *c, Operation *op, struct berval *id ) { - struct berval authcDN; + struct berval authcdn; int rc; - rc = slap_sasl_getdn( c, op, id, NULL, &authcDN, SLAP_GETDN_AUTHCID ); + rc = slap_sasl_getdn( c, op, id, NULL, &authcdn, SLAP_GETDN_AUTHCID ); if ( rc != LDAP_SUCCESS ) { fprintf( stderr, "ID: <%s> check failed %d (%s)\n", id->bv_val, rc, @@ -49,7 +49,7 @@ do_check( Connection *c, Operation *op, struct berval *id ) } else { if ( !BER_BVISNULL( &authzID ) ) { - rc = slap_sasl_authorized( op, &authcDN, &authzID ); + rc = slap_sasl_authorized( op, &authcdn, &authzID ); fprintf( stderr, "ID: <%s>\n" @@ -57,7 +57,7 @@ do_check( Connection *c, Operation *op, struct berval *id ) "authzDN: <%s>\n" "authorization %s\n", id->bv_val, - authcDN.bv_val, + authcdn.bv_val, authzID.bv_val, rc == LDAP_SUCCESS ? "OK" : "failed" ); @@ -65,8 +65,8 @@ do_check( Connection *c, Operation *op, struct berval *id ) fprintf( stderr, "ID: <%s> check succeeded\n" "authcID: <%s>\n", id->bv_val, - authcDN.bv_val ); - op->o_tmpfree( authcDN.bv_val, op->o_tmpmemctx ); + authcdn.bv_val ); + op->o_tmpfree( authcdn.bv_val, op->o_tmpmemctx ); } rc = 0; } @@ -96,9 +96,9 @@ slapauth( int argc, char **argv ) connection_fake_init( &conn, &op, &conn ); if ( !BER_BVISNULL( &authzID ) ) { - struct berval authzDN; + struct berval authzdn; - rc = slap_sasl_getdn( &conn, &op, &authzID, NULL, &authzDN, + rc = slap_sasl_getdn( &conn, &op, &authzID, NULL, &authzdn, SLAP_GETDN_AUTHZID ); if ( rc != LDAP_SUCCESS ) { fprintf( stderr, "authzID: <%s> check failed %d (%s)\n", @@ -109,7 +109,7 @@ slapauth( int argc, char **argv ) goto destroy; } - authzID = authzDN; + authzID = authzdn; } @@ -120,11 +120,11 @@ slapauth( int argc, char **argv ) } for ( ; argc--; argv++ ) { - struct berval authzDN; + struct berval authzdn; ber_str2bv( argv[ 0 ], 0, 0, &authzID ); - rc = slap_sasl_getdn( &conn, &op, &authzID, NULL, &authzDN, + rc = slap_sasl_getdn( &conn, &op, &authzID, NULL, &authzdn, SLAP_GETDN_AUTHZID ); if ( rc != LDAP_SUCCESS ) { fprintf( stderr, "authzID: <%s> check failed %d (%s)\n", @@ -135,7 +135,7 @@ slapauth( int argc, char **argv ) goto destroy; } - authzID = authzDN; + authzID = authzdn; rc = do_check( &conn, &op, &authcID ); diff --git a/servers/slapd/slapcommon.c b/servers/slapd/slapcommon.c index 857d422848..f3c73d93a7 100644 --- a/servers/slapd/slapcommon.c +++ b/servers/slapd/slapcommon.c @@ -73,6 +73,10 @@ usage( int tool, const char *progname ) case SLAPAUTH: options = "\t[-U authcID] [-X authzID] ID [...]\n"; break; + + case SLAPACL: + options = "\t[-U authcID | -D authcDN] -b DN attr[/level][:value] [...]\n"; + break; } if ( options != NULL ) { @@ -138,6 +142,10 @@ slap_tool_init( mode |= SLAP_TOOL_READMAIN; break; + case SLAPACL: + options = "b:D:d:f:U:v"; + break; + default: fprintf( stderr, "%s: unknown tool mode (%d)\n", progname, tool ); @@ -159,6 +167,10 @@ slap_tool_init( ldap_debug += atoi( optarg ); break; + case 'D': + ber_str2bv( optarg, 0, 0, &authcDN ); + break; + case 'f': /* specify a conf file */ conffile = strdup( optarg ); break; @@ -284,6 +296,16 @@ slap_tool_init( } break; + case SLAPACL: + if ( !BER_BVISNULL( &authcDN ) && !BER_BVISNULL( &authcID ) ) { + usage( tool, progname ); + } + if ( BER_BVISNULL( &base ) ) { + usage( tool, progname ); + } + ber_dupbv( &baseDN, &base ); + break; + default: break; } diff --git a/servers/slapd/slapcommon.h b/servers/slapd/slapcommon.h index ff29921cd1..41fca6f4fb 100644 --- a/servers/slapd/slapcommon.h +++ b/servers/slapd/slapcommon.h @@ -28,6 +28,7 @@ enum slaptool { SLAPPASSWD, /* password generation tool */ SLAPTEST, /* slapd.conf test tool */ SLAPAUTH, /* test authz-regexp and authc/authz stuff */ + SLAPACL, /* test acl */ SLAPLAST }; @@ -51,6 +52,8 @@ typedef struct tool_vars { int tv_dryrun; struct berval tv_sub_ndn; FILE *tv_ldiffp; + struct berval tv_authcDN; + struct berval tv_baseDN; struct berval tv_authcID; struct berval tv_authzID; } tool_vars; @@ -72,6 +75,8 @@ extern tool_vars tool_globals; #define dryrun tool_globals.tv_dryrun #define sub_ndn tool_globals.tv_sub_ndn #define ldiffp tool_globals.tv_ldiffp +#define authcDN tool_globals.tv_authcDN +#define baseDN tool_globals.tv_baseDN #define authcID tool_globals.tv_authcID #define authzID tool_globals.tv_authzID -- 2.39.5