1
0
Fork 0
mirror of https://github.com/YunoHost-Apps/z-push_ynh.git synced 2024-09-03 18:05:58 +02:00
z-push_ynh/sources/backend/ldap/ldap.php
2014-12-18 18:08:26 +01:00

584 lines
23 KiB
PHP

<?php
/***********************************************
* File : ldap.php
* Project : PHP-Push
* Descr : This backend is based on
* 'BackendDiff' and implements an
* (Open)LDAP interface
*
* Created : 07.04.2012
*
* Copyright 2012 - 2014 Jean-Louis Dupond
*
* Jean-Louis Dupond released this code as AGPLv3 here: https://github.com/dupondje/PHP-Push-2/issues/93
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation with the following additional
* term according to sec. 7:
*
* According to sec. 7 of the GNU Affero General Public License, version 3,
* the terms of the AGPL are supplemented with the following terms:
*
* "Zarafa" is a registered trademark of Zarafa B.V.
* "Z-Push" is a registered trademark of Zarafa Deutschland GmbH
* The licensing of the Program under the AGPL does not imply a trademark license.
* Therefore any rights, title and interest in our trademarks remain entirely with us.
*
* However, if you propagate an unmodified version of the Program you are
* allowed to use the term "Z-Push" to indicate that you distribute the Program.
* Furthermore you may use our trademarks where it is necessary to indicate
* the intended purpose of a product or service provided you use it in accordance
* with honest practices in industrial or commercial matters.
* If you want to propagate modified versions of the Program under the name "Z-Push",
* you may only do so if you have a written permission by Zarafa Deutschland GmbH
* (to acquire a permission please contact Zarafa at trademark@zarafa.com).
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Consult LICENSE file for details
************************************************/
// config file
require_once("backend/ldap/config.php");
include_once('lib/default/diffbackend/diffbackend.php');
class BackendLDAP extends BackendDiff {
private $ldap_link;
private $user;
public function Logon($username, $domain, $password) {
$this->user = $username;
$user_dn = str_replace('%u', $username, LDAP_USER_DN);
$this->ldap_link = ldap_connect(LDAP_SERVER, LDAP_SERVER_PORT);
ldap_set_option($this->ldap_link, LDAP_OPT_PROTOCOL_VERSION, 3);
if (ldap_bind($this->ldap_link, $user_dn, $password)) {
ZLog::Write(LOGLEVEL_INFO, sprintf("BackendLDAP->Logon(): User '%s' is authenticated on LDAP", $username));
return true;
}
else {
ZLog::Write(LOGLEVEL_INFO, sprintf("BackendLDAP->Logon(): User '%s' is not authenticated on LDAP. Error: ", $username, ldap_error($this->ldap_link)));
return false;
}
}
public function Logoff() {
if (ldap_unbind($this->ldap_link)) {
ZLog::Write(LOGLEVEL_INFO, sprintf("BackendLDAP->Logoff(): Disconnection successfull."));
}
else {
ZLog::Write(LOGLEVEL_INFO, sprintf("BackendLDAP->Logoff(): Disconnection failed. Error: %s", ldap_error($this->ldap_link)));
}
return true;
}
public function SendMail($sm) {
return false;
}
public function GetAttachmentData($attname) {
return false;
}
public function GetWasteBasket() {
return false;
}
public function GetFolderList() {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendLDAP->GetFolderList(): Getting all folders."));
$contacts = array();
$dns = explode("|", LDAP_BASE_DNS);
foreach ($dns as $dn) {
$name = explode(":", $dn);
$folder = $this->StatFolder($name[0]);
$contacts[] = $folder;
}
return $contacts;
}
public function GetFolder($id) {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendLDAP->GetFolder('%s')", $id));
$folder = new SyncFolder();
$folder->serverid = $id;
$folder->parentid = "0";
$folder->displayname = $id;
$folder->type = SYNC_FOLDER_TYPE_CONTACT;
return $folder;
}
public function StatFolder($id) {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendLDAP->StatFolder('%s')", $id));
$folder = $this->GetFolder($id);
$stat = array();
$stat["id"] = $id;
$stat["parent"] = $folder->parentid;
$stat["mod"] = $folder->displayname;
return $stat;
}
public function ChangeFolder($folderid, $oldid, $displayname, $type) {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendLDAP->ChangeFolder('%s','%s','%s','%s')", $folderid, $oldid, $displayname, $type));
return false;
}
public function DeleteFolder($id, $parentid) {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendLDAP->DeleteFolder('%s','%s')", $id, $parentid));
return false;
}
public function GetMessageList($folderid, $cutoffdate) {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendLDAP->GetMessageList('%s','%s')", $folderid, $cutoffdate));
$cutoff = date("YmdHis\Z", $cutoffdate);
$filter = sprintf('(modifyTimestamp>=%s)', $cutoff);
$attributes = array("entryUUID", "modifyTimestamp");
$messages = array();
$base_dns = explode("|", LDAP_BASE_DNS);
foreach ($base_dns as $base_dn) {
$folder = explode(":", $base_dn);
if ($folder[0] == $folderid) {
$base_dn = str_replace('%u', $this->user, $folder[1]);
$results = ldap_list($this->ldap_link, $base_dn, $filter, $attributes);
ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendLDAP->GetMessageList(): Got %s contacts in base_dn '%s'.", ldap_count_entries($this->ldap_link, $results), $base_dn));
$entries = ldap_get_entries($this->ldap_link, $results);
for ($i = 0; $i < $entries["count"]; $i++) {
$message = array();
$message["id"] = $entries[$i]["entryuuid"][0];
$message["mod"] = $entries[$i]["modifytimestamp"][0];
$message["flags"] = "1";
$messages[] = $message;
}
}
}
return $messages;
}
public function GetMessage($folderid, $id, $contentparameters) {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendLDAP->GetMessage('%s','%s')", $folderid, $id));
$truncsize = Utils::GetTruncSize($contentparameters->GetTruncation());
$base_dns = explode("|", LDAP_BASE_DNS);
foreach ($base_dns as $base_dn) {
$folder = explode(":", $base_dn);
if ($folder[0] == $folderid) {
$base_dn = str_replace('%u', $this->user, $folder[1]);
$result_id = ldap_list($this->ldap_link, $base_dn, "(entryUUID=".$id.")");
if ($result_id) {
$entry_id = ldap_first_entry($this->ldap_link, $result_id);
if ($entry_id) {
return $this->_ParseLDAPMessage($result_id, $entry_id, $truncsize);
}
}
}
}
}
private function _ParseLDAPMessage($result_id, $entry_id, $truncsize = -1) {
$contact = new SyncContact();
$values = ldap_get_attributes($this->ldap_link, $entry_id);
for ($i = 0; $i < $values["count"]; $i++) {
$name = $values[$i];
$value = $values[$name][0];
switch ($name) {
//person
case "cn":
case "fileAs":
$contact->fileas = $value;
break;
case "sn":
$contact->lastname = $value;
break;
//inetOrgPerson
case "departmentNumber":
$contact->department = $value;
break;
case "givenName":
$contact->firstname = $value;
break;
case "homePhone":
$contact->homephonenumber = $value;
if ($values[$name]["count"] >= 2) {
$contact->home2phonenumber = $values[$name][1];
}
break;
case "jpegPhoto":
$contact->picture = base64_encode($value);
break;
case "labeledURI":
$contact->webpage = $value;
break;
case "mail":
$contact->email1address = $value;
if ($values[$name]["count"] >= 2) {
$contact->email2address = $values[$name][1];
}
if ($values[$name]["count"] >= 3) {
$contact->email3address = $values[$name][2];
}
break;
case "mobile":
$contact->mobilephonenumber = $value;
break;
case "o":
$contact->companyname = $value;
break;
case "pager":
$contact->pagernumber = $value;
break;
case "secretary":
case "assistantName":
$contact->assistantname = $value;
break;
//organizationalPerson
case "l":
$contact->businesscity = $value;
break;
case "ou":
$contact->department = $value;
break;
case "physicalDeliveryOfficeName":
$contact->officelocation = $value;
break;
case "postalCode":
$contact->businesspostalcode = $value;
break;
case "st":
$contact->businessstate = $value;
break;
case "street":
$contact->businessstreet = $value;
break;
case "telephoneNumber":
$contact->businessphonenumber = $value;
if ($values[$name]["count"] >= 2) {
$contact->business2phonenumber = $values[$name][1];
}
break;
case "title":
$contact->title = $value;
break;
case "description":
case "note":
if (Request::GetProtocolVersion() >= 12.0) {
$contact->asbody = new SyncBaseBody();
$contact->asbody->type = SYNC_BODYPREFERENCE_PLAIN;
$contact->asbody->data = $value;
if ($truncsize > 0 && $truncsize < strlen($contact->asbody->data)) {
$contact->asbody->truncated = 1;
$contact->asbody->data = Utils::Utf8_truncate($contact->asbody->data, $truncsize);
}
else {
$contact->asbody->truncated = 0;
}
$contact->asbody->estimatedDataSize = strlen($contact->asbody->data);
}
else {
$contact->body = $value;
if ($truncsize > 0 && $truncsize < strlen($contact->body)) {
$contact->bodytruncated = 1;
$contact->body = Utils::Utf8_truncate($contact->body, $truncsize);
}
else {
$contact->bodytruncated = 0;
}
$contact->bodysize = strlen($contact->body);
}
break;
case "assistantPhone":
$contact->assistnamephonenumber = $value;
break;
case "birthDate":
$contact->birthday = $value;
break;
case "anniversary":
$contact->anniversary = $value;
break;
case "businessRole":
$contact->jobtitle = $value;
break;
case "carPhone":
$contact->carphonenumber = $value;
break;
case "facsimileTelephoneNumber":
$contact->businessfaxnumber = $value;
break;
case "homeFacsimileTelephoneNumber":
$contact->homefaxnumber = $value;
break;
case "spouseName":
$contact->spouse = $value;
break;
case "managerName":
$contact->managername = $value;
break;
case "radio":
$contact->radiophonenumber = $value;
break;
}
}
return $contact;
}
public function StatMessage($folderid, $id) {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendLDAP->StatMessage('%s','%s')", $folderid, $id));
$base_dns = explode("|", LDAP_BASE_DNS);
foreach ($base_dns as $base_dn) {
$folder = explode(":", $base_dn);
if ($folder[0] == $folderid) {
$base_dn = str_replace('%u', $this->user, $folder[1]);
$result_id = ldap_list($this->ldap_link, $base_dn, "(entryUUID=".$id.")", array("modifyTimestamp"));
if ($result_id) {
$entry_id = ldap_first_entry($this->ldap_link, $result_id);
if ($entry_id) {
$mod = ldap_get_values($this->ldap_link, $entry_id, "modifyTimestamp");
$message = array();
$message["id"] = $id;
$message["mod"] = $mod[0];
$message["flags"] = "1";
return $message;
}
}
}
}
}
public function ChangeMessage($folderid, $id, $message, $contentParameters) {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendLDAP->ChangeMessage('%s','%s')", $folderid, $id));
$base_dns = explode("|", LDAP_BASE_DNS);
foreach ($base_dns as $base_dn) {
$folder = explode(":", $base_dn);
if ($folder[0] == $folderid) {
$base_dn = str_replace('%u', $this->user, $folder[1]);
$ldap_attributes = $this->_GenerateLDAPArray($message);
$result_id = ldap_list($this->ldap_link, $base_dn, "(entryUUID=".$id.")", array("modifyTimestamp"));
if ($result_id) {
$entry_id = ldap_first_entry($this->ldap_link, $result_id);
if ($entry_id) {
$dn = ldap_get_dn($this->ldap_link, $entry_id);
// We cannot ldap_modify objectClass, but we can use ldap_mod_replace
$ldap_classes = array();
$ldap_classes['objectclass'] = Array("top", "person", "inetOrgPerson", "organizationalPerson", "evolutionPerson");
$mode = ldap_mod_replace($this->ldap_link, $dn, $ldap_classes);
$mod = ldap_modify($this->ldap_link, $dn, $ldap_attributes);
if (!$mod) {
return false;
}
return $this->StatMessage($folderid, $id);
}
else {
$uid = time() . mt_rand(100000, 999999);
$dn = "uid=" . $uid . "," . $base_dn;
$add = ldap_add($this->ldap_link, $dn, $ldap_attributes);
if (!$add) {
return false;
}
$result = ldap_read($this->ldap_link, $dn, "objectClass=*", array("entryUUID"));
$entry = ldap_first_entry($this->ldap_link, $result);
$values = ldap_get_values($this->ldap_link, $entry, "entryUUID");
$entryuuid = $values[0];
return $this->StatMessage($folderid, $entryuuid);
}
}
}
}
return false;
}
private function _GenerateLDAPArray($message) {
$ldap = array();
//Set the Object Class
$ldap["objectClass"] = Array("top", "person", "inetOrgPerson", "organizationalPerson", "evolutionPerson");
//Parse Data
if ($message->fileas) {
$ldap["cn"] = $message->fileas;
$ldap["fileAs"] = $message->fileas;
}
if ($message->lastname) {
$ldap["sn"] = $message->lastname;
}
if ($message->department) {
$ldap["departmentNumber"] = $message->department;
}
if ($message->firstname) {
$ldap["givenName"] = $message->firstname;
}
if ($message->homephonenumber) {
$ldap["homePhone"][0] = $message->homephonenumber;
}
if ($message->home2phonenumber) {
$ldap["homePhone"][1] = $message->home2phonenumber;
}
if ($message->picture) {
$ldap["jpegPhoto"] = base64_decode($message->picture);
}
if ($message->webpage) {
$ldap["labeledURI"] = $message->webpage;
}
if ($message->email1address) {
$ldap["mail"][] = $message->email1address;
}
if ($message->email2address) {
$ldap["mail"][] = $message->email2address;
}
if ($message->email3address) {
$ldap["mail"][] = $message->email3address;
}
if ($message->mobilephonenumber) {
$ldap["mobile"] = $message->mobilephonenumber;
}
if ($message->companyname) {
$ldap["o"] = $message->companyname;
}
if ($message->pagernumber) {
$ldap["pager"] = $message->pagernumber;
}
if ($message->assistantname) {
$ldap["secretary"] = $message->assistantname;
$ldap["assistantName"] = $message->assistantname;
}
if ($message->businesscity) {
$ldap["l"] = $message->businesscity;
}
if ($message->department) {
$ldap["ou"] = $message->department;
}
if ($message->officelocation) {
$ldap["physicalDeliveryOfficeName"] = $message->officelocation;
}
if ($message->businesspostalcode) {
$ldap["postalCode"] = $message->businesspostalcode;
}
if ($message->businessstate) {
$ldap["st"] = $message->businessstate;
}
if ($message->businessstreet) {
$ldap["street"] = $message->businessstreet;
}
if ($message->businessphonenumber) {
$ldap["telephoneNumber"][] = $message->businessphonenumber;
}
if ($message->business2phonenumber) {
$ldap["telephoneNumber"][] = $message->business2phonenumber;
}
if ($message->title) {
$ldap["title"] = $message->title;
}
if ($message->body) {
$ldap["description"] = $message->body;
}
if ($message->asbody) {
$ldap["description"] = $message->asbody->data;
}
if ($message->assistnamephonenumber) {
$ldap["assistantPhone"] = $message->assistnamephonenumber;
}
if ($message->birthday) {
$ldap["birthDate"] = $message->birthday;
}
if ($message->anniversary) {
$ldap["anniversary"] = $message->anniversary;
}
if ($message->jobtitle) {
$ldap["businessRole"] = $message->jobtitle;
}
if ($message->carphonenumber) {
$ldap["carPhone"] = $message->carphonenumber;
}
if ($message->businessfaxnumber) {
$ldap["facsimileTelephoneNumber"] = $message->businessfaxnumber;
}
if ($message->homefaxnumber) {
$ldap["homeFacsimileTelephoneNumber"] = $message->homefaxnumber;
}
if ($message->spouse) {
$ldap["spouseName"] = $message->spouse;
}
if ($message->managername) {
$ldap["managerName"] = $message->managername;
}
if ($message->radiophonenumber) {
$ldap["radio"] = $message->radiophonenumber;
}
return $ldap;
}
public function SetReadFlag($folderid, $id, $flags, $contentParameters) {
return false;
}
public function SetStarFlag($folderid, $id, $flags, $contentParameters) {
return false;
}
public function DeleteMessage($folderid, $id, $contentParameters) {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendLDAP->DeleteMessage('%s','%s')", $folderid, $id));
$base_dns = explode("|", LDAP_BASE_DNS);
foreach ($base_dns as $base_dn) {
$folder = explode(":", $base_dn);
if ($folder[0] == $folderid) {
$base_dn = str_replace('%u', $this->user, $folder[1]);
$result_id = ldap_list($this->ldap_link, $base_dn, "(entryUUID=".$id.")", array("entryUUID"));
if ($result_id) {
$entry_id = ldap_first_entry($this->ldap_link, $result_id);
if ($entry_id) {
$dn = ldap_get_dn($this->ldap_link, $entry_id);
return ldap_delete($this->ldap_link, $dn);
}
}
}
}
return false;
}
public function MoveMessage($folderid, $id, $newfolderid, $contentParameters) {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("BackendLDAP->MoveMessage('%s','%s', '%s')", $folderid, $id, $newfolderid));
$base_dns = explode("|", LDAP_BASE_DNS);
$old = "";
$new = "";
foreach ($base_dns as $base_dn) {
$folder = explode(":", $base_dn);
if ($folder[0] == $folderid) {
$old = str_replace('%u', $this->user, $folder[1]);
}
if ($folder[0] == $newfolderid) {
$new = str_replace('%u', $this->user, $folder[1]);
}
}
$result_id = ldap_list($this->ldap_link, $old, "(entryUUID=".$id.")", array("entryUUID"));
if ($result_id) {
$entry_id = ldap_first_entry($this->ldap_link, $result_id);
if ($entry_id) {
$dn = ldap_get_dn($this->ldap_link, $entry_id);
$newdn = ldap_explode_dn($dn, 0);
return ldap_rename($this->ldap_link, $dn, $newdn[0], true);
}
}
return false;
}
/**
* Indicates which AS version is supported by the backend.
*
* @access public
* @return string AS version constant
*/
public function GetSupportedASVersion() {
return ZPush::ASV_14;
}
}
?>