I had to do a dirty Linux hack for somebody so they could start a printer with the cupsenable printername
shell command while being a non-root user. I didn't want them to be able to use the entirety of the cupsenable
syntax as root, so I just wrote a C wrapper that sanitizes the input in argv[1]
and calls system("cupsenable sanitizedprintername")
.
I made the program setuid root, but even so, cupsenable
failed with "permission denied". Then I inserted a setuid(0)
call before system()
and, lo and behold, it worked.
Disregard the issue of there being a better way to give users control of the printer. There probably is a better way. What I'm interested in are the intricacies of chmod u+s
vs. setuid(0)
vs. system()
. Why did it behave that way?
The Unix access rights flags setuid and setgid (short for set user identity and set group identity) allow users to run an executable with the file system permissions of the executable's owner or group respectively and to change behaviour in directories.
SETUID 0 or root means that when the program is run it is as if root ran it - which leaves you open to all the usual security risks of running something at high permission levels - it could potentially do anything to your system - so generally the number of applications that require SETUID should be minimised on a Unix ...
If a file is “setuid” and is owned by the user “root” then a user that has the ability to execute that program will do so as the user root instead of themselves. The most common example of this in Linux is 'sudo'.
setuid and setgid files are dangerous because they might give an unauthorized user root access, or at least access to run a program in another user's name. To make a program setuid root, the user must be root.
From man system
:
Do not use
system()
from a program with set-user-ID or set-group-ID privileges, because strange values for some environment variables might be used to subvert system integrity. Use theexec(3)
family of functions instead, but notexeclp(3)
orexecvp(3)
.system()
will not, in fact, work properly from programs with set-user-ID or set-group-ID privileges on systems on which/bin/sh
is bash version 2, since bash 2 drops privileges on startup.
And from man bash
:
If the shell is started with the effective user (group) id not equal to the real user (group) id, and the
-p
option is not supplied, no startup files are read, shell functions are not inherited from the environment, theSHELLOPTS
variable, if it appears in the environment, is ignored, and the effective user id is set to the real user id.
It appears your setuid(0)
call circumvented that protection.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With