]> git.sur5r.net Git - openldap/commitdiff
Initial support for pre/post read controls.
authorKurt Zeilenga <kurt@openldap.org>
Tue, 16 Sep 2003 18:56:04 +0000 (18:56 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Tue, 16 Sep 2003 18:56:04 +0000 (18:56 +0000)
TODO:
Fix transactional consistency
Add client response control handling

18 files changed:
clients/tools/common.c
clients/tools/common.h
clients/tools/ldapmodify.c
include/lber.h
include/ldap.h
servers/slapd/back-bdb/add.c
servers/slapd/back-bdb/delete.c
servers/slapd/back-bdb/modify.c
servers/slapd/back-bdb/modrdn.c
servers/slapd/back-bdb/search.c
servers/slapd/connection.c
servers/slapd/controls.c
servers/slapd/dn.c
servers/slapd/operation.c
servers/slapd/proto-slap.h
servers/slapd/result.c
servers/slapd/slap.h
servers/slapd/tools/mimic.c

index f6cac8bd1c27c6a55aa1543973df7f04116fd2a5..1266f3010f6352e61bb4d0002b4fd0661aad6ff8 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "lutil_ldap.h"
 #include "ldap_defaults.h"
+#include "ldap_pvt.h"
 
 #include "common.h"
 
@@ -41,10 +42,15 @@ char        *sasl_secprops = NULL;
 #endif
 int   use_tls = 0;
 
+int      assertctl;
 char *assertion = NULL;
 char *authzid = NULL;
 int   manageDSAit = 0;
 int   noop = 0;
+int   preread = 0;
+char *preread_attrs = NULL;
+int   postread = 0;
+char *postread_attrs = NULL;
 
 int   not = 0;
 int   want_bindpw = 0;
@@ -75,10 +81,12 @@ N_("  -C         chase referrals\n"),
 N_("  -d level   set LDAP debugging level to `level'\n"),
 N_("  -D binddn  bind DN\n"),
 N_("  -e [!]<ctrl>[=<ctrlparam>] general controls (! indicates criticality)\n")
-N_("             [!]assert=<filter>   (an RFC 2254 Filter)\n")
-N_("             [!]authzid=<authzid> (\"dn:<dn>\" or \"u:<user>\")\n")
-N_("             [!]manageDSAit       (alternate form, see -M)\n")
+N_("             [!]assert=<filter>     (an RFC 2254 Filter)\n")
+N_("             [!]authzid=<authzid>   (\"dn:<dn>\" or \"u:<user>\")\n")
+N_("             [!]manageDSAit\n")
 N_("             [!]noop\n"),
+N_("             [!]postread[=<attrs>]  (a comma-separated attribute list)\n"),
+N_("             [!]preread[=<attrs>]   (a comma-separated attribute list)\n"),
 N_("  -f file    read operations from `file'\n"),
 N_("  -h host    LDAP server\n"),
 N_("  -H URI     LDAP Uniform Resource Indentifier(s)\n"),
@@ -158,7 +166,7 @@ tool_args( int argc, char **argv )
                        }
 
                        if ( strcasecmp( control, "assert" ) == 0 ) {
-                               if( assertion != NULL ) {
+                               if( assertctl ) {
                                        fprintf( stderr, "assert control previously specified\n");
                                        exit( EXIT_FAILURE );
                                }
@@ -167,6 +175,8 @@ tool_args( int argc, char **argv )
                                        usage();
                                }
 
+                               assertctl = 1 + crit;
+
                                assert( assertion == NULL );
                                assertion = cvalue;
 
@@ -213,6 +223,24 @@ tool_args( int argc, char **argv )
 
                                noop = 1 + crit;
 
+                       } else if ( strcasecmp( control, "preread" ) == 0 ) {
+                               if( preread ) {
+                                       fprintf( stderr, "preread control previously specified\n");
+                                       exit( EXIT_FAILURE );
+                               }
+
+                               preread = 1 + crit;
+                               preread_attrs = cvalue;
+
+                       } else if ( strcasecmp( control, "postread" ) == 0 ) {
+                               if( postread ) {
+                                       fprintf( stderr, "postread control previously specified\n");
+                                       exit( EXIT_FAILURE );
+                               }
+
+                               postread = 1 + crit;
+                               postread_attrs = cvalue;
+
                        } else {
                                fprintf( stderr, "Invalid general control name: %s\n",
                                        control );
@@ -725,7 +753,7 @@ void
 tool_server_controls( LDAP *ld, LDAPControl *extra_c, int count )
 {
        int i = 0, j, crit = 0, err;
-       LDAPControl c[4], **ctrls;
+       LDAPControl c[6], **ctrls;
 
        ctrls = (LDAPControl**) malloc(sizeof(c) + (count+1)*sizeof(LDAPControl*));
        if ( ctrls == NULL ) {
@@ -733,11 +761,11 @@ tool_server_controls( LDAP *ld, LDAPControl *extra_c, int count )
                exit( EXIT_FAILURE );
        }
 
-       if ( assertion ) {
+       if ( assertctl ) {
                char berbuf[LBER_ELEMENT_SIZEOF];
                BerElement *ber = (BerElement *)berbuf;
                
-               if( *assertion == '\0' ) {
+               if( assertion == NULL || *assertion == '\0' ) {
                        fprintf( stderr, "Assertion=<empty>\n" );
                        exit( EXIT_FAILURE );
                }
@@ -757,7 +785,7 @@ tool_server_controls( LDAP *ld, LDAPControl *extra_c, int count )
                }
 
                c[i].ldctl_oid = LDAP_CONTROL_ASSERT;
-               c[i].ldctl_iscritical = 1;
+               c[i].ldctl_iscritical = assertctl > 1;
                ctrls[i] = &c[i];
                i++;
        }
@@ -789,6 +817,66 @@ tool_server_controls( LDAP *ld, LDAPControl *extra_c, int count )
                i++;
        }
        
+       if ( preread ) {
+               char berbuf[LBER_ELEMENT_SIZEOF];
+               BerElement *ber = (BerElement *)berbuf;
+               char **attrs;
+
+               if( preread_attrs ) {
+                       attrs = ldap_str2charray( preread_attrs, "," );
+               }
+
+               ber_init2( ber, NULL, LBER_USE_DER );
+
+               if( ber_printf( ber, "{v}", attrs ) == -1 ) {
+                       fprintf( stderr, "preread attrs encode failed.\n" );
+                       exit( EXIT_FAILURE );
+               }
+
+               err = ber_flatten2( ber, &c[i].ldctl_value, 0 );
+               if( err < 0 ) {
+                       fprintf( stderr, "preread flatten failed (%d)\n", err );
+                       exit( EXIT_FAILURE );
+               }
+
+               c[i].ldctl_oid = LDAP_CONTROL_PRE_READ;
+               c[i].ldctl_iscritical = preread > 1;
+               ctrls[i] = &c[i];
+               i++;
+
+               if( attrs ) ldap_charray_free( attrs );
+       }
+
+       if ( postread ) {
+               char berbuf[LBER_ELEMENT_SIZEOF];
+               BerElement *ber = (BerElement *)berbuf;
+               char **attrs;
+
+               if( postread_attrs ) {
+                       attrs = ldap_str2charray( postread_attrs, "," );
+               }
+
+               ber_init2( ber, NULL, LBER_USE_DER );
+
+               if( ber_printf( ber, "{v}", attrs ) == -1 ) {
+                       fprintf( stderr, "postread attrs encode failed.\n" );
+                       exit( EXIT_FAILURE );
+               }
+
+               err = ber_flatten2( ber, &c[i].ldctl_value, 0 );
+               if( err < 0 ) {
+                       fprintf( stderr, "postread flatten failed (%d)\n", err );
+                       exit( EXIT_FAILURE );
+               }
+
+               c[i].ldctl_oid = LDAP_CONTROL_POST_READ;
+               c[i].ldctl_iscritical = postread > 1;
+               ctrls[i] = &c[i];
+               i++;
+
+               if( attrs ) ldap_charray_free( attrs );
+       }
+
        while ( count-- ) {
                ctrls[i++] = extra_c++;
        }
index 38ecf7d4bf7f535ba78d9808f44d52ee9760915a..dba31d251c94421b1d48b4fe590d432ba9d9e323 100644 (file)
@@ -33,6 +33,7 @@ extern char *assertion;
 extern char *authzid;
 extern int   manageDSAit;
 extern int   noop;
+extern int     preread, postread;
 
 extern int   not;
 extern int   want_bindpw;
index 219be2c5fd71728de18a2595a243a7e1d20fbac7..ff60a8b78ea65a1810cbd0ec0dcdfcc76697d863 100644 (file)
@@ -225,7 +225,7 @@ main( int argc, char **argv )
 
     rc = 0;
 
-       if ( assertion || authzid || manageDSAit || noop ) {
+       if ( assertion || authzid || manageDSAit || noop || preread || postread ) {
                tool_server_controls( ld, NULL, 0 );
        }
 
index c01b3acc04f59ac2ff4412317ea0a910e6e3050f..728f575090fd96796802bb52e9c39402e0b4881c 100644 (file)
@@ -532,9 +532,7 @@ LBER_V( Sockbuf_IO ) ber_sockbuf_io_tcp;
 LBER_V( Sockbuf_IO ) ber_sockbuf_io_readahead;
 LBER_V( Sockbuf_IO ) ber_sockbuf_io_fd;
 LBER_V( Sockbuf_IO ) ber_sockbuf_io_debug;
-#ifdef LDAP_CONNECTIONLESS
 LBER_V( Sockbuf_IO ) ber_sockbuf_io_udp;
-#endif
 
 /*
  * LBER memory.c
index 8a54468ad52e823986db83a15e4a838f0942277f..9d8b66056d6050e8fca130751c8cac3f4c774da3 100644 (file)
@@ -182,8 +182,8 @@ typedef struct ldapcontrol {
 
 /* LDAP Controls */
 #define LDAP_CONTROL_ASSERT                            "1.3.6.1.4.1.4203.666.5.9"
-#define LDAP_CONTROL_PRE_READ_BACK             "1.3.6.1.4.1.4203.666.5.10.1"
-#define LDAP_CONTROL_POST_READ_BACK            "1.3.6.1.4.1.4203.666.5.10.2"
+#define LDAP_CONTROL_PRE_READ                  "1.3.6.1.4.1.4203.666.5.10.1"
+#define LDAP_CONTROL_POST_READ                 "1.3.6.1.4.1.4203.666.5.10.2"
 #define LDAP_CONTROL_MODIFY_INCREMENT  "1.3.6.1.4.1.4203.666.5.11"
 
 #define LDAP_CONTROL_VALUESRETURNFILTER        "1.2.826.0.1.334810.2.3"
index 8086b04a9477be4ef6504bddad065bea375c8edc..e345b5ba3988029ace873f11d36f87f6d5003281 100644 (file)
@@ -41,6 +41,9 @@ bdb_add(Operation *op, SlapReply *rs )
        Entry           *ctxcsn_e;
        int                     ctxcsn_added = 0;
 
+       LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
+       int num_ctrls = 0;
+
 #ifdef NEW_LOGGING
        LDAP_LOG ( OPERATION, ARGS, "==> bdb_add: %s\n", op->oq_add.rs_e->e_name.bv_val, 0, 0 );
 #else
@@ -376,6 +379,23 @@ retry:     /* transaction retry */
                goto return_results;;
        }
 
+       /* post-read */
+       if( op->o_postread ) {
+               if ( slap_read_controls( op, rs, op->oq_add.rs_e,
+                       &slap_post_read_bv, &ctrls[num_ctrls] ) )
+               {
+#ifdef NEW_LOGGING
+                       LDAP_LOG ( OPERATION, DETAIL1, 
+                               "<=- bdb_add: post-read failed!\n", 0, 0, 0 );
+#else
+                       Debug( LDAP_DEBUG_TRACE,
+                               "<=- bdb_add: post-read failed!\n", 0, 0, 0 );
+#endif
+                       goto return_results;
+               }
+               ctrls[++num_ctrls] = NULL;
+       }
+
        /* nested transaction */
        rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, ltid, &lt2, 
                bdb->bi_db_opflags );
@@ -465,7 +485,8 @@ retry:      /* transaction retry */
        }
 
        if ( !op->o_bd->syncinfo ) {
-               rc = bdb_csn_commit( op, rs, ltid, ei, &suffix_ei, &ctxcsn_e, &ctxcsn_added, locker );
+               rc = bdb_csn_commit( op, rs, ltid, ei, &suffix_ei,
+                       &ctxcsn_e, &ctxcsn_added, locker );
                switch ( rc ) {
                case BDB_CSN_ABORT :
                        goto return_results;
@@ -527,28 +548,33 @@ retry:    /* transaction retry */
        ltid = NULL;
        op->o_private = NULL;
 
-       if (rs->sr_err == LDAP_SUCCESS) {
-#ifdef NEW_LOGGING
-               LDAP_LOG ( OPERATION, RESULTS, 
-                       "bdb_add: added%s id=%08lx dn=\"%s\"\n", 
-                       op->o_noop ? " (no-op)" : "", op->oq_add.rs_e->e_id, op->oq_add.rs_e->e_dn );
-#else
-               Debug(LDAP_DEBUG_TRACE, "bdb_add: added%s id=%08lx dn=\"%s\"\n",
-                       op->o_noop ? " (no-op)" : "", op->oq_add.rs_e->e_id, op->oq_add.rs_e->e_dn );
-#endif
-               rs->sr_text = NULL;
-       }
-       else {
+       if (rs->sr_err != LDAP_SUCCESS) {
 #ifdef NEW_LOGGING
                LDAP_LOG ( OPERATION, ERR, 
-                       "bdb_add: %s : %s (%d)\n",  rs->sr_text, db_strerror(rs->sr_err), rs->sr_err );
+                       "bdb_add: %s : %s (%d)\n",  rs->sr_text,
+                               db_strerror(rs->sr_err), rs->sr_err );
 #else
                Debug( LDAP_DEBUG_TRACE, "bdb_add: %s : %s (%d)\n",
                        rs->sr_text, db_strerror(rs->sr_err), rs->sr_err );
 #endif
                rs->sr_err = LDAP_OTHER;
+               goto return_results;
        }
 
+#ifdef NEW_LOGGING
+       LDAP_LOG ( OPERATION, RESULTS, 
+               "bdb_add: added%s id=%08lx dn=\"%s\"\n", 
+               op->o_noop ? " (no-op)" : "",
+               op->oq_add.rs_e->e_id, op->oq_add.rs_e->e_dn );
+#else
+       Debug(LDAP_DEBUG_TRACE, "bdb_add: added%s id=%08lx dn=\"%s\"\n",
+               op->o_noop ? " (no-op)" : "",
+               op->oq_add.rs_e->e_id, op->oq_add.rs_e->e_dn );
+#endif
+
+       rs->sr_text = NULL;
+       if( num_ctrls ) rs->sr_ctrls = ctrls;
+
 return_results:
        send_ldap_result( op, rs );
 
@@ -565,7 +591,6 @@ return_results:
        }
 
 done:
-
        if( ltid != NULL ) {
                TXN_ABORT( ltid );
                op->o_private = NULL;
index 2c7316f3d354da3b346152bee71a64b671084223..664d2f8e4ce666ed744ffe002b8b61911180cb2a 100644 (file)
@@ -41,6 +41,9 @@ bdb_delete( Operation *op, SlapReply *rs )
        Entry       *ctxcsn_e;
        int         ctxcsn_added = 0;
 
+       LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
+       int num_ctrls = 0;
+
 #ifdef NEW_LOGGING
        LDAP_LOG ( OPERATION, ARGS,  "==> bdb_delete: %s\n", op->o_req_dn.bv_val, 0, 0 );
 #else
@@ -319,6 +322,23 @@ retry:     /* transaction retry */
                goto done;
        }
 
+       /* pre-read */
+       if( op->o_preread ) {
+               if( slap_read_controls( op, rs, e,
+                       &slap_pre_read_bv, &ctrls[num_ctrls] ) )
+               {
+#ifdef NEW_LOGGING
+                       LDAP_LOG ( OPERATION, DETAIL1, 
+                               "<=- bdb_delete: pre-read failed!\n", 0, 0, 0 );
+#else
+                       Debug( LDAP_DEBUG_TRACE,
+                               "<=- bdb_delete: pre-read failed!\n", 0, 0, 0 );
+#endif
+                       goto return_results;
+               }
+               ctrls[++num_ctrls] = NULL;
+       }
+
        /* nested transaction */
        rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, ltid, &lt2, 
                bdb->bi_db_opflags );
@@ -501,20 +521,22 @@ retry:    /* transaction retry */
                rs->sr_err = LDAP_OTHER;
                rs->sr_text = "commit failed";
 
-       } else {
+               goto return_results;
+       }
+
 #ifdef NEW_LOGGING
-               LDAP_LOG ( OPERATION, RESULTS, 
-                       "bdb_delete: deleted%s id=%08lx db=\"%s\"\n",
-                       op->o_noop ? " (no-op)" : "", e->e_id, e->e_dn );
+       LDAP_LOG ( OPERATION, RESULTS, 
+               "bdb_delete: deleted%s id=%08lx db=\"%s\"\n",
+               op->o_noop ? " (no-op)" : "", e->e_id, e->e_dn );
 #else
-               Debug( LDAP_DEBUG_TRACE,
-                       "bdb_delete: deleted%s id=%08lx dn=\"%s\"\n",
-                       op->o_noop ? " (no-op)" : "",
-                       e->e_id, e->e_dn );
+       Debug( LDAP_DEBUG_TRACE,
+               "bdb_delete: deleted%s id=%08lx dn=\"%s\"\n",
+               op->o_noop ? " (no-op)" : "",
+               e->e_id, e->e_dn );
 #endif
-               rs->sr_err = LDAP_SUCCESS;
-               rs->sr_text = NULL;
-       }
+       rs->sr_err = LDAP_SUCCESS;
+       rs->sr_text = NULL;
+       if( num_ctrls ) rs->sr_ctrls = ctrls;
 
 return_results:
        send_ldap_result( op, rs );
index 5f6d87e26e6e1d87e82738e4ced1f6a7b5028e2f..68806a7859a6d512825da2a1b716d2cf17389771 100644 (file)
@@ -328,6 +328,9 @@ bdb_modify( Operation *op, SlapReply *rs )
 
        int             num_retries = 0;
 
+       LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
+       int num_ctrls = 0;
+
        Operation* ps_list;
        struct psid_entry *pm_list, *pm_prev;
        int rc;
@@ -495,6 +498,23 @@ retry:     /* transaction retry */
                }
        }
 
+       if( op->o_preread ) {
+               if ( slap_read_controls( op, rs, e,
+                       &slap_pre_read_bv, &ctrls[num_ctrls] ) )
+               {
+#ifdef NEW_LOGGING
+                       LDAP_LOG ( OPERATION, DETAIL1,
+                               "<=- bdb_modify: pre-read failed!\n", 0, 0, 0 );
+#else
+                       Debug( LDAP_DEBUG_TRACE,
+                               "<=- bdb_modify: pre-read failed!\n", 0, 0, 0 );
+#endif
+                       goto return_results;
+               }
+               ctrls[++num_ctrls] = NULL;
+               op->o_preread = 0; /* prevent redo on retry */
+       }
+
        /* nested transaction */
        rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, ltid, &lt2, 
                bdb->bi_db_opflags );
@@ -537,6 +557,24 @@ retry:     /* transaction retry */
                goto return_results;
        }
 
+       if( op->o_postread ) {
+               if( slap_read_controls( op, rs, e,
+                       &slap_post_read_bv, &ctrls[num_ctrls] ) )
+               {
+#ifdef NEW_LOGGING
+                       LDAP_LOG ( OPERATION, DETAIL1,
+                               "<=- bdb_modify: post-read failed!\n", 0, 0, 0 );
+#else
+                       Debug( LDAP_DEBUG_TRACE,
+                               "<=- bdb_modify: post-read failed!\n", 0, 0, 0 );
+#endif
+                       goto return_results;
+               }
+               ctrls[++num_ctrls] = NULL;
+               op->o_postread = 0;  /* prevent redo on retry */
+               /* FIXME: should read entry on the last retry */
+       }
+
        /* change the entry itself */
        rs->sr_err = bdb_id2entry_update( op->o_bd, lt2, &dummy );
        if ( rs->sr_err != 0 ) {
@@ -556,6 +594,7 @@ retry:      /* transaction retry */
                rs->sr_text = "entry update failed";
                goto return_results;
        }
+
        if ( TXN_COMMIT( lt2, 0 ) != 0 ) {
                rs->sr_err = LDAP_OTHER;
                rs->sr_text = "txn_commit(2) failed";
@@ -563,7 +602,8 @@ retry:      /* transaction retry */
        }
 
        if ( !op->o_bd->syncinfo ) {
-               rc = bdb_csn_commit( op, rs, ltid, ei, &suffix_ei, &ctxcsn_e, &ctxcsn_added, locker );
+               rc = bdb_csn_commit( op, rs, ltid, ei, &suffix_ei,
+                       &ctxcsn_e, &ctxcsn_added, locker );
                switch ( rc ) {
                case BDB_CSN_ABORT :
                        goto return_results;
@@ -598,12 +638,12 @@ retry:    /* transaction retry */
        ltid = NULL;
        op->o_private = NULL;
 
-
        if( rs->sr_err != 0 ) {
 #ifdef NEW_LOGGING
                LDAP_LOG ( OPERATION, ERR, 
                        "bdb_modify: txn_%s failed %s (%d)\n", 
-                       op->o_noop ? "abort (no_op)" : "commit", db_strerror(rs->sr_err), rs->sr_err );
+                       op->o_noop ? "abort (no_op)" : "commit",
+                       db_strerror(rs->sr_err), rs->sr_err );
 #else
                Debug( LDAP_DEBUG_TRACE,
                        "bdb_modify: txn_%s failed: %s (%d)\n",
@@ -613,20 +653,23 @@ retry:    /* transaction retry */
                rs->sr_err = LDAP_OTHER;
                rs->sr_text = "commit failed";
 
-       } else {
+               goto return_results;
+       }
+
 #ifdef NEW_LOGGING
-               LDAP_LOG ( OPERATION, DETAIL1, 
-                       "bdb_modify: updated%s id=%08lx dn=\"%s\"\n", 
-                       op->o_noop ? " (no_op)" : "", e->e_id, e->e_dn );
+       LDAP_LOG ( OPERATION, DETAIL1, 
+               "bdb_modify: updated%s id=%08lx dn=\"%s\"\n", 
+               op->o_noop ? " (no_op)" : "", e->e_id, e->e_dn );
 #else
-               Debug( LDAP_DEBUG_TRACE,
-                       "bdb_modify: updated%s id=%08lx dn=\"%s\"\n",
-                       op->o_noop ? " (no-op)" : "",
-                       e->e_id, e->e_dn );
+       Debug( LDAP_DEBUG_TRACE,
+               "bdb_modify: updated%s id=%08lx dn=\"%s\"\n",
+               op->o_noop ? " (no-op)" : "",
+               e->e_id, e->e_dn );
 #endif
-               rs->sr_err = LDAP_SUCCESS;
-               rs->sr_text = NULL;
-       }
+
+       rs->sr_err = LDAP_SUCCESS;
+       rs->sr_text = NULL;
+       if( num_ctrls ) rs->sr_ctrls = ctrls;
 
 return_results:
        send_ldap_result( op, rs );
index 35fa4e966eaccf1dbd5e2a2c24903900cabfa646..80d41518d51d9ce9c2c05540357c18aedd1fe5e4 100644 (file)
@@ -53,6 +53,9 @@ bdb_modrdn( Operation *op, SlapReply *rs )
 
        int             num_retries = 0;
 
+       LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
+       int num_ctrls = 0;
+
        Operation *ps_list;
        struct psid_entry *pm_list, *pm_prev;
        int     rc;
@@ -763,6 +766,23 @@ retry:     /* transaction retry */
                }
        }
 
+       if( op->o_preread ) {
+               if( slap_read_controls( op, rs, e,
+                       &slap_pre_read_bv, &ctrls[num_ctrls] ) )
+               {
+#ifdef NEW_LOGGING                                   
+                       LDAP_LOG ( OPERATION, DETAIL1,
+                               "<=- bdb_modrdn: post-read failed!\n", 0, 0, 0 );
+#else
+                       Debug( LDAP_DEBUG_TRACE,        
+                               "<=- bdb_modrdn: post-read failed!\n", 0, 0, 0 );
+#endif
+                       goto return_results;
+               }                   
+               ctrls[++num_ctrls] = NULL;
+               op->o_preread = 0;  /* prevent redo on retry */
+       }
+
        /* nested transaction */
        rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, ltid, &lt2, 
                bdb->bi_db_opflags );
@@ -874,7 +894,25 @@ retry:     /* transaction retry */
                }
                goto return_results;
        }
-       
+
+       if( op->o_postread ) {
+               if( slap_read_controls( op, rs, e,
+                       &slap_post_read_bv, &ctrls[num_ctrls] ) )
+               {
+#ifdef NEW_LOGGING                                   
+                       LDAP_LOG ( OPERATION, DETAIL1,
+                               "<=- bdb_modrdn: post-read failed!\n", 0, 0, 0 );
+#else
+                       Debug( LDAP_DEBUG_TRACE,        
+                               "<=- bdb_modrdn: post-read failed!\n", 0, 0, 0 );
+#endif
+                       goto return_results;
+               }                   
+               ctrls[++num_ctrls] = NULL;
+               op->o_postread = 0;  /* prevent redo on retry */
+               /* FIXME: should read entry on the last retry */
+       }
+
        /* id2entry index */
        rs->sr_err = bdb_id2entry_update( op->o_bd, lt2, e );
        if ( rs->sr_err != 0 ) {
@@ -953,18 +991,7 @@ retry:     /* transaction retry */
        ltid = NULL;
        op->o_private = NULL;
  
-       if( rs->sr_err == LDAP_SUCCESS ) {
-#ifdef NEW_LOGGING
-               LDAP_LOG ( OPERATION, RESULTS, 
-                       "bdb_modrdn: rdn modified%s id=%08lx dn=\"%s\"\n", 
-                       op->o_noop ? " (no-op)" : "", e->e_id, e->e_dn );
-#else
-               Debug(LDAP_DEBUG_TRACE,
-                       "bdb_modrdn: rdn modified%s id=%08lx dn=\"%s\"\n",
-                       op->o_noop ? " (no-op)" : "", e->e_id, e->e_dn );
-#endif
-               rs->sr_text = NULL;
-       } else {
+       if( rs->sr_err != LDAP_SUCCESS ) {
 #ifdef NEW_LOGGING
                LDAP_LOG ( OPERATION, RESULTS, "bdb_modrdn: %s : %s (%d)\n", 
                        rs->sr_text, db_strerror(rs->sr_err), rs->sr_err );
@@ -973,8 +1000,22 @@ retry:    /* transaction retry */
                        rs->sr_text, db_strerror(rs->sr_err), rs->sr_err );
 #endif
                rs->sr_err = LDAP_OTHER;
+
+               goto return_results;
        }
 
+#ifdef NEW_LOGGING
+       LDAP_LOG ( OPERATION, RESULTS, 
+               "bdb_modrdn: rdn modified%s id=%08lx dn=\"%s\"\n", 
+               op->o_noop ? " (no-op)" : "", e->e_id, e->e_dn );
+#else
+       Debug(LDAP_DEBUG_TRACE,
+               "bdb_modrdn: rdn modified%s id=%08lx dn=\"%s\"\n",
+               op->o_noop ? " (no-op)" : "", e->e_id, e->e_dn );
+#endif
+       rs->sr_text = NULL;
+       if( num_ctrls ) rs->sr_ctrls = ctrls;
+
 return_results:
        send_ldap_result( op, rs );
 
index 2e5d868c83056f8bcbbf8ca738f6417680959cea..93a8714d333da7e171823432c364c5240f704177 100644 (file)
@@ -18,6 +18,7 @@ static int base_candidate(
        BackendDB       *be,
        Entry   *e,
        ID              *ids );
+
 static int search_candidates(
        Operation *stackop,     /* op with the current threadctx/slab cache */
        Operation *sop,         /* search op */
@@ -26,6 +27,7 @@ static int search_candidates(
        u_int32_t locker,
        ID      *ids,
        ID      *scopes );
+
 static void send_pagerequest_response( 
        Operation *op,
        SlapReply *rs,
@@ -367,7 +369,7 @@ bdb_do_search( Operation *op, SlapReply *rs, Operation *sop,
        int             entry_count = 0;
        struct berval *search_context_csn = NULL;
        DB_LOCK         ctxcsn_lock;
-       LDAPControl     *ctrls[SLAP_SEARCH_MAX_CTRLS];
+       LDAPControl     *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
        int             num_ctrls = 0;
        AttributeName   uuid_attr[2];
        int             rc_sync = 0;
@@ -398,7 +400,7 @@ bdb_do_search( Operation *op, SlapReply *rs, Operation *sop,
        null_attr.an_name.bv_len = 0;
        null_attr.an_name.bv_val = NULL;
 
-       for ( num_ctrls = 0; num_ctrls < SLAP_SEARCH_MAX_CTRLS; num_ctrls++ ) {
+       for( num_ctrls = 0; num_ctrls < SLAP_MAX_RESPONSE_CONTROLS; num_ctrls++ ) {
                ctrls[num_ctrls] = NULL;
        }
        num_ctrls = 0;
index 0a71d72777ccb6859df1236ae208646f4639062d..e7effae3468768ec2ce5adedc1c40733959c3cc3 100644 (file)
@@ -1472,22 +1472,28 @@ connection_input(
 
        op->o_conn = conn;
        op->o_assertion = NULL;
+       op->o_preread_attrs = NULL;
+       op->o_postread_attrs = NULL;
        op->o_vrFilter = NULL;
+
 #ifdef LDAP_CONTROL_PAGEDRESULTS
        op->o_pagedresults_state = conn->c_pagedresults_state;
 #endif
+
+       op->o_res_ber = NULL;
+
 #ifdef LDAP_CONNECTIONLESS
        if (conn->c_is_udp) {
-
                if ( cdn ) {
                    ber_str2bv( cdn, 0, 1, &op->o_dn );
                    op->o_protocol = LDAP_VERSION2;
                }
                op->o_res_ber = ber_alloc_t( LBER_USE_DER );
-               if (op->o_res_ber == NULL)
-                       return 1;
+               if (op->o_res_ber == NULL) return 1;
+
+               rc = ber_write( op->o_res_ber, (char *)&peeraddr,
+                       sizeof(struct sockaddr), 0 );
 
-               rc = ber_write(op->o_res_ber, (char *)&peeraddr, sizeof(struct sockaddr), 0);
                if (rc != sizeof(struct sockaddr)) {
 #ifdef NEW_LOGGING
                        LDAP_LOG( CONNECTION, INFO, 
index e24ce18023ca03c960496c9903e2a5d2d7ecabd9..2a7806194ad1a6d02e9679900d1d3510626633d7 100644 (file)
@@ -20,6 +20,8 @@
 #include "../../libraries/liblber/lber-int.h"
 
 static SLAP_CTRL_PARSE_FN parseAssert;
+static SLAP_CTRL_PARSE_FN parsePreRead;
+static SLAP_CTRL_PARSE_FN parsePostRead;
 static SLAP_CTRL_PARSE_FN parseProxyAuthz;
 static SLAP_CTRL_PARSE_FN parseManageDSAit;
 static SLAP_CTRL_PARSE_FN parseModifyIncrement;
@@ -32,10 +34,13 @@ static SLAP_CTRL_PARSE_FN parseDomainScope;
 #ifdef LDAP_CONTROL_SUBENTRIES
 static SLAP_CTRL_PARSE_FN parseSubentries;
 #endif
-static SLAP_CTRL_PARSE_FN parseLdupSync;
+static SLAP_CTRL_PARSE_FN parseLDAPsync;
 
 #undef sc_mask /* avoid conflict with Irix 6.5 <sys/signal.h> */
 
+const struct berval slap_pre_read_bv = BER_BVC(LDAP_CONTROL_PRE_READ);
+const struct berval slap_post_read_bv = BER_BVC(LDAP_CONTROL_POST_READ);
+
 struct slap_control {
        /* Control OID */
        char *sc_oid;
@@ -70,6 +75,12 @@ static struct slap_control control_defs[] = {
        { LDAP_CONTROL_ASSERT,
                SLAP_CTRL_ACCESS, NULL,
                parseAssert, LDAP_SLIST_ENTRY_INITIALIZER(next) },
+       { LDAP_CONTROL_PRE_READ,
+               SLAP_CTRL_DELETE|SLAP_CTRL_MODIFY|SLAP_CTRL_RENAME, NULL,
+               parsePreRead, LDAP_SLIST_ENTRY_INITIALIZER(next) },
+       { LDAP_CONTROL_POST_READ,
+               SLAP_CTRL_ADD|SLAP_CTRL_MODIFY|SLAP_CTRL_RENAME, NULL,
+               parsePostRead, LDAP_SLIST_ENTRY_INITIALIZER(next) },
        { LDAP_CONTROL_VALUESRETURNFILTER,
                SLAP_CTRL_SEARCH, NULL,
                parseValuesReturnFilter, LDAP_SLIST_ENTRY_INITIALIZER(next) },
@@ -98,7 +109,7 @@ static struct slap_control control_defs[] = {
                parseNoOp, LDAP_SLIST_ENTRY_INITIALIZER(next) },
        { LDAP_CONTROL_SYNC,
                SLAP_CTRL_HIDE|SLAP_CTRL_SEARCH, NULL,
-               parseLdupSync, LDAP_SLIST_ENTRY_INITIALIZER(next) },
+               parseLDAPsync, LDAP_SLIST_ENTRY_INITIALIZER(next) },
        { LDAP_CONTROL_MODIFY_INCREMENT,
                SLAP_CTRL_MODIFY, NULL,
                parseModifyIncrement, LDAP_SLIST_ENTRY_INITIALIZER(next) },
@@ -907,7 +918,7 @@ static int parseAssert (
 
        ber = ber_init( &(ctrl->ldctl_value) );
        if (ber == NULL) {
-               rs->sr_text = "internal error";
+               rs->sr_text = "assert control: internal error";
                return LDAP_OTHER;
        }
        
@@ -921,14 +932,14 @@ static int parseAssert (
                } else {
                        send_ldap_result( op, rs );
                }
-               if( op->o_assertion != NULL) {
-                       filter_free_x( op, op->o_assertion ); 
+               if( op->o_assertion != NULL ) {
+                       filter_free_x( op, op->o_assertion );
                }
+               return rs->sr_err;
        }
+
 #ifdef LDAP_DEBUG
-       else {
-               filter2bv_x( op, op->o_assertion, &fstr );
-       }
+       filter2bv_x( op, op->o_assertion, &fstr );
 
 #ifdef NEW_LOGGING
        LDAP_LOG( OPERATION, ARGS, 
@@ -949,6 +960,104 @@ static int parseAssert (
        return LDAP_SUCCESS;
 }
 
+static int parsePreRead (
+       Operation *op,
+       SlapReply *rs,
+       LDAPControl *ctrl )
+{
+       ber_len_t siz, off, i;
+       AttributeName *an = NULL;
+       BerElement      *ber;
+
+       if ( op->o_preread != SLAP_NO_CONTROL ) {
+               rs->sr_text = "preread control specified multiple times";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       if ( ctrl->ldctl_value.bv_len == 0 ) {
+               rs->sr_text = "preread control value is empty (or absent)";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       ber = ber_init( &(ctrl->ldctl_value) );
+       if (ber == NULL) {
+               rs->sr_text = "preread control: internal error";
+               return LDAP_OTHER;
+       }
+
+       siz = sizeof( AttributeName );
+       off = 0;
+       if ( ber_scanf( ber, "{M}", &an, &siz, off ) == LBER_ERROR ) {
+               rs->sr_text = "preread control: decoding error";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       for( i=0; i<siz; i++ ) {
+               const char *dummy;
+               an[i].an_desc = NULL;
+               an[i].an_oc = NULL;
+               slap_bv2ad( &an[i].an_name, &an[i].an_desc, &dummy );
+       }
+
+       op->o_preread = ctrl->ldctl_iscritical
+               ? SLAP_CRITICAL_CONTROL
+               : SLAP_NONCRITICAL_CONTROL;
+
+       op->o_preread_attrs = an;
+
+       rs->sr_err = LDAP_SUCCESS;
+       return LDAP_SUCCESS;
+}
+
+static int parsePostRead (
+       Operation *op,
+       SlapReply *rs,
+       LDAPControl *ctrl )
+{
+       ber_len_t siz, off, i;
+       AttributeName *an = NULL;
+       BerElement      *ber;
+
+       if ( op->o_postread != SLAP_NO_CONTROL ) {
+               rs->sr_text = "postread control specified multiple times";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       if ( ctrl->ldctl_value.bv_len == 0 ) {
+               rs->sr_text = "postread control value is empty (or absent)";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       ber = ber_init( &(ctrl->ldctl_value) );
+       if (ber == NULL) {
+               rs->sr_text = "postread control: internal error";
+               return LDAP_OTHER;
+       }
+
+       siz = sizeof( AttributeName );
+       off = 0;
+       if ( ber_scanf( ber, "{M}", &an, &siz, off ) == LBER_ERROR ) {
+               rs->sr_text = "postread control: decoding error";
+               return LDAP_PROTOCOL_ERROR;
+       }
+
+       for( i=0; i<siz; i++ ) {
+               const char *dummy;
+               an[i].an_desc = NULL;
+               an[i].an_oc = NULL;
+               slap_bv2ad( &an[i].an_name, &an[i].an_desc, &dummy );
+       }
+
+       op->o_postread = ctrl->ldctl_iscritical
+               ? SLAP_CRITICAL_CONTROL
+               : SLAP_NONCRITICAL_CONTROL;
+
+       op->o_postread_attrs = an;
+
+       rs->sr_err = LDAP_SUCCESS;
+       return LDAP_SUCCESS;
+}
+
 int parseValuesReturnFilter (
        Operation *op,
        SlapReply *rs,
@@ -985,7 +1094,6 @@ int parseValuesReturnFilter (
                        send_ldap_result( op, rs );
                }
                if( op->o_vrFilter != NULL) vrFilter_free( op, op->o_vrFilter ); 
-
        }
 #ifdef LDAP_DEBUG
        else {
@@ -1089,7 +1197,7 @@ static int parseDomainScope (
 }
 #endif
 
-static int parseLdupSync (
+static int parseLDAPsync (
        Operation *op,
        SlapReply *rs,
        LDAPControl *ctrl )
index f147f518ab0b95ff8d73847e6881fc41b538fcde..be518eec58d58a8d9db1d0706d2f2515a121311a 100644 (file)
@@ -454,7 +454,11 @@ dnPretty(
                }
        }
 
+#ifdef NEW_LOGGING
+       LDAP_LOG( OPERATION, ARGS, "<<< dnPretty: <%s>\n", out->bv_val, 0, 0 );
+#else
        Debug( LDAP_DEBUG_TRACE, "<<< dnPretty: <%s>\n", out->bv_val, 0, 0 );
+#endif
 
        return LDAP_SUCCESS;
 }
index 4efd292a80cfd41506900a9158882d4a653890e8..17d4e4efaaaca442b45782821dceace943d9523e 100644 (file)
@@ -107,9 +107,7 @@ slap_op_alloc(
 
        op->o_time = slap_get_time();
        op->o_opid = id;
-#ifdef LDAP_CONNECTIONLESS
        op->o_res_ber = NULL;
-#endif
 
 #if defined( LDAP_SLAPI )
        op->o_pb = slapi_pblock_new();
index ef1afa7cd723632176ec14d149844f706f572ef7..008a258941b2874bf4b85e109a9ece44a093d642 100644 (file)
@@ -854,6 +854,11 @@ LDAP_SLAPD_F (void) slap_send_search_result LDAP_P(( Operation *op, SlapReply *r
 LDAP_SLAPD_F (int) slap_send_search_reference LDAP_P(( Operation *op, SlapReply *rs ));
 LDAP_SLAPD_F (int) slap_send_search_entry LDAP_P(( Operation *op, SlapReply *rs ));
 
+LDAP_SLAPD_V( const struct berval ) slap_pre_read_bv;
+LDAP_SLAPD_V( const struct berval ) slap_post_read_bv;
+LDAP_SLAPD_F (int) slap_read_controls LDAP_P(( Operation *op, SlapReply *rs,
+       Entry *e, const struct berval *oid, LDAPControl **ctrl ));
+
 LDAP_SLAPD_F (int) str2result LDAP_P(( char *s,
        int *code, char **matched, char **info ));
 
index e59f4a434c53323bbd46eef314f5557e93e75da5..c4311df7363513904964028e15ba06d5444a5a44 100644 (file)
@@ -449,11 +449,13 @@ slap_send_ldap_result( Operation *op, SlapReply *rs )
 #ifdef NEW_LOGGING
        LDAP_LOG( OPERATION, ARGS, 
                "send_ldap_result: err=%d matched=\"%s\" text=\"%s\"\n",
-               rs->sr_err, rs->sr_matched ? rs->sr_matched : "", rs->sr_text ? rs->sr_text : "" );
+               rs->sr_err, rs->sr_matched ? rs->sr_matched : "",
+               rs->sr_text ? rs->sr_text : "" );
 #else
        Debug( LDAP_DEBUG_ARGS,
                "send_ldap_result: err=%d matched=\"%s\" text=\"%s\"\n",
-               rs->sr_err, rs->sr_matched ? rs->sr_matched : "", rs->sr_text ? rs->sr_text : "" );
+               rs->sr_err, rs->sr_matched ? rs->sr_matched : "",
+               rs->sr_text ? rs->sr_text : "" );
 #endif
 
 
@@ -498,20 +500,21 @@ slap_send_ldap_result( Operation *op, SlapReply *rs )
 
        if ( op->o_tag == LDAP_REQ_SEARCH ) {
                char nbuf[64];
-               snprintf( nbuf, sizeof nbuf, "%d nentries=%d", rs->sr_err, rs->sr_nentries );
+               snprintf( nbuf, sizeof nbuf, "%d nentries=%d",
+                       rs->sr_err, rs->sr_nentries );
 
                Statslog( LDAP_DEBUG_STATS,
-                       "conn=%lu op=%lu SEARCH RESULT tag=%lu err=%s text=%s\n",
-                       op->o_connid, op->o_opid, rs->sr_tag, nbuf, rs->sr_text ? rs->sr_text : "" );
+               "conn=%lu op=%lu SEARCH RESULT tag=%lu err=%s text=%s\n",
+                       op->o_connid, op->o_opid, rs->sr_tag, nbuf,
+                       rs->sr_text ? rs->sr_text : "" );
        } else {
                Statslog( LDAP_DEBUG_STATS,
                        "conn=%lu op=%lu RESULT tag=%lu err=%d text=%s\n",
-                       op->o_connid, op->o_opid, rs->sr_tag, rs->sr_err, rs->sr_text ? rs->sr_text : "" );
+                       op->o_connid, op->o_opid, rs->sr_tag, rs->sr_err,
+                       rs->sr_text ? rs->sr_text : "" );
        }
 
-       if( tmp != NULL ) {
-               ch_free(tmp);
-       }
+       if( tmp != NULL ) ch_free(tmp);
        rs->sr_text = otext;
        rs->sr_ref = oref;
 }
@@ -523,10 +526,12 @@ send_ldap_sasl( Operation *op, SlapReply *rs )
 #ifdef NEW_LOGGING
        LDAP_LOG( OPERATION, ENTRY, 
                "send_ldap_sasl: conn %lu err=%d len=%lu\n",
-               op->o_connid, rs->sr_err, rs->sr_sasldata ? rs->sr_sasldata->bv_len : -1 );
+               op->o_connid, rs->sr_err,
+               rs->sr_sasldata ? rs->sr_sasldata->bv_len : -1 );
 #else
        Debug( LDAP_DEBUG_TRACE, "send_ldap_sasl: err=%d len=%ld\n",
-               rs->sr_err, rs->sr_sasldata ? (long) rs->sr_sasldata->bv_len : -1, NULL );
+               rs->sr_err,
+               rs->sr_sasldata ? (long) rs->sr_sasldata->bv_len : -1, NULL );
 #endif
 
        rs->sr_tag = req2res( op->o_tag );
@@ -641,12 +646,10 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
 
        edn = rs->sr_entry->e_nname.bv_val;
 
-#ifdef LDAP_CONNECTIONLESS
-       if (op->o_conn && op->o_conn->c_is_udp) {
+       if ( op->o_res_ber ) {
+               /* read back control or LDAP_CONNECTIONLESS */
            ber = op->o_res_ber;
-       } else
-#endif
-       {
+       } else {
                ber_len_t       siz, len;
                struct berval   bv;
 
@@ -659,14 +662,23 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
        }
 
 #ifdef LDAP_CONNECTIONLESS
-       if (op->o_conn && op->o_conn->c_is_udp && op->o_protocol == LDAP_VERSION2) {
-           rc = ber_printf(ber, "t{O{" /*}}*/,
-               LDAP_RES_SEARCH_ENTRY, &rs->sr_entry->e_name);
+       if ( op->o_conn && op->o_conn->c_is_udp ) {
+               /* CONNECTIONLESS */
+               if ( op->o_protocol == LDAP_VERSION2 ) {
+               rc = ber_printf(ber, "t{O{" /*}}*/,
+                               LDAP_RES_SEARCH_ENTRY, &rs->sr_entry->e_name );
+               } else {
+               rc = ber_printf( ber, "{it{O{" /*}}}*/, op->o_msgid,
+                               LDAP_RES_SEARCH_ENTRY, &rs->sr_entry->e_name );
+               }
        } else
 #endif
-       {
+       if ( op->o_res_ber ) {
+               /* read back control */
+           rc = ber_printf( ber, "{O{" /*}}*/, &rs->sr_entry->e_name );
+       } else {
            rc = ber_printf( ber, "{it{O{" /*}}}*/, op->o_msgid,
-               LDAP_RES_SEARCH_ENTRY, &rs->sr_entry->e_name );
+                       LDAP_RES_SEARCH_ENTRY, &rs->sr_entry->e_name );
        }
 
        if ( rc == -1 ) {
@@ -678,10 +690,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
                Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
 #endif
 
-#ifdef LDAP_CONNECTIONLESS
-               if (!op->o_conn || op->o_conn->c_is_udp == 0)
-#endif
-               ber_free_buf( ber );
+               if ( op->o_res_ber == NULL ) ber_free_buf( ber );
                send_ldap_error( op, rs, LDAP_OTHER, "encoding DN error" );
                goto error_return;
        }
@@ -742,13 +751,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
                        Debug( LDAP_DEBUG_ANY,
                                        "matched values filtering failed\n", 0, 0, 0 );
 #endif
-#ifdef LDAP_CONNECTIONLESS
-                               if (!op->o_conn || op->o_conn->c_is_udp == 0)
-#endif
-                               {
-                                       ber_free( ber, 1 );
-                               }
-
+                               if ( op->o_res_ber == NULL ) ber_free_buf( ber );
                                send_ldap_error( op, rs, LDAP_OTHER,
                                        "matched values filtering error" );
                                goto error_return;
@@ -803,10 +806,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
                        Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
 #endif
 
-#ifdef LDAP_CONNECTIONLESS
-                       if (!op->o_conn || op->o_conn->c_is_udp == 0)
-#endif
-                       ber_free_buf( ber );
+                       if ( op->o_res_ber == NULL ) ber_free_buf( ber );
                        send_ldap_error( op, rs, LDAP_OTHER, "encoding description error");
                        goto error_return;
                }
@@ -845,10 +845,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
                                            "ber_printf failed\n", 0, 0, 0 );
 #endif
 
-#ifdef LDAP_CONNECTIONLESS
-                                       if (!op->o_conn || op->o_conn->c_is_udp == 0)
-#endif
-                                       ber_free_buf( ber );
+                                       if ( op->o_res_ber == NULL ) ber_free_buf( ber );
                                        send_ldap_error( op, rs, LDAP_OTHER,
                                                "encoding values error" );
                                        goto error_return;
@@ -865,17 +862,14 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
                        Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
 #endif
 
-#ifdef LDAP_CONNECTIONLESS
-                       if (!op->o_conn || op->o_conn->c_is_udp == 0)
-#endif
-                       ber_free_buf( ber );
+                       if ( op->o_res_ber == NULL ) ber_free_buf( ber );
                        send_ldap_error( op, rs, LDAP_OTHER, "encode end error" );
                        goto error_return;
                }
        }
 
        /* eventually will loop through generated operational attributes */
-       /* only have subschemaSubentry implemented */
+       /* only have subschemaSubentry and numSubordinates are implemented */
        aa = backend_operational( op, rs, opattrs );
 
        if ( aa != NULL && op->o_vrFilter != NULL ) {
@@ -910,8 +904,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
                                        "for matched values filtering\n",
                                        op->o_connid, 0, 0 );
 #endif
-                               ber_free( ber, 1 );
-       
+                               if ( op->o_res_ber == NULL ) ber_free_buf( ber );
                                send_ldap_error( op, rs, LDAP_OTHER,
                                        "not enough memory for matched values filtering" );
                                goto error_return;
@@ -936,13 +929,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
                                Debug( LDAP_DEBUG_ANY,
                                        "matched values filtering failed\n", 0, 0, 0 );
 #endif
-#ifdef LDAP_CONNECTIONLESS
-                               if (!op->o_conn || op->o_conn->c_is_udp == 0)
-#endif
-                               {
-                                       ber_free( ber, 1 );
-                               }
-       
+                               if ( op->o_res_ber == NULL ) ber_free_buf( ber );
                                send_ldap_error( op, rs, LDAP_OTHER,
                                        "matched values filtering error" );
                                goto error_return;
@@ -998,14 +985,8 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
                        Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
 #endif
 
-#ifdef LDAP_CONNECTIONLESS
-                       if (!op->o_conn || op->o_conn->c_is_udp == 0)
-#endif
-                       {
-                               ber_free_buf( ber );
-                       }
+                       if ( op->o_res_ber == NULL ) ber_free_buf( ber );
                        send_ldap_error( op, rs, LDAP_OTHER, "encoding description error" );
-
                        attrs_free( aa );
                        goto error_return;
                }
@@ -1044,12 +1025,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
                                            "ber_printf failed\n", 0, 0, 0 );
 #endif
 
-#ifdef LDAP_CONNECTIONLESS
-                                       if (!op->o_conn || op->o_conn->c_is_udp == 0)
-#endif
-                                       {
-                                               ber_free_buf( ber );
-                                       }
+                                       if ( op->o_res_ber == NULL ) ber_free_buf( ber );
                                        send_ldap_error( op, rs, LDAP_OTHER,
                                                "encoding values error" );
                                        attrs_free( aa );
@@ -1067,14 +1043,8 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
                        Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
 #endif
 
-#ifdef LDAP_CONNECTIONLESS
-                       if (!op->o_conn || op->o_conn->c_is_udp == 0)
-#endif
-                       {
-                               ber_free_buf( ber );
-                       }
+                       if ( op->o_res_ber == NULL ) ber_free_buf( ber );
                        send_ldap_error( op, rs, LDAP_OTHER, "encode end error" );
-
                        attrs_free( aa );
                        goto error_return;
                }
@@ -1114,7 +1084,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
                        rs->sr_entry, slapi_x_compute_output_ber );
        }
        if ( rc == 1 ) {
-               ber_free_buf( ber );
+               if ( op->o_res_ber == NULL ) ber_free_buf( ber );
                send_ldap_error( op, rs, LDAP_OTHER, "computed attribute error" );
                goto error_return;
        }
@@ -1133,15 +1103,17 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
                rc = send_ldap_controls( ber, rs->sr_ctrls );
        }
 
+       if( rc != -1 ) {
 #ifdef LDAP_CONNECTIONLESS
-       if( op->o_conn && op->o_conn->c_is_udp &&
-               op->o_protocol == LDAP_VERSION2 )
-       {
-               ; /* empty, skip following if */
-       } else
+               if( op->o_conn && op->o_conn->c_is_udp ) {
+                       if ( op->o_protocol != LDAP_VERSION2 ) {
+                               rc = ber_printf( ber, /*{*/ "N}" );
+                       }
+               } else
 #endif
-       if( rc != -1 ) {
-               rc = ber_printf( ber, /*{*/ "N}" );
+               if ( op->o_res_ber == NULL ) {
+                       rc = ber_printf( ber, /*{*/ "N}" );
+               }
        }
 
        if ( rc == -1 ) {
@@ -1153,21 +1125,13 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
                Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
 #endif
 
-#ifdef LDAP_CONNECTIONLESS
-               if (!op->o_conn || op->o_conn->c_is_udp == 0)
-#endif
-               {
-                       ber_free_buf( ber );
-               }
+               if ( op->o_res_ber == NULL ) ber_free_buf( ber );
                send_ldap_error( op, rs, LDAP_OTHER, "encode entry end error" );
                sl_release( mark, op->o_tmpmemctx );
                return( 1 );
        }
 
-#ifdef LDAP_CONNECTIONLESS
-       if (!op->o_conn || op->o_conn->c_is_udp == 0)
-#endif
-       {
+       if ( op->o_res_ber == NULL ) {
                bytes = op->o_noop ? 0 : send_ldap_ber( op->o_conn, ber );
                ber_free_buf( ber );
 
@@ -1235,7 +1199,8 @@ slap_send_search_reference( Operation *op, SlapReply *rs )
 #ifdef NEW_LOGGING
        LDAP_LOG( OPERATION, ENTRY, 
                "send_search_reference: conn %lu  dn=\"%s\"\n", 
-               op->o_connid, rs->sr_entry ? rs->sr_entry->e_name.bv_val : "(null)", 0 );
+               op->o_connid,
+               rs->sr_entry ? rs->sr_entry->e_name.bv_val : "(null)", 0 );
 #else
        Debug( LDAP_DEBUG_TRACE,
                "=> send_search_reference: dn=\"%s\"\n",
@@ -1317,9 +1282,9 @@ slap_send_search_reference( Operation *op, SlapReply *rs )
        }
 
 #ifdef LDAP_CONNECTIONLESS
-       if (op->o_conn && op->o_conn->c_is_udp)
+       if( op->o_conn && op->o_conn->c_is_udp ) {
                ber = op->o_res_ber;
-       else
+       else
 #endif
        {
                ber_init_w_nullc( ber, LBER_USE_DER );
@@ -1448,3 +1413,57 @@ str2result(
 
        return( rc );
 }
+
+int slap_read_controls(
+       Operation *op,
+       SlapReply *rs,
+       Entry *e,
+       const struct berval *oid,
+       LDAPControl **ctrl )
+{
+       int rc;
+       struct berval bv;
+       char berbuf[LBER_ELEMENT_SIZEOF];
+       BerElement *ber = (BerElement *) berbuf;
+       LDAPControl c;
+       ber_len_t       siz, len;
+       Operation myop;
+
+#ifdef NEW_LOGGING
+       LDAP_LOG( OPERATION, INFO, "slap_read_controls: (%s) %s\n",
+               oid->bv_val, e->e_dn, 0 );
+#else
+       Debug( LDAP_DEBUG_ANY, "slap_read_controls: (%s) %s\n",
+               oid->bv_val, e->e_dn, 0 );
+#endif
+
+       rs->sr_entry = e;
+       rs->sr_attrs = ( oid == &slap_pre_read_bv ) ?
+               op->o_preread_attrs : op->o_postread_attrs; 
+
+       entry_flatsize( rs->sr_entry, &siz, &len, 0 );
+       bv.bv_len = siz + len;
+       bv.bv_val = op->o_tmpalloc(bv.bv_len, op->o_tmpmemctx );
+
+       ber_init2( ber, &bv, LBER_USE_DER );
+       ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx );
+
+       /* create new operation */
+       myop = *op;
+       myop.o_bd = NULL;
+       myop.o_res_ber = ber;
+
+       rc = slap_send_search_entry( &myop, rs );
+       if( rc ) return rc;
+
+       rc = ber_flatten2( ber, &c.ldctl_value, 0 );
+
+       if( rc == LBER_ERROR ) return LDAP_OTHER;
+
+       c.ldctl_oid = oid->bv_val;
+       c.ldctl_iscritical = 0;
+
+       *ctrl = sl_calloc( 1, sizeof(LDAPControl), NULL );
+       **ctrl = c;
+       return LDAP_SUCCESS;
+}
index 44a718f8fb8546769e9f9aab5d2464c2b1149a30..156ef3a225f4b355125cc310f555802e341f1936 100644 (file)
@@ -1433,9 +1433,7 @@ struct slap_backend_db {
 
 #define SLAP_DISALLOW_BIND_ANON                0x0001U /* no anonymous */
 #define SLAP_DISALLOW_BIND_SIMPLE      0x0002U /* simple authentication */
-#define SLAP_DISALLOW_BIND_SIMPLE_UNPROTECTED \
-                                                                       0x0004U /* unprotected simple auth */
-#define SLAP_DISALLOW_BIND_KRBV4       0x0008U /* Kerberos V4 authentication */
+#define SLAP_DISALLOW_BIND_KRBV4       0x0004U /* Kerberos V4 authentication */
 
 #define SLAP_DISALLOW_TLS_2_ANON       0x0010U /* StartTLS -> Anonymous */
 #define SLAP_DISALLOW_TLS_AUTHC                0x0020U /* TLS while authenticated */
@@ -1929,6 +1927,11 @@ typedef struct slap_op {
 #define get_domainScope(op)                            (0)
 #endif
 
+       char o_preread;
+       char o_postread;
+       AttributeName *o_preread_attrs;
+       AttributeName *o_postread_attrs;
+
 #ifdef LDAP_CONTROL_PAGEDRESULTS
        char o_pagedresults;
 #define get_pagedresults(op)                   ((int)(op)->o_pagedresults)
@@ -1952,11 +1955,9 @@ typedef struct slap_op {
 
        AuthorizationInformation o_authz;
 
-       BerElement      *o_ber;         /* ber of the request             */
-#ifdef LDAP_CONNECTIONLESS
-       BerElement      *o_res_ber;     /* ber of the reply               */
-#endif
-       slap_callback   *o_callback;    /* callback pointers */
+       BerElement      *o_ber;         /* ber of the request */
+       BerElement      *o_res_ber;     /* ber of the CLDAP reply or readback control */
+       slap_callback *o_callback;      /* callback pointers */
        LDAPControl     **o_ctrls;       /* controls */
 
        void    *o_threadctx;           /* thread pool thread context */
@@ -1972,6 +1973,7 @@ typedef struct slap_op {
 
        Filter *o_assertion; /* Assert control filter */
 #define get_assertion(op)                              ((op)->o_assertion)
+
        ValuesReturnFilter *o_vrFilter; /* ValuesReturnFilter */
 
        syncinfo_t*     o_si;
@@ -2180,7 +2182,8 @@ enum {
 #define SLAP_LDAPDN_PRETTY 0x1
 #define SLAP_LDAPDN_MAXLEN 8192
 
-#define SLAP_SEARCH_MAX_CTRLS   10
+/* number of response controls supported */
+#define SLAP_MAX_RESPONSE_CONTROLS   6
 
 #ifdef LDAP_DEVEL
 #define SLAP_CTRL_HIDE                         0x00000000U
index 1b300b479918eb9303bb7dbd7aac08cb484f48ce..9f972115e2d5ef030abf500e3d29efede37b247a 100644 (file)
@@ -80,6 +80,17 @@ slap_send_search_reference( Operation *op, SlapReply *rs )
        return -1;
 }
 
+int slap_read_controls(
+       Operation *op,
+       SlapReply *rs,
+       Entry *e,
+       const struct berval *oid,
+       LDAPControl **c )
+{
+       assert(0);
+       return -1;
+}
+
 int slap_sasl_init(void)
 {
        return LDAP_SUCCESS;