From 52d7a2d8b297d36b4164f43b8f4699c012a8fd45 Mon Sep 17 00:00:00 2001
From: Kurt Zeilenga <kurt@openldap.org>
Date: Wed, 23 Dec 1998 02:30:44 +0000
Subject: [PATCH] Add client/server control free/dup functions and
 ldap_set/get_option support for controls.

---
 include/ldap.h                  |  2 +-
 libraries/libldap/Makefile.in   |  4 +--
 libraries/libldap/ldap-int.h    | 12 ++++++-
 libraries/libldap/options.c     | 57 ++++++++++++++++++++++++++-------
 libraries/libldap_r/Makefile.in |  4 +--
 5 files changed, 62 insertions(+), 17 deletions(-)

diff --git a/include/ldap.h b/include/ldap.h
index 499d096aa0..16c33432c8 100644
--- a/include/ldap.h
+++ b/include/ldap.h
@@ -463,7 +463,7 @@ struct timeval;
 LDAP_F int ldap_get_option LDAP_P((LDAP *ld, int option, void *outvalue));
 LDAP_F int ldap_set_option LDAP_P((LDAP *ld, int option, void *invalue));
 
-/* Not yet */
+/* in controls.c */
 LDAP_F void ldap_control_free LDAP_P(( LDAPControl *ctrl ));
 LDAP_F void ldap_controls_free LDAP_P(( LDAPControl **ctrls ));
   
diff --git a/libraries/libldap/Makefile.in b/libraries/libldap/Makefile.in
index 013b2e4976..cb14f22a0c 100644
--- a/libraries/libldap/Makefile.in
+++ b/libraries/libldap/Makefile.in
@@ -6,14 +6,14 @@ XLIBRARY = ../libldap.a
 
 PROGRAMS = apitest ltest ttest
 
-SRCS	= bind.c open.c result.c error.c compare.c search.c \
+SRCS	= bind.c controls.c open.c result.c error.c compare.c search.c \
 	modify.c add.c modrdn.c delete.c abandon.c ufn.c cache.c \
 	getfilter.c sbind.c kbind.c unbind.c friendly.c cldap.c \
 	free.c disptmpl.c srchpref.c dsparse.c tmplout.c sort.c \
 	getdn.c getentry.c getattr.c getvalues.c addentry.c \
 	request.c getdxbyname.c os-ip.c url.c charset.c \
 	init.c options.c strdup.c util-int.c
-OBJS	= bind.lo open.lo result.lo error.lo compare.lo search.lo \
+OBJS	= bind.lo controls.lo open.lo result.lo error.lo compare.lo search.lo \
 	modify.lo add.lo modrdn.lo delete.lo abandon.lo ufn.lo cache.lo \
 	getfilter.lo sbind.lo kbind.lo unbind.lo friendly.lo cldap.lo \
 	free.lo disptmpl.lo srchpref.lo dsparse.lo tmplout.lo sort.lo \
diff --git a/libraries/libldap/ldap-int.h b/libraries/libldap/ldap-int.h
index 9fc14c3e67..d9c77df425 100644
--- a/libraries/libldap/ldap-int.h
+++ b/libraries/libldap/ldap-int.h
@@ -77,14 +77,18 @@ struct ldapoptions {
 
 	int		ldo_debug;
 
+	int		ldo_defport;
 	char*	ldo_defbase;
 	char*	ldo_defhost;
-	int		ldo_defport;
 
 	int		ldo_cldaptries;	/* connectionless search retry count */
 	int		ldo_cldaptimeout;/* time between retries */
 	int		ldo_refhoplimit;	/* limit on referral nesting */
 
+	/* LDAPv3 server and client controls */
+	LDAPControl	**ldo_server_controls;
+	LDAPControl **ldo_client_controls;
+	
 	LDAP_BOOLEANS ldo_booleans;	/* boolean options */
 };
 
@@ -237,6 +241,12 @@ void ldap_add_request_to_cache LDAP_P(( LDAP *ld, unsigned long msgtype,
 void ldap_add_result_to_cache LDAP_P(( LDAP *ld, LDAPMessage *result ));
 int ldap_check_cache LDAP_P(( LDAP *ld, unsigned long msgtype, BerElement *request ));
 
+/*
+ * in controls.c
+ */
+LDAPControl *ldap_control_dup LDAP_P(( LDAPControl *ctrl ));
+LDAPControl **ldap_controls_dup LDAP_P(( LDAPControl **ctrl ));
+
 /*
  * in dsparse.c
  */
diff --git a/libraries/libldap/options.c b/libraries/libldap/options.c
index 0fd9ef5c70..5037dc619d 100644
--- a/libraries/libldap/options.c
+++ b/libraries/libldap/options.c
@@ -142,18 +142,22 @@ ldap_get_option(
 		return 0;
 
 	case LDAP_OPT_SERVER_CONTROLS:
-		/* not yet supported */
-		break;
+		* (LDAPControl ***) outvalue =
+			ldap_controls_dup( lo->ldo_server_controls );
+
+		return 0;
 
 	case LDAP_OPT_CLIENT_CONTROLS:
-		/* not yet supported */
-		break;
+		* (LDAPControl ***) outvalue =
+			ldap_controls_dup( lo->ldo_client_controls );
+
+		return 0;
 
 	case LDAP_OPT_HOST_NAME:
 		/*
 		 * draft-ietf-ldapext-ldap-c-api-01 doesn't state
-		 * whether client to have to free host names or no,
-		 * we do
+		 * whether caller has to free host names or not,
+		 * we do.
 		 */
 
 		* (char **) outvalue = ldap_strdup(lo->ldo_defhost);
@@ -183,6 +187,7 @@ ldap_get_option(
 		} else {
 			* (char **) outvalue = ldap_strdup(ld->ld_error);
 		}
+
 		return 0;
 
 	case LDAP_OPT_API_FEATURE_INFO: {
@@ -281,12 +286,42 @@ ldap_set_option(
 		} return 0;
 
 	case LDAP_OPT_SERVER_CONTROLS: {
-			/* not yet supported */
-		} break;
+			LDAPControl **controls = (LDAPControl **) invalue;
+
+			ldap_controls_free( lo->ldo_server_controls );
+
+			if( controls == NULL || *controls == NULL ) {
+				lo->ldo_server_controls = NULL;
+				return 0;
+			}
+				
+			lo->ldo_server_controls =
+				ldap_controls_dup( (LDAPControl **) invalue );
+
+			if(lo->ldo_server_controls == NULL) {
+				/* memory allocation error ? */
+				break;
+			}
+		} return 0;
 
 	case LDAP_OPT_CLIENT_CONTROLS: {
-			/* not yet supported */
-		} break;
+			LDAPControl **controls = (LDAPControl **) invalue;
+
+			ldap_controls_free( lo->ldo_client_controls );
+
+			if( controls == NULL || *controls == NULL ) {
+				lo->ldo_client_controls = NULL;
+				return 0;
+			}
+				
+			lo->ldo_client_controls =
+				ldap_controls_dup( (LDAPControl **) invalue );
+
+			if(lo->ldo_client_controls == NULL) {
+				/* memory allocation error ? */
+				break;
+			}
+		} return 0;
 
 	case LDAP_OPT_HOST_NAME: {
 			char* host = (char *) invalue;
@@ -341,7 +376,7 @@ ldap_set_option(
 				free(ld->ld_error);
 			}
 
-			ld->ld_error = strdup(err);
+			ld->ld_error = ldap_strdup(err);
 		} return 0;
 
 	case LDAP_OPT_API_FEATURE_INFO:
diff --git a/libraries/libldap_r/Makefile.in b/libraries/libldap_r/Makefile.in
index f5a28dba9a..e8d5f69b0e 100644
--- a/libraries/libldap_r/Makefile.in
+++ b/libraries/libldap_r/Makefile.in
@@ -8,14 +8,14 @@ PROGRAMS = apitest ltest ttest
 
 XXDIR = ../libldap
 XXSRCS	= apitest.c test.c tmpltest.c \
-	bind.c open.c result.c error.c compare.c search.c \
+	bind.c controls.c open.c result.c error.c compare.c search.c \
 	modify.c add.c modrdn.c delete.c abandon.c ufn.c cache.c \
 	getfilter.c sbind.c kbind.c unbind.c friendly.c cldap.c \
 	free.c disptmpl.c srchpref.c dsparse.c tmplout.c sort.c \
 	getdn.c getentry.c getattr.c getvalues.c addentry.c \
 	request.c getdxbyname.c os-ip.c url.c charset.c \
 	init.c options.c strdup.c util-int.c
-OBJS	= bind.lo open.lo result.lo error.lo compare.lo search.lo \
+OBJS	= bind.lo controls.lo open.lo result.lo error.lo compare.lo search.lo \
 	modify.lo add.lo modrdn.lo delete.lo abandon.lo ufn.lo cache.lo \
 	getfilter.lo sbind.lo kbind.lo unbind.lo friendly.lo cldap.lo \
 	free.lo disptmpl.lo srchpref.lo dsparse.lo tmplout.lo sort.lo \
-- 
GitLab