summary refs log tree commit diff
path: root/nixos/modules/services/system/kerberos
diff options
context:
space:
mode:
authorKai Wohlfahrt <kjw53@cam.ac.uk>2017-11-06 17:41:34 +0000
committerKai Wohlfahrt <kai@prodo.ai>2018-12-11 13:33:10 +0000
commit6cca9c0f9f2d7ed80ae52609160d2678e6fe38cd (patch)
treee7c9dd4fee257d7a0e423581fbb14341576478dc /nixos/modules/services/system/kerberos
parentfe8f2b8813e75ab8b20e133b60afaac6e955bca7 (diff)
downloadnixpkgs-6cca9c0f9f2d7ed80ae52609160d2678e6fe38cd.tar
nixpkgs-6cca9c0f9f2d7ed80ae52609160d2678e6fe38cd.tar.gz
nixpkgs-6cca9c0f9f2d7ed80ae52609160d2678e6fe38cd.tar.bz2
nixpkgs-6cca9c0f9f2d7ed80ae52609160d2678e6fe38cd.tar.lz
nixpkgs-6cca9c0f9f2d7ed80ae52609160d2678e6fe38cd.tar.xz
nixpkgs-6cca9c0f9f2d7ed80ae52609160d2678e6fe38cd.tar.zst
nixpkgs-6cca9c0f9f2d7ed80ae52609160d2678e6fe38cd.zip
kerberos-server: add kerberos option
Allow switching out kerberos server implementation.

Sharing config is probably sensible, but implementation is different enough to
be worth splitting into two files. Not sure this is the correct way to split an
implementation, but it works for now.

Uses the switch from config.krb5 to select implementation.
Diffstat (limited to 'nixos/modules/services/system/kerberos')
-rw-r--r--nixos/modules/services/system/kerberos/default.nix76
-rw-r--r--nixos/modules/services/system/kerberos/heimdal.nix74
-rw-r--r--nixos/modules/services/system/kerberos/mit.nix74
3 files changed, 224 insertions, 0 deletions
diff --git a/nixos/modules/services/system/kerberos/default.nix b/nixos/modules/services/system/kerberos/default.nix
new file mode 100644
index 00000000000..90be7e8d551
--- /dev/null
+++ b/nixos/modules/services/system/kerberos/default.nix
@@ -0,0 +1,76 @@
+{pkgs, config, lib, ...}:
+
+let
+  inherit (lib) mkOption mkIf types;
+  cfg = config.services.kerberos_server;
+  kerberos = config.krb5.kerberos;
+
+  aclEntry = {
+    options = {
+      principal = mkOption {
+        type = types.str;
+        description = "Which principal the rule applies to";
+      };
+      access = mkOption {
+        type = types.either
+          (types.listOf (types.enum ["add" "cpw" "delete" "get" "list" "modify"]))
+          (types.enum ["all"]);
+        default = "all";
+        description = "The changes the principal is allowed to make.";
+      };
+      target = mkOption {
+        type = types.str;
+        default = "*";
+        description = "The principals that 'access' applies to.";
+      };
+    };
+  };
+
+  realm = {
+    options = {
+      acl = mkOption {
+        type = types.listOf (types.submodule aclEntry);
+        default = [
+          { principal = "*/admin"; access = "all"; }
+          { principal = "admin"; access = "all"; }
+        ];
+        description = ''
+          The privileges granted to a user.
+        '';
+      };
+    };
+  };
+in
+
+{
+  imports = [
+    ./mit.nix
+    ./heimdal.nix
+  ];
+
+  ###### interface
+  options = {
+    services.kerberos_server = {
+      enable = mkOption {
+        default = false;
+        description = ''
+          Enable the kerberos authentification server.
+        '';
+      };
+
+      realms = mkOption {
+        type = types.attrsOf (types.submodule realm);
+        description = ''
+          The realm(s) to serve keys for.
+        '';
+      };
+    };
+  };
+
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+    environment.systemPackages = [ kerberos ];
+  };
+}
diff --git a/nixos/modules/services/system/kerberos/heimdal.nix b/nixos/modules/services/system/kerberos/heimdal.nix
new file mode 100644
index 00000000000..554b1580810
--- /dev/null
+++ b/nixos/modules/services/system/kerberos/heimdal.nix
@@ -0,0 +1,74 @@
+{ pkgs, config, lib, ... } :
+
+let
+  inherit (lib) mkIf concatStringsSep concatMapStrings toList mapAttrs'
+    nameValuePair attrNames attrValues;
+  cfg = config.services.kerberos_server;
+  kerberos = config.krb5.kerberos;
+  stateDir = "/var/heimdal";
+  aclFiles = mapAttrs'
+    (name: {acl, ...}: nameValuePair "${name}.acl" (
+      pkgs.writeText "${name}.acl" (concatMapStrings ((
+        {principal, access, target, ...} :
+        "${principal}\t${concatStringsSep "," (toList access)}\t${target}\n"
+      )) acl)
+    )) cfg.realms;
+
+  kdcConfigs = map (name: ''
+    database = {
+      dbname = ${stateDir}/heimdal
+      acl_file = /etc/heimdal-kdc/${name}.acl
+    }
+  '') (attrNames cfg.realms);
+  kdcConfFile = pkgs.writeText "kdc.conf" ''
+    [kdc]
+    ${concatStringsSep "\n" kdcConfigs}
+  '';
+in
+
+{
+  # No documentation about correct triggers, so guessing at them.
+
+  config = mkIf (cfg.enable && kerberos == pkgs.heimdalFull) {
+    systemd.services.kadmind = {
+      description = "Kerberos Administration Daemon";
+      wantedBy = [ "multi-user.target" ];
+      preStart = ''
+        mkdir -m 0755 -p ${stateDir}
+      '';
+      serviceConfig.ExecStart =
+        "${kerberos}/libexec/heimdal/kadmind --config-file=/etc/heimdal-kdc/kdc.conf";
+      restartTriggers = [ kdcConfFile ] ++ (attrValues aclFiles);
+    };
+
+    systemd.services.kdc = {
+      description = "Key Distribution Center daemon";
+      wantedBy = [ "multi-user.target" ];
+      preStart = ''
+        mkdir -m 0755 -p ${stateDir}
+      '';
+      serviceConfig.ExecStart =
+        "${kerberos}/libexec/heimdal/kdc --config-file=/etc/heimdal-kdc/kdc.conf";
+      restartTriggers = [ kdcConfFile ];
+    };
+
+    systemd.services.kpasswdd = {
+      description = "Kerberos Password Changing daemon";
+      wantedBy = [ "multi-user.target" ];
+      preStart = ''
+        mkdir -m 0755 -p ${stateDir}
+      '';
+      serviceConfig.ExecStart = "${kerberos}/libexec/heimdal/kpasswdd";
+      restartTriggers = [ kdcConfFile ] ++ (attrValues aclFiles);
+    };
+
+    environment.etc = {
+      # Can be set via the --config-file option to KDC
+      "heimdal-kdc/kdc.conf".source = kdcConfFile;
+    } // (
+      mapAttrs'
+      (name: value: nameValuePair "heimdal-kdc/${name}" {source = value;})
+      aclFiles
+    );
+  };
+}
diff --git a/nixos/modules/services/system/kerberos/mit.nix b/nixos/modules/services/system/kerberos/mit.nix
new file mode 100644
index 00000000000..9ff67f64728
--- /dev/null
+++ b/nixos/modules/services/system/kerberos/mit.nix
@@ -0,0 +1,74 @@
+{ pkgs, config, lib, ... } :
+
+let
+  inherit (lib) mkIf concatStrings concatStringsSep concatMapStrings toList
+    mapAttrs' nameValuePair attrNames attrValues;
+  cfg = config.services.kerberos_server;
+  kerberos = config.krb5.kerberos;
+  stateDir = "/var/lib/krb5kdc";
+  PIDFile = "/run/kdc.pid";
+  aclMap = {
+    add = "a"; cpw = "c"; delete = "d"; get = "i"; list = "l"; modify = "m";
+    all = "*";
+  };
+  aclFiles = mapAttrs'
+    (name: {acl, ...}: nameValuePair "${name}.acl" (
+      pkgs.writeText "${name}.acl" (concatMapStrings (
+        {principal, access, target, ...} :
+        let access_code = map (a: aclMap.${a}) (toList access); in
+        "${principal} ${concatStrings access_code} ${target}\n"
+      ) acl)
+    )) cfg.realms;
+  kdcConfigs = map (name: ''
+    ${name} = {
+      acl_file = /etc/krb5kdc/${name}.acl
+    }
+  '') (attrNames cfg.realms);
+  kdcConfFile = pkgs.writeText "kdc.conf" ''
+    [realms]
+    ${concatStringsSep "\n" kdcConfigs}
+  '';
+  env = {
+    # What Debian uses, could possibly link directly to Nix store?
+    KRB5_KDC_PROFILE = "/etc/krb5kdc/kdc.conf";
+  };
+in
+
+{
+  config = mkIf (cfg.enable && kerberos == pkgs.krb5Full) {
+    systemd.services.kadmind = {
+      description = "Kerberos Administration Daemon";
+      wantedBy = [ "multi-user.target" ];
+      preStart = ''
+        mkdir -m 0755 -p ${stateDir}
+      '';
+      serviceConfig.ExecStart = "${kerberos}/bin/kadmind -nofork";
+      restartTriggers = [ kdcConfFile ] ++ (attrValues aclFiles);
+      environment = env;
+    };
+
+    systemd.services.kdc = {
+      description = "Key Distribution Center daemon";
+      wantedBy = [ "multi-user.target" ];
+      preStart = ''
+        mkdir -m 0755 -p ${stateDir}
+      '';
+      serviceConfig = {
+        Type = "forking";
+        PIDFile = PIDFile;
+        ExecStart = "${kerberos}/bin/krb5kdc -P ${PIDFile}";
+      };
+      restartTriggers = [ kdcConfFile ];
+      environment = env;
+    };
+
+    environment.etc = {
+      "krb5kdc/kdc.conf".source = kdcConfFile;
+    } // (
+      mapAttrs'
+      (name: value: nameValuePair "krb5kdc/${name}" {source = value;})
+      aclFiles
+    );
+    environment.variables = env;
+  };
+}