Allow numeric groups for containers without /etc/group

/etc/groups is not needed when specifying numeric group ids. This
change allows containers without /etc/groups to specify numeric
supplemental groups.

Signed-off-by: Sami Wagiaalla <swagiaal@redhat.com>
This commit is contained in:
Sami Wagiaalla 2015-10-04 19:02:30 -04:00
parent c573ffbd05
commit c25c38cc80
2 changed files with 58 additions and 17 deletions

View File

@ -349,21 +349,26 @@ func GetExecUser(userSpec string, defaults *ExecUser, passwd, group io.Reader) (
return user, nil return user, nil
} }
// GetAdditionalGroups looks up a list of groups by name or group id against // GetAdditionalGroups looks up a list of groups by name or group id
// against the given /etc/group formatted data. If a group name cannot be found, // against the given /etc/group formatted data. If a group name cannot
// an error will be returned. If a group id cannot be found, it will be returned // be found, an error will be returned. If a group id cannot be found,
// as-is. // or the given group data is nil, the id will be returned as-is
// provided it is in the legal range.
func GetAdditionalGroups(additionalGroups []string, group io.Reader) ([]int, error) { func GetAdditionalGroups(additionalGroups []string, group io.Reader) ([]int, error) {
groups, err := ParseGroupFilter(group, func(g Group) bool { var groups = []Group{}
for _, ag := range additionalGroups { if group != nil {
if g.Name == ag || strconv.Itoa(g.Gid) == ag { var err error
return true groups, err = ParseGroupFilter(group, func(g Group) bool {
for _, ag := range additionalGroups {
if g.Name == ag || strconv.Itoa(g.Gid) == ag {
return true
}
} }
return false
})
if err != nil {
return nil, fmt.Errorf("Unable to find additional groups %v: %v", additionalGroups, err)
} }
return false
})
if err != nil {
return nil, fmt.Errorf("Unable to find additional groups %v: %v", additionalGroups, err)
} }
gidMap := make(map[int]struct{}) gidMap := make(map[int]struct{})
@ -401,13 +406,13 @@ func GetAdditionalGroups(additionalGroups []string, group io.Reader) ([]int, err
return gids, nil return gids, nil
} }
// Wrapper around GetAdditionalGroups that opens the groupPath given and gives // GetAdditionalGroupsPath is a wrapper around GetAdditionalGroups
// it as an argument to GetAdditionalGroups. // that opens the groupPath given and gives it as an argument to
// GetAdditionalGroups.
func GetAdditionalGroupsPath(additionalGroups []string, groupPath string) ([]int, error) { func GetAdditionalGroupsPath(additionalGroups []string, groupPath string) ([]int, error) {
group, err := os.Open(groupPath) group, err := os.Open(groupPath)
if err != nil { if err == nil {
return nil, fmt.Errorf("Failed to open group file: %v", err) defer group.Close()
} }
defer group.Close()
return GetAdditionalGroups(additionalGroups, group) return GetAdditionalGroups(additionalGroups, group)
} }

View File

@ -434,3 +434,39 @@ this is just some garbage data
} }
} }
} }
func TestGetAdditionalGroupsNumeric(t *testing.T) {
tests := []struct {
groups []string
expected []int
hasError bool
}{
{
// numeric groups only
groups: []string{"1234", "5678"},
expected: []int{1234, 5678},
},
{
// numeric and alphabetic
groups: []string{"1234", "fake"},
expected: nil,
hasError: true,
},
}
for _, test := range tests {
gids, err := GetAdditionalGroups(test.groups, nil)
if test.hasError && err == nil {
t.Errorf("Parse(%#v) expects error but has none", test)
continue
}
if !test.hasError && err != nil {
t.Errorf("Parse(%#v) has error %v", test, err)
continue
}
sort.Sort(sort.IntSlice(gids))
if !reflect.DeepEqual(gids, test.expected) {
t.Errorf("Gids(%v), expect %v from groups %v", gids, test.expected, test.groups)
}
}
}