From da76c1951e4176398b603daff550cb7a2dd7607b Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Tue, 3 Dec 2002 06:11:32 +0000 Subject: [PATCH] First-cut proxy authorization support. --- clients/tools/ldapcompare.c | 2 +- clients/tools/ldapdelete.c | 2 +- clients/tools/ldapmodify.c | 2 +- clients/tools/ldapmodrdn.c | 2 +- clients/tools/ldappasswd.c | 2 +- clients/tools/ldapsearch.c | 2 +- clients/tools/ldapwhoami.c | 2 +- include/ldap.h | 3 +- libraries/libldap/error.c | 1 + servers/slapd/config.c | 2 - servers/slapd/controls.c | 187 ++++++++++--- servers/slapd/extended.c | 2 + servers/slapd/proto-slap.h | 3 + servers/slapd/result.c | 5 +- servers/slapd/sasl.c | 514 +++++++++++++++++------------------ servers/slapd/saslauthz.c | 216 +++++++-------- servers/slapd/slap.h | 8 + servers/slapd/tools/mimic.c | 12 + tests/scripts/test014-whoami | 33 +++ 19 files changed, 587 insertions(+), 413 deletions(-) diff --git a/clients/tools/ldapcompare.c b/clients/tools/ldapcompare.c index 46917ac9f9..17040324dc 100644 --- a/clients/tools/ldapcompare.c +++ b/clients/tools/ldapcompare.c @@ -215,7 +215,7 @@ main( int argc, char **argv ) } assert( authzid == NULL ); - authzid = control; + authzid = cvalue; } else if ( strcasecmp( control, "manageDSAit" ) == 0 ) { if( manageDSAit ) { diff --git a/clients/tools/ldapdelete.c b/clients/tools/ldapdelete.c index e51c38461f..5095d9d424 100644 --- a/clients/tools/ldapdelete.c +++ b/clients/tools/ldapdelete.c @@ -214,7 +214,7 @@ main( int argc, char **argv ) } assert( authzid == NULL ); - authzid = control; + authzid = cvalue; } else if ( strcasecmp( control, "manageDSAit" ) == 0 ) { if( manageDSAit ) { diff --git a/clients/tools/ldapmodify.c b/clients/tools/ldapmodify.c index 00c1899905..73e9069eba 100644 --- a/clients/tools/ldapmodify.c +++ b/clients/tools/ldapmodify.c @@ -278,7 +278,7 @@ main( int argc, char **argv ) } assert( authzid == NULL ); - authzid = control; + authzid = cvalue; } else if ( strcasecmp( control, "manageDSAit" ) == 0 ) { if( manageDSAit ) { diff --git a/clients/tools/ldapmodrdn.c b/clients/tools/ldapmodrdn.c index 3d18b92618..6f09348f73 100644 --- a/clients/tools/ldapmodrdn.c +++ b/clients/tools/ldapmodrdn.c @@ -234,7 +234,7 @@ main(int argc, char **argv) } assert( authzid == NULL ); - authzid = control; + authzid = cvalue; } else if ( strcasecmp( control, "manageDSAit" ) == 0 ) { if( manageDSAit ) { diff --git a/clients/tools/ldappasswd.c b/clients/tools/ldappasswd.c index dace530506..a86d6a1136 100644 --- a/clients/tools/ldappasswd.c +++ b/clients/tools/ldappasswd.c @@ -234,7 +234,7 @@ main( int argc, char *argv[] ) } assert( authzid == NULL ); - authzid = control; + authzid = cvalue; } else if ( strcasecmp( control, "manageDSAit" ) == 0 ) { if( manageDSAit ) { diff --git a/clients/tools/ldapsearch.c b/clients/tools/ldapsearch.c index b26778a268..d1a0bd471a 100644 --- a/clients/tools/ldapsearch.c +++ b/clients/tools/ldapsearch.c @@ -471,7 +471,7 @@ main( int argc, char **argv ) } assert( authzid == NULL ); - authzid = control; + authzid = cvalue; } else if ( strcasecmp( control, "manageDSAit" ) == 0 ) { if( manageDSAit ) { diff --git a/clients/tools/ldapwhoami.c b/clients/tools/ldapwhoami.c index 12dda6f000..5e2736f9f8 100644 --- a/clients/tools/ldapwhoami.c +++ b/clients/tools/ldapwhoami.c @@ -190,7 +190,7 @@ main( int argc, char *argv[] ) } assert( authzid == NULL ); - authzid = control; + authzid = cvalue; } else if ( strcasecmp( control, "manageDSAit" ) == 0 ) { if( manageDSAit ) { diff --git a/include/ldap.h b/include/ldap.h index e8b63f48c4..09019f507c 100644 --- a/include/ldap.h +++ b/include/ldap.h @@ -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 diff --git a/libraries/libldap/error.c b/libraries/libldap/error.c index 7aa9d46667..839d8c3e3e 100644 --- a/libraries/libldap/error.c +++ b/libraries/libldap/error.c @@ -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" }, diff --git a/servers/slapd/config.c b/servers/slapd/config.c index f6225eeff2..45616ae406 100644 --- a/servers/slapd/config.c +++ b/servers/slapd/config.c @@ -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; diff --git a/servers/slapd/controls.c b/servers/slapd/controls.c index 1021d267d9..736b5f8448 100644 --- a/servers/slapd/controls.c +++ b/servers/slapd/controls.c @@ -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 */ +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; } diff --git a/servers/slapd/extended.c b/servers/slapd/extended.c index 0da22bdfbb..dfff66d4d7 100644 --- a/servers/slapd/extended.c +++ b/servers/slapd/extended.c @@ -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 ) { diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index bb574abeec..0085f5f8d6 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -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 diff --git a/servers/slapd/result.c b/servers/slapd/result.c index 4cfd8f1e2b..703947b8d7 100644 --- a/servers/slapd/result.c +++ b/servers/slapd/result.c @@ -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; diff --git a/servers/slapd/sasl.c b/servers/slapd/sasl.c index 876d7d99b5..c97c144321 100644 --- a/servers/slapd/sasl.c +++ b/servers/slapd/sasl.c @@ -15,31 +15,28 @@ #include "slap.h" -#ifdef HAVE_CYRUS_SASL #include -#ifdef HAVE_SASL_SASL_H -#include -#else -#include -#endif +#ifdef HAVE_CYRUS_SASL +# ifdef HAVE_SASL_SASL_H +# include +# else +# include +# endif + +# if SASL_VERSION_MAJOR >= 2 +# include +# define SASL_CONST const +# else +# define SASL_CONST +# endif -#include -#if SASL_VERSION_MAJOR >= 2 -#include -#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 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 \" line\n", - fname, lineno, 0 ); + "%s: line %d: missing policy in" + " \"sasl-authz-policy \" line\n", + fname, lineno, 0 ); #else Debug( LDAP_DEBUG_ANY, - "%s: line %d: missing policy in \"sasl-authz-policy \" line\n", + "%s: line %d: missing policy in" + " \"sasl-authz-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 \"\n", + fname, lineno, 0 ); +#else + Debug( LDAP_DEBUG_ANY, + "%s: line %d: need 2 args in " + "\"saslregexp \"\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 \" line\n", - fname, lineno, 0 ); + "%s: line %d: missing host in \"sasl-host \" line\n", + fname, lineno, 0 ); #else Debug( LDAP_DEBUG_ANY, - "%s: line %d: missing host in \"sasl-host \" line\n", + "%s: line %d: missing host in \"sasl-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 \" line.\n", - fname, lineno, 0 ); + LDAP_LOG( CONFIG, CRIT, "%s: line %d: " + "missing realm in \"sasl-realm \" line.\n", + fname, lineno, 0 ); #else - Debug( LDAP_DEBUG_ANY, - "%s: line %d: missing realm in \"sasl-realm \" line\n", + Debug( LDAP_DEBUG_ANY, "%s: line %d: " + "missing realm in \"sasl-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 \"\n", - fname, lineno, 0 ); -#else - Debug( LDAP_DEBUG_ANY, - "%s: line %d: need 2 args in \"saslregexp \"\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 \" line\n", - fname, lineno, 0 ); + LDAP_LOG( CONFIG, CRIT, "%s: line %d: " + "missing flags in \"sasl-secprops \" line\n", + fname, lineno, 0 ); #else - Debug( LDAP_DEBUG_ANY, - "%s: line %d: missing flags in \"sasl-secprops \" line\n", + Debug( LDAP_DEBUG_ANY, "%s: line %d: " + "missing flags in \"sasl-secprops \" 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 : "") : "NULL", 0 ); -#else - Debug( LDAP_DEBUG_ARGS, "slap_sasl_getdn: id=%s\n", - id?(*id?id:""):"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: 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 : "") : "NULL", 0 ); +#else + Debug( LDAP_DEBUG_ARGS, "slap_sasl_getdn: id=%s\n", + id?(*id?id:""):"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: 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 ); +} diff --git a/servers/slapd/saslauthz.c b/servers/slapd/saslauthz.c index 24ccf062b4..8fdf1ca604 100644 --- a/servers/slapd/saslauthz.c +++ b/servers/slapd/saslauthz.c @@ -23,15 +23,8 @@ #include "slap.h" -#ifdef HAVE_CYRUS_SASL #include -#ifdef HAVE_SASL_SASL_H -#include -#else -#include -#endif - #include #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, ®out ) ) { - goto FINISHED; - } - - rc = slap_parseURI( ®out, &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 : "", 0, 0 ); -#else - Debug( LDAP_DEBUG_TRACE, "<==slap_sasl2dn: Converted SASL name to %s\n", - sasldn->bv_len ? sasldn->bv_val : "", 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, ®out ) ) { + goto FINISHED; + } + + rc = slap_parseURI( ®out, &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 : "", 0, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, "<==slap_sasl2dn: Converted SASL name to %s\n", + sasldn->bv_len ? sasldn->bv_val : "", 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 ); diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 7e33a378ad..af09fec6d6 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -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; diff --git a/servers/slapd/tools/mimic.c b/servers/slapd/tools/mimic.c index 375a6706b2..70f87c3ddd 100644 --- a/servers/slapd/tools/mimic.c +++ b/servers/slapd/tools/mimic.c @@ -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; +} + diff --git a/tests/scripts/test014-whoami b/tests/scripts/test014-whoami index b6aea511cc..219bce52e7 100755 --- a/tests/scripts/test014-whoami +++ b/tests/scripts/test014-whoami @@ -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" -- 2.39.5