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\Inetpub\Websites\LocalUser\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 ManagementException 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.RelativePath = @"Win32_LogicalFileSecuritySetting.Path="
+ "'" + fileName + "'";
ManagementObject fileSecurity = new ManagementObject(
scope, path, null);
// When used with UNC path, exception with "Not Found" is thrown.
ManagementBaseObject outParams =
(ManagementBaseObject)fileSecurity.InvokeMethod(
"GetSecurityDescriptor", null, null);
// Get security descriptor and DACL for specified file.
ManagementBaseObject descriptor =
(ManagementBaseObject)outParams.Properties["Descriptor"].Value;
ManagementBaseObject[] dacl =
(ManagementBaseObject[])descriptor.Properties["Dacl"].Value;
// Get the user account to be trustee.
ManagementObject userAccount = new ManagementClass(scope,
new ManagementPath("Win32_Trustee"), null);
userAccount.Properties["Name"].Value = account;
// Create a new ACE for the descriptor.
ManagementObject newAce = new ManagementClass(scope,
new ManagementPath("Win32_ACE"), null);
newAce.Properties["Trustee"].Value = userAccount;
// Low level ace flags.
int FILE_READ_DATA = 0x0;
int FILE_WRITE_DATA = 0x1;
int FILE_APPEND_DATA = 0x4;
int DELETE = 0x10000;
// Translate FileSystemRights to flags.
switch (accessRights)
{
case FileSystemRights.Read:
newAce.Properties["AccessMask"].Value = FILE_READ_DATA;
break;
case FileSystemRights.Modify:
newAce.Properties["AccessMask"].Value = FILE_READ_DATA
| FILE_WRITE_DATA | FILE_APPEND_DATA | DELETE;
break;
}
// ACL will be inherited.
newAce.Properties["AceFlags"].Value = 0x10;
// Allow access to resource.
newAce.Properties["AceType"].Value = 0;
// Add ACE to DACL and set to descriptor.
ArrayList daclArray = new ArrayList(dacl);
daclArray.Add(newAce);
descriptor.Properties["Dacl"].Value = daclArray.ToArray();
// User SetSecurityDescriptor to apply the descriptor.
ManagementBaseObject inParams =
fileSecurity.GetMethodParameters("SetSecurityDescriptor");
inParams["Descriptor"] = descriptor;
fileSecurity.InvokeMethod("SetSecurityDescriptor", inParams, null);
If you need to set the ACL's on the "share" you need to query the share
using it's name and look for it's associated
Win32_LogicalShareSecuritySetting. Once you have this one you can set the
security for the share using the same technique as for a local filz objzct.
Willy.
<ma...@rensoft.net> wrote in message
news:1136908463....@g43g2000cwa.googlegroups.com...
Sorry, I just realised that share security exists as well as file
security. I actually meant altering a Win32_LogicalFileSecuritySetting
through a UNC path.
I'm trying to produce the software in such a way that it will run
completely over UNC and not local file paths. This is so I can develop
on a workstation using a virtual server for testing. But then, roll the
application out on to a production server. I'd like to avoid using
local file paths to keep everything simple... Is a good idea?
Also, I tried accessing the Win32_LogicalFileSecuritySetting via a UNC
path, without specifying a server and it threw the same "Not Found"
error as before.
Perhaps you could show me a snippet of code to enumerate the DACL via a
UNC path?
Thanks Willy.
Nick