I wanted to allow a user to change their password to something else, so
maybe I've been confusing myself here. Our server is Win2K, and I was
changing the processModel section due to some info I found on the 'Net.
I can put it back to it's original form. Would you recommend upgrading
to the .NET framework 2.0 as well?
Basically, I'm looking for an example of allowing a user to hit the
site, enter their current password, and then enter a new one, using
ASP.NET and System.Directory services.
Sorry for the confusion, and thanks again for any help.
Harry
"Joe Kaplan (MVP - ADSI)" <
[email protected]>
wrote in message I thought you were doing password changes, not resets. There are
actually important differences on how that is approached.
It sounds like this is running on Win2K or XP, right? That's why you
are editing the processModel section.
It also looks like you are using the 1.0 version of the .NET Framework.
Any reason for that? 1.1 or 2.0 would be preferred. The 1.0.3300.0
version for System.DirectoryServices points to the 1.0 framework.
If you have changed the process model account, there is no reason to
also impersonate the same account in code. The process account will be
running as the admin user. However, this is generally not considered a
good practice, especially if other apps may be running on the same
server as they will all run under this administrative account and have
more privileges than they should.
Can you also show the exact line where this is crashing? If they page
displays, it seems like there should be some indication of what the
problem was on the postback.
Joe K.
I'm reasonably sure ASP.NET is working (the .aspx page that I'm
putting below comes up), but this is my first try at programming
anything in it, so take that for what it's worth. I'm including the
code for the reset.aspx file and web.config. The only change that I
made to machine.config was to change the username and password under
the processModel section to be my domain admin account (I found that
suggestion somewhere on the Web while researching the error).
Thanks for any help,
Harry
reset.aspx:
<%@ Assembly Name="System.DirectoryServices, Version=1.0.3300.0,
Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"%>
<%@ Assembly Name="Dunnry.Security" %>
<%@ Import Namespace="System.DirectoryServices" %>
<%@ Import Namespace="Dunnry.Security" %>
<HTML>
<script language="C#" runat="server">
void Page_Load(Object Src, EventArgs E ) {
if(!Page.IsPostBack)
{
}
}
private void ResetPassword(object sender, EventArgs e)
{
//for impersonation
string username = "AdminUser";
string password = "adminpwd";
string domain = "domain";
Impersonate i = new
Impersonate(LogonProvider.LOGON32_PROVIDER_WINNT50);
i.ImpersonateUser(username, domain, password);
string ldapPath = LDAP://dc=mydomain,dc=com;
DirectoryEntry de = new DirectoryEntry(ldapPath);
de.AuthenticationType = AuthenticationTypes.Secure;
string qry =
String.Format("(&(objectClass=user)(objectCategory=person)(sAMAccountName={0}))",
txtUsername.Text);
DirectorySearcher ds = new DirectorySearcher(de,qry);
SearchResult sr = ds.FindOne();
if(sr==null)
{
lblMessage.Text = "User not found";
return;
}
try
{
DirectoryEntry user = sr.GetDirectoryEntry();
user.AuthenticationType = AuthenticationTypes.Secure;
user.Invoke("SetPassword", new object[]{txtPassword.Text});
lblMessage.Text = "Success <br>";
}
catch(Exception ex)
{
//throw ex;
lblMessage.Text = "Failure: " + ex.Message;
if(ex.InnerException != null)
lblMessage.Text += "<br>" + ex.InnerException.Message;
}
finally
{
de.Close();
i.UndoImpersonation();
}
}
</script>
<body>
<form runat="server">
UserName: <asp:textbox id="txtUsername" runat="server"/><br>
New Password: <asp:textbox id="txtPassword" runat="server"/><br>
<asp:button id="btnReset" runat="server" Text="Reset"
OnClick="ResetPassword" /><br>
<asp:label id="lblMessage" runat="server"/><br><br>
I am running as: <%=Context.User.Identity.Name %><br>
My process is running as:
<%=System.Security.Principal.WindowsIdentity.GetCurrent().Name %>
</form>
</body>
</HTML>
web.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<compilation debug="true"/>
<authentication mode="Windows" />
<!--<authorization>
<deny users="?" />
</authorization>-->
</system.web>
<!-- Secure the .aspx page using web.config
<location path="reset.aspx">
<system.web>
<authorization>
<allow roles="DOMAIN\AdminUser" />
<deny users="*" />
</authorization>
</system.web>
</location> -->
</configuration>
processModel section of machine.config:
<processModel
enable="true"
timeout="Infinite"
idleTimeout="Infinite"
shutdownTimeout="0:00:05"
requestLimit="Infinite"
requestQueueLimit="5000"
restartQueueLimit="10"
memoryLimit="60"
webGarden="false"
cpuMask="0xffffffff"
userName="domain\adminuser"
password="adminpwd"
logLevel="Errors"
clientConnectedCheck="0:00:05"
comAuthenticationLevel="Connect"
comImpersonationLevel="Impersonate"
responseDeadlockInterval="00:03:00"
maxWorkerThreads="20"
maxIoThreads="20"
/>
"Joe Kaplan (MVP - ADSI)" <
[email protected]>
wrote in message The crux of doing this in a web page is simply to create a
DirectoryEntry object that is bound to the user's object in AD and
invoking the ChangePassword ADSI method. Impersonation may or may
not be needed as you need to prompt for the old password anyway, so
it doesn't really hurt to simply use those credentials in your
DirectoryEntry constructor.
The error you are getting sounds like it is unrelated to an
DirectoryServices programming stuff though. Are you sure ASP.NET is
working in general?
Note also that Ryan and I have book coming out that covers this stuff
in detail, but it won't be available for a few more months now.
Posting an example of the code you are using would be a great start.
Joe K.
I've been searching around for an answer to this question, but
haven't gotten too far. I'm fairly new to ASP.NET, so I'm not sure
how to setup machine.config and web.config properly.
What I want to be able to do is allow a domain user to change their
password in the AD via a webpage. We have several users with domain
accounts, but they do not actually login to our domain as they are
spread out all over the country. I have a VBS script that notifies
them when their password is due to expire, starting 10 days out.
Since these users are not local to where my domain controller
resides, they have to call me or email me to have their password
reset. I found an example written by Ryan Dunn using an Impersonate
function that he wrote (
www.dunnry.com), but I keep getting an error
stating: "Parser Error Message: The XML file
c:\winnt\microsoft.net\framework\v1.1.4322\Config\machine.config
could not be loaded. Either a required impersonation level was not
provided, or the provided impersonation level is invalid. "
This seems like, to me, a fundamental type of function to do, but
info on how to do it is all over the place. Does anyone have any
good ideas or steps on how to accomplish this?
Thanks for any help,
Harry