userKit README

Author: Jonathan Abbey
Release: $name:  $
Version: $Revision: 1.30 $
Last Mod Date: $Date: 2001/10/05 20:18:43 $
--------------------------------------------------------------------------------

userKit is an add-on schema kit for use with Ganymede 1.0.  It is
designed to be installed on top of an installed Ganymede server tree.
You will have to have downloaded, configured, and installed the
Ganymede server before you will be able to make use of this package.

userKit will customize your Ganymede server to support management of
user and group accounts for UNIX, Samba, and Windows NT.  It is
intended to serve as a template and as a starting point for further
customizations of the Ganymede server.

userKit, like all schema kits, accomplishes several things.  First, it
specifies a database schema definition for the Ganymede server.  The
schema definition defines the types of objects to be stored in the
Ganymede server, their attributes, and their relationship to each
other.  Second, it includes a set of custom plug-in Java classes that
customize the Ganymede server's behavior during object editing and at
transaction commit time.  Thirdly, it includes scripts that can import
data from your environment into the Ganymede server, using the
provided schema definition.  And finally, it includes scripts that can
take network directory files generated by the Ganymede server and
integrate them into your network environment.

This README will walk you through the steps involved in installing
and using userKit with the Ganymede system.  You may want to scan
through this whole document before beginning to install userKit so
that you'll have a good idea how everything fits together.

1. Installing the Schema Kit
----------------------------

The first thing you'll need to do, after unpacking the userKit archive,
is to install userKit on top of your Ganymede server.  The Ganymede
server's architecture supports installation of a single schema kit
at a time, so you can only install userKit if you don't already
have a schema kit installed in your Ganymede server directory.

Installing userKit is just about as simple as can be.  All you have to
do is to run the 'installKit' script in the userKit distribution
directory.  installKit will ask you a couple of questions:

  Where is the Ganymede server installed at?

     This is asking for the directory where you installed
     the Ganymede server with the 'installServer' script from the
     Ganymede distribution.  You can provide an absolute or relative
     path to the directory.

  Where are the Java binaries located at?

     This is asking for the directory that contains the javac compiler
     and the java jvm.

Once you have answered these two questions, installKit will find the
Ganymede server directory and copy itself into place, customizing and
installing files as needed to integrate itself into the server.  When
done, the userKit will be installed under the Ganymede server
directory, in a subdirectory called 'schema'.

Once installed, the <server>/schema directory contains several further
subdirectories, and a number of files.

  Modules/      README        makeArchive*  output/   scripts/
  NTscripts/    installKit*   schema.xml    src/

The src directory contains all of the source code for the custom
plug-in classes provided by userKit.  custom.jar contains all of these
class files in a Java JAR archive that the Ganymede server will
look at to find any plug-in classes registered.

The scripts directory contains a number of scaffolding scripts that
support installation of userKit into the Ganymede server directory.

The NTscripts directory contains files that are intended to be used
on a Windows NT Primary Domain Controller to handle Windows NT
account synchronization.

The makeArchive script uses the contents of the scripts directory to
regenerate the userKit distribution from scratch, so you can
distribute modified versions of userKit as a complete and installable
schema kit package.

The output directory is where the Ganymede server will write
custom network directory files, and where userKit will install
the scripts to be run when the Ganymede server does an update.

The schema.xml file is an XML-formatted description of the database
definition schema used by the userKit.

The loader.pl script is responsible for importing data from your
environment and combining it with the schema.xml file to produce a
data.xml file which can be used to initialize the server.  The Modules
directory contains an XML::Writer module which is used by loader.pl.
The loader.pl script is configured to look for modules in the Modules
directory, but if you like, you can run the install-modules.pl script
as root to install the XML::Writer module in your Perl5 installation
if you want to be able to use the XML::Writer module in other code.

That's the brief tour of what you get when you install userKit.  Now
we'll talk about the steps you'll have to perform in order to get
everything working in your environment.

2. Loading Data and Bootstrapping Your Server
---------------------------------------------

So, you've installed your Ganymede server and you have installed the
userKit files on top of the server, resulting in the creation of a
'schema' directory under your Ganymede server's top level directory.

At this point you should start the server.  The server will now be
able to find and load any custom classes from the custom.jar file that
installKit created and placed in the schema directory.

To do this, cd to the top-level server directory and run

  bin/runServer >& server.log &

if you are running csh or tcsh, or

  bin/runServer > server.log 2>&1 &

if you are running sh or bash or ksh.

Then you can run

  tail -f server.log

to see a running log of what the server is doing.  You'll probably
want to dedicate a window to watching the server log while you
do the data and schema loading described below.

When you start the server for the first time, it will initialize
itself with the default Ganymede schema, which includes only those
data types that the server depends on for its own functioning.  A
newly started Ganymede server will not know how to generate any
networking files, nor will it know how to use any of the classes
included in the schema kit's custom.jar file.

In order to educate the server about the data types we want to manage,
we need to load a database definition schema into the server.  The
schema.xml file in the schema directory fully describes the userKit
database definition schema.  The schema.xml file is easy to read,
and it follows the <ganyschema> entity definition described in the
file xml.html in the Ganymede server's doc directory.

There are two ways to load this schema definition into the server.
Both require that you already have the server up and running.  If you
just want to configure the server's schema without loading any data or
configuring how external builds are handled, you can simply run the
xmlclient on the schema.xml file.  To do this, simply cd to the
top-level server directory and run

  bin/xmlclient schema/schema.xml

Assuming the server is running, xmlclient will prompt you for the
supergash password you chose when you installed the server.  It
will then connect to the server and configure the server's
database definition schema.

Generally speaking, though, if you are using userKit, you won't do
this.  Instead, you'll run the loader.pl script generated in the
schema directory.  loader.pl will generate you an XML file that
can be used to initialize the server's database definition schema, and
will also initialize the actual data in the server's database
with user and group accounts from your local system, the Ganymede
permissions system, and the builder task database that is responsible
for generating network data files when data in Ganymede changes.

loader.pl will ask you a number of questions to learn what data you
want imported into Ganymede for use with userKit and what sort of data
export options you want supported.

These questions are as follows:

  1. Where is the passwd file that you want to import?

    The loader.pl script should be able to process just about any
    standard UNIX passwd file.  It can also import from a standard
    passwd NIS map if you have it.  In that case, do
    'ypcat passwd > myfile' to capture the NIS passwd map, and then
    provide that filename to this question.

  2. Where is the shadow file that you want to import?

    If you are operating on a system that uses a separate shadow file,
    tell loader.pl that here.  loader.pl will look in the directory
    where you told it to find your passwd file, and if it sees a
    file named 'shadow' or 'master.passwd', it will assume that
    you'll want to load data from it.  If you don't, enter 'none'.

    Note that you will most likely need to run loader.pl as root in
    order for it to be able to read the shadow file.  If you run
    loader.pl without root privileges and try to read your system
    shadow password file, loader.pl will warn you that it can't read
    the file, and any crypted passwords from your shadow file
    will be ignored.

  3. Where is the group file that you want to import?

    loader.pl will try to find a group file in the same directory
    that the passwd file was found.  Once again, loader.pl should
    be able to deal with any standard UNIX group file.  You can
    use a group NIS map here as well, just use a temporary file
    to capture the group map, as 'ypcat group > myfile2'.

  4. Do you want to import a shells list?

    userKit is able to import your /etc/shells file to provide a standard
    list of shell choices to your users in Ganymede.  If you've got
    an /etc/shells file, go ahead and say yes here.

    The /etc/shells file is simply a text file listing the acceptable
    shells for your users, one per line.

    5. Where is the shells file that you want to import?

      Pretty self-descriptive.  The default is '/etc/shells'.

  6. Do you want to produce generic UNIX/Linux passwd and group files?

    You probably want to say yes to this, unless you know you only want
    FreeBSD-style passwd, master.passwd, and group files and/or NT/Samba
    files generated.  Saying yes to this will make userKit set up the
    default UNIXBuilderTask, which is designed to write out files for
    use with pretty much any generic Unix.

    Note that because shadow files vary so much in format between
    operating systems, UNIXBuilderTask does not attempt to support
    shadow files.  If you want to use a shadow file on your particular
    system, it should be a fairly simple matter to write a Perl script
    to split the passwd file generated by UNIXBuilderTask into
    passwd and shadow files.

    7. Do you want to use MD5 password hashing under Linux?

      userKit has the ability to import, export and authenticate using
      FreeBSD-style md5 password hashing.  If you say yes to this, the
      passwd file generated by userKit when transactions are committed will
      have md5-hashed passwords where possible.  If the /etc/passwd file
      you provided for question 1 has passwords hashed using the old-style
      UNIX crypt() function, then those user accounts will remain crypt-hashed
      until such time as your users' passwords are changed in Ganymede. 

      8. Do you want to generate standard crypt-based password files as well?

        Ganymede and userKit are capable of maintaining passwords in both
        hash formats, which may be useful if you want to support both types
        concurrently.

  9. Do you want to produce BSD-specific passwd files?

    Thanks to Matt Bush and Matt Knopp, I do happen to know the specific
    standard for passwd, master.passwd (the BSD shadow file) and group under
    FreeBSD/BSDI.  If you want to register the BSDBuilderTask to support
    those operating systems, say yes here.

    10. Do you want to generate a separate master.passwd shadow file for BSD?

      If you say yes here, BSDBuilderTask will omit the passwords from
      the BSD passwd file and place them into the BSD master.passwd file
      instead.

    11. Do you want to use MD5 password hashing under BSD?

      As with the Linux support, the BSDBuilderTask is capable of writing
      out passwords in MD5 format.  Say yes here if that's what you want.

  12. Do you want to support generation of an encrypted Samba password file?

    Saying yes here will result in the NTBuilderTask being registered,
    with direction to generate an smb.passwd file
    when transactions are committed, containing records for those
    user passwords that the Ganymede server has had an opportunity to
    see the plaintext for.

    13. What version of Samba do you want to support?

      Version 2.0 and later of Samba use a slightly different password file
      format than the 1.0 series did.  userKit is able to generate either
      version of this file.  Choose '1' or '2' here.

  14. Do you want to support password synchronization to NT domain controllers?

    Saying yes here will result in the NTBuilderTask being registered,
    which will write out files to support synchronization to a freestanding
    Windows NT Primary Domain Controller when transactions are
    committed.  This file will include the plain text of any user
    passwords that have been entered or changed in Ganymede.  We have
    scripts that can run on a Windows NT primary domain controller that
    will take user and group information and synchronize Ganymede
    passwords and accounts onto an NT Domain Controller.

    See section 8 below for full details on using the Ganymede
    userKit with Windows NT and Samba.

  15. What shall the default home directory prefix for new user accounts be?

    One of the user fields necessary in a UNIX passwd file is the home
    directory field.  This question is asking you what directory path should
    be the default for newly created users.  Typically this will be '/home'
    or the like.  This is a convenience feature of userKit, much like
    the support for importing a shells list, and your answer here will
    not stop an admin who is creating a new user from choosing a
    different path.

Once you have answered all of loader.pl's questions, it will process
your password, (optional) shadow, and group files, along with the
schema.xml file, to generate a new data.xml file.  This file will
contain everything necessary to get the Ganymede server ready to
go with your data.

Once your data.xml file is generated, all you have to do to load it is
to make sure the server is running, cd to the top level of your server
directory and execute

  bin/xmlclient schema/data.xml

just as you would if you wanted to load schema.xml by itself

Note that loader.pl is designed to bootstrap the server from scratch,
so it will create a variety of objects in the server as needed to
register various builder tasks, to create admin roles, and more.  If
you want to add data to the server once it has been initialized and
has been running for awhile, you'll probably want to hand craft some
XML to do it, and you should see the file doc/xml.html in the server
directory for details.

However, if you look at the loader.pl script, you'll see that there is
a variable named '$importDataOnly'.  If you edit the script and set
this variable to 1, loader.pl will let you just import passwd and
group data, and it will only include that data in the data.xml file
that it generates.  This can be useful if you want to import
additional user and group accounts into Ganymede after initializing
the server with an initial data set.  Just remember that it is your
responsibility to make sure that there are no overlaps in user and
group names and uid's and gid's between the data you want to add to
your userKit server and that which you initially loaded into the
server.

Finally, bear in mind that neither the schema.xml file nor the
data.xml file are consulted by the Ganymede server directly.  The
purpose for these files is to be loaded into the server using the
xmlclient.  If you decide you want to change the Ganymede schema, you
should either use the Ganymede Schema Editor which is accessible from
within the admin console, or you can hand-edit the schema.xml file and
reload it with the xmlclient.  If you do use the schema editor, you
can subsequently run 'xmlclient -dumpschema > newschema.xml' to
generate a new xml file with your revised schema.

3. Loading Data - Permissions and Ownership
-------------------------------------------

The Ganymede server is designed around the ability to delegate
administration to discrete administration teams, each of which share
ownership and responsibility over a collection of objects in the
Ganymede server.

When you initialize the Ganymede server with your user and group data
loaded, userKit has no way of knowing how you want control over your
users and groups to be divided.  Since there's not really any
effective way to delegate control over portions of an /etc/passwd file
without something like Ganymede, you probably don't even have your
users and groups separated by administrative subunit.

Because of this, userKit imports all users and groups without
assigning any ownership to them.  This means that all users and groups
imported are implicitly owned by 'supergash', which is simply the
Ganymede 'root' account.  Logging in with the supergash account will
give you the ability to create new users and groups, and to edit or
delete existing ones.

Using the supergash account for daily activities is bad for two
reasons, however.  The first reason is simply that it is too powerful.
Anyone that you give supergash access to will be able to make any
changes to anything in the system at will, from your user' names and
uid's to the configuration options you have set in your registered
task.  The second reason is that you probably won't know what *person*
actually logged in and messed with stuff.

To get around the second problem, Ganymede allows you to create admin
personae.  All you have to do is edit a user registered in Ganymede,
click on the 'Personae' tab, and hit the 'Create' button.

You'll see a new panel appear that will let you fill in various fields
to set up a new admin persona.  The Persona Name can be something like
'supergash' or 'Group Admin', it doesn't really matter.  Whatever
persona name you choose will be suffixed to the user's name to form
their complete admin name.  So if you have a user 'jonabbey' and you
create them a Persona named 'supergash', you'll have an admin persona
entry called 'jonabbey:supergash'.

You'll need to give this persona a unique password, and then set its
owner sets and roles.  The owner sets control what objects the persona
will have ownership over, and the roles define what permissions this
admin persona will have, both over objects that it owns and objects in
the database at large.

Right now, you won't have any owner sets other than 'supergash', which
is a special group that 'owns everything'.  Any admin persona that is
a member of the supergash Owner Group will have the full power of the
supergash account, but when they log in you will see in the logs what
user was acting with supergash powers.

For everything short of a supergash-level admin, you'll need an owner
group and one or more roles.  You create a new owner group by opening
up the 'Admin-Level Objects' folder at the top of the tree in the
Ganymede client, then 'Permissions'.  Right-click on the 'Owner Group'
folder and select 'Create' in the pop-up menu.  Set the name for the
Owner Group, then click on the 'Objects Owned' tab.  Choose 'User' and
then use the selector that appears to move users into the group.  Do
the same thing with 'Group', and hit commit.  Bear in mind that all
objects may be in as many Owner Groups as you like, so don't worry if
you need to have a single user or group editable by more than one
admins who would not ordinarily share access to all objects in the
server.

Now you can create more limited personae.  Edit a user with a
supergash-level account, create a new persona, set the persona name
and password, then add the persona to the Owner Group and Roles you
want.  Commit, and then that admin persona will have the powers
granted by the Role(s) you have chosen over objects in the Owner
Group(s) you have chosen.

When it comes to Roles, there's probably not a whole lot of variety
that you need to worry about with a schema design as simple as that
supported in userKit. userKit has a 'Group Admin' role that is
predefined.  The Group Admin role allows admin personae that have that
role to be able to do most administrative actions on owned user and
group objects, but not to do things like change uid's and gid's, or to
rename users and groups.  This is probably about right for the admins
you want to delegate user and group administration to.

Note that in addition to the 'Group Admin' Role, there is also the
'Default' Role, which everyone in the Ganymede server has, whether
they are logged in with an admin persona or just as an end-user.

End-users automatically own themselves, so the 'Owned Object Bits'
table in the Default Role is where you go to change what users are
allowed to do to their own accounts when they log into Ganymede, or
when they use the command-line or web password change utilities that
come with Ganymede.  The 'Default Bits' table in the Default Role
controls what end-users are allowed to see in the Ganymede database.
You may want to change the Default Bits a bit if you don't want to let
your users see everything.  As shipped with userKit, all users are
allowed to look at all User and Group objects in the server.

Remember, everything in Ganymede is customizable, so if you want to
change how your users and groups are divided, or grant or retract
permissions, go for it.

4. Server Operations - Data File Writing
----------------------------------------

At this point I'm going to assume you were able to successfully load
the userKit schema and your user data into Ganymede using the data.xml
file generated by loader.pl.

So, what now?

Ganymede's purpose is to provide an intelligent database system that
can support delegation of administration powers to a group of
administrators, and that can provide fine-grained simultaneous editing
support, so all of your admins could be working in Ganymede at the
same time, browsing the database and creating, editing, and deleting
users and groups.

Of course, there's not much point in having a database holding your
user and group accounts if that's all there is to things.  The whole
point of Ganymede is that it be able to update your network
environment whenever things in the database change.  Ganymede does
this through a system of builder tasks that are asynchronously executed
after a transaction has been committed in the server.  These
builder tasks are registered in the Ganymede server's database under

  Admin-Level Objects/Task

The Task objects in the server specify the conditions under which a
task is to be run, and the Java plug-in class that contains the code
for that task.  Most tasks registered in the server are configured to
run on a periodic basis, to do housekeeping, or are configured to
run when ordered from the admin console's task monitor.

Builder tasks are different.  All builder tasks have the 'Run on
Transaction Commit' checkbox selected, and they are automatically
schedule for execution immediately after a transaction is committed
to the database.

userKit includes three Builder Tasks.  These are UNIXBuilderTask,
BSDBuilderTask, and NTSambaBuilderTask.  Depending on what you answer
to the loader.pl questions, any or all of these builder tasks will be
registered in the Ganymede server when you load the data.xml file with
xmlclient.

The builder tasks are designed to operate in two phases.  In the first
phase, the BuilderTask will write out one or more data files to disk.
Then, in phase two, the BuilderTask will execute an external script
which is meant to read those data files, process them, and propagate
them into the network environment, whether that means something as
simple as copying a passwd file to /etc, or as involved as doing a
complete rebuild of a dozen NIS maps and a DNS server reload.  It's up
to you.

All builder tasks have some things in common, though.  All of them
write out data files to subdirectories of the schema/output directory
under your server's installation directory.  All of them automatically
save backup copies of any old data files into the directory defined by
the 'ganymede.builder.backups' directory specified in the Ganymede
server's ganymede.properties file.

By default, this is the backups directory under the server
installation directory.  All files to be overwritten by newly written
data files are saved to the backups directory, in daily directories,
which contain time stamped copies of these backups.  Every 24 hours,
these daily directories are compressed and archived into zip files.

This is strictly for operational peace of mind.  Nothing in the
backups directory is ever used by the Ganymede server or by userKit
scripts, and you can disable this function if you want.  See the
Ganymede install guide for more details.

The next couple of sections will discuss configuration options for
userKit in the Ganymede server, then we'll talk about the actual
scripts themselves.

5. Server Operations - Task Options
-----------------------------------

There are three separate BuilderTasks included with userKit.  One or
more of them may have been specified in the data.xml file, depending
on how you answered the questions put to you by loader.pl.  These
builder tasks are:

  Unix Builder Task

  BSD Builder Task

  NT/Samba Builder Task  

Each of these builder tasks have a number of options that are defined
in the "Option Strings" field in their Ganymede task object.  These
options determine what files will be generated by these builder
tasks, where they will be placed, and what external script will
be run after they have been written out.  Most of these option
strings are in the form of label=value.  The options recognized by
the userKit builder tasks are as follows:

  Unix Builder Task

   If you answered yes to the question 'Do you want to produce
   generic UNIX/Linux passwd and group files?', UnixBuilderTask
   registration will be added to the data.xml file by loader.pl.

   The following option strings may be included by loader.pl:

    passwdFile

      The filename of the UNIX-standard crypt()-based password file
      that Unix Builder Task will write out when user information
      in the Ganymede database is changed.

      loader.pl will register the option string
      passwdFile=<serverdir>/schema/output/unix/passwd by default if
      you request support for the standard UNIX passwd file format
      without md5 hashing.

    groupFile

      The filename of the UNIX-standard group file that Unix Builder
      Task will write out when user information in the Ganymede
      database is changed.

      loader.pl will register the option string
      groupFile=<serverdir>/schema/output/unix/group by default.

    md5passwdFile

      The filename of the md5Crypt()-based password file that Unix
      Builder Task will write out when user information
      in the Ganymede database is changed.

      loader.pl will register the option string
      md5passwdFile=<serverdir>/schema/output/unix/md5.passwd by
      default, if you request md5 support.

    buildScript

      The filename of the executable script or program on disk to
      be run by the Ganymede server once Unix Builder Task has written
      out all of its data files.

      loader.pl will register the option string
      buildScript=<serverdir>/schema/output/unixBuild by default.

  BSD Builder Task

   If you answered yes to the question 'Do you want to produce
   BSD-specific passwd files?', BSDBuilderTask
   registration will be added to the data.xml file by loader.pl.

   The following option strings may be included by loader.pl:

    passwdFile

      The filename of the passwd file
      that BSD Builder Task will write out when user information
      in the Ganymede database is changed.

      loader.pl will register the option string
      passwdFile=<serverdir>/schema/output/bsd/passwd by default.

    groupFile

      The filename of the group file that BSD Builder Task will write
      out when user information in the Ganymede database is changed.

      loader.pl will register the option string
      groupFile=<serverdir>/schema/output/bsd/group by default.

    shadowFile

      The filename of the BSD shadow file to be generated by the
      BSD Builder Task when user information in the Ganymede database
      is changed.

      loader.pl will register the option string
      shadowFile=<serverdir>/schema/output/bsd/master.passwd by default.

    useMD5

      If the option string 'useMD5' is registered in the BSD Builder Task,
      the bsd passwd and master.passwd files will have md5-hashed
      passwords where possible.

    buildScript

      The filename of the executable script or program on disk to
      be run by the Ganymede server once BSD Builder Task has written
      out all of its data files.

      loader.pl will register the option string
      buildScript=<serverdir>/schema/output/bsdBuild by default.

  NT/Samba Builder Task

    NTPasswdFile

      The filename of the user data file to be written out for use by
      the NT/Samba update scripts.

      loader.pl will register the option string
      NTPasswdFile=<serverdir>/schema/output/ntsamba/passwd by default.

    NTGroupFile

      The filename of the group data file to be written out for use by
      the NT/Samba update scripts.

      loader.pl will register the option string
      NTGroupFile=<serverdir>/schema/output/ntsamba/group by default.

    SambaVersion1

      The filename of the Samba version 1 compatible smb.passwd
      file to be written out for use by the NT/Samba update script.

      This option should not be set if you want to support version 2.0
      or later of Samba, but there is nothing that will break
      if you do set both the SambaVersion1 and SambaVersion2 options.

    SambaVersion2

      The filename of the Samba version 2 compatible smb.passwd
      file to be written out for use by the NT/Samba update script.

      This option should not be set if you want to support versions
      prior to version 2.0 of Samba, but there is nothing that will
      break if you do set both the SambaVersion1 and SambaVersion2
      options.

    buildScript

      The filename of the script or program to be executed after 
      the NT/Samba Builder Task has finished writing out its
      datafiles.

      loader.pl will register the option string
      buildScript=<serverdir>/schema/output/ntsambaBuild by default.

All of these option strings may be changed in the server at any time,
but version 1.0 of the Ganymede GUI client makes this somewhat
difficult, as it doesn't allow you to edit strings that are already
entered.  The only way to edit strings already registered in a task's
"Option Strings" field is to remove the old version of the string and
then add its replacement.  This is yuck, and I hopefully will think of
a good way to change this, but for now, there's an easier way.

You can set the options for a particular builder task by
creating a text file like the following:

<ganymede>
  <ganydata>
    <object type="Task" id="UNIX Builder Task">
      <Option_Strings>
        <set>
          <string val="passwdFile=/home/jonabbey/ganymede/server/schema/output/passwd"/>
          <string val="groupFile=/home/jonabbey/ganymede/server/schema/output/group"/>
          <string val="buildScript=/home/jonabbey/ganymede/server/schema/output/unixBuild"/>
        </set>
      </Option_Strings>
    </object>
  </ganydata>
</ganymede>

Running xmlclient on the above file will edit the UNIX Builder Task
object and set three option strings in it.  All previous option
strings will be removed.

If you want to just add a new option string, you can do this:

<ganymede>
  <ganydata>
    <object type="Task" id="BSD Builder Task">
      <Option_Strings>
        <add>
          <string val="useMD5"/>
        </add>
      </Option_Strings>
    </object>
  </ganydata>
</ganymede>

See the doc/xml.html file in the server directory for more details on
the use of XML to make scripted changes to the Ganymede server's
database.

In most cases, you won't need to change these option strings at all
once you get things working, but you *will* need to change them if
you move the location of the server.

6. Server Operations - Schema Configuration Object
--------------------------------------------------

In addition to the builder task Option Strings, the userKit defines
a "Schema Configuration" object type that is held in the server
under the "Configuration" object type folder.

This object has the following fields, all of which have values set by
the loader.pl script when it generates the data.xml file.  These are
as follows:

  Default Home Dir

    This field will be set to whatever your answer was to question
    #13 in the loader.pl script, above.    

  Enable External Actions

    This checkbox must be selected in order to able the use of the
    New User Script, Delete User Script, and Rename User Script
    in the schema configuration object.

  New User Script

    This field is set to <serverdir>/schema/output/newUserScript by
    the loader.pl script.

    This filename is meant to be an executable script that will
    be run whenever a new user is created in Ganymede.

  Delete User Script

    This field is set to <serverdir>/schema/output/deleteUserScript by
    the loader.pl script.

    This filename is meant to be an executable script that will
    be run whenever a user is deleted in Ganymede.

  Rename User Script

    This field is set to <serverdir>/schema/output/renameUserScript by
    the loader.pl script.

    This filename is meant to be an executable script that will
    be run whenever a user is renamed in Ganymede.

  External Password Validator

    This field is not set by the loader.  You can set this to the
    location of an external password quality checking utility
    if you like.  See the 'npasswd' directory in the userKit
    for details on how to build and use the validator.

  External Password Saver

    This field is not set by the loader.  You can set this to the
    location of an external password history saving utility
    if you like.  See the 'npasswd' directory in the userKit
    for details on how to build and use the saver.

Note that having newUserScript defined will considerably slow down
large transactions that create many users, as the server will attempt
to execute the external newUserScript script once for each new user
created.  For this reason, loader.pl does not set the 'Enable External
Actions' checkbox.  Once you finish importing your initial data, you
should edit the 'User Kit Config Options' object in the 'Schema
Configuration' folder as supergash, and set the 'Enable External
Actions' checkbox to enable these external action scripts.

7. Server Operations - External Scripts
---------------------------------------

So, the various userKit builder tasks are designed to write out files,
and then to run a script to do the network update.  There are also the
scripts to handle new user creation, old user deletion, and user
rename.

These scripts are not written for you, at least not in Ganymede
1.0p1.  I include empty template scripts, but if you want to
actually have something happen when you make a change in the Ganymede
server, you'll have to decide what that behavior should be on your
system, and how to make it happen.

First, let's talk about the 3 scripts that are not specifically tied
to any given builder task in the userKit:

  New User Script

    The newUserScript is run late in the transaction commit time,
    but before the new version of the passwd file is written out.

    The newUserScript takes four parameters:

      directory username uid defaultgid

    I.e.,

      newUserScript /home/jonabbey jonabbey 502 101

    Hopefully this will be enough detail for you to do what
    user directory and mailbox creation you need to do before
    the passwd file is generated.

    If you need more context than that to be able to successfully
    do your new user generation, you'll want to put the logic into
    your unixBuild, bsdBuild, and/or ntsambaBuild scripts, see below.

  Delete User Script

    The deleteUserScript is run late in the transaction commit time,
    before the new version of the passwd file, with the user's
    deletion is reflected, is written out.

    The deleteUserScript takes only one parameter, the username.

    I.e.,

      deleteUserScript jonabbey

  Rename User Script

    The renameUserScript is run late in the transaction commit time,
    before the new version of the passwd file, with the user
    renamed, is written out.

    The renameUserScript takes two parameters, the old and new
    usernames.

    I.e.,

      renameUserScript oldname newname

These three scripts are completely optional, and only for convenience.
They are distributed in userKit with their functionality disabled,
both with the 'User Kit Config Options' 'Enable External Actions'
checkbox, and by the scripts themselves.  You will need to edit these
scripts once they are installed in order to enable whatever sort of
behavior is appropriate in your environment.  Having the Ganymede
server runs scripts to mess around with your environment is not
something to take too lightly, so we make you go to some effort
to enable them.

Both newUserScript and renameUserScript include default logic which
you may find appropriate to use in your environment.  To enable this
logic, you will have to edit these scripts and make sure the
$reallyRun variable is set to 1.  Both of these scripts are
distributed in a non-working fashion to make sure that you don't
accidentally trigger file-system activities while initially importing
data into the server.  deleteUserScript, as distributed, is just an
outline.  You will have to decide and implement whatever logic you
want to for user deletion.  At ARL:UT, we insist on handling user
deletion activities by hand to eliminate the possibility of accidental
data loss.  You may feel similarly.

Aside from those three schema-global scripts, there are the
transactional builder scripts. userKit includes three, named
'unixBuild', 'bsdBuild', and 'ntsambaBuild'.  These scripts are each
associated with a specific BuilderTask registered in the server.  When
the BuilderTasks fire, they will write out data files specific to
their purpose, and then run the corresponding external builder script.

These builder scripts don't take any command line parameters from the
server, and can do pretty much whatever they want to in order to
propagate the data files into the appropriate network environment.
The one requirement on them is that they must be synchronous.  It is
not allowed for these scripts to spawn anything off in the background
that would be disrupted if the build script was run again, or if the
data files being used were overwritten during the background process'
operation.

The Ganymede server is designed to wait for external builder scripts
to complete before the corresponding BuilderTask may be re-run.  The
Ganymede server will let users commit transactions while it waits for
an external builder script to complete, but it will not write out any
new data files for a given BuilderTask until the previous run is
complete.  Different BuilderTasks may complete at different rates.
The Ganymede server will take this into account, scheduling individual
BuilderTasks as needed to make sure that any changed data files are
written out to a given service as soon as possible, without
interfering in an external build that is already in progress.

unixBuild, bsdBuild, and ntsambaBuild are placed in the
<server>/schema/output directory by the installKit script when you
install userKit into your server.  These scripts are pre-configured to
find the data files they need in <server>/schema/output/unix,
<server>/schema/output/bsd, and <server>/schema/output/ntsamba,
respectively.  

The ntsambaBuild script runs a couple of scripts, one of which is used
to synchronize passwords to a remote NT PDC, called ntSync, and one
which is used to place a generated Samba password file in the right
location for your local Samba server, called sambaSync. See sections 8
and 9, below, for more details.

The unixBuild and bsdBuild scripts don't include any logic to actually
do much of anything, as there are so many different possibilities
for what to do in a UNIX environment.  So, here are some ideas for
what you might implement for these scripts:

 1. Copy passwd and group to /etc

      Super-simple.

 2. Build new NIS maps

      Also pretty straightforward.. just copy your passwd
      and group files to your NIS source directory and do
      the make.  Just make sure that nothing in your NIS
      Makefile runs in the background, to avoid doing overlapping
      NIS builds.

 3. Rdist or ssh/scp the files out

 4. Netinfo, on a MacOS X or NeXT system

 5. Take the passwd information and update an LDAP server

    Have the unixBuild script compare the newly created
    passwd file to the last version seen, calculate the
    differences with a bit of Perl code, and generate an
    LDIF file to submit to your local LDAP server.  When
    you're done with all your update, copy the new passwd
    file to passwd.old (or whatever name you like) so
    that the next run of your builder script will likewise
    be able to make this kind of comparison.

    Alternatively, you could just dump your LDAP server's
    complete user registry and regenerate its full state
    from the current passwd file.

    In either case, presto, instant update to your email directory!

 6. Handle user mailbox creation, deletion, rename.

    Have your unixBuild (or bsdBuild) compare the
    new passwd or group file with the old one and do whatever
    you'd like to do to take care of email boxes in your
    system, in lieu of using the newUserScript, renameUserScript,
    and deleteUserScript scripts.

If you make any scripts that you really like and think would be useful
to a wide audience, send mail about it to ganymede@arlut.utexas.edu!

8. Server Operations - Windows NT Password Synchronizaton
---------------------------------------------------------

Unlike the unixBuild and bsdBuild scripts, where we leave it up to you
to figure out what you want to do with the passwd and group files
emitted by Ganymede, we do provide some pre-written tools to support
user and group account synchronization from Ganymede to a Windows NT
4.0 Primary Domain Controller.  These tools are the ntSync script
which takes a complex .INI-style file describing the user and group
information that we know about in detail adequate for synchronization
with NT (i.e., user accounts that we have plaintext password
information for) and massages it with previously emitted data and the
ganymederemote.pl script, which is to be installed on your NT PDC and
which ntSync will call over rsh or ssh.  ntSync comes deactivated, you
will need to install the ganymederemote.pl script on your NT PDC,
along with ActiveState Perl and some sort of rsh or ssh service, and
then look at and edit ntSync in order to enable PDC synchronization.

However, before you do this, you should understand that supporting
synchronization of passwords to a Windows NT Primary Domain Controller
in the way we currently do is a security risk.  The reason for that is
that the Win32 Perl module we use for doing systems administration
activities on the Windows NT PDC is unable to set a user's password
with any sort of pre-hashed password encoding.  The only way that I
know of to set a password on a Windows NT 4.0 system is by getting the
password over to the NT machine in plain-text form.

In order to do this, the Ganymede server has to retain and write out
plain-text passwords for transmission to the NT side.  In order to
slightly reduce the danger posed by a script-kiddie getting access to
your Ganymede server files, the Ganymede server is configured by
userKit's loader.pl script to not retain plain-text passwords in its
on-disk database, relying instead on crypt() and md5Crypt() hashing of
saved passwords to support authentication.  Plain-text passwords will
be retained only in the Ganymede server's memory, and are inaccessible
to anything other than a loaded BuilderTask.  The NT/Samba Builder
Task will write out complete user and group files, but will only
include password information for users whose passwords have been
changed through Ganymede since the Ganymede server was restarted.

The implication of this is that Ganymede is depending on your NT PDC
to retain its own passwords once they are set, because the Ganymede
will forget them if it is stopped and restarted.  All that Ganymede
guarantees, in this setup, is that it will remember passwords entered
into Ganymede long enough to be able to write them out for the
ntsambaBuild script to be able to send a description of the changes to
your Windows NT PDC server.

And even that's not strictly true, because the Ganymede server could
conceivably be shut down or turned off between the time a user changes
their password and the time that the NT/Samba Builder Task gets run.

The Ganymede server would be able to recover its own data in that case
from the journal file without difficulty on startup, including crypt()
and md5Crypt() hashed versions of the passwords, but the plain-text
password for that user would be lost, and would have to be re-entered
so that it could be sent to the Windows NT system successfully.

It's a security trade-off.  If you want to make it so that the
Ganymede server will retain the plain-text of all passwords in its
on-disk database, you can edit the schema.xml and/or data.xml files
before running xmlclient to import data into Ganymede.

What you need to do is find the section of schema.xml (or data.xml)
that looks like this:

        <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="16"/>
              <badchars val=" :"/>
              <namespace val="username"/>
            </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">
              <maxlength val="32"/>
              <crypted/>
              <md5crypted/>
              <winHashed/>
            </typedef>
          </fielddef>

and change the Password field definition to this:

          <fielddef name="Password" id="101">
            <comment>Password for an individual privileged to log into Ganymede and/or the network</comment>
            <typedef type="password">
              <maxlength val="32"/>
              <crypted/>
              <md5crypted/>
              <winHashed/>
	      <plaintext/>
            </typedef>
          </fielddef>

Adding the <plaintext/> element before you run the xmlclient to import
the database definition schema will cause the Ganymede server to
retain the plaintext of passwords that are fed to it indefinitely.

You can also change this once the server has been loaded through
the use of the schema editor in the Ganymede admin console.

Note that since Ganymede depends on access to passwords in plain text
form in order to synchronize them to Windows NT, you will have to have
your users set their passwords in Ganymede once their accounts have
been imported from your UNIX passwd file.  The crypt() or md5Crypt()
passwords in your UNIX passwd file will not be adequate to support
synchronization to Windows NT.

If you already have a database of passwords in plaintext, you can
import them into Ganymede through the xmlclient.  See
<server>/doc/xml.html for details.

For details on setting up the Windows NT side of this builder task,
see the README file in the NTscripts directory.

An alternative to synchronizing passwords to a Windows NT domain
controller is to use a recent version of Samba and make your Samba
server your primary domain controller.  As of Samba 2.2, Samba can act
as a completely competent PDC for NT and Windows 2000 networks, except
that it does not support synchronization with BDC's.  If you can
live without a backup domain controller, you can perhaps get away
without having to pass plaintext passwords around for synchronization.

9. Samba Password Synchronization
---------------------------------

Assuming that you answered yes to the question about supporting the
generation of an encrypted Samba password file, the NTSambaBuilderTask
will be registered in the Ganymede server when the userKit is
initialized.  Whenever the NTSambaBuilderTask is run by the Ganymede
server, an smb.password file, conforming to either version 1 or
version 2 of the Samba password file format, will be written out to
<serverdir>/schema/output/ntsamba/smb.passwd.

The sambaSync script will be run by the ntsambaBuild script that is
executed immediately after any Samba password file (and NT
synchronization files, if you requested support for Windows NT domain
synchronization support) are written to disk.

As with the NT Primary Domain Controller synchronization support,
Ganymede is not able to convert UNIX-style crypt() or md5Crypt()
hashed passwords to a form that Samba is able to use.  Ganymede 1.0
does support the storage of passwords on the Ganymede server in the
two cryptographic hash formats that are used in the Samba encrypted
password file, and can do this without having to retain any plaintext
passwords, but it can only generate these hashes if it gets at least
one chance to see the passwords in their plaintext form.  That is, if
your users change their passwords in Ganymede, or if they even just
log into Ganymede, Ganymede will catch the plaintext and use it to
generate and store the Samba-compatible hash formats for future use.

In other words, if you want to use the Samba support in userKit,
you will need to have all of your users change their passwords
using Ganymede, once you have the accounts imported from your
/etc/passwd-type files.  If you happen to have access to the
plaintext of your users current passwords, or if you have access
to the Samba encrypted hashes for their current passwords, you could
use the xmlclient to pre-load that information to Ganymede.  Otherwise,
I would suggest requiring all of your users to change their passwords
in Ganymede before you attempt to use the Samba password file that
the userKit can generate.

To help encourage you to do the right thing, the sambaSync script that
we provide does not come preconfigured to copy the generated
smb.password file into place.  You will have to hand-edit this script
(located at <serverdir>/schema/output/sambaSync) to set the location
where the generated smb.password file needs to be copied for your
Samba server's installation.

Again, be sure not to do this until you have given all of your users
a chance to set their passwords in Ganymede, or else you will wind
up with an incomplete Samba password file to start.

10. Schema Editing
------------------

This is for advanced users.

There's already some documentation on this in the <server>/doc
directory, but I'll discuss it here briefly.

Basically, it's pretty easy to edit the server database definition
schema to define new kinds of objects and new fields in existing
objects.  Just run the admin console with a supergash-level account
and choose 'Edit Schema' under the Control menu.

You can create new objects by right-clicking on category folders,
and you can create new fields by right-clicking on object nodes.

You can change the ordering of objects in the tree and fields
in an object by dragging them up and down in the tree.

You may find that adding new fields, or changing the names of the ones
that are already there will allow you to customize the user
and group objects to your taste without too much pain.

Adding new fields probably won't do you much good, though, unless and
until you know how to work with the Java plug-in classes in the
<server>/schema/src directory to incorporate those fields into a
Ganymede builder task's output.

11. Java plug-in code - Builder Tasks and DBEditObject subclasses
-----------------------------------------------------------------

Also for advanced users.

The src directory in the userKit contains the source code
for the Java classes that userKit provides for incorporation
into the Ganymede server.  The build script recompiles everything,
and the buildJar script regenerates the custom.jar file in
the <server>/schema directory.

There are two major kinds of classes that you will find in src.  They
are DBEditObject subclasses and friends (like the wizard classes and
the object schema interfaces), which are responsible for injecting
intelligence into the server during editing and other object
operations.  The userCustom class, for instance, is responsible for
generating the choice list for the 'Login Shell' field, as well as
automatically updating the 'Home Directory' field when the user's name
is changed, and so on.  userCustom also calls out to the
newUserScript, deleteUserScript, and renameUserScript as needed.

Editing such classes will let you customize the interaction that
your users will have when they are editing objects in the server.

These classes are registered in the server through the use of
the admin console's schema editor.

The other major category of classes in the src directory are the
builder tasks.  These contain the code that scan the database
and write out the data files discussed above.  They are also
responsible for running the external scripts to propagate
the build files into your environment.

If you look at the BuilderTasks, you should find that it will be
fairly easy to adopt them to slightly alter the files they generate.
If you add new types of data objects to the server using the schema
editor, you'll probably need to edit a BuilderTask to make it write
out a new data file to match.

If you do any sort of changes to any Java source files here,
you'll need to run 'build' to compile them, then shut down the
server, then run 'buildJar' to generate a new custom.jar file,
then start the server back up again.

Documentation for the DBEditObject, GanymedeWizard, and
GanymedeBuilderTask classes can be found in the server's
doc directory.

