2024-06-14

fs-perm

ensure filesystem permissions with configuration files

a configuration file format and evaluator implementation for specifying and setting filesystem permissions. a bit like css for filesystem permissions

motivation

programs, copied files and remote users working on a system sometimes create new files with incorrect permissions and modify the permissions of existing files. if there are no regular automatic checks and fixes to keep desired filesystem permissions, the security of the system is at risk and processes that need specific permissions might stop working. for the purpose of ensuring filesystem permissions, writing shell scripts that use the chown, chmod, setfacl, find and similar utilities is much more cumbersome, unclear, error prone and harder to maintain than necessary

features

  • nested paths
  • user/group/other and acl permissions
  • file-type specific permissions
  • setting owner and group
  • automatic executable bit for directories if the read permission is set
  • globbing with a child selector "", recursive/descendants selector "", and "." ".**" for including the starting path
  • path production
  • dry-run option that displays shell commands
  • permission specifiers can be shortened, like just "r" or "rw,r::groupname"
  • list and string support for acl specifiers
  • no support for octal notation

examples

permission configuration file with almost all features mixed:

("/home/nonroot"
  "directory:rwx,rw:nonroot:http"
  (file-type regular default-user (nonroot rw) user (testuser rw http r) group (http rw) other r)
  ("temp/documents/*" (acl file-type directory "d:u:1000:rwx"))
  (("modules" "tests") "rwx,rw::git"))

same with comments

("/home/nonroot"
  ;restriction on directories. sets permissions, user and group
  "directory:rwx,rw:nonroot:http"
  ;acl as a key/value list
  (file-type regular default-user (nonroot rw) user (testuser rw http r) group (http rw) other r)
  ("temp/documents/*"
    ;an alternative acl notation as a key/value list and string as would be used with "setfacl"
    (acl file-type directory "d:u:1000:rwx"))
  ;matches any of the listed file names
  (("modules" "tests") "rwx,rw::git"))

more practical example

; matches all ".git" directories under "/home/testuser"
("/home/testuser/**/.git" "rw:nonroot:git")

command-line program

$ fs-perm-set --help

parameters
  options ... specifier path paths ...
options
  --acl
  --config-file=value
  --dry-run
  --help | -h
  --interface

usage examples

$ cat my-fs-config | fs-perm-set --dry-run
$ fs-perm-set --config-file=my-fs-config
$ fs-perm-set rw,r:testuser testpath testpath/**
$ fs-perm-set --acl u:testuser:rw testpath-1 testpath-2
$ fs-perm-set rwx,rw:nonroot /usr/share/guile/site/2.2/ice-9/* --dry-run
chown 1000:-1 "/usr/share/guile/site/2.2/ice-9/match-phd-lookup.scm"
chmod 760 "/usr/share/guile/site/2.2/ice-9/match-phd-lookup.scm"
chown 1000:-1 "/usr/share/guile/site/2.2/ice-9/match-phd.scm"
chmod 760 "/usr/share/guile/site/2.2/ice-9/match-phd.scm"
chown 1000:-1 "/usr/share/guile/site/2.2/ice-9/set"
chmod 770 "/usr/share/guile/site/2.2/ice-9/set"
chown 1000:-1 "/usr/share/guile/site/2.2/ice-9/vset.scm"
chmod 760 "/usr/share/guile/site/2.2/ice-9/vset.scm"

configuration file syntax

  • file-name: {valid filesystem file name character} ...
  • path: ["/"] file-name///./.** ["/" path] ...
  • perm-name: "r"/"w"/"x"
  • perm: perm-name [perm-name [perm-name]]
  • ugo-perm: perm ["," perm ["," perm]]
  • acl-specifier: ([symbol:key symbol/string:value])/(acl [symbol:key any:value] ... string [symbol:key any:value] ...)
  • rule: (string:path/(string:path ...) string:ugo-specifier/acl-specifier ... rule ...)

dependencies

rationale

why not support octal notation?

  • simplicity: in this program, not all permission parts (user, group, other) need to be specified. 'rwx' notation ensures a write-once, read-often approach, enhancing readability and reducing the cognitive load involved in understanding permissions
  • consistency: supporting both notations could lead to mixed usage, causing inconsistency and complicating the configuration. users would need to understand both systems well
  • clarity: while octal notation is shorter and preferred by some, including the author, on the command line, it requires memorizing which octal value corresponds to each permission. 'rwx' notation is more intuitive, with characters that directly indicate the type of permission

setup

  • download fs-perm from releases or clone from git://git.sph.mn/fs-perm
  • extract the downloaded archive
  • link or copy the files exe/fs-perm-set into a directory which is in the environment variable $PATH
  • link or copy the files modules/* into a directory which is in the environment variable $GUILE_LOAD_PATH or any other guile load path
  • adjust file system permissions eventually

module name

(sph fs-perm config)