Directory Services and ASP.NET

Directory Services and ASP.NET

Post by Joe Kapla » Sun, 14 Jan 2007 00:27:36


What are the error codes and what does your code look like? That would be
very helpful here.

Joe K.

--
Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.yqcomputer.com/
 
 
 

Directory Services and ASP.NET

Post by Joe Kapla » Sun, 14 Jan 2007 02:09:12

Can I also see the password change code too? It is important to see how
your actually constructed the DirectoryEntry object with the path you are
using and such.

Also, I highly recommend you read the section on password management in ch
10 of my book. It is one of the most troublesome topics in all of ADSI
programming and I've provided a lot of details about how it can go wrong
there. Ch 10 is available as a free download in PDF from the link in my
signature below.

Joe K.

--
Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.yqcomputer.com/

 
 
 

Directory Services and ASP.NET

Post by Joe Kapla » Sun, 14 Jan 2007 03:16:35

And where is Change_Password?

Joe K.

--
Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.yqcomputer.com/
 
 
 

Directory Services and ASP.NET

Post by Joe Kapla » Sun, 14 Jan 2007 05:13:34

Ok, that's what I needed to see. In the code below, you are trying to bind
to the directory under the identity of the current security context
(discoverable with
System.Security.Principal.WindowsIdentity.GetCurrent().Name). Depending on
how your web application is configured, this may or may not be the user you
want it to be. For that to be the browser user, you need to have integrated
or basic auth configured in IIS (no anonymous), need to have Windows auth
configured in ASP.NET and need to have <identity impersonate="true"/>.
Without impersonation, you'll have the process account and that won't work,
as the process account should not be changing the user's own password. That
also may not work for a variety of other reasons.

Based on the errors you are getting (operations error), it looks like your
bind to the directory may not be working and it is trying to log in as
anonymous instead, which causes the operations error in 2003 AD. To know
for sure, it would be helpful to see the entire stack trace of the exception
instead of just the error code.

Another thing to be concerned about in a web application is that in order to
use integrated auth and impersonation to bind as the remote browser user,
you will need to implement Kerberos delegation. It isn't the hardest thing
in the world, but it is non-trivial and can be very confusing if you've
never done it before.

In your case, given that you have the user's username and their current
password, it may be easier to bypass these issues entirely and just use
those in your DirectoryEntry contructor. You may also need to add a domain
name to your LDAP path in case serverless binding isn't working in the
current security context.

This will not necessarily get ChangePassword working, as its success depends
a great deal on other environment factors such as the availability of
SSL/LDAP on the DC or whether or not a NetUserChangePassword RPC call can be
made to work. I go into more details on that in ch 10 of the book.

Best of luck!

Joe K.

--
Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.yqcomputer.com/
 
 
 

Directory Services and ASP.NET

Post by Joe Kapla » Sun, 14 Jan 2007 06:48:35

The built in web server in VS 2005 runs under the account that VS runs
under, which is typically admin if you are logged in as admin and is
typically a full domain account. That is not necessarily a good translation
at all to how it will work under the IIS 6 process model. You have to be
careful to understand the security assumptions that your code is making and
what could potentially invalidate those assumptions.

Joe K.

--
Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.yqcomputer.com/
 
 
 

Directory Services and ASP.NET

Post by aG5nbzA » Mon, 15 Jan 2007 00:38:00

oe,
My test user acctL has "Must change password after first logon" flag set.
Can I different if user enter wrong password and corrrect password?
It seem return me same error code if (wrong/valid) password? Thanks


"Joe Kaplan" wrote:

 
 
 

Directory Services and ASP.NET

Post by Joe Kapla » Mon, 15 Jan 2007 11:43:04

My experience is that you can't do a password change via LDAP when the user
is in "must change password at next logon". That needs to be done
interactively at the workstation.

I'd love to see a way to deal with this programmatically from a web
application, but I haven't seen one yet.

Joe K.

--
Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.yqcomputer.com/
 
 
 

Directory Services and ASP.NET

Post by Joe Kapla » Wed, 17 Jan 2007 03:33:04

It depends. If you run on 2K3 server, the process identity is changed by
changing the app pool identity. Note that if you are running on a domain
member server and the app pool is configured to run as Network Service, then
it is already a domain account when it uses the network, as network service
uses the machine account in that case and it is a domain account.

If you are on XP or Win2K using IIS 5, then the process identity is changed
by changing the processModel configuration.

Using the <identity> tag in web.config does not change the process identity,
but will change the identity of the current thread to impersonate a domain
account, so that may be a way to accomplish what you want without changing
the process identity. It depends on what you are trying to do.

Joe K.

--
Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.yqcomputer.com/
 
 
 

Directory Services and ASP.NET

Post by Joe Kapla » Wed, 17 Jan 2007 13:18:58

The site is primarily a password change website, right? In that case, did
you try passing in the user's credentials to the DirectoryEntry constructor?
You have to collect the plaintext password to call ChangePassword anyway, so
that should not be a problem. One advantage here is that it should make it
possible to avoid having to change the process account at all.

How did that work? Can you show the code with that example in it?

Joe K.

--
Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.yqcomputer.com/
 
 
 

Directory Services and ASP.NET

Post by Joe Kapla » Thu, 18 Jan 2007 00:55:21

Are you using default credentials in the version on your workstation that
works (passing null for username and password)?

It should not be possible to actually do the initial bind if you are set to
change password at next logon and pass in credentials to the DE constructor.

If your goal is to build a web app that allows users to change password even
if they are set to "change at next logon", you will have trouble with that.
It is possible to build a web app that uses default credentials and accepts
the logon of the remote user, but that begs the question of how they got
logged on in the first place? They won't be able to provide credentials via
the browser for the same reason and the workstation won't let them log in
without changing their password, so there is a fairly narrow range of times
when that could work.

Please explain more what you are trying to do.

Joe K.

--
Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.yqcomputer.com/
 
 
 

Directory Services and ASP.NET

Post by Joe Kapla » Thu, 18 Jan 2007 04:52:05

So, if you run the code below and the user account is in "change password at
next logon", the bind will fail. Unfortunately, that is one of the
conditions that can cause a bind to fail in LDAP and it doesn't tell you
why. The error code returned is the same, no matter if the password was
just wrong or there was a more complex reason (could also be lockout,
password expired, account expired, etc.).

Now, another problem you can run into is with serverless binding, which is
what you are using below with your path LDAP://rootDSE

Because you don't provide a server or domain hint in that path, LDAP must
figure out what domain to use based on the current security context of the
app. Since this can vary a lot from deployment to deployment (as you have
seen), you can have different operational issues with this. What you might
consider doing is adding the domain to the path:

LDAP://mydomain.com/rootDSE

That should provide enough of a hint to the locator to allow it to find a DC
in that domain and make everything else work the same.

Like I said before, you may have problems with a password change website if
you will put people into "must change at next logon" state. The only way
this could possibly work is if they were already logged on before this
happened (or else they can't log on to Windows or the website!) and you get
the site to work based on default credentials, which will mean you'll need
Kerberos delegation to make it work. It is possible, but non-trivial and it
might not be worth trying to do in the first place.

I hope that helps some more.

Joe K.

--
Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.yqcomputer.com/
 
 
 

Directory Services and ASP.NET

Post by aG5nbzA » Sun, 21 Jan 2007 08:33:46

oe,
I were able to use "Setpassword" method any user (including user has flag
"must change password after first logon" using Impersonate an admin acct in
Web.config file.
The problem I were having and still researching is trying to authenticate
user with AD when has user with flag "must change ...after first logon".
Any feedback is appreciated.

"Joe Kaplan" wrote:

 
 
 

Directory Services and ASP.NET

Post by Joe Kapla » Sun, 21 Jan 2007 09:18:17

SetPassword makes sense. It is ChangePassword that is hard.

Like I said, you can't do an LDAP bind with credentials if the user you are
binding with is set to "must change password at next logon". You might be
able to a default credentials bind by impersonating that user, but it sort
of begs the question as to how they got logged in to the workstation they
are using to browse to the site with in the first place. They should have
had to change their password during workstation logon.

Joe K.

--
Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.yqcomputer.com/