23 #include "../../../core/exception.hpp"
24 #include "../../../core/trace.hpp"
28 using namespace libjmmcg;
29 using namespace NTUtils;
39 const TCHAR LookupAccountName_name[]=_T(
"LookupAccountNameW");
41 const TCHAR LookupAccountName_name[]=
_T(
"LookupAccountNameA");
43 const TCHAR InitializeAcl_name[]=
_T(
"InitializeAcl");
44 const TCHAR AddAccessAllowedAce_name[]=
_T(
"AddAccessAllowedAce");
45 const TCHAR InitializeSecurityDescriptor_name[]=
_T(
"InitializeSecurityDescriptor");
46 const TCHAR SetSecurityDescriptorDacl_name[]=
_T(
"SetSecurityDescriptorDacl");
47 const TCHAR GetLengthSid_name[]=
_T(
"GetLengthSid");
49 const TCHAR IsValidSid_name[]=_T(
"IsValidSid");
50 const TCHAR IsValidAcl_name[]=_T(
"IsValidAcl");
51 const TCHAR IsValidSecurityDescriptor_name[]=_T(
"IsValidSecurityDescriptor");
57 ACL_wrapper::ACL_wrapper(
void)
58 : LoadLibraryWrapper(scm_lib_name),
59 pInitializeAcl(
reinterpret_cast<InitializeAclType>(::GetProcAddress(Handle(),InitializeAcl_name))),
60 pAddAccessAllowedAce(
reinterpret_cast<AddAccessAllowedAceType>(::GetProcAddress(Handle(),AddAccessAllowedAce_name))),
62 pIsValidAcl(
reinterpret_cast<IsValidAclType>(::GetProcAddress(Handle(),IsValidAcl_name))),
68 ACL_wrapper::ACL_wrapper(
const unsigned long acl_size)
69 : LoadLibraryWrapper(scm_lib_name),
70 pInitializeAcl(
reinterpret_cast<InitializeAclType>(::GetProcAddress(Handle(),InitializeAcl_name))),
71 pAddAccessAllowedAce(
reinterpret_cast<AddAccessAllowedAceType>(::GetProcAddress(Handle(),AddAccessAllowedAce_name))),
73 pIsValidAcl(
reinterpret_cast<IsValidAclType>(::GetProcAddress(Handle(),IsValidAcl_name))),
76 buff(
new BYTE[acl_size]) {
80 ACL_wrapper::ACL_wrapper(ACL_wrapper &sw)
81 : LoadLibraryWrapper(scm_lib_name),
82 pInitializeAcl(
reinterpret_cast<InitializeAclType>(::GetProcAddress(Handle(),InitializeAcl_name))),
83 pAddAccessAllowedAce(
reinterpret_cast<AddAccessAllowedAceType>(::GetProcAddress(Handle(),AddAccessAllowedAce_name))),
85 pIsValidAcl(
reinterpret_cast<IsValidAclType>(::GetProcAddress(Handle(),IsValidAcl_name))),
92 ACL_wrapper::~ACL_wrapper(
void) {
96 ACL_wrapper::operator=(ACL_wrapper &aw) {
103 ACL_wrapper::copy(
const ACL_wrapper &aw) {
104 ::memcpy(buff.get(),aw.buff.get(),(size_<aw.size_) ? size_ : aw.size_);
108 ACL_wrapper::initialize(
void) {
109 const bool ret=!(*pInitializeAcl)(
reinterpret_cast<ACL*>(buff.get()),size_,ACL_REVISION);
110 assert((*pIsValidAcl)(
reinterpret_cast<ACL *>(buff.get())));
115 ACL_wrapper::add_ACE(
const DWORD access_mask,SID *sid) {
116 const bool ret=(*pAddAccessAllowedAce)(
reinterpret_cast<ACL *>(buff.get()),ACL_REVISION,access_mask,sid);
117 assert((*pIsValidAcl)(
reinterpret_cast<ACL *>(buff.get())));
122 ACL_wrapper::size(
void)
const {
127 ACL_wrapper::get(
void)
const {
128 return reinterpret_cast<
const ACL *>(buff.get());
132 ACL_wrapper::get(
void) {
133 return reinterpret_cast<ACL *>(buff.get());
136 SecurityDescriptor::SecurityDescriptor(
void) :
137 LoadLibraryWrapper(scm_lib_name),
138 pLookupAccountName(
reinterpret_cast<LookupAccountNameType>(::GetProcAddress(Handle(),LookupAccountName_name))),
139 pInitializeSecurityDescriptor(
reinterpret_cast<InitializeSecurityDescriptorType>(::GetProcAddress(Handle(),InitializeSecurityDescriptor_name))),
140 pSetSecurityDescriptorDacl(
reinterpret_cast<SetSecurityDescriptorDaclType>(::GetProcAddress(Handle(),SetSecurityDescriptorDacl_name))),
141 pGetLengthSid(
reinterpret_cast<GetLengthSidType>(::GetProcAddress(Handle(),GetLengthSid_name)))
144 pIsValidSid(
reinterpret_cast<IsValidSidType>(::GetProcAddress(Handle(),IsValidSid_name))),
145 pIsValidSecurityDescriptor(
reinterpret_cast<IsValidSecurityDescriptorType>(::GetProcAddress(Handle(),IsValidSecurityDescriptor_name)))
148 if (!(*pInitializeSecurityDescriptor)(&sd, SECURITY_DESCRIPTOR_REVISION)) {
149 throw exception_type(
_T(
"Failed to initialise security descriptor."),info::function(__LINE__,
__PRETTY_FUNCTION__,
typeid(*
this),info::function::argument(
_T(
""),
_T(
""))),__REV_INFO__);
154 SecurityDescriptor::~SecurityDescriptor(
void) {
155 for (std::vector<SID *>::iterator iter(sids.begin());iter!=sids.end();++iter) {
157 delete[]
reinterpret_cast<BYTE *>(*iter);
159 catch (
const std::exception &err) {
160 JMMCG_TRACE(_T(
"SecurityDescriptor::~SecurityDescriptor(): Exception '")<<err.what()<<_T(
"' thrown when trying to delete a SID, attempting to just leak the memory."));
167 SecurityDescriptor::Allow(
const TCHAR *
const machine,
const TCHAR *
const username,
const DWORD access_mask) {
169 const unsigned int SID_SIZE=96;
170 DWORD cbSid = SID_SIZE;
171 SID *sid=
reinterpret_cast<SID *>(
new BYTE[cbSid]);
173 JMMCG_TRACE(_T(
"SecurityDescriptor::Allow(...): SID new error!"));
176 TCHAR RefDomain[DNLEN + 1];
177 DWORD cchDomain = DNLEN + 1;
180 if (!(*pLookupAccountName)(
190 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
191 delete[]
reinterpret_cast<BYTE *>(sid);
192 sid=
reinterpret_cast<SID *>(
new BYTE[cbSid]);
194 cchDomain = DNLEN + 1;
195 if (!(*pLookupAccountName)(
204 const unsigned long err=GetLastError();
205 JMMCG_TRACE(_T(
"SecurityDescriptor::Allow(...): LookupAccountName(...) error! ")<<NTUtils::win_exception::StrFromWinErr(err));
206 delete[]
reinterpret_cast<BYTE *>(sid);
210 const unsigned long err=GetLastError();
211 JMMCG_TRACE(_T(
"SecurityDescriptor::Allow(...): SID new error!"));
212 delete[]
reinterpret_cast<BYTE *>(sid);
213 return err ? err : S_FALSE;
216 const unsigned long err=GetLastError();
217 JMMCG_TRACE(_T(
"SecurityDescriptor::Allow(...): LookupAccountName(...) error! ")<<NTUtils::win_exception::StrFromWinErr(err));
218 delete[]
reinterpret_cast<BYTE *>(sid);
222 assert((*pIsValidSid)(sid));
224 unsigned long orig_dwAclSize=
sizeof(ACL);
225 for (std::vector<SID *>::const_iterator iter(sids.begin());iter!=sids.end();++iter) {
226 orig_dwAclSize+=
sizeof(ACCESS_ALLOWED_ACE)-
sizeof(DWORD)+((*pGetLengthSid)(*iter)<<1);
229 const ACL_wrapper orig_acl(acl);
230 ACL_wrapper acl_wrap(orig_dwAclSize+
sizeof(ACCESS_ALLOWED_ACE)-
sizeof(DWORD)+((*pGetLengthSid)(sid)<<1));
233 if (acl.initialize()) {
234 const unsigned long err=GetLastError();
235 JMMCG_TRACE(_T(
"SecurityDescriptor::Allow(...): InitializeAcl(...) error! ")<<NTUtils::win_exception::StrFromWinErr(err));
236 delete[]
reinterpret_cast<BYTE *>(sid);
243 if (acl.add_ACE(access_mask,sid)) {
244 if ((*pSetSecurityDescriptorDacl)(&sd,
true,acl.get(),
false)) {
245 assert((*pIsValidSecurityDescriptor)(&sd));
246 JMMCG_TRACE(_T(
"SecurityDescriptor::Allow(...): Successfully added access allowed ACL to security descriptor for user '")<<username<<_T(
"' on machine '")<<(machine ? machine : _T(
"''"))<<_T(
"' with access mask: 0x")<<std::hex<<access_mask);
252 delete[]
reinterpret_cast<BYTE *>(sid);
253 const unsigned long err=GetLastError();
254 return err ? err : S_FALSE;