]> git.sur5r.net Git - openldap/commitdiff
Add support for unsolicited notifications.
authorKurt Zeilenga <kurt@openldap.org>
Wed, 7 Jul 1999 18:51:39 +0000 (18:51 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Wed, 7 Jul 1999 18:51:39 +0000 (18:51 +0000)
31 files changed:
servers/slapd/Makefile.in
servers/slapd/abandon.c
servers/slapd/acl.c
servers/slapd/add.c
servers/slapd/ava.c
servers/slapd/back-bdb2/modify.c
servers/slapd/back-bdb2/search.c
servers/slapd/back-ldap/search.c
servers/slapd/back-ldbm/modify.c
servers/slapd/back-ldbm/search.c
servers/slapd/back-passwd/search.c
servers/slapd/back-perl/search.c
servers/slapd/back-shell/result.c
servers/slapd/back-tcl/tcl_util.c
servers/slapd/bind.c
servers/slapd/compare.c
servers/slapd/configinfo.c
servers/slapd/connection.c
servers/slapd/controls.c
servers/slapd/delete.c
servers/slapd/filter.c
servers/slapd/libslapd.dsp
servers/slapd/modify.c
servers/slapd/modrdn.c
servers/slapd/monitor.c
servers/slapd/proto-slap.h
servers/slapd/result.c
servers/slapd/root_dse.c
servers/slapd/schema.c
servers/slapd/search.c
servers/slapd/tools/mimic.c

index 2c251e85a09530f64d5891d505d9885a17f07f0d..f3c87f6da74c32ac65a817257f9c6c764924f435 100644 (file)
@@ -9,7 +9,7 @@ SRCS    = main.c daemon.c connection.c search.c filter.c add.c charray.c \
                dn.c compare.c modify.c delete.c modrdn.c ch_malloc.c \
                value.c ava.c bind.c unbind.c abandon.c filterentry.c \
                phonetic.c acl.c str2filter.c aclparse.c init.c user.c \
-               repl.c lock.c controls.c \
+               repl.c lock.c controls.c extended.c \
                suffixalias.c schema.c schemaparse.c monitor.c configinfo.c \
                root_dse.c module.c
 OBJS   = main.o daemon.o connection.o search.o filter.o add.o charray.o \
@@ -17,7 +17,7 @@ OBJS  = main.o daemon.o connection.o search.o filter.o add.o charray.o \
                dn.o compare.o modify.o delete.o modrdn.o ch_malloc.o \
                value.o ava.o bind.o unbind.o abandon.o filterentry.o \
                phonetic.o acl.o str2filter.o aclparse.o init.o user.o \
-               repl.o lock.o controls.o \
+               repl.o lock.o controls.o extended.o \
                suffixalias.o schema.o schemaparse.o monitor.o configinfo.o \
                root_dse.o module.o
 
index d0eb0244e89e186051e2d3a69b0891d5bd53ea47..bac282e2b3c576f90f4864b3e5edf624cd9ab58a 100644 (file)
@@ -40,7 +40,9 @@ do_abandon(
 
        if ( ber_scanf( op->o_ber, "i", &id ) == LBER_ERROR ) {
                Debug( LDAP_DEBUG_ANY, "do_abandon: ber_scanf failed\n", 0, 0 ,0 );
-               return LDAP_PROTOCOL_ERROR;
+               send_ldap_disconnect( conn, op,
+                       LDAP_PROTOCOL_ERROR, "decoding error" );
+               return -1;
        }
 
        if( (rc = get_ctrls( conn, op, 0 )) != LDAP_SUCCESS ) {
index cfc8e8923c91599757300a24d4de6fc5e9ca4650..6dcdcd50870b045a946c60aa459b3cee572dbfd4 100644 (file)
@@ -55,7 +55,7 @@ access_allowed(
                e->e_dn, attr, 0 );
 
        /* the lastmod attributes are ignored by ACL checking */
-       if ( oc_check_operational( attr ) ) {
+       if ( oc_check_no_usermod_attr( attr ) ) {
                Debug( LDAP_DEBUG_ACL, "Operational attribute: %s access allowed\n",
                        attr, 0, 0 );
                return(1);
@@ -212,7 +212,6 @@ acl_access_allowed(
 )
 {
        int             i;
-       char            *odn;
        struct access   *b;
        Attribute       *at;
        struct berval   bv;
@@ -244,11 +243,9 @@ acl_access_allowed(
                return( default_access >= access );
        }
 
-       odn = op->o_ndn;
-
-       if ( odn != NULL ) {
-               bv.bv_val = odn;
-               bv.bv_len = strlen( odn );
+       if ( op->o_ndn != NULL ) {
+               bv.bv_val = op->o_ndn;
+               bv.bv_len = strlen( bv.bv_val );
        }
 
        for ( i = 1, b = a->acl_access; b != NULL; b = b->a_next, i++ ) {
@@ -282,7 +279,7 @@ acl_access_allowed(
                                        return ACL_GRANT(b->a_access, access );
                                }
                        } else {
-                               if ( regex_matches( b->a_dnpat, odn, edn, matches ) ) {
+                               if ( regex_matches( b->a_dnpat, op->o_ndn, edn, matches ) ) {
                                        Debug( LDAP_DEBUG_ACL,
                                    "<= acl_access_allowed: matched by clause #%d access %s\n",
                                    i, ACL_GRANT(b->a_access, access)
@@ -365,7 +362,7 @@ acl_access_allowed(
                        string_expand(buf, sizeof(buf), b->a_group, edn, matches);
                        (void) dn_normalize_case(buf);
 
-                       if (backend_group(be, e, buf, odn,
+                       if (backend_group(be, e, buf, op->o_ndn,
                                b->a_group_oc, b->a_group_at) == 0)
                        {
                                Debug( LDAP_DEBUG_ACL,
@@ -408,7 +405,7 @@ acl_check_modlist(
                regmatch_t       matches[MAXREMATCHES];
 
                /* the lastmod attributes are ignored by ACL checking */
-               if ( oc_check_operational( mlist->ml_type ) ) {
+               if ( oc_check_no_usermod_attr( mlist->ml_type ) ) {
                        Debug( LDAP_DEBUG_ACL, "Operational attribute: %s access allowed\n",
                                mlist->ml_type, 0, 0 );
                        continue;
index 5e85be3aa7e06aa1adb5b3383819a8cef05a9048..e2438a5d3ba713d160efe1fdb53155a5f5e1d1e6 100644 (file)
@@ -57,9 +57,9 @@ do_add( Connection *conn, Operation *op )
        /* get the name */
        if ( ber_scanf( ber, "{a", /*}*/ &dn ) == LBER_ERROR ) {
                Debug( LDAP_DEBUG_ANY, "do_add: ber_scanf failed\n", 0, 0, 0 );
-               send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR, NULL,
-                   "decoding error" );
-               return LDAP_PROTOCOL_ERROR;
+               send_ldap_disconnect( conn, op,
+                       LDAP_PROTOCOL_ERROR, "decoding error" );
+               return -1;
        }
 
        e = (Entry *) ch_calloc( 1, sizeof(Entry) );
@@ -80,17 +80,17 @@ do_add( Connection *conn, Operation *op )
                struct berval   **vals;
 
                if ( ber_scanf( ber, "{a{V}}", &type, &vals ) == LBER_ERROR ) {
-                       send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR,
-                           NULL, "decoding error" );
+                       send_ldap_disconnect( conn, op,
+                               LDAP_PROTOCOL_ERROR, "decoding error" );
                        entry_free( e );
-                       return LDAP_PROTOCOL_ERROR;
+                       return -1;
                }
 
                if ( vals == NULL ) {
                        Debug( LDAP_DEBUG_ANY, "no values for type %s\n", type,
                            0, 0 );
-                       send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR, NULL,
-                           NULL );
+                       send_ldap_result( conn, op,
+                               LDAP_PROTOCOL_ERROR, NULL, "no values for type" );
                        free( type );
                        entry_free( e );
                        return LDAP_PROTOCOL_ERROR;
@@ -105,9 +105,9 @@ do_add( Connection *conn, Operation *op )
        if ( ber_scanf( ber, /*{*/ "}") == LBER_ERROR ) {
                entry_free( e );
                Debug( LDAP_DEBUG_ANY, "do_add: ber_scanf failed\n", 0, 0, 0 );
-               send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR, NULL,
-                   "decoding error" );
-               return LDAP_PROTOCOL_ERROR;
+               send_ldap_disconnect( conn, op,
+                       LDAP_PROTOCOL_ERROR, "decoding error" );
+               return -1;
        }
 
        if( (rc = get_ctrls( conn, op, 1 )) != LDAP_SUCCESS ) {
@@ -186,7 +186,7 @@ add_created_attrs( Operation *op, Entry *e )
 
        /* remove any attempts by the user to add these attrs */
        for ( a = &e->e_attrs; *a != NULL; a = next ) {
-               if ( oc_check_operational( (*a)->a_type ) ) {
+               if ( oc_check_no_usermod_attr( (*a)->a_type ) ) {
                        tmp = *a;
                        *a = (*a)->a_next;
                        attr_free( tmp );
@@ -197,7 +197,7 @@ add_created_attrs( Operation *op, Entry *e )
        }
 
        if ( op->o_dn == NULL || op->o_dn[0] == '\0' ) {
-               bv.bv_val = "NULLDN";
+               bv.bv_val = "<anonymous>";
                bv.bv_len = strlen( bv.bv_val );
        } else {
                bv.bv_val = op->o_dn;
index 1e10339cb2c98614de6d2b51b7f6ad665661721e..33a70723ddbba269b15e88f66e3726d36eda93d5 100644 (file)
@@ -18,12 +18,12 @@ get_ava(
        if ( ber_scanf( ber, "{ao}", &ava->ava_type, &ava->ava_value )
            == LBER_ERROR ) {
                Debug( LDAP_DEBUG_ANY, "  get_ava ber_scanf\n", 0, 0, 0 );
-               return( LDAP_PROTOCOL_ERROR );
+               return( -1 );
        }
        attr_normalize( ava->ava_type );
        value_normalize( ava->ava_value.bv_val, attr_syntax( ava->ava_type ) );
 
-       return( 0 );
+       return( LDAP_SUCCESS );
 }
 
 void
index 8f137608f33e7e0bcdb3f1a4fd3d1a1cbcf8fee0..9e891e6a788415f0c91b013f6e0d17655bd895b8 100644 (file)
@@ -33,9 +33,9 @@ add_lastmods( Operation *op, LDAPModList **modlist )
 
        /* remove any attempts by the user to modify these attrs */
        for ( m = modlist; *m != NULL; m = &(*m)->ml_next ) {
-            if ( oc_check_operational( (*m)->ml_type ) ) {
+            if ( oc_check_no_usermod_attr( (*m)->ml_type ) ) {
                 Debug( LDAP_DEBUG_TRACE,
-                                       "add_lastmods: found operational attr: %s\n",
+                                       "add_lastmods: found no user mod attr: %s\n",
                                        (*m)->ml_type, 0, 0 );
                 tmp = *m;
                 *m = (*m)->ml_next;
index 3090e89cca00608bae044ea4ab557ec98bbbc729..28fed4863aa2d30c0b28a8638fc76cc611ba7bd1 100644 (file)
@@ -265,7 +265,7 @@ bdb2i_back_search_internal(
 
                                        if (e) {
                                                switch ( send_search_entry( be, conn, op, e,
-                                                       attrs, attrsonly ) ) {
+                                                       attrs, attrsonly, 0 ) ) {
                                                case 0:         /* entry sent ok */
                                                        nentries++;
                                                        break;
index e89cec69ae2bb753b5c924fb40f811f1a5e59c47..6145a0704d83adcdf917abb0079fc1a183f5a633 100644 (file)
@@ -158,7 +158,7 @@ ldap_send_entry(
                if (!attr->a_vals)
                        attr->a_vals = &dummy;
        }
-       send_search_entry( be, lc->conn, op, &ent, attrs, attrsonly );
+       send_search_entry( be, lc->conn, op, &ent, attrs, attrsonly, 0 );
        for (;ent.e_attrs;) {
                attr=ent.e_attrs;
                ent.e_attrs = attr->a_next;
index 15c2c72896f84de692d1cebc6c4c921e83766cc7..9ae82205434f763885580543596d5067d22d348f 100644 (file)
@@ -33,9 +33,9 @@ add_lastmods( Operation *op, LDAPModList **modlist )
 
        /* remove any attempts by the user to modify these attrs */
        for ( m = modlist; *m != NULL; m = &(*m)->ml_next ) {
-            if ( oc_check_operational( (*m)->ml_type ) ) {
+            if ( oc_check_no_usermod_attr( (*m)->ml_type ) ) {
                 Debug( LDAP_DEBUG_TRACE,
-                                       "add_lastmods: found operational attr: %s\n",
+                                       "add_lastmods: found no user mod attr: %s\n",
                                        (*m)->ml_type, 0, 0 );
                 tmp = *m;
                 *m = (*m)->ml_next;
index 80b184893cec716aa7dc99e1ddcb00d4dae338d6..7ab4f5f7617f16c58479f4508db67514a2553081 100644 (file)
@@ -264,7 +264,7 @@ ldbm_back_search(
                                        }
                                        if (e) {
                                                switch ( send_search_entry( be, conn, op, e,
-                                                       attrs, attrsonly ) ) {
+                                                       attrs, attrsonly, 0 ) ) {
                                                case 0:         /* entry sent ok */
                                                        nentries++;
                                                        break;
index 859648e9ed046e92bbd833af4d77c18ed33fe18e..bd61a8070cddda575c93f3ecb9f4f854fe1510f2 100644 (file)
@@ -139,7 +139,7 @@ passwd_back_search(
                                                return( 0 );
                                        }
 
-                                       send_search_entry( be, conn, op, e, attrs, attrsonly );
+                                       send_search_entry( be, conn, op, e, attrs, attrsonly, 0 );
                                        sent++;
                                }
 
@@ -176,7 +176,7 @@ passwd_back_search(
                e = pw2entry( be, pw, rdn );
 
                if ( test_filter( be, conn, op, e, filter ) == 0 ) {
-                       send_search_entry( be, conn, op, e, attrs, attrsonly );
+                       send_search_entry( be, conn, op, e, attrs, attrsonly, 0 );
                        sent++;
                }
 
index 693fcd89fcc0717428f34a147efa2ccf4e6d6f1a..7117f4b985e01cc9f1ae2ac58500b0935bc168c1 100644 (file)
@@ -91,7 +91,8 @@ perl_back_search(
                                                           op,
                                                           e,
                                                           attrs,
-                                                          attrsonly );
+                                                          attrsonly,
+                                                          0 );
                                                         
                                        entry_free( e );
                                }
index daa826775d0055a6d0cf113d2e47e7162935d54d..dfb479e36cae3b7295119c8bf71a5252e5d28b19 100644 (file)
@@ -59,7 +59,7 @@ read_and_send_results(
                                    buf, 0, 0 );
                        } else {
                                send_search_entry( be, conn, op, e, attrs,
-                                   attrsonly );
+                                   attrsonly, 0 );
                                entry_free( e );
                        }
 
index 3163abcdbc047cb9b65b4f690b41f584046fe22b..cdff332fc3d95a2a4fb41fc440674ed4acec9179 100644 (file)
@@ -1,6 +1,6 @@
 /* result.c - tcl backend utility functions
  *
- * $Id: tcl_util.c,v 1.4 1999/02/19 06:55:20 bcollins Exp $
+ * $Id: tcl_util.c,v 1.5 1999/02/28 04:55:49 bcollins Exp $
  *
  * Copyright 1999, Ben Collins <bcollins@debian.org>, All rights reserved.
  *
@@ -80,7 +80,7 @@ interp_send_results (
                                        buf, 0, 0);
                        } else {
                                send_search_entry (be, conn, op, e, attrs,
-                                       attrsonly);
+                                       attrsonly, 0 );
                                entry_free (e);
                        }
 
index 9586812e3e433a5cfc4473b27ff72f8ddd6f9b65..4ab5de594abb86beddde59b0f07ef32228bb37ae 100644 (file)
@@ -22,7 +22,6 @@
 #include "slap.h"
 
 char *supportedSASLMechanisms[] = {
-       "X-CRAM-MD5",
        "X-DIGEST-MD5",
        NULL
 };
@@ -103,8 +102,9 @@ do_bind(
 
        if ( tag == LBER_ERROR ) {
                Debug( LDAP_DEBUG_ANY, "bind: ber_scanf failed\n", 0, 0, 0 );
-               send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR, NULL,
-                   "decoding error" );
+               send_ldap_disconnect( conn, op,
+                       LDAP_PROTOCOL_ERROR, "decoding error" );
+               rc = -1;
                goto cleanup;
        }
 
@@ -131,8 +131,10 @@ do_bind(
        }
 
        if ( tag == LBER_ERROR ) {
-               send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR, NULL,
+               send_ldap_disconnect( conn, op,
+                       LDAP_PROTOCOL_ERROR,
                "decoding error" );
+               rc = -1;
                goto cleanup;
        }
 
@@ -156,8 +158,8 @@ do_bind(
 
        if ( version < LDAP_VERSION_MIN || version > LDAP_VERSION_MAX ) {
                Debug( LDAP_DEBUG_ANY, "unknown version %d\n", version, 0, 0 );
-               send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR, NULL,
-                   "version not supported" );
+               send_ldap_result( conn, op,
+                       rc = LDAP_PROTOCOL_ERROR, NULL, "version not supported" );
                goto cleanup;
        }
 
@@ -165,8 +167,9 @@ do_bind(
                if ( version < LDAP_VERSION3 ) {
                        Debug( LDAP_DEBUG_ANY, "do_bind: sasl with LDAPv%d\n",
                                version, 0, 0 );
-                       send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR, NULL,
-                               "sasl bind requires LDAPv3" );
+                       send_ldap_disconnect( conn, op,
+                               LDAP_PROTOCOL_ERROR, "sasl bind requires LDAPv3" );
+                       rc = -1;
                        goto cleanup;
                }
 
index c07c8dabcb630ef84be35a28f262ea715d4951c7..028a4f44d0c3c133b6266bf7153276e864b86d07 100644 (file)
@@ -54,8 +54,9 @@ do_compare(
        if ( ber_scanf( op->o_ber, "{a{ao}}", &ndn, &ava.ava_type,
            &ava.ava_value ) == LBER_ERROR ) {
                Debug( LDAP_DEBUG_ANY, "ber_scanf failed\n", 0, 0, 0 );
-               send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR, NULL, "" );
-               return rc;
+               send_ldap_disconnect( conn, op,
+                       LDAP_PROTOCOL_ERROR, "decoding error" );
+               return -1;
        }
 
        if( ( rc = get_ctrls( conn, op, 1 )) != LDAP_SUCCESS ) {
index 332826ceb09baf02d1be79b7d38180d9053cc1b2..ee6d63fd50ebdb17fe77541fdab5ed5a37b3d39e 100644 (file)
@@ -63,7 +63,7 @@ config_info( Connection *conn, Operation *op )
                attr_merge( e, "database", vals );
        }
 
-       send_search_entry( &backends[0], conn, op, e, NULL, 0 );
+       send_search_entry( &backends[0], conn, op, e, NULL, 0, 1 );
        send_ldap_search_result( conn, op, LDAP_SUCCESS, NULL, NULL, 1 );
 
        entry_free( e );
index dbae86bd30129d453f071398347095433d1fcc5f..e8defc96748feb770f7cdad77ee84a177764d6da 100644 (file)
@@ -681,18 +681,22 @@ connection_operation( void *arg_v )
                rc = do_abandon( conn, arg->co_op );
                break;
 
-#if 0
        case LDAP_REQ_EXTENDED:
                rc = do_extended( conn, arg->co_op );
                break;
-#endif
 
        default:
-               Debug( LDAP_DEBUG_ANY, "unknown request 0x%lx\n",
-                   arg->co_op->o_tag, 0, 0 );
+               Debug( LDAP_DEBUG_ANY, "unknown LDAP request 0x%lx\n",
+                   tag, 0, 0 );
+               arg->co_op->o_tag = LBER_ERROR;
+               send_ldap_disconnect( conn, arg->co_op,
+                       LDAP_PROTOCOL_ERROR, "unknown LDAP request" );
+               rc = -1;
                break;
        }
 
+       if( rc == -1 ) tag = LBER_ERROR;
+
        ldap_pvt_thread_mutex_lock( &num_ops_mutex );
        num_ops_completed++;
        ldap_pvt_thread_mutex_unlock( &num_ops_mutex );
@@ -710,6 +714,7 @@ connection_operation( void *arg_v )
        arg = NULL;
 
        switch( tag ) {
+       case LBER_ERROR:
        case LDAP_REQ_UNBIND:
                /* c_mutex is locked */
                connection_closing( conn );
index a1c70d7b3db7e105353c7d49101c19062fccb4b2..1afb52038a8f6c6092693063ab1a87b7117d1e5d 100644 (file)
@@ -32,6 +32,7 @@ int get_ctrls(
        BerElement *ber = op->o_ber;
        LDAPControl ***ctrls = &op->o_ctrls;
        int rc = LDAP_SUCCESS;
+       char *errmsg = NULL;
 
        len = ber_pvt_ber_remaining(ber);
 
@@ -43,14 +44,16 @@ int get_ctrls(
 
        if(( tag = ber_peek_tag( ber, &len )) != LDAP_TAG_CONTROLS ) {
                if( tag == LBER_ERROR ) {
-                       rc = LDAP_PROTOCOL_ERROR;
+                       rc = -1;
+                       errmsg = "unexpected data in PDU";
                }
 
                goto return_results;
        }
 
        if( op->o_protocol < LDAP_VERSION3 ) {
-               rc = LDAP_PROTOCOL_ERROR;
+               rc = -1;
+               errmsg = "controls require LDAPv3";
                goto return_results;
        }
 
@@ -61,6 +64,7 @@ int get_ctrls(
 #if 0
        if( *ctrls == NULL ) {
                rc = LDAP_NO_MEMORY;
+               errmsg = "no memory";
                goto return_results;
        }
 #endif
@@ -94,6 +98,7 @@ int get_ctrls(
                        *ctrls = NULL;
 
                        rc = LDAP_NO_MEMORY;
+                       errmsg = "no memory";
                        goto return_results;
                }
 #endif
@@ -128,7 +133,8 @@ int get_ctrls(
                if( tag == LBER_ERROR ) {
                        *ctrls = NULL;
                        ldap_controls_free( tctrls );
-                       rc = LDAP_DECODING_ERROR;
+                       rc = -1;
+                       errmsg = "decoding controls error";
                        goto return_results;
                }
 
@@ -136,6 +142,7 @@ int get_ctrls(
                        !charray_inlist( supportedControls, tctrl->ldctl_oid ) )
                {
                        rc = LDAP_UNAVAILABLE_CRITICAL_EXTENSION;
+                       errmsg = "critical extension is unavailable ";
                        goto return_results;
                }
 
@@ -144,7 +151,11 @@ int get_ctrls(
 
 return_results:
        if( sendres && rc != LDAP_SUCCESS ) {
-               send_ldap_result( conn, op, rc, NULL, NULL );
+               if( rc == -1 ) {
+                       send_ldap_disconnect( conn, op, rc, errmsg );
+               } else {
+                       send_ldap_result( conn, op, rc, NULL, errmsg );
+               }
        }
 
        return rc;
index 87b320760121c137781f5569350614e2914c0702..4d0d7fb0764b8383faf970b722dc6613f8bb7a11 100644 (file)
@@ -47,8 +47,9 @@ do_delete(
 
        if ( ber_scanf( op->o_ber, "a", &ndn ) == LBER_ERROR ) {
                Debug( LDAP_DEBUG_ANY, "ber_scanf failed\n", 0, 0, 0 );
-               send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR, NULL, "" );
-               return rc;
+               send_ldap_disconnect( conn, op,
+                       LDAP_PROTOCOL_ERROR, "decoding error" );
+               return -1;
        }
 
        if( ( rc = get_ctrls( conn, op, 1 ) ) != LDAP_SUCCESS ) {
index 7ea18509163c1e2bfbdc28b19a14a67db2f46d4a..c1bed43cce662d58007fcc58a2842afd5f2a9985 100644 (file)
@@ -34,6 +34,7 @@ get_filter( Connection *conn, BerElement *ber, Filter **filt, char **fstr )
         *              lessOrEqual     [6]     AttributeValueAssertion,
         *              present         [7]     AttributeType,,
         *              approxMatch     [8]     AttributeValueAssertion
+        *              extensibleMatch [9] MatchingRuleAssertion
         *      }
         *
         *      SubstringFilter ::= SEQUENCE {
@@ -44,19 +45,27 @@ get_filter( Connection *conn, BerElement *ber, Filter **filt, char **fstr )
         *                      final            [2] IA5String
         *              }
         *      }
+        *
+     *  MatchingRuleAssertion ::= SEQUENCE {
+     *          matchingRule    [1] MatchingRuleId OPTIONAL,
+     *          type            [2] AttributeDescription OPTIONAL,
+     *          matchValue      [3] AssertionValue,
+     *          dnAttributes    [4] BOOLEAN DEFAULT FALSE
+        *      }
+        *
         */
 
        f = (Filter *) ch_malloc( sizeof(Filter) );
        f->f_next = NULL;
 
-       err = 0;
+       err = LDAP_SUCCESS;
        *fstr = NULL;
        f->f_choice = ber_peek_tag( ber, &len );
 
        switch ( f->f_choice ) {
        case LDAP_FILTER_EQUALITY:
                Debug( LDAP_DEBUG_FILTER, "EQUALITY\n", 0, 0, 0 );
-               if ( (err = get_ava( ber, &f->f_ava )) == 0 ) {
+               if ( (err = get_ava( ber, &f->f_ava )) == LDAP_SUCCESS ) {
                        *fstr = ch_malloc(4 + strlen( f->f_avtype ) +
                            f->f_avvalue.bv_len);
                        sprintf( *fstr, "(%s=%s)", f->f_avtype,
@@ -71,7 +80,7 @@ get_filter( Connection *conn, BerElement *ber, Filter **filt, char **fstr )
 
        case LDAP_FILTER_GE:
                Debug( LDAP_DEBUG_FILTER, "GE\n", 0, 0, 0 );
-               if ( (err = get_ava( ber, &f->f_ava )) == 0 ) {
+               if ( (err = get_ava( ber, &f->f_ava )) == LDAP_SUCCESS ) {
                        *fstr = ch_malloc(5 + strlen( f->f_avtype ) +
                            f->f_avvalue.bv_len);
                        sprintf( *fstr, "(%s>=%s)", f->f_avtype,
@@ -81,7 +90,7 @@ get_filter( Connection *conn, BerElement *ber, Filter **filt, char **fstr )
 
        case LDAP_FILTER_LE:
                Debug( LDAP_DEBUG_FILTER, "LE\n", 0, 0, 0 );
-               if ( (err = get_ava( ber, &f->f_ava )) == 0 ) {
+               if ( (err = get_ava( ber, &f->f_ava )) == LDAP_SUCCESS ) {
                        *fstr = ch_malloc(5 + strlen( f->f_avtype ) +
                            f->f_avvalue.bv_len);
                        sprintf( *fstr, "(%s<=%s)", f->f_avtype,
@@ -92,7 +101,7 @@ get_filter( Connection *conn, BerElement *ber, Filter **filt, char **fstr )
        case LDAP_FILTER_PRESENT:
                Debug( LDAP_DEBUG_FILTER, "PRESENT\n", 0, 0, 0 );
                if ( ber_scanf( ber, "a", &f->f_type ) == LBER_ERROR ) {
-                       err = LDAP_PROTOCOL_ERROR;
+                       err = -1;
                } else {
                        err = LDAP_SUCCESS;
                        attr_normalize( f->f_type );
@@ -103,7 +112,7 @@ get_filter( Connection *conn, BerElement *ber, Filter **filt, char **fstr )
 
        case LDAP_FILTER_APPROX:
                Debug( LDAP_DEBUG_FILTER, "APPROX\n", 0, 0, 0 );
-               if ( (err = get_ava( ber, &f->f_ava )) == 0 ) {
+               if ( (err = get_ava( ber, &f->f_ava )) == LDAP_SUCCESS ) {
                        *fstr = ch_malloc(5 + strlen( f->f_avtype ) +
                            f->f_avvalue.bv_len);
                        sprintf( *fstr, "(%s~=%s)", f->f_avtype,
@@ -114,7 +123,7 @@ get_filter( Connection *conn, BerElement *ber, Filter **filt, char **fstr )
        case LDAP_FILTER_AND:
                Debug( LDAP_DEBUG_FILTER, "AND\n", 0, 0, 0 );
                if ( (err = get_filter_list( conn, ber, &f->f_and, &ftmp ))
-                   == 0 ) {
+                   == LDAP_SUCCESS ) {
                        if (ftmp == NULL) ftmp = ch_strdup("");
                        *fstr = ch_malloc( 4 + strlen( ftmp ) );
                        sprintf( *fstr, "(&%s)", ftmp );
@@ -125,7 +134,7 @@ get_filter( Connection *conn, BerElement *ber, Filter **filt, char **fstr )
        case LDAP_FILTER_OR:
                Debug( LDAP_DEBUG_FILTER, "OR\n", 0, 0, 0 );
                if ( (err = get_filter_list( conn, ber, &f->f_or, &ftmp ))
-                   == 0 ) {
+                   == LDAP_SUCCESS ) {
                        if (ftmp == NULL) ftmp = ch_strdup("");
                        *fstr = ch_malloc( 4 + strlen( ftmp ) );
                        sprintf( *fstr, "(|%s)", ftmp );
@@ -136,7 +145,7 @@ get_filter( Connection *conn, BerElement *ber, Filter **filt, char **fstr )
        case LDAP_FILTER_NOT:
                Debug( LDAP_DEBUG_FILTER, "NOT\n", 0, 0, 0 );
                (void) ber_skip_tag( ber, &len );
-               if ( (err = get_filter( conn, ber, &f->f_not, &ftmp )) == 0 ) {
+               if ( (err = get_filter( conn, ber, &f->f_not, &ftmp )) == LDAP_SUCCESS ) {
                        if (ftmp == NULL) ftmp = ch_strdup("");
                        *fstr = ch_malloc( 4 + strlen( ftmp ) );
                        sprintf( *fstr, "(!%s)", ftmp );
@@ -144,6 +153,12 @@ get_filter( Connection *conn, BerElement *ber, Filter **filt, char **fstr )
                }
                break;
 
+       case LBER_DEFAULT:
+               Debug( LDAP_DEBUG_ANY, "decoding filter error\n",
+                      0, 0, 0 );
+               err = -1;
+               break;
+
        default:
                Debug( LDAP_DEBUG_ANY, "unknown filter type %lu\n",
                       f->f_choice, 0, 0 );
@@ -151,7 +166,7 @@ get_filter( Connection *conn, BerElement *ber, Filter **filt, char **fstr )
                break;
        }
 
-       if ( err != 0 ) {
+       if ( err != LDAP_SUCCESS ) {
                free( (char *) f );
                if ( *fstr != NULL ) {
                        free( *fstr );
@@ -178,8 +193,9 @@ get_filter_list( Connection *conn, BerElement *ber, Filter **f, char **fstr )
        *fstr = NULL;
        new = f;
        for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
-           tag = ber_next_element( ber, &len, last ) ) {
-               if ( (err = get_filter( conn, ber, new, &ftmp )) != 0 )
+           tag = ber_next_element( ber, &len, last ) )
+       {
+               if ( (err = get_filter( conn, ber, new, &ftmp )) != LDAP_SUCCESS )
                        return( err );
                if ( *fstr == NULL ) {
                        *fstr = ftmp;
@@ -194,7 +210,7 @@ get_filter_list( Connection *conn, BerElement *ber, Filter **f, char **fstr )
        *new = NULL;
 
        Debug( LDAP_DEBUG_FILTER, "end get_filter_list\n", 0, 0, 0 );
-       return( 0 );
+       return( LDAP_SUCCESS );
 }
 
 static int
@@ -214,7 +230,7 @@ get_substring_filter(
        Debug( LDAP_DEBUG_FILTER, "begin get_substring_filter\n", 0, 0, 0 );
 
        if ( ber_scanf( ber, "{a" /*}*/, &f->f_sub_type ) == LBER_ERROR ) {
-               return( LDAP_PROTOCOL_ERROR );
+               return( -1 );
        }
        attr_normalize( f->f_sub_type );
        syntax = attr_syntax( f->f_sub_type );
@@ -225,10 +241,11 @@ get_substring_filter(
        *fstr = ch_malloc( strlen( f->f_sub_type ) + 3 );
        sprintf( *fstr, "(%s=", f->f_sub_type );
        for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT;
-           tag = ber_next_element( ber, &len, last ) ) {
-                       rc = ber_scanf( ber, "a", &val );
+           tag = ber_next_element( ber, &len, last ) )
+       {
+               rc = ber_scanf( ber, "a", &val );
                if ( rc == LBER_ERROR ) {
-                       return( LDAP_PROTOCOL_ERROR );
+                       return( -1 );
                }
                if ( val == NULL || *val == '\0' ) {
                        if ( val != NULL ) {
@@ -284,7 +301,7 @@ get_substring_filter(
        strcat( *fstr, ")" );
 
        Debug( LDAP_DEBUG_FILTER, "end get_substring_filter\n", 0, 0, 0 );
-       return( 0 );
+       return( LDAP_SUCCESS );
 }
 
 void
index 6800343d723979cfe529954ad603fbca91df1ca6..898d368c6a256c68606e9b066134768aae059fc9 100644 (file)
@@ -200,6 +200,10 @@ SOURCE=.\entry.c
 # End Source File
 # Begin Source File
 
+SOURCE=.\extended.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\filter.c
 # End Source File
 # Begin Source File
index 6be8038bdfd7257c6b749bb0ea539fc246a96e0a..ccae24d41f0a5f51d3d70c2359f464a59623f394 100644 (file)
@@ -71,8 +71,9 @@ do_modify(
 
        if ( ber_scanf( op->o_ber, "{a" /*}*/, &ndn ) == LBER_ERROR ) {
                Debug( LDAP_DEBUG_ANY, "ber_scanf failed\n", 0, 0, 0 );
-               send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR, NULL, "" );
-               return rc;
+               send_ldap_disconnect( conn, op,
+                       LDAP_PROTOCOL_ERROR, "decoding error" );
+               return -1;
        }
 
        Debug( LDAP_DEBUG_ARGS, "do_modify: dn (%s)\n", ndn, 0, 0 );
@@ -95,13 +96,13 @@ do_modify(
                    &(*modtail)->ml_type, &(*modtail)->ml_bvalues )
                    == LBER_ERROR )
                {
-                       send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR, NULL,
-                           "decoding error" );
+                       send_ldap_disconnect( conn, op,
+                               LDAP_PROTOCOL_ERROR, "decoding modlist error" );
                        free( ndn );
                        free( *modtail );
                        *modtail = NULL;
                        modlist_free( modlist );
-                       return rc;
+                       return -1;
                }
 
                (*modtail)->ml_op = mop;
@@ -110,21 +111,21 @@ do_modify(
                    (*modtail)->ml_op != LDAP_MOD_DELETE &&
                    (*modtail)->ml_op != LDAP_MOD_REPLACE )
                {
-                       send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR, NULL,
-                           "unrecognized modify operation" );
+                       send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR,
+                           NULL, "unrecognized modify operation" );
                        free( ndn );
                        modlist_free( modlist );
-                       return rc;
+                       return LDAP_PROTOCOL_ERROR;
                }
 
                if ( (*modtail)->ml_bvalues == NULL
                        && (*modtail)->ml_op != LDAP_MOD_DELETE )
                {
-                       send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR, NULL,
-                           "no values given" );
+                       send_ldap_result( conn, op, LDAP_PROTOCOL_ERROR,
+                           NULL, "unrecognized modify operation" );
                        free( ndn );
                        modlist_free( modlist );
-                       return rc;
+                       return LDAP_PROTOCOL_ERROR;
                }
                attr_normalize( (*modtail)->ml_type );
 
index d3f04f8ff52f80e17506e6c2f22ab152b3058e37..c80a605fbd3ffcd58ad41ded1a1908150e65a4d4 100644 (file)
@@ -72,8 +72,9 @@ do_modrdn(
        if ( ber_scanf( op->o_ber, "{aab", &ndn, &newrdn, &deloldrdn )
            == LBER_ERROR ) {
                Debug( LDAP_DEBUG_ANY, "ber_scanf failed\n", 0, 0, 0 );
-               send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR, NULL, "" );
-               return rc;
+               send_ldap_disconnect( conn, op,
+                       LDAP_PROTOCOL_ERROR, "decoding error" );
+               return -1;
        }
 
        /* Check for newSuperior parameter, if present scan it */
@@ -96,9 +97,9 @@ do_modrdn(
                        Debug( LDAP_DEBUG_ANY,
                               "modrdn(v2): invalid field newSuperior!\n",
                               0, 0, 0 );
-                       send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR,
-                                         NULL, "" );
-                       return rc;
+                       send_ldap_disconnect( conn, op,
+                               LDAP_PROTOCOL_ERROR, "newSuperior requires LDAPv3" );
+                       return -1;
                }
 
                if ( ber_scanf( op->o_ber, "a", &newSuperior ) 
@@ -106,9 +107,9 @@ do_modrdn(
 
                    Debug( LDAP_DEBUG_ANY, "ber_scanf(\"a\"}) failed\n",
                           0, 0, 0 );
-                   send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR, NULL,
-                                     "" );
-                   return rc;
+                       send_ldap_disconnect( conn, op,
+                               LDAP_PROTOCOL_ERROR, "decoding error" );
+                   return -1;
 
                }
 
@@ -124,12 +125,11 @@ do_modrdn(
                free( newrdn ); 
                free( newSuperior );
                Debug( LDAP_DEBUG_ANY, "do_modrdn: ber_scanf failed\n", 0, 0, 0 );
-               send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR, NULL,
-                   "decoding error" );
-               return rc;
+               send_ldap_disconnect( conn, op,
+                               LDAP_PROTOCOL_ERROR, "decoding error" );
+               return -1;
        }
 
-#ifdef  GET_CTRLS
        if( (rc = get_ctrls( conn, op, 1 )) != LDAP_SUCCESS ) {
                free( ndn );
                free( newrdn ); 
@@ -137,7 +137,6 @@ do_modrdn(
                Debug( LDAP_DEBUG_ANY, "do_modrdn: get_ctrls failed\n", 0, 0, 0 );
                return rc;
        } 
-#endif
 
        if( newSuperior != NULL ) {
                /* GET BACKEND FOR NEW SUPERIOR */
index 9dcf13d9e9714d385d3e1551df628a5a5b227202..a5a5274f120f1cab29df8750ea0fa999cb3e9e72 100644 (file)
 #include "ldap_defaults.h"
 #include "slap.h"
 
-char *supportedExtensions[] = {
-       NULL
-};
-
 #if defined( SLAPD_MONITOR_DN )
 
 void
@@ -232,7 +228,7 @@ monitor_info( Connection *conn, Operation *op )
        attr_merge( e, "concurrency", vals );
 #endif
 
-       send_search_entry( &backends[0], conn, op, e, NULL, 0 );
+       send_search_entry( &backends[0], conn, op, e, NULL, 0, 1 );
        send_ldap_search_result( conn, op, LDAP_SUCCESS, NULL, NULL, 1 );
 
        entry_free( e );
index d8c33673a615e5b6a3b89dfd7fc3ba4fc0ebd634..23cd1297bdadf5b87f06c47517db6d89834eade2 100644 (file)
@@ -257,17 +257,26 @@ void replog LDAP_P(( Backend *be, int optype, char *dn, void *change, int flag )
  * result.c
  */
 
-void send_ldap_result LDAP_P(( Connection *conn, Operation *op, int err, char *matched,
-       char *text ));
-void send_ldap_search_result LDAP_P(( Connection *conn, Operation *op, int err,
-       char *matched, char *text, int nentries ));
+void send_ldap_result LDAP_P((
+       Connection *conn, Operation *op,
+       int err, char *matched, char *text ));
+
+void send_ldap_disconnect LDAP_P((
+       Connection *conn, Operation *op,
+       int err, char *text ));
+
+void send_ldap_search_result LDAP_P((
+       Connection *conn, Operation *op,
+       int err, char *matched, char *text, int nentries ));
 
 /*
  * schema.c
  */
 
 int oc_schema_check LDAP_P(( Entry *e ));
-int oc_check_operational LDAP_P(( char *type ));
+int oc_check_operational_attr LDAP_P(( char *type ));
+int oc_check_usermod_attr LDAP_P(( char *type ));
+int oc_check_no_usermod_attr LDAP_P(( char *type ));
 ObjectClass *oc_find LDAP_P((const char *ocname));
 int oc_add LDAP_P((LDAP_OBJECT_CLASS *oc, const char **err));
 Syntax *syn_find LDAP_P((const char *synname));
@@ -401,9 +410,12 @@ extern int do_modify LDAP_P((Connection *conn, Operation *op));
 extern int     do_modrdn LDAP_P((Connection *conn, Operation *op));
 extern int     do_search LDAP_P((Connection *conn, Operation *op));
 extern int     do_unbind LDAP_P((Connection *conn, Operation *op));
-extern int     do_exop LDAP_P((Connection *conn, Operation *op));
+extern int     do_extended LDAP_P((Connection *conn, Operation *op));
+
+extern int send_search_entry LDAP_P((
+       Backend *be, Connection *conn, Operation *op,
+       Entry *e, char **attrs, int attrsonly, int opattrs ));
 
-extern int send_search_entry LDAP_P((Backend *be, Connection *conn, Operation *op, Entry *e, char **attrs, int attrsonly));
 extern int str2result LDAP_P(( char *s, int *code, char **matched, char **info ));
 
 extern ber_socket_t dtblsize;
index e9c05de439232c1a142dc5a5ce8ce60056822af7..4fbe02e21ccb20d0de1ff9faf232f587552e1e1e 100644 (file)
@@ -20,6 +20,7 @@ static void
 send_ldap_result2(
     Connection *conn,
     Operation  *op,
+       int             disconnect,
     ber_int_t  err,
     char       *matched,
     char       *text,
@@ -30,32 +31,50 @@ send_ldap_result2(
        int             rc;
        ber_tag_t       tag;
        ber_len_t       bytes;
+       int     msgid;
 
        assert( !LDAP_API_ERROR( err ) );
 
        if ( err == LDAP_PARTIAL_RESULTS && (text == NULL || *text == '\0') )
                err = LDAP_NO_SUCH_OBJECT;
 
-       Debug( LDAP_DEBUG_TRACE, "send_ldap_result %d:%s:%s\n", err,
-               matched ?  matched : "",
-               text ? text : "" );
+       if( disconnect ) {
+               msgid = 0;      /* unsolicited */
+               if ( op->o_protocol > LDAP_VERSION3 ) {
+                       tag = LDAP_RES_EXTENDED;
+               }
+
+#define LDAP_UNSOLICITED_ERROR(e) \
+       (  (e) == LDAP_PROTOCOL_ERROR \
+       || (e) == LDAP_STRONG_AUTH_REQUIRED \
+       || (e) == LDAP_UNAVAILABLE )
+
+               assert( LDAP_UNSOLICITED_ERROR( err ) );
 
-       switch ( op->o_tag ) {
-       case LBER_DEFAULT:
-               tag = LBER_SEQUENCE;
-               break;
+       } else {
+               msgid = op->o_msgid;
+
+               switch ( op->o_tag ) {
+               case LDAP_REQ_ABANDON:
+               case LDAP_REQ_UNBIND:
+               case LBER_ERROR:
+                       tag = LBER_SEQUENCE;
+                       msgid = 0;
+                       assert( LDAP_UNSOLICITED_ERROR( err ) );
+                       break;
 
-       case LDAP_REQ_SEARCH:
-               tag = LDAP_RES_SEARCH_RESULT;
-               break;
+               case LDAP_REQ_SEARCH:
+                       tag = LDAP_RES_SEARCH_RESULT;
+                       break;
 
-       case LDAP_REQ_DELETE:
-               tag = LDAP_RES_DELETE;
-               break;
+               case LDAP_REQ_DELETE:
+                       tag = LDAP_RES_DELETE;
+                       break;
 
-       default:
-               tag = op->o_tag + 1;
-               break;
+               default:
+                       tag = op->o_tag + 1;
+                       break;
+               }
        }
 
 
@@ -68,13 +87,20 @@ send_ldap_result2(
 
 #ifdef LDAP_CONNECTIONLESS
        if ( op->o_cldap ) {
-               rc = ber_printf( ber, "{is{t{ess}}}", op->o_msgid, "", tag,
+               rc = ber_printf( ber, "{is{t{ess}}}", msgid, "", tag,
                    err, matched ? matched : "", text ? text : "" );
        } else
 #endif
-       {
-               rc = ber_printf( ber, "{it{ess}}", op->o_msgid, tag, err,
-                   matched ? matched : "", text ? text : "" );
+       if( tag == LDAP_RES_EXTENDED ) {
+               rc = ber_printf( ber, "{it{esss}}",
+                       msgid, tag, err,
+                       "", text ? text : "",
+                       LDAP_NOTICE_DISCONNECT );
+
+       } else {
+               rc = ber_printf( ber, "{it{ess}}",
+                       msgid, tag, err,
+                       matched ? matched : "", text ? text : "" );
        }
 
        if ( rc == -1 ) {
@@ -158,6 +184,9 @@ send_ldap_result(
 {
        assert( !LDAP_API_ERROR( err ) );
 
+       Debug( LDAP_DEBUG_TRACE, "send_ldap_result %d:%s:%s\n",
+               err, matched ?  matched : "", text ? text : "" );
+
 #ifdef LDAP_CONNECTIONLESS
        if ( op->o_cldap ) {
                ber_pvt_sb_udp_set_dst( &conn->c_sb, &op->o_clientaddr );
@@ -168,7 +197,34 @@ send_ldap_result(
                    0 );
        }
 #endif
-       send_ldap_result2( conn, op, err, matched, text, 0 );
+       send_ldap_result2( conn, op, 0, err, matched, text, 0 );
+}
+
+void
+send_ldap_disconnect(
+    Connection *conn,
+    Operation  *op,
+    ber_int_t  err,
+    char       *text
+)
+{
+       assert( !LDAP_API_ERROR( err ) );
+
+       Debug( LDAP_DEBUG_TRACE,
+               "send_ldap_disconnect %d:%s\n",
+               err, text ? text : "", NULL );
+
+#ifdef LDAP_CONNECTIONLESS
+       if ( op->o_cldap ) {
+               ber_pvt_sb_udp_set_dst( &conn->c_sb, &op->o_clientaddr );
+               Debug( LDAP_DEBUG_TRACE, "UDP response to %s port %d\n", 
+                   inet_ntoa(((struct sockaddr_in *)
+                   &op->o_clientaddr)->sin_addr ),
+                   ((struct sockaddr_in *) &op->o_clientaddr)->sin_port,
+                   0 );
+       }
+#endif
+       send_ldap_result2( conn, op, 0, err, NULL, text, 0 );
 }
 
 void
@@ -181,7 +237,10 @@ send_ldap_search_result(
     int                nentries
 )
 {
-       send_ldap_result2( conn, op, err, matched, text, nentries );
+       Debug( LDAP_DEBUG_TRACE, "send_ldap_search_result %d:%s:%s\n",
+               err, matched ?  matched : "", text ? text : "" );
+
+       send_ldap_result2( conn, op, 0, err, matched, text, nentries );
 }
 
 int
@@ -191,7 +250,8 @@ send_search_entry(
     Operation  *op,
     Entry      *e,
     char       **attrs,
-    int                attrsonly
+    int                attrsonly,
+       int             opattrs
 )
 {
        BerElement      *ber;
@@ -202,6 +262,17 @@ send_search_entry(
 
        Debug( LDAP_DEBUG_TRACE, "=> send_search_entry (%s)\n", e->e_dn, 0, 0 );
 
+#if defined( SLAPD_SCHEMA_DN )
+       {
+               /* this could be backend specific */
+               struct  berval  val;
+               val.bv_val = SLAPD_SCHEMA_DN;
+               val.bv_len = strlen( val.bv_val );
+               attr_merge( e, "subschemaSubentry", vals );
+               ldap_memfree( val.bv_val );
+       }
+#endif
+
        if ( ! access_allowed( be, conn, op, e,
                "entry", NULL, ACL_READ ) )
        {
@@ -237,12 +308,15 @@ send_search_entry(
 
                if ( attrs == NULL ) {
                        /* all addrs request, skip operational attributes */
-                       if( oc_check_operational( a->a_type )) {
+                       if( !opattrs && oc_check_operational_attr( a->a_type )) {
                                continue;
                        }
+
                } else {
                        /* specific addrs requested */
-                       if ( !charray_inlist( attrs, a->a_type )) {
+                       if ( !charray_inlist( attrs, a->a_type )
+                               && !charray_inlist( attrs, LDAP_ALL_USER_ATTRIBUTES ) )
+                       {
                                continue;
                        }
                }
index f609e7114223e21b80ad7dbdeb16946029c477cf..540d218d1363740b68537f526de6306329048859 100644 (file)
@@ -19,8 +19,8 @@
 void
 root_dse_info( Connection *conn, Operation *op, char **attrs, int attrsonly )
 {
+       char buf[BUFSIZ];
        Entry           *e;
-       char            buf[BUFSIZ];
        struct berval   val;
        struct berval   *vals[2];
        int             i, j;
@@ -37,51 +37,44 @@ root_dse_info( Connection *conn, Operation *op, char **attrs, int attrsonly )
 
        for ( i = 0; i < nbackends; i++ ) {
                for ( j = 0; backends[i].be_suffix[j] != NULL; j++ ) {
-                       strcpy( buf, backends[i].be_suffix[j] );
-                       val.bv_val = buf;
-                       val.bv_len = strlen( buf );
+                       val.bv_val = backends[i].be_suffix[j];
+                       val.bv_len = strlen( val.bv_val );
                        attr_merge( e, "namingContexts", vals );
                }
        }
 
 #if defined( SLAPD_MONITOR_DN )
-       strcpy( buf, SLAPD_MONITOR_DN );
-       val.bv_val = buf;
-       val.bv_len = strlen( buf );
+       val.bv_val = SLAPD_MONITOR_DN;
+       val.bv_len = strlen( val.bv_val );
        attr_merge( e, "namingContexts", vals );
+       /* subschemasubentry is added by send_search_entry() */
 #endif
 
 #if defined( SLAPD_CONFIG_DN )
-       strcpy( buf, SLAPD_CONFIG_DN );
-       val.bv_val = buf;
-       val.bv_len = strlen( buf );
+       val.bv_val = SLAPD_CONFIG_DN;
+       val.bv_len = strlen( val.bv_val );
        attr_merge( e, "namingContexts", vals );
 #endif
 
 #if defined( SLAPD_SCHEMA_DN )
-       strcpy( buf, SLAPD_SCHEMA_DN );
-       val.bv_val = buf;
+       val.bv_val = SLAPD_SCHEMA_DN;
        val.bv_len = strlen( val.bv_val );
        attr_merge( e, "namingContexts", vals );
-       attr_merge( e, "subschemaSubentry", vals );
-       ldap_memfree( val.bv_val );
 #endif
 
        /* altServer unsupported */
 
        /* supportedControl */
        for ( i=0; supportedControls[i] != NULL; i++ ) {
-               strcpy( buf, supportedControls[i] );
-               val.bv_val = buf;
-               val.bv_len = strlen( buf );
+               val.bv_val = supportedControls[i];
+               val.bv_len = strlen( val.bv_val );
                attr_merge( e, "supportedControl", vals );
        }
 
        /* supportedExtension */
        for ( i=0; supportedExtensions[i] != NULL; i++ ) {
-               strcpy( buf, supportedExtensions[i] );
-               val.bv_val = buf;
-               val.bv_len = strlen( buf );
+               val.bv_val = supportedExtensions[i];
+               val.bv_len = strlen( val.bv_val );
                attr_merge( e, "supportedExtension", vals );
        }
 
@@ -89,20 +82,19 @@ root_dse_info( Connection *conn, Operation *op, char **attrs, int attrsonly )
        for ( i=LDAP_VERSION_MIN; i<=LDAP_VERSION_MAX; i++ ) {
                sprintf(buf,"%d",i);
                val.bv_val = buf;
-               val.bv_len = strlen( buf );
+               val.bv_len = strlen( val.bv_val );
                attr_merge( e, "supportedLDAPVersion", vals );
        }
 
        /* supportedSASLMechanism */
        for ( i=0; supportedSASLMechanisms[i] != NULL; i++ ) {
-               strcpy( buf, supportedSASLMechanisms[i] );
-               val.bv_val = buf;
-               val.bv_len = strlen( buf );
+               val.bv_val = supportedSASLMechanisms[i];
+               val.bv_len = strlen( val.bv_val );
                attr_merge( e, "supportedSASLMechanism", vals );
        }
 
 
-       send_search_entry( &backends[0], conn, op, e, attrs, attrsonly );
+       send_search_entry( &backends[0], conn, op, e, attrs, attrsonly, 1 );
        send_ldap_search_result( conn, op, LDAP_SUCCESS, NULL, NULL, 1 );
 
        entry_free( e );
index 746833f796a67027edf244676b1127128244c636..e71913e0e66b868fac3235491b20ca69c5372b20 100644 (file)
@@ -123,20 +123,78 @@ oc_check_required( Entry *e, char *ocname )
        return( NULL );
 }
 
+static char *oc_usermod_attrs[] = {
+       /*
+        * OpenLDAP doesn't support any user modification of
+        * operational attributes.
+        */
+       NULL
+};
+
+static char *oc_operational_attrs[] = {
+       /*
+        * these are operational attributes that *could* be
+        * modified by users if we supported such.
+        */
+       "objectClasses",
+       "attributeTypes",
+       "matchingRules",
+       "matchingRuleUse",
+       "dITStructureRules",
+       "dITContentRules",
+       "nameForms",
+       "ldapSyntaxes",
+       NULL
+
+};
+
+/* this list should be extensible  */
+static char *oc_no_usermod_attrs[] = {
+       /*
+        * Operational and 'no user modification' attributes
+        */
+
+       /* RFC2252, 3.2.1 */
+       "creatorsName",
+       "createTimestamp",
+       "modifiersName",
+       "modifyTimestamp",
+       "subschemaSubentry",
+
+       NULL
+};
+
+
 /*
  * check to see if attribute is 'operational' or not.
- * this list should be extensible...
  */
 int
-oc_check_operational( char *type )
+oc_check_operational_attr( char *type )
 {
-       return ( strcasecmp( type, "modifiersname" ) == 0 ||
-               strcasecmp( type, "modifytimestamp" ) == 0 ||
-               strcasecmp( type, "creatorsname" ) == 0 ||
-               strcasecmp( type, "createtimestamp" ) == 0 )
-               ? 1 : 0;
+       return charray_inlist( oc_operational_attrs, type )
+               || charray_inlist( oc_usermod_attrs, type )
+               || charray_inlist( oc_no_usermod_attrs, type );
 }
 
+/*
+ * check to see if attribute can be user modified or not.
+ */
+int
+oc_check_usermod_attr( char *type )
+{
+       return charray_inlist( oc_usermod_attrs, type );
+}
+
+/*
+ * check to see if attribute is 'no user modification' or not.
+ */
+int
+oc_check_no_usermod_attr( char *type )
+{
+       return charray_inlist( oc_no_usermod_attrs, type );
+}
+
+
 static int
 oc_check_allowed( char *type, struct berval **ocl )
 {
@@ -153,7 +211,12 @@ oc_check_allowed( char *type, struct berval **ocl )
                return( 0 );
        }
 
-       if ( oc_check_operational( type ) ) {
+       /*
+        * All operational attributions are allowed by schema rules.
+        * However, we only check attributions which are stored in the
+        * the directory regardless if they are user or non-user modified.
+        */
+       if ( oc_check_usermod_attr( type ) || oc_check_no_usermod_attr( type ) ) {
                return( 0 );
        }
 
@@ -1080,7 +1143,7 @@ schema_info( Connection *conn, Operation *op, char **attrs, int attrsonly )
                return;
        }
        
-       send_search_entry( &backends[0], conn, op, e, attrs, attrsonly );
+       send_search_entry( &backends[0], conn, op, e, attrs, attrsonly, 0 );
        send_ldap_search_result( conn, op, LDAP_SUCCESS, NULL, NULL, 1 );
 
        entry_free( e );
index fece855dc78622529108cc9d244c4971fe77fbe2..38f44be01cc651c3f81486aa7eec93ef53c6dc85 100644 (file)
@@ -74,14 +74,17 @@ do_search(
        if ( ber_scanf( op->o_ber, "{aiiiib",
                &base, &scope, &deref, &sizelimit,
            &timelimit, &attrsonly ) == LBER_ERROR ) {
-               send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR, NULL, "" );
+               send_ldap_disconnect( conn, op,
+                       LDAP_PROTOCOL_ERROR, "decoding error" );
+               rc = -1;
                goto return_results;
        }
 
        if ( scope != LDAP_SCOPE_BASE && scope != LDAP_SCOPE_ONELEVEL
            && scope != LDAP_SCOPE_SUBTREE ) {
-               send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR, NULL,
-                   "Unknown search scope" );
+               send_ldap_disconnect( conn, op,
+                       LDAP_PROTOCOL_ERROR, "decoding error" );
+               rc = -1;
                goto return_results;
        }
 
@@ -93,14 +96,22 @@ do_search(
 
        /* filter - returns a "normalized" version */
        if ( (err = get_filter( conn, op->o_ber, &filter, &fstr )) != 0 ) {
-               send_ldap_result( conn, op, err, NULL, "Bad search filter" );
+               if( err == -1 ) {
+                       send_ldap_disconnect( conn, op,
+                               LDAP_PROTOCOL_ERROR, "decode error" );
+               } else {
+                       send_ldap_result( conn, op, err, NULL, "Bad search filter" );
+               }
                goto return_results;
        }
+
        Debug( LDAP_DEBUG_ARGS, "    filter: %s\n", fstr, 0, 0 );
 
        /* attributes */
        if ( ber_scanf( op->o_ber, /*{*/ "{v}}", &attrs ) == LBER_ERROR ) {
-               send_ldap_result( conn, op, rc = LDAP_PROTOCOL_ERROR, NULL, "" );
+               send_ldap_disconnect( conn, op,
+                       LDAP_PROTOCOL_ERROR, "decoding error" );
+               rc = -1;
                goto return_results;
        }
 
index d84e8e5bd5be30f1da6dc8a84b8e66c32a89e965..be5a177ab7b7530ffe7da65d197b39b42a16aa70 100644 (file)
@@ -55,7 +55,8 @@ send_search_entry(
        Operation   *op,
        Entry   *e,
        char    **attrs,
-       int             attrsonly
+       int             attrsonly,
+       int             opattrs
 )        
 {
        assert(0);