Skip to content

Commit 005ec27

Browse files
committed
nixos/nixosTests.kerberos: add test suite for LDAP backend
1 parent 0ee34b3 commit 005ec27

File tree

4 files changed

+201
-0
lines changed

4 files changed

+201
-0
lines changed

nixos/tests/kerberos/default.nix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@
44
{
55
mit = import ./mit.nix { inherit system pkgs; };
66
heimdal = import ./heimdal.nix { inherit system pkgs; };
7+
ldap = import ./ldap { inherit system pkgs; };
78
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
system ? builtins.currentSystem,
3+
pkgs ? import ../../../.. { inherit system; },
4+
}:
5+
{
6+
mit = import ./mit.nix { inherit system pkgs; };
7+
}

nixos/tests/kerberos/ldap/mit.nix

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
import ../../make-test-python.nix (
2+
{ pkgs, ... }:
3+
let
4+
DITRoot = "dc=example,dc=com";
5+
realm = "EXAMPLE.COM";
6+
7+
krb5Package = pkgs.krb5.override { withLdap = true; };
8+
9+
# Password used by Kerberos services to bind to their identities
10+
krbSrvPwd = "kerberos_service_password";
11+
# Stash file read by Kerberos daemons containing the service password
12+
# DO NOT DO THIS IN PRODUCTION! The stash file is a fundamental secret!
13+
krbPwdStash = pkgs.runCommand "krb-pwd-stash" { } ''
14+
for srv in cn=kadmin,${DITRoot} cn=kdc,${DITRoot}
15+
do
16+
echo -e "${krbSrvPwd}\n${krbSrvPwd}" | \
17+
${krb5Package}/bin/kdb5_ldap_util -r ${realm} stashsrvpw -f $out $srv 2>&1 > /dev/null
18+
done
19+
'';
20+
21+
# The LDAP schema for Kerberos 5 objects is part of the source distribution of Kerberos 5
22+
krbLdapSchema = pkgs.runCommand "krb-ldap-schema" { } ''
23+
tar -Oxf ${krb5Package.src} \
24+
${krb5Package.sourceRoot}/plugins/kdb/ldap/libkdb_ldap/kerberos.openldap.ldif > $out
25+
'';
26+
27+
# Initial LDAP tree containing only the Kerberos services
28+
ldapDIT = ''
29+
dn: ${DITRoot}
30+
objectClass: organization
31+
objectClass: dcObject
32+
dc: example
33+
o: Example Company
34+
35+
dn: cn=kdc,${DITRoot}
36+
objectClass: krbKdcService
37+
objectClass: simpleSecurityObject
38+
cn: kdc
39+
userPassword: ${krbSrvPwd}
40+
41+
dn: cn=kadmin,${DITRoot}
42+
objectClass: krbAdmService
43+
objectClass: simpleSecurityObject
44+
cn: kadmin
45+
userPassword: ${krbSrvPwd}
46+
'';
47+
48+
rootDnPwd = "ldap_root_password";
49+
in
50+
{
51+
name = "kerberos_server-mit-ldap";
52+
53+
nodes.machine =
54+
{ pkgs, ... }:
55+
{
56+
57+
services.openldap = {
58+
enable = true;
59+
urlList = [
60+
"ldapi:///"
61+
"ldap://"
62+
];
63+
declarativeContents."${DITRoot}" = ldapDIT;
64+
settings = {
65+
children = {
66+
"cn=schema".includes = [
67+
"${pkgs.openldap}/etc/schema/core.ldif"
68+
"${pkgs.openldap}/etc/schema/cosine.ldif"
69+
"${pkgs.openldap}/etc/schema/inetorgperson.ldif"
70+
"${pkgs.openldap}/etc/schema/nis.ldif"
71+
"${krbLdapSchema}"
72+
];
73+
"olcDatabase={0}config" = {
74+
attrs = {
75+
objectClass = [ "olcDatabaseConfig" ];
76+
olcDatabase = "{0}config";
77+
};
78+
};
79+
"olcDatabase={1}mdb" = {
80+
attrs = {
81+
objectClass = [
82+
"olcDatabaseConfig"
83+
"olcMdbConfig"
84+
];
85+
olcDatabase = "{1}mdb";
86+
olcDbDirectory = "/var/lib/openldap/db";
87+
olcSuffix = DITRoot;
88+
olcRootDN = "cn=root,${DITRoot}";
89+
olcRootPW = rootDnPwd;
90+
# A tiny but realistic ACL
91+
olcAccess = [
92+
''
93+
to attrs=userPassword
94+
by anonymous auth
95+
by * none''
96+
''
97+
to dn.subtree="cn=${realm},cn=realms,${DITRoot}"
98+
by dn.exact="cn=kdc,${DITRoot}" write
99+
by dn.exact="cn=kadmin,${DITRoot}" write
100+
by * none''
101+
''
102+
to *
103+
by * read''
104+
];
105+
};
106+
};
107+
};
108+
};
109+
};
110+
111+
services.kerberos_server = {
112+
enable = true;
113+
settings = {
114+
libdefaults.default_realm = realm;
115+
realms = {
116+
"${realm}" = {
117+
acl = [
118+
{
119+
principal = "admin";
120+
access = "all";
121+
}
122+
];
123+
};
124+
};
125+
dbmodules = {
126+
"${realm}" = {
127+
db_library = "kldap";
128+
ldap_kerberos_container_dn = "cn=realms,${DITRoot}";
129+
ldap_kdc_dn = "cn=kdc,${DITRoot}";
130+
ldap_kadmind_dn = "cn=kadmin,${DITRoot}";
131+
ldap_service_password_file = toString krbPwdStash;
132+
ldap_servers = "ldapi:///";
133+
};
134+
};
135+
};
136+
};
137+
138+
security.krb5 = {
139+
enable = true;
140+
package = krb5Package;
141+
settings = {
142+
libdefaults = {
143+
default_realm = realm;
144+
};
145+
realms = {
146+
"${realm}" = {
147+
admin_server = "machine";
148+
kdc = "machine";
149+
};
150+
};
151+
};
152+
};
153+
154+
users.extraUsers.alice = {
155+
isNormalUser = true;
156+
};
157+
};
158+
159+
testScript = ''
160+
machine.wait_for_unit("openldap.service")
161+
162+
with subtest("realm container initialization"):
163+
machine.succeed(
164+
# Passing a master key directly avoids the need for a separate master key stash file
165+
"kdb5_ldap_util -D cn=root,${DITRoot} create -w ${rootDnPwd} -s -P master_key",
166+
)
167+
168+
# These units are bound to fail, as they are started before the directory service is ready
169+
machine.execute("systemctl restart kadmind.service kdc.service")
170+
171+
with subtest("service bind"):
172+
for unit in ["kadmind", "kdc"]:
173+
machine.wait_for_unit(f"{unit}.service")
174+
175+
with subtest("administration principal initialization"):
176+
machine.succeed("kadmin.local add_principal -pw admin_pw admin")
177+
178+
with subtest("user principal creation and kinit"):
179+
machine.succeed(
180+
"kadmin -p admin -w admin_pw addprinc -pw alice_pw alice",
181+
"echo alice_pw | sudo -u alice kinit",
182+
)
183+
# Make extra sure that the user principal actually exists in the directory
184+
machine.succeed(
185+
"ldapsearch -x -D cn=root,${DITRoot} -w ${rootDnPwd} \
186+
-b ${DITRoot} 'krbPrincipalName=alice@${realm}' | grep 'numEntries: 1'"
187+
)
188+
'';
189+
190+
meta.maintainers = [ pkgs.lib.maintainers.nessdoor ];
191+
}
192+
)

pkgs/by-name/op/openldap/package.nix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ stdenv.mkDerivation rec {
129129

130130
passthru.tests = {
131131
inherit (nixosTests) openldap;
132+
kerberosWithLdap = nixosTests.kerberos.ldap;
132133
};
133134

134135
meta = with lib; {

0 commit comments

Comments
 (0)