## top-level directory of the distribution or, alternatively, at
## <http://www.OpenLDAP.org/license.html>.
-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
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 \
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
*/
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;
assert( e != NULL );
assert( desc != NULL );
assert( access > ACL_NONE );
+ if ( maskp ) ACL_INVALIDATE( *maskp );
attr = desc->ad_cname.bv_val;
"<= root access granted\n",
0, 0, 0 );
#endif
+ if ( maskp ) {
+ mask = ACL_LVL_WRITE;
+ }
+
goto done;
}
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
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
}
state->as_recorded |= ACL_STATE_RECORDED;
}
if (be_null) op->o_bd = NULL;
+ if ( maskp ) *maskp = mask;
return ret;
}
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;
{"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
/*
* 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 ));
--- /dev/null
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * 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
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+/* ACKNOWLEDGEMENTS:
+ * This work was initially developed by Pierangelo Masarati for inclusion
+ * in OpenLDAP Software.
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+
+#include <ac/stdlib.h>
+
+#include <ac/ctype.h>
+#include <ac/string.h>
+#include <ac/socket.h>
+#include <ac/unistd.h>
+
+#include <lber.h>
+#include <ldif.h>
+#include <lutil.h>
+
+#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;
+}
+
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,
} else {
if ( !BER_BVISNULL( &authzID ) ) {
- rc = slap_sasl_authorized( op, &authcDN, &authzID );
+ rc = slap_sasl_authorized( op, &authcdn, &authzID );
fprintf( stderr,
"ID: <%s>\n"
"authzDN: <%s>\n"
"authorization %s\n",
id->bv_val,
- authcDN.bv_val,
+ authcdn.bv_val,
authzID.bv_val,
rc == LDAP_SUCCESS ? "OK" : "failed" );
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;
}
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",
goto destroy;
}
- authzID = authzDN;
+ authzID = authzdn;
}
}
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",
goto destroy;
}
- authzID = authzDN;
+ authzID = authzdn;
rc = do_check( &conn, &op, &authcID );
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 ) {
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 );
ldap_debug += atoi( optarg );
break;
+ case 'D':
+ ber_str2bv( optarg, 0, 0, &authcDN );
+ break;
+
case 'f': /* specify a conf file */
conffile = strdup( optarg );
break;
}
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;
}
SLAPPASSWD, /* password generation tool */
SLAPTEST, /* slapd.conf test tool */
SLAPAUTH, /* test authz-regexp and authc/authz stuff */
+ SLAPACL, /* test acl */
SLAPLAST
};
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;
#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