From 99f968b5974a86022ce2768db85c805ca4bcd19d Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Tue, 16 Sep 2003 18:56:04 +0000 Subject: [PATCH] Initial support for pre/post read controls. TODO: Fix transactional consistency Add client response control handling --- clients/tools/common.c | 104 ++++++++++++++-- clients/tools/common.h | 1 + clients/tools/ldapmodify.c | 2 +- include/lber.h | 2 - include/ldap.h | 4 +- servers/slapd/back-bdb/add.c | 55 ++++++--- servers/slapd/back-bdb/delete.c | 44 +++++-- servers/slapd/back-bdb/modify.c | 71 ++++++++--- servers/slapd/back-bdb/modrdn.c | 67 ++++++++-- servers/slapd/back-bdb/search.c | 6 +- servers/slapd/connection.c | 14 ++- servers/slapd/controls.c | 128 +++++++++++++++++-- servers/slapd/dn.c | 4 + servers/slapd/operation.c | 2 - servers/slapd/proto-slap.h | 5 + servers/slapd/result.c | 209 +++++++++++++++++--------------- servers/slapd/slap.h | 21 ++-- servers/slapd/tools/mimic.c | 11 ++ 18 files changed, 562 insertions(+), 188 deletions(-) diff --git a/clients/tools/common.c b/clients/tools/common.c index f6cac8bd1c..1266f3010f 100644 --- a/clients/tools/common.c +++ b/clients/tools/common.c @@ -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 [!][=] general controls (! indicates criticality)\n") -N_(" [!]assert= (an RFC 2254 Filter)\n") -N_(" [!]authzid= (\"dn:\" or \"u:\")\n") -N_(" [!]manageDSAit (alternate form, see -M)\n") +N_(" [!]assert= (an RFC 2254 Filter)\n") +N_(" [!]authzid= (\"dn:\" or \"u:\")\n") +N_(" [!]manageDSAit\n") N_(" [!]noop\n"), +N_(" [!]postread[=] (a comma-separated attribute list)\n"), +N_(" [!]preread[=] (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=\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++; } diff --git a/clients/tools/common.h b/clients/tools/common.h index 38ecf7d4bf..dba31d251c 100644 --- a/clients/tools/common.h +++ b/clients/tools/common.h @@ -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; diff --git a/clients/tools/ldapmodify.c b/clients/tools/ldapmodify.c index 219be2c5fd..ff60a8b78e 100644 --- a/clients/tools/ldapmodify.c +++ b/clients/tools/ldapmodify.c @@ -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 ); } diff --git a/include/lber.h b/include/lber.h index c01b3acc04..728f575090 100644 --- a/include/lber.h +++ b/include/lber.h @@ -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 diff --git a/include/ldap.h b/include/ldap.h index 8a54468ad5..9d8b66056d 100644 --- a/include/ldap.h +++ b/include/ldap.h @@ -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" diff --git a/servers/slapd/back-bdb/add.c b/servers/slapd/back-bdb/add.c index 8086b04a94..e345b5ba39 100644 --- a/servers/slapd/back-bdb/add.c +++ b/servers/slapd/back-bdb/add.c @@ -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, <2, 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; diff --git a/servers/slapd/back-bdb/delete.c b/servers/slapd/back-bdb/delete.c index 2c7316f3d3..664d2f8e4c 100644 --- a/servers/slapd/back-bdb/delete.c +++ b/servers/slapd/back-bdb/delete.c @@ -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, <2, 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 ); diff --git a/servers/slapd/back-bdb/modify.c b/servers/slapd/back-bdb/modify.c index 5f6d87e26e..68806a7859 100644 --- a/servers/slapd/back-bdb/modify.c +++ b/servers/slapd/back-bdb/modify.c @@ -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, <2, 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 ); diff --git a/servers/slapd/back-bdb/modrdn.c b/servers/slapd/back-bdb/modrdn.c index 35fa4e966e..80d41518d5 100644 --- a/servers/slapd/back-bdb/modrdn.c +++ b/servers/slapd/back-bdb/modrdn.c @@ -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, <2, 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 ); diff --git a/servers/slapd/back-bdb/search.c b/servers/slapd/back-bdb/search.c index 2e5d868c83..93a8714d33 100644 --- a/servers/slapd/back-bdb/search.c +++ b/servers/slapd/back-bdb/search.c @@ -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; diff --git a/servers/slapd/connection.c b/servers/slapd/connection.c index 0a71d72777..e7effae346 100644 --- a/servers/slapd/connection.c +++ b/servers/slapd/connection.c @@ -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, diff --git a/servers/slapd/controls.c b/servers/slapd/controls.c index e24ce18023..2a7806194a 100644 --- a/servers/slapd/controls.c +++ b/servers/slapd/controls.c @@ -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 */ +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; io_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; io_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 ) diff --git a/servers/slapd/dn.c b/servers/slapd/dn.c index f147f518ab..be518eec58 100644 --- a/servers/slapd/dn.c +++ b/servers/slapd/dn.c @@ -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; } diff --git a/servers/slapd/operation.c b/servers/slapd/operation.c index 4efd292a80..17d4e4efaa 100644 --- a/servers/slapd/operation.c +++ b/servers/slapd/operation.c @@ -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(); diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index ef1afa7cd7..008a258941 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -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 )); diff --git a/servers/slapd/result.c b/servers/slapd/result.c index e59f4a434c..c4311df736 100644 --- a/servers/slapd/result.c +++ b/servers/slapd/result.c @@ -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; +} diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 44a718f8fb..156ef3a225 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -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 diff --git a/servers/slapd/tools/mimic.c b/servers/slapd/tools/mimic.c index 1b300b4799..9f972115e2 100644 --- a/servers/slapd/tools/mimic.c +++ b/servers/slapd/tools/mimic.c @@ -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; -- 2.39.5