Get ActiveDirectory User by ObjectSID

I am trying to retrieve the user DirectoryEntry by SID which is the unique key to the Active Directory entry.  Here is my code:

        public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
        {
            if (!(providerUserKey is SecurityIdentifier))
                throw new ArgumentException("Invalid ProviderUserKey");

            SecurityIdentifier SID = providerUserKey as SecurityIdentifier;
            int SIDLen = SID.BinaryLength;
            byte[] SIDBuffer = new byte[SIDLen];
            SID.GetBinaryForm(SIDBuffer, 0);
            string  filter = string.Format("(sAMAccountName=*)(objectSid={0})",
                ConvertByteToStringSid(SIDBuffer));

           
            string[] attribs={"sAMAccountName", "objectSid", "mail", "name", "comment", "whenCreated", "pwdLastSet"};

            using (DirectoryEntry root = this.GetRootDirectoryEntry(""))
            {
                using (DirectorySearcher search = new DirectorySearcher(root))
                {
                    try
                    {
                        search.Filter = filter;
                        foreach (string prop in attribs)
                        {
                            search.PropertiesToLoad.Add(prop);
                        }


                        SearchResult resultItem = search.FindOne();    //Read the path

                        MembershipUser user = LoadUser(resultItem);
                        return user;

                    }
                    catch (Exception ex)
                    {
                        this.lastError="Not Found:" + SID.ToString() + ":" + ex.Message;
                        System.Diagnostics.Debug.WriteLine(this.lastError);
                        return null;
                    }
                }
            }
        }
        /// <summary>
        /// Converts the byte to string sid.
        /// </summary>
        /// <param name="sidBytes">The sid bytes.</param>
        /// <returns></returns>
        private string ConvertByteToStringSid(Byte[] sidBytes)
        {
            StringBuilder strSid = new StringBuilder();
            strSid.Append("S-");
            try
            {
                // Add SID revision.
                strSid.Append(sidBytes[0].ToString());
                // Next six bytes are SID authority value.
                if (sidBytes[6] != 0 || sidBytes[5] != 0)
                {
                    string strAuth = String.Format
                        ("0x{0:2x}{1:2x}{2:2x}{3:2x}{4:2x}{5:2x}",
                        (Int16)sidBytes[1],
                        (Int16)sidBytes[2],
                        (Int16)sidBytes[3],
                        (Int16)sidBytes[4],
                        (Int16)sidBytes[5],
                        (Int16)sidBytes[6]);
                    strSid.Append("-");
                    strSid.Append(strAuth);
                }
                else
                {
                    Int64 iVal = (Int32)(sidBytes[1]) +
                        (Int32)(sidBytes[2] << 8) +
                        (Int32)(sidBytes[3] << 16) +
                        (Int32)(sidBytes[4] << 24);
                    strSid.Append("-");
                    strSid.Append(iVal.ToString());
                }

                // Get sub authority count...
                int iSubCount = Convert.ToInt32(sidBytes[7]);
                int idxAuth = 0;
                for (int i = 0; i < iSubCount; i++)
                {
                    idxAuth = 8 + i * 4;
                    UInt32 iSubAuth = BitConverter.ToUInt32(sidBytes, idxAuth);
                    strSid.Append("-");
                    strSid.Append(iSubAuth.ToString());
                }
            }
            catch (Exception ex)
            {
                lastError = "Error building SID str:"+ex.Message;
                System.Diagnostics.Debug.WriteLine(lastError);
                return "";
            }
            return strSid.ToString();
        }

It tries to do a directory search with a filter of:
  "(sAMAccountName=*)(objectSid=S-1-5-21-1993962763-492894223-682003330-1126)"
but fails on the 'SearchResult resultItem = search.FindOne()' line with an exception of "Unknown error (0x80005000)"
LVL 21
MogalManicAsked:
Who is Participating?
 
ihenryConnect With a Mentor Commented:
If you look at the list of generic ADSI error codes in MSDN, the 0x80005000 hex decimal value is referred as E_ADS_BAD_PATHNAME. This means, the AD path you used to bind to AD could be invalid. Take a look closer to the path to see whether it is in the correct syntax and you didn't make any typo like putting a space or some other invalid character. Another possible cause would be security issue, which is the most tricky part when dealing with directory services. But if you can ensure that the user credential you used to run the code or to bind AD (if you explicitly pass user name and password to the DirectoryEntry object) has enough permissions to access and search user information, then all should be good.

Look at MSDN library, there should be enough information for you to solve this problem. If you get stumped again, please check back for more discussion.

http://msdn.microsoft.com/library/en-us/dsportal/dsportal/directory_services_portal.asp

0
All Courses

From novice to tech pro — start learning today.