From d0fb0184e8d542f06ad350ab7142c8a80dd431c8 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Sat, 18 Oct 2014 23:53:27 -0700 Subject: [PATCH] client/manager/server: finish LDAP support - get_project_config.php: if project supports LDAP, advertise this to the client. - Manager: if project supports LDAP, say "Email address or LDAP ID" in Attach Project wizard, and don't do email address validation. - lookup_account GUI RPC (client side): if passing an LDAP ID, don't lowercase it, and don't hash passwd - lookup_account GUI RPC (server side): if passing an LDAP ID, pass appropriate URL args to Web RPC - lookup_account Web RPC: in LDAP case, pass "ldap_auth" arg, and pass "ldap_uid" and "passwd". Handle these appropriately. --- client/acct_setup.cpp | 31 +++++++++--- clientgui/AccountInfoPage.cpp | 20 +++++--- html/user/get_project_config.php | 4 ++ html/user/lookup_account.php | 87 ++++++++++++++++++++------------ lib/gui_rpc_client.h | 4 +- lib/gui_rpc_client_ops.cpp | 11 +++- py/Boinc/boinc_db.py | 6 +++ 7 files changed, 113 insertions(+), 50 deletions(-) diff --git a/client/acct_setup.cpp b/client/acct_setup.cpp index 5faaff4c05..f3764c10d9 100644 --- a/client/acct_setup.cpp +++ b/client/acct_setup.cpp @@ -132,16 +132,31 @@ int LOOKUP_ACCOUNT_OP::do_rpc(ACCOUNT_IN& ai) { url = ai.url; canonicalize_master_url(url); + url += "lookup_account.php"; - url += "lookup_account.php?email_addr="; - parameter = ai.email_addr; - escape_url(parameter); - url += parameter; + if (strchr(ai.email_addr.c_str(), '@')) { + url += "?email_addr="; + parameter = ai.email_addr; + escape_url(parameter); + url += parameter; - url += "&passwd_hash="; - parameter = ai.passwd_hash; - escape_url(parameter); - url += parameter; + url += "&passwd_hash="; + parameter = ai.passwd_hash; + escape_url(parameter); + url += parameter; + } else { + // LDAP case + // + url += "?ldap_auth=1&ldap_uid="; + parameter = ai.email_addr; + escape_url(parameter); + url += parameter; + + url += "&passwd="; + parameter = ai.passwd_hash; + escape_url(parameter); + url += parameter; + } retval = gui_http->do_rpc( this, url.c_str(), LOOKUP_ACCOUNT_FILENAME, false diff --git a/clientgui/AccountInfoPage.cpp b/clientgui/AccountInfoPage.cpp index 1a0ca514f2..39e2eceaf5 100644 --- a/clientgui/AccountInfoPage.cpp +++ b/clientgui/AccountInfoPage.cpp @@ -492,9 +492,11 @@ void CAccountInfoPage::OnPageChanged( wxWizardExEvent& event ) { } } - m_pAccountEmailAddressCtrl->SetValidator( - CValidateEmailAddress(&m_strAccountEmailAddress) - ); + if (!pc.ldap_auth) { + m_pAccountEmailAddressCtrl->SetValidator( + CValidateEmailAddress(&m_strAccountEmailAddress) + ); + } m_pAccountUsernameCtrl->SetValidator( wxTextValidator(wxFILTER_NONE, &m_strAccountUsername) ); @@ -504,9 +506,15 @@ void CAccountInfoPage::OnPageChanged( wxWizardExEvent& event ) { m_pAccountUsernameStaticCtrl->Hide(); m_pAccountUsernameCtrl->Hide(); - m_pAccountEmailAddressStaticCtrl->SetLabel( - _("&Email address:") - ); + if (pc.ldap_auth) { + m_pAccountEmailAddressStaticCtrl->SetLabel( + _("&Email address or LDAP ID:") + ); + } else { + m_pAccountEmailAddressStaticCtrl->SetLabel( + _("&Email address:") + ); + } m_pAccountEmailAddressCtrl->SetValue(m_strAccountEmailAddress); } diff --git a/html/user/get_project_config.php b/html/user/get_project_config.php index 793bf58e78..0dbfc3cc5a 100644 --- a/html/user/get_project_config.php +++ b/html/user/get_project_config.php @@ -107,6 +107,10 @@ if (file_exists($tou_file)) { } } +if (LDAP_HOST) { + echo "\n"; +} + echo ""; ?> diff --git a/html/user/lookup_account.php b/html/user/lookup_account.php index f86a83a380..f35847d6c9 100644 --- a/html/user/lookup_account.php +++ b/html/user/lookup_account.php @@ -22,45 +22,66 @@ require_once("../inc/boinc_db.inc"); require_once("../inc/util.inc"); require_once("../inc/email.inc"); require_once("../inc/xml.inc"); +require_once("../inc/ldap.inc"); xml_header(); $retval = db_init_xml(); if ($retval) xml_error($retval); -$email_addr = get_str("email_addr"); -$passwd_hash = get_str("passwd_hash", true); +$ldap_auth = get_str("ldap_auth", true); -$email_addr = BoincDb::escape_string($email_addr); -$user = BoincUser::lookup("email_addr='$email_addr'"); -if (!$user) { - xml_error(ERR_DB_NOT_FOUND); -} - -if (!$passwd_hash) { - echo " - - -"; - exit(); -} - -$auth_hash = md5($user->authenticator.$user->email_addr); - -// if no password set, set password to account key -// -if (!strlen($user->passwd_hash)) { - $user->passwd_hash = $auth_hash; - $user->update("passwd_hash='$user->passwd_hash'"); -} - -// if the given password hash matches (auth+email), accept it -// -if ($user->passwd_hash == $passwd_hash || $auth_hash == $passwd_hash) { - echo "\n"; - echo "$user->authenticator\n"; - echo "\n"; +if (LDAP_HOST && $ldap_auth) { + // LDAP case. + // + $ldap_uid = get_str("ldap_uid"); + $passwd = get_str("passwd"); + list ($ldap_user, $error_msg) = ldap_auth($ldap_uid, $passwd); + if ($error_msg) { + xml_error(ERR_BAD_USER_NAME, $error_msg); + } + $x = ldap_email_string($ldap_uid); + $user = BoincUser::lookup_email_addr($x); + if (!$user) { + $user = make_user_ldap($x, $ldap_user->name); + if (!$user) { + xml_error(-1, "user record creation failed"); + } + } } else { - xml_error(ERR_BAD_PASSWD); -} + // normal (non-LDAP) case + $email_addr = get_str("email_addr"); + $passwd_hash = get_str("passwd_hash", true); + $email_addr = BoincDb::escape_string($email_addr); + $user = BoincUser::lookup("email_addr='$email_addr'"); + if (!$user) { + xml_error(ERR_DB_NOT_FOUND); + } + + if (!$passwd_hash) { + echo "\n"; + echo " \n"; + echo "\n"; + exit(); + } + + $auth_hash = md5($user->authenticator.$user->email_addr); + + // if no password set, set password to account key + // + if (!strlen($user->passwd_hash)) { + $user->passwd_hash = $auth_hash; + $user->update("passwd_hash='$user->passwd_hash'"); + } + + // if the given password hash matches (auth+email), accept it + // + if ($user->passwd_hash == $passwd_hash || $auth_hash == $passwd_hash) { + echo "\n"; + echo "$user->authenticator\n"; + echo "\n"; + } else { + xml_error(ERR_BAD_PASSWD); + } +} ?> diff --git a/lib/gui_rpc_client.h b/lib/gui_rpc_client.h index 1ac988cf98..e9c11b13f8 100644 --- a/lib/gui_rpc_client.h +++ b/lib/gui_rpc_client.h @@ -559,6 +559,8 @@ struct PROJECT_CONFIG { // before allowing attachment to continue. std::vector platforms; // platforms supported by project, or empty + bool ldap_auth; + // project supports LDAP authentication PROJECT_CONFIG(); ~PROJECT_CONFIG(); @@ -572,7 +574,7 @@ struct ACCOUNT_IN { std::string url; // URL prefix for web RPCs std::string email_addr; - // the account identifier (email address or user name) + // the account identifier (email address, user name, or LDAP uid) std::string user_name; std::string passwd; std::string team_name; diff --git a/lib/gui_rpc_client_ops.cpp b/lib/gui_rpc_client_ops.cpp index 95288304cd..63b8c82b68 100644 --- a/lib/gui_rpc_client_ops.cpp +++ b/lib/gui_rpc_client_ops.cpp @@ -2303,9 +2303,16 @@ int RPC_CLIENT::lookup_account(ACCOUNT_IN& ai) { SET_LOCALE sl; char buf[1024]; RPC rpc(this); + string passwd_hash; - downcase_string(ai.email_addr); - string passwd_hash = get_passwd_hash(ai.passwd, ai.email_addr); + if (strchr(ai.email_addr.c_str(), '@')) { + downcase_string(ai.email_addr); + passwd_hash = get_passwd_hash(ai.passwd, ai.email_addr); + } else { + // LDAP case + // + passwd_hash = ai.passwd; + } snprintf(buf, sizeof(buf), "\n" " %s\n" diff --git a/py/Boinc/boinc_db.py b/py/Boinc/boinc_db.py index a49734657d..0d201f4932 100644 --- a/py/Boinc/boinc_db.py +++ b/py/Boinc/boinc_db.py @@ -77,6 +77,12 @@ MODE_BLANKSCREEN = 4 MODE_REREAD_PREFS = 5 MODE_QUIT = 6 NGRAPHICS_MSGS = 7 +PROCESS_PRIORITY_UNSPECIFIED = 0 +PROCESS_PRIORITY_LOWEST = 1 +PROCESS_PRIORITY_LOW = 2 +PROCESS_PRIORITY_NORMAL = 3 +PROCESS_PRIORITY_HIGH = 4 +PROCESS_PRIORITY_HIGHEST = 5 MSG_INFO = 1 MSG_USER_ALERT = 2 MSG_INTERNAL_ERROR = 3