Ganymede

Ganymede and XML

Starting with the 1.0 series, the Ganymede server gains the ability to import and export data using XML. Like HTML, XML is a plain text data format with structural tagging. Unlike HTML, which has a predefined set of tags that represent the structuring and rendering facilities of modern web browsers, XML has no pre-defined document tags. Instead, XML allows applications to define their own sets of tags for use according to the XML syntactical rules. Ganymede uses XML to structure its data structures in a way that is accessible to other software and even readable by humans. Before we get into discussing the custom tags used by Ganymede, it is worth setting forth a number of facts about XML in general that software needs to know about in order to properly communicate with Ganymede via XML.

A Brief Introduction to XML

Facts about XML:

That's about all you should need to know about XML, at least as far as we'll need to talk about in discussing Ganymede. If you want to read about things like external reference entities, Document Type Definitions/DTD's, or the precise Backus-Naur style specification for what characters are allowed to go where when, you can probably find your way to the original XML standards documents over at www.XML.com.

On Ganymede and XML

Ganymede exports and imports object and schema data using a simple XML format, in which the schema definition section and the object data sections comprise two separate elements. The basic structure of an XML file for Ganymede looks like this:

      <ganymede major="1" minor="0" persona="supergash" password="testpass">
        <ganyschema>
           -- Optional Ganymede Schema Definition Section Here --
        </ganyschema>
        <ganydata>
           -- Optional Ganymede Object Data Section Here --
        </ganydata>
      </ganymede>
    

The ganymede element is the XML file's Document Element, and has two mandatory attributes, major and minor, which specify the major and minor version numbers of the Ganymede XML file format the file adheres to, and two optional attributes, persona and password, which may be used to specify the username and password for the xmlclient to use in attempting to log into the server to apply the changes in the file.

The ganyschema element contains the schema definition for the Ganymede database. This section contains definitions of the types of objects that the Ganymede server knows about, including the fields defined for those objects and the constraints and relationships among those fields and objects. The field definitions in the Ganymede schema definition section control what fields may legally appear in the object data section of a Ganymede XML file, and what kind of data those fields are allowed to contain.

The optional ganydata element contains actual data records from the Ganymede database. The ganydata element contains a number of object elements, each of which contain the data for a single object in the Ganymede database.

Each of these two sections are optional, but an XML file without one of these two sections is pointless, as far as Ganymede is concerned. The sections below discuss these two components of a Ganymede XML file in detail.

Ganymede Schema Definition in XML

The <ganyschema> element defines the structure of the Ganymede database, what types of objects are defined, what fields they have, what kind of data those fields can contained, and what everything is called.

The <ganyschema> element is optional. If you run 'xmlclient -dumpschema' or 'xmlclient -dump', you will get an XML file that includes the <ganyschema> element. If you run xmlclient on an XML file that includes a <ganyschema> element, xmlclient will attempt to edit the server's schema to bring it into alignment with that described in the <ganyschema> element.

The <ganyschema> element contains two other elements, <namespaces> and <object_type_definitions>.

    <ganyschema>
      <namespaces>
         -- Optional Namespace Definitions --
      </namespaces>
      <object_type_definitions>
         -- Object And Field Definitions --
      </object_type_definitions>
    </ganyschema>
    

<namespaces>

The <namespaces> element contains definition elements for all unique namespace structures in the server. A namespace is essentially a unique value index that the server uses to assure that, across all fields in the database connected to the namespace, no value is repeated. Namespaces are used to keep user, group, and system names unique, among other things.

Here is an example <namespaces> element that would be contained at the start of a <ganyschema> element:

    <namespaces>
      <namespace name="username"/>
      <namespace name="groupname"/>
      <namespace name="IPspace"/>
      <namespace name="UserCategory" case-sensitive="true"/>
      <namespace name="systemtype" case-sensitive="true"/>
    </namespaces>
    

In this example, the username, groupname, and IPspace namespaces consider two strings to be equivalent for namespace conflict considerations even if two instances of the string have different capitalization. The UserCategory and systemtype name spaces will not consider two strings to be in conflict if they have different capitalizations.

Namespaces are only significant when they are attached to fields in the <object_type_definitions> section, as we will see shortly.

<object_type_definitions>

In the Ganymede server, all data stored is stored in the form of fields, which are aggregated in objects. Each object stored in the Ganymede server is of a certain type, such as a user, group, system, network, or whatever else has been defined in the server's schema. The objects, in turn, may be grouped into categories. Categories are a way of grouping similar kinds of objects together so that they may be viewed or ignored in the client's tree view.

The <object_type_definitions> element under the <ganyschema> element contains the actual schema definition information in terms of categories, objects, and fields. The corresponding elements for these are the <category>, <objectdef>, and <fielddef> elements.

Here is an example:

    <object_type_definitions>
      <category name="Categories">
        <category name="Admin-Level Objects">
          <category name="Events">
            <objectdef name="System_Events" id="4">
              <classdef name="arlut.csd.ganymede.eventCustom"/>
              <label fieldid="100"/>
              <fielddef name="Event_Token" id="100">
                <comment>Single-word token for this event class</comment>
                <typedef type="string">
                  <maxlength val="32"/>
                  <badchars val=" |"/>
                  <namespace val="eventtoken"/>
                </typedef>
              </fielddef>
              <fielddef name="Event_Mail" id="103">
                <comment>If true, events of this type should be mailed</comment>
                <typedef type="boolean"/>
              </fielddef>
              <fielddef name="Mail_List" id="107">
                <typedef type="string">
                  <vector/>
                </typedef>
              </fielddef>
            </objectdef>
          </category>
        </category>
      </category>
    </object_type_definitions>
    

This example is of a small portion of a Ganymede server's schema definition. This fragment shows an object type called 'System Events' which has three fields defined; a scalar string field called 'Event Token' which is connected to the 'eventtoken' namespace, a boolean checkbox field caleld 'Event Mail', and a vector string field called 'Mail List'.

The 'System Events' object is contained within an 'Events' category, which is contained in turn within a 'Admin-Level Objects' category. The 'Categories' category is itself simply a container for the other categories.. it is the category root node. All <object_type_definitions> elements in Ganymede XML schema definition sections should contain a top-level 'Categories' category, even if you don't want any categorical organization of object types in the client. Note that all <category> elements that are opened are properly closed before the close of the <object_type_definitions> element.

Whenever the Ganymede server refers to object or field names, any spaces in the object or field name is replaced by an underscore in the XML file. This is so that when actual instances of objects are recorded in the <ganydata> element, encoded field names can be used directly as element names. Category names are never referred to from elsewhere in the XML file, so the category names do not have spaces converted to underscores.

<objectdef>

The objectdef element is used to define object types in the Ganymede server. Each object type has a name and a numeric id, which are defined in an open objectdef tag via the 'name' and 'id' attributes. Both of these values must be unique within the <ganyschema> section. The value of the 'id' attribute must be an integer number, and the value of the 'name' attribute must be a string which contains only the letters a-z, in upper or lower case, numbers, a period, a dash, or a space.

Example:

       <objectdef name="User" id="3">
    

Within the objectdef element, there are a couple of optional elements that define optional characteristics of the object, followed by a series of fielddef elements.

The optional elements are the <classdef>, <embedded> and <label> elements.

The classdef element, if present, specifies the fully qualified class name of a Java class to be loaded by the server to manage server operations on objects of this type. The classdef element has a name attribute whose value is the name of the Java class to be used. See the DBEditObject subclassing guide for details on the use of custom classes in the Ganymede server. The classdef element must be empty. That is, it must not contain any other elements.

Example:

       <classdef name="arlut.csd.ganymede.custom.userCustom"/>
    

or (equivalently)

       <classdef name="arlut.csd.ganymede.custom.userCustom"></classdef>
    

The optional embedded element, if present, indicates that the object is not a top-level object which will be shown in the client's object tree and which will have its ownership and permissions tracked independently, but rather is an embedded object which will be encapsulated in another object of a defined type. The embedded element must be empty and it takes no attributes.

Example:

       <embedded/>
    

The optional label element has a fieldid attribute which gives the numeric field id of the field within the object which is to serve as the label field. Objects do not need to have designated label fields, but if they do, they can have only one, and it must refer to a String, IP, Numeric, or Floating Point field defined within the <objectdef> element. Password, Permission Matrix, Object Reference, and Boolean fields may not be specified as label fields. The label element must be empty.

Example:

       <label fieldid="100"/>
    

Once the optional elements are out of the way, we get down to the meat of an object definition element.. the fields. The objectdef element will typically contain a series of fielddef elements, one for each field defined in this object type. These fielddef elements are listed in the order they should appear in the client. The first fielddef element in an objectdef element will appear at the top of the object editing window in the Ganymede client, with subsequent fielddef's in order below the first.

<fielddef>

The <fielddef> element is a complex one, with many possible component elements. There are currently 9 different kinds of fields supported by the Ganymede server, and each of these field types have different options available. The open tag for the fielddef element itself is fairly simple, however. It has just two attributes, both mandatory. These are the same as the ones used in the objectdef tag.. name and id. The contents of the name attribute is limited in precisely the same manner as the name attribute of the objectdef tag's name attribute. It must contain only letters in the standard ASCII set, a-z, the numbers 0-9, a period or dash, and an underscore in place of a space. The id attribute must be an integer number less than 32768.

Example of the fielddef element's open tag:

      <fielddef name="Username" id="100">
    

The fielddef element can contain a couple of optional elements, comment, and invisible.

The comment element is a text containing element. All text between the opening <comment> tag and the closing </comment> tags is treated as a comment to attach to the field. The Ganymede GUI client will show this text as a pop-up tooltip if the user lets the mouse linger on the GUI component. Aside from some text, however, the comment element should not contain any subelements.

The invisible element is an optional empty element, signifying that the field defined by the containing fielddef element should not be visible in the Ganymede client. This is used to establish invisible scratch fields used by custom code associated with the containing objectdef element for various purposes. This is a rather unusual element to define in a fielddef element, and will only be present in special cases.

Here's a (contrived) example of these two optional elements in use.

      <fielddef name="Hidden_Field" id="302">
        <comment>This is a hidden field to be used for namespace manipulations.</comment>
        <invisible/>
      </fielddef>
    

Okay, with the two optional elements out of the way, it's time for the meat of the fielddef element, the typedef element. The typedef element specifies what kind of data field the containing fielddef field definition element defines, and has a single attribute, type. The type attribute can have any of the values listed in the following table:

TypeExplanationVector Allowed?
stringUnicode StringYES
ipI.P. Address, IPv4 or IPv6YES
invidObject ReferenceYES
booleanBooleanNO
dateDate/TimestampNO
numericInteger Number FieldNO
floatDouble precision floatNO
passwordPassword FieldNO
permmatrixGanymede Permissions MatrixNO

For example:

      <typedef type="string">
    

After the typedef element open tag, there can be a variety of elements, depending on the element's type.

First off, the string, ip, and invid field types can be vector fields, in which a single data field can contain more than one value. In that case, the typedef element will contain a vector element.

The vector element is an empty element with a single attribute, maxSize, which has a numeric value specifying the maximum number of values that can be held in this field at a time. For example,

      <typedef type="string">
        <vector maxSize="100"/>
      </typedef>
    

would describe a vector string field that could contain up to 100 strings in the field. Vector fields in Ganymede can not hold more than 32767 elements, so if no maxSize attribute is defined, an implicit value of 32767 is still in effect.

After the optional vector element (for the string, ip, and invid types only), there are a number of optional field constraint elements which differ by type. These are summarized in the table below. The trickiest options conceptually are those associated with the invid field type. I need to link this material to a general discussion of invid fields.

field type element name element details example
string
minlength

The minlegth element is an empty element with a single attribute, val, which contains a numeric value specifying a mandatory minimum number of characters present in this string field.

<minlength val="2"/>
maxlength

The maxlength element is an empty element with a single attribute, val, which contains a numeric value specifying the maximum number of characters allowed in this string field. The Ganymede server supports string values of up to 32767 characters in length, and this limit is present implicitly if the maxlength element is not present in a string field definition.

<maxlength val="8"/>
okchars

The okchars element is an empty element with a single attribute, val, which contains a string value enumerating the characters allowed in this string field. If this optional element is defined in a string typedef element, no characters will be allowed in any field of this type unless that character is present in the val value.

<okchars val="0123456789-"/>
badchars

The badchars element is an empty element with a single attribute, val, which contains a string value enumerating the characters not allowed in this string field. If this optional element is defined in a string typedef element, a character will not be allowed in any field of this type if that character is present in the val value.

<badchars val=":"/>
regexp

The regexp element is an optional empty element with a pair of attributes, one mandatory and one optional. The mandatory attribute is val, which contains a string value which defines a Perl-style regular expression. The optional attribute is desc, which if present will be used as a textual description of the meaning of the regexp. The desc attribute will be provided to the user in an error dialog if they enter a string in the client which does not match the regexp. If no desc attribute is present, the user will be shown the regexp itself in the error message.

regexp is an optional element in the string typedef element. If a regexp element is present, all strings entered into fields of this type will be checked against the regexp. The regexp check is made in addition to any okchars and badchars constraints that are defined in the same typedef.

<regexp val="^[a-z]+[a-z|\d]*$" desc="Usernames may contain letters and numbers, but must begin with a letter."/>
multiline

The multiline element is an empty element with no attributes. This element signifies that this field should be presented in the Ganymede client as a multiline string area rather than a single line text field.

<multiline/>
namespace

The namespace element is an empty element with a single attribute, val, which contains a string naming a namespace defined in the namespaces element contained in the top-level ganyschema element. If this optional element is defined in a string typedef element, all fields associated with the specified namespace will be constrained to contain unique values across the specified namespace.

<namespace val="username"/>
ip
namespace

The namespace element is an empty element with a single attribute, val, which contains a string naming a namespace defined in the namespaces element contained in the top-level ganyschema element. If this optional element is defined in an ip typedef element, all fields associated with the specified namespace will be constrained to contain unique values across the specified namespace.

<namespace val="IPSpace"/>
invid
targetobject

The targetobject element is an empty element with a pair of attributes, name and id, which constrains the type of object this object reference field may point to in the server.

The name attribute contains a string which has the encoded (underscores for spaces) name of the object type to point to, while the id attribute contains the integer numberic id of the object type pointed to. Both may be specified, in which case the Ganymede server will verify that both the id number and the object name are consistent, or either one alone may be used.

If this invid field is intended to be able to point to any kind of object, this is specified by using the name attribute alone, with a value of "*any*". In this case, no id attribute should be specified.

<targetobject name="User" id="3"/>
targetfield

The targetfield element is an optional empty element that specifies the field that this invid field is to be linked with. If a targetfield is specified, the Ganymede server will maintain a symmetric link between this invid field and the target field in objects linked to this field. The target field may be identified using either a name or an id attribute.

The name attribute contains a string which has the encoded (underscores for spaces) name of the field to point to, while the id attribute contains the integer numberic id of the field pointed to. Both may be specified, in which case the Ganymede server will verify that both the id number and the field name are consistent, or either one alone may be used.

<targetfield name="Username" id="103"/>
embedded

The embedded element is an optional empty element that specifies that this invid field is to be used as an edit-in-place field. That is, that objects linked by this field will be handled as if it is contained within the object which holds this field.

<embedded/>
boolean
labeled

The labeled element is an optional empty element with a pair of attributes, true and false. If this element is present, the client will present this boolean field as a pair of radio buttons rather than a single check-box. This can be useful when you've got a pair of choices that don't fit naturally into a yes/no dichotomy.

In general, support for this option has not really been tested, and may not work well.

<labeled true="Normal User" false="Custom Account"/>
numeric
namespace

The namespace element is an optional, empty element with a single attribute, val, which contains a string naming a namespace defined in the namespaces element contained in the top-level ganyschema element. If this optional element is defined in a numeric typedef element, all fields associated with the specified namespace will be constrained to contain unique values across the specified namespace.

<namespace val="uid"/>
password
minlength

The minlegth element is an empty element with a single attribute, val, which contains a numeric value specifying a mandatory minimum number of characters present in this password field.

<minlength val="2"/>
maxlength

The maxlength element is an empty element with a single attribute, val, which contains a numeric value specifying the maximum number of characters allowed in this password field. The Ganymede server supports string values of up to 32767 characters in length, and this limit is present implicitly if the maxlength element is not present in a password field definition.

The crypt encryption hash method supported by Ganymede only considers the first 8 characters of the password in generating the authentication hash, so setting a maxlength larger than 8 characters will not guarantee that Ganymede will require the full password length for login authentication if the crypt method is used.

<maxlength val="8"/>
okchars

The okchars element is an empty element with a single attribute, val, which contains a string value enumerating the characters allowed in this password field. If this optional element is defined in a password typedef element, no characters will be allowed in any field of this type unless that character is present in the val value.

<okchars val="0123456789-"/>
badchars

The badchars element is an empty element with a single attribute, val, which contains a string value enumerating the characters not allowed in this password field. If this optional element is defined in a password typedef element, a character will not be allowed in any field of this type if that character is present in the val value.

<badchars val=":"/>
crypted

The crypted element is an optional, empty element. If this element is present, the Ganymede server will store the contents of this password in UNIX crypt() format.

<crypted/>
md5crypted

The md5crypted element is an optional, empty element. If this element is present, the Ganymede server will store the contents of this password in FreeBSD-style md5crypt() format.

<md5crypted/>
winHashed

The winHashed element is an optional, empty element. If this element is present, the Ganymede server will store the contents of this password in the two Windows NT compatible hash formats used in the Samba encrypted password file.

<winHashed/>
plaintext

The plaintext element is an optional, empty element. If this element is present, the Ganymede server will store the plaintext of passwords stored in this field to disk. Normally, if the Ganymede server has either crypted, md5crypted, or winHashed set, the server will never dump the plaintext of passwords in this field to disk, as it is capable of authenticating logins against any of the supported hash formats. If the plaintext element is present, the password will be preserved in plaintext form in the ganymede.db file, regardless of whether or not the password is also handled via one of the encryption hashes.

<plaintext/>

Schema Example Fragment

The following is a transcript of the User object definition from the GASHARL schema kit in use at ARL. Notable features of this fragment include the Groups invid field which is bidirectionally linked with the Users field in the Groups object type, and the edit-in-place Directory Volume field which contains embedded Embedded Automounter Map Entry objects.

Note also the newline in the middle of the Groups field comment, which is actually preserved faithfully in the Ganymede database.

          <objectdef name="User" id="3">
            <classdef name="arlut.csd.ganymede.custom.userCustom"/>
            <label fieldid="100"/>
            <fielddef name="Username" id="100">
              <comment>User name for an individual privileged to log into Ganymede and/or the network</comment>
              <typedef type="string">
                <maxlength val="8"/>
                <badchars val=" :"/>
                <namespace val="username"/>
                <regexp val="^[a-z]+[a-z|\d]*$" desc="User names may consist of letters and numbers, but must begin with a letter"/>
              </typedef>
            </fielddef>
            <fielddef name="UID" id="256">
              <typedef type="numeric">
                <namespace val="uid"/>
              </typedef>
            </fielddef>
            <fielddef name="Password" id="101">
              <comment>Password for an individual privileged to log into Ganymede and/or the network</comment>
              <typedef type="password">
                <minlength val="3"/>
                <maxlength val="32"/>
                <crypted/>
                <plaintext/>
              </typedef>
            </fielddef>
            <fielddef name="Account_Category" id="273">
              <typedef type="invid">
                <targetobject name="User_Category"/>
              </typedef>
            </fielddef>
            <fielddef name="Full_Name" id="257">
              <typedef type="string">
                <maxlength val="64"/>
                <badchars val=":,"/>
              </typedef>
            </fielddef>
            <fielddef name="Social_Security" id="274">
              <typedef type="string">
                <okchars val="0123456789-"/>
              </typedef>
            </fielddef>
            <fielddef name="Division" id="258">
              <typedef type="string">
                <maxlength val="32"/>
                <badchars val=":,"/>
              </typedef>
            </fielddef>
            <fielddef name="Room" id="259">
              <typedef type="string">
                <maxlength val="32"/>
                <badchars val=": ,"/>
              </typedef>
            </fielddef>
            <fielddef name="Office_Phone" id="260">
              <typedef type="string">
                <maxlength val="16"/>
                <badchars val=":"/>
              </typedef>
            </fielddef>
            <fielddef name="Home_Phone" id="261">
              <typedef type="string">
                <maxlength val="16"/>
                <badchars val=":, "/>
              </typedef>
            </fielddef>
            <fielddef name="Groups" id="264">
              <comment>List of non-primary groups the user is a member of.  
Limited to 16 for NFS.</comment>
              <typedef type="invid">
                <vector maxSize="16"/>
                <targetobject name="Group"/>
                <targetfield name="Users"/>
              </typedef>
            </fielddef>
            <fielddef name="Home_Group" id="265">
              <typedef type="invid">
                <targetobject name="Group"/>
                <targetfield name="Home_Users"/>
              </typedef>
            </fielddef>
            <fielddef name="Login_Shell" id="263">
              <typedef type="string">
                <maxlength val="128"/>
                <badchars val=" :"/>
              </typedef>
            </fielddef>
            <fielddef name="Home_Directory" id="262">
              <comment>UNIX default directory, normally assigned by Ganymede</comment>
              <typedef type="string">
                <maxlength val="128"/>
                <badchars val=" :"/>
              </typedef>
            </fielddef>
            <fielddef name="Admin_Personae" id="102">
              <comment>A list of admin personae this user can assume</comment>
              <typedef type="invid">
                <vector/>
                <targetobject name="Admin_Persona"/>
                <targetfield name="User"/>
              </typedef>
            </fielddef>
            <fielddef name="Netgroups" id="266">
              <typedef type="invid">
                <vector/>
                <targetobject name="User_Netgroup"/>
                <targetfield name="Users"/>
              </typedef>
            </fielddef>
            <fielddef name="Directory_Volume" id="271">
              <typedef type="invid">
                <vector/>
                <targetobject name="Embedded_Automounter_Map_Entry"/>
                <targetfield name="Containing_Object"/>
                <embedded/>
              </typedef>
            </fielddef>
            <fielddef name="Email_Aliases" id="267">
              <typedef type="string">
                <vector/>
                <maxlength val="32"/>
                <badchars val="@"/>
                <namespace val="username"/>
              </typedef>
            </fielddef>
            <fielddef name="Signature_Alias" id="268">
              <typedef type="string">
                <maxlength val="32"/>
                <badchars val="@"/>
              </typedef>
            </fielddef>
            <fielddef name="Email_target" id="269">
              <typedef type="string">
                <vector/>
                <badchars val=":"/>
              </typedef>
            </fielddef>
          </objectdef>
    

Ganymede Object Data Import/Export Definition in XML

While the Ganymede server is capable of expressing its schema definition information in the <ganyschema> section of its XML file, this aspect of Ganymede's XML support is bound to be much less used than the data dumping and loading support. This section discusses the <ganydata> element that may be present in the Ganymede XML file format.

<ganydata>
The <ganydata> element is a container for object data to be updated on the server. When exported, the <ganydata> element contains a complete dump of the server's data state. When imported, the <ganydata> element contains a collection of <object> elements which specify objects to be created, edited, inactivated, or deleted. [Example] , [Top]
Parent(s) Children
NONE <object>
Attributes

NONE
 

The <ganydata> element contains a series of <object> elements, each one corresponding to an object in the Ganymede database. The <object> element itself may contain one element for each field in the object. The open tag for the object element as exported contains possibly four attributes, those being type (required), id, num, and action.

<object>
The <object> element contains data for a single object. When exported, the <object> element contains a complete dump of the object's state, minus the historical fields (last modification data, etc.).When imported, the <object> element contains a collection of field elements whose contents are to be transmitted to the server to update the object identified by the <object>'s attributes. [Example] , [Top]
Parent(s) Children
<ganydata> Various field elements, each with a unique tag name based on the name of the corresponding server field
Attributes

type
The name of the type this object belongs to. This string is case sensitive and must match the name attribute for the type's <objectdef> element, which is the object's type name with underscores substituted for spaces.
id
An optional identifier string for this object, unique among objects of this type within the <ganydata> element in this XML file. If this string is not present, the num attribute becomes mandatory. The id attribute is used for two purposes; the first is to identify an object on the server to be edited, inactivated or deleted if the action attribute specifies these actions. This may only be done if objects of this type on the server have unique and determinable labels. The second is to act as a target for <invid> elements within the XML file to use to refer to <object> elements that are created during the XML file processing.
num
An optional object number for this object, unique among objects of this type on the server. If this number is not present, the id attribute becomes mandatory. If both the id and num attributes are present, the id attribute takes precedent. The number contained in this attribute corresponds to the Invid object number for the object designated by this <object> element. The num attribute is used to select pre-existing objects on the server for editing, inactivation, or deletion. If this <object> has an action attribute value that would cause a new object to be created on the Ganymede server, the num attribute is simply ignored. It is an error to specify a num attribute for an object that does not already exist on the server at the time the xml file is processed.
action
The action attribute is optional, and plays a role only in XML data importing. If the action attribute is present, it may contain one of four strings:
  • create
  • edit
  • inactivate
  • delete

If there is no action attribute specified at import time, the <object> element will be created if the object has a id attribute and no num attribute and if there is no object already on the server that matches the id attribute. Otherwise, the pre-existing object on the Ganymede server matching the identifying attribute will be checked out for editing.

If the action attribute is present and contains "create", the <object> element will cause the Ganymede xmlclient to create a new object, even if an object of the same type that matches the given id attribute already exists on the server. In addition, in such cases all <invid> elements in the XML file with matching type and id attributes will be interpreted to be referring to the newly created <object> element and not any pre-existing object on the server that might match those identifying attributes.

If the action attribute is present and contains "edit", the <object> element will cause the Ganymede xmlclient to seek to check the object out for editing from the server. If no object exists on the server matching the id attribute, an error will be displayed and xmlclient will abort the transaction.

In the unspecified, "create", and "edit" cases, the object element will typically contain a set of field elements. In the "inactivate" and "delete" cases, the <object> element must be empty, and the xmlclient will simply attempt to inactivate or delete the object identified by the id or num attributes.

Aside from the special case of object inactivation or deletion, all <object> elements in a <ganydata> section will contain a set of elements that correspond to fields in the object to be created or edited on the server. The elements for these fields have no fixed tag name. Instead, each field element will start with an open tag that is named according to the name of the field, with spaces transformed into underscores.

For instance, a record to change the values of the "Room", "Groups", "Home Group" and "Email Aliases" fields in a pre-existing object on the server would be represented in the XML file as:

  <object type="User" id="broccol" action="edit">
    <Room>S321</Room>
    <Groups>
        <invid type="Group" id="omssys"/>
        <invid type="Group" id="omsnet"/>
    </Groups>
    <Home_Group><invid type="Group" id="omssys"/></Home_Group>
    <Email_Aliases>
        <string val="abbey"/>
        <string val="jonabbey"/>
    </Email_Aliases>
  </object>

An <object> element contains nothing but such field elements, all of which lack any sort of attributes. The field elements themselves, however, will contain a variety of kinds of elements, depending on the field type. In the above example, the "Room" field is a scalar String field, the "Groups" field is a vector Invid/object reference field, the "Home Group" field is a scalar Invid/object reference field, and the "Email Aliases" field is a vector String field.

In the above example, the Groups and Email_Aliases vector field elements both contain a couple of items. These items will be added to those fields if they are not already present, but the xmlclient will not remove any other items which may already be in those fields.

If you want to assure that after xmlclient finishes its work that there will only be a given list of items in a vector field, you need to do this:

  <object type="User" id="broccol" action="edit">
    <Room>S321</Room>
    <Groups>
        <set>
            <invid type="Group" id="omssys"/>
            <invid type="Group" id="omsnet"/>
        </set>
    </Groups>
  </object>

In this example, the <set> container element will force the xmlclient to set the Groups field to contain only the two items listed, adding or removing items as necessary.

You can also manually add or remove individual items:

  <object type="User" id="broccol" action="edit">
    <Room>S321</Room>
    <Groups>
        <add>
            <invid type="Group" id="omsovr"/>
        </add>
        <delete>
            <invid type="Group" id="omsnet"/>
        </delete>
    </Groups>
  </object>

This will cause the omsovr group to be added and the omsnet group to be removed. You can have as many <add> and <delete> containers as you want within a vector field, but <add> and <delete> are not compatible with <set>. If you use <set>, you may not use <add> or <delete> as well.

If you don't specify <add>, <delete>, or <set>, the xmlclient will treat the items as belonging to an <add> container. For this reason, the following is not allowed:

  <object type="User" id="broccol" action="edit">
    <Room>S321</Room>
    <Groups>
        <invid type="Group" id="omsovr"/>
        <set>
            <invid type="Group" id="omssys"/>
            <invid type="Group" id="omsnet"/>
        </set>
    </Groups>
  </object>

because the omsovr element is considered to be in an <add>, which may not co-exist with a <set> in a single field element.

There are presently nine different types of data fields supported by the Ganymede server, and each of these types has its own rules as to what kinds of elements are allowed within the field element and how they may be structured. For the most part, these rules are very similar for all field types, with just the value carrying element type differing. The following table shows the data carrying element types that correspond to the nine field types.

<string>
The <string> element contains data for Ganymede string fields, but is mandatory only for vector string fields. The <string> element is not necessary for scalar string fields, which support simply placing the content to be placed in the string field directly between the field element's open and close tags. If the <string> element is used for string field content, it must be empty. [Example] , [Top]
Parent(s) Children
<object> NONE
Attributes
val
The contents of the mandatory val attribute actually holds the string value corresponding to this <string> element. As with all XML attributes, double quote characters must be replaced by '&quot;', naked ampersands must be replaced by '&amp;', and anything goes otherwise, including embedded newlines.
Example
<string val="broccol"/>
<boolean>

The <boolean> element is an optional data element for Ganymede boolean fields. Since Ganymede boolean fields are always scalar, you can simply place true, t, false or f (of whatever capitalization) between the field's start and end tags. If you do use the older <boolean> element as a data container, the <boolean> element must be empty.

[Example] , [Top]
Parent(s) Children
<object> NONE
Attributes
val
The contents of the mandatory val attribute holds a string corresponding to the value of this <boolean> element. "1", "true", "t", "yes", and "y", of whatever capitalization, all correspond to a true value. Any other value corresponds to a false value. Note that this is a looser standard than is allowed if you use a text string to represent the true or false value outside of the <boolean> element's val val attribute. In that case, you must use true, t, false, or f, of whatever capitalization.
Example
<boolean val="true"/>
<int>

The <int> element is an optional data element for Ganymede numeric fields. Since Ganymede numeric fields are always scalar, you can simply place a 32 bit signed integer value between the containing field's start and end tags. If you do use the older <int> element as a data container, the <int> element must be empty.

[Example] , [Top]
Parent(s) Children
<object> NONE
Attributes
val
The contents of the mandatory val attribute actually holds the integer value corresponding to this <int> element. This attribute can hold integer values in the range -4294967296 to 4294967295. The only characters allowed in this attribute value are the numeric digits and the minus sign. This same range holds if you skip the <int> element and just place the numeric value between the start and end tags of the containing field element.
Example
<int val="12042"/>
<float>
The <float> element contains a 64 bit floating point value, corresponding to the IEEE 754-1985 specification, for use with Ganymede float fields. As float fields are scalar in Ganymede, only one <float> element at a time may be contained in a float field element. The <float> element must be empty. [Example] , [Top]
Parent(s) Children
<object> NONE
Attributes
val
The contents of the mandatory val attribute actually holds the 64 bit float value corresponding to this <float> element. This attribute can hold floating point values corresponding to the 64 bit floating point value specified by IEEE 754-1985 specification. The text of this attribute must conform to the rules specified in the java.lang.Double class, which generally corresponds to normal rules of ASCII floating point number representation, with support for numbers of the form 6.04E+25 in scientific notation for very large or very small numbers.
Example
<float val="3.141596254"/>
<ip>
The <ip> element contains an IPv4 or IPv6 address. IP fields may be scalar or vector in Ganymede. The <ip> element must be empty. [Example] , [Top]
Parent(s) Children
<object> NONE
Attributes
val
The contents of the mandatory val attribute holds an IPv4 string in standard dotted decimal form, or an IPv6 string, in any RFC 1884 format. The Ganymede server will decide, based on its configuration, whether an IPv6 address will be accepted. Even if IPv6 addresses are supported, IPv4 strings will always be accepted, given the compatibility engineering the IPv6 folks have carried forth.
Example
<ip val="127.0.0.1"/>
<date>
The <date> element contains a Java date value, which is effectively a 64 bit time stamp with millisecond resolution centered at Midnight, January 1, 1970, UTC. As date fields are scalar in Ganymede, only one <date> element at a time may be contained in a field element. The <date> element must be empty. [Example] , [Top]
Parent(s) Children
<object> NONE
Attributes
val
The contents of the val attribute contains a human readable representation of the time stamp held in this <date> element. The val attribute takes data strings of the form "Sun, 03 Dec 1995 00:00:00", in which case the date is interpreted in the local timezone of the machine running the xmlclient or "Sun, 03 Dec 1995 00:00:00 CDT", in which the date will be interpreted by the specified timezone. The standard UNIX date format "Tue Jul 11 01:18:21 CDT 2000" is also supported. The precise form of date val string that may be parsed by the xmlclient, in particular the characters of the date and month, may differ according to the default Java locale of the JVM running the xmlclient. To avoid any possibility for imprecision, it may be necessary to instead use the timecode attribute.
timecode
The contents of the timecode attribute contains a 64 bit signed integer, corresponding to the number of milliseconds before or after Midnight, January 1, 1970, UTC. In order to use a UNIX-style 32 bit timecode to fill in the timecode attribute, you can simply multiply a 32 bit timecode by 1,000.
Example
<date val="Wed 28 Jun 2000 13:13:02" timecode="962215982000"/>
<password>
The <password> element contains a Java password value. As password fields are scalar in Ganymede, only one <password> element at a time may be contained in a field element. The <password> element must be empty. The <password> element must contain exactly one of three optional attributes, plaintext, crypt, or md5crypt, which are explained below. [Example] , [Top]
Parent(s) Children
<object> NONE
Attributes
plaintext
This attribute, if present, contains a password string in plain text. The client will transmit this password to the server, which will generate the UNIX crypt and md5Crypt and the Windows NT/Samba hashes according to the schema configuration for this field.
crypt
This attribute, if present, contains a password string pre-hashed in UNIX crypt() format. The client will transmit this password to the server, and will clear any pre-existing plain text or alternately hashed password information stored in this field in the server.
md5crypt
This attribute, if present, contains a password string pre-hashed in FreeBSD-style md5Crypt() format. The client will transmit this password to the server, and will clear any pre-existing plain text or alternately hashed password information stored in this field in the server.
lanman
This attribute, if present, contains a password string pre-hashed in the LANMAN encoding used by older versions of Windows networking. This hash format is one of the two password encryption formats used by the Samba password file. The client will transmit this password to the server, and will clear any pre-existing plain text or alternately hashed password information stored in this field in the server. The lanman and ntmd4 hashes may be set as a pair, in which case all other hashes are cleared.
ntmd4
This attribute, if present, contains a password string pre-hashed in the Unicode-md4 encoding used by Windows NT and Windows 98 and later. This hash format is one of the two password encryption formats used by the Samba password file. The client will transmit this password to the server, and will clear any pre-existing plain text or alternately hashed password information stored in this field in the server. The lanman and ntmd4 hashes may be set as a pair, in which case all other hashes are cleared.
Example
<password crypt="nxGots4NO.BJY"/>
<invid>
The <invid> element contains a Ganymede object reference value, which is used to identify an object pointer in an invid field on the Ganymede server. The <invid> element must be empty. [Example] , [Top]
Parent(s) Children
<object> NONE
Attributes
type
This attribute is mandatory, and contains an XML-encoded (underscores for spaces) object type string, with proper capitalization, to identify the kind of object this <invid> element is pointing to.
id

This attribute, if present, contains a string that is meant to uniquely identify a target object of type matching the value of the type attribute in this <invid> element on the Ganymede server. The targeted object may exist prior to XML file processing on the Ganymede server, or it may be created by processing of other <object> elements in the XML file by the xmlclient. If an <object> element of matching type with matching id is defined with an action attribute value of create, then all <invid> elements in the XML file with that type and id will point to the newly created object, and not any pre-existing object on the server that shared that type and id.

Not all types of objects on the server will have be addressable by id. Some types of objects, such as embedded objects within user or system objects, may not have a defined unique label field. This should be by far the exception rather than the rule, but for such cases, objects on the server may be addressed using the num attribute rather than the id attribute.

num
This attribute, if present, holds an object number on the Ganymede server, and is used to address a pre-existing object on the server. This attribute should only be used when you explicitly want to address an object on the server, regardless of whatever other activity the <ganydata> element in the XML file defines.
Example
<invid type="User" id="broccol"/>

Example

For example, a user object from the GASH schema kit might be represented in an XML file in the following fashion:

      <object type="User" id="broccol">
        <Username>broccol</Username>
        <UID>12003</UID>
        <Password><password crypt="j8hgwcyw232Jo"/></Password>
        <Account_Category><invid type="User_Category" id="normal"/></Account_Category>
        <Full_Name>Jonathan Abbey</Full_Name>
        <Social_Security>574743325</Social_Security>
        <Division>CSD</Division>
        <Room>S321</Room>
        <Office_Phone>3199</Office_Phone>
        <Home_Phone>335-7681</Home_Phone>
        <Groups>
          <invid type="Group" id="omsprl"/>
          <invid type="Group" id="omsovr"/>
          <invid type="Group" id="omssys"/>
          <invid type="Group" id="genweb"/>
          <invid type="Group" id="gendof"/>
          <invid type="Group" id="omsnet"/>
          <invid type="Group" id="ganycvs"/>
          <invid type="Group" id="omjrst"/>
        </Groups>
        <Home_Group><invid type="Group" id="omssys"/></Home_Group>
        <Login_Shell>/bin/tcsh</Login_Shell>
        <Home_Directory>/home/broccol</Home_Directory>
        <Admin_Personae>
          <invid type="Admin_Persona" id="broccol:GASH Admin"/>
          <invid type="Admin_Persona" id="broccol:supergash"/>
        </Admin_Personae>
        <Netgroups>
          <invid type="User_Netgroup" id="omg-u"/>
          <invid type="User_Netgroup" id="omguse-u"/>
          <invid type="User_Netgroup" id="supad1-u"/>
        </Netgroups>
        <Directory_Volume>
        <object type="Embedded_Automounter_Map_Entry" id="103" num="103">
          <Automounter_Map><invid type="Automounter_Map" id="2"/></Automounter_Map>
          <NFS_Volume><invid type="NFS_Volume" id="23"/></NFS_Volume>
        </object>
        </Directory_Volume>
        <Email_Aliases>
          <string val="jonabbey"/>
          <string val="abbey"/>
          <string val="rust-admin"/>
        </Email_Aliases>
        <Signature_Alias>jonabbey</Signature_Alias>
        <Email_target>
          <string val="broccol@arlut.utexas.edu"/>
          <string val="broccol@csdsun7.arlut.utexas.edu"/>
        </Email_target>
        <Owner_list>
          <invid type="Owner_Group" id="OMG"/>
        </Owner_list>
      </object>
    

Last modified: Fri Sep 15 01:40:42 CDT 2000, Jonathan Abbey