devxlogo

Implementation of LookupAccountName() in VB6

Implementation of LookupAccountName() in VB6

Question:
We’re trying to:

  1. Get the Logon Windows NT id for an Exchange mail box
  2. Get the Security Identifier (SID) corresponding to the Windows NT id (using advapi32.dll api’s)
  3. Map this SID with Assoc-NT-Account (which stores the SID) on Exchange server and get the corresponding mailbox information

I am having difficulty getting the SID (step 2). I am calling LookupAccountName() from advapi32.dll in Visual Basic. The return value of the LookupAccountName iscoming up as 0, but the GetLastError is also returning 0. What could be the problem?

Here is the code I am using:

' Advanced Windows 32 Base API Private Declare Function LookupAccountSid Lib
"advapi32.dll" _ Alias "LookupAccountSidA" (ByVal
lpSystemName As String, _ Sid As Any, ByVal name As String,
cbName As Long, ByVal ReferencedDomainName As String, _ cbReferencedDomainName As Long, peUse As
Integer) As Long Private Declare Function LookupAccountName
Lib "advapi32.dll" _ Alias "LookupAccountNameA" (ByVal
lpSystemName As String, _ ByVal lpAccountName As String,
Sid As Long, cbSid As Long, _ ByVal ReferencedDomainName
As String, cbReferencedDomainName As Long, peUse As Integer) As Long Private Declare Function GetLastError Lib
"kernel32" () As LongPrivate Function GetSID() Dim sUserName As String Dim sDomainName As String Dim sServerName As String Dim SIDSize As Long Dim DNSize As Long Dim SIDData As Long Dim iType As Integer Dim ret_val As Long sUser = "Sharmaan" 'sDomainName = "COMPAQ-GROUP" sServerName = "" DNSize = 255 ret_val = LookupAccountName(sServerName,
sUser, SIDData, SIDSize, sDomainName, DNSize, iType) If ret_val = 0 Then Debug.Print "Last Error:"; GetLastError() Else If DNSize > 0 Then sDomainName = Left$(sDomainName,
DNSize) & "" Else sDomainName = "" End If End If Debug.Print "SID:"; SIDData End FunctionPrivate Sub Form_Load()GetSIDEnd Sub

Answer:
First, never, ever use GetLastError from VB 5.0/6.0. Use Err.LastDllError instead. VB “masks” the errors you get from the actual API calls, so you get back either no error or the incorrect error.

Next, the following code should get you back a byte array of the user’s SID:

Option ExplicitDeclare Function LookupAccountName _   Lib "advapi32.dll" Alias "LookupAccountNameA" _   (ByVal lpSystemName As String, _    ByVal lpAccountName As String, _    sid As Any, _    cbSid As Long, _    ReferencedDomainName As Any, _    cbReferencedDomainName As Long, _    peUse As Integer) As LongPublic Sub Main()   GetSid "administrator"End SubPublic Sub GetSid(ByVal xi_strUserName As String)   Dim p_intUse                        As Integer   Dim p_strAcctName                   As String   Dim p_strSID_Account                As String   Dim p_strSID_Domain                 As String   Dim p_strDomainName                 As String   Dim p_lngAcctLength                 As Long   Dim p_lngDomainLength               As Long   Dim p_lngSID_Length                 As Long   Dim p_lngNumRIDs                    As Long   Dim p_lngRtn                        As Long   Dim p_abytSID()                     As Byte   Dim p_abytDomain()                  As Byte   Dim p_strDomain                     As String      ' Preinitialize p_abytSID array with one    '    element. It will be redimmed lated   ReDim p_abytSID(1) As Byte      p_strAcctName = xi_strUserName   p_lngRtn = LookupAccountName(vbNullString, _                              p_strAcctName, _                              p_abytSID(0), _                              p_lngSID_Length, _                              p_strDomainName, _                              p_lngDomainLength, _                              p_intUse)      ' Call fails but puts in required buffers size   '     in p_lngSID_Length and    '     p_lngDomainLength variables   ReDim p_abytSID(p_lngSID_Length) As Byte   ReDim p_abytDomain(p_lngDomainLength) As Byte      p_lngRtn = LookupAccountName(vbNullString, _                              p_strAcctName, _                              p_abytSID(0), _                              p_lngSID_Length, _                              p_abytDomain(0), _                              p_lngDomainLength, _                              p_intUse)      p_strDomain = Mid$(StrConv(p_abytDomain, _                 vbUnicode), 1, p_lngDomainLength)   Debug.Print "Domain Name: " & p_strDomain      ' Reset the lengths   p_lngAcctLength = 0   p_lngDomainLength = 0      Dim p_lngLoop   For p_lngLoop = 0 To 28      Debug.Print p_lngLoop & ": " & _         Hex$(p_abytSID(p_lngLoop))   Next p_lngLoop   End Sub

devx-admin

Share the Post: