]> git.sur5r.net Git - openldap/commitdiff
Sync with HEAD
authorKurt Zeilenga <kurt@openldap.org>
Mon, 24 Jan 2005 22:28:46 +0000 (22:28 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Mon, 24 Jan 2005 22:28:46 +0000 (22:28 +0000)
88 files changed:
configure
doc/Makefile.in
doc/man/Makefile.in
doc/man/man1/Makefile.in
doc/man/man3/Makefile.in
doc/man/man5/Makefile.in
doc/man/man5/slapd-ldap.5
doc/man/man5/slapd-meta.5
doc/man/man5/slapo-chain.5
doc/man/man5/slapo-rwm.5
doc/man/man8/Makefile.in
include/ldap.h
include/ldif.h
include/rewrite.h
libraries/libldap/open.c
libraries/liblutil/fetch.c
libraries/liblutil/ldif.c
libraries/librewrite/xmap.c
servers/Makefile.in
servers/slapd/add.c
servers/slapd/at.c
servers/slapd/attr.c
servers/slapd/back-bdb/attr.c
servers/slapd/back-bdb/back-bdb.h
servers/slapd/back-bdb/dbcache.c
servers/slapd/back-bdb/dn2id.c
servers/slapd/back-bdb/idl.c
servers/slapd/back-bdb/index.c
servers/slapd/back-bdb/init.c
servers/slapd/back-bdb/proto-bdb.h
servers/slapd/back-bdb/tools.c
servers/slapd/back-ldap/add.c
servers/slapd/back-ldap/back-ldap.h
servers/slapd/back-ldap/bind.c
servers/slapd/back-ldap/chain.c
servers/slapd/back-ldap/compare.c
servers/slapd/back-ldap/config.c
servers/slapd/back-ldap/delete.c
servers/slapd/back-ldap/extended.c
servers/slapd/back-ldap/init.c
servers/slapd/back-ldap/modify.c
servers/slapd/back-ldap/modrdn.c
servers/slapd/back-ldap/proto-ldap.h
servers/slapd/back-ldap/search.c
servers/slapd/back-ldbm/id2entry.c
servers/slapd/back-ldbm/tools.c
servers/slapd/back-meta/add.c
servers/slapd/back-meta/back-meta.h
servers/slapd/back-meta/config.c
servers/slapd/back-meta/map.c
servers/slapd/back-meta/modify.c
servers/slapd/back-null/null.c
servers/slapd/back-sql/back-sql.h
servers/slapd/back-sql/init.c
servers/slapd/back-sql/schema-map.c
servers/slapd/back-sql/search.c
servers/slapd/back-sql/sql-wrap.c
servers/slapd/back-sql/util.c
servers/slapd/backend.c
servers/slapd/bind.c
servers/slapd/compare.c
servers/slapd/daemon.c
servers/slapd/delete.c
servers/slapd/entry.c
servers/slapd/filterentry.c
servers/slapd/modify.c
servers/slapd/modrdn.c
servers/slapd/oc.c
servers/slapd/overlays/rwm.c
servers/slapd/overlays/rwmdn.c
servers/slapd/overlays/rwmmap.c
servers/slapd/proto-slap.h
servers/slapd/saslauthz.c
servers/slapd/schema/README
servers/slapd/search.c
servers/slapd/slap.h
servers/slapd/slapadd.c
servers/slapd/slapcommon.c
tests/data/chain.out
tests/data/chainmod.out
tests/data/chainref.out [new file with mode: 0644]
tests/data/relay.out
tests/data/slapd-relay.conf
tests/data/test-chain1.ldif
tests/data/test-chain2.ldif
tests/scripts/defines.sh
tests/scripts/relay
tests/scripts/test032-chain

index 78fcb210e8fcc6f82716b6cf9efa857236a5725c..ec687c71a55e4a3d39cbd30acda8a6f369e1f20a 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # $OpenLDAP$
-# from OpenLDAP: pkg/ldap/configure.in,v 1.560 2004/12/04 18:48:48 hyc Exp  
+# from OpenLDAP 
 
 # This work is part of OpenLDAP Software <http://www.openldap.org/>.
 #
index cc57b151a76c6f353fb2b26b03fb56a144d84e0f..bdf09732466fcf00e90bef67134f75fdecada0df 100644 (file)
@@ -1,5 +1,7 @@
 ## doc Makefile.in for OpenLDAP
 # $OpenLDAP$
+## This work is part of OpenLDAP Software <http://www.openldap.org/>.
+##
 ## Copyright 1998-2005 The OpenLDAP Foundation.
 ## All rights reserved.
 ##
index cd8110b7280062fa80fcf458600583592ec427bf..659c8d8f3aec0c1e8aaf20783a3f48d05c03797f 100644 (file)
@@ -1,5 +1,7 @@
 # man Makefile.in for OpenLDAP
 # $OpenLDAP$
+## This work is part of OpenLDAP Software <http://www.openldap.org/>.
+##
 ## Copyright 1998-2005 The OpenLDAP Foundation.
 ## All rights reserved.
 ##
index ec72d43eea19ab3132f75730761db55b90b5bded..e962328e4d572e8f3f173ef1294388bf400d1913 100644 (file)
@@ -1,5 +1,7 @@
 # man1 Makefile.in for OpenLDAP
 # $OpenLDAP$
+## This work is part of OpenLDAP Software <http://www.openldap.org/>.
+##
 ## Copyright 1998-2005 The OpenLDAP Foundation.
 ## All rights reserved.
 ##
index af516dc0e25dcc6f57a6ff2ec45f337a8e20f119..06b739e26192c1aa998385378ba8db6017639cdf 100644 (file)
@@ -1,5 +1,7 @@
 # man3 Makefile.in for OpenLDAP
 # $OpenLDAP$
+## This work is part of OpenLDAP Software <http://www.openldap.org/>.
+##
 ## Copyright 1998-2005 The OpenLDAP Foundation.
 ## All rights reserved.
 ##
index f51c6a178bd543575473119a022b93af00dee109..81b2ab6c328d1fdb3cb7ec4753d07c0dd4145530 100644 (file)
@@ -1,5 +1,7 @@
 # man5 Makefile.in for OpenLDAP
 # $OpenLDAP$
+## This work is part of OpenLDAP Software <http://www.openldap.org/>.
+##
 ## Copyright 1998-2005 The OpenLDAP Foundation.
 ## All rights reserved.
 ##
index e345281e53b1568be76dff541dddb919a88363e2..893861c504a4fda15ea6e1b5c563e1cb29ab9240 100644 (file)
@@ -79,8 +79,8 @@ The URI list is space- or comma-separated.
 .TP
 .B acl-authcDN "<administrative DN for access control purposes>"
 DN which is used to query the target server for acl checking; it
-should have read access on the target server to attributes used on the
-proxy for acl checking.
+is supposed to have read access on the target server to attributes used
+on the proxy for acl checking.
 There is no risk of giving away such values; they are only used to
 check permissions.
 .B The acl-authcDN identity is by no means implicitly used by the proxy 
@@ -90,7 +90,10 @@ See the
 feature instead.
 .TP
 .B acl-passwd <password>
-Password used with the bind DN above.
+Password used with the
+.B 
+acl-authcDN
+above.
 .TP
 .B idassert-authcdn "<administrative DN for proxyAuthz purposes>"
 DN which is used to propagate the client's identity to the target
index c063ab22479176a002127858486c240649229402..4b796d3760480e662e5da873f4a43319e0af9663 100644 (file)
@@ -134,17 +134,20 @@ The optional number marks target <target> as the default one, starting
 from 1.
 Target <target> must be defined.
 .TP
-.B binddn "<administrative DN for access control purposes>"
-This directive, as in the LDAP backend, allows to define the DN that is
-used to query the target server for acl checking; it should have read
-access on the target server to attributes used on the proxy for acl
-checking.
+.B acl-authcDN "<administrative DN for access control purposes>"
+DN which is used to query the target server for acl checking,
+as in the LDAP backend; it is supposed to have read access 
+on the target server to attributes used on the proxy for acl checking.
 There is no risk of giving away such values; they are only used to
 check permissions.
-.TP
-.B bindpw <password for access control purposes>
-This directive sets the password for acl checking in conjunction
-with the above mentioned "binddn" directive.
+.B The acl-authcDN identity is by no means implicitly used by the proxy 
+.B when the client connects anonymously.
+.TP
+.B acl-passwd <password>
+Password used with the
+.B 
+acl-authcDN
+above.
 .TP
 .B rebind-as-user
 If this option is given, the client's bind credentials are remembered
index 9f53458f5119f1320682203ba21a8017f6141433..f3ab4c4718ff9a8c0f934d71198b7859f928d190 100644 (file)
@@ -15,11 +15,11 @@ allows automatic referral chasing.
 Any time a referral is returned (except for bind operations),
 it is chased by using an instance of the ldap backend.
 If operations are performed with an identity (i.e. after a bind),
-the referrals are chased with the 
-.B acl-authcDN 
-(if any; see
+that identity can be asserted while chasing the referrals 
+by means of the \fIidentity assertion\fP feature of back-ldap
+(see
 .BR slapd-ldap (5)
-for details), with the original identity asserted by means of the
+for details), which is essentially based on the
 .B proxyAuthz
 control (see \fIdraft-weltman-ldapv3-proxy\fP for details).
 
@@ -28,36 +28,39 @@ The config directives that are specific to the
 .B chain
 overlay can be prefixed by
 .BR chain\- ,
-to avoid conflicts with directives specific to the underlying database
-or to other stacked overlays.
+to avoid potential conflicts with directives specific to the underlying 
+database or to other stacked overlays.
 
 .LP
 There are no chain overlay specific directives; however, directives 
-related to the instance of the ldap backend that is implicitly 
-instantiated by the overlay may assume a special meaning when used 
-in conjuction with this overlay.
+related to the \fIldap\fP database that is implicitly instantiated 
+by the overlay may assume a special meaning when used in conjuction 
+with this overlay.  They are described in
+.BR slapd-ldap (5).
 .TP
 .B overlay chain
 This directive adds the chain overlay to the current backend.
-The chain overlay may be used with any backend but is intended 
-for use with local storage backends that may return referrals.
-It is useless in conjunction with the ldap and meta backends
-because they exploit the libldap specific referral chase feature.
+The chain overlay may be used with any backend, but it is mainly 
+intended for use with local storage backends that may return referrals.
+It is useless in conjunction with the \fIldap\fP and \fImeta\fP backends
+because they already exploit the libldap specific referral chase feature.
 .TP
 .B chain-uri <ldapuri>
 This directive instructs the underlying ldap database about which
-URI to contact to follow referrals.
-If not given, the referral itself is parsed, and the protocol/host/port
+URI to contact to chase referrals.
+If not present, the referral itself is parsed, and the protocol/host/port
 portions are used to establish a connection.
 
 .LP
-Directives for configuring the underlying ldap database must also be given, 
-as shown here:
+Directives for configuring the underlying ldap database may also 
+be required, as shown here:
 .LP
 .RS
 .nf
-chain-acl-authcDN      cn=Auth,dc=example,dc=com
-chain-acl-passwd       secret
+chain-idassert-method  "simple"
+chain-idassert-authcDN "cn=Auth,dc=example,dc=com"
+chain-idassert-passwd  "secret"
+chain-idassert-mode    "self"
 .fi
 .RE
 .LP
index 0fe80aaa7a6568cd410adf1c86ca3437d977ad48..a2a19fde55052308fab53a9c4fe8f359488a98e5 100644 (file)
@@ -188,15 +188,15 @@ n
 as return code if the rule matches; the flag does not alter the recursive
 behavior of the rule, so, to have it performed only once, it must be used 
 in combination with `:', e.g.
-.B `:U{16}'
-returns the value `16' after exactly one execution of the rule, if the
-pattern matches.
+.B `:U{32}'
+returns the value `32' (indicating noSuchObject) after exactly 
+one execution of the rule, if the pattern matches.
 As a consequence, its behavior is equivalent to `@', with the return
 code set to
 .BR n ;
 or, in other words, `@' is equivalent to `U{0}'.
-By convention, the freely available codes are above 16 included;
-the others are reserved.
+Positive errors are allowed, indicating the related LDAP error codes
+as specified in \fIdraft-ietf-ldapbis-protocol\fP.
 .LP
 The ordering of the flags can be significant.
 For instance: `IG{2}' means ignore errors and jump two lines ahead
@@ -400,26 +400,29 @@ rwm-rewriteEngine on
 rwm-rewriteEngine on
 # all dataflow from client to server referring to DNs
 rwm-rewriteContext default
-rwm-rewriteRule "(.*)<virtualnamingcontext>$" "$1<realnamingcontext>" ":"
+rwm-rewriteRule "(.+,)?<virtualnamingcontext>$" "$1<realnamingcontext>" ":"
 # empty filter rule
 rwm-rewriteContext searchFilter
 # all dataflow from server to client
 rwm-rewriteContext searchEntryDN
-rwm-rewriteRule "(.*)<realnamingcontext>$" "$1<virtualnamingcontext>" ":"
+rwm-rewriteRule "(.+,)?<realnamingcontext>$" "$1<virtualnamingcontext>" ":"
 rwm-rewriteContext searchAttrDN alias searchEntryDN
 rwm-rewriteContext matchedDN alias searchEntryDN
+# misc empty rules
+rwm-rewriteContext referralAttrDN
+rwm-rewriteContext referralDN
 
 # Everything defined here goes into the `default' context.
 # This rule changes the naming context of anything sent
 # to `dc=home,dc=net' to `dc=OpenLDAP, dc=org'
 
-rwm-rewriteRule "(.*)dc=home,[ ]?dc=net$"
+rwm-rewriteRule "(.+,)?dc=home,[ ]?dc=net$"
             "$1dc=OpenLDAP, dc=org"  ":"
 
 # since a pretty/normalized DN does not include spaces
 # after rdn separators, e.g. `,', this rule suffices:
 
-rwm-rewriteRule "(.*)dc=home,dc=net$"
+rwm-rewriteRule "(.+,)?dc=home,dc=net$"
             "$1dc=OpenLDAP,dc=org"  ":"
 
 # Start a new context (ends input of the previous one).
index 49c7ac012062b999d740952b1ec1276b278271b3..70d8e1fd22c69ba17e4dc90cb269b39fa79a9963 100644 (file)
@@ -1,5 +1,7 @@
 # man8 Makefile.in for OpenLDAP
 # $OpenLDAP$
+## This work is part of OpenLDAP Software <http://www.openldap.org/>.
+##
 ## Copyright 1998-2005 The OpenLDAP Foundation.
 ## All rights reserved.
 ##
index daccf104ec93f61a2556ee2256cda400ca0951cf..b06dd612c3fda8a3e04e1f79772e64d80cec4d68 100644 (file)
@@ -234,10 +234,9 @@ typedef struct ldapcontrol {
 #define LDAP_CONTROL_VLVRESPONSE    "2.16.840.1.113730.3.4.10"
 
 /* Password policy Controls *//* work in progress */
-#ifdef LDAP_DEVEL
+/* ITS#3458: released, but not to latest draft; disabled by default */
 #define LDAP_CONTROL_PASSWORDPOLICYREQUEST     "1.3.6.1.4.1.42.2.27.8.5.1"
 #define LDAP_CONTROL_PASSWORDPOLICYRESPONSE    "1.3.6.1.4.1.42.2.27.8.5.1"
-#endif
 
 /* LDAP Sync -- draft-zeilenga-ldup-sync *//* submitted for publication */
 #define LDAP_SYNC_OID                  "1.3.6.1.4.1.4203.1.9.1"
index 88c062217ea8bd58af52dfa6f330f7e2030fbbb0..fec4b65ae910cb8ce79087660f420316fd0124e3 100644 (file)
@@ -75,6 +75,9 @@ ldif_fetch_url LDAP_P((
 LDAP_LDIF_F( char * )
 ldif_getline LDAP_P(( char **next ));
 
+LDAP_LDIF_F( int )
+ldif_countlines LDAP_P(( LDAP_CONST char *line ));
+
 LDAP_LDIF_F( int )
 ldif_read_record LDAP_P((
        FILE *fp,
index ccf359c297ee09c33e6c4e586a506b850e8a428c..155f5044524ba08a642d9f920371e1204ba61c18 100644 (file)
@@ -38,8 +38,7 @@
  * Rewrite internal status returns
  */
 #define REWRITE_SUCCESS                        LDAP_SUCCESS
-#define REWRITE_ERR                    LDAP_OPERATIONS_ERROR
-#define REWRITE_NO_SUCH_OBJECT         LDAP_NO_SUCH_OBJECT
+#define REWRITE_ERR                    LDAP_OTHER
 
 /*
  * Rewrite modes (input values for rewrite_info_init); determine the
  *     REWRITE_REGEXEC_UNWILLING       the server should issue an 'unwilling
  *                                     to perform' error
  */
-#define REWRITE_REGEXEC_OK              0x0000
-#define REWRITE_REGEXEC_ERR             0x0001
-#define REWRITE_REGEXEC_STOP            0x0002
-#define REWRITE_REGEXEC_UNWILLING       0x0003
-#define REWRITE_REGEXEC_USER           0x0004 /* and above ... */
+#define REWRITE_REGEXEC_OK              (0)
+#define REWRITE_REGEXEC_ERR             (-1)
+#define REWRITE_REGEXEC_STOP            (-2)
+#define REWRITE_REGEXEC_UNWILLING       (-3)
+#define REWRITE_REGEXEC_USER           (1)     /* and above: LDAP errors */
 
 /*
  * Rewrite variable flags
index e5243c869d934c866be0b76b4908efabe5ad2f24..407c1a3f99e8b15984288e146c7b6a069141e9fd 100644 (file)
@@ -119,6 +119,9 @@ ldap_create( LDAP **ldp )
        /* but not pointers to malloc'ed items */
        ld->ld_options.ldo_sctrls = NULL;
        ld->ld_options.ldo_cctrls = NULL;
+       ld->ld_options.ldo_tm_api = NULL;
+       ld->ld_options.ldo_tm_net = NULL;
+       ld->ld_options.ldo_defludp = NULL;
 
 #ifdef HAVE_CYRUS_SASL
        ld->ld_options.ldo_def_sasl_mech = gopts->ldo_def_sasl_mech
@@ -131,27 +134,26 @@ ldap_create( LDAP **ldp )
                ? LDAP_STRDUP( gopts->ldo_def_sasl_authzid ) : NULL;
 #endif
 
-       ld->ld_options.ldo_defludp = ldap_url_duplist(gopts->ldo_defludp);
+       if ( gopts->ldo_tm_api &&
+               ldap_int_timeval_dup( &ld->ld_options.ldo_tm_api, gopts->ldo_tm_api ))
+               goto nomem;
 
-       if ( ld->ld_options.ldo_defludp == NULL ) {
-               LDAP_FREE( (char*)ld );
-               return LDAP_NO_MEMORY;
-       }
+       if ( gopts->ldo_tm_net &&
+               ldap_int_timeval_dup( &ld->ld_options.ldo_tm_net, gopts->ldo_tm_net ))
+               goto nomem;
 
-       if (( ld->ld_selectinfo = ldap_new_select_info()) == NULL ) {
-               ldap_free_urllist( ld->ld_options.ldo_defludp );
-               LDAP_FREE( (char*) ld );
-               return LDAP_NO_MEMORY;
+       if ( gopts->ldo_defludp ) {
+               ld->ld_options.ldo_defludp = ldap_url_duplist(gopts->ldo_defludp);
+
+               if ( ld->ld_options.ldo_defludp == NULL ) goto nomem;
        }
 
+       if (( ld->ld_selectinfo = ldap_new_select_info()) == NULL ) goto nomem;
+
        ld->ld_lberoptions = LBER_USE_DER;
 
        ld->ld_sb = ber_sockbuf_alloc( );
-       if ( ld->ld_sb == NULL ) {
-               ldap_free_urllist( ld->ld_options.ldo_defludp );
-               LDAP_FREE( (char*) ld );
-               return LDAP_NO_MEMORY;
-       }
+       if ( ld->ld_sb == NULL ) goto nomem;
 
 #ifdef LDAP_R_COMPILE
        ldap_pvt_thread_mutex_init( &ld->ld_req_mutex );
@@ -159,6 +161,20 @@ ldap_create( LDAP **ldp )
 #endif
        *ldp = ld;
        return LDAP_SUCCESS;
+
+nomem:
+       ldap_free_select_info( ld->ld_selectinfo );
+       ldap_free_urllist( ld->ld_options.ldo_defludp );
+       LDAP_FREE( ld->ld_options.ldo_tm_net );
+       LDAP_FREE( ld->ld_options.ldo_tm_api );
+#ifdef HAVE_CYRUS_SASL
+       LDAP_FREE( ld->ld_options.ldo_def_sasl_authzid );
+       LDAP_FREE( ld->ld_options.ldo_def_sasl_authcid );
+       LDAP_FREE( ld->ld_options.ldo_def_sasl_realm );
+       LDAP_FREE( ld->ld_options.ldo_def_sasl_mech );
+#endif
+       LDAP_FREE( (char *)ld );
+       return LDAP_NO_MEMORY;
 }
 
 /*
index 0a0ef8524924698f85be7ace6b9139cdf3d793ee..49a72c6e4ca4b0a9c3c5aff53b6098408d829cc9 100644 (file)
@@ -1,6 +1,5 @@
 /* fetch.c - routines for fetching data at URLs */
 /* $OpenLDAP$ */
-/* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
  * Copyright 1999-2005 The OpenLDAP Foundation.
index 79f11406113fe8ce6984b445bfff5a368542d071..e0412b2ae903be75121a7a7deed3ee4d413065bf 100644 (file)
@@ -308,6 +308,21 @@ ldif_parse_line2(
  * which it updates and must be supplied on subsequent calls.
  */
 
+int
+ldif_countlines( LDAP_CONST char *buf )
+{
+       char *nl;
+       int ret = 0;
+
+       if ( !buf ) return ret;
+
+       for ( nl = strchr(buf, '\n'); nl; nl = strchr(nl, '\n') ) {
+               nl++;
+               if ( *nl != ' ' ) ret++;
+       }
+       return ret;
+}
+
 char *
 ldif_getline( char **next )
 {
index 0448c8ee964a5bf3c901e72b6358df8cb3ac03fc..ca6e6819be29a98e22ead559084437e5ec81ec5e 100644 (file)
@@ -259,7 +259,7 @@ rewrite_xmap_apply(
                        ldap_pvt_thread_mutex_unlock( &xpasswd_mutex );
 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
 
-                       rc = REWRITE_NO_SUCH_OBJECT;
+                       rc = LDAP_NO_SUCH_OBJECT;
                        break;
                }
 
index f8616acfb2b10e6c10b9279d8c86fa3ebc7a3622..fa3071f75e4f64e6d941235af5c4e04bc9438d28 100644 (file)
@@ -1,5 +1,7 @@
 # servers Makefile.in for OpenLDAP
 # $OpenLDAP$
+## This work is part of OpenLDAP Software <http://www.openldap.org/>.
+##
 ## Copyright 1998-2005 The OpenLDAP Foundation.
 ## All rights reserved.
 ##
index 204caa0380237e391c63363ec61d7298468ab519..92f6759aea4780fd17e2f8be50c7ea0757c758b0 100644 (file)
@@ -220,14 +220,18 @@ fe_op_add( Operation *op, SlapReply *rs )
                if ( !rs->sr_ref ) rs->sr_ref = default_referral;
                if ( rs->sr_ref ) {
                        rs->sr_err = LDAP_REFERRAL;
+                       op->o_bd = frontendDB;
                        send_ldap_result( op, rs );
+                       op->o_bd = NULL;
 
                        if ( rs->sr_ref != default_referral ) {
                                ber_bvarray_free( rs->sr_ref );
                        }
                } else {
+                       op->o_bd = frontendDB;
                        send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
                                "no global superior knowledge" );
+                       op->o_bd = NULL;
                }
                goto done;
        }
index 58c40006bd468bfde683978ad7f2e59499618359..7958a1ec3987b154c4916f71742ddcd80ab56656 100644 (file)
@@ -57,9 +57,12 @@ struct aindexrec {
 };
 
 static Avlnode *attr_index = NULL;
+static Avlnode *attr_cache = NULL;
 static LDAP_SLIST_HEAD(ATList, slap_attribute_type) attr_list
        = LDAP_SLIST_HEAD_INITIALIZER(&attr_list);
 
+int at_oc_cache;
+
 static int
 attr_index_cmp(
     const void *v_air1,
@@ -100,8 +103,18 @@ at_bvfind( struct berval *name )
 {
        struct aindexrec *air;
 
+       if ( attr_cache ) {
+               air = avl_find( attr_cache, name, attr_index_name_cmp );
+               if ( air ) return air->air_at;
+       }
+
        air = avl_find( attr_index, name, attr_index_name_cmp );
 
+       if ( air && ( slapMode & SLAP_TOOL_MODE ) && at_oc_cache ) {
+               avl_insert( &attr_cache, (caddr_t) air,
+                       attr_index_cmp, avl_dup_error );
+       }
+
        return air != NULL ? air->air_at : NULL;
 }
 
index 8908a65da90cc9a986a329e442740e9d3b90a8da..ee0f46daabc5d87fc631f06bb2c5f13295a6d49c 100644 (file)
@@ -177,7 +177,7 @@ attr_merge(
        Attribute       **a;
 
        for ( a = &e->e_attrs; *a != NULL; a = &(*a)->a_next ) {
-               if ( ad_cmp( (*a)->a_desc, desc ) == 0 ) {
+               if (  (*a)->a_desc == desc ) {
                        break;
                }
        }
@@ -261,7 +261,7 @@ attr_merge_one(
        Attribute       **a;
 
        for ( a = &e->e_attrs; *a != NULL; a = &(*a)->a_next ) {
-               if ( ad_cmp( (*a)->a_desc, desc ) == 0 ) {
+               if ( (*a)->a_desc == desc ) {
                        break;
                }
        }
@@ -353,7 +353,7 @@ attr_find(
        AttributeDescription *desc )
 {
        for ( ; a != NULL; a = a->a_next ) {
-               if ( ad_cmp( a->a_desc, desc ) == 0 ) {
+               if ( a->a_desc == desc ) {
                        return( a );
                }
        }
@@ -376,7 +376,7 @@ attr_delete(
        Attribute       **a;
 
        for ( a = attrs; *a != NULL; a = &(*a)->a_next ) {
-               if ( ad_cmp( (*a)->a_desc, desc ) == 0 ) {
+               if ( (*a)->a_desc == desc ) {
                        Attribute       *save = *a;
                        *a = (*a)->a_next;
                        attr_free( save );
index 73c35c86c2078cce61b68f50d253d1dd1aac6828..70a20ea9c1caecd877e21117168e1c24327e725f 100644 (file)
@@ -67,6 +67,24 @@ bdb_attr_comp_ref(
        
        *cr = a != NULL ? a->ai_cr : 0 ;
 }
+void
+bdb_attr_mask_cr(
+       struct bdb_info *bdb,
+       AttributeDescription *desc,
+       slap_mask_t *indexmask,
+       ComponentReference** cr )
+{
+       AttrInfo        *a;
+
+       a = (AttrInfo *) avl_find( bdb->bi_attrs, desc, ainfo_type_cmp );
+       if ( a ) {
+               *indexmask = a->ai_indexmask;
+               *cr = a->ai_cr;
+       } else {
+               *indexmask = NULL;
+               *cr = NULL;
+       }
+}
 #endif
 
 void
index d788665c3c044442d6eb556d4f986f522b306065..44517010fbf96dc4a03df63506efe0e59928b83e 100644 (file)
@@ -241,7 +241,7 @@ struct bdb_op_info {
 #if DB_VERSION_FULL >= 0x04010011
 #undef DB_OPEN
 #define        DB_OPEN(db, file, name, type, flags, mode) \
-       (db)->open(db, NULL, file, name, type, (flags)|DB_AUTO_COMMIT, mode)
+       (db)->open(db, NULL, file, name, type, flags, mode)
 #endif
 
 #endif
index adcdf463a7790cfcfca3a30b57250406edc18244..3885b4c09a0e828db6ffc86cd776deacec7e95b5 100644 (file)
@@ -63,7 +63,7 @@ bdb_db_cache(
        const char *name,
        DB **dbout )
 {
-       int i;
+       int i, flags;
        int rc;
        struct bdb_info *bdb = (struct bdb_info *) be->be_private;
        struct bdb_db_info *db;
@@ -118,11 +118,15 @@ bdb_db_cache(
 
 #ifdef HAVE_EBCDIC
        __atoe( file );
+#endif
+       flags = DB_CREATE | DB_THREAD;
+#ifdef DB_AUTO_COMMIT
+       if ( !( slapMode & SLAP_TOOL_QUICK ))
+               flags |= DB_AUTO_COMMIT;
 #endif
        rc = DB_OPEN( db->bdi_db,
                file, NULL /* name */,
-               BDB_INDEXTYPE, bdb->bi_db_opflags | DB_CREATE | DB_THREAD,
-               bdb->bi_dbenv_mode );
+               BDB_INDEXTYPE, bdb->bi_db_opflags | flags, bdb->bi_dbenv_mode );
 
        ch_free( file );
 
index b157ad23a9245f40b15eff0d8005893ef342181b..b1eee39761040af88865352a4d0461cf10a9a1e7 100644 (file)
@@ -577,7 +577,7 @@ hdb_dn2id_delete(
        data.data = d;
 
        /* Delete our ID from the parent's list */
-       rc = cursor->c_get( cursor, &key, &data, DB_GET_BOTH_RANGE | DB_RMW );
+       rc = cursor->c_get( cursor, &key, &data, DB_GET_BOTH_RANGE );
        if ( rc == 0 ) {
                if ( !strcmp( d->nrdn, BEI(e)->bei_nrdn.bv_val ))
                        rc = cursor->c_del( cursor, 0 );
@@ -591,7 +591,7 @@ hdb_dn2id_delete(
         */
        if ( rc == 0 ) {
                BDB_ID2DISK( e->e_id, &nid );
-               rc = cursor->c_get( cursor, &key, &data, DB_SET | DB_RMW );
+               rc = cursor->c_get( cursor, &key, &data, DB_SET );
                if ( rc == 0 )
                        rc = cursor->c_del( cursor, 0 );
        }
index 186ad24b3cd6bc8eb1dcc60b697b91993b0a391b..29a337218d3baa4facd6bbdd1bba9186caafe58c 100644 (file)
@@ -482,8 +482,6 @@ bdb_idl_fetch_key(
        data.ulen = sizeof(buf);
        data.flags = DB_DBT_USERMEM;
 
-       if ( tid ) flags |= DB_RMW;
-
        /* If we're not reusing an existing cursor, get a new one */
        if( opflag != DB_NEXT ) {
                rc = db->cursor( db, tid, &cursor, bdb->bi_db_opflags );
@@ -646,7 +644,7 @@ bdb_idl_insert_key(
        /* Fetch the first data item for this key, to see if it
         * exists and if it's a range.
         */
-       rc = cursor->c_get( cursor, key, &data, DB_SET | DB_RMW );
+       rc = cursor->c_get( cursor, key, &data, DB_SET );
        err = "c_get";
        if ( rc == 0 ) {
                if ( nlo != 0 ) {
@@ -690,42 +688,30 @@ bdb_idl_insert_key(
                                /* Update hi/lo if needed, then delete all the items
                                 * between lo and hi
                                 */
-                               data.data = &nid;
-                               if ( id > hi ) {
-                                       rc = cursor->c_del( cursor, 0 );
-                                       if ( rc != 0 ) {
-                                               err = "c_del hi";
-                                               goto fail;
-                                       }
-                                       rc = cursor->c_put( cursor, key, &data, DB_KEYLAST );
-                                       if ( rc != 0 ) {
-                                               err = "c_put hi";
-                                               goto fail;
-                                       }
+                               if ( id < lo ) {
+                                       lo = id;
+                                       nlo = nid;
+                               } else if ( id > hi ) {
+                                       hi = id;
+                                       nhi = nid;
                                }
+                               data.data = &nid;
                                /* Don't fetch anything, just position cursor */
                                data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL;
                                data.dlen = data.ulen = 0;
-                               rc = cursor->c_get( cursor, key, &data, DB_SET | DB_RMW );
+                               rc = cursor->c_get( cursor, key, &data, DB_SET );
                                if ( rc != 0 ) {
                                        err = "c_get 2";
                                        goto fail;
                                }
-                               if ( id < lo ) {
-                                       rc = cursor->c_del( cursor, 0 );
-                                       if ( rc != 0 ) {
-                                               err = "c_del lo";
-                                               goto fail;
-                                       }
-                                       rc = cursor->c_put( cursor, key, &data, DB_KEYFIRST );
-                                       if ( rc != 0 ) {
-                                               err = "c_put lo";
-                                               goto fail;
-                                       }
+                               rc = cursor->c_del( cursor, 0 );
+                               if ( rc != 0 ) {
+                                       err = "c_del range1";
+                                       goto fail;
                                }
-                               /* Delete all the records between lo and hi */
-                               for ( i=2; i<count; i++ ) {
-                                       rc = cursor->c_get( cursor, &key2, &data, DB_NEXT_DUP | DB_RMW );
+                               /* Delete all the records */
+                               for ( i=1; i<count; i++ ) {
+                                       rc = cursor->c_get( cursor, &key2, &data, DB_NEXT_DUP );
                                        if ( rc != 0 ) {
                                                err = "c_get next_dup";
                                                goto fail;
@@ -745,6 +731,18 @@ bdb_idl_insert_key(
                                        err = "c_put range";
                                        goto fail;
                                }
+                               nid = nlo;
+                               rc = cursor->c_put( cursor, key, &data, DB_KEYLAST );
+                               if ( rc != 0 ) {
+                                       err = "c_put lo";
+                                       goto fail;
+                               }
+                               nid = nhi;
+                               rc = cursor->c_put( cursor, key, &data, DB_KEYLAST );
+                               if ( rc != 0 ) {
+                                       err = "c_put hi";
+                                       goto fail;
+                               }
                        } else {
                        /* There's room, just store it */
                                goto put1;
@@ -854,7 +852,7 @@ bdb_idl_delete_key(
        /* Fetch the first data item for this key, to see if it
         * exists and if it's a range.
         */
-       rc = cursor->c_get( cursor, key, &data, DB_SET | DB_RMW );
+       rc = cursor->c_get( cursor, key, &data, DB_SET );
        err = "c_get";
        if ( rc == 0 ) {
                if ( tmp != 0 ) {
@@ -862,8 +860,7 @@ bdb_idl_delete_key(
                        if (tmp != nid) {
                                /* position to correct item */
                                tmp = nid;
-                               rc = cursor->c_get( cursor, key, &data, 
-                                       DB_GET_BOTH | DB_RMW  );
+                               rc = cursor->c_get( cursor, key, &data, DB_GET_BOTH );
                                if ( rc != 0 ) {
                                        err = "c_get id";
                                        goto fail;
index 6f101275be1381fe06946781603b3d11727facc2..3e725c880039a8103b325c824bda75489828842d 100644 (file)
@@ -283,20 +283,21 @@ static int index_at_values(
                if( rc ) return rc;
        }
 
-#ifdef LDAP_COMP_MATCH
-       /* component indexing */
-       bdb_attr_comp_ref ( op->o_bd->be_private, type->sat_ad, &cr_list );
-       if ( cr_list ) {
-               for( cr = cr_list ; cr ; cr = cr->cr_next ) {
-                       rc = indexer( op, txn, cr->cr_ad, &type->sat_cname,
-                               cr->cr_nvals, id, opid,
-                               cr->cr_indexmask );
-               }
-       }
-#endif
        /* If this type has no AD, we've never used it before */
        if( type->sat_ad ) {
+#ifdef LDAP_COMP_MATCH
+               /* component indexing */
+               bdb_attr_mask_cr( op->o_bd->be_private, type->sat_ad, &mask, &cr_list );
+               if ( cr_list ) {
+                       for( cr = cr_list ; cr ; cr = cr->cr_next ) {
+                               rc = indexer( op, txn, cr->cr_ad, &type->sat_cname,
+                                       cr->cr_nvals, id, opid,
+                                       cr->cr_indexmask );
+                       }
+               }
+#else
                bdb_attr_mask( op->o_bd->be_private, type->sat_ad, &mask );
+#endif
                ad = type->sat_ad;
        }
 
index 188464e42affe255161a26b5f555bf5a97b38b3f..53e036a6de1303cfa6d6a0e74fb43530d76d3413 100644 (file)
@@ -138,8 +138,10 @@ bdb_db_open( BackendDB *be )
                return rc;
        }
 
-       flags = DB_INIT_MPOOL | DB_THREAD | DB_CREATE
-               | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_TXN;
+       flags = DB_INIT_MPOOL | DB_THREAD | DB_CREATE;
+
+if ( !( slapMode & SLAP_TOOL_QUICK ))
+               flags |= DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_TXN;
        
 #if 0
        /* Never do automatic recovery, must perform it manually.
@@ -273,6 +275,11 @@ bdb_db_open( BackendDB *be )
 
        flags = DB_THREAD | bdb->bi_db_opflags;
 
+#ifdef DB_AUTO_COMMIT
+       if ( !( slapMode & SLAP_TOOL_QUICK ))
+               flags |= DB_AUTO_COMMIT;
+#endif
+
        bdb->bi_databases = (struct bdb_db_info **) ch_malloc(
                BDB_INDICES * sizeof(struct bdb_db_info *) );
 
@@ -364,7 +371,9 @@ bdb_db_open( BackendDB *be )
                return rc;
        }
 
-       XLOCK_ID(bdb->bi_dbenv, &bdb->bi_cache.c_locker);
+       if ( !( slapMode & SLAP_TOOL_QUICK )) {
+               XLOCK_ID(bdb->bi_dbenv, &bdb->bi_cache.c_locker);
+       }
 
        /* If we're in server mode and time-based checkpointing is enabled,
         * submit a task to perform periodic checkpoints.
@@ -417,7 +426,9 @@ bdb_db_close( BackendDB *be )
                ldap_pvt_thread_rdwr_wunlock ( &bdb->bi_idl_tree_rwlock );
        }
 
-       XLOCK_ID_FREE(bdb->bi_dbenv, bdb->bi_cache.c_locker);
+       if ( !( slapMode & SLAP_TOOL_QUICK )) {
+               XLOCK_ID_FREE(bdb->bi_dbenv, bdb->bi_cache.c_locker);
+       }
 
        return 0;
 }
@@ -434,11 +445,13 @@ bdb_db_destroy( BackendDB *be )
        /* close db environment */
        if( bdb->bi_dbenv ) {
                /* force a checkpoint */
-               rc = TXN_CHECKPOINT( bdb->bi_dbenv, 0, 0, DB_FORCE );
-               if( rc != 0 ) {
-                       Debug( LDAP_DEBUG_ANY,
-                               "bdb_db_destroy: txn_checkpoint failed: %s (%d)\n",
-                               db_strerror(rc), rc, 0 );
+               if ( !( slapMode & SLAP_TOOL_QUICK )) {
+                       rc = TXN_CHECKPOINT( bdb->bi_dbenv, 0, 0, DB_FORCE );
+                       if( rc != 0 ) {
+                               Debug( LDAP_DEBUG_ANY,
+                                       "bdb_db_destroy: txn_checkpoint failed: %s (%d)\n",
+                                       db_strerror(rc), rc, 0 );
+                       }
                }
 
                rc = bdb->bi_dbenv->close( bdb->bi_dbenv, 0 );
index c770b3fc4221d811c1cacc3f8ea8541fce4b7923..48f41659d1cdf44245180bdb56b6434b3fb229a2 100644 (file)
@@ -36,9 +36,14 @@ LDAP_BEGIN_DECL
 
 #ifdef LDAP_COMP_MATCH
 #define bdb_attr_comp_ref                      BDB_SYMBOL(attr_comp_ref)
+#define bdb_attr_mask_cr                       BDB_SYMBOL(attr_mask_cr)
 void bdb_attr_comp_ref( struct bdb_info *bdb,
        AttributeDescription *desc,
        ComponentReference **cr );
+void bdb_attr_mask_cr( struct bdb_info *bdb,
+       AttributeDescription *desc,
+       slap_mask_t *indexmask,
+       ComponentReference **cr );
 #endif
 
 void bdb_attr_mask( struct bdb_info *bdb,
index f65d4b99d4b96edba4797c13104c88e24e0a8fc8..ec38daa6cd17481e767d38f721ef4b5bd3f062b0 100644 (file)
@@ -307,6 +307,7 @@ ID bdb_tool_entry_put(
        Debug( LDAP_DEBUG_TRACE, "=> " LDAP_XSTRING(bdb_tool_entry_put)
                "( %ld, \"%s\" )\n", (long) e->e_id, e->e_dn, 0 );
 
+       if (! (slapMode & SLAP_TOOL_QUICK)) {
        rc = TXN_BEGIN( bdb->bi_dbenv, NULL, &tid, 
                bdb->bi_db_opflags );
        if( rc != 0 ) {
@@ -318,6 +319,7 @@ ID bdb_tool_entry_put(
                         text->bv_val, 0, 0 );
                return NOID;
        }
+       }
 
        op.o_hdr = &ohdr;
        op.o_bd = be;
@@ -356,6 +358,7 @@ ID bdb_tool_entry_put(
 
 done:
        if( rc == 0 ) {
+               if ( !( slapMode & SLAP_TOOL_QUICK )) {
                rc = TXN_COMMIT( tid, 0 );
                if( rc != 0 ) {
                        snprintf( text->bv_val, text->bv_len,
@@ -366,8 +369,10 @@ done:
                                text->bv_val, 0, 0 );
                        e->e_id = NOID;
                }
+               }
 
        } else {
+               if ( !( slapMode & SLAP_TOOL_QUICK )) {
                TXN_ABORT( tid );
                snprintf( text->bv_val, text->bv_len,
                        "txn_aborted! %s (%d)",
@@ -375,6 +380,7 @@ done:
                Debug( LDAP_DEBUG_ANY,
                        "=> " LDAP_XSTRING(bdb_tool_entry_put) ": %s\n",
                        text->bv_val, 0, 0 );
+               }
                e->e_id = NOID;
        }
 
@@ -420,6 +426,7 @@ int bdb_tool_entry_reindex(
                return -1;
        }
 
+       if (! (slapMode & SLAP_TOOL_QUICK)) {
        rc = TXN_BEGIN( bi->bi_dbenv, NULL, &tid, bi->bi_db_opflags );
        if( rc != 0 ) {
                Debug( LDAP_DEBUG_ANY,
@@ -428,6 +435,7 @@ int bdb_tool_entry_reindex(
                        db_strerror(rc), rc, 0 );
                goto done;
        }
+       }
        
        /*
         * just (re)add them for now
@@ -445,22 +453,11 @@ int bdb_tool_entry_reindex(
        op.o_tmpmemctx = NULL;
        op.o_tmpmfuncs = &ch_mfuncs;
 
-#if 0 /* ndef BDB_HIER */
-       /* add dn2id indices */
-       rc = bdb_dn2id_add( &op, tid, NULL, e );
-       if( rc != 0 && rc != DB_KEYEXIST ) {
-               Debug( LDAP_DEBUG_ANY,
-                       "=> " LDAP_XSTRING(bdb_tool_entry_reindex)
-                       ": dn2id_add failed: %s (%d)\n",
-                       db_strerror(rc), rc, 0 );
-               goto done;
-       }
-#endif
-
        rc = bdb_index_entry_add( &op, tid, e );
 
 done:
        if( rc == 0 ) {
+               if (! (slapMode & SLAP_TOOL_QUICK)) {
                rc = TXN_COMMIT( tid, 0 );
                if( rc != 0 ) {
                        Debug( LDAP_DEBUG_ANY,
@@ -469,13 +466,16 @@ done:
                                db_strerror(rc), rc, 0 );
                        e->e_id = NOID;
                }
+               }
 
        } else {
+               if (! (slapMode & SLAP_TOOL_QUICK)) {
                TXN_ABORT( tid );
                Debug( LDAP_DEBUG_ANY,
                        "=> " LDAP_XSTRING(bdb_tool_entry_reindex)
                        ": txn_aborted! %s (%d)\n",
                        db_strerror(rc), rc, 0 );
+               }
                e->e_id = NOID;
        }
        bdb_entry_release( &op, e, 0 );
@@ -508,6 +508,7 @@ ID bdb_tool_entry_modify(
                "=> " LDAP_XSTRING(bdb_tool_entry_modify) "( %ld, \"%s\" )\n",
                (long) e->e_id, e->e_dn, 0 );
 
+       if (! (slapMode & SLAP_TOOL_QUICK)) {
        rc = TXN_BEGIN( bdb->bi_dbenv, NULL, &tid, 
                bdb->bi_db_opflags );
        if( rc != 0 ) {
@@ -519,6 +520,7 @@ ID bdb_tool_entry_modify(
                         text->bv_val, 0, 0 );
                return NOID;
        }
+       }
 
        op.o_hdr = &ohdr;
        op.o_bd = be;
@@ -561,6 +563,7 @@ ID bdb_tool_entry_modify(
 
 done:
        if( rc == 0 ) {
+               if (! (slapMode & SLAP_TOOL_QUICK)) {
                rc = TXN_COMMIT( tid, 0 );
                if( rc != 0 ) {
                        snprintf( text->bv_val, text->bv_len,
@@ -571,8 +574,10 @@ done:
                                "%s\n", text->bv_val, 0, 0 );
                        e->e_id = NOID;
                }
+               }
 
        } else {
+               if (! (slapMode & SLAP_TOOL_QUICK)) {
                TXN_ABORT( tid );
                snprintf( text->bv_val, text->bv_len,
                        "txn_aborted! %s (%d)",
@@ -580,6 +585,7 @@ done:
                Debug( LDAP_DEBUG_ANY,
                        "=> " LDAP_XSTRING(bdb_tool_entry_modify) ": %s\n",
                        text->bv_val, 0, 0 );
+               }
                e->e_id = NOID;
        }
 
index 1805a31b3e40429cca9ab5160bf4acb849ec7e62..eb272c76628fa067c9f8f489fc96d056725be588 100644 (file)
@@ -46,14 +46,14 @@ ldap_back_add(
        int             isupdate;
        int             do_retry = 1;
        LDAPControl     **ctrls = NULL;
-       int             rc = LDAP_SUCCESS;
 
+       rs->sr_err = LDAP_SUCCESS;
+       
        Debug( LDAP_DEBUG_ARGS, "==> ldap_back_add(\"%s\")\n",
                        op->o_req_dn.bv_val, 0, 0 );
 
-       lc = ldap_back_getconn( op, rs );
-       if ( !lc || !ldap_back_dobind( lc, op, rs ) ) {
-               rc = -1;
+       lc = ldap_back_getconn( op, rs, LDAP_BACK_SENDERR );
+       if ( !lc || !ldap_back_dobind( lc, op, rs, LDAP_BACK_SENDERR ) ) {
                goto cleanup;
        }
 
@@ -89,20 +89,19 @@ ldap_back_add(
        attrs[ i ] = NULL;
 
        ctrls = op->o_ctrls;
-       rc = ldap_back_proxy_authz_ctrl( lc, op, rs, &ctrls );
-       if ( rc != LDAP_SUCCESS ) {
+       rs->sr_err = ldap_back_proxy_authz_ctrl( lc, op, rs, &ctrls );
+       if ( rs->sr_err != LDAP_SUCCESS ) {
                send_ldap_result( op, rs );
-               rc = -1;
                goto cleanup;
        }
 
 retry:
        rs->sr_err = ldap_add_ext( lc->lc_ld, op->o_req_dn.bv_val, attrs,
                        ctrls, NULL, &msgid );
-       rc = ldap_back_op_result( lc, op, rs, msgid, 1 );
+       rs->sr_err = ldap_back_op_result( lc, op, rs, msgid, LDAP_BACK_SENDRESULT );
        if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
                do_retry = 0;
-               if ( ldap_back_retry( lc, op, rs ) ) {
+               if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) {
                        goto retry;
                }
        }
@@ -118,8 +117,8 @@ cleanup:
        }
 
        Debug( LDAP_DEBUG_ARGS, "<== ldap_back_add(\"%s\"): %d\n",
-                       op->o_req_dn.bv_val, rc, 0 );
+                       op->o_req_dn.bv_val, rs->sr_err, 0 );
 
-       return rc;
+       return rs->sr_err;
 }
 
index 3f5b109d371bf53fdbb2d79ff7e0b88ce733586f..174a7039c580685be77921ebb4e0ed18345279d9 100644 (file)
@@ -90,12 +90,23 @@ struct ldapinfo {
        /* end of ID assert stuff */
 
        ldap_pvt_thread_mutex_t         conn_mutex;
-       int             savecred;
+       unsigned        flags;
+#define LDAP_BACK_F_NONE               0x00U
+#define LDAP_BACK_F_SAVECRED           0x01U
+#define LDAP_BACK_F_USE_TLS            0x02U
+#define LDAP_BACK_F_TLS_CRITICAL       ( 0x04U | LDAP_BACK_F_USE_TLS )
        Avlnode         *conntree;
 
        int             rwm_started;
 };
 
+typedef enum ldap_back_send_t {
+       LDAP_BACK_DONTSEND              = 0x00,
+       LDAP_BACK_SENDOK                = 0x01,
+       LDAP_BACK_SENDERR               = 0x02,
+       LDAP_BACK_SENDRESULT            = (LDAP_BACK_SENDOK|LDAP_BACK_SENDERR)
+} ldap_back_send_t;
+
 LDAP_END_DECL
 
 #include "proto-ldap.h"
index f7446f35c9c4250ac25720ee81de3bdf16f77bc7..998ce2453789f33bb4b960e32f5a94c81dd56d24 100644 (file)
@@ -16,7 +16,7 @@
  * <http://www.OpenLDAP.org/license.html>.
  */
 /* ACKNOWLEDGEMENTS:
- * This work was initially developed by the Howard Chu for inclusion
+ * This work was initially developed by Howard Chu for inclusion
  * in OpenLDAP Software and subsequently enhanced by Pierangelo
  * Masarati.
  */
@@ -41,6 +41,9 @@ static LDAP_REBIND_PROC       ldap_back_rebind;
 static int
 ldap_back_proxy_authz_bind( struct ldapconn *lc, Operation *op, SlapReply *rs );
 
+static int
+ldap_back_prepare_conn( struct ldapconn **lcp, Operation *op, SlapReply *rs, ldap_back_send_t sendok );
+
 int
 ldap_back_bind( Operation *op, SlapReply *rs )
 {
@@ -50,9 +53,9 @@ ldap_back_bind( Operation *op, SlapReply *rs )
        int rc = 0;
        ber_int_t msgid;
 
-       lc = ldap_back_getconn( op, rs );
+       lc = ldap_back_getconn( op, rs, LDAP_BACK_SENDERR );
        if ( !lc ) {
-               return( -1 );
+               return rs->sr_err;
        }
 
        if ( !BER_BVISNULL( &lc->lc_bound_ndn ) ) {
@@ -65,7 +68,7 @@ ldap_back_bind( Operation *op, SlapReply *rs )
        rs->sr_err = ldap_sasl_bind( lc->lc_ld, op->o_req_dn.bv_val,
                        LDAP_SASL_SIMPLE,
                        &op->orb_cred, op->o_ctrls, NULL, &msgid );
-       rc = ldap_back_op_result( lc, op, rs, msgid, 1 );
+       rc = ldap_back_op_result( lc, op, rs, msgid, LDAP_BACK_SENDRESULT );
 
        if ( rc == LDAP_SUCCESS ) {
                /* If defined, proxyAuthz will be used also when
@@ -84,7 +87,7 @@ ldap_back_bind( Operation *op, SlapReply *rs )
                lc->lc_bound = 1;
                ber_dupbv( &lc->lc_bound_ndn, &op->o_req_ndn );
 
-               if ( li->savecred ) {
+               if ( li->flags & LDAP_BACK_F_SAVECRED ) {
                        if ( !BER_BVISNULL( &lc->lc_cred ) ) {
                                memset( lc->lc_cred.bv_val, 0,
                                                lc->lc_cred.bv_len );
@@ -219,12 +222,76 @@ ldap_back_freeconn( Operation *op, struct ldapconn *lc )
        return 0;
 }
 
+static int
+ldap_back_prepare_conn( struct ldapconn **lcp, Operation *op, SlapReply *rs, ldap_back_send_t sendok )
+{
+       struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private;
+       int             vers = op->o_protocol;
+       LDAP            *ld = NULL;
+
+       assert( lcp != NULL );
+
+       rs->sr_err = ldap_initialize( &ld, li->url );
+       if ( rs->sr_err != LDAP_SUCCESS ) {
+               goto error_return;
+       }
+
+       /* Set LDAP version. This will always succeed: If the client
+        * bound with a particular version, then so can we.
+        */
+       ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, (const void *)&vers );
+
+       /* Set LDAP version. This will always succeed: If the client
+        * bound with a particular version, then so can we.
+        */
+       ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION,
+                       (const void *)&vers );
+
+       /* FIXME: configurable? */
+       ldap_set_option( ld, LDAP_OPT_REFERRALS, LDAP_OPT_ON );
+
+       if ( ( li->flags & LDAP_BACK_F_USE_TLS )
+                       && !ldap_is_ldaps_url( li->url )
+                       && ( rs->sr_err = ldap_start_tls_s( ld, NULL, NULL ) ) != LDAP_SUCCESS )
+       {
+               /* if StartTLS is requested, only attempt it if the URL
+                * is not "ldaps://"; this may occur not only in case
+                * of misconfiguration, but also when used in the chain 
+                * overlay, where the "uri" can be parsed out of a referral */
+               if ( rs->sr_err == LDAP_SERVER_DOWN
+                               || ( li->flags & LDAP_BACK_F_TLS_CRITICAL ) )
+               {
+                       ldap_unbind_ext_s( ld, NULL, NULL );
+                       goto error_return;
+               }
+       }
+
+       if ( *lcp == NULL ) {
+               *lcp = (struct ldapconn *)ch_malloc( sizeof( struct ldapconn ) );
+               memset( *lcp, 0, sizeof( struct ldapconn ) );
+       }
+       (*lcp)->lc_ld = ld;
+
+error_return:;
+       if ( rs->sr_err != LDAP_SUCCESS ) {
+               rs->sr_err = slap_map_api2result( rs );
+               if ( sendok & LDAP_BACK_SENDERR ) {
+                       if ( rs->sr_text == NULL ) {
+                               rs->sr_text = "ldap_initialize() failed";
+                       }
+                       send_ldap_result( op, rs );
+                       rs->sr_text = NULL;
+               }
+       }
+
+       return rs->sr_err;
+}
+
 struct ldapconn *
-ldap_back_getconn( Operation *op, SlapReply *rs )
+ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok )
 {
        struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private;
        struct ldapconn *lc, lc_curr;
-       LDAP            *ld;
        int             is_priv = 0;
 
        /* Searches for a ldapconn in the avl tree */
@@ -258,31 +325,12 @@ ldap_back_getconn( Operation *op, SlapReply *rs )
 
        /* Looks like we didn't get a bind. Open a new session... */
        if ( !lc ) {
-               int vers = op->o_protocol;
-               rs->sr_err = ldap_initialize( &ld, li->url );
-               
-               if ( rs->sr_err != LDAP_SUCCESS ) {
-                       rs->sr_err = slap_map_api2result( rs );
-                       if ( rs->sr_text == NULL ) {
-                               rs->sr_text = "ldap_initialize() failed";
-                       }
-                       if ( op->o_conn ) {
-                               send_ldap_result( op, rs );
-                       }
-                       rs->sr_text = NULL;
-                       return( NULL );
+               /* lc here must be NULL */
+               if ( ldap_back_prepare_conn( &lc, op, rs, sendok ) != LDAP_SUCCESS ) {
+                       return NULL;
                }
-               /* Set LDAP version. This will always succeed: If the client
-                * bound with a particular version, then so can we.
-                */
-               ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION,
-                               (const void *)&vers );
-               /* FIXME: configurable? */
-               ldap_set_option( ld, LDAP_OPT_REFERRALS, LDAP_OPT_ON );
 
-               lc = (struct ldapconn *)ch_malloc( sizeof( struct ldapconn ) );
                lc->lc_conn = lc_curr.lc_conn;
-               lc->lc_ld = ld;
                ber_dupbv( &lc->lc_local_ndn, &lc_curr.lc_local_ndn );
 
                ldap_pvt_thread_mutex_init( &lc->lc_mutex );
@@ -320,18 +368,18 @@ ldap_back_getconn( Operation *op, SlapReply *rs )
                /* Err could be -1 in case a duplicate ldapconn is inserted */
                if ( rs->sr_err != 0 ) {
                        ldap_back_conn_free( lc );
-                       if ( op->o_conn ) {
+                       if ( op->o_conn && ( sendok & LDAP_BACK_SENDERR ) ) {
                                send_ldap_error( op, rs, LDAP_OTHER,
                                "internal server error" );
                        }
-                       return( NULL );
+                       return NULL;
                }
        } else {
                Debug( LDAP_DEBUG_TRACE,
                        "=>ldap_back_getconn: conn %p fetched\n", (void *) lc, 0, 0 );
        }
        
-       return( lc );
+       return lc;
 }
 
 /*
@@ -341,12 +389,19 @@ ldap_back_getconn( Operation *op, SlapReply *rs )
  * it from all the callers, and I made the function return the flag, so
  * it can be used to simplify the check.
  */
-int
-ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs )
+static int
+ldap_back_dobind_int(
+       struct ldapconn         *lc,
+       Operation               *op,
+       SlapReply               *rs,
+       ldap_back_send_t        sendok,
+       int                     retries )
 {      
        int             rc;
        ber_int_t       msgid;
 
+       assert( retries >= 0 );
+
        ldap_pvt_thread_mutex_lock( &lc->lc_mutex );
        if ( !lc->lc_bound ) {
                /*
@@ -373,12 +428,33 @@ ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs )
                        goto done;
                }
 
+retry:;
                rs->sr_err = ldap_sasl_bind( lc->lc_ld,
                                lc->lc_bound_ndn.bv_val,
                                LDAP_SASL_SIMPLE, &lc->lc_cred,
                                NULL, NULL, &msgid );
-               
-               rc = ldap_back_op_result( lc, op, rs, msgid, 0 );
+
+               if ( rs->sr_err == LDAP_SERVER_DOWN ) {
+                       if ( retries > 0 ) {
+                               ldap_unbind_ext_s( lc->lc_ld, NULL, NULL );
+                               lc->lc_ld = NULL;
+
+                               /* lc here must be the regular lc, reset and ready for init */
+                               if ( ldap_back_prepare_conn( &lc, op, rs, sendok ) != LDAP_SUCCESS ) {
+                                       return 0;
+                               }
+
+                               retries--;
+                               goto retry;
+                       }
+
+                       ldap_back_freeconn( op, lc );
+                       rs->sr_err = slap_map_api2result( rs );
+
+                       return 0;
+               }
+
+               rc = ldap_back_op_result( lc, op, rs, msgid, sendok );
                if ( rc == LDAP_SUCCESS ) {
                        lc->lc_bound = 1;
                }
@@ -390,6 +466,12 @@ done:;
        return rc;
 }
 
+int
+ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs, ldap_back_send_t sendok )
+{
+       return ldap_back_dobind_int( lc, op, rs, sendok, 1 );
+}
+
 /*
  * ldap_back_rebind
  *
@@ -400,7 +482,9 @@ static int
 ldap_back_rebind( LDAP *ld, LDAP_CONST char *url, ber_tag_t request,
        ber_int_t msgid, void *params )
 {
-       struct ldapconn *lc = params;
+       struct ldapconn *lc = (struct ldapconn *)params;
+
+       /* FIXME: add checks on the URL/identity? */
 
        return ldap_sasl_bind_s( ld, lc->lc_bound_ndn.bv_val,
                        LDAP_SASL_SIMPLE, &lc->lc_cred, NULL, NULL, NULL );
@@ -408,11 +492,11 @@ ldap_back_rebind( LDAP *ld, LDAP_CONST char *url, ber_tag_t request,
 
 int
 ldap_back_op_result(
-               struct ldapconn *lc,
-               Operation       *op,
-               SlapReply       *rs,
-               ber_int_t       msgid,
-               int             sendok )
+               struct ldapconn         *lc,
+               Operation               *op,
+               SlapReply               *rs,
+               ber_int_t               msgid,
+               ldap_back_send_t        sendok )
 {
        char            *match = NULL;
        LDAPMessage     *res = NULL;
@@ -474,7 +558,10 @@ retry:;
                        rs->sr_matched = match;
                }
        }
-       if ( op->o_conn && ( sendok || rs->sr_err != LDAP_SUCCESS ) ) {
+       if ( op->o_conn &&
+                       ( ( sendok & LDAP_BACK_SENDOK ) 
+                         || ( ( sendok & LDAP_BACK_SENDERR ) && rs->sr_err != LDAP_SUCCESS ) ) )
+       {
                send_ldap_result( op, rs );
        }
        if ( match ) {
@@ -493,37 +580,20 @@ retry:;
 
 /* return true if bound, false if failed */
 int
-ldap_back_retry( struct ldapconn *lc, Operation *op, SlapReply *rs )
+ldap_back_retry( struct ldapconn *lc, Operation *op, SlapReply *rs, ldap_back_send_t sendok )
 {
-       struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private;
-       int vers = op->o_protocol;
-       LDAP *ld;
-
        ldap_pvt_thread_mutex_lock( &lc->lc_mutex );
        ldap_unbind_ext_s( lc->lc_ld, NULL, NULL );
+       lc->lc_ld = NULL;
        lc->lc_bound = 0;
-       rs->sr_err = ldap_initialize( &ld, li->url );
-               
-       if ( rs->sr_err != LDAP_SUCCESS ) {
-               rs->sr_err = slap_map_api2result( rs );
-               if ( rs->sr_text == NULL ) {
-                       rs->sr_text = "ldap_initialize() failed";
-               }
-               if ( op->o_conn ) {
-                       send_ldap_result( op, rs );
-               }
-               rs->sr_text = NULL;
+
+       /* lc here must be the regular lc, reset and ready for init */
+       if ( ldap_back_prepare_conn( &lc, op, rs, sendok ) != LDAP_SUCCESS ) {
                return 0;
        }
-       /* Set LDAP version. This will always succeed: If the client
-        * bound with a particular version, then so can we.
-        */
-       ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, (const void *)&vers );
-       /* FIXME: configurable? */
-       ldap_set_option( ld, LDAP_OPT_REFERRALS, LDAP_OPT_ON );
-       lc->lc_ld = ld;
+
        ldap_pvt_thread_mutex_unlock( &lc->lc_mutex );
-       return ldap_back_dobind( lc, op, rs );
+       return ldap_back_dobind_int( lc, op, rs, sendok, 0 );
 }
 
 static int
@@ -695,7 +765,7 @@ ldap_back_proxy_authz_bind( struct ldapconn *lc, Operation *op, SlapReply *rs )
                goto done;
        }
 
-       rc = ldap_back_op_result( lc, op, rs, msgid, 0 );
+       rc = ldap_back_op_result( lc, op, rs, msgid, LDAP_BACK_SENDERR );
        if ( rc == LDAP_SUCCESS ) {
                lc->lc_bound = 1;
        }
index 58b6106cf071f0ad6b5ba7db1b6dc864d084ac5e..67927c40d767c0c98eb6d788c79ee3af13abe3bf 100644 (file)
 
 static BackendInfo *lback;
 
-#if 0
-static int
-ldap_chain_chk_referrals( Operation *op, SlapReply *rs )
-{
-       return LDAP_SUCCESS;
-}
-#endif
-
 static int
 ldap_chain_operational( Operation *op, SlapReply *rs )
 {
-       /* trap entries generated by back-ldap.
+       /* Trap entries generated by back-ldap.
+        * 
         * FIXME: we need a better way to recognize them; a cleaner
         * solution would be to be able to intercept the response
         * of be_operational(), so that we can divert only those
@@ -57,8 +50,11 @@ ldap_chain_operational( Operation *op, SlapReply *rs )
        return SLAP_CB_CONTINUE;
 }
 
+/*
+ * Search specific response that strips entryDN from entries
+ */
 static int
-ldap_chain_cb_response( Operation *op, SlapReply *rs )
+ldap_chain_cb_search_response( Operation *op, SlapReply *rs )
 {
        assert( op->o_tag == LDAP_REQ_SEARCH );
 
@@ -82,83 +78,159 @@ ldap_chain_cb_response( Operation *op, SlapReply *rs )
                }
                
                return SLAP_CB_CONTINUE;
+
+       } else if ( rs->sr_type == REP_RESULT ) {
+               /* back-ldap tried to send result */
+               op->o_callback->sc_private = (void *)(1);
        }
 
        return 0;
 }
 
+/*
+ * Dummy response that simply traces if back-ldap tried to send 
+ * anything to the client
+ */
+static int
+ldap_chain_cb_response( Operation *op, SlapReply *rs )
+{
+       if ( rs->sr_type == REP_RESULT ) {
+               op->o_callback->sc_private = (void *)(1);
+
+       } else if ( op->o_tag == LDAP_REQ_SEARCH && rs->sr_type == REP_SEARCH )
+       {
+               /* strip the entryDN attribute, but keep returning results */
+               (void)ldap_chain_cb_search_response( op, rs );
+       }
+
+       return SLAP_CB_CONTINUE;
+}
+
+static int
+ldap_chain_op(
+       Operation       *op,
+       SlapReply       *rs,
+       int             ( *op_f )( Operation *op, SlapReply *rs ), 
+       BerVarray       ref )
+{
+       slap_overinst   *on = (slap_overinst *) op->o_bd->bd_info;
+       struct ldapinfo li, *lip = (struct ldapinfo *)on->on_bi.bi_private;
+       int             rc;
+
+       if ( lip->url != NULL ) {
+               op->o_bd->be_private = on->on_bi.bi_private;
+               return ( *op_f )( op, rs );
+       }
+
+       li = *lip;
+       op->o_bd->be_private = &li;
+
+       /* if we parse the URI then by no means 
+        * we can cache stuff or reuse connections, 
+        * because in back-ldap there's no caching
+        * based on the URI value, which is supposed
+        * to be set once for all (correct?) */
+       op->o_do_not_cache = 1;
+
+       for ( ; !BER_BVISNULL( ref ); ref++ ) {
+               LDAPURLDesc     *srv;
+               char            *save_dn;
+                       
+               /* We're setting the URI of the first referral;
+                * what if there are more?
+
+Document: draft-ietf-ldapbis-protocol-27.txt
+
+4.1.10. Referral 
+   ...
+   If the client wishes to progress the operation, it MUST follow the 
+   referral by contacting one of the supported services. If multiple 
+   URIs are present, the client assumes that any supported URI may be 
+   used to progress the operation. 
+
+                * so we actually need to follow exactly one,
+                * and we can assume any is fine.
+                */
+       
+               /* parse reference and use 
+                * proto://[host][:port]/ only */
+               rc = ldap_url_parse_ext( ref->bv_val, &srv );
+               if ( rc != LDAP_URL_SUCCESS ) {
+                       /* try next */
+                       rc = LDAP_OTHER;
+                       continue;
+               }
+
+               /* remove DN essentially because later on 
+                * ldap_initialize() will parse the URL 
+                * as a comma-separated URL list */
+               save_dn = srv->lud_dn;
+               srv->lud_dn = "";
+               srv->lud_scope = LDAP_SCOPE_DEFAULT;
+               li.url = ldap_url_desc2str( srv );
+               srv->lud_dn = save_dn;
+               ldap_free_urldesc( srv );
+
+               if ( li.url == NULL ) {
+                       /* try next */
+                       rc = LDAP_OTHER;
+                       continue;
+               }
+
+               rc = ( *op_f )( op, rs );
+
+               ldap_memfree( li.url );
+               li.url = NULL;
+               
+               if ( rc == LDAP_SUCCESS && rs->sr_err == LDAP_SUCCESS ) {
+                       break;
+               }
+       }
+
+       return rc;
+}
+
 static int
 ldap_chain_response( Operation *op, SlapReply *rs )
 {
        slap_overinst   *on = (slap_overinst *) op->o_bd->bd_info;
        void            *private = op->o_bd->be_private;
-       slap_callback   *sc = op->o_callback;
+       slap_callback   *sc = op->o_callback,
+                       sc2 = { 0 };
        int             rc = 0;
        int             cache = op->o_do_not_cache;
-       char            *authzid = NULL;
        BerVarray       ref;
        struct berval   ndn = op->o_ndn;
 
        struct ldapinfo li, *lip = (struct ldapinfo *)on->on_bi.bi_private;
 
-       if ( rs->sr_err != LDAP_REFERRAL && rs->sr_type != REP_SEARCHREF )
+       if ( rs->sr_err != LDAP_REFERRAL && rs->sr_type != REP_SEARCHREF ) {
                return SLAP_CB_CONTINUE;
+       }
+
+       /*
+        * TODO: add checks on who/when chain operations; e.g.:
+        *   a) what identities are authorized
+        *   b) what request DN (e.g. only chain requests rooted at <DN>)
+        *   c) what referral URIs
+        *   d) what protocol scheme (e.g. only ldaps://)
+        *   e) what ssf
+        */
 
        ref = rs->sr_ref;
        rs->sr_ref = NULL;
 
-       op->o_callback = NULL;
-
-       if ( lip->url == NULL ) {
-               /* if we parse the URI then by no means 
-                * we can cache stuff or reuse connections, 
-                * because in back-ldap there's no caching
-                * based on the URI value, which is supposed
-                * to be set once for all (correct?) */
-               op->o_do_not_cache = 1;
-
-               /* FIXME: we're setting the URI of the first referral;
-                * what if there are more?  Is this something we should
-                * worry about? */
-               li = *lip;
-               op->o_bd->be_private = &li;
-
-               if ( rs->sr_type != REP_SEARCHREF ) {
-                       LDAPURLDesc     *srv;
-                       char            *save_dn;
-
-                       /* parse reference and use 
-                        * proto://[host][:port]/ only */
-                       rc = ldap_url_parse_ext( ref[0].bv_val, &srv );
-                       if ( rc != LDAP_URL_SUCCESS ) {
-                               /* error */
-                               return 1;
-                       }
-
-                       /* remove DN essentially because later on 
-                        * ldap_initialize() will parse the URL 
-                        * as a comma-separated URL list */
-                       save_dn = srv->lud_dn;
-                       srv->lud_dn = "";
-                       srv->lud_scope = LDAP_SCOPE_DEFAULT;
-                       li.url = ldap_url_desc2str( srv );
-                       srv->lud_dn = save_dn;
-                       ldap_free_urldesc( srv );
-
-                       if ( li.url == NULL ) {
-                               /* error */
-                               return 1;
-                       }
-               }
-
-       } else {
-               op->o_bd->be_private = on->on_bi.bi_private;
-       }
+       /* we need this to know if back-ldap returned any result */
+       sc2.sc_response = ldap_chain_cb_response;
+       op->o_callback = &sc2;
 
        /* Chaining can be performed by a privileged user on behalf
         * of normal users, using the ProxyAuthz control, by exploiting
         * the identity assertion feature of back-ldap; see idassert-*
         * directives in slapd-ldap(5).
+        *
+        * FIXME: the idassert-authcDN is one, will it be fine regardless
+        * of the URI we obtain from the referral?
         */
 
        switch ( op->o_tag ) {
@@ -166,10 +238,10 @@ ldap_chain_response( Operation *op, SlapReply *rs )
                struct berval   rndn = op->o_req_ndn;
                Connection      *conn = op->o_conn;
 
+               /* FIXME: can we really get a referral for binds? */
                op->o_req_ndn = slap_empty_bv;
-
                op->o_conn = NULL;
-               rc = lback->bi_op_bind( op, rs );
+               rc = ldap_chain_op( op, rs, lback->bi_op_bind, ref );
                op->o_req_ndn = rndn;
                op->o_conn = conn;
                }
@@ -182,7 +254,7 @@ ldap_chain_response( Operation *op, SlapReply *rs )
                        char            textbuf[ SLAP_TEXT_BUFLEN ];
                        size_t          textlen = sizeof( textbuf );
 
-                       /* global overlay; create entry */
+                       /* global overlay: create entry */
                        /* NOTE: this is a hack to use the chain overlay
                         * as global.  I expect to be able to remove this
                         * soon by using slap_mods2entry() earlier in
@@ -197,7 +269,7 @@ ldap_chain_response( Operation *op, SlapReply *rs )
                                break;
                        }
                }
-               rc = lback->bi_op_add( op, rs );
+               rc = ldap_chain_op( op, rs, lback->bi_op_add, ref );
                if ( cleanup_attrs ) {
                        attrs_free( op->ora_e->e_attrs );
                        op->ora_e->e_attrs = NULL;
@@ -205,32 +277,38 @@ ldap_chain_response( Operation *op, SlapReply *rs )
                break;
                }
        case LDAP_REQ_DELETE:
-               rc = lback->bi_op_delete( op, rs );
+               rc = ldap_chain_op( op, rs, lback->bi_op_delete, ref );
                break;
        case LDAP_REQ_MODRDN:
-               rc = lback->bi_op_modrdn( op, rs );
+               rc = ldap_chain_op( op, rs, lback->bi_op_modrdn, ref );
                break;
        case LDAP_REQ_MODIFY:
-               rc = lback->bi_op_modify( op, rs );
+               rc = ldap_chain_op( op, rs, lback->bi_op_modify, ref );
                break;
        case LDAP_REQ_COMPARE:
-               rc = lback->bi_op_compare( op, rs );
+               rc = ldap_chain_op( op, rs, lback->bi_op_compare, ref );
                break;
        case LDAP_REQ_SEARCH:
                if ( rs->sr_type == REP_SEARCHREF ) {
                        struct berval   *curr = ref,
                                        odn = op->o_req_dn,
                                        ondn = op->o_req_ndn;
-                       slap_callback   sc2 = { 0 };
-                       int             tmprc = 0;
-                       ber_len_t       refcnt = 0;
-                       BerVarray       newref = NULL;
-
-                       sc2.sc_response = ldap_chain_cb_response;
-                       op->o_callback = &sc2;
 
                        rs->sr_type = REP_SEARCH;
 
+                       sc2.sc_response = ldap_chain_cb_search_response;
+
+                       li = *lip;
+                       li.url = NULL;
+                       op->o_bd->be_private = &li;
+                       
+                       /* if we parse the URI then by no means 
+                        * we can cache stuff or reuse connections, 
+                        * because in back-ldap there's no caching
+                        * based on the URI value, which is supposed
+                        * to be set once for all (correct?) */
+                       op->o_do_not_cache = 1;
+
                        /* copy the private info because we need to modify it */
                        for ( ; !BER_BVISNULL( &curr[0] ); curr++ ) {
                                LDAPURLDesc     *srv;
@@ -238,11 +316,11 @@ ldap_chain_response( Operation *op, SlapReply *rs )
 
                                /* parse reference and use
                                 * proto://[host][:port]/ only */
-                               tmprc = ldap_url_parse_ext( curr[0].bv_val, &srv );
-                               if ( tmprc != LDAP_URL_SUCCESS ) {
-                                       /* error */
-                                       rc = 1;
-                                       goto end_of_searchref;
+                               rc = ldap_url_parse_ext( curr[0].bv_val, &srv );
+                               if ( rc != LDAP_URL_SUCCESS ) {
+                                       /* try next */
+                                       rs->sr_err = LDAP_OTHER;
+                                       continue;
                                }
 
                                /* remove DN essentially because later on 
@@ -263,15 +341,15 @@ ldap_chain_response( Operation *op, SlapReply *rs )
                                ldap_free_urldesc( srv );
 
                                if ( li.url == NULL ) {
-                                       /* error */
-                                       rc = 1;
-                                       goto end_of_searchref;
+                                       /* try next */
+                                       rs->sr_err = LDAP_OTHER;
+                                       continue;
                                }
 
 
                                /* FIXME: should we also copy filter and scope?
                                 * according to RFC3296, no */
-                               tmprc = lback->bi_op_search( op, rs );
+                               rc = lback->bi_op_search( op, rs );
 
                                ldap_memfree( li.url );
                                li.url = NULL;
@@ -281,76 +359,51 @@ ldap_chain_response( Operation *op, SlapReply *rs )
                                op->o_tmpfree( op->o_req_ndn.bv_val,
                                                op->o_tmpmemctx );
 
-                               if ( tmprc ) {
-                                       /* error */
-                                       rc = 1;
-                                       goto end_of_searchref;
-                               }
-
-                               if ( rs->sr_err != LDAP_SUCCESS ) {
-                                       /* if search was not successful,
-                                        * at least return the referral! */
-                                       /* FIXME: assumes referrals 
-                                        * are always created via
-                                        * referral_rewrite() and freed via
-                                        * ber_bvarray_free( rs->sr_ref ) */
-                                       newref = ch_realloc( newref, sizeof( struct berval ) * (refcnt + 2) );
-                                       ber_dupbv( &newref[ refcnt ], &curr[ 0 ] );
-                                       refcnt++;
-                                       BER_BVZERO( &newref[ refcnt ] );
+                               if ( rc == LDAP_SUCCESS && rs->sr_err == LDAP_SUCCESS ) {
+                                       break;
                                }
                        }
 
-end_of_searchref:;
                        op->o_req_dn = odn;
                        op->o_req_ndn = ondn;
                        rs->sr_type = REP_SEARCHREF;
                        rs->sr_entry = NULL;
 
-                       /* if the error was bad, it was already returned
-                        * by back-ldap; destroy the referrals left;
-                        * otherwise, let the frontend return them. */
-                       if ( newref ) {
-                               if ( rc == 0 ) {
-                                       rc = SLAP_CB_CONTINUE;
-                                       if ( ref != default_referral ) {
-                                               ber_bvarray_free( ref );
-                                       }
-                                       ref = newref;
-
-                               } else {
-                                       ber_bvarray_free( newref );
-                               }
+                       if ( rc != LDAP_SUCCESS ) {
+                               /* couldn't chase any of the referrals */
+                               rc = SLAP_CB_CONTINUE;
                        }
                        
                } else {
-                       rc = lback->bi_op_search( op, rs );
+                       rc = ldap_chain_op( op, rs, lback->bi_op_search, ref );
                }
                break;
        case LDAP_REQ_EXTENDED:
-               rc = lback->bi_extended( op, rs );
+               rc = ldap_chain_op( op, rs, lback->bi_extended, ref );
                /* FIXME: ldap_back_extended() by design 
                 * doesn't send result; frontend is expected
                 * to send it... */
                if ( rc != SLAPD_ABANDON ) {
                        send_ldap_extended( op, rs );
+                       rc = LDAP_SUCCESS;
                }
                break;
        default:
                rc = SLAP_CB_CONTINUE;
                break;
        }
+
+       if ( sc2.sc_private == NULL ) {
+               op->o_callback = NULL;
+               rc = rs->sr_err = slap_map_api2result( rs );
+               send_ldap_result( op, rs );
+       }
+
        op->o_do_not_cache = cache;
        op->o_bd->be_private = private;
        op->o_callback = sc;
        op->o_ndn = ndn;
-       if ( authzid ) {
-               op->o_tmpfree( authzid, op->o_tmpmemctx );
-       }
        rs->sr_ref = ref;
-       if ( lip->url == NULL && li.url != NULL ) {
-               ldap_memfree( li.url );
-       }
 
        return rc;
 }
@@ -388,9 +441,9 @@ ldap_chain_db_init(
        BackendDB *be
 )
 {
-       slap_overinst *on = (slap_overinst *) be->bd_info;
-       void *private = be->be_private;
-       int rc;
+       slap_overinst   *on = (slap_overinst *)be->bd_info;
+       int             rc;
+       BackendDB       bd = *be;
 
        if ( lback == NULL ) {
                lback = backend_info( "ldap" );
@@ -400,10 +453,9 @@ ldap_chain_db_init(
                }
        }
 
-       be->be_private = NULL;
-       rc = lback->bi_db_init( be );
-       on->on_bi.bi_private = be->be_private;
-       be->be_private = private;
+       bd.be_private = NULL;
+       rc = lback->bi_db_init( &bd );
+       on->on_bi.bi_private = bd.be_private;
 
        return rc;
 }
@@ -447,10 +499,6 @@ chain_init( void )
        
        ldapchain.on_response = ldap_chain_response;
 
-#if 0
-       ldapchain.on_bi.bi_chk_referrals = ldap_chain_chk_referrals;
-#endif
-
        return overlay_register( &ldapchain );
 }
 
index ffa9f6bf77de6a5a59c1543a23b85839eef0d5ff..a538e3d4b27cb9ea94822dcd77c7463f1ea161a6 100644 (file)
@@ -42,9 +42,8 @@ ldap_back_compare(
        LDAPControl     **ctrls = NULL;
        int             rc = LDAP_SUCCESS;
 
-       lc = ldap_back_getconn( op, rs );
-       if (!lc || !ldap_back_dobind( lc, op, rs ) ) {
-               rc = -1;
+       lc = ldap_back_getconn( op, rs, LDAP_BACK_SENDERR );
+       if ( !lc || !ldap_back_dobind( lc, op, rs, LDAP_BACK_SENDERR ) ) {
                goto cleanup;
        }
 
@@ -52,7 +51,6 @@ ldap_back_compare(
        rc = ldap_back_proxy_authz_ctrl( lc, op, rs, &ctrls );
        if ( rc != LDAP_SUCCESS ) {
                send_ldap_result( op, rs );
-               rc = -1;
                goto cleanup;
        }
 
@@ -61,10 +59,10 @@ retry:
                        op->orc_ava->aa_desc->ad_cname.bv_val,
                        &op->orc_ava->aa_value, 
                        ctrls, NULL, &msgid );
-       rc = ldap_back_op_result( lc, op, rs, msgid, 1 );
-       if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
+       rc = ldap_back_op_result( lc, op, rs, msgid, LDAP_BACK_SENDRESULT );
+       if ( rc == LDAP_UNAVAILABLE && do_retry ) {
                do_retry = 0;
-               if ( ldap_back_retry(lc, op, rs ) ) {
+               if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) {
                        goto retry;
                }
        }
@@ -72,5 +70,5 @@ retry:
 cleanup:
        (void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
        
-       return rc;
+       return rs->sr_err;
 }
index bdbdc698ce279663b27bd6847b3ecd1a0a6cbb40..470becaa3cef9d773b84355b1799bcf7192142d1 100644 (file)
@@ -213,26 +213,67 @@ ldap_back_db_config(
                li->url = ch_strdup( argv[ 1 ] );
 #endif
 
+       /* start tls */
+       } else if ( strcasecmp( argv[0], "start-tls" ) == 0 ) {
+               if ( argc != 1 ) {
+                       fprintf( stderr,
+       "%s: line %d: start-tls takes no arguments\n",
+                                       fname, lineno );
+                       return( 1 );
+               }
+               li->flags |= LDAP_BACK_F_TLS_CRITICAL;
+       
+       /* try start tls */
+       } else if ( strcasecmp( argv[0], "try-start-tls" ) == 0 ) {
+               if ( argc != 1 ) {
+                       fprintf( stderr,
+       "%s: line %d: try-start-tls takes no arguments\n",
+                                       fname, lineno );
+                       return( 1 );
+               }
+               li->flags &= ~LDAP_BACK_F_TLS_CRITICAL;
+               li->flags |= LDAP_BACK_F_USE_TLS;
+       
        /* name to use for ldap_back_group */
        } else if ( strcasecmp( argv[0], "acl-authcdn" ) == 0
-                       || strcasecmp( argv[0], "binddn" ) == 0 ) {
+                       || strcasecmp( argv[0], "binddn" ) == 0 )
+       {
                if ( argc != 2 ) {
                        fprintf( stderr,
        "%s: line %d: missing name in \"%s <name>\" line\n",
                                        fname, lineno, argv[0] );
                        return( 1 );
                }
+
+               if ( strcasecmp( argv[0], "binddn" ) == 0 ) {
+                       fprintf( stderr, "%s: line %d: "
+                               "\"binddn\" statement is deprecated; "
+                               "use \"acl-authcDN\" instead\n",
+                               fname, lineno );
+                       /* FIXME: some day we'll need to throw an error */
+               }
+
                ber_str2bv( argv[1], 0, 1, &li->acl_authcDN );
 
        /* password to use for ldap_back_group */
        } else if ( strcasecmp( argv[0], "acl-passwd" ) == 0
-                       || strcasecmp( argv[0], "bindpw" ) == 0 ) {
+                       || strcasecmp( argv[0], "bindpw" ) == 0 )
+       {
                if ( argc != 2 ) {
                        fprintf( stderr,
        "%s: line %d: missing password in \"%s <password>\" line\n",
                                        fname, lineno, argv[0] );
                        return( 1 );
                }
+
+               if ( strcasecmp( argv[0], "bindpw" ) == 0 ) {
+                       fprintf( stderr, "%s: line %d: "
+                               "\"bindpw\" statement is deprecated; "
+                               "use \"acl-passwd\" instead\n",
+                               fname, lineno );
+                       /* FIXME: some day we'll need to throw an error */
+               }
+
                ber_str2bv( argv[1], 0, 1, &li->acl_passwd );
 
        /* identity assertion stuff... */
@@ -252,7 +293,7 @@ ldap_back_db_config(
                                        fname, lineno );
                        return( 1 );
                }
-               li->savecred = 1;
+               li->flags |= LDAP_BACK_F_SAVECRED;
        
        /* intercept exop_who_am_i? */
        } else if ( strcasecmp( argv[0], "proxy-whoami" ) == 0 ) {
@@ -340,8 +381,8 @@ ldap_back_exop_whoami(
 
                ctrls[0] = &c;
                op2.o_ndn = op->o_conn->c_ndn;
-               lc = ldap_back_getconn(&op2, rs);
-               if (!lc || !ldap_back_dobind( lc, op, rs )) {
+               lc = ldap_back_getconn(&op2, rs, LDAP_BACK_SENDERR);
+               if (!lc || !ldap_back_dobind( lc, op, rs, LDAP_BACK_SENDERR )) {
                        return -1;
                }
                c.ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ;
@@ -359,7 +400,7 @@ retry:
                                        &rs->sr_err);
                                if ( rs->sr_err == LDAP_SERVER_DOWN && do_retry ) {
                                        do_retry = 0;
-                                       if ( ldap_back_retry( lc, op, rs ) )
+                                       if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) )
                                                goto retry;
                                }
                                ldap_back_freeconn( op, lc );
index 4b0ce6b25c4df268440031f957a7d8e5cfb2ae0a..3d6575be57c9153453c57d0a167635f690c72627 100644 (file)
@@ -42,9 +42,9 @@ ldap_back_delete(
        int             do_retry = 1;
        int             rc = LDAP_SUCCESS;
 
-       lc = ldap_back_getconn( op, rs );
+       lc = ldap_back_getconn( op, rs, LDAP_BACK_SENDERR );
        
-       if ( !lc || !ldap_back_dobind( lc, op, rs ) ) {
+       if ( !lc || !ldap_back_dobind( lc, op, rs, LDAP_BACK_SENDERR ) ) {
                rc = -1;
                goto cleanup;
        }
@@ -60,10 +60,10 @@ ldap_back_delete(
 retry:
        rs->sr_err = ldap_delete_ext( lc->lc_ld, op->o_req_ndn.bv_val,
                        ctrls, NULL, &msgid );
-       rc = ldap_back_op_result( lc, op, rs, msgid, 1 );
+       rc = ldap_back_op_result( lc, op, rs, msgid, LDAP_BACK_SENDRESULT );
        if ( rs->sr_err == LDAP_SERVER_DOWN && do_retry ) {
                do_retry = 0;
-               if ( ldap_back_retry (lc, op, rs ) ) {
+               if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) {
                        goto retry;
                }
        }
index d4202d4c2b7e8971c9c3ee35382447ee9d7ef4e2..8fb7e44a53955b55048d6d586d52692b0acb0e87 100644 (file)
@@ -56,8 +56,8 @@ ldap_back_extended(
                         * called twice; maybe we could avoid the 
                         * ldap_back_dobind() call inside each extended()
                         * call ... */
-                       lc = ldap_back_getconn( op, rs );
-                       if ( !lc || !ldap_back_dobind( lc, op, rs ) ) {
+                       lc = ldap_back_getconn( op, rs, LDAP_BACK_SENDERR );
+                       if ( !lc || !ldap_back_dobind( lc, op, rs, LDAP_BACK_SENDERR ) ) {
                                return -1;
                        }
 
@@ -99,8 +99,8 @@ ldap_back_exop_passwd(
        int             rc, isproxy;
        int             do_retry = 1;
 
-       lc = ldap_back_getconn( op, rs );
-       if ( !lc || !ldap_back_dobind( lc, op, rs ) ) {
+       lc = ldap_back_getconn( op, rs, LDAP_BACK_SENDERR );
+       if ( !lc || !ldap_back_dobind( lc, op, rs, LDAP_BACK_SENDERR ) ) {
                return -1;
        }
 
@@ -154,7 +154,7 @@ retry:
                rs->sr_err = slap_map_api2result( rs );
                if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
                        do_retry = 0;
-                       if ( ldap_back_retry(lc, op, rs ) ) {
+                       if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) {
                                goto retry;
                        }
                }
index b00c579d36479c0792b4d0a9f796200e84031933..84f47becbd447c63b667605bb9a207c04a4fbf7f 100644 (file)
@@ -144,10 +144,10 @@ ldap_back_db_open( BackendDB *be )
                /* FIXME: disabled because namingContexts doesn't have
                 * a matching rule, and using an MRA filter doesn't work
                 * because the normalized assertion is compared to the 
-                * non-normalized value, which in general differ.
-                * See ITS#3406 */
+                * non-normalized value, which in general differs from
+                * the normalized one.  See ITS#3406 */
                struct berval   filter,
-                               base = BER_BVC( "cn=Databases,cn=Monitor" );
+                               base = BER_BVC( "cn=Databases," SLAPD_MONITOR );
                struct berval   vals[ 2 ];
                Attribute       a = { 0 };
 
index cc551243a1d095efeeda6dbdafaa2226d8312b78..0936bb4e0f75463795e24873309a31964bddb411 100644 (file)
@@ -46,8 +46,8 @@ ldap_back_modify(
        int             do_retry = 1;
        LDAPControl     **ctrls = NULL;
 
-       lc = ldap_back_getconn( op, rs );
-       if ( !lc || !ldap_back_dobind( lc, op, rs ) ) {
+       lc = ldap_back_getconn( op, rs, LDAP_BACK_SENDERR );
+       if ( !lc || !ldap_back_dobind( lc, op, rs, LDAP_BACK_SENDERR ) ) {
                return -1;
        }
 
@@ -106,10 +106,10 @@ ldap_back_modify(
 retry:
        rs->sr_err = ldap_modify_ext( lc->lc_ld, op->o_req_ndn.bv_val, modv,
                        ctrls, NULL, &msgid );
-       rc = ldap_back_op_result( lc, op, rs, msgid, 1 );
+       rc = ldap_back_op_result( lc, op, rs, msgid, LDAP_BACK_SENDRESULT );
        if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
                do_retry = 0;
-               if ( ldap_back_retry(lc, op, rs ) ) {
+               if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) {
                        goto retry;
                }
        }
index 92cce0a749d5dd7b6a844d025ceafe275eb9bfd5..22554b24307742c3912b2d388bfc86832eb89d4e 100644 (file)
@@ -43,8 +43,8 @@ ldap_back_modrdn(
        int             rc = LDAP_SUCCESS;
        char            *newSup = NULL;
 
-       lc = ldap_back_getconn( op, rs );
-       if ( !lc || !ldap_back_dobind( lc, op, rs ) ) {
+       lc = ldap_back_getconn( op, rs, LDAP_BACK_SENDERR );
+       if ( !lc || !ldap_back_dobind( lc, op, rs, LDAP_BACK_SENDERR ) ) {
                return( -1 );
        }
 
@@ -67,10 +67,10 @@ retry:
        rs->sr_err = ldap_rename( lc->lc_ld, op->o_req_ndn.bv_val,
                        op->orr_newrdn.bv_val, newSup,
                        op->orr_deleteoldrdn, ctrls, NULL, &msgid );
-       rc = ldap_back_op_result( lc, op, rs, msgid, 1 );
+       rc = ldap_back_op_result( lc, op, rs, msgid, LDAP_BACK_SENDRESULT );
        if ( rs->sr_err == LDAP_SERVER_DOWN && do_retry ) {
                do_retry = 0;
-               if ( ldap_back_retry( lc, op, rs ) ) {
+               if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) {
                        goto retry;
                }
        }
index eadc7d3949fd8228b947f9db3af785a58f37fa1e..8c85f507f414e1a8d1f44ba4876820f8c6412377 100644 (file)
@@ -49,12 +49,12 @@ extern BI_connection_destroy        ldap_back_conn_destroy;
 extern BI_entry_get_rw         ldap_back_entry_get;
 
 int ldap_back_freeconn( Operation *op, struct ldapconn *lc );
-struct ldapconn *ldap_back_getconn(struct slap_op *op, struct slap_rep *rs);
-int ldap_back_dobind(struct ldapconn *lc, Operation *op, SlapReply *rs);
-int ldap_back_retry(struct ldapconn *lc, Operation *op, SlapReply *rs);
+struct ldapconn *ldap_back_getconn(struct slap_op *op, struct slap_rep *rs, ldap_back_send_t sendok);
+int ldap_back_dobind(struct ldapconn *lc, Operation *op, SlapReply *rs, ldap_back_send_t sendok);
+int ldap_back_retry(struct ldapconn *lc, Operation *op, SlapReply *rs, ldap_back_send_t sendok);
 int ldap_back_map_result(SlapReply *rs);
 int ldap_back_op_result(struct ldapconn *lc, Operation *op, SlapReply *rs,
-       ber_int_t msgid, int sendok);
+       ber_int_t msgid, ldap_back_send_t sendok);
 int    back_ldap_LTX_init_module(int argc, char *argv[]);
 
 extern int ldap_back_conn_cmp( const void *c1, const void *c2);
index bf78dec637e58b79092969fc217bbbfd33d17795..b42352614f65e09159e8df6bfb80efcedadff3dd 100644 (file)
@@ -60,17 +60,17 @@ ldap_back_search(
        int             do_retry = 1;
        LDAPControl     **ctrls = NULL;
 
-       lc = ldap_back_getconn( op, rs );
+       lc = ldap_back_getconn( op, rs, LDAP_BACK_SENDERR );
        if ( !lc ) {
-               return -1;
+               return rs->sr_err;
        }
 
        /*
         * FIXME: in case of values return filter, we might want
         * to map attrs and maybe rewrite value
         */
-       if ( !ldap_back_dobind( lc, op, rs ) ) {
-               return -1;
+       if ( !ldap_back_dobind( lc, op, rs, LDAP_BACK_SENDERR ) ) {
+               return rs->sr_err;
        }
 
        /* should we check return values? */
@@ -120,7 +120,7 @@ retry:
 
        if ( rs->sr_err != LDAP_SUCCESS ) {
 fail:;
-               rc = ldap_back_op_result( lc, op, rs, msgid, 0 );
+               rc = ldap_back_op_result( lc, op, rs, msgid, LDAP_BACK_SENDERR );
                if ( freeconn ) {
                        ldap_back_freeconn( op, lc );
                        lc = NULL;
@@ -249,7 +249,7 @@ fail:;
        if ( rc == -1 ) {
                if ( do_retry ) {
                        do_retry = 0;
-                       if ( ldap_back_retry( lc, op, rs ) ) {
+                       if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) {
                                goto retry;
                        }
                }
@@ -500,7 +500,6 @@ ldap_back_entry_get(
                        *e = NULL;
        char            *gattr[3];
        char            *filter = NULL;
-       Connection      *oconn;
        SlapReply       rs;
        int             do_retry = 1;
        LDAPControl     **ctrls = NULL;
@@ -508,16 +507,12 @@ ldap_back_entry_get(
        /* Tell getconn this is a privileged op */
        do_not_cache = op->o_do_not_cache;
        op->o_do_not_cache = 1;
-       lc = ldap_back_getconn( op, &rs );
-       oconn = op->o_conn;
-       op->o_conn = NULL;
-       if ( !lc || !ldap_back_dobind( lc, op, &rs ) ) {
+       lc = ldap_back_getconn( op, &rs, LDAP_BACK_DONTSEND );
+       if ( !lc || !ldap_back_dobind( lc, op, &rs, LDAP_BACK_DONTSEND ) ) {
                op->o_do_not_cache = do_not_cache;
-               op->o_conn = oconn;
-               return 1;
+               return rs.sr_err;
        }
        op->o_do_not_cache = do_not_cache;
-       op->o_conn = oconn;
 
        if ( at ) {
                if ( oc && at != slap_schema.si_ad_objectClass ) {
@@ -555,7 +550,7 @@ retry:
        if ( rc != LDAP_SUCCESS ) {
                if ( rc == LDAP_SERVER_DOWN && do_retry ) {
                        do_retry = 0;
-                       if ( ldap_back_retry( lc, op, &rs ) ) {
+                       if ( ldap_back_retry( lc, op, &rs, LDAP_BACK_DONTSEND ) ) {
                                goto retry;
                        }
                }
index b5a7ec7fefeda11251d8f3da3e4fa36775ec8ca1..d45fb017b0ac5490abf6575bca5724f80df82406 100644 (file)
@@ -186,7 +186,7 @@ id2entry_rw( Backend *be, ID id, int rw )
                return( NULL );
        }
 
-       e = str2entry( data.dptr );
+       e = str2entry2( data.dptr, 0 );
        ldbm_datum_free( db->dbc_db, data );
        ldbm_cache_close( be, db );
 
index 17f4571af1b4032951ba8e7d2adf6e1125cc2415..4fffb1f9d55bf2839049b5f40c1733d492b4776c 100644 (file)
@@ -158,7 +158,7 @@ Entry* ldbm_tool_entry_get( BackendDB *be, ID id )
                return NULL;
        }
 
-       e = str2entry( data.dptr );
+       e = str2entry2( data.dptr, 0 );
        ldbm_datum_free( id2entry->dbc_db, data );
 
        if( e != NULL ) {
index 6f352696e030968441c5a5e46ccc721f7bc75bff..15f13ee892e8bed5c31acd819f476469859f4431 100644 (file)
@@ -54,13 +54,14 @@ meta_back_add( Operation *op, SlapReply *rs )
                        &op->o_req_ndn, &candidate );
        if ( !lc ) {
                send_ldap_result( op, rs );
+               return rs->sr_err;
        }
 
        if ( !meta_back_dobind( lc, op )
                        || !meta_back_is_valid( lc, candidate ) ) {
                rs->sr_err = LDAP_UNAVAILABLE;
                send_ldap_result( op, rs );
-               return -1;
+               return rs->sr_err;
        }
 
        /*
@@ -73,7 +74,7 @@ meta_back_add( Operation *op, SlapReply *rs )
 
        if ( ldap_back_dn_massage( &dc, &op->o_req_dn, &mdn ) ) {
                send_ldap_result( op, rs );
-               return -1;
+               return rs->sr_err;
        }
 
        /* Count number of attributes in entry */
@@ -82,18 +83,27 @@ meta_back_add( Operation *op, SlapReply *rs )
        /* Create array of LDAPMods for ldap_add() */
        attrs = ch_malloc( sizeof( LDAPMod * )*i );
 
+       dc.ctx = "addAttrDN";
        isupdate = be_shadow_update( op );
        for ( i = 0, a = op->ora_e->e_attrs; a; a = a->a_next ) {
-               int j;
+               int                     j, is_oc = 0;
 
                if ( !isupdate && a->a_desc->ad_type->sat_no_user_mod  ) {
                        continue;
                }
 
-               ldap_back_map( &li->targets[ candidate ]->mt_rwmap.rwm_at,
-                               &a->a_desc->ad_cname, &mapped, BACKLDAP_MAP );
-               if ( mapped.bv_val == NULL || mapped.bv_val[0] == '\0' ) {
-                       continue;
+               if ( a->a_desc == slap_schema.si_ad_objectClass 
+                               || a->a_desc == slap_schema.si_ad_structuralObjectClass )
+               {
+                       is_oc = 1;
+                       mapped = a->a_desc->ad_cname;
+
+               } else {
+                       ldap_back_map( &li->targets[ candidate ]->mt_rwmap.rwm_at,
+                                       &a->a_desc->ad_cname, &mapped, BACKLDAP_MAP );
+                       if ( BER_BVISNULL( &mapped ) || BER_BVISEMPTY( &mapped ) ) {
+                               continue;
+                       }
                }
 
                attrs[ i ] = ch_malloc( sizeof( LDAPMod ) );
@@ -103,31 +113,65 @@ meta_back_add( Operation *op, SlapReply *rs )
                attrs[ i ]->mod_op = LDAP_MOD_BVALUES;
                attrs[ i ]->mod_type = mapped.bv_val;
 
-               /*
-                * FIXME: dn-valued attrs should be rewritten
-                * to allow their use in ACLs at the back-ldap
-                * level.
-                */
-               if ( a->a_desc->ad_type->sat_syntax ==
+               if ( is_oc ) {
+                       for ( j = 0; !BER_BVISNULL( &a->a_vals[ j ] ); j++ )
+                               ;
+
+                       attrs[ i ]->mod_bvalues =
+                               (struct berval **)ch_malloc( ( j + 1 ) *
+                               sizeof( struct berval * ) );
+
+                       for ( j = 0; !BER_BVISNULL( &a->a_vals[ j ] ); ) {
+                               struct ldapmapping      *mapping;
+
+                               ldap_back_mapping( &li->targets[ candidate ]->mt_rwmap.rwm_oc,
+                                               &a->a_vals[ j ], &mapping, BACKLDAP_MAP );
+
+                               if ( mapping == NULL ) {
+                                       if ( li->targets[ candidate ]->mt_rwmap.rwm_oc.drop_missing ) {
+                                               continue;
+                                       }
+                                       attrs[ i ]->mod_bvalues[ j ] = &a->a_vals[ j ];
+
+                               } else {
+                                       attrs[ i ]->mod_bvalues[ j ] = &mapping->dst;
+                               }
+                               j++;
+                       }
+                       attrs[ i ]->mod_bvalues[ j ] = NULL;
+
+               } else {
+                       /*
+                        * FIXME: dn-valued attrs should be rewritten
+                        * to allow their use in ACLs at the back-ldap
+                        * level.
+                        */
+                       if ( a->a_desc->ad_type->sat_syntax ==
                                slap_schema.si_syn_distinguishedName )
-               {
-                       (void)ldap_dnattr_rewrite( &dc, a->a_vals );
-               }
-
-               for ( j = 0; a->a_vals[ j ].bv_val; j++ );
-               attrs[ i ]->mod_vals.modv_bvals = ch_malloc((j+1)*sizeof(struct berval *));
-               for ( j = 0; a->a_vals[ j ].bv_val; j++ ) {
-                       attrs[ i ]->mod_vals.modv_bvals[ j ] = &a->a_vals[ j ];
+                       {
+                               (void)ldap_dnattr_rewrite( &dc, a->a_vals );
+                               if ( a->a_vals == NULL ) {
+                                       continue;
+                               }
+                       }
+
+                       for ( j = 0; !BER_BVISNULL( &a->a_vals[ j ] ); j++ )
+                               ;
+                       
+                       attrs[ i ]->mod_bvalues = ch_malloc( ( j + 1 ) * sizeof( struct berval * ) );
+                       for ( j = 0; !BER_BVISNULL( &a->a_vals[ j ] ); j++ ) {
+                               attrs[ i ]->mod_bvalues[ j ] = &a->a_vals[ j ];
+                       }
+                       attrs[ i ]->mod_bvalues[ j ] = NULL;
                }
-               attrs[ i ]->mod_vals.modv_bvals[ j ] = NULL;
                i++;
        }
        attrs[ i ] = NULL;
 
-       (void)ldap_add_ext_s( lc->mc_conns[ candidate ].msc_ld, mdn.bv_val,
+       rs->sr_err = ldap_add_ext_s( lc->mc_conns[ candidate ].msc_ld, mdn.bv_val,
                              attrs, NULL, NULL );
        for ( --i; i >= 0; --i ) {
-               free( attrs[ i ]->mod_vals.modv_bvals );
+               free( attrs[ i ]->mod_bvalues );
                free( attrs[ i ] );
        }
        free( attrs );
index cd82865fb9e23a52f94f5bde3d0ca9151545403a..3ead454bb45ad38946787d6598467ee48531a9cf 100644 (file)
@@ -85,15 +85,6 @@ typedef struct dncookie {
 #define META_BIND_NRETRIES     3
 #define META_BIND_TIMEOUT      1000
 
-int ldap_back_freeconn( Operation *op, struct ldapconn *lc );
-struct ldapconn *ldap_back_getconn(struct slap_op *op, struct slap_rep *rs);
-int ldap_back_dobind(struct ldapconn *lc, Operation *op, SlapReply *rs);
-int ldap_back_retry(struct ldapconn *lc, Operation *op, SlapReply *rs);
-int ldap_back_map_result(SlapReply *rs);
-int ldap_back_op_result(struct ldapconn *lc, Operation *op, SlapReply *rs,
-       ber_int_t msgid, int sendok);
-int    back_ldap_LTX_init_module(int argc, char *argv[]);
-
 int ldap_back_dn_massage(dncookie *dc, struct berval *dn,
        struct berval *res);
 
@@ -106,6 +97,8 @@ int mapping_cmp (const void *, const void *);
 int mapping_dup (void *, void *);
 
 void ldap_back_map_init ( struct ldapmap *lm, struct ldapmapping ** );
+int ldap_back_mapping ( struct ldapmap *map, struct berval *s,
+       struct ldapmapping **m, int remap );
 void ldap_back_map ( struct ldapmap *map, struct berval *s, struct berval *m,
        int remap );
 #define BACKLDAP_MAP   0
index 1459cef1a6c4eb8cdf21302cb9e85131eb273fed..9682b2d7af54245b1e87516301675f303b9f8874 100644 (file)
@@ -302,7 +302,9 @@ meta_back_db_config(
                li->network_timeout = atol(argv[ 1 ]);
 
        /* name to use for meta_back_group */
-       } else if ( strcasecmp( argv[ 0 ], "binddn" ) == 0 ) {
+       } else if ( strcasecmp( argv[ 0 ], "acl-authcDN" ) == 0
+                       || strcasecmp( argv[ 0 ], "binddn" ) == 0 )
+       {
                int             i = li->ntargets-1;
                struct berval   dn;
 
@@ -320,6 +322,14 @@ meta_back_db_config(
                        return 1;
                }
 
+               if ( strcasecmp( argv[ 0 ], "binddn" ) == 0 ) {
+                       fprintf( stderr, "%s: line %d: "
+                               "\"binddn\" statement is deprecated; "
+                               "use \"acl-authcDN\" instead\n",
+                               fname, lineno );
+                       /* FIXME: some day we'll need to throw an error */
+               }
+
                dn.bv_val = argv[ 1 ];
                dn.bv_len = strlen( argv[ 1 ] );
                if ( dnNormalize( 0, NULL, NULL, &dn, &li->targets[ i ]->mt_binddn,
@@ -332,7 +342,9 @@ meta_back_db_config(
                }
 
        /* password to use for meta_back_group */
-       } else if ( strcasecmp( argv[ 0 ], "bindpw" ) == 0 ) {
+       } else if ( strcasecmp( argv[ 0 ], "acl-passwd" ) == 0
+                       || strcasecmp( argv[ 0 ], "bindpw" ) == 0 )
+       {
                int             i = li->ntargets-1;
 
                if ( i < 0 ) {
@@ -348,6 +360,15 @@ meta_back_db_config(
                            fname, lineno );
                        return 1;
                }
+
+               if ( strcasecmp( argv[ 0 ], "bindpw" ) == 0 ) {
+                       fprintf( stderr, "%s: line %d: "
+                               "\"bindpw\" statement is deprecated; "
+                               "use \"acl-passwd\" instead\n",
+                               fname, lineno );
+                       /* FIXME: some day we'll need to throw an error */
+               }
+
                ber_str2bv( argv[ 1 ], 0L, 1, &li->targets[ i ]->mt_bindpw );
                
        /* save bind creds for referral rebinds? */
index a607369b7edbd2c5db1ad829f2dcb95fb3285e91..5021fc5c59f3da827b5b38e9e980811d4d4695d3 100644 (file)
@@ -109,12 +109,14 @@ ldap_back_map_init ( struct ldapmap *lm, struct ldapmapping **m )
        *m = mapping;
 }
 
-void
-ldap_back_map ( struct ldapmap *map, struct berval *s, struct berval *bv,
+int
+ldap_back_mapping ( struct ldapmap *map, struct berval *s, struct ldapmapping **m,
        int remap )
 {
        Avlnode *tree;
-       struct ldapmapping *mapping, fmapping;
+       struct ldapmapping fmapping;
+
+       assert( m );
 
        if ( remap == BACKLDAP_REMAP ) {
                tree = map->remap;
@@ -122,9 +124,23 @@ ldap_back_map ( struct ldapmap *map, struct berval *s, struct berval *bv,
                tree = map->map;
        }
 
-       BER_BVZERO( bv );
        fmapping.src = *s;
-       mapping = (struct ldapmapping *)avl_find( tree, (caddr_t)&fmapping, mapping_cmp );
+       *m = (struct ldapmapping *)avl_find( tree, (caddr_t)&fmapping, mapping_cmp );
+       if ( *m == NULL ) {
+               return map->drop_missing;
+       }
+
+       return 0;
+}
+
+void
+ldap_back_map ( struct ldapmap *map, struct berval *s, struct berval *bv,
+       int remap )
+{
+       struct ldapmapping *mapping;
+
+       BER_BVZERO( bv );
+       ( void )ldap_back_mapping( map, s, &mapping, remap );
        if ( mapping != NULL ) {
                if ( !BER_BVISNULL( &mapping->dst ) ) {
                        *bv = mapping->dst;
@@ -135,8 +151,6 @@ ldap_back_map ( struct ldapmap *map, struct berval *s, struct berval *bv,
        if ( !map->drop_missing ) {
                *bv = *s;
        }
-
-       return;
 }
 
 int
index 77e92da1455e791ed06a2c48168e3c4c19a2dc12..40709354a4dafc2f5c3de380e12d6132f4a6c29e 100644 (file)
@@ -134,15 +134,22 @@ meta_back_modify( Operation *op, SlapReply *rs )
                                mods[ i ].mod_bvalues =
                                        (struct berval **)ch_malloc( ( j + 1 ) *
                                        sizeof( struct berval * ) );
-                               for ( j = 0; !BER_BVISNULL( &ml->sml_values[ j ] ); j++ ) {
-                                       ldap_back_map( &li->targets[ candidate ]->mt_rwmap.rwm_oc,
-                                                       &ml->sml_values[ j ],
-                                                       &mapped, BACKLDAP_MAP );
-                                       if ( BER_BVISNULL( &mapped ) || BER_BVISEMPTY( &mapped ) )
-                                       {
-                                               continue;
+                               for ( j = 0; !BER_BVISNULL( &ml->sml_values[ j ] ); ) {
+                                       struct ldapmapping      *mapping;
+
+                                       ldap_back_mapping( &li->targets[ candidate ]->mt_rwmap.rwm_oc,
+                                                       &ml->sml_values[ j ], &mapping, BACKLDAP_MAP );
+
+                                       if ( mapping == NULL ) {
+                                               if ( li->targets[ candidate ]->mt_rwmap.rwm_oc.drop_missing ) {
+                                                       continue;
+                                               }
+                                               mods[ i ].mod_bvalues[ j ] = &ml->sml_values[ j ];
+
+                                       } else {
+                                               mods[ i ].mod_bvalues[ j ] = &mapping->dst;
                                        }
-                                       mods[ i ].mod_bvalues[ j ] = &mapped;
+                                       j++;
                                }
                                mods[ i ].mod_bvalues[ j ] = NULL;
 
index 5093d23edfc42ad830de19ed6a63a2ec04872f2f..76b448dd12f6d2232c3f9e01e26fc4d122932339 100644 (file)
@@ -14,7 +14,7 @@
  * <http://www.OpenLDAP.org/license.html>.
  */
 /* ACKNOWLEDGEMENTS:
- * This work was originally developed by Howard Chu for inclusion
+ * This work was originally developed by Hallvard Furuseth for inclusion
  * in OpenLDAP Software.
  */
 
index 80794716864cf1707d6fd5f8f53958bc37657700..49af9ed694e9513f419c4d4c07013c31f9b54146 100644 (file)
@@ -245,8 +245,9 @@ typedef struct {
  * in quotes.  This is especially true for those that do not
  * allow keywords used as aliases.
  */
-/* #define BACKSQL_ALIASING_QUOTE      '"' */
-/* #define BACKSQL_ALIASING_QUOTE      '\'' */
+#define BACKSQL_ALIASING_QUOTE ""
+/* #define BACKSQL_ALIASING_QUOTE      "\"" */
+/* #define BACKSQL_ALIASING_QUOTE      "'" */
 
 /*
  * API
index 678d106d411753a4d9bcb677e747bad58a7629f0..69c72e85c70ed20574274acc6ca80e14388de1f0 100644 (file)
@@ -456,8 +456,9 @@ backsql_db_open(
        bb.bb_val.bv_len = 0;
        bb.bb_len = 0;
        backsql_strfcat( &bb, "sb",
-                       "SELECT COUNT(distinct subordinates.id) FROM ldap_entries,ldap_entries subordinates WHERE subordinates.parent=ldap_entries.id AND ",
-
+                       "SELECT COUNT(distinct subordinates.id) "
+                       "FROM ldap_entries,ldap_entries " BACKSQL_ALIASING "subordinates "
+                       "WHERE subordinates.parent=ldap_entries.id AND ",
                        &bi->sql_children_cond );
        bi->sql_has_children_query = bb.bb_val.bv_val;
  
index 7d7be83a8f311bff975ea17b8e430fee9640865a..9ce43498d3f40329746ebbcf0bc027e3cb2f4d55 100644 (file)
@@ -105,35 +105,20 @@ backsql_make_attr_query(
 {
        struct berbuf   bb = BB_NULL;
 
-#ifdef BACKSQL_ALIASING_QUOTE
-       backsql_strfcat( &bb, "lblcbclblbcbl", 
-                       (ber_len_t)STRLENOF( "SELECT " ), "SELECT ", 
-                       &at_map->bam_sel_expr, 
-                       (ber_len_t)STRLENOF( " " BACKSQL_ALIASING ), " " BACKSQL_ALIASING, 
-                       BACKSQL_ALIASING_QUOTE,
-                       &at_map->bam_ad->ad_cname,
-                       BACKSQL_ALIASING_QUOTE,
-                       (ber_len_t)STRLENOF( " FROM " ), " FROM ", 
-                       &at_map->bam_from_tbls, 
-                       (ber_len_t)STRLENOF( " WHERE " ), " WHERE ", 
-                       &oc_map->bom_keytbl,
-                       '.', 
-                       &oc_map->bom_keycol,
-                       (ber_len_t)STRLENOF( "=?" ), "=?" );
-#else /* ! BACKSQL_ALIASING_QUOTE */
        backsql_strfcat( &bb, "lblblblbcbl", 
                        (ber_len_t)STRLENOF( "SELECT " ), "SELECT ", 
                        &at_map->bam_sel_expr, 
-                       (ber_len_t)STRLENOF( " " BACKSQL_ALIASING ), " " BACKSQL_ALIASING, 
+                       (ber_len_t)STRLENOF( " " BACKSQL_ALIASING BACKSQL_ALIASING_QUOTE ),
+                               " " BACKSQL_ALIASING BACKSQL_ALIASING_QUOTE, 
                        &at_map->bam_ad->ad_cname,
-                       (ber_len_t)STRLENOF( " FROM " ), " FROM ", 
+                       (ber_len_t)STRLENOF( BACKSQL_ALIASING_QUOTE " FROM " ),
+                               BACKSQL_ALIASING_QUOTE " FROM ", 
                        &at_map->bam_from_tbls, 
                        (ber_len_t)STRLENOF( " WHERE " ), " WHERE ", 
                        &oc_map->bom_keytbl,
                        '.', 
                        &oc_map->bom_keycol,
                        (ber_len_t)STRLENOF( "=?" ), "=?" );
-#endif /* ! BACKSQL_ALIASING_QUOTE */
 
        if ( !BER_BVISNULL( &at_map->bam_join_where ) ) {
                backsql_strfcat( &bb, "lb",
@@ -141,17 +126,12 @@ backsql_make_attr_query(
                                &at_map->bam_join_where );
        }
 
-#ifdef BACKSQL_ALIASING_QUOTE
-       backsql_strfcat( &bb, "lcbc", 
-                       (ber_len_t)STRLENOF( " ORDER BY " ), " ORDER BY ",
-                       BACKSQL_ALIASING_QUOTE,
+       backsql_strfcat( &bb, "lbl", 
+                       (ber_len_t)STRLENOF( " ORDER BY " BACKSQL_ALIASING_QUOTE ),
+                               " ORDER BY " BACKSQL_ALIASING_QUOTE,
                        &at_map->bam_sel_expr,
-                       BACKSQL_ALIASING_QUOTE );
-#else /* ! BACKSQL_ALIASING_QUOTE */
-       backsql_strfcat( &bb, "lb", 
-                       (ber_len_t)STRLENOF( " ORDER BY " ), " ORDER BY ",
-                       &at_map->bam_sel_expr );
-#endif /* ! BACKSQL_ALIASING_QUOTE */
+                       (ber_len_t)STRLENOF( BACKSQL_ALIASING_QUOTE ),
+                               BACKSQL_ALIASING_QUOTE );
 
        at_map->bam_query = bb.bb_val.bv_val;
 
index e99842c67f9bbc6a3190cbc0de3c64f167d6514d..0381f6974f554bfc58e839e3b2e48f98d22ed49f 100644 (file)
@@ -1289,21 +1289,13 @@ backsql_srch_query( backsql_srch_info *bsi, struct berval *query )
                                &bsi->bsi_oc->bom_oc->soc_cname,
                                '\'' );
        }
-#ifdef BACKSQL_ALIASING_QUOTE
-       backsql_strfcat( &bsi->bsi_sel, "lclcl",
-                       (ber_len_t)STRLENOF( " " BACKSQL_ALIASING ),
-                               " " BACKSQL_ALIASING,
-                       BACKSQL_ALIASING_QUOTE,
-                       (ber_len_t)STRLENOF( "objectClass" ),
-                               "objectClass",
-                       BACKSQL_ALIASING_QUOTE,
-                       (ber_len_t)STRLENOF( ",ldap_entries.dn " BACKSQL_ALIASING "dn" ),
-                               ",ldap_entries.dn " BACKSQL_ALIASING "dn" );
-#else /* ! BACKSQL_ALIASING_QUOTE */
        backsql_strfcat( &bsi->bsi_sel, "l",
-                       (ber_len_t)STRLENOF( " " BACKSQL_ALIASING "objectClass,ldap_entries.dn " BACKSQL_ALIASING "dn" ),
-                               " " BACKSQL_ALIASING "objectClass,ldap_entries.dn " BACKSQL_ALIASING "dn" );
-#endif /* ! BACKSQL_ALIASING_QUOTE */
+                       (ber_len_t)STRLENOF( " " BACKSQL_ALIASING 
+                                       BACKSQL_ALIASING_QUOTE "objectClass" BACKSQL_ALIASING_QUOTE 
+                                       ",ldap_entries.dn " BACKSQL_ALIASING BACKSQL_ALIASING_QUOTE "dn" BACKSQL_ALIASING_QUOTE ),
+                               " " BACKSQL_ALIASING 
+                                       BACKSQL_ALIASING_QUOTE "objectClass" BACKSQL_ALIASING_QUOTE
+                                       ",ldap_entries.dn " BACKSQL_ALIASING BACKSQL_ALIASING_QUOTE "dn" BACKSQL_ALIASING_QUOTE );
 
        backsql_strfcat( &bsi->bsi_from, "lb",
                        (ber_len_t)STRLENOF( " FROM ldap_entries," ),
index 13d715395ffc1b2f510270b1d3d9eef695fb1cee..61beb4f14a176808d4aafb595f1d440817c9e632 100644 (file)
@@ -126,7 +126,7 @@ backsql_Prepare( SQLHDBC dbh, SQLHSTMT *sth, char *query, int timeout )
                        0, 0, 0 );
 #endif /* BACKSQL_TRACE */
 
-       return SQLPrepare( *sth, query, SQL_NTS );
+       return SQLPrepare( *sth, (SQLCHAR *)query, SQL_NTS );
 }
 
 RETCODE
@@ -174,7 +174,7 @@ backsql_BindRowAsStrings( SQLHSTMT sth, BACKSQL_ROW_NTS *row )
                                        (SQLUINTEGER)( sizeof( colname ) - 1 ),
                                        &name_len, &col_type,
                                        &col_prec, &col_scale, &col_null );
-                       ber_str2bv( colname, 0, 1, &row->col_names[ i - 1 ] );
+                       ber_str2bv( (char *)colname, 0, 1, &row->col_names[ i - 1 ] );
 #ifdef BACKSQL_TRACE
                        Debug( LDAP_DEBUG_TRACE, "backsql_BindRowAsStrings: "
                                "col_name=%s, col_prec[%d]=%d\n",
index 641abc7eb1829c74708d386396057164c981eda8..ab4042e9264ca79e6a4bcf400ba32c9299f63b3c 100644 (file)
@@ -312,12 +312,7 @@ backsql_get_table_spec( char **p )
        }
 
        /* oracle doesn't understand "AS" :( and other RDBMSes don't need it */
-#ifdef BACKSQL_ALIASING_QUOTE
-       backsql_strfcat( &res, "scsc", " " BACKSQL_ALIASING,
-                       BACKSQL_ALIASING_QUOTE, s, BACKSQL_ALIASING_QUOTE );
-#else /* ! BACKSQL_ALIASING */
-       backsql_strcat( &res, " " BACKSQL_ALIASING, s, NULL );
-#endif /* ! BACKSQL_ALIASING */
+       backsql_strcat( &res, " " BACKSQL_ALIASING BACKSQL_ALIASING_QUOTE, s, BACKSQL_ALIASING_QUOTE, NULL );
 
        return res.bb_val.bv_val;
 }
index 9e63b862d1f60998b98233228bbaa422c6ef34ae..105dffe4f911dc34db780da903e811664d712d93 100644 (file)
@@ -1439,7 +1439,8 @@ backend_attribute(
 
                        rc = backend_operational( op, &rs );
 
-                       if ( rc == LDAP_SUCCESS ) {
+                       if ( rc == LDAP_SUCCESS && rs.sr_operational_attrs ) {
+                               freeattr = 1;
                                a = rs.sr_operational_attrs;
                        }
                }
index cbc6abd83e877698fc9db9577efe06e309daa172..c39caea9f64e37be8a26d0ead16d2685e5fa49bd 100644 (file)
@@ -464,7 +464,9 @@ fe_op_bind( Operation *op, SlapReply *rs )
                /* don't return referral for bind requests */
                /* noSuchObject is not allowed to be returned by bind */
                rs->sr_err = LDAP_INVALID_CREDENTIALS;
+               op->o_bd = frontendDB;
                send_ldap_result( op, rs );
+               op->o_bd = NULL;
                goto cleanup;
        }
 
index ed575fd1e84627994235bfb002dca151583996fc..d6596c248791d9102f28b092118375cd3566e4fb 100644 (file)
@@ -208,7 +208,9 @@ fe_op_compare( Operation *op, SlapReply *rs )
 
                rs->sr_err = LDAP_REFERRAL;
                if (!rs->sr_ref) rs->sr_ref = default_referral;
+               op->o_bd = frontendDB;
                send_ldap_result( op, rs );
+               op->o_bd = NULL;
 
                if (rs->sr_ref != default_referral) ber_bvarray_free( rs->sr_ref );
                rs->sr_err = 0;
index 17122347577d820caa66eb702dcd9c7c0724da1f..147400ee844a1c3defa750c9f9d7db82ba95bc23 100644 (file)
@@ -1714,10 +1714,12 @@ slapd_daemon_task(
 
                case 0:         /* timeout - let threads run */
                        ebadf = 0;
+#ifndef HAVE_YIELDING_SELECT
                        Debug( LDAP_DEBUG_CONNS, "daemon: select timeout - yielding\n",
                            0, 0, 0 );
 
                        ldap_pvt_thread_yield();
+#endif
                        continue;
 
                default:        /* something happened - deal with it */
@@ -1770,7 +1772,9 @@ slapd_daemon_task(
 
                /* bypass the following tests if no descriptors left */
                if ( ns <= 0 ) {
+#ifndef HAVE_YIELDING_SELECT
                        ldap_pvt_thread_yield();
+#endif
                        continue;
                }
 
@@ -1966,7 +1970,9 @@ slapd_daemon_task(
                }
 #endif /* SLAP_EVENTS_ARE_INDEXED */
 
+#ifndef HAVE_YIELDING_SELECT
                ldap_pvt_thread_yield();
+#endif
        }
 
        if( slapd_shutdown == 1 ) {
index a1004f7967a57a0160130e35eb52617ed0ef0e48..6762093c4ace96e27fa5dfb3184dfe79fa229f0d 100644 (file)
@@ -124,12 +124,16 @@ fe_op_delete( Operation *op, SlapReply *rs )
                if ( rs->sr_ref != NULL ) {
                        rs->sr_err = LDAP_REFERRAL;
 
+                       op->o_bd = frontendDB;
                        send_ldap_result( op, rs );
+                       op->o_bd = NULL;
 
                        if (rs->sr_ref != default_referral) ber_bvarray_free( rs->sr_ref );
                } else {
+                       op->o_bd = frontendDB;
                        send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
                                "no global superior knowledge" );
+                       op->o_bd = NULL;
                }
                goto cleanup;
        }
index 11dfa830229c7c618bb19ea9087c7d9b6ab5896a..bd0274fb3964132199a8d0a33e3feabaaf060578 100644 (file)
@@ -61,17 +61,24 @@ int entry_destroy(void)
 
 Entry *
 str2entry( char *s )
+{
+       return str2entry2( s, 1 );
+}
+
+Entry *
+str2entry2( char *s, int checkvals )
 {
        int rc;
        Entry           *e;
-       struct berval   type;
-       struct berval   vals[2];
-       struct berval   nvals[2], *nvalsp;
+       struct berval   *nvalsp;
+       struct berval   *type, *vals, *nvals;
+       char    *freeval;
        AttributeDescription *ad, *ad_prev;
        const char *text;
        char    *next;
        int             attr_cnt;
-       int             freeval;
+       int             i, lines;
+       Attribute       ahead, *atail;
 
        /*
         * LDIF is used as the string format.
@@ -105,75 +112,154 @@ str2entry( char *s )
        e->e_id = NOID;
 
        /* dn + attributes */
-       vals[1].bv_len = 0;
-       vals[1].bv_val = NULL;
-
+       atail = &ahead;
+       ahead.a_next = NULL;
        ad = NULL;
        ad_prev = NULL;
        attr_cnt = 0;
        next = s;
+
+       lines = ldif_countlines( s );
+       type = ch_calloc( 1, (lines+1)*3*sizeof(struct berval)+lines );
+       vals = type+lines+1;
+       nvals = vals+lines+1;
+       freeval = (char *)(nvals+lines+1);
+       i = -1;
+
+       /* parse into individual values, record DN */
        while ( (s = ldif_getline( &next )) != NULL ) {
+               int freev;
                if ( *s == '\n' || *s == '\0' ) {
                        break;
                }
+               i++;
 
-               if ( ldif_parse_line2( s, &type, vals, &freeval ) != 0 ) {
+               rc = ldif_parse_line2( s, type+i, vals+i, &freev );
+               freeval[i] = freev;
+               if ( rc ) {
                        Debug( LDAP_DEBUG_TRACE,
                                "<= str2entry NULL (parse_line)\n", 0, 0, 0 );
                        continue;
                }
 
-               if ( type.bv_len == dn_bv.bv_len &&
-                       strcasecmp( type.bv_val, dn_bv.bv_val ) == 0 ) {
+               if ( type[i].bv_len == dn_bv.bv_len &&
+                       strcasecmp( type[i].bv_val, dn_bv.bv_val ) == 0 ) {
 
                        if ( e->e_dn != NULL ) {
                                Debug( LDAP_DEBUG_ANY, "str2entry: "
                                        "entry %ld has multiple DNs \"%s\" and \"%s\"\n",
-                                       (long) e->e_id, e->e_dn, vals[0].bv_val );
-                               if ( freeval ) free( vals[0].bv_val );
-                               entry_free( e );
-                               return NULL;
+                                       (long) e->e_id, e->e_dn, vals[i].bv_val );
+                               goto fail;
                        }
 
-                       rc = dnPrettyNormal( NULL, &vals[0], &e->e_name, &e->e_nname, NULL );
-                       if ( freeval ) free( vals[0].bv_val );
+                       rc = dnPrettyNormal( NULL, &vals[i], &e->e_name, &e->e_nname, NULL );
                        if( rc != LDAP_SUCCESS ) {
                                Debug( LDAP_DEBUG_ANY, "str2entry: "
                                        "entry %ld has invalid DN \"%s\"\n",
-                                       (long) e->e_id, vals[0].bv_val, 0 );
-                               entry_free( e );
-                               return NULL;
+                                       (long) e->e_id, vals[i].bv_val, 0 );
+                               goto fail;
                        }
+                       if ( freeval[i] ) free( vals[i].bv_val );
+                       vals[i].bv_val = NULL;
+                       i--;
                        continue;
                }
+       }
+       lines = i+1;
 
-               ad_prev = ad;
-               ad = NULL;
-               rc = slap_bv2ad( &type, &ad, &text );
+       /* check to make sure there was a dn: line */
+       if ( BER_BVISNULL( &e->e_name )) {
+               Debug( LDAP_DEBUG_ANY, "str2entry: entry %ld has no dn\n",
+                       (long) e->e_id, 0, 0 );
+               goto fail;
+       }
 
-               if( rc != LDAP_SUCCESS ) {
-                       Debug( slapMode & SLAP_TOOL_MODE
-                               ? LDAP_DEBUG_ANY : LDAP_DEBUG_TRACE,
-                               "<= str2entry: str2ad(%s): %s\n", type.bv_val, text, 0 );
-                       if( slapMode & SLAP_TOOL_MODE ) {
-                               entry_free( e );
-                               if ( freeval ) free( vals[0].bv_val );
-                               return NULL;
+       /* Make sure all attributes with multiple values are contiguous */
+       if ( checkvals ) {
+               int j, k;
+               struct berval bv;
+               int fv;
+
+               for (i=0; i<lines; i++) {
+                       k = i;
+                       for ( j=i+1; j<lines; j++ ) {
+                               if ( bvmatch( type+i, type+j )) {
+                                       /* out of order, move intervening attributes down */
+                                       if ( j != k+1 ) {
+                                               int l;
+                                               bv = vals[j];
+                                               fv = freeval[j];
+                                               for ( l=j; l>k; l-- ) {
+                                                       type[l] = type[l-1];
+                                                       vals[l] = vals[l-1];
+                                                       freeval[l] = freeval[l-1];
+                                               }
+                                               type[l] = type[i];
+                                               vals[l] = bv;
+                                               freeval[l] = fv;
+                                       }
+                                       i = k = j;
+                               }
                        }
+               }
+       }
+
+       for ( i=0; i<=lines; i++ ) {
+               ad_prev = ad;
+               if ( !ad || ( i<lines && !bvmatch( type+i, &ad->ad_cname ))) {
+                       ad = NULL;
+                       rc = slap_bv2ad( type+i, &ad, &text );
 
-                       rc = slap_bv2undef_ad( &type, &ad, &text );
                        if( rc != LDAP_SUCCESS ) {
-                               Debug( LDAP_DEBUG_ANY,
-                                       "<= str2entry: str2undef_ad(%s): %s\n",
-                                               type.bv_val, text, 0 );
-                               entry_free( e );
-                               if ( freeval ) free( vals[0].bv_val );
-                               return NULL;
+                               Debug( slapMode & SLAP_TOOL_MODE
+                                       ? LDAP_DEBUG_ANY : LDAP_DEBUG_TRACE,
+                                       "<= str2entry: str2ad(%s): %s\n", type[i].bv_val, text, 0 );
+                               if( slapMode & SLAP_TOOL_MODE ) {
+                                       goto fail;
+                               }
+
+                               rc = slap_bv2undef_ad( type+i, &ad, &text );
+                               if( rc != LDAP_SUCCESS ) {
+                                       Debug( LDAP_DEBUG_ANY,
+                                               "<= str2entry: str2undef_ad(%s): %s\n",
+                                                       type[i].bv_val, text, 0 );
+                                       goto fail;
+                               }
                        }
                }
 
-               if ( ad != ad_prev ) {
+               if (( ad_prev && ad != ad_prev ) || ( i == lines )) {
+                       int j, k;
+                       atail->a_next = (Attribute *) ch_malloc( sizeof(Attribute) );
+                       atail = atail->a_next;
+                       atail->a_desc = ad_prev;
+                       atail->a_vals = ch_malloc( (attr_cnt + 1) * sizeof(struct berval));
+                       if( ad_prev->ad_type->sat_equality &&
+                               ad_prev->ad_type->sat_equality->smr_normalize )
+                               atail->a_nvals = ch_malloc( (attr_cnt + 1) * sizeof(struct berval));
+                       else
+                               atail->a_nvals = NULL;
+                       k = i - attr_cnt;
+                       for ( j=0; j<attr_cnt; j++ ) {
+                               if ( freeval[k] )
+                                       atail->a_vals[j] = vals[k];
+                               else
+                                       ber_dupbv( atail->a_vals+j, &vals[k] );
+                               vals[k].bv_val = NULL;
+                               if ( atail->a_nvals ) {
+                                       atail->a_nvals[j] = nvals[k];
+                                       nvals[k].bv_val = NULL;
+                               }
+                               k++;
+                       }
+                       BER_BVZERO( &atail->a_vals[j] );
+                       if ( atail->a_nvals ) {
+                               BER_BVZERO( &atail->a_nvals[j] );
+                       } else {
+                               atail->a_nvals = atail->a_vals;
+                       }
                        attr_cnt = 0;
+                       if ( i == lines ) break;
                }
 
                if( slapMode & SLAP_TOOL_MODE ) {
@@ -185,13 +271,13 @@ str2entry( char *s )
 
                        if( pretty ) {
                                rc = pretty( ad->ad_type->sat_syntax,
-                                       &vals[0], &pval, NULL );
+                                       &vals[i], &pval, NULL );
 
                        } else if( validate ) {
                                /*
                                 * validate value per syntax
                                 */
-                               rc = validate( ad->ad_type->sat_syntax, &vals[0] );
+                               rc = validate( ad->ad_type->sat_syntax, &vals[i] );
 
                        } else {
                                Debug( LDAP_DEBUG_ANY,
@@ -199,9 +285,7 @@ str2entry( char *s )
                                        "no validator for syntax %s\n", 
                                        ad->ad_cname.bv_val, attr_cnt,
                                        ad->ad_type->sat_syntax->ssyn_oid );
-                               entry_free( e );
-                               if ( freeval ) free( vals[0].bv_val );
-                               return NULL;
+                               goto fail;
                        }
 
                        if( rc != 0 ) {
@@ -210,21 +294,16 @@ str2entry( char *s )
                                        "for attributeType %s #%d (syntax %s)\n",
                                        ad->ad_cname.bv_val, attr_cnt,
                                        ad->ad_type->sat_syntax->ssyn_oid );
-                               entry_free( e );
-                               if ( freeval ) free( vals[0].bv_val );
-                               return NULL;
+                               goto fail;
                        }
 
                        if( pretty ) {
-                               if ( freeval ) free( vals[0].bv_val );
-                               vals[0] = pval;
-                               freeval = 1;
+                               if ( freeval[i] ) free( vals[i].bv_val );
+                               vals[i] = pval;
+                               freeval[i] = 1;
                        }
                }
 
-               nvalsp = NULL;
-               nvals[0].bv_val = NULL;
-
                if( ad->ad_type->sat_equality &&
                        ad->ad_type->sat_equality->smr_normalize )
                {
@@ -232,49 +311,34 @@ str2entry( char *s )
                                SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
                                ad->ad_type->sat_syntax,
                                ad->ad_type->sat_equality,
-                               &vals[0], &nvals[0], NULL );
+                               &vals[i], &nvals[i], NULL );
 
                        if( rc ) {
                                Debug( LDAP_DEBUG_ANY,
                                        "<= str2entry NULL (smr_normalize %d)\n", rc, 0, 0 );
-
-                               entry_free( e );
-                               if ( freeval ) free( vals[0].bv_val );
-                               return NULL;
+                               goto fail;
                        }
-
-                       nvals[1].bv_len = 0;
-                       nvals[1].bv_val = NULL;
-
-                       nvalsp = &nvals[0];
                }
 
-               rc = attr_merge( e, ad, vals, nvalsp );
-               if( rc != 0 ) {
-                       Debug( LDAP_DEBUG_ANY,
-                               "<= str2entry NULL (attr_merge)\n", 0, 0, 0 );
-                       entry_free( e );
-                       if ( freeval ) free( vals[0].bv_val );
-                       return( NULL );
-               }
-
-               if ( freeval ) free( vals[0].bv_val );
-               free( nvals[0].bv_val );
-
                attr_cnt++;
        }
 
-       /* check to make sure there was a dn: line */
-       if ( e->e_dn == NULL ) {
-               Debug( LDAP_DEBUG_ANY, "str2entry: entry %ld has no dn\n",
-                       (long) e->e_id, 0, 0 );
-               entry_free( e );
-               return NULL;
-       }
+       free( type );
+       atail->a_next = NULL;
+       e->e_attrs = ahead.a_next;
 
        Debug(LDAP_DEBUG_TRACE, "<= str2entry(%s) -> 0x%lx\n",
                e->e_dn, (unsigned long) e, 0 );
        return( e );
+
+fail:
+       for ( i=0; i<lines; i++ ) {
+               if ( freeval[i] ) free( vals[i].bv_val );
+               free( nvals[i].bv_val );
+       }
+       free( type );
+       entry_free( e );
+       return NULL;
 }
 
 
index 66ffc4f6413d12686585d7af68aa375906d8d5d9..5cc91fbb8c9e7603350abbc4b95cc6b50addb1d1 100644 (file)
@@ -342,7 +342,7 @@ static int test_mra_filter(
        }
 
        /* check attrs in DN AVAs if required */
-       if ( mra->ma_dnattrs ) {
+       if ( mra->ma_dnattrs && !BER_BVISEMPTY( &e->e_nname ) ) {
                LDAPDN          dn = NULL;
                int             iRDN, iAVA;
                int             rc;
index 88a120bd74fd9297b4517d54ee8c1ce43393bfdc..ea961ef57f7d3823746d468195d278009aad5cec 100644 (file)
@@ -316,12 +316,16 @@ fe_op_modify( Operation *op, SlapReply *rs )
 
                if (rs->sr_ref != NULL ) {
                        rs->sr_err = LDAP_REFERRAL;
+                       op->o_bd = frontendDB;
                        send_ldap_result( op, rs );
+                       op->o_bd = NULL;
 
                        if (rs->sr_ref != default_referral) ber_bvarray_free( rs->sr_ref );
                } else {
+                       op->o_bd = frontendDB;
                        send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
                                "no global superior knowledge" );
+                       op->o_bd = NULL;
                }
                goto cleanup;
        }
index 44f97d059e9ff8d81f2a59bc1ea0f60c906c8f2d..c9e6c02dac31bd97e23a3a9c6017c0579ff5c354 100644 (file)
@@ -238,12 +238,16 @@ fe_op_modrdn( Operation *op, SlapReply *rs )
 
                if ( rs->sr_ref != NULL ) {
                        rs->sr_err = LDAP_REFERRAL;
+                       op->o_bd = frontendDB;
                        send_ldap_result( op, rs );
+                       op->o_bd = NULL;
 
                        if (rs->sr_ref != default_referral) ber_bvarray_free( rs->sr_ref );
                } else {
+                       op->o_bd = frontendDB;
                        send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM,
                                "no global superior knowledge" );
+                       op->o_bd = NULL;
                }
                goto cleanup;
        }
index b7ac0ba4e0e6b1c0b2e127e1a21be9127e2dd08a..4afb1e17514476afc4b7b5725ceeb8b713c2af86 100644 (file)
@@ -119,6 +119,7 @@ struct oindexrec {
 };
 
 static Avlnode *oc_index = NULL;
+static Avlnode *oc_cache = NULL;
 static LDAP_SLIST_HEAD(OCList, slap_object_class) oc_list
        = LDAP_SLIST_HEAD_INITIALIZER(&oc_list);
 
@@ -161,9 +162,17 @@ oc_bvfind( struct berval *ocname )
 {
        struct oindexrec        *oir;
 
+       if ( oc_cache ) {
+               oir = avl_find( oc_cache, ocname, oc_index_name_cmp );
+               if ( oir ) return oir->oir_oc;
+       }
        oir = avl_find( oc_index, ocname, oc_index_name_cmp );
 
        if ( oir != NULL ) {
+               if ( at_oc_cache ) {
+                       avl_insert( &oc_cache, (caddr_t) oir,
+                               oc_index_cmp, avl_dup_error );
+               }
                return( oir->oir_oc );
        }
 
index f627cd9ad458f01df0d4ef3aca1a77ed62683dd4..d9ca042554945b0fef7b05c07cfd9004f7c6080a 100644 (file)
@@ -121,55 +121,97 @@ rwm_op_add( Operation *op, SlapReply *rs )
        /* Count number of attributes in entry */ 
        isupdate = be_shadow_update( op );
        for ( i = 0, ap = &op->oq_add.rs_e->e_attrs; *ap; ) {
-               struct berval   mapped;
                Attribute       *a;
 
-               if ( !isupdate && (*ap)->a_desc->ad_type->sat_no_user_mod ) {
+               if ( (*ap)->a_desc == slap_schema.si_ad_objectClass ||
+                               (*ap)->a_desc == slap_schema.si_ad_structuralObjectClass )
+               {
+                       int             j, last;
+
+                       for ( last = 0; !BER_BVISNULL( &(*ap)->a_vals[ last ] ); last++ )
+                                       /* count values */ ;
+                       last--;
+                       for ( j = 0; !BER_BVISNULL( &(*ap)->a_vals[ j ] ); j++ ) {
+                               struct ldapmapping      *mapping = NULL;
+
+                               ( void )rwm_mapping( &rwmap->rwm_oc, &(*ap)->a_vals[ j ],
+                                               &mapping, RWM_MAP );
+                               if ( mapping == NULL ) {
+                                       if ( rwmap->rwm_at.drop_missing ) {
+                                               /* FIXME: we allow to remove objectClasses as well;
+                                                * if the resulting entry is inconsistent, that's
+                                                * the relayed database's business...
+                                                */
+                                               ch_free( (*ap)->a_vals[ j ].bv_val );
+                                               if ( last > j ) {
+                                                       (*ap)->a_vals[ j ] = (*ap)->a_vals[ last ];
+                                               }
+                                               BER_BVZERO( &(*ap)->a_vals[ last ] );
+                                               last--;
+                                               j--;
+                                       }
+
+                               } else {
+                                       ch_free( (*ap)->a_vals[ j ].bv_val );
+                                       ber_dupbv( &(*ap)->a_vals[ j ], &mapping->m_dst );
+                               }
+                       }
+
+               } else if ( !isupdate && (*ap)->a_desc->ad_type->sat_no_user_mod ) {
                        goto next_attr;
-               }
 
-               rwm_map( &rwmap->rwm_at, &(*ap)->a_desc->ad_cname,
-                               &mapped, RWM_MAP );
-               if ( BER_BVISNULL( &mapped ) || BER_BVISEMPTY( &mapped ) ) {
-                       goto cleanup_attr;
-               }
+               } else {
+                       struct ldapmapping      *mapping = NULL;
 
-               if ( (*ap)->a_desc->ad_type->sat_syntax
-                               == slap_schema.si_syn_distinguishedName )
-               {
-                       /*
-                        * FIXME: rewrite could fail; in this case
-                        * the operation should give up, right?
-                        */
+                       ( void )rwm_mapping( &rwmap->rwm_at, &(*ap)->a_desc->ad_cname,
+                                       &mapping, RWM_MAP );
+                       if ( mapping == NULL ) {
+                               if ( rwmap->rwm_at.drop_missing ) {
+                                       goto cleanup_attr;
+                               }
+                       }
+
+                       if ( (*ap)->a_desc->ad_type->sat_syntax
+                                       == slap_schema.si_syn_distinguishedName )
+                       {
+                               /*
+                                * FIXME: rewrite could fail; in this case
+                                * the operation should give up, right?
+                                */
 #ifdef ENABLE_REWRITE
-                       rc = rwm_dnattr_rewrite( op, rs, "addAttrDN",
-                                       (*ap)->a_vals,
-                                       (*ap)->a_nvals ? &(*ap)->a_nvals : NULL );
+                               rc = rwm_dnattr_rewrite( op, rs, "addAttrDN",
+                                               (*ap)->a_vals,
+                                               (*ap)->a_nvals ? &(*ap)->a_nvals : NULL );
 #else /* ! ENABLE_REWRITE */
-                       rc = 1;
-                       rc = rwm_dnattr_rewrite( op, rs, &rc, (*ap)->a_vals,
-                                       (*ap)->a_nvals ? &(*ap)->a_nvals : NULL );
+                               rc = 1;
+                               rc = rwm_dnattr_rewrite( op, rs, &rc, (*ap)->a_vals,
+                                               (*ap)->a_nvals ? &(*ap)->a_nvals : NULL );
 #endif /* ! ENABLE_REWRITE */
-                       if ( rc ) {
-                               goto cleanup_attr;
-                       }
+                               if ( rc ) {
+                                       goto cleanup_attr;
+                               }
 
-               } else if ( (*ap)->a_desc == slap_schema.si_ad_ref ) {
+                       } else if ( (*ap)->a_desc == slap_schema.si_ad_ref ) {
 #ifdef ENABLE_REWRITE
-                       rc = rwm_referral_rewrite( op, rs, "referralAttrDN",
-                                       (*ap)->a_vals,
-                                       (*ap)->a_nvals ? &(*ap)->a_nvals : NULL );
+                               rc = rwm_referral_rewrite( op, rs, "referralAttrDN",
+                                               (*ap)->a_vals,
+                                               (*ap)->a_nvals ? &(*ap)->a_nvals : NULL );
 #else /* ! ENABLE_REWRITE */
-                       rc = 1;
-                       rc = rwm_referral_rewrite( op, rs, &rc, (*ap)->a_vals,
-                                       (*ap)->a_nvals ? &(*ap)->a_nvals : NULL );
+                               rc = 1;
+                               rc = rwm_referral_rewrite( op, rs, &rc, (*ap)->a_vals,
+                                               (*ap)->a_nvals ? &(*ap)->a_nvals : NULL );
 #endif /* ! ENABLE_REWRITE */
-                       if ( rc != LDAP_SUCCESS ) {
-                               goto cleanup_attr;
+                               if ( rc != LDAP_SUCCESS ) {
+                                       goto cleanup_attr;
+                               }
+                       }
+               
+                       if ( mapping != NULL ) {
+                               assert( mapping->m_dst_ad );
+                               (*ap)->a_desc = mapping->m_dst_ad;
                        }
                }
 
-
 next_attr:;
                ap = &(*ap)->a_next;
                continue;
@@ -281,6 +323,7 @@ rwm_op_compare( Operation *op, SlapReply *rs )
                        }
 
                } else {
+                       assert( mapping->m_dst_ad );
                        ad = mapping->m_dst_ad;
                }
 
@@ -360,65 +403,61 @@ rwm_op_modify( Operation *op, SlapReply *rs )
 
        isupdate = be_shadow_update( op );
        for ( mlp = &op->oq_modify.rs_modlist; *mlp; ) {
-               int             is_oc = 0;
-               Modifications   *ml;
-
-               if ( !isupdate && (*mlp)->sml_desc->ad_type->sat_no_user_mod  ) {
-                       goto next_mod;
-               }
+               int                     is_oc = 0;
+               Modifications           *ml;
+               struct ldapmapping      *mapping = NULL;
 
                if ( (*mlp)->sml_desc == slap_schema.si_ad_objectClass 
-                               || (*mlp)->sml_desc == slap_schema.si_ad_structuralObjectClass ) {
+                               || (*mlp)->sml_desc == slap_schema.si_ad_structuralObjectClass )
+               {
                        is_oc = 1;
 
+               } else if ( !isupdate && (*mlp)->sml_desc->ad_type->sat_no_user_mod  ) {
+                       goto next_mod;
+
                } else {
-                       struct ldapmapping      *m;
                        int                     drop_missing;
 
-                       drop_missing = rwm_mapping( &rwmap->rwm_at, &(*mlp)->sml_desc->ad_cname, &m, RWM_MAP );
-                       if ( drop_missing || ( m != NULL && BER_BVISNULL( &m->m_dst ) ) )
+                       drop_missing = rwm_mapping( &rwmap->rwm_at,
+                                       &(*mlp)->sml_desc->ad_cname,
+                                       &mapping, RWM_MAP );
+                       if ( drop_missing || ( mapping != NULL && BER_BVISNULL( &mapping->m_dst ) ) )
                        {
                                goto cleanup_mod;
                        }
-
-                       if ( m ) {
-                               /* use new attribute description */
-                               assert( m->m_dst_ad );
-                               (*mlp)->sml_desc = m->m_dst_ad;
-                       }
                }
 
                if ( (*mlp)->sml_values != NULL ) {
                        if ( is_oc ) {
                                int     last, j;
 
-                               for ( last = 0; !BER_BVISNULL( &(*mlp)->sml_values[last] ); last++ )
+                               for ( last = 0; !BER_BVISNULL( &(*mlp)->sml_values[ last ] ); last++ )
                                        /* count values */ ;
                                last--;
 
-                               for ( j = 0; !BER_BVISNULL( &(*mlp)->sml_values[j] ); j++ ) {
-                                       struct berval   mapped = BER_BVNULL;
-
-                                       rwm_map( &rwmap->rwm_oc,
-                                                       &(*mlp)->sml_values[j],
-                                                       &mapped, RWM_MAP );
-                                       if ( BER_BVISNULL( &mapped ) || BER_BVISEMPTY( &mapped ) ) {
-                                               /* FIXME: we allow to remove objectClasses as well;
-                                                * if the resulting entry is inconsistent, that's
-                                                * the relayed database's business...
-                                                */
-#if 0
-                                               goto cleanup_mod;
-#endif
-                                               if ( last > j ) {
-                                                       (*mlp)->sml_values[j] = (*mlp)->sml_values[last];
-                                                       BER_BVZERO( &(*mlp)->sml_values[last] );
+                               for ( j = 0; !BER_BVISNULL( &(*mlp)->sml_values[ j ] ); j++ ) {
+                                       struct ldapmapping      *mapping = NULL;
+
+                                       ( void )rwm_mapping( &rwmap->rwm_oc, &(*mlp)->sml_values[ j ],
+                                                       &mapping, RWM_MAP );
+                                       if ( mapping == NULL ) {
+                                               if ( rwmap->rwm_at.drop_missing ) {
+                                                       /* FIXME: we allow to remove objectClasses as well;
+                                                        * if the resulting entry is inconsistent, that's
+                                                        * the relayed database's business...
+                                                        */
+                                                       ch_free( (*mlp)->sml_values[ j ].bv_val );
+                                                       if ( last > j ) {
+                                                               (*mlp)->sml_values[ j ] = (*mlp)->sml_values[ last ];
+                                                       }
+                                                       BER_BVZERO( &(*mlp)->sml_values[ last ] );
+                                                       last--;
+                                                       j--;
                                                }
-                                               last--;
-
+       
                                        } else {
-                                               ch_free( (*mlp)->sml_values[j].bv_val );
-                                               ber_dupbv( &(*mlp)->sml_values[j], &mapped );
+                                               ch_free( (*mlp)->sml_values[ j ].bv_val );
+                                               ber_dupbv( &(*mlp)->sml_values[ j ], &mapping->m_dst );
                                        }
                                }
 
@@ -461,6 +500,12 @@ rwm_op_modify( Operation *op, SlapReply *rs )
                }
 
 next_mod:;
+               if ( mapping != NULL ) {
+                       /* use new attribute description */
+                       assert( mapping->m_dst_ad );
+                       (*mlp)->sml_desc = mapping->m_dst_ad;
+               }
+
                mlp = &(*mlp)->sml_next;
                continue;
 
@@ -777,7 +822,7 @@ rwm_attrs( Operation *op, SlapReply *rs, Attribute** a_first )
         * about duplicate values?) */
        isupdate = be_shadow_update( op );
        for ( ap = a_first; *ap; ) {
-               struct ldapmapping      *m;
+               struct ldapmapping      *mapping;
                int                     drop_missing;
                int                     last;
                Attribute               *a;
@@ -786,10 +831,28 @@ rwm_attrs( Operation *op, SlapReply *rs, Attribute** a_first )
                {
                        /* go on */ ;
                        
-               } else if ( op->ors_attrs != NULL && 
-                               !SLAP_USERATTRS( rs->sr_attr_flags ) && 
-                               !ad_inlist( (*ap)->a_desc, op->ors_attrs ) )
-               {
+               } else {
+                       drop_missing = rwm_mapping( &rwmap->rwm_at,
+                                       &(*ap)->a_desc->ad_cname, &mapping, RWM_REMAP );
+                       if ( drop_missing || ( mapping != NULL && BER_BVISEMPTY( &mapping->m_dst ) ) )
+                       {
+                               goto cleanup_attr;
+                       }
+
+                       if ( mapping != NULL ) {
+                               (*ap)->a_desc = mapping->m_dst_ad;
+                       }
+
+                       if ( op->ors_attrs != NULL && 
+                                       !SLAP_USERATTRS( rs->sr_attr_flags ) &&
+                                       !ad_inlist( (*ap)->a_desc, op->ors_attrs ) )
+                       {
+                               goto cleanup_attr;
+                       }
+               }
+
+               if ( (*ap)->a_desc == slap_schema.si_ad_entryDN ) {
+                       /* will be generated by frontend */
                        goto cleanup_attr;
                }
 
@@ -799,12 +862,6 @@ rwm_attrs( Operation *op, SlapReply *rs, Attribute** a_first )
                        goto next_attr;
                }
 
-               drop_missing = rwm_mapping( &rwmap->rwm_at,
-                               &(*ap)->a_desc->ad_cname, &m, RWM_REMAP );
-               if ( drop_missing || ( m != NULL && BER_BVISEMPTY( &m->m_dst ) ) ) {
-                       goto cleanup_attr;
-               }
-
                for ( last = 0; !BER_BVISNULL( &(*ap)->a_vals[last] ); last++ )
                        /* just count */ ;
 
@@ -877,10 +934,10 @@ rwm_attrs( Operation *op, SlapReply *rs, Attribute** a_first )
                        }
                }
 
-               if ( m != NULL ) {
+               if ( mapping != NULL ) {
                        /* rewrite the attribute description */
-                       assert( m->m_dst_ad );
-                       (*ap)->a_desc = m->m_dst_ad;
+                       assert( mapping->m_dst_ad );
+                       (*ap)->a_desc = mapping->m_dst_ad;
                }
 
 next_attr:;
index 931687b70d9a900c91d678110030ccbf592c7c82..dd7203c3cdc06ecfa61e7eb77e004df9dc3c5c1a 100644 (file)
@@ -16,7 +16,7 @@
  * <http://www.OpenLDAP.org/license.html>.
  */
 /* ACKNOWLEDGEMENTS:
- * This work was initially developed by the Howard Chu for inclusion
+ * This work was initially developed by Howard Chu for inclusion
  * in OpenLDAP Software and subsequently enhanced by Pierangelo
  * Masarati.
  */
index 966266162264b884ee2434af2c49d10a8747715c..e551f3568a30d9cca49a96cec965b4c5893231d9 100644 (file)
@@ -321,40 +321,46 @@ rwm_map_attrs(
                return LDAP_SUCCESS;
        }
 
-       for ( i = 0; !BER_BVISNULL( &an[i].an_name ); i++ ) {
+       for ( i = 0; !BER_BVISNULL( &an[ i ].an_name ); i++ ) {
                /*  */
        }
 
        na = (char **)ch_calloc( i + 1, sizeof( char * ) );
-       if (na == NULL) {
+       if ( na == NULL ) {
                *mapped_attrs = NULL;
                return LDAP_NO_MEMORY;
        }
 
        for ( i = j = 0; !BER_BVISNULL( &an[i].an_name ); i++ ) {
-               struct ldapmapping      *m;
+               struct ldapmapping      *mapping;
                
-               if ( rwm_mapping( at_map, &an[i].an_name, &m, remap ) ) {
+               if ( rwm_mapping( at_map, &an[i].an_name, &mapping, remap ) ) {
                        continue;
                }
 
-               if ( !m || ( m && !BER_BVISNULL( &m->m_dst ) ) ) {
-                       na[j++] = m->m_dst.bv_val;
+               if ( !mapping ) {
+                       na[ j++ ] = an[ i ].an_name.bv_val;
+                       
+               } else if ( !BER_BVISNULL( &mapping->m_dst ) ) {
+                       na[ j++ ] = mapping->m_dst.bv_val;
                }
        }
+
        if ( j == 0 && i != 0 ) {
-               na[j++] = LDAP_NO_ATTRS;
+               na[ j++ ] = LDAP_NO_ATTRS;
        }
-       na[j] = NULL;
+
+       na[ j ] = NULL;
 
        *mapped_attrs = na;
+
        return LDAP_SUCCESS;
 }
 
 static int
 map_attr_value(
                dncookie                *dc,
-               AttributeDescription    *ad,
+               AttributeDescription    **adp,
                struct berval           *mapped_attr,
                struct berval           *value,
                struct berval           *mapped_value,
@@ -362,65 +368,72 @@ map_attr_value(
 {
        struct berval           vtmp = BER_BVNULL;
        int                     freeval = 0;
+       AttributeDescription    *ad = *adp;
+       struct ldapmapping      *mapping = NULL;
 
-       rwm_map( &dc->rwmap->rwm_at, &ad->ad_cname, mapped_attr, remap );
-       if ( BER_BVISNULL( mapped_attr ) || BER_BVISEMPTY( mapped_attr ) ) {
-               /*
-                * FIXME: are we sure we need to search oc_map if at_map fails?
-                */
-               rwm_map( &dc->rwmap->rwm_oc, &ad->ad_cname, mapped_attr, remap );
-               if ( BER_BVISNULL( mapped_attr ) || BER_BVISEMPTY( mapped_attr ) )
-               {
-                       *mapped_attr = ad->ad_cname;
+       rwm_mapping( &dc->rwmap->rwm_at, &ad->ad_cname, &mapping, remap );
+       if ( mapping == NULL ) {
+               if ( dc->rwmap->rwm_at.drop_missing ) {
+                       return -1;
                }
-       }
 
-       if ( value == NULL ) {
-               return 0;
+               *mapped_attr = ad->ad_cname;
+
+       } else {
+               *mapped_attr = mapping->m_dst;
        }
 
-       if ( ad->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName )
-       {
-               dncookie        fdc = *dc;
-               int             rc;
+       if ( value != NULL ) {
+               assert( mapped_value != NULL );
+
+               if ( ad->ad_type->sat_syntax == slap_schema.si_syn_distinguishedName )
+               {
+                       dncookie        fdc = *dc;
+                       int             rc;
 
 #ifdef ENABLE_REWRITE
-               fdc.ctx = "searchFilterAttrDN";
+                       fdc.ctx = "searchFilterAttrDN";
 #endif /* ENABLE_REWRITE */
 
-               vtmp = *value;
-               rc = rwm_dn_massage_normalize( &fdc, value, &vtmp );
-               switch ( rc ) {
-               case LDAP_SUCCESS:
-                       if ( vtmp.bv_val != value->bv_val ) {
-                               freeval = 1;
-                       }
-                       break;
+                       vtmp = *value;
+                       rc = rwm_dn_massage_normalize( &fdc, value, &vtmp );
+                       switch ( rc ) {
+                       case LDAP_SUCCESS:
+                               if ( vtmp.bv_val != value->bv_val ) {
+                                       freeval = 1;
+                               }
+                               break;
                
-               case LDAP_UNWILLING_TO_PERFORM:
-               case LDAP_OTHER:
-               default:
-                       return -1;
-               }
+                       case LDAP_UNWILLING_TO_PERFORM:
+                       case LDAP_OTHER:
+                       default:
+                               return -1;
+                       }
 
-       } else if ( ad == slap_schema.si_ad_objectClass
-                       || ad == slap_schema.si_ad_structuralObjectClass )
-       {
-               rwm_map( &dc->rwmap->rwm_oc, value, &vtmp, remap );
-               if ( BER_BVISNULL( &vtmp ) || BER_BVISEMPTY( &vtmp ) ) {
+               } else if ( ad == slap_schema.si_ad_objectClass
+                               || ad == slap_schema.si_ad_structuralObjectClass )
+               {
+                       rwm_map( &dc->rwmap->rwm_oc, value, &vtmp, remap );
+                       if ( BER_BVISNULL( &vtmp ) || BER_BVISEMPTY( &vtmp ) ) {
+                               vtmp = *value;
+                       }
+               
+               } else {
                        vtmp = *value;
                }
-               
-       } else {
-               vtmp = *value;
-       }
 
-       filter_escape_value( &vtmp, mapped_value );
+               filter_escape_value( &vtmp, mapped_value );
 
-       if ( freeval ) {
-               ch_free( vtmp.bv_val );
+               if ( freeval ) {
+                       ch_free( vtmp.bv_val );
+               }
        }
        
+       if ( mapping != NULL ) {
+               assert( mapping->m_dst_ad != NULL );
+               *adp = mapping->m_dst_ad;
+       }
+
        return 0;
 }
 
@@ -451,7 +464,7 @@ rwm_int_filter_map_rewrite(
 
        switch ( f->f_choice ) {
        case LDAP_FILTER_EQUALITY:
-               if ( map_attr_value( dc, f->f_av_desc, &atmp,
+               if ( map_attr_value( dc, &f->f_av_desc, &atmp,
                                        &f->f_av_value, &vtmp, RWM_MAP ) )
                {
                        return -1;
@@ -467,7 +480,7 @@ rwm_int_filter_map_rewrite(
                break;
 
        case LDAP_FILTER_GE:
-               if ( map_attr_value( dc, f->f_av_desc, &atmp,
+               if ( map_attr_value( dc, &f->f_av_desc, &atmp,
                                        &f->f_av_value, &vtmp, RWM_MAP ) )
                {
                        return -1;
@@ -483,7 +496,7 @@ rwm_int_filter_map_rewrite(
                break;
 
        case LDAP_FILTER_LE:
-               if ( map_attr_value( dc, f->f_av_desc, &atmp,
+               if ( map_attr_value( dc, &f->f_av_desc, &atmp,
                                        &f->f_av_value, &vtmp, RWM_MAP ) )
                {
                        return -1;
@@ -499,7 +512,7 @@ rwm_int_filter_map_rewrite(
                break;
 
        case LDAP_FILTER_APPROX:
-               if ( map_attr_value( dc, f->f_av_desc, &atmp,
+               if ( map_attr_value( dc, &f->f_av_desc, &atmp,
                                        &f->f_av_value, &vtmp, RWM_MAP ) )
                {
                        return -1;
@@ -515,7 +528,7 @@ rwm_int_filter_map_rewrite(
                break;
 
        case LDAP_FILTER_SUBSTRINGS:
-               if ( map_attr_value( dc, f->f_sub_desc, &atmp,
+               if ( map_attr_value( dc, &f->f_sub_desc, &atmp,
                                        NULL, NULL, RWM_MAP ) )
                {
                        return -1;
@@ -577,7 +590,7 @@ rwm_int_filter_map_rewrite(
                break;
 
        case LDAP_FILTER_PRESENT:
-               if ( map_attr_value( dc, f->f_desc, &atmp,
+               if ( map_attr_value( dc, &f->f_desc, &atmp,
                                        NULL, NULL, RWM_MAP ) )
                {
                        return -1;
@@ -621,7 +634,7 @@ rwm_int_filter_map_rewrite(
 
        case LDAP_FILTER_EXT: {
                if ( f->f_mr_desc ) {
-                       if ( map_attr_value( dc, f->f_mr_desc, &atmp,
+                       if ( map_attr_value( dc, &f->f_mr_desc, &atmp,
                                                &f->f_mr_value, &vtmp, RWM_MAP ) )
                        {
                                return -1;
index 2f91d7928f2deb98a6a1a3a35ddcfe6020a60585..bacc1b3772468e7a63dd0e8cd1a3068d617eef70 100644 (file)
@@ -144,6 +144,7 @@ LDAP_SLAPD_F (int) slap_entry2mods LDAP_P(( Entry *e,
 /*
  * at.c
  */
+LDAP_SLAPD_V(int) at_oc_cache;
 LDAP_SLAPD_F (void) at_config LDAP_P((
        const char *fname, int lineno,
        int argc, char **argv ));
@@ -626,6 +627,7 @@ LDAP_SLAPD_V (const Entry) slap_entry_root;
 LDAP_SLAPD_F (int) entry_destroy LDAP_P((void));
 
 LDAP_SLAPD_F (Entry *) str2entry LDAP_P(( char *s ));
+LDAP_SLAPD_F (Entry *) str2entry2 LDAP_P(( char        *s, int checkvals ));
 LDAP_SLAPD_F (char *) entry2str LDAP_P(( Entry *e, int *len ));
 
 LDAP_SLAPD_F (void) entry_flatsize LDAP_P((
index 1c0c1339c6c87d752f12b2641748b26363bbc916..28e44248cd71df6f374ff5eb30119c134fd7d86f 100644 (file)
@@ -1101,8 +1101,7 @@ void slap_sasl2dn( Operation *opx,
                "converting SASL name %s to a DN\n",
                saslname->bv_val, 0,0 );
 
-       sasldn->bv_val = NULL;
-       sasldn->bv_len = 0;
+       BER_BVZERO( sasldn );
        cb.sc_private = sasldn;
 
        /* Convert the SASL name into a minimal URI */
index 958a8ab40b028aa93a3d323e3f7c4555a1288a6a..0c0edfd4f44b8b2b9b4ab5aa1e72c7ee2bbab753 100644 (file)
@@ -11,7 +11,7 @@ dyngroup.schema                       Dynamic Group (experimental)
 inetorgperson.schema    InetOrgPerson
 java.schema             Java Object
 misc.schema             Miscellaneous Schema (experimental)
-nis.schema              Network Information Service
+nis.schema              Network Information Service (experimental)
 openldap.schema         OpenLDAP Project (FYI)
 ppolicy.schema          Password Policy Schema (work in progress)
 
index 283fb6dfcf4bd8e67eb30dff64d8468db4b639e6..a162b20068be6af2607b28996036f4123a27a173 100644 (file)
@@ -353,7 +353,9 @@ fe_op_search( Operation *op, SlapReply *rs )
 
                if (!rs->sr_ref) rs->sr_ref = default_referral;
                rs->sr_err = LDAP_REFERRAL;
+               op->o_bd = frontendDB;
                send_ldap_result( op, rs );
+               op->o_bd = NULL;
 
                if (rs->sr_ref != default_referral)
                ber_bvarray_free( rs->sr_ref );
index 5cc6f3274ad3497936d451c5e6f22539d40e6b32..79d3a38c1302db62b3bfab3b279f4643aac095b4 100644 (file)
@@ -1389,6 +1389,7 @@ LDAP_SLAPD_V (int) slapMode;
 #define SLAP_TRUNCATE_MODE     0x0100
 #define        SLAP_TOOL_READMAIN      0x0200
 #define        SLAP_TOOL_READONLY      0x0400
+#define        SLAP_TOOL_QUICK         0x0800
 
 struct slap_replica_info {
        char *ri_host;                          /* supersedes be_replica */
index 788100e615605c8b0d9a4f94986762ede874844a..1d45cd8a736fc660da063ce1771355700b370a35 100644 (file)
 
 static char csnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE ];
 static char maxcsnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE ];
+static const char *progname = "slapadd";
+
+static ldap_pvt_thread_cond_t put_cond1;
+static ldap_pvt_thread_cond_t put_cond2;
+static ldap_pvt_thread_mutex_t put_mutex1;
+static ldap_pvt_thread_mutex_t put_mutex2;
+static Entry *put_e;
+static struct berval bvtext;
+static int put_lineno;
+static int put_rc;
+
+static int use_thread = 0;     /*FIXME need a new switch for this */
+
+static void *do_put(void *ptr)
+{
+       ID id;
+       Entry *e;
+       int lineno;
+
+       ldap_pvt_thread_mutex_lock( &put_mutex1 );
+       do {
+               ldap_pvt_thread_cond_wait( &put_cond1, &put_mutex1 );
+               if ( put_rc ) {
+                       break;
+               }
+               ldap_pvt_thread_mutex_lock( &put_mutex2 );
+               ldap_pvt_thread_cond_signal( &put_cond2 );
+               ldap_pvt_thread_mutex_unlock( &put_mutex2 );
+
+               e = put_e;
+               lineno = put_lineno;
+
+               if ( !dryrun ) {
+                       id = be->be_entry_put( be, e, &bvtext );
+                       if( id == NOID ) {
+                               fprintf( stderr, "%s: could not add entry dn=\"%s\" "
+                                                                "(line=%d): %s\n", progname, e->e_dn,
+                                                                lineno, bvtext.bv_val );
+                               entry_free( e );
+                               if ( continuemode ) continue;
+                               put_rc = EXIT_FAILURE;
+                               break;
+                       }
+               }
+
+               if ( verbose ) {
+                       if ( dryrun ) {
+                               fprintf( stderr, "added: \"%s\"\n",
+                                       e->e_dn );
+                       } else {
+                               fprintf( stderr, "added: \"%s\" (%08lx)\n",
+                                       e->e_dn, (long) id );
+                       }
+               }
+
+               entry_free( e );
+
+       } while (1);
+       ldap_pvt_thread_mutex_unlock( &put_mutex1 );
+}
 
 int
 slapadd( int argc, char **argv )
@@ -52,7 +112,6 @@ slapadd( int argc, char **argv )
        const char *text;
        char textbuf[SLAP_TEXT_BUFLEN] = { '\0' };
        size_t textlen = sizeof textbuf;
-       const char *progname = "slapadd";
 
        struct berval csn;
        struct berval maxcsn;
@@ -61,9 +120,10 @@ slapadd( int argc, char **argv )
        Entry *ctxcsn_e;
        ID      ctxcsn_id, id;
        int ret;
-       struct berval bvtext;
-       int i;
+       int i, checkvals;
        struct berval mc;
+       ldap_pvt_thread_t put_tid;
+
        slap_tool_init( progname, SLAPADD, argc, argv );
 
        if( !be->be_entry_open ||
@@ -80,6 +140,23 @@ slapadd( int argc, char **argv )
                }
        }
 
+       checkvals = (slapMode & SLAP_TOOL_QUICK) ? 0 : 1;
+
+       if ( use_thread ) {
+               ldap_pvt_thread_initialize();
+               ldap_pvt_thread_cond_init( &put_cond1 );
+               ldap_pvt_thread_cond_init( &put_cond2 );
+               ldap_pvt_thread_mutex_init( &put_mutex1 );
+               ldap_pvt_thread_mutex_init( &put_mutex2 );
+               rc = ldap_pvt_thread_create( &put_tid, 0, do_put, NULL );
+               if ( rc ) {
+                       fprintf( stderr, "%s: could not create thread.\n",
+                               progname );
+                       exit( EXIT_FAILURE );
+               }
+               ldap_pvt_thread_mutex_lock( &put_mutex2 );
+       }
+
        lmax = 0;
        lineno = 0;
 
@@ -95,7 +172,7 @@ slapadd( int argc, char **argv )
        }
 
        while( ldif_read_record( ldiffp, &lineno, &buf, &lmax ) ) {
-               Entry *e = str2entry( buf );
+               Entry *e = str2entry2( buf, checkvals );
 
                /*
                 * Initialize text buffer
@@ -292,6 +369,22 @@ slapadd( int argc, char **argv )
                        }
                }
 
+               if ( use_thread ) {
+                       ldap_pvt_thread_mutex_lock( &put_mutex1 );
+                       if (put_rc) {
+                               rc = put_rc;
+                               ldap_pvt_thread_mutex_unlock( &put_mutex1 );
+                               break;
+                       }
+                       put_e = e;
+                       put_lineno = lineno;
+                       ldap_pvt_thread_cond_signal( &put_cond1 );
+                       ldap_pvt_thread_mutex_unlock( &put_mutex1 );
+                       /* Make sure writer wakes up */
+                       ldap_pvt_thread_cond_wait( &put_cond2, &put_mutex2 );
+                       continue;
+               }
+
                if ( !dryrun ) {
                        id = be->be_entry_put( be, e, &bvtext );
                        if( id == NOID ) {
@@ -315,15 +408,30 @@ slapadd( int argc, char **argv )
                        }
                }
 
-done:;
                entry_free( e );
        }
 
+       if ( use_thread ) {
+               ldap_pvt_thread_mutex_unlock( &put_mutex2 );
+               ldap_pvt_thread_mutex_lock( &put_mutex1 );
+               /* Tell child thread to stop if it hasn't aborted */
+               if ( !put_rc ) {
+                       put_rc = EXIT_FAILURE;
+                       ldap_pvt_thread_cond_signal( &put_cond1 );
+               }
+               ldap_pvt_thread_mutex_unlock( &put_mutex1 );
+               ldap_pvt_thread_join( put_tid, NULL );
+               ldap_pvt_thread_mutex_destroy( &put_mutex2 );
+               ldap_pvt_thread_mutex_destroy( &put_mutex1 );
+               ldap_pvt_thread_cond_destroy( &put_cond2 );
+               ldap_pvt_thread_cond_destroy( &put_cond1 );
+       }
+
        bvtext.bv_len = textlen;
        bvtext.bv_val = textbuf;
        bvtext.bv_val[0] = '\0';
 
-       if ( update_ctxcsn && !dryrun && maxcsn.bv_len ) {
+       if ( rc == EXIT_SUCCESS && update_ctxcsn && !dryrun && maxcsn.bv_len ) {
                ctxcsn_id = be->be_dn2id_get( be, be->be_nsuffix );
                if ( ctxcsn_id == NOID ) {
                        fprintf( stderr, "%s: context entry is missing\n", progname );
index bafe34dafe204ef6e457df07a676b956d9ef4087..c768f52f3ec7463c6dc81de01211219a024dbf48 100644 (file)
@@ -127,7 +127,7 @@ slap_tool_init(
 
        switch( tool ) {
        case SLAPADD:
-               options = "b:cd:f:l:n:tuvw";
+               options = "b:cd:f:l:n:qtuvw";
                break;
 
        case SLAPCAT:
@@ -204,6 +204,10 @@ slap_tool_init(
                        dbnum = atoi( optarg ) - 1;
                        break;
 
+               case 'q':       /* turn on quick */
+                       mode |= SLAP_TOOL_QUICK;
+                       break;
+
                case 'R':
                        realm = optarg;
                        break;
@@ -337,6 +341,7 @@ slap_tool_init(
                exit( EXIT_FAILURE );
        }
 
+       at_oc_cache = 1;
        ldap_syslog = 0;
 
        switch ( tool ) {
index 3d5347398908e68de367ed539c07af7c79aab9bb..985f5dd4df487d1d134c70f48e7b89683674940c 100644 (file)
@@ -386,6 +386,10 @@ pager: +1 313 555 7671
 facsimileTelephoneNumber: +1 313 555 7762
 telephoneNumber: +1 313 555 4177
 
+dn: ou=Other,dc=example,dc=com
+objectClass: organizationalUnit
+ou: Other
+
 dn: ou=People,dc=example,dc=com
 objectClass: organizationalUnit
 objectClass: extensibleObject
index a15e26f52801a4efe6f18ba15e2fb71021c5287f..67970afc2f8c6d8040c0cab65eeca7e074f86b21 100644 (file)
@@ -365,6 +365,10 @@ pager: +1 313 555 7671
 facsimileTelephoneNumber: +1 313 555 7762
 telephoneNumber: +1 313 555 4177
 
+dn: ou=Other,dc=example,dc=com
+objectClass: organizationalUnit
+ou: Other
+
 dn: ou=People,dc=example,dc=com
 objectClass: organizationalUnit
 objectClass: extensibleObject
diff --git a/tests/data/chainref.out b/tests/data/chainref.out
new file mode 100644 (file)
index 0000000..bec3250
--- /dev/null
@@ -0,0 +1,4 @@
+dn: ou=Other,dc=example,dc=com
+objectClass: organizationalUnit
+ou: Other
+
index b3ef32295cdf4e2db5dc8b97da644a1ed1624ac0..9588fd7db7dc65ddb7c9bfa16d6dc0cf3fab2939 100644 (file)
@@ -414,8 +414,8 @@ dn: o=Example,c=US
 objectClass: top
 objectClass: organization
 objectClass: domainRelatedObject
-objectClass: dcObject
-dc: example
+objectClass: uidObject
+uid: example
 l: Anytown, Michigan
 st: Michigan
 o: Example, Inc.
@@ -680,14 +680,14 @@ dn: cn=ITD Staff,ou=Groups,o=Example,c=US
 owner: cn=Manager,o=Example,c=US
 description: All ITD Staff
 cn: ITD Staff
-objectClass: groupOfUniqueNames
-uniqueMember: cn=Manager,dc=example,dc=com
-uniqueMember: cn=Bjorn Jensen,ou=Information Technology Division,ou=People,dc=
- example,dc=com
-uniqueMember: cn=James A Jones 2,ou=Information Technology Division,ou=People,
- dc=example,dc=com
-uniqueMember: cn=John Doe,ou=Information Technology Division,ou=People,dc=exam
- ple,dc=com
+objectClass: groupOfNames
+member: cn=Manager,o=Example,c=US
+member: cn=Bjorn Jensen,ou=Information Technology Division,ou=People,o=Example
+ ,c=US
+member: cn=James A Jones 2,ou=Information Technology Division,ou=People,o=Exam
+ ple,c=US
+member: cn=John Doe,ou=Information Technology Division,ou=People,o=Example,c=U
+ S
 
 dn: cn=James A Jones 1,ou=Alumni Association,ou=People,o=Example,c=US
 objectClass: OpenLDAPperson
@@ -1642,13 +1642,13 @@ pager: +1 313 555 2844
 facsimileTelephoneNumber: +1 313 555 9700
 telephoneNumber: +1 313 555 5331
 
-# searching base="o=Beispiel,c=DE"...
-dn: o=Beispiel,c=DE
+# searching base="o=Example,c=US"...
+dn: o=Example,c=US
 objectClass: top
 objectClass: organization
 objectClass: domainRelatedObject
-objectClass: dcObject
-dc: example
+objectClass: uidObject
+uid: example
 l: Anytown, Michigan
 st: Michigan
 o: Example, Inc.
@@ -1659,22 +1659,22 @@ postalAddress: Example, Inc. $ 535 W. William St. $ Anytown, MI 48109 $ US
 telephoneNumber: +1 313 555 1817
 associatedDomain: example.com
 
-dn: ou=People,o=Beispiel,c=DE
+dn: ou=People,o=Example,c=US
 objectClass: organizationalUnit
 objectClass: extensibleObject
 ou: People
 uidNumber: 0
 gidNumber: 0
 
-dn: ou=Groups,o=Beispiel,c=DE
+dn: ou=Groups,o=Example,c=US
 objectClass: organizationalUnit
 ou: Groups
 
-dn: ou=Alumni Association,ou=People,o=Beispiel,c=DE
+dn: ou=Alumni Association,ou=People,o=Example,c=US
 objectClass: organizationalUnit
 ou: Alumni Association
 
-dn: ou=Information Technology Division,ou=People,o=Beispiel,c=DE
+dn: ou=Information Technology Division,ou=People,o=Example,c=US
 objectClass: organizationalUnit
 ou: Information Technology Division
 description:: aMODwoPDgsKCw4PCgsOCwotFVlZQw4PCg8OCwoPDg8KCw4LCv0zDg8KDw4LCgsOD
@@ -1817,42 +1817,42 @@ description:: UF7Dg8KDw4LCg8ODwoLDgsKCw4PCg8OCwoPDg8KCw4LCjMODwoPDgsKDw4PCgsOC
  8ODwoLDgsKow4PCg8OCwoPDg8KCw4LCl8ODwoPDgsKDw4PCgsOCwrtWw4PCg8OCwoLDg8KCw4LCi8
  ODwoPDgsKDw4PCgsOCwo3Dg8KDw4LCg8ODwoLDgsKow4PCg8OCwoLDg8KCw4LCnw==
 
-dn: cn=All Staff,ou=Groups,o=Beispiel,c=DE
-member: cn=Manager,o=Beispiel,c=DE
-member: cn=Barbara Jensen,ou=Information Technology Division,ou=People,o=Beisp
- iel,c=DE
-member: cn=Jane Doe,ou=Alumni Association,ou=People,o=Beispiel,c=DE
-member: cn=John Doe,ou=Information Technology Division,ou=People,o=Beispiel,c=
- DE
-member: cn=Mark Elliot,ou=Alumni Association,ou=People,o=Beispiel,c=DE
-member: cn=James A Jones 1,ou=Alumni Association,ou=People,o=Beispiel,c=DE
-member: cn=James A Jones 2,ou=Information Technology Division,ou=People,o=Beis
- piel,c=DE
-member: cn=Jennifer Smith,ou=Alumni Association,ou=People,o=Beispiel,c=DE
-member: cn=Dorothy Stevens,ou=Alumni Association,ou=People,o=Beispiel,c=DE
-member: cn=Ursula Hampster,ou=Alumni Association,ou=People,o=Beispiel,c=DE
-member: cn=Bjorn Jensen,ou=Information Technology Division,ou=People,o=Beispie
- l,c=DE
-owner: cn=Manager,o=Beispiel,c=DE
+dn: cn=All Staff,ou=Groups,o=Example,c=US
+member: cn=Manager,o=Example,c=US
+member: cn=Barbara Jensen,ou=Information Technology Division,ou=People,o=Examp
+ le,c=US
+member: cn=Jane Doe,ou=Alumni Association,ou=People,o=Example,c=US
+member: cn=John Doe,ou=Information Technology Division,ou=People,o=Example,c=U
+ S
+member: cn=Mark Elliot,ou=Alumni Association,ou=People,o=Example,c=US
+member: cn=James A Jones 1,ou=Alumni Association,ou=People,o=Example,c=US
+member: cn=James A Jones 2,ou=Information Technology Division,ou=People,o=Exam
+ ple,c=US
+member: cn=Jennifer Smith,ou=Alumni Association,ou=People,o=Example,c=US
+member: cn=Dorothy Stevens,ou=Alumni Association,ou=People,o=Example,c=US
+member: cn=Ursula Hampster,ou=Alumni Association,ou=People,o=Example,c=US
+member: cn=Bjorn Jensen,ou=Information Technology Division,ou=People,o=Example
+ ,c=US
+owner: cn=Manager,o=Example,c=US
 cn: All Staff
 description: Everyone in the sample data
 objectClass: groupOfNames
 
-dn: cn=Alumni Assoc Staff,ou=Groups,o=Beispiel,c=DE
-member: cn=Manager,o=Beispiel,c=DE
-member: cn=Dorothy Stevens,ou=Alumni Association,ou=People,o=Beispiel,c=DE
-member: cn=James A Jones 1,ou=Alumni Association,ou=People,o=Beispiel,c=DE
-member: cn=Jane Doe,ou=Alumni Association,ou=People,o=Beispiel,c=DE
-member: cn=Jennifer Smith,ou=Alumni Association,ou=People,o=Beispiel,c=DE
-member: cn=Mark Elliot,ou=Alumni Association,ou=People,o=Beispiel,c=DE
-member: cn=Ursula Hampster,ou=Alumni Association,ou=People,o=Beispiel,c=DE
-owner: cn=Manager,o=Beispiel,c=DE
+dn: cn=Alumni Assoc Staff,ou=Groups,o=Example,c=US
+member: cn=Manager,o=Example,c=US
+member: cn=Dorothy Stevens,ou=Alumni Association,ou=People,o=Example,c=US
+member: cn=James A Jones 1,ou=Alumni Association,ou=People,o=Example,c=US
+member: cn=Jane Doe,ou=Alumni Association,ou=People,o=Example,c=US
+member: cn=Jennifer Smith,ou=Alumni Association,ou=People,o=Example,c=US
+member: cn=Mark Elliot,ou=Alumni Association,ou=People,o=Example,c=US
+member: cn=Ursula Hampster,ou=Alumni Association,ou=People,o=Example,c=US
+owner: cn=Manager,o=Example,c=US
 description: All Alumni Assoc Staff
 cn: Alumni Assoc Staff
 objectClass: groupOfNames
 
-dn: cn=Barbara Jensen,ou=Information Technology Division,ou=People,o=Beispiel,
- c=DE
+dn: cn=Barbara Jensen,ou=Information Technology Division,ou=People,o=Example,c
+ =US
 objectClass: OpenLDAPperson
 cn: Barbara Jensen
 cn: Babs Jensen
@@ -1861,7 +1861,7 @@ uid: bjensen
 title: Mythical Manager, Research Systems
 postalAddress: ITD Prod Dev & Deployment $ 535 W. William St. Room 4212 $ Anyt
  own, MI 48103-4943
-seeAlso: cn=All Staff,ou=Groups,o=Beispiel,c=DE
+seeAlso: cn=All Staff,ou=Groups,o=Example,c=US
 userPassword:: YmplbnNlbg==
 mail: bjensen@mailgw.example.com
 homePostalAddress: 123 Wesley $ Anytown, MI 48103
@@ -1872,14 +1872,14 @@ pager: +1 313 555 3233
 facsimileTelephoneNumber: +1 313 555 2274
 telephoneNumber: +1 313 555 9022
 
-dn: cn=Bjorn Jensen,ou=Information Technology Division,ou=People,o=Beispiel,c=
- DE
+dn: cn=Bjorn Jensen,ou=Information Technology Division,ou=People,o=Example,c=U
+ S
 objectClass: OpenLDAPperson
 cn: Bjorn Jensen
 cn: Biiff Jensen
 sn: Jensen
 uid: bjorn
-seeAlso: cn=All Staff,ou=Groups,o=Beispiel,c=DE
+seeAlso: cn=All Staff,ou=Groups,o=Example,c=US
 userPassword:: Ympvcm4=
 homePostalAddress: 19923 Seven Mile Rd. $ South Lyon, MI 49999
 drink: Iced Tea
@@ -1892,7 +1892,7 @@ pager: +1 313 555 4474
 facsimileTelephoneNumber: +1 313 555 2177
 telephoneNumber: +1 313 555 0355
 
-dn: cn=Dorothy Stevens,ou=Alumni Association,ou=People,o=Beispiel,c=DE
+dn: cn=Dorothy Stevens,ou=Alumni Association,ou=People,o=Example,c=US
 objectClass: OpenLDAPperson
 cn: Dorothy Stevens
 cn: Dot Stevens
@@ -1900,7 +1900,7 @@ sn: Stevens
 uid: dots
 title: Secretary, UM Alumni Association
 postalAddress: Alumni Association $ 111 Maple St $ Anytown, MI 48109
-seeAlso: cn=All Staff,ou=Groups,o=Beispiel,c=DE
+seeAlso: cn=All Staff,ou=Groups,o=Example,c=US
 drink: Lemonade
 homePostalAddress: 377 White St. Apt. 3 $ Anytown, MI 48104
 description: Very tall
@@ -1909,20 +1909,20 @@ telephoneNumber: +1 313 555 3664
 mail: dots@mail.alumni.example.com
 homePhone: +1 313 555 0454
 
-dn: cn=ITD Staff,ou=Groups,o=Beispiel,c=DE
-owner: cn=Manager,o=Beispiel,c=DE
+dn: cn=ITD Staff,ou=Groups,o=Example,c=US
+owner: cn=Manager,o=Example,c=US
 description: All ITD Staff
 cn: ITD Staff
-objectClass: groupOfUniqueNames
-uniqueMember: cn=Manager,dc=example,dc=com
-uniqueMember: cn=Bjorn Jensen,ou=Information Technology Division,ou=People,dc=
- example,dc=com
-uniqueMember: cn=James A Jones 2,ou=Information Technology Division,ou=People,
- dc=example,dc=com
-uniqueMember: cn=John Doe,ou=Information Technology Division,ou=People,dc=exam
- ple,dc=com
+objectClass: groupOfNames
+member: cn=Manager,o=Example,c=US
+member: cn=Bjorn Jensen,ou=Information Technology Division,ou=People,o=Example
+ ,c=US
+member: cn=James A Jones 2,ou=Information Technology Division,ou=People,o=Exam
+ ple,c=US
+member: cn=John Doe,ou=Information Technology Division,ou=People,o=Example,c=U
+ S
 
-dn: cn=James A Jones 1,ou=Alumni Association,ou=People,o=Beispiel,c=DE
+dn: cn=James A Jones 1,ou=Alumni Association,ou=People,o=Example,c=US
 objectClass: OpenLDAPperson
 cn: James A Jones 1
 cn: James Jones
@@ -1930,7 +1930,7 @@ cn: Jim Jones
 sn: Jones
 uid: jaj
 postalAddress: Alumni Association $ 111 Maple St $ Anytown, MI 48109
-seeAlso: cn=All Staff,ou=Groups,o=Beispiel,c=DE
+seeAlso: cn=All Staff,ou=Groups,o=Example,c=US
 userPassword:: amFq
 homePostalAddress: 3882 Beverly Rd. $ Anytown, MI 48105
 homePhone: +1 313 555 4772
@@ -1941,15 +1941,15 @@ mail: jaj@mail.alumni.example.com
 facsimileTelephoneNumber: +1 313 555 4332
 telephoneNumber: +1 313 555 0895
 
-dn: cn=James A Jones 2,ou=Information Technology Division,ou=People,o=Beispiel
- ,c=DE
+dn: cn=James A Jones 2,ou=Information Technology Division,ou=People,o=Example,
+ c=US
 objectClass: OpenLDAPperson
 cn: James A Jones 2
 cn: James Jones
 cn: Jim Jones
 sn: Doe
 uid: jjones
-seeAlso: cn=All Staff,ou=Groups,o=Beispiel,c=DE
+seeAlso: cn=All Staff,ou=Groups,o=Example,c=US
 homePostalAddress: 933 Brooks $ Anytown, MI 48104
 homePhone: +1 313 555 8838
 title: Senior Manager, Information Technology Division
@@ -1960,8 +1960,7 @@ pager: +1 313 555 2833
 facsimileTelephoneNumber: +1 313 555 8688
 telephoneNumber: +1 313 555 7334
 
-dn: cn=Jane Q. Doe,ou=Information Technology Division,ou=People,o=Beispiel,c=D
- E
+dn: cn=Jane Q. Doe,ou=Information Technology Division,ou=People,o=Example,c=US
 objectClass: OpenLDAPperson
 cn: Jane Alverson
 cn: Jane Q. Doe
@@ -1970,7 +1969,6 @@ sn: Doe
 uid: jdoe
 title: Programmer Analyst, UM Alumni Association
 postalAddress: Alumni Association $ 111 Maple St $ Anytown, MI 48109
-seeAlso: cn=All Staff,ou=Groups,o=Beispiel,c=DE
 homePostalAddress: 123 Anystreet $ Anytown, MI 48104
 drink: diet coke
 description: Enthusiastic
@@ -1979,15 +1977,16 @@ homePhone: +1 313 555 5445
 pager: +1 313 555 1220
 facsimileTelephoneNumber: +1 313 555 2311
 telephoneNumber: +1 313 555 4774
+seeAlso: cn=All Staff,ou=Groups,o=Example,c=US
 
-dn: cn=Jennifer Smith,ou=Alumni Association,ou=People,o=Beispiel,c=DE
+dn: cn=Jennifer Smith,ou=Alumni Association,ou=People,o=Example,c=US
 objectClass: OpenLDAPperson
 cn: Jennifer Smith
 cn: Jen Smith
 sn: Smith
 uid: jen
 postalAddress: Alumni Association $ 111 Maple St $ Anytown, MI 48109
-seeAlso: cn=All Staff,ou=Groups,o=Beispiel,c=DE
+seeAlso: cn=All Staff,ou=Groups,o=Example,c=US
 drink: Sam Adams
 homePostalAddress: 1000 Maple #44 $ Anytown, MI 48103
 title: Telemarketer, UM Alumni Association
@@ -1997,15 +1996,14 @@ pager: +1 313 555 6442
 facsimileTelephoneNumber: +1 313 555 2756
 telephoneNumber: +1 313 555 8232
 
-dn: cn=John P. Doe,ou=Information Technology Division,ou=People,o=Beispiel,c=D
- E
+dn: cn=John P. Doe,ou=Information Technology Division,ou=People,o=Example,c=US
 objectClass: OpenLDAPperson
 cn: Jonathon Doe
 cn: John P. Doe
 sn: Doe
 uid: johnd
 postalAddress: ITD $ 535 W. William $ Anytown, MI 48109
-seeAlso: cn=All Staff,ou=Groups,o=Beispiel,c=DE
+seeAlso: cn=All Staff,ou=Groups,o=Example,c=US
 homePostalAddress: 912 East Bllvd $ Anytown, MI 48104
 title: System Administrator, Information Technology Division
 description: overworked!
@@ -2015,7 +2013,7 @@ pager: +1 313 555 6573
 facsimileTelephoneNumber: +1 313 555 4544
 telephoneNumber: +1 313 555 9394
 
-dn: cn=Manager,o=Beispiel,c=DE
+dn: cn=Manager,o=Example,c=US
 objectClass: person
 cn: Manager
 cn: Directory Manager
@@ -2024,15 +2022,15 @@ sn: Manager
 description: Manager of the directory
 userPassword:: c2VjcmV0
 
-dn: cn=Ursula Hampster,ou=Alumni Association,ou=People,o=Beispiel,c=DE
+dn: cn=Ursula Hampster,ou=Alumni Association,ou=People,o=Example,c=US
 objectClass: OpenLDAPperson
 cn: Ursula Hampster
 sn: Hampster
 uid: uham
 title: Secretary, UM Alumni Association
 postalAddress: Alumni Association $ 111 Maple St $ Anytown, MI 48109
-seeAlso: cn=All Staff,ou=Groups,o=Beispiel,c=DE
-seeAlso: cn=Ursula Hampster,ou=Alumni Association,ou=People,o=Beispiel,c=DE
+seeAlso: cn=All Staff,ou=Groups,o=Example,c=US
+seeAlso: cn=Ursula Hampster,ou=Alumni Association,ou=People,o=Example,c=US
 homePostalAddress: 123 Anystreet $ Anytown, MI 48104
 mail: uham@mail.alumni.example.com
 homePhone: +1 313 555 8421
@@ -2042,12 +2040,12 @@ telephoneNumber: +1 313 555 5331
 description: Just added self to seeAlso in o=Beispiel,c=DE virtual naming cont
  ext
 
-dn: cn=Added User,ou=Alumni Association,ou=People,o=Beispiel,c=DE
+dn: cn=Added User,ou=Alumni Association,ou=People,o=Example,c=US
 objectClass: OpenLDAPperson
 cn: Added User
 sn: User
 uid: auser
-seeAlso: cn=All Staff,ou=Groups,o=Beispiel,c=DE
+seeAlso: cn=All Staff,ou=Groups,o=Example,c=US
 homePhone: +49 1234567890
 drink: Beer
 mail: auser@mail.alumni.example.com
@@ -2056,6 +2054,19 @@ description: Just added in o=Beispiel,c=DE naming context
 
 # refldap://localhost:9010/ou=Referrals,o=Beispiel,c=DE??sub
 
+dn: cn=Added Group,ou=Groups,o=Example,c=US
+objectClass: groupOfNames
+cn: Added Group
+member: cn=Added Group,ou=Groups,o=Example,c=US
+
+dn: cn=Another Added Group,ou=Groups,o=Example,c=US
+objectClass: groupOfNames
+objectClass: uidObject
+cn: Another Added Group
+member: cn=Added Group,ou=Groups,o=Example,c=US
+member: cn=Another Added Group,ou=Groups,o=Example,c=US
+uid: added
+
 # searching base="o=Esempio,c=IT"...
 dn: o=Esempio,c=IT
 objectClass: top
@@ -2383,7 +2394,6 @@ sn: Doe
 uid: jdoe
 title: Programmer Analyst, UM Alumni Association
 postalAddress: Alumni Association $ 111 Maple St $ Anytown, MI 48109
-seeAlso: cn=All Staff,ou=Groups,o=Esempio,c=IT
 homePostalAddress: 123 Anystreet $ Anytown, MI 48104
 drink: diet coke
 description: Enthusiastic
@@ -2392,6 +2402,7 @@ homePhone: +1 313 555 5445
 pager: +1 313 555 1220
 facsimileTelephoneNumber: +1 313 555 2311
 telephoneNumber: +1 313 555 4774
+seeAlso: cn=All Staff,ou=Groups,o=Esempio,c=IT
 
 dn: cn=Jennifer Smith,ou=Alumni Association,ou=People,o=Esempio,c=IT
 objectClass: OpenLDAPperson
@@ -2468,6 +2479,19 @@ description: Just added in o=Beispiel,c=DE naming context
 
 # refldap://localhost:9010/ou=Referrals,o=Beispiel,c=DE??sub
 
+dn: cn=Added Group,ou=Groups,o=Esempio,c=IT
+objectClass: groupOfUniqueNames
+cn: Added Group
+uniqueMember: cn=Added Group,ou=Groups,dc=example,dc=com
+
+dn: cn=Another Added Group,ou=Groups,o=Esempio,c=IT
+objectClass: groupOfUniqueNames
+objectClass: dcObject
+cn: Another Added Group
+uniqueMember: cn=Added Group,ou=Groups,dc=example,dc=com
+uniqueMember: cn=Another Added Group,ou=Groups,dc=example,dc=com
+dc: added
+
 # searching filter="(objectClass=referral)"
 #      attrs="'*' ref"
 #      base="dc=example,dc=com"...
@@ -2542,3 +2566,12 @@ seeAlso: cn=All Staff,ou=Groups,o=Example,c=US
 
 # refldap://localhost:9010/ou=Referrals,o=Beispiel,c=DE??sub
 
+# searching filter="(member=cn=Another Added Group,ou=Groups,o=Example,c=US)"
+#      attrs="member"
+#      base="o=Example,c=US"...
+# refldap://localhost:9010/ou=Referrals,o=Beispiel,c=DE??sub
+
+dn: cn=Another Added Group,ou=Groups,o=Example,c=US
+member: cn=Added Group,ou=Groups,o=Example,c=US
+member: cn=Another Added Group,ou=Groups,o=Example,c=US
+
index e13e66f1c686a0441b03cb03866d69e84815ae3c..b16e2d5deb717d1ec0941350b6e1a53c97f1ea4d 100644 (file)
@@ -50,12 +50,24 @@ database    @RELAY@
 suffix         "o=Example,c=US"
 ### back-relay can automatically instantiate the rwm overlay
 #relay#relay           "dc=example,dc=com" massage
+#relay#rwm-map         objectClass groupOfNames groupOfUniqueNames
+#relay#rwm-map         objectClass uidObject dcObject
+#relay#rwm-map         attribute member uniqueMember
+#relay#rwm-map         attribute uid dc
 ### back-ldap needs explicit instantiation of the rwm overlay
 #ldap#uri              "@URI1@"
 #ldap#overlay          rwm
 #ldap#rwm-suffixmassage        "dc=example,dc=com"
+#ldap#rwm-map          objectClass groupOfNames groupOfUniqueNames
+#ldap#rwm-map          objectClass uidObject dcObject
+#ldap#rwm-map          attribute member uniqueMember
+#ldap#rwm-map          attribute uid dc
 #meta#uri              "@URI1@o=Example,c=US"
 #meta#suffixmassage    "o=Example,c=US" "dc=example,dc=com"
+#meta#map              objectClass groupOfNames groupOfUniqueNames
+#meta#map              objectClass uidObject dcObject
+#meta#map              attribute member uniqueMember
+#meta#map              attribute uid dc
 
 database       @RELAY@
 suffix         "o=Esempio,c=IT"
index 7f419fd20ce13a1b45abffbbba99b364bf56a288..76e22f7629f627750015b3ae6f189c5fa3a68b36 100644 (file)
@@ -29,6 +29,14 @@ objectclass: extensibleobject
 ou: Groups
 ref: @URI2@ou=Groups,dc=example,dc=com
 
+dn: ou=Other,dc=example,dc=com
+objectclass: referral
+objectclass: extensibleobject
+ou: Other
+# invalid URI first to test failover capabilities (search only)
+ref: @URI3@ou=Other,dc=example,dc=com
+ref: @URI2@ou=Other,dc=example,dc=com
+
 dn: ou=Alumni Association,ou=People,dc=example,dc=com
 objectclass: organizationalUnit
 ou: Alumni Association
index fe0cd3e920f5c236934fa02a86a3354a02f3e8c4..e1fb680216e8b4f365ae2e38294715cac3019e88 100644 (file)
@@ -81,3 +81,8 @@ cn: Dir Man
 sn: Manager
 description: Manager of the directory
 userpassword:: c2VjcmV0
+
+dn: ou=Other,dc=example,dc=com
+objectclass: organizationalUnit
+ou: Other
+
index c083e666d8291cdf9718933ca8ff92211ca1f773..bb6d4011d4bb622ea12fd090081bbc96dff7bde4 100755 (executable)
@@ -235,6 +235,7 @@ LDAPGLUEOUT=$DATADIR/ldapglue.out
 LDAPGLUEANONYMOUSOUT=$DATADIR/ldapglueanonymous.out
 RELAYOUT=$DATADIR/relay.out
 CHAINOUT=$DATADIR/chain.out
+CHAINREFOUT=$DATADIR/chainref.out
 CHAINMODOUT=$DATADIR/chainmod.out
 SQLREAD=$DATADIR/sql-read.out
 SQLWRITE=$DATADIR/sql-write.out
index 5902876c174ef695afe7539181c79cbf54c98d4e..befaee6cff95406ebf16d00a3464b2314e963efa 100755 (executable)
@@ -148,6 +148,15 @@ changetype: modify
 add: cn
 cn: Jane Qissapaolo Doe
 -
+# This operation (delete of DN-valued attribute) triggered ITS#3498
+delete: seeAlso
+-
+
+dn: cn=Jane Q. Doe,ou=Information Technology Division,ou=People,$BASEDN
+changetype: modify
+add: seeAlso
+seeAlso: cn=All Staff,ou=Groups,$BASEDN
+-
 
 dn: ou=Referrals,$BASEDN
 changetype: add
@@ -174,6 +183,51 @@ if test $RC != 0 ; then
        exit $RC
 fi
 
+BASEDN="o=Example,c=US"
+echo "Modifying database \"$BASEDN\"..."
+$LDAPMODIFY -v -D "cn=Manager,$BASEDN" -h $LOCALHOST -p $PORT1 -w $PASSWD \
+       -M >> $TESTOUT 2>&1 << EOMODS
+# These operations (updates with objectClass mapping) triggered ITS#3499
+dn: cn=Added Group,ou=Groups,$BASEDN
+changetype: add
+objectClass: groupOfNames
+objectClass: uidObject
+cn: Added Group
+member: cn=Added Group,ou=Groups,$BASEDN
+uid: added
+
+dn: cn=Another Added Group,ou=Groups,$BASEDN
+changetype: add
+objectClass: groupOfNames
+cn: Another Added Group
+member: cn=Added Group,ou=Groups,$BASEDN
+member: cn=Another Added Group,ou=Groups,$BASEDN
+
+dn: cn=Another Added Group,ou=Groups,$BASEDN
+changetype: modify
+add: objectClass
+objectClass: uidObject
+-
+add: uid
+uid: added
+-
+
+dn: cn=Added Group,ou=Groups,$BASEDN
+changetype: modify
+delete: objectClass
+objectClass: uidObject
+-
+delete: uid
+-
+EOMODS
+
+RC=$?
+if test $RC != 0 ; then
+       echo "Modify failed ($RC)!"
+       test $KILLSERVERS != no && kill -HUP $KILLPIDS
+       exit $RC
+fi
+
 echo "Searching base=\"$BASEDN\"..."
 echo "# searching base=\"$BASEDN\"..." >> $SEARCHOUT
 $LDAPSEARCH -h $LOCALHOST -p $PORT1 -b "$BASEDN" >> $SEARCHOUT 2>&1
@@ -204,7 +258,7 @@ echo "#     attrs=\"'*' ref\"" >> $SEARCHOUT
 BASEDN="dc=example,dc=com"
 echo " base=\"$BASEDN\"..."
 echo "#        base=\"$BASEDN\"..." >> $SEARCHOUT
-$LDAPSEARCH -h $LOCALHOST -p $PORT1 -b "$BASEDN" -M "$FILTER" "*" ref \
+$LDAPSEARCH -h $LOCALHOST -p $PORT1 -b "$BASEDN" -M "$FILTER" '*' ref \
        >> $SEARCHOUT 2>&1
 RC=$?
 if test $RC != 0 ; then
@@ -216,7 +270,7 @@ fi
 BASEDN="o=Example,c=US"
 echo " base=\"$BASEDN\"..."
 echo "#        base=\"$BASEDN\"..." >> $SEARCHOUT
-$LDAPSEARCH -h $LOCALHOST -p $PORT1 -b "$BASEDN" -M "$FILTER" "*" ref \
+$LDAPSEARCH -h $LOCALHOST -p $PORT1 -b "$BASEDN" -M "$FILTER" '*' ref \
        >> $SEARCHOUT 2>&1
 RC=$?
 if test $RC != 0 ; then
@@ -228,7 +282,7 @@ fi
 BASEDN="o=Esempio,c=IT"
 echo " base=\"$BASEDN\"..."
 echo "#        base=\"$BASEDN\"..." >> $SEARCHOUT
-$LDAPSEARCH -h $LOCALHOST -p $PORT1 -b "$BASEDN" -M "$FILTER" "*" ref \
+$LDAPSEARCH -h $LOCALHOST -p $PORT1 -b "$BASEDN" -M "$FILTER" '*' ref \
        >> $SEARCHOUT 2>&1
 RC=$?
 if test $RC != 0 ; then
@@ -254,6 +308,23 @@ if test $RC != 0 ; then
        exit $RC
 fi
 
+BASEDN="o=Example,c=US"
+FILTER="(member=cn=Another Added Group,ou=Groups,$BASEDN)"
+echo "Searching filter=\"$FILTER\""
+echo " attrs=\"member\""
+echo " base=\"$BASEDN\"..."
+echo "# searching filter=\"$FILTER\"" >> $SEARCHOUT
+echo "#        attrs=\"member\"" >> $SEARCHOUT
+echo "#        base=\"$BASEDN\"..." >> $SEARCHOUT
+$LDAPSEARCH -h $LOCALHOST -p $PORT1 -b "$BASEDN" "$FILTER" member \
+       >> $SEARCHOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+       echo "Search failed ($RC)!"
+       test $KILLSERVERS != no && kill -HUP $KILLPIDS
+       exit $RC
+fi
+
 echo "Filtering ldapsearch results..."
 . $LDIFFILTER < $SEARCHOUT > $SEARCHFLT
 echo "Filtering original ldif used to create database..."
index de27ec0fce855c383982382ac3fc599630eb6534..7bf073a3fdb7ac50fdc3beff4c88b6bbb99f4690 100755 (executable)
@@ -110,6 +110,31 @@ for P in $PORT1 $PORT2 ; do
                test $KILLSERVERS != no && kill -HUP $KILLPIDS
                exit 1
        fi
+
+       echo "Reading the referral entry "ou=Other,$BASEDN" as anonymous on port $P..."
+       $LDAPSEARCH -h $LOCALHOST -p $P -b "ou=Other,$BASEDN" -S "" \
+                > $SEARCHOUT 2>&1
+
+       RC=$?
+       if test $RC != 0 ; then
+               echo "ldapsearch failed ($RC)!"
+               test $KILLSERVERS != no && kill -HUP $KILLPIDS
+               exit $RC
+       fi
+
+       echo "Filtering ldapsearch results..."
+       . $LDIFFILTER < $SEARCHOUT > $SEARCHFLT
+       echo "Filtering original ldif used to create database..."
+       . $LDIFFILTER < $CHAINREFOUT > $LDIFFLT
+       echo "Comparing filter output..."
+       $CMP $SEARCHFLT $LDIFFLT > $CMPOUT
+               
+       if test $? != 0 ; then
+               echo "comparison failed - chained search didn't succeed"
+               test $KILLSERVERS != no && kill -HUP $KILLPIDS
+               exit 1
+fi
+
 done
 
 #