4
A
回答
3
当然,你需要调用:
OpenThreadToken()
要获得用户的令牌。
GetTokenInformation(hToken, TokenGroups, NULL, 0, &dwNeeded)
要获得的令牌组信息的大小(以及分配足够的空间)
GetTokenInformation(hToken, TokenGroups, pTokenGroups, dwSize, &dwNeeded)
为了获得本地组
AllocateAndInitializeSid(&SIDAuthNT, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &psidAdministrators);
要得到管理员的SID
EqualSid()
To co与您本地组中的SID进行比较。
6
有几种根本不同的方法。不幸的是,最常见的 非常乏味。它包括确定当前 用户的SID,然后找到该组他所属的,然后 发现其中一个是否是管理员组:
#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
-3
4
稍微不同的使用IsUserAnAdmin方法改编自一些提示MSDN:
PSID administrators_group = NULL;
SID_IDENTIFIER_AUTHORITY nt_authority = SECURITY_NT_AUTHORITY;
BOOL result = AllocateAndInitializeSid(&nt_authority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &administrators_group);
BOOL is_user_admin = FALSE;
if (result)
{
CheckTokenMembership(NULL, administrators_group, &is_user_admin);
FreeSid(administrators_group);
}
if (is_user_admin)
{
// do something here for admin users...
}
+0
我还没有测试,但想知道是否可以使用支持UAC的机器来确定UAC提升,但不一定是管理员组的成员资格? – TaterJuice
相关问题
- 1. 检查用户是否具有特定的Windows权限Powershell
- 2. Postgres如何检查用户是否具有CREATEDB权限?
- 3. 如何检查当前用户是否具有管理权限
- 4. 如何检查用户是否具有windows api文件的访问权限
- 5. 检查用户是否有权限
- 6. Laravel:检查用户是否有权限
- 7. 检查用户是否具有查看文件夹权限
- 8. Python - 检查用户是否具有管理员权限
- 9. Qt,Linux,检查给定的用户是否具有sudo权限
- 10. 检查用户是否具有读/写权限
- 11. Redmine:检查用户是否具有特定权限
- 12. 检查请求的用户是否具有管理员权限
- 13. 脸书连接:检查用户是否具有javascript的权限
- 14. 如何检查用户是否具有数据库查询权限?
- 15. 如何检查用户是否同步拥有publish_stream权限?
- 16. 如何检查进程是否具有管理权限
- 17. 检查文件是否具有可执行权利Windows C++
- 18. 检查用户是否有权限查看页面
- 19. 如何检查用户是否已授予publish_actions权限
- 20. 如何检查用户是否授予Facebook访问权限?
- 21. FBLoginView如何检查用户是否接受了发布权限?
- 22. 使用AngularJS服务来检查用户是否具有管理员权限
- 23. 如何找出用户是否具有管理员权限?
- 24. 如何通过使用JAVA SDK检查用户是否具有S3权限是否允许?
- 25. 检查用户是否登录没有要求权限 - facebook
- 26. Mysql加入,检查用户是否有权限
- 27. 的Microsoft Dynamics 4.0 SDK检查用户是否有权限
- 28. 如何知道我是否具有管理权限在Windows中?
- 29. 是否有任何系统定义的函数来检查用户是否具有更改权限?
- 30. 检查用户权限的权限
谢谢,这帮助了我,但起初我没有意识到第一次调用GetTokenInformation可能会返回一个错误。我建议添加到答案中(确保GetLastError()== ERROR_INSUFFICIENT_MEMORY)。 – TBD
这实际上是Win32编程中一个非常常见的模式。无论何时你看到一个API被调用两次,第一次使用NULL时,通常情况下,第一次调用获取大小,以便为第二次调用分配正确的内存。 – Benj