如何在C#中从打印机中删除访问控制项

本文关键字:删除 访问 访问控制 控制项 打印机 | 更新日期: 2023-09-27 18:27:28

我一直在尝试使用WMI从与Windows 7中的本地打印机关联的自由访问控制列表(DACL)中删除访问控制项(ACE)。该代码获取安全描述符,并遍历DACL中的所有ACE。除非ALE中的受托人被命名为"Everyone",否则ACE将被添加到临时列表中。

临时列表将变成一个数组,并替换安全描述符的DACL属性。然后,代码使用修改后的描述符调用SetSecurityDescriptor()。

返回值为0x8007051B,0x051B为Win32错误代码:1307,此安全ID可能未分配为此对象的所有者

错误消息有点令人困惑,因为代码中没有我(故意)更改打印机的所有者。

如果我将方法更改为将每个ACE都包含在临时列表中,则对SetSecurityDescriptor()的调用将成功完成。

以管理员身份运行应用程序没有任何区别。

当然,还有代码:

    private void ChangeSecurity()
        {
            var query = String.Format("SELECT * from Win32_Printer where Name like '"%{0}%'"", PrinterName);
            var searcher = new ManagementObjectSearcher(query);
            var searchResults = searcher.Get();
            foreach (ManagementObject printer in searchResults)
            {
                var result = printer.InvokeMethod("GetSecurityDescriptor", null, null);
                var descriptor = (ManagementBaseObject)result["Descriptor"];
                var flags = (uint)descriptor["ControlFlags"];
                if ((flags & (uint)ControlFlags.DiscretionaryAclPresent) == (uint)ControlFlags.DiscretionaryAclPresent)
                {
                    Console.WriteLine("DACL present");
                    var dacl = (ManagementBaseObject[])descriptor["DACL"];
                    var newDaclList = new List<ManagementBaseObject>();
                    foreach (var ace in dacl)
                    {
                        var trustee = (ManagementBaseObject)ace["Trustee"];
                        var aceType = (uint)ace["AceType"];
                        if ((aceType & (uint) AceType.AccessAllowed) == (uint) AceType.AccessAllowed)
                        {
                            Console.WriteLine("{0}''{1}", trustee["Domain"], trustee["Name"]);
                            Console.WriteLine("Access mask {0}", ace["AccessMask"]);
                            if (trustee["Name"].ToString() == "Everyone" && trustee["Domain"] == null)
                            {
                                Console.WriteLine("Remove access");
                            }
                            else
                            {
                                newDaclList.Add(ace);
                            }
                        }
                    }
                    descriptor.SetPropertyValue("DACL", newDaclList.ToArray());
                    var inParams = printer.GetMethodParameters("SetSecurityDescriptor");
                    inParams["Descriptor"] = descriptor;
                    result = printer.InvokeMethod("SetSecurityDescriptor", inParams, null);
                    Console.WriteLine("Result code: {0}", result["ReturnValue"]);
                }
            }

如何在C#中从打印机中删除访问控制项

我也遇到了同样的问题。我想从非管理员帐户和组中删除对打印机的访问权限。

解决方案是:

替换此行:

descriptor.SetPropertyValue("DACL", newDaclList.ToArray());

这个:

descriptor.SetPropertyValue("DACL", newDaclList.ToArray());
descriptor.SetPropertyValue("Group", null);
descriptor.SetPropertyValue("Owner", null);
descriptor.SetPropertyValue("ControlFlags", (uint)ControlFlags.DiscretionaryAclPresent);

我花了几个小时才弄明白。

请参阅Microsoft:文档中的"备注"部分

https://msdn.microsoft.com/en-us/library/aa393594(v=vs.85).aspx