Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running external commands through os/exec under another user

Tags:

Using the os/exec package, I want to run an external command on a *nix OS, on behalf of another user (of course go process run under root user of another user with su privileges)

I want avoid "su" or "bash" commands and make it purely with go.

I made an approach using syscall.Setuid but this will change the user to the main project, I just need change the user to the external child process:

func (self *Command) LoseTo(username string) {
   u, err := user.Lookup(username)
   if err != nil {
      fmt.Printf("%v", err)
   }

   uid, err := strconv.Atoi(u.Uid)
   if err := syscall.Setuid(uid); err != nil {
      fmt.Printf("%v", err)
   }
}
like image 333
mcuadros Avatar asked Feb 11 '14 15:02

mcuadros


2 Answers

You can add a syscall.Credential struct to Cmd.SysProcAttr

cmd := exec.Command(command, args...)
cmd.SysProcAttr = &syscall.SysProcAttr{}
cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uid, Gid: gid}
like image 125
JimB Avatar answered Sep 22 '22 01:09

JimB


In case if someone is looking for a working code snippet:

u, erru := user.Lookup(LocalUserName)
if erru != nil {
    fmt.Println( erru, " for ",LocalUserName)
}
uid, err = strconv.ParseInt(u.Uid, 10, 32)
gid, err = strconv.ParseInt(u.Gid, 10, 32)

cmd := exec.Command("/bin/uname", "-a")
cmd.Stdout = &out
cmd.Stderr = &stderr
cmd.SysProcAttr = &syscall.SysProcAttr{}
cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}
err = cmd.Run()
like image 30
VikasPushkar Avatar answered Sep 22 '22 01:09

VikasPushkar