1{ config, lib, pkgs, utils, ... }:
2
3let
4 cfg = config.services.lldap;
5 format = pkgs.formats.toml { };
6in
7{
8 options.services.lldap = with lib; {
9 enable = mkEnableOption (mdDoc "lldap");
10
11 package = mkPackageOptionMD pkgs "lldap" { };
12
13 environment = mkOption {
14 type = with types; attrsOf str;
15 default = { };
16 example = {
17 LLDAP_JWT_SECRET_FILE = "/run/lldap/jwt_secret";
18 LLDAP_LDAP_USER_PASS_FILE = "/run/lldap/user_password";
19 };
20 description = lib.mdDoc ''
21 Environment variables passed to the service.
22 Any config option name prefixed with `LLDAP_` takes priority over the one in the configuration file.
23 '';
24 };
25
26 environmentFile = mkOption {
27 type = types.nullOr types.path;
28 default = null;
29 description = lib.mdDoc ''
30 Environment file as defined in {manpage}`systemd.exec(5)` passed to the service.
31 '';
32 };
33
34 settings = mkOption {
35 description = mdDoc ''
36 Free-form settings written directly to the `lldap_config.toml` file.
37 Refer to <https://github.com/lldap/lldap/blob/main/lldap_config.docker_template.toml> for supported values.
38 '';
39
40 default = { };
41
42 type = types.submodule {
43 freeformType = format.type;
44 options = {
45 ldap_host = mkOption {
46 type = types.str;
47 description = mdDoc "The host address that the LDAP server will be bound to.";
48 default = "::";
49 };
50
51 ldap_port = mkOption {
52 type = types.port;
53 description = mdDoc "The port on which to have the LDAP server.";
54 default = 3890;
55 };
56
57 http_host = mkOption {
58 type = types.str;
59 description = mdDoc "The host address that the HTTP server will be bound to.";
60 default = "::";
61 };
62
63 http_port = mkOption {
64 type = types.port;
65 description = mdDoc "The port on which to have the HTTP server, for user login and administration.";
66 default = 17170;
67 };
68
69 http_url = mkOption {
70 type = types.str;
71 description = mdDoc "The public URL of the server, for password reset links.";
72 default = "http://localhost";
73 };
74
75 ldap_base_dn = mkOption {
76 type = types.str;
77 description = mdDoc "Base DN for LDAP.";
78 example = "dc=example,dc=com";
79 };
80
81 ldap_user_dn = mkOption {
82 type = types.str;
83 description = mdDoc "Admin username";
84 default = "admin";
85 };
86
87 ldap_user_email = mkOption {
88 type = types.str;
89 description = mdDoc "Admin email.";
90 default = "admin@example.com";
91 };
92
93 database_url = mkOption {
94 type = types.str;
95 description = mdDoc "Database URL.";
96 default = "sqlite://./users.db?mode=rwc";
97 example = "postgres://postgres-user:password@postgres-server/my-database";
98 };
99 };
100 };
101 };
102 };
103
104 config = lib.mkIf cfg.enable {
105 systemd.services.lldap = {
106 description = "Lightweight LDAP server (lldap)";
107 after = [ "network-online.target" ];
108 wantedBy = [ "multi-user.target" ];
109 serviceConfig = {
110 ExecStart = "${lib.getExe cfg.package} run --config-file ${format.generate "lldap_config.toml" cfg.settings}";
111 StateDirectory = "lldap";
112 WorkingDirectory = "%S/lldap";
113 User = "lldap";
114 Group = "lldap";
115 DynamicUser = true;
116 EnvironmentFile = lib.mkIf (cfg.environmentFile != null) cfg.environmentFile;
117 };
118 inherit (cfg) environment;
119 };
120 };
121}