#include "master.h"
#include <aclapi.h>
#include <stdlib.h>
#include "utility.h"
#include "accessfunc.h"
PACL GetAcl(REQUEST* rq)
{
PACL lpAcl = NULL;
if(rq->ko == NULL)
{
if(GetNamedSecurityInfo(rq->szPath, rq->iType, DACL_SECURITY_INFORMATION, NULL, NULL, &lpAcl, NULL, NULL) == ERROR_SUCCESS)
{
_tprintf(TEXT("Retrieved DACL\n"));
}
else ConErrorInfo(__FUNCTION__);
}
else
{
DWORD dwBytesRequired = 0;
GetKernelObjectSecurity(rq->ko->hHandle, DACL_SECURITY_INFORMATION, NULL, 0, &dwBytesRequired);
rq->ko->lpsd = malloc(dwBytesRequired);
memset(rq->ko->lpsd, 0, dwBytesRequired);
if(GetKernelObjectSecurity(rq->ko->hHandle, DACL_SECURITY_INFORMATION, rq->ko->lpsd, dwBytesRequired, &dwBytesRequired) != 0)
{
BOOL bDacl = FALSE, bDefaulted = FALSE;
GetSecurityDescriptorDacl(rq->ko->lpsd, &bDacl, &lpAcl, &bDefaulted);
_tprintf(TEXT("\nRetrieved DACL\n"));
}
else
{
free(rq->ko->lpsd);
ConErrorInfo(__FUNCTION__);
}
}
return lpAcl;
}
/* We return a flag here, so we can reset the DACL to it's original state
* in case our failed attempt has corrupted or otherwise invalidated the DACL */
BOOL SetNewAcl(REQUEST* rq, PACL lpNewAcl)
{
if(rq->ko == NULL) /* Get/SetNamedSecurityInfo doesn't work for Kernel Objects*/
{
if(SetNamedSecurityInfo(rq->szPath, rq->iType, DACL_SECURITY_INFORMATION, NULL, NULL, lpNewAcl, NULL) == ERROR_SUCCESS)
{
_tprintf(TEXT("New DACL set successfully\n"));
return FALSE;
}
else
{
ConErrorInfo(__FUNCTION__);
return TRUE;
}
}
else
{
if(SetKernelObjectSecurity(rq->ko->hHandle, DACL_SECURITY_INFORMATION, rq->ko->lpsd) != 0)
{
_tprintf(TEXT("New DACL set successfully\n"));
return FALSE;
}
else
{
ConErrorInfo(__FUNCTION__);
return TRUE;
}
}
}
void AddAceToAcl(REQUEST* rq)
{
PACL pExistingAcl = NULL, pNewAcl = NULL;
PSID pSid = NULL;
SID_NAME_USE snu = 0;
pExistingAcl = GetAcl(rq);
if(rq->bDenied != -1) /* If the "clear" option wasn't specified on the commandline, make a new ACL */
{
snu = GetSID(rq->szAccountName, &pSid);
pNewAcl = MakeNewAcl(rq, pSid, pExistingAcl, snu);
}
if(pNewAcl != NULL || rq->bDenied == -1)
{
if(rq->ko != NULL)
{
/* SetSecurityDescriptorDacl requires an absolute SD but GetKernelObjectSecurity
* returns a self-relative one so we must convert between the two */
PSECURITY_DESCRIPTOR pSecDesc = GetAbsoluteSDFromRelative(rq->ko->lpsd);
if(SetSecurityDescriptorDacl(pSecDesc, TRUE, pNewAcl, FALSE) == FALSE)
{
ConErrorInfo(__FUNCTION__);
}
else
{
if(SetNewAcl(rq, pNewAcl) == TRUE)
{
_tprintf(TEXT("\nFailed to set new DACL, restoring the previous one\n"));
SetNewAcl(rq, pExistingAcl);
}
}
free(pSecDesc);
free(rq->ko->lpsd);
free(rq->ko);
}
else
{
if(SetNewAcl(rq, pNewAcl) == TRUE)
{
SetNewAcl(rq, pExistingAcl); /* Reset the previous ACL if we fail */
}
}
}
free(pSid);
if(pNewAcl != NULL)
{
LocalFree(pNewAcl);
}
return;
}
PACL MakeNewAcl(REQUEST* rq, PSID pSid, PACL lpOldAcl, SID_NAME_USE snu)
{
ULONG ulEntries = 1;
EXPLICIT_ACCESS ea = {0};
PACL lpNewAcl = NULL;
ea.grfAccessPermissions = rq->amPermissions;
if(rq->bDenied == TRUE)
{
ea.grfAccessMode = DENY_ACCESS;
}
else ea.grfAccessMode = GRANT_ACCESS;
ea.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
ea.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
ea.Trustee.pMultipleTrustee = NULL;
ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea.Trustee.TrusteeType = snu;
ea.Trustee.ptstrName = (LPTSTR)pSid;
if(SetEntriesInAcl(ulEntries, &ea, lpOldAcl, &lpNewAcl) == ERROR_SUCCESS)
{
_tprintf(TEXT("Created New DACL\n"));
}
else ConErrorInfo(__FUNCTION__);
return lpNewAcl;
}