/** * Do some important security checks: * * What it does: * - checks the existence of critical files e.g. install.php * - checks for an active admin session. * - checks cache directory is writable. * - calls secureDirectory to protect attachments & cache. * - checks if the forum is in maintance mode. */ function doSecurityChecks() { global $modSettings, $context, $maintenance, $user_info, $txt, $scripturl, $user_settings, $options; $show_warnings = false; if (allowedTo('admin_forum') && !$user_info['is_guest']) { // If agreement is enabled, at least the english version shall exists if ($modSettings['requireAgreement'] && !file_exists(BOARDDIR . '/agreement.txt')) { $context['security_controls_files']['title'] = $txt['generic_warning']; $context['security_controls_files']['errors']['agreement'] = $txt['agreement_missing']; $show_warnings = true; } // Cache directory writeable? if (!empty($modSettings['cache_enable']) && !is_writable(CACHEDIR)) { $context['security_controls_files']['title'] = $txt['generic_warning']; $context['security_controls_files']['errors']['cache'] = $txt['cache_writable']; $show_warnings = true; } // @todo add a hook here $securityFiles = array('install.php', 'upgrade.php', 'convert.php', 'repair_paths.php', 'repair_settings.php', 'Settings.php~', 'Settings_bak.php~'); foreach ($securityFiles as $securityFile) { if (file_exists(BOARDDIR . '/' . $securityFile)) { $context['security_controls_files']['title'] = $txt['security_risk']; $context['security_controls_files']['errors'][$securityFile] = sprintf($txt['not_removed'], $securityFile); $show_warnings = true; if ($securityFile == 'Settings.php~' || $securityFile == 'Settings_bak.php~') { $context['security_controls_files']['errors'][$securityFile] .= '<span class="smalltext">' . sprintf($txt['not_removed_extra'], $securityFile, substr($securityFile, 0, -1)) . '</span>'; } } } // We are already checking so many files...just few more doesn't make any difference! :P require_once SUBSDIR . '/Attachments.subs.php'; $path = getAttachmentPath(); secureDirectory($path, true); secureDirectory(CACHEDIR); // Active admin session? if (empty($modSettings['securityDisable']) && (isset($_SESSION['admin_time']) && $_SESSION['admin_time'] + $modSettings['admin_session_lifetime'] * 60 > time())) { $context['warning_controls']['admin_session'] = sprintf($txt['admin_session_active'], $scripturl . '?action=admin;area=adminlogoff;redir;' . $context['session_var'] . '=' . $context['session_id']); } // Maintenance mode enabled? if (!empty($maintenance)) { $context['warning_controls']['maintenance'] = sprintf($txt['admin_maintenance_active'], $scripturl . '?action=admin;area=serversettings;' . $context['session_var'] . '=' . $context['session_id']); } // New updates if (defined('FORUM_VERSION')) { $index = 'new_in_' . str_replace(array('ElkArte ', '.'), array('', '_'), FORUM_VERSION); if (!empty($modSettings[$index]) && empty($options['dismissed_' . $index])) { $show_warnings = true; $context['new_version_updates'] = array('title' => $txt['new_version_updates'], 'errors' => array(replaceBasicActionUrl($txt['new_version_updates_text']))); } } } // Check for database errors. if (!empty($_SESSION['query_command_denied'])) { if ($user_info['is_admin']) { $context['security_controls_query']['title'] = $txt['query_command_denied']; $show_warnings = true; foreach ($_SESSION['query_command_denied'] as $command => $error) { $context['security_controls_query']['errors'][$command] = '<pre>' . Util::htmlspecialchars($error) . '</pre>'; } } else { $context['security_controls_query']['title'] = $txt['query_command_denied_guests']; foreach ($_SESSION['query_command_denied'] as $command => $error) { $context['security_controls_query']['errors'][$command] = '<pre>' . sprintf($txt['query_command_denied_guests_msg'], Util::htmlspecialchars($command)) . '</pre>'; } } } // Are there any members waiting for approval? if (allowedTo('moderate_forum') && (!empty($modSettings['registration_method']) && $modSettings['registration_method'] == 2 || !empty($modSettings['approveAccountDeletion'])) && !empty($modSettings['unapprovedMembers'])) { $context['warning_controls']['unapproved_members'] = sprintf($txt[$modSettings['unapprovedMembers'] == 1 ? 'approve_one_member_waiting' : 'approve_many_members_waiting'], $scripturl . '?action=admin;area=viewmembers;sa=browse;type=approve', $modSettings['unapprovedMembers']); } if (!empty($context['open_mod_reports']) && (empty($user_settings['mod_prefs']) || $user_settings['mod_prefs'][0] == 1)) { $context['warning_controls']['open_mod_reports'] = '<a href="' . $scripturl . '?action=moderate;area=reports">' . sprintf($txt['mod_reports_waiting'], $context['open_mod_reports']) . '</a>'; } if (isset($_SESSION['ban']['cannot_post'])) { // An admin cannot be banned (technically he could), and if it is better he knows. $context['security_controls_ban']['title'] = sprintf($txt['you_are_post_banned'], $user_info['is_guest'] ? $txt['guest_title'] : $user_info['name']); $show_warnings = true; $context['security_controls_ban']['errors']['reason'] = ''; if (!empty($_SESSION['ban']['cannot_post']['reason'])) { $context['security_controls_ban']['errors']['reason'] = $_SESSION['ban']['cannot_post']['reason']; } if (!empty($_SESSION['ban']['expire_time'])) { $context['security_controls_ban']['errors']['reason'] .= '<span class="smalltext">' . sprintf($txt['your_ban_expires'], standardTime($_SESSION['ban']['expire_time'], false)) . '</span>'; } else { $context['security_controls_ban']['errors']['reason'] .= '<span class="smalltext">' . $txt['your_ban_expires_never'] . '</span>'; } } // Finally, let's show the layer. if ($show_warnings || !empty($context['warning_controls'])) { Template_Layers::getInstance()->addAfter('admin_warning', 'body'); } }
/** * Creates a directory as defined by the admin attach options * * What it does: * - Attempts to make the directory writable * - Places an .htaccess in new directories for security * * @package Attachments * @param string $updir */ function automanage_attachments_create_directory($updir) { global $modSettings, $context; $tree = get_directory_tree_elements($updir); $count = count($tree); $directory = !empty($tree) ? attachments_init_dir($tree, $count) : false; if ($directory === false) { // Maybe it's just the folder name $tree = get_directory_tree_elements(BOARDDIR . DIRECTORY_SEPARATOR . $updir); $count = count($tree); $directory = !empty($tree) ? attachments_init_dir($tree, $count) : false; if ($directory === false) { return false; } } $directory .= DIRECTORY_SEPARATOR . array_shift($tree); while (!@is_dir($directory) || $count != -1) { if (!@is_dir($directory)) { if (!@mkdir($directory, 0755)) { $context['dir_creation_error'] = 'attachments_no_create'; return false; } } $directory .= DIRECTORY_SEPARATOR . array_shift($tree); $count--; } // Try to make it writable if (!is_writable($directory)) { chmod($directory, 0755); if (!is_writable($directory)) { chmod($directory, 0775); if (!is_writable($directory)) { chmod($directory, 0777); if (!is_writable($directory)) { $context['dir_creation_error'] = 'attachments_no_write'; return false; } } } } // Everything seems fine...let's create the .htaccess if (!file_exists($directory . DIRECTORY_SEPARATOR . '.htaccess')) { secureDirectory($updir, true); } $sep = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN' ? '\\/' : DIRECTORY_SEPARATOR; $updir = rtrim($updir, $sep); // Only update if it's a new directory if (!in_array($updir, $modSettings['attachmentUploadDir'])) { $modSettings['currentAttachmentUploadDir'] = max(array_keys($modSettings['attachmentUploadDir'])) + 1; $modSettings['attachmentUploadDir'][$modSettings['currentAttachmentUploadDir']] = $updir; updateSettings(array('attachmentUploadDir' => serialize($modSettings['attachmentUploadDir']), 'currentAttachmentUploadDir' => $modSettings['currentAttachmentUploadDir']), true); $modSettings['attachmentUploadDir'] = unserialize($modSettings['attachmentUploadDir']); } $context['attach_dir'] = $modSettings['attachmentUploadDir'][$modSettings['currentAttachmentUploadDir']]; return true; }