nixos/users.mysql: remove with lib;

This commit is contained in:
Felix Buehler 2024-08-27 20:42:48 +02:00
parent 8cf91e2c5b
commit 15b6c50fa9

View file

@ -1,47 +1,44 @@
{ config, pkgs, lib, ... }: { config, pkgs, lib, ... }:
with lib;
let let
cfg = config.users.mysql; cfg = config.users.mysql;
in in
{ {
meta.maintainers = [ maintainers.netali ]; meta.maintainers = [ lib.maintainers.netali ];
options = { options = {
users.mysql = { users.mysql = {
enable = mkEnableOption "authentication against a MySQL/MariaDB database"; enable = lib.mkEnableOption "authentication against a MySQL/MariaDB database";
host = mkOption { host = lib.mkOption {
type = types.str; type = lib.types.str;
example = "localhost"; example = "localhost";
description = "The hostname of the MySQL/MariaDB server"; description = "The hostname of the MySQL/MariaDB server";
}; };
database = mkOption { database = lib.mkOption {
type = types.str; type = lib.types.str;
example = "auth"; example = "auth";
description = "The name of the database containing the users"; description = "The name of the database containing the users";
}; };
user = mkOption { user = lib.mkOption {
type = types.str; type = lib.types.str;
example = "nss-user"; example = "nss-user";
description = "The username to use when connecting to the database"; description = "The username to use when connecting to the database";
}; };
passwordFile = mkOption { passwordFile = lib.mkOption {
type = types.path; type = lib.types.path;
example = "/run/secrets/mysql-auth-db-passwd"; example = "/run/secrets/mysql-auth-db-passwd";
description = "The path to the file containing the password for the user"; description = "The path to the file containing the password for the user";
}; };
pam = mkOption { pam = lib.mkOption {
description = "Settings for `pam_mysql`"; description = "Settings for `pam_mysql`";
type = types.submodule { type = lib.types.submodule {
options = { options = {
table = mkOption { table = lib.mkOption {
type = types.str; type = lib.types.str;
example = "users"; example = "users";
description = "The name of table that maps unique login names to the passwords."; description = "The name of table that maps unique login names to the passwords.";
}; };
updateTable = mkOption { updateTable = lib.mkOption {
type = types.nullOr types.str; type = lib.types.nullOr lib.types.str;
default = null; default = null;
example = "users_updates"; example = "users_updates";
description = '' description = ''
@ -49,18 +46,18 @@ in
of the `table` option will be used instead. of the `table` option will be used instead.
''; '';
}; };
userColumn = mkOption { userColumn = lib.mkOption {
type = types.str; type = lib.types.str;
example = "username"; example = "username";
description = "The name of the column that contains a unix login name."; description = "The name of the column that contains a unix login name.";
}; };
passwordColumn = mkOption { passwordColumn = lib.mkOption {
type = types.str; type = lib.types.str;
example = "password"; example = "password";
description = "The name of the column that contains a (encrypted) password string."; description = "The name of the column that contains a (encrypted) password string.";
}; };
statusColumn = mkOption { statusColumn = lib.mkOption {
type = types.nullOr types.str; type = lib.types.nullOr lib.types.str;
default = null; default = null;
example = "status"; example = "status";
description = '' description = ''
@ -79,9 +76,9 @@ in
This ends up requiring that the user enter a new password. This ends up requiring that the user enter a new password.
''; '';
}; };
passwordCrypt = mkOption { passwordCrypt = lib.mkOption {
example = "2"; example = "2";
type = types.enum [ type = lib.types.enum [
"0" "plain" "0" "plain"
"1" "Y" "1" "Y"
"2" "mysql" "2" "mysql"
@ -121,28 +118,28 @@ in
Use sha256 hashed passwords. Use sha256 hashed passwords.
''; '';
}; };
cryptDefault = mkOption { cryptDefault = lib.mkOption {
type = types.nullOr (types.enum [ "md5" "sha256" "sha512" "blowfish" ]); type = lib.types.nullOr (lib.types.enum [ "md5" "sha256" "sha512" "blowfish" ]);
default = null; default = null;
example = "blowfish"; example = "blowfish";
description = "The default encryption method to use for `passwordCrypt = 1`."; description = "The default encryption method to use for `passwordCrypt = 1`.";
}; };
where = mkOption { where = lib.mkOption {
type = types.nullOr types.str; type = lib.types.nullOr lib.types.str;
default = null; default = null;
example = "host.name='web' AND user.active=1"; example = "host.name='web' AND user.active=1";
description = "Additional criteria for the query."; description = "Additional criteria for the query.";
}; };
verbose = mkOption { verbose = lib.mkOption {
type = types.bool; type = lib.types.bool;
default = false; default = false;
description = '' description = ''
If enabled, produces logs with detailed messages that describes what If enabled, produces logs with detailed messages that describes what
`pam_mysql` is doing. May be useful for debugging. `pam_mysql` is doing. May be useful for debugging.
''; '';
}; };
disconnectEveryOperation = mkOption { disconnectEveryOperation = lib.mkOption {
type = types.bool; type = lib.types.bool;
default = false; default = false;
description = '' description = ''
By default, `pam_mysql` keeps the connection to the MySQL By default, `pam_mysql` keeps the connection to the MySQL
@ -152,34 +149,34 @@ in
''; '';
}; };
logging = { logging = {
enable = mkOption { enable = lib.mkOption {
type = types.bool; type = lib.types.bool;
default = false; default = false;
description = "Enables logging of authentication attempts in the MySQL database."; description = "Enables logging of authentication attempts in the MySQL database.";
}; };
table = mkOption { table = lib.mkOption {
type = types.str; type = lib.types.str;
example = "logs"; example = "logs";
description = "The name of the table to which logs are written."; description = "The name of the table to which logs are written.";
}; };
msgColumn = mkOption { msgColumn = lib.mkOption {
type = types.str; type = lib.types.str;
example = "msg"; example = "msg";
description = '' description = ''
The name of the column in the log table to which the description The name of the column in the log table to which the description
of the performed operation is stored. of the performed operation is stored.
''; '';
}; };
userColumn = mkOption { userColumn = lib.mkOption {
type = types.str; type = lib.types.str;
example = "user"; example = "user";
description = '' description = ''
The name of the column in the log table to which the name of the The name of the column in the log table to which the name of the
user being authenticated is stored. user being authenticated is stored.
''; '';
}; };
pidColumn = mkOption { pidColumn = lib.mkOption {
type = types.str; type = lib.types.str;
example = "pid"; example = "pid";
description = '' description = ''
The name of the column in the log table to which the pid of the The name of the column in the log table to which the pid of the
@ -187,16 +184,16 @@ in
service is stored. service is stored.
''; '';
}; };
hostColumn = mkOption { hostColumn = lib.mkOption {
type = types.str; type = lib.types.str;
example = "host"; example = "host";
description = '' description = ''
The name of the column in the log table to which the name of the user The name of the column in the log table to which the name of the user
being authenticated is stored. being authenticated is stored.
''; '';
}; };
rHostColumn = mkOption { rHostColumn = lib.mkOption {
type = types.str; type = lib.types.str;
example = "rhost"; example = "rhost";
description = '' description = ''
The name of the column in the log table to which the name of the remote The name of the column in the log table to which the name of the remote
@ -204,8 +201,8 @@ in
set by the PAM-aware application with `pam_set_item(PAM_RHOST)`. set by the PAM-aware application with `pam_set_item(PAM_RHOST)`.
''; '';
}; };
timeColumn = mkOption { timeColumn = lib.mkOption {
type = types.str; type = lib.types.str;
example = "timestamp"; example = "timestamp";
description = '' description = ''
The name of the column in the log table to which the timestamp of the The name of the column in the log table to which the timestamp of the
@ -216,19 +213,19 @@ in
}; };
}; };
}; };
nss = mkOption { nss = lib.mkOption {
description = '' description = ''
Settings for `libnss-mysql`. Settings for `libnss-mysql`.
All examples are from the [minimal example](https://github.com/saknopper/libnss-mysql/tree/master/sample/minimal) All examples are from the [minimal example](https://github.com/saknopper/libnss-mysql/tree/master/sample/minimal)
of `libnss-mysql`, but they are modified with NixOS paths for bash. of `libnss-mysql`, but they are modified with NixOS paths for bash.
''; '';
type = types.submodule { type = lib.types.submodule {
options = { options = {
getpwnam = mkOption { getpwnam = lib.mkOption {
type = types.nullOr types.str; type = lib.types.nullOr lib.types.str;
default = null; default = null;
example = literalExpression '' example = lib.literalExpression ''
SELECT username,'x',uid,'5000','MySQL User', CONCAT('/home/',username),'/run/sw/current-system/bin/bash' \ SELECT username,'x',uid,'5000','MySQL User', CONCAT('/home/',username),'/run/sw/current-system/bin/bash' \
FROM users \ FROM users \
WHERE username='%1$s' \ WHERE username='%1$s' \
@ -239,10 +236,10 @@ in
syscall. syscall.
''; '';
}; };
getpwuid = mkOption { getpwuid = lib.mkOption {
type = types.nullOr types.str; type = lib.types.nullOr lib.types.str;
default = null; default = null;
example = literalExpression '' example = lib.literalExpression ''
SELECT username,'x',uid,'5000','MySQL User', CONCAT('/home/',username),'/run/sw/current-system/bin/bash' \ SELECT username,'x',uid,'5000','MySQL User', CONCAT('/home/',username),'/run/sw/current-system/bin/bash' \
FROM users \ FROM users \
WHERE uid='%1$u' \ WHERE uid='%1$u' \
@ -253,10 +250,10 @@ in
syscall. syscall.
''; '';
}; };
getspnam = mkOption { getspnam = lib.mkOption {
type = types.nullOr types.str; type = lib.types.nullOr lib.types.str;
default = null; default = null;
example = literalExpression '' example = lib.literalExpression ''
SELECT username,password,'1','0','99999','0','0','-1','0' \ SELECT username,password,'1','0','99999','0','0','-1','0' \
FROM users \ FROM users \
WHERE username='%1$s' \ WHERE username='%1$s' \
@ -267,10 +264,10 @@ in
syscall. syscall.
''; '';
}; };
getpwent = mkOption { getpwent = lib.mkOption {
type = types.nullOr types.str; type = lib.types.nullOr lib.types.str;
default = null; default = null;
example = literalExpression '' example = lib.literalExpression ''
SELECT username,'x',uid,'5000','MySQL User', CONCAT('/home/',username),'/run/sw/current-system/bin/bash' FROM users SELECT username,'x',uid,'5000','MySQL User', CONCAT('/home/',username),'/run/sw/current-system/bin/bash' FROM users
''; '';
description = '' description = ''
@ -278,10 +275,10 @@ in
syscall. syscall.
''; '';
}; };
getspent = mkOption { getspent = lib.mkOption {
type = types.nullOr types.str; type = lib.types.nullOr lib.types.str;
default = null; default = null;
example = literalExpression '' example = lib.literalExpression ''
SELECT username,password,'1','0','99999','0','0','-1','0' FROM users SELECT username,password,'1','0','99999','0','0','-1','0' FROM users
''; '';
description = '' description = ''
@ -289,10 +286,10 @@ in
syscall. syscall.
''; '';
}; };
getgrnam = mkOption { getgrnam = lib.mkOption {
type = types.nullOr types.str; type = lib.types.nullOr lib.types.str;
default = null; default = null;
example = literalExpression '' example = lib.literalExpression ''
SELECT name,password,gid FROM groups WHERE name='%1$s' LIMIT 1 SELECT name,password,gid FROM groups WHERE name='%1$s' LIMIT 1
''; '';
description = '' description = ''
@ -300,10 +297,10 @@ in
syscall. syscall.
''; '';
}; };
getgrgid = mkOption { getgrgid = lib.mkOption {
type = types.nullOr types.str; type = lib.types.nullOr lib.types.str;
default = null; default = null;
example = literalExpression '' example = lib.literalExpression ''
SELECT name,password,gid FROM groups WHERE gid='%1$u' LIMIT 1 SELECT name,password,gid FROM groups WHERE gid='%1$u' LIMIT 1
''; '';
description = '' description = ''
@ -311,10 +308,10 @@ in
syscall. syscall.
''; '';
}; };
getgrent = mkOption { getgrent = lib.mkOption {
type = types.nullOr types.str; type = lib.types.nullOr lib.types.str;
default = null; default = null;
example = literalExpression '' example = lib.literalExpression ''
SELECT name,password,gid FROM groups SELECT name,password,gid FROM groups
''; '';
description = '' description = ''
@ -322,10 +319,10 @@ in
syscall. syscall.
''; '';
}; };
memsbygid = mkOption { memsbygid = lib.mkOption {
type = types.nullOr types.str; type = lib.types.nullOr lib.types.str;
default = null; default = null;
example = literalExpression '' example = lib.literalExpression ''
SELECT username FROM grouplist WHERE gid='%1$u' SELECT username FROM grouplist WHERE gid='%1$u'
''; '';
description = '' description = ''
@ -333,10 +330,10 @@ in
syscall. syscall.
''; '';
}; };
gidsbymem = mkOption { gidsbymem = lib.mkOption {
type = types.nullOr types.str; type = lib.types.nullOr lib.types.str;
default = null; default = null;
example = literalExpression '' example = lib.literalExpression ''
SELECT gid FROM grouplist WHERE username='%1$s' SELECT gid FROM grouplist WHERE username='%1$s'
''; '';
description = '' description = ''
@ -350,7 +347,7 @@ in
}; };
}; };
config = mkIf cfg.enable { config = lib.mkIf cfg.enable {
system.nssModules = [ pkgs.libnss-mysql ]; system.nssModules = [ pkgs.libnss-mysql ];
system.nssDatabases.shadow = [ "mysql" ]; system.nssDatabases.shadow = [ "mysql" ];
system.nssDatabases.group = [ "mysql" ]; system.nssDatabases.group = [ "mysql" ];
@ -371,15 +368,15 @@ in
users.password_crypt=${cfg.pam.passwordCrypt} users.password_crypt=${cfg.pam.passwordCrypt}
users.disconnect_every_operation=${if cfg.pam.disconnectEveryOperation then "1" else "0"} users.disconnect_every_operation=${if cfg.pam.disconnectEveryOperation then "1" else "0"}
verbose=${if cfg.pam.verbose then "1" else "0"} verbose=${if cfg.pam.verbose then "1" else "0"}
'' + optionalString (cfg.pam.cryptDefault != null) '' '' + lib.optionalString (cfg.pam.cryptDefault != null) ''
users.use_${cfg.pam.cryptDefault}=1 users.use_${cfg.pam.cryptDefault}=1
'' + optionalString (cfg.pam.where != null) '' '' + lib.optionalString (cfg.pam.where != null) ''
users.where_clause=${cfg.pam.where} users.where_clause=${cfg.pam.where}
'' + optionalString (cfg.pam.statusColumn != null) '' '' + lib.optionalString (cfg.pam.statusColumn != null) ''
users.status_column=${cfg.pam.statusColumn} users.status_column=${cfg.pam.statusColumn}
'' + optionalString (cfg.pam.updateTable != null) '' '' + lib.optionalString (cfg.pam.updateTable != null) ''
users.update_table=${cfg.pam.updateTable} users.update_table=${cfg.pam.updateTable}
'' + optionalString cfg.pam.logging.enable '' '' + lib.optionalString cfg.pam.logging.enable ''
log.enabled=true log.enabled=true
log.table=${cfg.pam.logging.table} log.table=${cfg.pam.logging.table}
log.message_column=${cfg.pam.logging.msgColumn} log.message_column=${cfg.pam.logging.msgColumn}
@ -395,25 +392,25 @@ in
mode = "0600"; mode = "0600";
user = config.services.nscd.user; user = config.services.nscd.user;
group = config.services.nscd.group; group = config.services.nscd.group;
text = optionalString (cfg.nss.getpwnam != null) '' text = lib.optionalString (cfg.nss.getpwnam != null) ''
getpwnam ${cfg.nss.getpwnam} getpwnam ${cfg.nss.getpwnam}
'' + optionalString (cfg.nss.getpwuid != null) '' '' + lib.optionalString (cfg.nss.getpwuid != null) ''
getpwuid ${cfg.nss.getpwuid} getpwuid ${cfg.nss.getpwuid}
'' + optionalString (cfg.nss.getspnam != null) '' '' + lib.optionalString (cfg.nss.getspnam != null) ''
getspnam ${cfg.nss.getspnam} getspnam ${cfg.nss.getspnam}
'' + optionalString (cfg.nss.getpwent != null) '' '' + lib.optionalString (cfg.nss.getpwent != null) ''
getpwent ${cfg.nss.getpwent} getpwent ${cfg.nss.getpwent}
'' + optionalString (cfg.nss.getspent != null) '' '' + lib.optionalString (cfg.nss.getspent != null) ''
getspent ${cfg.nss.getspent} getspent ${cfg.nss.getspent}
'' + optionalString (cfg.nss.getgrnam != null) '' '' + lib.optionalString (cfg.nss.getgrnam != null) ''
getgrnam ${cfg.nss.getgrnam} getgrnam ${cfg.nss.getgrnam}
'' + optionalString (cfg.nss.getgrgid != null) '' '' + lib.optionalString (cfg.nss.getgrgid != null) ''
getgrgid ${cfg.nss.getgrgid} getgrgid ${cfg.nss.getgrgid}
'' + optionalString (cfg.nss.getgrent != null) '' '' + lib.optionalString (cfg.nss.getgrent != null) ''
getgrent ${cfg.nss.getgrent} getgrent ${cfg.nss.getgrent}
'' + optionalString (cfg.nss.memsbygid != null) '' '' + lib.optionalString (cfg.nss.memsbygid != null) ''
memsbygid ${cfg.nss.memsbygid} memsbygid ${cfg.nss.memsbygid}
'' + optionalString (cfg.nss.gidsbymem != null) '' '' + lib.optionalString (cfg.nss.gidsbymem != null) ''
gidsbymem ${cfg.nss.gidsbymem} gidsbymem ${cfg.nss.gidsbymem}
'' + '' '' + ''
host ${cfg.host} host ${cfg.host}