Creating File Shares using the System.Management class

G

Guest

I am attempting to create a local share on a Win XP (SP1) computer using the
..NET 2 framework and the System.Mangement class.

- Create the share based on a directory
- Assign a specific set of permissions to the share.

I know this is possible using WMI as I have a VBScript that does exactly
that. The equivalent C# code creates the share correctly but does not assign
any permissions. I have local admin rights on the target machine. Any help on
this issue would be appreciated. I include first the C# console application
code that does not work and then the VBScript that does. I could shell out to
the VB script but in the first instance I would like a complete .NET solution.

To reiterate the versions:
Windows XP SP1
Visual Studio 2005 Console App using V2 of the framework (I have tried 1.1
and it has the same problem)
Interactive account on the target machine has local admin privileges.

1. C# Code

using System;
using System.Management;
using System.Security.Principal;

namespace Console2005
{
class Program
{
static void Main(string[] args)
{
// Create a ManagementPath and scope object that will control
the creating of the share
ManagementPath path = new ManagementPath();
path.Server = "lonmw44635"; // Change this to be the machine
name of the local computer
path.NamespacePath = @"root\CIMV2";
ManagementScope scope = new ManagementScope(path);

NTAccount ntAccount = new NTAccount("BUILTIN", "GUESTS");
SecurityIdentifier sid =
(SecurityIdentifier)ntAccount.Translate(typeof(SecurityIdentifier));
byte[] sidArray = new byte[sid.BinaryLength];
sid.GetBinaryForm(sidArray , 0);

//ManagementObject to represent the group to be added as a trustee
ManagementObject newGroup = new ManagementClass(scope,
new ManagementPath("Win32_Trustee"), null).CreateInstance();
newGroup["Domain"] = "BUILTIN";
newGroup["Name"] = "GUESTS";
newGroup["SID"] = sidArray;

// ManagementObject to represent the new group to add to the
acle of the share
ManagementObject aceGroup = new ManagementClass(scope,
new ManagementPath("Win32_ACE"), null).CreateInstance();
aceGroup["AccessMask"] = 2032127;
aceGroup["AceFlags"] = 3;
aceGroup["AceType"] = 0;
aceGroup["Trustee"] = newGroup;

// Management class to modify the ACL
ManagementObject secDescriptor = new ManagementClass(scope,
new ManagementPath("Win32_SecurityDescriptor"),
null).CreateInstance();
secDescriptor["ControlFlags"] = 4;
secDescriptor["DACL"] = new ManagementObject[] { aceGroup };

// Management class to modify creation of the share itself
ManagementObject mc = new
System.Management.ManagementClass(scope,
new ManagementPath("Win32_Share"), null);

System.Management.ManagementBaseObject inParams =
mc.GetMethodParameters("Create");
inParams["Path"] = @"c:\ShareTest";
inParams["Name"] = "ShareTest";
inParams["Type"] = 0;
inParams["Access"] = secDescriptor;
inParams["Description"] = "Test";
inParams["Access"] = null;

System.Management.ManagementBaseObject mbo =
mc.InvokeMethod("Create", inParams, null);
uint result = (uint)mbo.Properties["ReturnValue"].Value;
// 0 = success

Console.ReadLine();
}
}
}

2. VB Script

'*** You should substitute the name of the remote system for
"\\lonmw44635" ***
Set objservices = GetObject("WINMGMTS:" _
&
"{impersonationLevel=impersonate,(Security)}" _
& "!\\lonmw44635\ROOT\CIMV2")

'*** Get the Win32_SecurityDescriptor class and spawn a new instance
****
Set objclass = objservices.Get("Win32_SecurityDescriptor")
Set objSecDescriptor = objclass.SpawnInstance_()

'****** Prepare the security descriptor for the new share ******
objSecDescriptor.Properties_.Item("ControlFlags") = 4
Set ACE1 = SetACE(objservices, 2032127, _
3, _
0, _
SetTrustee(objservices, "BUILTIN", _
"GUESTS", _
Array(1, 5, 0, 0, 0, 0, 0, 5, 21, _
0, 0, 0, 160, 101, 207, 126, _
120, 75, 155, 95, 231, 124, _
135, 112, 119, 238, 0, 0)))

objSecDescriptor.Properties_.Item("DACL") = Array(ACE1)


'************************ Create the new share *********************

Set objShare = objservices.Get("Win32_Share")
Set objInParam = objShare.Methods_("Create").InParameters.SpawnInstance_()
objInParam.Properties_.Item("Access") = objSecDescriptor
objInParam.Properties_.Item("Description") = "New share created by WMI
script"
objInParam.Properties_.Item("Name") = "ShareTest"
objInParam.Properties_.Item("Path") = "C:\ShareTest"
objInParam.Properties_.Item("Type") = 0



'************************ Execute the method **********************
Set objOutParams = objShare.ExecMethod_("Create", objInParam)
If objOutParams.ReturnValue = 0 Then
wscript.echo "Share created successfully"
Else
If objOutParams.ReturnValue = 22 Then
wscript.echo "Share may already exist"
Else
wscript.echo "Unable to create share, return value was : " _
& objOutParams.ReturnValue
End If
End If

'************************* HELPER FUNCTIONS *********************
Function SetTrustee(objservices, strDomain, strName, SID)
Set objTrustee = objservices.Get("Win32_Trustee").SpawnInstance_
objTrustee.Domain = strDomain
objTrustee.Name = strName
objTrustee.Properties_.Item("SID") = SID
Set SetTrustee = objTrustee
End Function

Function SetACE(objservices, AccessMask, AceFlags, AceType, objTrustee)
Set objAce = objservices.Get("Win32_Ace").SpawnInstance_
objAce.Properties_.Item("AccessMask") = AccessMask
objAce.Properties_.Item("AceFlags") = AceFlags
objAce.Properties_.Item("AceType") = AceType
objAce.Properties_.Item("Trustee") = objTrustee
Set SetACE = objAce
End Function
 

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