I am trying to create a page where my users can go to update their information in Active Directory. I am able to pull the information out without any problem, but when I try to write back any changes, I get a "General Access Denied Error." I have been searching for solutions to the problem, but I have not been able to find anything.
Here is the stack trace for the error I am getting
[UnauthorizedAccessException: General access denied error
]
System.DirectoryServices.Interop.IAds.SetInfo() +0
System.DirectoryServices.DirectoryEntry.CommitChanges() +147
ADUser.UpdateUserProperty(String propertyName, String propertyValue) +158
MyInfo.SaveUserInfo() +526
MyInfo.SubmitChanges(Object sender, EventArgs e) +7
System.Web.UI.WebControls.Button.OnClick(EventArgs e) +105
System.Web.UI.WebControls.Button.RaisePostBackEvent(String eventArgument) +107
System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +7
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +11
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +33
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +5102
|
I would like for the site to use the user's credentials to perform the operation (not sure if this is possible).
I have created my own Classes that take care of my interfacing with Active Directory, and I have seem to have a problem with them until know. I do not want to post all of the code, as it may be a little long. I am going to try to include all the relevant pieces, if you need to see more, I'll post it.
This is the sub on the web page that is responsible for the updating.
Private Sub SaveUserInfo()
ThisUser = New ADUser(My.User.Name, ConfigurationManager.ConnectionStrings("ADConnectionString").ConnectionString, "SpiritBank\" & Session("username"), Session("password"))
With ThisUser
.FirstName = txtFName.Text
.MiddleName = txtMName.Text
.LastName = txtLName.Text
.DisplayName = txtDisplayName.Text
.Title = txtTitle.Text
.Department = ddlDepartment.SelectedValue
.Office = ddlLocation.SelectedValue
.HomePhone = txtHomePhone.Text
.HomeEmail = txtHomeEmail.Text
.PrimaryPhone = txtWorkPhone.Text
.Pager = txtPager.Text
.MobilePhone = txtCellPhone.Text
.Fax = txtFax.Text
.OtherWorkPhone = txtAlternatePhone.Text
.HomeAddress = txtHomeAddress1.Text & vbCrLf & txtHomeAddress2.Text & vbCrLf & txtHomeCity.Text & "," & txtHomeState.Text & vbTab & txtHomeZip.Text
.Company = txtCompany.Text
.Initials = CreateInitials()
End With
ThisUser.Dispose()
End Sub
ADUser is the class that I created to handle all my interactions with Active Directory.
Here is one of the property definitions from ADUser
Public Property DisplayName() As String
Get
Return GetPropertyValue("displayName")
End Get
Set(ByVal value As String)
UpdateUserProperty(
"displayName", value)
End Set
End Property
Here is the UpdateUserProperty Sub
Private Sub UpdateUserProperty(ByVal propertyName As String, ByVal propertyValue As String)
If GetPropertyValue(propertyName) <> propertyValue Then
If userDE.Properties(propertyName).Count = 0 Then
userDE.Properties(propertyName).Add(propertyValue)
Else
userDE.Properties(propertyName)(0) = propertyValue
End If
userDE.CommitChanges()
End If
End Sub
The error is always thrown when it makes the call to CommitChanges.
The following code is where I create the userDE object
Dim DE As DirectoryEntry = Nothing
Dim DS As DirectorySearcher = Nothing
Try
DE =
New DirectoryEntry(LdapPath, Me.UserName, Me.Password)
DS =
New DirectorySearcher(DE)
DS.Filter =
"(sAMAccountName=" & _user & ")"
Dim sr As SearchResult = DS.FindOne
userDE =
New DirectoryEntry(sr.Path)
Catch Null As NullReferenceException
Dim errMsg As String = stringManager.GetString("UserDoesNotExistMessage", Globalization.CultureInfo.CurrentUICulture)
errMsg = errMsg.Replace(
"VALUE", value)
Throw New UserDoesNotExistException(errMsg, Null)
Finally
If DS IsNot Nothing Then DS.Dispose()
If DE IsNot Nothing Then DE.Dispose()
End Try
The username and password that are used with the new DirectoryEntry call are the same ones that are being passed in when a new ADUser object is created.
I hope this helps someone figure out what I am doing wrong.
Any and all help will be greatly appreciated.