Bug 488814 - mapping tree code inconsistent about treatment of quoted node names
Summary: mapping tree code inconsistent about treatment of quoted node names
Keywords:
Status: CLOSED CURRENTRELEASE
Alias: None
Product: Red Hat Directory Server
Classification: Red Hat
Component: Directory Server
Version: 8.0
Hardware: All
OS: All
low
medium
Target Milestone: ---
: ---
Assignee: Rich Megginson
QA Contact: Chandrasekar Kannan
URL:
Whiteboard:
Depends On:
Blocks: 249650 FDS1.2.0
TreeView+ depends on / blocked
 
Reported: 2009-03-05 20:06 UTC by Ulf Weltman
Modified: 2015-01-04 23:36 UTC (History)
4 users (show)

Fixed In Version: 8.1
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2009-04-29 23:11:10 UTC
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)

Description Ulf Weltman 2009-03-05 20:06:11 UTC
When a new mapping tree node is added over the wire, the callback mapping_tree_entry_add() handles it.  This function looks through the entry and handles the various important attributes.  In particular, it finds the nsslapd-parent-suffix attribute to see if we're adding a child-node (sub-suffix).  We use get_parent_from_entry() to get the value, e.g. ""dc=example,dc=com"" (literal quotes).  get_parent_from_entry() strips off quotes if they are present before searching for existing in-memory parent node.

This means that a child node like this:
dn: cn="ou=test,dc=example,dc=com",cn=mapping tree,cn=config
objectClass: top
objectClass: nsMappingTree
objectClass: extensibleObject
nsslapd-state: backend
nsslapd-backend: testRoot
nsslapd-parent-suffix: dc=example,dc=com
cn: "ou=test,dc=example,dc=com"

Would be considered a valid child-node of:
dn: cn="dc=example,dc=com",cn=mapping tree,cn=config
objectClass: top
objectClass: nsMappingTree
objectClass: extensibleObject
nsslapd-state: backend
nsslapd-backend: userRoot
cn: "dc=example,dc=com"

Normally it wouldn't, since "dc=example,dc=com" is not equivalent to ""dc=example,dc=com"" (literal quotes).

This allows a sub-suffix to be added over the wire with the parent suffix specified with or without quotes.

The problem comes after a restart.  When the mapping tree is initialized from dse.ldif, the quotes ARE significant because the function mapping_tree_node_get_children() performs searches like "(&(objectclass=nsMappingTree)(%s=\"%s\"))".  Note the literal quotes in the search filter.  This means the sub-suffix will not be usable after a restart because it will not be found by the search.

Comment 1 Rich Megginson 2009-03-05 20:21:15 UTC
I've noticed this too, recently.  We used to have this:
cn: "dc=example,dc=com"
cn: dc=example,dc=com

But now it's only the one with the quotes.

Comment 2 Noriko Hosoi 2009-03-05 22:50:44 UTC
It was introduced by this change I made to fix bz#438139:

https://bugzilla.redhat.com/attachment.cgi?id=328240&action=diff#util.c_sec1/

I accidentally removed this case for '"'. :(
Index: util.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/util.c,v
retrieving revision 1.28
diff -t -w -U 8 -r1.28 util.c
--- util.c	4 Feb 2009 18:21:01 -0000	1.28
+++ util.c	5 Mar 2009 22:43:22 -0000
@@ -208,16 +208,18 @@
 strcpy_unescape_value( char *d, const char *s )
 {
     int gotesc = 0;
     const char *end = s + strlen(s);
     for ( ; *s; s++ )
     {
         switch ( *s )
         {
+        case '"':
+            break;
         case '\\':
             if ( gotesc ) {
                 gotesc = 0;
             } else {

By recovering this code, I could resume both cn values:
dn: cn="dc=test,dc=com",cn=mapping tree, cn=config
objectClass: top
objectClass: extensibleObject
objectClass: nsMappingTree
nsslapd-state: Backend
cn: "dc=test,dc=com"
cn: dc=test,dc=com
nsslapd-backend: testRoot

dn: cn="dc=test,dc=example,dc=com",cn=mapping tree, cn=config
objectClass: top
objectClass: extensibleObject
objectClass: nsMappingTree
nsslapd-state: Backend
cn: "dc=test,dc=example,dc=com"
cn: dc=test,dc=example,dc=com
nsslapd-parent-suffix: "dc=example,dc=com"
nsslapd-backend: subtestRoot

B*U*T, except "dc=example,dc=com": the first suffix created at the instance creation...
dn: cn="dc=example,dc=com",cn=mapping tree,cn=config
objectClass: top
objectClass: extensibleObject
objectClass: nsMappingTree
cn: "dc=example,dc=com"
nsslapd-state: backend
nsslapd-backend: userRoot

I'm puzzled why this difference is made...

Comment 3 Ulf Weltman 2009-03-05 23:54:17 UTC
Needing both a quoted and an unquoted value shouldn't really be needed I think.  My concern was that mixing the use of quotes works fine when setting up the mapping tree over LDAP, but when the mapping tree is initialized from dse.ldif it does not work.  Unfortunately the documentation uses mixed quoting which led to some confusing situations where the sub-suffix configuration worked until the instance was restarted.  I filed a separate documentation bug for that: 488818

This bug is low priority in my opinion as long as the documentation is correct.  A quick fix to this bug to make the behavior between adding over LDAP and reading from dse.ldif might be to change the search filter in mapping_tree_node_get_children() to something like this:
"(&(objectclass=nsMappingTree)(|(%s=\"%s\")(%s=%s)))"

Comment 4 Noriko Hosoi 2009-03-06 01:02:39 UTC
I also think that's a good idea.  Something like this, right?

Index: mapping_tree.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/mapping_tree.c,v
retrieving revision 1.17
diff -t -w -U 8 -r1.17 mapping_tree.c
--- mapping_tree.c	4 Dec 2008 00:42:18 -0000	1.17
+++ mapping_tree.c	6 Mar 2009 00:06:34 -0000
@@ -905,17 +905,17 @@
     
     /* Remember that the root node of the mapping tree is the NULL suffix.
      * Since we don't really support it, children of the root node won't
      * have a MAPPING_TREE_PARENT_ATTRIBUTE. */
     if (is_root) {
         filter = slapi_ch_smprintf("(&(objectclass=nsMappingTree)(!(%s=*)))",
                  MAPPING_TREE_PARENT_ATTRIBUTE);
     } else {
-        filter = slapi_ch_smprintf("(&(objectclass=nsMappingTree)(%s=\"%s\"))",
+        filter = slapi_ch_smprintf("(&(objectclass=nsMappingTree)(|(%s=\"%s\")(%s=%s)))",
             MAPPING_TREE_PARENT_ATTRIBUTE, 
             slapi_sdn_get_dn(target->mtn_subtree));
     }

Comment 5 Rich Megginson 2009-03-06 19:25:05 UTC
yes, except the latter diff should be like this:
+        filter =
slapi_ch_smprintf("(&(objectclass=nsMappingTree)(|(%s=\"%s\")(%s=%s)))",
             MAPPING_TREE_PARENT_ATTRIBUTE, 
             slapi_sdn_get_dn(target->mtn_subtree),
             MAPPING_TREE_PARENT_ATTRIBUTE, 
             slapi_sdn_get_dn(target->mtn_subtree));

Comment 6 Noriko Hosoi 2009-03-07 00:46:28 UTC
I tested the change in the comment #5 Rich put.

It passed the mapping tree test 100%.
mappingTree run 	 100% (7/7)

Index: mapping_tree.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/slapd/mapping_tree.c,v
retrieving revision 1.17
diff -t -w -U 8 -r1.17 mapping_tree.c
--- mapping_tree.c	4 Dec 2008 00:42:18 -0000	1.17
+++ mapping_tree.c	7 Mar 2009 00:41:44 -0000
@@ -905,17 +905,19 @@
     
     /* Remember that the root node of the mapping tree is the NULL suffix.
      * Since we don't really support it, children of the root node won't
      * have a MAPPING_TREE_PARENT_ATTRIBUTE. */
     if (is_root) {
         filter = slapi_ch_smprintf("(&(objectclass=nsMappingTree)(!(%s=*)))",
                  MAPPING_TREE_PARENT_ATTRIBUTE);
     } else {
-        filter = slapi_ch_smprintf("(&(objectclass=nsMappingTree)(%s=\"%s\"))",
+        filter = slapi_ch_smprintf("(&(objectclass=nsMappingTree)(|(%s=\"%s\")(%s=%s)))",
+            MAPPING_TREE_PARENT_ATTRIBUTE, 
+            slapi_sdn_get_dn(target->mtn_subtree),
             MAPPING_TREE_PARENT_ATTRIBUTE, 
             slapi_sdn_get_dn(target->mtn_subtree));
     }
 
     slapi_search_internal_set_pb(pb, MAPPING_TREE_BASE_DN, LDAP_SCOPE_ONELEVEL,
         filter, NULL, 0, NULL, NULL, (void *) plugin_get_default_component_id(), 0);
     slapi_search_internal_pb(pb);
     slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &res);

I've marked reviewed.  Rich, could you check in the code?
Thanks!
--noriko

Comment 7 Rich Megginson 2009-03-07 00:59:24 UTC
Checking in mapping_tree.c;
/cvs/dirsec/ldapserver/ldap/servers/slapd/mapping_tree.c,v  <--  mapping_tree.c
new revision: 1.18; previous revision: 1.17
done

Comment 8 Michael Gregg 2009-04-09 23:36:11 UTC
I am able to create cn="dc=example,dc=com" and cn=dc=example,dc=com and I can add sub domains to both without errors upon restart

Verified against 8.1.0-2

Comment 9 Chandrasekar Kannan 2009-04-29 23:11:10 UTC
An advisory has been issued which should help the problem
described in this bug report. This report is therefore being
closed with a resolution of ERRATA. For more information
on therefore solution and/or where to find the updated files,
please follow the link below. You may reopen this bug report
if the solution does not work for you.

http://rhn.redhat.com/errata/RHEA-2009-0455.html


Note You need to log in before you can comment on or make changes to this bug.