gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 13:51:30 25 4
gpt4 key购买 nike

有没有办法有条件地检查(严格在 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,
0,
&buffer_size
);

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

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

bool succeeded = GetTokenInformation(
access_token,
TokenGroups,
group_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,
0,0,0,0,0,0,
&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, TokenGroups, group_token, 0, &buffer_size);

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

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

if (GetTokenInformation(token, TokenGroups, group_token, buffer_size, &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

关于c - 如何检查 Windows 用户是否具有 C 中的管理员权限?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10551538/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com