Qt, Linux, check if a given user has sudo privileges

Ivan Caravanio picture Ivan Caravanio · Jul 1, 2012 · Viewed 21.3k times · Source

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.

Answer

   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.