From 0f4979332c73b48eefa0ad36e87437c37bee668d Mon Sep 17 00:00:00 2001 From: Nathan Kinder Date: Nov 30 2010 22:59:48 +0000 Subject: Bug 658312 - Allow mapped attribute types to be quoted This patch enhances the way mapped attributes can be defined in a managed entry template. There are three scenarios that this patch adds support for. The first is to allow a mapping in the template entry that maps the DN like this: attr: $dn The second thing is to stop parsing an attribute variable at the first character that is not legal in an attribute name (see RFC 4512 for what is legal). This allows a mapping like this to work: attr: cn=$cn,dc=example,dc=com The third thing is to allow quoting of an attribute variable. This allows one to append anything to the end of a mapped attribute value, even if it begins with a character that is valid for use in an attribute name. An example of this sort of mapping is: attr: ${cn}test I also fixed a crash that could occur when one created an invalid managed entry template. The test managed entry that is created from the pending template ends up being NULL, but we still try to check if that entry violates the schema. If the test entry is not able to be created, we should not try to check it against the schema as that causes a NULL dereference. --- diff --git a/ldap/servers/plugins/mep/mep.c b/ldap/servers/plugins/mep/mep.c index cb329e4..9436332 100644 --- a/ldap/servers/plugins/mep/mep.c +++ b/ldap/servers/plugins/mep/mep.c @@ -1325,19 +1325,48 @@ mep_parse_mapped_attr(char *mapping, Slapi_Entry *origin, /* This is an escaped $, so just skip it. */ p++; } else { + int quoted = 0; + /* We found a variable. Terminate the pre * string and process the variable. */ *p = '\0'; p++; + /* Check if the variable name is quoted. If it is, we skip past + * the quoting brace to avoid putting it in the mapped value. */ + if (*p == '{') { + quoted = 1; + if (p < end) { + p++; + } else { + slapi_log_error( SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM, + "mep_parse_mapped_attr: Invalid mapped " + "attribute value for type \"%s\".\n", mapping); + ret = 1; + goto bail; + } + } + /* We should be pointing at the variable name now. */ var_start = p; - /* Move the pointer to the end of the variable name. */ - while ((p < end) && !isspace(*p)) { + /* Move the pointer to the end of the variable name. We + * stop at the first character that is not legal for use + * in an attribute description. */ + while ((p < end) && IS_ATTRDESC_CHAR(*p)) { p++; } + /* If the variable is quoted and this is not a closing + * brace, there is a syntax error in the mapping rule. */ + if (quoted && (*p != '}')) { + slapi_log_error( SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM, + "mep_parse_mapped_attr: Invalid mapped " + "attribute value for type \"%s\".\n", mapping); + ret = 1; + goto bail; + } + /* Check for a missing variable name. */ if (p == var_start) { break; @@ -1352,7 +1381,13 @@ mep_parse_mapped_attr(char *mapping, Slapi_Entry *origin, if (p == end) { post_str = ""; } else { - post_str = p; + /* If the variable is quoted, don't include + * the closing brace in the post string. */ + if (quoted) { + post_str = p+1; + } else { + post_str = p; + } } /* We only support a single variable, so we're done. */ @@ -1363,7 +1398,14 @@ mep_parse_mapped_attr(char *mapping, Slapi_Entry *origin, if (map_type) { if (origin) { - char *map_val = slapi_entry_attr_get_charptr(origin, map_type); + char *map_val = NULL; + + /* If the map type is dn, fetch the origin dn. */ + if (slapi_attr_type_cmp(map_type, "dn", SLAPI_TYPE_CMP_EXACT) == 0) { + map_val = slapi_entry_get_ndn(origin); + } else { + map_val = slapi_entry_attr_get_charptr(origin, map_type); + } if (map_val) { /* Create the new mapped value. */ @@ -1625,9 +1667,7 @@ mep_pre_op(Slapi_PBlock * pb, int modop) errstr = slapi_ch_smprintf("Changes result in an invalid " "managed entries template."); ret = LDAP_UNWILLING_TO_PERFORM; - } - - if (slapi_entry_schema_check(NULL, test_entry) != 0) { + } else if (slapi_entry_schema_check(NULL, test_entry) != 0) { errstr = slapi_ch_smprintf("Changes result in an invalid " "managed entries template due " "to a schema violation."); diff --git a/ldap/servers/plugins/mep/mep.h b/ldap/servers/plugins/mep/mep.h index 9cbd204..e2e680c 100644 --- a/ldap/servers/plugins/mep/mep.h +++ b/ldap/servers/plugins/mep/mep.h @@ -90,6 +90,11 @@ #define MEP_ORIGIN_OC "mepOriginEntry" /* + * Helper defines + */ +#define IS_ATTRDESC_CHAR(c) ( isalnum(c) || (c == '.') || (c == ';') || (c == '-') ) + +/* * Linked list of config entries. */ struct configEntry {