diff --git a/protogeni/lib/GNUmakefile.in b/protogeni/lib/GNUmakefile.in
index 599aff51e1885dba027e9a69a163e00a1072ac83..c8159d8e9d02b3d185cea6f7fbaa7bf864c6731f 100644
--- a/protogeni/lib/GNUmakefile.in
+++ b/protogeni/lib/GNUmakefile.in
@@ -13,7 +13,7 @@ include $(OBJDIR)/Makeconf
 
 LIB_SCRIPTS     = Protogeni.pm GeniDB.pm GeniUser.pm GeniSAClient.pm \
 		  GeniSlice.pm GeniSA.pm GeniCM.pm GeniCMClient.pm \
-		  test.pl GeniTicket.pm GeniSliver.pm
+		  test.pl GeniTicket.pm GeniSliver.pm GeniCredential.pm
 
 #
 # Force dependencies on the scripts so that they will be rerun through
diff --git a/protogeni/lib/GeniCM.pm.in b/protogeni/lib/GeniCM.pm.in
index 9364b102c4ab9af20f305773b77975add6766b74..54b593968e411f178b8c2ee9c5bdfd66285ca495 100644
--- a/protogeni/lib/GeniCM.pm.in
+++ b/protogeni/lib/GeniCM.pm.in
@@ -23,6 +23,7 @@ use GeniDB;
 use Genixmlrpc;
 use GeniResponse;
 use GeniTicket;
+use GeniCredential;
 use GeniSliver;
 use GeniUser;
 use libtestbed;
@@ -52,26 +53,39 @@ my $NALLOC	   = "$TB/bin/nalloc";
 sub GetTicket($)
 {
     my ($argref) = @_;
-    my $owner_uuid = $argref->{'owner_uuid'};
     my $slice_uuid = $argref->{'slice_uuid'};
     my $rspec      = $argref->{'rspec'};
+    my $impotent   = $argref->{'impotent'};
+    my $credstring = $argref->{'credential_string'};
+    my $owner_uuid = $ENV{'GENIUSER'};
 
     if (! (defined($slice_uuid) && ($slice_uuid =~ /^[-\w]+$/))) {
 	return GeniResponse->MalformedArgsResponse();
     }
-    # XXX This needs to come from the SSL environment.
     if (! (defined($owner_uuid) && ($owner_uuid =~ /^[-\w]+$/))) {
 	return GeniResponse->MalformedArgsResponse();
     }
     if (! defined($rspec)) {
 	return GeniResponse->MalformedArgsResponse();
     }
+    $impotent = 0
+	if (!defined($impotent));
+
+    my $credential = GeniCredential->CreateFromSigned($credstring);
+    if (!defined($credential)) {
+	return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
+				    "Could not create GeniCredential object");
+    }
+    # The credential owner/slice has to match what was provided.
+    if (! ($owner_uuid eq $credential->owner_uuid() &&
+	   $slice_uuid eq $credential->this_uuid())) {
+	return GeniResponse->Create(GENIRESPONSE_FORBIDDEN, undef,
+				    "Invalid credentials for operation");
+    }
 
     #
     # XXX Should we create a local geni_slices record in the DB?
     #
-if (0) {
-    #
     # If the underlying experiment does not exist, need to create
     # a holding experiment. All these are going to go into the same
     # project for now. Generally, users for non-local slices do not
@@ -110,7 +124,6 @@ if (0) {
 	return GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
 				    "Improper node id");
     }
-}
 
     #
     # Create the ticket first, before allocating the node.
@@ -120,20 +133,20 @@ if (0) {
 	return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
 				    "Could not create GeniTicket object");
     }
-if (0) {
     # Nalloc might fail if the node gets picked up by someone else.
-#    system("$NALLOC $pid $eid $node_id");
-    if (($? >> 8) < 0) {
-	$ticket->Delete();
-	return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
-				    "Allocation failure");
-    }
-    elsif (($? >> 8) > 0) {
-	$ticket->Delete();
-	return GeniResponse->Create(GENIRESPONSE_UNAVAILABLE, undef,
-				    "Could not allocate node\n");
+    if (!$impotent) {
+	system("$NALLOC $pid $eid $node_id");
+	if (($? >> 8) < 0) {
+	    $ticket->Delete();
+	    return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
+					"Allocation failure");
+	}
+	elsif (($? >> 8) > 0) {
+	    $ticket->Delete();
+	    return GeniResponse->Create(GENIRESPONSE_UNAVAILABLE, undef,
+					"Could not allocate node\n");
+	}
     }
-}
     if ($ticket->Sign() != 0) {
 	# Release will free the node.
 	$ticket->Release();
@@ -147,6 +160,8 @@ if (0) {
 #
 # Create a sliver.
 #
+# XXX Credentials stuff.
+#
 sub CreateSliver($)
 {
     my ($argref) = @_;
@@ -190,5 +205,74 @@ sub CreateSliver($)
 				    "Could not provision sliver");
     }
     
-    return GeniResponse->Create(GENIRESPONSE_SUCCESS, 0, "Wow!");
+    return GeniResponse->Create(GENIRESPONSE_SUCCESS, $sliver->uuid(), "Wow!");
+}
+
+
+#
+# Start a sliver. I take this to mean, reboot the node. Currently, using
+# the ticket as the credential.
+#
+# XXX Credentials stuff.
+#
+sub StartSliver($)
+{
+    my ($argref) = @_;
+    my $ticket      = $argref->{'ticket'};
+    my $sliver_uuid = $argref->{'uuid'};
+
+    if (!defined($sliver_uuid)) {
+	return GeniResponse->Create(GENIRESPONSE_BADARGS);
+    }
+    my $sliver = GeniSliver->Lookup($sliver_uuid);
+    if (!defined($sliver)) {
+	return GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
+				    "No such sliver $sliver_uuid");
+    }
+
+    if (! (defined($ticket) &&
+	   !TBcheck_dbslot($ticket, "default", "text",
+			   TBDB_CHECKDBSLOT_ERROR))) {
+	return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
+				    "ticket: ". TBFieldErrorString());
+    }
+    $ticket = GeniTicket->CreateFromSignedTicket($ticket);
+    if (!defined($ticket)) {
+	return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
+				    "Could not create GeniTicket object");
+    }
+
+    $sliver->Start() == 0 or
+	return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
+				    "Could not start $sliver");
+	
+    return GeniResponse->Create(GENIRESPONSE_SUCCESS);
+}
+
+#
+# Destroy a sliver.
+#
+# XXX Credential stuff ...
+#
+sub DestroySliver($)
+{
+    my ($argref) = @_;
+    my $sliver_uuid = $argref->{'uuid'};
+
+    if (!defined($sliver_uuid)) {
+	return GeniResponse->Create(GENIRESPONSE_BADARGS);
+    }
+    my $sliver = GeniSliver->Lookup($sliver_uuid);
+    if (!defined($sliver)) {
+	return GeniResponse->Create(GENIRESPONSE_BADARGS, undef,
+				    "No such sliver $sliver_uuid");
+    }
+    $sliver->UnProvision() == 0 or
+	return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
+				    "Could not unprovision sliver");
+    $sliver->Delete() == 0 or
+	return GeniResponse->Create(GENIRESPONSE_ERROR, undef,
+				    "Could not delete sliver");
+    
+    return GeniResponse->Create(GENIRESPONSE_SUCCESS);
 }
diff --git a/protogeni/lib/GeniCMClient.pm.in b/protogeni/lib/GeniCMClient.pm.in
index c9b30d9eba4e1b96924732122f01a4cd5b74e67f..3b2143c38535d9607da833df672358268d651a67 100644
--- a/protogeni/lib/GeniCMClient.pm.in
+++ b/protogeni/lib/GeniCMClient.pm.in
@@ -23,6 +23,7 @@ use GeniDB;
 use Genixmlrpc;
 use GeniResponse;
 use GeniTicket;
+use GeniCredential;
 use GeniSliver;
 use User;
 use libtestbed;
@@ -50,7 +51,8 @@ sub DiscoverResources($$)
     my ($experiment, $pref) = @_;
 
     my $response =
-	Genixmlrpc::CallMethodHTTP($GENICENTRAL, "SA::DiscoverResources",
+	Genixmlrpc::CallMethodHTTP($GENICENTRAL, User->LookupByUnixId($UID),
+				   "SA::DiscoverResources",
 				   { "uuid"  => $experiment->uuid() });
 
     return -1
@@ -87,11 +89,28 @@ sub GetTicket($$$$)
 	return -1;
     }
 
+    # Need to construct a credential.
+    my $credential = GeniCredential->Create($experiment->uuid(),
+					    $this_user->uuid());
+    if (!defined($credential)) {
+	print STDERR "Could not create a slice credential for $experiment!\n";
+	return -1;
+    }
+    if ($credential->AddCapability("createslice", 0)) {
+	print STDERR "Could not add capability to slice credential!\n";
+	return -1;
+    }
+    if ($credential->Sign()) {
+	print STDERR "Could not sign slice credential!\n";
+	return -1;
+    }
+
     my $response =
-	Genixmlrpc::CallMethodHTTP($component, "CM::GetTicket",
-				   { "slice_uuid"  => $experiment->uuid(),
-				     "owner_uuid"  => $this_user->uuid(),
-				     "rspec" => $rspec });
+	Genixmlrpc::CallMethodHTTP($component, $this_user, "CM::GetTicket",
+			{ "slice_uuid"        => $experiment->uuid(),
+			  "credential_string" => $credential->asString(),
+			  "impotent"          => 1,
+			  "rspec"             => $rspec });
     
     return -1
 	if (!defined($response));
@@ -120,15 +139,35 @@ sub CreateSliver($$$)
     return -1
 	if (!defined($response));
 
-    print Dumper($response);
-
     return -1
 	if ($response->code() != GENIRESPONSE_SUCCESS);
 
-    my $sliver = undef;
-
+    my $sliver = GeniSliver->Create($ticket, $response->value());
+    if (!defined($sliver)) {
+	print STDERR "Could not create local sliver object\n";
+	return undef;
+    }
     $$pref = $sliver;
     return 0;
+}
+		 
+sub DestroySliver($$)
+{
+    my ($experiment, $sliver) = @_;
+    my $ticket = $sliver->GetTicket();
 
+    my $response =
+	Genixmlrpc::CallMethodHTTP($ticket->component(),
+				   "CM::DestroySliver",
+				   { "uuid" => $sliver->uuid() });
+    
+    if ($response->code() != GENIRESPONSE_SUCCESS) {
+	print STDERR "Could not destroy sliver $sliver\n";
+	return -1;
+    }
+    $sliver->Delete() == 0
+	or return -1;
+
+    return 0;
 }
 		 
diff --git a/protogeni/lib/GeniCredential.pm.in b/protogeni/lib/GeniCredential.pm.in
new file mode 100644
index 0000000000000000000000000000000000000000..2ef01e73935d467f3574294a2d6e65eade093fac
--- /dev/null
+++ b/protogeni/lib/GeniCredential.pm.in
@@ -0,0 +1,228 @@
+#!/usr/bin/perl -wT
+#
+# EMULAB-COPYRIGHT
+# Copyright (c) 2008 University of Utah and the Flux Group.
+# All rights reserved.
+#
+package GeniCredential;
+
+#
+# Some simple credential stuff.
+#
+use strict;
+use Exporter;
+use vars qw(@ISA @EXPORT);
+
+@ISA    = "Exporter";
+@EXPORT = qw ( );
+
+# Must come after package declaration!
+use lib '@prefix@/lib';
+use GeniDB;
+use libtestbed;
+use Experiment;
+use libdb qw(TBGetUniqueIndex);
+use English;
+use XML::Simple;
+use XML::LibXML;
+use Data::Dumper;
+use File::Temp qw(tempfile);
+
+# Configure variables
+my $TB		   = "@prefix@";
+my $TBOPS          = "@TBOPSEMAIL@";
+my $TBAPPROVAL     = "@TBAPPROVALEMAIL@";
+my $TBAUDIT   	   = "@TBAUDITEMAIL@";
+my $BOSSNODE       = "@BOSSNODE@";
+my $OURDOMAIN      = "@OURDOMAIN@";
+my $GENICENTRAL    = "https://boss/protogeni/xmlrpc";
+my $SIGNCRED	   = "$TB/sbin/signgenicred";
+my $VERIFYCRED	   = "$TB/sbin/verifygenicred";
+my $NFREE	   = "$TB/bin/nfree";
+
+#
+# Create an empty credential object.
+#
+sub Create($$$$)
+{
+    my ($class, $this_uuid, $owner_uuid) = @_;
+
+    my $self = {};
+    $self->{'this_uuid'}     = $this_uuid;
+    $self->{'owner_uuid'}    = $owner_uuid;
+    $self->{'string'}        = undef;
+    $self->{'capabilities'}  = undef;
+    bless($self, $class);
+
+    return $self;
+}
+# accessors
+sub field($$)           { return ($_[0]->{$_[1]}); }
+sub this_uuid($)	{ return field($_[0], "this_uuid"); }
+sub owner_uuid($)	{ return field($_[0], "owner_uuid"); }
+sub asString($)		{ return field($_[0], "string"); }
+sub capabilities($)	{ return field($_[0], "capabilities"); }
+
+#
+# Add a capability to the array.
+#
+sub AddCapability($$$)
+{
+    my ($self, $name, $delegate) = @_;
+
+    return -1
+	if (!ref($self));
+
+    if (!defined($self->capabilities())) {
+	$self->{'capabilities'} = {};
+    }
+    $self->{'capabilities'}->{$name} = {"can_delegate" => $delegate};
+    return 0;
+}
+
+#
+# Create a credential object from a signed credential string.
+#
+sub CreateFromSigned($$)
+{
+    my ($class, $string) = @_;
+
+    # First verify the credential
+    my ($fh, $filename) = tempfile(UNLINK => 0);
+    return undef
+	if (!defined($fh));
+    print $fh $string;
+    close($fh);
+    system("$VERIFYCRED $filename");
+    if ($?) {
+	print STDERR "Credential in $filename did not verify\n";
+	return undef;
+    }
+    unlink($filename);
+
+    # Use XML::Simple to convert to something we can mess with.
+    my $parser = XML::LibXML->new;
+    my $doc    = $parser->parse_string($string);
+
+    # Dig out the capabilities
+    my ($cap_node) = $doc->getElementsByTagName("capabilities");
+    return undef
+	if (!defined($cap_node));
+    my $capabilities = XMLin($cap_node->toString(), ForceArray => 0);
+
+    # Dig out the slice uuid. Locally, I am not sure if we bother to
+    # keep slices in the DB (they are in the DB at geni central).
+    my ($uuid_node) = $doc->getElementsByTagName("this_uuid");
+    return undef
+	if (!defined($uuid_node));
+    my $this_uuid = $uuid_node->to_literal();
+
+    if (! ($this_uuid =~ /^\w+\-\w+\-\w+\-\w+\-\w+$/)) {
+	print STDERR "Invalid this_uuid in credential\n";
+	return undef;
+    }
+
+    # Dig out the owner uuid. Locally, I am not sure if we bother to
+    # keep users in the DB (they are in the DB at geni central).
+    ($uuid_node) = $doc->getElementsByTagName("owner_uuid");
+    return undef
+	if (!defined($uuid_node));
+    my $owner_uuid = $uuid_node->to_literal();
+
+    if (! ($owner_uuid =~ /^\w+\-\w+\-\w+\-\w+\-\w+$/)) {
+	print STDERR "Invalid owner_uuid in credential\n";
+	return undef;
+    }
+
+    my $self = {};
+    $self->{'capabilities'}  = $capabilities;
+    $self->{'this_uuid'}     = $this_uuid;
+    $self->{'owner_uuid'}    = $owner_uuid;
+    $self->{'string'}        = $string;
+    $self->{'xmlref'}        = $doc;
+    bless($self, $class);
+
+    return $self;
+}
+
+#
+# Might have to delete this from the DB.
+#
+sub Delete($)
+{
+    my ($self) = @_;
+
+    return -1
+	if (! ref($self));
+
+    return 0;
+}
+
+#
+# Sign the credential.
+#
+sub Sign($)
+{
+    my ($self) = @_;
+
+    return -1
+	if (!ref($self));
+
+    # If no capabilities, then allow all rights, no delegation.
+    if (!defined($self->capabilities())) {
+	$self->AddCapability("*", 0);
+    }
+    # This little wrapup is for xmlout.
+    my $capabilities = {"capability" => $self->capabilities()};
+
+    # Every one gets a new unique index, which is used in the xml:id below.
+    my $idx = TBGetUniqueIndex('next_ticket', 1);
+    
+    my $this_uuid  = $self->this_uuid();
+    my $owner_uuid = $self->owner_uuid();
+    my $cap_xml    = XMLout($capabilities, "NoAttr" => 1);
+    $cap_xml =~ s/opt\>/capabilities\>/g;
+
+    #
+    # Create a template xml file to sign.
+    #
+    my $template =
+	"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n".
+	"<credential xml:id=\"ref1\">\n".
+	" <type>capability</type>\n".
+	" <serial>$idx</serial>\n".
+	" <owner_uuid>$owner_uuid</owner_uuid>\n".
+	" <this_uuid>$this_uuid</this_uuid>\n".
+	"  $cap_xml\n".
+        "</credential>\n";
+
+    my ($fh, $filename) = tempfile(UNLINK => 0);
+    return -1
+	if (!defined($fh));
+
+    print $fh $template;
+    close($fh);
+
+    #
+    # Fire up the signer and capture the output. This is the signed credential
+    # that is returned. 
+    #
+    if (! open(SIGNER, "$SIGNCRED $filename |")) {
+	print STDERR "Could not start $SIGNCRED on $filename\n";
+	return -1;
+    }
+    my $credential = "";
+    while (<SIGNER>) {
+	$credential .= $_;
+    }
+    if (!close(SIGNER)) {
+	print STDERR "Could not sign $filename\n";
+	return -1;
+    }
+    $self->{'string'} = $credential;
+    unlink($filename);
+    return 0;
+}
+
+# _Always_ make sure that this 1 is at the end of the file...
+1;
diff --git a/protogeni/lib/GeniSliver.pm.in b/protogeni/lib/GeniSliver.pm.in
index 9f9e46bbce2e101d6c1276b1ff17befa35c8cb8d..4be2ec12eadcfb8baf1d2f2f330ce9c60227ff41 100644
--- a/protogeni/lib/GeniSliver.pm.in
+++ b/protogeni/lib/GeniSliver.pm.in
@@ -25,6 +25,7 @@ use Node;
 use English;
 use Data::Dumper;
 use File::Temp qw(tempfile);
+use overload ('""' => 'Stringify');
 
 # Configure variables
 my $TB		   = "@prefix@";
@@ -96,20 +97,22 @@ sub Stringify($)
 }
 
 #
-# Create a sliver. Not much to it yet.
+# Create a sliver. 
 #
-sub Create($$)
+sub Create($$;$)
 {
-    my ($class, $ticket) = @_;
+    my ($class, $ticket, $uuid) = @_;
     my @insert_data = ();
 
     # Every sliver gets a new unique index.
     my $idx = TBGetUniqueIndex('next_sliver', 1);
-    # And a new uuid. 
-    my $uuid = NewUUID();
     if (!defined($uuid)) {
-	print "*** WARNING: Could not generate a UUID!\n";
-	return undef;
+	# And a new uuid for a local sliver.
+	$uuid = NewUUID();
+	if (!defined($uuid)) {
+	    print "*** WARNING: Could not generate a UUID!\n";
+	    return undef;
+	}
     }
     my $slice_uuid = $ticket->slice_uuid();
     my $owner_uuid = $ticket->owner_uuid();
@@ -127,7 +130,12 @@ sub Create($$)
     DBQueryWarn("insert into geni_slivers set " . join(",", @insert_data))
 	or return undef;
 
-    return GeniSlice->Lookup($idx);
+    my $sliver = GeniSliver->Lookup($idx);
+    return undef
+	if (!defined($sliver));
+    $sliver->{'TICKET'} = $ticket;
+
+    return $sliver;
 }
 # accessors
 sub field($$) { return ((! ref($_[0])) ? -1 : $_[0]->{'SLIVER'}->{$_[1]}); }
@@ -170,11 +178,67 @@ sub GetExperiment($)
     return Experiment->Lookup($self->slice_uuid());
 }
 
+#
+# Get the ticket for the sliver.
+#
+sub GetTicket($)
+{
+    my ($self) = @_;
+
+    return undef
+	if (! ref($self));
+
+    if (!exists($self->{'TICKET'})) {
+	print STDERR "No ticket object associated with $self\n";
+	return undef;
+    }
+    return $self->{'TICKET'};
+}
+
 #
 # Provision a slice. We actually did this when the ticket was requested.
 #
 sub Provision($)
 {
+    my ($self) = @_;
+
+    return -1
+	if (! ref($self));
+
+    #
+    # the node is already allocated to the sliver, but still need to enter
+    # a virt_nodes entry, and possibly more virt table entries, so that the
+    # node will boot properly, and is otherwie controllable.
+    #
+    my $experiment = Experiment->Lookup($self->slice_uuid());
+    if (!defined($experiment)) {
+	print STDERR "Could not map $self to its experiment\n";
+	return -1;
+    }
+    my $node_id    = $self->node_id();
+    return 0
+	if (!defined($node_id));
+    my $node       = Node->Lookup($node_id);
+    if (!defined($node)) {
+	print STDERR "Could not map node $node_id to its object\n";
+	return -1;
+    }
+    my $reservation = $node->Reservation();
+    if (!defined($reservation)) {
+	print STDERR "$node was already released from $self\n";
+	return -1;
+    }
+    if ($reservation->SameExperiment($experiment)) {
+	if ($experiment->InsertVirtNode($node) != 0) {
+	    print STDERR "Could not add virtnode entry for $node to $self\n";
+	    return -1;
+	}
+    }
+    else {
+	print STDERR "$node is reserved to another, not $self\n";
+	# Signal error so we can look at what happened.
+	return -1;
+    }
     return 0;
 }
 
@@ -189,20 +253,83 @@ sub UnProvision($)
 	if (! ref($self));
 
     my $experiment = Experiment->Lookup($self->slice_uuid());
+    if (!defined($experiment)) {
+	print STDERR "Could not map $self to its experiment\n";
+	return -1;
+    }
     my $node_id    = $self->node_id();
+    return 0
+	if (!defined($node_id));
     my $node       = Node->Lookup($node_id);
-    return -1
-	if (!defined($node));
-    my $reservation = Node->Reservation();
-    
-    if (defined($reservation) && $reservation->SameExperiment($experiment)) {
+    if (!defined($node)) {
+	print STDERR "Could not map node $node_id to its object\n";
+	return -1;
+    }
+    my $reservation = $node->Reservation();
+    if (!defined($reservation)) {
+	print STDERR "$node was already released from $self\n";
+	return 0;
+    }
+    if ($reservation->SameExperiment($experiment)) {
 	my $pid = $experiment->pid();
 	my $eid = $experiment->eid();
 	
-	system("$NFREE $pid $eid $node_id");
+	system("export NORELOAD=1; $NFREE -q $pid $eid $node_id");
+	if ($?) {
+	    print STDERR "Could not deallocate $node from $self\n";
+	    return -1;
+	}
+    }
+    else {
+	print STDERR "$node is reserved to another, not $self\n";
+	# Signal error so we can look at what happened.
+	return -1;
+    }
+    return 0;
+}
+
+#
+# Start a slice, which roughly translates to reboot the node.
+#
+sub Start($)
+{
+    my ($self) = @_;
+
+    return -1
+	if (! ref($self));
+
+    my $experiment = Experiment->Lookup($self->slice_uuid());
+    if (!defined($experiment)) {
+	print STDERR "Could not map $self to its experiment\n";
+	return -1;
+    }
+    my $node_id    = $self->node_id();
+    return 0
+	if (!defined($node_id));
+    my $node       = Node->Lookup($node_id);
+    if (!defined($node)) {
+	print STDERR "Could not map node $node_id to its object\n";
+	return -1;
+    }
+    my $reservation = $node->Reservation();
+    if (!defined($reservation)) {
+	print STDERR "$node was already released from $self\n";
+	return -1;
+    }
+    if ($reservation->SameExperiment($experiment)) {
+	#
+	# Reboot and wait?
+	#
+	#system("$NODEREBOOT $node_id");
+    }
+    else {
+	print STDERR "$node is reserved to another, not $self\n";
+	# Signal error so we can look at what happened.
+	return -1;
     }
     return 0;
 }
 
+
 # _Always_ make sure that this 1 is at the end of the file...
 1;
diff --git a/protogeni/lib/GeniTicket.pm.in b/protogeni/lib/GeniTicket.pm.in
index 3e29f903e7be7a78b85489746df1569fb079ec28..19a9fd4a024366de8f3d778b3b857bdd6f40480a 100644
--- a/protogeni/lib/GeniTicket.pm.in
+++ b/protogeni/lib/GeniTicket.pm.in
@@ -37,6 +37,7 @@ my $BOSSNODE       = "@BOSSNODE@";
 my $OURDOMAIN      = "@OURDOMAIN@";
 my $GENICENTRAL    = "https://boss/protogeni/xmlrpc";
 my $SIGNCRED	   = "$TB/sbin/signgenicred";
+my $VERIFYCRED	   = "$TB/sbin/verifygenicred";
 my $NFREE	   = "$TB/bin/nfree";
 
 #
@@ -78,6 +79,19 @@ sub CreateFromSignedTicket($$)
 {
     my ($class, $ticket_string) = @_;
 
+    # First verify the ticket.
+    my ($fh, $filename) = tempfile(UNLINK => 0);
+    return undef
+	if (!defined($fh));
+    print $fh $ticket_string;
+    close($fh);
+    system("$VERIFYCRED $filename");
+    if ($?) {
+	print STDERR "Ticket in $filename did not verify\n";
+	return undef;
+    }
+    unlink($filename);
+
     # Use XML::Simple to convert to something we can mess with.
     my $parser = XML::LibXML->new;
     my $doc    = $parser->parse_string($ticket_string);
@@ -142,8 +156,6 @@ sub CreateFromSignedTicket($$)
     $self->{'idx'}           = $serial;
     bless($self, $class);
 
-    print Dumper($self);
-
     return $self;
 }
 
@@ -182,8 +194,9 @@ sub Grant($$)
 }
 
 #
-# Store the given ticket in the DB. We only do this for signed tickets
-# which we hand out, so we have a record of them. 
+# Store the given ticket in the DB. We only do this for signed tickets,
+# so we have a record of them. We store them on the server and the client
+# side.
 #
 sub Store($$)
 {
@@ -267,12 +280,16 @@ sub Sign($)
     while (<SIGNER>) {
 	$ticket .= $_;
     }
-    close(SIGNER);
+    if (!close(SIGNER)) {
+	print STDERR "Could not sign $filename\n";
+	return -1;
+    }
     $self->{'ticket_string'} = $ticket;
 
     $self->Store($idx) == 0
 	or return -1;
 
+    unlink($filename);
     return 0;
 }
 
diff --git a/protogeni/lib/test.pl.in b/protogeni/lib/test.pl.in
index 389484f95c21d5aebafbde23fd48d452402429fa..dc1274449f13048116cdacd1a54ec8918d07e515 100644
--- a/protogeni/lib/test.pl.in
+++ b/protogeni/lib/test.pl.in
@@ -30,11 +30,18 @@ GeniCMClient::GetTicket($experiment, $resources->[0], $rspec, \$ticket);
 open(T, "> /tmp/T");
 print T $ticket->asString();
 close(T);
-     
 exit(0);
-if ($ticket) {
+     
+if (defined($ticket)) {
     GeniCMClient::CreateSliver($experiment, $ticket, \$sliver);
 }
 
+# Wait for input before proceeding.
+$_ = <STDIN>;
+
+if (defined($sliver)) {
+    print $sliver . "\n";
+    GeniCMClient::DestroySliver($experiment, $sliver);
+}
 
 
diff --git a/protogeni/xmlrpc/Genixmlrpc.pm.in b/protogeni/xmlrpc/Genixmlrpc.pm.in
index a57956492a12fc65e32b5a75ed11b45e952c24a0..5c4f2cc342ae4a37a3efc3b3b427cff492b1ae96 100644
--- a/protogeni/xmlrpc/Genixmlrpc.pm.in
+++ b/protogeni/xmlrpc/Genixmlrpc.pm.in
@@ -30,16 +30,10 @@ use Data::Dumper;
 my $TB		= "@prefix@";
 my $TBOPS       = "@TBOPSEMAIL@";
 my $BOSSNODE    = "@BOSSNODE@";
+my $EMULAB_PEMFILE = "@prefix@/etc/server.pem";
 
 my $debug = 1;
 
-#
-# This is for the Crypt::SSL library, many levels down. It appears to
-# be the only way to specify this.
-#
-$ENV{'HTTPS_CERT_FILE'} = "@prefix@/etc/server.pem";
-$ENV{'HTTPS_KEY_FILE'}  = "@prefix@/etc/server.pem";
-
 ##
 # The package version number
 #
@@ -63,9 +57,29 @@ my $PACKAGE_VERSION = 0.1;
 # If there was an HTTP error, the hash also contains the keys
 # httpcode and httpmsg.
 #
-sub CallMethodHTTP($$@)
+sub CallMethodHTTP($$$@)
 {
-    my ($httpURL,$method,@args) = @_;
+    my ($httpURL, $user, $method, @args) = @_;
+
+    #
+    # This is for the Crypt::SSL library, many levels down. It appears to
+    # be the only way to specify this. Even worse, when we want to use
+    # an encrypted key belonging to a user, have to use the pkcs12 format
+    # of the file, since that is the only format for which we can provide
+    # the passphrase.
+    #
+    if (!defined($user)) {
+	$ENV{'HTTPS_CERT_FILE'} = $EMULAB_PEMFILE;
+	$ENV{'HTTPS_KEY_FILE'}  = $EMULAB_PEMFILE;
+    }
+    else {
+	my $pkcs12 = $user->HomeDir() . "/.ssl/encrypted.p12";
+	my $password;
+	$user->SSLPassPhrase(1,\$password);
+	$ENV{'HTTPS_PKCS12_FILE'}     = $pkcs12;
+	$ENV{'HTTPS_PKCS12_PASSWORD'} = $password;
+	print "$password, $pkcs12\n";
+    }
 
     my $request = new RPC::XML::request($method, @args);
     if ($debug) {
diff --git a/protogeni/xmlrpc/protogeni-client.pl.in b/protogeni/xmlrpc/protogeni-client.pl.in
index f511e2277ac866ba69286aace12596dec10ea670..914fff2737eccd5ebc80f115ee8001037af5b913 100644
--- a/protogeni/xmlrpc/protogeni-client.pl.in
+++ b/protogeni/xmlrpc/protogeni-client.pl.in
@@ -21,7 +21,7 @@ my $server = shift(@ARGV);
 my $method = shift(@ARGV);
 
 my $response = 
-    Genixmlrpc::CallMethodHTTP("https://$server/protogeni/xmlrpc",
+    Genixmlrpc::CallMethodHTTP("https://$server/protogeni/xmlrpc", undef,
 			       $method, @ARGV);
 
 print Dumper($response);
diff --git a/protogeni/xmlrpc/protogeni-cm.pl.in b/protogeni/xmlrpc/protogeni-cm.pl.in
index eb63373450b3630c6ba5350ea38896df6079515e..d23ba6d809982c150c2b2d01433c32baec962276 100644
--- a/protogeni/xmlrpc/protogeni-cm.pl.in
+++ b/protogeni/xmlrpc/protogeni-cm.pl.in
@@ -56,6 +56,22 @@ $EUID = $UID    = $unix_uid;
 $ENV{'USER'}    = $user;
 $ENV{'LOGNAME'} = $user;
 
+#
+# The UUID of the client certificate is in the env var SSL_CLIENT_S_DN_CN.
+# If it actually looks like a UUID, then this correponds to an actual user,
+# and the supplied credentials/tickets must match. At present, if there is
+# no UUID, it is another emulab making a request directly, with no user
+# context, and we just let that pass for now.
+#
+if (exists($ENV{'SSL_CLIENT_S_DN_CN'}) &&
+    $ENV{'SSL_CLIENT_S_DN_CN'} =~ /^\w+\-\w+\-\w+\-\w+\-\w+$/) {
+    $ENV{'GENIUSER'} = $ENV{'SSL_CLIENT_S_DN_CN'};
+}
+else {
+    delete($ENV{'GENIUSER'})
+	if (exists($ENV{'GENIUSER'}));
+}    
+
 #
 # Use libaudit to capture any output from libraries and programs.
 # Send that to tbops so they can be fixed.
@@ -69,6 +85,7 @@ my $responder = Frontier::Responder->new( "methods" => {
     "SA::DiscoverResources" => \&Protogeni::SA::DiscoverResources,
     "CM::GetTicket"         => \&GeniCM::GetTicket,
     "CM::CreateSliver"      => \&GeniCM::CreateSliver,
+    "CM::DestroySliver"     => \&GeniCM::DestroySliver,
     "add"                   => \&Protogeni::add,
    },
 );