1 /* LDAPSource.m - this file is part of SOGo
3 * Copyright (C) 2007 Inverse groupe conseil
5 * Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
7 * This file is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2, or (at your option)
12 * This file is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; see the file COPYING. If not, write to
19 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
23 #import <Foundation/NSArray.h>
24 #import <Foundation/NSDictionary.h>
25 #import <Foundation/NSString.h>
27 #import <EOControl/EOControl.h>
28 #import <NGLdap/NGLdapConnection.h>
29 #import <NGLdap/NGLdapAttribute.h>
30 #import <NGLdap/NGLdapEntry.h>
32 #import "LDAPSource.h"
34 static NSArray *commonSearchFields;
36 @implementation LDAPSource
40 if (!commonSearchFields)
42 commonSearchFields = [NSArray arrayWithObjects:
55 @"mozillaHomeCountryName",
72 @"facsimileTelephoneNumber",
75 @"mozillaSecondEmail",
76 @"xmozillasecondemail",
88 @"mozillaHomePostalCode",
89 @"mozillaHomeLocalityName",
90 @"mozillaWorkStreet2",
91 @"mozillaUseHtmlMail",
92 @"xmozillausehtmlmail",
93 @"mozillaHomeStreet2",
111 [commonSearchFields retain];
115 + (id) sourceFromUDSource: (NSDictionary *) udSource
119 newSource = [[self alloc] initFromUDSource: udSource];
120 [newSource autorelease];
127 if ((self = [super init]))
135 IDField = @"cn"; /* the first part of a user DN */
140 ldapConnection = nil;
141 searchAttributes = nil;
156 [bindFields release];
157 [ldapConnection release];
161 - (id) initFromUDSource: (NSDictionary *) udSource
165 [self setBindDN: [udSource objectForKey: @"bindDN"]
166 hostname: [udSource objectForKey: @"hostname"]
167 port: [udSource objectForKey: @"port"]
168 andPassword: [udSource objectForKey: @"bindPassword"]];
169 [self setBaseDN: [udSource objectForKey: @"baseDN"]
170 IDField: [udSource objectForKey: @"IDFieldName"]
171 CNField: [udSource objectForKey: @"CNFieldName"]
172 UIDField: [udSource objectForKey: @"UIDFieldName"]
173 andBindFields: [udSource objectForKey: @"bindFields"]];
178 - (void) setBindDN: (NSString *) newBindDN
179 hostname: (NSString *) newBindHostname
180 port: (NSString *) newBindPort
181 andPassword: (NSString *) newBindPassword
183 ASSIGN (bindDN, newBindDN);
184 ASSIGN (hostname, newBindHostname);
186 port = [newBindPort intValue];
187 ASSIGN (password, newBindPassword);
190 - (void) setBaseDN: (NSString *) newBaseDN
191 IDField: (NSString *) newIDField
192 CNField: (NSString *) newCNField
193 UIDField: (NSString *) newUIDField
194 andBindFields: (NSString *) newBindFields
196 ASSIGN (baseDN, newBaseDN);
198 ASSIGN (IDField, newIDField);
200 ASSIGN (CNField, newCNField);
202 ASSIGN (UIDField, newUIDField);
204 ASSIGN (bindFields, newBindFields);
207 - (void) _initLDAPConnection
209 ldapConnection = [[NGLdapConnection alloc] initWithHostName: hostname
211 [ldapConnection bindWithMethod: @"simple"
213 credentials: password];
216 /* user management */
217 - (EOQualifier *) _qualifierForBindFilter: (NSString *) uid
220 NSEnumerator *fields;
221 NSString *currentField;
223 qs = [NSMutableString string];
224 fields = [[bindFields componentsSeparatedByString: @","] objectEnumerator];
225 currentField = [fields nextObject];
228 [qs appendFormat: @"OR (%@='%@')", currentField, uid];
229 currentField = [fields nextObject];
231 [qs deleteCharactersInRange: NSMakeRange (0, 3)];
233 return [EOQualifier qualifierWithQualifierFormat: qs];
236 - (NSString *) _fetchUserDNForLogin: (NSString *) loginToCheck
239 NSEnumerator *entries;
240 NGLdapEntry *userEntry;
242 [self _initLDAPConnection];
243 entries = [ldapConnection deepSearchAtBaseDN: baseDN
244 qualifier: [self _qualifierForBindFilter: loginToCheck]
245 attributes: [NSArray arrayWithObject: @"dn"]];
246 userEntry = [entries nextObject];
248 userDN = [userEntry dn];
251 [ldapConnection release];
256 - (BOOL) checkLogin: (NSString *) loginToCheck
257 andPassword: (NSString *) passwordToCheck
261 NGLdapConnection *bindConnection;
263 if ([loginToCheck length] > 0)
265 bindConnection = [[NGLdapConnection alloc] initWithHostName: hostname
268 userDN = [self _fetchUserDNForLogin: loginToCheck];
270 userDN = [NSString stringWithFormat: @"%@=%@,%@",
271 IDField, loginToCheck, baseDN];
275 didBind = [bindConnection bindWithMethod: @"simple"
277 credentials: passwordToCheck];
282 [bindConnection release];
290 /* contact management */
291 - (EOQualifier *) _qualifierForFilter: (NSString *) filter
294 EOQualifier *qualifier;
296 if ([filter length] > 0)
298 if ([filter isEqualToString: @"."])
301 qs = [NSString stringWithFormat:
304 @"OR (displayName='%@*')"
306 @"OR (telephoneNumber='*%@*')",
307 filter, filter, filter, filter, filter];
308 qualifier = [EOQualifier qualifierWithQualifierFormat: qs];
316 - (EOQualifier *) _qualifierForUIDFilter: (NSString *) uid
320 qs = [NSString stringWithFormat: (@"(%@='%@') OR (mail='%@')"
321 @" OR (mozillaSecondEmail='%@')"
322 @" OR (xmozillasecondemail='%@')"),
323 UIDField, uid, uid, uid, uid];
325 return [EOQualifier qualifierWithQualifierFormat: qs];
328 - (NSArray *) _searchAttributes
330 if (!searchAttributes)
332 searchAttributes = [NSMutableArray new];
334 [searchAttributes addObject: CNField];
336 [searchAttributes addObject: UIDField];
337 [searchAttributes addObjectsFromArray: commonSearchFields];
340 return searchAttributes;
343 - (NSArray *) allEntryIDs
346 NSEnumerator *entries;
347 NGLdapEntry *currentEntry;
350 ids = [NSMutableArray array];
352 [self _initLDAPConnection];
353 entries = [ldapConnection deepSearchAtBaseDN: baseDN
355 attributes: [NSArray arrayWithObject: IDField]];
358 currentEntry = [entries nextObject];
361 value = [[currentEntry attributeWithName: IDField]
362 stringValueAtIndex: 0];
363 if ([value length] > 0)
364 [ids addObject: value];
365 currentEntry = [entries nextObject];
368 [ldapConnection release];
373 - (NSDictionary *) _convertLDAPEntryToContact: (NGLdapEntry *) ldapEntry
375 NSMutableDictionary *contactEntry;
376 NSEnumerator *attributes;
377 NSString *currentAttribute, *value;
379 contactEntry = [NSMutableDictionary dictionary];
380 attributes = [[self _searchAttributes] objectEnumerator];
381 currentAttribute = [attributes nextObject];
382 while (currentAttribute)
384 value = [[ldapEntry attributeWithName: currentAttribute]
385 stringValueAtIndex: 0];
387 [contactEntry setObject: value forKey: currentAttribute];
388 currentAttribute = [attributes nextObject];
390 value = [[ldapEntry attributeWithName: IDField] stringValueAtIndex: 0];
393 [contactEntry setObject: value forKey: @"c_name"];
394 value = [[ldapEntry attributeWithName: UIDField] stringValueAtIndex: 0];
397 [contactEntry setObject: value forKey: @"c_uid"];
398 value = [[ldapEntry attributeWithName: CNField] stringValueAtIndex: 0];
401 [contactEntry setObject: value forKey: @"c_cn"];
406 - (NSArray *) fetchContactsMatching: (NSString *) match
408 NSMutableArray *contacts;
409 NGLdapEntry *currentEntry;
410 NSEnumerator *entries;
412 contacts = [NSMutableArray array];
414 if ([match length] > 0)
416 [self _initLDAPConnection];
417 entries = [ldapConnection deepSearchAtBaseDN: baseDN
418 qualifier: [self _qualifierForFilter: match]
419 attributes: [self _searchAttributes]];
422 currentEntry = [entries nextObject];
426 [self _convertLDAPEntryToContact: currentEntry]];
427 currentEntry = [entries nextObject];
430 [ldapConnection release];
436 - (NSDictionary *) lookupContactEntry: (NSString *) entryID;
438 NSDictionary *contactEntry;
439 NGLdapEntry *ldapEntry;
443 if ([entryID length] > 0)
445 [self _initLDAPConnection];
447 = [ldapConnection entryAtDN: [NSString stringWithFormat: @"%@=%@,%@",
448 IDField, entryID, baseDN]
449 attributes: [self _searchAttributes]];
451 contactEntry = [self _convertLDAPEntryToContact: ldapEntry];
452 [ldapConnection release];
458 - (NSDictionary *) lookupContactEntryWithUIDorEmail: (NSString *) uid;
460 NSDictionary *contactEntry;
461 NGLdapEntry *ldapEntry;
462 NSEnumerator *entries;
463 EOQualifier *qualifier;
467 if ([uid length] > 0)
469 [self _initLDAPConnection];
470 qualifier = [self _qualifierForUIDFilter: uid];
471 entries = [ldapConnection deepSearchAtBaseDN: baseDN
473 attributes: [self _searchAttributes]];
474 ldapEntry = [entries nextObject];
476 contactEntry = [self _convertLDAPEntryToContact: ldapEntry];
477 [ldapConnection release];