I am running Fedora 17 KDE x64 and Qt 4.8.1.
In contrast with Ubuntu, Fedora doesn’t give the first created user sudo privileges and it doesn’t add the first created user to the /etc/sudoers
file. Therefore when installing programs on Fedora 17 KDE (haven’t tested the Gnome and etc. spins) it requires root
(not sudo
) privileges. So, we have three levels of privileges (listed in descending order according to the level of privileges):
1) root 2) sudo 3) user
In Fedora 17 KDE if you have access to the root
user account you can give sudo
privileges to any other user you want simply by editing the /etc/sudoers
file and adding the line:
user ALL = (ALL) ALL
… below the line:
root ALL = (ALL) ALL
Replace user
with the name of the account you wish to give sudo access to.
But not every user has access to the root
user’s account. That’s why the root
user could give super-user (sudo
) privileges to some user accounts.
What I want to to is to check if the current user running the application is registered as super-user. If so I will make the /usr/bin/kdesu
tool use the /usr/bin/sudo
tool which asks for sudo
password.
If the user is not super-user I leave /usr/bin/kdesu
behave as it does by default – it uses the /usr/bin/su
tool that requires root
password.
Currently, I am using getenv('USER')
(“USERNAME” on Windows but I need this functionality on Linux only) to get the current user. The current user’s name could be acquired by traversing QProcess::systemEnvironment()
where HOSTNAME and USER variables are listed.
Parsing the /etc/sudoers
file is not an option since opening the file requires sudo
or root
privileges.
man sudo
[...]
-l[l] [command]
If no command is specified, the -l (list)
option will list the allowed (and forbidden)
commands for the invoking user (or the user
specified by the -U option) on the current
host. If a command is specified and is
permitted by sudoers, the fully-qualified
path to the command is displayed along with
any command line arguments. If command is
specified but not allowed, sudo will exit
with a status value of 1. If the -l option
is specified with an l argument (i.e. -ll),
or if -l is specified multiple times, a
longer list format is used.
Update You need a (pseudo)terminal in order to run sudo
. Here's one way to do it:
#include <pty.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
int main (int argc, char* argv[])
{
int status, master;
pid_t respid, pid = forkpty (&master, 0, 0, 0);
if (pid == 0) {
/* we are child */
argv[0] = "/usr/bin/sudo"; /* I know it's a sin... just for a demo */
execve("/usr/bin/sudo", argv, 0);
}
else if (pid > 0) {
/* we are parent */
respid = waitpid(pid, &status, 0);
fprintf (stderr, "sudo exited with status %d\n",
WEXITSTATUS(status));
}
}
else {
fprintf (stderr, "could not forkpty\n");
}
}
Run this: runsudo -l
and runsudo -l /foo/bar/baz
for example.