2016-12-09 06:32 EST

View Issue Details Jump to Notes ] Wiki ]
IDProjectCategoryView StatusLast Update
0009954mantisbtldappublic2016-11-09 05:28
ReporterKirill 
Assigned To 
PrioritynormalSeverityfeatureReproducibilityhave not tried
StatusnewResolutionopen 
PlatformWindowsOSWindows XPOS Version1.1.0
Product Version1.1.5 
Target VersionFixed in Version 
Summary0009954: More than one ldap-server
DescriptionI have 3 different AD-server with ldap. I can write in config only one ldap-server for authentication.
May be add more than one server?
TagsNo tags attached.
Attached Files
  • patch file icon multildap.patch (8,862 bytes) 2010-05-13 07:22 -
    diff -r -u mantisbt-1.2.1\/account_update.php mantisbt-1.2.1x/account_update.php
    --- mantisbt-1.2.1\/account_update.php	2010-04-23 14:28:34.000000000 +0300
    +++ mantisbt-1.2.1x/account_update.php	2010-05-13 13:09:10.962955300 +0300
    @@ -31,6 +31,10 @@
     
     	require_once( 'email_api.php' );
     
    +	if ( MIXED == $g_login_method) {
    +		$g_login_method = MD5;
    +	}
    +
     	form_security_validate('account_update');
     
     	auth_ensure_user_authenticated();
    diff -r -u mantisbt-1.2.1\/config_defaults_inc.php mantisbt-1.2.1x/config_defaults_inc.php
    --- mantisbt-1.2.1\/config_defaults_inc.php	2010-04-23 14:28:34.000000000 +0300
    +++ mantisbt-1.2.1x/config_defaults_inc.php	2010-05-13 14:03:07.270004500 +0300
    @@ -1720,8 +1720,65 @@
     	 * systems this option should be set to ''.
     	 */
     	$g_ldap_simulation_file_path = '';
    +	
    +	/**
    +	 * Whether or not to store password, realname and email from LDAP to local database.
    +	 *
    +	 * @global int $g_ldap_store_to_localdb
    +	 */
    +	$g_ldap_store_to_localdb = ON;
     
     	/*******************
    +	 * Multi LDAP auth *
    +	 *******************/
    +	/**
    +	 * The same as for LDAP but you can configure defferent options for each LDAP profile.
    +	 * And additional you can use other auth schemes this way
    +	 * To enable multi LDAP scheme set $g_login_method to MIXED
    +	 */
    +	 
    +	 $g_auth_profiles = array (
    +		"0"  => array(
    +			"auth_profile_name"			=> "LOCAL",
    +			"login_method"				=> MD5
    +			),
    +		"1"  => array(
    +			"auth_profile_name" 		=> "LDAP SERVER 1",
    +			"login_method"				=> LDAP,
    +			"ldap_server" 				=> "ldap1.example1.com.au",
    +			"ldap_port" 				=> "389",
    +			"ldap_root_dn"				=> "dc=example1,dc=com,dc=au",
    +			"ldap_organization"			=> "",
    +			"ldap_uid_field"			=> "sAMAccountName",
    +			"ldap_realname_field"		=> "cn",
    +			"ldap_bind_dn"				=> "",
    +			"ldap_bind_passwd"			=> "",
    +			"ldap_email"				=> OFF,
    +			"ldap_realname"				=> OFF,
    +			"ldap_protocol_version"		=> "3",
    +			"ldap_follow_referrals"		=> OFF,
    +			"ldap_simulation_file_path"	=> ""
    +			),
    +		"2"  => array(
    +			"auth_profile_name" 		=> "LDAP SERVER 2",
    +			"login_method"				=> LDAP,
    +			"ldap_server" 				=> "ldap2.example2.com.au",
    +			"ldap_port" 				=> "389",
    +			"ldap_root_dn"				=> "dc=example1,dc=com,dc=au",
    +			"ldap_organization"			=> "",
    +			"ldap_uid_field"			=> "sAMAccountName",
    +			"ldap_realname_field"		=> "cn",
    +			"ldap_bind_dn"				=> "",
    +			"ldap_bind_passwd"			=> "",
    +			"ldap_email"				=> OFF,
    +			"ldap_realname"				=> OFF,
    +			"ldap_protocol_version"		=> "3",
    +			"ldap_follow_referrals"		=> OFF,
    +			"ldap_simulation_file_path"	=> ""
    +			)
    +	);
    +	
    +	/*******************
     	 * Status Settings *
     	 *******************/
     
    @@ -2479,6 +2536,7 @@
     	/**
     	 * login method
     	 * CRYPT or PLAIN or MD5 or LDAP or BASIC_AUTH
    +	 * or MIXED for multiLDAP
     	 * You can simply change this at will. MantisBT will try to figure out how the passwords were encrypted.
     	 * @global int $g_login_method
     	 */
    @@ -2797,6 +2855,15 @@
     	 * @global string $g_bug_list_cookie
     	 */
     	$g_bug_list_cookie		= '%cookie_prefix%_BUG_LIST_COOKIE';
    +	
    +	/**
    +	 *
    +	 * @global string $g_bug_list_cookie
    +	 */
    +	$g_logon_to_cookie		= '%cookie_prefix%_LOGON_TO_COOKIE';
    +	
    +	
    +	
     
     	/*****************************
     	 * MantisBT Filter Variables *
    diff -r -u mantisbt-1.2.1\/core/authentication_api.php mantisbt-1.2.1x/core/authentication_api.php
    --- mantisbt-1.2.1\/core/authentication_api.php	2010-04-23 14:28:34.000000000 +0300
    +++ mantisbt-1.2.1x/core/authentication_api.php	2010-05-13 13:22:36.317013700 +0300
    @@ -52,6 +52,18 @@
      */
     $g_cache_current_user_id = null;
     
    +
    +	if (gpc_get_cookie( config_get('logon_to_cookie'), '')){
    +		$t_cookie_logon_to = gpc_get_cookie( config_get('logon_to_cookie'), '');
    +		
    +		if ( MIXED == $g_login_method ){
    +			foreach ($g_auth_profiles[$t_cookie_logon_to] as $t_key => $t_value){
    +				${'g_'.$t_key} = $t_value;
    +			}
    +		}
    +	}	
    +
    +
     /**
      * Check that there is a user logged-in and authenticated
      * If the user's account is disabled they will be logged out
    @@ -458,12 +470,17 @@
     
     	$t_cookie_name = config_get( 'string_cookie' );
     
    +	$t_cookie_logon_to = config_get( 'logon_to_cookie' );
    +	global $f_logon_to;
    +	
     	if( $p_perm_login ) {
     		# set permanent cookie (1 year)
     		gpc_set_cookie( $t_cookie_name, $t_cookie_string, true );
    +		gpc_set_cookie( $t_cookie_logon_to, $g_ldap_server, true );
     	} else {
     		# set temp cookie, cookie dies after browser closes
     		gpc_set_cookie( $t_cookie_name, $t_cookie_string, false );
    +		gpc_set_cookie( $t_cookie_logon_to, $f_logon_to, false );
     	}
     }
     
    @@ -482,8 +499,10 @@
     	if( $g_script_login_cookie == null ) {
     		$t_cookie_name = config_get( 'string_cookie' );
     		$t_cookie_path = config_get( 'cookie_path' );
    +		$t_cookie_logon_to = config_get( 'logon_to_cookie' );
     
     		gpc_clear_cookie( $t_cookie_name, $t_cookie_path );
    +		gpc_clear_cookie( $t_cookie_logon_to, $t_cookie_path );
     		$t_cookies_cleared = true;
     	} else {
     		$g_script_login_cookie = null;
    diff -r -u mantisbt-1.2.1\/core/constant_inc.php mantisbt-1.2.1x/core/constant_inc.php
    --- mantisbt-1.2.1\/core/constant_inc.php	2010-04-23 14:28:34.000000000 +0300
    +++ mantisbt-1.2.1x/core/constant_inc.php	2010-05-13 10:04:00.938673700 +0300
    @@ -134,6 +134,7 @@
     define( 'LDAP', 4 );
     define( 'BASIC_AUTH', 5 );
     define( 'HTTP_AUTH', 6 );
    +define( 'MIXED', 7 );
     
     # file upload methods
     define( 'DISK', 1 );
    diff -r -u mantisbt-1.2.1\/core/custom_function_api.php mantisbt-1.2.1x/core/custom_function_api.php
    --- mantisbt-1.2.1\/core/custom_function_api.php	2010-04-23 14:28:34.000000000 +0300
    +++ mantisbt-1.2.1x/core/custom_function_api.php	2010-05-13 12:02:14.394077100 +0300
    @@ -197,7 +197,7 @@
     		CRYPT_FULL_SALT,
     		MD5,
     	);
    -	if( in_array( config_get( 'login_method' ), $t_can_change ) ) {
    +	if( ( in_array( config_get( 'login_method' ), $t_can_change ) ) || ( is_page_name( 'verify.php' ) && config_get( 'login_method' ) == MIXED )) {
     		return true;
     	} else {
     		return false;
    diff -r -u mantisbt-1.2.1\/core/ldap_api.php mantisbt-1.2.1x/core/ldap_api.php
    --- mantisbt-1.2.1\/core/ldap_api.php	2010-04-23 14:28:34.000000000 +0300
    +++ mantisbt-1.2.1x/core/ldap_api.php	2010-05-12 15:44:20.435179300 +0300
    @@ -352,7 +352,10 @@
     	# If user authenticated successfully then update the local DB with information
     	# from LDAP.  This will allow us to use the local data after login without
     	# having to go back to LDAP.  This will also allow fallback to DB if LDAP is down.
    -	if ( $t_authenticated ) {
    +		
    +	global $g_ldap_store_to_localdb;
    +	
    +	if ( $t_authenticated && $g_ldap_store_to_localdb == ON ) {
     		$t_user_id = user_get_id_by_name( $p_username );
     
     		if ( false !== $t_user_id ) {
    diff -r -u mantisbt-1.2.1\/login.php mantisbt-1.2.1x/login.php
    --- mantisbt-1.2.1\/login.php	2010-04-23 14:28:34.000000000 +0300
    +++ mantisbt-1.2.1x/login.php	2010-05-13 13:14:50.451675700 +0300
    @@ -28,10 +28,17 @@
     
     	$f_username		= gpc_get_string( 'username', '' );
     	$f_password		= gpc_get_string( 'password', '' );
    +	$f_logon_to		= gpc_get_string( 'logon_to', '' );
     	$f_perm_login	= gpc_get_bool( 'perm_login' );
     	$t_return		= string_url( string_sanitize_url( gpc_get_string( 'return', config_get( 'default_home_page' ) ) ) );
     	$f_from			= gpc_get_string( 'from', '' );
     	$f_secure_session = gpc_get_bool( 'secure_session', false );
    +	
    +	if ( MIXED == $g_login_method ){
    +		foreach ($g_auth_profiles[$f_logon_to] as $t_key => $t_value){
    +			${'g_'.$t_key} = $t_value;
    +		}
    +	}
     
     	$f_username = auth_prepare_username($f_username);
     	$f_password = auth_prepare_password($f_password);
    @@ -48,11 +55,10 @@
     			'&error=1&username=' . urlencode( $f_username ) .
     			'&perm_login=' . ( $f_perm_login ? 1 : 0 ) .
     			'&secure_session=' . ( $f_secure_session ? 1 : 0 );
    -
    +		
     		if ( HTTP_AUTH == config_get( 'login_method' ) ) {
     			auth_http_prompt();
     			exit;
     		}
     	}
    -
     	print_header_redirect( $t_redirect_url );
    diff -r -u mantisbt-1.2.1\/login_page.php mantisbt-1.2.1x/login_page.php
    --- mantisbt-1.2.1\/login_page.php	2010-04-23 14:28:34.000000000 +0300
    +++ mantisbt-1.2.1x/login_page.php	2010-05-13 10:37:28.636246900 +0300
    @@ -132,6 +132,15 @@
     		<input type="password" name="password" size="16" maxlength="<?php echo PASSLEN;?>" />
     	</td>
     </tr>
    +<?php
    +if ( MIXED == $g_login_method ){
    +	echo '<tr class="row-1"><td class="category" width="25%">Logon to</td><td width="75%"><select name="logon_to">';
    +	foreach ($g_auth_profiles as $t_key => $t_value){
    +		echo '<option value="'.$t_key.'">'.$t_value["auth_profile_name"].'</option>';	
    +	}
    +	echo '</select></td></tr>';
    +}
    +?>
     <tr class="row-1">
     	<td class="category">
     		<?php echo lang_get( 'save_login' ) ?>
    
    patch file icon multildap.patch (8,862 bytes) 2010-05-13 07:22 +

-Relationships
related to 0015721closedgrangeway Functionality to consider porting to master-2.0.x 
has duplicate 0007011closedvboctor Ability to authenticate against multiple LDAP directories 
related to 0020769acknowledged New functionnality : LDAP fallback server OR round robin 
+Relationships

-Notes
vboctor

~0020352

vboctor (manager)

So each LDAP server has a separate set of users? What is the user case behind having multiple LDAP servers?
Kirill

~0020357

Kirill (reporter)

Yes. All users unique
grangeway

~0020363

grangeway (reporter)

I run at a patch at work against mantis to support multiple OU's.

I'm just wondering whether the code for that case could be extended to support this, although i'm thinking probably not.

Is this within 1 project?
I'm just trying to think of what one might want the code to do - when trying to find a user, try 1st, try 2nd server... then lookup email, try 1st, try 2nd (you'd probably not want to store the LDAP server details against a user),.. so this would be a performance hit.

Similarly, what would the expected behaviour be if you've got 2 different users ( Fred in LDAP A and Fred in LDAP B) with the same username when logging in...

What we probably could/should do is allow a fallback ldap server (for if first if offline), in that case, you could probably make a small change to the routines to continue instead of breaking off if you got a 'not found' result from a server.

Paul
Kirill

~0020366

Kirill (reporter)

Can we login with full domain name? For example fred@domain1.com and fred@fomain2.com
AlexM600

~0025494

AlexM600 (reporter)

Hello
I've written a little patch for 1.2.1 to Multi LDAP
1. Added new login_method MIXED
  1.1 You can configure several LDAP profiles
  1.2 You also have LOCAL (SQL BD) auth profile
  1.3 You can select Profile on the Login page
2. When you use MIXED method
  2.1 Users can not reset their passwords (like in LDAP profile)
  2.2 Administrator can reset user's password on User Management page. This password will be used for LOCAL profile
3. On ReAuthetication page administrator use early selected profile to relogon
4. Storing LDAP password to local db is now configurable by $g_ldap_store_to_localdb.
AlexM600

~0025495

AlexM600 (reporter)

Please, somebody check it for possible bugs.
mikehelms

~0025708

mikehelms (reporter)

Alex, this is brilliant and it works perfectly.

Thanks for sharing this. I hope this eventually gets worked into the main build; it's probably not something that a lot of people will use, but it makes the LDAP functionality incredibly versatile.
paontis

~0026026

paontis (reporter)

Hi Alex great job.
But i have a question. I see that in your patch you modify on the fly the GLOBAL variable $g_login_method.
Isn't this dangerous in case of concurrent accesses? In this way there is a discrepancy between the variable read from configuration file and the same variable directly accessed.

I report here some logging i added, I hope this could be helpful:

 2010-07-06 18:08 CEST ldap login.php BEFORE the patch code:
 2010-07-06 18:08 CEST ldap config_get( 'login_method' ): 7
 2010-07-06 18:08 CEST ldap g_login_method' : 7

 2010-07-06 18:08 CEST ldap login.php AFTER the patch code:
 2010-07-06 18:08 CEST ldap config_get( 'login_method' ): 7
 2010-07-06 18:08 CEST ldap g_login_method' : 4
paontis

~0026041

paontis (reporter)

More: i logged in with my user with local profile and changed the local password.
The i am no more able to login with LDAP.
I think because also before i didn't really authenticated with LDAP.
The login appeared to be successfull becuse when using the native LDAP the password was copied in local db.
But the function auth_does_password_match in authentication_api.php perform the following check:
if( LDAP == $t_configured_login_method ) {
        return ldap_authenticate( $p_user_id, $p_test_password );
    }
It means that when the login method is == MIXED, the LDAP authentications is not performed.
So the patch by alex is a good starting point, but it needs to be reworked.
kgron

~0028520

kgron (reporter)

Hi Alex,
this patch is exactly what I needed to put Mantis to work. However I found an error in the process which could be problematic. When you have to reauthenticate, Mantis saves your password in PLAIN TEXT into mantis database instead of a MD5 hash.
I located the problem in function auth_process_plain_password (authentication_api.php) and changed the default behaviour of a plain password into the same as MD5.
Has someone noticed the same behaviour on his Mantis with this patch?
paontis

~0028720

paontis (reporter)

Hi kgron,

instead of change the case of the plain password, i think it is more clean to add this one:

case MIXED:
     $t_processed_password = md5( $p_password );
     break;

see also my two previous notes: 0009954:0026041 and 0009954:0026026
pigbrain

~0030555

pigbrain (reporter)

Hi Paontis

I meet the same problem with you in notes: 0009954:0026041
Could you share me how did you fix the problem´╝č
Thanks lot.
grangeway

~0030991

grangeway (reporter)

The 1.3 series will support an array of ldap servers
grangeway

~0036296

grangeway (reporter)

Marking as 'acknowledged' not resolved/closed to track that change gets ported to master-2.0.x branch
atrol

~0054059

atrol (developer)

0009954:0030991 caused a bit confusion in forum.
This feature is not implemented in 1.3.
modir

~0054349

modir (reporter)

I would like to work on this item.

Should I follow roughly the idea of the attached patch or should I work on a different solution?

One idea could be to have "login_method" as an array and then go through all logon methods after each other. And then have one or more LDAP entries in this array.
atrol

~0054362

atrol (developer)

No time to have a deeper look at it, but would like to comment on this
> go through all logon methods after each other

IMO no good idea as it decreases security.
modir

~0054366

modir (reporter)

Why would it decrease security? I don't see a huge problem as you can limit a lot in the config file as an administrator.
atrol

~0054440

atrol (developer)

> Why would it decrease security?

Not sure, maybe I misunderstand what you mean with
> go through all logon methods after each other.

Does it mean you want to try if the entered password matches using one of the logon methods?
modir

~0054442

modir (reporter)

> Does it mean you want to try if the entered password matches using one of the logon methods?

Yes, correct. That's what it means.

I have several problems to solve at once.

1) My client is migrating all users from one Active Directory to another one. In order to make the migration easier we try the logon first on the old AD and it is not possible then we try it on the new one. (There is absolutely no security problem as both domains are under control of one team.)

2) We have several user accounts which are only used by interfaces (e.g. a "SOAP user"). The client would like to have this user in the future in the local user table and not in Active Directory. What I understand, as it doesn't make much sense to treat such a "technical user" like a normal user account. It will be too complicated to specify if a user should be authenticated locally or remotely. Hence I would make this flexible and would allow one array of different authentication methods.
modir

~0054485

modir (reporter)

I created now a fork where I added the functionality. You can look at it here:

https://github.com/modir/mantisbt/commits/master

I solved several problems at once so we could close several issues here. When you follow my commits you see that I went through these steps:

1) Migrated the whole LDAP code into one class. (Except for functions which are widely used all over the code where I didn't had the time for it yet.)

2) Added the possibility to define "login_method" as an array so that e.g. the login with LDAP and locally is possible.

3) Migrated all the LDAP config parameters into one array. (The reason behind is that all parameters belong together. It doesn't make sense to define e.g the bind user but not to which server we should connect to.)

4) I changed the code so that we could provide an array of LDAP config arrays.

This code is based on the 2.0.0 code and is now in use at one client.

Ideal would be if we can merge all into your code base. But I am happy as well if e.g only 1 and 2 are merge. The less I have to keep separate the better.

Before I create a push/pull request I thought it is better to discuss it here.
+Notes

-Issue History
Date Modified Username Field Change
2008-12-10 06:49 Kirill New Issue
2008-12-12 02:47 vboctor Note Added: 0020352
2008-12-12 02:47 vboctor Status new => feedback
2008-12-12 05:05 Kirill Note Added: 0020357
2008-12-12 14:21 grangeway Note Added: 0020363
2008-12-13 11:27 Kirill Note Added: 0020366
2009-07-05 21:11 vboctor Relationship added has duplicate 0007011
2009-10-27 23:29 vboctor Status feedback => acknowledged
2010-05-13 07:22 AlexM600 Note Added: 0025494
2010-05-13 07:22 AlexM600 File Added: multildap.patch
2010-05-13 07:25 AlexM600 Note Added: 0025495
2010-06-04 10:42 mikehelms Note Added: 0025708
2010-07-06 12:21 paontis Note Added: 0026026
2010-07-08 12:19 paontis Note Added: 0026041
2011-04-04 04:38 kgron Note Added: 0028520
2011-04-29 07:14 paontis Note Added: 0028720
2011-12-12 03:29 pigbrain Note Added: 0030555
2012-01-22 05:34 grangeway Note Added: 0030991
2012-01-22 05:34 grangeway Status acknowledged => resolved
2012-01-22 05:34 grangeway Fixed in Version => 1.3.0-beta.1
2012-01-22 05:34 grangeway Resolution open => fixed
2012-01-22 05:34 grangeway Assigned To => grangeway
2013-04-05 17:57 grangeway Status resolved => acknowledged
2013-04-05 17:57 grangeway Note Added: 0036296
2013-04-05 18:26 grangeway Relationship added related to 0015721
2013-04-06 09:26 dregad Tag Attached: 2.0.x check
2013-04-06 09:26 dregad Status acknowledged => resolved
2013-04-27 16:58 atrol Assigned To grangeway =>
2013-04-27 16:58 atrol Status resolved => new
2013-04-27 16:58 atrol Resolution fixed => open
2013-04-27 16:58 atrol Fixed in Version 1.3.0-beta.1 =>
2014-09-23 18:05 grangeway Tag Detached: 2.0.x check
2016-03-29 17:30 dregad Relationship added related to 0020769
2016-09-23 02:58 atrol Note Added: 0054059
2016-10-27 13:10 modir Note Added: 0054349
2016-11-01 10:42 atrol Note Added: 0054362
2016-11-01 12:02 modir Note Added: 0054366
2016-11-06 06:35 atrol Note Added: 0054440
2016-11-06 07:52 modir Note Added: 0054442
2016-11-09 05:28 modir Note Added: 0054485
+Issue History