Products

Solutions

Resources

Partners

Community

Blog

About

QA

Ideas Test

New Community Website

Ordinarily, you'd be at the right spot, but we've recently launched a brand new community website... For the community, by the community.

Yay... Take Me to the Community!

Welcome to the DNN Community Forums, your preferred source of online community support for all things related to DNN.
In order to participate you must be a registered DNNizen

HomeHomeDNN Open Source...DNN Open Source...Provider and Extension ForumsProvider and Extension ForumsAuthenticationAuthenticationAD Fixes - Post YourAD Fixes - Post Your's Here
Previous
 
Next
New Post
8/7/2007 4:12 PM
 

hi

I tried to download the DNN AD fix for 3.3.7.  Though description says its for ver 3.3.7, the Dotnetnuke.dll 's version in the zip file is 3.3.5.  Appreciate if you can check this?

Thanks.

 
New Post
12/31/2007 2:12 AM
 

If you have to deal with an overly aggressive network administrator and can't or don't what to run your whole site under an impersonated user id, make the following changes to your ADSI Provider.  I have used this method with all versions of  the DotNetNuke AD code but the code listed here is for 4.06x + code.


1. un-comment the <identity impersonate="true" /> but do not add a userid password.


2. Add the following class to your ADSIProvider project (you will need the Active Directory Provider source code)

********************* Copy From Here *******************************
Imports Microsoft.VisualBasic
Imports System.Web
Imports System.Web.Security
Imports System.Security.Principal
Imports System.Runtime.InteropServices

Namespace DotNetNuke.Authentication.ActiveDirectory.ADSI

    Public Class ImpersonateUser

        Private LOGON32_LOGON_INTERACTIVE As Integer = 2
        Private LOGON32_LOGON_NETWORK As Integer = 3
        Private LOGON32_PROVIDER_DEFAULT As Integer = 0

        Private impersonationContext As WindowsImpersonationContext

        Declare Function LogonUserA Lib "advapi32.dll" (ByVal lpszUsername As String, _
                                ByVal lpszDomain As String, _
                                ByVal lpszPassword As String, _
                                ByVal dwLogonType As Integer, _
                                ByVal dwLogonProvider As Integer, _
                                ByRef phToken As IntPtr) As Integer

        Declare Auto Function DuplicateToken Lib "advapi32.dll" ( _
                                ByVal ExistingTokenHandle As IntPtr, _
                                ByVal ImpersonationLevel As Integer, _
                                ByRef DuplicateTokenHandle As IntPtr) As Integer

        Declare Auto Function RevertToSelf Lib "advapi32.dll" () As Long
        Declare Auto Function CloseHandle Lib "kernel32.dll" (ByVal handle As IntPtr) As Long

        Public Function impersonateValidUser(ByVal userName As String, _
                                             ByVal domain As String, _
                                             ByVal password As String) As Boolean

            Dim tempWindowsIdentity As WindowsIdentity
            Dim token As IntPtr = IntPtr.Zero
            Dim tokenDuplicate As IntPtr = IntPtr.Zero
            impersonateValidUser = False

            If CBool(RevertToSelf()) Then
                If LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE, _
                         LOGON32_PROVIDER_DEFAULT, token) <> 0 Then
                    If DuplicateToken(token, 2, tokenDuplicate) <> 0 Then
                        tempWindowsIdentity = New WindowsIdentity(tokenDuplicate)
                        impersonationContext = tempWindowsIdentity.Impersonate()
                        If Not impersonationContext Is Nothing Then
                            impersonateValidUser = True
                        End If
                    End If
                End If
            End If
            If Not tokenDuplicate.Equals(IntPtr.Zero) Then
                CloseHandle(tokenDuplicate)
            End If
            If Not token.Equals(IntPtr.Zero) Then
                CloseHandle(token)
            End If
        End Function

        Public Sub undoImpersonation()
            If Not impersonationContext Is Nothing Then
                impersonationContext.Undo()
            End If
        End Sub

    End Class
End Namespace
********************* To Here *******************************


3. Replace the new function in the Configuration.vb file with the following function.  The actual new 4 lines end with the commit '***ImpersonateUser***

********************* Copy From Here *******************************
        Sub New()
   Dim UseUser As New ImpersonateUser   '***ImpersonateUser***
            Dim authConfig As DotNetNuke.Authentication.ActiveDirectory.Configuration = DotNetNuke.Authentication.ActiveDirectory.Configuration.GetConfig()

            mPortalId = authConfig.PortalId

            Try
                'Temporary fix this setting as TRUE for design, to be removed when release
                mConfigDomainPath = authConfig.RootDomain
                mDefaultEmailDomain = authConfig.EmailDomain
                mUserName = authConfig.UserName
                mPassword = authConfig.Password
                mAuthenticationType = CType([Enum].Parse(GetType(AuthenticationTypes), authConfig.AuthenticationType), AuthenticationTypes)
                ' IMPORTANT: Remove ADSIPath, to be added later depends on accessing method

                mRootDomainPath = ADSI.Utilities.ValidateDomainPath(mConfigDomainPath)
                mRootDomainPath = Right(mRootDomainPath, mRootDomainPath.Length - mRootDomainPath.IndexOf("DC="))

            Catch exc As Exception
                mProcessLog += exc.Message & "<br>"
            End Try

            UseUser.impersonateValidUser(mUserName, mConfigDomainPath, mPassword)   '***ImpersonateUser***
            ' Also check if Authentication implemented in this Windows Network
            Dim gc As New DirectoryEntry
            Try
                If DirectoryEntry.Exists("GC://rootDSE") Then
                    Dim rootGC As DirectoryEntry
                    If (mUserName.Length > 0) AndAlso (mPassword.Length > 0) Then
                        rootGC = New DirectoryEntry("GC://rootDSE", mUserName, mPassword, mAuthenticationType)
                    Else
                        rootGC = New DirectoryEntry("GC://rootDSE")
                    End If
                    mConfigurationPath = rootGC.Properties(ADSI_CONFIGURATIONNAMIMGCONTEXT).Value.ToString
                    mADSINetwork = True
                End If
            Catch exc As System.Runtime.InteropServices.COMException
                mADSINetwork = False
                mLDAPAccesible = False
                mProcessLog += exc.Message & "<br>"
                LogException(exc)
                UseUser.undoImpersonation()   '***ImpersonateUser***
                ' Nothing to do if we could not access Global Catalog, so return
                Return
            End Try

            ' Also check if LDAP fully accessible
            Dim ldap As New DirectoryEntry
            Try
                If DirectoryEntry.Exists("LDAP://rootDSE") Then
                    mLDAPAccesible = True
                    mRefCollection = New ADSI.CrossReferenceCollection(mUserName, mPassword, mAuthenticationType)
                End If
            Catch exc As System.Runtime.InteropServices.COMException
                mLDAPAccesible = False
                mProcessLog += exc.Message & "<br>"
                LogException(exc)
            End Try

            UseUser.undoImpersonation()   '***ImpersonateUser***
        End Sub

********************* To Here *******************************

4. Compile the DotNetNuke.Authentication.ActiveDirectory.dll and configure the provider as you normally would and the new code will use the provide user id and password when integrating AD during the configuration process.

As long as the supplied user has read access to your AD this code should work no matter how tight the security is. I would also like to apologize for requiring you to cut and paste, but I just lost my personal web server due to a hardware failure and current have no place to host the files for download.

 
New Post
1/2/2008 5:45 PM
 

Nice work Charles. Getting rid of the need for impersonation is something I was planning on doing for the 02.00.00 release (Q1 2008).

 
New Post
1/11/2008 8:16 AM
 

Hi Mike

If an admin add a property (for example : employeeNumber, company, department, etc.), he current provider won't update theses values.

My fix read added properties and update them.

SQL Stored Procedure :

 

                        

CREATE PROCEDURE dbo.[GetAddedPropertyDefinition]
 @PortalID INT
AS

SELECT dbo.ProfilePropertyDefinition.PropertyName
FROM dbo.ProfilePropertyDefinition
WHERE PortalID = @PortalID
AND Deleted = 0
AND PropertyName
 NOT IN (SELECT PropertyName FROM ProfilePropertyDefinition WHERE PortalID IS NULL)

GO

 

And the fix is in ADSIProvider.vb

                                       

Private Sub FillUserInfo(ByVal UserEntry As DirectoryEntry, ByVal UserInfo As UserInfo)

    ' web-inside fix - START
    ' Load personnal added properties for the current portal
    ' I suppose these two lines are not in the right place :/
    Dim AddedPropertiesTable As DataTable = New DataTable()
    AddedPropertiesTable.Load(CType(DataProvider.Instance().ExecuteSQL("EXEC dbo.GetAddedPropertyDefinition '" & Me._portalSettings.PortalId & "'"), IDataReader))
    ' web-inside fix - END

    With UserInfo
        .IsSuperUser = False
        .Username = UserInfo.Username
        .Membership.Approved = True
        .Membership.LastLoginDate = Date.Today()
        .Email = Utilities.CheckNullString(UserEntry.Properties(Configuration.ADSI_EMAIL).Value)
        .CName = Utilities.CheckNullString(UserEntry.Properties(Configuration.ADSI_CNAME).Value.ToString)
        .DisplayName = Utilities.CheckNullString(UserEntry.Properties(Configuration.ADSI_DISPLAYNAME).Value)
        If .DisplayName = "" Then
            .DisplayName = .CName
        End If
        .DistinguishedName = Utilities.CheckNullString(UserEntry.Properties(Configuration.ADSI_DISTINGUISHEDNAME).Value.ToString)
        .sAMAccountName = Utilities.CheckNullString(UserEntry.Properties(Configuration.ADSI_ACCOUNTNAME).Value.ToString)
        .Profile.FirstName = Utilities.CheckNullString(UserEntry.Properties(Configuration.ADSI_FIRSTNAME).Value)
        .Profile.LastName = Utilities.CheckNullString(UserEntry.Properties(Configuration.ADSI_LASTNAME).Value)
        .Profile.Street = Utilities.CheckNullString(UserEntry.Properties(Configuration.ADSI_STREET).Value)
        .Profile.City = Utilities.CheckNullString(UserEntry.Properties(Configuration.ADSI_CITY).Value)
        .Profile.Region = Utilities.CheckNullString(UserEntry.Properties(Configuration.ADSI_REGION).Value)
        .Profile.PostalCode = Utilities.CheckNullString(UserEntry.Properties(Configuration.ADSI_POSTALCODE).Value)
        .Profile.Country = Utilities.CheckNullString(UserEntry.Properties(Configuration.ADSI_COUNTRY).Value)
        .Profile.Telephone = Utilities.CheckNullString(UserEntry.Properties(Configuration.ADSI_TELEPHONE).Value)
        .Profile.Fax = Utilities.CheckNullString(UserEntry.Properties(Configuration.ADSI_FAX).Value)
        .Profile.Cell = Utilities.CheckNullString(UserEntry.Properties(Configuration.ADSI_CELL).Value)
        .Profile.Website = Utilities.CheckNullString(UserEntry.Properties(Configuration.ADSI_WEBSITE).Value)

        ' web-inside fix - START
        ' Test if propertyName exist on ActiveDirectory
        For Each propertyNameRow As DataRow In AddedPropertiesTable.Rows
            Try
                Dim propertyName As String = CType(propertyNameRow(0), String)
                .Profile.SetProfileProperty(propertyName, Utilities.CheckNullString(UserEntry.Properties(propertyName).Value))
            Catch ex As Exception
                ' Nothing to Do??
                ' Should add a second Try/Catch to read in LDAP and not in GC - problem of replication -
            End Try
        Next
        ' web-inside fix - END

        .AuthenticationExists = True
        ' obtain firstname from username if admin has not enter enough user info
        If .Profile.FirstName.Length = 0 Then
            .Profile.FirstName = Utilities.TrimUserDomainName(UserInfo.Username)
        End If
    End With
End Sub

 

 I hope it will help on your job

 

 
New Post
7/25/2008 10:14 AM
 

I have an idea for an AD upgrade that may or may not have already been mentioned.

When a user logs in, the webserver authenticates with AD and details such as their name, display name, telephone number, email address etc get synchronised with AD. The question is that I want to add a new profile property, say Title (Job Title) and when a user logs in, I would like title to synchronise with the field title in the AD Schema for that user. Is this something that you might be looking at?

Thanks

 
Previous
 
Next
HomeHomeDNN Open Source...DNN Open Source...Provider and Extension ForumsProvider and Extension ForumsAuthenticationAuthenticationAD Fixes - Post YourAD Fixes - Post Your's Here


These Forums are dedicated to discussion of DNN Platform and Evoq Solutions.

For the benefit of the community and to protect the integrity of the ecosystem, please observe the following posting guidelines:

  1. No Advertising. This includes promotion of commercial and non-commercial products or services which are not directly related to DNN.
  2. No vendor trolling / poaching. If someone posts about a vendor issue, allow the vendor or other customers to respond. Any post that looks like trolling / poaching will be removed.
  3. Discussion or promotion of DNN Platform product releases under a different brand name are strictly prohibited.
  4. No Flaming or Trolling.
  5. No Profanity, Racism, or Prejudice.
  6. Site Moderators have the final word on approving / removing a thread or post or comment.
  7. English language posting only, please.
What is Liquid Content?
Find Out
What is Liquid Content?
Find Out
What is Liquid Content?
Find Out