Tôi có nhu cầu hạn chế các chức năng cụ thể của một ứng dụng dựa trên vị trí của người dùng hiện đang đăng nhập. Như tôi đã thực hiện logic này trong Delphi, tôi không muốn đi overboard với đầy đủ thư mục hoạt động/LDAP truy vấn.Làm cách nào để chương trình của tôi có thể phát hiện xem chương trình có đang chạy trên một miền cụ thể không?
Suy nghĩ của tôi là sử dụng DsGetDcName và sử dụng GUID được trả lại trong cấu trúc DOMAIN_CONTROLLER_INFO và so sánh nó với hằng số được mã hóa cứng. Có vẻ như lý do rằng một tên miền GUID sẽ chỉ thay đổi nếu tên miền được tái tạo, do đó, điều này sẽ cung cấp chức năng mà tôi mong muốn với chi phí giới hạn. Mối quan tâm duy nhất của tôi là tôi không thể tìm thấy bất kỳ tài liệu nào về MSDN xác nhận giả định của tôi.
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;
Đã thêm câu hỏi có liên quan trên ServerFault như được đề xuất.
Tìm thấy một cách đọc thú vị khác trên Technet cũng có vẻ gợi ý cho tôi là đúng, nhưng không được cụ thể phạm vi tại miền của SID.
Tôi đồng ý rằng GUID sẽ không thay đổi nhưng tôi muốn chỉ ra rằng bạn chắc chắn sẽ nhận được GUID khác nếu bộ điều khiển miền thay đổi. –
Lưu ý rằng tôi đang sử dụng tên miền GUID, không phải là hướng dẫn DC. Như vậy (người ta sẽ nghĩ) nó sẽ yêu cầu demoting/loại bỏ tất cả DC và máy trạm, và di chuyển chúng vào một tên miền mới. Tôi đang theo giả định rằng tên miền GUID được tạo ra khi bạn thúc đẩy các máy chủ đầu tiên đến một bộ điều khiển tên miền, và sau đó nó sống trên cho cuộc sống của tên miền. – jchoover
Ok, xấu của tôi, xin lỗi. Tôi đồng ý với giả định của bạn, thật không may tôi đã không nhìn thấy nó tuyên bố bất cứ nơi nào. Có thể bạn muốn hỏi điều này tại [serverfault] (http://serverfault.com/). –