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.
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.
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; } }
Thank you for your code snippet. It will help me.@ulsa
The objectSid seems to be a systemOnly attribute. You don't mention any specific problems, so assuming that the attribute is readable...
I still have the following question:
The value of the attribute 'objectSid' is a binary object. The parameter of '' is a String.Code:public List getPersonsByObjectSid(String sid)
How does this String look like? Is it Base64 Encoded?
Thank you for your advise.
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})
I'm considering adding Java 1.4-compatible SID converters to LdapUtils. Meanwhile, try this code. You'll need the ArrayUtils in Commons Lang.
Unit tests for the interested: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; }
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]); } }
Added two methods to LdapUtils:
It's available in trunk. I would appreciate if anyone else could verify them.Code:public static String convertBinarySidToString(byte[] sid); public static byte[] convertStringSidToBinary(String string);
Could you try specifying a single backslash and two digits, like "\15" instead of "\\15"?
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:We have to use '\\' to obtain a single backslash (escape rules under Java).
Code:String binary = "\15\15\15\11";