1 // Windows/SecurityUtils.h
2 
3 #ifndef __WINDOWS_SECURITY_UTILS_H
4 #define __WINDOWS_SECURITY_UTILS_H
5 
6 #include <NTSecAPI.h>
7 
8 #include "Defs.h"
9 
10 namespace NWindows {
11 namespace NSecurity {
12 
13 class CAccessToken
14 {
15   HANDLE _handle;
16 public:
CAccessToken()17   CAccessToken(): _handle(NULL) {};
~CAccessToken()18   ~CAccessToken() { Close(); }
Close()19   bool Close()
20   {
21     if (_handle == NULL)
22       return true;
23     bool res = BOOLToBool(::CloseHandle(_handle));
24     if (res)
25       _handle = NULL;
26     return res;
27   }
28 
OpenProcessToken(HANDLE processHandle,DWORD desiredAccess)29   bool OpenProcessToken(HANDLE processHandle, DWORD desiredAccess)
30   {
31     Close();
32     return BOOLToBool(::OpenProcessToken(processHandle, desiredAccess, &_handle));
33   }
34 
35   /*
36   bool OpenThreadToken(HANDLE threadHandle, DWORD desiredAccess, bool openAsSelf)
37   {
38     Close();
39     return BOOLToBool(::OpenTreadToken(threadHandle, desiredAccess, BoolToBOOL(anOpenAsSelf), &_handle));
40   }
41   */
42 
AdjustPrivileges(bool disableAllPrivileges,PTOKEN_PRIVILEGES newState,DWORD bufferLength,PTOKEN_PRIVILEGES previousState,PDWORD returnLength)43   bool AdjustPrivileges(bool disableAllPrivileges, PTOKEN_PRIVILEGES newState,
44       DWORD bufferLength, PTOKEN_PRIVILEGES previousState, PDWORD returnLength)
45     { return BOOLToBool(::AdjustTokenPrivileges(_handle, BoolToBOOL(disableAllPrivileges),
46       newState, bufferLength, previousState, returnLength)); }
47 
AdjustPrivileges(bool disableAllPrivileges,PTOKEN_PRIVILEGES newState)48   bool AdjustPrivileges(bool disableAllPrivileges, PTOKEN_PRIVILEGES newState)
49     { return AdjustPrivileges(disableAllPrivileges, newState, 0, NULL, NULL); }
50 
AdjustPrivileges(PTOKEN_PRIVILEGES newState)51   bool AdjustPrivileges(PTOKEN_PRIVILEGES newState)
52     { return AdjustPrivileges(false, newState); }
53 
54 };
55 
56 #ifndef _UNICODE
57 typedef NTSTATUS (NTAPI *LsaOpenPolicyP)(PLSA_UNICODE_STRING SystemName,
58     PLSA_OBJECT_ATTRIBUTES ObjectAttributes, ACCESS_MASK DesiredAccess, PLSA_HANDLE PolicyHandle);
59 typedef NTSTATUS (NTAPI *LsaCloseP)(LSA_HANDLE ObjectHandle);
60 typedef NTSTATUS (NTAPI *LsaAddAccountRightsP)(LSA_HANDLE PolicyHandle,
61     PSID AccountSid, PLSA_UNICODE_STRING UserRights, ULONG CountOfRights );
62 #define MY_STATUS_NOT_IMPLEMENTED           ((NTSTATUS)0xC0000002L)
63 #endif
64 
65 struct CPolicy
66 {
67 protected:
68   LSA_HANDLE _handle;
69   #ifndef _UNICODE
70   HMODULE hModule;
71   #endif
72 public:
LSA_HANDLECPolicy73   operator LSA_HANDLE() const { return _handle; }
CPolicyCPolicy74   CPolicy(): _handle(NULL)
75   {
76     #ifndef _UNICODE
77     hModule = GetModuleHandle(TEXT("Advapi32.dll"));
78     #endif
79   };
~CPolicyCPolicy80   ~CPolicy() { Close(); }
81 
OpenCPolicy82   NTSTATUS Open(PLSA_UNICODE_STRING systemName, PLSA_OBJECT_ATTRIBUTES objectAttributes,
83       ACCESS_MASK desiredAccess)
84   {
85     #ifndef _UNICODE
86     if (hModule == NULL)
87       return MY_STATUS_NOT_IMPLEMENTED;
88     LsaOpenPolicyP lsaOpenPolicy = (LsaOpenPolicyP)GetProcAddress(hModule, "LsaOpenPolicy");
89     if (lsaOpenPolicy == NULL)
90       return MY_STATUS_NOT_IMPLEMENTED;
91     #endif
92 
93     Close();
94     return
95       #ifdef _UNICODE
96       ::LsaOpenPolicy
97       #else
98       lsaOpenPolicy
99       #endif
100       (systemName, objectAttributes, desiredAccess, &_handle);
101   }
102 
CloseCPolicy103   NTSTATUS Close()
104   {
105     if (_handle == NULL)
106       return 0;
107 
108     #ifndef _UNICODE
109     if (hModule == NULL)
110       return MY_STATUS_NOT_IMPLEMENTED;
111     LsaCloseP lsaClose = (LsaCloseP)GetProcAddress(hModule, "LsaClose");
112     if (lsaClose == NULL)
113       return MY_STATUS_NOT_IMPLEMENTED;
114     #endif
115 
116     NTSTATUS res =
117       #ifdef _UNICODE
118       ::LsaClose
119       #else
120       lsaClose
121       #endif
122       (_handle);
123     _handle = NULL;
124     return res;
125   }
126 
EnumerateAccountsWithUserRightCPolicy127   NTSTATUS EnumerateAccountsWithUserRight(PLSA_UNICODE_STRING userRights,
128       PLSA_ENUMERATION_INFORMATION *enumerationBuffer, PULONG countReturned)
129     { return LsaEnumerateAccountsWithUserRight(_handle, userRights, (void **)enumerationBuffer, countReturned); }
130 
EnumerateAccountRightsCPolicy131   NTSTATUS EnumerateAccountRights(PSID sid, PLSA_UNICODE_STRING* userRights, PULONG countOfRights)
132     { return ::LsaEnumerateAccountRights(_handle, sid, userRights, countOfRights); }
133 
LookupSidsCPolicy134   NTSTATUS LookupSids(ULONG count, PSID* sids,
135       PLSA_REFERENCED_DOMAIN_LIST* referencedDomains, PLSA_TRANSLATED_NAME* names)
136     { return LsaLookupSids(_handle, count, sids, referencedDomains, names); }
137 
AddAccountRightsCPolicy138   NTSTATUS AddAccountRights(PSID accountSid, PLSA_UNICODE_STRING userRights, ULONG countOfRights)
139   {
140     #ifndef _UNICODE
141     if (hModule == NULL)
142       return MY_STATUS_NOT_IMPLEMENTED;
143     LsaAddAccountRightsP lsaAddAccountRights = (LsaAddAccountRightsP)GetProcAddress(hModule, "LsaAddAccountRights");
144     if (lsaAddAccountRights == NULL)
145       return MY_STATUS_NOT_IMPLEMENTED;
146     #endif
147 
148     return
149       #ifdef _UNICODE
150       ::LsaAddAccountRights
151       #else
152       lsaAddAccountRights
153       #endif
154       (_handle, accountSid, userRights, countOfRights);
155   }
AddAccountRightsCPolicy156   NTSTATUS AddAccountRights(PSID accountSid, PLSA_UNICODE_STRING userRights)
157     { return AddAccountRights(accountSid, userRights, 1); }
158 
RemoveAccountRightsCPolicy159   NTSTATUS RemoveAccountRights(PSID accountSid, bool allRights, PLSA_UNICODE_STRING userRights, ULONG countOfRights)
160     { return LsaRemoveAccountRights(_handle, accountSid, (BOOLEAN)(allRights ? TRUE : FALSE), userRights, countOfRights); }
161 };
162 
163 bool AddLockMemoryPrivilege();
164 
165 }}
166 
167 #endif
168