Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/report/security/locallib.php
Go to the documentation of this file.
00001 <?php
00002 // This file is part of Moodle - http://moodle.org/
00003 //
00004 // Moodle is free software: you can redistribute it and/or modify
00005 // it under the terms of the GNU General Public License as published by
00006 // the Free Software Foundation, either version 3 of the License, or
00007 // (at your option) any later version.
00008 //
00009 // Moodle is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
00016 
00026 defined('MOODLE_INTERNAL') || die;
00027 
00028 
00029 define('REPORT_SECURITY_OK', 'ok');
00030 define('REPORT_SECURITY_INFO', 'info');
00031 define('REPORT_SECURITY_WARNING', 'warning');
00032 define('REPORT_SECURITY_SERIOUS', 'serious');
00033 define('REPORT_SECURITY_CRITICAL', 'critical');
00034 
00035 function report_security_hide_timearning() {
00036      global $PAGE;
00037      $PAGE->requires->js_init_code("Y.one('#timewarning').addClass('timewarninghidden')");
00038 }
00039 
00040 function report_security_get_issue_list() {
00041     return array(
00042         'report_security_check_globals',
00043         'report_security_check_unsecuredataroot',
00044         'report_security_check_displayerrors',
00045         'report_security_check_noauth',
00046         'report_security_check_embed',
00047         'report_security_check_mediafilterswf',
00048         'report_security_check_openprofiles',
00049         'report_security_check_google',
00050         'report_security_check_passwordpolicy',
00051         'report_security_check_passwordsaltmain',
00052         'report_security_check_emailchangeconfirmation',
00053         'report_security_check_cookiesecure',
00054         'report_security_check_configrw',
00055         'report_security_check_riskxss',
00056         'report_security_check_riskadmin',
00057         'report_security_check_riskbackup',
00058         'report_security_check_defaultuserrole',
00059         'report_security_check_guestrole',
00060         'report_security_check_frontpagerole',
00061 
00062     );
00063 }
00064 
00065 function report_security_doc_link($issue, $name) {
00066     global $CFG, $OUTPUT;
00067 
00068     if (empty($CFG->docroot)) {
00069         return $name;
00070     }
00071 
00072     return $OUTPUT->doc_link('report/security/'.$issue, $name);
00073 }
00074 
00078 
00079 
00085 function report_security_check_globals($detailed=false) {
00086     $result = new stdClass();
00087     $result->issue   = 'report_security_check_globals';
00088     $result->name    = get_string('check_globals_name', 'report_security');
00089     $result->info    = null;
00090     $result->details = null;
00091     $result->status  = null;
00092     $result->link    = null;
00093 
00094     if (ini_get_bool('register_globals')) {
00095         $result->status = REPORT_SECURITY_CRITICAL;
00096         $result->info   = get_string('check_globals_error', 'report_security');
00097     } else {
00098         $result->status = REPORT_SECURITY_OK;
00099         $result->info   = get_string('check_globals_ok', 'report_security');
00100     }
00101 
00102     if ($detailed) {
00103         $result->details = get_string('check_globals_details', 'report_security');
00104     }
00105 
00106     return $result;
00107 }
00108 
00114 function report_security_check_noauth($detailed=false) {
00115     global $CFG;
00116 
00117     $result = new stdClass();
00118     $result->issue   = 'report_security_check_noauth';
00119     $result->name    = get_string('check_noauth_name', 'report_security');
00120     $result->info    = null;
00121     $result->details = null;
00122     $result->status  = null;
00123     $result->link    = null;
00124     $result->link    = "<a href=\"$CFG->wwwroot/$CFG->admin/settings.php?section=manageauths\">".get_string('authsettings', 'admin').'</a>';
00125 
00126     if (is_enabled_auth('none')) {
00127         $result->status = REPORT_SECURITY_CRITICAL;
00128         $result->info   = get_string('check_noauth_error', 'report_security');
00129     } else {
00130         $result->status = REPORT_SECURITY_OK;
00131         $result->info   = get_string('check_noauth_ok', 'report_security');
00132     }
00133 
00134     if ($detailed) {
00135         $result->details = get_string('check_noauth_details', 'report_security');
00136     }
00137 
00138     return $result;
00139 }
00140 
00146 function report_security_check_passwordpolicy($detailed=false) {
00147     global $CFG;
00148 
00149     $result = new stdClass();
00150     $result->issue   = 'report_security_check_passwordpolicy';
00151     $result->name    = get_string('check_passwordpolicy_name', 'report_security');
00152     $result->info    = null;
00153     $result->details = null;
00154     $result->status  = null;
00155     $result->link    = "<a href=\"$CFG->wwwroot/$CFG->admin/settings.php?section=sitepolicies\">".get_string('sitepolicies', 'admin').'</a>';
00156 
00157     if (empty($CFG->passwordpolicy)) {
00158         $result->status = REPORT_SECURITY_WARNING;
00159         $result->info   = get_string('check_passwordpolicy_error', 'report_security');
00160     } else {
00161         $result->status = REPORT_SECURITY_OK;
00162         $result->info   = get_string('check_passwordpolicy_ok', 'report_security');
00163     }
00164 
00165     if ($detailed) {
00166         $result->details = get_string('check_passwordpolicy_details', 'report_security');
00167     }
00168 
00169     return $result;
00170 }
00171 
00177 function report_security_check_embed($detailed=false) {
00178     global $CFG;
00179 
00180     $result = new stdClass();
00181     $result->issue   = 'report_security_check_embed';
00182     $result->name    = get_string('check_embed_name', 'report_security');
00183     $result->info    = null;
00184     $result->details = null;
00185     $result->status  = null;
00186     $result->link    = "<a href=\"$CFG->wwwroot/$CFG->admin/settings.php?section=sitepolicies\">".get_string('sitepolicies', 'admin').'</a>';
00187 
00188     if (!empty($CFG->allowobjectembed)) {
00189         $result->status = REPORT_SECURITY_CRITICAL;
00190         $result->info   = get_string('check_embed_error', 'report_security');
00191     } else {
00192         $result->status = REPORT_SECURITY_OK;
00193         $result->info   = get_string('check_embed_ok', 'report_security');
00194     }
00195 
00196     if ($detailed) {
00197         $result->details = get_string('check_embed_details', 'report_security');
00198     }
00199 
00200     return $result;
00201 }
00202 
00208 function report_security_check_mediafilterswf($detailed=false) {
00209     global $CFG;
00210 
00211     $result = new stdClass();
00212     $result->issue   = 'report_security_check_mediafilterswf';
00213     $result->name    = get_string('check_mediafilterswf_name', 'report_security');
00214     $result->info    = null;
00215     $result->details = null;
00216     $result->status  = null;
00217     $result->link    = "<a href=\"$CFG->wwwroot/$CFG->admin/settings.php?section=filtersettingfiltermediaplugin\">".get_string('filtersettings', 'admin').'</a>';
00218 
00219     $activefilters = filter_get_globally_enabled();
00220 
00221     if (array_search('filter/mediaplugin', $activefilters) !== false and !empty($CFG->filter_mediaplugin_enable_swf)) {
00222         $result->status = REPORT_SECURITY_CRITICAL;
00223         $result->info   = get_string('check_mediafilterswf_error', 'report_security');
00224     } else {
00225         $result->status = REPORT_SECURITY_OK;
00226         $result->info   = get_string('check_mediafilterswf_ok', 'report_security');
00227     }
00228 
00229     if ($detailed) {
00230         $result->details = get_string('check_mediafilterswf_details', 'report_security');
00231     }
00232 
00233     return $result;
00234 }
00235 
00241 function report_security_check_unsecuredataroot($detailed=false) {
00242     global $CFG;
00243 
00244     $result = new stdClass();
00245     $result->issue   = 'report_security_check_unsecuredataroot';
00246     $result->name    = get_string('check_unsecuredataroot_name', 'report_security');
00247     $result->info    = null;
00248     $result->details = null;
00249     $result->status  = null;
00250     $result->link    = null;
00251 
00252     $insecuredataroot = is_dataroot_insecure(true);
00253 
00254     if ($insecuredataroot == INSECURE_DATAROOT_WARNING) {
00255         $result->status = REPORT_SECURITY_SERIOUS;
00256         $result->info   = get_string('check_unsecuredataroot_warning', 'report_security', $CFG->dataroot);
00257 
00258     } else if ($insecuredataroot == INSECURE_DATAROOT_ERROR) {
00259         $result->status = REPORT_SECURITY_CRITICAL;
00260         $result->info   = get_string('check_unsecuredataroot_error', 'report_security', $CFG->dataroot);
00261 
00262     } else {
00263         $result->status = REPORT_SECURITY_OK;
00264         $result->info   = get_string('check_unsecuredataroot_ok', 'report_security');
00265     }
00266 
00267     if ($detailed) {
00268         $result->details = get_string('check_unsecuredataroot_details', 'report_security');
00269     }
00270 
00271     return $result;
00272 }
00273 
00280 function report_security_check_displayerrors($detailed=false) {
00281     $result = new stdClass();
00282     $result->issue   = 'report_security_check_displayerrors';
00283     $result->name    = get_string('check_displayerrors_name', 'report_security');
00284     $result->info    = null;
00285     $result->details = null;
00286     $result->status  = null;
00287     $result->link    = null;
00288 
00289     if (defined('WARN_DISPLAY_ERRORS_ENABLED')) {
00290         $result->status = REPORT_SECURITY_WARNING;
00291         $result->info   = get_string('check_displayerrors_error', 'report_security');
00292     } else {
00293         $result->status = REPORT_SECURITY_OK;
00294         $result->info   = get_string('check_displayerrors_ok', 'report_security');
00295     }
00296 
00297     if ($detailed) {
00298         $result->details = get_string('check_displayerrors_details', 'report_security');
00299     }
00300 
00301     return $result;
00302 }
00303 
00309 function report_security_check_openprofiles($detailed=false) {
00310     global $CFG;
00311 
00312     $result = new stdClass();
00313     $result->issue   = 'report_security_check_openprofiles';
00314     $result->name    = get_string('check_openprofiles_name', 'report_security');
00315     $result->info    = null;
00316     $result->details = null;
00317     $result->status  = null;
00318     $result->link    = "<a href=\"$CFG->wwwroot/$CFG->admin/settings.php?section=sitepolicies\">".get_string('sitepolicies', 'admin').'</a>';
00319 
00320     if (empty($CFG->forcelogin) and empty($CFG->forceloginforprofiles)) {
00321         $result->status = REPORT_SECURITY_WARNING;
00322         $result->info   = get_string('check_openprofiles_error', 'report_security');
00323     } else {
00324         $result->status = REPORT_SECURITY_OK;
00325         $result->info   = get_string('check_openprofiles_ok', 'report_security');
00326     }
00327 
00328     if ($detailed) {
00329         $result->details = get_string('check_openprofiles_details', 'report_security');
00330     }
00331 
00332     return $result;
00333 }
00334 
00341 function report_security_check_google($detailed=false) {
00342     global $CFG;
00343 
00344     $result = new stdClass();
00345     $result->issue   = 'report_security_check_google';
00346     $result->name    = get_string('check_google_name', 'report_security');
00347     $result->info    = null;
00348     $result->details = null;
00349     $result->status  = null;
00350     $result->link    = "<a href=\"$CFG->wwwroot/$CFG->admin/settings.php?section=sitepolicies\">".get_string('sitepolicies', 'admin').'</a>';
00351 
00352     if (empty($CFG->opentogoogle)) {
00353         $result->status = REPORT_SECURITY_OK;
00354         $result->info   = get_string('check_google_ok', 'report_security');
00355     } else if (!empty($CFG->guestloginbutton)) {
00356         $result->status = REPORT_SECURITY_INFO;
00357         $result->info   = get_string('check_google_info', 'report_security');
00358     } else {
00359         $result->status = REPORT_SECURITY_SERIOUS;
00360         $result->info   = get_string('check_google_error', 'report_security');
00361     }
00362 
00363     if ($detailed) {
00364         $result->details = get_string('check_google_details', 'report_security');
00365     }
00366 
00367     return $result;
00368 }
00369 
00375 function report_security_check_emailchangeconfirmation($detailed=false) {
00376     global $CFG;
00377 
00378     $result = new stdClass();
00379     $result->issue   = 'report_security_check_emailchangeconfirmation';
00380     $result->name    = get_string('check_emailchangeconfirmation_name', 'report_security');
00381     $result->info    = null;
00382     $result->details = null;
00383     $result->status  = null;
00384     $result->link    = "<a href=\"$CFG->wwwroot/$CFG->admin/settings.php?section=sitepolicies\">".get_string('sitepolicies', 'admin').'</a>';
00385 
00386     if (empty($CFG->emailchangeconfirmation)) {
00387         if (empty($CFG->allowemailaddresses)) {
00388             $result->status = REPORT_SECURITY_WARNING;
00389             $result->info   = get_string('check_emailchangeconfirmation_error', 'report_security');
00390         } else {
00391             $result->status = REPORT_SECURITY_INFO;
00392             $result->info   = get_string('check_emailchangeconfirmation_info', 'report_security');
00393         }
00394     } else {
00395         $result->status = REPORT_SECURITY_OK;
00396         $result->info   = get_string('check_emailchangeconfirmation_ok', 'report_security');
00397     }
00398 
00399     if ($detailed) {
00400         $result->details = get_string('check_emailchangeconfirmation_details', 'report_security');
00401     }
00402 
00403     return $result;
00404 }
00405 
00412 function report_security_check_cookiesecure($detailed=false) {
00413     global $CFG;
00414 
00415     if (strpos($CFG->wwwroot, 'https://') !== 0) {
00416         return null;
00417     }
00418 
00419     $result = new stdClass();
00420     $result->issue   = 'report_security_check_cookiesecure';
00421     $result->name    = get_string('check_cookiesecure_name', 'report_security');
00422     $result->info    = null;
00423     $result->details = null;
00424     $result->status  = null;
00425     $result->link    = "<a href=\"$CFG->wwwroot/$CFG->admin/settings.php?section=httpsecurity\">".get_string('httpsecurity', 'admin').'</a>';
00426 
00427     if (empty($CFG->cookiesecure)) {
00428         $result->status = REPORT_SECURITY_SERIOUS;
00429         $result->info   = get_string('check_cookiesecure_error', 'report_security');
00430     } else {
00431         $result->status = REPORT_SECURITY_OK;
00432         $result->info   = get_string('check_cookiesecure_ok', 'report_security');
00433     }
00434 
00435     if ($detailed) {
00436         $result->details = get_string('check_cookiesecure_details', 'report_security');
00437     }
00438 
00439     return $result;
00440 }
00441 
00448 function report_security_check_configrw($detailed=false) {
00449     global $CFG;
00450 
00451     $result = new stdClass();
00452     $result->issue   = 'report_security_check_configrw';
00453     $result->name    = get_string('check_configrw_name', 'report_security');
00454     $result->info    = null;
00455     $result->details = null;
00456     $result->status  = null;
00457     $result->link    = null;
00458 
00459     if (is_writable($CFG->dirroot.'/config.php')) {
00460         $result->status = REPORT_SECURITY_WARNING;
00461         $result->info   = get_string('check_configrw_warning', 'report_security');
00462     } else {
00463         $result->status = REPORT_SECURITY_OK;
00464         $result->info   = get_string('check_configrw_ok', 'report_security');
00465     }
00466 
00467     if ($detailed) {
00468         $result->details = get_string('check_configrw_details', 'report_security');
00469     }
00470 
00471     return $result;
00472 }
00473 
00474 function report_security_check_passwordsaltmain($detailed=false) {
00475     global $CFG;
00476 
00477     $result = new stdClass();
00478     $result->issue   = 'report_security_check_passwordsaltmain';
00479     $result->name    = get_string('check_passwordsaltmain_name', 'report_security');
00480     $result->info    = null;
00481     $result->details = null;
00482     $result->status  = null;
00483     $result->link    = null;
00484 
00485     if (empty($CFG->passwordsaltmain)) {
00486         $result->status = REPORT_SECURITY_WARNING;
00487         $result->info   = get_string('check_passwordsaltmain_warning', 'report_security');
00488     } else if ($CFG->passwordsaltmain === 'some long random string here with lots of characters'
00489             || trim($CFG->passwordsaltmain) === '' || preg_match('/^([a-z0-9]{0,10})$/i', $CFG->passwordsaltmain)) {
00490         $result->status = REPORT_SECURITY_WARNING;
00491         $result->info   = get_string('check_passwordsaltmain_weak', 'report_security');
00492     } else {
00493         $result->status = REPORT_SECURITY_OK;
00494         $result->info   = get_string('check_passwordsaltmain_ok', 'report_security');
00495     }
00496 
00497     if ($detailed) {
00498         $result->details = get_string('check_passwordsaltmain_details', 'report_security', get_docs_url('report/security/report_security_check_passwordsaltmain'));
00499     }
00500 
00501     return $result;
00502 }
00503 
00510 function report_security_check_riskxss($detailed=false) {
00511     global $DB;
00512 
00513     $result = new stdClass();
00514     $result->issue   = 'report_security_check_riskxss';
00515     $result->name    = get_string('check_riskxss_name', 'report_security');
00516     $result->info    = null;
00517     $result->details = null;
00518     $result->status  = REPORT_SECURITY_WARNING;
00519     $result->link    = null;
00520 
00521     $params = array('capallow'=>CAP_ALLOW);
00522 
00523     $sqlfrom = "FROM (SELECT rcx.*
00524                        FROM {role_capabilities} rcx
00525                        JOIN {capabilities} cap ON (cap.name = rcx.capability AND ".$DB->sql_bitand('cap.riskbitmask', RISK_XSS)." <> 0)
00526                        WHERE rcx.permission = :capallow) rc,
00527                      {context} c,
00528                      {context} sc,
00529                      {role_assignments} ra,
00530                      {user} u
00531                WHERE c.id = rc.contextid
00532                      AND (sc.path = c.path OR sc.path LIKE ".$DB->sql_concat('c.path', "'/%'")." OR c.path LIKE ".$DB->sql_concat('sc.path', "'/%'").")
00533                      AND u.id = ra.userid AND u.deleted = 0
00534                      AND ra.contextid = sc.id AND ra.roleid = rc.roleid";
00535 
00536     $count = $DB->count_records_sql("SELECT COUNT(DISTINCT u.id) $sqlfrom", $params);
00537 
00538     $result->info = get_string('check_riskxss_warning', 'report_security', $count);
00539 
00540     if ($detailed) {
00541         $users = $DB->get_records_sql("SELECT DISTINCT u.id, u.firstname, u.lastname, u.picture, u.imagealt $sqlfrom", $params);
00542         foreach ($users as $uid=>$user) {
00543             $users[$uid] = fullname($user);
00544         }
00545         $users = implode(', ', $users);
00546         $result->details = get_string('check_riskxss_details', 'report_security', $users);
00547     }
00548 
00549     return $result;
00550 }
00551 
00557 function report_security_check_defaultuserrole($detailed=false) {
00558     global $DB, $CFG;
00559 
00560     $result = new stdClass();
00561     $result->issue   = 'report_security_check_defaultuserrole';
00562     $result->name    = get_string('check_defaultuserrole_name', 'report_security');
00563     $result->info    = null;
00564     $result->details = null;
00565     $result->status  = null;
00566     $result->link    = "<a href=\"$CFG->wwwroot/$CFG->admin/settings.php?section=userpolicies\">".get_string('userpolicies', 'admin').'</a>';;
00567 
00568     if (!$default_role = $DB->get_record('role', array('id'=>$CFG->defaultuserroleid))) {
00569         $result->status  = REPORT_SECURITY_WARNING;
00570         $result->info    = get_string('check_defaultuserrole_notset', 'report_security');
00571         $result->details = $result->info;
00572 
00573         return $result;
00574     }
00575 
00576     // risky caps - usually very dangerous
00577     $params = array('capallow'=>CAP_ALLOW, 'roleid'=>$default_role->id);
00578     $sql = "SELECT COUNT(DISTINCT rc.contextid)
00579               FROM {role_capabilities} rc
00580               JOIN {capabilities} cap ON cap.name = rc.capability
00581              WHERE ".$DB->sql_bitand('cap.riskbitmask', (RISK_XSS | RISK_CONFIG | RISK_DATALOSS))." <> 0
00582                    AND rc.permission = :capallow
00583                    AND rc.roleid = :roleid";
00584 
00585     $riskycount = $DB->count_records_sql($sql, $params);
00586 
00587     // it may have either none or 'user' archetype - nothing else, or else it would break during upgrades badly
00588     if ($default_role->archetype === '' or $default_role->archetype === 'user') {
00589         $legacyok = true;
00590     } else {
00591         $legacyok = false;
00592     }
00593 
00594     if ($riskycount or !$legacyok) {
00595         $result->status  = REPORT_SECURITY_CRITICAL;
00596         $result->info    = get_string('check_defaultuserrole_error', 'report_security', format_string($default_role->name));
00597 
00598     } else {
00599         $result->status  = REPORT_SECURITY_OK;
00600         $result->info    = get_string('check_defaultuserrole_ok', 'report_security');
00601     }
00602 
00603     if ($detailed) {
00604         $result->details = get_string('check_defaultuserrole_details', 'report_security');
00605     }
00606 
00607     return $result;
00608 }
00609 
00615 function report_security_check_guestrole($detailed=false) {
00616     global $DB, $CFG;
00617 
00618     $result = new stdClass();
00619     $result->issue   = 'report_security_check_guestrole';
00620     $result->name    = get_string('check_guestrole_name', 'report_security');
00621     $result->info    = null;
00622     $result->details = null;
00623     $result->status  = null;
00624     $result->link    = "<a href=\"$CFG->wwwroot/$CFG->admin/settings.php?section=userpolicies\">".get_string('userpolicies', 'admin').'</a>';;
00625 
00626     if (!$guest_role = $DB->get_record('role', array('id'=>$CFG->guestroleid))) {
00627         $result->status  = REPORT_SECURITY_WARNING;
00628         $result->info    = get_string('check_guestrole_notset', 'report_security');
00629         $result->details = $result->info;
00630 
00631         return $result;
00632     }
00633 
00634     // risky caps - usually very dangerous
00635     $params = array('capallow'=>CAP_ALLOW, 'roleid'=>$guest_role->id);
00636     $sql = "SELECT COUNT(DISTINCT rc.contextid)
00637               FROM {role_capabilities} rc
00638               JOIN {capabilities} cap ON cap.name = rc.capability
00639              WHERE ".$DB->sql_bitand('cap.riskbitmask', (RISK_XSS | RISK_CONFIG | RISK_DATALOSS))." <> 0
00640                    AND rc.permission = :capallow
00641                    AND rc.roleid = :roleid";
00642 
00643     $riskycount = $DB->count_records_sql($sql, $params);
00644 
00645     // it may have either no or 'guest' archetype - nothing else, or else it would break during upgrades badly
00646     if ($guest_role->archetype === '' or $guest_role->archetype === 'guest') {
00647         $legacyok = true;
00648     } else {
00649         $legacyok = false;
00650     }
00651 
00652     if ($riskycount or !$legacyok) {
00653         $result->status  = REPORT_SECURITY_CRITICAL;
00654         $result->info    = get_string('check_guestrole_error', 'report_security', format_string($guest_role->name));
00655 
00656     } else {
00657         $result->status  = REPORT_SECURITY_OK;
00658         $result->info    = get_string('check_guestrole_ok', 'report_security');
00659     }
00660 
00661     if ($detailed) {
00662         $result->details = get_string('check_guestrole_details', 'report_security');
00663     }
00664 
00665     return $result;
00666 }
00667 
00673 function report_security_check_frontpagerole($detailed=false) {
00674     global $DB, $CFG;
00675 
00676     $result = new stdClass();
00677     $result->issue   = 'report_security_check_frontpagerole';
00678     $result->name    = get_string('check_frontpagerole_name', 'report_security');
00679     $result->info    = null;
00680     $result->details = null;
00681     $result->status  = null;
00682     $result->link    = "<a href=\"$CFG->wwwroot/$CFG->admin/settings.php?section=frontpagesettings\">".get_string('frontpagesettings','admin').'</a>';;
00683 
00684     if (!$frontpage_role = $DB->get_record('role', array('id'=>$CFG->defaultfrontpageroleid))) {
00685         $result->status  = REPORT_SECURITY_INFO;
00686         $result->info    = get_string('check_frontpagerole_notset', 'report_security');
00687         $result->details = get_string('check_frontpagerole_details', 'report_security');
00688 
00689         return $result;
00690     }
00691 
00692     // risky caps - usually very dangerous
00693     $params = array('capallow'=>CAP_ALLOW, 'roleid'=>$frontpage_role->id);
00694     $sql = "SELECT COUNT(DISTINCT rc.contextid)
00695               FROM {role_capabilities} rc
00696               JOIN {capabilities} cap ON cap.name = rc.capability
00697              WHERE ".$DB->sql_bitand('cap.riskbitmask', (RISK_XSS | RISK_CONFIG | RISK_DATALOSS))." <> 0
00698                    AND rc.permission = :capallow
00699                    AND rc.roleid = :roleid";
00700 
00701     $riskycount = $DB->count_records_sql($sql, $params);
00702 
00703     // there is no legacy role type for frontpage yet - anyway we can not allow teachers or admins there!
00704     if ($frontpage_role->archetype === 'teacher' or $frontpage_role->archetype === 'editingteacher'
00705       or $frontpage_role->archetype === 'coursecreator' or $frontpage_role->archetype === 'manager') {
00706         $legacyok = false;
00707     } else {
00708         $legacyok = true;
00709     }
00710 
00711     if ($riskycount or !$legacyok) {
00712         $result->status  = REPORT_SECURITY_CRITICAL;
00713         $result->info    = get_string('check_frontpagerole_error', 'report_security', format_string($frontpage_role->name));
00714 
00715     } else {
00716         $result->status  = REPORT_SECURITY_OK;
00717         $result->info    = get_string('check_frontpagerole_ok', 'report_security');
00718     }
00719 
00720     if ($detailed) {
00721         $result->details = get_string('check_frontpagerole_details', 'report_security');
00722     }
00723 
00724     return $result;
00725 }
00726 
00732 function report_security_check_riskadmin($detailed=false) {
00733     global $DB, $CFG;
00734 
00735     $result = new stdClass();
00736     $result->issue   = 'report_security_check_riskadmin';
00737     $result->name    = get_string('check_riskadmin_name', 'report_security');
00738     $result->info    = null;
00739     $result->details = null;
00740     $result->status  = null;
00741     $result->link    = null;
00742 
00743     $sql = "SELECT u.id, u.firstname, u.lastname, u.picture, u.imagealt, u.email
00744               FROM {user} u
00745              WHERE u.id IN ($CFG->siteadmins)";
00746 
00747     $admins = $DB->get_records_sql($sql);
00748     $admincount = count($admins);
00749 
00750     if ($detailed) {
00751         foreach ($admins as $uid=>$user) {
00752             $url = "$CFG->wwwroot/user/view.php?id=$user->id";
00753             $admins[$uid] = '<li><a href="'.$url.'">'.fullname($user).' ('.$user->email.')</a></li>';
00754         }
00755         $admins = '<ul>'.implode('', $admins).'</ul>';
00756     }
00757 
00758     $result->status  = REPORT_SECURITY_OK;
00759     $result->info = get_string('check_riskadmin_ok', 'report_security', $admincount);
00760 
00761     if ($detailed) {
00762         $result->details = get_string('check_riskadmin_detailsok', 'report_security', $admins);
00763     }
00764 
00765     return $result;
00766 }
00767 
00773 function report_security_check_riskbackup($detailed=false) {
00774     global $CFG, $DB;
00775 
00776     $result = new stdClass();
00777     $result->issue   = 'report_security_check_riskbackup';
00778     $result->name    = get_string('check_riskbackup_name', 'report_security');
00779     $result->info    = null;
00780     $result->details = null;
00781     $result->status  = null;
00782     $result->link    = null;
00783 
00784     $syscontext = get_context_instance(CONTEXT_SYSTEM);
00785 
00786     $params = array('capability'=>'moodle/backup:userinfo', 'permission'=>CAP_ALLOW, 'contextid'=>$syscontext->id);
00787     $sql = "SELECT DISTINCT r.id, r.name, r.shortname, r.sortorder, r.archetype
00788               FROM {role} r
00789               JOIN {role_capabilities} rc ON rc.roleid = r.id
00790              WHERE rc.capability = :capability
00791                AND rc.contextid  = :contextid
00792                AND rc.permission = :permission";
00793     $systemroles = $DB->get_records_sql($sql, $params);
00794 
00795     $params = array('capability'=>'moodle/backup:userinfo', 'permission'=>CAP_ALLOW, 'contextid'=>$syscontext->id);
00796     $sql = "SELECT DISTINCT r.id, r.name, r.shortname, r.sortorder, r.archetype, rc.contextid
00797               FROM {role} r
00798               JOIN {role_capabilities} rc ON rc.roleid = r.id
00799              WHERE rc.capability = :capability
00800                AND rc.contextid <> :contextid
00801                AND rc.permission = :permission";
00802     $overriddenroles = $DB->get_records_sql($sql, $params);
00803 
00804     // list of users that are able to backup personal info
00805     // note: "sc" is context where is role assigned,
00806     //       "c" is context where is role overridden or system context if in role definition
00807     $params = array('capability'=>'moodle/backup:userinfo', 'permission'=>CAP_ALLOW, 'context1'=>CONTEXT_COURSE, 'context2'=>CONTEXT_COURSE);
00808 
00809     $sqluserinfo = "
00810         FROM (SELECT rcx.*
00811                 FROM {role_capabilities} rcx
00812                WHERE rcx.permission = :permission AND rcx.capability = :capability) rc,
00813              {context} c,
00814              {context} sc,
00815              {role_assignments} ra,
00816              {user} u
00817        WHERE c.id = rc.contextid
00818              AND (sc.path = c.path OR sc.path LIKE ".$DB->sql_concat('c.path', "'/%'")." OR c.path LIKE ".$DB->sql_concat('sc.path', "'/%'").")
00819              AND u.id = ra.userid AND u.deleted = 0
00820              AND ra.contextid = sc.id AND ra.roleid = rc.roleid
00821              AND sc.contextlevel <= :context1 AND c.contextlevel <= :context2";
00822 
00823     $usercount = $DB->count_records_sql("SELECT COUNT('x') FROM (SELECT DISTINCT u.id $sqluserinfo) userinfo", $params);
00824     $systemrolecount = empty($systemroles) ? 0 : count($systemroles);
00825     $overriddenrolecount = empty($overriddenroles) ? 0 : count($overriddenroles);
00826 
00827     $result->status  = REPORT_SECURITY_WARNING; // there is always at least one admin
00828     $a = (object)array('rolecount'=>$systemrolecount,'overridecount'=>$overriddenrolecount,'usercount'=>$usercount);
00829     $result->info = get_string('check_riskbackup_warning', 'report_security', $a);
00830 
00831     if ($detailed) {
00832 
00833         $result->details = '';  // Will be added to later
00834 
00835         // Make a list of roles
00836         if ($systemroles) {
00837             $links = array();
00838             foreach ($systemroles as $role) {
00839                 $role->url = "$CFG->wwwroot/$CFG->admin/roles/manage.php?action=edit&amp;roleid=$role->id";
00840                 $links[] = '<li>'.get_string('check_riskbackup_editrole', 'report_security', $role).'</li>';
00841             }
00842             $links = '<ul>'.implode($links).'</ul>';
00843             $result->details .= get_string('check_riskbackup_details_systemroles', 'report_security', $links);
00844         }
00845 
00846         // Make a list of overrides to roles
00847         $rolelinks2 = array();
00848         if ($overriddenroles) {
00849             $links = array();
00850             foreach ($overriddenroles as $role) {
00851                 $context = get_context_instance_by_id($role->contextid);
00852                 if ($context->contextlevel == CONTEXT_COURSE) {
00853                     $role->name = role_get_name($role, $context);
00854                 }
00855                 $role->contextname = print_context_name($context);
00856                 $role->url = "$CFG->wwwroot/$CFG->admin/roles/override.php?contextid=$role->contextid&amp;roleid=$role->id";
00857                 $links[] = '<li>'.get_string('check_riskbackup_editoverride', 'report_security', $role).'</li>';
00858             }
00859             $links = '<ul>'.implode('', $links).'</ul>';
00860             $result->details .= get_string('check_riskbackup_details_overriddenroles', 'report_security', $links);
00861         }
00862 
00863         // Get a list of affected users as well
00864         $users = array();
00865 
00866         $rs = $DB->get_recordset_sql("SELECT DISTINCT u.id, u.firstname, u.lastname, u.picture, u.imagealt, u.email, ra.contextid, ra.roleid
00867             $sqluserinfo ORDER BY u.lastname, u.firstname", $params);
00868 
00869         foreach ($rs as $user) {
00870             $context = get_context_instance_by_id($user->contextid);
00871             $url = "$CFG->wwwroot/$CFG->admin/roles/assign.php?contextid=$user->contextid&amp;roleid=$user->roleid";
00872             $a = (object)array('fullname'=>fullname($user), 'url'=>$url, 'email'=>$user->email,
00873                                'contextname'=>print_context_name($context));
00874             $users[] = '<li>'.get_string('check_riskbackup_unassign', 'report_security', $a).'</li>';
00875         }
00876         if (!empty($users)) {
00877             $users = '<ul>'.implode('', $users).'</ul>';
00878             $result->details .= get_string('check_riskbackup_details_users', 'report_security', $users);
00879         }
00880     }
00881 
00882     return $result;
00883 }
 All Data Structures Namespaces Files Functions Variables Enumerations