[RADIATOR] <AuthBy LDAP2> => AD => Group Nesting Issues

Heikki Vatiainen hvn at open.com.au
Mon May 30 06:24:46 CDT 2011


On 05/26/2011 09:38 PM, W.Siebert at t-systems.com wrote:

Hello Waldemar,

> the problem <AuthBy LDAP2> => AD => Group Nesting will be over and over
> again addressed in this forum but not sufficiently resolved.
> We have evermore requirements in our projects to authenticate users in
> nested LDAP group environments.
> I found a perl script from Shawn Poulson,
> _http://www.explodingcoder.com/cms/content/how-query-active-directory-security-group-membership_
>  
> and adjusted it to my relevance. Script is tested directly, very usable.

> My problem is to convert this script to a PostSearchHook.

You can convert the script to a Perl module. This lets you keep the
script structured as it is now. Creating a module is easy.

package ExampleModule;

# You may want to enable these
use strict;
use warnings;

# Variables
my $myvar;

# Functions
sub myfunc {
  # Function body
}

1;

Note that the last thing in the module file should be "1;" as shown
above. Please see below about how to load the module and call its
functions from various Hooks.

> 1. How can I avoid the second LDAP Login/Connection? <AuthBy LDAP2> is
> allready logged in and connected, how can I get to Net::LDAP level?

Define an Identifier for your <AuthBy LDAP2> and use Radiator APIs to
locate the connection:
    my $ldap = Radius::AuthGeneric::find('myidentifier');
    unless ($ldap) {
       # error handling

> $_[4] is Net::LDAP::Entry and caused a error:
>  
> Thu May 26 17:18:28 2011: ERR: Error in PostSearchHook(): Can't locate
> object method "root_dse" via package "Net::LDAP::Entry" at (eval 36)
> line 43.

I tried running the script (needed to remove this line fist: AddToReply
tacacsgroup = XXX) and it was successful for me. You should check what
version of LDAP module you are using. It may be very old or incomplete:

http://cpansearch.perl.org/src/GBARR/perl-ldap-0.4001/Changes

perl-ldap 0.28 19 May 2003
==========================
* New class Net::LDAP::RootDSE

On my OpenSUSE system I have
/usr/lib/perl5/vendor_perl/5.12.1/Net/LDAP/RootDSE.pm and this is what
is required for root_dse to work.

> 2. How can I deliver the LDAP group name ($grp2chk in my script) from
> outside of hook? Can I use arguments in the hook directive? Something
> like this:
>  
> PostSearchHook() ("ASA_FULL", "ARGUMENT02");

If you decide to go with making a Perl module, as I described above, you
can do the following:

StartupHook sub { require "/etc/radiator/ExampleModule.pm"; }

<AuthBy LDAP2>
   # ...
   PostSearchHook sub { ExampleModule::myfunc(@_, 'ASA_FULL'); }
</AuthBy>

this adds 'ASA_FULL' to PostSearchHook arguments, or

PostSearchHook sub { ExampleModule::myfunc(@_, \
   &Radius::Util::format_special('%{User-Name}', $_[2]); }

this example takes User-Name from the current request.

> The script:
>  
> #!/bin/perl
> use Net::LDAP;
> my ($ldap_server, $ldap_username, $ldap_password) = ('10.11.11.112',
> 'radiator', 'Makaka77');
> print "Connecting to LDAP...";     # Login to LDAP
> my $ldap = Net::LDAP->new($ldap_server, async => 0) or die $@;
> print "Binding... ";
> $_ = $ldap->bind($ldap_username, password => $ldap_password) or die $@;
> print $_->error_text();
> #Variablen###############################
> $usr2chk = 'aduser05';
> $grp2chk = 'ASA_FULL';
> #$grp2chk = 'ASA_ANLS';
> $grp2chk = 'ADMINS';
> #Variablen###############################
> my $userDN = GetDNByID($ldap, $usr2chk);
> print "User DN: $userDN\n";
> # Quick check if user is a member of a group
> $check_OK = IsMemberOf($ldap, $userDN, GetDNByID($ldap, $grp2chk));
>   if (IsMemberOf($ldap, $userDN, GetDNByID($ldap, $grp2chk))) {
>   print "User is a member of $grp2chk: $check_OK\n";
>  
>   AddToReply            tacacsgroup = XXX
>  
>   }
>   else {
>   print "User is not a member of $grp2chk: $check_OK\n";
>   }
> $ldap->unbind;
> exit;
>  
> ###Sub's###############################
> # Is DN a member of security group?  Usage: <bool> = IsMemberOf(<DN of
> object>, <DN of group>)
> sub IsMemberOf($$$) {
>   my ($ldap, $objectDN, $groupDN) = @_;
>   return if ($groupDN eq "");
>   my $groupSid = GetSidByDN($ldap, $groupDN);
>   return if ($groupSid eq "");
>   my @matches = grep { $_ eq $groupSid } GetTokenGroups($ldap, $objectDN);
>   @matches > 0;
> }
> # Get object's SID by DN , Usage: <SID> = GetSidByDN(<LDAP ref>, <DN>)
> sub GetSidByDN($$) {
>   my ($ldap, $objectDN) = @_;
>   my $results = $ldap->search( base => $objectDN, scope => 'base',
>   filter => '(objectCategory=*)',attrs => ['objectSid'] );
>     if ($results->count) {
>     return $results->entry(0)->get_value('objectSid');
>     }
> }
> # Gets tokenGroups attribute from the provided DN, Usage: <Array of
> tokens> = GetTokenGroups(<LDAP ref>, <DN of object>)
> sub GetTokenGroups($$) {
>   my ($ldap, $objectDN) = @_;
>   my $results = $ldap->search( base => $objectDN, scope => 'base',
> filter => '(objectCategory=*)',
>   attrs => ['tokenGroups'] );
>     if ($results->count) {
>     return $results->entry(0)->get_value('tokenGroups');
>     }
> }
> # Get DN by sAMAccountName, # Usage: <DN> = GetDNByID(<LDAP ref>, <ID>)
> sub GetDNByID($$) {
>   my ($ldap, $ID) = @_;
>   my $results = $ldap->search( base => GetRootDN($ldap), filter =>
> "(sAMAccountName=$ID)",
>   attrs => ['distinguishedName'] );
>     if ($results->count) {
>     return $results->entry(0)->get_value('distinguishedName');
>     }
> }
> # Get Root DN of logged in domain (e.g. DC=yourdomain,DC=com), Usage:
> <DN> = GetRootDN(<LDAP ref>)
> sub GetRootDN($) {
>   my ($ldap) = @_;
>   ($ldap->root_dse->get_value('namingContexts'))[0];
> }
>  
> Kind regards
> *Waldemar Siebert
> 
> *T-Systems International GmbH
> Corporate Customers
> Telecommunications Services & Solutions (TSS)
> Technical Engineering (TSS TE) - Security & Production Engineering
> Dipl.-Ing. Waldemar Siebert
> Address: Nauheimer Str. 101, D-70372 Stuttgart
> Phone: +49 (711) 555 - 43989
> Fax: +49 (6151) 937 - 3129
> Mobile: +49 (151) 174 66 111
> E-mail: w.siebert at t-systems.com
> Internet: http:\\www.t-systems.com
>  
> 
> 
> 
> _______________________________________________
> radiator mailing list
> radiator at open.com.au
> http://www.open.com.au/mailman/listinfo/radiator


-- 
Heikki Vatiainen <hvn at open.com.au>

Radiator: the most portable, flexible and configurable RADIUS server
anywhere. SQL, proxy, DBM, files, LDAP, NIS+, password, NT, Emerald,
Platypus, Freeside, TACACS+, PAM, external, Active Directory, EAP, TLS,
TTLS, PEAP, TNC, WiMAX, RSA, Vasco, Yubikey, MOTP, HOTP, TOTP,
DIAMETER etc. Full source on Unix, Windows, MacOSX, Solaris, VMS,
NetWare etc.


More information about the radiator mailing list