]> git.sur5r.net Git - openldap/commitdiff
add slapsaslauth test tool
authorPierangelo Masarati <ando@openldap.org>
Tue, 13 Apr 2004 17:18:03 +0000 (17:18 +0000)
committerPierangelo Masarati <ando@openldap.org>
Tue, 13 Apr 2004 17:18:03 +0000 (17:18 +0000)
doc/man/man8/slapsaslauth.8 [new file with mode: 0644]
servers/slapd/main.c
servers/slapd/slapcommon.c
servers/slapd/slapcommon.h
servers/slapd/slapdn.c
servers/slapd/slapsaslauth.c [new file with mode: 0644]

diff --git a/doc/man/man8/slapsaslauth.8 b/doc/man/man8/slapsaslauth.8
new file mode 100644 (file)
index 0000000..5450746
--- /dev/null
@@ -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.  
index 528867ba00163986dcce9300541caad4fc7f4a73..d5cff55b1223986df9360e7ee6cb01e683483274 100644 (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}
 };
 
index a04be91af650278b5f438c420c7086b36abf9e00..a3cbc72507488d11218112de09addf1528e8e972 100644 (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
index 12a1b57ffd3e88e631216da0e0179495d2a3f577..3722fb603d63ebbc990f9050db57027e7c3bb3e5 100644 (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,
index 3db6e0be1f42358665aa112461ff05d5747e21eb..7eb4b823cd3cc05b1991363b412e348343ffd9d0 100644 (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 );
diff --git a/servers/slapd/slapsaslauth.c b/servers/slapd/slapsaslauth.c
new file mode 100644 (file)
index 0000000..baa9236
--- /dev/null
@@ -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;
+}
+