1

Scenario 1: I am able to obtain objectGUID from active directory but it's not in readable string format. Also we need to store it in db with decoded format. With the given example in the provided link "http://www.developerscrappad.com/1109/windows/active-directory/java-ldap-jndi-2-ways-of-decoding-and-using-the-objectguid-from-windows-active-directory/", it demonstrates how to decode objectGUID, but they considered objectGUID length 16 byte(128 bit). In our case, when I try to obtain objectGUID, i get more than 128 bit and sometime i get less than 128 bit i.e we don't get specific bit length. My implemented code for the reference:

public class GetLDAPUsers {

public static void main(String args[]) {
    new GetLDAPUsers().getUserFromAD();
}

void getUserFromAD() {
    try {
        LDAPConnection connection = new LDAPConnection("192.xxx.xx.xxx", 389);
        System.out.println(connection);
        String baseDN = "DC=wcomp1,DC=com";
        String[] attributes = { "entryUUID", "sn", "mail", "givenName",
                "objectGUID", "userAccountControl", "isDeleted", "modifyTimestamp", "WhenChanged", "WhenCreated"};
        // Set Ldap Connection Options for server timeout
        LDAPConnectionOptions connOption = new LDAPConnectionOptions();
        connOption.setAutoReconnect(true);
        connOption.setConnectTimeoutMillis(55000);
        connection.setConnectionOptions(connOption);
        //connection bind
        connection.bind("CN=abc,CN=ab,DC=users,DC=com", "password");
        System.out.println("connection successfully");

        //search filter query for search specific user,for all users use (&(objectclass=User)) filter.
        Filter filter = Filter.create("(&(objectclass=User)(givenName=testUserName))");
        SearchRequest searchRequest = new SearchRequest(baseDN, SearchScope.SUB, filter,
                attributes);
        SearchResult searchResult = connection.search(searchRequest);
        //get user detail
        for (SearchResultEntry searchResultEntry : searchResult.getSearchEntries()) {


            System.out.println("user name " + searchResultEntry.getAttribute("givenName").getValue() + 
                    searchResultEntry.getAttribute("objectGUID").getValue()); //We get here objectGUID string which unreadable format 

            //We convert here objectGUID in dashed string 
            System.out.println("decoded objectGUID = " + convertToDashedString(searchResultEntry.getAttribute("objectGUID").getValue().getBytes()));
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
}

public static String convertToDashedString(byte[] objectGUID) {
    StringBuilder displayStr = new StringBuilder();
    displayStr.append(prefixZeros((int) objectGUID[3] & 0xFF));
    displayStr.append(prefixZeros((int) objectGUID[2] & 0xFF));
    displayStr.append(prefixZeros((int) objectGUID[1] & 0xFF));
    displayStr.append(prefixZeros((int) objectGUID[0] & 0xFF));
    displayStr.append("-");
    displayStr.append(prefixZeros((int) objectGUID[5] & 0xFF));
    displayStr.append(prefixZeros((int) objectGUID[4] & 0xFF));
    displayStr.append("-");
    displayStr.append(prefixZeros((int) objectGUID[7] & 0xFF));
    displayStr.append(prefixZeros((int) objectGUID[6] & 0xFF));
    displayStr.append("-");
    displayStr.append(prefixZeros((int) objectGUID[8] & 0xFF));
    displayStr.append(prefixZeros((int) objectGUID[9] & 0xFF));
    displayStr.append("-");
    displayStr.append(prefixZeros((int) objectGUID[10] & 0xFF));
    displayStr.append(prefixZeros((int) objectGUID[11] & 0xFF));
    displayStr.append(prefixZeros((int) objectGUID[12] & 0xFF));
    displayStr.append(prefixZeros((int) objectGUID[13] & 0xFF));
    displayStr.append(prefixZeros((int) objectGUID[14] & 0xFF));
    displayStr.append(prefixZeros((int) objectGUID[15] & 0xFF));
    return displayStr.toString();
}


private static String prefixZeros(int value) {
    if (value <= 0xF) {
        StringBuilder sb = new StringBuilder("0");
        sb.append(Integer.toHexString(value));

        return sb.toString();

    } else {
        return Integer.toHexString(value);
    }
}

}

Scenario 2: Also when i try to fetch objectGUID using above example in windows environment and linux environment I get different objectGUID for the same user.

  • I am guessing from the information you provided that your issue is addressed in the URL: https://ldapwiki.com/wiki/Universally%20Unique%20Identifier#section-Universally+Unique+Identifier-BinaryEncoding Provide some more informaiton and or some code samples. – jwilleke Oct 19 '15 at 23:11
  • thanks jeemster for your comments but i am not able to open you provided link. – Dhanaji Nalawade Oct 23 '15 at 14:20
  • Try: http://ldapwiki.com/wiki/Universally%20Unique%20Identifier#section-Universally+Unique+Identifier-BinaryEncoding – jwilleke Oct 24 '15 at 15:28
  • Typecasting every byte to `(int)` is unnecessary in _convertToDashedString_. Bitwise AND causes [Binary Numeric Promotion](https://docs.oracle.com/javase/specs/jls/se10/html/jls-5.html#jls-5.6.2) of *byte* (objectGUID[xx]) to *int* unconditionally (not because the second operand _0xFF_ is *int*). – Ivan A. Malich Jun 14 '23 at 11:08

4 Answers4

2

You cannot interpret the ObjectGUID as a string. Normally, I would set directory context environment to return ObjectGUID as a byte[] and then use the convert method

env.put("java.naming.ldap.attributes.binary", "ObjectGUID");

String newGuid = convertToDashedString(guid);
RamPrakash
  • 1,687
  • 3
  • 20
  • 25
Carl Young
  • 21
  • 2
2

You can simply do this:

public static String getGuidFromByteArray(byte[] bytes) {
    ByteBuffer bb = ByteBuffer.wrap(bytes);
    long high = bb.getLong();
    long low = bb.getLong();
    UUID uuid = new UUID(high, low);
    return uuid.toString();
}
bradvido
  • 2,743
  • 7
  • 32
  • 49
  • 1
    This is a perfect answer, and deserve upvote, thanks @bradvido for the solution :) – user2730259 Apr 26 '21 at 12:25
  • but it doesn't maintain bytes order - symbols are reversed in the resulting dash-separated string compared to AD-provided string – Ivan A. Malich Jun 14 '23 at 10:42
  • The string returned from this function matches exactly what I see for objectSID in Active Directory Users & Computers attributes tab – bradvido Jun 24 '23 at 14:20
1

For Spring: to inject property

java.naming.ldap.attributes.binary

correctly into ldapTemplate.

https://stackoverflow.com/a/52209645/406065

Dmitry
  • 557
  • 5
  • 12
0

Corrections in above code: searchResultEntry.getAttribute("objectGUID").getValueByteArray()

This above will give you the byte array that you can use to encode with Base64.

The below is wrong: searchResultEntry.getAttribute("objectGUID").getValue().getBytes() will convert the result to String and then to bytes which is incorrect.