晋太元中,武陵人捕鱼为业。缘溪行,忘路之远近。忽逢桃花林,夹岸数百步,中无杂树,芳草鲜美,落英缤纷。渔人甚异之,复前行,欲穷其林。 林尽水源,便得一山,山有小口,仿佛若有光。便舍船,从口入。初极狭,才通人。复行数十步,豁然开朗。土地平旷,屋舍俨然,有良田、美池、桑竹之属。阡陌交通,鸡犬相闻。其中往来种作,男女衣着,悉如外人。黄发垂髫,并怡然自乐。 见渔人,乃大惊,问所从来。具答之。便要还家,设酒杀鸡作食。村中闻有此人,咸来问讯。自云先世避秦时乱,率妻子邑人来此绝境,不复出焉,遂与外人间隔。问今是何世,乃不知有汉,无论魏晋。此人一一为具言所闻,皆叹惋。余人各复延至其家,皆出酒食。停数日,辞去。此中人语云:“不足为外人道也。”(间隔 一作:隔绝) 既出,得其船,便扶向路,处处志之。及郡下,诣太守,说如此。太守即遣人随其往,寻向所志,遂迷,不复得路。 南阳刘子骥,高尚士也,闻之,欣然规往。未果,寻病终。后遂无问津者。
| DIR:/proc/thread-self/root/opt/cloudlinux/venv/lib/python3.11/site-packages/clcagefslib/ |
| Current File : //proc/thread-self/root/opt/cloudlinux/venv/lib/python3.11/site-packages/clcagefslib/io.py |
# Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2024 All Rights Reserved
#
# Licensed under CLOUD LINUX LICENSE AGREEMENT
# http://cloudlinux.com/docs/LICENSE.TXT
import errno
import functools
import logging
import os
import pwd
import sys
import tempfile
import secureio
from clcommon import clcaptain
from clcommon.utils import ExternalProgramFailed
logger = logging.getLogger(__name__)
def read_file(filename, exit_on_error=True):
"""
Helper for read file, process errors and make backup before read
:param: filename `str` name of file for read
:param: exit_on_error `bool` use sys.exit on error or raise exception
"""
try:
with open(filename, "r") as _file:
return _file.readlines()
except (OSError, IOError):
secureio.logging("Error: failed to read " + filename, secureio.SILENT_FLAG, 1)
if not exit_on_error:
raise
sys.exit(1)
@functools.cache
def read_file_cached(path):
return read_file(path)
# Returns True if error has occured
def make_userdir(path, perm, uid, gid, parent_path):
# Create directory if it does not exist, and set permissions/owner
fd = secureio.create_dir_secure(
path, perm, uid, gid, parent_path, logger=secureio.logging
)
secureio.closefd(fd)
return fd is None
def home_owned_by_other_user(home_path, target_uid):
"""
CLOS-4545 guard against stealing a shared home's ``.cagefs``.
Return ``True`` when ``home_path`` is owned by a user *other than*
``target_uid`` and that owner is a real ``/etc/passwd`` user whose home
directory is ``home_path`` itself.
On every panel CageFS supports, the home directory is owned by the real
subscription/account user, so its owner is the authoritative answer to
"who does this home belong to". When several ``/etc/passwd`` entries share
one home -- e.g. an orphan ``sys_user`` left behind by a reverted Plesk
migration, which merely has the home as its ``pw_dir`` but does not own it
-- an operation aimed at a uid that is *not* the home owner must not chown
``<home>/.cagefs`` to it: that would strip the real owner of its own
``.cagefs`` and break the subscription (the next HTTP request fails with
503). Callers must skip the chown when this returns ``True``.
Keying on the home owner (rather than the current ``.cagefs`` owner) means
the legitimate owner -- and automated repair such as
``update_status(fix_owner=True)`` -- can always (re)claim ``.cagefs``, even
after it was previously flipped to an orphan. ``False`` is also returned
when ``target_uid`` owns the home, when the home cannot be stat'd, or when
it is owned by an unrelated uid (e.g. root) that does not live in this home,
so normal provisioning, brand-new subscriptions and ownership repair keep
working.
"""
try:
home_uid = os.stat(home_path).st_uid
except OSError:
return False
if home_uid == target_uid:
# target_uid is the real owner of the home -> always allowed (this is
# also what lets the owner / fix_owner reclaim a flipped .cagefs).
return False
try:
home_owner = pwd.getpwuid(home_uid)
except KeyError:
return False
# Only protect when the home owner is a real user that actually lives here,
# i.e. a genuine shared-home situation -- not a root-owned or unrelated home.
return os.path.realpath(home_owner.pw_dir) == os.path.realpath(home_path)
def switch_symlink(dest_path, link_name, write_log=True, force=True, silent=False):
if force or not os.path.islink(link_name):
try:
os.unlink(link_name)
except OSError as e:
if e.errno == errno.ENOENT: # No such file error
logger.info(f"Symlink {link_name} does not exist")
else:
logger.error(f"Error: Unable to remove symlink {link_name}", exc_info=e)
try:
clcaptain.symlink(dest_path, link_name)
except (OSError, ExternalProgramFailed) as e:
msg = f"Error: failed to create symlink {link_name} to {dest_path} : {str(e).replace('Errno', 'Err code')}"
logger.error(msg, exc_info=e)
if write_log:
secureio.logging(msg, silent, True)
else:
print(msg, file=sys.stderr)
return True
return False
def write_via_tmp(directory, filename, content):
temp_path = None
try:
with tempfile.NamedTemporaryFile("w", dir=directory, delete=False) as tmp_file:
temp_path = tmp_file.name
tmp_file.write(content)
tmp_file.flush()
os.fsync(tmp_file.fileno())
os.replace(temp_path, filename)
finally:
if temp_path and os.path.exists(temp_path):
try:
os.remove(temp_path)
except OSError:
pass
def apply_metadata_nofollow(path, mode, uid, gid):
# Open with O_NOFOLLOW so a symlink planted at `path` between, e.g.,
# write_via_tmp's os.replace and this call raises ELOOP rather than
# being followed; fchmod/fchown then act on the inode via the fd.
fd = os.open(path, os.O_RDONLY | os.O_NOFOLLOW | os.O_CLOEXEC)
try:
os.fchmod(fd, mode)
os.fchown(fd, uid, gid)
finally:
os.close(fd)
|