NickMalloy
asked on
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.D irectoryEn try(CStr(A pplication ("")))
Dim objUser As DirectoryServices.Director yEntry = New DirectoryServices.Director yEntry
objUser = objDE.children.Add("cn=" & login.text & "","user")
objUser.Properties("sAMAcc ountName") .add(login .text)
objUser.Properties("sn").a dd(lname.t ext)
objUser.Properties("displa yName").ad d(lname.te xt & "," & fname.text)
objUser.Properties("teleph oneNumber" ).add(tel. text)
objUser.Properties("mail") .add(email .text)
objUser.Properties("userAc countContr ol").add(5 12)
objUser.commitChanges()
objUser.Invoke("setPasswor d", "sweet98")
objUser.commitChanges()
Dim objDE As New System.DirectoryServices.D
Dim objUser As DirectoryServices.Director
objUser = objDE.children.Add("cn=" & login.text & "","user")
objUser.Properties("sAMAcc
objUser.Properties("sn").a
objUser.Properties("displa
objUser.Properties("teleph
objUser.Properties("mail")
objUser.Properties("userAc
objUser.commitChanges()
objUser.Invoke("setPasswor
objUser.commitChanges()
Can you post here the exception stack trace?
ASKER
Stack Trace:
[UnauthorizedAccessExcepti
]
System.DirectoryServices.I
System.DirectoryServices.D
ASP.addaduser_aspx.add_ad(
System.Web.UI.WebControls.
System.Web.UI.WebControls.
System.Web.UI.Page.RaisePo
System.Web.UI.Page.RaisePo
System.Web.UI.Page.Process
stack trace when the setpassword is moved. up
[COMException (0x80072030): There is no such object on the server.]
[TargetInvocationException
System.RuntimeType.InvokeD
System.RuntimeType.InvokeM
System.Type.InvokeMember(S
System.DirectoryServices.D
ASP.addaduser_aspx.add_ad(
System.Web.UI.WebControls.
System.Web.UI.WebControls.
System.Web.UI.Page.RaisePo
System.Web.UI.Page.RaisePo
System.Web.UI.Page.Process
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?
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?
ASKER
no it doesn't create a user.
Line 27: objUser.commitChanges()
Line 27: objUser.commitChanges()
this?
objUser.commitChanges()
objUser.Invoke("setPasswor d", "sweet98")
objUser.commitChanges() <-- line 27?
objUser.commitChanges()
objUser.Invoke("setPasswor
objUser.commitChanges() <-- line 27?
NickMalloy,
You have 2 lines which have objUser.commitChanges().
You have 2 lines which have objUser.commitChanges().
ASKER
That is to set the password if I am correct
ASKER
Are you saying it should look like this?
objUser = objDE.children.Add("cn=" & login.text & "","user")
objUser.Properties("sAMAcc ountName") .add(login .text)
objUser.Properties("sn").a dd(lname.t ext)
objUser.Properties("displa yName").ad d(lname.te xt & "," & fname.text)
objUser.Properties("teleph oneNumber" ).add(tel. text)
objUser.Properties("mail") .add(email .text)
objUser.commitChanges()
objUser.Invoke("setPasswor d", "sweet98")
objUser.commitChanges()
objUser.Properties("userAc countContr ol").add(5 12)
objUser.commitChanges()
objUser = objDE.children.Add("cn=" & login.text & "","user")
objUser.Properties("sAMAcc
objUser.Properties("sn").a
objUser.Properties("displa
objUser.Properties("teleph
objUser.Properties("mail")
objUser.commitChanges()
objUser.Invoke("setPasswor
objUser.commitChanges()
objUser.Properties("userAc
objUser.commitChanges()
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("userAc countContr ol").add(5 12)
objUser.commitChanges() <-- here
objUser.Invoke("setPasswor d", "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?
objUser.Properties("mail")
objUser.Properties("userAc
objUser.commitChanges() <-- here
objUser.Invoke("setPasswor
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?
When the SetPassword is moved up, it seems you have another problem.
I'm not sure if this line works
objUser.Invoke("setPasswor d", "sweet98")
I'm using the following lines and it works great
objUser.Invoke( "setPassword", New Object() { "sweet98" } )
I'm not sure if this line works
objUser.Invoke("setPasswor
I'm using the following lines and it works great
objUser.Invoke( "setPassword", New Object() { "sweet98" } )
ASKER
The first one is throwing it.
objUser.Properties("mail") .add(email .text)
objUser.Properties("userAc countContr ol").add(5 12)
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.
objUser.Properties("mail")
objUser.Properties("userAc
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.
Lets narrowing the problem down to whether you are able to bind to AD in the first place
Dim objDE As New System.DirectoryServices.D irectoryEn try()
Dim ldapPath As String = "LDAP://<SERVER_NAME>/bla. .bla.."
objDE.Path = Path
objDE.RefreshCache()
Try to run the above code and see what happen.
Dim objDE As New System.DirectoryServices.D
Dim ldapPath As String = "LDAP://<SERVER_NAME>/bla.
objDE.Path = Path
objDE.RefreshCache()
Try to run the above code and see what happen.
ASKER
is it really objDE.Path = Path or what is path suppose to be?
oops..sorry..that should be
objDE.Path = ldapPath
objDE.Path = ldapPath
ASKER
okay the page simply reloaded.
Try more code and execute it
Dim objDE As New System.DirectoryServices.D irectoryEn try()
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("distingu ishedName" ).Value
Dim objUser As DirectoryServices.Director yEntry = objDE.children.Add("cn=" & login.text & "","user")
objUser.Properties("sAMAcc ountName") .add(login .text)
objUser.Properties("sn").a dd(lname.t ext)
objUser.Properties("displa yName").ad d(lname.te xt & "," & fname.text)
objUser.Properties("teleph oneNumber" ).add(tel. text)
objUser.Properties("mail") .add(email .text)
objUser.Properties("userAc countContr ol").add(5 12)
objUser.commitChanges()
Dim objDE As New System.DirectoryServices.D
Dim ldapPath As String = "LDAP://<SERVER_NAME>/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("distingu
Dim objUser As DirectoryServices.Director
objUser.Properties("sAMAcc
objUser.Properties("sn").a
objUser.Properties("displa
objUser.Properties("teleph
objUser.Properties("mail")
objUser.Properties("userAc
objUser.commitChanges()
ASKER
that line didn't produce an error when the bottom part is left off. This code produces an error
UnauthorizedAccessExceptio n: General access denied error
]
System.DirectoryServices.I nterop.IAd s.SetInfo( ) +0
System.DirectoryServices.D irectoryEn try.Commit Changes() +37
ASP.addaduser_aspx.add_ad( Object Source, EventArgs E) in D:\Intranet\Mystuff\Mystuf f\addaduse r.aspx:43
System.Web.UI.WebControls. Button.OnC lick(Event Args e) +108
System.Web.UI.WebControls. Button.Sys tem.Web.UI .IPostBack EventHandl er.RaisePo stBackEven t(String eventArgument) +57
System.Web.UI.Page.RaisePo stBackEven t(IPostBac kEventHand ler sourceControl, String eventArgument) +18
System.Web.UI.Page.RaisePo stBackEven t(NameValu eCollectio n postData) +33
System.Web.UI.Page.Process RequestMai n() +1277
UnauthorizedAccessExceptio
]
System.DirectoryServices.I
System.DirectoryServices.D
ASP.addaduser_aspx.add_ad(
System.Web.UI.WebControls.
System.Web.UI.WebControls.
System.Web.UI.Page.RaisePo
System.Web.UI.Page.RaisePo
System.Web.UI.Page.Process
hm..can you post the ldapPath value?
and the return value from this line
Dim ds As String = objDE.Properties("distingu ishedName" ).Value
and the return value from this line
Dim ds As String = objDE.Properties("distingu
ASKER
how do I get the return value for ds???
ASKER
Here is the path
LDAP://CN=Users,DC=sthmpsn ,DC=com
LDAP://CN=Users,DC=sthmpsn
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?
ASKER
Yes and yes.
I am using Dreamweaver for my coding so I have no idea how to debug to get you that value.
I am using Dreamweaver for my coding so I have no idea how to debug to get you that value.
Use Response.Write( ds )
ASKER
ds = CN=Users,DC=sthmpsn,DC=com
Try to include server name in the ldapPath, like this
Dim objDE As New System.DirectoryServices.D
Dim ldapPath As String = "LDAP://<SERVER_NAME>//CN=
objDE.Path = ldapPath
objDE.AuthenticationType = AuthenticationTypes.Server
objDE.RefreshCache()
Dim ds As String = objDE.Properties("distingu
Dim objUser As DirectoryServices.Director
objUser.Properties("sAMAcc
objUser.Properties("sn").a
objUser.Properties("displa
objUser.Properties("teleph
objUser.Properties("mail")
objUser.Properties("userAc
objUser.commitChanges()
And run the code
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.
ASKER
still the same
hm..forgot to ask. do you enable anonymous access in the IIS security settings?
ASKER
no
Or pass the user name and password explicitly in your code
Dim objDE As New System.DirectoryServices.D irectoryEn try()
Dim ldapPath As String = "LDAP://<SERVER_NAME>//CN= Users,DC=s thmpsn,DC= com"
objDE.Username = "Domain/theUserAccount"
objDE.Username = "thePassword"
objDE.Path = ldapPath
objDE.AuthenticationType = AuthenticationTypes.Server Bind
objDE.RefreshCache()
...
...
Dim objDE As New System.DirectoryServices.D
Dim ldapPath As String = "LDAP://<SERVER_NAME>//CN=
objDE.Username = "Domain/theUserAccount"
objDE.Username = "thePassword"
objDE.Path = ldapPath
objDE.AuthenticationType = AuthenticationTypes.Server
objDE.RefreshCache()
...
...
ASKER
[COMException (0x80072035): The server is unwilling to process the request.]
System.DirectoryServices.I nterop.IAd s.SetInfo( ) +0
System.DirectoryServices.D irectoryEn try.Commit Changes() +37
ASP.addaduser_aspx.add_ad( Object Source, EventArgs E) in D:\Intranet\llctest\addadu ser.aspx:4 4
System.Web.UI.WebControls. Button.OnC lick(Event Args e) +108
System.Web.UI.WebControls. Button.Sys tem.Web.UI .IPostBack EventHandl er.RaisePo stBackEven t(String eventArgument) +57
System.Web.UI.Page.RaisePo stBackEven t(IPostBac kEventHand ler sourceControl, String eventArgument) +18
System.Web.UI.Page.RaisePo stBackEven t(NameValu eCollectio n postData) +33
System.Web.UI.Page.Process RequestMai n() +1277
System.DirectoryServices.I
System.DirectoryServices.D
ASP.addaduser_aspx.add_ad(
System.Web.UI.WebControls.
System.Web.UI.WebControls.
System.Web.UI.Page.RaisePo
System.Web.UI.Page.RaisePo
System.Web.UI.Page.Process
ASKER
new error I just noticed
yup, commenting out this line
objUser.Properties("userAc countContr ol").add(5 12)
objUser.Properties("userAc
ASKER
user shows up but account is disabled.
yup, but what is new created userAccountControl attribute value, by default 512 should be included automatically.
ASKER
so what do I ned to do so that the user isn't disabled when he is created?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
The ADS_UF_ACCOUNTDISABLE is equal to 2
or you can just do this if no other settings required
objUser.Properties["userAc countContr ol"].Value = 512
objUser.commitChanges()
or you can just do this if no other settings required
objUser.Properties["userAc
objUser.commitChanges()
ASKER
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.
>> 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.
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.
ASKER
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.
sorry, understood it wrongly.
you mean, ms exchange?
you mean, ms exchange?
ASKER
yeah
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.
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.
I've gotta sign off another few minutes. Good luck for you!
ASKER
thanks for all your help
you're welcome!
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.
>> ...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.