[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

(PRSC) dokuwiki update for stable and oldstable



Hello,

I have an update for the package dokuwiki in stable and oldstable, to
apply an upstream security fix for an ACL bypass.

The packages are here:
http://tanguy.ortolo.eu/deb/dokuwiki/dokuwiki_0.0.20080505-4+lenny2.dsc
http://tanguy.ortolo.eu/deb/dokuwiki/dokuwiki_0.0.20091225c-10+squeeze1.dsc

I attach to this message the corresponding diffs with the versions
currently in the archive. As the modification consists in introducing a
patch, I also attach this patch as it may be more readable than a
“square-patch”.

Basically, this change is a backport from an upstream commit. It applies
nicely to the version from stable, but only partly to the version from
oldstable, because some of the functions it patches were not yet
present. You may notice that I also added one word to the README.Debian:
this is a spelling error that was detected by lintian, I hope it is not
a problem for a stable update.

I think I missed a point release dealine, sorry for this…

Regards,

-- 
 ,--.
: /` )   Tanguy Ortolo <xmpp:tanguy@ortolo.eu> <irc://irc.oftc.net/Elessar>
| `-'    Debian Maintainer
 \_
diff -Nru dokuwiki-0.0.20091225c-10/debian/changelog dokuwiki-0.0.20091225c-10+squeeze1/debian/changelog
--- dokuwiki-0.0.20091225c-10/debian/changelog	2011-03-16 20:20:13.000000000 +0100
+++ dokuwiki-0.0.20091225c-10+squeeze1/debian/changelog	2011-03-16 21:03:49.000000000 +0100
@@ -1,3 +1,11 @@
+dokuwiki (0.0.20091225c-10+squeeze1) stable; urgency=low
+
+  * debian/README.Debian: Correct a spelling error.
+  * debian/patches/xmlrpc_security.diff: Backport an upstream security fix for
+    an ACL bypass (TEMP-0000000-52FF39).
+
+ -- Tanguy Ortolo <tanguy+debian@ortolo.eu>  Wed, 16 Mar 2011 21:02:46 +0100
+
 dokuwiki (0.0.20091225c-10) unstable; urgency=low
 
   * debian/po/ja.po: debconf template translation update
diff -Nru dokuwiki-0.0.20091225c-10/debian/patches/series dokuwiki-0.0.20091225c-10+squeeze1/debian/patches/series
--- dokuwiki-0.0.20091225c-10/debian/patches/series	2011-03-16 20:20:13.000000000 +0100
+++ dokuwiki-0.0.20091225c-10+squeeze1/debian/patches/series	2011-03-16 21:02:43.000000000 +0100
@@ -1,3 +1,4 @@
+xmlrpc_security.diff
 use_packaged_simplepie.diff
 use_packaged_php-geshi_SA32559.diff
 posts-are-public-domain-by-default.diff
diff -Nru dokuwiki-0.0.20091225c-10/debian/patches/xmlrpc_security.diff dokuwiki-0.0.20091225c-10+squeeze1/debian/patches/xmlrpc_security.diff
--- dokuwiki-0.0.20091225c-10/debian/patches/xmlrpc_security.diff	1970-01-01 01:00:00.000000000 +0100
+++ dokuwiki-0.0.20091225c-10+squeeze1/debian/patches/xmlrpc_security.diff	2011-03-16 21:02:43.000000000 +0100
@@ -0,0 +1,123 @@
+Author: Michael Hamann <michael@content-space.de>
+Author: Tanguy Ortolo <tanguy+debian@ortolo.eu>
+Origin: upstream, https://github.com/splitbrain/dokuwiki/commit/29af721754761e8b633e346fefc6e1067150d83c
+Last-Update: 2011-03-02
+Description: Fix several security issues in the XML-RPC interface
+    .
+    For locks and getRevisions there hasn't been any acl check. In many
+    other cases the id hadn't been cleaned before the acl check was done
+    which means that many acl rules that should be applied weren't applied.
+    So e.g. when you have read permissions for the root namespace but not
+    for a subnamespace you could add a leading ":" and the permissions for
+    the root namespace will be used instead of the permissions for the
+    subnamespace. This did not apply to writing pages and reading media
+    files, but writing and deleting media files have been concerned as well
+    as reading both plain and html versions of pages.
+    .
+    This only concerns installations where XML-RPC is enabled (default is
+    disabled) and XML-RPC is allowed for all or untrusted users.
+
+Index: dokuwiki/lib/exe/xmlrpc.php
+===================================================================
+--- dokuwiki.orig/lib/exe/xmlrpc.php	2011-03-02 21:26:55.211171043 +0100
++++ dokuwiki/lib/exe/xmlrpc.php	2011-03-02 21:27:41.397079790 +0100
+@@ -278,6 +278,7 @@
+      * Return a raw wiki page
+      */
+     function rawPage($id,$rev=''){
++        $id = cleanID($id);
+         if(auth_quickaclcheck($id) < AUTH_READ){
+             return new IXR_Error(1, 'You are not allowed to read this page');
+         }
+@@ -334,6 +335,7 @@
+      * Return a wiki page rendered to html
+      */
+     function htmlPage($id,$rev=''){
++        $id = cleanID($id);
+         if(auth_quickaclcheck($id) < AUTH_READ){
+             return new IXR_Error(1, 'You are not allowed to read this page');
+         }
+@@ -434,6 +436,7 @@
+      * Return some basic data about a page
+      */
+     function pageInfo($id,$rev=''){
++        $id = cleanID($id);
+         if(auth_quickaclcheck($id) < AUTH_READ){
+             return new IXR_Error(1, 'You are not allowed to read this page');
+         }
+@@ -538,6 +541,7 @@
+      * Michael Klier <chi@chimeric.de>
+      */
+     function putAttachment($id, $file, $params) {
++        $id = cleanID($id);
+         global $conf;
+         global $lang;
+ 
+@@ -607,6 +611,7 @@
+      * @author Gina Haeussge <osd@foosel.net>
+      */
+     function deleteAttachment($id){
++        $id = cleanID($id);
+         $auth = auth_quickaclcheck(getNS($id).':*');
+         if($auth < AUTH_DELETE) return new IXR_ERROR(1, "You don't have permissions to delete files.");
+         global $conf;
+@@ -667,6 +672,7 @@
+     * Returns the permissions of a given wiki page
+     */
+     function aclCheck($id) {
++        $id = cleanID($id);
+         return auth_quickaclcheck($id);
+     }
+ 
+@@ -676,13 +682,14 @@
+      * @author Michael Klier <chi@chimeric.de>
+      */
+     function listLinks($id) {
++        $id = cleanID($id);
+         if(auth_quickaclcheck($id) < AUTH_READ){
+             return new IXR_Error(1, 'You are not allowed to read this page');
+         }
+         $links = array();
+ 
+         // resolve page instructions
+-        $ins   = p_cached_instructions(wikiFN(cleanID($id)));
++        $ins   = p_cached_instructions(wikiFN($id));
+ 
+         // instantiate new Renderer - needed for interwiki links
+         include(DOKU_INC.'inc/parser/xhtml.php');
+@@ -796,6 +803,10 @@
+      * @author Michael Klier <chi@chimeric.de>
+      */
+     function pageVersions($id, $first) {
++        $id = cleanID($id);
++        if(auth_quickaclcheck($id) < AUTH_READ){
++            return new IXR_Error(1, 'You are not allowed to read this page');
++        }
+         global $conf;
+ 
+         $versions = array();
+@@ -873,7 +884,8 @@
+         $unlockfail = array();
+ 
+         foreach((array) $set['lock'] as $id){
+-            if(checklock($id)){
++            $id = cleanID($id);
++            if(auth_quickaclcheck($id) < AUTH_EDIT || checklock($id)){
+                 $lockfail[] = $id;
+             }else{
+                 lock($id);
+@@ -882,10 +894,11 @@
+         }
+ 
+         foreach((array) $set['unlock'] as $id){
+-            if(unlock($id)){
+-                $unlocked[] = $id;
+-            }else{
++            $id = cleanID($id);
++            if(auth_quickaclcheck($id) < AUTH_EDIT || !unlock($id)){
+                 $unlockfail[] = $id;
++            }else{
++                $unlocked[] = $id;
+             }
+         }
+ 
diff -Nru dokuwiki-0.0.20091225c-10/debian/README.Debian dokuwiki-0.0.20091225c-10+squeeze1/debian/README.Debian
--- dokuwiki-0.0.20091225c-10/debian/README.Debian	2011-03-16 20:20:13.000000000 +0100
+++ dokuwiki-0.0.20091225c-10+squeeze1/debian/README.Debian	2011-03-16 21:02:43.000000000 +0100
@@ -23,7 +23,7 @@
 Multiple uploader tool
 ----------------------
 
-DokuWiki originally comes with a Flash-based tool that allows to upload several
+DokuWiki originally comes with a Flash-based tool that allows one to upload several
 files at a time to a wiki <http://www.dokuwiki.org/multiuploader>. However,
 that tool violates the Debian Policy, as stated in the bug #592593. That is
 why this tool is not shipped with the Debian package anymore.
diff -Nru dokuwiki-0.0.20091225c-10/lib/exe/xmlrpc.php dokuwiki-0.0.20091225c-10+squeeze1/lib/exe/xmlrpc.php
--- dokuwiki-0.0.20091225c-10/lib/exe/xmlrpc.php	2010-01-17 11:35:46.000000000 +0100
+++ dokuwiki-0.0.20091225c-10+squeeze1/lib/exe/xmlrpc.php	2011-03-16 21:05:09.000000000 +0100
@@ -278,6 +278,7 @@
      * Return a raw wiki page
      */
     function rawPage($id,$rev=''){
+        $id = cleanID($id);
         if(auth_quickaclcheck($id) < AUTH_READ){
             return new IXR_Error(1, 'You are not allowed to read this page');
         }
@@ -334,6 +335,7 @@
      * Return a wiki page rendered to html
      */
     function htmlPage($id,$rev=''){
+        $id = cleanID($id);
         if(auth_quickaclcheck($id) < AUTH_READ){
             return new IXR_Error(1, 'You are not allowed to read this page');
         }
@@ -434,6 +436,7 @@
      * Return some basic data about a page
      */
     function pageInfo($id,$rev=''){
+        $id = cleanID($id);
         if(auth_quickaclcheck($id) < AUTH_READ){
             return new IXR_Error(1, 'You are not allowed to read this page');
         }
@@ -538,6 +541,7 @@
      * Michael Klier <chi@chimeric.de>
      */
     function putAttachment($id, $file, $params) {
+        $id = cleanID($id);
         global $conf;
         global $lang;
 
@@ -607,6 +611,7 @@
      * @author Gina Haeussge <osd@foosel.net>
      */
     function deleteAttachment($id){
+        $id = cleanID($id);
         $auth = auth_quickaclcheck(getNS($id).':*');
         if($auth < AUTH_DELETE) return new IXR_ERROR(1, "You don't have permissions to delete files.");
         global $conf;
@@ -667,6 +672,7 @@
     * Returns the permissions of a given wiki page
     */
     function aclCheck($id) {
+        $id = cleanID($id);
         return auth_quickaclcheck($id);
     }
 
@@ -676,13 +682,14 @@
      * @author Michael Klier <chi@chimeric.de>
      */
     function listLinks($id) {
+        $id = cleanID($id);
         if(auth_quickaclcheck($id) < AUTH_READ){
             return new IXR_Error(1, 'You are not allowed to read this page');
         }
         $links = array();
 
         // resolve page instructions
-        $ins   = p_cached_instructions(wikiFN(cleanID($id)));
+        $ins   = p_cached_instructions(wikiFN($id));
 
         // instantiate new Renderer - needed for interwiki links
         include(DOKU_INC.'inc/parser/xhtml.php');
@@ -796,6 +803,10 @@
      * @author Michael Klier <chi@chimeric.de>
      */
     function pageVersions($id, $first) {
+        $id = cleanID($id);
+        if(auth_quickaclcheck($id) < AUTH_READ){
+            return new IXR_Error(1, 'You are not allowed to read this page');
+        }
         global $conf;
 
         $versions = array();
@@ -873,7 +884,8 @@
         $unlockfail = array();
 
         foreach((array) $set['lock'] as $id){
-            if(checklock($id)){
+            $id = cleanID($id);
+            if(auth_quickaclcheck($id) < AUTH_EDIT || checklock($id)){
                 $lockfail[] = $id;
             }else{
                 lock($id);
@@ -882,10 +894,11 @@
         }
 
         foreach((array) $set['unlock'] as $id){
-            if(unlock($id)){
-                $unlocked[] = $id;
-            }else{
+            $id = cleanID($id);
+            if(auth_quickaclcheck($id) < AUTH_EDIT || !unlock($id)){
                 $unlockfail[] = $id;
+            }else{
+                $unlocked[] = $id;
             }
         }
 
diff -Nru dokuwiki-0.0.20091225c-10/.pc/applied-patches dokuwiki-0.0.20091225c-10+squeeze1/.pc/applied-patches
--- dokuwiki-0.0.20091225c-10/.pc/applied-patches	2011-03-16 20:24:13.795782591 +0100
+++ dokuwiki-0.0.20091225c-10+squeeze1/.pc/applied-patches	2011-03-16 21:05:09.967380858 +0100
@@ -1,3 +1,4 @@
+xmlrpc_security.diff
 use_packaged_simplepie.diff
 use_packaged_php-geshi_SA32559.diff
 posts-are-public-domain-by-default.diff
diff -Nru dokuwiki-0.0.20091225c-10/.pc/xmlrpc_security.diff/lib/exe/xmlrpc.php dokuwiki-0.0.20091225c-10+squeeze1/.pc/xmlrpc_security.diff/lib/exe/xmlrpc.php
--- dokuwiki-0.0.20091225c-10/.pc/xmlrpc_security.diff/lib/exe/xmlrpc.php	1970-01-01 01:00:00.000000000 +0100
+++ dokuwiki-0.0.20091225c-10+squeeze1/.pc/xmlrpc_security.diff/lib/exe/xmlrpc.php	2010-01-17 11:35:46.000000000 +0100
@@ -0,0 +1,921 @@
+<?php
+if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../');
+
+// fix when '<?xml' isn't on the very first line
+if(isset($HTTP_RAW_POST_DATA)) $HTTP_RAW_POST_DATA = trim($HTTP_RAW_POST_DATA);
+
+/**
+ * Increased whenever the API is changed
+ */
+define('DOKU_XMLRPC_API_VERSION',2);
+
+require_once(DOKU_INC.'inc/init.php');
+require_once(DOKU_INC.'inc/common.php');
+require_once(DOKU_INC.'inc/auth.php');
+session_write_close();  //close session
+
+if(!$conf['xmlrpc']) die('XML-RPC server not enabled.');
+
+require_once(DOKU_INC.'inc/IXR_Library.php');
+
+
+/**
+ * Contains needed wrapper functions and registers all available
+ * XMLRPC functions.
+ */
+class dokuwiki_xmlrpc_server extends IXR_IntrospectionServer {
+    var $methods       = array();
+    var $public_methods = array();
+
+    /**
+     * Checks if the current user is allowed to execute non anonymous methods
+     */
+    function checkAuth(){
+        global $conf;
+        global $USERINFO;
+
+        if(!$conf['useacl']) return true; //no ACL - then no checks
+
+        $allowed = explode(',',$conf['xmlrpcuser']);
+        $allowed = array_map('trim', $allowed);
+        $allowed = array_unique($allowed);
+        $allowed = array_filter($allowed);
+
+        if(!count($allowed)) return true; //no restrictions
+
+        $user   = $_SERVER['REMOTE_USER'];
+        $groups = (array) $USERINFO['grps'];
+
+        if(in_array($user,$allowed)) return true; //user explicitly mentioned
+
+        //check group memberships
+        foreach($groups as $group){
+            if(in_array('@'.$group,$allowed)) return true;
+        }
+
+        //still here? no access!
+        return false;
+    }
+
+    /**
+     * Adds a callback, extends parent method
+     *
+     * add another parameter to define if anonymous access to
+     * this method should be granted.
+     */
+    function addCallback($method, $callback, $args, $help, $public=false){
+        if($public) $this->public_methods[] = $method;
+        return parent::addCallback($method, $callback, $args, $help);
+    }
+
+    /**
+     * Execute a call, extends parent method
+     *
+     * Checks for authentication first
+     */
+    function call($methodname, $args){
+        if(!in_array($methodname,$this->public_methods) && !$this->checkAuth()){
+            return new IXR_Error(-32603, 'server error. not authorized to call method "'.$methodname.'".');
+        }
+        return parent::call($methodname, $args);
+    }
+
+    /**
+     * Constructor. Register methods and run Server
+     */
+    function dokuwiki_xmlrpc_server(){
+        $this->IXR_IntrospectionServer();
+
+        /* DokuWiki's own methods */
+        $this->addCallback(
+            'dokuwiki.getXMLRPCAPIVersion',
+            'this:getAPIVersion',
+            array('integer'),
+            'Returns the XMLRPC API version.',
+            true
+        );
+
+        $this->addCallback(
+            'dokuwiki.getVersion',
+            'getVersion',
+            array('string'),
+            'Returns the running DokuWiki version.',
+            true
+        );
+
+        $this->addCallback(
+            'dokuwiki.login',
+            'this:login',
+            array('integer','string','string'),
+            'Tries to login with the given credentials and sets auth cookies.',
+            true
+        );
+
+        $this->addCallback(
+            'dokuwiki.getPagelist',
+            'this:readNamespace',
+            array('struct','string','struct'),
+            'List all pages within the given namespace.'
+        );
+
+        $this->addCallback(
+            'dokuwiki.getTime',
+            'time',
+            array('int'),
+            'Return the current time at the wiki server.'
+        );
+
+        $this->addCallback(
+            'dokuwiki.setLocks',
+            'this:setLocks',
+            array('struct','struct'),
+            'Lock or unlock pages.'
+        );
+
+        /* Wiki API v2 http://www.jspwiki.org/wiki/WikiRPCInterface2 */
+        $this->addCallback(
+            'wiki.getRPCVersionSupported',
+            'this:wiki_RPCVersion',
+            array('int'),
+            'Returns 2 with the supported RPC API version.',
+            true
+        );
+        $this->addCallback(
+            'wiki.getPage',
+            'this:rawPage',
+            array('string','string'),
+            'Get the raw Wiki text of page, latest version.'
+        );
+        $this->addCallback(
+            'wiki.getPageVersion',
+            'this:rawPage',
+            array('string','string','int'),
+            'Get the raw Wiki text of page.'
+        );
+        $this->addCallback(
+            'wiki.getPageHTML',
+            'this:htmlPage',
+            array('string','string'),
+            'Return page in rendered HTML, latest version.'
+        );
+        $this->addCallback(
+            'wiki.getPageHTMLVersion',
+            'this:htmlPage',
+            array('string','string','int'),
+            'Return page in rendered HTML.'
+        );
+        $this->addCallback(
+            'wiki.getAllPages',
+            'this:listPages',
+            array('struct'),
+            'Returns a list of all pages. The result is an array of utf8 pagenames.'
+        );
+        $this->addCallback(
+            'wiki.getAttachments',
+            'this:listAttachments',
+            array('struct', 'string', 'struct'),
+            'Returns a list of all media files.'
+        );
+        $this->addCallback(
+            'wiki.getBackLinks',
+            'this:listBackLinks',
+            array('struct','string'),
+            'Returns the pages that link to this page.'
+        );
+        $this->addCallback(
+            'wiki.getPageInfo',
+            'this:pageInfo',
+            array('struct','string'),
+            'Returns a struct with infos about the page.'
+        );
+        $this->addCallback(
+            'wiki.getPageInfoVersion',
+            'this:pageInfo',
+            array('struct','string','int'),
+            'Returns a struct with infos about the page.'
+        );
+        $this->addCallback(
+            'wiki.getPageVersions',
+            'this:pageVersions',
+            array('struct','string','int'),
+            'Returns the available revisions of the page.'
+        );
+        $this->addCallback(
+            'wiki.putPage',
+            'this:putPage',
+            array('int', 'string', 'string', 'struct'),
+            'Saves a wiki page.'
+        );
+        $this->addCallback(
+            'wiki.listLinks',
+            'this:listLinks',
+            array('struct','string'),
+            'Lists all links contained in a wiki page.'
+        );
+        $this->addCallback(
+            'wiki.getRecentChanges',
+            'this:getRecentChanges',
+            array('struct','int'),
+            'Returns a struct about all recent changes since given timestamp.'
+        );
+        $this->addCallback(
+            'wiki.getRecentMediaChanges',
+            'this:getRecentMediaChanges',
+            array('struct','int'),
+            'Returns a struct about all recent media changes since given timestamp.'
+        );
+        $this->addCallback(
+            'wiki.aclCheck',
+            'this:aclCheck',
+            array('int', 'string'),
+            'Returns the permissions of a given wiki page.'
+        );
+        $this->addCallback(
+            'wiki.putAttachment',
+            'this:putAttachment',
+            array('struct', 'string', 'base64', 'struct'),
+            'Upload a file to the wiki.'
+        );
+        $this->addCallback(
+            'wiki.deleteAttachment',
+            'this:deleteAttachment',
+            array('int', 'string'),
+            'Delete a file from the wiki.'
+        );
+        $this->addCallback(
+            'wiki.getAttachment',
+            'this:getAttachment',
+            array('base64', 'string'),
+            'Download a file from the wiki.'
+        );
+        $this->addCallback(
+            'wiki.getAttachmentInfo',
+            'this:getAttachmentInfo',
+            array('struct', 'string'),
+            'Returns a struct with infos about the attachment.'
+        );
+
+        /**
+         * Trigger XMLRPC_CALLBACK_REGISTER, action plugins can use this event
+         * to extend the XMLRPC interface and register their own callbacks.
+         *
+         * Event data:
+         *  The XMLRPC server object:
+         *
+         *  $event->data->addCallback() - register a callback, the second
+         *  paramter has to be of the form "plugin:<pluginname>:<plugin
+         *  method>"
+         *
+         *  $event->data->callbacks - an array which holds all awaylable
+         *  callbacks
+         */
+        trigger_event('XMLRPC_CALLBACK_REGISTER', $this);
+
+        $this->serve();
+    }
+
+    /**
+     * Return a raw wiki page
+     */
+    function rawPage($id,$rev=''){
+        if(auth_quickaclcheck($id) < AUTH_READ){
+            return new IXR_Error(1, 'You are not allowed to read this page');
+        }
+        $text = rawWiki($id,$rev);
+        if(!$text) {
+            $data = array($id);
+            return trigger_event('HTML_PAGE_FROMTEMPLATE',$data,'pageTemplate',true);
+        } else {
+            return $text;
+        }
+    }
+
+    /**
+     * Return a media file encoded in base64
+     *
+     * @author Gina Haeussge <osd@foosel.net>
+     */
+    function getAttachment($id){
+        $id = cleanID($id);
+        if (auth_quickaclcheck(getNS($id).':*') < AUTH_READ)
+            return new IXR_Error(1, 'You are not allowed to read this file');
+
+        $file = mediaFN($id);
+        if (!@ file_exists($file))
+            return new IXR_Error(1, 'The requested file does not exist');
+
+        $data = io_readFile($file, false);
+        $base64 = base64_encode($data);
+        return $base64;
+    }
+
+    /**
+     * Return info about a media file
+     *
+     * @author Gina Haeussge <osd@foosel.net>
+     */
+    function getAttachmentInfo($id){
+        $id = cleanID($id);
+        $info = array(
+            'lastModified' => 0,
+            'size' => 0,
+        );
+
+        $file = mediaFN($id);
+        if ((auth_quickaclcheck(getNS($id).':*') >= AUTH_READ) && file_exists($file)){
+            $info['lastModified'] = new IXR_Date(filemtime($file));
+            $info['size'] = filesize($file);
+        }
+
+        return $info;
+    }
+
+    /**
+     * Return a wiki page rendered to html
+     */
+    function htmlPage($id,$rev=''){
+        if(auth_quickaclcheck($id) < AUTH_READ){
+            return new IXR_Error(1, 'You are not allowed to read this page');
+        }
+        return p_wiki_xhtml($id,$rev,false);
+    }
+
+    /**
+     * List all pages - we use the indexer list here
+     */
+    function listPages(){
+        global $conf;
+
+        $list  = array();
+        $pages = file($conf['indexdir'] . '/page.idx');
+        $pages = array_filter($pages, 'isVisiblePage');
+
+        foreach(array_keys($pages) as $idx) {
+            if(page_exists($pages[$idx])) {
+                $perm = auth_quickaclcheck($pages[$idx]);
+                if($perm >= AUTH_READ) {
+                    $page = array();
+                    $page['id'] = trim($pages[$idx]);
+                    $page['perms'] = $perm;
+                    $page['size'] = @filesize(wikiFN($pages[$idx]));
+                    $page['lastModified'] = new IXR_Date(@filemtime(wikiFN($pages[$idx])));
+                    $list[] = $page;
+                }
+            }
+        }
+
+        return $list;
+    }
+
+    /**
+     * List all pages in the given namespace (and below)
+     */
+    function readNamespace($ns,$opts){
+        global $conf;
+
+        if(!is_array($opts)) $opts=array();
+
+        $ns = cleanID($ns);
+        $dir = utf8_encodeFN(str_replace(':', '/', $ns));
+        $data = array();
+        require_once(DOKU_INC.'inc/search.php');
+        $opts['skipacl'] = 0; // no ACL skipping for XMLRPC
+        search($data, $conf['datadir'], 'search_allpages', $opts, $dir);
+        return $data;
+    }
+
+    /**
+     * List all media files.
+     *
+     * Available options are 'recursive' for also including the subnamespaces
+     * in the listing, and 'pattern' for filtering the returned files against
+     * a regular expression matching their name.
+     *
+     * @author Gina Haeussge <osd@foosel.net>
+     */
+    function listAttachments($ns, $options = array()) {
+        global $conf;
+        global $lang;
+
+        $ns = cleanID($ns);
+
+        if (!is_array($options)) $options = array();
+        $options['skipacl'] = 0; // no ACL skipping for XMLRPC
+
+
+        if(auth_quickaclcheck($ns.':*') >= AUTH_READ) {
+            $dir = utf8_encodeFN(str_replace(':', '/', $ns));
+
+            $data = array();
+            require_once(DOKU_INC.'inc/search.php');
+            search($data, $conf['mediadir'], 'search_media', $options, $dir);
+            $len = count($data);
+            if(!$len) return array();
+
+            for($i=0; $i<$len; $i++) {
+                unset($data[$i]['meta']);
+                $data[$i]['lastModified'] = new IXR_Date($data[$i]['mtime']);
+            }
+            return $data;
+        } else {
+            return new IXR_Error(1, 'You are not allowed to list media files.');
+        }
+    }
+
+    /**
+     * Return a list of backlinks
+     */
+    function listBackLinks($id){
+        require_once(DOKU_INC.'inc/fulltext.php');
+        return ft_backlinks($id);
+    }
+
+    /**
+     * Return some basic data about a page
+     */
+    function pageInfo($id,$rev=''){
+        if(auth_quickaclcheck($id) < AUTH_READ){
+            return new IXR_Error(1, 'You are not allowed to read this page');
+        }
+        $file = wikiFN($id,$rev);
+        $time = @filemtime($file);
+        if(!$time){
+            return new IXR_Error(10, 'The requested page does not exist');
+        }
+
+        $info = getRevisionInfo($id, $time, 1024);
+
+        $data = array(
+            'name'         => $id,
+            'lastModified' => new IXR_Date($time),
+            'author'       => (($info['user']) ? $info['user'] : $info['ip']),
+            'version'      => $time
+        );
+
+        return ($data);
+    }
+
+    /**
+     * Save a wiki page
+     *
+     * @author Michael Klier <chi@chimeric.de>
+     */
+    function putPage($id, $text, $params) {
+        global $TEXT;
+        global $lang;
+        global $conf;
+
+        $id    = cleanID($id);
+        $TEXT  = cleanText($text);
+        $sum   = $params['sum'];
+        $minor = $params['minor'];
+
+        if(empty($id))
+            return new IXR_Error(1, 'Empty page ID');
+
+        if(!page_exists($id) && trim($TEXT) == '' ) {
+            return new IXR_ERROR(1, 'Refusing to write an empty new wiki page');
+        }
+
+        if(auth_quickaclcheck($id) < AUTH_EDIT)
+            return new IXR_Error(1, 'You are not allowed to edit this page');
+
+        // Check, if page is locked
+        if(checklock($id))
+            return new IXR_Error(1, 'The page is currently locked');
+
+        // SPAM check
+        if(checkwordblock())
+            return new IXR_Error(1, 'Positive wordblock check');
+
+        // autoset summary on new pages
+        if(!page_exists($id) && empty($sum)) {
+            $sum = $lang['created'];
+        }
+
+        // autoset summary on deleted pages
+        if(page_exists($id) && empty($TEXT) && empty($sum)) {
+            $sum = $lang['deleted'];
+        }
+
+        lock($id);
+
+        saveWikiText($id,$TEXT,$sum,$minor);
+
+        unlock($id);
+
+        // run the indexer if page wasn't indexed yet
+        if(!@file_exists(metaFN($id, '.indexed'))) {
+            // try to aquire a lock
+            $lock = $conf['lockdir'].'/_indexer.lock';
+            while(!@mkdir($lock,$conf['dmode'])){
+                usleep(50);
+                if(time()-@filemtime($lock) > 60*5){
+                    // looks like a stale lock - remove it
+                    @rmdir($lock);
+                }else{
+                    return false;
+                }
+            }
+            if($conf['dperm']) chmod($lock, $conf['dperm']);
+
+            require_once(DOKU_INC.'inc/indexer.php');
+
+            // do the work
+            idx_addPage($id);
+
+            // we're finished - save and free lock
+            io_saveFile(metaFN($id,'.indexed'),INDEXER_VERSION);
+            @rmdir($lock);
+        }
+
+        return 0;
+    }
+
+    /**
+     * Uploads a file to the wiki.
+     *
+     * Michael Klier <chi@chimeric.de>
+     */
+    function putAttachment($id, $file, $params) {
+        global $conf;
+        global $lang;
+
+        $auth = auth_quickaclcheck(getNS($id).':*');
+        if($auth >= AUTH_UPLOAD) {
+            if(!isset($id)) {
+                return new IXR_ERROR(1, 'Filename not given.');
+            }
+
+            $ftmp = $conf['tmpdir'] . '/' . $id;
+
+            // save temporary file
+            @unlink($ftmp);
+            $buff = base64_decode($file);
+            io_saveFile($ftmp, $buff);
+
+            // get filename
+            list($iext, $imime,$dl) = mimetype($id);
+            $id = cleanID($id);
+            $fn = mediaFN($id);
+
+            // get filetype regexp
+            $types = array_keys(getMimeTypes());
+            $types = array_map(create_function('$q','return preg_quote($q,"/");'),$types);
+            $regex = join('|',$types);
+
+            // because a temp file was created already
+            if(preg_match('/\.('.$regex.')$/i',$fn)) {
+                //check for overwrite
+                $overwrite = @file_exists($fn);
+                if($overwrite && (!$params['ow'] || $auth < AUTH_DELETE)) {
+                    return new IXR_ERROR(1, $lang['uploadexist'].'1');
+                }
+                // check for valid content
+                @require_once(DOKU_INC.'inc/media.php');
+                $ok = media_contentcheck($ftmp, $imime);
+                if($ok == -1) {
+                    return new IXR_ERROR(1, sprintf($lang['uploadexist'].'2', ".$iext"));
+                } elseif($ok == -2) {
+                    return new IXR_ERROR(1, $lang['uploadspam']);
+                } elseif($ok == -3) {
+                    return new IXR_ERROR(1, $lang['uploadxss']);
+                }
+
+                // prepare event data
+                $data[0] = $ftmp;
+                $data[1] = $fn;
+                $data[2] = $id;
+                $data[3] = $imime;
+                $data[4] = $overwrite;
+
+                // trigger event
+                require_once(DOKU_INC.'inc/events.php');
+                return trigger_event('MEDIA_UPLOAD_FINISH', $data, array($this, '_media_upload_action'), true);
+
+            } else {
+                return new IXR_ERROR(1, $lang['uploadwrong']);
+            }
+        } else {
+            return new IXR_ERROR(1, "You don't have permissions to upload files.");
+        }
+    }
+
+    /**
+     * Deletes a file from the wiki.
+     *
+     * @author Gina Haeussge <osd@foosel.net>
+     */
+    function deleteAttachment($id){
+        $auth = auth_quickaclcheck(getNS($id).':*');
+        if($auth < AUTH_DELETE) return new IXR_ERROR(1, "You don't have permissions to delete files.");
+        global $conf;
+        global $lang;
+
+        // check for references if needed
+        $mediareferences = array();
+        if($conf['refcheck']){
+            require_once(DOKU_INC.'inc/fulltext.php');
+            $mediareferences = ft_mediause($id,$conf['refshow']);
+        }
+
+        if(!count($mediareferences)){
+            $file = mediaFN($id);
+            if(@unlink($file)){
+                require_once(DOKU_INC.'inc/changelog.php');
+                addMediaLogEntry(time(), $id, DOKU_CHANGE_TYPE_DELETE);
+                io_sweepNS($id,'mediadir');
+                return 0;
+            }
+            //something went wrong
+               return new IXR_ERROR(1, 'Could not delete file');
+        } else {
+            return new IXR_ERROR(1, 'File is still referenced');
+        }
+    }
+
+    /**
+     * Moves the temporary file to its final destination.
+     *
+     * Michael Klier <chi@chimeric.de>
+     */
+    function _media_upload_action($data) {
+        global $conf;
+
+        if(is_array($data) && count($data)===5) {
+            io_createNamespace($data[2], 'media');
+            if(rename($data[0], $data[1])) {
+                chmod($data[1], $conf['fmode']);
+                media_notify($data[2], $data[1], $data[3]);
+                // add a log entry to the media changelog
+                require_once(DOKU_INC.'inc/changelog.php');
+                if ($data[4]) {
+                    addMediaLogEntry(time(), $data[2], DOKU_CHANGE_TYPE_EDIT);
+                } else {
+                    addMediaLogEntry(time(), $data[2], DOKU_CHANGE_TYPE_CREATE);
+                }
+                return $data[2];
+            } else {
+                return new IXR_ERROR(1, 'Upload failed.');
+            }
+        } else {
+            return new IXR_ERROR(1, 'Upload failed.');
+        }
+    }
+
+    /**
+    * Returns the permissions of a given wiki page
+    */
+    function aclCheck($id) {
+        return auth_quickaclcheck($id);
+    }
+
+    /**
+     * Lists all links contained in a wiki page
+     *
+     * @author Michael Klier <chi@chimeric.de>
+     */
+    function listLinks($id) {
+        if(auth_quickaclcheck($id) < AUTH_READ){
+            return new IXR_Error(1, 'You are not allowed to read this page');
+        }
+        $links = array();
+
+        // resolve page instructions
+        $ins   = p_cached_instructions(wikiFN(cleanID($id)));
+
+        // instantiate new Renderer - needed for interwiki links
+        include(DOKU_INC.'inc/parser/xhtml.php');
+        $Renderer = new Doku_Renderer_xhtml();
+        $Renderer->interwiki = getInterwiki();
+
+        // parse parse instructions
+        foreach($ins as $in) {
+            $link = array();
+            switch($in[0]) {
+                case 'internallink':
+                    $link['type'] = 'local';
+                    $link['page'] = $in[1][0];
+                    $link['href'] = wl($in[1][0]);
+                    array_push($links,$link);
+                    break;
+                case 'externallink':
+                    $link['type'] = 'extern';
+                    $link['page'] = $in[1][0];
+                    $link['href'] = $in[1][0];
+                    array_push($links,$link);
+                    break;
+                case 'interwikilink':
+                    $url = $Renderer->_resolveInterWiki($in[1][2],$in[1][3]);
+                    $link['type'] = 'extern';
+                    $link['page'] = $url;
+                    $link['href'] = $url;
+                    array_push($links,$link);
+                    break;
+            }
+        }
+
+        return ($links);
+    }
+
+    /**
+     * Returns a list of recent changes since give timestamp
+     *
+     * @author Michael Hamann <michael@content-space.de>
+     * @author Michael Klier <chi@chimeric.de>
+     */
+    function getRecentChanges($timestamp) {
+        if(strlen($timestamp) != 10)
+            return new IXR_Error(20, 'The provided value is not a valid timestamp');
+
+        require_once(DOKU_INC.'inc/changelog.php');
+        require_once(DOKU_INC.'inc/pageutils.php');
+
+        $recents = getRecentsSince($timestamp);
+
+        $changes = array();
+
+        foreach ($recents as $recent) {
+            $change = array();
+            $change['name']         = $recent['id'];
+            $change['lastModified'] = new IXR_Date($recent['date']);
+            $change['author']       = $recent['user'];
+            $change['version']      = $recent['date'];
+            $change['perms']        = $recent['perms'];
+            $change['size']         = @filesize(wikiFN($recent['id']));
+            array_push($changes, $change);
+        }
+
+        if (!empty($changes)) {
+            return $changes;
+        } else {
+            // in case we still have nothing at this point
+            return new IXR_Error(30, 'There are no changes in the specified timeframe');
+        }
+    }
+
+    /**
+     * Returns a list of recent media changes since give timestamp
+     *
+     * @author Michael Hamann <michael@content-space.de>
+     * @author Michael Klier <chi@chimeric.de>
+     */
+    function getRecentMediaChanges($timestamp) {
+        if(strlen($timestamp) != 10)
+            return new IXR_Error(20, 'The provided value is not a valid timestamp');
+
+        require_once(DOKU_INC.'inc/changelog.php');
+        require_once(DOKU_INC.'inc/pageutils.php');
+
+        $recents = getRecentsSince($timestamp, null, '', RECENTS_MEDIA_CHANGES);
+
+        $changes = array();
+
+        foreach ($recents as $recent) {
+            $change = array();
+            $change['name']         = $recent['id'];
+            $change['lastModified'] = new IXR_Date($recent['date']);
+            $change['author']       = $recent['user'];
+            $change['version']      = $recent['date'];
+            $change['perms']        = $recent['perms'];
+            $change['size']         = @filesize(mediaFN($recent['id']));
+            array_push($changes, $change);
+        }
+
+        if (!empty($changes)) {
+            return $changes;
+        } else {
+            // in case we still have nothing at this point
+            return new IXR_Error(30, 'There are no changes in the specified timeframe');
+        }
+    }
+
+    /**
+     * Returns a list of available revisions of a given wiki page
+     *
+     * @author Michael Klier <chi@chimeric.de>
+     */
+    function pageVersions($id, $first) {
+        global $conf;
+
+        $versions = array();
+
+        if(empty($id))
+            return new IXR_Error(1, 'Empty page ID');
+
+        require_once(DOKU_INC.'inc/changelog.php');
+
+        $revisions = getRevisions($id, $first, $conf['recent']+1);
+
+        if(count($revisions)==0 && $first!=0) {
+            $first=0;
+            $revisions = getRevisions($id, $first, $conf['recent']+1);
+        }
+
+        if(count($revisions)>0 && $first==0) {
+            array_unshift($revisions, '');  // include current revision
+            array_pop($revisions);          // remove extra log entry
+        }
+
+        $hasNext = false;
+        if(count($revisions)>$conf['recent']) {
+            $hasNext = true;
+            array_pop($revisions); // remove extra log entry
+        }
+
+        if(!empty($revisions)) {
+            foreach($revisions as $rev) {
+                $file = wikiFN($id,$rev);
+                $time = @filemtime($file);
+                // we check if the page actually exists, if this is not the
+                // case this can lead to less pages being returned than
+                // specified via $conf['recent']
+                if($time){
+                    $info = getRevisionInfo($id, $time, 1024);
+                    if(!empty($info)) {
+                        $data['user'] = $info['user'];
+                        $data['ip']   = $info['ip'];
+                        $data['type'] = $info['type'];
+                        $data['sum']  = $info['sum'];
+                        $data['modified'] = new IXR_Date($info['date']);
+                        $data['version'] = $info['date'];
+                        array_push($versions, $data);
+                    }
+                }
+            }
+            return $versions;
+        } else {
+            return array();
+        }
+    }
+
+    /**
+     * The version of Wiki RPC API supported
+     */
+    function wiki_RPCVersion(){
+        return 2;
+    }
+
+
+    /**
+     * Locks or unlocks a given batch of pages
+     *
+     * Give an associative array with two keys: lock and unlock. Both should contain a
+     * list of pages to lock or unlock
+     *
+     * Returns an associative array with the keys locked, lockfail, unlocked and
+     * unlockfail, each containing lists of pages.
+     */
+    function setLocks($set){
+        $locked     = array();
+        $lockfail   = array();
+        $unlocked   = array();
+        $unlockfail = array();
+
+        foreach((array) $set['lock'] as $id){
+            if(checklock($id)){
+                $lockfail[] = $id;
+            }else{
+                lock($id);
+                $locked[] = $id;
+            }
+        }
+
+        foreach((array) $set['unlock'] as $id){
+            if(unlock($id)){
+                $unlocked[] = $id;
+            }else{
+                $unlockfail[] = $id;
+            }
+        }
+
+        return array(
+            'locked'     => $locked,
+            'lockfail'   => $lockfail,
+            'unlocked'   => $unlocked,
+            'unlockfail' => $unlockfail,
+        );
+    }
+
+    function getAPIVersion(){
+        return DOKU_XMLRPC_API_VERSION;
+    }
+
+    function login($user,$pass){
+        global $conf;
+        global $auth;
+        if(!$conf['useacl']) return 0;
+        if(!$auth) return 0;
+        if($auth->canDo('external')){
+            return $auth->trustExternal($user,$pass,false);
+        }else{
+            return auth_login($user,$pass,false,true);
+        }
+    }
+
+
+}
+
+$server = new dokuwiki_xmlrpc_server();
+
+// vim:ts=4:sw=4:et:enc=utf-8:
diff -Nru '--exclude=.git' dokuwiki-0.0.20080505-4+lenny1/debian/changelog dokuwiki-0.0.20080505-4+lenny2/debian/changelog
--- dokuwiki-0.0.20080505-4+lenny1/debian/changelog	2011-03-16 20:32:18.000000000 +0100
+++ dokuwiki-0.0.20080505-4+lenny2/debian/changelog	2011-03-16 21:06:13.111759522 +0100
@@ -1,3 +1,10 @@
+dokuwiki (0.0.20080505-4+lenny2) oldstable; urgency=low
+
+  * debian/patches/xmlrpc_security.diff: Backport an upstream security fix for
+    an ACL bypass (TEMP-0000000-52FF39).
+
+ -- Tanguy Ortolo <tanguy+debian@ortolo.eu>  Wed, 16 Mar 2011 21:05:51 +0100
+
 dokuwiki (0.0.20080505-4+lenny1) stable-security; urgency=high
 
   * Non-maintainer upload by the Security Team.
diff -Nru '--exclude=.git' dokuwiki-0.0.20080505-4+lenny1/debian/patches/series dokuwiki-0.0.20080505-4+lenny2/debian/patches/series
--- dokuwiki-0.0.20080505-4+lenny1/debian/patches/series	2011-03-16 20:32:18.000000000 +0100
+++ dokuwiki-0.0.20080505-4+lenny2/debian/patches/series	2011-03-16 20:47:14.253995556 +0100
@@ -4,3 +4,4 @@
 removeccreferences.diff
 debianize.diff
 security.diff
+xmlrpc_security.diff
diff -Nru '--exclude=.git' dokuwiki-0.0.20080505-4+lenny1/debian/patches/xmlrpc_security.diff dokuwiki-0.0.20080505-4+lenny2/debian/patches/xmlrpc_security.diff
--- dokuwiki-0.0.20080505-4+lenny1/debian/patches/xmlrpc_security.diff	1970-01-01 01:00:00.000000000 +0100
+++ dokuwiki-0.0.20080505-4+lenny2/debian/patches/xmlrpc_security.diff	2011-03-16 20:43:15.737991509 +0100
@@ -0,0 +1,74 @@
+Author: Michael Hamann <michael@content-space.de>
+Author: Tanguy Ortolo <tanguy+debian@ortolo.eu>
+Origin: upstream, https://github.com/splitbrain/dokuwiki/commit/29af721754761e8b633e346fefc6e1067150d83c
+Last-Update: 2011-03-02
+Description: Fix several security issues in the XML-RPC interface
+    .
+    For locks and getRevisions there hasn't been any acl check. In many
+    other cases the id hadn't been cleaned before the acl check was done
+    which means that many acl rules that should be applied weren't applied.
+    So e.g. when you have read permissions for the root namespace but not
+    for a subnamespace you could add a leading ":" and the permissions for
+    the root namespace will be used instead of the permissions for the
+    subnamespace. This did not apply to writing pages and reading media
+    files, but writing and deleting media files have been concerned as well
+    as reading both plain and html versions of pages.
+    .
+    This only concerns installations where XML-RPC is enabled (default is
+    disabled) and XML-RPC is allowed for all or untrusted users.
+
+Index: dokuwiki-0.0.20080505/lib/exe/xmlrpc.php
+===================================================================
+--- dokuwiki-0.0.20080505.orig/lib/exe/xmlrpc.php	2011-03-02 21:58:28.711229534 +0100
++++ dokuwiki-0.0.20080505/lib/exe/xmlrpc.php	2011-03-02 21:58:33.402936029 +0100
+@@ -125,6 +125,7 @@
+      * Return a raw wiki page
+      */
+     function rawPage($id,$rev=''){
++        $id = cleanID($id);
+         if(auth_quickaclcheck($id) < AUTH_READ){
+             return new IXR_Error(1, 'You are not allowed to read this page');
+         }
+@@ -141,6 +142,7 @@
+      * Return a wiki page rendered to html
+      */
+     function htmlPage($id,$rev=''){
++        $id = cleanID($id);
+         if(auth_quickaclcheck($id) < AUTH_READ){
+             return new IXR_Error(1, 'You are not allowed to read this page');
+         }
+@@ -167,6 +169,7 @@
+      * Return some basic data about a page
+      */
+     function pageInfo($id,$rev=''){
++        $id = cleanID($id);
+         if(auth_quickaclcheck($id) < AUTH_READ){
+             return new IXR_Error(1, 'You are not allowed to read this page');
+         }
+@@ -245,13 +248,14 @@
+      * @author Michael Klier <chi@chimeric.de>
+      */
+     function listLinks($id) {
++        $id = cleanID($id);
+         if(auth_quickaclcheck($id) < AUTH_READ){
+             return new IXR_Error(1, 'You are not allowed to read this page');
+         }
+         $links = array();
+ 
+         // resolve page instructions
+-        $ins   = p_cached_instructions(wikiFN(cleanID($id)));
++        $ins   = p_cached_instructions(wikiFN($id));
+ 
+         // instantiate new Renderer - needed for interwiki links
+         include(DOKU_INC.'inc/parser/xhtml.php');
+@@ -363,6 +367,10 @@
+      * @author Michael Klier <chi@chimeric.de>
+      */
+     function pageVersions($id, $first) {
++        $id = cleanID($id);
++        if(auth_quickaclcheck($id) < AUTH_READ){
++            return new IXR_Error(1, 'You are not allowed to read this page');
++        }
+         global $conf;
+ 
+         $versions = array();
Author: Michael Hamann <michael@content-space.de>
Author: Tanguy Ortolo <tanguy+debian@ortolo.eu>
Origin: upstream, https://github.com/splitbrain/dokuwiki/commit/29af721754761e8b633e346fefc6e1067150d83c
Last-Update: 2011-03-02
Description: Fix several security issues in the XML-RPC interface
    .
    For locks and getRevisions there hasn't been any acl check. In many
    other cases the id hadn't been cleaned before the acl check was done
    which means that many acl rules that should be applied weren't applied.
    So e.g. when you have read permissions for the root namespace but not
    for a subnamespace you could add a leading ":" and the permissions for
    the root namespace will be used instead of the permissions for the
    subnamespace. This did not apply to writing pages and reading media
    files, but writing and deleting media files have been concerned as well
    as reading both plain and html versions of pages.
    .
    This only concerns installations where XML-RPC is enabled (default is
    disabled) and XML-RPC is allowed for all or untrusted users.

Index: dokuwiki/lib/exe/xmlrpc.php
===================================================================
--- dokuwiki.orig/lib/exe/xmlrpc.php	2011-03-02 21:26:55.211171043 +0100
+++ dokuwiki/lib/exe/xmlrpc.php	2011-03-02 21:27:41.397079790 +0100
@@ -278,6 +278,7 @@
      * Return a raw wiki page
      */
     function rawPage($id,$rev=''){
+        $id = cleanID($id);
         if(auth_quickaclcheck($id) < AUTH_READ){
             return new IXR_Error(1, 'You are not allowed to read this page');
         }
@@ -334,6 +335,7 @@
      * Return a wiki page rendered to html
      */
     function htmlPage($id,$rev=''){
+        $id = cleanID($id);
         if(auth_quickaclcheck($id) < AUTH_READ){
             return new IXR_Error(1, 'You are not allowed to read this page');
         }
@@ -434,6 +436,7 @@
      * Return some basic data about a page
      */
     function pageInfo($id,$rev=''){
+        $id = cleanID($id);
         if(auth_quickaclcheck($id) < AUTH_READ){
             return new IXR_Error(1, 'You are not allowed to read this page');
         }
@@ -538,6 +541,7 @@
      * Michael Klier <chi@chimeric.de>
      */
     function putAttachment($id, $file, $params) {
+        $id = cleanID($id);
         global $conf;
         global $lang;
 
@@ -607,6 +611,7 @@
      * @author Gina Haeussge <osd@foosel.net>
      */
     function deleteAttachment($id){
+        $id = cleanID($id);
         $auth = auth_quickaclcheck(getNS($id).':*');
         if($auth < AUTH_DELETE) return new IXR_ERROR(1, "You don't have permissions to delete files.");
         global $conf;
@@ -667,6 +672,7 @@
     * Returns the permissions of a given wiki page
     */
     function aclCheck($id) {
+        $id = cleanID($id);
         return auth_quickaclcheck($id);
     }
 
@@ -676,13 +682,14 @@
      * @author Michael Klier <chi@chimeric.de>
      */
     function listLinks($id) {
+        $id = cleanID($id);
         if(auth_quickaclcheck($id) < AUTH_READ){
             return new IXR_Error(1, 'You are not allowed to read this page');
         }
         $links = array();
 
         // resolve page instructions
-        $ins   = p_cached_instructions(wikiFN(cleanID($id)));
+        $ins   = p_cached_instructions(wikiFN($id));
 
         // instantiate new Renderer - needed for interwiki links
         include(DOKU_INC.'inc/parser/xhtml.php');
@@ -796,6 +803,10 @@
      * @author Michael Klier <chi@chimeric.de>
      */
     function pageVersions($id, $first) {
+        $id = cleanID($id);
+        if(auth_quickaclcheck($id) < AUTH_READ){
+            return new IXR_Error(1, 'You are not allowed to read this page');
+        }
         global $conf;
 
         $versions = array();
@@ -873,7 +884,8 @@
         $unlockfail = array();
 
         foreach((array) $set['lock'] as $id){
-            if(checklock($id)){
+            $id = cleanID($id);
+            if(auth_quickaclcheck($id) < AUTH_EDIT || checklock($id)){
                 $lockfail[] = $id;
             }else{
                 lock($id);
@@ -882,10 +894,11 @@
         }
 
         foreach((array) $set['unlock'] as $id){
-            if(unlock($id)){
-                $unlocked[] = $id;
-            }else{
+            $id = cleanID($id);
+            if(auth_quickaclcheck($id) < AUTH_EDIT || !unlock($id)){
                 $unlockfail[] = $id;
+            }else{
+                $unlocked[] = $id;
             }
         }
 
Author: Michael Hamann <michael@content-space.de>
Author: Tanguy Ortolo <tanguy+debian@ortolo.eu>
Origin: upstream, https://github.com/splitbrain/dokuwiki/commit/29af721754761e8b633e346fefc6e1067150d83c
Last-Update: 2011-03-02
Description: Fix several security issues in the XML-RPC interface
    .
    For locks and getRevisions there hasn't been any acl check. In many
    other cases the id hadn't been cleaned before the acl check was done
    which means that many acl rules that should be applied weren't applied.
    So e.g. when you have read permissions for the root namespace but not
    for a subnamespace you could add a leading ":" and the permissions for
    the root namespace will be used instead of the permissions for the
    subnamespace. This did not apply to writing pages and reading media
    files, but writing and deleting media files have been concerned as well
    as reading both plain and html versions of pages.
    .
    This only concerns installations where XML-RPC is enabled (default is
    disabled) and XML-RPC is allowed for all or untrusted users.

Index: dokuwiki-0.0.20080505/lib/exe/xmlrpc.php
===================================================================
--- dokuwiki-0.0.20080505.orig/lib/exe/xmlrpc.php	2011-03-02 21:58:28.711229534 +0100
+++ dokuwiki-0.0.20080505/lib/exe/xmlrpc.php	2011-03-02 21:58:33.402936029 +0100
@@ -125,6 +125,7 @@
      * Return a raw wiki page
      */
     function rawPage($id,$rev=''){
+        $id = cleanID($id);
         if(auth_quickaclcheck($id) < AUTH_READ){
             return new IXR_Error(1, 'You are not allowed to read this page');
         }
@@ -141,6 +142,7 @@
      * Return a wiki page rendered to html
      */
     function htmlPage($id,$rev=''){
+        $id = cleanID($id);
         if(auth_quickaclcheck($id) < AUTH_READ){
             return new IXR_Error(1, 'You are not allowed to read this page');
         }
@@ -167,6 +169,7 @@
      * Return some basic data about a page
      */
     function pageInfo($id,$rev=''){
+        $id = cleanID($id);
         if(auth_quickaclcheck($id) < AUTH_READ){
             return new IXR_Error(1, 'You are not allowed to read this page');
         }
@@ -245,13 +248,14 @@
      * @author Michael Klier <chi@chimeric.de>
      */
     function listLinks($id) {
+        $id = cleanID($id);
         if(auth_quickaclcheck($id) < AUTH_READ){
             return new IXR_Error(1, 'You are not allowed to read this page');
         }
         $links = array();
 
         // resolve page instructions
-        $ins   = p_cached_instructions(wikiFN(cleanID($id)));
+        $ins   = p_cached_instructions(wikiFN($id));
 
         // instantiate new Renderer - needed for interwiki links
         include(DOKU_INC.'inc/parser/xhtml.php');
@@ -363,6 +367,10 @@
      * @author Michael Klier <chi@chimeric.de>
      */
     function pageVersions($id, $first) {
+        $id = cleanID($id);
+        if(auth_quickaclcheck($id) < AUTH_READ){
+            return new IXR_Error(1, 'You are not allowed to read this page');
+        }
         global $conf;
 
         $versions = array();

Attachment: signature.asc
Description: Digital signature


Reply to: