/** * Updates the capabilities table with the component capability definitions. * If no parameters are given, the function updates the core moodle * capabilities. * * Note that the absence of the db/access.php capabilities definition file * will cause any stored capabilities for the component to be removed from * the database. * * @param $component - examples: 'moodle', 'mod/forum', 'block/quiz_results' * @return boolean true if success, exception in case of any problems */ function update_capabilities($component = 'moodle') { global $DB; $storedcaps = array(); $filecaps = load_capability_def($component); $cachedcaps = get_cached_capabilities($component); if ($cachedcaps) { foreach ($cachedcaps as $cachedcap) { array_push($storedcaps, $cachedcap->name); // update risk bitmasks and context levels in existing capabilities if needed if (array_key_exists($cachedcap->name, $filecaps)) { if (!array_key_exists('riskbitmask', $filecaps[$cachedcap->name])) { $filecaps[$cachedcap->name]['riskbitmask'] = 0; // no risk if not specified } if ($cachedcap->riskbitmask != $filecaps[$cachedcap->name]['riskbitmask']) { $updatecap = new object(); $updatecap->id = $cachedcap->id; $updatecap->riskbitmask = $filecaps[$cachedcap->name]['riskbitmask']; $DB->update_record('capabilities', $updatecap); } if (!array_key_exists('contextlevel', $filecaps[$cachedcap->name])) { $filecaps[$cachedcap->name]['contextlevel'] = 0; // no context level defined } if ($cachedcap->contextlevel != $filecaps[$cachedcap->name]['contextlevel']) { $updatecap = new object(); $updatecap->id = $cachedcap->id; $updatecap->contextlevel = $filecaps[$cachedcap->name]['contextlevel']; $DB->update_record('capabilities', $updatecap); } } } } // Are there new capabilities in the file definition? $newcaps = array(); foreach ($filecaps as $filecap => $def) { if (!$storedcaps || $storedcaps && in_array($filecap, $storedcaps) === false) { if (!array_key_exists('riskbitmask', $def)) { $def['riskbitmask'] = 0; // no risk if not specified } $newcaps[$filecap] = $def; } } // Add new capabilities to the stored definition. foreach ($newcaps as $capname => $capdef) { $capability = new object(); $capability->name = $capname; $capability->captype = $capdef['captype']; $capability->contextlevel = $capdef['contextlevel']; $capability->component = $component; $capability->riskbitmask = $capdef['riskbitmask']; $DB->insert_record('capabilities', $capability, false); if (isset($capdef['clonepermissionsfrom']) && in_array($capdef['clonepermissionsfrom'], $storedcaps)) { if ($rolecapabilities = $DB->get_records('role_capabilities', array('capability' => $capdef['clonepermissionsfrom']))) { foreach ($rolecapabilities as $rolecapability) { //assign_capability will update rather than insert if capability exists if (!assign_capability($capname, $rolecapability->permission, $rolecapability->roleid, $rolecapability->contextid, true)) { notify('Could not clone capabilities for ' . $capname); } } } // Do we need to assign the new capabilities to roles that have the // legacy capabilities moodle/legacy:* as well? // we ignore legacy key if we have cloned permissions } else { if (isset($capdef['legacy']) && is_array($capdef['legacy']) && !assign_legacy_capabilities($capname, $capdef['legacy'])) { notify('Could not assign legacy capabilities for ' . $capname); } } } // Are there any capabilities that have been removed from the file // definition that we need to delete from the stored capabilities and // role assignments? capabilities_cleanup($component, $filecaps); // reset static caches is_valid_capability('reset', false); return true; }
/** * Used by {@link optional_param()} and {@link required_param()} to * clean the variables and/or cast to specific types, based on * an options field. * <code> * $course->format = clean_param($course->format, PARAM_ALPHA); * $selectedgrade_item = clean_param($selectedgrade_item, PARAM_CLEAN); * </code> * * @global object * @uses PARAM_RAW * @uses PARAM_CLEAN * @uses PARAM_CLEANHTML * @uses PARAM_INT * @uses PARAM_FLOAT * @uses PARAM_NUMBER * @uses PARAM_ALPHA * @uses PARAM_ALPHAEXT * @uses PARAM_ALPHANUM * @uses PARAM_ALPHANUMEXT * @uses PARAM_SEQUENCE * @uses PARAM_BOOL * @uses PARAM_NOTAGS * @uses PARAM_TEXT * @uses PARAM_SAFEDIR * @uses PARAM_SAFEPATH * @uses PARAM_FILE * @uses PARAM_PATH * @uses PARAM_HOST * @uses PARAM_URL * @uses PARAM_LOCALURL * @uses PARAM_PEM * @uses PARAM_BASE64 * @uses PARAM_TAG * @uses PARAM_SEQUENCE * @param mixed $param the variable we are cleaning * @param int $type expected format of param after cleaning. * @return mixed */ function clean_param($param, $type) { global $CFG; if (is_array($param)) { // Let's loop $newparam = array(); foreach ($param as $key => $value) { $newparam[$key] = clean_param($value, $type); } return $newparam; } switch ($type) { case PARAM_RAW: // no cleaning at all return $param; case PARAM_CLEAN: // General HTML cleaning, try to use more specific type if possible if (is_numeric($param)) { return $param; } return clean_text($param); // Sweep for scripts, etc // Sweep for scripts, etc case PARAM_CLEANHTML: // prepare html fragment for display, do not store it into db!! $param = clean_text($param); // Sweep for scripts, etc return trim($param); case PARAM_INT: return (int) $param; // Convert to integer // Convert to integer case PARAM_FLOAT: case PARAM_NUMBER: return (double) $param; // Convert to float // Convert to float case PARAM_ALPHA: // Remove everything not a-z return preg_replace('/[^a-zA-Z]/i', '', $param); case PARAM_ALPHAEXT: // Remove everything not a-zA-Z_- (originally allowed "/" too) return preg_replace('/[^a-zA-Z_-]/i', '', $param); case PARAM_ALPHANUM: // Remove everything not a-zA-Z0-9 return preg_replace('/[^A-Za-z0-9]/i', '', $param); case PARAM_ALPHANUMEXT: // Remove everything not a-zA-Z0-9_- return preg_replace('/[^A-Za-z0-9_-]/i', '', $param); case PARAM_SEQUENCE: // Remove everything not 0-9, return preg_replace('/[^0-9,]/i', '', $param); case PARAM_BOOL: // Convert to 1 or 0 $tempstr = strtolower($param); if ($tempstr === 'on' or $tempstr === 'yes' or $tempstr === 'true') { $param = 1; } else { if ($tempstr === 'off' or $tempstr === 'no' or $tempstr === 'false') { $param = 0; } else { $param = empty($param) ? 0 : 1; } } return $param; case PARAM_NOTAGS: // Strip all tags return strip_tags($param); case PARAM_TEXT: // leave only tags needed for multilang return clean_param(strip_tags($param, '<lang><span>'), PARAM_CLEAN); case PARAM_SAFEDIR: // Remove everything not a-zA-Z0-9_- return preg_replace('/[^a-zA-Z0-9_-]/i', '', $param); case PARAM_SAFEPATH: // Remove everything not a-zA-Z0-9/_- return preg_replace('/[^a-zA-Z0-9\\/_-]/i', '', $param); case PARAM_FILE: // Strip all suspicious characters from filename $param = preg_replace('~[[:cntrl:]]|[&<>"`\\|\':\\/]~u', '', $param); $param = preg_replace('~\\.\\.+~', '', $param); if ($param === '.') { $param = ''; } return $param; case PARAM_PATH: // Strip all suspicious characters from file path $param = str_replace('\\', '/', $param); $param = preg_replace('~[[:cntrl:]]|[&<>"`\\|\':]~u', '', $param); $param = preg_replace('~\\.\\.+~', '', $param); $param = preg_replace('~//+~', '/', $param); return preg_replace('~/(\\./)+~', '/', $param); case PARAM_HOST: // allow FQDN or IPv4 dotted quad $param = preg_replace('/[^\\.\\d\\w-]/', '', $param); // only allowed chars // match ipv4 dotted quad if (preg_match('/(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/', $param, $match)) { // confirm values are ok if ($match[0] > 255 || $match[1] > 255 || $match[3] > 255 || $match[4] > 255) { // hmmm, what kind of dotted quad is this? $param = ''; } } elseif (preg_match('/^[\\w\\d\\.-]+$/', $param) && !preg_match('/^[\\.-]/', $param) && !preg_match('/[\\.-]$/', $param)) { // all is ok - $param is respected } else { // all is not ok... $param = ''; } return $param; case PARAM_URL: // allow safe ftp, http, mailto urls include_once $CFG->dirroot . '/lib/validateurlsyntax.php'; if (!empty($param) && validateUrlSyntax($param, 's?H?S?F?E?u-P-a?I?p?f?q?r?')) { // all is ok, param is respected } else { $param = ''; // not really ok } return $param; case PARAM_LOCALURL: // allow http absolute, root relative and relative URLs within wwwroot $param = clean_param($param, PARAM_URL); if (!empty($param)) { if (preg_match(':^/:', $param)) { // root-relative, ok! } elseif (preg_match('/^' . preg_quote($CFG->wwwroot, '/') . '/i', $param)) { // absolute, and matches our wwwroot } else { // relative - let's make sure there are no tricks if (validateUrlSyntax('/' . $param, 's-u-P-a-p-f+q?r?')) { // looks ok. } else { $param = ''; } } } return $param; case PARAM_PEM: $param = trim($param); // PEM formatted strings may contain letters/numbers and the symbols // forward slash: / // plus sign: + // equal sign: = // , surrounded by BEGIN and END CERTIFICATE prefix and suffixes if (preg_match('/^-----BEGIN CERTIFICATE-----([\\s\\w\\/\\+=]+)-----END CERTIFICATE-----$/', trim($param), $matches)) { list($wholething, $body) = $matches; unset($wholething, $matches); $b64 = clean_param($body, PARAM_BASE64); if (!empty($b64)) { return "-----BEGIN CERTIFICATE-----\n{$b64}\n-----END CERTIFICATE-----\n"; } else { return ''; } } return ''; case PARAM_BASE64: if (!empty($param)) { // PEM formatted strings may contain letters/numbers and the symbols // forward slash: / // plus sign: + // equal sign: = if (0 >= preg_match('/^([\\s\\w\\/\\+=]+)$/', trim($param))) { return ''; } $lines = preg_split('/[\\s]+/', $param, -1, PREG_SPLIT_NO_EMPTY); // Each line of base64 encoded data must be 64 characters in // length, except for the last line which may be less than (or // equal to) 64 characters long. for ($i = 0, $j = count($lines); $i < $j; $i++) { if ($i + 1 == $j) { if (64 < strlen($lines[$i])) { return ''; } continue; } if (64 != strlen($lines[$i])) { return ''; } } return implode("\n", $lines); } else { return ''; } case PARAM_TAG: //as long as magic_quotes_gpc is used, a backslash will be a //problem, so remove *all* backslash. //$param = str_replace('\\', '', $param); //remove some nasties $param = preg_replace('~[[:cntrl:]]|[<>`]~', '', $param); //convert many whitespace chars into one $param = preg_replace('/\\s+/', ' ', $param); $textlib = textlib_get_instance(); $param = $textlib->substr(trim($param), 0, TAG_MAX_LENGTH); return $param; case PARAM_TAGLIST: $tags = explode(',', $param); $result = array(); foreach ($tags as $tag) { $res = clean_param($tag, PARAM_TAG); if ($res !== '') { $result[] = $res; } } if ($result) { return implode(',', $result); } else { return ''; } case PARAM_CAPABILITY: if (is_valid_capability($param)) { return $param; } else { return ''; } case PARAM_PERMISSION: $param = (int) $param; if (in_array($param, array(CAP_INHERIT, CAP_ALLOW, CAP_PREVENT, CAP_PROHIBIT))) { return $param; } else { return CAP_INHERIT; } default: // throw error, switched parameters in optional_param or another serious problem print_error("unknowparamtype", '', '', $type); } }
/** * see admin_externalpage * * @return bool Returns true for yes false for no */ public function check_access() { global $CFG; $context = empty($this->context) ? get_context_instance(CONTEXT_SYSTEM) : $this->context; foreach ($this->req_capability as $cap) { if (is_valid_capability($cap) and has_capability($cap, $context)) { return true; } } return false; }
function check_access() { if (!get_site()) { return true; // no access check before site is fully set up } $context = empty($this->context) ? get_context_instance(CONTEXT_SYSTEM) : $this->context; foreach ($this->req_capability as $cap) { if (is_valid_capability($cap) and has_capability($cap, $context)) { return true; } } return false; }