Commit 746fe9d8 authored by Leigh B. Stoller's avatar Leigh B. Stoller

Sync up with the trunk wrt credential.rnc (I had been on revision 1.2

for a while). I am still not using the actual rspec definition yet, still
using my adhoc one.
parent cb7cf310
......@@ -100,6 +100,7 @@ CREATE TABLE `geni_slices` (
`hrn` varchar(256) NOT NULL default '',
`idx` mediumint(8) unsigned NOT NULL default '0',
`uuid` varchar(40) NOT NULL default '',
`exptidx` int(11) default NULL,
`created` datetime default NULL,
`creator_uuid` varchar(40) NOT NULL default '',
`name` tinytext,
......@@ -117,6 +118,8 @@ DROP TABLE IF EXISTS `geni_slivers`;
CREATE TABLE `geni_slivers` (
`idx` mediumint(8) unsigned NOT NULL default '0',
`uuid` varchar(40) NOT NULL default '',
`hrn` varchar(256) NOT NULL default '',
`name` varchar(256) NOT NULL default '',
`slice_uuid` varchar(40) NOT NULL default '',
`creator_uuid` varchar(40) NOT NULL default '',
`resource_uuid` varchar(40) NOT NULL default '',
......@@ -125,7 +128,7 @@ CREATE TABLE `geni_slivers` (
`credential_idx` int(10) unsigned default NULL,
`component_uuid` varchar(40) default NULL,
`aggregate_uuid` varchar(40) default NULL,
`status` enum('ready','broken') NOT NULL default 'ready',
`status` enum('created','ready','broken') NOT NULL default 'created',
`rspec_string` text,
PRIMARY KEY (`idx`),
UNIQUE KEY `uuid` (`uuid`),
......@@ -138,6 +141,8 @@ CREATE TABLE `geni_slivers` (
DROP TABLE IF EXISTS `geni_aggregates`;
CREATE TABLE `geni_aggregates` (
`idx` mediumint(8) unsigned NOT NULL default '0',
`hrn` varchar(256) NOT NULL default '',
`name` varchar(256) NOT NULL default '',
`uuid` varchar(40) NOT NULL default '',
`type` varchar(40) NOT NULL default '',
`slice_uuid` varchar(40) NOT NULL default '',
......@@ -147,7 +152,7 @@ CREATE TABLE `geni_aggregates` (
`ticket_idx` int(10) unsigned default NULL,
`component_idx` int(10) unsigned NOT NULL default '0',
`aggregate_idx` int(10) unsigned default NULL,
`status` enum('ready','broken') NOT NULL default 'ready',
`status` enum('created','ready','broken') NOT NULL default 'created',
PRIMARY KEY (`idx`),
UNIQUE KEY `uuid` (`uuid`),
INDEX `slice_uuid` (`slice_uuid`)
......@@ -159,12 +164,13 @@ CREATE TABLE `geni_aggregates` (
DROP TABLE IF EXISTS `geni_tickets`;
CREATE TABLE `geni_tickets` (
`idx` mediumint(8) unsigned NOT NULL default '0',
`ticket_uuid` varchar(40) NOT NULL default '',
`owner_uuid` varchar(40) NOT NULL default '',
`slice_uuid` varchar(40) NOT NULL default '',
`created` datetime default NULL,
`redeem_before` datetime default NULL,
`valid_until` datetime default NULL,
`component_idx` int(10) unsigned NOT NULL default '0',
`component_uuid` varchar(40) NOT NULL default '',
`seqno` int(10) unsigned NOT NULL default '0',
`ticket_string` text,
PRIMARY KEY (`idx`),
......@@ -179,6 +185,7 @@ CREATE TABLE `geni_tickets` (
DROP TABLE IF EXISTS `geni_credentials`;
CREATE TABLE `geni_credentials` (
`idx` mediumint(8) unsigned NOT NULL default '0',
`uuid` varchar(40) NOT NULL default '',
`owner_uuid` varchar(40) NOT NULL default '',
`this_uuid` varchar(40) NOT NULL default '',
`created` datetime default NULL,
......
......@@ -112,6 +112,8 @@ sub Create($$$$)
my $self = {};
$self->{'target'} = $target;
$self->{'owner'} = $owner;
$self->{'uuid'} = undef;
$self->{'cert'} = undef;
$self->{'target_uuid'} = $target->uuid();
$self->{'target_cert'} = $target->cert();
$self->{'owner_uuid'} = $owner->uuid();
......@@ -126,6 +128,8 @@ sub Create($$$$)
# accessors
sub field($$) { return ($_[0]->{$_[1]}); }
sub idx($) { return field($_[0], "idx"); }
sub uuid($) { return field($_[0], "uuid"); }
sub cert($) { return field($_[0], "cert"); }
sub hrn($) { return field($_[0], "hrn"); }
sub target($) { return field($_[0], "target"); }
sub owner($) { return field($_[0], "owner"); }
......@@ -208,14 +212,13 @@ sub CreateFromSigned($$;$)
}
# Dig out the capabilities
my ($cap_node) = $doc->getElementsByTagName("capabilities");
my ($cap_node) = $doc->getElementsByTagName("privileges");
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");
# UUID of the credential.
my ($uuid_node) = $doc->getElementsByTagName("uuid");
return undef
if (!defined($uuid_node));
my $this_cert = $uuid_node->to_literal();
......@@ -228,6 +231,21 @@ sub CreateFromSigned($$;$)
return undef;
}
# 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).
($uuid_node) = $doc->getElementsByTagName("target_uuid");
return undef
if (!defined($uuid_node));
my $target_cert = $uuid_node->to_literal();
my $target_uuid;
GeniCertificate->CertificateInfo($target_cert, \$target_uuid) == 0
or return undef;
if (! ($target_uuid =~ /^\w+\-\w+\-\w+\-\w+\-\w+$/)) {
print STDERR "Invalid target_uuid in credential\n";
return undef;
}
# Dig out the hrn.
my ($hrn_node) = $doc->getElementsByTagName("hrn");
return undef
......@@ -251,8 +269,10 @@ sub CreateFromSigned($$;$)
my $self = {};
$self->{'capabilities'} = $capabilities;
$self->{'target_uuid'} = $this_uuid;
$self->{'target_cert'} = $this_cert;
$self->{'uuid'} = $this_uuid;
$self->{'cert'} = $this_cert;
$self->{'target_uuid'} = $target_uuid;
$self->{'target_cert'} = $target_cert;
$self->{'owner_uuid'} = $owner_uuid;
$self->{'hrn'} = $hrn;
$self->{'string'} = $string;
......@@ -275,8 +295,11 @@ sub Delete($)
if (! ref($self));
if (defined($self->idx())) {
my $idx = $self->idx();
my $idx = $self->idx();
my $uuid = $self->uuid();
DBQueryWarn("delete from geni_certificates where uuid='$uuid'")
or return -1;
DBQueryWarn("delete from geni_credentials where idx='$idx'")
or return -1;
}
......@@ -298,14 +321,32 @@ sub Sign($$)
$self->AddCapability("*", 0);
}
# This little wrapup is for xmlout.
my $capabilities = {"capability" => $self->capabilities()};
my $cap_xml = XMLout($capabilities, "NoAttr" => 1);
$cap_xml =~ s/opt\>/capabilities\>/g;
my $cap_xml = "<privileges>\n";
foreach my $cap (keys(%{ $self->capabilities() })) {
my $can_delegate = $self->capabilities()->{$cap}->{'can_delegate'};
$cap_xml .= "<privilege>";
$cap_xml .= "<name>$cap</name>";
$cap_xml .= "<can_delegate>$can_delegate</can_delegate>";
$cap_xml .= "</privilege>\n";
}
$cap_xml .= "</privileges>\n";
# Every one gets a new unique index, which is used in the xml:id below.
my $idx = TBGetUniqueIndex('next_ticket', 1);
my $hrn = $self->hrn();
#
# Every ticket/credential its own uuid (certificate).
#
my $certificate = GeniCertificate->Create("credential");
if (!defined($certificate)) {
print STDERR "Could not generate new certificate for $self!\n";
return -1;
}
$self->{'cert'} = $certificate->cert();
$self->{'uuid'} = $certificate->uuid();
my $cred_cert = $certificate->cert();
#
# Need the certificates for target and owner of the credential.
#
......@@ -327,11 +368,11 @@ sub Sign($$)
my $template =
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n".
"<credential xml:id=\"ref1\">\n".
" <type>capability</type>\n".
" <type>privilege</type>\n".
" <serial>$idx</serial>\n".
" <owner_uuid>$owner_cert</owner_uuid>\n".
" <target_uuid>$target_cert</target_uuid>\n".
" <this_uuid>$target_cert</this_uuid>\n".
" <uuid>$cred_cert</uuid>\n".
" <hrn>$hrn</hrn>\n".
" <expires>2008-05-10T09:00:00</expires>\n".
" $cap_xml\n".
......@@ -409,14 +450,16 @@ sub Store($)
# Every credential store gets a new unique index.
my $idx = TBGetUniqueIndex('next_ticket', 1);
my $this_uuid = $self->this_uuid();
my $this_uuid = $self->target_uuid();
my $owner_uuid = $self->owner_uuid();
my $uuid = $self->uuid();
# Now tack on other stuff we need.
push(@insert_data, "created=now()");
push(@insert_data, "idx='$idx'");
push(@insert_data, "this_uuid='$this_uuid'");
push(@insert_data, "owner_uuid='$owner_uuid'");
push(@insert_data, "uuid='$uuid'");
my $safe_credential = DBQuoteSpecial($self->asString());
push(@insert_data, "credential_string=$safe_credential");
......
......@@ -678,7 +678,7 @@ sub Create($$$$$)
my $experiment = $slice->GetExperiment();
if (!defined($experiment)) {
print STDERR "Could not map $slice to its experiment\n";
return -1;
return undef;
}
#
......@@ -689,17 +689,17 @@ sub Create($$$$$)
my $node = Node->Lookup($resource_uuid);
if (!defined($node)) {
print STDERR "Could not map node $resource_uuid to its object\n";
return -1;
return undef;
}
my $reservation = $node->Reservation();
if (!defined($reservation)) {
print STDERR "$node was already released from $slice\n";
return -1;
return undef;
}
if (! $reservation->SameExperiment($experiment)) {
print STDERR "$node is reserved to another, not $reservation\n";
# Signal error so we can look at what happened.
return -1;
return undef;
}
#
......@@ -719,7 +719,7 @@ sub Create($$$$$)
"nodeid" => $node->node_id(),
"verbose" => 1 }) < 0) {
print STDERR "Could not create fake jail node on $node\n";
return -1;
return undef;
}
my $vnode = Node->Lookup($vnodes[0]);
$uuid = $vnode->uuid();
......
......@@ -98,6 +98,8 @@ sub Create($$$$)
my $self = {};
$self->{'rspec'} = $rspec;
$self->{'ticket_cert'} = undef;
$self->{'ticket_uuid'} = undef;
$self->{'slice_uuid'} = $slice->uuid();
$self->{'owner_uuid'} = $owner->uuid();
$self->{'slice_cert'} = $slice->cert();
......@@ -129,6 +131,8 @@ sub slice_uuid($) { return field($_[0], "slice_uuid"); }
sub owner_uuid($) { return field($_[0], "owner_uuid"); }
sub slice_cert($) { return field($_[0], "slice_cert"); }
sub owner_cert($) { return field($_[0], "owner_cert"); }
sub ticket_cert($) { return field($_[0], "ticket_cert"); }
sub ticket_uuid($) { return field($_[0], "ticket_uuid"); }
sub ticket($) { return field($_[0], "ticket"); }
sub asString($) { return field($_[0], "ticket_string"); }
sub ticket_string($) { return field($_[0], "ticket_string"); }
......@@ -200,9 +204,23 @@ sub CreateFromSignedTicket($$;$$)
my $rspec = XMLin($rspec_node->toString(), ForceArray => ["node",
"link"]);
# Dig out the ticket uuid.
my ($uuid_node) = $doc->getElementsByTagName("uuid");
return undef
if (!defined($uuid_node));
my $ticket_cert = $uuid_node->to_literal();
my $ticket_uuid;
GeniCertificate->CertificateInfo($ticket_cert, \$ticket_uuid) == 0
or return undef;
if (! ($ticket_uuid =~ /^\w+\-\w+\-\w+\-\w+\-\w+$/)) {
print STDERR "Invalid uuid in ticket\n";
return undef;
}
# 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");
my ($uuid_node) = $doc->getElementsByTagName("target_uuid");
return undef
if (!defined($uuid_node));
my $slice_cert = $uuid_node->to_literal();
......@@ -243,6 +261,8 @@ sub CreateFromSignedTicket($$;$$)
my $self = {};
$self->{'idx'} = undef;
$self->{'rspec'} = $rspec;
$self->{'ticket_cert'} = $ticket_cert;
$self->{'ticket_uuid'} = $ticket_uuid;
$self->{'slice_uuid'} = $slice_uuid;
$self->{'owner_uuid'} = $owner_uuid;
$self->{'slice_cert'} = $slice_cert;
......@@ -284,8 +304,11 @@ sub Delete($)
if (! ref($self));
if ($self->stored()) {
my $idx = $self->idx();
my $idx = $self->idx();
my $uuid = $self->ticket_uuid();
DBQueryWarn("delete from geni_certificates where uuid='$uuid'")
or return -1;
DBQueryWarn("delete from geni_tickets where idx='$idx'")
or return -1;
......@@ -323,6 +346,7 @@ sub Store($)
my $seqno = $self->seqno();
my $slice_uuid = $self->slice_uuid();
my $owner_uuid = $self->owner_uuid();
my $ticket_uuid= $self->ticket_uuid();
#
# For a locally created/signed ticket, seqno=idx. For a ticket from
......@@ -341,6 +365,7 @@ sub Store($)
push(@insert_data, "created=now()");
push(@insert_data, "idx='$idx'");
push(@insert_data, "seqno='$seqno'");
push(@insert_data, "ticket_uuid='$ticket_uuid'");
push(@insert_data, "slice_uuid='$slice_uuid'");
push(@insert_data, "owner_uuid='$owner_uuid'");
......@@ -374,6 +399,18 @@ sub Sign($)
my $rspec_xml = XMLout($self->rspec(), "NoAttr" => 1);
$rspec_xml =~ s/opt\>/rspec\>/g;
#
# Every ticket/credential its own uuid (certificate).
#
my $certificate = GeniCertificate->Create("ticket");
if (!defined($certificate)) {
print STDERR "Could not generate new certificate for $self!\n";
return -1;
}
$self->{'ticket_cert'} = $certificate->cert();
$self->{'ticket_uuid'} = $certificate->uuid();
my $ticket_cert = $certificate->cert();
#
# Create a template xml file to sign.
#
......@@ -384,11 +421,12 @@ sub Sign($)
" <serial>$idx</serial>\n".
" <owner_uuid>$owner_cert</owner_uuid>\n".
" <target_uuid>$slice_cert</target_uuid>\n".
" <this_uuid>$slice_cert</this_uuid>\n".
" <uuid>$ticket_cert</uuid>\n".
" <hrn>$hrn</hrn>\n".
" <expires>2008-05-10T09:00:00</expires>\n".
" <ticket>\n".
" <can_delegate>1</can_delegate>\n".
" <redeem_before>2008-05-10T09:00:00</redeem_before>\n".
" $rspec_xml\n".
" </ticket>\n".
"</credential>\n";
......
......@@ -100,6 +100,7 @@ CREATE TABLE `geni_slices` (
`hrn` varchar(256) NOT NULL default '',
`idx` mediumint(8) unsigned NOT NULL default '0',
`uuid` varchar(40) NOT NULL default '',
`exptidx` int(11) default NULL,
`created` datetime default NULL,
`creator_uuid` varchar(40) NOT NULL default '',
`name` tinytext,
......@@ -117,6 +118,8 @@ DROP TABLE IF EXISTS `geni_slivers`;
CREATE TABLE `geni_slivers` (
`idx` mediumint(8) unsigned NOT NULL default '0',
`uuid` varchar(40) NOT NULL default '',
`hrn` varchar(256) NOT NULL default '',
`name` varchar(256) NOT NULL default '',
`slice_uuid` varchar(40) NOT NULL default '',
`creator_uuid` varchar(40) NOT NULL default '',
`resource_uuid` varchar(40) NOT NULL default '',
......@@ -125,7 +128,7 @@ CREATE TABLE `geni_slivers` (
`credential_idx` int(10) unsigned default NULL,
`component_uuid` varchar(40) default NULL,
`aggregate_uuid` varchar(40) default NULL,
`status` enum('ready','broken') NOT NULL default 'ready',
`status` enum('created','ready','broken') NOT NULL default 'created',
`rspec_string` text,
PRIMARY KEY (`idx`),
UNIQUE KEY `uuid` (`uuid`),
......@@ -138,6 +141,8 @@ CREATE TABLE `geni_slivers` (
DROP TABLE IF EXISTS `geni_aggregates`;
CREATE TABLE `geni_aggregates` (
`idx` mediumint(8) unsigned NOT NULL default '0',
`hrn` varchar(256) NOT NULL default '',
`name` varchar(256) NOT NULL default '',
`uuid` varchar(40) NOT NULL default '',
`type` varchar(40) NOT NULL default '',
`slice_uuid` varchar(40) NOT NULL default '',
......@@ -147,7 +152,7 @@ CREATE TABLE `geni_aggregates` (
`ticket_idx` int(10) unsigned default NULL,
`component_idx` int(10) unsigned NOT NULL default '0',
`aggregate_idx` int(10) unsigned default NULL,
`status` enum('ready','broken') NOT NULL default 'ready',
`status` enum('created','ready','broken') NOT NULL default 'created',
PRIMARY KEY (`idx`),
UNIQUE KEY `uuid` (`uuid`),
INDEX `slice_uuid` (`slice_uuid`)
......@@ -159,12 +164,13 @@ CREATE TABLE `geni_aggregates` (
DROP TABLE IF EXISTS `geni_tickets`;
CREATE TABLE `geni_tickets` (
`idx` mediumint(8) unsigned NOT NULL default '0',
`ticket_uuid` varchar(40) NOT NULL default '',
`owner_uuid` varchar(40) NOT NULL default '',
`slice_uuid` varchar(40) NOT NULL default '',
`created` datetime default NULL,
`redeem_before` datetime default NULL,
`valid_until` datetime default NULL,
`component_idx` int(10) unsigned NOT NULL default '0',
`component_uuid` varchar(40) NOT NULL default '',
`seqno` int(10) unsigned NOT NULL default '0',
`ticket_string` text,
PRIMARY KEY (`idx`),
......@@ -179,6 +185,7 @@ CREATE TABLE `geni_tickets` (
DROP TABLE IF EXISTS `geni_credentials`;
CREATE TABLE `geni_credentials` (
`idx` mediumint(8) unsigned NOT NULL default '0',
`uuid` varchar(40) NOT NULL default '',
`owner_uuid` varchar(40) NOT NULL default '',
`this_uuid` varchar(40) NOT NULL default '',
`created` datetime default NULL,
......
......@@ -14,7 +14,8 @@ include $(OBJDIR)/Makeconf
SBIN_STUFF = signgenicred verifygenicred
LIBEXEC_STUFF =
CTRLSBIN_STUFF =
LIBFILES = credential.xsd sig.xsd xml.xsd
LIBFILES = credential.xsd sig.xsd xml.xsd top.xsd \
protogeni-rspec-common.xsd
# These scripts installed setuid, with sudo.
SETUID_BIN_SCRIPTS =
......
......@@ -14,7 +14,7 @@
# blob will be signed. So, there will be multiple signatures in the
# document, each with a reference to the credential it signs.
#
default namespace = "http://www.protogeni.net/resources/credential/0.1"
#default namespace = "http://www.protogeni.net/resources/credential/0.1"
namespace sig = "http://www.w3.org/2000/09/xmldsig#"
datatypes xs = "http://www.w3.org/2001/XMLSchema-datatypes"
......@@ -36,6 +36,18 @@ PrivilegesSpec = element privileges {
PrivilegeSpec*
}
## Backwards compat my original credential spec.
CapabilitySpec = element capability {
# Name of the capability.
element name { xsd:string { minLength = "1" }},
# Flag indicating this capability can be delegated
element can_delegate { "0" | "1" }
}
## Backwards compat my original credential spec.
CapabilitiesSpec = element capabilities {
CapabilitySpec*
}
## Define a stub for future ticket.
TicketSpec = element ticket {
## Can the ticket be delegated?
......@@ -46,7 +58,7 @@ TicketSpec = element ticket {
# Note: What I really want to do here is reference RSpec as being
# in a separate namespace. But, it's not clear to me how to do this,
# so we basically just use by inclusion
RSpec
anyelementbody
}
## A list of signatures.
......@@ -59,15 +71,21 @@ credentials = element credential {
## The ID for signature referencing.
attribute xml:id {xs:ID},
## The type of this credential. Currently a Privilege set or a Ticket.
element type { "privilege" | "ticket" },
element type { "privilege" | "ticket" | "capability" },
## A serial number.
element serial { xsd:string },
## UUID of the owner of this credential.
element owner_uuid { xsd:string },
## UUID of the target of this credential.
element target_uuid { xsd:string },
## UUID of this credential
element this_uuid { xsd:string },
element uuid { xsd:string },
## HRN
element hrn { xsd:string },
## Expires on
element expires { xsd:dateTime },
## Privileges or a ticket
(PrivilegesSpec | TicketSpec),
(PrivilegesSpec | TicketSpec | CapabilitiesSpec),
## Parent that delegated to us
element parent { credentials }?
}
......
......@@ -17,22 +17,25 @@
blob will be signed. So, there will be multiple signatures in the
document, each with a reference to the credential it signs.
default namespace = "http://www.protogeni.net/resources/credential/0.1"
-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" targetNamespace="http://www.protogeni.net/resources/credential/0.1" xmlns:sig="http://www.w3.org/2000/09/xmldsig#" xmlns:credential="http://www.protogeni.net/resources/credential/0.1">
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" xmlns:sig="http://www.w3.org/2000/09/xmldsig#">
<xs:include schemaLocation="protogeni-rspec-common.xsd"/>
<xs:import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="sig.xsd"/>
<xs:import namespace="http://www.w3.org/XML/1998/namespace" schemaLocation="xml.xsd"/>
<xs:complexType name="anyelementbody" mixed="true">
<xs:group name="anyelementbody">
<xs:sequence>
<xs:any minOccurs="0" maxOccurs="unbounded" processContents="skip"/>
</xs:sequence>
</xs:group>
<xs:attributeGroup name="anyelementbody">
<xs:anyAttribute processContents="skip"/>
</xs:complexType>
</xs:attributeGroup>
<!-- This is where we get the definition of RSpec from -->
<xs:element name="privilege">
<xs:complexType>
<xs:sequence>
<xs:element ref="credential:name"/>
<xs:element ref="name"/>
<xs:element name="can_delegate" type="xs:boolean"/>
</xs:sequence>
</xs:complexType>
......@@ -47,25 +50,48 @@
<xs:element name="privileges">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="credential:privilege"/>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="privilege"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="ticket">
<xs:element name="capability">
<xs:complexType>
<xs:sequence>
<xs:element ref="name"/>
<xs:element name="can_delegate">
<xs:simpleType>
<xs:restriction base="xs:token">
<xs:enumeration value="0"/>
<xs:enumeration value="1"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="capabilities">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" ref="capability"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="ticket">
<xs:complexType mixed="true">
<xs:sequence>
<xs:element name="can_delegate" type="xs:boolean">
<xs:annotation>
<xs:documentation>Can the ticket be delegated?</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element ref="credential:redeem_before"/>
<xs:element ref="credential:rspec">
<xs:element ref="redeem_before"/>
<xs:group ref="anyelementbody">
<xs:annotation>
<xs:documentation>A desciption of the resources that are being promised</xs:documentation>
</xs:annotation>
</xs:element>
</xs:group>
</xs:sequence>
<xs:attributeGroup ref="anyelementbody"/>
</xs:complexType>
</xs:element>
<xs:element name="redeem_before" type="xs:dateTime">
......@@ -85,24 +111,28 @@
<xs:documentation>A credential granting privileges or a ticket.</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element ref="credential:credential"/>
<xs:element ref="credential"/>
</xs:sequence>
</xs:complexType>
<xs:element name="credential">
<xs:complexType>
<xs:sequence>
<xs:element ref="credential:type"/>
<xs:element ref="credential:serial"/>
<xs:element ref="credential:owner_uuid"/>
<xs:element ref="credential:this_uuid"/>
<xs:element ref="type"/>
<xs:element ref="serial"/>
<xs:element ref="owner_uuid"/>
<xs:element ref="target_uuid"/>
<xs:element ref="uuid"/>
<xs:element ref="hrn"/>
<xs:element ref="expires"/>
<xs:choice>
<xs:annotation>
<xs:documentation>Privileges or a ticket</xs:documentation>
</xs:annotation>
<xs:element ref="credential:privileges"/>
<xs:element ref="credential:ticket"/>
<xs:element ref="privileges"/>
<xs:element ref="ticket"/>
<xs:element ref="capabilities"/>
</xs:choice>
<xs:element minOccurs="0" ref="credential:parent"/>
<xs:element minOccurs="0" ref="parent"/>
</xs:sequence>
<xs:attribute ref="xml:id" use="required"/>
</xs:complexType>
......@@ -115,6 +145,7 @@
<xs:restriction base="xs:token">
<xs:enumeration value="privilege"/>
<xs:enumeration value="ticket"/>
<xs:enumeration value="capability"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
......@@ -128,12 +159,27 @@
<xs:documentation>UUID of the owner of this credential. </xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="this_uuid" type="xs:string">
<xs:element name="target_uuid" type="xs:string">
<xs:annotation>
<xs:documentation>UUID of the target of this credential. </xs:documentation>
</xs:annotation>