func chuser(username string) (uid, gid int) { usr, err := user.Lookup(username) if err != nil { fmt.Printf("failed to find user %q: %s", username, err) } uid, err = strconv.Atoi(usr.Uid) if err != nil { fmt.Printf("bad user ID %q: %s", usr.Uid, err) } gid, err = strconv.Atoi(usr.Gid) if err != nil { fmt.Printf("bad group ID %q: %s", usr.Gid, err) } if err := syscall.Setgid(gid); err != nil { fmt.Printf("setgid(%d): %s", gid, err) } if err := syscall.Setuid(uid); err != nil { fmt.Printf("setuid(%d): %s", uid, err) } return uid, gid }
// SetupUser changes the groups, gid, and uid for the user inside the container func SetupUser(u string) error { uid, gid, suppGids, home, err := user.GetUserGroupSupplementaryHome(u, syscall.Getuid(), syscall.Getgid(), "/") if err != nil { return fmt.Errorf("get supplementary groups %s", err) } if err := syscall.Setgroups(suppGids); err != nil { return fmt.Errorf("setgroups %s", err) } if err := syscall.Setgid(gid); err != nil { return fmt.Errorf("setgid %s", err) } if err := syscall.Setuid(uid); err != nil { return fmt.Errorf("setuid %s", err) } // if we didn't get HOME already, set it based on the user's HOME if envHome := os.Getenv("HOME"); envHome == "" { if err := os.Setenv("HOME", home); err != nil { return fmt.Errorf("set HOME %s", err) } } return nil }
// Takes care of dropping privileges to the desired user func changeUser(args *DockerInitArgs) error { if args.user == "" { return nil } userent, err := utils.UserLookup(args.user) if err != nil { return fmt.Errorf("Unable to find user %v: %v", args.user, err) } uid, err := strconv.Atoi(userent.Uid) if err != nil { return fmt.Errorf("Invalid uid: %v", userent.Uid) } gid, err := strconv.Atoi(userent.Gid) if err != nil { return fmt.Errorf("Invalid gid: %v", userent.Gid) } if err := syscall.Setgid(gid); err != nil { return fmt.Errorf("setgid failed: %v", err) } if err := syscall.Setuid(uid); err != nil { return fmt.Errorf("setuid failed: %v", err) } return nil }
// Takes care of dropping privileges to the desired user func changeUser(u string) { if u == "" { return } userent, err := utils.UserLookup(u) if err != nil { log.Fatalf("Unable to find user %v: %v", u, err) } uid, err := strconv.Atoi(userent.Uid) if err != nil { log.Fatalf("Invalid uid: %v", userent.Uid) } gid, err := strconv.Atoi(userent.Gid) if err != nil { log.Fatalf("Invalid gid: %v", userent.Gid) } if err := syscall.Setgid(gid); err != nil { log.Fatalf("setgid failed: %v", err) } if err := syscall.Setuid(uid); err != nil { log.Fatalf("setuid failed: %v", err) } }
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 = syscall.Setgroups([]int{gid}) if err != nil { return err } err = syscall.Setgid(gid) if err != nil { return err } err = syscall.Setuid(uid) if err != nil { return err } return nil }
// SetupEnv will create pidfile and possibly change the workdir. func SetupEnv(cfg *config.Config) error { if cfg.System.User != "" { // Get the current user currentUser, err := user.Current() if err != nil { return fmt.Errorf("Could not get the current user: %s", err) } // If the current user is different than the wanted user, try to change it if currentUser.Username != cfg.System.User { wantedUser, err := user.Lookup(cfg.System.User) if err != nil { return err } uid, err := strconv.Atoi(wantedUser.Uid) if err != nil { return fmt.Errorf("Error converting UID [%s] to int: %s", wantedUser.Uid, err) } gid, err := strconv.Atoi(wantedUser.Gid) if err != nil { return fmt.Errorf("Error converting GID [%s] to int: %s", wantedUser.Gid, err) } if err = syscall.Setgid(gid); err != nil { return fmt.Errorf("Setting group id: %s", err) } if err = syscall.Setuid(uid); err != nil { return fmt.Errorf("Setting user id: %s", err) } } } if cfg.System.Workdir != "" { if err := os.Chdir(cfg.System.Workdir); err != nil { return fmt.Errorf("Could not chdir to '%s': %s", cfg.System.Workdir, err) } } pFile, err := os.Create(cfg.System.Pidfile) if err != nil { return err } defer pFile.Close() _, err = pFile.WriteString(fmt.Sprintf("%d", os.Getpid())) if err != nil { return err } return nil }
func DropPrivileges(uid int, gid int) (error, bool) { if err := syscall.Setuid(uid); err != nil { return err, false } if err := syscall.Setgid(gid); err != nil { return err, false } return nil, true }
// SetRuntimeGroup sets group on what to run as func SetRuntimeGroup(groupname string) (err error) { log.Printf("Setting gid to %s", groupname) gstruct, err := user.LookupGroupId(groupname) if err != nil { return } egid, _ := strconv.Atoi(gstruct.Gid) syscall.Setgid(egid) return }
func setuid(u string, g string) (err error) { if len(u) <= 0 { return } uid := -1 gid := -1 for { userent, err := user.Lookup(u) if err != nil { if userent, err = user.LookupId(u); err != nil { log.Println("Unable to find user", u, err) break } } uid, err = strconv.Atoi(userent.Uid) if err != nil { log.Println("Invalid uid:", userent.Uid) } gid, err = strconv.Atoi(userent.Gid) if err != nil { log.Println("Invalid gid:", userent.Gid) } break } if uid < 0 { uid, err = strconv.Atoi(u) if err != nil { log.Println("Invalid uid:", u, err) return } } if gid < 0 { gid, err = strconv.Atoi(g) if err != nil { log.Println("Invalid gid:", g, err) return } } if err = syscall.Setgid(gid); err != nil { log.Println("setgid failed: ", err) } if err = syscall.Setuid(uid); err != nil { log.Println("setuid failed: ", err) } return }
func (s *internalService) DropPrivileges(arg *struct{ R internalDropArg }, result *struct{ R internalDropResult }) error { if rv := syscall.Setgid(arg.R.Gid); rv != nil { result.R.SetgidErrno = uintptr(rv.(syscall.Errno)) } else { result.R.GidDropped = true } if rv := syscall.Setuid(arg.R.Uid); rv != nil { result.R.SetuidErrno = uintptr(rv.(syscall.Errno)) } else { result.R.UidDropped = true } return nil }
func AttachFiles(containerId, fromFile, toDir, rootDir, perm, uid, gid string) error { if containerId == "" { return fmt.Errorf("Please make sure the arguments are not NULL!\n") } permInt, err := strconv.Atoi(perm) if err != nil { return err } // It just need the block device without copying any files // FIXME whether we need to return an error if the target directory is null if toDir == "" { return nil } // Make a new file with the given premission and wirte the source file content in it if _, err := os.Stat(fromFile); err != nil && os.IsNotExist(err) { return err } buf, err := ioutil.ReadFile(fromFile) if err != nil { return err } targetDir := path.Join(rootDir, containerId, "rootfs", toDir) _, err = os.Stat(targetDir) targetFile := targetDir if err != nil && os.IsNotExist(err) { // we need to create a target directory with given premission if err := os.MkdirAll(targetDir, os.FileMode(permInt)); err != nil { return err } targetFile = targetDir + "/" + filepath.Base(fromFile) } else { targetFile = targetDir + "/" + filepath.Base(fromFile) } err = ioutil.WriteFile(targetFile, buf, os.FileMode(permInt)) if err != nil { return err } user_id, _ := strconv.Atoi(uid) err = syscall.Setuid(user_id) if err != nil { return err } group_id, _ := strconv.Atoi(gid) err = syscall.Setgid(group_id) if err != nil { return err } return nil }
func chrootuid(dir, user string) { pw_filename := "/etc/passwd" pwf, err := os.Open(pw_filename) if err != nil { log.Fatalf("%%Can't open %s: %s", pw_filename, err) } pwr := bufio.NewReader(pwf) for { line, err := pwr.ReadString('\n') if err != nil { log.Fatalf("%%Can't find UID for %s: %s", user, err) } pw_row := strings.SplitN(line, ":", 5) if len(pw_row) != 5 { continue } if pw_row[0] == user { uid, err = strconv.Atoi(pw_row[2]) if err != nil { log.Fatalln("%Wrong UID:", err) } gid, err = strconv.Atoi(pw_row[3]) if err != nil { log.Fatalln("%Wrong GID:", err) } break } } err = syscall.Chroot(dir) if err != nil { log.Fatalln("%Chroot error:", err) } err = syscall.Setgid(gid) if err != nil { log.Fatalln("%Setgid error:", err) } err = syscall.Setuid(uid) if err != nil { log.Fatalln("%Setuid error:", err) } err = os.Chdir("/") if err != nil { log.Fatalln("%Can't cd to '/':", err) } }
func MaybeBecomeChildProcess() { lrs := os.Getenv("_RUNSIT_LAUNCH_INFO") if lrs == "" { return } defer os.Exit(2) // should never make it this far, though lr := new(LaunchRequest) d := gob.NewDecoder(base64.NewDecoder(base64.StdEncoding, strings.NewReader(lrs))) err := d.Decode(lr) if err != nil { log.Fatalf("Failed to decode LaunchRequest in child: %v", err) } if lr.NumFiles != 0 { var lim syscall.Rlimit if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &lim); err != nil { log.Fatalf("failed to get NOFILE rlimit: %v", err) } noFile := rlim_t(lr.NumFiles) lim.Cur = noFile lim.Max = noFile if err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, &lim); err != nil { log.Fatalf("failed to set NOFILE rlimit: %v", err) } } if lr.Gid != 0 { if err := syscall.Setgid(lr.Gid); err != nil { log.Fatalf("failed to Setgid(%d): %v", lr.Gid, err) } } if len(lr.Gids) != 0 { if err := syscall.Setgroups(lr.Gids); err != nil { log.Printf("setgroups: %v", err) } } if lr.Uid != 0 { if err := syscall.Setuid(lr.Uid); err != nil { log.Fatalf("failed to Setuid(%d): %v", lr.Uid, err) } } if lr.Path != "" { err = os.Chdir(lr.Dir) if err != nil { log.Fatalf("failed to chdir to %q: %v", lr.Dir, err) } } err = syscall.Exec(lr.Path, lr.Argv, lr.Env) log.Fatalf("failed to exec %q: %v", lr.Path, err) }
func setgid() error { exe, err := exec.LookPath(os.Args[0]) if err != nil { return err } st, err := os.Stat(exe) if err != nil { return err } gid := int(st.Sys().(*syscall.Stat_t).Gid) return syscall.Setgid(gid) }
// Init create pid file, set working dir, setgid and setuid. func Init(userGroup, dir, pidFile string) error { // change working dir if err := os.Chdir(dir); err != nil { return err } // create pid file if err := ioutil.WriteFile(pidFile, []byte(fmt.Sprintf("%d\n", os.Getpid())), 0644); err != nil { return err } // setuid and setgid ug := strings.SplitN(userGroup, " ", 2) usr := defaultUser grp := defaultGroup if len(ug) == 0 { // default user and group (nobody) } else if len(ug) == 1 { usr = ug[0] grp = "" } else if len(ug) == 2 { usr = ug[0] grp = ug[1] } uid := 0 gid := 0 ui, err := user.Lookup(usr) if err != nil { return err } uid, _ = strconv.Atoi(ui.Uid) // group no set if grp == "" { gid, _ = strconv.Atoi(ui.Gid) } else { // use user's group instread // TODO LookupGroup gid, _ = strconv.Atoi(ui.Gid) } if err := syscall.Setgid(gid); err != nil { return err } if err := syscall.Setuid(uid); err != nil { return err } return nil }
func main() { var Hostname, User, DatabaseFile, VoicemailDirectory, HttpPort, SmtpPort string var Limit int flag.StringVar(&Hostname, "host", "localhost", "Hostname or IP to bind to") flag.StringVar(&User, "user", "nobody", "User to drop to after binding") flag.StringVar(&DatabaseFile, "database", "./voicemail.sqlite", "Database file location") flag.StringVar(&VoicemailDirectory, "voicemail", "./mp3/", "Voicemail storage directory") flag.StringVar(&HttpPort, "http-port", "8080", "Port for the HTTP service") flag.StringVar(&SmtpPort, "smtp-port", "2500", "Port for the SMTP service") flag.IntVar(&Limit, "limit", -1, "Only display this many voicemails in the web interface") flag.Parse() smtpListener, err := net.Listen("tcp", Hostname+":"+SmtpPort) if err != nil { logger.Panic(err) } httpListener, err := net.Listen("tcp", Hostname+":"+HttpPort) if err != nil { logger.Panic(err) } u, err := user.Lookup(User) if err != nil { logger.Panic(err) } uid, _ := strconv.Atoi(u.Uid) gid, _ := strconv.Atoi(u.Gid) if err = syscall.Setgid(gid); err != nil { logger.Panic(err) } if err = syscall.Setuid(uid); err != nil { logger.Panic(err) } db := model.OpenDatabase(DatabaseFile, VoicemailDirectory) go mail.Serve(smtpListener, db) web.Serve(httpListener, db, VoicemailDirectory, Limit) }
func main() { exedir := flag.String("dir", "/", "directory to chroot to.") uid := flag.Int("uid", 0, "uid to use.") gid := flag.Int("gid", 0, "gid to use.") binary := flag.String("binary", "", "full path of binary.") flag.Parse() if len(flag.Args()) < 2 { log.Fatal("use: chroot DIR COMMAND [ARG ..]") } args := flag.Args()[1:] dir := flag.Arg(0) en := syscall.Chroot(dir) if en != 0 { log.Fatalln("Chroot error:", os.Errno(en)) } en = syscall.Setgid(*gid) if en != 0 { log.Fatalln("Setgid error:", os.Errno(en)) } en = syscall.Setuid(*uid) if en != 0 { log.Fatalln("Setuid error:", os.Errno(en)) } err := os.Chdir(*exedir) if err != nil { log.Fatalln("Can't cd to", *exedir, err) } bin := *binary if bin == "" { bin = args[0] } en = syscall.Exec(bin, args, os.Environ()) if en != 0 { log.Fatalln("Can't exec", args, os.Errno(en)) } }
func (t *pty) fork(file string, args, env []string, cwd string, cols, rows, uid, gid int) error { var winp = new(C.struct_winsize) winp.ws_col = C.ushort(cols) winp.ws_row = C.ushort(rows) winp.ws_xpixel = 0 winp.ws_ypixel = 0 //fork the pty var master C.int = -1 var name []C.char = make([]C.char, 40) var pid C.int = C.GoForkpty(&master, &name[0], winp) t.fd = int(master) t.pid = int(pid) t.pty = C.GoString(&name[0]) switch t.pid { case -1: return errors.New("forkpty(3) failed") case 0: if cwd != "" { if err := syscall.Chdir(cwd); err != nil { panic("chdir failed") } } if uid != -1 && gid != -1 { if err := syscall.Setgid(gid); err != nil { panic("setgid failed") } if err := syscall.Setuid(uid); err != nil { panic("setuid failed") } } syscall.Exec(file, args, env) panic("exec failed") } return nil }
func main() { // NOTE: Sandbox doesn't work correctly with /more/ than 1 goroutine! runtime.GOMAXPROCS(1) // Open the port, to be used later... log.Printf("Opening port...") l, e := net.Listen("tcp", ":80") if e != nil { log.Fatal(e.Error()) } // Chroot into /jailed os.Chdir("/jailed") e = syscall.Chroot("/jailed") if e != nil { log.Fatal("Failed to chroot: %v", e.Error()) } // Drop group (group must be done first, apparently?) e = syscall.Setgid(9999) if e != nil { log.Fatal("Failed to drop group: %v", e.Error()) } // Drop user e = syscall.Setuid(9999) if e != nil { log.Fatal("Failed to drop user: %v", e.Error()) } // Handle pages http.HandleFunc("/", indexHandler) http.HandleFunc("/nyancat.gif", nyanHandler) http.HandleFunc("/bd8d1dda5442e2888b7633335cd38f39a95db855", badSyscallHandler) // TODO: DELETE ME // Enable seccomp filtering Sandbox() // Begin serving on the previously-opened socket log.Printf("Starting web server.") http.Serve(l, nil) }
// SetupUser changes the groups, gid, and uid for the user inside the container func SetupUser(u string) error { uid, gid, suppGids, err := user.GetUserGroupSupplementary(u, syscall.Getuid(), syscall.Getgid()) if err != nil { return fmt.Errorf("get supplementary groups %s", err) } if err := syscall.Setgroups(suppGids); err != nil { return fmt.Errorf("setgroups %s", err) } if err := syscall.Setgid(gid); err != nil { return fmt.Errorf("setgid %s", err) } if err := syscall.Setuid(uid); err != nil { return fmt.Errorf("setuid %s", err) } return nil }
func (db *DB) readDB(filename string) (r []string, err error) { var fb []byte func() { gid := syscall.Getgid() if setgid() != nil { defer syscall.Setgid(gid) } fb, err = ioutil.ReadFile(filename) }() if err != nil { return } if bytes.Compare(fb[0:8], []byte("\x00mlocate")) == 0 { return db.readMlocateDB(fb) } return }
// Takes care of dropping privileges to the desired user func changeUser(args *execdriver.InitArgs) error { uid, gid, suppGids, err := user.GetUserGroupSupplementary( args.User, syscall.Getuid(), syscall.Getgid(), ) if err != nil { return err } if err := syscall.Setgroups(suppGids); err != nil { return fmt.Errorf("Setgroups failed: %v", err) } if err := syscall.Setgid(gid); err != nil { return fmt.Errorf("Setgid failed: %v", err) } if err := syscall.Setuid(uid); err != nil { return fmt.Errorf("Setuid failed: %v", err) } return nil }
func Secure(uid, gid int) { debug("Enabled.") if syscall.Getuid() != 0 { debug("Not running as sudo.") return } // set group id first as you need to be root to change group debug("Setting GID (group id) to %v", gid) err := syscall.Setgid(gid) if err != nil { debug("Fatal: Failed to set group id: %v", err) debug(" Use -gid parameter to specify the correct group id.") } debug("Setting UID (user id) to %v", gid) err = syscall.Setuid(uid) if err != nil { debug("Fatal: Failed to set user id: %v", err) debug(" Use -uid parameter to specify the correct user id.") } }
func DropPrivileges() error { var err error if !_ConfigMeta.IsDefined("runoptions", "uid") { // not found, no dropping privileges but no err return nil } if !_ConfigMeta.IsDefined("runoptions", "gid") { return MsgError("GID must be specified for dropping privileges") } INFO("Switching to user: %d.%d", _Config.RunOptions.Uid, _Config.RunOptions.Gid) if err = syscall.Setgid(_Config.RunOptions.Gid); err != nil { return MsgError("setgid: %s", err.Error()) } if err = syscall.Setuid(_Config.RunOptions.Uid); err != nil { return MsgError("setuid: %s", err.Error()) } return nil }
func DropPrivileges(username string, groupname string) (err error) { uid, err := GetUidByName(username) if err != nil { return } gid, err := GetGidByName(groupname) if err != nil { return } err = syscall.Setgid(gid) if err != nil { return } log.Printf("Dropped group privileges") err = syscall.Setuid(uid) if err != nil { return } log.Printf("Dropped user privileges") return }
func DropPrivileges(config RunOptions) error { var err error if config.Uid == nil { // not found, no dropping privileges but no err return nil } if config.Gid == nil { return errors.New("GID must be specified for dropping privileges") } logp.Info("Switching to user: %d.%d", config.Uid, config.Gid) if err = syscall.Setgid(*config.Gid); err != nil { return fmt.Errorf("setgid: %s", err.Error()) } if err = syscall.Setuid(*config.Uid); err != nil { return fmt.Errorf("setuid: %s", err.Error()) } return nil }
func Setgid(gid int) error { return syscall.Setgid(gid) }
// Activates the mitigation measurements. func Activate(uid int, gid int, path string) { if !CanActivate() { panic("Cannot activate mitigation measurements!") } // chroot directory err := syscall.Chroot(path) if err != nil { panic(err) } // change directory to new / err = syscall.Chdir("/") if err != nil { panic(err) } // drop all other groups err = syscall.Setgroups([]int{gid}) if err != nil { panic(err) } // verify the empty group list gids, err := syscall.Getgroups() if err != nil { panic("Could not read groups!") } if len(gids) > 1 { panic("Could not drop groups!") } else if len(gids) == 1 { if gids[0] != gid { panic("Could not drop foreign groups!") } } // change group err = syscall.Setgid(gid) if err != nil { panic(err) } // verify the group change ngid := syscall.Getgid() if ngid != gid { panic("Could not change group id!") } // change user err = syscall.Setuid(uid) if err != nil { panic(err) } // verify the user change nuid := syscall.Getuid() if nuid != uid { panic("Could not change user id!") } // now drop all environment variables os.Clearenv() }
func Setgid(gid int) (err error) { return syscall.Setgid(gid) }
func (k *PosixKernel) Setgid(gid int) int { // TODO: doesn't work on Linux syscall.Setgid(gid) return 0 }