Skip to content

Commit f54103e

Browse files
committed
argument to change uid/gid
1 parent 3dfa6d0 commit f54103e

File tree

3 files changed

+92
-0
lines changed

3 files changed

+92
-0
lines changed

cmd/yggdrasil/chuser_other.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//go:build !aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris
2+
// +build !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd,!solaris
3+
4+
package main
5+
6+
import "errors"
7+
8+
func chuser(user string) error {
9+
return errors.New("setting uid/gid is not supported on this platform")
10+
}

cmd/yggdrasil/chuser_unix.go

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
2+
// +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
3+
4+
package main
5+
6+
import (
7+
"fmt"
8+
osuser "os/user"
9+
"strconv"
10+
"strings"
11+
"syscall"
12+
)
13+
14+
func chuser(user string) error {
15+
group := ""
16+
if i := strings.IndexByte(user, ':'); i >= 0 {
17+
user, group = user[:i], user[i+1:]
18+
}
19+
20+
u := (*osuser.User)(nil)
21+
g := (*osuser.Group)(nil)
22+
23+
if user != "" {
24+
if _, err := strconv.ParseUint(user, 10, 32); err == nil {
25+
u, err = osuser.LookupId(user)
26+
if err != nil {
27+
return fmt.Errorf("failed to lookup user by id %q: %v", user, err)
28+
}
29+
} else {
30+
u, err = osuser.Lookup(user)
31+
if err != nil {
32+
return fmt.Errorf("failed to lookup user by name %q: %v", user, err)
33+
}
34+
}
35+
}
36+
if group != "" {
37+
if _, err := strconv.ParseUint(group, 10, 32); err == nil {
38+
g, err = osuser.LookupGroupId(group)
39+
if err != nil {
40+
return fmt.Errorf("failed to lookup group by id %q: %v", user, err)
41+
}
42+
} else {
43+
g, err = osuser.LookupGroup(group)
44+
if err != nil {
45+
return fmt.Errorf("failed to lookup group by name %q: %v", user, err)
46+
}
47+
}
48+
}
49+
50+
if g != nil {
51+
gid, _ := strconv.ParseUint(g.Gid, 10, 32)
52+
err := syscall.Setgid(int(gid))
53+
if err != nil {
54+
return fmt.Errorf("failed to setgid %d: %v", gid, err)
55+
}
56+
} else if u != nil {
57+
gid, _ := strconv.ParseUint(u.Gid, 10, 32)
58+
err := syscall.Setgid(int(gid))
59+
if err != nil {
60+
return fmt.Errorf("failed to setgid %d: %v", gid, err)
61+
}
62+
}
63+
64+
if u != nil {
65+
uid, _ := strconv.ParseUint(u.Uid, 10, 32)
66+
err := syscall.Setuid(int(uid))
67+
if err != nil {
68+
return fmt.Errorf("failed to setuid %d: %v", uid, err)
69+
}
70+
}
71+
72+
return nil
73+
}

cmd/yggdrasil/main.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ func main() {
5252
getsnet := flag.Bool("subnet", false, "use in combination with either -useconf or -useconffile, outputs your IPv6 subnet")
5353
getpkey := flag.Bool("publickey", false, "use in combination with either -useconf or -useconffile, outputs your public key")
5454
loglevel := flag.String("loglevel", "info", "loglevel to enable")
55+
chuserto := flag.String("user", "", "user (and, optionally, group) to set UID/GID to")
5556
flag.Parse()
5657

5758
// Catch interrupts from the operating system to exit gracefully.
@@ -272,6 +273,14 @@ func main() {
272273
}
273274
}
274275

276+
// Change user if requested
277+
if *chuserto != "" {
278+
err = chuser(*chuserto)
279+
if err != nil {
280+
panic(err)
281+
}
282+
}
283+
275284
// Block until we are told to shut down.
276285
<-ctx.Done()
277286

0 commit comments

Comments
 (0)