Solved

Change Active Directory User Password method SetPassword and ASP.Net

Posted on 2004-09-20
13
2,213 Views
Last Modified: 2008-03-17
Hi,

I cannot make the following code work in asp.net. It works fine in Console application.

string strLDAP = "LDAP://192.168.0.2CN=jdoe,OU=sample_ou,DC=MYDOMAIN,DC=local";
                  DirectoryEntry entry  = new DirectoryEntry(strLDAP,"administrator","abcde",AuthenticationTypes.ServerBind);
                  object native = entry.NativeGuid;
                  entry.Invoke("SetPassword",new object[] {"testing"});
                  Response.Write("Authenticated.<br>");
                  Response.Write(entry.Properties["name"].Value);

This always give me the exception: System.Runtime.InteropServices.COMException: One or more input parameters are invalid
at entry.Invoke("SetPassword",new object[] {"testing"});

I have already tried using the AuthenticationType as a secure socket layer but that gave me "The server is not operational." . This thing is really annoying and wants me to shift my application to Windows as it works fine there. Any suggestions regarding changing the user password in active directory using ASP.net will be very helpful.

Thanks, Nauman.
0
Comment
Question by:nauman_ahmed
  • 7
  • 5
13 Comments
 
LVL 25

Author Comment

by:nauman_ahmed
ID: 12104502
I have already searched a lot on the net and tried almost everything. I will be really very thankful if a working solution is posted.

Thanks, Nauman.
0
 
LVL 17

Expert Comment

by:AerosSaga
ID: 12104720
try this:

      
Joe Kaplan \(MVP - ADSI\) (VIP)
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

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.

Regards,

Aeros
0
 
LVL 17

Expert Comment

by:AerosSaga
ID: 12104751
0
 
LVL 25

Author Comment

by:nauman_ahmed
ID: 12104769
Thanks Aeros.

ChangePassword is working fine at my side. The problem is with SetPassowrd.

-Nauman.
0
 
LVL 17

Expert Comment

by:AerosSaga
ID: 12104800
IIS 5.0 or 6.0?
0
 
LVL 25

Author Comment

by:nauman_ahmed
ID: 12104894
I tried on both :(

-Nauman.
0
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 17

Expert Comment

by:AerosSaga
ID: 12104958
same result?
0
 
LVL 25

Author Comment

by:nauman_ahmed
ID: 12104999
yeah. Its all the same and no luck until now.

-Nauman.
0
 
LVL 17

Accepted Solution

by:
AerosSaga earned 500 total points
ID: 12105013
try it this way then:

private void AddUser(string strDoamin, string strLogin, string strPwd)
{
      DirectoryEntry obDirEntry = null;
      try
      {
            obDirEntry = new DirectoryEntry("WinNT://" + strDoamin);
            DirectoryEntries entries = obDirEntry.Children;
            DirectoryEntry obUser = entries.Add(strLogin, "User");
            obUser.Properties["FullName"].Add("Amigo");
            object obRet = obUser.Invoke("SetPassword", strPwd);
            obUser.CommitChanges();
      }
      catch (Exception ex)
      {
            Trace.Warn(ex.Message);
      }
}

0
 
LVL 25

Author Comment

by:nauman_ahmed
ID: 12105405
thanks aeros.. It is working with WINNT prefix. But one thing that I will never understand is why we have to tame windows instead of using the methods that have been already defined in MSDN? I have been working on this since 2 days but didnt have any luck. Thanks a lot again..and if there is an explanation of using WinNT instead of LDAP prefix, please post it here.

Thanks, Nauman.
0
 
LVL 17

Expert Comment

by:AerosSaga
ID: 12105449
You must have noticed from the above list that there is no property to set or get user password value. Operating system does not give access to clear text password value. So we can't expect and property or method to get it. In ADSI,  IAdsUser interface provides SetPassword method to set a user's password. This is where Invoke method of DirectoryEntry  class comes handy. So we call Invoke to set the password value. The Invoke method can be used to call native methods on underlying active directory objects. There is one important thing to remeber when you set a user's password value. If you are using LDAP provider, then the user account should already have been created in the system by calling CommitChanges  or SetInfo method. But WinNT provider does not have this restriction. You can set password value without commiting the changes first.

http://www.netomatix.com/AddNewUser.aspx

Regards,

Aeros
0
 
LVL 17

Expert Comment

by:AerosSaga
ID: 12105530
Glad I could be of some assistance to you my friend.

Aeros
0
 

Expert Comment

by:erikking
ID: 14953478

entry.Invoke("SetPassword",new object[] {"testing"});

This command does not work in Active Directory which run on Window 2003. With error message that "Type mismatch."
So...Please help me..!!
0

Featured Post

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

I have developed many web applications with asp & asp.net and to add and use a dropdownlist was always a very simple task, but with the new asp.net, setting the value is a bit tricky and its not similar to the old traditional method. So in this a…
In this Article, I will provide a few tips in problem and solution manner. Opening an ASPX page in Visual studio 2003 is very slow. To make it fast, please do follow below steps:   Open the Solution/Project. Right click the ASPX file to b…
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

759 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now