Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .debug.env
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ SANDAL_HOST_NET="172.19.0.1/24,fd34:0135:0127::1/64,172.20.0.130/27"
SANDAL_LOG_LEVEL=debug
SANDAL_LIB_DIR="/tmp/sandal/lib"
SANDAL_RUN_DIR="/tmp/sandal/run"
CGO_ENABLED=0
CGO_ENABLED=0
LOOP_DEVICE_PREFIX=/devtmpfs/loop
18 changes: 18 additions & 0 deletions docs/guide/commands/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,24 @@ Benefical for:

---

### `-user string`

: Start container as custom user or user:group configuration.
>
```bash
# chroot to given path
sandal run -rm --lw / -user dnsmasq -- id
uid=100(dnsmasq) gid=101(dnsmasq)
sandal run -rm --lw / -user dnsmasq:wheel -- id
uid=100(dnsmasq) gid=10(wheel)
sandal run -rm --lw / -user 10:nogroup -- id
uid=10(uucp) gid=65533(nogroup)
sandal run -rm --lw / -user 10 -- id
uid=10(uucp) gid=10(wheel)
sandal run -rm --lw / -user adm:10 -- id
uid=3(adm) gid=10(wheel)
```

### `-v value`

: volume mount point
Expand Down
2 changes: 2 additions & 0 deletions pkg/cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ func Run(args []string) error {

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

f.StringVar(&c.User, "user", "", "user or user:group information")

f.Var(&c.RunPrePivot, "rcp", "run command before pivoting")
f.Var(&c.RunPreExec, "rci", "run command before init")

Expand Down
3 changes: 1 addition & 2 deletions pkg/container/config/definations.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ type Config struct {
ContPid int
TmpSize uint

ProjectDir string

ChangeDir string
RootfsDir string

Expand All @@ -34,6 +32,7 @@ type Config struct {
Background bool
Startup bool
NS namespace.Namespaces
User string
Devtmpfs string
Resolv string
Hosts string
Expand Down
5 changes: 5 additions & 0 deletions pkg/container/cruntime/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@ func ContainerInitProc() {
os.Chdir(c.Dir)
}

err = switchUser(c.User)
if err != nil {
return err
}

// Jump to real process
if err := unix.Exec(execPath, append([]string{c.ContArgs[0]}, c.ContArgs[1:]...), os.Environ()); err != nil {
return fmt.Errorf("unable to exec %s: %s", c.ContArgs[0], err)
Expand Down
54 changes: 54 additions & 0 deletions pkg/container/cruntime/user.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package cruntime

import (
os_user "os/user"
"strconv"
"strings"
"syscall"
)

func switchUser(user string) (err error) {

if user == "" {
return nil
}

var (
uid int
gid int
)
credential := strings.Split(user, ":")

if uid, err = strconv.Atoi(credential[0]); err != nil {
user, err := os_user.Lookup(credential[0])
if err == nil {
uid, _ = strconv.Atoi(user.Uid)
// if usergroup is not presented, try gid info from user information

if len(credential) == 1 && user.Gid != "" {
credential = append(credential, user.Gid)
}
} else {
return err
}
}

// if usergroup is not presented, set group name identical to username
if len(credential) == 1 {
credential = append(credential, credential[0])
}

if gid, err = strconv.Atoi(credential[1]); err != nil {
group, err := os_user.LookupGroup(credential[1])
if err == nil {
gid, _ = strconv.Atoi(group.Gid)
}
}

err = syscall.Setgid(gid)
if err != nil {
return err
}
err = syscall.Setuid(uid)
return
}
Loading