diff --git a/ChangeLog b/ChangeLog index 3efe0f5d3..f8c133f33 100644 --- a/ChangeLog +++ b/ChangeLog @@ -59,6 +59,93 @@ -[iCalEntityObject categories] returns an NSArray that we need to convert to a string for the database content. +2011-12-02 Wolfgang Sourdeau + + * OpenChange/MAPIStoreNotesMessage.m + (-getPrMessageClass:inMemCtx:): explicit method. + (-getPrSubject:inMemCtx:): explicit method. + + * OpenChange/MAPIStoreMessage.m (-getPrAccess:inMemCtx:) + (-getPrAccessLevel:inMemCtx:): reimplemented methods in a generic + way just like the MAPIStoreFolder versions. + + * OpenChange/MAPIStoreFSMessage.m (-subscriberCanModifyMessage): + handle the case where the message is being created. + + * OpenChange/MAPIStoreFSFolder.m + (-messageKeysMatchingQualifier:andSortOrderings:): ensure the + active user can read the folder messages before returning them. + +2011-12-01 Wolfgang Sourdeau + + * OpenChange/MAPIStoreFAIMessage.m (-subscriberCanReadMessage) + (-subscriberCanModifyMessage): always return "NO" for subscribers. + + * OpenChange/MAPIStoreFSFolder.m: mapped role strings into + variables. + + * OpenChange/MAPIStoreGCSMessage.m (-getPrAccess:inMemCtx:) + (-getPrAccessLevel:inMemCtx:): return a value based on the ACL + getters below. + + * OpenChange/MAPIStoreFSMessage.m (-subscriberCanReadMessage): + returns YES when the message is of class + "IPM.Microsoft.ScheduleData.FreeBusy", as a hack until freebusy + messages are handled by the backend. + + * OpenChange/MAPIStoreContext.m (_prepareContextClass): now return + the context via a pointer parameter. Return a proper "enum + mapistore_error" value. + + * OpenChange/MAPIStoreCalendarMessage.m (-appointmentWrapper): + pass the owner user as parameter to the appointment wrapper + contructor rather than the active user. + (-save): make use of the owner user coordinates instead of the + ones of the active user. Handle the "sent-by" parameter for the + organizer element. + + * OpenChange/MAPIStoreFolder.m + (-openMessage:withMID:forWriting:inMemCtx:): takes a new + "forWriting:" parameter and make use of subscriberCanModifyMessage + and subscriberCanReadMessage to return a proper error code, if + needed. + + * OpenChange/MAPIStoreSOGo.m (sogo_folder_open_message): added the + "write_access" parameter. + + * OpenChange/MAPIStoreTasksMessage.m: + invoke component:secure: with the secure parameter set to "YES" in + all accessors that requires the iCalTask object. + + * OpenChange/MAPIStoreCalendarMessage.m (-appointmentWrapper): + invoke component:secure: with the secure parameter set to "YES". + + * OpenChange/MAPIStoreTasksMessageTable.m + (-evaluatePropertyRestriction:intoQualifier:): return + MAPIRestrictionStateAlwaysTrue for PR_SENSITIVITY since privacy + filtering is performed internally. + + * OpenChange/MAPIStoreGCSMessageTable.m (-componentQualifier): + removed useless accessor, left over by a previous commit. + + * OpenChange/MAPIStoreGCSFolder.m (-aclQualifier): new accessor + providing an additional qualifier when listing elements of a + table, based on the current user rights. + (-messageKeysMatchingQualifier:andSortOrderings:): make use of the + new -aclQualifier method when the active user is not the owner of + the sogo object. Slightly simplified code by storing all + qualifiers in an array passed as parameter to the EOAndQualifier + constructor. + + * OpenChange/MAPIStoreMessage.m (-subscriberCanReadMessage) + (-subscriberCanModifyMessage): new getters for ACL operations at + the message level. + + * OpenChange/MAPIStoreFolder.m (-subscriberCanCreateMessages) + (-subscriberCanModifyMessages, -subscriberCanReadMessages) + (-subscriberCanDeleteMessages, -subscriberCanCreateSubFolders): + new getters for ACL operations at the folder level. + 2011-11-30 Wolfgang Sourdeau * SoObjects/SOGo/SOGoFolder.m diff --git a/OpenChange/GNUmakefile b/OpenChange/GNUmakefile index 4a0171582..3af4c776e 100644 --- a/OpenChange/GNUmakefile +++ b/OpenChange/GNUmakefile @@ -161,7 +161,6 @@ TEST_TOOL_NAME += $(PLREADER_TOOL) ### cflags and libs LIBMAPI_CFLAGS = $(shell pkg-config libmapi --cflags) -LIBMAPISTORE_CFLAGS = $(shell pkg-config libmapistore --cflags) -DSAMBA_PREFIX="\"$(shell pkg-config libmapistore --variable=prefix)\"" ifeq ($(LIBMAPI_CFLAGS),) all install:: @@ -169,6 +168,8 @@ all install:: else LIBMAPI_LIBS = $(shell pkg-config libmapi --libs) + +LIBMAPISTORE_CFLAGS = $(shell pkg-config libmapistore --cflags) -DSAMBA_PREFIX="\"$(shell pkg-config libmapistore --variable=prefix)\"" LIBMAPISTORE_LIBS = $(shell pkg-config libmapistore --libs) -lmapiproxy ADDITIONAL_INCLUDE_DIRS += \ @@ -178,14 +179,17 @@ ADDITIONAL_INCLUDE_DIRS += \ -I../SoObjects -I../SOPE \ -DBACKEND_BUNDLE_NAME="@\"$(BUNDLE_NAME)$(BUNDLE_EXTENSION)\"" \ -DSOGO_BUNDLES_DIR="@\"$(BUNDLE_INSTALL_DIR)\"" -ADDITIONAL_LIB_DIRS += -Wl,--no-as-needed \ - -L../SoObjects/SOGo/SOGo.framework/ -lSOGo \ - -L../OGoContentStore/$(GNUSTEP_OBJ_DIR)/ -lOGoContentStore \ - $(LIBMAPI_LIBS) \ - $(LIBMAPISTORE_LIBS) + +ADDITIONAL_LIB_DIRS += -Wl,--no-as-needed SAMBA_LIB_DIR = $(shell pkg-config libmapistore --variable=libdir) +$(SOGOBACKEND)_LDFLAGS += \ + $(LIBMAPI_LIBS) \ + $(LIBMAPISTORE_LIBS) \ + -L../SoObjects/SOGo/SOGo.framework/ -lSOGo \ + -L../OGoContentStore/$(GNUSTEP_OBJ_DIR)/ -lOGoContentStore + -include GNUmakefile.preamble include $(GNUSTEP_MAKEFILES)/bundle.make include $(GNUSTEP_MAKEFILES)/library.make diff --git a/OpenChange/MAPIStoreCalendarFolder.m b/OpenChange/MAPIStoreCalendarFolder.m index 34c5dea6b..8ed3f19ed 100644 --- a/OpenChange/MAPIStoreCalendarFolder.m +++ b/OpenChange/MAPIStoreCalendarFolder.m @@ -157,4 +157,43 @@ return rights; } +- (BOOL) subscriberCanReadMessages +{ + static NSArray *viewerRoles = nil; + + if (!viewerRoles) + viewerRoles = [[NSArray alloc] initWithObjects: + SOGoCalendarRole_PublicViewer, + SOGoCalendarRole_PublicDAndTViewer, + SOGoCalendarRole_PrivateViewer, + SOGoCalendarRole_PrivateDAndTViewer, + SOGoCalendarRole_ConfidentialViewer, + SOGoCalendarRole_ConfidentialDAndTViewer, + nil]; + + return ([[self activeUserRoles] firstObjectCommonWithArray: viewerRoles] + != nil); +} + +- (BOOL) subscriberCanModifyMessages +{ + static NSArray *modifierRoles = nil; + + if (!modifierRoles) + modifierRoles = [[NSArray alloc] initWithObjects: + SOGoCalendarRole_PublicModifier, + SOGoCalendarRole_PrivateModifier, + SOGoCalendarRole_ConfidentialModifier, + nil]; + + return ([[self activeUserRoles] firstObjectCommonWithArray: modifierRoles] + != nil); +} + +- (EOQualifier *) aclQualifier +{ + return [EOQualifier qualifierWithQualifierFormat: + [(SOGoAppointmentFolder *) sogoObject aclSQLListingFilter]]; +} + @end diff --git a/OpenChange/MAPIStoreCalendarMessage.m b/OpenChange/MAPIStoreCalendarMessage.m index 73729cc66..263e60d30 100644 --- a/OpenChange/MAPIStoreCalendarMessage.m +++ b/OpenChange/MAPIStoreCalendarMessage.m @@ -42,6 +42,7 @@ #import #import #import +#import #import #import #import @@ -108,11 +109,11 @@ if (!appointmentWrapper) { - event = [sogoObject component: NO secure: NO]; + event = [sogoObject component: NO secure: YES]; context = [self context]; ASSIGN (appointmentWrapper, [MAPIStoreAppointmentWrapper wrapperWithICalEvent: event - andUser: [context activeUser] + andUser: [context ownerUser] andSenderEmail: nil inTimeZone: [self ownerTimeZone] withConnectionInfo: [context connectionInfo]]); @@ -620,6 +621,27 @@ } } +- (BOOL) subscriberCanReadMessage +{ + return ([[self activeUserRoles] + containsObject: SOGoCalendarRole_ComponentViewer] + || [self subscriberCanModifyMessage]); +} + +- (BOOL) subscriberCanModifyMessage +{ + BOOL rc; + NSArray *roles = [self activeUserRoles]; + + if (isNew) + rc = [roles containsObject: SOGoRole_ObjectCreator]; + else + rc = ([roles containsObject: SOGoCalendarRole_ComponentModifier] + || [roles containsObject: SOGoCalendarRole_ComponentResponder]); + + return rc; +} + - (void) save { iCalCalendar *vCalendar; @@ -631,7 +653,7 @@ iCalEvent *newEvent; iCalPerson *userPerson; NSUInteger responseStatus = 0; - SOGoUser *activeUser; + SOGoUser *activeUser, *ownerUser; id value; if (isNew) @@ -662,8 +684,8 @@ vCalendar = [iCalCalendar parseSingleFromSource: content]; newEvent = [[vCalendar events] objectAtIndex: 0]; - activeUser = [[self context] activeUser]; - userPerson = [newEvent userAsAttendee: activeUser]; + ownerUser = [[self context] ownerUser]; + userPerson = [newEvent userAsAttendee: ownerUser]; [newEvent setTimeStampAsDate: now]; if (userPerson) @@ -701,7 +723,7 @@ { // iCalPerson *participant; - // participant = [newEvent userAsAttendee: activeUser]; + // participant = [newEvent userAsAttendee: ownerUser]; // [participant setParticipationStatus: newPartStat]; // [sogoObject saveComponent: newEvent]; @@ -849,7 +871,7 @@ { NSArray *recipients; NSDictionary *dict; - NSString *orgEmail, *attEmail; + NSString *orgEmail, *sentBy, *attEmail; iCalPerson *person; iCalPersonPartStat newPartStat; NSNumber *flags, *trackStatus; @@ -858,11 +880,20 @@ /* We must set the organizer preliminarily here because, unlike what the doc states, Outlook does not always pass the real organizer in the recipients list. */ - dict = [activeUser primaryIdentity]; + dict = [ownerUser primaryIdentity]; person = [iCalPerson new]; [person setCn: [dict objectForKey: @"fullName"]]; orgEmail = [dict objectForKey: @"email"]; [person setEmail: orgEmail]; + + activeUser = [[self context] activeUser]; + if (![activeUser isEqual: ownerUser]) + { + dict = [activeUser primaryIdentity]; + sentBy = [NSString stringWithFormat: @"mailto:%@", + [dict objectForKey: @"email"]]; + [person setSentBy: sentBy]; + } [newEvent setOrganizer: person]; [person release]; diff --git a/OpenChange/MAPIStoreContactsFolder.m b/OpenChange/MAPIStoreContactsFolder.m index 0b7354d9e..ba3d36c6d 100644 --- a/OpenChange/MAPIStoreContactsFolder.m +++ b/OpenChange/MAPIStoreContactsFolder.m @@ -142,4 +142,14 @@ return rights; } +- (BOOL) subscriberCanModifyMessages +{ + return [[self activeUserRoles] containsObject: SOGoRole_ObjectEditor]; +} + +- (BOOL) subscriberCanReadMessages +{ + return [[self activeUserRoles] containsObject: SOGoRole_ObjectViewer]; +} + @end diff --git a/OpenChange/MAPIStoreContactsMessage.m b/OpenChange/MAPIStoreContactsMessage.m index 5ef07ff99..3ef9e4c66 100644 --- a/OpenChange/MAPIStoreContactsMessage.m +++ b/OpenChange/MAPIStoreContactsMessage.m @@ -33,6 +33,7 @@ #import #import #import +#import #import "MAPIStoreContactsAttachment.h" #import "MAPIStoreContactsFolder.h" @@ -847,6 +848,22 @@ } } +- (BOOL) subscriberCanReadMessage +{ + return [[self activeUserRoles] containsObject: SOGoRole_ObjectViewer]; +} + +- (BOOL) subscriberCanModifyMessage +{ + NSArray *roles; + + roles = [self activeUserRoles]; + + return ((isNew + && [roles containsObject: SOGoRole_ObjectCreator]) + || (!isNew && [roles containsObject: SOGoRole_ObjectEditor])); +} + // // // diff --git a/OpenChange/MAPIStoreContext.m b/OpenChange/MAPIStoreContext.m index 3236a4603..07ac7116a 100644 --- a/OpenChange/MAPIStoreContext.m +++ b/OpenChange/MAPIStoreContext.m @@ -101,30 +101,44 @@ static NSMutableDictionary *contextClassMapping; } } -static inline MAPIStoreContext * +static inline enum mapistore_error _prepareContextClass (Class contextClass, struct mapistore_connection_info *connInfo, - struct tdb_wrap *indexingTdb, NSURL *url) + struct tdb_wrap *indexingTdb, NSURL *url, + MAPIStoreContext **contextP) { MAPIStoreContext *context; MAPIStoreAuthenticator *authenticator; + enum mapistore_error rc; context = [[contextClass alloc] initFromURL: url withConnectionInfo: connInfo andTDBIndexing: indexingTdb]; - [context autorelease]; + if (context) + { + [context autorelease]; - authenticator = [MAPIStoreAuthenticator new]; - [authenticator setUsername: [url user]]; - [authenticator setPassword: [url password]]; - [context setAuthenticator: authenticator]; - [authenticator release]; + authenticator = [MAPIStoreAuthenticator new]; + [authenticator setUsername: [url user]]; + [authenticator setPassword: [url password]]; + [context setAuthenticator: authenticator]; + [authenticator release]; - [context setupRequest]; - [context setupBaseFolder: url]; - [context tearDownRequest]; + [context setupRequest]; + [context setupBaseFolder: url]; + [context tearDownRequest]; + if (context->baseFolder && [context->baseFolder sogoObject]) + { + *contextP = context; + rc = MAPISTORE_SUCCESS; + } + else + rc = MAPISTORE_ERR_DENIED; + } + else + rc = MAPISTORE_ERROR; - return context; + return rc; } + (int) openContext: (MAPIStoreContext **) contextPtr @@ -157,16 +171,15 @@ _prepareContextClass (Class contextClass, contextClass = [contextClassMapping objectForKey: module]; if (contextClass) { - context = _prepareContextClass (contextClass, - newConnInfo, indexingTdb, - baseURL); - if (context) + rc = _prepareContextClass (contextClass, + newConnInfo, indexingTdb, + baseURL, &context); + if (rc == MAPISTORE_SUCCESS) { *contextPtr = context; mapistore_mgmt_backend_register_user (newConnInfo, "SOGo", [[[context authenticator] username] UTF8String]); - rc = MAPISTORE_SUCCESS; } } else diff --git a/OpenChange/MAPIStoreFAIMessage.m b/OpenChange/MAPIStoreFAIMessage.m index 8ae940af0..e0d5faeee 100644 --- a/OpenChange/MAPIStoreFAIMessage.m +++ b/OpenChange/MAPIStoreFAIMessage.m @@ -21,6 +21,7 @@ */ #import "MAPIStoreActiveTables.h" +#import "MAPIStoreContext.h" #import "NSObject+MAPIStore.h" #import "MAPIStoreFAIMessage.h" @@ -29,6 +30,7 @@ #include #include #include +#include @implementation MAPIStoreFAIMessage @@ -45,4 +47,28 @@ return [self getYes: data inMemCtx: memCtx]; } +- (enum mapistore_error) saveMessage +{ + enum mapistore_error rc; + MAPIStoreContext *context; + + context = [self context]; + if ([[context activeUser] isEqual: [context ownerUser]]) + rc = [super saveMessage]; + else + rc = MAPISTORE_ERR_DENIED; + + return rc; +} + +- (BOOL) subscriberCanReadMessage +{ + return NO; +} + +- (BOOL) subscriberCanModifyMessage +{ + return NO; +} + @end diff --git a/OpenChange/MAPIStoreFSFolder.m b/OpenChange/MAPIStoreFSFolder.m index acacc7b49..bb6cf3d7b 100644 --- a/OpenChange/MAPIStoreFSFolder.m +++ b/OpenChange/MAPIStoreFSFolder.m @@ -27,7 +27,9 @@ #import #import #import +#import #import "EOQualifier+MAPI.h" +#import "MAPIStoreContext.h" #import "MAPIStoreFSFolderTable.h" #import "MAPIStoreFSMessage.h" #import "MAPIStoreFSMessageTable.h" @@ -45,6 +47,16 @@ static Class EOKeyValueQualifierK; +static NSString *MAPIStoreRightReadItems = @"RightsReadItems"; +static NSString *MAPIStoreRightCreateItems = @"RightsCreateItems"; +static NSString *MAPIStoreRightEditOwn = @"RightsEditOwn"; +static NSString *MAPIStoreRightEditAll = @"RightsEditAll"; +static NSString *MAPIStoreRightDeleteOwn = @"RightsDeleteOwn"; +static NSString *MAPIStoreRightDeleteAll = @"RightsDeleteAll"; +static NSString *MAPIStoreRightCreateSubfolders = @"RightsCreateSubfolders"; +static NSString *MAPIStoreRightFolderOwner = @"RightsFolderOwner"; +static NSString *MAPIStoreRightFolderContact = @"RightsFolderContact"; + @implementation MAPIStoreFSFolder + (void) initialize @@ -102,20 +114,28 @@ static Class EOKeyValueQualifierK; newKey = [NSString stringWithFormat: @"%@.plist", [SOGoObject globallyUniqueObjectId]]; - fsObject = [SOGoMAPIFSMessage objectWithName: newKey inContainer: sogoObject]; + fsObject = [SOGoMAPIFSMessage objectWithName: newKey + inContainer: sogoObject]; newMessage = [MAPIStoreFSMessage mapiStoreObjectWithSOGoObject: fsObject inContainer: self]; - return newMessage; } - (NSArray *) messageKeysMatchingQualifier: (EOQualifier *) qualifier andSortOrderings: (NSArray *) sortOrderings { - return [(SOGoMAPIFSFolder *) sogoObject - toOneRelationshipKeysMatchingQualifier: qualifier - andSortOrderings: sortOrderings]; + NSArray *keys; + + if ([[context activeUser] isEqual: [context ownerUser]] + || [self subscriberCanReadMessages]) + keys = [(SOGoMAPIFSFolder *) sogoObject + toOneRelationshipKeysMatchingQualifier: qualifier + andSortOrderings: sortOrderings]; + else + keys = [NSArray array]; + + return keys; } - (NSArray *) folderKeysMatchingQualifier: (EOQualifier *) qualifier @@ -187,23 +207,23 @@ static Class EOKeyValueQualifierK; roles = [NSMutableArray arrayWithCapacity: 9]; if (rights & RightsReadItems) - [roles addObject: @"RightsReadItems"]; + [roles addObject: MAPIStoreRightReadItems]; if (rights & RightsCreateItems) - [roles addObject: @"RightsCreateItems"]; + [roles addObject: MAPIStoreRightCreateItems]; if (rights & RightsEditOwn) - [roles addObject: @"RightsEditOwn"]; + [roles addObject: MAPIStoreRightEditOwn]; if (rights & RightsDeleteOwn) - [roles addObject: @"RightsDeleteOwn"]; + [roles addObject: MAPIStoreRightDeleteOwn]; if (rights & RightsEditAll) - [roles addObject: @"RightsEditAll"]; + [roles addObject: MAPIStoreRightEditAll]; if (rights & RightsDeleteAll) - [roles addObject: @"RightsDeleteAll"]; + [roles addObject: MAPIStoreRightDeleteAll]; if (rights & RightsCreateSubfolders) - [roles addObject: @"RightsCreateSubfolders"]; + [roles addObject: MAPIStoreRightCreateSubfolders]; if (rights & RightsFolderOwner) - [roles addObject: @"RightsFolderOwner"]; + [roles addObject: MAPIStoreRightFolderOwner]; if (rights & RightsFolderContact) - [roles addObject: @"RightsFolderContact"]; + [roles addObject: MAPIStoreRightFolderContact]; return roles; } @@ -212,23 +232,23 @@ static Class EOKeyValueQualifierK; { uint32_t rights = 0; - if ([roles containsObject: @"RightsReadItems"]) + if ([roles containsObject: MAPIStoreRightReadItems]) rights |= RightsReadItems; - if ([roles containsObject: @"RightsCreateItems"]) + if ([roles containsObject: MAPIStoreRightCreateItems]) rights |= RightsCreateItems; - if ([roles containsObject: @"RightsEditOwn"]) + if ([roles containsObject: MAPIStoreRightEditOwn]) rights |= RightsEditOwn; - if ([roles containsObject: @"RightsDeleteOwn"]) + if ([roles containsObject: MAPIStoreRightDeleteOwn]) rights |= RightsDeleteOwn; - if ([roles containsObject: @"RightsEditAll"]) + if ([roles containsObject: MAPIStoreRightEditAll]) rights |= RightsEditAll; - if ([roles containsObject: @"RightsDeleteAll"]) + if ([roles containsObject: MAPIStoreRightDeleteAll]) rights |= RightsDeleteAll; - if ([roles containsObject: @"RightsCreateSubfolders"]) + if ([roles containsObject: MAPIStoreRightCreateSubfolders]) rights |= RightsCreateSubfolders; - if ([roles containsObject: @"RightsFolderOwner"]) + if ([roles containsObject: MAPIStoreRightFolderOwner]) rights |= RightsFolderOwner; - if ([roles containsObject: @"RightsFolderContact"]) + if ([roles containsObject: MAPIStoreRightFolderContact]) rights |= RightsFolderContact; if (rights != 0) rights |= RoleNone; /* actually "folder visible" */ @@ -236,4 +256,43 @@ static Class EOKeyValueQualifierK; return rights; } +- (BOOL) _testRoleForActiveUser: (const NSString *) role +{ + SOGoUser *activeUser; + NSArray *roles; + + activeUser = [[self context] activeUser]; + + roles = [[self aclFolder] aclsForUser: [activeUser login]]; + + return [roles containsObject: role]; +} + +- (BOOL) subscriberCanCreateMessages +{ + return [self _testRoleForActiveUser: MAPIStoreRightCreateItems]; +} + +- (BOOL) subscriberCanModifyMessages +{ + return ([self _testRoleForActiveUser: MAPIStoreRightEditAll] + || [self _testRoleForActiveUser: MAPIStoreRightEditOwn]); +} + +- (BOOL) subscriberCanReadMessages +{ + return [self _testRoleForActiveUser: MAPIStoreRightReadItems]; +} + +- (BOOL) subscriberCanDeleteMessages +{ + return ([self _testRoleForActiveUser: MAPIStoreRightDeleteAll] + || [self _testRoleForActiveUser: MAPIStoreRightDeleteOwn]); +} + +- (BOOL) subscriberCanCreateSubFolders +{ + return [self _testRoleForActiveUser: MAPIStoreRightCreateSubfolders]; +} + @end diff --git a/OpenChange/MAPIStoreFSMessage.m b/OpenChange/MAPIStoreFSMessage.m index 6104cc72a..8af3edca2 100644 --- a/OpenChange/MAPIStoreFSMessage.m +++ b/OpenChange/MAPIStoreFSMessage.m @@ -28,6 +28,7 @@ #import "MAPIStorePropertySelectors.h" #import "SOGoMAPIFSMessage.h" +#import "MAPIStoreFSFolder.h" #import "MAPIStoreFSMessage.h" #import "MAPIStoreTypes.h" #import "NSData+MAPIStore.h" @@ -83,6 +84,34 @@ [properties removeAllObjects]; } +- (BOOL) _messageIsFreeBusy +{ + NSString *msgClass; + + /* This is a HACK until we figure out how to determine a message position in + the mailbox hierarchy.... (missing: folderid and role) */ + msgClass = [[sogoObject properties] + objectForKey: MAPIPropertyKey (PR_MESSAGE_CLASS_UNICODE)]; + + return [msgClass isEqualToString: @"IPM.Microsoft.ScheduleData.FreeBusy"]; +} + +/* TODO: differentiate between the "Own" and "All" cases */ +- (BOOL) subscriberCanReadMessage +{ + return ([(MAPIStoreFolder *) container subscriberCanReadMessages] + || [self _messageIsFreeBusy]); +} + +- (BOOL) subscriberCanModifyMessage +{ + return ((isNew + && [(MAPIStoreFolder *) container subscriberCanCreateMessages]) + || (!isNew + && [(MAPIStoreFolder *) container subscriberCanModifyMessages]) + || [self _messageIsFreeBusy]); +} + - (NSDate *) creationTime { return [sogoObject creationTime]; diff --git a/OpenChange/MAPIStoreFolder.h b/OpenChange/MAPIStoreFolder.h index 085795de2..c124cdce7 100644 --- a/OpenChange/MAPIStoreFolder.h +++ b/OpenChange/MAPIStoreFolder.h @@ -111,9 +111,9 @@ withMID: (uint64_t) mid isAssociated: (BOOL) isAssociated; - - (int) openMessage: (MAPIStoreMessage **) messagePtr withMID: (uint64_t) mid + forWriting: (BOOL) readWrite inMemCtx: (TALLOC_CTX *) memCtx; - (int) deleteMessageWithMID: (uint64_t) mid andFlags: (uint8_t) flags; @@ -161,6 +161,12 @@ - (NSArray *) rolesForExchangeRights: (uint32_t) rights; - (uint32_t) exchangeRightsForRoles: (NSArray *) roles; +- (BOOL) subscriberCanCreateMessages; +- (BOOL) subscriberCanModifyMessages; +- (BOOL) subscriberCanReadMessages; +- (BOOL) subscriberCanDeleteMessages; +- (BOOL) subscriberCanCreateSubFolders; + /* subclass helpers */ - (void) postNotificationsForMoveCopyMessagesWithMIDs: (uint64_t *) srcMids andMessageURLs: (NSArray *) oldMessageURLs diff --git a/OpenChange/MAPIStoreFolder.m b/OpenChange/MAPIStoreFolder.m index 43c56dd46..fa13b9da7 100644 --- a/OpenChange/MAPIStoreFolder.m +++ b/OpenChange/MAPIStoreFolder.m @@ -336,35 +336,41 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe [self logWithFormat: @"METHOD '%s' (%d)", __FUNCTION__, __LINE__]; - mapping = [[self context] mapping]; - childURL = [mapping urlFromID: fid]; - if (childURL) - rc = MAPISTORE_ERR_EXIST; - else + if ([[context activeUser] isEqual: [context ownerUser]] + || [self subscriberCanCreateSubFolders]) { - folderKey = [self createFolder: aRow withFID: fid]; - if (folderKey) + mapping = [[self context] mapping]; + childURL = [mapping urlFromID: fid]; + if (childURL) + rc = MAPISTORE_ERR_EXIST; + else { - [self cleanupCaches]; - baseURL = [self url]; - if (![baseURL hasSuffix: @"/"]) - baseURL = [NSString stringWithFormat: @"%@/", baseURL]; - childURL = [NSString stringWithFormat: @"%@%@", - baseURL, folderKey]; - [mapping registerURL: childURL withID: fid]; - childFolder = [self lookupFolder: folderKey]; - if (childFolder) + folderKey = [self createFolder: aRow withFID: fid]; + if (folderKey) { - [childFolder addPropertiesFromRow: aRow]; - *childFolderPtr = childFolder; + [self cleanupCaches]; + baseURL = [self url]; + if (![baseURL hasSuffix: @"/"]) + baseURL = [NSString stringWithFormat: @"%@/", baseURL]; + childURL = [NSString stringWithFormat: @"%@%@", + baseURL, folderKey]; + [mapping registerURL: childURL withID: fid]; + childFolder = [self lookupFolder: folderKey]; + if (childFolder) + { + [childFolder addPropertiesFromRow: aRow]; + *childFolderPtr = childFolder; + } + else + [NSException raise: @"MAPIStoreIOException" + format: @"unable to fetch created folder"]; } else - [NSException raise: @"MAPIStoreIOException" - format: @"unable to fetch created folder"]; + rc = MAPISTORE_ERROR; } - else - rc = MAPISTORE_ERROR; } + else + rc = MAPISTORE_ERR_DENIED; return rc; } @@ -403,6 +409,7 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe - (int) openMessage: (MAPIStoreMessage **) messagePtr withMID: (uint64_t) mid + forWriting: (BOOL) readWrite inMemCtx: (TALLOC_CTX *) memCtx; { NSString *messageURL; @@ -417,8 +424,15 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe message = [self lookupMessageByURL: messageURL]; if (message) { - *messagePtr = message; - rc = MAPISTORE_SUCCESS; + if ([[context activeUser] isEqual: [context ownerUser]] + || (readWrite && [message subscriberCanModifyMessage]) + || (!readWrite && [message subscriberCanReadMessage])) + { + *messagePtr = message; + rc = MAPISTORE_SUCCESS; + } + else + rc = MAPISTORE_ERR_DENIED; } } @@ -429,7 +443,7 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe withMID: (uint64_t) mid isAssociated: (BOOL) isAssociated { - int rc; + enum mapistore_error rc; MAPIStoreMessage *message; NSString *baseURL, *childURL; MAPIStoreMapping *mapping; @@ -437,26 +451,33 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe [self logWithFormat: @"METHOD '%s' -- mid: 0x%.16llx associated: %d", __FUNCTION__, mid, isAssociated]; - mapping = [[self context] mapping]; - if ([mapping urlFromID: mid]) - rc = MAPISTORE_ERR_EXIST; - else + context = [self context]; + if ([[context activeUser] isEqual: [context ownerUser]] + || (!isAssociated && [self subscriberCanCreateMessages])) { - message = [self createMessage: isAssociated]; - if (message) - { - baseURL = [self url]; - if (![baseURL hasSuffix: @"/"]) - baseURL = [NSString stringWithFormat: @"%@/", baseURL]; - childURL = [NSString stringWithFormat: @"%@%@", - baseURL, [message nameInContainer]]; - [mapping registerURL: childURL withID: mid]; - *messagePtr = message; - rc = MAPISTORE_SUCCESS; - } + mapping = [[self context] mapping]; + if ([mapping urlFromID: mid]) + rc = MAPISTORE_ERR_EXIST; else - rc = MAPISTORE_ERROR; + { + message = [self createMessage: isAssociated]; + if (message) + { + baseURL = [self url]; + if (![baseURL hasSuffix: @"/"]) + baseURL = [NSString stringWithFormat: @"%@/", baseURL]; + childURL = [NSString stringWithFormat: @"%@%@", + baseURL, [message nameInContainer]]; + [mapping registerURL: childURL withID: mid]; + *messagePtr = message; + rc = MAPISTORE_SUCCESS; + } + else + rc = MAPISTORE_ERROR; + } } + else + rc = MAPISTORE_ERR_DENIED; return rc; } @@ -483,73 +504,80 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe message = [self lookupMessageByURL: childURL]; if (message) { - /* we ensure the table caches are loaded so that old and new state - can be compared */ - activeTables = ([message isKindOfClass: MAPIStoreFAIMessageK] - ? [self activeFAIMessageTables] - : [self activeMessageTables]); - max = [activeTables count]; - for (count = 0; count < max; count++) - [[activeTables objectAtIndex: count] restrictedChildKeys]; - - msgObject = [message sogoObject]; - if (([msgObject respondsToSelector: @selector (prepareDelete)] - && [msgObject prepareDelete]) - || [msgObject delete]) + if ([[context activeUser] isEqual: [context ownerUser]] + || (![message isKindOfClass: MAPIStoreFAIMessageK] + && [self subscriberCanDeleteMessages])) { - rc = MAPISTORE_ERROR; - [self logWithFormat: @"ERROR deleting object at URL: %@", childURL]; + /* we ensure the table caches are loaded so that old and new state + can be compared */ + activeTables = ([message isKindOfClass: MAPIStoreFAIMessageK] + ? [self activeFAIMessageTables] + : [self activeMessageTables]); + max = [activeTables count]; + for (count = 0; count < max; count++) + [[activeTables objectAtIndex: count] restrictedChildKeys]; + + msgObject = [message sogoObject]; + if (([msgObject respondsToSelector: @selector (prepareDelete)] + && [msgObject prepareDelete]) + || [msgObject delete]) + { + rc = MAPISTORE_ERROR; + [self logWithFormat: @"ERROR deleting object at URL: %@", childURL]; + } + else + { + if (![message isNew]) + { + /* folder notification */ + notif_parameters + = talloc_zero(NULL, + struct mapistore_object_notification_parameters); + notif_parameters->object_id = [self objectId]; + notif_parameters->tag_count = 5; + notif_parameters->tags = talloc_array (notif_parameters, + enum MAPITAGS, 5); + notif_parameters->tags[0] = PR_CONTENT_COUNT; + notif_parameters->tags[1] = PR_DELETED_COUNT_TOTAL; + notif_parameters->tags[2] = PR_MESSAGE_SIZE; + notif_parameters->tags[3] = PR_NORMAL_MESSAGE_SIZE; + notif_parameters->tags[4] = PR_DELETED_MSG_COUNT; + notif_parameters->new_message_count = true; + notif_parameters->message_count = [[self messageKeys] + count] - 1; + connInfo = [[self context] connectionInfo]; + mapistore_push_notification (connInfo->mstore_ctx, + MAPISTORE_FOLDER, + MAPISTORE_OBJECT_MODIFIED, + notif_parameters); + talloc_free(notif_parameters); + + /* message notification */ + notif_parameters + = talloc_zero(NULL, + struct mapistore_object_notification_parameters); + notif_parameters->object_id = mid; + notif_parameters->folder_id = [self objectId]; + /* Exchange sends a fnevObjectCreated!! */ + mapistore_push_notification (connInfo->mstore_ctx, + MAPISTORE_MESSAGE, + MAPISTORE_OBJECT_CREATED, + notif_parameters); + talloc_free(notif_parameters); + + /* table notification */ + for (count = 0; count < max; count++) + [[activeTables objectAtIndex: count] + notifyChangesForChild: message]; + } + [self logWithFormat: @"successfully deleted object at URL: %@", childURL]; + [mapping unregisterURLWithID: mid]; + [self cleanupCaches]; + rc = MAPISTORE_SUCCESS; + } } else - { - if (![message isNew]) - { - /* folder notification */ - notif_parameters - = talloc_zero(NULL, - struct mapistore_object_notification_parameters); - notif_parameters->object_id = [self objectId]; - notif_parameters->tag_count = 5; - notif_parameters->tags = talloc_array (notif_parameters, - enum MAPITAGS, 5); - notif_parameters->tags[0] = PR_CONTENT_COUNT; - notif_parameters->tags[1] = PR_DELETED_COUNT_TOTAL; - notif_parameters->tags[2] = PR_MESSAGE_SIZE; - notif_parameters->tags[3] = PR_NORMAL_MESSAGE_SIZE; - notif_parameters->tags[4] = PR_DELETED_MSG_COUNT; - notif_parameters->new_message_count = true; - notif_parameters->message_count = [[self messageKeys] - count] - 1; - connInfo = [[self context] connectionInfo]; - mapistore_push_notification (connInfo->mstore_ctx, - MAPISTORE_FOLDER, - MAPISTORE_OBJECT_MODIFIED, - notif_parameters); - talloc_free(notif_parameters); - - /* message notification */ - notif_parameters - = talloc_zero(NULL, - struct mapistore_object_notification_parameters); - notif_parameters->object_id = mid; - notif_parameters->folder_id = [self objectId]; - /* Exchange sends a fnevObjectCreated!! */ - mapistore_push_notification (connInfo->mstore_ctx, - MAPISTORE_MESSAGE, - MAPISTORE_OBJECT_CREATED, - notif_parameters); - talloc_free(notif_parameters); - - /* table notification */ - for (count = 0; count < max; count++) - [[activeTables objectAtIndex: count] - notifyChangesForChild: message]; - } - [self logWithFormat: @"successfully deleted object at URL: %@", childURL]; - [mapping unregisterURLWithID: mid]; - [self cleanupCaches]; - rc = MAPISTORE_SUCCESS; - } + rc = MAPISTORE_ERR_DENIED; } else rc = MAPISTORE_ERR_NOT_FOUND; @@ -580,6 +608,7 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe memCtx = talloc_zero (NULL, TALLOC_CTX); rc = [sourceFolder openMessage: &sourceMsg withMID: srcMid + forWriting: NO inMemCtx: memCtx]; if (rc != MAPISTORE_SUCCESS) goto end; @@ -658,46 +687,51 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe MAPIStoreMapping *mapping; struct Binary_r *targetChangeKey; - if ([sourceFolder isKindOfClass: isa] - || [self isKindOfClass: [sourceFolder class]]) - [self logWithFormat: @"%s: this class could probably implement" - @" a specialized/optimized version", __FUNCTION__]; - oldMessageURLs = [NSMutableArray arrayWithCapacity: midCount]; - mapping = [[self context] mapping]; - for (count = 0; rc == MAPISTORE_SUCCESS && count < midCount; count++) + if (wantCopy || [[context activeUser] isEqual: [context ownerUser]]) { - oldMessageURL = [mapping urlFromID: srcMids[count]]; - if (oldMessageURL) + if ([sourceFolder isKindOfClass: isa] + || [self isKindOfClass: [sourceFolder class]]) + [self logWithFormat: @"%s: this class could probably implement" + @" a specialized/optimized version", __FUNCTION__]; + oldMessageURLs = [NSMutableArray arrayWithCapacity: midCount]; + mapping = [[self context] mapping]; + for (count = 0; rc == MAPISTORE_SUCCESS && count < midCount; count++) { - [oldMessageURLs addObject: oldMessageURL]; - if (targetChangeKeys) - targetChangeKey = targetChangeKeys[count]; + oldMessageURL = [mapping urlFromID: srcMids[count]]; + if (oldMessageURL) + { + [oldMessageURLs addObject: oldMessageURL]; + if (targetChangeKeys) + targetChangeKey = targetChangeKeys[count]; + else + targetChangeKey = NULL; + rc = [self moveCopyMessageWithMID: srcMids[count] + fromFolder: sourceFolder + withMID: targetMids[count] + andChangeKey: targetChangeKey + wantCopy: wantCopy]; + } else - targetChangeKey = NULL; - rc = [self moveCopyMessageWithMID: srcMids[count] - fromFolder: sourceFolder - withMID: targetMids[count] - andChangeKey: targetChangeKey - wantCopy: wantCopy]; + rc = MAPISTORE_ERR_NOT_FOUND; } - else - rc = MAPISTORE_ERR_NOT_FOUND; - } - /* Notifications */ - if (rc == MAPISTORE_SUCCESS) - { - [self postNotificationsForMoveCopyMessagesWithMIDs: srcMids - andMessageURLs: oldMessageURLs - andCount: midCount - fromFolder: sourceFolder - withMIDs: targetMids - wantCopy: wantCopy]; + /* Notifications */ + if (rc == MAPISTORE_SUCCESS) + { + [self postNotificationsForMoveCopyMessagesWithMIDs: srcMids + andMessageURLs: oldMessageURLs + andCount: midCount + fromFolder: sourceFolder + withMIDs: targetMids + wantCopy: wantCopy]; - // We cleanup cache of our source and destination folders - [self cleanupCaches]; - [sourceFolder cleanupCaches]; + // We cleanup cache of our source and destination folders + [self cleanupCaches]; + [sourceFolder cleanupCaches]; + } } + else + rc = MAPISTORE_ERR_DENIED; return rc; } @@ -1097,7 +1131,24 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe - (int) getPrAccess: (void **) data inMemCtx: (TALLOC_CTX *) memCtx { - *data = MAPILongValue (memCtx, 0x1|0x2|0x4|0x8|0x10|0x20); + uint32_t access = 0; + BOOL userIsOwner; + + userIsOwner = [[context activeUser] isEqual: [context ownerUser]]; + if (userIsOwner || [self subscriberCanModifyMessages]) + access |= 0x01; + if (userIsOwner || [self subscriberCanReadMessages]) + access |= 0x02; + if (userIsOwner || [self subscriberCanDeleteMessages]) + access |= 0x04; + if (userIsOwner || [self subscriberCanCreateSubFolders]) + access |= 0x08; + if (userIsOwner || [self subscriberCanCreateMessages]) + access |= 0x10; + if (userIsOwner) + access |= 0x20; + + *data = MAPILongValue (memCtx, access); return MAPISTORE_SUCCESS; } @@ -1519,4 +1570,29 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe return nil; } +- (BOOL) subscriberCanCreateMessages +{ + return NO; +} + +- (BOOL) subscriberCanModifyMessages +{ + return NO; +} + +- (BOOL) subscriberCanReadMessages +{ + return NO; +} + +- (BOOL) subscriberCanDeleteMessages +{ + return NO; +} + +- (BOOL) subscriberCanCreateSubFolders +{ + return NO; +} + @end diff --git a/OpenChange/MAPIStoreGCSFolder.h b/OpenChange/MAPIStoreGCSFolder.h index 84ff6fcce..91ec334fd 100644 --- a/OpenChange/MAPIStoreGCSFolder.h +++ b/OpenChange/MAPIStoreGCSFolder.h @@ -25,6 +25,7 @@ #import "MAPIStoreFolder.h" +@class NSArray; @class NSCalendarDate; @class NSData; @class NSMutableDictionary; @@ -34,6 +35,7 @@ @interface MAPIStoreGCSFolder : MAPIStoreFolder { SOGoMAPIFSMessage *versionsMessage; + NSArray *activeUserRoles; } /* synchronisation */ @@ -46,7 +48,10 @@ - (void) setChangeKey: (NSData *) changeKey forMessageWithKey: (NSString *) messageKey; +- (NSArray *) activeUserRoles; + /* subclasses */ +- (EOQualifier *) aclQualifier; - (EOQualifier *) componentQualifier; @end diff --git a/OpenChange/MAPIStoreGCSFolder.m b/OpenChange/MAPIStoreGCSFolder.m index 6fe81e303..0a88a9a96 100644 --- a/OpenChange/MAPIStoreGCSFolder.m +++ b/OpenChange/MAPIStoreGCSFolder.m @@ -29,6 +29,8 @@ #import #import #import +#import +#import #import "MAPIStoreContext.h" #import "MAPIStoreTypes.h" @@ -53,6 +55,7 @@ ASSIGN (versionsMessage, [SOGoMAPIFSMessage objectWithName: @"versions.plist" inContainer: propsFolder]); + activeUserRoles = nil; } return self; @@ -66,6 +69,7 @@ ASSIGN (versionsMessage, [SOGoMAPIFSMessage objectWithName: @"versions.plist" inContainer: propsFolder]); + activeUserRoles = nil; } return self; @@ -74,6 +78,7 @@ - (void) dealloc { [versionsMessage release]; + [activeUserRoles release]; [super dealloc]; } @@ -82,7 +87,8 @@ { static NSArray *fields = nil; NSArray *records; - EOQualifier *componentQualifier, *fetchQualifier; + NSMutableArray *qualifierArray; + EOQualifier *fetchQualifier, *aclQualifier; GCSFolder *ocsFolder; EOFetchSpecification *fs; NSArray *keys; @@ -91,24 +97,27 @@ fields = [[NSArray alloc] initWithObjects: @"c_name", @"c_version", nil]; - componentQualifier = [self componentQualifier]; - if (qualifier) + qualifierArray = [NSMutableArray new]; + if (![[context activeUser] isEqual: [context ownerUser]]) { - fetchQualifier = [[EOAndQualifier alloc] - initWithQualifiers: - componentQualifier, - qualifier, - nil]; - [fetchQualifier autorelease]; + aclQualifier = [self aclQualifier]; + if (aclQualifier) + [qualifierArray addObject: aclQualifier]; } - else - fetchQualifier = componentQualifier; + [qualifierArray addObject: [self componentQualifier]]; + if (qualifier) + [qualifierArray addObject: qualifier]; + + fetchQualifier = [[EOAndQualifier alloc] + initWithQualifierArray: qualifierArray]; ocsFolder = [sogoObject ocsFolder]; fs = [EOFetchSpecification fetchSpecificationWithEntityName: [ocsFolder folderName] qualifier: fetchQualifier sortOrderings: sortOrderings]; + [fetchQualifier release]; + [qualifierArray release]; records = [ocsFolder fetchFields: fields fetchSpecification: fs]; keys = [records objectsForKey: @"c_name" notFoundMarker: nil]; @@ -516,8 +525,38 @@ return deletedKeys; } +- (NSArray *) activeUserRoles +{ + SOGoUser *activeUser; + + if (!activeUserRoles) + { + activeUser = [[self context] activeUser]; + activeUserRoles = [activeUser rolesForObject: sogoObject + inContext: [context woContext]]; + [activeUserRoles retain]; + } + + return activeUserRoles; +} + +- (BOOL) subscriberCanCreateMessages +{ + return [[self activeUserRoles] containsObject: SOGoRole_ObjectCreator]; +} + +- (BOOL) subscriberCanDeleteMessages +{ + return [[self activeUserRoles] containsObject: SOGoRole_ObjectEraser]; +} + /* subclasses */ +- (EOQualifier *) aclQualifier +{ + return nil; +} + - (EOQualifier *) componentQualifier { [self subclassResponsibility: _cmd]; diff --git a/OpenChange/MAPIStoreGCSMessage.m b/OpenChange/MAPIStoreGCSMessage.m index 695561da0..c5e945583 100644 --- a/OpenChange/MAPIStoreGCSMessage.m +++ b/OpenChange/MAPIStoreGCSMessage.m @@ -22,8 +22,10 @@ #import #import +#import #import #import +#import #import "MAPIStoreContext.h" #import "MAPIStoreGCSFolder.h" @@ -48,6 +50,69 @@ return [sogoObject lastModified]; } +- (int) getPrAccess: (void **) data // TODO + inMemCtx: (TALLOC_CTX *) memCtx +{ + MAPIStoreContext *context; + WOContext *woContext; + SoSecurityManager *sm; + uint32_t access; + + context = [self context]; + if ([[context activeUser] isEqual: [context ownerUser]]) + access = 0x03; + else + { + sm = [SoSecurityManager sharedSecurityManager]; + woContext = [context woContext]; + + access = 0; + if (![sm validatePermission: SoPerm_ChangeImagesAndFiles + onObject: sogoObject + inContext: woContext]) + access |= 1; + if (![sm validatePermission: SoPerm_AccessContentsInformation + onObject: sogoObject + inContext: woContext]) + access |= 2; + if (![sm validatePermission: SOGoPerm_DeleteObject + onObject: sogoObject + inContext: woContext]) + access |= 4; + } + *data = MAPILongValue (memCtx, access); + + return MAPISTORE_SUCCESS; +} + +- (int) getPrAccessLevel: (void **) data // TODO + inMemCtx: (TALLOC_CTX *) memCtx +{ + MAPIStoreContext *context; + WOContext *woContext; + SoSecurityManager *sm; + uint32_t accessLvl; + + context = [self context]; + if ([[context activeUser] isEqual: [context ownerUser]]) + accessLvl = 1; + else + { + sm = [SoSecurityManager sharedSecurityManager]; + woContext = [context woContext]; + + if (![sm validatePermission: SoPerm_ChangeImagesAndFiles + onObject: sogoObject + inContext: woContext]) + accessLvl = 1; + else + accessLvl = 0; + } + *data = MAPILongValue (memCtx, accessLvl); + + return MAPISTORE_SUCCESS; +} + - (int) getPrChangeKey: (void **) data inMemCtx: (TALLOC_CTX *) memCtx { diff --git a/OpenChange/MAPIStoreGCSMessageTable.h b/OpenChange/MAPIStoreGCSMessageTable.h index 8c1a941ed..00b03cded 100644 --- a/OpenChange/MAPIStoreGCSMessageTable.h +++ b/OpenChange/MAPIStoreGCSMessageTable.h @@ -29,7 +29,6 @@ @interface MAPIStoreGCSMessageTable : MAPIStoreMessageTable -- (EOQualifier *) componentQualifier; - (NSString *) sortIdentifierForProperty: (enum MAPITAGS) property; @end diff --git a/OpenChange/MAPIStoreGCSMessageTable.m b/OpenChange/MAPIStoreGCSMessageTable.m index 40477775a..6eb096ebe 100644 --- a/OpenChange/MAPIStoreGCSMessageTable.m +++ b/OpenChange/MAPIStoreGCSMessageTable.m @@ -152,13 +152,6 @@ return rc; } -- (EOQualifier *) componentQualifier -{ - [self subclassResponsibility: _cmd]; - - return nil; -} - /* sorting */ - (EOSortOrdering *) _sortOrderingFromSortOrder: (struct SSortOrder *) sortOrder diff --git a/OpenChange/MAPIStoreMessage.h b/OpenChange/MAPIStoreMessage.h index 83dfa57a2..d1494c060 100644 --- a/OpenChange/MAPIStoreMessage.h +++ b/OpenChange/MAPIStoreMessage.h @@ -42,6 +42,7 @@ NSArray *attachmentKeys; NSMutableDictionary *attachmentParts; NSMutableArray *activeTables; + NSArray *activeUserRoles; } - (void) getMessageData: (struct mapistore_message **) dataPtr @@ -63,13 +64,15 @@ - (int) getAttachmentTable: (MAPIStoreAttachmentTable **) tablePtr andRowCount: (uint32_t *) countPtr; - (int) setReadFlag: (uint8_t) flag; -- (int) saveMessage; +- (enum mapistore_error) saveMessage; /* helper getters */ - (int) getSMTPAddrType: (void **) data inMemCtx: (TALLOC_CTX *) memCtx; - (NSArray *) activeContainerMessageTables; +- (NSArray *) activeUserRoles; + /* subclasses */ - (void) save; @@ -77,6 +80,9 @@ - (MAPIStoreAttachment *) createAttachment; - (MAPIStoreAttachmentTable *) attachmentTable; +- (BOOL) subscriberCanReadMessage; +- (BOOL) subscriberCanModifyMessage; + @end #endif /* MAPISTOREMESSAGE_H */ diff --git a/OpenChange/MAPIStoreMessage.m b/OpenChange/MAPIStoreMessage.m index f2c78814e..be25d9a18 100644 --- a/OpenChange/MAPIStoreMessage.m +++ b/OpenChange/MAPIStoreMessage.m @@ -28,6 +28,7 @@ #import #import #import +#import #import #import "MAPIStoreActiveTables.h" @@ -137,6 +138,7 @@ rtf2html (NSData *compressedRTF) { attachmentParts = [NSMutableDictionary new]; activeTables = [NSMutableArray new]; + activeUserRoles = nil; } return self; @@ -144,6 +146,7 @@ rtf2html (NSData *compressedRTF) - (void) dealloc { + [activeUserRoles release]; [attachmentKeys release]; [attachmentParts release]; [activeTables release]; @@ -279,6 +282,22 @@ rtf2html (NSData *compressedRTF) return MAPISTORE_SUCCESS; } +- (int) addPropertiesFromRow: (struct SRow *) aRow +{ + enum mapistore_error rc; + MAPIStoreContext *context; + + context = [self context]; + + if ([[context activeUser] isEqual: [context ownerUser]] + || [self subscriberCanModifyMessage]) + rc = [super addPropertiesFromRow: aRow]; + else + rc = MAPISTORE_ERR_DENIED; + + return rc; +} + - (void) addProperties: (NSDictionary *) newNewProperties { NSData *htmlData, *rtfData; @@ -404,73 +423,85 @@ rtf2html (NSData *compressedRTF) andType: MAPISTORE_MESSAGE_TABLE]; } -- (int) saveMessage +- (enum mapistore_error) saveMessage { + enum mapistore_error rc; NSArray *containerTables; NSUInteger count, max; struct mapistore_object_notification_parameters *notif_parameters; uint64_t folderId; struct mapistore_context *mstoreCtx; + MAPIStoreContext *context; - /* notifications */ - folderId = [(MAPIStoreFolder *) container objectId]; - mstoreCtx = [[self context] connectionInfo]->mstore_ctx; - - /* folder modified */ - notif_parameters - = talloc_zero(NULL, struct mapistore_object_notification_parameters); - notif_parameters->object_id = folderId; - if (isNew) + context = [self context]; + if ([[context activeUser] isEqual: [context ownerUser]] + || ((isNew + && [(MAPIStoreFolder *) container subscriberCanCreateMessages]) + || (!isNew && [self subscriberCanModifyMessage]))) { - notif_parameters->tag_count = 3; - notif_parameters->tags = talloc_array (notif_parameters, - enum MAPITAGS, 3); - notif_parameters->tags[0] = PR_CONTENT_COUNT; - notif_parameters->tags[1] = PR_MESSAGE_SIZE; - notif_parameters->tags[2] = PR_NORMAL_MESSAGE_SIZE; - notif_parameters->new_message_count = true; - notif_parameters->message_count - = [[(MAPIStoreFolder *) container messageKeys] count] + 1; - } - mapistore_push_notification (mstoreCtx, - MAPISTORE_FOLDER, MAPISTORE_OBJECT_MODIFIED, - notif_parameters); - talloc_free (notif_parameters); + /* notifications */ + folderId = [(MAPIStoreFolder *) container objectId]; + mstoreCtx = [[self context] connectionInfo]->mstore_ctx; - /* message created */ - if (isNew) - { + /* folder modified */ notif_parameters - = talloc_zero(NULL, - struct mapistore_object_notification_parameters); - notif_parameters->object_id = [self objectId]; - notif_parameters->folder_id = folderId; - - notif_parameters->tag_count = 0xffff; + = talloc_zero(NULL, struct mapistore_object_notification_parameters); + notif_parameters->object_id = folderId; + if (isNew) + { + notif_parameters->tag_count = 3; + notif_parameters->tags = talloc_array (notif_parameters, + enum MAPITAGS, 3); + notif_parameters->tags[0] = PR_CONTENT_COUNT; + notif_parameters->tags[1] = PR_MESSAGE_SIZE; + notif_parameters->tags[2] = PR_NORMAL_MESSAGE_SIZE; + notif_parameters->new_message_count = true; + notif_parameters->message_count + = [[(MAPIStoreFolder *) container messageKeys] count] + 1; + } mapistore_push_notification (mstoreCtx, - MAPISTORE_MESSAGE, MAPISTORE_OBJECT_CREATED, + MAPISTORE_FOLDER, MAPISTORE_OBJECT_MODIFIED, notif_parameters); talloc_free (notif_parameters); - } - /* we ensure the table caches are loaded so that old and new state - can be compared */ - containerTables = [self activeContainerMessageTables]; - max = [containerTables count]; - for (count = 0; count < max; count++) - [[containerTables objectAtIndex: count] restrictedChildKeys]; + /* message created */ + if (isNew) + { + notif_parameters + = talloc_zero(NULL, + struct mapistore_object_notification_parameters); + notif_parameters->object_id = [self objectId]; + notif_parameters->folder_id = folderId; + + notif_parameters->tag_count = 0xffff; + mapistore_push_notification (mstoreCtx, + MAPISTORE_MESSAGE, MAPISTORE_OBJECT_CREATED, + notif_parameters); + talloc_free (notif_parameters); + } + + /* we ensure the table caches are loaded so that old and new state + can be compared */ + containerTables = [self activeContainerMessageTables]; + max = [containerTables count]; + for (count = 0; count < max; count++) + [[containerTables objectAtIndex: count] restrictedChildKeys]; - [self save]; + [self save]; - /* table modified */ - for (count = 0; count < max; count++) - [[containerTables objectAtIndex: count] - notifyChangesForChild: self]; - [self setIsNew: NO]; - [properties removeAllObjects]; - [container cleanupCaches]; + /* table modified */ + for (count = 0; count < max; count++) + [[containerTables objectAtIndex: count] + notifyChangesForChild: self]; + [self setIsNew: NO]; + [properties removeAllObjects]; + [container cleanupCaches]; + rc = MAPISTORE_SUCCESS; + } + else + rc = MAPISTORE_ERR_DENIED; - return MAPISTORE_SUCCESS; + return rc; } /* helper getters */ @@ -513,32 +544,61 @@ rtf2html (NSData *compressedRTF) return MAPISTORE_SUCCESS; } -- (int) getPrAccess: (void **) data // TODO +/* + Possible values are: + + 0x00000001 Modify + 0x00000002 Read + 0x00000004 Delete + 0x00000008 Create Hierarchy Table + 0x00000010 Create Contents Table + 0x00000020 Create Associated Contents Table +*/ +- (int) getPrAccess: (void **) data inMemCtx: (TALLOC_CTX *) memCtx { - *data = MAPILongValue (memCtx, 0x03); + uint32_t access = 0; + BOOL userIsOwner; + MAPIStoreContext *context; + + context = [self context]; + userIsOwner = [[context activeUser] isEqual: [context ownerUser]]; + if (userIsOwner || [self subscriberCanModifyMessage]) + access |= 0x01; + if (userIsOwner || [self subscriberCanReadMessage]) + access |= 0x02; + if (userIsOwner || [(MAPIStoreFolder *) container subscriberCanDeleteMessages]) + access |= 0x04; + + *data = MAPILongValue (memCtx, access); return MAPISTORE_SUCCESS; } -- (int) getPrAccessLevel: (void **) data // TODO +/* + Possible values are: + + 0x00000000 Read-Only + 0x00000001 Modify +*/ +- (int) getPrAccessLevel: (void **) data inMemCtx: (TALLOC_CTX *) memCtx { - *data = MAPILongValue (memCtx, 0x01); + uint32_t access = 0; + BOOL userIsOwner; + MAPIStoreContext *context; + + context = [self context]; + userIsOwner = [[context activeUser] isEqual: [context ownerUser]]; + if (userIsOwner || [self subscriberCanModifyMessage]) + access = 0x01; + else + access = 0; + *data = MAPILongValue (memCtx, access); return MAPISTORE_SUCCESS; } -// - (int) getPrViewStyle: (void **) data -// { -// return [self getLongZero: data inMemCtx: memCtx]; -// } - -// - (int) getPrViewMajorversion: (void **) data -// { -// return [self getLongZero: data inMemCtx: memCtx]; -// } - - (int) getPidLidSideEffects: (void **) data // TODO inMemCtx: (TALLOC_CTX *) memCtx { @@ -799,4 +859,31 @@ rtf2html (NSData *compressedRTF) [activeTables removeObject: activeTable]; } +- (NSArray *) activeUserRoles +{ + MAPIStoreContext *context; + + if (!activeUserRoles) + { + context = [self context]; + + activeUserRoles = [[context activeUser] + rolesForObject: sogoObject + inContext: [context woContext]]; + [activeUserRoles retain]; + } + + return activeUserRoles; +} + +- (BOOL) subscriberCanReadMessage +{ + return NO; +} + +- (BOOL) subscriberCanModifyMessage +{ + return NO; +} + @end diff --git a/OpenChange/MAPIStoreNotesMessage.m b/OpenChange/MAPIStoreNotesMessage.m index 825e167a1..3933c167e 100644 --- a/OpenChange/MAPIStoreNotesMessage.m +++ b/OpenChange/MAPIStoreNotesMessage.m @@ -20,7 +20,11 @@ * Boston, MA 02111-1307, USA. */ +#import + #import "MAPIStoreTypes.h" +#import "NSObject+MAPIStore.h" +#import "NSString+MAPIStore.h" #import "MAPIStoreNotesMessage.h" @@ -42,12 +46,28 @@ return MAPISTORE_SUCCESS; } +- (int) getPrMessageClass: (void **) data inMemCtx: (TALLOC_CTX *) memCtx +{ + *data = [@"IPM.StickyNote" asUnicodeInMemCtx: memCtx]; + + return MAPISTORE_SUCCESS; +} + - (int) getPrSubject: (void **) data inMemCtx: (TALLOC_CTX *) memCtx { - return [self getProperty: data - withTag: PR_NORMALIZED_SUBJECT_UNICODE - inMemCtx: memCtx]; + id value; + int rc; + + value = [[sogoObject properties] + objectForKey: MAPIPropertyKey (PR_NORMALIZED_SUBJECT_UNICODE)]; + if (value) + rc = [value getValue: data forTag: PR_NORMALIZED_SUBJECT_UNICODE + inMemCtx: memCtx]; + else + rc = MAPISTORE_ERR_NOT_FOUND; + + return rc; } @end diff --git a/OpenChange/MAPIStoreSOGo.m b/OpenChange/MAPIStoreSOGo.m index 3deda51e7..ffdbea6d0 100644 --- a/OpenChange/MAPIStoreSOGo.m +++ b/OpenChange/MAPIStoreSOGo.m @@ -50,7 +50,7 @@ #include #include -static int +static enum mapistore_error sogo_backend_unexpected_error() { NSLog (@" UNEXPECTED WEIRDNESS: RECEIVED NO OBJECT"); @@ -62,7 +62,7 @@ sogo_backend_unexpected_error() \return MAPISTORE_SUCCESS on success */ -static int +static enum mapistore_error sogo_backend_init (void) { NSAutoreleasePool *pool; @@ -115,7 +115,7 @@ sogo_backend_init (void) \param private_data pointer to the private backend context */ -static int +static enum mapistore_error sogo_backend_create_context(TALLOC_CTX *mem_ctx, struct mapistore_connection_info *conn_info, struct tdb_wrap *indexingTdb, @@ -163,7 +163,7 @@ sogo_backend_create_context(TALLOC_CTX *mem_ctx, \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE error */ -static int +static enum mapistore_error sogo_context_get_path(void *backend_object, TALLOC_CTX *mem_ctx, uint64_t fmid, char **path) { @@ -190,7 +190,7 @@ sogo_context_get_path(void *backend_object, TALLOC_CTX *mem_ctx, return rc; } -static int +static enum mapistore_error sogo_context_get_root_folder(void *backend_object, TALLOC_CTX *mem_ctx, uint64_t fid, void **folder_object) { @@ -229,7 +229,7 @@ sogo_context_get_root_folder(void *backend_object, TALLOC_CTX *mem_ctx, \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR */ -static int +static enum mapistore_error sogo_folder_open_folder(void *folder_object, TALLOC_CTX *mem_ctx, uint64_t fid, void **childfolder_object) { struct MAPIStoreTallocWrapper *wrapper; @@ -265,7 +265,7 @@ sogo_folder_open_folder(void *folder_object, TALLOC_CTX *mem_ctx, uint64_t fid, \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR */ -static int +static enum mapistore_error sogo_folder_create_folder(void *folder_object, TALLOC_CTX *mem_ctx, uint64_t fid, struct SRow *aRow, void **childfolder_object) @@ -304,7 +304,7 @@ sogo_folder_create_folder(void *folder_object, TALLOC_CTX *mem_ctx, \return MAPISTORE_SUCCESS on success, otherwise MAPISTORE_ERROR */ -static int +static enum mapistore_error sogo_folder_delete_folder(void *folder_object, uint64_t fid) { struct MAPIStoreTallocWrapper *wrapper; @@ -330,7 +330,7 @@ sogo_folder_delete_folder(void *folder_object, uint64_t fid) return rc; } -static int +static enum mapistore_error sogo_folder_get_child_count(void *folder_object, uint8_t table_type, uint32_t *child_count) { struct MAPIStoreTallocWrapper *wrapper; @@ -356,10 +356,10 @@ sogo_folder_get_child_count(void *folder_object, uint8_t table_type, uint32_t *c return rc; } -static int +static enum mapistore_error sogo_folder_open_message(void *folder_object, TALLOC_CTX *mem_ctx, - uint64_t mid, + uint64_t mid, bool write_access, void **message_object) { struct MAPIStoreTallocWrapper *wrapper; @@ -375,7 +375,10 @@ sogo_folder_open_message(void *folder_object, wrapper = folder_object; folder = wrapper->MAPIStoreSOGoObject; pool = [NSAutoreleasePool new]; - rc = [folder openMessage: &message withMID: mid inMemCtx: mem_ctx]; + rc = [folder openMessage: &message + withMID: mid + forWriting: write_access + inMemCtx: mem_ctx]; if (rc == MAPISTORE_SUCCESS) *message_object = [message tallocWrapper: mem_ctx]; [pool release]; @@ -388,7 +391,7 @@ sogo_folder_open_message(void *folder_object, return rc; } -static int +static enum mapistore_error sogo_folder_create_message(void *folder_object, TALLOC_CTX *mem_ctx, uint64_t mid, @@ -423,7 +426,7 @@ sogo_folder_create_message(void *folder_object, return rc; } -static int +static enum mapistore_error sogo_folder_delete_message(void *folder_object, uint64_t mid, uint8_t flags) { struct MAPIStoreTallocWrapper *wrapper; @@ -449,7 +452,7 @@ sogo_folder_delete_message(void *folder_object, uint64_t mid, uint8_t flags) return rc; } -static int +static enum mapistore_error sogo_folder_move_copy_messages(void *folder_object, void *source_folder_object, uint32_t mid_count, @@ -489,7 +492,7 @@ sogo_folder_move_copy_messages(void *folder_object, return rc; } -static int +static enum mapistore_error sogo_folder_get_deleted_fmids(void *folder_object, TALLOC_CTX *mem_ctx, uint8_t table_type, uint64_t change_num, struct I8Array_r **fmidsp, uint64_t *cnp) @@ -521,7 +524,7 @@ sogo_folder_get_deleted_fmids(void *folder_object, TALLOC_CTX *mem_ctx, return rc; } -static int +static enum mapistore_error sogo_folder_open_table(void *folder_object, TALLOC_CTX *mem_ctx, uint8_t table_type, uint32_t handle_id, void **table_object, uint32_t *row_count) @@ -555,7 +558,7 @@ sogo_folder_open_table(void *folder_object, TALLOC_CTX *mem_ctx, return rc; } -static int +static enum mapistore_error sogo_folder_modify_permissions(void *folder_object, uint8_t flags, uint16_t pcount, struct PermissionData *permissions) @@ -585,7 +588,7 @@ sogo_folder_modify_permissions(void *folder_object, uint8_t flags, return rc; } -static int +static enum mapistore_error sogo_message_get_message_data(void *message_object, TALLOC_CTX *mem_ctx, struct mapistore_message **msg_dataP) @@ -615,7 +618,7 @@ sogo_message_get_message_data(void *message_object, return rc; } -static int +static enum mapistore_error sogo_message_create_attachment (void *message_object, TALLOC_CTX *mem_ctx, void **attachment_object, uint32_t *aidp) { struct MAPIStoreTallocWrapper *wrapper; @@ -645,7 +648,7 @@ sogo_message_create_attachment (void *message_object, TALLOC_CTX *mem_ctx, void return rc; } -static int +static enum mapistore_error sogo_message_open_attachment (void *message_object, TALLOC_CTX *mem_ctx, uint32_t aid, void **attachment_object) { @@ -676,7 +679,7 @@ sogo_message_open_attachment (void *message_object, TALLOC_CTX *mem_ctx, return rc; } -static int +static enum mapistore_error sogo_message_get_attachment_table (void *message_object, TALLOC_CTX *mem_ctx, void **table_object, uint32_t *row_count) { struct MAPIStoreTallocWrapper *wrapper; @@ -707,7 +710,7 @@ sogo_message_get_attachment_table (void *message_object, TALLOC_CTX *mem_ctx, vo return rc; } -static int +static enum mapistore_error sogo_message_modify_recipients (void *message_object, struct SPropTagArray *columns, uint16_t count, @@ -739,7 +742,7 @@ sogo_message_modify_recipients (void *message_object, return rc; } -static int +static enum mapistore_error sogo_message_set_read_flag (void *message_object, uint8_t flag) { struct MAPIStoreTallocWrapper *wrapper; @@ -766,7 +769,7 @@ sogo_message_set_read_flag (void *message_object, uint8_t flag) return rc; } -static int +static enum mapistore_error sogo_message_save (void *message_object) { struct MAPIStoreTallocWrapper *wrapper; @@ -793,7 +796,7 @@ sogo_message_save (void *message_object) return rc; } -static int +static enum mapistore_error sogo_message_submit (void *message_object, enum SubmitFlags flags) { struct MAPIStoreTallocWrapper *wrapper; @@ -820,7 +823,7 @@ sogo_message_submit (void *message_object, enum SubmitFlags flags) return rc; } -static int +static enum mapistore_error sogo_message_attachment_open_embedded_message (void *attachment_object, TALLOC_CTX *mem_ctx, void **message_object, @@ -858,7 +861,7 @@ sogo_message_attachment_open_embedded_message return rc; } -static int sogo_table_get_available_properties(void *table_object, +static enum mapistore_error sogo_table_get_available_properties(void *table_object, TALLOC_CTX *mem_ctx, struct SPropTagArray **propertiesP) { struct MAPIStoreTallocWrapper *wrapper; @@ -884,7 +887,7 @@ static int sogo_table_get_available_properties(void *table_object, return rc; } -static int +static enum mapistore_error sogo_table_set_columns (void *table_object, uint16_t count, enum MAPITAGS *properties) { struct MAPIStoreTallocWrapper *wrapper; @@ -911,7 +914,7 @@ sogo_table_set_columns (void *table_object, uint16_t count, enum MAPITAGS *prope return rc; } -static int +static enum mapistore_error sogo_table_set_restrictions (void *table_object, struct mapi_SRestriction *restrictions, uint8_t *table_status) { struct MAPIStoreTallocWrapper *wrapper; @@ -940,7 +943,7 @@ sogo_table_set_restrictions (void *table_object, struct mapi_SRestriction *restr return rc; } -static int +static enum mapistore_error sogo_table_set_sort_order (void *table_object, struct SSortOrderSet *sort_order, uint8_t *table_status) { struct MAPIStoreTallocWrapper *wrapper; @@ -969,7 +972,7 @@ sogo_table_set_sort_order (void *table_object, struct SSortOrderSet *sort_order, return rc; } -static int +static enum mapistore_error sogo_table_get_row (void *table_object, TALLOC_CTX *mem_ctx, enum table_query_type query_type, uint32_t row_id, struct mapistore_property_data **data) @@ -998,7 +1001,7 @@ sogo_table_get_row (void *table_object, TALLOC_CTX *mem_ctx, return rc; } -static int +static enum mapistore_error sogo_table_get_row_count (void *table_object, enum table_query_type query_type, uint32_t *row_countp) @@ -1027,7 +1030,7 @@ sogo_table_get_row_count (void *table_object, return rc; } -static int +static enum mapistore_error sogo_table_handle_destructor (void *table_object, uint32_t handle_id) { struct MAPIStoreTallocWrapper *wrapper; @@ -1054,7 +1057,7 @@ sogo_table_handle_destructor (void *table_object, uint32_t handle_id) return rc; } -static int sogo_properties_get_available_properties(void *object, +static enum mapistore_error sogo_properties_get_available_properties(void *object, TALLOC_CTX *mem_ctx, struct SPropTagArray **propertiesP) { @@ -1081,7 +1084,7 @@ static int sogo_properties_get_available_properties(void *object, return rc; } -static int +static enum mapistore_error sogo_properties_get_properties (void *object, TALLOC_CTX *mem_ctx, uint16_t count, enum MAPITAGS *properties, @@ -1112,7 +1115,7 @@ sogo_properties_get_properties (void *object, return rc; } -static int +static enum mapistore_error sogo_properties_set_properties (void *object, struct SRow *aRow) { struct MAPIStoreTallocWrapper *wrapper; @@ -1138,7 +1141,7 @@ sogo_properties_set_properties (void *object, struct SRow *aRow) return rc; } -static int +static enum mapistore_error sogo_manager_generate_uri (TALLOC_CTX *mem_ctx, const char *user, const char *folder, diff --git a/OpenChange/MAPIStoreTasksFolder.m b/OpenChange/MAPIStoreTasksFolder.m index 83eaea02a..228fb8eb5 100644 --- a/OpenChange/MAPIStoreTasksFolder.m +++ b/OpenChange/MAPIStoreTasksFolder.m @@ -157,4 +157,10 @@ return rights; } +- (EOQualifier *) aclQualifier +{ + return [EOQualifier qualifierWithQualifierFormat: + [(SOGoAppointmentFolder *) sogoObject aclSQLListingFilter]]; +} + @end diff --git a/OpenChange/MAPIStoreTasksMessage.m b/OpenChange/MAPIStoreTasksMessage.m index 3dcc4b41d..1418d76fc 100644 --- a/OpenChange/MAPIStoreTasksMessage.m +++ b/OpenChange/MAPIStoreTasksMessage.m @@ -31,10 +31,13 @@ #import #import #import +#import #import #import +#import #import +#import "MAPIStoreContext.h" #import "MAPIStoreTasksFolder.h" #import "MAPIStoreTypes.h" #import "NSDate+MAPIStore.h" @@ -89,7 +92,7 @@ { iCalToDo *task; - task = [sogoObject component: NO secure: NO]; + task = [sogoObject component: NO secure: YES]; *data = [[task summary] asUnicodeInMemCtx: memCtx]; return MAPISTORE_SUCCESS; @@ -101,7 +104,7 @@ uint32_t v; iCalToDo *task; - task = [sogoObject component: NO secure: NO]; + task = [sogoObject component: NO secure: YES]; if ([[task priority] isEqualToString: @"9"]) v = 0x0; else if ([[task priority] isEqualToString: @"1"]) @@ -119,7 +122,7 @@ { iCalToDo *task; - task = [sogoObject component: NO secure: NO]; + task = [sogoObject component: NO secure: YES]; *data = MAPIBoolValue (memCtx, [[task status] isEqualToString: @"COMPLETED"]); @@ -132,7 +135,7 @@ double doubleValue; iCalToDo *task; - task = [sogoObject component: NO secure: NO]; + task = [sogoObject component: NO secure: YES]; doubleValue = ((double) [[task percentComplete] intValue] / 100); *data = MAPIDoubleValue (memCtx, doubleValue); @@ -147,7 +150,7 @@ NSCalendarDate *dateValue; iCalToDo *task; - task = [sogoObject component: NO secure: NO]; + task = [sogoObject component: NO secure: YES]; dateValue = [task completed]; if (dateValue) @@ -209,7 +212,7 @@ NSCalendarDate *dateValue; iCalToDo *task; - task = [sogoObject component: NO secure: NO]; + task = [sogoObject component: NO secure: YES]; dateValue = [task due]; if (dateValue) *data = [dateValue asFileTimeInMemCtx: memCtx]; @@ -226,7 +229,7 @@ NSCalendarDate *dateValue; iCalToDo *task; - task = [sogoObject component: NO secure: NO]; + task = [sogoObject component: NO secure: YES]; dateValue = [task startDate]; if (dateValue) *data = [dateValue asFileTimeInMemCtx: memCtx]; @@ -262,7 +265,7 @@ uint32_t longValue; iCalToDo *task; - task = [sogoObject component: NO secure: NO]; + task = [sogoObject component: NO secure: YES]; status = [task status]; if (![status length] || [status isEqualToString: @"NEEDS-ACTION"]) @@ -296,6 +299,27 @@ return [self getLongZero: data inMemCtx: memCtx]; } +- (BOOL) subscriberCanReadMessage +{ + return ([[self activeUserRoles] + containsObject: SOGoCalendarRole_ComponentViewer] + || [self subscriberCanModifyMessage]); +} + +- (BOOL) subscriberCanModifyMessage +{ + BOOL rc; + NSArray *roles = [self activeUserRoles]; + + if (isNew) + rc = [roles containsObject: SOGoRole_ObjectCreator]; + else + rc = ([roles containsObject: SOGoCalendarRole_ComponentModifier] + || [roles containsObject: SOGoCalendarRole_ComponentResponder]); + + return rc; +} + - (void) save { iCalCalendar *vCalendar; diff --git a/OpenChange/MAPIStoreTasksMessageTable.m b/OpenChange/MAPIStoreTasksMessageTable.m index 1fa190b83..9f6e5ad28 100644 --- a/OpenChange/MAPIStoreTasksMessageTable.m +++ b/OpenChange/MAPIStoreTasksMessageTable.m @@ -84,6 +84,9 @@ static Class MAPIStoreTasksMessageK = Nil; else rc = MAPIRestrictionStateAlwaysFalse; break; + case PR_SENSITIVITY: + rc = MAPIRestrictionStateAlwaysTrue; + break; case PR_RULE_PROVIDER_UNICODE: // TODO: what's this? rc = MAPIRestrictionStateAlwaysTrue; break; diff --git a/OpenChange/MAPIStoreTypes.m b/OpenChange/MAPIStoreTypes.m index ba8ed926a..06eadf4e9 100644 --- a/OpenChange/MAPIStoreTypes.m +++ b/OpenChange/MAPIStoreTypes.m @@ -190,12 +190,12 @@ NSObjectFromSPropValue (const struct SPropValue *value) case PT_UNICODE: result = (value->value.lpszW ? [NSString stringWithUTF8String: value->value.lpszW] - : @""); + : (id) @""); break; case PT_STRING8: result = (value->value.lpszA ? [NSString stringWithUTF8String: value->value.lpszA] - : @""); + : (id) @""); break; case PT_SYSTIME: result = [NSCalendarDate dateFromFileTime: &(value->value.ft)]; diff --git a/OpenChange/unrtf-0.21.2.diff b/OpenChange/unrtf-0.21.2.diff index 1c054cac1..2cf49e698 100644 --- a/OpenChange/unrtf-0.21.2.diff +++ b/OpenChange/unrtf-0.21.2.diff @@ -1,6 +1,6 @@ diff -durpN unrtf-0.21.2.old/outputs/html.conf unrtf-0.21.2/outputs/html.conf --- unrtf-0.21.2.old/outputs/html.conf 2010-08-15 08:44:09.000000000 -0400 -+++ unrtf-0.21.2/outputs/html.conf 2011-11-09 15:48:29.982798286 -0500 ++++ unrtf-0.21.2/outputs/html.conf 2011-11-09 15:53:21.802783775 -0500 @@ -5,7 +5,7 @@ comment_end --> @@ -12,7 +12,7 @@ diff -durpN unrtf-0.21.2.old/outputs/html.conf unrtf-0.21.2/outputs/html.conf diff -durpN unrtf-0.21.2.old/src/attr.c unrtf-0.21.2/src/attr.c --- unrtf-0.21.2.old/src/attr.c 2010-07-03 22:30:58.000000000 -0400 -+++ unrtf-0.21.2/src/attr.c 2011-11-09 15:48:29.990798214 -0500 ++++ unrtf-0.21.2/src/attr.c 2011-12-01 10:14:45.282855488 -0500 @@ -1,23 +1,23 @@ /*============================================================================= - GNU UnRTF, a command-line program to convert RTF documents to other formats. @@ -1176,7 +1176,7 @@ diff -durpN unrtf-0.21.2.old/src/attr.c unrtf-0.21.2/src/attr.c + { + col = (Collection *)my_malloc(sizeof(Collection)); + col->nr = nr; -+ col->text = text; ++ col->text = strdup(text); + col->next = NULL; + } + else @@ -1188,7 +1188,7 @@ diff -durpN unrtf-0.21.2.old/src/attr.c unrtf-0.21.2/src/attr.c + /* Here is a memory leak but not heavy. Do we need to care about this? + my_free(a->alias.text); + */ -+ c->text = text; ++ c->text = strdup(text); - return col; - } @@ -1207,7 +1207,7 @@ diff -durpN unrtf-0.21.2.old/src/attr.c unrtf-0.21.2/src/attr.c - } + c->next = (Collection *)my_malloc(sizeof(Collection)); + c->next->nr = nr; -+ c->next->text = text; ++ c->next->text = strdup(text); + c->next->next = NULL; + } @@ -1239,7 +1239,7 @@ diff -durpN unrtf-0.21.2.old/src/attr.c unrtf-0.21.2/src/attr.c } /*======================================================================== -@@ -855,13 +831,13 @@ get_from_collection(Collection *c, int n +@@ -855,13 +831,15 @@ get_from_collection(Collection *c, int n void free_collection(Collection *c) { @@ -1255,14 +1255,17 @@ diff -durpN unrtf-0.21.2.old/src/attr.c unrtf-0.21.2/src/attr.c + while (c != NULL) + { + c2 = c->next; ++ if (c->text) { ++ my_free((void *)c->text); ++ } + my_free((void *)c); + c = c2; + } } - +- diff -durpN unrtf-0.21.2.old/src/attr.h unrtf-0.21.2/src/attr.h --- unrtf-0.21.2.old/src/attr.h 2010-07-03 22:30:58.000000000 -0400 -+++ unrtf-0.21.2/src/attr.h 2011-11-09 15:48:29.990798214 -0500 ++++ unrtf-0.21.2/src/attr.h 2011-11-09 15:53:21.806783776 -0500 @@ -1,23 +1,23 @@ /*============================================================================= - GNU UnRTF, a command-line program to convert RTF documents to other formats. @@ -1412,7 +1415,7 @@ diff -durpN unrtf-0.21.2.old/src/attr.h unrtf-0.21.2/src/attr.h +#endif /* ATTR_H */ diff -durpN unrtf-0.21.2.old/src/convert.c unrtf-0.21.2/src/convert.c --- unrtf-0.21.2.old/src/convert.c 2011-06-07 08:00:23.000000000 -0400 -+++ unrtf-0.21.2/src/convert.c 2011-11-09 15:52:04.710787385 -0500 ++++ unrtf-0.21.2/src/convert.c 2011-12-01 10:32:16.958862025 -0500 @@ -1,24 +1,24 @@ /*=========================================================================== @@ -6856,7 +6859,7 @@ diff -durpN unrtf-0.21.2.old/src/convert.c unrtf-0.21.2/src/convert.c } -@@ -3652,37 +3664,225 @@ word_print_core (Word *w) +@@ -3652,37 +3664,227 @@ word_print_core (Word *w) *=======================================================================*/ void @@ -7045,6 +7048,8 @@ diff -durpN unrtf-0.21.2.old/src/convert.c unrtf-0.21.2/src/convert.c + } + + hash_free(&cc); ++ if (cc.input_str) ++ my_free(cc.input_str); + word_free(word); + fonttable_free(oc.conversion); + if (my_iconv_is_valid(oc.conversion->desc)) @@ -7106,7 +7111,7 @@ diff -durpN unrtf-0.21.2.old/src/convert.c unrtf-0.21.2/src/convert.c } diff -durpN unrtf-0.21.2.old/src/convert.h unrtf-0.21.2/src/convert.h --- unrtf-0.21.2.old/src/convert.h 2010-07-03 22:30:58.000000000 -0400 -+++ unrtf-0.21.2/src/convert.h 2011-11-09 15:48:29.998798267 -0500 ++++ unrtf-0.21.2/src/convert.h 2011-11-09 15:53:21.810783765 -0500 @@ -36,18 +36,135 @@ #ifndef _CONVERT @@ -7250,7 +7255,7 @@ diff -durpN unrtf-0.21.2.old/src/convert.h unrtf-0.21.2/src/convert.h diff -durpN unrtf-0.21.2.old/src/defs.h unrtf-0.21.2/src/defs.h --- unrtf-0.21.2.old/src/defs.h 2010-07-03 22:30:58.000000000 -0400 -+++ unrtf-0.21.2/src/defs.h 2011-11-09 15:48:29.998798267 -0500 ++++ unrtf-0.21.2/src/defs.h 2011-11-09 15:53:21.810783765 -0500 @@ -64,9 +64,6 @@ #define SKIP_ONE_WORD 2 #endif @@ -7270,7 +7275,7 @@ diff -durpN unrtf-0.21.2.old/src/defs.h unrtf-0.21.2/src/defs.h +#define DEFAULT_OUTPUT "html" diff -durpN unrtf-0.21.2.old/src/error.c unrtf-0.21.2/src/error.c --- unrtf-0.21.2.old/src/error.c 2010-07-03 22:30:58.000000000 -0400 -+++ unrtf-0.21.2/src/error.c 2011-11-09 15:48:29.998798267 -0500 ++++ unrtf-0.21.2/src/error.c 2011-11-09 15:53:21.810783765 -0500 @@ -51,27 +51,11 @@ #include #endif @@ -7315,7 +7320,7 @@ diff -durpN unrtf-0.21.2.old/src/error.c unrtf-0.21.2/src/error.c #endif diff -durpN unrtf-0.21.2.old/src/error.h unrtf-0.21.2/src/error.h --- unrtf-0.21.2.old/src/error.h 2010-07-03 22:30:58.000000000 -0400 -+++ unrtf-0.21.2/src/error.h 2011-11-09 15:48:29.998798267 -0500 ++++ unrtf-0.21.2/src/error.h 2011-11-09 15:53:21.810783765 -0500 @@ -37,9 +37,10 @@ #define CHECK_MALLOC_SUCCESS(XX) { if ((XX)==NULL) { fprintf (stderr, "internal error: cannot allocate memory in %s at %d\n", __FILE__, __LINE__); exit (1); }} @@ -7330,7 +7335,7 @@ diff -durpN unrtf-0.21.2.old/src/error.h unrtf-0.21.2/src/error.h diff -durpN unrtf-0.21.2.old/src/hash.c unrtf-0.21.2/src/hash.c --- unrtf-0.21.2.old/src/hash.c 2010-07-03 22:30:58.000000000 -0400 -+++ unrtf-0.21.2/src/hash.c 2011-11-09 15:48:29.998798267 -0500 ++++ unrtf-0.21.2/src/hash.c 2011-11-09 15:53:21.810783765 -0500 @@ -53,24 +53,16 @@ #include #endif @@ -7535,7 +7540,7 @@ diff -durpN unrtf-0.21.2.old/src/hash.c unrtf-0.21.2/src/hash.c +} diff -durpN unrtf-0.21.2.old/src/hash.h unrtf-0.21.2/src/hash.h --- unrtf-0.21.2.old/src/hash.h 2010-07-03 22:30:58.000000000 -0400 -+++ unrtf-0.21.2/src/hash.h 2011-11-09 15:51:52.846788680 -0500 ++++ unrtf-0.21.2/src/hash.h 2011-11-09 15:53:21.810783765 -0500 @@ -32,11 +32,15 @@ * 16 Dec 07, daved@physiol.usyd.edu.au: updated to GPL v3 *--------------------------------------------------------------------*/ @@ -7559,7 +7564,7 @@ diff -durpN unrtf-0.21.2.old/src/hash.h unrtf-0.21.2/src/hash.h +#endif /* HASH_H */ diff -durpN unrtf-0.21.2.old/src/main.c unrtf-0.21.2/src/main.c --- unrtf-0.21.2.old/src/main.c 2010-07-03 22:30:58.000000000 -0400 -+++ unrtf-0.21.2/src/main.c 2011-11-09 15:48:29.998798267 -0500 ++++ unrtf-0.21.2/src/main.c 2011-11-09 15:53:21.810783765 -0500 @@ -1,23 +1,23 @@ /*============================================================================= - GNU UnRTF, a command-line program to convert RTF documents to other formats. @@ -7981,7 +7986,7 @@ diff -durpN unrtf-0.21.2.old/src/main.c unrtf-0.21.2/src/main.c - diff -durpN unrtf-0.21.2.old/src/main.h unrtf-0.21.2/src/main.h --- unrtf-0.21.2.old/src/main.h 2010-07-03 22:30:58.000000000 -0400 -+++ unrtf-0.21.2/src/main.h 2011-11-09 15:48:29.998798267 -0500 ++++ unrtf-0.21.2/src/main.h 2011-11-09 15:53:21.810783765 -0500 @@ -35,21 +35,8 @@ * 17 Jan 10, daved@physiol.usyd.edu.au: change CONFIG_DIR to drop outputs/ *--------------------------------------------------------------------*/ @@ -8007,7 +8012,7 @@ diff -durpN unrtf-0.21.2.old/src/main.h unrtf-0.21.2/src/main.h +#define USAGE "unrtf [--version] [--verbose] [--help] [--nopict|-n] [--noremap] [--html] [--text] [--vt] [--latex] [--rtf] [-P config_search_path] [-t )] " diff -durpN unrtf-0.21.2.old/src/Makefile.am unrtf-0.21.2/src/Makefile.am --- unrtf-0.21.2.old/src/Makefile.am 2010-07-03 22:30:58.000000000 -0400 -+++ unrtf-0.21.2/src/Makefile.am 2011-11-09 15:48:29.998798267 -0500 ++++ unrtf-0.21.2/src/Makefile.am 2011-11-09 15:53:21.810783765 -0500 @@ -13,7 +13,6 @@ unrtf_SOURCES = attr.c attr.h \ malloc.c malloc.h \ output.c output.h \ @@ -8018,7 +8023,7 @@ diff -durpN unrtf-0.21.2.old/src/Makefile.am unrtf-0.21.2/src/Makefile.am util.c util.h \ diff -durpN unrtf-0.21.2.old/src/malloc.c unrtf-0.21.2/src/malloc.c --- unrtf-0.21.2.old/src/malloc.c 2010-07-09 01:13:05.000000000 -0400 -+++ unrtf-0.21.2/src/malloc.c 2011-11-09 15:48:29.998798267 -0500 ++++ unrtf-0.21.2/src/malloc.c 2011-12-01 10:36:18.514864760 -0500 @@ -135,19 +135,19 @@ total_malloced (void) { *=======================================================================*/ @@ -8058,7 +8063,7 @@ diff -durpN unrtf-0.21.2.old/src/malloc.c unrtf-0.21.2/src/malloc.c } diff -durpN unrtf-0.21.2.old/src/malloc.h unrtf-0.21.2/src/malloc.h --- unrtf-0.21.2.old/src/malloc.h 2010-07-03 22:30:58.000000000 -0400 -+++ unrtf-0.21.2/src/malloc.h 2011-11-09 15:48:29.998798267 -0500 ++++ unrtf-0.21.2/src/malloc.h 2011-11-09 15:53:21.810783765 -0500 @@ -32,9 +32,10 @@ * 09 Nov 08, arkadiusz.firus@gmail.com: added my_realloc *--------------------------------------------------------------------*/ @@ -8074,7 +8079,7 @@ diff -durpN unrtf-0.21.2.old/src/malloc.h unrtf-0.21.2/src/malloc.h +extern char * my_strdup (struct ConversionContext *, char*); diff -durpN unrtf-0.21.2.old/src/my_iconv.c unrtf-0.21.2/src/my_iconv.c --- unrtf-0.21.2.old/src/my_iconv.c 2010-08-16 00:12:43.000000000 -0400 -+++ unrtf-0.21.2/src/my_iconv.c 2011-11-09 15:48:29.998798267 -0500 ++++ unrtf-0.21.2/src/my_iconv.c 2011-11-09 15:53:21.814783744 -0500 @@ -12,154 +12,133 @@ #include #include @@ -8316,7 +8321,7 @@ diff -durpN unrtf-0.21.2.old/src/my_iconv.c unrtf-0.21.2/src/my_iconv.c diff -durpN unrtf-0.21.2.old/src/my_iconv.h unrtf-0.21.2/src/my_iconv.h --- unrtf-0.21.2.old/src/my_iconv.h 2010-07-03 22:30:58.000000000 -0400 -+++ unrtf-0.21.2/src/my_iconv.h 2011-11-09 15:48:29.998798267 -0500 ++++ unrtf-0.21.2/src/my_iconv.h 2011-11-09 15:53:21.814783744 -0500 @@ -5,6 +5,9 @@ * Purpose: my_conv definitions *--------------------------------------------------------------------*/ @@ -8346,7 +8351,7 @@ diff -durpN unrtf-0.21.2.old/src/my_iconv.h unrtf-0.21.2/src/my_iconv.h +#endif /* _MY_ICONV */ diff -durpN unrtf-0.21.2.old/src/output.c unrtf-0.21.2/src/output.c --- unrtf-0.21.2.old/src/output.c 2011-06-07 08:04:38.000000000 -0400 -+++ unrtf-0.21.2/src/output.c 2011-11-09 15:50:35.126792073 -0500 ++++ unrtf-0.21.2/src/output.c 2011-12-01 10:30:41.598861702 -0500 @@ -1,23 +1,23 @@ /*============================================================================= - GNU UnRTF, a command-line program to convert RTF documents to other formats. @@ -8449,7 +8454,7 @@ diff -durpN unrtf-0.21.2.old/src/output.c unrtf-0.21.2/src/output.c /*======================================================================== * Name: op_translate_char -@@ -119,102 +122,110 @@ op_free (OutputPersonality *op) +@@ -119,102 +122,113 @@ op_free (OutputPersonality *op) *=======================================================================*/ char * @@ -8463,7 +8468,7 @@ diff -durpN unrtf-0.21.2.old/src/output.c unrtf-0.21.2/src/output.c - size_t inbytes = (ch / 256) + 1, outbytes = inbytes * 4, i; + char *result=NULL; + static char output_buffer[2]={ 0, 0 }; -+ char *inbuf, *outbuf, *originbuf, *origoutbuf; ++ char *inbuf, *outbuf, *originbuf, *origoutbuf, *alias; + size_t inbytes = (ch / 256) + 1, outbytes = inbytes * 4, i; + my_iconv_t cd; @@ -8615,7 +8620,7 @@ diff -durpN unrtf-0.21.2.old/src/output.c unrtf-0.21.2/src/output.c + /* End of conversion*/ - result = get_alias(op, ch); -+ result = get_alias(op, ch); ++ alias = get_alias(op, ch); - if (result == NULL) - if (ch > 127 && op->unisymbol_print) @@ -8623,23 +8628,26 @@ diff -durpN unrtf-0.21.2.old/src/output.c unrtf-0.21.2/src/output.c - else - result = outbuf; - } -+ if (result == NULL) ++ if (alias == NULL) + { + if (ch > 127 && op->unisymbol_print) + result = assemble_string(op->unisymbol_print, ch); + else -+ result = outbuf; ++ result = strdup(outbuf); + } ++ else ++ result = strdup(alias); - return result; + free (originbuf); ++ free (origoutbuf); + } + + return result; } #if 0 /* daved - 0.21.2 */ -@@ -227,123 +238,122 @@ op_translate_char (OutputPersonality *op +@@ -227,123 +241,122 @@ op_translate_char (OutputPersonality *op *=======================================================================*/ char * @@ -8851,7 +8859,7 @@ diff -durpN unrtf-0.21.2.old/src/output.c unrtf-0.21.2/src/output.c } #endif -@@ -357,113 +367,115 @@ op_translate_str (OutputPersonality *op, +@@ -357,113 +370,115 @@ op_translate_str (OutputPersonality *op, *=======================================================================*/ char * @@ -9050,7 +9058,7 @@ diff -durpN unrtf-0.21.2.old/src/output.c unrtf-0.21.2/src/output.c } #endif /*======================================================================== -@@ -475,123 +487,113 @@ op_translate_doublet (OutputPersonality +@@ -475,123 +490,113 @@ op_translate_doublet (OutputPersonality *=======================================================================*/ void @@ -9277,7 +9285,7 @@ diff -durpN unrtf-0.21.2.old/src/output.c unrtf-0.21.2/src/output.c } -@@ -604,123 +606,113 @@ op_begin_std_fontsize (OutputPersonality +@@ -604,123 +609,113 @@ op_begin_std_fontsize (OutputPersonality *=======================================================================*/ void @@ -9504,7 +9512,7 @@ diff -durpN unrtf-0.21.2.old/src/output.c unrtf-0.21.2/src/output.c } #if 1 /* AK3 - AF */ -@@ -734,7 +726,7 @@ op_end_std_fontsize (OutputPersonality * +@@ -734,7 +729,7 @@ op_end_std_fontsize (OutputPersonality * void add_alias(OutputPersonality *op, int nr, char *text) { @@ -9513,7 +9521,7 @@ diff -durpN unrtf-0.21.2.old/src/output.c unrtf-0.21.2/src/output.c } /*======================================================================== -@@ -745,9 +737,8 @@ add_alias(OutputPersonality *op, int nr, +@@ -745,9 +740,8 @@ add_alias(OutputPersonality *op, int nr, *=======================================================================*/ char * @@ -9527,7 +9535,7 @@ diff -durpN unrtf-0.21.2.old/src/output.c unrtf-0.21.2/src/output.c - diff -durpN unrtf-0.21.2.old/src/output.h unrtf-0.21.2/src/output.h --- unrtf-0.21.2.old/src/output.h 2010-08-11 21:09:02.000000000 -0400 -+++ unrtf-0.21.2/src/output.h 2011-11-09 15:48:30.002798270 -0500 ++++ unrtf-0.21.2/src/output.h 2011-11-09 15:53:21.814783744 -0500 @@ -44,227 +44,228 @@ typedef Collection Aliases; @@ -9915,7 +9923,7 @@ diff -durpN unrtf-0.21.2.old/src/output.h unrtf-0.21.2/src/output.h - diff -durpN unrtf-0.21.2.old/src/parse.c unrtf-0.21.2/src/parse.c --- unrtf-0.21.2.old/src/parse.c 2010-07-03 22:30:58.000000000 -0400 -+++ unrtf-0.21.2/src/parse.c 2011-11-09 15:48:30.002798270 -0500 ++++ unrtf-0.21.2/src/parse.c 2011-12-01 10:27:41.486860883 -0500 @@ -1,23 +1,23 @@ /*============================================================================= - GNU UnRTF, a command-line program to convert RTF documents to other formats. @@ -10170,7 +10178,7 @@ diff -durpN unrtf-0.21.2.old/src/parse.c unrtf-0.21.2/src/parse.c } -@@ -222,183 +179,181 @@ expand_word_buffer () +@@ -222,183 +179,184 @@ expand_word_buffer () *=======================================================================*/ static int @@ -10202,6 +10210,9 @@ diff -durpN unrtf-0.21.2.old/src/parse.c unrtf-0.21.2/src/parse.c - error_handler("Cannot allocate word storage"); + /* Get some storage for a word. + */ ++ if (cc->input_str) { ++ my_free(cc->input_str); ++ } + cc->input_str = my_malloc (cc->current_max_length); + if (!cc->input_str) + error_handler(cc, "Cannot allocate word storage"); @@ -10509,7 +10520,7 @@ diff -durpN unrtf-0.21.2.old/src/parse.c unrtf-0.21.2/src/parse.c } -@@ -412,44 +367,42 @@ read_word (FILE *f) +@@ -412,44 +370,42 @@ read_word (FILE *f) *=======================================================================*/ Word * @@ -10586,7 +10597,7 @@ diff -durpN unrtf-0.21.2.old/src/parse.c unrtf-0.21.2/src/parse.c } diff -durpN unrtf-0.21.2.old/src/parse.h unrtf-0.21.2/src/parse.h --- unrtf-0.21.2.old/src/parse.h 2010-07-03 22:30:58.000000000 -0400 -+++ unrtf-0.21.2/src/parse.h 2011-11-09 15:48:30.002798270 -0500 ++++ unrtf-0.21.2/src/parse.h 2011-11-09 15:53:21.814783744 -0500 @@ -38,8 +38,6 @@ #include "word.h" #endif @@ -10679,7 +10690,7 @@ diff -durpN unrtf-0.21.2.old/src/path.h unrtf-0.21.2/src/path.h -void show_dirs(); diff -durpN unrtf-0.21.2.old/src/unrtf.h unrtf-0.21.2/src/unrtf.h --- unrtf-0.21.2.old/src/unrtf.h 1969-12-31 19:00:00.000000000 -0500 -+++ unrtf-0.21.2/src/unrtf.h 2011-11-09 15:48:30.002798270 -0500 ++++ unrtf-0.21.2/src/unrtf.h 2011-11-09 15:53:21.814783744 -0500 @@ -0,0 +1,55 @@ +/*=========================================================================== + GNU UnRTF, a command-line program to convert RTF documents to other formats. @@ -10738,7 +10749,7 @@ diff -durpN unrtf-0.21.2.old/src/unrtf.h unrtf-0.21.2/src/unrtf.h +#endif /* UNRTF_H */ diff -durpN unrtf-0.21.2.old/src/user.c unrtf-0.21.2/src/user.c --- unrtf-0.21.2.old/src/user.c 2011-06-07 08:08:17.000000000 -0400 -+++ unrtf-0.21.2/src/user.c 2011-11-09 15:48:30.002798270 -0500 ++++ unrtf-0.21.2/src/user.c 2011-12-01 09:59:46.215667415 -0500 @@ -7,7 +7,7 @@ *---------------------------------------------------------------------- * Changes: @@ -11168,7 +11179,7 @@ diff -durpN unrtf-0.21.2.old/src/user.c unrtf-0.21.2/src/user.c diff -durpN unrtf-0.21.2.old/src/user.h unrtf-0.21.2/src/user.h --- unrtf-0.21.2.old/src/user.h 2010-07-03 22:30:58.000000000 -0400 -+++ unrtf-0.21.2/src/user.h 2011-11-09 15:48:30.002798270 -0500 ++++ unrtf-0.21.2/src/user.h 2011-11-09 15:53:21.814783744 -0500 @@ -151,9 +151,10 @@ #ifndef _USER @@ -11184,7 +11195,7 @@ diff -durpN unrtf-0.21.2.old/src/user.h unrtf-0.21.2/src/user.h #endif diff -durpN unrtf-0.21.2.old/src/word.c unrtf-0.21.2/src/word.c --- unrtf-0.21.2.old/src/word.c 2010-07-03 22:30:58.000000000 -0400 -+++ unrtf-0.21.2/src/word.c 2011-11-09 15:48:30.002798270 -0500 ++++ unrtf-0.21.2/src/word.c 2011-12-01 10:15:34.590855632 -0500 @@ -1,23 +1,23 @@ /*============================================================================= - GNU UnRTF, a command-line program to convert RTF documents to other formats. @@ -11243,7 +11254,7 @@ diff -durpN unrtf-0.21.2.old/src/word.c unrtf-0.21.2/src/word.c /*======================================================================== * Name: word_string * Purpose: Obtains the string of a Word object. This involves accessing -@@ -90,12 +87,12 @@ static int indent_level=0; +@@ -90,12 +87,14 @@ static int indent_level=0; *=======================================================================*/ char * @@ -11256,13 +11267,15 @@ diff -durpN unrtf-0.21.2.old/src/word.c unrtf-0.21.2/src/word.c +word_string (const struct ConversionContext *cc, Word *w) { + char *str; + CHECK_PARAM_NOT_NULL(w); ++ + if (w->hash_index) str = hash_get_string (cc, w->hash_index); + else str = NULL; ++ + return str; } -@@ -108,24 +105,22 @@ word_string (Word *w) { +@@ -108,24 +107,22 @@ word_string (Word *w) { *=======================================================================*/ Word * @@ -11297,7 +11310,7 @@ diff -durpN unrtf-0.21.2.old/src/word.c unrtf-0.21.2/src/word.c /*======================================================================== * Name: word_free * Purpose: Deallocates a Word object. This is only called at the end of -@@ -135,20 +130,20 @@ word_new (char *str) { +@@ -135,20 +132,20 @@ word_new (char *str) { *=======================================================================*/ void word_free (Word *w) { @@ -11329,7 +11342,7 @@ diff -durpN unrtf-0.21.2.old/src/word.c unrtf-0.21.2/src/word.c } -@@ -165,14 +160,14 @@ void word_free (Word *w) { +@@ -165,14 +162,14 @@ void word_free (Word *w) { static void print_indentation (int level) { @@ -11351,7 +11364,7 @@ diff -durpN unrtf-0.21.2.old/src/word.c unrtf-0.21.2/src/word.c } -@@ -186,33 +181,33 @@ print_indentation (int level) +@@ -186,33 +183,33 @@ print_indentation (int level) *=======================================================================*/ void @@ -11407,7 +11420,7 @@ diff -durpN unrtf-0.21.2.old/src/word.c unrtf-0.21.2/src/word.c } #if 1 /* AK6 - AF */ -@@ -223,56 +218,56 @@ word_dump (Word *w) +@@ -223,56 +220,56 @@ word_dump (Word *w) * Returns: Optimized word. *=======================================================================*/ Word * @@ -11507,7 +11520,7 @@ diff -durpN unrtf-0.21.2.old/src/word.c unrtf-0.21.2/src/word.c diff -durpN unrtf-0.21.2.old/src/word.h unrtf-0.21.2/src/word.h --- unrtf-0.21.2.old/src/word.h 2010-07-03 22:30:58.000000000 -0400 -+++ unrtf-0.21.2/src/word.h 2011-11-09 15:48:30.002798270 -0500 ++++ unrtf-0.21.2/src/word.h 2011-11-09 15:53:21.814783744 -0500 @@ -41,14 +41,15 @@ typedef struct _w { struct _w * child; } Word; diff --git a/SoObjects/Appointments/SOGoAppointmentFolder.h b/SoObjects/Appointments/SOGoAppointmentFolder.h index 2ad6ba6b0..73ba92330 100644 --- a/SoObjects/Appointments/SOGoAppointmentFolder.h +++ b/SoObjects/Appointments/SOGoAppointmentFolder.h @@ -140,6 +140,8 @@ typedef enum { /* bulk fetches */ +- (NSString *) aclSQLListingFilter; + - (NSString *) roleForComponentsWithAccessClass: (iCalAccessClass) accessClass forUser: (NSString *) uid; diff --git a/Version b/Version index a1ff82509..09503ebca 100644 --- a/Version +++ b/Version @@ -2,6 +2,6 @@ # This file is included by library makefiles to set the version information # of the executable. -MAJOR_VERSION=1 -MINOR_VERSION=3 -SUBMINOR_VERSION=11 +MAJOR_VERSION=2 +MINOR_VERSION=0 +SUBMINOR_VERSION=0