* run PAM session stuff
 
-* tcpwrap
-
 * use setproctitle() when forking, before exec() (waiting for (PR_SET_PROCTITLE_AREA to enter the kernel)
 
 * follow property change dbus spec
 
         "  <property name=\"CapabilityBoundingSetDrop\" type=\"t\" access=\"read\"/>\n" \
         "  <property name=\"User\" type=\"s\" access=\"read\"/>\n"      \
         "  <property name=\"Group\" type=\"s\" access=\"read\"/>\n"     \
-        "  <property name=\"SupplementaryGroups\" type=\"as\" access=\"read\"/>\n"
+        "  <property name=\"SupplementaryGroups\" type=\"as\" access=\"read\"/>\n" \
+        "  <property name=\"TCPWrapName\" type=\"s\" access=\"read\"/>\n"
 
 #define BUS_EXEC_CONTEXT_PROPERTIES(interface, context)                 \
         { interface, "Environment",                   bus_property_append_strv,   "as",    (context).environment                   }, \
         { interface, "CapabilityBoundingSetDrop",     bus_property_append_uint64, "t",     &(context).capability_bounding_set_drop }, \
         { interface, "User",                          bus_property_append_string, "s",     (context).user                          }, \
         { interface, "Group",                         bus_property_append_string, "s",     (context).group                         }, \
-        { interface, "SupplementaryGroups",           bus_property_append_strv,   "as",    (context).supplementary_groups          }
+        { interface, "SupplementaryGroups",           bus_property_append_strv,   "as",    (context).supplementary_groups          }, \
+        { interface, "TCPWrapName",                   bus_property_append_string, "s",     (context).tcpwrap_name                  }
 
 int bus_execute_append_output(Manager *m, DBusMessageIter *i, const char *property, void *data);
 int bus_execute_append_input(Manager *m, DBusMessageIter *i, const char *property, void *data);
 
         "  <property name=\"DirectoryMode\" type=\"u\" access=\"read\"/>\n" \
         "  <property name=\"SocketMode\" type=\"u\" access=\"read\"/>\n" \
         "  <property name=\"Accept\" type=\"b\" access=\"read\"/>\n"    \
-        "  <property name=\"TCPWrapName\" type=\"s\" access=\"read\"/>\n" \
         " </interface>\n"                                               \
 
 #define INTROSPECTION                                                   \
                 { "org.freedesktop.systemd1.Socket", "DirectoryMode", bus_property_append_mode,     "u", &u->socket.directory_mode },
                 { "org.freedesktop.systemd1.Socket", "SocketMode",    bus_property_append_mode,     "u", &u->socket.socket_mode },
                 { "org.freedesktop.systemd1.Socket", "Accept",        bus_property_append_bool,     "b", &u->socket.accept },
-                { "org.freedesktop.systemd1.Socket", "TCPWrapName",   bus_property_append_string,   "s", u->socket.tcpwrap_name },
                 { NULL, NULL, NULL, NULL, NULL }
         };
 
 
 #include "securebits.h"
 #include "cgroup.h"
 #include "namespace.h"
+#include "tcpwrap.h"
 
 /* This assumes there is a 'tty' group */
 #define TTY_MODE 0620
                                 goto fail;
                         }
 
+                if (socket_fd >= 0 && context->tcpwrap_name)
+                        if (!socket_tcpwrap(socket_fd, context->tcpwrap_name)) {
+                                r = EXIT_TCPWRAP;
+                                goto fail;
+                        }
+
                 if (confirm_spawn) {
                         char response;
 
         free(c->tty_path);
         c->tty_path = NULL;
 
+        free(c->tcpwrap_name);
+        c->tcpwrap_name = NULL;
+
         free(c->syslog_identifier);
         c->syslog_identifier = NULL;
 
                 for (e = c->environment; *e; e++)
                         fprintf(f, "%sEnvironment: %s\n", prefix, *e);
 
+        if (c->tcpwrap_name)
+                fprintf(f,
+                        "%sTCPWrapName: %s\n",
+                        prefix, c->tcpwrap_name);
+
         if (c->nice_set)
                 fprintf(f,
                         "%sNice: %i\n",
         case EXIT_STDERR:
                 return "STDERR";
 
+        case EXIT_TCPWRAP:
+                return "TCPWRAP";
+
         default:
                 return NULL;
         }
 
         char *syslog_identifier;
         bool syslog_no_prefix;
 
+        char *tcpwrap_name;
+
         char *tty_path;
 
         /* Since resolving these names might might involve socket
         EXIT_CGROUP,
         EXIT_SETSID,   /* 220 */
         EXIT_CONFIRM,
-        EXIT_STDERR
+        EXIT_STDERR,
+        EXIT_TCPWRAP
 
 } ExitStatus;
 
 
                 { "ReadOnlyDirectories",    config_parse_path_strv,       &(context).read_only_dirs,                       section   }, \
                 { "InaccessibleDirectories",config_parse_path_strv,       &(context).inaccessible_dirs,                    section   }, \
                 { "PrivateTmp",             config_parse_bool,            &(context).private_tmp,                          section   }, \
-                { "MountFlags",             config_parse_mount_flags,     &(context),                                      section   }
+                { "MountFlags",             config_parse_mount_flags,     &(context),                                      section   }, \
+                { "TCPWrapName",            config_parse_string,          &(context).tcpwrap_name,                         section   }
 
         const ConfigItem items[] = {
                 { "Names",                  config_parse_names,           u,                                               "Unit"    },
                 { "SocketMode",             config_parse_mode,            &u->socket.socket_mode,                          "Socket"  },
                 { "KillMode",               config_parse_kill_mode,       &u->socket.kill_mode,                            "Socket"  },
                 { "Accept",                 config_parse_bool,            &u->socket.accept,                               "Socket"  },
-                { "TCPWrapName",            config_parse_string,          &u->socket.tcpwrap_name,                         "Socket"  },
                 EXEC_CONTEXT_CONFIG_ITEMS(u->socket.exec_context, "Socket"),
 
                 { "What",                   config_parse_string,          &u->mount.parameters_fragment.what,              "Mount"   },
 
 #include "strv.h"
 #include "unit-name.h"
 #include "dbus-socket.h"
-#include "tcpwrap.h"
 
 static const UnitActiveState state_translation_table[_SOCKET_STATE_MAX] = {
         [SOCKET_DEAD] = UNIT_INACTIVE,
         free(s->bind_to_device);
         s->bind_to_device = NULL;
 
-        free(s->tcpwrap_name);
-        s->tcpwrap_name = NULL;
-
         unit_unwatch_timer(u, &s->timer_watch);
 }
 
                         "%sBindToDevice: %s\n",
                         prefix, s->bind_to_device);
 
-        if (s->tcpwrap_name)
-                fprintf(f,
-                        "%sTCPWrapName: %s\n",
-                        prefix, s->tcpwrap_name);
-
         if (s->accept)
                 fprintf(f,
                         "%sAccepted: %u\n",
 
                         break;
                 }
-
-                if (s->tcpwrap_name)
-                        if (!socket_tcpwrap(cfd, s->tcpwrap_name)) {
-                                close_nointr_nofail(cfd);
-                                return;
-                        }
         }
 
         socket_enter_running(s, cfd);
 
         mode_t directory_mode;
         mode_t socket_mode;
 
-        char *tcpwrap_name;
-
         bool accept;
         unsigned n_accepted;