Ich muss bestimmte Funktionen einer Anwendung basierend auf dem Standort des aktuell angemeldeten Benutzers beschränken. Da ich diese Logik in Delphi implementieren muss, würde ich es vorziehen, nicht mit vollen Active Directory/LDAP-Abfragen über Bord zu gehen.Wie kann mein Programm feststellen, ob es auf einer bestimmten Domain läuft?
Mein aktueller Gedanke ist die Verwendung von DsGetDcName und die Verwendung der in der Struktur DOMAIN_CONTROLLER_INFO zurückgegebenen GUID und den Vergleich mit einer fest codierten Konstante. Es scheint, dass eine Domänen-GUID sich nur ändert, wenn die Domäne neu erstellt wird, sodass dies die Funktionalität bietet, die ich mit begrenztem Overhead wünsche. Meine einzige Sorge ist, dass ich keine Dokumentation auf MSDN finden kann, die meine Annahme bestätigt.
type
EAccessDenied = Exception;
EInvalidOwner = Exception;
EInsufficientBuffer = Exception;
ELibraryNotFound = Exception;
NET_API_STATUS = Integer;
TDomainControllerInfoA = record
DomainControllerName: LPSTR;
DomainControllerAddress: LPSTR;
DomainControllerAddressType: ULONG;
DomainGuid: TGUID;
DomainName: LPSTR;
DnsForestName: LPSTR;
Flags: ULONG;
DcSiteName: LPSTR;
ClientSiteName: LPSTR;
end;
PDomainControllerInfoA = ^TDomainControllerInfoA;
const
NERR_Success = 0;
procedure NetCheck(ErrCode: NET_API_STATUS);
begin
if ErrCode <> NERR_Success then
begin
case ErrCode of
ERROR_ACCESS_DENIED:
raise EAccessDenied.Create('Access is Denied');
ERROR_INVALID_OWNER:
raise EInvalidOwner.Create('Cannot assign the owner of this object.');
ERROR_INSUFFICIENT_BUFFER:
raise EInsufficientBuffer.Create('Buffer passed was too small');
else
raise Exception.Create('Error Code: ' + IntToStr(ErrCode) + #13 +
SysErrorMessage(ErrCode));
end;
end;
end;
function IsInternalDomain: Boolean;
var
NTNetDsGetDcName: function(ComputerName, DomainName: PChar; DomainGuid: PGUID; SiteName: PChar; Flags: ULONG; var DomainControllerInfo: PDomainControllerInfoA): NET_API_STATUS; stdcall;
NTNetApiBufferFree: function (lpBuffer: Pointer): NET_API_STATUS; stdcall;
LibHandle: THandle;
DomainControllerInfo: PDomainControllerInfoA;
ErrMode: Word;
const
NTlib = 'NETAPI32.DLL';
DS_IS_FLAT_NAME = $00010000;
DS_RETURN_DNS_NAME = $40000000;
INTERNAL_DOMAIN_GUID: TGUID = '{????????-????-????-????-????????????}';
begin
if Win32Platform = VER_PLATFORM_WIN32_NT then
begin
ErrMode := SetErrorMode(SEM_NOOPENFILEERRORBOX);
LibHandle := LoadLibrary(NTlib);
SetErrorMode(ErrMode);
if LibHandle = 0 then
raise ELibraryNotFound.Create('Unable to map library: ' + NTlib);
try
@NTNetDsGetDcName := GetProcAddress(Libhandle, 'DsGetDcNameA');
@NTNetApiBufferFree := GetProcAddress(Libhandle,'NetApiBufferFree');
try
NetCheck(NTNetDsGetDcName(nil, nil, nil, nil, DS_IS_FLAT_NAME or DS_RETURN_DNS_NAME, DomainControllerInfo));
Result := (DomainControllerInfo.DomainName = 'foo.com') and (CompareMem(@DomainControllerInfo.DomainGuid,@INTERNAL_DOMAIN_GUID, SizeOf(TGuid)));//WideCharToString(pDomain);
finally
NetCheck(NTNetApiBufferFree(DomainControllerInfo));
end;
finally
FreeLibrary(LibHandle);
end;
end
else
Result := False;
end;
Added eine ähnliche Frage auf ServerFault wie vorgeschlagen.
Gefunden eine andere interessante lesen auf Technet, die auch darauf hindeutet, dass ich richtig zu sein, ist aber nicht speziell auf Domäne SIDs beschränkt.
Ich würde zustimmen, dass die GUID nicht geändert wird, aber ich möchte darauf hinweisen, dass Sie sicherlich eine andere GUID erhalten würden, wenn der Domänencontroller ändert. –
Beachten Sie, dass ich die Domänen-GUID verwende, nicht die DC-GUID. Als solches (würde man meinen) müssten alle DCs und Workstations degradiert/entfernt und in eine neue Domain migriert werden. Ich gehe davon aus, dass die Domänen-GUID erstellt wird, wenn Sie den ersten Server auf einen Domänencontroller heraufstufen und dann für die gesamte Lebensdauer der Domäne bestehen. – jchoover
Ok, mein Schade, tut mir leid. Ich stimme Ihrer Vermutung zu, leider habe ich nirgendwo anders gesehen. Vielleicht möchten Sie dies bei [serverfault] (http://serverfault.com/) fragen. –