I am merging the changes made by Cody Cutrer into Wix 3.0.4610, and I
noticed that the code for SchedSecureObjects has been cleaned up
considerably.
I have a couple of comments / questions:
* Shouldn't there be a check on the return value of GetTargetPath on
line 383?
* Do you see any problems with only storing rollback information once
per table / path pair?
In Cody's code, the rollback information is only stored once per object
(table and path); I have altered the code in SchedSecureObjectsRollback
to reflect this behavior.
Attached is a unified diff of the changes to secureobj.cpp. It includes
a check of the HRESULT from GetTargetPath.
Thanks,
--
Thomas S. Trias
Senior Developer
Artizan Internet Services
http://www.artizan.com/
--- src\ca\wixca\dll\secureobj.cpp 2008-10-21 10:50:42.000000000 -0700
+++ src\ca\wixca\dll\secureobj.cpp 2008-10-22 09:16:06.000000000 -0700
@@ -17,15 +17,16 @@
//-------------------------------------------------------------------------------------------------
#include "precomp.h"
// structs
LPCWSTR wzQUERY_SECUREOBJECTS = L"SELECT `SecureObjects`.`SecureObject`,
`SecureObjects`.`Table`, `SecureObjects`.`Domain`, `SecureObjects`.`User`, "
- L"`SecureObjects`.`Permission`,
`SecureObjects`.`Component_`, `Component`.`Attributes` FROM
`SecureObjects`,`Component` WHERE "
-
L"`SecureObjects`.`Component_`=`Component`.`Component`";
-enum eQUERY_SECUREOBJECTS { QSO_SECUREOBJECT = 1, QSO_TABLE, QSO_DOMAIN,
QSO_USER, QSO_PERMISSION, QSO_COMPONENT, QSO_COMPATTRIBUTES };
+ L"`SecureObjects`.`Permission`,
`SecureObjects`.`Component_`, `SecureObjects`.`Type`, `SecureObjects`.`Flags`,
`Component`.`Attributes` "
+ L"FROM `SecureObjects`,`Component` WHERE
`SecureObjects`.`Component_`=`Component`.`Component` "
+ L"ORDER BY `SecureObjects`.`Table`,
`SecureObjects`.`SecureObject`, `SecureObjects`.`Type`";
+enum eQUERY_SECUREOBJECTS { QSO_SECUREOBJECT = 1, QSO_TABLE, QSO_DOMAIN,
QSO_USER, QSO_PERMISSION, QSO_COMPONENT, QSO_TYPE, QSO_FLAGS,
QSO_COMPATTRIBUTES };
LPCWSTR wzQUERY_REGISTRY = L"SELECT `Registry`.`Registry`, `Registry`.`Root`,
`Registry`.`Key` FROM `Registry` WHERE `Registry`.`Registry`=?";
enum eQUERY_OBJECTCOMPONENT { QSOC_REGISTRY = 1, QSOC_REGROOT, QSOC_REGKEY};
enum eOBJECTTYPE { OT_UNKNOWN, OT_SERVICE, OT_FOLDER, OT_FILE, OT_REGISTRY };
@@ -104,13 +105,13 @@
Assert(pwzObject && pwzTable);
SE_OBJECT_TYPE objectType = SEObjectTypeFromString(const_cast<LPCWSTR>
(pwzTable));
if (SE_UNKNOWN_OBJECT_TYPE != objectType)
{
- er = ::GetNamedSecurityInfoW(pwzObject, objectType,
DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &psd);
+ er = ::GetNamedSecurityInfoW(pwzObject, objectType,
DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL,
&psd);
if (ERROR_FILE_NOT_FOUND == er || ERROR_PATH_NOT_FOUND == er ||
ERROR_SERVICE_DOES_NOT_EXIST == HRESULT_CODE(er))
{
// If the file, path or service doesn't exist yet, skip rollback
without a message
hr = HRESULT_FROM_WIN32(er);
ExitFunction();
}
@@ -121,13 +122,13 @@
if(!::GetSecurityDescriptorControl(psd, &sdc, &dwRevision))
{
ExitOnLastError1(hr, "Unable to schedule rollback for object
(failed to get security descriptor control): %S", pwzObject);
}
// Convert the security information to a string, and write this to the
custom action data
- if
(!::ConvertSecurityDescriptorToStringSecurityDescriptorW(psd,SDDL_REVISION_1,DACL_SECURITY_INFORMATION,&pwzSecurityInfo,NULL))
+ if
(!::ConvertSecurityDescriptorToStringSecurityDescriptorW(psd,SDDL_REVISION_1,DACL_SECURITY_INFORMATION
| SACL_SECURITY_INFORMATION,&pwzSecurityInfo,NULL))
{
hr = E_UNEXPECTED;
ExitOnFailure1(hr, "Unable to schedule rollback for object (failed
to convert security descriptor to a valid security descriptor string): %S",
pwzObject);
}
hr = WcaWriteStringToCaData(pwzObject, &pwzCustomActionData);
@@ -138,12 +139,24 @@
hr = WcaWriteStringToCaData(pwzSecurityInfo,&pwzCustomActionData);
ExitOnFailure(hr, "failed to add data to rollback CustomActionData");
// Write a 1 if DACL is protected, 0 otherwise
if (sdc & SE_DACL_PROTECTED)
+ {
+ hr = WcaWriteIntegerToCaData(1,&pwzCustomActionData);
+ ExitOnFailure(hr, "failed to add data to
rollbackCustomActionData");
+ }
+ else
+ {
+ hr = WcaWriteIntegerToCaData(0,&pwzCustomActionData);
+ ExitOnFailure(hr, "failed to add data to rollback
CustomActionData");
+ }
+
+ // Write a 1 if SACL is protected, 0 otherwise
+ if (sdc & SE_SACL_PROTECTED)
{
hr = WcaWriteIntegerToCaData(1,&pwzCustomActionData);
ExitOnFailure(hr, "failed to add data to
rollbackCustomActionData");
}
else
{
@@ -377,13 +390,14 @@
#endif
// Get the object to secure
hr = WcaGetRecordString(hRec, QSO_SECUREOBJECT, &pwzSecureObject);
ExitOnFailure(hr, "failed to get name of object");
- GetTargetPath(eType, pwzSecureObject, &pwzTargetPath);
+ hr = GetTargetPath(eType, pwzSecureObject, &pwzTargetPath);
+ ExitOnFailure(hr, "failed to get Target path for secure object");
hr = WcaGetRecordString(hRec, QSO_COMPONENT, &pwzData);
ExitOnFailure(hr, "failed to get Component name for secure object");
//
// if we are installing this Component
@@ -412,12 +426,22 @@
ExitOnFailure(hr, "failed to get user to configure object");
hr = WcaWriteStringToCaData(pwzData, &pwzCustomActionData);
ExitOnFailure(hr, "failed to add data to CustomActionData");
hr = WcaGetRecordString(hRec, QSO_PERMISSION, &pwzData);
ExitOnFailure(hr, "failed to get permission to configure object");
+ hr = WcaWriteStringToCaData(pwzData, &pwzCustomActionData);
+ ExitOnFailure(hr, "failed to add data to CustomActionData");
+
+ hr = WcaGetRecordString(hRec, QSO_TYPE, &pwzData);
+ ExitOnFailure(hr, "failed to get ACE type to configure object");
+ hr = WcaWriteStringToCaData(pwzData, &pwzCustomActionData);
+ ExitOnFailure(hr, "failed to add data to CustomActionData");
+
+ hr = WcaGetRecordString(hRec, QSO_FLAGS, &pwzData);
+ ExitOnFailure(hr, "failed to get flags to configure object");
hr = WcaWriteStringToCaData(pwzData, &pwzCustomActionData);
ExitOnFailure(hr, "failed to add data to CustomActionData");
cObjects++;
}
}
@@ -470,12 +494,15 @@
UINT er = ERROR_SUCCESS;
LPWSTR pwzSecureObject = NULL;
LPWSTR pwzTable = NULL;
LPWSTR pwzTargetPath = NULL;
+ LPWSTR pwzPreviousTable = NULL;
+ LPWSTR pwzPreviousTargetPath = NULL;
+
PMSIHANDLE hView = NULL;
PMSIHANDLE hRec = NULL;
LPWSTR pwzCustomActionData = NULL;
eOBJECTTYPE eType = OT_UNKNOWN;
@@ -526,25 +553,39 @@
hr = WcaGetRecordString(hRec, QSO_SECUREOBJECT, &pwzSecureObject);
ExitOnFailure(hr, "failed to get name of object");
hr = GetTargetPath(eType, pwzSecureObject, &pwzTargetPath);
ExitOnFailure1(hr, "failed to get target path of object '%S' in order
to schedule rollback - ignoring", pwzSecureObject);
- StoreACLRollbackInfo(pwzTargetPath, pwzTable);
+ // Only store rollback information once for each object
+ if (NULL == pwzPreviousTargetPath ||
+ 0 != lstrcmpW(pwzTargetPath, pwzPreviousTargetPath) ||
+ 0 != lstrcmpW(pwzTable, pwzPreviousTable)) {
+ StoreACLRollbackInfo(pwzTargetPath, pwzTable);
+ ReleaseStr(pwzPreviousTargetPath);
+ ReleaseStr(pwzPreviousTable);
+ pwzPreviousTargetPath = pwzTargetPath;
+ pwzPreviousTable = pwzTable;
+ pwzTargetPath = NULL;
+ pwzTable = NULL;
+ }
}
// if we looped through all records all is well
if (E_NOMOREITEMS == hr)
hr = S_OK;
ExitOnFailure(hr, "failed while looping through all objects to schedule
rollback for");
LExit:
ReleaseStr(pwzCustomActionData);
ReleaseStr(pwzSecureObject);
ReleaseStr(pwzTable);
ReleaseStr(pwzTargetPath);
+
+ ReleaseStr(pwzPreviousTable);
+ ReleaseStr(pwzPreviousTargetPath);
if (FAILED(hr))
er = ERROR_INSTALL_FAILURE;
return WcaFinalize(er);
}
@@ -563,27 +604,36 @@
HRESULT hr = S_OK;
DWORD er = ERROR_SUCCESS;
LPWSTR pwz = NULL;
LPWSTR pwzData = NULL;
LPWSTR pwzObject = NULL;
+ LPWSTR pwzPreviousObject = NULL;
LPWSTR pwzTable = NULL;
+ LPWSTR pwzPreviousTable = NULL;
LPWSTR pwzDomain = NULL;
DWORD dwRevision = 0;
LPWSTR pwzUser = NULL;
DWORD dwPermissions = 0;
+ DWORD dwFlags = 0;
+ DWORD dwType = 0;
LPWSTR pwzAccount = NULL;
PSID psid = NULL;
EXPLICIT_ACCESSW ea = {0};
SE_OBJECT_TYPE objectType = SE_UNKNOWN_OBJECT_TYPE;
PSECURITY_DESCRIPTOR psd = NULL;
SECURITY_DESCRIPTOR_CONTROL sdc = {0};
SECURITY_INFORMATION si = {0};
- PACL pAclExisting = NULL; // doesn't get freed
- PACL pAclNew = NULL;
+ PACL pDaclExisting = NULL; // doesn't get freed
+ PACL pDaclNew = NULL;
+ PACL pSaclExisting = NULL; // doesn't get freed
+ PACL pSaclNew = NULL;
+ PACL pAclExisting = NULL; // doesn't get freed
+ PACL *pAclNew = NULL; // doesn't get freed
+ PACL pAclTemp = NULL; // doesn't get freed
PMSIHANDLE hActionRec = ::MsiCreateRecord(1);
//
// initialize
//
@@ -609,19 +659,93 @@
ExitOnFailure(hr, "failed to process CustomActionData");
hr = WcaReadStringFromCaData(&pwz, &pwzDomain);
ExitOnFailure(hr, "failed to process CustomActionData");
hr = WcaReadStringFromCaData(&pwz, &pwzUser);
ExitOnFailure(hr, "failed to process CustomActionData");
hr = WcaReadIntegerFromCaData(&pwz,
reinterpret_cast<int*>(&dwPermissions));
- ExitOnFailure(hr, "failed to processCustomActionData");
+ ExitOnFailure(hr, "failed to process CustomActionData");
+ hr = WcaReadIntegerFromCaData(&pwz, reinterpret_cast<int*>(&dwType));
+ ExitOnFailure(hr, "failed to process CustomActionData");
+ hr = WcaReadIntegerFromCaData(&pwz, reinterpret_cast<int*>(&dwFlags));
+ ExitOnFailure(hr, "failed to process CustomActionData");
WcaLog(LOGMSG_VERBOSE, "Securing Object: %S Type: %S User: %S",
pwzObject, pwzTable, pwzUser);
+ if (NULL == pwzPreviousObject ||
+ 0 != lstrcmpW(pwzPreviousObject, pwzObject) ||
+ 0 != lstrcmpW(pwzPreviousTable, pwzTable))
+ {
+ if (NULL != pwzPreviousObject)
+ {
+ // commit the ACLs
+ if (!pDaclNew)
+ {
+ si &= ~(DACL_SECURITY_INFORMATION |
PROTECTED_DACL_SECURITY_INFORMATION);
+ }
+ if (!pSaclNew)
+ {
+ si &= ~(SACL_SECURITY_INFORMATION |
PROTECTED_SACL_SECURITY_INFORMATION);
+ }
+ er = ::SetNamedSecurityInfoW(pwzPreviousObject, objectType,
si, NULL, NULL, pDaclNew, pSaclNew);
+ MessageExitOnFailure1(hr = HRESULT_FROM_WIN32(er),
msierrSecureObjectsFailedSet, "failed to set security info for object: %S",
pwzPreviousObject);
+ if (pDaclNew)
+ ::LocalFree(pDaclNew);
+ if (pSaclNew)
+ ::LocalFree(pSaclNew);
+ if (psd)
+ ::LocalFree(psd);
+ pDaclNew = NULL;
+ pSaclNew = NULL;
+ psd = NULL;
+ objectType = SE_UNKNOWN_OBJECT_TYPE;
+ }
+
+ objectType = SEObjectTypeFromString(const_cast<LPCWSTR>
(pwzTable));
+ if (SE_UNKNOWN_OBJECT_TYPE != objectType)
+ {
+ er = ::GetNamedSecurityInfoW(pwzObject, objectType,
DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION, NULL, NULL,
&pDaclExisting, &pSaclExisting, &psd);
+ ExitOnFailure1(hr = HRESULT_FROM_WIN32(er), "failed to get
security info for object: %S", pwzObject);
+
+ // Need to see if ACL is protected so getting Descriptor
information
+ if(!::GetSecurityDescriptorControl(psd, &sdc, &dwRevision))
+ {
+ ExitOnLastError1(hr, "failed to get security descriptor
control for object: %S", pwzObject);
+ }
+
+ si = DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
+ if ((sdc & SE_DACL_PROTECTED) || (dwFlags &
SOF_PROTECTED_DACL)) {
+ si |= PROTECTED_DACL_SECURITY_INFORMATION;
+ }
+ if ((sdc & SE_SACL_PROTECTED) || (dwFlags &
SOF_PROTECTED_SACL)) {
+ si |= PROTECTED_SACL_SECURITY_INFORMATION;
+ }
+
+ if (dwFlags & SOF_PROTECTED_DACL) {
+ pDaclExisting = NULL;
+ }
+ if (dwFlags & SOF_PROTECTED_SACL) {
+ pSaclExisting = NULL;
+ }
+ }
+ else
+ {
+ MessageExitOnFailure1(hr = E_UNEXPECTED,
msierrSecureObjectsUnknownType, "unknown object type: %S", pwzTable);
+ }
+
+ hr = StrAllocString(&pwzPreviousObject, pwzObject, 0);
+ ExitOnFailure1(hr, "failed to allocate string to store previous
object: %S", pwzObject);
+ hr = StrAllocString(&pwzPreviousTable, pwzTable, 0);
+ ExitOnFailure1(hr, "failed to allocate string to store previous
table: %S", pwzTable);
+ }
+
//
// create the appropriate SID
//
+ if (psid)
+ AclFreeSid(psid);
+ psid = NULL;
// figure out the right user to put into the access block
if (!*pwzDomain && 0 == lstrcmpW(pwzUser, L"Everyone"))
{
hr = AclGetWellKnownSid(WinWorldSid, &psid);
}
@@ -658,100 +782,130 @@
hr = AclGetWellKnownSid(WinInteractiveSid, &psid);
}
else if(!*pwzDomain && 0 == lstrcmpW(pwzUser, L"Users"))
{
hr = AclGetWellKnownSid(WinBuiltinUsersSid, &psid);
}
+ else if(!*pwzDomain && (hr = AclGetSidFromString(pwzUser, &psid)) ==
S_OK)
+ {
+ // hr is already S_OK
+ }
else
{
hr = StrAllocFormatted(&pwzAccount, L"%s\\%s", *pwzDomain ?
pwzDomain : L".", pwzUser);
ExitOnFailure(hr, "failed to build domain user name");
hr = AclGetAccountSid(NULL, pwzAccount, &psid);
}
ExitOnFailure3(hr, "failed to get sid for account: %S%S%S", pwzDomain,
*pwzDomain ? L"\\" : L"", pwzUser);
//
// build up the explicit access
//
- ea.grfAccessMode = SET_ACCESS;
+ switch (dwType) {
+ case SOT_ALLOW:
+ ea.grfAccessMode = SET_ACCESS;
+ break;
+ case SOT_DENY:
+ ea.grfAccessMode = DENY_ACCESS;
+ break;
+ case SOT_AUDIT_SUCCESS:
+ ea.grfAccessMode = SET_AUDIT_SUCCESS;
+ break;
+ case SOT_AUDIT_FAILURE:
+ ea.grfAccessMode = SET_AUDIT_FAILURE;
+ break;
+ }
- if (0 == lstrcmpW(L"CreateFolder", pwzTable))
+ ea.grfInheritance = NO_INHERITANCE;
+ if (!(dwFlags & SOF_SELF_INHERIT))
{
- ea.grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
+ ea.grfInheritance |= INHERIT_ONLY;
}
- else
+ if (dwFlags & SOF_CONTAINER_INHERIT)
+ {
+ ea.grfInheritance |= SUB_CONTAINERS_ONLY_INHERIT;
+ }
+ if (dwFlags & SOF_OBJECT_INHERIT)
{
- ea.grfInheritance = NO_INHERITANCE;
+ ea.grfInheritance |= SUB_OBJECTS_ONLY_INHERIT;
}
#pragma prefast(push)
#pragma prefast(disable:25029)
::BuildTrusteeWithSidW(&ea.Trustee, psid);
#pragma prefast(pop)
-
- objectType = SEObjectTypeFromString(const_cast<LPCWSTR> (pwzTable));
// always add these permissions for services
// these are basic permissions that are often forgotten
if (0 == lstrcmpW(L"ServiceInstall", pwzTable))
{
dwPermissions |= SERVICE_QUERY_CONFIG | SERVICE_QUERY_STATUS |
SERVICE_ENUMERATE_DEPENDENTS | SERVICE_INTERROGATE;
}
ea.grfAccessPermissions = dwPermissions;
- if (SE_UNKNOWN_OBJECT_TYPE != objectType)
- {
- er = ::GetNamedSecurityInfoW(pwzObject, objectType,
DACL_SECURITY_INFORMATION, NULL, NULL, &pAclExisting, NULL, &psd);
- ExitOnFailure1(hr = HRESULT_FROM_WIN32(er), "failed to get
security info for object: %S", pwzObject);
-
- //Need to see if DACL is protected so getting Descriptor
information
- if(!::GetSecurityDescriptorControl(psd, &sdc, &dwRevision))
- {
- ExitOnLastError1(hr, "failed to get security descriptor
control for object: %S", pwzObject);
- }
+ switch (dwType) {
+ case SOT_ALLOW:
+ case SOT_DENY:
+ pAclExisting = pDaclNew;
+ pAclNew = &pDaclNew;
+ if (!pAclExisting)
+ pAclExisting = pDaclExisting;
+ break;
+ case SOT_AUDIT_SUCCESS:
+ case SOT_AUDIT_FAILURE:
+ pAclExisting = pSaclNew;
+ pAclNew = &pSaclNew;
+ if (!pAclExisting)
+ pAclExisting = pSaclExisting;
+ break;
+ }
#pragma prefast(push)
#pragma prefast(disable:25029)
- er = ::SetEntriesInAclW(1, &ea, pAclExisting, &pAclNew);
+ er = ::SetEntriesInAclW(1, &ea, pAclExisting, &pAclTemp);
#pragma prefast(pop)
- ExitOnFailure1(hr = HRESULT_FROM_WIN32(er), "failed to add ACLs
for object: %S", pwzObject);
+ ExitOnFailure1(hr = HRESULT_FROM_WIN32(er), "failed to add ACLs for
object: %S", pwzObject);
- if (sdc & SE_DACL_PROTECTED)
- {
- si = DACL_SECURITY_INFORMATION |
PROTECTED_DACL_SECURITY_INFORMATION;
- }
- else
- {
- si = DACL_SECURITY_INFORMATION;
- }
- er = ::SetNamedSecurityInfoW(pwzObject, objectType, si, NULL,
NULL, pAclNew, NULL);
- MessageExitOnFailure1(hr = HRESULT_FROM_WIN32(er),
msierrSecureObjectsFailedSet, "failed to set security info for object: %S",
pwzObject);
+ if (*pAclNew)
+ ::LocalFree(*pAclNew);
+ *pAclNew = pAclTemp;
+
+ hr = WcaProgressMessage(COST_SECUREOBJECT, FALSE);
+ ExitOnFailure(hr, "failed to send progress message");
+ }
+ if (NULL != pwzObject)
+ {
+ // commit the ACLs
+ if (!pDaclNew)
+ {
+ si &= ~(DACL_SECURITY_INFORMATION |
PROTECTED_DACL_SECURITY_INFORMATION);
}
- else
+ if (!pSaclNew)
{
- MessageExitOnFailure1(hr = E_UNEXPECTED,
msierrSecureObjectsUnknownType, "unknown object type: %S", pwzTable);
+ si &= ~(SACL_SECURITY_INFORMATION |
PROTECTED_SACL_SECURITY_INFORMATION);
}
-
- hr = WcaProgressMessage(COST_SECUREOBJECT, FALSE);
- ExitOnFailure(hr, "failed to send progress message");
-
- objectType = SE_UNKNOWN_OBJECT_TYPE;
+ er = ::SetNamedSecurityInfoW(pwzObject, objectType, si, NULL, NULL,
pDaclNew, pSaclNew);
+ MessageExitOnFailure1(hr = HRESULT_FROM_WIN32(er),
msierrSecureObjectsFailedSet, "failed to set security info for object: %S",
pwzPreviousObject);
}
LExit:
ReleaseStr(pwzUser);
ReleaseStr(pwzDomain);
ReleaseStr(pwzTable);
+ ReleaseStr(pwzPreviousTable);
ReleaseStr(pwzObject);
+ ReleaseStr(pwzPreviousObject);
ReleaseStr(pwzData);
ReleaseStr(pwzAccount);
- if (pAclNew)
- ::LocalFree(pAclNew);
+ if (pDaclNew)
+ ::LocalFree(pDaclNew);
+ if (pSaclNew)
+ ::LocalFree(pSaclNew);
if (psd)
::LocalFree(psd);
if (psid)
AclFreeSid(psid);
if (FAILED(hr))
@@ -775,18 +929,22 @@
EXPLICIT_ACCESSW ea = {0};
SE_OBJECT_TYPE objectType = SE_UNKNOWN_OBJECT_TYPE;
PSECURITY_DESCRIPTOR psd = NULL;
ULONG psdSize;
SECURITY_DESCRIPTOR_CONTROL sdc = {0};
- SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION;
+ SECURITY_INFORMATION si = DACL_SECURITY_INFORMATION |
SACL_SECURITY_INFORMATION;
PACL pDacl = NULL;
BOOL bDaclPresent = false;
BOOL bDaclDefaulted = false;
+ PACL pSacl = NULL;
+ BOOL bSaclPresent = false;
+ BOOL bSaclDefaulted = false;
DWORD dwRevision = 0;
- int iProtected;
+ int iDaclProtected;
+ int iSaclProtected;
// initialize
hr = WcaInitialize(hInstall, "ExecSecureObjectsRollback");
ExitOnFailure(hr, "failed to initialize");
hr = WcaGetProperty(L"CustomActionData", &pwzData);
@@ -806,13 +964,16 @@
if (SE_UNKNOWN_OBJECT_TYPE != objectType)
{
hr = WcaReadStringFromCaData(&pwz, &pwzSecurityInfo);
ExitOnFailure(hr, "failed to process CustomActionData");
- hr = WcaReadIntegerFromCaData(&pwz, &iProtected);
+ hr = WcaReadIntegerFromCaData(&pwz, &iDaclProtected);
+ ExitOnFailure(hr, "failed to process CustomActionData");
+
+ hr = WcaReadIntegerFromCaData(&pwz, &iSaclProtected);
ExitOnFailure(hr, "failed to process CustomActionData");
if
(!::ConvertStringSecurityDescriptorToSecurityDescriptorW(pwzSecurityInfo,SDDL_REVISION_1,&psd,&psdSize))
{
ExitOnLastError(hr, "failed to convert security descriptor string
to a valid security descriptor");
}
@@ -834,13 +995,13 @@
if(!::GetSecurityDescriptorControl(psd, &sdc, &dwRevision))
{
ExitOnLastError1(hr, "failed to get security descriptor control
for object: %S", pwzObject);
}
// Write a 1 if DACL is protected, 0 otherwise
- switch (iProtected)
+ switch (iDaclProtected)
{
case 0:
// Unnecessary to do anything - leave si to the default flags
break;
case 1:
@@ -850,13 +1011,43 @@
default:
hr = E_UNEXPECTED;
ExitOnFailure(hr, "unrecognized value in CustomActionData");
break;
}
- er = ::SetNamedSecurityInfoW(pwzObject, objectType, si, NULL, NULL,
pDacl, NULL);
+ if
(!::GetSecurityDescriptorSacl(psd,&bSaclPresent,&pSacl,&bSaclDefaulted))
+ {
+ hr = E_UNEXPECTED;
+ ExitOnFailure2(hr, "failed to get security descriptor's SACL -
error code: %d",pwzSecurityInfo,GetLastError());
+ }
+
+ // The below situation may always be caught by the above if block -
the documentation isn't very clear. To be safe, we're going to test for it.
+ if (!bSaclPresent)
+ {
+ hr = E_UNEXPECTED;
+ ExitOnFailure(hr, "security descriptor does not contain a SACL");
+ }
+
+ // Write a 1 if DACL is protected, 0 otherwise
+ switch (iSaclProtected)
+ {
+ case 0:
+ // Unnecessary to do anything - leave si to the default flags
+ break;
+
+ case 1:
+ si = si | PROTECTED_SACL_SECURITY_INFORMATION;
+ break;
+
+ default:
+ hr = E_UNEXPECTED;
+ ExitOnFailure(hr, "unrecognized value in CustomActionData");
+ break;
+ }
+
+ er = ::SetNamedSecurityInfoW(pwzObject, objectType, si, NULL, NULL,
pDacl, pSacl);
ExitOnFailure2(hr = HRESULT_FROM_WIN32(er), "failed to set security
info for object: %S error code: %d", pwzObject, GetLastError());
}
else
{
MessageExitOnFailure1(hr = E_UNEXPECTED,
msierrSecureObjectsUnknownType, "unknown object type: %S", pwzTable);
}
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
WiX-devs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/wix-devs