Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

Change Active Directory User Password method SetPassword and ASP.Net

Posted on 2004-09-20
13
Medium Priority
?
2,259 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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
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
 
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 2000 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

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Lots of people ask this question on how to extend the “MembershipProvider” to make use of custom authentication like using existing database or make use of some other way of authentication. Many blogs show you how to extend the membership provider c…
ASP.Net to Oracle Connectivity Recently I had to develop an ASP.NET application connecting to an Oracle database.As I am doing it first time ,I had to solve several problems. This article will help to such developers  to develop an ASP.NET client…
We’ve all felt that sense of false security before—locking down external access to a database or component and feeling like we’ve done all we need to do to secure company data. But that feeling is fleeting. Attacks these days can happen in many w…
Are you ready to place your question in front of subject-matter experts for more timely responses? With the release of Priority Question, Premium Members, Team Accounts and Qualified Experts can now identify the emergent level of their issue, signal…
Suggested Courses

824 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