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
10namespace NWindows {
11namespace NSecurity {
12
13class CAccessToken
14{
15  HANDLE _handle;
16public:
17  CAccessToken(): _handle(NULL) {};
18  ~CAccessToken() { 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
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
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
48  bool AdjustPrivileges(bool disableAllPrivileges, PTOKEN_PRIVILEGES newState)
49    { return AdjustPrivileges(disableAllPrivileges, newState, 0, NULL, NULL); }
50
51  bool AdjustPrivileges(PTOKEN_PRIVILEGES newState)
52    { return AdjustPrivileges(false, newState); }
53
54};
55
56#ifndef _UNICODE
57typedef NTSTATUS (NTAPI *LsaOpenPolicyP)(PLSA_UNICODE_STRING SystemName,
58    PLSA_OBJECT_ATTRIBUTES ObjectAttributes, ACCESS_MASK DesiredAccess, PLSA_HANDLE PolicyHandle);
59typedef NTSTATUS (NTAPI *LsaCloseP)(LSA_HANDLE ObjectHandle);
60typedef 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
65struct CPolicy
66{
67protected:
68  LSA_HANDLE _handle;
69  #ifndef _UNICODE
70  HMODULE hModule;
71  #endif
72public:
73  operator LSA_HANDLE() const { return _handle; }
74  CPolicy(): _handle(NULL)
75  {
76    #ifndef _UNICODE
77    hModule = GetModuleHandle(TEXT("Advapi32.dll"));
78    #endif
79  };
80  ~CPolicy() { Close(); }
81
82  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
103  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
127  NTSTATUS EnumerateAccountsWithUserRight(PLSA_UNICODE_STRING userRights,
128      PLSA_ENUMERATION_INFORMATION *enumerationBuffer, PULONG countReturned)
129    { return LsaEnumerateAccountsWithUserRight(_handle, userRights, (void **)enumerationBuffer, countReturned); }
130
131  NTSTATUS EnumerateAccountRights(PSID sid, PLSA_UNICODE_STRING* userRights, PULONG countOfRights)
132    { return ::LsaEnumerateAccountRights(_handle, sid, userRights, countOfRights); }
133
134  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
138  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  }
156  NTSTATUS AddAccountRights(PSID accountSid, PLSA_UNICODE_STRING userRights)
157    { return AddAccountRights(accountSid, userRights, 1); }
158
159  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
163bool AddLockMemoryPrivilege();
164
165}}
166
167#endif
168