1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195:
<?php
namespace Module\Support;
use Module_Skeleton;
use Opcenter;
use Opcenter\Filesystem;
use Opcenter\Http\Apache\Map;
use Opcenter\Provisioning\ConfigurationWriter;
use User_Module;
abstract class Aliases extends Module_Skeleton implements \Opcenter\Contracts\Hookable
{
const CONFIG_DB_DIR = Opcenter\Http\Apache::DOMAIN_PATH;
const BYPASS_FILE = '/etc/virtualhosting/dnsbypass';
const CACHE_KEY = 'aliases';
protected function addMap(string $domain, string $path): bool
{
$map = Map::fromSiteDomainMap($this->domain_info_path(), $this->site,
Map::MODE_WRITE);
$domain = strtolower($domain);
if (isset($map[$domain])) {
warn("overwriting domain `%s' with new path `%s'", $domain, $path);
}
if (0 !== strpos($path, FILESYSTEM_VIRTBASE)) {
$path = $this->domain_fs_path($path);
}
$map[$domain] = $path;
\Cache_Account::spawn($this->getAuthContext())->del(self::CACHE_KEY);
return true;
}
protected function removeMap(string $domain): bool
{
$map = Map::fromSiteDomainMap($this->domain_info_path(), $this->site,
Map::MODE_WRITE);
$domain = strtolower($domain);
unset($map[$domain]);
\Cache_Account::spawn($this->getAuthContext())->del(self::CACHE_KEY);
return true;
}
protected function cache(array $data): void
{
$cache = \Cache_Account::spawn($this->getAuthContext());
$cache->set(static::CACHE_KEY, $data);
}
protected function transformMap(): array
{
$map = Map::fromSiteDomainMap($this->domain_info_path(), $this->site,
Map::MODE_READ);
$domains = [];
if (!$map) {
return $domains;
}
foreach ($map as $domain => $path) {
$domains[$domain] = $this->jailDomain($path);
}
unset($domains[$this->domain]);
$this->cache($domains);
return $domains;
}
private function jailDomain(string $path): string {
$fst = $this->domain_fs_path();
$len = \strlen($fst);
return rtrim(0 === strpos($path, $fst) ? substr($path, $len) : $path, '/');
}
protected function removeBypass(string $domain): bool
{
if (!file_exists(self::BYPASS_FILE)) {
return true;
}
$recs = file(self::BYPASS_FILE, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
if (false === ($line = array_search($domain, $recs, true))) {
return -1;
}
unset($recs[$line]);
if (\count($recs) < 1) {
unlink(self::BYPASS_FILE);
} else {
file_put_contents(self::BYPASS_FILE, implode("\n", $recs));
}
return true;
}
protected function createDocumentRoot(string $path)
{
$this->file_purge();
if (file_exists($this->domain_fs_path() . '/' . $path)) {
return true;
}
$gid = $this->group_id;
if (preg_match('!^/home/([^/]+)/!', $path, $user)) {
$user = $user[1];
$home = '/home/' . $user;
$users = $this->user_get_users();
$uid = $users[$user]['uid'];
if ($uid < User_Module::MIN_UID) {
return error('%s: user unknown in system', $user);
}
$stat = $this->file_stat($home);
$perms = decoct($stat['permissions'] | ($this->php_jailed() ? 0010 : 0001));
if ($stat && !$this->file_chmod($home, $perms)) {
warn("Failed to open permissions on `%s' to allow HTTP access");
}
} else {
$uid = $this->user_id;
}
$fullpath = $this->domain_fs_path() . '/' . $path;
if (!mkdir($fullpath)) {
return error("z'huh!? failed to create doc root?");
}
chown($fullpath, $uid);
chgrp($fullpath, $gid);
$index = $fullpath . '/index.html';
return file_put_contents($index, (string)(new ConfigurationWriter('apache.placeholder',
\Opcenter\SiteConfiguration::import($this->getAuthContext())))->compile([])) &&
Filesystem::chogp($index, $uid, $gid, 0644);
}
protected function isBypass(string $domain): bool
{
if (\defined('DOMAINS_DNS_CHECK') && !\constant('DOMAINS_DNS_CHECK')) {
return true;
}
if (!file_exists(self::BYPASS_FILE)) {
return false;
}
$recs = file(self::BYPASS_FILE, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
return (false !== ($line = array_search($domain, $recs, true)));
}
}