.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
/* 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 */
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;
* 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
/* 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;
}
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;
lc->bound = 1;
}
}
+
+done:;
rc = lc->bound;
ldap_pvt_thread_mutex_unlock( &lc->lc_mutex );
return rc;
struct ldapinfo *li = (struct ldapinfo *) op->o_bd->be_private;
LDAPControl **ctrls = NULL;
int i = 0;
- struct berval assertedDN;
+ struct berval assertedID;
*pctrls = NULL;
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
}
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) );
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++ ) {
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 */
/* 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;
}
}
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
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) {