nixpkgs/nixos/modules/services/network-filesystems/samba.nix
2015-01-03 21:45:16 -08:00

244 lines
6.5 KiB
Nix

{ config, lib, pkgs, ... }:
with lib;
let
cfg = config.services.samba;
logDir = "/var/log/samba";
privateDir = "/var/samba/private";
samba = cfg.package;
setupScript =
''
if ! test -d /var/samba ; then
mkdir -p /var/samba/locks /var/samba/cores/nmbd /var/samba/cores/smbd /var/samba/cores/winbindd
fi
passwdFile="$(${pkgs.gnused}/bin/sed -n 's/^.*smb[ ]\+passwd[ ]\+file[ ]\+=[ ]\+\(.*\)/\1/p' ${configFile})"
if [ -n "$passwdFile" ]; then
echo 'INFO: [samba] creating directory containing passwd file'
mkdir -p "$(dirname "$passwdFile")"
fi
mkdir -p ${logDir}
mkdir -p ${privateDir}
'';
shareConfig = name:
let share = getAttr name cfg.shares; in
"[${name}]\n " + (toString (
map
(key: "${key} = ${toString (getAttr key share)}\n")
(attrNames share)
));
configFile = pkgs.writeText "smb.conf"
(if cfg.configText != null then cfg.configText else
''
[ global ]
log file = ${logDir}/log.%m
private dir = ${privateDir}
${optionalString cfg.syncPasswordsByPam "pam password change = true"}
${cfg.extraConfig}
${toString (map shareConfig (attrNames cfg.shares))}
'');
# This may include nss_ldap, needed for samba if it has to use ldap.
nssModulesPath = config.system.nssModules.path;
daemonService = appName: args:
{ description = "Samba Service Daemon ${appName}";
requiredBy = [ "samba.target" ];
partOf = [ "samba.target" ];
environment = {
LD_LIBRARY_PATH = nssModulesPath;
LOCALE_ARCHIVE = "/run/current-system/sw/lib/locale/locale-archive";
};
serviceConfig = {
ExecStart = "${samba}/sbin/${appName} ${args}";
ExecReload = "${pkgs.coreutils}/bin/kill -HUP $MAINPID";
};
restartTriggers = [ configFile ];
};
in
{
###### interface
options = {
# !!! clean up the descriptions.
services.samba = {
enable = mkOption {
default = false;
description = "
Whether to enable Samba, which provides file and print
services to Windows clients through the SMB/CIFS protocol.
";
};
package = mkOption {
default = pkgs.samba;
example = pkgs.samba4;
description = ''
Defines which package should be used for the samba server.
'';
};
syncPasswordsByPam = mkOption {
default = false;
description = "
enabling this will add a line directly after pam_unix.so.
Whenever a password is changed the samba password will be updated as well.
However you still yave to add the samba password once using smbpasswd -a user
If you don't want to maintain an extra pwd database you still can send plain text
passwords which is not secure.
";
};
extraConfig = mkOption {
# !!! Bad default.
default = ''
# [global] continuing global section here, section is started by nix to set pids etc
smb passwd file = /etc/samba/passwd
# is this useful ?
domain master = auto
encrypt passwords = Yes
client plaintext auth = No
# yes: if you use this you probably also want to enable syncPasswordsByPam
# no: You can still use the pam password database. However
# passwords will be sent plain text on network (discouraged)
workgroup = Users
server string = %h
comment = Samba
log file = /var/log/samba/log.%m
log level = 10
max log size = 50000
security = ${cfg.securityType}
client lanman auth = Yes
dns proxy = no
invalid users = root
passdb backend = tdbsam
passwd program = /usr/bin/passwd %u
'';
description = "
additional global section and extra section lines go in here.
";
};
configFile = mkOption {
description = "
internal use to pass filepath to samba pam module
";
};
configText = mkOption {
type = types.nullOr types.lines;
default = null;
description = "
Verbatim contents of smb.conf. If null (default), use the
autogenerated file from NixOS instead.
";
};
securityType = mkOption {
description = "Samba security type";
default = "user";
example = "share";
};
nsswins = mkOption {
default = false;
type = types.uniq types.bool;
description = ''
Whether to enable the WINS NSS (Name Service Switch) plug-in.
Enabling it allows applications to resolve WINS/NetBIOS names (a.k.a.
Windows machine names) by transparently querying the winbindd daemon.
'';
};
shares = mkOption {
default = {};
description =
''
A set describing shared resources.
See <command>man smb.conf</command> for options.
'';
type = types.attrsOf (types.attrsOf types.str);
example =
{ srv =
{ path = "/srv";
"read only" = "yes";
comment = "Public samba share.";
};
};
};
};
};
###### implementation
config = mkMerge
[ { # Always provide a smb.conf to shut up programs like smbclient and smbspool.
environment.etc = singleton
{ source =
if cfg.enable then configFile
else pkgs.writeText "smb-dummy.conf" "# Samba is disabled.";
target = "samba/smb.conf";
};
}
(mkIf config.services.samba.enable {
system.nssModules = optional cfg.nsswins samba;
systemd = {
targets.samba = {
description = "Samba Server";
requires = [ "samba-setup.service" ];
after = [ "samba-setup.service" "network.target" ];
wantedBy = [ "multi-user.target" ];
};
services = {
"samba-nmbd" = daemonService "nmbd" "-F";
"samba-smbd" = daemonService "smbd" "-F";
"samba-winbindd" = daemonService "winbindd" "-F";
"samba-setup" = {
description = "Samba Setup Task";
script = setupScript;
unitConfig.RequiresMountsFor = "/var/samba /var/log/samba";
};
};
};
security.pam.services.sambda = {};
})
];
}