?
Solved

Working with the Active Directory

Posted on 2004-11-15
48
Medium Priority
?
501 Views
Last Modified: 2008-01-09
I have the following code that is suppose to be used to add a user to the active directory using directoryservices. My problem is that my server requires certain parameters for a password when a user is created. Is there anyway to set the password at the same time when the user is actually created. Right now when I try to move the password setting under the UserAccountControl I get an object doesn't exist.

Dim objDE As New System.DirectoryServices.DirectoryEntry(CStr(Application("")))
 Dim objUser As  DirectoryServices.DirectoryEntry = New DirectoryServices.DirectoryEntry
            objUser = objDE.children.Add("cn=" & login.text & "","user")
             objUser.Properties("sAMAccountName").add(login.text)
             objUser.Properties("sn").add(lname.text)
             objUser.Properties("displayName").add(lname.text & "," & fname.text)
             objUser.Properties("telephoneNumber").add(tel.text)
             objUser.Properties("mail").add(email.text)
            objUser.Properties("userAccountControl").add(512)
            objUser.commitChanges()
            objUser.Invoke("setPassword", "sweet98")
            objUser.commitChanges()
0
Comment
Question by:NickMalloy
  • 26
  • 22
48 Comments
 
LVL 20

Expert Comment

by:ihenry
ID: 12586004
Can you post here the exception stack trace?
0
 

Author Comment

by:NickMalloy
ID: 12586035

Stack Trace:


[UnauthorizedAccessException: General access denied error
]
   System.DirectoryServices.Interop.IAds.SetInfo() +0
   System.DirectoryServices.DirectoryEntry.CommitChanges() +37
   ASP.addaduser_aspx.add_ad(Object Source, EventArgs E) in D:\Intranet\Mystuff\Mystuff\addaduser.aspx:27
   System.Web.UI.WebControls.Button.OnClick(EventArgs e) +108
   System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +57
   System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +18
   System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +33
   System.Web.UI.Page.ProcessRequestMain() +1277

 
stack trace when the setpassword is moved. up



[COMException (0x80072030): There is no such object on the server.]

[TargetInvocationException: Exception has been thrown by the target of an invocation.]
   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) +106
   ASP.addaduser_aspx.add_ad(Object Source, EventArgs E) in D:\Intranet\Mystuff\Mystuff\addaduser.aspx:27
   System.Web.UI.WebControls.Button.OnClick(EventArgs e) +108
   System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +57
   System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +18
   System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +33
   System.Web.UI.Page.ProcessRequestMain() +1277

 

0
 
LVL 20

Expert Comment

by:ihenry
ID: 12586114
Generally, when create a new user account you want to do it like this

Create the object and CommitChanges
Then, call SetPassword and CommitChanges
Then, set userAccountControl to enable the object and call CommitChanges one last time.

Is the user account created? what is line 27 in the adduser.aspx?
0
Industry Leaders: 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!

 

Author Comment

by:NickMalloy
ID: 12586154
no it doesn't create a user.
Line 27:  objUser.commitChanges()
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12586157
this?

objUser.commitChanges()
objUser.Invoke("setPassword", "sweet98")
objUser.commitChanges()     <-- line 27?
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12586172
NickMalloy,

You have 2 lines which have objUser.commitChanges().
0
 

Author Comment

by:NickMalloy
ID: 12586177
That is to set the password if I am correct
0
 

Author Comment

by:NickMalloy
ID: 12586178
Are you saying it should look like this?

objUser = objDE.children.Add("cn=" & login.text & "","user")
             objUser.Properties("sAMAccountName").add(login.text)
             objUser.Properties("sn").add(lname.text)
             objUser.Properties("displayName").add(lname.text & "," & fname.text)
             objUser.Properties("telephoneNumber").add(tel.text)
             objUser.Properties("mail").add(email.text)
            objUser.commitChanges()
            objUser.Invoke("setPassword", "sweet98")
            objUser.commitChanges()
            objUser.Properties("userAccountControl").add(512)
            objUser.commitChanges()
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12586330
What I wanted to know is at which line exactly the exception is thrown. There're only 2 possibilities

objUser.Properties("mail").add(email.text)
objUser.Properties("userAccountControl").add(512)
objUser.commitChanges()     <-- here
objUser.Invoke("setPassword", "sweet98")
objUser.commitChanges()     <-- or here

But since no user account created during execution so most likely the first CommitChange that giving you the problem.

>> Are you saying it should look like this?
Almost exactly yes, except ADS_UF_NORMAL_ACCOUNT ( =512 ) can be executed right before the first CommitChange and removal of ADS_UF_ACCOUNTDISABLE right before the last CommitChange.

But it seems your problem is likely more on security problem. Tell me more on what authentication for the web app, windows or forms authentication? if windows do you enable IIS "Integrated Windows Authentication"? And are you sure the current user windows login account has proper permission rights?
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12586393
When the SetPassword is moved up, it seems you have another problem.

I'm not sure if this line works
objUser.Invoke("setPassword", "sweet98")

I'm using the following lines and it works great
objUser.Invoke( "setPassword", New Object() { "sweet98" } )
0
 

Author Comment

by:NickMalloy
ID: 12586565
The first one is throwing it.
objUser.Properties("mail").add(email.text)
objUser.Properties("userAccountControl").add(512)
objUser.commitChanges()     <-- here

For authenitication I am using windows. "Integrated Windows Authentication" is not checked. The current login user is me who is an Admin.
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12586706
Lets narrowing the problem down to whether you are able to bind to AD in the first place

Dim objDE As New System.DirectoryServices.DirectoryEntry()
Dim ldapPath As String = "LDAP://<SERVER_NAME>/bla..bla.."
objDE.Path = Path
objDE.RefreshCache()

Try to run the above code and see what happen.
0
 

Author Comment

by:NickMalloy
ID: 12586748
is it really objDE.Path = Path or what is path suppose to be?
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12586768
oops..sorry..that should be
objDE.Path = ldapPath
0
 

Author Comment

by:NickMalloy
ID: 12586774
okay the page simply reloaded.
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12586821
Try more code and execute it

Dim objDE As New System.DirectoryServices.DirectoryEntry()
Dim ldapPath As String = "LDAP://<SERVER_NAME>/bla..bla.."
objDE.Path = Path
objDE.RefreshCache()
' check if this line gets executed with no error and please post the result
Dim ds As String = objDE.Properties("distinguishedName").Value

Dim objUser As  DirectoryServices.DirectoryEntry = objDE.children.Add("cn=" & login.text & "","user")
objUser.Properties("sAMAccountName").add(login.text)
objUser.Properties("sn").add(lname.text)
objUser.Properties("displayName").add(lname.text & "," & fname.text)
objUser.Properties("telephoneNumber").add(tel.text)
objUser.Properties("mail").add(email.text)
objUser.Properties("userAccountControl").add(512)
objUser.commitChanges()
0
 

Author Comment

by:NickMalloy
ID: 12586859
that line didn't produce an error when the bottom part is left off. This code produces an error

UnauthorizedAccessException: General access denied error
]
   System.DirectoryServices.Interop.IAds.SetInfo() +0
   System.DirectoryServices.DirectoryEntry.CommitChanges() +37
   ASP.addaduser_aspx.add_ad(Object Source, EventArgs E) in D:\Intranet\Mystuff\Mystuff\addaduser.aspx:43
   System.Web.UI.WebControls.Button.OnClick(EventArgs e) +108
   System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +57
   System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +18
   System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +33
   System.Web.UI.Page.ProcessRequestMain() +1277
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12586903
hm..can you post the ldapPath value?
and the return value from this line
Dim ds As String = objDE.Properties("distinguishedName").Value
0
 

Author Comment

by:NickMalloy
ID: 12586920
how do I get the return value for ds???
0
 

Author Comment

by:NickMalloy
ID: 12586935
Here is the path

LDAP://CN=Users,DC=sthmpsn,DC=com
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12586975
debugging by step through the code. Is your dev box is part of the AD domain? is the windows login account is member of domain administrator?
0
 

Author Comment

by:NickMalloy
ID: 12586999
Yes and yes.

 I am using Dreamweaver for my coding so I have no idea how to debug to get you that value.
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12587027
Use Response.Write( ds )
0
 

Author Comment

by:NickMalloy
ID: 12587063
ds = CN=Users,DC=sthmpsn,DC=com
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12587125

Try to include server name in the ldapPath, like this

Dim objDE As New System.DirectoryServices.DirectoryEntry()
Dim ldapPath As String = "LDAP://<SERVER_NAME>//CN=Users,DC=sthmpsn,DC=com"
objDE.Path = ldapPath
objDE.AuthenticationType = AuthenticationTypes.ServerBind
objDE.RefreshCache()
Dim ds As String = objDE.Properties("distinguishedName").Value

Dim objUser As  DirectoryServices.DirectoryEntry = objDE.children.Add("cn=" & login.text & "","user")
objUser.Properties("sAMAccountName").add(login.text)
objUser.Properties("sn").add(lname.text)
objUser.Properties("displayName").add(lname.text & "," & fname.text)
objUser.Properties("telephoneNumber").add(tel.text)
objUser.Properties("mail").add(email.text)
objUser.Properties("userAccountControl").add(512)
objUser.commitChanges()

And run the code
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12587154
And do you have VS.NET installed on the dev machine? you might need to run the code on a console app to see whether security issues has something to do with this problem.
0
 

Author Comment

by:NickMalloy
ID: 12587172
still the same
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12587180
hm..forgot to ask. do you enable anonymous access in the IIS security settings?
0
 

Author Comment

by:NickMalloy
ID: 12587202
no
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12587209
Or pass the user name and password explicitly in your code

Dim objDE As New System.DirectoryServices.DirectoryEntry()
Dim ldapPath As String = "LDAP://<SERVER_NAME>//CN=Users,DC=sthmpsn,DC=com"
objDE.Username = "Domain/theUserAccount"
objDE.Username = "thePassword"
objDE.Path = ldapPath
objDE.AuthenticationType = AuthenticationTypes.ServerBind
objDE.RefreshCache()
...
...
0
 

Author Comment

by:NickMalloy
ID: 12587254
[COMException (0x80072035): The server is unwilling to process the request.]
   System.DirectoryServices.Interop.IAds.SetInfo() +0
   System.DirectoryServices.DirectoryEntry.CommitChanges() +37
   ASP.addaduser_aspx.add_ad(Object Source, EventArgs E) in D:\Intranet\llctest\addaduser.aspx:44
   System.Web.UI.WebControls.Button.OnClick(EventArgs e) +108
   System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +57
   System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +18
   System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +33
   System.Web.UI.Page.ProcessRequestMain() +1277
0
 

Author Comment

by:NickMalloy
ID: 12587260
new error I just noticed
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12587344
yup, commenting out this line
objUser.Properties("userAccountControl").add(512)
0
 

Author Comment

by:NickMalloy
ID: 12587377
user shows up but account is disabled.
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12587397
yup, but what is new created userAccountControl attribute value, by default 512 should be included automatically.
0
 

Author Comment

by:NickMalloy
ID: 12587421
so what do I ned to do so that the user isn't disabled when he is created?
0
 
LVL 20

Accepted Solution

by:
ihenry earned 2000 total points
ID: 12587478
gosh..you have NTLM disable, basic auth only and anonymous access disable but the symptoms still looked like double hope/delegation issue or the app is running under aspnet user context. anyway, we will find out soon after executing the SetPassword.

User password must be set before you can enable it

' make sure the password meets domain password policy
objUser.Invoke("setPassword", New Object() {"sweet98"} )
objUser.commitChanges() ' hopefully no more error from this line

Dim userAccountControl As Integer = CType( objUser.Properties["userAccountControl"].Value, Integer )
objUser.Properties["userAccountControl"].Value = val And Not ADS_UF_ACCOUNTDISABLE
objUser.commitChanges()
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12587515
The ADS_UF_ACCOUNTDISABLE is equal to 2

or you can just do this if no other settings required

objUser.Properties["userAccountControl"].Value = 512
objUser.commitChanges()
0
 

Author Comment

by:NickMalloy
ID: 12587591
YES!!! Now two very short questions for you. How do you exchange enable the account? Also when you open AD and show the users what is the property name of the name that is displayed for each user. Like in ad my account is displayed under name as "Malloy, Nick", but when I am creating a user right now it displays the loginID as the name.
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12587713
>> YES!!!
Is that means the user is created, enabled and with the correct password.

>> How do you exchange enable the account
Read this, but in c#
http://msdn.microsoft.com/library/en-us/sds/sds/enabling_and_disabling_the_user_account.asp

>> ..I am creating a user right now it displays the loginID as the name..
You mean via "Active Directory Users and Computers" snap-ins or ADSI viewer? "Active Directory Users and Computers" snap-ins should showing like "LastName, FirstName" and ADSI viewer is showing sAMAccountName value. I'm not very sure, though. I don't have access to AD now and far away from my office pc, but I let you know maybe tommorow.

Note:
Binding to AD is an expensive operation, thus closing and disposing connected DirectoryEntry object is necessary.
0
 

Author Comment

by:NickMalloy
ID: 12587749
yes the user is created!!!! Now all I need to do is get it to display right under Active Directory Users and Computers and then enable exhange. I don't see in that link how you enable exchange. That looks like enabling an account.
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12587759
sorry, understood it wrongly.

you mean, ms exchange?
0
 

Author Comment

by:NickMalloy
ID: 12587765
yeah
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12587810
First, You need to install CDOEXM in your dev machine. Import the necessary assembly to the project and read this article should put you on the right track.

http://support.microsoft.com/kb/313114

And be ready for another errors messages :o).

If you have problem just open another question, I'll try to help you as I can.
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12587874
I've gotta sign off another few minutes. Good luck for you!
0
 

Author Comment

by:NickMalloy
ID: 12587888
thanks for all your help
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12587903
you're welcome!
0
 
LVL 20

Expert Comment

by:ihenry
ID: 12601373
Hi Nick, I still owed you one question

>> ...Like in ad my account is displayed under name as "Malloy, Nick",
>> but when I am creating a user right now it displays the loginID as the name.

When a user object is created in the “Active Directory Users and Computers” MMC, the names default as follows. You specify the “givenName”, “initials”, and “sn” attributes of the user and it's displayed as <givenName> <initials>. <sn>. The source of confusion is when you create a user programmatically it's displayed as cn attribute's value. You can overwrite this behaviour by set the cn attributes the same way as when you create a user via “Active Directory Users and Computers” MMC.
0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

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.

Question has a verified solution.

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

Today is the age of broadband.  More and more people are going this route determined to experience the web and it’s multitude of services as quickly and painlessly as possible. Coupled with the move to broadband, people are experiencing the web via …
In .NET 2.0, Microsoft introduced the Web Site.  This was the default way to create a web Project in Visual Studio 2005.  In Visual Studio 2008, the Web Application has been restored as the default web Project in Visual Studio/.NET 3.x The Web Si…
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…
Please read the paragraph below before following the instructions in the video — there are important caveats in the paragraph that I did not mention in the video. If your PaperPort 12 or PaperPort 14 is failing to start, or crashing, or hanging, …
Suggested Courses
Course of the Month14 days, 17 hours left to enroll

839 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