如何以编程方式确定帐户是否属于Administrators组?

时间:2015-06-19 16:40:34

标签: c++ windows account

我的Windows有几个帐户,例如属于Administrators组的“test1”,“test2”和“test3”。我正在开发一个应用程序,我希望该程序通过设计布尔函数来了解它自己是否在属于Administrators组的帐户下运行: isCurrentUserAdminMember() isCurrentUserAdminMember() 功能只应在“test1”,“test2”,“test3”或内置管理员帐户 运行流程时返回TRUE,无论流程是否提升

我在http://www.codeproject.com/Articles/320748/Haephrati-Elevating-during-runtime中找到了一些代码,如下所示,但似乎只是检查当前进程是否作为管理员提升。我不关心进程是否提升,我只想知道进程的启动帐户是否是Administrators组的成员。我希望决心本身不是必需的特权。那可能吗?感谢。

    BOOL IsAppRunningAsAdminMode()
    {
        BOOL fIsRunAsAdmin = FALSE;
        DWORD dwError = ERROR_SUCCESS;
        PSID pAdministratorsGroup = NULL;

        // Allocate and initialize a SID of the administrators group.
        SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
        if (!AllocateAndInitializeSid(
            &NtAuthority, 
            2, 
            SECURITY_BUILTIN_DOMAIN_RID, 
            DOMAIN_ALIAS_RID_ADMINS, 
            0, 0, 0, 0, 0, 0, 
            &pAdministratorsGroup))
        {
            dwError = GetLastError();
            goto Cleanup;
        }

        // Determine whether the SID of administrators group is enabled in 
        // the primary access token of the process.
        if (!CheckTokenMembership(NULL, pAdministratorsGroup, &fIsRunAsAdmin))
        {
            dwError = GetLastError();
            goto Cleanup;
        }

    Cleanup:
        // Centralized cleanup for all allocated resources.
        if (pAdministratorsGroup)
        {
            FreeSid(pAdministratorsGroup);
            pAdministratorsGroup = NULL;
        }

        // Throw the error if something failed in the function.
        if (ERROR_SUCCESS != dwError)
        {
            throw dwError;
        }

        return fIsRunAsAdmin;
    }

最后,我们实现了将管理员组成员身份检查为下面的代码的目标,但是 USELESS 作为答案和评论说,如果有人需要它,请留待此处参考其他用途。

// PermTest.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "stdio.h"
#include "iostream"
using namespace std;
#include "windows.h"

#include <lm.h>
#pragma comment(lib, "netapi32.lib")

BOOL IsUserInGroup(const wchar_t* groupe)
{
    BOOL result = FALSE;
    SID_NAME_USE snu;
    WCHAR szDomain[256];
    DWORD dwSidSize = 0;
    DWORD dwSize = sizeof szDomain / sizeof * szDomain;

    if ((LookupAccountNameW(NULL, groupe, 0, &dwSidSize, szDomain, &dwSize, &snu) == 0)
        && (ERROR_INSUFFICIENT_BUFFER == GetLastError()))
    {
        SID* pSid = (SID*)malloc(dwSidSize);

        if (LookupAccountNameW(NULL, groupe, pSid, &dwSidSize, szDomain, &dwSize, &snu))
        {
            BOOL b;

            if (CheckTokenMembership(NULL, pSid, &b))
            {
                if (b == TRUE)
                {
                    result = TRUE;
                }
            }
            else
            {
                result = FALSE;
            }
        }

        //Si tout vas bien (la presque totalitée des cas), on delete notre pointeur
        //avec le bon operateur.
        free(pSid);
    }

    return result;
}

void getUserInfo(WCHAR *domainName, WCHAR *userName)
{
    LPUSER_INFO_3 pBuf = NULL;
    int j = 0;
    DWORD nStatus = NetUserGetInfo(domainName, userName, 3, (LPBYTE *) &pBuf);

    LPUSER_INFO_2 pBuf2 = NULL;
    pBuf2 = (LPUSER_INFO_2) pBuf;
    if (pBuf)
    {
        wprintf(L"User account name: %s\\%s\n", domainName, pBuf2->usri2_name);
        wprintf(L"Privilege level: %d\n\n", pBuf2->usri2_priv);
    }



//  wprintf(L"\tPassword: %s\n", pBuf2->usri2_password);
//  wprintf(L"\tPassword age (seconds): %d\n",
//      pBuf2->usri2_password_age);
//  wprintf(L"Privilege level: %d\n\n", pBuf2->usri2_priv);
// #define USER_PRIV_GUEST     0
// #define USER_PRIV_USER      1
// #define USER_PRIV_ADMIN     2

//  wprintf(L"\tHome directory: %s\n", pBuf2->usri2_home_dir);
//  wprintf(L"\tComment: %s\n", pBuf2->usri2_comment);
//  wprintf(L"\tFlags (in hex): %x\n", pBuf2->usri2_flags);
//  wprintf(L"\tScript path: %s\n", pBuf2->usri2_script_path);
//  wprintf(L"\tAuth flags (in hex): %x\n",
//      pBuf2->usri2_auth_flags);
//  wprintf(L"\tFull name: %s\n", pBuf2->usri2_full_name);
//  wprintf(L"\tUser comment: %s\n", pBuf2->usri2_usr_comment);
//  wprintf(L"\tParameters: %s\n", pBuf2->usri2_parms);
//  wprintf(L"\tWorkstations: %s\n", pBuf2->usri2_workstations);
//  wprintf
//      (L"\tLast logon (seconds since January 1, 1970 GMT): %d\n",
//      pBuf2->usri2_last_logon);
//  wprintf
//      (L"\tLast logoff (seconds since January 1, 1970 GMT): %d\n",
//      pBuf2->usri2_last_logoff);
//  wprintf
//      (L"\tAccount expires (seconds since January 1, 1970 GMT): %d\n",
//      pBuf2->usri2_acct_expires);
//  wprintf(L"\tMax storage: %d\n", pBuf2->usri2_max_storage);
//  wprintf(L"\tUnits per week: %d\n",
//      pBuf2->usri2_units_per_week);
//  wprintf(L"\tLogon hours:");
//  for (j = 0; j < 21; j++) 
//  {
//      printf(" %x", (BYTE) pBuf2->usri2_logon_hours[j]);
//  }
//  wprintf(L"\n");
//  wprintf(L"\tBad password count: %d\n",
//      pBuf2->usri2_bad_pw_count);
//  wprintf(L"\tNumber of logons: %d\n",
//      pBuf2->usri2_num_logons);
//  wprintf(L"\tLogon server: %s\n", pBuf2->usri2_logon_server);
//  wprintf(L"\tCountry code: %d\n", pBuf2->usri2_country_code);
//  wprintf(L"\tCode page: %d\n", pBuf2->usri2_code_page);
}

#include <comdef.h>
#define MAX_NAME 256
BOOL GetLogonFromToken (HANDLE hToken, _bstr_t& strUser, _bstr_t& strdomain) 
{
    DWORD dwSize = MAX_NAME;
    BOOL bSuccess = FALSE;
    DWORD dwLength = 0;
    strUser = "";
    strdomain = "";
    PTOKEN_USER ptu = NULL;
    //Verify the parameter passed in is not NULL.
    if (NULL == hToken)
        goto Cleanup;

    if (!GetTokenInformation(
        hToken,         // handle to the access token
        TokenUser,    // get information about the token's groups 
        (LPVOID) ptu,   // pointer to PTOKEN_USER buffer
        0,              // size of buffer
        &dwLength       // receives required buffer size
        )) 
    {
        if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) 
            goto Cleanup;

        ptu = (PTOKEN_USER)HeapAlloc(GetProcessHeap(),
            HEAP_ZERO_MEMORY, dwLength);

        if (ptu == NULL)
            goto Cleanup;
    }

    if (!GetTokenInformation(
        hToken,         // handle to the access token
        TokenUser,    // get information about the token's groups 
        (LPVOID) ptu,   // pointer to PTOKEN_USER buffer
        dwLength,       // size of buffer
        &dwLength       // receives required buffer size
        )) 
    {
        goto Cleanup;
    }
    SID_NAME_USE SidType;
    char lpName[MAX_NAME];
    char lpDomain[MAX_NAME];

    if( !LookupAccountSidA( NULL , ptu->User.Sid, lpName, &dwSize, lpDomain, &dwSize, &SidType ) )                                    
    {
        DWORD dwResult = GetLastError();
        if( dwResult == ERROR_NONE_MAPPED )
            strcpy (lpName, "NONE_MAPPED" );
        else 
        {
            printf("LookupAccountSid Error %u\n", GetLastError());
        }
    }
    else
    {
//      printf( "Current user is  %s\\%s\n", 
//          lpDomain, lpName );
        strUser = lpName;
        strdomain = lpDomain;
        bSuccess = TRUE;
    }

Cleanup: 

    if (ptu != NULL)
        HeapFree(GetProcessHeap(), 0, (LPVOID)ptu);
    return bSuccess;
}

HRESULT GetUserFromProcess( _bstr_t& strUser, _bstr_t& strdomain)
{
    //HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,procId); 
    HANDLE hProcess = GetCurrentProcess();
    if(hProcess == NULL)
        return E_FAIL;
    HANDLE hToken = NULL;

    if( !OpenProcessToken( hProcess, TOKEN_QUERY, &hToken ) )
    {
        CloseHandle( hProcess );
        return E_FAIL;
    }
    BOOL bres = GetLogonFromToken (hToken, strUser,  strdomain);

    CloseHandle( hToken );
    CloseHandle( hProcess );
    return bres?S_OK:E_FAIL;
}



int _tmain(int argc, _TCHAR* argv[])
{
    //cout << IsUserInGroup(L"administrators");


    getUserInfo(L"adtest.net", L"Administrator");
    getUserInfo(NULL, L"Administrator");
    getUserInfo(NULL, L"test");
    getUserInfo(NULL, L"test2");
    getUserInfo(NULL, L"testnormal");

    _bstr_t username;
    _bstr_t domain;
    GetUserFromProcess(username, domain);
    cout << "Current account running this program is: " << endl << domain << "\\" << username << endl;

    getchar();
    return 0;
}

2 个答案:

答案 0 :(得分:0)

您可以通过打开流程令牌(OpenProcessToken,使用GetTokenInformation列出SID并将每个SID与管理员SID进行比较来执行此操作。

Microsoft在此处提供示例代码:Searching for a SID in an Access Token in C++

然而,这很少有用。即使用户不是Administrators组的成员,他们仍然可以通过提供管理用户名和密码来提升,因此如果用户位于Administrators组中,您不应该(例如)提供提升。

答案 1 :(得分:0)

li {
   display: inline-block;
}
相关问题