View Issue Details

This bug affects 1 person(s).
 16
IDProjectCategoryView StatusLast Update
10323Bug reportsAuthenticationpublic2016-05-17 12:41
Reporteremmarichardson Assigned Toc_schmitz  
PriorityhighSeveritypartial_block 
Status closedResolutionfixed 
Product Version2.50.x 
Fixed in Version2.50.x 
Summary10323: LDAP Authentication not working after 2.5 upgrade
Description

I have LDAP authentication set up for Search and Bind our with our MSAD server. It was working successfully and I was able to log in as an AD user and the user was automatically created in Limesurvey.

I then upgraded to 2.5. I can still log in as the existing LDAP user in Limesurvey but cannot log in as any new user. I get the error message Incorrect username/password.

I ran ldapsearch from the limesurvey server to check that there was not a problem between the two servers and was able to connect successfully and verify a user.

Also, I have the LDAP set as default authentication method but login page does not default to LDAP. It defaults instead to Internal Database so LDAP has to be manually selected everytime.

Steps To Reproduce

Set up LDAP Auth to Search and Bind.
Try to log in as AS user that does not already exist in Limesurvey.

Additional Information

I tried reinstalling and checking ownership and permissions but still no luck.

TagsNo tags attached.
Attached Files
AuthLDAP.php (20,415 bytes)   
<?php
class AuthLDAP extends ls\pluginmanager\AuthPluginBase
{
    protected $storage = 'DbStorage';

    static protected $description = 'Core: LDAP authentication';
    static protected $name = 'LDAP';

    /**
     * Can we autocreate users? For the moment this is disabled, will be moved
     * to a setting when we have more robust user creation system.
     *
     * @var boolean
     */
    protected $autoCreate = false;

    protected $settings = array(
        'server' => array(
            'type' => 'string',
            'label' => 'Ldap server',
            'help' => 'e.g. ldap://ldap.example.com or ldaps://ldap.example.com'
            ),
        'ldapport' => array(
            'type' => 'string',
            'label' => 'Port number',
            'help' => 'Default when omitted is 389',
            ),
        'ldapversion' => array(
            'type' => 'select',
            'label' => 'LDAP version',
            'options' => array('2' => 'LDAPv2', '3'  => 'LDAPv3'),
            'default' => '2',
            'submitonchange'=> true
            ),
        'ldapoptreferrals' => array(
            'type' => 'boolean',
            'label' => 'Select true if referrals must be followed (use false for ActiveDirectory)',
            'default' => '0'
            ),
        'ldaptls' => array(
            'type' => 'boolean',
            'help' => 'Check to enable Start-TLS encryption, when using LDAPv3',
            'label' => 'Enable Start-TLS',
            'default' => '0'
            ),
        'ldapmode' => array(
            'type' => 'select',
            'label' => 'Select how to perform authentication.',
            'options' => array("simplebind" => "Simple bind", "searchandbind" => "Search and bind"),
            'default' => "simplebind",
            'submitonchange'=> true
            ),
        'userprefix' => array(
            'type' => 'string',
            'label' => 'Username prefix',
            'help' => 'e.g. cn= or uid=',
            ),
        'domainsuffix' => array(
                'type' => 'string',
                'label' => 'Username suffix',
                'help' => 'e.g. @mydomain.com or remaining part of ldap query',
                ),
        'searchuserattribute' => array(
                'type' => 'string',
                'label' => 'Attribute to compare to the given login can be uid, cn, mail, ...'
                ),
        'usersearchbase' => array(
                'type' => 'string',
                'label' => 'Base DN for the user search operation'
                ),
        'extrauserfilter' => array(
                'type' => 'string',
                'label' => 'Optional extra LDAP filter to be ANDed to the basic (searchuserattribute=username) filter. Don\'t forget the outmost enclosing parentheses'
                ),
        'binddn' => array(
                'type' => 'string',
                'label' => 'Optional DN of the LDAP account used to search for the end-user\'s DN. An anonymous bind is performed if empty.'
                ),
        'bindpwd' => array(
                'type' => 'password',
                'label' => 'Password of the LDAP account used to search for the end-user\'s DN if previoulsy set.'
                ),
        'mailattribute' => array(
                'type' => 'string',
                'label' => 'LDAP attribute of email address'
                ),
        'fullnameattribute' => array(
                'type' => 'string',
                'label' => 'LDAP attribute of full name'
                ),
        'is_default' => array(
                'type' => 'checkbox',
                'label' => 'Check to make default authentication method'
                ),
        'autocreate' => array(
                'type' => 'checkbox',
                'label' => 'Automatically create user if it exists in LDAP server'
                ),
        'automaticsurveycreation' => array(
                'type' => 'checkbox',
                'label' => 'Grant survey creation permission to automatically created users'
                )
    );

    public function init() {
        /**
         * Here you should handle subscribing to the events your plugin will handle
         */
        $this->subscribe('beforeActivate');
        $this->subscribe('createNewUser');
        $this->subscribe('beforeLogin');
        $this->subscribe('newLoginForm');
        $this->subscribe('afterLoginFormSubmit');
        $this->subscribe('newUserSession');
    }

    /**
     * Check availability of LDAP Apache Module
     *
     * @return unknown_type
     */
    public function beforeActivate()
    {
        if (!function_exists("ldap_connect")){
            $event = $this->getEvent();
            $event->set('success', false);

            $event->set('message', gT("LDAP authentication failed: LDAP PHP module is not available."));
        }
    }

    /**
     * Create a LDAP user
     *
     * @return unknown_type
     */
    public function createNewUser()
    {
        // Do nothing if the user to be added is not LDAP type
        if (flattenText(Yii::app()->request->getPost('user_type')) != 'LDAP')
        {
            return;
        }

        $this->_createNewUser(flattenText(Yii::app()->request->getPost('new_user'), false, true));
    }

    /**
     * Create a LDAP user
     *
     * @param string $new_user
     * @return null|string New user ID
     */
    private function _createNewUser($new_user)
    {
        $oEvent = $this->getEvent();

        // Get configuration settings:
        $ldapserver     = $this->get('server');
        $ldapport       = $this->get('ldapport');
        $ldapmode       = $this->get('ldapmode');
        $searchuserattribute    = $this->get('searchuserattribute');
        $extrauserfilter      = $this->get('extrauserfilter');
        $usersearchbase   = $this->get('usersearchbase');
        $binddn         = $this->get('binddn');
        $bindpwd        = $this->get('bindpwd');
        $mailattribute = $this->get('mailattribute');
        $fullnameattribute = $this->get('fullnameattribute');

        // Try to connect
        $ldapconn = $this->createConnection();
        if (!is_resource($ldapconn))
        {
            $oEvent->set('errorCode',self::ERROR_LDAP_CONNECTION);
            $oEvent->set('errorMessageTitle','');
            $oEvent->set('errorMessageBody',$ldapconn['errorMessage']);
            return null;
        }

        if (empty($ldapmode) || $ldapmode=='simplebind')
        {
            $oEvent->set('errorCode',self::ERROR_LDAP_MODE);
            $oEvent->set('errorMessageTitle',gT("Failed to add user"));
            $oEvent->set('errorMessageBody',gT("Simple bind LDAP configuration doesn't allow LDAP user creation"));
            return null;
        }

        // Search email address and full name
        if (empty($binddn))
        {
            // There is no account defined to do the LDAP search,
            // let's use anonymous bind instead
            $ldapbindsearch = @ldap_bind($ldapconn);
        }
       else
        {
            // An account is defined to do the LDAP search, let's use it
            $ldapbindsearch = @ldap_bind($ldapconn, $binddn, $bindpwd);
        }
        if (!$ldapbindsearch) {
            $oEvent->set('errorCode',self::ERROR_LDAP_NO_BIND);
            $oEvent->set('errorMessageTitle',gT('Could not connect to LDAP server.'));
            $oEvent->set('errorMessageBody',gT(ldap_error($ldapconn)));
            ldap_close($ldapconn); // all done? close connection
            return null;
        }
        // Now prepare the search fitler
        if ( $extrauserfilter != "")
        {
            $usersearchfilter = "(&($searchuserattribute=$new_user)$extrauserfilter)";
        }
        else
        {
            $usersearchfilter = "($searchuserattribute=$new_user)";
        }
        // Search for the user
        $dnsearchres = ldap_search($ldapconn, $usersearchbase, $usersearchfilter, array($mailattribute,$fullnameattribute));
        $rescount=ldap_count_entries($ldapconn,$dnsearchres);
        if ($rescount == 1)
        {
            $userentry=ldap_get_entries($ldapconn, $dnsearchres);
            $new_email = flattenText($userentry[0][$mailattribute][0]);
            $new_full_name = flattenText($userentry[0][strtolower($fullnameattribute)][0]);
        }
        else
        {
            $oEvent->set('errorCode',self::ERROR_LDAP_NO_SEARCH_RESULT);
            $oEvent->set('errorMessageTitle',gT('Username not found in LDAP server'));
            $oEvent->set('errorMessageBody',gT('Verify username and try again'));
            ldap_close($ldapconn); // all done? close connection
            return null;
        }

        if (!validateEmailAddress($new_email))
        {
            $oEvent->set('errorCode',self::ERROR_INVALID_EMAIL);
            $oEvent->set('errorMessageTitle',gT("Failed to add user"));
            $oEvent->set('errorMessageBody',gT("The email address is not valid."));
            return null;
        }
        $new_pass = createPassword();
        // If user is being auto created we set parent ID to 1 (admin user)
        if (isset(Yii::app()->session['loginID']))
        {
            $parentID = Yii::app()->session['loginID'];
        }
        else
        {
            $parentID = 1;
        }
        $iNewUID = User::model()->insertUser($new_user, $new_pass, $new_full_name, $parentID, $new_email);
        if (!$iNewUID)
        {
            $oEvent->set('errorCode',self::ERROR_ALREADY_EXISTING_USER);
            $oEvent->set('errorMessageTitle','');
            $oEvent->set('errorMessageBody',gT("Failed to add user"));
            return null;
        }

        Permission::model()->setGlobalPermission($iNewUID,'auth_ldap');

        $oEvent->set('newUserID',$iNewUID);
        $oEvent->set('newPassword',$new_pass);
        $oEvent->set('newEmail',$new_email);
        $oEvent->set('newFullName',$new_full_name);
        $oEvent->set('errorCode',self::ERROR_NONE);
        return $iNewUID;
    }

    /**
     * Create LDAP connection
     *
     * @return mixed
     */
    private function createConnection()
    {
        // Get configuration settings:
        $ldapserver     = $this->get('server');
        $ldapport       = $this->get('ldapport');
        $ldapver        = $this->get('ldapversion');
        $ldaptls        = $this->get('ldaptls');
        $ldapoptreferrals = $this->get('ldapoptreferrals');

        if (empty($ldapport)) {
            $ldapport = 389;
        }

        // Try to connect
        $ldapconn = ldap_connect($ldapserver, (int) $ldapport);
        if (false == $ldapconn) {
            return array( "errorCode" => 1, "errorMessage" => gT('Error creating LDAP connection') );
        }

        // using LDAP version
        if ($ldapver === null)
        {
            // If the version hasn't been set, default = 2
            $ldapver = 2;
        }

        ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, $ldapver);
        ldap_set_option($ldapconn, LDAP_OPT_REFERRALS, $ldapoptreferrals);

        if (!empty($ldaptls) && $ldaptls == '1' && $ldapver == 3 && preg_match("/^ldaps:\/\//", $ldapserver) == 0 )
        {
            // starting TLS secure layer
            if(!ldap_start_tls($ldapconn))
            {
                ldap_close($ldapconn); // all done? close connection
                return array( "errorCode" => 100, 'errorMessage' => ldap_error($ldapconn) );
            }
        }

        return $ldapconn;
    }

    public function beforeLogin()
    {
        if ($this->get('is_default', null, null, false) == true) {
            // This is configured to be the default login method
            $this->getEvent()->set('default', get_class($this));
        }
    }

    public function newLoginForm()
    {
        $this->getEvent()->getContent($this)
            ->addContent(CHtml::tag('li', array(), "<label for='user'>"  . gT("Username") . "</label><input name='user' id='user' type='text' size='40' maxlength='40' value='' />"))
            ->addContent(CHtml::tag('li', array(), "<label for='password'>"  . gT("Password") . "</label><input name='password' id='password' type='password' size='40' maxlength='40' value='' />"));
    }

    /**
     * Modified getPluginSettings since we have a select box that autosubmits
     * and we only want to show the relevant options.
     *
     * @param boolean $getValues
     * @return array
     */
    public function getPluginSettings($getValues = true)
    {
        $aPluginSettings = parent::getPluginSettings($getValues);
        if ($getValues) {
            $ldapmode = $aPluginSettings['ldapmode']['current'];
            $ldapver = $aPluginSettings['ldapversion']['current'];

            // If it is a post request, it could be an autosubmit so read posted
            // value over the saved value
            if (App()->request->isPostRequest) {
                $ldapmode = App()->request->getPost('ldapmode', $ldapmode);
                $aPluginSettings['ldapmode']['current'] = $ldapmode;
                $ldapver = App()->request->getPost('ldapversion', $ldapver);
                $aPluginSettings['ldapversion']['current'] = $ldapver;
            }

            if ($ldapver == '2' ) {
               unset($aPluginSettings['ldaptls']);
            }

            if ($ldapmode == 'searchandbind') {
                // Hide simple settings
                unset($aPluginSettings['userprefix']);
                unset($aPluginSettings['domainsuffix']);

            } else {
                // Hide searchandbind settings
                unset($aPluginSettings['searchuserattribute']);
                unset($aPluginSettings['usersearchbase']);
                unset($aPluginSettings['extrauserfilter']);
                unset($aPluginSettings['binddn']);
                unset($aPluginSettings['bindpwd']);
                unset($aPluginSettings['ldapoptreferrals']);
                unset($aPluginSettings['mailattribute']);
                unset($aPluginSettings['fullnameattribute']);
                unset($aPluginSettings['autocreate']);
                unset($aPluginSettings['automaticsurveycreation']);
            }
        }

        return $aPluginSettings;
    }

    public function newUserSession()
    {
        // Do nothing if this user is not AuthLDAP type
        $identity = $this->getEvent()->get('identity');
        if ($identity->plugin != 'AuthLDAP')
        {
            return;
        }

        // Here we do the actual authentication
        $username = $this->getUsername();
        $password = $this->getPassword();

        $ldapmode = $this->get('ldapmode');
        $autoCreateFlag = false;
        $user = $this->api->getUserByName($username);
        // No user found!
        if ($user === null)
        {
            // If ldap mode is searchandbind and autocreation is enabled we can continue
            if ($ldapmode=='searchandbind' && $this->get('autocreate', null, null, false) == true)
            {
                $autoCreateFlag = true;
            }
            else
            {
              // If the user doesnt exist in the LS database, he can not login
              $this->setAuthFailure(self::ERROR_USERNAME_INVALID);
              return;
            }
        }
        if ($user !== null && ($user->uid == 1 || !Permission::model()->hasGlobalPermission('auth_ldap','read',$user->uid)))
        {
            $this->setAuthFailure(self::ERROR_AUTH_METHOD_INVALID, gT('LDAP authentication method is not allowed for this user'));
            return;
        }

        if (empty($password))
        {
            // If password is null or blank reject login
            // This is necessary because in simple bind ldap server authenticates with blank password
            $this->setAuthFailure(self::ERROR_PASSWORD_INVALID);
            return;
        }

        // Get configuration settings:
        $ldapserver 		= $this->get('server');
        $ldapport   		= $this->get('ldapport');
        $suffix     		= $this->get('domainsuffix');
        $prefix     		= $this->get('userprefix');
        $searchuserattribute    = $this->get('searchuserattribute');
        $extrauserfilter    	= $this->get('extrauserfilter');
        $usersearchbase		= $this->get('usersearchbase');
        $binddn     		= $this->get('binddn');
        $bindpwd     		= $this->get('bindpwd');

        // Try to connect
        $ldapconn = $this->createConnection();
        if (!is_resource($ldapconn))
        {
            $this->setAuthFailure($ldapconn['errorCode'], gT($ldapconn['errorMessage']));
            return;
        }

        if (empty($ldapmode) || $ldapmode=='simplebind')
        {
            // in simple bind mode we know how to construct the userDN from the username
            $ldapbind = @ldap_bind($ldapconn, $prefix . $username . $suffix, $password);
        }
        else
        {
            // in search and bind mode we first do a LDAP search from the username given
            // to foind the userDN and then we procced to the bind operation
            if (empty($binddn))
            {
                // There is no account defined to do the LDAP search,
                // let's use anonymous bind instead
                $ldapbindsearch = @ldap_bind($ldapconn);
            }
            else
            {
                // An account is defined to do the LDAP search, let's use it
                $ldapbindsearch = @ldap_bind($ldapconn, $binddn, $bindpwd);
            }
            if (!$ldapbindsearch) {
                $this->setAuthFailure(100, ldap_error($ldapconn));
                ldap_close($ldapconn); // all done? close connection
                return;
            }
            // Now prepare the search fitler
            if ( $extrauserfilter != "")
            {
                $usersearchfilter = "(&($searchuserattribute=$username)$extrauserfilter)";
            }
            else
            {
                $usersearchfilter = "($searchuserattribute=$username)";
            }
            // Search for the user
            $dnsearchres = ldap_search($ldapconn, $usersearchbase, $usersearchfilter, array($searchuserattribute));
            $rescount=ldap_count_entries($ldapconn,$dnsearchres);
            if ($rescount == 1)
            {
                $userentry=ldap_get_entries($ldapconn, $dnsearchres);
                $userdn = $userentry[0]["dn"];
            }
            else
            {
                // if no entry or more than one entry returned
                // then deny authentication
                $this->setAuthFailure(100, ldap_error($ldapconn));
                ldap_close($ldapconn); // all done? close connection
                return;
            }

            // binding to ldap server with the userDN and privided credentials
            $ldapbind = @ldap_bind($ldapconn, $userdn, $password);
        }

        // verify user binding
        if (!$ldapbind) {
            $this->setAuthFailure(100, ldap_error($ldapconn));
            ldap_close($ldapconn); // all done? close connection
            return;
        }

        // Authentication was successful, now see if we have a user or that we should create one
        if (is_null($user) && !$autoCreateFlag) {
                $this->setAuthFailure(self::ERROR_USERNAME_INVALID);
                ldap_close($ldapconn); // all done? close connection
                return;
        }

        ldap_close($ldapconn); // all done? close connection

        // Finally, if user didn't exist and auto creation is enabled, we create it
        if ($autoCreateFlag)
        {
            if (($iNewUID = $this->_createNewUser($username)) && $this->get('automaticsurveycreation', null, null, false))
            {
                Permission::model()->setGlobalPermission($iNewUID, 'surveys', array('create_p'));
            }
            $user = $this->api->getUserByName($username);
            if ($user === null)
            {
                $this->setAuthFailure(self::ERROR_USERNAME_INVALID, gT('Credentials are valid but we failed to create a user'));
                return;
            }
        }
        // If we made it here, authentication was a success and we do have a valid user
        $this->pluginManager->dispatchEvent(new PluginEvent('newUserLogin', $this));
        $this->setAuthSuccess($user);
    }
}
AuthLDAP.php (20,415 bytes)   
Bug heat16
Complete LimeSurvey version number (& build)Version 2.50+ Build 160206
I will donate to the project if issue is resolvedNo
BrowserChrome/Safari/Firefox
Database type & versionMysql
Server OS (if known)Linux Debian
Webserver software & version (if known)Apache2
PHP Version5.4.45

Relationships

has duplicate 11167 closedc_schmitz LDAP Authentication -> automatically create user not working 

Users monitoring this issue

There are no users monitoring this issue.

Activities

emmarichardson

emmarichardson

2016-03-09 17:50

reporter   ~36234

Curious as to why this has been dropped to low. Is being able to login to Lime Survey not of some importance?

LouisGac

LouisGac

2016-03-10 09:41

developer   ~36250

just mean that we'll resolve it later.
reproducing the bug, finding it, and fixing it, will probably take a lot of time.
So we'll do it when the other critical bugs will be corrected (probably less than one month).
So it's more about organizing our work.

emmarichardson

emmarichardson

2016-04-05 20:36

reporter   ~37017

Update on this.
The authentication part works if I first add a user in LimeSurvey. What does not work is the automatic creation of users that just try logging in.
Also, when the automatic creation did work (prior to Jan/Feb upgrade), it did not automatically assign that user survey creation permission even though that option was selected.

georgrath

georgrath

2016-05-11 17:57

reporter   ~38380

I ran into the same problem.
The PR in https://github.com/LimeSurvey/LimeSurvey/pull/489 fixes the problem by backporting an older version of the plugin.

DenisChenu

DenisChenu

2016-05-11 18:01

developer   ~38381

Hi,

Actually : you can add your own plugin for LDAP:
Make a copŷ of core plugin in plugins directory

Renampe all Class name/function name/ dir name / file name from AuthLDAP to AuthLDAP2

And you'r done.

georgrath

georgrath

2016-05-11 18:29

reporter   ~38383

Seeing that AuthLDAP is a core plugin and that it was broken after an update without prior notice, I thought that this might warrant inclusion of this fix to upstream. Maintaining my own plugin is not an option for me.

The PR removed functionality before this comment (did not fire PluginEvent newUserLogin), so I re-added that - it now only falls back to the 'old' user creation behaviour instead of doing it by default.

For clarification: is this a bug or has the user creation feature been removed on purpose?

emmarichardson

emmarichardson

2016-05-11 18:50

reporter   ~38384

Seeing as the option is still there asking to create users, I would have to say it is a bug. I agree - why would this not be fixed?
Thank you for the fix Georgrath - at least I can now get it working until it is resolved.

c_schmitz

c_schmitz

2016-05-12 09:32

administrator   ~38390

Last edited: 2016-05-12 09:32

Thank you for the effort with the PR but the patch is unfortunately bogus - there is just a bug in the current implementation.

Can you please check the attached file, set autocreation in the plugin settings to true, if it works for you ?

The files replaces the one at application\core\plugins\AuthLDAP

georgrath

georgrath

2016-05-12 10:22

reporter   ~38400

Seems to work.

emmarichardson

emmarichardson

2016-05-12 15:38

reporter   ~38489

Yes, seems to work as expected - thank you!

c_schmitz

c_schmitz

2016-05-12 16:00

administrator   ~38492

Fix committed to master branch: http://bugs.limesurvey.org/plugin.php?page=Source/view&amp;id=19018

c_schmitz

c_schmitz

2016-05-17 12:41

administrator   ~38618

Version 2.50+ Build 160516 released

Related Changesets

LimeSurvey: master 9c19c83d

2016-05-12 13:59:24

c_schmitz

Details Diff
Fixed issue 10323: LDAP Authentication not working Affected Issues
10323
mod - application/core/plugins/AuthLDAP/AuthLDAP.php Diff File

Issue History

Date Modified Username Field Change
2016-02-06 17:00 emmarichardson New Issue
2016-02-06 17:00 emmarichardson File Added: Screen Shot 2016-02-06 at 8.58.05 AM.png
2016-02-07 20:43 c_schmitz Assigned To => LouisGac
2016-02-07 20:43 c_schmitz Status new => assigned
2016-02-17 14:44 c_schmitz Priority urgent => normal
2016-03-09 17:00 LouisGac Priority normal => low
2016-03-09 17:50 emmarichardson Note Added: 36234
2016-03-10 09:41 LouisGac Note Added: 36250
2016-04-05 20:36 emmarichardson Note Added: 37017
2016-04-07 18:20 LouisGac Assigned To LouisGac =>
2016-05-03 09:54 c_schmitz Priority low => high
2016-05-03 09:54 c_schmitz Status assigned => new
2016-05-11 17:57 georgrath Note Added: 38380
2016-05-11 18:01 DenisChenu Note Added: 38381
2016-05-11 18:29 georgrath Note Added: 38383
2016-05-11 18:50 emmarichardson Note Added: 38384
2016-05-12 09:16 c_schmitz Assigned To => c_schmitz
2016-05-12 09:16 c_schmitz Status new => assigned
2016-05-12 09:32 c_schmitz Note Added: 38390
2016-05-12 09:32 c_schmitz File Added: AuthLDAP.php
2016-05-12 09:32 c_schmitz Note Edited: 38390
2016-05-12 09:33 c_schmitz Status assigned => feedback
2016-05-12 10:22 georgrath Note Added: 38400
2016-05-12 14:30 c_schmitz Relationship added has duplicate 11167
2016-05-12 15:38 emmarichardson Note Added: 38489
2016-05-12 15:38 emmarichardson Status feedback => assigned
2016-05-12 16:00 c_schmitz Changeset attached => LimeSurvey master 9c19c83d
2016-05-12 16:00 c_schmitz Note Added: 38492
2016-05-12 16:00 c_schmitz Resolution open => fixed
2016-05-12 17:25 c_schmitz Status assigned => resolved
2016-05-12 17:25 c_schmitz Fixed in Version => 2.5
2016-05-17 12:41 c_schmitz Note Added: 38618
2016-05-17 12:41 c_schmitz Status resolved => closed