xref: /dokuwiki/lib/plugins/authad/adLDAP/classes/adLDAPContacts.php (revision 0489c64b7de1b71fdd124114dd18525156f26327)
176ce1169SAndreas Gohr<?php
276ce1169SAndreas Gohr/**
376ce1169SAndreas Gohr * PHP LDAP CLASS FOR MANIPULATING ACTIVE DIRECTORY
476ce1169SAndreas Gohr * Version 4.0.4
576ce1169SAndreas Gohr *
676ce1169SAndreas Gohr * PHP Version 5 with SSL and LDAP support
776ce1169SAndreas Gohr *
876ce1169SAndreas Gohr * Written by Scott Barnett, Richard Hyland
976ce1169SAndreas Gohr *   email: scott@wiggumworld.com, adldap@richardhyland.com
1076ce1169SAndreas Gohr *   http://adldap.sourceforge.net/
1176ce1169SAndreas Gohr *
1276ce1169SAndreas Gohr * Copyright (c) 2006-2012 Scott Barnett, Richard Hyland
1376ce1169SAndreas Gohr *
1476ce1169SAndreas Gohr * We'd appreciate any improvements or additions to be submitted back
1576ce1169SAndreas Gohr * to benefit the entire community :)
1676ce1169SAndreas Gohr *
1776ce1169SAndreas Gohr * This library is free software; you can redistribute it and/or
1876ce1169SAndreas Gohr * modify it under the terms of the GNU Lesser General Public
1976ce1169SAndreas Gohr * License as published by the Free Software Foundation; either
2076ce1169SAndreas Gohr * version 2.1 of the License.
2176ce1169SAndreas Gohr *
2276ce1169SAndreas Gohr * This library is distributed in the hope that it will be useful,
2376ce1169SAndreas Gohr * but WITHOUT ANY WARRANTY; without even the implied warranty of
2476ce1169SAndreas Gohr * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
2576ce1169SAndreas Gohr * Lesser General Public License for more details.
2676ce1169SAndreas Gohr *
2776ce1169SAndreas Gohr * @category ToolsAndUtilities
2876ce1169SAndreas Gohr * @package adLDAP
2976ce1169SAndreas Gohr * @subpackage Contacts
3076ce1169SAndreas Gohr * @author Scott Barnett, Richard Hyland
3176ce1169SAndreas Gohr * @copyright (c) 2006-2012 Scott Barnett, Richard Hyland
3276ce1169SAndreas Gohr * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html LGPLv2.1
3376ce1169SAndreas Gohr * @revision $Revision: 97 $
3476ce1169SAndreas Gohr * @version 4.0.4
3576ce1169SAndreas Gohr * @link http://adldap.sourceforge.net/
3676ce1169SAndreas Gohr */
3776ce1169SAndreas Gohr
3876ce1169SAndreas Gohrrequire_once(dirname(__FILE__) . '/../adLDAP.php');
3976ce1169SAndreas Gohrrequire_once(dirname(__FILE__) . '/../collections/adLDAPContactCollection.php');
4076ce1169SAndreas Gohr
41*0489c64bSMoisés Braga Ribeirouse dokuwiki\Utf8\Sort;
42*0489c64bSMoisés Braga Ribeiro
4376ce1169SAndreas Gohrclass adLDAPContacts {
4476ce1169SAndreas Gohr    /**
4576ce1169SAndreas Gohr    * The current adLDAP connection via dependency injection
4676ce1169SAndreas Gohr    *
4776ce1169SAndreas Gohr    * @var adLDAP
4876ce1169SAndreas Gohr    */
4976ce1169SAndreas Gohr    protected $adldap;
5076ce1169SAndreas Gohr
5176ce1169SAndreas Gohr    public function __construct(adLDAP $adldap) {
5276ce1169SAndreas Gohr        $this->adldap = $adldap;
5376ce1169SAndreas Gohr    }
5476ce1169SAndreas Gohr
5576ce1169SAndreas Gohr    //*****************************************************************************************************************
5676ce1169SAndreas Gohr    // CONTACT FUNCTIONS
5776ce1169SAndreas Gohr    // * Still work to do in this area, and new functions to write
5876ce1169SAndreas Gohr
5976ce1169SAndreas Gohr    /**
6076ce1169SAndreas Gohr    * Create a contact
6176ce1169SAndreas Gohr    *
6276ce1169SAndreas Gohr    * @param array $attributes The attributes to set to the contact
6376ce1169SAndreas Gohr    * @return bool
6476ce1169SAndreas Gohr    */
6576ce1169SAndreas Gohr    public function create($attributes)
6676ce1169SAndreas Gohr    {
6776ce1169SAndreas Gohr        // Check for compulsory fields
6876ce1169SAndreas Gohr        if (!array_key_exists("display_name", $attributes)) { return "Missing compulsory field [display_name]"; }
6976ce1169SAndreas Gohr        if (!array_key_exists("email", $attributes)) { return "Missing compulsory field [email]"; }
7076ce1169SAndreas Gohr        if (!array_key_exists("container", $attributes)) { return "Missing compulsory field [container]"; }
7176ce1169SAndreas Gohr        if (!is_array($attributes["container"])) { return "Container attribute must be an array."; }
7276ce1169SAndreas Gohr
7376ce1169SAndreas Gohr        // Translate the schema
7476ce1169SAndreas Gohr        $add = $this->adldap->adldap_schema($attributes);
7576ce1169SAndreas Gohr
7676ce1169SAndreas Gohr        // Additional stuff only used for adding contacts
7776ce1169SAndreas Gohr        $add["cn"][0] = $attributes["display_name"];
7876ce1169SAndreas Gohr        $add["objectclass"][0] = "top";
7976ce1169SAndreas Gohr        $add["objectclass"][1] = "person";
8076ce1169SAndreas Gohr        $add["objectclass"][2] = "organizationalPerson";
8176ce1169SAndreas Gohr        $add["objectclass"][3] = "contact";
8276ce1169SAndreas Gohr        if (!isset($attributes['exchange_hidefromlists'])) {
8376ce1169SAndreas Gohr            $add["msExchHideFromAddressLists"][0] = "TRUE";
8476ce1169SAndreas Gohr        }
8576ce1169SAndreas Gohr
8676ce1169SAndreas Gohr        // Determine the container
8776ce1169SAndreas Gohr        $attributes["container"] = array_reverse($attributes["container"]);
8876ce1169SAndreas Gohr        $container= "OU=" . implode(",OU=", $attributes["container"]);
8976ce1169SAndreas Gohr
9076ce1169SAndreas Gohr        // Add the entry
9176ce1169SAndreas Gohr        $result = @ldap_add($this->adldap->getLdapConnection(), "CN=" . $this->adldap->utilities()->escapeCharacters($add["cn"][0]) . ", " . $container . "," . $this->adldap->getBaseDn(), $add);
9276ce1169SAndreas Gohr        if ($result != true) {
9376ce1169SAndreas Gohr            return false;
9476ce1169SAndreas Gohr        }
9576ce1169SAndreas Gohr
9676ce1169SAndreas Gohr        return true;
9776ce1169SAndreas Gohr    }
9876ce1169SAndreas Gohr
9976ce1169SAndreas Gohr    /**
10076ce1169SAndreas Gohr    * Determine the list of groups a contact is a member of
10176ce1169SAndreas Gohr    *
10276ce1169SAndreas Gohr    * @param string $distinguisedname The full DN of a contact
10376ce1169SAndreas Gohr    * @param bool $recursive Recursively check groups
10476ce1169SAndreas Gohr    * @return array
10576ce1169SAndreas Gohr    */
10676ce1169SAndreas Gohr    public function groups($distinguishedName, $recursive = NULL)
10776ce1169SAndreas Gohr    {
10876ce1169SAndreas Gohr        if ($distinguishedName === NULL) { return false; }
10976ce1169SAndreas Gohr        if ($recursive === NULL) { $recursive = $this->adldap->getRecursiveGroups(); } //use the default option if they haven't set it
11076ce1169SAndreas Gohr        if (!$this->adldap->getLdapBind()){ return false; }
11176ce1169SAndreas Gohr
11276ce1169SAndreas Gohr        // Search the directory for their information
11376ce1169SAndreas Gohr        $info = @$this->info($distinguishedName, array("memberof", "primarygroupid"));
11476ce1169SAndreas Gohr        $groups = $this->adldap->utilities()->niceNames($info[0]["memberof"]); //presuming the entry returned is our contact
11576ce1169SAndreas Gohr
11676ce1169SAndreas Gohr        if ($recursive === true){
11776ce1169SAndreas Gohr            foreach ($groups as $id => $groupName){
11876ce1169SAndreas Gohr                $extraGroups = $this->adldap->group()->recursiveGroups($groupName);
11976ce1169SAndreas Gohr                $groups = array_merge($groups, $extraGroups);
12076ce1169SAndreas Gohr            }
12176ce1169SAndreas Gohr        }
12276ce1169SAndreas Gohr
12376ce1169SAndreas Gohr        return $groups;
12476ce1169SAndreas Gohr    }
12576ce1169SAndreas Gohr
12676ce1169SAndreas Gohr    /**
12776ce1169SAndreas Gohr    * Get contact information. Returned in a raw array format from AD
12876ce1169SAndreas Gohr    *
12976ce1169SAndreas Gohr    * @param string $distinguisedname The full DN of a contact
13076ce1169SAndreas Gohr    * @param array $fields Attributes to be returned
13176ce1169SAndreas Gohr    * @return array
13276ce1169SAndreas Gohr    */
13376ce1169SAndreas Gohr    public function info($distinguishedName, $fields = NULL)
13476ce1169SAndreas Gohr    {
13576ce1169SAndreas Gohr        if ($distinguishedName === NULL) { return false; }
13676ce1169SAndreas Gohr        if (!$this->adldap->getLdapBind()) { return false; }
13776ce1169SAndreas Gohr
13876ce1169SAndreas Gohr        $filter = "distinguishedName=" . $distinguishedName;
13976ce1169SAndreas Gohr        if ($fields === NULL) {
14076ce1169SAndreas Gohr            $fields = array("distinguishedname", "mail", "memberof", "department", "displayname", "telephonenumber", "primarygroupid", "objectsid");
14176ce1169SAndreas Gohr        }
14276ce1169SAndreas Gohr        $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
14376ce1169SAndreas Gohr        $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
14476ce1169SAndreas Gohr
14576ce1169SAndreas Gohr        if ($entries[0]['count'] >= 1) {
14676ce1169SAndreas Gohr            // AD does not return the primary group in the ldap query, we may need to fudge it
14776ce1169SAndreas Gohr            if ($this->adldap->getRealPrimaryGroup() && isset($entries[0]["primarygroupid"][0]) && isset($entries[0]["primarygroupid"][0])){
14876ce1169SAndreas Gohr                //$entries[0]["memberof"][]=$this->group_cn($entries[0]["primarygroupid"][0]);
14976ce1169SAndreas Gohr                $entries[0]["memberof"][] = $this->adldap->group()->getPrimaryGroup($entries[0]["primarygroupid"][0], $entries[0]["objectsid"][0]);
15076ce1169SAndreas Gohr            } else {
15176ce1169SAndreas Gohr                $entries[0]["memberof"][] = "CN=Domain Users,CN=Users," . $this->adldap->getBaseDn();
15276ce1169SAndreas Gohr            }
15376ce1169SAndreas Gohr        }
15476ce1169SAndreas Gohr
15576ce1169SAndreas Gohr        $entries[0]["memberof"]["count"]++;
15676ce1169SAndreas Gohr        return $entries;
15776ce1169SAndreas Gohr    }
15876ce1169SAndreas Gohr
15976ce1169SAndreas Gohr    /**
16076ce1169SAndreas Gohr    * Find information about the contacts. Returned in a raw array format from AD
16176ce1169SAndreas Gohr    *
16276ce1169SAndreas Gohr    * @param string $distinguishedName The full DN of a contact
16376ce1169SAndreas Gohr    * @param array $fields Array of parameters to query
16476ce1169SAndreas Gohr    * @return mixed
16576ce1169SAndreas Gohr    */
16676ce1169SAndreas Gohr    public function infoCollection($distinguishedName, $fields = NULL)
16776ce1169SAndreas Gohr    {
16876ce1169SAndreas Gohr        if ($distinguishedName === NULL) { return false; }
16976ce1169SAndreas Gohr        if (!$this->adldap->getLdapBind()) { return false; }
17076ce1169SAndreas Gohr
17176ce1169SAndreas Gohr        $info = $this->info($distinguishedName, $fields);
17276ce1169SAndreas Gohr
17376ce1169SAndreas Gohr        if ($info !== false) {
17476ce1169SAndreas Gohr            $collection = new adLDAPContactCollection($info, $this->adldap);
17576ce1169SAndreas Gohr            return $collection;
17676ce1169SAndreas Gohr        }
17776ce1169SAndreas Gohr        return false;
17876ce1169SAndreas Gohr    }
17976ce1169SAndreas Gohr
18076ce1169SAndreas Gohr    /**
18176ce1169SAndreas Gohr    * Determine if a contact is a member of a group
18276ce1169SAndreas Gohr    *
18376ce1169SAndreas Gohr    * @param string $distinguisedName The full DN of a contact
18476ce1169SAndreas Gohr    * @param string $group The group name to query
18576ce1169SAndreas Gohr    * @param bool $recursive Recursively check groups
18676ce1169SAndreas Gohr    * @return bool
18776ce1169SAndreas Gohr    */
18876ce1169SAndreas Gohr    public function inGroup($distinguisedName, $group, $recursive = NULL)
18976ce1169SAndreas Gohr    {
19076ce1169SAndreas Gohr        if ($distinguisedName === NULL) { return false; }
19176ce1169SAndreas Gohr        if ($group === NULL) { return false; }
19276ce1169SAndreas Gohr        if (!$this->adldap->getLdapBind()) { return false; }
19376ce1169SAndreas Gohr        if ($recursive === NULL) { $recursive = $this->adldap->getRecursiveGroups(); } //use the default option if they haven't set it
19476ce1169SAndreas Gohr
19576ce1169SAndreas Gohr        // Get a list of the groups
19676ce1169SAndreas Gohr        $groups = $this->groups($distinguisedName, array("memberof"), $recursive);
19776ce1169SAndreas Gohr
19876ce1169SAndreas Gohr        // Return true if the specified group is in the group list
19976ce1169SAndreas Gohr        if (in_array($group, $groups)){
20076ce1169SAndreas Gohr            return true;
20176ce1169SAndreas Gohr        }
20276ce1169SAndreas Gohr
20376ce1169SAndreas Gohr        return false;
20476ce1169SAndreas Gohr    }
20576ce1169SAndreas Gohr
20676ce1169SAndreas Gohr    /**
20776ce1169SAndreas Gohr    * Modify a contact
20876ce1169SAndreas Gohr    *
20976ce1169SAndreas Gohr    * @param string $distinguishedName The contact to query
21076ce1169SAndreas Gohr    * @param array $attributes The attributes to modify.  Note if you set the enabled attribute you must not specify any other attributes
21176ce1169SAndreas Gohr    * @return bool
21276ce1169SAndreas Gohr    */
21376ce1169SAndreas Gohr    public function modify($distinguishedName, $attributes) {
21476ce1169SAndreas Gohr        if ($distinguishedName === NULL) { return "Missing compulsory field [distinguishedname]"; }
21576ce1169SAndreas Gohr
21676ce1169SAndreas Gohr        // Translate the update to the LDAP schema
21776ce1169SAndreas Gohr        $mod = $this->adldap->adldap_schema($attributes);
21876ce1169SAndreas Gohr
21976ce1169SAndreas Gohr        // Check to see if this is an enabled status update
22076ce1169SAndreas Gohr        if (!$mod) {
22176ce1169SAndreas Gohr            return false;
22276ce1169SAndreas Gohr        }
22376ce1169SAndreas Gohr
22476ce1169SAndreas Gohr        // Do the update
22576ce1169SAndreas Gohr        $result = ldap_modify($this->adldap->getLdapConnection(), $distinguishedName, $mod);
22676ce1169SAndreas Gohr        if ($result == false) {
22776ce1169SAndreas Gohr            return false;
22876ce1169SAndreas Gohr        }
22976ce1169SAndreas Gohr
23076ce1169SAndreas Gohr        return true;
23176ce1169SAndreas Gohr    }
23276ce1169SAndreas Gohr
23376ce1169SAndreas Gohr    /**
23476ce1169SAndreas Gohr    * Delete a contact
23576ce1169SAndreas Gohr    *
23676ce1169SAndreas Gohr    * @param string $distinguishedName The contact dn to delete (please be careful here!)
23776ce1169SAndreas Gohr    * @return array
23876ce1169SAndreas Gohr    */
23976ce1169SAndreas Gohr    public function delete($distinguishedName)
24076ce1169SAndreas Gohr    {
24176ce1169SAndreas Gohr        $result = $this->folder()->delete($distinguishedName);
24276ce1169SAndreas Gohr        if ($result != true) {
24376ce1169SAndreas Gohr            return false;
24476ce1169SAndreas Gohr        }
24576ce1169SAndreas Gohr        return true;
24676ce1169SAndreas Gohr    }
24776ce1169SAndreas Gohr
24876ce1169SAndreas Gohr    /**
24976ce1169SAndreas Gohr    * Return a list of all contacts
25076ce1169SAndreas Gohr    *
25176ce1169SAndreas Gohr    * @param bool $includeDescription Include a description of a contact
25276ce1169SAndreas Gohr    * @param string $search The search parameters
25376ce1169SAndreas Gohr    * @param bool $sorted Whether to sort the results
25476ce1169SAndreas Gohr    * @return array
25576ce1169SAndreas Gohr    */
25676ce1169SAndreas Gohr    public function all($includeDescription = false, $search = "*", $sorted = true) {
25776ce1169SAndreas Gohr        if (!$this->adldap->getLdapBind()) { return false; }
25876ce1169SAndreas Gohr
25976ce1169SAndreas Gohr        // Perform the search and grab all their details
26076ce1169SAndreas Gohr        $filter = "(&(objectClass=contact)(cn=" . $search . "))";
26176ce1169SAndreas Gohr        $fields = array("displayname","distinguishedname");
26276ce1169SAndreas Gohr        $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
26376ce1169SAndreas Gohr        $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
26476ce1169SAndreas Gohr
26576ce1169SAndreas Gohr        $usersArray = array();
26676ce1169SAndreas Gohr        for ($i=0; $i<$entries["count"]; $i++){
26776ce1169SAndreas Gohr            if ($includeDescription && strlen($entries[$i]["displayname"][0])>0){
26876ce1169SAndreas Gohr                $usersArray[$entries[$i]["distinguishedname"][0]] = $entries[$i]["displayname"][0];
26976ce1169SAndreas Gohr            } elseif ($includeDescription){
27076ce1169SAndreas Gohr                $usersArray[$entries[$i]["distinguishedname"][0]] = $entries[$i]["distinguishedname"][0];
27176ce1169SAndreas Gohr            } else {
27276ce1169SAndreas Gohr                array_push($usersArray, $entries[$i]["distinguishedname"][0]);
27376ce1169SAndreas Gohr            }
27476ce1169SAndreas Gohr        }
27576ce1169SAndreas Gohr        if ($sorted) {
276*0489c64bSMoisés Braga Ribeiro            Sort::asort($usersArray);
27776ce1169SAndreas Gohr        }
27876ce1169SAndreas Gohr        return $usersArray;
27976ce1169SAndreas Gohr    }
28076ce1169SAndreas Gohr
28176ce1169SAndreas Gohr    /**
28276ce1169SAndreas Gohr    * Mail enable a contact
28376ce1169SAndreas Gohr    * Allows email to be sent to them through Exchange
28476ce1169SAndreas Gohr    *
28576ce1169SAndreas Gohr    * @param string $distinguishedname The contact to mail enable
28676ce1169SAndreas Gohr    * @param string $emailaddress The email address to allow emails to be sent through
28776ce1169SAndreas Gohr    * @param string $mailnickname The mailnickname for the contact in Exchange.  If NULL this will be set to the display name
28876ce1169SAndreas Gohr    * @return bool
28976ce1169SAndreas Gohr    */
29076ce1169SAndreas Gohr    public function contactMailEnable($distinguishedName, $emailAddress, $mailNickname = NULL){
29176ce1169SAndreas Gohr        return $this->adldap->exchange()->contactMailEnable($distinguishedName, $emailAddress, $mailNickname);
29276ce1169SAndreas Gohr    }
29376ce1169SAndreas Gohr
29476ce1169SAndreas Gohr
29576ce1169SAndreas Gohr}
29676ce1169SAndreas Gohr?>
297