From f5fd9f14785d3ebe73fd180df4832dff05af9c28 Mon Sep 17 00:00:00 2001 From: Robert Parker Date: Mon, 3 Sep 2018 14:04:49 +0100 Subject: [PATCH] Add container suplimentary groups support --- cmd/runmqserver/main.go | 7 +++ cmd/runmqserver/mqconfig.go | 20 ------- cmd/runmqserver/user.go | 101 ++++++++++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+), 20 deletions(-) create mode 100644 cmd/runmqserver/user.go diff --git a/cmd/runmqserver/main.go b/cmd/runmqserver/main.go index 3c100a2b..e38a0a8a 100644 --- a/cmd/runmqserver/main.go +++ b/cmd/runmqserver/main.go @@ -64,6 +64,13 @@ func doMain() error { logTermination(err) return err } + + err = verifyCurrentUser() + if err != nil { + logTermination(err) + return err + } + err = createVolume("/mnt/mqm") if err != nil { logTermination(err) diff --git a/cmd/runmqserver/mqconfig.go b/cmd/runmqserver/mqconfig.go index a653ce14..da8ed2d7 100644 --- a/cmd/runmqserver/mqconfig.go +++ b/cmd/runmqserver/mqconfig.go @@ -18,7 +18,6 @@ package main import ( "fmt" "io/ioutil" - "os/user" "runtime" "strings" @@ -52,25 +51,6 @@ func logBaseImage() error { return nil } -func logUser() { - u, err := user.Current() - if err == nil { - g, err := u.GroupIds() - if err != nil { - log.Printf("Running as user ID %v (%v) with primary group %v", u.Uid, u.Name, u.Gid) - } else { - // Look for the primary group in the list of group IDs - for i, v := range g { - if v == u.Gid { - // Remove the element from the slice - g = append(g[:i], g[i+1:]...) - } - } - log.Printf("Running as user ID %v (%v) with primary group %v, and supplemental groups %v", u.Uid, u.Name, u.Gid, strings.Join(g, ",")) - } - } -} - // logCapabilities logs the Linux capabilities (e.g. setuid, setgid). See https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities func logCapabilities() error { caps, err := container.Capabilities() diff --git a/cmd/runmqserver/user.go b/cmd/runmqserver/user.go new file mode 100644 index 00000000..521244dd --- /dev/null +++ b/cmd/runmqserver/user.go @@ -0,0 +1,101 @@ +/* +© Copyright IBM Corporation 2018 + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package main + +import ( + "fmt" + "os/user" + "strings" + + "github.com/ibm-messaging/mq-container/internal/command" +) + +const groupName string = "suplgroup" + +func verifyCurrentUser() error { + log.Debug("Verifying current user information") + curUser, err := user.Current() + if err != nil { + return err + } + log.Debugf("Detected current user as: %v+", curUser) + if curUser.Username == "mqm" { + // Not supported yet + return fmt.Errorf("Container is running as mqm user which is not supported. Please run this container as root") + } else if curUser.Username == "root" { + // We're running as root so need to check for suplimentary groups. + // We can't use the golang User.GroupIDs as it doesn't seem to detect container supplimentary groups.. + groups, err := getCurrentGroups() + for _, e := range groups { + _, _, testGroup := command.Run("getent", "group", e) + if testGroup != nil { + log.Printf("Group %s does not exist on the system... Adding to system and MQM user", e) + _, _, err = command.Run("groupadd", "-g", e, groupName) + if err != nil { + log.Errorf("Failed to create group %s as %s", e, groupName) + return err + } + _, _, err = command.Run("usermod", "-aG", groupName, "mqm") + if err != nil { + log.Errorf("Failed to add group %s(%s) to the mqm user.", groupName, e) + return err + } + } + } + } else { + // We're running as an unknown user... + return fmt.Errorf("Container is running as %s user which is not supported. Please run this container as root", curUser.Username) + } + + return nil +} + +func logUser() { + u, err := user.Current() + if err == nil { + g, err := getCurrentGroups() + if err != nil && len(g) == 0 { + log.Printf("Running as user ID %v (%v) with primary group %v", u.Uid, u.Name, u.Gid) + } else { + // Look for the primary group in the list of group IDs + for i, v := range g { + if v == u.Gid { + // Remove the element from the slice + g = append(g[:i], g[i+1:]...) + } + } + log.Printf("Running as user ID %v (%v) with primary group %v, and supplemental groups %v", u.Uid, u.Name, u.Gid, strings.Join(g, ",")) + } + } +} + +func getCurrentGroups() ([]string, error) { + var nilArray []string + out, _, err := command.Run("id", "--groups") + if err != nil { + log.Debug("Unable to get current user groups") + return nilArray, err + } + + out = strings.TrimSpace(out) + if out == "" { + // we don't have any groups? + return nilArray, fmt.Errorf("Unable to determine groups for current user") + } + + groups := strings.Split(out, " ") + return groups, nil +}