Skip to content

Commit 13c01b6

Browse files
authored
Merge pull request #48 from ahmetozer/feat/uid-gid
Feat/uid gid
2 parents f7f5e4a + d637b2a commit 13c01b6

File tree

5 files changed

+94
-30
lines changed

5 files changed

+94
-30
lines changed

pkg/cmd/exec.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,15 @@ func ExecOnContainer(args []string) error {
2323
EnvAll bool
2424
PassEnv wrapper.StringFlags
2525
Dir string
26+
User string
2627
contName string
2728
)
2829

2930
f.BoolVar(&help, "help", false, "show this help message")
3031
f.BoolVar(&EnvAll, "env-all", false, "send all enviroment variables to container")
3132
f.StringVar(&Dir, "dir", "", "working directory")
33+
f.StringVar(&User, "user", "", "work user")
34+
3235
f.Var(&PassEnv, "env-pass", "pass only requested enviroment variables to container")
3336

3437
// Allocate variable locations
@@ -90,7 +93,10 @@ func ExecOnContainer(args []string) error {
9093
}
9194
}
9295

93-
exitCode, err = cruntime.Exec(childArgs, "")
96+
if User == "" {
97+
User = c.User
98+
}
99+
exitCode, err = cruntime.Exec(childArgs, "", User)
94100
if err != nil && strings.Contains(err.Error(), "exit status") {
95101
err = nil
96102
}

pkg/container/cruntime/exec.go

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@ import (
1212
"golang.org/x/sys/unix"
1313
)
1414

15-
func runCommands(c []string, chroot string) {
15+
func runCommands(c []string, chroot string, user string) {
1616
for _, command := range c {
17-
Exec(cmdline.Parse(command), chroot)
17+
Exec(cmdline.Parse(command), chroot, user)
1818
}
1919
}
2020

2121
// Execute under container chroot
22-
func Exec(c []string, chroot string) (exitCode int, err error) {
22+
func Exec(c []string, chroot string, user string) (exitCode int, err error) {
2323
var (
2424
cmd *exec.Cmd
2525
mainRoot *os.File
@@ -70,13 +70,24 @@ func Exec(c []string, chroot string) (exitCode int, err error) {
7070
// Cloneflags: unix.CLONE_NEWUTS,
7171
}
7272

73-
if chroot != "" {
74-
cmd.SysProcAttr = &unix.SysProcAttr{
75-
// Cloneflags: unix.CLONE_NEWUTS,
76-
Chroot: chroot,
73+
if user != "" {
74+
u, err2 := getUser(user)
75+
if err2 != nil {
76+
err = err2
77+
return
78+
}
79+
80+
cmd.SysProcAttr.Credential = u.Credential
81+
if u.User != nil && u.User.HomeDir != "" {
82+
cmd.Dir = u.User.HomeDir
83+
cmd.Env = append([]string{"HOME=" + u.User.HomeDir}, cmd.Env...)
7784
}
7885
}
7986

87+
if chroot != "" {
88+
cmd.SysProcAttr.Chroot = chroot
89+
}
90+
8091
err = cmd.Run()
8192

8293
if err != nil && err.Error() == "waitid: no child processes" {

pkg/container/cruntime/init.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,10 @@ func ContainerInitProc() {
110110
if err != nil {
111111
return err
112112
}
113-
runCommands(c.RunPrePivot, "/.old_root/")
113+
// do not execute pre commands as defined user
114+
runCommands(c.RunPrePivot, "/.old_root/", "")
114115
purgeOldRoot(c)
115-
runCommands(c.RunPreExec, "")
116+
runCommands(c.RunPreExec, "", "")
116117

117118
if len(c.ContArgs) == 0 {
118119
return fmt.Errorf("no container arg providen, malformed container file")
@@ -127,7 +128,11 @@ func ContainerInitProc() {
127128
os.Chdir(c.Dir)
128129
}
129130

130-
err = switchUser(c.User)
131+
user, err := getUser(c.User)
132+
if err != nil {
133+
return err
134+
}
135+
err = switchUser(user)
131136
if err != nil {
132137
return err
133138
}

pkg/container/cruntime/namespace/allocate.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
package namespace
22

33
func (ns *NamespaceConf) defaults() {
4+
5+
if ns.UserValue == nil {
6+
temp := ""
7+
ns.UserValue = &temp
8+
}
9+
410
switch *ns.UserValue {
511
case "host":
612
ns.IsHost = true

pkg/container/cruntime/user.go

Lines changed: 55 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,90 @@
11
package cruntime
22

33
import (
4+
"os"
45
os_user "os/user"
56
"strconv"
67
"strings"
78
"syscall"
89
)
910

10-
func switchUser(user string) (err error) {
11+
type User struct {
12+
Credential *syscall.Credential
13+
User *os_user.User
14+
}
1115

12-
if user == "" {
13-
return nil
16+
func getUser(ug string) (User User, err error) {
17+
if ug == "" {
18+
return
1419
}
1520

1621
var (
17-
uid int
18-
gid int
22+
uid uint64
23+
gid uint64
1924
)
20-
credential := strings.Split(user, ":")
25+
user_group := strings.Split(ug, ":")
2126

22-
if uid, err = strconv.Atoi(credential[0]); err != nil {
23-
user, err := os_user.Lookup(credential[0])
27+
if uid, err = strconv.ParseUint(user_group[0], 10, 32); err != nil {
28+
User.User, err = os_user.Lookup(user_group[0])
2429
if err == nil {
25-
uid, _ = strconv.Atoi(user.Uid)
30+
uid, _ = strconv.ParseUint(User.User.Uid, 10, 32)
2631
// if usergroup is not presented, try gid info from user information
2732

28-
if len(credential) == 1 && user.Gid != "" {
29-
credential = append(credential, user.Gid)
33+
if len(user_group) == 1 && User.User.Gid != "" {
34+
user_group = append(user_group, User.User.Gid)
3035
}
3136
} else {
32-
return err
37+
return
3338
}
39+
3440
}
3541

3642
// if usergroup is not presented, set group name identical to username
37-
if len(credential) == 1 {
38-
credential = append(credential, credential[0])
43+
if len(user_group) == 1 {
44+
user_group = append(user_group, user_group[0])
3945
}
4046

41-
if gid, err = strconv.Atoi(credential[1]); err != nil {
42-
group, err := os_user.LookupGroup(credential[1])
47+
if gid, err = strconv.ParseUint(user_group[1], 10, 32); err != nil {
48+
group, err := os_user.LookupGroup(user_group[1])
4349
if err == nil {
44-
gid, _ = strconv.Atoi(group.Gid)
50+
gid, _ = strconv.ParseUint(group.Gid, 10, 32)
4551
}
4652
}
4753

48-
err = syscall.Setgid(gid)
54+
User.Credential = &syscall.Credential{}
55+
User.Credential.Uid = uint32(uid)
56+
User.Credential.Gid = uint32(gid)
57+
58+
return
59+
}
60+
61+
func switchUser(user User) error {
62+
err := switchCredential(user.Credential)
4963
if err != nil {
5064
return err
5165
}
52-
err = syscall.Setuid(uid)
66+
67+
if user.User == nil {
68+
return nil
69+
}
70+
71+
if user.User.HomeDir != "" {
72+
os.Chdir(user.User.HomeDir)
73+
}
74+
75+
return nil
76+
}
77+
78+
func switchCredential(Credential *syscall.Credential) (err error) {
79+
if Credential == nil {
80+
return
81+
}
82+
err = syscall.Setgid(int(Credential.Gid))
83+
if err != nil {
84+
return
85+
}
86+
87+
err = syscall.Setuid(int(Credential.Uid))
88+
5389
return
5490
}

0 commit comments

Comments
 (0)