Home All Groups Group Topic Archive Search About

Impersonation problem

Author
25 Jul 2006 9:36 AM
dodot63
Hi there,

I'm trying to create Windows users in my NT4 domain using ADSI, from a
web application (ASPX / VB / framework version 1.1). I am using
Web.config to impersonate an admin account :

        <identity impersonate="true" userName="the-domain\the-admin"
password="the-password" />

Then, just before the user creation, I'm checking my identity with :

        Security.Principal.WindowsIdentity.GetCurrent.Name

which returns "the-domain\the-admin". Everything works as expected. But
when I'm trying to create the user :

        Dim objDomain As IADsContainer = GetObject("WinNT://" & domain)
        Dim objUser As IADsUser = objDomain.Create("User", userName)
        objUser.FullName = fullName
        objUser.Description = description
        objUser.LoginScript = loginScript
        objUser.Profile = profilePath
        objUser.SetInfo()       ' <== exception thrown here
        If Not password Is Nothing Then
            objUser.SetPassword(password)
            objUser.SetInfo()
        End If

I have a nice UnauthorizedAccessException thrown. You will answer :
"your admin isn't admin !"... It is. Using the same account, I can
create users from the Windows User Manager.

The funny part is that very code used to work before I started to play
with the web app authentication options : I wanted to use a Form
authentication and then to impersonate my admin account but it didn't
work. Since I came back to the old version, it refuses to let me create
Windows users.

I have tried many things but I always get the same result. I'm stuck
with that sh*t.

Any idea would be greatly appreciated.

Author
25 Jul 2006 10:38 AM
Dominick Baier
I guess this is a delegation problem - Joe will know more i am sure.

Is this IIS6 ?

If yes and you really need this elevated privs - you better create a separate
app pool with the admin's identity and properly lock access to the app down.

dominick

Show quoteHide quote
> Hi there,
>
> I'm trying to create Windows users in my NT4 domain using ADSI, from a
> web application (ASPX / VB / framework version 1.1). I am using
> Web.config to impersonate an admin account :
>
> <identity impersonate="true" userName="the-domain\the-admin"
> password="the-password" />
>
> Then, just before the user creation, I'm checking my identity with :
>
> Security.Principal.WindowsIdentity.GetCurrent.Name
>
> which returns "the-domain\the-admin". Everything works as expected.
> But when I'm trying to create the user :
>
> Dim objDomain As IADsContainer = GetObject("WinNT://" &
> domain)
> Dim objUser As IADsUser = objDomain.Create("User", userName)
> objUser.FullName = fullName
> objUser.Description = description
> objUser.LoginScript = loginScript
> objUser.Profile = profilePath
> objUser.SetInfo()       ' <== exception thrown here
> If Not password Is Nothing Then
> objUser.SetPassword(password)
> objUser.SetInfo()
> End If
> I have a nice UnauthorizedAccessException thrown. You will answer :
> "your admin isn't admin !"... It is. Using the same account, I can
> create users from the Windows User Manager.
>
> The funny part is that very code used to work before I started to play
> with the web app authentication options : I wanted to use a Form
> authentication and then to impersonate my admin account but it didn't
> work. Since I came back to the old version, it refuses to let me
> create Windows users.
>
> I have tried many things but I always get the same result. I'm stuck
> with that sh*t.
>
> Any idea would be greatly appreciated.
>
Author
25 Jul 2006 11:44 AM
Dodot63
Dominick,

Thanks for your answer. I'm using IIS 5 on my desktop with Win XP. It
seems that even if the thread owner is the admin account, the ADSI code
is executed without admin privileges. Can this be related to the
delegation problem you're talking about?

I am going to google for impersonation+delegation, hope I will find
something useful...



Dominick Baier wrote:
Show quoteHide quote
> I guess this is a delegation problem - Joe will know more i am sure.
>
> Is this IIS6 ?
>
> If yes and you really need this elevated privs - you better create a separate
> app pool with the admin's identity and properly lock access to the app down.
>
> dominick
Author
25 Jul 2006 12:41 PM
Dodot63
I GOT IT !

Let me explain the whole thing.

I want my app to run as admin, but I also want to authenticate the user
with a form. I have tried :

<authentication mode="Forms">
  <forms name="huhu" loginUrl="login.aspx" protection="all"
timeout="30" path="/">
</authentication>

<identity impersonate="true" userName="the-domain\the-admin"
password="the-password" />

But the impersonation didn't work. Don't know why. So now I'm using :

<authentication mode="Windows" />
<identity impersonate="true" userName="the-domain\the-admin"
password="the-password" />

And I'm checking the user authentication by myself, using... ADSI ! To
check the user's password, I'm trying the following:

    Public Shared Function TestUserPassword(ByVal domain As String,
ByVal userName As String, ByVal password As String)
        Dim testUser As DirectoryEntry = New DirectoryEntry("WinNT://"
& domain & "/" & userName & ",User", userName, password)
        Try
            Dim testUserName As String = testUser.Name
        Catch ex As System.Runtime.InteropServices.COMException
            Return False
        End Try
        Return True
    End Function

(if anyone knows a better way with a NT4 domain, I'll take it)

Note that I'm trying to connect to ADSI using the username and
password. The point is if this is successful, ADSI keeps the username
in memory for the next calls!

So after that, when I call :

    Dim objDomain As IADsContainer = GetObject("WinNT://" & domain)

I'm not connecting with the thread owner, but with the user account!
Replacing the GetObject call by a DirectoryEntry will solve the problem
:)

Good to know!
Author
25 Jul 2006 12:55 PM
Dodot63
I just wanted to add a little conclusion:

1. Don't use GetObject.

2. Don't follow my example, impersonating an admin for an entire app
isn't a good idea!

;)
Author
25 Jul 2006 1:35 PM
Dominick Baier
right :))



Show quoteHide quote
> I just wanted to add a little conclusion:
>
> 1. Don't use GetObject.
>
> 2. Don't follow my example, impersonating an admin for an entire app
> isn't a good idea!
>
> ;)
>
Author
25 Jul 2006 2:33 PM
Joe Kaplan (MVP - ADSI)
Why use WinNT also?  Creating users for an NT 4 domain?  You should always
use LDAP when working with AD.

AD also allows you to just pass the credentials you want to use into your
DirectoryEntry directly and works just fine that way.

Joe K.

--
Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.directoryprogramming.net
--
Show quoteHide quote
"Dodot63" <dodo***@gmail.com> wrote in message
news:1153832132.600734.177800@b28g2000cwb.googlegroups.com...
>I just wanted to add a little conclusion:
>
> 1. Don't use GetObject.
>
> 2. Don't follow my example, impersonating an admin for an entire app
> isn't a good idea!
>
> ;)
>
Author
26 Jul 2006 7:56 AM
Dodot63
As I said, I'm in a NT4 domain. Otherwise I agree that the LDAP
provider has to be preferred. In my opinion, the GetObject function is
designed for scripts, and DirectoryEntry for programs. Note that with
any provider, WinNT or LDAP, you can specify the username and password
in the DirectoryEntry constructor.
Author
26 Jul 2006 2:22 PM
Joe Kaplan (MVP - ADSI)
Sorry I missed the NT4 domain bit.  You have my sincere condolences.  :)

The statement about any provider being able to take credentials is not
really true.  In fact, the IIS provider (for changing the IIS metabase) does
not support this at all.  The WinNT provider is also known to be flakey when
supplying credentials.  It doesn't always work.  If it is working for you,
then that's good, but be aware that you may get some unexpected results
somewhere.

LDAP is generally very solid when it comes to taking credentials, and the
protocol itself is designed to work this way.

I agree on your other points.  GetObject in .NET is supplied strictly for
backwards compat with VB6 converted code.  .NET devs should use S.DS.

Joe K.

--
Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.directoryprogramming.net
--
Show quoteHide quote
"Dodot63" <dodo***@gmail.com> wrote in message
news:1153900566.928220.245470@h48g2000cwc.googlegroups.com...
> As I said, I'm in a NT4 domain. Otherwise I agree that the LDAP
> provider has to be preferred. In my opinion, the GetObject function is
> designed for scripts, and DirectoryEntry for programs. Note that with
> any provider, WinNT or LDAP, you can specify the username and password
> in the DirectoryEntry constructor.
>