启动 CA 控制台 ( certsrv.msc
) 时,我可以右键单击我的 CA,选择特性然后我可以在安全选项卡。当我修改它时,更改将应用于 AD 对象:
CN=MY-CA,CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration,DC=contoso,DC=com
当我在 ADSI 编辑器中查看它时,修改后的 ACL 条目不会被继承,而是直接应用(如预期的那样)。但是当我以编程方式更改此对象的 ACL 时,例如通过:
Import-Module ActiveDirectory
$path = 'AD:CN=MY-CA,CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration,DC=contoso,DC=com'
$acl = Get-Acl -Path $path
$acl.AddAccessRule(...)
Set-Acl -Path $path -AclObject $acl
然后,我可以在 ADSI 编辑器中看到这些更改,但是当我通过 CA 控制台查看我的 CA 的 ACL 时,我看不到这些更改。
那么,我做错了什么吗? 我是否也必须以编程方式修改其他对象?
我尝试过的:
- 更改后,我强制 AD 与以下设备同步:
repadmin /syncall /Aed
- 我重新启动了 CA 服务
certsvc
但这似乎不是一个“同步”问题......
答案1
这些 ACL 略有不同。AD 对象上的 ACL 仅影响 AD 条目,不会传播到 CA。
您在 CA 管理控制台中看到的 ACL 存储在注册表中的 CA 配置中。
我不确定是否有一种简单的方法可以使用 PowerShell 本地编辑 CA 上的权限(无需第三方工具)。不过,我建议使用PowerShell PKI模块来简化任务。该模块包含几个与 ACL 相关的命令:
ps 我是这个 PSPKI 模块的作者
每个命令都有内置和在线帮助,并提供有关如何使用每个命令的有用示例。
答案2
感谢指点Crypt32和一些额外的来源1,我想出了此外需要在 CA 注册表中执行以下更改:
# Get binary security descriptor of the CA from the registry
$sd_bin = Get-ItemPropertyValue -Path 'Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\CertSvc\Configuration\MY-CA' -Name 'Security'
# Create security descriptor object of it
$sd = New-Object -TypeName System.Security.AccessControl.CommonSecurityDescriptor -ArgumentList @($false, $false, $sd_bin, 0)
# Modify the DACL in place
$sd.DiscretionaryAcl.AddAccess([System.Security.AccessControl.AccessControlType]::Allow, "<SID>", <INT32_PERMISSIONS>, [System.Security.AccessControl.InheritanceFlags]::None, [System.Security.AccessControl.PropagationFlags]::None)
# Convert the security descriptor back to binary form
$sd_bin_new = [System.Byte[]]::CreateInstance([System.Byte], $sd.BinaryLength)
$sd.GetBinaryForm($sd_bin_new, 0)
# Write it back to the registry
Set-ItemProperty -Path 'Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\CertSvc\Configuration\MY-CA' -Name 'Security' -Value $sd_bin_new
# Restart the certificate services
Restart-Service -Name CertSvc
1进一步阅读: