Hi guys,
So far I've spent about a week hacking away at this code, and I just
can't get it to add an ACE to a the DACL for a network share using WMI.
Just to set the scene, I'm trying to add an ACL from machine A
(workstation; Saturn) and set it to a UNC path
(\\Mercury\Inet pub\Websites\Lo calUser\Test) on machine B (server;
Mercury).
Neither of these machines are on a domain, and the trustee for the new
ACL is a local user on machine B (server; Mercury), lets call him
'test' for now.
I don't want to use xcacls because it's a bit of a hack, and the ADSI
code from Microsoft looks a little offputting as it uses COM
(http://support.microsoft.com/kb/899553/EN-US/).
At this point I'm able to use the following code to apply permissions
to a local resource on machine A (e.g. C:\Test), however when I try it
on a UNC path it throws a ManagementExcep tion with the message "Not
Found", which isn't very useful.
I can only presume it's complaing about the UNC path. I've tried
doubling up the slashes, and just having single slashes (which makes no
difference).
// Works when server name is ".", "SATURN" but not "MERCURY".
ManagementScope scope = new ManagementScope (@"\\" + ServerName +
@"\root\cimv2") ;
// Works when fileName is local directory, but not UNC path.
ManagementPath path = new ManagementPath( );
path.RelativePa th = @"Win32_Logical FileSecuritySet ting.Path="
+ "'" + fileName + "'";
ManagementObjec t fileSecurity = new ManagementObjec t(
scope, path, null);
// When used with UNC path, exception with "Not Found" is thrown.
ManagementBaseO bject outParams =
(ManagementBase Object)fileSecu rity.InvokeMeth od(
"GetSecurityDes criptor", null, null);
// Get security descriptor and DACL for specified file.
ManagementBaseO bject descriptor =
(ManagementBase Object)outParam s.Properties["Descriptor "].Value;
ManagementBaseO bject[] dacl =
(ManagementBase Object[])descriptor.Pro perties["Dacl"].Value;
// Get the user account to be trustee.
ManagementObjec t userAccount = new ManagementClass (scope,
new ManagementPath( "Win32_Trustee" ), null);
userAccount.Pro perties["Name"].Value = account;
// Create a new ACE for the descriptor.
ManagementObjec t newAce = new ManagementClass (scope,
new ManagementPath( "Win32_ACE" ), null);
newAce.Properti es["Trustee"].Value = userAccount;
// Low level ace flags.
int FILE_READ_DATA = 0x0;
int FILE_WRITE_DATA = 0x1;
int FILE_APPEND_DAT A = 0x4;
int DELETE = 0x10000;
// Translate FileSystemRight s to flags.
switch (accessRights)
{
case FileSystemRight s.Read:
newAce.Properti es["AccessMask "].Value = FILE_READ_DATA;
break;
case FileSystemRight s.Modify:
newAce.Properti es["AccessMask "].Value = FILE_READ_DATA
| FILE_WRITE_DATA | FILE_APPEND_DAT A | DELETE;
break;
}
// ACL will be inherited.
newAce.Properti es["AceFlags"].Value = 0x10;
// Allow access to resource.
newAce.Properti es["AceType"].Value = 0;
// Add ACE to DACL and set to descriptor.
ArrayList daclArray = new ArrayList(dacl) ;
daclArray.Add(n ewAce);
descriptor.Prop erties["Dacl"].Value = daclArray.ToArr ay();
// User SetSecurityDesc riptor to apply the descriptor.
ManagementBaseO bject inParams =
fileSecurity.Ge tMethodParamete rs("SetSecurity Descriptor");
inParams["Descriptor "] = descriptor;
fileSecurity.In vokeMethod("Set SecurityDescrip tor", inParams, null);