View Issue Details

IDProjectCategoryView StatusLast Update
0007731mantisbtldappublic2010-04-23 23:22
Reportermlowrie Assigned Tovboctor  
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionduplicate 
Product Version1.0.6 
Summary0007731: 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.

Tagspatch
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
?>
ldap_api.php (6,295 bytes)   
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.php (17,164 bytes)   
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 );
authentication_api.diff (1,405 bytes)   
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
ldap_api.diff (1,116 bytes)   
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 ) {
authentication_ldap.diff (3,262 bytes)   

Relationships

duplicate of 0010689 closedvboctor Support pulling realname from LDAP 

Activities

mlowrie

mlowrie

2007-01-22 00:00

reporter   ~0013942

Last edited: 2007-01-22 00:26

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):
$t_cookie_string = user_create( $p_username, '', ldap_email_from_username( $p_username ), null, false, true, ldap_realname_from_username( $p_username ) );

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:
<?php echo $u_realname ?>
instead of the form entry. It really should be changed so the "update information" button is no longer displayed as no information can be updated.

I just hacked this together, but if somebody has a more elegant way of implementing this, let me know!

Libra

Libra

2007-09-23 11:29

reporter   ~0015698

Last edited: 2007-09-23 11:29

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?

mlowrie

mlowrie

2007-10-30 22:16

reporter   ~0016035

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.

Libra

Libra

2007-11-01 17:59

reporter   ~0016058

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:
$g_use_ldap_realname = ON;
$g_ldap_realname_field = 'cn';

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

mlowrie

mlowrie

2007-11-05 02:04

reporter   ~0016081

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.

lolotrav

lolotrav

2008-04-25 07:43

reporter   ~0017688

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 !
I modified slightly your patch so that mantis user is created only if it exists in ldap.
Find attached patch 'authentication_ldap.diff' (one patch for both files)

micahg

micahg

2008-08-07 20:38

reporter   ~0019090

Any chance of this making it into 1.1.3?