Win2K/Net user group enumeration with LDAP? 
Author Message
 Win2K/Net user group enumeration with LDAP?

I know user group enumeration has been beaten to death in this
newsgroup and I have read many of the articles. Michael Harris's
script and knowledge are the basis of what I have so far and it works
well. I will include my modified logon script below...

My question is, can this script be modified to use LDAP? It might be
simple... I just don't understand LDAP that well. Here is one entry of
what my User container looks like:

LDAP://yamato/CN=Test User,CN=Users,DC=Command,DC=starbase-01,DC=com

And here is the basic LDAP connection to pull the data:

Set UserContainer =
GetObject("LDAP://yamato/CN=Users,DC=Command,DC=starbase-01,DC=com")

Hope this helps someone answer my question.

Thanks!
/*Raj*/

=-=-=-=-=-=-=-=-=-=-=-=-=
Logon script
=-=-=-=-=-=-=-=-=-=-=-=-=

Option Explicit

Dim strDomainName, strUsername
Dim objNet
Dim objGroupList
Dim objUser

Set objNet = createObject("Wscript.Network")

On Error Resume Next
  strUsername = ""
  While strUsername = ""
    Err.Clear: strUsername = objNet.Username
    If Err Then WScript.Sleep 100
  Wend
On Error Goto 0

'Get the Domain Name
strDomainName = objNet.UserDomain

Set objGroupList = CreateObject("Scripting.Dictionary")

Call LoadNTGroups(strDomainName, strUsername)

'Print some information for the user
Set objUser = GetObject("WinNT://" & strDomainName & "/" &
strUsername)
Wscript.Echo "Hello " & objUser.FullName
Wscript.Echo "Password expires on: " & objUser.passwordexpirationdate

If InGroup("domain users") Then
    'do this....
    Wscript.Echo "User is a Domain User"
    'Map drive(s)
    'objNet.MapNetworkDrive "l:", "\\filesrv01\applics"
End if
If InGroup("domain admins") Then
    'do that...
     Wscript.Echo "User is a Domain Admin"
    'Map drive(s)
    'objNet.MapNetworkDrive "m:", "\\filesrv01\admin"
End If

'====================================================================
' Load objGroupList (Dictionary) with user's NT group membership...
'====================================================================
Sub LoadNTGroups(vDomainName, vUsername)

  Dim objUser
  Dim objGrp

  Set objUser = GetObject("WinNT://" & vDomainName & "/" & vUsername)

  objGroupList.CompareMode = vbTextCompare
  For Each objGrp In objUser.Groups
    objGroupList(objGrp.name) = True
  Next

End Sub

'====================================================================
' Emulate the KIX InGroup function...
'====================================================================
Function InGroup(sGroup)
  InGroup = objGroupList.Exists(sGroup)
End Function

Wscript.Quit



Fri, 08 Apr 2005 10:17:56 GMT  
 Win2K/Net user group enumeration with LDAP?
Hi,

The short answer is that it can be done with LDAP.
However, it can quickly get complicated. I note that you
use a loop to retrieve objNet.UserName, so I assume you
have Win9x clients. I find that objNet.UserDomain returns
blank on Win9x clients. Also, to use Wscript.Sleep, all
the clients must have WSH 5.1 or above.

LDAP has many advantages, such as revealing membership in
nested groups. It also reveals many more attributes. If
you don't need these features, you can stick with WinNT.
If you use LDAP, I assume you want to take advantage of
it, so I include an IsMember function that handles nested
groups. It doesn't crash if the nested groups are
circular. However, it does NOT reveal membership in
the "primary" group. This is a limitation of LDAP.

The first problem with LDAP (after you get
objNet.UserName) is binding to the user object.
objNet.UserName must be translated. Also, getting the DNS
Domain name is required. All of this is handled below.
Note that group objects do not support the .Groups method,
so you must use the .MemberOf collection in a recursive
function to get nested groups. The code has to handle
cases where this collection is empty, has one item, or has
many items.

Option Explicit
Dim oRoot, oTrans, sNetBIOSDomain, oNet, sNTUser, sAdsPath
Dim oGroupList, sGroup, oUser, sDNSDomain

Set oNet = CreateObject("Wscript.Network")

sNTName = ""
On Error Resume Next
Err.Clear
Do While sNTName = ""
  sNTName = oNet.UserName
  Err.Clear
  If Wscript.Version > 5 Then
    Wscript.Sleep 100
  End If
Loop
On Error GoTo 0

Set oRoot = GetObject("LDAP://RootDSE")
Set oTrans = CreateObject("NameTranslate")
sDNSDomain = oRoot.Get("DefaultNamingContext")
oTrans.Init 3, sDNSDomain
oTrans.Set 1, sDNSDomain
sNetBIOSDomain = oTrans.Get(3)
oTrans.Init 1, _
  Left(sNetBIOSDomain, Len(sNetBIOSDomain) - 1)
oTrans.Set 3, sNetBIOSDomain & sNTUser
sAdsPath = oTrans.Get(1)
Set oUser = GetObject("LDAP://" & sAdsPath)

If IsMember("Domain Admin") Then
  oNet.MapNetworkDrive "M:", "\\filesrv01\admin"
End If

Function IsMember(sGroup)
' Function to test for group membership.
  If IsEmpty(oGroupList) Then
    Set oGroupList = CreateObject("Scripting.Dictionary")
    Call LoadGroups(oUser)
  End If
  IsMember = oGroupList.Exists(sGroup)
End Function

Sub LoadGroups(oADObject)
' Recursive subroutine to populate dictionary object.
  Dim sGroups, oGroup, j
  oGroupList.CompareMode = vbTextCompare
  sGroups = oADObject.MemberOf
  If IsEmpty(sGroups) Then
    Exit Sub
  End If
  If TypeName(sGroups) = "String" Then
    Set oGroup = GetObject("LDAP://" & sGroups)
    If Not oGroupList.Exists(oGroup.sAMAccountName) Then
      oGroupList(oGroup.sAMAccountName) = True
      Call LoadGroups(oGroup)
    End If
    Set oGroup = Nothing
    Exit Sub
  End If
  For j = 0 To UBound(sGroups)
    Set oGroup = GetObject("LDAP://" & sGroups(j))
    If Not oGroupList.Exists(oGroup.sAMAccountName) Then
      oGroupList(oGroup.sAMAccountName) = True
      Call LoadGroups(oGroup)
    End If
  Next
  Set oGroup = Nothing
End Sub

If you need a routine that reveals "primary" group
membership, reply. In most networks this is left as the
default "Domain User" for users and "Domain Computers" for
computer objects, but it can be changed. There are ways to
handle it. Note that the IsMember function above also
works with computer objects. You could map printers
according to which group the computer belongs to.

Richard

Quote:
>-----Original Message-----

>I know user group enumeration has been beaten to death in
this
>newsgroup and I have read many of the articles. Michael
Harris's
>script and knowledge are the basis of what I have so far
and it works
>well. I will include my modified logon script below...

>My question is, can this script be modified to use LDAP?
It might be
>simple... I just don't understand LDAP that well. Here is
one entry of
>what my User container looks like:

>LDAP://yamato/CN=Test

User,CN=Users,DC=Command,DC=starbase-01,DC=com

- Show quoted text -

Quote:

>And here is the basic LDAP connection to pull the data:

>Set UserContainer =
>GetObject("LDAP://yamato/CN=Users,DC=Command,DC=starbase-
01,DC=com")

>Hope this helps someone answer my question.

>Thanks!
>/*Raj*/

>=-=-=-=-=-=-=-=-=-=-=-=-=
>Logon script
>=-=-=-=-=-=-=-=-=-=-=-=-=

>Option Explicit

>Dim strDomainName, strUsername
>Dim objNet
>Dim objGroupList
>Dim objUser

>Set objNet = createObject("Wscript.Network")

>On Error Resume Next
>  strUsername = ""
>  While strUsername = ""
>    Err.Clear: strUsername = objNet.Username
>    If Err Then WScript.Sleep 100
>  Wend
>On Error Goto 0

>'Get the Domain Name
>strDomainName = objNet.UserDomain

>Set objGroupList = CreateObject("Scripting.Dictionary")

>Call LoadNTGroups(strDomainName, strUsername)

>'Print some information for the user
>Set objUser = GetObject("WinNT://" & strDomainName & "/" &
>strUsername)
>Wscript.Echo "Hello " & objUser.FullName
>Wscript.Echo "Password expires on: " &

objUser.passwordexpirationdate

- Show quoted text -

Quote:

>If InGroup("domain users") Then
>    'do this....
>    Wscript.Echo "User is a Domain User"
>    'Map drive(s)
>    'objNet.MapNetworkDrive "l:", "\\filesrv01\applics"
>End if
>If InGroup("domain admins") Then
>    'do that...
>     Wscript.Echo "User is a Domain Admin"
>    'Map drive(s)
>    'objNet.MapNetworkDrive "m:", "\\filesrv01\admin"
>End If

>'=========================================================
===========
>' Load objGroupList (Dictionary) with user's NT group
membership...
>'=========================================================
===========
>Sub LoadNTGroups(vDomainName, vUsername)

>  Dim objUser
>  Dim objGrp

>  Set objUser = GetObject("WinNT://" & vDomainName & "/"
& vUsername)

>  objGroupList.CompareMode = vbTextCompare
>  For Each objGrp In objUser.Groups
>    objGroupList(objGrp.name) = True
>  Next

>End Sub

>'=========================================================
===========
>' Emulate the KIX InGroup function...
>'=========================================================
===========
>Function InGroup(sGroup)
>  InGroup = objGroupList.Exists(sGroup)
>End Function

>Wscript.Quit

>.



Fri, 08 Apr 2005 23:47:11 GMT  
 Win2K/Net user group enumeration with LDAP?

Richard,

Thank you for the detailed script and the education! :) Digging
through Microsoft's limited LDAP documentation is a frustrating
experience to say the least.

On Mon, 21 Oct 2002 08:47:11 -0700, "Richard Mueller"

Quote:

>The short answer is that it can be done with LDAP.
>However, it can quickly get complicated. I note that you
>use a loop to retrieve objNet.UserName, so I assume you
>have Win9x clients. I find that objNet.UserDomain returns
>blank on Win9x clients. Also, to use Wscript.Sleep, all
>the clients must have WSH 5.1 or above.

You are correct I do have quite a few Win98 and WinMe workstations.
Prior to our Win2K migration we pushed WSH 5.6 down to all of our
client systems.

Quote:
>If you need a routine that reveals "primary" group
>membership, reply. In most networks this is left as the
>default "Domain User" for users and "Domain Computers" for
>computer objects, but it can be changed.

Our Win2K network is in it's fledgeling stages right now so for the
most part we have a lot of "primary" groups. Retrieving the primary
group membership would actually be required.

Thank you for all of your help and time.

/*Raj*/



Sat, 09 Apr 2005 02:52:55 GMT  
 Win2K/Net user group enumeration with LDAP?

Quote:

>>computer objects, but it can be changed.

>Our Win2K network is in it's fledgeling stages right now
so for the
>most part we have a lot of "primary" groups. Retrieving
the primary
>group membership would actually be required.

>Thank you for all of your help and time.

>/*Raj*/

I would note that there should be no need to change the
primary group for any user or computer. Then, you can just
assume that everyone is a member of "Domain Users", and
every computer object is a member of "Domain Computers".
The exception (I hear) is if the network supports
Macintosh clients.

Otherwise, the easiest solution is to use the WinNT
provider to enumerate groups, since this will include the
primary group (but not nested groups).

Richard



Sat, 09 Apr 2005 04:41:31 GMT  
 Win2K/Net user group enumeration with LDAP?
On Mon, 21 Oct 2002 13:41:31 -0700, "Richard Mueller"

Quote:

>Otherwise, the easiest solution is to use the WinNT
>provider to enumerate groups, since this will include the
>primary group (but not nested groups).

I agree that would probably be the easiest solution. But just for
argument sake, how would you enumerate the primary groups? I'm trying
to learn as much LDAP as I can... and understand how MS has the
directory (shema?) organized.

Thanks!
/*Raj*/



Sat, 09 Apr 2005 05:19:10 GMT  
 Win2K/Net user group enumeration with LDAP?
Hi,

The procedure Wayne mentions is described in KB article
Q297951. A variation is in Q321360. The primary group of a
user is stored in the PrimaryGroupID attribute. This
number matches the PrimaryGroupToken of the group.
However, because PrimaryGroupToken is calculated, you must
use ADO to search for all groups and return their
PrimaryGroupToken. You then loop through the results,
looking for the group whose PrimaryGroupToken matches the
user's PrimaryGroupID.

You can improve the search by only searching for groups
enumerated as the user's groups by the WinNT provider.
However, maybe it makes more sense to simply determine
which of these groups is not enumerated by LDAP.

Finally, there is another method entirely to enumerate
group memberships. Each user object has a TokenGroups
property. This is a collection of the Sids of all the
groups the user is a member of. This collection includes
the primary group, plus all nested group memberships. It
is a complete list. However, the Sids are OctetString (a
byte array), which requires conversion to a hex string.
Then, you can bind to the group objects with the Sid hex
string to find the group name.

Richard

Quote:
>-----Original Message-----


>> On Mon, 21 Oct 2002 13:41:31 -0700, "Richard Mueller"

>>>Otherwise, the easiest solution is to use the WinNT
>>>provider to enumerate groups, since this will include
the
>>>primary group (but not nested groups).

>> I agree that would probably be the easiest solution.
But just for
>> argument sake, how would you enumerate the primary
groups? I'm trying
>> to learn as much LDAP as I can... and understand how MS
has the
>> directory (shema?) organized.

>> Thanks!
>> /*Raj*/

>I posted an example of how to get the name of a users
Primary Group on
>http://cwashington.netreach.net which you can find if you
search for
>"primarygroup".  The process is to get the PrimaryGroupID
from the user
>object, which is the RID of the Primary Group, and then
calculate the RID
>of each of the user's groups (as obtained from the

WinNT:// provider) to
Quote:
>compare against the value returned from the

PrimaryGroupID attribute.  If

- Show quoted text -

Quote:
>you wanted to do that without using the WinNT provider at
all, you would
>have to enumerate ALL groups in the domain, calculate
each one's RID and
>compare that; not difficult if you've got 100 groups but
hugely time
>consuming if you've got 10,000 groups.

>Wayne

>--
>Standard Disclaimer: I said it, they didn't, so blame me,
not them!
>Spam Avoidance: My reply address is invalid to confuse
the spambots.
>You can reach me at 'Wayne_Tilton at yahoo dot com'
>.



Sun, 10 Apr 2005 03:51:58 GMT  
 
 [ 6 post ] 

 Relevant Pages 

1. Group Enumeration for a user using WSH Vbscript?

2. Adding multiple users to Group with LDAP

3. add user to local win2k administrator group

4. Add Domain Users Group to Powe Users Group in Script

5. Embedded Group Enumeration

6. Guest Group Enumeration

7. Active Directory group member enumeration

8. .NET user group topics are getting BORING........

9. Bay.net user's group meeting

10. SF Bay Area Bay.NET user group presentation

11. Portland Area .NET User Group (PADNUG) Meets 10/29/01

12. Portland Area .NET User Group (PADNUG) Meets 9/24/01

 

 
Powered by phpBB® Forum Software