|
|
/*
* Acl.c * * Author: BreenH * * Acl utilities. */
/*
* Includes */
#include "precomp.h"
#include "tsutil.h"
#include "tsutilnt.h"
/*
* Function Implementations */
BOOL WINAPI AddSidToObjectsSecurityDescriptor( HANDLE hObject, SE_OBJECT_TYPE ObjectType, PSID pSid, DWORD dwNewAccess, ACCESS_MODE AccessMode, DWORD dwInheritance ) { BOOL fRet; DWORD dwRet; EXPLICIT_ACCESS ExpAccess; PACL pNewDacl; PACL pOldDacl; PSECURITY_DESCRIPTOR pSd;
//
// Get the objects security descriptor and current Dacl.
//
pSd = NULL; pOldDacl = NULL;
dwRet = GetSecurityInfo( hObject, ObjectType, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldDacl, NULL, &pSd );
if (dwRet != ERROR_SUCCESS) { return(FALSE); }
//
// Initialize an EXPLICIT_ACCESS structure for the new ace.
//
ZeroMemory(&ExpAccess, sizeof(EXPLICIT_ACCESS)); ExpAccess.grfAccessPermissions = dwNewAccess; ExpAccess.grfAccessMode = AccessMode; ExpAccess.grfInheritance = dwInheritance; BuildTrusteeWithSid(&(ExpAccess.Trustee), pSid);
//
// Merge the new ace into the existing Dacl.
//
fRet = FALSE;
dwRet = SetEntriesInAcl( 1, &ExpAccess, pOldDacl, &pNewDacl );
if (dwRet == ERROR_SUCCESS) {
//
// Set the new security for the object.
//
dwRet = SetSecurityInfo( hObject, ObjectType, DACL_SECURITY_INFORMATION, NULL, NULL, pNewDacl, NULL );
if (dwRet == ERROR_SUCCESS) { fRet = TRUE; } }
if (pNewDacl != NULL) { LocalFree(pNewDacl); }
if (pSd != NULL) { LocalFree(pSd); }
return(fRet); }
BOOL WINAPI AddSidToSecurityDescriptor( PSECURITY_DESCRIPTOR *ppSd, PSID pSid, DWORD dwNewAccess, ACCESS_MODE AccessMode, DWORD dwInheritance ) { BOOL fAbsoluteSd; BOOL fDaclDefaulted; BOOL fDaclPresent; BOOL fRet; PACL pDacl; PSECURITY_DESCRIPTOR pAbsoluteSd; PSECURITY_DESCRIPTOR pOriginalSd;
ASSERT(ppSd != NULL); ASSERT(*ppSd != NULL);
//
// The security descriptors should be absolute to allow the addition of
// the new ace.
//
pOriginalSd = *ppSd;
fAbsoluteSd = IsSecurityDescriptorAbsolute(pOriginalSd);
if (!fAbsoluteSd) { fRet = ConvertSelfRelativeToAbsolute(&pAbsoluteSd, pOriginalSd);
if (!fRet) { return(FALSE); } } else { pAbsoluteSd = pOriginalSd; }
//
// Now that the type of security descriptor is absolute, get the Dacl.
//
pDacl = NULL;
fRet = GetSecurityDescriptorDacl( pAbsoluteSd, &fDaclPresent, &pDacl, &fDaclDefaulted );
if (fRet) { DWORD dwRet; EXPLICIT_ACCESS ExplicitAccess; PACL pNewDacl;
//
// Initialize an EXPLICIT_ACCESS structure for the new ace.
//
RtlZeroMemory(&ExplicitAccess, sizeof(EXPLICIT_ACCESS)); ExplicitAccess.grfAccessPermissions = dwNewAccess; ExplicitAccess.grfAccessMode = AccessMode; ExplicitAccess.grfInheritance = dwInheritance; BuildTrusteeWithSid(&(ExplicitAccess.Trustee), pSid);
//
// Merge the ace into the existing Dacl. This will allocate a new
// Dacl. Unfortunately this API is only available as a WINAPI.
//
pNewDacl = NULL;
dwRet = SetEntriesInAcl( 1, &ExplicitAccess, pDacl, &pNewDacl );
if (dwRet == ERROR_SUCCESS) { ASSERT(pNewDacl != NULL);
//
// Point the security descriptor's Dacl to the new Dacl.
//
fRet = SetSecurityDescriptorDacl( pAbsoluteSd, TRUE, pNewDacl, FALSE );
if (fRet) { PULONG_PTR pBeginning; PULONG_PTR pEnd; PULONG_PTR pPtr;
//
// The new Dacl has been set, free the old. Be careful here;
// the RTL folks like to put absolute security descriptors in
// one big allocation, just like a self-relative security
// descriptor. If the old Dacl is inside the security
// descriptor allocation, it cannot be freed. Essentially,
// that memory becomes unused, and the security descriptor
// takes up more space than necessary.
//
pBeginning = (PULONG_PTR)pAbsoluteSd; pEnd = (PULONG_PTR)((PBYTE)pAbsoluteSd + LocalSize(pAbsoluteSd)); pPtr = (PULONG_PTR)pDacl;
if ((pPtr < pBeginning) || (pPtr > pEnd)) { LocalFree(pDacl); } } else {
//
// A failure occurred setting the new Dacl. This should never
// occur, but if it does, free the newly created Dacl.
//
LocalFree(pNewDacl); } } else { fRet = FALSE; } }
//
// The new security descriptor should be returned in the same format as
// the original security descriptor. The returned security descriptor is
// also dependent on the success of the function.
//
if (!fAbsoluteSd) { if (fRet) { PSECURITY_DESCRIPTOR pNewSd;
//
// The original security descriptor was self-relative, and until
// now everything has succeeded. Convert the temporary absolute
// security descriptor back to self-relative form. This creates a
// third security descriptor (the other two being the original
// and the absolute).
//
pNewSd = NULL;
fRet = ConvertAbsoluteToSelfRelative( &pNewSd, pAbsoluteSd, NULL );
if (fRet) {
//
// The final conversion was successful. Free the original
// security descriptor. The absolute security descriptor is
// freed later. The only possible error from destroying the
// security descriptor is a version mismatch, but that would
// have happened long ago.
//
*ppSd = pNewSd;
(VOID)DestroySecurityDescriptor(&pOriginalSd); } else {
//
// The final conversion failed. At this point, the original
// security descriptor is still intact. Free the absolute
// security descriptor that was created earlier, and leave
// the passed in security descriptor pointer alone. Note that
// with the absolute security descriptor being freed later,
// there is nothing to do here.
//
} }
//
// Regardless of success or failure, the absolute security descriptor
// was created, so it must be freed. The only possible error from destroying the
// security descriptor is a version mismatch, but that would
// have happened long ago.
//
(VOID)DestroySecurityDescriptor(&pAbsoluteSd);
} else {
//
// Regardless of what happened, there is nothing to do here. The
// original security descriptor was absolute; therefore no copies
// were made. The only data that changed was the Dacl, and whether
// or not that succeeded is irrelevant, as that was handled above.
//
}
return(fRet); }
BOOL WINAPI ConvertAbsoluteToSelfRelative( PSECURITY_DESCRIPTOR *ppSelfRelativeSd, PSECURITY_DESCRIPTOR pAbsoluteSd, PDWORD pcbSelfRelativeSd ) { BOOL fRet; NTSTATUS Status;
Status = NtConvertAbsoluteToSelfRelative( ppSelfRelativeSd, pAbsoluteSd, pcbSelfRelativeSd );
if (NT_SUCCESS(Status)) { fRet = TRUE; } else { fRet = FALSE; SetLastError(RtlNtStatusToDosError(Status)); }
return(fRet); }
BOOL WINAPI ConvertSelfRelativeToAbsolute( PSECURITY_DESCRIPTOR *ppAbsoluteSd, PSECURITY_DESCRIPTOR pSelfRelativeSd ) { BOOL fRet; NTSTATUS Status;
Status = NtConvertSelfRelativeToAbsolute(ppAbsoluteSd, pSelfRelativeSd);
if (NT_SUCCESS(Status)) { fRet = TRUE; } else { fRet = FALSE; SetLastError(RtlNtStatusToDosError(Status)); }
return(fRet); }
BOOL WINAPI DestroySecurityDescriptor( PSECURITY_DESCRIPTOR *ppSd ) { BOOL fRet; NTSTATUS Status;
Status = NtDestroySecurityDescriptor(ppSd);
if (NT_SUCCESS(Status)) { fRet = TRUE; } else { fRet = FALSE; SetLastError(RtlNtStatusToDosError(Status)); }
return(fRet); }
BOOL WINAPI IsSecurityDescriptorAbsolute( PSECURITY_DESCRIPTOR pSd ) { BOOLEAN fAbsolute; BOOL fRet; NTSTATUS Status;
fAbsolute = FALSE;
Status = NtIsSecurityDescriptorAbsolute(pSd, &fAbsolute);
fRet = ((NT_SUCCESS(Status)) && fAbsolute);
return(fRet); }
|