From f4476bd9b5badd36cd0617d76538e47d9649986b Mon Sep 17 00:00:00 2001 From: Jan Schumann Date: Mon, 20 Feb 2012 19:51:26 +0100 Subject: Refactored auth system: All auth methods are now introduced as plugins. --- lib/plugins/authmysql/auth.php | 946 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 946 insertions(+) create mode 100644 lib/plugins/authmysql/auth.php (limited to 'lib/plugins/authmysql/auth.php') diff --git a/lib/plugins/authmysql/auth.php b/lib/plugins/authmysql/auth.php new file mode 100644 index 000000000..9150d3939 --- /dev/null +++ b/lib/plugins/authmysql/auth.php @@ -0,0 +1,946 @@ + + */ +// must be run within Dokuwiki +if(!defined('DOKU_INC')) die(); + +/** + * MySQLP authentication backend + * + * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) + * @author Andreas Gohr + * @author Chris Smith + * @author Matthias Grimm + * @author Jan Schumann + */ +class auth_plugin_authmysql extends DokuWiki_Auth_Plugin +{ + var $dbcon = 0; + var $dbver = 0; // database version + var $dbrev = 0; // database revision + var $dbsub = 0; // database subrevision + var $cnf = null; + var $defaultgroup = ""; + + /** + * Constructor + * + * checks if the mysql interface is available, otherwise it will + * set the variable $success of the basis class to false + * + * @author Matthias Grimm + */ + function auth_plugin_authmysql() { + global $conf; + $this->cnf = $conf['auth']['mysql']; + + if (method_exists($this, 'auth_basic')) + parent::auth_basic(); + + if(!function_exists('mysql_connect')) { + if ($this->cnf['debug']) + msg("MySQL err: PHP MySQL extension not found.",-1,__LINE__,__FILE__); + $this->success = false; + return; + } + + // default to UTF-8, you rarely want something else + if(!isset($this->cnf['charset'])) $this->cnf['charset'] = 'utf8'; + + $this->defaultgroup = $conf['defaultgroup']; + + // set capabilities based upon config strings set + if (empty($this->cnf['server']) || empty($this->cnf['user']) || + !isset($this->cnf['password']) || empty($this->cnf['database'])){ + if ($this->cnf['debug']) + msg("MySQL err: insufficient configuration.",-1,__LINE__,__FILE__); + $this->success = false; + return; + } + + $this->cando['addUser'] = $this->_chkcnf(array('getUserInfo', + 'getGroups', + 'addUser', + 'getUserID', + 'getGroupID', + 'addGroup', + 'addUserGroup'),true); + $this->cando['delUser'] = $this->_chkcnf(array('getUserID', + 'delUser', + 'delUserRefs'),true); + $this->cando['modLogin'] = $this->_chkcnf(array('getUserID', + 'updateUser', + 'UpdateTarget'),true); + $this->cando['modPass'] = $this->cando['modLogin']; + $this->cando['modName'] = $this->cando['modLogin']; + $this->cando['modMail'] = $this->cando['modLogin']; + $this->cando['modGroups'] = $this->_chkcnf(array('getUserID', + 'getGroups', + 'getGroupID', + 'addGroup', + 'addUserGroup', + 'delGroup', + 'getGroupID', + 'delUserGroup'),true); + /* getGroups is not yet supported + $this->cando['getGroups'] = $this->_chkcnf(array('getGroups', + 'getGroupID'),false); */ + $this->cando['getUsers'] = $this->_chkcnf(array('getUsers', + 'getUserInfo', + 'getGroups'),false); + $this->cando['getUserCount'] = $this->_chkcnf(array('getUsers'),false); + } + + /** + * Check if the given config strings are set + * + * @author Matthias Grimm + * @return bool + */ + function _chkcnf($keys, $wop=false){ + foreach ($keys as $key){ + if (empty($this->cnf[$key])) return false; + } + + /* write operation and lock array filled with tables names? */ + if ($wop && (!is_array($this->cnf['TablesToLock']) || + !count($this->cnf['TablesToLock']))){ + return false; + } + + return true; + } + + /** + * Checks if the given user exists and the given plaintext password + * is correct. Furtheron it might be checked wether the user is + * member of the right group + * + * Depending on which SQL string is defined in the config, password + * checking is done here (getpass) or by the database (passcheck) + * + * @param $user user who would like access + * @param $pass user's clear text password to check + * @return bool + * + * @author Andreas Gohr + * @author Matthias Grimm + */ + function checkPass($user,$pass){ + $rc = false; + + if($this->_openDB()) { + $sql = str_replace('%{user}',$this->_escape($user),$this->cnf['checkPass']); + $sql = str_replace('%{pass}',$this->_escape($pass),$sql); + $sql = str_replace('%{dgroup}',$this->_escape($this->defaultgroup),$sql); + $result = $this->_queryDB($sql); + + if($result !== false && count($result) == 1) { + if($this->cnf['forwardClearPass'] == 1) + $rc = true; + else + $rc = auth_verifyPassword($pass,$result[0]['pass']); + } + $this->_closeDB(); + } + return $rc; + } + + /** + * [public function] + * + * Returns info about the given user needs to contain + * at least these fields: + * name string full name of the user + * mail string email addres of the user + * grps array list of groups the user is in + * + * @param $user user's nick to get data for + * + * @author Andreas Gohr + * @author Matthias Grimm + */ + function getUserData($user){ + if($this->_openDB()) { + $this->_lockTables("READ"); + $info = $this->_getUserInfo($user); + $this->_unlockTables(); + $this->_closeDB(); + } else + $info = false; + return $info; + } + + /** + * [public function] + * + * Create a new User. Returns false if the user already exists, + * null when an error occurred and true if everything went well. + * + * The new user will be added to the default group by this + * function if grps are not specified (default behaviour). + * + * @param $user nick of the user + * @param $pwd clear text password + * @param $name full name of the user + * @param $mail email address + * @param $grps array of groups the user should become member of + * + * @author Andreas Gohr + * @author Chris Smith + * @author Matthias Grimm + */ + function createUser($user,$pwd,$name,$mail,$grps=null){ + if($this->_openDB()) { + if (($info = $this->_getUserInfo($user)) !== false) + return false; // user already exists + + // set defaultgroup if no groups were given + if ($grps == null) + $grps = array($this->defaultgroup); + + $this->_lockTables("WRITE"); + $pwd = $this->cnf['forwardClearPass'] ? $pwd : auth_cryptPassword($pwd); + $rc = $this->_addUser($user,$pwd,$name,$mail,$grps); + $this->_unlockTables(); + $this->_closeDB(); + if ($rc) return true; + } + return null; // return error + } + + /** + * Modify user data [public function] + * + * An existing user dataset will be modified. Changes are given in an array. + * + * The dataset update will be rejected if the user name should be changed + * to an already existing one. + * + * The password must be provides unencrypted. Pasword cryption is done + * automatically if configured. + * + * If one or more groups could't be updated, an error would be set. In + * this case the dataset might already be changed and we can't rollback + * the changes. Transactions would be really usefull here. + * + * modifyUser() may be called without SQL statements defined that are + * needed to change group membership (for example if only the user profile + * should be modified). In this case we asure that we don't touch groups + * even $changes['grps'] is set by mistake. + * + * @param $user nick of the user to be changed + * @param $changes array of field/value pairs to be changed (password + * will be clear text) + * @return bool true on success, false on error + * + * @author Chris Smith + * @author Matthias Grimm + */ + function modifyUser($user, $changes) { + $rc = false; + + if (!is_array($changes) || !count($changes)) + return true; // nothing to change + + if($this->_openDB()) { + $this->_lockTables("WRITE"); + + if (($uid = $this->_getUserID($user))) { + $rc = $this->_updateUserInfo($changes, $uid); + + if ($rc && isset($changes['grps']) && $this->cando['modGroups']) { + $groups = $this->_getGroups($user); + $grpadd = array_diff($changes['grps'], $groups); + $grpdel = array_diff($groups, $changes['grps']); + + foreach($grpadd as $group) + if (($this->_addUserToGroup($user, $group, 1)) == false) + $rc = false; + + foreach($grpdel as $group) + if (($this->_delUserFromGroup($user, $group)) == false) + $rc = false; + } + } + + $this->_unlockTables(); + $this->_closeDB(); + } + return $rc; + } + + /** + * [public function] + * + * Remove one or more users from the list of registered users + * + * @param array $users array of users to be deleted + * @return int the number of users deleted + * + * @author Christopher Smith + * @author Matthias Grimm + */ + function deleteUsers($users) { + $count = 0; + + if($this->_openDB()) { + if (is_array($users) && count($users)) { + $this->_lockTables("WRITE"); + foreach ($users as $user) { + if ($this->_delUser($user)) + $count++; + } + $this->_unlockTables(); + } + $this->_closeDB(); + } + return $count; + } + + /** + * [public function] + * + * Counts users which meet certain $filter criteria. + * + * @param array $filter filter criteria in item/pattern pairs + * @return count of found users. + * + * @author Matthias Grimm + */ + function getUserCount($filter=array()) { + $rc = 0; + + if($this->_openDB()) { + $sql = $this->_createSQLFilter($this->cnf['getUsers'], $filter); + + if ($this->dbver >= 4) { + $sql = substr($sql, 6); /* remove 'SELECT' or 'select' */ + $sql = "SELECT SQL_CALC_FOUND_ROWS".$sql." LIMIT 1"; + $this->_queryDB($sql); + $result = $this->_queryDB("SELECT FOUND_ROWS()"); + $rc = $result[0]['FOUND_ROWS()']; + } else if (($result = $this->_queryDB($sql))) + $rc = count($result); + + $this->_closeDB(); + } + return $rc; + } + + /** + * Bulk retrieval of user data. [public function] + * + * @param first index of first user to be returned + * @param limit max number of users to be returned + * @param filter array of field/pattern pairs + * @return array of userinfo (refer getUserData for internal userinfo details) + * + * @author Matthias Grimm + */ + function retrieveUsers($first=0,$limit=10,$filter=array()) { + $out = array(); + + if($this->_openDB()) { + $this->_lockTables("READ"); + $sql = $this->_createSQLFilter($this->cnf['getUsers'], $filter); + $sql .= " ".$this->cnf['SortOrder']." LIMIT $first, $limit"; + $result = $this->_queryDB($sql); + + if (!empty($result)) { + foreach ($result as $user) + if (($info = $this->_getUserInfo($user['user']))) + $out[$user['user']] = $info; + } + + $this->_unlockTables(); + $this->_closeDB(); + } + return $out; + } + + /** + * Give user membership of a group [public function] + * + * @param $user + * @param $group + * @return bool true on success, false on error + * + * @author Matthias Grimm + */ + function joinGroup($user, $group) { + $rc = false; + + if ($this->_openDB()) { + $this->_lockTables("WRITE"); + $rc = $this->_addUserToGroup($user, $group); + $this->_unlockTables(); + $this->_closeDB(); + } + return $rc; + } + + /** + * Remove user from a group [public function] + * + * @param $user user that leaves a group + * @param $group group to leave + * @return bool + * + * @author Matthias Grimm + */ + function leaveGroup($user, $group) { + $rc = false; + + if ($this->_openDB()) { + $this->_lockTables("WRITE"); + $uid = $this->_getUserID($user); + $rc = $this->_delUserFromGroup($user, $group); + $this->_unlockTables(); + $this->_closeDB(); + } + return $rc; + } + + /** + * MySQL is case-insensitive + */ + function isCaseSensitive(){ + return false; + } + + /** + * Adds a user to a group. + * + * If $force is set to '1' non existing groups would be created. + * + * The database connection must already be established. Otherwise + * this function does nothing and returns 'false'. It is strongly + * recommended to call this function only after all participating + * tables (group and usergroup) have been locked. + * + * @param $user user to add to a group + * @param $group name of the group + * @param $force '1' create missing groups + * @return bool 'true' on success, 'false' on error + * + * @author Matthias Grimm + */ + function _addUserToGroup($user, $group, $force=0) { + $newgroup = 0; + + if (($this->dbcon) && ($user)) { + $gid = $this->_getGroupID($group); + if (!$gid) { + if ($force) { // create missing groups + $sql = str_replace('%{group}',$this->_escape($group),$this->cnf['addGroup']); + $gid = $this->_modifyDB($sql); + $newgroup = 1; // group newly created + } + if (!$gid) return false; // group didn't exist and can't be created + } + + $sql = $this->cnf['addUserGroup']; + if(strpos($sql,'%{uid}') !== false){ + $uid = $this->_getUserID($user); + $sql = str_replace('%{uid}', $this->_escape($uid),$sql); + } + $sql = str_replace('%{user}', $this->_escape($user),$sql); + $sql = str_replace('%{gid}', $this->_escape($gid),$sql); + $sql = str_replace('%{group}',$this->_escape($group),$sql); + if ($this->_modifyDB($sql) !== false) return true; + + if ($newgroup) { // remove previously created group on error + $sql = str_replace('%{gid}', $this->_escape($gid),$this->cnf['delGroup']); + $sql = str_replace('%{group}',$this->_escape($group),$sql); + $this->_modifyDB($sql); + } + } + return false; + } + + /** + * Remove user from a group + * + * @param $user user that leaves a group + * @param $group group to leave + * @return bool true on success, false on error + * + * @author Matthias Grimm + */ + function _delUserFromGroup($user, $group) { + $rc = false; + + + if (($this->dbcon) && ($user)) { + $sql = $this->cnf['delUserGroup']; + if(strpos($sql,'%{uid}') !== false){ + $uid = $this->_getUserID($user); + $sql = str_replace('%{uid}', $this->_escape($uid),$sql); + } + $gid = $this->_getGroupID($group); + if ($gid) { + $sql = str_replace('%{user}', $this->_escape($user),$sql); + $sql = str_replace('%{gid}', $this->_escape($gid),$sql); + $sql = str_replace('%{group}',$this->_escape($group),$sql); + $rc = $this->_modifyDB($sql) == 0 ? true : false; + } + } + return $rc; + } + + /** + * Retrieves a list of groups the user is a member off. + * + * The database connection must already be established + * for this function to work. Otherwise it will return + * 'false'. + * + * @param $user user whose groups should be listed + * @return bool false on error + * @return array array containing all groups on success + * + * @author Matthias Grimm + */ + function _getGroups($user) { + $groups = array(); + + if($this->dbcon) { + $sql = str_replace('%{user}',$this->_escape($user),$this->cnf['getGroups']); + $result = $this->_queryDB($sql); + + if($result !== false && count($result)) { + foreach($result as $row) + $groups[] = $row['group']; + } + return $groups; + } + return false; + } + + /** + * Retrieves the user id of a given user name + * + * The database connection must already be established + * for this function to work. Otherwise it will return + * 'false'. + * + * @param $user user whose id is desired + * @return user id + * + * @author Matthias Grimm + */ + function _getUserID($user) { + if($this->dbcon) { + $sql = str_replace('%{user}',$this->_escape($user),$this->cnf['getUserID']); + $result = $this->_queryDB($sql); + return $result === false ? false : $result[0]['id']; + } + return false; + } + + /** + * Adds a new User to the database. + * + * The database connection must already be established + * for this function to work. Otherwise it will return + * 'false'. + * + * @param $user login of the user + * @param $pwd encrypted password + * @param $name full name of the user + * @param $mail email address + * @param $grps array of groups the user should become member of + * @return bool + * + * @author Andreas Gohr + * @author Chris Smith + * @author Matthias Grimm + */ + function _addUser($user,$pwd,$name,$mail,$grps){ + if($this->dbcon && is_array($grps)) { + $sql = str_replace('%{user}', $this->_escape($user),$this->cnf['addUser']); + $sql = str_replace('%{pass}', $this->_escape($pwd),$sql); + $sql = str_replace('%{name}', $this->_escape($name),$sql); + $sql = str_replace('%{email}',$this->_escape($mail),$sql); + $uid = $this->_modifyDB($sql); + + if ($uid) { + foreach($grps as $group) { + $gid = $this->_addUserToGroup($user, $group, 1); + if ($gid === false) break; + } + + if ($gid) return true; + else { + /* remove the new user and all group relations if a group can't + * be assigned. Newly created groups will remain in the database + * and won't be removed. This might create orphaned groups but + * is not a big issue so we ignore this problem here. + */ + $this->_delUser($user); + if ($this->cnf['debug']) + msg ("MySQL err: Adding user '$user' to group '$group' failed.",-1,__LINE__,__FILE__); + } + } + } + return false; + } + + /** + * Deletes a given user and all his group references. + * + * The database connection must already be established + * for this function to work. Otherwise it will return + * 'false'. + * + * @param $user user whose id is desired + * @return bool + * + * @author Matthias Grimm + */ + function _delUser($user) { + if($this->dbcon) { + $uid = $this->_getUserID($user); + if ($uid) { + $sql = str_replace('%{uid}',$this->_escape($uid),$this->cnf['delUserRefs']); + $this->_modifyDB($sql); + $sql = str_replace('%{uid}',$this->_escape($uid),$this->cnf['delUser']); + $sql = str_replace('%{user}', $this->_escape($user),$sql); + $this->_modifyDB($sql); + return true; + } + } + return false; + } + + /** + * getUserInfo + * + * Gets the data for a specific user The database connection + * must already be established for this function to work. + * Otherwise it will return 'false'. + * + * @param $user user's nick to get data for + * @return bool false on error + * @return array user info on success + * + * @author Matthias Grimm + */ + function _getUserInfo($user){ + $sql = str_replace('%{user}',$this->_escape($user),$this->cnf['getUserInfo']); + $result = $this->_queryDB($sql); + if($result !== false && count($result)) { + $info = $result[0]; + $info['grps'] = $this->_getGroups($user); + return $info; + } + return false; + } + + /** + * Updates the user info in the database + * + * Update a user data structure in the database according changes + * given in an array. The user name can only be changes if it didn't + * exists already. If the new user name exists the update procedure + * will be aborted. The database keeps unchanged. + * + * The database connection has already to be established for this + * function to work. Otherwise it will return 'false'. + * + * The password will be crypted if necessary. + * + * @param $changes array of items to change as pairs of item and value + * @param $uid user id of dataset to change, must be unique in DB + * @return true on success or false on error + * + * @author Matthias Grimm + */ + function _updateUserInfo($changes, $uid) { + $sql = $this->cnf['updateUser']." "; + $cnt = 0; + $err = 0; + + if($this->dbcon) { + foreach ($changes as $item => $value) { + if ($item == 'user') { + if (($this->_getUserID($changes['user']))) { + $err = 1; /* new username already exists */ + break; /* abort update */ + } + if ($cnt++ > 0) $sql .= ", "; + $sql .= str_replace('%{user}',$value,$this->cnf['UpdateLogin']); + } else if ($item == 'name') { + if ($cnt++ > 0) $sql .= ", "; + $sql .= str_replace('%{name}',$value,$this->cnf['UpdateName']); + } else if ($item == 'pass') { + if (!$this->cnf['forwardClearPass']) + $value = auth_cryptPassword($value); + if ($cnt++ > 0) $sql .= ", "; + $sql .= str_replace('%{pass}',$value,$this->cnf['UpdatePass']); + } else if ($item == 'mail') { + if ($cnt++ > 0) $sql .= ", "; + $sql .= str_replace('%{email}',$value,$this->cnf['UpdateEmail']); + } + } + + if ($err == 0) { + if ($cnt > 0) { + $sql .= " ".str_replace('%{uid}', $uid, $this->cnf['UpdateTarget']); + if(get_class($this) == 'auth_mysql') $sql .= " LIMIT 1"; //some PgSQL inheritance comp. + $this->_modifyDB($sql); + } + return true; + } + } + return false; + } + + /** + * Retrieves the group id of a given group name + * + * The database connection must already be established + * for this function to work. Otherwise it will return + * 'false'. + * + * @param $group group name which id is desired + * @return group id + * + * @author Matthias Grimm + */ + function _getGroupID($group) { + if($this->dbcon) { + $sql = str_replace('%{group}',$this->_escape($group),$this->cnf['getGroupID']); + $result = $this->_queryDB($sql); + return $result === false ? false : $result[0]['id']; + } + return false; + } + + /** + * Opens a connection to a database and saves the handle for further + * usage in the object. The successful call to this functions is + * essential for most functions in this object. + * + * @return bool + * + * @author Matthias Grimm + */ + function _openDB() { + if (!$this->dbcon) { + $con = @mysql_connect ($this->cnf['server'], $this->cnf['user'], $this->cnf['password']); + if ($con) { + if ((mysql_select_db($this->cnf['database'], $con))) { + if ((preg_match("/^(\d+)\.(\d+)\.(\d+).*/", mysql_get_server_info ($con), $result)) == 1) { + $this->dbver = $result[1]; + $this->dbrev = $result[2]; + $this->dbsub = $result[3]; + } + $this->dbcon = $con; + if(!empty($this->cnf['charset'])){ + mysql_query('SET CHARACTER SET "' . $this->cnf['charset'] . '"', $con); + } + return true; // connection and database successfully opened + } else { + mysql_close ($con); + if ($this->cnf['debug']) + msg("MySQL err: No access to database {$this->cnf['database']}.",-1,__LINE__,__FILE__); + } + } else if ($this->cnf['debug']) + msg ("MySQL err: Connection to {$this->cnf['user']}@{$this->cnf['server']} not possible.", + -1,__LINE__,__FILE__); + + return false; // connection failed + } + return true; // connection already open + } + + /** + * Closes a database connection. + * + * @author Matthias Grimm + */ + function _closeDB() { + if ($this->dbcon) { + mysql_close ($this->dbcon); + $this->dbcon = 0; + } + } + + /** + * Sends a SQL query to the database and transforms the result into + * an associative array. + * + * This function is only able to handle queries that returns a + * table such as SELECT. + * + * @param $query SQL string that contains the query + * @return array with the result table + * + * @author Matthias Grimm + */ + function _queryDB($query) { + if($this->cnf['debug'] >= 2){ + msg('MySQL query: '.hsc($query),0,__LINE__,__FILE__); + } + + $resultarray = array(); + if ($this->dbcon) { + $result = @mysql_query($query,$this->dbcon); + if ($result) { + while (($t = mysql_fetch_assoc($result)) !== false) + $resultarray[]=$t; + mysql_free_result ($result); + return $resultarray; + } + if ($this->cnf['debug']) + msg('MySQL err: '.mysql_error($this->dbcon),-1,__LINE__,__FILE__); + } + return false; + } + + /** + * Sends a SQL query to the database + * + * This function is only able to handle queries that returns + * either nothing or an id value such as INPUT, DELETE, UPDATE, etc. + * + * @param $query SQL string that contains the query + * @return insert id or 0, false on error + * + * @author Matthias Grimm + */ + function _modifyDB($query) { + if ($this->dbcon) { + $result = @mysql_query($query,$this->dbcon); + if ($result) { + $rc = mysql_insert_id($this->dbcon); //give back ID on insert + if ($rc !== false) return $rc; + } + if ($this->cnf['debug']) + msg('MySQL err: '.mysql_error($this->dbcon),-1,__LINE__,__FILE__); + } + return false; + } + + /** + * Locked a list of tables for exclusive access so that modifications + * to the database can't be disturbed by other threads. The list + * could be set with $conf['auth']['mysql']['TablesToLock'] = array() + * + * If aliases for tables are used in SQL statements, also this aliases + * must be locked. For eg. you use a table 'user' and the alias 'u' in + * some sql queries, the array must looks like this (order is important): + * array("user", "user AS u"); + * + * MySQL V3 is not able to handle transactions with COMMIT/ROLLBACK + * so that this functionality is simulated by this function. Nevertheless + * it is not as powerful as transactions, it is a good compromise in safty. + * + * @param $mode could be 'READ' or 'WRITE' + * + * @author Matthias Grimm + */ + function _lockTables($mode) { + if ($this->dbcon) { + if (is_array($this->cnf['TablesToLock']) && !empty($this->cnf['TablesToLock'])) { + if ($mode == "READ" || $mode == "WRITE") { + $sql = "LOCK TABLES "; + $cnt = 0; + foreach ($this->cnf['TablesToLock'] as $table) { + if ($cnt++ != 0) $sql .= ", "; + $sql .= "$table $mode"; + } + $this->_modifyDB($sql); + return true; + } + } + } + return false; + } + + /** + * Unlock locked tables. All existing locks of this thread will be + * abrogated. + * + * @author Matthias Grimm + */ + function _unlockTables() { + if ($this->dbcon) { + $this->_modifyDB("UNLOCK TABLES"); + return true; + } + return false; + } + + /** + * Transforms the filter settings in an filter string for a SQL database + * The database connection must already be established, otherwise the + * original SQL string without filter criteria will be returned. + * + * @param $sql SQL string to which the $filter criteria should be added + * @param $filter array of filter criteria as pairs of item and pattern + * @return SQL string with attached $filter criteria on success + * @return the original SQL string on error. + * + * @author Matthias Grimm + */ + function _createSQLFilter($sql, $filter) { + $SQLfilter = ""; + $cnt = 0; + + if ($this->dbcon) { + foreach ($filter as $item => $pattern) { + $tmp = '%'.$this->_escape($pattern).'%'; + if ($item == 'user') { + if ($cnt++ > 0) $SQLfilter .= " AND "; + $SQLfilter .= str_replace('%{user}',$tmp,$this->cnf['FilterLogin']); + } else if ($item == 'name') { + if ($cnt++ > 0) $SQLfilter .= " AND "; + $SQLfilter .= str_replace('%{name}',$tmp,$this->cnf['FilterName']); + } else if ($item == 'mail') { + if ($cnt++ > 0) $SQLfilter .= " AND "; + $SQLfilter .= str_replace('%{email}',$tmp,$this->cnf['FilterEmail']); + } else if ($item == 'grps') { + if ($cnt++ > 0) $SQLfilter .= " AND "; + $SQLfilter .= str_replace('%{group}',$tmp,$this->cnf['FilterGroup']); + } + } + + // we have to check SQLfilter here and must not use $cnt because if + // any of cnf['Filter????'] is not defined, a malformed SQL string + // would be generated. + + if (strlen($SQLfilter)) { + $glue = strpos(strtolower($sql),"where") ? " AND " : " WHERE "; + $sql = $sql.$glue.$SQLfilter; + } + } + + return $sql; + } + + /** + * Escape a string for insertion into the database + * + * @author Andreas Gohr + * @param string $string The string to escape + * @param boolean $like Escape wildcard chars as well? + */ + function _escape($string,$like=false){ + if($this->dbcon){ + $string = mysql_real_escape_string($string, $this->dbcon); + }else{ + $string = addslashes($string); + } + if($like){ + $string = addcslashes($string,'%_'); + } + return $string; + } +} \ No newline at end of file -- cgit v1.2.3