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 Utils 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 Gohrrequire_once(dirname(__FILE__) . '/../adLDAP.php'); 3876ce1169SAndreas Gohr 3976ce1169SAndreas Gohr/** 4076ce1169SAndreas Gohr* UTILITY FUNCTIONS 4176ce1169SAndreas Gohr*/ 4276ce1169SAndreas Gohrclass adLDAPUtils { 4376ce1169SAndreas Gohr const ADLDAP_VERSION = '4.0.4'; 4476ce1169SAndreas Gohr 4576ce1169SAndreas Gohr /** 4676ce1169SAndreas Gohr * The current adLDAP connection via dependency injection 4776ce1169SAndreas Gohr * 4876ce1169SAndreas Gohr * @var adLDAP 4976ce1169SAndreas Gohr */ 5076ce1169SAndreas Gohr protected $adldap; 5176ce1169SAndreas Gohr 5276ce1169SAndreas Gohr public function __construct(adLDAP $adldap) { 5376ce1169SAndreas Gohr $this->adldap = $adldap; 5476ce1169SAndreas Gohr } 5576ce1169SAndreas Gohr 5676ce1169SAndreas Gohr 5776ce1169SAndreas Gohr /** 5876ce1169SAndreas Gohr * Take an LDAP query and return the nice names, without all the LDAP prefixes (eg. CN, DN) 5976ce1169SAndreas Gohr * 6076ce1169SAndreas Gohr * @param array $groups 6176ce1169SAndreas Gohr * @return array 6276ce1169SAndreas Gohr */ 6376ce1169SAndreas Gohr public function niceNames($groups) 6476ce1169SAndreas Gohr { 6576ce1169SAndreas Gohr 6676ce1169SAndreas Gohr $groupArray = array(); 6776ce1169SAndreas Gohr for ($i=0; $i<$groups["count"]; $i++){ // For each group 6876ce1169SAndreas Gohr $line = $groups[$i]; 6976ce1169SAndreas Gohr 7076ce1169SAndreas Gohr if (strlen($line)>0) { 7176ce1169SAndreas Gohr // More presumptions, they're all prefixed with CN= 7276ce1169SAndreas Gohr // so we ditch the first three characters and the group 7376ce1169SAndreas Gohr // name goes up to the first comma 7476ce1169SAndreas Gohr $bits=explode(",", $line); 7576ce1169SAndreas Gohr $groupArray[] = substr($bits[0], 3, (strlen($bits[0])-3)); 7676ce1169SAndreas Gohr } 7776ce1169SAndreas Gohr } 7876ce1169SAndreas Gohr return $groupArray; 7976ce1169SAndreas Gohr } 8076ce1169SAndreas Gohr 8176ce1169SAndreas Gohr /** 8276ce1169SAndreas Gohr * Escape characters for use in an ldap_create function 8376ce1169SAndreas Gohr * 8476ce1169SAndreas Gohr * @param string $str 8576ce1169SAndreas Gohr * @return string 8676ce1169SAndreas Gohr */ 8776ce1169SAndreas Gohr public function escapeCharacters($str) { 8876ce1169SAndreas Gohr $str = str_replace(",", "\,", $str); 8976ce1169SAndreas Gohr return $str; 9076ce1169SAndreas Gohr } 9176ce1169SAndreas Gohr 9276ce1169SAndreas Gohr /** 9376ce1169SAndreas Gohr * Escape strings for the use in LDAP filters 9476ce1169SAndreas Gohr * 9576ce1169SAndreas Gohr * DEVELOPERS SHOULD BE DOING PROPER FILTERING IF THEY'RE ACCEPTING USER INPUT 9676ce1169SAndreas Gohr * Ported from Perl's Net::LDAP::Util escape_filter_value 9776ce1169SAndreas Gohr * 9876ce1169SAndreas Gohr * @param string $str The string the parse 9976ce1169SAndreas Gohr * @author Port by Andreas Gohr <andi@splitbrain.org> 10076ce1169SAndreas Gohr * @return string 10176ce1169SAndreas Gohr */ 102*f4208becSGerrit Uitslag protected function ldapSlashes($str) { 103*f4208becSGerrit Uitslag // see https://github.com/adldap/adLDAP/issues/22 104*f4208becSGerrit Uitslag return preg_replace_callback( 105*f4208becSGerrit Uitslag '/([\x00-\x1F\*\(\)\\\\])/', 106*f4208becSGerrit Uitslag function ($matches) { 107*f4208becSGerrit Uitslag return "\\".join("", unpack("H2", $matches[1])); 108*f4208becSGerrit Uitslag }, 109*f4208becSGerrit Uitslag $str 110*f4208becSGerrit Uitslag ); 11176ce1169SAndreas Gohr } 11276ce1169SAndreas Gohr /** 11376ce1169SAndreas Gohr * Converts a string GUID to a hexdecimal value so it can be queried 11476ce1169SAndreas Gohr * 11576ce1169SAndreas Gohr * @param string $strGUID A string representation of a GUID 11676ce1169SAndreas Gohr * @return string 11776ce1169SAndreas Gohr */ 11876ce1169SAndreas Gohr public function strGuidToHex($strGUID) 11976ce1169SAndreas Gohr { 12076ce1169SAndreas Gohr $strGUID = str_replace('-', '', $strGUID); 12176ce1169SAndreas Gohr 12276ce1169SAndreas Gohr $octet_str = '\\' . substr($strGUID, 6, 2); 12376ce1169SAndreas Gohr $octet_str .= '\\' . substr($strGUID, 4, 2); 12476ce1169SAndreas Gohr $octet_str .= '\\' . substr($strGUID, 2, 2); 12576ce1169SAndreas Gohr $octet_str .= '\\' . substr($strGUID, 0, 2); 12676ce1169SAndreas Gohr $octet_str .= '\\' . substr($strGUID, 10, 2); 12776ce1169SAndreas Gohr $octet_str .= '\\' . substr($strGUID, 8, 2); 12876ce1169SAndreas Gohr $octet_str .= '\\' . substr($strGUID, 14, 2); 12976ce1169SAndreas Gohr $octet_str .= '\\' . substr($strGUID, 12, 2); 13076ce1169SAndreas Gohr //$octet_str .= '\\' . substr($strGUID, 16, strlen($strGUID)); 13176ce1169SAndreas Gohr for ($i=16; $i<=(strlen($strGUID)-2); $i++) { 13276ce1169SAndreas Gohr if (($i % 2) == 0) { 13376ce1169SAndreas Gohr $octet_str .= '\\' . substr($strGUID, $i, 2); 13476ce1169SAndreas Gohr } 13576ce1169SAndreas Gohr } 13676ce1169SAndreas Gohr 13776ce1169SAndreas Gohr return $octet_str; 13876ce1169SAndreas Gohr } 13976ce1169SAndreas Gohr 14076ce1169SAndreas Gohr /** 14176ce1169SAndreas Gohr * Convert a binary SID to a text SID 14276ce1169SAndreas Gohr * 14376ce1169SAndreas Gohr * @param string $binsid A Binary SID 14476ce1169SAndreas Gohr * @return string 14576ce1169SAndreas Gohr */ 14676ce1169SAndreas Gohr public function getTextSID($binsid) { 14776ce1169SAndreas Gohr $hex_sid = bin2hex($binsid); 14876ce1169SAndreas Gohr $rev = hexdec(substr($hex_sid, 0, 2)); 14976ce1169SAndreas Gohr $subcount = hexdec(substr($hex_sid, 2, 2)); 15076ce1169SAndreas Gohr $auth = hexdec(substr($hex_sid, 4, 12)); 15176ce1169SAndreas Gohr $result = "$rev-$auth"; 15276ce1169SAndreas Gohr 15376ce1169SAndreas Gohr for ($x=0;$x < $subcount; $x++) { 15476ce1169SAndreas Gohr $subauth[$x] = 15576ce1169SAndreas Gohr hexdec($this->littleEndian(substr($hex_sid, 16 + ($x * 8), 8))); 15676ce1169SAndreas Gohr $result .= "-" . $subauth[$x]; 15776ce1169SAndreas Gohr } 15876ce1169SAndreas Gohr 15976ce1169SAndreas Gohr // Cheat by tacking on the S- 16076ce1169SAndreas Gohr return 'S-' . $result; 16176ce1169SAndreas Gohr } 16276ce1169SAndreas Gohr 16376ce1169SAndreas Gohr /** 16476ce1169SAndreas Gohr * Converts a little-endian hex number to one that hexdec() can convert 16576ce1169SAndreas Gohr * 16676ce1169SAndreas Gohr * @param string $hex A hex code 16776ce1169SAndreas Gohr * @return string 16876ce1169SAndreas Gohr */ 16976ce1169SAndreas Gohr public function littleEndian($hex) 17076ce1169SAndreas Gohr { 17176ce1169SAndreas Gohr $result = ''; 17276ce1169SAndreas Gohr for ($x = strlen($hex) - 2; $x >= 0; $x = $x - 2) { 17376ce1169SAndreas Gohr $result .= substr($hex, $x, 2); 17476ce1169SAndreas Gohr } 17576ce1169SAndreas Gohr return $result; 17676ce1169SAndreas Gohr } 17776ce1169SAndreas Gohr 17876ce1169SAndreas Gohr /** 17976ce1169SAndreas Gohr * Converts a binary attribute to a string 18076ce1169SAndreas Gohr * 18176ce1169SAndreas Gohr * @param string $bin A binary LDAP attribute 18276ce1169SAndreas Gohr * @return string 18376ce1169SAndreas Gohr */ 18476ce1169SAndreas Gohr public function binaryToText($bin) 18576ce1169SAndreas Gohr { 18676ce1169SAndreas Gohr $hex_guid = bin2hex($bin); 18776ce1169SAndreas Gohr $hex_guid_to_guid_str = ''; 18876ce1169SAndreas Gohr for($k = 1; $k <= 4; ++$k) { 18976ce1169SAndreas Gohr $hex_guid_to_guid_str .= substr($hex_guid, 8 - 2 * $k, 2); 19076ce1169SAndreas Gohr } 19176ce1169SAndreas Gohr $hex_guid_to_guid_str .= '-'; 19276ce1169SAndreas Gohr for($k = 1; $k <= 2; ++$k) { 19376ce1169SAndreas Gohr $hex_guid_to_guid_str .= substr($hex_guid, 12 - 2 * $k, 2); 19476ce1169SAndreas Gohr } 19576ce1169SAndreas Gohr $hex_guid_to_guid_str .= '-'; 19676ce1169SAndreas Gohr for($k = 1; $k <= 2; ++$k) { 19776ce1169SAndreas Gohr $hex_guid_to_guid_str .= substr($hex_guid, 16 - 2 * $k, 2); 19876ce1169SAndreas Gohr } 19976ce1169SAndreas Gohr $hex_guid_to_guid_str .= '-' . substr($hex_guid, 16, 4); 20076ce1169SAndreas Gohr $hex_guid_to_guid_str .= '-' . substr($hex_guid, 20); 20176ce1169SAndreas Gohr return strtoupper($hex_guid_to_guid_str); 20276ce1169SAndreas Gohr } 20376ce1169SAndreas Gohr 20476ce1169SAndreas Gohr /** 20576ce1169SAndreas Gohr * Converts a binary GUID to a string GUID 20676ce1169SAndreas Gohr * 20776ce1169SAndreas Gohr * @param string $binaryGuid The binary GUID attribute to convert 20876ce1169SAndreas Gohr * @return string 20976ce1169SAndreas Gohr */ 21076ce1169SAndreas Gohr public function decodeGuid($binaryGuid) 21176ce1169SAndreas Gohr { 21276ce1169SAndreas Gohr if ($binaryGuid === null){ return "Missing compulsory field [binaryGuid]"; } 21376ce1169SAndreas Gohr 21476ce1169SAndreas Gohr $strGUID = $this->binaryToText($binaryGuid); 21576ce1169SAndreas Gohr return $strGUID; 21676ce1169SAndreas Gohr } 21776ce1169SAndreas Gohr 21876ce1169SAndreas Gohr /** 21976ce1169SAndreas Gohr * Convert a boolean value to a string 22076ce1169SAndreas Gohr * You should never need to call this yourself 22176ce1169SAndreas Gohr * 22276ce1169SAndreas Gohr * @param bool $bool Boolean value 22376ce1169SAndreas Gohr * @return string 22476ce1169SAndreas Gohr */ 22576ce1169SAndreas Gohr public function boolToStr($bool) 22676ce1169SAndreas Gohr { 22776ce1169SAndreas Gohr return ($bool) ? 'TRUE' : 'FALSE'; 22876ce1169SAndreas Gohr } 22976ce1169SAndreas Gohr 23076ce1169SAndreas Gohr /** 23176ce1169SAndreas Gohr * Convert 8bit characters e.g. accented characters to UTF8 encoded characters 23276ce1169SAndreas Gohr */ 23376ce1169SAndreas Gohr public function encode8Bit(&$item, $key) { 23476ce1169SAndreas Gohr $encode = false; 23576ce1169SAndreas Gohr if (is_string($item)) { 23676ce1169SAndreas Gohr for ($i=0; $i<strlen($item); $i++) { 23776ce1169SAndreas Gohr if (ord($item[$i]) >> 7) { 23876ce1169SAndreas Gohr $encode = true; 23976ce1169SAndreas Gohr } 24076ce1169SAndreas Gohr } 24176ce1169SAndreas Gohr } 24276ce1169SAndreas Gohr if ($encode === true && $key != 'password') { 24376ce1169SAndreas Gohr $item = utf8_encode($item); 24476ce1169SAndreas Gohr } 24576ce1169SAndreas Gohr } 24676ce1169SAndreas Gohr 24776ce1169SAndreas Gohr /** 24876ce1169SAndreas Gohr * Get the current class version number 24976ce1169SAndreas Gohr * 25076ce1169SAndreas Gohr * @return string 25176ce1169SAndreas Gohr */ 25276ce1169SAndreas Gohr public function getVersion() { 25376ce1169SAndreas Gohr return self::ADLDAP_VERSION; 25476ce1169SAndreas Gohr } 25576ce1169SAndreas Gohr 25676ce1169SAndreas Gohr /** 25776ce1169SAndreas Gohr * Round a Windows timestamp down to seconds and remove the seconds between 1601-01-01 and 1970-01-01 25876ce1169SAndreas Gohr * 25976ce1169SAndreas Gohr * @param long $windowsTime 26076ce1169SAndreas Gohr * @return long $unixTime 26176ce1169SAndreas Gohr */ 26276ce1169SAndreas Gohr public static function convertWindowsTimeToUnixTime($windowsTime) { 26376ce1169SAndreas Gohr $unixTime = round($windowsTime / 10000000) - 11644477200; 26476ce1169SAndreas Gohr return $unixTime; 26576ce1169SAndreas Gohr } 26676ce1169SAndreas Gohr} 26776ce1169SAndreas Gohr 26876ce1169SAndreas Gohr?>