Page 1 of 2 12 LastLast
Results 1 to 10 of 13

Thread: objectSID and LdapTemplate

  1. #1
    Join Date
    Jun 2009
    Posts
    6

    Default objectSID and LdapTemplate

    Hi,

    I am using LdapTemplate (spring-ldap-core/1.3.0.RELEASE).

    How can I read the value of the attribute "objectSID" using LdapTemplate?
    How can I find a user given his "objectSID" using LdapTemplate?

    Thank you for your help.
    J.-Cl.

  2. #2
    Join Date
    Jul 2005
    Location
    Helsingborg, Sweden
    Posts
    504

    Default

    The objectSid seems to be a systemOnly attribute. You don't mention any specific problems, so assuming that the attribute is readable, you could probably do something like this:

    Code:
    public class LdapPersonDao implements PersonDao {
       private LdapTemplate ldapTemplate;
       ...
       public String getObjectSidForPerson(DistinguishedName dn) {
          return ldapTemplate.lookup(
             dn, 
             new AbstractContextMapper() {
                public Object doMapFromContext(DirContextOperations ctx) {
                   return ctx.getStringAttribute("objectSid");
                }
             });
       }
    
       public List getPersonsByObjectSid(String sid) {
          AndFilter filter = new AndFilter();
          filter.and(new EqualsFilter("objectclass", "person"));
          filter.and(new EqualsFilter("objectSid", sid));
          return ldapTemplate.search("", filter.encode(), new PersonContextMapper());
       }
    }
    Code:
    public class PersonContextMapper extends AbstractContextMapper {
       public Object doMapFromContext(DirContextOperations ctx) {
          Person p = new Person();
          p.setFullName(context.getStringAttribute("cn"));
          p.setLastName(context.getStringAttribute("sn"));
          p.setDescription(context.getStringAttribute("description"));
          p.setDn(context.getDn());
          return p;
       }
    }
    Ulrik Sandberg
    Jayway (www.jayway.com)
    Spring LDAP project member

  3. #3
    Join Date
    Jun 2009
    Posts
    6

    Default objectSid - Format of the String

    @ulsa
    The objectSid seems to be a systemOnly attribute. You don't mention any specific problems, so assuming that the attribute is readable...
    Thank you for your code snippet. It will help me.

    I still have the following question:
    The value of the attribute 'objectSid' is a binary object. The parameter of '
    Code:
    public List getPersonsByObjectSid(String sid)
    ' is a String.

    How does this String look like? Is it Base64 Encoded?

    Thank you for your advise.

  4. #4
    Join Date
    Jun 2009
    Posts
    6

    Default

    Hi,
    I found this link: http://www.pcreview.co.uk/forums/thread-1458615.php

    So I can implement the search.

    The question now is: How can I convert a String like S-1-5-21-2562418665-3218585558-1813906818-1576 to its binary representation (in this case: {01,05,00,00,00,00,00,05,15,00,00,00,e9,67,bb,98,d 6,b7,d7,bf,82,05,1e,6c,28,06,00,00})

  5. #5
    Join Date
    Jul 2005
    Location
    Helsingborg, Sweden
    Posts
    504

    Default

    I'm considering adding Java 1.4-compatible SID converters to LdapUtils. Meanwhile, try this code. You'll need the ArrayUtils in Commons Lang.

    Code:
    	/**
    	 * Converts a String SID to its binary representation, according to the
    	 * algorithm described <a
    	 * href="http://blogs.msdn.com/oldnewthing/archive/2004/03/15/89753.aspx"
    	 * >here</a>. 
    	 * 
    	 * @param sid SID in readable format
    	 * @return Binary version of the given sid
    	 * @see LdapUtils#convertBinarySidToString(byte[])
    	 * @since 1.3.1
    	 */
    	public static byte[] convertStringSidToBinary(String string) {
    		String[] parts = string.split("-");
    		byte sidRevision = (byte) Integer.parseInt(parts[1]);
    		int subAuthCount = parts.length - 3;
    		
    		byte[] sid = new byte[] {sidRevision, (byte) subAuthCount};
    		sid = ArrayUtils.addAll(sid, numberToBytes(parts[2], 6, true));
    		for (int i = 0; i < subAuthCount; i++) {
    			sid = ArrayUtils.addAll(sid, numberToBytes(parts[3 + i], 4, false));
    		}
    		return sid;
    	}
    
    	/**
    	 * Converts the given number to a binary representation of the specified
    	 * length and "endian-ness".
    	 * 
    	 * @param number String with number to convert
    	 * @param length How long the resulting binary array should be
    	 * @param bigEndian <code>true</code> if big endian (5=0005), or
    	 * <code>false</code> if little endian (5=5000)
    	 * @return byte array containing the binary result in the given order
    	 */
    	static byte[] numberToBytes(String number, int length, boolean bigEndian) {
    		BigInteger bi = new BigInteger(number);
    		byte[] bytes = bi.toByteArray();
    		int remaining = length - bytes.length;
    		if (remaining < 0) {
    			bytes = ArrayUtils.subarray(bytes, -remaining, bytes.length);
    		} else {
    			byte[] fill = new byte[remaining];
    			bytes = ArrayUtils.addAll(fill, bytes);
    		}
    		if (!bigEndian) {
    			ArrayUtils.reverse(bytes);
    		}
    		return bytes;
    	}
    Unit tests for the interested:

    Code:
    	/**
    	 * Hand-crafted SID.
    	 */
    	public void testConvertHandCraftedStringSidToBinary() throws Exception {
    		byte[] expectedSid = { (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x00,
    				(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x05,
    				(byte) 0x15, (byte) 0x00, (byte) 0x00, (byte) 0x00,
    				(byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00,
    				(byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00,
    				(byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00,
    				(byte) 0x04, (byte) 0x00, (byte) 0x00, (byte) 0x00 };
    		byte[] result = LdapUtils.convertStringSidToBinary("S-1-5-21-1-2-3-4");
    		assertTrue("incorrect length of array", ArrayUtils.isSameLength(expectedSid, result));
    		for (int i = 0; i < result.length; i++) {
    			assertEquals("i=" + i + ",", expectedSid[i], result[i]);
    		}
    	}
    
    	/**
    	 * Example SID from "http://www.pcreview.co.uk/forums/thread-1458615.php".
    	 */
    	public void testConvertStringSidToBinary() throws Exception {
    		byte[] expectedSid = { (byte) 0x01, (byte) 0x05, (byte) 0x00, (byte) 0x00,
    				(byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x05,
    				(byte) 0x15, (byte) 0x00, (byte) 0x00, (byte) 0x00,
    				(byte) 0xe9, (byte) 0x67, (byte) 0xbb, (byte) 0x98,
    				(byte) 0xd6, (byte) 0xb7, (byte) 0xd7, (byte) 0xbf,
    				(byte) 0x82, (byte) 0x05, (byte) 0x1e, (byte) 0x6c,
    				(byte) 0x28, (byte) 0x06, (byte) 0x00, (byte) 0x00 };
    		byte[] result = LdapUtils.convertStringSidToBinary("S-1-5-21-2562418665-3218585558-1813906818-1576");
    		assertTrue("incorrect length of array", ArrayUtils.isSameLength(expectedSid, result));
    		for (int i = 0; i < result.length; i++) {
    			assertEquals("i=" + i + ",", expectedSid[i], result[i]);
    		}
    	}
    Ulrik Sandberg
    Jayway (www.jayway.com)
    Spring LDAP project member

  6. #6
    Join Date
    Jul 2005
    Location
    Helsingborg, Sweden
    Posts
    504

    Default

    Added two methods to LdapUtils:

    Code:
    	public static String convertBinarySidToString(byte[] sid);
    	public static byte[] convertStringSidToBinary(String string);
    It's available in trunk. I would appreciate if anyone else could verify them.
    Ulrik Sandberg
    Jayway (www.jayway.com)
    Spring LDAP project member

  7. #7
    Join Date
    Jun 2009
    Posts
    6

    Default

    Quote Originally Posted by ulsa View Post
    Added two methods to LdapUtils:

    Code:
    	public static String convertBinarySidToString(byte[] sid);
    	public static byte[] convertStringSidToBinary(String string);
    It's available in trunk. I would appreciate if anyone else could verify them.
    Thank you very much.

    Yet another Problem:
    How can I use the result of convertStringSidToBinary(String string) with an EqualsFilter?
    The EqualsFilter calls in its constructor hierarchy LdapEncoder.filterEncode what replaces all \\ by \\5c

  8. #8
    Join Date
    Jul 2005
    Location
    Helsingborg, Sweden
    Posts
    504

    Default

    Could you try specifying a single backslash and two digits, like "\15" instead of "\\15"?
    Ulrik Sandberg
    Jayway (www.jayway.com)
    Spring LDAP project member

  9. #9
    Join Date
    Jun 2009
    Posts
    6

    Default

    Quote Originally Posted by ulsa View Post
    Could you try specifying a single backslash and two digits, like "\15" instead of "\\15"?
    We have to use '\\' to obtain a single backslash (escape rules under Java). Therefore your solution can not be used. May be the implementation of a Binary Filter would be useful in this case (sorry for not helping you more than this but I'm short of time).

  10. #10
    Join Date
    Jul 2005
    Location
    Helsingborg, Sweden
    Posts
    504

    Default

    We have to use '\\' to obtain a single backslash (escape rules under Java).
    The Java language specification (section 3.10.6) says an octal escape sequence inside a literal String shall consist of a backslash followed by: OctalDigit | OctalDigit OctalDigit | ZeroToThree OctalDigit OctalDigit. It's perfectly valid to write a Java string like this:

    Code:
    String binary = "\15\15\15\11";
    Ulrik Sandberg
    Jayway (www.jayway.com)
    Spring LDAP project member

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •