Working with the Active Directory

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()
NickMalloySystems LeadAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

ihenryCommented:
Can you post here the exception stack trace?
0
NickMalloySystems LeadAuthor Commented:

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
ihenryCommented:
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
Cloud Class® Course: C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

NickMalloySystems LeadAuthor Commented:
no it doesn't create a user.
Line 27:  objUser.commitChanges()
0
ihenryCommented:
this?

objUser.commitChanges()
objUser.Invoke("setPassword", "sweet98")
objUser.commitChanges()     <-- line 27?
0
ihenryCommented:
NickMalloy,

You have 2 lines which have objUser.commitChanges().
0
NickMalloySystems LeadAuthor Commented:
That is to set the password if I am correct
0
NickMalloySystems LeadAuthor Commented:
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
ihenryCommented:
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
ihenryCommented:
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
NickMalloySystems LeadAuthor Commented:
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
ihenryCommented:
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
NickMalloySystems LeadAuthor Commented:
is it really objDE.Path = Path or what is path suppose to be?
0
ihenryCommented:
oops..sorry..that should be
objDE.Path = ldapPath
0
NickMalloySystems LeadAuthor Commented:
okay the page simply reloaded.
0
ihenryCommented:
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
NickMalloySystems LeadAuthor Commented:
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
ihenryCommented:
hm..can you post the ldapPath value?
and the return value from this line
Dim ds As String = objDE.Properties("distinguishedName").Value
0
NickMalloySystems LeadAuthor Commented:
how do I get the return value for ds???
0
NickMalloySystems LeadAuthor Commented:
Here is the path

LDAP://CN=Users,DC=sthmpsn,DC=com
0
ihenryCommented:
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
NickMalloySystems LeadAuthor Commented:
Yes and yes.

 I am using Dreamweaver for my coding so I have no idea how to debug to get you that value.
0
ihenryCommented:
Use Response.Write( ds )
0
NickMalloySystems LeadAuthor Commented:
ds = CN=Users,DC=sthmpsn,DC=com
0
ihenryCommented:

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
ihenryCommented:
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
NickMalloySystems LeadAuthor Commented:
still the same
0
ihenryCommented:
hm..forgot to ask. do you enable anonymous access in the IIS security settings?
0
NickMalloySystems LeadAuthor Commented:
no
0
ihenryCommented:
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
NickMalloySystems LeadAuthor Commented:
[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
NickMalloySystems LeadAuthor Commented:
new error I just noticed
0
ihenryCommented:
yup, commenting out this line
objUser.Properties("userAccountControl").add(512)
0
NickMalloySystems LeadAuthor Commented:
user shows up but account is disabled.
0
ihenryCommented:
yup, but what is new created userAccountControl attribute value, by default 512 should be included automatically.
0
NickMalloySystems LeadAuthor Commented:
so what do I ned to do so that the user isn't disabled when he is created?
0
ihenryCommented:
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
ihenryCommented:
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
NickMalloySystems LeadAuthor Commented:
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
ihenryCommented:
>> 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
NickMalloySystems LeadAuthor Commented:
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
ihenryCommented:
sorry, understood it wrongly.

you mean, ms exchange?
0
NickMalloySystems LeadAuthor Commented:
yeah
0
ihenryCommented:
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
ihenryCommented:
I've gotta sign off another few minutes. Good luck for you!
0
NickMalloySystems LeadAuthor Commented:
thanks for all your help
0
ihenryCommented:
you're welcome!
0
ihenryCommented:
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
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
ASP.NET

From novice to tech pro — start learning today.

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.