1

I,m writing a mono application which is intended to run at startup as root (upstart + mono-service) and listen to user login/logout events. When user loggs in I start another mono service to listen to session events. But it should not run as root, but as session owner. I have access to session owner's name, uid, gid.

My problem is someow similar to Start a process as user from an process running as admin , but for linux.

So how to run external process as specified user while running from root properly?

Edit:

Here's my solution:

According to http://pages.infinit.net/ctech/20040405-1133.html I've tried to impersonate to user while starting process, and it works well as I can see for now.

public class SpawnerService : ServiceBase
{
    public SpawnerService ()
    {
        logger = new StreamWriter (new FileStream("/home/username/Log.txt", FileMode.Append));

        info = new ProcessStartInfo {
            FileName = "/usr/bin/mono-service",
            Arguments = "/home/username/SlaveService.exe",
            UseShellExecute = false,
            CreateNoWindow = true
        };
    }

    protected override void OnStart (string[] args)
    {
        logger.WriteLine ("Spawner service started");
        logger.Flush ();

        var user = new WindowsIdentity ("username");
        logger.WriteLine ("Trying to mimc to {0}, {1}", user.Name,user.Token.ToString());
        logger.Flush ();

        WindowsImpersonationContext wic = null;
        try {
            wic = user.Impersonate ();
            Process.Start (info);
            logger.WriteLine ("Seems allright");
            logger.Flush ();
        }
        catch (Exception) {
            logger.WriteLine ("Seems failed");
            logger.Flush ();
        }
        finally {
            if (wic != null) {
                wic.Undo ();
                wic = null;
            }
        }
    }

    protected override void OnStop ()
    {
        logger.WriteLine ("Spawner service stopped");
        logger.Flush ();
    }

    private ProcessStartInfo info;
    private StreamWriter logger;
}

Is this a reliable method? Or are there some better ones?

2 Answers2

0

This will run echo hello as user alice:

sudo su alice -c 'echo hello'
Brian Malehorn
  • 2,627
  • 14
  • 15
  • That's really an option, thanks! But I'm not quite sure how well `System.Diagnostics.Process` will handle such chain: `sudo su username -c mono-service /home/username/App.exe`. As far as I know, it's syntax is ("application","parameters") – Alexander Yushkov Oct 07 '15 at 03:44
  • `Proccess("sudo", "su username -c mono-service /home/username/App.exe")` perhaps? Or maybe `/usr/bin/sudo`. By the way, are you sure you're running linux? The `.exe` file extension is usually only used in windows. – Brian Malehorn Oct 07 '15 at 20:17
0

This can be accomplished by using the -c argument to su and specifying a command you wish the user to run.

"-c, --command COMMAND
       Specify a command that will be invoked by the shell using its -c."


su someuser -c "touch someusersfile"

ls -la someusersfile

The output of ls -la should look something like this: -rw-r--r-- 1 someuser someuser 0 Oct 6 22:22 mynewfile