Problem with changepassword webcontrol

T

tpeltz

We have a website that we are trying to control access to using the
ActiveDirectoryMembershipProvider. In the webconfig we have specified
a ConnectionString that includes a port number.

LDAP://acme.local.com:50001/CN=Users,DC=local,DC=com"

Our membership properties are as follows.

<membership defaultProvider="MembershipADProvider">
<providers>
<add connectionStringName="ADConnectionString"
connectionUsername="CN=Admin,CN=Users,DC=local,DC=com"
connectionPassword="np4dev'sio" connectionProtection="Secure"
requiresUniqueEmail="false"
minRequiredNonalphanumericCharacters="0"
enableSearchMethods="true"
passwordStrengthRegularExpression="(?!^[0-9]*$)(?!^[a-zA-Z]*$)
^([a-zA-Z0-9]{7,})$"
minRequiredPasswordLength="7"
name="MembershipADProvider"
type="System.Web.Security.ActiveDirectoryMembershipProvider,
System.Web, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a" />
</providers>


We are able to logon successfully with accounts stored on our remote
AD LDS server. We would like to allow users to change their password
and have configured a change password page with a ChangePassword
control. When we try to change the password while logged on as a user
we get the following stack trace.

[DirectoryServicesCOMException (0x80072030): There is no such object
on the server.
]
System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
+377678
System.DirectoryServices.DirectoryEntry.Bind() +36
System.DirectoryServices.DirectoryEntry.get_AdsObject() +31
System.DirectoryServices.DirectoryEntry.get_Options() +31

System.Web.Security.ActiveDirectoryMembershipProvider.SetPasswordPortIfApplicable
(DirectoryEntry userEntry) +297
System.Web.Security.ActiveDirectoryMembershipProvider.ChangePassword
(String username, String oldPassword, String newPassword) +1945
System.Web.Security.MembershipUser.ChangePassword(String
oldPassword, String newPassword) +129
System.Web.Security.MembershipUser.ChangePassword(String
oldPassword, String newPassword, Boolean throwOnError) +43
System.Web.UI.WebControls.ChangePassword.AttemptChangePassword()
+162
System.Web.UI.WebControls.ChangePassword.OnBubbleEvent(Object
source, EventArgs e) +114
System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs
args) +37
System.Web.UI.WebControls.Button.OnCommand(CommandEventArgs e) +118
System.Web.UI.WebControls.Button.RaisePostBackEvent(String
eventArgument) +166

System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent
(String eventArgument) +10
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler
sourceControl, String eventArgument) +13
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData)
+36
System.Web.UI.Page.ProcessRequestMain(Boolean
includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
+1565


First, does anyone know what might cause this? Second, I notice that
it calls SetPasswordPortIfApplicable. I can't find any documentation
on this method of ActiveDirectoryMembershipProvider. We are using an
alternate port (50001). When we created the accounts using
DirectoryServices it was necessary to tell the provider what port we
were using with the following command.

user.Invoke("SetOption",
(ADS_OPTION_PASSWORD_PORTNUMBER), IntPort)
user.Invoke("SetPassword", str)

I don't see a way of telling the changepassword control which port to
use. Could this be the reason for our problems?

Thanks for you insight.
 
J

Joe Kaplan

The code is failing because it is failing to actually find the user in the
LDS directory to change their password. I'm not sure why this would happen
given that they were presumably able to log in already, but that's what
causes the failure as near as I can tell. I'm guessing there is some
mismatch in the username string used to find the user somehow.

The operation to set the password port is done because of the way ADSI
works. It needs to know what port to attempt an LDAP password change on
because by default it tries this on AD LDAP with SSL (636) and your server
is not listening on that port. Given your settings, it is likely going to
attempt a clear text password change so make sure you have LDS configured to
allow that (it is not enabled by default).

The main thing to figure out here is why the ChangePassword method is not
finding the user though.

--
Joe Kaplan-MS MVP Directory Services Programming
Co-author of "The .NET Developer's Guide to Directory Services Programming"
http://www.directoryprogramming.net
tpeltz said:
We have a website that we are trying to control access to using the
ActiveDirectoryMembershipProvider. In the webconfig we have specified
a ConnectionString that includes a port number.

LDAP://acme.local.com:50001/CN=Users,DC=local,DC=com"

Our membership properties are as follows.

<membership defaultProvider="MembershipADProvider">
<providers>
<add connectionStringName="ADConnectionString"
connectionUsername="CN=Admin,CN=Users,DC=local,DC=com"
connectionPassword="np4dev'sio" connectionProtection="Secure"
requiresUniqueEmail="false"
minRequiredNonalphanumericCharacters="0"
enableSearchMethods="true"
passwordStrengthRegularExpression="(?!^[0-9]*$)(?!^[a-zA-Z]*$)
^([a-zA-Z0-9]{7,})$"
minRequiredPasswordLength="7"
name="MembershipADProvider"
type="System.Web.Security.ActiveDirectoryMembershipProvider,
System.Web, Version=2.0.0.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a" />
</providers>


We are able to logon successfully with accounts stored on our remote
AD LDS server. We would like to allow users to change their password
and have configured a change password page with a ChangePassword
control. When we try to change the password while logged on as a user
we get the following stack trace.

[DirectoryServicesCOMException (0x80072030): There is no such object
on the server.
]
System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
+377678
System.DirectoryServices.DirectoryEntry.Bind() +36
System.DirectoryServices.DirectoryEntry.get_AdsObject() +31
System.DirectoryServices.DirectoryEntry.get_Options() +31

System.Web.Security.ActiveDirectoryMembershipProvider.SetPasswordPortIfApplicable
(DirectoryEntry userEntry) +297
System.Web.Security.ActiveDirectoryMembershipProvider.ChangePassword
(String username, String oldPassword, String newPassword) +1945
System.Web.Security.MembershipUser.ChangePassword(String
oldPassword, String newPassword) +129
System.Web.Security.MembershipUser.ChangePassword(String
oldPassword, String newPassword, Boolean throwOnError) +43
System.Web.UI.WebControls.ChangePassword.AttemptChangePassword()
+162
System.Web.UI.WebControls.ChangePassword.OnBubbleEvent(Object
source, EventArgs e) +114
System.Web.UI.Control.RaiseBubbleEvent(Object source, EventArgs
args) +37
System.Web.UI.WebControls.Button.OnCommand(CommandEventArgs e) +118
System.Web.UI.WebControls.Button.RaisePostBackEvent(String
eventArgument) +166

System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent
(String eventArgument) +10
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler
sourceControl, String eventArgument) +13
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData)
+36
System.Web.UI.Page.ProcessRequestMain(Boolean
includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
+1565


First, does anyone know what might cause this? Second, I notice that
it calls SetPasswordPortIfApplicable. I can't find any documentation
on this method of ActiveDirectoryMembershipProvider. We are using an
alternate port (50001). When we created the accounts using
DirectoryServices it was necessary to tell the provider what port we
were using with the following command.

user.Invoke("SetOption",
(ADS_OPTION_PASSWORD_PORTNUMBER), IntPort)
user.Invoke("SetPassword", str)

I don't see a way of telling the changepassword control which port to
use. Could this be the reason for our problems?

Thanks for you insight.
 
T

tpeltz

I've discovered a nuance with this. If I make the user an
adminstrator the change password works. Users that are not
administrators get the error described above. Is there some setting
that I need to modify that allows user to change their password?
 
J

Joe Kaplan

It may just be a problem with read access in general. I suggest adding the
authenticated users group to the ADAM readers role group so that all users
that ADAM can authenticate are treated as readers.

However, it may be the case that the service account for the membership
provider must have admin access for this to work. I'm not sure why that
would be, but it may be. I'd try the lesser permission (read access) first.
 
T

tpeltz

Thanks! Adding Authenticated Users to the readers group worked.
Strange that I had to go through this extra step that nobody else had
to.
 
J

Joe Kaplan

The default behavior of ADAM/AD LDS is that users defined in the directory
have no read access to anything in the directory including their own
account. This is part of the "secure by default" mantra that Microsoft
designs for these days. It is also a very different security model than AD.
I've also heard the term "useless by default" applied to this design
decision, but the main thing to know is that this is how it works.

So, in any case where the user's own credentials are used to access the
directory and read anything from it as is the case with how ChangePassword
works under the hood, you need to ensure that the user has read access.
Adding the authenticated users group to the readers role is just one
possible way to do this, but it is the easiest. If you wanted tighter
security, you might use an inheritable SELF read ACL entry on the parent
container so that each user could only read their own object or something.

Unfortunately, the error returned is so obscure that you have little chance
of figuring out how to correct it without knowing a lot of additional
details about how it works. It would certainly be nice if it anticipated
this problem and provided a useful suggestion.
 
T

tpeltz

Thanks again. I've since discovered that users created with the
membership provider are added to the readers group automatically. I
was using DirectoryServices objects to create the accounts within a
console application. I've used your suggestion of adding the
Authenticated Users group. That seems the simplest.
 

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

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top