[rt-devel] Patch to lib/RT/User.pm to use LDAP Authentication. (for rt 2.0.15)

Marcelo Bartsch mbartsch at netglobalis.net
Thu Dec 12 13:01:41 EST 2002


Hello,
i was looking at the mailing list and couldn't find a patch
that just do autehntication, all do authentication plus 
information fetch from ldap, so i write my own.

This patch allow to autenticate users using Net::LDAP to
autenticate against ldap using normal auth (not external)

for user information i use the script from contrib called
rtimportldap.pl from Stanislav Sinyagin <ssinyagin_[at]_yahoo_[dot]_com>
so user information is pushed into RT from crontab every 5 minutes, and
authentication is performed online thanks to this patch. i hope it can
be from use to other people.

you musty add this variables to etc/config.pm inside the RT Package

$LDAPExternalAuth = 1;
$LdapServer="ldap.domian.com";
$LdapUser="CN=ldapuser,CN=Users,DC=domain,DC=com";
$LdapPass="ldapasswd";
$LdapBase="DC=domain,DC=com";
$LdapUidAttr="uid";
$LdapFilter="(|(memberOf=CN=WebRT,OU=ACLS,DC=domain,DC=com)(memberOf=CN=WebRT-admin,OU=ACLS,DC=domain,DC=com))";


please note, this is an ldap from Windows2000 Active Directory.
what i do to control access is:

create a new OU called ACLS, then i create groups called WebRT
,WebRT-admin and some other for authentication then i add the 
users to those groups, and using filter i can check if someone had
access to some areas or not, so the ldap schema is something like

dn: CN=Name LastName,OU=Support 1,OU=Main OU,DC=domain,DC=com
memberOf: CN=webrt-admin,OU=ACLS,DC=domain,DC=com
memberOf: CN=other-access-group,OU=ACLS,DC=domain,DC=com
accountExpires: 9223372036854775807
badPasswordTime: 126841869968308180
badPwdCount: 0
codePage: 0
cn: Name LastName
[more lines of AD ldap stuff]

so "memberOf" makes the trick, the only thing will not work (i mean
i had not tested so if didn't work, don't blame me) is that the user is
member of a group wich
is member of webrt for example)


the filter used for query ldap is:

(&(&(objectclass=user)(<LdapUidAttr>=<USERNAME>))<LdapFilter>)

i had't tested with an empty LdapFilter.

Please not i wrote this patch in some 2 hours, so bugs must
be there.

P.D.: is there any way to overwrite a built in function with an
external on, so i can write a module to replace IsPassword ?
P.D.2: i'm a new perl programmer so there must be bugs on the code
or line bad writen, this patch also has not been intensive tested.


-- 
   Marcelo Bartsch
mbartsch at netglobalis.net
  www.netglobalis.net

PGP Fingerprint : 
877E 3A56 F523 B44A 3260  8F83 8916 E158 6100 F721
-------------- next part --------------
--- /root/rt-2-0-15/lib/RT/User.pm	Wed Jul 10 14:36:27 2002
+++ lib/RT/User.pm	Thu Dec 12 14:57:38 2002
@@ -583,11 +583,60 @@
          ($self->__Value('Password') eq undef) )  {
         return(undef);
      }
-    if ($self->__Value('Password') eq crypt($value, $self->__Value('Password'))) {
-	return (1);
+    if (! $RT::LDAPExternalAuth)
+    {
+	    if ($self->__Value('Password') eq crypt($value, $self->__Value('Password'))) {
+		return (1);
+	    }
+	    else {
+		return (undef);
+	    }
     }
-    else {
-	return (undef);
+    else
+    {
+#Modification by Marcelo Bartsch <bartschm_cl at hotmail.com>
+        $RT::Logger->info("Using External Authentication\n");
+	use Net::LDAP::Util qw( ldap_error_name ldap_error_text) ;
+
+	my $ldap = Net::LDAP->new($RT::LdapServer, version=>3) or $RT::Logger->critical("GetExternalUserWithLDAP: " . "Cannot connect to LDAP'\n"), return 0;
+	
+	my $mesg = $ldap->bind($RT::LdapUser, password =>$RT::LdapPass );
+	if ($mesg->code != LDAP_SUCCESS) {
+	     $RT::Logger->critical("GetExternalUserWithLDAP: Cannot bind to LDAP:",
+				   $mesg->code, "\n");
+	     return 0;
+	}
+	
+	my $filter = "(&(&(objectclass=user)(" . $RT::LdapUidAttr . "=" . $self->Name ."))$RT::LdapFilter)";
+	$RT::Logger->debug("GetExternalUserWithLDAP: First search filter '$filter'\n");
+	$mesg = $ldap->search(base   => $RT::LdapBase, 
+			  filter => $filter,
+			  attrs  => ['dn']);
+	if (($mesg->code != LDAP_SUCCESS) or ($mesg->code != LDAP_PARTIAL_RESULTS))
+	{
+		$RT::Logger->debug("GetExternalUserWithLDAP: Could not search for $filter: ", 
+			      $mesg->code, "" , ldap_error_name($mesg->code) ,"\n");
+		return 0;
+	}
+	$RT::Logger->debug("GetExternalUserWithLDAP: First search produced ",
+     	$mesg->count, " results\n");
+	if (! $mesg->count)
+	{
+		$RT::Logger->info("AUTH FAILED: " . $self->Name . "\n");
+		return 0;
+	}
+	$RT::Logger->debug("LDAP DN: " . $mesg->first_entry->dn . " " . $value . "\n");
+	my $mesg2 = $ldap->bind($mesg->first_entry->dn, password =>$value );
+	if ($mesg2->code != LDAP_SUCCESS) {
+		$RT::Logger->critical("GetExternalUserWithLDAP: Cannot bind to LDAP:",
+			$mesg2->code, "\n");
+		return 0;
+	}
+	else
+	{
+		$RT::Logger->info("AUTH OK: " . $self->Name . " (" .$mesg->first_entry->dn . ")\n");
+		return 1;
+	}
     }
 }
 


More information about the Rt-devel mailing list