diff --git a/ChangeLog b/ChangeLog index 1f0ab2025..9d97a55a7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2011-11-17 Wolfgang Sourdeau + + * OpenChange/MAPIStoreSamDBUtils.m: new module containing helpers + pertaining to the SamDB. + (MAPIStoreSamDBUserAttribute): new function that returns the value + of a specified key from a user record matching one simple criteria. + (MAPIStoreInternalEntrydId, MAPIStoreExternalEntryId): moved + functions from MAPIStoreMessage.m. + + * OpenChange/MAPIStoreMessage.m (MAPIStoreInternalEntryId): now + takes a ldb_context * parameter pointing to the samdb, which + enables us: 1) to return the real legacyExchangeDN 2) to make use + of sAMAccountName as search parameter for the username. + 2011-11-16 Ludovic Marcotte * SoObjects/SOGo/SOGoSieveManager.m (-updateFiltersForLogin:...) diff --git a/OpenChange/MAPIStoreAppointmentWrapper.h b/OpenChange/MAPIStoreAppointmentWrapper.h index 4fcf2b4d8..fa1cb8f20 100644 --- a/OpenChange/MAPIStoreAppointmentWrapper.h +++ b/OpenChange/MAPIStoreAppointmentWrapper.h @@ -39,6 +39,7 @@ extern NSTimeZone *utcTZ; @interface MAPIStoreAppointmentWrapper : NSObject { + struct mapistore_connection_info *connInfo; iCalCalendar *calendar; iCalEvent *event; NSTimeZone *timeZone; @@ -56,11 +57,13 @@ extern NSTimeZone *utcTZ; + (id) wrapperWithICalEvent: (iCalEvent *) newEvent andUser: (SOGoUser *) newUser andSenderEmail: (NSString *) newSenderEmail - inTimeZone: (NSTimeZone *) newTimeZone; + inTimeZone: (NSTimeZone *) newTimeZone + withConnectionInfo: (struct mapistore_connection_info *) newConnInfo; - (id) initWithICalEvent: (iCalEvent *) newEvent andUser: (SOGoUser *) newUser andSenderEmail: (NSString *) newSenderEmail - inTimeZone: (NSTimeZone *) newTimeZone; + inTimeZone: (NSTimeZone *) newTimeZone + withConnectionInfo: (struct mapistore_connection_info *) newConnInfo; /* getters */ - (void) fillMessageData: (struct mapistore_message *) dataPtr diff --git a/OpenChange/MAPIStoreAppointmentWrapper.m b/OpenChange/MAPIStoreAppointmentWrapper.m index 82753c076..c1f0e8b90 100644 --- a/OpenChange/MAPIStoreAppointmentWrapper.m +++ b/OpenChange/MAPIStoreAppointmentWrapper.m @@ -37,8 +37,8 @@ #import #import -#import "MAPIStoreMessage.h" #import "MAPIStoreRecurrenceUtils.h" +#import "MAPIStoreSamDBUtils.h" #import "MAPIStoreTypes.h" #import "NSData+MAPIStore.h" #import "NSDate+MAPIStore.h" @@ -80,13 +80,15 @@ static NSCharacterSet *hexCharacterSet = nil; andUser: (SOGoUser *) newUser andSenderEmail: (NSString *) newSenderEmail inTimeZone: (NSTimeZone *) newTimeZone + withConnectionInfo: (struct mapistore_connection_info *) newConnInfo { MAPIStoreAppointmentWrapper *wrapper; wrapper = [[self alloc] initWithICalEvent: newEvent andUser: newUser andSenderEmail: newSenderEmail - inTimeZone: newTimeZone]; + inTimeZone: newTimeZone + withConnectionInfo: newConnInfo]; [wrapper autorelease]; return wrapper; @@ -96,6 +98,7 @@ static NSCharacterSet *hexCharacterSet = nil; { if ((self = [super init])) { + connInfo = NULL; calendar = nil; event = nil; timeZone = nil; @@ -178,9 +181,11 @@ static NSCharacterSet *hexCharacterSet = nil; andUser: (SOGoUser *) newUser andSenderEmail: (NSString *) newSenderEmail inTimeZone: (NSTimeZone *) newTimeZone + withConnectionInfo: (struct mapistore_connection_info *) newConnInfo { if ((self = [self init])) { + connInfo = newConnInfo; ASSIGN (event, newEvent); ASSIGN (calendar, [event parent]); ASSIGN (timeZone, newTimeZone); @@ -256,7 +261,7 @@ static NSCharacterSet *hexCharacterSet = nil; { username = [contactInfos objectForKey: @"c_uid"]; recipient->username = [username asUnicodeInMemCtx: msgData]; - entryId = MAPIStoreInternalEntryId (username); + entryId = MAPIStoreInternalEntryId (connInfo->sam_ctx, username); } else { @@ -357,7 +362,7 @@ static NSCharacterSet *hexCharacterSet = nil; { username = [contactInfos objectForKey: @"c_uid"]; recipient->username = [username asUnicodeInMemCtx: msgData]; - entryId = MAPIStoreInternalEntryId (username); + entryId = MAPIStoreInternalEntryId (connInfo->sam_ctx, username); } else { @@ -727,7 +732,7 @@ static NSCharacterSet *hexCharacterSet = nil; if (contactInfos) { username = [contactInfos objectForKey: @"c_uid"]; - entryId = MAPIStoreInternalEntryId (username); + entryId = MAPIStoreInternalEntryId (connInfo->sam_ctx, username); } else entryId = MAPIStoreExternalEntryId (cn, email); diff --git a/OpenChange/MAPIStoreCalendarMessage.m b/OpenChange/MAPIStoreCalendarMessage.m index 33b7ffe9d..73729cc66 100644 --- a/OpenChange/MAPIStoreCalendarMessage.m +++ b/OpenChange/MAPIStoreCalendarMessage.m @@ -104,15 +104,18 @@ - (MAPIStoreAppointmentWrapper *) appointmentWrapper { iCalEvent *event; + MAPIStoreContext *context; if (!appointmentWrapper) { event = [sogoObject component: NO secure: NO]; + context = [self context]; ASSIGN (appointmentWrapper, [MAPIStoreAppointmentWrapper wrapperWithICalEvent: event - andUser: [[self context] activeUser] + andUser: [context activeUser] andSenderEmail: nil - inTimeZone: [self ownerTimeZone]]); + inTimeZone: [self ownerTimeZone] + withConnectionInfo: [context connectionInfo]]); } return appointmentWrapper; diff --git a/OpenChange/MAPIStoreMailMessage.m b/OpenChange/MAPIStoreMailMessage.m index 7ab44bd2b..8c165cc6e 100644 --- a/OpenChange/MAPIStoreMailMessage.m +++ b/OpenChange/MAPIStoreMailMessage.m @@ -48,6 +48,7 @@ #import "MAPIStoreMailAttachment.h" #import "MAPIStoreMailFolder.h" #import "MAPIStoreMapping.h" +#import "MAPIStoreSamDBUtils.h" #import "MAPIStoreTypes.h" #import "MAPIStoreMailMessage.h" @@ -263,6 +264,7 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data) iCalCalendar *calendar; iCalEvent *event; NSString *stringValue, *senderEmail; + MAPIStoreContext *context; if (!appointmentWrapper) { @@ -280,11 +282,13 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data) senderEmail = [[from objectAtIndex: 0] email]; else senderEmail = nil; + context = [self context]; appointmentWrapper = [MAPIStoreAppointmentWrapper wrapperWithICalEvent: event - andUser: [[self context] activeUser] + andUser: [context activeUser] andSenderEmail: senderEmail - inTimeZone: [self ownerTimeZone]]; + inTimeZone: [self ownerTimeZone] + withConnectionInfo: [context connectionInfo]]; [appointmentWrapper retain]; } } @@ -721,6 +725,7 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data) NSDictionary *contactInfos; NGMailAddress *ngAddress; NSData *entryId; + struct ldb_context *samCtx; int rc; if (fullMail) @@ -743,7 +748,8 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data) if (contactInfos) { username = [contactInfos objectForKey: @"c_uid"]; - entryId = MAPIStoreInternalEntryId (username); + samCtx = [[self context] connectionInfo]->sam_ctx; + entryId = MAPIStoreInternalEntryId (samCtx, username); } else entryId = MAPIStoreExternalEntryId (cn, email); @@ -1349,9 +1355,11 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data) NSData *entryId; NSDictionary *contactInfos; SOGoUserManager *mgr; + struct ldb_context *samCtx; struct mapistore_message *msgData; struct mapistore_message_recipient *recipient; + samCtx = [[self context] connectionInfo]->sam_ctx; [super getMessageData: &msgData inMemCtx: memCtx]; if (!headerSetup) @@ -1397,7 +1405,7 @@ _compareBodyKeysByPriority (id entry1, id entry2, void *data) { username = [contactInfos objectForKey: @"c_uid"]; recipient->username = [username asUnicodeInMemCtx: msgData]; - entryId = MAPIStoreInternalEntryId (username); + entryId = MAPIStoreInternalEntryId (samCtx, username); } else { diff --git a/OpenChange/MAPIStoreMailVolatileMessage.m b/OpenChange/MAPIStoreMailVolatileMessage.m index bc62b181a..5952eb405 100644 --- a/OpenChange/MAPIStoreMailVolatileMessage.m +++ b/OpenChange/MAPIStoreMailVolatileMessage.m @@ -54,6 +54,7 @@ #import "MAPIStoreMailFolder.h" #import "MAPIStoreMIME.h" #import "MAPIStoreMapping.h" +#import "MAPIStoreSamDBUtils.h" #import "MAPIStoreTypes.h" #import "NSData+MAPIStore.h" #import "NSObject+MAPIStore.h" @@ -249,10 +250,13 @@ static NSString *recTypes[] = { @"orig", @"to", @"cc", @"bcc" }; NSData *entryId; NSDictionary *allRecipients, *dict, *contactInfos; SOGoUserManager *mgr; + struct ldb_context *samCtx; struct mapistore_message *msgData; struct mapistore_message_recipient *recipient; enum ulRecipClass type; + samCtx = [[self context] connectionInfo]->sam_ctx; + [super getMessageData: &msgData inMemCtx: memCtx]; allRecipients = [[sogoObject properties] objectForKey: @"recipients"]; @@ -295,7 +299,7 @@ static NSString *recTypes[] = { @"orig", @"to", @"cc", @"bcc" }; { username = [contactInfos objectForKey: @"c_uid"]; recipient->username = [username asUnicodeInMemCtx: msgData]; - entryId = MAPIStoreInternalEntryId (username); + entryId = MAPIStoreInternalEntryId (samCtx, username); } else { diff --git a/OpenChange/MAPIStoreMessage.h b/OpenChange/MAPIStoreMessage.h index 85c3d2d9b..83dfa57a2 100644 --- a/OpenChange/MAPIStoreMessage.h +++ b/OpenChange/MAPIStoreMessage.h @@ -37,9 +37,6 @@ #import "MAPIStoreObject.h" -extern NSData *MAPIStoreInternalEntryId (NSString *username); -extern NSData *MAPIStoreExternalEntryId (NSString *cn, NSString *email); - @interface MAPIStoreMessage : MAPIStoreObject { NSArray *attachmentKeys; diff --git a/OpenChange/MAPIStoreMessage.m b/OpenChange/MAPIStoreMessage.m index 6c912c6e3..f2c78814e 100644 --- a/OpenChange/MAPIStoreMessage.m +++ b/OpenChange/MAPIStoreMessage.m @@ -36,6 +36,7 @@ #import "MAPIStoreContext.h" #import "MAPIStoreFolder.h" #import "MAPIStorePropertySelectors.h" +#import "MAPIStoreSamDBUtils.h" #import "MAPIStoreTypes.h" #import "NSData+MAPIStore.h" #import "NSObject+MAPIStore.h" @@ -54,104 +55,6 @@ static NSString *resourcesDir = nil; -NSData * -MAPIStoreInternalEntryId (NSString *username) -{ - NSMutableData *entryId; - static uint8_t providerUid[] = { 0xdc, 0xa7, 0x40, 0xc8, - 0xc0, 0x42, 0x10, 0x1a, - 0xb4, 0xb9, 0x08, 0x00, - 0x2b, 0x2f, 0xe1, 0x82 }; - NSString *x500dn; - - /* structure: - flags: 32 - provideruid: 32 * 4 - version: 32 - type: 32 - X500DN: variable */ - - entryId = [NSMutableData dataWithCapacity: 256]; - [entryId appendUInt32: 0]; // flags - [entryId appendBytes: providerUid length: 16]; // provideruid - [entryId appendUInt32: 1]; // version - [entryId appendUInt32: 0]; // type (local mail user) - - /* X500DN */ - /* FIXME: the DN will likely work on DEMO installations for now but we - really should get the dn prefix from the server */ - x500dn = [NSString stringWithFormat: @"/O=FIRST ORGANIZATION" - @"/OU=FIRST ADMINISTRATIVE GROUP" - @"/CN=RECIPIENTS/CN=%@", username]; - [entryId appendData: [x500dn dataUsingEncoding: NSISOLatin1StringEncoding]]; - [entryId appendUInt8: 0]; - - return entryId; -} - -NSData * -MAPIStoreExternalEntryId (NSString *cn, NSString *email) -{ - NSMutableData *entryId; - static uint8_t providerUid[] = { 0x81, 0x2b, 0x1f, 0xa4, - 0xbe, 0xa3, 0x10, 0x19, - 0x9d, 0x6e, 0x00, 0xdd, - 0x01, 0x0f, 0x54, 0x02 }; - uint8_t flags21, flags22; - - /* structure: - flags: 32 - provideruid: 32 * 4 - version: 16 - { - PaD: 1 - MAE: 2 - Format: 4 - M: 1 - U: 1 - R: 2 - L: 1 - Pad: 4 - } - DisplayName: variable - AddressType: variable - EmailAddress: variable */ - - entryId = [NSMutableData dataWithCapacity: 256]; - [entryId appendUInt32: 0]; // flags - [entryId appendBytes: providerUid length: 16]; // provideruid - [entryId appendUInt16: 0]; // version - - flags21 = 0; /* PaD, MAE, R, Pad = 0 */ - flags21 |= 0x16; /* Format: text and HTML */ - flags21 |= 0x01; /* M: mime format */ - - flags22 = 0x90; /* U: unicode, L: no lookup */ - [entryId appendUInt8: flags21]; - [entryId appendUInt8: flags22]; - - /* DisplayName */ - if (!cn) - cn = @""; - [entryId - appendData: [cn dataUsingEncoding: NSUTF16LittleEndianStringEncoding]]; - [entryId appendUInt16: 0]; - - /* AddressType */ - [entryId - appendData: [@"SMTP" dataUsingEncoding: NSUTF16LittleEndianStringEncoding]]; - [entryId appendUInt16: 0]; - - /* EMailAddress */ - if (!email) - email = @""; - [entryId - appendData: [email dataUsingEncoding: NSUTF16LittleEndianStringEncoding]]; - [entryId appendUInt16: 0]; - - return entryId; -} - /* rtf conversion via unrtf */ static int unrtf_data_output (void *data, const char *str, size_t str_len) diff --git a/OpenChange/MAPIStoreSamDBUtils.h b/OpenChange/MAPIStoreSamDBUtils.h new file mode 100644 index 000000000..c58a12686 --- /dev/null +++ b/OpenChange/MAPIStoreSamDBUtils.h @@ -0,0 +1,37 @@ +/* MAPIStoreSamDBUtils.h - this file is part of SOGo + * + * Copyright (C) 2011 Inverse inc + * + * Author: Wolfgang Sourdeau + * + * 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 + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef MAPISTORESAMDBUTILS_H +#define MAPISTORESAMDBUTILS_H + +@class NSString; + +struct ldb_context; + +NSString *MAPIStoreSamDBUserAttribute (struct ldb_context *samCtx, + NSString *userKey, + NSString *value, + NSString *attributeName); +NSData *MAPIStoreInternalEntryId (struct ldb_context *, NSString *username); +NSData *MAPIStoreExternalEntryId (NSString *cn, NSString *email); + +#endif /* MAPISTORESAMDBUTILS_H */ diff --git a/OpenChange/MAPIStoreSamDBUtils.m b/OpenChange/MAPIStoreSamDBUtils.m new file mode 100644 index 000000000..4d7caff63 --- /dev/null +++ b/OpenChange/MAPIStoreSamDBUtils.m @@ -0,0 +1,165 @@ +/* MAPIStoreSamDBUtils.m - this file is part of SOGo + * + * Copyright (C) 2011 Inverse inc + * + * Author: Wolfgang Sourdeau + * + * 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 + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#import +#import +#include +#include + +#import "NSData+MAPIStore.h" + +#import "MAPIStoreSamDBUtils.h" + +NSString * +MAPIStoreSamDBUserAttribute (struct ldb_context *samCtx, + NSString *userKey, + NSString *value, + NSString *attributeName) +{ + NSString *resultValue = nil; + const char *attrs[] = { "", NULL }; + NSString *searchFormat; + const char *result; + struct ldb_result *res = NULL; + TALLOC_CTX *memCtx; + int ret; + + memCtx = talloc_zero(NULL, TALLOC_CTX); + + attrs[0] = [attributeName UTF8String]; + searchFormat + = [NSString stringWithFormat: @"(&(objectClass=user)(%@=%%s))", userKey]; + ret = ldb_search (samCtx, memCtx, &res, ldb_get_default_basedn(samCtx), + LDB_SCOPE_SUBTREE, attrs, + [searchFormat UTF8String], + [value UTF8String]); + if (ret == LDB_SUCCESS && res->count == 1) + { + result = ldb_msg_find_attr_as_string (res->msgs[0], attrs[0], NULL); + if (result) + resultValue = [NSString stringWithUTF8String: result]; + } + + talloc_free (memCtx); + + return resultValue; +} + +NSData * +MAPIStoreInternalEntryId (struct ldb_context *samCtx, NSString *username) +{ + static const uint8_t const providerUid[] = { 0xdc, 0xa7, 0x40, 0xc8, + 0xc0, 0x42, 0x10, 0x1a, + 0xb4, 0xb9, 0x08, 0x00, + 0x2b, 0x2f, 0xe1, 0x82 }; + NSMutableData *entryId; + NSData *legacyDNData; + NSString *legacyDN; + + /* structure: + flags: 32 + provideruid: 32 * 4 + version: 32 + type: 32 + X500DN: variable */ + + legacyDN = MAPIStoreSamDBUserAttribute (samCtx, @"sAMAccountName", username, + @"legacyExchangeDN"); + if (legacyDN) + { + entryId = [NSMutableData dataWithCapacity: 256]; + [entryId appendUInt32: 0]; // flags + [entryId appendBytes: providerUid length: 16]; // provideruid + [entryId appendUInt32: 1]; // version + [entryId appendUInt32: 0]; // type (local mail user) + legacyDNData = [legacyDN dataUsingEncoding: NSASCIIStringEncoding]; + [entryId appendData: legacyDNData]; // x500dn + [entryId appendUInt8: 0]; // end of string + } + else + entryId = nil; + + return entryId; +} + +NSData * +MAPIStoreExternalEntryId (NSString *cn, NSString *email) +{ + NSMutableData *entryId; + static uint8_t providerUid[] = { 0x81, 0x2b, 0x1f, 0xa4, + 0xbe, 0xa3, 0x10, 0x19, + 0x9d, 0x6e, 0x00, 0xdd, + 0x01, 0x0f, 0x54, 0x02 }; + uint8_t flags21, flags22; + + /* structure: + flags: 32 + provideruid: 32 * 4 + version: 16 + { + PaD: 1 + MAE: 2 + Format: 4 + M: 1 + U: 1 + R: 2 + L: 1 + Pad: 4 + } + DisplayName: variable + AddressType: variable + EmailAddress: variable */ + + entryId = [NSMutableData dataWithCapacity: 256]; + [entryId appendUInt32: 0]; // flags + [entryId appendBytes: providerUid length: 16]; // provideruid + [entryId appendUInt16: 0]; // version + + flags21 = 0; /* PaD, MAE, R, Pad = 0 */ + flags21 |= 0x16; /* Format: text and HTML */ + flags21 |= 0x01; /* M: mime format */ + + flags22 = 0x90; /* U: unicode, L: no lookup */ + [entryId appendUInt8: flags21]; + [entryId appendUInt8: flags22]; + + /* DisplayName */ + if (!cn) + cn = @""; + [entryId + appendData: [cn dataUsingEncoding: NSUTF16LittleEndianStringEncoding]]; + [entryId appendUInt16: 0]; + + /* AddressType */ + [entryId + appendData: [@"SMTP" dataUsingEncoding: NSUTF16LittleEndianStringEncoding]]; + [entryId appendUInt16: 0]; + + /* EMailAddress */ + if (!email) + email = @""; + [entryId + appendData: [email dataUsingEncoding: NSUTF16LittleEndianStringEncoding]]; + [entryId appendUInt16: 0]; + + return entryId; +}