Golang如何让子进程以另一个用户身份运行

当父进程launch一个子进程的时候,如何使得子进程使用另一个用户身份运行。

前提条件当前用户得用足够的权限切换到另一个用户,所以通常父进程是root。

下面的例子是root用户的父进程,如何launch一个子进程,并且使得子进程以nobody的身份在运行(nobody是*nix操作系统的内置账号)。

package main

import (
    "os"
    "log"
    "syscall"
    "strconv"
    "os/exec"
    "os/user"
)

func main() {
    cmd := exec.Command("./subcommand")
    cmd.Stdout = os.Stdout
    cmd.Stderr = os.Stderr

    user, err := user.Lookup("nobody")
    if err == nil {
       log.Printf("uid=%s,gid=%s", user.Uid, user.Gid)

       uid, _ := strconv.Atoi(user.Uid)
       gid, _ := strconv.Atoi(user.Gid)

       cmd.SysProcAttr = &syscall.SysProcAttr{}
       cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}
    }

    err = cmd.Run();
    if err != nil {
        log.Fatal(err)
    }
}

其中关键的命令就是两行

cmd.SysProcAttr = &syscall.SysProcAttr{}
cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}

先查找到nobody用户的uid和gid,然后调用syscall.Credential对象。

注意上述的操作都需要特权,通常只有root用户才有这个权限。