Complete guide to Python's os.geteuid function covering effective user IDs, process permissions, and practical examples.
Last modified April 11, 2025
This comprehensive guide explores Python’s os.geteuid function, which returns the effective user ID of the current process. We’ll cover Unix user IDs, real vs effective UIDs, and practical permission checking examples.
The os.geteuid function returns the numeric effective user ID of the current process. This is a Unix-specific function that doesn’t work on Windows systems.
Effective UID determines what files and resources a process can access. It may differ from the real UID when running setuid programs or when privileges are changed.
The simplest use of os.geteuid retrieves the current process’s effective user ID. This example shows basic retrieval and comparison.
basic_geteuid.py
import os
euid = os.geteuid() print(f"Effective UID: {euid}")
if euid == os.getuid(): print(“Effective UID matches real UID”) else: print(“Effective UID differs from real UID”)
This code retrieves the effective UID and compares it with the real UID. For most normal processes, these values will be the same.
The effective UID is what the system uses for permission checks, while the real UID identifies the user who started the process.
A common use of os.geteuid is checking if a process is running with root privileges (UID 0). This example demonstrates root privilege check.
check_root.py
import os import sys
if os.geteuid() == 0: print(“Running with root privileges”) else: print(“Not running as root”) print(“This program requires root privileges”) sys.exit(1)
with open("/etc/shadow", “r”) as f: print(“Successfully accessed /etc/shadow”)
This script checks for root privileges before attempting to access a root-protected file. It exits if not running as root.
Note that checking UID 0 is the proper way to detect root privileges, not checking for the username “root”.
This example demonstrates the difference between real and effective UIDs by temporarily changing privileges. Requires root to run fully.
compare_uids.py
import os
def print_uids(): print(f"Real UID: {os.getuid()}") print(f"Effective UID: {os.geteuid()}")
print(“Initial state:”) print_uids()
if os.geteuid() == 0: original_euid = os.geteuid() os.seteuid(1000) # Change to a normal user print("\nAfter seteuid(1000):") print_uids()
# Restore original privileges
os.seteuid(original_euid)
print("\nAfter restoring privileges:")
print_uids()
else: print("\nCannot demonstrate privilege changes - run as root")
This script shows how to temporarily drop and restore privileges while maintaining the real UID. The effective UID changes affect permissions.
Note that os.seteuid only changes the effective UID, while os.setuid changes both real and effective UIDs.
This example simulates a setuid program behavior where effective and real UIDs differ. Requires root to set up properly.
setuid_example.py
import os import pwd
def print_user_info(): try: euser = pwd.getpwuid(os.geteuid()).pw_name ruser = pwd.getpwuid(os.getuid()).pw_name print(f"Real user: {ruser} (UID: {os.getuid()})") print(f"Effective user: {euser} (UID: {os.geteuid()})") except KeyError: print(“Could not resolve UID to username”)
print(“Starting as:”) print_user_info()
if os.geteuid() == 0: print("\nDropping privileges to nobody:") nobody = pwd.getpwnam(“nobody”) os.setegid(nobody.pw_gid) os.seteuid(nobody.pw_uid) print_user_info()
print("\nRestoring root privileges:")
os.seteuid(0)
os.setegid(0)
print_user_info()
else: print("\nRun as root to see privilege change demonstration")
This script demonstrates how setuid programs can temporarily assume different privileges while maintaining the original user identity.
The example uses both UID and GID changes for completeness, though geteuid only deals with user IDs.
This example shows how to use os.geteuid with file permissions to implement custom access checks beyond standard Unix permissions.
file_access_check.py
import os import stat
def check_file_access(path): try: st = os.stat(path) except FileNotFoundError: return False
# Check if owner matches our effective UID
if st.st_uid == os.geteuid():
mode = "owner"
# Check if group matches any of our groups
elif st.st_gid in os.getgroups():
mode = "group"
else:
mode = "other"
# Check read permission based on mode
if mode == "owner" and st.st_mode & stat.S_IRUSR:
return True
elif mode == "group" and st.st_mode & stat.S_IRGRP:
return True
elif mode == "other" and st.st_mode & stat.S_IROTH:
return True
return False
file_path = “/etc/passwd” if check_file_access(file_path): print(f"Read access granted to {file_path}") else: print(f"Read access denied to {file_path}")
This custom access check function mimics Unix permission checks but could be extended with additional rules. It uses geteuid to determine ownership.
The function checks owner, group, and other permissions separately based on the effective UID and group membership.
This example shows how effective UID affects the security context of child processes and file operations. Requires root to demonstrate fully.
security_context.py
import os import subprocess
print(f"Parent process - EUID: {os.geteuid()}")
test_file = “euid_test.txt” with open(test_file, “w”) as f: f.write(“Test content”)
st = os.stat(test_file) print(f"File owner UID: {st.st_uid}")
pid = os.fork() if pid == 0: print(f"Child process - EUID: {os.geteuid()}")
# Try to modify the file
try:
with open(test_file, "a") as f:
f.write("\nChild process addition")
print("Child successfully modified file")
except PermissionError:
print("Child failed to modify file")
os._exit(0)
os.waitpid(pid, 0)
if os.geteuid() == 0: original_euid = os.geteuid() os.seteuid(1000) # Change to normal user
pid = os.fork()
if pid == 0:
print(f"\nChild with changed EUID: {os.geteuid()}")
try:
with open(test_file, "a") as f:
f.write("\nChanged EUID addition")
print("Child with changed EUID modified file")
except PermissionError:
print("Child with changed EUID failed to modify file")
os._exit(0)
os.waitpid(pid, 0)
os.seteuid(original_euid) # Restore EUID
os.unlink(test_file)
This example demonstrates how child processes inherit the effective UID and how changing it affects file operations. The second part requires root.
The example shows that file access permissions depend on the effective UID at the time of the operation, not when the process started.
Privilege separation: Use minimal effective privileges
Windows compatibility: geteuid is Unix-specific
Setuid programs: Be cautious with privilege escalation
Child processes: Inherit effective UID by default
Root detection: Check for UID 0, not username
Drop privileges early: Reduce effective privileges when possible
Check return values: Verify seteuid operations succeed
Document requirements: Clearly note privilege needs
Use os.geteuid: For security checks rather than os.getuid
Consider alternatives: Capabilities on Linux for finer control
My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.
List all Python tutorials.