at 18.09-beta 11 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 7 cfg = config.krb5; 8 9 # This is to provide support for old configuration options (as much as is 10 # reasonable). This can be removed after 18.03 was released. 11 defaultConfig = { 12 libdefaults = optionalAttrs (cfg.defaultRealm != null) 13 { default_realm = cfg.defaultRealm; }; 14 15 realms = optionalAttrs (lib.all (value: value != null) [ 16 cfg.defaultRealm cfg.kdc cfg.kerberosAdminServer 17 ]) { 18 "${cfg.defaultRealm}" = { 19 kdc = cfg.kdc; 20 admin_server = cfg.kerberosAdminServer; 21 }; 22 }; 23 24 domain_realm = optionalAttrs (lib.all (value: value != null) [ 25 cfg.domainRealm cfg.defaultRealm 26 ]) { 27 ".${cfg.domainRealm}" = cfg.defaultRealm; 28 "${cfg.domainRealm}" = cfg.defaultRealm; 29 }; 30 }; 31 32 mergedConfig = (recursiveUpdate defaultConfig { 33 inherit (config.krb5) 34 kerberos libdefaults realms domain_realm capaths appdefaults plugins 35 extraConfig config; 36 }); 37 38 filterEmbeddedMetadata = value: if isAttrs value then 39 (filterAttrs 40 (attrName: attrValue: attrName != "_module" && attrValue != null) 41 value) 42 else value; 43 44 mkIndent = depth: concatStrings (builtins.genList (_: " ") (2 * depth)); 45 46 mkRelation = name: value: "${name} = ${mkVal { inherit value; }}"; 47 48 mkVal = { value, depth ? 0 }: 49 if (value == true) then "true" 50 else if (value == false) then "false" 51 else if (isInt value) then (toString value) 52 else if (isList value) then 53 concatMapStringsSep " " mkVal { inherit value depth; } 54 else if (isAttrs value) then 55 (concatStringsSep "\n${mkIndent (depth + 1)}" 56 ([ "{" ] ++ (mapAttrsToList 57 (attrName: attrValue: let 58 mappedAttrValue = mkVal { 59 value = attrValue; 60 depth = depth + 1; 61 }; 62 in "${attrName} = ${mappedAttrValue}") 63 value))) + "\n${mkIndent depth}}" 64 else value; 65 66 mkMappedAttrsOrString = value: concatMapStringsSep "\n" 67 (line: if builtins.stringLength line > 0 68 then "${mkIndent 1}${line}" 69 else line) 70 (splitString "\n" 71 (if isAttrs value then 72 concatStringsSep "\n" 73 (mapAttrsToList mkRelation value) 74 else value)); 75 76in { 77 78 ###### interface 79 80 options = { 81 krb5 = { 82 enable = mkEnableOption "Whether to enable Kerberos V."; 83 84 kerberos = mkOption { 85 type = types.package; 86 default = pkgs.krb5Full; 87 defaultText = "pkgs.krb5Full"; 88 example = literalExample "pkgs.heimdalFull"; 89 description = '' 90 The Kerberos implementation that will be present in 91 <literal>environment.systemPackages</literal> after enabling this 92 service. 93 ''; 94 }; 95 96 libdefaults = mkOption { 97 type = with types; either attrs lines; 98 default = {}; 99 apply = attrs: filterEmbeddedMetadata attrs; 100 example = literalExample '' 101 { 102 default_realm = "ATHENA.MIT.EDU"; 103 }; 104 ''; 105 description = '' 106 Settings used by the Kerberos V5 library. 107 ''; 108 }; 109 110 realms = mkOption { 111 type = with types; either attrs lines; 112 default = {}; 113 example = literalExample '' 114 { 115 "ATHENA.MIT.EDU" = { 116 admin_server = "athena.mit.edu"; 117 kdc = "athena.mit.edu"; 118 }; 119 }; 120 ''; 121 apply = attrs: filterEmbeddedMetadata attrs; 122 description = "Realm-specific contact information and settings."; 123 }; 124 125 domain_realm = mkOption { 126 type = with types; either attrs lines; 127 default = {}; 128 example = literalExample '' 129 { 130 "example.com" = "EXAMPLE.COM"; 131 ".example.com" = "EXAMPLE.COM"; 132 }; 133 ''; 134 apply = attrs: filterEmbeddedMetadata attrs; 135 description = '' 136 Map of server hostnames to Kerberos realms. 137 ''; 138 }; 139 140 capaths = mkOption { 141 type = with types; either attrs lines; 142 default = {}; 143 example = literalExample '' 144 { 145 "ATHENA.MIT.EDU" = { 146 "EXAMPLE.COM" = "."; 147 }; 148 "EXAMPLE.COM" = { 149 "ATHENA.MIT.EDU" = "."; 150 }; 151 }; 152 ''; 153 apply = attrs: filterEmbeddedMetadata attrs; 154 description = '' 155 Authentication paths for non-hierarchical cross-realm authentication. 156 ''; 157 }; 158 159 appdefaults = mkOption { 160 type = with types; either attrs lines; 161 default = {}; 162 example = literalExample '' 163 { 164 pam = { 165 debug = false; 166 ticket_lifetime = 36000; 167 renew_lifetime = 36000; 168 max_timeout = 30; 169 timeout_shift = 2; 170 initial_timeout = 1; 171 }; 172 }; 173 ''; 174 apply = attrs: filterEmbeddedMetadata attrs; 175 description = '' 176 Settings used by some Kerberos V5 applications. 177 ''; 178 }; 179 180 plugins = mkOption { 181 type = with types; either attrs lines; 182 default = {}; 183 example = literalExample '' 184 { 185 ccselect = { 186 disable = "k5identity"; 187 }; 188 }; 189 ''; 190 apply = attrs: filterEmbeddedMetadata attrs; 191 description = '' 192 Controls plugin module registration. 193 ''; 194 }; 195 196 extraConfig = mkOption { 197 type = with types; nullOr lines; 198 default = null; 199 example = '' 200 [logging] 201 kdc = SYSLOG:NOTICE 202 admin_server = SYSLOG:NOTICE 203 default = SYSLOG:NOTICE 204 ''; 205 description = '' 206 These lines go to the end of <literal>krb5.conf</literal> verbatim. 207 <literal>krb5.conf</literal> may include any of the relations that are 208 valid for <literal>kdc.conf</literal> (see <literal>man 209 kdc.conf</literal>), but it is not a recommended practice. 210 ''; 211 }; 212 213 config = mkOption { 214 type = with types; nullOr lines; 215 default = null; 216 example = '' 217 [libdefaults] 218 default_realm = EXAMPLE.COM 219 220 [realms] 221 EXAMPLE.COM = { 222 admin_server = kerberos.example.com 223 kdc = kerberos.example.com 224 default_principal_flags = +preauth 225 } 226 227 [domain_realm] 228 example.com = EXAMPLE.COM 229 .example.com = EXAMPLE.COM 230 231 [logging] 232 kdc = SYSLOG:NOTICE 233 admin_server = SYSLOG:NOTICE 234 default = SYSLOG:NOTICE 235 ''; 236 description = '' 237 Verbatim <literal>krb5.conf</literal> configuration. Note that this 238 is mutually exclusive with configuration via 239 <literal>libdefaults</literal>, <literal>realms</literal>, 240 <literal>domain_realm</literal>, <literal>capaths</literal>, 241 <literal>appdefaults</literal>, <literal>plugins</literal> and 242 <literal>extraConfig</literal> configuration options. Consult 243 <literal>man krb5.conf</literal> for documentation. 244 ''; 245 }; 246 247 defaultRealm = mkOption { 248 type = with types; nullOr str; 249 default = null; 250 example = "ATHENA.MIT.EDU"; 251 description = '' 252 DEPRECATED, please use 253 <literal>krb5.libdefaults.default_realm</literal>. 254 ''; 255 }; 256 257 domainRealm = mkOption { 258 type = with types; nullOr str; 259 default = null; 260 example = "athena.mit.edu"; 261 description = '' 262 DEPRECATED, please create a map of server hostnames to Kerberos realms 263 in <literal>krb5.domain_realm</literal>. 264 ''; 265 }; 266 267 kdc = mkOption { 268 type = with types; nullOr str; 269 default = null; 270 example = "kerberos.mit.edu"; 271 description = '' 272 DEPRECATED, please pass a <literal>kdc</literal> attribute to a realm 273 in <literal>krb5.realms</literal>. 274 ''; 275 }; 276 277 kerberosAdminServer = mkOption { 278 type = with types; nullOr str; 279 default = null; 280 example = "kerberos.mit.edu"; 281 description = '' 282 DEPRECATED, please pass an <literal>admin_server</literal> attribute 283 to a realm in <literal>krb5.realms</literal>. 284 ''; 285 }; 286 }; 287 }; 288 289 ###### implementation 290 291 config = mkIf cfg.enable { 292 293 environment.systemPackages = [ cfg.kerberos ]; 294 295 environment.etc."krb5.conf".text = if isString cfg.config 296 then cfg.config 297 else ('' 298 [libdefaults] 299 ${mkMappedAttrsOrString mergedConfig.libdefaults} 300 301 [realms] 302 ${mkMappedAttrsOrString mergedConfig.realms} 303 304 [domain_realm] 305 ${mkMappedAttrsOrString mergedConfig.domain_realm} 306 307 [capaths] 308 ${mkMappedAttrsOrString mergedConfig.capaths} 309 310 [appdefaults] 311 ${mkMappedAttrsOrString mergedConfig.appdefaults} 312 313 [plugins] 314 ${mkMappedAttrsOrString mergedConfig.plugins} 315 '' + optionalString (mergedConfig.extraConfig != null) 316 ("\n" + mergedConfig.extraConfig)); 317 318 warnings = flatten [ 319 (optional (cfg.defaultRealm != null) '' 320 The option krb5.defaultRealm is deprecated, please use 321 krb5.libdefaults.default_realm. 322 '') 323 (optional (cfg.domainRealm != null) '' 324 The option krb5.domainRealm is deprecated, please use krb5.domain_realm. 325 '') 326 (optional (cfg.kdc != null) '' 327 The option krb5.kdc is deprecated, please pass a kdc attribute to a 328 realm in krb5.realms. 329 '') 330 (optional (cfg.kerberosAdminServer != null) '' 331 The option krb5.kerberosAdminServer is deprecated, please pass an 332 admin_server attribute to a realm in krb5.realms. 333 '') 334 ]; 335 336 assertions = [ 337 { assertion = !((builtins.any (value: value != null) [ 338 cfg.defaultRealm cfg.domainRealm cfg.kdc cfg.kerberosAdminServer 339 ]) && ((builtins.any (value: value != {}) [ 340 cfg.libdefaults cfg.realms cfg.domain_realm cfg.capaths 341 cfg.appdefaults cfg.plugins 342 ]) || (builtins.any (value: value != null) [ 343 cfg.config cfg.extraConfig 344 ]))); 345 message = '' 346 Configuration of krb5.conf by deprecated options is mutually exclusive 347 with configuration by section. Please migrate your config using the 348 attributes suggested in the warnings. 349 ''; 350 } 351 { assertion = !(cfg.config != null 352 && ((builtins.any (value: value != {}) [ 353 cfg.libdefaults cfg.realms cfg.domain_realm cfg.capaths 354 cfg.appdefaults cfg.plugins 355 ]) || (builtins.any (value: value != null) [ 356 cfg.extraConfig cfg.defaultRealm cfg.domainRealm cfg.kdc 357 cfg.kerberosAdminServer 358 ]))); 359 message = '' 360 Configuration of krb5.conf using krb.config is mutually exclusive with 361 configuration by section. If you want to mix the two, you can pass 362 lines to any configuration section or lines to krb5.extraConfig. 363 ''; 364 } 365 ]; 366 }; 367}