Link to home
Start Free TrialLog in
Avatar of davidrickey
davidrickeyFlag for United States of America

asked on

I need a way to programmaticly retrieve a sid when given a users full nt login by querying AD.

I have a database that is populated with user names "domain\user"

I need a way to query AD and select a users SID based on their login name.

I am then going to take the SID given by AD and write that information back to the database.

ASKER CERTIFIED SOLUTION
Avatar of virtuatech
virtuatech
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of davidrickey

ASKER

That would be great if i could access the program through vb.  Since you posted I have been trying to find a way to execute the psgetsid application and return the value back to my application for the database update.

Is there an easy way to interface psgetsid with my application?
SOLUTION
Avatar of jkr
jkr
Flag of Germany image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
jkr,
Before your last post I found this on the internet.  Slightly modified, I was able to use it to do exactly what I needed.  Thanks for responding.
private void button1_Click(object sender, EventArgs e)
        {
            SqlDataReader dr;
            string qry = "select ntaccount from tiuser where  (sid = '' or sid is null) and (not ntaccount is null and not ntaccount = '') order by ntaccount";
            SqlConnection con = new SqlConnection("ConnectionString");
 
            SqlCommand cmd = new SqlCommand(qry, con);
 
            try
            {
                con.Open();
                dr = cmd.ExecuteReader();
                while (dr.Read())
                {
                    writeData(GetSid(dr.GetString(0)), dr.GetString(0));
                }
            }
            catch { }
 
        }
 
        private string GetSid(string strLogin)
        {
            string str = "";
            // Parse the string to check if domain name is present.
            int idx = strLogin.IndexOf('\\');
            if (idx == -1)
            {
                idx = strLogin.IndexOf('@');
            }
 
            string strDomain;
            string strName;
 
            if (idx != -1)
            {
                strDomain = strLogin.Substring(0, idx);
                strName = strLogin.Substring(idx + 1);
            }
            else
            {
                strDomain = Environment.MachineName;
                strName = strLogin;
            }
 
 
            DirectoryEntry obDirEntry = null;
            try
            {
                Int64 iBigVal = 5;
                Byte[] bigArr = BitConverter.GetBytes(iBigVal);
                obDirEntry = new DirectoryEntry("WinNT://" +
                                      strDomain + "/" + strName);
                System.DirectoryServices.PropertyCollection
                                   coll = obDirEntry.Properties;
                object obVal = coll["objectSid"].Value;
                if (null != obVal)
                {
                    str = this.ConvertByteToStringSid((Byte[])obVal);
                }
 
            }
            catch (Exception ex)
            {
                str = "";
                //Trace.Write(ex.Message);
            }
            return str;
        }
 
        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)
            {
                //Trace.Warn(ex.Message);
                return "";
            }
            return strSid.ToString();
        }
 
        private void writeData(string SID, string user)
        {
            SqlDataAdapter da = new SqlDataAdapter();
            SqlConnection con = new SqlConnection("ConnectionString");
            string qry = "UPDATE TIUSER SET SID = '" + SID + "' WHERE (NTACCOUNT = '" + user + "')";
            da.UpdateCommand = new SqlCommand(qry, con);
 
            try
            {
                con.Open();
                da.UpdateCommand.ExecuteNonQuery();
 
            }
            catch{}
            con.Close();
        
        }

Open in new window