When using tokeGroups attribuet to retrieve group membership fails
When using tokeGroups attribute to retrieve group membership fails, well more optionally would of course be to use the attribute tokenGroupsNoGCAcceptable as it will return a value on "best effort" even if there isn't a GC around, but that's not the issue here, and the issue actually applies to tokenGroupsNoGCAcceptable as well.
If we assume that all DCs in the forest are also made GCs, what will cause the code below to break? It contains an interesting bug actually, and a scenario that the developers of this app failed to take care of, Note this application is actually a Microsoft app. I will be interesting to see if anyone else can identify the issue J btw; it caused the entire app to crash.
internal
class
Program
{
internal
static
void Main(string[] args)
{
Console.WriteLine("BREUtils:checkDomainUseRoles.");
ArrayList tokenGroups = new
ArrayList();
tokenGroups = checkDomainUserRoles("internal\\ADCH");
}
public
static
ArrayList checkDomainUserRoles(string user)
{
ArrayList list = new
ArrayList();
DirectoryEntry entry = null;
DirectoryEntry searchRoot = null;
DirectorySearcher searcher = null;
SearchResultCollection results = null;
try
{
//ZeroTouchServiceUtil.LogDebugEvent(string.Format("Entering BREUtilities::checkDomainUserRoles called with parameters user: {0} ", user));
string str = user.Split(new
char[] { '\\' })[1];
string str2 = user.Split(new
char[] { '\\' })[0];
entry = new
DirectoryEntry("LDAP://rootDSE");
string str3 = (string)entry.Properties["DefaultNamingContext"][0];
searchRoot = new
DirectoryEntry("GC://" + str3);
searcher = new
DirectorySearcher(searchRoot);
string str4 = "(&(objectClass=user)(samaccountname=" + str + "))";
searcher.Filter = str4;
searcher.SearchRoot = new
DirectoryEntry("LDAP://" + str2);
searcher.PropertiesToLoad.Add("CN");
results = searcher.FindAll();
if (results.Count != 1)
{
//ZeroTouchServiceUtil.LogDebugEvent(string.Format("BREUtilities::checkDomainUserRoles: User Account {0} found {1} times.", user, results.Count));
return list;
}
DirectoryEntry entry3 = null;
try
{
entry3 = new
DirectoryEntry(results[0].Path.Replace("GC://", "LDAP://"));
entry3.RefreshCache(new
string[] { "CN", "tokenGroups" });
PropertyValueCollection c = entry3.Properties["tokenGroups"];
ArrayList list2 = new
ArrayList(c.Count);
list2.AddRange(c);
for (int i = 0; i < list2.Count; i++)
{
byte[] sid = (byte[])list2[i];
string str5 = ConvertSidToStringSid(sid);
DirectoryEntry entry4 = new
DirectoryEntry(string.Format("LDAP://<SID={0}>", str5));
try
{
string str7 = entry4.Properties["samAccountName"].Value.ToString();
list.Add(str7);
}
catch (Exception exception)
{
Console.WriteLine("Error: " + exception.Message);
}
finally
{
DisposeDirectoryObject(entry4);
}
}
return list;
}
catch (Exception exception2)
{
Console.WriteLine("Error in BREUtilities::checkDomainUserRoles: " + exception2.Message);
return list;
}
finally
{
DisposeDirectoryObject(entry3);
}
}
catch (Exception exception3)
{
Console.WriteLine("Error in BREUtilities::checkDomainUserRoles. " + exception3.Message);
}
finally
{
DisposeDirectoryObject(searcher);
DisposeDirectoryObject(searchRoot);
DisposeDirectoryObject(entry);
DisposeDirectoryObject(results);
}
return list;
}
public
static
void DisposeDirectoryObject(object obj)
{
try
{
if (obj != null)
{
if (obj is
DirectorySearcher)
{
((DirectorySearcher)obj).Dispose();
}
else
if (obj is
DirectoryEntry)
{
((DirectoryEntry)obj).Dispose();
}
else
if (obj is
SearchResultCollection)
{
((SearchResultCollection)obj).Dispose();
}
}
}
catch (Exception exception)
{
//ZeroTouchServiceUtil.LogErrorEvent(string.Format("Exception in BREUtilities:DisposeDirectoryObjects. Error: {0}", exception.ToString()));
}
}
private
static
string ConvertSidToStringSid(byte[] sid)
{
IntPtr destination = new
IntPtr();
IntPtr pSidString = new
IntPtr();
destination = Marshal.AllocHGlobal(sid.Length);
Marshal.Copy(sid, 0, destination, sid.Length);
ConvertSidToStringSid(destination, ref pSidString);
string str = Marshal.PtrToStringAuto(pSidString);
Marshal.FreeHGlobal(destination);
Marshal.FreeHGlobal(pSidString);
return str;
}
private
static
string ConvertToOctetString(byte[] val)
{
StringBuilder builder = new
StringBuilder((val.GetUpperBound(0) + 1) * 2);
for (int i = 0; i < val.GetUpperBound(0); i++)
{
builder.Append(val[i].ToString("x2"));
}
return builder.ToString();
}
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private
static
extern
int ConvertSidToStringSid(IntPtr pSID, ref
IntPtr pSidString);
[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
private
static
extern
bool ConvertSidToStringSid(IntPtr pSID, [In, Out, MarshalAs(UnmanagedType.LPTStr)] ref
string pStringSid);
[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
private
static
extern
bool ConvertStringSidToSid(string pStringSid, ref
IntPtr pSID);
}