Exemplo n.º 1
0
 /**
  * Constructor
  *
  * @param mapisession       $session
  * @param mapistore         $store
  * @param string             (opt)
  *
  * @access public
  * @throws StatusException
  */
 public function ExportChangesICS($session, $store, $folderid = false)
 {
     // Open a hierarchy or a contents exporter depending on whether a folderid was specified
     $this->session = $session;
     $this->folderid = $folderid;
     $this->store = $store;
     $this->restriction = false;
     try {
         if ($folderid) {
             $entryid = mapi_msgstore_entryidfromsourcekey($store, $folderid);
         } else {
             $storeprops = mapi_getprops($this->store, array(PR_IPM_SUBTREE_ENTRYID));
             $entryid = $storeprops[PR_IPM_SUBTREE_ENTRYID];
         }
         $folder = false;
         if ($entryid) {
             $folder = mapi_msgstore_openentry($this->store, $entryid);
         }
         // Get the actual ICS exporter
         if ($folderid) {
             if ($folder) {
                 $this->exporter = mapi_openproperty($folder, PR_CONTENTS_SYNCHRONIZER, IID_IExchangeExportChanges, 0, 0);
             } else {
                 $this->exporter = false;
             }
         } else {
             $this->exporter = mapi_openproperty($folder, PR_HIERARCHY_SYNCHRONIZER, IID_IExchangeExportChanges, 0, 0);
         }
     } catch (MAPIException $me) {
         $this->exporter = false;
         // We return the general error SYNC_FSSTATUS_CODEUNKNOWN (12) which is also SYNC_STATUS_FOLDERHIERARCHYCHANGED (12)
         // if this happened while doing content sync, the mobile will try to resync the folderhierarchy
         throw new StatusException(sprintf("ExportChangesICS('%s','%s','%s'): Error, unable to open folder: 0x%X", $session, $store, Utils::PrintAsString($folderid), mapi_last_hresult()), SYNC_FSSTATUS_CODEUNKNOWN);
     }
 }
Exemplo n.º 2
0
 /**
  * Imports a folder deletion
  *
  * @param string        $id
  * @param string        $parent id is ignored in ICS
  *
  * @access public
  * @return int          SYNC_FOLDERHIERARCHY_STATUS
  * @throws StatusException
  */
 public function ImportFolderDeletion($id, $parent = false)
 {
     ZLog::Write(LOGLEVEL_DEBUG, sprintf("ImportChangesICS->ImportFolderDeletion('%s','%s'): importing folder deletetion", $id, $parent));
     $folderentryid = mapi_msgstore_entryidfromsourcekey($this->store, hex2bin($id));
     if (!$folderentryid) {
         throw new StatusException(sprintf("ImportChangesICS->ImportFolderDeletion('%s','%s'): Error, unable to resolve folder", $id, $parent, mapi_last_hresult()), SYNC_FSSTATUS_FOLDERDOESNOTEXIST);
     }
     // get the folder type from the MAPIProvider
     $type = $this->mapiprovider->GetFolderType($folderentryid);
     if (Utils::IsSystemFolder($type)) {
         throw new StatusException(sprintf("ImportChangesICS->ImportFolderDeletion('%s','%s'): Error deleting system/default folder", $id, $parent), SYNC_FSSTATUS_SYSTEMFOLDER);
     }
     $ret = mapi_importhierarchychanges_importfolderdeletion($this->importer, 0, array(PR_SOURCE_KEY => hex2bin($id)));
     if (!$ret) {
         throw new StatusException(sprintf("ImportChangesICS->ImportFolderDeletion('%s','%s'): Error deleting folder: 0x%X", $id, $parent, mapi_last_hresult()), SYNC_FSSTATUS_SERVERERROR);
     }
     return $ret;
 }
Exemplo n.º 3
0
 private function hasSecretaryACLs($store, $folderid)
 {
     $entryid = mapi_msgstore_entryidfromsourcekey($store, hex2bin($folderid));
     if (!$entryid) {
         return false;
     }
     $folder = mapi_msgstore_openentry($store, $entryid);
     if (!$folder) {
         return false;
     }
     $props = mapi_getprops($folder, array(PR_RIGHTS));
     if (isset($props[PR_RIGHTS]) && $props[PR_RIGHTS] & ecRightsReadAny && $props[PR_RIGHTS] & ecRightsCreate && $props[PR_RIGHTS] & ecRightsEditOwned && $props[PR_RIGHTS] & ecRightsDeleteOwned && $props[PR_RIGHTS] & ecRightsEditAny && $props[PR_RIGHTS] & ecRightsDeleteAny && $props[PR_RIGHTS] & ecRightsFolderVisible) {
         return true;
     }
     return false;
 }
Exemplo n.º 4
0
 function MeetingResponse($requestid, $folderid, $response, &$calendarid)
 {
     // Use standard meeting response code to process meeting request
     $reqentryid = mapi_msgstore_entryidfromsourcekey($this->_defaultstore, hex2bin($folderid), hex2bin($requestid));
     $mapimessage = mapi_msgstore_openentry($this->_defaultstore, $reqentryid);
     if (!$mapimessage) {
         debugLog("Unable to open request message for response");
         return false;
     }
     $meetingrequest = new Meetingrequest($this->_defaultstore, $mapimessage);
     if (!$meetingrequest->isMeetingRequest()) {
         debugLog("Attempt to respond to non-meeting request");
         return false;
     }
     if ($meetingrequest->isLocalOrganiser()) {
         debugLog("Attempt to response to meeting request that we organized");
         return false;
     }
     // Process the meeting response. We don't have to send the actual meeting response
     // e-mail, because the device will send it itself.
     switch ($response) {
         case 1:
             // accept
         // accept
         default:
             $entryid = $meetingrequest->doAccept(false, false, false, false, false, false, true);
             // last true is the $userAction
             break;
         case 2:
             // tentative
             $entryid = $meetingrequest->doAccept(true, false, false, false, false, false, true);
             // last true is the $userAction
             break;
         case 3:
             // decline
             $meetingrequest->doDecline(false);
             break;
     }
     // F/B will be updated on logoff
     // We have to return the ID of the new calendar item, so do that here
     if (isset($entryid)) {
         $newitem = mapi_msgstore_openentry($this->_defaultstore, $entryid);
         $newprops = mapi_getprops($newitem, array(PR_SOURCE_KEY));
         $calendarid = bin2hex($newprops[PR_SOURCE_KEY]);
     }
     // on recurring items, the MeetingRequest class responds with a wrong entryid
     if ($requestid == $calendarid) {
         debugLog("returned calender id is the same as the requestid - re-searching");
         $goidprop = GetPropIDFromString($this->_defaultstore, "PT_BINARY:{6ED8DA90-450B-101B-98DA-00AA003F1305}:0x3");
         $messageprops = mapi_getprops($mapimessage, array($goidprop, PR_OWNER_APPT_ID));
         $goid = $messageprops[$goidprop];
         if (isset($messageprops[PR_OWNER_APPT_ID])) {
             $apptid = $messageprops[PR_OWNER_APPT_ID];
         } else {
             $apptid = false;
         }
         //findCalendarItems signature was changed in 6.40.8, Mantis #485
         $items = checkMapiExtVersion("6.40.8") ? $meetingrequest->findCalendarItems($goid) : $meetingrequest->findCalendarItems($goid, $apptid);
         if (is_array($items)) {
             $newitem = mapi_msgstore_openentry($this->_defaultstore, $items[0]);
             $newprops = mapi_getprops($newitem, array(PR_SOURCE_KEY));
             $calendarid = bin2hex($newprops[PR_SOURCE_KEY]);
             debugLog("found other calendar entryid");
         }
     }
     // delete meeting request from Inbox
     $folderentryid = mapi_msgstore_entryidfromsourcekey($this->_defaultstore, hex2bin($folderid));
     $folder = mapi_msgstore_openentry($this->_defaultstore, $folderentryid);
     mapi_folder_deletemessages($folder, array($reqentryid), 0);
     return true;
 }
Exemplo n.º 5
0
 /**
  * Imports a single message
  *
  * @param array         $props
  * @param long          $flags
  * @param object        $retmapimessage
  *
  * @access public
  * @return long
  */
 public function ImportMessageChange($props, $flags, &$retmapimessage)
 {
     $sourcekey = $props[PR_SOURCE_KEY];
     $parentsourcekey = $props[PR_PARENT_SOURCE_KEY];
     $entryid = mapi_msgstore_entryidfromsourcekey($this->store, $parentsourcekey, $sourcekey);
     if (!$entryid) {
         return SYNC_E_IGNORE;
     }
     $mapimessage = mapi_msgstore_openentry($this->store, $entryid);
     try {
         $message = $this->mapiprovider->GetMessage($mapimessage, $this->contentparameters);
     } catch (SyncObjectBrokenException $mbe) {
         $brokenSO = $mbe->GetSyncObject();
         if (!$brokenSO) {
             ZLog::Write(LOGLEVEL_ERROR, sprintf("PHPWrapper->ImportMessageChange(): Catched SyncObjectBrokenException but broken SyncObject available"));
         } else {
             if (!isset($brokenSO->id)) {
                 $brokenSO->id = "Unknown ID";
                 ZLog::Write(LOGLEVEL_ERROR, sprintf("PHPWrapper->ImportMessageChange(): Catched SyncObjectBrokenException but no ID of object set"));
             }
             ZPush::GetDeviceManager()->AnnounceIgnoredMessage(false, $brokenSO->id, $brokenSO);
         }
         // tell MAPI to ignore the message
         return SYNC_E_IGNORE;
     }
     // substitute the MAPI SYNC_NEW_MESSAGE flag by a z-push proprietary flag
     if ($flags == SYNC_NEW_MESSAGE) {
         $message->flags = SYNC_NEWMESSAGE;
     } else {
         $message->flags = $flags;
     }
     $this->importer->ImportMessageChange(bin2hex($sourcekey), $message);
     // Tell MAPI it doesn't need to do anything itself, as we've done all the work already.
     return SYNC_E_IGNORE;
 }
Exemplo n.º 6
0
 /**
  * Returns categories for a message.
  *
  * @param binary $parentsourcekey
  * @param binary $sourcekey
  *
  * @access public
  * @return array or false on failure
  */
 public function GetMessageCategories($parentsourcekey, $sourcekey)
 {
     $entryid = mapi_msgstore_entryidfromsourcekey($this->store, $parentsourcekey, $sourcekey);
     if (!$entryid) {
         ZLog::Write(LOGLEVEL_INFO, sprintf("MAPIProvider->GetMessageCategories(): Couldn't retrieve message, sourcekey: '%s', parentsourcekey: '%s'", bin2hex($sourcekey), bin2hex($parentsourcekey)));
         return false;
     }
     $mapimessage = mapi_msgstore_openentry($this->store, $entryid);
     $emailMapping = MAPIMapping::GetEmailMapping();
     $emailMapping = array("categories" => $emailMapping["categories"]);
     $messageCategories = $this->getProps($mapimessage, $emailMapping);
     if (isset($messageCategories[$emailMapping["categories"]]) && is_array($messageCategories[$emailMapping["categories"]])) {
         return $messageCategories[$emailMapping["categories"]];
     }
     return false;
 }
Exemplo n.º 7
0
 function MeetingResponse($requestid, $folderid, $response, &$calendarid)
 {
     // Use standard meeting response code to process meeting request
     $entryid = mapi_msgstore_entryidfromsourcekey($this->_defaultstore, hex2bin($folderid), hex2bin($requestid));
     $mapimessage = mapi_msgstore_openentry($this->_defaultstore, $entryid);
     if (!$mapimessage) {
         debugLog("Unable to open request message for response");
         return false;
     }
     $meetingrequest = new Meetingrequest($this->_defaultstore, $mapimessage);
     if (!$meetingrequest->isMeetingRequest()) {
         debugLog("Attempt to respond to non-meeting request");
         return false;
     }
     if ($meetingrequest->isLocalOrganiser()) {
         debugLog("Attempt to response to meeting request that we organized");
         return false;
     }
     // Process the meeting response. We don't have to send the actual meeting response
     // e-mail, because the device will send it itself.
     switch ($response) {
         case 1:
             // accept
         // accept
         default:
             $entryid = $meetingrequest->doAccept(false, false, $meetingrequest->isInCalendar());
             break;
         case 2:
             // tentative
             $meetingrequest->doAccept(true, false, $meetingrequest->isInCalendar());
             break;
         case 3:
             // decline
             $meetingrequest->doDecline(false);
             break;
     }
     // Update F/B
     $root = mapi_msgstore_openentry($this->_defaultstore);
     $rootprops = mapi_getprops($root, array(PR_IPM_APPOINTMENT_ENTRYID));
     $calendar = mapi_msgstore_openentry($this->_defaultstore, $rootprops[PR_IPM_APPOINTMENT_ENTRYID]);
     $storeprops = mapi_getprops($this->_defaultstore, array(PR_USER_ENTRYID));
     $pub = new FreeBusyPublish($this->_session, $this->_defaultstore, $calendar, $storeprops[PR_USER_ENTRYID]);
     $pub->publishFB(time() - 7 * 24 * 60 * 60, 6 * 30 * 24 * 60 * 60);
     // publish from one week ago, 6 months ahead
     // We have to return the ID of the new calendar item, so do that here
     $newitem = mapi_msgstore_openentry($this->_defaultstore, $entryid);
     $newprops = mapi_getprops($newitem, array(PR_SOURCE_KEY));
     $calendarid = bin2hex($newprops[PR_SOURCE_KEY]);
     return true;
 }
Exemplo n.º 8
0
 function MeetingResponse($requestid, $folderid, $response, &$calendarid)
 {
     // Use standard meeting response code to process meeting request
     $reqentryid = mapi_msgstore_entryidfromsourcekey($this->_defaultstore, hex2bin($folderid), hex2bin($requestid));
     $mapimessage = mapi_msgstore_openentry($this->_defaultstore, $reqentryid);
     if (!$mapimessage) {
         debugLog("Unable to open request message for response");
         return false;
     }
     $meetingrequest = new Meetingrequest($this->_defaultstore, $mapimessage);
     if (!$meetingrequest->isMeetingRequest()) {
         debugLog("Attempt to respond to non-meeting request");
         return false;
     }
     if ($meetingrequest->isLocalOrganiser()) {
         debugLog("Attempt to response to meeting request that we organized");
         return false;
     }
     // Process the meeting response. We don't have to send the actual meeting response
     // e-mail, because the device will send it itself.
     switch ($response) {
         case 1:
             // accept
         // accept
         default:
             $entryid = $meetingrequest->doAccept(false, false, false, false, false, false, true);
             // last true is the $userAction
             break;
         case 2:
             // tentative
             $entryid = $meetingrequest->doAccept(true, false, false, false, false, false, true);
             // last true is the $userAction
             break;
         case 3:
             // decline
             $meetingrequest->doDecline(false);
             break;
     }
     // F/B will be updated on logoff
     // We have to return the ID of the new calendar item, so do that here
     $newitem = mapi_msgstore_openentry($this->_defaultstore, $entryid);
     $newprops = mapi_getprops($newitem, array(PR_SOURCE_KEY));
     $calendarid = bin2hex($newprops[PR_SOURCE_KEY]);
     // delete meeting request from Inbox
     $folderentryid = mapi_msgstore_entryidfromsourcekey($this->_defaultstore, hex2bin($folderid));
     $folder = mapi_msgstore_openentry($this->_defaultstore, $folderentryid);
     mapi_folder_deletemessages($folder, array($reqentryid), 0);
     return true;
 }
Exemplo n.º 9
0
 private function getMessage($id, $announceErrors = true)
 {
     if (!$id) {
         return false;
     }
     $message = false;
     list($fsk, $sk) = Utils::SplitMessageId($id);
     $sourcekey = hex2bin($sk);
     $parentsourcekey = hex2bin(ZPush::GetDeviceManager()->GetBackendIdForFolderId($fsk));
     // Backwards compatibility for old style folder ids
     if (empty($parentsourcekey)) {
         $parentsourcekey = $this->folderid;
     }
     $entryid = mapi_msgstore_entryidfromsourcekey($this->store, $parentsourcekey, $sourcekey);
     if (!$entryid) {
         ZLog::Write(LOGLEVEL_INFO, sprintf("ReplyBackImExporter->getMessage(): Couldn't retrieve message from MAPIProvider, sourcekey: '%s', parentsourcekey: '%s'", bin2hex($sourcekey), bin2hex($parentsourcekey), bin2hex($entryid)));
         return false;
     }
     $mapimessage = mapi_msgstore_openentry($this->store, $entryid);
     try {
         ZLog::Write(LOGLEVEL_DEBUG, sprintf("ReplyBackImExporter->getMessage(): Getting message from MAPIProvider, sourcekey: '%s', parentsourcekey: '%s', entryid: '%s'", bin2hex($sourcekey), bin2hex($parentsourcekey), bin2hex($entryid)));
         $message = $this->mapiprovider->GetMessage($mapimessage, $this->contentparameters);
     } catch (SyncObjectBrokenException $mbe) {
         if ($announceErrors) {
             $brokenSO = $mbe->GetSyncObject();
             if (!$brokenSO) {
                 ZLog::Write(LOGLEVEL_ERROR, sprintf("ReplyBackImExporter->getMessage(): Catched SyncObjectBrokenException but broken SyncObject available"));
             } else {
                 if (!isset($brokenSO->id)) {
                     $brokenSO->id = "Unknown ID";
                     ZLog::Write(LOGLEVEL_ERROR, sprintf("ReplyBackImExporter->getMessage(): Catched SyncObjectBrokenException but no ID of object set"));
                 }
                 ZPush::GetDeviceManager()->AnnounceIgnoredMessage(false, $brokenSO->id, $brokenSO);
             }
             return false;
         }
     }
     return $message;
 }
Exemplo n.º 10
0
 /**
  * Imports a single folder change
  *
  * @param mixed         $props     sourcekey of the changed folder
  *
  * @access public
  * @return
  */
 function ImportFolderChange($props)
 {
     $sourcekey = $props[PR_SOURCE_KEY];
     $entryid = mapi_msgstore_entryidfromsourcekey($this->store, $sourcekey);
     $mapifolder = mapi_msgstore_openentry($this->store, $entryid);
     $folder = $this->mapiprovider->GetFolder($mapifolder);
     // do not import folder if there is something "wrong" with it
     if ($folder === false) {
         return 0;
     }
     $this->importer->ImportFolderChange($folder);
     return 0;
 }
Exemplo n.º 11
0
 /**
  * Opens a folder.
  *
  * @param ressource $store
  * @param string    $folderid
  *
  * @access private
  * @return ressource
  */
 private function getFolder($store, $folderid)
 {
     if (!isset($this->folderCache[$folderid])) {
         $folderentryid = mapi_msgstore_entryidfromsourcekey($store, hex2bin($folderid));
         if (!$folderentryid) {
             $this->Terminate(sprintf("Kopano->getFolder(): Error, unable to open folder (no entry id): 0x%08X", mapi_last_hresult()));
         }
         $this->folderCache[$folderid] = mapi_msgstore_openentry($store, $folderentryid);
     }
     return $this->folderCache[$folderid];
 }
Exemplo n.º 12
0
 /**
  * Checks if the logged in user has read permissions on a folder.
  *
  * @param ressource $store
  * @param string $folderid
  *
  * @access public
  * @return boolean
  */
 public function HasReadACLs($store, $folderid)
 {
     $entryid = mapi_msgstore_entryidfromsourcekey($store, hex2bin($folderid));
     if (!$entryid) {
         ZLog::Write(LOGLEVEL_WARN, sprintf("KopanoBackend->HasReadACLs(): error, no entryid resolved for %s on store %s", $folderid, $store));
         return false;
     }
     $folder = mapi_msgstore_openentry($store, $entryid);
     if (!$folder) {
         ZLog::Write(LOGLEVEL_WARN, sprintf("KopanoBackend->HasReadACLs(): error, could not open folder with entryid %s on store %s", bin2hex($entryid), $store));
         return false;
     }
     $props = mapi_getprops($folder, array(PR_RIGHTS));
     if (isset($props[PR_RIGHTS]) && $props[PR_RIGHTS] & ecRightsReadAny) {
         return true;
     }
     return false;
 }