--- old/usr/src/cmd/ssh/include/session.h	2013-07-26 21:45:03.009517517 +0000
+++ new/usr/src/cmd/ssh/include/session.h	2013-07-26 21:45:03.016313261 +0000
@@ -25,6 +25,11 @@
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
+/*
+ * Copyright (c) 2013, Joyent, Inc.  All rights reserved.
+ */
+
+#include "sys-queue.h"
 
 #ifndef	_SESSION_H
 #define	_SESSION_H
@@ -37,7 +42,7 @@
 #define TTYSZ 64
 typedef struct Session Session;
 struct Session {
-	int	used;
+	LIST_ENTRY(Session) list_entry;
 	int	self;
 	struct passwd *pw;
 	Authctxt *authctxt;
--- old/usr/src/cmd/ssh/sshd/session.c	2013-07-26 21:45:03.196591076 +0000
+++ new/usr/src/cmd/ssh/sshd/session.c	2013-07-26 21:45:03.203248442 +0000
@@ -35,6 +35,9 @@
  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
+/*
+ * Copyright (c) 2013, Joyent, Inc.  All rights reserved.
+ */
 
 #include "includes.h"
 RCSID("$OpenBSD: session.c,v 1.150 2002/09/16 19:55:33 stevesk Exp $");
@@ -54,6 +57,7 @@
 #include "ssh1.h"
 #include "ssh2.h"
 #include "xmalloc.h"
+#include "sys-queue.h"
 #include "sshpty.h"
 #include "packet.h"
 #include "buffer.h"
@@ -139,7 +143,9 @@
 
 /* data */
 #define MAX_SESSIONS 10
-Session	sessions[MAX_SESSIONS];
+static int sessions_next_id = 0;
+static LIST_HEAD(sessions_head, Session) sessions =
+    LIST_HEAD_INITIALIZER(sessions);
 
 #define	SUBSYSTEM_NONE		0
 #define	SUBSYSTEM_EXT		1
@@ -1527,40 +1533,30 @@
 Session *
 session_new(void)
 {
-	int i;
-	static int did_init = 0;
-	if (!did_init) {
-		debug("session_new: init");
-		for (i = 0; i < MAX_SESSIONS; i++) {
-			sessions[i].used = 0;
-		}
-		did_init = 1;
-	}
-	for (i = 0; i < MAX_SESSIONS; i++) {
-		Session *s = &sessions[i];
-		if (! s->used) {
-			memset(s, 0, sizeof(*s));
-			s->chanid = -1;
-			s->ptyfd = -1;
-			s->ttyfd = -1;
-			s->used = 1;
-			s->self = i;
-			s->env = NULL;
-			debug("session_new: session %d", i);
-			return s;
-		}
-	}
-	return NULL;
+	Session *s;
+
+	debug("session_new: init");
+
+	s = xmalloc(sizeof (*s));
+	memset(s, 0, sizeof(*s));
+	s->chanid = -1;
+	s->ptyfd = -1;
+	s->ttyfd = -1;
+	s->self = sessions_next_id++;
+	s->env = NULL;
+	LIST_INSERT_HEAD(&sessions, s, list_entry);
+
+	debug("session_new: session %d", s->self);
+
+	return (s);
 }
 
 static void
 session_dump(void)
 {
-	int i;
-	for (i = 0; i < MAX_SESSIONS; i++) {
-		Session *s = &sessions[i];
-		debug("dump: used %d session %d %p channel %d pid %ld",
-		    s->used,
+	Session *s;
+	LIST_FOREACH(s, &sessions, list_entry) {
+		debug("dump: session %d %p channel %d pid %ld",
 		    s->self,
 		    s,
 		    s->chanid,
@@ -1590,11 +1586,10 @@
 Session *
 session_by_tty(char *tty)
 {
-	int i;
-	for (i = 0; i < MAX_SESSIONS; i++) {
-		Session *s = &sessions[i];
-		if (s->used && s->ttyfd != -1 && strcmp(s->tty, tty) == 0) {
-			debug("session_by_tty: session %d tty %s", i, tty);
+	Session *s;
+	LIST_FOREACH(s, &sessions, list_entry) {
+		if (s->ttyfd != -1 && strcmp(s->tty, tty) == 0) {
+			debug("session_by_tty: session %d tty %s", s->self, tty);
 			return s;
 		}
 	}
@@ -1607,11 +1602,10 @@
 static Session *
 session_by_channel(int id)
 {
-	int i;
-	for (i = 0; i < MAX_SESSIONS; i++) {
-		Session *s = &sessions[i];
-		if (s->used && s->chanid == id) {
-			debug("session_by_channel: session %d channel %d", i, id);
+	Session *s;
+	LIST_FOREACH(s, &sessions, list_entry) {
+		if (s->chanid == id) {
+			debug("session_by_channel: session %d channel %d", s->self, id);
 			return s;
 		}
 	}
@@ -1623,11 +1617,10 @@
 static Session *
 session_by_pid(pid_t pid)
 {
-	int i;
+	Session *s;
 	debug("session_by_pid: pid %ld", (long)pid);
-	for (i = 0; i < MAX_SESSIONS; i++) {
-		Session *s = &sessions[i];
-		if (s->used && s->pid == pid)
+	LIST_FOREACH(s, &sessions, list_entry) {
+		if (s->pid == pid)
 			return s;
 	}
 	error("session_by_pid: unknown pid %ld", (long)pid);
@@ -2287,8 +2280,10 @@
 	if (s->command)
 		xfree(s->command);
 	session_free_env(&s->env);
-	s->used = 0;
+
+	LIST_REMOVE(s, list_entry);
 	session_proctitle(s);
+	xfree(s);
 }
 
 void
@@ -2341,27 +2336,23 @@
 void
 session_destroy_all(void (*closefunc)(Session *))
 {
-	int i;
-	for (i = 0; i < MAX_SESSIONS; i++) {
-		Session *s = &sessions[i];
-		if (s->used) {
-			if (closefunc != NULL)
-				closefunc(s);
-			else
-				session_close(s);
-		}
+	Session *s;
+	LIST_FOREACH(s, &sessions, list_entry) {
+		if (closefunc != NULL)
+			closefunc(s);
+		else
+			session_close(s);
 	}
 }
 
 static char *
 session_tty_list(void)
 {
+	Session *s;
 	static char buf[1024];
-	int i;
 	buf[0] = '\0';
-	for (i = 0; i < MAX_SESSIONS; i++) {
-		Session *s = &sessions[i];
-		if (s->used && s->ttyfd != -1) {
+	LIST_FOREACH(s, &sessions, list_entry) {
+		if (s->ttyfd != -1) {
 			if (buf[0] != '\0')
 				strlcat(buf, ",", sizeof buf);
 			strlcat(buf, strrchr(s->tty, '/') + 1, sizeof buf);
