1 // Config: parse permissions.yaml
3 // SPDX-License-Identifier: GPL-3.0-or-later
4 // Copyright (C) 2021-2024 Simon Ruderich
18 "ruderich.org/simon/safcm"
21 func LoadPermissions(group string, files map[string]*safcm.File) error {
22 path := filepath.Join(group, "permissions.yaml")
24 var cfg map[string]string
25 x, err := os.ReadFile(path)
27 if os.IsNotExist(err) {
32 err = yaml.UnmarshalStrict(x, &cfg)
34 return fmt.Errorf("%s: failed to load: %v", path, err)
37 for p, x := range cfg {
40 return fmt.Errorf("%s: %q does not exist in files/",
44 xs := strings.Fields(x)
45 if len(xs) != 1 && len(xs) != 3 {
46 return fmt.Errorf("%s: invalid line %q "+
47 "(expected <perm> [<user> <group>])",
50 perm, err := strconv.ParseInt(xs[0], 8, 32)
52 return fmt.Errorf("%s: invalid permission %q "+
53 "(expected e.g. %q or %q)",
54 path, xs[0], "0644", "01777")
56 if perm < 0 || perm > 07777 {
57 return fmt.Errorf("%s: invalid permission %#o "+
58 "(expected e.g. %#o or %#o)",
59 path, perm, 0644, 01777)
64 if file.Mode.Perm()&0111 != 0 && perm&0111 == 0 {
66 "%s: %q: trying to remove +x from file, "+
67 "manually chmod -x in files/",
70 file.Mode = file.Mode.Type() | FullPermToFileMode(int(perm))
80 func FileModeToFullPerm(mode fs.FileMode) int {
82 if mode&fs.ModeSticky != 0 {
85 if mode&fs.ModeSetgid != 0 {
88 if mode&fs.ModeSetuid != 0 {
94 func FullPermToFileMode(perm int) fs.FileMode {
95 mode := fs.FileMode(perm & 0777)
100 mode |= fs.ModeSetgid
103 mode |= fs.ModeSetuid