diff --git a/nixos/modules/services/network-filesystems/samba.nix b/nixos/modules/services/network-filesystems/samba.nix
index e661d3ff33bf8..c0d12586dec83 100644
--- a/nixos/modules/services/network-filesystems/samba.nix
+++ b/nixos/modules/services/network-filesystems/samba.nix
@@ -101,6 +101,19 @@ in
};
};
+ usershares = {
+ enable = lib.mkEnableOption "user-configurable Samba shares";
+ group = lib.mkOption {
+ type = lib.types.str;
+ default = "samba";
+ description = ''
+ Name of the group members of which will be allowed to create usershares.
+
+ The group will be created automatically.
+ '';
+ };
+ };
+
nsswins = lib.mkEnableOption ''
WINS NSS (Name Service Switch) plug-in.
@@ -308,5 +321,22 @@ in
restartTriggers = [ configFile ];
};
})
+
+ (lib.mkIf (cfg.enable && cfg.usershares.enable) {
+ users.groups.${cfg.usershares.group} = {};
+
+ systemd.tmpfiles.settings."50-samba-usershares"."/var/lib/samba/usershares".d = {
+ user = "root";
+ group = cfg.usershares.group;
+ mode = "1775"; # sticky so users can't delete others' shares
+ };
+
+ # set some reasonable defaults
+ services.samba.settings.global = lib.mkDefault {
+ "usershare path" = "/var/lib/samba/usershares";
+ "usershare max shares" = 100; # high enough to be considered ~unlimited
+ "usershare allow guests" = true;
+ };
+ })
];
}
diff --git a/pkgs/kde/gear/kdenetwork-filesharing/default.nix b/pkgs/kde/gear/kdenetwork-filesharing/default.nix
index 35292d554ef6d..86089c92ced19 100644
--- a/pkgs/kde/gear/kdenetwork-filesharing/default.nix
+++ b/pkgs/kde/gear/kdenetwork-filesharing/default.nix
@@ -1,14 +1,34 @@
{
+ lib,
mkKdeDerivation,
+ substituteAll,
+ samba,
+ shadow,
qtdeclarative,
}:
mkKdeDerivation {
pname = "kdenetwork-filesharing";
- patches = [ ./smbd-path.patch ];
+ patches = [
+ (substituteAll {
+ src = ./dependency-paths.patch;
+ inherit samba;
+ usermod = lib.getExe' shadow "usermod";
+ })
+
+ # Provide a better looking and more NixOS specific Samba hint
+ # Proposed upstream: https://invent.kde.org/network/kdenetwork-filesharing/-/merge_requests/56
+ ./samba-hint.patch
+ ];
extraBuildInputs = [ qtdeclarative ];
# We can't actually install samba via PackageKit, so let's not confuse users any more than we have to
extraCmakeFlags = [ "-DSAMBA_INSTALL=OFF" ];
+
+ # Hardcoded as QStrings, which are UTF-16 so Nix can't pick these up automatically
+ postFixup = ''
+ mkdir -p $out/nix-support
+ echo "${samba} ${shadow}" > $out/nix-support/depends
+ '';
}
diff --git a/pkgs/kde/gear/kdenetwork-filesharing/dependency-paths.patch b/pkgs/kde/gear/kdenetwork-filesharing/dependency-paths.patch
new file mode 100644
index 0000000000000..f5716e663162a
--- /dev/null
+++ b/pkgs/kde/gear/kdenetwork-filesharing/dependency-paths.patch
@@ -0,0 +1,71 @@
+diff --git a/samba/filepropertiesplugin/authhelper.cpp b/samba/filepropertiesplugin/authhelper.cpp
+index 6cbbd90..ae1d696 100644
+--- a/samba/filepropertiesplugin/authhelper.cpp
++++ b/samba/filepropertiesplugin/authhelper.cpp
+@@ -49,7 +49,7 @@ ActionReply AuthHelper::isuserknown(const QVariantMap &args)
+ }
+
+ QProcess p;
+- const auto program = QStringLiteral("pdbedit");
++ const auto program = QStringLiteral("@samba@/bin/pdbedit");
+ const auto arguments = QStringList({QStringLiteral("--debuglevel=0"), QStringLiteral("--user"), username });
+ p.setProgram(program);
+ p.setArguments(arguments);
+@@ -88,7 +88,7 @@ ActionReply AuthHelper::createuser(const QVariantMap &args)
+ }
+
+ QProcess p;
+- p.setProgram(QStringLiteral("smbpasswd"));
++ p.setProgram(QStringLiteral("@samba@/bin/smbpasswd"));
+ p.setArguments({
+ QStringLiteral("-L"), /* local mode */
+ QStringLiteral("-s"), /* read from stdin */
+@@ -152,7 +152,7 @@ ActionReply AuthHelper::addtogroup(const QVariantMap &args)
+ QStringLiteral("-m"),
+ QStringLiteral("{%1}").arg(user.value()) });
+ #elif defined(Q_OS_LINUX) || defined(Q_OS_HURD)
+- p.setProgram(QStringLiteral("/usr/sbin/usermod"));
++ p.setProgram(QStringLiteral("@usermod@"));
+ p.setArguments({
+ QStringLiteral("--append"),
+ QStringLiteral("--groups"),
+diff --git a/samba/filepropertiesplugin/groupmanager.cpp b/samba/filepropertiesplugin/groupmanager.cpp
+index a2ba851..d54f6ce 100644
+--- a/samba/filepropertiesplugin/groupmanager.cpp
++++ b/samba/filepropertiesplugin/groupmanager.cpp
+@@ -18,7 +18,7 @@ GroupManager::GroupManager(QObject *parent)
+ {
+ metaObject()->invokeMethod(this, [this] {
+ auto proc = new QProcess;
+- proc->setProgram(QStringLiteral("testparm"));
++ proc->setProgram(QStringLiteral("@samba@/bin/testparm"));
+ proc->setArguments({QStringLiteral("--debuglevel=0"),
+ QStringLiteral("--suppress-prompt"),
+ QStringLiteral("--verbose"),
+diff --git a/samba/filepropertiesplugin/sambausershareplugin.cpp b/samba/filepropertiesplugin/sambausershareplugin.cpp
+index 4f6642e..86ea121 100644
+--- a/samba/filepropertiesplugin/sambausershareplugin.cpp
++++ b/samba/filepropertiesplugin/sambausershareplugin.cpp
+@@ -112,7 +112,8 @@ SambaUserSharePlugin::SambaUserSharePlugin(QObject *parent)
+ bool SambaUserSharePlugin::isSambaInstalled()
+ {
+ return QFile::exists(QStringLiteral("/usr/sbin/smbd"))
+- || QFile::exists(QStringLiteral("/usr/local/sbin/smbd"));
++ || QFile::exists(QStringLiteral("/usr/local/sbin/smbd"))
++ || QFile::exists(QStringLiteral("/run/current-system/sw/bin/smbd"));
+ }
+
+ void SambaUserSharePlugin::showSambaStatus()
+diff --git a/samba/filepropertiesplugin/usermanager.cpp b/samba/filepropertiesplugin/usermanager.cpp
+index 29238ce..ff20fcb 100644
+--- a/samba/filepropertiesplugin/usermanager.cpp
++++ b/samba/filepropertiesplugin/usermanager.cpp
+@@ -138,7 +138,7 @@ bool UserManager::canManageSamba() const
+ void UserManager::load()
+ {
+ auto proc = new QProcess(this);
+- proc->setProgram(QStringLiteral("testparm"));
++ proc->setProgram(QStringLiteral("@samba@/bin/testparm"));
+ proc->setArguments({
+ QStringLiteral("--debuglevel=0"),
+ QStringLiteral("--suppress-prompt"),
diff --git a/pkgs/kde/gear/kdenetwork-filesharing/samba-hint.patch b/pkgs/kde/gear/kdenetwork-filesharing/samba-hint.patch
new file mode 100644
index 0000000000000..0849639fc49f9
--- /dev/null
+++ b/pkgs/kde/gear/kdenetwork-filesharing/samba-hint.patch
@@ -0,0 +1,35 @@
+diff --git a/samba/filepropertiesplugin/qml/MissingSambaPage.qml b/samba/filepropertiesplugin/qml/MissingSambaPage.qml
+index 327c4a7..9e2eba7 100644
+--- a/samba/filepropertiesplugin/qml/MissingSambaPage.qml
++++ b/samba/filepropertiesplugin/qml/MissingSambaPage.qml
+@@ -6,20 +6,17 @@
+ import QtQuick 2.12
+ import QtQuick.Controls 2.5 as QQC2
+ import QtQuick.Layouts 1.14
+-import org.kde.kirigami 2.4 as Kirigami
+-import org.kde.filesharing.samba 1.0 as Samba
++import org.kde.kirigami as Kirigami
+
+ // When built without packagekit we cannot do auto-installation.
+-ColumnLayout {
+- QQC2.Label {
+- Layout.alignment: Qt.AlignHCenter
+- Layout.fillWidth: true
+- text: xi18nc("@info", "The Samba file sharing service must be installed before folders can be shared.")
+- explanation: i18n("Because this distro does not include PackageKit, we cannot show you a nice \"Install it\" button, and you will have to use your package manager to install the samba server package manually.")
+- wrapMode: Text.Wrap
+- }
+- Item {
+- Layout.alignment: Qt.AlignHCenter
+- Layout.fillHeight: true // space everything up
++Item {
++ Kirigami.PlaceholderMessage {
++ anchors.centerIn: parent
++ width: parent.width - (Kirigami.Units.largeSpacing * 4)
++
++ icon.name: "dialog-error"
++
++ text: xi18nc("@info", "File sharing service unavailable")
++ explanation: i18n("Please enable the `services.samba.enable` and `services.samba.usershares.enable` options in your NixOS configuration.")
+ }
+ }
diff --git a/pkgs/kde/gear/kdenetwork-filesharing/smbd-path.patch b/pkgs/kde/gear/kdenetwork-filesharing/smbd-path.patch
deleted file mode 100644
index e6e4e73333a74..0000000000000
--- a/pkgs/kde/gear/kdenetwork-filesharing/smbd-path.patch
+++ /dev/null
@@ -1,14 +0,0 @@
-diff --git a/samba/filepropertiesplugin/sambausershareplugin.cpp b/samba/filepropertiesplugin/sambausershareplugin.cpp
-index d5c8d77..11c45d4 100644
---- a/samba/filepropertiesplugin/sambausershareplugin.cpp
-+++ b/samba/filepropertiesplugin/sambausershareplugin.cpp
-@@ -112,7 +112,8 @@ SambaUserSharePlugin::SambaUserSharePlugin(QObject *parent)
- bool SambaUserSharePlugin::isSambaInstalled()
- {
- return QFile::exists(QStringLiteral("/usr/sbin/smbd"))
-- || QFile::exists(QStringLiteral("/usr/local/sbin/smbd"));
-+ || QFile::exists(QStringLiteral("/usr/local/sbin/smbd"))
-+ || QFile::exists(QStringLiteral("/run/current-system/sw/bin/smbd"));
- }
-
- void SambaUserSharePlugin::showSambaStatus()