0

I am using the code below to read example 6 from http://www.ietf.org/rfc/rfc2849.txt I am using unboundid-ldapsdk version 4.0.6. I get the following exception Entries read:3 Entries with error:1 LDIFException(lineNumber=23, mayContinueReading=true, message='The record starting at or near line number 23 contains a line that does not begin with an attribute name followed by a colon.', dataLines='dn: ou=PD Accountants, ou=Product Development, dc=airius, dc=com{end-of-line}changetype: modrdn{end-of-line}newrdn: ou=Product Development Accountants{end-of-line}deleteoldrdn: 0{end-of-line}newsuperior: ou=Accounting, dc=airius, dc=com{end-of-line}dn: cn=Paula Jensen, ou=Product Development, dc=airius, dc=com{end-of-line}changetype: modify{end-of-line}add: postaladdress{end-of-line}postaladdress: 123 Anystreet $ Sunnyvale, CA $ 94086{end-of-line}-{end-of-line}') at com.unboundid.ldif.LDIFReader.parseAttributes(LDIFReader.java:2744) at com.unboundid.ldif.LDIFReader.decodeEntry(LDIFReader.java:2070)

Is there something missing in UnboudId implementation for parsing LDIF files? I was facing similar errors when trying to read an actual LDIF file. I went through the documentation which mentions that it is as per RFC 2849.

Sample code -

public class ReadLDFDemo {
    private final String example6 = "version: 1\n"
            + "# Add a new entry\n"
            + "dn: cn=Fiona Jensen, ou=Marketing, dc=airius, dc=com\n"
            + "changetype: add\n"
            + "objectclass: top\n"
            + "objectclass: person\n"
            + "objectclass: organizationalPerson\n"
            + "cn: Fiona Jensen\n"
            + "sn: Jensen\n"
            + "uid: fiona\n"
            + "telephonenumber: +1 408 555 1212\n"
//            + "jpegphoto:< file:///usr/local/directory/photos/fiona.jpg\n"
            + "\n"
            + "# Delete an existing entry\n"
            + "dn: cn=Robert Jensen, ou=Marketing, dc=airius, dc=com\n"
            + "changetype: delete\n"
            + "\n"
            + "# Modify an entry's relative distinguished name\n"
            + "dn: cn=Paul Jensen, ou=Product Development, dc=airius, dc=com\n"
            + "changetype: modrdn\n"
            + "newrdn: cn=Paula Jensen\n"
            + "deleteoldrdn: 1\n"
            + "\n"
            + "# Rename an entry and move all of its children to a new location in\n"
            + "# the directory tree (only implemented by LDAPv3 servers).\n"
            + "dn: ou=PD Accountants, ou=Product Development, dc=airius, dc=com\n"
            + "changetype: modrdn\n"
            + "newrdn: ou=Product Development Accountants\n"
            + "deleteoldrdn: 0\n"
            + "newsuperior: ou=Accounting, dc=airius, dc=com\n"
            + "# Modify an entry: add an additional value to the postaladdress\n"
            + "# attribute, completely delete the description attribute, replace\n"
            + "# the telephonenumber attribute with two values, and delete a specific\n"
            + "# value from the facsimiletelephonenumber attribute\n"
            + "dn: cn=Paula Jensen, ou=Product Development, dc=airius, dc=com\n"
            + "changetype: modify\n"
            + "add: postaladdress\n"
            + "postaladdress: 123 Anystreet $ Sunnyvale, CA $ 94086\n"
            + "-\n"
            + "\n"
            + "delete: description\n"
            + "-\n"
            + "replace: telephonenumber\n"
            + "telephonenumber: +1 408 555 1234\n"
            + "telephonenumber: +1 408 555 5678\n"
            + "-\n"
            + "delete: facsimiletelephonenumber\n"
            + "facsimiletelephonenumber: +1 408 555 9876\n"
            + "-\n"
            + "\n"
            + "# Modify an entry: replace the postaladdress attribute with an empty\n"
            + "# set of values (which will cause the attribute to be removed), and\n"
            + "# delete the entire description attribute. Note that the first will\n"
            + "# always succeed, while the second will only succeed if at least\n"
            + "# one value for the description attribute is present.\n"
            + "dn: cn=Ingrid Jensen, ou=Product Support, dc=airius, dc=com\n"
            + "changetype: modify\n"
            + "replace: postaladdress\n"
            + "-\n"
            + "delete: description\n"
            + "-";

public void readLDFSamples() {
        System.out.println(example6);
        InputStream inputStream =
                new ByteArrayInputStream(example6.getBytes());
        readUnboundIdLdifFile(inputStream);
    }

    private void readUnboundIdLdifFile(InputStream inputStream) {
        LDIFReader ldifReader = null;
        try {
            ldifReader = new LDIFReader(inputStream);
            Entry entry = null;
            long count = 0;
            long errorCount = 0;
            while (true) {
                try {
                    entry = ldifReader.readEntry();
                    count++;
                    if (entry == null) {
                        break;
                    }
                } catch (LDIFException ldifE) {
                    errorCount++;
                    ldifE.printStackTrace();
                    break;
                }
            }
            System.out.println("Entries read:" + count + " Entries with error:"
                    + errorCount);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (ldifReader != null) {
                    ldifReader.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
Jyothrilinga K
  • 307
  • 3
  • 10
  • Despite the LDIF syntax error the above looks awful. Why don't you directly use the API methods for modifying entries instead? – Michael Ströder Aug 05 '18 at 16:44
  • @MichaelStröder The use case is to store a part of LDAP entries for disaster recovery. I would be periodically reading the generated LDIF backup files and be able to create a new site populated with the entries. – Jyothrilinga K Aug 05 '18 at 17:58
  • Then I'd recommend to test with the LDIF backup data which is likely correct LDIF. – Michael Ströder Aug 05 '18 at 19:43

1 Answers1

0

There is an empty separator line missing between these two lines in your source:

        + "newsuperior: ou=Accounting, dc=airius, dc=com\n"
        + "# Modify an entry: add an additional value to the postaladdress\n"

So the second change record gets parsed as continuation of the modrdn change record.

Michael Ströder
  • 1,248
  • 8
  • 12
  • Thanks for the input. That fixes the line. I missed the line at end of page! However, I now see error `message='The record starting at or near line number 31 contains a line that does not begin with an attribute name followed by a colon.', dataLines='dn: cn=Paula Jensen, ou=Product Development, dc=airius, dc=com{end-of-line}changetype: modify{end-of-line}add: postaladdress{end-of-line}postaladdress: 123 Anystreet $ Sunnyvale, CA $ 94086{end-of-line}-{end-of-line}')` – Jyothrilinga K Aug 05 '18 at 18:06
  • Please read my answer again and find the affected line in your code. Hint: The comment lines likely do not separate the LDIF change records. – Michael Ströder Aug 05 '18 at 19:45
  • I have separated the comment line and that works. Now I am getting error while reading https://pastebin.com/9W8LG894 I tried adding separator after `-`. I'll accept ur answer as it addresses the issue I posted. I'll open a new question if you would like. – Jyothrilinga K Aug 05 '18 at 20:01