--- lightdm-1.19.3/config.h.in.1	2016-08-11 16:37:18.327488055 +0300
+++ lightdm-1.19.3/config.h.in	2016-08-11 16:37:49.333955249 +0300
@@ -27,6 +27,9 @@
 /* libaudit support */
 #undef HAVE_LIBAUDIT
 
+/* libcontract support */
+#undef HAVE_SMF_CONTRACTS
+
 /* Define to 1 if you have the <memory.h> header file. */
 #undef HAVE_MEMORY_H
 
--- lightdm-1.19.3/configure.ac.1	2016-08-11 16:35:29.359045915 +0300
+++ lightdm-1.19.3/configure.ac	2016-08-11 16:37:03.732983253 +0300
@@ -155,6 +155,15 @@
 fi
 AM_CONDITIONAL(COMPILE_LIBLIGHTDM_QT5, test x"$compile_liblightdm_qt5" != "xno")
 
+dnl ---------------------------------------------------------------------------
+dnl check for Solaris SMF contract support
+dnl ---------------------------------------------------------------------------
+
+AC_MSG_CHECKING(for Solaris SMF contract support)
+AC_CHECK_LIB(contract, ct_tmpl_activate, [
+                       AC_DEFINE(HAVE_SMF_CONTRACTS,1,[lcontract support])
+                            LIGHTDM_LIBS="${LIGHTDM_LIBS} -lcontract" ])
+
 AC_ARG_ENABLE([libaudit],
     AS_HELP_STRING([--enable-libaudit],
                    [Enable libaudit logging of login and logout events [[default=auto]]]),
--- lightdm-1.28.0/src/session.c	2018-08-30 02:28:55.000000000 +0000
+++ lightdm-1.28.0/src/session.c	2018-12-22 12:13:04.194567557 +0000
@@ -21,6 +21,13 @@
 #include <grp.h>
 #include <pwd.h>
 
+#ifdef HAVE_SMF_CONTRACTS
+#include <sys/ctfs.h>
+#include <sys/contract.h>
+#include <sys/contract/process.h>
+#include <libcontract.h>
+#endif
+
 #include "session.h"
 #include "configuration.h"
 #include "console-kit.h"
@@ -131,6 +138,141 @@ G_DEFINE_TYPE_WITH_CODE (Session, sessio
                          G_IMPLEMENT_INTERFACE (
                              LOGGER_TYPE, session_logger_iface_init))
 
+#ifdef HAVE_SMF_CONTRACTS
+static int contracts_fd = -1;
+
+void contracts_pre_fork ();
+void contracts_post_fork_child ();
+void contracts_post_fork_parent (int fork_succeeded);
+
+void
+contracts_pre_fork ()
+{
+   const char *errmsg = "opening process contract template";
+
+        /*
+         * On failure, just continue since it is better to start with
+         * children in the same contract than to not start them at all.
+         */
+        if (contracts_fd == -1) {
+                if ((contracts_fd = open64 (CTFS_ROOT "/process/template",
+                                            O_RDWR)) == -1)
+                        goto exit;
+
+                errmsg = "setting contract terms";
+                if ((errno = ct_pr_tmpl_set_param (contracts_fd, CT_PR_PGRPONLY)))
+                        goto exit;
+
+                if ((errno = ct_tmpl_set_informative (contracts_fd, CT_PR_EV_HWERR)))
+                        goto exit;
+
+                if ((errno = ct_pr_tmpl_set_fatal (contracts_fd, CT_PR_EV_HWERR)))
+                        goto exit;
+
+                if ((errno = ct_tmpl_set_critical (contracts_fd, 0)))
+                        goto exit;
+        }
+
+        errmsg = "setting active template";
+        if ((errno = ct_tmpl_activate (contracts_fd)))
+                goto exit;
+
+        g_debug ("Set active contract");
+        return;
+
+exit:
+            if (contracts_fd != -1)
+                (void) close (contracts_fd);
+
+        contracts_fd = -1;
+
+        if (errno) {
+                g_debug (
+                        "Error setting up active contract template: %s while %s",
+                        strerror (errno), errmsg);
+        }
+}
+
+void
+contracts_post_fork_child ()
+{
+        /* Clear active template so no new contracts are created on fork */
+        if (contracts_fd == -1)
+                return;
+
+        if ((errno = (ct_tmpl_clear (contracts_fd)))) {
+                g_debug (
+                        "Error clearing active contract template (child): %s",
+                        strerror (errno));
+        } else {
+                g_debug ("Cleared active contract template (child)");
+        }
+
+        (void) close (contracts_fd);
+
+        contracts_fd = -1;
+}
+
+void
+contracts_post_fork_parent (int fork_succeeded)
+{
+        char path[PATH_MAX];
+        int cfd;
+        ct_stathdl_t status;
+        ctid_t latest;
+
+        /* Clear active template, abandon latest contract. */
+        if (contracts_fd == -1)
+                return;
+
+        if ((errno = ct_tmpl_clear (contracts_fd)))
+                g_debug ("Error while clearing active contract template: %s",
+                         strerror (errno));
+        else
+                g_debug ("Cleared active contract template (parent)");
+
+        if (!fork_succeeded)
+                return;
+
+        if ((cfd = open64 (CTFS_ROOT "/process/latest", O_RDONLY)) == -1) {
+                g_debug ("Error getting latest contract: %s",
+                         strerror(errno));
+                return;
+        }
+
+        if ((errno = ct_status_read (cfd, CTD_COMMON, &status)) != 0) {
+                g_debug ("Error getting latest contract ID: %s",
+                         strerror(errno));
+                (void) close (cfd);
+                return;
+        }
+
+        latest = ct_status_get_id (status);
+        ct_status_free (status);
+        (void) close (cfd);
+
+        if ((snprintf (path, PATH_MAX, CTFS_ROOT "/all/%ld/ctl", latest)) >=
+             PATH_MAX) {
+                g_debug ("Error opening the latest contract ctl file: %s",
+                         strerror (ENAMETOOLONG));
+                return;
+        }
+
+        cfd = open64 (path, O_WRONLY);
+        if (cfd == -1) {
+                g_debug ("Error opening the latest contract ctl file: %s",
+                         strerror (errno));
+                return;
+        }
+
+        if ((errno = ct_ctl_abandon (cfd)))
+                g_debug ("Error abandoning latest contract: %s",
+                         strerror (errno));
+        else
+                g_debug ("Abandoned latest contract");
+}
+#endif
+
 Session *
 session_new (void)
 {
@@ -612,10 +754,16 @@ session_real_start (Session *session)
 
     /* Run the child */
     g_autofree gchar *arg0 = g_strdup_printf ("%d", to_child_output);
+#ifdef HAVE_SMF_CONTRACTS
+    contracts_pre_fork ();
+#endif
     g_autofree gchar *arg1 = g_strdup_printf ("%d", from_child_input);
     priv->pid = fork ();
     if (priv->pid == 0)
     {
+#ifdef HAVE_SMF_CONTRACTS
+        contracts_post_fork_child ();
+#endif
         /* Run us again in session child mode */
         execlp ("lightdm",
                 "lightdm",
@@ -623,6 +771,10 @@ session_real_start (Session *session)
                 arg0, arg1, NULL);
         _exit (EXIT_FAILURE);
     }
+#ifdef HAVE_SMF_CONTRACTS
+    /* Child would have already exited */
+    contracts_post_fork_parent ((priv->pid > 0));
+#endif
 
     if (priv->pid < 0)
     {
