From 48832a4878d5f1763c22ab6d9f0f4d6b128b5b74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Garc=C3=ADa=20S=C3=A1ez?= Date: Wed, 23 Sep 2015 14:51:46 +0200 Subject: [PATCH 01/11] Add domain to lookupGroupEntryByUID/ByEmail --- SoObjects/SOGo/LDAPSource.h | 6 ++++-- SoObjects/SOGo/LDAPSource.m | 2 ++ SoObjects/SOGo/SOGoGroup.m | 10 +++++----- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/SoObjects/SOGo/LDAPSource.h b/SoObjects/SOGo/LDAPSource.h index 3877ec4ee..9081196be 100644 --- a/SoObjects/SOGo/LDAPSource.h +++ b/SoObjects/SOGo/LDAPSource.h @@ -120,8 +120,10 @@ andMultipleBookingsField: (NSString *) newMultipleBookingsField; - (void) setContactMapping: (NSDictionary *) newMapping andObjectClasses: (NSArray *) newObjectClasses; -- (NGLdapEntry *) lookupGroupEntryByUID: (NSString *) theUID; -- (NGLdapEntry *) lookupGroupEntryByEmail: (NSString *) theEmail; +- (NGLdapEntry *) lookupGroupEntryByUID: (NSString *) theUID + inDomain: (NSString *) domain; +- (NGLdapEntry *) lookupGroupEntryByEmail: (NSString *) theEmail + inDomain: (NSString *) domain; @end diff --git a/SoObjects/SOGo/LDAPSource.m b/SoObjects/SOGo/LDAPSource.m index d537c6aec..f13541024 100644 --- a/SoObjects/SOGo/LDAPSource.m +++ b/SoObjects/SOGo/LDAPSource.m @@ -1339,12 +1339,14 @@ groupObjectClasses: (NSArray *) newGroupObjectClasses } - (NGLdapEntry *) lookupGroupEntryByUID: (NSString *) theUID + inDomain: (NSString *) domain { return [self _lookupGroupEntryByAttributes: [NSArray arrayWithObject: UIDField] andValue: theUID]; } - (NGLdapEntry *) lookupGroupEntryByEmail: (NSString *) theEmail + inDomain: (NSString *) domain { return [self _lookupGroupEntryByAttributes: mailFields andValue: theEmail]; diff --git a/SoObjects/SOGo/SOGoGroup.m b/SoObjects/SOGo/SOGoGroup.m index cacdd7770..9b74f2dee 100644 --- a/SoObjects/SOGo/SOGoGroup.m +++ b/SoObjects/SOGo/SOGoGroup.m @@ -113,7 +113,7 @@ uid = [theID hasPrefix: @"@"] ? [theID substringFromIndex: 1] : theID; return [SOGoGroup groupWithValue: uid - andSourceSelector: @selector (lookupGroupEntryByUID:) + andSourceSelector: @selector (lookupGroupEntryByUID:inDomain:) inDomain: domain]; } @@ -121,7 +121,7 @@ inDomain: (NSString *) domain { return [SOGoGroup groupWithValue: theEmail - andSourceSelector: @selector (lookupGroupEntryByEmail:) + andSourceSelector: @selector (lookupGroupEntryByEmail:inDomain:) inDomain: domain]; } @@ -158,9 +158,9 @@ // Our different sources might not all implements groups support if ([source respondsToSelector: theSelector]) - entry = [source performSelector: theSelector - withObject: theValue]; - + entry = [source performSelector: theSelector + withObject: theValue + withObject: domain]; if (entry) break; From 7d49674d9d431dc6fbb838416f8862af74a95d96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Garc=C3=ADa=20S=C3=A1ez?= Date: Wed, 23 Sep 2015 15:09:45 +0200 Subject: [PATCH 02/11] Add domain to lookupContactEntry --- SoObjects/Contacts/SOGoContactSourceFolder.m | 21 ++++++++++++-------- SoObjects/SOGo/LDAPSource.m | 1 + SoObjects/SOGo/SOGoSource.h | 3 ++- SoObjects/SOGo/SOGoUserManager.m | 2 +- SoObjects/SOGo/SQLSource.m | 3 ++- Tools/SOGoToolBackup.m | 14 +++++++------ 6 files changed, 27 insertions(+), 17 deletions(-) diff --git a/SoObjects/Contacts/SOGoContactSourceFolder.m b/SoObjects/Contacts/SOGoContactSourceFolder.m index e385d9c09..26c965d9c 100644 --- a/SoObjects/Contacts/SOGoContactSourceFolder.m +++ b/SoObjects/Contacts/SOGoContactSourceFolder.m @@ -164,9 +164,10 @@ ldifEntry = [childRecords objectForKey: objectName]; if (!ldifEntry) { - ldifEntry = [source lookupContactEntry: objectName]; - if (ldifEntry) - [childRecords setObject: ldifEntry forKey: objectName]; + ldifEntry = [source lookupContactEntry: objectName + inDomain: [[context activeUser] domain]]; + if (ldifEntry) + [childRecords setObject: ldifEntry forKey: objectName]; else if ([self isValidContentName: objectName]) { url = [[[lookupContext request] uri] urlWithoutParameters]; @@ -324,10 +325,14 @@ NSDictionary *record; if (aName && [aName length] > 0) - record = [self _flattenedRecord: [source lookupContactEntry: aName]]; + { + record = [source lookupContactEntry: aName + inDomain: [[context activeUser] domain]]; + record = [self _flattenedRecord: record]; + } else record = nil; - + return record; } @@ -562,7 +567,7 @@ toResponse: (WOResponse *) response { NSObject *element; - NSString *url, *baseURL, *cname; + NSString *url, *baseURL, *cname, *domain; NSString **propertiesArray; NSMutableString *buffer; NSDictionary *object; @@ -579,13 +584,13 @@ max = [refs length]; buffer = [NSMutableString stringWithCapacity: max*512]; - + domain = [[context activeUser] domain]; for (count = 0; count < max; count++) { element = [refs objectAtIndex: count]; url = [[[element firstChild] nodeValue] stringByUnescapingURL]; cname = [self _deduceObjectNameFromURL: url fromBaseURL: baseURL]; - object = [source lookupContactEntry: cname]; + object = [source lookupContactEntry: cname inDomain: domain]; if (object) [self appendObject: object properties: propertiesArray diff --git a/SoObjects/SOGo/LDAPSource.m b/SoObjects/SOGo/LDAPSource.m index f13541024..2973c65a4 100644 --- a/SoObjects/SOGo/LDAPSource.m +++ b/SoObjects/SOGo/LDAPSource.m @@ -1242,6 +1242,7 @@ groupObjectClasses: (NSArray *) newGroupObjectClasses } - (NSDictionary *) lookupContactEntry: (NSString *) theID + inDomain: (NSString *) domain { NGLdapEntry *ldapEntry; EOQualifier *qualifier; diff --git a/SoObjects/SOGo/SOGoSource.h b/SoObjects/SOGo/SOGoSource.h index b55a5a14a..d59a81086 100644 --- a/SoObjects/SOGo/SOGoSource.h +++ b/SoObjects/SOGo/SOGoSource.h @@ -56,7 +56,8 @@ newPassword: (NSString *) newPassword perr: (SOGoPasswordPolicyError *) perr; -- (NSDictionary *) lookupContactEntry: (NSString *) theID; +- (NSDictionary *) lookupContactEntry: (NSString *) theID + inDomain: (NSString *) domain; - (NSDictionary *) lookupContactEntryWithUIDorEmail: (NSString *) entryID inDomain: (NSString *) domain; diff --git a/SoObjects/SOGo/SOGoUserManager.m b/SoObjects/SOGo/SOGoUserManager.m index d5a6a94d0..3846da9d8 100644 --- a/SoObjects/SOGo/SOGoUserManager.m +++ b/SoObjects/SOGo/SOGoUserManager.m @@ -1047,7 +1047,7 @@ static Class NSNullK; while ((sourceID = [sources nextObject])) { currentSource = [_sources objectForKey: sourceID]; - contact = [currentSource lookupContactEntry: uid]; + contact = [currentSource lookupContactEntry: uid inDomain: domain]; if (contact) [contacts addObject: contact]; } diff --git a/SoObjects/SOGo/SQLSource.m b/SoObjects/SOGo/SQLSource.m index 7d0de6c07..06d40557a 100644 --- a/SoObjects/SOGo/SQLSource.m +++ b/SoObjects/SOGo/SQLSource.m @@ -618,8 +618,9 @@ - (NSDictionary *) lookupContactEntry: (NSString *) theID + inDomain: (NSString *) domain { - return [self _lookupContactEntry: theID considerEmail: NO inDomain: nil]; + return [self _lookupContactEntry: theID considerEmail: NO inDomain: domain]; } - (NSDictionary *) lookupContactEntryWithUIDorEmail: (NSString *) entryID diff --git a/Tools/SOGoToolBackup.m b/Tools/SOGoToolBackup.m index fb2b4d016..3f2cb27bc 100644 --- a/Tools/SOGoToolBackup.m +++ b/Tools/SOGoToolBackup.m @@ -363,6 +363,7 @@ } - (BOOL) extractUserLDIFRecord: (NSString *) uid + inDomain: (NSString *) domain intoRecord: (NSMutableDictionary *) userRecord { NSEnumerator *ldapSources; @@ -375,11 +376,11 @@ lm = [SOGoUserManager sharedUserManager]; done = NO; - ldapSources = [[lm authenticationSourceIDsInDomain: nil] objectEnumerator]; + ldapSources = [[lm authenticationSourceIDsInDomain: domain] objectEnumerator]; while (!done && (sourceID = [ldapSources nextObject])) { currentSource = [lm sourceWithID: sourceID]; - userEntry = [currentSource lookupContactEntry: uid]; + userEntry = [currentSource lookupContactEntry: uid inDomain: domain]; if (userEntry) { [userRecord setObject: [userEntry ldifRecordAsString] @@ -411,25 +412,26 @@ - (BOOL) exportUser: (NSDictionary *) theUser { - NSString *exportPath, *gcsUID, *ldapUID; + NSString *exportPath, *gcsUID, *ldapUID, *domain; NSMutableDictionary *userRecord; SOGoSystemDefaults *sd; - + sd = [SOGoSystemDefaults sharedSystemDefaults]; userRecord = [NSMutableDictionary dictionary]; ldapUID = [theUser objectForKey: @"c_uid"]; exportPath = [directory stringByAppendingPathComponent: ldapUID]; - + domain = [theUser objectForKey: @"c_domain"]; gcsUID = [theUser objectForKey: @"c_uid"]; if ([sd enableDomainBasedUID] && [gcsUID rangeOfString: @"@"].location == NSNotFound) gcsUID = [NSString stringWithFormat: @"%@@%@", gcsUID, [theUser objectForKey: @"c_domain"]]; - + return ([self extractUserFolders: gcsUID intoRecord: userRecord] && [self extractUserLDIFRecord: ldapUID + inDomain: domain intoRecord: userRecord] && [self extractUserPreferences: gcsUID intoRecord: userRecord] From 9d3f3c619d5172c9a303bd3681f8a4b01f514df0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Garc=C3=ADa=20S=C3=A1ez?= Date: Wed, 23 Sep 2015 15:11:08 +0200 Subject: [PATCH 03/11] LDAPSource: release displayName on dealloc --- SoObjects/SOGo/LDAPSource.m | 1 + 1 file changed, 1 insertion(+) diff --git a/SoObjects/SOGo/LDAPSource.m b/SoObjects/SOGo/LDAPSource.m index 2973c65a4..a4a2b9976 100644 --- a/SoObjects/SOGo/LDAPSource.m +++ b/SoObjects/SOGo/LDAPSource.m @@ -162,6 +162,7 @@ static Class NSStringK; [multipleBookingsField release]; [MSExchangeHostname release]; [modifiers release]; + [displayName release]; [super dealloc]; } From bf4a581d0f6ddd18493d4813292f7bd9c7ad4bcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Garc=C3=ADa=20S=C3=A1ez?= Date: Wed, 23 Sep 2015 15:36:39 +0200 Subject: [PATCH 04/11] Added isDomainDefined To check whether a domain is supported by our defined sources --- SoObjects/SOGo/SOGoSession.m | 3 ++- SoObjects/SOGo/SOGoUser.m | 2 +- SoObjects/SOGo/SOGoUserManager.h | 1 + SoObjects/SOGo/SOGoUserManager.m | 31 ++++++++++++++++++++++++++++++- 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/SoObjects/SOGo/SOGoSession.m b/SoObjects/SOGo/SOGoSession.m index 9af654b90..73bbbfa5d 100644 --- a/SoObjects/SOGo/SOGoSession.m +++ b/SoObjects/SOGo/SOGoSession.m @@ -41,6 +41,7 @@ #include #import "SOGoSystemDefaults.h" +#import "SOGoUserManager.h" @implementation SOGoSession @@ -262,7 +263,7 @@ // The domain is probably appended to the username; // make sure it is defined as a domain in the configuration. *theDomain = [*theLogin substringFromIndex: (r.location + r.length)]; - if (![[sd domainIds] containsObject: *theDomain]) + if (![[SOGoUserManager sharedUserManager] isDomainDefined: *theDomain]) *theDomain = nil; } } diff --git a/SoObjects/SOGo/SOGoUser.m b/SoObjects/SOGo/SOGoUser.m index d81dcf52c..d84eb6188 100644 --- a/SoObjects/SOGo/SOGoUser.m +++ b/SoObjects/SOGo/SOGoUser.m @@ -165,7 +165,7 @@ // The domain is probably appended to the username; // make sure it is defined as a domain in the configuration. domain = [newLogin substringFromIndex: (r.location + r.length)]; - if ([[sd domainIds] containsObject: domain] && + if ([[SOGoUserManager sharedUserManager] isDomainDefined: domain] && ![sd enableDomainBasedUID]) newLogin = [newLogin substringToIndex: r.location]; diff --git a/SoObjects/SOGo/SOGoUserManager.h b/SoObjects/SOGo/SOGoUserManager.h index d30821108..5cf246d3a 100644 --- a/SoObjects/SOGo/SOGoUserManager.h +++ b/SoObjects/SOGo/SOGoUserManager.h @@ -58,6 +58,7 @@ - (NSArray *) sourceIDsInDomain: (NSString *) domain; - (NSArray *) authenticationSourceIDsInDomain: (NSString *) domain; - (NSArray *) addressBookSourceIDsInDomain: (NSString *) domain; +- (BOOL) isDomainDefined: (NSString *) domain; - (NSObject *) sourceWithID: (NSString *) sourceID; - (NSDictionary *) metadataForSourceID: (NSString *) sourceID; diff --git a/SoObjects/SOGo/SOGoUserManager.m b/SoObjects/SOGo/SOGoUserManager.m index 3846da9d8..9afd3a74c 100644 --- a/SoObjects/SOGo/SOGoUserManager.m +++ b/SoObjects/SOGo/SOGoUserManager.m @@ -305,6 +305,35 @@ static Class NSNullK; return sourceIDs; } +- (BOOL) isDomainDefined: (NSString *) domain +{ + NSEnumerator *allIDs; + NSArray *ids; + NSString *currentID, *sourceDomain; + SOGoSystemDefaults *sd; + + if (!domain) return NO; + + ids = [_sources allKeys]; + if ([ids containsObject: domain]) + // FIXME check SOGoMailDomain? + // Now source id is being considered as the domain + return YES; + + sd = [SOGoSystemDefaults sharedSystemDefaults]; + if ([sd enableDomainBasedUID]) + { + allIDs = [ids objectEnumerator]; + while ((currentID = [allIDs nextObject])) + { + sourceDomain = [[_sources objectForKey: currentID] domain]; + if (!sourceDomain) // source that can identify any domain + return YES; + } + } + + return NO; +} - (NSString *) displayNameForSourceWithID: (NSString *) sourceID { NSDictionary *metadata; @@ -932,7 +961,7 @@ static Class NSNullK; // The domain is probably appended to the username; // make sure it is a defined domain in the configuration. domain = [uid substringFromIndex: (r.location + r.length)]; - if ([[sd domainIds] containsObject: domain]) + if ([self isDomainDefined: domain]) username = [uid substringToIndex: r.location]; else domain = nil; From 0d05e3579cb56b98cd80a3216ea8e6c51655e04e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Garc=C3=ADa=20S=C3=A1ez?= Date: Wed, 23 Sep 2015 15:38:11 +0200 Subject: [PATCH 05/11] defaultsForDomain return sharedSystemDefaults for unknown domains --- SoObjects/SOGo/SOGoDomainDefaults.m | 3 +++ 1 file changed, 3 insertions(+) diff --git a/SoObjects/SOGo/SOGoDomainDefaults.m b/SoObjects/SOGo/SOGoDomainDefaults.m index b55cc0851..4c7541b19 100644 --- a/SoObjects/SOGo/SOGoDomainDefaults.m +++ b/SoObjects/SOGo/SOGoDomainDefaults.m @@ -50,6 +50,9 @@ andParentSource: systemDefaults]; } + if (!domainDefaults) + domainDefaults = [SOGoSystemDefaults sharedSystemDefaults]; + return domainDefaults; } From ec533809aa46141545628be5d918a966ca8514e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Garc=C3=ADa=20S=C3=A1ez?= Date: Wed, 23 Sep 2015 15:41:48 +0200 Subject: [PATCH 06/11] return enableDomainBasedUID based only on the key --- SoObjects/SOGo/SOGoSystemDefaults.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SoObjects/SOGo/SOGoSystemDefaults.m b/SoObjects/SOGo/SOGoSystemDefaults.m index 8c9181665..9447b1da3 100644 --- a/SoObjects/SOGo/SOGoSystemDefaults.m +++ b/SoObjects/SOGo/SOGoSystemDefaults.m @@ -261,7 +261,7 @@ _injectConfigurationFromFile (NSMutableDictionary *defaultsDict, - (BOOL) enableDomainBasedUID { - return ([[self domainIds] count] > 0 && [self boolForKey: @"SOGoEnableDomainBasedUID"]); + return [self boolForKey: @"SOGoEnableDomainBasedUID"]; } - (NSArray *) loginDomains From 30a94161af562ed83b9a06afbce2661f4529fa84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Garc=C3=ADa=20S=C3=A1ez?= Date: Wed, 23 Sep 2015 15:48:21 +0200 Subject: [PATCH 07/11] SOGoUserManager.m: format and small refactor Removed all tabs used for indentation --- SoObjects/SOGo/SOGoUserManager.m | 239 ++++++++++++++----------------- 1 file changed, 110 insertions(+), 129 deletions(-) diff --git a/SoObjects/SOGo/SOGoUserManager.m b/SoObjects/SOGo/SOGoUserManager.m index 9afd3a74c..fe81be52d 100644 --- a/SoObjects/SOGo/SOGoUserManager.m +++ b/SoObjects/SOGo/SOGoUserManager.m @@ -104,65 +104,58 @@ static Class NSNullK; NSString *sourceID, *value, *type; NSMutableDictionary *metadata; NSObject *sogoSource; - BOOL isAddressBook, result; + BOOL isAddressBook; Class c; - result = NO; sourceID = [udSource objectForKey: @"id"]; - if ([sourceID length] > 0) + if (!sourceID || [sourceID length] == 0) { - if ([_sourcesMetadata objectForKey: sourceID]) - [self errorWithFormat: @"attempted to register a contact/user source" - @" with duplicated id (%@)", sourceID]; - else - { - type = [[udSource objectForKey: @"type"] lowercaseString]; - c = NSClassFromString([_registry sourceClassForType: type]); - sogoSource = [c sourceFromUDSource: udSource inDomain: domain]; - if (sourceID) - [_sources setObject: sogoSource forKey: sourceID]; - else - [self errorWithFormat: @"id field missing in an user source," - @" check the SOGoUserSources defaults"]; - metadata = [NSMutableDictionary dictionary]; - if (domain) - [metadata setObject: domain forKey: @"domain"]; - value = [udSource objectForKey: @"canAuthenticate"]; - if (value) - [metadata setObject: value forKey: @"canAuthenticate"]; - value = [udSource objectForKey: @"isAddressBook"]; - if (value) - { - [metadata setObject: value forKey: @"isAddressBook"]; - isAddressBook = [value boolValue]; - } - else - isAddressBook = NO; - value = [udSource objectForKey: @"displayName"]; - if (value) - [metadata setObject: value forKey: @"displayName"]; - else - { - if (isAddressBook) - [self errorWithFormat: @"addressbook source '%@' has" - @" no displayname", sourceID]; - } - value = [udSource objectForKey: @"MailFieldNames"]; - if (value) - [metadata setObject: value forKey: @"MailFieldNames"]; - value = [udSource objectForKey: @"SearchFieldNames"]; - if (value) - [metadata setObject: value forKey: @"SearchFieldNames"]; - - [_sourcesMetadata setObject: metadata forKey: sourceID]; - result = YES; - } + [self errorWithFormat: @"attempted to register a contact/user source " + @"without id (skipped)"]; + return NO; + } + if ([_sourcesMetadata objectForKey: sourceID]) + { + [self errorWithFormat: @"attempted to register a contact/user source " + @"with duplicated id (%@)", sourceID]; + return NO; + } + + type = [[udSource objectForKey: @"type"] lowercaseString]; + c = NSClassFromString([_registry sourceClassForType: type]); + sogoSource = [c sourceFromUDSource: udSource inDomain: domain]; + [_sources setObject: sogoSource forKey: sourceID]; + + metadata = [NSMutableDictionary dictionary]; + if (domain) + [metadata setObject: domain forKey: @"domain"]; + value = [udSource objectForKey: @"canAuthenticate"]; + if (value) + [metadata setObject: value forKey: @"canAuthenticate"]; + value = [udSource objectForKey: @"isAddressBook"]; + if (value) + { + [metadata setObject: value forKey: @"isAddressBook"]; + isAddressBook = [value boolValue]; } else - [self errorWithFormat: @"attempted to register a contact/user source" - @" without id (skipped)"]; + isAddressBook = NO; + value = [udSource objectForKey: @"displayName"]; + if (value) + [metadata setObject: value forKey: @"displayName"]; + else if (isAddressBook) + [self errorWithFormat: @"addressbook source '%@' has no displayname", sourceID]; - return result; + value = [udSource objectForKey: @"MailFieldNames"]; + if (value) + [metadata setObject: value forKey: @"MailFieldNames"]; + value = [udSource objectForKey: @"SearchFieldNames"]; + if (value) + [metadata setObject: value forKey: @"SearchFieldNames"]; + + [_sourcesMetadata setObject: metadata forKey: sourceID]; + + return YES; } - (int) _registerSourcesInDomain: (NSString *) domain @@ -171,11 +164,7 @@ static Class NSNullK; unsigned int count, max, total; SOGoDomainDefaults *dd; - if (domain) - dd = [SOGoDomainDefaults defaultsForDomain: domain]; - else - dd = [SOGoSystemDefaults sharedSystemDefaults]; - + dd = [SOGoDomainDefaults defaultsForDomain: domain]; userSources = [dd userSources]; max = [userSources count]; total = 0; @@ -357,7 +346,6 @@ static Class NSNullK; { NSDictionary *contactInfos; -// NSLog (@"getEmailForUID: %@", uid); contactInfos = [self contactInfosForUserWithUIDorEmail: uid]; return [contactInfos objectForKey: @"c_email"]; @@ -374,8 +362,7 @@ static Class NSNullK; if ([cn length] > 0) { if ([email length] > 0) - fullEmail = [NSString stringWithFormat: @"%@ <%@>", - cn, email]; + fullEmail = [NSString stringWithFormat: @"%@ <%@>", cn, email]; else fullEmail = cn; } @@ -398,11 +385,7 @@ static Class NSNullK; login = [contactInfos objectForKey: @"c_imaplogin"]; if (login == nil) { - if ([domain length]) - dd = [SOGoDomainDefaults defaultsForDomain: domain]; - else - dd = [SOGoSystemDefaults sharedSystemDefaults]; - + dd = [SOGoDomainDefaults defaultsForDomain: domain]; if ([dd forceExternalLoginWithEmail]) { sd = [SOGoSystemDefaults sharedSystemDefaults]; @@ -444,16 +427,16 @@ static Class NSNullK; - (BOOL) _sourceChangePasswordForLogin: (NSString *) login inDomain: (NSString *) domain oldPassword: (NSString *) oldPassword - newPassword: (NSString *) newPassword - perr: (SOGoPasswordPolicyError *) perr + newPassword: (NSString *) newPassword + perr: (SOGoPasswordPolicyError *) perr { NSObject *sogoSource; NSEnumerator *authIDs; NSString *currentID; BOOL didChange; - + didChange = NO; - + authIDs = [[self authenticationSourceIDsInDomain: domain] objectEnumerator]; while (!didChange && (currentID = [authIDs nextObject])) { @@ -478,8 +461,6 @@ static Class NSNullK; NSEnumerator *authIDs; NSString *currentID; BOOL checkOK; - SOGoSystemDefaults *sd; - NSRange r; checkOK = NO; @@ -577,7 +558,7 @@ static Class NSNullK; delta = current_time - start_time; block_time = [sd failedLoginBlockInterval]; - + if ([[failedCount objectForKey: @"FailedCount"] intValue] >= [sd maximumFailedLoginCount] && delta >= [sd maximumFailedLoginInterval] && delta <= block_time ) @@ -585,7 +566,7 @@ static Class NSNullK; *_perr = PolicyAccountLocked; return NO; } - + if (delta > block_time) { [[SOGoCache sharedCache] setFailedCount: 0 @@ -669,7 +650,7 @@ static Class NSNullK; [[SOGoCache sharedCache] setFailedCount: ([[failedCount objectForKey: @"FailedCount"] intValue] + 1) forLogin: username]; } - + checkOK = NO; } @@ -680,7 +661,7 @@ static Class NSNullK; { NSObject *currentSource; NSEnumerator *sources; - + sources = [[_sources allValues] objectEnumerator]; while ((currentSource = [sources nextObject])) if ([currentSource conformsToProtocol: @protocol(SOGoDNSource)] && @@ -700,9 +681,9 @@ static Class NSNullK; // - (BOOL) changePasswordForLogin: (NSString *) login inDomain: (NSString *) domain - oldPassword: (NSString *) oldPassword - newPassword: (NSString *) newPassword - perr: (SOGoPasswordPolicyError *) perr + oldPassword: (NSString *) oldPassword + newPassword: (NSString *) newPassword + perr: (SOGoPasswordPolicyError *) perr { NSString *jsonUser, *userLogin; NSMutableDictionary *currentUser; @@ -817,7 +798,7 @@ static Class NSNullK; while (!userEntry && (sourceID = [sogoSources nextObject])) { currentSource = [_sources objectForKey: sourceID]; - + userEntry = [currentSource lookupContactEntryWithUIDorEmail: theUID inDomain: theDomain]; if (userEntry) @@ -932,7 +913,7 @@ static Class NSNullK; [user setObject: [NSNumber numberWithBool: YES] forKey: @"CalendarAccess"]; [user setObject: [NSNumber numberWithBool: NO] - forKey: @"MailAccess"]; + forKey: @"MailAccess"]; } return user; @@ -976,7 +957,7 @@ static Class NSNullK; // search using the original uid. infos = [self contactInfosForUserWithUIDorEmail: uid inDomain: nil]; - + return infos; } @@ -1005,29 +986,29 @@ static Class NSNullK; if ([currentUser isKindOfClass: NSNullK]) currentUser = nil; else if (!([currentUser objectForKey: @"emails"] - && [currentUser objectForKey: @"cn"])) - { - // We make sure that we either have no occurence of a cache entry or - // that we have an occurence with only a cached password. In the - // latter case, we update the entry with the remaining information - // and recache the value. - if (!currentUser || + && [currentUser objectForKey: @"cn"])) + { + // We make sure that we either have no occurence of a cache entry or + // that we have an occurence with only a cached password. In the + // latter case, we update the entry with the remaining information + // and recache the value. + if (!currentUser || ([currentUser count] == 1 && [currentUser objectForKey: @"password"]) || ([currentUser count] == 2 && [currentUser objectForKey: @"password"] && [currentUser objectForKey: @"DomainLessLogin"])) { - newUser = YES; + newUser = YES; - if (!currentUser) - currentUser = [NSMutableDictionary dictionary]; - } - else - newUser = NO; - [self _fillContactInfosForUser: currentUser + if (!currentUser) + currentUser = [NSMutableDictionary dictionary]; + } + else + newUser = NO; + [self _fillContactInfosForUser: currentUser withUIDorEmail: aUID inDomain: domain]; - if (newUser) - { - if ([[currentUser objectForKey: @"c_uid"] length] == 0) + if (newUser) + { + if ([[currentUser objectForKey: @"c_uid"] length] == 0) { [self _retainUser: (NSDictionary *) [NSNull null] withLogin: cacheUid]; @@ -1050,7 +1031,7 @@ static Class NSNullK; [self _retainUser: currentUser withLogin: cacheUid]; } } - } + } } else currentUser = nil; @@ -1105,30 +1086,30 @@ static Class NSNullK; { uid = [userEntry objectForKey: @"c_uid"]; if ([uid length]) - { - returnContact = [compactContacts objectForKey: uid]; - if (!returnContact) - { - returnContact = [NSMutableDictionary dictionary]; - [returnContact setObject: uid forKey: @"c_uid"]; + { + returnContact = [compactContacts objectForKey: uid]; + if (!returnContact) + { + returnContact = [NSMutableDictionary dictionary]; + [returnContact setObject: uid forKey: @"c_uid"]; source = [userEntry objectForKey: @"source"]; if (source) [returnContact setObject: source forKey: @"source"]; [compactContacts setObject: returnContact forKey: uid]; } - if (![[returnContact objectForKey: @"c_name"] length]) - [returnContact setObject: [userEntry objectForKey: @"c_name"] - forKey: @"c_name"]; - if (![[returnContact objectForKey: @"cn"] length]) - [returnContact setObject: [userEntry objectForKey: @"c_cn"] - forKey: @"cn"]; - emails = [returnContact objectForKey: @"emails"]; - if (!emails) - { - emails = [NSMutableArray array]; - [returnContact setObject: emails forKey: @"emails"]; - } - email = [userEntry objectForKey: @"mail"]; + if (![[returnContact objectForKey: @"c_name"] length]) + [returnContact setObject: [userEntry objectForKey: @"c_name"] + forKey: @"c_name"]; + if (![[returnContact objectForKey: @"cn"] length]) + [returnContact setObject: [userEntry objectForKey: @"c_cn"] + forKey: @"cn"]; + emails = [returnContact objectForKey: @"emails"]; + if (!emails) + { + emails = [NSMutableArray array]; + [returnContact setObject: emails forKey: @"emails"]; + } + email = [userEntry objectForKey: @"mail"]; if ([email isKindOfClass: [NSArray class]]) { allEmails = (NSArray *) email; @@ -1140,22 +1121,22 @@ static Class NSNullK; } } else if (email && ![emails containsObject: email]) - [emails addObject: email]; - email = [userEntry objectForKey: @"mozillasecondemail"]; - if (email && ![emails containsObject: email]) - [emails addObject: email]; - email = [userEntry objectForKey: @"xmozillasecondemail"]; - if (email && ![emails containsObject: email]) - [emails addObject: email]; + [emails addObject: email]; + email = [userEntry objectForKey: @"mozillasecondemail"]; + if (email && ![emails containsObject: email]) + [emails addObject: email]; + email = [userEntry objectForKey: @"xmozillasecondemail"]; + if (email && ![emails containsObject: email]) + [emails addObject: email]; info = [userEntry objectForKey: @"c_info"]; if ([info length] > 0 && ![[returnContact objectForKey: @"c_info"] length]) [returnContact setObject: info forKey: @"c_info"]; - [self _fillContactMailRecords: returnContact]; + [self _fillContactMailRecords: returnContact]; isGroup = [userEntry objectForKey: @"isGroup"]; if (isGroup) [returnContact setObject: isGroup forKey: @"isGroup"]; - } + } } newContacts = [compactContacts allValues]; @@ -1164,7 +1145,7 @@ static Class NSNullK; } - (NSArray *) _fetchEntriesInSources: (NSArray *) sourcesList - matching: (NSString *) filter + matching: (NSString *) filter inDomain: (NSString *) domain { NSMutableArray *contacts; @@ -1178,7 +1159,7 @@ static Class NSNullK; { currentSource = [_sources objectForKey: sourceID]; [contacts addObjectsFromArray: - [currentSource fetchContactsMatching: filter + [currentSource fetchContactsMatching: filter inDomain: domain]]; } From 08f57f6ad527f0f0b55fbf43c69c3609bc389bd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Garc=C3=ADa=20S=C3=A1ez?= Date: Wed, 23 Sep 2015 15:49:53 +0200 Subject: [PATCH 08/11] SOGoUserManager: get domain after authentication For multidomain source which has no domain defined, we get the domain from the username which must have @domain as suffix --- SoObjects/SOGo/SOGoUserManager.m | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/SoObjects/SOGo/SOGoUserManager.m b/SoObjects/SOGo/SOGoUserManager.m index fe81be52d..60f69f9a3 100644 --- a/SoObjects/SOGo/SOGoUserManager.m +++ b/SoObjects/SOGo/SOGoUserManager.m @@ -477,7 +477,24 @@ static Class NSNullK; } if (checkOK && *domain == nil) - *domain = [sogoSource domain]; + { + SOGoSystemDefaults *sd = [SOGoSystemDefaults sharedSystemDefaults]; + BOOL multidomainSource = [sd enableDomainBasedUID] && + [sogoSource domain] == nil; + if (multidomainSource) + { + NSArray *parts = [login componentsSeparatedByString: @"@"]; + if ([parts count] != 2) + { + [self errorWithFormat: @"Authenticated with multidomain source " + @"but login is not an email (%@).", login]; + return NO; + } + *domain = [parts objectAtIndex: 1]; + } + else + *domain = [sogoSource domain]; + } return checkOK; } From 8cfb0f0d44830fe8972990dd781b77cc2372070b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Garc=C3=ADa=20S=C3=A1ez?= Date: Wed, 23 Sep 2015 15:52:41 +0200 Subject: [PATCH 09/11] Avoid inserting second email for Contacts When we have a contact with an email, avoid generating another one with SOGoMailDomain value (normally we ended up with a contact with two identical emails on 'emails' key and for multidomain source we would had ended up with an email @localhost) --- SoObjects/SOGo/SOGoUserManager.m | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/SoObjects/SOGo/SOGoUserManager.m b/SoObjects/SOGo/SOGoUserManager.m index 60f69f9a3..4425a8a8e 100644 --- a/SoObjects/SOGo/SOGoUserManager.m +++ b/SoObjects/SOGo/SOGoUserManager.m @@ -749,21 +749,19 @@ static Class NSNullK; SOGoDomainDefaults *dd; domain = [contact objectForKey: @"c_domain"]; - if ([domain length]) - dd = [SOGoDomainDefaults defaultsForDomain: domain]; - else - dd = [SOGoSystemDefaults sharedSystemDefaults]; + dd = [SOGoDomainDefaults defaultsForDomain: domain]; emails = [contact objectForKey: @"emails"]; - uid = [contact objectForKey: @"c_uid"]; - if ([uid rangeOfString: @"@"].location == NSNotFound) - systemEmail - = [NSString stringWithFormat: @"%@@%@", uid, [dd mailDomain]]; - else - systemEmail = uid; - - // We always add the system email, which will always be returned - // by SOGoUser -systemEmail. - [emails addObject: systemEmail]; + if ([emails count] == 0) + { + uid = [contact objectForKey: @"c_uid"]; + if ([uid rangeOfString: @"@"].location == NSNotFound) + systemEmail = [NSString stringWithFormat: @"%@@%@", uid, [dd mailDomain]]; + else + systemEmail = uid; + // We always add the system email, which will always be returned + // by SOGoUser -systemEmail. + [emails addObject: systemEmail]; + } [contact setObject: [emails objectAtIndex: 0] forKey: @"c_email"]; } From a6bbe13f9bb2766651a45b947bdc50135edc9f35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20P=C3=A9rez-Aradros=20Herce?= Date: Thu, 5 Nov 2015 17:47:43 +0100 Subject: [PATCH 10/11] Add missing header files --- SoObjects/SOGo/GNUmakefile | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/SoObjects/SOGo/GNUmakefile b/SoObjects/SOGo/GNUmakefile index 40e19725b..65713871a 100644 --- a/SoObjects/SOGo/GNUmakefile +++ b/SoObjects/SOGo/GNUmakefile @@ -32,6 +32,12 @@ SOGo_HEADER_FILES = \ SOGoGCSFolder.h \ SOGoParentFolder.h \ SOGoUserFolder.h \ + SOGoSource.h \ + SOGoSystemDefaults.h \ + SOGoDomainDefaults.h \ + SOGoLDAPDefaults.h \ + SOGoDefaultsSource.h \ + SOGoUserDefaults.h \ \ SOGoSieveManager.h \ \ From ec598321c4d1c2dedf509f6785a8f6673162c1f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20P=C3=A9rez-Aradros=20Herce?= Date: Tue, 10 Nov 2015 17:38:35 +0100 Subject: [PATCH 11/11] Add user defined user source --- SoObjects/SOGo/SOGoUserManager.m | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/SoObjects/SOGo/SOGoUserManager.m b/SoObjects/SOGo/SOGoUserManager.m index 4425a8a8e..67eabaf10 100644 --- a/SoObjects/SOGo/SOGoUserManager.m +++ b/SoObjects/SOGo/SOGoUserManager.m @@ -67,10 +67,12 @@ static Class NSNullK; if (type) { - if ([type isEqualToString: @"ldap"]) + if ([type caseInsensitiveCompare: @"ldap"] == NSOrderedSame) sourceClass = @"LDAPSource"; - else if ([type isEqualToString: @"sql"]) + else if ([type caseInsensitiveCompare: @"sql"] == NSOrderedSame) sourceClass = @"SQLSource"; + else if (NSClassFromString(type)) + sourceClass = type; else { [NSException raise: @"SOGoUserManagerRegistryException" @@ -121,7 +123,7 @@ static Class NSNullK; return NO; } - type = [[udSource objectForKey: @"type"] lowercaseString]; + type = [udSource objectForKey: @"type"]; c = NSClassFromString([_registry sourceClassForType: type]); sogoSource = [c sourceFromUDSource: udSource inDomain: domain]; [_sources setObject: sogoSource forKey: sourceID];