Example #1
0
func main() {
	flagUsername := flag.String("username", "nobody", "username for the unprivileged child")

	isChild, r, w, _, err := privsep.MaybeBecomeChild()
	if err != nil {
		log.Fatalf("MaybeBecomeChild failed: %s", err)
	}

	who := "parent"
	if isChild {
		who = "child"
	}
	log.Printf("%s: pid=%d uid=%d euid=%d gid=%d egid=%d",
		who, os.Getpid(), os.Getuid(), os.Geteuid(), os.Getgid(), os.Getegid())

	if isChild {
		child(r, w)
		return
	}

	if os.Getuid() != 0 {
		log.Print("Warning: this example only works when run as the root user")
	}

	_, r, w, err = privsep.CreateChild(*flagUsername, os.Args[0], nil, nil)
	if err != nil {
		log.Fatalf("CreateChild failed: %s", err)
	}
	parent(r, w)
}
Example #2
0
func main() {
	flagUsername := flag.String("username", "nobody", "username for the unprivileged child")

	isChild, _, _, files, err := privsep.MaybeBecomeChild()
	if err != nil {
		log.Fatalf("MaybeBecomeChild failed: %s", err)
	}

	who := "parent"
	if isChild {
		who = "child"
	}
	log.Printf("%s: pid=%d uid=%d euid=%d gid=%d egid=%d",
		who, os.Getpid(), os.Getuid(), os.Geteuid(), os.Getgid(), os.Getegid())

	if isChild {
		if len(files) < 1 {
			log.Fatalf("no extra files: %v", files)
		}
		l, err := net.FileListener(files[0])
		if err != nil {
			log.Fatalf("FileListener: %s", err)
		}
		child(l)
		return
	}

	if os.Getuid() != 0 {
		log.Print("Warning: this example only works when run as the root user")
	}

	addr := "localhost:1111"
	laddr, err := net.ResolveTCPAddr("tcp", addr)
	if err != nil {
		log.Fatalf("resolve %s: %s", addr, err)
	}

	l, err := net.ListenTCP("tcp", laddr)
	if err != nil {
		log.Fatalf("listen %s: %s", laddr, err)
	}

	sock, err := l.File()
	if err != nil {
		log.Fatalf("fd: %s", err)
	}

	proc, _, _, err := privsep.CreateChild(*flagUsername, os.Args[0], nil, []*os.File{sock})
	if err != nil {
		log.Fatalf("CreateChild failed: %s", err)
	}

	sock.Close()

	// tidy up so child doesn't run forever
	defer proc.Kill()

	parent(laddr)
}
Example #3
0
func main() {
	var (
		flagUsername = flag.String("username", "nobody", "username for the unprivileged child")
		flagChildren = flag.Int("children", 32, "exit code")
		flagPause    = flag.Duration("pause", 10*time.Second, "time for children to sleep")
		flagTimeout  = flag.Duration("timeout", 5*time.Second, "time for parent to wait")
	)

	isChild, _, _, _, err := privsep.MaybeBecomeChild()
	if err != nil {
		log.Fatalf("MaybeBecomeChild failed: %s", err)
	}

	if isChild {
		rand.Seed(int64(time.Now().Nanosecond()))
		sleep := time.Duration(rand.Float64() * float64(*flagPause))
		code := rand.Intn(8)
		log.Printf("[%d] sleep(%.1fs), exit(%d)", os.Getpid(), sleep.Seconds(), code)
		time.Sleep(sleep)
		os.Exit(code)
		return
	}

	if os.Getuid() != 0 {
		log.Fatal("Error: this example only works when run as the root user")
	}

	var procsMu sync.Mutex
	procs := make(map[interface{}]*os.Process)

	var wg sync.WaitGroup
	wg.Add(*flagChildren)
	for i := 0; i < *flagChildren; i++ {
		proc, _, _, err := privsep.CreateChild(*flagUsername, os.Args[0], nil, nil)
		if err != nil {
			log.Fatalf("CreateChild failed: %s", err)
		}

		procsMu.Lock()
		procs[proc] = proc
		procsMu.Unlock()

		go func() {
			defer wg.Done()
			status, err := proc.Wait()
			if err != nil {
				log.Printf("child %d errored: %s", proc.Pid, err)
			}

			procsMu.Lock()
			delete(procs, proc)
			procsMu.Unlock()

			// detailed status information is available by casting to the
			// appropriate type for the platform
			if s, ok := status.Sys().(syscall.WaitStatus); ok {
				log.Printf("child %d exited with code %d", proc.Pid, s.ExitStatus())
			}
		}()
	}

	go func() {
		time.Sleep(*flagTimeout)
		log.Print("Parent timed out, killing children")
		procsMu.Lock()
		defer procsMu.Unlock()
		for _, proc := range procs {
			proc.Kill()
		}
	}()

	wg.Wait()
}