Example #1
0
/**
 * 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;
}
Example #2
0
/**
 * 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);
    }
}
Example #3
0
 /**
  * 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;
 }
Example #4
0
 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;
 }