Click to See Complete Forum and Search --> : validate NT network password


sinjon
December 14th, 1999, 01:54 AM
I'm writing a application that will reside on a network and will be used by many. The program requires a small degree of password security and I don't want to have to manually administer a passord table. As some user's will only use the application once in a great while, I don't want them to need to remember a password.

If I could allow the application to use their network password it would be nice. I'm pulling their logon name via an API call but I see nothing for validating a password.

I thought about allowing access using the logon name only since they must have known the password to log on to the network in the first place. However, it was decided it would be too easy to use someone else's PC when they walked away.

Is there a way to do what I want?

Tom Welch
December 15th, 1999, 09:45 AM
You should look at the WNetAddConnection2 API. I did this once a long time ago. Basically, try to connect a drive letter using their username and password. See if it worked and disconnect the drive letter if it did. That should give you what you want.

Tom Welch
December 15th, 1999, 10:58 AM
I decided to resurrect my code and clean it up. Here is the module code. All you need to do is call it.

sNetShare is a network share that the user has rights to access.
sUserName is the username.
sPassword is the password.

option Explicit

'//
'// Optionally, you can comment out to END_COMMENT and use WIN.TLB from Hardcore Visual Basic
'//
'START_COMMENT
'
private Declare Function WNetAddConnection2 Lib "mpr.dll" Alias "WNetAddConnection2A" (lpNetResource as NETRESOURCE, byval lpPassword as string, byval lpUserName as string, byval dwFlags as Long) as Long
private Declare Function WNetCancelConnection2 Lib "mpr.dll" Alias "WNetCancelConnection2A" (byval lpName as string, byval dwFlags as Long, byval fForce as Long) as Long
private Declare Function WNetGetConnection& Lib "mpr.dll" Alias "WNetGetConnectionA" (byval lpszLocalName$, byval lpszRemoteName$, cbRemoteName&)
private Type NETRESOURCE
dwScope as Long
dwType as Long
dwDisplayType as Long
dwUsage as Long
lpLocalName as Long
lpRemoteName as Long
lpComment as Long
lpProvider as Long
End Type
Const ERROR_SUCCESS = 0
Const ERROR_NOT_CONNECTED = 2250
Const RESOURCETYPE_DISK = 0
'END_COMMENT

public Function ValidUser(byval sNetShare as string, byval sUserName as string, byval sPassword as string) as Boolean

'// very simple - will fail if all drive letters are used. can enhance to use an unnammed mapping.
Dim iCnt as Integer
Dim sDrive as string
Dim sRemote as string * 255

Dim lpNR as NETRESOURCE
Dim lRes as Long

Dim aDrive() as Byte
Dim aResource() as Byte

for iCnt = Asc("Z") to Asc("A") step -1
lRes = WNetGetConnection(Chr$(iCnt) & ":", sRemote, len(sRemote))

If lRes = ERROR_NOT_CONNECTED then
sDrive = Chr$(iCnt) & ":"
Exit for
End If
next iCnt


If len(sDrive) > 0 then
ReDim aDrive(0 to len(sDrive))
ReDim aResource(0 to len(sNetShare))

'// passing as long to ansi function, must be in byte array without padding
for iCnt = 0 to len(sDrive) - 1
aDrive(iCnt) = Asc(mid$(sDrive, iCnt + 1, 1))
next iCnt

'// passing as long to ansi function, must be in byte array without padding
for iCnt = 0 to len(sNetShare) - 1
aResource(iCnt) = Asc(mid$(sNetShare, iCnt + 1, 1))
next iCnt

lpNR.dwType = RESOURCETYPE_DISK
lpNR.lpLocalName = VarPtr(aDrive(0))
lpNR.lpRemoteName = VarPtr(aResource(0))

lRes = WNetAddConnection2(lpNR, sPassword, sUserName, false)

If lRes = ERROR_SUCCESS then
lRes = WNetCancelConnection2(sDrive, false, true)
ValidUser = true
End If

End If

End Function