Removing 'su' password request from within a C++ program

时间:2017-04-10 00:06:50

标签: c++ google-drive-api ubuntu-16.04 mount setuid

I'm running an Ubuntu 16.04 LTS system. The entire system is contained in one partition (/dev/sda1). I'm trying to write a tool in C++ that runs as root and uses the 'su' command to run a command for the user of the tool to achieve a particular task. The reason I want the tool to run as root is that I want to avoid the password request of 'su' for the user. (In a terminal, if logged in as root, 'su' to another user never requests a password. I'd like to have the same behavior from within the C++ program.)

If I were to go into detail, I want to allow the mounting of a user's google drive, whose mounting options (including its mount point) are expressed in an entry in the /etc/fstab file, by a mount command issued by the user. I found a tool that mounts a google drive to a specified mount point in this TechRepublic article[1]. I have run the tool as a regular user to allow it to access my google drive and can successfully run the tool to mount the drive. I wanted to automate this by putting an entry in the /etc/fstab file and discovered that it was possible in this answer[2] to a related question so I wrote the following C++ code, compiled it, gave ownership of its executable to root, set the executable's setuid bit and put it in the /usr/local/sbin directory (as /usr/local/sbin/mount-google-drive).

[1] http://www.techrepublic.com/article/how-to-mount-your-google-drive-on-linux-with-google-drive-ocamlfuse/

[2] https://stackoverflow.com/a/8108474/7842054

//mount-google-drive.cc
#include <iostream>
#include <cstdlib>
#include <string>

int main(int argc, char* argv[])
{
  if (std::system("which google-drive-ocamlfuse > /dev/null"))
  {
    std::cout << argv[0] <<
      " needs 'google-drive-ocamlfuse' to mount the drive." << std::endl;
    return 1;
  }

  if (argc < 3)
  {
    std::cout << "Usage: " << argv[0] <<
      "<label> <mount point> [google-drive-ocamlfuse options]" << std::endl;
    return 0;
  }

  // Compile the mount command.
  std::string mount_command = (std::string) "google-drive-ocamlfuse -label " +
    argv[1];
  for (int i = 2; i < argc; i++)
  {
    mount_command += (std::string) " " + argv[i];
  }

  std::string system_command = (std::string) "su $USER -l -c \"" + mount_command + "\"";

  // Output the compiled command
  std::cout << system_command << std::endl;

  // Run the mount command to mount the google drive for the user.
  std::system(system_command.c_str());

  return 0;
}

I then placed this entry in the /etc/fstab file:

# This is to allow the 'GoogleDrive' remote filesystem to be mounted locally
mount-google-drive#default  /media/GoogleDrive     fuse    user,noauto     0       0

And created the /media/GoogleDrive mount point accessible to my regular user account.

With these changes, I can run 'mount /media/GoogleDrive' as a regular user, but, as a regular user, I always get prompted for my password.

My ultimate goal is to allow a drive mounting app on my gnome desktop to mount the google drive. The app only recognizes entries in the /etc/fstab file.

As far as running a tool as root, am I right in understanding that having the tool owned by root and having its setuid bit set would make the tool run as root? Does this then mean that running 'su' within that tool would remove the password request for the user? Any help would be greatly appreciated.

0 个答案:

没有答案