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'))
28 trigger_error(_("No or unsupported GROUP_METHOD defined"), E_USER_WARNING);
30 /* Special group names for ACL */
31 define('GROUP_EVERY', _("Every"));
32 define('GROUP_ANONYMOUS', _("Anonymous Users"));
33 define('GROUP_BOGOUSER', _("Bogo Users"));
34 define('GROUP_SIGNED', _("Signed Users"));
35 define('GROUP_AUTHENTICATED', _("Authenticated Users"));
36 define('GROUP_ADMIN', _("Administrators"));
37 define('GROUP_OWNER', _("Owner"));
38 define('GROUP_CREATOR', _("Creator"));
41 * WikiGroup is an abstract class to provide the base functions for determining
42 * group membership for a specific user. Some functions are user independent.
44 * Limitation: For the current user only. This must be fixed to be able to query
45 * for membership of any user.
47 * WikiGroup is an abstract class with three functions:
48 * <ol><li />Provide the static method getGroup with will return the proper
50 * <li />Provide an interface for subclasses to implement.
51 * <li />Provide fallover methods (with error msgs) if not impemented in subclass.
53 * Do not ever instantiate this class. Use: $group = &WikiGroup::getGroup();
54 * This will instantiate the proper subclass.
56 * @author Joby Walker <zorloc@imperium.org>
63 /** User object if different from current user */
65 /** The global WikiRequest object */
67 /** Array of groups $username is confirmed to belong to */
69 /** boolean if not the current user */
70 var $not_current = false;
73 * Initializes a WikiGroup object which should never happen. Use:
74 * $group = &WikiGroup::getGroup();
75 * @param object $request The global WikiRequest object -- ignored.
77 function WikiGroup($not_current = false)
79 $this->not_current = $not_current;
80 //$this->request =& $GLOBALS['request'];
84 * Gets the current username from the internal user object
85 * and erases $this->membership if is different than
86 * the stored $this->username
87 * @return string Current username.
89 function _getUserName()
92 $user = (!empty($this->user)) ? $this->user : $request->getUser();
93 $username = $user->getID();
94 if ($username != $this->username) {
95 $this->membership = array();
96 $this->username = $username;
98 if (!$this->not_current)
104 * Static method to return the WikiGroup subclass used in this wiki. Controlled
105 * by the constant GROUP_METHOD.
106 * @param object $request The global WikiRequest object.
107 * @return object Subclass of WikiGroup selected via GROUP_METHOD.
109 function getGroup($not_current = false)
111 switch (GROUP_METHOD) {
113 return new GroupNone($not_current);
116 return new GroupWikiPage($not_current);
119 if ($GLOBALS['DBParams']['dbtype'] == 'ADODB') {
120 return new GroupDB_ADODB($not_current);
121 } elseif ($GLOBALS['DBParams']['dbtype'] == 'SQL') {
122 return new GroupDb_PearDB($not_current);
124 trigger_error("GROUP_METHOD = DB: Unsupported dbtype "
125 . $GLOBALS['DBParams']['dbtype'],
130 return new GroupFile($not_current);
133 return new GroupLDAP($not_current);
136 trigger_error(_("No or unsupported GROUP_METHOD defined"), E_USER_WARNING);
137 return new WikiGroup($not_current);
141 /** ACL PagePermissions will need those special groups based on the User status only.
144 function specialGroup($group)
146 return in_array($group, $this->specialGroups());
150 function _specialGroup($group)
152 return in_array($group, $this->_specialGroups());
156 function specialGroups()
170 function _specialGroups()
184 * Determines if the current user is a member of a group.
186 * This method is an abstraction. The group is ignored, an error is sent, and
187 * false (not a member of the group) is returned.
188 * @param string $group Name of the group to check for membership (ignored).
189 * @return boolean True if user is a member, else false (always false).
191 function isMember($group)
193 if (isset($this->membership[$group]))
194 return $this->membership[$group];
195 if ($this->specialGroup($group)) {
196 return $this->isSpecialMember($group);
198 trigger_error(__sprintf("Method '%s' not implemented in this GROUP_METHOD %s",
199 'isMember', GROUP_METHOD),
205 function isSpecialMember($group)
209 if (isset($this->membership[$group]))
210 return $this->membership[$group];
211 $user = (!empty($this->user)) ? $this->user : $request->getUser();
214 return $this->membership[$group] = true;
215 case GROUP_ANONYMOUS:
216 return $this->membership[$group] = !$user->isSignedIn();
218 return $this->membership[$group] = (isa($user, '_BogoUser')
219 and $user->_level >= WIKIAUTH_BOGO);
221 return $this->membership[$group] = $user->isSignedIn();
222 case GROUP_AUTHENTICATED:
223 return $this->membership[$group] = $user->isAuthenticated();
225 return $this->membership[$group] = (isset($user->_level)
226 and $user->_level == WIKIAUTH_ADMIN);
231 trigger_error(__sprintf("Undefined method %s for special group %s",
239 * Determines all of the groups of which the current user is a member.
241 * This method is an abstraction. An error is sent and an empty
243 * @return array Array of groups to which the user belongs (always empty).
245 function getAllGroupsIn()
247 trigger_error(__sprintf("Method '%s' not implemented in this GROUP_METHOD %s",
248 'getAllGroupsIn', GROUP_METHOD),
255 static $result = array();
260 /* WikiPage users: */
261 $dbh =& $request->_dbi;
262 $page_iter = $dbh->getAllPages();
264 while ($page = $page_iter->next()) {
265 if ($page->isUserPage())
266 $users[] = $page->_pagename;
269 /* WikiDB users from prefs (not from users): */
271 $dbi = _PassUser::getAuthDbh();
275 if ($dbi and $dbh->getAuthParam('pref_select')) {
277 $sql = preg_replace('/SELECT .+ FROM/i', 'SELECT userid FROM',
278 $dbh->getAuthParam('pref_select'));
279 //don't strip WHERE, only the userid stuff.
280 $sql = preg_replace('/(WHERE.*?)\s+\w+\s*=\s*["\']\$userid[\'"]/i', '\\1 AND 1', $sql);
281 $sql = str_replace('WHERE AND 1', '', $sql);
282 if (isa($dbi, 'ADOConnection')) {
283 $db_result = $dbi->Execute($sql);
284 foreach ($db_result->GetArray() as $u) {
285 $users = array_merge($users, array_values($u));
287 } elseif (isa($dbi, 'DB_common')) { // PearDB
288 $users = array_merge($users, $dbi->getCol($sql));
292 /* WikiDB users from users: */
293 // Fixme: don't strip WHERE, only the userid stuff.
294 if ($dbi and $dbh->getAuthParam('auth_user_exists')) {
295 //don't strip WHERE, only the userid stuff.
296 $sql = preg_replace('/(WHERE.*?)\s+\w+\s*=\s*["\']\$userid[\'"]/i', '\\1 AND 1',
297 $dbh->getAuthParam('auth_user_exists'));
298 $sql = str_replace('WHERE AND 1', '', $sql);
299 if (isa($dbi, 'ADOConnection')) {
300 $db_result = $dbi->Execute($sql);
301 foreach ($db_result->GetArray() as $u) {
302 $users = array_merge($users, array_values($u));
304 } elseif (isa($dbi, 'DB_common')) {
305 $users = array_merge($users, $dbi->getCol($sql));
309 // remove empty and duplicate users
311 foreach ($users as $u) {
312 if (empty($u) or in_array($u, $result)) continue;
319 * Determines all of the members of a particular group.
321 * This method is an abstraction. The group is ignored, an error is sent,
322 * and an empty array is returned
323 * @param string $group Name of the group to get the full membership list of.
324 * @return array Array of usernames that have joined the group (always empty).
326 function getMembersOf($group)
328 if ($this->specialGroup($group)) {
329 return $this->getSpecialMembersOf($group);
331 trigger_error(__sprintf("Method '%s' not implemented in this GROUP_METHOD %s",
332 'getMembersOf', GROUP_METHOD),
337 function getSpecialMembersOf($group)
339 //$request = &$this->request;
340 $all = $this->_allUsers();
345 case GROUP_ANONYMOUS:
348 foreach ($all as $u) {
349 if (isWikiWord($u)) $users[] = $u;
353 foreach ($all as $u) {
354 $user = WikiUser($u);
355 if ($user->isSignedIn()) $users[] = $u;
358 case GROUP_AUTHENTICATED:
359 foreach ($all as $u) {
360 $user = WikiUser($u);
361 if ($user->isAuthenticated()) $users[] = $u;
365 foreach ($all as $u) {
366 $user = WikiUser($u);
367 if (isset($user->_level) and $user->_level == WIKIAUTH_ADMIN)
373 // this could get complex so just return an empty array
376 trigger_error(__sprintf("Unknown special group '%s'", $group),
382 * Add the current or specified user to a group.
384 * This method is an abstraction. The group and user are ignored, an error
385 * is sent, and false (not added) is always returned.
386 * @param string $group User added to this group.
387 * @param string $user Username to add to the group (default = current user).
388 * @return bool On true user was added, false if not.
390 function setMemberOf($group, $user = false)
392 trigger_error(__sprintf("Method '%s' not implemented in this GROUP_METHOD %s",
393 'setMemberOf', GROUP_METHOD),
399 * Remove the current or specified user to a group.
401 * This method is an abstraction. The group and user are ignored, and error
402 * is sent, and false (not removed) is always returned.
403 * @param string $group User removed from this group.
404 * @param string $user Username to remove from the group (default = current user).
405 * @return bool On true user was removed, false if not.
407 function removeMemberOf($group, $user = false)
409 trigger_error(__sprintf("Method '%s' not implemented in this GROUP_METHOD %s",
410 'removeMemberOf', GROUP_METHOD),
417 * GroupNone disables all Group funtionality
419 * All of the GroupNone functions return false or empty values to indicate failure or
420 * no results. Use GroupNone if group controls are not desired.
421 * @author Joby Walker <zorloc@imperium.org>
423 class GroupNone extends WikiGroup
429 * Ignores the parameter provided.
430 * @param object $request The global WikiRequest object - ignored.
434 //$this->request = &$GLOBALS['request'];
439 * Determines if the current user is a member of a group.
441 * The group is ignored and false (not a member of the group) is returned.
442 * @param string $group Name of the group to check for membership (ignored).
443 * @return boolean True if user is a member, else false (always false).
445 function isMember($group)
447 if ($this->specialGroup($group)) {
448 return $this->isSpecialMember($group);
455 * Determines all of the groups of which the current user is a member.
457 * The group is ignored and an empty array (a member of no groups) is returned.
458 * @param string $group Name of the group to check for membership (ignored).
459 * @return array Array of groups to which the user belongs (always empty).
461 function getAllGroupsIn()
467 * Determines all of the members of a particular group.
469 * The group is ignored and an empty array (a member of no groups) is returned.
470 * @param string $group Name of the group to check for membership (ignored).
471 * @return array Array of groups user belongs to (always empty).
473 function getMembersOf($group)
481 * GroupWikiPage provides group functionality via pages within the Wiki.
483 * GroupWikiPage is the Wiki way of managing a group. Every group will have
484 * a page. To modify the membership of the group, one only needs to edit the
485 * membership list on the page.
486 * @author Joby Walker <zorloc@imperium.org>
488 class GroupWikiPage extends WikiGroup
494 * Initializes the three superclass instance variables
495 * @param object $request The global WikiRequest object.
497 function GroupWikiPage()
499 //$this->request = &$GLOBALS['request'];
500 $this->username = $this->_getUserName();
501 //$this->username = null;
502 $this->membership = array();
506 * Determines if the current user is a member of a group.
508 * To determine membership in a particular group, this method checks the
509 * superclass instance variable $membership to see if membership has
510 * already been determined. If not, then the group page is parsed to
511 * determine membership.
512 * @param string $group Name of the group to check for membership.
513 * @return boolean True if user is a member, else false.
515 function isMember($group)
517 if (isset($this->membership[$group])) {
518 return $this->membership[$group];
521 $group_page = $request->getPage($group);
522 if ($this->_inGroupPage($group_page)) {
523 $this->membership[$group] = true;
526 $this->membership[$group] = false;
527 // Let grouppages override certain defaults, such as members of admin
528 if ($this->specialGroup($group)) {
529 return $this->isSpecialMember($group);
535 * Private method to take a WikiDB_Page and parse to determine if the
536 * current_user is a member of the group.
537 * @param object $group_page WikiDB_Page object for the group's page
538 * @return boolean True if user is a member, else false.
541 function _inGroupPage($group_page, $strict = false)
543 $group_revision = $group_page->getCurrentRevision();
544 if ($group_revision->hasDefaultContents()) {
545 $group = $group_page->getName();
546 if ($strict) trigger_error(sprintf(_("Group page '%s' does not exist"), $group),
550 $contents = $group_revision->getContent();
551 $match = '/^\s*[\*\#]+\s*\[?' . $this->username . '\]?(\s|$)/';
552 foreach ($contents as $line) {
553 if (preg_match($match, $line)) {
561 * Determines all of the groups of which the current user is a member.
563 * Checks the root Group page ('CategoryGroup') for the list of all groups,
564 * then checks each group to see if the current user is a member.
565 * @param string $group Name of the group to check for membership.
566 * @return array Array of groups to which the user belongs.
568 function getAllGroupsIn()
570 $membership = array();
572 $specialgroups = $this->specialGroups();
573 foreach ($specialgroups as $group) {
574 $this->membership[$group] = $this->isSpecialMember($group);
578 $dbh = &$request->_dbi;
579 $master_page = $request->getPage(CATEGORY_GROUP_PAGE);
580 $master_list = $master_page->getLinks(true);
581 while ($group_page = $master_list->next()) {
582 $group = $group_page->getName();
583 $this->membership[$group] = $this->_inGroupPage($group_page);
585 foreach ($this->membership as $g => $bool) {
586 if ($bool) $membership[] = $g;
592 * Determines all of the members of a particular group.
594 * Checks a group's page to return all the current members. Currently this
595 * method is disabled and triggers an error and returns an empty array.
596 * @param string $group Name of the group to get the full membership list of.
597 * @return array Array of usernames that have joined the group (always empty).
599 function getMembersOf($group)
601 if ($this->specialGroup($group))
602 return $this->getSpecialMembersOf($group);
604 $group_page = $GLOBALS['request']->getPage($group);
605 $group_revision = $group_page->getCurrentRevision();
606 if ($group_revision->hasDefaultContents()) {
607 trigger_error(sprintf(_("Group %s does not exist"), $group), E_USER_WARNING);
610 $contents = $group_revision->getContent();
611 // This is not really a reliable way to check if a string is a username. But better than nothing.
612 $match = '/^(\s*[\*\#]+\s*\[?)(\w+)(\]?\s*)$/';
614 foreach ($contents as $line) {
615 if (preg_match($match, $line, $matches)) {
616 $members[] = $matches[2];
624 * GroupDb is configured by $DbAuthParams[] statements
629 class GroupDb extends WikiGroup
632 var $_is_member, $_group_members, $_user_groups;
637 * @param object $request The global WikiRequest object. ignored
641 global $DBAuthParams, $DBParams;
642 //$this->request = &$GLOBALS['request'];
643 $this->username = $this->_getUserName();
644 $this->membership = array();
646 if (empty($DBAuthParams['group_members']) or
647 empty($DBAuthParams['user_groups']) or
648 empty($DBAuthParams['is_member'])
650 trigger_error(_("No or not enough GROUP_DB SQL statements defined"),
652 return new GroupNone();
654 // FIXME: This only works with ENABLE_USER_NEW
655 if (empty($this->user)) {
656 // use _PassUser::prepare instead
657 if (isa($request->getUser(), '_PassUser'))
658 $user = $request->getUser();
660 $user = new _PassUser($this->username);
661 } elseif (!isa($this->user, '_PassUser')) {
662 $user = new _PassUser($this->username);
664 $user =& $this->user;
666 if (isa($this->user, '_PassUser')) { // TODO: safety by Charles Corrigan
667 $this->_is_member = $user->prepare($DBAuthParams['is_member'],
668 array('userid', 'groupname'));
669 $this->_group_members = $user->prepare($DBAuthParams['group_members'], 'groupname');
670 $this->_user_groups = $user->prepare($DBAuthParams['user_groups'], 'userid');
671 $this->dbh = $user->_auth_dbi;
681 class GroupDb_PearDB extends GroupDb
685 * Determines if the current user is a member of a database group.
687 * @param string $group Name of the group to check for membership.
688 * @return boolean True if user is a member, else false.
690 function isMember($group)
692 if (isset($this->membership[$group])) {
693 return $this->membership[$group];
696 $db_result = $dbh->query(sprintf($this->_is_member,
697 $dbh->quote($this->username),
698 $dbh->quote($group)));
699 if ($db_result->numRows() > 0) {
700 $this->membership[$group] = true;
703 $this->membership[$group] = false;
704 // Let override certain defaults, such as members of admin
705 if ($this->specialGroup($group))
706 return $this->isSpecialMember($group);
711 * Determines all of the groups of which the current user is a member.
713 * then checks each group to see if the current user is a member.
714 * @param string $group Name of the group to check for membership.
715 * @return array Array of groups to which the user belongs.
717 function getAllGroupsIn()
719 $membership = array();
722 $db_result = $dbh->query(sprintf($this->_user_groups, $dbh->quote($this->username)));
723 if ($db_result->numRows() > 0) {
724 while (list($group) = $db_result->fetchRow(DB_FETCHMODE_ORDERED)) {
725 $membership[] = $group;
726 $this->membership[$group] = true;
730 $specialgroups = $this->specialGroups();
731 foreach ($specialgroups as $group) {
732 if ($this->isMember($group)) {
733 $membership[] = $group;
740 * Determines all of the members of a particular group.
742 * Checks a group's page to return all the current members. Currently this
743 * method is disabled and triggers an error and returns an empty array.
744 * @param string $group Name of the group to get the full membership list of.
745 * @return array Array of usernames that have joined the group.
747 function getMembersOf($group)
752 $db_result = $dbh->query(sprintf($this->_group_members, $dbh->quote($group)));
753 if ($db_result->numRows() > 0) {
754 while (list($userid) = $db_result->fetchRow(DB_FETCHMODE_ORDERED)) {
755 $members[] = $userid;
758 // add certain defaults, such as members of admin
759 if ($this->specialGroup($group))
760 $members = array_merge($members, $this->getSpecialMembersOf($group));
770 class GroupDb_ADODB extends GroupDb
774 * Determines if the current user is a member of a database group.
776 * @param string $group Name of the group to check for membership.
777 * @return boolean True if user is a member, else false.
779 function isMember($group)
781 if (isset($this->membership[$group])) {
782 return $this->membership[$group];
785 $rs = $dbh->Execute(sprintf($this->_is_member, $dbh->qstr($this->username),
786 $dbh->qstr($group)));
790 if ($rs->numRows() > 0) {
791 $this->membership[$group] = true;
796 $this->membership[$group] = false;
797 if ($this->specialGroup($group))
798 return $this->isSpecialMember($group);
804 * Determines all of the groups of which the current user is a member.
805 * then checks each group to see if the current user is a member.
807 * @param string $group Name of the group to check for membership.
808 * @return array Array of groups to which the user belongs.
810 function getAllGroupsIn()
812 $membership = array();
815 $rs = $dbh->Execute(sprintf($this->_user_groups, $dbh->qstr($this->username)));
816 if (!$rs->EOF and $rs->numRows() > 0) {
818 $group = reset($rs->fields);
819 $membership[] = $group;
820 $this->membership[$group] = true;
826 $specialgroups = $this->specialGroups();
827 foreach ($specialgroups as $group) {
828 if ($this->isMember($group)) {
829 $membership[] = $group;
836 * Determines all of the members of a particular group.
838 * @param string $group Name of the group to get the full membership list of.
839 * @return array Array of usernames that have joined the group.
841 function getMembersOf($group)
845 $rs = $dbh->Execute(sprintf($this->_group_members, $dbh->qstr($group)));
846 if (!$rs->EOF and $rs->numRows() > 0) {
848 $members[] = reset($rs->fields);
853 // add certain defaults, such as members of admin
854 if ($this->specialGroup($group))
855 $members = array_merge($members, $this->getSpecialMembersOf($group));
861 * GroupFile is configured by AUTH_GROUP_FILE
862 * groupname: user1 user2 ...
866 class GroupFile extends WikiGroup
872 * @param object $request The global WikiRequest object.
876 //$this->request = &$GLOBALS['request'];
877 $this->username = $this->_getUserName();
878 //$this->username = null;
879 $this->membership = array();
881 if (!defined('AUTH_GROUP_FILE')) {
882 trigger_error(sprintf(_("%s: not defined"), "AUTH_GROUP_FILE"),
886 if (!file_exists(AUTH_GROUP_FILE)) {
887 trigger_error(sprintf(_("Cannot open AUTH_GROUP_FILE %s"), AUTH_GROUP_FILE),
891 require_once 'lib/pear/File_Passwd.php';
892 $this->_file = new File_Passwd(AUTH_GROUP_FILE, false, AUTH_GROUP_FILE . ".lock");
896 * Determines if the current user is a member of a group.
898 * To determine membership in a particular group, this method checks the
899 * superclass instance variable $membership to see if membership has
900 * already been determined. If not, then the group file is parsed to
901 * determine membership.
902 * @param string $group Name of the group to check for membership.
903 * @return boolean True if user is a member, else false.
905 function isMember($group)
907 //$request = $this->request;
908 //$username = $this->username;
909 if (isset($this->membership[$group])) {
910 return $this->membership[$group];
913 if (is_array($this->_file->users)) {
914 foreach ($this->_file->users as $g => $u) {
915 $users = explode(' ', $u);
916 if (in_array($this->username, $users)) {
917 $this->membership[$group] = true;
922 $this->membership[$group] = false;
923 if ($this->specialGroup($group))
924 return $this->isSpecialMember($group);
929 * Determines all of the groups of which the current user is a member.
931 * then checks each group to see if the current user is a member.
932 * @param string $group Name of the group to check for membership.
933 * @return array Array of groups to which the user belongs.
935 function getAllGroupsIn()
937 //$username = $this->_getUserName();
938 $membership = array();
940 if (is_array($this->_file->users)) {
941 foreach ($this->_file->users as $group => $u) {
942 $users = explode(' ', $u);
943 if (in_array($this->username, $users)) {
944 $this->membership[$group] = true;
945 $membership[] = $group;
950 $specialgroups = $this->specialGroups();
951 foreach ($specialgroups as $group) {
952 if ($this->isMember($group)) {
953 $this->membership[$group] = true;
954 $membership[] = $group;
961 * Determines all of the members of a particular group.
963 * Return all the current members.
964 * @param string $group Name of the group to get the full membership list of.
965 * @return array Array of usernames that have joined the group.
967 function getMembersOf($group)
970 if (!empty($this->_file->users[$group])) {
971 $members = explode(' ', $this->_file->users[$group]);
973 if ($this->specialGroup($group)) {
974 $members = array_merge($members, $this->getSpecialMembersOf($group));
981 * Ldap is configured in index.php
985 class GroupLdap extends WikiGroup
991 * @param object $request The global WikiRequest object.
995 //$this->request = &$GLOBALS['request'];
996 $this->username = $this->_getUserName();
997 $this->membership = array();
999 if (!defined("LDAP_AUTH_HOST")) {
1000 trigger_error(sprintf(_("%s not defined"), "LDAP_AUTH_HOST"),
1004 // We should ignore multithreaded environments, not generally windows.
1006 if (!function_exists('ldap_connect') and (!isWindows() or isCGI())) {
1007 // on MacOSX >= 4.3 you'll need PHP_SHLIB_SUFFIX instead.
1008 dl("ldap" . defined('PHP_SHLIB_SUFFIX') ? PHP_SHLIB_SUFFIX : DLL_EXT);
1009 if (!function_exists('ldap_connect')) {
1010 trigger_error(_("No LDAP in this PHP version"), E_USER_WARNING);
1014 if (!defined("LDAP_BASE_DN"))
1015 define("LDAP_BASE_DN", '');
1016 $this->base_dn = LDAP_BASE_DN;
1017 // if no users ou (organizational unit) is defined,
1018 // then take out the ou= from the base_dn (if exists) and append a default
1019 // from users and group
1021 if (strstr(LDAP_BASE_DN, "ou="))
1022 $this->base_dn = preg_replace("/(ou=\w+,)?()/", "\$2", LDAP_BASE_DN);
1024 if (!isset($this->user) or !isa($this->user, '_LDAPPassUser'))
1025 $this->_user = new _LDAPPassUser('LdapGroupTest'); // to have a valid username
1027 $this->_user =& $this->user;
1031 * Determines if the current user is a member of a group.
1034 * @param string $group Name of the group to check for membership.
1035 * @return boolean True if user is a member, else false.
1037 function isMember($group)
1039 if (isset($this->membership[$group])) {
1040 return $this->membership[$group];
1042 //$request = $this->request;
1043 //$username = $this->_getUserName();
1044 $this->membership[$group] = in_array($this->username, $this->getMembersOf($group));
1045 if ($this->membership[$group])
1047 if ($this->specialGroup($group))
1048 return $this->isSpecialMember($group);
1052 * Determines all of the groups of which the current user is a member.
1054 * @param string $group Name of the group to check for membership.
1055 * @return array Array of groups to which the user belongs.
1057 function getAllGroupsIn()
1059 //$request = &$this->request;
1060 //$username = $this->_getUserName();
1061 $membership = array();
1063 $specialgroups = $this->specialGroups();
1064 foreach ($specialgroups as $group) {
1065 if ($this->isMember($group)) {
1066 $this->membership[$group] = true;
1067 $membership[] = $group;
1071 // must be a valid LDAP server, and username must not contain a wildcard
1072 if ($ldap = $this->_user->_init()) {
1073 $st_search = LDAP_SEARCH_FIELD ? LDAP_SEARCH_FIELD . "=" . $this->username
1074 : "uid=" . $this->username;
1075 $sr = ldap_search($ldap, (LDAP_OU_USERS ? LDAP_OU_USERS : "ou=Users")
1076 . ($this->base_dn ? "," . $this->base_dn : ''),
1079 $this->_user->_free();
1080 return $this->membership;
1082 $info = ldap_get_entries($ldap, $sr);
1083 if (empty($info["count"])) {
1084 $this->_user->_free();
1085 return $this->membership;
1087 for ($i = 0; $i < $info["count"]; $i++) {
1088 if ($info[$i]["gidNumber"]["count"]) {
1089 $gid = $info[$i]["gidnumber"][0];
1090 $sr2 = ldap_search($ldap, (LDAP_OU_GROUP ? LDAP_OU_GROUP : "ou=Groups")
1091 . ($this->base_dn ? "," . $this->base_dn : ''),
1094 $info2 = ldap_get_entries($ldap, $sr2);
1095 if (!empty($info2["count"]))
1096 $membership[] = $info2[0]["cn"][0];
1101 trigger_error(fmt("Unable to connect to LDAP server %s", LDAP_AUTH_HOST),
1104 $this->_user->_free();
1105 //ldap_close($ldap);
1106 $this->membership = $membership;
1111 * Determines all of the members of a particular group.
1113 * Return all the members of the given group. LDAP just returns the gid of each user
1114 * @param string $group Name of the group to get the full membership list of.
1115 * @return array Array of usernames that have joined the group.
1117 function getMembersOf($group)
1120 if ($ldap = $this->_user->_init()) {
1121 $base_dn = (LDAP_OU_GROUP ? LDAP_OU_GROUP : "ou=Groups")
1122 . ($this->base_dn ? "," . $this->base_dn : '');
1123 $sr = ldap_search($ldap, $base_dn, "cn=$group");
1125 $info = ldap_get_entries($ldap, $sr);
1127 $info = array('count' => 0);
1128 trigger_error("LDAP_SEARCH: base=\"$base_dn\" \"(cn=$group)\" failed", E_USER_NOTICE);
1130 $base_dn = (LDAP_OU_USERS ? LDAP_OU_USERS : "ou=Users")
1131 . ($this->base_dn ? "," . $this->base_dn : '');
1132 for ($i = 0; $i < $info["count"]; $i++) {
1133 $gid = $info[$i]["gidNumber"][0];
1134 //uid=* would be better probably
1135 $sr2 = ldap_search($ldap, $base_dn, "gidNumber=$gid");
1137 $info2 = ldap_get_entries($ldap, $sr2);
1138 for ($j = 0; $j < $info2["count"]; $j++) {
1139 $members[] = $info2[$j]["cn"][0];
1142 trigger_error("LDAP_SEARCH: base=\"$base_dn\" \"(gidNumber=$gid)\" failed", E_USER_NOTICE);
1146 $this->_user->_free();
1147 //ldap_close($ldap);
1149 if ($this->specialGroup($group)) {
1150 $members = array_merge($members, $this->getSpecialMembersOf($group));
1159 // c-basic-offset: 4
1160 // c-hanging-comment-ender-p: nil
1161 // indent-tabs-mode: nil