Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
Python tarfile extractall without root privs? [SOLVED]
View unanswered posts
View posts from last 24 hours

 
Reply to topic    Gentoo Forums Forum Index Portage & Programming
View previous topic :: View next topic  
Author Message
audiodef
Watchman
Watchman


Joined: 06 Jul 2005
Posts: 6656
Location: The soundosphere

PostPosted: Fri Jun 14, 2024 6:10 pm    Post subject: Python tarfile extractall without root privs? [SOLVED] Reply with quote

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
View user's profile Send private message
szatox
Advocate
Advocate


Joined: 27 Aug 2013
Posts: 3437

PostPosted: Fri Jun 14, 2024 7:04 pm    Post subject: Reply with quote

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
View user's profile Send private message
Genone
Retired Dev
Retired Dev


Joined: 14 Mar 2003
Posts: 9612
Location: beyond the rim

PostPosted: Sat Jun 15, 2024 11:39 am    Post subject: Reply with quote

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
View user's profile Send private message
audiodef
Watchman
Watchman


Joined: 06 Jul 2005
Posts: 6656
Location: The soundosphere

PostPosted: Sun Jun 23, 2024 11:53 pm    Post subject: Reply with quote

I'm going to totally blame myself for overthinking this one and require that the user be root to use this program. But I appreciate the replies.
_________________
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
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Portage & Programming All times are GMT
Page 1 of 1

 
Jump to:  
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