Blame SOURCES/0091-Ticket-48492-heap-corruption-at-schema-replication.patch

f5000e
From bc3328ebbe1b8279f77ad1020bce9fb638d4c94c Mon Sep 17 00:00:00 2001
f5000e
From: Noriko Hosoi <nhosoi@redhat.com>
f5000e
Date: Fri, 8 Apr 2016 14:17:12 -0700
f5000e
Subject: [PATCH 91/93] Ticket #48492 - heap corruption at schema replication.
f5000e
f5000e
Bug Description: If nsslapd-enquote-sup-oc is on, the server is supposed to
f5000e
handle the quoted SYNTAX values although the spec is deprecated.  Currently,
f5000e
if nsslapd-enquote-sup-oc is on, it wraps SYNTAX values with quotes, but the
f5000e
information is not passed to the openldap schema parser where the parsing the
f5000e
schema fails.
f5000e
f5000e
Fix Description: This patch passes the info (flag LDAP_SCHEMA_ALLOW_QUOTED)
f5000e
to the openldap API ldap_str2attributetype if nsslapd-enquote-sup-oc is on.
f5000e
f5000e
Additionally, to support the old style quoted SYNTAX values in the schema
f5000e
files, loading the schema has to get the enquote information prior to the
f5000e
configuration parameters evaluated.  To pass the information, this patch
f5000e
accepts the environment variable LDAP_SCHEMA_ALLOW_QUOTED. If it is defined
f5000e
with any value, old style schema files are processed.
f5000e
f5000e
To set the environment variable, add
f5000e
    LDAP_SCHEMA_ALLOW_QUOTED="on"
f5000e
to /etc/sysconfig/dirsrv-INSTANCE.
f5000e
f5000e
https://fedorahosted.org/389/ticket/48492
f5000e
f5000e
Reviewed by firstyear@redhat.com (Thank you, William!!)
f5000e
f5000e
(cherry picked from commit 955dc66d42511c2cc8d6ff18cf030508f6da2770)
f5000e
(cherry picked from commit 7927e4420fb185ae328d56cfd4741583ae1f667b)
f5000e
---
f5000e
 ldap/servers/slapd/schema.c | 66 ++++++++++++++++++++++++++++++++++-----------
f5000e
 1 file changed, 51 insertions(+), 15 deletions(-)
f5000e
f5000e
diff --git a/ldap/servers/slapd/schema.c b/ldap/servers/slapd/schema.c
f5000e
index dd56599..806c38d 100644
f5000e
--- a/ldap/servers/slapd/schema.c
f5000e
+++ b/ldap/servers/slapd/schema.c
f5000e
@@ -1638,6 +1638,16 @@ schema_attr_enum_callback(struct asyntaxinfo *asip, void *arg)
f5000e
 	}
f5000e
 
f5000e
 	if ( !aew->schema_ds4x_compat ) {
f5000e
+#if defined (USE_OPENLDAP)
f5000e
+		/* 
f5000e
+		 * These values in quotes are not supported by the openldap parser.
f5000e
+		 * Even if nsslapd-enquote-sup-oc is on, quotes should not be added.
f5000e
+		 */
f5000e
+		outp += put_tagged_oid( outp, "SUP ", asip->asi_superior, NULL, 0 );
f5000e
+		outp += put_tagged_oid( outp, "EQUALITY ", asip->asi_mr_equality, NULL, 0 );
f5000e
+		outp += put_tagged_oid( outp, "ORDERING ", asip->asi_mr_ordering, NULL, 0 );
f5000e
+		outp += put_tagged_oid( outp, "SUBSTR ", asip->asi_mr_substring, NULL, 0 );
f5000e
+#else
f5000e
 		outp += put_tagged_oid( outp, "SUP ",
f5000e
 				asip->asi_superior, NULL, aew->enquote_sup_oc );
f5000e
 		outp += put_tagged_oid( outp, "EQUALITY ",
f5000e
@@ -1646,6 +1656,7 @@ schema_attr_enum_callback(struct asyntaxinfo *asip, void *arg)
f5000e
 				asip->asi_mr_ordering, NULL, aew->enquote_sup_oc );
f5000e
 		outp += put_tagged_oid( outp, "SUBSTR ",
f5000e
 				asip->asi_mr_substring, NULL, aew->enquote_sup_oc );
f5000e
+#endif
f5000e
 	}
f5000e
 
f5000e
 	outp += put_tagged_oid( outp, "SYNTAX ", syntaxoid, syntaxlengthbuf,
f5000e
@@ -4105,7 +4116,7 @@ parse_attr_str(const char *input, struct asyntaxinfo **asipp, char *errorbuf,
f5000e
     char **attr_names = NULL;
f5000e
     unsigned long flags = SLAPI_ATTR_FLAG_OVERRIDE;
f5000e
     /* If we ever accept openldap schema directly, then make parser_flags configurable */
f5000e
-    const int parser_flags = LDAP_SCHEMA_ALLOW_NONE | LDAP_SCHEMA_ALLOW_NO_OID;
f5000e
+    unsigned int parser_flags = LDAP_SCHEMA_ALLOW_NONE | LDAP_SCHEMA_ALLOW_NO_OID;
f5000e
     int invalid_syntax_error;
f5000e
     int syntaxlength = SLAPI_SYNTAXLENGTH_NONE;
f5000e
     int num_names = 0;
f5000e
@@ -4113,6 +4124,17 @@ parse_attr_str(const char *input, struct asyntaxinfo **asipp, char *errorbuf,
f5000e
     int rc = 0;
f5000e
     int a, aa;
f5000e
 
f5000e
+    if (config_get_enquote_sup_oc()) {
f5000e
+        parser_flags |= LDAP_SCHEMA_ALLOW_QUOTED;
f5000e
+    } else if (getenv("LDAP_SCHEMA_ALLOW_QUOTED")) {
f5000e
+        char ebuf[SLAPI_DSE_RETURNTEXT_SIZE];
f5000e
+        parser_flags |= LDAP_SCHEMA_ALLOW_QUOTED;
f5000e
+        if (config_set_enquote_sup_oc(CONFIG_ENQUOTE_SUP_OC_ATTRIBUTE, "on", ebuf, CONFIG_APPLY)) {
f5000e
+            slapi_log_error(SLAPI_LOG_FATAL, "schema", "Failed to enable %s: %s\n",
f5000e
+                            CONFIG_ENQUOTE_SUP_OC_ATTRIBUTE, ebuf);
f5000e
+        }
f5000e
+    }
f5000e
+
f5000e
     /*
f5000e
      *      OpenLDAP AttributeType struct
f5000e
      *
f5000e
@@ -4159,7 +4181,7 @@ parse_attr_str(const char *input, struct asyntaxinfo **asipp, char *errorbuf,
f5000e
         /* trim any leading spaces */
f5000e
         input++;
f5000e
     }
f5000e
-    if((atype = ldap_str2attributetype(input, &rc, &errp, parser_flags )) == NULL){
f5000e
+    if((atype = ldap_str2attributetype(input, &rc, &errp, (const unsigned int)parser_flags )) == NULL){
f5000e
         schema_create_errormsg( errorbuf, errorbufsize, schema_errprefix_at, input,
f5000e
                                "Failed to parse attribute, error(%d - %s) at (%s)", rc, ldap_scherr2str(rc), errp );
f5000e
         return invalid_syntax_error;
f5000e
@@ -4478,12 +4500,23 @@ parse_objclass_str ( const char *input, struct objclass **oc, char *errorbuf,
f5000e
     char **OrigRequiredAttrsArray, **OrigAllowedAttrsArray;
f5000e
     char *first_oc_name = NULL;
f5000e
     /* If we ever accept openldap schema directly, then make parser_flags configurable */
f5000e
-    const int parser_flags = LDAP_SCHEMA_ALLOW_NONE | LDAP_SCHEMA_ALLOW_NO_OID;
f5000e
+    unsigned int parser_flags = LDAP_SCHEMA_ALLOW_NONE | LDAP_SCHEMA_ALLOW_NO_OID;
f5000e
     PRUint8 flags = 0;
f5000e
     int invalid_syntax_error;
f5000e
     int i, j;
f5000e
     int rc = 0;
f5000e
 
f5000e
+    if (config_get_enquote_sup_oc()) {
f5000e
+        parser_flags |= LDAP_SCHEMA_ALLOW_QUOTED;
f5000e
+    } else if (getenv("LDAP_SCHEMA_ALLOW_QUOTED")) {
f5000e
+        char ebuf[SLAPI_DSE_RETURNTEXT_SIZE];
f5000e
+        parser_flags |= LDAP_SCHEMA_ALLOW_QUOTED;
f5000e
+        if (config_set_enquote_sup_oc(CONFIG_ENQUOTE_SUP_OC_ATTRIBUTE, "on", ebuf, CONFIG_APPLY)) {
f5000e
+            slapi_log_error(SLAPI_LOG_FATAL, "schema", "Failed to enable %s: %s\n",
f5000e
+                            CONFIG_ENQUOTE_SUP_OC_ATTRIBUTE, ebuf);
f5000e
+        }
f5000e
+    }
f5000e
+
f5000e
     /*
f5000e
      *     openLDAP Objectclass struct
f5000e
      *
f5000e
@@ -4521,10 +4554,10 @@ parse_objclass_str ( const char *input, struct objclass **oc, char *errorbuf,
f5000e
      *  Parse the input and create the openLdap objectclass structure
f5000e
      */
f5000e
     while(isspace(*input)){
f5000e
-    	/* trim any leading spaces */
f5000e
+        /* trim any leading spaces */
f5000e
         input++;
f5000e
     }
f5000e
-    if((objClass = ldap_str2objectclass(input, &rc, &errp, parser_flags )) == NULL){
f5000e
+    if((objClass = ldap_str2objectclass(input, &rc, &errp, (const unsigned int)parser_flags )) == NULL){
f5000e
         schema_create_errormsg( errorbuf, errorbufsize, schema_errprefix_oc, input,
f5000e
                                "Failed to parse objectclass, error(%d) at (%s)", rc, errp );
f5000e
         return invalid_syntax_error;
f5000e
@@ -5592,7 +5625,7 @@ get_tagged_oid( const char *tag, const char **inputp,
f5000e
 	PR_ASSERT( NULL != *inputp );
f5000e
 	PR_ASSERT( NULL != tag );
f5000e
 	PR_ASSERT( '\0' != tag[ 0 ] );
f5000e
-       	if('(' !=tag[0]) 
f5000e
+	if('(' !=tag[0]) 
f5000e
 	  PR_ASSERT((' ' == tag[ strlen( tag ) - 1 ]) || ('(' == tag[ strlen( tag ) - 1 ]));
f5000e
 
f5000e
 	if ( NULL == strstr_fn ) {
f5000e
@@ -5611,8 +5644,8 @@ get_tagged_oid( const char *tag, const char **inputp,
f5000e
 		/* skip past the leading single quote, if present */
f5000e
 		if ( *startp == '\'' ) {
f5000e
 			++startp;
f5000e
-                        /* skip past any extra white space */
f5000e
-                        startp = skipWS( startp );
f5000e
+			/* skip past any extra white space */
f5000e
+			startp = skipWS( startp );
f5000e
 		}
f5000e
 
f5000e
 		/* locate the end of the OID */
f5000e
@@ -7155,6 +7188,7 @@ schema_berval_to_oclist(struct berval **oc_berval)
f5000e
                 errorbuf[0] = '\0';
f5000e
                 for (i = 0; oc_berval[i] != NULL; i++) {
f5000e
                         /* parse the objectclass value */
f5000e
+                        oc = NULL;
f5000e
                         if (LDAP_SUCCESS != (rc = parse_oc_str(oc_berval[i]->bv_val, &oc,
f5000e
                                 errorbuf, sizeof (errorbuf), DSE_SCHEMA_NO_CHECK | DSE_SCHEMA_USE_PRIV_SCHEMA, 0,
f5000e
                                 schema_ds4x_compat, oc_list))) {
f5000e
@@ -7197,12 +7231,13 @@ schema_berval_to_atlist(struct berval **at_berval)
f5000e
         errorbuf[0] = '\0';
f5000e
         for (i = 0; at_berval[i] != NULL; i++) {
f5000e
             /* parse the objectclass value */
f5000e
+            at = NULL;
f5000e
             rc = parse_at_str(at_berval[i]->bv_val, &at, errorbuf, sizeof (errorbuf),
f5000e
                     DSE_SCHEMA_NO_CHECK | DSE_SCHEMA_USE_PRIV_SCHEMA, 0, schema_ds4x_compat, 0);
f5000e
             if (rc) {
f5000e
                 slapi_log_error(SLAPI_LOG_FATAL, "schema",
f5000e
-                                "parse_oc_str returned error: %s\n",
f5000e
-                                errorbuf[0]?errorbuf:"unknown");
f5000e
+                                "schema_berval_to_atlist: parse_at_str(%s) failed - %s\n",
f5000e
+                                at_berval[i]->bv_val, errorbuf[0]?errorbuf:"unknown");
f5000e
                 attr_syntax_free(at);
f5000e
                 break;
f5000e
             }
f5000e
@@ -7217,6 +7252,7 @@ schema_berval_to_atlist(struct berval **at_berval)
f5000e
     }
f5000e
     if (rc) {
f5000e
         schema_atlist_free(head);
f5000e
+        head = NULL;
f5000e
     }
f5000e
 
f5000e
     return head;
f5000e
@@ -7319,12 +7355,12 @@ schema_attributetypes_superset_check(struct berval **remote_schema, char *type)
f5000e
 static void
f5000e
 modify_schema_internal_mod(Slapi_DN *sdn, Slapi_Mods *smods)
f5000e
 {
f5000e
-        Slapi_PBlock *newpb;
f5000e
+	Slapi_PBlock *newpb;
f5000e
 	int op_result;
f5000e
-        CSN *schema_csn;
f5000e
+	CSN *schema_csn;
f5000e
         
f5000e
-        /* allocate internal mod components: pblock*/
f5000e
-        newpb = slapi_pblock_new();
f5000e
+	/* allocate internal mod components: pblock*/
f5000e
+	newpb = slapi_pblock_new();
f5000e
         
f5000e
 	slapi_modify_internal_set_pb_ext (
f5000e
 			newpb,
f5000e
@@ -7333,7 +7369,7 @@ modify_schema_internal_mod(Slapi_DN *sdn, Slapi_Mods *smods)
f5000e
 			NULL, /* Controls */
f5000e
 			NULL,
f5000e
 			(void *)plugin_get_default_component_id(),
f5000e
-			0);	
f5000e
+			0);
f5000e
 
f5000e
 	/* do modify */
f5000e
 	slapi_modify_internal_pb (newpb);
f5000e
-- 
f5000e
2.4.11
f5000e