00001 <?php
00002
00003
00004
00013 class SLdapAuthModule 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 $username = strtolower($username);
00114 if(isset($this->userNames[$username]))
00115 return $this->userNames[$username];
00116 $this->lookupUsers();
00117 if(isset($this->userNames[$username]))
00118 return $this->userNames[$username];
00119 else
00120 return false;
00121 }
00122
00132 public function getUidFromRealName($firstName = "", $lastName = "") {
00133 $this->lookupUsers();
00134 $firstName = strtolower($firstName);
00135 $lastName = strtolower($lastName);
00136 $matches = array();
00137 foreach($this->userInfoCache as $uid => $uinfo) {
00138 if($firstName != "" && strtolower($uinfo['firstName']) == $firstName) {
00139 if($lastName != "" && strtolower($uinfo['lastName']) == $lastName) {
00140 array_push($matches, $uid);
00141 }
00142 continue;
00143 }
00144 if($lastName != "" && strtolower($uinfo['lastName']) == $lastName)
00145 array_push($matches, $uid);
00146 }
00147 return $matches;
00148 }
00149
00158 public function getGroupInfo($gid) {
00159 if(ctype_digit((string) $gid)) {
00160 if(!isset($this->groupInfoCache[$gid]))
00161 if($this->lookupGroups($gid) === false)
00162 return null;
00163 }
00164 else if($gid != "") {
00165 if(!isset($this->groupNames[$gid]))
00166 if($this->lookupGroups() === false)
00167 return null;
00168 if(!isset($this->groupNames[$gid]))
00169 return null;
00170 $gid = $this->groupNames[$gid];
00171 }
00172 else
00173 return null;
00174
00175 return $this->groupInfoCache[$gid];
00176 }
00177
00186 public function getUserFromUid($uid) {
00187 if(isset($this->userInfoCache[$uid]))
00188 return $this->userInfoCache[$uid];
00189 $this->lookupUsers();
00190 if(isset($this->userInfoCache[$uid]))
00191 return $this->userInfoCache[$uid];
00192 return null;
00193 }
00194
00203 public function getGroupFromGid($gid) {
00204 if(isset($this->groupInfoCache[$gid]))
00205 return $this->groupInfoCache[$gid]['groupname'];
00206 $this->lookupGroups($gid);
00207 if(isset($this->groupInfoCache[$gid]))
00208 return $this->groupInfoCache[$gid]['groupname'];
00209 return null;
00210 }
00211
00220 public function listGroups($uid = "") {
00221 if($uid != "") {
00222 $this->lookupUsers();
00223 if(!isset($this->userInfoCache[$uid]))
00224 return null;
00225 $res = array();
00226 $this->lookupGroups();
00227 foreach($this->userInfoCache[$uid]['groups'] as $gid) {
00228 $res[$gid] = $this->groupInfoCache[$gid]['groupname'];
00229 }
00230 return $res;
00231 }
00232 $this->lookupGroups();
00233 return $this->groupInfoCache;
00234 }
00235
00243 public function listUsers() {
00244 $this->lookupUsers();
00245 return $this->userInfoCache;
00246 }
00247
00255 public function __construct() {
00256 parent::__construct();
00257
00258 $this->ad_server = SConfig::getDefault('ldap.host');
00259 $this->ad_port = SConfig::getDefault('ldap.port');
00260 $this->ad_dn = SConfig::getDefault('ldap.domain');
00261 }
00262
00272 public function authenticate($username, $password) {
00273 $username = strtolower($username);
00274 if(!$this->connect($this->ad_server, $this->ad_port, $this->ad_dn, $username, $password))
00275 return false;
00276 $this->fillLoggedInUserInfo();
00277 $this->lookupGroups();
00278 $staffGid = $this->groupNames['staff'];
00279 $internGid = $this->groupNames['interns'];
00280 if(isset($this->groupNames['apprentice']))
00281 $apprenticeGid = $this->groupNames['apprentice'];
00282 else
00283 $apprenticeGid = -1;
00284 if(in_array($staffGid, $this->userInfoCache[$this->currentUid]['groups']))
00285 $this->role = "staff";
00286 else if(in_array($internGid, $this->userInfoCache[$this->currentUid]['groups']))
00287 $this->role = "intern";
00288 else if(in_array($apprenticeGid, $this->userInfoCache[$this->currentUid]['groups']))
00289 $this->role = "apprentice";
00290 else
00291 $this->role = "";
00292 return true;
00293 }
00294
00302 public function getPassword() {
00303 return $this->ad_pass;
00304 }
00305
00313 public function getUserName() {
00314 return $this->ad_user;
00315 }
00316
00324 public function getUID() {
00325 return $this->currentUid;
00326 }
00327
00336 public function getFirstName($uid = '') {
00337 if($uid == '')
00338 $uid = $this->currentUid;
00339 if(!isset($this->userInfoCache[$uid]))
00340 $this->fillLoggedInUserInfo($uid);
00341 return $this->userInfoCache[$uid]['firstName'];
00342 }
00343
00352 public function getLastName($uid = '') {
00353 if($uid == '')
00354 $uid = $this->currentUid;
00355 if(!isset($this->userInfoCache[$uid]))
00356 $this->fillLoggedInUserInfo($uid);
00357 return $this->userInfoCache[$uid]['lastName'];
00358 }
00359
00368 public function getEmail($uid = '') {
00369 if($uid == '')
00370 $uid = $this->currentUid;
00371 if(!isset($this->userInfoCache[$uid]))
00372 $this->fillLoggedInUserInfo($uid);
00373 if(isset($this->userInfoCache[$uid]['email'][0]))
00374 return $this->userInfoCache[$uid]['email'][0];
00375 else
00376 return false;
00377 }
00378
00387 public function getPhone($uid = '') {
00388 if($uid == '')
00389 $uid = $this->currentUid;
00390 if(!isset($this->userInfoCache[$uid]))
00391 $this->fillLoggedInUserInfo($uid);
00392 if(isset($this->userInfoCache[$uid]['telephoneNumber'][0]))
00393 return $this->userInfoCache[$uid]['telephoneNumber'][0];
00394 else
00395 return false;
00396 }
00397
00406 public function getMobile($uid = '') {
00407 if($uid == '')
00408 $uid = $this->currentUid;
00409 if(!isset($this->userInfoCache[$uid]))
00410 $this->fillLoggedInUserInfo($uid);
00411 if(isset($this->userInfoCache[$uid]['mobile'][0]))
00412 return $this->userInfoCache[$uid]['mobile'][0];
00413 else
00414 return false;
00415 }
00416
00425 public function getHomePhone($uid = '') {
00426 if($uid == '')
00427 $uid = $this->currentUid;
00428 if(!isset($this->userInfoCache[$uid]))
00429 $this->fillLoggedInUserInfo($uid);
00430 if(isset($this->userInfoCache[$uid]['homePhone'][0]))
00431 return $this->userInfoCache[$uid]['homePhone'][0];
00432 else
00433 return false;
00434 }
00435
00440 public function getRole() {
00441 return $this->role;
00442 }
00443
00451 public function getPermissions() {
00452 return false;
00453 }
00454
00465 private function connect($server, $port, $dn, $user = "anonymous", $pass = "anonymous") {
00466 if($this->ad_connect != null)
00467 return false;
00468 $user = strtolower($user);
00469 $this->ad_server = $server;
00470 $this->ad_port = $port;
00471 $this->ad_dn = $dn;
00472 $this->ad_user = $user;
00473 $this->ad_pass = $pass;
00474
00475 $this->ad_connect = ldap_connect($this->ad_server, (int)$this->ad_port);
00476 ldap_set_option($this->ad_connect, LDAP_OPT_PROTOCOL_VERSION, 3);
00477
00478 if($user == "" || $pass == "")
00479 return false;
00480
00481 register_shutdown_function(array($this, 'disconnect'));
00482 $this->ad_bind = ldap_bind($this->ad_connect, "uid=$user,ou=People,dc=".$this->ad_dn[0].",dc=".$this->ad_dn[1],
00483 $this->ad_pass);
00484 if(!$this->ad_bind)
00485 return false;
00486 else
00487 return true;
00488 }
00489
00494 public function disconnect() {
00495 if($this->ad_connect != null) {
00496 $ret = ldap_close($this->ad_connect);
00497 }
00498 $this->ad_connect = null;
00499 }
00500
00506 private function checkConnect() {
00507 if($this->ad_connect == null) {
00508 if(!$this->connect($this->ad_server, $this->ad_port, $this->ad_dn, $this->ad_user, $this->ad_pass))
00509 return false;
00510 }
00511
00512 return true;
00513 }
00514
00519 private function fillLoggedInUserInfo($uid = '') {
00520 if(!$this->checkConnect()) return false;
00521 if($uid != '') {
00522 $this->lookupUsers();
00523 return true;
00524 }
00525 else {
00526 if($this->lookupUsers($this->ad_user) == false)
00527 return false;
00528 $this->currentUid = $this->userNames[$this->ad_user];
00529 $this->currentGroups = $this->userInfoCache[$this->currentUid]['groups'];
00530 return true;
00531 }
00532 }
00533
00542 private function lookupUsers($username = "") {
00543 if(!$this->checkConnect()) return false;
00544
00545 $username = strtolower($username);
00546
00547 if(count($this->userInfoCache) > 0) {
00548 if(($username == "" && $this->fullUserLookup)
00549 || ($username != "" && isset($this->userNames[$username]))) {
00550 return true;
00551 }
00552 }
00553
00554 if($username != "")
00555 $filter = "(|(memberUid=$username)(uid=$username))";
00556 else
00557 $filter = "(|(objectClass=posixGroup)(objectClass=inetOrgPerson))";
00558 $attribute = array('uid', 'uidNumber', 'cn', 'sn', 'givenName', 'mail', 'gidNumber', 'objectClass', 'memberUid',
00559 'telephoneNumber', 'mobile', 'homePhone');
00560
00561 $result = @ldap_search($this->ad_connect, "dc=".$this->ad_dn[0].",dc=".$this->ad_dn[1], $filter, $attribute);
00562 if($result === false) {
00563 $this->setError("Could not get LDAP information about users");
00564 return false;
00565 }
00566 ldap_sort($this->ad_connect, $result, 'cn');
00567 ldap_sort($this->ad_connect, $result, 'sn');
00568 ldap_sort($this->ad_connect, $result, 'objectClass');
00569 $entries = @ldap_get_entries($this->ad_connect, $result);
00570
00571 $users = array();
00572 $groups = array();
00573 for($i = 0; $i < $entries['count']; $i++) {
00574 if(in_array('posixAccount', $entries[$i]['objectclass']))
00575 array_push($users, $entries[$i]);
00576 else if(in_array('posixGroup', $entries[$i]['objectclass']))
00577 array_push($groups, $entries[$i]);
00578 }
00579
00580
00581 for($i = 0; $i < count($users); $i++) {
00582 $mails = array();
00583 if(isset($users[$i]['mail']) && $users[$i]['mail']['count'] > 0) {
00584 foreach($users[$i]['mail'] as $k => $m) {
00585 if(ctype_digit((string) $k))
00586 $mails[] = $m;
00587 }
00588 }
00589 $tnums = array();
00590 if(isset($users[$i]['telephonenumber']) && $users[$i]['telephonenumber']['count'] > 0) {
00591 foreach($users[$i]['telephonenumber'] as $k => $m) {
00592 if(ctype_digit((string) $k))
00593 $tnums[] = $m;
00594 }
00595 }
00596 $mobiles = array();
00597 if(isset($users[$i]['mobile']) && $users[$i]['mobile']['count'] > 0) {
00598 foreach($users[$i]['mobile'] as $k => $m) {
00599 if(ctype_digit((string) $k))
00600 $mobiles[] = $m;
00601 }
00602 }
00603 $homes = array();
00604 if(isset($users[$i]['homephone']) && $users[$i]['homephone']['count'] > 0) {
00605 foreach($users[$i]['homephone'] as $k => $m) {
00606 if(ctype_digit((string) $k))
00607 $homes[] = $m;
00608 }
00609 }
00610 $this->userInfoCache[$users[$i]['uidnumber'][0]] = array(
00611 'userName' => $users[$i]['uid'][0],
00612 'firstName' => isset($users[$i]['givenname'][0]) ? $users[$i]['givenname'][0] : '',
00613 'lastName' => isset($users[$i]['sn'][0]) ? $users[$i]['sn'][0] : '',
00614 'email' => $mails,
00615 'telephoneNumber' => $tnums,
00616 'mobile' => $mobiles,
00617 'homePhone' => $homes,
00618 'groups' => array()
00619 );
00620 $this->userNames[$users[$i]['uid'][0]] = $users[$i]['uidnumber'][0];
00621 }
00622
00623
00624 for($i = 0; $i < count($groups); $i++) {
00625 if(!isset($groups[$i]['memberuid']))
00626 continue;
00627 if($username != "")
00628 array_push($this->userInfoCache[$this->userNames[$username]]['groups'], $groups[$i]['gidnumber'][0]);
00629 else {
00630 foreach($groups[$i]['memberuid'] as $muid) {
00631 if(isset($this->userNames[$muid]))
00632 array_push($this->userInfoCache[$this->userNames[$muid]]['groups'], $groups[$i]['gidnumber'][0]);
00633 }
00634 }
00635 }
00636
00637 if($username == "")
00638 $this->fullUserLookup = true;
00639
00640 $GLOBALS['SWAT']->syncSession();
00641
00642 return true;
00643 }
00644
00653 private function lookupGroups($gid = "") {
00654 if(!$this->checkConnect()) return false;
00655 if(count($this->groupInfoCache) > 0) {
00656 if(($gid == "" && $this->fullGroupLookup)
00657 || ($gid != "" && isset($this->groupCacheInfo[$gid]))) {
00658 return true;
00659 }
00660 }
00661
00662 if($gid != "")
00663 $filter = "(&(objectClass=posixGroup)(gidNumber=$gid))";
00664 else
00665 $filter = "(objectClass=posixGroup)";
00666 $attribute = array('cn', 'gidNumber', 'memberUid');
00667
00668 $result = @ldap_search($this->ad_connect, "ou=Group,dc=".$this->ad_dn[0].",dc=".$this->ad_dn[1], $filter, $attribute);
00669 if($result === false) {
00670 $this->setError("Could not get LDAP information about groups");
00671 return false;
00672 }
00673 ldap_sort($this->ad_connect, $result, "cn");
00674 $entries = @ldap_get_entries($this->ad_connect, $result);
00675 for($i = 0; $i < $entries['count']; $i++) {
00676 $this->groupInfoCache[$entries[$i]['gidnumber'][0]] = array('groupname' => $entries[$i]['cn'][0], 'users' => array());
00677 $this->groupNames[$entries[$i]['cn'][0]] = $entries[$i]['gidnumber'][0];
00678 if(isset($entries[$i]['memberuid'])) {
00679 for($j = 0; $j < $entries[$i]['memberuid']['count']; $j++) {
00680 array_push($this->groupInfoCache[$entries[$i]['gidnumber'][0]]['users'],$entries[$i]['memberuid'][$j]);
00681 }
00682 }
00683 }
00684
00685 if($gid == "")
00686 $this->fullGroupLookup = true;
00687
00688 $GLOBALS['SWAT']->syncSession();
00689
00690 return true;
00691 }
00692
00700 public function __sleep() {
00701 $this->disconnect();
00702 return array_keys(get_object_vars($this));
00703 }
00704
00712 public function __wakeup() {
00713 $this->checkConnect();
00714 return array_keys(get_object_vars($this));
00715 }
00716 }
00717
00718 ?>