以root身份运行时以用户身份启动外部进程

问题描述:

我编写了一个在启动时以root用户身份运行的单声道应用程序(upstart + mono-service)并监听用户登录/注销事件。当用户登录时,我开始另一个单声道服务来监听会话事件。但它不应以root身份运行,而应以会话所有者身份运行。我有权访问会话所有者的名称,uid,gid。以root身份运行时以用户身份启动外部进程

我的问题有点类似于Start a process as user from an process running as admin,但对于Linux。

那么如何在正确运行根目录的情况下以指定的用户身份运行外部进程呢?

编辑:

这里是我的解决方案:

根据http://pages.infinit.net/ctech/20040405-1133.html我试图冒充用户在启动的过程,它工作得很好,因为我可以看到现在。

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; 
} 

这是一个可靠的方法吗?或者有更好的吗?

这将运行echo hello为用户alice

sudo su alice -c 'echo hello' 
+0

这是一个真正的选择,谢谢!但我不太清楚'System.Diagnostics.Process'将如何处理这样的链:'sudo su username -c mono-service/home/username/App.exe'。据我所知,它的语法是(“应用程序”,“参数”) –

+0

'Proccess(“sudo”,“su用户名-c mono-service /home/username/App.exe”)'也许?或者'/ usr/bin/sudo'。 顺便说一下,你确定你在运行linux吗? '.exe'文件扩展名通常只用于Windows。 –

+0

来自单声道 –

这可以通过使用-c参数su,并指定希望用户运行一个命令来完成。

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


su someuser -c "touch someusersfile" 

ls -la someusersfile 

ls -la输出应该是这个样子: -rw-R - R-- 1 SomeUser的SomeUser的0 10月06日22:22 mynewfile