func DropPrivileges(username string) error { userInfo, err := user.Lookup(username) if err != nil { return err } uid, err := strconv.Atoi(userInfo.Uid) if err != nil { return err } gid, err := strconv.Atoi(userInfo.Gid) if err != nil { return err } // TODO: should set secondary groups too err = unix.Setgroups([]int{gid}) if err != nil { return err } err = unix.Setregid(gid, gid) if err != nil { return err } err = unix.Setreuid(uid, uid) if err != nil { return err } return nil }
func main() { flag.IntVar(&JID, "jid", -1, "Jail ID") flag.IntVar(&Uid, "uid", 0, "User to run as") flag.IntVar(&Gid, "gid", 0, "Group to run as") flag.StringVar(&AppName, "app", "", "Application name") flag.StringVar(&WorkingDirectory, "cwd", "/", "Working directory") flag.StringVar(&MetadataURL, "mds", "", "Metadata server URL") flag.Var(&Env, "setenv", "Environment variables") flag.Parse() Exec = flag.Args() // TODO: sanity check? if err := JailAttach(JID); err != nil { panic(err) } if err := unix.Chroot(filepath.Join("/app", AppName, "rootfs")); err != nil { panic(err) } if err := os.Chdir(WorkingDirectory); err != nil { panic(err) } if _, ok := Env["PATH"]; !ok { Env["PATH"] = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" } if _, ok := Env["TERM"]; !ok { term := os.Getenv("TERM") if term == "" { term = "vt100" } Env["TERM"] = term } Env["AC_APP_NAME"] = AppName Env["AC_METADATA_URL"] = MetadataURL envv := make([]string, 0, len(Env)) for k, v := range Env { envv = append(envv, k+"="+v) } if err := unix.Setgroups([]int{}); err != nil { panic(err) } if err := unix.Setregid(Gid, Gid); err != nil { panic(err) } if err := unix.Setreuid(Uid, Uid); err != nil { panic(err) } // FIXME: setusercontext()? // See https://github.com/freebsd/freebsd/blob/master/usr.sbin/jexec/jexec.c#L123-L126 os.Clearenv() if err := syscall.Exec(Exec[0], Exec, envv); err != nil { panic(err) } }