|
18 | 18 | package userutils
|
19 | 19 |
|
20 | 20 | import (
|
| 21 | + "fmt" |
21 | 22 | "log"
|
22 | 23 | "os"
|
23 |
| - "os/exec" |
24 |
| - gouser "os/user" |
25 |
| - "strconv" |
| 24 | + "path/filepath" |
26 | 25 | "syscall"
|
27 | 26 |
|
28 | 27 | "github.com/opencontainers/runc/libcontainer/user"
|
29 | 28 | "golang.org/x/sys/unix"
|
30 | 29 | )
|
31 | 30 |
|
32 |
| -var defaultUser = "aoc" |
| 31 | +var aocUserName = "aoc" |
33 | 32 | var defaultInstallPath = "/opt/aws/aws-otel-collector/"
|
34 | 33 |
|
| 34 | +type ChownFunc func(name string, uid, gid int) error |
| 35 | + |
| 36 | +var chown ChownFunc = os.Chown |
| 37 | + |
35 | 38 | // switchUser swithes the current process to new user
|
36 | 39 | func switchUser(execUser *user.ExecUser) error {
|
37 | 40 | if err := unix.Setgroups(execUser.Sgids); err != nil {
|
@@ -76,73 +79,84 @@ func getRunAsExecUser(runasuser string) (*user.ExecUser, error) {
|
76 | 79 | // ChangeUser allow customers to run the collector in selected user
|
77 | 80 | // by default it ran as 'aoc' user but can be set by environment variable
|
78 | 81 | func ChangeUser() (string, error) {
|
79 |
| - runAsUser := getCustomUser() |
80 |
| - log.Printf("I! Detected runAsUser: %v", runAsUser) |
81 | 82 |
|
82 |
| - _, err := user.LookupUser(runAsUser) |
| 83 | + _, err := user.LookupUser(aocUserName) |
83 | 84 | if err != nil {
|
84 |
| - log.Printf("E! User %s does not exist: %v", runAsUser, err) |
| 85 | + log.Printf("E! User %s does not exist: %v", aocUserName, err) |
85 | 86 | return "root", err
|
86 | 87 | }
|
87 | 88 |
|
88 |
| - if runAsUser == "root" { |
89 |
| - return "root", nil |
90 |
| - } |
91 |
| - |
92 |
| - execUser, err := getRunAsExecUser(runAsUser) |
| 89 | + execUser, err := getRunAsExecUser(aocUserName) |
93 | 90 | if err != nil {
|
94 | 91 | log.Printf("E! Failed to getRunAsExecUser: %v", err)
|
95 |
| - return runAsUser, err |
| 92 | + return aocUserName, err |
96 | 93 | }
|
97 | 94 |
|
98 |
| - changeFileOwner(runAsUser, execUser.Gid) |
| 95 | + changeFileOwner(execUser.Uid, execUser.Gid) |
99 | 96 |
|
100 | 97 | if err := switchUser(execUser); err != nil {
|
101 |
| - log.Printf("E! failed switching to %q: %v", runAsUser, err) |
102 |
| - return runAsUser, err |
| 98 | + log.Printf("E! failed switching to %q: %v", aocUserName, err) |
| 99 | + return aocUserName, err |
103 | 100 | }
|
104 | 101 |
|
105 |
| - return runAsUser, nil |
| 102 | + return aocUserName, nil |
106 | 103 | }
|
107 | 104 |
|
108 | 105 | // changeFileOwner changes the folder to new user as owner
|
109 |
| -func changeFileOwner(runAsUser string, groupId int) { |
110 |
| - group, err := gouser.LookupGroupId(strconv.Itoa(groupId)) |
111 |
| - owner := runAsUser |
112 |
| - if err == nil { |
113 |
| - owner = owner + ":" + group.Name |
114 |
| - } else { |
115 |
| - log.Printf("I! Failed to get the group name: %v, it will just change the user, but not group.", err) |
116 |
| - } |
117 |
| - log.Printf("I! Change ownership to %v", owner) |
118 |
| - |
119 |
| - chowncmd := exec.Command("chown", "-R", "-L", owner, getInstallPath()+"logs") |
120 |
| - stdoutStderr, err := chowncmd.CombinedOutput() |
121 |
| - if err != nil { |
122 |
| - log.Printf("E! Change ownership of %slogs: %s %v", getInstallPath(), stdoutStderr, err) |
| 106 | +func changeFileOwner(uid int, gid int) { |
| 107 | + if err := chownRecursive(uid, gid, filepath.Join(getInstallPath(), "logs")); err != nil { |
| 108 | + log.Printf("E! Change ownership of %slogs: %v", getInstallPath(), err) |
123 | 109 | }
|
124 | 110 |
|
125 |
| - chowncmd = exec.Command("chown", "-R", "-L", owner, getInstallPath()+"etc") |
126 |
| - stdoutStderr, err = chowncmd.CombinedOutput() |
127 |
| - if err != nil { |
128 |
| - log.Printf("E! Change ownership of %setc: %s %v", getInstallPath(), stdoutStderr, err) |
| 111 | + if err := chownRecursive(uid, gid, filepath.Join(getInstallPath(), "etc")); err != nil { |
| 112 | + log.Printf("E! Change ownership of %setc: %v", getInstallPath(), err) |
129 | 113 | }
|
130 | 114 |
|
131 |
| - chowncmd = exec.Command("chown", "-R", "-L", owner, getInstallPath()+"var") |
132 |
| - stdoutStderr, err = chowncmd.CombinedOutput() |
133 |
| - if err != nil { |
134 |
| - log.Printf("E! Change ownership of %svar: %s %v", getInstallPath(), stdoutStderr, err) |
| 115 | + if err := chownRecursive(uid, gid, filepath.Join(getInstallPath(), "var")); err != nil { |
| 116 | + log.Printf("E! Change ownership of %svar: %v", getInstallPath(), err) |
135 | 117 | }
|
136 |
| -} |
137 | 118 |
|
138 |
| -// getCustomUser allows to override the default user |
139 |
| -func getCustomUser() string { |
140 |
| - if user, ok := os.LookupEnv("AOT_RUN_USER"); ok { |
141 |
| - defaultUser = user |
142 |
| - } |
143 |
| - return defaultUser |
| 119 | + log.Printf("I! Change ownership to %v:%v", uid, gid) |
144 | 120 | }
|
145 | 121 |
|
146 | 122 | func getInstallPath() string {
|
147 | 123 | return defaultInstallPath
|
148 | 124 | }
|
| 125 | + |
| 126 | +func chownRecursive(uid, gid int, dir string) error { |
| 127 | + |
| 128 | + err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { |
| 129 | + if err != nil { |
| 130 | + return err |
| 131 | + } |
| 132 | + |
| 133 | + fmode := info.Mode() |
| 134 | + if fmode.IsRegular() { |
| 135 | + if fmode&os.ModeSetuid != 0 || fmode&os.ModeSetgid != 0 { |
| 136 | + return nil |
| 137 | + } |
| 138 | + |
| 139 | + if fmode.Perm()&0111 != 0 { |
| 140 | + return nil |
| 141 | + } |
| 142 | + |
| 143 | + if fmode.Perm()&0002 != 0 { |
| 144 | + return nil |
| 145 | + } |
| 146 | + } |
| 147 | + |
| 148 | + if fmode&os.ModeSymlink != 0 { |
| 149 | + return nil |
| 150 | + } |
| 151 | + |
| 152 | + if err := chown(path, uid, gid); err != nil { |
| 153 | + return err |
| 154 | + } |
| 155 | + return nil |
| 156 | + }) |
| 157 | + |
| 158 | + if err != nil { |
| 159 | + return fmt.Errorf("error change owner of dir %s to %v:%v due to error: %w", dir, uid, gid, err) |
| 160 | + } |
| 161 | + return nil |
| 162 | +} |
0 commit comments