Re: How does LogonUser API work to prevent impersonating users?

From: Damon S. (DamonS_at_discussions.microsoft.com)
Date: 08/18/04


Date: Wed, 18 Aug 2004 10:55:03 -0700

Agreeing with Rob, if a user is already authenticated to the Window Network
why have them login again?
But, if you must, because of an old-school user requirement thinking
passwords are safer than locking your computer, use this Managed .NET SSPI
authenticate code I wrote and not the unmanaged crap.

Imports System.Runtime.InteropServices
Module SSPIValidate
  Private Const HEAP_ZERO_MEMORY As Integer = &H8

  Private Const SEC_WINNT_AUTH_IDENTITY_ANSI As Integer = &H1

  Private Const SECBUFFER_TOKEN As Integer = &H2

  Private Const SECURITY_NATIVE_DREP As Integer = &H10

  Private Const SECPKG_CRED_INBOUND As Integer = &H1
  Private Const SECPKG_CRED_OUTBOUND As Integer = &H2

  Private Const SEC_I_CONTINUE_NEEDED As Integer = &H90312
  Private Const SEC_I_COMPLETE_NEEDED As Integer = &H90313
  Private Const SEC_I_COMPLETE_AND_CONTINUE As Integer = &H90314

  Private Const VER_PLATFORM_WIN32_NT As Integer = &H2

    Private Structure SecPkgInfo
        Dim fCapabilities As Integer
        Dim wVersion As Short
        Dim wRPCID As Short
        Dim cbMaxToken As Integer
        Dim Name As Integer
        Dim Comment As Integer
    End Structure

    Private Structure SecHandle
        Dim dwLower As Integer
        Dim dwUpper As Integer
    End Structure

    Private Structure AUTH_SEQ
        Dim fInitialized As Boolean
        Dim fHaveCredHandle As Boolean
        Dim fHaveCtxtHandle As Boolean
        Dim hcred As SecHandle
        Dim hctxt As SecHandle
    End Structure

    Private Structure SEC_WINNT_AUTH_IDENTITY
        Dim User As String
        Dim UserLength As Integer
        Dim Domain As String
        Dim DomainLength As Integer
        Dim Password As String
        Dim PasswordLength As Integer
        Dim Flags As Integer
    End Structure

    Private Structure TimeStamp
        Dim LowPart As Integer
        Dim HighPart As Integer
    End Structure

    Private Structure SecBuffer
        Dim cbBuffer As Integer
        Dim BufferType As Integer
        Dim pvBuffer As Integer
    End Structure

    Private Structure SecBufferDesc
        Dim ulVersion As Integer
        Dim cBuffers As Integer
        Dim pBuffers As Integer
    End Structure

    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory"
(ByVal Destination As Integer, ByRef Source As SecBuffer, ByVal Length As
Integer)
    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory"
(ByRef Destination As SecBuffer, ByVal Source As Integer, ByVal Length As
Integer)
    Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory"
(ByRef Destination As SecPkgInfo, ByVal Source As Integer, ByVal Length As
Integer)

    Private Declare Function NT4QuerySecurityPackageInfo Lib "security"
Alias "QuerySecurityPackageInfoA" (ByVal PackageName As String, ByRef
pPackageInfo As Integer) As Integer
    Private Declare Function QuerySecurityPackageInfo Lib "secur32" Alias
"QuerySecurityPackageInfoA" (ByVal PackageName As String, ByRef pPackageInfo
As Integer) As Integer

    Private Declare Function NT4FreeContextBuffer Lib "security" Alias
"FreeContextBuffer" (ByVal pvContextBuffer As Integer) As Integer
    Private Declare Function FreeContextBuffer Lib "secur32" (ByVal
pvContextBuffer As Integer) As Integer

    Private Declare Function NT4InitializeSecurityContext Lib "security"
Alias "InitializeSecurityContextA" _
          (ByRef phCredential As SecHandle, ByRef phContext As SecHandle, _
          ByVal pszTargetName As Integer, ByVal fContextReq As Integer, _
          ByVal Reserved1 As Integer, ByVal TargetDataRep As Integer, _
          ByRef pInput As SecBufferDesc, ByVal Reserved2 As Integer, _
          ByRef phNewContext As SecHandle, ByRef pOutput As SecBufferDesc, _
          ByRef pfContextAttr As Integer, ByRef ptsExpiry As TimeStamp) As
Integer
    Private Declare Function InitializeSecurityContext Lib "secur32" _
          Alias "InitializeSecurityContextA" _
          (ByRef phCredential As SecHandle, ByRef phContext As SecHandle, _
          ByVal pszTargetName As Integer, ByVal fContextReq As Integer, _
          ByVal Reserved1 As Integer, ByVal TargetDataRep As Integer, _
          ByRef pInput As SecBufferDesc, ByVal Reserved2 As Integer, _
          ByRef phNewContext As SecHandle, ByRef pOutput As SecBufferDesc, _
          ByRef pfContextAttr As Integer, ByRef ptsExpiry As TimeStamp) As
Integer

    Private Declare Function NT4InitializeSecurityContext2 Lib "security"
Alias "InitializeSecurityContextA" _
          (ByRef phCredential As SecHandle, ByVal phContext As Integer, _
          ByVal pszTargetName As Integer, ByVal fContextReq As Integer, _
          ByVal Reserved1 As Integer, ByVal TargetDataRep As Integer, _
          ByVal pInput As Integer, ByVal Reserved2 As Integer, _
          ByRef phNewContext As SecHandle, ByRef pOutput As SecBufferDesc, _
          ByRef pfContextAttr As Integer, ByRef ptsExpiry As TimeStamp) As
Integer
    Private Declare Function InitializeSecurityContext2 Lib "secur32" Alias
"InitializeSecurityContextA" _
          (ByRef phCredential As SecHandle, ByVal phContext As Integer, _
          ByVal pszTargetName As Integer, ByVal fContextReq As Integer, _
          ByVal Reserved1 As Integer, ByVal TargetDataRep As Integer, _
          ByVal pInput As Integer, ByVal Reserved2 As Integer, _
          ByRef phNewContext As SecHandle, ByRef pOutput As SecBufferDesc, _
          ByRef pfContextAttr As Integer, ByRef ptsExpiry As TimeStamp) As
Integer

    Private Declare Function NT4AcquireCredentialsHandle Lib "security"
Alias "AcquireCredentialsHandleA" _
         (ByVal pszPrincipal As Integer, _
          ByVal pszPackage As String, ByVal fCredentialUse As Integer, _
          ByVal pvLogonId As Integer, _
          ByRef pAuthData As SEC_WINNT_AUTH_IDENTITY, _
          ByVal pGetKeyFn As Integer, ByVal pvGetKeyArgument As Integer, _
          ByRef phCredential As SecHandle, ByRef ptsExpiry As TimeStamp) As
Integer
    Private Declare Function AcquireCredentialsHandle Lib "secur32" Alias
"AcquireCredentialsHandleA" _
         (ByVal pszPrincipal As Integer, _
          ByVal pszPackage As String, ByVal fCredentialUse As Integer, _
          ByVal pvLogonId As Integer, _
          ByRef pAuthData As SEC_WINNT_AUTH_IDENTITY, _
          ByVal pGetKeyFn As Integer, ByVal pvGetKeyArgument As Integer, _
          ByRef phCredential As SecHandle, ByRef ptsExpiry As TimeStamp) As
Integer

    Private Declare Function NT4AcquireCredentialsHandle2 Lib "security"
Alias "AcquireCredentialsHandleA" _
         (ByVal pszPrincipal As Integer, _
          ByVal pszPackage As String, ByVal fCredentialUse As Integer, _
          ByVal pvLogonId As Integer, ByVal pAuthData As Integer, _
          ByVal pGetKeyFn As Integer, ByVal pvGetKeyArgument As Integer, _
          ByRef phCredential As SecHandle, ByRef ptsExpiry As TimeStamp) As
Integer
    Private Declare Function AcquireCredentialsHandle2 Lib "secur32" Alias
"AcquireCredentialsHandleA" _
         (ByVal pszPrincipal As Integer, _
          ByVal pszPackage As String, ByVal fCredentialUse As Integer, _
          ByVal pvLogonId As Integer, ByVal pAuthData As Integer, _
          ByVal pGetKeyFn As Integer, ByVal pvGetKeyArgument As Integer, _
          ByRef phCredential As SecHandle, ByRef ptsExpiry As TimeStamp) As
Integer

    Private Declare Function NT4AcceptSecurityContext Lib "security" Alias
"AcceptSecurityContext" _
         (ByRef phCredential As SecHandle, _
          ByRef phContext As SecHandle, ByRef pInput As SecBufferDesc, _
          ByVal fContextReq As Integer, ByVal TargetDataRep As Integer, _
          ByRef phNewContext As SecHandle, ByRef pOutput As SecBufferDesc, _
          ByRef pfContextAttr As Integer, ByRef ptsExpiry As TimeStamp) As
Integer
    Private Declare Function AcceptSecurityContext Lib "secur32" _
         (ByRef phCredential As SecHandle, _
          ByRef phContext As SecHandle, ByRef pInput As SecBufferDesc, _
          ByVal fContextReq As Integer, ByVal TargetDataRep As Integer, _
          ByRef phNewContext As SecHandle, ByRef pOutput As SecBufferDesc, _
          ByRef pfContextAttr As Integer, ByRef ptsExpiry As TimeStamp) As
Integer

    Private Declare Function NT4AcceptSecurityContext2 Lib "security" Alias
"AcceptSecurityContext" _
         (ByRef phCredential As SecHandle, _
          ByVal phContext As Integer, ByRef pInput As SecBufferDesc, _
          ByVal fContextReq As Integer, ByVal TargetDataRep As Integer, _
          ByRef phNewContext As SecHandle, ByRef pOutput As SecBufferDesc, _
          ByRef pfContextAttr As Integer, ByRef ptsExpiry As TimeStamp) As
Integer
    Private Declare Function AcceptSecurityContext2 Lib "secur32" Alias
"AcceptSecurityContext" _
         (ByRef phCredential As SecHandle, _
          ByVal phContext As Integer, ByRef pInput As SecBufferDesc, _
          ByVal fContextReq As Integer, ByVal TargetDataRep As Integer, _
          ByRef phNewContext As SecHandle, ByRef pOutput As SecBufferDesc, _
          ByRef pfContextAttr As Integer, ByRef ptsExpiry As TimeStamp) As
Integer

    Private Declare Function NT4CompleteAuthToken Lib "security" Alias
"CompleteAuthToken" _
         (ByRef phContext As SecHandle, _
          ByRef pToken As SecBufferDesc) As Integer
    Private Declare Function CompleteAuthToken Lib "secur32" _
         (ByRef phContext As SecHandle, _
          ByRef pToken As SecBufferDesc) As Integer

    Private Declare Function NT4DeleteSecurityContext Lib "security" _
          Alias "DeleteSecurityContext" (ByRef phContext As SecHandle) _
          As Integer
    Private Declare Function DeleteSecurityContext Lib "secur32" _
          (ByRef phContext As SecHandle) _
          As Integer

    Private Declare Function NT4FreeCredentialsHandle Lib "security" _
          Alias "FreeCredentialsHandle" (ByRef phContext As SecHandle) _
          As Integer
    Private Declare Function FreeCredentialsHandle Lib "secur32" _
          (ByRef phContext As SecHandle) _
          As Integer

    Private Declare Function GetProcessHeap Lib "kernel32" () As Integer

    Private Declare Function HeapAlloc Lib "kernel32" _
          (ByVal hHeap As Integer, ByVal dwFlags As Integer, _
          ByVal dwBytes As Integer) As Integer

    Private Declare Function HeapFree Lib "kernel32" (ByVal hHeap As
Integer, _
          ByVal dwFlags As Integer, ByVal lpMem As Integer) As Integer

    Dim g_NT4 As Boolean

    Private Function GenClientContext(ByRef AuthSeq As AUTH_SEQ, _
          ByRef AuthIdentity As SEC_WINNT_AUTH_IDENTITY, _
          ByVal pIn As Integer, ByVal cbIn As Integer, _
          ByVal pOut As Integer, ByRef cbOut As Integer, _
          ByRef fDone As Boolean) As Boolean

        Dim ss As Integer
        Dim tsExpiry As TimeStamp
        Dim sbdOut As SecBufferDesc
        Dim sbOut As SecBuffer
        Dim sbdIn As SecBufferDesc
        Dim sbIn As SecBuffer
        Dim fContextAttr As Integer

        GenClientContext = False

        If Not AuthSeq.fInitialized Then
            If g_NT4 Then
                ss = NT4AcquireCredentialsHandle(0&, "NTLM", _
                      SECPKG_CRED_OUTBOUND, 0&, AuthIdentity, 0&, 0&, _
                      AuthSeq.hcred, tsExpiry)
            Else
                ss = AcquireCredentialsHandle(0&, "NTLM", _
                      SECPKG_CRED_OUTBOUND, 0&, AuthIdentity, 0&, 0&, _
                      AuthSeq.hcred, tsExpiry)
            End If

            If ss < 0 Then
                Exit Function
            End If

            AuthSeq.fHaveCredHandle = True
        End If

        ' Prepare output buffer
        sbdOut.ulVersion = 0
        sbdOut.cBuffers = 1
        sbdOut.pBuffers = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
Marshal.SizeOf(sbOut))

        sbOut.cbBuffer = cbOut
        sbOut.BufferType = SECBUFFER_TOKEN
        sbOut.pvBuffer = pOut

        CopyMemory(sbdOut.pBuffers, sbOut, Marshal.SizeOf(sbOut))

        ' Prepare input buffer
        If AuthSeq.fInitialized Then
            sbdIn.ulVersion = 0
            sbdIn.cBuffers = 1
            sbdIn.pBuffers = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
Marshal.SizeOf(sbIn))

            sbIn.cbBuffer = cbIn
            sbIn.BufferType = SECBUFFER_TOKEN
            sbIn.pvBuffer = pIn

            CopyMemory(sbdIn.pBuffers, sbIn, Marshal.SizeOf(sbIn))
        End If

        If AuthSeq.fInitialized Then
            If g_NT4 Then
                ss = NT4InitializeSecurityContext(AuthSeq.hcred, _
                      AuthSeq.hctxt, 0&, 0, 0, SECURITY_NATIVE_DREP, sbdIn, _
                      0, AuthSeq.hctxt, sbdOut, fContextAttr, tsExpiry)
            Else
                ss = InitializeSecurityContext(AuthSeq.hcred, _
                      AuthSeq.hctxt, 0&, 0, 0, SECURITY_NATIVE_DREP, sbdIn, _
                      0, AuthSeq.hctxt, sbdOut, fContextAttr, tsExpiry)
            End If
        Else
            If g_NT4 Then
                ss = NT4InitializeSecurityContext2(AuthSeq.hcred, 0&, 0&, _
                      0, 0, SECURITY_NATIVE_DREP, 0&, 0, AuthSeq.hctxt, _
                      sbdOut, fContextAttr, tsExpiry)
            Else
                ss = InitializeSecurityContext2(AuthSeq.hcred, 0&, 0&, _
                      0, 0, SECURITY_NATIVE_DREP, 0&, 0, AuthSeq.hctxt, _
                      sbdOut, fContextAttr, tsExpiry)
            End If
        End If

        If ss < 0 Then
            GoTo FreeResourcesAndExit
        End If

        AuthSeq.fHaveCtxtHandle = True

        ' If necessary, complete token
        If ss = SEC_I_COMPLETE_NEEDED Or ss = SEC_I_COMPLETE_AND_CONTINUE Then
            If g_NT4 Then
                ss = NT4CompleteAuthToken(AuthSeq.hctxt, sbdOut)
            Else
                ss = CompleteAuthToken(AuthSeq.hctxt, sbdOut)
            End If

            If ss < 0 Then
                GoTo FreeResourcesAndExit
            End If
        End If

        CopyMemory(sbOut, sbdOut.pBuffers, Marshal.SizeOf(sbOut))
        cbOut = sbOut.cbBuffer

        If Not AuthSeq.fInitialized Then
            AuthSeq.fInitialized = True
        End If

        fDone = Not (ss = SEC_I_CONTINUE_NEEDED Or ss =
SEC_I_COMPLETE_AND_CONTINUE)

        GenClientContext = True

FreeResourcesAndExit:

        If sbdOut.pBuffers <> 0 Then
            HeapFree(GetProcessHeap(), 0, sbdOut.pBuffers)
        End If

        If sbdIn.pBuffers <> 0 Then
            HeapFree(GetProcessHeap(), 0, sbdIn.pBuffers)
        End If
    End Function

    Private Function GenServerContext(ByRef AuthSeq As AUTH_SEQ, _
          ByVal pIn As Integer, ByVal cbIn As Integer, _
          ByVal pOut As Integer, ByRef cbOut As Integer, _
          ByRef fDone As Boolean) As Boolean

        Dim ss As Integer
        Dim tsExpiry As TimeStamp
        Dim sbdOut As SecBufferDesc
        Dim sbOut As SecBuffer
        Dim sbdIn As SecBufferDesc
        Dim sbIn As SecBuffer
        Dim fContextAttr As Integer

        GenServerContext = False

        If Not AuthSeq.fInitialized Then
            If g_NT4 Then
                ss = NT4AcquireCredentialsHandle2(0&, "NTLM", _
                      SECPKG_CRED_INBOUND, 0&, 0&, 0&, 0&, AuthSeq.hcred, _
                      tsExpiry)
            Else
                ss = AcquireCredentialsHandle2(0&, "NTLM", _
                      SECPKG_CRED_INBOUND, 0&, 0&, 0&, 0&, AuthSeq.hcred, _
                      tsExpiry)
            End If

            If ss < 0 Then
                Exit Function
            End If

            AuthSeq.fHaveCredHandle = True
        End If

        ' Prepare output buffer
        sbdOut.ulVersion = 0
        sbdOut.cBuffers = 1
        sbdOut.pBuffers = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
Marshal.SizeOf(sbOut))

        sbOut.cbBuffer = cbOut
        sbOut.BufferType = SECBUFFER_TOKEN
        sbOut.pvBuffer = pOut

        CopyMemory(sbdOut.pBuffers, sbOut, Marshal.SizeOf(sbOut))

        ' Prepare input buffer
        sbdIn.ulVersion = 0
        sbdIn.cBuffers = 1
        sbdIn.pBuffers = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
Marshal.SizeOf(sbIn))

        sbIn.cbBuffer = cbIn
        sbIn.BufferType = SECBUFFER_TOKEN
        sbIn.pvBuffer = pIn

        CopyMemory(sbdIn.pBuffers, sbIn, Marshal.SizeOf(sbIn))

        If AuthSeq.fInitialized Then
            If g_NT4 Then
                ss = NT4AcceptSecurityContext(AuthSeq.hcred, AuthSeq.hctxt, _
                      sbdIn, 0, SECURITY_NATIVE_DREP, AuthSeq.hctxt, sbdOut, _
                      fContextAttr, tsExpiry)
            Else
                ss = AcceptSecurityContext(AuthSeq.hcred, AuthSeq.hctxt, _
                      sbdIn, 0&, SECURITY_NATIVE_DREP, AuthSeq.hctxt,
sbdOut, _
                      fContextAttr, tsExpiry)
            End If
        Else
            If g_NT4 Then
                ss = NT4AcceptSecurityContext2(AuthSeq.hcred, 0&, sbdIn, 0, _
                      SECURITY_NATIVE_DREP, AuthSeq.hctxt, sbdOut, _
                      fContextAttr, tsExpiry)
            Else
                ss = AcceptSecurityContext2(AuthSeq.hcred, 0&, sbdIn, 0, _
                      SECURITY_NATIVE_DREP, AuthSeq.hctxt, sbdOut, _
                      fContextAttr, tsExpiry)
            End If
        End If

        If ss < 0 Then
            GoTo FreeResourcesAndExit
        End If

        AuthSeq.fHaveCtxtHandle = True

        ' If necessary, complete token
        If ss = SEC_I_COMPLETE_NEEDED Or ss = SEC_I_COMPLETE_AND_CONTINUE Then
            If g_NT4 Then
                ss = NT4CompleteAuthToken(AuthSeq.hctxt, sbdOut)
            Else
                ss = CompleteAuthToken(AuthSeq.hctxt, sbdOut)
            End If

            If ss < 0 Then
                GoTo FreeResourcesAndExit
            End If
        End If

        CopyMemory(sbOut, sbdOut.pBuffers, Marshal.SizeOf(sbOut))
        cbOut = sbOut.cbBuffer

        If Not AuthSeq.fInitialized Then
            AuthSeq.fInitialized = True
        End If

        fDone = Not (ss = SEC_I_CONTINUE_NEEDED Or ss =
SEC_I_COMPLETE_AND_CONTINUE)

        GenServerContext = True

FreeResourcesAndExit:

        If sbdOut.pBuffers <> 0 Then
            HeapFree(GetProcessHeap(), 0, sbdOut.pBuffers)
        End If

        If sbdIn.pBuffers <> 0 Then
            HeapFree(GetProcessHeap(), 0, sbdIn.pBuffers)
        End If

    End Function

    Public Function SSPValidateUser(ByVal User As String, ByVal Domain As
String, ByVal Password As String) As Boolean
        Dim pSPI As Integer
        Dim SPI As SecPkgInfo
        Dim cbMaxToken As Integer

        Dim pClientBuf As Integer
        Dim pServerBuf As Integer

        Dim ai As SEC_WINNT_AUTH_IDENTITY

        Dim asClient As AUTH_SEQ
        Dim asServer As AUTH_SEQ
        Dim cbIn As Integer
        Dim cbOut As Integer
        Dim fDone As Boolean

        SSPValidateUser = False

        ' Determine if system is Windows NT (version 4.0 or earlier)
        g_NT4 = (System.Environment.OSVersion.Platform =
VER_PLATFORM_WIN32_NT And System.Environment.OSVersion.Version.Major <= 4)

        ' Get max token size
        If g_NT4 Then
            NT4QuerySecurityPackageInfo("NTLM", pSPI)
        Else
            QuerySecurityPackageInfo("NTLM", pSPI)
        End If

        CopyMemory(SPI, pSPI, Marshal.SizeOf(SPI))
        cbMaxToken = SPI.cbMaxToken

        If g_NT4 Then
            NT4FreeContextBuffer(pSPI)
        Else
            FreeContextBuffer(pSPI)
        End If

        ' Allocate buffers for client and server messages
        pClientBuf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbMaxToken)
        If pClientBuf = 0 Then
            GoTo FreeResourcesAndExit
        End If

        pServerBuf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbMaxToken)
        If pServerBuf = 0 Then
            GoTo FreeResourcesAndExit
        End If

        ' Initialize auth identity structure
        ai.Domain = Domain
        ai.DomainLength = Domain.Length
        ai.User = User
        ai.UserLength = User.Length
        ai.Password = Password
        ai.PasswordLength = Password.Length
        ai.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI

        ' Prepare client message (negotiate) .
        cbOut = cbMaxToken
        If Not GenClientContext(asClient, ai, 0, 0, pClientBuf, cbOut,
fDone) Then
            GoTo FreeResourcesAndExit
        End If

        ' Prepare server message (challenge) .
        cbIn = cbOut
        cbOut = cbMaxToken
        If Not GenServerContext(asServer, pClientBuf, cbIn, pServerBuf,
cbOut, fDone) Then
            GoTo FreeResourcesAndExit
        End If

        ' Prepare client message (authenticate) .
        cbIn = cbOut
        cbOut = cbMaxToken
        If Not GenClientContext(asClient, ai, pServerBuf, cbIn, pClientBuf,
cbOut, fDone) Then
            GoTo FreeResourcesAndExit
        End If

        ' Prepare server message (authentication) .
        cbIn = cbOut
        cbOut = cbMaxToken
        If Not GenServerContext(asServer, pClientBuf, cbIn, pServerBuf,
cbOut, fDone) Then
            GoTo FreeResourcesAndExit
        End If

        SSPValidateUser = True

FreeResourcesAndExit:

        ' Clean up resources
        If asClient.fHaveCtxtHandle Then
            If g_NT4 Then
                NT4DeleteSecurityContext(asClient.hctxt)
            Else
                DeleteSecurityContext(asClient.hctxt)
            End If
        End If

        If asClient.fHaveCredHandle Then
            If g_NT4 Then
                NT4FreeCredentialsHandle(asClient.hcred)
            Else
                FreeCredentialsHandle(asClient.hcred)
            End If
        End If

        If asServer.fHaveCtxtHandle Then
            If g_NT4 Then
                NT4DeleteSecurityContext(asServer.hctxt)
            Else
                DeleteSecurityContext(asServer.hctxt)
            End If
        End If

        If asServer.fHaveCredHandle Then
            If g_NT4 Then
                NT4FreeCredentialsHandle(asServer.hcred)
            Else
                FreeCredentialsHandle(asServer.hcred)
            End If
        End If

        If pClientBuf <> 0 Then
            HeapFree(GetProcessHeap(), 0, pClientBuf)
        End If

        If pServerBuf <> 0 Then
            HeapFree(GetProcessHeap(), 0, pServerBuf)
        End If

    End Function

End Module

"Rob Teixeira [MVP]" wrote:

> OK, long answer ahead with a few sections of info, so make sure to read it
> thoroughly :-)
>
> LoginUser doesn't "do" anything to prevent any kind of scenario like you
> cited. However, it does require a domain name, so a user that is on the
> local machine "domain" isn't the same user that is on the network domain.
> Therefore, *if* you use LogonUser, you must check the user credentials
> assigned to the token after the call, and not just check to see if the
> function succeeds or fails.
>
> However, your instinct to use the currently logged on user credentials is
> the better choice. This also prevents the user from having to always type in
> their credentials, which is nice. In order to do this, you need to work with
> the SSPI API. Specifically, the functions are AcquireCredentialsHandle,
> InitializeSecurityContext, and AcceptSecurityContext. You need to call these
> multiple times on both the client and server to do a handshake. The number
> of roundtrips required depends on the protocal your domain is using (such as
> NTLM or Kerberos, etc.). If you really don't want to go through the headache
> of calling the API functions directly, you can download the
> Microsoft.Samples.Security.SSPI assembly -
> http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/remsspi.asp
>
> The download is the top link (RemSSPI.exe). It installs a zip file, and the
> only real file you need for this purpose is the
> Microsoft.Samples.Security.SSPI.dll. There's a short summary of what it does
> and how to use it about 3/4 down the page on the original link i pasted
> here. It's basically a .NET wrapper for the same APIs I was talking about
> earlier, but much cleaner to use. The only thing you need to provide is that
> after each call on both the client and server side, you need to create a
> mechanism to ship the resulting token data to the other side (client or
> server).
>
> -Rob Teixeira [MVP]
>
> "Brian E" <brian_anon@hotmail.com> wrote in message
> news:737943bc.0408110407.194a23cb@posting.google.com...
> > I am trying to understand how the LogonUser API works.
> >
> > I would like to utilize the credentials of the currently logged on
> > user as the basis for authenticating access to a client-server
> > application. Currently, the application only forwards the user name
> > of the currently logged on user.
> >
> > Since we use a standard naming convention for usernames I can easily
> > impersonate another user. I could install a standalone system and
> > create a local user account that matches the username of the
> > application administrator. When I start the client it forwards the
> > Windows username of the currently logged on user to the application.
> > Access is then granted.
> >
> > Obviously I do not know the Windows password for the application
> > administrator but have been able to get access.
> >
> > How does LogonUser API work to prevent this situation (i.e. creating a
> > similar account on another machine)?
> >
> > Regards,
> > Brian_anon@hotmail.com
>
>
>



Relevant Pages

  • Re: Configure Shared Fax
    ... Please do not send mail directly to this alias. ... >I have a Windows SBS 2000 width Shared Fax configured and working on ... > How can i configure a Windows XP SP2 Client to use Shared FAX? ... > connect to the Shared fax server width the message "Cannot find Server or ...
    (microsoft.public.win2000.fax)
  • alias is a vile weak little man
    ... Hate to tell you but Windows as an OS will see its last incarnation with Windows 7. ... Maybe Alias should buy Lottery tickets. ... Those were insults sheep-fukker! ... No, those were questions that, if interpreted a certain way, could be perceived as implied insults but only if you answer yes so now we have your answer; you had sex with both your mother and father. ...
    (microsoft.public.windows.vista.general)
  • Re: Windows authentication
    ... (ByVal Destination As Integer, ByRef Source As SecBuffer, ByVal Length As ... Alias "QuerySecurityPackageInfoA" (ByVal PackageName As String, ... cbOut, fDone) Then ...
    (microsoft.public.dotnet.security)
  • RE: Username/Password Validation with SSPI
    ... (ByVal Destination As Integer, ByRef Source As SecBuffer, ByVal Length As ... Alias "QuerySecurityPackageInfoA" (ByVal PackageName As String, ... cbOut, fDone) Then ...
    (microsoft.public.dotnet.general)
  • Re: Fax in Win2k3
    ... Yuval had mentioned in the first mail that he was using Win2k3 Std edition, ... Please do not send email directly to this alias. ... > The machine having the problems is running Windows 2003 SBS OEM standard. ... install fax and send a fax. Send a fax ...
    (microsoft.public.win2000.fax)