写入没有读取权限的文件

时间:2016-01-09 16:50:44

标签: c# .net windows file-permissions acl

我正在尝试在C#中的本地Windows帐户上实现Bell-La Padula模型,并且在此模型中,较低安全级别的用户可以写入属于更高安全级别的文件而无需读取它! 我已经为这样的文件添加了权限

  

file.txt:read [deny] - 写[Allow]

现在我正在努力让用户将文本附加到file.txt而不读取它。 我用过这个:

using (FileStream aFile = new FileStream(filename, FileMode.Append, FileAccess.Write))
                using (StreamWriter sw = new StreamWriter(aFile))
                {
                    sw.WriteLine(DateTime.Now.ToString() + " Modified BY :" + username + Environment.NewLine);
                    sw.WriteLine(textBox1.Text);
                    sw.WriteLine("---------- END User Edition --------------");
                }

当我从管理员帐户运行该程序时,它有效,但当我尝试从Guset帐户运行它时,它会引发异常:您无法访问此文件!

我尝试在开始编辑之前添加读取权限,并在完成后删除它,但文件权限从未更改。

是否有任何编程方式可以实现,或允许我的应用程序在Guest帐户中运行时对文件生效?

2 个答案:

答案 0 :(得分:1)

花了一点时间,但弄清楚了。不得不用procmon弄明白。你的代码很好。但是,您需要正确设置权限。

对于您的文本文件,您需要将有限的帐户权限授予“仅写入”。不要在deny列下检查任何内容。因为如果你这样做,拒绝访问将胜过其他任何东西。您还需要授予该帐户对读取属性读取扩展属性权限的权限。

您可以使用icaclscacls完成同样的事情。以下是有关如何手动执行此操作的手动说明。这基于Windows 10(Win7应该类似):

  1. 右键单击文件

  2. 点击属性。

  3. 切换到“安全”标签。

  4. 点击“编辑”按钮

  5. 点击“添加...”按钮

  6. 查找有限的用户帐户。

  7. 返回权限标签,选择该帐户。

  8. 取消选中“写入”复选框以外的所有内容。   enter image description here

  9. 单击“确定”关闭此对话框。

  10. 点击“高级”按钮。

  11. 选择帐户,然后点击“修改”按钮。

  12. 在下一个对话框中,单击“显示高级权限”   enter image description here

  13. 确保选中以下复选框。

    • 读取属性
    • 阅读扩展属性
    • 创建文件/写入数据
    • 创建文件夹/附加数据
    • 写属性
    • 编写扩展属性

      enter image description here

  14. 在所有对话框中单击“确定”。

答案 1 :(得分:0)

要以编程方式执行此操作,您需要允许以下内容:

System.Security.AccessControl.FileSystemRights.AppendData
System.Security.AccessControl.FileSystemRights.CreateFiles
System.Security.AccessControl.FileSystemRights.ReadAttributes
System.Security.AccessControl.FileSystemRights.ReadExtendedAttributes
System.Security.AccessControl.FileSystemRights.WriteAttributes
System.Security.AccessControl.FileSystemRights.WriteExtendedAttributes

Extra info here

Read/Write(Extended)Attributes是写操作所必需的,上面将允许用户创建日志文件并将文本追加到它们而不能读取任何内容,如果你添加Delete权限,那将使滚动日志文件也可能(我会说大多数人都需要它,因为没有滚动的无限大小的日志是非常危险的)

这可以通过任何.NET语言,PowerShell示例(创建和写入日志文件并滚动它们的权限)来完成:

$acl = Get-Acl "C:\logs"

$acl.SetAccessRuleProtection($true, $false) # Remove inherited
$acl.Access | % { $acl.RemoveAccessRule($_) } | Out-Null # Remove existing
$acl.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule("SYSTEM", "FullControl", "ContainerInherit, ObjectInherit", "None", "Allow")))
$acl.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule("Administrators", "FullControl", "ContainerInherit, ObjectInherit", "None", "Allow")))

$logsRights = [System.Security.AccessControl.FileSystemRights]::AppendData -bor `
              [System.Security.AccessControl.FileSystemRights]::CreateFiles -bor `
              [System.Security.AccessControl.FileSystemRights]::Delete -bor `
              [System.Security.AccessControl.FileSystemRights]::ReadAttributes -bor `
              [System.Security.AccessControl.FileSystemRights]::ReadExtendedAttributes -bor `
              [System.Security.AccessControl.FileSystemRights]::WriteAttributes -bor `
              [System.Security.AccessControl.FileSystemRights]::WriteExtendedAttributes

$acl.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule("Users", $logsRights, "ContainerInherit, ObjectInherit", "None", "Allow")))
Set-Acl "C:\logs" $acl
Write-Host "logs ACL"
$acl.Access

根据您的使用情况,您可能需要或不需要清除现有规则并添加系统/管理员,但您明白了