diff options
Diffstat (limited to 'Bugzilla/Auth/Verify')
-rw-r--r-- | Bugzilla/Auth/Verify/DB.pm | 132 | ||||
-rw-r--r-- | Bugzilla/Auth/Verify/LDAP.pm | 193 |
2 files changed, 325 insertions, 0 deletions
diff --git a/Bugzilla/Auth/Verify/DB.pm b/Bugzilla/Auth/Verify/DB.pm new file mode 100644 index 000000000..4db34b5cf --- /dev/null +++ b/Bugzilla/Auth/Verify/DB.pm @@ -0,0 +1,132 @@ +# -*- 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> +# Erik Stambaugh <erik@dasbistro.com> + +package Bugzilla::Auth::Verify::DB; + +use strict; + +use Bugzilla::Config; +use Bugzilla::Constants; +use Bugzilla::Util; + +# can_edit is now a hash. + +my $can_edit = { + 'new' => 1, + 'userid' => 0, + 'login_name' => 1, + 'realname' => 1, +}; + +sub authenticate { + my ($class, $username, $passwd) = @_; + + return (AUTH_NODATA) unless defined $username && defined $passwd; + + # We're just testing against the db: any value is ok + trick_taint($username); + + my $userid = $class->get_id_from_username($username); + return (AUTH_LOGINFAILED) unless defined $userid; + + return (AUTH_LOGINFAILED, $userid) + unless $class->check_password($userid, $passwd); + + # The user's credentials are okay, so delete any outstanding + # password tokens they may have generated. + require Bugzilla::Token; + Bugzilla::Token::DeletePasswordTokens($userid, "user_logged_in"); + + # Account may have been disabled + my $disabledtext = $class->get_disabled($userid); + return (AUTH_DISABLED, $userid, $disabledtext) + if $disabledtext ne ''; + + return (AUTH_OK, $userid); +} + +sub get_id_from_username { + my ($class, $username) = @_; + my $dbh = Bugzilla->dbh; + my $sth = $dbh->prepare_cached("SELECT userid FROM profiles " . + "WHERE login_name=?"); + my ($userid) = $dbh->selectrow_array($sth, undef, $username); + return $userid; +} + +sub get_disabled { + my ($class, $userid) = @_; + my $dbh = Bugzilla->dbh; + my $sth = $dbh->prepare_cached("SELECT disabledtext FROM profiles " . + "WHERE userid=?"); + my ($text) = $dbh->selectrow_array($sth, undef, $userid); + return $text; +} + +sub check_password { + my ($class, $userid, $passwd) = @_; + my $dbh = Bugzilla->dbh; + my $sth = $dbh->prepare_cached("SELECT cryptpassword FROM profiles " . + "WHERE userid=?"); + my ($realcryptpwd) = $dbh->selectrow_array($sth, undef, $userid); + + # Get the salt from the user's crypted password. + my $salt = $realcryptpwd; + + # Using the salt, crypt the password the user entered. + my $enteredCryptedPassword = crypt($passwd, $salt); + + return $enteredCryptedPassword eq $realcryptpwd; +} + +sub change_password { + my ($class, $userid, $password) = @_; + my $dbh = Bugzilla->dbh; + my $cryptpassword = Crypt($password); + $dbh->do("UPDATE profiles SET cryptpassword = ? WHERE userid = ?", + undef, $cryptpassword, $userid); +} + +1; + +__END__ + +=head1 NAME + +Bugzilla::Auth::Verify::DB - database authentication for Bugzilla + +=head1 SUMMARY + +This is an L<authentication module|Bugzilla::Auth/"AUTHENTICATION"> for +Bugzilla, which logs the user in using the password stored in the C<profiles> +table. This is the most commonly used authentication module. + +=head1 SEE ALSO + +L<Bugzilla::Auth> diff --git a/Bugzilla/Auth/Verify/LDAP.pm b/Bugzilla/Auth/Verify/LDAP.pm new file mode 100644 index 000000000..737827ee0 --- /dev/null +++ b/Bugzilla/Auth/Verify/LDAP.pm @@ -0,0 +1,193 @@ +# -*- 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> +# Erik Stambaugh <erik@dasbistro.com> + +package Bugzilla::Auth::Verify::LDAP; + +use strict; + +use Bugzilla::Config; +use Bugzilla::Constants; + +use Net::LDAP; + +# can_edit is now a hash. + +my $can_edit = { + 'new' => 0, + 'userid' => 0, + 'login_name' => 0, + 'realname' => 0, +}; + +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->error }); + } + + # We've got our anonymous bind; let's look up this user. + $mesg = $LDAPconn->search( base => Param("LDAPBaseDN"), + scope => "sub", + filter => '(&(' . Param("LDAPuidattribute") . "=$username)" . Param("LDAPfilter") . ')', + 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)" . Param("LDAPfilter") . ')', + ); + 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); +} + +1; + +__END__ + +=head1 NAME + +Bugzilla::Auth::Verify::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> |