How can my program determine if it works in a specific domain?

I need to restrict certain application features based on the location of the current user. Since I have to implement this logic in Delphi, I would prefer not to go overboard with full active directory requests / LDAP.

My current thought is to use DsGetDcName and use the GUID returned in the DOMAIN_CONTROLLER_INFO structure and compare it with a hard-coded constant. It looks like the domain GUID will only change if the domain is recreated, so this will provide the functionality that I want with limited overhead. My only problem is that I cannot find the MSDN documentation that confirms my assumption.

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, , , , , SID ..

+5
3

;

GUID - (), , .

GUID GUID.

"".

LDAP- , .

+2
+1

, DsGetDcName.

domainA. . DsGetDcName domainB GUID, domainA GUID

, , LookupAccountName. LookupAccountName SID . SID SID . SID , . , SID SID , ,

GUID , , . AFAIK, , SID GUID. , .

0

All Articles