Change Active Directory User Password method SetPassword and ASP.Net

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.
LVL 25
nauman_ahmedAsked:
Who is Participating?

Improve company productivity with a Business Account.Sign Up

x
 
AerosSagaConnect With a Mentor Commented:
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
 
nauman_ahmedAuthor Commented:
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
 
AerosSagaCommented:
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
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
AerosSagaCommented:
0
 
nauman_ahmedAuthor Commented:
Thanks Aeros.

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

-Nauman.
0
 
AerosSagaCommented:
IIS 5.0 or 6.0?
0
 
nauman_ahmedAuthor Commented:
I tried on both :(

-Nauman.
0
 
AerosSagaCommented:
same result?
0
 
nauman_ahmedAuthor Commented:
yeah. Its all the same and no luck until now.

-Nauman.
0
 
nauman_ahmedAuthor Commented:
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
 
AerosSagaCommented:
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
 
AerosSagaCommented:
Glad I could be of some assistance to you my friend.

Aeros
0
 
erikkingCommented:

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
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.