function action_randompage(&$event, $args) { global $conf; global $ID; $data = array(); $dir = $conf['savedir']; $data = file($dir . '/index/page.idx'); //We loops through ten random page... $i = 1; while ($i <= 10 & $i != "ok") { //echo $i; $i++; $id = rtrim($data[array_rand($data, 1)]); $testACL = auth_aclcheck($id, $_SERVER['REMOTE_USER'], $USERINFO['grps']); if ($testACL > 1 and file_exists(wikiFN($id))) { $i = "ok"; //echo $id; } } if ($testACL < 1) { $id = $ID; } header("Location: " . wl($id, '', true)); //echo wl($page,'',true); exit; }
/** * Builds a Google Sitemap of all public pages known to the indexer * * The map is placed in the cache directory named sitemap.xml.gz - This * file needs to be writable! * * @author Michael Hamann * @author Andreas Gohr * @link https://www.google.com/webmasters/sitemaps/docs/en/about.html * @link http://www.sitemaps.org/ */ public function generate() { global $conf; if ($conf['sitemap'] < 1 || !is_numeric($conf['sitemap'])) { return false; } $sitemap = Sitemapper::getFilePath(); if (@file_exists($sitemap)) { if (!is_writable($sitemap)) { return false; } } else { if (!is_writable(dirname($sitemap))) { return false; } } if (@filesize($sitemap) && @filemtime($sitemap) > time() - $conf['sitemap'] * 86400) { // 60*60*24=86400 dbglog('Sitemapper::generate(): Sitemap up to date'); // FIXME: only in debug mode return false; } dbglog("Sitemapper::generate(): using {$sitemap}"); // FIXME: Only in debug mode $pages = idx_getIndex('page', ''); dbglog('Sitemapper::generate(): creating sitemap using ' . count($pages) . ' pages'); $items = array(); // build the sitemap items foreach ($pages as $id) { //skip hidden, non existing and restricted files if (isHiddenPage($id)) { continue; } if (auth_aclcheck($id, '', '') < AUTH_READ) { continue; } $item = SitemapItem::createFromID($id); if ($item !== NULL) { $items[] = $item; } } $eventData = array('items' => &$items, 'sitemap' => &$sitemap); $event = new Doku_Event('SITEMAP_GENERATE', $eventData); if ($event->advise_before(true)) { //save the new sitemap $result = io_saveFile($sitemap, Sitemapper::getXML($items)); } $event->advise_after(); return $result; }
/** * Create output * * @param string $format Renderer mode (supported modes: xhtml) * @param Doku_Renderer $renderer The renderer * @param array $data The data from the handler() function * @return bool If rendering was successful. */ function render($format, Doku_Renderer $renderer, $data) { if ($format == 'metadata') { return false; } if ($data[0] != DOKU_LEXER_SPECIAL) { return false; } $hlp = plugin_load('helper', 'rating'); $list = $hlp->best($data[1]['lang'], $data[1]['startdate'], 20); if ($data[1]['tag'] == 'ol') { $renderer->listo_open(); } else { $renderer->listu_open(); } $num_items = 0; foreach ($list as $item) { if (auth_aclcheck($item['page'], '', null) < AUTH_READ) { continue; } if (!page_exists($item['page'])) { continue; } $num_items = $num_items + 1; $renderer->listitem_open(1); if (strpos($item['page'], ':') === false) { $item['page'] = ':' . $item['page']; } $renderer->internallink($item['page']); if ($data[1]['score'] === 'true') { $renderer->cdata(' (' . $item['val'] . ')'); } $renderer->listitem_close(); if ($num_items >= 10) { break; } } if ($data[1]['tag'] == 'ol') { $renderer->listo_close(); } else { $renderer->listu_close(); } return true; }
/** * Handle the Redirection to an id or the search engine */ function RedirectToId($Vl_Id) { global $ID; //If the user have right to see the page if ($_SERVER['REMOTE_USER']) { $perm = auth_quickaclcheck($Vl_Id); } else { $perm = auth_aclcheck($Vl_Id, '', null); } require_once dirname(__FILE__) . '/admin.php'; $RedirectManager = new admin_plugin_404manager(); $RedirectManager->SetRedirection($ID, $Vl_Id); if ($perm > AUTH_NONE) { $this->OldId = $ID; $ID = $Vl_Id; } }
/** * Default callback for COMMON_NOTIFY_ADDRESSLIST * * Aggregates all email addresses of user who have subscribed the given page with 'every' style * * @author Steven Danz <*****@*****.**> * @author Adrian Lang <*****@*****.**> * * @todo move the whole functionality into this class, trigger SUBSCRIPTION_NOTIFY_ADDRESSLIST instead, * use an array for the addresses within it * * @param array &$data Containing $id (the page id), $self (whether the author * should be notified, $addresslist (current email address * list) */ public function notifyaddresses(&$data) { if (!$this->isenabled()) { return; } /** @var auth_basic $auth */ global $auth; global $conf; $id = $data['id']; $self = $data['self']; $addresslist = $data['addresslist']; $subscriptions = $this->subscribers($id, null, 'every'); $result = array(); foreach ($subscriptions as $target => $users) { foreach ($users as $user => $info) { $userinfo = $auth->getUserData($user); if ($userinfo === false) { continue; } if (!$userinfo['mail']) { continue; } if (!$self && $user == $_SERVER['REMOTE_USER']) { continue; } //skip our own changes $level = auth_aclcheck($id, $user, $userinfo['grps']); if ($level >= AUTH_READ) { if (strcasecmp($userinfo['mail'], $conf['notify']) != 0) { //skip user who get notified elsewhere $result[$user] = $userinfo['mail']; } } } } $data['addresslist'] = trim($addresslist . ',' . implode(',', $result), ','); }
/** * Convinience function for auth_aclcheck() * * This checks the permissions for the current user * * @author Andreas Gohr <*****@*****.**> * * @param string $id page ID (needs to be resolved and cleaned) * @return int permission level */ function auth_quickaclcheck($id) { global $conf; global $USERINFO; /* @var Input $INPUT */ global $INPUT; # if no ACL is used always return upload rights if (!$conf['useacl']) { return AUTH_UPLOAD; } return auth_aclcheck($id, $INPUT->server->str('REMOTE_USER'), $USERINFO['grps']); }
/** * Return a string with the email addresses of all the * users subscribed to a page * * @author Steven Danz <*****@*****.**> */ function subscriber_addresslist($id) { global $conf; global $auth; $emails = ''; if (!$conf['subscribers']) { return; } $mlist = array(); $file = metaFN($id, '.mlist'); if (@file_exists($file)) { $mlist = file($file); } if (count($mlist) > 0) { foreach ($mlist as $who) { $who = rtrim($who); $info = $auth->getUserData($who); $level = auth_aclcheck($id, $who, $info['grps']); if ($level >= AUTH_READ) { if (strcasecmp($info['mail'], $conf['notify']) != 0) { if (empty($emails)) { $emails = $info['mail']; } else { $emails = "{$emails}," . $info['mail']; } } } } } return $emails; }
/** * Determine basic information for a request of $id * * @author Andreas Gohr <*****@*****.**> * @author Chris Smith <*****@*****.**> * * @param string $id pageid * @param bool $htmlClient add info about whether is mobile browser * @return array with info for a request of $id * */ function basicinfo($id, $htmlClient = true) { global $USERINFO; /* @var Input $INPUT */ global $INPUT; // set info about manager/admin status. $info = array(); $info['isadmin'] = false; $info['ismanager'] = false; if ($INPUT->server->has('REMOTE_USER')) { $info['userinfo'] = $USERINFO; $info['perm'] = auth_quickaclcheck($id); $info['client'] = $INPUT->server->str('REMOTE_USER'); if ($info['perm'] == AUTH_ADMIN) { $info['isadmin'] = true; $info['ismanager'] = true; } elseif (auth_ismanager()) { $info['ismanager'] = true; } // if some outside auth were used only REMOTE_USER is set if (!$info['userinfo']['name']) { $info['userinfo']['name'] = $INPUT->server->str('REMOTE_USER'); } } else { $info['perm'] = auth_aclcheck($id, '', null); $info['client'] = clientIP(true); } $info['namespace'] = getNS($id); // mobile detection if ($htmlClient) { $info['ismobile'] = clientismobile(); } return $info; }
/** * Returns ACL access level of the user or the (virtual) 'runas' user * * @param string $id pageid * @return int */ protected function aclcheck($id) { $runas = $this->getConf('runas'); if ($runas) { $auth = auth_aclcheck($id, $runas, array()); } else { $auth = auth_quickaclcheck($id); } return $auth; }
/** * Handles the INDEXER_PAGE_ADD event, prevents indexing of metadata from included pages that aren't public if enabled * * @param Doku_Event $event the event object * @param array $params optional parameters (unused) */ public function handle_indexer(Doku_Event $event, $params) { global $USERINFO; // check if the feature is enabled at all if (!$this->getConf('safeindex')) return; // is there a user logged in at all? If not everything is fine already if (is_null($USERINFO) && !isset($_SERVER['REMOTE_USER'])) return; // get the include metadata in order to see which pages were included $inclmeta = p_get_metadata($event->data['page'], 'plugin_include', METADATA_RENDER_UNLIMITED); $all_public = true; // are all included pages public? // check if the current metadata indicates that non-public pages were included if ($inclmeta !== null && isset($inclmeta['pages'])) { foreach ($inclmeta['pages'] as $page) { if (auth_aclcheck($page['id'], '', array()) < AUTH_READ) { // is $page public? $all_public = false; break; } } } if (!$all_public) { // there were non-public pages included - action required! // backup the user information $userinfo_backup = $USERINFO; $remote_user = $_SERVER['REMOTE_USER']; // unset user information - temporary logoff! $USERINFO = null; unset($_SERVER['REMOTE_USER']); // metadata is only rendered once for a page in one request - thus we need to render manually. $meta = p_read_metadata($event->data['page']); // load the original metdata $meta = p_render_metadata($event->data['page'], $meta); // render the metadata p_save_metadata($event->data['page'], $meta); // save the metadata so other event handlers get the public metadata, too $meta = $meta['current']; // we are only interested in current metadata. // check if the tag plugin handler has already been called before the include plugin $tag_called = isset($event->data['metadata']['subject']); // Reset the metadata in the renderer. This removes data from all other event handlers, but we need to be on the safe side here. $event->data['metadata'] = array('title' => $meta['title']); // restore the relation references metadata if (isset($meta['relation']['references'])) { $event->data['metadata']['relation_references'] = array_keys($meta['relation']['references']); } else { $event->data['metadata']['relation_references'] = array(); } // restore the tag metadata if the tag plugin handler has been called before the include plugin handler. if ($tag_called) { $tag_helper = $this->loadHelper('tag', false); if ($tag_helper) { if (isset($meta['subject'])) { $event->data['metadata']['subject'] = $tag_helper->_cleanTagList($meta['subject']); } else { $event->data['metadata']['subject'] = array(); } } } // restore user information $USERINFO = $userinfo_backup; $_SERVER['REMOTE_USER'] = $remote_user; } }
/** * Returns the permissions of a given wiki page for the current user or another user * * @param string $id page id * @param string|null $user username * @param array|null $groups array of groups * @return int permission level */ public function aclCheck($id, $user = null, $groups = null) { /** @var DokuWiki_Auth_Plugin $auth */ global $auth; $id = $this->resolvePageId($id); if ($user === null) { return auth_quickaclcheck($id); } else { if ($groups === null) { $userinfo = $auth->getUserData($user); if ($userinfo === false) { $groups = array(); } else { $groups = $userinfo['grps']; } } return auth_aclcheck($id, $user, $groups); } }
/** * Return a string with the email addresses of all the * users subscribed to a page * * @author Steven Danz <*****@*****.**> */ function subscriber_addresslist($id, $self = true) { global $conf; global $auth; if (!$conf['subscribers']) { return ''; } $users = array(); $emails = array(); // load the page mlist file content $mlist = array(); $file = metaFN($id, '.mlist'); if (@file_exists($file)) { $mlist = file($file); foreach ($mlist as $who) { $who = rtrim($who); if (!$self && $who == $_SERVER['REMOTE_USER']) { continue; } $users[$who] = true; } } // load also the namespace mlist file content $ns = getNS($id); while ($ns) { $nsfile = metaFN($ns, '/.mlist'); if (@file_exists($nsfile)) { $mlist = file($nsfile); foreach ($mlist as $who) { $who = rtrim($who); if (!$self && $who == $_SERVER['REMOTE_USER']) { continue; } $users[$who] = true; } } $ns = getNS($ns); } // root namespace $nsfile = metaFN('', '.mlist'); if (@file_exists($nsfile)) { $mlist = file($nsfile); foreach ($mlist as $who) { $who = rtrim($who); if (!$self && $who == $_SERVER['REMOTE_USER']) { continue; } $users[$who] = true; } } if (!empty($users)) { foreach (array_keys($users) as $who) { $info = $auth->getUserData($who); if ($info === false) { continue; } $level = auth_aclcheck($id, $who, $info['grps']); if ($level >= AUTH_READ) { if (strcasecmp($info['mail'], $conf['notify']) != 0) { $emails[] = $info['mail']; } } } } return implode(',', $emails); }
/** * Notifies subscribers */ function _notifySubscribers($updates) { global $auth; // acl required if (!$auth) { return; } $page_ids = $media_ids = array(); $subs = array('page' => array(), 'media' => array(), 'ns' => array(), 'user' => array()); // collect updated page and media IDs foreach ($updates as $entry) { if ($entry['class'] === 'page') { $page_ids[$entry['id']] = 1; } elseif ($entry['class'] === 'media') { $media_ids[$entry['id']] = 1; } } // load subscribers of each page/media and its parent namespaces foreach (array_keys($page_ids) as $id) { $this->_loadSubscribers($subs, $id, 'page'); } foreach (array_keys($media_ids) as $id) { $ns = (string) getNS($id); $this->_loadSubscribers($subs, $ns); $subs['media'][$id] = $subs['ns'][$ns]; } // notify for each user (not for each update entry) $mail_count = 0; foreach (array_keys($subs['user']) as $user) { // user exists? if (!($info = $auth->getUserData($user))) { continue; } // search subscribed pages and media with acl checking $subscribed = array(); foreach (array('page', 'media') as $type) { foreach (array_keys($subs[$type]) as $id) { if (!isset($subs[$type][$id][$user])) { continue; } $checkid = $type === 'media' ? getNS($id) . ':dummyID' : $id; if (auth_aclcheck($checkid, $user, $info['grps']) < AUTH_READ) { continue; } $subscribed[$type][$id] = 1; } } if (empty($subscribed)) { continue; } // extract update log entries for the user $updates_for_user = array(); foreach ($updates as $entry) { if (isset($this->_skip['sub_selfmod']) && $entry['user'] === $user) { continue; // skip selfmod } if (isset($subscribed[$entry['class']][$entry['id']])) { $updates_for_user[] = $entry; } } if (empty($updates_for_user)) { continue; } // send email digest $successfully_sent = $this->_sendMail($info['mail'], $this->_buildMailSubject('subscribers'), $this->_buildMailBody('subscribers', $updates_for_user), $this->_buildFromAddress($info['mail'])); if ($successfully_sent) { $mail_count++; } } if ($mail_count) { $this->_debug("Digest message sent (subscribers: {$mail_count} messages)"); } }
/** * Convinience function for auth_aclcheck() * * This checks the permissions for the current user * * @author Andreas Gohr <*****@*****.**> * * @param string $id page ID (needs to be resolved and cleaned) * @return int permission level */ function auth_quickaclcheck($id) { global $conf; global $USERINFO; # if no ACL is used always return upload rights if (!$conf['useacl']) { return AUTH_UPLOAD; } //error_log("DOKUWIKI: auth_quickaclcheck:".$_SERVER['REMOTE_USER'].":".$id.json_encode($USERINFO)); return auth_aclcheck($id, $_SERVER['REMOTE_USER'], $USERINFO['grps']); }
/** * @param $runas * @return mixed * @throws Exception */ function checkTargetPageNames($runas) { foreach (array_keys($this->templates) as $pname) { // prevent overriding already existing pages if (page_exists($pname)) { throw new Exception(sprintf($this->getLang('e_pageexists'), html_wikilink($pname))); } // check auth if ($runas) { $auth = auth_aclcheck($pname, $runas, array()); } else { $auth = auth_quickaclcheck($pname); } if ($auth < AUTH_CREATE) { throw new Exception($this->getLang('e_denied')); } } return $pname; }
/** * Convinience function for auth_aclcheck() * * This checks the permissions for the current user * * @author Andreas Gohr <*****@*****.**> * * @param string $id page ID (needs to be resolved and cleaned) * @return int permission level */ function auth_quickaclcheck($id) { global $conf; global $USERINFO; # if no ACL is used always return upload rights if (!$conf['useacl']) { return AUTH_UPLOAD; } return auth_aclcheck($id, $_SERVER['REMOTE_USER'], $USERINFO['grps']); }
function test_multiadmin_restricted_ropage() { global $conf; global $AUTH_ACL; $conf['superuser'] = '******'; $conf['useacl'] = 1; $AUTH_ACL = array('* @ALL 0', '* @user 8', 'namespace:page @user 1'); // anonymous user $this->assertEqual(auth_aclcheck('page', '', array()), AUTH_NONE); $this->assertEqual(auth_aclcheck('namespace:page', '', array()), AUTH_NONE); $this->assertEqual(auth_aclcheck('namespace:*', '', array()), AUTH_NONE); // user with no matching group $this->assertEqual(auth_aclcheck('page', 'jill', array('foo')), AUTH_NONE); $this->assertEqual(auth_aclcheck('namespace:page', 'jill', array('foo')), AUTH_NONE); $this->assertEqual(auth_aclcheck('namespace:*', 'jill', array('foo')), AUTH_NONE); // user with matching group $this->assertEqual(auth_aclcheck('page', 'jill', array('foo', 'user')), AUTH_UPLOAD); $this->assertEqual(auth_aclcheck('namespace:page', 'jill', array('foo', 'user')), AUTH_READ); $this->assertEqual(auth_aclcheck('namespace:*', 'jill', array('foo', 'user')), AUTH_UPLOAD); // super user john $this->assertEqual(auth_aclcheck('page', 'john', array('foo')), AUTH_ADMIN); $this->assertEqual(auth_aclcheck('namespace:page', 'john', array('foo')), AUTH_ADMIN); $this->assertEqual(auth_aclcheck('namespace:*', 'john', array('foo')), AUTH_ADMIN); // super user doe $this->assertEqual(auth_aclcheck('page', 'doe', array('foo')), AUTH_ADMIN); $this->assertEqual(auth_aclcheck('namespace:page', 'doe', array('foo')), AUTH_ADMIN); $this->assertEqual(auth_aclcheck('namespace:*', 'doe', array('foo')), AUTH_ADMIN); // user with matching admin group $this->assertEqual(auth_aclcheck('page', 'jill', array('foo', 'admin')), AUTH_ADMIN); $this->assertEqual(auth_aclcheck('namespace:page', 'jill', array('foo', 'admin')), AUTH_ADMIN); $this->assertEqual(auth_aclcheck('namespace:*', 'jill', array('foo', 'admin')), AUTH_ADMIN); // user with matching another admin group $this->assertEqual(auth_aclcheck('page', 'jill', array('foo', 'roots')), AUTH_ADMIN); $this->assertEqual(auth_aclcheck('namespace:page', 'jill', array('foo', 'roots')), AUTH_ADMIN); $this->assertEqual(auth_aclcheck('namespace:*', 'jill', array('foo', 'roots')), AUTH_ADMIN); }
/** * find hierarchically highest level parent namespace which allows acl CREATE */ function get_start_dir() { global $Config; global $AUTH; global $AUTH_INI; global $sep; global $dwfck_client; if (!$dwfck_client || $AUTH_INI == 255) { return ""; } if (isset($_REQUEST['DWFCK_usergrps'])) { $usergrps = get_conf_array($_REQUEST['DWFCK_usergrps']); } else { $usergrps = array(); } $elems = explode(':', $_COOKIE['FCK_NmSp']); array_pop($elems); $ns = ""; $prev_auth = -1; while (count($elems) > 0) { $ns_tmp = implode(':', $elems); $test = $ns_tmp . ':*'; $AUTH = auth_aclcheck($test, $dwfck_client, $usergrps); if ($AUTH < 4) { if (!$ns) { $ns = $ns_tmp; break; } $AUTH = $prev_auth; break; } $prev_auth = $AUTH; $ns = $ns_tmp; array_pop($elems); } if ($ns) { if (strpos($ns, ':')) { return str_replace(':', '/', $ns); } $AUTH = auth_aclcheck(':*', $dwfck_client, $usergrps); if ($AUTH >= 8) { return ""; } return $ns; } $AUTH = auth_aclcheck(':*', $dwfck_client, $usergrps); return ""; }
function FileUpload($resourceType, $currentFolder, $sCommand) { global $dwfck_conf; if (!isset($_FILES)) { global $_FILES; } $sErrorNumber = '0'; $sFileName = ''; $sess_id = session_id(); if (!isset($sess_id) || $sess_id != $_COOKIE['FCK_NmSp_acl']) { session_id($_COOKIE['FCK_NmSp_acl']); session_start(); } global $Dwfck_conf_values; $dwfck_conf = $_SESSION['dwfck_conf']; if (empty($dwfck_conf)) { $dwfck_conf['deaccent'] = isset($Dwfck_conf_values['deaccent']) ? $Dwfck_conf_values['deaccent'] : 1; $dwfck_conf['useslash'] = isset($Dwfck_conf_values['useslash']) ? $Dwfck_conf_values['useslash'] : 0; $dwfck_conf['sepchar'] = isset($Dwfck_conf_values['sepchar']) ? $Dwfck_conf_values['sepchar'] : '_'; } $auth = 0; if (isset($_REQUEST['TopLevel'])) { list($top_level, $auth) = explode(';;', $_REQUEST['TopLevel']); } $safe = false; global $Dwfck_conf_values; if ($Dwfck_conf_values['fnencode'] == 'safe') { if (preg_match('/%[a-z]+[0-9]/', $currentFolder) || preg_match('/%[0-9][a-z]/', $currentFolder)) { $safe = true; } } $ns_tmp = dwiki_decodeFN(trim($currentFolder, '/')); $ns_tmp = str_replace('/', ':', $ns_tmp); $test = $ns_tmp . ':*'; if (!$safe) { $test = urldecode($test); while (preg_match('/%25/', $test)) { $test = urldecode($test); } $test = urldecode($test); } $isadmin = isset($_SESSION['dwfck_conf']['isadmin']) ? $_SESSION['dwfck_conf']['isadmin'] : false; if (!$isadmin) { $AUTH = auth_aclcheck($test, $_SESSION['dwfck_client'], $_SESSION['dwfck_grps'], 1); if ($AUTH < 8) { $msg = ""; $sFileUrl = CombinePaths(GetResourceTypePath($resourceType, $sCommand), $currentFolder); $sFileUrl = CombinePaths($sFileUrl, $_FILES['NewFile']['name']); SendUploadResults('203', $sFileUrl, htmlentities($_FILES['NewFile']['name']), $msg); return; } } if (!$safe) { $currentFolder = encode_dir($currentFolder); } if (isset($_FILES['NewFile']) && !is_null($_FILES['NewFile']['tmp_name'])) { global $Config; $upload_err = $_FILES['NewFile']['error']; if ($upload_err) { send_ckg_UploadError($upload_err, $sFileUrl, htmlentities($_FILES['NewFile']['name'])); exit; } $oFile = $_FILES['NewFile']; // Map the virtual path to the local server path. $sServerDir = ServerMapFolder($resourceType, $currentFolder, $sCommand); // Get the uploaded file name. $sFileName = dwiki_encodeFN($oFile['name']); $sOriginalFileName = dwiki_encodeFN($sFileName); // Get the extension. $sExtension = substr($sFileName, strrpos($sFileName, '.') + 1); $sExtension = strtolower($sExtension); $image_file = false; if (in_array($sExtension, $Config['AllowedExtensions']['Image'])) { $image_file = true; } if (isset($Config['SecureImageUploads'])) { if (($isImageValid = IsImageValid($oFile['tmp_name'], $sExtension)) === false) { $sErrorNumber = '202'; } } if (isset($Config['HtmlExtensions'])) { if (!IsHtmlExtension($sExtension, $Config['HtmlExtensions']) && ($detectHtml = DetectHtml($oFile['tmp_name'])) === true) { $sErrorNumber = '202'; } } $sFileName = Dwfck_sanitize($sFileName, $image_file); // Check if it is an allowed extension. if (!$sErrorNumber && IsAllowedExt($sExtension, $resourceType)) { $iCounter = 0; while (true) { //$sFileName = strtolower($sFileName); if (!is_dir($sServerDir)) { if (isset($Config['ChmodOnFolderCreate']) && !$Config['ChmodOnFolderCreate']) { mkdir_rek($sServerDir, $permissions); } else { $permissions = 0777; if (isset($Config['ChmodOnFolderCreate'])) { $permissions = $Config['ChmodOnFolderCreate']; } // To create the folder with 0777 permissions, we need to set umask to zero. $oldumask = umask(0); mkdir_rek($sServerDir, $permissions); umask($oldumask); } } $sFilePath = $sServerDir . $sFileName; if (is_file($sFilePath)) { $iCounter++; if ($Dwfck_conf_values['fnencode'] == 'safe') { $sFileName = RemoveExtension(dwiki_decodeFN($sOriginalFileName)) . '_' . $iCounter . ".{$sExtension}"; } else { $sFileName = RemoveExtension($sOriginalFileName) . '_' . $iCounter . ".{$sExtension}"; } $sFileName = Dwfck_sanitize($sFileName, $image_file); $sErrorNumber = '201'; } else { move_uploaded_file($oFile['tmp_name'], $sFilePath); if (is_file($sFilePath)) { if (isset($Config['ChmodOnUpload']) && !$Config['ChmodOnUpload']) { break; } $permissions = 0777; if (isset($Config['ChmodOnUpload']) && $Config['ChmodOnUpload']) { $permissions = $Config['ChmodOnUpload']; } $oldumask = umask(0); chmod($sFilePath, $permissions); umask($oldumask); } break; } } if (file_exists($sFilePath)) { //previous checks failed, try once again if (isset($isImageValid) && $isImageValid === -1 && IsImageValid($sFilePath, $sExtension) === false) { @unlink($sFilePath); $sErrorNumber = '202'; } else { if (isset($detectHtml) && $detectHtml === -1 && DetectHtml($sFilePath) === true) { @unlink($sFilePath); $sErrorNumber = '202'; } } } } else { $sErrorNumber = '202'; } } else { $sErrorNumber = '202'; } $sFileUrl = CombinePaths(GetResourceTypePath($resourceType, $sCommand), $currentFolder); $sFileUrl = CombinePaths($sFileUrl, $sFileName); SendUploadResults($sErrorNumber, $sFileUrl, htmlentities($sFileName)); exit; }
/** * Check if a media item is public (eg, external URL or readable by @ALL) * * @author Andreas Gohr <*****@*****.**> * @param string $id the media ID or URL * @return bool */ function media_ispublic($id) { if (preg_match('/^https?:\\/\\//i', $id)) { return true; } $id = cleanID($id); if (auth_aclcheck(getNS($id) . ':*', '', array()) >= AUTH_READ) { return true; } return false; }
/** * Return a string with the email addresses of all the * users subscribed to a page * * This is the default action for COMMON_NOTIFY_ADDRESSLIST. * * @param array $data Containing $id (the page id), $self (whether the author * should be notified, $addresslist (current email address * list) * * @author Steven Danz <*****@*****.**> * @author Adrian Lang <*****@*****.**> */ function subscription_addresslist(&$data) { global $conf; global $auth; $id = $data['id']; $self = $data['self']; $addresslist = $data['addresslist']; if (!$conf['subscribers'] || $auth === null) { return ''; } $pres = array('style' => 'every', 'escaped' => true); if (!$self && isset($_SERVER['REMOTE_USER'])) { $pres['user'] = '******' . preg_quote_cb($_SERVER['REMOTE_USER']) . '(?: |$))\\S+)'; } $subs = subscription_find($id, $pres); $emails = array(); foreach ($subs as $by_targets) { foreach ($by_targets as $sub) { $info = $auth->getUserData($sub[0]); if ($info === false) { continue; } $level = auth_aclcheck($id, $sub[0], $info['grps']); if ($level >= AUTH_READ) { if (strcasecmp($info['mail'], $conf['notify']) != 0) { $emails[$sub[0]] = $info['mail']; } } } } $data['addresslist'] = trim($addresslist . ',' . implode(',', $emails), ','); }
function run($data, $thanks, $argv) { global $ID; global $conf; global $USERINFO; list($tpl, $pagename, $sep) = $argv; if (is_null($sep)) { $sep = $conf['sepchar']; } $runas = $this->getConf('runas'); $patterns = array(); $values = array(); $templates = array(); // run through fields foreach ($data as $opt) { $label = $opt->getParam('label'); $value = $opt->getParam('value'); // prepare replacements if (!is_null($label)) { $patterns[$label] = '/(@@|##)' . preg_quote($label, '/') . '(?:\\|([^|]*?))' . (is_null($value) ? '' : '?') . '\\1/si'; $values[$label] = is_null($value) ? '$2' : $value; $patterns[$label . '|'] = '/(@@|##)' . preg_quote($label, '/') . '(?:\\|(.*?))(?:\\|(.*?))\\1/si'; $values[$label . '|'] = is_null($value) ? '$2' : '$3'; } // handle pagenames $pname = $opt->getParam('pagename'); if (!is_null($pname)) { $pagename .= $sep . $pname; } if (!is_null($opt->getParam('page_tpl')) && !is_null($opt->getParam('page_tgt'))) { $page_tpl = $this->replace($patterns, $values, $opt->getParam('page_tpl')); if (auth_aclcheck($page_tpl, $runas ? $runas : $_SERVER['REMOTE_USER'], $USERINFO['grps']) >= AUTH_READ) { $templates[$opt->getParam('page_tgt')] = rawWiki($page_tpl); } } } $pagename = $this->replace($patterns, $values, $pagename); // check pagename $pagename = cleanID($pagename); if ($pagename === '') { throw new Exception($this->getLang('e_pagename')); } $_templates = array(); foreach ($templates as $k => $v) { $_templates[cleanID("{$pagename}:{$k}")] = $v; } $templates = $_templates; // get templates if ($tpl == '_') { // use namespace template if (!isset($templates[$pagename])) { $templates[$pagename] = pageTemplate(array($pagename)); } } elseif ($tpl !== '!') { // Namespace link require_once DOKU_INC . 'inc/search.php'; if ($runas) { // Hack user credentials. global $USERINFO; $backup = array($_SERVER['REMOTE_USER'], $USERINFO['grps']); $_SERVER['REMOTE_USER'] = $runas; $USERINFO['grps'] = array(); } $t_pages = array(); search($t_pages, $conf['datadir'], 'search_universal', array('depth' => 0, 'listfiles' => true), str_replace(':', '/', getNS($tpl))); foreach ($t_pages as $t_page) { $t_name = cleanID($t_page['id']); $p_name = preg_replace('/^' . preg_quote_cb(cleanID($tpl)) . '($|:)/', $pagename . '$1', $t_name); if ($p_name === $t_name) { // When using a single-page template, ignore other pages // in the same namespace. continue; } if (!isset($templates[$p_name])) { // load page data and do default pattern replacements like // namespace templates do $data = array('id' => $p_name, 'tpl' => rawWiki($t_name), 'doreplace' => true); parsePageTemplate($data); $templates[$p_name] = $data['tpl']; } } if ($runas) { /* Restore user credentials. */ global $USERINFO; list($_SERVER['REMOTE_USER'], $USERINFO['grps']) = $backup; } } if (empty($templates)) { throw new Exception(sprintf($this->getLang('e_template'), $tpl)); } // check all target pagenames foreach (array_keys($templates) as $pname) { // prevent overriding already existing pages if (page_exists($pname)) { throw new Exception(sprintf($this->getLang('e_pageexists'), html_wikilink($pname))); } // check auth if ($runas) { $auth = auth_aclcheck($pname, $runas, array()); } else { $auth = auth_quickaclcheck($pname); } if ($auth < AUTH_CREATE) { throw new Exception($this->getLang('e_denied')); } } foreach ($templates as $pname => $template) { // set NSBASE var to make certain dataplugin constructs easier $patterns['__nsbase__'] = '/@NSBASE@/'; $values['__nsbase__'] = noNS(getNS($pname)); // save page saveWikiText($pname, $this->replace($patterns, $values, $template, false), sprintf($this->getLang('summary'), $ID)); } $ret = "<p>{$thanks}</p>"; // Build result tree $pages = array_keys($templates); usort($pages, array($this, '_sort')); $oldid = $ID; $data = array(); $last_folder = array(); foreach ($pages as $ID) { $lvl = substr_count($ID, ':'); for ($n = 0; $n < $lvl; ++$n) { if (!isset($last_folder[$n]) || strpos($ID, $last_folder[$n]['id']) !== 0) { $last_folder[$n] = array('id' => substr($ID, 0, strpos($ID, ':', ($n > 0 ? strlen($last_folder[$n - 1]['id']) : 0) + 1) + 1), 'level' => $n + 1, 'open' => 1); $data[] = $last_folder[$n]; } } $data[] = array('id' => $ID, 'level' => 1 + substr_count($ID, ':'), 'type' => 'f'); } $ret .= html_buildlist($data, 'idx', array($this, 'html_list_index'), 'html_li_index'); // Add indexer bugs for every just-created page $ret .= '<div class="no">'; ob_start(); foreach ($pages as $ID) { // indexerWebBug uses ID and INFO[exists], but the bureaucracy form // page always exists, as does the just-saved page, so INFO[exists] // is correct in any case tpl_indexerWebBug(); // the iframe will trigger real rendering of the pages to make sure // any used plugins are initialized (eg. the do plugin) echo '<iframe src="' . wl($ID, array('do' => 'export_html')) . '" width="1" height="1" style="visibility:hidden"></iframe>'; } $ret .= ob_get_contents(); ob_end_clean(); $ID = $oldid; $ret .= '</div>'; return $ret; }
function test_wildcards() { global $conf; global $AUTH_ACL; global $USERINFO; $conf['useacl'] = 1; $_SERVER['REMOTE_USER'] = '******'; $USERINFO['grps'] = array('test', 'töst', 'foo bar'); $AUTH_ACL = auth_loadACL(); // default test file // default setting $this->assertEquals(AUTH_UPLOAD, auth_aclcheck('page', $_SERVER['REMOTE_USER'], $USERINFO['grps'])); // user namespace $this->assertEquals(AUTH_DELETE, auth_aclcheck('users:john:foo', $_SERVER['REMOTE_USER'], $USERINFO['grps'])); $this->assertEquals(AUTH_READ, auth_aclcheck('users:john:foo', 'schmock', array())); // group namespace $this->assertEquals(AUTH_DELETE, auth_aclcheck('groups:test:foo', $_SERVER['REMOTE_USER'], $USERINFO['grps'])); $this->assertEquals(AUTH_READ, auth_aclcheck('groups:test:foo', 'schmock', array())); $this->assertEquals(AUTH_DELETE, auth_aclcheck('groups:toest:foo', $_SERVER['REMOTE_USER'], $USERINFO['grps'])); $this->assertEquals(AUTH_READ, auth_aclcheck('groups:toest:foo', 'schmock', array())); $this->assertEquals(AUTH_DELETE, auth_aclcheck('groups:foo_bar:foo', $_SERVER['REMOTE_USER'], $USERINFO['grps'])); $this->assertEquals(AUTH_READ, auth_aclcheck('groups:foo_bar:foo', 'schmock', array())); }
/** * Check if a media item is public (eg, external URL or readable by @ALL) * * @author Andreas Gohr <*****@*****.**> * @param string $id the media ID or URL * @return bool */ function media_ispublic($id) { if (media_isexternal($id)) { return true; } $id = cleanID($id); if (auth_aclcheck(getNS($id) . ':*', '', array()) >= AUTH_READ) { return true; } return false; }
/** * Return info about the current document as associative * array. * * @author Andreas Gohr <*****@*****.**> */ function pageinfo() { global $ID; global $REV; global $RANGE; global $USERINFO; global $lang; // include ID & REV not redundant, as some parts of DokuWiki may temporarily change $ID, e.g. p_wiki_xhtml // FIXME ... perhaps it would be better to ensure the temporary changes weren't necessary $info['id'] = $ID; $info['rev'] = $REV; // set info about manager/admin status. $info['isadmin'] = false; $info['ismanager'] = false; if (isset($_SERVER['REMOTE_USER'])) { $info['userinfo'] = $USERINFO; $info['perm'] = auth_quickaclcheck($ID); $info['subscribed'] = get_info_subscribed(); $info['client'] = $_SERVER['REMOTE_USER']; if ($info['perm'] == AUTH_ADMIN) { $info['isadmin'] = true; $info['ismanager'] = true; } elseif (auth_ismanager()) { $info['ismanager'] = true; } // if some outside auth were used only REMOTE_USER is set if (!$info['userinfo']['name']) { $info['userinfo']['name'] = $_SERVER['REMOTE_USER']; } } else { $info['perm'] = auth_aclcheck($ID, '', null); $info['subscribed'] = false; $info['client'] = clientIP(true); } $info['namespace'] = getNS($ID); $info['locked'] = checklock($ID); $info['filepath'] = fullpath(wikiFN($ID)); $info['exists'] = @file_exists($info['filepath']); if ($REV) { //check if current revision was meant if ($info['exists'] && @filemtime($info['filepath']) == $REV) { $REV = ''; } elseif ($RANGE) { //section editing does not work with old revisions! $REV = ''; $RANGE = ''; msg($lang['nosecedit'], 0); } else { //really use old revision $info['filepath'] = fullpath(wikiFN($ID, $REV)); $info['exists'] = @file_exists($info['filepath']); } } $info['rev'] = $REV; if ($info['exists']) { $info['writable'] = is_writable($info['filepath']) && $info['perm'] >= AUTH_EDIT; } else { $info['writable'] = $info['perm'] >= AUTH_CREATE; } $info['editable'] = $info['writable'] && empty($info['locked']); $info['lastmod'] = @filemtime($info['filepath']); //load page meta data $info['meta'] = p_get_metadata($ID); //who's the editor if ($REV) { $revinfo = getRevisionInfo($ID, $REV, 1024); } else { if (is_array($info['meta']['last_change'])) { $revinfo = $info['meta']['last_change']; } else { $revinfo = getRevisionInfo($ID, $info['lastmod'], 1024); // cache most recent changelog line in metadata if missing and still valid if ($revinfo !== false) { $info['meta']['last_change'] = $revinfo; p_set_metadata($ID, array('last_change' => $revinfo)); } } } //and check for an external edit if ($revinfo !== false && $revinfo['date'] != $info['lastmod']) { // cached changelog line no longer valid $revinfo = false; $info['meta']['last_change'] = $revinfo; p_set_metadata($ID, array('last_change' => $revinfo)); } $info['ip'] = $revinfo['ip']; $info['user'] = $revinfo['user']; $info['sum'] = $revinfo['sum']; // See also $INFO['meta']['last_change'] which is the most recent log line for page $ID. // Use $INFO['meta']['last_change']['type']===DOKU_CHANGE_TYPE_MINOR_EDIT in place of $info['minor']. if ($revinfo['user']) { $info['editor'] = $revinfo['user']; } else { $info['editor'] = $revinfo['ip']; } // draft $draft = getCacheName($info['client'] . $ID, '.draft'); if (@file_exists($draft)) { if (@filemtime($draft) < @filemtime(wikiFN($ID))) { // remove stale draft @unlink($draft); } else { $info['draft'] = $draft; } } // mobile detection $info['ismobile'] = clientismobile(); return $info; }
if (!$id) { exit; } $remake = isset($opts['remake']) ? $opts['remake'] : FALSE; if (!isset($opts['baseurl'])) { exit; } define(DOKU_URL, $opts['baseurl']); define(DOKU_REL, $opts['baseurl']); require_once dirname(__FILE__) . '/project/file.php'; require_once DOKU_INC . '/inc/init.php'; if (!isset($opts['sectok'])) { exit; } if (!checkSecurityToken($opts['sectok'])) { exit; } $user = !isset($opts['user']) ? '' : $opts['user']; $group = !isset($opts['group']) ? '' : $opts['group']; $group = explode(':', $group); if (auth_aclcheck($id, $user, $group) < DOKU_EDIT) { exit; } $file = Projects_file::file($id); if ($file->is_making()) { return; } $result = $file->make(array(), $remake); if (is_numeric($result)) { copy($file->file_path(), mediaFN($file->id())); }
/** * Explain the currently set permissions in plain english/$lang * * @author Andreas Gohr <*****@*****.**> */ function _html_explain($current) { global $ID; global $auth; $who = $this->who; $ns = $this->ns; // prepare where to check if ($ns) { if ($ns == '*') { $check = '*'; } else { $check = $ns . ':*'; } } else { $check = $ID; } // prepare who to check if ($who[0] == '@') { $user = ''; $groups = array(ltrim($who, '@')); } else { $user = $who; $info = $auth->getUserData($user); if ($info === false) { $groups = array(); } else { $groups = $info['grps']; } } // check the permissions $perm = auth_aclcheck($check, $user, $groups); // build array of named permissions $names = array(); if ($perm) { if ($ns) { if ($perm >= AUTH_DELETE) { $names[] = $this->getLang('acl_perm16'); } if ($perm >= AUTH_UPLOAD) { $names[] = $this->getLang('acl_perm8'); } if ($perm >= AUTH_CREATE) { $names[] = $this->getLang('acl_perm4'); } } if ($perm >= AUTH_EDIT) { $names[] = $this->getLang('acl_perm2'); } if ($perm >= AUTH_READ) { $names[] = $this->getLang('acl_perm1'); } $names = array_reverse($names); } else { $names[] = $this->getLang('acl_perm0'); } // print permission explanation echo '<p>'; if ($user) { if ($ns) { printf($this->getLang('p_user_ns'), hsc($who), hsc($ns), join(', ', $names)); } else { printf($this->getLang('p_user_id'), hsc($who), hsc($ID), join(', ', $names)); } } else { if ($ns) { printf($this->getLang('p_group_ns'), hsc(ltrim($who, '@')), hsc($ns), join(', ', $names)); } else { printf($this->getLang('p_group_id'), hsc(ltrim($who, '@')), hsc($ID), join(', ', $names)); } } echo '</p>'; // add note if admin if ($perm == AUTH_ADMIN) { echo '<p>' . $this->getLang('p_isadmin') . '</p>'; } elseif (is_null($current)) { echo '<p>' . $this->getLang('p_inherited') . '</p>'; } }
/** * Builds a Google Sitemap of all public pages known to the indexer * * The map is placed in the root directory named sitemap.xml.gz - This * file needs to be writable! * * @author Andreas Gohr * @link https://www.google.com/webmasters/sitemaps/docs/en/about.html */ function runSitemapper() { global $conf; print "runSitemapper(): started" . NL; if (!$conf['sitemap']) { return false; } if ($conf['compression'] == 'bz2' || $conf['compression'] == 'gz') { $sitemap = 'sitemap.xml.gz'; } else { $sitemap = 'sitemap.xml'; } print "runSitemapper(): using {$sitemap}" . NL; if (@file_exists(DOKU_INC . $sitemap)) { if (!is_writable(DOKU_INC . $sitemap)) { return false; } } else { if (!is_writable(DOKU_INC)) { return false; } } if (@filesize(DOKU_INC . $sitemap) && @filemtime(DOKU_INC . $sitemap) > time() - $conf['sitemap'] * 60 * 60 * 24) { print 'runSitemapper(): Sitemap up to date' . NL; return false; } $pages = file($conf['indexdir'] . '/page.idx'); print 'runSitemapper(): creating sitemap using ' . count($pages) . ' pages' . NL; // build the sitemap ob_start(); print '<?xml version="1.0" encoding="UTF-8"?>' . NL; print '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . NL; foreach ($pages as $id) { $id = trim($id); $file = wikiFN($id); //skip hidden, non existing and restricted files if (isHiddenPage($id)) { continue; } $date = @filemtime($file); if (!$date) { continue; } if (auth_aclcheck($id, '', '') < AUTH_READ) { continue; } print ' <url>' . NL; print ' <loc>' . wl($id, '', true) . '</loc>' . NL; print ' <lastmod>' . date_iso8601($date) . '</lastmod>' . NL; print ' </url>' . NL; } print '</urlset>' . NL; $data = ob_get_contents(); ob_end_clean(); //save the new sitemap io_saveFile(DOKU_INC . $sitemap, $data); //ping search engines... $http = new DokuHTTPClient(); $http->timeout = 8; //ping google print 'runSitemapper(): pinging google' . NL; $url = 'http://www.google.com/webmasters/sitemaps/ping?sitemap='; $url .= urlencode(DOKU_URL . $sitemap); $resp = $http->get($url); if ($http->error) { print 'runSitemapper(): ' . $http->error . NL; } print 'runSitemapper(): ' . preg_replace('/[\\n\\r]/', ' ', strip_tags($resp)) . NL; //ping yahoo print 'runSitemapper(): pinging yahoo' . NL; $url = 'http://search.yahooapis.com/SiteExplorerService/V1/updateNotification?appid=dokuwiki&url='; $url .= urlencode(DOKU_URL . $sitemap); $resp = $http->get($url); if ($http->error) { print 'runSitemapper(): ' . $http->error . NL; } print 'runSitemapper(): ' . preg_replace('/[\\n\\r]/', ' ', strip_tags($resp)) . NL; //ping microsoft print 'runSitemapper(): pinging microsoft' . NL; $url = 'http://www.bing.com/webmaster/ping.aspx?siteMap='; $url .= urlencode(DOKU_URL . $sitemap); $resp = $http->get($url); if ($http->error) { print 'runSitemapper(): ' . $http->error . NL; } print 'runSitemapper(): ' . preg_replace('/[\\n\\r]/', ' ', strip_tags($resp)) . NL; print 'runSitemapper(): finished' . NL; return true; }
/** * Convinience function for auth_aclcheck() * * This checks the permissions for the current user * * @author Andreas Gohr <*****@*****.**> * * @param string $id page ID (needs to be resolved and cleaned) * @return int permission level */ function auth_quickaclcheck($id) { global $conf; global $USERINFO; // for PART-DB return !$conf['useacl'] && file_exists(DOKU_INC . '../../data/ENABLE-DOKUWIKI-WRITE-PERMS.txt') ? AUTH_ADMIN : AUTH_READ; # if no ACL is used always return upload rights if (!$conf['useacl']) { return AUTH_UPLOAD; } return auth_aclcheck($id, $_SERVER['REMOTE_USER'], $USERINFO['grps']); }
function test_restricted_allread() { global $conf; global $AUTH_ACL; $conf['superuser'] = '******'; $conf['useacl'] = 1; $AUTH_ACL = array('* @ALL 1', '* @group1 8'); // anonymous user $this->assertEquals(auth_aclcheck('page', '', array()), AUTH_READ); $this->assertEquals(auth_aclcheck('namespace:page', '', array()), AUTH_READ); $this->assertEquals(auth_aclcheck('namespace:*', '', array()), AUTH_READ); // user with no matching group $this->assertEquals(auth_aclcheck('page', 'jill', array('foo')), AUTH_READ); $this->assertEquals(auth_aclcheck('namespace:page', 'jill', array('foo')), AUTH_READ); $this->assertEquals(auth_aclcheck('namespace:*', 'jill', array('foo')), AUTH_READ); // user with matching group $this->assertEquals(auth_aclcheck('page', 'jill', array('foo', 'Group1')), AUTH_UPLOAD); $this->assertEquals(auth_aclcheck('namespace:page', 'jill', array('foo', 'Group1')), AUTH_UPLOAD); $this->assertEquals(auth_aclcheck('namespace:*', 'jill', array('foo', 'Group1')), AUTH_UPLOAD); // super user $this->assertEquals(auth_aclcheck('page', 'John', array('foo')), AUTH_ADMIN); $this->assertEquals(auth_aclcheck('namespace:page', 'John', array('foo')), AUTH_ADMIN); $this->assertEquals(auth_aclcheck('namespace:*', 'John', array('foo')), AUTH_ADMIN); }