2018-06-13 16:52:41 +02:00
|
|
|
// +build !windows
|
|
|
|
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"os"
|
|
|
|
"os/exec"
|
|
|
|
"os/user"
|
|
|
|
"path/filepath"
|
|
|
|
"strconv"
|
|
|
|
"syscall"
|
2018-07-01 23:06:28 +02:00
|
|
|
"time"
|
2018-06-13 17:24:16 +02:00
|
|
|
|
2018-06-13 16:52:41 +02:00
|
|
|
"github.com/jedisct1/dlog"
|
|
|
|
)
|
|
|
|
|
2018-08-04 00:57:52 +02:00
|
|
|
var cmd *exec.Cmd
|
|
|
|
|
2018-06-13 16:52:41 +02:00
|
|
|
func (proxy *Proxy) dropPrivilege(userStr string, fds []*os.File) {
|
2018-08-04 00:57:52 +02:00
|
|
|
currentUser, err := user.Current()
|
|
|
|
if err != nil {
|
|
|
|
dlog.Fatal(err)
|
|
|
|
}
|
|
|
|
if currentUser.Uid != "0" {
|
|
|
|
dlog.Fatal("I need root permissions. Try again with 'sudo'")
|
|
|
|
}
|
2018-06-13 16:52:41 +02:00
|
|
|
user, err := user.Lookup(userStr)
|
|
|
|
args := os.Args
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
dlog.Fatal(err)
|
|
|
|
}
|
|
|
|
uid, err := strconv.Atoi(user.Uid)
|
|
|
|
if err != nil {
|
|
|
|
dlog.Fatal(err)
|
|
|
|
}
|
|
|
|
gid, err := strconv.Atoi(user.Gid)
|
|
|
|
if err != nil {
|
|
|
|
dlog.Fatal(err)
|
|
|
|
}
|
2018-06-13 17:24:16 +02:00
|
|
|
execPath, err := exec.LookPath(args[0])
|
2018-06-13 16:52:41 +02:00
|
|
|
if err != nil {
|
|
|
|
dlog.Fatal(err)
|
|
|
|
}
|
2018-06-13 17:24:16 +02:00
|
|
|
path, err := filepath.Abs(execPath)
|
2018-06-13 16:52:41 +02:00
|
|
|
if err != nil {
|
|
|
|
dlog.Fatal(err)
|
|
|
|
}
|
|
|
|
|
2018-07-19 19:03:57 +02:00
|
|
|
ServiceManagerReadyNotify()
|
2018-07-07 17:21:21 +02:00
|
|
|
|
2018-07-01 22:48:50 +02:00
|
|
|
args = args[1:]
|
2018-06-13 17:24:16 +02:00
|
|
|
args = append(args, "-child")
|
2018-06-13 16:52:41 +02:00
|
|
|
|
|
|
|
dlog.Notice("Dropping privileges")
|
2018-07-01 23:06:28 +02:00
|
|
|
for {
|
2018-08-04 00:57:52 +02:00
|
|
|
cmd = exec.Command(path, args...)
|
2018-07-01 23:06:28 +02:00
|
|
|
cmd.Stdout = os.Stdout
|
|
|
|
cmd.Stderr = os.Stderr
|
|
|
|
cmd.ExtraFiles = fds
|
|
|
|
cmd.SysProcAttr = &syscall.SysProcAttr{}
|
|
|
|
cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}
|
|
|
|
if cmd.Run() == nil {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
time.Sleep(1 * time.Second)
|
2018-06-13 16:52:41 +02:00
|
|
|
}
|
|
|
|
os.Exit(0)
|
|
|
|
}
|
2018-08-04 00:57:52 +02:00
|
|
|
|
|
|
|
func killChild() {
|
|
|
|
if cmd != nil {
|
|
|
|
if err := cmd.Process.Kill(); err != nil {
|
|
|
|
dlog.Fatal("Failed to kill child process.")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|