]> git.sur5r.net Git - openldap/commitdiff
First-cut proxy authorization support.
authorKurt Zeilenga <kurt@openldap.org>
Tue, 3 Dec 2002 06:11:32 +0000 (06:11 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Tue, 3 Dec 2002 06:11:32 +0000 (06:11 +0000)
19 files changed:
clients/tools/ldapcompare.c
clients/tools/ldapdelete.c
clients/tools/ldapmodify.c
clients/tools/ldapmodrdn.c
clients/tools/ldappasswd.c
clients/tools/ldapsearch.c
clients/tools/ldapwhoami.c
include/ldap.h
libraries/libldap/error.c
servers/slapd/config.c
servers/slapd/controls.c
servers/slapd/extended.c
servers/slapd/proto-slap.h
servers/slapd/result.c
servers/slapd/sasl.c
servers/slapd/saslauthz.c
servers/slapd/slap.h
servers/slapd/tools/mimic.c
tests/scripts/test014-whoami

index 46917ac9f95792e565c49c975d274843ca2a78bc..17040324dc3abaa670e33dc01940088a2890dc75 100644 (file)
@@ -215,7 +215,7 @@ main( int argc, char **argv )
                        }
 
                        assert( authzid == NULL );
-                       authzid = control;
+                       authzid = cvalue;
 
                } else if ( strcasecmp( control, "manageDSAit" ) == 0 ) {
                        if( manageDSAit ) {
index e51c38461f4ab59287b15450864a7c0f6e43b3ea..5095d9d424dba30b6949b0973d0483415d2eb027 100644 (file)
@@ -214,7 +214,7 @@ main( int argc, char **argv )
                        }
 
                        assert( authzid == NULL );
-                       authzid = control;
+                       authzid = cvalue;
 
                } else if ( strcasecmp( control, "manageDSAit" ) == 0 ) {
                        if( manageDSAit ) {
index 00c1899905d26036c785120e3dda02e51e027356..73e9069ebaf2d8c31c8860fb15d240aabecab22a 100644 (file)
@@ -278,7 +278,7 @@ main( int argc, char **argv )
                        }
 
                        assert( authzid == NULL );
-                       authzid = control;
+                       authzid = cvalue;
 
                } else if ( strcasecmp( control, "manageDSAit" ) == 0 ) {
                        if( manageDSAit ) {
index 3d18b92618e849f2a165f1657d7feef64ad5233e..6f09348f73908f30bf8173fd2f41e8381453652a 100644 (file)
@@ -234,7 +234,7 @@ main(int argc, char **argv)
                        }
 
                        assert( authzid == NULL );
-                       authzid = control;
+                       authzid = cvalue;
 
                } else if ( strcasecmp( control, "manageDSAit" ) == 0 ) {
                        if( manageDSAit ) {
index dace530506b646fadcf8ee848cc4a622364ee7d9..a86d6a11365808a4cc82fcc684e014188d8c8e9e 100644 (file)
@@ -234,7 +234,7 @@ main( int argc, char *argv[] )
                        }
 
                        assert( authzid == NULL );
-                       authzid = control;
+                       authzid = cvalue;
 
                } else if ( strcasecmp( control, "manageDSAit" ) == 0 ) {
                        if( manageDSAit ) {
index b26778a268363359e99e9ca8fe28038b4ce52800..d1a0bd471a0e9bd1c1c89dce01c8805a835aa5aa 100644 (file)
@@ -471,7 +471,7 @@ main( int argc, char **argv )
                        }
 
                        assert( authzid == NULL );
-                       authzid = control;
+                       authzid = cvalue;
 
                } else if ( strcasecmp( control, "manageDSAit" ) == 0 ) {
                        if( manageDSAit ) {
index 12dda6f00066f09915d42924aa5a3e85faeed76c..5e2736f9f8ac039ecdec2f032dc88d0c3c65e995 100644 (file)
@@ -190,7 +190,7 @@ main( int argc, char *argv[] )
                        }
 
                        assert( authzid == NULL );
-                       authzid = control;
+                       authzid = cvalue;
 
                } else if ( strcasecmp( control, "manageDSAit" ) == 0 ) {
                        if( manageDSAit ) {
index e8b63f48c42383d04436b09dca36025a918f840b..09019f507cda56186e73a617d437ae655af67ab2 100644 (file)
@@ -413,8 +413,9 @@ typedef struct ldapcontrol {
 #define LDAP_IS_LEAF                   0x23 /* not LDAPv3 */
 #define LDAP_ALIAS_DEREF_PROBLEM       0x24
 
-#define LDAP_SECURITY_ERROR(n) LDAP_RANGE((n),0x30,0x32) /* 48-50 */
+#define LDAP_SECURITY_ERROR(n) LDAP_RANGE((n),0x2F,0x32) /* 47-50 */
 
+#define LDAP_PROXY_AUTHZ_FAILURE       0x2F /* LDAPv3 proxy authorization */
 #define LDAP_INAPPROPRIATE_AUTH                0x30
 #define LDAP_INVALID_CREDENTIALS       0x31
 #define LDAP_INSUFFICIENT_ACCESS       0x32
index 7aa9d4666701341d7585a3e20467c186e77a9751..839d8c3e3e1340e1ec6a9f4258bef748b04e8707 100644 (file)
@@ -53,6 +53,7 @@ static struct ldaperror ldap_builtin_errlist[] = {
        {LDAP_IS_LEAF,                                  "Entry is a leaf" },
        {LDAP_ALIAS_DEREF_PROBLEM,              "Alias dereferencing problem" },
 
+       {LDAP_PROXY_AUTHZ_FAILURE,              "Proxy Authorization Failure" },
        {LDAP_INAPPROPRIATE_AUTH,               "Inappropriate authentication" },
        {LDAP_INVALID_CREDENTIALS,              "Invalid credentials" },
        {LDAP_INSUFFICIENT_ACCESS,              "Insufficient access" },
index f6225eeff22d47a2f308f4940b24baa40e441653..45616ae406ea836326da9f3be0b7982cea3968af 100644 (file)
@@ -561,12 +561,10 @@ read_config( const char *fname, int depth )
 
                        lutil_salt_format( cargv[1] );
 
-#ifdef HAVE_CYRUS_SASL
                /* SASL config options */
                } else if ( strncasecmp( cargv[0], "sasl", 4 ) == 0 ) {
                        if ( slap_sasl_config( cargc, cargv, line, fname, lineno ) )
                                return 1;
-#endif /* HAVE_CYRUS_SASL */
 
                } else if ( strcasecmp( cargv[0], "schemadn" ) == 0 ) {
                        struct berval dn;
index 1021d267d92a126499e7412d74faa26773ba91fa..736b5f8448813b07fe70804153b539e0403d1bc1 100644 (file)
@@ -44,18 +44,27 @@ typedef int (SLAP_CTRL_PARSE_FN) LDAP_P((
        LDAPControl *ctrl,
        const char **text ));
 
+static SLAP_CTRL_PARSE_FN parseProxyAuthz;
 static SLAP_CTRL_PARSE_FN parseManageDSAit;
-static SLAP_CTRL_PARSE_FN parseSubentries;
 static SLAP_CTRL_PARSE_FN parseNoOp;
 static SLAP_CTRL_PARSE_FN parsePagedResults;
 static SLAP_CTRL_PARSE_FN parseValuesReturnFilter;
 
+#ifdef LDAP_CONTROL_SUBENTRIES
+static SLAP_CTRL_PARSE_FN parseSubentries;
+#endif
 #ifdef LDAP_CLIENT_UPDATE
 static SLAP_CTRL_PARSE_FN parseClientUpdate;
-#endif /* LDAP_CLIENT_UPDATE */
+#endif
 
 #undef sc_mask /* avoid conflict with Irix 6.5 <sys/signal.h> */
 
+static char *proxy_authz_extops[] = {
+       LDAP_EXOP_MODIFY_PASSWD,
+       LDAP_EXOP_X_WHO_AM_I,
+       NULL
+};
+
 static struct slap_control {
        char *sc_oid;
        slap_mask_t sc_mask;
@@ -63,14 +72,12 @@ static struct slap_control {
        SLAP_CTRL_PARSE_FN *sc_parse;
 
 } supportedControls[] = {
+       { LDAP_CONTROL_PROXY_AUTHZ,
+               SLAP_CTRL_FRONTEND|SLAP_CTRL_ACCESS, proxy_authz_extops,
+               parseProxyAuthz },
        { LDAP_CONTROL_MANAGEDSAIT,
                SLAP_CTRL_ACCESS, NULL,
                parseManageDSAit },
-#ifdef LDAP_CONTROL_SUBENTRIES
-       { LDAP_CONTROL_SUBENTRIES,
-               SLAP_CTRL_SEARCH, NULL,
-               parseSubentries },
-#endif
        { LDAP_CONTROL_NOOP,
                SLAP_CTRL_ACCESS, NULL,
                parseNoOp },
@@ -79,7 +86,12 @@ static struct slap_control {
                parsePagedResults },
        { LDAP_CONTROL_VALUESRETURNFILTER,
                SLAP_CTRL_SEARCH, NULL,
-               parseValuesReturnFilter },
+               parseValuesReturnFilter },
+#ifdef LDAP_CONTROL_SUBENTRIES
+       { LDAP_CONTROL_SUBENTRIES,
+               SLAP_CTRL_SEARCH, NULL,
+               parseSubentries },
+#endif
 #ifdef LDAP_CLIENT_UPDATE
        { LDAP_CONTROL_CLIENT_UPDATE,
                SLAP_CTRL_SEARCH, NULL,
@@ -316,8 +328,19 @@ int get_ctrls(
                                tagmask = SLAP_CTRL_ABANDON;
                                break;
                        case LDAP_REQ_EXTENDED:
-                               /* FIXME: check list of extended operations */
-                               tagmask = ~0U;
+                               tagmask=~0L;
+                               assert( op->o_extendedop != NULL );
+                               if( sc->sc_extendedops != NULL ) {
+                                       int i;
+                                       for( i=0; sc->sc_extendedops[i] != NULL; i++ ) {
+                                               if( strcmp( op->o_extendedop, sc->sc_extendedops[i] )
+                                                       == 0 )
+                                               {
+                                                       tagmask=0L;
+                                                       break;
+                                               }
+                                       }
+                               }
                                break;
                        default:
                                rc = LDAP_OTHER;
@@ -367,9 +390,11 @@ int get_ctrls(
 return_results:
 #ifdef NEW_LOGGING
        LDAP_LOG( OPERATION, RESULTS, 
-               "get_ctrls: n=%d rc=%d err=%s\n", nctrls, rc, errmsg ? errmsg : "" );
+               "get_ctrls: n=%d rc=%d err=\"%s\"\n",
+               nctrls, rc, errmsg ? errmsg : "" );
 #else
-       Debug( LDAP_DEBUG_TRACE, "<= get_ctrls: n=%d rc=%d err=%s\n",
+       Debug( LDAP_DEBUG_TRACE,
+               "<= get_ctrls: n=%d rc=%d err=\"%s\"\n",
                nctrls, rc, errmsg ? errmsg : "");
 #endif
 
@@ -408,37 +433,101 @@ static int parseManageDSAit (
        return LDAP_SUCCESS;
 }
 
-#ifdef LDAP_CONTROL_SUBENTRIES
-static int parseSubentries (
+static int parseProxyAuthz (
        Connection *conn,
        Operation *op,
        LDAPControl *ctrl,
        const char **text )
 {
-       if ( op->o_subentries != SLAP_NO_CONTROL ) {
-               *text = "subentries control specified multiple times";
-               return LDAP_PROTOCOL_ERROR;
-       }
+       int rc;
+       struct berval dn;
 
-       /* FIXME: should use BER library */
-       if( ( ctrl->ldctl_value.bv_len != 3 )
-               && ( ctrl->ldctl_value.bv_val[0] != 0x01 )
-               && ( ctrl->ldctl_value.bv_val[1] != 0x01 ))
-       {
-               *text = "subentries control value encoding is bogus";
+       if ( op->o_proxy_authz != SLAP_NO_CONTROL ) {
+               *text = "proxy authorization control specified multiple times";
                return LDAP_PROTOCOL_ERROR;
        }
 
-       op->o_subentries = ctrl->ldctl_iscritical
+       op->o_proxy_authz = ctrl->ldctl_iscritical
                ? SLAP_CRITICAL_CONTROL
                : SLAP_NONCRITICAL_CONTROL;
 
-       op->o_subentries_visibility = (ctrl->ldctl_value.bv_val[2] != 0x00);
+#ifdef NEW_LOGGING
+       LDAP_LOG( OPERATION, ARGS, 
+               "parseProxyAuthz: conn %d authzid=\"%s\"\n", 
+               conn->c_connid,
+               ctrl->ldctl_value.bv_len ?  ctrl->ldctl_value.bv_val : "anonymous",
+               0 );
+#else
+       Debug( LDAP_DEBUG_ARGS,
+               "parseProxyAuthz: conn %d authzid=\"%s\"\n", 
+               conn->c_connid,
+               ctrl->ldctl_value.bv_len ?  ctrl->ldctl_value.bv_val : "anonymous",
+               0 );
+#endif
 
-       return LDAP_SUCCESS;
-}
+       if( ctrl->ldctl_value.bv_len == 0 ) {
+#ifdef NEW_LOGGING
+               LDAP_LOG( OPERATION, TRACE, 
+                       "parseProxyAuthz: conn=%d anonymous\n", 
+                       conn->c_connid, 0, 0 );
+#else
+               Debug( LDAP_DEBUG_TRACE,
+                       "parseProxyAuthz: conn=%d anonymous\n", 
+                       conn->c_connid, 0, 0 );
+#endif
+
+               /* anonymous */
+               free( op->o_dn.bv_val );
+               op->o_dn.bv_len = 0;
+               op->o_dn.bv_val = ch_strdup( "" );
+
+               free( op->o_ndn.bv_val );
+               op->o_ndn.bv_len = 0;
+               op->o_ndn.bv_val = ch_strdup( "" );
+
+               return LDAP_SUCCESS;
+       }
+
+       rc = slap_sasl_getdn( conn,
+               ctrl->ldctl_value.bv_val, ctrl->ldctl_value.bv_len,
+               NULL, &dn, SLAP_GETDN_AUTHZID );
+
+       if( rc != LDAP_SUCCESS || !dn.bv_len ) {
+               *text = "authzId mapping failed";
+               return LDAP_PROXY_AUTHZ_FAILURE;
+       }
+
+#ifdef NEW_LOGGING
+       LDAP_LOG( OPERATION, TRACE, 
+               "parseProxyAuthz: conn=%d \"%s\"\n", 
+               conn->c_connid,
+               dn.bv_len ? dn.bv_val : "(NULL)", 0 );
+#else
+       Debug( LDAP_DEBUG_TRACE,
+               "parseProxyAuthz: conn=%d \"%s\"\n", 
+               conn->c_connid,
+               dn.bv_len ? dn.bv_val : "(NULL)", 0 );
+#endif
+
+       rc = slap_sasl_authorized( conn, &op->o_dn, &dn );
+
+       if( rc ) {
+               ch_free( dn.bv_val );
+               *text = "not authorized to assume identity";
+               return LDAP_PROXY_AUTHZ_FAILURE;
+       }
+
+#if 0
+       ch_free( op->o_dn );
+       ch_free( op->o_ndn );
+
+       op->o_dn = dn;
 #endif
 
+       *text = "not (yet) implemented";
+       return LDAP_OTHER;
+}
+
 static int parseNoOp (
        Connection *conn,
        Operation *op,
@@ -479,7 +568,7 @@ static int parsePagedResults (
        }
 
        if ( ctrl->ldctl_value.bv_len == 0 ) {
-               *text = "paged results control value is empty";
+               *text = "paged results control value is empty (or absent)";
                return LDAP_PROTOCOL_ERROR;
        }
 
@@ -555,7 +644,12 @@ int parseValuesReturnFilter (
        const char *err_msg = "";
 
        if ( op->o_valuesreturnfilter != SLAP_NO_CONTROL ) {
-               *text = "valuesreturnfilter control specified multiple times";
+               *text = "valuesReturnFilter control specified multiple times";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       if ( ctrl->ldctl_value.bv_len == 0 ) {
+               *text = "valuesReturnFilter control value is empty (or absent)";
                return LDAP_PROTOCOL_ERROR;
        }
 
@@ -599,6 +693,37 @@ int parseValuesReturnFilter (
        return LDAP_SUCCESS;
 }
 
+#ifdef LDAP_CONTROL_SUBENTRIES
+static int parseSubentries (
+       Connection *conn,
+       Operation *op,
+       LDAPControl *ctrl,
+       const char **text )
+{
+       if ( op->o_subentries != SLAP_NO_CONTROL ) {
+               *text = "subentries control specified multiple times";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       /* FIXME: should use BER library */
+       if( ( ctrl->ldctl_value.bv_len != 3 )
+               && ( ctrl->ldctl_value.bv_val[0] != 0x01 )
+               && ( ctrl->ldctl_value.bv_val[1] != 0x01 ))
+       {
+               *text = "subentries control value encoding is bogus";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       op->o_subentries = ctrl->ldctl_iscritical
+               ? SLAP_CRITICAL_CONTROL
+               : SLAP_NONCRITICAL_CONTROL;
+
+       op->o_subentries_visibility = (ctrl->ldctl_value.bv_val[2] != 0x00);
+
+       return LDAP_SUCCESS;
+}
+#endif
+
 #ifdef LDAP_CLIENT_UPDATE
 static int parseClientUpdate (
        Connection *conn,
@@ -620,7 +745,7 @@ static int parseClientUpdate (
        }
 
        if ( ctrl->ldctl_value.bv_len == 0 ) {
-               *text = "LCUP client update control value is empty";
+               *text = "LCUP client update control value is empty (or absent)";
                return LDAP_PROTOCOL_ERROR;
        }
 
index 0da22bdfbbfdc46db73a3fb9282832524ba66a81..dfff66d4d79b9cdb63eb8ad717aab55dd62b209d 100644 (file)
@@ -150,6 +150,8 @@ do_extended(
                goto done;
        }
 
+       op->o_extendedop = reqoid.bv_val;
+
        tag = ber_peek_tag( op->o_ber, &len );
        
        if( ber_peek_tag( op->o_ber, &len ) == LDAP_TAG_EXOP_REQ_VALUE ) {
index bb574abeec1ebcb3c03a1183976102fa9498bfa9..0085f5f8d6a00b2e3784a3837220292497c13986 100644 (file)
@@ -875,6 +875,9 @@ LDAP_SLAPD_F (int) slap_sasl_config(
        const char *fname,
        int lineno );
 
+LDAP_SLAPD_F (int) slap_sasl_getdn( Connection *conn,
+       char *id, int len,
+       char *user_realm, struct berval *dn, int flags );
 
 /*
  * saslauthz.c
index 4cfd8f1e2b7faffb8ff12a81f8666c2779030699..703947b8d71645bc2a15c9f6d45ef489f05f903c 100644 (file)
@@ -447,7 +447,7 @@ send_ldap_result(
 
 #ifdef NEW_LOGGING
        LDAP_LOG( OPERATION, ENTRY, 
-               "send_ldap_result : conn %lu      op=%lu p=%d\n",
+               "send_ldap_result: conn %lu op=%lu p=%d\n",
                op->o_connid, op->o_opid, op->o_protocol );
 #else
        Debug( LDAP_DEBUG_TRACE,
@@ -567,13 +567,12 @@ send_ldap_extended(
                rspdata != NULL ? rspdata->bv_len : 0 );
 #else
        Debug( LDAP_DEBUG_TRACE,
-               "send_ldap_extended err=%d oid=%s len=%ld\n",
+               "send_ldap_extended: err=%d oid=%s len=%ld\n",
                err,
                rspoid ? rspoid : "",
                rspdata != NULL ? rspdata->bv_len : 0 );
 #endif
 
-
        tag = req2res( op->o_tag );
        msgid = (tag != LBER_SEQUENCE) ? op->o_msgid : 0;
 
index 876d7d99b5ed50d9537a287a38e6ad4dfa85431a..c97c144321a76faea1c861e18cf10d7d85a213c2 100644 (file)
 
 #include "slap.h"
 
-#ifdef HAVE_CYRUS_SASL
 #include <limits.h>
 
-#ifdef HAVE_SASL_SASL_H
-#include <sasl/sasl.h>
-#else
-#include <sasl.h>
-#endif
+#ifdef HAVE_CYRUS_SASL
+# ifdef HAVE_SASL_SASL_H
+#  include <sasl/sasl.h>
+# else
+#  include <sasl.h>
+# endif
+
+# if SASL_VERSION_MAJOR >= 2
+#  include <sasl/saslplug.h>
+#  define      SASL_CONST const
+# else
+#  define      SASL_CONST
+# endif
 
-#include <lutil.h>
-#if SASL_VERSION_MAJOR >= 2
-#include <sasl/saslplug.h>
-#define        SASL_CONST const
-#else
-#define        SASL_CONST
-#endif
+static sasl_security_properties_t sasl_secprops;
+#endif /* HAVE_CYRUS_SASL */
 
 #include "ldap_pvt.h"
 #include "lber_pvt.h"
-
-/* Flags for telling slap_sasl_getdn() what type of identity is being passed */
-#define FLAG_GETDN_AUTHCID 2
-#define FLAG_GETDN_AUTHZID 4
-
-static sasl_security_properties_t sasl_secprops;
+#include <lutil.h>
 
 int slap_sasl_config( int cargc, char **cargv, char *line,
        const char *fname, int lineno )
@@ -49,11 +46,13 @@ int slap_sasl_config( int cargc, char **cargv, char *line,
                        if ( cargc != 2 ) {
 #ifdef NEW_LOGGING
                                LDAP_LOG( CONFIG, CRIT,
-                                          "%s: line %d: missing policy in \"sasl-authz-policy <policy>\" line\n",
-                                          fname, lineno, 0 );
+                                       "%s: line %d: missing policy in"
+                                       " \"sasl-authz-policy <policy>\" line\n",
+                                       fname, lineno, 0 );
 #else
                                Debug( LDAP_DEBUG_ANY,
-           "%s: line %d: missing policy in \"sasl-authz-policy <policy>\" line\n",
+                                       "%s: line %d: missing policy in"
+                                       " \"sasl-authz-policy <policy>\" line\n",
                                    fname, lineno, 0 );
 #endif
 
@@ -77,18 +76,42 @@ int slap_sasl_config( int cargc, char **cargv, char *line,
 #endif
                                return( 1 );
                        }
-                       
 
+               } else if ( !strcasecmp( cargv[0], "sasl-regexp" ) 
+                       || !strcasecmp( cargv[0], "saslregexp" ) )
+               {
+                       int rc;
+                       if ( cargc != 3 ) {
+#ifdef NEW_LOGGING
+                               LDAP_LOG( CONFIG, CRIT,
+                                       "%s: line %d: need 2 args in "
+                                       "\"saslregexp <match> <replace>\"\n",
+                                       fname, lineno, 0 );
+#else
+                               Debug( LDAP_DEBUG_ANY, 
+                                       "%s: line %d: need 2 args in "
+                                       "\"saslregexp <match> <replace>\"\n",
+                                       fname, lineno, 0 );
+#endif
+
+                               return( 1 );
+                       }
+                       rc = slap_sasl_regexp_config( cargv[1], cargv[2] );
+                       if ( rc ) {
+                               return rc;
+                       }
+
+#ifdef HAVE_CYRUS_SASL
                /* set SASL host */
                } else if ( strcasecmp( cargv[0], "sasl-host" ) == 0 ) {
                        if ( cargc < 2 ) {
 #ifdef NEW_LOGGING
                                LDAP_LOG( CONFIG, CRIT,
-                                          "%s: line %d: missing host in \"sasl-host <host>\" line\n",
-                                          fname, lineno, 0 );
+                                       "%s: line %d: missing host in \"sasl-host <host>\" line\n",
+                                       fname, lineno, 0 );
 #else
                                Debug( LDAP_DEBUG_ANY,
-           "%s: line %d: missing host in \"sasl-host <host>\" line\n",
+                               "%s: line %d: missing host in \"sasl-host <host>\" line\n",
                                    fname, lineno, 0 );
 #endif
 
@@ -98,8 +121,8 @@ int slap_sasl_config( int cargc, char **cargv, char *line,
                        if ( global_host != NULL ) {
 #ifdef NEW_LOGGING
                                LDAP_LOG( CONFIG, CRIT,
-                                          "%s: line %d: already set sasl-host!\n",
-                                          fname, lineno, 0 );
+                                       "%s: line %d: already set sasl-host!\n",
+                                       fname, lineno, 0 );
 #else
                                Debug( LDAP_DEBUG_ANY,
                                        "%s: line %d: already set sasl-host!\n",
@@ -116,12 +139,12 @@ int slap_sasl_config( int cargc, char **cargv, char *line,
                } else if ( strcasecmp( cargv[0], "sasl-realm" ) == 0 ) {
                        if ( cargc < 2 ) {
 #ifdef NEW_LOGGING
-                               LDAP_LOG( CONFIG, CRIT,
-                                          "%s: line %d: missing realm in \"sasl-realm <realm>\" line.\n",
-                                          fname, lineno, 0 );
+                               LDAP_LOG( CONFIG, CRIT, "%s: line %d: "
+                                       "missing realm in \"sasl-realm <realm>\" line.\n",
+                                       fname, lineno, 0 );
 #else
-                               Debug( LDAP_DEBUG_ANY,
-           "%s: line %d: missing realm in \"sasl-realm <realm>\" line\n",
+                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+                                       "missing realm in \"sasl-realm <realm>\" line.\n",
                                    fname, lineno, 0 );
 #endif
 
@@ -131,8 +154,8 @@ int slap_sasl_config( int cargc, char **cargv, char *line,
                        if ( global_realm != NULL ) {
 #ifdef NEW_LOGGING
                                LDAP_LOG( CONFIG, CRIT,
-                                          "%s: line %d: already set sasl-realm!\n",
-                                          fname, lineno, 0 );
+                                       "%s: line %d: already set sasl-realm!\n",
+                                       fname, lineno, 0 );
 #else
                                Debug( LDAP_DEBUG_ANY,
                                        "%s: line %d: already set sasl-realm!\n",
@@ -145,42 +168,18 @@ int slap_sasl_config( int cargc, char **cargv, char *line,
                                global_realm = ch_strdup( cargv[1] );
                        }
 
-               } else if ( !strcasecmp( cargv[0], "sasl-regexp" ) 
-                       || !strcasecmp( cargv[0], "saslregexp" ) )
-               {
-                       int rc;
-                       if ( cargc != 3 ) {
-#ifdef NEW_LOGGING
-                               LDAP_LOG( CONFIG, CRIT,
-                                          "%s: line %d: need 2 args in "
-                                          "\"saslregexp <match> <replace>\"\n",
-                                          fname, lineno, 0 );
-#else
-                               Debug( LDAP_DEBUG_ANY, 
-                               "%s: line %d: need 2 args in \"saslregexp <match> <replace>\"\n",
-                                   fname, lineno, 0 );
-#endif
-
-                               return( 1 );
-                       }
-                       rc = slap_sasl_regexp_config( cargv[1], cargv[2] );
-                       if ( rc ) {
-                               return rc;
-                       }
-
                /* SASL security properties */
                } else if ( strcasecmp( cargv[0], "sasl-secprops" ) == 0 ) {
                        char *txt;
 
                        if ( cargc < 2 ) {
 #ifdef NEW_LOGGING
-                               LDAP_LOG( CONFIG, CRIT,
-                                          "%s: line %d: missing flags in "
-                                          "\"sasl-secprops <properties>\" line\n",
-                                          fname, lineno, 0 );
+                               LDAP_LOG( CONFIG, CRIT, "%s: line %d: "
+                                       "missing flags in \"sasl-secprops <properties>\" line\n",
+                                       fname, lineno, 0 );
 #else
-                               Debug( LDAP_DEBUG_ANY,
-           "%s: line %d: missing flags in \"sasl-secprops <properties>\" line\n",
+                               Debug( LDAP_DEBUG_ANY, "%s: line %d: "
+                                       "missing flags in \"sasl-secprops <properties>\" line\n",
                                    fname, lineno, 0 );
 #endif
 
@@ -191,22 +190,25 @@ int slap_sasl_config( int cargc, char **cargv, char *line,
                        if ( txt != NULL ) {
 #ifdef NEW_LOGGING
                                LDAP_LOG( CONFIG, CRIT,
-                                          "%s: line %d sasl-secprops: %s\n",
-                                          fname, lineno, txt );
+                                       "%s: line %d sasl-secprops: %s\n",
+                                       fname, lineno, txt );
 #else
                                Debug( LDAP_DEBUG_ANY,
-           "%s: line %d: sasl-secprops: %s\n",
+                                       "%s: line %d: sasl-secprops: %s\n",
                                    fname, lineno, txt );
 #endif
 
                                return 1;
                        }
+#endif /* HAVE_CYRUS_SASL */
            }
 
            return LDAP_SUCCESS;
 }
 
-static int
+#ifdef HAVE_CYRUS_SASL
+
+int
 slap_sasl_log(
        void *context,
        int priority,
@@ -286,190 +288,6 @@ slap_sasl_log(
 }
 
 
-/* Take any sort of identity string and return a DN with the "dn:" prefix. The
-   string returned in *dn is in its own allocated memory, and must be free'd 
-   by the calling process.
-   -Mark Adamson, Carnegie Mellon
-
-   The "dn:" prefix is no longer used anywhere inside slapd. It is only used
-   on strings passed in directly from SASL.
-   -Howard Chu, Symas Corp.
-*/
-
-#define        SET_DN  1
-#define        SET_U   2
-
-static struct berval ext_bv = BER_BVC( "EXTERNAL" );
-
-int slap_sasl_getdn( Connection *conn, char *id, int len,
-       char *user_realm, struct berval *dn, int flags )
-{
-       char *c1;
-       int rc, is_dn = 0, do_norm = 1;
-       sasl_conn_t *ctx;
-       struct berval dn2;
-
-#ifdef NEW_LOGGING
-       LDAP_LOG( TRANSPORT, ENTRY, 
-               "slap_sasl_getdn: conn %d id=%s\n",
-               conn ? conn->c_connid : -1, id ? (*id ? id : "<empty>") : "NULL", 0 );
-#else
-       Debug( LDAP_DEBUG_ARGS, "slap_sasl_getdn: id=%s\n", 
-      id?(*id?id:"<empty>"):"NULL",0,0 );
-#endif
-
-       dn->bv_val = NULL;
-       dn->bv_len = 0;
-
-       if ( id ) {
-               if ( len == 0 ) len = strlen( id );
-
-               /* Blatantly anonymous ID */
-               if ( len == sizeof("anonymous") - 1 &&
-                       !strcasecmp( id, "anonymous" ) ) {
-                       return( LDAP_SUCCESS );
-               }
-       } else {
-               len = 0;
-       }
-
-       ctx = conn->c_sasl_context;
-
-       /* An authcID needs to be converted to authzID form. Set the
-        * values directly into *dn; they will be normalized later. (and
-        * normalizing always makes a new copy.) An ID from a TLS certificate
-        * is already normalized, so copy it and skip normalization.
-        */
-       if( flags & FLAG_GETDN_AUTHCID ) {
-#ifdef HAVE_TLS
-               if( conn->c_is_tls &&
-                       conn->c_sasl_bind_mech.bv_len == ext_bv.bv_len &&
-                       strcasecmp( ext_bv.bv_val, conn->c_sasl_bind_mech.bv_val ) == 0 )
-               {
-                       /* X.509 DN is already normalized */
-                       do_norm = 0;
-                       is_dn = SET_DN;
-                       ber_str2bv( id, len, 1, dn );
-
-               } else
-#endif
-               {
-                       /* convert to u:<username> form */
-                       is_dn = SET_U;
-                       dn->bv_val = id;
-                       dn->bv_len = len;
-               }
-       }
-       if( !is_dn ) {
-               if( !strncasecmp( id, "u:", sizeof("u:")-1 )) {
-                       is_dn = SET_U;
-                       dn->bv_val = id+2;
-                       dn->bv_len = len-2;
-               } else if ( !strncasecmp( id, "dn:", sizeof("dn:")-1) ) {
-                       is_dn = SET_DN;
-                       dn->bv_val = id+3;
-                       dn->bv_len = len-3;
-               }
-       }
-
-       /* No other possibilities from here */
-       if( !is_dn ) {
-               dn->bv_val = NULL;
-               dn->bv_len = 0;
-               return( LDAP_INAPPROPRIATE_AUTH );
-       }
-
-       /* Username strings */
-       if( is_dn == SET_U ) {
-               char *p, *realm;
-               len = dn->bv_len + sizeof("uid=")-1 + sizeof(",cn=auth")-1;
-
-               /* username may have embedded realm name */
-               if( ( realm = strchr( dn->bv_val, '@') ) ) {
-                       *realm++ = '\0';
-                       len += sizeof(",cn=")-2;
-               } else if( user_realm && *user_realm ) {
-                       len += strlen( user_realm ) + sizeof(",cn=")-1;
-               }
-
-               if( conn->c_sasl_bind_mech.bv_len ) {
-                       len += conn->c_sasl_bind_mech.bv_len + sizeof(",cn=")-1;
-               }
-
-               /* Build the new dn */
-               c1 = dn->bv_val;
-               dn->bv_val = SLAP_MALLOC( len+1 );
-               if( dn->bv_val == NULL ) {
-#ifdef NEW_LOGGING
-                       LDAP_LOG( TRANSPORT, ERR, 
-                               "slap_sasl_getdn: SLAP_MALLOC failed", 0, 0, 0 );
-#else
-                       Debug( LDAP_DEBUG_ANY, 
-                               "slap_sasl_getdn: SLAP_MALLOC failed", 0, 0, 0 );
-#endif
-                       return LDAP_OTHER;
-               }
-               p = lutil_strcopy( dn->bv_val, "uid=" );
-               p = lutil_strncopy( p, c1, dn->bv_len );
-
-               if( realm ) {
-                       int rlen = dn->bv_len - ( realm - c1 );
-                       p = lutil_strcopy( p, ",cn=" );
-                       p = lutil_strncopy( p, realm, rlen );
-                       realm[-1] = '@';
-               } else if( user_realm && *user_realm ) {
-                       p = lutil_strcopy( p, ",cn=" );
-                       p = lutil_strcopy( p, user_realm );
-               }
-
-               if( conn->c_sasl_bind_mech.bv_len ) {
-                       p = lutil_strcopy( p, ",cn=" );
-                       p = lutil_strcopy( p, conn->c_sasl_bind_mech.bv_val );
-               }
-               p = lutil_strcopy( p, ",cn=auth" );
-               dn->bv_len = p - dn->bv_val;
-
-#ifdef NEW_LOGGING
-               LDAP_LOG( TRANSPORT, ENTRY, 
-                       "slap_sasl_getdn: u:id converted to %s.\n", dn->bv_val, 0, 0 );
-#else
-               Debug( LDAP_DEBUG_TRACE, "getdn: u:id converted to %s\n", dn->bv_val,0,0 );
-#endif
-       }
-
-       /* All strings are in DN form now. Normalize if needed. */
-       if ( do_norm ) {
-               rc = dnNormalize2( NULL, dn, &dn2 );
-
-               /* User DNs were constructed above and must be freed now */
-               if ( is_dn == SET_U )
-                       ch_free( dn->bv_val );
-
-               if ( rc != LDAP_SUCCESS ) {
-                       dn->bv_val = NULL;
-                       dn->bv_len = 0;
-                       return rc;
-               }
-               *dn = dn2;
-       }
-
-       /* Run thru regexp */
-       slap_sasl2dn( conn, dn, &dn2 );
-       if( dn2.bv_val ) {
-               ch_free( dn->bv_val );
-               *dn = dn2;
-#ifdef NEW_LOGGING
-               LDAP_LOG( TRANSPORT, ENTRY, 
-                       "slap_sasl_getdn: dn:id converted to %s.\n", dn->bv_val, 0, 0 );
-#else
-               Debug( LDAP_DEBUG_TRACE, "getdn: dn:id converted to %s\n",
-                       dn->bv_val, 0, 0 );
-#endif
-       }
-
-       return( LDAP_SUCCESS );
-}
-
 #if SASL_VERSION_MAJOR >= 2
 static const char *slap_propnames[] = {
        "*slapConn", "*authcDN", "*authzDN", NULL };
@@ -714,7 +532,7 @@ slap_sasl_checkpass(
         */
 
        rc = slap_sasl_getdn( conn, (char *)username, 0, NULL, &dn,
-               FLAG_GETDN_AUTHCID );
+               SLAP_GETDN_AUTHCID );
        if ( rc != LDAP_SUCCESS ) {
                sasl_seterror( sconn, 0, ldap_err2string( rc ) );
                return SASL_NOUSER;
@@ -849,7 +667,7 @@ slap_sasl_canonicalize(
        }
 
        rc = slap_sasl_getdn( conn, (char *)in, inlen, (char *)user_realm, &dn,
-               (flags & SASL_CU_AUTHID) ? FLAG_GETDN_AUTHCID : FLAG_GETDN_AUTHZID );
+               (flags & SASL_CU_AUTHID) ? SLAP_GETDN_AUTHCID : SLAP_GETDN_AUTHZID );
        if ( rc != LDAP_SUCCESS ) {
                sasl_seterror( sconn, 0, ldap_err2string( rc ) );
                return SASL_NOAUTHZ;
@@ -1004,7 +822,8 @@ slap_sasl_authorize(
 
        /* Convert the identities to DN's. If no authzid was given, client will
           be bound as the DN matching their username */
-       rc = slap_sasl_getdn( conn, (char *)authcid, 0, realm, &authcDN, FLAG_GETDN_AUTHCID );
+       rc = slap_sasl_getdn( conn, (char *)authcid, 0, realm,
+               &authcDN, SLAP_GETDN_AUTHCID );
        if( rc != LDAP_SUCCESS ) {
                *errstr = ldap_err2string( rc );
                return SASL_NOAUTHZ;
@@ -1023,7 +842,8 @@ slap_sasl_authorize(
                *errstr = NULL;
                return SASL_OK;
        }
-       rc = slap_sasl_getdn( conn, (char *)authzid, 0, realm, &authzDN, FLAG_GETDN_AUTHZID );
+       rc = slap_sasl_getdn( conn, (char *)authzid, 0, realm,
+               &authzDN, SLAP_GETDN_AUTHZID );
        if( rc != LDAP_SUCCESS ) {
                ch_free( authcDN.bv_val );
                *errstr = ldap_err2string( rc );
@@ -1101,7 +921,6 @@ slap_sasl_err2ldap( int saslerr )
 }
 #endif
 
-
 int slap_sasl_init( void )
 {
 #ifdef HAVE_CYRUS_SASL
@@ -1677,4 +1496,185 @@ slap_sasl_setpass(
 done:
        return rc;
 }
+#endif /* HAVE_CYRUS_SASL */
+
+/* Take any sort of identity string and return a DN with the "dn:" prefix. The
+   string returned in *dn is in its own allocated memory, and must be free'd 
+   by the calling process.
+   -Mark Adamson, Carnegie Mellon
+
+   The "dn:" prefix is no longer used anywhere inside slapd. It is only used
+   on strings passed in directly from SASL.
+   -Howard Chu, Symas Corp.
+*/
+
+#define        SET_DN  1
+#define        SET_U   2
+
+static struct berval ext_bv = BER_BVC( "EXTERNAL" );
+
+int slap_sasl_getdn( Connection *conn, char *id, int len,
+       char *user_realm, struct berval *dn, int flags )
+{
+       char *c1;
+       int rc, is_dn = 0, do_norm = 1;
+       struct berval dn2;
+
+#ifdef NEW_LOGGING
+       LDAP_LOG( TRANSPORT, ENTRY, 
+               "slap_sasl_getdn: conn %d id=%s\n",
+               conn ? conn->c_connid : -1, id ? (*id ? id : "<empty>") : "NULL", 0 );
+#else
+       Debug( LDAP_DEBUG_ARGS, "slap_sasl_getdn: id=%s\n", 
+      id?(*id?id:"<empty>"):"NULL",0,0 );
+#endif
+
+       dn->bv_val = NULL;
+       dn->bv_len = 0;
+
+       if ( id ) {
+               if ( len == 0 ) len = strlen( id );
+
+               /* Blatantly anonymous ID */
+               if ( len == sizeof("anonymous") - 1 &&
+                       !strcasecmp( id, "anonymous" ) ) {
+                       return( LDAP_SUCCESS );
+               }
+       } else {
+               len = 0;
+       }
+
+       /* An authcID needs to be converted to authzID form. Set the
+        * values directly into *dn; they will be normalized later. (and
+        * normalizing always makes a new copy.) An ID from a TLS certificate
+        * is already normalized, so copy it and skip normalization.
+        */
+       if( flags & SLAP_GETDN_AUTHCID ) {
+#ifdef HAVE_TLS
+               if( conn->c_is_tls &&
+                       conn->c_sasl_bind_mech.bv_len == ext_bv.bv_len &&
+                       strcasecmp( ext_bv.bv_val, conn->c_sasl_bind_mech.bv_val ) == 0 )
+               {
+                       /* X.509 DN is already normalized */
+                       do_norm = 0;
+                       is_dn = SET_DN;
+                       ber_str2bv( id, len, 1, dn );
+
+               } else
 #endif
+               {
+                       /* convert to u:<username> form */
+                       is_dn = SET_U;
+                       dn->bv_val = id;
+                       dn->bv_len = len;
+               }
+       }
+       if( !is_dn ) {
+               if( !strncasecmp( id, "u:", sizeof("u:")-1 )) {
+                       is_dn = SET_U;
+                       dn->bv_val = id+2;
+                       dn->bv_len = len-2;
+               } else if ( !strncasecmp( id, "dn:", sizeof("dn:")-1) ) {
+                       is_dn = SET_DN;
+                       dn->bv_val = id+3;
+                       dn->bv_len = len-3;
+               }
+       }
+
+       /* No other possibilities from here */
+       if( !is_dn ) {
+               dn->bv_val = NULL;
+               dn->bv_len = 0;
+               return( LDAP_INAPPROPRIATE_AUTH );
+       }
+
+       /* Username strings */
+       if( is_dn == SET_U ) {
+               char *p, *realm;
+               len = dn->bv_len + sizeof("uid=")-1 + sizeof(",cn=auth")-1;
+
+               /* username may have embedded realm name */
+               if( ( realm = strchr( dn->bv_val, '@') ) ) {
+                       *realm++ = '\0';
+                       len += sizeof(",cn=")-2;
+               } else if( user_realm && *user_realm ) {
+                       len += strlen( user_realm ) + sizeof(",cn=")-1;
+               }
+
+               if( conn->c_sasl_bind_mech.bv_len ) {
+                       len += conn->c_sasl_bind_mech.bv_len + sizeof(",cn=")-1;
+               }
+
+               /* Build the new dn */
+               c1 = dn->bv_val;
+               dn->bv_val = SLAP_MALLOC( len+1 );
+               if( dn->bv_val == NULL ) {
+#ifdef NEW_LOGGING
+                       LDAP_LOG( TRANSPORT, ERR, 
+                               "slap_sasl_getdn: SLAP_MALLOC failed", 0, 0, 0 );
+#else
+                       Debug( LDAP_DEBUG_ANY, 
+                               "slap_sasl_getdn: SLAP_MALLOC failed", 0, 0, 0 );
+#endif
+                       return LDAP_OTHER;
+               }
+               p = lutil_strcopy( dn->bv_val, "uid=" );
+               p = lutil_strncopy( p, c1, dn->bv_len );
+
+               if( realm ) {
+                       int rlen = dn->bv_len - ( realm - c1 );
+                       p = lutil_strcopy( p, ",cn=" );
+                       p = lutil_strncopy( p, realm, rlen );
+                       realm[-1] = '@';
+               } else if( user_realm && *user_realm ) {
+                       p = lutil_strcopy( p, ",cn=" );
+                       p = lutil_strcopy( p, user_realm );
+               }
+
+               if( conn->c_sasl_bind_mech.bv_len ) {
+                       p = lutil_strcopy( p, ",cn=" );
+                       p = lutil_strcopy( p, conn->c_sasl_bind_mech.bv_val );
+               }
+               p = lutil_strcopy( p, ",cn=auth" );
+               dn->bv_len = p - dn->bv_val;
+
+#ifdef NEW_LOGGING
+               LDAP_LOG( TRANSPORT, ENTRY, 
+                       "slap_sasl_getdn: u:id converted to %s.\n", dn->bv_val, 0, 0 );
+#else
+               Debug( LDAP_DEBUG_TRACE, "getdn: u:id converted to %s\n", dn->bv_val,0,0 );
+#endif
+       }
+
+       /* All strings are in DN form now. Normalize if needed. */
+       if ( do_norm ) {
+               rc = dnNormalize2( NULL, dn, &dn2 );
+
+               /* User DNs were constructed above and must be freed now */
+               if ( is_dn == SET_U )
+                       ch_free( dn->bv_val );
+
+               if ( rc != LDAP_SUCCESS ) {
+                       dn->bv_val = NULL;
+                       dn->bv_len = 0;
+                       return rc;
+               }
+               *dn = dn2;
+       }
+
+       /* Run thru regexp */
+       slap_sasl2dn( conn, dn, &dn2 );
+       if( dn2.bv_val ) {
+               ch_free( dn->bv_val );
+               *dn = dn2;
+#ifdef NEW_LOGGING
+               LDAP_LOG( TRANSPORT, ENTRY, 
+                       "slap_sasl_getdn: dn:id converted to %s.\n", dn->bv_val, 0, 0 );
+#else
+               Debug( LDAP_DEBUG_TRACE, "getdn: dn:id converted to %s\n",
+                       dn->bv_val, 0, 0 );
+#endif
+       }
+
+       return( LDAP_SUCCESS );
+}
index 24ccf062b496ce9bded6320abf307d3999edd821..8fdf1ca6049ee6459614ff8d1f2b314676fd46b3 100644 (file)
 
 #include "slap.h"
 
-#ifdef HAVE_CYRUS_SASL
 #include <limits.h>
 
-#ifdef HAVE_SASL_SASL_H
-#include <sasl/sasl.h>
-#else
-#include <sasl.h>
-#endif
-
 #include <ldap_pvt.h>
 
 #define SASLREGEX_REPLACE 10
@@ -372,107 +365,6 @@ static int sasl_sc_sasl2dn( BackendDB *be, Connection *conn, Operation *o,
        return 0;
 }
 
-/*
- * Given a SASL name (e.g. "UID=name,cn=REALM,cn=MECH,cn=AUTH")
- * return the LDAP DN to which it matches. The SASL regexp rules in the config
- * file turn the SASL name into an LDAP URI. If the URI is just a DN (or a
- * search with scope=base), just return the URI (or its searchbase). Otherwise
- * an internal search must be done, and if that search returns exactly one
- * entry, return the DN of that one entry.
- */
-
-void slap_sasl2dn( Connection *conn,
-       struct berval *saslname, struct berval *sasldn )
-{
-       int rc;
-       Backend *be = NULL;
-       struct berval dn = { 0, NULL };
-       int scope = LDAP_SCOPE_BASE;
-       Filter *filter = NULL;
-       slap_callback cb = {slap_cb_null_response, slap_cb_null_sresult, sasl_sc_sasl2dn, NULL};
-       Operation op = {0};
-       struct berval regout = { 0, NULL };
-
-#ifdef NEW_LOGGING
-       LDAP_LOG( TRANSPORT, ENTRY, 
-               "slap_sasl2dn: converting SASL name %s to DN.\n",
-               saslname->bv_val, 0, 0 );
-#else
-       Debug( LDAP_DEBUG_TRACE, "==>slap_sasl2dn: "
-               "converting SASL name %s to a DN\n",
-               saslname->bv_val, 0,0 );
-#endif
-
-       sasldn->bv_val = NULL;
-       sasldn->bv_len = 0;
-       cb.sc_private = sasldn;
-
-       /* Convert the SASL name into a minimal URI */
-       if( !slap_sasl_regexp( saslname, &regout ) ) {
-               goto FINISHED;
-       }
-
-       rc = slap_parseURI( &regout, &dn, &scope, &filter );
-       if( rc != LDAP_SUCCESS ) {
-               goto FINISHED;
-       }
-
-       /* Must do an internal search */
-       be = select_backend( &dn, 0, 1 );
-
-       /* Massive shortcut: search scope == base */
-       if( scope == LDAP_SCOPE_BASE ) {
-               *sasldn = dn;
-               dn.bv_len = 0;
-               dn.bv_val = NULL;
-               goto FINISHED;
-       }
-
-#ifdef NEW_LOGGING
-       LDAP_LOG( TRANSPORT, DETAIL1, 
-               "slap_sasl2dn: performing internal search (base=%s, scope=%d)\n",
-               dn.bv_val, scope, 0 );
-#else
-       Debug( LDAP_DEBUG_TRACE,
-               "slap_sasl2dn: performing internal search (base=%s, scope=%d)\n",
-               dn.bv_val, scope, 0 );
-#endif
-
-       if(( be == NULL ) || ( be->be_search == NULL)) {
-               goto FINISHED;
-       }
-       suffix_alias( be, &dn );
-
-       op.o_tag = LDAP_REQ_SEARCH;
-       op.o_protocol = LDAP_VERSION3;
-       op.o_ndn = *saslname;
-       op.o_callback = &cb;
-       op.o_time = slap_get_time();
-       op.o_do_not_cache = 1;
-       op.o_threadctx = conn->c_sasl_bindop->o_threadctx;
-
-       (*be->be_search)( be, conn, &op, NULL, &dn,
-               scope, LDAP_DEREF_NEVER, 1, 0,
-               filter, NULL, NULL, 1 );
-       
-FINISHED:
-       if( sasldn->bv_len ) {
-               conn->c_authz_backend = be;
-       }
-       if( dn.bv_len ) ch_free( dn.bv_val );
-       if( filter ) filter_free( filter );
-
-#ifdef NEW_LOGGING
-       LDAP_LOG( TRANSPORT, ENTRY, 
-               "slap_sasl2dn: Converted SASL name to %s\n",
-               sasldn->bv_len ? sasldn->bv_val : "<nothing>", 0, 0 );
-#else
-       Debug( LDAP_DEBUG_TRACE, "<==slap_sasl2dn: Converted SASL name to %s\n",
-               sasldn->bv_len ? sasldn->bv_val : "<nothing>", 0, 0 );
-#endif
-
-       return;
-}
 
 typedef struct smatch_info {
        struct berval *dn;
@@ -652,7 +544,108 @@ COMPLETE:
 
        return( rc );
 }
-#endif /* HAVE_CYRUS_SASL */
+
+/*
+ * Given a SASL name (e.g. "UID=name,cn=REALM,cn=MECH,cn=AUTH")
+ * return the LDAP DN to which it matches. The SASL regexp rules in the config
+ * file turn the SASL name into an LDAP URI. If the URI is just a DN (or a
+ * search with scope=base), just return the URI (or its searchbase). Otherwise
+ * an internal search must be done, and if that search returns exactly one
+ * entry, return the DN of that one entry.
+ */
+void slap_sasl2dn( Connection *conn,
+       struct berval *saslname, struct berval *sasldn )
+{
+       int rc;
+       Backend *be = NULL;
+       struct berval dn = { 0, NULL };
+       int scope = LDAP_SCOPE_BASE;
+       Filter *filter = NULL;
+       slap_callback cb = { slap_cb_null_response,
+               slap_cb_null_sresult, sasl_sc_sasl2dn, NULL};
+       Operation op = {0};
+       struct berval regout = { 0, NULL };
+
+#ifdef NEW_LOGGING
+       LDAP_LOG( TRANSPORT, ENTRY, 
+               "slap_sasl2dn: converting SASL name %s to DN.\n",
+               saslname->bv_val, 0, 0 );
+#else
+       Debug( LDAP_DEBUG_TRACE, "==>slap_sasl2dn: "
+               "converting SASL name %s to a DN\n",
+               saslname->bv_val, 0,0 );
+#endif
+
+       sasldn->bv_val = NULL;
+       sasldn->bv_len = 0;
+       cb.sc_private = sasldn;
+
+       /* Convert the SASL name into a minimal URI */
+       if( !slap_sasl_regexp( saslname, &regout ) ) {
+               goto FINISHED;
+       }
+
+       rc = slap_parseURI( &regout, &dn, &scope, &filter );
+       if( rc != LDAP_SUCCESS ) {
+               goto FINISHED;
+       }
+
+       /* Must do an internal search */
+       be = select_backend( &dn, 0, 1 );
+
+       /* Massive shortcut: search scope == base */
+       if( scope == LDAP_SCOPE_BASE ) {
+               *sasldn = dn;
+               dn.bv_len = 0;
+               dn.bv_val = NULL;
+               goto FINISHED;
+       }
+
+#ifdef NEW_LOGGING
+       LDAP_LOG( TRANSPORT, DETAIL1, 
+               "slap_sasl2dn: performing internal search (base=%s, scope=%d)\n",
+               dn.bv_val, scope, 0 );
+#else
+       Debug( LDAP_DEBUG_TRACE,
+               "slap_sasl2dn: performing internal search (base=%s, scope=%d)\n",
+               dn.bv_val, scope, 0 );
+#endif
+
+       if(( be == NULL ) || ( be->be_search == NULL)) {
+               goto FINISHED;
+       }
+       suffix_alias( be, &dn );
+
+       op.o_tag = LDAP_REQ_SEARCH;
+       op.o_protocol = LDAP_VERSION3;
+       op.o_ndn = *saslname;
+       op.o_callback = &cb;
+       op.o_time = slap_get_time();
+       op.o_do_not_cache = 1;
+       op.o_threadctx = conn->c_sasl_bindop->o_threadctx;
+
+       (*be->be_search)( be, conn, &op, NULL, &dn,
+               scope, LDAP_DEREF_NEVER, 1, 0,
+               filter, NULL, NULL, 1 );
+       
+FINISHED:
+       if( sasldn->bv_len ) {
+               conn->c_authz_backend = be;
+       }
+       if( dn.bv_len ) ch_free( dn.bv_val );
+       if( filter ) filter_free( filter );
+
+#ifdef NEW_LOGGING
+       LDAP_LOG( TRANSPORT, ENTRY, 
+               "slap_sasl2dn: Converted SASL name to %s\n",
+               sasldn->bv_len ? sasldn->bv_val : "<nothing>", 0, 0 );
+#else
+       Debug( LDAP_DEBUG_TRACE, "<==slap_sasl2dn: Converted SASL name to %s\n",
+               sasldn->bv_len ? sasldn->bv_val : "<nothing>", 0, 0 );
+#endif
+
+       return;
+}
 
 
 /* Check if a bind can SASL authorize to another identity.
@@ -664,7 +657,6 @@ int slap_sasl_authorized( Connection *conn,
 {
        int rc = LDAP_INAPPROPRIATE_AUTH;
 
-#ifdef HAVE_CYRUS_SASL
        /* User binding as anonymous */
        if ( authzDN == NULL ) {
                rc = LDAP_SUCCESS;
@@ -677,7 +669,8 @@ int slap_sasl_authorized( Connection *conn,
                authcDN->bv_val, authzDN->bv_val, 0 );
 #else
        Debug( LDAP_DEBUG_TRACE,
-          "==>slap_sasl_authorized: can %s become %s?\n", authcDN->bv_val, authzDN->bv_val, 0 );
+          "==>slap_sasl_authorized: can %s become %s?\n",
+               authcDN->bv_val, authzDN->bv_val, 0 );
 #endif
 
        /* If person is authorizing to self, succeed */
@@ -707,7 +700,6 @@ int slap_sasl_authorized( Connection *conn,
        rc = LDAP_INAPPROPRIATE_AUTH;
 
 DONE:
-#endif
 
 #ifdef NEW_LOGGING
        LDAP_LOG( TRANSPORT, RESULTS, "slap_sasl_authorized: return %d\n", rc,0,0 );
index 7e33a378ada68f3dfcce88d539c7604669cdbf77..af09fec6d601aa9b1806eb41f5414b7f6161d5eb 100644 (file)
@@ -169,6 +169,11 @@ typedef struct slap_ssf_set {
        slap_ssf_t sss_simple_bind;
 } slap_ssf_set_t;
 
+
+/* Flags for telling slap_sasl_getdn() what type of identity is being passed */
+#define SLAP_GETDN_AUTHCID 2
+#define SLAP_GETDN_AUTHZID 4
+
 /*
  * Index types
  */
@@ -1631,6 +1636,8 @@ typedef struct slap_op {
        ber_tag_t       o_tag;          /* tag of the request */
        time_t          o_time;         /* time op was initiated */
 
+       char *          o_extendedop;   /* extended operation OID */
+
        ldap_pvt_thread_t       o_tid;  /* thread handling this op */
 
        volatile sig_atomic_t o_abandon;        /* abandon flag */
@@ -1642,6 +1649,7 @@ typedef struct slap_op {
 #define SLAP_CRITICAL_CONTROL 2
        char o_managedsait;
        char o_noop;
+       char o_proxy_authz;
        char o_subentries;
        char o_subentries_visibility;
        char o_valuesreturnfilter;
index 375a6706b22f0f3d827bac6a8fe19e500b36b9c2..70f87c3dddbf2e28b152512b072529b9a062fbd4 100644 (file)
@@ -270,3 +270,15 @@ slap_modrdn2mods(
        return 0;
 }
 
+int slap_sasl_getdn( Connection *conn, char *id, int len,
+       char *user_realm, struct berval *dn, int flags )
+{
+       return -1;
+}
+
+int slap_sasl_authorized( Connection *conn,
+       struct berval *authcDN, struct berval *authzDN )
+{
+       return -1;
+}
+
index b6aea511cc0b1b57f2269d2ea565daaaec0a9a62..219bce52e797ea138c98fc820475cc1e6720afb1 100755 (executable)
@@ -66,6 +66,39 @@ if test $RC != 0 ; then
        exit $RC
 fi
 
+echo "Testing ldapwhoami as ${MANAGERDN} for anonymous..."
+$LDAPWHOAMI -h $LOCALHOST -p $PORT -D "$MANAGERDN" -w $PASSWD \
+       -e \!authzid=""
+
+RC=$?
+if test $RC != 0 ; then
+       echo "ldapwhoami failed ($RC)!"
+       kill -HUP $PID
+       exit $RC
+fi
+
+echo "Testing ldapwhoami as ${MANAGERDN} for dn:$BABSDN..."
+$LDAPWHOAMI -h $LOCALHOST -p $PORT -D "$MANAGERDN" -w $PASSWD \
+       -e \!authzid="dn:$BABSDN"
+
+RC=$?
+if test $RC != 0 ; then
+       echo "ldapwhoami failed ($RC)!"
+#      kill -HUP $PID
+#      exit $RC
+fi
+
+echo "Testing ldapwhoami as ${MANAGERDN} for u:ursula..."
+$LDAPWHOAMI -h $LOCALHOST -p $PORT -D "$MANAGERDN" -w $PASSWD \
+       -e \!authzid="u:ursula"
+
+RC=$?
+if test $RC != 0 ; then
+       echo "ldapwhoami failed ($RC)!"
+#      kill -HUP $PID
+#      exit $RC
+fi
+
 kill -HUP $PID
 
 echo ">>>>> Test succeeded"