It's not really clear exactly what you're trying to achieve. From your question you might be:
- Attempting to execute something as a different user for testing without the overhead of creating that user every time
- Attempting to run a process as a user that doesn't exist (with not matching entry in
/etc/passwd
or more precisely with getent passwd
)
- Attempting to test the behaviour of
CAP_SETUID
If either of the first two then you could just create an executable with setuid
and setgid
bits set and set the executable user and group to an arbitary number. You don't even need to compile your own executable, just copy an existing one.
As root:
mkdir test_dir
# Secure the directory to prevent tampering by other users
chmod go-rx test_dir
cd test_dir
cp $(which bash) .
# arbitrary user 1997 group 1998
chown 1997:1998 ./bash
chmod ug+s ./bash
chmod go+rx ./bash
# Run touch as an arbitrary user
./bash -p -c `touch /tmp/test_file`
# Check the result
ls -lh /tmp/test_file
-rw-r----- 1 1997 1998 0 Jan 11 08:22 /tmp/test_file
Additionally python (a scripting programming language) is available on many platforms. You could write a very short python script to run something after calling setuid and setgid:
eg uid.py:
import os
import sys
import subprocess
# Set uid and gid
os.setuid(int(sys.argv[1]))
os.setgid(int(sys.argv[2]))
# Run the given command, passing in remaining arguments.
subprocess.run(*sys.argv[3:])
Then, with CAP_SETUID
given to python you could:
python setuid.py 1997 1998 touch /tmp/test_file
This will have the same effect of running touch
with uid 1997 and gid 1998.
Note that python scripts do not need to be created as files they can be passed inline: https://stackoverflow.com/a/16938013/453851