IIS ADSI virtual dir creation problem from web application

Discussion in 'ASP .Net Security' started by Gabriel R, Nov 25, 2004.

  1. Gabriel R

    Gabriel R Guest

    I am trying to create a virtual directory using ADSI, with the following
    C# code:

    string Server = <srv>;
    string ApplicationName = <app>;
    DirectoryEntry root = new DirectoryEntry("IIS://" + Server +
    "/W3SVC/1/Root", adminusername, adminuserpass);
    // look up the virtual dir
    DirectoryEntry app = null;
    foreach (DirectoryEntry e in root.Children)
    {
    if (e.SchemaClassName == "IISWebVirtualDir" && e.Name.ToUpper() ==
    ApplicationName.ToUpper())
    {
    app = e; break;
    }
    }
    if (app == null)
    {
    // create the virtual dir
    app = root.Children.Add(ApplicationName, "IISWebVirtualDir");
    }
    // create the application attached to it
    app.Invoke("AppCreate", false);
    // set the properties of the virtual dir
    app.Properties["Path"][0] = "D:\\Web";
    app.Properties["DefaultDoc"][0] = "default.aspx";
    app.Properties["AppFriendlyName"][0] = ApplicationName;
    app.CommitChanges();

    The code works fine if I run it from a Windows Forms application,
    however if it's run from a web application I get a COMException: Access
    denied.
    The web application runs under the credentials of the admin user (I used
    <identity impersonate=true ...> in web.config).

    How could I solve this problem?

    Gabriel

    *** Sent via Developersdex http://www.developersdex.com ***
    Don't just participate in USENET...get rewarded for it!
     
    Gabriel R, Nov 25, 2004
    #1
    1. Advertising

  2. One thing to know about the IIS provider is that it doesn't respect the
    username and password properties. It always uses the security context of
    the current thread. Therefore, you need to make sure you change that
    instead. I'm not sure why this isn't welll documented or doesn't throw an
    exception, but that's the way it is.

    Joe K.

    "Gabriel R" <> wrote in message
    news:%...
    >I am trying to create a virtual directory using ADSI, with the following
    > C# code:
    >
    > string Server = <srv>;
    > string ApplicationName = <app>;
    > DirectoryEntry root = new DirectoryEntry("IIS://" + Server +
    > "/W3SVC/1/Root", adminusername, adminuserpass);
    > // look up the virtual dir
    > DirectoryEntry app = null;
    > foreach (DirectoryEntry e in root.Children)
    > {
    > if (e.SchemaClassName == "IISWebVirtualDir" && e.Name.ToUpper() ==
    > ApplicationName.ToUpper())
    > {
    > app = e; break;
    > }
    > }
    > if (app == null)
    > {
    > // create the virtual dir
    > app = root.Children.Add(ApplicationName, "IISWebVirtualDir");
    > }
    > // create the application attached to it
    > app.Invoke("AppCreate", false);
    > // set the properties of the virtual dir
    > app.Properties["Path"][0] = "D:\\Web";
    > app.Properties["DefaultDoc"][0] = "default.aspx";
    > app.Properties["AppFriendlyName"][0] = ApplicationName;
    > app.CommitChanges();
    >
    > The code works fine if I run it from a Windows Forms application,
    > however if it's run from a web application I get a COMException: Access
    > denied.
    > The web application runs under the credentials of the admin user (I used
    > <identity impersonate=true ...> in web.config).
    >
    > How could I solve this problem?
    >
    > Gabriel
    >
    > *** Sent via Developersdex http://www.developersdex.com ***
    > Don't just participate in USENET...get rewarded for it!
     
    Joe Kaplan \(MVP - ADSI\), Nov 25, 2004
    #2
    1. Advertising

  3. I'd suggest using the sample code that MS publishes for programmatic
    impersonation:

    http://msdn.microsoft.com/library/d...ImpersonationContextClassTopic.asp?frame=true

    It has the benefit of some nicer error handling which might help explain
    what didn't work on 2000 or 2003. Essentially, they should both work fine.
    However, you do need "Act as part of the operating system" privilege to call
    LogonUser under Windows 2000 which might be a deal breaker.

    The other option is putting the code in a COM+ component and running that
    under the identity you need to manage the server(s).

    Another option might be to look at the WMI provider for IIS instead of ADSI.
    It might give you more flexibility (although I don't know anything about
    it).

    HTH,

    Joe K.

    "Gabriel R via DotNetMonster.com" <> wrote in message
    news:...
    >I have tried to run the code impersonated (first calling
    >impersonateValidUser then, after everything's done, undoImpersonation). I
    >have used:
    >
    > #region setup impersonation via interop
    > public const int LOGON32_LOGON_INTERACTIVE = 2;
    > public const int LOGON32_PROVIDER_DEFAULT = 0;
    > static System.Security.Principal.WindowsImpersonationContext
    > impersonationContext;
    >
    > [DllImport("advapi32.dll", CharSet=CharSet.Auto)]public static extern int
    > LogonUser(String lpszUserName, String lpszDomain,String lpszPassword,int
    > dwLogonType, int dwLogonProvider,ref IntPtr phToken);
    > [DllImport("advapi32.dll",
    > CharSet=System.Runtime.InteropServices.CharSet.Auto,
    > SetLastError=true)]public extern static int DuplicateToken(IntPtr hToken,
    > int impersonationLevel, ref IntPtr hNewToken);
    > #endregion
    >
    > #region impersonation methods
    > private static bool impersonateValidUser(String userName, String domain,
    > String password)
    > {
    > WindowsIdentity tempWindowsIdentity;
    > IntPtr token = IntPtr.Zero;
    > IntPtr tokenDuplicate = IntPtr.Zero;
    >
    > // try raw impersonation (username, pass)
    > if (LogonUser(userName, domain, password, LOGON32_LOGON_INTERACTIVE,
    > LOGON32_PROVIDER_DEFAULT, ref token) == 0)
    > return false;
    >
    > // duplicate the token and use it for impersonation
    > if (DuplicateToken(token, 2, ref tokenDuplicate) != 0)
    > {
    > tempWindowsIdentity = new WindowsIdentity(tokenDuplicate);
    > impersonationContext = tempWindowsIdentity.Impersonate();
    > if (impersonationContext != null) return true;
    > else return false;
    > }
    > else return false;
    > }
    >
    > private static void undoImpersonation()
    > {
    > impersonationContext.Undo();
    > }
    > #endregion
    >
    > What's interesting is that it works fine on IIS 5.1 (WinXP), but it
    > wouldn't work on IIS 5 (Win2k) or IIS 6 (Win2003). However, if run from a
    > Windows Forms application, it works on all machines.
    >
    > Is there another way to impersonate the current thread (apart from the
    > functions I used from advapi32.dll)?
    >
    > Thanks,
    > Gabriel
    >
    > --
    > Message posted via http://www.dotnetmonster.com
     
    Joe Kaplan \(MVP - ADSI\), Dec 2, 2004
    #3
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Drew Berkemeyer

    installing virtual dir in IIS problem

    Drew Berkemeyer, Dec 3, 2004, in forum: ASP .Net
    Replies:
    0
    Views:
    396
    Drew Berkemeyer
    Dec 3, 2004
  2. =?Utf-8?B?UnVkeQ==?=

    Sub Dir, Virtual dir, what do I use?

    =?Utf-8?B?UnVkeQ==?=, Jun 12, 2005, in forum: ASP .Net
    Replies:
    0
    Views:
    438
    =?Utf-8?B?UnVkeQ==?=
    Jun 12, 2005
  3. scott
    Replies:
    1
    Views:
    1,076
    scott
    Jun 12, 2006
  4. Peter Maas

    module not found in IIS virtual dir

    Peter Maas, Aug 31, 2005, in forum: Python
    Replies:
    1
    Views:
    294
    Peter Maas
    Aug 31, 2005
  5. Odie
    Replies:
    1
    Views:
    127
    joker
    Aug 21, 2004
Loading...

Share This Page