1*76ce1169SAndreas Gohr<?php 2*76ce1169SAndreas Gohr/** 3*76ce1169SAndreas Gohr * PHP LDAP CLASS FOR MANIPULATING ACTIVE DIRECTORY 4*76ce1169SAndreas Gohr * Version 4.0.4 5*76ce1169SAndreas Gohr * 6*76ce1169SAndreas Gohr * PHP Version 5 with SSL and LDAP support 7*76ce1169SAndreas Gohr * 8*76ce1169SAndreas Gohr * Written by Scott Barnett, Richard Hyland 9*76ce1169SAndreas Gohr * email: scott@wiggumworld.com, adldap@richardhyland.com 10*76ce1169SAndreas Gohr * http://adldap.sourceforge.net/ 11*76ce1169SAndreas Gohr * 12*76ce1169SAndreas Gohr * Copyright (c) 2006-2012 Scott Barnett, Richard Hyland 13*76ce1169SAndreas Gohr * 14*76ce1169SAndreas Gohr * We'd appreciate any improvements or additions to be submitted back 15*76ce1169SAndreas Gohr * to benefit the entire community :) 16*76ce1169SAndreas Gohr * 17*76ce1169SAndreas Gohr * This library is free software; you can redistribute it and/or 18*76ce1169SAndreas Gohr * modify it under the terms of the GNU Lesser General Public 19*76ce1169SAndreas Gohr * License as published by the Free Software Foundation; either 20*76ce1169SAndreas Gohr * version 2.1 of the License. 21*76ce1169SAndreas Gohr * 22*76ce1169SAndreas Gohr * This library is distributed in the hope that it will be useful, 23*76ce1169SAndreas Gohr * but WITHOUT ANY WARRANTY; without even the implied warranty of 24*76ce1169SAndreas Gohr * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 25*76ce1169SAndreas Gohr * Lesser General Public License for more details. 26*76ce1169SAndreas Gohr * 27*76ce1169SAndreas Gohr * @category ToolsAndUtilities 28*76ce1169SAndreas Gohr * @package adLDAP 29*76ce1169SAndreas Gohr * @subpackage Utils 30*76ce1169SAndreas Gohr * @author Scott Barnett, Richard Hyland 31*76ce1169SAndreas Gohr * @copyright (c) 2006-2012 Scott Barnett, Richard Hyland 32*76ce1169SAndreas Gohr * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html LGPLv2.1 33*76ce1169SAndreas Gohr * @revision $Revision: 97 $ 34*76ce1169SAndreas Gohr * @version 4.0.4 35*76ce1169SAndreas Gohr * @link http://adldap.sourceforge.net/ 36*76ce1169SAndreas Gohr */ 37*76ce1169SAndreas Gohrrequire_once(dirname(__FILE__) . '/../adLDAP.php'); 38*76ce1169SAndreas Gohr 39*76ce1169SAndreas Gohr/** 40*76ce1169SAndreas Gohr* UTILITY FUNCTIONS 41*76ce1169SAndreas Gohr*/ 42*76ce1169SAndreas Gohrclass adLDAPUtils { 43*76ce1169SAndreas Gohr const ADLDAP_VERSION = '4.0.4'; 44*76ce1169SAndreas Gohr 45*76ce1169SAndreas Gohr /** 46*76ce1169SAndreas Gohr * The current adLDAP connection via dependency injection 47*76ce1169SAndreas Gohr * 48*76ce1169SAndreas Gohr * @var adLDAP 49*76ce1169SAndreas Gohr */ 50*76ce1169SAndreas Gohr protected $adldap; 51*76ce1169SAndreas Gohr 52*76ce1169SAndreas Gohr public function __construct(adLDAP $adldap) { 53*76ce1169SAndreas Gohr $this->adldap = $adldap; 54*76ce1169SAndreas Gohr } 55*76ce1169SAndreas Gohr 56*76ce1169SAndreas Gohr 57*76ce1169SAndreas Gohr /** 58*76ce1169SAndreas Gohr * Take an LDAP query and return the nice names, without all the LDAP prefixes (eg. CN, DN) 59*76ce1169SAndreas Gohr * 60*76ce1169SAndreas Gohr * @param array $groups 61*76ce1169SAndreas Gohr * @return array 62*76ce1169SAndreas Gohr */ 63*76ce1169SAndreas Gohr public function niceNames($groups) 64*76ce1169SAndreas Gohr { 65*76ce1169SAndreas Gohr 66*76ce1169SAndreas Gohr $groupArray = array(); 67*76ce1169SAndreas Gohr for ($i=0; $i<$groups["count"]; $i++){ // For each group 68*76ce1169SAndreas Gohr $line = $groups[$i]; 69*76ce1169SAndreas Gohr 70*76ce1169SAndreas Gohr if (strlen($line)>0) { 71*76ce1169SAndreas Gohr // More presumptions, they're all prefixed with CN= 72*76ce1169SAndreas Gohr // so we ditch the first three characters and the group 73*76ce1169SAndreas Gohr // name goes up to the first comma 74*76ce1169SAndreas Gohr $bits=explode(",", $line); 75*76ce1169SAndreas Gohr $groupArray[] = substr($bits[0], 3, (strlen($bits[0])-3)); 76*76ce1169SAndreas Gohr } 77*76ce1169SAndreas Gohr } 78*76ce1169SAndreas Gohr return $groupArray; 79*76ce1169SAndreas Gohr } 80*76ce1169SAndreas Gohr 81*76ce1169SAndreas Gohr /** 82*76ce1169SAndreas Gohr * Escape characters for use in an ldap_create function 83*76ce1169SAndreas Gohr * 84*76ce1169SAndreas Gohr * @param string $str 85*76ce1169SAndreas Gohr * @return string 86*76ce1169SAndreas Gohr */ 87*76ce1169SAndreas Gohr public function escapeCharacters($str) { 88*76ce1169SAndreas Gohr $str = str_replace(",", "\,", $str); 89*76ce1169SAndreas Gohr return $str; 90*76ce1169SAndreas Gohr } 91*76ce1169SAndreas Gohr 92*76ce1169SAndreas Gohr /** 93*76ce1169SAndreas Gohr * Escape strings for the use in LDAP filters 94*76ce1169SAndreas Gohr * 95*76ce1169SAndreas Gohr * DEVELOPERS SHOULD BE DOING PROPER FILTERING IF THEY'RE ACCEPTING USER INPUT 96*76ce1169SAndreas Gohr * Ported from Perl's Net::LDAP::Util escape_filter_value 97*76ce1169SAndreas Gohr * 98*76ce1169SAndreas Gohr * @param string $str The string the parse 99*76ce1169SAndreas Gohr * @author Port by Andreas Gohr <andi@splitbrain.org> 100*76ce1169SAndreas Gohr * @return string 101*76ce1169SAndreas Gohr */ 102*76ce1169SAndreas Gohr public function ldapSlashes($str){ 103*76ce1169SAndreas Gohr return preg_replace('/([\x00-\x1F\*\(\)\\\\])/e', 104*76ce1169SAndreas Gohr '"\\\\\".join("",unpack("H2","$1"))', 105*76ce1169SAndreas Gohr $str); 106*76ce1169SAndreas Gohr } 107*76ce1169SAndreas Gohr 108*76ce1169SAndreas Gohr /** 109*76ce1169SAndreas Gohr * Converts a string GUID to a hexdecimal value so it can be queried 110*76ce1169SAndreas Gohr * 111*76ce1169SAndreas Gohr * @param string $strGUID A string representation of a GUID 112*76ce1169SAndreas Gohr * @return string 113*76ce1169SAndreas Gohr */ 114*76ce1169SAndreas Gohr public function strGuidToHex($strGUID) 115*76ce1169SAndreas Gohr { 116*76ce1169SAndreas Gohr $strGUID = str_replace('-', '', $strGUID); 117*76ce1169SAndreas Gohr 118*76ce1169SAndreas Gohr $octet_str = '\\' . substr($strGUID, 6, 2); 119*76ce1169SAndreas Gohr $octet_str .= '\\' . substr($strGUID, 4, 2); 120*76ce1169SAndreas Gohr $octet_str .= '\\' . substr($strGUID, 2, 2); 121*76ce1169SAndreas Gohr $octet_str .= '\\' . substr($strGUID, 0, 2); 122*76ce1169SAndreas Gohr $octet_str .= '\\' . substr($strGUID, 10, 2); 123*76ce1169SAndreas Gohr $octet_str .= '\\' . substr($strGUID, 8, 2); 124*76ce1169SAndreas Gohr $octet_str .= '\\' . substr($strGUID, 14, 2); 125*76ce1169SAndreas Gohr $octet_str .= '\\' . substr($strGUID, 12, 2); 126*76ce1169SAndreas Gohr //$octet_str .= '\\' . substr($strGUID, 16, strlen($strGUID)); 127*76ce1169SAndreas Gohr for ($i=16; $i<=(strlen($strGUID)-2); $i++) { 128*76ce1169SAndreas Gohr if (($i % 2) == 0) { 129*76ce1169SAndreas Gohr $octet_str .= '\\' . substr($strGUID, $i, 2); 130*76ce1169SAndreas Gohr } 131*76ce1169SAndreas Gohr } 132*76ce1169SAndreas Gohr 133*76ce1169SAndreas Gohr return $octet_str; 134*76ce1169SAndreas Gohr } 135*76ce1169SAndreas Gohr 136*76ce1169SAndreas Gohr /** 137*76ce1169SAndreas Gohr * Convert a binary SID to a text SID 138*76ce1169SAndreas Gohr * 139*76ce1169SAndreas Gohr * @param string $binsid A Binary SID 140*76ce1169SAndreas Gohr * @return string 141*76ce1169SAndreas Gohr */ 142*76ce1169SAndreas Gohr public function getTextSID($binsid) { 143*76ce1169SAndreas Gohr $hex_sid = bin2hex($binsid); 144*76ce1169SAndreas Gohr $rev = hexdec(substr($hex_sid, 0, 2)); 145*76ce1169SAndreas Gohr $subcount = hexdec(substr($hex_sid, 2, 2)); 146*76ce1169SAndreas Gohr $auth = hexdec(substr($hex_sid, 4, 12)); 147*76ce1169SAndreas Gohr $result = "$rev-$auth"; 148*76ce1169SAndreas Gohr 149*76ce1169SAndreas Gohr for ($x=0;$x < $subcount; $x++) { 150*76ce1169SAndreas Gohr $subauth[$x] = 151*76ce1169SAndreas Gohr hexdec($this->littleEndian(substr($hex_sid, 16 + ($x * 8), 8))); 152*76ce1169SAndreas Gohr $result .= "-" . $subauth[$x]; 153*76ce1169SAndreas Gohr } 154*76ce1169SAndreas Gohr 155*76ce1169SAndreas Gohr // Cheat by tacking on the S- 156*76ce1169SAndreas Gohr return 'S-' . $result; 157*76ce1169SAndreas Gohr } 158*76ce1169SAndreas Gohr 159*76ce1169SAndreas Gohr /** 160*76ce1169SAndreas Gohr * Converts a little-endian hex number to one that hexdec() can convert 161*76ce1169SAndreas Gohr * 162*76ce1169SAndreas Gohr * @param string $hex A hex code 163*76ce1169SAndreas Gohr * @return string 164*76ce1169SAndreas Gohr */ 165*76ce1169SAndreas Gohr public function littleEndian($hex) 166*76ce1169SAndreas Gohr { 167*76ce1169SAndreas Gohr $result = ''; 168*76ce1169SAndreas Gohr for ($x = strlen($hex) - 2; $x >= 0; $x = $x - 2) { 169*76ce1169SAndreas Gohr $result .= substr($hex, $x, 2); 170*76ce1169SAndreas Gohr } 171*76ce1169SAndreas Gohr return $result; 172*76ce1169SAndreas Gohr } 173*76ce1169SAndreas Gohr 174*76ce1169SAndreas Gohr /** 175*76ce1169SAndreas Gohr * Converts a binary attribute to a string 176*76ce1169SAndreas Gohr * 177*76ce1169SAndreas Gohr * @param string $bin A binary LDAP attribute 178*76ce1169SAndreas Gohr * @return string 179*76ce1169SAndreas Gohr */ 180*76ce1169SAndreas Gohr public function binaryToText($bin) 181*76ce1169SAndreas Gohr { 182*76ce1169SAndreas Gohr $hex_guid = bin2hex($bin); 183*76ce1169SAndreas Gohr $hex_guid_to_guid_str = ''; 184*76ce1169SAndreas Gohr for($k = 1; $k <= 4; ++$k) { 185*76ce1169SAndreas Gohr $hex_guid_to_guid_str .= substr($hex_guid, 8 - 2 * $k, 2); 186*76ce1169SAndreas Gohr } 187*76ce1169SAndreas Gohr $hex_guid_to_guid_str .= '-'; 188*76ce1169SAndreas Gohr for($k = 1; $k <= 2; ++$k) { 189*76ce1169SAndreas Gohr $hex_guid_to_guid_str .= substr($hex_guid, 12 - 2 * $k, 2); 190*76ce1169SAndreas Gohr } 191*76ce1169SAndreas Gohr $hex_guid_to_guid_str .= '-'; 192*76ce1169SAndreas Gohr for($k = 1; $k <= 2; ++$k) { 193*76ce1169SAndreas Gohr $hex_guid_to_guid_str .= substr($hex_guid, 16 - 2 * $k, 2); 194*76ce1169SAndreas Gohr } 195*76ce1169SAndreas Gohr $hex_guid_to_guid_str .= '-' . substr($hex_guid, 16, 4); 196*76ce1169SAndreas Gohr $hex_guid_to_guid_str .= '-' . substr($hex_guid, 20); 197*76ce1169SAndreas Gohr return strtoupper($hex_guid_to_guid_str); 198*76ce1169SAndreas Gohr } 199*76ce1169SAndreas Gohr 200*76ce1169SAndreas Gohr /** 201*76ce1169SAndreas Gohr * Converts a binary GUID to a string GUID 202*76ce1169SAndreas Gohr * 203*76ce1169SAndreas Gohr * @param string $binaryGuid The binary GUID attribute to convert 204*76ce1169SAndreas Gohr * @return string 205*76ce1169SAndreas Gohr */ 206*76ce1169SAndreas Gohr public function decodeGuid($binaryGuid) 207*76ce1169SAndreas Gohr { 208*76ce1169SAndreas Gohr if ($binaryGuid === null){ return "Missing compulsory field [binaryGuid]"; } 209*76ce1169SAndreas Gohr 210*76ce1169SAndreas Gohr $strGUID = $this->binaryToText($binaryGuid); 211*76ce1169SAndreas Gohr return $strGUID; 212*76ce1169SAndreas Gohr } 213*76ce1169SAndreas Gohr 214*76ce1169SAndreas Gohr /** 215*76ce1169SAndreas Gohr * Convert a boolean value to a string 216*76ce1169SAndreas Gohr * You should never need to call this yourself 217*76ce1169SAndreas Gohr * 218*76ce1169SAndreas Gohr * @param bool $bool Boolean value 219*76ce1169SAndreas Gohr * @return string 220*76ce1169SAndreas Gohr */ 221*76ce1169SAndreas Gohr public function boolToStr($bool) 222*76ce1169SAndreas Gohr { 223*76ce1169SAndreas Gohr return ($bool) ? 'TRUE' : 'FALSE'; 224*76ce1169SAndreas Gohr } 225*76ce1169SAndreas Gohr 226*76ce1169SAndreas Gohr /** 227*76ce1169SAndreas Gohr * Convert 8bit characters e.g. accented characters to UTF8 encoded characters 228*76ce1169SAndreas Gohr */ 229*76ce1169SAndreas Gohr public function encode8Bit(&$item, $key) { 230*76ce1169SAndreas Gohr $encode = false; 231*76ce1169SAndreas Gohr if (is_string($item)) { 232*76ce1169SAndreas Gohr for ($i=0; $i<strlen($item); $i++) { 233*76ce1169SAndreas Gohr if (ord($item[$i]) >> 7) { 234*76ce1169SAndreas Gohr $encode = true; 235*76ce1169SAndreas Gohr } 236*76ce1169SAndreas Gohr } 237*76ce1169SAndreas Gohr } 238*76ce1169SAndreas Gohr if ($encode === true && $key != 'password') { 239*76ce1169SAndreas Gohr $item = utf8_encode($item); 240*76ce1169SAndreas Gohr } 241*76ce1169SAndreas Gohr } 242*76ce1169SAndreas Gohr 243*76ce1169SAndreas Gohr /** 244*76ce1169SAndreas Gohr * Get the current class version number 245*76ce1169SAndreas Gohr * 246*76ce1169SAndreas Gohr * @return string 247*76ce1169SAndreas Gohr */ 248*76ce1169SAndreas Gohr public function getVersion() { 249*76ce1169SAndreas Gohr return self::ADLDAP_VERSION; 250*76ce1169SAndreas Gohr } 251*76ce1169SAndreas Gohr 252*76ce1169SAndreas Gohr /** 253*76ce1169SAndreas Gohr * Round a Windows timestamp down to seconds and remove the seconds between 1601-01-01 and 1970-01-01 254*76ce1169SAndreas Gohr * 255*76ce1169SAndreas Gohr * @param long $windowsTime 256*76ce1169SAndreas Gohr * @return long $unixTime 257*76ce1169SAndreas Gohr */ 258*76ce1169SAndreas Gohr public static function convertWindowsTimeToUnixTime($windowsTime) { 259*76ce1169SAndreas Gohr $unixTime = round($windowsTime / 10000000) - 11644477200; 260*76ce1169SAndreas Gohr return $unixTime; 261*76ce1169SAndreas Gohr } 262*76ce1169SAndreas Gohr} 263*76ce1169SAndreas Gohr 264*76ce1169SAndreas Gohr?>