15#pragma comment(lib, "netapi32.lib")
16#pragma comment(lib, "advapi32.lib")
51 LPGROUP_USERS_INFO_0 pGroups = NULL;
52 DWORD dwEntriesRead = 0, dwTotalEntries = 0;
54 NET_API_STATUS nStatus = ::NetUserGetGroups(NULL, pwszUser, 0, (LPBYTE*)&pGroups, MAX_PREFERRED_LENGTH, &dwEntriesRead, &dwTotalEntries);
55 if (nStatus == ERROR_ACCESS_DENIED) {
60 if (nStatus == NERR_Success) {
61 for (DWORD i = 0; i < dwEntriesRead; i++) {
63 lstPermissions.
Add(
String(
"GroupMember:") + sGroup.c_str());
64 lstGroups.
Add(sGroup.c_str());
66 ::NetApiBufferFree(pGroups);
72 BYTE sidBuffer[SECURITY_MAX_SID_SIZE];
73 DWORD cbSid =
sizeof(sidBuffer);
74 WCHAR szDomain[256] = { 0 };
75 DWORD cchDomain = 256;
78 if (::LookupAccountNameW(NULL, pwszUser, (PSID)sidBuffer, &cbSid, szDomain, &cchDomain, &peUse)) {
79 LPWSTR pszStringSid = NULL;
80 if (::ConvertSidToStringSidW((PSID)sidBuffer, &pszStringSid)) {
82 ::LocalFree(pszStringSid);
99 info.
bIsDisabled = (pUi->usri1_flags & UF_ACCOUNTDISABLE) != 0;
117 LPUSER_INFO_1 pBuf = NULL;
118 DWORD dwEntriesRead = 0, dwTotalEntries = 0, dwResumeHandle = 0;
120 NET_API_STATUS nStatus = ::NetUserEnum(NULL, 1, FILTER_NORMAL_ACCOUNT, (LPBYTE*)&pBuf, MAX_PREFERRED_LENGTH, &dwEntriesRead, &dwTotalEntries, &dwResumeHandle);
121 if (nStatus == ERROR_ACCESS_DENIED) {
125 if (nStatus == NERR_Success || nStatus == ERROR_MORE_DATA) {
126 for (DWORD i = 0; i < dwEntriesRead; i++) {
132 ::NetApiBufferFree(pBuf);
136 static UserInfo BuildLinuxUserInfo(
const struct passwd* pw) {
139 info.sUsername = pw->pw_name;
140 info.sDomain =
"LOCAL";
141 info.sSidOrUid = std::to_string(pw->pw_uid).c_str();
142 info.bIsDisabled =
false;
143 info.bIsPasswordRequired =
true;
144 info.bIsAccountLocked =
false;
146 if (pw->pw_uid == 0) {
148 info.lstPermissions.Add(
"RootPrivileges");
149 info.lstPermissions.Add(
"FullControl");
150 }
else if (pw->pw_uid < 1000) {
152 info.lstPermissions.Add(
"SystemDaemonRights");
155 info.lstPermissions.Add(
"StandardUserRights");
161 static void EnumerateLinuxUsers(Collections::Generic::List<UserInfo>& lstUsers) {
166 while ((pw = getpwent()) != NULL) {
167 lstUsers.
Add(BuildLinuxUserInfo(pw));
169 if (errno == EACCES || errno == EPERM) {
184 EnumerateLinuxUsers(lstUsers);
194 LPUSER_INFO_1 pBuf = NULL;
195 NET_API_STATUS nStatus = ::NetUserGetInfo(NULL, wUsername.c_str(), 1, (LPBYTE*)&pBuf);
196 if (nStatus == NERR_Success && pBuf != NULL) {
198 ::NetApiBufferFree(pBuf);
201 if (nStatus == ERROR_ACCESS_DENIED)
throw UnauthorizedAccessException(
"Access denied querying user information for: " + sUsername);
202 if (nStatus == NERR_UserNotFound || nStatus == ERROR_NO_SUCH_USER)
throw ArgumentException(
"User not found: " + sUsername);
208 WCHAR szName[256] = { 0 };
210 if (!::GetUserNameW(szName, &dwSize)) {
211 DWORD dwErr = ::GetLastError();
223 if (errno == EACCES || errno == EPERM)
throw UnauthorizedAccessException(
"Access denied querying user information for: " + sUsername);
226 return BuildLinuxUserInfo(pw);
229 static UserInfo QueryCurrentLinuxUser() {
232 struct passwd* pw = getpwuid(getuid());
237 return BuildLinuxUserInfo(pw);
247 return QueryLinuxUser(sUsername);
256 return QueryCurrentLinuxUser();
Defines the exception thrown when an invalid argument is provided to a method.
Serves as the base class for system exceptions across the library.
The exception that is thrown when the operating system denies access because of an I/O error or a spe...
User principal and account enumeration operations per POSIX and Win32 security APIs.
Exception thrown for a Win32 or platform-native error code.
ArgumentException(const String &sMessage)
Initializes a new instance of the ArgumentException class with a specified error message.
Represents a strongly typed list of objects accessible by index.
void Add(const T &item)
Adds an object to the end of the List.
Exception thrown for a Win32 or POSIX platform error code.
static std::wstring Utf8ToWChar(const char *pUtf8Str)
static std::string WCharToUtf8(const wchar_t *pWStr)
static Collections::Generic::List< UserInfo > EnumerateUsers()
Enumerates all registered local user accounts on the host system.
static UserInfo GetCurrent()
Retrieves account information for the currently executing process user.
static UserInfo GetUser(const String &sUsername)
Retrieves account information for a specified username.
UserPrincipal()
Initializes a new instance of the UserPrincipal class.
virtual ~UserPrincipal()
Releases resources used by the UserPrincipal.
Represents text as a sequence of UTF-8 code units with culture-invariant operations.
String()
Initializes a new instance of the String class to an empty string.
const char * GetRawString() const
SystemException()
Initializes a new instance of the SystemException class with a default message.
UnauthorizedAccessException()
Initializes a new instance of the UnauthorizedAccessException class with a default message.
static void PopulateWin32SidAndDomain(LPCWSTR pwszUser, UserInfo &info)
static void PopulateWin32UserGroups(LPCWSTR pwszUser, Collections::Generic::List< String > &lstGroups, Collections::Generic::List< String > &lstPermissions)
static UserInfo BuildWin32UserInfo(const USER_INFO_1 *pUi)
static UserClass ClassifyWindowsUser(DWORD dwPriv, DWORD dwFlags)
static std::string GetCurrentWin32UserName()
UserClass
Defines user account classification categories.
@ Normal
Standard authenticated user account.
@ System
System service or daemon account.
@ Guest
Guest or anonymous account.
@ Admin
Administrative or root user account.
static void EnumerateWin32Users(Collections::Generic::List< UserInfo > &lstUsers)
static UserInfo QueryWin32User(const String &sUsername)
@ UserInfo
User name and password authorization data.
Represents platform user account information and privileges.
bool bIsPasswordRequired
Indicates whether a password is required.
bool bIsDisabled
Indicates whether the account is disabled.
UserClass eUserClass
Classification level of the user.
String sSidOrUid
Security identifier (SID on Windows, UID on POSIX).
String sDomain
Domain or host machine name.
String sUsername
User login or account name.
Collections::Generic::List< String > lstPermissions
List of assigned permission strings.
Collections::Generic::List< String > lstGroups
List of security groups the user belongs to.
bool bIsAccountLocked
Indicates whether the account is currently locked out.