pkg.re/essentialkaos/ek.10@v12.41.0+incompatible/knf/validators/fs/validators.go (about) 1 // Package fs provides KNF validators for checking file-system items 2 package fs 3 4 // ////////////////////////////////////////////////////////////////////////////////// // 5 // // 6 // Copyright (c) 2022 ESSENTIAL KAOS // 7 // Apache License, Version 2.0 <https://www.apache.org/licenses/LICENSE-2.0> // 8 // // 9 // ////////////////////////////////////////////////////////////////////////////////// // 10 11 import ( 12 "fmt" 13 "os" 14 15 "pkg.re/essentialkaos/ek.v12/fsutil" 16 "pkg.re/essentialkaos/ek.v12/knf" 17 "pkg.re/essentialkaos/ek.v12/path" 18 "pkg.re/essentialkaos/ek.v12/system" 19 ) 20 21 // ////////////////////////////////////////////////////////////////////////////////// // 22 23 var ( 24 // Perms returns error if config property contains path to object with given 25 // permissions 26 Perms = validatePerms 27 28 // Owner returns error if config property contains path to object with other 29 // owner 30 Owner = validateOwner 31 32 // OwnerGroup returns error if config property contains path to object with other 33 // owner group 34 OwnerGroup = validateOwnerGroup 35 36 // FileMode returns error if config property contains path to object with other 37 // file mode 38 FileMode = validateFileMode 39 40 // MatchPattern returns error if config property contains path which doesn't match 41 // given shell pattern 42 MatchPattern = validateMatchPattern 43 ) 44 45 // ////////////////////////////////////////////////////////////////////////////////// // 46 47 func validatePerms(config *knf.Config, prop string, value interface{}) error { 48 perms := value.(string) 49 target := config.GetS(prop) 50 51 if target == "" { 52 return nil 53 } 54 55 if !fsutil.CheckPerms(perms, target) { 56 switch perms { 57 case "F": 58 return fmt.Errorf("Property %s must be path to file", prop) 59 case "FR": 60 return fmt.Errorf("Property %s must be path to readable file", prop) 61 case "FW": 62 return fmt.Errorf("Property %s must be path to writable file", prop) 63 case "FX": 64 return fmt.Errorf("Property %s must be path to executable file", prop) 65 case "FRW": 66 return fmt.Errorf("Property %s must be path to readable/writable file", prop) 67 case "DX": 68 return fmt.Errorf("Property %s must be path to directory", prop) 69 case "DRX": 70 return fmt.Errorf("Property %s must be path to readable directory", prop) 71 case "DWX": 72 return fmt.Errorf("Property %s must be path to writable directory", prop) 73 case "DRWX": 74 return fmt.Errorf("Property %s must be path to readable/writable directory", prop) 75 default: 76 return fmt.Errorf("Property %s must be path to object with given permissions (%s)", prop, perms) 77 } 78 } 79 80 return nil 81 } 82 83 func validateOwner(config *knf.Config, prop string, value interface{}) error { 84 target := config.GetS(prop) 85 owner := value.(string) 86 87 if target == "" { 88 return nil 89 } 90 91 user, err := system.LookupUser(owner) 92 93 if err != nil { 94 return fmt.Errorf("Can't find user %s on system", owner) 95 } 96 97 uid, _, err := fsutil.GetOwner(target) 98 99 if err != nil { 100 return fmt.Errorf("Can't get owner for %s", target) 101 } 102 103 if user.UID != uid { 104 return fmt.Errorf("User %s must be owner of %s", owner, target) 105 } 106 107 return nil 108 } 109 110 func validateOwnerGroup(config *knf.Config, prop string, value interface{}) error { 111 target := config.GetS(prop) 112 ownerGroup := value.(string) 113 114 if target == "" { 115 return nil 116 } 117 118 group, err := system.LookupGroup(ownerGroup) 119 120 if err != nil { 121 return fmt.Errorf("Can't find group %s on system", ownerGroup) 122 } 123 124 _, gid, err := fsutil.GetOwner(target) 125 126 if err != nil { 127 return fmt.Errorf("Can't get owner group for %s", target) 128 } 129 130 if group.GID != gid { 131 return fmt.Errorf("Group %s must be owner of %s", ownerGroup, target) 132 } 133 134 return nil 135 } 136 137 func validateFileMode(config *knf.Config, prop string, value interface{}) error { 138 perms := value.(os.FileMode) 139 target := config.GetS(prop) 140 141 if target == "" { 142 return nil 143 } 144 145 targetPerms := fsutil.GetMode(target) 146 147 if targetPerms == 0 { 148 return fmt.Errorf("Can't get mode for %s", target) 149 } 150 151 if perms != targetPerms { 152 return fmt.Errorf("%s has different mode (%d != %d)", target, targetPerms, perms) 153 } 154 155 return nil 156 } 157 158 func validateMatchPattern(config *knf.Config, prop string, value interface{}) error { 159 pattern := value.(string) 160 confPath := config.GetS(prop) 161 162 if pattern == "" || confPath == "" { 163 return nil 164 } 165 166 isMatch, err := path.Match(pattern, confPath) 167 168 if err != nil { 169 return fmt.Errorf("Can't parse shell pattern: %v", err) 170 } 171 172 if !isMatch { 173 return fmt.Errorf("Property %s must match shell pattern %s", prop, pattern) 174 } 175 176 return nil 177 }