Перевести SID на имя - PullRequest
       2

Перевести SID на имя

3 голосов
/ 19 декабря 2010

Моему приложению Delphi 2010 необходимо добавить пользователя Windows в локальную группу администраторов.Я получил эту часть, работающую с помощью NetLocalGroupAddMembers.

Теперь приложение должно работать в локализованных версиях Windows с другими языками.Для этого я использую SID с функцией LsaLookupSids, чтобы получить переведенное имя группы, но не могу этого сделать, потому что я не знаю, как сделать вызов API.

Я был бы благодаренкто-то может показать мне, как использовать функцию LsaLookupSids для получения имени группы («Администраторы» на английском языке, версия для США для Windows) из SID.

Ниже приведен мой код:

function AddUser(const username, password: PChar; resetpassword: boolean): boolean; stdcall;
var
  NetApiStatus: NET_API_STATUS;
  UserInfo1003: USER_INFO_1003;
  UserInfo1005: USER_INFO_1005;
  ui: USER_INFO_1;
  grp: String;
  sid: PSID;
  snu: SID_NAME_USE;
  sidsize: LongWord;
  refdomain: PLsaReferencedDomainList; //array [0..MAX_PATH - 1] of char;
  refdomainsize: LongWord;
  sidstring: PChar;
  lgmi3: _LOCALGROUP_MEMBERS_INFO_3;
  reftranname: PLsaTranslatedName;
begin
  if UserExists(username) then begin


    sidstring := PChar('S-1-5-32-544'); //Local Administrators group

    refdomain := AllocMem(SizeOf(refdomain));
    FillChar(refdomain, SizeOf(refdomain), 0);

    reftranname := AllocMem(SizeOf(reftranname));

    sidsize := 0;
    sid := nil;
    sid := AllocMem(Length(sidstring) );
    sid := PChar(sidstring);
    try
      LsaLookupSids(GetPolicyHandle, 1, sid, refdomain, reftranname);
      grp := reftranname^.Name.Buffer;
      showmessage('messg ' + grp);
    finally
      FreeMem(sid, sidsize);
    end;
  end;

Ответы [ 2 ]

6 голосов
/ 19 декабря 2010

Вам не нужны LsaLookupSids, это предназначено для поиска или массива SID.Поиск одного SID обычно выполняется с использованием LookupAccountSid.Пример:

uses JwaWindows; // or JwaSddl, JwaWinBase;
    var
      Sid: PSID;
      peUse: DWORD;
      cchDomain: DWORD;
      cchName: DWORD;
      Name: array of Char;
      Domain: array of Char;
    begin
      Sid := nil;
      // First convert String SID to SID
      Win32Check(ConvertStringSidToSid(PChar('S-1-5-32-544'), Sid));

      cchName := 0;
      cchDomain := 0;
      // Get Length
      if (not LookupAccountSid(nil, Sid, nil, cchName, nil, cchDomain, peUse))
        and (GetLastError = ERROR_INSUFFICIENT_BUFFER) then
      begin
        SetLength(Name, cchName);
        SetLength(Domain, cchDomain);
        if LookupAccountSid(nil, Sid, @Name[0], cchName, @Domain[0], cchDomain, peUse) then
        begin
           // note: cast to PChar because LookupAccountSid returns zero terminated string
           ShowMessageFmt('%s\%s', [PChar(Domain), PChar(Name)]);
        end;
      end;

      if Assigned(Sid) then
        LocalFree(DWORD(Sid));

или даже проще, используя Jwscl:

uses JwsclSid;

    var
      Sid: TJwSecurityId;
    begin
      Sid := TJwSecurityId.Create('S-1-5-32-544');
      try
        ShowMessage(Sid.GetAccountName);
      finally
        Sid.Free;
      end;
4 голосов
/ 19 декабря 2010

Простой пример с использованием JCL. Вы также можете использовать http://blog.delphi -jedi.net / security-library / (например, TJwSecurityId).

Этот код не использует LsaLookupSids, но внутренне LookupAccountSid (но для локальной группы не думаю, что это имеет значение).

uses
  JclSecurity, JclWin32;

// Raises exception in case of invalid ASID or if SID is not found
function GetNameFromSid(ASID: String): String;
var
  lSidLen: DWORD;
  lSid: PSID;
  lName, lDomain: WideString;
begin
  lSidLen := SECURITY_MAX_SID_SIZE;

  lSid := AllocMem(lSidLen);
  try
    StringToSID(ASID, lSid, lSidLen);
    LookupAccountBySid(lSid, lName, lDomain);
    Result := lName;
  finally
    FreeMem(lSid);
  end;
end;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...