From 492762f1c5851265011016afcf665e329042cadc Mon Sep 17 00:00:00 2001
From: Kurt Zeilenga <kurt@openldap.org>
Date: Thu, 17 Jan 2002 03:58:52 +0000
Subject: [PATCH] Don't use BDB group/attribute callbacks as they may cause
 deadlock. Add code to bdb_attribute and bdb_group where use TXN id and to
 provide error, but need to rework callers (and their callers) to ensure error
 is properly bubbled up to the backend operation routine handling the
 transaction.  Ugh.

---
 servers/slapd/acl.c                |  3 +--
 servers/slapd/back-bdb/attribute.c | 12 ++++++++++--
 servers/slapd/back-bdb/group.c     | 11 ++++++++++-
 servers/slapd/back-bdb/init.c      | 13 +++++++++++--
 4 files changed, 32 insertions(+), 7 deletions(-)

diff --git a/servers/slapd/acl.c b/servers/slapd/acl.c
index 1c6ab94845..189ea1bc95 100644
--- a/servers/slapd/acl.c
+++ b/servers/slapd/acl.c
@@ -794,8 +794,7 @@ acl_mask(
 				b->a_group_oc, b->a_group_at);
 			if ( ndn.bv_val )
 				free( ndn.bv_val );
-			if ( rc != 0 )
-			{
+			if ( rc != 0 ) {
 				continue;
 			}
 		}
diff --git a/servers/slapd/back-bdb/attribute.c b/servers/slapd/back-bdb/attribute.c
index d5b707e5ac..f248163830 100644
--- a/servers/slapd/back-bdb/attribute.c
+++ b/servers/slapd/back-bdb/attribute.c
@@ -16,7 +16,6 @@
 #include "back-bdb.h"
 #include "proto-bdb.h"
 
-
 /* return LDAP_SUCCESS IFF we can retrieve the attributes
  * of entry with e_ndn
  */
@@ -31,6 +30,8 @@ bdb_attribute(
 	BerVarray *vals )
 {
 	struct bdbinfo *li = (struct bdbinfo *) be->be_private;
+	struct bdb_op_info *boi = (struct bdb_op_info *) op->o_private;
+	DB_TXN *txn = NULL;
 	Entry *e;
 	int	i, j, rc;
 	Attribute *attr;
@@ -58,6 +59,10 @@ bdb_attribute(
 		target ? target->e_ndn : "", 0, 0 ); 
 #endif
 
+	if( boi != NULL && be == boi->boi_bdb ) {
+		txn = boi->boi_txn;
+	}
+
 	if (target != NULL && dn_match(&target->e_nname, entry_ndn)) {
 		/* we already have a LOCKED copy of the entry */
 		e = target;
@@ -74,12 +79,15 @@ bdb_attribute(
 
 	} else {
 		/* can we find entry */
-		rc = bdb_dn2entry( be, NULL, entry_ndn, &e, NULL, 0 );
+		rc = bdb_dn2entry( be, txn, entry_ndn, &e, NULL, 0 );
 		switch( rc ) {
 		case DB_NOTFOUND:
 		case 0:
 			break;
 		default:
+			if( txn != NULL ) {
+				boi->boi_err = rc;
+			}
 			return LDAP_OTHER;
 		}
 		if (e == NULL) {
diff --git a/servers/slapd/back-bdb/group.c b/servers/slapd/back-bdb/group.c
index 9bd50a3a10..2e55471eaf 100644
--- a/servers/slapd/back-bdb/group.c
+++ b/servers/slapd/back-bdb/group.c
@@ -34,6 +34,8 @@ bdb_group(
 )
 {
 	struct bdbinfo *li = (struct bdbinfo *) be->be_private;
+	struct bdb_op_info *boi = (struct bdb_op_info *) op->o_private;
+	DB_TXN *txn;
 	Entry *e;
 	int	rc = 1;
 	Attribute *attr;
@@ -69,6 +71,10 @@ bdb_group(
 		target->e_ndn, 0, 0 ); 
 #endif
 
+	if( boi != NULL && be == boi->boi_bdb ) {
+		txn = boi->boi_txn;
+	}
+
 	if (dn_match(&target->e_name, gr_ndn)) {
 		/* we already have a LOCKED copy of the entry */
 		e = target;
@@ -82,8 +88,11 @@ bdb_group(
 #endif
 	} else {
 		/* can we find group entry */
-		rc = bdb_dn2entry( be, NULL, gr_ndn, &e, NULL, 0 );
+		rc = bdb_dn2entry( be, txn, gr_ndn, &e, NULL, 0 );
 		if( rc ) {
+			if( txn ) {
+				boi->boi_err = rc;
+			}
 			return( 1 );
 		}
 		if (e == NULL) {
diff --git a/servers/slapd/back-bdb/init.c b/servers/slapd/back-bdb/init.c
index 3e3956d747..8c5e43103c 100644
--- a/servers/slapd/back-bdb/init.c
+++ b/servers/slapd/back-bdb/init.c
@@ -446,11 +446,20 @@ bdb_initialize(
 	bi->bi_op_abandon = 0;
 
 	bi->bi_extended = bdb_extended;
-	bi->bi_acl_group = bdb_group;
 
+#if 0
+	/*
+	 * these routines (and their callers) are not yet designed
+	 * to work with transaction.  Using them may cause deadlock.
+	 */
+	bi->bi_acl_group = bdb_group;
 	bi->bi_acl_attribute = bdb_attribute;
-	bi->bi_chk_referrals = bdb_referrals;
+#else
+	bi->bi_acl_group = 0;
+	bi->bi_acl_attribute = 0;
+#endif
 
+	bi->bi_chk_referrals = bdb_referrals;
 	bi->bi_entry_release_rw = bdb_entry_release;
 
 	/*
-- 
GitLab