diff options
Diffstat (limited to 'lib/plugins/authplain/auth.php')
-rw-r--r-- | lib/plugins/authplain/auth.php | 72 |
1 files changed, 64 insertions, 8 deletions
diff --git a/lib/plugins/authplain/auth.php b/lib/plugins/authplain/auth.php index 8c4ce0dd9..b31c02fc8 100644 --- a/lib/plugins/authplain/auth.php +++ b/lib/plugins/authplain/auth.php @@ -17,6 +17,9 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin { /** @var array filter pattern */ protected $_pattern = array(); + /** @var bool safe version of preg_split */ + protected $_pregsplit_safe = false; + /** * Constructor * @@ -44,6 +47,8 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin { $this->cando['getUsers'] = true; $this->cando['getUserCount'] = true; } + + $this->_pregsplit_safe = version_compare(PCRE_VERSION,'6.7','>='); } /** @@ -76,14 +81,36 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin { * * @author Andreas Gohr <andi@splitbrain.org> * @param string $user - * @return array|bool + * @param bool $requireGroups (optional) ignored by this plugin, grps info always supplied + * @return array|false */ - public function getUserData($user) { + public function getUserData($user, $requireGroups=true) { if($this->users === null) $this->_loadUserData(); return isset($this->users[$user]) ? $this->users[$user] : false; } /** + * Creates a string suitable for saving as a line + * in the file database + * (delimiters escaped, etc.) + * + * @param string $user + * @param string $pass + * @param string $name + * @param string $mail + * @param array $grps list of groups the user is in + * @return string + */ + protected function _createUserLine($user, $pass, $name, $mail, $grps) { + $groups = join(',', $grps); + $userline = array($user, $pass, $name, $mail, $groups); + $userline = str_replace('\\', '\\\\', $userline); // escape \ as \\ + $userline = str_replace(':', '\\:', $userline); // escape : as \: + $userline = join(':', $userline)."\n"; + return $userline; + } + + /** * Create a new User * * Returns false if the user already exists, null when an error @@ -115,8 +142,7 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin { if(!is_array($grps)) $grps = array($conf['defaultgroup']); // prepare user line - $groups = join(',', $grps); - $userline = join(':', array($user, $pass, $name, $mail, $groups))."\n"; + $userline = $this->_createUserLine($user, $pass, $name, $mail, $grps); if(io_saveFile($config_cascade['plainauth.users']['default'], $userline, true)) { $this->users[$user] = compact('pass', 'name', 'mail', 'grps'); @@ -157,8 +183,7 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin { $userinfo[$field] = $value; } - $groups = join(',', $userinfo['grps']); - $userline = join(':', array($newuser, $userinfo['pass'], $userinfo['name'], $userinfo['mail'], $groups))."\n"; + $userline = $this->_createUserLine($newuser, $userinfo['pass'], $userinfo['name'], $userinfo['mail'], $userinfo['grps']); if(!$this->deleteUsers(array($user))) { msg('Unable to modify user data. Please inform the Wiki-Admin', -1); @@ -300,7 +325,7 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin { $this->users = array(); - if(!@file_exists($config_cascade['plainauth.users']['default'])) return; + if(!file_exists($config_cascade['plainauth.users']['default'])) return; $lines = file($config_cascade['plainauth.users']['default']); foreach($lines as $line) { @@ -308,7 +333,11 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin { $line = trim($line); if(empty($line)) continue; - $row = explode(":", $line, 5); + /* NB: preg_split can be deprecated/replaced with str_getcsv once dokuwiki is min php 5.3 */ + $row = $this->_splitUserData($line); + $row = str_replace('\\:', ':', $row); + $row = str_replace('\\\\', '\\', $row); + $groups = array_values(array_filter(explode(",", $row[4]))); $this->users[$row[0]]['pass'] = $row[1]; @@ -318,6 +347,33 @@ class auth_plugin_authplain extends DokuWiki_Auth_Plugin { } } + protected function _splitUserData($line){ + // due to a bug in PCRE 6.6, preg_split will fail with the regex we use here + // refer github issues 877 & 885 + if ($this->_pregsplit_safe){ + return preg_split('/(?<![^\\\\]\\\\)\:/', $line, 5); // allow for : escaped as \: + } + + $row = array(); + $piece = ''; + $len = strlen($line); + for($i=0; $i<$len; $i++){ + if ($line[$i]=='\\'){ + $piece .= $line[$i]; + $i++; + if ($i>=$len) break; + } else if ($line[$i]==':'){ + $row[] = $piece; + $piece = ''; + continue; + } + $piece .= $line[$i]; + } + $row[] = $piece; + + return $row; + } + /** * return true if $user + $info match $filter criteria, false otherwise * |