Skip to content

Commit f7f5e4a

Browse files
authored
Merge pull request #47 from ahmetozer/feat/uid-gid
feat: add user support
2 parents f047776 + 5ab3c1b commit f7f5e4a

File tree

6 files changed

+82
-3
lines changed

6 files changed

+82
-3
lines changed

.debug.env

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ SANDAL_HOST_NET="172.19.0.1/24,fd34:0135:0127::1/64,172.20.0.130/27"
33
SANDAL_LOG_LEVEL=debug
44
SANDAL_LIB_DIR="/tmp/sandal/lib"
55
SANDAL_RUN_DIR="/tmp/sandal/run"
6-
CGO_ENABLED=0
6+
CGO_ENABLED=0
7+
LOOP_DEVICE_PREFIX=/devtmpfs/loop

docs/guide/commands/index.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,24 @@ Benefical for:
270270

271271
---
272272

273+
### `-user string`
274+
275+
: Start container as custom user or user:group configuration.
276+
>
277+
```bash
278+
# chroot to given path
279+
sandal run -rm --lw / -user dnsmasq -- id
280+
uid=100(dnsmasq) gid=101(dnsmasq)
281+
sandal run -rm --lw / -user dnsmasq:wheel -- id
282+
uid=100(dnsmasq) gid=10(wheel)
283+
sandal run -rm --lw / -user 10:nogroup -- id
284+
uid=10(uucp) gid=65533(nogroup)
285+
sandal run -rm --lw / -user 10 -- id
286+
uid=10(uucp) gid=10(wheel)
287+
sandal run -rm --lw / -user adm:10 -- id
288+
uid=3(adm) gid=10(wheel)
289+
```
290+
273291
### `-v value`
274292

275293
: volume mount point

pkg/cmd/run.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ func Run(args []string) error {
6969

7070
f.StringVar(&c.Devtmpfs, "devtmpfs", "", "mount point of devtmpfs")
7171

72+
f.StringVar(&c.User, "user", "", "user or user:group information")
73+
7274
f.Var(&c.RunPrePivot, "rcp", "run command before pivoting")
7375
f.Var(&c.RunPreExec, "rci", "run command before init")
7476

pkg/container/config/definations.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@ type Config struct {
2323
ContPid int
2424
TmpSize uint
2525

26-
ProjectDir string
27-
2826
ChangeDir string
2927
RootfsDir string
3028

@@ -34,6 +32,7 @@ type Config struct {
3432
Background bool
3533
Startup bool
3634
NS namespace.Namespaces
35+
User string
3736
Devtmpfs string
3837
Resolv string
3938
Hosts string

pkg/container/cruntime/init.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,11 @@ func ContainerInitProc() {
127127
os.Chdir(c.Dir)
128128
}
129129

130+
err = switchUser(c.User)
131+
if err != nil {
132+
return err
133+
}
134+
130135
// Jump to real process
131136
if err := unix.Exec(execPath, append([]string{c.ContArgs[0]}, c.ContArgs[1:]...), os.Environ()); err != nil {
132137
return fmt.Errorf("unable to exec %s: %s", c.ContArgs[0], err)

pkg/container/cruntime/user.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package cruntime
2+
3+
import (
4+
os_user "os/user"
5+
"strconv"
6+
"strings"
7+
"syscall"
8+
)
9+
10+
func switchUser(user string) (err error) {
11+
12+
if user == "" {
13+
return nil
14+
}
15+
16+
var (
17+
uid int
18+
gid int
19+
)
20+
credential := strings.Split(user, ":")
21+
22+
if uid, err = strconv.Atoi(credential[0]); err != nil {
23+
user, err := os_user.Lookup(credential[0])
24+
if err == nil {
25+
uid, _ = strconv.Atoi(user.Uid)
26+
// if usergroup is not presented, try gid info from user information
27+
28+
if len(credential) == 1 && user.Gid != "" {
29+
credential = append(credential, user.Gid)
30+
}
31+
} else {
32+
return err
33+
}
34+
}
35+
36+
// if usergroup is not presented, set group name identical to username
37+
if len(credential) == 1 {
38+
credential = append(credential, credential[0])
39+
}
40+
41+
if gid, err = strconv.Atoi(credential[1]); err != nil {
42+
group, err := os_user.LookupGroup(credential[1])
43+
if err == nil {
44+
gid, _ = strconv.Atoi(group.Gid)
45+
}
46+
}
47+
48+
err = syscall.Setgid(gid)
49+
if err != nil {
50+
return err
51+
}
52+
err = syscall.Setuid(uid)
53+
return
54+
}

0 commit comments

Comments
 (0)