Как определить, установлена ​​ли привилегия Windows «Отладка программ»? - PullRequest
2 голосов
/ 03 февраля 2011

При установке SQL Server 2008, если эта привилегия не включена для пользователя, выполняющего установку, установка завершается неудачно. Поэтому в моем приложении перед установкой SQL Server (с использованием установки без вывода сообщений) я хотел бы определить, есть ли у текущего запущенного пользователя набор привилегий «Отладка программ» (т. Е. SeDebugPrivilege, SE_DEBUG_NAME ...)

Я не хочу знать, установлен ли он текущим процессом (потому что, по-видимому, в большинстве случаев это не так, даже если привилегия включена в системе). Первоначально я думал, что API "PrivilegeCheck" будет работать, но это не так. Если вы запускаете этот код в отладчике VS, то он говорит, что привилегия включена. Если вы запустите его из командной строки, он скажет вам, что привилегия отключена. Как я должен исправить эту программу, чтобы на самом деле иметь возможность проверить, доступна ли привилегия?

<br> HANDLE hToken;</p> <pre><code>// Get the calling thread's access token. if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &hToken)) { if (GetLastError() != ERROR_NO_TOKEN) { printf("CAN'T GET THREAD TOKEN!!!\n"); return -1; } // Retry against process token if no thread token exists. if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) { printf("CAN'T GET PROCESS TOKEN!!!\n"); return -1; } } //Find the LUID for the debug privilege token LUID luidDebugPrivilege; if ( !LookupPrivilegeValue( NULL, // lookup privilege on local system "SeDebugPrivilege", // privilege to lookup &luidDebugPrivilege ) ) // receives LUID of privilege { printf("LookupPrivilegeValue error: %u\n", GetLastError() ); return -1; } PRIVILEGE_SET privs; privs.PrivilegeCount = 1; privs.Control = PRIVILEGE_SET_ALL_NECESSARY; privs.Privilege[0].Luid = luidDebugPrivilege; privs.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED; BOOL bResult; ::PrivilegeCheck(hToken, &privs, &bResult); if(bResult) { printf("DEBUG ENABLED!\n"); } else { printf("DEBUG NOT ENABLED!\n"); }

Ответы [ 3 ]

2 голосов
/ 03 февраля 2011

Функция GetTokenInformation может использоваться для получения списка привилегий для процесса.PrivilegeCheck проверяет, включена ли привилегия или отключена, и привилегии, не принадлежащие пользователю, всегда будут отключены.Привилегии, которыми владеет пользователь, могут или не могут быть отключены (некоторые отключены по умолчанию)

По вашему вопросу, я думаю, что вы действительно хотите проверить, является ли пользователь администратором.

2 голосов
/ 03 февраля 2011

ОК, мы поняли это после публикации оригинального вопроса. Что нам действительно нужно сделать, так это попытаться установить привилегию «отладочные программы» для текущего процесса. Если мы можем включить эту привилегию, то это означает, что у текущего вошедшего в систему пользователя эта привилегия включена для него в редакторе локальной политики безопасности (gpedit.msc в XP ...)

См. Пример кода, если кому-то еще нужно решить эту проблему! Важные части:

  • Используйте LookupPrivilegeValue (), чтобы найти LUID для SeDebugPrivilege. (Все API для этого материала нуждаются в LUID ...)
  • Используйте GetTokenInformation (), чтобы узнать, какие привилегии уже включены в этом процессе. Если процесс уже имеет активированную привилегию, это означает, что процесс, скорее всего, выполняется под отладчиком и что у текущего вошедшего в систему пользователя активирована привилегия.
  • Если процесс не имеет установленной привилегии, используйте AdjustTokenPrivileges (), чтобы попытаться установить привилегию. Это в нашем методе AttemptToAddDebugPrivilegeToProcess () ниже; мы возвращаем true, если привилегия может быть установлена ​​(имеется в виду, что у текущего вошедшего в систему пользователя включена привилегия «отладочные программы») или false, если она не может.

#include "stdafx.h"
#include <strsafe.h>

void ShowLastError(LPTSTR lpszFunction) { 
    // Retrieve the system error message for the last-error code

    LPVOID lpMsgBuf;
    LPVOID lpDisplayBuf;
    DWORD dw = GetLastError(); 

    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        dw,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR) &lpMsgBuf,
        0, NULL );

    // Display the error message and exit the process

    lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT, 
        (lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR)); 
    StringCchPrintf((LPTSTR)lpDisplayBuf, 
        LocalSize(lpDisplayBuf) / sizeof(TCHAR),
        TEXT("%s failed with error %d: %s"), 
        lpszFunction, dw, lpMsgBuf); 
    printf((LPTSTR)lpDisplayBuf);

    LocalFree(lpMsgBuf);
    LocalFree(lpDisplayBuf);
}



bool LuidsMatch(LUID l1, LUID l2)
{
    return l1.LowPart == l2.LowPart && l1.HighPart == l2.HighPart; }

bool AttemptToAddDebugPrivilegeToProcess(HANDLE hToken) {
    //Find the LUID for the debug privilege token
    LUID luidDebugPrivilege;
    if ( !LookupPrivilegeValue( 
        NULL,            // lookup privilege on local system
        "SeDebugPrivilege",   // privilege to lookup 
        &luidDebugPrivilege ) )        // receives LUID of privilege
    {
        printf("LookupPrivilegeValue error: %u\n", GetLastError() ); 
        return false; 
    }

    TOKEN_PRIVILEGES newState;
    newState.PrivilegeCount = 1;
    newState.Privileges[0].Luid = luidDebugPrivilege;
    newState.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

    if(AdjustTokenPrivileges(
        hToken,
        FALSE,
        &newState,
        sizeof(newState),
        NULL, //&previousState, 
        0))
    {
        if(GetLastError() == ERROR_NOT_ALL_ASSIGNED)
        {
            printf("Couldn't set debug!!!");
            return false;
        }

        //*************************************************************
        //IF YOU MADE IT HERE, THE USER HAS THE DEBUG PROGRAMS PRIVILEGE
        //*************************************************************
        printf("DEBUG OK!!!");
        return true;
    }

    printf("AdjustTokenPrivileges returned false!!!");
    ShowLastError("AdjustTokenPrivileges");
    return false;
}

int _tmain(int argc, _TCHAR* argv[])
{
    HANDLE hToken;

    // Get the calling thread's access token.
    if (!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, TRUE, &hToken)) 
    {
        if (GetLastError() != ERROR_NO_TOKEN)
        {
            printf("CAN'T GET THREAD TOKEN!!!\n");
            return -1;
        }

        // Retry against process token if no thread token exists.
        if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &hToken))
        {
            printf("CAN'T GET PROCESS TOKEN!!!\n");
            return -1;
        }
    }

    //Find the LUID for the debug privilege token
    LUID luidDebugPrivilege;
    if ( !LookupPrivilegeValue( 
        NULL,            // lookup privilege on local system
        "SeDebugPrivilege",   // privilege to lookup 
        &luidDebugPrivilege ) )        // receives LUID of privilege
    {
        printf("LookupPrivilegeValue error: %u\n", GetLastError() ); 
        return -1; 
    }


    //Find if the "debug programs" privilege is already assigned to this process
    DWORD dwReturnedDataSize;
    GetTokenInformation(
        hToken,
        TokenPrivileges,
        NULL,
        0,
        &dwReturnedDataSize);

    BYTE* pData = new BYTE[dwReturnedDataSize];
    GetTokenInformation(
        hToken,
        TokenPrivileges,
        pData,
        dwReturnedDataSize,
        &dwReturnedDataSize);

    TOKEN_PRIVILEGES* pPrivileges = (TOKEN_PRIVILEGES*)pData;

    bool bFound = false;

    for(unsigned int count = 0; count PrivilegeCount; count++)
    {
        LUID_AND_ATTRIBUTES& luidAndAttrs = pPrivileges->Privileges[count];

        if(LuidsMatch(luidAndAttrs.Luid, luidDebugPrivilege))
        {
            bFound = true;
            if((luidAndAttrs.Attributes & SE_PRIVILEGE_ENABLED) == SE_PRIVILEGE_ENABLED)
            {
                //**************************************************************
                //IF YOU MADE IT HERE, THE USER HAS THE DEBUG PROGRAMS PRIVILEGE
                //**************************************************************
            }
            else
            {
                printf("THIS PROCESS DOES NOT HAVE THE DEBUG PROGRAMS PRIVILEGE ENABLED\n");                                AttemptToAddDebugPrivilegeToProcess(hToken);
            }
        }
    }

    if(!bFound)
    {
        printf("THIS PROCESS DOES NOT HAVE THE DEBUG PROGRAMS PRIVILEGE ENABLED\n");
        AttemptToAddDebugPrivilegeToProcess(hToken);
    }

    return 0;
}
1 голос
/ 03 февраля 2011

Если я правильно понимаю, вы можете использовать LsaEnumerateAccountRights , чтобы получить список привилегий, которыми обладает пользователь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...