-
Notifications
You must be signed in to change notification settings - Fork 1
/
user.go
91 lines (81 loc) · 2.23 KB
/
user.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
package user
import (
"crypto/sha1"
"encoding/binary"
"fmt"
"log"
"os/exec"
osuser "os/user"
"path/filepath"
"strings"
)
// User represents a mirrored user between AWS IAM and the local system
type User struct {
Groups []*Group
Username string
}
// Ensure ensure a user is correctly configured on the system
func (u *User) Ensure(sandboxed bool, additionalGroups []string) error {
return ensureUser(u.Username, sandboxed, additionalGroups)
}
// HomeDir returns the user's home directory
func (u User) HomeDir() string {
return filepath.Join("/home", u.Username)
}
// Remove removes an user from the system
func (u *User) Remove() error {
return exec.Command("/usr/sbin/userdel", "--remove", u.Username).Run()
}
// Uid returns the user unique id
func (u User) Uid() uint16 {
return uidFromString(u.Username)
}
// ensureUser add an user in the system idempotently
func ensureUser(username string, sandboxed bool, additionalGroups []string) error {
if userExists(username) {
return nil
}
if err := userAdd(username, sandboxed, additionalGroups); err != nil {
return fmt.Errorf("failed to create user: %q", err)
}
log.Printf("Created user %q", username)
return nil
}
// userAdd adds a user to the system with toolbox as the default shell
func userAdd(username string, sandboxed bool, additionalGroups []string) error {
shell := "/opt/bin/bastrd-toolbox"
if !sandboxed {
shell = "/bin/bash"
}
uid := fmt.Sprintf("%d", uidFromString(username))
cmd := exec.Command(
"/usr/sbin/useradd",
"-m",
"-u", uid,
"-U",
"-G", strings.Join(additionalGroups, ","),
"-p", "*", // disable password
"-s", shell,
"-c", "bastrd managed user",
username,
)
err := cmd.Run()
if err != nil {
out, _ := cmd.Output()
log.Printf("call to useradd %q failed: %q %q", username, err, out)
return fmt.Errorf("call to useradd %q failed: %q", username, err)
}
return nil
}
// userExists checks if the user already exists in the system
func userExists(username string) bool {
_, err := osuser.Lookup(username)
return err == nil
}
// uidFromString Converts an string into an uid
func uidFromString(awsID string) uint16 {
sha := sha1.Sum([]byte(awsID))
last2 := sha[len(sha)-2:]
n := binary.LittleEndian.Uint16(last2)
return 2000 + (n / 2)
}