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>
Password used with the proxy authzDN above.
.TP
.B idassert-mode {none|anonymous|self|proxyid|<dn>}
defines what type of identity assertion is used.
.B idassert-mode <mode>
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
.BR none ,
which implies that the proxy will bind as itself and assert the user's
identity only when a user is bound.
Other values are
.BR legacy ,
which implies that the proxy will bind as
.I proxyauthzdn
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
and
.BR self ,
which respectively mean that the empty or the client's identity
will be asserted,
.BR proxyid ,
which means that no proxyAuthz control will be used, so the proxyauthzdn
which respectively mean that the
.I empty
or the
.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.
Moreover, if a valid DN is used as
Moreover, if a string prefixed with
.B u:
or
.B dn:
is used as
.BR <mode> ,
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
.B idassert-authz <authz>
if defined, selects what
.I local
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
.B proxy-whoami
Turns on proxying of the WhoAmI extended operation. If this option is

View File

@ -94,12 +94,13 @@ struct ldapinfo {
/* ID assert stuff */
int idassert_mode;
#define LDAP_BACK_IDASSERT_NONE 0
#define LDAP_BACK_IDASSERT_PROXYID 1
#define LDAP_BACK_IDASSERT_LEGACY 0
#define LDAP_BACK_IDASSERT_NOASSERT 1
#define LDAP_BACK_IDASSERT_ANONYMOUS 2
#define LDAP_BACK_IDASSERT_SELF 3
#define LDAP_BACK_IDASSERT_OTHER 4
struct berval idassert_dn;
#define LDAP_BACK_IDASSERT_OTHERDN 4
#define LDAP_BACK_IDASSERT_OTHERID 5
struct berval idassert_id;
BerVarray idassert_authz;
/* end of ID assert stuff */
#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 );
if ( !lc->bound ) {
#ifdef LDAP_BACK_PROXY_AUTHZ
int gotit = 0;
#if 0
/*
* FIXME: we need to let clients use proxyAuthz
* 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
* control to be provided with Bind requests
*/
gotit = op->o_proxy_authz;
#endif
/*
* if no bind took place yet, but the connection is bound
* 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,
* or if the client's identity is authorized */
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 )
&& !BER_BVISNULL( &li->proxyauthzdn ) && !BER_BVISEMPTY( &li->proxyauthzdn )
&& !gotit ) {
&& !BER_BVISNULL( &li->proxyauthzdn ) && !BER_BVISEMPTY( &li->proxyauthzdn ) )
{
binddn = li->proxyauthzdn;
bindcred = li->proxyauthzpw;
}
@ -425,10 +420,12 @@ ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs )
if ( li->idassert_authz ) {
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 );
if ( rc != LDAP_SUCCESS ) {
break;
if ( rs->sr_err != LDAP_SUCCESS ) {
send_ldap_result( op, rs );
lc->bound = 0;
goto done;
}
}
binddn = li->proxyauthzdn;
@ -451,6 +448,8 @@ ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs )
lc->bound = 1;
}
}
done:;
rc = lc->bound;
ldap_pvt_thread_mutex_unlock( &lc->lc_mutex );
return rc;
@ -636,7 +635,7 @@ ldap_back_proxy_authz_ctrl(
struct ldapinfo *li = (struct ldapinfo *) op->o_bd->be_private;
LDAPControl **ctrls = NULL;
int i = 0;
struct berval assertedDN;
struct berval assertedID;
*pctrls = NULL;
@ -648,7 +647,7 @@ ldap_back_proxy_authz_ctrl(
goto done;
}
if ( li->idassert_mode == LDAP_BACK_IDASSERT_NONE ) {
if ( li->idassert_mode == LDAP_BACK_IDASSERT_LEGACY ) {
if ( op->o_proxy_authz ) {
/*
* FIXME: we do not want to perform proxyAuthz
@ -694,33 +693,34 @@ ldap_back_proxy_authz_ctrl(
}
switch ( li->idassert_mode ) {
case LDAP_BACK_IDASSERT_NONE:
case LDAP_BACK_IDASSERT_LEGACY:
case LDAP_BACK_IDASSERT_SELF:
/* original behavior:
* assert the client's identity */
assertedDN = op->o_conn->c_dn;
assertedID = op->o_conn->c_dn;
break;
case LDAP_BACK_IDASSERT_ANONYMOUS:
/* assert "anonymous" */
assertedDN = slap_empty_bv;
assertedID = slap_empty_bv;
break;
case LDAP_BACK_IDASSERT_PROXYID:
case LDAP_BACK_IDASSERT_NOASSERT:
/* don't assert; bind as proxyauthzdn */
goto done;
case LDAP_BACK_IDASSERT_OTHER:
case LDAP_BACK_IDASSERT_OTHERID:
case LDAP_BACK_IDASSERT_OTHERDN:
/* assert idassert DN */
assertedDN = li->idassert_dn;
assertedID = li->idassert_id;
break;
default:
assert( 0 );
}
if ( BER_BVISNULL( &assertedDN ) ) {
assertedDN = slap_empty_bv;
if ( BER_BVISNULL( &assertedID ) ) {
assertedID = slap_empty_bv;
}
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_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 );
AC_MEMCPY( ctrls[ 0 ]->ldctl_value.bv_val, "dn:", STRLENOF( "dn:" ) );
AC_MEMCPY( ctrls[ 0 ]->ldctl_value.bv_val + STRLENOF( "dn:" ),
assertedDN.bv_val, assertedDN.bv_len );
ctrls[ 0 ]->ldctl_value.bv_val[ ctrls[ 0 ]->ldctl_value.bv_len ] = '\0';
/* already in u:ID form */
if ( li->idassert_mode == LDAP_BACK_IDASSERT_OTHERID ) {
ber_dupbv( &ctrls[ 0 ]->ldctl_value, &assertedID );
/* 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 ) {
for ( i = 0; op->o_ctrls[ i ]; i++ ) {

View File

@ -687,9 +687,9 @@ parse_idassert(
return 1;
}
if ( strcasecmp( argv[1], "none" ) == 0 ) {
if ( strcasecmp( argv[1], "legacy" ) == 0 ) {
/* 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 ) {
/* will proxyAuthz as client's identity */
@ -699,31 +699,45 @@ parse_idassert(
/* will proxyAuthz as 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 */
li->idassert_mode = LDAP_BACK_IDASSERT_PROXYID;
li->idassert_mode = LDAP_BACK_IDASSERT_NOASSERT;
} else {
struct berval dn;
struct berval id;
int rc;
/* will proxyAuthz as argv[1] */
li->idassert_mode = LDAP_BACK_IDASSERT_OTHER;
ber_str2bv( argv[1], 0, 0, &dn );
ber_str2bv( argv[1], 0, 0, &id );
rc = dnNormalize( 0, NULL, NULL, &dn, &li->idassert_dn, NULL );
if ( rc != LDAP_SUCCESS ) {
if ( strncasecmp( id.bv_val, "u:", STRLENOF( "u:" ) ) == 0 ) {
/* 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
LDAP_LOG( CONFIG, CRIT,
"%s: line %d: idassert DN \"%s\" is invalid.\n",
fname, lineno, argv[1] );
LDAP_LOG( CONFIG, CRIT,
"%s: line %d: idassert ID \"%s\" is not a valid DN.\n",
fname, lineno, argv[1] );
#else
Debug( LDAP_DEBUG_ANY,
"%s: line %d: idassert DN \"%s\" is invalid\n",
fname, lineno, argv[1] );
Debug( LDAP_DEBUG_ANY,
"%s: line %d: idassert ID \"%s\" is not a valid DN\n",
fname, lineno, argv[1] );
#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->proxyauthzpw );
li->idassert_mode = LDAP_BACK_IDASSERT_NONE;
BER_BVZERO( &li->idassert_dn );
li->idassert_mode = LDAP_BACK_IDASSERT_LEGACY;
BER_BVZERO( &li->idassert_id );
#endif /* LDAP_BACK_PROXY_AUTHZ */
#ifdef ENABLE_REWRITE
@ -217,9 +217,9 @@ ldap_back_db_destroy(
ch_free( li->proxyauthzpw.bv_val );
BER_BVZERO( &li->proxyauthzpw );
}
if ( !BER_BVISNULL( &li->idassert_dn ) ) {
ch_free( li->idassert_dn.bv_val );
BER_BVZERO( &li->idassert_dn );
if ( !BER_BVISNULL( &li->idassert_id ) ) {
ch_free( li->idassert_id.bv_val );
BER_BVZERO( &li->idassert_id );
}
#endif /* LDAP_BACK_PROXY_AUTHZ */
if (li->conntree) {