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