Good day
Background:
I am creating an OpenVPN wrapper application for Linux systems which is near completion. I have run into a little snag.
However, this does not seem to work with modern day Linux systems. Here is the output of executing a root owned application with the s bit set, run as a normal (unprivileged) user:
2017-12-19 12::21:08 Fatal: FATAL: The application binary appears to be running setuid, this is a security hole. ((null):0, (null))
The above error has nothing to do with modern day Linux systems. Its a Qt protection against stupid developers using setuid without understanding it.
Simply call
QCoreApplication::setSetuidAllowed(true)
when your application starts, and then you can do setuid() just fine. You can even run privileged commands before dropping down to 'normal' user.
Summary:
Your Qt application must have root owner, and setuid bit set. Example debmaker is my Qt application that I want to perform privileged actions from. So after I build debmaker, I do:
sudo chown root:root debmaker
sudo chmod 4755 debmaker
(The latter sets the setuid bit)
Now run the Qt application
./debmaker
First thing the app does is check geteuid()==0 and getuid()==1000 (1000 is my user id, 0 is the root)
Then it launches a new process (using QProcess in Qt). This will run in privileged mode. (Example my child process is called chroot)
Now drop the main application (my debmaker) to normal user level by calling
setuid(getuid());
chroot (the child process ) will keep running as root user.
The main application, now no longer is running in elevated mode, but can send requests to its child process which is still running in elevated mode.
QProcess *chroot = new QProcess;
blah blah setup the chroot and start it
chroot->write("chown root:root /home/oosman/foo");
The last line will send a message to the child process. You read the stdin in the child process, parse the command, check it to ensure its not malicious (or malicious depending on your intent!) and execute the command.