Админ / не админ?

ёёёёё
Дата: 31.05.2019 17:23:11
Как определить?
CheckTokenMembership() или чего ишо?
Мимопроходящий
Дата: 31.05.2019 17:24:24

какова цель?

Posted via ActualForum NNTP Server 1.5

ёёёёё
Дата: 31.05.2019 17:30:40
Мимопроходящий,

Узнать, есть ли смысл пробовать выполнить регистрацию COM - серверов и инсталлировать драйвера устройств.
Гаджимурадов Рустам
Дата: 31.05.2019 17:42:28
Это и PowerUser могут делать, IIRC.

P.S. Делай попытку и проверяй результат.

Posted via ActualForum NNTP Server 1.5

Мимопроходящий
Дата: 31.05.2019 17:52:06

31.05.2019 17:42, Гаджимурадов Рустам пишет:
> Делай попытку и проверяй результат.

+1

Posted via ActualForum NNTP Server 1.5

ёёёёё
Дата: 31.05.2019 18:19:22
Не, надо заранее.
makhaon
Дата: 31.05.2019 18:23:41
ёёёёё,

шоб было (ц)?
Мимопроходящий
Дата: 31.05.2019 18:26:31

31.05.2019 18:19, ёёёёё пишет:
> Не, надо заранее.

ты пытаешься к офисному туалету прицепить табличку «don't disturb»

Posted via ActualForum NNTP Server 1.5

Dimitry Sibiryakov
Дата: 31.05.2019 18:41:14

ёёёёё
Узнать, есть ли смысл пробовать выполнить регистрацию COM - серверов и инсталлировать
драйвера устройств.

1) Узнать какая именно привилегия для этого требуется.
2) Проверить её наличие через AccessCheck().

Posted via ActualForum NNTP Server 1.5

ёёёёё
Дата: 04.06.2019 14:16:27
Подсмотрел, как в инсталляторах делается.

+

function GetAccountType(aCheckTokenForGroupDeny: boolean): string;
type
  _TCTN = function(TokenHandle: THANDLE; SidToCheck: Pointer;
    var IsMember: BOOL): BOOL; stdcall;

  _TGroup = record
    auth_id: DWORD;
    name: string;
  end;
const
  DOMAIN_ALIAS_RID_ADMINS = $00000220;
  DOMAIN_ALIAS_RID_USERS = $00000221;
  DOMAIN_ALIAS_RID_GUESTS = $00000222;
  DOMAIN_ALIAS_RID_POWER_USERS = $00000223;

  SECURITY_BUILTIN_DOMAIN_RID = $00000020;
  SE_GROUP_USE_FOR_DENY_ONLY = $00000010;

  cGroups: array[0..3] of _TGroup = (
    (auth_id: DOMAIN_ALIAS_RID_USERS; name: 'User'),
    (auth_id: DOMAIN_ALIAS_RID_GUESTS; name: 'Guest'),
    (auth_id: DOMAIN_ALIAS_RID_POWER_USERS; name: 'Power'),
    (auth_id: DOMAIN_ALIAS_RID_ADMINS; name: 'Admin'));

var
  fCurrGroup: string;
  fpTG: PTokenGroups;
  fIsValidTokenGroups: Boolean;
  fIsMember: LongBool;
  fcbTokenGroups: DWORD;
  fHToken: DWORD;
  i, j: Integer;
  fCheckTokenMembershipFunc: _TCTN;
  fpSID: PSID;

const
  SystemSidAuthority: SID_IDENTIFIER_AUTHORITY = (Value: (0, 0, 0, 0, 0, 5));
    // SECURITY_NT_AUTHORITY           {0,0,0,0,0,5}
begin
  fCurrGroup := '';
  fHToken := 0;

  fCheckTokenMembershipFunc := nil;
 // Открываем хэндл токена доступа к текущему треду
  if (OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, fHToken)
    or OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, fHToken)) then begin
    fpTG := nil;
    fIsValidTokenGroups := False;

    if aCheckTokenForGroupDeny then
   // ...без Load/Freelibrary
      fCheckTokenMembershipFunc :=
        GetProcAddress(GetModuleHandle('ADVAPI32'), 'CheckTokenMembership');

  // "Олдскул"...
    if (not aCheckTokenForGroupDeny
      or not Assigned(fCheckTokenMembershipFunc)) then
   // Запрашиваем размер информации. Ожидаем от GetTokenInformation результата FALSE,
   // так передаем ему NULL - буфер. По завершению в cbTokenGroups будет размер
   // групповой информации.
      if (not GetTokenInformation(fHToken, TokenGroups, nil, 0, fcbTokenGroups)
        and (GetLastError() = ERROR_INSUFFICIENT_BUFFER)) then
      begin
    // Выделяем память и снова запрашиваем инфу.
    // ! Если админ добавит эту учетку к дополнительной группе между
    // вызовами GetTokenInformation  - возможен глюк
        fpTG := PTokenGroups(GlobalAlloc(GPTR, fcbTokenGroups));
        if (Assigned(fpTG) and
          GetTokenInformation(fHToken, TokenGroups, fpTG,
          fcbTokenGroups, fcbTokenGroups)) then
          fIsValidTokenGroups := True
      end;

    if (fIsValidTokenGroups
      or (aCheckTokenForGroupDeny
      and Assigned(fCheckTokenMembershipFunc))) then begin
      for i := 0 to High(cGroups) do begin
    // Создаем SID для локальной группы, потом проверяем, существует ли он в нашем токене
        if (AllocateAndInitializeSid(
          SystemSidAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
          cGroups[i].auth_id, 0, 0, 0, 0, 0, 0, fpSID)) then begin
          fIsMember := False;
          if aCheckTokenForGroupDeny
            and Assigned(fCheckTokenMembershipFunc) then
            fCheckTokenMembershipFunc(0, fpSID, fIsMember)
          else if fIsValidTokenGroups then
            for j := 0 to fpTG.GroupCount - 1 do
// Временно отключаем проверку диапазонов, из-за Groups: array[0..0]
{$IFOPT R+}
{$R-}
{$DEFINE RANGE}
{$ENDIF}
              if (EqualSid(fpTG.Groups[j].Sid, fpSID)) then
{$IFDEF RANGE}
{$R+}
{$UNDEF RANGE}
{$ENDIF}
                fIsMember := True;

          if (fIsMember) then
            fCurrGroup := cGroups[i].name;
          FreeSid(fpSID);
        end
      end
    end;

    if Assigned(fpTG) then
      GlobalFree(HGLOBAL(fpTG));
    CloseHandle(fHToken);

    result := fCurrGroup;
    exit;
  end;

  result := '';
end;



Параметр - для учета текущего состояния UAC.
Если параметр == True, то в *Vista при "задранном" UAC вернет "User", а если == True - то "Admin".
Для WinXP - без разницы, естественно.