diff options
Diffstat (limited to 'pkg/permissions.go')
-rw-r--r-- | pkg/permissions.go | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/pkg/permissions.go b/pkg/permissions.go new file mode 100644 index 0000000..2bd73a9 --- /dev/null +++ b/pkg/permissions.go @@ -0,0 +1,89 @@ +package gonf + +import ( + "errors" + "io/fs" + "os" + "os/user" + "strconv" + "syscall" +) + +type Permissions struct { + group Value + mode Value + user Value +} + +func ModeUserGroup(mode, user, group interface{}) *Permissions { + return &Permissions{ + group: interfaceToTemplateValue(group), + mode: interfaceToTemplateValue(mode), + user: interfaceToTemplateValue(user), + } +} + +func (p *Permissions) resolve(filename string) (Status, error) { + g, ok := p.group.(*IntValue) + if !ok { + if group, err := user.LookupGroup(p.group.String()); err != nil { + return BROKEN, err + } else { + if groupId, err := strconv.Atoi(group.Gid); err != nil { + return BROKEN, err + } else { + g = &IntValue{groupId} + p.group = g + } + } + } + m, ok := p.mode.(*IntValue) + if !ok { + if i, err := strconv.Atoi(p.mode.String()); err != nil { + return BROKEN, err + } else { + m = &IntValue{i} + p.mode = m + } + } + u, ok := p.user.(*IntValue) + if !ok { + if user, err := user.Lookup(p.user.String()); err != nil { + return BROKEN, err + } else { + if userId, err := strconv.Atoi(user.Uid); err != nil { + return BROKEN, err + } else { + u = &IntValue{userId} + p.group = u + } + } + } + var status Status = KEPT + if fileInfo, err := os.Lstat(filename); err != nil { + return BROKEN, err + } else { + gv := g.Int() + mv := fs.FileMode(m.Int()) + uv := u.Int() + if fileInfo.Mode() != mv { + if err := os.Chmod(filename, mv); err != nil { + return BROKEN, err + } + status = REPAIRED + } + if stat, ok := fileInfo.Sys().(*syscall.Stat_t); ok { + if stat.Gid != uint32(gv) || stat.Uid != uint32(uv) { + if err := os.Chown(filename, uv, gv); err != nil { + return BROKEN, err + } + status = REPAIRED + } + } else { + return BROKEN, errors.New("Unsupported operating system") + } + _ = gv + _ = uv + } + return status, nil +} |