From 8ac304ee4ca61bdb394c7a32416f9a24e88b6fde Mon Sep 17 00:00:00 2001
From: Kurt Zeilenga <kurt@openldap.org>
Date: Fri, 13 May 2005 03:00:04 +0000
Subject: [PATCH] Add client-side ManageDIT control support (to be used to
 'manage' DIT entries).

---
 clients/tools/common.c       | 33 +++++++++++++++++++++++++++++++--
 include/ldap.h               |  1 +
 tests/scripts/test037-manage | 11 ++++++++++-
 3 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/clients/tools/common.c b/clients/tools/common.c
index b6bc01aad2..783716a12c 100644
--- a/clients/tools/common.c
+++ b/clients/tools/common.c
@@ -63,6 +63,7 @@ int   use_tls = 0;
 int	  assertctl;
 char *assertion = NULL;
 char *authzid = NULL;
+int   manageDIT = 0;
 int   manageDSAit = 0;
 int   noop = 0;
 int   ppolicy = 0;
@@ -133,6 +134,7 @@ N_("             [!]chaining[=<resolveBehavior>[/<continuationBehavior>]]\n")
 N_("                     one of \"chainingPreferred\", \"chainingRequired\",\n")
 N_("                     \"referralsPreferred\", \"referralsRequired\"\n")
 #endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
+N_("             [!]manageDIT\n")
 N_("             [!]manageDSAit\n")
 N_("             [!]noop\n")
 #ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST
@@ -256,6 +258,20 @@ tool_args( int argc, char **argv )
 				assert( authzid == NULL );
 				authzid = cvalue;
 
+			} else if ( strcasecmp( control, "manageDIT" ) == 0 ) {
+				if( manageDIT ) {
+					fprintf( stderr,
+						"manageDIT control previously specified\n");
+					exit( EXIT_FAILURE );
+				}
+				if( cvalue != NULL ) {
+					fprintf( stderr,
+						"manageDIT: no control value expected\n" );
+					usage();
+				}
+
+				manageDIT = 1 + crit;
+
 			} else if ( strcasecmp( control, "manageDSAit" ) == 0 ) {
 				if( manageDSAit ) {
 					fprintf( stderr,
@@ -720,7 +736,12 @@ tool_args( int argc, char **argv )
 		}
 	}
 	if( protocol == LDAP_VERSION2 ) {
-		if( authzid || manageDSAit || noop || ppolicy ) {
+		if( assertctl || authzid || manageDIT || manageDSAit ||
+#ifdef LDAP_CONTROL_X_CHAINING_BEHAVIOR
+			chaining ||
+#endif
+			noop || ppolicy || preread || postread )
+		{
 			fprintf( stderr, "%s: -e/-M incompatible with LDAPv2\n", prog );
 			exit( EXIT_FAILURE );
 		}
@@ -968,7 +989,7 @@ void
 tool_server_controls( LDAP *ld, LDAPControl *extra_c, int count )
 {
 	int i = 0, j, crit = 0, err;
-	LDAPControl c[9], **ctrls;
+	LDAPControl c[10], **ctrls;
 
 	ctrls = (LDAPControl**) malloc(sizeof(c) + (count+1)*sizeof(LDAPControl*));
 	if ( ctrls == NULL ) {
@@ -1014,6 +1035,14 @@ tool_server_controls( LDAP *ld, LDAPControl *extra_c, int count )
 		i++;
 	}
 
+	if ( manageDIT ) {
+		c[i].ldctl_oid = LDAP_CONTROL_MANAGEDIT;
+		BER_BVZERO( &c[i].ldctl_value );
+		c[i].ldctl_iscritical = manageDIT > 1;
+		ctrls[i] = &c[i];
+		i++;
+	}
+
 	if ( manageDSAit ) {
 		c[i].ldctl_oid = LDAP_CONTROL_MANAGEDSAIT;
 		BER_BVZERO( &c[i].ldctl_value );
diff --git a/include/ldap.h b/include/ldap.h
index 4817393590..8d71406083 100644
--- a/include/ldap.h
+++ b/include/ldap.h
@@ -220,6 +220,7 @@ typedef struct ldapcontrol {
 #define LDAP_CONTROL_NOOP				"1.3.6.1.4.1.4203.666.5.2"
 #define LDAP_CONTROL_PRE_READ			"1.3.6.1.4.1.4203.666.5.10.1"
 #define LDAP_CONTROL_POST_READ			"1.3.6.1.4.1.4203.666.5.10.2"
+#define LDAP_CONTROL_MANAGEDIT			"1.3.6.1.4.1.4203.666.5.11"
 
 /* LDAP Duplicated Entry Control Extension *//* not implemented in slapd(8) */
 #define LDAP_CONTROL_DUPENT_REQUEST		"2.16.840.1.113719.1.27.101.1"
diff --git a/tests/scripts/test037-manage b/tests/scripts/test037-manage
index c31f887220..0267c91b6b 100755
--- a/tests/scripts/test037-manage
+++ b/tests/scripts/test037-manage
@@ -58,7 +58,8 @@ if test $RC != 0 ; then
 fi
 
 echo "Testing modify, add, and delete..."
-$LDAPMODIFY -v -MM -D "$MANAGERDN" -h $LOCALHOST -p $PORT1 -w $PASSWD > \
+$LDAPMODIFY -v -D "$MANAGERDN" -h $LOCALHOST -p $PORT1 -w $PASSWD \
+	-e \!ManageDIT > \
 	$TESTOUT 2>&1 << EOMODS
 version: 1
 
@@ -69,6 +70,9 @@ dn: cn=James A Jones 1,ou=Alumni Association,ou=People,dc=example,dc=com
 changetype: modify
 replace: objectClass
 objectClass: testPerson
+-
+replace: objectClass
+objectClass: structuralObjectClass
 
 dn: cn=Bjorn Jensen,ou=Information Technology Division,ou=People,dc=example,dc=com
 # update structural object class of entry via objectClass modify
@@ -78,6 +82,11 @@ objectClass: OpenLDAPperson
 -
 add: objectClass
 objectClass: testPerson
+-
+delete: structuralObjectClass
+-
+add: objectClass
+objectClass: testPerson
 
 dn: cn=ITD Staff,ou=Groups,dc=example,dc=com
 # change entryUUID
-- 
GitLab