]> git.sur5r.net Git - openldap/commitdiff
more on idassert: SASL bind/authz
authorPierangelo Masarati <ando@openldap.org>
Sat, 15 May 2004 10:11:10 +0000 (10:11 +0000)
committerPierangelo Masarati <ando@openldap.org>
Sat, 15 May 2004 10:11:10 +0000 (10:11 +0000)
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 96e8ef5af452b290d1f9434703c804c14c9aa1fd..2697340a1ea0525b16ec912024a957cbfedf9753 100644 (file)
@@ -89,9 +89,6 @@ struct ldapinfo {
        struct berval binddn;
        struct berval bindpw;
 #ifdef LDAP_BACK_PROXY_AUTHZ
-       struct berval proxyauthzdn;
-       struct berval proxyauthzpw;
-
        /* ID assert stuff */
        int             idassert_mode;
 #define        LDAP_BACK_IDASSERT_LEGACY       0
@@ -100,8 +97,20 @@ struct ldapinfo {
 #define        LDAP_BACK_IDASSERT_SELF         3
 #define        LDAP_BACK_IDASSERT_OTHERDN      4
 #define        LDAP_BACK_IDASSERT_OTHERID      5
-       struct berval   idassert_id;
+
+       struct berval idassert_authcID;
+       struct berval idassert_authcDN;
+       struct berval idassert_passwd;
+
+       struct berval   idassert_authzID;
        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 26e94c62c04638c2aed4bc36e2c03c1a0d0b10f0..4d91afe8b68602c2911eed8c4168a605b4940806 100644 (file)
 #include <ac/socket.h>
 #include <ac/string.h>
 
-
 #define AVL_INTERNAL
 #include "slap.h"
 #include "back-ldap.h"
 
+#include <lutil_ldap.h>
+
 #define PRINT_CONNTREE 0
 
 static LDAP_REBIND_PROC        ldap_back_rebind;
@@ -408,11 +409,13 @@ ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs )
                         * 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 )
-                                               && !BER_BVISNULL( &li->proxyauthzdn ) && !BER_BVISEMPTY( &li->proxyauthzdn ) )
-                               {
-                                       binddn = li->proxyauthzdn;
-                                       bindcred = li->proxyauthzpw;
+                               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 ) )
+                                       {
+                                               binddn = li->idassert_authcDN;
+                                               bindcred = li->idassert_passwd;
+                                       }
                                }
                                break;
 
@@ -428,13 +431,85 @@ ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs )
                                                goto done;
                                        }
                                }
-                               binddn = li->proxyauthzdn;
-                               bindcred = li->proxyauthzpw;
+
+                               if ( li->idassert_authmethod != LDAP_AUTH_SASL ) {
+                                       binddn = li->idassert_authcDN;
+                               }
+                               bindcred = li->idassert_passwd;
                                break;
                        }
 
-                       rs->sr_err = ldap_sasl_bind(lc->ld, binddn.bv_val,
-                               LDAP_SASL_SIMPLE, &bindcred, NULL, NULL, &msgid);
+                       /* NOTE: essentially copied from clients/tools/common.c :) */
+                       switch ( li->idassert_authmethod ) {
+#ifdef HAVE_CYRUS_SASL
+                       case LDAP_AUTH_SASL:
+                               {
+                               void            *defaults = NULL;
+                               struct berval   authzID = BER_BVNULL;
+
+#if 0  /* will deal with this later... */
+                               if ( sasl_secprops != NULL ) {
+                                       rs->sr_err = ldap_set_option( lc->ld, LDAP_OPT_X_SASL_SECPROPS,
+                                               (void *) sasl_secprops );
+
+                                       if ( rs->sr_err != LDAP_OPT_SUCCESS ) {
+                                               send_ldap_result( op, rs );
+                                               lc->bound = 0;
+                                               goto done;
+                                               
+                                       }
+                               }
+#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,
+                                               li->idassert_authcID.bv_val,
+                                               li->idassert_passwd.bv_val,
+                                               authzID.bv_val );
+
+                               rs->sr_err = ldap_sasl_interactive_bind_s( lc->ld, NULL,
+                                               li->idassert_sasl_mech.bv_val, NULL, NULL,
+                                               li->idassert_sasl_flags, lutil_sasl_interact,
+                                               defaults );
+
+                               lutil_sasl_freedefs( defaults );
+
+                               rs->sr_err = slap_map_api2result( rs );
+                               if ( rs->sr_err != LDAP_SUCCESS ) {
+                                       lc->bound = 0;
+                                       send_ldap_result( op, rs );
+
+                               } else {
+                                       lc->bound = 1;
+                               }
+                               goto done;
+                               }
+#endif /* HAVE_CYRUS_SASL */
+
+                       case LDAP_AUTH_SIMPLE:
+                               rs->sr_err = ldap_sasl_bind(lc->ld,
+                                               binddn.bv_val, LDAP_SASL_SIMPLE,
+                                               &bindcred, NULL, NULL, &msgid);
+                               break;
+
+                       case LDAP_AUTH_NONE:
+                               lc->bound = 1;
+                               goto done;
+
+                       default:
+                               /* unsupported! */
+                               lc->bound = 0;
+                               rs->sr_err = LDAP_AUTH_METHOD_NOT_SUPPORTED;
+                               send_ldap_result( op, rs );
+                               goto done;
+                       }
 
                } else
 #endif /* LDAP_BACK_PROXY_AUTHZ */
@@ -639,7 +714,7 @@ ldap_back_proxy_authz_ctrl(
 
        *pctrls = NULL;
 
-       if ( BER_BVISNULL( &li->proxyauthzdn ) ) {
+       if ( BER_BVISNULL( &li->idassert_authcID ) ) {
                goto done;
        }
 
@@ -674,10 +749,14 @@ ldap_back_proxy_authz_ctrl(
                        goto done;
                }
 
-               if ( BER_BVISEMPTY( &li->proxyauthzdn ) ) {
+               if ( BER_BVISEMPTY( &li->idassert_authcID ) ) {
                        goto done;
                }
 
+       } else if ( li->idassert_mode == LDAP_BACK_IDASSERT_OTHERID && li->idassert_authmethod == LDAP_AUTH_SASL ) {
+               /* already asserted in SASL */
+               goto done;
+
        } else if ( li->idassert_authz ) {
                int             rc;
                struct berval   authcDN = BER_BVISNULL( &op->o_conn->c_dn ) ? slap_empty_bv : op->o_conn->c_dn;
@@ -712,7 +791,7 @@ ldap_back_proxy_authz_ctrl(
        case LDAP_BACK_IDASSERT_OTHERID:
        case LDAP_BACK_IDASSERT_OTHERDN:
                /* assert idassert DN */
-               assertedID = li->idassert_id;
+               assertedID = li->idassert_authzID;
                break;
 
        default:
@@ -729,17 +808,21 @@ ldap_back_proxy_authz_ctrl(
        ctrls[ 0 ]->ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ;
        ctrls[ 0 ]->ldctl_iscritical = 1;
 
-       /* already in u:ID form */
-       if ( li->idassert_mode == LDAP_BACK_IDASSERT_OTHERID ) {
+       switch ( li->idassert_mode ) {
+       /* already in u:ID or dn:DN form */
+       case LDAP_BACK_IDASSERT_OTHERID:
+       case LDAP_BACK_IDASSERT_OTHERDN:
                ber_dupbv( &ctrls[ 0 ]->ldctl_value, &assertedID );
+               break;
 
        /* needs the dn: prefix */
-       } else {
+       default:
                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 );
+               break;
        }
 
        if ( op->o_ctrls ) {
index b83405e244349977c8d387ff68eef914ec69f9e0..a98431fe79d7b0e3732a3c050bc0eabaa6503069 100644 (file)
@@ -153,28 +153,9 @@ ldap_back_db_config(
                ber_str2bv( argv[1], 0, 1, &li->bindpw );
 
 #ifdef LDAP_BACK_PROXY_AUTHZ
-       /* name to use for proxyAuthz propagation */
-       } else if ( strcasecmp( argv[0], "proxyauthzdn" ) == 0 ) {
-               if (argc != 2) {
-                       fprintf( stderr,
-       "%s: line %d: missing name in \"proxyauthzdn <name>\" line\n",
-                           fname, lineno );
-                       return( 1 );
-               }
-               ber_str2bv( argv[1], 0, 1, &li->proxyauthzdn );
-
-       /* password to use for proxyAuthz propagation */
-       } else if ( strcasecmp( argv[0], "proxyauthzpw" ) == 0 ) {
-               if (argc != 2) {
-                       fprintf( stderr,
-       "%s: line %d: missing password in \"proxyauthzpw <password>\" line\n",
-                           fname, lineno );
-                       return( 1 );
-               }
-               ber_str2bv( argv[1], 0, 1, &li->proxyauthzpw );
-
        /* identity assertion stuff... */
-       } else if ( strncasecmp( argv[0], "idassert-", STRLENOF( "idassert-" ) ) == 0 ) {
+       } else if ( strncasecmp( argv[0], "idassert-", STRLENOF( "idassert-" ) ) == 0
+                       || strncasecmp( argv[0], "proxyauthz", STRLENOF( "proxyauthz" ) ) == 0 ) {
                return parse_idassert( be, fname, lineno, argc, argv );
 #endif /* LDAP_BACK_PROXY_AUTHZ */
 
@@ -673,6 +654,7 @@ parse_idassert(
 {
        struct ldapinfo *li = (struct ldapinfo *) be->be_private;
 
+       /* identity assertion mode */
        if ( strcasecmp( argv[0], "idassert-mode" ) == 0 ) {
                if ( argc != 2 ) {
 #ifdef NEW_LOGGING
@@ -714,16 +696,18 @@ parse_idassert(
                                /* force lowercase... */
                                id.bv_val[0] = 'u';
                                li->idassert_mode = LDAP_BACK_IDASSERT_OTHERID;
-                               ber_dupbv( &li->idassert_id, &id );
+                               ber_dupbv( &li->idassert_authzID, &id );
 
                        } else {
+                               struct berval   dn;
+
                                /* 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 );
+                               rc = dnNormalize( 0, NULL, NULL, &id, &dn, NULL );
                                if ( rc != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
                                        LDAP_LOG( CONFIG, CRIT, 
@@ -737,10 +721,61 @@ parse_idassert(
                                        return 1;
                                }
 
+                               li->idassert_authzID.bv_val = ch_malloc( STRLENOF( "dn:" ) + dn.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 );
+
                                li->idassert_mode = LDAP_BACK_IDASSERT_OTHERDN;
                        }
                }
 
+       /* name to use for proxyAuthz propagation */
+       } else if ( strcasecmp( argv[0], "idassert-authcdn" ) == 0
+                       || strcasecmp( argv[0], "proxyauthzdn" ) == 0 ) {
+               if ( argc != 2 ) {
+                       fprintf( stderr,
+       "%s: line %d: missing name in \"%s <name>\" line\n",
+                           fname, lineno, argv[0] );
+                       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",
+                                       fname, lineno );
+                       ch_free( li->idassert_authcDN.bv_val );
+               }
+               
+               ber_str2bv( argv[1], 0, 1, &li->idassert_authcDN );
+
+       /* password to use for proxyAuthz propagation */
+       } else if ( strcasecmp( argv[0], "idassert-passwd" ) == 0
+                       || strcasecmp( argv[0], "proxyauthzpw" ) == 0 ) {
+               if ( argc != 2 ) {
+                       fprintf( stderr,
+       "%s: line %d: missing password in \"%s <password>\" line\n",
+                           fname, lineno, argv[0] );
+                       return( 1 );
+               }
+
+               if ( !BER_BVISNULL( &li->idassert_passwd ) ) {
+                       fprintf( stderr, "%s: line %d: "
+                                       "passwd already defined; replacing...\n",
+                                       fname, lineno );
+                       ch_free( li->idassert_passwd.bv_val );
+               }
+               
+               ber_str2bv( argv[1], 0, 1, &li->idassert_passwd );
+
+       /* rules to accept identity assertion... */
        } else if ( strcasecmp( argv[0], "idassert-authz" ) == 0 ) {
                struct berval   rule;
 
@@ -748,6 +783,116 @@ parse_idassert(
 
                ber_bvarray_add( &li->idassert_authz, &rule );
 
+       } else if ( strcasecmp( argv[0], "idassert-method" ) == 0 ) {
+               if ( argc < 2 ) {
+                       fprintf( stderr,
+       "%s: line %d: missing method in \"%s <method>\" line\n",
+                           fname, lineno, argv[0] );
+                       return( 1 );
+               }
+
+               if ( strcasecmp( argv[1], "none" ) == 0 ) {
+                       /* FIXME: is this useful? */
+                       li->idassert_authmethod = LDAP_AUTH_NONE;
+
+                       if ( argc != 2 ) {
+                               fprintf( stderr,
+       "%s: line %d: trailing args in \"%s %s ...\" line ignored\"\n",
+                                       fname, lineno, argv[0], argv[1] );
+                       }
+
+               } else if ( strcasecmp( argv[1], "simple" ) == 0 ) {
+                       li->idassert_authmethod = LDAP_AUTH_SIMPLE;
+
+                       if ( argc != 2 ) {
+                               fprintf( stderr,
+       "%s: line %d: trailing args in \"%s %s ...\" line ignored\"\n",
+                                       fname, lineno, argv[0], argv[1] );
+                       }
+
+               } else if ( strcasecmp( argv[1], "sasl" ) == 0 ) {
+#ifdef HAVE_CYRUS_SASL
+                       int     arg;
+
+                       for ( arg = 2; arg < argc; arg++ ) {
+                               if ( strncasecmp( argv[arg], "mech=", STRLENOF( "mech=" ) ) == 0 ) {
+                                       char    *val = argv[arg] + STRLENOF( "mech=" );
+
+                                       if ( !BER_BVISNULL( &li->idassert_sasl_mech ) ) {
+                                               fprintf( stderr, "%s: line %d: "
+                                                               "SASL mech already defined; replacing...\n",
+                                                               fname, lineno );
+                                               ch_free( li->idassert_sasl_mech.bv_val );
+                                       }
+                                       ber_str2bv( val, 0, 1, &li->idassert_sasl_mech );
+
+                               } else if ( strncasecmp( argv[arg], "realm=", STRLENOF( "realm=" ) ) == 0 ) {
+                                       char    *val = argv[arg] + STRLENOF( "realm=" );
+
+                                       if ( !BER_BVISNULL( &li->idassert_sasl_realm ) ) {
+                                               fprintf( stderr, "%s: line %d: "
+                                                               "SASL realm already defined; replacing...\n",
+                                                               fname, lineno );
+                                               ch_free( li->idassert_sasl_realm.bv_val );
+                                       }
+                                       ber_str2bv( val, 0, 1, &li->idassert_sasl_realm );
+
+                               } else if ( strncasecmp( argv[arg], "authcid=", STRLENOF( "authcid=" ) ) == 0 ) {
+                                       char    *val = argv[arg] + STRLENOF( "authcid=" );
+
+                                       if ( !BER_BVISNULL( &li->idassert_authcDN ) ) {
+                                               fprintf( stderr,
+                               "%s: line %d: SASL authcID incompatible with previously defined authcDN\n",
+                                                               fname, lineno );
+                                               return( 1 );
+                                       }
+
+                                       if ( !BER_BVISNULL( &li->idassert_authcID ) ) {
+                                               fprintf( stderr, "%s: line %d: "
+                                                               "SASL authcID already defined; replacing...\n",
+                                                               fname, lineno );
+                                               ch_free( li->idassert_authcID.bv_val );
+                                       }
+                                       if ( strncasecmp( argv[arg], "u:", STRLENOF( "u:" ) ) == 0 ) {
+                                               val += STRLENOF( "u:" );
+                                       }
+                                       ber_str2bv( val, 0, 1, &li->idassert_authcID );
+
+                               } else if ( strncasecmp( argv[arg], "cred=", STRLENOF( "cred=" ) ) == 0 ) {
+                                       char    *val = argv[arg] + STRLENOF( "cred=" );
+
+                                       if ( !BER_BVISNULL( &li->idassert_passwd ) ) {
+                                               fprintf( stderr, "%s: line %d: "
+                                                               "SASL cred already defined; replacing...\n",
+                                                               fname, lineno );
+                                               ch_free( li->idassert_passwd.bv_val );
+                                       }
+                                       ber_str2bv( val, 0, 1, &li->idassert_passwd );
+
+                               } else {
+                                       fprintf( stderr, "%s: line %d: "
+                                                       "unknown SASL parameter %s\n",
+                                                       fname, lineno, argv[arg] );
+                                       return 1;
+                               }
+                       }
+
+                       li->idassert_authmethod = LDAP_AUTH_SASL;
+
+#else /* !HAVE_CYRUS_SASL */
+                       fprintf( stderr, "%s: line %d: "
+                                       "compile --with-cyrus-sasl to enable SASL auth\n",
+                                       fname, lineno );
+                       return 1;
+#endif /* !HAVE_CYRUS_SASL */
+
+               } else {
+                       fprintf( stderr, "%s: line %d: "
+                                       "unhandled auth method %s\n",
+                                       fname, lineno );
+                       return 1;
+               }
+
        } else {
                return SLAP_CONF_UNKNOWN;
        }
index 4645b5195e461c4fc12026c2ba97fe2fe69ac31b..2a7ec514911e1ac98d0b594f66402d7f371c8a13 100644 (file)
@@ -102,11 +102,21 @@ ldap_back_db_init(
        BER_BVZERO( &li->bindpw );
 
 #ifdef LDAP_BACK_PROXY_AUTHZ
-       BER_BVZERO( &li->proxyauthzdn );
-       BER_BVZERO( &li->proxyauthzpw );
-
        li->idassert_mode = LDAP_BACK_IDASSERT_LEGACY;
-       BER_BVZERO( &li->idassert_id );
+
+       BER_BVZERO( &li->idassert_authcID );
+       BER_BVZERO( &li->idassert_authcDN );
+       BER_BVZERO( &li->idassert_passwd );
+
+       BER_BVZERO( &li->idassert_authzID );
+       li->idassert_authz = NULL;
+
+       li->idassert_authmethod = LDAP_AUTH_SIMPLE;
+       li->idassert_sasl_flags = LDAP_SASL_QUIET;
+       BER_BVZERO( &li->idassert_sasl_mech );
+       BER_BVZERO( &li->idassert_sasl_realm );
+
+       li->idassert_ppolicy = 0;
 #endif /* LDAP_BACK_PROXY_AUTHZ */
 
 #ifdef ENABLE_REWRITE
@@ -209,17 +219,29 @@ ldap_back_db_destroy(
                        BER_BVZERO( &li->bindpw );
                }
 #ifdef LDAP_BACK_PROXY_AUTHZ
-               if ( !BER_BVISNULL( &li->proxyauthzdn ) ) {
-                       ch_free( li->proxyauthzdn.bv_val );
-                       BER_BVZERO( &li->proxyauthzdn );
+               if ( !BER_BVISNULL( &li->idassert_authcID ) ) {
+                       ch_free( li->idassert_authcID.bv_val );
+                       BER_BVZERO( &li->idassert_authcID );
+               }
+               if ( !BER_BVISNULL( &li->idassert_authcDN ) ) {
+                       ch_free( li->idassert_authcDN.bv_val );
+                       BER_BVZERO( &li->idassert_authcDN );
+               }
+               if ( !BER_BVISNULL( &li->idassert_passwd ) ) {
+                       ch_free( li->idassert_passwd.bv_val );
+                       BER_BVZERO( &li->idassert_passwd );
+               }
+               if ( !BER_BVISNULL( &li->idassert_authzID ) ) {
+                       ch_free( li->idassert_authzID.bv_val );
+                       BER_BVZERO( &li->idassert_authzID );
                }
-               if ( !BER_BVISNULL( &li->proxyauthzpw ) ) {
-                       ch_free( li->proxyauthzpw.bv_val );
-                       BER_BVZERO( &li->proxyauthzpw );
+               if ( !BER_BVISNULL( &li->idassert_sasl_mech ) ) {
+                       ch_free( li->idassert_sasl_mech.bv_val );
+                       BER_BVZERO( &li->idassert_sasl_mech );
                }
-               if ( !BER_BVISNULL( &li->idassert_id ) ) {
-                       ch_free( li->idassert_id.bv_val );
-                       BER_BVZERO( &li->idassert_id );
+               if ( !BER_BVISNULL( &li->idassert_sasl_realm ) ) {
+                       ch_free( li->idassert_sasl_realm.bv_val );
+                       BER_BVZERO( &li->idassert_sasl_realm );
                }
 #endif /* LDAP_BACK_PROXY_AUTHZ */
                 if (li->conntree) {