Forum: Ruby Retrieving Groups from a DSQUERY

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
D4f5ba376e2d4e280889ed462939f632?d=identicon&s=25 anon1m0us (Guest)
on 2007-04-24 15:30
(Received via mailing list)
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??
260b864377cc125e575de59843cb02b3?d=identicon&s=25 Clifford Heath (Guest)
on 2007-04-25 01:36
(Received via mailing list)
anon1m0us wrote:
> 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.
6087a044557d6b59ab52e7dd20f94da8?d=identicon&s=25 Peña, Botp (Guest)
on 2007-04-25 04:21
(Received via mailing list)
From: anon1m0us [mailto:anon1m0us@yahoo.com] :
# 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??

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=`dsquery group -limit 1000 | egrep -i "internet(users| mail)"`

len = 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 = `dsget group #{g} -members`

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

hth.
kind regards -botp
260b864377cc125e575de59843cb02b3?d=identicon&s=25 Clifford Heath (Guest)
on 2007-04-25 05:45
(Received via mailing list)
Peña wrote:
> 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.
6087a044557d6b59ab52e7dd20f94da8?d=identicon&s=25 Peña, Botp (Guest)
on 2007-04-25 06:23
(Received via mailing list)
From: Clifford Heath [mailto:no.spam@please.net] :
# 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)

# 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.

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..
260b864377cc125e575de59843cb02b3?d=identicon&s=25 Clifford Heath (Guest)
on 2007-04-25 07:36
(Received via mailing list)
Peña wrote:
> 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.
6087a044557d6b59ab52e7dd20f94da8?d=identicon&s=25 Peña, Botp (Guest)
on 2007-04-25 08:07
(Received via mailing list)
From: Clifford Heath [mailto:no.spam@please.net]
# 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.
Many thanks again,
-botp
This topic is locked and can not be replied to.