Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

NT User Group Info

Status
Not open for further replies.

tcorrigan

Programmer
Jun 3, 1999
43
US
I need to get the list of groups a user belongs to in an NT Domain. Can anybody point me at sample VB code as to how to do this?
 
<br>
Take a look at the Net* functions. Do you care if the groups are NT local groups or domain groups? I think the API has trouble returning one or the other of them -- probably only gives you the domain groups.<br>
<br>
I'm on vacation starting five hours ago, so can you possibly wait until next Tuesday when I'm back in the office, and I'll check for you then?<br>
<br>
Chip H.<br>

 
I just got back from vacation myself. I would be very interested in any more information you can provide.
 
The microsoft site has all the API's well documented.<br>
The calls you are looking for are:<br>
<br>
For getting the group names given a user ID:<br>
1)NetUserGetGroups (for global groups - specify a userid)<br>
2)NetUserGetLocalGroups (for Local groups - specify a userid)<br>
3)NetGroupEnum (for global groups - gives all group names, no user name req'd)<br>
4)NetLocalGroupEnum (for Local groups - gives all group names, no user name req'd)<br>
<br>
For getting the users within a group: <br>
1)NetGroupGetUsers (for global groups - specify a group)<br>
2)NetLocalGroupGetMembers (for local groups - specify a group)<br>
3)NetUserEnum (for all the users in a domain - no group name req'd)<br>
<br>
There is a snipit of code supplied by microsoft at their site. You should check out the site directly yourself. The code sample is as follows......<br>
__________________________________________________________<br>
Option Explicit<br>
Option Base 0 ' Important assumption for this code<br>
<br>
Type MungeLong<br>
X As Long<br>
Dummy As Integer<br>
End Type<br>
<br>
Type MungeInt<br>
XLo As Integer<br>
XHi As Integer<br>
Dummy As Integer<br>
End Type<br>
<br>
Type TUser0 ' Level 0<br>
ptrName As Long<br>
End Type<br>
<br>
Type TUser1 ' Level 1<br>
ptrName As Long<br>
ptrPassword As Long<br>
dwPasswordAge As Long<br>
dwPriv As Long<br>
ptrHomeDir As Long<br>
ptrComment As Long<br>
dwFlags As Long<br>
ptrScriptPath As Long<br>
End Type<br>
<br>
'<br>
' for dwPriv<br>
'<br>
Const USER_PRIV_MASK = &H3<br>
Const USER_PRIV_GUEST = &H0<br>
Const USER_PRIV_USER = &H1<br>
Const USER_PRIV_ADMIN = &H2<br>
<br>
'<br>
' for dwFlags<br>
'<br>
Const UF_SCRIPT = &H1<br>
Const UF_ACCOUNTDISABLE = &H2<br>
Const UF_HOMEDIR_REQUIRED = &H8<br>
Const UF_LOCKOUT = &H10<br>
Const UF_PASSWD_NOTREQD = &H20<br>
Const UF_PASSWD_CANT_CHANGE = &H40<br>
Const UF_NORMAL_ACCOUNT = &H200 ' Needs to be ORed with the<br>
' other flags<br>
<br>
'<br>
' for lFilter<br>
'<br>
Const FILTER_NORMAL_ACCOUNT = &H2<br>
<br>
Declare Function NetGetDCName Lib "NETAPI32.DLL" (ServerName As Byte, _<br>
DomainName As Byte, DCNPtr As Long) As Long<br>
<br>
Declare Function NetUserDel Lib "NETAPI32.DLL" (ServerName As Byte, _<br>
UserName As Byte) As Long<br>
<br>
Declare Function NetGroupAddUser Lib "NETAPI32.DLL" (ServerName As _<br>
Byte, GroupName As Byte, UserName As Byte) As Long<br>
<br>
Declare Function NetGroupDelUser Lib "NETAPI32.DLL" (ServerName As _<br>
Byte, GroupName As Byte, UserName As Byte) As Long<br>
<br>
' Add using Level 1 user structure<br>
Declare Function NetUserAdd1 Lib "NETAPI32.DLL" Alias "NetUserAdd" _<br>
(ServerName As Byte, ByVal Level As Long, Buffer As TUser1, ParmError _<br>
As Long) As Long<br>
<br>
' Enumerate using Level 0 user structure<br>
Declare Function NetUserEnum0 Lib "NETAPI32.DLL" Alias "NetUserEnum" _<br>
(ServerName As Byte, ByVal Level As Long, ByVal lFilter As Long, _<br>
Buffer As Long, ByVal PrefMaxLen As Long, EntriesRead As Long, _<br>
TotalEntries As Long, ResumeHandle As Long) As Long<br>
<br>
Declare Function NetGroupEnumUsers0 Lib "NETAPI32.DLL" Alias _<br>
"NetGroupGetUsers" (ServerName As Byte, GroupName As Byte, _<br>
ByVal Level As Long, Buffer As Long, ByVal PrefMaxLen As Long, _<br>
EntriesRead As Long, TotalEntries As Long, ResumeHandle As Long) As Long<br>
<br>
Declare Function NetGroupEnum0 Lib "NETAPI32.DLL" Alias "NetGroupEnum" _<br>
(ServerName As Byte, ByVal Level As Long, Buffer As Long, ByVal _<br>
PrefMaxLen As Long, EntriesRead As Long, TotalEntries As Long, _<br>
ResumeHandle As Long) As Long<br>
<br>
Declare Function NetUserGetGroups0 Lib "NETAPI32.DLL" Alias _<br>
"NetUserGetGroups" (ServerName As Byte, UserName As Byte, _<br>
ByVal Level As Long, Buffer As Long, ByVal PrefMaxLen As Long, _<br>
EntriesRead As Long, TotalEntries As Long) As Long<br>
<br>
Declare Function NetAPIBufferFree Lib "NETAPI32.DLL" Alias _<br>
"NetApiBufferFree" (ByVal Ptr As Long) As Long<br>
<br>
Declare Function NetAPIBufferAllocate Lib "NETAPI32.DLL" Alias _<br>
"NetApiBufferAllocate" (ByVal ByteCount As Long, Ptr As Long) As Long<br>
<br>
Declare Function PtrToStr Lib "Kernel32" Alias "lstrcpyW" _<br>
(RetVal As Byte, ByVal Ptr As Long) As Long<br>
<br>
Declare Function StrToPtr Lib "Kernel32" Alias "lstrcpyW" _<br>
(ByVal Ptr As Long, Source As Byte) As Long<br>
<br>
Declare Function PtrToInt Lib "Kernel32" Alias "lstrcpynW" _<br>
(RetVal As Any, ByVal Ptr As Long, ByVal nCharCount As Long) As Long<br>
<br>
Declare Function StrLen Lib "Kernel32" Alias "lstrlenW" _<br>
(ByVal Ptr As Long) As Long<br>
<br>
Function AddUserToGroup(ByVal SName As String, _<br>
ByVal GName As String, ByVal UName As String) As Long<br>
'<br>
' This only adds users to global groups - not to local groups<br>
'<br>
Dim SNArray() As Byte, GNArray() As Byte, UNArray() As Byte, _<br>
Result As Long<br>
SNArray = SName & vbNullChar<br>
GNArray = GName & vbNullChar<br>
UNArray = UName & vbNullChar<br>
Result = NetGroupAddUser(SNArray(0), GNArray(0), UNArray(0))<br>
If Result = 2220 Then Debug.Print _<br>
"There is no **GLOBAL** group '" & GName & "'"<br>
AddUserToGroup = Result<br>
End Function<br>
<br>
Function DelUser(ByVal SName As String, ByVal UName As String) As Long<br>
Dim UNArray() As Byte, SNArray() As Byte<br>
UNArray = UName & vbNullChar<br>
SNArray = SName & vbNullChar<br>
DelUser = NetUserDel(SNArray(0), UNArray(0))<br>
End Function<br>
<br>
Function DelUserFromGroup(ByVal SName As String, _<br>
ByVal GName As String, ByVal UName As String) As Long<br>
'<br>
' This only deletes users from global groups - not local groups<br>
'<br>
Dim SNArray() As Byte, GNArray() As Byte, UNArray() As Byte, _<br>
Result As Long<br>
SNArray = SName & vbNullChar<br>
GNArray = GName & vbNullChar<br>
UNArray = UName & vbNullChar<br>
Result = NetGroupDelUser(SNArray(0), GNArray(0), UNArray(0))<br>
If Result = 2220 Then Debug.Print _<br>
"There is no **GLOBAL** group '" & GName & "'"<br>
DelUserFromGroup = Result<br>
End Function<br>
<br>
Function EnumerateGroups(ByVal SName As String, _<br>
ByVal UName As String) As Long<br>
'<br>
' Enumerates global groups only - not local groups<br>
'<br>
' The buffer is filled from the left with pointers to user names that<br>
' are filled from the right side. For example:<br>
'<br>
' ptr1¦ptr2¦...¦ptrn¦&lt;garbage&gt;¦strn¦...¦str2¦str1<br>
' ^-------------- BufPtr buffer ----------------^<br>
'<br>
' On NT, TotalEntries is the number of entries left to be read including<br>
' the currently read entries.<br>
'<br>
' On LanMan and OS/2, it is the total number of entries, period. Code<br>
' would have to be changed to reflect this if the Domain controller<br>
' wasn't an NT machine.<br>
'<br>
' BufPtr gets the address of the buffer (or ptr1 - add 4 to BufPtr for<br>
' each additional pointer)<br>
'<br>
Dim Result As Long, BufPtr As Long, EntriesRead As Long, _<br>
TotalEntries As Long, ResumeHandle As Long, BufLen As Long, _<br>
SNArray() As Byte, GNArray(99) As Byte, UNArray() As Byte, _<br>
GName As String, I As Integer, UNPtr As Long, _<br>
TempPtr As MungeLong, TempStr As MungeInt<br>
<br>
SNArray = SName & vbNullChar ' Move to byte array<br>
UNArray = UName & vbNullChar ' Move to Byte array<br>
BufLen = 255 ' Buffer size<br>
ResumeHandle = 0 ' Start with the first entry<br>
<br>
Do<br>
If UName = "" Then<br>
Result = NetGroupEnum0(SNArray(0), 0, BufPtr, BufLen, _<br>
EntriesRead, TotalEntries, ResumeHandle)<br>
Else<br>
Result = NetUserGetGroups0(SNArray(0), UNArray(0), 0, BufPtr, _<br>
BufLen, EntriesRead, TotalEntries)<br>
End If<br>
EnumerateGroups = Result<br>
If Result &lt;&gt; 0 And Result &lt;&gt; 234 Then ' 234 means multiple reads<br>
' required<br>
Debug.Print "Error " & Result & " enumerating group " & _<br>
EntriesRead & " of " & TotalEntries<br>
Exit Function<br>
End If<br>
For I = 1 To EntriesRead<br>
' Get pointer to string from beginning of buffer<br>
' Copy 4 byte block of memory in 2 steps<br>
Result = PtrToInt(TempStr.XLo, BufPtr + (I - 1) * 4, 2)<br>
Result = PtrToInt(TempStr.XHi, BufPtr + (I - 1) * 4 + 2, 2)<br>
LSet TempPtr = TempStr ' munge 2 Integers to a Long<br>
' Copy string to array and convert to a string<br>
Result = PtrToStr(GNArray(0), TempPtr.X)<br>
GName = Left(GNArray, StrLen(TempPtr.X))<br>
Debug.Print "Group: " & GName<br>
Next I<br>
Loop Until EntriesRead = TotalEntries<br>
' The above condition only valid for reading accounts on NT<br>
' but not OK for OS/2 or LanMan<br>
<br>
Result = NetAPIBufferFree(BufPtr) ' Don't leak memory<br>
<br>
End Function<br>
<br>
Function EnumerateUsers(ByVal SName As String, ByVal GName As String) _<br>
As Long<br>
'<br>
' If a group name is specified, it must be a global group<br>
' and not a local group.<br>
'<br>
' The buffer is filled from the left with pointers to user names that<br>
' are filled from the right side. For example:<br>
'<br>
' ptr1¦ptr2¦...¦ptrn¦&lt;garbage&gt;¦strn¦...¦str2¦str1<br>
' ^-------------- BufPtr buffer ----------------^<br>
'<br>
' On Windows NT, TotalEntries is the number of entries left to be read,<br>
' including the currently read entries.<br>
' On LanMan and OS/2, it is the total number of entries, period. Code<br>
' would have to be changed to reflect this if the Domain controller<br>
' wasn't an NT machine.<br>
'<br>
' BufPtr gets the address of the buffer (or ptr1 - add 4 to BufPtr for<br>
' each additional pointer)<br>
'<br>
' SName should be "\\servername"<br>
'<br>
Dim Result As Long, BufPtr As Long, EntriesRead As Long, _<br>
TotalEntries As Long, ResumeHandle As Long, BufLen As Long, _<br>
SNArray() As Byte, GNArray() As Byte, UNArray(99) As Byte, _<br>
UName As String, I As Integer, UNPtr As Long, TempPtr As MungeLong, _<br>
TempStr As MungeInt<br>
<br>
SNArray = SName & vbNullChar ' Move to byte array<br>
GNArray = GName & vbNullChar ' Move to Byte array<br>
BufLen = 255 ' Buffer size<br>
ResumeHandle = 0 ' Start with the first entry<br>
<br>
Do<br>
If GName = "" Then<br>
Result = NetUserEnum0(SNArray(0), 0, FILTER_NORMAL_ACCOUNT, _<br>
BufPtr, BufLen, EntriesRead, TotalEntries, ResumeHandle)<br>
Else<br>
Result = NetGroupEnumUsers0(SNArray(0), GNArray(0), 0, BufPtr, _<br>
BufLen, EntriesRead, TotalEntries, ResumeHandle)<br>
End If<br>
EnumerateUsers = Result<br>
If Result &lt;&gt; 0 And Result &lt;&gt; 234 Then ' 234 means multiple reads<br>
' required<br>
Debug.Print "Error " & Result & " enumerating user " _<br>
& EntriesRead & " of " & TotalEntries<br>
If Result = 2220 Then Debug.Print _<br>
"There is no **GLOBAL** group '" & GName & "'"<br>
Exit Function<br>
End If<br>
For I = 1 To EntriesRead<br>
' Get pointer to string from beginning of buffer<br>
' Copy 4-byte block of memory in 2 steps<br>
Result = PtrToInt(TempStr.XLo, BufPtr + (I - 1) * 4, 2)<br>
Result = PtrToInt(TempStr.XHi, BufPtr + (I - 1) * 4 + 2, 2)<br>
LSet TempPtr = TempStr ' munge 2 integers into a Long<br>
' Copy string to array<br>
Result = PtrToStr(UNArray(0), TempPtr.X)<br>
UName = Left(UNArray, StrLen(TempPtr.X))<br>
Debug.Print "User: " & UName<br>
Next I<br>
Loop Until EntriesRead = TotalEntries<br>
' The above condition is only valid for reading accounts on Windows NT,<br>
' but is not OK for OS/2 or LanMan<br>
<br>
Result = NetAPIBufferFree(BufPtr) ' Don't leak memory<br>
<br>
End Function<br>
<br>
Function GetPrimaryDCName(ByVal MName As String, _<br>
ByVal DName As String) As String<br>
Dim Result As Long, DCName As String, DCNPtr As Long<br>
Dim DNArray() As Byte, MNArray() As Byte, DCNArray(100) As Byte<br>
MNArray = MName & vbNullChar<br>
DNArray = DName & vbNullChar<br>
Result = NetGetDCName(MNArray(0), DNArray(0), DCNPtr)<br>
If Result &lt;&gt; 0 Then<br>
Debug.Print "Error: " & Result<br>
Exit Function<br>
End If<br>
Result = PtrToStr(DCNArray(0), DCNPtr)<br>
Result = NetAPIBufferFree(DCNPtr)<br>
DCName = DCNArray()<br>
GetPrimaryDCName = DCName<br>
End Function<br>
<br>
Function AddUser(ByVal SName As String, ByVal UName As String, _<br>
ByVal PWD As String) As Long<br>
Dim Result As Long, UNPtr As Long, PWDPtr As Long, ParmError As Long<br>
Dim SNArray() As Byte, UNArray() As Byte, PWDArray() As Byte<br>
Dim UserStruct As TUser1<br>
'<br>
' Move to byte arrays<br>
'<br>
SNArray = SName & vbNullChar<br>
UNArray = UName & vbNullChar<br>
PWDArray = PWD & vbNullChar<br>
'<br>
' Allocate buffer space<br>
'<br>
Result = NetAPIBufferAllocate(UBound(UNArray) + 1, UNPtr)<br>
Result = NetAPIBufferAllocate(UBound(PWDArray) + 1, PWDPtr)<br>
'<br>
' Copy arrays to the buffer<br>
'<br>
Result = StrToPtr(UNPtr, UNArray(0))<br>
Result = StrToPtr(PWDPtr, PWDArray(0))<br>
'<br>
' Fill the structure<br>
'<br>
With UserStruct<br>
.ptrName = UNPtr<br>
.ptrPassword = PWDPtr<br>
.dwPasswordAge = 3<br>
.dwPriv = USER_PRIV_USER<br>
.ptrHomeDir = 0<br>
.ptrComment = 0<br>
.dwFlags = UF_NORMAL_ACCOUNT Or UF_SCRIPT<br>
.ptrScriptPath = 0<br>
End With<br>
'<br>
' Add the user<br>
'<br>
Result = NetUserAdd1(SNArray(0), 1, UserStruct, ParmError)<br>
AddUser = Result<br>
If Result &lt;&gt; 0 Then<br>
Debug.Print "Error " & Result & " in parameter " & ParmError _<br>
& " when adding user " & UName<br>
End If<br>
'<br>
' Release buffers from memory<br>
'<br>
Result = NetAPIBufferFree(UNPtr)<br>
Result = NetAPIBufferFree(PWDPtr)<br>
<br>
End Function<br>
<br>

 
Thanks for your help, this is just what I was looking for
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top