View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0007731 | mantisbt | ldap | public | 2007-01-21 23:42 | 2010-04-23 23:22 |
Reporter | mlowrie | Assigned To | vboctor | ||
Priority | normal | Severity | minor | Reproducibility | always |
Status | closed | Resolution | duplicate | ||
Product Version | 1.0.6 | ||||
Summary | 0007731: LDAP directory and Real Name | ||||
Description | When using LDAP for authentication, Mantis successfully obtains the e-mail address from a given username, but does not have the capability to obtain the real name and leaves it to the user to enter it manually. Automatically obtaining the real name is very useful for organizations that do not use part of a person's name as their login name or use some other method that makes it difficult to determine who the login name belongs to (something like sxy76 instead of jsmith for example). Also, if using a directory, the person's real name most likely exists in the directory and should be the one used. | ||||
Tags | patch | ||||
Attached Files | ldap_api.php (6,295 bytes)
<?php # Mantis - a php based bugtracking system # Copyright (C) 2000 - 2002 Kenzaburo Ito - kenito@300baud.org # Copyright (C) 2002 - 2004 Mantis Team - mantisbt-dev@lists.sourceforge.net # This program is distributed under the terms and conditions of the GPL # See the README and LICENSE files for details # -------------------------------------------------------- # $Id: ldap_api.php,v 1.18 2005/02/12 20:01:17 jlatour Exp $ # -------------------------------------------------------- ########################################################################### # LDAP API ########################################################################### # -------------------- # Connect and bind to the LDAP directory function ldap_connect_bind( $p_binddn = '', $p_password = '' ) { $t_ldap_server = config_get( 'ldap_server' ); $t_ldap_port = config_get( 'ldap_port' ); $t_ds = @ldap_connect ( $t_ldap_server, $t_ldap_port ); if ( $t_ds > 0 ) { # If no Bind DN and Password is set, attempt to login as the configured # Bind DN. if ( is_blank( $p_binddn ) && is_blank( $p_password ) ) { $p_binddn = config_get( 'ldap_bind_dn', '' ); $p_password = config_get( 'ldap_bind_passwd', '' ); } if ( !is_blank( $p_binddn ) && !is_blank( $p_password ) ) { $t_br = @ldap_bind( $t_ds, $p_binddn, $p_password ); } else { # Either the Bind DN or the Password are empty, so attempt an anonymous bind. $t_br = @ldap_bind( $t_ds ); } if ( !$t_br ) { trigger_error( ERROR_LDAP_AUTH_FAILED, ERROR ); } } else { trigger_error( ERROR_LDAP_SERVER_CONNECT_FAILED, ERROR ); } return $t_ds; } # -------------------- # Return an email address from LDAP, given a userid function ldap_email( $p_user_id ) { $t_username = user_get_field( $p_user_id, 'username' ); return ldap_email_from_username($t_username); } # ------------------- # Return the common name from LDAP given a userid function ldap_commonname( $p_user_id ) { $t_commonname = user_get_field( $p_user_id, 'username' ); return ldap_commonname_from_username($t_commonname); } # -------------------- # Return the real name from LDAP, given a username function ldap_realname_from_username( $p_username ) { $t_ldap_organization = config_get( 'ldap_organization' ); $t_ldap_root_dn = config_get( 'ldap_root_dn' ); $t_ldap_uid_field = config_get( 'ldap_uid_field', 'uid' ) ; $t_search_filter = "(&$t_ldap_organization($t_ldap_uid_field=$p_username))"; $t_search_attrs = array( $t_ldap_uid_field, 'cn', 'dn' ); $t_ds = ldap_connect_bind(); $t_sr = ldap_search( $t_ds, $t_ldap_root_dn, $t_search_filter, $t_search_attrs ); $t_info = ldap_get_entries( $t_ds, $t_sr ); ldap_free_result( $t_sr ); ldap_unbind( $t_ds ); return $t_info[0]['cn'][0]; } # -------------------- # Return an email address from LDAP, given a username function ldap_email_from_username( $p_username ) { $t_ldap_organization = config_get( 'ldap_organization' ); $t_ldap_root_dn = config_get( 'ldap_root_dn' ); $t_ldap_uid_field = config_get( 'ldap_uid_field', 'uid' ) ; $t_search_filter = "(&$t_ldap_organization($t_ldap_uid_field=$p_username))"; $t_search_attrs = array( $t_ldap_uid_field, 'mail', 'dn' ); $t_ds = ldap_connect_bind(); $t_sr = ldap_search( $t_ds, $t_ldap_root_dn, $t_search_filter, $t_search_attrs ); $t_info = ldap_get_entries( $t_ds, $t_sr ); ldap_free_result( $t_sr ); ldap_unbind( $t_ds ); return $t_info[0]['mail'][0]; } # -------------------- # Return true if the $uid has an assigngroup=$p_group tag, false otherwise function ldap_has_group( $p_user_id, $p_group ) { $t_ldap_organization = config_get( 'ldap_organization' ); $t_ldap_root_dn = config_get( 'ldap_root_dn' ); $t_username = user_get_field( $p_user_id, 'username' ); $t_ldap_uid_field = config_get( 'ldap_uid_field', 'uid' ) ; $t_search_filter = "(&$t_ldap_organization($t_ldap_uid_field=$t_username)(assignedgroup=$p_group))"; $t_search_attrs = array( $t_ldap_uid_field, 'dn', 'assignedgroup' ); $t_ds = ldap_connect_bind(); $t_sr = ldap_search( $t_ds, $t_ldap_root_dn, $t_search_filter, $t_search_attrs ); $t_entries = ldap_count_entries( $t_ds, $t_sr ); ldap_free_result( $t_sr ); ldap_unbind( $t_ds ); if ( $t_entries > 0 ) { return true; } else { return false; } } # -------------------- # Attempt to authenticate the user against the LDAP directory # return true on successful authentication, false otherwise function ldap_authenticate( $p_user_id, $p_password ) { # if password is empty and ldap allows anonymous login, then # the user will be able to login, hence, we need to check # for this special case. if ( is_blank( $p_password ) ) { return false; } $t_ldap_organization = config_get( 'ldap_organization' ); $t_ldap_root_dn = config_get( 'ldap_root_dn' ); $t_username = user_get_field( $p_user_id, 'username' ); $t_ldap_uid_field = config_get( 'ldap_uid_field', 'uid' ) ; $t_search_filter = "(&$t_ldap_organization($t_ldap_uid_field=$t_username))"; $t_search_attrs = array( $t_ldap_uid_field, 'dn' ); $t_ds = ldap_connect_bind(); # Search for the user id $t_sr = ldap_search( $t_ds, $t_ldap_root_dn, $t_search_filter, $t_search_attrs ); $t_info = ldap_get_entries( $t_ds, $t_sr ); $t_authenticated = false; if ( $t_info ) { # Try to authenticate to each until we get a match for ( $i = 0 ; $i < $t_info['count'] ; $i++ ) { $t_dn = $t_info[$i]['dn']; # Attempt to bind with the DN and password if ( @ldap_bind( $t_ds, $t_dn, $p_password ) ) { $t_authenticated = true; break; # Don't need to go any further } } } ldap_free_result( $t_sr ); ldap_unbind( $t_ds ); return $t_authenticated; } # -------------------- # Create a new user account in the LDAP Directory. # -------------------- # Update the user's account in the LDAP Directory # -------------------- # Change the user's password in the LDAP Directory ?> authentication_api.php (17,164 bytes)
<?php # Mantis - a php based bugtracking system # Copyright (C) 2000 - 2002 Kenzaburo Ito - kenito@300baud.org # Copyright (C) 2002 - 2004 Mantis Team - mantisbt-dev@lists.sourceforge.net # This program is distributed under the terms and conditions of the GPL # See the README and LICENSE files for details # -------------------------------------------------------- # $Id: authentication_api.php,v 1.53 2005/08/10 16:21:28 thraxisp Exp $ # -------------------------------------------------------- ### Authentication API ### $g_script_login_cookie = null; $g_cache_anonymous_user_cookie_string = null; #=================================== # Boolean queries and ensures #=================================== # -------------------- # Check that there is a user logged-in and authenticated # If the user's account is disabled they will be logged out # If there is no user logged in, redirect to the login page # If parameter is given it is used as a URL to redirect to following # successful login. If none is given, the URL of the current page is used function auth_ensure_user_authenticated( $p_return_page = '' ) { if ( !php_version_at_least( '4.1.0' ) ) { global $_SERVER; } # if logged in if ( auth_is_user_authenticated() ) { # check for access enabled # This also makes sure the cookie is valid if ( OFF == current_user_get_field( 'enabled' ) ) { print_header_redirect( 'logout_page.php' ); } } else { # not logged in if ( is_blank( $p_return_page ) ) { if (!isset($_SERVER['REQUEST_URI'])) { $_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'] . '?' . $_SERVER['QUERY_STRING']; } $p_return_page = $_SERVER['REQUEST_URI']; } $p_return_page = string_url( $p_return_page ); print_header_redirect( 'login_page.php?return=' . $p_return_page ); } } # -------------------- # Return true if there is a currently logged in and authenticated user, # false otherwise function auth_is_user_authenticated() { return ( auth_is_cookie_valid( auth_get_current_user_cookie() ) ); } #=================================== # Login / Logout #=================================== # -------------------- # Attempt to login the user with the given password # If the user fails validation, false is returned # If the user passes validation, the cookies are set and # true is returned. If $p_perm_login is true, the long-term # cookie is created. function auth_attempt_login( $p_username, $p_password, $p_perm_login=false ) { $t_user_id = user_get_id_by_name( $p_username ); $t_login_method = config_get( 'login_method' ); if ( false === $t_user_id ) { if ( BASIC_AUTH == $t_login_method || LDAP == $t_login_method ) { # attempt to create the user if using BASIC_AUTH or LDAP if ( BASIC_AUTH == $t_login_method) { $t_cookie_string = user_create( $p_username, $p_password ); } elseif ( LDAP == $t_login_method ) { # get the users' email address as well if using LDAP $t_cookie_string = user_create( $p_username, '', ldap_email_from_username( $p_username ), null, false, true, ldap_realname_from_username( $p_username ) ); } if ( false === $t_cookie_string ) { # it didn't work return false; } # ok, we created the user, get the row again $t_user_id = user_get_id_by_name( $p_username ); if ( false === $t_user_id ) { # uh oh, something must be really wrong # @@@ trigger an error here? return false; } } else { return false; } } # check for disabled account if ( !user_is_enabled( $t_user_id ) ) { return false; } # max. failed login attempts achieved... if( !user_is_login_request_allowed( $t_user_id ) ) { return false; } $t_anon_account = config_get( 'anonymous_account' ); $t_anon_allowed = config_get( 'allow_anonymous_login' ); # check for anonymous login if ( !( ( ON == $t_anon_allowed ) && ( $t_anon_account == $p_username) ) ) { # anonymous login didn't work, so check the password if ( !auth_does_password_match( $t_user_id, $p_password ) ) { user_increment_failed_login_count( $t_user_id ); return false; } } # ok, we're good to login now # increment login count user_increment_login_count( $t_user_id ); user_reset_failed_login_count_to_zero( $t_user_id ); user_reset_lost_password_in_progress_count_to_zero( $t_user_id ); # set the cookies auth_set_cookies( $t_user_id, $p_perm_login ); return true; } # -------------------- # Allows scripts to login using a login name or ( login name + password ) function auth_attempt_script_login( $p_username, $p_password = null ) { global $g_script_login_cookie, $g_cache_current_user_id; $t_user_id = user_get_id_by_name( $p_username ); $t_user = user_get_row( $t_user_id ); # check for disabled account if ( OFF == $t_user['enabled'] ) { return false; } # validate password if supplied if ( null !== $p_password ) { if ( !auth_does_password_match( $t_user_id, $p_password ) ) { return false; } } # ok, we're good to login now # increment login count user_increment_login_count( $t_user_id ); # set the cookies $g_script_login_cookie = $t_user['cookie_string']; # cache user id for future reference $g_cache_current_user_id = $t_user_id; return true; } # -------------------- # Logout the current user and remove any remaining cookies from their browser # Returns true on success, false otherwise function auth_logout() { global $g_cache_current_user_id; # clear cached userid $g_cache_current_user_id = null; # clear cookies, if they were set if (auth_clear_cookies()) { helper_clear_pref_cookies(); } return true; } #=================================== # Password functions #=================================== # -------------------- # Return true if the password for the user id given matches the given # password (taking into account the global login method) function auth_does_password_match( $p_user_id, $p_test_password ) { $t_configured_login_method = config_get( 'login_method' ); if ( LDAP == $t_configured_login_method ) { return ldap_authenticate( $p_user_id, $p_test_password ); } $t_password = user_get_field( $p_user_id, 'password' ); $t_login_methods = Array(MD5, CRYPT, PLAIN); foreach ( $t_login_methods as $t_login_method ) { # pass the stored password in as the salt if ( auth_process_plain_password( $p_test_password, $t_password, $t_login_method ) == $t_password ) { # Check for migration to another login method and test whether the password was encrypted # with our previously insecure implemention of the CRYPT method if ( ( $t_login_method != $t_configured_login_method ) || ( ( CRYPT == $t_configured_login_method ) && substr( $t_password, 0, 2 ) == substr( $p_test_password, 0, 2 ) ) ) { user_set_password( $p_user_id, $p_test_password, true ); } return true; } } return false; } # -------------------- # Encrypt and return the plain password given, as appropriate for the current # global login method. # # When generating a new password, no salt should be passed in. # When encrypting a password to compare to a stored password, the stored # password should be passed in as salt. If the auth method is CRYPT then # crypt() will extract the appropriate portion of the stored password as its salt function auth_process_plain_password( $p_password, $p_salt=null, $p_method=null ) { $t_login_method = config_get( 'login_method' ); if ( $p_method !== null ) { $t_login_method = $p_method; } switch ( $t_login_method ) { case CRYPT: # a null salt is the same as no salt, which causes a salt to be generated # otherwise, use the salt given $t_processed_password = crypt( $p_password, $p_salt ); break; case MD5: $t_processed_password = md5( $p_password ); break; case BASIC_AUTH: case PLAIN: default: $t_processed_password = $p_password; break; } # cut this off to 32 cahracters which the largest possible string in the database return substr( $t_processed_password, 0, 32 ); } # -------------------- # Generate a random 12 character password # p_email is unused function auth_generate_random_password( $p_email ) { $t_val = mt_rand( 0, mt_getrandmax() ) + mt_rand( 0, mt_getrandmax() ); $t_val = md5( $t_val ); return substr( $t_val, 0, 12 ); } # -------------------- # Generate a confirm_hash 12 character to valide the password reset request function auth_generate_confirm_hash( $p_user_id ) { $t_confirm_hash_generator = config_get( 'password_confirm_hash_magic_string' ); $t_password = user_get_field( $p_user_id, 'password' ); $t_last_visit = user_get_field( $p_user_id, 'last_visit' ); $t_confirm_hash = md5( $t_confirm_hash_generator . $t_password . $t_last_visit ); return $t_confirm_hash; } #=================================== # Cookie functions #=================================== # -------------------- # Set login cookies for the user # If $p_perm_login is true, a long-term cookie is created function auth_set_cookies( $p_user_id, $p_perm_login=false ) { $t_cookie_string = user_get_field( $p_user_id, 'cookie_string' ); $t_cookie_name = config_get( 'string_cookie' ); if ( $p_perm_login ) { # set permanent cookie (1 year) gpc_set_cookie( $t_cookie_name, $t_cookie_string, true ); } else { # set temp cookie, cookie dies after browser closes gpc_set_cookie( $t_cookie_name, $t_cookie_string, false ); } } # -------------------- # Clear login cookies, return true if they were cleared function auth_clear_cookies() { global $g_script_login_cookie; $t_cookies_cleared = false; # clear cookie, if not logged in from script if ($g_script_login_cookie == null) { $t_cookie_name = config_get( 'string_cookie' ); $t_cookie_path = config_get( 'cookie_path' ); gpc_clear_cookie( $t_cookie_name, $t_cookie_path ); $t_cookies_cleared = true; } else { $g_script_login_cookie = null; } return $t_cookies_cleared; } # -------------------- # Generate a string to use as the identifier for the login cookie # It is not guaranteed to be unique and should be checked # The string returned should be 64 characters in length function auth_generate_cookie_string() { $t_val = mt_rand( 0, mt_getrandmax() ) + mt_rand( 0, mt_getrandmax() ); $t_val = md5( $t_val ) . md5( time() ); return substr( $t_val, 0, 64 ); } # -------------------- # Generate a UNIQUE string to use as the identifier for the login cookie # The string returned should be 64 characters in length function auth_generate_unique_cookie_string() { do { $t_cookie_string = auth_generate_cookie_string(); } while ( !auth_is_cookie_string_unique( $t_cookie_string ) ); return $t_cookie_string; } # -------------------- # Return true if the cookie login identifier is unique, false otherwise function auth_is_cookie_string_unique( $p_cookie_string ) { $t_user_table = config_get( 'mantis_user_table' ); $c_cookie_string = db_prepare_string( $p_cookie_string ); $query = "SELECT COUNT(*) FROM $t_user_table WHERE cookie_string='$c_cookie_string'"; $result = db_query( $query ); $t_count = db_result( $result ); if ( $t_count > 0 ) { return false; } else { return true; } } # -------------------- # Return the current user login cookie string, # note that the cookie cached by a script login superceeds the cookie provided by # the browser. This shouldn't normally matter, except that the password verification uses # this routine to bypass the normal authentication, and can get confused when a normal user # logs in, then runs the verify script. the act of fetching config variables may get the wrong # userid. # if no user is logged in and anonymous login is enabled, returns cookie for anonymous user # otherwise returns '' (an empty string) function auth_get_current_user_cookie() { global $g_script_login_cookie, $g_cache_anonymous_user_cookie_string; # if logging in via a script, return that cookie if ( $g_script_login_cookie !== null ) { return $g_script_login_cookie; } # fetch user cookie $t_cookie_name = config_get( 'string_cookie' ); $t_cookie = gpc_get_cookie( $t_cookie_name, '' ); # if cookie not found, and anonymous login enabled, use cookie of anonymous account. if ( is_blank( $t_cookie ) ) { if ( ON == config_get( 'allow_anonymous_login' ) ) { if ( $g_cache_anonymous_user_cookie_string === null ) { if ( function_exists( 'db_is_connected' ) && db_is_connected() ) { # get anonymous information if database is available $query = sprintf('SELECT id, cookie_string FROM %s WHERE username = \'%s\'', config_get( 'mantis_user_table' ), config_get( 'anonymous_account' ) ); $result = db_query( $query ); if ( 1 == db_num_rows( $result ) ) { $row = db_fetch_array( $result ); $t_cookie = $row['cookie_string']; $g_cache_anonymous_user_cookie_string = $t_cookie; $g_cache_current_user_id = $row['id']; } } } else { $t_cookie = $g_cache_anonymous_user_cookie_string; } } } return $t_cookie; } #=================================== # Data Access #=================================== ######################################### # is cookie valid? function auth_is_cookie_valid( $p_cookie_string ) { global $g_cache_current_user_id; # fail if DB isn't accessible if ( !db_is_connected() ) { return false; } # fail if cookie is blank if ( '' === $p_cookie_string ) { return false; } # succeeed if user has already been authenticated if ( null !== $g_cache_current_user_id ) { return true; } # look up cookie in the database to see if it is valid $t_user_table = config_get( 'mantis_user_table' ); $c_cookie_string = db_prepare_string( $p_cookie_string ); $query = "SELECT id FROM $t_user_table WHERE cookie_string='$c_cookie_string'"; $result = db_query( $query ); # return true if a matching cookie was found return ( 1 == db_num_rows( $result ) ); } ######################################### # SECURITY NOTE: cache globals are initialized here to prevent them # being spoofed if register_globals is turned on # $g_cache_current_user_id = null; function auth_get_current_user_id() { global $g_cache_current_user_id; if ( null !== $g_cache_current_user_id ) { return $g_cache_current_user_id; } $t_user_table = config_get( 'mantis_user_table' ); $t_cookie_string = auth_get_current_user_cookie(); # @@@ error with an error saying they aren't logged in? # Or redirect to the login page maybe? $c_cookie_string = db_prepare_string( $t_cookie_string ); $query = "SELECT id FROM $t_user_table WHERE cookie_string='$c_cookie_string'"; $result = db_query( $query ); # The cookie was invalid. Clear the cookie (to allow people to log in again) # and give them an Access Denied message. if ( db_num_rows( $result ) < 1 ) { auth_clear_cookies(); access_denied(); # never returns return false; } $t_user_id = (int)db_result( $result ); $g_cache_current_user_id = $t_user_id; return $t_user_id; } #=================================== # HTTP Auth #=================================== function auth_http_prompt() { header( "HTTP/1.0 401 Authorization Required" ); header( "WWW-Authenticate: Basic realm=\"" . lang_get( 'http_auth_realm' ) . "\"" ); header( 'status: 401 Unauthorized' ); echo '<center>'; echo '<p>'.error_string(ERROR_ACCESS_DENIED).'</p>'; print_bracket_link( 'main_page.php', lang_get( 'proceed' ) ); echo '</center>'; exit; } function auth_http_set_logout_pending( $p_pending ) { $t_cookie_name = config_get( 'logout_cookie' ); if ( $p_pending ) { gpc_set_cookie( $t_cookie_name, "1", false ); } else { $t_cookie_path = config_get( 'cookie_path' ); gpc_clear_cookie( $t_cookie_name, $t_cookie_path ); } } function auth_http_is_logout_pending() { $t_cookie_name = config_get( 'logout_cookie' ); $t_cookie = gpc_get_cookie( $t_cookie_name, '' ); return( $t_cookie > '' ); } ?> authentication_api.diff (1,405 bytes)
--- authentication_api.php.orig Fri Oct 19 09:54:58 2007 +++ authentication_api.php Thu Nov 1 23:55:48 2007 @@ -82,9 +82,15 @@ $t_login_method = config_get( 'login_method' ); if ( false === $t_user_id ) { - if ( BASIC_AUTH == $t_login_method ) { - # attempt to create the user if using BASIC_AUTH - $t_cookie_string = user_create( $p_username, $p_password ); + if ( BASIC_AUTH == $t_login_method || LDAP == $t_login_method ) { + + # attempt to create the user if using BASIC_AUTH or LDAP + if ( BASIC_AUTH == $t_login_method) { + $t_cookie_string = user_create( $p_username, $p_password ); + } elseif ( LDAP == $t_login_method ) { + # get the users' email address as well if using LDAP + $t_cookie_string = user_create( $p_username, '', ldap_email_from_username( $p_username ), null, false, true, ldap_realname_from_username( $p_username ) ); + } if ( false === $t_cookie_string ) { # it didn't work @@ -136,6 +142,11 @@ user_reset_failed_login_count_to_zero( $t_user_id ); user_reset_lost_password_in_progress_count_to_zero( $t_user_id ); + + # set user Real Name to value from LDAP + if ( ON == config_get( 'use_ldap_realname' ) ) { + user_set_realname( $t_user_id, ldap_realname_from_username( $p_username ) ); + } # set the cookies auth_set_cookies( $t_user_id, $p_perm_login ); ldap_api.diff (1,116 bytes)
--- ldap_api.php.orig Sun Oct 14 01:35:32 2007 +++ ldap_api.php Thu Nov 1 23:56:06 2007 @@ -91,6 +91,26 @@ return $t_info[0]['mail'][0]; } + + # -------------------- + # Return the real name from LDAP, given a username + function ldap_realname_from_username( $p_username ) { + $t_ldap_organization = config_get( 'ldap_organization' ); + $t_ldap_root_dn = config_get( 'ldap_root_dn' ); + + $t_ldap_uid_field = config_get( 'ldap_uid_field', 'uid' ); + $t_ldap_realname_field = config_get( 'ldap_realname_field', 'cn' ); + $t_search_filter = "(&$t_ldap_organization($t_ldap_uid_field=$p_username))"; + $t_search_attrs = array( $t_ldap_uid_field, $t_ldap_realname_field, 'dn' ); + $t_ds = ldap_connect_bind(); + + $t_sr = ldap_search( $t_ds, $t_ldap_root_dn, $t_search_filter, $t_search_attrs ); + $t_info = ldap_get_entries( $t_ds, $t_sr ); + ldap_free_result( $t_sr ); + ldap_unbind( $t_ds ); + + return $t_info[0][$t_ldap_realname_field][0]; + } # -------------------- # Return true if the $uid has an assigngroup=$p_group tag, false otherwise authentication_ldap.diff (3,262 bytes)
diff -uNr mantis-1.1.1/core/authentication_api.php www/core/authentication_api.php --- mantis-1.1.1/core/authentication_api.php 2007-10-19 08:54:58.000000000 +0200 +++ www/core/authentication_api.php 2008-04-25 13:33:50.000000000 +0200 @@ -82,16 +82,27 @@ $t_login_method = config_get( 'login_method' ); if ( false === $t_user_id ) { - if ( BASIC_AUTH == $t_login_method ) { - # attempt to create the user if using BASIC_AUTH - $t_cookie_string = user_create( $p_username, $p_password ); - - if ( false === $t_cookie_string ) { - # it didn't work - return false; + if ( BASIC_AUTH == $t_login_method || LDAP == $t_login_method ) { + + # attempt to create the user if using BASIC_AUTH or LDAP + if ( BASIC_AUTH == $t_login_method) { + $t_cookie_string = user_create( $p_username, $p_password ); + } elseif ( LDAP == $t_login_method ) { + # get the users' email address as well if using LDAP + $email = ldap_email_from_username( $p_username ); + $realname = ldap_realname_from_username( $p_username ); + if ( $email && $realname ) { + # Both email and realname exists in LDAP : create mantis user + $t_cookie_string = user_create( $p_username, '', $email, null, false, true, $realname ); + if ( false === $t_cookie_string ) { + # it didn't work + return false; + } + } } - # ok, we created the user, get the row again + # we may have created the user, get the row again $t_user_id = user_get_id_by_name( $p_username ); if ( false === $t_user_id ) { @@ -136,6 +147,12 @@ user_reset_failed_login_count_to_zero( $t_user_id ); user_reset_lost_password_in_progress_count_to_zero( $t_user_id ); + + # update user Real Name to value from LDAP (in case it changed) at each login + if ( ON == config_get( 'use_ldap_realname' ) ) { + user_set_realname( $t_user_id, ldap_realname_from_username( $p_username ) ); + } # set the cookies auth_set_cookies( $t_user_id, $p_perm_login ); diff -uNr mantis-1.1.1/core/ldap_api.php www/core/ldap_api.php --- mantis-1.1.1/core/ldap_api.php 2007-10-14 00:36:41.000000000 +0200 +++ www/core/ldap_api.php 2008-04-25 13:37:29.000000000 +0200 @@ -92,6 +92,27 @@ return $t_info[0]['mail'][0]; } + # -------------------- + # Return the real name from LDAP, given a username + function ldap_realname_from_username( $p_username ) { + $t_ldap_organization = config_get( 'ldap_organization' ); + $t_ldap_root_dn = config_get( 'ldap_root_dn' ); + + $t_ldap_uid_field = config_get( 'ldap_uid_field', 'uid' ); + $t_ldap_realname_field = config_get( 'ldap_realname_field', 'cn' ); + $t_search_filter = "(&$t_ldap_organization($t_ldap_uid_field=$p_username))"; + $t_search_attrs = array( $t_ldap_uid_field, $t_ldap_realname_field, 'dn' ); + $t_ds = ldap_connect_bind(); + + $t_sr = ldap_search( $t_ds, $t_ldap_root_dn, $t_search_filter, $t_search_attrs ); + $t_info = ldap_get_entries( $t_ds, $t_sr ); + ldap_free_result( $t_sr ); + ldap_unbind( $t_ds ); + + return $t_info[0][$t_ldap_realname_field][0]; + } + # -------------------- # Return true if the $uid has an assigngroup=$p_group tag, false otherwise function ldap_has_group( $p_user_id, $p_group ) { | ||||
To implement this, I added a function in ldap_api.php (attached) called ldap_realname_from_username that is basically a copy of the 'ldap_email_from_username' function, but returns the real name. Just change 'cn' to whatever attribute contains your user's real names. For user's that have not logged in before, I used the authentication_api.php from bug 5595 that autocreats the user. To enable the creation of the real name as well, change line 82 to this (attached): The 'null', 'false', and 'true' are the default values of the user_create function in user_api.php as it required values other than '' in order to create the user as enabled and with the reporter access level. To ensure user's can't change their real name under "My Account", edit line 190 of account_page.php so it reads: I just hacked this together, but if somebody has a more elegant way of implementing this, let me know! |
|
Thanks for a patch - I have already installed it on our internal portal! In our organization the Real Name also is not used, as a username. But there is one more problem - entry for user is created in LDAP from other database, in which the Real Name is not always correct. The user can change own Real Name with the help of a profile (used CMS) - these changes also affected the LDAP entry. Therefore in our case it would be quite good to update a Real Name of the user each time when the user enters in Mantis (LDAP Real Name -> Mantis). What do you think about this? |
|
Ideally, Mantis should always refer to the LDAP directory for any user information instead of keeping a local copy. Some may argue this, but it's the best way to ensure you are getting the most recent data. At a minimum, it should copy the data from the LDAP server upon login so that the database is up to date in case of any changes. There are a whole list of items that should be configurable when using LDAP, and unfortunately there doesn't seem to be anyone able or willing to implement some of these vital tasks. |
|
I add some changes to files from this issue (authentication_api.php and ldap_api.php) for refer to LDAP and set Real Name every time, when user login to the system. For using this feature you must add two variables in config_inc.php: Where $g_ldap_realname_field is LDAP attribute, responsible for Real Name of user, e.g. 'cn' or 'displayName' etc. I attached only diff files (authentication_api.diff and ldap_api.diff) for ORIGINAL files from version 1.1.0rc2 |
|
Thanks for updating the patch. I did apply your diffs and everything seems to work great. I still need to do some in-depth testing, but this will have to wait until December - no time at the moment. I would like to expand it a bit more allowing a configuration variable that either allows the real name to be changed or disables changes like the other fields. Of course, this will require the removeal of the form as no fields will be editable. Thanks for the update, and I hope to get some additional feedback in a month or so. |
|
I tested your patch on mantis 1.1.1 and it works fine, however there is one problem : user is created in mantis even before its username is checked in ldap. Thus, there is a fake mantis user for all invalid login username ! |
|
Any chance of this making it into 1.1.3? |
|