00001 <?php
00002
00003
00004
00013 class SLdap extends SAuthModule {
00014 private $ad_server;
00015 private $ad_port;
00016 private $ad_dn = null;
00017 private $ad_user = "anonymous";
00018 private $ad_pass = "anonymous";
00019 private $ad_errorCode;
00020 private $ad_errorText;
00021 private $ad_connect = null;
00022 private $ad_bind = null;
00023
00024 private $userInfoCache = array();
00025 private $userNames = array();
00026 private $groupInfoCache = array();
00027 private $groupNames = array();
00028
00029 private $currentUid = null;
00030 private $currentGroups = null;
00031
00032 private $fullUserLookup = false;
00033 private $fullGroupLookup = false;
00034
00035
00043 public function clearUserCache() {
00044 $this->userInfoCache = array();
00045 }
00046
00054 public function clearGroupCache() {
00055 $this->groupInfoCache = array();
00056 }
00057
00065 public function clearAllCaches() {
00066 $this->clearUserCache();
00067 $this->clearGroupCache();
00068 }
00069
00078 public function getUserInfo($uid) {
00079 if(ctype_digit((string) $uid)) {
00080 if(!isset($this->userInfoCache[$uid]))
00081 if($this->lookupUsers() === false)
00082 return null;
00083 }
00084 else if(is_string($uid) && $uid != "") {
00085 if(!isset($this->userNames[$uid]))
00086 if($this->lookupUsers() === false)
00087 return null;
00088 if(!isset($this->userNames[$uid]))
00089 return null;
00090 $uid = $this->userNames[$uid];
00091 if(!isset($this->userInfoCache[$uid]))
00092 if($this->lookupUsers() === false)
00093 return null;
00094 }
00095 else
00096 return null;
00097
00098 if(isset($this->userInfoCache[$uid]))
00099 return $this->userInfoCache[$uid];
00100 else
00101 return null;
00102 }
00103
00112 public function getUidFromUserName($username) {
00113 if(isset($this->userNames[$username]))
00114 return $this->userNames[$username];
00115 $this->lookupUsers();
00116 if(isset($this->userNames[$username]))
00117 return $this->userNames[$username];
00118 else
00119 return false;
00120 }
00121
00131 public function getUidFromRealName($firstName = "", $lastName = "") {
00132 $this->lookupUsers();
00133 $firstName = strtolower($firstName);
00134 $lastName = strtolower($lastName);
00135 $matches = array();
00136 foreach($this->userInfoCache as $uid => $uinfo) {
00137 if($firstName != "" && strtolower($uinfo['firstName']) == $firstName) {
00138 if($lastName != "" && strtolower($uinfo['lastName']) == $lastName) {
00139 array_push($matches, $uid);
00140 }
00141 continue;
00142 }
00143 if($lastName != "" && strtolower($uinfo['lastName']) == $lastName)
00144 array_push($matches, $uid);
00145 }
00146 return $matches;
00147 }
00148
00157 public function getGroupInfo($gid) {
00158 if(ctype_digit((string) $gid)) {
00159 if(!isset($this->groupInfoCache[$gid]))
00160 if($this->lookupGroups($gid) === false)
00161 return null;
00162 }
00163 else if($gid != "") {
00164 if(!isset($this->groupNames[$gid]))
00165 if($this->lookupGroups() === false)
00166 return null;
00167 if(!isset($this->groupNames[$gid]))
00168 return null;
00169 $gid = $this->groupNames[$gid];
00170 }
00171 else
00172 return null;
00173
00174 return $this->groupInfoCache[$gid];
00175 }
00176
00185 public function getUserFromUid($uid) {
00186 if(isset($this->userInfoCache[$uid]))
00187 return $this->userInfoCache[$uid];
00188 $this->lookupUsers();
00189 if(isset($this->userInfoCache[$uid]))
00190 return $this->userInfoCache[$uid];
00191 return null;
00192 }
00193
00202 public function getGroupFromGid($gid) {
00203 if(isset($this->groupInfoCache[$gid]))
00204 return $this->groupInfoCache[$gid]['groupname'];
00205 $this->lookupGroups($gid);
00206 if(isset($this->groupInfoCache[$gid]))
00207 return $this->groupInfoCache[$gid]['groupname'];
00208 return null;
00209 }
00210
00219 public function listGroups($uid = "") {
00220 if($uid != "") {
00221 $this->lookupUsers();
00222 if(!isset($this->userInfoCache[$uid]))
00223 return null;
00224 $res = array();
00225 $this->lookupGroups();
00226 foreach($this->userInfoCache[$uid]['groups'] as $gid) {
00227 $res[$gid] = $this->groupInfoCache[$gid]['groupname'];
00228 }
00229 return $res;
00230 }
00231 $this->lookupGroups();
00232 return $this->groupInfoCache;
00233 }
00234
00242 public function listUsers() {
00243 $this->lookupUsers();
00244 return $this->userInfoCache;
00245 }
00246
00254 public function __construct() {
00255 parent::__construct();
00256
00257 $this->ad_server = SConfig::getDefault('ldap.host');
00258 $this->ad_port = SConfig::getDefault('ldap.port');
00259 $this->ad_dn = SConfig::getDefault('ldap.domain');
00260 }
00261
00271 public function authenticate($username, $password) {
00272 if(!$this->connect($this->ad_server, $this->ad_port, $this->ad_dn, $username, $password))
00273 return false;
00274 $this->fillLoggedInUserInfo();
00275 $this->lookupGroups();
00276 $staffGid = $this->groupNames['staff'];
00277 $internGid = $this->groupNames['interns'];
00278 if(isset($this->groupNames['apprentice']))
00279 $apprenticeGid = $this->groupNames['apprentice'];
00280 else
00281 $apprenticeGid = -1;
00282 if(in_array($staffGid, $this->userInfoCache[$this->currentUid]['groups']))
00283 $this->role = "staff";
00284 else if(in_array($internGid, $this->userInfoCache[$this->currentUid]['groups']))
00285 $this->role = "intern";
00286 else if(in_array($apprenticeGid, $this->userInfoCache[$this->currentUid]['groups']))
00287 $this->role = "apprentice";
00288 else
00289 $this->role = "";
00290 return true;
00291 }
00292
00300 public function getPassword() {
00301 return $this->ad_pass;
00302 }
00303
00311 public function getUserName() {
00312 return $this->ad_user;
00313 }
00314
00322 public function getUID() {
00323 return $this->currentUid;
00324 }
00325
00334 public function getFirstName($uid = '') {
00335 if($uid == '')
00336 $uid = $this->currentUid;
00337 if(!isset($this->userInfoCache[$uid]))
00338 $this->fillLoggedInUserInfo($uid);
00339 return $this->userInfoCache[$uid]['firstName'];
00340 }
00341
00350 public function getLastName($uid = '') {
00351 if($uid == '')
00352 $uid = $this->currentUid;
00353 if(!isset($this->userInfoCache[$uid]))
00354 $this->fillLoggedInUserInfo($uid);
00355 return $this->userInfoCache[$uid]['lastName'];
00356 }
00357
00366 public function getEmail($uid = '') {
00367 if($uid == '')
00368 $uid = $this->currentUid;
00369 if(!isset($this->userInfoCache[$uid]))
00370 $this->fillLoggedInUserInfo($uid);
00371 if(isset($this->userInfoCache[$uid]['email'][0]))
00372 return $this->userInfoCache[$uid]['email'][0];
00373 else
00374 return false;
00375 }
00376
00385 public function getPhone($uid = '') {
00386 if($uid == '')
00387 $uid = $this->currentUid;
00388 if(!isset($this->userInfoCache[$uid]))
00389 $this->fillLoggedInUserInfo($uid);
00390 if(isset($this->userInfoCache[$uid]['telephoneNumber'][0]))
00391 return $this->userInfoCache[$uid]['telephoneNumber'][0];
00392 else
00393 return false;
00394 }
00395
00404 public function getMobile($uid = '') {
00405 if($uid == '')
00406 $uid = $this->currentUid;
00407 if(!isset($this->userInfoCache[$uid]))
00408 $this->fillLoggedInUserInfo($uid);
00409 if(isset($this->userInfoCache[$uid]['mobile'][0]))
00410 return $this->userInfoCache[$uid]['mobile'][0];
00411 else
00412 return false;
00413 }
00414
00423 public function getHomePhone($uid = '') {
00424 if($uid == '')
00425 $uid = $this->currentUid;
00426 if(!isset($this->userInfoCache[$uid]))
00427 $this->fillLoggedInUserInfo($uid);
00428 if(isset($this->userInfoCache[$uid]['homePhone'][0]))
00429 return $this->userInfoCache[$uid]['homePhone'][0];
00430 else
00431 return false;
00432 }
00433
00438 public function getRole() {
00439 return $this->role;
00440 }
00441
00449 public function getPermissions() {
00450 return false;
00451 }
00452
00463 private function connect($server, $port, $dn, $user = "anonymous", $pass = "anonymous") {
00464 if($this->ad_connect != null)
00465 return false;
00466 $this->ad_server = $server;
00467 $this->ad_port = $port;
00468 $this->ad_dn = $dn;
00469 $this->ad_user = $user;
00470 $this->ad_pass = $pass;
00471
00472 $this->ad_connect = ldap_connect($this->ad_server, (int)$this->ad_port);
00473 ldap_set_option($this->ad_connect, LDAP_OPT_PROTOCOL_VERSION, 3);
00474
00475 if($user == "" || $pass == "")
00476 return false;
00477
00478 register_shutdown_function(array($this, 'disconnect'));
00479 $this->ad_bind = ldap_bind($this->ad_connect, "uid=$user,ou=People,dc=".$this->ad_dn[0].",dc=".$this->ad_dn[1],
00480 $this->ad_pass);
00481 if(!$this->ad_bind)
00482 return false;
00483 else
00484 return true;
00485 }
00486
00491 public function disconnect() {
00492 if($this->ad_connect != null) {
00493 $ret = ldap_close($this->ad_connect);
00494 }
00495 $this->ad_connect = null;
00496 }
00497
00503 private function checkConnect() {
00504 if($this->ad_connect == null) {
00505 if(!$this->connect($this->ad_server, $this->ad_port, $this->ad_dn, $this->ad_user, $this->ad_pass))
00506 return false;
00507 }
00508
00509 return true;
00510 }
00511
00516 private function fillLoggedInUserInfo($uid = '') {
00517 if(!$this->checkConnect()) return false;
00518 if($uid != '') {
00519 $this->lookupUsers();
00520 return true;
00521 }
00522 else {
00523 if($this->lookupUsers($this->ad_user) == false)
00524 return false;
00525 $this->currentUid = $this->userNames[$this->ad_user];
00526 $this->currentGroups = $this->userInfoCache[$this->currentUid]['groups'];
00527 return true;
00528 }
00529 }
00530
00539 private function lookupUsers($username = "") {
00540 if(!$this->checkConnect()) return false;
00541
00542 if(count($this->userInfoCache) > 0) {
00543 if(($username == "" && $this->fullUserLookup)
00544 || ($username != "" && isset($this->userNames[$username]))) {
00545 return true;
00546 }
00547 }
00548
00549 if($username != "")
00550 $filter = "(|(memberUid=$username)(uid=$username))";
00551 else
00552 $filter = "(|(objectClass=posixGroup)(objectClass=inetOrgPerson))";
00553 $attribute = array('uid', 'uidNumber', 'cn', 'sn', 'givenName', 'mail', 'gidNumber', 'objectClass', 'memberUid',
00554 'telephoneNumber', 'mobile', 'homePhone');
00555
00556 $result = @ldap_search($this->ad_connect, "dc=".$this->ad_dn[0].",dc=".$this->ad_dn[1], $filter, $attribute);
00557 if($result === false) {
00558 $this->setError("Could not get LDAP information about users");
00559 return false;
00560 }
00561 ldap_sort($this->ad_connect, $result, 'cn');
00562 ldap_sort($this->ad_connect, $result, 'sn');
00563 ldap_sort($this->ad_connect, $result, 'objectClass');
00564 $entries = @ldap_get_entries($this->ad_connect, $result);
00565
00566 $users = array();
00567 $groups = array();
00568 for($i = 0; $i < $entries['count']; $i++) {
00569 if(in_array('posixAccount', $entries[$i]['objectclass']))
00570 array_push($users, $entries[$i]);
00571 else if(in_array('posixGroup', $entries[$i]['objectclass']))
00572 array_push($groups, $entries[$i]);
00573 }
00574
00575
00576 for($i = 0; $i < count($users); $i++) {
00577 $mails = array();
00578 if(isset($users[$i]['mail']) && $users[$i]['mail']['count'] > 0) {
00579 foreach($users[$i]['mail'] as $k => $m) {
00580 if(ctype_digit((string) $k))
00581 $mails[] = $m;
00582 }
00583 }
00584 $tnums = array();
00585 if(isset($users[$i]['telephonenumber']) && $users[$i]['telephonenumber']['count'] > 0) {
00586 foreach($users[$i]['telephonenumber'] as $k => $m) {
00587 if(ctype_digit((string) $k))
00588 $tnums[] = $m;
00589 }
00590 }
00591 $mobiles = array();
00592 if(isset($users[$i]['mobile']) && $users[$i]['mobile']['count'] > 0) {
00593 foreach($users[$i]['mobile'] as $k => $m) {
00594 if(ctype_digit((string) $k))
00595 $mobiles[] = $m;
00596 }
00597 }
00598 $homes = array();
00599 if(isset($users[$i]['homephone']) && $users[$i]['homephone']['count'] > 0) {
00600 foreach($users[$i]['homephone'] as $k => $m) {
00601 if(ctype_digit((string) $k))
00602 $homes[] = $m;
00603 }
00604 }
00605 $this->userInfoCache[$users[$i]['uidnumber'][0]] = array(
00606 'userName' => $users[$i]['uid'][0],
00607 'firstName' => isset($users[$i]['givenname'][0]) ? $users[$i]['givenname'][0] : '',
00608 'lastName' => isset($users[$i]['sn'][0]) ? $users[$i]['sn'][0] : '',
00609 'email' => $mails,
00610 'telephoneNumber' => $tnums,
00611 'mobile' => $mobiles,
00612 'homePhone' => $homes,
00613 'groups' => array()
00614 );
00615 $this->userNames[$users[$i]['uid'][0]] = $users[$i]['uidnumber'][0];
00616 }
00617
00618
00619 for($i = 0; $i < count($groups); $i++) {
00620 if(!isset($groups[$i]['memberuid']))
00621 continue;
00622 if($username != "")
00623 array_push($this->userInfoCache[$this->userNames[$username]]['groups'], $groups[$i]['gidnumber'][0]);
00624 else {
00625 foreach($groups[$i]['memberuid'] as $muid) {
00626 if(isset($this->userNames[$muid]))
00627 array_push($this->userInfoCache[$this->userNames[$muid]]['groups'], $groups[$i]['gidnumber'][0]);
00628 }
00629 }
00630 }
00631
00632 if($username == "")
00633 $this->fullUserLookup = true;
00634
00635 $GLOBALS['SWAT']->syncSession();
00636
00637 return true;
00638 }
00639
00648 private function lookupGroups($gid = "") {
00649 if(!$this->checkConnect()) return false;
00650 if(count($this->groupInfoCache) > 0) {
00651 if(($gid == "" && $this->fullGroupLookup)
00652 || ($gid != "" && isset($this->groupCacheInfo[$gid]))) {
00653 return true;
00654 }
00655 }
00656
00657 if($gid != "")
00658 $filter = "(&(objectClass=posixGroup)(gidNumber=$gid))";
00659 else
00660 $filter = "(objectClass=posixGroup)";
00661 $attribute = array('cn', 'gidNumber', 'memberUid');
00662
00663 $result = @ldap_search($this->ad_connect, "ou=Group,dc=".$this->ad_dn[0].",dc=".$this->ad_dn[1], $filter, $attribute);
00664 if($result === false) {
00665 $this->setError("Could not get LDAP information about groups");
00666 return false;
00667 }
00668 ldap_sort($this->ad_connect, $result, "cn");
00669 $entries = @ldap_get_entries($this->ad_connect, $result);
00670 for($i = 0; $i < $entries['count']; $i++) {
00671 $this->groupInfoCache[$entries[$i]['gidnumber'][0]] = array('groupname' => $entries[$i]['cn'][0], 'users' => array());
00672 $this->groupNames[$entries[$i]['cn'][0]] = $entries[$i]['gidnumber'][0];
00673 if(isset($entries[$i]['memberuid'])) {
00674 for($j = 0; $j < $entries[$i]['memberuid']['count']; $j++) {
00675 array_push($this->groupInfoCache[$entries[$i]['gidnumber'][0]]['users'],$entries[$i]['memberuid'][$j]);
00676 }
00677 }
00678 }
00679
00680 if($gid == "")
00681 $this->fullGroupLookup = true;
00682
00683 $GLOBALS['SWAT']->syncSession();
00684
00685 return true;
00686 }
00687
00695 public function __sleep() {
00696 $this->disconnect();
00697 return array_keys(get_object_vars($this));
00698 }
00699
00707 public function __wakeup() {
00708 $this->checkConnect();
00709 return array_keys(get_object_vars($this));
00710 }
00711 }
00712
00713 ?>