diff -urN ../z-push-2.6.4+0.orig/src/backend/searchpasswd/config.php.dist ./src/backend/searchpasswd/config.php.dist --- ../z-push-2.6.4+0.orig/src/backend/searchpasswd/config.php.dist 1970-01-01 03:00:00.000000000 +0300 +++ ./src/backend/searchpasswd/config.php.dist 2023-06-19 17:31:35.267083000 +0300 @@ -0,0 +1,29 @@ +. +* +* Consult LICENSE file for details +************************************************/ + +define('PASSWD_FILE', '/usr/local/etc/passwd.imap'); + +define('FIX_DOMAIN_SEARCH', true); diff -urN ../z-push-2.6.4+0.orig/src/backend/searchpasswd/searchpasswd.php ./src/backend/searchpasswd/searchpasswd.php --- ../z-push-2.6.4+0.orig/src/backend/searchpasswd/searchpasswd.php 1970-01-01 03:00:00.000000000 +0300 +++ ./src/backend/searchpasswd/searchpasswd.php 2023-06-19 18:09:57.017372000 +0300 @@ -0,0 +1,178 @@ +. +* +* Consult LICENSE file for details +************************************************/ + +/********************************************************************* + * The BackendSearchPasswd is a stub to implement own search funtionality + * + * If you wish to implement an alternative search method, you should implement the + * ISearchProvider interface like the BackendSearchPasswd backend + */ + +require_once("backend/searchpasswd/config.php"); + +class BackendSearchPasswd implements ISearchProvider{ + private $passwd_file = null; + + /** + * Constructor + * initializes the searchprovider to perform the search + * + * @access public + * @return + * @throws StatusException, FatalException + */ + public function __construct() { + if (!defined('PASSWD_FILE')) { + ZLog::Write(LOGLEVEL_ERROR, "BackendSearchPasswd(): PASSWD_FILE not defined"); + return false; + } elseif (!file_exists(PASSWD_FILE)) { + ZLog::Write(LOGLEVEL_ERROR, sprintf("BackendSearchPasswd(): file %s not found", PASSWD_FILE)); + return false; + } elseif (!is_readable(PASSWD_FILE)) { + ZLog::Write(LOGLEVEL_ERROR, sprintf("BackendSearchPasswd(): file %s not readable", PASSWD_FILE)); + return false; + } else { + $this->passwd_file = PASSWD_FILE; + return true; + } + } + + /** + * Indicates if a search type is supported by this SearchProvider + * Currently only the type ISearchProvider::SEARCH_GAL (Global Address List) is implemented + * + * @param string $searchtype + * + * @access public + * @return boolean + */ + public function SupportsType($searchtype) { + return ($searchtype == ISearchProvider::SEARCH_GAL); + } + + /** + * Searches the GAL + * + * @param string $searchquery string to be searched for + * @param string $searchrange specified searchrange + * @param SyncResolveRecipientsPicture $searchpicture limitations for picture + * + * @access public + * @return array search results + * @throws StatusException + */ + public function GetGALSearchResults($searchquery, $searchrange, $searchpicture) { + $items = array(); + + if ($this->passwd_file and ($fh = fopen($this->passwd_file, 'r'))) { + while (($buffer = fgets($fh, 4096)) !== false) { + list($username, $passwd, $uid, $gid, $name, $homedir, $shell) = preg_split('/:/', $buffer); + if ((mb_stripos($username, $searchquery) !== false) or (mb_stripos($name, $searchquery) !== false)) { + $item[SYNC_GAL_DISPLAYNAME] = ($name ? $name : $username); + $item[SYNC_GAL_LASTNAME] = ($name ? $name : $username); + $item[SYNC_GAL_EMAILADDRESS] = $username; + + if (defined('FIX_DOMAIN_SEARCH') and (FIX_DOMAIN_SEARCH === true)) { + $item[SYNC_GAL_DISPLAYNAME] = preg_replace('/@(\S+)/', ' ($1)', $item[SYNC_GAL_DISPLAYNAME]); + $item[SYNC_GAL_FIRSTNAME] = preg_replace('/@(\S+)/', ' ($1)', $item[SYNC_GAL_FIRSTNAME]); + $item[SYNC_GAL_LASTNAME] = preg_replace('/@(\S+)/', ' ($1)', $item[SYNC_GAL_LASTNAME]); + list($local_part, $domain) = preg_split('/@/', $item[SYNC_GAL_EMAILADDRESS]); + if ( + (mb_stripos($domain, $searchquery) !== false) + and (mb_stripos($local_part, $searchquery) === false) + and (mb_stripos($item[SYNC_GAL_DISPLAYNAME], $searchquery) === false) + ) { + $item[SYNC_GAL_DISPLAYNAME] .= ' (' . $domain . ')'; + $item[SYNC_GAL_LASTNAME] .= ' (' . $domain . ')'; + } + } + + $items[] = $item; + } + } + fclose($fh); + +// ZLog::Write(LOGLEVEL_DEBUG, sprintf("got total items: %s", print_r($items, true))); + + $searchtotal = count($items); + + $rangestart = 0; + $rangeend = 50; + if (!empty($searchrange) and ($searchrange != '0')) { + $pos = strpos($searchrange, '-'); + if ($pos !== false) { + $rangestart = substr($searchrange, 0, $pos); + $rangeend = substr($searchrange, ($pos + 1)); + } + } + + while (count($items) > $rangeend + 1) array_pop($items); + for ($i = 0; $i < $rangestart; $i++) { + if (count($items) > 0) array_shift($items); + } + $items['range'] = $rangestart . '-' . ($rangestart + count($items) - 1); + $items['searchtotal'] = $searchtotal; + +// ZLog::Write(LOGLEVEL_DEBUG, sprintf("got ranged items: %s", print_r($items, true))); + } + + return $items; + } + + /** + * Searches for the emails on the server + * + * @param ContentParameter $cpo + * + * @return array + */ + public function GetMailboxSearchResults($cpo){ + return array(); + } + + /** + * Terminates a search for a given PID + * + * @param int $pid + * + * @return boolean + */ + public function TerminateSearch($pid) { + return true; + } + + /** + * Disconnects from the current search provider + * + * @access public + * @return boolean + */ + public function Disconnect() { + return true; + } +}