diff --git a/ChangeLog b/ChangeLog index e69854a10..3409738b4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-12-14 Ludovic Marcotte + + * Implemented the "bindAsCurrentUser" feature (when + set to the LDAP SOGoUserSources, to YES) which forces + SOGo to use the DN of the currently "requesting" user + to perform all LDAP-related operations + 2010-12-13 Wolfgang Sourdeau * OpenChange/EOQualifier+MAPIFS.[hm]: new category module for diff --git a/Documentation/SOGo Installation Guide.odt b/Documentation/SOGo Installation Guide.odt index f6219c3c9..251f8b5d5 100644 Binary files a/Documentation/SOGo Installation Guide.odt and b/Documentation/SOGo Installation Guide.odt differ diff --git a/Main/SOGo.h b/Main/SOGo.h index 574f036d3..c6ed757d8 100644 --- a/Main/SOGo.h +++ b/Main/SOGo.h @@ -1,14 +1,15 @@ /* + Copyright (C) 2005-2010 Inverse inc. Copyright (C) 2004-2005 SKYRIX Software AG - This file is part of OpenGroupware.org. + This file is part of SOGo. - OGo is free software; you can redistribute it and/or modify it under + SOGo is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. - OGo is distributed in the hope that it will be useful, but WITHOUT ANY + SOGo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. @@ -38,7 +39,6 @@ - (NSDictionary *) currentLocaleConsideringLanguages:(NSArray *)_langs; - (NSDictionary *) localeForLanguageNamed:(NSString *)_name; - - (NSString *) davURLAsString; @end diff --git a/SoObjects/SOGo/LDAPSource.h b/SoObjects/SOGo/LDAPSource.h index 4c3a418a1..907249200 100644 --- a/SoObjects/SOGo/LDAPSource.h +++ b/SoObjects/SOGo/LDAPSource.h @@ -3,6 +3,7 @@ * Copyright (C) 2007-2010 Inverse inc. * * Author: Wolfgang Sourdeau + * Ludovic Marcotte * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -54,6 +55,7 @@ NSArray *mailFields; NSString *IMAPHostField; NSArray *bindFields; + BOOL _bindAsCurrentUser; NSString *domain; NSString *contactInfoAttribute; @@ -61,15 +63,18 @@ NSDictionary *modulesConstraints; NSMutableArray *searchAttributes; - + BOOL passwordPolicy; + + NSMutableDictionary *_dnCache; } - (void) setBindDN: (NSString *) newBindDN password: (NSString *) newBindPassword hostname: (NSString *) newBindHostname port: (NSString *) newBindPort - encryption: (NSString *) newEncryption; + encryption: (NSString *) newEncryption + bindAsCurrentUser: (NSString *) bindAsCurrentUser; - (void) setBaseDN: (NSString *) newBaseDN IDField: (NSString *) newIDField diff --git a/SoObjects/SOGo/LDAPSource.m b/SoObjects/SOGo/LDAPSource.m index 8844be790..b73082a27 100644 --- a/SoObjects/SOGo/LDAPSource.m +++ b/SoObjects/SOGo/LDAPSource.m @@ -1,8 +1,9 @@ /* LDAPSource.m - this file is part of SOGo * - * Copyright (C) 2007-2009 Inverse inc. + * Copyright (C) 2007-2010 Inverse inc. * * Author: Wolfgang Sourdeau + * Ludovic Marcotte * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -40,6 +41,8 @@ #import "LDAPSource.h" +#import "../../Main/SOGo.h" + #define SafeLDAPCriteria(x) [[[x stringByReplacingString: @"\\" withString: @"\\\\"] \ stringByReplacingString: @"'" withString: @"\\'"] \ stringByReplacingString: @"%" withString: @"%%"] @@ -162,6 +165,8 @@ static NSArray *commonSearchFields; searchAttributes = nil; passwordPolicy = NO; + + _dnCache = [[NSMutableDictionary alloc] init]; } return self; @@ -169,6 +174,7 @@ static NSArray *commonSearchFields; - (void) dealloc { + NSLog(@"LDAPSource: -dealloc"); [bindDN release]; [hostname release]; [encryption release]; @@ -186,6 +192,7 @@ static NSArray *commonSearchFields; [_scope release]; [searchAttributes release]; [domain release]; + [_dnCache release]; [super dealloc]; } @@ -203,7 +210,9 @@ static NSArray *commonSearchFields; password: [udSource objectForKey: @"bindPassword"] hostname: [udSource objectForKey: @"hostname"] port: [udSource objectForKey: @"port"] - encryption: [udSource objectForKey: @"encryption"]]; + encryption: [udSource objectForKey: @"encryption"] + bindAsCurrentUser: [udSource objectForKey: @"bindAsCurrentUser"]]; + [self setBaseDN: [udSource objectForKey: @"baseDN"] IDField: [udSource objectForKey: @"IDFieldName"] CNField: [udSource objectForKey: @"CNFieldName"] @@ -252,11 +261,27 @@ static NSArray *commonSearchFields; return self; } +- (void) setBindDN: (NSString *) theDN +{ + ASSIGN(bindDN, theDN); +} + +- (void) setBindPassword: (NSString *) thePassword +{ + ASSIGN (password, thePassword); +} + +- (BOOL) bindAsCurrentUser +{ + return _bindAsCurrentUser; +} + - (void) setBindDN: (NSString *) newBindDN password: (NSString *) newBindPassword hostname: (NSString *) newBindHostname port: (NSString *) newBindPort encryption: (NSString *) newEncryption + bindAsCurrentUser: (NSString *) bindAsCurrentUser { ASSIGN (bindDN, newBindDN); ASSIGN (encryption, [newEncryption uppercaseString]); @@ -266,6 +291,7 @@ static NSArray *commonSearchFields; if (newBindPort) port = [newBindPort intValue]; ASSIGN (password, newBindPassword); + _bindAsCurrentUser = [bindAsCurrentUser boolValue]; } - (void) setBaseDN: (NSString *) newBaseDN @@ -337,6 +363,8 @@ static NSArray *commonSearchFields; NS_DURING { + //NSLog(@"Creating NGLdapConnection instance for bindDN '%@'", bindDN); + ldapConnection = [[NGLdapConnection alloc] initWithHostName: hostname port: port]; [ldapConnection autorelease]; @@ -442,11 +470,21 @@ static NSArray *commonSearchFields; { if (queryTimeout > 0) [bindConnection setQueryTimeLimit: queryTimeout]; - if (bindFields) - userDN = [self _fetchUserDNForLogin: _login]; - else - userDN = [NSString stringWithFormat: @"%@=%@,%@", - IDField, _login, baseDN]; + + userDN = [_dnCache objectForKey: _login]; + + if (!userDN) + { + if (bindFields) + userDN = [self _fetchUserDNForLogin: _login]; + else + userDN = [NSString stringWithFormat: @"%@=%@,%@", + IDField, _login, baseDN]; + } + + // We cache the _login <-> userDN entry to speed up things + [_dnCache setObject: userDN forKey: _login]; + if (userDN) { NS_DURING @@ -975,6 +1013,11 @@ static NSArray *commonSearchFields; return login; } +- (NSString *) lookupDNByLogin: (NSString *) theLogin +{ + return [_dnCache objectForKey: theLogin]; +} + - (NGLdapEntry *) lookupGroupEntryByUID: (NSString *) theUID { return [self lookupGroupEntryByAttribute: UIDField diff --git a/SoObjects/SOGo/SOGoSource.h b/SoObjects/SOGo/SOGoSource.h index 18acc5093..f6cdf9bf9 100644 --- a/SoObjects/SOGo/SOGoSource.h +++ b/SoObjects/SOGo/SOGoSource.h @@ -41,6 +41,7 @@ - (NSString *) domain; - (BOOL) checkLogin: (NSString *) _login + password: (NSString *) _pwd perr: (SOGoPasswordPolicyError *) _perr expire: (int *) _expire @@ -62,7 +63,13 @@ @protocol SOGoDNSource +- (void) setBindDN: (NSString *) theDN; +- (void) setBindPassword: (NSString *) thePassword; +- (BOOL) bindAsCurrentUser; + - (NSString *) lookupLoginByDN: (NSString *) theDN; +- (NSString *) lookupDNByLogin: (NSString *) theLogin; + - (NSString *) baseDN; @end diff --git a/SoObjects/SOGo/SOGoUser.h b/SoObjects/SOGo/SOGoUser.h index 6552f49e6..00acf9962 100644 --- a/SoObjects/SOGo/SOGoUser.h +++ b/SoObjects/SOGo/SOGoUser.h @@ -1,15 +1,15 @@ /* - Copyright (C) 2006-2009 Inverse inc. + Copyright (C) 2006-2010 Inverse inc. Copyright (C) 2005 SKYRIX Software AG - This file is part of OpenGroupware.org. + This file is part of SOGo. - OGo is free software; you can redistribute it and/or modify it under + SOGo is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. - OGo is distributed in the hope that it will be useful, but WITHOUT ANY + SOGo is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. @@ -29,7 +29,7 @@ SOGoUser This adds some additional SOGo properties to the SoUser object. The - properties are (currently) looked up using the LDAPUserManager. + properties are (currently) looked up using the SOGoUserManager. You have access to this object from the WOContext: context.activeUser @@ -52,12 +52,6 @@ @class SOGoUserProfile; @class SOGoUserSettings; -// @interface SoUser (SOGoExtension) - -// - (NSString *) language; - -// @end - @interface SOGoUser : SoUser { SOGoUserDefaults *_defaults; @@ -72,8 +66,6 @@ NSString *cn; } -// + (NSString *) language; - + (SOGoUser *) userWithLogin: (NSString *) newLogin; + (SOGoUser *) userWithLogin: (NSString *) login diff --git a/SoObjects/SOGo/SOGoUserManager.m b/SoObjects/SOGo/SOGoUserManager.m index 9ab8aa2d3..0bc2ddb7f 100644 --- a/SoObjects/SOGo/SOGoUserManager.m +++ b/SoObjects/SOGo/SOGoUserManager.m @@ -416,6 +416,9 @@ NSMutableDictionary *currentUser; BOOL checkOK; + // We check for cached passwords. If the entry is cached, we + // check this immediately. If not, we'll go directly at the + // authentication source and try to validate there, then cache it. jsonUser = [[SOGoCache sharedCache] userAttributesForLogin: _login]; currentUser = [jsonUser objectFromJSONString]; dictPassword = [currentUser objectForKey: @"password"]; @@ -446,6 +449,25 @@ else checkOK = NO; + // We MUST, for all LDAP sources, update the bindDN and bindPassword + // to the user's value if bindAsCurrentUser is set to true in the + // LDAP source configuration + if (checkOK) + { + NSObject *currentSource; + NSEnumerator *sources; + + sources = [[_sources allValues] objectEnumerator]; + while ((currentSource = [sources nextObject])) + if ([currentSource conformsToProtocol: @protocol(SOGoDNSource)] && + [currentSource bindAsCurrentUser] && + [currentSource lookupDNByLogin: _login]) + { + [currentSource setBindDN: [currentSource lookupDNByLogin: _login]]; + [currentSource setBindPassword: _pwd]; + } + } + return checkOK; } diff --git a/SoObjects/SOGo/SQLSource.h b/SoObjects/SOGo/SQLSource.h index 40f0425f7..8d08a1fdc 100644 --- a/SoObjects/SOGo/SQLSource.h +++ b/SoObjects/SOGo/SQLSource.h @@ -1,6 +1,6 @@ /* SQLSource.h - this file is part of SOGo * - * Copyright (C) 2009 Inverse inc. + * Copyright (C) 2009-2010 Inverse inc. * * Author: Ludovic Marcotte *