4 * Copyright (C) 2003, 2004 $ThePhpWikiProgrammingTeam
5 * Copyright (C) 2010 Marc-Etienne Vargenau, Alcatel-Lucent
7 * This file is part of PhpWiki.
9 * PhpWiki is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * PhpWiki is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License along
20 * with PhpWiki; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 if (!defined('GROUP_METHOD') or
25 !in_array(GROUP_METHOD,
26 array('NONE','WIKIPAGE','DB','FILE','LDAP')))
27 trigger_error(_("No or unsupported GROUP_METHOD defined"), E_USER_WARNING);
29 /* Special group names for ACL */
30 define('GROUP_EVERY', _("Every"));
31 define('GROUP_ANONYMOUS', _("Anonymous Users"));
32 define('GROUP_BOGOUSER', _("Bogo Users"));
33 define('GROUP_SIGNED', _("Signed Users"));
34 define('GROUP_AUTHENTICATED', _("Authenticated Users"));
35 define('GROUP_ADMIN', _("Administrators"));
36 define('GROUP_OWNER', _("Owner"));
37 define('GROUP_CREATOR', _("Creator"));
40 * WikiGroup is an abstract class to provide the base functions for determining
41 * group membership for a specific user. Some functions are user independent.
43 * Limitation: For the current user only. This must be fixed to be able to query
44 * for membership of any user.
46 * WikiGroup is an abstract class with three functions:
47 * <ol><li />Provide the static method getGroup with will return the proper
49 * <li />Provide an interface for subclasses to implement.
50 * <li />Provide fallover methods (with error msgs) if not impemented in subclass.
52 * Do not ever instantiate this class. Use: $group = &WikiGroup::getGroup();
53 * This will instantiate the proper subclass.
55 * @author Joby Walker <zorloc@imperium.org>
61 /** User object if different from current user */
63 /** The global WikiRequest object */
65 /** Array of groups $username is confirmed to belong to */
67 /** boolean if not the current user */
68 var $not_current = false;
71 * Initializes a WikiGroup object which should never happen. Use:
72 * $group = &WikiGroup::getGroup();
73 * @param object $request The global WikiRequest object -- ignored.
75 function WikiGroup($not_current = false) {
76 $this->not_current = $not_current;
77 //$this->request =& $GLOBALS['request'];
81 * Gets the current username from the internal user object
82 * and erases $this->membership if is different than
83 * the stored $this->username
84 * @return string Current username.
86 function _getUserName(){
88 $user = (!empty($this->user)) ? $this->user : $request->getUser();
89 $username = $user->getID();
90 if ($username != $this->username) {
91 $this->membership = array();
92 $this->username = $username;
94 if (!$this->not_current)
100 * Static method to return the WikiGroup subclass used in this wiki. Controlled
101 * by the constant GROUP_METHOD.
102 * @param object $request The global WikiRequest object.
103 * @return object Subclass of WikiGroup selected via GROUP_METHOD.
105 function getGroup($not_current = false){
106 switch (GROUP_METHOD){
108 return new GroupNone($not_current);
111 return new GroupWikiPage($not_current);
114 if ($GLOBALS['DBParams']['dbtype'] == 'ADODB') {
115 return new GroupDB_ADODB($not_current);
116 } elseif ($GLOBALS['DBParams']['dbtype'] == 'SQL') {
117 return new GroupDb_PearDB($not_current);
119 trigger_error("GROUP_METHOD = DB: Unsupported dbtype "
120 . $GLOBALS['DBParams']['dbtype'],
125 return new GroupFile($not_current);
128 return new GroupLDAP($not_current);
131 trigger_error(_("No or unsupported GROUP_METHOD defined"), E_USER_WARNING);
132 return new WikiGroup($not_current);
136 /** ACL PagePermissions will need those special groups based on the User status only.
139 function specialGroup($group){
140 return in_array($group,$this->specialGroups());
143 function _specialGroup($group){
144 return in_array($group,$this->_specialGroups());
147 function specialGroups(){
159 function _specialGroups(){
172 * Determines if the current user is a member of a group.
174 * This method is an abstraction. The group is ignored, an error is sent, and
175 * false (not a member of the group) is returned.
176 * @param string $group Name of the group to check for membership (ignored).
177 * @return boolean True if user is a member, else false (always false).
179 function isMember($group){
180 if (isset($this->membership[$group]))
181 return $this->membership[$group];
182 if ($this->specialGroup($group)) {
183 return $this->isSpecialMember($group);
185 trigger_error(__sprintf("Method '%s' not implemented in this GROUP_METHOD %s",
186 'isMember', GROUP_METHOD),
192 function isSpecialMember($group){
195 if (isset($this->membership[$group]))
196 return $this->membership[$group];
197 $user = (!empty($this->user)) ? $this->user : $request->getUser();
200 return $this->membership[$group] = true;
201 case GROUP_ANONYMOUS:
202 return $this->membership[$group] = ! $user->isSignedIn();
204 return $this->membership[$group] = (isa($user,'_BogoUser')
205 and $user->_level >= WIKIAUTH_BOGO);
207 return $this->membership[$group] = $user->isSignedIn();
208 case GROUP_AUTHENTICATED:
209 return $this->membership[$group] = $user->isAuthenticated();
211 return $this->membership[$group] = (isset($user->_level)
212 and $user->_level == WIKIAUTH_ADMIN);
217 trigger_error(__sprintf("Undefined method %s for special group %s",
225 * Determines all of the groups of which the current user is a member.
227 * This method is an abstraction. An error is sent and an empty
229 * @return array Array of groups to which the user belongs (always empty).
231 function getAllGroupsIn(){
232 trigger_error(__sprintf("Method '%s' not implemented in this GROUP_METHOD %s",
233 'getAllGroupsIn', GROUP_METHOD),
238 function _allUsers() {
239 static $result = array();
244 /* WikiPage users: */
245 $dbh =& $request->_dbi;
246 $page_iter = $dbh->getAllPages();
248 while ($page = $page_iter->next()) {
249 if ($page->isUserPage())
250 $users[] = $page->_pagename;
253 /* WikiDB users from prefs (not from users): */
255 $dbi = _PassUser::getAuthDbh();
259 if ($dbi and $dbh->getAuthParam('pref_select')) {
261 $sql = preg_replace('/SELECT .+ FROM/i','SELECT userid FROM',
262 $dbh->getAuthParam('pref_select'));
263 //don't strip WHERE, only the userid stuff.
264 $sql = preg_replace('/(WHERE.*?)\s+\w+\s*=\s*["\']\$userid[\'"]/i','\\1 AND 1', $sql);
265 $sql = str_replace('WHERE AND 1','',$sql);
266 if (isa($dbi, 'ADOConnection')) {
267 $db_result = $dbi->Execute($sql);
268 foreach ($db_result->GetArray() as $u) {
269 $users = array_merge($users,array_values($u));
271 } elseif (isa($dbi, 'DB_common')) { // PearDB
272 $users = array_merge($users, $dbi->getCol($sql));
276 /* WikiDB users from users: */
277 // Fixme: don't strip WHERE, only the userid stuff.
278 if ($dbi and $dbh->getAuthParam('auth_user_exists')) {
279 //don't strip WHERE, only the userid stuff.
280 $sql = preg_replace('/(WHERE.*?)\s+\w+\s*=\s*["\']\$userid[\'"]/i','\\1 AND 1',
281 $dbh->getAuthParam('auth_user_exists'));
282 $sql = str_replace('WHERE AND 1','', $sql);
283 if (isa($dbi, 'ADOConnection')) {
284 $db_result = $dbi->Execute($sql);
285 foreach ($db_result->GetArray() as $u) {
286 $users = array_merge($users, array_values($u));
288 } elseif (isa($dbi, 'DB_common')) {
289 $users = array_merge($users, $dbi->getCol($sql));
293 // remove empty and duplicate users
295 foreach ($users as $u) {
296 if (empty($u) or in_array($u,$result)) continue;
303 * Determines all of the members of a particular group.
305 * This method is an abstraction. The group is ignored, an error is sent,
306 * and an empty array is returned
307 * @param string $group Name of the group to get the full membership list of.
308 * @return array Array of usernames that have joined the group (always empty).
310 function getMembersOf($group){
311 if ($this->specialGroup($group)) {
312 return $this->getSpecialMembersOf($group);
314 trigger_error(__sprintf("Method '%s' not implemented in this GROUP_METHOD %s",
315 'getMembersOf', GROUP_METHOD),
320 function getSpecialMembersOf($group) {
321 //$request = &$this->request;
322 $all = $this->_allUsers();
327 case GROUP_ANONYMOUS:
330 foreach ($all as $u) {
331 if (isWikiWord($u)) $users[] = $u;
335 foreach ($all as $u) {
336 $user = WikiUser($u);
337 if ($user->isSignedIn()) $users[] = $u;
340 case GROUP_AUTHENTICATED:
341 foreach ($all as $u) {
342 $user = WikiUser($u);
343 if ($user->isAuthenticated()) $users[] = $u;
347 foreach ($all as $u) {
348 $user = WikiUser($u);
349 if (isset($user->_level) and $user->_level == WIKIAUTH_ADMIN)
355 // this could get complex so just return an empty array
358 trigger_error(__sprintf("Unknown special group '%s'", $group),
364 * Add the current or specified user to a group.
366 * This method is an abstraction. The group and user are ignored, an error
367 * is sent, and false (not added) is always returned.
368 * @param string $group User added to this group.
369 * @param string $user Username to add to the group (default = current user).
370 * @return bool On true user was added, false if not.
372 function setMemberOf($group, $user = false){
373 trigger_error(__sprintf("Method '%s' not implemented in this GROUP_METHOD %s",
374 'setMemberOf', GROUP_METHOD),
380 * Remove the current or specified user to a group.
382 * This method is an abstraction. The group and user are ignored, and error
383 * is sent, and false (not removed) is always returned.
384 * @param string $group User removed from this group.
385 * @param string $user Username to remove from the group (default = current user).
386 * @return bool On true user was removed, false if not.
388 function removeMemberOf($group, $user = false){
389 trigger_error(__sprintf("Method '%s' not implemented in this GROUP_METHOD %s",
390 'removeMemberOf', GROUP_METHOD),
397 * GroupNone disables all Group funtionality
399 * All of the GroupNone functions return false or empty values to indicate failure or
400 * no results. Use GroupNone if group controls are not desired.
401 * @author Joby Walker <zorloc@imperium.org>
403 class GroupNone extends WikiGroup{
408 * Ignores the parameter provided.
409 * @param object $request The global WikiRequest object - ignored.
411 function GroupNone() {
412 //$this->request = &$GLOBALS['request'];
417 * Determines if the current user is a member of a group.
419 * The group is ignored and false (not a member of the group) is returned.
420 * @param string $group Name of the group to check for membership (ignored).
421 * @return boolean True if user is a member, else false (always false).
423 function isMember($group){
424 if ($this->specialGroup($group)) {
425 return $this->isSpecialMember($group);
432 * Determines all of the groups of which the current user is a member.
434 * The group is ignored and an empty array (a member of no groups) is returned.
435 * @param string $group Name of the group to check for membership (ignored).
436 * @return array Array of groups to which the user belongs (always empty).
438 function getAllGroupsIn(){
443 * Determines all of the members of a particular group.
445 * The group is ignored and an empty array (a member of no groups) is returned.
446 * @param string $group Name of the group to check for membership (ignored).
447 * @return array Array of groups user belongs to (always empty).
449 function getMembersOf($group){
456 * GroupWikiPage provides group functionality via pages within the Wiki.
458 * GroupWikiPage is the Wiki way of managing a group. Every group will have
459 * a page. To modify the membership of the group, one only needs to edit the
460 * membership list on the page.
461 * @author Joby Walker <zorloc@imperium.org>
463 class GroupWikiPage extends WikiGroup{
468 * Initializes the three superclass instance variables
469 * @param object $request The global WikiRequest object.
471 function GroupWikiPage() {
472 //$this->request = &$GLOBALS['request'];
473 $this->username = $this->_getUserName();
474 //$this->username = null;
475 $this->membership = array();
479 * Determines if the current user is a member of a group.
481 * To determine membership in a particular group, this method checks the
482 * superclass instance variable $membership to see if membership has
483 * already been determined. If not, then the group page is parsed to
484 * determine membership.
485 * @param string $group Name of the group to check for membership.
486 * @return boolean True if user is a member, else false.
488 function isMember($group){
489 if (isset($this->membership[$group])) {
490 return $this->membership[$group];
493 $group_page = $request->getPage($group);
494 if ($this->_inGroupPage($group_page)) {
495 $this->membership[$group] = true;
498 $this->membership[$group] = false;
499 // Let grouppages override certain defaults, such as members of admin
500 if ($this->specialGroup($group)) {
501 return $this->isSpecialMember($group);
507 * Private method to take a WikiDB_Page and parse to determine if the
508 * current_user is a member of the group.
509 * @param object $group_page WikiDB_Page object for the group's page
510 * @return boolean True if user is a member, else false.
513 function _inGroupPage($group_page, $strict=false){
514 $group_revision = $group_page->getCurrentRevision();
515 if ($group_revision->hasDefaultContents()) {
516 $group = $group_page->getName();
517 if ($strict) trigger_error(sprintf(_("Group page '%s' does not exist"), $group),
521 $contents = $group_revision->getContent();
522 $match = '/^\s*[\*\#]+\s*\[?' . $this->username . '\]?(\s|$)/';
523 foreach ($contents as $line){
524 if (preg_match($match, $line)) {
532 * Determines all of the groups of which the current user is a member.
534 * Checks the root Group page ('CategoryGroup') for the list of all groups,
535 * then checks each group to see if the current user is a member.
536 * @param string $group Name of the group to check for membership.
537 * @return array Array of groups to which the user belongs.
539 function getAllGroupsIn(){
540 $membership = array();
542 $specialgroups = $this->specialGroups();
543 foreach ($specialgroups as $group) {
544 $this->membership[$group] = $this->isSpecialMember($group);
548 $dbh = &$request->_dbi;
549 $master_page = $request->getPage(CATEGORY_GROUP_PAGE);
550 $master_list = $master_page->getLinks(true);
551 while ($group_page = $master_list->next()){
552 $group = $group_page->getName();
553 $this->membership[$group] = $this->_inGroupPage($group_page);
555 foreach ($this->membership as $g => $bool) {
556 if ($bool) $membership[] = $g;
562 * Determines all of the members of a particular group.
564 * Checks a group's page to return all the current members. Currently this
565 * method is disabled and triggers an error and returns an empty array.
566 * @param string $group Name of the group to get the full membership list of.
567 * @return array Array of usernames that have joined the group (always empty).
569 function getMembersOf($group){
570 if ($this->specialGroup($group))
571 return $this->getSpecialMembersOf($group);
573 $group_page = $GLOBALS['request']->getPage($group);
574 $group_revision = $group_page->getCurrentRevision();
575 if ($group_revision->hasDefaultContents()) {
576 trigger_error(sprintf(_("Group %s does not exist"),$group), E_USER_WARNING);
579 $contents = $group_revision->getContent();
580 // This is not really a reliable way to check if a string is a username. But better than nothing.
581 $match = '/^(\s*[\*\#]+\s*\[?)(\w+)(\]?\s*)$/';
583 foreach ($contents as $line){
584 if (preg_match($match, $line, $matches)){
585 $members[] = $matches[2];
593 * GroupDb is configured by $DbAuthParams[] statements
598 class GroupDb extends WikiGroup {
600 var $_is_member, $_group_members, $_user_groups;
605 * @param object $request The global WikiRequest object. ignored
608 global $DBAuthParams, $DBParams;
609 //$this->request = &$GLOBALS['request'];
610 $this->username = $this->_getUserName();
611 $this->membership = array();
613 if (empty($DBAuthParams['group_members']) or
614 empty($DBAuthParams['user_groups']) or
615 empty($DBAuthParams['is_member'])) {
616 trigger_error(_("No or not enough GROUP_DB SQL statements defined"),
618 return new GroupNone();
620 // FIXME: This only works with ENABLE_USER_NEW
621 if (empty($this->user)) {
622 // use _PassUser::prepare instead
623 if (isa($request->getUser(),'_PassUser'))
624 $user = $request->getUser();
626 $user = new _PassUser($this->username);
627 } elseif (!isa($this->user, '_PassUser')) {
628 $user = new _PassUser($this->username);
630 $user =& $this->user;
632 if (isa($this->user, '_PassUser')) { // TODO: safety by Charles Corrigan
633 $this->_is_member = $user->prepare($DBAuthParams['is_member'],
634 array('userid','groupname'));
635 $this->_group_members = $user->prepare($DBAuthParams['group_members'],'groupname');
636 $this->_user_groups = $user->prepare($DBAuthParams['user_groups'],'userid');
637 $this->dbh = $user->_auth_dbi;
647 class GroupDb_PearDB extends GroupDb {
650 * Determines if the current user is a member of a database group.
652 * @param string $group Name of the group to check for membership.
653 * @return boolean True if user is a member, else false.
655 function isMember($group) {
656 if (isset($this->membership[$group])) {
657 return $this->membership[$group];
660 $db_result = $dbh->query(sprintf($this->_is_member,
661 $dbh->quote($this->username),
662 $dbh->quote($group)));
663 if ($db_result->numRows() > 0) {
664 $this->membership[$group] = true;
667 $this->membership[$group] = false;
668 // Let override certain defaults, such as members of admin
669 if ($this->specialGroup($group))
670 return $this->isSpecialMember($group);
675 * Determines all of the groups of which the current user is a member.
677 * then checks each group to see if the current user is a member.
678 * @param string $group Name of the group to check for membership.
679 * @return array Array of groups to which the user belongs.
681 function getAllGroupsIn(){
682 $membership = array();
685 $db_result = $dbh->query(sprintf($this->_user_groups, $dbh->quote($this->username)));
686 if ($db_result->numRows() > 0) {
687 while (list($group) = $db_result->fetchRow(DB_FETCHMODE_ORDERED)) {
688 $membership[] = $group;
689 $this->membership[$group] = true;
693 $specialgroups = $this->specialGroups();
694 foreach ($specialgroups as $group) {
695 if ($this->isMember($group)) {
696 $membership[] = $group;
703 * Determines all of the members of a particular group.
705 * Checks a group's page to return all the current members. Currently this
706 * method is disabled and triggers an error and returns an empty array.
707 * @param string $group Name of the group to get the full membership list of.
708 * @return array Array of usernames that have joined the group.
710 function getMembersOf($group){
714 $db_result = $dbh->query(sprintf($this->_group_members,$dbh->quote($group)));
715 if ($db_result->numRows() > 0) {
716 while (list($userid) = $db_result->fetchRow(DB_FETCHMODE_ORDERED)) {
717 $members[] = $userid;
720 // add certain defaults, such as members of admin
721 if ($this->specialGroup($group))
722 $members = array_merge($members, $this->getSpecialMembersOf($group));
732 class GroupDb_ADODB extends GroupDb {
735 * Determines if the current user is a member of a database group.
737 * @param string $group Name of the group to check for membership.
738 * @return boolean True if user is a member, else false.
740 function isMember($group) {
741 if (isset($this->membership[$group])) {
742 return $this->membership[$group];
745 $rs = $dbh->Execute(sprintf($this->_is_member,$dbh->qstr($this->username),
746 $dbh->qstr($group)));
750 if ($rs->numRows() > 0) {
751 $this->membership[$group] = true;
756 $this->membership[$group] = false;
757 if ($this->specialGroup($group))
758 return $this->isSpecialMember($group);
764 * Determines all of the groups of which the current user is a member.
765 * then checks each group to see if the current user is a member.
767 * @param string $group Name of the group to check for membership.
768 * @return array Array of groups to which the user belongs.
770 function getAllGroupsIn(){
771 $membership = array();
774 $rs = $dbh->Execute(sprintf($this->_user_groups, $dbh->qstr($this->username)));
775 if (!$rs->EOF and $rs->numRows() > 0) {
777 $group = reset($rs->fields);
778 $membership[] = $group;
779 $this->membership[$group] = true;
785 $specialgroups = $this->specialGroups();
786 foreach ($specialgroups as $group) {
787 if ($this->isMember($group)) {
788 $membership[] = $group;
795 * Determines all of the members of a particular group.
797 * @param string $group Name of the group to get the full membership list of.
798 * @return array Array of usernames that have joined the group.
800 function getMembersOf($group){
803 $rs = $dbh->Execute(sprintf($this->_group_members,$dbh->qstr($group)));
804 if (!$rs->EOF and $rs->numRows() > 0) {
806 $members[] = reset($rs->fields);
811 // add certain defaults, such as members of admin
812 if ($this->specialGroup($group))
813 $members = array_merge($members, $this->getSpecialMembersOf($group));
819 * GroupFile is configured by AUTH_GROUP_FILE
820 * groupname: user1 user2 ...
824 class GroupFile extends WikiGroup {
829 * @param object $request The global WikiRequest object.
831 function GroupFile(){
832 //$this->request = &$GLOBALS['request'];
833 $this->username = $this->_getUserName();
834 //$this->username = null;
835 $this->membership = array();
837 if (!defined('AUTH_GROUP_FILE')) {
838 trigger_error(sprintf(_("%s: not defined"), "AUTH_GROUP_FILE"),
842 if (!file_exists(AUTH_GROUP_FILE)) {
843 trigger_error(sprintf(_("Cannot open AUTH_GROUP_FILE %s"), AUTH_GROUP_FILE),
847 require_once 'lib/pear/File_Passwd.php';
848 $this->_file = new File_Passwd(AUTH_GROUP_FILE,false,AUTH_GROUP_FILE.".lock");
852 * Determines if the current user is a member of a group.
854 * To determine membership in a particular group, this method checks the
855 * superclass instance variable $membership to see if membership has
856 * already been determined. If not, then the group file is parsed to
857 * determine membership.
858 * @param string $group Name of the group to check for membership.
859 * @return boolean True if user is a member, else false.
861 function isMember($group) {
862 //$request = $this->request;
863 //$username = $this->username;
864 if (isset($this->membership[$group])) {
865 return $this->membership[$group];
868 if (is_array($this->_file->users)) {
869 foreach ($this->_file->users as $g => $u) {
870 $users = explode(' ',$u);
871 if (in_array($this->username,$users)) {
872 $this->membership[$group] = true;
877 $this->membership[$group] = false;
878 if ($this->specialGroup($group))
879 return $this->isSpecialMember($group);
884 * Determines all of the groups of which the current user is a member.
886 * then checks each group to see if the current user is a member.
887 * @param string $group Name of the group to check for membership.
888 * @return array Array of groups to which the user belongs.
890 function getAllGroupsIn(){
891 //$username = $this->_getUserName();
892 $membership = array();
894 if (is_array($this->_file->users)) {
895 foreach ($this->_file->users as $group => $u) {
896 $users = explode(' ',$u);
897 if (in_array($this->username,$users)) {
898 $this->membership[$group] = true;
899 $membership[] = $group;
904 $specialgroups = $this->specialGroups();
905 foreach ($specialgroups as $group) {
906 if ($this->isMember($group)) {
907 $this->membership[$group] = true;
908 $membership[] = $group;
915 * Determines all of the members of a particular group.
917 * Return all the current members.
918 * @param string $group Name of the group to get the full membership list of.
919 * @return array Array of usernames that have joined the group.
921 function getMembersOf($group){
923 if (!empty($this->_file->users[$group])) {
924 $members = explode(' ',$this->_file->users[$group]);
926 if ($this->specialGroup($group)) {
927 $members = array_merge($members, $this->getSpecialMembersOf($group));
934 * Ldap is configured in index.php
938 class GroupLdap extends WikiGroup {
943 * @param object $request The global WikiRequest object.
945 function GroupLdap(){
946 //$this->request = &$GLOBALS['request'];
947 $this->username = $this->_getUserName();
948 $this->membership = array();
950 if (!defined("LDAP_AUTH_HOST")) {
951 trigger_error(sprintf(_("%s not defined"), "LDAP_AUTH_HOST"),
955 // We should ignore multithreaded environments, not generally windows.
957 if (! function_exists('ldap_connect') and (!isWindows() or isCGI())) {
958 // on MacOSX >= 4.3 you'll need PHP_SHLIB_SUFFIX instead.
959 dl("ldap".defined('PHP_SHLIB_SUFFIX') ? PHP_SHLIB_SUFFIX : DLL_EXT);
960 if (! function_exists('ldap_connect')) {
961 trigger_error(_("No LDAP in this PHP version"), E_USER_WARNING);
965 if (!defined("LDAP_BASE_DN"))
966 define("LDAP_BASE_DN",'');
967 $this->base_dn = LDAP_BASE_DN;
968 // if no users ou (organizational unit) is defined,
969 // then take out the ou= from the base_dn (if exists) and append a default
970 // from users and group
972 if (strstr(LDAP_BASE_DN, "ou="))
973 $this->base_dn = preg_replace("/(ou=\w+,)?()/","\$2", LDAP_BASE_DN);
975 if (!isset($this->user) or !isa($this->user, '_LDAPPassUser'))
976 $this->_user = new _LDAPPassUser('LdapGroupTest'); // to have a valid username
978 $this->_user =& $this->user;
982 * Determines if the current user is a member of a group.
985 * @param string $group Name of the group to check for membership.
986 * @return boolean True if user is a member, else false.
988 function isMember($group) {
989 if (isset($this->membership[$group])) {
990 return $this->membership[$group];
992 //$request = $this->request;
993 //$username = $this->_getUserName();
994 $this->membership[$group] = in_array($this->username,$this->getMembersOf($group));
995 if ($this->membership[$group])
997 if ($this->specialGroup($group))
998 return $this->isSpecialMember($group);
1002 * Determines all of the groups of which the current user is a member.
1004 * @param string $group Name of the group to check for membership.
1005 * @return array Array of groups to which the user belongs.
1007 function getAllGroupsIn(){
1008 //$request = &$this->request;
1009 //$username = $this->_getUserName();
1010 $membership = array();
1012 $specialgroups = $this->specialGroups();
1013 foreach ($specialgroups as $group) {
1014 if ($this->isMember($group)) {
1015 $this->membership[$group] = true;
1016 $membership[] = $group;
1020 // must be a valid LDAP server, and username must not contain a wildcard
1021 if ($ldap = $this->_user->_init()) {
1022 $st_search = LDAP_SEARCH_FIELD ? LDAP_SEARCH_FIELD."=".$this->username
1023 : "uid=".$this->username;
1024 $sr = ldap_search($ldap, (LDAP_OU_USERS ? LDAP_OU_USERS : "ou=Users")
1025 .($this->base_dn ? ",".$this->base_dn : ''),
1028 $this->_user->_free();
1029 return $this->membership;
1031 $info = ldap_get_entries($ldap, $sr);
1032 if (empty($info["count"])) {
1033 $this->_user->_free();
1034 return $this->membership;
1036 for ($i = 0; $i < $info["count"]; $i++) {
1037 if ($info[$i]["gidNumber"]["count"]) {
1038 $gid = $info[$i]["gidnumber"][0];
1039 $sr2 = ldap_search($ldap, (LDAP_OU_GROUP ? LDAP_OU_GROUP : "ou=Groups")
1040 .($this->base_dn ? ",".$this->base_dn : ''),
1043 $info2 = ldap_get_entries($ldap, $sr2);
1044 if (!empty($info2["count"]))
1045 $membership[] = $info2[0]["cn"][0];
1050 trigger_error(fmt("Unable to connect to LDAP server %s", LDAP_AUTH_HOST),
1053 $this->_user->_free();
1054 //ldap_close($ldap);
1055 $this->membership = $membership;
1060 * Determines all of the members of a particular group.
1062 * Return all the members of the given group. LDAP just returns the gid of each user
1063 * @param string $group Name of the group to get the full membership list of.
1064 * @return array Array of usernames that have joined the group.
1066 function getMembersOf($group){
1068 if ($ldap = $this->_user->_init()) {
1069 $base_dn = (LDAP_OU_GROUP ? LDAP_OU_GROUP : "ou=Groups")
1070 .($this->base_dn ? ",".$this->base_dn : '');
1071 $sr = ldap_search($ldap, $base_dn, "cn=$group");
1073 $info = ldap_get_entries($ldap, $sr);
1075 $info = array('count' => 0);
1076 trigger_error("LDAP_SEARCH: base=\"$base_dn\" \"(cn=$group)\" failed", E_USER_NOTICE);
1078 $base_dn = (LDAP_OU_USERS ? LDAP_OU_USERS : "ou=Users")
1079 .($this->base_dn ? ",".$this->base_dn : '');
1080 for ($i = 0; $i < $info["count"]; $i++) {
1081 $gid = $info[$i]["gidNumber"][0];
1082 //uid=* would be better probably
1083 $sr2 = ldap_search($ldap, $base_dn, "gidNumber=$gid");
1085 $info2 = ldap_get_entries($ldap, $sr2);
1086 for ($j = 0; $j < $info2["count"]; $j++) {
1087 $members[] = $info2[$j]["cn"][0];
1090 trigger_error("LDAP_SEARCH: base=\"$base_dn\" \"(gidNumber=$gid)\" failed", E_USER_NOTICE);
1094 $this->_user->_free();
1095 //ldap_close($ldap);
1097 if ($this->specialGroup($group)) {
1098 $members = array_merge($members, $this->getSpecialMembersOf($group));
1107 // c-basic-offset: 4
1108 // c-hanging-comment-ender-p: nil
1109 // indent-tabs-mode: nil