Tech Off Thread

14 posts

Set IIsWebDirectory Permissions via WMI in C#

Back to Forum: Tech Off
  • User profile image
    mrichman

    Let's say I just uploaded a directory structure to my website under W3SVC/123456/Root/foo/bar/baz. The metabase only contains an entry for W3SVC/123456/Root. How do I set IIS permissions (i.e. AuthAnonymous) on /foo/bar/baz given there is no metabase key for that IIsWebDirectory yet.

    Any attempt at referencing the following produces an "Invalid Object"
    ManagementException:

    IIsWebDirectorySetting="W3SVC/123456/Root/foo/bar/baz"

    Looking for examples using WMI in C#. No ADSI or VBScript please.

  • User profile image
    jrg

    Hehe, yeah, this is a fun one.

    First, there is a utility (vbscript) available to help you set permissions:
    http://support.microsoft.com/kb/267904

    Second, if you can avoid using anonymous access, that's best.  Use impersonation to tell your ASP code "act like the user that is using this".

    I just saw your "NO VBSCRIPT" comment... sorry about that.

    I was looking at this exact problem about a month ago because I wanted to stay away from scripts as well.  P-Invoke is an ugly but sometimes necessary approach when it comes to ACE/ACL.  I know Microsoft is adding new permission toys in 2.0.

    This may be of help:
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/setting_user_security.asp
    "Note  A NULL ACL in the SECURITY_DESCRIPTOR grants unlimited access to everyone all the time. For more information about the implications of unlimited access, see Creating a Security Descriptor for a New Object."

    <still looking for a better answer... will revise this in a few.. I want to know as well Smiley>

  • User profile image
    mrichman

    Actually, my question has nothing to do with ACLs at all. I am interested in setting the following properties:

    IIsWebDirectory.AccessRead
    IIsWebDirectory.AccessScript
    IIsWebDirectory.AccessExecute
    IIsWebDirectory.EnableDirBrowsing
    IIsWebDirectory.AuthAnonymous

    Thanks,
    Mark

  • User profile image
    jrg

    Hi Mark,

    Sorry about the wrong tangent! Smiley

    You'd like to set up an IIS virtual directory through C# and WMI and have the operation perform just like you were doing mmc configuration of a new virtual directory?

  • User profile image
    mrichman

    This would be a physical path, not a virtual. IIsWebDirectory is for physical paths off the site root, IIsWebVirtualDir would be for virtuals.

    Thanks again,
    Mark

  • User profile image
    jrg

    Are you on IIS 6.0?

  • User profile image
    mrichman

    I sure am!

    Here is an abbreviated example of the code I am wrestling with:

    ConnectionOptions connection = new ConnectionOptions();
    ManagementScope scope = new ManagementScope(@"\\localhost\root\MicrosoftIISV2", connection);
    scope.Connect();

    string mpath = "IIsWebDirectorySetting='W3SVC/" + siteIndex + "/ROOT" + path + "'"; // path is "/foo/bar" for example    
    ManagementPath mp = new ManagementPath(mpath);
            
    ManagementObject dir = new ManagementObject(scope, mp, null);

    dir.SetPropertyValue("AuthAnonymous", false);
    dir.SetPropertyValue("AccessRead", true);
    dir.SetPropertyValue("AccessScript", true);
    dir.SetPropertyValue("EnableDirBrowsing", false);
    dir.Put();

    That last Put() command is what throws the "Invalid Object" exception on me.

    Thanks,
    Mark

  • User profile image
    jrg

    I'm doing a compare and contrast with your code and some Microsoft example code in VBScript:
    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/iissdk/html/504d8e75-4a12-433b-8894-ac7fd414a634.asp

    I know the following is using IIsWebVirtualDirectory rather than IIsWebDirectory but the concept should still be valid:

    const APP_POOLED = 2 
    var strNewVdir
    strNewVdir = "W3SVC/1/Root/newVdir"

    ' Make connections to WMI, to the IIS namespace on MyMachine.
    set locatorObj = CreateObject("WbemScripting.SWbemLocator")
    set providerObj = locatorObj.ConnectServer("MyMachine", "root/MicrosoftIISv2")

    ' Add a virtual directory to the site. This requires SpawnInstance().
    Set vdirClassObj = providerObj.Get("IIsWebVirtualDirSetting")
    Set vdirObj = vdirClassObj.SpawnInstance_()
    vdirObj.Name = strNewVdir
    vdirObj.Path = "C:\Inetpub\Wwwroot"
    vdirObj.AuthFlags = 5 ' AuthNTLM + AuthAnonymous
    vdirObj.EnableDefaultDoc = True
    vdirObj.DirBrowseFlags = &H4000003E ' date, time, size, extension, longdate
    vdirObj.AccessFlags = 513 ' read, script

    ' Save the new settings to the metabase
    vdirObj.Put_()

    ' Create a pooled application on the new virtual directory.
    Set vdirObj = providerObj.Get("IIsWebVirtualDir='" & strNewVdir & "'")
    vdirObj.AppCreate2(2)

    ' Set the application name.
    Set vdirObj = providerObj.Get("IIsWebVirtualDirSetting='" & strNewVdir & "'")
    vdirObj.AppFriendlyName = "Root Application"
    vdirObj.Put_()
    "SpawnInstance()" sticks out as something to research as they say it is "required" which tells me it can be a sticky point.  It appears that they create the object without yet giving the path... just create an IIsWebDirectorySetting object first, no path.  Next, on your object, set the properties.  I'm not set up to test this so forgive me if this is getting off base.  Once you've set your properties, including a path and name, then you may find it does the Put properly.

  • User profile image
    mrichman

    Yeah, that's pretty much equivalent to this piece of code, which also fails with the same error:

    ManagementClass clsIIsWebDirectorySetting = new ManagementClass(scope, new ManagementPath("IIsWebDirectorySetting"), null);
    ManagementObject dir = clsIIsWebDirectorySetting.CreateInstance();
    dir.Properties["Name"].Value = "W3SVC/" + account + "/ROOT" + path;
    dir.Put();

    If I try the VBScript version of this, I also get "Invalid Object":

    strNewVdir = "W3SVC/666666/Root/foo/bar"
     
    ' Make connections to WMI, to the IIS namespace on MyMachine.
    set locatorObj = CreateObject("WbemScripting.SWbemLocator")
    set providerObj = locatorObj.ConnectServer("localhost", "root/MicrosoftIISv2")
     
    ' Add a virtual directory to the site. This requires SpawnInstance().
    Set vdirClassObj = providerObj.Get("IIsWebDirectorySetting")
    Set vdirObj = vdirClassObj.SpawnInstance_()
    vdirObj.Name = strNewVdir
    vdirObj.AuthFlags = 5 ' AuthNTLM + AuthAnonymous
    vdirObj.EnableDefaultDoc = True
    vdirObj.DirBrowseFlags = &H4000003E ' date, time, size, extension, longdate
    vdirObj.AccessFlags = 513 ' read, script
     
    ' Save the new settings to the metabase
    vdirObj.Put_()

    So clearly, this is not a C# issue, so maybe I'm just using WMI the wrong way!

    Arrrgh!

    - Mark

  • User profile image
    mrichman

    Yet another setback I discovered is that to create a Metabase entry for /foo/bar, its parent key /foo must exist.

    Looks like I need to create a recursive method for creating a key if and only if its parent exists (creating the parent key if not there).

    Kill me now please.

  • User profile image
    Maurits

    mrichman wrote:
    Yet another setback I discovered is that to create a Metabase entry for /foo/bar, its parent key /foo must exist.


    I was going to suggest this after initially reading the thread... but I thought "nah, that's too easy"

    Guess sometimes it's the simple things...

  • User profile image
    jrg

    mrichman wrote:
    Yet another setback I discovered is that to create a Metabase entry for /foo/bar, its parent key /foo must exist.

    Looks like I need to create a recursive method for creating a key if and only if its parent exists (creating the parent key if not there).

    Kill me now please.


    Copyright your problem and solution before it becomes the next Microsoft interview question! Tongue Out

    "Umm, let me think, string path = "some/path"; string [] pathParts = path.Split('/');  recursiveFunction(rootPath, pathParts, 0)..."

  • User profile image
    mrichman

    That's really scary -- I used the same variable names.

    Great minds think alike.

    I got it to work, by the way.

    - Mark

  • User profile image
    Aranda

    Hi All,

    I'm having the exact same problem! Just wondering if you can point me to some more information about how to create the metabase keys?

    I don't need the recursive trick, I just need to set the AuthAnonymous property on a sub directory of a virtual directory, but i can't actually get a reference to the sub directory until i've manually edited the properties on the sub dir....  [C]

    Thanks!

Comments closed

Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums, or Contact Us and let us know.