github.com/geofffranks/garden-linux@v0.0.0-20160715111146-26c893169cfa/system/user_execer_linux.go (about) 1 package system 2 3 import ( 4 "errors" 5 "fmt" 6 "os" 7 "os/exec" 8 "runtime" 9 "syscall" 10 ) 11 12 func init() { 13 runtime.LockOSThread() 14 } 15 16 type UserExecer struct{} 17 18 func (UserExecer) ExecAsUser(uid, gid int, workDir, programName string, args ...string) error { 19 if _, _, errNo := syscall.RawSyscall(syscall.SYS_SETGID, uintptr(gid), 0, 0); errNo != 0 { 20 return fmt.Errorf("system: setgid: %s", errNo.Error()) 21 } 22 23 if err := syscall.Setgroups([]int{}); err != nil { 24 return fmt.Errorf("system: setgroups: %s", err) 25 } 26 27 if _, _, errNo := syscall.RawSyscall(syscall.SYS_SETUID, uintptr(uid), 0, 0); errNo != 0 { 28 return fmt.Errorf("system: setuid: %s", errNo.Error()) 29 } 30 31 if workDir == "" { 32 return errors.New("system: working directory is not provided.") 33 } 34 35 if err := os.MkdirAll(workDir, 0755); err != nil { 36 return fmt.Errorf("system: %s", err) 37 } 38 39 if err := os.Chdir(workDir); err != nil { 40 return fmt.Errorf("system: invalid working directory: %s", workDir) 41 } 42 43 programPath, err := exec.LookPath(programName) 44 if err != nil { 45 return fmt.Errorf("system: program '%s' was not found in $PATH: %s", programName, err) 46 } 47 48 if err := syscall.Exec(programPath, append([]string{programName}, args...), os.Environ()); err != nil { 49 return fmt.Errorf("system: exec of %s: %s", programName, err) 50 } 51 return nil 52 }