ldapauth with imapauth problem

Get help from the community here.

Moderator: Developers

mathias
Posts: 13
Joined: Tue Jan 26, 2010 10:46 am

ldapauth with imapauth problem

Postby mathias » Tue Jan 26, 2010 12:44 pm

Hi,

I'm experiencing a problem when adding users automatically during logon.

I'm running GO pro 3.3.11 on an Ubuntu 9.04 x64 server. I have set up the mail server as suggested in the guide at http://www.group-office.com/wiki/Mailserver. I have also installed the modules Postfix admin, Serverclient and ldapauth. LDAP-authentication works fine and a user account is created in GO during first logon. When I add users manually in GO automatic creation of e-mailaccounts works as well. But when I try to automatically add an account in both GO and the imap-server during logon by placing imapauth.config.php alongside config.php and setting 'create_email_account' => true I get the error:

"Warning: Failed creating e-mail account for user testuser in imapauth module. in /var/www/modules/imapauth/classes/imapauth.class.inc.php on line 165

Warning: Cannot modify header information - headers already sent by (output started at /var/www/modules/imapauth/classes/imapauth.class.inc.php:165) in /var/www/action.php on line 177
{"success":true,"user_id":"21","name":"Test Testare"}Ext.decode exception occurred"

I have tried double checking everything but to no avail. This is supposed to work isn't it?

Any suggestion would be appreciated.

//Mathias
mschering
Site Admin
Site Admin
Posts: 8154
Joined: Tue Apr 20, 2004 1:06 pm
Location: The Netherlands - Den Bosch
Contact:

Re: ldapauth with imapauth problem

Postby mschering » Fri Jan 29, 2010 10:08 am

It fails to connect to the IMAP server. You must check all parameters that are used to connect.
Best regards,

Merijn Schering
Intermesh
mathias
Posts: 13
Joined: Tue Jan 26, 2010 10:46 am

Re: ldapauth with imapauth problem

Postby mathias » Fri Jan 29, 2010 3:49 pm

Hm, the parameters have been right all along. The problem was that I misunderstood the function of the "ldapauth combined with imapauth.config.php"-feature. I thought that if a user logs in and authenticate with a ldap-server, a new account is created in Group-office AND on the imap-server and linked with each other. (Just like when I use the serverclient-module to create a user on the imap-server when adding accounts manually in Group-office.) Not that it created an account in Group-office and tried to link this to an EXISTING account on the imap-server. Now I get it after digging through some of the code.

What I'm after is this: When a user tries to authenticate with Group-office, GO checks the ldap-server (which gets it's data from our Active directory) if the logon-info is correct and if the ldap-account has an email-address specified in one of the domains that the GO-server hosts. If the checks go through and the user has never logged on to GO, a GO-account and an email-account should be created.

All this works today aside from the last part, automatic creation of an account on the imap-server. (I had to tinker a bit with the ldap-auth code since our ldap-server requiers a bind-operation to be performed before any query will be executed.)

I guess I'll have a go at setting this up myself. Or has anyone done this? Shouldn't be all to hard, or what do you think? Handling of multiple aliases gathered from the ldap-data would be nice as well...

Lastly I must thank you for a great product. Group-office is by far one of the most promising pieces of code I've seen in some time. Keep up the good work!

/Mathias
mschering
Site Admin
Site Admin
Posts: 8154
Joined: Tue Apr 20, 2004 1:06 pm
Location: The Netherlands - Den Bosch
Contact:

Re: ldapauth with imapauth problem

Postby mschering » Fri Jan 29, 2010 4:54 pm

But you can set all the right IMAP parameters in the config file right? What happens if you debug the code what does it use to connect to the IMAP server?


Could you post a small howto for an ActiveDirectory environment?
Best regards,



Merijn Schering

Intermesh
mathias
Posts: 13
Joined: Tue Jan 26, 2010 10:46 am

Re: ldapauth with imapauth problem

Postby mathias » Mon Feb 22, 2010 12:27 pm

I've made some changes to the Group-Office code to get what I want.

This involved changing three files, imapauth.class.inc.php, ldapauth.class.inc.php and serverclient.class.inc.php. This way I use the serverclient to create users on the imap-server during logon just as I would when manually adding users. Should I post the changes I made here in the forum (I guess 'General help' is not really the right branch for this) or do you want me to e-mail them to you for review. Maybe this setup could be useful for other users as well.

Regarding an Active Directory-tutorial I can put something together as soon as I get the time.

/Mathias
thomason
Posts: 4
Joined: Wed Mar 03, 2010 10:44 am

Re: ldapauth with imapauth problem

Postby thomason » Wed Mar 03, 2010 10:58 am

Mathias,
What code did you tinker with...
I had to tinker a bit with the ldap-auth code since our ldap-server requiers a bind-operation to be performed before any query will be executed.


When I debug the ldapauth code, the bind() method never gets called prior to the login attempt.

Once I get past this step, I assume I'm going to run into the same issue you are having with imapauth and automatic account creation.

Our company really wants to buy this software (pro version), but if these features are broken, I can't recommend the product (and I REALLY like GO!).

Intermesh, can you please look @ Mathias' patches and push an update to the Debian repository? Please...

Thanks a million,
John Thomason
mschering
Site Admin
Site Admin
Posts: 8154
Joined: Tue Apr 20, 2004 1:06 pm
Location: The Netherlands - Den Bosch
Contact:

Re: ldapauth with imapauth problem

Postby mschering » Wed Mar 03, 2010 11:19 am

But he didn't submit any patches yet.

As far as I know the LDAP authentication works perfecty already with open ldap. I'm just not sure about ActiveDirectory.
Best regards,



Merijn Schering

Intermesh
thomason
Posts: 4
Joined: Wed Mar 03, 2010 10:44 am

Re: ldapauth with imapauth problem

Postby thomason » Wed Mar 03, 2010 12:00 pm

Intermesh,
Yes, with OpenLdap the code should work because openldap allows anonymous binding to the directory tree.

Active Directory, on the other hand, requires you to bind with an authorized user before making the authentication query to the DIT.

Here's the actual LDAP_ERR from tcpdump (captured during a login request)...

Code: Select all

tcpdump -nn -X -s0 port 389

Ldap_Err: DSID-0C090627, comment: In order to perform this operation a sucessful bind must be completed on the connection


As for patches, Mathias asked:

Should I post the changes I made here in the forum (I guess 'General help' is not really the right branch for this) or do you want me to e-mail them to you for review. Maybe this setup could be useful for other users as well.


Thanks for all the help, GO is a Gem!
John Thomason
mathias
Posts: 13
Joined: Tue Jan 26, 2010 10:46 am

Re: ldapauth with imapauth problem

Postby mathias » Wed Mar 03, 2010 3:01 pm

Hi,

Sorry thomason, I didn't see your question until today.

The changes I made to get the ldap working is rather simple. I don't know if this modification breaks the ldapauth when using it with openldap. Maybe someone can test that?

Insert the following two lines on line 81 in "<group-office-dir>/modules/ldapauth/classes/ldapauth.class.inc.php":

Code: Select all

$ldap->connect($GO_CONFIG->ldap_host);
$ldap->bind();


It must be before the line

Code: Select all

$ldap->search('uid='.$username, $ldap->PeopleDN);


... so lines 81-83 in my ldapauth.class.inc.php looks like this:

Code: Select all

$ldap->connect($GO_CONFIG->ldap_host);
$ldap->bind();
$ldap->search('uid='.$username, $ldap->PeopleDN);


This will make a bind-request before performing the search. We are not connecting directly to our Active Directory servers to make the ldap query so I haven't tried that.

Hope this helps.

/Mathias
thomason
Posts: 4
Joined: Wed Mar 03, 2010 10:44 am

Re: ldapauth with imapauth problem

Postby thomason » Wed Mar 03, 2010 6:51 pm

Perfect...

Adding the connect and bind before the search works with ADS with one(1) minor change...

Code: Select all

$ldap->connect($GO_CONFIG->ldap_host);
$ldap->bind();
$ldap->search('sAMAccountName='.$username, $ldap->PeopleDN);


ADS uses "sAMAccountName" instead of "uid"

Now, how about the changes you made to imapauth to auto create the email account??? I can now authenticate against ADS, but the user does not have any email once they login.

Again, thanks for the help, and sorry about using ADS (LDAP is out of my area of control).

You guys Rock!
John
thomason
Posts: 4
Joined: Wed Mar 03, 2010 10:44 am

Re: ldapauth with imapauth problem

Postby thomason » Wed Mar 03, 2010 7:01 pm

Intermesh,
Here's the LDIF extract for an ADS user account:

Code: Select all

dn: CN=Bob Hope,OU=People,DC=example,DC=com
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: user
cn: Bob Hope
sn: Hope
givenName: Bob
distinguishedName: CN=Bob Hope,OU=People,DC=example,DC=com
instanceType: 4
whenCreated: 19990606134936.0Z
whenChanged: 19990606181555.0Z
displayName: Bob Hope
uSNCreated: 16948054
memberOf: CN=Users,DC=example,DC=com
memberOf: CN=Administrators,CN=Builtin,DC=example,DC=com
memberOf: CN=Domain Admins,CN=Users,DC=example,DC=com
uSNChanged: 16951415
name: Bob Hope
objectGUID:: XYZ9X/R+T0AugjjaHgZM3g==
userAccountControl: 66048
badPwdCount: 0
codePage: 0
countryCode: 0
badPasswordTime: 129084029491406250
lastLogoff: 0
lastLogon: 129121160556250000
pwdLastSet: 128907569765468750
primaryGroupID: 513
objectSid:: AQUAAAUUUUVAAAAgoumKBwJsAlDFwoyNRgAAA==
adminCount: 1
accountExpires: 9223372036854775807
logonCount: 36476
sAMAccountName: bhope
sAMAccountType: 805306368
userPrincipalName: bhope@example.com
objectCategory: CN=Person,CN=Schema,CN=Configuration,DC=example,DC=com
mail: bhope@example.com


Hope this helps for future ADS integration.
Cheers,
John Thomason
mschering
Site Admin
Site Admin
Posts: 8154
Joined: Tue Apr 20, 2004 1:06 pm
Location: The Netherlands - Den Bosch
Contact:

Re: ldapauth with imapauth problem

Postby mschering » Fri Mar 05, 2010 1:33 pm

I'll test this and hopefully it won't break openldap. Thanks!
Best regards,



Merijn Schering

Intermesh
mathias
Posts: 13
Joined: Tue Jan 26, 2010 10:46 am

Re: ldapauth with imapauth problem

Postby mathias » Tue Mar 09, 2010 12:53 pm

Ok, about imap-account creation I choose to begin by quoting myself :)

About the changes I made to Group-Office to automatically create user accounts on my imap server:
This involved changing three files, imapauth.class.inc.php, ldapauth.class.inc.php and serverclient.class.inc.php. This way I use the serverclient-module to create users on the imap-server during logon just as I would when manually adding users.


The files we need to change for this are located in modules/<module>/classes, for example <group-office folder>/modules/serverclient/classes/.

You do not need to install the imapauth-module in Group-Office as long as the imapauth-files are present on the server. Postfixadmin, ldapauth och serverclient need to be installed though. (This is done inside Group-Office -> modules.)

The parameters used in imapauth.class.inc.php are fetched from a file called imapauth.config.php that should be placed alongside the Group-Office config.php, for example in /etc/groupoffice/<your go domain>/.

My imapauth.config.php looks like this: (I have replaced the 'domains' and 'host' value for this example and you have to customize it to your needs of course)

Code: Select all

<?php
/**
 * For more information visit: http://www.group-office.com/wiki/IMAP_or_LDAP_authentication
 */
 
$config[] =
   array(         
   'proto' => 'imap',
   'domains' => 'my-go-domain.com',
   'host' => 'my-host.my-go-domain.com',
   'port' => '993',
   'ssl' => true,
   'novalidate_cert' => true,
   'mbroot' => '',
   'remove_domain_from_username' => false,
   'create_email_account' => true,
   'groups' => array('Internal'),
   'visible_groups' => array('Everyone', 'Internal'),
   'modules_read' => array('email', 'files', 'addressbook', 'calendar', 'tasks', 'notes', 'summary'),
   'modules_write' => array(),
   
   'smtp_host'=>'localhost',
   'smtp_port'=>'25',
   'smtp_encryption'=>'',
   'smtp_username'=>'',
   'smtp_password'=>'',
      
   'ldap_use_email_as_imap_username'=>false
   );
?>


One important thing to notice here is that I set 'ldap_use_email_as_imap_username' to 'false'. (See the note below about changes to ldapauth.class.inc.php)

Changes made to imapauth.class.inc.php:

On line 135 I've added the additional parameter '$name' since I want the name of the owner of the e-mail account to show up as a persons name and not his/her e-mail address (the e-mail address is still shown as well):

Code: Select all

protected function create_email_account($config, $user_id, $username, $password, $email, $name){


On line 160 you have to change $account from '$email' to '$name' for the above to work.

Code: Select all

$account['name']=$name;


Next we move on to ldapauth.class.inc.php:
Here I've changed how the account name info is gathered. I think I need to exlpain why I've done this. The ldap-query, performed during logon, returns an e-mailaddress in the form <first name>.<last name>@<domain>, according to our company standard. I don't want my users to have account names on the e-mail server in the same form as their e-mail addresses (which I believe is too long and would only be confusing). Hence the "ldap_use_email_as_imap_username => false"-statement above. The line changed below originally only allows for usernames in the form <username> or <users e-mail address> and the dovecot imap-server running on my system expects usernames to be in the form <username>@<domain>. That's why I've added the <domain>-part to the script. This might not be what you need so adjust to your liking. (Hope this isn't confusing.)

Change line 142 (might be line 140 if you haven't added the extra bind-information as mentioned earlier in this thread) to:

Code: Select all

$mail_username = empty($config['ldap_use_email_as_imap_username']) ? ($username.'@'.$domain) : $user['email'];

from: (original)

Code: Select all

$mail_username = empty($config['ldap_use_email_as_imap_username']) ? $username : $user['email'];


Move line 144 to 146 and change it to: (This is where the $name parameter is passed on to imapauth.class.inc.php.)

Code: Select all

$la->create_email_account($config, $user_id, $mail_username, $password, $user['email'], $name);

from: (original)

Code: Select all

$la->create_email_account($config, $user_id, $mail_username, $password,$user['email']);


Add the following to line 144: (This is to assign the value to the $name parameter.)

Code: Select all

$name = String::format_name($user);


This far the changes have been mostly cosmetic but the next change is what makes the script create an account on the imap-server.

Edit the file serverclient.class.inc.php.

Move line 15 to 17 and change it to:

Code: Select all

class serverclient extends imapauth


Add the following to line 15:

Code: Select all

require_once($GLOBALS['GO_CONFIG']->root_path.'modules/imapauth/classes/imapauth.class.inc.php');


Move the end marker (}) on line 87 (line 85 if you haven't added the lines above, yet) down a bit and insert the following ahead of the end marker:

Code: Select all

      else
      {
      //Create account on IMAP-server if set in file imap.config.php

         if(!isset($_POST['serverclient_domains']))
         {
            if(!empty($user['email']))
            {
               $arr = explode('@', $user['email']);
               $mailbox = trim($arr[0]);
               $domain = isset($arr[1]) ? trim($arr[1]) : '';

               $config = $sc->get_domain_config($domain);

               if($config['create_email_account'])
               {
                  $sc->login();
            
                  $params=array(
                     'task'=>'serverclient_create_mailbox',
                     'domain'=>($domain),
                     'go_installation_id'=>$GO_CONFIG->id,
                     'username'=>$user['username'],
                     'password1'=>$user['password'],
                     'password2'=>$user['password'],
                     'aliases'=>$user['email'],
                     'name'=>String::format_name($user),
                     'quota'=>0,
                     'active'=>'1',               
                     'vacation_subject'=>'',
                     'vacation_body'=>''               
                     );

                  $response = $sc->send_request($sc->server_url.'modules/postfixadmin/action.php', $params);
                  $response = json_decode($response, true);
                  
                  //debug($response, true);

                  if(!is_array($response) || !$response['success'])
                  {
                     throw new Exception($response['feedback']);
                  }
               }
            }
         }
      }


This part uses (almost) the same code of the serverclient module as is used to create an e-mail account during manual account creation in Group-Office, only slightly different.

The changes I made consists of code that is already present in Group-Office. I have only re-used and re-ordered parts of it with some minor additions of my own.

I would greatly appreciate if Intermesh would take a look at this and give me some feedback. I hope I haven't made any fatal mistakes.

If I've been blurry about anything don't hesitate to ask and I'll try to clarify it.

Have a nice day!

/Mathias
gerardbeekmans
Posts: 12
Joined: Fri Jul 22, 2011 2:30 pm

Re: ldapauth with imapauth problem

Postby gerardbeekmans » Wed Sep 07, 2011 9:16 pm

Just adding my own comment to this: I've made similar changes in order for the name field in outgoing emails to actually contain a user's name and not their email address as is the default. In our LDAP environment first and last names are always provided when we create accounts so these values can safely be assumed to always exist.

A more robust code enhancement would be to try and construct the name field of a GO user from their LDAP config in the following order of preference:

displayName
cn
givenName + sn (allow one of the two being blank)
mail (as a fall back if no name fields are found)

Those are the LDAP fields; it probably makes sense depending on where that code is inserted to use the GO mapped values instead. But the idea should be clear?
mschering
Site Admin
Site Admin
Posts: 8154
Joined: Tue Apr 20, 2004 1:06 pm
Location: The Netherlands - Den Bosch
Contact:

Re: ldapauth with imapauth problem

Postby mschering » Wed Sep 14, 2011 8:05 am

You could map the field to a function:

Code: Select all

function my_ldap_mapping_username($entry){
$username= //do your thing here
        return $username;
}




Code: Select all

'username'=>new ldap_mapping_type('function','my_ldap_mapping_username')
Best regards,



Merijn Schering

Intermesh

Return to “General help”

Who is online

Users browsing this forum: No registered users and 8 guests

cron