reflect Kurt's comments on ID assertion

This commit is contained in:
Pierangelo Masarati 2004-05-14 10:01:22 +00:00
parent 9da35acf44
commit 8b954144d6
5 changed files with 138 additions and 64 deletions

View File

@ -98,29 +98,81 @@ their usage.
.B proxyauthzpw <password> .B proxyauthzpw <password>
Password used with the proxy authzDN above. Password used with the proxy authzDN above.
.TP .TP
.B idassert-mode {none|anonymous|self|proxyid|<dn>} .B idassert-mode <mode>
defines what type of identity assertion is used. defines what type of
.I identity assertion
is used.
The supported modes are:
.RS
.RS
.TP
.B <mode>={legacy|anonymous|self|none|<id>}
.RE
.RS
.B <id>={u:<ID>|[dn:]<DN>}
.RE
The default is The default is
.BR none , .BR legacy ,
which implies that the proxy will bind as itself and assert the user's which implies that the proxy will bind as
identity only when a user is bound. .I proxyauthzdn
Other values are and assert the client's identity when it is not anonymous.
Direct binds are always proxied.
The other modes imply that the proxy will always bind as
.IR proxyauthzdn ,
unless restricted by
.BR idassert-authz
rules (see below), in which case the operation will fail;
eventually, it will assert some other identity according to
.BR <mode> .
Other identity assertion modes are
.BR anonymous .BR anonymous
and and
.BR self , .BR self ,
which respectively mean that the empty or the client's identity which respectively mean that the
will be asserted, .I empty
.BR proxyid , or the
which means that no proxyAuthz control will be used, so the proxyauthzdn .IR client 's
identity
will be asserted;
.BR none ,
which means that no proxyAuthz control will be used, so the
.I proxyauthzdn
identity will be asserted. identity will be asserted.
Moreover, if a valid DN is used as Moreover, if a string prefixed with
.B u:
or
.B dn:
is used as
.BR <mode> , .BR <mode> ,
that identity will be asserted. that identity will be asserted.
Ths string is also treated as a DN if it is not prefixed
by any recognized type indicator. Whether or not the
.B dn:
prefix is present, the string must pass DN validation and normalization.
For all modes that require the use of the
.I proxyAuthz
control, on the remote server the proxy identity must have appropriate
.I authzTo
permissions, or the asserted identities must have appropriate
.I authzFrom
permissions. Note, however, that the ID assertion feature is mostly
useful when the asserted identities do not exist on the remote server.
.TP .TP
.B idassert-authz <authz> .B idassert-authz <authz>
if defined, selects what if defined, selects what
.I local .I local
identities are authorized to exploit the identity assertion feature. identities are authorized to exploit the identity assertion feature.
The string
.B authz
follows the rules defined for the
.I authzFrom
attribute.
See
.BR slapd.conf (5),
section related to
.BR authz-policy ,
for details on the supported syntaxes.
.TP .TP
.B proxy-whoami .B proxy-whoami
Turns on proxying of the WhoAmI extended operation. If this option is Turns on proxying of the WhoAmI extended operation. If this option is

View File

@ -94,12 +94,13 @@ struct ldapinfo {
/* ID assert stuff */ /* ID assert stuff */
int idassert_mode; int idassert_mode;
#define LDAP_BACK_IDASSERT_NONE 0 #define LDAP_BACK_IDASSERT_LEGACY 0
#define LDAP_BACK_IDASSERT_PROXYID 1 #define LDAP_BACK_IDASSERT_NOASSERT 1
#define LDAP_BACK_IDASSERT_ANONYMOUS 2 #define LDAP_BACK_IDASSERT_ANONYMOUS 2
#define LDAP_BACK_IDASSERT_SELF 3 #define LDAP_BACK_IDASSERT_SELF 3
#define LDAP_BACK_IDASSERT_OTHER 4 #define LDAP_BACK_IDASSERT_OTHERDN 4
struct berval idassert_dn; #define LDAP_BACK_IDASSERT_OTHERID 5
struct berval idassert_id;
BerVarray idassert_authz; BerVarray idassert_authz;
/* end of ID assert stuff */ /* end of ID assert stuff */
#endif /* LDAP_BACK_PROXY_AUTHZ */ #endif /* LDAP_BACK_PROXY_AUTHZ */

View File

@ -380,8 +380,6 @@ ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs )
ldap_pvt_thread_mutex_lock( &lc->lc_mutex ); ldap_pvt_thread_mutex_lock( &lc->lc_mutex );
if ( !lc->bound ) { if ( !lc->bound ) {
#ifdef LDAP_BACK_PROXY_AUTHZ #ifdef LDAP_BACK_PROXY_AUTHZ
int gotit = 0;
#if 0
/* /*
* FIXME: we need to let clients use proxyAuthz * FIXME: we need to let clients use proxyAuthz
* otherwise we cannot do symmetric pools of servers; * otherwise we cannot do symmetric pools of servers;
@ -394,9 +392,6 @@ ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs )
* and implementation do not allow proxy authorization * and implementation do not allow proxy authorization
* control to be provided with Bind requests * control to be provided with Bind requests
*/ */
gotit = op->o_proxy_authz;
#endif
/* /*
* if no bind took place yet, but the connection is bound * if no bind took place yet, but the connection is bound
* and the "proxyauthzdn" is set, then bind as * and the "proxyauthzdn" is set, then bind as
@ -412,10 +407,10 @@ ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs )
/* bind as proxyauthzdn only if no idassert mode is requested, /* bind as proxyauthzdn only if no idassert mode is requested,
* or if the client's identity is authorized */ * or if the client's identity is authorized */
switch ( li->idassert_mode ) { switch ( li->idassert_mode ) {
case LDAP_BACK_IDASSERT_NONE: case LDAP_BACK_IDASSERT_LEGACY:
if ( !BER_BVISNULL( &op->o_conn->c_dn ) && !BER_BVISEMPTY( &op->o_conn->c_dn ) if ( !BER_BVISNULL( &op->o_conn->c_dn ) && !BER_BVISEMPTY( &op->o_conn->c_dn )
&& !BER_BVISNULL( &li->proxyauthzdn ) && !BER_BVISEMPTY( &li->proxyauthzdn ) && !BER_BVISNULL( &li->proxyauthzdn ) && !BER_BVISEMPTY( &li->proxyauthzdn ) )
&& !gotit ) { {
binddn = li->proxyauthzdn; binddn = li->proxyauthzdn;
bindcred = li->proxyauthzpw; bindcred = li->proxyauthzpw;
} }
@ -425,10 +420,12 @@ ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs )
if ( li->idassert_authz ) { if ( li->idassert_authz ) {
struct berval authcDN = BER_BVISNULL( &op->o_conn->c_dn ) ? slap_empty_bv : op->o_conn->c_dn; struct berval authcDN = BER_BVISNULL( &op->o_conn->c_dn ) ? slap_empty_bv : op->o_conn->c_dn;
rc = slap_sasl_matches( op, li->idassert_authz, rs->sr_err = slap_sasl_matches( op, li->idassert_authz,
&authcDN, &authcDN ); &authcDN, &authcDN );
if ( rc != LDAP_SUCCESS ) { if ( rs->sr_err != LDAP_SUCCESS ) {
break; send_ldap_result( op, rs );
lc->bound = 0;
goto done;
} }
} }
binddn = li->proxyauthzdn; binddn = li->proxyauthzdn;
@ -451,6 +448,8 @@ ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs )
lc->bound = 1; lc->bound = 1;
} }
} }
done:;
rc = lc->bound; rc = lc->bound;
ldap_pvt_thread_mutex_unlock( &lc->lc_mutex ); ldap_pvt_thread_mutex_unlock( &lc->lc_mutex );
return rc; return rc;
@ -636,7 +635,7 @@ ldap_back_proxy_authz_ctrl(
struct ldapinfo *li = (struct ldapinfo *) op->o_bd->be_private; struct ldapinfo *li = (struct ldapinfo *) op->o_bd->be_private;
LDAPControl **ctrls = NULL; LDAPControl **ctrls = NULL;
int i = 0; int i = 0;
struct berval assertedDN; struct berval assertedID;
*pctrls = NULL; *pctrls = NULL;
@ -648,7 +647,7 @@ ldap_back_proxy_authz_ctrl(
goto done; goto done;
} }
if ( li->idassert_mode == LDAP_BACK_IDASSERT_NONE ) { if ( li->idassert_mode == LDAP_BACK_IDASSERT_LEGACY ) {
if ( op->o_proxy_authz ) { if ( op->o_proxy_authz ) {
/* /*
* FIXME: we do not want to perform proxyAuthz * FIXME: we do not want to perform proxyAuthz
@ -694,33 +693,34 @@ ldap_back_proxy_authz_ctrl(
} }
switch ( li->idassert_mode ) { switch ( li->idassert_mode ) {
case LDAP_BACK_IDASSERT_NONE: case LDAP_BACK_IDASSERT_LEGACY:
case LDAP_BACK_IDASSERT_SELF: case LDAP_BACK_IDASSERT_SELF:
/* original behavior: /* original behavior:
* assert the client's identity */ * assert the client's identity */
assertedDN = op->o_conn->c_dn; assertedID = op->o_conn->c_dn;
break; break;
case LDAP_BACK_IDASSERT_ANONYMOUS: case LDAP_BACK_IDASSERT_ANONYMOUS:
/* assert "anonymous" */ /* assert "anonymous" */
assertedDN = slap_empty_bv; assertedID = slap_empty_bv;
break; break;
case LDAP_BACK_IDASSERT_PROXYID: case LDAP_BACK_IDASSERT_NOASSERT:
/* don't assert; bind as proxyauthzdn */ /* don't assert; bind as proxyauthzdn */
goto done; goto done;
case LDAP_BACK_IDASSERT_OTHER: case LDAP_BACK_IDASSERT_OTHERID:
case LDAP_BACK_IDASSERT_OTHERDN:
/* assert idassert DN */ /* assert idassert DN */
assertedDN = li->idassert_dn; assertedID = li->idassert_id;
break; break;
default: default:
assert( 0 ); assert( 0 );
} }
if ( BER_BVISNULL( &assertedDN ) ) { if ( BER_BVISNULL( &assertedID ) ) {
assertedDN = slap_empty_bv; assertedID = slap_empty_bv;
} }
ctrls = ch_malloc( sizeof( LDAPControl * ) * (i + 2) ); ctrls = ch_malloc( sizeof( LDAPControl * ) * (i + 2) );
@ -728,12 +728,19 @@ ldap_back_proxy_authz_ctrl(
ctrls[ 0 ]->ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ; ctrls[ 0 ]->ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ;
ctrls[ 0 ]->ldctl_iscritical = 1; ctrls[ 0 ]->ldctl_iscritical = 1;
ctrls[ 0 ]->ldctl_value.bv_len = assertedDN.bv_len + STRLENOF( "dn:" );
ctrls[ 0 ]->ldctl_value.bv_val = ch_malloc( ctrls[ 0 ]->ldctl_value.bv_len + 1 ); /* already in u:ID form */
AC_MEMCPY( ctrls[ 0 ]->ldctl_value.bv_val, "dn:", STRLENOF( "dn:" ) ); if ( li->idassert_mode == LDAP_BACK_IDASSERT_OTHERID ) {
AC_MEMCPY( ctrls[ 0 ]->ldctl_value.bv_val + STRLENOF( "dn:" ), ber_dupbv( &ctrls[ 0 ]->ldctl_value, &assertedID );
assertedDN.bv_val, assertedDN.bv_len );
ctrls[ 0 ]->ldctl_value.bv_val[ ctrls[ 0 ]->ldctl_value.bv_len ] = '\0'; /* needs the dn: prefix */
} else {
ctrls[ 0 ]->ldctl_value.bv_len = assertedID.bv_len + STRLENOF( "dn:" );
ctrls[ 0 ]->ldctl_value.bv_val = ch_malloc( ctrls[ 0 ]->ldctl_value.bv_len + 1 );
AC_MEMCPY( ctrls[ 0 ]->ldctl_value.bv_val, "dn:", STRLENOF( "dn:" ) );
AC_MEMCPY( ctrls[ 0 ]->ldctl_value.bv_val + STRLENOF( "dn:" ),
assertedID.bv_val, assertedID.bv_len + 1 );
}
if ( op->o_ctrls ) { if ( op->o_ctrls ) {
for ( i = 0; op->o_ctrls[ i ]; i++ ) { for ( i = 0; op->o_ctrls[ i ]; i++ ) {

View File

@ -687,9 +687,9 @@ parse_idassert(
return 1; return 1;
} }
if ( strcasecmp( argv[1], "none" ) == 0 ) { if ( strcasecmp( argv[1], "legacy" ) == 0 ) {
/* will proxyAuthz as client's identity only if bound */ /* will proxyAuthz as client's identity only if bound */
li->idassert_mode = LDAP_BACK_IDASSERT_NONE; li->idassert_mode = LDAP_BACK_IDASSERT_LEGACY;
} else if ( strcasecmp( argv[1], "self" ) == 0 ) { } else if ( strcasecmp( argv[1], "self" ) == 0 ) {
/* will proxyAuthz as client's identity */ /* will proxyAuthz as client's identity */
@ -699,31 +699,45 @@ parse_idassert(
/* will proxyAuthz as anonymous */ /* will proxyAuthz as anonymous */
li->idassert_mode = LDAP_BACK_IDASSERT_ANONYMOUS; li->idassert_mode = LDAP_BACK_IDASSERT_ANONYMOUS;
} else if ( strcasecmp( argv[1], "proxyid" ) == 0 ) { } else if ( strcasecmp( argv[1], "none" ) == 0 ) {
/* will not proxyAuthz */ /* will not proxyAuthz */
li->idassert_mode = LDAP_BACK_IDASSERT_PROXYID; li->idassert_mode = LDAP_BACK_IDASSERT_NOASSERT;
} else { } else {
struct berval dn; struct berval id;
int rc; int rc;
/* will proxyAuthz as argv[1] */ /* will proxyAuthz as argv[1] */
li->idassert_mode = LDAP_BACK_IDASSERT_OTHER; ber_str2bv( argv[1], 0, 0, &id );
ber_str2bv( argv[1], 0, 0, &dn );
rc = dnNormalize( 0, NULL, NULL, &dn, &li->idassert_dn, NULL ); if ( strncasecmp( id.bv_val, "u:", STRLENOF( "u:" ) ) == 0 ) {
if ( rc != LDAP_SUCCESS ) { /* force lowercase... */
id.bv_val[0] = 'u';
li->idassert_mode = LDAP_BACK_IDASSERT_OTHERID;
ber_dupbv( &li->idassert_id, &id );
} else {
/* default is DN? */
if ( strncasecmp( id.bv_val, "dn:", STRLENOF( "dn:" ) ) == 0 ) {
id.bv_val += STRLENOF( "dn:" );
id.bv_len -= STRLENOF( "dn:" );
}
rc = dnNormalize( 0, NULL, NULL, &id, &li->idassert_id, NULL );
if ( rc != LDAP_SUCCESS ) {
#ifdef NEW_LOGGING #ifdef NEW_LOGGING
LDAP_LOG( CONFIG, CRIT, LDAP_LOG( CONFIG, CRIT,
"%s: line %d: idassert DN \"%s\" is invalid.\n", "%s: line %d: idassert ID \"%s\" is not a valid DN.\n",
fname, lineno, argv[1] ); fname, lineno, argv[1] );
#else #else
Debug( LDAP_DEBUG_ANY, Debug( LDAP_DEBUG_ANY,
"%s: line %d: idassert DN \"%s\" is invalid\n", "%s: line %d: idassert ID \"%s\" is not a valid DN\n",
fname, lineno, argv[1] ); fname, lineno, argv[1] );
#endif #endif
return 1; return 1;
}
li->idassert_mode = LDAP_BACK_IDASSERT_OTHERDN;
} }
} }

View File

@ -105,8 +105,8 @@ ldap_back_db_init(
BER_BVZERO( &li->proxyauthzdn ); BER_BVZERO( &li->proxyauthzdn );
BER_BVZERO( &li->proxyauthzpw ); BER_BVZERO( &li->proxyauthzpw );
li->idassert_mode = LDAP_BACK_IDASSERT_NONE; li->idassert_mode = LDAP_BACK_IDASSERT_LEGACY;
BER_BVZERO( &li->idassert_dn ); BER_BVZERO( &li->idassert_id );
#endif /* LDAP_BACK_PROXY_AUTHZ */ #endif /* LDAP_BACK_PROXY_AUTHZ */
#ifdef ENABLE_REWRITE #ifdef ENABLE_REWRITE
@ -217,9 +217,9 @@ ldap_back_db_destroy(
ch_free( li->proxyauthzpw.bv_val ); ch_free( li->proxyauthzpw.bv_val );
BER_BVZERO( &li->proxyauthzpw ); BER_BVZERO( &li->proxyauthzpw );
} }
if ( !BER_BVISNULL( &li->idassert_dn ) ) { if ( !BER_BVISNULL( &li->idassert_id ) ) {
ch_free( li->idassert_dn.bv_val ); ch_free( li->idassert_id.bv_val );
BER_BVZERO( &li->idassert_dn ); BER_BVZERO( &li->idassert_id );
} }
#endif /* LDAP_BACK_PROXY_AUTHZ */ #endif /* LDAP_BACK_PROXY_AUTHZ */
if (li->conntree) { if (li->conntree) {