473,419 Members | 1,831 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,419 software developers and data experts.

Check Credentials against OS

doma23
107 100+
This thread was taken from a post in Nz function not working and refers to comments in post #4.

Yeah, I was thinking if you could share that API function you have, because I was searching for a way to verify the user's win password in access for some time now.
Jul 28 '10 #1
9 3036
Jerry Maiapu
259 100+
Ok, Create a form "FRM_LOGIN" make sure you you have these text boxes TXT_USERNAME,TXT_PASSWORD,and a combo box CMBO_DOMAIN (lists names of domain if in a network or name of PC if stand-lone)

Create a login cmd button ,CMD_LOGIN, to validate
Copy and paste the following in the form's VB Editor..


Expand|Select|Wrap|Line Numbers
  1. Option Compare Database
  2. Option Explicit
  3.  
  4. Dim stDocName As String
  5.  
  6.  
  7. Private Type NETRESOURCE
  8.    dwScope                             As Long
  9.    dwType                              As Long
  10.    dwDisplayType                       As Long
  11.    dwUsage                             As Long
  12.    pLocalName                          As Long
  13.    pRemoteName                         As Long
  14.    pComment                            As Long
  15.    pProvider                           As Long
  16. End Type
  17.  
  18. Private Declare Function WNetOpenEnum _
  19.    Lib "mpr.dll" Alias "WNetOpenEnumA" _
  20.    (ByVal dwScope As Long, _
  21.    ByVal dwType As Long, _
  22.    ByVal dwUsage As Long, _
  23.    lpNetResource As Any, _
  24.    lppEnumHwnd As Long) As Long
  25.  
  26. Private Declare Function WNetEnumResource _
  27.    Lib "mpr.dll" Alias "WNetEnumResourceA" _
  28.    (ByVal pEnumHwnd As Long, _
  29.    lpcCount As Long, _
  30.    lpBuffer As NETRESOURCE, _
  31.    lpBufferSize As Long) As Long
  32.  
  33. Private Declare Function WNetCloseEnum _
  34.    Lib "mpr.dll" _
  35.    (ByVal p_lngEnumHwnd As Long) As Long
  36.  
  37. Private Declare Function NetUserGetInfo _
  38.    Lib "netapi32.dll" _
  39.    (ServerName As Byte, _
  40.    Username As Byte, _
  41.    ByVal Level As Long, _
  42.    Buffer As Long) As Long
  43.  
  44. Private Declare Function StrLenA _
  45.    Lib "kernel32" Alias "lstrlenA" _
  46.    (ByVal Ptr As Long) As Long
  47.  
  48. Private Declare Function StrCopyA _
  49.    Lib "kernel32" Alias "lstrcpyA" _
  50.    (ByVal RetVal As String, _
  51.    ByVal Ptr As Long) As Long
  52.  
  53. Private Const MAX_RESOURCES            As Long = 256
  54. Private Const RESOURCE_GLOBALNET       As Long = &H2&
  55. Private Const RESOURCETYPE_ANY         As Long = &H0&
  56. Private Const RESOURCEUSAGE_ALL        As Long = &H0&
  57. Private Const NO_ERROR                 As Long = 0&
  58. Private Const RESOURCE_ENUM_ALL        As Long = &HFFFF
  59.  
  60.  
  61. Private Sub Form_Load()
  62. GetDomains
  63. DoCmd.GoToControl "TXT_PASSWORD"
  64. End Sub
  65.  
  66. Private Sub CMD_LOGIN_Click()
  67. Dim StrPWord As String
  68. Dim StrUserName As String
  69. Dim StrDomain As String
  70.  
  71. On Error GoTo NoData
  72. StrPWord = Me.TXT_PASSWORD
  73. StrUserName = Me.TXT_USERNAME
  74. StrDomain = Me.CMBO_DOMAIN
  75.  
  76. ValidatePW StrPWord, StrUserName, StrDomain
  77.  
  78. Exit Sub
  79.  
  80. NoData:
  81.  
  82. MsgBox "Unable to complete login; One or more pieces of required information are missing", vbInformation, "Missing Data"
  83.  
  84. End Sub
  85. Public Function ValidatePW(Password As String, Username As String, DomainName As String) As Boolean
  86. ' Start by retrieving the user's name
  87. Dim lpBuffer As String, nSize As Long
  88. Dim rv As Long, usrName As String
  89. Dim hToken As Long
  90.  
  91. ' Initialise an empty buffer, 10 characters long (long enough for most user names)
  92. lpBuffer = String(10, Chr(0))
  93. Do
  94.     nSize = Len(lpBuffer)
  95.     rv = GetUserName(lpBuffer, nSize)
  96.     If rv = 0 Then
  97.         ' The function probably failed due to the buffer being too small
  98.         ' nSize holds the required size
  99.         lpBuffer = String(nSize, Chr(0)) ' Resize buffer to accomodate big name
  100.     End If
  101. Loop Until rv <> 0
  102. ' Extract user name from buffer
  103. usrName = Left(lpBuffer, nSize - 1)
  104.  
  105. If usrName <> Username Then
  106.   Msgbox "Username Incorrect"
  107.     TXT_USERNAME.SetFocus
  108.  
  109.     Exit Function
  110.  
  111. End If
  112.  
  113. If Domain() <> DomainName Then
  114.     MsgBox " Wrong Domain name"
  115.     CMBO_DOMAIN.SetFocus
  116.  
  117.     Exit Function
  118.  
  119. End If
  120.  
  121. ' Now validate the password
  122. rv = LogonUser(usrName, vbNullString, Password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, hToken)
  123. If rv <> 0 Then
  124.     ' Password validated successfully    
  125.      Me!TXT_PASSWORD = ""
  126.         Me.Visible = False
  127.      stDocName = "Enter name of form to open after validation success"
  128.      DoCmd.OpenForm stDocName
  129.  
  130. Else
  131.     ' Username and password failed validation
  132.   Msgbox"Incorrect Password"
  133.      TXT_PASSWORD.SetFocus
  134. End If
  135. End Function
  136.  
  137. Public Function Domain() As String
  138. Dim wshNet As Object
  139. Set wshNet = CreateObject("WScript.Network")
  140. On Error GoTo errBadNetwork
  141. Domain = wshNet.UserDomain
  142. Set wshNet = Nothing
  143. Exit Function
  144. errBadNetwork:
  145. Domain = "Unavailable"
  146. End Function
  147. Public Sub GetDomains()
  148.  
  149. Dim p_avntDomains                   As Variant
  150. Dim p_lngLoop                       As Long
  151. Dim p_lngNumItems                   As Long
  152.  
  153. p_avntDomains = EnumDomains()
  154.  
  155. On Error Resume Next
  156. p_lngNumItems = UBound(p_avntDomains)
  157. On Error GoTo 0
  158.  
  159. If p_lngNumItems > 0 Then
  160.    For p_lngLoop = 1 To p_lngNumItems
  161.  
  162.       Me.CMBO_DOMAIN.AddItem p_avntDomains(p_lngLoop)
  163.  
  164.    Next p_lngLoop
  165.  
  166. Else
  167.  
  168.     Me.CMBO_DOMAIN.AddItem Domain()
  169.  
  170. End If
  171.  
  172. End Sub
  173.  
  174. Private Function EnumDomains() As Variant
  175.  
  176. Dim p_lngRtn                        As Long
  177. Dim p_lngEnumHwnd                   As Long
  178. Dim p_lngCount                      As Long
  179. Dim p_lngLoop                       As Long
  180. Dim p_lngBufSize                    As Long
  181. Dim p_astrDomainNames()             As String
  182. Dim p_atypNetAPI(0 To MAX_RESOURCES) As NETRESOURCE
  183.  
  184. ' ------------------------------------------
  185. ' First time thru, we are just getting the root level
  186. ' ------------------------------------------
  187. p_lngEnumHwnd = 0&
  188. p_lngRtn = WNetOpenEnum(dwScope:=RESOURCE_GLOBALNET, _
  189.    dwType:=RESOURCETYPE_ANY, _
  190.    dwUsage:=RESOURCEUSAGE_ALL, _
  191.    lpNetResource:=ByVal 0&, _
  192.    lppEnumHwnd:=p_lngEnumHwnd)
  193.  
  194. If p_lngRtn = NO_ERROR Then
  195.    p_lngCount = RESOURCE_ENUM_ALL
  196.  
  197.    p_lngBufSize = UBound(p_atypNetAPI) * Len(p_atypNetAPI(0))
  198.    p_lngRtn = WNetEnumResource(pEnumHwnd:=p_lngEnumHwnd, _
  199.       lpcCount:=p_lngCount, _
  200.       lpBuffer:=p_atypNetAPI(0), _
  201.       lpBufferSize:=p_lngBufSize)
  202.  
  203. End If
  204.  
  205. If p_lngEnumHwnd <> 0 Then
  206.    Call WNetCloseEnum(p_lngEnumHwnd)
  207. End If
  208.  
  209. ' ------------------------------------------
  210. ' Now we are going for the second level,
  211. '     which should contain the domain names
  212. ' ------------------------------------------
  213. p_lngRtn = WNetOpenEnum(dwScope:=RESOURCE_GLOBALNET, _
  214.    dwType:=RESOURCETYPE_ANY, _
  215.    dwUsage:=RESOURCEUSAGE_ALL, _
  216.    lpNetResource:=p_atypNetAPI(0), _
  217.    lppEnumHwnd:=p_lngEnumHwnd)
  218.  
  219. If p_lngRtn = NO_ERROR Then
  220.    p_lngCount = RESOURCE_ENUM_ALL
  221.  
  222.    p_lngBufSize = UBound(p_atypNetAPI) * Len(p_atypNetAPI(0))
  223.    p_lngRtn = WNetEnumResource(pEnumHwnd:=p_lngEnumHwnd, _
  224.       lpcCount:=p_lngCount, _
  225.       lpBuffer:=p_atypNetAPI(0), _
  226.       lpBufferSize:=p_lngBufSize)
  227.  
  228.    If p_lngCount > 0 Then
  229.       ReDim p_astrDomainNames(1 To p_lngCount) As String
  230.       For p_lngLoop = 0 To p_lngCount - 1
  231.          p_astrDomainNames(p_lngLoop + 1) = _
  232.          PointerToAsciiStr(p_atypNetAPI(p_lngLoop).pRemoteName)
  233.       Next p_lngLoop
  234.    End If
  235. End If
  236.  
  237. If p_lngEnumHwnd <> 0 Then
  238.    Call WNetCloseEnum(p_lngEnumHwnd)
  239. End If
  240.  
  241. ' ------------------------------------------
  242. ' Set the return value
  243. ' ------------------------------------------
  244. EnumDomains = p_astrDomainNames
  245.  
  246. End Function
  247.  
  248. Private Function PointerToAsciiStr(ByVal xi_lngPtrToString _
  249.   As Long) As String
  250.  
  251. On Error Resume Next         ' Don't accept an error here
  252.  
  253. Dim p_lngLen                        As Long
  254. Dim p_strStringValue                As String
  255. Dim p_lngNullPos                    As Long
  256. Dim p_lngRtn                        As Long
  257.  
  258. p_lngLen = StrLenA(xi_lngPtrToString)
  259. If xi_lngPtrToString > 0 And p_lngLen > 0 Then
  260.    p_strStringValue = Space$(p_lngLen + 1)
  261.    p_lngRtn = StrCopyA(p_strStringValue, xi_lngPtrToString)
  262.    p_lngNullPos = InStr(p_strStringValue, Chr$(0))
  263.    If p_lngNullPos > 0 Then
  264.       PointerToAsciiStr = Left$(p_strStringValue, _
  265.          p_lngNullPos - 1) 'Lose the null terminator...
  266.    Else
  267.       'Just pass the string...
  268.       PointerToAsciiStr = p_strStringValue
  269.    End If
  270. Else
  271.    PointerToAsciiStr = ""
  272. End If
  273.  
  274. End Function
Hope this helps..
Note: REPLACE Enter name of form to open after validation successIN CODE LINE 127 WITH YOU FORM'S NAME THAT WILL OPEN AFTER VALIDATION IS SUCCESSFUL.

Cheers..

Jerry Maiapu
Mangi Karex

Welcome to Bytes..
Jul 28 '10 #2
doma23
107 100+
@Jerry Maiapu
Tnx a bunch!
I'll give it a shot and let you know if the implementation was succesful.
Jul 29 '10 #3
doma23
107 100+
Uhhh, late reply. Here it goes.
I've tried to implement this and this is what I got:

1) On a click of a LOGIN button I got "Sub or function not define" error, pointing to "GetUserName" in the code. After that I've added this line:
Expand|Select|Wrap|Line Numbers
  1. Private Declare Function GetUserName Lib "advapi32.dll" (ByVal lpBuffer As String, nSize As Long) As Long
It seemed to work, as the next error message was different.

2) Variable not defined pointing to "LOGON32_LOGON_NETWORK" in this code:
Expand|Select|Wrap|Line Numbers
  1. ' Now validate the password
  2. rv = LogonUser(usrName, vbNullString, Password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, hToken)
Thanks!
Aug 2 '10 #4
NeoPa
32,556 Expert Mod 16PB
Jerry, I guess the actual procedure that makes the OS call to check the name and password is called LogonUser(). Unfortunately, this particular procedure wasn't included in your post.

As I think there may be some interest in this, from public and members alike, would you mind posting that routine and any supporting declarations for all to see. Thanks for your efforts :)
Aug 2 '10 #5
Jerry Maiapu
259 100+
My fault. Shame on me.. Create a new module and add this

Expand|Select|Wrap|Line Numbers
  1. Option Compare Database
  2.  
  3. Public Const LOGON32_LOGON_BATCH = 4
  4. Public Const LOGON32_LOGON_INTERACTIVE = 2
  5. Public Const LOGON32_LOGON_SERVICE = 5
  6. Public Const LOGON32_LOGON_NETWORK = 3
  7. Public Const LOGON32_PROVIDER_DEFAULT = 0
  8. Public Const LOGON32_PROVIDER_WINNT35 = 1
  9. Public Declare Function LogonUser Lib "advapi32.dll" Alias "LogonUserA" (ByVal lpszUsername As String, ByVal lpszDomain As String, ByVal lpszPassword As String, ByVal dwLogonType As Long, ByVal dwLogonProvider As Long, phToken As Long) As Long
  10.  
  11.  
  12. Public Declare Function GetUserName Lib "advapi32.dll" Alias "GetUserNameA" (ByVal lpBuffer As String, nSize As Long) As Long
It should be fine now

Cheers!

Jerry
Aug 2 '10 #6
Jerry Maiapu
259 100+
NeoPA,

Would you mind making these posts concerning usernanme,password stuff a new threat while giving a suitable title..(All posts starting from say post# 8)This is to help those interest public and members like you mention..

Thanks..

Jerry
Aug 2 '10 #7
NeoPa
32,556 Expert Mod 16PB
All done Jerry :)
Aug 3 '10 #8
Jerry Maiapu
259 100+
Heaps of thanks

Cheers
Aug 3 '10 #9
NeoPa
32,556 Expert Mod 16PB
If my reading of the documentation is right, then LogonUserA doesn't only check the credentials, it also creates a validated user context, within which processes can initiated on behalf of the said user. As such, tidy code would demand that the context be cleared down with a user logoff of some form. I found nothing for UserLogoffA. Perhaps you have code to handle this Jerry (Sorry if it's in your posted code and I missed it).
Aug 4 '10 #10

Sign in to post your reply or Sign up for a free account.

Similar topics

2
by: Jeroen | last post by:
I am developing an asp.net website with windows authentification and I want to check to which group the user belongs. I know how to check for the user that has logged in and to see if he belongs...
1
by: Jake | last post by:
Hello, I am developing an application and there is a specific area in which I want a specific group of windows users to access only. The users belong to a group called Security1. How can I test...
1
by: Raghu | last post by:
I have following code that validates a given user credentails against a active directory. The login part works but I can not search as it fails to return the record. Does any one have any idea...
3
by: Rich | last post by:
The procedure below checks if a character entered into a cell of a datagridview is contained in a string array of valid characters for this particular cell. It seems kludgy. I am asking what the...
2
by: JasonC | last post by:
Hi, First time posting here so please be gentle! I wish to check a variable for a number of words that are in a array. Not sure if this is the best way to do it, but this is what i have. ...
2
by: rote | last post by:
My sceanrio is this on an asp.net 2.0 freamework. I want to use any of the data controls e.g Gridview,DetailView etc.. But i want some buttons e.g update,edit save etc to be enable or disabled...
17
by: wswilson | last post by:
In python, I could write: a = 1 if a in : do something... In c (and many other languages):
2
by: marioliveira | last post by:
I have a orm built with RSForms Pro in which there is a calendar. The form is about bookings for activities, some of which are not available every weekday. Is there a way of checking the date the...
2
by: Peter Peter | last post by:
Hi guys, I've got a text file and im trying to read the text from that file and then check every word with 40 words around that word, to make sure the word in question has not been repeated more...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.