mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-04-18 15:20:35 +08:00
First-cut proxy authorization support.
This commit is contained in:
parent
9ba95dd027
commit
da76c1951e
@ -215,7 +215,7 @@ main( int argc, char **argv )
|
||||
}
|
||||
|
||||
assert( authzid == NULL );
|
||||
authzid = control;
|
||||
authzid = cvalue;
|
||||
|
||||
} else if ( strcasecmp( control, "manageDSAit" ) == 0 ) {
|
||||
if( manageDSAit ) {
|
||||
|
@ -214,7 +214,7 @@ main( int argc, char **argv )
|
||||
}
|
||||
|
||||
assert( authzid == NULL );
|
||||
authzid = control;
|
||||
authzid = cvalue;
|
||||
|
||||
} else if ( strcasecmp( control, "manageDSAit" ) == 0 ) {
|
||||
if( manageDSAit ) {
|
||||
|
@ -278,7 +278,7 @@ main( int argc, char **argv )
|
||||
}
|
||||
|
||||
assert( authzid == NULL );
|
||||
authzid = control;
|
||||
authzid = cvalue;
|
||||
|
||||
} else if ( strcasecmp( control, "manageDSAit" ) == 0 ) {
|
||||
if( manageDSAit ) {
|
||||
|
@ -234,7 +234,7 @@ main(int argc, char **argv)
|
||||
}
|
||||
|
||||
assert( authzid == NULL );
|
||||
authzid = control;
|
||||
authzid = cvalue;
|
||||
|
||||
} else if ( strcasecmp( control, "manageDSAit" ) == 0 ) {
|
||||
if( manageDSAit ) {
|
||||
|
@ -234,7 +234,7 @@ main( int argc, char *argv[] )
|
||||
}
|
||||
|
||||
assert( authzid == NULL );
|
||||
authzid = control;
|
||||
authzid = cvalue;
|
||||
|
||||
} else if ( strcasecmp( control, "manageDSAit" ) == 0 ) {
|
||||
if( manageDSAit ) {
|
||||
|
@ -471,7 +471,7 @@ main( int argc, char **argv )
|
||||
}
|
||||
|
||||
assert( authzid == NULL );
|
||||
authzid = control;
|
||||
authzid = cvalue;
|
||||
|
||||
} else if ( strcasecmp( control, "manageDSAit" ) == 0 ) {
|
||||
if( manageDSAit ) {
|
||||
|
@ -190,7 +190,7 @@ main( int argc, char *argv[] )
|
||||
}
|
||||
|
||||
assert( authzid == NULL );
|
||||
authzid = control;
|
||||
authzid = cvalue;
|
||||
|
||||
} else if ( strcasecmp( control, "manageDSAit" ) == 0 ) {
|
||||
if( manageDSAit ) {
|
||||
|
@ -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
|
||||
|
@ -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" },
|
||||
|
@ -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;
|
||||
|
@ -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";
|
||||
int rc;
|
||||
struct berval dn;
|
||||
|
||||
if ( op->o_proxy_authz != SLAP_NO_CONTROL ) {
|
||||
*text = "proxy authorization 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
|
||||
op->o_proxy_authz = ctrl->ldctl_iscritical
|
||||
? SLAP_CRITICAL_CONTROL
|
||||
: SLAP_NONCRITICAL_CONTROL;
|
||||
|
||||
op->o_subentries_visibility = (ctrl->ldctl_value.bv_val[2] != 0x00);
|
||||
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
#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
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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 ) {
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -15,31 +15,28 @@
|
||||
|
||||
#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
|
||||
|
||||
#include <lutil.h>
|
||||
#if SASL_VERSION_MAJOR >= 2
|
||||
#include <sasl/saslplug.h>
|
||||
#define SASL_CONST const
|
||||
#else
|
||||
#define SASL_CONST
|
||||
#endif
|
||||
# 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 );
|
||||
}
|
||||
|
@ -23,15 +23,8 @@
|
||||
|
||||
#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, ®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 : "<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, ®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 : "<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 );
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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"
|
||||
|
Loading…
x
Reference in New Issue
Block a user