]> git.sur5r.net Git - openldap/commitdiff
reflect Kurt's comments on ID assertion
authorPierangelo Masarati <ando@openldap.org>
Fri, 14 May 2004 10:01:22 +0000 (10:01 +0000)
committerPierangelo Masarati <ando@openldap.org>
Fri, 14 May 2004 10:01:22 +0000 (10:01 +0000)
doc/man/man5/slapd-ldap.5
servers/slapd/back-ldap/back-ldap.h
servers/slapd/back-ldap/bind.c
servers/slapd/back-ldap/config.c
servers/slapd/back-ldap/init.c

index 265b1282700ef43068db65160e335d9064105cc6..4f232b977f70ffa6904a5715e401fcefad5d6406 100644 (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
index 11ce343af499b70403c29e75e356681864c94839..96e8ef5af452b290d1f9434703c804c14c9aa1fd 100644 (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 */
index a4ea5e909222a1517462e2006e2581a24bdba742..26e94c62c04638c2aed4bc36e2c03c1a0d0b10f0 100644 (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++ ) {
index d7cc0b2b1464788d89a3c791636259632f0a36a2..b83405e244349977c8d387ff68eef914ec69f9e0 100644 (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;
                        }
                }
 
index a5492e954a2fecd38b65b39efaa9f7f2260c2a91..4645b5195e461c4fc12026c2ba97fe2fe69ac31b 100644 (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) {