Пример #1
0
/*---------------------------------------------------------------------------*\
 * NAME: UpdatePrincipalInNamedValueSD 
 * --------------------------------------------------------------------------*
 * DESCRIPTION: Retrieves the designated security descriptor from the
 * registry and updates all ACLs that belong to the named principal.
\*---------------------------------------------------------------------------*/
DWORD UpdatePrincipalInNamedValueSD (
    HKEY hkeyRoot,
    LPTSTR tszKeyName,
    LPTSTR tszValueName,
    LPTSTR tszPrincipal,
    DWORD dwAccessMask,
    BOOL fRemove,
    DWORD fAceType
    )
{
    DWORD               dwReturnValue    = ERROR_SUCCESS;
    SECURITY_DESCRIPTOR *pSD             = NULL;
    SECURITY_DESCRIPTOR *psdSelfRelative = NULL;
    SECURITY_DESCRIPTOR *psdAbsolute     = NULL;
    DWORD               cbSecurityDesc   = 0;
    BOOL                fPresent         = FALSE;
    BOOL                fDefaultDACL     = FALSE;
    PACL                pDacl            = NULL;


    // Get security descriptor from registry
    dwReturnValue = GetNamedValueSD (hkeyRoot, tszKeyName, tszValueName, &pSD, NULL);


    if (dwReturnValue != ERROR_SUCCESS)
    {
        if(dwReturnValue == ERROR_FILE_NOT_FOUND && fRemove)
        {
            dwReturnValue = ERROR_SUCCESS;
        }
        goto CLEANUP;
    }

    if (!GetSecurityDescriptorDacl (pSD, &fPresent, &pDacl, &fDefaultDACL))
    {
        dwReturnValue = GetLastError();
        goto CLEANUP;
    }

    // Update the tszPrincipal that the caller wants to change
    dwReturnValue = UpdatePrincipalInACL (pDacl, tszPrincipal, dwAccessMask, fRemove, fAceType);
    if(dwReturnValue == ERROR_FILE_NOT_FOUND)
    {
        dwReturnValue = ERROR_SUCCESS;
        goto CLEANUP;
    }
    else if (dwReturnValue != ERROR_SUCCESS)
    {
        dwReturnValue = GetLastError();
        goto CLEANUP;
    }

    // Make the security descriptor absolute 
    dwReturnValue = MakeSDAbsolute ((PSECURITY_DESCRIPTOR) pSD, (PSECURITY_DESCRIPTOR *) &psdAbsolute); 
    if (dwReturnValue != ERROR_SUCCESS)  goto CLEANUP;

    // Set the discretionary ACL on the security descriptor
    if (!SetSecurityDescriptorDacl (psdAbsolute, TRUE, pDacl, FALSE))
    {
        dwReturnValue = GetLastError();
        goto CLEANUP;
    }

    //Now ensure consistency of the SD
    dwReturnValue = CanonicalizeSD(psdAbsolute);
    if (dwReturnValue != ERROR_SUCCESS) goto CLEANUP;

    // Make the security descriptor self-relative so that we can
    // store it in the registry
    cbSecurityDesc = 0;
    MakeSelfRelativeSD (psdAbsolute, psdSelfRelative, &cbSecurityDesc);

    psdSelfRelative = (SECURITY_DESCRIPTOR *) malloc (cbSecurityDesc);


    if (!MakeSelfRelativeSD (psdAbsolute, psdSelfRelative, &cbSecurityDesc))
    {
        dwReturnValue = GetLastError();
        goto CLEANUP;
    }

    // Store the security descriptor in the registry
    dwReturnValue = SetNamedValueSD (hkeyRoot, tszKeyName, tszValueName, psdSelfRelative);

CLEANUP:

    if(pSD) free (pSD);
    if(psdSelfRelative) free (psdSelfRelative);
    if(psdAbsolute) free (psdAbsolute);

    return dwReturnValue;
}
Пример #2
0
DWORD COxtSecurityHelper::UpdatePrincipalInNamedSecurityDescriptor(LPCTSTR tszPermissionName,
																   LPCTSTR tszPrincipal,
																   DWORD dwAccessMask)
{
	DWORD				 dwReturnValue	 = ERROR_SUCCESS;
	SECURITY_DESCRIPTOR *pSD			 = NULL;
	SECURITY_DESCRIPTOR *psdSelfRelative = NULL;
	SECURITY_DESCRIPTOR *psdAbsolute	 = NULL;
	DWORD				 cbSecurityDesc  = 0;
	BOOL				 bPresent		 = FALSE;
	BOOL				 bDefaultDACL	 = FALSE;
	PACL				 pDacl			 = NULL;

	do {
		// Get security descriptor from registry
		dwReturnValue = GetSecurityDescripterByName(tszPermissionName, &pSD, NULL);
		if (dwReturnValue != ERROR_SUCCESS)
		{
			if (dwReturnValue == ERROR_FILE_NOT_FOUND)
				dwReturnValue = ERROR_SUCCESS;
			break;
		}

		if (!::GetSecurityDescriptorDacl(pSD, &bPresent, &pDacl, &bDefaultDACL))
		{
			dwReturnValue = ::GetLastError();
			break;
		}

		// Update the tszPrincipal that the caller wants to change
		dwReturnValue = UpdatePrincipalInACL(pDacl, tszPrincipal, dwAccessMask);
		if(dwReturnValue == ERROR_FILE_NOT_FOUND)
		{
			dwReturnValue = ERROR_SUCCESS;
			break;
		}
		else if (dwReturnValue != ERROR_SUCCESS)
		{
			dwReturnValue = ::GetLastError();
			break;
		}

		// Make the security descriptor absolute
		dwReturnValue = MakeAbsoluteSecurityDescriptor((PSECURITY_DESCRIPTOR)pSD,
													   (PSECURITY_DESCRIPTOR *)&psdAbsolute);
		if (dwReturnValue != ERROR_SUCCESS)
			break;

		// Set the discretionary ACL on the security descriptor
		if (!::SetSecurityDescriptorDacl(psdAbsolute, TRUE, pDacl, FALSE))
		{
			dwReturnValue = ::GetLastError();
			break;
		}

		// Now ensure consistency of the SD
		dwReturnValue = CanonicalizeSecurityDescriptor(psdAbsolute);
		if (dwReturnValue != ERROR_SUCCESS)
			break;

		// Make the security descriptor self-relative so that we can
		// store it in the registry
		cbSecurityDesc = 0;
		::MakeSelfRelativeSD(psdAbsolute, psdSelfRelative, &cbSecurityDesc);

		psdSelfRelative = (SECURITY_DESCRIPTOR *)malloc(cbSecurityDesc);
		if (psdSelfRelative == NULL)
		{
			dwReturnValue = ERROR_OUTOFMEMORY;
			break;
		}

		if (!::MakeSelfRelativeSD(psdAbsolute, psdSelfRelative, &cbSecurityDesc))
		{
			dwReturnValue = ::GetLastError();
			break;
		}

		// Store the security descriptor in the registry
		dwReturnValue = SetSecurityDescriptorByName(tszPermissionName, psdSelfRelative);
	} while (false);

	if (pSD != NULL)
		free(pSD);
	if (psdSelfRelative != NULL)
		free(psdSelfRelative);
	if (psdAbsolute != NULL)
		free(psdAbsolute);

	return dwReturnValue;
}