# Calculate format=diff merge(x11-misc/sddm)>=0.20.0
diff --git data/CMakeLists.txt data/CMakeLists.txt
index f3b5781..fb1047a 100644
--- data/CMakeLists.txt
+++ data/CMakeLists.txt
@@ -22,6 +22,8 @@ install(FILES
     "scripts/Xsession"
     "scripts/Xsetup"
     "scripts/Xstop"
+    "scripts/Xlogin"
+    "scripts/Xlogout"
     "scripts/wayland-session"
     DESTINATION "${DATA_INSTALL_DIR}/scripts"
     PERMISSIONS
diff --git data/man/sddm.conf.rst.in data/man/sddm.conf.rst.in
index 32bebf8..39fae23 100644
--- data/man/sddm.conf.rst.in
+++ data/man/sddm.conf.rst.in
@@ -150,6 +150,14 @@ OPTIONS
 	is "x11", otherwise as sddm user.
 	Default value is "@DATA_INSTALL_DIR@/scripts/Xstop".
 
+`LoginCommand=`
+       Path of script to execute before user login.
+       Default value is "@DATA_INSTALL_DIR@/scripts/Xlogin".
+
+`LogoutCommand=`
+       Path of script to execute after user logout.
+       Default value is "@DATA_INSTALL_DIR@/scripts/Xlogout".
+
 `MinimumVT=`
 	Minimum virtual terminal number that will be used
 	by the first display. Virtual terminal number will
diff --git data/scripts/Xlogin data/scripts/Xlogin
new file mode 100755
index 0000000..5cbaa46
--- /dev/null
+++ data/scripts/Xlogin
@@ -0,0 +1,2 @@
+#!/bin/sh
+# Xlogin - run as root before user login
diff --git data/scripts/Xlogout data/scripts/Xlogout
new file mode 100755
index 0000000..d09725c
--- /dev/null
+++ data/scripts/Xlogout
@@ -0,0 +1,2 @@
+#!/bin/sh
+# Xlogin - run as root before user logout
diff --git src/common/Configuration.h src/common/Configuration.h
index 54bcace..2db0a99 100644
--- src/common/Configuration.h
+++ src/common/Configuration.h
@@ -74,7 +74,11 @@ namespace SDDM {
             Entry(SessionLogFile,      QString,     _S(".local/share/sddm/xorg-session.log"),   _S("Path to the user session log file"));
             Entry(DisplayCommand,      QString,     _S(DATA_INSTALL_DIR "/scripts/Xsetup"),     _S("Path to a script to execute when starting the display server"));
             Entry(DisplayStopCommand,  QString,     _S(DATA_INSTALL_DIR "/scripts/Xstop"),      _S("Path to a script to execute when stopping the display server"));
-            Entry(EnableHiDPI,         bool,        true,                                      _S("Enable Qt's automatic high-DPI scaling"));
+            Entry(LoginCommand,        QString,     _S(DATA_INSTALL_DIR "/scripts/Xlogin"),     _S("Xlogin script path\n"
+                                                                                                   "A script to execute before user login"));
+            Entry(LogoutCommand,       QString,     _S(DATA_INSTALL_DIR "/scripts/Xlogout"),    _S("Xlogout script path\n"
+                                                                                                   "A script to execute before user logout"));
+            Entry(EnableHiDPI,         bool,        true,                                       _S("Enable Qt's automatic high-DPI scaling"));
         );
 
         Section(Wayland,
diff --git src/helper/HelperApp.cpp src/helper/HelperApp.cpp
index 14cf276..db29af4 100644
--- src/helper/HelperApp.cpp
+++ src/helper/HelperApp.cpp
@@ -167,6 +167,11 @@ namespace SDDM {
         m_user = m_backend->userName();
         QProcessEnvironment env = authenticated(m_user);
 
+        if(!runExternalScript(mainConfig.X11.LoginCommand.get())) {
+            exit(Auth::HELPER_SESSION_ERROR);
+            return;
+        }
+
         if (!m_session->path().isEmpty()) {
             env.insert(m_session->processEnvironment());
             m_session->setProcessEnvironment(env);
@@ -193,7 +198,29 @@ namespace SDDM {
         return;
     }
 
+    bool HelperApp::runExternalScript(const QString &command) {
+        bool ret = true;
+        QProcessEnvironment env = authenticated(m_user);
+        env.insert(m_session->processEnvironment());
+        if (!command.isEmpty() &&
+            env.value(QStringLiteral("XDG_SESSION_CLASS")) == QStringLiteral("user")) {
+            QProcess *displayStopScript = new QProcess();
+            env.insert(QStringLiteral("USER"), m_user);
+            env.insert(QStringLiteral("HOME"), QStringLiteral("/root"));
+            displayStopScript->setProcessEnvironment(env);
+            // start script
+            displayStopScript->start(command);
+            if(!displayStopScript->waitForFinished(-1) || displayStopScript->exitCode() != 0) {
+                ret = false;
+            }
+            displayStopScript->deleteLater();
+        }
+        return ret;
+    }
+
     void HelperApp::sessionFinished(int status) {
+        // create logout script process
+        runExternalScript(mainConfig.X11.LogoutCommand.get());
         exit(status);
     }
 
diff --git src/helper/HelperApp.h src/helper/HelperApp.h
index 64ea0e1..fa44371 100644
--- src/helper/HelperApp.h
+++ src/helper/HelperApp.h
@@ -62,6 +62,7 @@ namespace SDDM {
         UserSession *m_session { nullptr };
         QLocalSocket *m_socket { nullptr };
         QString m_user { };
+        bool runExternalScript(const QString &command);
         // TODO: get rid of this in a nice clean way along the way with moving to user session X server
         QByteArray m_cookie { };
 
