Просмотр исходного кода

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.
Nathan Kinder 15 лет назад
Родитель
Сommit
0f4979332c
2 измененных файлов с 52 добавлено и 7 удалено
  1. 47 7
      ldap/servers/plugins/mep/mep.c
  2. 5 0
      ldap/servers/plugins/mep/mep.h

+ 47 - 7
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.");

+ 5 - 0
ldap/servers/plugins/mep/mep.h

@@ -89,6 +89,11 @@
 #define MEP_TEMPLATE_OC "mepTemplateEntry"
 #define MEP_ORIGIN_OC   "mepOriginEntry"
 
+/*
+ * Helper defines
+ */
+#define IS_ATTRDESC_CHAR(c) ( isalnum(c) || (c == '.') || (c == ';') || (c == '-') )
+
 /*
  * Linked list of config entries.
  */