зеркало из https://github.com/mozilla/pjs.git
186 строки
6.5 KiB
Perl
186 строки
6.5 KiB
Perl
# -*- Mode: perl; indent-tabs-mode: nil -*-
|
|
#
|
|
# The contents of this file are subject to the Mozilla Public
|
|
# License Version 1.1 (the "License"); you may not use this file
|
|
# except in compliance with the License. You may obtain a copy of
|
|
# the License at http://www.mozilla.org/MPL/
|
|
#
|
|
# Software distributed under the License is distributed on an "AS
|
|
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
# implied. See the License for the specific language governing
|
|
# rights and limitations under the License.
|
|
#
|
|
# The Original Code is the Bugzilla Bug Tracking System.
|
|
#
|
|
# The Initial Developer of the Original Code is Netscape Communications
|
|
# Corporation. Portions created by Netscape are
|
|
# Copyright (C) 1998 Netscape Communications Corporation. All
|
|
# Rights Reserved.
|
|
#
|
|
# Contributor(s): Terry Weissman <terry@mozilla.org>
|
|
# Dan Mosedale <dmose@mozilla.org>
|
|
# Joe Robins <jmrobins@tgix.com>
|
|
# Dave Miller <justdave@syndicomm.com>
|
|
# Christopher Aillon <christopher@aillon.com>
|
|
# Gervase Markham <gerv@gerv.net>
|
|
# Christian Reis <kiko@async.com.br>
|
|
# Bradley Baetz <bbaetz@acm.org>
|
|
|
|
package Bugzilla::Auth::LDAP;
|
|
|
|
use strict;
|
|
|
|
use Bugzilla::Config;
|
|
use Bugzilla::Constants;
|
|
|
|
use Net::LDAP;
|
|
|
|
sub authenticate {
|
|
my ($class, $username, $passwd) = @_;
|
|
|
|
# If no password was provided, then fail the authentication.
|
|
# While it may be valid to not have an LDAP password, when you
|
|
# bind without a password (regardless of the binddn value), you
|
|
# will get an anonymous bind. I do not know of a way to determine
|
|
# whether a bind is anonymous or not without making changes to the
|
|
# LDAP access control settings
|
|
return (AUTH_NODATA) unless $username && $passwd;
|
|
|
|
# We need to bind anonymously to the LDAP server. This is
|
|
# because we need to get the Distinguished Name of the user trying
|
|
# to log in. Some servers (such as iPlanet) allow you to have unique
|
|
# uids spread out over a subtree of an area (such as "People"), so
|
|
# just appending the Base DN to the uid isn't sufficient to get the
|
|
# user's DN. For servers which don't work this way, there will still
|
|
# be no harm done.
|
|
my $LDAPserver = Param("LDAPserver");
|
|
if ($LDAPserver eq "") {
|
|
return (AUTH_ERROR, undef, "server_not_defined");
|
|
}
|
|
|
|
my $LDAPport = "389"; # default LDAP port
|
|
if($LDAPserver =~ /:/) {
|
|
($LDAPserver, $LDAPport) = split(":",$LDAPserver);
|
|
}
|
|
my $LDAPconn = Net::LDAP->new($LDAPserver, port => $LDAPport, version => 3);
|
|
if(!$LDAPconn) {
|
|
return (AUTH_ERROR, undef, "connect_failed");
|
|
}
|
|
|
|
my $mesg;
|
|
if (Param("LDAPbinddn")) {
|
|
my ($LDAPbinddn,$LDAPbindpass) = split(":",Param("LDAPbinddn"));
|
|
$mesg = $LDAPconn->bind($LDAPbinddn, password => $LDAPbindpass);
|
|
}
|
|
else {
|
|
$mesg = $LDAPconn->bind();
|
|
}
|
|
if($mesg->code) {
|
|
return (AUTH_ERROR, undef,
|
|
"connect_failed",
|
|
{ errstr => $mesg->err });
|
|
}
|
|
|
|
# We've got our anonymous bind; let's look up this user.
|
|
$mesg = $LDAPconn->search( base => Param("LDAPBaseDN"),
|
|
scope => "sub",
|
|
filter => Param("LDAPuidattribute") . "=$username",
|
|
attrs => ['dn'],
|
|
);
|
|
return (AUTH_LOGINFAILED, undef, "lookup_failure")
|
|
unless $mesg->count;
|
|
|
|
# Now we get the DN from this search.
|
|
my $userDN = $mesg->shift_entry->dn;
|
|
|
|
# Now we attempt to bind as the specified user.
|
|
$mesg = $LDAPconn->bind( $userDN, password => $passwd);
|
|
|
|
return (AUTH_LOGINFAILED) if $mesg->code;
|
|
|
|
# And now we're going to repeat the search, so that we can get the
|
|
# mail attribute for this user.
|
|
$mesg = $LDAPconn->search( base => Param("LDAPBaseDN"),
|
|
scope => "sub",
|
|
filter => Param("LDAPuidattribute") . "=$username",
|
|
);
|
|
my $user_entry = $mesg->shift_entry if !$mesg->code && $mesg->count;
|
|
if(!$user_entry || !$user_entry->exists(Param("LDAPmailattribute"))) {
|
|
return (AUTH_ERROR, undef,
|
|
"cannot_retreive_attr",
|
|
{ attr => Param("LDAPmailattribute") });
|
|
}
|
|
|
|
# get the mail attribute
|
|
$username = $user_entry->get_value(Param("LDAPmailattribute"));
|
|
# OK, so now we know that the user is valid. Lets try finding them in the
|
|
# Bugzilla database
|
|
|
|
# XXX - should this part be made more generic, and placed in
|
|
# Bugzilla::Auth? Lots of login mechanisms may have to do this, although
|
|
# until we actually get some more, its hard to know - BB
|
|
|
|
my $dbh = Bugzilla->dbh;
|
|
my $sth = $dbh->prepare_cached("SELECT userid, disabledtext " .
|
|
"FROM profiles " .
|
|
"WHERE login_name=?");
|
|
my ($userid, $disabledtext) =
|
|
$dbh->selectrow_array($sth,
|
|
undef,
|
|
$username);
|
|
|
|
# If the user doesn't exist, then they need to be added
|
|
unless ($userid) {
|
|
# We'll want the user's name for this.
|
|
my $userRealName = $user_entry->get_value("displayName");
|
|
if($userRealName eq "") {
|
|
$userRealName = $user_entry->get_value("cn");
|
|
}
|
|
&::InsertNewUser($username, $userRealName);
|
|
|
|
($userid, $disabledtext) = $dbh->selectrow_array($sth,
|
|
undef,
|
|
$username);
|
|
return (AUTH_ERROR, $userid, "no_userid")
|
|
unless $userid;
|
|
}
|
|
|
|
# we're done, so disconnect
|
|
$LDAPconn->unbind;
|
|
|
|
# Test for disabled account
|
|
return (AUTH_DISABLED, $userid, $disabledtext)
|
|
if $disabledtext ne '';
|
|
|
|
# If we get to here, then the user is allowed to login, so we're done!
|
|
return (AUTH_OK, $userid);
|
|
}
|
|
|
|
sub can_edit { return 0; }
|
|
|
|
1;
|
|
|
|
__END__
|
|
|
|
=head1 NAME
|
|
|
|
Bugzilla::Auth::LDAP - LDAP based authentication for Bugzilla
|
|
|
|
This is an L<authentication module|Bugzilla::Auth/"AUTHENTICATION"> for
|
|
Bugzilla, which logs the user in using an LDAP directory.
|
|
|
|
=head1 DISCLAIMER
|
|
|
|
B<This module is experimental>. It is poorly documented, and not very flexible.
|
|
Search L<http://bugzilla.mozilla.org/> for a list of known LDAP bugs.
|
|
|
|
None of the core Bugzilla developers, nor any of the large installations, use
|
|
this module, and so it has received less testing. (In fact, this iteration
|
|
hasn't been tested at all)
|
|
|
|
Patches are accepted.
|
|
|
|
=head1 SEE ALSO
|
|
|
|
L<Bugzilla::Auth>
|