From 429752a69d4a224e0aa65e09a4f9c396ee3eaa70 Mon Sep 17 00:00:00 2001 From: Mrunal Patel Date: Thu, 30 Apr 2015 19:02:31 -0400 Subject: [PATCH] Lookup additional groups in the container. Signed-off-by: Mrunal Patel --- configs/config.go | 2 +- init_linux.go | 9 ++++++++- user/user.go | 49 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 2 deletions(-) diff --git a/configs/config.go b/configs/config.go index 7275b6421..04ea91ffd 100644 --- a/configs/config.go +++ b/configs/config.go @@ -119,7 +119,7 @@ type Config struct { // AdditionalGroups specifies the gids that should be added to supplementary groups // in addition to those that the user belongs to. - AdditionalGroups []int `json:"additional_groups"` + AdditionalGroups []string `json:"additional_groups"` // UidMappings is an array of User ID mappings for User Namespaces UidMappings []IDMap `json:"uid_mappings"` diff --git a/init_linux.go b/init_linux.go index 3eabe3cd6..521de51c8 100644 --- a/init_linux.go +++ b/init_linux.go @@ -177,10 +177,17 @@ func setupUser(config *initConfig) error { if err != nil { return err } - suppGroups := append(execUser.Sgids, config.Config.AdditionalGroups...) + + addGroups, err := user.GetAdditionalGroupsPath(config.Config.AdditionalGroups, groupPath) + if err != nil { + return err + } + + suppGroups := append(execUser.Sgids, addGroups...) if err := syscall.Setgroups(suppGroups); err != nil { return err } + if err := system.Setgid(execUser.Gid); err != nil { return err } diff --git a/user/user.go b/user/user.go index d7439f12e..baff970c8 100644 --- a/user/user.go +++ b/user/user.go @@ -348,3 +348,52 @@ func GetExecUser(userSpec string, defaults *ExecUser, passwd, group io.Reader) ( return user, nil } + +// GetAdditionalGroupsPath is a wrapper for GetAdditionalGroups. It reads data from the +// given file path and uses that data as the arguments to GetAdditionalGroups. +func GetAdditionalGroupsPath(additionalGroups []string, groupPath string) ([]int, error) { + var groupIds []int + + for _, ag := range additionalGroups { + groupReader, err := os.Open(groupPath) + if err != nil { + return nil, fmt.Errorf("Failed to open group file: %v", err) + } + defer groupReader.Close() + + groupId, err := GetAdditionalGroup(ag, groupReader) + if err != nil { + return nil, err + } + groupIds = append(groupIds, groupId) + } + + return groupIds, nil +} + +// GetAdditionalGroup looks up the specified group in the passed groupReader. +func GetAdditionalGroup(additionalGroup string, groupReader io.Reader) (int, error) { + groups, err := ParseGroupFilter(groupReader, func(g Group) bool { + return g.Name == additionalGroup || strconv.Itoa(g.Gid) == additionalGroup + }) + if err != nil { + return -1, fmt.Errorf("Unable to find additional groups %v: %v", additionalGroup, err) + } + if groups != nil && len(groups) > 0 { + // if we found any group entries that matched our filter, let's take the first one as "correct" + return groups[0].Gid, nil + } else { + // we asked for a group but didn't find id... let's check to see if we wanted a numeric group + addGroup, err := strconv.Atoi(additionalGroup) + if err != nil { + // not numeric - we have to bail + return -1, fmt.Errorf("Unable to find group %v", additionalGroup) + } + + // Ensure gid is inside gid range. + if addGroup < minId || addGroup > maxId { + return -1, ErrRange + } + return addGroup, nil + } +}