From: Kurt Zeilenga Date: Sun, 30 Nov 2003 23:20:22 +0000 (+0000) Subject: First rounded of changes in prep for 2.2.beta3 X-Git-Tag: OPENLDAP_REL_ENG_2_2_3BETA~6 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=c350b558d7cbfb36ec8991fadd702c5dee3f4de8;p=openldap First rounded of changes in prep for 2.2.beta3 --- diff --git a/clients/tools/common.c b/clients/tools/common.c index 1266f3010f..bc74e28459 100644 --- a/clients/tools/common.c +++ b/clients/tools/common.c @@ -20,6 +20,7 @@ #include "lutil_ldap.h" #include "ldap_defaults.h" #include "ldap_pvt.h" +#include "lber_pvt.h" #include "common.h" @@ -762,8 +763,8 @@ tool_server_controls( LDAP *ld, LDAPControl *extra_c, int count ) } if ( assertctl ) { - char berbuf[LBER_ELEMENT_SIZEOF]; - BerElement *ber = (BerElement *)berbuf; + BerElementBuffer berbuf; + BerElement *ber = (BerElement *)&berbuf; if( assertion == NULL || *assertion == '\0' ) { fprintf( stderr, "Assertion=\n" ); @@ -820,7 +821,7 @@ tool_server_controls( LDAP *ld, LDAPControl *extra_c, int count ) if ( preread ) { char berbuf[LBER_ELEMENT_SIZEOF]; BerElement *ber = (BerElement *)berbuf; - char **attrs; + char **attrs = NULL; if( preread_attrs ) { attrs = ldap_str2charray( preread_attrs, "," ); @@ -850,7 +851,7 @@ tool_server_controls( LDAP *ld, LDAPControl *extra_c, int count ) if ( postread ) { char berbuf[LBER_ELEMENT_SIZEOF]; BerElement *ber = (BerElement *)berbuf; - char **attrs; + char **attrs = NULL; if( postread_attrs ) { attrs = ldap_str2charray( postread_attrs, "," ); diff --git a/clients/tools/ldapsearch.c b/clients/tools/ldapsearch.c index d2ded3e91a..6a33da58ae 100644 --- a/clients/tools/ldapsearch.c +++ b/clients/tools/ldapsearch.c @@ -1131,10 +1131,10 @@ print_entry( } write_ldif( LDIF_PUT_VALUE, "dn", bv.bv_val, bv.bv_len ); - rc = ldap_pvt_get_controls( ber, &ctrls ); + rc = ldap_get_entry_controls( ld, entry, &ctrls ); if( rc != LDAP_SUCCESS ) { fprintf(stderr, _("print_entry: %d\n"), rc ); - ldap_perror( ld, "ldap_pvt_get_controls" ); + ldap_perror( ld, "ldap_get_entry_controls" ); exit( EXIT_FAILURE ); } diff --git a/configure.in b/configure.in index e19651a421..7aed038024 100644 --- a/configure.in +++ b/configure.in @@ -173,7 +173,8 @@ OL_ARG_ENABLE(slapd,[ --enable-slapd enable building slapd], yes)dnl OL_ARG_ENABLE(aci,[ --enable-aci enable per-object ACIs (experimental)], no)dnl OL_ARG_ENABLE(cleartext,[ --enable-cleartext enable cleartext passwords], yes)dnl OL_ARG_ENABLE(crypt,[ --enable-crypt enable crypt(3) passwords], no)dnl -OL_ARG_ENABLE(kpasswd,[ --enable-kpasswd enable Kerberos password verification], no)dnl +dnl OL_ARG_ENABLE(kpasswd,[ --enable-kpasswd enable Kerberos password verification], no)dnl +ol_enable_kpasswd=${ol_enable_kpasswd-no} OL_ARG_ENABLE(lmpasswd,[ --enable-lmpasswd enable LAN Manager passwords], no)dnl OL_ARG_ENABLE(spasswd,[ --enable-spasswd enable (Cyrus) SASL password verification], no)dnl OL_ARG_ENABLE(modules,[ --enable-modules enable dynamic module support], no)dnl @@ -209,7 +210,7 @@ OL_ARG_WITH(ldbm_type,[ --with-ldbm-type use LDBM type auto|btree|hash], au OL_ARG_ENABLE(meta,[ --enable-meta enable metadirectory backend], no)dnl OL_ARG_WITH(meta_module,[ --with-meta-module module type static|dynamic], static, [static dynamic]) -OL_ARG_ENABLE(monitor,[ --enable-monitor enable monitor backend], no)dnl +OL_ARG_ENABLE(monitor,[ --enable-monitor enable monitor backend], yes)dnl OL_ARG_WITH(monitor_module,[ --with-monitor-module module type static|dynamic], static, [static dynamic]) OL_ARG_ENABLE(null,[ --enable-null enable null backend], no)dnl @@ -666,10 +667,12 @@ if test $ol_enable_perl != no ; then else PERL_CPPFLAGS="`$PERLBIN -MExtUtils::Embed -e ccopts`" + PERL_LDFLAGS="`$PERLBIN -MExtUtils::Embed -e ldopts|sed -e 's/ -lc / /'`" + if test x"$ol_with_perl_module" = "xstatic" ; then - SLAPD_PERL_LDFLAGS="`$PERLBIN -MExtUtils::Embed -e ldopts|sed -e s/-lc//`" + SLAPD_PERL_LDFLAGS="$PERL_LDFLAGS" else - MOD_PERL_LDFLAGS="`$PERLBIN -MExtUtils::Embed -e ldopts|sed -e s/-lc//`" + MOD_PERL_LDFLAGS="$PERL_LDFLAGS" fi dnl should check perl version ol_link_perl=yes @@ -1293,8 +1296,10 @@ else AC_WARN([TLS data protection not supported!]) fi +WITH_TLS=no if test $ol_link_tls = yes ; then AC_DEFINE(HAVE_TLS, 1, [define if you have TLS]) + WITH_TLS=yes elif test $ol_with_tls = auto ; then AC_WARN([Could not locate TLS/SSL package]) @@ -2769,6 +2774,7 @@ fi AC_SUBST(LIBSRCS) AC_SUBST(PLAT) +AC_SUBST(WITH_TLS) AC_SUBST(BUILD_LIBS_DYNAMIC) AC_SUBST(BUILD_SLAPD) @@ -2887,8 +2893,10 @@ servers/slapd/slapi/Makefile:build/top.mk:servers/slapd/slapi/Makefile.in:build/ servers/slapd/tools/Makefile:build/top.mk:servers/slapd/tools/Makefile.in \ servers/slurpd/Makefile:build/top.mk:servers/slurpd/Makefile.in:build/srv.mk \ tests/Makefile:build/top.mk:tests/Makefile.in:build/dir.mk \ +tests/run \ tests/progs/Makefile:build/top.mk:tests/progs/Makefile.in:build/rules.mk \ ,[ +chmod +x tests/run date > stamp-h echo Please run \"make depend\" to build dependencies ]) diff --git a/doc/devel/todo b/doc/devel/todo index a8a72a75f1..4df30ab78d 100644 --- a/doc/devel/todo +++ b/doc/devel/todo @@ -38,17 +38,21 @@ Implement LDAP sorted search results control Medium projects --------------- +Add DSML capabilities to command line tools Implement authPassword (RFC 3112) Implement DIT Structure Rules and Name Forms Implement LDAP Transactions extension +Implement native support for simple SASL mechanisms (e.g. EXTERNAL and PLAIN) +Implement LDAPprep Redesign slapd memory allocation fault handling Localize tools Small projects -------------- -Add DSML capabilities to command line tools Add dumpasn1 logging support +Implement SASLprep +Redesign test suite to use configure generated run script Add tests to test suite Convert utfconv.txt into man page(s). Recode linked-list structs to use macros diff --git a/doc/man/man3/ldap_add.3 b/doc/man/man3/ldap_add.3 index e42cc279a5..7605776702 100644 --- a/doc/man/man3/ldap_add.3 +++ b/doc/man/man3/ldap_add.3 @@ -10,16 +10,16 @@ OpenLDAP LDAP (libldap, -lldap) .nf .B #include .sp -.BI "int ldap_add(LDAP *" ld ", const char *" dn ", LDAPMOD *" attrs "[]);" +.BI "int ldap_add(LDAP *" ld ", const char *" dn ", LDAPMod *" attrs "[]);" .sp .BI "int ldap_add_s(LDAP *" ld ", const char *" dn ", LDAPMod *" attrs "[]);" .sp -.BI "int ldap_add_ext(LDAP *" ld ", const char *" dn ", LDAPMOD *" attrs "[]," +.BI "int ldap_add_ext(LDAP *" ld ", const char *" dn ", LDAPMod *" attrs "[]," .RS .BI "LDAPControl *" sctrls "[], LDAPControl *" cctrls "[], int *" msgidp ");" .RE .sp -.BI "int ldap_add_ext_s(LDAP *" ld ", const char *" dn ", LDAPMOD *" attrs "[]," +.BI "int ldap_add_ext_s(LDAP *" ld ", const char *" dn ", LDAPMod *" attrs "[]," .RS .BI "LDAPControl *" sctrls "[], LDAPControl *" cctrls "[]);" .RE diff --git a/doc/man/man3/ldap_bind.3 b/doc/man/man3/ldap_bind.3 index 86dc518822..940b2727ec 100644 --- a/doc/man/man3/ldap_bind.3 +++ b/doc/man/man3/ldap_bind.3 @@ -53,7 +53,7 @@ OpenLDAP LDAP (libldap, -lldap) .LP .BI "int ldap_sasl_interactive_bind_s(LDAP *" ld ", const char *" dn "," .RS -.BI "const char *" mechs ", struct berval *" cred "," +.BI "const char *" mechs "," .BI "LDAPControl *" sctrls "[], LDAPControl *" cctrls "[]," .BI "unsigned " flags ", LDAP_SASL_INTERACT_PROC *" interact "," .BI "void *" defaults ");" diff --git a/doc/man/man5/slapd.access.5 b/doc/man/man5/slapd.access.5 index ebf9264488..77c52ca7ef 100644 --- a/doc/man/man5/slapd.access.5 +++ b/doc/man/man5/slapd.access.5 @@ -216,6 +216,16 @@ dn.regex clause by using the form with .B digit ranging from 1 to 9. +The style qualifier +allows an optional +.BR modifier . +At present, the only type allowed is +.BR expand , +which causes substring substitution of submatches to take place +even if +.B dnstyle +is not +.BR regex . .LP The statement .B dnattr= @@ -240,7 +250,8 @@ can be .BR regex , which means that .B -will be expanded according to regex (7), and +will be expanded as a replacement string (but not as a regular expression) +according to regex (7), and .B base or .B exact @@ -298,6 +309,22 @@ of the contacting host is determined by performing a DNS reverse lookup. As this lookup can easily be spoofed, use of the .B domain statement is strongly discouraged. By default, reverse lookups are disabled. +The optional +.B domainstyle +qualifier of the +.B domain +clause allows a +.B modifier +option; the only value currently supported is +.BR expand , +which causes substring substitution of submatches to take place even if +the +.B domainstyle +is not +.BR regex , +much like the analogous usage in +.B dn +clause. .LP The statement .B set= diff --git a/doc/man/man5/slapd.conf.5 b/doc/man/man5/slapd.conf.5 index 6a4d9a7536..f59ac00bc3 100644 --- a/doc/man/man5/slapd.conf.5 +++ b/doc/man/man5/slapd.conf.5 @@ -45,9 +45,12 @@ As many backend-specific sections as desired may be included. Global options can be overridden in a backend (for options that appear more than once, the last appearance in the .B slapd.conf -file is used). Blank lines and comment lines beginning with a `#' -character are ignored. If a line begins with white space, it is -considered a continuation of the previous line. +file is used). +.LP +If a line begins with white space, it is considered a continuation +of the previous line. Blank lines and comment lines beginning with +a `#' character are ignored. (Note: continuation lines are unwrapped +before comment processing is applied.) .LP Arguments on configuration lines are separated by white space. If an argument contains white space, the argument should be enclosed in diff --git a/include/lber.h b/include/lber.h index 3b351c5818..a5c996cd9c 100644 --- a/include/lber.h +++ b/include/lber.h @@ -157,18 +157,6 @@ extern char ber_pvt_opt_on; #define LBER_OPT_SUCCESS (0) #define LBER_OPT_ERROR (-1) -#define LBER_ELEMENT_SIZEOF (256) /* must be >= sizeof(BerElement) */ -typedef union ber_buffer_u { - char charbuf[LBER_ELEMENT_SIZEOF]; - - /* force alignment */ - int intbuf; - long longbuf; - float floatbuf; - double doublebuf; - char* ptrbuf; -} BerElementBuffer; - typedef struct berelement BerElement; typedef struct sockbuf Sockbuf; typedef struct seqorset Seqorset; diff --git a/include/lber_pvt.h b/include/lber_pvt.h index 48817d1b01..69eaee3ced 100644 --- a/include/lber_pvt.h +++ b/include/lber_pvt.h @@ -21,6 +21,22 @@ LDAP_BEGIN_DECL +/* for allocating aligned buffers (on the stack) */ +#define LBER_ALIGNED_BUFFER(uname,size) \ + union uname { \ + char buffer[size]; \ + /* force alignment */ \ + int ialign; \ + long lalign; \ + float falign; \ + double dalign; \ + char* palign; \ + } + +#define LBER_ELEMENT_SIZEOF (256) /* must be >= sizeof(BerElement) */ +typedef LBER_ALIGNED_BUFFER(lber_berelement_u,LBER_ELEMENT_SIZEOF) + BerElementBuffer; + typedef struct sockbuf_buf { ber_len_t buf_size; ber_len_t buf_ptr; diff --git a/include/ldap.h b/include/ldap.h index 9d8b66056d..cf96aa7f98 100644 --- a/include/ldap.h +++ b/include/ldap.h @@ -206,14 +206,18 @@ typedef struct ldapcontrol { #define LDAP_CONTROL_SYNC_DONE "1.3.6.1.4.1.4203.666.5.8" #define LDAP_SYNC_INFO "1.3.6.1.4.1.4203.666.10.2" -#define LDAP_SYNC_NEW_COOKIE 0 -#define LDAP_SYNC_STATE_MODE_DONE 1 -#define LDAP_SYNC_LOG_MODE_DONE 2 -#define LDAP_SYNC_REFRESH_DONE 3 +#define LDAP_SYNC_REFRESH_PRESENTS 0 +#define LDAP_SYNC_REFRESH_DELETES 1 -#define LDAP_SYNC_STATE_MODE 0 -#define LDAP_SYNC_LOG_MODE 1 -#define LDAP_SYNC_PERSIST_MODE 2 +#define LDAP_TAG_SYNC_NEW_COOKIE ((ber_tag_t) 0x80U) +#define LDAP_TAG_SYNC_REFRESH_DELETE ((ber_tag_t) 0xa1U) +#define LDAP_TAG_SYNC_REFRESH_PRESENT ((ber_tag_t) 0xa2U) +#define LDAP_TAG_SYNC_ID_SET ((ber_tag_t) 0xa3U) + +#define LDAP_TAG_SYNC_COOKIE ((ber_tag_t) 0x04U) +#define LDAP_TAG_REFRESHDELETES ((ber_tag_t) 0x01U) +#define LDAP_TAG_REFRESHDONE ((ber_tag_t) 0x01U) +#define LDAP_TAG_RELOAD_HINT ((ber_tag_t) 0x01U) #define LDAP_SYNC_PRESENT 0 #define LDAP_SYNC_ADD 1 @@ -293,9 +297,6 @@ typedef struct ldapcontrol { #define LDAP_TAG_SASL_RES_CREDS ((ber_tag_t) 0x87U) /* context specific + primitive */ -#define LDAP_SYNC_TAG_COOKIE ((ber_tag_t) 0x04U) /* octet string */ - - /* possible operations a client can invoke */ #define LDAP_REQ_BIND ((ber_tag_t) 0x60U) /* application + constructed */ #define LDAP_REQ_UNBIND ((ber_tag_t) 0x42U) /* application + primitive */ diff --git a/include/ldap_pvt.h b/include/ldap_pvt.h index 72af273dfc..a1cf5c7514 100644 --- a/include/ldap_pvt.h +++ b/include/ldap_pvt.h @@ -155,7 +155,7 @@ LDAP_F (struct ldapcontrol *) ldap_control_dup LDAP_P(( LDAP_F (struct ldapcontrol **) ldap_controls_dup LDAP_P(( struct ldapcontrol *const *ctrls )); -LDAP_F (int) ldap_int_get_controls LDAP_P(( +LDAP_F (int) ldap_pvt_get_controls LDAP_P(( BerElement *be, struct ldapcontrol ***ctrlsp)); diff --git a/include/ldap_rq.h b/include/ldap_rq.h index de6f32a936..b2f0b43090 100644 --- a/include/ldap_rq.h +++ b/include/ldap_rq.h @@ -73,7 +73,8 @@ ldap_pvt_runqueue_isrunning( LDAP_F( void ) ldap_pvt_runqueue_resched( struct runqueue_s* rq, - struct re_s* entry + struct re_s* entry, + int defer ); LDAP_F( int ) diff --git a/include/ldbm.h b/include/ldbm.h index 5a86a5fa70..786cde15bb 100644 --- a/include/ldbm.h +++ b/include/ldbm.h @@ -15,7 +15,7 @@ #define _LDBM_H_ #include -#include +#include /* dummy DB_ENV for non Berkeley DB */ #if !defined( LDBM_USE_DBBTREE ) && !defined( LDBM_USE_DBHASH ) diff --git a/include/rewrite.h b/include/rewrite.h index 08398420c0..fdf7c1f4df 100644 --- a/include/rewrite.h +++ b/include/rewrite.h @@ -96,7 +96,7 @@ rewrite_info_init( */ LDAP_REWRITE_F (int) rewrite_info_delete( - struct rewrite_info *info + struct rewrite_info **info ); diff --git a/include/slapi-plugin.h b/include/slapi-plugin.h index fc6ac13ad2..5058b1cca2 100644 --- a/include/slapi-plugin.h +++ b/include/slapi-plugin.h @@ -3,11 +3,10 @@ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file */ /* - * (C) Copyright IBM Corp. 1997,2002 - * Redistribution and use in source and binary forms are permitted - * provided that this notice is preserved and that due credit is - * given to IBM Corporation. This software is provided ``as is'' - * without express or implied warranty. + * Copyright IBM Corp. 1997,2002,2003 + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. */ #ifndef _SLAPI_PLUGIN_H diff --git a/libraries/libldap/cyrus.c b/libraries/libldap/cyrus.c index 1816d8d7c3..5c70c5ec46 100644 --- a/libraries/libldap/cyrus.c +++ b/libraries/libldap/cyrus.c @@ -185,7 +185,7 @@ sb_sasl_remove( Sockbuf_IO_Desc *sbiod ) } static ber_len_t -sb_sasl_pkt_length( const unsigned char *buf, unsigned max, int debuglevel ) +sb_sasl_pkt_length( const unsigned char *buf, int debuglevel ) { ber_len_t size; @@ -209,7 +209,7 @@ sb_sasl_pkt_length( const unsigned char *buf, unsigned max, int debuglevel ) /* Drop a processed packet from the input buffer */ static void -sb_sasl_drop_packet ( Sockbuf_Buf *sec_buf_in, unsigned max, int debuglevel ) +sb_sasl_drop_packet ( Sockbuf_Buf *sec_buf_in, int debuglevel ) { ber_slen_t len; @@ -220,7 +220,7 @@ sb_sasl_drop_packet ( Sockbuf_Buf *sec_buf_in, unsigned max, int debuglevel ) if ( len >= 4 ) { sec_buf_in->buf_end = sb_sasl_pkt_length( - (unsigned char *) sec_buf_in->buf_base, max, debuglevel); + (unsigned char *) sec_buf_in->buf_base, debuglevel); } else { sec_buf_in->buf_end = 0; @@ -269,7 +269,7 @@ sb_sasl_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len) /* The new packet always starts at p->sec_buf_in.buf_base */ ret = sb_sasl_pkt_length( (unsigned char *) p->sec_buf_in.buf_base, - *p->sasl_maxbuf, sbiod->sbiod_sb->sb_debug ); + sbiod->sbiod_sb->sb_debug ); /* Grow the packet buffer if neccessary */ if ( ( p->sec_buf_in.buf_size < (ber_len_t) ret ) && @@ -304,8 +304,7 @@ sb_sasl_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len) (unsigned *)&p->buf_in.buf_end ); /* Drop the packet from the input buffer */ - sb_sasl_drop_packet( &p->sec_buf_in, - *p->sasl_maxbuf, sbiod->sbiod_sb->sb_debug ); + sb_sasl_drop_packet( &p->sec_buf_in, sbiod->sbiod_sb->sb_debug ); if ( ret != SASL_OK ) { ber_log_printf( LDAP_DEBUG_ANY, sbiod->sbiod_sb->sb_debug, @@ -599,9 +598,10 @@ ldap_int_sasl_bind( ld->ld_defconn->lconn_sasl_authctx = NULL; } - rc = ldap_int_sasl_open( ld, ld->ld_defconn, - ld->ld_defconn->lconn_server->lud_host ? - ld->ld_defconn->lconn_server->lud_host : "localhost" ); + { char *saslhost = ldap_host_connected_to( ld->ld_sb, "localhost" ); + rc = ldap_int_sasl_open( ld, ld->ld_defconn, saslhost ); + LDAP_FREE( saslhost ); + } if ( rc != LDAP_SUCCESS ) return rc; diff --git a/libraries/libldap/dnssrv.c b/libraries/libldap/dnssrv.c index d9bbcbe81e..d1e3a9fa8b 100644 --- a/libraries/libldap/dnssrv.c +++ b/libraries/libldap/dnssrv.c @@ -28,11 +28,6 @@ #include #endif -/* Sometimes this is not defined. */ -#ifndef T_SRV -#define T_SRV 33 -#endif /* T_SRV */ - int ldap_dn2domain( LDAP_CONST char *dn_in, char **domainp) @@ -203,7 +198,16 @@ int ldap_domain2hostlist( #endif rc = LDAP_UNAVAILABLE; +#ifdef NS_HFIXEDSZ + /* Bind 8/9 interface */ + len = res_query(request, ns_c_in, ns_t_srv, reply, sizeof(reply)); +#else + /* Bind 4 interface */ +# ifndef T_SRV +# define T_SRV 33 +# endif len = res_query(request, C_IN, T_SRV, reply, sizeof(reply)); +#endif if (len >= 0) { unsigned char *p; char host[DNSBUFSIZ]; @@ -213,7 +217,13 @@ int ldap_domain2hostlist( /* Parse out query */ p = reply; - p += sizeof(HEADER); +#ifdef NS_HFIXEDSZ + /* Bind 8/9 interface */ + p += NS_HFIXEDSZ; +#else + /* Bind 4 interface */ + p += HFIXEDSZ; +#endif status = dn_expand(reply, reply + len, p, host, sizeof(host)); if (status < 0) { goto out; diff --git a/libraries/libldap/init.c b/libraries/libldap/init.c index 1a09236687..37c4298b7c 100644 --- a/libraries/libldap/init.c +++ b/libraries/libldap/init.c @@ -398,6 +398,8 @@ ldap_int_destroy_global_options(void) { struct ldapoptions *gopts = LDAP_INT_GLOBAL_OPT(); + gopts->ldo_valid = LDAP_UNINITIALIZED; + if ( gopts->ldo_defludp ) { ldap_free_urllist( gopts->ldo_defludp ); gopts->ldo_defludp = NULL; diff --git a/libraries/libldap/os-ip.c b/libraries/libldap/os-ip.c index 57195918db..af0c2c8270 100644 --- a/libraries/libldap/os-ip.c +++ b/libraries/libldap/os-ip.c @@ -371,6 +371,9 @@ ldap_connect_to_host(LDAP *ld, Sockbuf *sb, #if defined( HAVE_GETADDRINFO ) && defined( HAVE_INET_NTOP ) memset( &hints, '\0', sizeof(hints) ); +#ifdef AI_ADDRCONFIG + hints.ai_flags = AI_ADDRCONFIG; +#endif hints.ai_family = ldap_int_inet4or6; hints.ai_socktype = socktype; snprintf(serv, sizeof serv, "%d", port ); diff --git a/libraries/libldap/tls.c b/libraries/libldap/tls.c index 3786c19da9..6e5878a27e 100644 --- a/libraries/libldap/tls.c +++ b/libraries/libldap/tls.c @@ -858,45 +858,6 @@ ldap_pvt_tls_inplace ( Sockbuf *sb ) return HAS_TLS( sb ) ? 1 : 0; } -void * -ldap_pvt_tls_sb_ctx( Sockbuf *sb ) -{ - void *p; - - if (HAS_TLS( sb )) { - ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_SSL, (void *)&p ); - return p; - } - - return NULL; -} - -int -ldap_pvt_tls_get_strength( void *s ) -{ - SSL_CIPHER *c; - - c = SSL_get_current_cipher((SSL *)s); - return SSL_CIPHER_get_bits(c, NULL); -} - - -int -ldap_pvt_tls_get_my_dn( void *s, struct berval *dn, LDAPDN_rewrite_dummy *func, unsigned flags ) -{ - X509 *x; - X509_NAME *xn; - int rc; - - x = SSL_get_certificate((SSL *)s); - - if (!x) return LDAP_INVALID_CREDENTIALS; - - xn = X509_get_subject_name(x); - rc = ldap_X509dn2bv(xn, dn, (LDAPDN_rewrite_func *)func, flags ); - return rc; -} - static X509 * tls_get_cert( SSL *s ) { @@ -1692,6 +1653,55 @@ tls_tmp_dh_cb( SSL *ssl, int is_export, int key_length ) #endif #endif +void * +ldap_pvt_tls_sb_ctx( Sockbuf *sb ) +{ +#ifdef HAVE_TLS + void *p; + + if (HAS_TLS( sb )) { + ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_SSL, (void *)&p ); + return p; + } +#endif + + return NULL; +} + +int +ldap_pvt_tls_get_strength( void *s ) +{ +#ifdef HAVE_TLS + SSL_CIPHER *c; + + c = SSL_get_current_cipher((SSL *)s); + return SSL_CIPHER_get_bits(c, NULL); +#else + return 0; +#endif +} + + +int +ldap_pvt_tls_get_my_dn( void *s, struct berval *dn, LDAPDN_rewrite_dummy *func, unsigned flags ) +{ +#ifdef HAVE_TLS + X509 *x; + X509_NAME *xn; + int rc; + + x = SSL_get_certificate((SSL *)s); + + if (!x) return LDAP_INVALID_CREDENTIALS; + + xn = X509_get_subject_name(x); + rc = ldap_X509dn2bv(xn, dn, (LDAPDN_rewrite_func *)func, flags ); + return rc; +#else + return LDAP_NOT_SUPPORTED; +#endif +} + int ldap_start_tls_s ( LDAP *ld, LDAPControl **serverctrls, diff --git a/libraries/libldap_r/rq.c b/libraries/libldap_r/rq.c index 16a8111501..eed92e72e9 100644 --- a/libraries/libldap_r/rq.c +++ b/libraries/libldap_r/rq.c @@ -3,6 +3,24 @@ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved. * COPYING RESTRICTIONS APPLY, see COPYRIGHT file */ +/* Copyright (c) 2003 by International Business Machines, Inc. + * + * International Business Machines, Inc. (hereinafter called IBM) grants + * permission under its copyrights to use, copy, modify, and distribute this + * Software with or without fee, provided that the above copyright notice and + * all paragraphs of this notice appear in all copies, and that the name of IBM + * not be used in connection with the marketing of any product incorporating + * the Software or modifications thereof, without specific, written prior + * permission. + * + * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, + * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN + * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + #include "portable.h" #include @@ -118,7 +136,8 @@ ldap_pvt_runqueue_isrunning( void ldap_pvt_runqueue_resched( struct runqueue_s* rq, - struct re_s* entry + struct re_s* entry, + int defer ) { struct re_s* prev; @@ -133,7 +152,7 @@ ldap_pvt_runqueue_resched( LDAP_STAILQ_REMOVE( &rq->task_list, entry, re_s, tnext ); - if ( entry->interval.tv_sec ) { + if ( entry->interval.tv_sec && !defer ) { entry->next_sched.tv_sec = time( NULL ) + entry->interval.tv_sec; } else { entry->next_sched.tv_sec = 0; diff --git a/libraries/libldap_r/thr_posix.c b/libraries/libldap_r/thr_posix.c index 825761e330..ed0c9425b8 100644 --- a/libraries/libldap_r/thr_posix.c +++ b/libraries/libldap_r/thr_posix.c @@ -121,7 +121,12 @@ ldap_pvt_thread_create( ldap_pvt_thread_t * thread, pthread_attr_setdetachstate(&attr, detach); #endif #endif + +#if HAVE_PTHREADS < 5 + rtn = pthread_create( thread, attr, start_routine, arg ); +#else rtn = pthread_create( thread, &attr, start_routine, arg ); +#endif #if HAVE_PTHREADS > 5 pthread_attr_destroy(&attr); #else diff --git a/libraries/libldif/line64.c b/libraries/libldif/line64.c index c3775a7bd2..b82933d971 100644 --- a/libraries/libldif/line64.c +++ b/libraries/libldif/line64.c @@ -571,7 +571,7 @@ ldif_read_record( { char linebuf[BUFSIZ], *line, *nbufp; ber_len_t lcur = 0, len, linesize; - int last_ch = '\n', found_entry = 0, stop; + int last_ch = '\n', found_entry = 0, stop, top_comment = 0; line = linebuf; linesize = sizeof( linebuf ); @@ -588,18 +588,25 @@ ldif_read_record( (*lno)++; if ( line[0] == '\n' ) { - if ( !found_entry ) + if ( !found_entry ) { + lcur = 0; + top_comment = 0; continue; + } break; } if ( !found_entry ) { - /* Found a new entry */ - found_entry = 1; - - if ( isdigit( (unsigned char) line[0] ) ) { - /* skip index */ - continue; + if ( line[0] == '#' ) { + top_comment = 1; + } else if ( ! ( top_comment && line[0] == ' ' ) ) { + /* Found a new entry */ + found_entry = 1; + + if ( isdigit( (unsigned char) line[0] ) ) { + /* skip index */ + continue; + } } } } diff --git a/libraries/liblunicode/ucstr.c b/libraries/liblunicode/ucstr.c index d854b2aead..474837ae6b 100644 --- a/libraries/liblunicode/ucstr.c +++ b/libraries/liblunicode/ucstr.c @@ -252,8 +252,8 @@ struct berval * UTF8bvnormalize( last = i; /* Allocate more space in out if necessary */ - if (len - i > outsize - outpos) { - outsize = outsize + ((len - i) - (outsize - outpos)); + if (len - i >= outsize - outpos) { + outsize += 1 + ((len - i) - (outsize - outpos)); outtmp = (char *) realloc(out, outsize); if (outtmp == NULL) { free(out); diff --git a/libraries/liblutil/csn.c b/libraries/liblutil/csn.c index 6f49a8cf13..0c95ccfef8 100644 --- a/libraries/liblutil/csn.c +++ b/libraries/liblutil/csn.c @@ -13,16 +13,18 @@ /* * This file contains routines to generate a change sequence number. Every - * add delete, and modification is given a unique identifier for use in + * add, delete, and modification is given a unique identifier for use in * resolving conflicts during replication operations. * - * These routines are based upon draft-ietf-ldup-model-03.txt, and will - * need to be revisited once standardized. + * These routines are (loosly) based upon draft-ietf-ldup-model-03.txt, + * A WORK IN PROGRESS. The format will likely change. * - * The format of a CSN string is: yyyymmddhh:mm:ssz#0xSSSS#d#0xssss - * where SSSS is a counter of operations within a timeslice, d is an - * offset into a list of replica records, and ssss is a counter of - * modifications within this operation. + * The format of a CSN string is: yyyymmddhhmmssz#s#r#c + * where s is a counter of operations within a timeslice, r is + * the replica id (normally zero), and c is a counter of + * modifications within this operation. s, r, and c are + * represented in hex and zero padded to lengths of 6, 2, and + * 6, respectively. * * Calls to this routine MUST be serialized with other calls * to gmtime(). @@ -53,7 +55,8 @@ lutil_csnstr(char *buf, size_t len, unsigned int replica, unsigned int mod) op = ++csnop; ltm = gmtime( &t ); - n = snprintf( buf, len, "%4d%02d%02d%02d:%02d:%02dZ#0x%04x#%d#%04x", + n = snprintf( buf, len, + "%4d%02d%02d%02d%02d%02dZ#%06x#%02x#%06x", ltm->tm_year + 1900, ltm->tm_mon + 1, ltm->tm_mday, ltm->tm_hour, ltm->tm_min, ltm->tm_sec, op, replica, mod ); diff --git a/libraries/liblutil/passwd.c b/libraries/liblutil/passwd.c index 737a1e2562..9bf78292c8 100644 --- a/libraries/liblutil/passwd.c +++ b/libraries/liblutil/passwd.c @@ -485,7 +485,7 @@ static int chk_ssha1( rc = lutil_b64_pton(passwd->bv_val, orig_pass, passwd->bv_len); - if (rc <= sizeof(SHA1digest)) { + if (rc < 0 || (unsigned)rc <= sizeof(SHA1digest)) { ber_memfree(orig_pass); return -1; } @@ -566,7 +566,7 @@ static int chk_smd5( rc = lutil_b64_pton(passwd->bv_val, orig_pass, passwd->bv_len); - if (rc <= sizeof(MD5digest)) { + if (rc < 0 || (unsigned)rc <= sizeof(MD5digest)) { ber_memfree(orig_pass); return -1; } @@ -762,7 +762,7 @@ static int chk_ns_mta_md5( char buffer[LUTIL_MD5_BYTES*2]; int i; - if( passwd.bv_len != LUTIL_MD5_BYTES*2 ) { + if( passwd->bv_len != LUTIL_MD5_BYTES*2 ) { return 1; } diff --git a/libraries/librewrite/Makefile.in b/libraries/librewrite/Makefile.in index f2e4cdfa6a..b8a487192f 100644 --- a/libraries/librewrite/Makefile.in +++ b/libraries/librewrite/Makefile.in @@ -8,11 +8,11 @@ ## SRCS = config.c context.c info.c ldapmap.c map.c params.c rule.c \ - session.c subst.c var.c \ + session.c subst.c var.c xmap.c \ parse.c rewrite.c XSRCS = version.c OBJS = config.o context.o info.o ldapmap.o map.o params.o rule.o \ - session.o subst.o var.o + session.o subst.o var.o xmap.o LDAP_INCDIR= ../../include LDAP_LIBDIR= ../../libraries diff --git a/libraries/librewrite/config.c b/libraries/librewrite/config.c index 556fd30947..514b16c415 100644 --- a/libraries/librewrite/config.c +++ b/libraries/librewrite/config.c @@ -75,6 +75,7 @@ rewrite_parse( "[%s:%d] rewriteEngine needs 'state'\n%s", fname, lineno, "" ); return -1; + } else if ( argc > 2 ) { Debug( LDAP_DEBUG_ANY, "[%s:%d] extra fields in rewriteEngine" @@ -84,8 +85,10 @@ rewrite_parse( if ( strcasecmp( argv[ 1 ], "on" ) == 0 ) { info->li_state = REWRITE_ON; + } else if ( strcasecmp( argv[ 1 ], "off" ) == 0 ) { info->li_state = REWRITE_OFF; + } else { Debug( LDAP_DEBUG_ANY, "[%s:%d] unknown 'state' in rewriteEngine;" @@ -123,12 +126,12 @@ rewrite_parse( * Checks for existence (lots of contexts should be * available by default ...) */ - __curr_context = rewrite_context_find( info, argv[ 1 ] ); - if ( __curr_context == NULL ) { - __curr_context = rewrite_context_create( info, + rewrite_int_curr_context = rewrite_context_find( info, argv[ 1 ] ); + if ( rewrite_int_curr_context == NULL ) { + rewrite_int_curr_context = rewrite_context_create( info, argv[ 1 ] ); } - if ( __curr_context == NULL ) { + if ( rewrite_int_curr_context == NULL ) { return -1; } @@ -151,6 +154,7 @@ rewrite_parse( " 'alias'\n%s", fname, lineno, "" ); return -1; + } else if ( argc > 4 ) { Debug( LDAP_DEBUG_ANY, "[%s:%d] extra fields in" @@ -173,8 +177,9 @@ rewrite_parse( return -1; } - __curr_context->lc_alias = aliased; - __curr_context = aliased; + rewrite_int_curr_context->lc_alias = aliased; + rewrite_int_curr_context = aliased; + } else { Debug( LDAP_DEBUG_ANY, "[%s:%d] extra fields" @@ -195,6 +200,7 @@ rewrite_parse( " 'subst' ['flags']\n%s", fname, lineno, "" ); return -1; + } else if ( argc > 4 ) { Debug( LDAP_DEBUG_ANY, "[%s:%d] extra fields in rewriteRule" @@ -202,22 +208,22 @@ rewrite_parse( fname, lineno, "" ); } - if ( __curr_context == NULL ) { + if ( rewrite_int_curr_context == NULL ) { Debug( LDAP_DEBUG_ANY, "[%s:%d] rewriteRule outside a" " context; will add to default\n%s", fname, lineno, "" ); - __curr_context = rewrite_context_find( info, + rewrite_int_curr_context = rewrite_context_find( info, REWRITE_DEFAULT_CONTEXT ); /* * Default context MUST exist in a properly initialized * struct rewrite_info */ - assert( __curr_context != NULL ); + assert( rewrite_int_curr_context != NULL ); } - rc = rewrite_rule_compile( info, __curr_context, argv[ 1 ], + rc = rewrite_rule_compile( info, rewrite_int_curr_context, argv[ 1 ], argv[ 2 ], ( argc == 4 ? argv[ 3 ] : "" ) ); /* diff --git a/libraries/librewrite/context.c b/libraries/librewrite/context.c index 115cca6f1e..e77b485165 100644 --- a/libraries/librewrite/context.c +++ b/libraries/librewrite/context.c @@ -144,6 +144,7 @@ rewrite_context_create( free( context ); return NULL; } + memset( context->lc_rule, 0, sizeof( struct rewrite_rule ) ); /* * Add context to tree @@ -250,7 +251,7 @@ rewrite_context_apply( case REWRITE_REGEXEC_ERR: Debug( LDAP_DEBUG_ANY, "==> rewrite_context_apply" - " error ...\n%s%s%s", "", "", ""); + " error ...\n", 0, 0, 0); /* * Checks for special actions to be taken @@ -272,8 +273,7 @@ rewrite_context_apply( case REWRITE_ACTION_IGNORE_ERR: Debug( LDAP_DEBUG_ANY, "==> rewrite_context_apply" - " ignoring error ...\n%s%s%s", - "", "", "" ); + " ignoring error ...\n", 0, 0, 0 ); do_continue = 1; break; @@ -413,3 +413,49 @@ rc_end_of_context:; return return_code; } +void +rewrite_context_free( + void *tmp +) +{ + struct rewrite_context *context = (struct rewrite_context *)tmp; + + assert( tmp ); + + rewrite_context_destroy( &context ); +} + +int +rewrite_context_destroy( + struct rewrite_context **pcontext +) +{ + struct rewrite_context *context; + struct rewrite_rule *r; + + assert( pcontext ); + assert( *pcontext ); + + context = *pcontext; + + assert( context->lc_rule ); + + for ( r = context->lc_rule->lr_next; r; ) { + struct rewrite_rule *cr = r; + + r = r->lr_next; + rewrite_rule_destroy( &cr ); + } + + free( context->lc_rule ); + context->lc_rule = NULL; + + assert( context->lc_name ); + free( context->lc_name ); + context->lc_name = NULL; + + free( context ); + *pcontext = NULL; + + return 0; +} diff --git a/libraries/librewrite/info.c b/libraries/librewrite/info.c index 6a89f3ce43..fbc2fc67ba 100644 --- a/libraries/librewrite/info.c +++ b/libraries/librewrite/info.c @@ -35,7 +35,7 @@ * rewrite_parse; it can be altered only by a * rewriteContext config line or by a change in info. */ -struct rewrite_context *__curr_context = NULL; +struct rewrite_context *rewrite_int_curr_context = NULL; /* * Inits the info @@ -63,7 +63,7 @@ rewrite_info_init( /* * Resets the running context for parsing ... */ - __curr_context = NULL; + rewrite_int_curr_context = NULL; info = calloc( sizeof( struct rewrite_info ), 1 ); if ( info == NULL ) { @@ -102,20 +102,41 @@ rewrite_info_init( */ int rewrite_info_delete( - struct rewrite_info *info + struct rewrite_info **pinfo ) { - assert( info != NULL ); + struct rewrite_info *info; + + assert( pinfo != NULL ); + assert( *pinfo != NULL ); + + info = *pinfo; + if ( info->li_context ) { + avl_free( info->li_context, rewrite_context_free ); + } + info->li_context = NULL; + + if ( info->li_maps ) { + avl_free( info->li_maps, rewrite_builtin_map_free ); + } + info->li_context = NULL; + rewrite_session_destroy( info ); +#ifdef USE_REWRITE_LDAP_PVT_THREADS + ldap_pvt_thread_rdwr_destroy( &info->li_cookies_mutex ); +#endif /* USE_REWRITE_LDAP_PVT_THREADS */ + rewrite_param_destroy( info ); #ifdef USE_REWRITE_LDAP_PVT_THREADS - ldap_pvt_thread_rdwr_destroy( &info->li_cookies_mutex ); ldap_pvt_thread_rdwr_destroy( &info->li_params_mutex ); #endif /* USE_REWRITE_LDAP_PVT_THREADS */ + free( info ); + *pinfo = NULL; + return REWRITE_SUCCESS; } @@ -156,7 +177,7 @@ rewrite_session( ) { struct rewrite_context *context; - struct rewrite_op op = { 0, 0, NULL, NULL, NULL, NULL }; + struct rewrite_op op = { 0, 0, NULL, NULL, NULL }; int rc; assert( info != NULL ); @@ -189,34 +210,40 @@ rewrite_session( case REWRITE_MODE_ERR: rc = REWRITE_REGEXEC_ERR; goto rc_return; + case REWRITE_MODE_OK: rc = REWRITE_REGEXEC_OK; goto rc_return; + case REWRITE_MODE_COPY_INPUT: *result = strdup( string ); rc = REWRITE_REGEXEC_OK; goto rc_return; + case REWRITE_MODE_USE_DEFAULT: context = rewrite_context_find( info, REWRITE_DEFAULT_CONTEXT ); break; } } - + +#if 0 /* FIXME: not used anywhere! (debug? then, why strdup?) */ op.lo_string = strdup( string ); if ( op.lo_string == NULL ) { rc = REWRITE_REGEXEC_ERR; goto rc_return; } +#endif /* * Applies rewrite context */ - rc = rewrite_context_apply(info, &op, context, string, result ); + rc = rewrite_context_apply( info, &op, context, string, result ); assert( op.lo_depth == 0 ); - /* ?!? */ +#if 0 /* FIXME: not used anywhere! (debug? then, why strdup?) */ free( op.lo_string ); +#endif switch ( rc ) { /* diff --git a/libraries/librewrite/ldapmap.c b/libraries/librewrite/ldapmap.c index 6f83ff7aa3..07e04bccf2 100644 --- a/libraries/librewrite/ldapmap.c +++ b/libraries/librewrite/ldapmap.c @@ -331,3 +331,21 @@ rc_return:; return rc; } +int +map_ldap_destroy( + struct rewrite_builtin_map **pmap +) +{ + struct ldap_map_data *data; + + assert( pmap ); + assert( *pmap ); + + data = ( struct ldap_map_data * )(*pmap)->lb_private; + + free( data ); + *pmap = NULL; + + return 0; +} + diff --git a/libraries/librewrite/map.c b/libraries/librewrite/map.c index 7ddd0d99dd..d17d814629 100644 --- a/libraries/librewrite/map.c +++ b/libraries/librewrite/map.c @@ -33,195 +33,6 @@ #include "rewrite-int.h" #include "rewrite-map.h" -/* - * Global data - */ -#ifdef USE_REWRITE_LDAP_PVT_THREADS -ldap_pvt_thread_mutex_t xpasswd_mutex; -static int xpasswd_mutex_init = 0; -#endif /* USE_REWRITE_LDAP_PVT_THREADS */ - -/* - * Map parsing - * NOTE: these are old-fashion maps; new maps will be parsed on separate - * config lines, and referred by name. - */ -struct rewrite_map * -rewrite_xmap_parse( - struct rewrite_info *info, - const char *s, - const char **currpos -) -{ - struct rewrite_map *map; - - assert( info != NULL ); - assert( s != NULL ); - assert( currpos != NULL ); - - Debug( LDAP_DEBUG_ARGS, "rewrite_xmap_parse: %s\n%s%s", - s, "", "" ); - - *currpos = NULL; - - map = calloc( sizeof( struct rewrite_map ), 1 ); - if ( map == NULL ) { - Debug( LDAP_DEBUG_ANY, "rewrite_xmap_parse:" - " calloc failed\n%s%s%s", "", "", "" ); - return NULL; - } - - /* - * Experimental passwd map: - * replaces the uid with the matching gecos from /etc/passwd file - */ - if ( strncasecmp(s, "xpasswd", 7 ) == 0 ) { - map->lm_type = REWRITE_MAP_XPWDMAP; - map->lm_name = strdup( "xpasswd" ); - - assert( s[7] == '}' ); - *currpos = s + 8; - -#ifdef USE_REWRITE_LDAP_PVT_THREADS - if ( !xpasswd_mutex_init ) { - xpasswd_mutex_init = 1; - if ( ldap_pvt_thread_mutex_init( &xpasswd_mutex ) ) { - free( map ); - return NULL; - } - } -#endif /* USE_REWRITE_LDAP_PVT_THREADS */ - - /* Don't really care if fails */ - return map; - - /* - * Experimental file map: - * looks up key in a `key value' ascii file - */ - } else if ( strncasecmp(s, "xfile", 5 ) == 0 ) { - char *filename; - const char *p; - int l; - int c = 5; - - map->lm_type = REWRITE_MAP_XFILEMAP; - - if ( s[ c ] != '(' ) { - free( map ); - return NULL; - } - - /* Must start with '/' for security concerns */ - c++; - if ( s[ c ] != '/' ) { - free( map ); - return NULL; - } - - for ( p = s + c; p[ 0 ] != '\0' && p[ 0 ] != ')'; p++ ); - if ( p[ 0 ] != ')' ) { - free( map ); - return NULL; - } - - l = p - s - c; - filename = calloc( sizeof( char ), l + 1 ); - AC_MEMCPY( filename, s + c, l ); - filename[ l ] = '\0'; - - map->lm_args = ( void * )fopen( filename, "r" ); - free( filename ); - - if ( map->lm_args == NULL ) { - free( map ); - return NULL; - } - - *currpos = p + 1; - -#ifdef USE_REWRITE_LDAP_PVT_THREADS - if ( ldap_pvt_thread_mutex_init( &map->lm_mutex ) ) { - fclose( ( FILE * )map->lm_args ); - free( map ); - return NULL; - } -#endif /* USE_REWRITE_LDAP_PVT_THREADS */ - - return map; - - /* - * Experimental ldap map: - * looks up key on the fly (not implemented!) - */ - } else if ( strncasecmp(s, "xldap", 5 ) == 0 ) { - char *p; - char *url; - int l, rc; - int c = 5; - LDAPURLDesc *lud; - - if ( s[ c ] != '(' ) { - free( map ); - return NULL; - } - c++; - - p = strchr( s, '}' ); - if ( p == NULL ) { - free( map ); - return NULL; - } - p--; - - *currpos = p + 2; - - /* - * Add two bytes for urlencoding of '%s' - */ - l = p - s - c; - url = calloc( sizeof( char ), l + 3 ); - AC_MEMCPY( url, s + c, l ); - url[ l ] = '\0'; - - /* - * Urlencodes the '%s' for ldap_url_parse - */ - p = strchr( url, '%' ); - if ( p != NULL ) { - AC_MEMCPY( p + 3, p + 1, strlen( p + 1 ) + 1 ); - p[ 1 ] = '2'; - p[ 2 ] = '5'; - } - - rc = ldap_url_parse( url, &lud ); - free( url ); - - if ( rc != LDAP_SUCCESS ) { - free( map ); - return NULL; - } - assert( lud != NULL ); - - map->lm_args = ( void * )lud; - map->lm_type = REWRITE_MAP_XLDAPMAP; - -#ifdef USE_REWRITE_LDAP_PVT_THREADS - if ( ldap_pvt_thread_mutex_init( &map->lm_mutex ) ) { - ldap_free_urldesc( lud ); - free( map ); - return NULL; - } -#endif /* USE_REWRITE_LDAP_PVT_THREADS */ - - return map; - - /* Unhandled map */ - } - - return NULL; -} - struct rewrite_map * rewrite_map_parse( struct rewrite_info *info, @@ -233,7 +44,7 @@ rewrite_map_parse( struct rewrite_subst *subst = NULL; char *s, *begin = NULL, *end; const char *p; - int l, cnt; + int l, cnt, mtx = 0, rc = 0; assert( info != NULL ); assert( string != NULL ); @@ -259,8 +70,11 @@ rewrite_map_parse( cnt++; p++; } - if ( p[ 1 ] != '\0' ) + + if ( p[ 1 ] != '\0' ) { p++; + } + } else if ( p[ 0 ] == '}' ) { cnt--; } @@ -285,11 +99,12 @@ rewrite_map_parse( case REWRITE_OPERATOR_VARIABLE_GET: case REWRITE_OPERATOR_PARAM_GET: break; + default: begin = strchr( s, '(' ); if ( begin == NULL ) { - free( s ); - return NULL; + rc = -1; + goto cleanup; } begin[ 0 ] = '\0'; begin++; @@ -333,13 +148,13 @@ rewrite_map_parse( * Check the syntax of the variable name */ if ( !isalpha( (unsigned char) p[ 0 ] ) ) { - free( s ); - return NULL; + rc = -1; + goto cleanup; } for ( p++; p[ 0 ] != '\0'; p++ ) { if ( !isalnum( (unsigned char) p[ 0 ] ) ) { - free( s ); - return NULL; + rc = -1; + goto cleanup; } } @@ -350,11 +165,12 @@ rewrite_map_parse( case REWRITE_OPERATOR_VARIABLE_GET: case REWRITE_OPERATOR_PARAM_GET: break; + default: end = strrchr( begin, ')' ); if ( end == NULL ) { - free( s ); - return NULL; + rc = -1; + goto cleanup; } end[ 0 ] = '\0'; @@ -363,8 +179,8 @@ rewrite_map_parse( */ subst = rewrite_subst_compile( info, begin ); if ( subst == NULL ) { - free( s ); - return NULL; + rc = -1; + goto cleanup; } break; } @@ -374,22 +190,17 @@ rewrite_map_parse( */ map = calloc( sizeof( struct rewrite_map ), 1 ); if ( map == NULL ) { - if ( subst != NULL ) { - free( subst ); - } - free( s ); - return NULL; + rc = -1; + goto cleanup; } + memset( map, 0, sizeof( struct rewrite_map ) ); #ifdef USE_REWRITE_LDAP_PVT_THREADS if ( ldap_pvt_thread_mutex_init( &map->lm_mutex ) ) { - if ( subst != NULL ) { - free( subst ); - } - free( s ); - free( map ); - return NULL; + rc = -1; + goto cleanup; } + ++mtx; #endif /* USE_REWRITE_LDAP_PVT_THREADS */ /* @@ -399,6 +210,7 @@ rewrite_map_parse( case REWRITE_OPERATOR_VARIABLE_GET: case REWRITE_OPERATOR_PARAM_GET: break; + default: map->lm_subst = subst; break; @@ -422,19 +234,17 @@ rewrite_map_parse( map->lm_name = strdup( s + 1 ); map->lm_data = rewrite_context_find( info, s + 1 ); if ( map->lm_data == NULL ) { - free( s ); - free( map ); - return NULL; + rc = -1; + goto cleanup; } break; /* - * External command + * External command (not implemented yet) */ case REWRITE_OPERATOR_COMMAND: /* '|' */ - free( map ); - map = NULL; - break; + rc = -1; + goto cleanup; /* * Variable set @@ -488,226 +298,36 @@ rewrite_map_parse( map->lm_name = strdup( s ); map->lm_data = rewrite_builtin_map_find( info, s ); if ( map->lm_data == NULL ) { - return NULL; + rc = -1; + goto cleanup; } break; } - - free( s ); - return map; -} -/* - * Map key -> value resolution - * NOTE: these are old-fashion maps; new maps will be parsed on separate - * config lines, and referred by name. - */ -int -rewrite_xmap_apply( - struct rewrite_info *info, - struct rewrite_op *op, - struct rewrite_map *map, - struct berval *key, - struct berval *val -) -{ - int rc = REWRITE_SUCCESS; - - assert( info != NULL ); - assert( op != NULL ); - assert( map != NULL ); - assert( key != NULL ); - assert( val != NULL ); - - val->bv_val = NULL; - val->bv_len = 0; - - switch ( map->lm_type ) { -#ifdef HAVE_GETPWNAM - case REWRITE_MAP_XPWDMAP: { - struct passwd *pwd; - -#ifdef USE_REWRITE_LDAP_PVT_THREADS - ldap_pvt_thread_mutex_lock( &xpasswd_mutex ); -#endif /* USE_REWRITE_LDAP_PVT_THREADS */ - - pwd = getpwnam( key->bv_val ); - if ( pwd == NULL ) { - -#ifdef USE_REWRITE_LDAP_PVT_THREADS - ldap_pvt_thread_mutex_unlock( &xpasswd_mutex ); -#endif /* USE_REWRITE_LDAP_PVT_THREADS */ - - rc = REWRITE_NO_SUCH_OBJECT; - break; +cleanup: + free( s ); + if ( rc ) { + if ( subst != NULL ) { + free( subst ); } - -#ifdef HAVE_PW_GECOS - if ( pwd->pw_gecos != NULL && pwd->pw_gecos[0] != '\0' ) { - int l = strlen( pwd->pw_gecos ); - - val->bv_val = strdup( pwd->pw_gecos ); - if ( val->bv_val == NULL ) { - + if ( map ) { #ifdef USE_REWRITE_LDAP_PVT_THREADS - ldap_pvt_thread_mutex_unlock( &xpasswd_mutex ); -#endif /* USE_REWRITE_LDAP_PVT_THREADS */ - - rc = REWRITE_ERR; - break; + if ( mtx ) { + ldap_pvt_thread_mutex_destroy( &map->lm_mutex ); } - val->bv_len = l; - } else -#endif /* HAVE_PW_GECOS */ - { - val->bv_val = strdup( key->bv_val ); - val->bv_len = key->bv_len; - } - -#ifdef USE_REWRITE_LDAP_PVT_THREADS - ldap_pvt_thread_mutex_unlock( &xpasswd_mutex ); -#endif /* USE_REWRITE_LDAP_PVT_THREADS */ - - break; - } -#endif /* HAVE_GETPWNAM*/ - - case REWRITE_MAP_XFILEMAP: { - char buf[1024]; - - if ( map->lm_args == NULL ) { - rc = REWRITE_ERR; - break; - } - -#ifdef USE_REWRITE_LDAP_PVT_THREADS - ldap_pvt_thread_mutex_lock( &map->lm_mutex ); #endif /* USE_REWRITE_LDAP_PVT_THREADS */ - rewind( ( FILE * )map->lm_args ); - - while ( fgets( buf, sizeof( buf ), ( FILE * )map->lm_args ) ) { - char *p; - int blen; - - blen = strlen( buf ); - if ( buf[ blen - 1 ] == '\n' ) { - buf[ blen - 1 ] = '\0'; + if ( map->lm_name ) { + free( map->lm_name ); + map->lm_name = NULL; } - - p = strtok( buf, " " ); - if ( p == NULL ) { -#ifdef USE_REWRITE_LDAP_PVT_THREADS - ldap_pvt_thread_mutex_unlock( &map->lm_mutex ); -#endif /* USE_REWRITE_LDAP_PVT_THREADS */ - rc = REWRITE_ERR; - goto rc_return; - } - if ( strcasecmp( p, key->bv_val ) == 0 - && ( p = strtok( NULL, "" ) ) ) { - val->bv_val = strdup( p ); - if ( val->bv_val == NULL ) { - return REWRITE_ERR; - } - - val->bv_len = strlen( p ); - -#ifdef USE_REWRITE_LDAP_PVT_THREADS - ldap_pvt_thread_mutex_unlock( &map->lm_mutex ); -#endif /* USE_REWRITE_LDAP_PVT_THREADS */ - - goto rc_return; - } - } - -#ifdef USE_REWRITE_LDAP_PVT_THREADS - ldap_pvt_thread_mutex_unlock( &map->lm_mutex ); -#endif /* USE_REWRITE_LDAP_PVT_THREADS */ - - rc = REWRITE_ERR; - - break; - } - - case REWRITE_MAP_XLDAPMAP: { - LDAP *ld; - char filter[1024]; - LDAPMessage *res = NULL, *entry; - LDAPURLDesc *lud = ( LDAPURLDesc * )map->lm_args; - int attrsonly = 0; - char **values; - - assert( lud != NULL ); - - /* - * No mutex because there is no write on the map data - */ - - ld = ldap_init( lud->lud_host, lud->lud_port ); - if ( ld == NULL ) { - rc = REWRITE_ERR; - goto rc_return; - } - - snprintf( filter, sizeof( filter ), lud->lud_filter, - key->bv_val ); - - if ( strcasecmp( lud->lud_attrs[ 0 ], "dn" ) == 0 ) { - attrsonly = 1; - } - rc = ldap_search_s( ld, lud->lud_dn, lud->lud_scope, - filter, lud->lud_attrs, attrsonly, &res ); - if ( rc != LDAP_SUCCESS ) { - ldap_unbind( ld ); - rc = REWRITE_ERR; - goto rc_return; - } - - if ( ldap_count_entries( ld, res ) != 1 ) { - ldap_unbind( ld ); - rc = REWRITE_ERR; - goto rc_return; - } - - entry = ldap_first_entry( ld, res ); - if ( entry == NULL ) { - ldap_msgfree( res ); - ldap_unbind( ld ); - rc = REWRITE_ERR; - goto rc_return; - } - if ( attrsonly == 1 ) { - val->bv_val = ldap_get_dn( ld, entry ); - if ( val->bv_val == NULL ) { - ldap_msgfree( res ); - ldap_unbind( ld ); - rc = REWRITE_ERR; - goto rc_return; - } - } else { - values = ldap_get_values( ld, entry, - lud->lud_attrs[0] ); - if ( values == NULL ) { - ldap_msgfree( res ); - ldap_unbind( ld ); - rc = REWRITE_ERR; - goto rc_return; - } - val->bv_val = strdup( values[ 0 ] ); - ldap_value_free( values ); + free( map ); + map = NULL; } - val->bv_len = strlen( val->bv_val ); - - ldap_msgfree( res ); - ldap_unbind( ld ); - - rc = REWRITE_SUCCESS; - } } -rc_return:; - return rc; + return map; } /* @@ -796,6 +416,7 @@ rewrite_map_apply( case REWRITE_MAP_BUILTIN: { struct rewrite_builtin_map *bmap = map->lm_data; + switch ( bmap->lb_type ) { case REWRITE_BUILTIN_MAP_LDAP: rc = map_ldap_apply( bmap, key->bv_val, val ); @@ -815,3 +436,62 @@ rewrite_map_apply( return rc; } +void +rewrite_builtin_map_free( + void *tmp +) +{ + struct rewrite_builtin_map *map = ( struct rewrite_builtin_map * )tmp; + + assert( map ); + + switch ( map->lb_type ) { + case REWRITE_BUILTIN_MAP_LDAP: + map_ldap_destroy( &map ); + break; + + default: + assert(0); + break; + } + + free( map->lb_name ); + free( map ); +} + +int +rewrite_map_destroy( + struct rewrite_map **pmap +) +{ + struct rewrite_map *map; + + assert( pmap ); + assert( *pmap ); + + map = *pmap; + +#ifdef USE_REWRITE_LDAP_PVT_THREADS + ldap_pvt_thread_mutex_lock( &map->lm_mutex ); +#endif /* USE_REWRITE_LDAP_PVT_THREADS */ + + if ( map->lm_name ) { + free( map->lm_name ); + map->lm_name = NULL; + } + + if ( map->lm_subst ) { + rewrite_subst_destroy( &map->lm_subst ); + } + +#ifdef USE_REWRITE_LDAP_PVT_THREADS + ldap_pvt_thread_mutex_unlock( &map->lm_mutex ); + ldap_pvt_thread_mutex_destroy( &map->lm_mutex ); +#endif /* USE_REWRITE_LDAP_PVT_THREADS */ + + free( map ); + *pmap = NULL; + + return 0; +} + diff --git a/libraries/librewrite/params.c b/libraries/librewrite/params.c index 07daa0aabd..3f5488d69e 100644 --- a/libraries/librewrite/params.c +++ b/libraries/librewrite/params.c @@ -60,7 +60,7 @@ rewrite_param_set( #endif /* USE_REWRITE_LDAP_PVT_THREADS */ return REWRITE_ERR; } - } + } #ifdef USE_REWRITE_LDAP_PVT_THREADS ldap_pvt_thread_rdwr_wunlock( &info->li_params_mutex ); @@ -112,6 +112,22 @@ rewrite_param_get( return REWRITE_SUCCESS; } +static void +rewrite_param_free( + void *tmp +) +{ + struct rewrite_var *var = ( struct rewrite_var * )tmp; + assert( var != NULL ); + + assert( var->lv_name != NULL ); + assert( var->lv_value.bv_val != NULL ); + + free( var->lv_name ); + free( var->lv_value.bv_val ); + free( var ); +} + /* * Destroys the parameter tree */ @@ -128,7 +144,7 @@ rewrite_param_destroy( ldap_pvt_thread_rdwr_wlock( &info->li_params_mutex ); #endif /* USE_REWRITE_LDAP_PVT_THREADS */ - count = avl_free( info->li_params, NULL ); + count = avl_free( info->li_params, rewrite_param_free ); info->li_params = NULL; #ifdef USE_REWRITE_LDAP_PVT_THREADS diff --git a/libraries/librewrite/rewrite-int.h b/libraries/librewrite/rewrite-int.h index b8bc161a54..85358b72fc 100644 --- a/libraries/librewrite/rewrite-int.h +++ b/libraries/librewrite/rewrite-int.h @@ -189,10 +189,10 @@ struct rewrite_submatch { */ struct rewrite_subst { size_t lt_subs_len; - struct berval **lt_subs; + struct berval *lt_subs; int lt_num_submatch; - struct rewrite_submatch **lt_submatch; + struct rewrite_submatch *lt_submatch; }; /* @@ -262,7 +262,9 @@ struct rewrite_var { struct rewrite_op { int lo_num_passes; int lo_depth; +#if 0 /* FIXME: not used anywhere! (debug? then, why strdup?) */ char *lo_string; +#endif char *lo_result; Avlnode *lo_vars; const void *lo_cookie; @@ -315,7 +317,7 @@ struct rewrite_info { * PRIVATE * ***********/ -LDAP_REWRITE_V (struct rewrite_context*) __curr_context; +LDAP_REWRITE_V (struct rewrite_context*) rewrite_int_curr_context; /* * Maps @@ -359,7 +361,20 @@ rewrite_xmap_apply( struct berval *val ); +LDAP_REWRITE_F (int) +rewrite_map_destroy( + struct rewrite_map **map +); + +LDAP_REWRITE_F (int) +rewrite_xmap_destroy( + struct rewrite_map **map +); +LDAP_REWRITE_F (void) +rewrite_builtin_map_free( + void *map +); /* * Submatch substitution */ @@ -387,6 +402,11 @@ rewrite_subst_apply( struct berval *val ); +LDAP_REWRITE_F (int) +rewrite_subst_destroy( + struct rewrite_subst **subst +); + /* * Rules @@ -422,6 +442,11 @@ rewrite_rule_apply( char **result ); +LDAP_REWRITE_F (int) +rewrite_rule_destroy( + struct rewrite_rule **rule +); + /* * Sessions */ @@ -555,5 +580,15 @@ rewrite_context_apply( char **result ); +LDAP_REWRITE_F (int) +rewrite_context_destroy( + struct rewrite_context **context +); + +LDAP_REWRITE_F (void) +rewrite_context_free( + void *tmp +); + #endif /* REWRITE_INT_H */ diff --git a/libraries/librewrite/rewrite-map.h b/libraries/librewrite/rewrite-map.h index 918dc4b063..13283e4bed 100644 --- a/libraries/librewrite/rewrite-map.h +++ b/libraries/librewrite/rewrite-map.h @@ -53,4 +53,7 @@ map_ldap_apply( struct rewrite_builtin_map *map, struct berval *val ); +LDAP_REWRITE_F (int) +map_ldap_destroy( struct rewrite_builtin_map **map ); + #endif /* MAP_H */ diff --git a/libraries/librewrite/rewrite.c b/libraries/librewrite/rewrite.c index ac301b7a51..f02f6983cf 100644 --- a/libraries/librewrite/rewrite.c +++ b/libraries/librewrite/rewrite.c @@ -52,7 +52,7 @@ apply( int rc; void *cookie = &info; - info = rewrite_info_init(REWRITE_MODE_ERR); + info = rewrite_info_init( REWRITE_MODE_ERR ); if ( rewrite_read( fin, info ) != 0 ) { exit( EXIT_FAILURE ); @@ -84,8 +84,12 @@ apply( string = result; } + free( string ); + rewrite_session_delete( info, cookie ); + rewrite_info_delete( &info ); + return result; } @@ -128,7 +132,7 @@ main( int argc, char *argv[] ) exit( EXIT_SUCCESS ); case 'r': - rewriteContext = strdup( optarg ); + rewriteContext = optarg; break; } } @@ -139,6 +143,10 @@ main( int argc, char *argv[] ) apply( ( fin ? fin : stdin ), rewriteContext, argv[ optind ] ); + if ( fin ) { + fclose( fin ); + } + return 0; } diff --git a/libraries/librewrite/rule.c b/libraries/librewrite/rule.c index c8a1c07a14..c025000183 100644 --- a/libraries/librewrite/rule.c +++ b/libraries/librewrite/rule.c @@ -70,6 +70,39 @@ append_action( return REWRITE_SUCCESS; } +static int +destroy_action( + struct rewrite_action **paction +) +{ + struct rewrite_action *action; + + assert( paction ); + assert( *paction ); + + action = *paction; + + /* do something */ + switch ( action->la_type ) { + case REWRITE_FLAG_GOTO: { + int *pi = (int *)action->la_args; + + if ( pi ) { + free( pi ); + } + break; + } + + default: + break; + } + + free( action ); + *paction = NULL; + + return 0; +} + /* * In case of error it returns NULL and does not free all the memory * it allocated; as this is a once only phase, and an error at this stage @@ -336,7 +369,8 @@ rewrite_rule_apply( int rc = REWRITE_SUCCESS; char *string; - struct berval val; + int strcnt = 0; + struct berval val = { 0, NULL }; assert( info != NULL ); assert( op != NULL ); @@ -346,10 +380,7 @@ rewrite_rule_apply( *result = NULL; - string = strdup( arg ); - if ( string == NULL ) { - return REWRITE_REGEXEC_ERR; - } + string = (char *)arg; /* * In case recursive match is required (default) @@ -357,13 +388,14 @@ rewrite_rule_apply( recurse:; Debug( LDAP_DEBUG_TRACE, "==> rewrite_rule_apply" - " rule='%s' string='%s'\n%s", - rule->lr_pattern, string, "" ); + " rule='%s' string='%s'\n", + rule->lr_pattern, string, 0 ); op->lo_num_passes++; if ( regexec( &rule->lr_regex, string, nmatch, match, 0 ) != 0 ) { - if ( *result == NULL ) { + if ( *result == NULL && strcnt > 0 ) { free( string ); + string = NULL; } /* @@ -376,7 +408,11 @@ recurse:; match, &val ); *result = val.bv_val; - free( string ); + val.bv_val = NULL; + if ( strcnt > 0 ) { + free( string ); + string = NULL; + } if ( rc != REWRITE_REGEXEC_OK ) { return rc; @@ -385,9 +421,58 @@ recurse:; if ( ( rule->lr_mode & REWRITE_RECURSE ) == REWRITE_RECURSE && op->lo_num_passes <= info->li_max_passes ) { string = *result; + strcnt++; + goto recurse; } return REWRITE_REGEXEC_OK; } +int +rewrite_rule_destroy( + struct rewrite_rule **prule + ) +{ + struct rewrite_rule *rule; + struct rewrite_action *action; + + assert( prule ); + assert( *prule ); + + rule = *prule; + + if ( rule->lr_pattern ) { + free( rule->lr_pattern ); + rule->lr_pattern = NULL; + } + + if ( rule->lr_subststring ) { + free( rule->lr_subststring ); + rule->lr_subststring = NULL; + } + + if ( rule->lr_flagstring ) { + free( rule->lr_flagstring ); + rule->lr_flagstring = NULL; + } + + if ( rule->lr_subst ) { + rewrite_subst_destroy( &rule->lr_subst ); + } + + regfree( &rule->lr_regex ); + + for ( action = rule->lr_action; action; ) { + struct rewrite_action *curraction = action; + + action = action->la_next; + destroy_action( &curraction ); + } + + free( rule ); + *prule = NULL; + + return 0; +} + diff --git a/libraries/librewrite/session.c b/libraries/librewrite/session.c index 3366559a3d..20ab8fdde8 100644 --- a/libraries/librewrite/session.c +++ b/libraries/librewrite/session.c @@ -317,23 +317,27 @@ rewrite_session_delete( session = rewrite_session_find( info, cookie ); - if ( session != NULL ) { - if ( --session->ls_count > 0 ) { - rewrite_session_return( info, session ); - return REWRITE_SUCCESS; - } + if ( session == NULL ) { + return REWRITE_SUCCESS; + } + + if ( --session->ls_count > 0 ) { + rewrite_session_return( info, session ); + return REWRITE_SUCCESS; + } #ifdef USE_REWRITE_LDAP_PVT_THREADS - ldap_pvt_thread_rdwr_wlock( &session->ls_vars_mutex ); + ldap_pvt_thread_rdwr_wlock( &session->ls_vars_mutex ); #endif /* USE_REWRITE_LDAP_PVT_THREADS */ - rewrite_var_delete( session->ls_vars ); + rewrite_var_delete( session->ls_vars ); #ifdef USE_REWRITE_LDAP_PVT_THREADS - ldap_pvt_thread_rdwr_destroy( &session->ls_vars_mutex ); - ldap_pvt_thread_mutex_destroy( &session->ls_mutex ); + ldap_pvt_thread_rdwr_wunlock( &session->ls_vars_mutex ); + ldap_pvt_thread_rdwr_destroy( &session->ls_vars_mutex ); + ldap_pvt_thread_mutex_unlock( &session->ls_mutex ); + ldap_pvt_thread_mutex_destroy( &session->ls_mutex ); #endif /* USE_REWRITE_LDAP_PVT_THREADS */ - } #ifdef USE_REWRITE_LDAP_PVT_THREADS ldap_pvt_thread_rdwr_wlock( &info->li_cookies_mutex ); diff --git a/libraries/librewrite/subst.c b/libraries/librewrite/subst.c index a6d9fdbabf..9c7421aedb 100644 --- a/libraries/librewrite/subst.c +++ b/libraries/librewrite/subst.c @@ -36,8 +36,8 @@ rewrite_subst_compile( ) { size_t subs_len; - struct berval **subs = NULL, **tmps; - struct rewrite_submatch **submatch = NULL; + struct berval *subs = NULL, *tmps; + struct rewrite_submatch *submatch = NULL; struct rewrite_subst *s = NULL; @@ -51,28 +51,27 @@ rewrite_subst_compile( * Take care of substitution string */ for ( p = begin = result, subs_len = 0; p[ 0 ] != '\0'; p++ ) { - + /* * Keep only single escapes '%' */ if ( p[ 0 ] != REWRITE_SUBMATCH_ESCAPE ) { continue; } + if ( p[ 1 ] == REWRITE_SUBMATCH_ESCAPE ) { - AC_MEMCPY((char *)p, p + 1, strlen( p ) ); + /* Pull &p[1] over p, including the trailing '\0' */ + AC_MEMCPY((char *)p, &p[ 1 ], strlen( p ) ); continue; } - nsub++; - - tmps = (struct berval **)realloc( subs, - sizeof( struct berval * )*( nsub + 1 ) ); + tmps = ( struct berval * )realloc( subs, + sizeof( struct berval )*( nsub + 1 ) ); if ( tmps == NULL ) { - /* cleanup */ + /* FIXME: cleanup */ return NULL; } subs = tmps; - subs[ nsub ] = NULL; /* * I think an `if l > 0' at runtime is better outside than @@ -81,62 +80,52 @@ rewrite_subst_compile( l = p - begin; if ( l > 0 ) { subs_len += l; - subs[ nsub - 1 ] = - calloc( sizeof( struct berval ), 1 ); - if ( subs[ nsub - 1 ] == NULL ) { - /* cleanup */ - return NULL; - } - subs[ nsub - 1 ]->bv_len = l; - subs[ nsub - 1 ]->bv_val = malloc( l + 1 ); - if ( subs[ nsub - 1 ]->bv_val == NULL ) { + subs[ nsub ].bv_len = l; + subs[ nsub ].bv_val = malloc( l + 1 ); + if ( subs[ nsub ].bv_val == NULL ) { return NULL; } - AC_MEMCPY( subs[ nsub - 1 ]->bv_val, begin, l ); - subs[ nsub - 1 ]->bv_val[ l ] = '\0'; + AC_MEMCPY( subs[ nsub ].bv_val, begin, l ); + subs[ nsub ].bv_val[ l ] = '\0'; } else { - subs[ nsub - 1 ] = NULL; + subs[ nsub ].bv_val = NULL; + subs[ nsub ].bv_len = 0; } /* * Substitution pattern */ if ( isdigit( (unsigned char) p[ 1 ] ) ) { + struct rewrite_submatch *tmpsm; int d = p[ 1 ] - '0'; - struct rewrite_submatch **tmpsm; /* * Add a new value substitution scheme */ - tmpsm = realloc( submatch, - sizeof( struct rewrite_submatch * )*( nsub + 1 ) ); + + tmpsm = ( struct rewrite_submatch * )realloc( submatch, + sizeof( struct rewrite_submatch )*( nsub + 1 ) ); if ( tmpsm == NULL ) { /* cleanup */ return NULL; } submatch = tmpsm; - submatch[ nsub ] = NULL; - - submatch[ nsub - 1 ] = - calloc( sizeof( struct rewrite_submatch ), 1 ); - if ( submatch[ nsub - 1 ] == NULL ) { - /* cleanup */ - return NULL; - } - submatch[ nsub - 1 ]->ls_submatch = d; + submatch[ nsub ].ls_submatch = d; /* * If there is no argument, use default * (substitute substring as is) */ if ( p[ 2 ] != '{' ) { - submatch[ nsub - 1 ]->ls_type = + submatch[ nsub ].ls_type = REWRITE_SUBMATCH_ASIS; + submatch[ nsub ].ls_map = NULL; begin = ++p + 1; + } else { struct rewrite_map *map; - submatch[ nsub - 1 ]->ls_type = + submatch[ nsub ].ls_type = REWRITE_SUBMATCH_XMAP; map = rewrite_xmap_parse( info, @@ -145,9 +134,8 @@ rewrite_subst_compile( /* cleanup */ return NULL; } + submatch[ nsub ].ls_map = map; p = begin - 1; - - submatch[ nsub - 1 ]->ls_map = map; } /* @@ -155,7 +143,7 @@ rewrite_subst_compile( */ } else if ( p[ 1 ] == '{' ) { struct rewrite_map *map; - struct rewrite_submatch **tmpsm; + struct rewrite_submatch *tmpsm; map = rewrite_map_parse( info, p + 2, &begin ); if ( map == NULL ) { @@ -167,52 +155,43 @@ rewrite_subst_compile( /* * Add a new value substitution scheme */ - tmpsm = realloc( submatch, - sizeof( struct rewrite_submatch * )*( nsub + 1 ) ); + tmpsm = ( struct rewrite_submatch * )realloc( submatch, + sizeof( struct rewrite_submatch )*( nsub + 1 ) ); if ( tmpsm == NULL ) { /* cleanup */ return NULL; } submatch = tmpsm; - submatch[ nsub ] = NULL; - submatch[ nsub - 1 ] = - calloc( sizeof( struct rewrite_submatch ), 1 ); - if ( submatch[ nsub - 1 ] == NULL ) { - /* cleanup */ - return NULL; - } - - submatch[ nsub - 1 ]->ls_type = + submatch[ nsub ].ls_type = REWRITE_SUBMATCH_MAP_W_ARG; - - submatch[ nsub - 1 ]->ls_map = map; + submatch[ nsub ].ls_map = map; } + + nsub++; } /* * Last part of string */ - tmps = realloc( subs, sizeof( struct berval *)*( nsub + 2 ) ); + tmps = (struct berval * )realloc( subs, sizeof( struct berval )*( nsub + 1 ) ); if ( tmps == NULL ) { /* * XXX need to free the value subst stuff! */ - free( submatch ); + free( subs ); return NULL; } - subs = tmps; - subs[ nsub + 1 ] = NULL; l = p - begin; if ( l > 0 ) { - subs[ nsub ] = calloc( sizeof( struct berval ), 1 ); subs_len += l; - subs[ nsub ]->bv_len = l; - subs[ nsub ]->bv_val = malloc( l + 1 ); - AC_MEMCPY( subs[ nsub ]->bv_val, begin, l ); - subs[ nsub ]->bv_val[ l ] = '\0'; + subs[ nsub ].bv_len = l; + subs[ nsub ].bv_val = malloc( l + 1 ); + AC_MEMCPY( subs[ nsub ].bv_val, begin, l ); + subs[ nsub ].bv_val[ l ] = '\0'; } else { - subs[ nsub ] = NULL; + subs[ nsub ].bv_val = NULL; + subs[ nsub ].bv_len = 0; } s = calloc( sizeof( struct rewrite_subst ), 1 ); @@ -241,8 +220,8 @@ submatch_copy( struct berval *val ) { - int c, l; - const char *s; + int c, l; + const char *s; assert( submatch != NULL ); assert( submatch->ls_type == REWRITE_SUBMATCH_ASIS @@ -250,14 +229,14 @@ submatch_copy( assert( string != NULL ); assert( match != NULL ); assert( val != NULL ); + assert( val->bv_val == NULL ); c = submatch->ls_submatch; s = string + match[ c ].rm_so; l = match[ c ].rm_eo - match[ c ].rm_so; - val->bv_val = NULL; val->bv_len = l; - val->bv_val = calloc( sizeof( char ), l + 1 ); + val->bv_val = malloc( l + 1 ); if ( val->bv_val == NULL ) { return REWRITE_ERR; } @@ -284,7 +263,7 @@ rewrite_subst_apply( { struct berval *submatch = NULL; char *res = NULL; - int n, l, cl; + int n = 0, l, cl; int rc = REWRITE_REGEXEC_OK; assert( info != NULL ); @@ -294,6 +273,8 @@ rewrite_subst_apply( assert( match != NULL ); assert( val != NULL ); + assert( val->bv_val == NULL ); + val->bv_val = NULL; val->bv_len = 0; @@ -312,58 +293,59 @@ rewrite_subst_apply( * Resolve submatches (simple subst, map expansion and so). */ for ( n = 0, l = 0; n < subst->lt_num_submatch; n++ ) { - struct berval key; - int rc; + struct berval key = { 0, NULL }; + + submatch[ n ].bv_val = NULL; /* * Get key */ - switch( subst->lt_submatch[ n ]->ls_type ) { + switch ( subst->lt_submatch[ n ].ls_type ) { case REWRITE_SUBMATCH_ASIS: case REWRITE_SUBMATCH_XMAP: - rc = submatch_copy( subst->lt_submatch[ n ], + rc = submatch_copy( &subst->lt_submatch[ n ], string, match, &key ); if ( rc != REWRITE_SUCCESS ) { - free( submatch ); - return REWRITE_REGEXEC_ERR; + rc = REWRITE_REGEXEC_ERR; + goto cleanup; } break; case REWRITE_SUBMATCH_MAP_W_ARG: - switch ( subst->lt_submatch[ n ]->ls_map->lm_type ) { + switch ( subst->lt_submatch[ n ].ls_map->lm_type ) { case REWRITE_MAP_GET_OP_VAR: case REWRITE_MAP_GET_SESN_VAR: case REWRITE_MAP_GET_PARAM: rc = REWRITE_SUCCESS; break; + default: rc = rewrite_subst_apply( info, op, - subst->lt_submatch[ n ]->ls_map->lm_subst, + subst->lt_submatch[ n ].ls_map->lm_subst, string, match, &key); } if ( rc != REWRITE_SUCCESS ) { - free( submatch ); - return REWRITE_REGEXEC_ERR; + rc = REWRITE_REGEXEC_ERR; + goto cleanup; } break; default: - Debug( LDAP_DEBUG_ANY, "Not Implemented\n%s%s%s", - "", "", "" ); + Debug( LDAP_DEBUG_ANY, "Not Implemented\n", 0, 0, 0 ); rc = REWRITE_ERR; break; } if ( rc != REWRITE_SUCCESS ) { - free( submatch ); - return REWRITE_REGEXEC_ERR; + rc = REWRITE_REGEXEC_ERR; + goto cleanup; } /* * Resolve key */ - switch ( subst->lt_submatch[ n ]->ls_type ) { + switch ( subst->lt_submatch[ n ].ls_type ) { case REWRITE_SUBMATCH_ASIS: submatch[ n ] = key; rc = REWRITE_SUCCESS; @@ -371,16 +353,20 @@ rewrite_subst_apply( case REWRITE_SUBMATCH_XMAP: rc = rewrite_xmap_apply( info, op, - subst->lt_submatch[ n ]->ls_map, + subst->lt_submatch[ n ].ls_map, &key, &submatch[ n ] ); + free( key.bv_val ); + key.bv_val = NULL; break; case REWRITE_SUBMATCH_MAP_W_ARG: rc = rewrite_map_apply( info, op, - subst->lt_submatch[ n ]->ls_map, + subst->lt_submatch[ n ].ls_map, &key, &submatch[ n ] ); + free( key.bv_val ); + key.bv_val = NULL; break; - + default: /* * When implemented, this might return the @@ -393,8 +379,7 @@ rewrite_subst_apply( } if ( rc != REWRITE_SUCCESS ) { - free( submatch ); - return REWRITE_REGEXEC_ERR; + rc = REWRITE_REGEXEC_ERR; } /* @@ -408,7 +393,7 @@ rewrite_subst_apply( * of the subst pattern and initialize it */ l += subst->lt_subs_len; - res = calloc( sizeof( char ), l + 1 ); + res = malloc( l + 1 ); if ( res == NULL ) { rc = REWRITE_REGEXEC_ERR; goto cleanup; @@ -418,29 +403,92 @@ rewrite_subst_apply( * Apply submatches (possibly resolved thru maps */ for ( n = 0, cl = 0; n < subst->lt_num_submatch; n++ ) { - if ( subst->lt_subs[ n ] != NULL ) { - AC_MEMCPY( res + cl, subst->lt_subs[ n ]->bv_val, - subst->lt_subs[ n ]->bv_len ); - cl += subst->lt_subs[ n ]->bv_len; + if ( subst->lt_subs[ n ].bv_val != NULL ) { + AC_MEMCPY( res + cl, subst->lt_subs[ n ].bv_val, + subst->lt_subs[ n ].bv_len ); + cl += subst->lt_subs[ n ].bv_len; } AC_MEMCPY( res + cl, submatch[ n ].bv_val, submatch[ n ].bv_len ); cl += submatch[ n ].bv_len; - free( submatch[ n ].bv_val ); } - if ( subst->lt_subs[ n ] != NULL ) { - AC_MEMCPY( res + cl, subst->lt_subs[ n ]->bv_val, - subst->lt_subs[ n ]->bv_len ); + if ( subst->lt_subs[ n ].bv_val != NULL ) { + AC_MEMCPY( res + cl, subst->lt_subs[ n ].bv_val, + subst->lt_subs[ n ].bv_len ); + cl += subst->lt_subs[ n ].bv_len; } + res[ cl ] = '\0'; val->bv_val = res; val->bv_len = l; cleanup:; if ( submatch ) { + for ( ; --n >= 0; ) { + if ( submatch[ n ].bv_val ) { + free( submatch[ n ].bv_val ); + } + } free( submatch ); } return rc; } +/* + * frees data + */ +int +rewrite_subst_destroy( + struct rewrite_subst **psubst +) +{ + int n; + struct rewrite_subst *subst; + + assert( psubst ); + assert( *psubst ); + + subst = *psubst; + + for ( n = 0; n < subst->lt_num_submatch; n++ ) { + if ( subst->lt_subs[ n ].bv_val ) { + free( subst->lt_subs[ n ].bv_val ); + subst->lt_subs[ n ].bv_val = NULL; + } + + switch ( subst->lt_submatch[ n ].ls_type ) { + case REWRITE_SUBMATCH_ASIS: + break; + + case REWRITE_SUBMATCH_XMAP: + rewrite_xmap_destroy( &subst->lt_submatch[ n ].ls_map ); + break; + + case REWRITE_SUBMATCH_MAP_W_ARG: + rewrite_map_destroy( &subst->lt_submatch[ n ].ls_map ); + break; + + default: + break; + } + } + + free( subst->lt_submatch ); + subst->lt_submatch = NULL; + + /* last one */ + if ( subst->lt_subs[ n ].bv_val ) { + free( subst->lt_subs[ n ].bv_val ); + subst->lt_subs[ n ].bv_val = NULL; + } + + free( subst->lt_subs ); + subst->lt_subs = NULL; + + free( subst ); + *psubst = NULL; + + return 0; +} + diff --git a/libraries/librewrite/var.c b/libraries/librewrite/var.c index 941e54b426..aa39261ce5 100644 --- a/libraries/librewrite/var.c +++ b/libraries/librewrite/var.c @@ -109,25 +109,31 @@ rewrite_var_insert( if ( var == NULL ) { return NULL; } - var->lv_name = ( char * )strdup( name ); + memset( var, 0, sizeof( struct rewrite_var ) ); + var->lv_name = strdup( name ); if ( var->lv_name == NULL ) { - free( var ); - return NULL; + rc = -1; + goto cleanup; } var->lv_value.bv_val = strdup( value ); if ( var->lv_value.bv_val == NULL ) { - free( var ); - free( var->lv_name ); - return NULL; + rc = -1; + goto cleanup; } var->lv_value.bv_len = strlen( value ); rc = avl_insert( tree, ( caddr_t )var, rewrite_var_cmp, rewrite_var_dup ); if ( rc != 0 ) { - free( var ); + rc = -1; + goto cleanup; + } + +cleanup:; + if ( rc != 0 ) { free( var->lv_name ); free( var->lv_value.bv_val ); - return NULL; + free( var ); + var = NULL; } return var; @@ -184,6 +190,7 @@ rewrite_var_free( free( var->lv_name ); free( var->lv_value.bv_val ); + free( var ); } /* diff --git a/libraries/librewrite/xmap.c b/libraries/librewrite/xmap.c new file mode 100644 index 0000000000..3ec9873b2d --- /dev/null +++ b/libraries/librewrite/xmap.c @@ -0,0 +1,503 @@ +/****************************************************************************** + * + * Copyright (C) 2000 Pierangelo Masarati, + * All rights reserved. + * + * Permission is granted to anyone to use this software for any purpose + * on any computer system, and to alter it and redistribute it, subject + * to the following restrictions: + * + * 1. The author is not responsible for the consequences of use of this + * software, no matter how awful, even if they arise from flaws in it. + * + * 2. The origin of this software must not be misrepresented, either by + * explicit claim or by omission. Since few users ever read sources, + * credits should appear in the documentation. + * + * 3. Altered versions must be plainly marked as such, and must not be + * misrepresented as being the original software. Since few users + * ever read sources, credits should appear in the documentation. + * + * 4. This notice may not be removed or altered. + * + ******************************************************************************/ + +#include + +#include + +#ifdef HAVE_PWD_H +#include +#endif + +#include "rewrite-int.h" +#include "rewrite-map.h" + +/* + * Global data + */ +#ifdef USE_REWRITE_LDAP_PVT_THREADS +ldap_pvt_thread_mutex_t xpasswd_mutex; +static int xpasswd_mutex_init = 0; +#endif /* USE_REWRITE_LDAP_PVT_THREADS */ + +/* + * Map parsing + * NOTE: these are old-fashion maps; new maps will be parsed on separate + * config lines, and referred by name. + */ +struct rewrite_map * +rewrite_xmap_parse( + struct rewrite_info *info, + const char *s, + const char **currpos +) +{ + struct rewrite_map *map; + + assert( info != NULL ); + assert( s != NULL ); + assert( currpos != NULL ); + + Debug( LDAP_DEBUG_ARGS, "rewrite_xmap_parse: %s\n%s%s", + s, "", "" ); + + *currpos = NULL; + + map = calloc( sizeof( struct rewrite_map ), 1 ); + if ( map == NULL ) { + Debug( LDAP_DEBUG_ANY, "rewrite_xmap_parse:" + " calloc failed\n%s%s%s", "", "", "" ); + return NULL; + } + + /* + * Experimental passwd map: + * replaces the uid with the matching gecos from /etc/passwd file + */ + if ( strncasecmp(s, "xpasswd", 7 ) == 0 ) { + map->lm_type = REWRITE_MAP_XPWDMAP; + map->lm_name = strdup( "xpasswd" ); + + assert( s[7] == '}' ); + *currpos = s + 8; + +#ifdef USE_REWRITE_LDAP_PVT_THREADS + if ( !xpasswd_mutex_init ) { + if ( ldap_pvt_thread_mutex_init( &xpasswd_mutex ) ) { + free( map ); + return NULL; + } + } + ++xpasswd_mutex_init; +#endif /* USE_REWRITE_LDAP_PVT_THREADS */ + + /* Don't really care if fails */ + return map; + + /* + * Experimental file map: + * looks up key in a `key value' ascii file + */ + } else if ( strncasecmp(s, "xfile", 5 ) == 0 ) { + char *filename; + const char *p; + int l; + int c = 5; + + map->lm_type = REWRITE_MAP_XFILEMAP; + + if ( s[ c ] != '(' ) { + free( map ); + return NULL; + } + + /* Must start with '/' for security concerns */ + c++; + if ( s[ c ] != '/' ) { + free( map ); + return NULL; + } + + for ( p = s + c; p[ 0 ] != '\0' && p[ 0 ] != ')'; p++ ); + if ( p[ 0 ] != ')' ) { + free( map ); + return NULL; + } + + l = p - s - c; + filename = calloc( sizeof( char ), l + 1 ); + AC_MEMCPY( filename, s + c, l ); + filename[ l ] = '\0'; + + map->lm_args = ( void * )fopen( filename, "r" ); + free( filename ); + + if ( map->lm_args == NULL ) { + free( map ); + return NULL; + } + + *currpos = p + 1; + +#ifdef USE_REWRITE_LDAP_PVT_THREADS + if ( ldap_pvt_thread_mutex_init( &map->lm_mutex ) ) { + fclose( ( FILE * )map->lm_args ); + free( map ); + return NULL; + } +#endif /* USE_REWRITE_LDAP_PVT_THREADS */ + + return map; + + /* + * Experimental ldap map: + * looks up key on the fly (not implemented!) + */ + } else if ( strncasecmp(s, "xldap", 5 ) == 0 ) { + char *p; + char *url; + int l, rc; + int c = 5; + LDAPURLDesc *lud; + + if ( s[ c ] != '(' ) { + free( map ); + return NULL; + } + c++; + + p = strchr( s, '}' ); + if ( p == NULL ) { + free( map ); + return NULL; + } + p--; + + *currpos = p + 2; + + /* + * Add two bytes for urlencoding of '%s' + */ + l = p - s - c; + url = calloc( sizeof( char ), l + 3 ); + AC_MEMCPY( url, s + c, l ); + url[ l ] = '\0'; + + /* + * Urlencodes the '%s' for ldap_url_parse + */ + p = strchr( url, '%' ); + if ( p != NULL ) { + AC_MEMCPY( p + 3, p + 1, strlen( p + 1 ) + 1 ); + p[ 1 ] = '2'; + p[ 2 ] = '5'; + } + + rc = ldap_url_parse( url, &lud ); + free( url ); + + if ( rc != LDAP_SUCCESS ) { + free( map ); + return NULL; + } + assert( lud != NULL ); + + map->lm_args = ( void * )lud; + map->lm_type = REWRITE_MAP_XLDAPMAP; + +#ifdef USE_REWRITE_LDAP_PVT_THREADS + if ( ldap_pvt_thread_mutex_init( &map->lm_mutex ) ) { + ldap_free_urldesc( lud ); + free( map ); + return NULL; + } +#endif /* USE_REWRITE_LDAP_PVT_THREADS */ + + return map; + + /* Unhandled map */ + } + + return NULL; +} + +/* + * Map key -> value resolution + * NOTE: these are old-fashion maps; new maps will be parsed on separate + * config lines, and referred by name. + */ +int +rewrite_xmap_apply( + struct rewrite_info *info, + struct rewrite_op *op, + struct rewrite_map *map, + struct berval *key, + struct berval *val +) +{ + int rc = REWRITE_SUCCESS; + + assert( info != NULL ); + assert( op != NULL ); + assert( map != NULL ); + assert( key != NULL ); + assert( val != NULL ); + + val->bv_val = NULL; + val->bv_len = 0; + + switch ( map->lm_type ) { +#ifdef HAVE_GETPWNAM + case REWRITE_MAP_XPWDMAP: { + struct passwd *pwd; + +#ifdef USE_REWRITE_LDAP_PVT_THREADS + ldap_pvt_thread_mutex_lock( &xpasswd_mutex ); +#endif /* USE_REWRITE_LDAP_PVT_THREADS */ + + pwd = getpwnam( key->bv_val ); + if ( pwd == NULL ) { + +#ifdef USE_REWRITE_LDAP_PVT_THREADS + ldap_pvt_thread_mutex_unlock( &xpasswd_mutex ); +#endif /* USE_REWRITE_LDAP_PVT_THREADS */ + + rc = REWRITE_NO_SUCH_OBJECT; + break; + } + +#ifdef HAVE_PW_GECOS + if ( pwd->pw_gecos != NULL && pwd->pw_gecos[0] != '\0' ) { + int l = strlen( pwd->pw_gecos ); + + val->bv_val = strdup( pwd->pw_gecos ); + if ( val->bv_val == NULL ) { + +#ifdef USE_REWRITE_LDAP_PVT_THREADS + ldap_pvt_thread_mutex_unlock( &xpasswd_mutex ); +#endif /* USE_REWRITE_LDAP_PVT_THREADS */ + + rc = REWRITE_ERR; + break; + } + val->bv_len = l; + } else +#endif /* HAVE_PW_GECOS */ + { + val->bv_val = strdup( key->bv_val ); + val->bv_len = key->bv_len; + } + +#ifdef USE_REWRITE_LDAP_PVT_THREADS + ldap_pvt_thread_mutex_unlock( &xpasswd_mutex ); +#endif /* USE_REWRITE_LDAP_PVT_THREADS */ + + break; + } +#endif /* HAVE_GETPWNAM*/ + + case REWRITE_MAP_XFILEMAP: { + char buf[1024]; + + if ( map->lm_args == NULL ) { + rc = REWRITE_ERR; + break; + } + +#ifdef USE_REWRITE_LDAP_PVT_THREADS + ldap_pvt_thread_mutex_lock( &map->lm_mutex ); +#endif /* USE_REWRITE_LDAP_PVT_THREADS */ + + rewind( ( FILE * )map->lm_args ); + + while ( fgets( buf, sizeof( buf ), ( FILE * )map->lm_args ) ) { + char *p; + int blen; + + blen = strlen( buf ); + if ( buf[ blen - 1 ] == '\n' ) { + buf[ blen - 1 ] = '\0'; + } + + p = strtok( buf, " " ); + if ( p == NULL ) { +#ifdef USE_REWRITE_LDAP_PVT_THREADS + ldap_pvt_thread_mutex_unlock( &map->lm_mutex ); +#endif /* USE_REWRITE_LDAP_PVT_THREADS */ + rc = REWRITE_ERR; + goto rc_return; + } + if ( strcasecmp( p, key->bv_val ) == 0 + && ( p = strtok( NULL, "" ) ) ) { + val->bv_val = strdup( p ); + if ( val->bv_val == NULL ) { + return REWRITE_ERR; + } + + val->bv_len = strlen( p ); + +#ifdef USE_REWRITE_LDAP_PVT_THREADS + ldap_pvt_thread_mutex_unlock( &map->lm_mutex ); +#endif /* USE_REWRITE_LDAP_PVT_THREADS */ + + goto rc_return; + } + } + +#ifdef USE_REWRITE_LDAP_PVT_THREADS + ldap_pvt_thread_mutex_unlock( &map->lm_mutex ); +#endif /* USE_REWRITE_LDAP_PVT_THREADS */ + + rc = REWRITE_ERR; + + break; + } + + case REWRITE_MAP_XLDAPMAP: { + LDAP *ld; + char filter[1024]; + LDAPMessage *res = NULL, *entry; + LDAPURLDesc *lud = ( LDAPURLDesc * )map->lm_args; + int attrsonly = 0; + char **values; + + assert( lud != NULL ); + + /* + * No mutex because there is no write on the map data + */ + + ld = ldap_init( lud->lud_host, lud->lud_port ); + if ( ld == NULL ) { + rc = REWRITE_ERR; + goto rc_return; + } + + snprintf( filter, sizeof( filter ), lud->lud_filter, + key->bv_val ); + + if ( strcasecmp( lud->lud_attrs[ 0 ], "dn" ) == 0 ) { + attrsonly = 1; + } + rc = ldap_search_s( ld, lud->lud_dn, lud->lud_scope, + filter, lud->lud_attrs, attrsonly, &res ); + if ( rc != LDAP_SUCCESS ) { + ldap_unbind( ld ); + rc = REWRITE_ERR; + goto rc_return; + } + + if ( ldap_count_entries( ld, res ) != 1 ) { + ldap_unbind( ld ); + rc = REWRITE_ERR; + goto rc_return; + } + + entry = ldap_first_entry( ld, res ); + if ( entry == NULL ) { + ldap_msgfree( res ); + ldap_unbind( ld ); + rc = REWRITE_ERR; + goto rc_return; + } + if ( attrsonly == 1 ) { + val->bv_val = ldap_get_dn( ld, entry ); + if ( val->bv_val == NULL ) { + ldap_msgfree( res ); + ldap_unbind( ld ); + rc = REWRITE_ERR; + goto rc_return; + } + } else { + values = ldap_get_values( ld, entry, + lud->lud_attrs[0] ); + if ( values == NULL ) { + ldap_msgfree( res ); + ldap_unbind( ld ); + rc = REWRITE_ERR; + goto rc_return; + } + val->bv_val = strdup( values[ 0 ] ); + ldap_value_free( values ); + } + val->bv_len = strlen( val->bv_val ); + + ldap_msgfree( res ); + ldap_unbind( ld ); + + rc = REWRITE_SUCCESS; + } + } + +rc_return:; + return rc; +} + +int +rewrite_xmap_destroy( + struct rewrite_map **pmap +) +{ + struct rewrite_map *map; + + assert( pmap ); + assert( *pmap ); + + map = *pmap; + + switch ( map->lm_type ) { + case REWRITE_MAP_XPWDMAP: +#ifdef USE_REWRITE_LDAP_PVT_THREADS + --xpasswd_mutex_init; + if ( !xpasswd_mutex_init ) { + ldap_pvt_thread_mutex_destroy( &xpasswd_mutex ); + } +#endif /* USE_REWRITE_LDAP_PVT_THREADS */ + + break; + + case REWRITE_MAP_XFILEMAP: +#ifdef USE_REWRITE_LDAP_PVT_THREADS + ldap_pvt_thread_mutex_lock( &map->lm_mutex ); +#endif /* USE_REWRITE_LDAP_PVT_THREADS */ + + if ( map->lm_args ) { + fclose( ( FILE * )map->lm_args ); + map->lm_args = NULL; + } + +#ifdef USE_REWRITE_LDAP_PVT_THREADS + ldap_pvt_thread_mutex_unlock( &map->lm_mutex ); + ldap_pvt_thread_mutex_destroy( &map->lm_mutex ); +#endif /* USE_REWRITE_LDAP_PVT_THREADS */ + break; + + case REWRITE_MAP_XLDAPMAP: +#ifdef USE_REWRITE_LDAP_PVT_THREADS + ldap_pvt_thread_mutex_lock( &map->lm_mutex ); +#endif /* USE_REWRITE_LDAP_PVT_THREADS */ + + if ( map->lm_args ) { + ldap_free_urldesc( ( LDAPURLDesc * )map->lm_args ); + map->lm_args = NULL; + } + +#ifdef USE_REWRITE_LDAP_PVT_THREADS + ldap_pvt_thread_mutex_unlock( &map->lm_mutex ); + ldap_pvt_thread_mutex_destroy( &map->lm_mutex ); +#endif /* USE_REWRITE_LDAP_PVT_THREADS */ + break; + + default: + break; + + } + + free( map->lm_name ); + free( map ); + *pmap = NULL; + + return 0; +} + diff --git a/servers/slapd/Makefile.in b/servers/slapd/Makefile.in index b5b76a2ef1..2ece47608f 100644 --- a/servers/slapd/Makefile.in +++ b/servers/slapd/Makefile.in @@ -23,7 +23,7 @@ SRCS = main.c globals.c config.c daemon.c \ oidm.c starttls.c index.c sets.c referral.c root_dse.c \ sasl.c module.c mra.c mods.c sl_malloc.c limits.c \ backglue.c operational.c matchedValues.c cancel.c syncrepl.c \ - backover.c ctxcsn.c $(@PLAT@_SRCS) + backover.c ctxcsn.c ldapsync.c sessionlog.c $(@PLAT@_SRCS) OBJS = main.o globals.o config.o daemon.o \ connection.o search.o filter.o add.o cr.o \ @@ -37,7 +37,7 @@ OBJS = main.o globals.o config.o daemon.o \ oidm.o starttls.o index.o sets.o referral.o root_dse.o \ sasl.o module.o mra.o mods.o sl_malloc.o limits.o \ backglue.o operational.o matchedValues.o cancel.o syncrepl.o \ - backover.o ctxcsn.o $(@PLAT@_OBJS) + backover.o ctxcsn.o ldapsync.o sessionlog.o $(@PLAT@_OBJS) LDAP_INCDIR= ../../include -I$(srcdir)/slapi LDAP_LIBDIR= ../../libraries diff --git a/servers/slapd/acl.c b/servers/slapd/acl.c index 17f4459e00..7673e27d12 100644 --- a/servers/slapd/acl.c +++ b/servers/slapd/acl.c @@ -178,8 +178,8 @@ access_allowed( } #ifdef LDAP_SLAPI - ret = slapi_x_access_allowed( op, e, desc, val, access, state ); - if ( ret == 0 ) { + if ( op->o_pb && + !slapi_x_access_allowed( op, e, desc, val, access, state )) { /* ACL plugin denied access */ goto done; } diff --git a/servers/slapd/aclparse.c b/servers/slapd/aclparse.c index d642c305f6..7a5d9fddf6 100644 --- a/servers/slapd/aclparse.c +++ b/servers/slapd/aclparse.c @@ -1565,7 +1565,7 @@ print_access( Access *b ) fprintf( stderr, " %s", b->a_dn_pat.bv_val ); } else { - fprintf( stderr, " dn.%s=%s", + fprintf( stderr, " dn.%s=\"%s\"", style_strings[b->a_dn_style], b->a_dn_pat.bv_val ); } } @@ -1575,25 +1575,19 @@ print_access( Access *b ) } if ( b->a_group_pat.bv_len ) { - fprintf( stderr, " group=%s", b->a_group_pat.bv_val ); - - if ( b->a_group_oc ) { - fprintf( stderr, " objectClass: %s", - b->a_group_oc->soc_oclass.oc_oid ); - - if ( b->a_group_at ) { - fprintf( stderr, " attributeType: %s", - b->a_group_at->ad_cname.bv_val ); - } - } + fprintf( stderr, " group/%s/%s.%s=\"%s\"", + b->a_group_oc ? b->a_group_oc->soc_cname.bv_val : "groupOfNames", + b->a_group_at ? b->a_group_at->ad_cname.bv_val : "member", + style_strings[b->a_group_style], + b->a_group_pat.bv_val ); } if ( b->a_peername_pat.bv_len != 0 ) { - fprintf( stderr, " peername=%s", b->a_peername_pat.bv_val ); + fprintf( stderr, " peername=\"%s\"", b->a_peername_pat.bv_val ); } if ( b->a_sockname_pat.bv_len != 0 ) { - fprintf( stderr, " sockname=%s", b->a_sockname_pat.bv_val ); + fprintf( stderr, " sockname=\"%s\"", b->a_sockname_pat.bv_val ); } if ( b->a_domain_pat.bv_len != 0 ) { @@ -1601,7 +1595,7 @@ print_access( Access *b ) } if ( b->a_sockurl_pat.bv_len != 0 ) { - fprintf( stderr, " sockurl=%s", b->a_sockurl_pat.bv_val ); + fprintf( stderr, " sockurl=\"%s\"", b->a_sockurl_pat.bv_val ); } #ifdef SLAPD_ACI_ENABLED @@ -1657,7 +1651,7 @@ print_acl( Backend *be, AccessControl *a ) if ( a->acl_dn_pat.bv_len != 0 ) { to++; - fprintf( stderr, " dn.%s=%s\n", + fprintf( stderr, " dn.%s=\"%s\"\n", style_strings[a->acl_dn_style], a->acl_dn_pat.bv_val ); } @@ -1687,7 +1681,7 @@ print_acl( Backend *be, AccessControl *a ) if ( a->acl_attrval.bv_len != 0 ) { to++; - fprintf( stderr, " val.%s=%s\n", + fprintf( stderr, " val.%s=\"%s\"\n", style_strings[a->acl_attrval_style], a->acl_attrval.bv_val ); } diff --git a/servers/slapd/add.c b/servers/slapd/add.c index dd8dcb7ac5..323fd00bdc 100644 --- a/servers/slapd/add.c +++ b/servers/slapd/add.c @@ -231,7 +231,7 @@ do_add( Operation *op, SlapReply *rs ) } #ifdef LDAP_SLAPI - initAddPlugin( op, &dn, e, manageDSAit ); + if ( op->o_pb ) initAddPlugin( op, &dn, e, manageDSAit ); #endif /* LDAP_SLAPI */ /* @@ -244,10 +244,10 @@ do_add( Operation *op, SlapReply *rs ) /* do the update here */ int repl_user = be_isupdate(op->o_bd, &op->o_ndn ); #ifndef SLAPD_MULTIMASTER - if ( !op->o_bd->syncinfo && - ( !op->o_bd->be_update_ndn.bv_len || repl_user )) + if ( !op->o_bd->be_syncinfo && + ( !op->o_bd->be_update_ndn.bv_len || repl_user )) #else - if ( !op->o_bd->syncinfo ) + if ( !op->o_bd->be_syncinfo ) #endif { int update = op->o_bd->be_update_ndn.bv_len; @@ -290,10 +290,12 @@ do_add( Operation *op, SlapReply *rs ) * Call the preoperation plugin here, because the entry * will actually contain something. */ - rs->sr_err = doPreAddPluginFNs( op ); - if ( rs->sr_err != LDAP_SUCCESS ) { - /* plugin will have sent result */ - goto done; + if ( op->o_pb ) { + rs->sr_err = doPreAddPluginFNs( op ); + if ( rs->sr_err != LDAP_SUCCESS ) { + /* plugin will have sent result */ + goto done; + } } #endif /* LDAP_SLAPI */ @@ -317,18 +319,20 @@ do_add( Operation *op, SlapReply *rs ) * SLAPI_ADD_ENTRY will be empty, but this may be acceptable * on replicas (for now, it involves the minimum code intrusion). */ - rs->sr_err = doPreAddPluginFNs( op ); - if ( rs->sr_err != LDAP_SUCCESS ) { - /* plugin will have sent result */ - goto done; + if ( op->o_pb ) { + rs->sr_err = doPreAddPluginFNs( op ); + if ( rs->sr_err != LDAP_SUCCESS ) { + /* plugin will have sent result */ + goto done; + } } #endif /* LDAP_SLAPI */ - if ( op->o_bd->syncinfo ) { - defref = op->o_bd->syncinfo->provideruri_bv; + if ( op->o_bd->be_syncinfo ) { + defref = op->o_bd->be_syncinfo->si_provideruri_bv; } else { defref = op->o_bd->be_update_refs - ? op->o_bd->be_update_refs : default_referral; + ? op->o_bd->be_update_refs : default_referral; } if ( defref != NULL ) { @@ -349,10 +353,12 @@ do_add( Operation *op, SlapReply *rs ) } } else { #ifdef LDAP_SLAPI - rs->sr_err = doPreAddPluginFNs( op ); - if ( rs->sr_err != LDAP_SUCCESS ) { - /* plugin will have sent result */ - goto done; + if ( op->o_pb ) { + rs->sr_err = doPreAddPluginFNs( op ); + if ( rs->sr_err != LDAP_SUCCESS ) { + /* plugin will have sent result */ + goto done; + } } #endif #ifdef NEW_LOGGING @@ -366,7 +372,7 @@ do_add( Operation *op, SlapReply *rs ) } #ifdef LDAP_SLAPI - doPostAddPluginFNs( op ); + if ( op->o_pb ) doPostAddPluginFNs( op ); #endif /* LDAP_SLAPI */ done: diff --git a/servers/slapd/attr.c b/servers/slapd/attr.c index 4bb4e2a53a..a552ebad24 100644 --- a/servers/slapd/attr.c +++ b/servers/slapd/attr.c @@ -162,7 +162,9 @@ attr_merge_normalize( BerVarray nvals = NULL; int rc; - if ( desc->ad_type->sat_equality && desc->ad_type->sat_equality->smr_normalize ) { + if ( desc->ad_type->sat_equality && + desc->ad_type->sat_equality->smr_normalize ) + { int i; for ( i = 0; vals[i].bv_val; i++ ); @@ -170,7 +172,7 @@ attr_merge_normalize( nvals = sl_calloc( sizeof(struct berval), i + 1, memctx ); for ( i = 0; vals[i].bv_val; i++ ) { rc = (*desc->ad_type->sat_equality->smr_normalize)( - 0, + SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, desc->ad_type->sat_syntax, desc->ad_type->sat_equality, &vals[i], &nvals[i], memctx ); @@ -235,9 +237,11 @@ attr_merge_normalize_one( struct berval *nvalp; int rc; - if ( desc->ad_type->sat_equality && desc->ad_type->sat_equality->smr_normalize ) { + if ( desc->ad_type->sat_equality && + desc->ad_type->sat_equality->smr_normalize ) + { rc = (*desc->ad_type->sat_equality->smr_normalize)( - 0, + SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, desc->ad_type->sat_syntax, desc->ad_type->sat_equality, val, &nval, memctx ); diff --git a/servers/slapd/back-bdb/add.c b/servers/slapd/back-bdb/add.c index 7d5849e0cf..bb6e2aeb2e 100644 --- a/servers/slapd/back-bdb/add.c +++ b/servers/slapd/back-bdb/add.c @@ -436,7 +436,7 @@ retry: /* transaction retry */ goto return_results; } - if ( !op->o_bd->syncinfo ) { + if ( !op->o_bd->be_syncinfo ) { rc = bdb_csn_commit( op, rs, ltid, ei, &suffix_ei, &ctxcsn_e, &ctxcsn_added, locker ); switch ( rc ) { @@ -481,7 +481,7 @@ retry: /* transaction retry */ suffix_ei = op->oq_add.rs_e->e_private; } - if ( !op->o_bd->syncinfo ) { + if ( !op->o_bd->be_syncinfo ) { if ( ctxcsn_added ) { bdb_cache_add( bdb, suffix_ei, ctxcsn_e, (struct berval *)&slap_ldapsync_cn_bv, locker ); } @@ -528,7 +528,7 @@ retry: /* transaction retry */ return_results: send_ldap_result( op, rs ); - if ( rs->sr_err == LDAP_SUCCESS && !noop ) { + if ( rs->sr_err == LDAP_SUCCESS && !noop && !op->o_no_psearch ) { LDAP_LIST_FOREACH ( ps_list, &bdb->bi_psearch_list, o_ps_link ) { bdb_psearch( op, rs, ps_list, op->oq_add.rs_e, LDAP_PSEARCH_BY_ADD ); } diff --git a/servers/slapd/back-bdb/back-bdb.h b/servers/slapd/back-bdb/back-bdb.h index 1a249f41e6..76e130fb88 100644 --- a/servers/slapd/back-bdb/back-bdb.h +++ b/servers/slapd/back-bdb/back-bdb.h @@ -162,6 +162,8 @@ struct bdb_info { ID bi_lastid; ldap_pvt_thread_mutex_t bi_lastid_mutex; LDAP_LIST_HEAD(pl, slap_op) bi_psearch_list; + ldap_pvt_thread_mutex_t bi_pslist_mutex; + LDAP_LIST_HEAD(se, slap_session_entry) bi_session_list; #ifdef SLAP_IDL_CACHE int bi_idl_cache_max_size; int bi_idl_cache_size; diff --git a/servers/slapd/back-bdb/cache.c b/servers/slapd/back-bdb/cache.c index f18e21ce20..234f2cf85d 100644 --- a/servers/slapd/back-bdb/cache.c +++ b/servers/slapd/back-bdb/cache.c @@ -744,6 +744,8 @@ bdb_cache_add( if ( eip->bei_dkids ) eip->bei_dkids++; #endif rc = bdb_entryinfo_add_internal( bdb, &ei, &new ); + /* bdb_csn_commit can cause this when adding the database root entry */ + if ( new->bei_e ) bdb_entry_return( new->bei_e ); new->bei_e = e; e->e_private = new; new->bei_state = CACHE_ENTRY_NO_KIDS | CACHE_ENTRY_NO_GRANDKIDS; diff --git a/servers/slapd/back-bdb/config.c b/servers/slapd/back-bdb/config.c index d1bd93cd75..7fa83327ac 100644 --- a/servers/slapd/back-bdb/config.c +++ b/servers/slapd/back-bdb/config.c @@ -127,31 +127,31 @@ bdb_db_config( if( rc != LDAP_SUCCESS ) return 1; /* unique key for shared memory regions */ - } else if ( strcasecmp( argv[0], "shm_key" ) == 0 ) { - if ( argc < 2 ) { - fprintf( stderr, - "%s: line %d: missing key in \"shm_key \" line\n", - fname, lineno ); - return( 1 ); - } - bdb->bi_shm_key = atoi( argv[1] ); + } else if ( strcasecmp( argv[0], "shm_key" ) == 0 ) { + if ( argc < 2 ) { + fprintf( stderr, + "%s: line %d: missing key in \"shm_key \" line\n", + fname, lineno ); + return( 1 ); + } + bdb->bi_shm_key = atoi( argv[1] ); /* size of the cache in entries */ - } else if ( strcasecmp( argv[0], "cachesize" ) == 0 ) { - if ( argc < 2 ) { - fprintf( stderr, - "%s: line %d: missing size in \"cachesize \" line\n", - fname, lineno ); - return( 1 ); - } - bdb->bi_cache.c_maxsize = atoi( argv[1] ); + } else if ( strcasecmp( argv[0], "cachesize" ) == 0 ) { + if ( argc < 2 ) { + fprintf( stderr, + "%s: line %d: missing size in \"cachesize \" line\n", + fname, lineno ); + return( 1 ); + } + bdb->bi_cache.c_maxsize = atoi( argv[1] ); /* depth of search stack cache in units of (IDL)s */ - } else if ( strcasecmp( argv[0], "searchstack" ) == 0 ) { + } else if ( strcasecmp( argv[0], "searchstack" ) == 0 ) { if ( argc < 2 ) { fprintf( stderr, - "%s: line %d: missing depth in \"searchstack \" line\n", - fname, lineno ); + "%s: line %d: missing depth in \"searchstack \" line\n", + fname, lineno ); return( 1 ); } bdb->bi_search_stack_depth = atoi( argv[1] ); @@ -165,17 +165,82 @@ bdb_db_config( #ifdef SLAP_IDL_CACHE /* size of the IDL cache in entries */ - } else if ( strcasecmp( argv[0], "idlcachesize" ) == 0 ) { - if ( argc < 2 ) { - fprintf( stderr, - "%s: line %d: missing size in \"idlcachesize \" line\n", - fname, lineno ); - return( 1 ); - } - if ( !( slapMode & SLAP_TOOL_MODE ) ) - bdb->bi_idl_cache_max_size = atoi( argv[1] ); + } else if ( strcasecmp( argv[0], "idlcachesize" ) == 0 ) { + if ( argc < 2 ) { + fprintf( stderr, + "%s: line %d: missing size in \"idlcachesize \" line\n", + fname, lineno ); + return( 1 ); + } + if ( !( slapMode & SLAP_TOOL_MODE ) ) + bdb->bi_idl_cache_max_size = atoi( argv[1] ); #endif + } else if ( strcasecmp( argv[0], "sessionlog" ) == 0 ) { + int se_id = 0, se_size = 0; + struct slap_session_entry *sent; + if ( argc < 3 ) { +#ifdef NEW_LOGGING + LDAP_LOG( CONFIG, CRIT, + "%s: line %d: missing arguments in \"sessionlog \"" + " line.\n", fname, lineno , 0 ); +#else + Debug( LDAP_DEBUG_ANY, + "%s: line %d: missing arguments in \"sessionlog \"" + " line\n", fname, lineno, 0 ); +#endif + return( 1 ); + } + + se_id = atoi( argv[1] ); + se_size = atoi( argv[2] ); + + if ( se_id < 0 || se_id > 999 ) { +#ifdef NEW_LOGGING + LDAP_LOG( CONFIG, CRIT, + "%s: line %d: session log id %d is out of range [0..999]\n", + fname, lineno , se_id ); +#else + Debug( LDAP_DEBUG_ANY, + "%s: line %d: session log id %d is out of range [0..999]\n", + fname, lineno , se_id ); +#endif + return( 1 ); + } + + if ( se_size < 0 || se_size > 999 ) { +#ifdef NEW_LOGGING + LDAP_LOG( CONFIG, CRIT, + "%s: line %d: session log size %d is negative\n", + fname, lineno , se_size ); +#else + Debug( LDAP_DEBUG_ANY, + "%s: line %d: session log size %d is negative\n", + fname, lineno , se_size ); +#endif + return( 1 ); + } + + LDAP_LIST_FOREACH( sent, &bdb->bi_session_list, se_link ) { + if ( sent->se_id == se_id ) { +#ifdef NEW_LOGGING + LDAP_LOG( CONFIG, CRIT, + "%s: line %d: session %d already exists\n", + fname, lineno , se_id ); +#else + Debug( LDAP_DEBUG_ANY, + "%s: line %d: session %d already exists\n", + fname, lineno , se_id ); +#endif + return( 1 ); + } + } + sent = (struct slap_session_entry *) ch_calloc( 1, + sizeof( struct slap_session_entry )); + sent->se_id = se_id; + sent->se_size = se_size; + LDAP_LIST_INSERT_HEAD( &bdb->bi_session_list, sent, se_link ); + /* anything else */ } else { fprintf( stderr, "%s: line %d: " diff --git a/servers/slapd/back-bdb/ctxcsn.c b/servers/slapd/back-bdb/ctxcsn.c index 3f9dfc1f61..6d9af8c80b 100644 --- a/servers/slapd/back-bdb/ctxcsn.c +++ b/servers/slapd/back-bdb/ctxcsn.c @@ -262,16 +262,18 @@ bdb_get_commit_csn( int num_retries = 0; int ctxcsn_added = 0; int rc; + struct sync_cookie syncCookie = { NULL, -1, NULL}; if ( op->o_sync_mode != SLAP_SYNC_NONE ) { - if ( op->o_bd->syncinfo ) { + if ( op->o_bd->be_syncinfo ) { char substr[67]; struct berval bv; - sprintf( substr, "cn=syncrepl%d", op->o_bd->syncinfo->id ); + sprintf( substr, "cn=syncrepl%d", op->o_bd->be_syncinfo->si_id ); ber_str2bv( substr, 0, 0, &bv ); build_new_dn( &ctxcsn_ndn, &op->o_bd->be_nsuffix[0], &bv, NULL ); } else { - build_new_dn( &ctxcsn_ndn, &op->o_bd->be_nsuffix[0], (struct berval *)&slap_ldapsync_cn_bv, NULL ); + build_new_dn( &ctxcsn_ndn, &op->o_bd->be_nsuffix[0], + (struct berval *)&slap_ldapsync_cn_bv, NULL ); } ctxcsn_retry : @@ -292,9 +294,9 @@ ctxcsn_retry : case DB_LOCK_NOTGRANTED: goto ctxcsn_retry; case DB_NOTFOUND: - if ( !op->o_bd->syncinfo ) { + if ( !op->o_bd->be_syncinfo ) { snprintf( gid, sizeof( gid ), "%s-%08lx-%08lx", - bdb_uuid.bv_val, (long) op->o_connid, (long) op->o_opid ); + bdb_uuid.bv_val, (long) op->o_connid, (long) op->o_opid ); slap_get_csn( op, csnbuf, sizeof(csnbuf), &csn, 1 ); @@ -330,7 +332,8 @@ txn_retry: return rs->sr_err; } - bdb_cache_add( bdb, suffix_ei, ctxcsn_e, (struct berval *)&slap_ldapsync_cn_bv, locker ); + bdb_cache_add( bdb, suffix_ei, ctxcsn_e, + (struct berval *)&slap_ldapsync_cn_bv, locker ); rs->sr_err = TXN_COMMIT( ltid, 0 ); if ( rs->sr_err != 0 ) { @@ -358,15 +361,27 @@ txn_retry: } if ( ctxcsn_e ) { - if ( op->o_bd->syncinfo ) { - csn_a = attr_find( ctxcsn_e->e_attrs, slap_schema.si_ad_syncreplCookie ); - } else { - csn_a = attr_find( ctxcsn_e->e_attrs, slap_schema.si_ad_contextCSN ); - } - if ( csn_a ) { - *search_context_csn = ber_dupbv( NULL, &csn_a->a_vals[0] ); + if ( op->o_bd->be_syncinfo ) { + csn_a = attr_find( ctxcsn_e->e_attrs, + slap_schema.si_ad_syncreplCookie ); + if ( csn_a ) { + struct berval cookie; + ber_dupbv( &cookie, &csn_a->a_vals[0] ); + ber_bvarray_add( &syncCookie.octet_str, &cookie ); + slap_parse_sync_cookie( &syncCookie ); + *search_context_csn = ber_dupbv( NULL, syncCookie.ctxcsn ); + slap_sync_cookie_free( &syncCookie, 0 ); + } else { + *search_context_csn = NULL; + } } else { - *search_context_csn = NULL; + csn_a = attr_find( ctxcsn_e->e_attrs, + slap_schema.si_ad_contextCSN ); + if ( csn_a ) { + *search_context_csn = ber_dupbv( NULL, &csn_a->a_vals[0] ); + } else { + *search_context_csn = NULL; + } } } else { *search_context_csn = NULL; diff --git a/servers/slapd/back-bdb/delete.c b/servers/slapd/back-bdb/delete.c index 9acab3aa18..fa25873ac7 100644 --- a/servers/slapd/back-bdb/delete.c +++ b/servers/slapd/back-bdb/delete.c @@ -251,9 +251,10 @@ retry: /* transaction retry */ matched = NULL; } else { - BerVarray deref = op->o_bd->syncinfo ? - op->o_bd->syncinfo->provideruri_bv : default_referral; - rs->sr_ref = referral_rewrite( deref, NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT ); + BerVarray deref = op->o_bd->be_syncinfo ? + op->o_bd->be_syncinfo->si_provideruri_bv : default_referral; + rs->sr_ref = referral_rewrite( deref, NULL, &op->o_req_dn, + LDAP_SCOPE_DEFAULT ); } rs->sr_err = LDAP_REFERRAL; @@ -471,8 +472,9 @@ retry: /* transaction retry */ ldap_pvt_thread_mutex_unlock( &bdb->bi_lastid_mutex ); #endif - if ( !op->o_bd->syncinfo ) { - rc = bdb_csn_commit( op, rs, ltid, ei, &suffix_ei, &ctxcsn_e, &ctxcsn_added, locker ); + if ( !op->o_bd->be_syncinfo ) { + rc = bdb_csn_commit( op, rs, ltid, ei, &suffix_ei, + &ctxcsn_e, &ctxcsn_added, locker ); switch ( rc ) { case BDB_CSN_ABORT : goto return_results; @@ -492,9 +494,10 @@ retry: /* transaction retry */ bdb_cache_delete( &bdb->bi_cache, e, bdb->bi_dbenv, locker, &lock ); - if ( !op->o_bd->syncinfo ) { + if ( !op->o_bd->be_syncinfo ) { if ( ctxcsn_added ) { - bdb_cache_add( bdb, suffix_ei, ctxcsn_e, (struct berval *)&slap_ldapsync_cn_bv, locker ); + bdb_cache_add( bdb, suffix_ei, + ctxcsn_e, (struct berval *)&slap_ldapsync_cn_bv, locker ); } } @@ -537,7 +540,7 @@ retry: /* transaction retry */ return_results: send_ldap_result( op, rs ); - if ( rs->sr_err == LDAP_SUCCESS && !noop ) { + if ( rs->sr_err == LDAP_SUCCESS && !noop && !op->o_no_psearch ) { LDAP_LIST_FOREACH( ps_list, &bdb->bi_psearch_list, o_ps_link ) { bdb_psearch( op, rs, ps_list, e, LDAP_PSEARCH_BY_DELETE ); } diff --git a/servers/slapd/back-bdb/init.c b/servers/slapd/back-bdb/init.c index 77bb9e91cb..fe6bbdf270 100644 --- a/servers/slapd/back-bdb/init.c +++ b/servers/slapd/back-bdb/init.c @@ -554,12 +554,17 @@ bdb_db_destroy( BackendDB *be ) return 0; } -#ifdef SLAPD_BDB_DYNAMIC +#if (defined(SLAPD_BDB_DYNAMIC) && !defined(BDB_HIER)) || \ + (defined(SLAPD_HDB_DYNAMIC) && defined(BDB_HIER)) int init_module( int argc, char *argv[] ) { BackendInfo bi; memset( &bi, '\0', sizeof(bi) ); +#ifdef BDB_HIER + bi.bi_type = "hdb"; +#else bi.bi_type = "bdb"; +#endif bi.bi_init = bdb_initialize; backend_add( &bi ); diff --git a/servers/slapd/back-bdb/modify.c b/servers/slapd/back-bdb/modify.c index 71c80ec798..ba219deaa5 100644 --- a/servers/slapd/back-bdb/modify.c +++ b/servers/slapd/back-bdb/modify.c @@ -421,9 +421,10 @@ retry: /* transaction retry */ e = NULL; } else { - BerVarray deref = op->o_bd->syncinfo ? - op->o_bd->syncinfo->provideruri_bv : default_referral; - rs->sr_ref = referral_rewrite( deref, NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT ); + BerVarray deref = op->o_bd->be_syncinfo ? + op->o_bd->be_syncinfo->si_provideruri_bv : default_referral; + rs->sr_ref = referral_rewrite( deref, NULL, &op->o_req_dn, + LDAP_SCOPE_DEFAULT ); } rs->sr_err = LDAP_REFERRAL; @@ -466,7 +467,7 @@ retry: /* transaction retry */ goto return_results; } - if ( rs->sr_err == LDAP_SUCCESS && !op->o_noop ) { + if ( rs->sr_err == LDAP_SUCCESS && !op->o_noop && !op->o_no_psearch ) { LDAP_LIST_FOREACH ( ps_list, &bdb->bi_psearch_list, o_ps_link ) { bdb_psearch(op, rs, ps_list, e, LDAP_PSEARCH_BY_PREMODIFY ); } @@ -575,7 +576,7 @@ retry: /* transaction retry */ goto return_results; } - if ( !op->o_bd->syncinfo ) { + if ( !op->o_bd->be_syncinfo ) { rc = bdb_csn_commit( op, rs, ltid, ei, &suffix_ei, &ctxcsn_e, &ctxcsn_added, locker ); switch ( rc ) { @@ -598,9 +599,10 @@ retry: /* transaction retry */ bdb_cache_modify( e, dummy.e_attrs, bdb->bi_dbenv, locker, &lock ); - if ( !op->o_bd->syncinfo ) { + if ( !op->o_bd->be_syncinfo ) { if ( ctxcsn_added ) { - bdb_cache_add( bdb, suffix_ei, ctxcsn_e, (struct berval *)&slap_ldapsync_cn_bv, locker ); + bdb_cache_add( bdb, suffix_ei, ctxcsn_e, + (struct berval *)&slap_ldapsync_cn_bv, locker ); } } diff --git a/servers/slapd/back-bdb/modrdn.c b/servers/slapd/back-bdb/modrdn.c index ff4dab5a72..18f14807aa 100644 --- a/servers/slapd/back-bdb/modrdn.c +++ b/servers/slapd/back-bdb/modrdn.c @@ -173,9 +173,10 @@ retry: /* transaction retry */ e = NULL; } else { - BerVarray deref = op->o_bd->syncinfo ? - op->o_bd->syncinfo->provideruri_bv : default_referral; - rs->sr_ref = referral_rewrite( deref, NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT ); + BerVarray deref = op->o_bd->be_syncinfo ? + op->o_bd->be_syncinfo->si_provideruri_bv : default_referral; + rs->sr_ref = referral_rewrite( deref, NULL, &op->o_req_dn, + LDAP_SCOPE_DEFAULT ); } rs->sr_err = LDAP_REFERRAL; @@ -863,7 +864,7 @@ retry: /* transaction retry */ goto return_results; } - if ( rs->sr_err == LDAP_SUCCESS && !op->o_noop ) { + if ( rs->sr_err == LDAP_SUCCESS && !op->o_noop && !op->o_no_psearch ) { LDAP_LIST_FOREACH ( ps_list, &bdb->bi_psearch_list, o_ps_link ) { bdb_psearch( op, rs, ps_list, e, LDAP_PSEARCH_BY_PREMODIFY ); } @@ -939,8 +940,9 @@ retry: /* transaction retry */ goto return_results; } - if ( !op->o_bd->syncinfo ) { - rc = bdb_csn_commit( op, rs, ltid, ei, &suffix_ei, &ctxcsn_e, &ctxcsn_added, locker ); + if ( !op->o_bd->be_syncinfo ) { + rc = bdb_csn_commit( op, rs, ltid, ei, &suffix_ei, + &ctxcsn_e, &ctxcsn_added, locker ); switch ( rc ) { case BDB_CSN_ABORT : goto return_results; @@ -970,9 +972,10 @@ retry: /* transaction retry */ bdb_cache_modrdn( save, &op->orr_nnewrdn, e, neip, bdb->bi_dbenv, locker, &lock ); - if ( !op->o_bd->syncinfo ) { + if ( !op->o_bd->be_syncinfo ) { if ( ctxcsn_added ) { - bdb_cache_add( bdb, suffix_ei, ctxcsn_e, (struct berval *)&slap_ldapsync_cn_bv, locker ); + bdb_cache_add( bdb, suffix_ei, ctxcsn_e, + (struct berval *)&slap_ldapsync_cn_bv, locker ); } } diff --git a/servers/slapd/back-bdb/proto-bdb.h b/servers/slapd/back-bdb/proto-bdb.h index f9e14ee560..fb4ab4808d 100644 --- a/servers/slapd/back-bdb/proto-bdb.h +++ b/servers/slapd/back-bdb/proto-bdb.h @@ -548,37 +548,6 @@ int bdb_do_search( ); #define bdb_psearch(op, rs, sop, e, ps_type) bdb_do_search(op, rs, sop, e, ps_type) -#define bdb_build_sync_state_ctrl BDB_SYMBOL(build_sync_state_ctrl) -#define bdb_build_sync_done_ctrl BDB_SYMBOL(build_sync_done_ctrl) -#define bdb_send_ldap_intermediate BDB_SYMBOL(send_ldap_intermediate) - -int -bdb_build_sync_state_ctrl( - Operation *op, - SlapReply *rs, - Entry *e, - int entry_sync_state, - LDAPControl **ctrls, - int num_ctrls, - int send_cookie, - struct berval *csn ); - -int -bdb_build_sync_done_ctrl( - Operation *op, - SlapReply *rs, - LDAPControl **ctrls, - int num_ctrls, - int send_cookie, - struct berval *latest_entrycsn_bv ); - -int -bdb_send_ldap_intermediate( - Operation *op, - SlapReply *rs, - int state, - struct berval *cookie ); - /* * trans.c */ diff --git a/servers/slapd/back-bdb/search.c b/servers/slapd/back-bdb/search.c index 7e37aca405..f7eed19933 100644 --- a/servers/slapd/back-bdb/search.c +++ b/servers/slapd/back-bdb/search.c @@ -291,48 +291,62 @@ int is_sync_protocol( Operation *op ) ( type == LDAP_PSEARCH_BY_SCOPEOUT )) #define IS_PSEARCH (op != sop) -int -bdb_abandon( Operation *op, SlapReply *rs ) +static Operation * +bdb_drop_psearch( Operation *op, ber_int_t msgid ) { Operation *ps_list; struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; LDAP_LIST_FOREACH ( ps_list, &bdb->bi_psearch_list, o_ps_link ) { if ( ps_list->o_connid == op->o_connid ) { - if ( ps_list->o_msgid == op->oq_abandon.rs_msgid ) { + if ( ps_list->o_msgid == msgid ) { ps_list->o_abandon = 1; LDAP_LIST_REMOVE( ps_list, o_ps_link ); - slap_op_free ( ps_list ); - return LDAP_SUCCESS; + ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); + LDAP_STAILQ_REMOVE( &op->o_conn->c_ops, ps_list, + slap_op, o_next ); + LDAP_STAILQ_NEXT( ps_list, o_next ) = NULL; + op->o_conn->c_n_ops_executing--; + op->o_conn->c_n_ops_completed++; + ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); + return ps_list; } } } - return LDAP_UNAVAILABLE; + + return NULL; } int -bdb_cancel( Operation *op, SlapReply *rs ) +bdb_abandon( Operation *op, SlapReply *rs ) { - Operation *ps_list; - struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; - - LDAP_LIST_FOREACH ( ps_list, &bdb->bi_psearch_list, o_ps_link ) { - if ( ps_list->o_connid == op->o_connid ) { - if ( ps_list->o_msgid == op->oq_cancel.rs_msgid ) { - ps_list->o_cancel = SLAP_CANCEL_DONE; - LDAP_LIST_REMOVE( ps_list, o_ps_link ); - - rs->sr_err = LDAP_CANCELLED; - send_ldap_result( ps_list, rs ); + Operation *ps; - if ( ps_list->o_tmpmemctx ) { - sl_mem_destroy( NULL, ps_list->o_tmpmemctx ); - } + ps = bdb_drop_psearch( op, op->oq_abandon.rs_msgid ); + if ( ps ) { + if ( ps->o_tmpmemctx ) { + sl_mem_destroy( NULL, ps->o_tmpmemctx ); + } + slap_op_free ( ps ); + return LDAP_SUCCESS; + } + return LDAP_UNAVAILABLE; +} - slap_op_free ( ps_list ); - return LDAP_SUCCESS; - } +int +bdb_cancel( Operation *op, SlapReply *rs ) +{ + Operation *ps; + + ps = bdb_drop_psearch( op, op->oq_cancel.rs_msgid ); + if ( ps ) { + rs->sr_err = LDAP_CANCELLED; + send_ldap_result( ps, rs ); + if ( ps->o_tmpmemctx ) { + sl_mem_destroy( NULL, ps->o_tmpmemctx ); } + slap_op_free ( ps ); + return LDAP_SUCCESS; } return LDAP_UNAVAILABLE; } @@ -364,7 +378,6 @@ bdb_do_search( Operation *op, SlapReply *rs, Operation *sop, AttributeName *attrs; Filter contextcsnand, contextcsnle, cookief, csnfnot, csnfeq, csnfand, csnfge; - Filter omitcsnf, omitcsnfle; AttributeAssertion aa_ge, aa_eq, aa_le; int entry_count = 0; struct berval *search_context_csn = NULL; @@ -382,19 +395,81 @@ bdb_do_search( Operation *op, SlapReply *rs, Operation *sop, u_int32_t locker = 0; DB_LOCK lock; + Operation *ps_list; + int sync_send_present_mode = 1; + int match; + MatchingRule *mr; + const char *text; + int slog_found = 0; + + BerVarray syncUUID_set = NULL; + int syncUUID_set_cnt = 0; + #ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ENTRY, "bdb_back_search\n", 0, 0, 0 ); + LDAP_LOG( OPERATION, ENTRY, "bdb_search\n", 0, 0, 0 ); #else - Debug( LDAP_DEBUG_TRACE, "=> bdb_back_search\n", + Debug( LDAP_DEBUG_TRACE, "=> bdb_search\n", 0, 0, 0); #endif attrs = sop->oq_search.rs_attrs; + if ( !IS_PSEARCH && sop->o_sync_mode & SLAP_SYNC_REFRESH_AND_PERSIST ) { + struct slap_session_entry *sent; + if ( sop->o_sync_state.sid >= 0 ) { + LDAP_LIST_FOREACH( sent, &bdb->bi_session_list, se_link ) { + if ( sent->se_id == sop->o_sync_state.sid ) { + sop->o_sync_slog_size = sent->se_size; + break; + } + } + } + } + /* psearch needs to be registered before refresh begins */ /* psearch and refresh transmission is serialized in send_ldap_ber() */ if ( !IS_PSEARCH && sop->o_sync_mode & SLAP_SYNC_PERSIST ) { + ldap_pvt_thread_mutex_lock( &bdb->bi_pslist_mutex ); LDAP_LIST_INSERT_HEAD( &bdb->bi_psearch_list, sop, o_ps_link ); + ldap_pvt_thread_mutex_unlock( &bdb->bi_pslist_mutex ); + } else if ( !IS_PSEARCH && sop->o_sync_mode & SLAP_SYNC_REFRESH_AND_PERSIST + && sop->o_sync_slog_size >= 0 ) { + ldap_pvt_thread_mutex_lock( &bdb->bi_pslist_mutex ); + LDAP_LIST_FOREACH( ps_list, &bdb->bi_psearch_list, o_ps_link ) { + if ( ps_list->o_sync_slog_size >= 0 ) { + if ( ps_list->o_sync_state.sid == sop->o_sync_state.sid ) { + slog_found = 1; + break; + } + } + } + + if ( slog_found ) { + if ( ps_list->o_sync_slog_omitcsn.bv_len != 0 ) { + mr = slap_schema.si_ad_entryCSN->ad_type->sat_ordering; + if ( sop->o_sync_state.ctxcsn && + sop->o_sync_state.ctxcsn->bv_val != NULL ) { + value_match( &match, slap_schema.si_ad_entryCSN, mr, + SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, + sop->o_sync_state.ctxcsn, + &ps_list->o_sync_slog_omitcsn, + &text ); + } else { + match = -1; + } + if ( match >= 0 ) { + sync_send_present_mode = 0; + } + } else { + sync_send_present_mode = 0; + } + } else if ( sop->o_sync_slog_size >= 0 ) { + LDAP_LIST_INSERT_HEAD( &bdb->bi_psearch_list, sop, o_ps_link ); + } else { + sop->o_sync_state.sid = -1; + } + ldap_pvt_thread_mutex_unlock( &bdb->bi_pslist_mutex ); } + null_attr.an_desc = NULL; null_attr.an_oc = NULL; null_attr.an_name.bv_len = 0; @@ -656,6 +731,14 @@ dn2entry_retry: goto done; } + if ( sop->o_sync_mode != SLAP_SYNC_NONE && sop->o_sync_state.ctxcsn && + sop->o_sync_state.ctxcsn->bv_val && + ber_bvcmp( &sop->o_sync_state.ctxcsn[0], search_context_csn ) == 0 ) + { + bdb_cache_entry_db_unlock( bdb->bi_dbenv, &ctxcsn_lock ); + goto nochange; + } + /* select candidates */ if ( sop->oq_search.rs_scope == LDAP_SCOPE_BASE ) { rs->sr_err = base_candidate( op->o_bd, &base, candidates ); @@ -756,8 +839,6 @@ dn2entry_retry: if ( (sop->o_sync_mode & SLAP_SYNC_REFRESH) || IS_PSEARCH ) { - MatchingRule *mr; - const char *text; int match; cookief.f_choice = LDAP_FILTER_AND; @@ -771,7 +852,11 @@ dn2entry_retry: csnfeq.f_choice = LDAP_FILTER_EQUALITY; csnfeq.f_ava = &aa_eq; csnfeq.f_av_desc = slap_schema.si_ad_entryCSN; - csnfeq.f_av_value = sop->o_sync_state; + if ( sop->o_sync_state.ctxcsn != NULL ) { + csnfeq.f_av_value = *sop->o_sync_state.ctxcsn; + } else { + csnfeq.f_av_value = slap_empty_bv; + } csnfand.f_choice = LDAP_FILTER_AND; csnfand.f_and = &csnfge; @@ -780,7 +865,11 @@ dn2entry_retry: csnfge.f_choice = LDAP_FILTER_GE; csnfge.f_ava = &aa_ge; csnfge.f_av_desc = slap_schema.si_ad_entryCSN; - csnfge.f_av_value = sop->o_sync_state; + if ( sop->o_sync_state.ctxcsn != NULL ) { + csnfge.f_av_value = *sop->o_sync_state.ctxcsn; + } else { + csnfge.f_av_value = slap_empty_bv; + } if ( search_context_csn && !IS_PSEARCH ) { csnfge.f_next = &contextcsnand; @@ -796,21 +885,23 @@ dn2entry_retry: contextcsnle.f_next = sop->oq_search.rs_filter; mr = slap_schema.si_ad_entryCSN->ad_type->sat_ordering; - if ( sop->o_sync_state.bv_len != 0 ) { + if ( sop->o_sync_state.ctxcsn && + sop->o_sync_state.ctxcsn->bv_val != NULL ) { value_match( &match, slap_schema.si_ad_entryCSN, mr, - SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, - &sop->o_sync_state, search_context_csn, &text ); + SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, + &sop->o_sync_state.ctxcsn[0], search_context_csn, + &text ); } else { match = -1; } - no_sync_state_change = !match; + no_sync_state_change = ( match >= 0 ); } else { csnfge.f_next = sop->oq_search.rs_filter; } } for ( id = bdb_idl_first( candidates, &cursor ); - id != NOID; + id != NOID && !no_sync_state_change; id = bdb_idl_next( candidates, &cursor ) ) { int scopeok = 0; @@ -818,6 +909,9 @@ dn2entry_retry: loop_begin: /* check for abandon */ if ( sop->o_abandon ) { + if ( sop != op ) { + bdb_drop_psearch( sop, sop->o_msgid ); + } rs->sr_err = LDAP_SUCCESS; goto done; } @@ -1036,8 +1130,7 @@ id2entry_retry: } else { if ( sop->o_sync_mode & SLAP_SYNC_REFRESH ) { rc_sync = test_filter( sop, rs->sr_entry, &cookief ); - rs->sr_err = test_filter( sop, - rs->sr_entry, &contextcsnand ); + rs->sr_err = test_filter( sop, rs->sr_entry, &contextcsnand ); if ( rs->sr_err == LDAP_COMPARE_TRUE ) { if ( rc_sync == LDAP_COMPARE_TRUE ) { if ( no_sync_state_change ) { @@ -1067,7 +1160,8 @@ id2entry_retry: if ( rs->sr_err == LDAP_COMPARE_TRUE ) { /* check size limit */ - if ( --sop->oq_search.rs_slimit == -1 ) { + if ( --sop->oq_search.rs_slimit == -1 && + sop->o_sync_slog_size == -1 ) { if (!IS_PSEARCH) { bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache, e, &lock ); @@ -1133,53 +1227,100 @@ id2entry_retry: } else { entry_sync_state = LDAP_SYNC_ADD; } - } else if ( ps_type == LDAP_PSEARCH_BY_SCOPEOUT ) + } else if ( ps_type == LDAP_PSEARCH_BY_SCOPEOUT ) { entry_sync_state = LDAP_SYNC_DELETE; - else { + } else { rs->sr_err = LDAP_OTHER; goto done; } - rs->sr_err = bdb_build_sync_state_ctrl( sop, - rs, e, entry_sync_state, ctrls, - num_ctrls++, 1, search_context_csn ); - if ( rs->sr_err != LDAP_SUCCESS ) goto done; - rs->sr_attrs = attrs; - rs->sr_ctrls = ctrls; - result = send_search_entry( sop, rs ); - ch_free( ctrls[num_ctrls-1]->ldctl_value.bv_val ); - ch_free( ctrls[--num_ctrls] ); - ctrls[num_ctrls] = NULL; - rs->sr_ctrls = NULL; - + if ( sop->o_sync_slog_size != -1 ) { + if ( entry_sync_state == LDAP_SYNC_DELETE ) { + result = slap_add_session_log( op, sop, e ); + } else { + result = 1; + } + } else { + struct berval cookie; + slap_compose_sync_cookie( sop, &cookie, + search_context_csn, + sop->o_sync_state.sid ); + rs->sr_err = slap_build_sync_state_ctrl( sop, + rs, e, entry_sync_state, ctrls, + num_ctrls++, 1, &cookie ); + if ( rs->sr_err != LDAP_SUCCESS ) goto done; + rs->sr_attrs = attrs; + rs->sr_ctrls = ctrls; + result = send_search_entry( sop, rs ); + if ( cookie.bv_val ) + ch_free( cookie.bv_val ); + sl_free( ctrls[num_ctrls-1]->ldctl_value.bv_val, + sop->o_tmpmemctx ); + sl_free( ctrls[--num_ctrls], sop->o_tmpmemctx ); + ctrls[num_ctrls] = NULL; + rs->sr_ctrls = NULL; + } } else if ( ps_type == LDAP_PSEARCH_BY_PREMODIFY ) { struct psid_entry* psid_e; - psid_e = (struct psid_entry *) calloc (1, + psid_e = (struct psid_entry *) ch_calloc (1, sizeof(struct psid_entry)); psid_e->ps_op = sop; LDAP_LIST_INSERT_HEAD( &op->o_pm_list, psid_e, ps_link ); } else { - printf("Error !\n"); +#ifdef NEW_LOGGING + LDAP_LOG ( OPERATION, RESULTS, + "bdb_search: invalid ps_type (%d) \n", + ps_type, 0, 0); +#else + Debug( LDAP_DEBUG_TRACE, + "bdb_search: invalid ps_type (%d) \n", + ps_type, 0, 0); +#endif } } else { if ( sop->o_sync_mode & SLAP_SYNC_REFRESH ) { - rs->sr_err = bdb_build_sync_state_ctrl( sop, - rs, e, entry_sync_state, ctrls, - num_ctrls++, 0, search_context_csn ); - if ( rs->sr_err != LDAP_SUCCESS ) goto done; - rs->sr_ctrls = ctrls; if ( rc_sync == LDAP_COMPARE_TRUE ) { /* ADD */ + rs->sr_err = slap_build_sync_state_ctrl( sop, + rs, e, entry_sync_state, ctrls, + num_ctrls++, 0, NULL ); + if ( rs->sr_err != LDAP_SUCCESS ) goto done; + rs->sr_ctrls = ctrls; rs->sr_attrs = sop->oq_search.rs_attrs; + result = send_search_entry( sop, rs ); + sl_free( ctrls[num_ctrls-1]->ldctl_value.bv_val, + sop->o_tmpmemctx ); + sl_free( ctrls[--num_ctrls], sop->o_tmpmemctx ); + ctrls[num_ctrls] = NULL; + rs->sr_ctrls = NULL; } else { /* PRESENT */ - rs->sr_attrs = &null_attr; + if ( sync_send_present_mode ) { + result = slap_build_syncUUID_set( sop, + &syncUUID_set, e ); + if ( result <= 0 ) { + result = -1; + } else { + syncUUID_set_cnt++; + if ( syncUUID_set_cnt == SLAP_SYNCUUID_SET_SIZE ) { + rs->sr_err = LDAP_SUCCESS; + rs->sr_rspoid = LDAP_SYNC_INFO; + rs->sr_ctrls = NULL; + result = slap_send_syncinfo( sop, rs, + LDAP_TAG_SYNC_ID_SET, + NULL, 0, syncUUID_set, 0 ); + if ( result != LDAP_SUCCESS ) + result = -1; + ber_bvarray_free_x( syncUUID_set, + sop->o_tmpmemctx ); + syncUUID_set = NULL; + syncUUID_set_cnt = 0; + } + } + } else { + result = 1; + } } - result = send_search_entry( sop, rs ); - ch_free( ctrls[num_ctrls-1]->ldctl_value.bv_val ); - ch_free( ctrls[--num_ctrls] ); - ctrls[num_ctrls] = NULL; - rs->sr_ctrls = NULL; } else { rs->sr_attrs = sop->oq_search.rs_attrs; rs->sr_ctrls = NULL; @@ -1230,38 +1371,114 @@ loop_continue: ldap_pvt_thread_yield(); } + if ( syncUUID_set_cnt > 0 ) { + rs->sr_err = LDAP_SUCCESS; + rs->sr_rspoid = LDAP_SYNC_INFO; + rs->sr_ctrls = NULL; + slap_send_syncinfo( sop, rs, LDAP_TAG_SYNC_ID_SET, + NULL, 0, syncUUID_set, 0 ); + ber_bvarray_free_x( syncUUID_set, sop->o_tmpmemctx ); + syncUUID_set_cnt = 0; + } + +nochange: if (!IS_PSEARCH) { if ( sop->o_sync_mode & SLAP_SYNC_REFRESH ) { - rs->sr_err = LDAP_SUCCESS; - rs->sr_rspoid = LDAP_SYNC_INFO; - rs->sr_ctrls = NULL; - bdb_send_ldap_intermediate( sop, rs, - LDAP_SYNC_STATE_MODE_DONE, search_context_csn ); - - /* If changelog is supported, this is where to process it */ - if ( sop->o_sync_mode & SLAP_SYNC_PERSIST ) { - /* refreshAndPersist mode */ - bdb_send_ldap_intermediate( sop, rs, - LDAP_SYNC_LOG_MODE_DONE, search_context_csn ); + struct berval cookie; + slap_compose_sync_cookie( sop, &cookie, + search_context_csn, + sop->o_sync_state.sid ); + + if ( sync_send_present_mode ) { + rs->sr_err = LDAP_SUCCESS; + rs->sr_rspoid = LDAP_SYNC_INFO; + rs->sr_ctrls = NULL; + slap_send_syncinfo( sop, rs, + LDAP_TAG_SYNC_REFRESH_PRESENT, &cookie, 1, NULL, 0 ); + } else { + if ( !no_sync_state_change ) { + int slog_found = 0; + ldap_pvt_thread_mutex_lock( &bdb->bi_pslist_mutex ); + LDAP_LIST_FOREACH( ps_list, &bdb->bi_psearch_list, o_ps_link ) { + if ( ps_list->o_sync_slog_size > 0 ) { + if ( ps_list->o_sync_state.sid == sop->o_sync_state.sid ) { + slog_found = 1; + break; + } + } + } + + if ( slog_found ) { + rs->sr_err = LDAP_SUCCESS; + rs->sr_rspoid = NULL; + rs->sr_ctrls = NULL; + slap_send_session_log( op, ps_list, rs ); + } + ldap_pvt_thread_mutex_unlock( &bdb->bi_pslist_mutex ); + } + rs->sr_err = LDAP_SUCCESS; + rs->sr_rspoid = LDAP_SYNC_INFO; + rs->sr_ctrls = NULL; + slap_send_syncinfo( sop, rs, + LDAP_TAG_SYNC_REFRESH_DELETE, &cookie, 1, NULL, 0 ); + } + + if ( cookie.bv_val ) { + ch_free( cookie.bv_val ); + } } else { /* refreshOnly mode */ - bdb_build_sync_done_ctrl( sop, rs, ctrls, - num_ctrls++, 1, search_context_csn ); + struct berval cookie; + slap_compose_sync_cookie( sop, &cookie, + search_context_csn, + sop->o_sync_state.sid ); + + if ( sync_send_present_mode ) { + slap_build_sync_done_ctrl( sop, rs, ctrls, + num_ctrls++, 1, &cookie, LDAP_SYNC_REFRESH_PRESENTS ); + } else { + if ( !no_sync_state_change ) { + int slog_found = 0; + ldap_pvt_thread_mutex_lock( &bdb->bi_pslist_mutex ); + LDAP_LIST_FOREACH( ps_list, &bdb->bi_psearch_list, + o_ps_link ) { + if ( ps_list->o_sync_slog_size > 0 ) { + if ( ps_list->o_sync_state.sid == + sop->o_sync_state.sid ) { + slog_found = 1; + break; + } + } + } + + if ( slog_found ) { + slap_send_session_log( op, ps_list, rs ); + } + ldap_pvt_thread_mutex_unlock( &bdb->bi_pslist_mutex ); + } + slap_build_sync_done_ctrl( sop, rs, ctrls, + num_ctrls++, 1, &cookie, LDAP_SYNC_REFRESH_DELETES ); + } + rs->sr_ctrls = ctrls; rs->sr_ref = rs->sr_v2ref; rs->sr_err = (rs->sr_v2ref == NULL) ? LDAP_SUCCESS : LDAP_REFERRAL; + rs->sr_rspoid = NULL; send_ldap_result( sop, rs ); if ( ctrls[num_ctrls-1]->ldctl_value.bv_val != NULL ) { - ch_free( ctrls[num_ctrls-1]->ldctl_value.bv_val ); + sl_free( ctrls[num_ctrls-1]->ldctl_value.bv_val, sop->o_tmpmemctx ); } - ch_free( ctrls[--num_ctrls] ); + sl_free( ctrls[--num_ctrls], sop->o_tmpmemctx ); ctrls[num_ctrls] = NULL; + if ( cookie.bv_val ) + ch_free( cookie.bv_val ); } } else { rs->sr_ctrls = NULL; rs->sr_ref = rs->sr_v2ref; rs->sr_err = (rs->sr_v2ref == NULL) ? LDAP_SUCCESS : LDAP_REFERRAL; + rs->sr_rspoid = NULL; send_ldap_result( sop, rs ); } } @@ -1562,160 +1779,3 @@ done: (void) ber_free_buf( ber ); } #endif - -int -bdb_build_sync_state_ctrl( - Operation *op, - SlapReply *rs, - Entry *e, - int entry_sync_state, - LDAPControl **ctrls, - int num_ctrls, - int send_cookie, - struct berval *csn) -{ - Attribute* a; - int ret; - int res; - const char *text = NULL; - - BerElementBuffer berbuf; - BerElement *ber = (BerElement *)&berbuf; - - struct berval entryuuid_bv = { 0, NULL }; - - ber_init2( ber, 0, LBER_USE_DER ); - - ctrls[num_ctrls] = ch_malloc ( sizeof ( LDAPControl ) ); - - for ( a = e->e_attrs; a != NULL; a = a->a_next ) { - AttributeDescription *desc = a->a_desc; - if ( desc == slap_schema.si_ad_entryUUID ) { - ber_dupbv( &entryuuid_bv, &a->a_vals[0] ); - } - } - - if ( send_cookie && csn ) { - ber_printf( ber, "{eOON}", - entry_sync_state, &entryuuid_bv, csn ); - } else { - ber_printf( ber, "{eON}", - entry_sync_state, &entryuuid_bv ); - } - - ch_free( entryuuid_bv.bv_val ); - entryuuid_bv.bv_val = NULL; - - ctrls[num_ctrls]->ldctl_oid = LDAP_CONTROL_SYNC_STATE; - ctrls[num_ctrls]->ldctl_iscritical = op->o_sync; - ret = ber_flatten2( ber, &ctrls[num_ctrls]->ldctl_value, 1 ); - - ber_free_buf( ber ); - - if ( ret < 0 ) { -#ifdef NEW_LOGGING - LDAP_LOG ( OPERATION, RESULTS, - "bdb_build_sync_ctrl: ber_flatten2 failed\n", - 0, 0, 0 ); -#else - Debug( LDAP_DEBUG_TRACE, - "bdb_build_sync_ctrl: ber_flatten2 failed\n", - 0, 0, 0 ); -#endif - send_ldap_error( op, rs, LDAP_OTHER, "internal error" ); - return ret; - } - - return LDAP_SUCCESS; -} - -int -bdb_build_sync_done_ctrl( - Operation *op, - SlapReply *rs, - LDAPControl **ctrls, - int num_ctrls, - int send_cookie, - struct berval *csn ) -{ - int ret; - BerElementBuffer berbuf; - BerElement *ber = (BerElement *)&berbuf; - - ber_init2( ber, NULL, LBER_USE_DER ); - - ctrls[num_ctrls] = ch_malloc ( sizeof ( LDAPControl ) ); - - if ( send_cookie && csn ) { - ber_printf( ber, "{ON}", csn ); - } else { - ber_printf( ber, "{N}" ); - } - - ctrls[num_ctrls]->ldctl_oid = LDAP_CONTROL_SYNC_DONE; - ctrls[num_ctrls]->ldctl_iscritical = op->o_sync; - ret = ber_flatten2( ber, &ctrls[num_ctrls]->ldctl_value, 1 ); - - ber_free_buf( ber ); - - if ( ret < 0 ) { -#ifdef NEW_LOGGING - LDAP_LOG ( OPERATION, RESULTS, - "bdb_build_sync_done_ctrl: ber_flatten2 failed\n", - 0, 0, 0 ); -#else - Debug( LDAP_DEBUG_TRACE, - "bdb_build_sync_done_ctrl: ber_flatten2 failed\n", - 0, 0, 0 ); -#endif - send_ldap_error( op, rs, LDAP_OTHER, "internal error" ); - return ret; - } - - return LDAP_SUCCESS; -} - -int -bdb_send_ldap_intermediate( - Operation *op, - SlapReply *rs, - int state, - struct berval *cookie ) -{ - BerElementBuffer berbuf; - BerElement *ber = (BerElement *)&berbuf; - struct berval rspdata; - - int ret; - - ber_init2( ber, NULL, LBER_USE_DER ); - - if ( cookie == NULL ) { - ber_printf( ber, "{eN}", state ); - } else { - ber_printf( ber, "{eON}", state, cookie ); - } - - ret = ber_flatten2( ber, &rspdata, 0 ); - - if ( ret < 0 ) { -#ifdef NEW_LOGGING - LDAP_LOG ( OPERATION, RESULTS, - "bdb_send_ldap_intermediate: ber_flatten2 failed\n", - 0, 0, 0 ); -#else - Debug( LDAP_DEBUG_TRACE, - "bdb_send_ldap_intermediate: ber_flatten2 failed\n", - 0, 0, 0 ); -#endif - send_ldap_error( op, rs, LDAP_OTHER, "internal error" ); - return ret; - } - - rs->sr_rspdata = &rspdata; - send_ldap_intermediate( op, rs ); - rs->sr_rspdata = NULL; - ber_free_buf( ber ); - - return LDAP_SUCCESS; -} diff --git a/servers/slapd/back-ldap/init.c b/servers/slapd/back-ldap/init.c index fb3d8d676d..327ffc7f4e 100644 --- a/servers/slapd/back-ldap/init.c +++ b/servers/slapd/back-ldap/init.c @@ -198,7 +198,7 @@ ldap_back_db_destroy( } #ifdef ENABLE_REWRITE if (li->rwmap.rwm_rw) { - rewrite_info_delete( li->rwmap.rwm_rw ); + rewrite_info_delete( &li->rwmap.rwm_rw ); } #else /* !ENABLE_REWRITE */ if (li->rwmap.rwm_suffix_massage) { diff --git a/servers/slapd/back-ldbm/delete.c b/servers/slapd/back-ldbm/delete.c index edcfbf5be4..ddad52d7a0 100644 --- a/servers/slapd/back-ldbm/delete.c +++ b/servers/slapd/back-ldbm/delete.c @@ -60,9 +60,10 @@ ldbm_back_delete( cache_return_entry_r( &li->li_cache, matched ); } else { - BerVarray deref = op->o_bd->syncinfo ? - op->o_bd->syncinfo->provideruri_bv : default_referral; - rs->sr_ref = referral_rewrite( deref, NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT ); + BerVarray deref = op->o_bd->be_syncinfo ? + op->o_bd->be_syncinfo->si_provideruri_bv : default_referral; + rs->sr_ref = referral_rewrite( deref, NULL, &op->o_req_dn, + LDAP_SCOPE_DEFAULT ); } ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); diff --git a/servers/slapd/back-ldbm/modify.c b/servers/slapd/back-ldbm/modify.c index 5679f2dadc..bed5eefd8e 100644 --- a/servers/slapd/back-ldbm/modify.c +++ b/servers/slapd/back-ldbm/modify.c @@ -324,9 +324,10 @@ ldbm_back_modify( : NULL; cache_return_entry_r( &li->li_cache, matched ); } else { - BerVarray deref = op->o_bd->syncinfo ? - op->o_bd->syncinfo->provideruri_bv : default_referral; - rs->sr_ref = referral_rewrite( deref, NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT ); + BerVarray deref = op->o_bd->be_syncinfo ? + op->o_bd->be_syncinfo->si_provideruri_bv : default_referral; + rs->sr_ref = referral_rewrite( deref, NULL, &op->o_req_dn, + LDAP_SCOPE_DEFAULT ); } ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); diff --git a/servers/slapd/back-ldbm/modrdn.c b/servers/slapd/back-ldbm/modrdn.c index 99440e9d45..2c20f1d589 100644 --- a/servers/slapd/back-ldbm/modrdn.c +++ b/servers/slapd/back-ldbm/modrdn.c @@ -92,9 +92,10 @@ ldbm_back_modrdn( : NULL; cache_return_entry_r( &li->li_cache, matched ); } else { - BerVarray deref = op->o_bd->syncinfo ? - op->o_bd->syncinfo->provideruri_bv : default_referral; - rs->sr_ref = referral_rewrite( deref, NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT ); + BerVarray deref = op->o_bd->be_syncinfo ? + op->o_bd->be_syncinfo->si_provideruri_bv : default_referral; + rs->sr_ref = referral_rewrite( deref, NULL, &op->o_req_dn, + LDAP_SCOPE_DEFAULT ); } ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock); diff --git a/servers/slapd/back-meta/cache-merge.c b/servers/slapd/back-meta/cache-merge.c index 211ec672e3..38df26fec3 100644 --- a/servers/slapd/back-meta/cache-merge.c +++ b/servers/slapd/back-meta/cache-merge.c @@ -120,7 +120,14 @@ merge_entry( sreply.sr_nentries = 0; e = ( Entry * ) ch_calloc( 1, sizeof( Entry )); - dnPrettyNormal(0, &rs->sr_entry->e_name, &e->e_name, &e->e_nname, op->o_tmpmemctx); + + dnPrettyNormal(0, &rs->sr_entry->e_name, &op_tmp.o_req_dn, &op_tmp.o_req_ndn, op->o_tmpmemctx); + ber_dupbv( &e->e_name, &op_tmp.o_req_dn ); + ber_dupbv( &e->e_nname, &op_tmp.o_req_ndn ); + sl_free( op_tmp.o_req_ndn.bv_val, op->o_tmpmemctx ); + sl_free( op_tmp.o_req_dn.bv_val, op->o_tmpmemctx ); + op_tmp.o_req_dn = e->e_name; + op_tmp.o_req_ndn = e->e_nname; e->e_private = NULL; e->e_attrs = NULL; @@ -163,8 +170,6 @@ merge_entry( op_tmp.o_do_not_cache = 1; op_tmp.ora_e = e; - op_tmp.o_req_dn = e->e_name; - op_tmp.o_req_ndn = e->e_nname; rc = op->o_bd->be_add( &op_tmp, &sreply ); if ( rc != LDAP_SUCCESS ) { @@ -178,8 +183,7 @@ merge_entry( result->rc = info.added; } else if ( rc == LDAP_REFERRAL || rc == LDAP_NO_SUCH_OBJECT ) { - slap_entry2mods( e, &modlist, &text ); - syncrepl_add_glue( NULL, NULL, &op_tmp, e, modlist, 0, NULL, NULL ); + syncrepl_add_glue( &op_tmp, e ); result->rc = info.added; } else { result->rc = 0; @@ -256,7 +260,7 @@ normalize_values( Attribute* attr ) { for ( i = 0; i < nvals; i++ ) { rc = attr->a_desc->ad_type->sat_equality->smr_normalize( - 0, + SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, attr->a_desc->ad_type->sat_syntax, attr->a_desc->ad_type->sat_equality, &attr->a_vals[i], &attr->a_nvals[i], NULL ); diff --git a/servers/slapd/back-meta/cache-search.c b/servers/slapd/back-meta/cache-search.c index 8f61bef9f6..31effb378f 100644 --- a/servers/slapd/back-meta/cache-search.c +++ b/servers/slapd/back-meta/cache-search.c @@ -849,7 +849,7 @@ meta_create_entry ( struct berval *bv, bdn; const char *text; char* ename = NULL; - struct berval sc; + struct berval sc = { 0, NULL }; char* textbuf; size_t textlen; diff --git a/servers/slapd/back-meta/cache.h b/servers/slapd/back-meta/cache.h index 1f7a50c083..0c3accb576 100644 --- a/servers/slapd/back-meta/cache.h +++ b/servers/slapd/back-meta/cache.h @@ -1,24 +1,18 @@ /* Copyright (c) 2003 by International Business Machines, Inc. * * International Business Machines, Inc. (hereinafter called IBM) grants - * permission under its copyrights to use, copy, modify, and distribute -this - * Software with or without fee, provided that the above copyright notice -and - * all paragraphs of this notice appear in all copies, and that the name -of IBM - * not be used in connection with the marketing of any product -incorporating + * permission under its copyrights to use, copy, modify, and distribute this + * Software with or without fee, provided that the above copyright notice and + * all paragraphs of this notice appear in all copies, and that the name of IBM + * not be used in connection with the marketing of any product incorporating * the Software or modifications thereof, without specific, written prior * permission. * * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, - * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER -ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, -EVEN + * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. */ diff --git a/servers/slapd/back-meta/init.c b/servers/slapd/back-meta/init.c index 3f8009a185..c4ac607e38 100644 --- a/servers/slapd/back-meta/init.c +++ b/servers/slapd/back-meta/init.c @@ -147,13 +147,13 @@ meta_back_db_init( cm = (cache_manager *)ch_malloc(sizeof(cache_manager)); if ( cm == NULL ) { - rewrite_info_delete( rwinfo ); + rewrite_info_delete( &rwinfo ); return -1; } qm = (query_manager*)ch_malloc(sizeof(query_manager)); if ( qm == NULL ) { - rewrite_info_delete( rwinfo ); + rewrite_info_delete( &rwinfo ); ch_free( cm ); return -1; } @@ -259,7 +259,7 @@ target_free( free( lt->pseudorootpw.bv_val ); } if ( lt->rwmap.rwm_rw ) { - rewrite_info_delete( lt->rwmap.rwm_rw ); + rewrite_info_delete( <->rwmap.rwm_rw ); } avl_free( lt->rwmap.rwm_oc.remap, NULL ); avl_free( lt->rwmap.rwm_oc.map, mapping_free ); diff --git a/servers/slapd/back-monitor/log.c b/servers/slapd/back-monitor/log.c index 6b072071b2..7b2d4c0bee 100644 --- a/servers/slapd/back-monitor/log.c +++ b/servers/slapd/back-monitor/log.c @@ -122,7 +122,7 @@ monitor_subsys_log_init( int rc; rc = (*mi->mi_ad_managedInfo->ad_type->sat_equality->smr_normalize)( - 0, + SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, mi->mi_ad_managedInfo->ad_type->sat_syntax, mi->mi_ad_managedInfo->ad_type->sat_equality, &int_2_level[ i ].s, diff --git a/servers/slapd/backend.c b/servers/slapd/backend.c index 7458a2b910..8edb10f2d6 100644 --- a/servers/slapd/backend.c +++ b/servers/slapd/backend.c @@ -244,8 +244,6 @@ int backend_startup(Backend *be) int i; int rc = 0; - init_syncrepl(); - if( ! ( nBackendDB > 0 ) ) { /* no databases */ #ifdef NEW_LOGGING @@ -336,10 +334,12 @@ int backend_startup(Backend *be) /* open each backend database */ for( i = 0; i < nBackendDB; i++ ) { +#ifndef SLAPD_MULTIMASTER if ( backendDB[i].be_update_ndn.bv_val && ( !backendDB[i].be_update_refs && - !backendDB[i].syncinfo && - !default_referral ) ) { + !backendDB[i].be_syncinfo && + !default_referral ) ) + { #ifdef NEW_LOGGING LDAP_LOG( BACKEND, CRIT, "backend_startup: slave \"%s\" updateref missing\n", @@ -352,6 +352,7 @@ int backend_startup(Backend *be) #endif return -1; } +#endif /* append global access controls */ acl_append( &backendDB[i].be_acl, global_acl ); @@ -374,12 +375,13 @@ int backend_startup(Backend *be) } } - if ( backendDB[i].syncinfo != NULL ) { - syncinfo_t *si = ( syncinfo_t * ) backendDB[i].syncinfo; - si->be = &backendDB[i]; + if ( backendDB[i].be_syncinfo != NULL ) { + syncinfo_t *si = ( syncinfo_t * ) backendDB[i].be_syncinfo; + si->si_be = &backendDB[i]; + init_syncrepl(si); ldap_pvt_thread_mutex_lock( &syncrepl_rq.rq_mutex ); - ldap_pvt_runqueue_insert( &syncrepl_rq, si->interval, - do_syncrepl, (void *) backendDB[i].syncinfo ); + ldap_pvt_runqueue_insert( &syncrepl_rq, si->si_interval, + do_syncrepl, (void *) backendDB[i].be_syncinfo ); ldap_pvt_thread_mutex_unlock( &syncrepl_rq.rq_mutex ); } } @@ -550,7 +552,7 @@ backend_db_init( ldap_pvt_thread_mutex_init( &be->be_pcl_mutex ); ldap_pvt_thread_mutex_init( &be->be_context_csn_mutex ); - be->syncinfo = NULL; + be->be_syncinfo = NULL; /* assign a default depth limit for alias deref */ be->be_max_deref_depth = SLAPD_DEFAULT_MAXDEREFDEPTH; @@ -743,31 +745,29 @@ int backend_unbind( Operation *op, SlapReply *rs ) { int i; -#if defined( LDAP_SLAPI ) - Slapi_PBlock *pb = op->o_pb; - - int rc; - slapi_x_pblock_set_operation( pb, op ); -#endif /* defined( LDAP_SLAPI ) */ for ( i = 0; i < nbackends; i++ ) { #if defined( LDAP_SLAPI ) - slapi_pblock_set( pb, SLAPI_BACKEND, (void *)&backends[i] ); - rc = doPluginFNs( &backends[i], SLAPI_PLUGIN_PRE_UNBIND_FN, - (Slapi_PBlock *)pb ); - if ( rc < 0 ) { - /* - * A preoperation plugin failure will abort the - * entire operation. - */ + if ( op->o_pb ) { + int rc; + if ( i == 0 ) slapi_x_pblock_set_operation( op->o_pb, op ); + slapi_pblock_set( op->o_pb, SLAPI_BACKEND, (void *)&backends[i] ); + rc = doPluginFNs( &backends[i], SLAPI_PLUGIN_PRE_UNBIND_FN, + (Slapi_PBlock *)op->o_pb ); + if ( rc < 0 ) { + /* + * A preoperation plugin failure will abort the + * entire operation. + */ #ifdef NEW_LOGGING - LDAP_LOG( OPERATION, INFO, "do_bind: Unbind preoperation plugin " - "failed\n", 0, 0, 0); + LDAP_LOG( OPERATION, INFO, "do_bind: Unbind preoperation plugin " + "failed\n", 0, 0, 0); #else - Debug(LDAP_DEBUG_TRACE, "do_bind: Unbind preoperation plugin " - "failed.\n", 0, 0, 0); + Debug(LDAP_DEBUG_TRACE, "do_bind: Unbind preoperation plugin " + "failed.\n", 0, 0, 0); #endif - return 0; + return 0; + } } #endif /* defined( LDAP_SLAPI ) */ @@ -777,8 +777,8 @@ backend_unbind( Operation *op, SlapReply *rs ) } #if defined( LDAP_SLAPI ) - if ( doPluginFNs( &backends[i], SLAPI_PLUGIN_POST_UNBIND_FN, - (Slapi_PBlock *)pb ) < 0 ) { + if ( op->o_pb && doPluginFNs( &backends[i], SLAPI_PLUGIN_POST_UNBIND_FN, + (Slapi_PBlock *)op->o_pb ) < 0 ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, INFO, "do_unbind: Unbind postoperation plugins " "failed\n", 0, 0, 0); @@ -1176,9 +1176,7 @@ backend_group( op->o_bd = select_backend( gr_ndn, 0, 0 ); - ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); - - for (g = op->o_conn->c_groups; g; g=g->ga_next) { + for (g = op->o_groups; g; g=g->ga_next) { if (g->ga_be != op->o_bd || g->ga_oc != group_oc || g->ga_at != group_at || g->ga_len != gr_ndn->bv_len) continue; @@ -1186,8 +1184,6 @@ backend_group( break; } - ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); - if (g) { rc = g->ga_res; goto done; @@ -1283,17 +1279,15 @@ backend_group( } if ( op->o_tag != LDAP_REQ_BIND && !op->o_do_not_cache ) { - g = ch_malloc(sizeof(GroupAssertion) + gr_ndn->bv_len); + g = sl_malloc(sizeof(GroupAssertion) + gr_ndn->bv_len, op->o_tmpmemctx); g->ga_be = op->o_bd; g->ga_oc = group_oc; g->ga_at = group_at; g->ga_res = rc; g->ga_len = gr_ndn->bv_len; strcpy(g->ga_ndn, gr_ndn->bv_val); - ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); - g->ga_next = op->o_conn->c_groups; - op->o_conn->c_groups = g; - ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); + g->ga_next = op->o_groups; + op->o_groups = g; } done: op->o_bd = be; diff --git a/servers/slapd/bind.c b/servers/slapd/bind.c index b4095cf56b..a500dd37cb 100644 --- a/servers/slapd/bind.c +++ b/servers/slapd/bind.c @@ -45,11 +45,6 @@ do_bind( ber_tag_t tag; Backend *be = NULL; -#ifdef LDAP_SLAPI - Slapi_PBlock *pb = op->o_pb; - int rc; -#endif - #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ENTRY, "do_bind: conn %d\n", op->o_connid, 0, 0 ); #else @@ -357,6 +352,7 @@ do_bind( } #ifdef LDAP_SLAPI +#define pb op->o_pb /* * Normally post-operation plugins are called only after the * backend operation. Because the front-end performs SASL @@ -364,12 +360,14 @@ do_bind( * exception to call the post-operation plugins after a * SASL bind. */ - slapi_x_pblock_set_operation( pb, op ); - slapi_pblock_set( pb, SLAPI_BIND_TARGET, (void *)dn.bv_val ); - slapi_pblock_set( pb, SLAPI_BIND_METHOD, (void *)method ); - slapi_pblock_set( pb, SLAPI_BIND_CREDENTIALS, (void *)&op->orb_cred ); - slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)(0) ); - (void) doPluginFNs( op->o_bd, SLAPI_PLUGIN_POST_BIND_FN, pb ); + if ( pb ) { + slapi_x_pblock_set_operation( pb, op ); + slapi_pblock_set( pb, SLAPI_BIND_TARGET, (void *)dn.bv_val ); + slapi_pblock_set( pb, SLAPI_BIND_METHOD, (void *)method ); + slapi_pblock_set( pb, SLAPI_BIND_CREDENTIALS, (void *)&op->orb_cred ); + slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)(0) ); + (void) doPluginFNs( op->o_bd, SLAPI_PLUGIN_POST_BIND_FN, pb ); + } #endif /* LDAP_SLAPI */ ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); @@ -522,84 +520,87 @@ do_bind( } #if defined( LDAP_SLAPI ) - slapi_x_pblock_set_operation( pb, op ); - slapi_pblock_set( pb, SLAPI_BIND_TARGET, (void *)dn.bv_val ); - slapi_pblock_set( pb, SLAPI_BIND_METHOD, (void *)method ); - slapi_pblock_set( pb, SLAPI_BIND_CREDENTIALS, (void *)&op->orb_cred ); - slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)(0) ); - slapi_pblock_set( pb, SLAPI_CONN_DN, (void *)(0) ); + if ( pb ) { + int rc; + slapi_x_pblock_set_operation( pb, op ); + slapi_pblock_set( pb, SLAPI_BIND_TARGET, (void *)dn.bv_val ); + slapi_pblock_set( pb, SLAPI_BIND_METHOD, (void *)method ); + slapi_pblock_set( pb, SLAPI_BIND_CREDENTIALS, (void *)&op->orb_cred ); + slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)(0) ); + slapi_pblock_set( pb, SLAPI_CONN_DN, (void *)(0) ); - rc = doPluginFNs( op->o_bd, SLAPI_PLUGIN_PRE_BIND_FN, pb ); + rc = doPluginFNs( op->o_bd, SLAPI_PLUGIN_PRE_BIND_FN, pb ); #ifdef NEW_LOGGING - LDAP_LOG( OPERATION, INFO, - "do_bind: Bind preoperation plugin returned %d\n", - rs->sr_err, 0, 0); + LDAP_LOG( OPERATION, INFO, + "do_bind: Bind preoperation plugin returned %d\n", + rs->sr_err, 0, 0); #else - Debug(LDAP_DEBUG_TRACE, - "do_bind: Bind preoperation plugin returned %d.\n", - rs->sr_err, 0, 0); + Debug(LDAP_DEBUG_TRACE, + "do_bind: Bind preoperation plugin returned %d.\n", + rs->sr_err, 0, 0); #endif - switch ( rc ) { - case SLAPI_BIND_SUCCESS: - /* Continue with backend processing */ - break; - case SLAPI_BIND_FAIL: - /* Failure, server sends result */ - rs->sr_err = LDAP_INVALID_CREDENTIALS; - send_ldap_result( op, rs ); - goto cleanup; - break; - case SLAPI_BIND_ANONYMOUS: - /* SLAPI_BIND_ANONYMOUS is undocumented XXX */ - default: - /* Authoritative, plugin sent result, or no plugins called. */ - if ( slapi_pblock_get( op->o_pb, SLAPI_RESULT_CODE, - (void *)&rs->sr_err) != 0 ) - { - rs->sr_err = LDAP_OTHER; - } + switch ( rc ) { + case SLAPI_BIND_SUCCESS: + /* Continue with backend processing */ + break; + case SLAPI_BIND_FAIL: + /* Failure, server sends result */ + rs->sr_err = LDAP_INVALID_CREDENTIALS; + send_ldap_result( op, rs ); + goto cleanup; + break; + case SLAPI_BIND_ANONYMOUS: + /* SLAPI_BIND_ANONYMOUS is undocumented XXX */ + default: + /* Authoritative, plugin sent result, or no plugins called. */ + if ( slapi_pblock_get( op->o_pb, SLAPI_RESULT_CODE, + (void *)&rs->sr_err) != 0 ) + { + rs->sr_err = LDAP_OTHER; + } - op->orb_edn.bv_val = NULL; - op->orb_edn.bv_len = 0; + op->orb_edn.bv_val = NULL; + op->orb_edn.bv_len = 0; - if ( rs->sr_err == LDAP_SUCCESS ) { - slapi_pblock_get( pb, SLAPI_CONN_DN, (void *)&op->orb_edn.bv_val ); - if ( op->orb_edn.bv_val == NULL ) { - if ( rc == 1 ) { - /* No plugins were called; continue. */ - break; + if ( rs->sr_err == LDAP_SUCCESS ) { + slapi_pblock_get( pb, SLAPI_CONN_DN, (void *)&op->orb_edn.bv_val ); + if ( op->orb_edn.bv_val == NULL ) { + if ( rc == 1 ) { + /* No plugins were called; continue. */ + break; + } + } else { + op->orb_edn.bv_len = strlen( op->orb_edn.bv_val ); } - } else { - op->orb_edn.bv_len = strlen( op->orb_edn.bv_val ); - } - rs->sr_err = dnPrettyNormal( NULL, &op->orb_edn, - &op->o_req_dn, &op->o_req_ndn, op->o_tmpmemctx ); - ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); - ber_dupbv(&op->o_conn->c_dn, &op->o_req_dn); - ber_dupbv(&op->o_conn->c_ndn, &op->o_req_ndn); - op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx ); - op->o_req_dn.bv_val = NULL; - op->o_req_dn.bv_len = 0; - op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx ); - op->o_req_ndn.bv_val = NULL; - op->o_req_ndn.bv_len = 0; - if ( op->o_conn->c_dn.bv_len != 0 ) { - ber_len_t max = sockbuf_max_incoming_auth; - ber_sockbuf_ctrl( op->o_conn->c_sb, - LBER_SB_OPT_SET_MAX_INCOMING, &max ); + rs->sr_err = dnPrettyNormal( NULL, &op->orb_edn, + &op->o_req_dn, &op->o_req_ndn, op->o_tmpmemctx ); + ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); + ber_dupbv(&op->o_conn->c_dn, &op->o_req_dn); + ber_dupbv(&op->o_conn->c_ndn, &op->o_req_ndn); + op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx ); + op->o_req_dn.bv_val = NULL; + op->o_req_dn.bv_len = 0; + op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx ); + op->o_req_ndn.bv_val = NULL; + op->o_req_ndn.bv_len = 0; + if ( op->o_conn->c_dn.bv_len != 0 ) { + ber_len_t max = sockbuf_max_incoming_auth; + ber_sockbuf_ctrl( op->o_conn->c_sb, + LBER_SB_OPT_SET_MAX_INCOMING, &max ); + } + /* log authorization identity */ + Statslog( LDAP_DEBUG_STATS, + "conn=%lu op=%lu BIND dn=\"%s\" mech=simple (SLAPI) ssf=0\n", + op->o_connid, op->o_opid, + op->o_conn->c_dn.bv_val ? op->o_conn->c_dn.bv_val : "", + 0, 0 ); + ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); } - /* log authorization identity */ - Statslog( LDAP_DEBUG_STATS, - "conn=%lu op=%lu BIND dn=\"%s\" mech=simple (SLAPI) ssf=0\n", - op->o_connid, op->o_opid, - op->o_conn->c_dn.bv_val ? op->o_conn->c_dn.bv_val : "", - 0, 0 ); - ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); + goto cleanup; + break; } - goto cleanup; - break; } #endif /* defined( LDAP_SLAPI ) */ @@ -660,7 +661,7 @@ do_bind( } #if defined( LDAP_SLAPI ) - if ( doPluginFNs( op->o_bd, SLAPI_PLUGIN_POST_BIND_FN, pb ) < 0 ) { + if ( pb && doPluginFNs( op->o_bd, SLAPI_PLUGIN_POST_BIND_FN, pb ) < 0 ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, INFO, "do_bind: Bind postoperation plugins failed\n", diff --git a/servers/slapd/compare.c b/servers/slapd/compare.c index 7615323a5c..bac553cb1b 100644 --- a/servers/slapd/compare.c +++ b/servers/slapd/compare.c @@ -45,10 +45,6 @@ do_compare( AttributeAssertion ava = { NULL, { 0, NULL } }; int manageDSAit; -#ifdef LDAP_SLAPI - Slapi_PBlock *pb = op->o_pb; -#endif - ava.aa_desc = NULL; #ifdef NEW_LOGGING @@ -254,30 +250,33 @@ do_compare( ava.aa_desc->ad_cname.bv_val, 0 ); #if defined( LDAP_SLAPI ) - slapi_x_pblock_set_operation( pb, op ); - slapi_pblock_set( pb, SLAPI_COMPARE_TARGET, (void *)dn.bv_val ); - slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)manageDSAit ); - slapi_pblock_set( pb, SLAPI_COMPARE_TYPE, (void *)desc.bv_val ); - slapi_pblock_set( pb, SLAPI_COMPARE_VALUE, (void *)&value ); - - rs->sr_err = doPluginFNs( op->o_bd, SLAPI_PLUGIN_PRE_COMPARE_FN, pb ); - if ( rs->sr_err < 0 ) { - /* - * A preoperation plugin failure will abort the - * entire operation. - */ +#define pb op->o_pb + if ( pb ) { + slapi_x_pblock_set_operation( pb, op ); + slapi_pblock_set( pb, SLAPI_COMPARE_TARGET, (void *)dn.bv_val ); + slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)manageDSAit ); + slapi_pblock_set( pb, SLAPI_COMPARE_TYPE, (void *)desc.bv_val ); + slapi_pblock_set( pb, SLAPI_COMPARE_VALUE, (void *)&value ); + + rs->sr_err = doPluginFNs( op->o_bd, SLAPI_PLUGIN_PRE_COMPARE_FN, pb ); + if ( rs->sr_err < 0 ) { + /* + * A preoperation plugin failure will abort the + * entire operation. + */ #ifdef NEW_LOGGING - LDAP_LOG( OPERATION, INFO, "do_compare: compare preoperation plugin " - "failed\n", 0, 0, 0); + LDAP_LOG( OPERATION, INFO, "do_compare: compare preoperation plugin " + "failed\n", 0, 0, 0); #else - Debug(LDAP_DEBUG_TRACE, "do_compare: compare preoperation plugin " - "failed.\n", 0, 0, 0); + Debug(LDAP_DEBUG_TRACE, "do_compare: compare preoperation plugin " + "failed.\n", 0, 0, 0); #endif - if ( ( slapi_pblock_get( op->o_pb, SLAPI_RESULT_CODE, (void *)&rs->sr_err ) != 0 ) || - rs->sr_err == LDAP_SUCCESS ) { - rs->sr_err = LDAP_OTHER; + if ( ( slapi_pblock_get( op->o_pb, SLAPI_RESULT_CODE, (void *)&rs->sr_err ) != 0 ) || + rs->sr_err == LDAP_SUCCESS ) { + rs->sr_err = LDAP_OTHER; + } + goto cleanup; } - goto cleanup; } #endif /* defined( LDAP_SLAPI ) */ @@ -290,7 +289,7 @@ do_compare( } #if defined( LDAP_SLAPI ) - if ( doPluginFNs( op->o_bd, SLAPI_PLUGIN_POST_COMPARE_FN, pb ) < 0 ) { + if ( pb && doPluginFNs( op->o_bd, SLAPI_PLUGIN_POST_COMPARE_FN, pb ) < 0 ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, INFO, "do_compare: compare postoperation plugins " "failed\n", 0, 0, 0 ); diff --git a/servers/slapd/config.c b/servers/slapd/config.c index 39c8367106..881e428823 100644 --- a/servers/slapd/config.c +++ b/servers/slapd/config.c @@ -73,6 +73,10 @@ char *strtok_quote_ptr; int use_reverse_lookup = 0; +#ifdef LDAP_SLAPI +int slapi_plugins_used = 0; +#endif + static char *fp_getline(FILE *fp, int *lineno); static void fp_getline_init(int *lineno); static int fp_parse_line(int lineno, char *line); @@ -1639,13 +1643,11 @@ read_config( const char *fname, int depth ) #endif } -#ifdef SLAP_EXTENDED_SCHEMA } else if ( strcasecmp( cargv[0], "ditcontentrule" ) == 0 ) { char * p; p = strchr(saveline,'(' /*')'*/); rc = parse_cr( fname, lineno, p, cargv ); if( rc ) return rc; -#endif /* specify an attribute type */ } else if (( strcasecmp( cargv[0], "attributetype" ) == 0 ) @@ -1937,7 +1939,7 @@ read_config( const char *fname, int depth ) } } - /* dn of master entity allowed to write to replica */ + /* dn of slave entity allowed to write to replica */ } else if ( strcasecmp( cargv[0], "updatedn" ) == 0 ) { if ( cargc < 2 ) { #ifdef NEW_LOGGING @@ -2406,6 +2408,7 @@ read_config( const char *fname, int depth ) != LDAP_SUCCESS ) { return( 1 ); } + slapi_plugins_used++; #else /* !defined( LDAP_SLAPI ) */ #ifdef NEW_LOGGING @@ -2753,7 +2756,7 @@ add_syncrepl( { syncinfo_t *si; - if ( be->syncinfo ) { + if ( be->be_syncinfo ) { #ifdef NEW_LOGGING LDAP_LOG( CONFIG, INFO, "add_syncrepl: multiple syncrepl lines in a database " @@ -2766,7 +2769,7 @@ add_syncrepl( return 1; } - si = be->syncinfo = (syncinfo_t *) ch_calloc( 1, sizeof( syncinfo_t ) ); + si = be->be_syncinfo = (syncinfo_t *) ch_calloc( 1, sizeof( syncinfo_t ) ); if ( si == NULL ) { #ifdef NEW_LOGGING @@ -2777,30 +2780,32 @@ add_syncrepl( return 1; } - si->tls = TLS_OFF; - if ( be->be_rootndn.bv_val ) - ber_dupbv( &si->updatedn, &be->be_rootndn ); - si->bindmethod = LDAP_AUTH_SIMPLE; - si->schemachecking = 0; - si->filterstr = "(objectclass=*)"; - if ( be->be_suffix && be->be_suffix[0].bv_val ) - si->base = ch_strdup( be->be_suffix[0].bv_val ); - si->scope = LDAP_SCOPE_SUBTREE; - si->attrsonly = 0; - si->attrs = (char **) ch_calloc( 1, sizeof( char * )); - si->attrs[0] = NULL; - si->type = LDAP_SYNC_REFRESH_ONLY; - si->interval = 86400; - si->syncCookie = NULL; - si->manageDSAit = 0; - si->tlimit = -1; - si->slimit = -1; - si->syncUUID = NULL; - si->syncUUID_ndn = NULL; - si->sync_mode = LDAP_SYNC_STATE_MODE; - - si->presentlist = NULL; - LDAP_LIST_INIT( &si->nonpresentlist ); + si->si_tls = SYNCINFO_TLS_OFF; + if ( be->be_rootndn.bv_val ) { + ber_dupbv( &si->si_updatedn, &be->be_rootndn ); + } + si->si_bindmethod = LDAP_AUTH_SIMPLE; + si->si_schemachecking = 0; + ber_str2bv( "(objectclass=*)", sizeof("(objectclass=*)")-1, 0, + &si->si_filterstr ); + si->si_base.bv_val = NULL; + si->si_scope = LDAP_SCOPE_SUBTREE; + si->si_attrsonly = 0; + si->si_attrs = (char **) ch_calloc( 1, sizeof( char * )); + si->si_attrs[0] = NULL; + si->si_type = LDAP_SYNC_REFRESH_ONLY; + si->si_interval = 86400; + si->si_syncCookie.ctxcsn = NULL; + si->si_syncCookie.octet_str = NULL; + si->si_syncCookie.sid = -1; + si->si_manageDSAit = 0; + si->si_tlimit = -1; + si->si_slimit = -1; + si->si_syncUUID_ndn.bv_val = NULL; + si->si_syncUUID_ndn.bv_len = 0; + + si->si_presentlist = NULL; + LDAP_LIST_INIT( &si->si_nonpresentlist ); if ( parse_syncrepl_line( cargv, cargc, si ) < 0 ) { /* Something bad happened - back out */ @@ -2810,22 +2815,22 @@ add_syncrepl( Debug( LDAP_DEBUG_ANY, "failed to add syncinfo\n", 0, 0, 0 ); #endif free( si ); - be->syncinfo = NULL; + be->be_syncinfo = NULL; return 1; } else { #ifdef NEW_LOGGING LDAP_LOG ( CONFIG, RESULTS, "add_syncrepl: Config: ** successfully added syncrepl \"%s\"\n", - si->provideruri == NULL ? "(null)" : si->provideruri, 0, 0 ); + si->si_provideruri == NULL ? "(null)" : si->si_provideruri, 0, 0 ); #else Debug( LDAP_DEBUG_CONFIG, "Config: ** successfully added syncrepl \"%s\"\n", - si->provideruri == NULL ? "(null)" : si->provideruri, 0, 0 ); + si->si_provideruri == NULL ? "(null)" : si->si_provideruri, 0, 0 ); #endif - if ( !si->schemachecking ) { + if ( !si->si_schemachecking ) { be->be_flags |= SLAP_BFLAG_NO_SCHEMA_CHECK; } - si->be = be; + si->si_be = be; return 0; } } @@ -2857,7 +2862,6 @@ add_syncrepl( #define ATTRSONLYSTR "attrsonly" #define TYPESTR "type" #define INTERVALSTR "interval" -#define COOKIESTR "cookie" #define LASTMODSTR "lastmod" #define LMREQSTR "req" #define LMGENSTR "gen" @@ -2885,205 +2889,244 @@ parse_syncrepl_line( for ( i = 1; i < cargc; i++ ) { if ( !strncasecmp( cargv[ i ], IDSTR, sizeof( IDSTR ) - 1 )) { + int tmp; /* '\0' string terminator accounts for '=' */ val = cargv[ i ] + sizeof( IDSTR ); - si->id = atoi( val ); - if ( si->id >= 1000 ) { + tmp= atoi( val ); + if ( tmp >= 1000 || tmp < 0 ) { fprintf( stderr, "Error: parse_syncrepl_line: " - "syncrepl id %d is out of range [0..999]\n", si->id ); + "syncrepl id %d is out of range [0..999]\n", tmp ); return -1; } + si->si_id = tmp; gots |= GOT_ID; } else if ( !strncasecmp( cargv[ i ], PROVIDERSTR, sizeof( PROVIDERSTR ) - 1 )) { val = cargv[ i ] + sizeof( PROVIDERSTR ); - si->provideruri = ch_strdup( val ); - si->provideruri_bv = (BerVarray) ch_calloc( 2, sizeof( struct berval )); - ber_str2bv( si->provideruri, strlen( si->provideruri ), 0, &si->provideruri_bv[0] ); - si->provideruri_bv[1].bv_len = 0; - si->provideruri_bv[1].bv_val = NULL; + si->si_provideruri = ch_strdup( val ); + si->si_provideruri_bv = (BerVarray) + ch_calloc( 2, sizeof( struct berval )); + ber_str2bv( si->si_provideruri, strlen( si->si_provideruri ), + 0, &si->si_provideruri_bv[0] ); + si->si_provideruri_bv[1].bv_len = 0; + si->si_provideruri_bv[1].bv_val = NULL; gots |= GOT_PROVIDER; } else if ( !strncasecmp( cargv[ i ], STARTTLSSTR, sizeof(STARTTLSSTR) - 1 ) ) { val = cargv[ i ] + sizeof( STARTTLSSTR ); if( !strcasecmp( val, CRITICALSTR ) ) { - si->tls = TLS_CRITICAL; + si->si_tls = SYNCINFO_TLS_CRITICAL; } else { - si->tls = TLS_ON; + si->si_tls = SYNCINFO_TLS_ON; } } else if ( !strncasecmp( cargv[ i ], - UPDATEDNSTR, sizeof( UPDATEDNSTR ) - 1 ) ) { - char *str; + UPDATEDNSTR, sizeof( UPDATEDNSTR ) - 1 ) ) + { struct berval updatedn = {0, NULL}; val = cargv[ i ] + sizeof( UPDATEDNSTR ); - str = ch_strdup( val ); - ber_str2bv( str, strlen(str), 1, &updatedn ); - dnNormalize( 0, NULL, NULL, &updatedn, &si->updatedn, NULL ); - ch_free( str ); - ch_free( updatedn.bv_val ); + ber_str2bv( val, 0, 0, &updatedn ); + ch_free( si->si_updatedn.bv_val ); + dnNormalize( 0, NULL, NULL, &updatedn, &si->si_updatedn, NULL ); } else if ( !strncasecmp( cargv[ i ], BINDMETHSTR, - sizeof( BINDMETHSTR ) - 1 ) ) { + sizeof( BINDMETHSTR ) - 1 ) ) + { val = cargv[ i ] + sizeof( BINDMETHSTR ); if ( !strcasecmp( val, SIMPLESTR )) { - si->bindmethod = LDAP_AUTH_SIMPLE; + si->si_bindmethod = LDAP_AUTH_SIMPLE; gots |= GOT_METHOD; } else if ( !strcasecmp( val, SASLSTR )) { - si->bindmethod = LDAP_AUTH_SASL; +#ifdef HAVE_CYRUS_SASL + si->si_bindmethod = LDAP_AUTH_SASL; gots |= GOT_METHOD; +#else /* HAVE_CYRUS_SASL */ + fprintf( stderr, "Error: parse_syncrepl_line: " + "not compiled with SASL support\n" ); + return 1; +#endif /* HAVE_CYRUS_SASL */ } else { - si->bindmethod = -1; + si->si_bindmethod = -1; } } else if ( !strncasecmp( cargv[ i ], BINDDNSTR, sizeof( BINDDNSTR ) - 1 ) ) { val = cargv[ i ] + sizeof( BINDDNSTR ); - si->binddn = ch_strdup( val ); + si->si_binddn = ch_strdup( val ); } else if ( !strncasecmp( cargv[ i ], CREDSTR, sizeof( CREDSTR ) - 1 ) ) { val = cargv[ i ] + sizeof( CREDSTR ); - si->passwd = ch_strdup( val ); + si->si_passwd = ch_strdup( val ); } else if ( !strncasecmp( cargv[ i ], SASLMECHSTR, sizeof( SASLMECHSTR ) - 1 ) ) { val = cargv[ i ] + sizeof( SASLMECHSTR ); - si->saslmech = ch_strdup( val ); + si->si_saslmech = ch_strdup( val ); } else if ( !strncasecmp( cargv[ i ], SECPROPSSTR, sizeof( SECPROPSSTR ) - 1 ) ) { val = cargv[ i ] + sizeof( SECPROPSSTR ); - si->secprops = ch_strdup( val ); + si->si_secprops = ch_strdup( val ); } else if ( !strncasecmp( cargv[ i ], REALMSTR, sizeof( REALMSTR ) - 1 ) ) { val = cargv[ i ] + sizeof( REALMSTR ); - si->realm = ch_strdup( val ); + si->si_realm = ch_strdup( val ); } else if ( !strncasecmp( cargv[ i ], AUTHCSTR, sizeof( AUTHCSTR ) - 1 ) ) { val = cargv[ i ] + sizeof( AUTHCSTR ); - si->authcId = ch_strdup( val ); + si->si_authcId = ch_strdup( val ); } else if ( !strncasecmp( cargv[ i ], OLDAUTHCSTR, sizeof( OLDAUTHCSTR ) - 1 ) ) { /* Old authcID is provided for some backwards compatibility */ val = cargv[ i ] + sizeof( OLDAUTHCSTR ); - si->authcId = ch_strdup( val ); + si->si_authcId = ch_strdup( val ); } else if ( !strncasecmp( cargv[ i ], AUTHZSTR, sizeof( AUTHZSTR ) - 1 ) ) { val = cargv[ i ] + sizeof( AUTHZSTR ); - si->authzId = ch_strdup( val ); + si->si_authzId = ch_strdup( val ); } else if ( !strncasecmp( cargv[ i ], - SRVTABSTR, sizeof( SRVTABSTR ) - 1 ) ) { - val = cargv[ i ] + sizeof( SRVTABSTR ); - if ( si->srvtab != NULL ) { - free( si->srvtab ); - } - si->srvtab = ch_strdup( val ); - } else if ( !strncasecmp( cargv[ i ], - SCHEMASTR, sizeof( SCHEMASTR ) - 1 ) ) { + SCHEMASTR, sizeof( SCHEMASTR ) - 1 ) ) + { val = cargv[ i ] + sizeof( SCHEMASTR ); if ( !strncasecmp( val, "on", sizeof( "on" ) - 1 )) { - si->schemachecking = 1; + si->si_schemachecking = 1; } else if ( !strncasecmp( val, "off", sizeof( "off" ) - 1 ) ) { - si->schemachecking = 0; + si->si_schemachecking = 0; } else { - si->schemachecking = 1; + si->si_schemachecking = 1; } } else if ( !strncasecmp( cargv[ i ], - FILTERSTR, sizeof( FILTERSTR ) - 1 ) ) { + FILTERSTR, sizeof( FILTERSTR ) - 1 ) ) + { val = cargv[ i ] + sizeof( FILTERSTR ); - si->filterstr = ch_strdup( val ); + ber_str2bv( val, 0, 1, &si->si_filterstr ); } else if ( !strncasecmp( cargv[ i ], - SEARCHBASESTR, sizeof( SEARCHBASESTR ) - 1 ) ) { + SEARCHBASESTR, sizeof( SEARCHBASESTR ) - 1 ) ) + { + struct berval bv; val = cargv[ i ] + sizeof( SEARCHBASESTR ); - si->base = ch_strdup( val ); + if ( si->si_base.bv_val ) { + ch_free( si->si_base.bv_val ); + } + ber_str2bv( val, 0, 0, &bv ); + if ( dnNormalize( 0, NULL, NULL, &bv, &si->si_base, NULL )) { + fprintf( stderr, "Invalid base DN \"%s\"\n", val ); + return 1; + } } else if ( !strncasecmp( cargv[ i ], - SCOPESTR, sizeof( SCOPESTR ) - 1 ) ) { + SCOPESTR, sizeof( SCOPESTR ) - 1 ) ) + { val = cargv[ i ] + sizeof( SCOPESTR ); if ( !strncasecmp( val, "base", sizeof( "base" ) - 1 )) { - si->scope = LDAP_SCOPE_BASE; + si->si_scope = LDAP_SCOPE_BASE; } else if ( !strncasecmp( val, "one", sizeof( "one" ) - 1 )) { - si->scope = LDAP_SCOPE_ONELEVEL; + si->si_scope = LDAP_SCOPE_ONELEVEL; } else if ( !strncasecmp( val, "sub", sizeof( "sub" ) - 1 )) { - si->scope = LDAP_SCOPE_SUBTREE; + si->si_scope = LDAP_SCOPE_SUBTREE; } else { fprintf( stderr, "Error: parse_syncrepl_line: " - "unknown scope \"%s\"\n", val); + "unknown scope \"%s\"\n", val); return 1; } } else if ( !strncasecmp( cargv[ i ], - ATTRSONLYSTR, sizeof( ATTRSONLYSTR ) - 1 ) ) { - si->attrsonly = 1; + ATTRSONLYSTR, sizeof( ATTRSONLYSTR ) - 1 ) ) + { + si->si_attrsonly = 1; } else if ( !strncasecmp( cargv[ i ], - ATTRSSTR, sizeof( ATTRSSTR ) - 1 ) ) { + ATTRSSTR, sizeof( ATTRSSTR ) - 1 ) ) + { val = cargv[ i ] + sizeof( ATTRSSTR ); - str2clist( &si->attrs, val, "," ); + str2clist( &si->si_attrs, val, "," ); } else if ( !strncasecmp( cargv[ i ], - TYPESTR, sizeof( TYPESTR ) - 1 ) ) { + TYPESTR, sizeof( TYPESTR ) - 1 ) ) + { val = cargv[ i ] + sizeof( TYPESTR ); - if ( !strncasecmp( val, "refreshOnly", sizeof( "refreshOnly" ) - 1 )) { - si->type = LDAP_SYNC_REFRESH_ONLY; - } else if ( !strncasecmp( val, "refreshAndPersist", sizeof( "refreshAndPersist" ) - 1 )) { - si->type = LDAP_SYNC_REFRESH_AND_PERSIST; - si->interval = 0; + if ( !strncasecmp( val, "refreshOnly", sizeof("refreshOnly")-1 )) { + si->si_type = LDAP_SYNC_REFRESH_ONLY; + } else if ( !strncasecmp( val, "refreshAndPersist", + sizeof("refreshAndPersist")-1 )) + { + si->si_type = LDAP_SYNC_REFRESH_AND_PERSIST; + si->si_interval = 60; } else { fprintf( stderr, "Error: parse_syncrepl_line: " - "unknown sync type \"%s\"\n", val); + "unknown sync type \"%s\"\n", val); return 1; } } else if ( !strncasecmp( cargv[ i ], - INTERVALSTR, sizeof( INTERVALSTR ) - 1 ) ) { + INTERVALSTR, sizeof( INTERVALSTR ) - 1 ) ) + { val = cargv[ i ] + sizeof( INTERVALSTR ); - if ( si->type == LDAP_SYNC_REFRESH_AND_PERSIST ) { - si->interval = 0; + if ( si->si_type == LDAP_SYNC_REFRESH_AND_PERSIST ) { + si->si_interval = 0; } else { - char *dstr; char *hstr; char *mstr; + char *dstr; + char *sstr; + int dd, hh, mm, ss; dstr = val; hstr = strchr( dstr, ':' ); if ( hstr == NULL ) { fprintf( stderr, "Error: parse_syncrepl_line: " - "invalid interval \"%s\"\n", val ); + "invalid interval \"%s\"\n", val ); return 1; } *hstr++ = '\0'; mstr = strchr( hstr, ':' ); if ( mstr == NULL ) { fprintf( stderr, "Error: parse_syncrepl_line: " - "invalid interval \"%s\"\n", val ); + "invalid interval \"%s\"\n", val ); return 1; } *mstr++ = '\0'; - si->interval = (( atoi( dstr ) * 24 + atoi( hstr )) * 60 - + atoi( mstr )) * 60; + sstr = strchr( mstr, ':' ); + if ( sstr == NULL ) { + fprintf( stderr, "Error: parse_syncrepl_line: " + "invalid interval \"%s\"\n", val ); + return 1; + } + *sstr++ = '\0'; + + dd = atoi( dstr ); + hh = atoi( hstr ); + mm = atoi( mstr ); + ss = atoi( sstr ); + if (( hh > 24 ) || ( hh < 0 ) || + ( mm > 60 ) || ( mm < 0 ) || + ( ss > 60 ) || ( ss < 0 ) || ( dd < 0 )) { + fprintf( stderr, "Error: parse_syncrepl_line: " + "invalid interval \"%s\"\n", val ); + return 1; + } + si->si_interval = (( dd * 24 + hh ) * 60 + mm ) * 60 + ss; } - if ( si->interval < 0 ) { + if ( si->si_interval < 0 ) { fprintf( stderr, "Error: parse_syncrepl_line: " - "invalid interval \"%ld\"\n", - (long) si->interval); + "invalid interval \"%ld\"\n", + (long) si->si_interval); return 1; } } else if ( !strncasecmp( cargv[ i ], - COOKIESTR, sizeof( COOKIESTR ) - 1 ) ) { - val = cargv[ i ] + sizeof( COOKIESTR ); - si->syncCookie = ber_str2bv( val, strlen( val ), 1, NULL ); - } else if ( !strncasecmp( cargv[ i ], - MANAGEDSAITSTR, sizeof( MANAGEDSAITSTR ) - 1 ) ) { - val = cargv[ i ] + sizeof( COOKIESTR ); - si->manageDSAit = atoi( val ); + MANAGEDSAITSTR, sizeof( MANAGEDSAITSTR ) - 1 ) ) + { + val = cargv[ i ] + sizeof( MANAGEDSAITSTR ); + si->si_manageDSAit = atoi( val ); } else if ( !strncasecmp( cargv[ i ], - SLIMITSTR, sizeof( SLIMITSTR ) - 1 ) ) { + SLIMITSTR, sizeof( SLIMITSTR ) - 1 ) ) + { val = cargv[ i ] + sizeof( SLIMITSTR ); - si->slimit = atoi( val ); + si->si_slimit = atoi( val ); } else if ( !strncasecmp( cargv[ i ], - TLIMITSTR, sizeof( TLIMITSTR ) - 1 ) ) { + TLIMITSTR, sizeof( TLIMITSTR ) - 1 ) ) + { val = cargv[ i ] + sizeof( TLIMITSTR ); - si->tlimit = atoi( val ); + si->si_tlimit = atoi( val ); } else { fprintf( stderr, "Error: parse_syncrepl_line: " - "unknown keyword \"%s\"\n", cargv[ i ] ); + "unknown keyword \"%s\"\n", cargv[ i ] ); } } if ( gots != GOT_ALL ) { - fprintf( stderr, "Error: Malformed \"syncrepl\" line in slapd config file" - ); + fprintf( stderr, + "Error: Malformed \"syncrepl\" line in slapd config file" ); return -1; } diff --git a/servers/slapd/connection.c b/servers/slapd/connection.c index 731f46bc8c..01c233bb35 100644 --- a/servers/slapd/connection.c +++ b/servers/slapd/connection.c @@ -39,16 +39,18 @@ static unsigned long conn_nextid = 0; #define SLAP_C_ACTIVE 0x02 /* one or more threads */ #define SLAP_C_BINDING 0x03 /* binding */ #define SLAP_C_CLOSING 0x04 /* closing */ +#define SLAP_C_CLIENT 0x05 /* outbound client conn */ const char * connection_state2str( int state ) { switch( state ) { - case SLAP_C_INVALID: return "!"; - case SLAP_C_INACTIVE: return "|"; - case SLAP_C_ACTIVE: return ""; + case SLAP_C_INVALID: return "!"; + case SLAP_C_INACTIVE: return "|"; + case SLAP_C_ACTIVE: return ""; case SLAP_C_BINDING: return "B"; - case SLAP_C_CLOSING: return "C"; + case SLAP_C_CLOSING: return "C"; + case SLAP_C_CLIENT: return "L"; } return "?"; @@ -76,7 +78,7 @@ int connections_init(void) if( connections != NULL) { #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, INFO, - "connections_init: already initialized.\n", 0, 0, 0 ); + "connections_init: already initialized.\n", 0, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "connections_init: already initialized.\n", 0, 0, 0 ); @@ -92,8 +94,8 @@ int connections_init(void) if( connections == NULL ) { #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, ERR, - "connections_init: allocation (%d * %ld) of connection " - "array failed\n", dtblsize, (long) sizeof(Connection), 0 ); + "connections_init: allocation (%d * %ld) of connection " + "array failed\n", dtblsize, (long) sizeof(Connection), 0 ); #else Debug( LDAP_DEBUG_ANY, "connections_init: allocation (%d*%ld) of connection array failed\n", @@ -102,8 +104,8 @@ int connections_init(void) return -1; } - assert( connections[0].c_struct_state == SLAP_C_UNINITIALIZED ); - assert( connections[dtblsize-1].c_struct_state == SLAP_C_UNINITIALIZED ); + assert( connections[0].c_struct_state == SLAP_C_UNINITIALIZED ); + assert( connections[dtblsize-1].c_struct_state == SLAP_C_UNINITIALIZED ); /* * per entry initialization of the Connection array initialization @@ -125,7 +127,7 @@ int connections_destroy(void) if( connections == NULL) { #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, INFO, - "connections_destroy: nothing to destroy.\n", 0, 0, 0 ); + "connections_destroy: nothing to destroy.\n", 0, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "connections_destroy: nothing to destroy.\n", 0, 0, 0 ); @@ -140,7 +142,9 @@ int connections_destroy(void) ldap_pvt_thread_mutex_destroy( &connections[i].c_write_mutex ); ldap_pvt_thread_cond_destroy( &connections[i].c_write_cv ); #ifdef LDAP_SLAPI - slapi_x_free_object_extensions( SLAPI_X_EXT_CONNECTION, &connections[i] ); + if ( slapi_plugins_used ) { + slapi_x_free_object_extensions( SLAPI_X_EXT_CONNECTION, &connections[i] ); + } #endif } } @@ -165,6 +169,12 @@ int connections_shutdown(void) if( connections[i].c_struct_state != SLAP_C_USED ) { continue; } + /* give persistent clients a chance to cleanup */ + if( connections[i].c_conn_state == SLAP_C_CLIENT ) { + ldap_pvt_thread_pool_submit( &connection_pool, + connections[i].c_clientfunc, connections[i].c_clientarg ); + continue; + } ldap_pvt_thread_mutex_lock( &connections[i].c_mutex ); @@ -193,8 +203,10 @@ int connections_timeout_idle(time_t now) c != NULL; c = connection_next( c, &connindex ) ) { - /* Don't timeout a slow-running request */ - if( c->c_n_ops_executing ) continue; + /* Don't timeout a slow-running request or a persistent + * outbound connection */ + if( c->c_n_ops_executing || + c->c_conn_state == SLAP_C_CLIENT ) continue; if( difftime( c->c_activitytime+global_idletimeout, now) < 0 ) { /* close it */ @@ -280,7 +292,7 @@ static Connection* connection_get( ber_socket_t s ) #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, ARGS, - "connection_get: connection %d not used\n", s, 0, 0 ); + "connection_get: connection %d not used\n", s, 0, 0 ); #else Debug( LDAP_DEBUG_TRACE, "connection_get(%d): connection not used\n", @@ -290,6 +302,7 @@ static Connection* connection_get( ber_socket_t s ) ldap_pvt_thread_mutex_unlock( &c->c_mutex ); return NULL; } + if( c->c_conn_state == SLAP_C_CLIENT ) sd = 0; #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, RESULTS, @@ -328,7 +341,7 @@ long connection_init( Listener *listener, const char* dnsname, const char* peername, - int tls_udp_option, + int flags, slap_ssf_t ssf, const char *authid ) { @@ -342,17 +355,16 @@ long connection_init( assert( peername != NULL ); #ifndef HAVE_TLS - assert( tls_udp_option != 1 ); + assert( flags != CONN_IS_TLS ); #endif if( s == AC_SOCKET_INVALID ) { #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, INFO, - "connection_init: init of socket %ld invalid.\n", (long)s, 0, 0 ); + "connection_init: init of socket %ld invalid.\n", (long)s, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, - "connection_init(%ld): invalid.\n", - (long) s, 0, 0 ); + "connection_init: init of socket %ld invalid.\n", (long)s, 0, 0 ); #endif return -1; } @@ -369,48 +381,49 @@ long connection_init( #else { - ber_socket_t i; - + ber_socket_t i; c = NULL; - for( i=0; i < dtblsize; i++) { - ber_socket_t sd; + for( i=0; i < dtblsize; i++) { + ber_socket_t sd; - if( connections[i].c_struct_state == SLAP_C_UNINITIALIZED ) { - assert( connections[i].c_sb == 0 ); - c = &connections[i]; - break; - } + if( connections[i].c_struct_state == SLAP_C_UNINITIALIZED ) { + assert( connections[i].c_sb == 0 ); + c = &connections[i]; + break; + } sd = AC_SOCKET_INVALID; - if (connections[i].c_sb != NULL) - ber_sockbuf_ctrl( connections[i].c_sb, LBER_SB_OPT_GET_FD, &sd ); - - if( connections[i].c_struct_state == SLAP_C_UNUSED ) { - assert( sd == AC_SOCKET_INVALID ); - c = &connections[i]; - break; - } + if (connections[i].c_sb != NULL) { + ber_sockbuf_ctrl( connections[i].c_sb, + LBER_SB_OPT_GET_FD, &sd ); + } - assert( connections[i].c_struct_state == SLAP_C_USED ); - assert( connections[i].c_conn_state != SLAP_C_INVALID ); - assert( sd != AC_SOCKET_INVALID ); - } + if( connections[i].c_struct_state == SLAP_C_UNUSED ) { + assert( sd == AC_SOCKET_INVALID ); + c = &connections[i]; + break; + } - if( c == NULL ) { + assert( connections[i].c_struct_state == SLAP_C_USED ); + assert( connections[i].c_conn_state != SLAP_C_INVALID ); + assert( sd != AC_SOCKET_INVALID ); + } + + if( c == NULL ) { #ifdef NEW_LOGGING - LDAP_LOG( CONNECTION, INFO, - "connection_init: skt %d connection table full " - "(%d/%d)\n", s, i, dtblsize ); + LDAP_LOG( CONNECTION, INFO, + "connection_init(%d): connection table full " + "(%d/%d)\n", s, i, dtblsize ); #else - Debug( LDAP_DEBUG_ANY, + Debug( LDAP_DEBUG_ANY, "connection_init(%d): connection table full " "(%d/%d)\n", s, i, dtblsize); #endif - ldap_pvt_thread_mutex_unlock( &connections_mutex ); - return -1; + ldap_pvt_thread_mutex_unlock( &connections_mutex ); + return -1; + } } - } #endif assert( c != NULL ); @@ -430,7 +443,6 @@ long connection_init( c->c_dn.bv_len = 0; c->c_ndn.bv_val = NULL; c->c_ndn.bv_len = 0; - c->c_groups = NULL; c->c_listener = NULL; c->c_peer_domain.bv_val = NULL; @@ -464,24 +476,25 @@ long connection_init( ldap_pvt_thread_cond_init( &c->c_write_cv ); #ifdef LDAP_SLAPI - slapi_x_create_object_extensions( SLAPI_X_EXT_CONNECTION, c ); + if ( slapi_plugins_used ) { + slapi_x_create_object_extensions( SLAPI_X_EXT_CONNECTION, c ); + } #endif c->c_struct_state = SLAP_C_UNUSED; } - ldap_pvt_thread_mutex_lock( &c->c_mutex ); + ldap_pvt_thread_mutex_lock( &c->c_mutex ); - assert( c->c_struct_state == SLAP_C_UNUSED ); - assert( c->c_authmech.bv_val == NULL ); - assert( c->c_dn.bv_val == NULL ); - assert( c->c_ndn.bv_val == NULL ); - assert( c->c_groups == NULL ); - assert( c->c_listener == NULL ); - assert( c->c_peer_domain.bv_val == NULL ); - assert( c->c_peer_name.bv_val == NULL ); - assert( LDAP_STAILQ_EMPTY(&c->c_ops) ); - assert( LDAP_STAILQ_EMPTY(&c->c_pending_ops) ); + assert( c->c_struct_state == SLAP_C_UNUSED ); + assert( c->c_authmech.bv_val == NULL ); + assert( c->c_dn.bv_val == NULL ); + assert( c->c_ndn.bv_val == NULL ); + assert( c->c_listener == NULL ); + assert( c->c_peer_domain.bv_val == NULL ); + assert( c->c_peer_name.bv_val == NULL ); + assert( LDAP_STAILQ_EMPTY(&c->c_ops) ); + assert( LDAP_STAILQ_EMPTY(&c->c_pending_ops) ); assert( c->c_sasl_bind_mech.bv_val == NULL ); assert( c->c_sasl_done == 0 ); assert( c->c_sasl_authctx == NULL ); @@ -489,15 +502,26 @@ long connection_init( assert( c->c_sasl_extra == NULL ); assert( c->c_sasl_bindop == NULL ); assert( c->c_currentber == NULL ); + assert( c->c_writewaiter == 0); c->c_listener = listener; + + if ( flags == CONN_IS_CLIENT ) { + c->c_conn_state = SLAP_C_CLIENT; + c->c_struct_state = SLAP_C_USED; + ldap_pvt_thread_mutex_unlock( &c->c_mutex ); + ldap_pvt_thread_mutex_unlock( &connections_mutex ); + + return 0; + } + ber_str2bv( dnsname, 0, 1, &c->c_peer_domain ); ber_str2bv( peername, 0, 1, &c->c_peer_name ); - c->c_n_ops_received = 0; - c->c_n_ops_executing = 0; - c->c_n_ops_pending = 0; - c->c_n_ops_completed = 0; + c->c_n_ops_received = 0; + c->c_n_ops_executing = 0; + c->c_n_ops_pending = 0; + c->c_n_ops_completed = 0; c->c_n_get = 0; c->c_n_read = 0; @@ -516,7 +540,7 @@ long connection_init( #ifdef LDAP_CONNECTIONLESS c->c_is_udp = 0; - if( tls_udp_option == 2 ) { + if( flags == CONN_IS_UDP ) { c->c_is_udp = 1; #ifdef LDAP_DEBUG ber_sockbuf_add_io( c->c_sb, &ber_sockbuf_io_debug, @@ -547,8 +571,8 @@ long connection_init( { #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, INFO, - "connection_init: conn %lu set nonblocking failed\n", - c->c_connid, 0, 0 ); + "connection_init: conn %lu set nonblocking failed\n", + c->c_connid, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "connection_init(%d, %s): set nonblocking failed\n", @@ -556,33 +580,33 @@ long connection_init( #endif } - id = c->c_connid = conn_nextid++; + id = c->c_connid = conn_nextid++; - c->c_conn_state = SLAP_C_INACTIVE; - c->c_struct_state = SLAP_C_USED; + c->c_conn_state = SLAP_C_INACTIVE; + c->c_struct_state = SLAP_C_USED; c->c_ssf = c->c_transport_ssf = ssf; c->c_tls_ssf = 0; #ifdef HAVE_TLS - if ( tls_udp_option == 1 ) { - c->c_is_tls = 1; - c->c_needs_tls_accept = 1; - } else { - c->c_is_tls = 0; - c->c_needs_tls_accept = 0; - } + if ( flags == CONN_IS_TLS ) { + c->c_is_tls = 1; + c->c_needs_tls_accept = 1; + } else { + c->c_is_tls = 0; + c->c_needs_tls_accept = 0; + } #endif slap_sasl_open( c, 0 ); slap_sasl_external( c, ssf, authid ); - ldap_pvt_thread_mutex_unlock( &c->c_mutex ); - ldap_pvt_thread_mutex_unlock( &connections_mutex ); + ldap_pvt_thread_mutex_unlock( &c->c_mutex ); + ldap_pvt_thread_mutex_unlock( &connections_mutex ); - backend_connection_init(c); + backend_connection_init(c); - return id; + return id; } void connection2anonymous( Connection *c ) @@ -613,39 +637,31 @@ void connection2anonymous( Connection *c ) c->c_ndn.bv_len = 0; c->c_authz_backend = NULL; - - { - GroupAssertion *g, *n; - for (g = c->c_groups; g; g=n) { - n = g->ga_next; - free(g); - } - c->c_groups = NULL; - } } static void connection_destroy( Connection *c ) { /* note: connections_mutex should be locked by caller */ - ber_socket_t sd; - unsigned long connid; + ber_socket_t sd; + unsigned long connid; - assert( connections != NULL ); - assert( c != NULL ); - assert( c->c_struct_state != SLAP_C_UNUSED ); - assert( c->c_conn_state != SLAP_C_INVALID ); - assert( LDAP_STAILQ_EMPTY(&c->c_ops) ); + assert( connections != NULL ); + assert( c != NULL ); + assert( c->c_struct_state != SLAP_C_UNUSED ); + assert( c->c_conn_state != SLAP_C_INVALID ); + assert( LDAP_STAILQ_EMPTY(&c->c_ops) ); + assert( c->c_writewaiter == 0); - /* only for stats (print -1 as "%lu" may give unexpected results ;) */ - connid = c->c_connid; + /* only for stats (print -1 as "%lu" may give unexpected results ;) */ + connid = c->c_connid; - backend_connection_destroy(c); + backend_connection_destroy(c); - c->c_protocol = 0; - c->c_connid = -1; + c->c_protocol = 0; + c->c_connid = -1; - c->c_activitytime = c->c_starttime = 0; + c->c_activitytime = c->c_starttime = 0; connection2anonymous( c ); c->c_listener = NULL; @@ -677,10 +693,10 @@ connection_destroy( Connection *c ) ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_GET_FD, &sd ); if ( sd != AC_SOCKET_INVALID ) { - slapd_remove( sd, 0 ); + slapd_remove( sd, 1, 0 ); Statslog( LDAP_DEBUG_STATS, - "conn=%lu fd=%ld closed\n", + "conn=%lu fd=%ld closed\n", connid, (long) sd, 0, 0, 0 ); } @@ -693,12 +709,14 @@ connection_destroy( Connection *c ) ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_MAX_INCOMING, &max ); } - c->c_conn_state = SLAP_C_INVALID; - c->c_struct_state = SLAP_C_UNUSED; + c->c_conn_state = SLAP_C_INVALID; + c->c_struct_state = SLAP_C_UNUSED; #ifdef LDAP_SLAPI /* call destructors, then constructors; avoids unnecessary allocation */ - slapi_x_clear_object_extensions( SLAPI_X_EXT_CONNECTION, c ); + if ( slapi_plugins_used ) { + slapi_x_clear_object_extensions( SLAPI_X_EXT_CONNECTION, c ); + } #endif } @@ -750,8 +768,8 @@ void connection_closing( Connection *c ) ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_GET_FD, &sd ); #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, DETAIL1, - "connection_closing: conn %lu readying socket %d for close.\n", - c->c_connid, sd, 0 ); + "connection_closing: conn %lu readying socket %d for close.\n", + c->c_connid, sd, 0 ); #else Debug( LDAP_DEBUG_TRACE, "connection_closing: readying conn=%lu sd=%d for close\n", @@ -787,8 +805,8 @@ static void connection_close( Connection *c ) if( !LDAP_STAILQ_EMPTY(&c->c_ops) ) { #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, DETAIL1, - "connection_close: conn %lu deferring sd %d\n", - c->c_connid, sd, 0 ); + "connection_close: conn %lu deferring sd %d\n", + c->c_connid, sd, 0 ); #else Debug( LDAP_DEBUG_TRACE, "connection_close: deferring conn=%lu sd=%d\n", @@ -799,7 +817,7 @@ static void connection_close( Connection *c ) #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, RESULTS, - "connection_close: conn %lu sd %d\n", c->c_connid, sd, 0 ); + "connection_close: conn %lu sd %d\n", c->c_connid, sd, 0 ); #else Debug( LDAP_DEBUG_TRACE, "connection_close: conn=%lu sd=%d\n", c->c_connid, sd, 0 ); @@ -912,6 +930,7 @@ connection_operation( void *ctx, void *arg_v ) #endif /* SLAPD_MONITOR */ Connection *conn = op->o_conn; void *memctx = NULL; + void *memctx_null = NULL; ber_len_t memsiz; ldap_pvt_thread_mutex_lock( &num_ops_mutex ); @@ -1010,11 +1029,11 @@ connection_operation( void *ctx, void *arg_v ) default: #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, INFO, - "connection_operation: conn %lu unknown LDAP request 0x%lx\n", - conn->c_connid, tag, 0 ); + "connection_operation: conn %lu unknown LDAP request 0x%lx\n", + conn->c_connid, tag, 0 ); #else Debug( LDAP_DEBUG_ANY, "unknown LDAP request 0x%lx\n", - tag, 0, 0 ); + tag, 0, 0 ); #endif op->o_tag = LBER_ERROR; rs.sr_err = LDAP_PROTOCOL_ERROR; @@ -1082,24 +1101,25 @@ operations_error: ldap_pvt_thread_mutex_lock( &conn->c_mutex ); - LDAP_STAILQ_REMOVE( &conn->c_ops, op, slap_op, o_next); - LDAP_STAILQ_NEXT(op, o_next) = NULL; + ber_set_option( op->o_ber, LBER_OPT_BER_MEMCTX, &memctx_null ); - if ( op->o_cancel == SLAP_CANCEL_ACK ) - goto co_op_free; - if ( ( op->o_sync_mode & SLAP_SYNC_PERSIST ) ) { + if ( op->o_cancel != SLAP_CANCEL_ACK && + ( op->o_sync_mode & SLAP_SYNC_PERSIST ) ) { sl_mem_detach( ctx, memctx ); - goto no_co_op_free; + } else if (( op->o_sync_slog_size != -1 )) { + sl_mem_detach( ctx, memctx ); + LDAP_STAILQ_REMOVE( &conn->c_ops, op, slap_op, o_next); + LDAP_STAILQ_NEXT(op, o_next) = NULL; + conn->c_n_ops_executing--; + conn->c_n_ops_completed++; + } else { + LDAP_STAILQ_REMOVE( &conn->c_ops, op, slap_op, o_next); + LDAP_STAILQ_NEXT(op, o_next) = NULL; + slap_op_free( op ); + conn->c_n_ops_executing--; + conn->c_n_ops_completed++; } -co_op_free: - - conn->c_n_ops_executing--; - conn->c_n_ops_completed++; - memctx = NULL; - ber_set_option( op->o_ber, LBER_OPT_BER_MEMCTX, &memctx ); - slap_op_free( op ); - no_co_op_free: switch( tag ) { @@ -1125,6 +1145,52 @@ no_co_op_free: return NULL; } +int connection_client_setup( + ber_socket_t s, + Listener *l, + ldap_pvt_thread_start_t *func, + void *arg ) +{ + Connection *c; + + if ( connection_init( s, l, "", "", CONN_IS_CLIENT, 0, "" ) < 0 ) { + return -1; + } + + c = connection_get( s ); + c->c_clientfunc = func; + c->c_clientarg = arg; + connection_return( c ); + slapd_add_internal( s, 0 ); + slapd_set_read( s, 1 ); + return 0; +} + +void connection_client_enable( + ber_socket_t s +) +{ + slapd_set_read( s, 1 ); +} + +void connection_client_stop( + ber_socket_t s +) +{ + Connection *c; + + /* get (locked) connection */ + c = connection_get( s ); + + assert( c->c_conn_state == SLAP_C_CLIENT ); + + c->c_listener = NULL; + c->c_conn_state = SLAP_C_INVALID; + c->c_struct_state = SLAP_C_UNUSED; + connection_return( c ); + slapd_remove( s, 0, 1 ); +} + int connection_read(ber_socket_t s) { int rc = 0; @@ -1146,7 +1212,7 @@ int connection_read(ber_socket_t s) "connection_read(%ld): no connection!\n", (long) s, 0, 0 ); #endif - slapd_remove(s, 0); + slapd_remove(s, 1, 0); ldap_pvt_thread_mutex_unlock( &connections_mutex ); return -1; @@ -1169,10 +1235,19 @@ int connection_read(ber_socket_t s) return 0; } + if ( c->c_conn_state == SLAP_C_CLIENT ) { + slapd_clr_read( s, 0 ); + ldap_pvt_thread_pool_submit( &connection_pool, + c->c_clientfunc, c->c_clientarg ); + connection_return( c ); + ldap_pvt_thread_mutex_unlock( &connections_mutex ); + return 0; + } + #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, DETAIL1, - "connection_read: conn %lu checking for input.\n", - c->c_connid, 0, 0 ); + "connection_read: conn %lu checking for input.\n", + c->c_connid, 0, 0 ); #else Debug( LDAP_DEBUG_TRACE, "connection_read(%d): checking for input on id=%lu\n", @@ -1190,8 +1265,8 @@ int connection_read(ber_socket_t s) #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, ERR, - "connection_read: conn %lu TLS accept error, error %d\n", - c->c_connid, rc, 0 ); + "connection_read: conn %lu TLS accept error, error %d\n", + c->c_connid, rc, 0 ); #else Debug( LDAP_DEBUG_TRACE, "connection_read(%d): TLS accept error " @@ -1208,10 +1283,10 @@ int connection_read(ber_socket_t s) FD_ZERO(&rfd); FD_SET(s, &rfd); for (rc=1; rc>0;) { - tv.tv_sec = 1; - tv.tv_usec = 0; - rc = select(s+1, &rfd, NULL, NULL, &tv); - if (rc == 1) { + tv.tv_sec = 1; + tv.tv_usec = 0; + rc = select(s+1, &rfd, NULL, NULL, &tv); + if (rc == 1) { ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_DRAIN, NULL); } } @@ -1271,7 +1346,7 @@ int connection_read(ber_socket_t s) c->c_sasl_layers = 0; - rc = ldap_pvt_sasl_install( c->c_sb, c->c_sasl_sockctx ); + rc = ldap_pvt_sasl_install( c->c_sb, c->c_sasl_sockctx ); if( rc != LDAP_SUCCESS ) { #ifdef NEW_LOGGING @@ -1313,7 +1388,7 @@ int connection_read(ber_socket_t s) if( rc < 0 ) { #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, ERR, - "connection_read: conn %lu input error %d, closing.\n", + "connection_read: conn %lu input error %d, closing.\n", c->c_connid, rc, 0 ); #else Debug( LDAP_DEBUG_TRACE, @@ -1343,7 +1418,7 @@ int connection_read(ber_socket_t s) static int connection_input( - Connection *conn + Connection *conn ) { Operation *op; @@ -1362,7 +1437,7 @@ connection_input( { #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, ERR, - "connection_input: conn %lu ber_alloc failed.\n", + "connection_input: conn %lu ber_alloc failed.\n", conn->c_connid, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "ber_alloc failed\n", 0, 0, 0 ); @@ -1396,7 +1471,7 @@ connection_input( #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, ERR, - "connection_input: conn %lu ber_get_next failed, errno %d (%s).\n", + "connection_input: conn %lu ber_get_next failed, errno %d (%s).\n", conn->c_connid, err, sock_errstr(err) ); #else Debug( LDAP_DEBUG_TRACE, @@ -1420,11 +1495,11 @@ connection_input( /* log, close and send error */ #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, ERR, - "connection_input: conn %lu ber_get_int returns 0x%lx.\n", + "connection_input: conn %lu ber_get_int returns 0x%lx.\n", conn->c_connid, tag, 0 ); #else - Debug( LDAP_DEBUG_ANY, "ber_get_int returns 0x%lx\n", tag, 0, - 0 ); + Debug( LDAP_DEBUG_ANY, "ber_get_int returns 0x%lx\n", + tag, 0, 0 ); #endif ber_free( ber, 1 ); return -1; @@ -1434,11 +1509,11 @@ connection_input( /* log, close and send error */ #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, ERR, - "connection_input: conn %lu ber_peek_tag returns 0x%lx.\n", - conn->c_connid, tag, 0 ); + "connection_input: conn %lu ber_peek_tag returns 0x%lx.\n", + conn->c_connid, tag, 0 ); #else - Debug( LDAP_DEBUG_ANY, "ber_peek_tag returns 0x%lx\n", tag, 0, - 0 ); + Debug( LDAP_DEBUG_ANY, "ber_peek_tag returns 0x%lx\n", + tag, 0, 0 ); #endif ber_free( ber, 1 ); @@ -1453,15 +1528,14 @@ connection_input( } if( tag != LDAP_REQ_ABANDON && tag != LDAP_REQ_SEARCH ) { #ifdef NEW_LOGGING - LDAP_LOG( CONNECTION, ERR, - "connection_input: conn %lu invalid req for UDP 0x%lx.\n", - conn->c_connid, tag, 0 ); + LDAP_LOG( CONNECTION, ERR, + "connection_input: conn %lu invalid req for UDP 0x%lx.\n", + conn->c_connid, tag, 0 ); #else - Debug( LDAP_DEBUG_ANY, "invalid req for UDP 0x%lx\n", tag, 0, - 0 ); + Debug( LDAP_DEBUG_ANY, "invalid req for UDP 0x%lx\n", tag, 0, 0 ); #endif - ber_free( ber, 1 ); - return 0; + ber_free( ber, 1 ); + return 0; } } #endif @@ -1487,8 +1561,8 @@ connection_input( #ifdef LDAP_CONNECTIONLESS if (conn->c_is_udp) { if ( cdn ) { - ber_str2bv( cdn, 0, 1, &op->o_dn ); - op->o_protocol = LDAP_VERSION2; + 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; @@ -1499,7 +1573,7 @@ connection_input( if (rc != sizeof(struct sockaddr)) { #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, INFO, - "connection_input: conn %lu ber_write failed\n", + "connection_input: conn %lu ber_write failed\n", conn->c_connid, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "ber_write failed\n", 0, 0, 0 ); @@ -1512,7 +1586,7 @@ connection_input( if (rc == -1) { #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, INFO, - "connection_input: conn %lu put outer sequence failed\n", + "connection_input: conn %lu put outer sequence failed\n", conn->c_connid, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "ber_write failed\n", 0, 0, 0 ); @@ -1539,14 +1613,18 @@ connection_input( || conn->c_n_ops_pending || conn->c_writewaiter)) { - int max = conn->c_dn.bv_len ? slap_conn_max_pending_auth - : slap_conn_max_pending; + int max = conn->c_dn.bv_len + ? slap_conn_max_pending_auth + : slap_conn_max_pending; + #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, INFO, - "connection_input: conn %lu deferring operation\n", + "connection_input: conn %lu deferring operation\n", conn->c_connid, 0, 0 ); #else - Debug( LDAP_DEBUG_ANY, "deferring operation\n", 0, 0, 0 ); + Debug( LDAP_DEBUG_ANY, + "connection_input: conn=%lu deferring operation\n", + conn->c_connid, 0, 0 ); #endif conn->c_n_ops_pending++; LDAP_STAILQ_INSERT_TAIL( &conn->c_pending_ops, op, o_next ); @@ -1587,7 +1665,7 @@ connection_resched( Connection *conn ) if( rc ) { #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, DETAIL1, - "connection_resched: conn %lu reaquiring locks.\n", + "connection_resched: conn %lu reaquiring locks.\n", conn->c_connid, 0, 0 ); #else Debug( LDAP_DEBUG_TRACE, @@ -1607,7 +1685,7 @@ connection_resched( Connection *conn ) if( conn->c_conn_state != SLAP_C_CLOSING ) { #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, INFO, - "connection_resched: conn %lu closed by other thread.\n", + "connection_resched: conn %lu closed by other thread.\n", conn->c_connid, 0, 0 ); #else Debug( LDAP_DEBUG_TRACE, "connection_resched: " @@ -1617,7 +1695,7 @@ connection_resched( Connection *conn ) } else { #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, DETAIL1, - "connection_resched: conn %lu attempting closing.\n", + "connection_resched: conn %lu attempting closing.\n", conn->c_connid, 0, 0 ); #else Debug( LDAP_DEBUG_TRACE, "connection_resched: " @@ -1667,19 +1745,20 @@ static int connection_op_activate( Operation *op ) } if (!op->o_dn.bv_len) { - op->o_authz = op->o_conn->c_authz; - ber_dupbv( &op->o_dn, &op->o_conn->c_dn ); - ber_dupbv( &op->o_ndn, &op->o_conn->c_ndn ); + op->o_authz = op->o_conn->c_authz; + ber_dupbv( &op->o_dn, &op->o_conn->c_dn ); + ber_dupbv( &op->o_ndn, &op->o_conn->c_ndn ); } op->o_authtype = op->o_conn->c_authtype; ber_dupbv( &op->o_authmech, &op->o_conn->c_authmech ); if (!op->o_protocol) { - op->o_protocol = op->o_conn->c_protocol - ? op->o_conn->c_protocol : LDAP_VERSION3; + op->o_protocol = op->o_conn->c_protocol + ? op->o_conn->c_protocol : LDAP_VERSION3; } if (op->o_conn->c_conn_state == SLAP_C_INACTIVE - && op->o_protocol > LDAP_VERSION2) { + && op->o_protocol > LDAP_VERSION2) + { op->o_conn->c_conn_state = SLAP_C_ACTIVE; } @@ -1697,7 +1776,8 @@ static int connection_op_activate( Operation *op ) op->o_connid, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, - "ldap_pvt_thread_pool_submit failed (%d)\n", status, 0, 0 ); + "ldap_pvt_thread_pool_submit: failed (%d) for conn=%lu\n", + status, op->o_connid, 0 ); #endif /* should move op to pending list */ } @@ -1720,13 +1800,13 @@ int connection_write(ber_socket_t s) if( c == NULL ) { #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, ERR, - "connection_write: sock %ld no connection!\n", (long)s, 0, 0); + "connection_write: sock %ld no connection!\n", (long)s, 0, 0); #else Debug( LDAP_DEBUG_ANY, "connection_write(%ld): no connection!\n", - (long) s, 0, 0 ); + (long)s, 0, 0 ); #endif - slapd_remove(s, 0); + slapd_remove(s, 1, 0); ldap_pvt_thread_mutex_unlock( &connections_mutex ); return -1; } @@ -1735,7 +1815,7 @@ int connection_write(ber_socket_t s) #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, DETAIL1, - "connection_write conn %lu waking output.\n", c->c_connid, 0, 0 ); + "connection_write conn %lu waking output.\n", c->c_connid, 0, 0 ); #else Debug( LDAP_DEBUG_TRACE, "connection_write(%d): waking output for id=%lu\n", @@ -1743,10 +1823,12 @@ int connection_write(ber_socket_t s) #endif ldap_pvt_thread_cond_signal( &c->c_write_cv ); - if ( ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_NEEDS_READ, NULL ) ) + if ( ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_NEEDS_READ, NULL ) ) { slapd_set_read( s, 1 ); - if ( ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_NEEDS_WRITE, NULL ) ) + } + if ( ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_NEEDS_WRITE, NULL ) ) { slapd_set_write( s, 1 ); + } connection_return( c ); ldap_pvt_thread_mutex_unlock( &connections_mutex ); return 0; diff --git a/servers/slapd/controls.c b/servers/slapd/controls.c index 8bdecdeef3..16a9e3fcdc 100644 --- a/servers/slapd/controls.c +++ b/servers/slapd/controls.c @@ -986,7 +986,7 @@ static int parsePreRead ( } siz = sizeof( AttributeName ); - off = 0; + off = offsetof( AttributeName, an_name ); if ( ber_scanf( ber, "{M}", &an, &siz, off ) == LBER_ERROR ) { rs->sr_text = "preread control: decoding error"; return LDAP_PROTOCOL_ERROR; @@ -1035,7 +1035,7 @@ static int parsePostRead ( } siz = sizeof( AttributeName ); - off = 0; + off = offsetof( AttributeName, an_name ); if ( ber_scanf( ber, "{M}", &an, &siz, off ) == LBER_ERROR ) { rs->sr_text = "postread control: decoding error"; return LDAP_PROTOCOL_ERROR; @@ -1206,7 +1206,7 @@ static int parseLDAPsync ( BerElement *ber; ber_int_t mode; ber_len_t len; - struct berval cookie = { 0, NULL }; + struct slap_session_entry *se; if ( op->o_sync != SLAP_NO_CONTROL ) { rs->sr_text = "LDAP Sync control specified multiple times"; @@ -1255,22 +1255,25 @@ static int parseLDAPsync ( tag = ber_peek_tag( ber, &len ); - if ( tag == LDAP_SYNC_TAG_COOKIE ) { - if (( ber_scanf( ber, /*{*/ "m}", - &cookie )) == LBER_ERROR ) { + if ( tag == LDAP_TAG_SYNC_COOKIE ) { + struct berval tmp_bv; + if (( ber_scanf( ber, /*{*/ "o", &tmp_bv )) == LBER_ERROR ) { rs->sr_text = "LDAP Sync control : cookie decoding error"; return LDAP_PROTOCOL_ERROR; } - } else { - if (( ber_scanf( ber, /*{*/ "}")) == LBER_ERROR ) { - rs->sr_text = "LDAP Sync control : decoding error"; + ber_bvarray_add( &op->o_sync_state.octet_str, &tmp_bv ); + slap_parse_sync_cookie( &op->o_sync_state ); + } + if ( tag == LDAP_TAG_RELOAD_HINT ) { + if (( ber_scanf( ber, /*{*/ "b", &op->o_sync_rhint )) == LBER_ERROR ) { + rs->sr_text = "LDAP Sync control : rhint decoding error"; return LDAP_PROTOCOL_ERROR; } - cookie.bv_len = 0; - cookie.bv_val = NULL; } - - ber_dupbv( &op->o_sync_state, &cookie ); + if (( ber_scanf( ber, /*{*/ "}")) == LBER_ERROR ) { + rs->sr_text = "LDAP Sync control : decoding error"; + return LDAP_PROTOCOL_ERROR; + } (void) ber_free( ber, 1 ); diff --git a/servers/slapd/cr.c b/servers/slapd/cr.c index 24c546e364..6e33b5a728 100644 --- a/servers/slapd/cr.c +++ b/servers/slapd/cr.c @@ -16,8 +16,6 @@ #include "slap.h" #include "ldap_pvt.h" -#ifdef SLAP_EXTENDED_SCHEMA - struct cindexrec { struct berval cir_name; ContentRule *cir_cr; @@ -35,8 +33,7 @@ cr_index_cmp( const struct cindexrec *cir1 = v_cir1; const struct cindexrec *cir2 = v_cir2; int i = cir1->cir_name.bv_len - cir2->cir_name.bv_len; - if (i) - return i; + if (i) return i; return strcasecmp( cir1->cir_name.bv_val, cir2->cir_name.bv_val ); } @@ -48,8 +45,7 @@ cr_index_name_cmp( const struct berval *name = v_name; const struct cindexrec *cir = v_cir; int i = name->bv_len - cir->cir_name.bv_len; - if (i) - return i; + if (i) return i; return strncasecmp( name->bv_val, cir->cir_name.bv_val, name->bv_len ); } @@ -194,7 +190,11 @@ cr_add_auxiliaries( return SLAP_SCHERR_CLASS_NOT_FOUND; } - if( soc->soc_flags & SLAP_OC_OPERATIONAL ) (*op)++; + if( soc->soc_flags & SLAP_OC_OPERATIONAL && + soc != slap_schema.si_oc_extensibleObject ) + { + (*op)++; + } if( soc->soc_kind != LDAP_SCHEMA_AUXILIARY ) { *err = scr->scr_oc_oids_aux[naux]; @@ -203,7 +203,6 @@ cr_add_auxiliaries( } scr->scr_auxiliaries[naux] = NULL; - return 0; } @@ -387,18 +386,17 @@ cr_add( code = cr_create_precluded( scr, &op, err ); if ( code != 0 ) return code; - if( user && op ) return SLAP_SCHERR_CR_BAD_AUX; + if( user && op ) { + return SLAP_SCHERR_CR_BAD_AUX; + } code = cr_insert(scr,err); return code; } -#endif - int cr_schema_info( Entry *e ) { -#ifdef SLAP_EXTENDED_SCHEMA AttributeDescription *ad_ditContentRules = slap_schema.si_ad_ditContentRules; ContentRule *cr; @@ -428,6 +426,5 @@ cr_schema_info( Entry *e ) } ldap_memfree( val.bv_val ); } -#endif return 0; } diff --git a/servers/slapd/ctxcsn.c b/servers/slapd/ctxcsn.c index 459fc35583..71c7188bd3 100644 --- a/servers/slapd/ctxcsn.c +++ b/servers/slapd/ctxcsn.c @@ -26,7 +26,6 @@ #include #include -#include #include "ldap_pvt.h" #include "lutil.h" @@ -188,15 +187,13 @@ slap_get_csn( if ( csn == NULL ) return LDAP_OTHER; - if ( manage_ctxcsn ) { - pending = (struct slap_csn_entry *) ch_calloc( 1, sizeof( struct slap_csn_entry )); - } - csn->bv_len = lutil_csnstr( csnbuf, len, 0, 0 ); csn->bv_val = csnbuf; if ( manage_ctxcsn ) { + pending = (struct slap_csn_entry *) ch_calloc( 1, sizeof( struct slap_csn_entry )); ldap_pvt_thread_mutex_lock( &op->o_bd->be_pcl_mutex ); + ber_dupbv( &op->o_sync_csn, csn ); pending->csn = ber_dupbv( NULL, csn ); pending->connid = op->o_connid; pending->opid = op->o_opid; diff --git a/servers/slapd/daemon.c b/servers/slapd/daemon.c index c8283828bd..349e9a7580 100644 --- a/servers/slapd/daemon.c +++ b/servers/slapd/daemon.c @@ -195,8 +195,13 @@ void slapd_slp_dereg() { /* * Add a descriptor to daemon control + * + * If isactive, the descriptor is a live server session and is subject + * to idletimeout control. Otherwise, the descriptor is a passive + * listener or an outbound client session, and not subject to + * idletimeout. */ -static void slapd_add(ber_socket_t s) { +static void slapd_add(ber_socket_t s, int isactive) { ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex ); assert( !FD_ISSET( s, &slap_daemon.sd_actives )); @@ -209,7 +214,9 @@ static void slapd_add(ber_socket_t s) { } #endif - slap_daemon.sd_nactives++; + if ( isactive ) { + slap_daemon.sd_nactives++; + } FD_SET( s, &slap_daemon.sd_actives ); FD_SET( s, &slap_daemon.sd_readers ); @@ -231,10 +238,12 @@ static void slapd_add(ber_socket_t s) { /* * Remove the descriptor from daemon control */ -void slapd_remove(ber_socket_t s, int wake) { +void slapd_remove(ber_socket_t s, int wasactive, int wake) { ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex ); - slap_daemon.sd_nactives--; + if ( wasactive ) { + slap_daemon.sd_nactives--; + } #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, DETAIL1, @@ -1119,7 +1128,7 @@ close_listeners( for ( l = 0; slap_listeners[l] != NULL; l++ ) { if ( slap_listeners[l]->sl_sd != AC_SOCKET_INVALID ) { if ( remove ) - slapd_remove( slap_listeners[l]->sl_sd, 0 ); + slapd_remove( slap_listeners[l]->sl_sd, 0, 0 ); #ifdef LDAP_PF_LOCAL if ( slap_listeners[l]->sl_sa.sa_addr.sa_family == AF_LOCAL ) { unlink( slap_listeners[l]->sl_sa.sa_un_addr.sun_path ); @@ -1171,7 +1180,7 @@ slapd_daemon_task( * are unnecessary. */ if ( slap_listeners[l]->sl_is_udp ) { - slapd_add( slap_listeners[l]->sl_sd ); + slapd_add( slap_listeners[l]->sl_sd, 1 ); continue; } #endif @@ -1228,7 +1237,7 @@ slapd_daemon_task( return( (void*)-1 ); } - slapd_add( slap_listeners[l]->sl_sd ); + slapd_add( slap_listeners[l]->sl_sd, 0 ); } #ifdef HAVE_NT_SERVICE_MANAGER @@ -1332,11 +1341,6 @@ slapd_daemon_task( ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex ); - if ( !at ) { - at = ldap_pvt_thread_pool_backload(&connection_pool) - - ldap_pvt_runqueue_persistent_backload( &syncrepl_rq ); - } - if ( at #if defined(HAVE_YIELDING_SELECT) || defined(NO_THREADS) && ( tv.tv_sec || tv.tv_usec ) @@ -1350,15 +1354,15 @@ slapd_daemon_task( rtask = ldap_pvt_runqueue_next_sched( &syncrepl_rq, &cat ); while ( cat && cat->tv_sec && cat->tv_sec <= now ) { if ( ldap_pvt_runqueue_isrunning( &syncrepl_rq, rtask )) { - ldap_pvt_runqueue_resched( &syncrepl_rq, rtask ); + ldap_pvt_runqueue_resched( &syncrepl_rq, rtask, 0 ); } else { ldap_pvt_runqueue_runtask( &syncrepl_rq, rtask ); - ldap_pvt_runqueue_resched( &syncrepl_rq, rtask ); + ldap_pvt_runqueue_resched( &syncrepl_rq, rtask, 0 ); ldap_pvt_thread_mutex_unlock( &syncrepl_rq.rq_mutex ); ldap_pvt_thread_pool_submit( &connection_pool, rtask->routine, (void *) rtask ); + ldap_pvt_thread_mutex_lock( &syncrepl_rq.rq_mutex ); } - ldap_pvt_thread_mutex_lock( &syncrepl_rq.rq_mutex ); rtask = ldap_pvt_runqueue_next_sched( &syncrepl_rq, &cat ); } ldap_pvt_thread_mutex_unlock( &syncrepl_rq.rq_mutex ); @@ -1503,7 +1507,7 @@ slapd_daemon_task( id = connection_init( slap_listeners[l]->sl_sd, slap_listeners[l], "", "", - 2, ssf, authid ); + CONN_IS_UDP, ssf, authid ); slap_listeners[l]->sl_is_udp++; } continue; @@ -1733,7 +1737,7 @@ slapd_daemon_task( dnsname != NULL ? dnsname : SLAP_STRING_UNKNOWN, peername, #ifdef HAVE_TLS - slap_listeners[l]->sl_is_tls, + slap_listeners[l]->sl_is_tls ? CONN_IS_TLS : 0, #else 0, #endif @@ -1769,7 +1773,7 @@ slapd_daemon_task( slap_listeners[l]->sl_name.bv_val, 0 ); - slapd_add( s ); + slapd_add( s, 1 ); continue; } @@ -2077,19 +2081,11 @@ slap_sig_shutdown( int sig ) * SIGBREAK is generated when a user logs out. */ -#if 0 #if HAVE_NT_SERVICE_MANAGER && SIGBREAK if (is_NT_Service && sig == SIGBREAK) -#ifdef NEW_LOGGING - LDAP_LOG( CONNECTION, CRIT, - "slap_sig_shutdown: SIGBREAK ignored.\n", 0, 0, 0 ); -#else - Debug(LDAP_DEBUG_TRACE, "slap_sig_shutdown: SIGBREAK ignored.\n", - 0, 0, 0); -#endif + ; else #endif -#endif #ifdef SIGHUP if (sig == SIGHUP && global_gentlehup && slapd_gentle_shutdown == 0) slapd_gentle_shutdown = 1; @@ -2113,8 +2109,8 @@ slap_sig_wake( int sig ) } -void slapd_add_internal(ber_socket_t s) { - slapd_add(s); +void slapd_add_internal(ber_socket_t s, int isactive) { + slapd_add(s, isactive); } Listener ** slapd_get_listeners(void) { diff --git a/servers/slapd/delete.c b/servers/slapd/delete.c index 7c46560c4e..cebb526c04 100644 --- a/servers/slapd/delete.c +++ b/servers/slapd/delete.c @@ -40,10 +40,6 @@ do_delete( struct berval dn = { 0, NULL }; int manageDSAit; -#ifdef LDAP_SLAPI - Slapi_PBlock *pb = op->o_pb; -#endif - #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ENTRY, "do_delete: conn %d\n", op->o_connid, 0, 0 ); @@ -158,28 +154,31 @@ do_delete( } #if defined( LDAP_SLAPI ) - slapi_x_pblock_set_operation( pb, op ); - slapi_pblock_set( pb, SLAPI_DELETE_TARGET, (void *)dn.bv_val ); - slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)manageDSAit ); - - rs->sr_err = doPluginFNs( op->o_bd, SLAPI_PLUGIN_PRE_DELETE_FN, pb ); - if ( rs->sr_err < 0 ) { - /* - * A preoperation plugin failure will abort the - * entire operation. - */ +#define pb op->o_pb + if ( pb ) { + slapi_x_pblock_set_operation( pb, op ); + slapi_pblock_set( pb, SLAPI_DELETE_TARGET, (void *)dn.bv_val ); + slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)manageDSAit ); + + rs->sr_err = doPluginFNs( op->o_bd, SLAPI_PLUGIN_PRE_DELETE_FN, pb ); + if ( rs->sr_err < 0 ) { + /* + * A preoperation plugin failure will abort the + * entire operation. + */ #ifdef NEW_LOGGING - LDAP_LOG( OPERATION, INFO, "do_delete: delete preoperation plugin " - "failed\n", 0, 0, 0 ); + LDAP_LOG( OPERATION, INFO, "do_delete: delete preoperation plugin " + "failed\n", 0, 0, 0 ); #else - Debug (LDAP_DEBUG_TRACE, "do_delete: delete preoperation plugin failed.\n", - 0, 0, 0); + Debug (LDAP_DEBUG_TRACE, "do_delete: delete preoperation plugin failed.\n", + 0, 0, 0); #endif - if ( ( slapi_pblock_get( op->o_pb, SLAPI_RESULT_CODE, (void *)&rs->sr_err ) != 0 ) || - rs->sr_err == LDAP_SUCCESS ) { - rs->sr_err = LDAP_OTHER; + if ( ( slapi_pblock_get( pb, SLAPI_RESULT_CODE, (void *)&rs->sr_err ) != 0 ) || + rs->sr_err == LDAP_SUCCESS ) { + rs->sr_err = LDAP_OTHER; + } + goto cleanup; } - goto cleanup; } #endif /* defined( LDAP_SLAPI ) */ @@ -193,9 +192,10 @@ do_delete( /* do the update here */ int repl_user = be_isupdate( op->o_bd, &op->o_ndn ); #ifndef SLAPD_MULTIMASTER - if ( !op->o_bd->syncinfo && ( !op->o_bd->be_update_ndn.bv_len || repl_user )) + if ( !op->o_bd->be_syncinfo && + ( !op->o_bd->be_update_ndn.bv_len || repl_user )) #else - if ( !op->o_bd->syncinfo ) + if ( !op->o_bd->be_syncinfo ) #endif { @@ -216,11 +216,11 @@ do_delete( #ifndef SLAPD_MULTIMASTER } else { BerVarray defref = NULL; - if ( op->o_bd->syncinfo ) { - defref = op->o_bd->syncinfo->provideruri_bv; + if ( op->o_bd->be_syncinfo ) { + defref = op->o_bd->be_syncinfo->si_provideruri_bv; } else { defref = op->o_bd->be_update_refs - ? op->o_bd->be_update_refs : default_referral; + ? op->o_bd->be_update_refs : default_referral; } if ( defref != NULL ) { rs->sr_ref = referral_rewrite( defref, @@ -244,7 +244,7 @@ do_delete( } #if defined( LDAP_SLAPI ) - if ( doPluginFNs( op->o_bd, SLAPI_PLUGIN_POST_DELETE_FN, pb ) < 0) { + if ( pb && doPluginFNs( op->o_bd, SLAPI_PLUGIN_POST_DELETE_FN, pb ) < 0) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, INFO, "do_delete: delete postoperation plugins " "failed\n", 0, 0, 0 ); diff --git a/servers/slapd/dn.c b/servers/slapd/dn.c index 5696dbf837..348336f8a6 100644 --- a/servers/slapd/dn.c +++ b/servers/slapd/dn.c @@ -314,7 +314,7 @@ LDAPDN_rewrite( LDAPDN dn, unsigned flags, void *ctx ) * if value is empty, use empty_bv */ rc = ( *normf )( - 0, + SLAP_MR_VALUE_OF_ASSERTION_SYNTAX, ad->ad_type->sat_syntax, mr, ava->la_value.bv_len @@ -329,8 +329,10 @@ LDAPDN_rewrite( LDAPDN dn, unsigned flags, void *ctx ) if( bv.bv_val ) { - ber_memfree_x( ava->la_value.bv_val, ctx ); + if ( ava->la_flags & LDAP_AVA_FREE_VALUE ) + ber_memfree_x( ava->la_value.bv_val, ctx ); ava->la_value = bv; + ava->la_flags |= LDAP_AVA_FREE_VALUE; } if( do_sort ) AVA_Sort( rdn, iAVA ); @@ -882,7 +884,12 @@ int dnX509normalize( void *x509_name, struct berval *out ) { /* Invoke the LDAP library's converter with our schema-rewriter */ - return ldap_X509dn2bv( x509_name, out, LDAPDN_rewrite, 0 ); + int rc = ldap_X509dn2bv( x509_name, out, LDAPDN_rewrite, 0 ); + + Debug( LDAP_DEBUG_TRACE, + "dnX509Normalize: <%s>\n", out->bv_val, 0, 0 ); + + return rc; } /* diff --git a/servers/slapd/entry.c b/servers/slapd/entry.c index 35e3cd47dc..01b22e62bc 100644 --- a/servers/slapd/entry.c +++ b/servers/slapd/entry.c @@ -66,9 +66,10 @@ str2entry( char *s ) */ #ifdef NEW_LOGGING - LDAP_LOG( OPERATION, DETAIL1, "str2entry: \"%s\"\n", s ? s : "NULL", 0, 0 ); + LDAP_LOG( OPERATION, DETAIL1, "str2entry: \"%s\"\n", + s ? s : "NULL", 0, 0 ); #else - Debug( LDAP_DEBUG_TRACE, "=> str2entry\n", + Debug( LDAP_DEBUG_TRACE, "=> str2entry: \"%s\"\n", s ? s : "NULL", 0, 0 ); #endif diff --git a/servers/slapd/filterentry.c b/servers/slapd/filterentry.c index b8a7964fc2..0086b34ab0 100644 --- a/servers/slapd/filterentry.c +++ b/servers/slapd/filterentry.c @@ -218,12 +218,13 @@ static int test_mra_filter( /* If ma_rule is not the same as the attribute's * normal rule, then we can't use the a_nvals. */ - if (mra->ma_rule == a->a_desc->ad_type->sat_equality) + if (mra->ma_rule == a->a_desc->ad_type->sat_equality) { bv = a->a_nvals; - else + } else { bv = a->a_vals; - for ( ; bv->bv_val != NULL; bv++ ) - { + } + + for ( ; bv->bv_val != NULL; bv++ ) { int ret; int rc; const char *text; diff --git a/servers/slapd/globals.c b/servers/slapd/globals.c index fdc4c823a2..1869805805 100644 --- a/servers/slapd/globals.c +++ b/servers/slapd/globals.c @@ -25,3 +25,5 @@ const struct berval slap_unknown_bv = BER_BVC("unknown"); /* normalized boolean values */ const struct berval slap_true_bv = BER_BVC("TRUE"); const struct berval slap_false_bv = BER_BVC("FALSE"); + +struct sync_cookie *slap_sync_cookie = NULL; diff --git a/servers/slapd/ldapsync.c b/servers/slapd/ldapsync.c new file mode 100644 index 0000000000..7d62ef860f --- /dev/null +++ b/servers/slapd/ldapsync.c @@ -0,0 +1,500 @@ +/* $OpenLDAP$ */ +/* + * LDAP Content Sync Routines + */ +/* + * Copyright 2003 The OpenLDAP Foundation, All Rights Reserved. + * COPYING RESTRICTIONS APPLY, see COPYRIGHT file + */ +/* Copyright (c) 2003 by International Business Machines, Inc. + * + * International Business Machines, Inc. (hereinafter called IBM) grants + * permission under its copyrights to use, copy, modify, and distribute this + * Software with or without fee, provided that the above copyright notice and + * all paragraphs of this notice appear in all copies, and that the name of IBM + * not be used in connection with the marketing of any product incorporating + * the Software or modifications thereof, without specific, written prior + * permission. + * + * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, + * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN + * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +#include "portable.h" + +#include + +#include +#include + +#include "ldap_pvt.h" +#include "lutil.h" +#include "slap.h" +#include "lutil_ldap.h" + +int +slap_build_sync_state_ctrl( + Operation *op, + SlapReply *rs, + Entry *e, + int entry_sync_state, + LDAPControl **ctrls, + int num_ctrls, + int send_cookie, + struct berval *cookie) +{ + Attribute* a; + int ret; + int res; + const char *text = NULL; + + BerElementBuffer berbuf; + BerElement *ber = (BerElement *)&berbuf; + + struct berval entryuuid_bv = { 0, NULL }; + + ber_init2( ber, 0, LBER_USE_DER ); + ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx ); + + ctrls[num_ctrls] = sl_malloc ( sizeof ( LDAPControl ), op->o_tmpmemctx ); + + for ( a = e->e_attrs; a != NULL; a = a->a_next ) { + AttributeDescription *desc = a->a_desc; + if ( desc == slap_schema.si_ad_entryUUID ) { + ber_dupbv( &entryuuid_bv, &a->a_nvals[0] ); + } + } + + if ( send_cookie && cookie ) { + ber_printf( ber, "{eOON}", + entry_sync_state, &entryuuid_bv, cookie ); + } else { + ber_printf( ber, "{eON}", + entry_sync_state, &entryuuid_bv ); + } + + ch_free( entryuuid_bv.bv_val ); + entryuuid_bv.bv_val = NULL; + + ctrls[num_ctrls]->ldctl_oid = LDAP_CONTROL_SYNC_STATE; + ctrls[num_ctrls]->ldctl_iscritical = op->o_sync; + ret = ber_flatten2( ber, &ctrls[num_ctrls]->ldctl_value, 1 ); + + ber_free_buf( ber ); + + if ( ret < 0 ) { +#ifdef NEW_LOGGING + LDAP_LOG ( OPERATION, RESULTS, + "slap_build_sync_ctrl: ber_flatten2 failed\n", + 0, 0, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, + "slap_build_sync_ctrl: ber_flatten2 failed\n", + 0, 0, 0 ); +#endif + send_ldap_error( op, rs, LDAP_OTHER, "internal error" ); + return ret; + } + + return LDAP_SUCCESS; +} + +int +slap_build_sync_done_ctrl( + Operation *op, + SlapReply *rs, + LDAPControl **ctrls, + int num_ctrls, + int send_cookie, + struct berval *cookie, + int refreshDeletes ) +{ + int ret; + BerElementBuffer berbuf; + BerElement *ber = (BerElement *)&berbuf; + + ber_init2( ber, NULL, LBER_USE_DER ); + ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx ); + + ctrls[num_ctrls] = ch_malloc ( sizeof ( LDAPControl ) ); + + ber_printf( ber, "{" ); + if ( send_cookie && cookie ) { + ber_printf( ber, "O", cookie ); + } + if ( refreshDeletes == LDAP_SYNC_REFRESH_DELETES ) { + ber_printf( ber, "b", refreshDeletes ); + } + ber_printf( ber, "N}" ); + + ctrls[num_ctrls]->ldctl_oid = LDAP_CONTROL_SYNC_DONE; + ctrls[num_ctrls]->ldctl_iscritical = op->o_sync; + ret = ber_flatten2( ber, &ctrls[num_ctrls]->ldctl_value, 1 ); + + ber_free_buf( ber ); + + if ( ret < 0 ) { +#ifdef NEW_LOGGING + LDAP_LOG ( OPERATION, RESULTS, + "slap_build_sync_done_ctrl: ber_flatten2 failed\n", + 0, 0, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, + "slap_build_sync_done_ctrl: ber_flatten2 failed\n", + 0, 0, 0 ); +#endif + send_ldap_error( op, rs, LDAP_OTHER, "internal error" ); + return ret; + } + + return LDAP_SUCCESS; +} + + +int +slap_build_sync_state_ctrl_from_slog( + Operation *op, + SlapReply *rs, + struct slog_entry *slog_e, + int entry_sync_state, + LDAPControl **ctrls, + int num_ctrls, + int send_cookie, + struct berval *cookie) +{ + Attribute* a; + int ret; + int res; + const char *text = NULL; + + BerElementBuffer berbuf; + BerElement *ber = (BerElement *)&berbuf; + + struct berval entryuuid_bv = { 0, NULL }; + + ber_init2( ber, NULL, LBER_USE_DER ); + ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx ); + + ctrls[num_ctrls] = ch_malloc ( sizeof ( LDAPControl ) ); + + ber_dupbv( &entryuuid_bv, &slog_e->sl_uuid ); + + if ( send_cookie && cookie ) { + ber_printf( ber, "{eOON}", + entry_sync_state, &entryuuid_bv, cookie ); + } else { + ber_printf( ber, "{eON}", + entry_sync_state, &entryuuid_bv ); + } + + ch_free( entryuuid_bv.bv_val ); + entryuuid_bv.bv_val = NULL; + + ctrls[num_ctrls]->ldctl_oid = LDAP_CONTROL_SYNC_STATE; + ctrls[num_ctrls]->ldctl_iscritical = op->o_sync; + ret = ber_flatten2( ber, &ctrls[num_ctrls]->ldctl_value, 1 ); + + ber_free_buf( ber ); + + if ( ret < 0 ) { +#ifdef NEW_LOGGING + LDAP_LOG ( OPERATION, RESULTS, + "slap_build_sync_ctrl: ber_flatten2 failed\n", + 0, 0, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, + "slap_build_sync_ctrl: ber_flatten2 failed\n", + 0, 0, 0 ); +#endif + send_ldap_error( op, rs, LDAP_OTHER, "internal error" ); + return ret; + } + + return LDAP_SUCCESS; +} + +int +slap_send_syncinfo( + Operation *op, + SlapReply *rs, + int type, + struct berval *cookie, + int refreshDone, + BerVarray syncUUIDs, + int refreshDeletes ) +{ + BerElementBuffer berbuf; + BerElement *ber = (BerElement *)&berbuf; + struct berval rspdata; + + int ret; + + ber_init2( ber, NULL, LBER_USE_DER ); + ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx ); + + if ( type ) { + switch ( type ) { + case LDAP_TAG_SYNC_NEW_COOKIE: + ber_printf( ber, "tO", type, cookie ); + break; + case LDAP_TAG_SYNC_REFRESH_DELETE: + case LDAP_TAG_SYNC_REFRESH_PRESENT: + ber_printf( ber, "t{", type ); + if ( cookie ) { + ber_printf( ber, "O", cookie ); + } + if ( refreshDone == 0 ) { + ber_printf( ber, "b", refreshDone ); + } + ber_printf( ber, "N}" ); + break; + case LDAP_TAG_SYNC_ID_SET: + ber_printf( ber, "t{", type ); + if ( cookie ) { + ber_printf( ber, "O", cookie ); + } + if ( refreshDeletes == 1 ) { + ber_printf( ber, "b", refreshDeletes ); + } + ber_printf( ber, "[W]", syncUUIDs ); + ber_printf( ber, "N}" ); + break; + default: +#ifdef NEW_LOGGING + LDAP_LOG ( OPERATION, RESULTS, + "slap_send_syncinfo: invalid syncinfo type (%d)\n", + type, 0, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, + "slap_send_syncinfo: invalid syncinfo type (%d)\n", + type, 0, 0 ); +#endif + return LDAP_OTHER; + } + } + + ret = ber_flatten2( ber, &rspdata, 0 ); + + if ( ret < 0 ) { +#ifdef NEW_LOGGING + LDAP_LOG ( OPERATION, RESULTS, + "slap_send_syncinfo: ber_flatten2 failed\n", + 0, 0, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, + "slap_send_syncinfo: ber_flatten2 failed\n", + 0, 0, 0 ); +#endif + send_ldap_error( op, rs, LDAP_OTHER, "internal error" ); + return ret; + } + + rs->sr_rspdata = &rspdata; + send_ldap_intermediate( op, rs ); + rs->sr_rspdata = NULL; + ber_free_buf( ber ); + + return LDAP_SUCCESS; +} + +void +slap_compose_sync_cookie( + Operation *op, + struct berval *cookie, + struct berval *csn, + int sid ) +{ + char cookiestr[ LDAP_LUTIL_CSNSTR_BUFSIZE + 10 ]; + + if ( csn->bv_val == NULL ) { + if ( sid == -1 ) { + cookiestr[0] = '\0'; + } else { + snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 10, + "sid=%03d", sid ); + } + } else if ( sid == -1 ) { + snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 10, + "csn=%s", csn->bv_val ); + } else { + snprintf( cookiestr, LDAP_LUTIL_CSNSTR_BUFSIZE + 10, + "csn=%s,sid=%03d", csn->bv_val, sid ); + } + ber_str2bv( cookiestr, strlen(cookiestr), 1, cookie ); +} + +void +slap_sync_cookie_free( + struct sync_cookie *cookie, + int free_cookie +) +{ + if ( cookie == NULL ) + return; + + if ( cookie->ctxcsn ) { + ber_bvarray_free( cookie->ctxcsn ); + cookie->ctxcsn = NULL; + } + + if ( cookie->octet_str ) { + ber_bvarray_free( cookie->octet_str ); + cookie->octet_str = NULL; + } + + if ( free_cookie ) { + ch_free( cookie ); + } + + return; +} + +int +slap_parse_sync_cookie( + struct sync_cookie *cookie +) +{ + char *csn_ptr; + char *csn_str; + int csn_str_len; + char *sid_ptr; + char *sid_str; + char *cval; + struct berval *ctxcsn; + + if ( cookie == NULL ) + return -1; + + if (( csn_ptr = strstr( cookie->octet_str[0].bv_val, "csn=" )) != NULL ) { + csn_str = (char *) SLAP_STRNDUP( csn_ptr, LDAP_LUTIL_CSNSTR_BUFSIZE ); + if ( cval = strchr( csn_str, ',' )) { + *cval = '\0'; + csn_str_len = cval - csn_str - (sizeof("csn=") - 1); + } else { + csn_str_len = cookie->octet_str[0].bv_len - + (csn_ptr - cookie->octet_str[0].bv_val) - + (sizeof("csn=") - 1); + } + ctxcsn = ber_str2bv( csn_str + (sizeof("csn=")-1), + csn_str_len, 1, NULL ); + ch_free( csn_str ); + ber_bvarray_add( &cookie->ctxcsn, ctxcsn ); + ch_free( ctxcsn ); + } else { + cookie->ctxcsn = NULL; + } + + if (( sid_ptr = strstr( cookie->octet_str->bv_val, "sid=" )) != NULL ) { + sid_str = (char *) SLAP_STRNDUP( sid_ptr, + SLAP_SYNC_SID_SIZE + sizeof("sid=") - 1 ); + if ( cval = strchr( sid_str, ',' )) { + *cval = '\0'; + } + cookie->sid = atoi( sid_str + sizeof("sid=") - 1 ); + ch_free( sid_str ); + } else { + cookie->sid = -1; + } +} + +int +slap_init_sync_cookie_ctxcsn( + struct sync_cookie *cookie +) +{ + char csnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE + 4 ]; + struct berval octet_str = { 0, NULL }; + struct berval ctxcsn = { 0, NULL }; + struct berval ctxcsn_dup = { 0, NULL }; + struct berval slap_syncCookie; + + if ( cookie == NULL ) + return -1; + + octet_str.bv_len = snprintf( csnbuf, LDAP_LUTIL_CSNSTR_BUFSIZE + 4, + "csn=%4d%02d%02d%02d%02d%02dZ#%06x#%02x#%06x", + 1900, 1, 1, 0, 0, 0, 0, 0, 0 ); + octet_str.bv_val = csnbuf; + build_new_dn( &slap_syncCookie, &cookie->octet_str[0], &octet_str, NULL ); + ber_bvarray_free( cookie->octet_str ); + cookie->octet_str = NULL; + ber_bvarray_add( &cookie->octet_str, &slap_syncCookie ); + + ber_dupbv( &ctxcsn, &octet_str ); + ctxcsn.bv_val += 4; + ctxcsn.bv_len -= 4; + ber_dupbv( &ctxcsn_dup, &ctxcsn ); + ch_free( ctxcsn.bv_val ); + ber_bvarray_add( &cookie->ctxcsn, &ctxcsn_dup ); + + return 0; +} + +struct sync_cookie * +slap_dup_sync_cookie( + struct sync_cookie *dst, + struct sync_cookie *src +) +{ + int i; + struct sync_cookie *new; + struct berval tmp_bv; + + if ( src == NULL ) + return NULL; + + if ( dst ) { + ber_bvarray_free( dst->ctxcsn ); + ber_bvarray_free( dst->octet_str ); + new = dst; + } else { + new = ( struct sync_cookie * ) + ch_calloc( 1, sizeof( struct sync_cookie )); + } + + new->sid = src->sid; + + if ( src->ctxcsn ) { + for ( i=0; src->ctxcsn[i].bv_val; i++ ) { + ber_dupbv( &tmp_bv, &src->ctxcsn[i] ); + ber_bvarray_add( &new->ctxcsn, &tmp_bv ); + } + } + + if ( src->octet_str ) { + for ( i=0; src->octet_str[i].bv_val; i++ ) { + ber_dupbv( &tmp_bv, &src->octet_str[i] ); + ber_bvarray_add( &new->octet_str, &tmp_bv ); + } + } + + return new; +} + +int +slap_build_syncUUID_set( + Operation *op, + BerVarray *set, + Entry *e +) +{ + int ret; + Attribute* a; + + struct berval entryuuid_bv = { 0, NULL }; + + for ( a = e->e_attrs; a != NULL; a = a->a_next ) { + AttributeDescription *desc = a->a_desc; + if ( desc == slap_schema.si_ad_entryUUID ) { + ber_dupbv_x( &entryuuid_bv, &a->a_nvals[0], op->o_tmpmemctx ); + } + } + + ret = ber_bvarray_add_x( set, &entryuuid_bv, op->o_tmpmemctx ); + + return ret; +} diff --git a/servers/slapd/main.c b/servers/slapd/main.c index 61dc82e121..c15dee8c1d 100644 --- a/servers/slapd/main.c +++ b/servers/slapd/main.c @@ -92,6 +92,7 @@ usage( char *name ) fprintf( stderr, "\t-4\t\tIPv4 only\n" "\t-6\t\tIPv6 only\n" + "\t-c cookie\tSync cookie of consumer\n" "\t-d level\tDebug level" "\n" "\t-f filename\tConfiguration file\n" #if defined(HAVE_SETUID) && defined(HAVE_SETGID) @@ -144,6 +145,8 @@ int main( int argc, char **argv ) char *serverName = NULL; int serverMode = SLAP_SERVER_MODE; + struct berval cookie = { 0, NULL }; + #ifdef CSRIMALLOC FILE *leakfile; if( ( leakfile = fopen( "slapd.leak", "w" )) == NULL ) { @@ -214,7 +217,7 @@ int main( int argc, char **argv ) #endif while ( (i = getopt( argc, argv, - "d:f:h:s:n:t" + "c:d:f:h:s:n:t" #if LDAP_PF_INET6 "46" #endif @@ -243,6 +246,16 @@ int main( int argc, char **argv ) urls = ch_strdup( optarg ); break; + case 'c': /* provide sync cookie, override if exist in replica */ + if ( slap_sync_cookie ) { + slap_sync_cookie_free( slap_sync_cookie, 1 ); + } + slap_sync_cookie = (struct sync_cookie *) ch_calloc( 1, + sizeof( struct sync_cookie )); + ber_str2bv( optarg, strlen( optarg ), 1, &cookie ); + ber_bvarray_add( &slap_sync_cookie->octet_str, &cookie ); + break; + case 'd': /* set debug level and 'do not detach' flag */ no_detach = 1; #ifdef LDAP_DEBUG diff --git a/servers/slapd/modify.c b/servers/slapd/modify.c index ac412159c1..eebb174c0d 100644 --- a/servers/slapd/modify.c +++ b/servers/slapd/modify.c @@ -47,7 +47,6 @@ do_modify( #endif #ifdef LDAP_SLAPI LDAPMod **modv = NULL; - Slapi_PBlock *pb = op->o_pb; #endif int manageDSAit; int increment = 0; @@ -316,8 +315,15 @@ do_modify( if (len + 1 + tmp->sml_type.bv_len > sizeof(abuf)) { Statslog( LDAP_DEBUG_STATS, "conn=%lu op=%lu MOD attr=%s\n", op->o_connid, op->o_opid, abuf, 0, 0 ); - len = 0; + + len = 0; ptr = abuf; + + if( 1 + tmp->sml_type.bv_len > sizeof(abuf)) { + Statslog( LDAP_DEBUG_STATS, "conn=%lu op=%lu MOD attr=%s\n", + op->o_connid, op->o_opid, tmp->sml_type.bv_val, 0, 0 ); + continue; + } } if (len) { *ptr++ = ' '; @@ -376,44 +382,47 @@ do_modify( } #if defined( LDAP_SLAPI ) - slapi_x_pblock_set_operation( pb, op ); - slapi_pblock_set( pb, SLAPI_MODIFY_TARGET, (void *)dn.bv_val ); - slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)manageDSAit ); - modv = slapi_x_modifications2ldapmods( &modlist ); - slapi_pblock_set( pb, SLAPI_MODIFY_MODS, (void *)modv ); - - rs->sr_err = doPluginFNs( op->o_bd, SLAPI_PLUGIN_PRE_MODIFY_FN, pb ); - if ( rs->sr_err < 0 ) { - /* - * A preoperation plugin failure will abort the - * entire operation. - */ +#define pb op->o_pb + if ( pb ) { + slapi_x_pblock_set_operation( pb, op ); + slapi_pblock_set( pb, SLAPI_MODIFY_TARGET, (void *)dn.bv_val ); + slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)manageDSAit ); + modv = slapi_x_modifications2ldapmods( &modlist ); + slapi_pblock_set( pb, SLAPI_MODIFY_MODS, (void *)modv ); + + rs->sr_err = doPluginFNs( op->o_bd, SLAPI_PLUGIN_PRE_MODIFY_FN, pb ); + if ( rs->sr_err < 0 ) { + /* + * A preoperation plugin failure will abort the + * entire operation. + */ #ifdef NEW_LOGGING - LDAP_LOG( OPERATION, INFO, "do_modify: modify preoperation plugin " - "failed\n", 0, 0, 0 ); + LDAP_LOG( OPERATION, INFO, "do_modify: modify preoperation plugin " + "failed\n", 0, 0, 0 ); #else - Debug(LDAP_DEBUG_TRACE, "do_modify: modify preoperation plugin failed.\n", - 0, 0, 0); + Debug(LDAP_DEBUG_TRACE, "do_modify: modify preoperation plugin failed.\n", + 0, 0, 0); #endif - if ( ( slapi_pblock_get( op->o_pb, SLAPI_RESULT_CODE, (void *)&rs->sr_err ) != 0 ) || - rs->sr_err == LDAP_SUCCESS ) { - rs->sr_err = LDAP_OTHER; + if ( ( slapi_pblock_get( op->o_pb, SLAPI_RESULT_CODE, (void *)&rs->sr_err ) != 0 ) || + rs->sr_err == LDAP_SUCCESS ) { + rs->sr_err = LDAP_OTHER; + } + slapi_x_free_ldapmods( modv ); + modv = NULL; + goto cleanup; } - slapi_x_free_ldapmods( modv ); - modv = NULL; - goto cleanup; - } - /* - * It's possible that the preoperation plugin changed the - * modification array, so we need to convert it back to - * a Modification list. - * - * Calling slapi_x_modifications2ldapmods() destroyed modlist so - * we don't need to free it. - */ - slapi_pblock_get( pb, SLAPI_MODIFY_MODS, (void **)&modv ); - modlist = slapi_x_ldapmods2modifications( modv ); + /* + * It's possible that the preoperation plugin changed the + * modification array, so we need to convert it back to + * a Modification list. + * + * Calling slapi_x_modifications2ldapmods() destroyed modlist so + * we don't need to free it. + */ + slapi_pblock_get( pb, SLAPI_MODIFY_MODS, (void **)&modv ); + modlist = slapi_x_ldapmods2modifications( modv ); + } /* * NB: it is valid for the plugin to return no modifications @@ -446,10 +455,10 @@ do_modify( * because it accepts each modify request */ #ifndef SLAPD_MULTIMASTER - if ( !op->o_bd->syncinfo && + if ( !op->o_bd->be_syncinfo && ( !op->o_bd->be_update_ndn.bv_len || repl_user )) #else - if ( !op->o_bd->syncinfo ) + if ( !op->o_bd->be_syncinfo ) #endif { int update = op->o_bd->be_update_ndn.bv_len; @@ -494,8 +503,8 @@ do_modify( /* send a referral */ } else { BerVarray defref = NULL; - if ( op->o_bd->syncinfo ) { - defref = op->o_bd->syncinfo->provideruri_bv; + if ( op->o_bd->be_syncinfo ) { + defref = op->o_bd->be_syncinfo->si_provideruri_bv; } else { defref = op->o_bd->be_update_refs ? op->o_bd->be_update_refs : default_referral; @@ -525,7 +534,7 @@ do_modify( #if defined( LDAP_SLAPI ) } /* modlist != NULL */ - if ( doPluginFNs( op->o_bd, SLAPI_PLUGIN_POST_MODIFY_FN, pb ) < 0 ) { + if ( pb && doPluginFNs( op->o_bd, SLAPI_PLUGIN_POST_MODIFY_FN, pb ) < 0 ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, INFO, "do_modify: modify postoperation plugins " "failed\n", 0, 0, 0 ); @@ -727,7 +736,7 @@ int slap_mods_check( for( nvals = 0; ml->sml_values[nvals].bv_val; nvals++ ) { rc = ad->ad_type->sat_equality->smr_normalize( - 0, + SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, ad->ad_type->sat_syntax, ad->ad_type->sat_equality, &ml->sml_values[nvals], &ml->sml_nvalues[nvals], ctx ); @@ -841,12 +850,20 @@ int slap_mods_opattrs( mod->sml_type.bv_val = NULL; mod->sml_desc = slap_schema.si_ad_entryUUID; mod->sml_values = - (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); + (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); ber_dupbv( &mod->sml_values[0], &tmpval ); mod->sml_values[1].bv_len = 0; mod->sml_values[1].bv_val = NULL; assert( mod->sml_values[0].bv_val ); - mod->sml_nvalues = NULL; + mod->sml_nvalues = + (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); + (*mod->sml_desc->ad_type->sat_equality->smr_normalize)( + SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, + mod->sml_desc->ad_type->sat_syntax, + mod->sml_desc->ad_type->sat_equality, + mod->sml_values, mod->sml_nvalues, NULL ); + mod->sml_nvalues[1].bv_len = 0; + mod->sml_nvalues[1].bv_val = NULL; *modtail = mod; modtail = &mod->sml_next; @@ -854,7 +871,8 @@ int slap_mods_opattrs( mod->sml_op = mop; mod->sml_type.bv_val = NULL; mod->sml_desc = slap_schema.si_ad_creatorsName; - mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); + mod->sml_values = + (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); ber_dupbv( &mod->sml_values[0], &name ); mod->sml_values[1].bv_len = 0; mod->sml_values[1].bv_val = NULL; @@ -872,7 +890,8 @@ int slap_mods_opattrs( mod->sml_op = mop; mod->sml_type.bv_val = NULL; mod->sml_desc = slap_schema.si_ad_createTimestamp; - mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); + mod->sml_values = + (BerVarray) ch_malloc( 2 * sizeof( struct berval ) ); ber_dupbv( &mod->sml_values[0], ×tamp ); mod->sml_values[1].bv_len = 0; mod->sml_values[1].bv_val = NULL; diff --git a/servers/slapd/modrdn.c b/servers/slapd/modrdn.c index f780dd3aa2..f63aca9d56 100644 --- a/servers/slapd/modrdn.c +++ b/servers/slapd/modrdn.c @@ -60,10 +60,6 @@ do_modrdn( ber_len_t length; int manageDSAit; -#ifdef LDAP_SLAPI - Slapi_PBlock *pb = op->o_pb; -#endif - #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ENTRY, "do_modrdn: begin\n", 0, 0, 0 ); #else @@ -315,32 +311,35 @@ do_modrdn( } #if defined( LDAP_SLAPI ) - slapi_x_pblock_set_operation( pb, op ); - slapi_pblock_set( pb, SLAPI_MODRDN_TARGET, (void *)dn.bv_val ); - slapi_pblock_set( pb, SLAPI_MODRDN_NEWRDN, (void *)newrdn.bv_val ); - slapi_pblock_set( pb, SLAPI_MODRDN_NEWSUPERIOR, - (void *)newSuperior.bv_val ); - slapi_pblock_set( pb, SLAPI_MODRDN_DELOLDRDN, (void *)deloldrdn ); - slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)manageDSAit ); - - rs->sr_err = doPluginFNs( op->o_bd, SLAPI_PLUGIN_PRE_MODRDN_FN, pb ); - if ( rs->sr_err < 0 ) { - /* - * A preoperation plugin failure will abort the - * entire operation. - */ +#define pb op->o_pb + if ( pb ) { + slapi_x_pblock_set_operation( pb, op ); + slapi_pblock_set( pb, SLAPI_MODRDN_TARGET, (void *)dn.bv_val ); + slapi_pblock_set( pb, SLAPI_MODRDN_NEWRDN, (void *)newrdn.bv_val ); + slapi_pblock_set( pb, SLAPI_MODRDN_NEWSUPERIOR, + (void *)newSuperior.bv_val ); + slapi_pblock_set( pb, SLAPI_MODRDN_DELOLDRDN, (void *)deloldrdn ); + slapi_pblock_set( pb, SLAPI_MANAGEDSAIT, (void *)manageDSAit ); + + rs->sr_err = doPluginFNs( op->o_bd, SLAPI_PLUGIN_PRE_MODRDN_FN, pb ); + if ( rs->sr_err < 0 ) { + /* + * A preoperation plugin failure will abort the + * entire operation. + */ #ifdef NEW_LOGGING - LDAP_LOG( OPERATION, INFO, "do_modrdn: modrdn preoperation plugin " - "failed\n", 0, 0, 0 ); + LDAP_LOG( OPERATION, INFO, "do_modrdn: modrdn preoperation plugin " + "failed\n", 0, 0, 0 ); #else - Debug(LDAP_DEBUG_TRACE, "do_modrdn: modrdn preoperation plugin " - "failed.\n", 0, 0, 0); + Debug(LDAP_DEBUG_TRACE, "do_modrdn: modrdn preoperation plugin " + "failed.\n", 0, 0, 0); #endif - if ( ( slapi_pblock_get( pb, SLAPI_RESULT_CODE, (void *)&rs->sr_err ) != 0 ) || - rs->sr_err == LDAP_SUCCESS ) { - rs->sr_err = LDAP_OTHER; + if ( ( slapi_pblock_get( pb, SLAPI_RESULT_CODE, (void *)&rs->sr_err ) != 0 ) || + rs->sr_err == LDAP_SUCCESS ) { + rs->sr_err = LDAP_OTHER; + } + goto cleanup; } - goto cleanup; } #endif /* defined( LDAP_SLAPI ) */ @@ -354,10 +353,10 @@ do_modrdn( /* do the update here */ int repl_user = be_isupdate( op->o_bd, &op->o_ndn ); #ifndef SLAPD_MULTIMASTER - if ( !op->o_bd->syncinfo && - ( !op->o_bd->be_update_ndn.bv_len || repl_user )) + if ( !op->o_bd->be_syncinfo && + ( !op->o_bd->be_update_ndn.bv_len || repl_user )) #else - if ( !op->o_bd->syncinfo ) + if ( !op->o_bd->be_syncinfo ) #endif { op->orr_deleteoldrdn = deloldrdn; @@ -371,11 +370,11 @@ do_modrdn( #ifndef SLAPD_MULTIMASTER } else { BerVarray defref = NULL; - if ( op->o_bd->syncinfo ) { - defref = op->o_bd->syncinfo->provideruri_bv; + if ( op->o_bd->be_syncinfo ) { + defref = op->o_bd->be_syncinfo->si_provideruri_bv; } else { defref = op->o_bd->be_update_refs - ? op->o_bd->be_update_refs : default_referral; + ? op->o_bd->be_update_refs : default_referral; } if ( defref != NULL ) { rs->sr_ref = referral_rewrite( defref, @@ -399,7 +398,7 @@ do_modrdn( } #if defined( LDAP_SLAPI ) - if ( doPluginFNs( op->o_bd, SLAPI_PLUGIN_POST_MODRDN_FN, pb ) < 0 ) { + if ( pb && doPluginFNs( op->o_bd, SLAPI_PLUGIN_POST_MODRDN_FN, pb ) < 0 ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, INFO, "do_modrdn: modrdn postoperation plugins " "failed\n", 0, 0, 0 ); @@ -495,7 +494,7 @@ slap_modrdn2mods( if( desc->ad_type->sat_equality->smr_normalize) { mod_tmp->sml_nvalues = &mod_tmp->sml_values[2]; (void) (*desc->ad_type->sat_equality->smr_normalize)( - SLAP_MR_EQUALITY, + SLAP_MR_EQUALITY|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX, desc->ad_type->sat_syntax, desc->ad_type->sat_equality, &mod_tmp->sml_values[0], @@ -564,7 +563,7 @@ slap_modrdn2mods( if( desc->ad_type->sat_equality->smr_normalize) { mod_tmp->sml_nvalues = &mod_tmp->sml_values[2]; (void) (*desc->ad_type->sat_equality->smr_normalize)( - SLAP_MR_EQUALITY, + SLAP_MR_EQUALITY|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX, desc->ad_type->sat_syntax, desc->ad_type->sat_equality, &mod_tmp->sml_values[0], diff --git a/servers/slapd/mods.c b/servers/slapd/mods.c index 02d4bcb207..f2c7319db5 100644 --- a/servers/slapd/mods.c +++ b/servers/slapd/mods.c @@ -216,6 +216,7 @@ modify_delete_values( Attribute *a; MatchingRule *mr = mod->sm_desc->ad_type->sat_equality; char dummy = '\0'; + int match = 0; /* * If permissive is set, then the non-existence of an @@ -264,7 +265,6 @@ modify_delete_values( for ( i = 0; mod->sm_values[i].bv_val != NULL; i++ ) { int found = 0; for ( j = 0; a->a_vals[j].bv_val != NULL; j++ ) { - int match; if( mod->sm_nvalues ) { assert( a->a_nvals ); @@ -291,7 +291,7 @@ modify_delete_values( snprintf( textbuf, textlen, "%s: matching rule failed", mod->sm_desc->ad_cname.bv_val ); - goto return_results; + break; } if ( match != 0 ) { @@ -317,7 +317,11 @@ modify_delete_values( "modify/delete: %s: no such value", mod->sm_desc->ad_cname.bv_val ); rc = LDAP_NO_SUCH_ATTRIBUTE; - goto return_results; + if ( i > 0 ) { + break; + } else { + goto return_results; + } } } diff --git a/servers/slapd/mr.c b/servers/slapd/mr.c index bc0a1777f1..0d3b8bb2e4 100644 --- a/servers/slapd/mr.c +++ b/servers/slapd/mr.c @@ -326,14 +326,14 @@ mru_destroy( void ) if ( m->smru_str.bv_val ) { ch_free( m->smru_str.bv_val ); + m->smru_str.bv_val = NULL; } /* memory borrowed from m->smru_mr */ m->smru_oid = NULL; m->smru_names = NULL; m->smru_desc = NULL; - /* free what's left (basically - * smru_mruleuse.mru_applies_oids) */ + /* free what's left (basically smru_mruleuse.mru_applies_oids) */ ldap_matchingruleuse_free((LDAPMatchingRuleUse *)m); } } @@ -494,10 +494,10 @@ int mr_schema_info( Entry *e ) Debug( LDAP_DEBUG_TRACE, "Merging mr [%lu] %s\n", mr->smr_str.bv_len, mr->smr_str.bv_val, 0 ); #endif + nval.bv_val = mr->smr_oid; nval.bv_len = strlen(mr->smr_oid); - if( attr_merge_one( e, ad_matchingRules, &mr->smr_str, &nval ) ) - { + if( attr_merge_one( e, ad_matchingRules, &mr->smr_str, &nval ) ) { return -1; } } @@ -512,7 +512,6 @@ int mru_schema_info( Entry *e ) struct berval nval; LDAP_SLIST_FOREACH( mru, &mru_list, smru_next ) { - assert( !( mru->smru_usage & SLAP_MR_HIDE ) ); if ( mru->smru_str.bv_val == NULL ) { @@ -526,10 +525,10 @@ int mru_schema_info( Entry *e ) Debug( LDAP_DEBUG_TRACE, "Merging mru [%lu] %s\n", mru->smru_str.bv_len, mru->smru_str.bv_val, 0 ); #endif + nval.bv_val = mru->smru_oid; nval.bv_len = strlen(mru->smru_oid); - if( attr_merge_one( e, ad_matchingRuleUse, &mru->smru_str, &nval ) ) - { + if( attr_merge_one( e, ad_matchingRuleUse, &mru->smru_str, &nval ) ) { return -1; } } diff --git a/servers/slapd/operation.c b/servers/slapd/operation.c index 17d4e4efaa..ff6fbf3cc6 100644 --- a/servers/slapd/operation.c +++ b/servers/slapd/operation.c @@ -42,6 +42,8 @@ void slap_op_destroy(void) void slap_op_free( Operation *op ) { + struct berval slap_empty_bv_dup; + assert( LDAP_STAILQ_NEXT(op, o_next) == NULL ); if ( op->o_ber != NULL ) { @@ -65,18 +67,33 @@ slap_op_free( Operation *op ) ber_free( op->o_res_ber, 1 ); } #endif - if ( op->o_sync_state.bv_val != NULL ) { - free( op->o_sync_state.bv_val ); + + slap_sync_cookie_free( &op->o_sync_state, 0 ); + + { + GroupAssertion *g, *n; + for (g = op->o_groups; g; g=n) { + n = g->ga_next; + sl_free(g, op->o_tmpmemctx); + } + op->o_groups = NULL; } #if defined( LDAP_SLAPI ) if ( op->o_pb != NULL ) { slapi_pblock_destroy( (Slapi_PBlock *)op->o_pb ); + slapi_x_free_object_extensions( SLAPI_X_EXT_OPERATION, op ); } - slapi_x_free_object_extensions( SLAPI_X_EXT_OPERATION, op ); #endif /* defined( LDAP_SLAPI ) */ + if ( op->o_sync_csn.bv_val != NULL ) { + ch_free( op->o_sync_csn.bv_val ); + } + memset( op, 0, sizeof(Operation) ); + + op->o_sync_state.sid = -1; + op->o_sync_slog_size = -1; ldap_pvt_thread_mutex_lock( &slap_op_mutex ); LDAP_STAILQ_INSERT_HEAD( &slap_free_ops, op, o_next ); ldap_pvt_thread_mutex_unlock( &slap_op_mutex ); @@ -91,6 +108,7 @@ slap_op_alloc( ) { Operation *op; + struct berval slap_empty_bv_dup; ldap_pvt_thread_mutex_lock( &slap_op_mutex ); if ((op = LDAP_STAILQ_FIRST( &slap_free_ops ))) { @@ -98,8 +116,9 @@ slap_op_alloc( } ldap_pvt_thread_mutex_unlock( &slap_op_mutex ); - if (!op) + if (!op) { op = (Operation *) ch_calloc( 1, sizeof(Operation) ); + } op->o_ber = ber; op->o_msgid = msgid; @@ -109,9 +128,16 @@ slap_op_alloc( op->o_opid = id; op->o_res_ber = NULL; + op->o_sync_state.sid = -1; + op->o_sync_slog_size = -1; + LDAP_STAILQ_FIRST( &op->o_sync_slog_list ) = NULL; + op->o_sync_slog_list.stqh_last = &LDAP_STAILQ_FIRST( &op->o_sync_slog_list ); + #if defined( LDAP_SLAPI ) - op->o_pb = slapi_pblock_new(); - slapi_x_create_object_extensions( SLAPI_X_EXT_OPERATION, op ); + if ( slapi_plugins_used ) { + op->o_pb = slapi_pblock_new(); + slapi_x_create_object_extensions( SLAPI_X_EXT_OPERATION, op ); + } #endif /* defined( LDAP_SLAPI ) */ return( op ); diff --git a/servers/slapd/passwd.c b/servers/slapd/passwd.c index b1c7864fd2..cfd3253f7f 100644 --- a/servers/slapd/passwd.c +++ b/servers/slapd/passwd.c @@ -57,8 +57,8 @@ int passwd_extop( } else if( op->o_bd->be_update_ndn.bv_len ) { /* we SHOULD return a referral in this case */ BerVarray defref = NULL; - if ( op->o_bd->syncinfo ) { - defref = op->o_bd->syncinfo->provideruri_bv; + if ( op->o_bd->be_syncinfo ) { + defref = op->o_bd->be_syncinfo->si_provideruri_bv; } else { defref = referral_rewrite( op->o_bd->be_update_refs, NULL, NULL, LDAP_SCOPE_DEFAULT ); diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h index 9664030f91..f65144c3e2 100644 --- a/servers/slapd/proto-slap.h +++ b/servers/slapd/proto-slap.h @@ -304,6 +304,9 @@ LDAP_SLAPD_F (int) get_supported_controls LDAP_P (( char ***ctrloidsp, slap_mask LDAP_SLAPD_F (int) read_config LDAP_P(( const char *fname, int depth )); LDAP_SLAPD_F (void) config_destroy LDAP_P ((void)); LDAP_SLAPD_F (char **) str2clist LDAP_P(( char ***, char *, const char * )); +#ifdef LDAP_SLAPI +LDAP_SLAPD_V (int) slapi_plugins_used; +#endif /* * connection.c @@ -313,6 +316,15 @@ LDAP_SLAPD_F (int) connections_shutdown LDAP_P((void)); LDAP_SLAPD_F (int) connections_destroy LDAP_P((void)); LDAP_SLAPD_F (int) connections_timeout_idle LDAP_P((time_t)); +LDAP_SLAPD_F (int) connection_client_setup LDAP_P(( + ber_socket_t s, + Listener *l, + ldap_pvt_thread_start_t *func, + void *arg )); +LDAP_SLAPD_F (void) connection_client_enable LDAP_P(( ber_socket_t s )); +LDAP_SLAPD_F (void) connection_client_stop LDAP_P(( ber_socket_t s )); + + LDAP_SLAPD_F (long) connection_init LDAP_P(( ber_socket_t s, Listener* url, @@ -370,12 +382,12 @@ LDAP_SLAPD_F (int) slap_get_csn LDAP_P(( Operation *, char *, int, struct berval /* * daemon.c */ -LDAP_SLAPD_F (void) slapd_add_internal(ber_socket_t s); +LDAP_SLAPD_F (void) slapd_add_internal(ber_socket_t s, int isactive); LDAP_SLAPD_F (int) slapd_daemon_init( const char *urls ); LDAP_SLAPD_F (int) slapd_daemon_destroy(void); LDAP_SLAPD_F (int) slapd_daemon(void); LDAP_SLAPD_F (Listener **) slapd_get_listeners LDAP_P((void)); -LDAP_SLAPD_F (void) slapd_remove LDAP_P((ber_socket_t s, int wake)); +LDAP_SLAPD_F (void) slapd_remove LDAP_P((ber_socket_t s, int wasactive, int wake)); LDAP_SLAPD_F (RETSIGTYPE) slap_sig_shutdown LDAP_P((int sig)); LDAP_SLAPD_F (RETSIGTYPE) slap_sig_wake LDAP_P((int sig)); @@ -539,6 +551,7 @@ LDAP_SLAPD_V( const struct berval ) slap_empty_bv; LDAP_SLAPD_V( const struct berval ) slap_unknown_bv; LDAP_SLAPD_V( const struct berval ) slap_true_bv; LDAP_SLAPD_V( const struct berval ) slap_false_bv; +LDAP_SLAPD_V( struct sync_cookie * ) slap_sync_cookie; /* * index.c @@ -563,6 +576,34 @@ LDAP_SLAPD_V (char *) ldap_srvtab; LDAP_SLAPD_V (int) krbv4_ldap_auth(); #endif +/* + * ldapsync.c + */ +LDAP_SLAPD_F (int) slap_build_sync_state_ctrl LDAP_P(( + Operation *, SlapReply *, Entry *, int, LDAPControl **, + int, int, struct berval * )); +LDAP_SLAPD_F (int) slap_build_sync_done_ctrl LDAP_P(( + Operation *, SlapReply *, LDAPControl **, + int, int, struct berval *, int )); +LDAP_SLAPD_F (int) slap_build_sync_state_ctrl_from_slog LDAP_P(( + Operation *, SlapReply *, struct slog_entry *, int, + LDAPControl **, int, int, struct berval * )); +LDAP_SLAPD_F (int) slap_send_syncinfo LDAP_P(( + Operation *, SlapReply *, int, + struct berval *, int, BerVarray, int )); +LDAP_SLAPD_F (void) slap_compose_sync_cookie LDAP_P(( + Operation *, struct berval *, struct berval *, int )); +LDAP_SLAPD_F (void) slap_sync_cookie_free LDAP_P(( + struct sync_cookie *, int free_cookie )); +LDAP_SLAPD_F (int) slap_parse_sync_cookie LDAP_P(( + struct sync_cookie * )); +LDAP_SLAPD_F (int) slap_init_sync_cookie_ctxcsn LDAP_P(( + struct sync_cookie * )); +LDAP_SLAPD_F (struct sync_cookie *) slap_dup_sync_cookie LDAP_P(( + struct sync_cookie *, struct sync_cookie * )); +LDAP_SLAPD_F (int) slap_build_syncUUID_set LDAP_P(( + Operation *, BerVarray *, Entry * )); + /* * limits.c */ @@ -992,6 +1033,14 @@ LDAP_SLAPD_F (char *) scherr2str LDAP_P((int code)) LDAP_GCCATTR((const)); LDAP_SLAPD_F (int) dscompare LDAP_P(( const char *s1, const char *s2del, char delim )); +/* + * sessionlog.c + */ +LDAP_SLAPD_F (int) slap_send_session_log LDAP_P(( + Operation *, Operation *, SlapReply *)); +LDAP_SLAPD_F (int) slap_add_session_log LDAP_P(( + Operation *, Operation *, Entry * )); + /* * sl_malloc.c */ @@ -1019,6 +1068,32 @@ LDAP_SLAPD_F (SLAP_EXTOP_MAIN_FN) starttls_extop; LDAP_SLAPD_F (Filter *) str2filter LDAP_P(( const char *str )); LDAP_SLAPD_F (Filter *) str2filter_x LDAP_P(( Operation *op, const char *str )); +/* + * syncrepl.c + */ + +LDAP_SLAPD_V (struct runqueue_s) syncrepl_rq; + +LDAP_SLAPD_F (void) init_syncrepl LDAP_P((syncinfo_t *)); +LDAP_SLAPD_F (void*) do_syncrepl LDAP_P((void *, void *)); +LDAP_SLAPD_F (Entry*) syncrepl_message_to_entry LDAP_P(( + syncinfo_t *, Operation *, LDAPMessage *, + Modifications **, int )); +LDAP_SLAPD_F (int) syncrepl_entry LDAP_P(( + syncinfo_t *, Operation*, Entry*, + Modifications*,int, struct berval*, + struct sync_cookie * )); +LDAP_SLAPD_F (void) syncrepl_updateCookie LDAP_P(( + syncinfo_t *, Operation *, struct berval *, + struct sync_cookie * )); +LDAP_SLAPD_F (void) syncrepl_add_glue LDAP_P(( + Operation*, Entry* )); +LDAP_SLAPD_F (Entry*) slap_create_syncrepl_entry LDAP_P(( + Backend *, struct berval *, + struct berval *, struct berval * )); +LDAP_SLAPD_F (struct berval *) slap_uuidstr_from_normalized LDAP_P(( + struct berval *, struct berval *, void * )); + /* syntax.c */ LDAP_SLAPD_F (Syntax *) syn_find LDAP_P(( const char *synname )); @@ -1171,36 +1246,6 @@ LDAP_SLAPD_F (int) do_search LDAP_P((Operation *op, SlapReply *rs)); LDAP_SLAPD_F (int) do_unbind LDAP_P((Operation *op, SlapReply *rs)); LDAP_SLAPD_F (int) do_extended LDAP_P((Operation *op, SlapReply *rs)); -/* - * syncrepl.c - */ - -LDAP_SLAPD_V( const struct berval ) slap_syncrepl_bvc; -LDAP_SLAPD_V( const struct berval ) slap_syncrepl_cn_bvc; - -LDAP_SLAPD_V (struct runqueue_s) syncrepl_rq; - -LDAP_SLAPD_F (void) init_syncrepl LDAP_P(()); -LDAP_SLAPD_F (void*) do_syncrepl LDAP_P((void *, void *)); -LDAP_SLAPD_F (int) ldap_sync_search LDAP_P(( - syncinfo_t *, LDAP *, LDAPControl **, - LDAPControl **, int *)); -LDAP_SLAPD_F (Entry*) syncrepl_message_to_entry LDAP_P(( - syncinfo_t *, LDAP *, Operation *, LDAPMessage *, - Modifications **, int*, struct berval *, struct berval * )); -LDAP_SLAPD_F (int) syncrepl_entry LDAP_P(( - syncinfo_t *, LDAP *, Operation*, Entry*, - Modifications*,int, struct berval*, struct berval*, int )); -LDAP_SLAPD_F (void) syncrepl_updateCookie LDAP_P(( - syncinfo_t *, LDAP *, Operation *, struct berval *, - struct berval * )); -LDAP_SLAPD_F (void) syncrepl_add_glue LDAP_P(( syncinfo_t *, LDAP *, - Operation*, Entry*, Modifications*, int, - struct berval*, struct berval* )); -LDAP_SLAPD_F (Entry*) slap_create_syncrepl_entry LDAP_P(( - Backend *, struct berval *, - struct berval *, struct berval * )); - LDAP_END_DECL #endif /* PROTO_SLAP_H */ diff --git a/servers/slapd/result.c b/servers/slapd/result.c index 3beff2f438..d05dd42132 100644 --- a/servers/slapd/result.c +++ b/servers/slapd/result.c @@ -371,9 +371,11 @@ send_ldap_response( } #ifdef LDAP_SLAPI - slapi_pblock_set( op->o_pb, SLAPI_RESULT_CODE, (void *)rs->sr_err ); - slapi_pblock_set( op->o_pb, SLAPI_RESULT_MATCHED, (void *)rs->sr_matched ); - slapi_pblock_set( op->o_pb, SLAPI_RESULT_TEXT, (void *)rs->sr_text ); + if ( op->o_pb ) { + slapi_pblock_set( op->o_pb, SLAPI_RESULT_CODE, (void *)rs->sr_err ); + slapi_pblock_set( op->o_pb, SLAPI_RESULT_MATCHED, (void *)rs->sr_matched ); + slapi_pblock_set( op->o_pb, SLAPI_RESULT_TEXT, (void *)rs->sr_text ); + } #endif /* LDAP_SLAPI */ ldap_pvt_thread_mutex_lock( &num_sent_mutex ); @@ -493,12 +495,14 @@ slap_send_ldap_result( Operation *op, SlapReply *rs ) * should just set SLAPI_RESULT_CODE rather than sending a * result if they wish to change the result. */ - slapi_x_pblock_set_operation( op->o_pb, op ); - slapi_pblock_set( op->o_pb, SLAPI_RESULT_CODE, (void *)rs->sr_err ); - slapi_pblock_set( op->o_pb, SLAPI_RESULT_TEXT, (void *)rs->sr_text ); - slapi_pblock_set( op->o_pb, SLAPI_RESULT_MATCHED, (void *)rs->sr_matched ); + if ( op->o_pb ) { + slapi_x_pblock_set_operation( op->o_pb, op ); + slapi_pblock_set( op->o_pb, SLAPI_RESULT_CODE, (void *)rs->sr_err ); + slapi_pblock_set( op->o_pb, SLAPI_RESULT_TEXT, (void *)rs->sr_text ); + slapi_pblock_set( op->o_pb, SLAPI_RESULT_MATCHED, (void *)rs->sr_matched ); - (void) doPluginFNs( op->o_bd, SLAPI_PLUGIN_PRE_RESULT_FN, op->o_pb ); + (void) doPluginFNs( op->o_bd, SLAPI_PLUGIN_PRE_RESULT_FN, op->o_pb ); + } #endif /* LDAP_SLAPI */ if ( op->o_protocol < LDAP_VERSION3 ) { @@ -1069,38 +1073,40 @@ slap_send_search_entry( Operation *op, SlapReply *rs ) * First, setup the computed attribute context that is * passed to all plugins. */ - ctx.cac_pb = op->o_pb; - ctx.cac_attrs = rs->sr_attrs; - ctx.cac_attrsonly = op->ors_attrsonly; - ctx.cac_userattrs = userattrs; - ctx.cac_opattrs = opattrs; - ctx.cac_acl_state = acl_state; - ctx.cac_private = (void *)ber; + if ( op->o_pb ) { + ctx.cac_pb = op->o_pb; + ctx.cac_attrs = rs->sr_attrs; + ctx.cac_attrsonly = op->ors_attrsonly; + ctx.cac_userattrs = userattrs; + ctx.cac_opattrs = opattrs; + ctx.cac_acl_state = acl_state; + ctx.cac_private = (void *)ber; - /* - * For each client requested attribute, call the plugins. - */ - if ( rs->sr_attrs != NULL ) { - for ( anp = rs->sr_attrs; anp->an_name.bv_val != NULL; anp++ ) { - rc = compute_evaluator( &ctx, anp->an_name.bv_val, - rs->sr_entry, slapi_x_compute_output_ber ); - if ( rc == 1 ) { - break; - } - } - } else { /* - * Technically we shouldn't be returning operational attributes - * when the user requested only user attributes. We'll let the - * plugin decide whether to be naughty or not. + * For each client requested attribute, call the plugins. */ - rc = compute_evaluator( &ctx, "*", - rs->sr_entry, slapi_x_compute_output_ber ); - } - if ( rc == 1 ) { - if ( op->o_res_ber == NULL ) ber_free_buf( ber ); - send_ldap_error( op, rs, LDAP_OTHER, "computed attribute error" ); - goto error_return; + if ( rs->sr_attrs != NULL ) { + for ( anp = rs->sr_attrs; anp->an_name.bv_val != NULL; anp++ ) { + rc = compute_evaluator( &ctx, anp->an_name.bv_val, + rs->sr_entry, slapi_x_compute_output_ber ); + if ( rc == 1 ) { + break; + } + } + } else { + /* + * Technically we shouldn't be returning operational attributes + * when the user requested only user attributes. We'll let the + * plugin decide whether to be naughty or not. + */ + rc = compute_evaluator( &ctx, "*", + rs->sr_entry, slapi_x_compute_output_ber ); + } + if ( rc == 1 ) { + if ( op->o_res_ber == NULL ) ber_free_buf( ber ); + send_ldap_error( op, rs, LDAP_OTHER, "computed attribute error" ); + goto error_return; + } } #endif /* LDAP_SLAPI */ diff --git a/servers/slapd/root_dse.c b/servers/slapd/root_dse.c index b2bde3fcfa..b15725fce3 100644 --- a/servers/slapd/root_dse.c +++ b/servers/slapd/root_dse.c @@ -1,5 +1,5 @@ /* $OpenLDAP$ */ -/* root_dse.c - Provides the ROOT DSA-Specific Entry +/* root_dse.c - Provides the Root DSA-Specific Entry * * Copyright 1999-2003 The OpenLDAP Foundation. * All rights reserved. diff --git a/servers/slapd/sasl.c b/servers/slapd/sasl.c index 34c5aadffb..06254e3f12 100644 --- a/servers/slapd/sasl.c +++ b/servers/slapd/sasl.c @@ -297,6 +297,7 @@ static const char *slap_propnames[] = { "*slapConn", "*authcDN", "*authzDN", NULL }; static Filter generic_filter = { LDAP_FILTER_PRESENT }; +static struct berval generic_filterstr = BER_BVC("(objectclass=*)"); #define PROP_CONN 0 #define PROP_AUTHC 1 @@ -449,10 +450,12 @@ slap_auxprop_lookup( #endif op.o_conn = conn; op.o_connid = conn->c_connid; + op.o_req_dn = op.o_req_ndn; op.ors_scope = LDAP_SCOPE_BASE; op.ors_deref = LDAP_DEREF_NEVER; op.ors_slimit = 1; op.ors_filter = &generic_filter; + op.ors_filterstr = generic_filterstr; op.o_bd->be_search( &op, &rs ); } @@ -577,10 +580,12 @@ slap_sasl_checkpass( #endif op.o_conn = conn; op.o_connid = conn->c_connid; + op.o_req_dn = op.o_req_ndn; op.ors_scope = LDAP_SCOPE_BASE; op.ors_deref = LDAP_DEREF_NEVER; op.ors_slimit = 1; op.ors_filter = &generic_filter; + op.ors_filterstr = generic_filterstr; op.o_bd->be_search( &op, &rs ); } diff --git a/servers/slapd/saslauthz.c b/servers/slapd/saslauthz.c index b536580930..ba3cfe1291 100644 --- a/servers/slapd/saslauthz.c +++ b/servers/slapd/saslauthz.c @@ -66,15 +66,20 @@ int slap_sasl_setpolicy( const char *arg ) } static int slap_parseURI( Operation *op, struct berval *uri, - struct berval *searchbase, int *scope, Filter **filter ) + struct berval *base, struct berval *nbase, + int *scope, Filter **filter, struct berval *fstr ) { struct berval bv; int rc; LDAPURLDesc *ludp; assert( uri != NULL && uri->bv_val != NULL ); - searchbase->bv_val = NULL; - searchbase->bv_len = 0; + base->bv_val = NULL; + base->bv_len = 0; + nbase->bv_val = NULL; + nbase->bv_len = 0; + fstr->bv_val = NULL; + fstr->bv_len = 0; *scope = -1; *filter = NULL; @@ -93,7 +98,7 @@ static int slap_parseURI( Operation *op, struct berval *uri, is_dn: bv.bv_len = uri->bv_len - (bv.bv_val - uri->bv_val); - rc = dnNormalize( 0, NULL, NULL, &bv, searchbase, op->o_tmpmemctx ); + rc = dnNormalize( 0, NULL, NULL, &bv, nbase, op->o_tmpmemctx ); if( rc == LDAP_SUCCESS ) { *scope = LDAP_SCOPE_BASE; } @@ -129,16 +134,24 @@ is_dn: bv.bv_len = uri->bv_len - (bv.bv_val - uri->bv_val); rc = LDAP_PROTOCOL_ERROR; goto done; } + ber_str2bv( ludp->lud_filter, 0, 0, fstr ); } /* Grab the searchbase */ - bv.bv_val = ludp->lud_dn; - bv.bv_len = strlen( bv.bv_val ); - rc = dnNormalize( 0, NULL, NULL, &bv, searchbase, op->o_tmpmemctx ); + ber_str2bv( ludp->lud_dn, 0, 0, base ); + rc = dnNormalize( 0, NULL, NULL, base, nbase, op->o_tmpmemctx ); done: if( rc != LDAP_SUCCESS ) { if( *filter ) filter_free_x( op, *filter ); + base->bv_val = NULL; + base->bv_len = 0; + fstr->bv_val = NULL; + fstr->bv_len = 0; + } else { + /* Don't free these, return them to caller */ + ludp->lud_filter = NULL; + ludp->lud_dn= NULL; } ldap_free_urldesc( ludp ); @@ -405,8 +418,9 @@ int slap_sasl_match( Operation *opx, struct berval *rule, assertDN->bv_val, rule->bv_val, 0 ); #endif - rc = slap_parseURI( opx, rule, - &op.o_req_ndn, &op.oq_search.rs_scope, &op.oq_search.rs_filter ); + rc = slap_parseURI( opx, rule, &op.o_req_dn, + &op.o_req_ndn, &op.oq_search.rs_scope, &op.oq_search.rs_filter, + &op.ors_filterstr ); if( rc != LDAP_SUCCESS ) goto CONCLUDED; /* Massive shortcut: search scope == base */ @@ -462,6 +476,7 @@ int slap_sasl_match( Operation *opx, struct berval *rule, #endif op.o_conn = opx->o_conn; op.o_connid = opx->o_connid; + op.o_req_dn = op.o_req_ndn; op.o_bd->be_search( &op, &rs ); @@ -472,8 +487,10 @@ int slap_sasl_match( Operation *opx, struct berval *rule, } CONCLUDED: + if( op.o_req_dn.bv_len ) ch_free( op.o_req_dn.bv_val ); if( op.o_req_ndn.bv_len ) sl_free( op.o_req_ndn.bv_val, opx->o_tmpmemctx ); if( op.oq_search.rs_filter ) filter_free_x( opx, op.oq_search.rs_filter ); + if( op.ors_filterstr.bv_len ) ch_free( op.ors_filterstr.bv_val ); #ifdef NEW_LOGGING LDAP_LOG( TRANSPORT, ENTRY, @@ -580,8 +597,9 @@ void slap_sasl2dn( Operation *opx, goto FINISHED; } - rc = slap_parseURI( opx, ®out, - &op.o_req_ndn, &op.oq_search.rs_scope, &op.oq_search.rs_filter ); + rc = slap_parseURI( opx, ®out, &op.o_req_dn, + &op.o_req_ndn, &op.oq_search.rs_scope, &op.oq_search.rs_filter, + &op.ors_filterstr ); if( regout.bv_val ) sl_free( regout.bv_val, opx->o_tmpmemctx ); if( rc != LDAP_SUCCESS ) { goto FINISHED; @@ -630,6 +648,7 @@ void slap_sasl2dn( Operation *opx, op.oq_search.rs_deref = LDAP_DEREF_NEVER; op.oq_search.rs_slimit = 1; op.oq_search.rs_attrsonly = 1; + op.o_req_dn = op.o_req_ndn; op.o_bd->be_search( &op, &rs ); @@ -637,8 +656,10 @@ FINISHED: if( sasldn->bv_len ) { opx->o_conn->c_authz_backend = op.o_bd; } - if( op.o_req_ndn.bv_len ) ch_free( op.o_req_ndn.bv_val ); + if( op.o_req_dn.bv_len ) ch_free( op.o_req_dn.bv_val ); + if( op.o_req_ndn.bv_len ) sl_free( op.o_req_ndn.bv_val, opx->o_tmpmemctx ); if( op.oq_search.rs_filter ) filter_free_x( opx, op.oq_search.rs_filter ); + if( op.ors_filterstr.bv_len ) ch_free( op.ors_filterstr.bv_val ); #ifdef NEW_LOGGING LDAP_LOG( TRANSPORT, ENTRY, diff --git a/servers/slapd/schema/core.schema b/servers/slapd/schema/core.schema index 60315d27e2..ac08b7483f 100644 --- a/servers/slapd/schema/core.schema +++ b/servers/slapd/schema/core.schema @@ -202,13 +202,17 @@ attributetype ( 2.5.4.34 NAME 'seeAlso' # SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{128} ) # Must be transferred using ;binary +# with certificateExactMatch rule (per X.509) attributetype ( 2.5.4.36 NAME 'userCertificate' DESC 'RFC2256: X.509 user certificate, use ;binary' + EQUALITY certificateExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.8 ) # Must be transferred using ;binary +# with certificateExactMatch rule (per X.509) attributetype ( 2.5.4.37 NAME 'cACertificate' DESC 'RFC2256: X.509 CA certificate, use ;binary' + EQUALITY certificateExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.8 ) # Must be transferred using ;binary diff --git a/servers/slapd/schema_check.c b/servers/slapd/schema_check.c index c15d78eb37..5634962c27 100644 --- a/servers/slapd/schema_check.c +++ b/servers/slapd/schema_check.c @@ -42,10 +42,8 @@ entry_schema_check( { Attribute *a, *asc, *aoc; ObjectClass *sc, *oc; -#ifdef SLAP_EXTENDED_SCHEMA AttributeType *at; ContentRule *cr; -#endif int rc, i; struct berval nsc; AttributeDescription *ad_structuralObjectClass @@ -229,16 +227,15 @@ entry_schema_check( } /* naming check */ - if ( !is_entry_objectclass ( e, slap_schema.si_oc_glue, 0 ) ) { - rc = entry_naming_check( e, text, textbuf, textlen ); - if( rc != LDAP_SUCCESS ) { - return rc; - } - } else { - /* Glue Entry */ - } - -#ifdef SLAP_EXTENDED_SCHEMA + if ( !is_entry_objectclass ( e, slap_schema.si_oc_glue, 0 ) ) { + rc = entry_naming_check( e, text, textbuf, textlen ); + if( rc != LDAP_SUCCESS ) { + return rc; + } + } else { + /* Glue Entry */ + } + /* find the content rule for the structural class */ cr = cr_find( sc->soc_oid ); @@ -322,7 +319,6 @@ entry_schema_check( } } } -#endif /* SLAP_EXTENDED_SCHEMA */ /* check that the entry has required attrs for each oc */ for ( i = 0; aoc->a_vals[i].bv_val != NULL; i++ ) { @@ -434,7 +430,6 @@ entry_schema_check( } else if ( oc->soc_kind != LDAP_SCHEMA_STRUCTURAL || oc == sc ) { char *s; -#ifdef SLAP_EXTENDED_SCHEMA if( oc->soc_kind == LDAP_SCHEMA_AUXILIARY ) { int k; @@ -475,7 +470,6 @@ entry_schema_check( return LDAP_OBJECT_CLASS_VIOLATION; } } -#endif /* SLAP_EXTENDED_SCHEMA */ s = oc_check_required( e, oc, &aoc->a_vals[i] ); if (s != NULL) { @@ -509,7 +503,6 @@ entry_schema_check( for ( a = e->e_attrs; a != NULL; a = a->a_next ) { int ret; -#ifdef SLAP_EXTENDED_SCHEMA ret = LDAP_OBJECT_CLASS_VIOLATION; if( cr && cr->scr_required ) { @@ -531,7 +524,6 @@ entry_schema_check( } if( ret != LDAP_SUCCESS ) -#endif /* SLAP_EXTENDED_SCHEMA */ { ret = oc_check_allowed( a->a_desc->ad_type, aoc->a_vals, sc ); } @@ -727,7 +719,7 @@ int structural_class( if( xc == NULL ) { snprintf( textbuf, textlen, "unrecognized objectClass '%s'", - ocs[i].bv_val ); + ocs[j].bv_val ); *text = textbuf; return LDAP_OBJECT_CLASS_VIOLATION; } @@ -849,40 +841,98 @@ entry_naming_check( Attribute *attr; const char *errtext; + if( ava->la_flags & LDAP_AVA_BINARY ) { + snprintf( textbuf, textlen, + "value of naming attribute '%s' in unsupported BER form", + ava->la_attr.bv_val ); + rc = LDAP_NAMING_VIOLATION; + } + rc = slap_bv2ad( &ava->la_attr, &desc, &errtext ); if ( rc != LDAP_SUCCESS ) { snprintf( textbuf, textlen, "%s (in RDN)", errtext ); break; } - /* find the naming attribute */ - attr = attr_find( e->e_attrs, desc ); - if ( attr == NULL ) { + if( desc->ad_type->sat_usage ) { snprintf( textbuf, textlen, - "naming attribute '%s' is not present in entry", + "naming attribute '%s' is operational", + ava->la_attr.bv_val ); + rc = LDAP_NAMING_VIOLATION; + break; + } + + if( desc->ad_type->sat_collective ) { + snprintf( textbuf, textlen, + "naming attribute '%s' is collective", ava->la_attr.bv_val ); rc = LDAP_NAMING_VIOLATION; break; } - if( ava->la_flags & LDAP_AVA_BINARY ) { + if( desc->ad_type->sat_obsolete ) { snprintf( textbuf, textlen, - "value of naming attribute '%s' in unsupported BER form", + "naming attribute '%s' is collective", ava->la_attr.bv_val ); rc = LDAP_NAMING_VIOLATION; + break; } - if ( value_find_ex( desc, - SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH, - attr->a_nvals, - &ava->la_value, NULL ) != 0 ) - { + if( !desc->ad_type->sat_equality ) { snprintf( textbuf, textlen, - "value of naming attribute '%s' is not present in entry", + "naming attribute '%s' has no equality matching rule", ava->la_attr.bv_val ); rc = LDAP_NAMING_VIOLATION; break; } + + if( !desc->ad_type->sat_equality->smr_match ) { + snprintf( textbuf, textlen, + "naming attribute '%s' has unsupported equality matching rule", + ava->la_attr.bv_val ); + rc = LDAP_NAMING_VIOLATION; + break; + } + + /* find the naming attribute */ + attr = attr_find( e->e_attrs, desc ); + if ( attr == NULL ) { + snprintf( textbuf, textlen, + "naming attribute '%s' is not present in entry", + ava->la_attr.bv_val ); + rc = LDAP_NAMING_VIOLATION; + break; + } + + rc = value_find_ex( desc, SLAP_MR_VALUE_OF_ASSERTION_SYNTAX| + SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH, + attr->a_nvals, &ava->la_value, NULL ); + + if( rc != 0 ) { + switch( rc ) { + case LDAP_INAPPROPRIATE_MATCHING: + snprintf( textbuf, textlen, + "inappropriate matching for naming attribute '%s'", + ava->la_attr.bv_val ); + break; + case LDAP_INVALID_SYNTAX: + snprintf( textbuf, textlen, + "value of naming attribute '%s' is invalid", + ava->la_attr.bv_val ); + break; + case LDAP_NO_SUCH_ATTRIBUTE: + snprintf( textbuf, textlen, + "value of naming attribute '%s' is not present in entry", + ava->la_attr.bv_val ); + break; + default: + snprintf( textbuf, textlen, + "naming attribute '%s' is inappropriate", + ava->la_attr.bv_val ); + } + rc = LDAP_NAMING_VIOLATION; + break; + } } ldap_rdnfree( rdn ); diff --git a/servers/slapd/schema_init.c b/servers/slapd/schema_init.c index 4d3d90c014..0885ff0361 100644 --- a/servers/slapd/schema_init.c +++ b/servers/slapd/schema_init.c @@ -21,6 +21,18 @@ #include "ldap_utf8.h" +#ifdef HAVE_TLS +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif + #include "lutil_hash.h" #define HASH_BYTES LUTIL_HASH_BYTES #define HASH_CONTEXT lutil_HASH_CTX @@ -60,6 +72,33 @@ blobValidate( #define berValidate blobValidate +static int +sequenceValidate( + Syntax *syntax, + struct berval *in ) +{ + if ( in->bv_len < 2 ) return LDAP_INVALID_SYNTAX; + if ( in->bv_val[0] != LBER_SEQUENCE ) return LDAP_INVALID_SYNTAX; + + return LDAP_SUCCESS; +} + + +#ifdef HAVE_TLS +static int certificateValidate( Syntax *syntax, struct berval *in ) +{ + X509 *xcert=NULL; + unsigned char *p = in->bv_val; + + xcert = d2i_X509(NULL, &p, in->bv_len); + if ( !xcert ) return LDAP_INVALID_SYNTAX; + X509_free(xcert); + return LDAP_SUCCESS; +} +#else +#define certificateValidate sequenceValidate +#endif + static int octetStringMatch( int *matchp, @@ -822,6 +861,8 @@ uniqueMemberNormalize( struct berval out; int rc; + assert( SLAP_MR_IS_VALUE_OF_SYNTAX( usage )); + ber_dupbv( &out, val ); if( out.bv_len != 0 ) { struct berval uid = { 0, NULL }; @@ -1131,6 +1172,8 @@ UTF8StringNormalize( int flags; int i, wasspace; + assert( SLAP_MR_IS_VALUE_OF_SYNTAX( use )); + if( val->bv_val == NULL ) { /* assume we're dealing with a syntax (e.g., UTF8String) * which allows empty strings @@ -1424,6 +1467,8 @@ telephoneNumberNormalize( { char *p, *q; + assert( SLAP_MR_IS_VALUE_OF_SYNTAX( usage )); + /* validator should have refused an empty string */ assert( val->bv_len ); @@ -1669,10 +1714,12 @@ IA5StringNormalize( void *ctx ) { char *p, *q; - int casefold = SLAP_MR_ASSOCIATED(mr, slap_schema.si_mr_caseExactIA5Match); + int casefold = !SLAP_MR_ASSOCIATED(mr, slap_schema.si_mr_caseExactIA5Match); assert( val->bv_len ); + assert( SLAP_MR_IS_VALUE_OF_SYNTAX( use )); + p = val->bv_val; /* Ignore initial whitespace */ @@ -1723,6 +1770,86 @@ IA5StringNormalize( return LDAP_SUCCESS; } +static int +UUIDValidate( + Syntax *syntax, + struct berval *in ) +{ + int i; + if( in->bv_len != 36 ) { + assert(0); + return LDAP_INVALID_SYNTAX; + } + + for( i=0; i<36; i++ ) { + switch(i) { + case 8: + case 13: + case 18: + case 23: + if( in->bv_val[i] != '-' ) { + return LDAP_INVALID_SYNTAX; + } + break; + default: + if( !ASCII_HEX( in->bv_val[i]) ) { + return LDAP_INVALID_SYNTAX; + } + } + } + + return LDAP_SUCCESS; +} + +static int +UUIDNormalize( + slap_mask_t usage, + Syntax *syntax, + MatchingRule *mr, + struct berval *val, + struct berval *normalized, + void *ctx ) +{ + unsigned char octet; + int i; + int j; + normalized->bv_len = 16; + normalized->bv_val = sl_malloc( normalized->bv_len+1, ctx ); + + for( i=0, j=0; i<36; i++ ) { + unsigned char nibble; + if( val->bv_val[i] == '-' ) { + continue; + + } else if( ASCII_DIGIT( val->bv_val[i] ) ) { + nibble = val->bv_val[i] - '0'; + + } else if( ASCII_HEXLOWER( val->bv_val[i] ) ) { + nibble = val->bv_val[i] - ('a'-10); + + } else if( ASCII_HEXUPPER( val->bv_val[i] ) ) { + nibble = val->bv_val[i] - ('A'-10); + + } else { + sl_free( normalized->bv_val, ctx ); + return LDAP_INVALID_SYNTAX; + } + + if( j & 1 ) { + octet |= nibble; + normalized->bv_val[j>>1] = octet; + } else { + octet = nibble << 4; + } + j++; + } + + normalized->bv_val[normalized->bv_len] = 0; + return LDAP_SUCCESS; +} + + + static int numericStringValidate( Syntax *syntax, @@ -1864,211 +1991,202 @@ serialNumberAndIssuerValidate( Syntax *syntax, struct berval *in ) { - int rc = LDAP_INVALID_SYNTAX; - struct berval serialNumber, issuer; + int rc; + int state; + ber_len_t n; + struct berval sn, i; + if( in->bv_len < 3 ) return LDAP_INVALID_SYNTAX; - serialNumber.bv_val = in->bv_val; - for( serialNumber.bv_len = 0; - serialNumber.bv_len < in->bv_len; - serialNumber.bv_len++ ) - { - if ( serialNumber.bv_val[serialNumber.bv_len] == '$' ) { - issuer.bv_val = &serialNumber.bv_val[serialNumber.bv_len+1]; - issuer.bv_len = in->bv_len - (serialNumber.bv_len+1); + i.bv_val = strchr( in->bv_val, '$' ); + if( i.bv_val == NULL ) return LDAP_INVALID_SYNTAX; - if( serialNumber.bv_len == 0 || issuer.bv_len == 0 ) break; + sn.bv_val = in->bv_val; + sn.bv_len = i.bv_val - in->bv_val; - rc = integerValidate( NULL, &serialNumber ); - if( rc ) break; + i.bv_val++; + i.bv_len = in->bv_len - (sn.bv_len + 1); - rc = dnValidate( NULL, &issuer ); - break; + /* validate serial number (strict for now) */ + for( n=0; n < sn.bv_len; n++ ) { + if( !ASCII_DIGIT(sn.bv_val[n]) ) { + return LDAP_INVALID_SYNTAX; } } - return rc; + /* validate DN */ + rc = dnValidate( NULL, &i ); + if( rc ) return LDAP_INVALID_SYNTAX; + + return LDAP_SUCCESS; } -static int -serialNumberAndIssuerNormalize( - slap_mask_t usage, +int +serialNumberAndIssuerPretty( Syntax *syntax, - MatchingRule *mr, struct berval *val, - struct berval *normalized, + struct berval *out, void *ctx ) { - int rc = LDAP_INVALID_SYNTAX; - struct berval serialNumber, issuer, nissuer; - - serialNumber.bv_val = val->bv_val; - for( serialNumber.bv_len = 0; - serialNumber.bv_len < val->bv_len; - serialNumber.bv_len++ ) - { - if ( serialNumber.bv_val[serialNumber.bv_len] == '$' ) { - issuer.bv_val = &serialNumber.bv_val[serialNumber.bv_len+1]; - issuer.bv_len = val->bv_len - (serialNumber.bv_len+1); - - if( serialNumber.bv_len == 0 || issuer.bv_len == 0 ) break; - - rc = dnNormalize( usage, syntax, mr, &issuer, &nissuer, ctx ); - if( rc ) break; + int rc; + int state; + ber_len_t n; + struct berval sn, i, newi; - normalized->bv_len = serialNumber.bv_len + 1 + nissuer.bv_len; - normalized->bv_val = ch_malloc( normalized->bv_len + 1); + assert( val ); + assert( out ); - AC_MEMCPY( normalized->bv_val, - serialNumber.bv_val, serialNumber.bv_len ); - normalized->bv_val[serialNumber.bv_len] = '$'; - AC_MEMCPY( &normalized->bv_val[serialNumber.bv_len+1], - nissuer.bv_val, nissuer.bv_len ); - normalized->bv_val[normalized->bv_len] = '\0'; - break; - } - } +#ifdef NEW_LOGGING + LDAP_LOG( OPERATION, ARGS, ">>> serialNumberAndIssuerPretty: <%s>\n", + val->bv_val, 0, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, ">>> serialNumberAndIssuerPretty: <%s>\n", + val->bv_val, 0, 0 ); +#endif - return rc; -} + if( val->bv_len < 3 ) return LDAP_INVALID_SYNTAX; -#ifdef HAVE_TLS -#include -#include + i.bv_val = strchr( val->bv_val, '$' ); + if( i.bv_val == NULL ) return LDAP_INVALID_SYNTAX; -/* - * Next function returns a string representation of a ASN1_INTEGER. - * It works for unlimited lengths. - */ + sn.bv_val = val->bv_val; + sn.bv_len = i.bv_val - val->bv_val; -static struct berval * -asn1_integer2str(ASN1_INTEGER *a, struct berval *bv) -{ - char buf[256]; - char *p; - static char digit[] = "0123456789"; - - /* We work backwards, make it fill from the end of buf */ - p = buf + sizeof(buf) - 1; - *p = '\0'; + i.bv_val++; + i.bv_len = val->bv_len - (sn.bv_len + 1); - if ( a == NULL || a->length == 0 ) { - *--p = '0'; - } else { - int i; - int n = a->length; - int base = 0; - unsigned int *copy; + /* eat leading zeros */ + for( n=0; n < (sn.bv_len-1); n++ ) { + if( sn.bv_val[n] != '0' ) break; + } + sn.bv_val += n; + sn.bv_len -= n; - /* We want to preserve the original */ - copy = ch_malloc(n*sizeof(unsigned int)); - for (i = 0; idata[i]; + for( n=0; n < sn.bv_len; n++ ) { + if( !ASCII_DIGIT(sn.bv_val[n]) ) { + return LDAP_INVALID_SYNTAX; } + } - /* - * base indicates the index of the most significant - * byte that might be nonzero. When it goes off the - * end, we now there is nothing left to do. - */ - while (base < n) { - unsigned int carry; - - carry = 0; - for (i = base; ibv_len = sn.bv_len + newi.bv_len + 1; + out->bv_val = sl_realloc( newi.bv_val, out->bv_len + 1, ctx ); - if ( a->type == V_ASN1_NEG_INTEGER ) { - *--p = '-'; + if( out->bv_val == NULL ) { + sl_free( newi.bv_val, ctx ); + return LDAP_OTHER; } - return ber_str2bv( p, 0, 1, bv ); + /* push issuer over */ + AC_MEMCPY( &out->bv_val[sn.bv_len+1], newi.bv_val, newi.bv_len ); + /* insert sn and "$" */ + AC_MEMCPY( out->bv_val, sn.bv_val, sn.bv_len ); + out->bv_val[sn.bv_len] = '$'; + /* terminate */ + out->bv_val[out->bv_len] = '\0'; + +#ifdef NEW_LOGGING + LDAP_LOG( OPERATION, ARGS, "<<< serialNumberAndIssuerPretty: <%s>\n", + out->bv_val, 0, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, "<<< serialNumberAndIssuerPretty: <%s>\n", + out->bv_val, 0, 0 ); +#endif + + return LDAP_SUCCESS; } /* - * Given a certificate in DER format, extract the corresponding - * assertion value for certificateExactMatch + * This routine is called by certificateExactNormalize when + * certificateExactNormalize receives a search string instead of + * a certificate. This routine checks if the search value is valid + * and then returns the normalized value */ static int -certificateExactConvert( - struct berval * in, - struct berval * out ) +serialNumberAndIssuerNormalize( + slap_mask_t usage, + Syntax *syntax, + MatchingRule *mr, + struct berval *val, + struct berval *out, + void *ctx ) { int rc; - X509 *xcert; - unsigned char *p = in->bv_val; - struct berval serial; - struct berval issuer_dn; + int state; + ber_len_t n; + struct berval sn, i, newi; + + assert( val ); + assert( out ); - xcert = d2i_X509(NULL, &p, in->bv_len); - if ( !xcert ) { #ifdef NEW_LOGGING - LDAP_LOG( CONFIG, ENTRY, - "certificateExactConvert: error parsing cert: %s\n", - ERR_error_string(ERR_get_error(),NULL), 0, 0 ); + LDAP_LOG( OPERATION, ARGS, ">>> serialNumberAndIssuerNormalize: <%s>\n", + val->bv_val, 0, 0 ); #else - Debug( LDAP_DEBUG_ARGS, "certificateExactConvert: " - "error parsing cert: %s\n", - ERR_error_string(ERR_get_error(),NULL), NULL, NULL ); + Debug( LDAP_DEBUG_TRACE, ">>> serialNumberAndIssuerNormalize: <%s>\n", + val->bv_val, 0, 0 ); #endif - return LDAP_INVALID_SYNTAX; - } - if ( !asn1_integer2str(xcert->cert_info->serialNumber, &serial) ) { - X509_free(xcert); - return LDAP_INVALID_SYNTAX; + if( val->bv_len < 3 ) return LDAP_INVALID_SYNTAX; + + i.bv_val = strchr( val->bv_val, '$' ); + if( i.bv_val == NULL ) return LDAP_INVALID_SYNTAX; + + sn.bv_val = val->bv_val; + sn.bv_len = i.bv_val - val->bv_val; + + i.bv_val++; + i.bv_len = val->bv_len - (sn.bv_len + 1); + + /* eat leading zeros */ + for( n=0; n < (sn.bv_len-1); n++ ) { + if( sn.bv_val[n] != '0' ) break; } + sn.bv_val += n; + sn.bv_len -= n; - rc = dnX509normalize( X509_get_issuer_name(xcert), &issuer_dn ); - if( rc != LDAP_SUCCESS ) { - X509_free(xcert); - ber_memfree(serial.bv_val); - return LDAP_INVALID_SYNTAX; + for( n=0; n < sn.bv_len; n++ ) { + if( !ASCII_DIGIT(sn.bv_val[n]) ) { + return LDAP_INVALID_SYNTAX; + } } - X509_free(xcert); + /* pretty DN */ + rc = dnNormalize( usage, syntax, mr, &i, &newi, ctx ); + if( rc ) return LDAP_INVALID_SYNTAX; - out->bv_len = serial.bv_len + issuer_dn.bv_len + sizeof(" $ "); - out->bv_val = ch_malloc(out->bv_len); - p = out->bv_val; - AC_MEMCPY(p, serial.bv_val, serial.bv_len); - p += serial.bv_len; - AC_MEMCPY(p, " $ ", sizeof(" $ ")-1); - p += 3; - AC_MEMCPY(p, issuer_dn.bv_val, issuer_dn.bv_len); - p += issuer_dn.bv_len; - *p++ = '\0'; + /* make room from sn + "$" */ + out->bv_len = sn.bv_len + newi.bv_len + 1; + out->bv_val = sl_realloc( newi.bv_val, out->bv_len + 1, ctx ); + + if( out->bv_val == NULL ) { + sl_free( newi.bv_val, ctx ); + return LDAP_OTHER; + } + + /* push issuer over */ + AC_MEMCPY( &out->bv_val[sn.bv_len+1], newi.bv_val, newi.bv_len ); + /* insert sn and "$" */ + AC_MEMCPY( out->bv_val, sn.bv_val, sn.bv_len ); + out->bv_val[sn.bv_len] = '$'; + /* terminate */ + out->bv_val[out->bv_len] = '\0'; #ifdef NEW_LOGGING - LDAP_LOG( CONFIG, ARGS, "certificateExactConvert: %s\n", + LDAP_LOG( OPERATION, ARGS, "<<< serialNumberAndIssuerNormalize: <%s>\n", out->bv_val, 0, 0 ); #else - Debug( LDAP_DEBUG_ARGS, "certificateExactConvert: %s\n", - out->bv_val, NULL, NULL ); + Debug( LDAP_DEBUG_TRACE, "<<< serialNumberAndIssuerNormalize: <%s>\n", + out->bv_val, 0, 0 ); #endif - ber_memfree(serial.bv_val); - ber_memfree(issuer_dn.bv_val); - - return LDAP_SUCCESS; + return rc; } +#ifdef HAVE_TLS static int certificateExactNormalize( slap_mask_t usage, @@ -2078,16 +2196,60 @@ certificateExactNormalize( struct berval *normalized, void *ctx ) { - int rc; + int rc = LDAP_INVALID_SYNTAX; + unsigned char *p; + char *serial = NULL; + ber_len_t seriallen; + struct berval issuer_dn = { 0, NULL }; + X509_NAME *name = NULL; + ASN1_INTEGER *sn = NULL; + X509 *xcert = NULL; - if( SLAP_MR_IS_VALUE_OF_ASSERTION_SYNTAX( usage ) ) { - rc = serialNumberAndIssuerNormalize( usage, syntax, mr, - val, normalized, ctx ); + if( val->bv_len == 0 ) goto done; - } else { - rc = certificateExactConvert( val, normalized ); + if( SLAP_MR_IS_VALUE_OF_ASSERTION_SYNTAX(usage) ) { + return serialNumberAndIssuerNormalize(0,NULL,NULL,val,normalized,ctx); } + assert( SLAP_MR_IS_VALUE_OF_ATTRIBUTE_SYNTAX(usage) ); + + p = val->bv_val; + xcert = d2i_X509( NULL, &p, val->bv_len); + if( xcert == NULL ) goto done; + + sn=X509_get_serialNumber(xcert); + if ( sn == NULL ) goto done; + serial=i2s_ASN1_INTEGER(0, sn ); + if( serial == NULL ) goto done; + seriallen=strlen(serial); + + name=X509_get_issuer_name(xcert); + if( name == NULL ) goto done; + rc = dnX509normalize( name, &issuer_dn ); + if( rc != LDAP_SUCCESS ) goto done; + + normalized->bv_len = seriallen + issuer_dn.bv_len + 1; + p = normalized->bv_val = ch_malloc(normalized->bv_len+1); + AC_MEMCPY(p, serial, seriallen); + p += seriallen; + *p++ = '$'; + AC_MEMCPY(p, issuer_dn.bv_val, issuer_dn.bv_len); + p += issuer_dn.bv_len; + *p = '\0'; + +#ifdef NEW_LOGGING + LDAP_LOG( CONFIG, ARGS, "certificateExactNormalize: %s\n", + normalized->bv_val, 0, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, "certificateExactNormalize: %s\n", + normalized->bv_val, NULL, NULL ); +#endif + +done: + if (xcert) X509_free(xcert); + if (serial) ch_free(serial); + if (issuer_dn.bv_val) ber_memfree(issuer_dn.bv_val); + return rc; } #endif /* HAVE_TLS */ @@ -2553,13 +2715,13 @@ static slap_syntax_defs_rec syntax_defs[] = { 0, booleanValidate, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.8 DESC 'Certificate' " X_BINARY X_NOT_H_R ")", - SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL}, + SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, certificateValidate, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.9 DESC 'Certificate List' " X_BINARY X_NOT_H_R ")", - SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL}, + SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, sequenceValidate, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.10 DESC 'Certificate Pair' " X_BINARY X_NOT_H_R ")", - SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, berValidate, NULL}, + SLAP_SYNTAX_BINARY|SLAP_SYNTAX_BER, sequenceValidate, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.11 DESC 'Country String' )", 0, countryStringValidate, NULL}, {"( 1.3.6.1.4.1.1466.115.121.1.12 DESC 'Distinguished Name' )", @@ -2659,16 +2821,14 @@ static slap_syntax_defs_rec syntax_defs[] = { {"( 1.3.6.1.1.1.0.1 DESC 'RFC2307 Boot Parameter' )", 0, bootParameterValidate, NULL}, - /* From PKIX */ - /* These OIDs are not published yet, but will be in the next - * I-D for PKIX LDAPv3 schema as have been advanced by David - * Chadwick in private mail. - */ - {"( 1.2.826.0.1.3344810.7.1 DESC 'Serial Number and Issuer' )", - 0, serialNumberAndIssuerValidate, NULL}, + /* From PKIX *//* This OID is not published yet. */ + {"( 1.2.826.0.1.3344810.7.1 DESC 'Certificate Serial Number and Issuer' )", + SLAP_SYNTAX_HIDE, + serialNumberAndIssuerValidate, + serialNumberAndIssuerPretty}, - /* OpenLDAP Experimental Syntaxes */ #ifdef SLAPD_ACI_ENABLED + /* OpenLDAP Experimental Syntaxes */ {"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )", SLAP_SYNTAX_HIDE, UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */, @@ -2681,18 +2841,19 @@ static slap_syntax_defs_rec syntax_defs[] = { SLAP_SYNTAX_HIDE, NULL, NULL}, #endif + {"( 1.3.6.1.4.1.4203.666.2.6 DESC 'UUID' )", + SLAP_SYNTAX_HIDE, UUIDValidate, NULL}, + /* OpenLDAP Void Syntax */ {"( 1.3.6.1.4.1.4203.1.1.1 DESC 'OpenLDAP void' )" , SLAP_SYNTAX_HIDE, inValidate, NULL}, {NULL, 0, NULL, NULL} }; -#ifdef HAVE_TLS char *certificateExactMatchSyntaxes[] = { "1.3.6.1.4.1.1466.115.121.1.8" /* certificate */, NULL }; -#endif char *directoryStringSyntaxes[] = { "1.3.6.1.4.1.1466.115.121.1.44" /* printableString */, NULL @@ -2723,7 +2884,6 @@ char *objectIdentifierFirstComponentMatchSyntaxes[] = { * 2.5.13.31 directoryStringFirstComponentMatch * 2.5.13.32 wordMatch * 2.5.13.33 keywordMatch - * 2.5.13.35 certificateMatch * 2.5.13.36 certificatePairExactMatch * 2.5.13.37 certificatePairMatch * 2.5.13.38 certificateListExactMatch @@ -2949,14 +3109,27 @@ static slap_mrule_defs_rec mrule_defs[] = { octetStringIndexer, octetStringFilter, NULL }, -#ifdef HAVE_TLS {"( 2.5.13.34 NAME 'certificateExactMatch' " "SYNTAX 1.2.826.0.1.3344810.7.1 )", SLAP_MR_EQUALITY | SLAP_MR_EXT, certificateExactMatchSyntaxes, +#ifdef HAVE_TLS NULL, certificateExactNormalize, octetStringMatch, octetStringIndexer, octetStringFilter, +#else + NULL, NULL, NULL, NULL, NULL, +#endif NULL }, + + {"( 2.5.13.35 NAME 'certificateMatch' " + "SYNTAX 1.3.6.1.4.1.1466.115.121.1.8 )", + SLAP_MR_EQUALITY | SLAP_MR_EXT, NULL, +#ifdef HAVE_TLS + NULL, NULL, octetStringMatch, + octetStringIndexer, octetStringFilter, +#else + NULL, NULL, NULL, NULL, NULL, #endif + NULL }, {"( 1.3.6.1.4.1.1466.109.114.1 NAME 'caseExactIA5Match' " "SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )", @@ -3019,6 +3192,20 @@ static slap_mrule_defs_rec mrule_defs[] = { NULL, NULL, "integerMatch" }, + {"( 1.3.6.1.4.1.4203.666.4.6 NAME 'UUIDMatch' " + "SYNTAX 1.3.6.1.4.1.4203.666.2.6 )", + SLAP_MR_HIDE | SLAP_MR_EQUALITY, NULL, + NULL, UUIDNormalize, octetStringMatch, + octetStringIndexer, octetStringFilter, + NULL}, + + {"( 1.3.6.1.4.1.4203.666.4.7 NAME 'UUIDOrderingMatch' " + "SYNTAX 1.3.6.1.4.1.4203.666.2.6 )", + SLAP_MR_HIDE | SLAP_MR_ORDERING, NULL, + NULL, UUIDNormalize, octetStringOrderingMatch, + octetStringIndexer, octetStringFilter, + "UUIDMatch"}, + {NULL, SLAP_MR_NONE, NULL, NULL, NULL, NULL, NULL, NULL, NULL } diff --git a/servers/slapd/schema_prep.c b/servers/slapd/schema_prep.c index 0b43eea524..3fe17d8c28 100644 --- a/servers/slapd/schema_prep.c +++ b/servers/slapd/schema_prep.c @@ -1,4 +1,4 @@ -/* schema_init.c - init builtin schema */ +/* schema_prep.c - load builtin schema */ /* $OpenLDAP$ */ /* * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved. @@ -368,8 +368,9 @@ static struct slap_schema_ad_map { { "entryUUID", "( 1.3.6.1.4.1.4203.666.1.6 NAME 'entryUUID' " "DESC 'UUID of the entry' " - "EQUALITY octetStringMatch " - "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64} " + "EQUALITY UUIDMatch " + "ORDERING UUIDOrderingMatch " + "SYNTAX 1.3.6.1.4.1.4203.666.2.6 " "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", NULL, SLAP_AT_HIDE, NULL, NULL, @@ -422,7 +423,7 @@ static struct slap_schema_ad_map { "DESC 'syncrepl Cookie for shadow copy' " "EQUALITY octetStringMatch " "ORDERING octetStringOrderingMatch " - "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64} " + "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 " "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", NULL, SLAP_AT_HIDE, NULL, NULL, @@ -434,7 +435,7 @@ static struct slap_schema_ad_map { "DESC 'the largest committed CSN of a context' " "EQUALITY octetStringMatch " "ORDERING octetStringOrderingMatch " - "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{64} " + "SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 " "SINGLE-VALUE NO-USER-MODIFICATION USAGE directoryOperation )", NULL, SLAP_AT_HIDE, NULL, NULL, @@ -682,7 +683,7 @@ static struct slap_schema_ad_map { "EQUALITY OpenLDAPaciMatch " "SYNTAX 1.3.6.1.4.1.4203.666.2.1 " "USAGE directoryOperation )", - NULL, 0, + NULL, SLAP_AT_HIDE, NULL, NULL, NULL, NULL, NULL, NULL, NULL, offsetof(struct slap_internal_schema, si_ad_aci) }, diff --git a/servers/slapd/schemaparse.c b/servers/slapd/schemaparse.c index 8eeba03d4d..d05d70ae8d 100644 --- a/servers/slapd/schemaparse.c +++ b/servers/slapd/schemaparse.c @@ -45,7 +45,7 @@ static char *const err2text[] = { "OID could not be expanded", "Duplicate Content Rule", "Content Rule not for STRUCTURAL object class", - "Content Rule AUX contains non-AUXILIARY object class" + "Content Rule AUX contains inappropriate object class", "Content Rule attribute type list contains duplicate" }; @@ -96,8 +96,6 @@ dscompare(const char *s1, const char *s2, char delim) return 0; } -#ifdef SLAP_EXTENDED_SCHEMA - static void cr_usage( void ) { @@ -153,8 +151,6 @@ parse_cr( return 0; } -#endif - int parse_oc( const char *fname, diff --git a/servers/slapd/search.c b/servers/slapd/search.c index 71c8960611..0b898a78bb 100644 --- a/servers/slapd/search.c +++ b/servers/slapd/search.c @@ -159,7 +159,7 @@ do_search( /* attributes */ siz = sizeof(AttributeName); - off = 0; + off = offsetof(AttributeName,an_name); if ( ber_scanf( op->o_ber, "{M}}", &op->ors_attrs, &siz, off ) == LBER_ERROR ) { send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding attrs error" ); rs->sr_err = SLAPD_DISCONNECT; @@ -245,7 +245,8 @@ do_search( manageDSAit = get_manageDSAit( op ); - if ( op->ors_scope == LDAP_SCOPE_BASE ) { + /* fake while loop to allow breaking out */ + while ( op->ors_scope == LDAP_SCOPE_BASE ) { Entry *entry = NULL; if ( op->o_req_ndn.bv_len == 0 ) { @@ -262,16 +263,15 @@ do_search( } #ifdef LDAP_SLAPI - attrs = anlist2charray( op, op->ors_attrs ); - initSearchPlugin( op, attrs, manageDSAit ); - rs->sr_err = doPreSearchPluginFNs( op ); - if ( rs->sr_err == LDAP_SUCCESS ) { + if ( op->o_pb ) { + attrs = anlist2charray( op, op->ors_attrs ); + initSearchPlugin( op, attrs, manageDSAit ); + rs->sr_err = doPreSearchPluginFNs( op ); + if ( rs->sr_err ) break; doSearchRewriteFNs( op ); -#endif /* LDAP_SLAPI */ - rs->sr_err = root_dse_info( op->o_conn, &entry, &rs->sr_text ); -#ifdef LDAP_SLAPI } #endif /* LDAP_SLAPI */ + rs->sr_err = root_dse_info( op->o_conn, &entry, &rs->sr_text ); } else if ( bvmatch( &op->o_req_ndn, &global_schemandn ) ) { /* check restrictions */ @@ -281,22 +281,21 @@ do_search( } #ifdef LDAP_SLAPI - attrs = anlist2charray( op, op->ors_attrs ); - initSearchPlugin( op, attrs, manageDSAit ); - rs->sr_err = doPreSearchPluginFNs( op ); - if ( rs->sr_err == LDAP_SUCCESS ) { + if ( op->o_pb ) { + attrs = anlist2charray( op, op->ors_attrs ); + initSearchPlugin( op, attrs, manageDSAit ); + rs->sr_err = doPreSearchPluginFNs( op ); + if ( rs->sr_err ) break; doSearchRewriteFNs( op ); -#endif /* LDAP_SLAPI */ - rs->sr_err = schema_info( &entry, &rs->sr_text ); -#ifdef LDAP_SLAPI } #endif /* LDAP_SLAPI */ + rs->sr_err = schema_info( &entry, &rs->sr_text ); } if( rs->sr_err != LDAP_SUCCESS ) { send_ldap_result( op, rs ); #ifdef LDAP_SLAPI - doPostSearchPluginFNs( op ); + if ( op->o_pb ) doPostSearchPluginFNs( op ); #endif /* LDAP_SLAPI */ goto return_results; @@ -314,10 +313,11 @@ do_search( rs->sr_err = LDAP_SUCCESS; send_ldap_result( op, rs ); #ifdef LDAP_SLAPI - doPostSearchPluginFNs( op ); + if ( op->o_pb ) doPostSearchPluginFNs( op ); #endif /* LDAP_SLAPI */ goto return_results; } + break; } if( !op->o_req_ndn.bv_len && default_search_nbase.bv_len ) { @@ -372,14 +372,16 @@ do_search( } #ifdef LDAP_SLAPI - attrs = anlist2charray( op, op->ors_attrs ); - initSearchPlugin( op, attrs, manageDSAit ); - rs->sr_err = doPreSearchPluginFNs( op ); - if ( rs->sr_err != LDAP_SUCCESS ) { - goto return_results; - } + if ( op->o_pb ) { + attrs = anlist2charray( op, op->ors_attrs ); + initSearchPlugin( op, attrs, manageDSAit ); + rs->sr_err = doPreSearchPluginFNs( op ); + if ( rs->sr_err != LDAP_SUCCESS ) { + goto return_results; + } - doSearchRewriteFNs( op ); + doSearchRewriteFNs( op ); + } #endif /* LDAP_SLAPI */ /* actually do the search and send the result(s) */ @@ -391,7 +393,7 @@ do_search( } #ifdef LDAP_SLAPI - doPostSearchPluginFNs( op ); + if ( op->o_pb ) doPostSearchPluginFNs( op ); #endif /* LDAP_SLAPI */ return_results:; @@ -399,6 +401,9 @@ return_results:; if ( ( op->o_sync_mode & SLAP_SYNC_PERSIST ) ) return rs->sr_err; + if ( ( op->o_sync_slog_size != -1 ) ) + return rs->sr_err; + if( op->o_req_dn.bv_val != NULL) sl_free( op->o_req_dn.bv_val, op->o_tmpmemctx ); if( op->o_req_ndn.bv_val != NULL) sl_free( op->o_req_ndn.bv_val, op->o_tmpmemctx ); diff --git a/servers/slapd/sessionlog.c b/servers/slapd/sessionlog.c new file mode 100644 index 0000000000..3e4c30987d --- /dev/null +++ b/servers/slapd/sessionlog.c @@ -0,0 +1,140 @@ +/* $OpenLDAP$ */ +/* + * Session History Management Routines + */ +/* + * Copyright 2003 The OpenLDAP Foundation, All Rights Reserved. + * COPYING RESTRICTIONS APPLY, see COPYRIGHT file + */ +/* Copyright (c) 2003 by International Business Machines, Inc. + * + * International Business Machines, Inc. (hereinafter called IBM) grants + * permission under its copyrights to use, copy, modify, and distribute this + * Software with or without fee, provided that the above copyright notice and + * all paragraphs of this notice appear in all copies, and that the name of IBM + * not be used in connection with the marketing of any product incorporating + * the Software or modifications thereof, without specific, written prior + * permission. + * + * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, + * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN + * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +#include "portable.h" + +#include + +#include +#include + +#include "ldap_pvt.h" +#include "lutil.h" +#include "slap.h" +#include "lutil_ldap.h" + +int +slap_send_session_log( + Operation *op, + Operation *sop, + SlapReply *rs +) +{ + Entry e; + AttributeName uuid_attr[2]; + LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS]; + int num_ctrls = 0; + struct slog_entry *slog_e; + int result; + int match; + const char *text; + + uuid_attr[0].an_desc = NULL; + uuid_attr[0].an_oc = NULL; + uuid_attr[0].an_name.bv_len = 0; + uuid_attr[0].an_name.bv_val = NULL; + e.e_attrs = NULL; + e.e_id = 0; + e.e_name.bv_val = NULL; + e.e_name.bv_len = 0; + e.e_nname.bv_val = NULL; + e.e_nname.bv_len = 0; + + for( num_ctrls = 0; + num_ctrls < SLAP_MAX_RESPONSE_CONTROLS; + num_ctrls++ ) { + ctrls[num_ctrls] = NULL; + } + num_ctrls = 0; + + LDAP_STAILQ_FOREACH( slog_e, &sop->o_sync_slog_list, sl_link ) { + + if ( op->o_sync_state.ctxcsn->bv_val == NULL ) { + match = 1; + } else { + value_match( &match, slap_schema.si_ad_entryCSN, + slap_schema.si_ad_entryCSN->ad_type->sat_ordering, + SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, + op->o_sync_state.ctxcsn, &slog_e->sl_csn, &text ); + } + + if ( match < 0 ) { + rs->sr_err = slap_build_sync_state_ctrl_from_slog( op, rs, slog_e, + LDAP_SYNC_DELETE, ctrls, num_ctrls++, 0, NULL ); + + if ( rs->sr_err != LDAP_SUCCESS ) + return rs->sr_err; + + if ( e.e_name.bv_val ) + ch_free( e.e_name.bv_val ); + ber_dupbv( &e.e_name, &slog_e->sl_name ); + + rs->sr_entry = &e; + rs->sr_attrs = uuid_attr; + rs->sr_ctrls = ctrls; + result = send_search_entry( op, rs ); + sl_free( ctrls[num_ctrls-1]->ldctl_value.bv_val, op->o_tmpmemctx ); + sl_free( ctrls[--num_ctrls], op->o_tmpmemctx ); + ctrls[num_ctrls] = NULL; + rs->sr_ctrls = NULL; + } + } +} + +int +slap_add_session_log( + Operation *op, + Operation *sop, + Entry *e +) +{ + struct slog_entry* slog_e; + Attribute *a; + + slog_e = (struct slog_entry *) ch_calloc (1, sizeof( struct slog_entry )); + a = attr_find( e->e_attrs, slap_schema.si_ad_entryUUID ); + ber_dupbv( &slog_e->sl_uuid, &a->a_nvals[0] ); + ber_dupbv( &slog_e->sl_name, &e->e_name ); + ber_dupbv( &slog_e->sl_csn, &op->o_sync_csn ); + LDAP_STAILQ_INSERT_TAIL( &sop->o_sync_slog_list, slog_e, sl_link ); + sop->o_sync_slog_len++; + + while ( sop->o_sync_slog_len > sop->o_sync_slog_size ) { + slog_e = LDAP_STAILQ_FIRST( &sop->o_sync_slog_list ); + if ( sop->o_sync_slog_omitcsn.bv_val ) { + ch_free( sop->o_sync_slog_omitcsn.bv_val ); + } + ber_dupbv( &sop->o_sync_slog_omitcsn, &slog_e->sl_csn ); + LDAP_STAILQ_REMOVE_HEAD( &sop->o_sync_slog_list, sl_link ); + ch_free( slog_e->sl_uuid.bv_val ); + ch_free( slog_e->sl_name.bv_val ); + ch_free( slog_e->sl_csn.bv_val ); + ch_free( slog_e ); + sop->o_sync_slog_len--; + } + + return LDAP_SUCCESS; +} diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index 30465dffdd..4185bba5fc 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -36,8 +36,6 @@ #include "ldap_pvt_thread.h" #include "ldap_queue.h" -#define SLAP_EXTENDED_SCHEMA 1 - LDAP_BEGIN_DECL /* * SLAPD Memory allocation macros @@ -98,6 +96,10 @@ LDAP_BEGIN_DECL #define ASCII_UPPER(c) ( (c) >= 'A' && (c) <= 'Z' ) #define ASCII_ALPHA(c) ( ASCII_LOWER(c) || ASCII_UPPER(c) ) #define ASCII_DIGIT(c) ( (c) >= '0' && (c) <= '9' ) +#define ASCII_HEXLOWER(c) ( (c) >= 'a' && (c) <= 'f' ) +#define ASCII_HEXUPPER(c) ( (c) >= 'A' && (c) <= 'F' ) +#define ASCII_HEX(c) ( ASCII_DIGIT(c) || \ + ASCII_HEXLOWER(c) || ASCII_HEXUPPER(c) ) #define ASCII_ALNUM(c) ( ASCII_ALPHA(c) || ASCII_DIGIT(c) ) #define ASCII_PRINTABLE(c) ( (c) >= ' ' && (c) <= '~' ) @@ -451,11 +453,18 @@ typedef struct slap_matching_rule { */ #define SLAP_MR_VALUE_OF_ASSERTION_SYNTAX 0x0001U #define SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX 0x0002U +#define SLAP_MR_VALUE_OF_SYNTAX 0x0003U #define SLAP_MR_IS_VALUE_OF_ATTRIBUTE_SYNTAX( usage ) \ ((usage) & SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX ) #define SLAP_MR_IS_VALUE_OF_ASSERTION_SYNTAX( usage ) \ ((usage) & SLAP_MR_VALUE_OF_ASSERTION_SYNTAX ) +#ifdef LDAP_DEBUG +#define SLAP_MR_IS_VALUE_OF_SYNTAX( usage ) \ + ((usage) & SLAP_MR_VALUE_OF_SYNTAX) +#else +#define SLAP_MR_IS_VALUE_OF_SYNTAX( usage ) (1) +#endif /* either or both the asserted value or attribute value * may be provided in normalized form @@ -1278,55 +1287,60 @@ typedef BackendDB Backend; #define nbackends nBackendDB #define backends backendDB +/* + * syncinfo structure for syncrepl + */ + +#define SLAP_SYNC_SID_SIZE 3 +#define SLAP_SYNCUUID_SET_SIZE 256 + struct nonpresent_entry { - struct berval *dn; - struct berval *ndn; - LDAP_LIST_ENTRY(nonpresent_entry) np_link; + struct berval *npe_name; + struct berval *npe_nname; + LDAP_LIST_ENTRY(nonpresent_entry) npe_link; +}; + +struct sync_cookie { + struct berval *ctxcsn; + long sid; + struct berval *octet_str; }; - /* - * syncinfo structure for syncrepl - */ typedef struct syncinfo_s { - struct slap_conn *conn; - struct slap_backend_db *be; - struct slap_entry *e; - void *ctx; - int id; - char *provideruri; - BerVarray provideruri_bv; -#define TLS_OFF 0 -#define TLS_ON 1 -#define TLS_CRITICAL 2 - int tls; - struct berval updatedn; - int bindmethod; - char *binddn; - char *passwd; - char *saslmech; - char *secprops; - char *realm; - char *authcId; - char *authzId; - char *srvtab; - int schemachecking; - Filter *filter; - char *filterstr; - char *base; - int scope; - int attrsonly; - char **attrs; - int type; - time_t interval; - struct berval *syncCookie; - int manageDSAit; - int slimit; - int tlimit; - struct berval *syncUUID; - struct berval *syncUUID_ndn; - Avlnode *presentlist; - int sync_mode; - LDAP_LIST_HEAD(np, nonpresent_entry) nonpresentlist; + struct slap_backend_db *si_be; + unsigned int si_id; + char *si_provideruri; + BerVarray si_provideruri_bv; +#define SYNCINFO_TLS_OFF 0 +#define SYNCINFO_TLS_ON 1 +#define SYNCINFO_TLS_CRITICAL 2 + int si_tls; + struct berval si_updatedn; + int si_bindmethod; + char *si_binddn; + char *si_passwd; + char *si_saslmech; + char *si_secprops; + char *si_realm; + char *si_authcId; + char *si_authzId; + int si_schemachecking; + Filter *si_filter; + struct berval si_filterstr; + struct berval si_base; + int si_scope; + int si_attrsonly; + char **si_attrs; + int si_type; + time_t si_interval; + struct sync_cookie si_syncCookie; + int si_manageDSAit; + int si_slimit; + int si_tlimit; + struct berval si_syncUUID_ndn; + Avlnode *si_presentlist; + LDAP *si_ld; + LDAP_LIST_HEAD(np, nonpresent_entry) si_nonpresentlist; } syncinfo_t; struct slap_backend_db { @@ -1481,7 +1495,7 @@ struct slap_backend_db { ldap_pvt_thread_mutex_t be_pcl_mutex; struct berval be_context_csn; ldap_pvt_thread_mutex_t be_context_csn_mutex; - syncinfo_t *syncinfo; /* For syncrepl */ + syncinfo_t *be_syncinfo; /* For syncrepl */ }; struct slap_conn; @@ -1807,6 +1821,21 @@ struct psid_entry { LDAP_LIST_ENTRY(psid_entry) ps_link; }; +struct slog_entry { + struct berval sl_uuid; + struct berval sl_name; + struct berval sl_csn; + LDAP_STAILQ_ENTRY(slog_entry) sl_link; +}; + +/* session lists */ +struct slap_session_entry { + int se_id; + int se_size; + struct berval se_spec; + LDAP_LIST_ENTRY( slap_session_entry ) se_link; +}; + struct slap_csn_entry { struct berval *csn; unsigned long opid; @@ -1817,6 +1846,19 @@ struct slap_csn_entry { LDAP_TAILQ_ENTRY (slap_csn_entry) csn_link; }; +/* + * Caches the result of a backend_group check for ACL evaluation + */ +typedef struct slap_gacl { + struct slap_gacl *ga_next; + Backend *ga_be; + ObjectClass *ga_oc; + AttributeDescription *ga_at; + int ga_res; + ber_len_t ga_len; + char ga_ndn[1]; +} GroupAssertion; + /* * represents an operation pending from an ldap client */ @@ -1895,7 +1937,8 @@ typedef struct slap_op { #define SLAP_CANCEL_ACK 0x02 #define SLAP_CANCEL_DONE 0x03 - char o_do_not_cache; /* don't cache from this op */ + GroupAssertion *o_groups; + char o_do_not_cache; /* don't cache groups from this op */ char o_is_auth_check; /* authorization in progress */ #define SLAP_NO_CONTROL 0 @@ -1947,13 +1990,21 @@ typedef struct slap_op { char o_sync; char o_sync_mode; -#define SLAP_SYNC_NONE (0x0) -#define SLAP_SYNC_REFRESH (0x1) -#define SLAP_SYNC_PERSIST (0x2) -#define SLAP_SYNC_REFRESH_AND_PERSIST (0x3) - struct berval o_sync_state; +#define SLAP_SYNC_NONE (0x0) +#define SLAP_SYNC_REFRESH (0x1) +#define SLAP_SYNC_PERSIST (0x2) +#define SLAP_SYNC_REFRESH_AND_PERSIST (0x3) + struct sync_cookie o_sync_state; + int o_sync_rhint; + struct berval o_sync_cid; + int o_sync_slog_size; + struct berval o_sync_csn; + struct berval o_sync_slog_omitcsn; + int o_sync_slog_len; + LDAP_STAILQ_HEAD(sl, slog_entry) o_sync_slog_list; int o_ps_entries; + int o_no_psearch; LDAP_LIST_ENTRY(slap_op) o_ps_link; LDAP_LIST_HEAD(pe, psid_entry) o_pm_list; @@ -1980,7 +2031,6 @@ typedef struct slap_op { ValuesReturnFilter *o_vrFilter; /* ValuesReturnFilter */ - syncinfo_t* o_si; int o_nocaching; #ifdef LDAP_SLAPI @@ -2020,19 +2070,6 @@ typedef void (SEND_LDAP_INTERMEDIATE)( #define send_ldap_intermediate( op, rs ) \ (op->o_conn->c_send_ldap_intermediate)( op, rs ) -/* - * Caches the result of a backend_group check for ACL evaluation - */ -typedef struct slap_gacl { - struct slap_gacl *ga_next; - Backend *ga_be; - ObjectClass *ga_oc; - AttributeDescription *ga_at; - int ga_res; - ber_len_t ga_len; - char ga_ndn[1]; -} GroupAssertion; - typedef struct slap_listener Listener; /* @@ -2065,7 +2102,6 @@ typedef struct slap_conn { Backend *c_authz_backend; AuthorizationInformation c_authz; - GroupAssertion *c_groups; ber_int_t c_protocol; /* version of the LDAP protocol used by client */ @@ -2078,6 +2114,10 @@ typedef struct slap_conn { BerElement *c_currentber; /* ber we're attempting to read */ int c_writewaiter; /* true if writer is waiting */ +#define CONN_IS_TLS 1 +#define CONN_IS_UDP 2 +#define CONN_IS_CLIENT 3 + #ifdef LDAP_CONNECTIONLESS int c_is_udp; /* true if this is (C)LDAP over UDP */ #endif @@ -2106,6 +2146,12 @@ typedef struct slap_conn { void *c_pb; /* Netscape plugin */ void *c_extensions; /* Netscape plugin */ + /* + * Client connection handling + */ + ldap_pvt_thread_start_t *c_clientfunc; + void *c_clientarg; + /* * These are the "callbacks" that are available for back-ends to * supply data back to connected clients that are connected diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c index b079892cd3..ef28f922cd 100644 --- a/servers/slapd/syncrepl.c +++ b/servers/slapd/syncrepl.c @@ -2,6 +2,10 @@ /* * Replication Engine which uses the LDAP Sync protocol */ +/* + * Copyright 2003 The OpenLDAP Foundation, All Rights Reserved. + * COPYING RESTRICTIONS APPLY, see COPYRIGHT file + */ /* Copyright (c) 2003 by International Business Machines, Inc. * * International Business Machines, Inc. (hereinafter called IBM) grants @@ -19,6 +23,12 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. */ +/* Modified by Howard Chu + * + * Copyright (c) 2003 by Howard Chu, Symas Corporation + * + * Modifications provided under the terms of the OpenLDAP public license. + */ #include "portable.h" @@ -26,7 +36,6 @@ #include #include -#include #include "ldap_pvt.h" #include "lutil.h" @@ -35,471 +44,478 @@ #include "ldap_rq.h" -static const struct berval slap_syncrepl_bvc = BER_BVC("syncreplxxx"); -static const struct berval slap_syncrepl_cn_bvc = BER_BVC("cn=syncreplxxx"); +#define SYNCREPL_STR "syncreplxxx" +#define CN_STR "cn=" -static void -syncrepl_del_nonpresent( LDAP *, Operation * ); +static const struct berval slap_syncrepl_bvc = BER_BVC(SYNCREPL_STR); +static const struct berval slap_syncrepl_cn_bvc = BER_BVC(CN_STR SYNCREPL_STR); + +static int syncuuid_cmp( const void *, const void * ); +static void avl_ber_bvfree( void * ); +static void syncrepl_del_nonpresent( Operation *, syncinfo_t * ); /* callback functions */ -static int cookie_callback( struct slap_op *, struct slap_rep * ); static int dn_callback( struct slap_op *, struct slap_rep * ); static int nonpresent_callback( struct slap_op *, struct slap_rep * ); static int null_callback( struct slap_op *, struct slap_rep * ); -static int contextcsn_callback( Operation*, SlapReply* ); -static AttributeDescription **sync_descs; +static AttributeDescription *sync_descs[4]; struct runqueue_s syncrepl_rq; void -init_syncrepl() -{ - sync_descs = ch_malloc( 4 * sizeof( AttributeDescription * )); - sync_descs[0] = slap_schema.si_ad_objectClass; - sync_descs[1] = slap_schema.si_ad_structuralObjectClass; - sync_descs[2] = slap_schema.si_ad_entryCSN; - sync_descs[3] = NULL; -} - -int -ldap_sync_search( - syncinfo_t *si, - LDAP *ld, - LDAPControl **sctrls, - LDAPControl **cctrls, - int *msgidp ) +init_syncrepl(syncinfo_t *si) { - BerElement *ber; - int timelimit; - ber_int_t id; - - int rc; - BerElement *sync_ber = NULL; - struct berval *sync_bvalp = NULL; - LDAPControl c[2]; - LDAPControl **ctrls; - int err; - struct timeval timeout; - - /* setup LDAP SYNC control */ - sync_ber = ber_alloc_t( LBER_USE_DER ); - ber_set_option( sync_ber, LBER_OPT_BER_MEMCTX, NULL ); - - if ( si->syncCookie ) { - ber_printf( sync_ber, "{eO}", abs(si->type), si->syncCookie ); - } else { - ber_printf( sync_ber, "{e}", abs(si->type) ); - } - - if ( ber_flatten( sync_ber, &sync_bvalp ) == LBER_ERROR ) { - ber_free( sync_ber, 1 ); - return LBER_ERROR; - } - ber_free( sync_ber, 1 ); - - ctrls = (LDAPControl**) sl_calloc( 3, sizeof(LDAPControl*), NULL ); - - c[0].ldctl_oid = LDAP_CONTROL_SYNC; - c[0].ldctl_value = (*sync_bvalp); - c[0].ldctl_iscritical = si->type < 0; - ctrls[0] = &c[0]; - - if ( si->authzId ) { - c[1].ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ; - c[1].ldctl_value.bv_val = si->authzId; - c[1].ldctl_value.bv_len = strlen( si->authzId ); - c[1].ldctl_iscritical = 1; - ctrls[1] = &c[1]; - } else { - ctrls[1] = NULL; - } - - ctrls[2] = NULL; - - err = ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS, ctrls ); + int i, j, k, n; + char **tmp; - ber_bvfree( sync_bvalp ); - ch_free( ctrls ); + if ( !sync_descs[0] ) { + sync_descs[0] = slap_schema.si_ad_objectClass; + sync_descs[1] = slap_schema.si_ad_structuralObjectClass; + sync_descs[2] = slap_schema.si_ad_entryCSN; + sync_descs[3] = NULL; + } - if ( err != LDAP_OPT_SUCCESS ) - fprintf( stderr, "Could not set controls : %d\n", err ); + for ( n = 0; si->si_attrs[ n ] != NULL; n++ ) /* empty */; - timeout.tv_sec = si->tlimit > 0 ? si->tlimit : 1; + if ( n ) { + /* Delete Attributes */ + for ( i = 0; sync_descs[i] != NULL; i++ ) { + for ( j = 0; si->si_attrs[j] != NULL; j++ ) { + if ( strcmp( si->si_attrs[j], sync_descs[i]->ad_cname.bv_val ) + == 0 ) + { + ch_free( si->si_attrs[j] ); + for ( k = j; si->si_attrs[k] != NULL; k++ ) { + si->si_attrs[k] = si->si_attrs[k+1]; + } + } + } + } + for ( n = 0; si->si_attrs[ n ] != NULL; n++ ) /* empty */; + tmp = ( char ** ) ch_realloc( si->si_attrs, (n + 4)*sizeof( char * )); + if ( tmp == NULL ) { +#ifdef NEW_LOGGING + LDAP_LOG( OPERATION, ERR, "out of memory\n", 0,0,0 ); +#else + Debug( LDAP_DEBUG_ANY, "out of memory\n", 0,0,0 ); +#endif + } + } else { + tmp = ( char ** ) ch_realloc( si->si_attrs, 5 * sizeof( char * )); + if ( tmp == NULL ) { +#ifdef NEW_LOGGING + LDAP_LOG( OPERATION, ERR, "out of memory\n", 0,0,0 ); +#else + Debug( LDAP_DEBUG_ANY, "out of memory\n", 0,0,0 ); +#endif + } + tmp[ n++ ] = ch_strdup( "*" ); + } + + si->si_attrs = tmp; - rc = ldap_search_ext( ld, si->base, si->scope, si->filterstr, - si->attrs, si->attrsonly, sctrls, cctrls, - si->tlimit < 0 ? NULL : &timeout, - si->slimit, msgidp ); + /* Add Attributes */ - return rc; + for ( i = 0; sync_descs[ i ] != NULL; i++ ) { + si->si_attrs[ n++ ] = ch_strdup ( sync_descs[i]->ad_cname.bv_val ); + si->si_attrs[ n ] = NULL; + } } -void * -do_syncrepl( - void *ctx, - void *arg ) +static int +ldap_sync_search( + syncinfo_t *si, + void *ctx +) { - struct re_s* rtask = arg; - syncinfo_t *si = ( syncinfo_t * ) rtask->arg; - Backend *be = si->be; - - SlapReply rs = {REP_RESULT}; - - LDAPControl c[2]; - LDAPControl **sctrls = NULL; - LDAPControl **rctrls = NULL; - LDAPControl *rctrlp = NULL; - BerElement *sync_ber = NULL; - struct berval *sync_bvalp = NULL; - - BerElement *ctrl_ber = NULL; - BerElement *res_ber = NULL; - - LDAP *ld = NULL; - LDAPMessage *res = NULL; - LDAPMessage *msg = NULL; - + BerElementBuffer berbuf; + BerElement *ber = (BerElement *)&berbuf; + LDAPControl c[2], *ctrls[3]; + struct timeval timeout; ber_int_t msgid; + int rc; - int nresponses, nreferences, nextended, npartial; - int nresponses_psearch; - - int cancel_msgid = -1; - char *retoid = NULL; - struct berval *retdata = NULL; - - int sync_info_arrived = 0; - Entry *entry = NULL; - - int syncstate; - struct berval syncUUID = { 0, NULL }; - struct berval syncCookie = { 0, NULL }; - struct berval syncCookie_req = { 0, NULL }; - - int rc; - int err; - ber_len_t len; - int syncinfo_arrived = 0; - - char **tmp = NULL; - AttributeDescription** descs = NULL; + /* setup LDAP SYNC control */ + ber_init2( ber, NULL, LBER_USE_DER ); + ber_set_option( ber, LBER_OPT_BER_MEMCTX, &ctx ); - Connection conn; - Operation op = {0}; - slap_callback cb; + if ( si->si_syncCookie.octet_str && + si->si_syncCookie.octet_str[0].bv_val ) { + ber_printf( ber, "{eO}", abs(si->si_type), + &si->si_syncCookie.octet_str[0] ); + } else { + ber_printf( ber, "{e}", abs(si->si_type) ); + } - void *memctx = NULL; - ber_len_t memsiz; - - int i, j, k, n; - int rc_efree; + if ( (rc = ber_flatten2( ber, &c[0].ldctl_value, 0 )) == LBER_ERROR ) { + ber_free_buf( ber ); + return rc; + } - struct berval base_bv = { 0, NULL }; - struct berval pbase = { 0, NULL }; - struct berval nbase = { 0, NULL }; - struct berval psubrdn = { 0, NULL }; - struct berval nsubrdn = { 0, NULL }; - struct berval psub = { 0, NULL }; - struct berval nsub = { 0, NULL }; - Modifications *modlist = NULL; - Modifications *ml, *mlnext; - char *def_filter_str = NULL; + c[0].ldctl_oid = LDAP_CONTROL_SYNC; + c[0].ldctl_iscritical = si->si_type < 0; + ctrls[0] = &c[0]; - struct berval slap_syncrepl_bv = BER_BVNULL; + if ( si->si_authzId ) { + c[1].ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ; + ber_str2bv( si->si_authzId, 0, 0, &c[1].ldctl_value ); + c[1].ldctl_iscritical = 1; + ctrls[1] = &c[1]; + ctrls[2] = NULL; + } else { + ctrls[1] = NULL; + } - const char *text; - int match; + timeout.tv_sec = si->si_tlimit > 0 ? si->si_tlimit : 1; + timeout.tv_usec = 0; - struct timeval *tout_p = NULL; - struct timeval tout = { 10, 0 }; + rc = ldap_search_ext( si->si_ld, si->si_base.bv_val, si->si_scope, + si->si_filterstr.bv_val, si->si_attrs, si->si_attrsonly, + ctrls, NULL, si->si_tlimit < 0 ? NULL : &timeout, + si->si_slimit, &msgid ); + ber_free_buf( ber ); -#ifdef NEW_LOGGING - LDAP_LOG ( OPERATION, DETAIL1, "do_syncrepl\n", 0, 0, 0 ); -#else - Debug( LDAP_DEBUG_TRACE, "=>do_syncrepl\n", 0, 0, 0 ); -#endif + return rc; +} - if ( si == NULL ) - return NULL; +static const Listener dummy_list = { {0, ""}, {0, ""} }; - if ( abs(si->type) != LDAP_SYNC_REFRESH_ONLY && - abs(si->type) != LDAP_SYNC_REFRESH_AND_PERSIST ) { - return NULL; - } +static int +do_syncrep1( + Operation *op, + syncinfo_t *si ) +{ + int rc; - si->sync_mode = LDAP_SYNC_STATE_MODE; + char syncrepl_cbuf[sizeof(CN_STR SYNCREPL_STR)]; + struct berval syncrepl_cn_bv; + struct sync_cookie syncCookie = { NULL, -1, NULL }; /* Init connection to master */ - rc = ldap_initialize( &ld, si->provideruri ); + rc = ldap_initialize( &si->si_ld, si->si_provideruri ); if ( rc != LDAP_SUCCESS ) { #ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, "do_syncrepl: " - "ldap_initialize failed (%s)\n", - si->provideruri, 0, 0 ); + LDAP_LOG( OPERATION, ERR, + "do_syncrep1: ldap_initialize failed (%s)\n", + si->si_provideruri, 0, 0 ); #else - Debug( LDAP_DEBUG_ANY, "do_syncrepl: " - "ldap_initialize failed (%s)\n", - si->provideruri, 0, 0 ); + Debug( LDAP_DEBUG_ANY, + "do_syncrep1: ldap_initialize failed (%s)\n", + si->si_provideruri, 0, 0 ); #endif + return rc; } - op.o_protocol = LDAP_VERSION3; - ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &op.o_protocol ); + op->o_protocol = LDAP_VERSION3; + ldap_set_option( si->si_ld, LDAP_OPT_PROTOCOL_VERSION, &op->o_protocol ); /* Bind to master */ - if ( si->tls ) { - rc = ldap_start_tls_s( ld, NULL, NULL ); + if ( si->si_tls ) { + rc = ldap_start_tls_s( si->si_ld, NULL, NULL ); if( rc != LDAP_SUCCESS ) { #ifdef NEW_LOGGING - LDAP_LOG ( OPERATION, ERR, "do_syncrepl: " + LDAP_LOG ( OPERATION, ERR, "do_syncrep1: " "%s: ldap_start_tls failed (%d)\n", - si->tls == TLS_CRITICAL ? "Error" : "Warning", + si->si_tls == SYNCINFO_TLS_CRITICAL ? "Error" : "Warning", rc, 0 ); #else Debug( LDAP_DEBUG_ANY, "%s: ldap_start_tls failed (%d)\n", - si->tls == TLS_CRITICAL ? "Error" : "Warning", + si->si_tls == SYNCINFO_TLS_CRITICAL ? "Error" : "Warning", rc, 0 ); #endif - if( si->tls == TLS_CRITICAL ) - return NULL; + if( si->si_tls == SYNCINFO_TLS_CRITICAL ) goto done; } } - if ( si->bindmethod == LDAP_AUTH_SASL ) { + if ( si->si_bindmethod == LDAP_AUTH_SASL ) { #ifdef HAVE_CYRUS_SASL void *defaults; - if ( si->secprops != NULL ) { - int err = ldap_set_option( ld, - LDAP_OPT_X_SASL_SECPROPS, si->secprops); + if ( si->si_secprops != NULL ) { + rc = ldap_set_option( si->si_ld, + LDAP_OPT_X_SASL_SECPROPS, si->si_secprops); - if( err != LDAP_OPT_SUCCESS ) { + if( rc != LDAP_OPT_SUCCESS ) { #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, ERR, "do_bind: Error: " "ldap_set_option(%s,SECPROPS,\"%s\") failed!\n", - si->provideruri, si->secprops, 0 ); + si->si_provideruri, si->si_secprops, 0 ); #else Debug( LDAP_DEBUG_ANY, "Error: ldap_set_option " "(%s,SECPROPS,\"%s\") failed!\n", - si->provideruri, si->secprops, NULL ); + si->si_provideruri, si->si_secprops, 0 ); #endif - return NULL; + goto done; } } - defaults = lutil_sasl_defaults( ld, - si->saslmech, - si->realm, - si->authcId, - si->passwd, - si->authzId ); + defaults = lutil_sasl_defaults( si->si_ld, + si->si_saslmech, si->si_realm, + si->si_authcId, si->si_passwd, si->si_authzId ); - rc = ldap_sasl_interactive_bind_s( ld, - si->binddn, - si->saslmech, + rc = ldap_sasl_interactive_bind_s( si->si_ld, + si->si_binddn, + si->si_saslmech, NULL, NULL, LDAP_SASL_QUIET, lutil_sasl_interact, defaults ); + lutil_sasl_freedefs( defaults ); + /* FIXME : different error behaviors according to - 1) return code - 2) on err policy : exit, retry, backoff ... - */ + * 1) return code + * 2) on err policy : exit, retry, backoff ... + */ if ( rc != LDAP_SUCCESS ) { #ifdef NEW_LOGGING - LDAP_LOG ( OPERATION, ERR, "do_syncrepl: " + LDAP_LOG ( OPERATION, ERR, "do_syncrep1: " "ldap_sasl_interactive_bind_s failed (%d)\n", rc, 0, 0 ); #else - Debug( LDAP_DEBUG_ANY, "do_syncrepl: " + Debug( LDAP_DEBUG_ANY, "do_syncrep1: " "ldap_sasl_interactive_bind_s failed (%d)\n", rc, 0, 0 ); #endif - return NULL; + goto done; } #else /* HAVE_CYRUS_SASL */ + /* Should never get here, we trapped this at config time */ fprintf( stderr, "not compiled with SASL support\n" ); - return NULL; + rc = LDAP_OTHER; + goto done; #endif } else { - rc = ldap_bind_s( ld, si->binddn, si->passwd, si->bindmethod ); + rc = ldap_bind_s( si->si_ld, si->si_binddn, si->si_passwd, si->si_bindmethod ); if ( rc != LDAP_SUCCESS ) { #ifdef NEW_LOGGING - LDAP_LOG ( OPERATION, ERR, "do_syncrepl: " + LDAP_LOG ( OPERATION, ERR, "do_syncrep1: " "ldap_bind_s failed (%d)\n", rc, 0, 0 ); #else - Debug( LDAP_DEBUG_ANY, "do_syncrepl: " + Debug( LDAP_DEBUG_ANY, "do_syncrep1: " "ldap_bind_s failed (%d)\n", rc, 0, 0 ); #endif - return NULL; + goto done; } } - /* set thread context in syncinfo */ - si->ctx = ctx; + /* get syncrepl cookie of shadow replica from subentry */ - /* set memory context */ -#define SLAB_SIZE 1048576 - memsiz = SLAB_SIZE; - memctx = sl_mem_create( memsiz, ctx ); - op.o_tmpmemctx = memctx; - op.o_tmpmfuncs = &sl_mfuncs; + assert( si->si_id < 1000 ); + syncrepl_cn_bv.bv_val = syncrepl_cbuf; + syncrepl_cn_bv.bv_len = snprintf(syncrepl_cbuf, sizeof(syncrepl_cbuf), + CN_STR "syncrepl%d", si->si_id ); + build_new_dn( &op->o_req_ndn, &si->si_base, &syncrepl_cn_bv, + op->o_tmpmemctx ); + op->o_req_dn = op->o_req_ndn; + + if ( slap_sync_cookie != NULL ) { + /* cookie is supplied in the command line */ + + BerVarray cookie = NULL; + struct berval cookie_bv; + + slap_sync_cookie_free( &si->si_syncCookie, 0 ); + slap_parse_sync_cookie( slap_sync_cookie ); + + /* read stored cookie if it exists */ + backend_attribute( op, NULL, &op->o_req_ndn, + slap_schema.si_ad_syncreplCookie, &cookie ); + + if ( !cookie ) { + /* no stored cookie */ + if ( slap_sync_cookie->ctxcsn == NULL || + slap_sync_cookie->ctxcsn->bv_val == NULL ) { + /* if slap_sync_cookie does not have ctxcsn component */ + /* set it to an initial value */ + slap_init_sync_cookie_ctxcsn( slap_sync_cookie ); + } + slap_dup_sync_cookie( &si->si_syncCookie, slap_sync_cookie ); + slap_sync_cookie_free( slap_sync_cookie, 1 ); + slap_sync_cookie = NULL; + } else { + /* stored cookie */ + ber_dupbv( &cookie_bv, &cookie[0] ); + ber_bvarray_add( &si->si_syncCookie.octet_str, &cookie_bv ); + slap_parse_sync_cookie( &si->si_syncCookie ); + ber_bvarray_free_x( cookie, op->o_tmpmemctx ); + if ( slap_sync_cookie->sid != -1 ) { + /* command line cookie wins */ + si->si_syncCookie.sid = slap_sync_cookie->sid; + } + if ( slap_sync_cookie->ctxcsn != NULL ) { + /* command line cookie wins */ + if ( si->si_syncCookie.ctxcsn ) { + ber_bvarray_free( si->si_syncCookie.ctxcsn ); + si->si_syncCookie.ctxcsn = NULL; + } + ber_dupbv( &cookie_bv, &slap_sync_cookie->ctxcsn[0] ); + ber_bvarray_add( &si->si_syncCookie.ctxcsn, &cookie_bv ); + } + slap_sync_cookie_free( slap_sync_cookie, 1 ); + slap_sync_cookie = NULL; + } + } else { + /* no command line cookie is specified */ + if ( si->si_syncCookie.octet_str == NULL ) { + BerVarray cookie = NULL; + struct berval cookie_bv; + /* try to read stored cookie */ + backend_attribute( op, NULL, &op->o_req_ndn, + slap_schema.si_ad_syncreplCookie, &cookie ); + if ( cookie ) { + ber_dupbv( &cookie_bv, &cookie[0] ); + ber_bvarray_add( &si->si_syncCookie.octet_str, &cookie_bv ); + slap_parse_sync_cookie( &si->si_syncCookie ); + ber_bvarray_free_x( cookie, op->o_tmpmemctx ); + } + } + } - op.o_si = si; - op.o_tag = LDAP_REQ_SEARCH; - op.o_dn = si->updatedn; - op.o_ndn = si->updatedn; - op.o_callback = &cb; - op.o_time = slap_get_time(); - op.o_managedsait = 1; - op.o_threadctx = si->ctx; - op.o_bd = be; - op.o_conn = &conn; - op.o_connid = op.o_conn->c_connid; - op.ors_scope = LDAP_SCOPE_BASE; - op.ors_deref = LDAP_DEREF_NEVER; - op.ors_slimit = 0; - op.ors_tlimit = 0; - op.ors_attrsonly = 0; - op.ors_attrs = NULL; - op.ors_filter = str2filter_x( &op, def_filter_str = "(objectClass=*)" ); - ber_str2bv( def_filter_str, 0, 0, &op.ors_filterstr ); - - si->conn = &conn; - conn.c_send_ldap_result = slap_send_ldap_result; - conn.c_send_search_entry = slap_send_search_entry; - conn.c_send_search_reference = slap_send_search_reference; + rc = ldap_sync_search( si, op->o_tmpmemctx ); - /* get syncrepl cookie of shadow replica from subentry */ - ber_str2bv( si->base, 0, 0, &base_bv ); - dnPrettyNormal( 0, &base_bv, &pbase, &nbase, op.o_tmpmemctx ); + if( rc != LDAP_SUCCESS ) { +#ifdef NEW_LOGGING + LDAP_LOG ( OPERATION, ERR, "do_syncrep1: " + "ldap_search_ext: %s (%d)\n", ldap_err2string( rc ), rc, 0 ); +#else + Debug( LDAP_DEBUG_ANY, "do_syncrep1: " + "ldap_search_ext: %s (%d)\n", ldap_err2string( rc ), rc, 0 ); +#endif + } - ber_dupbv( &slap_syncrepl_bv, (struct berval *) &slap_syncrepl_bvc ); - slap_syncrepl_bv.bv_len = snprintf( slap_syncrepl_bv.bv_val, - slap_syncrepl_bvc.bv_len, - "syncrepl%d", si->id ); - build_new_dn( &op.o_req_dn, &pbase, &slap_syncrepl_bv, op.o_tmpmemctx ); - build_new_dn( &op.o_req_ndn, &nbase, &slap_syncrepl_bv, op.o_tmpmemctx ); +done: + if ( rc ) { + if ( si->si_ld ) { + ldap_unbind( si->si_ld ); + si->si_ld = NULL; + } + } - /* set callback function */ - cb.sc_response = cookie_callback; - cb.sc_private = si; + return rc; +} - /* search subentry to retrieve cookie */ - si->syncCookie = NULL; - be->be_search( &op, &rs ); +static int +do_syncrep2( + Operation *op, + syncinfo_t *si ) +{ + LDAPControl **rctrls = NULL; + LDAPControl *rctrlp; - if ( op.o_req_dn.bv_val ) - ch_free( op.o_req_dn.bv_val ); - if ( op.o_req_ndn.bv_val ) - ch_free( op.o_req_ndn.bv_val ); - if ( op.ors_filter ) - filter_free( op.ors_filter ); - if ( op.ors_filterstr.bv_val ) - ch_free( op.ors_filterstr.bv_val ); - if ( slap_syncrepl_bv.bv_val ) - ch_free( slap_syncrepl_bv.bv_val ); - if ( pbase.bv_val ) - ch_free( pbase.bv_val ); - if ( nbase.bv_val ) - ch_free( nbase.bv_val ); + BerElementBuffer berbuf; + BerElement *ber = (BerElement *)&berbuf; - ber_dupbv( &syncCookie_req, si->syncCookie ); + LDAPMessage *res = NULL; + LDAPMessage *msg = NULL; - psub = be->be_nsuffix[0]; + char *retoid = NULL; + struct berval *retdata = NULL; - for ( n = 0; si->attrs[ n ] != NULL; n++ ) ; + Entry *entry = NULL; + + int syncstate; + struct berval syncUUID = { 0, NULL }; + struct sync_cookie syncCookie = { NULL, -1, NULL }; + struct sync_cookie syncCookie_req = { NULL, -1, NULL }; + struct berval cookie = { 0, NULL }; + + int rc, err, i; + ber_len_t len; + + slap_callback cb; + + int rc_efree; + + struct berval *psub; + Modifications *modlist = NULL; + + const char *text; + int match; + + struct timeval *tout_p = NULL; + struct timeval tout = { 0, 0 }; + + int refreshDeletes = 0; + int refreshDone = 1; + BerVarray syncUUIDs = NULL; + ber_tag_t si_tag; + + if ( slapd_abrupt_shutdown ) { + rc = -2; + goto done; + } + + ber_init2( ber, NULL, LBER_USE_DER ); + ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx ); - if ( n != 0 ) { - /* Delete Attributes */ - descs = sync_descs; - for ( i = 0; descs[i] != NULL; i++ ) { - for ( j = 0; si->attrs[j] != NULL; j++ ) { - if ( !strcmp( si->attrs[j], descs[i]->ad_cname.bv_val )) { - ch_free( si->attrs[j] ); - for ( k = j; si->attrs[k] != NULL; k++ ) { - si->attrs[k] = si->attrs[k+1]; - } - } - } - } - for ( n = 0; si->attrs[ n ] != NULL; n++ ); - tmp = ( char ** ) ch_realloc( si->attrs, ( n + 4 ) * sizeof( char * )); - if ( tmp == NULL ) { -#ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, "out of memory\n", 0,0,0 ); -#else - Debug( LDAP_DEBUG_ANY, "out of memory\n", 0,0,0 ); -#endif - } - } else { - tmp = ( char ** ) ch_realloc( si->attrs, 5 * sizeof( char * )); - if ( tmp == NULL ) { #ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, "out of memory\n", 0,0,0 ); + LDAP_LOG ( OPERATION, DETAIL1, "do_syncrep2\n", 0, 0, 0 ); #else - Debug( LDAP_DEBUG_ANY, "out of memory\n", 0,0,0 ); + Debug( LDAP_DEBUG_TRACE, "=>do_syncrep2\n", 0, 0, 0 ); #endif - } - tmp[ n++ ] = ch_strdup( "*" ); - } - - descs = sync_descs; - si->attrs = tmp; - /* Add Attributes */ + op->o_callback = &cb; - for ( i = 0; descs[ i ] != NULL; i++ ) { - si->attrs[ n++ ] = ch_strdup ( descs[i]->ad_cname.bv_val ); - si->attrs[ n ] = NULL; - } + psub = &si->si_be->be_nsuffix[0]; - rc = ldap_sync_search( si, ld, NULL, NULL, &msgid ); - if( rc != LDAP_SUCCESS ) { - fprintf( stderr, "syncrepl: ldap_search_ext: %s (%d)\n", - ldap_err2string( rc ), rc ); - return NULL; - } + slap_dup_sync_cookie( &syncCookie_req, &si->si_syncCookie ); - if ( abs(si->type) == LDAP_SYNC_REFRESH_AND_PERSIST ){ + if ( abs(si->si_type) == LDAP_SYNC_REFRESH_AND_PERSIST ){ tout_p = &tout; } else { tout_p = NULL; } - while (( rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ONE, tout_p, &res )) >= 0 ) { - - if ( rc == 0 ) { - if ( slapd_abrupt_shutdown ) { - break; - } else { - continue; - } + while (( rc = ldap_result( si->si_ld, LDAP_RES_ANY, LDAP_MSG_ONE, tout_p, &res )) + > 0 ) + { + if ( slapd_abrupt_shutdown ) { + rc = -2; + goto done; } - - for ( msg = ldap_first_message( ld, res ); - msg != NULL; - msg = ldap_next_message( ld, msg ) ) + for( msg = ldap_first_message( si->si_ld, res ); + msg != NULL; + msg = ldap_next_message( si->si_ld, msg ) ) { - syncCookie.bv_len = 0; syncCookie.bv_val = NULL; switch( ldap_msgtype( msg ) ) { case LDAP_RES_SEARCH_ENTRY: - entry = syncrepl_message_to_entry( si, ld, &op, msg, - &modlist, &syncstate, &syncUUID, &syncCookie ); - rc_efree = syncrepl_entry( si, ld, &op, entry, modlist, - syncstate, &syncUUID, &syncCookie, !syncinfo_arrived ); - if ( syncCookie.bv_len ) { - syncrepl_updateCookie( si, ld, &op, &psub, &syncCookie ); + ldap_get_entry_controls( si->si_ld, msg, &rctrls ); + /* we can't work without the control */ + if ( !rctrls ) { + rc = -1; + goto done; + } + rctrlp = *rctrls; + ber_init2( ber, &rctrlp->ldctl_value, LBER_USE_DER ); + ber_scanf( ber, "{em", &syncstate, &syncUUID ); + if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SYNC_COOKIE ) { + ber_scanf( ber, "m}", &cookie ); + if ( cookie.bv_val ) { + struct berval tmp_bv; + ber_dupbv( &tmp_bv, &cookie ); + ber_bvarray_add( &syncCookie.octet_str, &tmp_bv ); + } + if ( syncCookie.octet_str && + syncCookie.octet_str[0].bv_val ) + slap_parse_sync_cookie( &syncCookie ); } + entry = syncrepl_message_to_entry( si, op, msg, + &modlist, syncstate ); + rc_efree = syncrepl_entry( si, op, entry, modlist, syncstate, + &syncUUID, &syncCookie_req ); + if ( syncCookie.octet_str && syncCookie.octet_str[0].bv_val ) { + syncrepl_updateCookie( si, op, psub, &syncCookie ); + } + ldap_controls_free( rctrls ); if ( modlist ) { slap_mods_free( modlist ); } - if ( rc_efree ) { + if ( rc_efree && entry ) { entry_free( entry ); } break; @@ -507,123 +523,188 @@ do_syncrepl( case LDAP_RES_SEARCH_REFERENCE: #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ERR, - "do_syncrepl : reference received\n", 0, 0, 0 ); + "do_syncrep2 : reference received\n", 0, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, - "do_syncrepl : reference received\n", 0, 0, 0 ); + "do_syncrep2 : reference received\n", 0, 0, 0 ); #endif break; case LDAP_RES_SEARCH_RESULT: - ldap_parse_result( ld, msg, &err, NULL, NULL, NULL, &rctrls, 0 ); + ldap_parse_result( si->si_ld, msg, &err, NULL, NULL, NULL, + &rctrls, 0 ); if ( rctrls ) { rctrlp = *rctrls; - ctrl_ber = ber_alloc_t( LBER_USE_DER ); - ber_set_option( ctrl_ber, LBER_OPT_BER_MEMCTX, &op.o_tmpmemctx ); - ber_write( ctrl_ber, rctrlp->ldctl_value.bv_val, rctrlp->ldctl_value.bv_len, 0 ); - ber_reset( ctrl_ber, 1 ); - - ber_scanf( ctrl_ber, "{" /*"}"*/); - if ( ber_peek_tag( ctrl_ber, &len ) - == LDAP_SYNC_TAG_COOKIE ) { - ber_scanf( ctrl_ber, "o", &syncCookie ); + ber_init2( ber, &rctrlp->ldctl_value, LBER_USE_DER ); + + ber_scanf( ber, "{" /*"}"*/); + if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SYNC_COOKIE ) + { + ber_scanf( ber, "m", &cookie ); + if ( cookie.bv_val ) { + struct berval tmp_bv; + ber_dupbv( &tmp_bv, &cookie ); + ber_bvarray_add( &syncCookie.octet_str, &tmp_bv); + } + if ( syncCookie.octet_str && + syncCookie.octet_str[0].bv_val ) + slap_parse_sync_cookie( &syncCookie ); } - } - value_match( &match, slap_schema.si_ad_entryCSN, - slap_schema.si_ad_entryCSN->ad_type->sat_ordering, - SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, - &syncCookie_req, &syncCookie, &text ); - if (si->type == LDAP_SYNC_REFRESH_AND_PERSIST) { - /* FIXME : different error behaviors according to - 1) err code : LDAP_BUSY ... - 2) on err policy : stop service, stop sync, retry - */ - if ( syncCookie.bv_len && match < 0) { - syncrepl_updateCookie( si, ld, &op, &psub, &syncCookie ); + if ( ber_peek_tag( ber, &len ) == LDAP_TAG_REFRESHDELETES ) + { + ber_scanf( ber, "b", &refreshDeletes ); } - if ( ctrl_ber ) - ber_free( ctrl_ber, 1 ); - goto done; + ber_scanf( ber, "}" ); + } + if ( syncCookie_req.ctxcsn == NULL ) { + match = -1; + } else if ( syncCookie.ctxcsn == NULL ) { + match = 1; } else { + value_match( &match, slap_schema.si_ad_entryCSN, + slap_schema.si_ad_entryCSN->ad_type->sat_ordering, + SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, + &syncCookie_req.ctxcsn[0], &syncCookie.ctxcsn[0], &text ); + } + if ( syncCookie.octet_str && syncCookie.octet_str->bv_val + && match < 0 ) { + syncrepl_updateCookie( si, op, psub, &syncCookie ); + } + if ( rctrls ) { + ldap_controls_free( rctrls ); + } + if (si->si_type != LDAP_SYNC_REFRESH_AND_PERSIST) { /* FIXME : different error behaviors according to - 1) err code : LDAP_BUSY ... - 2) on err policy : stop service, stop sync, retry - */ - if ( syncCookie.bv_len && match < 0 ) { - syncrepl_updateCookie( si, ld, &op, &psub, &syncCookie); - } - if ( si->sync_mode == LDAP_SYNC_STATE_MODE && match < 0 ) { - syncrepl_del_nonpresent( ld, &op ); + * 1) err code : LDAP_BUSY ... + * 2) on err policy : stop service, stop sync, retry + */ + if ( refreshDeletes == 0 && match < 0 ) { + syncrepl_del_nonpresent( op, si ); + } else { + avl_free( si->si_presentlist, avl_ber_bvfree ); + si->si_presentlist = NULL; } - if ( ctrl_ber ) - ber_free( ctrl_ber, 1 ); - goto done; } + rc = -2; + goto done; break; case LDAP_RES_INTERMEDIATE: - rc = ldap_parse_intermediate( ld, msg, + rc = ldap_parse_intermediate( si->si_ld, msg, &retoid, &retdata, NULL, 0 ); if ( !rc && !strcmp( retoid, LDAP_SYNC_INFO ) ) { - sync_info_arrived = 1; - res_ber = ber_init( retdata ); - ber_scanf( res_ber, "{e" /*"}"*/, &syncstate ); - - if ( ber_peek_tag( res_ber, &len ) - == LDAP_SYNC_TAG_COOKIE ) { - ber_scanf( res_ber, /*"{"*/ "o}", &syncCookie ); - } else { - if ( syncstate == LDAP_SYNC_NEW_COOKIE ) { + int si_refreshDelete = 0; + int si_refreshPresent = 0; + ber_init2( ber, retdata, LBER_USE_DER ); + + switch ( si_tag = ber_peek_tag( ber, &len )) { + ber_tag_t tag; + case LDAP_TAG_SYNC_NEW_COOKIE: + ber_scanf( ber, "tm", &tag, &cookie ); + break; + case LDAP_TAG_SYNC_REFRESH_DELETE: + si_refreshDelete = 1; + case LDAP_TAG_SYNC_REFRESH_PRESENT: + si_refreshPresent = 1; + ber_scanf( ber, "t{", &tag ); + if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SYNC_COOKIE ) + { + ber_scanf( ber, "m", &cookie ); + if ( cookie.bv_val ) { + struct berval tmp_bv; + ber_dupbv( &tmp_bv, &cookie ); + ber_bvarray_add( &syncCookie.octet_str, &tmp_bv); + } + if ( syncCookie.octet_str && + syncCookie.octet_str[0].bv_val ) + slap_parse_sync_cookie( &syncCookie ); + } + if ( ber_peek_tag( ber, &len ) == + LDAP_TAG_REFRESHDONE ) + { + ber_scanf( ber, "b", &refreshDone ); + } + ber_scanf( ber, "}" ); + break; + case LDAP_TAG_SYNC_ID_SET: + ber_scanf( ber, "t{", &tag ); + if ( ber_peek_tag( ber, &len ) == + LDAP_TAG_SYNC_COOKIE ) { + ber_scanf( ber, "m", &cookie ); + if ( cookie.bv_val ) { + struct berval tmp_bv; + ber_dupbv( &tmp_bv, &cookie ); + ber_bvarray_add( &syncCookie.octet_str, + &tmp_bv ); + } + if ( syncCookie.octet_str && + syncCookie.octet_str[0].bv_val ) + slap_parse_sync_cookie( &syncCookie ); + } + if ( ber_peek_tag( ber, &len ) == + LDAP_TAG_REFRESHDELETES ) + { + ber_scanf( ber, "b", &refreshDeletes ); + } + ber_scanf( ber, "[W]", &syncUUIDs ); + ber_scanf( ber, "}" ); + for ( i = 0; syncUUIDs[i].bv_val; i++ ) { + struct berval *syncuuid_bv; + syncuuid_bv = ber_dupbv( NULL, &syncUUIDs[i] ); + avl_insert( &si->si_presentlist, + (caddr_t) syncuuid_bv, + syncuuid_cmp, avl_dup_error ); + } + ber_memfree_x( syncUUIDs, op->o_tmpmemctx ); + break; + default: #ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, - "do_syncrepl : cookie required\n", 0, 0, 0 ); + LDAP_LOG( OPERATION, ERR, + "do_syncrep2 : unknown syncinfo tag (%d)\n", + si_tag, 0, 0 ); #else - Debug( LDAP_DEBUG_ANY, - "do_syncrepl : cookie required\n", 0, 0, 0 ); + Debug( LDAP_DEBUG_ANY, + "do_syncrep2 : unknown syncinfo tag (%d)\n", + si_tag, 0, 0 ); #endif - } + ldap_memfree( retoid ); + ber_bvfree( retdata ); + continue; } - value_match( &match, slap_schema.si_ad_entryCSN, - slap_schema.si_ad_entryCSN->ad_type->sat_ordering, - SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, - &syncCookie_req, &syncCookie, &text ); + if ( syncCookie_req.ctxcsn == NULL ) { + match = -1; + } else if ( syncCookie.ctxcsn == NULL ) { + match = 1; + } else { + value_match( &match, slap_schema.si_ad_entryCSN, + slap_schema.si_ad_entryCSN->ad_type->sat_ordering, + SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, + &syncCookie_req.ctxcsn[0], + &syncCookie.ctxcsn[0], &text ); + } - if ( syncCookie.bv_len && match < 0 ) { - syncrepl_updateCookie( si, ld, &op, &psub, &syncCookie); + if ( syncCookie.ctxcsn && syncCookie.ctxcsn[0].bv_val + && match < 0 ) { + syncrepl_updateCookie( si, op, psub, &syncCookie); } - if ( syncstate == LDAP_SYNC_STATE_MODE_DONE ) { + if ( si_refreshPresent == 1 ) { if ( match < 0 ) { - syncrepl_del_nonpresent( ld, &op ); + syncrepl_del_nonpresent( op, si ); } - si->sync_mode = LDAP_SYNC_LOG_MODE; - } else if ( syncstate == LDAP_SYNC_LOG_MODE_DONE ) { - si->sync_mode = LDAP_SYNC_PERSIST_MODE; - } else if ( syncstate == LDAP_SYNC_REFRESH_DONE ) { - si->sync_mode = LDAP_SYNC_PERSIST_MODE; - } else if ( syncstate != LDAP_SYNC_NEW_COOKIE || - syncstate != LDAP_SYNC_LOG_MODE_DONE ) { -#ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, - "do_syncrepl : unknown sync info\n", 0, 0, 0 ); -#else - Debug( LDAP_DEBUG_ANY, - "do_syncrepl : unknown sync info\n", 0, 0, 0 ); -#endif - } + } ldap_memfree( retoid ); ber_bvfree( retdata ); - ber_free( res_ber, 1 ); break; } else { #ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR,"do_syncrepl :" + LDAP_LOG( OPERATION, ERR,"do_syncrep2 :" " unknown intermediate " "response\n", 0, 0, 0 ); #else - Debug( LDAP_DEBUG_ANY, "do_syncrepl : " + Debug( LDAP_DEBUG_ANY, "do_syncrep2 : " "unknown intermediate response (%d)\n", rc, 0, 0 ); #endif @@ -634,58 +715,177 @@ do_syncrepl( break; default: #ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, "do_syncrepl : " + LDAP_LOG( OPERATION, ERR, "do_syncrep2 : " "unknown message\n", 0, 0, 0 ); #else - Debug( LDAP_DEBUG_ANY, "do_syncrepl : " + Debug( LDAP_DEBUG_ANY, "do_syncrep2 : " "unknown message\n", 0, 0, 0 ); #endif break; } - if ( syncCookie.bv_val ) - ch_free( syncCookie.bv_val ); - if ( syncUUID.bv_val ) - ch_free( syncUUID.bv_val ); + if ( syncCookie.octet_str ) { + slap_sync_cookie_free( &syncCookie_req, 0 ); + slap_dup_sync_cookie( &syncCookie_req, &syncCookie ); + slap_sync_cookie_free( &syncCookie, 0 ); + } } ldap_msgfree( res ); + res = NULL; } if ( rc == -1 ) { - int errno; const char *errstr; - ldap_get_option( ld, LDAP_OPT_ERROR_NUMBER, &errno ); - errstr = ldap_err2string( errno ); + ldap_get_option( si->si_ld, LDAP_OPT_ERROR_NUMBER, &rc ); + errstr = ldap_err2string( rc ); #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ERR, - "do_syncrepl : %s\n", errstr, 0, 0 ); + "do_syncrep2 : %s\n", errstr, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, - "do_syncrepl : %s\n", errstr, 0, 0 ); + "do_syncrep2 : %s\n", errstr, 0, 0 ); +#endif + } + +done: + slap_sync_cookie_free( &syncCookie, 0 ); + slap_sync_cookie_free( &syncCookie_req, 0 ); + + if ( res ) ldap_msgfree( res ); + + if ( rc && si->si_ld ) { + ldap_unbind( si->si_ld ); + si->si_ld = NULL; + } + + return rc; +} + +void * +do_syncrepl( + void *ctx, + void *arg ) +{ + struct re_s* rtask = arg; + syncinfo_t *si = ( syncinfo_t * ) rtask->arg; + Connection conn = {0}; + Operation op = {0}; + int rc = LDAP_SUCCESS; + int first = 0; + int dostop = 0; + ber_socket_t s; + +#ifdef NEW_LOGGING + LDAP_LOG ( OPERATION, DETAIL1, "do_syncrepl\n", 0, 0, 0 ); +#else + Debug( LDAP_DEBUG_TRACE, "=>do_syncrepl\n", 0, 0, 0 ); #endif + + if ( si == NULL ) + return NULL; + + switch( abs( si->si_type )) { + case LDAP_SYNC_REFRESH_ONLY: + case LDAP_SYNC_REFRESH_AND_PERSIST: + break; + default: + return NULL; + } + + if ( slapd_abrupt_shutdown && si->si_ld ) { + ldap_get_option( si->si_ld, LDAP_OPT_DESC, &s ); + connection_client_stop( s ); + ldap_unbind( si->si_ld ); + si->si_ld = NULL; + return NULL; + } + + conn.c_connid = -1; + conn.c_send_ldap_result = slap_send_ldap_result; + conn.c_send_search_entry = slap_send_search_entry; + conn.c_send_search_reference = slap_send_search_reference; + conn.c_listener = (Listener *)&dummy_list; + conn.c_peer_name = slap_empty_bv; + + /* set memory context */ +#define SLAB_SIZE 1048576 + op.o_tmpmemctx = sl_mem_create( SLAB_SIZE, ctx ); + op.o_tmpmfuncs = &sl_mfuncs; + + op.o_dn = si->si_updatedn; + op.o_ndn = si->si_updatedn; + op.o_time = slap_get_time(); + op.o_threadctx = ctx; + op.o_managedsait = 1; + op.o_bd = si->si_be; + op.o_conn = &conn; + op.o_connid = op.o_conn->c_connid; + + op.o_sync_state.ctxcsn = NULL; + op.o_sync_state.sid = -1; + op.o_sync_state.octet_str = NULL; + op.o_sync_slog_size = -1; + LDAP_STAILQ_FIRST( &op.o_sync_slog_list ) = NULL; + op.o_sync_slog_list.stqh_last = &LDAP_STAILQ_FIRST(&op.o_sync_slog_list); + + /* Establish session, do search */ + if ( !si->si_ld ) { + first = 1; + rc = do_syncrep1( &op, si ); + } + + /* Process results */ + if ( rc == LDAP_SUCCESS ) { + ldap_get_option( si->si_ld, LDAP_OPT_DESC, &s ); + + rc = do_syncrep2( &op, si ); + + if ( abs(si->si_type) == LDAP_SYNC_REFRESH_AND_PERSIST ) { + /* If we succeeded, enable the connection for further listening. + * If we failed, tear down the connection and reschedule. + */ + if ( rc == LDAP_SUCCESS ) { + if ( first ) { + rc = connection_client_setup( s, (Listener *)&dummy_list, do_syncrepl, + arg ); + } else { + connection_client_enable( s ); + } + } else if ( !first ) { + dostop = 1; + } + } else { + if ( rc == -2 ) rc = 0; + } } -done: - if ( syncCookie.bv_val ) - ch_free( syncCookie.bv_val ); - if ( syncCookie_req.bv_val ) - ch_free( syncCookie_req.bv_val ); - if ( syncUUID.bv_val ) - ch_free( syncUUID.bv_val ); - - if ( res ) - ldap_msgfree( res ); + /* At this point, we have 4 cases: + * 1) for any hard failure, give up and remove this task + * 2) for ServerDown, reschedule this task to run + * 3) for Refresh and Success, reschedule to run + * 4) for Persist and Success, reschedule to defer + */ + ldap_pvt_thread_mutex_lock( &syncrepl_rq.rq_mutex ); + if ( ldap_pvt_runqueue_isrunning( &syncrepl_rq, rtask )) { + ldap_pvt_runqueue_stoptask( &syncrepl_rq, rtask ); + } - ldap_unbind( ld ); + if ( dostop ) { + connection_client_stop( s ); + } - ldap_pvt_thread_mutex_lock( &syncrepl_rq.rq_mutex ); - ldap_pvt_runqueue_stoptask( &syncrepl_rq, rtask ); - if ( si->type == LDAP_SYNC_REFRESH_ONLY ) { - ldap_pvt_runqueue_resched( &syncrepl_rq, rtask ); - } else { + if ( rc && rc != LDAP_SERVER_DOWN ) { ldap_pvt_runqueue_remove( &syncrepl_rq, rtask ); + } else { + if ( rc == LDAP_SERVER_DOWN || + si->si_type == LDAP_SYNC_REFRESH_ONLY ) { + rc = 0; + } else { + rc = 1; + } + ldap_pvt_runqueue_resched( &syncrepl_rq, rtask, rc ); } ldap_pvt_thread_mutex_unlock( &syncrepl_rq.rq_mutex ); @@ -695,46 +895,24 @@ done: Entry* syncrepl_message_to_entry( syncinfo_t *si, - LDAP *ld, Operation *op, LDAPMessage *msg, Modifications **modlist, - int *syncstate, - struct berval *syncUUID, - struct berval *syncCookie + int syncstate ) { - Entry *e; + Entry *e = NULL; BerElement *ber = NULL; - BerElement *tmpber; - struct berval bv = {0, NULL}; Modifications tmp; Modifications *mod; Modifications **modtail = modlist; - Backend *be = op->o_bd; const char *text; char txtbuf[SLAP_TEXT_BUFLEN]; size_t textlen = sizeof txtbuf; - struct berval **bvals = NULL; - char *dn; - struct berval bdn = {0, NULL}; - Attribute *attr; - struct berval empty_bv = { 0, NULL }; + struct berval bdn = {0, NULL}, dn, ndn; int rc; - char *a; - - ber_len_t len; - LDAPControl* rctrlp; - LDAPControl** rctrls = NULL; - BerElement* ctrl_ber; - - ber_tag_t tag; - - Modifications *ml = NULL; - AttributeDescription** descs; - int i; *modlist = NULL; @@ -751,7 +929,7 @@ syncrepl_message_to_entry( op->o_tag = LDAP_REQ_ADD; - rc = ldap_get_dn_ber( ld, msg, &ber, &bdn ); + rc = ldap_get_dn_ber( si->si_ld, msg, &ber, &bdn ); if ( rc != LDAP_SUCCESS ) { #ifdef NEW_LOGGING @@ -764,16 +942,27 @@ syncrepl_message_to_entry( return NULL; } - e = ( Entry * ) ch_calloc( 1, sizeof( Entry )); - dnPrettyNormal( NULL, &bdn, &e->e_name, &e->e_nname, NULL ); + dnPrettyNormal( NULL, &bdn, &dn, &ndn, op->o_tmpmemctx ); + ber_dupbv( &op->o_req_dn, &dn ); + ber_dupbv( &op->o_req_ndn, &ndn ); + sl_free( ndn.bv_val, op->o_tmpmemctx ); + sl_free( dn.bv_val, op->o_tmpmemctx ); - e->e_attrs = NULL; + if ( syncstate == LDAP_SYNC_PRESENT || syncstate == LDAP_SYNC_DELETE ) + { + return NULL; + } - while ( ber_remaining( ber ) ) { - tag = ber_scanf( ber, "{mW}", &tmp.sml_type, &tmp.sml_values ); + e = ( Entry * ) ch_calloc( 1, sizeof( Entry ) ); + e->e_name = op->o_req_dn; + e->e_nname = op->o_req_ndn; - if ( tag == LBER_ERROR ) break; - if ( tmp.sml_type.bv_val == NULL ) break; + while ( ber_remaining( ber ) ) { + if ( (ber_scanf( ber, "{mW}", &tmp.sml_type, &tmp.sml_values ) == + LBER_ERROR ) || ( tmp.sml_type.bv_val == NULL )) + { + break; + } mod = (Modifications *) ch_malloc( sizeof( Modifications )); @@ -788,61 +977,6 @@ syncrepl_message_to_entry( modtail = &mod->sml_next; } - if ( ber_scanf( ber, "}") == LBER_ERROR ) { -#ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, - "syncrepl_message_to_entry: ber_scanf failed\n", 0, 0, 0 ); -#else - Debug( LDAP_DEBUG_ANY, "syncrepl_message_to_entry: ber_scanf failed\n", - 0, 0, 0 ); -#endif - return NULL; - } - - ber_free( ber, 0 ); - tmpber = ldap_get_message_ber( msg ); - ber = ber_dup( tmpber ); - - ber_scanf( ber, "{xx" ); - - rc = ldap_pvt_get_controls( ber, &rctrls ); - if ( rc != LDAP_SUCCESS ) { -#ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, - "syncrepl_message_to_entry : control get failed (%d)", rc, 0, 0 ); -#else - Debug( LDAP_DEBUG_ANY, - "syncrepl_message_to_entry : control get failed (%d)", rc, 0, 0 ); -#endif - return NULL; - } - - if ( rctrls ) { - rctrlp = *rctrls; - ctrl_ber = ber_alloc_t( LBER_USE_DER ); - ber_set_option( ctrl_ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx ); - ber_write( ctrl_ber, rctrlp->ldctl_value.bv_val, rctrlp->ldctl_value.bv_len, 0 ); - ber_reset( ctrl_ber, 1 ); - ber_scanf( ctrl_ber, "{eo", syncstate, syncUUID ); - if ( ber_peek_tag( ctrl_ber, &len ) == LDAP_SYNC_TAG_COOKIE ) { - ber_scanf( ctrl_ber, "o}", syncCookie ); - } - ber_free( ctrl_ber, 1 ); - ldap_controls_free( rctrls ); - } else { -#ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR,"syncrepl_message_to_entry : " - " rctrls absent\n", 0, 0, 0 ); -#else - Debug( LDAP_DEBUG_ANY, "syncrepl_message_to_entry :" - " rctrls absent\n", 0, 0, 0 ); -#endif - } - - if ( *syncstate == LDAP_SYNC_PRESENT || *syncstate == LDAP_SYNC_DELETE ) { - goto done; - } - if ( *modlist == NULL ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ERR, @@ -853,21 +987,6 @@ syncrepl_message_to_entry( #endif } - ml = *modlist; - while ( ml != NULL ) { - AttributeDescription *ad = NULL; - rc = slap_bv2ad( &ml->sml_type, &ml->sml_desc, &text ); - - if( rc != LDAP_SUCCESS ) { - e = NULL; - goto done; - } - - ad = ml->sml_desc; - ml->sml_desc = NULL; - ml = ml->sml_next; - } - rc = slap_mods_check( *modlist, 1, &text, txtbuf, textlen, NULL ); if ( rc != LDAP_SUCCESS ) { @@ -878,7 +997,7 @@ syncrepl_message_to_entry( Debug( LDAP_DEBUG_ANY, "syncrepl_message_to_entry: mods check (%s)\n", text, 0, 0 ); #endif - return NULL; + goto done; } rc = slap_mods2entry( *modlist, &e, 1, 1, &text, txtbuf, textlen); @@ -893,127 +1012,118 @@ syncrepl_message_to_entry( } done: - ber_free ( ber, 0 ); + if ( rc != LDAP_SUCCESS ) { + entry_free( e ); + e = NULL; + } return e; } -int -syncuuid_cmp( const void* v_uuid1, const void* v_uuid2 ) -{ - const struct berval *uuid1 = v_uuid1; - const struct berval *uuid2 = v_uuid2; - int rc = uuid1->bv_len - uuid2->bv_len; - if ( rc ) return rc; - return ( strcmp( uuid1->bv_val, uuid2->bv_val ) ); -} - int syncrepl_entry( syncinfo_t* si, - LDAP *ld, Operation *op, Entry* e, Modifications* modlist, int syncstate, struct berval* syncUUID, - struct berval* syncCookie, - int refresh + struct sync_cookie* syncCookie_req ) { Backend *be = op->o_bd; slap_callback cb; - struct berval csn_bv = {0, NULL}; struct berval *syncuuid_bv = NULL; - char csnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE ]; + struct berval syncUUID_strrep = { 0, NULL }; SlapReply rs = {REP_RESULT}; + Filter f = {0}; + AttributeAssertion ava = {0}; int rc = LDAP_SUCCESS; + int ret = LDAP_SUCCESS; + const char *text; - struct berval base_bv = {0, NULL}; - - char *filterstr; - Filter *filter; - - Attribute *a; - - if ( refresh && - ( syncstate == LDAP_SYNC_PRESENT || syncstate == LDAP_SYNC_ADD )) { + if (( syncstate == LDAP_SYNC_PRESENT || syncstate == LDAP_SYNC_ADD )) + { syncuuid_bv = ber_dupbv( NULL, syncUUID ); - avl_insert( &si->presentlist, (caddr_t) syncuuid_bv, - syncuuid_cmp, avl_dup_error ); + avl_insert( &si->si_presentlist, (caddr_t) syncuuid_bv, + syncuuid_cmp, avl_dup_error ); } if ( syncstate == LDAP_SYNC_PRESENT ) { - if ( e ) { - return 1; - } else { - return 0; - } + return e ? 1 : 0; } - filterstr = (char *) sl_malloc( strlen("entryUUID=") + syncUUID->bv_len + 1, - op->o_tmpmemctx ); - strcpy( filterstr, "entryUUID=" ); - strcat( filterstr, syncUUID->bv_val ); + f.f_choice = LDAP_FILTER_EQUALITY; + f.f_ava = &ava; + ava.aa_desc = slap_schema.si_ad_entryUUID; + slap_uuidstr_from_normalized( &syncUUID_strrep, syncUUID, op->o_tmpmemctx ); + ava.aa_value = *syncUUID; + op->ors_filter = &f; + + op->ors_filterstr.bv_len = (sizeof("entryUUID=")-1) + syncUUID->bv_len; + op->ors_filterstr.bv_val = (char *) sl_malloc( + op->ors_filterstr.bv_len + 1, op->o_tmpmemctx ); + AC_MEMCPY( op->ors_filterstr.bv_val, "entryUUID=", sizeof("entryUUID=")-1 ); + AC_MEMCPY( &op->ors_filterstr.bv_val[sizeof("entryUUID=")-1], + syncUUID->bv_val, syncUUID->bv_len ); + op->ors_filterstr.bv_val[op->ors_filterstr.bv_len] = '\0'; - si->e = e; - si->syncUUID_ndn = NULL; - - filter = str2filter( filterstr ); - ber_str2bv( filterstr, strlen(filterstr), 1, &op->ors_filterstr ); - ch_free( filterstr ); - op->ors_filter = filter; op->ors_scope = LDAP_SCOPE_SUBTREE; /* get syncrepl cookie of shadow replica from subentry */ - ber_str2bv( si->base, strlen(si->base), 1, &base_bv ); - dnPrettyNormal( 0, &base_bv, &op->o_req_dn, &op->o_req_ndn, op->o_tmpmemctx ); - ch_free( base_bv.bv_val ); + op->o_req_dn = si->si_base; + op->o_req_ndn = si->si_base; /* set callback function */ op->o_callback = &cb; cb.sc_response = dn_callback; cb.sc_private = si; - si->syncUUID_ndn = NULL; + si->si_syncUUID_ndn.bv_val = NULL; rc = be->be_search( op, &rs ); - if ( op->o_req_dn.bv_val ) - ch_free( op->o_req_dn.bv_val ); - if ( op->o_req_ndn.bv_val ) - ch_free( op->o_req_ndn.bv_val ); - if ( op->ors_filter ) - filter_free( op->ors_filter ); - if ( op->ors_filterstr.bv_val ) - ch_free( op->ors_filterstr.bv_val ); + if ( op->ors_filterstr.bv_val ) { + sl_free( op->ors_filterstr.bv_val, op->o_tmpmemctx ); + } cb.sc_response = null_callback; cb.sc_private = si; - if ( rc == LDAP_SUCCESS && si->syncUUID_ndn && si->sync_mode != LDAP_SYNC_LOG_MODE ) { - op->o_req_dn = *si->syncUUID_ndn; - op->o_req_ndn = *si->syncUUID_ndn; + if ( rc == LDAP_SUCCESS && si->si_syncUUID_ndn.bv_val ) + { + char *subseq_ptr; + + if ( syncstate != LDAP_SYNC_DELETE ) { + op->o_no_psearch = 1; + } + + ber_dupbv( &op->o_sync_csn, syncCookie_req->ctxcsn ); + if ( op->o_sync_csn.bv_val ) { + subseq_ptr = strstr( op->o_sync_csn.bv_val, "#0000" ); + subseq_ptr += 4; + *subseq_ptr = '1'; + } + + op->o_req_dn = si->si_syncUUID_ndn; + op->o_req_ndn = si->si_syncUUID_ndn; op->o_tag = LDAP_REQ_DELETE; rc = be->be_delete( op, &rs ); - } - - if ( si->syncUUID_ndn ) { - ber_bvfree( si->syncUUID_ndn ); + op->o_no_psearch = 0; } switch ( syncstate ) { - case LDAP_SYNC_ADD : - case LDAP_SYNC_MODIFY : - + case LDAP_SYNC_ADD: + case LDAP_SYNC_MODIFY: if ( rc == LDAP_SUCCESS || rc == LDAP_REFERRAL || - rc == LDAP_NO_SUCH_OBJECT ) { - + rc == LDAP_NO_SUCH_OBJECT ) + { attr_delete( &e->e_attrs, slap_schema.si_ad_entryUUID ); - attr_merge_normalize_one( e, slap_schema.si_ad_entryUUID, syncUUID, op->o_tmpmemctx ); + attr_merge_one( e, slap_schema.si_ad_entryUUID, + syncUUID, &ava.aa_value ); op->o_tag = LDAP_REQ_ADD; op->ora_e = e; @@ -1028,7 +1138,6 @@ syncrepl_entry( op->o_req_dn = e->e_name; op->o_req_ndn = e->e_nname; rc = be->be_modify( op, &rs ); - si->e = NULL; if ( rc != LDAP_SUCCESS ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ERR, @@ -1040,14 +1149,12 @@ syncrepl_entry( rc, 0, 0 ); #endif } - return 1; - } else if ( rc == LDAP_REFERRAL || - rc == LDAP_NO_SUCH_OBJECT ) { - syncrepl_add_glue( si, ld, op, e, - modlist, syncstate, - syncUUID, syncCookie); - si->e = NULL; - return 0; + ret = 1; + goto done; + } else if ( rc == LDAP_REFERRAL || rc == LDAP_NO_SUCH_OBJECT ) { + syncrepl_add_glue( op, e ); + ret = 0; + goto done; } else { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ERR, @@ -1058,13 +1165,13 @@ syncrepl_entry( "syncrepl_entry : be_add failed (%d)\n", rc, 0, 0 ); #endif - si->e = NULL; - return 1; + ret = 1; + goto done; } } else { - si->e = NULL; be_entry_release_w( op, e ); - return 0; + ret = 0; + goto done; } } else { #ifdef NEW_LOGGING @@ -1074,19 +1181,14 @@ syncrepl_entry( Debug( LDAP_DEBUG_ANY, "syncrepl_entry : be_search failed (%d)\n", rc, 0, 0 ); #endif - si->e = NULL; - return 1; + ret = 1; + goto done; } case LDAP_SYNC_DELETE : - if ( si->sync_mode == LDAP_SYNC_LOG_MODE ) { - op->o_req_dn = *si->syncUUID_ndn; - op->o_req_ndn = *si->syncUUID_ndn; - op->o_tag = LDAP_REQ_DELETE; - rc = be->be_delete( op, &rs ); - } - /* Already deleted otherwise */ - return 1; + /* Already deleted */ + ret = 1; + goto done; default : #ifdef NEW_LOGGING @@ -1096,73 +1198,70 @@ syncrepl_entry( Debug( LDAP_DEBUG_ANY, "syncrepl_entry : unknown syncstate\n", 0, 0, 0 ); #endif - return 1; + ret = 1; + goto done; + } + +done : + + if ( syncUUID_strrep.bv_val ) { + ber_memfree_x( syncUUID_strrep.bv_val, op->o_tmpmemctx ); } + if ( si->si_syncUUID_ndn.bv_val ) { + ber_memfree_x( si->si_syncUUID_ndn.bv_val, op->o_tmpmemctx ); + } + return ret; } static void syncrepl_del_nonpresent( - LDAP *ld, - Operation *op + Operation *op, + syncinfo_t *si ) { Backend* be = op->o_bd; - syncinfo_t *si = op->o_si; slap_callback cb; - struct berval base_bv = {0, NULL}; - Filter *filter; SlapReply rs = {REP_RESULT}; - struct berval filterstr_bv = {0, NULL}; struct nonpresent_entry *np_list, *np_prev; - ber_str2bv( si->base, strlen(si->base), 1, &base_bv ); - dnPrettyNormal(0, &base_bv, &op->o_req_dn, &op->o_req_ndn, op->o_tmpmemctx ); - ch_free( base_bv.bv_val ); - - filter = str2filter( si->filterstr ); + op->o_req_dn = si->si_base; + op->o_req_ndn = si->si_base; cb.sc_response = nonpresent_callback; cb.sc_private = si; op->o_callback = &cb; op->o_tag = LDAP_REQ_SEARCH; - op->ors_scope = si->scope; + op->ors_scope = si->si_scope; op->ors_deref = LDAP_DEREF_NEVER; op->ors_slimit = 0; op->ors_tlimit = 0; op->ors_attrsonly = 0; op->ors_attrs = NULL; - op->ors_filter = filter; - ber_str2bv( si->filterstr, strlen( si->filterstr ), 1, &op->ors_filterstr ); + op->ors_filter = str2filter_x( op, si->si_filterstr.bv_val ); + op->ors_filterstr = si->si_filterstr; op->o_nocaching = 1; be->be_search( op, &rs ); op->o_nocaching = 0; - if ( op->o_req_dn.bv_val ) - ch_free( op->o_req_dn.bv_val ); - if ( op->o_req_ndn.bv_val ) - ch_free( op->o_req_ndn.bv_val ); - if ( op->ors_filter ) - filter_free( op->ors_filter ); - if ( op->ors_filterstr.bv_val ) - ch_free( op->ors_filterstr.bv_val ); - - if ( !LDAP_LIST_EMPTY( &si->nonpresentlist ) ) { - np_list = LDAP_LIST_FIRST( &si->nonpresentlist ); + if ( op->ors_filter ) filter_free_x( op, op->ors_filter ); + + if ( !LDAP_LIST_EMPTY( &si->si_nonpresentlist ) ) { + np_list = LDAP_LIST_FIRST( &si->si_nonpresentlist ); while ( np_list != NULL ) { - LDAP_LIST_REMOVE( np_list, np_link ); + LDAP_LIST_REMOVE( np_list, npe_link ); np_prev = np_list; - np_list = LDAP_LIST_NEXT( np_list, np_link ); + np_list = LDAP_LIST_NEXT( np_list, npe_link ); op->o_tag = LDAP_REQ_DELETE; op->o_callback = &cb; cb.sc_response = null_callback; cb.sc_private = si; - op->o_req_dn = *np_prev->dn; - op->o_req_ndn = *np_prev->ndn; + op->o_req_dn = *np_prev->npe_name; + op->o_req_ndn = *np_prev->npe_nname; op->o_bd->be_delete( op, &rs ); - ber_bvfree( np_prev->dn ); - ber_bvfree( np_prev->ndn ); + ber_bvfree( np_prev->npe_name ); + ber_bvfree( np_prev->npe_nname ); op->o_req_dn.bv_val = NULL; op->o_req_ndn.bv_val = NULL; ch_free( np_prev ); @@ -1173,85 +1272,84 @@ syncrepl_del_nonpresent( } +static struct berval gcbva[] = { + BER_BVC("top"), + BER_BVC("glue") +}; + void syncrepl_add_glue( - syncinfo_t *si, - LDAP *ld, Operation* op, - Entry *e, - Modifications* modlist, - int syncstate, - struct berval* syncUUID, - struct berval* syncCookie + Entry *e ) { Backend *be = op->o_bd; - struct berval uuid_bv = {0, NULL}; slap_callback cb; Attribute *a; int rc; - char uuidbuf[ LDAP_LUTIL_UUIDSTR_BUFSIZE ]; - int levels = 0; - int i, j, k; + int suffrdns; + int i; struct berval dn = {0, NULL}; - struct berval pdn = {0, NULL}; struct berval ndn = {0, NULL}; - struct berval rdn = {0, NULL}; Entry *glue; SlapReply rs = {REP_RESULT}; - Connection *conn = op->o_conn; - char* ptr; + char *ptr, *comma; op->o_tag = LDAP_REQ_ADD; op->o_callback = &cb; cb.sc_response = null_callback; - cb.sc_private = si; + cb.sc_private = NULL; - ber_dupbv( &dn, &e->e_nname ); - ber_dupbv( &pdn, &e->e_nname ); + dn = e->e_name; + ndn = e->e_nname; - ptr = dn.bv_val; - while ( !be_issuffix ( be, &pdn )) { - dnParent( &dn, &pdn ); - dn.bv_val = pdn.bv_val; - dn.bv_len = pdn.bv_len; - levels++; + /* count RDNs in suffix */ + if ( be->be_nsuffix[0].bv_len ) { + for (i=0, ptr=be->be_nsuffix[0].bv_val; ptr; ptr=strchr( ptr, ',' )) { + ptr++; + i++; + } + suffrdns = i; + } else { + /* suffix is "" */ + suffrdns = 0; } - ch_free( ptr ); - - for ( i = 0; i <= levels; i++ ) { - glue = (Entry*) ch_calloc( 1, sizeof(Entry) ); - ber_dupbv( &dn, &e->e_nname ); - j = levels - i; - ptr = dn.bv_val; - for ( k = 0; k < j; k++ ) { - dnParent( &dn, &pdn ); - dn.bv_val = pdn.bv_val; - dn.bv_len = pdn.bv_len; - } + /* Start with BE suffix */ + for ( i = 0, ptr = NULL; i < suffrdns; i++ ) { + comma = strrchr(dn.bv_val, ','); + if ( ptr ) *ptr = ','; + if ( comma ) *comma = '\0'; + ptr = comma; + } + if ( ptr ) { + *ptr++ = ','; + dn.bv_len -= ptr - dn.bv_val; + dn.bv_val = ptr; + } + /* the normalizedDNs are always the same length, no counting + * required. + */ + if ( ndn.bv_len > be->be_nsuffix[0].bv_len ) { + ndn.bv_val += ndn.bv_len - be->be_nsuffix[0].bv_len; + ndn.bv_len = be->be_nsuffix[0].bv_len; + } - dnPrettyNormal( 0, &dn, &pdn, &ndn, op->o_tmpmemctx ); - ber_dupbv( &glue->e_name, &pdn ); + while ( ndn.bv_val > e->e_nname.bv_val ) { + glue = (Entry *) ch_calloc( 1, sizeof(Entry) ); + ber_dupbv( &glue->e_name, &dn ); ber_dupbv( &glue->e_nname, &ndn ); - ch_free( ptr ); - ch_free( pdn.bv_val ); - ch_free( ndn.bv_val ); a = ch_calloc( 1, sizeof( Attribute )); a->a_desc = slap_schema.si_ad_objectClass; a->a_vals = ch_calloc( 3, sizeof( struct berval )); - ber_str2bv( "top", strlen("top"), 1, &a->a_vals[0] ); - ber_str2bv( "glue", strlen("glue"), 1, &a->a_vals[1] ); + ber_dupbv( &a->a_vals[0], &gcbva[0] ); + ber_dupbv( &a->a_vals[1], &gcbva[1] ); a->a_vals[2].bv_len = 0; a->a_vals[2].bv_val = NULL; - a->a_nvals = ch_calloc( 3, sizeof( struct berval )); - ber_str2bv( "top", strlen("top"), 1, &a->a_nvals[0] ); - ber_str2bv( "glue", strlen("glue"), 1, &a->a_nvals[1] ); - a->a_nvals[2].bv_len = 0; - a->a_nvals[2].bv_val = NULL; + a->a_nvals = a->a_vals; a->a_next = glue->e_attrs; glue->e_attrs = a; @@ -1260,40 +1358,51 @@ syncrepl_add_glue( a->a_desc = slap_schema.si_ad_structuralObjectClass; a->a_vals = ch_calloc( 2, sizeof( struct berval )); - ber_str2bv( "glue", strlen("glue"), 1, &a->a_vals[0] ); + ber_dupbv( &a->a_vals[0], &gcbva[1] ); a->a_vals[1].bv_len = 0; a->a_vals[1].bv_val = NULL; - a->a_nvals = ch_calloc( 2, sizeof( struct berval )); - ber_str2bv( "glue", strlen("glue"), 1, &a->a_nvals[0] ); - a->a_nvals[1].bv_len = 0; - a->a_nvals[1].bv_val = NULL; + a->a_nvals = a->a_vals; a->a_next = glue->e_attrs; glue->e_attrs = a; - if ( !strcmp( e->e_nname.bv_val, glue->e_nname.bv_val )) { - op->o_req_dn = e->e_name; - op->o_req_ndn = e->e_nname; - op->ora_e = e; - rc = be->be_add ( op, &rs ); - if ( rc == LDAP_SUCCESS ) - be_entry_release_w( op, e ); - else - entry_free( e ); - entry_free( glue ); + op->o_req_dn = glue->e_name; + op->o_req_ndn = glue->e_nname; + op->ora_e = glue; + rc = be->be_add ( op, &rs ); + if ( rc == LDAP_SUCCESS ) { + be_entry_release_w( op, glue ); } else { - op->o_req_dn = glue->e_name; - op->o_req_ndn = glue->e_nname; - op->ora_e = glue; - rc = be->be_add ( op, &rs ); - if ( rc == LDAP_SUCCESS ) { - be_entry_release_w( op, glue ); - } else { - /* incl. ALREADY EXIST */ - entry_free( glue ); - } + /* incl. ALREADY EXIST */ + entry_free( glue ); + } + + /* Move to next child */ + for (ptr = dn.bv_val-2; ptr > e->e_name.bv_val && *ptr != ','; ptr--) { + /* empty */ + } + if ( ptr == e->e_name.bv_val ) break; + dn.bv_val = ++ptr; + dn.bv_len = e->e_name.bv_len - (ptr-e->e_name.bv_val); + for( ptr = ndn.bv_val-2; + ptr > e->e_nname.bv_val && *ptr != ','; + ptr--) + { + /* empty */ } + ndn.bv_val = ++ptr; + ndn.bv_len = e->e_nname.bv_len - (ptr-e->e_nname.bv_val); + } + + op->o_req_dn = e->e_name; + op->o_req_ndn = e->e_nname; + op->ora_e = e; + rc = be->be_add ( op, &rs ); + if ( rc == LDAP_SUCCESS ) { + be_entry_release_w( op, e ); + } else { + entry_free( e ); } return; @@ -1317,17 +1426,16 @@ static struct berval ssbva[] = { }; static struct berval scbva[] = { - BER_BVC("subentry"), + BER_BVNULL, BER_BVNULL }; void syncrepl_updateCookie( syncinfo_t *si, - LDAP *ld, Operation *op, struct berval *pdn, - struct berval *syncCookie + struct sync_cookie *syncCookie ) { Backend *be = op->o_bd; @@ -1344,17 +1452,16 @@ syncrepl_updateCookie( Entry* e = NULL; int rc; + char syncrepl_cbuf[sizeof(CN_STR SYNCREPL_STR)]; struct berval slap_syncrepl_dn_bv = BER_BVNULL; struct berval slap_syncrepl_cn_bv = BER_BVNULL; slap_callback cb; SlapReply rs = {REP_RESULT}; - /* update in memory cookie */ - if ( si->syncCookie != NULL ) { - ber_bvfree( si->syncCookie ); - } - si->syncCookie = ber_dupbv( NULL, syncCookie ); + slap_sync_cookie_free( &si->si_syncCookie, 0 ); + slap_dup_sync_cookie( &si->si_syncCookie, syncCookie ); + mod = (Modifications *) ch_calloc( 1, sizeof( Modifications )); mod->sml_op = LDAP_MOD_REPLACE; mod->sml_desc = slap_schema.si_ad_objectClass; @@ -1364,9 +1471,10 @@ syncrepl_updateCookie( modtail = &mod->sml_next; ber_dupbv( &cnbva[0], (struct berval *) &slap_syncrepl_bvc ); + assert( si->si_id < 1000 ); cnbva[0].bv_len = snprintf( cnbva[0].bv_val, - slap_syncrepl_bvc.bv_len, - "syncrepl%d", si->id ); + slap_syncrepl_bvc.bv_len, + "syncrepl%d", si->si_id ); mod = (Modifications *) ch_calloc( 1, sizeof( Modifications )); mod->sml_op = LDAP_MOD_REPLACE; mod->sml_desc = slap_schema.si_ad_cn; @@ -1375,7 +1483,8 @@ syncrepl_updateCookie( *modtail = mod; modtail = &mod->sml_next; - ber_dupbv( &scbva[0], si->syncCookie ); + if ( scbva[0].bv_val ) ch_free( scbva[0].bv_val ); + ber_dupbv( &scbva[0], &si->si_syncCookie.octet_str[0] ); mod = (Modifications *) ch_calloc( 1, sizeof( Modifications )); mod->sml_op = LDAP_MOD_REPLACE; mod->sml_desc = slap_schema.si_ad_syncreplCookie; @@ -1392,33 +1501,20 @@ syncrepl_updateCookie( *modtail = mod; modtail = &mod->sml_next; -#if 0 - rc = slap_mods_check( modlist, 1, &text, txtbuf, textlen, NULL ); - - if ( rc != LDAP_SUCCESS ) { -#ifdef NEW_LOGGING - LDAP_LOG( OPERATION, ERR, - "syncrepl_updateCookie: mods check (%s)\n", text, 0, 0 ); -#else - Debug( LDAP_DEBUG_ANY, "syncrepl_updateCookie: mods check (%s)\n", - text, 0, 0 ); -#endif - } -#endif + mlnext = mod; op->o_tag = LDAP_REQ_ADD; rc = slap_mods_opattrs( op, modlist, modtail, &text,txtbuf, textlen ); - for ( ml = modlist; ml != NULL; ml = mlnext ) { - mlnext = ml->sml_next; + for ( ml = modlist; ml != NULL; ml = ml->sml_next ) { ml->sml_op = LDAP_MOD_REPLACE; } if( rc != LDAP_SUCCESS ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ERR, - "syncrepl_updateCookie: mods opattrs (%s)\n", text, 0, 0 ); + "syncrepl_updateCookie: mods opattrs (%s)\n", text, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "syncrepl_updateCookie: mods opattrs (%s)\n", text, 0, 0 ); @@ -1427,18 +1523,20 @@ syncrepl_updateCookie( e = ( Entry * ) ch_calloc( 1, sizeof( Entry )); - ber_dupbv( &slap_syncrepl_cn_bv, (struct berval *) &slap_syncrepl_cn_bvc ); + slap_syncrepl_cn_bv.bv_val = syncrepl_cbuf; + assert( si->si_id < 1000 ); slap_syncrepl_cn_bv.bv_len = snprintf( slap_syncrepl_cn_bv.bv_val, - slap_syncrepl_cn_bvc.bv_len, - "cn=syncrepl%d", si->id ); + slap_syncrepl_cn_bvc.bv_len, + "cn=syncrepl%d", si->si_id ); - build_new_dn( &slap_syncrepl_dn_bv, pdn, &slap_syncrepl_cn_bv, NULL ); - dnPrettyNormal( NULL, &slap_syncrepl_dn_bv, &e->e_name, &e->e_nname, NULL ); + build_new_dn( &slap_syncrepl_dn_bv, pdn, &slap_syncrepl_cn_bv, + op->o_tmpmemctx ); + ber_dupbv( &e->e_name, &slap_syncrepl_dn_bv ); + ber_dupbv( &e->e_nname, &slap_syncrepl_dn_bv ); - if ( slap_syncrepl_cn_bv.bv_val ) - ch_free( slap_syncrepl_cn_bv.bv_val ); - if ( slap_syncrepl_dn_bv.bv_val ) - ch_free( slap_syncrepl_dn_bv.bv_val ); + if ( slap_syncrepl_dn_bv.bv_val ) { + sl_free( slap_syncrepl_dn_bv.bv_val, op->o_tmpmemctx ); + } e->e_attrs = NULL; @@ -1447,7 +1545,7 @@ syncrepl_updateCookie( if( rc != LDAP_SUCCESS ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ERR, - "syncrepl_updateCookie: mods2entry (%s)\n", text, 0, 0 ); + "syncrepl_updateCookie: mods2entry (%s)\n", text, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "syncrepl_updateCookie: mods2entry (%s)\n", text, 0, 0 ); @@ -1519,10 +1617,21 @@ update_cookie_retry: done : - if ( cnbva[0].bv_val ) + if ( cnbva[0].bv_val ) { ch_free( cnbva[0].bv_val ); + cnbva[0].bv_val = NULL; + } + if ( scbva[0].bv_val ) { + ch_free( scbva[0].bv_val ); + scbva[0].bv_val = NULL; + } - for ( ; ml != NULL; ml = mlnext ) { + if ( mlnext->sml_next ) { + slap_mods_free( mlnext->sml_next ); + mlnext->sml_next = NULL; + } + + for (ml = modlist ; ml != NULL; ml = mlnext ) { mlnext = ml->sml_next; free( ml ); } @@ -1530,39 +1639,6 @@ done : return; } -void -avl_ber_bvfree( void *bv ) -{ - if( bv == NULL ) { - return; - } - if ( ((struct berval *)bv)->bv_val != NULL ) { - ch_free ( ((struct berval *)bv)->bv_val ); - } - ch_free ( (char *) bv ); -} - -static int -cookie_callback( - Operation* op, - SlapReply* rs -) -{ - syncinfo_t *si = op->o_callback->sc_private; - Attribute *a; - - if ( rs->sr_type != REP_SEARCH ) return LDAP_SUCCESS; - - a = attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_syncreplCookie ); - - if ( a == NULL ) { - si->syncCookie = NULL; - } else { - si->syncCookie = ber_dupbv( NULL, &a->a_vals[0] ); - } - return LDAP_SUCCESS; -} - static int dn_callback( Operation* op, @@ -1572,7 +1648,7 @@ dn_callback( syncinfo_t *si = op->o_callback->sc_private; if ( rs->sr_type == REP_SEARCH ) { - if ( si->syncUUID_ndn != NULL ) { + if ( si->si_syncUUID_ndn.bv_val != NULL ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ERR, "dn_callback : multiple entries match dn\n", 0, 0, 0 ); @@ -1581,11 +1657,7 @@ dn_callback( "dn_callback : multiple entries match dn\n", 0, 0, 0 ); #endif } else { - if ( rs->sr_entry == NULL ) { - si->syncUUID_ndn = NULL; - } else { - si->syncUUID_ndn = ber_dupbv( NULL, &rs->sr_entry->e_nname ); - } + ber_dupbv_x( &si->si_syncUUID_ndn, &rs->sr_entry->e_nname, op->o_tmpmemctx ); } } @@ -1602,39 +1674,35 @@ nonpresent_callback( Attribute *a; int count = 0; struct berval* present_uuid = NULL; - slap_callback cb; - SlapReply rs_cb = {REP_RESULT}; struct nonpresent_entry *np_entry; if ( rs->sr_type == REP_RESULT ) { - count = avl_free( si->presentlist, avl_ber_bvfree ); - si->presentlist = NULL; - return LDAP_SUCCESS; + count = avl_free( si->si_presentlist, avl_ber_bvfree ); + si->si_presentlist = NULL; + } else if ( rs->sr_type == REP_SEARCH ) { a = attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_entryUUID ); - if ( a == NULL ) - return 0; + if ( a == NULL ) return 0; - present_uuid = avl_find( si->presentlist, &a->a_vals[0], syncuuid_cmp ); + present_uuid = avl_find( si->si_presentlist, &a->a_vals[0], + syncuuid_cmp ); if ( present_uuid == NULL ) { np_entry = (struct nonpresent_entry *) - ch_calloc( 1, sizeof( struct nonpresent_entry )); - np_entry->dn = ber_dupbv( NULL, &rs->sr_entry->e_name ); - np_entry->ndn = ber_dupbv( NULL, &rs->sr_entry->e_nname ); - LDAP_LIST_INSERT_HEAD( &si->nonpresentlist, np_entry, np_link ); + ch_calloc( 1, sizeof( struct nonpresent_entry )); + np_entry->npe_name = ber_dupbv( NULL, &rs->sr_entry->e_name ); + np_entry->npe_nname = ber_dupbv( NULL, &rs->sr_entry->e_nname ); + LDAP_LIST_INSERT_HEAD( &si->si_nonpresentlist, np_entry, npe_link ); + } else { - avl_delete( &si->presentlist, + avl_delete( &si->si_presentlist, &a->a_vals[0], syncuuid_cmp ); ch_free( present_uuid->bv_val ); ch_free( present_uuid ); } - return LDAP_SUCCESS; - } else { - return LDAP_SUCCESS; } - + return LDAP_SUCCESS; } static int @@ -1643,12 +1711,11 @@ null_callback( SlapReply* rs ) { - syncinfo_t *si = op->o_callback->sc_private; - if ( rs->sr_err != LDAP_SUCCESS && - rs->sr_err != LDAP_REFERRAL && - rs->sr_err != LDAP_ALREADY_EXISTS && - rs->sr_err != LDAP_NO_SUCH_OBJECT ) { + rs->sr_err != LDAP_REFERRAL && + rs->sr_err != LDAP_ALREADY_EXISTS && + rs->sr_err != LDAP_NO_SUCH_OBJECT ) + { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, ERR, "null_callback : error code 0x%x\n", @@ -1671,7 +1738,6 @@ slap_create_syncrepl_entry( ) { Entry* e; - int rc; struct berval bv; @@ -1679,7 +1745,8 @@ slap_create_syncrepl_entry( attr_merge( e, slap_schema.si_ad_objectClass, ocbva, NULL ); - attr_merge_one( e, slap_schema.si_ad_structuralObjectClass, &ocbva[1], NULL ); + attr_merge_one( e, slap_schema.si_ad_structuralObjectClass, + &ocbva[1], NULL ); attr_merge_one( e, slap_schema.si_ad_cn, cn, NULL ); @@ -1697,3 +1764,83 @@ slap_create_syncrepl_entry( return e; } + +struct berval * +slap_uuidstr_from_normalized( + struct berval* uuidstr, + struct berval* normalized, + void *ctx ) +{ + struct berval *new; + unsigned char nibble; + int i, d = 0; + + if ( normalized == NULL ) + return NULL; + + if ( normalized->bv_len != 16 ) { + return NULL; + } + + if ( uuidstr ) { + new = uuidstr; + } else { + new = (struct berval *)sl_malloc( sizeof(struct berval), ctx ); + } + + new->bv_len = 36; + + if (( new->bv_val = sl_malloc( new->bv_len + 1, ctx )) == NULL) { + if ( !uuidstr ) + sl_free( new, ctx ); + return NULL; + } + + for ( i = 0; i < 16; i++ ) { + if ( i == 4 || i == 6 || i == 8 || i == 10 ) { + new->bv_val[(i<<1)+d] = '-'; + d += 1; + } + + nibble = (normalized->bv_val[i] >> 4) & 0xF; + if ( nibble < 10 ) { + new->bv_val[(i<<1)+d] = nibble + '0'; + } else { + new->bv_val[(i<<1)+d] = nibble - 10 + 'a'; + } + + nibble = (normalized->bv_val[i]) & 0xF; + if ( nibble < 10 ) { + new->bv_val[(i<<1)+d+1] = nibble + '0'; + } else { + new->bv_val[(i<<1)+d+1] = nibble - 10 + 'a'; + } + } + + new->bv_val[new->bv_len] = '\0'; + + return new; +} + +static int +syncuuid_cmp( const void* v_uuid1, const void* v_uuid2 ) +{ + const struct berval *uuid1 = v_uuid1; + const struct berval *uuid2 = v_uuid2; + int rc = uuid1->bv_len - uuid2->bv_len; + if ( rc ) return rc; + return ( strcmp( uuid1->bv_val, uuid2->bv_val ) ); +} + +static void +avl_ber_bvfree( void *bv ) +{ + if( bv == NULL ) { + return; + } + if ( ((struct berval *)bv)->bv_val != NULL ) { + ch_free ( ((struct berval *)bv)->bv_val ); + } + ch_free ( (char *) bv ); +} + diff --git a/servers/slapd/tools/Makefile.in b/servers/slapd/tools/Makefile.in index 8934eac54c..8f71829cff 100644 --- a/servers/slapd/tools/Makefile.in +++ b/servers/slapd/tools/Makefile.in @@ -46,7 +46,8 @@ SLAPD_OBJS = ../globals.o ../config.o ../ch_malloc.o ../cr.o ../backend.o \ ../init.o ../controls.o ../kerberos.o ../passwd.o \ ../index.o ../extended.o ../starttls.o ../sets.o ../mra.o \ ../referral.o ../backglue.o ../oidm.o ../mods.o ../operation.o \ - ../cancel.o ../sl_malloc.o ../backover.o ../ctxcsn.o ../syncrepl.o + ../cancel.o ../sl_malloc.o ../backover.o ../ctxcsn.o ../syncrepl.o \ + ../ldapsync.o ../sessionlog.o SLAPOBJS = $(SLAPD_OBJS) slapcommon.o mimic.o diff --git a/servers/slapd/tools/mimic.c b/servers/slapd/tools/mimic.c index c9bade3f96..51f7324c40 100644 --- a/servers/slapd/tools/mimic.c +++ b/servers/slapd/tools/mimic.c @@ -117,6 +117,26 @@ int slap_sasl_config( } +int connection_client_setup( + ber_socket_t s, + Listener *l, + ldap_pvt_thread_start_t *func, + void *arg ) +{ + assert(0); + return 0; +} + +void connection_client_enable( ber_socket_t s ) +{ + assert(0); +} + +void connection_client_stop( ber_socket_t s ) +{ + assert(0); +} + void connection2anonymous( Connection *c ) { assert(0); diff --git a/servers/slapd/tools/slapadd.c b/servers/slapd/tools/slapadd.c index 1958a42493..cf0a8ef130 100644 --- a/servers/slapd/tools/slapadd.c +++ b/servers/slapd/tools/slapadd.c @@ -3,6 +3,29 @@ * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved. * COPYING RESTRICTIONS APPLY, see COPYRIGHT file */ +/* + * Modified by Jong Hyuk Choi + * + * Modifications provided under the terms of the following condition: + * + * Copyright (c) 2003 by International Business Machines, Inc. + * + * International Business Machines, Inc. (hereinafter called IBM) grants + * permission under its copyrights to use, copy, modify, and distribute this + * Software with or without fee, provided that the above copyright notice and + * all paragraphs of this notice appear in all copies, and that the name of IBM + * not be used in connection with the marketing of any product incorporating + * the Software or modifications thereof, without specific, written prior + * permission. + * + * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, + * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN + * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + #include "portable.h" #include @@ -226,7 +249,8 @@ main( int argc, char **argv ) { vals[0].bv_len = lutil_uuidstr( uuidbuf, sizeof( uuidbuf ) ); vals[0].bv_val = uuidbuf; - attr_merge( e, slap_schema.si_ad_entryUUID, vals, NULL ); + attr_merge_normalize_one( e, + slap_schema.si_ad_entryUUID, vals, NULL ); } if( attr_find( e->e_attrs, slap_schema.si_ad_creatorsName ) diff --git a/servers/slapd/tools/slapcommon.c b/servers/slapd/tools/slapcommon.c index 073f2924c2..cea438712d 100644 --- a/servers/slapd/tools/slapcommon.c +++ b/servers/slapd/tools/slapcommon.c @@ -151,7 +151,7 @@ slap_tool_init( case 'i': /* specify syncrepl id list */ replica_id_string = strdup( optarg ); - if ( !isdigit( *replica_id_string )) { + if ( !isdigit( (unsigned char) *replica_id_string )) { usage( tool ); exit( EXIT_FAILURE ); } diff --git a/servers/slapd/value.c b/servers/slapd/value.c index cf0129738f..01ee39b08a 100644 --- a/servers/slapd/value.c +++ b/servers/slapd/value.c @@ -163,7 +163,8 @@ int asserted_value_validate_normalize( } if( mr->smr_normalize ) { - rc = (mr->smr_normalize)( usage, + rc = (mr->smr_normalize)( + usage|SLAP_MR_VALUE_OF_ASSERTION_SYNTAX, ad ? ad->ad_type->sat_syntax : NULL, mr, in, out, ctx ); @@ -238,7 +239,7 @@ int value_find_ex( mr->smr_normalize ) { rc = (mr->smr_normalize)( - flags & (SLAP_MR_TYPE_MASK|SLAP_MR_SUBTYPE_MASK), + flags & (SLAP_MR_TYPE_MASK|SLAP_MR_SUBTYPE_MASK|SLAP_MR_VALUE_OF_SYNTAX), ad ? ad->ad_type->sat_syntax : NULL, mr, val, &nval, ctx ); diff --git a/servers/slurpd/config.c b/servers/slurpd/config.c index 3f7a8f8b65..ac7f017f35 100644 --- a/servers/slurpd/config.c +++ b/servers/slurpd/config.c @@ -523,10 +523,10 @@ parse_replica_line( fprintf( stderr, "slurpd no longer supports Kerberos.\n" ); exit( EXIT_FAILURE ); } else if ( !strcasecmp( val, SIMPLESTR )) { - ri->ri_bind_method = AUTH_SIMPLE; + ri->ri_bind_method = LDAP_AUTH_SIMPLE; gots |= GOT_METHOD; } else if ( !strcasecmp( val, SASLSTR )) { - ri->ri_bind_method = AUTH_SASL; + ri->ri_bind_method = LDAP_AUTH_SASL; gots |= GOT_METHOD; } else { ri->ri_bind_method = -1; @@ -575,14 +575,13 @@ parse_replica_line( } } - if ( ri->ri_bind_method == AUTH_SASL) { + if ( ri->ri_bind_method == LDAP_AUTH_SASL) { if ((gots & GOT_MECH) == 0) { fprintf( stderr, "Error: \"replica\" line needs SASLmech flag in " ); fprintf( stderr, "slapd config file, line %d\n", lineno ); return -1; } - } - else if ( gots != GOT_ALL ) { + } else if ( gots != GOT_ALL ) { fprintf( stderr, "Error: Malformed \"replica\" line in slapd " ); fprintf( stderr, "config file, line %d\n", lineno ); return -1; diff --git a/servers/slurpd/ldap_op.c b/servers/slurpd/ldap_op.c index f501a17cf0..8b68c15c57 100644 --- a/servers/slurpd/ldap_op.c +++ b/servers/slurpd/ldap_op.c @@ -37,10 +37,10 @@ /* Forward references */ static struct berval **make_singlevalued_berval LDAP_P(( char *, int )); -static int op_ldap_add LDAP_P(( Ri *, Re *, char ** )); -static int op_ldap_modify LDAP_P(( Ri *, Re *, char ** )); -static int op_ldap_delete LDAP_P(( Ri *, Re *, char ** )); -static int op_ldap_modrdn LDAP_P(( Ri *, Re *, char ** )); +static int op_ldap_add LDAP_P(( Ri *, Re *, char **, int * )); +static int op_ldap_modify LDAP_P(( Ri *, Re *, char **, int * )); +static int op_ldap_delete LDAP_P(( Ri *, Re *, char **, int * )); +static int op_ldap_modrdn LDAP_P(( Ri *, Re *, char **, int * )); static LDAPMod *alloc_ldapmod LDAP_P(( void )); static void free_ldapmod LDAP_P(( LDAPMod * )); static void free_ldmarr LDAP_P(( LDAPMod ** )); @@ -64,11 +64,13 @@ int do_ldap( Ri *ri, Re *re, - char **errmsg + char **errmsg, + int *errfree ) { int retry = 2; *errmsg = NULL; + *errfree = 0; do { int lderr; @@ -82,7 +84,7 @@ do_ldap( switch ( re->re_changetype ) { case T_ADDCT: - lderr = op_ldap_add( ri, re, errmsg ); + lderr = op_ldap_add( ri, re, errmsg, errfree ); if ( lderr != LDAP_SUCCESS ) { #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, ERR, "do_ldap: " @@ -99,7 +101,7 @@ do_ldap( break; case T_MODIFYCT: - lderr = op_ldap_modify( ri, re, errmsg ); + lderr = op_ldap_modify( ri, re, errmsg, errfree ); if ( lderr != LDAP_SUCCESS ) { #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, ERR, "do_ldap: " @@ -116,7 +118,7 @@ do_ldap( break; case T_DELETECT: - lderr = op_ldap_delete( ri, re, errmsg ); + lderr = op_ldap_delete( ri, re, errmsg, errfree ); if ( lderr != LDAP_SUCCESS ) { #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, ERR, "do_ldap: " @@ -133,7 +135,7 @@ do_ldap( break; case T_MODRDNCT: - lderr = op_ldap_modrdn( ri, re, errmsg ); + lderr = op_ldap_modrdn( ri, re, errmsg, errfree ); if ( lderr != LDAP_SUCCESS ) { #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, ERR, "do_ldap: " @@ -192,7 +194,8 @@ static int op_ldap_add( Ri *ri, Re *re, - char **errmsg + char **errmsg, + int *errfree ) { Mi *mi; @@ -235,6 +238,8 @@ op_ldap_add( rc = ldap_add_s( ri->ri_ldp, re->re_dn, ldmarr ); ldap_get_option( ri->ri_ldp, LDAP_OPT_ERROR_NUMBER, &lderr); + ldap_get_option( ri->ri_ldp, LDAP_OPT_ERROR_STRING, errmsg); + *errfree = 1; } else { *errmsg = "No modifications to do"; @@ -261,7 +266,8 @@ static int op_ldap_modify( Ri *ri, Re *re, - char **errmsg + char **errmsg, + int *errfree ) { Mi *mi; @@ -397,6 +403,8 @@ op_ldap_modify( ri->ri_hostname, ri->ri_port, re->re_dn ); #endif rc = ldap_modify_s( ri->ri_ldp, re->re_dn, ldmarr ); + ldap_get_option( ri->ri_ldp, LDAP_OPT_ERROR_STRING, errmsg); + *errfree = 1; } free_ldmarr( ldmarr ); return( rc ); @@ -412,7 +420,8 @@ static int op_ldap_delete( Ri *ri, Re *re, - char **errmsg + char **errmsg, + int *errfree ) { int rc; @@ -426,6 +435,8 @@ op_ldap_delete( ri->ri_hostname, ri->ri_port, re->re_dn ); #endif rc = ldap_delete_s( ri->ri_ldp, re->re_dn ); + ldap_get_option( ri->ri_ldp, LDAP_OPT_ERROR_STRING, errmsg); + *errfree = 1; return( rc ); } @@ -446,7 +457,8 @@ static int op_ldap_modrdn( Ri *ri, Re *re, - char **errmsg + char **errmsg, + int *errfree ) { int rc = 0; @@ -603,6 +615,8 @@ op_ldap_modrdn( rc = ldap_rename2_s( ri->ri_ldp, re->re_dn, newrdn, newsup, drdnflag ); ldap_get_option( ri->ri_ldp, LDAP_OPT_ERROR_NUMBER, &lderr); + ldap_get_option( ri->ri_ldp, LDAP_OPT_ERROR_STRING, errmsg); + *errfree = 1; return( lderr ); } @@ -763,6 +777,7 @@ do_bind( ) { int ldrc; + int do_tls = ri->ri_tls; *lderr = 0; @@ -885,7 +900,7 @@ retry: } ldap_set_option(ri->ri_ldp, LDAP_OPT_RESTART, LDAP_OPT_ON); - if( ri->ri_tls ) { + if( do_tls ) { int err = ldap_start_tls_s(ri->ri_ldp, NULL, NULL); if( err != LDAP_SUCCESS ) { @@ -907,13 +922,13 @@ retry: ri->ri_ldp = NULL; return BIND_ERR_TLS_FAILED; } - ri->ri_tls = TLS_OFF; + do_tls = TLS_OFF; goto retry; } } switch ( ri->ri_bind_method ) { - case AUTH_SIMPLE: + case LDAP_AUTH_SIMPLE: /* * Bind with a plaintext password. */ @@ -944,7 +959,7 @@ retry: } break; - case AUTH_SASL: + case LDAP_AUTH_SASL: #ifdef NEW_LOGGING LDAP_LOG ( OPERATION, ARGS, "do_bind: bind to %s as %s via %s (SASL)\n", diff --git a/servers/slurpd/main.c b/servers/slurpd/main.c index 5f53a89e6b..aad65a33ee 100644 --- a/servers/slurpd/main.c +++ b/servers/slurpd/main.c @@ -288,6 +288,10 @@ stop: /* destroy the thread package */ ldap_pvt_thread_destroy(); +#ifdef HAVE_TLS + ldap_pvt_tls_destroy(); +#endif + #ifdef NEW_LOGGING LDAP_LOG ( SLURPD, RESULTS, "main: slurpd terminated\n", 0, 0, 0 ); #else diff --git a/servers/slurpd/proto-slurp.h b/servers/slurpd/proto-slurp.h index d91ba66656..2c5e28b3a2 100644 --- a/servers/slurpd/proto-slurp.h +++ b/servers/slurpd/proto-slurp.h @@ -53,7 +53,7 @@ extern int ldap_debug; extern struct globals *init_globals LDAP_P((void)); /* ldap_op.c */ -int do_ldap LDAP_P((Ri *ri, Re *re, char **errmsg)); +int do_ldap LDAP_P((Ri *ri, Re *re, char **errmsg, int *errfree)); /* lock.c */ FILE *lock_fopen LDAP_P((const char *fname, const char *type, FILE **lfp)); diff --git a/servers/slurpd/ri.c b/servers/slurpd/ri.c index a614c4e2f6..38d48870ac 100644 --- a/servers/slurpd/ri.c +++ b/servers/slurpd/ri.c @@ -51,6 +51,7 @@ Ri_process( Re *re = NULL, *new_re = NULL; int rc ; char *errmsg; + int errfree; (void) SIGNAL( LDAP_SIGUSR1, do_nothing ); #ifdef SIGPIPE @@ -113,7 +114,7 @@ Ri_process( ri->ri_hostname, ri->ri_port, re->re_dn ); #endif } else { - rc = do_ldap( ri, re, &errmsg ); + rc = do_ldap( ri, re, &errmsg, &errfree ); switch ( rc ) { case DO_LDAP_ERR_RETRYABLE: ldap_pvt_thread_sleep( RETRY_SLEEP_TIME ); @@ -145,6 +146,9 @@ Ri_process( (void) sglob->st->st_write( sglob->st ); break; } + if ( errfree && errmsg ) { + ch_free( errmsg ); + } } } else { #ifdef NEW_LOGGING @@ -169,6 +173,10 @@ Ri_process( re = new_re; rq->rq_unlock( rq ); if ( sglob->slurpd_shutdown ) { + if ( ri->ri_ldp ) { + ldap_unbind( ri->ri_ldp ); + ri->ri_ldp = NULL; + } return 0; } } diff --git a/servers/slurpd/slurp.h b/servers/slurpd/slurp.h index 34fe83a062..806c72f921 100644 --- a/servers/slurpd/slurp.h +++ b/servers/slurpd/slurp.h @@ -65,9 +65,6 @@ /* slurpd dump file - contents of rq struct are written here (debugging) */ #define SLURPD_DUMPFILE LDAP_TMPDIR LDAP_DIRSEP "slurpd.dump" -/* default srvtab file. Can be overridden */ -#define SRVTAB "/etc/srvtab" - /* Amount of time to sleep if no more work to do */ #define DEFAULT_NO_WORK_INTERVAL 3 @@ -85,11 +82,6 @@ #define TLS_ON 1 #define TLS_CRITICAL 2 -/* We support simple (plaintext password) and SASL authentication */ -#define AUTH_SIMPLE 1 -#define AUTH_KERBEROS 2 -#define AUTH_SASL 3 - /* Rejection records are prefaced with this string */ #define ERROR_STR "ERROR" diff --git a/tests/Makefile.in b/tests/Makefile.in index 4d5543d329..3759f56e0e 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -3,81 +3,45 @@ ## COPYING RESTRICTIONS APPLY, see COPYRIGHT file ## ## tests Makefile.in for OpenLDAP +RUN=./run SUBDIRS= progs + BUILD_BDB=@BUILD_BDB@ BUILD_HDB=@BUILD_HDB@ BUILD_LDBM=@BUILD_LDBM@ -BUILD_MONITOR=@BUILD_MONITOR@ -BUILD_CACHE=@BUILD_CACHE@ - -test: tests -tests: ldbm -ldbm: hdb -hdb: bdb - -links: data schema ucdata -data: - @-$(LN_S) $(srcdir)/data . -schema: - @-$(LN_S) $(top_srcdir)/servers/slapd/schema . -ucdata: - @-$(LN_S) ../libraries/liblunicode ucdata -dirs: test-db test-repl -test-db test-repl: - @$(MKDIR) $@ +test tests: + @$(MAKE) bdb + @$(MAKE) hdb + @$(MAKE) ldbm -test-bdb: bdb -bdb: bdb-$(BUILD_BDB) +bdb test-bdb: bdb-$(BUILD_BDB) bdb-no: @echo "run configure with --enable-bdb" -bdb-yes bdb-mod: links dirs FORCE +bdb-yes bdb-mod: FORCE @echo "Initiating LDAP tests for BDB..." - @MONITORDB=$(BUILD_MONITOR) PROXYCACHE=$(BUILD_CACHE) BACKENDTYPE=$(BUILD_BDB) $(srcdir)/scripts/all $(srcdir) bdb bdb + @$(RUN) -b bdb all -test-hdb: hdb -hdb: hdb-$(BUILD_HDB) +hdb test-hdb: hdb-$(BUILD_HDB) hdb-no: @echo "run configure with --enable-hdb" -hdb-yes hdb-mod: links dirs FORCE +hdb-yes hdb-mod: FORCE @echo "Initiating LDAP tests for HDB..." - @MONITORDB=$(BUILD_MONITOR) PROXYCACHE=$(BUILD_CACHE) BACKENDTYPE=$(BUILD_HDB) $(srcdir)/scripts/all $(srcdir) hdb hdb + @$(RUN) -b hdb all -test-ldbm: ldbm -ldbm: ldbm-$(BUILD_LDBM) +ldbm test-ldbm: ldbm-$(BUILD_LDBM) ldbm-no: @echo "run configure with --enable-ldbm" -ldbm-yes ldbm-mod: links dirs FORCE +ldbm-yes ldbm-mod: FORCE @echo "Initiating LDAP tests for LDBM..." - @MONITORDB=$(BUILD_MONITOR); PROXYCACHE=$(BUILD_CACHE); \ - BACKENDTYPE=$(BUILD_LDBM); export MONITORDB PROXYCACHE BACKENDTYPE; \ - if test "$(BUILD_BDB)" != "no"; then \ - $(srcdir)/scripts/all $(srcdir) ldbm bdb ; \ - else \ - if test "$(BUILD_HDB)" != "no"; then \ - $(srcdir)/scripts/all $(srcdir) ldbm hdb ; \ - else \ - $(srcdir)/scripts/all $(srcdir) ldbm no ; \ - fi ; \ - fi - -passwd: test-passwd -test-passwd: links dirs FORCE - @echo "Initiating LDAP tests..." - @$(srcdir)/scripts/passwd-search $(srcdir) passwd - -test-nis-schema: test-nis-schema-ldbm -test-nis-schema-ldbm: links dirs FORCE - @echo "Initiating LDAP server with NIS schema & ldbm backend..."; \ - $(srcdir)/scripts/startup_nis_ldap_server.sh $(srcdir) ldbm + @$(RUN) -b ldbm all clean-local: FORCE - -$(RM) -r test-db/[!C]* test-repl/[!C]* test-cache/[!C]* *leak *gmon *core + -$(RM) -r testrun *leak *gmon *core veryclean-local: FORCE @-$(RM) data schema ucdata - -$(RM) -r test-db test-repl test-cache diff --git a/tests/README b/tests/README index e10fb9107d..2ede0e995f 100644 --- a/tests/README +++ b/tests/README @@ -3,6 +3,7 @@ verify basic functionality of the LDAP libraries, slapd, and slurpd. To run all of the tests, type "make test". To run BDB tests, type "make bdb". + To run HDB tests, type "make hdb". To run LDBM tests, type "make ldbm". The test scripts depends on a number of tools commonly available on diff --git a/tests/data/certificate.out b/tests/data/certificate.out new file mode 100644 index 0000000000..0a85b49428 --- /dev/null +++ b/tests/data/certificate.out @@ -0,0 +1,106 @@ +# (userCertificate;binary=*) +dn: cn=Jennifer Smith,ou=Alumni Association,ou=People,o=University of Michigan + ,c=US +objectClass: OpenLDAPperson +objectClass: strongAuthenticationUser +cn: Jennifer Smith +cn: Jen Smith +sn: Smith +uid: jen +postalAddress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109 +seeAlso: cn=All Staff,ou=Groups,o=University of Michigan,c=US +drink: Sam Adams +homePostalAddress: 1000 Maple #44 $ Ann Arbor, MI 48103 +title: Telemarketer, UM Alumni Association +mail: jen@mail.alumni.example.com +homePhone: +1 313 555 2333 +pager: +1 313 555 6442 +facsimileTelephoneNumber: +1 313 555 2756 +telephoneNumber: +1 313 555 8232 +userCertificate;binary:: MIIDjDCCAvWgAwIBAgIBAzANBgkqhkiG9w0BAQQFADB3MQswCQYDV + QQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEfMB0GA1UEChMWT3BlbkxEQVAgRXhhbXBsZSwgTH + RkLjETMBEGA1UEAxMKRXhhbXBsZSBDQTEdMBsGCSqGSIb3DQEJARYOY2FAZXhhbXBsZS5jb20wHhc + NMDMxMDE3MTYzNTM1WhcNMDQxMDE2MTYzNTM1WjCBnjELMAkGA1UEBhMCVVMxETAPBgNVBAgTCE1p + Y2hpZ2FuMR8wHQYDVQQKExZPcGVuTERBUCBFeGFtcGxlLCBMdGQuMRswGQYDVQQLExJBbHVtbmkgQ + XNzb2ljYXRpb24xEjAQBgNVBAMTCUplbiBTbWl0aDEqMCgGCSqGSIb3DQEJARYbamVuQG1haWwuYW + x1bW5pLmV4YW1wbGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDpnXWAL0VkROGO1Rg + 8J3u6F4F7yMqQCbUMsV9rxQisYj45+pmqiHV5urogvT4MGD6eLNFZKBn+0KRni++uu7gbartzpmBa + HOlzRII9ZdVMFfrT2xYNgAlkne6pb6IZIN9UONuH/httENCDJ5WEpjZ48D1Lrml/HYO/W+SAMkpEq + QIDAQABo4H/MIH8MAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIE + NlcnRpZmljYXRlMB0GA1UdDgQWBBTB2saht/od/nis76b9m+pjxfhSPjCBoQYDVR0jBIGZMIGWgBR + LbyEaNiTSkPlDsFNHLX3hwOaYI6F7pHkwdzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3Ju + aWExHzAdBgNVBAoTFk9wZW5MREFQIEV4YW1wbGUsIEx0ZC4xEzARBgNVBAMTCkV4YW1wbGUgQ0ExH + TAbBgkqhkiG9w0BCQEWDmNhQGV4YW1wbGUuY29tggEAMA0GCSqGSIb3DQEBBAUAA4GBAIoGPc/AS0 + cNkMRDNoMIzcFdF9lONMduKBiSuFvv+x8nCek+LUdXxF59V2NPKh2V5gFh5xbAchyv6FVBnpVtPdB + 5akCr5tdFQhuBLUXXDk/tTHGpIWt7OAjEmpuMzsz3GUB8Zf9rioHOs1DMw+GpzWdnFITxXhAqEDc3 + quqPrpxZ + +dn: cn=Ursula Hampster,ou=Alumni Association,ou=People,o=University of Michiga + n,c=US +objectClass: OpenLDAPperson +objectClass: strongAuthenticationUser +cn: Ursula Hampster +sn: Hampster +uid: uham +title: Secretary, UM Alumni Association +postalAddress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109 +seeAlso: cn=All Staff,ou=Groups,o=University of Michigan,c=US +homePostalAddress: 123 Anystreet $ Ann Arbor, MI 48104 +mail: uham@mail.alumni.example.com +homePhone: +1 313 555 8421 +pager: +1 313 555 2844 +facsimileTelephoneNumber: +1 313 555 9700 +telephoneNumber: +1 313 555 5331 +userCertificate;binary:: MIIDazCCAtSgAwIBAgIBAjANBgkqhkiG9w0BAQQFADB3MQswCQYDV + QQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEfMB0GA1UEChMWT3BlbkxEQVAgRXhhbXBsZSwgTH + RkLjETMBEGA1UEAxMKRXhhbXBsZSBDQTEdMBsGCSqGSIb3DQEJARYOY2FAZXhhbXBsZS5jb20wHhc + NMDMxMDE3MTYzMzE5WhcNMDQxMDE2MTYzMzE5WjB+MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2Fs + aWZvcm5pYTEfMB0GA1UEChMWT3BlbkxEQVAgRXhhbXBsZSwgTHRkLjEYMBYGA1UEAxMPVXJzdWxhI + EhhbXBzdGVyMR8wHQYJKoZIhvcNAQkBFhB1aGFtQGV4YW1wbGUuY29tMIGfMA0GCSqGSIb3DQEBAQ + UAA4GNADCBiQKBgQDuxgp5ELV9LmhxWMpV7qc4028QQT3+zzFDXhruuXE7ji2n3S3ea8bOwDtJh+q + nsDe561DhHHHlgIjMKCiDEizYMpxvJPYEXmvp0huRkMgpKZgmel95BSkt6TYmJ0erS3aoimOHLEFi + mmnTLolNRMiWqNBvqwobx940PGwUWEePKQIDAQABo4H/MIH8MAkGA1UdEwQCMAAwLAYJYIZIAYb4Q + gENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBSjI94TbBmuDEeUUO + iC37EK0Uf0XjCBoQYDVR0jBIGZMIGWgBRLbyEaNiTSkPlDsFNHLX3hwOaYI6F7pHkwdzELMAkGA1U + EBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExHzAdBgNVBAoTFk9wZW5MREFQIEV4YW1wbGUsIEx0 + ZC4xEzARBgNVBAMTCkV4YW1wbGUgQ0ExHTAbBgkqhkiG9w0BCQEWDmNhQGV4YW1wbGUuY29tggEAM + A0GCSqGSIb3DQEBBAUAA4GBAIgUcARb3OlWYNbmr1nmqESuxLn16uqI1Ot6WkcICvpkdQ+Bo+R9AP + 05xpoXocZtKdNvBu3FNxB/jFkiOcLU2lX7Px1Ijnsjh60qVRy9HOsHCungIKlGcnXLKHmKu0y//5j + ds/HnaJsGcHI5JRG7CBJbW+wrwge3trJ1xHJI8prN + +# (cAcertificate=*) +dn: o=University of Michigan,c=US +objectClass: organization +objectClass: domainRelatedObject +objectClass: extensibleObject +l: Ann Arbor, Michigan +st: Michigan +o: University of Michigan +o: UMICH +o: UM +o: U-M +o: U of M +description: The University of Michigan at Ann Arbor +postalAddress: University of Michigan $ 535 W. William St. $ Ann Arbor, MI 481 + 09 $ US +telephoneNumber: +1 313 764-1817 +associatedDomain: example.com +cACertificate;binary:: MIIDVDCCAr2gAwIBAgIBADANBgkqhkiG9w0BAQQFADB3MQswCQYDVQQ + GEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEfMB0GA1UEChMWT3BlbkxEQVAgRXhhbXBsZSwgTHRk + LjETMBEGA1UEAxMKRXhhbXBsZSBDQTEdMBsGCSqGSIb3DQEJARYOY2FAZXhhbXBsZS5jb20wHhcNM + DMxMDE3MTYzMDQxWhcNMDQxMDE2MTYzMDQxWjB3MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaW + Zvcm5pYTEfMB0GA1UEChMWT3BlbkxEQVAgRXhhbXBsZSwgTHRkLjETMBEGA1UEAxMKRXhhbXBsZSB + DQTEdMBsGCSqGSIb3DQEJARYOY2FAZXhhbXBsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ + AoGBANljUGxiisAzEiALukzt3Gj/24MRw1J0AZx6GncXLhpNJsAFyA0bYZdAzgvydKeq/uX0i5o/4 + Byc3G71XAAcbJZxDPtrLwpDAdMNOBvKV2r67yTgnpatFLfGRt/FWazj5EbFYkorWWTe+4eEBd9VPz + ebHdIm+DPHipUfIAzRoNejAgMBAAGjge8wgewwHQYDVR0OBBYEFEtvIRo2JNKQ+UOwU0ctfeHA5pg + jMIGhBgNVHSMEgZkwgZaAFEtvIRo2JNKQ+UOwU0ctfeHA5pgjoXukeTB3MQswCQYDVQQGEwJVUzET + MBEGA1UECBMKQ2FsaWZvcm5pYTEfMB0GA1UEChMWT3BlbkxEQVAgRXhhbXBsZSwgTHRkLjETMBEGA + 1UEAxMKRXhhbXBsZSBDQTEdMBsGCSqGSIb3DQEJARYOY2FAZXhhbXBsZS5jb22CAQAwDAYDVR0TBA + UwAwEB/zAZBgNVHREEEjAQgQ5jYUBleGFtcGxlLmNvbTANBgkqhkiG9w0BAQQFAAOBgQCgXD/+28E + l3GXi/uxMNEKqtnIhQdTnNU4il0fZ6pcmHPFC+61Bddow90ZZZh5Gbg5ZBxFRhDXN8K/fix3ewRSj + ASt40dGlEODkE+FsLMt04sYl6kX7RGKg9a46DkeG+uzZnN/3252uCgh+rjNMFAglueUTERv3EtUB1 + iXEoU3GyA== + +# (userCertificate=2$EMAIL=ca@example.com,CN=Example CA,O=Openldap Example\5C, Ltd.,ST=California,C=US) + diff --git a/tests/data/certificate.tls b/tests/data/certificate.tls new file mode 100644 index 0000000000..5aa35341bd --- /dev/null +++ b/tests/data/certificate.tls @@ -0,0 +1,209 @@ +# (userCertificate;binary=*) +dn: cn=Jennifer Smith,ou=Alumni Association,ou=People,o=University of Michigan + ,c=US +objectClass: OpenLDAPperson +objectClass: strongAuthenticationUser +cn: Jennifer Smith +cn: Jen Smith +sn: Smith +uid: jen +postalAddress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109 +seeAlso: cn=All Staff,ou=Groups,o=University of Michigan,c=US +drink: Sam Adams +homePostalAddress: 1000 Maple #44 $ Ann Arbor, MI 48103 +title: Telemarketer, UM Alumni Association +mail: jen@mail.alumni.example.com +homePhone: +1 313 555 2333 +pager: +1 313 555 6442 +facsimileTelephoneNumber: +1 313 555 2756 +telephoneNumber: +1 313 555 8232 +userCertificate;binary:: MIIDjDCCAvWgAwIBAgIBAzANBgkqhkiG9w0BAQQFADB3MQswCQYDV + QQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEfMB0GA1UEChMWT3BlbkxEQVAgRXhhbXBsZSwgTH + RkLjETMBEGA1UEAxMKRXhhbXBsZSBDQTEdMBsGCSqGSIb3DQEJARYOY2FAZXhhbXBsZS5jb20wHhc + NMDMxMDE3MTYzNTM1WhcNMDQxMDE2MTYzNTM1WjCBnjELMAkGA1UEBhMCVVMxETAPBgNVBAgTCE1p + Y2hpZ2FuMR8wHQYDVQQKExZPcGVuTERBUCBFeGFtcGxlLCBMdGQuMRswGQYDVQQLExJBbHVtbmkgQ + XNzb2ljYXRpb24xEjAQBgNVBAMTCUplbiBTbWl0aDEqMCgGCSqGSIb3DQEJARYbamVuQG1haWwuYW + x1bW5pLmV4YW1wbGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDpnXWAL0VkROGO1Rg + 8J3u6F4F7yMqQCbUMsV9rxQisYj45+pmqiHV5urogvT4MGD6eLNFZKBn+0KRni++uu7gbartzpmBa + HOlzRII9ZdVMFfrT2xYNgAlkne6pb6IZIN9UONuH/httENCDJ5WEpjZ48D1Lrml/HYO/W+SAMkpEq + QIDAQABo4H/MIH8MAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIE + NlcnRpZmljYXRlMB0GA1UdDgQWBBTB2saht/od/nis76b9m+pjxfhSPjCBoQYDVR0jBIGZMIGWgBR + LbyEaNiTSkPlDsFNHLX3hwOaYI6F7pHkwdzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3Ju + aWExHzAdBgNVBAoTFk9wZW5MREFQIEV4YW1wbGUsIEx0ZC4xEzARBgNVBAMTCkV4YW1wbGUgQ0ExH + TAbBgkqhkiG9w0BCQEWDmNhQGV4YW1wbGUuY29tggEAMA0GCSqGSIb3DQEBBAUAA4GBAIoGPc/AS0 + cNkMRDNoMIzcFdF9lONMduKBiSuFvv+x8nCek+LUdXxF59V2NPKh2V5gFh5xbAchyv6FVBnpVtPdB + 5akCr5tdFQhuBLUXXDk/tTHGpIWt7OAjEmpuMzsz3GUB8Zf9rioHOs1DMw+GpzWdnFITxXhAqEDc3 + quqPrpxZ + +dn: cn=Ursula Hampster,ou=Alumni Association,ou=People,o=University of Michiga + n,c=US +objectClass: OpenLDAPperson +objectClass: strongAuthenticationUser +cn: Ursula Hampster +sn: Hampster +uid: uham +title: Secretary, UM Alumni Association +postalAddress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109 +seeAlso: cn=All Staff,ou=Groups,o=University of Michigan,c=US +homePostalAddress: 123 Anystreet $ Ann Arbor, MI 48104 +mail: uham@mail.alumni.example.com +homePhone: +1 313 555 8421 +pager: +1 313 555 2844 +facsimileTelephoneNumber: +1 313 555 9700 +telephoneNumber: +1 313 555 5331 +userCertificate;binary:: MIIDazCCAtSgAwIBAgIBAjANBgkqhkiG9w0BAQQFADB3MQswCQYDV + QQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEfMB0GA1UEChMWT3BlbkxEQVAgRXhhbXBsZSwgTH + RkLjETMBEGA1UEAxMKRXhhbXBsZSBDQTEdMBsGCSqGSIb3DQEJARYOY2FAZXhhbXBsZS5jb20wHhc + NMDMxMDE3MTYzMzE5WhcNMDQxMDE2MTYzMzE5WjB+MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2Fs + aWZvcm5pYTEfMB0GA1UEChMWT3BlbkxEQVAgRXhhbXBsZSwgTHRkLjEYMBYGA1UEAxMPVXJzdWxhI + EhhbXBzdGVyMR8wHQYJKoZIhvcNAQkBFhB1aGFtQGV4YW1wbGUuY29tMIGfMA0GCSqGSIb3DQEBAQ + UAA4GNADCBiQKBgQDuxgp5ELV9LmhxWMpV7qc4028QQT3+zzFDXhruuXE7ji2n3S3ea8bOwDtJh+q + nsDe561DhHHHlgIjMKCiDEizYMpxvJPYEXmvp0huRkMgpKZgmel95BSkt6TYmJ0erS3aoimOHLEFi + mmnTLolNRMiWqNBvqwobx940PGwUWEePKQIDAQABo4H/MIH8MAkGA1UdEwQCMAAwLAYJYIZIAYb4Q + gENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBSjI94TbBmuDEeUUO + iC37EK0Uf0XjCBoQYDVR0jBIGZMIGWgBRLbyEaNiTSkPlDsFNHLX3hwOaYI6F7pHkwdzELMAkGA1U + EBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExHzAdBgNVBAoTFk9wZW5MREFQIEV4YW1wbGUsIEx0 + ZC4xEzARBgNVBAMTCkV4YW1wbGUgQ0ExHTAbBgkqhkiG9w0BCQEWDmNhQGV4YW1wbGUuY29tggEAM + A0GCSqGSIb3DQEBBAUAA4GBAIgUcARb3OlWYNbmr1nmqESuxLn16uqI1Ot6WkcICvpkdQ+Bo+R9AP + 05xpoXocZtKdNvBu3FNxB/jFkiOcLU2lX7Px1Ijnsjh60qVRy9HOsHCungIKlGcnXLKHmKu0y//5j + ds/HnaJsGcHI5JRG7CBJbW+wrwge3trJ1xHJI8prN + +# (cAcertificate=*) +dn: o=University of Michigan,c=US +objectClass: organization +objectClass: domainRelatedObject +objectClass: extensibleObject +l: Ann Arbor, Michigan +st: Michigan +o: University of Michigan +o: UMICH +o: UM +o: U-M +o: U of M +description: The University of Michigan at Ann Arbor +postalAddress: University of Michigan $ 535 W. William St. $ Ann Arbor, MI 481 + 09 $ US +telephoneNumber: +1 313 764-1817 +associatedDomain: example.com +cACertificate;binary:: MIIDVDCCAr2gAwIBAgIBADANBgkqhkiG9w0BAQQFADB3MQswCQYDVQQ + GEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEfMB0GA1UEChMWT3BlbkxEQVAgRXhhbXBsZSwgTHRk + LjETMBEGA1UEAxMKRXhhbXBsZSBDQTEdMBsGCSqGSIb3DQEJARYOY2FAZXhhbXBsZS5jb20wHhcNM + DMxMDE3MTYzMDQxWhcNMDQxMDE2MTYzMDQxWjB3MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaW + Zvcm5pYTEfMB0GA1UEChMWT3BlbkxEQVAgRXhhbXBsZSwgTHRkLjETMBEGA1UEAxMKRXhhbXBsZSB + DQTEdMBsGCSqGSIb3DQEJARYOY2FAZXhhbXBsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ + AoGBANljUGxiisAzEiALukzt3Gj/24MRw1J0AZx6GncXLhpNJsAFyA0bYZdAzgvydKeq/uX0i5o/4 + Byc3G71XAAcbJZxDPtrLwpDAdMNOBvKV2r67yTgnpatFLfGRt/FWazj5EbFYkorWWTe+4eEBd9VPz + ebHdIm+DPHipUfIAzRoNejAgMBAAGjge8wgewwHQYDVR0OBBYEFEtvIRo2JNKQ+UOwU0ctfeHA5pg + jMIGhBgNVHSMEgZkwgZaAFEtvIRo2JNKQ+UOwU0ctfeHA5pgjoXukeTB3MQswCQYDVQQGEwJVUzET + MBEGA1UECBMKQ2FsaWZvcm5pYTEfMB0GA1UEChMWT3BlbkxEQVAgRXhhbXBsZSwgTHRkLjETMBEGA + 1UEAxMKRXhhbXBsZSBDQTEdMBsGCSqGSIb3DQEJARYOY2FAZXhhbXBsZS5jb22CAQAwDAYDVR0TBA + UwAwEB/zAZBgNVHREEEjAQgQ5jYUBleGFtcGxlLmNvbTANBgkqhkiG9w0BAQQFAAOBgQCgXD/+28E + l3GXi/uxMNEKqtnIhQdTnNU4il0fZ6pcmHPFC+61Bddow90ZZZh5Gbg5ZBxFRhDXN8K/fix3ewRSj + ASt40dGlEODkE+FsLMt04sYl6kX7RGKg9a46DkeG+uzZnN/3252uCgh+rjNMFAglueUTERv3EtUB1 + iXEoU3GyA== + +# (userCertificate=2$EMAIL=ca@example.com,CN=Example CA,O=Openldap Example\5C, Ltd.,ST=California,C=US) +dn: cn=Ursula Hampster,ou=Alumni Association,ou=People,o=University of Michiga + n,c=US +objectClass: OpenLDAPperson +objectClass: strongAuthenticationUser +cn: Ursula Hampster +sn: Hampster +uid: uham +title: Secretary, UM Alumni Association +postalAddress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109 +seeAlso: cn=All Staff,ou=Groups,o=University of Michigan,c=US +homePostalAddress: 123 Anystreet $ Ann Arbor, MI 48104 +mail: uham@mail.alumni.example.com +homePhone: +1 313 555 8421 +pager: +1 313 555 2844 +facsimileTelephoneNumber: +1 313 555 9700 +telephoneNumber: +1 313 555 5331 +userCertificate;binary:: MIIDazCCAtSgAwIBAgIBAjANBgkqhkiG9w0BAQQFADB3MQswCQYDV + QQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEfMB0GA1UEChMWT3BlbkxEQVAgRXhhbXBsZSwgTH + RkLjETMBEGA1UEAxMKRXhhbXBsZSBDQTEdMBsGCSqGSIb3DQEJARYOY2FAZXhhbXBsZS5jb20wHhc + NMDMxMDE3MTYzMzE5WhcNMDQxMDE2MTYzMzE5WjB+MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2Fs + aWZvcm5pYTEfMB0GA1UEChMWT3BlbkxEQVAgRXhhbXBsZSwgTHRkLjEYMBYGA1UEAxMPVXJzdWxhI + EhhbXBzdGVyMR8wHQYJKoZIhvcNAQkBFhB1aGFtQGV4YW1wbGUuY29tMIGfMA0GCSqGSIb3DQEBAQ + UAA4GNADCBiQKBgQDuxgp5ELV9LmhxWMpV7qc4028QQT3+zzFDXhruuXE7ji2n3S3ea8bOwDtJh+q + nsDe561DhHHHlgIjMKCiDEizYMpxvJPYEXmvp0huRkMgpKZgmel95BSkt6TYmJ0erS3aoimOHLEFi + mmnTLolNRMiWqNBvqwobx940PGwUWEePKQIDAQABo4H/MIH8MAkGA1UdEwQCMAAwLAYJYIZIAYb4Q + gENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBSjI94TbBmuDEeUUO + iC37EK0Uf0XjCBoQYDVR0jBIGZMIGWgBRLbyEaNiTSkPlDsFNHLX3hwOaYI6F7pHkwdzELMAkGA1U + EBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExHzAdBgNVBAoTFk9wZW5MREFQIEV4YW1wbGUsIEx0 + ZC4xEzARBgNVBAMTCkV4YW1wbGUgQ0ExHTAbBgkqhkiG9w0BCQEWDmNhQGV4YW1wbGUuY29tggEAM + A0GCSqGSIb3DQEBBAUAA4GBAIgUcARb3OlWYNbmr1nmqESuxLn16uqI1Ot6WkcICvpkdQ+Bo+R9AP + 05xpoXocZtKdNvBu3FNxB/jFkiOcLU2lX7Px1Ijnsjh60qVRy9HOsHCungIKlGcnXLKHmKu0y//5j + ds/HnaJsGcHI5JRG7CBJbW+wrwge3trJ1xHJI8prN + +# (userCertificate:certificateExactMatch:=3$EMAIL=ca@example.com,CN=Example CA,O=Openldap Example\5C, Ltd.,ST=California,C=US) +dn: cn=Jennifer Smith,ou=Alumni Association,ou=People,o=University of Michigan + ,c=US +objectClass: OpenLDAPperson +objectClass: strongAuthenticationUser +cn: Jennifer Smith +cn: Jen Smith +sn: Smith +uid: jen +postalAddress: Alumni Association $ 111 Maple St $ Ann Arbor, MI 48109 +seeAlso: cn=All Staff,ou=Groups,o=University of Michigan,c=US +drink: Sam Adams +homePostalAddress: 1000 Maple #44 $ Ann Arbor, MI 48103 +title: Telemarketer, UM Alumni Association +mail: jen@mail.alumni.example.com +homePhone: +1 313 555 2333 +pager: +1 313 555 6442 +facsimileTelephoneNumber: +1 313 555 2756 +telephoneNumber: +1 313 555 8232 +userCertificate;binary:: MIIDjDCCAvWgAwIBAgIBAzANBgkqhkiG9w0BAQQFADB3MQswCQYDV + QQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEfMB0GA1UEChMWT3BlbkxEQVAgRXhhbXBsZSwgTH + RkLjETMBEGA1UEAxMKRXhhbXBsZSBDQTEdMBsGCSqGSIb3DQEJARYOY2FAZXhhbXBsZS5jb20wHhc + NMDMxMDE3MTYzNTM1WhcNMDQxMDE2MTYzNTM1WjCBnjELMAkGA1UEBhMCVVMxETAPBgNVBAgTCE1p + Y2hpZ2FuMR8wHQYDVQQKExZPcGVuTERBUCBFeGFtcGxlLCBMdGQuMRswGQYDVQQLExJBbHVtbmkgQ + XNzb2ljYXRpb24xEjAQBgNVBAMTCUplbiBTbWl0aDEqMCgGCSqGSIb3DQEJARYbamVuQG1haWwuYW + x1bW5pLmV4YW1wbGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDpnXWAL0VkROGO1Rg + 8J3u6F4F7yMqQCbUMsV9rxQisYj45+pmqiHV5urogvT4MGD6eLNFZKBn+0KRni++uu7gbartzpmBa + HOlzRII9ZdVMFfrT2xYNgAlkne6pb6IZIN9UONuH/httENCDJ5WEpjZ48D1Lrml/HYO/W+SAMkpEq + QIDAQABo4H/MIH8MAkGA1UdEwQCMAAwLAYJYIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIE + NlcnRpZmljYXRlMB0GA1UdDgQWBBTB2saht/od/nis76b9m+pjxfhSPjCBoQYDVR0jBIGZMIGWgBR + LbyEaNiTSkPlDsFNHLX3hwOaYI6F7pHkwdzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3Ju + aWExHzAdBgNVBAoTFk9wZW5MREFQIEV4YW1wbGUsIEx0ZC4xEzARBgNVBAMTCkV4YW1wbGUgQ0ExH + TAbBgkqhkiG9w0BCQEWDmNhQGV4YW1wbGUuY29tggEAMA0GCSqGSIb3DQEBBAUAA4GBAIoGPc/AS0 + cNkMRDNoMIzcFdF9lONMduKBiSuFvv+x8nCek+LUdXxF59V2NPKh2V5gFh5xbAchyv6FVBnpVtPdB + 5akCr5tdFQhuBLUXXDk/tTHGpIWt7OAjEmpuMzsz3GUB8Zf9rioHOs1DMw+GpzWdnFITxXhAqEDc3 + quqPrpxZ + +# (cAcertificate;binary:certificateMatch:=\30\82\03\54\30\82\02\bd\a0\03\02\01\02\02\01\00\30\0d\06\09\2a\86\48\86\f7\0d\01\01\04\05\00\30\77\31\0b\30\09\06\03\55\04\06\13\02\55\53\31\13\30\11\06\03\55\04\08\13\0a\43\61\6c\69\66\6f\72\6e\69\61\31\1f\30\1d\06\03\55\04\0a\13\16\4f\70\65\6e\4c\44\41\50\20\45\78\61\6d\70\6c\65\2c\20\4c\74\64\2e\31\13\30\11\06\03\55\04\03\13\0a\45\78\61\6d\70\6c\65\20\43\41\31\1d\30\1b\06\09\2a\86\48\86\f7\0d\01\09\01\16\0e\63\61\40\65\78\61\6d\70\6c\65\2e\63\6f\6d\30\1e\17\0d\30\33\31\30\31\37\31\36\33\30\34\31\5a\17\0d\30\34\31\30\31\36\31\36\33\30\34\31\5a\30\77\31\0b\30\09\06\03\55\04\06\13\02\55\53\31\13\30\11\06\03\55\04\08\13\0a\43\61\6c\69\66\6f\72\6e\69\61\31\1f\30\1d\06\03\55\04\0a\13\16\4f\70\65\6e\4c\44\41\50\20\45\78\61\6d\70\6c\65\2c\20\4c\74\64\2e\31\13\30\11\06\03\55\04\03\13\0a\45\78\61\6d\70\6c\65\20\43\41\31\1d\30\1b\06\09\2a\86\48\86\f7\0d\01\09\01\16\0e\63\61\40\65\78\61\6d\70\6c\65\2e\63\6f\6d\30\81\9f\30\0d\06\09\2a\86\48\86\f7\0d\01\01\01\05\00\03\81\8d\00\30\81\89\02\81\81\00\d9\63\50\6c\62\8a\c0\33\12\20\0b\ba\4c\ed\dc\68\ff\db\83\11\c3\52\74\01\9c\7a\1a\77\17\2e\1a\4d\26\c0\05\c8\0d\1b\61\97\40\ce\0b\f2\74\a7\aa\fe\e5\f4\8b\9a\3f\e0\1c\9c\dc\6e\f5\5c\00\1c\6c\96\71\0c\fb\6b\2f\0a\43\01\d3\0d\38\1b\ca\57\6a\fa\ef\24\e0\9e\96\ad\14\b7\c6\46\df\c5\59\ac\e3\e4\46\c5\62\4a\2b\59\64\de\fb\87\84\05\df\55\3f\37\9b\1d\d2\26\f8\33\c7\8a\95\1f\20\0c\d1\a0\d7\a3\02\03\01\00\01\a3\81\ef\30\81\ec\30\1d\06\03\55\1d\0e\04\16\04\14\4b\6f\21\1a\36\24\d2\90\f9\43\b0\53\47\2d\7d\e1\c0\e6\98\23\30\81\a1\06\03\55\1d\23\04\81\99\30\81\96\80\14\4b\6f\21\1a\36\24\d2\90\f9\43\b0\53\47\2d\7d\e1\c0\e6\98\23\a1\7b\a4\79\30\77\31\0b\30\09\06\03\55\04\06\13\02\55\53\31\13\30\11\06\03\55\04\08\13\0a\43\61\6c\69\66\6f\72\6e\69\61\31\1f\30\1d\06\03\55\04\0a\13\16\4f\70\65\6e\4c\44\41\50\20\45\78\61\6d\70\6c\65\2c\20\4c\74\64\2e\31\13\30\11\06\03\55\04\03\13\0a\45\78\61\6d\70\6c\65\20\43\41\31\1d\30\1b\06\09\2a\86\48\86\f7\0d\01\09\01\16\0e\63\61\40\65\78\61\6d\70\6c\65\2e\63\6f\6d\82\01\00\30\0c\06\03\55\1d\13\04\05\30\03\01\01\ff\30\19\06\03\55\1d\11\04\12\30\10\81\0e\63\61\40\65\78\61\6d\70\6c\65\2e\63\6f\6d\30\0d\06\09\2a\86\48\86\f7\0d\01\01\04\05\00\03\81\81\00\a0\5c\3f\fe\db\c1\25\dc\65\e2\fe\ec\4c\34\42\aa\b6\72\21\41\d4\e7\35\4e\22\97\47\d9\ea\97\26\1c\f1\42\fb\ad\41\75\da\30\f7\46\59\66\1e\46\6e\0e\59\07\11\51\84\35\cd\f0\af\df\8b\1d\de\c1\14\a3\01\2b\78\d1\d1\a5\10\e0\e4\13\e1\6c\2c\cb\74\e2\c6\25\ea\45\fb\44\62\a0\f5\ae\3a\0e\47\86\fa\ec\d9\9c\df\f7\db\9d\ae\0a\08\7e\ae\33\4c\14\08\25\b9\e5\13\11\1b\f7\12\d5\01\d6\25\c4\a1\4d\c6\c8) +dn: o=University of Michigan,c=US +objectClass: organization +objectClass: domainRelatedObject +objectClass: extensibleObject +l: Ann Arbor, Michigan +st: Michigan +o: University of Michigan +o: UMICH +o: UM +o: U-M +o: U of M +description: The University of Michigan at Ann Arbor +postalAddress: University of Michigan $ 535 W. William St. $ Ann Arbor, MI 481 + 09 $ US +telephoneNumber: +1 313 764-1817 +associatedDomain: example.com +cACertificate;binary:: MIIDVDCCAr2gAwIBAgIBADANBgkqhkiG9w0BAQQFADB3MQswCQYDVQQ + GEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEfMB0GA1UEChMWT3BlbkxEQVAgRXhhbXBsZSwgTHRk + LjETMBEGA1UEAxMKRXhhbXBsZSBDQTEdMBsGCSqGSIb3DQEJARYOY2FAZXhhbXBsZS5jb20wHhcNM + DMxMDE3MTYzMDQxWhcNMDQxMDE2MTYzMDQxWjB3MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaW + Zvcm5pYTEfMB0GA1UEChMWT3BlbkxEQVAgRXhhbXBsZSwgTHRkLjETMBEGA1UEAxMKRXhhbXBsZSB + DQTEdMBsGCSqGSIb3DQEJARYOY2FAZXhhbXBsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ + AoGBANljUGxiisAzEiALukzt3Gj/24MRw1J0AZx6GncXLhpNJsAFyA0bYZdAzgvydKeq/uX0i5o/4 + Byc3G71XAAcbJZxDPtrLwpDAdMNOBvKV2r67yTgnpatFLfGRt/FWazj5EbFYkorWWTe+4eEBd9VPz + ebHdIm+DPHipUfIAzRoNejAgMBAAGjge8wgewwHQYDVR0OBBYEFEtvIRo2JNKQ+UOwU0ctfeHA5pg + jMIGhBgNVHSMEgZkwgZaAFEtvIRo2JNKQ+UOwU0ctfeHA5pgjoXukeTB3MQswCQYDVQQGEwJVUzET + MBEGA1UECBMKQ2FsaWZvcm5pYTEfMB0GA1UEChMWT3BlbkxEQVAgRXhhbXBsZSwgTHRkLjETMBEGA + 1UEAxMKRXhhbXBsZSBDQTEdMBsGCSqGSIb3DQEJARYOY2FAZXhhbXBsZS5jb22CAQAwDAYDVR0TBA + UwAwEB/zAZBgNVHREEEjAQgQ5jYUBleGFtcGxlLmNvbTANBgkqhkiG9w0BAQQFAAOBgQCgXD/+28E + l3GXi/uxMNEKqtnIhQdTnNU4il0fZ6pcmHPFC+61Bddow90ZZZh5Gbg5ZBxFRhDXN8K/fix3ewRSj + ASt40dGlEODkE+FsLMt04sYl6kX7RGKg9a46DkeG+uzZnN/3252uCgh+rjNMFAglueUTERv3EtUB1 + iXEoU3GyA== + diff --git a/tests/data/ditcontentrules.conf b/tests/data/ditcontentrules.conf new file mode 100644 index 0000000000..905cc15cc1 --- /dev/null +++ b/tests/data/ditcontentrules.conf @@ -0,0 +1,5 @@ +# $OpenLDAP$ +ditcontentrule ( 2.5.6.4 NAME 'organization' AUX domainRelatedObject ) +ditcontentrule ( 2.5.6.5 NAME 'organizationalUnit' AUX extensibleObject ) +ditcontentrule ( 2.5.6.9 NAME 'groupOfNames' ) +ditcontentrule ( 2.5.6.17 NAME 'groupOfUniqueNames' ) diff --git a/tests/data/slapd-acl.conf b/tests/data/slapd-acl.conf index 9c58c0cd27..2a59e3d3b1 100644 --- a/tests/data/slapd-acl.conf +++ b/tests/data/slapd-acl.conf @@ -8,8 +8,8 @@ include ./schema/cosine.schema include ./schema/inetorgperson.schema include ./schema/openldap.schema include ./schema/nis.schema -pidfile ./test-db/slapd.pid -argsfile ./test-db/slapd.args +pidfile ./testrun/slapd.1.pid +argsfile ./testrun/slapd.1.args # global ACLs access to dn.base="" attr=objectClass by users read @@ -25,7 +25,7 @@ modulepath ../servers/slapd/back-@BACKEND@/ database @BACKEND@ #ldbm#cachesize 0 suffix "o=University of Michigan,c=US" -directory ./test-db +directory ./testrun/db.1.a rootdn "cn=Manager,o=University of Michigan,c=US" rootpw secret #ldbm#index objectClass eq diff --git a/tests/data/slapd-cache-master.conf b/tests/data/slapd-cache-master.conf index c6721fcf42..b9054cdc95 100644 --- a/tests/data/slapd-cache-master.conf +++ b/tests/data/slapd-cache-master.conf @@ -8,8 +8,8 @@ include ./schema/inetorgperson.schema include ./schema/openldap.schema include ./schema/nis.schema # -pidfile ./test-db/slapd.pid -argsfile ./test-db/slapd.args +pidfile ./testrun/slapd.1.pid +argsfile ./testrun/slapd.1.args modulepath ../servers/slapd/back-@BACKEND@/ @MODULELOAD@ @@ -20,7 +20,7 @@ modulepath ../servers/slapd/back-@BACKEND@/ database @BACKEND@ suffix "o=University of Michigan,c=US" -directory ./test-db +directory ./testrun/db.1.a rootdn "cn=Manager,o=University of Michigan,c=US" rootpw secret index objectClass eq diff --git a/tests/data/slapd-glue.conf b/tests/data/slapd-glue.conf index e3979d0833..76822fbcaf 100644 --- a/tests/data/slapd-glue.conf +++ b/tests/data/slapd-glue.conf @@ -9,8 +9,8 @@ include ./schema/cosine.schema include ./schema/inetorgperson.schema include ./schema/openldap.schema include ./schema/nis.schema -pidfile ./test-db/slapd.pid -argsfile ./test-db/slapd.args +pidfile ./testrun/slapd.1.pid +argsfile ./testrun/slapd.1.args modulepath ../servers/slapd/back-@BACKEND@/ @MODULELOAD@ @@ -22,7 +22,7 @@ modulepath ../servers/slapd/back-@BACKEND@/ database @BACKEND@ suffix "ou=Information Technology Division,ou=People,o=University of Michigan, c=US" subordinate -directory ./test-db/C_db1 +directory ./testrun/db.1.a rootdn "cn=Manager, o=University of Michigan, c=US" #ldbm#index objectclass eq #ldbm#index uid pres,eq,sub @@ -36,7 +36,7 @@ rootdn "cn=Manager, o=University of Michigan, c=US" database @BACKEND@ suffix "ou=Groups,o=University of Michigan, c=US" subordinate -directory ./test-db/C_db2 +directory ./testrun/db.1.b rootdn "cn=Manager, o=University of Michigan, c=US" #ldbm#index objectclass eq #ldbm#index uid pres,eq,sub @@ -49,7 +49,7 @@ rootdn "cn=Manager, o=University of Michigan, c=US" database @BACKEND@ suffix "o=University of Michigan, c=US" -directory ./test-db/C_db3 +directory ./testrun/db.1.c rootdn "cn=Manager, o=University of Michigan, c=US" rootpw secret #ldbm#index objectclass eq diff --git a/tests/data/slapd-master.conf b/tests/data/slapd-master.conf index f11a4013fe..67cfad2c01 100644 --- a/tests/data/slapd-master.conf +++ b/tests/data/slapd-master.conf @@ -8,8 +8,11 @@ include ./schema/cosine.schema include ./schema/inetorgperson.schema include ./schema/openldap.schema include ./schema/nis.schema -pidfile ./test-db/slapd.pid -argsfile ./test-db/slapd.args + +include ./testdata/ditcontentrules.conf + +pidfile ./testrun/slapd.1.pid +argsfile ./testrun/slapd.1.args modulepath ../servers/slapd/back-@BACKEND@/ @MODULELOAD@ @@ -20,7 +23,7 @@ modulepath ../servers/slapd/back-@BACKEND@/ database @BACKEND@ suffix "o=University of Michigan,c=US" -directory ./test-db +directory ./testrun/db.1.a rootdn "cn=Manager,o=University of Michigan,c=US" rootpw secret #ldbm#index objectClass eq diff --git a/tests/data/slapd-proxycache.conf b/tests/data/slapd-proxycache.conf index b0dd36b7de..7392f3e356 100644 --- a/tests/data/slapd-proxycache.conf +++ b/tests/data/slapd-proxycache.conf @@ -8,11 +8,14 @@ include ./schema/inetorgperson.schema include ./schema/openldap.schema include ./schema/nis.schema -pidfile ./test-cache/slapd.pid -argsfile ./test-cache/slapd.args +pidfile ./testrun/slapd.2.pid +argsfile ./testrun/slapd.2.args access to * by write +modulepath ../servers/slapd/back-@BACKEND@/ +@MODULELOAD@ + ####################################################################### # database definitions ####################################################################### @@ -21,7 +24,7 @@ database @BACKEND@ suffix "o=University of Michigan,c=US,cn=cache" cachesize 20 -directory ./test-cache +directory ./testrun/db.2.a index objectClass eq index cn,sn,uid,mail pres,eq,sub @@ -36,7 +39,7 @@ rewriteRule "(.*)o=University of Michigan,c=US,cn=cache" "%1o=University of Mich suffix "o=University of Michigan,c=US" -uri ldap://127.0.0.1:9009/o=University%20of%20Michigan,c=US +uri ldap://127.0.0.1:9011/o=University%20of%20Michigan,c=US cacheparams 10000 15000 2 @ENTRY_LIMIT@ @CACHETTL@ attrset 0 sn cn title uid diff --git a/tests/data/slapd-pw.conf b/tests/data/slapd-pw.conf index 2c6dd41666..bb0ae11f01 100644 --- a/tests/data/slapd-pw.conf +++ b/tests/data/slapd-pw.conf @@ -8,8 +8,8 @@ include ./schema/cosine.schema include ./schema/inetorgperson.schema include ./schema/openldap.schema include ./schema/nis.schema -pidfile ./test-db/slapd.pid -argsfile ./test-db/slapd.args +pidfile ./testrun/slapd.1.pid +argsfile ./testrun/slapd.1.args # password-hash {md5} @@ -23,7 +23,7 @@ modulepath ../servers/slapd/back-@BACKEND@/ database @BACKEND@ #ldbm#cachesize 0 suffix "o=University of Michigan,c=US" -directory ./test-db +directory ./testrun/db.1.a rootdn "cn=Manager,o=University of Michigan,c=US" rootpw secret index objectClass eq diff --git a/tests/data/slapd-ref-slave.conf b/tests/data/slapd-ref-slave.conf index c4ae949fdd..9a9d9897f6 100644 --- a/tests/data/slapd-ref-slave.conf +++ b/tests/data/slapd-ref-slave.conf @@ -9,8 +9,8 @@ include ./schema/inetorgperson.schema include ./schema/openldap.schema include ./schema/nis.schema # -pidfile ./test-repl/slapd.pid -argsfile ./test-repl/slapd.args +pidfile ./testrun/slapd.2.pid +argsfile ./testrun/slapd.2.args modulepath ../servers/slapd/back-@BACKEND@/ @MODULELOAD@ @@ -19,12 +19,12 @@ modulepath ../servers/slapd/back-@BACKEND@/ # ldbm database definitions ####################################################################### -referral "ldap://localhost:9009/" +referral "ldap://localhost:9011/" database @BACKEND@ cachesize 0 suffix "o=University of Mich,c=US" -directory ./test-repl +directory ./testrun/db.2.a rootdn "cn=Manager,o=University of Mich,c=US" rootpw secret #ldbm#index objectClass eq diff --git a/tests/data/slapd-referrals.conf b/tests/data/slapd-referrals.conf index ed0fb9db32..a24079d6dc 100644 --- a/tests/data/slapd-referrals.conf +++ b/tests/data/slapd-referrals.conf @@ -8,8 +8,8 @@ include ./schema/cosine.schema include ./schema/inetorgperson.schema include ./schema/openldap.schema include ./schema/nis.schema -pidfile ./test-db/slapd.pid -argsfile ./test-db/slapd.args +pidfile ./testrun/slapd.pid +argsfile ./testrun/slapd.args modulepath ../servers/slapd/back-@BACKEND@/ @MODULELOAD@ @@ -20,7 +20,7 @@ modulepath ../servers/slapd/back-@BACKEND@/ database @BACKEND@ suffix "c=US" -directory ./test-db +directory ./testrun/db.1.a rootdn "cn=Manager,o=University of Michigan,c=US" rootpw secret #ldbm#index objectClass eq diff --git a/tests/data/slapd-repl-master.conf b/tests/data/slapd-repl-master.conf index f2afea37f1..590b354261 100644 --- a/tests/data/slapd-repl-master.conf +++ b/tests/data/slapd-repl-master.conf @@ -9,8 +9,8 @@ include ./schema/inetorgperson.schema include ./schema/openldap.schema include ./schema/nis.schema # -pidfile ./test-db/slapd.pid -argsfile ./test-db/slapd.args +pidfile ./testrun/slapd.1.pid +argsfile ./testrun/slapd.1.args modulepath ../servers/slapd/back-@BACKEND@/ @MODULELOAD@ @@ -22,7 +22,7 @@ modulepath ../servers/slapd/back-@BACKEND@/ database @BACKEND@ #ldbm#cachesize 0 suffix "o=University of Michigan,c=US" -directory ./test-db +directory ./testrun/db.1.a rootdn "cn=Manager,o=University of Michigan,c=US" rootpw secret #ldbm#index objectClass eq @@ -30,9 +30,9 @@ rootpw secret #bdb#index objectClass eq #bdb#index cn,sn,uid pres,eq,sub -replogfile ./test-db/slapd.replog +replogfile ./testrun/slapd.1.replog -replica host=localhost:9010 +replica host=localhost:9012 binddn="cn=Replica,o=University of Michigan,c=US" bindmethod=simple credentials=secret diff --git a/tests/data/slapd-repl-slave.conf b/tests/data/slapd-repl-slave.conf index 569faabb98..cdd78785a9 100644 --- a/tests/data/slapd-repl-slave.conf +++ b/tests/data/slapd-repl-slave.conf @@ -9,8 +9,8 @@ include ./schema/inetorgperson.schema include ./schema/openldap.schema include ./schema/nis.schema # -pidfile ./test-repl/slapd.pid -argsfile ./test-repl/slapd.args +pidfile ./testrun/slapd.2.pid +argsfile ./testrun/slapd.2.args modulepath ../servers/slapd/back-@BACKEND@/ @MODULELOAD@ @@ -22,11 +22,11 @@ modulepath ../servers/slapd/back-@BACKEND@/ database @BACKEND@ #ldbm#cachesize 0 suffix "o=University of Michigan,c=US" -directory ./test-repl +directory ./testrun/db.2.a rootdn "cn=Replica,o=University of Michigan,c=US" rootpw secret updatedn "cn=Replica,o=University of Michigan,c=US" -updateref "ldap://localhost:9009" +updateref "ldap://localhost:9010" #ldbm#index objectClass eq #ldbm#index cn,sn,uid pres,eq,sub #bdb#index objectClass eq diff --git a/tests/data/slapd-repl-submaster.conf b/tests/data/slapd-repl-submaster.conf deleted file mode 100644 index a2d44a5946..0000000000 --- a/tests/data/slapd-repl-submaster.conf +++ /dev/null @@ -1,40 +0,0 @@ -# $OpenLDAP$ -# -# master slapd config -- for testing of replication -# -ucdata-path ./ucdata -include ./schema/core.schema -include ./schema/cosine.schema -include ./schema/inetorgperson.schema -include ./schema/openldap.schema -include ./schema/nis.schema -# -pidfile ./test-db/slapd.pid -argsfile ./test-db/slapd.args - -modulepath ../servers/slapd/back-@BACKEND@/ -@MODULELOAD@ - -####################################################################### -# ldbm database definitions -####################################################################### - -database @BACKEND@ -#ldbm#cachesize 0 -suffix "o=University of Michigan,c=US" -directory ./test-db -rootdn "cn=Manager,o=University of Michigan,c=US" -rootpw secret -#ldbm#index objectClass eq -#ldbm#index cn,sn,uid pres,eq,sub -#bdb#index objectClass eq -#bdb#index cn,sn,uid pres,eq,sub - -replogfile ./test-db/slapd.replog - -replica host=localhost:9010 - suffix="ou=Groups,o=University of Michigan,c=US" - attr!=description - binddn="cn=Replica,ou=Groups,o=University of Michigan,c=US" - bindmethod=simple - credentials=secret diff --git a/tests/data/slapd-repl-subslave.conf b/tests/data/slapd-repl-subslave.conf deleted file mode 100644 index b67ad30404..0000000000 --- a/tests/data/slapd-repl-subslave.conf +++ /dev/null @@ -1,33 +0,0 @@ -# $OpenLDAP$ -# -# slave slapd config -- for testing of replication -# -ucdata-path ./ucdata -include ./schema/core.schema -include ./schema/cosine.schema -include ./schema/inetorgperson.schema -include ./schema/openldap.schema -include ./schema/nis.schema -# -pidfile ./test-repl/slapd.pid -argsfile ./test-repl/slapd.args - -modulepath ../servers/slapd/back-@BACKEND@/ -@MODULELOAD@ - -####################################################################### -# ldbm database definitions -####################################################################### - -database @BACKEND@ -#ldbm#cachesize 0 -suffix "ou=Groups, o=University of Michigan, c=US" -directory ./test-repl -rootdn "cn=Replica,ou=Groups,o=University of Michigan,c=US" -rootpw secret -updatedn "cn=Replica,ou=Groups,o=University of Michigan,c=US" -updateref "ldap://localhost:9009" -#ldbm#index objectClass eq -#ldbm#index cn,sn,uid pres,eq,sub -#bdb#index objectClass eq -#bdb#index cn,sn,uid pres,eq,sub diff --git a/tests/data/slapd-schema.conf b/tests/data/slapd-schema.conf index b4b9bfbb70..5db0d0edfa 100644 --- a/tests/data/slapd-schema.conf +++ b/tests/data/slapd-schema.conf @@ -15,11 +15,11 @@ include ./schema/misc.schema include ./schema/nis.schema include ./schema/openldap.schema # -pidfile ./test-db/slapd.pid -argsfile ./test-db/slapd.args +pidfile ./testrun/slapd.1.pid +argsfile ./testrun/slapd.1.args # -rootdse ./data/rootdse.ldif +rootdse ./testdata/rootdse.ldif modulepath ../servers/slapd/back-@BACKEND@/ @MODULELOAD@ @@ -30,13 +30,13 @@ modulepath ../servers/slapd/back-@BACKEND@/ database @BACKEND@ suffix "o=OpenLDAP Project,l=Internet" -directory ./test-db +directory ./testrun/db.1.a #ldbm#index objectClass eq #bdb#index objectClass eq #database @BACKEND@ #suffix "dc=example,dc=com" -#directory ./test-repl +#directory ./testrun/db.1.b #index objectClass eq #monitor#database monitor diff --git a/tests/data/slapd-syncrepl-master.conf b/tests/data/slapd-syncrepl-master.conf index e9e2b286fd..7e2fa3406e 100644 --- a/tests/data/slapd-syncrepl-master.conf +++ b/tests/data/slapd-syncrepl-master.conf @@ -9,8 +9,8 @@ include ./schema/inetorgperson.schema include ./schema/openldap.schema include ./schema/nis.schema # -pidfile ./test-db/slapd.pid -argsfile ./test-db/slapd.args +pidfile ./testrun/slapd.1.pid +argsfile ./testrun/slapd.1.args modulepath ../servers/slapd/back-@BACKEND@/ @MODULELOAD@ @@ -21,10 +21,12 @@ modulepath ../servers/slapd/back-@BACKEND@/ database @BACKEND@ suffix "o=University of Michigan,c=US" -directory ./test-db +directory ./testrun/db.1.a rootdn "cn=Manager,o=University of Michigan,c=US" rootpw secret #ldbm#index objectClass eq #ldbm#index cn,sn,uid pres,eq,sub #bdb#index objectClass eq #bdb#index cn,sn,uid pres,eq,sub + +sessionlog 1 100 diff --git a/tests/data/slapd-syncrepl-slave-persist1.conf b/tests/data/slapd-syncrepl-slave-persist1.conf index fb925e456c..31fc3660ba 100644 --- a/tests/data/slapd-syncrepl-slave-persist1.conf +++ b/tests/data/slapd-syncrepl-slave-persist1.conf @@ -9,8 +9,8 @@ include ./schema/inetorgperson.schema include ./schema/openldap.schema include ./schema/nis.schema # -pidfile ./test-repl/p1/slapd.pid -argsfile ./test-repl/p1/slapd.args +pidfile ./testrun/slapd.4.pid +argsfile ./testrun/slapd.4.args modulepath ../servers/slapd/back-@BACKEND@/ @MODULELOAD@ @@ -21,7 +21,7 @@ modulepath ../servers/slapd/back-@BACKEND@/ database @BACKEND@ suffix "o=University of Michigan,c=US" -directory ./test-repl/p1 +directory ./testrun/db.4.a rootdn "cn=Replica,o=University of Michigan,c=US" rootpw secret #ldbm#index objectClass eq @@ -31,7 +31,7 @@ rootpw secret # Don't change syncrepl spec yet syncrepl id=1 - provider=ldap://localhost:9009 + provider=ldap://localhost:9011 updatedn="cn=Replica,o=University of Michigan,c=US" binddn="cn=Manager,o=University of Michigan,c=US" bindmethod=simple diff --git a/tests/data/slapd-syncrepl-slave-persist2.conf b/tests/data/slapd-syncrepl-slave-persist2.conf index 3e36b665b5..6b3ab2376a 100644 --- a/tests/data/slapd-syncrepl-slave-persist2.conf +++ b/tests/data/slapd-syncrepl-slave-persist2.conf @@ -9,8 +9,8 @@ include ./schema/inetorgperson.schema include ./schema/openldap.schema include ./schema/nis.schema # -pidfile ./test-repl/p2/slapd.pid -argsfile ./test-repl/p2/slapd.args +pidfile ./testrun/slapd.5.pid +argsfile ./testrun/slapd.5.args modulepath ../servers/slapd/back-@BACKEND@/ @MODULELOAD@ @@ -21,7 +21,7 @@ modulepath ../servers/slapd/back-@BACKEND@/ database @BACKEND@ suffix "o=University of Michigan,c=US" -directory ./test-repl/p2 +directory ./testrun/db.5.a rootdn "cn=Replica,o=University of Michigan,c=US" rootpw secret #ldbm#index objectClass eq @@ -31,7 +31,7 @@ rootpw secret # Don't change syncrepl spec yet syncrepl id=1 - provider=ldap://localhost:9013 + provider=ldap://localhost:9014 updatedn="cn=Replica,o=University of Michigan,c=US" binddn="cn=Replica,o=University of Michigan,c=US" bindmethod=simple diff --git a/tests/data/slapd-syncrepl-slave-persist3.conf b/tests/data/slapd-syncrepl-slave-persist3.conf index bb3d315b9b..a7901858c1 100644 --- a/tests/data/slapd-syncrepl-slave-persist3.conf +++ b/tests/data/slapd-syncrepl-slave-persist3.conf @@ -9,8 +9,8 @@ include ./schema/inetorgperson.schema include ./schema/openldap.schema include ./schema/nis.schema # -pidfile ./test-repl/p3/slapd.pid -argsfile ./test-repl/p3/slapd.args +pidfile ./testrun/slapd.6.pid +argsfile ./testrun/slapd.6.args modulepath ../servers/slapd/back-@BACKEND@/ @MODULELOAD@ @@ -21,7 +21,7 @@ modulepath ../servers/slapd/back-@BACKEND@/ database @BACKEND@ suffix "o=University of Michigan,c=US" -directory ./test-repl/p3 +directory ./testrun/db.6.a rootdn "cn=Replica,o=University of Michigan,c=US" rootpw secret #ldbm#index objectClass eq @@ -31,7 +31,7 @@ rootpw secret # Don't change syncrepl spec yet syncrepl id=1 - provider=ldap://localhost:9009 + provider=ldap://localhost:9011 updatedn="cn=Replica,o=University of Michigan,c=US" binddn="cn=Manager,o=University of Michigan,c=US" bindmethod=simple diff --git a/tests/data/slapd-syncrepl-slave-refresh1.conf b/tests/data/slapd-syncrepl-slave-refresh1.conf index 5245f1a800..15543497ab 100644 --- a/tests/data/slapd-syncrepl-slave-refresh1.conf +++ b/tests/data/slapd-syncrepl-slave-refresh1.conf @@ -9,8 +9,8 @@ include ./schema/inetorgperson.schema include ./schema/openldap.schema include ./schema/nis.schema # -pidfile ./test-repl/r1/slapd.pid -argsfile ./test-repl/r1/slapd.args +pidfile ./testrun/slapd.2.pid +argsfile ./testrun/slapd.2.args modulepath ../servers/slapd/back-@BACKEND@/ @MODULELOAD@ @@ -21,7 +21,7 @@ modulepath ../servers/slapd/back-@BACKEND@/ database @BACKEND@ suffix "o=University of Michigan,c=US" -directory ./test-repl/r1 +directory ./testrun/db.2.a rootdn "cn=Replica,o=University of Michigan,c=US" rootpw secret #ldbm#index objectClass eq @@ -29,9 +29,11 @@ rootpw secret #bdb#index objectClass eq #bdb#index cn,sn,uid pres,eq,sub +sessionlog 1 100 + # Don't change syncrepl spec yet syncrepl id=1 - provider=ldap://localhost:9009 + provider=ldap://localhost:9011 updatedn="cn=Replica,o=University of Michigan,c=US" binddn="cn=Manager,o=University of Michigan,c=US" bindmethod=simple @@ -42,4 +44,4 @@ syncrepl id=1 schemachecking=off scope=sub type=refreshOnly - interval=00:00:01 + interval=00:00:00:10 diff --git a/tests/data/slapd-syncrepl-slave-refresh2.conf b/tests/data/slapd-syncrepl-slave-refresh2.conf index 5499fcd466..f9271cc2c9 100644 --- a/tests/data/slapd-syncrepl-slave-refresh2.conf +++ b/tests/data/slapd-syncrepl-slave-refresh2.conf @@ -9,8 +9,8 @@ include ./schema/inetorgperson.schema include ./schema/openldap.schema include ./schema/nis.schema # -pidfile ./test-repl/r2/slapd.pid -argsfile ./test-repl/r2/slapd.args +pidfile ./testrun/slapd.3.pid +argsfile ./testrun/slapd.3.args modulepath ../servers/slapd/back-@BACKEND@/ @MODULELOAD@ @@ -21,7 +21,7 @@ modulepath ../servers/slapd/back-@BACKEND@/ database @BACKEND@ suffix "o=University of Michigan,c=US" -directory ./test-repl/r2 +directory ./testrun/db.3.a rootdn "cn=Replica,o=University of Michigan,c=US" rootpw secret #ldbm#index objectClass eq @@ -31,7 +31,7 @@ rootpw secret # Don't change syncrepl spec yet syncrepl id=1 - provider=ldap://localhost:9011 + provider=ldap://localhost:9012 updatedn="cn=Replica,o=University of Michigan,c=US" binddn="cn=Replica,o=University of Michigan,c=US" bindmethod=simple @@ -42,4 +42,4 @@ syncrepl id=1 schemachecking=off scope=sub type=refreshOnly - interval=00:00:01 + interval=00:00:00:10 diff --git a/tests/data/slapd.conf b/tests/data/slapd.conf index 5942610de9..350280aa87 100644 --- a/tests/data/slapd.conf +++ b/tests/data/slapd.conf @@ -9,27 +9,24 @@ include ./schema/cosine.schema include ./schema/inetorgperson.schema include ./schema/openldap.schema include ./schema/nis.schema -pidfile ./test-db/slapd.pid -argsfile ./test-db/slapd.args + +# +pidfile ./testrun/slapd.1.pid +argsfile ./testrun/slapd.1.args modulepath ../servers/slapd/back-@BACKEND@/ @MODULELOAD@ + ####################################################################### -# ldbm database definitions +# database definitions ####################################################################### database @BACKEND@ -suffix "o=University of Michigan, c=US" -directory ./test-db -rootdn "cn=Manager, o=University of Michigan, c=US" +suffix "o=University of Michigan,c=US" +directory ./testrun/db.1.a +rootdn "cn=Manager,o=University of Michigan,c=US" rootpw secret -#ldbm#index objectclass eq -#ldbm#index uid pres,eq,sub -#ldbm#index name pres,eq,sub,subany -#ldbm#dbnosync -#ldbm#dbnolocking -#bdb#index objectclass eq -#bdb#index uid pres,eq,sub -#bdb#index name pres,eq,sub,subany -#bdb#lockdetect default 5 +index objectClass eq +index cn,sn,uid pres,eq,sub + diff --git a/tests/data/slapd2.conf b/tests/data/slapd2.conf new file mode 100644 index 0000000000..1f4c1bbd93 --- /dev/null +++ b/tests/data/slapd2.conf @@ -0,0 +1,31 @@ +# $OpenLDAP$ +# +# stand-alone slapd config -- for testing +# with indexing +# +ucdata-path ./ucdata +include ./schema/core.schema +include ./schema/cosine.schema +include ./schema/inetorgperson.schema +include ./schema/openldap.schema +include ./schema/nis.schema +# +pidfile ./testrun/slapd.2.pid +argsfile ./testrun/slapd.2.args + +modulepath ../servers/slapd/back-@BACKEND@/ +@MODULELOAD@ + + +####################################################################### +# database definitions +####################################################################### + +database @BACKEND@ +suffix "o=University of Michigan,c=US" +directory ./testrun/db.2.a +rootdn "cn=Manager,o=University of Michigan,c=US" +rootpw secret +index objectClass eq +index cn,sn,uid pres,eq,sub + diff --git a/tests/data/test-ordered-nocp.ldif b/tests/data/test-ordered-nocp.ldif index 64171d1df2..b53fec6cd3 100644 --- a/tests/data/test-ordered-nocp.ldif +++ b/tests/data/test-ordered-nocp.ldif @@ -267,11 +267,11 @@ description: All ITD Staff cn: ITD Staff objectclass: groupofuniquenames uniquemember: cn=Manager,o=University of Michigan,c=US -uniquemember: cn=Bjorn Jensen,OU=Information Technology Division,ou=PEOPLE,o=U +uniquemember: cn=Bjorn Jensen,OU=Information Technology Division,ou=PEOPLE,o=U niversity of Michigan,c=US -uniquemember: cn=James A Jones 2,ou=Information Technology Division,ou=PEOPLE, +uniquemember: cn=James A Jones 2,ou=Information Technology Division,ou=PEOPLE, o=University of Michigan,c=US -uniquemember: cn=John Doe,ou=Information Technology Division,ou=People,o=Unive +uniquemember: cn=John Doe,ou=Information Technology Division,ou=People,o=Unive rsity of Michigan,c=US dn: cn=James A Jones 1,ou=Alumni Association,ou=People,o=University of Mich diff --git a/tests/run.in b/tests/run.in new file mode 100644 index 0000000000..246a27a907 --- /dev/null +++ b/tests/run.in @@ -0,0 +1,146 @@ +#!/bin/sh + +USAGE="$0 [-b ] [-c] [-k] [-p] [-u] [-w]