{******************************************************************************}
// USER: GET PRIMARY GROUP FOR USER
// do it with WINNT Service, it gets also the primary group...
// read this article for better understanding visit:
// [url]http://support.microsoft.com/kb/321360[/url]
//
// after getting all groups name with WINNT provider we get the LDAPPATHES
// of the groups and then get the Attribute Primary Group Token.
// After comparing with Primary Group ID from the user, we know its
// Primary Group.
{******************************************************************************}
function TEADSUsers.GetPrimaryGroupForUser(user: IADsUser):
string;
var
tmp: OleVariant;
sAMAccountName:
string;
PGID: Integer;
objUser: IADs;
strPath:
string;
Enum: IEnumVariant;
grps: IAdsMembers;
grp: IAdsGroup;
varGroup: OleVariant;
Temp: LongWord;
QueryFilter:
string;
search: IDirectorySearch;
ptrResult: ADS_SEARCH_HANDLE;
opt: ads_searchpref_info;
dwCount: DWORD;
hr: HResult;
col: ads_search_column;
dwErr: DWord;
szErr :
array[0..255]
of WideChar;
szName :
array[0..255]
of WideChar;
AttrArray:
array of PWideChar;
gr:
Array of OleVariant;
groupPath:
string;
group: IADsGroup;
begin
result := '
';
try
// get sAMAccountName
tmp := user.Get('
sAMAccountName');
sAMAccountName :=
String(tmp);
// get Primary Group Id of the user
tmp := user.Get('
PrimaryGroupID');
PGID := Integer(tmp);
QueryFilter := '
(|';
// lists all of the groups the user belongs to
strPath := '
WinNT://'+AdsMgr.ADSController.GetDomain+'
/'+sAMAccountName;
if SUCCEEDED(AccessObject(strPath, IID_IADs, objUser))
then
begin
grps := (objUser
as IADsUser).Groups;
Enum := grps._NewEnum
as IEnumVariant;
if Enum <>
nil then
begin
while Enum.Next(1, varGroup, Temp) = S_OK
do
begin
grp := IDispatch(varGroup)
as IAdsGroup;
QueryFilter := QueryFilter + '
(sAMAccountName=' + grp.
Name + '
)'
end;
end;
end;
QueryFilter := QueryFilter + '
)';
// attribute we want to get...
SetLength(AttrArray, 1);
getmem(AttrArray[Length(AttrArray)-1], 256);
//StringToWideChar('primaryGroupToken', AttrArray[Length(AttrArray)-1], 256);
StringToWideChar('
ADSPath', AttrArray[Length(AttrArray)-1], 256);
// prepare for group.getInfoEx...
SetLength(gr, 1);
gr[0] := '
primaryGroupToken';
// get the search object
if SUCCEEDED(AccessObject(AdsMgr.ADSController.LDAPPATH, IDirectorySearch, search))
then
begin
// set parameters
opt.dwSearchPref := ADS_SEARCHPREF_SEARCH_SCOPE
OR ADS_SEARCHPREF_SORT_ON;
opt.vValue.dwType := ADSTYPE_INTEGER;
opt.vValue.__MIDL_0010.Integer := ADS_SCOPE_SUBTREE;
// setting search preferences
if not SUCCEEDED(search.SetSearchPreference(opt, 1))
then
begin
ADsGetLastError(dwErr, @szErr[0], 254, @szName[0], 254);
ShowMessage(WideCharToString(szErr));
Exit;
end;
// prepare
dwCount := Length(AttrArray);
// execute the search
hr := search.ExecuteSearch(LPCWSTR(QueryFilter), @AttrArray[0], dwCount, ptrResult);
// handle the result if hr is S_OK
if SUCCEEDED(hr)
then
begin
hr := search.GetNextRow(ptrResult);
while hr <> S_ADS_NOMORE_ROWS
do
begin
if Succeeded(search.GetColumn(ptrResult, AttrArray[0], col))
then
begin
if col.pADsValues <>
nil then
begin
groupPath := col.pADsValues^.__MIDL_0010.BackLink.ObjectName;
// get group
group := ADsMgr.ADSGroups.GetGroup(groupPath);
// update cache
group.GetInfoEx(gr, 0);
tmp := group.Get('
primaryGroupToken');
// compare token
if Integer(tmp) = Integer(PGID)
then
begin
result := groupPath;
exit;
end;
end;
search.FreeColumn(col);
end;
hr := search.GetNextRow(ptrResult);
end;
end;
search.CloseSearchHandle(ptrResult);
end;
except
on e: EOleException
do
AdsMgr.SetLastError(e.
Message);
end;
end;