From: Pierangelo Masarati Date: Fri, 14 May 2004 10:01:22 +0000 (+0000) Subject: reflect Kurt's comments on ID assertion X-Git-Tag: OPENDLAP_REL_ENG_2_2_MP~371 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=8b954144d612e78da4c8c815007717fc9781cab6;p=openldap reflect Kurt's comments on ID assertion --- diff --git a/doc/man/man5/slapd-ldap.5 b/doc/man/man5/slapd-ldap.5 index 265b128270..4f232b977f 100644 --- a/doc/man/man5/slapd-ldap.5 +++ b/doc/man/man5/slapd-ldap.5 @@ -98,29 +98,81 @@ their usage. .B proxyauthzpw Password used with the proxy authzDN above. .TP -.B idassert-mode {none|anonymous|self|proxyid|} -defines what type of identity assertion is used. +.B idassert-mode +defines what type of +.I identity assertion +is used. +The supported modes are: +.RS +.RS +.TP +.B ={legacy|anonymous|self|none|} +.RE +.RS +.B ={u:|[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 . +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 , 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 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 diff --git a/servers/slapd/back-ldap/back-ldap.h b/servers/slapd/back-ldap/back-ldap.h index 11ce343af4..96e8ef5af4 100644 --- a/servers/slapd/back-ldap/back-ldap.h +++ b/servers/slapd/back-ldap/back-ldap.h @@ -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 */ diff --git a/servers/slapd/back-ldap/bind.c b/servers/slapd/back-ldap/bind.c index a4ea5e9092..26e94c62c0 100644 --- a/servers/slapd/back-ldap/bind.c +++ b/servers/slapd/back-ldap/bind.c @@ -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++ ) { diff --git a/servers/slapd/back-ldap/config.c b/servers/slapd/back-ldap/config.c index d7cc0b2b14..b83405e244 100644 --- a/servers/slapd/back-ldap/config.c +++ b/servers/slapd/back-ldap/config.c @@ -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; } } diff --git a/servers/slapd/back-ldap/init.c b/servers/slapd/back-ldap/init.c index a5492e954a..4645b5195e 100644 --- a/servers/slapd/back-ldap/init.c +++ b/servers/slapd/back-ldap/init.c @@ -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) {