Fix ticket #800: sudo doesn't work

Git doesn't store setuid bit. Store all permissions in the metadata dir
ticket-769
Vadim vtroshchinskiy 2024-10-02 10:26:08 +02:00
parent ebcf90e8ea
commit 77f7fa0d80
1 changed files with 47 additions and 1 deletions

View File

@ -296,7 +296,10 @@ class OpengnsysGitLibrary:
"""
self.debug_check_for_untracked_files = True
self.logger.debug(f"Git repository: {self.repo_server}")
if not self.repo_server:
self.logger.error("Git repository not known, we may not have booted correctly? Check ogrepo and oglive kernel arguments.")
else:
self.logger.debug(f"Git repository: {self.repo_server}")
def _is_efi(self):
"""Determina si hemos arrancado con EFI
@ -839,6 +842,7 @@ class OpengnsysGitLibrary:
empties_file = open(os.path.join(meta_dir, "empty_directories.jsonl.new"), "w")
specials_file = open(os.path.join(meta_dir, "special_files.jsonl.new"), "w")
acls_file = open(os.path.join(meta_dir, "acls.jsonl.new"), "w")
perms_file = open(os.path.join(meta_dir, "unix_permissions.jsonl.new"), "w")
xattrs_file = open(os.path.join(meta_dir, "xattrs.jsonl.new"), "w")
gitignores_file = open(os.path.join(meta_dir, "gitignores.jsonl.new"), "w")
filesystems_file = open(os.path.join(meta_dir, "filesystems.json.new"), "w")
@ -947,6 +951,16 @@ class OpengnsysGitLibrary:
if not ntfs and os.path.isfile(full_path) and not os.path.islink(full_path):
# docs: https://pylibacl.k1024.org/module.html#posix1e.ACL.to_any_text
# Git doesn't preserve setuid, we've got to store it separately
stat_data = os.stat(full_path)
perms_json = json.dumps({
"file" : full_path_rel,
"mode" : stat_data.st_mode,
"uid" : stat_data.st_uid,
"gid" : stat_data.st_gid
})
xattrs = str(xattr.get_all(full_path))
acls = posix1e.ACL(file=full_path)
@ -958,6 +972,7 @@ class OpengnsysGitLibrary:
acl_data = str(base64.b64encode(acls.__getstate__()), 'utf-8')
acls_json = json.dumps({"file": full_path_rel, "acl" : acl_data })
perms_file.write(perms_json + "\n")
xattrs_file.write(xattrs_json + "\n")
acls_file.write(acls_json + "\n")
@ -1016,6 +1031,7 @@ class OpengnsysGitLibrary:
specials_file.close()
xattrs_file.close()
acls_file.close()
perms_file.close()
gitignores_file.close()
filesystems_file.close()
metadata_file.close()
@ -1023,6 +1039,7 @@ class OpengnsysGitLibrary:
os.rename(os.path.join(meta_dir, "empty_directories.jsonl.new"), os.path.join(meta_dir, "empty_directories.jsonl"))
os.rename(os.path.join(meta_dir, "special_files.jsonl.new"), os.path.join(meta_dir, "special_files.jsonl"))
os.rename(os.path.join(meta_dir, "acls.jsonl.new"), os.path.join(meta_dir, "acls.jsonl"))
os.rename(os.path.join(meta_dir, "unix_permissions.jsonl.new"), os.path.join(meta_dir, "unix_permissions.jsonl"))
os.rename(os.path.join(meta_dir, "xattrs.jsonl.new"), os.path.join(meta_dir, "xattrs.jsonl"))
os.rename(os.path.join(meta_dir, "gitignores.jsonl.new"), os.path.join(meta_dir, "gitignores.jsonl"))
os.rename(os.path.join(meta_dir, "filesystems.json.new"), os.path.join(meta_dir, "filesystems.json"))
@ -1084,6 +1101,32 @@ class OpengnsysGitLibrary:
self.logger.debug(f"Deleting: {empty_dir_keep}")
os.unlink(empty_dir_keep)
if not destructive_only:
self.logger.debug("Processing unix_permissions.jsonl")
with open(os.path.join(meta_dir, "unix_permissions.jsonl"), "r") as acls_file:
for line in acls_file:
perms_data = json.loads(line)
#self.logger.debug(f"Data: {acls_data}")
perms_file = perms_data['file']
file_perms = perms_data['mode']
file_uid = perms_data['uid']
file_gid = perms_data['gid']
if perms_file.startswith("/"):
perms_file = perms_file[1:]
perms_file_path = os.path.join(path, perms_file)
if os.path.exists(perms_file_path):
self.logger.debug(f"Applying permissions {file_perms}, owner {file_uid}, group {file_gid} to {perms_file_path}")
# chown clears suid bits, must come first
os.chown(perms_file_path, file_uid, file_gid)
os.chmod(perms_file_path, file_perms)
else:
self.logger.warn(f"Can't apply permissions to {perms_file_path}, file doesn't exist.")
if not destructive_only:
self.logger.debug("Processing acls.jsonl")
with open(os.path.join(meta_dir, "acls.jsonl"), "r") as acls_file:
@ -1167,7 +1210,10 @@ class OpengnsysGitLibrary:
except FileExistsError as exists:
self.logger.debug(f"Exists: {full_path}")
# chown clears suid bit, so even though it's redundant in most cases and already
# done above, set the full perms on the file again anyway.
os.chown(full_path, data['uid'], data['gid'])
os.chmod(full_path, file_mode)
self.logger.debug("Metadata restoration completed.")