View Issue Details

IDProjectCategoryView StatusLast Update
0009954mantisbtldappublic2021-01-17 06:12
ReporterKirill Assigned Todregad  
PrioritynormalSeverityfeatureReproducibilityhave not tried
Status closedResolutionno change required 
PlatformWindowsOSWindows XPOS Version1.1.0
Product Version1.1.5 
Summary0009954: More than one ldap-server
Description

I 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
multildap.patch (8,862 bytes)   
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' ) ?>
multildap.patch (8,862 bytes)   

Relationships

related to 0015721 closedgrangeway Functionality to consider porting to master-2.0.x 
has duplicate 0007011 closedvboctor Ability to authenticate against multiple LDAP directories 
has duplicate 0026633 closedvboctor Ldap connection to multiple domains 
related to 0020769 closeddregad New functionnality : LDAP fallback server OR round robin 

Activities

vboctor

vboctor

2008-12-12 02:47

manager   ~0020352

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

Kirill

Kirill

2008-12-12 05:05

reporter   ~0020357

Yes. All users unique

grangeway

grangeway

2008-12-12 14:21

reporter   ~0020363

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

Kirill

2008-12-13 11:27

reporter   ~0020366

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

AlexM600

AlexM600

2010-05-13 07:22

reporter   ~0025494

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

AlexM600

2010-05-13 07:25

reporter   ~0025495

Please, somebody check it for possible bugs.

mikehelms

mikehelms

2010-06-04 10:42

reporter   ~0025708

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

paontis

2010-07-06 12:21

reporter   ~0026026

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

paontis

2010-07-08 12:19

reporter   ~0026041

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

kgron

2011-04-04 04:38

reporter   ~0028520

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

paontis

2011-04-29 07:14

reporter   ~0028720

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

pigbrain

2011-12-12 03:29

reporter   ~0030555

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

grangeway

2012-01-22 05:34

reporter   ~0030991

The 1.3 series will support an array of ldap servers

grangeway

grangeway

2013-04-05 17:57

reporter   ~0036296

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

atrol

atrol

2016-09-23 02:58

developer   ~0054059

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

modir

modir

2016-10-27 13:10

reporter   ~0054349

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

atrol

2016-11-01 10:42

developer   ~0054362

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

modir

2016-11-01 12:02

reporter   ~0054366

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

atrol

2016-11-06 06:35

developer   ~0054440

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

modir

2016-11-06 07:52

reporter   ~0054442

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

modir

2016-11-09 05:28

reporter   ~0054485

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.

dregad

dregad

2017-01-05 06:52

developer   ~0054939

Sorry for the lack of response, this fell off the radar.

I commented in the PR you just submitted https://github.com/mantisbt/mantisbt/pull/984

dregad

dregad

2021-01-06 18:29

developer   ~0064948

Last edited: 2021-01-06 18:31

As mentioned by @rogueresearch in 0020769:0064943 , ldap_connect() accepts a space-separated list of servers (specified as LDAP URIs) [1]. That should satisfy this issue's requirements, so I'm closing it as no change required.

Note: this will be better documented when PR https://github.com/mantisbt/mantisbt/pull/1727 is merged.