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