Active directory groups

Phil Mayers p.mayers at imperial.ac.uk
Wed May 18 18:38:37 CEST 2011


On 18/05/11 17:22, Gary Gatten wrote:
> If one has (just for example) 1000 groups, this is a lot of overhead

Sure (I did see your query the other day - I just haven't had a chance 
to write up a reply, but see below)

> - checking every group.  Also, what if they belong to several groups?

Well, you have to decide some order of precedence. FreeRADIUS can't do 
that for you

> The last group checked would be the only one that matters - unless of
> course you account for that somehow in your code.
>
> Is there a way to reference the users "primary" group - does LDAP /
> AD support such a concept?

Yes, but it's got a list of caveats a mile long. I would avoid it. In brief:

Primary group is encoded in LDAP in a really unhelpful manner:

primaryGroupID: <number>

...the number is a RID. You need to find the domain SID, append the RID, 
encode the SID to binary, then do a lookup on objectSid. It's tedious.

In addition, the tools to control which group is "primary" are (IMHO) 
weak because

You've also got the problem that the "primary" group does NOT appear in 
the "memberOf" attribute for a user, and group members who are primary 
do not appear in the "member" attribute of the group, meaning you can't 
check them over LDAP using the "normal" route either.

In most domains, the primary group of a user ends up being "Domain 
Users". My advice: don't fiddle with that, and avoid using primary 
group. We've had endless troubles with this.

>
> Or, "fetch" their full distinguished name using just their common /
> logon name, such that?

The "ldap" module already extracts the DN for you:

authorize {
   ..
   ldap
   if (control:Ldap-UserDN =~ /^CN=[^,]+,OU=([^,]+)/) {
     update control {
       Tmp-String-0 := "%{1}"
     }
   }

   switch (control:Tmp-String-0) {
     case "neteng" {
       update reply {
         ..
       }
     }

   }

}


The other option would be to pull *all* the LDAP groups into a radius 
attribute, like so:

/etc/raddb/dictionary:

ATTRIBUTE	My-Groups	3001	string

/etc/raddb/ldap.attrmap

checkItem	My-Groups	memberOf

/etc/raddb/sites-enabled/XXX:

authorize {

   ldap
   if (control:My-Groups == CN=group,OU=bar,DC=domain,DC=com) {
     ...
   }

}

...but it's messy, because memberOf is an LDAP DN, and LDAP DNs are messy.

It also doesn't handle nested groups well, but nested groups over LDAP 
are a nightmare.

Frankly, the best way to handle this might be a perl/python 
module/script. Or better yet, extract all the groups from AD/LDAP and 
put them into a user:group file and read it with rlm_passwd, or into an 
SQL group cache (we do this).

Basically, extracting group data from AD over LDAP is a non-trivial 
amount of work for almost all non-trivial cases.



More information about the Freeradius-Users mailing list