"Fossies" - the Fresh Open Source Software Archive 
Member "adLDAP-4.0.4/src/classes/adLDAPUsers.php" (13 Apr 2013, 28353 Bytes) of package /linux/www/old/adLDAP-4.0.4.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) PHP source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "adLDAPUsers.php" see the
Fossies "Dox" file reference documentation.
1 <?php
2 /**
3 * PHP LDAP CLASS FOR MANIPULATING ACTIVE DIRECTORY
4 * Version 4.0.4
5 *
6 * PHP Version 5 with SSL and LDAP support
7 *
8 * Written by Scott Barnett, Richard Hyland
9 * email: scott@wiggumworld.com, adldap@richardhyland.com
10 * http://adldap.sourceforge.net/
11 *
12 * Copyright (c) 2006-2012 Scott Barnett, Richard Hyland
13 *
14 * We'd appreciate any improvements or additions to be submitted back
15 * to benefit the entire community :)
16 *
17 * This library is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU Lesser General Public
19 * License as published by the Free Software Foundation; either
20 * version 2.1 of the License.
21 *
22 * This library is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 * Lesser General Public License for more details.
26 *
27 * @category ToolsAndUtilities
28 * @package adLDAP
29 * @subpackage User
30 * @author Scott Barnett, Richard Hyland
31 * @copyright (c) 2006-2012 Scott Barnett, Richard Hyland
32 * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html LGPLv2.1
33 * @revision $Revision: 97 $
34 * @version 4.0.4
35 * @link http://adldap.sourceforge.net/
36 */
37 require_once(dirname(__FILE__) . '/../adLDAP.php');
38 require_once(dirname(__FILE__) . '/../collections/adLDAPUserCollection.php');
39
40 /**
41 * USER FUNCTIONS
42 */
43 class adLDAPUsers {
44 /**
45 * The current adLDAP connection via dependency injection
46 *
47 * @var adLDAP
48 */
49 protected $adldap;
50
51 public function __construct(adLDAP $adldap) {
52 $this->adldap = $adldap;
53 }
54
55 /**
56 * Validate a user's login credentials
57 *
58 * @param string $username A user's AD username
59 * @param string $password A user's AD password
60 * @param bool optional $prevent_rebind
61 * @return bool
62 */
63 public function authenticate($username, $password, $preventRebind = false) {
64 return $this->adldap->authenticate($username, $password, $preventRebind);
65 }
66
67 /**
68 * Create a user
69 *
70 * If you specify a password here, this can only be performed over SSL
71 *
72 * @param array $attributes The attributes to set to the user account
73 * @return bool
74 */
75 public function create($attributes)
76 {
77 // Check for compulsory fields
78 if (!array_key_exists("username", $attributes)){ return "Missing compulsory field [username]"; }
79 if (!array_key_exists("firstname", $attributes)){ return "Missing compulsory field [firstname]"; }
80 if (!array_key_exists("surname", $attributes)){ return "Missing compulsory field [surname]"; }
81 if (!array_key_exists("email", $attributes)){ return "Missing compulsory field [email]"; }
82 if (!array_key_exists("container", $attributes)){ return "Missing compulsory field [container]"; }
83 if (!is_array($attributes["container"])){ return "Container attribute must be an array."; }
84
85 if (array_key_exists("password",$attributes) && (!$this->adldap->getUseSSL() && !$this->adldap->getUseTLS())){
86 throw new adLDAPException('SSL must be configured on your webserver and enabled in the class to set passwords.');
87 }
88
89 if (!array_key_exists("display_name", $attributes)) {
90 $attributes["display_name"] = $attributes["firstname"] . " " . $attributes["surname"];
91 }
92
93 // Translate the schema
94 $add = $this->adldap->adldap_schema($attributes);
95
96 // Additional stuff only used for adding accounts
97 $add["cn"][0] = $attributes["display_name"];
98 $add["samaccountname"][0] = $attributes["username"];
99 $add["objectclass"][0] = "top";
100 $add["objectclass"][1] = "person";
101 $add["objectclass"][2] = "organizationalPerson";
102 $add["objectclass"][3] = "user"; //person?
103 //$add["name"][0]=$attributes["firstname"]." ".$attributes["surname"];
104
105 // Set the account control attribute
106 $control_options = array("NORMAL_ACCOUNT");
107 if (!$attributes["enabled"]) {
108 $control_options[] = "ACCOUNTDISABLE";
109 }
110 $add["userAccountControl"][0] = $this->accountControl($control_options);
111
112 // Determine the container
113 $attributes["container"] = array_reverse($attributes["container"]);
114 $container = "OU=" . implode(", OU=",$attributes["container"]);
115
116 // Add the entry
117 $result = @ldap_add($this->adldap->getLdapConnection(), "CN=" . $add["cn"][0] . ", " . $container . "," . $this->adldap->getBaseDn(), $add);
118 if ($result != true) {
119 return false;
120 }
121
122 return true;
123 }
124
125 /**
126 * Account control options
127 *
128 * @param array $options The options to convert to int
129 * @return int
130 */
131 protected function accountControl($options)
132 {
133 $val=0;
134
135 if (is_array($options)) {
136 if (in_array("SCRIPT",$options)){ $val=$val+1; }
137 if (in_array("ACCOUNTDISABLE",$options)){ $val=$val+2; }
138 if (in_array("HOMEDIR_REQUIRED",$options)){ $val=$val+8; }
139 if (in_array("LOCKOUT",$options)){ $val=$val+16; }
140 if (in_array("PASSWD_NOTREQD",$options)){ $val=$val+32; }
141 //PASSWD_CANT_CHANGE Note You cannot assign this permission by directly modifying the UserAccountControl attribute.
142 //For information about how to set the permission programmatically, see the "Property flag descriptions" section.
143 if (in_array("ENCRYPTED_TEXT_PWD_ALLOWED",$options)){ $val=$val+128; }
144 if (in_array("TEMP_DUPLICATE_ACCOUNT",$options)){ $val=$val+256; }
145 if (in_array("NORMAL_ACCOUNT",$options)){ $val=$val+512; }
146 if (in_array("INTERDOMAIN_TRUST_ACCOUNT",$options)){ $val=$val+2048; }
147 if (in_array("WORKSTATION_TRUST_ACCOUNT",$options)){ $val=$val+4096; }
148 if (in_array("SERVER_TRUST_ACCOUNT",$options)){ $val=$val+8192; }
149 if (in_array("DONT_EXPIRE_PASSWORD",$options)){ $val=$val+65536; }
150 if (in_array("MNS_LOGON_ACCOUNT",$options)){ $val=$val+131072; }
151 if (in_array("SMARTCARD_REQUIRED",$options)){ $val=$val+262144; }
152 if (in_array("TRUSTED_FOR_DELEGATION",$options)){ $val=$val+524288; }
153 if (in_array("NOT_DELEGATED",$options)){ $val=$val+1048576; }
154 if (in_array("USE_DES_KEY_ONLY",$options)){ $val=$val+2097152; }
155 if (in_array("DONT_REQ_PREAUTH",$options)){ $val=$val+4194304; }
156 if (in_array("PASSWORD_EXPIRED",$options)){ $val=$val+8388608; }
157 if (in_array("TRUSTED_TO_AUTH_FOR_DELEGATION",$options)){ $val=$val+16777216; }
158 }
159 return $val;
160 }
161
162 /**
163 * Delete a user account
164 *
165 * @param string $username The username to delete (please be careful here!)
166 * @param bool $isGUID Is the username a GUID or a samAccountName
167 * @return array
168 */
169 public function delete($username, $isGUID = false)
170 {
171 $userinfo = $this->info($username, array("*"), $isGUID);
172 $dn = $userinfo[0]['distinguishedname'][0];
173 $result = $this->adldap->folder()->delete($dn);
174 if ($result != true) {
175 return false;
176 }
177 return true;
178 }
179
180 /**
181 * Groups the user is a member of
182 *
183 * @param string $username The username to query
184 * @param bool $recursive Recursive list of groups
185 * @param bool $isGUID Is the username passed a GUID or a samAccountName
186 * @return array
187 */
188 public function groups($username, $recursive = NULL, $isGUID = false)
189 {
190 if ($username === NULL) { return false; }
191 if ($recursive === NULL) { $recursive = $this->adldap->getRecursiveGroups(); } // Use the default option if they haven't set it
192 if (!$this->adldap->getLdapBind()) { return false; }
193
194 // Search the directory for their information
195 $info = @$this->info($username, array("memberof", "primarygroupid"), $isGUID);
196 $groups = $this->adldap->utilities()->niceNames($info[0]["memberof"]); // Presuming the entry returned is our guy (unique usernames)
197
198 if ($recursive === true){
199 foreach ($groups as $id => $groupName){
200 $extraGroups = $this->adldap->group()->recursiveGroups($groupName);
201 $groups = array_merge($groups, $extraGroups);
202 }
203 }
204
205 return $groups;
206 }
207
208 /**
209 * Find information about the users. Returned in a raw array format from AD
210 *
211 * @param string $username The username to query
212 * @param array $fields Array of parameters to query
213 * @param bool $isGUID Is the username passed a GUID or a samAccountName
214 * @return array
215 */
216 public function info($username, $fields = NULL, $isGUID = false)
217 {
218 if ($username === NULL) { return false; }
219 if (!$this->adldap->getLdapBind()) { return false; }
220
221 if ($isGUID === true) {
222 $username = $this->adldap->utilities()->strGuidToHex($username);
223 $filter = "objectguid=" . $username;
224 }
225 else if (strstr($username, "@")) {
226 $filter = "userPrincipalName=" . $username;
227 }
228 else {
229 $filter = "samaccountname=" . $username;
230 }
231 $filter = "(&(objectCategory=person)({$filter}))";
232 if ($fields === NULL) {
233 $fields = array("samaccountname","mail","memberof","department","displayname","telephonenumber","primarygroupid","objectsid");
234 }
235 if (!in_array("objectsid", $fields)) {
236 $fields[] = "objectsid";
237 }
238 $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
239 $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
240
241 if (isset($entries[0])) {
242 if ($entries[0]['count'] >= 1) {
243 if (in_array("memberof", $fields)) {
244 // AD does not return the primary group in the ldap query, we may need to fudge it
245 if ($this->adldap->getRealPrimaryGroup() && isset($entries[0]["primarygroupid"][0]) && isset($entries[0]["objectsid"][0])){
246 //$entries[0]["memberof"][]=$this->group_cn($entries[0]["primarygroupid"][0]);
247 $entries[0]["memberof"][] = $this->adldap->group()->getPrimaryGroup($entries[0]["primarygroupid"][0], $entries[0]["objectsid"][0]);
248 } else {
249 $entries[0]["memberof"][] = "CN=Domain Users,CN=Users," . $this->adldap->getBaseDn();
250 }
251 if (!isset($entries[0]["memberof"]["count"])) {
252 $entries[0]["memberof"]["count"] = 0;
253 }
254 $entries[0]["memberof"]["count"]++;
255 }
256 }
257
258 return $entries;
259 }
260 return false;
261 }
262
263 /**
264 * Find information about the users. Returned in a raw array format from AD
265 *
266 * @param string $username The username to query
267 * @param array $fields Array of parameters to query
268 * @param bool $isGUID Is the username passed a GUID or a samAccountName
269 * @return mixed
270 */
271 public function infoCollection($username, $fields = NULL, $isGUID = false)
272 {
273 if ($username === NULL) { return false; }
274 if (!$this->adldap->getLdapBind()) { return false; }
275
276 $info = $this->info($username, $fields, $isGUID);
277
278 if ($info !== false) {
279 $collection = new adLDAPUserCollection($info, $this->adldap);
280 return $collection;
281 }
282 return false;
283 }
284
285 /**
286 * Determine if a user is in a specific group
287 *
288 * @param string $username The username to query
289 * @param string $group The name of the group to check against
290 * @param bool $recursive Check groups recursively
291 * @param bool $isGUID Is the username passed a GUID or a samAccountName
292 * @return bool
293 */
294 public function inGroup($username, $group, $recursive = NULL, $isGUID = false)
295 {
296 if ($username === NULL) { return false; }
297 if ($group === NULL) { return false; }
298 if (!$this->adldap->getLdapBind()) { return false; }
299 if ($recursive === NULL) { $recursive = $this->adldap->getRecursiveGroups(); } // Use the default option if they haven't set it
300
301 // Get a list of the groups
302 $groups = $this->groups($username, $recursive, $isGUID);
303
304 // Return true if the specified group is in the group list
305 if (in_array($group, $groups)) {
306 return true;
307 }
308
309 return false;
310 }
311
312 /**
313 * Determine a user's password expiry date
314 *
315 * @param string $username The username to query
316 * @param book $isGUID Is the username passed a GUID or a samAccountName
317 * @requires bcmath http://www.php.net/manual/en/book.bc.php
318 * @return array
319 */
320 public function passwordExpiry($username, $isGUID = false)
321 {
322 if ($username === NULL) { return "Missing compulsory field [username]"; }
323 if (!$this->adldap->getLdapBind()) { return false; }
324 if (!function_exists('bcmod')) { throw new adLDAPException("Missing function support [bcmod] http://www.php.net/manual/en/book.bc.php"); };
325
326 $userInfo = $this->info($username, array("pwdlastset", "useraccountcontrol"), $isGUID);
327 $pwdLastSet = $userInfo[0]['pwdlastset'][0];
328 $status = array();
329
330 if ($userInfo[0]['useraccountcontrol'][0] == '66048') {
331 // Password does not expire
332 return "Does not expire";
333 }
334 if ($pwdLastSet === '0') {
335 // Password has already expired
336 return "Password has expired";
337 }
338
339 // Password expiry in AD can be calculated from TWO values:
340 // - User's own pwdLastSet attribute: stores the last time the password was changed
341 // - Domain's maxPwdAge attribute: how long passwords last in the domain
342 //
343 // Although Microsoft chose to use a different base and unit for time measurements.
344 // This function will convert them to Unix timestamps
345 $sr = ldap_read($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), 'objectclass=*', array('maxPwdAge'));
346 if (!$sr) {
347 return false;
348 }
349 $info = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
350 $maxPwdAge = $info[0]['maxpwdage'][0];
351
352
353 // See MSDN: http://msdn.microsoft.com/en-us/library/ms974598.aspx
354 //
355 // pwdLastSet contains the number of 100 nanosecond intervals since January 1, 1601 (UTC),
356 // stored in a 64 bit integer.
357 //
358 // The number of seconds between this date and Unix epoch is 11644473600.
359 //
360 // maxPwdAge is stored as a large integer that represents the number of 100 nanosecond
361 // intervals from the time the password was set before the password expires.
362 //
363 // We also need to scale this to seconds but also this value is a _negative_ quantity!
364 //
365 // If the low 32 bits of maxPwdAge are equal to 0 passwords do not expire
366 //
367 // Unfortunately the maths involved are too big for PHP integers, so I've had to require
368 // BCMath functions to work with arbitrary precision numbers.
369 if (bcmod($maxPwdAge, 4294967296) === '0') {
370 return "Domain does not expire passwords";
371 }
372
373 // Add maxpwdage and pwdlastset and we get password expiration time in Microsoft's
374 // time units. Because maxpwd age is negative we need to subtract it.
375 $pwdExpire = bcsub($pwdLastSet, $maxPwdAge);
376
377 // Convert MS's time to Unix time
378 $status['expiryts'] = bcsub(bcdiv($pwdExpire, '10000000'), '11644473600');
379 $status['expiryformat'] = date('Y-m-d H:i:s', bcsub(bcdiv($pwdExpire, '10000000'), '11644473600'));
380
381 return $status;
382 }
383
384 /**
385 * Modify a user
386 *
387 * @param string $username The username to query
388 * @param array $attributes The attributes to modify. Note if you set the enabled attribute you must not specify any other attributes
389 * @param bool $isGUID Is the username passed a GUID or a samAccountName
390 * @return bool
391 */
392 public function modify($username, $attributes, $isGUID = false)
393 {
394 if ($username === NULL) { return "Missing compulsory field [username]"; }
395 if (array_key_exists("password", $attributes) && !$this->adldap->getUseSSL() && !$this->adldap->getUseTLS()) {
396 throw new adLDAPException('SSL/TLS must be configured on your webserver and enabled in the class to set passwords.');
397 }
398
399 // Find the dn of the user
400 $userDn = $this->dn($username, $isGUID);
401 if ($userDn === false) {
402 return false;
403 }
404
405 // Translate the update to the LDAP schema
406 $mod = $this->adldap->adldap_schema($attributes);
407
408 // Check to see if this is an enabled status update
409 if (!$mod && !array_key_exists("enabled", $attributes)){
410 return false;
411 }
412
413 // Set the account control attribute (only if specified)
414 if (array_key_exists("enabled", $attributes)){
415 if ($attributes["enabled"]){
416 $controlOptions = array("NORMAL_ACCOUNT");
417 }
418 else {
419 $controlOptions = array("NORMAL_ACCOUNT", "ACCOUNTDISABLE");
420 }
421 $mod["userAccountControl"][0] = $this->accountControl($controlOptions);
422 }
423
424 // Do the update
425 $result = @ldap_modify($this->adldap->getLdapConnection(), $userDn, $mod);
426 if ($result == false) {
427 return false;
428 }
429
430 return true;
431 }
432
433 /**
434 * Disable a user account
435 *
436 * @param string $username The username to disable
437 * @param bool $isGUID Is the username passed a GUID or a samAccountName
438 * @return bool
439 */
440 public function disable($username, $isGUID = false)
441 {
442 if ($username === NULL) { return "Missing compulsory field [username]"; }
443 $attributes = array("enabled" => 0);
444 $result = $this->modify($username, $attributes, $isGUID);
445 if ($result == false) { return false; }
446
447 return true;
448 }
449
450 /**
451 * Enable a user account
452 *
453 * @param string $username The username to enable
454 * @param bool $isGUID Is the username passed a GUID or a samAccountName
455 * @return bool
456 */
457 public function enable($username, $isGUID = false)
458 {
459 if ($username === NULL) { return "Missing compulsory field [username]"; }
460 $attributes = array("enabled" => 1);
461 $result = $this->modify($username, $attributes, $isGUID);
462 if ($result == false) { return false; }
463
464 return true;
465 }
466
467 /**
468 * Set the password of a user - This must be performed over SSL
469 *
470 * @param string $username The username to modify
471 * @param string $password The new password
472 * @param bool $isGUID Is the username passed a GUID or a samAccountName
473 * @return bool
474 */
475 public function password($username, $password, $isGUID = false)
476 {
477 if ($username === NULL) { return false; }
478 if ($password === NULL) { return false; }
479 if (!$this->adldap->getLdapBind()) { return false; }
480 if (!$this->adldap->getUseSSL() && !$this->adldap->getUseTLS()) {
481 throw new adLDAPException('SSL must be configured on your webserver and enabled in the class to set passwords.');
482 }
483
484 $userDn = $this->dn($username, $isGUID);
485 if ($userDn === false) {
486 return false;
487 }
488
489 $add=array();
490 $add["unicodePwd"][0] = $this->encodePassword($password);
491
492 $result = @ldap_mod_replace($this->adldap->getLdapConnection(), $userDn, $add);
493 if ($result === false){
494 $err = ldap_errno($this->adldap->getLdapConnection());
495 if ($err) {
496 $msg = 'Error ' . $err . ': ' . ldap_err2str($err) . '.';
497 if($err == 53) {
498 $msg .= ' Your password might not match the password policy.';
499 }
500 throw new adLDAPException($msg);
501 }
502 else {
503 return false;
504 }
505 }
506
507 return true;
508 }
509
510 /**
511 * Encode a password for transmission over LDAP
512 *
513 * @param string $password The password to encode
514 * @return string
515 */
516 public function encodePassword($password)
517 {
518 $password="\"".$password."\"";
519 $encoded="";
520 for ($i=0; $i <strlen($password); $i++){ $encoded.="{$password{$i}}\000"; }
521 return $encoded;
522 }
523
524 /**
525 * Obtain the user's distinguished name based on their userid
526 *
527 *
528 * @param string $username The username
529 * @param bool $isGUID Is the username passed a GUID or a samAccountName
530 * @return string
531 */
532 public function dn($username, $isGUID=false)
533 {
534 $user = $this->info($username, array("cn"), $isGUID);
535 if ($user[0]["dn"] === NULL) {
536 return false;
537 }
538 $userDn = $user[0]["dn"];
539 return $userDn;
540 }
541
542 /**
543 * Return a list of all users in AD
544 *
545 * @param bool $includeDescription Return a description of the user
546 * @param string $search Search parameter
547 * @param bool $sorted Sort the user accounts
548 * @return array
549 */
550 public function all($includeDescription = false, $search = "*", $sorted = true)
551 {
552 if (!$this->adldap->getLdapBind()) { return false; }
553
554 // Perform the search and grab all their details
555 $filter = "(&(objectClass=user)(samaccounttype=" . adLDAP::ADLDAP_NORMAL_ACCOUNT .")(objectCategory=person)(cn=" . $search . "))";
556 $fields = array("samaccountname","displayname");
557 $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
558 $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
559
560 $usersArray = array();
561 for ($i=0; $i<$entries["count"]; $i++){
562 if ($includeDescription && strlen($entries[$i]["displayname"][0])>0){
563 $usersArray[$entries[$i]["samaccountname"][0]] = $entries[$i]["displayname"][0];
564 } elseif ($includeDescription){
565 $usersArray[$entries[$i]["samaccountname"][0]] = $entries[$i]["samaccountname"][0];
566 } else {
567 array_push($usersArray, $entries[$i]["samaccountname"][0]);
568 }
569 }
570 if ($sorted) {
571 asort($usersArray);
572 }
573 return $usersArray;
574 }
575
576 /**
577 * Converts a username (samAccountName) to a GUID
578 *
579 * @param string $username The username to query
580 * @return string
581 */
582 public function usernameToGuid($username)
583 {
584 if (!$this->adldap->getLdapBind()){ return false; }
585 if ($username === null){ return "Missing compulsory field [username]"; }
586
587 $filter = "samaccountname=" . $username;
588 $fields = array("objectGUID");
589 $sr = @ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
590 if (ldap_count_entries($this->adldap->getLdapConnection(), $sr) > 0) {
591 $entry = @ldap_first_entry($this->adldap->getLdapConnection(), $sr);
592 $guid = @ldap_get_values_len($this->adldap->getLdapConnection(), $entry, 'objectGUID');
593 $strGUID = $this->adldap->utilities()->binaryToText($guid[0]);
594 return $strGUID;
595 }
596 return false;
597 }
598
599 /**
600 * Return a list of all users in AD that have a specific value in a field
601 *
602 * @param bool $includeDescription Return a description of the user
603 * @param string $searchField Field to search search for
604 * @param string $searchFilter Value to search for in the specified field
605 * @param bool $sorted Sort the user accounts
606 * @return array
607 */
608 public function find($includeDescription = false, $searchField = false, $searchFilter = false, $sorted = true){
609 if (!$this->adldap->getLdapBind()){ return false; }
610
611 // Perform the search and grab all their details
612 $searchParams = "";
613 if ($searchField) {
614 $searchParams = "(" . $searchField . "=" . $searchFilter . ")";
615 }
616 $filter = "(&(objectClass=user)(samaccounttype=" . adLDAP::ADLDAP_NORMAL_ACCOUNT .")(objectCategory=person)" . $searchParams . ")";
617 $fields = array("samaccountname","displayname");
618 $sr = ldap_search($this->adldap->getLdapConnection(), $this->adldap->getBaseDn(), $filter, $fields);
619 $entries = ldap_get_entries($this->adldap->getLdapConnection(), $sr);
620
621 $usersArray = array();
622 for ($i=0; $i < $entries["count"]; $i++) {
623 if ($includeDescription && strlen($entries[$i]["displayname"][0]) > 0) {
624 $usersArray[$entries[$i]["samaccountname"][0]] = $entries[$i]["displayname"][0];
625 }
626 else if ($includeDescription) {
627 $usersArray[$entries[$i]["samaccountname"][0]] = $entries[$i]["samaccountname"][0];
628 }
629 else {
630 array_push($usersArray, $entries[$i]["samaccountname"][0]);
631 }
632 }
633 if ($sorted){
634 asort($usersArray);
635 }
636 return ($usersArray);
637 }
638
639 /**
640 * Move a user account to a different OU
641 *
642 * @param string $username The username to move (please be careful here!)
643 * @param array $container The container or containers to move the user to (please be careful here!).
644 * accepts containers in 1. parent 2. child order
645 * @return array
646 */
647 public function move($username, $container)
648 {
649 if (!$this->adldap->getLdapBind()) { return false; }
650 if ($username === null) { return "Missing compulsory field [username]"; }
651 if ($container === null) { return "Missing compulsory field [container]"; }
652 if (!is_array($container)) { return "Container must be an array"; }
653
654 $userInfo = $this->info($username, array("*"));
655 $dn = $userInfo[0]['distinguishedname'][0];
656 $newRDn = "cn=" . $username;
657 $container = array_reverse($container);
658 $newContainer = "ou=" . implode(",ou=",$container);
659 $newBaseDn = strtolower($newContainer) . "," . $this->adldap->getBaseDn();
660 $result = @ldap_rename($this->adldap->getLdapConnection(), $dn, $newRDn, $newBaseDn, true);
661 if ($result !== true) {
662 return false;
663 }
664 return true;
665 }
666
667 /**
668 * Get the last logon time of any user as a Unix timestamp
669 *
670 * @param string $username
671 * @return long $unixTimestamp
672 */
673 public function getLastLogon($username) {
674 if (!$this->adldap->getLdapBind()) { return false; }
675 if ($username === null) { return "Missing compulsory field [username]"; }
676 $userInfo = $this->info($username, array("lastLogonTimestamp"));
677 $lastLogon = adLDAPUtils::convertWindowsTimeToUnixTime($userInfo[0]['lastLogonTimestamp'][0]);
678 return $lastLogon;
679 }
680
681 }
682 ?>