Announcement Announcement Module
No announcement yet.
ModDN Operations Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • ModDN Operations


    I got a quick question for ya about Mod DN (rename) operations... when I do an ldapmoddn from the command line (using the SunONE Directory Resource Kit) I get the following log entry:

    20090609.180536.771 "cn=admin,ou=applications,o=company" MODDN "uid=sz3_0498,ou=grp8,ou=Subscribers,o=company" "uid=sz3_0498_temp"
    However, when I use the rename operation in Spring, the log entry shows up as:

    20090609.180544.990 "cn=admin,ou=Applications,o=company" MODDN "uid=sz3_0498_temp,ou=grp8,ou=Subscribers,o=company" "uid=sz3_0498" newSuperior="ou=grp8,ou=Subscribers,o=company"
    It would appear as though the operation is coming down as a modification to the base DN by default, rather than just a modification to the rdn...

    $ ldapmoddn -h
    usage: c:\oracle\product\10.2.0\client_1\bin\ldapmoddn.exe [options]
        -D binddn   bind dn
        -w passwd   bind passwd (for simple authentication)
        -b basedn (dn of the entry to be moved)
        -R newrdn (new rdn)
        -N new parentDN (dn of the parent where this has to be moved)
        -r delete old rdn (if specified removes old rdn )
        -h host     ldap server
        -p port     port on ldap server
        -W Wallet   Wallet location
        -P Wpasswd  Wallet Password
        -U SSLAuth  SSL Authentication Mode
        -q          prompt for simple bind password
        -Q          prompt for SSL wallet password
        -E character set encoding
        -Z [enable native authentication]


  • #2
    This stuff is delegated to the Java LDAP provider; don't know the details of what's happening down there. The key question: is the end result what you would expect (i.e. does the entry end up in the correct place of your LDAP tree)?

    Could you post the actual Spring LDAP renaming statement and the corresponding ldapmoddn statement?


    • #3
      Thats what I thought... didn't think it was you guys. I was just kinda hoping there might have been an option to leverage control features for altering behavior.

      Its not a terrible thing as the rename does happen properly - i.e. it does end up in the desired location.

      The code used to execute the rename from the DAO:

      public void rename(GdsSubscriberObject subscriber, String name) {
      		LdapOperations ldapOperations = _ldapTemplate.getLdapOperations();
      		DistinguishedName dn = subscriber.getDn();
      		dn.append(key, name);
      		ldapOperations.rename(subscriber.getDn(), dn);
      The corresponding ldapmoddn operation:

      $ ldapmoddn -h -p 30389 -D "cn=anonymous" -w "" -b "uid=sz3_0007,ou=grp9,ou=subscribers,o=company" -R "uid=sz3_0007_temp"
      uid=sz3_0007,ou=grp9,ou=subscribers,o=company renamed successfully.
      The logs for the command-line version produce:

      20090609.180536.771 (none) MODDN "uid=sz3_0007,ou=grp9,ou=Subscribers,o=company" "uid=sz3_0007_temp"
      The only reason its even an issue for us is that we have a propagation service that listens to the log files for updates to the directory. They are not reading the log entries correctly when a new base DN is specified (which we will have to have fixed as this is a perfectly valid LDAP operation). However, from the pragmatic front, I was curious to see if there was a way to simply execute a mod RDN.

      PS. Do you know who the default provider is? When using JNDI we have to specify a provider in the connection details I believe but Spring does not require that - do you default to a specific provider?




      • #4
        You might want to try experimenting with the base DN on the ContextSource. I'm thinking if the base DN would be parent of the entry you're trying to rename you will get a different behavior.

        The default LDAP provider is the built-in one: com.sun.jndi.ldap.LdapCtxFactory


        • #5
          I'll look into it...




          • #6
            Well... I haven't tested your idea yet... thought it might work, something bothered me: it seemed like a workaround for an operation that is defined by the LDAP RFC.

            So I did some poking around... I decided to look and see how JXplorer does it because the logs on modifications of those entries show only the RDN being modified, not the whole DN.

            Here is what I found - they leverage an environment property to make RDN modifications. See below:


                 * This method allows an object to be renamed, while also specifying
                 * the exact fate of the old name.
                 * @param OldDN        the original name to be changed
                 * @param NewDN        the new name
                 * @param deleteOldRDN whether the rdn of the old name should be removed,
                 *                     or retained as a second attribute value.
                public void renameEntry(Name OldDN, Name NewDN, boolean deleteOldRDN)
                        throws NamingException
                    String value = (deleteOldRDN) ? "true" : "false";
                        ctx.addToEnvironment("java.naming.ldap.deleteRDN", value);
                        renameEntry(OldDN, NewDN);
                        ctx.addToEnvironment("java.naming.ldap.deleteRDN", "false");  // reset to default of 'false' afterwards.
                    catch (NamingException e)
                        ctx.addToEnvironment("java.naming.ldap.deleteRDN", "false");  // reset to default of 'false' afterwards.
                        throw e;
            I looked up the property and found that this:

            The value of this property is a string that specifies whether the old RDN is removed by the Context.rename method. The following values are defined for this property:

            delete the old RDN from the entry during the rename operation.
            retain the old RDN as an attribute value of the entry.

            If this property is not set then its default value is true.
            For example:

            env.put("java.naming.ldap.deleteRDN", "false");
            causes the old RDN to be retained as an attribute of the renamed entry.
            Browsing the source code, I don't think this property is set anywhere for Spring, I think its just left to the default. However, the description doesn't really seem like the answer and setting the environment property in my code doesn't seem to help:

            Map<String, String> baseEnvironmentProperties = new HashMap<String, String>();
            		baseEnvironmentProperties.put("java.naming.ldap.deleteRDN", "false");
            Something tells me there is a property I am missing as they use the same default provider.