dcsimg
Login | Register   
LinkedIn
Google+
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX

By submitting your information, you agree that devx.com may send you DevX offers via email, phone and text message, as well as email offers about other products and services that DevX believes may be of interest to you. DevX will process your information in accordance with the Quinstreet Privacy Policy.


Tip of the Day
Language: NT
Expertise: Beginner
Jun 22, 1998

WEBINAR:

On-Demand

Building the Right Environment to Support AI, Machine Learning and Deep Learning


NT Server Local Groups

Question:
I would like to be able to gain access to NT server local groups for enum, member enum, add member, delete member.

We have a lot of servers as well as NT and OS/2 domains. Because of this, there is a need to synchronize users and group memberships across multiple servers.

I have not found anything that will allow me to access a local group on a server from a VB program running on a client. Can you point me in the right direction?

Answer:
None of the NT Unicode network functions are particularly easy to use. In fact, they are a real pain. However, the following code will do what you want:

' ************************************************
' In a form
' ************************************************
Option Explicit

Private Sub Command1_Click()
On Error Resume Next
   Dim p_vntRtn   As Variant
   Dim p_lngNum   As Long
   Dim p_lngLoop  As Long
   Dim p_strGroup As String
   
   p_strGroup = Trim$(Me.List1.List(Me.List1.ListIndex))
   If Len(p_strGroup) <= 0 Then
      MsgBox "You must select a group first!"
      Exit Sub
   End If
   
   Me.List2.Clear
   p_vntRtn = GetLocalGroupMembers("", p_strGroup)
   
   p_lngNum = UBound(p_vntRtn)
   If p_lngNum > 0 Then
      For p_lngLoop = 1 To p_lngNum
         Me.List2.AddItem p_vntRtn(p_lngLoop)
      Next p_lngLoop
   End If
   
End Sub

Private Sub Command2_Click()
On Error Resume Next
   Dim p_vntRtn   As Variant
   Dim p_lngNum   As Long
   Dim p_lngLoop  As Long
   
   Me.List1.Clear
   p_vntRtn = GetLocalGroups("")
   
   p_lngNum = UBound(p_vntRtn)
   If p_lngNum > 0 Then
      For p_lngLoop = 1 To p_lngNum
         Me.List1.AddItem p_vntRtn(p_lngLoop)
      Next p_lngLoop
   End If
   
End Sub

Private Sub Command3_Click()
   Dim p_blnRtn   As Boolean
   Dim p_strGroup As String
   Dim p_strUser  As String
   
   p_strGroup = Trim$(Me.List1.List(Me.List1.ListIndex))
   If Len(p_strGroup) <= 0 Then
      MsgBox "You must select a group first!"
      Exit Sub
   End If
  
   p_strUser = Trim$(Me.Text1.Text)
   If Len(p_strUser) <= 0 Then
      MsgBox "You must add a user name first!"
      Exit Sub
   End If
   
   p_blnRtn = AddDelUserToLocal(p_strGroup, _
                             p_strUser, _
                             "", True)
End Sub

Private Sub Command4_Click()
   Dim p_blnRtn   As Boolean
   Dim p_strGroup As String
   Dim p_strUser  As String
   
   p_strGroup = Trim$(Me.List1.List(Me.List1.ListIndex))
   If Len(p_strGroup) <= 0 Then
      MsgBox "You must select a group first!"
      Exit Sub
   End If
  
   p_strUser = Trim$(Me.Text2.Text)
   If Len(p_strUser) <= 0 Then
      MsgBox "You must add a user name first!"
      Exit Sub
   End If
   
   p_blnRtn = AddDelUserToLocal(p_strGroup, _
                             p_strUser, _
                             "", False)
End Sub


' ************************************************
' In a BAS file
' ************************************************

Option Explicit

Private Const NERR_Success             As Long = 0&

Private Const LocalGroupInfo0          As Long = 0&
Private Const LocalGroupInfo1          As Long = 1&

Private Const LocalGroupMembersInfo0   As Long = 0&
Private Const LocalGroupMembersInfo1   As Long = 1&
Private Const LocalGroupMembersInfo2   As Long = 2&
Private Const LocalGroupMembersInfo3   As Long = 3&

Private Const SidTypeUser              As Long = 1&
Private Const SidTypeGroup             As Long = 2&
Private Const SidTypeDomain            As Long = 3&
Private Const SidTypeAlias             As Long = 4&
Private Const SidTypeWellKnownGroup    As Long = 5&
Private Const SidTypeDeletedAccount    As Long = 6&
Private Const SidTypeInvalid           As Long = 7&
Private Const SidTypeUnknown           As Long = 8&
    
Public Declare Sub CopyMem _
   Lib "kernel32" Alias "RtlMoveMemory" _
   (pTo As Any, _
    pFrom As Any, _
    ByVal lCount As Long)
Private Declare Function lstrlenW _
   Lib "kernel32" _
   (ByVal psString As Long) As Long
Private Declare Function NetApiBufferFree _
   Lib "netapi32.dll" _
   (ByVal p_lngPtrBuffer As Long) As Long

Private Type LOCALGROUP_INFO_0
   PtrGroupName                        As Long
End Type

Private Type LOCALGROUP_MEMBERS_INFO_0
   PtrSidID                            As Long
End Type

Private Type LOCALGROUP_MEMBERS_INFO_1
   PtrSidID                            As Long
   SidUsage                            As Long
   PtrName                             As Long
End Type

Private Type LOCALGROUP_MEMBERS_INFO_3
   DomainAndName                       As Long
End Type

Private Declare Function NetLocalGroupEnum _
   Lib "netapi32" _
   (ByVal psServer As Long, _
    ByVal level As Long, _
    pPtrBuffer As Long, _
    ByVal prefmaxlen As Long, _
    EntriesRead As Long, _
    TotalEntries As Long, _
    ResumeHandle As Long) As Long
 
Private Declare Function NetLocalGroupGetMembers _
   Lib "netapi32" _
   (ByVal psServer As Long, _
    ByVal psLocalGroupName As Long, _
    ByVal level As Long, _
    pPtrBuffer As Long, _
    ByVal prefmaxlen As Long, _
    EntriesRead As Long, _
    TotalEntries As Long, _
    ResumeHandle As Long) As Long
 
Private Declare Function NetLocalGroupAddMembers _
   Lib "netapi32" _
   (ByVal psServer As Long, _
    ByVal psLocalGroupName As Long, _
    ByVal level As Long, _
    pPtrBuffer As Long, _
    ByVal membercount As Long) As Long
    
Private Declare Function NetLocalGroupDelMembers _
   Lib "netapi32" _
   (ByVal psServer As Long, _
    ByVal psLocalGroupName As Long, _
    ByVal level As Long, _
    pPtrBuffer As Long, _
    ByVal membercount As Long) As Long
    
' ================================================
' Get all the memebers of a selected local group
' ================================================
Public Function GetLocalGroupMembers(ByVal xi_strServerName As String, _
                                     ByVal xi_strLocalGroupName As String) As Variant
   Dim p_lngRtn                     As Long
   Dim p_lngPtrBuffer               As Long
   Dim p_lngPtrServerName           As Long
   Dim p_lngPtrLocalGroupName       As Long
   Dim p_lngPreferredMaxLen         As Long
   Dim p_lngEntriesRead             As Long
   Dim p_lngTotalEntries            As Long
   Dim p_lngResumeHwnd              As Long
   Dim p_lngLoop                    As Long
   Dim p_lngSidType                 As Long
   Dim p_strUserName                As String
   Dim p_strSidType                 As String
   Dim p_strSID                     As String
   Dim p_typLocalGroupMembers1      As LOCALGROUP_MEMBERS_INFO_1
   Dim p_alngMemberInfo()           As Long
   Dim p_astrMemberInfo()           As String
   
   ' Convert the server name to a pointer
   If Len(Trim$(xi_strServerName)) = 0 Then
      p_lngPtrServerName = 0&
   Else
      p_lngPtrServerName = StrPtr(xi_strServerName)
   End If
   
   ' Convert the user name to a pointer
   If Len(Trim$(p_lngPtrLocalGroupName)) = 0 Then
      MsgBox "You must enter a local group name!", vbExclamation, "Input Error"
      Exit Function
   Else
      p_lngPtrLocalGroupName = StrPtr(xi_strLocalGroupName)
   End If
   
   p_lngPreferredMaxLen = 4096&
   p_lngResumeHwnd = 0&
   p_lngRtn = NetLocalGroupGetMembers(p_lngPtrServerName, _
                                      p_lngPtrLocalGroupName, _
                                      LocalGroupMembersInfo1, _
                                      p_lngPtrBuffer, _
                                      p_lngPreferredMaxLen, _
                                      p_lngEntriesRead, _
                                      p_lngTotalEntries, _
                                      p_lngResumeHwnd)
   If p_lngRtn = NERR_Success Then
      ReDim p_alngMemberInfo(0 To (p_lngEntriesRead * 3) - 1) As Long
      ReDim p_astrMemberInfo(1 To p_lngEntriesRead) As String
      
      ' This gets the pointers to the structures
      CopyMem p_alngMemberInfo(0), _
              ByVal p_lngPtrBuffer, _
              p_lngEntriesRead * 4 * 3
      
      If p_lngEntriesRead > 0 Then
         For p_lngLoop = 0 To p_lngEntriesRead - 1
            p_strSidType = TranslateSidUsage(p_alngMemberInfo((p_lngLoop * 3) + 1))
            p_strUserName = PointerToStringW(p_alngMemberInfo((p_lngLoop * 3) + 2))
            p_astrMemberInfo(p_lngLoop + 1) = p_strUserName & " [" & p_strSidType & "]"
         Next p_lngLoop
      End If
      
      If p_lngPtrBuffer Then
         NetApiBufferFree p_lngPtrBuffer
      End If
      
      GetLocalGroupMembers = p_astrMemberInfo
   Else
      GetLocalGroupMembers = ""
   End If
   
End Function

' ================================================
' Get all of the local groups
' ================================================
Public Function GetLocalGroups(ByVal xi_strServerName As String) As Variant
   Dim p_lngRtn                     As Long
   Dim p_lngLoop                    As Long
   Dim p_lngPtrBuffer               As Long
   Dim p_lngPtrServerName           As Long
   Dim p_lngPreferredMaxLen         As Long
   Dim p_lngResumeHwnd              As Long
   Dim p_lngEntriesRead             As Long
   Dim p_lngTotalEntries            As Long
   Dim p_alngGroupInfo()            As Long
   Dim p_astrGroupInfo()            As String
   
   ' Convert the server name to a pointer
   If Len(Trim$(xi_strServerName)) = 0 Then
      p_lngPtrServerName = 0&
   Else
      p_lngPtrServerName = StrPtr(xi_strServerName)
   End If

   p_lngPreferredMaxLen = 4096&
   p_lngResumeHwnd = 0&

   p_lngRtn = NetLocalGroupEnum(p_lngPtrServerName, _
                                LocalGroupInfo0, _
                                p_lngPtrBuffer, _
                                p_lngPreferredMaxLen, _
                                p_lngEntriesRead, _
                                p_lngTotalEntries, _
                                p_lngResumeHwnd)
   If p_lngRtn = NERR_Success Then
      ReDim p_alngGroupInfo(0 To p_lngEntriesRead - 1) As Long
      ReDim p_astrGroupInfo(1 To p_lngEntriesRead) As String
      
      ' This gets the pointers to the structures
      CopyMem p_alngGroupInfo(0), _
              ByVal p_lngPtrBuffer, _
              p_lngEntriesRead * 4
      
      If p_lngEntriesRead > 0 Then
         For p_lngLoop = 0 To p_lngEntriesRead - 1
            p_astrGroupInfo(p_lngLoop + 1) = PointerToStringW(p_alngGroupInfo(p_lngLoop))
         Next p_lngLoop
      End If
      
      If p_lngPtrBuffer Then
         NetApiBufferFree p_lngPtrBuffer
      End If
      
      GetLocalGroups = p_astrGroupInfo
   Else
      GetLocalGroups = ""
   End If
   
End Function

' ================================================
' Either add or delete a user from a selected
' local group (depends upon xi_blnAddUser)
' ================================================
Function AddDelUserToLocal(ByVal xi_strGroupName As String, _
                           ByVal xi_strUserName As String, _
                           ByVal xi_strServerName As String, _
                           ByVal xi_blnAddUser As Boolean) As Boolean
   Dim p_lngPtrGroupName   As Long
   Dim p_lngPtrUserName    As Long
   Dim p_lngPtrServerName  As Long
   Dim p_lngMemberCount    As Long
   Dim p_lngRtn            As Long
   
   ' Convert the server name to a pointer
   If Len(Trim$(xi_strServerName)) = 0 Then
      p_lngPtrServerName = 0&
   Else
      p_lngPtrServerName = StrPtr(xi_strServerName)
   End If

   ' Convert the group name to a pointer
   p_lngPtrGroupName = StrPtr(xi_strGroupName)
   
   ' Convert the user name to a pointer
   p_lngPtrUserName = StrPtr(xi_strUserName)
   
   ' Add the user
   p_lngMemberCount = 1
   
   If xi_blnAddUser = True Then
      p_lngRtn = NetLocalGroupAddMembers(p_lngPtrServerName, _
                                         p_lngPtrGroupName, _
                                         LocalGroupMembersInfo3, _
                                         p_lngPtrUserName, _
                                         p_lngMemberCount)
   Else
      p_lngRtn = NetLocalGroupDelMembers(p_lngPtrServerName, _
                                         p_lngPtrGroupName, _
                                         LocalGroupMembersInfo3, _
                                         p_lngPtrUserName, _
                                         p_lngMemberCount)
   End If
   
   If p_lngRtn = NERR_Success Then
      AddDelUserToLocal = True
   Else
      AddDelUserToLocal = False
   End If
   
End Function

' ================================================
' Convert the SID type to a text string
' ================================================
Private Function TranslateSidUsage(ByVal xi_lngSidType As Long) As String
   Dim p_strTmp                  As String
   
   Select Case xi_lngSidType
      Case SidTypeUser
         p_strTmp = "User Account"
      Case SidTypeGroup
         p_strTmp = "Global Group Account"
      Case SidTypeDomain
         p_strTmp = "Domain Group Account"
      Case SidTypeAlias
         p_strTmp = "Alias Account"
      Case SidTypeWellKnownGroup
         p_strTmp = "Well-known Group Account (ie, Everyone)"
      Case SidTypeDeletedAccount
         p_strTmp = "Deleted Account"
      Case SidTypeInvalid
         p_strTmp = "Invalid Account"
      Case SidTypeUnknown
         p_strTmp = "Account Type Cannot Be Determined"
      Case Else
         p_strTmp = "Bad Parameter for Sid Usage"
   End Select
   
   ' Set the return value
   TranslateSidUsage = p_strTmp
   
End Function

' ================================================
' Convert a pointer to a string into a string
' ================================================
Public Function PointerToStringW(ByVal xi_lngPtrToString As Long) As String
   Dim p_strText           As String
   Dim p_lngLength         As Long

   If xi_lngPtrToString Then
         p_lngLength = lstrlenW(xi_lngPtrToString)
      If p_lngLength > 0 Then
         p_strText = Space$(p_lngLength)
         CopyMem ByVal StrPtr(p_strText), ByVal xi_lngPtrToString, p_lngLength * 2
      End If
   End If
   
   PointerToStringW = p_strText

End Function

' ================================================
' Convert a pointer to a string into a string via 
' a byte array
' ================================================
Private Function PointerToStringWByte(ByVal xi_lngPtrToString As Long) As String
   Dim p_abytBuffer()      As Byte
   Dim p_lngLen            As Long
   
   If xi_lngPtrToString <> 0 Then
      p_lngLen = lstrlenW(xi_lngPtrToString) * 2
      If p_lngLen Then
         ReDim p_abytBuffer(0 To (p_lngLen - 1)) As Byte
         CopyMem p_abytBuffer(0), ByVal xi_lngPtrToString, p_lngLen
         PointerToStringWByte = p_abytBuffer
      End If
   End If
   
End Function
DevX Pro
 
Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap
Thanks for your registration, follow us on our social networks to keep up-to-date