मुझे वर्तमान में लॉग इन किए गए उपयोगकर्ता के स्थान के आधार पर किसी एप्लिकेशन के विशिष्ट कार्यों को प्रतिबंधित करने की आवश्यकता है। जैसा कि मुझे डेल्फी में इस तर्क को लागू करना है, मैं पूर्ण सक्रिय निर्देशिका/एलडीएपी प्रश्नों के साथ ओवरबोर्ड नहीं जाना पसंद करूंगा।मेरा प्रोग्राम कैसे पता लगा सकता है कि यह किसी विशेष डोमेन पर चल रहा है या नहीं?
मेरा इलाज विचार DsGetDcName का उपयोग करना है, और GUID का उपयोग DOMAIN_CONTROLLER_INFO संरचना में वापस किया गया है और इसकी तुलना हार्ड कोडित स्थिरांक से करें। ऐसा लगता है कि डोमेन GUID केवल तभी बदल जाएगा जब डोमेन पुनर्निर्मित हो, इसलिए यह कार्यक्षमता प्रदान करेगा जो मैं सीमित ओवरहेड के साथ चाहता हूं। मेरी एकमात्र चिंता यह है कि मुझे अपनी धारणा की पुष्टि करने वाले एमएसडीएन पर कोई दस्तावेज नहीं मिल रहा है।
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;
जोड़ा गया ServerFault पर एक संबंधित सवाल के रूप में सुझाव दिया।
Technet पर एक और दिलचस्प पठन मिला जो मुझे सही होने पर संकेत देता है, लेकिन विशेष रूप से डोमेन एसआईडी पर स्कॉप्ड नहीं किया गया है।
मैं सहमत हूं कि GUID नहीं बदलेगा, लेकिन मैं यह इंगित करना चाहता हूं कि यदि डोमेन नियंत्रक बदलता है तो आपको निश्चित रूप से एक अलग GUID प्राप्त होगा। –
नोटिंग मैं डोमेन GUID का उपयोग कर रहा हूं, डीसी गाइड नहीं। जैसे (कोई सोचता है) इसे सभी डीसी और वर्कस्टेशन को डिमोट करने/हटाने की आवश्यकता होगी, और उन्हें एक नए डोमेन में माइग्रेट करना होगा। मैं इस धारणा के तहत हूं कि जब आप डोमेन नियंत्रक को पहले सर्वर को बढ़ावा देते हैं, तो डोमेन GUID बनाया जाता है, और फिर यह डोमेन के जीवन के लिए रहता है। – jchoover
ठीक है, मेरे बुरे, क्षमा करें। मैं आपकी धारणा से सहमत हूं, दुर्भाग्य से मैंने इसे कहीं भी नहीं देखा है। हो सकता है कि आप इसे [serverfault] (http://serverfault.com/) पर पूछना चाहें। –