C#通过WMI设置NTFS目录共享和目录安全
1) 目录共享:通过WMI的Win32_Share类的Create()方法来实现。
2) 目录安全:通过WMI的Win32_LogicalFileSecuritySetting类的SetSecurityDescriptor()方法来实现,涉及到win32_trustee和win32_ace类。
完整代码 如下:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Management;
namespace SharePermissions
...{
public enum ShareResourceType : uint
...{
DiskDrive = 0x0,
PrintQueue = 0x1,
Device = 0x2,
IPC = 0x3,
DiskDriveAdmin = 0x80000000,
PrintQueueAdmin = 0x80000001,
DeviceAdmin = 0x80000002,
IPCAdmin = 0x80000003
}
[Flags]
public enum AccessPrivileges : uint
...{
FileReadData = 0x00000001,
FileWriteData = 0x00000002,
FileAppendData = 0x00000004,
FileReadEA = 0x00000008,
FileWriteEA = 0x00000010,
FileExecute = 0x00000020,
FileDeleteChild = 0x00000040,
FileReadAttributes = 0x00000080,
FileWriteAttributes = 0x00000100,
Delete = 0x00010000,
ReadControl = 0x00020000,
WriteDac = 0x00040000,
WriteOwner = 0x00080000,
Synchronize = 0x00100000
}
[Flags]
enum AceFlags : uint
...{
NonInheritAce = 0,
ObjectInheritAce = 1,
ContainerInheritAce = 2,
NoPropagateInheritAce = 4,
InheritOnlyAce = 8,
InheritedAce = 16
}
[Flags]
enum AceType : uint
...{
AccessAllowed = 0,
AccessDenied = 1,
Audit = 2
}
public partial class Form1 : Form
...{
public Form1()
...{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
...{
SetShares();
SetPermissions();
}
void SetShares()
...{
ManagementClass mc = new ManagementClass("win32_share");
ManagementBaseObject inParams = mc.GetMethodParameters("Create");
inParams["Path"] = @"C:DownloadsTemp";
inParams["Name"] = "Temp";
inParams["Type"] = ShareResourceType.DiskDrive;
inParams["MaximumAllowed"] = null; //null = 用户数连接无限制,否则指定一个正整数
inParams["Description"] = null;
inParams["Password"] = null;
inParams["Access"] = null; //null = 使Everyone拥有完全控制权限
ManagementBaseObject outParams = mc.InvokeMethod("Create", inParams, null);
uint returnValue = (uint)outParams.Properties["ReturnValue"].Value;
string ErrorMessage = null;
switch (returnValue)
...{
case 0: //Success
break;
case 2: //Access denied
ErrorMessage = "无权访问";
break;
case 8: //Unknown failure
ErrorMessage = "未知失败";
break;
case 9: //Invalid name
ErrorMessage = "非法的共享名";
break;
case 10: //Invalid level
ErrorMessage = "非法的层次";
break;
case 21: //Invalid parameter
ErrorMessage = "非法的参数";
break;
case 22: //Duplicate share
ErrorMessage = "重复共享";
break;
case 23: //Redirected path
ErrorMessage = "重定向路径";
break;
case 24: //Unknown device or directory
ErrorMessage = "未知的目录";
break;
case 25: //Net name not found
ErrorMessage = "网络名不存在";
break;
default:
break;
}
if (returnValue == 0)
MessageBox.Show("成功");
else
MessageBox.Show(ErrorMessage);
}
bool SetPermissions()
...{
//ManagementPath path = new ManagementPath();
//path.Server = "."; // 机器名, .表示本机
//path.NamespacePath = @"rootcimv2";
//path.RelativePath = string.Format("Win32_LogicalFileSecuritySetting.Path=''{0}''", @"C:DownloadsTemp");
//ManagementObject mo = new ManagementObject(path);
ManagementObject mo = new ManagementObject(string.Format("Win32_LogicalFileSecuritySetting.Path=''{0}''", @"C:DownloadsTemp"));
ManagementBaseObject outParams = mo.InvokeMethod("GetSecurityDescriptor", null, null);
if ((uint)outParams.Properties["ReturnValue"].Value != 0)
return false;
ManagementBaseObject Descriptor = (ManagementBaseObject)outParams.Properties["Descriptor"].Value;
//foreach (ManagementBaseObject mbo in (ManagementBaseObject[])Descriptor.Properties["Dacl"].Value)
//{
// this.richTextBox1.AppendText(string.Format("AccessMask: {0} AceFlags:{1} AceType: {2} ", mbo["AccessMask"],
// Enum.Format(typeof(AceFlags), mbo["AceFlags"], "g"), mbo["AceType"]));
// if ((uint)mbo["AceType"] == (uint)AceType.AccessDenied)
// this.richTextBox1.AppendText("Denied Ace ");
// else
// this.richTextBox1.AppendText("Allowed Ace ");
// ManagementBaseObject Trustee = ((ManagementBaseObject)(mbo["Trustee"]));
// this.richTextBox1.AppendText(string.Format("Name: {0} Domain: {1} SID: {2} ",
// Trustee.Properties["Name"].Value,
// Trustee.Properties["Domain"].Value,
// Trustee.Properties["SIDString"].Value));
// uint mask = (UInt32)mbo["AccessMask"];
// this.richTextBox1.AppendText(Enum.Format(typeof(AccessPrivileges), mask, "g"));
// this.richTextBox1.AppendText(" ");
//}
List
//newDacl.AddRange((ManagementBaseObject[])Descriptor.Properties["Dacl"].Value);
//增加Everyone用户
ManagementClass trustee = new ManagementClass("win32_trustee");
trustee.Properties["Name"].Value = "Everyone";
trustee.Properties["Domain"].Value = null;
//设置只读/运行权限
ManagementClass ace = new ManagementClass("win32_ace");
ace.Properties["AccessMask"].Value = AccessPrivileges.FileReadData | AccessPrivileges.FileReadAttributes | AccessPrivileges.FileReadEA
| AccessPrivileges.ReadControl | AccessPrivileges.FileExecute;
ace.Properties["AceFlags"].Value = AceFlags.ObjectInheritAce | AceFlags.ContainerInheritAce | AceFlags.NoPropagateInheritAce;
ace.Properties["AceType"].Value = AceType.AccessAllowed;
ace.Properties["Trustee"].Value = trustee;
newDacl.Add(ace);
ManagementBaseObject inParams = mo.GetMethodParameters("SetSecurityDescriptor");
Descriptor.Properties["Dacl"].Value = newDacl.ToArray();
//Descriptor.Properties["Group"].Value = null;
//Descriptor.Properties["Owner"].Value = null;
inParams["Descriptor"] = Descriptor;
ManagementBaseObject ret = mo.InvokeMethod("SetSecurityDescriptor", inParams, null);
uint returnValue = (uint)ret.Properties["ReturnValue"].Value;
string ErrorMessage = null;
switch (returnValue)
...{
case 0: //Success
break;
case 2: //Access denied
ErrorMessage = "无权访问";
break;
case 8: //Unknown failure
ErrorMessage = "未知失败";
break;
case 9: //Privilege missing
ErrorMessage = "缺少权限";
break;
case 21: //Invalid parameter
ErrorMessage = "非法的参数";
break;
default:
break;
}
if (returnValue == 0)
...{
MessageBox.Show("成功");
return true;
}
else
...{
MessageBox.Show(ErrorMessage);
return false;
}
}
}
}
另外需要注意的是:当新建目录时,系统会从上级目录自动继承用户,这些用户可能有完全控制权限,当你对某个目录设置只读时,可能由于这些继承用户的存在而影响到最终结果。所以要将根目录(如C:/, d:/等)的目录属性的安全页中将一些系统自动添加的具有完全控制的用户(如Creator Owner, Users, System)删除或改为非继承或仅当前目录有效。
注:根目录的Everyone不会被继承(可以通过目录属性的安全/高级/编辑中看到),另外也不要把本机管理员或域管理员(都是Administrator)误删了。