at 25.11-pre 5.5 kB view raw
1{ pkgs, lib, ... }: 2 3# Based on 4# - https://web.mit.edu/kerberos/krb5-1.12/doc/admin/conf_files/krb5_conf.html 5# - https://manpages.debian.org/unstable/heimdal-docs/krb5.conf.5heimdal.en.html 6 7let 8 inherit (lib) 9 boolToString 10 concatMapStringsSep 11 concatStringsSep 12 filter 13 isAttrs 14 isBool 15 isList 16 mapAttrsToList 17 mkOption 18 singleton 19 splitString 20 ; 21 inherit (lib.types) 22 attrsOf 23 bool 24 coercedTo 25 either 26 enum 27 int 28 listOf 29 oneOf 30 path 31 str 32 submodule 33 ; 34in 35{ 36 enableKdcACLEntries ? false, 37}: 38rec { 39 sectionType = 40 let 41 relation = oneOf [ 42 (listOf (attrsOf value)) 43 (attrsOf value) 44 value 45 ]; 46 value = either (listOf atom) atom; 47 atom = oneOf [ 48 int 49 str 50 bool 51 ]; 52 in 53 attrsOf relation; 54 55 type = 56 let 57 aclEntry = submodule { 58 options = { 59 principal = mkOption { 60 type = str; 61 description = "Which principal the rule applies to"; 62 }; 63 access = mkOption { 64 type = coercedTo str singleton ( 65 listOf (enum [ 66 "all" 67 "add" 68 "cpw" 69 "delete" 70 "get-keys" 71 "get" 72 "list" 73 "modify" 74 ]) 75 ); 76 default = "all"; 77 description = '' 78 The changes the principal is allowed to make. 79 80 :::{.important} 81 The "all" permission does not imply the "get-keys" permission. This 82 is consistent with the behavior of both MIT Kerberos and Heimdal. 83 ::: 84 85 :::{.warning} 86 Value "all" is allowed as a list member only if it appears alone 87 or accompanied by "get-keys". Any other combination involving 88 "all" will raise an exception. 89 ::: 90 ''; 91 }; 92 target = mkOption { 93 type = str; 94 default = "*"; 95 description = "The principals that 'access' applies to."; 96 }; 97 }; 98 }; 99 100 realm = submodule ( 101 { name, ... }: 102 { 103 freeformType = sectionType; 104 options = { 105 acl = mkOption { 106 type = listOf aclEntry; 107 default = [ 108 { 109 principal = "*/admin"; 110 access = "all"; 111 } 112 { 113 principal = "admin"; 114 access = "all"; 115 } 116 ]; 117 description = '' 118 The privileges granted to a user. 119 ''; 120 }; 121 }; 122 } 123 ); 124 in 125 submodule { 126 freeformType = attrsOf sectionType; 127 options = 128 { 129 include = mkOption { 130 default = [ ]; 131 description = '' 132 Files to include in the Kerberos configuration. 133 ''; 134 type = coercedTo path singleton (listOf path); 135 }; 136 includedir = mkOption { 137 default = [ ]; 138 description = '' 139 Directories containing files to include in the Kerberos configuration. 140 ''; 141 type = coercedTo path singleton (listOf path); 142 }; 143 module = mkOption { 144 default = [ ]; 145 description = '' 146 Modules to obtain Kerberos configuration from. 147 ''; 148 type = coercedTo path singleton (listOf path); 149 }; 150 151 } 152 // (lib.optionalAttrs enableKdcACLEntries { 153 realms = mkOption { 154 type = attrsOf realm; 155 description = '' 156 The realm(s) to serve keys for. 157 ''; 158 }; 159 }); 160 }; 161 162 generate = 163 let 164 indent = str: concatMapStringsSep "\n" (line: " " + line) (splitString "\n" str); 165 166 formatToplevel = 167 args@{ 168 include ? [ ], 169 includedir ? [ ], 170 module ? [ ], 171 ... 172 }: 173 let 174 sections = removeAttrs args [ 175 "include" 176 "includedir" 177 "module" 178 ]; 179 in 180 concatStringsSep "\n" ( 181 filter (x: x != "") [ 182 (concatStringsSep "\n" (mapAttrsToList formatSection sections)) 183 (concatMapStringsSep "\n" (m: "module ${m}") module) 184 (concatMapStringsSep "\n" (i: "include ${i}") include) 185 (concatMapStringsSep "\n" (i: "includedir ${i}") includedir) 186 ] 187 ); 188 189 formatSection = name: section: '' 190 [${name}] 191 ${indent (concatStringsSep "\n" (mapAttrsToList formatRelation section))} 192 ''; 193 194 formatRelation = 195 name: relation: 196 if isAttrs relation then 197 '' 198 ${name} = { 199 ${indent (concatStringsSep "\n" (mapAttrsToList formatValue relation))} 200 }'' 201 else if isList relation then 202 concatMapStringsSep "\n" (formatRelation name) relation 203 else 204 formatValue name relation; 205 206 formatValue = 207 name: value: 208 if isList value then concatMapStringsSep "\n" (formatAtom name) value else formatAtom name value; 209 210 formatAtom = 211 name: atom: 212 let 213 v = if isBool atom then boolToString atom else toString atom; 214 in 215 "${name} = ${v}"; 216 in 217 name: value: 218 pkgs.writeText name '' 219 ${formatToplevel value} 220 ''; 221}