at master 5.4 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 include = mkOption { 129 default = [ ]; 130 description = '' 131 Files to include in the Kerberos configuration. 132 ''; 133 type = coercedTo path singleton (listOf path); 134 }; 135 includedir = mkOption { 136 default = [ ]; 137 description = '' 138 Directories containing files to include in the Kerberos configuration. 139 ''; 140 type = coercedTo path singleton (listOf path); 141 }; 142 module = mkOption { 143 default = [ ]; 144 description = '' 145 Modules to obtain Kerberos configuration from. 146 ''; 147 type = coercedTo path singleton (listOf path); 148 }; 149 150 } 151 // (lib.optionalAttrs enableKdcACLEntries { 152 realms = mkOption { 153 type = attrsOf realm; 154 description = '' 155 The realm(s) to serve keys for. 156 ''; 157 }; 158 }); 159 }; 160 161 generate = 162 let 163 indent = str: concatMapStringsSep "\n" (line: " " + line) (splitString "\n" str); 164 165 formatToplevel = 166 args@{ 167 include ? [ ], 168 includedir ? [ ], 169 module ? [ ], 170 ... 171 }: 172 let 173 sections = removeAttrs args [ 174 "include" 175 "includedir" 176 "module" 177 ]; 178 in 179 concatStringsSep "\n" ( 180 filter (x: x != "") [ 181 (concatStringsSep "\n" (mapAttrsToList formatSection sections)) 182 (concatMapStringsSep "\n" (m: "module ${m}") module) 183 (concatMapStringsSep "\n" (i: "include ${i}") include) 184 (concatMapStringsSep "\n" (i: "includedir ${i}") includedir) 185 ] 186 ); 187 188 formatSection = name: section: '' 189 [${name}] 190 ${indent (concatStringsSep "\n" (mapAttrsToList formatRelation section))} 191 ''; 192 193 formatRelation = 194 name: relation: 195 if isAttrs relation then 196 '' 197 ${name} = { 198 ${indent (concatStringsSep "\n" (mapAttrsToList formatValue relation))} 199 }'' 200 else if isList relation then 201 concatMapStringsSep "\n" (formatRelation name) relation 202 else 203 formatValue name relation; 204 205 formatValue = 206 name: value: 207 if isList value then concatMapStringsSep "\n" (formatAtom name) value else formatAtom name value; 208 209 formatAtom = 210 name: atom: 211 let 212 v = if isBool atom then boolToString atom else toString atom; 213 in 214 "${name} = ${v}"; 215 in 216 name: value: 217 pkgs.writeText name '' 218 ${formatToplevel value} 219 ''; 220}