View previous topic :: View next topic |
Author |
Message |
audiodef Watchman
Joined: 06 Jul 2005 Posts: 6656 Location: The soundosphere
|
Posted: Fri Jun 14, 2024 6:10 pm Post subject: Python tarfile extractall without root privs? [SOLVED] |
|
|
Posting here because this concerns the Gentoo stage3 tarballs. My question is about the last section of code. Is it possible to execute this code without requiring root privs? As is, it won't finish unpacking unless I'm root.
Manually, I would tar xpvf stage3-*.tar.xz --xattrs-include='*.*' --numeric-owner -C CHROOT_DIR.
This program will be for setting up a chroot to create custom stage4's, if you're wondering.
Code: |
import requests
import os
import shutil
import tarfile
from pathlib import Path
# These could be set via config file.
ARCH_TYPE = "stage3-amd64-desktop-systemd"
DISTFILES_URL = "https://distfiles.gentoo.org/releases/amd64/autobuilds/current-"
CHROOT_DIR = "/home/audiodef/decibellinux/stagebuilder/stage3chroot"
### DOWNLOAD STAGE3
# Get current stage3 filename:
arch_url = f"{DISTFILES_URL}{ARCH_TYPE}/"
manifest_resp = requests.get(f"{arch_url}latest-{ARCH_TYPE}.txt") # Get the manifest file.
manifest_resp.raise_for_status() # Halt execution if the URL for the manifest file is not valid.
xz_filename = None
for line in manifest_resp.text.splitlines():
if line.startswith(ARCH_TYPE) and ".tar.xz" in line: # Change this logic if the manifest file format changes.
xz_filename = line.split()[0] # Extract the current stage3 filename from the manifest file.
break
if not xz_filename:
raise ValueError("Could not get the stage3 filename.") # If no filename, stop execution.
else:
print(f"Current stage3 is {xz_filename}.")
# Fetch stage3 seed file or continue with existing seed if it is still current:
seed_file_path = Path(xz_filename)
if seed_file_path.exists():
print("Seed file exists. Proceeding with existing seed file.")
else:
print("Seed file does not exist. Fetching seed file...")
src_url = f"{arch_url}/{xz_filename}"
response = requests.get(src_url, stream=True)
response.raise_for_status() # Make sure the URL is valid and/or there is a working connection.
with open(ARCH_FILE, mode="wb") as file:
for chunk in response.iter_content(chunk_size=10 * 1024):
file.write(chunk)
print("Done.")
### UNPACK STAGE3
# At this point, testing should only be done in a testing-only environment such as a VM.
# As written, this program requires root privileges, but I would prefer that it not.
print("Clearing previous run...")
shutil.rmtree(CHROOT_DIR, ignore_errors=True) # Clear previous run. Any errors would be because this path doesn't exist yet, and that's fine.
os.makedirs(CHROOT_DIR, exist_ok=False) # Create empty chroot dir. exist_ok should not be True because it should have been rm'd by previous line.
print("Done.")
print("Extracting stage3...")
with tarfile.open(f'{xz_filename}') as f:
f.extractall(f'{CHROOT_DIR}', numeric_owner=True) # How to not require root privs at this point?
print("Done.")
|
_________________ decibel Linux: https://decibellinux.org
Github: https://github.com/Gentoo-Music-and-Audio-Technology
Facebook: https://www.facebook.com/decibellinux
Discord: https://discord.gg/73XV24dNPN
Last edited by audiodef on Sun Jun 23, 2024 11:53 pm; edited 1 time in total |
|
Back to top |
|
|
szatox Advocate
Joined: 27 Aug 2013 Posts: 3433
|
Posted: Fri Jun 14, 2024 7:04 pm Post subject: |
|
|
Quote: | Manually, I would tar xpvf stage3-*.tar.xz --xattrs-include='*.*' --numeric-owner -C CHROOT_DIR. | p covers permissions, and I think also xattrs. Setting owner to _not_you_ also requires root access.
Quote: | f.extractall(f'{CHROOT_DIR}', numeric_owner=True) # How to not require root privs at this point? | I guess omitting numeric_owner would let it run, but you'll likely end up with a broken system.
At least that's how things used to be. Currently linux has more fine-grained access control implemented with capabilities. In particular, this looks promissing:
Code: | CAP_CHOWN
Make arbitrary changes to file UIDs and GIDs (see chown(2)). | Not sure how it works on python scripts though... E.g. I think kernel ignores suid on shell scripts, considering them too easy to modify (even though modification removes suid from binary executables) to be safe.
Still, it might be worth checking out. Anyway, this looks like a decent quickstart guide https://linuxconfig.org/introduction-to-linux-capabilities
Ah, one more thing to keep in mind: AFAIR capabilities are flags set at filesystem level. Not all filesystems support them. _________________ Make Computing Fun Again |
|
Back to top |
|
|
Genone Retired Dev
Joined: 14 Mar 2003 Posts: 9611 Location: beyond the rim
|
Posted: Sat Jun 15, 2024 11:39 am Post subject: |
|
|
szatox wrote: | Ah, one more thing to keep in mind: AFAIR capabilities are flags set at filesystem level. Not all filesystems support them. |
The classic approach with caps is that a process (e.g. ping) is started with full root priviledges, and then explicitly drops all priviledges except those it actually needs via syscall as early as possible. Any solution to elevate priviledges for a non-root process unfortunately won't be very portable. |
|
Back to top |
|
|
audiodef Watchman
Joined: 06 Jul 2005 Posts: 6656 Location: The soundosphere
|
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|