Index: trunk/packages/sipb-xen-console/debian/changelog
===================================================================
--- trunk/packages/sipb-xen-console/debian/changelog	(revision 343)
+++ trunk/packages/sipb-xen-console/debian/changelog	(revision 344)
@@ -1,2 +1,8 @@
+sipb-xen-console (2) unstable; urgency=low
+
+  * Actually functional release.
+
+ -- SIPB Xen Project <sipb-xen@mit.edu>  Sun, 30 Mar 2008 05:07:43 -0400
+
 sipb-xen-console (1) unstable; urgency=low
 
Index: trunk/packages/sipb-xen-console/debian/control.in
===================================================================
--- trunk/packages/sipb-xen-console/debian/control.in	(revision 343)
+++ trunk/packages/sipb-xen-console/debian/control.in	(revision 344)
@@ -10,5 +10,5 @@
 Provides: ${diverted-files}
 Conflicts: ${diverted-files}
-Depends: ${shlibs:Depends}, ${misc:Depends}, fuse-utils, libnss-pgsql1, openssh-client, openssh-server, python-fuse, sipb-xen-database-common
+Depends: ${shlibs:Depends}, ${misc:Depends}, daemon, fuse-utils, libnss-pgsql1, nscd, openssh-client, openssh-server, python-fuse, sipb-xen-database-common
 Description: SIPB Xen serial console server
  This package  should be installed on sipb-xen-console
Index: trunk/packages/sipb-xen-console/debian/rules
===================================================================
--- trunk/packages/sipb-xen-console/debian/rules	(revision 343)
+++ trunk/packages/sipb-xen-console/debian/rules	(revision 344)
@@ -4,5 +4,7 @@
 DEB_DIVERT_EXTENSION = .sipb-xen
 DEB_DIVERT_FILES_sipb-xen-console += \
-	/etc/nsswitch.conf
+	/etc/nscd.conf \
+	/etc/nsswitch.conf \
+	/etc/pam.d/ssh \
 	/etc/ssh/ssh_config
 
Index: trunk/packages/sipb-xen-console/debian/sipb-xen-console.init
===================================================================
--- trunk/packages/sipb-xen-console/debian/sipb-xen-console.init	(revision 343)
+++ trunk/packages/sipb-xen-console/debian/sipb-xen-console.init	(revision 344)
@@ -64,4 +64,5 @@
 	# Many daemons don't delete their pidfiles when they exit.
 	rm -f $PIDFILE
+	umount "$DAEMON_ARGS"
 	return "$RETVAL"
 }
Index: trunk/packages/sipb-xen-console/files/etc/nscd.conf.sipb-xen
===================================================================
--- trunk/packages/sipb-xen-console/files/etc/nscd.conf.sipb-xen	(revision 344)
+++ trunk/packages/sipb-xen-console/files/etc/nscd.conf.sipb-xen	(revision 344)
@@ -0,0 +1,67 @@
+#
+# /etc/nscd.conf
+#
+# An example Name Service Cache config file.  This file is needed by nscd.
+#
+# Legal entries are:
+#
+#	logfile			<file>
+#	debug-level		<level>
+#	threads			<initial #threads to use>
+#	max-threads		<maximum #threads to use>
+#	server-user             <user to run server as instead of root>
+#		server-user is ignored if nscd is started with -S parameters
+#       stat-user               <user who is allowed to request statistics>
+#	reload-count		unlimited|<number>
+#	paranoia		<yes|no>
+#	restart-interval	<time in seconds>
+#
+#       enable-cache		<service> <yes|no>
+#	positive-time-to-live	<service> <time in seconds>
+#	negative-time-to-live   <service> <time in seconds>
+#       suggested-size		<service> <prime number>
+#	check-files		<service> <yes|no>
+#	persistent		<service> <yes|no>
+#	shared			<service> <yes|no>
+#
+# Currently supported cache names (services): passwd, group, hosts
+#
+
+
+#	logfile			/var/log/nscd.log
+#	threads			6
+#	max-threads		128
+#	server-user		nobody
+#	stat-user		somebody
+	debug-level		0
+#	reload-count		5
+	paranoia		no
+#	restart-interval	3600
+
+	enable-cache		passwd		yes
+	positive-time-to-live	passwd		600
+#	negative-time-to-live	passwd		20
+	negative-time-to-live	passwd		3
+	suggested-size		passwd		211
+	check-files		passwd		yes
+#	persistent		passwd		yes
+	persistent		passwd		no
+	shared			passwd		yes
+
+	enable-cache		group		yes
+	positive-time-to-live	group		3600
+#	negative-time-to-live	group		60
+	negative-time-to-live	group		3
+	suggested-size		group		211
+	check-files		group		yes
+#	persistent		group		yes
+	persistent		group		no
+	shared			group		yes
+
+	enable-cache		hosts		yes
+	positive-time-to-live	hosts		3600
+	negative-time-to-live	hosts		20
+	suggested-size		hosts		211
+	check-files		hosts		yes
+	persistent		hosts		yes
+	shared			hosts		yes
Index: trunk/packages/sipb-xen-console/files/etc/nss-pgsql.conf
===================================================================
--- trunk/packages/sipb-xen-console/files/etc/nss-pgsql.conf	(revision 343)
+++ trunk/packages/sipb-xen-console/files/etc/nss-pgsql.conf	(revision 344)
@@ -6,18 +6,13 @@
 database	= sipb_xen
 login		= sipb-xen
-#passwd		= foo
-#passwdtable	= machines
-#grouptable	= machines
-# you can use anything postgres accepts as table expression
-#groupmembertable = accounts JOIN usergroups ON accounts.uid=usergroups.uid JOIN groups ON usergroups.gid=groups.gid
 
-querypasswd = SELECT name, 'moo', 1000 as uid, 1000, '', '/vmhome/'|| name, '/usr/local/bin/sipb-xen-consolesh' FROM machines
-querygroup = SELECT name, NULL, 1000 as gid FROM machines
-querymembers = SELECT name FROM machines WHERE 1000 = %d
-queryids = SELECT 1000 AS gid FROM machines LIMIT 0;
+querypasswd = SELECT name, NULL, machine_id + 1000 as uid, machine_id + 1000 as gid, '', '/consolefs/'|| name, '/usr/bin/sipb-xen-consolesh' FROM machines
+querygroup = SELECT name, NULL, machine_id + 1000 as gid FROM machines
+querymembers = SELECT name FROM machines WHERE 1000 + machine_id = %d
+queryids = SELECT 1000 + machine_id AS gid FROM machines LIMIT 0
 
 passwd_name = name
-passwd_uid = uid
+passwd_uid = 1000 + machine_id
 
 group_name = name
-group_gid = gid
+group_gid = 1000 + machine_id
Index: trunk/packages/sipb-xen-console/files/etc/nsswitch.conf.sipb-xen
===================================================================
--- trunk/packages/sipb-xen-console/files/etc/nsswitch.conf.sipb-xen	(revision 343)
+++ trunk/packages/sipb-xen-console/files/etc/nsswitch.conf.sipb-xen	(revision 344)
@@ -6,5 +6,5 @@
 
 passwd:         compat pgsql
-group:          compat
+group:          compat pgsql
 shadow:         compat
 
Index: trunk/packages/sipb-xen-console/files/etc/pam.d/ssh.sipb-xen
===================================================================
--- trunk/packages/sipb-xen-console/files/etc/pam.d/ssh.sipb-xen	(revision 344)
+++ trunk/packages/sipb-xen-console/files/etc/pam.d/ssh.sipb-xen	(revision 344)
@@ -0,0 +1,39 @@
+# PAM configuration for the Secure Shell service
+
+# Read environment variables from /etc/environment and
+# /etc/security/pam_env.conf.
+auth       required     pam_env.so # [1]
+# In Debian 4.0 (etch), locale-related environment variables were moved to
+# /etc/default/locale, so read that as well.
+auth       required     pam_env.so envfile=/etc/default/locale
+
+# Standard Un*x authentication.
+@include common-auth
+
+# Disallow non-root logins when /etc/nologin exists.
+account    required     pam_nologin.so
+
+# Uncomment and edit /etc/security/access.conf if you need to set complex
+# access limits that are hard to express in sshd_config.
+# account  required     pam_access.so
+
+# Standard Un*x authorization.
+@include common-account
+
+# Standard Un*x session setup and teardown.
+@include common-session
+
+# Print the message of the day upon successful login.
+#session    optional     pam_motd.so # [1]
+
+# Print the status of the user's mailbox upon successful login.
+session    optional     pam_mail.so standard noenv # [1]
+
+# Set up user limits from /etc/security/limits.conf.
+session    required     pam_limits.so
+
+# Set up SELinux capabilities (need modified pam)
+# session  required     pam_selinux.so multiple
+
+# Standard Un*x password updating.
+@include common-password
Index: trunk/packages/sipb-xen-console/files/etc/ssh/ssh_config.sipb-xen
===================================================================
--- trunk/packages/sipb-xen-console/files/etc/ssh/ssh_config.sipb-xen	(revision 343)
+++ trunk/packages/sipb-xen-console/files/etc/ssh/ssh_config.sipb-xen	(revision 344)
@@ -18,5 +18,5 @@
 
 Host *
-   SetEnv VM_NAME
+   SendEnv VM_NAME
 #   ForwardAgent no
 #   ForwardX11 no
Index: trunk/packages/sipb-xen-console/files/etc/ssh/ssh_known_hosts
===================================================================
--- trunk/packages/sipb-xen-console/files/etc/ssh/ssh_known_hosts	(revision 344)
+++ trunk/packages/sipb-xen-console/files/etc/ssh/ssh_known_hosts	(revision 344)
@@ -0,0 +1,3 @@
+|1|CoekhjakJDYiibQ38vZna+XKwCg=|Ts2GavZxl8KVEl++tnJnjqfn84s= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAsoOOazVHn04z6s+kQnoFcw9fv7dGB9s/9H1QygYW9QAbvklWx0q4J8KGTATXCFwjooLNqjHYONOQ8x0h1fZPDmhdoHk24wH/EBUAAyhtrwTMpsgfqZwG7yuRpcbO382F3wRv6CIRYZ6hyIlm0Zt3680mO/u7l2wAFoMTyYwSdZ8Gl9p5Ay750TFCZoEI/Z4EQY5lGPHrHIXN+uo0Yus//AmWIzY9y3TSKabHz77rPGIzJc8Y4XjDqA7LzXCY+KGw2Of059AseVHNTCMo6KzVIKgdZoRBtiY7fD1l7ystgKL6lGJr4C1UyWoM41EVkDqsRJZ70C4Elcr1x/MrQFLEgQ==
+|1|SFl+Ci6EXZcVvxvxDm4Cf85nGho=|InwYz5wWUf/NRbBQRa/TO3Lm2uQ= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAsoOOazVHn04z6s+kQnoFcw9fv7dGB9s/9H1QygYW9QAbvklWx0q4J8KGTATXCFwjooLNqjHYONOQ8x0h1fZPDmhdoHk24wH/EBUAAyhtrwTMpsgfqZwG7yuRpcbO382F3wRv6CIRYZ6hyIlm0Zt3680mO/u7l2wAFoMTyYwSdZ8Gl9p5Ay750TFCZoEI/Z4EQY5lGPHrHIXN+uo0Yus//AmWIzY9y3TSKabHz77rPGIzJc8Y4XjDqA7LzXCY+KGw2Of059AseVHNTCMo6KzVIKgdZoRBtiY7fD1l7ystgKL6lGJr4C1UyWoM41EVkDqsRJZ70C4Elcr1x/MrQFLEgQ==
+|1|52lp5FTRtu4Fyk8GvC3mH2idB+0=|fGJ+LwWltfUP9kC1fiMfJO5XrVk= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAsoOOazVHn04z6s+kQnoFcw9fv7dGB9s/9H1QygYW9QAbvklWx0q4J8KGTATXCFwjooLNqjHYONOQ8x0h1fZPDmhdoHk24wH/EBUAAyhtrwTMpsgfqZwG7yuRpcbO382F3wRv6CIRYZ6hyIlm0Zt3680mO/u7l2wAFoMTyYwSdZ8Gl9p5Ay750TFCZoEI/Z4EQY5lGPHrHIXN+uo0Yus//AmWIzY9y3TSKabHz77rPGIzJc8Y4XjDqA7LzXCY+KGw2Of059AseVHNTCMo6KzVIKgdZoRBtiY7fD1l7ystgKL6lGJr4C1UyWoM41EVkDqsRJZ70C4Elcr1x/MrQFLEgQ==
Index: trunk/packages/sipb-xen-console/files/home/machines/.ssh/known_hosts
===================================================================
--- trunk/packages/sipb-xen-console/files/home/machines/.ssh/known_hosts	(revision 343)
+++ 	(revision )
@@ -1,2 +1,0 @@
-|1|CoekhjakJDYiibQ38vZna+XKwCg=|Ts2GavZxl8KVEl++tnJnjqfn84s= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAsoOOazVHn04z6s+kQnoFcw9fv7dGB9s/9H1QygYW9QAbvklWx0q4J8KGTATXCFwjooLNqjHYONOQ8x0h1fZPDmhdoHk24wH/EBUAAyhtrwTMpsgfqZwG7yuRpcbO382F3wRv6CIRYZ6hyIlm0Zt3680mO/u7l2wAFoMTyYwSdZ8Gl9p5Ay750TFCZoEI/Z4EQY5lGPHrHIXN+uo0Yus//AmWIzY9y3TSKabHz77rPGIzJc8Y4XjDqA7LzXCY+KGw2Of059AseVHNTCMo6KzVIKgdZoRBtiY7fD1l7ystgKL6lGJr4C1UyWoM41EVkDqsRJZ70C4Elcr1x/MrQFLEgQ==
-|1|SFl+Ci6EXZcVvxvxDm4Cf85nGho=|InwYz5wWUf/NRbBQRa/TO3Lm2uQ= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAsoOOazVHn04z6s+kQnoFcw9fv7dGB9s/9H1QygYW9QAbvklWx0q4J8KGTATXCFwjooLNqjHYONOQ8x0h1fZPDmhdoHk24wH/EBUAAyhtrwTMpsgfqZwG7yuRpcbO382F3wRv6CIRYZ6hyIlm0Zt3680mO/u7l2wAFoMTyYwSdZ8Gl9p5Ay750TFCZoEI/Z4EQY5lGPHrHIXN+uo0Yus//AmWIzY9y3TSKabHz77rPGIzJc8Y4XjDqA7LzXCY+KGw2Of059AseVHNTCMo6KzVIKgdZoRBtiY7fD1l7ystgKL6lGJr4C1UyWoM41EVkDqsRJZ70C4Elcr1x/MrQFLEgQ==
Index: trunk/packages/sipb-xen-console/files/usr/bin/sipb-xen-consolefs
===================================================================
--- trunk/packages/sipb-xen-console/files/usr/bin/sipb-xen-consolefs	(revision 343)
+++ trunk/packages/sipb-xen-console/files/usr/bin/sipb-xen-consolefs	(revision 344)
@@ -11,9 +11,9 @@
 			   # - note: these must be returned as negatives
 
+import sipb_xen_database
+
 fuse.fuse_python_api = (0, 2)
 
-machines = ['moo17', 'remus']
 realpath = "/home/machines/"
-uid = 1000
 
 def dirFromList(list):
@@ -48,5 +48,5 @@
 		self.st_dev = 0
 		self.st_nlink = 0
-		self.st_uid = uid
+		self.st_uid = 0
 		self.st_gid = 0
 		self.st_size = 0
@@ -64,8 +64,33 @@
 	def __init__(self, *args, **kw):
 		Fuse.__init__(self, *args, **kw)
+		self.lasttime = time()
+		self.allow_other = 1
 		print 'Init complete.'
 	
 	def mirrorPath(self, path):
 		return realpath + "/".join(getParts(path)[1:])
+	
+	def getMachines(self):
+		if time() - self.lasttime > 15:
+			self.lasttime = time()
+			sipb_xen_database.clear_cache()
+		return [machine.name for machine in sipb_xen_database.Machine.select()]
+	
+	def getUid(self, machine_name):
+		return sipb_xen_database.Machine.get_by(name=machine_name).machine_id + 1000
+	
+	def getK5login(self, machine_name):
+		machine = sipb_xen_database.Machine.get_by(name=machine_name)
+		users = [acl.user for acl in machine.acl]
+		return "\n".join(map(self.userToPrinc, users) + [''])
+	
+	def userToPrinc(self, user):
+		if '@' in user:
+			(princ, realm) = user.split('@')
+		else:
+			princ = user
+			realm = "ATHENA.MIT.EDU"
+		
+		return princ.replace('.', '/') + realm
 	
 	def getattr(self, path):
@@ -94,7 +119,8 @@
 			st.st_nlink = 2
 		elif depth == 1:
-			if parts[-1] in machines:
+			if parts[-1] in self.getMachines():
 				st.st_mode = stat.S_IFDIR | 0755
 				st.st_nlink = 2
+				st.st_uid = st.st_gid = self.getUid(parts[0])
 			else:
 				return -errno.ENOENT
@@ -102,28 +128,39 @@
 			st.st_mode = stat.S_IFREG | 0444
 			st.st_nlink = 1
-			st.st_size = 17
+			st.st_size = len(self.getK5login(parts[0]))
+			st.st_uid = st.st_gid = self.getUid(parts[0])
 		else:
-			st = os.lstat(self.mirrorPath(path))
+			stats = list(os.lstat(self.mirrorPath(path)))
+			stats[4:6] = [self.getUid(parts[0])] * 2
+			return tuple(stats)
 		return st.toTuple()
 	
 	def readdir(self, path, offset):
 		print '*** readdir', path, offset
+		for (value, zero) in self.getdir(path):
+			yield fuse.Direntry(value)
+	
+	def getdir(self, path):
+		print '*** getdir', path
 		if path == '/':
-			for r in  ['.', '..']+machines:
-				yield fuse.Direntry(r)
+			contents = ['.', '..']+self.getMachines()
 		elif getDepth(path) == 1:
-			for r in set(os.listdir(self.mirrorPath(path)) + ['.k5login']):
-				yield fuse.Direntry(r)
+			contents = set(os.listdir(self.mirrorPath(path)) + ['.k5login', '.', '..'])
 		else:
-			for r in os.listdir(self.mirrorPath(path)):
-				yield fuse.Direntry(r)
+			contents = os.listdir(self.mirrorPath(path)) + ['.', '..']
+		return [(i, 0) for i in contents]
 	
 	def read ( self, path, length, offset ):
 		print '*** read', path, length, offset
 		
+		parts = getParts(path)
+		
 		if getDepth(path) < 2:
 			return -errno.ENOENT
-		elif getParts(path)[1:] == ['.k5login']:
-			pass
+		elif parts[1:] == ['.k5login']:
+			if parts[0] not in self.getMachines():
+				return -errno.ENOENT
+			else:
+				return self.getK5login(parts[0])[offset:length + offset]
 		else:
 			fname = self.mirrorPath(path)
@@ -136,4 +173,5 @@
 
 if __name__ == '__main__':
+	sipb_xen_database.connect('postgres://sipb-xen@sipb-xen-dev.mit.edu/sipb_xen')
 	usage="""
 ConsoleFS [mount_path]
Index: trunk/packages/sipb-xen-console/files/usr/bin/sipb-xen-consolesh
===================================================================
--- trunk/packages/sipb-xen-console/files/usr/bin/sipb-xen-consolesh	(revision 344)
+++ trunk/packages/sipb-xen-console/files/usr/bin/sipb-xen-consolesh	(revision 344)
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+export VM_NAME="d_$USER"
+ssh console@black-mesa
