1 2 Previous Next 23 Replies Latest reply on May 16, 2011 7:18 PM by Al_Maline Go to original post
      • 15. Re: JNDI, Active Directory & Persistent Searches (part 1)

        I am using Sun LDAP Booster pack for retrieving changes from Active directory and synchronize some data with an application database. My problem is I need to use DirSyncControl and PagedResultsControl in the same LdapContext. But some how this is not working together. When I add both the controls always DirSyncControl takes precedence and paging never happens. If used seperately both the control works fine. Am I missing some thing here or this is a known limitation? Here is code snippet where i add both controls.
        Control[] ctls = new Control[] {new DirSyncControl(), new PagedResultsControl(pageSize)};
        Thanks in Advance
        • 16. Re: JNDI, Active Directory & Persistent Searches (part 1)
          Steven or anyone else,

          Can you provide me some hint on this issue which i posted above

          • 17. Re: JNDI, Active Directory & Persistent Searches (part 1)
            Sorry for my tardy reply, kind of slipped through the gaps.

            I don't think there is any reason to use the paged results control & dirsync control together.

            To the best of my knowledge AD will only return "max page size" results in each search reponse.

            I'm guessing that you are issuing a search request, retrieving the results and then based on a schedule, reissuing the search using the returned cookie. The problem is performing the initial sync, you want to return all of the results and then begin the schedule.

            What you need to do is examine the response controls for the value of "hasMoreData".

            I must apologize that in my original sample code I omitted that property of the response control and you would have been unaware of it's existence without referring to the Sun Dirsync Response Control documentation. The code should look like:
            //save the response controls
            if ((rspCtls = ctx.getResponseControls()) != null) {
                 System.out.println("Response Controls: " + rspCtls.length);
                 for (int i=0; i < rspCtls.length;i++) {
                      if (rspCtls[i] instanceof DirSyncResponseControl) {
                           DirSyncResponseControl rspCtl = (DirSyncResponseControl)rspCtls;
                           cookie = rspCtl.getCookie();
                           System.out.println("Flag: " + rspCtl.getFlag());
                           System.out.println("Length: " + rspCtl.getMaxReturnLength());
                           System.out.println("More Data: " + rspCtl.hasMoreData());
                           System.out.println("Cookie: " + cookie.toString());

            What you need to do is submit the initial search, examine the response control for hasMoreData, continue until hasMoreData is false, and then begin the schedule.

            BTW, I should mention two other things, firstly the constructor for the Dirsync Control does support additional parameters.
            Control[] ctls = new Control[] {new DirSyncControl(flags,maxResultSetSize,cookie,criticality)};
            Secondly there are different flags that can be included in the control, which are documented at http://msdn2.microsoft.com/en-us/library/aa366978.aspx.

            For example if searching for changes in group memberships, to avoid the maximum number of values that can be returned for a multi-valued attribute (refer to the post "JNDI, Active Directory, Paging and Range Retrieval" at http://forum.java.sun.com/thread.jspa?threadID=578347&tstart=0) you should be using LDAP_DIRSYNC_INCREMENTAL_VALUES in which case you will need to parse the search response values, which will be of the form:

            member;range1-1:<dn> which indicates an attribute value addition
            member;range;0-0:<dn> which indicates an attribute value deletion

            Hope this helps.
            • 18. Re: JNDI, Active Directory & Persistent Searches (part 1)
              I`ve been research for this error message *"[LDAP: error code 53 - 000020F7: LdapErr: DSID-0C0907FA, comment: Error processing control, data 0, vece"* that I got when execute both samples (delchanges and modchanges).

              Does anybody known what's happenig ?

              • 19. Re: JNDI, Active Directory & Persistent Searches (part 1)

                I've got the answer ! This occurs because the name of the context or object to search (search base) has somenthing wrong.

                In my case I had "OU=??, DC=??, DC=??, DC=??" when I a changed to "DC=??, DC=??, DC=??" it works.

                I hope this help.

                • 20. Re: JNDI, Active Directory & Persistent Searches (part 1)
                  hi steven,
                  I have tried some test following your directions, but the returned search result is NOT consistent to the "*maxResultSetSize*", always to be the all modified items in a return, "*maxResultSetSize*" seems not to wotk at all, any idea about it? please give me a hand. thanks in advance.
                  • 21. Re: JNDI, Active Directory & Persistent Searches (part 1)
                    I also tried to do the DirSyncControl with the LDAP_DIRSYNC_INCREMENTAL_VALUES flag enabled, but seem to get all the values for the "member" attribute. Through other documentation, I found out that the LDAP_DIRSYNC_INCREMENTAL_VALUES is 0x80000000. I used this post as a reference for making another Control called DirSyncControlWithFlags ("JNDI, Active Directory and LDAP Extended Controls (LDAP Stats, Verify Name)" at http://forums.sun.com/thread.jspa?threadID=5117992&tstart=465). I specified "member;range=1-1" for the returned attributes as well. The DirSyncControlWithFlags control functions just fine except for the fact that it still returns every single value for "member" changes.

                    Here's the constructor from the class:
                    public DirSyncControlWithFlags(int maxAttrCount, byte[] cookie) {
                              try {
                                   //Flags = 0
                                   int value = 0x80000000;
                                   ASN1Integer asnFlag = new ASN1Integer(value);
                                   //Result set size
                                   ASN1Integer asnAttrSize = new ASN1Integer(maxAttrCount);
                                   //Octet String cookie
                                   ASN1OctetString asnString = new ASN1OctetString(cookie);
                                   ASN1Sequence asnSequence = new ASN1Sequence();
                                   ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
                                   ASN1Writer aw = new ASN1Writer(byteOut);
                                   asn = byteOut.toByteArray();
                              catch (UnsupportedEncodingException e) {
                                   System.err.println("Problem encoding " + e);
                              catch (IOException e) {
                                   System.err.println("ASN1/BER Encoding error: " + e);
                    The fact that it works is promising, but it would be nice to have only the changed value returned like the documentation says it should. Any ideas?
                    • 22. Re: JNDI, Active Directory & Persistent Searches (part 1)
                      I discovered that my problem was that I was not at forest functionality Windows 2003. Previously only the domain functionality was at Windows 2003. Program works now.
                      • 23. Re: JNDI, Active Directory & Persistent Searches (part 1)
                        Used your example to get it working with the LDAP booster pack. Had to use some different flags since without the LDAP_DIRSYNC_OBJECT_SECURITY (value 1) I was getting a permission error.
                        package org.yourorg.utilities.ldap;
                        import com.sun.jndi.ldap.*;
                        import java.io.IOException;
                          // The DirectoryAttribute “member;range=0-0″ contains all delete operations
                          // The DirectoryAttribute “member;range=1-1″ contains all add operations 
                        public class DirSyncControlWithFlags extends BasicControl {
                          public static final String OID = "1.2.840.113556.1.4.841";
                          private static final byte[] EMPTY_COOKIE = new byte[0];
                          private  int flags=0x80000801;
                          public DirSyncControlWithFlags()
                              throws IOException
                              super(OID, true, null);
                              //int maxReturnLength = 0x7fffffff;
                              //cookie = new byte[0];
                              super.value = setEncodedValue(Integer.MAX_VALUE,EMPTY_COOKIE);
                          public DirSyncControlWithFlags(int flags) throws IOException {
                            super(OID, true, null);
                            super.value = setEncodedValue(Integer.MAX_VALUE,EMPTY_COOKIE);
                          public DirSyncControlWithFlags(int maxAttrCount, boolean criticality) throws IOException {
                            super(OID, criticality, null);
                          public DirSyncControlWithFlags(int maxAttrCount,boolean criticality, byte[] cookie) throws IOException {
                          private byte[] setEncodedValue(int maxAttrCount, byte[] cookie) throws IOException {
                            BerEncoder ber=new BerEncoder(64);
                            ber.beginSeq(48); // (Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
                            ber.encodeOctetString(cookie, 4); // (cookie, Ber.ASN_OCTET_STR);
                            return ber.getTrimmedBuf();
                        1 2 Previous Next