[entropy.db.skel,entropy.client.interfaces.db] disallow unprivileged repository update
This commit is contained in:
@@ -48,9 +48,8 @@ def repositories(options):
|
||||
try:
|
||||
if options[0] == "update":
|
||||
# check if I am root
|
||||
er_txt = darkred(_("You must be either root or in this group:")) + \
|
||||
" " + etpConst['sysgroup']
|
||||
if not entropy.tools.is_user_in_entropy_group():
|
||||
er_txt = darkred(_("You must be root"))
|
||||
if not entropy.tools.is_root():
|
||||
print_error(er_txt)
|
||||
return 1
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ from entropy.dump import dumpobj
|
||||
from entropy.cache import EntropyCacher
|
||||
from entropy.db import EntropyRepository
|
||||
from entropy.exceptions import RepositoryError, SystemDatabaseError, \
|
||||
ConnectionError
|
||||
ConnectionError, PermissionDenied
|
||||
from entropy.security import Repository as RepositorySecurity
|
||||
from entropy.misc import TimeScheduled
|
||||
from entropy.i18n import _
|
||||
@@ -695,7 +695,7 @@ class AvailablePackagesRepositoryUpdater(object):
|
||||
if self._entropy.installed_repository() is not None:
|
||||
try: # client db can be absent
|
||||
self._entropy.installed_repository().createAllIndexes()
|
||||
except (OperationalError, IntegrityError,):
|
||||
except (DatabaseError, OperationalError, IntegrityError,):
|
||||
pass
|
||||
const_set_nice_level(old_prio)
|
||||
|
||||
@@ -838,7 +838,7 @@ class AvailablePackagesRepositoryUpdater(object):
|
||||
rc = fetcher.download()
|
||||
if rc in ("-1", "-2", "-3", "-4"):
|
||||
return False
|
||||
const_setup_file(filepath, etpConst['entropygid'], 0o664)
|
||||
const_setup_file(filepath, etpConst['entropygid'], 0o644)
|
||||
return True
|
||||
|
||||
def _is_repository_unlocked(self):
|
||||
@@ -1016,6 +1016,8 @@ class AvailablePackagesRepositoryUpdater(object):
|
||||
continue
|
||||
continue
|
||||
|
||||
const_setup_file(to_mypath, etpConst['entropygid'], 0o644)
|
||||
|
||||
finally:
|
||||
shutil.rmtree(tmpdir, True)
|
||||
|
||||
@@ -1758,6 +1760,11 @@ class AvailablePackagesRepositoryUpdater(object):
|
||||
|
||||
def update(self):
|
||||
|
||||
# disallow unprivileged update
|
||||
if not entropy.tools.is_root():
|
||||
raise PermissionDenied(
|
||||
"cannot update repository as unprivileged user")
|
||||
|
||||
self.__show_repository_information()
|
||||
|
||||
# this calls writes self._last_rev which is used to write back
|
||||
@@ -1949,8 +1956,13 @@ class AvailablePackagesRepositoryUpdater(object):
|
||||
continue
|
||||
return EntropyRepositoryBase.REPOSITORY_GENERIC_ERROR
|
||||
|
||||
if os.path.isfile(dbfile) and os.access(dbfile, os.W_OK):
|
||||
const_setup_file(dbfile, etpConst['entropygid'], 0o664)
|
||||
# make sure that all the repository files are stored with proper
|
||||
# permissions to avoid possible XSS and trust boundary problems.
|
||||
downloaded_files.append(dbfile)
|
||||
for downloaded_file in sorted(set(downloaded_files)):
|
||||
if os.path.isfile(downloaded_file) and \
|
||||
os.access(downloaded_file, os.W_OK | os.R_OK):
|
||||
const_setup_file(downloaded_file, etpConst['entropygid'], 0o644)
|
||||
|
||||
# remove garbage left around
|
||||
for path in files_to_remove:
|
||||
@@ -1992,6 +2004,11 @@ class AvailablePackagesRepository(EntropyRepository):
|
||||
subclass of EntropyRepository. It implements the update() method in order
|
||||
to make possible to update the repository.
|
||||
"""
|
||||
def __init__(self, *args, **kwargs):
|
||||
EntropyRepository.__init__(self, *args, **kwargs)
|
||||
# ensure proper repository file permissions
|
||||
if entropy.tools.is_root() and os.path.isfile(self._db_path):
|
||||
const_setup_file(self._db_path, etpConst['entropygid'], 0o644)
|
||||
|
||||
@staticmethod
|
||||
def update(entropy_client, repository_id, force, gpg):
|
||||
|
||||
@@ -16,7 +16,7 @@ import subprocess
|
||||
|
||||
from entropy.i18n import _
|
||||
from entropy.const import etpConst, const_debug_write
|
||||
from entropy.exceptions import RepositoryError
|
||||
from entropy.exceptions import RepositoryError, PermissionDenied
|
||||
from entropy.output import blue, darkred, red, darkgreen, bold
|
||||
|
||||
from entropy.db.exceptions import Error
|
||||
@@ -67,8 +67,12 @@ class Repository:
|
||||
for repo in self.repo_ids:
|
||||
|
||||
# handle
|
||||
status = self._entropy.get_repository(repo).update(self._entropy,
|
||||
repo, self.force, self._gpg_feature)
|
||||
try:
|
||||
status = self._entropy.get_repository(repo).update(self._entropy,
|
||||
repo, self.force, self._gpg_feature)
|
||||
except PermissionDenied:
|
||||
status = EntropyRepositoryBase.REPOSITORY_PERMISSION_DENIED_ERROR
|
||||
|
||||
if status == EntropyRepositoryBase.REPOSITORY_ALREADY_UPTODATE:
|
||||
self.already_updated = True
|
||||
elif status == EntropyRepositoryBase.REPOSITORY_NOT_AVAILABLE:
|
||||
|
||||
@@ -3512,6 +3512,7 @@ class EntropyRepositoryBase(TextInterface, EntropyRepositoryPluginStore, object)
|
||||
REPOSITORY_NOT_AVAILABLE = -2
|
||||
REPOSITORY_GENERIC_ERROR = -3
|
||||
REPOSITORY_CHECKSUM_ERROR = -4
|
||||
REPOSITORY_PERMISSION_DENIED_ERROR = -5
|
||||
REPOSITORY_UPDATED_OK = 0
|
||||
|
||||
@staticmethod
|
||||
@@ -3527,6 +3528,9 @@ class EntropyRepositoryBase(TextInterface, EntropyRepositoryPluginStore, object)
|
||||
EntropyRepositoryBase.REPOSITORY_UPDATED_OK
|
||||
If your repository is not supposed to be remotely updated, just
|
||||
ignore this method.
|
||||
Otherwise, if you intend to implement this method, make sure that
|
||||
any unprivileged call raises entropy.exceptions.PermissionDenied().
|
||||
Only superuser should call this method.
|
||||
|
||||
@param entropy_client: Entropy Client based object
|
||||
@type entropy_client: entropy.client.interfaces.Client
|
||||
|
||||
Reference in New Issue
Block a user