add slapsaslauth test tool

This commit is contained in:
Pierangelo Masarati 2004-04-13 17:18:03 +00:00
parent 629cd41f58
commit 3ea4368913
6 changed files with 316 additions and 9 deletions

103
doc/man/man8/slapsaslauth.8 Normal file
View File

@ -0,0 +1,103 @@
.TH SLAPSASLAUTH 8C "RELEASEDATE" "OpenLDAP LDVERSION"
.\" Copyright 2004 The OpenLDAP Foundation All Rights Reserved.
.\" Copying restrictions apply. See COPYRIGHT/LICENSE.
.SH NAME
slapsaslauth \- Check a list of string-represented IDs for authc/authz.
.SH SYNOPSIS
.B SBINDIR/slapsaslauth
.B [\-v]
.B [\-d level]
.B [\-f slapd.conf]
.B [\-U authcID]
.B [\-X authzID]
.B ID [...]
.LP
.SH DESCRIPTION
.LP
.B Slapsaslauth
is used to check the behavior of the slapd in mapping identities
for authentication and authorization purposes, as specified in
.BR slapd.conf (5).
It opens the
.BR slapd.conf (5)
configuration file, reads in the
.B sasl-authz-policy
and
.B sasl-regexp
directives, and then parses the
.B ID
list given on the command-line.
.LP
.SH OPTIONS
.TP
.B \-v
enable verbose mode.
.TP
.BI \-d " level"
enable debugging messages as defined by the specified
.IR level .
.TP
.BI \-f " slapd.conf"
specify an alternative
.BR slapd.conf (5)
file.
.TP
.BI \-U " authcID"
specify an ID to be used as
.I authcID
throughout the test session.
If present, and if no
.B authzID
is given, the IDs in the ID list are treated as
.BR authzID .
.TP
.BI \-X " authzID"
specify an ID to be used as
.I authzID
throughout the test session.
If present, and if no
.B authcID
is given, the IDs in the ID list are treated as
.BR authcID .
If both
.I authcID
and
.I authzID
are given via command line switch, the ID list cannot be present.
.SH EXAMPLES
The command
.LP
.nf
.ft tt
SBINDIR/slapsaslauth -f /ETCDIR/slapd.conf -v \\
-U bjorn -X u:bjensen
.ft
.fi
tests whether the user
.I bjorn
can assume the identity of the user
.I bjensen
provided the directives
.LP
.nf
.ft tt
sasl-authz-policy from
sasl-regexp "^uid=([^,]+).*,cn=auth$"
"ldap:///o=University of Michigan,c=US??sub?uid=$1"
.ft
.fi
are defined in
.BR slapd.conf (5).
.SH "SEE ALSO"
.BR ldap (3),
.BR slapd (8)
.BR slaptest (8)
.LP
"OpenLDAP Administrator's Guide" (http://www.OpenLDAP.org/doc/admin/)
.SH ACKNOWLEDGEMENTS
.B OpenLDAP
is developed and maintained by The OpenLDAP Project (http://www.openldap.org/).
.B OpenLDAP
is derived from University of Michigan LDAP 3.3 Release.

View File

@ -65,7 +65,7 @@ static struct sockaddr_in bind_addr;
#endif
typedef int (MainFunc) LDAP_P(( int argc, char *argv[] ));
extern MainFunc slapadd, slapcat, slapdn, slapindex, slappasswd, slaptest;
extern MainFunc slapadd, slapcat, slapdn, slapindex, slappasswd, slaptest, slapsaslauth;
static struct {
char *name;
@ -77,6 +77,7 @@ static struct {
{"slapindex", slapindex},
{"slappasswd", slappasswd},
{"slaptest", slaptest},
{"slapsaslauth", slapsaslauth},
{NULL, NULL}
};

View File

@ -69,6 +69,10 @@ usage( int tool, const char *progname )
case SLAPINDEX:
options = "\t[-n databasenumber | -b suffix]\n";
break;
case SLAPSASLAUTH:
options = "\t[-U authcID] [-X authzID] ID [...]\n";
break;
}
if ( options != NULL ) {
@ -102,7 +106,7 @@ slap_tool_init(
int truncatemode = 0;
#ifdef CSRIMALLOC
leakfilename = malloc( strlen( progname ) + sizeof(".leak") );
leakfilename = malloc( strlen( progname ) + STRLEOF( ".leak" ) - 1 );
sprintf( leakfilename, "%s.leak", progname );
if( ( leakfile = fopen( leakfilename, "w" )) == NULL ) {
leakfile = stderr;
@ -125,6 +129,10 @@ slap_tool_init(
options = "d:f:v";
break;
case SLAPSASLAUTH:
options = "d:f:U:vX:";
break;
case SLAPINDEX:
options = "b:cd:f:n:v";
mode |= SLAP_TOOL_READMAIN;
@ -140,8 +148,7 @@ slap_tool_init(
while ( (i = getopt( argc, argv, options )) != EOF ) {
switch ( i ) {
case 'b':
base.bv_val = strdup( optarg );
base.bv_len = strlen( base.bv_val );
ber_str2bv( optarg, 0, 1, &base );
break;
case 'c': /* enable continue mode */
@ -210,6 +217,10 @@ slap_tool_init(
mode |= SLAP_TRUNCATE_MODE;
break;
case 'U':
ber_str2bv( optarg, 0, 0, &authcID );
break;
case 'u': /* dry run */
dryrun++;
break;
@ -227,6 +238,10 @@ slap_tool_init(
update_ctxcsn = SLAP_TOOL_CTXCSN_BATCH;
break;
case 'X':
ber_str2bv( optarg, 0, 0, &authzID );
break;
default:
usage( tool, progname );
break;
@ -257,6 +272,12 @@ slap_tool_init(
}
break;
case SLAPSASLAUTH:
if ( argc == optind && BER_BVISNULL( &authcID ) ) {
usage( tool, progname );
}
break;
case SLAPTEST:
if ( argc != optind ) {
usage( tool, progname );
@ -350,21 +371,24 @@ slap_tool_init(
case SLAPTEST:
return;
case SLAPSASLAUTH:
be = NULL;
goto startup;
default:
break;
}
if( subtree ) {
struct berval val;
val.bv_val = subtree;
val.bv_len = strlen( subtree );
ber_str2bv( subtree, 0, 0, &val );
rc = dnNormalize( 0, NULL, NULL, &val, &sub_ndn, NULL );
if( rc != LDAP_SUCCESS ) {
fprintf( stderr, "Invalid subtree DN '%s'\n", optarg );
exit( EXIT_FAILURE );
}
if( base.bv_val == NULL && dbnum == -1 )
if ( BER_BVISNULL( &base ) && dbnum == -1 )
base = val;
else
free( subtree );
@ -444,6 +468,8 @@ slap_tool_init(
be = &backends[dbnum];
}
startup:;
#ifdef CSRIMALLOC
mal_leaktrace(1);
#endif

View File

@ -27,6 +27,7 @@ enum slaptool {
SLAPINDEX, /* database index tool */
SLAPPASSWD, /* password generation tool */
SLAPTEST, /* slapd.conf test tool */
SLAPSASLAUTH, /* test sasl-regexp and authc/authz stuff */
SLAPLAST
};
@ -50,6 +51,8 @@ typedef struct tool_vars {
int tv_dryrun;
struct berval tv_sub_ndn;
FILE *tv_ldiffp;
struct berval tv_authcID;
struct berval tv_authzID;
} tool_vars;
extern tool_vars tool_globals;
@ -69,6 +72,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 authcID tool_globals.tv_authcID
#define authzID tool_globals.tv_authzID
void slap_tool_init LDAP_P((
const char* name,

View File

@ -51,8 +51,7 @@ slapdn( int argc, char **argv )
for ( ; argc--; argv++ ) {
struct berval dn, pdn, ndn;
dn.bv_val = argv[ 0 ];
dn.bv_len = strlen( argv[ 0 ] );
ber_str2bv( argv[ 0 ], 0, 0, &dn );
rc = dnPrettyNormal( NULL, &dn,
&pdn, &ndn, NULL );

View File

@ -0,0 +1,173 @@
/* 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"
static int
do_check( Connection *c, Operation *op, struct berval *id )
{
struct berval authcDN;
int rc;
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,
ldap_err2string( rc ) );
rc = 1;
} else {
if ( !BER_BVISNULL( &authzID ) ) {
rc = slap_sasl_authorized( op, &authcDN, &authzID );
fprintf( stderr,
"ID: <%s>\n"
"authcDN: <%s>\n"
"authzDN: <%s>\n"
"authorization %s\n",
id->bv_val,
authcDN.bv_val,
authzID.bv_val,
rc == LDAP_SUCCESS ? "OK" : "failed" );
} else {
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 );
}
rc = 0;
}
return rc;
}
int
slapsaslauth( int argc, char **argv )
{
int rc = EXIT_SUCCESS;
const char *progname = "slapsaslauth";
Connection conn;
Operation op;
#ifdef NEW_LOGGING
lutil_log_initialize( argc, argv );
#endif
slap_tool_init( progname, SLAPSASLAUTH, argc, argv );
argv = &argv[ optind ];
argc -= optind;
memset( &conn, 0, sizeof( Connection ) );
memset( &op, 0, sizeof( Operation ) );
connection_fake_init( &conn, &op, &conn );
if ( !BER_BVISNULL( &authzID ) ) {
struct berval 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",
authzID.bv_val, rc,
ldap_err2string( rc ) );
rc = 1;
BER_BVZERO( &authzID );
goto destroy;
}
authzID = authzDN;
}
if ( !BER_BVISNULL( &authcID ) ) {
if ( !BER_BVISNULL( &authzID ) || argc == 0 ) {
rc = do_check( &conn, &op, &authcID );
goto destroy;
}
for ( ; argc--; argv++ ) {
struct berval authzDN;
ber_str2bv( argv[ 0 ], 0, 0, &authzID );
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",
authzID.bv_val, rc,
ldap_err2string( rc ) );
rc = 1;
BER_BVZERO( &authzID );
goto destroy;
}
authzID = authzDN;
rc = do_check( &conn, &op, &authcID );
op.o_tmpfree( authzID.bv_val, op.o_tmpmemctx );
BER_BVZERO( &authzID );
if ( rc ) {
goto destroy;
}
}
goto destroy;
}
for ( ; argc--; argv++ ) {
struct berval id;
ber_str2bv( argv[ 0 ], 0, 0, &id );
rc = do_check( &conn, &op, &id );
if ( rc ) {
goto destroy;
}
}
destroy:;
if ( !BER_BVISNULL( &authzID ) ) {
op.o_tmpfree( authzID.bv_val, op.o_tmpmemctx );
}
slap_tool_destroy();
return rc;
}