Skip to content

Commit 424cf72

Browse files
committed
argument to change uid/gid
1 parent 1420ea5 commit 424cf72

File tree

3 files changed

+94
-0
lines changed

3 files changed

+94
-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: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ type yggArgs struct {
153153
useconffile string
154154
logto string
155155
loglevel string
156+
chuser string
156157
}
157158

158159
func getArgs() yggArgs {
@@ -167,6 +168,7 @@ func getArgs() yggArgs {
167168
getaddr := flag.Bool("address", false, "returns the IPv6 address as derived from the supplied configuration")
168169
getsnet := flag.Bool("subnet", false, "returns the IPv6 subnet as derived from the supplied configuration")
169170
loglevel := flag.String("loglevel", "info", "loglevel to enable")
171+
chuser := flag.String("user", "", "user (and, optionally, group) to set UID/GID to")
170172
flag.Parse()
171173
return yggArgs{
172174
genconf: *genconf,
@@ -180,6 +182,7 @@ func getArgs() yggArgs {
180182
getaddr: *getaddr,
181183
getsnet: *getsnet,
182184
loglevel: *loglevel,
185+
chuser: *chuser,
183186
}
184187
}
185188

@@ -369,6 +372,14 @@ func run(args yggArgs, ctx context.Context) {
369372
}
370373
}
371374

375+
// Change user if requested
376+
if args.chuser != "" {
377+
err = chuser(args.chuser)
378+
if err != nil {
379+
panic(err)
380+
}
381+
}
382+
372383
// Make some nice output that tells us what our IPv6 address and subnet are.
373384
// This is just logged to stdout for the user.
374385
address := n.core.Address()

0 commit comments

Comments
 (0)