]> git.sur5r.net Git - openldap/commitdiff
more on identity assertion
authorPierangelo Masarati <ando@openldap.org>
Sat, 22 May 2004 17:26:02 +0000 (17:26 +0000)
committerPierangelo Masarati <ando@openldap.org>
Sat, 22 May 2004 17:26:02 +0000 (17:26 +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
servers/slapd/back-ldap/search.c

index afff3fe073c95942c96059733777ce0e7b4d50fa..8449b9997a20cc07d03321f6c0a8f703848876ff 100644 (file)
@@ -77,14 +77,17 @@ The URI list is space- or comma-separated.
 .B server <hostport>
 Obsolete option; same as `uri ldap://<hostport>/'.
 .TP
-.B binddn "<administrative DN for access control purposes>"
+.B acl-authcDN "<administrative DN for access control purposes>"
 DN which is used to query the target server for acl checking; it
 should have read access on the target server to attributes used on the
 proxy for acl checking.
 There is no risk of giving away such values; they are only used to
 check permissions.
+.B The acl-authcDN identity is by no means implicitly used by the proxy 
+.B when the client connects anonymously, so it cannot be used to
+.B anonymously query Active Directory.
 .TP
-.B bindpw <password>
+.B acl-passwd <password>
 Password used with the bind DN above.
 .TP
 .B idassert-authcdn "<administrative DN for proxyAuthz purposes>"
@@ -94,7 +97,7 @@ belong to the DIT fragment that is being proxyied by back-ldap.
 This is useful when operations performed by users bound to another 
 backend are propagated through back-ldap.
 This requires the entry with 
-.B proxyauthzdn 
+.B idassert-authcdn
 identity on the remote server to have
 .B proxyAuthz
 privileges on a wide set of DNs, e.g.
@@ -130,11 +133,11 @@ The supported modes are:
 The default is 
 .BR legacy ,
 which implies that the proxy will bind as
-.I proxyauthzdn
+.I idassert-authcdn
 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 ,
+.IR idassert-authcdn ,
 unless restricted by
 .BR idassert-authz
 rules (see below), in which case the operation will fail;
@@ -152,7 +155,7 @@ identity
 will be asserted;
 .BR none ,
 which means that no proxyAuthz control will be used, so the
-.I proxyauthzdn
+.I idassert-authcdn
 identity will be asserted.
 Moreover, if a string prefixed with
 .B u:
index 2697340a1ea0525b16ec912024a957cbfedf9753..a16d0504345c16ece48f9c1ea48b79f4b10bf25f 100644 (file)
@@ -82,12 +82,27 @@ struct ldaprwmap {
        struct ldapmap rwm_at;
 };
 
+struct ldapauth {
+       struct berval   la_authcID;
+       struct berval   la_authcDN;
+       struct berval   la_passwd;
+
+       struct berval   la_authzID;
+       
+       int             la_authmethod;
+       int             la_sasl_flags;
+       struct berval   la_sasl_mech;
+       struct berval   la_sasl_realm;
+};
+
 struct ldapinfo {
        struct slap_backend_db  *be;
        char            *url;
        LDAPURLDesc     *lud;
-       struct berval binddn;
-       struct berval bindpw;
+       struct ldapauth acl_la;
+#define        acl_authcDN     acl_la.la_authcDN
+#define        acl_passwd      acl_la.la_passwd
+
 #ifdef LDAP_BACK_PROXY_AUTHZ
        /* ID assert stuff */
        int             idassert_mode;
@@ -98,18 +113,17 @@ struct ldapinfo {
 #define        LDAP_BACK_IDASSERT_OTHERDN      4
 #define        LDAP_BACK_IDASSERT_OTHERID      5
 
-       struct berval idassert_authcID;
-       struct berval idassert_authcDN;
-       struct berval idassert_passwd;
-
-       struct berval   idassert_authzID;
+       struct ldapauth idassert_la;
+#define        idassert_authcID        idassert_la.la_authcID
+#define        idassert_authcDN        idassert_la.la_authcDN
+#define        idassert_passwd         idassert_la.la_passwd
+#define        idassert_authzID        idassert_la.la_authzID
+#define        idassert_authmethod     idassert_la.la_authmethod
+#define        idassert_sasl_flags     idassert_la.la_sasl_flags
+#define        idassert_sasl_mech      idassert_la.la_sasl_mech
+#define        idassert_sasl_realm     idassert_la.la_sasl_realm
        BerVarray       idassert_authz;
        
-       int             idassert_authmethod;
-       int             idassert_sasl_flags;
-       struct berval   idassert_sasl_mech;
-       struct berval   idassert_sasl_realm;
-
        int             idassert_ppolicy;
        /* end of ID assert stuff */
 #endif /* LDAP_BACK_PROXY_AUTHZ */
index 4d91afe8b68602c2911eed8c4168a605b4940806..f5f23e1c793db584f848f9d9800799d38ee580fc 100644 (file)
@@ -224,6 +224,7 @@ ldap_back_getconn(Operation *op, SlapReply *rs)
                || (op->o_conn
                  && (op->o_bd == op->o_conn->c_authz_backend ))) {
                lc_curr.conn = op->o_conn;
+
        } else {
                lc_curr.conn = NULL;
        }
@@ -233,6 +234,7 @@ ldap_back_getconn(Operation *op, SlapReply *rs)
                lc_curr.local_dn = li->be->be_rootndn;
                lc_curr.conn = NULL;
                is_priv = 1;
+
        } else {
                lc_curr.local_dn = op->o_ndn;
        }
@@ -283,8 +285,9 @@ ldap_back_getconn(Operation *op, SlapReply *rs)
                ldap_pvt_thread_mutex_init( &lc->lc_mutex );
 
                if ( is_priv ) {
-                       ber_dupbv( &lc->cred, &li->bindpw );
-                       ber_dupbv( &lc->bound_dn, &li->binddn );
+                       ber_dupbv( &lc->cred, &li->acl_passwd );
+                       ber_dupbv( &lc->bound_dn, &li->acl_authcDN );
+
                } else {
                        BER_BVZERO( &lc->cred );
                        BER_BVZERO( &lc->bound_dn );
@@ -404,17 +407,18 @@ ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs )
                                && ( BER_BVISNULL( &lc->bound_dn ) || BER_BVISEMPTY( &lc->bound_dn ) ) ) {
                        struct berval   binddn = slap_empty_bv;
                        struct berval   bindcred = slap_empty_bv;
+                       int             dobind = 0;
 
                        /* 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_LEGACY:
                                if ( !BER_BVISNULL( &op->o_conn->c_dn ) && !BER_BVISEMPTY( &op->o_conn->c_dn ) ) {
-                                       if ( li->idassert_authmethod != LDAP_AUTH_SASL
-                                                       && !BER_BVISNULL( &li->idassert_authcDN ) && !BER_BVISEMPTY( &li->idassert_authcDN ) )
+                                       if ( !BER_BVISNULL( &li->idassert_authcDN ) && !BER_BVISEMPTY( &li->idassert_authcDN ) )
                                        {
                                                binddn = li->idassert_authcDN;
                                                bindcred = li->idassert_passwd;
+                                               dobind = 1;
                                        }
                                }
                                break;
@@ -432,20 +436,40 @@ ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs )
                                        }
                                }
 
-                               if ( li->idassert_authmethod != LDAP_AUTH_SASL ) {
-                                       binddn = li->idassert_authcDN;
-                               }
+                               binddn = li->idassert_authcDN;
                                bindcred = li->idassert_passwd;
+                               dobind = 1;
                                break;
                        }
 
-                       /* NOTE: essentially copied from clients/tools/common.c :) */
-                       switch ( li->idassert_authmethod ) {
+                       if ( dobind && li->idassert_authmethod == LDAP_AUTH_SASL ) {
 #ifdef HAVE_CYRUS_SASL
-                       case LDAP_AUTH_SASL:
-                               {
                                void            *defaults = NULL;
                                struct berval   authzID = BER_BVNULL;
+                               int             freeauthz = 0;
+
+                               switch ( li->idassert_mode ) {
+                               case LDAP_BACK_IDASSERT_OTHERID:
+                               case LDAP_BACK_IDASSERT_OTHERDN:
+                                       authzID = li->idassert_authzID;
+                                       break;
+
+                               case LDAP_BACK_IDASSERT_ANONYMOUS:
+                                       BER_BVSTR( &authzID, "dn:" );
+                                       break;
+
+                               case LDAP_BACK_IDASSERT_SELF:
+                                       authzID.bv_len = STRLENOF( "dn:" ) + op->o_conn->c_dn.bv_len;
+                                       authzID.bv_val = slap_sl_malloc( authzID.bv_len + 1, op->o_tmpmemctx );
+                                       AC_MEMCPY( authzID.bv_val, "dn:", STRLENOF( "dn:" ) );
+                                       AC_MEMCPY( authzID.bv_val + STRLENOF( "dn:" ),
+                                                       op->o_conn->c_dn.bv_val, op->o_conn->c_dn.bv_len + 1 );
+                                       freeauthz = 1;
+                                       break;
+
+                               default:
+                                       break;
+                               }
 
 #if 0  /* will deal with this later... */
                                if ( sasl_secprops != NULL ) {
@@ -461,12 +485,6 @@ ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs )
                                }
 #endif
 
-                               switch ( li->idassert_mode ) {
-                               case LDAP_BACK_IDASSERT_OTHERID:
-                               case LDAP_BACK_IDASSERT_OTHERDN:
-                                       authzID = li->idassert_authzID;
-                               }
-
                                defaults = lutil_sasl_defaults( lc->ld,
                                                li->idassert_sasl_mech.bv_val,
                                                li->idassert_sasl_realm.bv_val,
@@ -474,12 +492,15 @@ ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs )
                                                li->idassert_passwd.bv_val,
                                                authzID.bv_val );
 
-                               rs->sr_err = ldap_sasl_interactive_bind_s( lc->ld, NULL,
+                               rs->sr_err = ldap_sasl_interactive_bind_s( lc->ld, binddn.bv_val,
                                                li->idassert_sasl_mech.bv_val, NULL, NULL,
                                                li->idassert_sasl_flags, lutil_sasl_interact,
                                                defaults );
 
                                lutil_sasl_freedefs( defaults );
+                               if ( freeauthz ) {
+                                       slap_sl_free( authzID.bv_val, op->o_tmpmemctx );
+                               }
 
                                rs->sr_err = slap_map_api2result( rs );
                                if ( rs->sr_err != LDAP_SUCCESS ) {
@@ -490,9 +511,10 @@ ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs )
                                        lc->bound = 1;
                                }
                                goto done;
-                               }
+                       }
 #endif /* HAVE_CYRUS_SASL */
 
+                       switch ( li->idassert_authmethod ) {
                        case LDAP_AUTH_SIMPLE:
                                rs->sr_err = ldap_sasl_bind(lc->ld,
                                                binddn.bv_val, LDAP_SASL_SIMPLE,
@@ -714,7 +736,8 @@ ldap_back_proxy_authz_ctrl(
 
        *pctrls = NULL;
 
-       if ( BER_BVISNULL( &li->idassert_authcID ) ) {
+       if ( ( BER_BVISNULL( &li->idassert_authcID ) || BER_BVISEMPTY( &li->idassert_authcID ) )
+                       && ( BER_BVISNULL( &li->idassert_authcDN ) || BER_BVISEMPTY( &li->idassert_authcDN ) ) ) {
                goto done;
        }
 
@@ -749,11 +772,11 @@ ldap_back_proxy_authz_ctrl(
                        goto done;
                }
 
-               if ( BER_BVISEMPTY( &li->idassert_authcID ) ) {
+               if ( BER_BVISNULL( &li->idassert_authcDN ) || BER_BVISEMPTY( &li->idassert_authcDN ) ) {
                        goto done;
                }
 
-       } else if ( li->idassert_mode == LDAP_BACK_IDASSERT_OTHERID && li->idassert_authmethod == LDAP_AUTH_SASL ) {
+       } else if ( li->idassert_authmethod == LDAP_AUTH_SASL ) {
                /* already asserted in SASL */
                goto done;
 
index a98431fe79d7b0e3732a3c050bc0eabaa6503069..1b2da1c40027a7fca9514b46a2c5767224d260ba 100644 (file)
@@ -133,24 +133,26 @@ ldap_back_db_config(
 #endif
 
        /* name to use for ldap_back_group */
-       } else if ( strcasecmp( argv[0], "binddn" ) == 0 ) {
+       } else if ( strcasecmp( argv[0], "acl-authcdn" ) == 0
+                       || strcasecmp( argv[0], "binddn" ) == 0 ) {
                if (argc != 2) {
                        fprintf( stderr,
-       "%s: line %d: missing name in \"binddn <name>\" line\n",
-                           fname, lineno );
+       "%s: line %d: missing name in \"%s <name>\" line\n",
+                           fname, lineno, argv[0] );
                        return( 1 );
                }
-               ber_str2bv( argv[1], 0, 1, &li->binddn );
+               ber_str2bv( argv[1], 0, 1, &li->acl_authcDN );
 
        /* password to use for ldap_back_group */
-       } else if ( strcasecmp( argv[0], "bindpw" ) == 0 ) {
+       } else if ( strcasecmp( argv[0], "acl-passwd" ) == 0
+                       || strcasecmp( argv[0], "bindpw" ) == 0 ) {
                if (argc != 2) {
                        fprintf( stderr,
-       "%s: line %d: missing password in \"bindpw <password>\" line\n",
-                           fname, lineno );
+       "%s: line %d: missing password in \"%s <password>\" line\n",
+                           fname, lineno, argv[0] );
                        return( 1 );
                }
-               ber_str2bv( argv[1], 0, 1, &li->bindpw );
+               ber_str2bv( argv[1], 0, 1, &li->acl_passwd );
 
 #ifdef LDAP_BACK_PROXY_AUTHZ
        /* identity assertion stuff... */
@@ -721,7 +723,8 @@ parse_idassert(
                                        return 1;
                                }
 
-                               li->idassert_authzID.bv_val = ch_malloc( STRLENOF( "dn:" ) + dn.bv_len + 1 );
+                               li->idassert_authzID.bv_len = STRLENOF( "dn:" ) + dn.bv_len;
+                               li->idassert_authzID.bv_val = ch_malloc( li->idassert_authzID.bv_len + 1 );
                                AC_MEMCPY( li->idassert_authzID.bv_val, "dn:", STRLENOF( "dn:" ) );
                                AC_MEMCPY( &li->idassert_authzID.bv_val[ STRLENOF( "dn:" ) ], dn.bv_val, dn.bv_len + 1 );
                                ch_free( dn.bv_val );
@@ -733,6 +736,9 @@ parse_idassert(
        /* name to use for proxyAuthz propagation */
        } else if ( strcasecmp( argv[0], "idassert-authcdn" ) == 0
                        || strcasecmp( argv[0], "proxyauthzdn" ) == 0 ) {
+               struct berval   dn;
+               int             rc;
+
                if ( argc != 2 ) {
                        fprintf( stderr,
        "%s: line %d: missing name in \"%s <name>\" line\n",
@@ -740,13 +746,6 @@ parse_idassert(
                        return( 1 );
                }
 
-               if ( !BER_BVISNULL( &li->idassert_authcID ) ) {
-                       fprintf( stderr,
-       "%s: line %d: authcDN incompatible with previously defined authcID\n",
-                           fname, lineno );
-                       return( 1 );
-               }
-
                if ( !BER_BVISNULL( &li->idassert_authcDN ) ) {
                        fprintf( stderr, "%s: line %d: "
                                        "authcDN already defined; replacing...\n",
@@ -754,7 +753,20 @@ parse_idassert(
                        ch_free( li->idassert_authcDN.bv_val );
                }
                
-               ber_str2bv( argv[1], 0, 1, &li->idassert_authcDN );
+               ber_str2bv( argv[1], 0, 0, &dn );
+               rc = dnNormalize( 0, NULL, NULL, &dn, &li->idassert_authcDN, NULL );
+               if ( rc != LDAP_SUCCESS ) {
+#ifdef NEW_LOGGING
+                       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 ID \"%s\" is not a valid DN\n",
+                               fname, lineno, argv[1] );
+#endif
+                       return 1;
+               }
 
        /* password to use for proxyAuthz propagation */
        } else if ( strcasecmp( argv[0], "idassert-passwd" ) == 0
@@ -837,16 +849,39 @@ parse_idassert(
                                        }
                                        ber_str2bv( val, 0, 1, &li->idassert_sasl_realm );
 
-                               } else if ( strncasecmp( argv[arg], "authcid=", STRLENOF( "authcid=" ) ) == 0 ) {
-                                       char    *val = argv[arg] + STRLENOF( "authcid=" );
+                               } else if ( strncasecmp( argv[arg], "authcdn=", STRLENOF( "authcdn=" ) ) == 0 ) {
+                                       char            *val = argv[arg] + STRLENOF( "authcdn=" );
+                                       struct berval   dn;
+                                       int             rc;
 
                                        if ( !BER_BVISNULL( &li->idassert_authcDN ) ) {
-                                               fprintf( stderr,
-                               "%s: line %d: SASL authcID incompatible with previously defined authcDN\n",
-                                                               fname, lineno );
-                                               return( 1 );
+                                               fprintf( stderr, "%s: line %d: "
+                                                               "SASL authcDN already defined; replacing...\n",
+                                                               fname, lineno );
+                                               ch_free( li->idassert_authcDN.bv_val );
+                                       }
+                                       if ( strncasecmp( argv[arg], "dn:", STRLENOF( "dn:" ) ) == 0 ) {
+                                               val += STRLENOF( "dn:" );
                                        }
 
+                                       ber_str2bv( val, 0, 0, &dn );
+                                       rc = dnNormalize( 0, NULL, NULL, &dn, &li->idassert_authcDN, NULL );
+                                       if ( rc != LDAP_SUCCESS ) {
+#ifdef NEW_LOGGING
+                                               LDAP_LOG( CONFIG, CRIT, 
+                                                       "%s: line %d: SASL authcdn \"%s\" is not a valid DN.\n",
+                                                       fname, lineno, val );
+#else
+                                               Debug( LDAP_DEBUG_ANY,
+                                                       "%s: line %d: SASL authcdn \"%s\" is not a valid DN\n",
+                                                       fname, lineno, val );
+#endif
+                                               return 1;
+                                       }
+
+                               } else if ( strncasecmp( argv[arg], "authcid=", STRLENOF( "authcid=" ) ) == 0 ) {
+                                       char    *val = argv[arg] + STRLENOF( "authcid=" );
+
                                        if ( !BER_BVISNULL( &li->idassert_authcID ) ) {
                                                fprintf( stderr, "%s: line %d: "
                                                                "SASL authcID already defined; replacing...\n",
index 2a7ec514911e1ac98d0b594f66402d7f371c8a13..75870fac0b27e62c04c6efccdc251e46aec4a788 100644 (file)
@@ -98,8 +98,8 @@ ldap_back_db_init(
                return -1;
        }
 
-       BER_BVZERO( &li->binddn );
-       BER_BVZERO( &li->bindpw );
+       BER_BVZERO( &li->acl_authcDN );
+       BER_BVZERO( &li->acl_passwd );
 
 #ifdef LDAP_BACK_PROXY_AUTHZ
        li->idassert_mode = LDAP_BACK_IDASSERT_LEGACY;
@@ -210,13 +210,13 @@ ldap_back_db_destroy(
                        ldap_free_urldesc( li->lud );
                        li->lud = NULL;
                }
-               if ( !BER_BVISNULL( &li->binddn ) ) {
-                       ch_free( li->binddn.bv_val );
-                       BER_BVZERO( &li->binddn );
+               if ( !BER_BVISNULL( &li->acl_authcDN ) ) {
+                       ch_free( li->acl_authcDN.bv_val );
+                       BER_BVZERO( &li->acl_authcDN );
                }
-               if ( !BER_BVISNULL( &li->bindpw ) ) {
-                       ch_free( li->bindpw.bv_val );
-                       BER_BVZERO( &li->bindpw );
+               if ( !BER_BVISNULL( &li->acl_passwd ) ) {
+                       ch_free( li->acl_passwd.bv_val );
+                       BER_BVZERO( &li->acl_passwd );
                }
 #ifdef LDAP_BACK_PROXY_AUTHZ
                if ( !BER_BVISNULL( &li->idassert_authcID ) ) {
index 469d1cea87aea52b3c425c9d034d803450ebe622..9b12268b7a97b7579f7998c9698d84c7bf28f9c8 100644 (file)
@@ -368,12 +368,15 @@ ldap_build_entry(
         * 
         * FIXME: should we log anything, or delegate to dnNormalize?
         */
+       /* Note: if the distinguished values or the naming attributes
+        * change, should we massage them as well?
+        */
        if ( dnNormalize( 0, NULL, NULL, &ent->e_name, &ent->e_nname,
                op->o_tmpmemctx ) != LDAP_SUCCESS )
        {
                return LDAP_INVALID_DN_SYNTAX;
        }
-       
+
        attrp = &ent->e_attrs;
 
 #ifdef ENABLE_REWRITE