change password in active directory by webapplication (vb.net)

S

Sara

Dear Sir,
I want to change password of users in active directory by asp.net
form.this is my code, but i recieve error could anyone help me to
solve it. thanks

Protected WithEvents newpass As System.Web.UI.WebControls.TextBox
Protected WithEvents btn1 As System.Web.UI.WebControls.Button
Protected WithEvents username As System.Web.UI.WebControls.TextBox
Protected WithEvents oldpass As System.Web.UI.WebControls.TextBox
Private Sub btn1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btn1.Click
Dim dom As DirectoryEntry = New
DirectoryEntry("LDAP://Hosnieh_Rafiee", "Hosnieh_Rafiee\admin11",
"bbb")

Dim entry As DirectoryEntry = New
DirectoryEntry("LDAP://Hosnieh_Rafiee", username.Text, oldpass.Text)
Dim search As New DirectorySearcher(entry)

Dim result As SearchResult = search.FindOne

'If entry.Password = oldpass.Text Then
Dim b As String

entry.Invoke("setPassword", "newpassword")
entry.CommitChanges()

Response.Write(entry.Password)

Response.Write("successful")

'Else
' Response.Write("your username or password is incorrect")
'End If





End Sub
 
J

Joe Kaplan \(MVP - ADSI\)

Hi,

Can you give details about what exception gets thrown? There are many
reasons why the SetPassword method might fail, including an inability to get
a secure connection to AD (SSL or Kerberos), a password policy issue or a
permissions issue.

I'd suggest using AuthenticationTypes.Secure and/or
AuthenticationTypes.SecureSocketsLayer on your initial bind.

Also, the Password property on the DirectoryEntry is not related to the
underlying password of a user object in Active Directory. That is the
password used to bind to the directory.

You may find lots of ideas on solving the problem by searching on
SetPassword. There are many threads on this in
microsoft.public.adsi.general.

Joe K.
 
S

Sara rafiee

Hi
this is my error on my code for changing user password in active
directory programmatically
Inherits System.Web.UI.Page
Protected WithEvents newpass As System.Web.UI.WebControls.TextBox
Protected WithEvents btn1 As System.Web.UI.WebControls.Button
Protected WithEvents username As System.Web.UI.WebControls.TextBox
Protected WithEvents txt2 As System.Web.UI.WebControls.TextBox
Protected WithEvents txt1 As System.Web.UI.WebControls.TextBox
Protected WithEvents btn2 As System.Web.UI.WebControls.Button
Protected WithEvents oldpass As System.Web.UI.WebControls.TextBox
Private Sub btn1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btn1.Click
Dim dom As DirectoryEntry = New
DirectoryEntry("LDAP://Hosnieh_Rafiee", "Hosnieh_Rafiee\admin11", "bbb")

Dim entry As DirectoryEntry = New
DirectoryEntry("LDAP://Hosnieh_Rafiee", username.Text, oldpass.Text)
Dim search As New DirectorySearcher(entry)

Dim result As SearchResult = search.FindOne

'If entry.Password = oldpass.Text Then
Dim b As String

entry.Invoke("setPassword", "newpassword")
entry.CommitChanges()

Response.Write(entry.Password)

Response.Write("successful")

'Else
' Response.Write("your username or password is incorrect")
'End If
End Sub

Server Error in '/netaccount' Application.
------------------------------------------------------------

The Active Directory property cannot be found in the cache.
Description: An unhandled exception occurred during the execution of the
current web request. Please review the stack trace for more information
about the error and where it originated in the code.

Exception Details: System.Runtime.InteropServices.COMException: The
Active Directory property cannot be found in the cache.

Source Error:


Line 42: Dim b As String
Line 43:
Line 44: entry.Invoke("setPassword", "newpassword")
Line 45: entry.CommitChanges()
Line 46:


Source File: g:\My Documents\Visual Studio
Projects\netaccount\WebForm1.aspx.vb Line: 44

Stack Trace:


[COMException (0x80020006): The Active Directory property cannot be
found in the cache.
]
System.RuntimeType.InvokeDispMethod(String name, BindingFlags
invokeAttr, Object target, Object[] args, Boolean[] byrefModifiers,
Int32 culture, String[] namedParameters) +0
System.RuntimeType.InvokeMember(String name, BindingFlags invokeAttr,
Binder binder, Object target, Object[] args, ParameterModifier[]
modifiers, CultureInfo culture, String[] namedParameters) +473
System.Type.InvokeMember(String name, BindingFlags invokeAttr, Binder
binder, Object target, Object[] args) +29
System.DirectoryServices.DirectoryEntry.Invoke(String methodName,
Object[] args)
netaccount.WebForm1.btn1_Click(Object sender, EventArgs e) in g:\My
Documents\Visual Studio Projects\netaccount\WebForm1.aspx.vb:44
System.Web.UI.WebControls.Button.OnClick(EventArgs e)

System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.Rai
sePostBackEvent(String eventArgument)
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler
sourceControl, String eventArgument)
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData)
System.Web.UI.Page.ProcessRequestMain()
 
J

Joe Kaplan \(MVP - ADSI\)

It is not clear to me from your code that you have bound to an actual user
object to change a password on.

You need to either know the distinguished name of the use you want to change
the password on and bind to that username or you need to create a search to
find the user by some other known criteria. The code for the former would
look something like:

'you need to supply a valid path to a user and valid admin credentials to
set the password
Try
Dim entry As DirectoryEntry = New
DirectoryEntry("LDAP://Hosnieh_Rafiee/cn=someone,cn=users,dc=yourdomain,dc=c
om", adminUsername, adminPassword, AuthenticationTypes.Secure)

Dim bindCheck As Object = entry.NativeObject

entry.Invoke("setPassword", New Object() {"newpassword"})
entry.CommitChanges()
Finally
If Not entry is Nothing then entry.Dispose()
End Try

Note that the Invoke method throws a TargetInvocationException, so if you
want to get the actual exception thrown, you need to check the
InnerException property to get the COMException.

Explain more what you are trying to do and I can probably help more.

Joe K.
Sara rafiee said:
Hi
this is my error on my code for changing user password in active
directory programmatically
Inherits System.Web.UI.Page
Protected WithEvents newpass As System.Web.UI.WebControls.TextBox
Protected WithEvents btn1 As System.Web.UI.WebControls.Button
Protected WithEvents username As System.Web.UI.WebControls.TextBox
Protected WithEvents txt2 As System.Web.UI.WebControls.TextBox
Protected WithEvents txt1 As System.Web.UI.WebControls.TextBox
Protected WithEvents btn2 As System.Web.UI.WebControls.Button
Protected WithEvents oldpass As System.Web.UI.WebControls.TextBox
Private Sub btn1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btn1.Click
Dim dom As DirectoryEntry = New
DirectoryEntry("LDAP://Hosnieh_Rafiee", "Hosnieh_Rafiee\admin11", "bbb")

Dim entry As DirectoryEntry = New
DirectoryEntry("LDAP://Hosnieh_Rafiee", username.Text, oldpass.Text)
Dim search As New DirectorySearcher(entry)

Dim result As SearchResult = search.FindOne

'If entry.Password = oldpass.Text Then
Dim b As String

entry.Invoke("setPassword", "newpassword")
entry.CommitChanges()

Response.Write(entry.Password)

Response.Write("successful")

'Else
' Response.Write("your username or password is incorrect")
'End If
End Sub

Server Error in '/netaccount' Application.
------------------------------------------------------------

The Active Directory property cannot be found in the cache.
Description: An unhandled exception occurred during the execution of the
current web request. Please review the stack trace for more information
about the error and where it originated in the code.

Exception Details: System.Runtime.InteropServices.COMException: The
Active Directory property cannot be found in the cache.

Source Error:


Line 42: Dim b As String
Line 43:
Line 44: entry.Invoke("setPassword", "newpassword")
Line 45: entry.CommitChanges()
Line 46:


Source File: g:\My Documents\Visual Studio
Projects\netaccount\WebForm1.aspx.vb Line: 44

Stack Trace:


[COMException (0x80020006): The Active Directory property cannot be
found in the cache.
]
System.RuntimeType.InvokeDispMethod(String name, BindingFlags
invokeAttr, Object target, Object[] args, Boolean[] byrefModifiers,
Int32 culture, String[] namedParameters) +0
System.RuntimeType.InvokeMember(String name, BindingFlags invokeAttr,
Binder binder, Object target, Object[] args, ParameterModifier[]
modifiers, CultureInfo culture, String[] namedParameters) +473
System.Type.InvokeMember(String name, BindingFlags invokeAttr, Binder
binder, Object target, Object[] args) +29
System.DirectoryServices.DirectoryEntry.Invoke(String methodName,
Object[] args)
netaccount.WebForm1.btn1_Click(Object sender, EventArgs e) in g:\My
Documents\Visual Studio Projects\netaccount\WebForm1.aspx.vb:44
System.Web.UI.WebControls.Button.OnClick(EventArgs e)

System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.Rai
sePostBackEvent(String eventArgument)
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler
sourceControl, String eventArgument)
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData)
System.Web.UI.Page.ProcessRequestMain()
 
S

Sara rafiee

Hi
let me explain it clearly
I have a form which has three textbox, to get user information. first
textbox is username, second one is user_old_password and third one is
user_new_password. with that code when user entered request part and
click on submit button I want that this user at first checked with
active directory and then if he entered his username and old_password
correctly ; I mean the result of search is one then the new password set
instead of old one. but up to now I wasn't success in it. if you need
any more details I will tell you more. thanks...


Private Sub btn1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles btn1.Click


Dim entry As DirectoryEntry = New
DirectoryEntry("LDAP://Hosnieh_Rafiee", username.Text, oldpass.Text,
AuthenticationTypes.Secure)
Dim search As New DirectorySearcher(entry)
Dim result As SearchResult = search.FindOne
If Not result Is Nothing Then
entry.Invoke("setPassword", New Object() {newpass.Text})
entry.CommitChanges()
Response.Write("successful")
Else
Response.Write("invalid")
End If

End Sub
 
J

Joe Kaplan \(MVP - ADSI\)

Ok, I see. Here are the steps to accomplish that:

1. Bind to the directory root with with the user's current name and password
to get the domain search root
2. Find the user by their username in the directory using the
DirectorySearcher
3. Bind the user's DirectoryEntry (found from 2)
4. Invoke the ChangePassword method (not the SetPassword method, since that
is used by admins to reset a password)

Here is some sample code that should come close to what you are trying to
do. I wasn't able to test this, and you may need to modify it based on your
DC name and also on the type of encryption you are going to use (SSL or
Kerberos).

Private Sub ChangePassword(ByVal username As String, ByVal oldPassword
As String, ByVal newPassword As String)

Dim dcDNS As String = "yourdc.com" 'use this if you want to supply a
server name
Dim rootDN As String
Dim rootDSE As DirectoryEntry
Dim searchRoot As DirectoryEntry
Dim userEntry As DirectoryEntry
Dim searcher As DirectorySearcher
Dim results As SearchResultCollection
Dim result As SearchResult

Try
'note the authenicationtypes here
'you need to either use SecureSocketsLayer or Kerberos (Secure +
Sealing)
rootDSE = New DirectoryEntry(String.Format("LDAP://{0}/rootDSE",
dcDNS), username, oldPassword, AuthenticationTypes.Secure Or
AuthenticationTypes.Sealing Or AuthenticationTypes.ServerBind)
rootDN =
DirectCast(rootDSE.Properties("defaultNamingContext").Value, String)
searchRoot = New DirectoryEntry(String.Format("LDAP://{0}/{1}",
dcDNS, rootDN), username, oldPassword, AuthenticationTypes.Secure Or
AuthenticationTypes.Sealing Or AuthenticationTypes.ServerBind)
searcher = New DirectorySearcher(searchRoot)
searcher.Filter = String.Format("sAMAccountName={0}", username)
searcher.SearchScope = SearchScope.Subtree
searcher.CacheResults = False

'I use FindAll here because FindOne leaks memory if it does not
find anything
'in .NET 1.0 and 1.1
results = searcher.FindAll()
For Each result In results
'only use this method on .NET 1.1 or higher
'otherwise, get the adsPath value and build a new
DirectoryEntry with the supplied credentials
userEntry = result.GetDirectoryEntry()
Exit For 'this is redundant because sAMAccountName is unique
in the domain, but it is done for clarity
Next

If userEntry Is Nothing Then
Throw New InvalidOperationException("User not found in this
domain.")
End If

userEntry.Invoke("ChangePassword", New Object() {oldPassword,
newPassword})
userEntry.CommitChanges()

Catch ex As System.Reflection.TargetInvocationException
Throw ex.InnerException

Finally 'these prevent other memory leaks
If Not userEntry Is Nothing Then userEntry.Dispose()
If Not results Is Nothing Then results.Dispose()
If Not searcher Is Nothing Then searcher.Dispose()
If Not searchRoot Is Nothing Then searchRoot.Dispose()
If Not rootDSE Is Nothing Then rootDSE.Dispose()
End Try
End Sub

Joe K.
 
S

Sara rafiee

Hi
thanks ... very much. yeah it is what I want but again another exception
occured when I run this code with my own domain


The server is not operational
Description: An unhandled exception occurred during the execution of the
current web request. Please review the stack trace for more information
about the error and where it originated in the code.

Exception Details: System.Runtime.InteropServices.COMException: The
server is not operational

Source Error:


Line 123: 'you need to either use SecureSocketsLayer or
Kerberos (Secure + Sealing)
Line 124: rootDSE = New
DirectoryEntry(String.Format("LDAP://{0}/rootDSE", dcDNS), username,
oldPassword, AuthenticationTypes.Secure Or AuthenticationTypes.Sealing
Or AuthenticationTypes.ServerBind)
Line 125: rootDN =
DirectCast(rootDSE.Properties("defaultNamingContext").Value, String)
Line 126: searchRoot = New
DirectoryEntry(String.Format("LDAP://{0}/{1}", dcDNS, rootDN), username,
oldPassword, AuthenticationTypes.Secure Or AuthenticationTypes.Sealing
Or AuthenticationTypes.ServerBind)
Line 127: searcher = New DirectorySearcher(searchRoot)


Source File: g:\My Documents\Visual Studio
Projects\netaccount\WebForm1.aspx.vb Line: 125

Stack Trace:


[COMException (0x8007203a): The server is not operational]
System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
System.DirectoryServices.DirectoryEntry.Bind()
System.DirectoryServices.DirectoryEntry.get_AdsObject()
System.DirectoryServices.PropertyValueCollection.PopulateList()
System.DirectoryServices.PropertyValueCollection..ctor(DirectoryEntry
entry, String propertyName)
System.DirectoryServices.PropertyCollection.get_Item(String
propertyName)
netaccount.WebForm1.ChangePassword(String username, String
oldPassword, String newPassword) in g:\My Documents\Visual Studio
Projects\netaccount\WebForm1.aspx.vb:125
netaccount.WebForm1.btn1_Click(Object sender, EventArgs e) in g:\My
Documents\Visual Studio Projects\netaccount\WebForm1.aspx.vb:35
System.Web.UI.WebControls.Button.OnClick(EventArgs e)

System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.Rai
sePostBackEvent(String eventArgument)
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler
sourceControl, String eventArgument)
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData)
System.Web.UI.Page.ProcessRequestMain()
 
J

Joe Kaplan \(MVP - ADSI\)

You may need to experiment with different variations on the dcDNS variable
and you may need to remove the ServerBind flag if you are using a NETBIOS
name. Also, you may need to remove the Sealing flag as well, but be warned
that in order to set or change passwords, some sort of encrypted channel
(SSL or Kerberos) must be available.

Joe K.

Sara rafiee said:
Hi
thanks ... very much. yeah it is what I want but again another exception
occured when I run this code with my own domain


The server is not operational
Description: An unhandled exception occurred during the execution of the
current web request. Please review the stack trace for more information
about the error and where it originated in the code.

Exception Details: System.Runtime.InteropServices.COMException: The
server is not operational

Source Error:


Line 123: 'you need to either use SecureSocketsLayer or
Kerberos (Secure + Sealing)
Line 124: rootDSE = New
DirectoryEntry(String.Format("LDAP://{0}/rootDSE", dcDNS), username,
oldPassword, AuthenticationTypes.Secure Or AuthenticationTypes.Sealing
Or AuthenticationTypes.ServerBind)
Line 125: rootDN =
DirectCast(rootDSE.Properties("defaultNamingContext").Value, String)
Line 126: searchRoot = New
DirectoryEntry(String.Format("LDAP://{0}/{1}", dcDNS, rootDN), username,
oldPassword, AuthenticationTypes.Secure Or AuthenticationTypes.Sealing
Or AuthenticationTypes.ServerBind)
Line 127: searcher = New DirectorySearcher(searchRoot)


Source File: g:\My Documents\Visual Studio
Projects\netaccount\WebForm1.aspx.vb Line: 125

Stack Trace:


[COMException (0x8007203a): The server is not operational]
System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
System.DirectoryServices.DirectoryEntry.Bind()
System.DirectoryServices.DirectoryEntry.get_AdsObject()
System.DirectoryServices.PropertyValueCollection.PopulateList()
System.DirectoryServices.PropertyValueCollection..ctor(DirectoryEntry
entry, String propertyName)
System.DirectoryServices.PropertyCollection.get_Item(String
propertyName)
netaccount.WebForm1.ChangePassword(String username, String
oldPassword, String newPassword) in g:\My Documents\Visual Studio
Projects\netaccount\WebForm1.aspx.vb:125
netaccount.WebForm1.btn1_Click(Object sender, EventArgs e) in g:\My
Documents\Visual Studio Projects\netaccount\WebForm1.aspx.vb:35
System.Web.UI.WebControls.Button.OnClick(EventArgs e)

System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.Rai
sePostBackEvent(String eventArgument)
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler
sourceControl, String eventArgument)
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData)
System.Web.UI.Page.ProcessRequestMain()
 

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,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top