summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcyeh%bluemartini.com <>2000-09-16 03:35:16 +0200
committercyeh%bluemartini.com <>2000-09-16 03:35:16 +0200
commit391664703db43356450e6e471e30f4053a2e62a2 (patch)
treeff6fea075afa01e5d49f464288c36d9b9fdbed13
parentc89c74e34e758d9eb7050f416e788eb82e71691a (diff)
downloadbugzilla-391664703db43356450e6e471e30f4053a2e62a2.tar.gz
bugzilla-391664703db43356450e6e471e30f4053a2e62a2.tar.xz
fixes for 51184, 51185, 51186: allow for ldap authentication. patches
by jmrobins@tgix.com (Joe Robins). LDAP sections haven't been tested yet, but the code is arranged such that it shouldn't disturb existing user authentication system.
-rw-r--r--CGI.pl250
-rwxr-xr-xcreateaccount.cgi9
-rw-r--r--defparams.pl30
-rwxr-xr-xeditusers.cgi31
4 files changed, 261 insertions, 59 deletions
diff --git a/CGI.pl b/CGI.pl
index 4b85caec6..21f5c8c77 100644
--- a/CGI.pl
+++ b/CGI.pl
@@ -19,6 +19,7 @@
#
# Contributor(s): Terry Weissman <terry@mozilla.org>
# Dan Mosedale <dmose@mozilla.org>
+# Joe Robins <jmrobins@tgix.com>
# Contains some global routines used throughout the CGI scripts of Bugzilla.
@@ -27,6 +28,9 @@ use strict;
# use Carp; # for confess
# Shut up misguided -w warnings about "used only once". For some reason,
# "use vars" chokes on me when I try it here.
+# We want to check for the existence of the LDAP modules here.
+eval "use Mozilla::LDAP::Conn";
+my $have_ldap = $@ ? 0 : 1;
sub CGI_pl_sillyness {
my $zz;
@@ -623,60 +627,179 @@ sub confirm_login {
# print "Content-type: text/plain\n\n";
ConnectToDatabase();
+ # I'm going to reorganize some of this stuff a bit. Since we're adding
+ # a second possible validation method (LDAP), we need to move some of this
+ # to a later section. -Joe Robins, 8/3/00
+ my $enteredlogin = "";
+ my $realcryptpwd = "";
if (defined $::FORM{"Bugzilla_login"} &&
defined $::FORM{"Bugzilla_password"}) {
- my $enteredlogin = $::FORM{"Bugzilla_login"};
- my $enteredpwd = $::FORM{"Bugzilla_password"};
- CheckEmailSyntax($enteredlogin);
-
- my $realcryptpwd = PasswordForLogin($::FORM{"Bugzilla_login"});
-
- if (defined $::FORM{"PleaseMailAPassword"}) {
- my $realpwd;
- if ($realcryptpwd eq "") {
- $realpwd = InsertNewUser($enteredlogin, "");
- } else {
- SendSQL("select password from profiles where login_name = " .
- SqlQuote($enteredlogin));
- $realpwd = FetchOneColumn();
- }
- print "Content-type: text/html\n\n";
- PutHeader("Password has been emailed");
- MailPassword($enteredlogin, $realpwd);
- PutFooter();
- exit;
- }
-
- SendSQL("SELECT encrypt(" . SqlQuote($enteredpwd) . ", " .
- SqlQuote(substr($realcryptpwd, 0, 2)) . ")");
- my $enteredcryptpwd = FetchOneColumn();
-
- if ($realcryptpwd eq "" || $enteredcryptpwd ne $realcryptpwd) {
- print "Content-type: text/html\n\n";
- PutHeader("Login failed");
- print "The username or password you entered is not valid.\n";
- print "Please click <b>Back</b> and try again.\n";
- PutFooter();
- exit;
- }
- $::COOKIE{"Bugzilla_login"} = $enteredlogin;
- if (!defined $ENV{'REMOTE_HOST'}) {
- $ENV{'REMOTE_HOST'} = $ENV{'REMOTE_ADDR'};
- }
- SendSQL("insert into logincookies (userid,cryptpassword,hostname) values (@{[DBNameToIdAndCheck($enteredlogin)]}, @{[SqlQuote($realcryptpwd)]}, @{[SqlQuote($ENV{'REMOTE_HOST'})]})");
- SendSQL("select LAST_INSERT_ID()");
- my $logincookie = FetchOneColumn();
-
- $::COOKIE{"Bugzilla_logincookie"} = $logincookie;
- print "Set-Cookie: Bugzilla_login=$enteredlogin ; path=/; expires=Sun, 30-Jun-2029 00:00:00 GMT\n";
- print "Set-Cookie: Bugzilla_logincookie=$logincookie ; path=/; expires=Sun, 30-Jun-2029 00:00:00 GMT\n";
-
- # This next one just cleans out any old bugzilla passwords that may
- # be sitting around in the cookie files, from the bad old days when
- # we actually stored the password there.
- print "Set-Cookie: Bugzilla_password= ; path=/; expires=Sun, 30-Jun-80 00:00:00 GMT\n";
-
+ $enteredlogin = $::FORM{"Bugzilla_login"};
+ my $enteredpwd = $::FORM{"Bugzilla_password"};
+ CheckEmailSyntax($enteredlogin);
+
+ $realcryptpwd = PasswordForLogin($::FORM{"Bugzilla_login"});
+
+ if (defined $::FORM{"PleaseMailAPassword"}) {
+ my $realpwd;
+ if ($realcryptpwd eq "") {
+ $realpwd = InsertNewUser($enteredlogin, "");
+ } else {
+ SendSQL("select password from profiles where login_name = " .
+ SqlQuote($enteredlogin));
+ $realpwd = FetchOneColumn();
+ }
+ print "Content-type: text/html\n\n";
+ PutHeader("Password has been emailed");
+ MailPassword($enteredlogin, $realpwd);
+ PutFooter();
+ exit;
+ }
+
+ SendSQL("SELECT encrypt(" . SqlQuote($enteredpwd) . ", " .
+ SqlQuote(substr($realcryptpwd, 0, 2)) . ")");
+ my $enteredcryptpwd = FetchOneColumn();
+
+ if ($realcryptpwd eq "" || $enteredcryptpwd ne $realcryptpwd) {
+ print "Content-type: text/html\n\n";
+ PutHeader("Login failed");
+ print "The username or password you entered is not valid.\n";
+ print "Please click <b>Back</b> and try again.\n";
+ PutFooter();
+ exit;
+ }
+ } elsif (Param("useLDAP") &&
+ defined $::FORM{"LDAP_login"} &&
+ defined $::FORM{"LDAP_password"}) {
+ # If we're using LDAP for login, we've got an entirely different
+ # set of things to check.
+ # First, if we don't have the LDAP modules available to us, we can't
+ # do this.
+ if(!$have_ldap) {
+ print "Content-type: text/html\n\n";
+ PutHeader("LDAP not enabled");
+ print "The necessary modules for LDAP login are not installed on ";
+ print "this machine. Please send mail to ".Param("maintainer");
+ print " and notify him of this problem.\n";
+ PutFooter();
+ exit;
+ }
+
+ # Next, 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 "") {
+ print "Content-type: text/html\n\n";
+ PutHeader("LDAP server not defined");
+ print "The LDAP server for authentication has not been defined. ";
+ print "Please contact ".Param("maintainer")." ";
+ print "and notify him of this problem.\n";
+ PutFooter();
+ exit;
+ }
+
+ my $LDAPport = "389"; #default LDAP port
+ if($LDAPserver =~ /:/) {
+ ($LDAPserver, $LDAPport) = split(":",$LDAPserver);
+ }
+ my $LDAPconn = new Mozilla::LDAP::Conn($LDAPserver,$LDAPport);
+ if(!$LDAPconn) {
+ print "Content-type: text/html\n\n";
+ PutHeader("Unable to connect to LDAP server");
+ print "I was unable to connect to the LDAP server for user ";
+ print "authentication. Please contact ".Param("maintainer");
+ print " and notify him of this problem.\n";
+ PutFooter();
+ exit;
+ }
+
+ # We've got our anonymous bind; let's look up this user.
+ my $dnEntry = $LDAPconn->search(Param("LDAPBaseDN"),"subtree","uid=".$::FORM{"LDAP_login"});
+ if(!$dnEntry) {
+ print "Content-type: text/html\n\n";
+ PutHeader("Login Failed");
+ print "The username or password you entered is not valid.\n";
+ print "Please click <b>Back</b> and try again.\n";
+ PutFooter();
+ exit;
+ }
+
+ # Now we get the DN from this search. Once we've got that, we're
+ # done with the anonymous bind, so we close it.
+ my $userDN = $dnEntry->getDN;
+ $LDAPconn->close;
+
+ # Now we attempt to bind as the specified user.
+ $LDAPconn = new Mozilla::LDAP::Conn($LDAPserver,$LDAPport,$userDN,$::FORM{"LDAP_password"});
+ if(!$LDAPconn) {
+ print "Content-type: text/html\n\n";
+ PutHeader("Login Failed");
+ print "The username or password you entered is not valid.\n";
+ print "Please click <b>Back</b> and try again.\n";
+ PutFooter();
+ exit;
+ }
+
+ # And now we're going to repeat the search, so that we can get the
+ # mail attribute for this user.
+ my $userEntry = $LDAPconn->search(Param("LDAPBaseDN"),"subtree","uid=".$::FORM{"LDAP_login"});
+ if(!$userEntry->exists(Param("LDAPmailattribute"))) {
+ print "Content-type: text/html\n\n";
+ PutHeader("LDAP authentication error");
+ print "I was unable to retrieve the ".Param("LDAPmailattribute");
+ print " attribute from the LDAP server. Please contact ";
+ print Param("maintainer")." and notify him of this error.\n";
+ PutFooter();
+ exit;
+ }
+
+ # Mozilla::LDAP::Entry->getValues returns an array for the attribute
+ # requested, even if there's only one entry.
+ $enteredlogin = ($userEntry->getValues(Param("LDAPmailattribute")))[0];
+
+ # We're going to need the cryptpwd for this user from the database
+ # so that we can set the cookie below, even though we're not going
+ # to use it for authentication.
+ $realcryptpwd = PasswordForLogin($enteredlogin);
+
+ # If we don't get a result, then we've got a user who isn't in
+ # Bugzilla's database yet, so we've got to add them.
+ if($realcryptpwd eq "") {
+ # We'll want the user's name for this.
+ my $userRealName = ($userEntry->getValues("displayName"))[0];
+ if($userRealName eq "") {
+ $userRealName = ($userEntry->getValues("cn"))[0];
+ }
+ InsertNewUser($enteredlogin, $userRealName);
+ $realcryptpwd = PasswordForLogin($enteredlogin);
+ }
+ } # end LDAP authentication
+
+ # And now, if we've logged in via either method, then we need to set
+ # the cookies.
+ if($enteredlogin ne "") {
+ $::COOKIE{"Bugzilla_login"} = $enteredlogin;
+ if (!defined $ENV{'REMOTE_HOST'}) {
+ $ENV{'REMOTE_HOST'} = $ENV{'REMOTE_ADDR'};
+ }
+ SendSQL("insert into logincookies (userid,cryptpassword,hostname) values (@{[DBNameToIdAndCheck($enteredlogin)]}, @{[SqlQuote($realcryptpwd)]}, @{[SqlQuote($ENV{'REMOTE_HOST'})]})");
+ SendSQL("select LAST_INSERT_ID()");
+ my $logincookie = FetchOneColumn();
+
+ $::COOKIE{"Bugzilla_logincookie"} = $logincookie;
+ print "Set-Cookie: Bugzilla_login=$enteredlogin ; path=/; expires=Sun, 30-Jun-2029 00:00:00 GMT\n";
+ print "Set-Cookie: Bugzilla_logincookie=$logincookie ; path=/; expires=Sun, 30-Jun-2029 00:00:00 GMT\n";
+
+ # This next one just cleans out any old bugzilla passwords that may
+ # be sitting around in the cookie files, from the bad old days when
+ # we actually stored the password there.
+ print "Set-Cookie: Bugzilla_password= ; path=/; expires=Sun, 30-Jun-80 00:00:00 GMT\n";
}
@@ -701,7 +824,11 @@ Content-type: text/html
}
print "Content-type: text/html\n\n";
PutHeader("Login", undef, undef, undef, 1);
- print "I need a legitimate e-mail address and password to continue.\n";
+ if(Param("useLDAP")) {
+ print "I need a legitimate LDAP username and password to continue.\n";
+ } else {
+ print "I need a legitimate e-mail address and password to continue.\n";
+ }
if (!defined $nexturl || $nexturl eq "") {
# Sets nexturl to be argv0, stripping everything up to and
# including the last slash.
@@ -715,13 +842,25 @@ Content-type: text/html
print "
<FORM action=$nexturl method=$method>
<table>
+<tr>";
+ if(Param("useLDAP")) {
+ print "
+<td align=right><b>Username:</b></td>
+<td><input size=10 name=LDAP_login></td>
+</tr>
<tr>
+<td align=right><b>Password:</b></td>
+<td><input type=password size=10 name=LDAP_password></td>";
+ } else {
+ print "
<td align=right><b>E-mail address:</b></td>
<td><input size=35 name=Bugzilla_login></td>
</tr>
<tr>
<td align=right><b>Password:</b></td>
-<td><input type=password size=35 name=Bugzilla_password></td>
+<td><input type=password size=35 name=Bugzilla_password></td>";
+ }
+ print "
</tr>
</table>
";
@@ -733,11 +872,16 @@ Content-type: text/html
}
print "
<input type=submit value=Login name=GoAheadAndLogIn><hr>
+";
+ # If we're using LDAP, we can't request that a password be mailed...
+ unless(Param("useLDAP")) {
+ print "
If you don't have a password, or have forgotten it, then please fill in the
e-mail address above and click
here:<input type=submit value=\"E-mail me a password\"
name=PleaseMailAPassword>
</form>\n";
+ }
# This seems like as good as time as any to get rid of old
# crufty junk in the logincookies table. Get rid of any entry
diff --git a/createaccount.cgi b/createaccount.cgi
index 8a905c465..2ff2c0b1f 100755
--- a/createaccount.cgi
+++ b/createaccount.cgi
@@ -20,6 +20,7 @@
#
# Contributor(s): Terry Weissman <terry@mozilla.org>
# David Gardiner <david.gardiner@unisa.edu.au>
+# Joe Robins <jmrobins@tgix.com>
use diagnostics;
use strict;
@@ -42,6 +43,14 @@ Content-type: text/html
";
+# If we're using LDAP for login, then we can't create a new account here.
+if(Param('useLDAP')) {
+ PutHeader("Can't create LDAP accounts");
+ print "This site is using LDAP for authentication. Please contact an LDAP ";
+ print "administrator to get a new account created.\n";
+ PutFooter();
+ exit;
+}
my $login = $::FORM{'login'};
my $realname = $::FORM{'realname'};
diff --git a/defparams.pl b/defparams.pl
index 695bd2c9c..3a767f84f 100644
--- a/defparams.pl
+++ b/defparams.pl
@@ -203,6 +203,36 @@ sub check_despotbaseurl {
}
+# Adding in four parameters for LDAP authentication. -JMR, 7/28/00
+DefParam("useLDAP",
+ "Turn this on to use an LDAP directory for user authentication ".
+ "instead of the Bugzilla database. (User profiles will still be ".
+ "stored in the database, and will match against the LDAP user by ".
+ "email address.)",
+ "b",
+ 0);
+
+
+DefParam("LDAPserver",
+ "The name (and optionally port) of your LDAP server. (e.g. ldap.company.com, or ldap.company.com:portnum)",
+ "t",
+ "");
+
+
+DefParam("LDAPBaseDN",
+ "The BaseDN for authenticating users against. (e.g. \"ou=People,o=Company\")",
+ "t",
+ "");
+
+
+DefParam("LDAPmailattribute",
+ "The name of the attribute of a user in your directory that ".
+ "contains the email address.",
+ "t",
+ "mail");
+#End of LDAP parameters
+
+
DefParam("headerhtml",
"Additional HTML to add to the HEAD area of documents, eg. links to stylesheets.",
"l",
diff --git a/editusers.cgi b/editusers.cgi
index 73ee8f131..3af80a86a 100755
--- a/editusers.cgi
+++ b/editusers.cgi
@@ -20,6 +20,7 @@
#
# Contributor(s): Holger Schurig <holgerschurig@nikocity.de>
# Dave Miller <dave@intrec.com>
+# Joe Robins <jmrobins@tgix.com>
#
# Direct any questions on this source code to
#
@@ -109,8 +110,11 @@ sub EmitFormElements ($$$$$$$)
if ($editall) {
print "</TR><TR>\n";
print " <TH ALIGN=\"right\">Password:</TH>\n";
- print " <TD><INPUT TYPE=\"PASSWORD\" SIZE=16 MAXLENGTH=16 NAME=\"password\" VALUE=\"$password\"></TD>\n";
-
+ if(Param('useLDAP')) {
+ print " <TD><FONT COLOR=RED>This site is using LDAP for authentication!</FONT></TD>\n";
+ } else {
+ print " <TD><INPUT TYPE=\"PASSWORD\" SIZE=16 MAXLENGTH=16 NAME=\"password\" VALUE=\"$password\"></TD>\n";
+ }
print "</TR><TR>\n";
print " <TH ALIGN=\"right\">Email notification:</TH>\n";
print qq{<TD><SELECT NAME="emailnotification">};
@@ -341,7 +345,7 @@ if ($action eq 'list') {
}
print "</TR>";
}
- if ($editall) {
+ if ($editall && !Param('useLDAP')) {
print "<TR>\n";
my $span = $candelete ? 3 : 2;
print qq{
@@ -375,6 +379,13 @@ if ($action eq 'add') {
exit;
}
+ if(Param('useLDAP')) {
+ print "This site is using LDAP for authentication. To add a new user, ";
+ print "please contact the LDAP administrators.";
+ PutTrailer();
+ exit;
+ }
+
print "<FORM METHOD=POST ACTION=editusers.cgi>\n";
print "<TABLE BORDER=0 CELLPADDING=4 CELLSPACING=0><TR>\n";
@@ -406,6 +417,13 @@ if ($action eq 'new') {
exit;
}
+ if(Param('useLDAP')) {
+ print "This site is using LDAP for authentication. To add a new user, ";
+ print "please contact the LDAP administrators.";
+ PutTrailer();
+ exit;
+ }
+
# Cleanups and valididy checks
my $realname = trim($::FORM{realname} || '');
my $password = trim($::FORM{password} || '');
@@ -667,7 +685,7 @@ if ($action eq 'edit') {
print "</TR></TABLE>\n";
print "<INPUT TYPE=HIDDEN NAME=\"userold\" VALUE=\"$user\">\n";
- if ($editall) {
+ if ($editall && !Param('useLDAP')) {
print "<INPUT TYPE=HIDDEN NAME=\"passwordold\" VALUE=\"$password\">\n";
}
print "<INPUT TYPE=HIDDEN NAME=\"realnameold\" VALUE=\"$realname\">\n";
@@ -764,13 +782,14 @@ if ($action eq 'update') {
WHERE login_name=" . SqlQuote($userold));
print "Updated email notification.<BR>\n";
}
-
- if ($editall && $password ne $passwordold) {
+ if(!Param('useLDAP')) {
+ if ($editall && $password ne $passwordold) {
my $q = SqlQuote($password);
SendSQL("UPDATE profiles
SET password= $q, cryptpassword = ENCRYPT($q)
WHERE login_name=" . SqlQuote($userold));
print "Updated password.<BR>\n";
+ }
}
if ($editall && $realname ne $realnameold) {
SendSQL("UPDATE profiles