Problem setting DACL on remote folder share using C# and Managment Space

B

Brian Hampson

I've swiped the following code pretty much directly from a technet
article, and modified it for my purposes. Something isn't working.

I'm trying to

1) create a share on a remote server (works)
2) Set an ACE on the SHARE of Full Control for CORP\Domain Admins
3) Set an ACE on the SHARE of Change for CORP\HelpDesks

When the code is done, there is an entry for full contol for System and
Administrators on the remote server - Nothing regarding what I actually
WANTED to add :(

Code:

private void ShareFolder(string path, string name, string
description)
{
//==0. Create Win32_Trustee
ManagementObject HDtrustee = new ManagementClass(new
ManagementPath("Win32_Trustee"), null);
HDtrustee["Domain"] = "CORP";
HDtrustee["Name"] = "HelpDesks";

ManagementObject Admintrustee = new ManagementClass(new
ManagementPath("Win32_Trustee"), null);
Admintrustee["Domain"] = "CORP";
Admintrustee["Name"] = "Domain Admins";

//==1. Create win32_ace
ManagementObject AdminACE = new ManagementClass(new
ManagementPath("Win32_Ace"), null);
AdminACE["AccessMask"] = AccessMasks.FullControl;
AdminACE["AceFlags"] = AceFlags.OBJECT_INHERIT_ACE |
AceFlags.CONTAINER_INHERIT_ACE;
AdminACE["AceType"] = AceType.Allow;
AdminACE["Trustee"] = Admintrustee;

ManagementObject HelpDeskACE = new ManagementClass(new
ManagementPath("Win32_Ace"), null);
HelpDeskACE["AccessMask"] = AccessMasks.Modify;
HelpDeskACE["AceFlags"] = AceFlags.OBJECT_INHERIT_ACE |
AceFlags.CONTAINER_INHERIT_ACE;
HelpDeskACE["AceType"] = AceType.Allow;
HelpDeskACE["Trustee"] = HDtrustee;


//==2. Create Win32_SecurityDescriptor
ManagementObject secDescriptor = new ManagementClass(new
ManagementPath("Win32_SecurityDescriptor"), null);
secDescriptor["ControlFlags"] = 4; //SE_DACL_PRESENT
//secDescriptor["DACL"] = new object[] { AdminACE };
secDescriptor["DACL"] = new object[] { HelpDeskACE,AdminACE
};

//==3. Using Win32_Share

ManagementClass classObj = new ManagementClass("\\\\" +
this.Server.Text + "\\root\\cimv2", "Win32_Share", null);
ManagementBaseObject inParams =
classObj.GetMethodParameters("Create");
inParams["Access"] = secDescriptor;
inParams["Description"] = description;
//inParams["MaximumAllowed"] = maxAllowed;
inParams["Name"] = name;
//inParams["Password"] = ""; //default is no password
inParams["Path"] = path;
inParams["Type"] = 0; //0: Disk Drive, 1: Print Queue ,2:
Device , 3: IPC

ManagementBaseObject outParams =
classObj.InvokeMethod("Create", inParams, null);
uint ret =
(uint)(outParams.Properties["ReturnValue"].Value);
}

Help?

Brian Hampson
System Administrator, North America
ALS Laboratory Group - Environmental Division
 
G

Guest

You need to supply the xxx["SID"] in addition to the Domain and Name
prooperties. I use the following line to define the "Everyone" SID:

EveryoneTrustee["SID"] = new uint[12] { 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 };



Brian Hampson said:
I've swiped the following code pretty much directly from a technet
article, and modified it for my purposes. Something isn't working.

I'm trying to

1) create a share on a remote server (works)
2) Set an ACE on the SHARE of Full Control for CORP\Domain Admins
3) Set an ACE on the SHARE of Change for CORP\HelpDesks

When the code is done, there is an entry for full contol for System and
Administrators on the remote server - Nothing regarding what I actually
WANTED to add :(

Code:

private void ShareFolder(string path, string name, string
description)
{
//==0. Create Win32_Trustee
ManagementObject HDtrustee = new ManagementClass(new
ManagementPath("Win32_Trustee"), null);
HDtrustee["Domain"] = "CORP";
HDtrustee["Name"] = "HelpDesks";

ManagementObject Admintrustee = new ManagementClass(new
ManagementPath("Win32_Trustee"), null);
Admintrustee["Domain"] = "CORP";
Admintrustee["Name"] = "Domain Admins";

//==1. Create win32_ace
ManagementObject AdminACE = new ManagementClass(new
ManagementPath("Win32_Ace"), null);
AdminACE["AccessMask"] = AccessMasks.FullControl;
AdminACE["AceFlags"] = AceFlags.OBJECT_INHERIT_ACE |
AceFlags.CONTAINER_INHERIT_ACE;
AdminACE["AceType"] = AceType.Allow;
AdminACE["Trustee"] = Admintrustee;

ManagementObject HelpDeskACE = new ManagementClass(new
ManagementPath("Win32_Ace"), null);
HelpDeskACE["AccessMask"] = AccessMasks.Modify;
HelpDeskACE["AceFlags"] = AceFlags.OBJECT_INHERIT_ACE |
AceFlags.CONTAINER_INHERIT_ACE;
HelpDeskACE["AceType"] = AceType.Allow;
HelpDeskACE["Trustee"] = HDtrustee;


//==2. Create Win32_SecurityDescriptor
ManagementObject secDescriptor = new ManagementClass(new
ManagementPath("Win32_SecurityDescriptor"), null);
secDescriptor["ControlFlags"] = 4; //SE_DACL_PRESENT
//secDescriptor["DACL"] = new object[] { AdminACE };
secDescriptor["DACL"] = new object[] { HelpDeskACE,AdminACE
};

//==3. Using Win32_Share

ManagementClass classObj = new ManagementClass("\\\\" +
this.Server.Text + "\\root\\cimv2", "Win32_Share", null);
ManagementBaseObject inParams =
classObj.GetMethodParameters("Create");
inParams["Access"] = secDescriptor;
inParams["Description"] = description;
//inParams["MaximumAllowed"] = maxAllowed;
inParams["Name"] = name;
//inParams["Password"] = ""; //default is no password
inParams["Path"] = path;
inParams["Type"] = 0; //0: Disk Drive, 1: Print Queue ,2:
Device , 3: IPC

ManagementBaseObject outParams =
classObj.InvokeMethod("Create", inParams, null);
uint ret =
(uint)(outParams.Properties["ReturnValue"].Value);
}

Help?

Brian Hampson
System Administrator, North America
ALS Laboratory Group - Environmental Division
 
B

Brian Hampson

So, How can I get the SID of the user (in a bytearray format) given
that I know the name and domain?
You need to supply the xxx["SID"] in addition to the Domain and Name
prooperties. I use the following line to define the "Everyone" SID:

EveryoneTrustee["SID"] = new uint[12] { 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 };



Brian Hampson said:
I've swiped the following code pretty much directly from a technet
article, and modified it for my purposes. Something isn't working.

I'm trying to

1) create a share on a remote server (works)
2) Set an ACE on the SHARE of Full Control for CORP\Domain Admins
3) Set an ACE on the SHARE of Change for CORP\HelpDesks

When the code is done, there is an entry for full contol for System and
Administrators on the remote server - Nothing regarding what I actually
WANTED to add :(

Code:

private void ShareFolder(string path, string name, string
description)
{
//==0. Create Win32_Trustee
ManagementObject HDtrustee = new ManagementClass(new
ManagementPath("Win32_Trustee"), null);
HDtrustee["Domain"] = "CORP";
HDtrustee["Name"] = "HelpDesks";

ManagementObject Admintrustee = new ManagementClass(new
ManagementPath("Win32_Trustee"), null);
Admintrustee["Domain"] = "CORP";
Admintrustee["Name"] = "Domain Admins";

//==1. Create win32_ace
ManagementObject AdminACE = new ManagementClass(new
ManagementPath("Win32_Ace"), null);
AdminACE["AccessMask"] = AccessMasks.FullControl;
AdminACE["AceFlags"] = AceFlags.OBJECT_INHERIT_ACE |
AceFlags.CONTAINER_INHERIT_ACE;
AdminACE["AceType"] = AceType.Allow;
AdminACE["Trustee"] = Admintrustee;

ManagementObject HelpDeskACE = new ManagementClass(new
ManagementPath("Win32_Ace"), null);
HelpDeskACE["AccessMask"] = AccessMasks.Modify;
HelpDeskACE["AceFlags"] = AceFlags.OBJECT_INHERIT_ACE |
AceFlags.CONTAINER_INHERIT_ACE;
HelpDeskACE["AceType"] = AceType.Allow;
HelpDeskACE["Trustee"] = HDtrustee;


//==2. Create Win32_SecurityDescriptor
ManagementObject secDescriptor = new ManagementClass(new
ManagementPath("Win32_SecurityDescriptor"), null);
secDescriptor["ControlFlags"] = 4; //SE_DACL_PRESENT
//secDescriptor["DACL"] = new object[] { AdminACE };
secDescriptor["DACL"] = new object[] { HelpDeskACE,AdminACE
};

//==3. Using Win32_Share

ManagementClass classObj = new ManagementClass("\\\\" +
this.Server.Text + "\\root\\cimv2", "Win32_Share", null);
ManagementBaseObject inParams =
classObj.GetMethodParameters("Create");
inParams["Access"] = secDescriptor;
inParams["Description"] = description;
//inParams["MaximumAllowed"] = maxAllowed;
inParams["Name"] = name;
//inParams["Password"] = ""; //default is no password
inParams["Path"] = path;
inParams["Type"] = 0; //0: Disk Drive, 1: Print Queue ,2:
Device , 3: IPC

ManagementBaseObject outParams =
classObj.InvokeMethod("Create", inParams, null);
uint ret =
(uint)(outParams.Properties["ReturnValue"].Value);
}

Help?

Brian Hampson
System Administrator, North America
ALS Laboratory Group - Environmental Division
 
G

Guest

You can use the following code:

using System.Security.Principal;

NTAccount ntAccount = new NTAccount("Everyone"); // or whatever account you
will grant access
SecurityIdentifier sid = (SecurityIdentifier)ntAccount
..Translate(typeof(SecurityIdentifier));
byte[] sidArray = new byte[sid.BinaryLength];
sid.GetBinaryForm(sidArray , 0);
ManagementObject Trustee = new ManagementClass(new
ManagementPath("Win32_Trustee"), null);
Trustee["SID"] = sidArray ;

When specifying the SID this way, neither the ["Domain"] nor the ["Name"]
properties are needed. I have not experienced that the ["SIDLength"] is ever
needed.

If the NTAccount constructor is not specifying a domain, the SAM on the
local system will be used.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top