diff --git a/config-dist.php b/config-dist.php index fb45533b60c..90989bbd28a 100644 --- a/config-dist.php +++ b/config-dist.php @@ -742,6 +742,9 @@ $CFG->admin = 'admin'; // Force developer level debug and add debug info to the output of cron // $CFG->showcrondebugging = true; // +// Force result of checks used to determine whether a site is considered "public" or not (such as for site registration). +// $CFG->site_is_public = false; +// //========================================================================= // 8. FORCED SETTINGS //========================================================================= diff --git a/lib/classes/ip_utils.php b/lib/classes/ip_utils.php index d2e9a3dd02e..387df8f9211 100644 --- a/lib/classes/ip_utils.php +++ b/lib/classes/ip_utils.php @@ -245,4 +245,22 @@ final class ip_utils { return false; } + /** + * Return IP address for given hostname, or null on failure + * + * @param string $hostname + * @return string|null + */ + public static function get_ip_address(string $hostname): ?string { + if (self::is_domain_name($hostname)) { + $address = gethostbyname($hostname); + + // If address is different from hostname, we have success. + if (strcasecmp($address, $hostname) !== 0) { + return $address; + } + } + + return null; + } } diff --git a/lib/moodlelib.php b/lib/moodlelib.php index 542fd0d32d6..75c6175f4ae 100644 --- a/lib/moodlelib.php +++ b/lib/moodlelib.php @@ -10571,18 +10571,26 @@ function get_callable_name($callable) { * It just performs some simple checks, and mainly is used for places where we want to hide some options * such as site registration when $CFG->wwwroot is not publicly accessible. * Good thing is there is no false negative. + * Note that it's possible to force the result of this check by specifying $CFG->site_is_public in config.php * * @return bool */ function site_is_public() { global $CFG; + // Return early if site admin has forced this setting. + if (isset($CFG->site_is_public)) { + return (bool)$CFG->site_is_public; + } + $host = parse_url($CFG->wwwroot, PHP_URL_HOST); if ($host === 'localhost' || preg_match('|^127\.\d+\.\d+\.\d+$|', $host)) { $ispublic = false; } else if (\core\ip_utils::is_ip_address($host) && !ip_is_public($host)) { $ispublic = false; + } else if (($address = \core\ip_utils::get_ip_address($host)) && !ip_is_public($address)) { + $ispublic = false; } else { $ispublic = true; }