Retrieving Groups from a DSQUERY

A

anon1m0us

I need a list of all the groups a user is part of. When I do the
DSQuery in returns a bunch of groups. I need to capture the group
names.
All groups start with CN=group name and end with a comma.
How to I capture the group name only, which starts after CN= and ends
at the FIRST comma??
 
C

Clifford Heath

anon1m0us said:
I need a list of all the groups a user is part of. When I do the
DSQuery in returns a bunch of groups. I need to capture the group
names.
All groups start with CN=group name and end with a comma.
How to I capture the group name only, which starts after CN= and ends
at the FIRST comma??

Actually it doesn't end at the first comma - you could have
a backslashed comma inside the group's CN. I recsll doing it
something like this:

group_dn ='CN=Users\, Group,OU=farnarkle'

group_cn = group_dn.sub(/CN=(:)?[^\\,]|\\.)*).*/, $1)

puts group_cn

Users\, Group

This matches the name as a sequence of either a single
backslashed character, or a char that's not either
a backslash or a comma. Note that the result is still
LDAP-escaped.

Clifford Heath.
 
P

Peña, Botp

From: anon1m0us [mailto:[email protected]] :
# I need a list of all the groups a user is part of. When I do the
# DSQuery in returns a bunch of groups. I need to capture the group
# names.
# All groups start with CN=3Dgroup name and end with a comma.
# How to I capture the group name only, which starts after CN=3D and =
ends
# at the FIRST comma??

small world ;)

look into "dsquery group" and "dsget group <group_name> -members"

C:\family\ruby\win-ds-groups>cat test.rb
#######################
# botp
# updated: 2007 03 21
#######################

# get all internet groups w names like "internet mail or internetusers"
groups=3D`dsquery group -limit 1000 | egrep -i "internet(users| mail)"`

len =3D groups.max.length + 20 # not important; just want to get length =
for
header line separator

# display groups and the count
groups.each_with_index do |g,i|
puts "-"*len
puts "Group #{i+1}: #{g}"
puts "-"*len

# for each group get the members
members =3D `dsget group #{g} -members`

# for each member display name and the count
members.each_with_index do |m,i|
name =3D m.sub ",CN=3DUsers,DC=3Ddelmonte-phil,DC=3Dcom\"", ""
name =3D name.sub "\"CN=3D", ""
name =3D name.sub "\\", ""
puts "#{i+1}: #{name}"
end
end
#------------------

hth.
kind regards -botp
 
C

Clifford Heath

Peña said:
look into "dsquery group" and "dsget group <group_name> -members"

It sounds like the OP already did that.
name = m.sub ",CN=Users,DC=delmonte-phil,DC=com\"", ""
name = name.sub "\"CN=", ""
name = name.sub "\\", ""

This only works for users in CN=Users, even assuming that
you adjust the domain name as appropriate. My solution
gets the CN from any user, whether in CN=Users or not,
without knowing the domain name.

Hint: many organizations put their users in OU's... The
CN=Users container is really only there for migration
from NT4, so the domain root isn't filled up with users
and computers from the migration.

It's even legal to put users in a container (CN=) under
an OU, though it's not advised (it's allowed because
that's what CN=Users is). The only correct solution is
to match the RDN component after the user's CN=, up to
the start of the next RDN part, as I showed.

Clifford Heath.
 
P

Peña, Botp

From: Clifford Heath [mailto:[email protected]] :
# It sounds like the OP already did that.

arggh, mea culpa. you're right, in fact, after reading again th op, my =
sample was totally wrong. He was asking what groups the user belong to =
and my sample just plain listed all the groups and users (of no use =
really)
=20
# This only works for users in CN=3DUsers, even assuming that
# you adjust the domain name as appropriate. My solution
# gets the CN from any user, whether in CN=3DUsers or not,
# without knowing the domain name.
#=20
# Hint: many organizations put their users in OU's... The
# CN=3DUsers container is really only there for migration
# from NT4, so the domain root isn't filled up with users
# and computers from the migration.
#=20
# It's even legal to put users in a container (CN=3D) under
# an OU, though it's not advised (it's allowed because
# that's what CN=3DUsers is). The only correct solution is
# to match the RDN component after the user's CN=3D, up to
# the start of the next RDN part, as I showed.

Great tip/info there, Clifford.

Many thanks
-botp

ps: Clifford, if by any chance you know how to query a msexchange: I'd =
like to query all exchange mailboxes and for each mailbox, list all the =
users who have rights to access it. (since many of us share mailboxes). =
Pardon the nubiness on windows/exchange..
 
C

Clifford Heath

Peña said:
ps: Clifford, if by any chance you know how to query a msexchange:
I'd like to query all exchange mailboxes and for each mailbox,
list all the users who have rights to access it.
(since many of us share mailboxes).
Pardon the nubiness on windows/exchange..

On the contrary, this is *not* a nuby question.
I do know how to do it, it is *not* simple,
and there's not a supported method AFAIK.

Apologies for the non-Ruby-ness of the following...

You need to enumerate the Access Control Entries for
the mailbox (and potentially the mbox's ancestors)
and for each relevant ACE that pertains to a group,
establish the transitive closure of the group's
membership. Do this separately across all ACEs for
both the allowed members and the denied members, then
subtract the denied set from the allowed set. Either
set may be a wild-card (like World, or Authenticated
Users), so you must handle that.

This is thousands of lines of code, and cannot be done
efficiently using ADSI (or ADO/ADSI) because the ADSI
ACE's hide the SID, exposing only the SAM name of the
ACE, which is obtained by a remote directory lookup.
LDAP is the way to go. Even that's not easy, since you
can't get the ACL via LDAP unless you send a special
custom LDAP control with the query, saying you don't
want the sACL when you fetch the ntSecurityDescriptor.

As you can tell, I've actually done this, but it was
for a former employer and I'm not at liberty to share
the code. It was close to being their prize jewel :).

Clifford Heath.
 
P

Peña, Botp

From: Clifford Heath [mailto:[email protected]]=20
# You need to enumerate the Access Control Entries for
# the mailbox (and potentially the mbox's ancestors)
# and for each relevant ACE that pertains to a group,
# establish the transitive closure of the group's
# membership. Do this separately across all ACEs for
# both the allowed members and the denied members, then
# subtract the denied set from the allowed set. Either
# set may be a wild-card (like World, or Authenticated
# Users), so you must handle that.
# This is thousands of lines of code, and cannot be done
# efficiently using ADSI (or ADO/ADSI) because the ADSI
# ACE's hide the SID, exposing only the SAM name of the
# ACE, which is obtained by a remote directory lookup.
# LDAP is the way to go. Even that's not easy, since you
# can't get the ACL via LDAP unless you send a special
# custom LDAP control with the query, saying you don't
# want the sACL when you fetch the ntSecurityDescriptor.

Clifford, this great info.=20
Many thanks again,
-botp
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top