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

C++ 如何以编程方式确定帐户是否属于Administrators组?,c++,windows,account,C++,Windows,Account,我的Windows有几个属于Administrators组的帐户,如“test1”、“test2”和“test3”。我正在开发一个应用程序,我希望该程序通过设计一个布尔函数来知道自己是否在属于Administrators组的帐户下运行:isCurrentUserAdminMember(),isCurrentUserAdminMember()函数应该只在进程由test1>运行时返回TRUE,“test2”、“test3”或内置管理员帐户无论进程是否提升 我在下面的中找到一些代码,但它似乎只是检查当

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

我在下面的中找到一些代码,但它似乎只是检查当前进程是否提升为管理员。我不在乎进程是否提升,我只想知道进程的启动帐户是否是管理员组的成员。我希望确定本身不需要特权。可能吗?谢谢

    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;
    }

最后,我们实现了如下代码检查Administrators组成员身份的目标,但是它是无用的,正如回答和评论所说,请留下此处以供参考,以防任何人需要它用于其他用途

// 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;
}
//PermTest.cpp:定义控制台应用程序的入口点。
//
#包括“stdafx.h”
#包括“stdio.h”
#包括“iostream”
使用名称空间std;
#包括“windows.h”
#包括
#pragma注释(lib,“netapi32.lib”)
BOOL IsUserInGroup(常量wchar\u t*groupe)
{
布尔结果=假;
SID_NAME_使用snu;
WCHAR域[256];
DWORD dwSidSize=0;
DWORD dwSize=sizeof szDomain/sizeof*szDomain;
if((LookupAccountNameW(NULL、groupe、0、&dwSidSize、szDomain、&dwSize、&snu)==0)
&&(错误\u缓冲区不足==GetLastError()))
{
SID*pSid=(SID*)malloc(dwSidSize);
if(LookupAccountNameW(NULL、groupe、pSid和dwSidSize、szDomain和dwSize和snu))
{
布尔b;
if(CheckTokenMembership(NULL、pSid和b))
{
如果(b==TRUE)
{
结果=真;
}
}
其他的
{
结果=假;
}
}
//在删除notre pointeur时,我向您介绍了《全面和平协议》(la presque totalitée des cas)
//乐邦歌剧院。
免费(pSid);
}
返回结果;
}
void getUserInfo(WCHAR*域名,WCHAR*用户名)
{
LPUSER_INFO_3 pBuf=NULL;
int j=0;
DWORD nStatus=NetUserGetInfo(域名,用户名,3,(LPBYTE*)和pBuf);
LPUSER_INFO_2 pBuf2=NULL;
pBuf2=(LPUSER_INFO_2)pBuf;
如果(pBuf)
{
wprintf(L“用户帐户名:%s\\%s\n”,域名,pBuf2->usri2\u名称);
wprintf(L“特权级别:%d\n\n”,pBuf2->usri2_priv);
}
//wprintf(L“\t密码:%s\n”,pBuf2->usri2\u密码);
//wprintf(L“\t密码期限(秒):%d\n”,
//pBuf2->usri2_密码_年龄);
//wprintf(L“特权级别:%d\n\n”,pBuf2->usri2_priv);
//#定义用户_PRIV_GUEST 0
//#定义用户_PRIV_用户1
//#定义用户权限管理2
//wprintf(L“\tHome目录:%s\n”,pBuf2->usri2\u home\u dir);
//wprintf(L“\t建议:%s\n”,pBuf2->usri2\u注释);
//wprintf(L“\tFlags(十六进制):%x\n”,pBuf2->usri2\u标志);
//wprintf(L“\t脚本路径:%s\n”,pBuf2->usri2\u脚本路径);
//wprintf(L“\t第六个标志(十六进制):%x\n”,
//pBuf2->usri2_认证标志);
//wprintf(L“\t全名:%s\n”,pBuf2->usri2\u全名);
//wprintf(L“\t用户注释:%s\n”,pBuf2->usri2\u usr\u注释);
//wprintf(L“\t参数:%s\n”,pBuf2->usri2\u参数);
//WPRINF(L“\t工作站:%s\n”,pBuf2->usri2\u工作站);
//wprintf
//(L“\t首次登录(自1970年1月1日格林威治标准时间起的秒数):%d\n”,
//pBuf2->usri2(上次登录);
//wprintf
//(L“\t上次注销(自1970年1月1日格林威治标准时间起的秒):%d\n”,
//pBuf2->usri2(最后一次注销);
//wprintf
//(L“\t计数过期(自1970年1月1日格林威治标准时间起的秒):%d\n”,
//pBuf2->usri2账户到期);
//wprintf(L“\t最大存储:%d\n”,pBuf2->usri2\u最大存储);
//wprintf(L“\t每周:%d\n”,
//pBuf2->usri2单位/周);
//wprintf(L“\t登录小时:”;
//对于(j=0;j<21;j++)
//  {
//printf(“%x”,(字节)pBuf2->usri2_logon_hours[j]);
//  }
//wprintf(L“\n”);
//wprintf(L“\t负载密码计数:%d\n”,
//pBuf2->usri2_坏_pw_计数);
//wprintf(L“\t登录次数:%d\n”,
//pBuf2->usri2_num_logons);
//wprintf(L“\t登录服务器:%s\n”,pBuf2->usri2\u登录服务器);
//WPRINF(L“\t国家代码:%d\n”,pBuf2->usri2\u国家代码);
//WPRINF(L“\t代码页:%d\n”,pBuf2->usri2\u代码页);
}
#包括
#定义MAX_NAME 256
BOOL GetLogonFromToken(句柄hToken、str和strUser、str和strdomain)
{
DWORD dwSize=最大名称;
BOOL bsucces=假;
DWORD dwLength=0;
strUser=“”;
标准域=”;
PTOKEN_用户ptu=NULL;
//验证传入的参数不为NULL。
if(NULL==hToken)
去清理;
如果(!GetTokenInformation(
hToken,//访问令牌的句柄
TokenUser,//获取有关令牌组的信息
(LPVOID)ptu,//指向PTOKEN_用户缓冲区的指针
0,//缓冲区大小
&dwLength//接收所需的缓冲区大小
)) 
{
如果(GetLastError()!=错误\u缓冲区不足)
去清理;
ptu=(PTOKEN_USER)HeapAlloc(GetProcessHeap(),
堆(零内存,dwLength);
如果(ptu==NULL)
去清理;
}
如果(!GetTokenInformation(
hToken,//访问令牌的句柄
TokenUser,//获取有关令牌组的信息
(LPVOID)ptu,//指向PTOKEN_用户缓冲区的指针
dwLength,//缓冲区的大小
&dwLength//接收所需的缓冲区大小
)) 
{
去清理;
}
SID\u名称\u使用SidType;
中国
bool IsMemberOfGroup(const char *pszGroupName){
bool bFound = false;

HANDLE hToken=INVALID_HANDLE_VALUE;
BOOL bSuccess = OpenProcessToken( GetCurrentProcess(),
                                    TOKEN_QUERY,//|TOKEN_QUERY_SOURCE,
                                    &hToken);
if ( bSuccess )
{
    DWORD   dwSizeToken=0;
    DWORD   dwSizeName=0;
    DWORD   dwSizeReferencedDomainName = 0;
    // Get group information:
    GetTokenInformation(hToken, TokenGroups, NULL, dwSizeToken, &dwSizeToken);
    {
        const int MAX_NAME = 256;
        char *psName    = new char[MAX_NAME];
        char *psDomain  = new char[MAX_NAME];
        char *pBuf = new char[dwSizeToken+10];
        TOKEN_GROUPS *pGroupInfo = (TOKEN_GROUPS *)pBuf;
        bSuccess = GetTokenInformation(hToken, TokenGroups, pGroupInfo, dwSizeToken, &dwSizeToken);
        if ( bSuccess )
        {
            // find the group name we are looking for
            for ( UINT uiGroupNdx = 0; uiGroupNdx < pGroupInfo->GroupCount && !bFound; uiGroupNdx++ )
            {
                SID_NAME_USE    SidType;
                dwSizeName = MAX_NAME;
                dwSizeReferencedDomainName = MAX_NAME;

                bSuccess = LookupAccountSid(NULL,   // local system,
                                            pGroupInfo->Groups[uiGroupNdx].Sid,
                                            psName,
                                            &dwSizeName,
                                            psDomain,
                                            &dwSizeReferencedDomainName,
                                            &SidType);
                if ( bSuccess )
                {
                    if ( SidTypeGroup == SidType )
                    {
                        if ( !lstrcmpi(pszGroupName, psName) )
                        {
                            bFound = true;
                        }
                    }
                }
            }
        }

        delete [] pBuf;
        delete [] psName;
        delete [] psDomain;
    }

    CloseHandle(hToken);
}

return bFound;
}