加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

如何检查Windows用户是否具有C的管理员权限?

发布时间:2020-12-13 22:38:55 所属栏目:Windows 来源:网络整理
导读:有没有办法有条件地检查(严格地说是C) Windows用户是否具有管理员权限? 我希望以编程方式执行此操作(而不是简单地告诉用户“以管理员身份运行”). 解决方法 有几种根本不同的方式.最普遍的 不幸的是,这是相当乏味的.它涉及寻找当前 用户的SID,然后找到他所
有没有办法有条件地检查(严格地说是C) Windows用户是否具有管理员权限?

我希望以编程方式执行此操作(而不是简单地告诉用户“以管理员身份运行”).

解决方法

有几种根本不同的方式.最普遍的
不幸的是,这是相当乏味的.它涉及寻找当前
用户的SID,然后找到他所属的组,然后
查找其中一个是否为Administrators组:

#include <windows.h> 
#include <vector>

bool is_administrator() { 
    HANDLE access_token; 
    DWORD buffer_size = 0; 
    PSID admin_SID; 
    TOKEN_GROUPS *group_token = NULL; 
    SID_IDENTIFIER_AUTHORITY NT_authority = SECURITY_NT_AUTHORITY; 

    if (!OpenProcessToken(GetCurrentProcess(),TOKEN_READ,&access_token)) 
        return false; 

    GetTokenInformation( 
        access_token,TokenGroups,group_token,&buffer_size 
        ); 

    std::vector<char> buffer(buffer_size);

    group_token = 
        reinterpret_cast<TOKEN_GROUPS*>(&buffer[0]); 

    bool succeeded = GetTokenInformation( 
        access_token,buffer_size,&buffer_size 
        ); 

    CloseHandle(access_token); 
    if (!succeeded) 
        return false;

    if (!AllocateAndInitializeSid( 
        &NT_authority,2,SECURITY_BUILTIN_DOMAIN_RID,DOMAIN_ALIAS_RID_ADMINS,&admin_SID 
        )) 
    {
        return false; 
    }

    bool found=false; 
    for(int i=0; !found && i < group_token->GroupCount; i++) 
        found = EqualSid(admin_SID,group_token->Groups[i].Sid); 
    FreeSid(admin_SID); 
    return found; 
}

还有另一种方法,虽然有点简单:

bool is_administrator() 
{ 
        bool result; 
        DWORD rc; 
        wchar_t user_name[256]; 
        USER_INFO_1 *info; 
        DWORD size = sizeof( user_name ); 
        GetUserNameW( user_name,&size); 
        rc = NetUserGetInfo( NULL,user_name,1,(byte **) &info ); 
        if ( rc != NERR_Success ) 
                return false; 
        result = info->usri1_priv == USER_PRIV_ADMIN; 
        NetApiBufferFree( info ); 
        return result; 
}

在任何一种情况下,如果你有一个域,事情可能有点毛茸茸,
因为特定用户可能是本地的管理员
机器,但不在域上,反之亦然.查找信息
并不一定会有太大变化,但你可能需要考虑一下
找出你真正想要的东西.

编辑:正如@Benj指出的那样,第一种方法确实可以使用一些更新.虽然我已经修复了它所带来的明显泄漏,但它仍然是一个巨大的单片功能,没有异常安全,而且通常是过时的编码风格.也许是一个小的更新:

#include <windows.h> 
#include <vector>
#include <algorithm>

class sid {
    PSID s;
public:
    sid(SID_IDENTIFIER_AUTHORITY auth,std::vector<DWORD> sub_auths) {
        DWORD count = sub_auths.size();
        sub_auths.resize(7,DWORD());

        if (!AllocateAndInitializeSid( 
            &auth,count,sub_auths[0],sub_auths[1],sub_auths[2],sub_auths[3],sub_auths[4],sub_auths[5],sub_auths[6],sub_auths[7],&s 
            )) 
        {
            throw std::runtime_error("Unable to allocate Admin SID");
        }
    }

    sid(PSID const &p=NULL) : s(p) {}
    bool operator==(sid const &r) const { return EqualSid(s,r.s); }
};

class access_token {
    HANDLE token;
public:
    access_token(HANDLE PID=GetCurrentProcess(),DWORD access=TOKEN_READ) {
        if (!OpenProcessToken(PID,access,&token))
            throw std::runtime_error("Unable to open process token");
    }
    operator HANDLE() { return token; }
    ~access_token() { CloseHandle(token); }
};

std::vector<sid> get_group_sids() {
    DWORD buffer_size = 0; 
    TOKEN_GROUPS *group_token = NULL; 
    std::vector<sid> groups;
    access_token token;

    GetTokenInformation(token,&buffer_size);

    std::vector<char> buffer(buffer_size);

    group_token = reinterpret_cast<TOKEN_GROUPS*>(&buffer[0]);

    if (GetTokenInformation(token,&buffer_size))
        for (int i=0; i<group_token->GroupCount; i++)
            groups.push_back(group_token->Groups[i].Sid);
    return groups;
}

bool is_administrator() {
    std::vector<sid> groups = get_group_sids();

    SID_IDENTIFIER_AUTHORITY NT_authority = SECURITY_NT_AUTHORITY;
    std::vector<DWORD> sub_auths;

    sub_auths.push_back(SECURITY_BUILTIN_DOMAIN_RID);
    sub_auths.push_back(DOMAIN_ALIAS_RID_ADMINS);

    sid admin_SID(NT_authority,sub_auths);

    return std::find(groups.begin(),groups.end(),admin_SID) != groups.end();
}

#ifdef TEST
#include <iostream>
#include <iomanip>

int main() {
    std::cout << std::boolalpha << is_administrator() << "n";
}

#endif

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读