Commit 5bff42fe authored by Sebastian Kummer's avatar Sebastian Kummer

Merge pull request #428 in ZP/z-push from develop to release/2.3

* commit '04a25dda':
  ZP-1103 redirect error output of 'hash git' to /dev/null.
  ZP-916 Undo removal of SYSTEM check.
  ZP-916 Only define constants if they are not defined yet.
  ZP-916 Log message when account is hidden.
  ZP-1098 Use native body type algorithm to set native body type if it is undefined for appointments.
  ZP-972 Fixed @access.
  ZP-1102 Add folder origin constants to the allowed characters in the incoming data filter.
  ZP-916 Remove space in PR_EC_AB_HIDDEN constant name, check if value isset().
  ZP-1101 Log query string.
  ZP-972 Implement ZLog::SpecialLogUser() to be called before authentication is completed to force the generation of a user log, fixed method descriptions, use Log::unauthMessageCache for all unauthenticated users, fixed ZLog dependency in PrintWBXML, removed ZLog::RequestHeaders(), removed ZLog::SetSpecialLogUsers(), removed ZLog::EnableDeviceLog().
  ZP-1098 Set native body type to plain if it is undefined for appointments.
  replace deprecated mapi_openpropertytostream
  ZP-1094 Remove the use of spl_autoload for backend inclusion. Released under the Affero GNU General Public License (AGPL) version 3.
  ZP-916 Query and check for PR_EC_AB_HIDDEN.
  ZP-972 Add request header also to device specific log, by moving it from index.php to protected method ZLog::RequestHeader and calling it from ZLog::Initialise and ZLog::EnableDeviceLog.
  ZP-972 Use deviceid and authuser from Logger in zlog instead of getting them from Request. Renamed setLogToUserFile to SetLogToUserFile and added it as public to the abstract Log class. Renamed WbxmlDebug to IsWbxmlDebugEnabled. Fixed typos in function descriptions. Replaced tabs with spaces.
  ZP-972 fix WBXML is not logged for LOGUSERLEVEL >= LOGLEVEL_WBXML, if LOGLEVEL < LOGLEVEL_WBXML and $specialLogUsers is not already defined in config.php, because enabled on runtime via ZLog::EnableDeviceLog() or ZLog::setSpecialLogUsers().
  ZP-972 allow backends to enable device or user specific logging.
parents 5225982b 04a25dda
......@@ -730,7 +730,7 @@ class BackendKopano implements IBackend, ISearchProvider {
$attachment->contenttype = "message/rfc822";
}
else
$stream = mapi_openpropertytostream($attach, PR_ATTACH_DATA_BIN);
$stream = mapi_openproperty($attach, PR_ATTACH_DATA_BIN, IID_IStream, 0, 0);
if(!$stream)
throw new StatusException(sprintf("KopanoBackend->GetAttachmentData('%s'): Error, unable to open attachment data stream: 0x%X", $attname, mapi_last_hresult()), SYNC_ITEMOPERATIONSSTATUS_INVALIDATT);
......
......@@ -304,7 +304,7 @@
if (!empty($msgbody) && strrpos($msgbody, $separator) === false) {
$msgbody = $separator . $msgbody;
$stream = mapi_openpropertytostream($this->message, PR_BODY, MAPI_CREATE | MAPI_MODIFY);
$stream = mapi_openproperty($this->message, PR_BODY, IID_IStream, 0, MAPI_CREATE | MAPI_MODIFY);
mapi_stream_setsize($stream, strlen($msgbody));
mapi_stream_write($stream, $msgbody);
mapi_stream_commit($stream);
......
......@@ -313,7 +313,7 @@
// Set Body
$body = $this->getBody();
$stream = mapi_openpropertytostream($outgoing, PR_BODY, MAPI_CREATE | MAPI_MODIFY);
$stream = mapi_openproperty($outgoing, PR_BODY, IID_IStream, 0, MAPI_MODIFY | MAPI_CREATE);
mapi_stream_setsize($stream, strlen($body));
mapi_stream_write($stream, $body);
mapi_stream_commit($stream);
......@@ -487,7 +487,7 @@
$this->setRecipientsForResponse($outgoing, tdmtTaskUpd, true);
$body = $this->getBody();
$stream = mapi_openpropertytostream($outgoing, PR_BODY, MAPI_CREATE | MAPI_MODIFY);
$stream = mapi_openproperty($outgoing, PR_BODY, IID_IStream, 0, MAPI_CREATE | MAPI_MODIFY);
mapi_stream_setsize($stream, strlen($body));
mapi_stream_write($stream, $body);
mapi_stream_commit($stream);
......@@ -633,7 +633,7 @@
// Set Body
$body = $this->getBody();
$stream = mapi_openpropertytostream($outgoing, PR_BODY, MAPI_CREATE | MAPI_MODIFY);
$stream = mapi_openproperty($outgoing, PR_BODY, IID_IStream, 0, MAPI_CREATE | MAPI_MODIFY);
mapi_stream_setsize($stream, strlen($body));
mapi_stream_write($stream, $body);
mapi_stream_commit($stream);
......
......@@ -312,7 +312,14 @@ class MAPIProvider {
}
if (!isset($message->nativebodytype)) $message->nativebodytype = $this->getNativeBodyType($messageprops);
if (!isset($message->nativebodytype)) {
$message->nativebodytype = $this->getNativeBodyType($messageprops);
}
elseif ($message->nativebodytype == SYNC_BODYPREFERENCE_UNDEFINED) {
$nbt = $this->getNativeBodyType($messageprops);
ZLog::Write(LOGLEVEL_INFO, sprintf("MAPIProvider->getAppointment(): native body type is undefined. Set it to %d.", $nbt));
$message->nativebodytype = $nbt;
}
// If the user is working from a location other than the office the busystatus should be interpreted as free.
if (isset($message->busystatus) && $message->busystatus == fbWorkingElsewhere) {
......@@ -733,7 +740,7 @@ class MAPIProvider {
}
// android devices require attachment size in order to display an attachment properly
if (!isset($attachprops[PR_ATTACH_SIZE])) {
$stream = mapi_openpropertytostream($mapiattach, PR_ATTACH_DATA_BIN);
$stream = mapi_openproperty($mapiattach, PR_ATTACH_DATA_BIN, IID_IStream, 0, 0);
// It's not possible to open some (embedded only?) messages, so we need to open the attachment object itself to get the data
if (mapi_last_hresult()) {
$embMessage = mapi_attach_openobj($mapiattach);
......
......@@ -37,6 +37,7 @@ class DeviceManager {
const FLD_SYNC_INPROGRESS = 2;
const FLD_SYNC_COMPLETED = 4;
// new types need to be added to Request::HEX_EXTENDED2 filter
const FLD_ORIGIN_USER = "U";
const FLD_ORIGIN_CONFIG = "C";
const FLD_ORIGIN_SHARED = "S";
......
......@@ -33,14 +33,12 @@ class ZLog {
static private $logger = null;
/**
* Initializes the logging
* Initializes the logging.
*
* @access public
* @return boolean
*/
static public function Initialize() {
$logger = self::getLogger();
// define some constants for the logging
if (!defined('LOGUSERLEVEL'))
define('LOGUSERLEVEL', LOGLEVEL_OFF);
......@@ -48,26 +46,30 @@ class ZLog {
if (!defined('LOGLEVEL'))
define('LOGLEVEL', LOGLEVEL_OFF);
if (!defined('WBXML_DEBUG')) {
// define the WBXML_DEBUG mode on user basis depending on the configurations
if (LOGLEVEL >= LOGLEVEL_WBXML || (LOGUSERLEVEL >= LOGLEVEL_WBXML && $logger->HasSpecialLogUsers()))
define('WBXML_DEBUG', true);
else
define('WBXML_DEBUG', false);
}
$logger = self::getLogger();
return true;
}
/**
* Writes a log line
* Check if WBXML logging is enabled in current LOG(USER)LEVEL.
*
* @access public
* @return boolean
*/
static public function IsWbxmlDebugEnabled() {
return LOGLEVEL >= LOGLEVEL_WBXML || (LOGUSERLEVEL >= LOGLEVEL_WBXML && self::getLogger()->HasSpecialLogUsers());
}
/**
* Writes a log line.
*
* @param int $loglevel one of the defined LOGLEVELS
* @param string $message
* @param boolean $truncate indicate if the message should be truncated, default true
*
* @access public
* @return
* @return void
*/
static public function Write($loglevel, $message, $truncate = true) {
// truncate messages longer than 10 KB
......@@ -91,7 +93,7 @@ class ZLog {
}
/**
* Returns logged information about the WBXML stack
* Returns logged information about the WBXML stack.
*
* @access public
* @return string
......@@ -101,7 +103,7 @@ class ZLog {
}
/**
* Returns the last message logged for a log level
* Returns the last message logged for a log level.
*
* @param int $loglevel one of the defined LOGLEVELS
*
......@@ -112,6 +114,19 @@ class ZLog {
return (isset(self::$lastLogs[$loglevel]))?self::$lastLogs[$loglevel]:false;
}
/**
* If called, the authenticated current user gets an extra log-file.
*
* If called until the user is authenticated (e.g. at the end of IBackend->Logon()) all log
* messages that happened until this point will also be logged.
*
* @access public
* @return void
*/
static public function SpecialLogUser() {
self::getLogger()->SpecialLogUser();
}
/**
* Returns the logger object. If no logger has been initialized, FileLog will be initialized and returned.
*
......@@ -153,9 +168,6 @@ class ZLog {
* Legacy debug stuff
*/
// E_DEPRECATED only available since PHP 5.3.0
if (!defined('E_DEPRECATED')) define(E_DEPRECATED, 8192);
// TODO review error handler
function zpush_error_handler($errno, $errstr, $errfile, $errline, $errcontext) {
if (defined('LOG_ERROR_MASK')) $errno &= LOG_ERROR_MASK;
......
......@@ -564,7 +564,6 @@ class ZPush {
static public function GetBackend() {
// if the backend is not yet loaded, load backend drivers and instantiate it
if (!isset(ZPush::$backend)) {
$isIbar = false;
// Initialize our backend
$ourBackend = @constant('BACKEND_PROVIDER');
......@@ -582,20 +581,13 @@ class ZPush {
throw new FatalMisconfigurationException("No Backend provider can be found. Check your installation and/or configuration!");
}
elseif (!class_exists($ourBackend)) {
spl_autoload_register('\ZPush::IncludeBackend');
$isIbar = true;
ZLog::Write(LOGLEVEL_DEBUG, "ZPush::GetBackend(): autoload register ZPush::IncludeBackend");
\ZPush::IncludeBackend($ourBackend);
}
if (class_exists($ourBackend))
ZPush::$backend = new $ourBackend();
else
throw new FatalMisconfigurationException(sprintf("Backend provider '%s' can not be loaded. Check configuration!", $ourBackend));
if ($isIbar) {
spl_autoload_unregister('\ZPush::IncludeBackend');
ZLog::Write(LOGLEVEL_DEBUG, "ZPush::GetBackend(): autoload unregister ZPush::IncludeBackend");
}
}
return ZPush::$backend;
}
......
......@@ -22,6 +22,7 @@
*
* Consult LICENSE file for details
************************************************/
class FileLog extends Log {
/**
......@@ -29,6 +30,12 @@ class FileLog extends Log {
*/
private $log_to_user_file = false;
/**
* Constructor
*/
public function __construct() {
}
/**
* Get the log user file.
*
......@@ -43,17 +50,19 @@ class FileLog extends Log {
}
/**
* Set user log-file relative to log directory.
*
* @param string $value
*
* @access private
* @return void
*/
private function setLogToUserFile($value) {
$this->log_to_user_file = $value;
}
public function __construct() {
}
/**
* Returns the string to be logged
* Returns the string to be logged.
*
* @param int $loglevel
* @param string $message
......@@ -74,6 +83,15 @@ class FileLog extends Log {
// Implementation of Log
//
/**
* Writes a log message to the general log.
*
* @param int $loglevel
* @param string $message
*
* @access protected
* @return void
*/
protected function Write($loglevel, $message) {
$data = $this->buildLogString($loglevel, $message) . PHP_EOL;
@file_put_contents(LOGFILE, $data, FILE_APPEND);
......@@ -83,11 +101,26 @@ class FileLog extends Log {
}
}
/**
* Writes a log message to the user specific log.
* @param int $loglevel
* @param string $message
*
* @access public
* @return void
*/
public function WriteForUser($loglevel, $message) {
$data = $this->buildLogString($loglevel, $message) . PHP_EOL;
@file_put_contents(LOGFILEDIR . $this->getLogToUserFile(), $data, FILE_APPEND);
}
/**
* This function is used as an event for log implementer.
* It happens when the a call to the Log function is finished.
*
* @access protected
* @return void
*/
protected function afterLog($loglevel, $message) {
if (($loglevel & LOGLEVEL_FATAL) || ($loglevel & LOGLEVEL_ERROR)) {
$data = $this->buildLogString($loglevel, $message) . PHP_EOL;
......
......@@ -68,6 +68,14 @@ abstract class Log {
private $unauthMessageCache = array();
/**
* Constructor
*/
public function __construct() {
}
/**
* Returns the current user.
*
* @access public
* @return string
*/
......@@ -76,15 +84,20 @@ abstract class Log {
}
/**
* Sets the current user.
*
* @param string $value
*
* @access public
* @return void
*/
public function SetUser($value) {
$this->user = $value;
}
/**
* Returns the current authenticated user.
*
* @access public
* @return string
*/
......@@ -93,9 +106,12 @@ abstract class Log {
}
/**
* Sets the current authenticated user.
*
* @param string $value
*
* @access public
* @return void
*/
public function SetAuthUser($value) {
$this->isAuthUserInSpecialLogUsers = false;
......@@ -122,6 +138,8 @@ abstract class Log {
}
/**
* Returns the current device id.
*
* @access public
* @return string
*/
......@@ -130,15 +148,20 @@ abstract class Log {
}
/**
* Sets the current device id.
*
* @param string $value
*
* @access public
* @return void
*/
public function SetDevid($value) {
$this->devid = $value;
}
/**
* Returns the current PID (as string).
*
* @access public
* @return string
*/
......@@ -147,15 +170,20 @@ abstract class Log {
}
/**
* Sets the current PID.
*
* @param string $value
*
* @access public
* @return void
*/
public function SetPidstr($value) {
$this->pidstr = $value;
}
/**
* Indicates if special log users are known.
*
* @access public
* @return bool True if we do have to log some specific user. False otherwise.
*/
......@@ -164,9 +192,11 @@ abstract class Log {
}
/**
* Indicates if the user is in the special log users.
*
* @param string $user
*
* @acces public
* @access public
* @return bool
*/
public function IsUserInSpecialLogUsers($user) {
......@@ -181,6 +211,8 @@ abstract class Log {
}
/**
* Returns the current special log users array.
*
* @access public
* @return array
*/
......@@ -189,29 +221,53 @@ abstract class Log {
}
/**
* Sets the current special log users array.
*
* @param array $value
*
* @access public
* @return void
*/
public function SetSpecialLogUsers(array $value) {
$this->isUserInSpecialLogUsers = array(); // reset cache
$this->specialLogUsers = $value;
}
public function __construct() {
/**
* If called, the current user should get an extra log-file.
*
* If called until the user is authenticated (e.g. at the end of IBackend->Logon()) all
* messages logged until then will also be logged in the user file.
*
* @access public
* @return void
*/
public function SpecialLogUser() {
$this->isAuthUserInSpecialLogUsers = true;
}
/**
* Logs a message with a given log level.
*
*
* @param int $loglevel
* @param string $message
*
* @access public
* @return void
*/
public function Log($loglevel, $message) {
if ($loglevel <= LOGLEVEL) {
$this->Write($loglevel, $message);
}
if ($loglevel <= LOGUSERLEVEL && $this->IsAuthUserInSpecialLogUsers()) {
if (RequestProcessor::isUserAuthenticated()) {
// something was logged before the user was authenticated, write this to the log
if ($loglevel <= LOGUSERLEVEL) {
// cache log messages for unauthenticated users
if (!RequestProcessor::isUserAuthenticated()) {
$this->unauthMessageCache[] = array($loglevel, $message);
}
// user is authenticated now
elseif ($this->IsAuthUserInSpecialLogUsers()) {
// something was logged before the user was authenticated and cached write it to the log
if (!empty($this->unauthMessageCache)) {
foreach ($this->unauthMessageCache as $authcache) {
$this->WriteForUser($authcache[0], $authcache[1]);
......@@ -231,6 +287,9 @@ abstract class Log {
/**
* This function is used as an event for log implementer.
* It happens when the ZLog static class is finished with the initialization of this instance.
*
* @access public
* @return void
*/
public function AfterInitialize() {
}
......@@ -238,6 +297,9 @@ abstract class Log {
/**
* This function is used as an event for log implementer.
* It happens when the a call to the Log function is finished.
*
* @access protected
* @return void
*/
protected function afterLog($loglevel, $message) {
}
......@@ -271,20 +333,23 @@ abstract class Log {
}
/**
* Writes a log message to the general log.
*
* @param int $loglevel
* @param string $message
*
* @access public
* @return null
* @access protected
* @return void
*/
abstract protected function Write($loglevel, $message);
/**
* Writes a log message to the user specific log.
* @param int $loglevel
* @param string $message
*
* @access public
* @return null
* @return void
*/
abstract public function WriteForUser($loglevel, $message);
}
\ No newline at end of file
......@@ -84,6 +84,14 @@ class Syslog extends Log {
}
}
/**
* Constructor.
* Sets configured values if no parameters are given.
*
* @param string $program_name
* @param string $host
* @param string $port
*/
public function __construct($program_name = null, $host = null, $port = null) {
parent::__construct();
......@@ -104,7 +112,6 @@ class Syslog extends Log {
* @return string
*/
protected function GenerateProgramName() {
// @TODO Use another mechanism than debug_backtrace to determine to origin of the log
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
// Shift the "syslog.php" entry.
......@@ -166,11 +173,19 @@ class Syslog extends Log {
return $log;
}
//
// Implementation of Log
//
/**
* Writes a log message to the general log.
*
* @param int $loglevel
* @param string $message
*
* @access protected
* @return void
*/
protected function Write($loglevel, $message) {
if ($this->GetHost() && $this->GetPort()) {
$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
......@@ -191,6 +206,13 @@ class Syslog extends Log {
}
}
/**
* This function is used as an event for log implementer.
* It happens when the a call to the Log function is finished.
*
* @access public
* @return void
*/
public function WriteForUser($loglevel, $message) {
$this->Write(LOGLEVEL_DEBUG, $message); // Always pass the logleveldebug so it uses syslog level LOG_DEBUG
}
......
......@@ -37,6 +37,7 @@ class Request {
const NUMBERSDOT_ONLY = 5;
const HEX_EXTENDED = 6;
const ISO8601 = 7;
const HEX_EXTENDED2 = 8;
/**
* Command parameters for base64 encoded requests (AS >= 12.1)
......@@ -108,11 +109,11 @@ class Request {
if(isset($_GET["DeviceType"]))
self::$devtype = self::filterEvilInput($_GET["DeviceType"], self::LETTERS_ONLY);
if (isset($_GET["AttachmentName"]))
self::$attachmentName = self::filterEvilInput($_GET["AttachmentName"], self::HEX_EXTENDED);
self::$attachmentName = self::filterEvilInput($_GET["AttachmentName"], self::HEX_EXTENDED2);
if (isset($_GET["CollectionId"]))
self::$collectionId = self::filterEvilInput($_GET["CollectionId"], self::HEX_ONLY);
self::$collectionId = self::filterEvilInput($_GET["CollectionId"], self::HEX_EXTENDED2);
if (isset($_GET["ItemId"]))
self::$itemId = self::filterEvilInput($_GET["ItemId"], self::HEX_ONLY);
self::$itemId = self::filterEvilInput($_GET["ItemId"], self::HEX_EXTENDED2);
if (isset($_GET["SaveInSent"]) && $_GET["SaveInSent"] == "T")
self::$saveInSent = true;
......@@ -148,13 +149,13 @@ class Request {
self::$asProtocolVersion = self::filterEvilInput($query['ProtVer'], self::NUMBERS_ONLY) / 10;
if (isset($query[self::COMMANDPARAM_ATTACHMENTNAME]))
self::$attachmentName = self::filterEvilInput($query[self::COMMANDPARAM_ATTACHMENTNAME], self::HEX_EXTENDED);
self::$attachmentName = self::filterEvilInput($query[self::COMMANDPARAM_ATTACHMENTNAME], self::HEX_EXTENDED2);
if (isset($query[self::COMMANDPARAM_COLLECTIONID]))
self::$collectionId = self::filterEvilInput($query[self::COMMANDPARAM_COLLECTIONID], self::HEX_ONLY);
self::$collectionId = self::filterEvilInput($query[self::COMMANDPARAM_COLLECTIONID], self::HEX_EXTENDED2);
if (isset($query[self::COMMANDPARAM_ITEMID]))
self::$itemId = self::filterEvilInput($query[self::COMMANDPARAM_ITEMID], self::HEX_ONLY);
self::$itemId = self::filterEvilInput($query[self::COMMANDPARAM_ITEMID], self::HEX_EXTENDED2);
if (isset($query[self::COMMANDPARAM_OPTIONS]) && (ord($query[self::COMMANDPARAM_OPTIONS]) & self::COMMANDPARAM_OPTIONS_SAVEINSENT))
self::$saveInSent = true;
......@@ -669,6 +670,7 @@ class Request {
else if ($filter == self::NUMBERS_ONLY) $re = "/[^0-9]/";
else if ($filter == self::NUMBERSDOT_ONLY) $re = "/[^0-9\.]/";
else if ($filter == self::HEX_EXTENDED) $re = "/[^A-Fa-f0-9\:]/";
else if ($filter == self::HEX_EXTENDED2) $re = "/[^A-Fa-f0-9\:USG]/"; // Folder origin constants from DeviceManager::FLD_ORIGIN_* (C already hex)
else if ($filter == self::ISO8601) $re = "/[^\d{8}T\d{6}Z]/";
return ($re) ? preg_replace($re, $replacevalue, $input) : '';
......
......@@ -117,7 +117,7 @@ abstract class RequestProcessor {
}
// also log WBXML in happy case
if (@constant('WBXML_DEBUG') === true) {
if (ZLog::IsWbxmlDebugEnabled()) {
ZLog::Write(LOGLEVEL_WBXML, "WBXML-IN : ". Request::GetInputAsBase64(), false);
}
}
......
......@@ -580,6 +580,7 @@ class Utils {
* variable - value of the parameter
*
*/
ZLog::Write(LOGLEVEL_DEBUG, sprintf("Utils::DecodeBase64URI(): decoding base64 query string: %s", $query));
$decoded = base64_decode($query);
$devIdLength = ord($decoded[4]); //device ID length
$polKeyLength = ord($decoded[5+$devIdLength]); //policy key length
......
......@@ -85,7 +85,7 @@ class WBXMLDecoder extends WBXMLDefs {
* @access public
*/
public function __construct($input) {
$this->log = defined('WBXML_DEBUG') && WBXML_DEBUG;
$this->log = ZLog::IsWbxmlDebugEnabled();
$this->in = $input;
......
......@@ -44,7 +44,7 @@ class WBXMLEncoder extends WBXMLDefs {
private $bodyparts;
public function __construct($output, $multipart = false) {
$this->log = @constant('WBXML_DEBUG') === true;
$this->log = ZLog::IsWbxmlDebugEnabled();
$this->_out = $output;
......
......@@ -25,8 +25,8 @@
if (!defined("ZPUSH_VERSION")) {
$path = escapeshellarg(dirname(realpath($_SERVER['SCRIPT_FILENAME'])));
$branch = trim(exec("hash git && cd $path >/dev/null 2>&1 && git branch --no-color 2>/dev/null | sed -e '/^[^*]/d' -e \"s/* \(.*\)/\\1/\""));
$version = exec("hash git && cd $path >/dev/null 2>&1 && git describe --always &2>/dev/null");
$branch = trim(exec("hash git 2>/dev/null && cd $path >/dev/null 2>&1 && git branch --no-color 2>/dev/null | sed -e '/^[^*]/d' -e \"s/* \(.*\)/\\1/\""));
$version = exec("hash git 2>/dev/null && cd $path >/dev/null 2>&1 && git describe --always 2>/dev/null");
if ($branch && $version) {
define("ZPUSH_VERSION", $branch .'-'. $version);
}
......
......@@ -69,6 +69,10 @@ class ZLog {
}
}
}
static public function IsWbxmlDebugEnabled() {
return true;
}
}
// setup
......
......@@ -49,7 +49,12 @@ include_once('mapi/mapitags.php');
include_once('mapi/mapicode.php');
include_once('mapi/mapiguid.php');
define('PR_EMS_AB_THUMBNAIL_PHOTO', mapi_prop_tag(PT_BINARY, 0x8C9E));
if (!defined('PR_EMS_AB_THUMBNAIL_PHOTO')) {
define('PR_EMS_AB_THUMBNAIL_PHOTO', mapi_prop_tag(PT_BINARY, 0x8C9E));
}
if (!defined('PR_EC_AB_HIDDEN')) {
define('PR_EC_AB_HIDDEN', mapi_prop_tag(PT_BOOLEAN, 0x67A7));
}
class Kopano extends SyncWorker {
const NAME = "Z-Push Kopano GAB Sync";
......@@ -355,6 +360,7 @@ class Kopano extends SyncWorker {
PR_INITIALS,
PR_LANGUAGE,
PR_EMS_AB_THUMBNAIL_PHOTO,
PR_EC_AB_HIDDEN,
PR_DISPLAY_TYPE_EX
));
foreach ($gabentries as $entry) {
......@@ -362,6 +368,12 @@ class Kopano extends SyncWorker {
if (strtoupper($entry[PR_DISPLAY_NAME]) == "SYSTEM") {
continue;
}
// ignore hidden entries
if (isset($entry[PR_EC_AB_HIDDEN]) && $entry[PR_EC_AB_HIDDEN]) {
$this->Log(sprintf("Kopano->GetGAB(): Ignoring user '%s' as account is hidden", $entry[PR_ACCOUNT]));
continue;
}
$a = new GABEntry();
$a->type = GABEntry::CONTACT;
$a->memberOf = array();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment