github.com/apptainer/singularity@v3.1.1+incompatible/internal/pkg/util/fs/files/group.go (about) 1 // Copyright (c) 2018, Sylabs Inc. All rights reserved. 2 // This software is licensed under a 3-clause BSD license. Please consult the 3 // LICENSE.md file distributed with the sources of this project regarding your 4 // rights to use or distribute this software. 5 6 package files 7 8 import ( 9 "fmt" 10 "io/ioutil" 11 "os" 12 13 "github.com/sylabs/singularity/internal/pkg/sylog" 14 "github.com/sylabs/singularity/internal/pkg/util/fs" 15 "github.com/sylabs/singularity/internal/pkg/util/user" 16 ) 17 18 // Group creates a group template based on content of file provided in path, 19 // updates content with current user information and returns content 20 func Group(path string, uid int, gids []int) (content []byte, err error) { 21 duplicate := false 22 groups := make([]int, 0) 23 24 sylog.Verbosef("Checking for template group file: %s\n", path) 25 if fs.IsFile(path) == false { 26 return content, fmt.Errorf("group file doesn't exist in container, not updating") 27 } 28 29 sylog.Verbosef("Creating group content\n") 30 groupFile, err := os.Open(path) 31 if err != nil { 32 return content, fmt.Errorf("failed to open group file in container: %s", err) 33 } 34 defer groupFile.Close() 35 36 pwInfo, err := user.GetPwUID(uint32(uid)) 37 if err != nil || pwInfo == nil { 38 return content, err 39 } 40 if len(gids) == 0 { 41 grInfo, err := user.GetGrGID(pwInfo.GID) 42 if err != nil || grInfo == nil { 43 return content, err 44 } 45 groups, err = os.Getgroups() 46 if err != nil { 47 return content, err 48 } 49 } else { 50 groups = gids 51 } 52 for _, gid := range groups { 53 if gid == int(pwInfo.GID) { 54 duplicate = true 55 break 56 } 57 } 58 if duplicate == false { 59 if len(gids) == 0 { 60 groups = append(groups, int(pwInfo.GID)) 61 } 62 } 63 content, err = ioutil.ReadAll(groupFile) 64 if err != nil { 65 return content, fmt.Errorf("failed to read group file content in container: %s", err) 66 } 67 68 if len(content) > 0 && content[len(content)-1] != '\n' { 69 content = append(content, '\n') 70 } 71 72 for _, gid := range groups { 73 grInfo, err := user.GetGrGID(uint32(gid)) 74 if err != nil || grInfo == nil { 75 sylog.Verbosef("Skipping GID %d as group entry doesn't exist.\n", gid) 76 continue 77 } 78 groupLine := fmt.Sprintf("%s:x:%d:%s\n", grInfo.Name, grInfo.GID, pwInfo.Name) 79 content = append(content, []byte(groupLine)...) 80 } 81 return content, nil 82 }