Calling NetUserGetInfo from ASP.NET app

M

Michael D'Angelo

I have an ASP.NET 2.0 app with windows authentication and impersonation
enabled. The application pool is running as local system.

I'm trying to call NetUserGetInfo to retrieve the full name of a user
account. The code works when run from a console application. When I
execute it from the ASP.NET page, I can see in the event log on the domain
controller the following failure audit:
Object Open:

Object Server: Security Account Manager

Object Type: SAM_SERVER

Object Name: CN=Server,CN=System,DC=domain,DC=com

Handle ID: -

Operation ID: {0,706132358}

Process ID: 544

Process Name: C:\WINDOWS\system32\lsass.exe

Primary User Name: DC$

Primary Domain: DOMAIN

Primary Logon ID: (0x0,0x3E7)

Client User Name: ANONYMOUS LOGON

Client Domain: NT AUTHORITY

Client Logon ID: (0x0,0x2A16B979)

Accesses: MAX_ALLOWED


Privileges: -

Properties:

---

samServer

Access Mask: 0



So it appears as though delegation is not working...however I've gone into
the properties on teh server, and in the delegation tab, I've added every
service listed on the domain controller, using any authentication protocol.
Despite this it's still failing. Any ideas?
 
M

Michael D'Angelo

I also get Access is Denied if I use System.DirectoryServices using WinNT,
or Operations Error using LDAP.
 
J

Joe Kaplan \(MVP - ADSI\)

Yep, it sounds like delegation isn't working. I'm not sure of what
service/SPN you need to have delegation rights to in order for
NetUserSetInfo to work (or S.DS with WinNT), but for S.DS with LDAP, you
should just need LDAP with the appropriate DCs in the SPN.

One thing you might consider doing is using a trusted subsystem model and
NOT using impersonation. That way, you wouldn't need delegation to work.
BTW, there are also some other APIs you can look at to do this like the
TranslateName Win32 API and the DsCrackNames DS RPC method (which is wrapped
by the IADsNameTranslate interface in ADSI and can be called from .NET via
COM interop).

On the delegation troubleshooting issue, I'd first check to make sure you
are getting Kerberos authentication in IIS. If you are getting NTLM, then
you'll also need to have protocol transition working. It is probably easier
to troubleshoot first with an end-to-end Kerberos solution first. The nice
thing about this is with a full Kerberos solution, you can first enable
"uncontrained delegation", which means that you can get it working without
knowing which SPNs you need to actually delegate to. Then you can switch to
constrained delegation later and then finally add protocol transition into
the mix last if needed.

I usually start by watching the HTTP traffic and seeing the auth headers
that are being exchanged. I also enabled logon auditing in the local
security policy and watch the events in the security event log on the web
server to see what's actually going on there.

HTH,

Joe K.
 
M

Michael D'Angelo

I am using Integrated Windows Authentication, and I've seen references to
the "double-hop" issue. The only suggestion I've seen is to turn off
integrated windows authentication, but I need to have it on in order to
enforce local filesystem ACLs.

I thought I got it working by calling ImpersonateSelf, but it still doesn't
seem to be working. The answer seems to lie with doing an impersonation
with SecurityDelegation
(http://msdn.microsoft.com/library/d...thz/security/security_impersonation_level.asp)
but I can't find a good example of how to do it...
 
J

Joe Kaplan \(MVP - ADSI\)

I'm sure it is a delegation issue. The operations error you mentioned when
using LDAP is a classic symptom of an authentication failure related to a
delegation issue.

All of the stuff I suggested earlier will be helpful for you if you want to
get delegation working. I'd also suggest reading the technet doc
"troubleshooting Kerberos errors". It is extremely informative.

From a code perspective, you are doing everything right. When you get the
config right, it will just start working.

Joe K.
 
M

Michael D'Angelo

Well, I kind of got it working...
Not sure if I like this method, but I switched to basic authentication and
then used a slightly modified version of this example, using
Request.ServerVariables["AUTH_USER"] and AUTH_PASSWORD:
http://support.microsoft.com/?scid=306158

The LDAP provider works fine now, so it seems delegation is working
correctly, although calling the WinNT provider and NetUserGetInfo both
return Access Denied.

With the WinNT provider, I do get a failed object access (although nothing
with NetUserGetInfo)
The error is:
Object Open:

Object Server: SC Manager

Object Type: SC_MANAGER OBJECT

Object Name: ServicesActive

Handle ID: -

Operation ID: {0,714329947}

Process ID: 532

Image File Name: C:\WINDOWS\system32\services.exe

Primary User Name: BRCAD1$

Primary Domain: PACE

Primary Logon ID: (0x0,0x3E7)

Client User Name: md48497p

Client Domain: PACE

Client Logon ID: (0x0,0x2A93CF3A)

Accesses: READ_CONTROL

Connect to service controller

Enumerate services

Query service database lock state


Privileges: -

Restricted Sid Count: 0

Access Mask: 0x20015
 
M

Michael D'Angelo

It does seem to be a permission issue of some kind, since if I authenticate
as an administrator, WinNT and NetUserGetInfo work.

Michael D'Angelo said:
Well, I kind of got it working...
Not sure if I like this method, but I switched to basic authentication and
then used a slightly modified version of this example, using
Request.ServerVariables["AUTH_USER"] and AUTH_PASSWORD:
http://support.microsoft.com/?scid=306158

The LDAP provider works fine now, so it seems delegation is working
correctly, although calling the WinNT provider and NetUserGetInfo both
return Access Denied.

With the WinNT provider, I do get a failed object access (although nothing
with NetUserGetInfo)
The error is:
Object Open:

Object Server: SC Manager

Object Type: SC_MANAGER OBJECT

Object Name: ServicesActive

Handle ID: -

Operation ID: {0,714329947}

Process ID: 532

Image File Name: C:\WINDOWS\system32\services.exe

Primary User Name: BRCAD1$

Primary Domain: PACE

Primary Logon ID: (0x0,0x3E7)

Client User Name: md48497p

Client Domain: PACE

Client Logon ID: (0x0,0x2A93CF3A)

Accesses: READ_CONTROL

Connect to service controller

Enumerate services

Query service database lock state


Privileges: -

Restricted Sid Count: 0

Access Mask: 0x20015


Joe Kaplan (MVP - ADSI) said:
I'm sure it is a delegation issue. The operations error you mentioned
when using LDAP is a classic symptom of an authentication failure related
to a delegation issue.

All of the stuff I suggested earlier will be helpful for you if you want
to get delegation working. I'd also suggest reading the technet doc
"troubleshooting Kerberos errors". It is extremely informative.

From a code perspective, you are doing everything right. When you get
the config right, it will just start working.

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
 
J

Joe Kaplan \(MVP - ADSI\)

Regarding permissions, that could be. Perhaps there is some DCOM thing or
something? I really don't know. I've never tried to use those APIs in an
architecture like this. In web apps, I mostly do delegation stuff with
HTTP, SQL and and LDAP.

Also, when using basic auth, you aren't really using Kerberos delegation
since basic auth performs a local login with plain credentials. There is
only one hop involved there.

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
--
Michael D'Angelo said:
It does seem to be a permission issue of some kind, since if I
authenticate as an administrator, WinNT and NetUserGetInfo work.

Michael D'Angelo said:
Well, I kind of got it working...
Not sure if I like this method, but I switched to basic authentication
and then used a slightly modified version of this example, using
Request.ServerVariables["AUTH_USER"] and AUTH_PASSWORD:
http://support.microsoft.com/?scid=306158

The LDAP provider works fine now, so it seems delegation is working
correctly, although calling the WinNT provider and NetUserGetInfo both
return Access Denied.

With the WinNT provider, I do get a failed object access (although
nothing with NetUserGetInfo)
The error is:
Object Open:

Object Server: SC Manager

Object Type: SC_MANAGER OBJECT

Object Name: ServicesActive

Handle ID: -

Operation ID: {0,714329947}

Process ID: 532

Image File Name: C:\WINDOWS\system32\services.exe

Primary User Name: BRCAD1$

Primary Domain: PACE

Primary Logon ID: (0x0,0x3E7)

Client User Name: md48497p

Client Domain: PACE

Client Logon ID: (0x0,0x2A93CF3A)

Accesses: READ_CONTROL

Connect to service controller

Enumerate services

Query service database lock state


Privileges: -

Restricted Sid Count: 0

Access Mask: 0x20015


Joe Kaplan (MVP - ADSI) said:
I'm sure it is a delegation issue. The operations error you mentioned
when using LDAP is a classic symptom of an authentication failure
related to a delegation issue.

All of the stuff I suggested earlier will be helpful for you if you want
to get delegation working. I'd also suggest reading the technet doc
"troubleshooting Kerberos errors". It is extremely informative.

From a code perspective, you are doing everything right. When you get
the config right, it will just start working.

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
--
I am using Integrated Windows Authentication, and I've seen references
to the "double-hop" issue. The only suggestion I've seen is to turn off
integrated windows authentication, but I need to have it on in order to
enforce local filesystem ACLs.

I thought I got it working by calling ImpersonateSelf, but it still
doesn't seem to be working. The answer seems to lie with doing an
impersonation with SecurityDelegation
(http://msdn.microsoft.com/library/d...thz/security/security_impersonation_level.asp)
but I can't find a good example of how to do it...
 
M

Michael D'Angelo

Right, I'm "cheating" by calling native apis LogonUser and
ImpersonateLoggedOnUser using the username and password passed to the web
site. :)

I can't figure out what permission is missing exactly, but since the LDAP
provider works, I at least have something to go with.

Joe Kaplan (MVP - ADSI) said:
Regarding permissions, that could be. Perhaps there is some DCOM thing or
something? I really don't know. I've never tried to use those APIs in an
architecture like this. In web apps, I mostly do delegation stuff with
HTTP, SQL and and LDAP.

Also, when using basic auth, you aren't really using Kerberos delegation
since basic auth performs a local login with plain credentials. There is
only one hop involved there.

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
--
Michael D'Angelo said:
It does seem to be a permission issue of some kind, since if I
authenticate as an administrator, WinNT and NetUserGetInfo work.

Michael D'Angelo said:
Well, I kind of got it working...
Not sure if I like this method, but I switched to basic authentication
and then used a slightly modified version of this example, using
Request.ServerVariables["AUTH_USER"] and AUTH_PASSWORD:
http://support.microsoft.com/?scid=306158

The LDAP provider works fine now, so it seems delegation is working
correctly, although calling the WinNT provider and NetUserGetInfo both
return Access Denied.

With the WinNT provider, I do get a failed object access (although
nothing with NetUserGetInfo)
The error is:
Object Open:

Object Server: SC Manager

Object Type: SC_MANAGER OBJECT

Object Name: ServicesActive

Handle ID: -

Operation ID: {0,714329947}

Process ID: 532

Image File Name: C:\WINDOWS\system32\services.exe

Primary User Name: BRCAD1$

Primary Domain: PACE

Primary Logon ID: (0x0,0x3E7)

Client User Name: md48497p

Client Domain: PACE

Client Logon ID: (0x0,0x2A93CF3A)

Accesses: READ_CONTROL

Connect to service controller

Enumerate services

Query service database lock state


Privileges: -

Restricted Sid Count: 0

Access Mask: 0x20015


"Joe Kaplan (MVP - ADSI)" <[email protected]>
wrote in message I'm sure it is a delegation issue. The operations error you mentioned
when using LDAP is a classic symptom of an authentication failure
related to a delegation issue.

All of the stuff I suggested earlier will be helpful for you if you
want to get delegation working. I'd also suggest reading the technet
doc "troubleshooting Kerberos errors". It is extremely informative.

From a code perspective, you are doing everything right. When you get
the config right, it will just start working.

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
--
I am using Integrated Windows Authentication, and I've seen references
to the "double-hop" issue. The only suggestion I've seen is to turn
off integrated windows authentication, but I need to have it on in
order to enforce local filesystem ACLs.

I thought I got it working by calling ImpersonateSelf, but it still
doesn't seem to be working. The answer seems to lie with doing an
impersonation with SecurityDelegation
(http://msdn.microsoft.com/library/d...thz/security/security_impersonation_level.asp)
but I can't find a good example of how to do it...
 
M

Michael D'Angelo

Joe Kaplan (MVP - ADSI) said:
Regarding permissions, that could be. Perhaps there is some DCOM thing or
something? I really don't know. I've never tried to use those APIs in an
architecture like this. In web apps, I mostly do delegation stuff with
HTTP, SQL and and LDAP.

Well I discovered if I put the user in the Pre-Windows 2000 Compatible group
it works. However, the user does have read access to the object in the tree
I'm trying to get info on. It seems to be something else that's failing,
which isn't getting audited in the event log.
 
M

Michael D'Angelo

Finally! I got it to work by using TranslateName. Go figure.
Thanks for mentioning it though, I didn't know about that api :)
 
J

Joe Kaplan \(MVP - ADSI\)

Good deal. It uses the LSA to do the work for you using the machine's
credentials, so you don't necessarily need to do an RPC on the client's
behalf. It is probably a lot easier than getting delegation working and I
think the LSA also provides some built in caching for you. Of course, the
next time you really do need delegation, you still won't know how to get it
working. :)

Joe K.
 
M

Michael D'Angelo

nah I did get it working.
I can query AD using the LDAP provider just fine. As I said, I cheated by
calling LogonUser, DuplicateToken, and ImpersonateLoggenOnUser ;)
It's only NetUserGetInfo that fails, and I narrowed it down to a permission
issue, because it works when the user is in the Pre-Windows 2000 Compatible
group.
I do it in Global.asax in the PreRequestHandlerExecute event, then call
RevertToSelf in PostRequestHandlerExecute. Seems to do the job. I cas
share the code if you like :)

The main thing is that I needed it to work even with non-IE browsers, and
through a firewall. Two things it doesn't seem regular Kerberos-based
delegation work with...
 
J

Joe Kaplan \(MVP - ADSI\)

The LogonUser thing isn't delegation, since that's a local logon, but that
is a way to get it working if you have plaintext credentials.

There is a feature in Windows 2003 (with Windows 2003 AD) called protocol
transition (S4U) that you could use as well. PT allows non-Kerberos
authentication on the front end (like basic, NTLM or Digest) and will
"transition" to Kerberos when Kerberos auth is needed. PT can also be
called programmatically by your code. Essentially, you can call
LsaLogonUser with the proper arguments, or in .NET, you can use the
WindowsIdentity constructor that simply takes a UPN as the argument. That
will give you a Windows user token/WindowsIdentity that you can impersonate
and use for remote calls, assuming that the account has the correct rights
for delegation with any protocol and can delegate to the services you need
to visit.

If you are going to have plaintext credentials, then this isn't really
necessary, but it is an option.

Joe K.
 

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

Members online

No members online now.

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,810
Latest member
Kassie0918

Latest Threads

Top