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.Parse() Info.Pid = os.Getpid() Info.Uid = -1 Info.Gid = -1 Info.Version = jetpack.Version() if host, err := jetpack.NewHost(); err != nil { log.Fatalln("Error initializing host:", err) } else { Host = host } if hostip, _, err := Host.HostIP(); err != nil { panic(err) } else { Info.IP = hostip.String() } Info.Port = jetpack.Config().MustGetInt("mds.port") if s, err := hex.DecodeString(jetpack.Config().MustGet("mds.signing-key")); err != nil { panic(err) } else { SigningKey = s } switch lfPath, _ := jetpack.Config().Get("mds.logfile"); lfPath { case "-", "": log.SetOutput(os.Stderr) case "none", "/dev/null": log.SetOutput(ioutil.Discard) default: if lf, err := os.OpenFile(lfPath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0640); err != nil { log.Fatalf("Cannot open log file %#v: %v", lfPath, err) } else { log.SetOutput(lf) defer lf.Close() } } if pfPath, ok := jetpack.Config().Get("mds.pidfile"); ok { if err := ioutil.WriteFile(pfPath, []byte(fmt.Sprintln(os.Getpid())), 0644); err != nil { log.Fatalf("Cannot write pidfile %#v: %v", pfPath, err) } } addr := fmt.Sprintf("%v:%d", Info.IP, Info.Port) listener, err := net.Listen("tcp", addr) if err != nil { log.Fatalf("Cannot listen on %v: %v", addr, err) } if !jetpack.Config().GetBool("mds.keep-uid", false) { uid, gid := jetpack.MDSUidGid() if err := unix.Setgroups(nil); err != nil { log.Fatal("Cannot clear groups:", err) } if err := unix.Setresgid(gid, gid, gid); err != nil { log.Fatal("Cannot drop gid:", err) } if err := unix.Setresuid(uid, uid, uid); err != nil { log.Fatal("Cannot drop uid:", err) } } Info.Uid = os.Getuid() Info.Gid = os.Getgid() log.Println("Listening on:", addr) log.Fatal(http.Serve(listener, http.HandlerFunc(ServeMetadata))) }
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) } }