nixpkgs-suyu/modules/services/network-filesystems/samba.nix

211 lines
5.4 KiB
Nix
Raw Normal View History

{ config, pkgs, ... }:
with pkgs.lib;
let
cfg = config.services.samba;
user = "smbguest";
group = "smbguest";
logDir = "/var/log/samba";
privateDir = "/var/samba/private";
inherit (pkgs) samba;
setupScript =
''
mkdir -p /var/lock
if ! test -d /home/smbd ; then
mkdir -p /home/smbd
chown ${user} /home/smbd
chmod a+rwx /home/smbd
fi
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="$(sed -n 's/^.*smb[ ]\+passwd[ ]\+file[ ]\+=[ ]\+\(.*\)/\1/p' ${configFile})"
if [ -n "$passwdFile" ]; then
echo 'INFO: creating directory containing passwd file'
mkdir -p "$(dirname "$passwdFile")"
fi
mkdir -p ${logDir}
mkdir -p ${privateDir}
# The following line is to trigger a restart of the daemons when
# the configuration changes:
# ${configFile}
'';
configFile = pkgs.writeText "smb.conf"
''
[ global ]
log file = ${logDir}/log.%m
private dir = ${privateDir}
${optionalString cfg.syncPasswordsByPam "pam password change = true"}
${if cfg.defaultShare.enable then ''
[default]
path = /home/smbd
read only = ${if cfg.defaultShare.writeable then "no" else "yes"}
guest ok = ${if cfg.defaultShare.guest then "yes" else "no"}
''else ""}
${cfg.extraConfig}
'';
daemonJob = appName: args:
{ name = "samba-${appName}";
description = "Samba Service daemon ${appName}";
startOn = "started samba";
stopOn = "stopping samba-control";
exec = "${samba}/sbin/${appName} ${args}";
};
in
{
###### interface
options = {
# !!! clean up the descriptions.
services.samba = {
enable = mkOption {
default = false;
description = "
Whether to enable the samba server. (to communicate with, and provide windows shares)
use start / stop samba-control to start/stop all daemons.
smbd and nmbd are not shutdown correctly yet. so just pkill them and restart those jobs.
";
};
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 = user
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
";
};
defaultShare = {
enable = mkOption {
description = "Whether to share /home/smbd as 'default'";
default = false;
};
writeable = mkOption {
description = "Whether to allow write access to default share";
default = false;
};
guest = mkOption {
description = "Whether to allow guest access to default share";
default = true;
};
};
};
};
###### implementation
config = mkIf config.services.samba.enable {
users.extraUsers = singleton
{ name = user;
description = "Samba service user";
group = group;
};
users.extraGroups = singleton
{ name = group;
};
# always provide a smb.conf to shut up programs like smbclient and smbspool.
environment.etc = mkAlways (singleton
{ source =
if cfg.enable then configFile
else pkgs.writeText "smb-dummy.conf" "# Samba is disabled.";
target = "samba/smb.conf";
});
# Dummy job to start the real Samba daemons (nmbd, smbd, winbindd).
jobs.sambaControl =
{ name = "samba";
description = "Samba server";
startOn = "started network-interfaces";
stopOn = "stopping network-interfaces";
preStart = setupScript;
};
# nmbd says "standard input is not a socket, assuming -D option",
# but using -i makes it stay in foreground (?)
jobs.nmbd = daemonJob "nmbd" " -i -F";
jobs.smbd = daemonJob "smbd" " -i -F";
jobs.winbindd = daemonJob "winbindd" " -F";
};
}