PSPKI
PSPKI copied to clipboard
Copying ACL's - Unexpected Results
Hi Folks
Module Version: 3.7.2 OS: Windows 2019 Possibly related to #113 I have downloaded and am using the updated .dll from #113
Using the following code snippet I'm not getting the expected results.
$template = 'Test Template'
$SourceACL = Get-CertificateTemplate -Name "WebServer" | Get-CertificateTemplateAcl
$DestinationACL = Get-CertificateTemplate -DisplayName $template | Get-CertificateTemplateAcl | Remove-CertificateTemplateAcl -Force
$DestinationACL | Add-CertificateTemplateAcl -AcessRule $SourceACL.Access | Set-CertificateTemplateAcl | Out-Null
Before making any changes I get this:
PS C:\Windows\system32> (Get-CertificateTemplate -DisplayName $template | Get-CertificateTemplateAcl).Access
CertificateTemplateRights : Read, Write
Rights : Read, Write
AccessControlType : Allow
IdentityReference : NT AUTHORITY\Authenticated Users
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
CertificateTemplateRights : Read, Write, FullControl
Rights : Read, Write, FullControl
AccessControlType : Allow
IdentityReference : CONTOSO\Domain Admins
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
CertificateTemplateRights : Read, Write, FullControl
Rights : Read, Write, FullControl
AccessControlType : Allow
IdentityReference : CONTOSO\Enterprise Admins
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
When running my code snippet above, $SourceACL.Access has the following values and these are what I expect:
PS C:\Windows\system32> $SourceACL.Access
CertificateTemplateRights : Read
Rights : Read
AccessControlType : Allow
IdentityReference : NT AUTHORITY\Authenticated Users
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
CertificateTemplateRights : Read, Write, Enroll
Rights : Read, Write, Enroll
AccessControlType : Allow
IdentityReference : CONTOSO\Domain Admins
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
CertificateTemplateRights : Read, Write, Enroll
Rights : Read, Write, Enroll
AccessControlType : Allow
IdentityReference : CONTOSO\Enterprise Admins
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
After running my code snippet above, the ACLs have changed, but are not what I expect:
PS C:\Windows\system32> (Get-CertificateTemplate -DisplayName $template | Get-CertificateTemplateAcl).Access
CertificateTemplateRights : Read, Write
Rights : Read, Write
AccessControlType : Allow
IdentityReference : NT AUTHORITY\Authenticated Users
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
CertificateTemplateRights : Write, Enroll, Autoenroll
Rights : Write, Enroll, Autoenroll
AccessControlType : Allow
IdentityReference : CONTOSO\Domain Admins
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
CertificateTemplateRights : Write, Enroll, Autoenroll
Rights : Write, Enroll, Autoenroll
AccessControlType : Allow
IdentityReference : CONTOSO\Enterprise Admins
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
Note that if I run the following code, all the permissions are removed and I have to use ADSI Edit to fix the object up in AD so I can access it, it is no longer visible in the to PowerShell or via the Certificate Template Console. I think this is the expected outcome and I ran it just to test the individual lines of my snippet above.
Get-CertificateTemplate -DisplayName $template | Get-CertificateTemplateAcl | Remove-CertificateTemplateAcl -Force | Set-CertificateTemplateAcl
Am I doing something wrong or is there a bug here?
Thanks!
PS: Perhaps related, the code is also not removing inheritable permissions, I haven't dug into that in any detail but the results above show IsInherited being false and my first assumption is inheritable permissions should be removed, but I haven't really thought that through in detail. In my tests above I have manually removed inheritable permissions via ADSIEdit before running the examples and I haven't fully tested this.
Hi, I'm not really understand the problem you are facing. The snippet from the top is working just fine. Last snippet indeed removes all ACEs from security descriptor and you have to use ADSIEdit to use owner rights and re-gain access to certificate template.
Perhaps related, the code is also not removing inheritable permissions
From my understanding, certificate templates use only explicit permissions on every template. There is no template (at least from default list) that inherits permissions from parent container? Can you tell more about your configuration:
- What permissions you have before modification
- Code you are running to modify permissions
- Actual results
- Expected results
On the inheritable permissions ...
I'm using ADCSTemplate to import certificate templates and it seems to create them with inheritable permissions. I don't seem to get inheritiable permissions when using the the Certificate Template Console, so perhaps its an issue with ADCSTemplate.
As noted in my original post, I haven't dug into this in to much detail at the moment.
Hi
Here is the full process of what I'm doing, including the template export and subsequent import ... I've repeated much of what is above for clarity. I hope this is answering your question?
Step 1 - Manually copy a suitable default template to create two new templates using the Certificate Template Console, adjusting properties as required.
Step 2 - Export templates from the development PKI environment so I can deploy the templates to other PKI environments:
Install-Module ADCSTemplate -Force
$ExportPath = 'C:\Temp\PKITemplates'
if (-not (Test-Path -Path $ExportPath)) {
New-Item -Path $ExportPath -ItemType Directory | Out-Null
}
$Templates = @(
'Test SSL Certificate Template'
'Test Code Signing Template'
)
foreach ($template in $Templates) {
$fileName = "$(($template -replace ' ', '').Trim()).json"
Export-ADCSTemplate -DisplayName $template | Set-Content -Path "$ExportPath\$fileName"
}
Step 3 - Import the templates into a new environment
Install-Module ADCSTemplate -Force
$ImportPath = 'C:\Temp\PKITemplates'
$Templates = @(
'Test SSL Certificate Template'
'Test Code Signing Template'
)
foreach ($template in $Templates) {
$fileName = "$(($template -replace ' ', '').Trim()).json"
New-ADCSTemplate -DisplayName $template -JSON (Get-Content "$ImportPath\$fileName" -Raw)
}
After this step the permissions on the two new templates look like this:
PS C:\Windows\system32> (Get-CertificateTemplate -DisplayName $template | Get-CertificateTemplateAcl).Access
CertificateTemplateRights : Read
Rights : Read
AccessControlType : Allow
IdentityReference : NT AUTHORITY\Authenticated Users
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
CertificateTemplateRights : Read, Write, FullControl
Rights : Read, Write, FullControl
AccessControlType : Allow
IdentityReference : NT AUTHORITY\SYSTEM
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
CertificateTemplateRights : Read, Write, FullControl
Rights : Read, Write, FullControl
AccessControlType : Allow
IdentityReference : CONTOSO\Domain Admins
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
CertificateTemplateRights : Read, Write, FullControl
Rights : Read, Write, FullControl
AccessControlType : Allow
IdentityReference : CONTOSO\Enterprise Admins
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
NOTE: The new templates also have permissions that are being inherited, but let's ignore that for now.
Step 4 - Fix up permissions:
foreach ($template in $Templates) {
$SourceACL = Get-CertificateTemplate -Name "WebServer" | Get-CertificateTemplateAcl
$DestinationACL = Get-CertificateTemplate -DisplayName $template | Get-CertificateTemplateAcl | Remove-CertificateTemplateAcl -Force
$DestinationACL | Add-CertificateTemplateAcl -AcessRule $SourceACL.Access | Set-CertificateTemplateAcl | Out-Null
}
After running this step the permissions on my new templates look like this (they have changed from what they were earlier).
PS C:\Windows\system32> (Get-CertificateTemplate -DisplayName $template | Get-CertificateTemplateAcl).Access
CertificateTemplateRights : Read, Write
Rights : Read, Write
AccessControlType : Allow
IdentityReference : NT AUTHORITY\Authenticated Users
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
CertificateTemplateRights : Read, Write, Enroll, Autoenroll
Rights : Read, Write, Enroll, Autoenroll
AccessControlType : Allow
IdentityReference : CONTOSO\Domain Admins
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
CertificateTemplateRights : Read, Write, FullControl, Enroll, Autoenroll
Rights : Read, Write, FullControl, Enroll, Autoenroll
AccessControlType : Allow
IdentityReference : CONTOSO\Enterprise Admins
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
However, the permission on the WebServer template that I'm using as a source location to copy permissions from look like this.
PS C:\Windows\system32> (Get-CertificateTemplate -DisplayName 'Web Server' | Get-CertificateTemplateAcl).Access
CertificateTemplateRights : Read
Rights : Read
AccessControlType : Allow
IdentityReference : NT AUTHORITY\Authenticated Users
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
CertificateTemplateRights : Read, Write, Enroll
Rights : Read, Write, Enroll
AccessControlType : Allow
IdentityReference : CONTOSO\Domain Admins
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
CertificateTemplateRights : Read, Write, Enroll
Rights : Read, Write, Enroll
AccessControlType : Allow
IdentityReference : CONTOSO\Enterprise Admins
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
I also get this result if I output $SourceACL.Access from the code above (as I would expect). You can see the actual permissions on the new templates does not match the permissions on the WebServer certificate template (that is correct in $SourceACL.Access). NT AUTHORITY\SYSTEM does get removed, but the permissions for the remaining objects are not what I expect and don't match the WebServer certificate template.
If I repeat the process and use ADSI Edit to remove the inheritable permissions before running step 4 above (selecting the option to convert all inheritable permissions to direct permissions) the permissions look like this (same as above):
PS C:\Windows\system32> (Get-CertificateTemplate -DisplayName $template | Get-CertificateTemplateAcl).Access
CertificateTemplateRights : Read
Rights : Read
AccessControlType : Allow
IdentityReference : NT AUTHORITY\Authenticated Users
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
CertificateTemplateRights : Read, Write, FullControl
Rights : Read, Write, FullControl
AccessControlType : Allow
IdentityReference : NT AUTHORITY\SYSTEM
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
CertificateTemplateRights : Read, Write, FullControl
Rights : Read, Write, FullControl
AccessControlType : Allow
IdentityReference : CONTOSO\Domain Admins
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
CertificateTemplateRights : Read, Write, FullControl
Rights : Read, Write, FullControl
AccessControlType : Allow
IdentityReference : CONTOSO\Enterprise Admins
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
If I now run Step 4, having removed the inheritable permissions, the resulting permissions look like this (different from above, but still not the expected result ...):
PS C:\Windows\system32> (Get-CertificateTemplate -DisplayName $template | Get-CertificateTemplateAcl).Access
CertificateTemplateRights : Read, Write
Rights : Read, Write
AccessControlType : Allow
IdentityReference : NT AUTHORITY\Authenticated Users
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
CertificateTemplateRights : Write, Enroll, Autoenroll
Rights : Write, Enroll, Autoenroll
AccessControlType : Allow
IdentityReference : CONTOSO\Domain Admins
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
CertificateTemplateRights : Write, Enroll, Autoenroll
Rights : Write, Enroll, Autoenroll
AccessControlType : Allow
IdentityReference : CONTOSO\Enterprise Admins
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
Playing around I have also found the following.
- Import the templates (Step 3 above).
- Use ADSI Edit to remove inheritiable permissions
- Use ADSI Edit to remove all permissions and give Enterprise Admins 'Full Controll'
- Run the following code
Get-CertificateTemplate -DisplayName $template | Get-CertificateTemplateAcl | Remove-CertificateTemplateAcl -Force | Add-CertificateTemplateAcl -Identity 'CONTOSO\Enterprise Admins' -AccessType Allow -AccessMask Read | Set-CertificateTemplateAcl
Get-CertificateTemplate -DisplayName $template | Get-CertificateTemplateAcl | Add-CertificateTemplateAcl -Identity 'CONTOSO\Enterprise Admins' -AccessType Allow -AccessMask Write | Set-CertificateTemplateAcl
Get-CertificateTemplate -DisplayName $template | Get-CertificateTemplateAcl | Add-CertificateTemplateAcl -Identity 'CONTOSO\Enterprise Admins' -AccessType Allow -AccessMask Enroll | Set-CertificateTemplateAcl
The result from line 1 and 2 from this snippet looks okay, the template gets read and write permissions only. When I run the third line to configure 'enroll' things break and I have to use ADSI Edit to fix them as the template is no longer available to PowerShell or the Certificate Template Console.
I hope this information is useful and I'm not missing something obvious.
Looks like I see the problem and can replicate.
Awesome. Thanks for the your efforts here!
A small update (not related to this issue, but same subject): https://github.com/PKISolutions/PSPKI/issues/130
Another related: https://github.com/PKISolutions/PSPKI/issues/131
Another related: https://github.com/PKISolutions/PSPKI/issues/132
Finally, got it working. Please, check if this DLL works for you: SysadminsLV.PKI-v3.2.7.5.zip
That appears to be working for me thank you! With the updated .DLL I am now getting the results I expect when both copying ACLs to a new template or attempting to set new permission on a certificate template.
I still have to deal with inheritable permissions separately using ADSI Edit and not in my script.
Thanks for confirming this!
@jimchurches I was facing the same problem with inheritable permissions on new templates created outside of the console. Maybe you can use this sample code for removing inheritable permissions:
# Set permissions for deployment account before remove inheritance
Get-certificateTemplate -Name "$NewTemplateName" | Get-CertificateTemplateAcl `
| Add-CertificateTemplateAcl -User $DeploymentAccount -AccessType "Allow" -AccessMask Read, Write `
| Set-CertificateTemplateAcl -Verbose
# Remove Inheritance from new template.
<#
isProtected Boolean
true to protect the access rules associated with this ObjectSecurity object from inheritance; false to allow inheritance.
preserveInheritance Boolean
true to preserve inherited access rules; false to remove inherited access rules. This parameter is ignored if isProtected is false.
#>
$template = Get-certificateTemplate -Name "$NewTemplateName" -ErrorAction Stop -verbose
$adsi = [ADSI]("LDAP://" + $template.DistinguishedName)
$adsi.ObjectSecurity.SetAccessRuleProtection($true, $false)
$adsi.CommitChanges()
# Set wanted permissions
Get-certificateTemplate -Name "$NewTemplateName" | Get-CertificateTemplateAcl `
| Add-CertificateTemplateAcl -User "Domain Admins", "Enterprise Admins", $CATemplMgr -AccessType "Allow" -AccessMask Read, Write `
| Set-CertificateTemplateAcl -Verbose
Get-certificateTemplate -Name "$NewTemplateName" | Get-CertificateTemplateAcl `
| Add-CertificateTemplateAcl -User $inputTemplate.DomainLocalGroupName -AccessType "Allow" -AccessMask $inputTemplate.AccessMask `
| Set-CertificateTemplateAcl -Verbose
# Remove temporary deployment account permissions
Get-certificateTemplate -Name "$NewTemplateName" | Get-CertificateTemplateAcl `
| Remove-CertificateTemplateAcl -User $DeploymentAccount -AccessType "Allow" `
| Set-CertificateTemplateAcl -Verbose
Fixed in v4.0.0