mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-01-01 02:23:54 +00:00
193 lines
6.2 KiB
Nix
193 lines
6.2 KiB
Nix
import ../../make-test-python.nix (
|
|
{ pkgs, ... }:
|
|
let
|
|
DITRoot = "dc=example,dc=com";
|
|
realm = "EXAMPLE.COM";
|
|
|
|
krb5Package = pkgs.krb5.override { withLdap = true; };
|
|
|
|
# Password used by Kerberos services to bind to their identities
|
|
krbSrvPwd = "kerberos_service_password";
|
|
# Stash file read by Kerberos daemons containing the service password
|
|
# DO NOT DO THIS IN PRODUCTION! The stash file is a fundamental secret!
|
|
krbPwdStash = pkgs.runCommand "krb-pwd-stash" { } ''
|
|
for srv in cn=kadmin,${DITRoot} cn=kdc,${DITRoot}
|
|
do
|
|
echo -e "${krbSrvPwd}\n${krbSrvPwd}" | \
|
|
${krb5Package}/bin/kdb5_ldap_util -r ${realm} stashsrvpw -f $out $srv 2>&1 > /dev/null
|
|
done
|
|
'';
|
|
|
|
# The LDAP schema for Kerberos 5 objects is part of the source distribution of Kerberos 5
|
|
krbLdapSchema = pkgs.runCommand "krb-ldap-schema" { } ''
|
|
tar -Oxf ${krb5Package.src} \
|
|
${krb5Package.sourceRoot}/plugins/kdb/ldap/libkdb_ldap/kerberos.openldap.ldif > $out
|
|
'';
|
|
|
|
# Initial LDAP tree containing only the Kerberos services
|
|
ldapDIT = ''
|
|
dn: ${DITRoot}
|
|
objectClass: organization
|
|
objectClass: dcObject
|
|
dc: example
|
|
o: Example Company
|
|
|
|
dn: cn=kdc,${DITRoot}
|
|
objectClass: krbKdcService
|
|
objectClass: simpleSecurityObject
|
|
cn: kdc
|
|
userPassword: ${krbSrvPwd}
|
|
|
|
dn: cn=kadmin,${DITRoot}
|
|
objectClass: krbAdmService
|
|
objectClass: simpleSecurityObject
|
|
cn: kadmin
|
|
userPassword: ${krbSrvPwd}
|
|
'';
|
|
|
|
rootDnPwd = "ldap_root_password";
|
|
in
|
|
{
|
|
name = "kerberos_server-mit-ldap";
|
|
|
|
nodes.machine =
|
|
{ pkgs, ... }:
|
|
{
|
|
|
|
services.openldap = {
|
|
enable = true;
|
|
urlList = [
|
|
"ldapi:///"
|
|
"ldap://"
|
|
];
|
|
declarativeContents."${DITRoot}" = ldapDIT;
|
|
settings = {
|
|
children = {
|
|
"cn=schema".includes = [
|
|
"${pkgs.openldap}/etc/schema/core.ldif"
|
|
"${pkgs.openldap}/etc/schema/cosine.ldif"
|
|
"${pkgs.openldap}/etc/schema/inetorgperson.ldif"
|
|
"${pkgs.openldap}/etc/schema/nis.ldif"
|
|
"${krbLdapSchema}"
|
|
];
|
|
"olcDatabase={0}config" = {
|
|
attrs = {
|
|
objectClass = [ "olcDatabaseConfig" ];
|
|
olcDatabase = "{0}config";
|
|
};
|
|
};
|
|
"olcDatabase={1}mdb" = {
|
|
attrs = {
|
|
objectClass = [
|
|
"olcDatabaseConfig"
|
|
"olcMdbConfig"
|
|
];
|
|
olcDatabase = "{1}mdb";
|
|
olcDbDirectory = "/var/lib/openldap/db";
|
|
olcSuffix = DITRoot;
|
|
olcRootDN = "cn=root,${DITRoot}";
|
|
olcRootPW = rootDnPwd;
|
|
# A tiny but realistic ACL
|
|
olcAccess = [
|
|
''
|
|
to attrs=userPassword
|
|
by anonymous auth
|
|
by * none''
|
|
''
|
|
to dn.subtree="cn=${realm},cn=realms,${DITRoot}"
|
|
by dn.exact="cn=kdc,${DITRoot}" write
|
|
by dn.exact="cn=kadmin,${DITRoot}" write
|
|
by * none''
|
|
''
|
|
to *
|
|
by * read''
|
|
];
|
|
};
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
services.kerberos_server = {
|
|
enable = true;
|
|
settings = {
|
|
libdefaults.default_realm = realm;
|
|
realms = {
|
|
"${realm}" = {
|
|
acl = [
|
|
{
|
|
principal = "admin";
|
|
access = "all";
|
|
}
|
|
];
|
|
};
|
|
};
|
|
dbmodules = {
|
|
"${realm}" = {
|
|
db_library = "kldap";
|
|
ldap_kerberos_container_dn = "cn=realms,${DITRoot}";
|
|
ldap_kdc_dn = "cn=kdc,${DITRoot}";
|
|
ldap_kadmind_dn = "cn=kadmin,${DITRoot}";
|
|
ldap_service_password_file = toString krbPwdStash;
|
|
ldap_servers = "ldapi:///";
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
security.krb5 = {
|
|
enable = true;
|
|
package = krb5Package;
|
|
settings = {
|
|
libdefaults = {
|
|
default_realm = realm;
|
|
};
|
|
realms = {
|
|
"${realm}" = {
|
|
admin_server = "machine";
|
|
kdc = "machine";
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
users.extraUsers.alice = {
|
|
isNormalUser = true;
|
|
};
|
|
};
|
|
|
|
testScript = ''
|
|
machine.wait_for_unit("openldap.service")
|
|
|
|
with subtest("realm container initialization"):
|
|
machine.succeed(
|
|
# Passing a master key directly avoids the need for a separate master key stash file
|
|
"kdb5_ldap_util -D cn=root,${DITRoot} create -w ${rootDnPwd} -s -P master_key",
|
|
)
|
|
|
|
# These units are bound to fail, as they are started before the directory service is ready
|
|
machine.execute("systemctl restart kadmind.service kdc.service")
|
|
|
|
with subtest("service bind"):
|
|
for unit in ["kadmind", "kdc"]:
|
|
machine.wait_for_unit(f"{unit}.service")
|
|
|
|
with subtest("administration principal initialization"):
|
|
machine.succeed("kadmin.local add_principal -pw admin_pw admin")
|
|
|
|
with subtest("user principal creation and kinit"):
|
|
machine.succeed(
|
|
"kadmin -p admin -w admin_pw addprinc -pw alice_pw alice",
|
|
"echo alice_pw | sudo -u alice kinit",
|
|
)
|
|
# Make extra sure that the user principal actually exists in the directory
|
|
machine.succeed(
|
|
"ldapsearch -x -D cn=root,${DITRoot} -w ${rootDnPwd} \
|
|
-b ${DITRoot} 'krbPrincipalName=alice@${realm}' | grep 'numEntries: 1'"
|
|
)
|
|
'';
|
|
|
|
meta.maintainers = [ pkgs.lib.maintainers.nessdoor ];
|
|
}
|
|
)
|