Windows 小记 5 -- 判断账户是否是管理员账户
判断账户是否位于管理员用户组的方法有:
net localgroup Administrators "账户名" /add
如果返回“操作成功完成”,则表明之前不是管理员账户。那么再调用 /del 删除添加的管理员。
如果返回 “\n发生系统错误 1378。\n指定的帐户名已是此组的成员。\n” 则表明已经位于管理员用户组。
那么怎么通过编程实现更加准确快速的检测呢?
本地账户:
#include <windows.h>
#include <lm.h>
#include <iostream>
#pragma comment(lib, "Netapi32.lib")
bool IsAccountAdministrator(const std::wstring& userName) {
LPLOCALGROUP_USERS_INFO_0 groupInfo = NULL;
DWORD entriesRead = 0;
DWORD totalEntries = 0;
// 使用 NetUserGetLocalGroups 获取本地用户组信息
NET_API_STATUS status = NetUserGetLocalGroups(
NULL, // 本地计算机
userName.c_str(),
0, // 信息级别 0
LG_INCLUDE_INDIRECT, // 包含间接组成员关系
(LPBYTE*)&groupInfo,
MAX_PREFERRED_LENGTH,
&entriesRead,
&totalEntries
);
if (status == NERR_Success) {
for (DWORD i = 0; i < entriesRead; i++) {
// 检查用户是否属于 "Administrators" 组
if (_wcsicmp(groupInfo[i].lgrui0_name, L"Administrators") == 0) {
NetApiBufferFree(groupInfo);
return true; // 用户属于管理员组
}
}
NetApiBufferFree(groupInfo);
}
else {
std::wcerr << L"Failed to get local groups, error code: " << status << std::endl;
}
return false; // 用户不属于管理员组
}
int main() {
std::wstring userName = L"XXXXXXXX"; // 替换为要检查的用户名
if (IsAccountAdministrator(userName)) {
std::wcout << userName << L" is an administrator." << std::endl;
}
else {
std::wcout << userName << L" is not an administrator." << std::endl;
}
return 0;
}
域用户(针对间接或者嵌套用户组,最佳的获取方式是通过令牌SID,如果用户账户已经登陆,则可以通过进程句柄获取令牌,否则,则需要通过凭据登陆获取令牌)
#include <windows.h>
#include <sddl.h>
#include <iostream>
#include <tchar.h>
bool IsSpecifiedUserAdmin(const std::wstring& userName, const std::wstring& domainName, const std::wstring& password) {
HANDLE tokenHandle = NULL;
DWORD size = 0;
PTOKEN_GROUPS tokenGroups = NULL;
SID_IDENTIFIER_AUTHORITY ntAuthority = SECURITY_NT_AUTHORITY;
PSID adminGroup = NULL;
bool isAdmin = false;
// 尝试使用提供的用户名和密码登录
if (!LogonUser(userName.c_str(), domainName.c_str(), password.c_str(),
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &tokenHandle)) {
std::wcerr << L"Failed to log on user: " << GetLastError() << std::endl;
return false;
}
// 获取用户令牌中的组信息
if (!GetTokenInformation(tokenHandle, TokenGroups, NULL, 0, &size) &&
GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
std::cerr << "Failed to get token information size." << std::endl;
CloseHandle(tokenHandle);
return false;
}
tokenGroups = (PTOKEN_GROUPS)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
if (tokenGroups == NULL) {
std::cerr << "Failed to allocate memory for token groups." << std::endl;
CloseHandle(tokenHandle);
return false;
}
if (!GetTokenInformation(tokenHandle, TokenGroups, tokenGroups, size, &size)) {
std::cerr << "Failed to get token information." << std::endl;
HeapFree(GetProcessHeap(), 0, tokenGroups);
CloseHandle(tokenHandle);
return false;
}
// 创建管理员组 SID
if (!AllocateAndInitializeSid(&ntAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &adminGroup)) {
std::cerr << "Failed to initialize SID." << std::endl;
HeapFree(GetProcessHeap(), 0, tokenGroups);
CloseHandle(tokenHandle);
return false;
}
// 检查是否属于管理员组
for (DWORD i = 0; i < tokenGroups->GroupCount; i++) {
if (EqualSid(adminGroup, tokenGroups->Groups[i].Sid)) {
isAdmin = true;
break;
}
}
// 清理
FreeSid(adminGroup);
HeapFree(GetProcessHeap(), 0, tokenGroups);
CloseHandle(tokenHandle);
return isAdmin;
}
int main() {
// 替换为要检测的用户名、域和密码
std::wstring userName = L"TestUser";
std::wstring domainName = L"."; // 本地计算机使用 "."
std::wstring password = L"UserPassword";
if (IsSpecifiedUserAdmin(userName, domainName, password)) {
std::wcout << L"The specified user is an administrator." << std::endl;
}
else {
std::wcout << L"The specified user is not an administrator." << std::endl;
}
return 0;
}
下面代码未测试域用户等复杂情况。
添加/删除目标用户到管理员用户组:
#include <windows.h>
#include <lm.h>
#include <iostream>
#pragma comment(lib, "Netapi32.lib")
bool AddUserToGroup(const std::wstring& userName) {
LOCALGROUP_MEMBERS_INFO_3 memberInfo;
memberInfo.lgrmi3_domainandname = const_cast<wchar_t*>(userName.c_str());
NET_API_STATUS status = NetLocalGroupAddMembers(NULL, L"Administrators", 3, (LPBYTE)&memberInfo, 1);
if (status == NERR_Success) {
std::wcout << L"User " << userName << L" added to Administrators group." << std::endl;
return true;
}
else {
std::wcerr << L"Failed to add user to Administrators group, error code: " << status << std::endl;
return false;
}
}
bool RemoveUserFromGroup(const std::wstring& userName) {
LOCALGROUP_MEMBERS_INFO_3 memberInfo;
memberInfo.lgrmi3_domainandname = const_cast<wchar_t*>(userName.c_str());
NET_API_STATUS status = NetLocalGroupDelMembers(NULL, L"Administrators", 3, (LPBYTE)&memberInfo, 1);
if (status == NERR_Success) {
std::wcout << L"User " << userName << L" removed from Administrators group." << std::endl;
return true;
}
else {
std::wcerr << L"Failed to remove user from Administrators group, error code: " << status << std::endl;
return false;
}
}
int main() {
std::wstring userName = L"XXXXX"; // 设置需要操作的用户名
// 添加用户到管理员组
AddUserToGroup(userName);
system("pause");
// 从管理员组移除用户
RemoveUserFromGroup(userName);
return 0;
}
可以通过 net localgroup Administrators 进行验证。
此外需要注意,当账户没有启用时,可能是无法创建和登陆管理员用户的。所以我们也可以查询管理员用户组中用户的状态,使用下面的代码:
#include <windows.h>
#include <lm.h>
#include <iostream>
#pragma comment(lib, "Netapi32.lib")
void CheckAdministratorsGroup(bool showAllUsers) {
LOCALGROUP_MEMBERS_INFO_1* groupMembers = NULL;
DWORD entriesRead = 0;
DWORD totalEntries = 0;
DWORD_PTR resumeHandle = 0;
NET_API_STATUS status;
// 获取 Administrators 组的成员列表
status = NetLocalGroupGetMembers(
NULL, // 本地计算机
L"Administrators", // 组名
1, // 信息级别
(LPBYTE*)&groupMembers, // 输出缓冲区
MAX_PREFERRED_LENGTH, // 缓冲区大小
&entriesRead, // 读取的条目数
&totalEntries, // 总条目数
&resumeHandle // 分页句柄
);
if (status != NERR_Success) {
std::cerr << "Failed to get group members. Error code: " << status << std::endl;
return;
}
bool hasEnabledUser = false;
// 遍历组成员
for (DWORD i = 0; i < entriesRead; ++i) {
USER_INFO_1* userInfo = NULL;
// 获取每个成员的用户信息
status = NetUserGetInfo(NULL, groupMembers[i].lgrmi1_name, 1, (LPBYTE*)&userInfo);
if (status == NERR_Success) {
// 检查用户是否被禁用
bool isUserEnabled = !(userInfo->usri1_flags & UF_ACCOUNTDISABLE);
if (isUserEnabled) {
hasEnabledUser = true;
}
// 如果开关参数为 true,显示每个用户的状态
if (showAllUsers) {
std::wcout << L"User: " << groupMembers[i].lgrmi1_name
<< L" - Status: " << (isUserEnabled ? L"Enabled" : L"Disabled") << std::endl;
}
NetApiBufferFree(userInfo);
}
}
NetApiBufferFree(groupMembers);
// 如果不显示所有用户,仅报告是否有启用的用户
if (!showAllUsers) {
if (hasEnabledUser) {
std::cout << "The Administrators group has at least one enabled user." << std::endl;
}
else {
std::cout << "No enabled user found in the Administrators group." << std::endl;
}
}
}
int main() {
bool showAllUsers = true; // 设置为 true 以显示所有用户及其状态
CheckAdministratorsGroup(showAllUsers);
return 0;
}
添加或者删除本地用户(出于一些原因,不提供凭据验证过程代码):
#include <windows.h>
#include <lm.h>
#include <iostream>
#include <string>
#include <tchar.h>
#include <strsafe.h>
#pragma comment(lib, "Netapi32.lib")
#pragma comment(lib, "Advapi32.lib")
// 添加本地用户
bool AddLocalUser(const std::wstring& userName, const std::wstring& password) {
USER_INFO_1 userInfo;
ZeroMemory(&userInfo, sizeof(userInfo));
userInfo.usri1_name = const_cast<wchar_t*>(userName.c_str());
userInfo.usri1_password = const_cast<wchar_t*>(password.c_str());
userInfo.usri1_priv = USER_PRIV_USER; // 普通用户权限
userInfo.usri1_home_dir = NULL;
userInfo.usri1_comment = NULL;
userInfo.usri1_flags = UF_SCRIPT | UF_DONT_EXPIRE_PASSWD; // 用户必须使用脚本,密码永不过期
userInfo.usri1_script_path = NULL;
DWORD error = 0;
NET_API_STATUS status = NetUserAdd(NULL, 1, (LPBYTE)&userInfo, &error);
if (status == NERR_Success) {
std::wcout << L"User " << userName << L" added successfully." << std::endl;
return true;
}
else {
std::wcerr << L"Failed to add user. Error code: " << status << std::endl;
return false;
}
}
// 删除本地用户
bool DeleteLocalUser(const std::wstring& userName) {
NET_API_STATUS status = NetUserDel(NULL, userName.c_str());
if (status == NERR_Success) {
std::wcout << L"User " << userName << L" deleted successfully." << std::endl;
return true;
}
else {
std::wcerr << L"Failed to delete user. Error code: " << status << std::endl;
return false;
}
}
// 验证用户凭据
bool AuthenticateUser() {
return true; // 出于安全考虑,此处代码不提供给大家
}
int main() {
std::wstring userName;
std::wcout << L"Enter the username to add or delete: ";
std::getline(std::wcin, userName);
// 验证用户凭据
std::wcout << L"Please authenticate to proceed." << std::endl;
if (!AuthenticateUser()) {
std::wcerr << L"Failed to authenticate user." << std::endl;
return 1;
}
std::wcout << L"Do you want to (a)dd or (d)elete the user? (a/d): ";
wchar_t action;
std::wcin >> action;
if (action == L'a' || action == L'A') {
std::wstring password;
std::wcout << L"Enter the password for the new user: ";
std::wcin.ignore(); // 清除输入缓冲区
std::getline(std::wcin, password);
AddLocalUser(userName, password);
}
else if (action == L'd' || action == L'D') {
DeleteLocalUser(userName);
}
else {
std::wcout << L"Invalid action selected." << std::endl;
}
return 0;
}
凭据验证模式:
文章出处链接:[https://blog.csdn.net/qq_59075481/article/details/143821835].
原文地址:https://blog.csdn.net/qq_59075481/article/details/143821835
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!