chiark / gitweb /
@@ -1,3 +1,9 @@
[userv.git] / spec.sgml
index 0307c864042fddf3d031b34cd8ffac51cde19211..511400ac4661fe6fca1d6052a3d991c556c7322c 100644 (file)
--- a/spec.sgml
+++ b/spec.sgml
@@ -1,8 +1,9 @@
 <!doctype debiandoc system>
+
 <book>
 <title>User service daemon and client specification
-<author>Ian Jackson <email>ian@chiark.greenend.org.uk
-<version>draft 0.17
+<author>Ian Jackson <email>ian@davenant.greenend.org.uk
+<version>1.0.1</version>
 
 <abstract>
 This is a specification for a Unix system facility to allow one
@@ -10,7 +11,7 @@ program to invoke another when only limited trust exists
 between them.
 
 <copyright>
-Copyright 1996-1997 Ian Jackson.
+<prgn/userv/ is Copyright 1996-2000 Ian Jackson.
 <p>
 
 <prgn/userv/ is free software; you can redistribute it and/or modify
@@ -38,10 +39,11 @@ There is a daemon which invokes user service programs (henceforth
 program (henceforth the `client') and according to rules set forth in
 system-wide and user-specific configuration files.  The companion
 client program is setuid root, and negotiates with the daemon through
-an <tt/AF_UNIX/ socket and associated objects in a system-wide private
-directory set aside for the purpose.  The user who wishes the service
-to be performed and calls the client is called the `calling user'; the
-process which calls the client is called the `calling process'.
+an <prgn/AF_UNIX/ socket and associated objects in a system-wide
+private directory set aside for the purpose.  The user who wishes the
+service to be performed and calls the client is called the `calling
+user'; the process which calls the client is called the `calling
+process'.
 
 <p>
 The daemon and the client are responsible for ensuring that
@@ -63,7 +65,7 @@ The user may be a login name or a numeric uid, or <tt/-/ to indicate
 that the service user is to be the same as the calling user.
 <p>
 
-The service name is interpreted by the userv<footnote><tt/userv/ is
+The service name is interpreted by the userv<footnote><prgn/userv/ is
 short for `user services', and is pronounced `you-serve'.</footnote>
 daemon on behalf of the service user.  It will often be the name of a
 program.
@@ -80,15 +82,26 @@ the next.
 <tag/<tt/--builtin//
 <item>
 Requests that a builtin service be provided.  This is equivalent to
-using the <tt/--override/ option to specify a string consisting of
-<tt/--execute-builtin/ followed by the <var/builtin-service/
+using the <prgn/--override/ option to specify a string consisting of
+<prgn/execute-builtin/ followed by the <var/builtin-service/
 requested, and requesting a service user of <tt/-/ (indicating the
-calling user).  Note that the <var/info argument/s supplied will be
-ignored by most services; if the builtin service being requested
-requires a <var/service-argument/ then this must be supplied to the
-client in the same argument as the <var/builtin-service/.  See <ref
-id="execdirectives"> for details of the builtin services available,
-and <ref id="optoverride"> for details of the <tt/--override/ options.
+calling user).
+<p>
+
+If the builtin service being requested requires a
+<var/service-argument/ then this must be supplied to the client in the
+same argument as the <var/builtin-service/.  See <ref
+id="dirs-execution"> for details of the builtin services available,
+and <ref id="optoverride"> for details of the <prgn/--override/
+options.
+<p>
+
+The actual service name passed will be the <var/builtin-service/; note
+that this actual service name (as opposed to the override data) and
+the <var/info-argument/s supplied will be ignored by most builtin
+services; the override mechanism and <prgn/execute-builtin/ will be
+used to ensure that the right builtin service is called with the right
+<var/service-argument/s.
 
 <tag/<tt/-f<var/fd/[<var/modifiers/]=<var/filename///
 <tag/<tt/--file <var/fd/[<var/modifiers/]=<var/filename///
@@ -151,7 +164,8 @@ May not be used with <tt/exclusive/.
 
 <tag/<tt/append//
 <item>
-<tt/O_APPEND/: All writes will append to the file.  Implies <tt/write/.
+<tt/O_APPEND/: All writes will append to the file.  Implies <tt/write/
+(but not <tt/create/).
 
 <tag/<tt/sync//
 <item>
@@ -177,11 +191,10 @@ other words are allowed.  The <var/filename/ may also be <tt/stdin/,
 <p>
 
 If no <var/modifiers/ which imply <tt/read/ or <tt/write/ are used it
-is as if <tt/read/ had been specified, except that if the
-filedescriptor 1 or 2 of the service is being opened (either specified
-numerically or with <tt/stdout/ or <tt/stderr/) it is as if
-<tt/overwrite/ had been specified (or <tt/write/ if only <tt/fd/ was
-specified).
+is as if <tt/write/ had been specified, except that if the
+filedescriptor 0 of the service is being opened (either specified
+numerically or with <tt/stdin/) it is as if <tt/overwrite/ had been
+specified (or <tt/write/ if only <tt/fd/ was specified).
 <p>
 
 The client will also use <tt/O_NOCTTY/ when opening files specified by
@@ -232,9 +245,9 @@ Sets the action on termination of the service for the specified file
 descriptor; <var/action/ must be <tt/wait/, <tt/nowait/ or <tt/close/
 as described above.  The file descriptor must be specified as open
 when this option is encountered; this option is overridden by any
-later <tt/--file/ or <tt/--fdwait/ option - even by a <tt/--file/
-which does not specify an action on termination (in this case the
-default will be used, as described above).
+later <prgn/--file/ or <prgn/--fdwait/ option - even by a
+<prgn/--file/ which does not specify an action on termination (in this
+case the default will be used, as described above).
 
 <tag/<tt/-D<var/name/=<var/value///
 <tag/<tt/--defvar <var/name/=<var/value///
@@ -259,10 +272,10 @@ timeout will be implemented (this is the default).
 <tag/<tt/--signals/ <var/method//
 <item>
 Affects the handling of the exit status when the service terminates
-due to a signal.  (The client will always finish by calling <tt/exit/,
-so that only numbers from 0 to 255 can be returned and not the full
-range of numbers and signal indications which can be returned by the
-<tt/wait/ family of system calls.)
+due to a signal.  (The client will always finish by calling
+<prgn/_exit/, so that only numbers from 0 to 255 can be returned and
+not the full range of numbers and signal indications which can be
+returned by the <prgn/wait/ family of system calls.)
 <p>
 
 The <var/method/ may be one of the following:
@@ -358,7 +371,10 @@ contain one or more real newlines.
 Pretend to the service that it is being called by <var/user/ (which
 may be a username or a uid).  This will also affect the group and
 supplementary groups supplied to the service; they will be the
-standard group and supplementary groups for <var/user/.
+standard group and supplementary groups for <var/user/.  The
+<tt/--spoof-user/ option will <em/not/ affect which user is chosen if
+the service user is specified as just <tt/-/; in this case the service
+user will be the real calling user.
 
 </taglist>
 
@@ -428,7 +444,7 @@ next write causing a <prgn/SIGPIPE/.
 
 Read errors on file descriptors (and disconnection) will only be
 visible to the service and distinguishable from normal end of file if
-<tt/disconnect-hup/ is in effect.
+<prgn/disconnect-hup/ is in effect.
 <p>
 
 Read and write errors (other than broken pipes, as described above)
@@ -444,7 +460,7 @@ relevant file descriptor in the client's arguments.  By default
 writing filedescriptors remain open and the client will wait for them
 to be closed at the service end, and reading file descriptors are
 closed immediately.  These leftover child processes will not get a any
-<tt/SIGHUP/ even if a read or write error occurs or the client
+<prgn/SIGHUP/ even if a read or write error occurs or the client
 disconnects before then.
 
 <sect>Environment
@@ -476,14 +492,14 @@ decimal, separated by spaces.
 <tag/<tt/USERV_GROUP//
 <item>
 The group names of the calling process, listed in the same way as the
-ids are in <tt/USERV_GID/.  If no name can be found for any of the
+ids are in <prgn/USERV_GID/.  If no name can be found for any of the
 calling process's group(s) then the service will not be invoked.
 
 <tag/<tt/USERV_CWD//
 <item>
 The client's current working directory name (this directory may not be
 accessible to the service).  If it could not be determined or the
-<tt/--hidecwd/ flag was used then this variable will be set to an
+<prgn/--hidecwd/ flag was used then this variable will be set to an
 empty string (this is not considered an error).
 
 <tag/<tt/USERV_SERVICE//
@@ -558,10 +574,10 @@ current directory (usually the service user's home directory).
 Pathnames starting with the two characters <tt>~/</> are taken to be
 relative to the service user's home directory.
 
-<sect>Configuration file directives
+<sect id="directives">Configuration file directives
 <p>
 
-<sect1>Immediate directives
+<sect1 id="dirs-immediate">Immediate directives
 <p>
 
 The following directives take effect immediately:
@@ -582,35 +598,35 @@ error).
 <tag/<tt/eof//
 <item>
 Stop reading the configuration file in question, as if end of file had
-been reached.  Any control constructs (<tt/if/, <tt/catch-quit/ or
-<tt/errors-push/) which were started in that file will be considered
+been reached.  Any control constructs (<prgn/if/, <prgn/catch-quit/ or
+<prgn/errors-push/) which were started in that file will be considered
 finished.  Parsing will continue in the file which caused the file
-containing the <tt/eof/ to be read.
+containing the <prgn/eof/ to be read.
 
 <tag/<tt/quit//
 <item>
 Stop reading configuration files and act immediately on the current
-settings.  The behaviour of <tt/quit/ is subject to the
-<tt/catch-quit/ control construct.
+settings.  The behaviour of <prgn/quit/ is subject to the
+<prgn/catch-quit/ control construct.
 
 <tag/<tt/include <var/filename///
 <tag/<tt/include-ifexist <var/filename///
 <item>
 Read the configuration file <var/filename/, and then return to this
 file and continue parsing it with the next directive.  It is an error
-if the file cannot be opened and read, unless <tt/include-ifexist/ is
-used and the file does not exist, in which case the directive is
+if the file cannot be opened and read, unless <prgn/include-ifexist/
+is used and the file does not exist, in which case the directive is
 silently ignored.
 
 <tag/<tt/include-lookup <var/parameter/ <var/directory///
 <tag/<tt/include-lookup-all <var/parameter/ <var/directory///
 <item>
 Read the configuration file in <var/directory/ whose name is the value
-of <var/parameter/ (see the description of <tt/if/, above).  If
-<var/parameter/ has several values they will be tried in order; with
-<tt/include-lookup/ this search will stop when one is found, but with
-<tt/include-lookup-all/ the search will continue and any files
-appropriate to other values will be read too.
+of <var/parameter/ (see the description of <prgn/if/, <ref
+id="dirs-control">).  If <var/parameter/ has several values they will
+be tried in order; with <prgn/include-lookup/ this search will stop
+when one is found, but with <prgn/include-lookup-all/ the search will
+continue and any files appropriate to other values will be read too.
 <p>
 
 If none of the parameter's values had a corresponding file then the
@@ -662,7 +678,7 @@ delivered as if it were an error message, but does not actually cause
 an error.
 </taglist>
 
-<sect1>Directives with delayed effect
+<sect1 id="dirs-delayed">Directives with delayed effect
 <p>
 
 The following directives have no immediate effect, but are remembered
@@ -674,9 +690,9 @@ and have an effect on later processing of the configuration files.
 Specifies that the file <var/filename/ should be read instead of the
 user's <tt>~/.userv/rc</>.  This does <em/not/ happen immediately;
 instead, the setting is remembered and used after the
-<tt/system.default/ configuration file has been read.  This directive
-has no effect in a user's configuration file or in the
-<tt/system.override/ file, as the user's configuration file has
+<prgn/system.default/ configuration file has been read.  This
+directive has no effect in a user's configuration file or in the
+<prgn/system.override/ file, as the user's configuration file has
 already been found and read by then and will not be re-read.
 
 <tag/<tt/errors-to-stderr//
@@ -691,10 +707,10 @@ in the context of and with the privileges of the service user.
 <tag/<tt/errors-to-syslog/ [<var/facility/ [<var/level/]]/
 <item>
 Error messages will be delivered using <prgn/syslog/.  The default
-<var/facility/ is <tt/daemon/; the default <var/level/ is <tt/error/.
+<var/facility/ is <tt/user/; the default <var/level/ is <tt/error/.
 </taglist>
 
-<sect1>Control structure directives
+<sect1 id="dirs-control">Control structure directives
 <p>
 
 The following directives are used to create control structures.  If
@@ -708,11 +724,12 @@ considered finished.  This is not an error.
 <tag/<tt/else//
 <tag/<tt/fi//
 <item>
-Lines following <tt/if/ are interpreted only if the condition is true.
-Many conditions are properties of parameter values.  Most parameters
-have a single string as a value; however, some may yield zero or
-several strings, in which case the condition is true if it is true of
-any of the strings individually.  Parameters are described below.
+Lines following <prgn/if/ are interpreted only if the condition is
+true.  Many conditions are properties of parameter values.  Most
+parameters have a single string as a value; however, some may yield
+zero or several strings, in which case the condition is true if it is
+true of any of the strings individually.  Parameters are described
+below.
 <p>
 
 The conditions are:
@@ -767,7 +784,8 @@ The service name specified when the client was called.
 <tag/<tt/calling-user//
 <item>
 Two strings: the login name of the calling user (determined as for
-<tt/USERV_USER/, above) and the calling uid (represented in decimal).
+<prgn/USERV_USER/, above) and the calling uid (represented in
+decimal).
 
 <tag/<tt/calling-group//
 <item>
@@ -779,7 +797,7 @@ the primary group then it is elided.
 <tag/<tt/calling-user-shell//
 <item>
 The calling user's shell, as listed in the password entry for the
-calling login name (as determined for <tt/USERV_USER/, above).
+calling login name (as determined for <prgn/USERV_USER/, above).
 
 <tag/<tt/service-user//
 <item>
@@ -798,9 +816,9 @@ The service user's shell, as listed in their password entry.
 <tag/<tt/u-<var/name///
 <item>
 The value of the user-defined variable <var/name/ passed by the caller
-using the <tt/-D/ command-line option to the client.  If the variable
-was not defined then this parameter is an empty list of strings; in
-this case any condition which tests it will be false, and
+using the <prgn/--defvar/ command-line option to the client.  If the
+variable was not defined then this parameter is an empty list of
+strings; in this case any condition which tests it will be false, and
 <tt/include-lookup/ on it will read the <tt/:none/ file, or
 <tt/:default/ if <tt/:none/ is not found.
 
@@ -810,30 +828,30 @@ this case any condition which tests it will be false, and
 <tag/<tt/srorre//
 <item>
 Stacks the error handling behaviour currently in effect.  Any changes
-to error handling will take effect only between <tt/errors-push/ and
-<tt/srorre/.
+to error handling will take effect only between <prgn/errors-push/ and
+<prgn/srorre/.
 
 <tag/<tt/catch-quit//
 <tag/<tt/hctac//
 <item>
-Any use of <tt/quit/ inside <tt/catch-quit/ will merely cause the
-parsing to continue at <tt/hctac/ instead.  Any control constructs
-started since the <tt/catch-quit/ will be considered finished if a
-<tt/quit/ is found.
+Any use of <prgn/quit/ inside <prgn/catch-quit/ will merely cause the
+parsing to continue at <prgn/hctac/ instead.  Any control constructs
+started since the <prgn/catch-quit/ will be considered finished if a
+<prgn/quit/ is found.
 <p>
 
-If an error occurs inside <tt/catch-quit/ the execution settings will
-be reset (as if by the <tt/reset/ directive) and parsing will likewise
-continue at <tt/hctac/.
+If an error occurs inside <prgn/catch-quit/ the execution settings
+will be reset (as if by the <prgn/reset/ directive) and parsing will
+likewise continue at <prgn/hctac/.
 <p>
 
 If a lexical or syntax error is detected in the same configuration
-file as the <tt/catch-quit/, while looking for the <tt/hctac/, that
-error will not be caught.
+file as the <prgn/catch-quit/, while looking for the <prgn/hctac/
+after an error or <prgn/quit/, that new error will not be caught.
 
 </taglist>
 
-<sect1 id="execdirectives">Directives for changing execution settings
+<sect1 id="dirs-execution">Directives for changing execution settings
 <p>
 
 The following directives modify the execution settings; the server
@@ -844,15 +862,17 @@ directive which modifies any particuar setting will take effect.
 <taglist>
 <tag/<tt/reject//
 <item>
-Reject the request.  <tt/execute/, <tt/execute-from-directory/ and
-<tt/execute-from-path/ will change this setting.
+Reject the request.  <prgn/execute/, <prgn/execute-from-directory/ and
+<prgn/execute-from-path/ will change this setting.
 
-<tag/<tt/execute <var/pathname/ [<var/argument/ ...]//
+<tag/<tt/execute <var/program/ [<var/argument/ ...]//
 <item>
-Execute the program <var/pathname/, with the arguments as specified,
-followed by any arguments given to the client if <tt/no-suppress-args/
-is in effect.  It is an error for the execution to fail when it is
-attempted (after all the configuration has been parsed).
+Execute the program <var/program/, with the arguments as specified,
+followed by any arguments given to the client if
+<prgn/no-suppress-args/ is in effect.  It is an error for the
+execution to fail when it is attempted (after all the configuration
+has been parsed).  If <var/program/ does not contain a slash it will
+be searched for on the service user's path.
 
 <tag/<tt/execute-from-directory <var/pathname/ [<var/argument/ ...]//
 <item>
@@ -879,7 +899,7 @@ all the configuration has been parsed).
 <var/service/ is interpreted as a program on the default <prgn/PATH/
 (or as a pathname of an executable, if it contains a <tt>/</>).  This
 directive is <em/very dangerous/, and is only provided to make the
-<tt/--override/ options effective.  It should not normally be used.
+<prgn/--override/ options effective.  It should not normally be used.
 It is an error for the execution to fail when it is attempted (after
 all the configuration has been parsed).
 
@@ -894,35 +914,46 @@ builtin services are:
 
 <taglist compact>
 <tag/<tt/execute//
+<item>
 Displays the execution settings, defined variables,
 arguments, etc. with which the builtin service was invoked.
 
 <tag/<tt/environment//
+<item>
 Displays the environment variable settings with which the builtin
 service was invoked.
 
 <tag/<tt/parameter <var/parameter///
+<item>
 Displays the values of the service configuration language parameter
 specified.
 
 <tag/<tt/version//
+<item>
 Displays the version string and compilation details of the uservd
 server program.
 
 <tag/<tt/reset//
-Displays the default reset configuration (evaluated when <tt/reset/ is
-found in a configuration file, or when an error is caught by
-<tt/catch-quit/).
+<item>
+Displays the default reset configuration (evaluated when <prgn/reset/
+is found in a configuration file, or when an error is caught by
+<prgn/catch-quit/).
 
 <tag/<tt/toplevel//
+<item>
 Displays the top-level default configuration (the configuration data,
 evaluated by the server, which calls all the other configuration
 files).
 
 <tag/<tt/override//
+<item>
 Displays the top-level override configuration (the configuration data,
 evaluated by the server, which causes all the other configuration data
 to be parsed).
+
+<tag/<tt/help//
+<item>
+Displays a list of the understood builtin service names and arguments.
 </taglist>
 
 In the future other builtin services may be defined which do more than
@@ -942,15 +973,16 @@ as
 <example>
 /bin/sh -c '. /etc/environment; exec "$@"' - .../program arg arg arg ...
 </example>
-<tt/no-set-environment/ cancels the effect of <tt/set-environment/.
+<prgn/no-set-environment/ cancels the effect of
+<prgn/set-environment/.
 
 <tag/<tt/no-suppress-args//
 <tag/<tt/suppress-args//
 <item>
 Include any arguments given to the client as arguments to the program
-invoked as a result of an <tt/execute/ or <tt/execute-from-directory/
-directive.  <tt/suppress-args/ undoes the effect of
-<tt/no-suppress-args/.
+invoked as a result of an <prgn/execute/,
+<prgn/execute-from-directory/ or <prgn/execute-from-path/ directive.
+<prgn/suppress-args/ undoes the effect of <prgn/no-suppress-args/.
 
 <tag/<tt/require-fd <var/fd-range/ read|write//
 <item>
@@ -958,24 +990,24 @@ Insist that the filedescriptor(s) be opened for reading resp. writing.
 It is an error if any descriptor marked as required when the service
 is about to be invoked (after the configuration has been parsed) was
 not specified when the client was invoked.  Each file descriptor has a
-separate setting, and the last one of <tt/require-fd/, <tt/allow-fd/,
-<tt/ignore-fd/, <tt/null-fd/ or <tt/reject-fd/ which affected a
-particular file descriptor will take effect.
+separate setting, and the last one of <prgn/require-fd/,
+<prgn/allow-fd/, <prgn/ignore-fd/, <prgn/null-fd/ or <prgn/reject-fd/
+which affected a particular file descriptor will take effect.
 <p>
 
 <var/fd-range/ may be a single number, two numbers separated by a
 hyphen, or one number followed by a hyphen (indicating all descriptors
 from that number onwards).  It may also be one of the words
 <tt/stdin/, <tt/stdout/ or <tt/stderr/.  Open-ended file descriptor
-rangers are allowed only with <tt/reject-fd/ and <tt/ignore-fd/, as
-otherwise the service program would find itself with a very large
+rangers are allowed only with <prgn/reject-fd/ and <prgn/ignore-fd/,
+as otherwise the service program would find itself with a very large
 number of file descriptors open.
 <p>
 
 When the configuration has been parsed, and before the service is
 about to be executed, stderr (fd 2) must be required or allowed
-(<tt/require-fd/ or <tt/allow-fd/) for writing; this is so that the
-error message printed by the server's child process if it cannot
+(<prgn/require-fd/ or <prgn/allow-fd/) for writing; this is so that
+the error message printed by the server's child process if it cannot
 <prgn/exec/ the service program is not lost.
 
 <tag/<tt/allow-fd <var/fd-range/ [read|write]//
@@ -1012,7 +1044,7 @@ closed just before the service is invoked.
 <item>
 Causes the service's process group to get a <prgn/SIGHUP/ if the
 client disconnects before the main service process terminates.
-<tt/no-disconnect-hup/ cancels <tt/disconnect-hup/.
+<prgn/no-disconnect-hup/ cancels <prgn/disconnect-hup/.
 <p>
 
 If one of the reading descriptors specified when the client is called
@@ -1037,28 +1069,28 @@ disconnect-hup
 
 </taglist>
 
-If no <tt/execute/, <tt/execute-from-path/ or
-<tt/execute-from-directory/ is interpreted before all the files are
-read then the request is rejected.
+If no <prgn/execute/, <prgn/execute-from-path/,
+<prgn/execute-from-directory/ or <prgn/builtin/ is interpreted before
+all the files are read then the request is rejected.
 
 
-<sect>Errors in the configuration file
+<sect id="configerrors">Errors in the configuration file
 <p>
 
 If a syntax error or other problem occurs when processing a
 configuration file then a diagnostic will be issued, to wherever the
-error messages are currently being sent (see the <tt/errors-/ family
+error messages are currently being sent (see the <prgn/errors-/ family
 of directives, above).
 <p>
 
 The error will cause processing of the configuration files to cease at
-that point, unless the error was inside a <tt/catch-quit/ construct.
+that point, unless the error was inside a <prgn/catch-quit/ construct.
 In this case the settings controlling the program's execution will be
-reset to the defaults as if a <tt/reset/ directive had been issued,
-and parsing continues after <tt/hctac/.
+reset to the defaults as if a <prgn/reset/ directive had been issued,
+and parsing continues after <prgn/hctac/.
 
 
-<sect>Defaults
+<sect id="defaults">Defaults
 <p>
 
 The default configuration processing is as if the daemon were parsing
@@ -1081,8 +1113,9 @@ quit
 </example>
 <p>
 
-If one of the <tt/override/ options to the client is used then it will
-be as if the daemon were parsing an overall configuration as follows:
+If one of the <prgn/--override/ options to the client is used then it
+will instead be as if the daemon were parsing an overall configuration
+as follows:
 
 <example>
 reset
@@ -1102,11 +1135,11 @@ between the caller and the service.
 <item>
 The service name supplied by the caller is available in the
 configuration language for deciding whether and which service program
-to invoke, in the <tt/service/ parameter, and is used by the
-<tt/execute-from-directory/ and <tt/execute-from-path/ configuration
-directives.  It is usually used to select which service program to
-invoke.  It is also passed to the service program in the
-<tt/USERV_SERVICE/ environment variable.
+to invoke, in the <prgn/service/ parameter, and is used by the
+<prgn/execute-from-directory/ and <prgn/execute-from-path/
+configuration directives.  It is usually used to select which service
+program to invoke.  It is also passed to the service program in the
+<prgn/USERV_SERVICE/ environment variable.
 
 <item>
 File descriptors specified by the client and allowed according to the
@@ -1138,33 +1171,33 @@ caller to be closed, so that if these are pipes processes which write
 to them will receive <prgn/SIGPIPE/ or <prgn/EPIPE/.
 
 <item>
-If <tt/no-suppress-args/ is set then arguments passed to the client by
-its caller will be passed on, verbatim, to the service.
+If <prgn/no-suppress-args/ is set then arguments passed to the client
+by its caller will be passed on, verbatim, to the service.
 
 <item>
 Fatal signals and system call failures experienced by the client will
 result in the disconnection of the service from the client and
 possibly some of the communication file descriptors described above;
-if <tt/disconnect-hup/ is set they will also cause the service to get
-<prgn/SIGHUP/.
+if <prgn/disconnect-hup/ is set then the service will also be sent a
+<prgn/SIGHUP/.
 
 <item>
-The value of the <tt/LOGNAME/ (or <tt/USER/) environment variable as
-passed to the client will be used as the login name of the calling
+The value of the <prgn/LOGNAME/ (or <prgn/USER/) environment variable
+as passed to the client will be used as the login name of the calling
 user if the uid of the calling process matches the uid corresponding
 to that login name.  Otherwise the calling uid's password entry will
 be used to determine the calling user's login name.
 <p>
 
 This login name and the calling uid are available in the configuration
-language in the <tt/calling-user/ parameter and are passed to the
-service program in environment variables <tt/USERV_USER/ and
-<tt/USERV_UID/.
+language in the <prgn/calling-user/ parameter and are passed to the
+service program in environment variables <prgn/USERV_USER/ and
+<prgn/USERV_UID/.
 <p>
 
 The shell corresponding to that login name (according to the password
 entry) is available as in the configuration language's
-<tt/calling-user-shell/ parameter.
+<prgn/calling-user-shell/ parameter.
 <p>
 
 If no relevant password entry can be found then no service will be
@@ -1173,7 +1206,7 @@ invoked.
 <item>
 The numeric values and textual names for calling gid and supplementary
 group list are available in the configuration language in the
-<tt/calling-group/ parameter and are passed to the service in
+<prgn/calling-group/ parameter and are passed to the service in
 environment variables.
 <p>
 
@@ -1182,16 +1215,16 @@ process belongs then no service will be invoked.
 
 <item>
 The name of the current working directory in which the client was
-invoked is passed, if available and not hidden using <tt/--hidecwd/,
-to the service program in the <tt/USERV_CWD/ variable.  This grants no
+invoked is passed, if available and not hidden using <prgn/--hidecwd/,
+to the service program in the <prgn/USERV_CWD/ variable.  This grants no
 special access to that directory unless it is a subdirectory of a
 directory which is executable (searchable) but not readable by the
 service user.
 
 <item>
-Settings specified by the caller using the
-<tt/-D<var/name/=<var/value// option to the client are available in
-the configuration language as the corresponding <tt/u-<var/name//
+Settings specified by the caller using the <tt/--defvar
+<var/name/=<var/value// option to the client are available in the
+configuration language as the corresponding <tt/u-<var/name//
 parameters and are passed to the service program in environment
 variables <tt/USERV_U_<var/name//.
 
@@ -1206,7 +1239,40 @@ and the service.
 <chapt id="notes">Applications and notes on use
 <p>
 
-<sect>Reducing the number of absolutely privileged subsystems
+<sect id="examples">Examples
+<p>
+
+The companion package, <prgn/userv-utils/, contains a selection of
+example services, some of which are useful tools in their own right.
+See the <prgn/README/ in its top-level directory for details.
+
+<sect id="standards">Standard services and directory management
+<p>
+
+In later versions of this specification standard service names and
+interfaces for common services such as mail delivery and WWW CGI
+scripts may be specified.
+<p>
+
+<prgn/userv/-using applications and system services which hide
+<prgn/userv/ behind wrapper scripts may need to store information in
+the user's filespace to preserve the correct placement of the security
+perimiters.  Such applications should usually do so in a directory
+(created by them) <tt>~/.userv/<var/service/</>, where <var/service/
+is the service name or application in question.
+<p>
+
+If desired, a dot-directory inside <tt>~/.userv</> may be used to
+avoid the user becoming confused by finding parts of a semi-privileged
+application's internal state in their filespace, and/or discourage
+them from fiddling with and thus corrupting it.
+<p>
+
+However, <prgn/userv/ applications should of course not rely for their
+global integrity and security on the integrity of the data on the
+user's side of the security boundary.
+
+<sect id="reducepriv">Reducing the number of absolutely privileged subsystems
 <p>
 
 Currently most Unix systems have many components which need to run as
@@ -1215,15 +1281,15 @@ it.  This gives rise to a large and complex body of code which must be
 trusted with the security of the system.
 <p>
 
-Using <prgn/userv/ many of these subsystems no longer need any unusual
-privilege.
-<p>
+If they were to use <prgn/userv/, many of these subsystems would no
+longer need any unusual privilege.  <p>
 
 <prgn/cron/ and <prgn/at/, <prgn/lpr/ and the system's mail transfer
 agent (<prgn/sendmail/, <prgn/smail/, <prgn/exim/ or the like) all
-fall into this category.
+fall into this category, though <prgn/userv/-based versions of these
+programs are not currently available.
 
-<sect>Do not give away excessive privilege to <prgn/userv/-using facilities
+<sect id="noexcess">Do not give away excessive privilege to <prgn/userv/-using facilities
 <p>
 
 There is a danger that people reimplementing the facilities I mention
@@ -1243,8 +1309,8 @@ the file in the context of the user, rather than its own.
 <p>
 
 A simple-minded approach to converting this scheme to use <prgn/userv/
-might involve giving the printer daemon (the <tt/lp/ user) the ability
-to read the file by allowing them to run <prgn/cat/ (or a
+might involve giving the printer daemon (the <prgn/lp/ user) the
+ability to read the file by allowing them to run <prgn/cat/ (or a
 special-purpose file-reading program) as any user.  The <prgn/lpr/
 program would use a <prgn/userv/ service to store the filename in the
 printer daemon's queues, and the daemon would read the file later when
@@ -1256,7 +1322,7 @@ system, whether or not someone had asked for it to be printed.  Since
 many files will contain passwords and other security-critical
 information this is nearly as bad as giving the daemon root access in
 the first place.  Any security holes in the print server which allow a
-user to execute commands as the <tt/lp/ user will give the user the
+user to execute commands as the <prgn/lp/ user will give the user the
 ability to read any file on the system.
 <p>
 
@@ -1287,36 +1353,66 @@ facilities which currently run as root.
 It is debatable whether the user-controlled state should be kept in
 the user's filespace (in dotfiles, say) or kept in a separate area set
 aside for the purpose; however, using the user's home directory (and
-probably creating a separate subdirectory of it as a dotfile to
-contain many subsystems' state) has fewer implications for the rest of
-the system and makes it entirely clear where the security boundaries
-lie.
+possibly creating a separate subdirectory of it as a dotfile to
+contain subsystem state) has fewer implications for the rest of the
+system and makes it entirely clear where the security boundaries lie.
 
-<sect><prgn/userv/ is not a replacement for <prgn/really/ and <prgn/sudo/
+<sect id="notreally"><prgn/userv/ can often replace <prgn/sudo/, but not <prgn/really/
 <p>
 
 <prgn/userv/ is not intended as a general-purpose system
 administration tool with which system administrators can execute
-privileged programs when they need to.  It is unsuitable for this
-purpose precisely because it enforces a strong separation between the
-calling and the called program, which is undesirable in this context.
+arbitrary programs like text editors as root (or other system users)
+when they need to.  It is unsuitable for this purpose precisely
+because it enforces a strong separation between the calling and the
+called program, which is undesirable in this context.
 <p>
 
-Its facilities for restricting activities to running certain programs
-may at first glance seem to provide similar functionality to
+However, its use when restricted to running particular programs in
+particular ways is very similar to many common uses of
 <prgn/sudo/<footnote><prgn/sudo/ is a program which allows users to
 execute certain programs as root, according to configuration files
-specified by the system administrator.</footnote>.  However, the
-separation mentioned above is a problem here too, particular for
-interaction - it can be hard for a <prgn/userv/ service program to
-interact with its real caller or the user in question.
+specified by the system administrator.</footnote>.  <prgn/userv/ is
+generally much better than restricted <prgn/sudo/, because it protects
+the called program much more strongly from bad environmental
+conditions set up by the caller.  Most programs that one might want to
+run via restricted <prgn/sudo/, have not been designed to run in a
+partially hostile environment.  <prgn/userv/ allows these programs to
+be run in a safer environment and should be used instead.
+
+<sect id="stdinerr">Error handling and input streams (eg stdin)
+<p>
+
+When the service program is reading from a file descriptor connected
+to the calling side, the fd that the service program refers to a pipe
+set up by <prgn/userv/ and not to the same object as was presented by
+the caller.
+<p>
+
+Therefore if there is some kind of error it is possible for the
+service-side fd to give premature end of file.  If it is important to
+tell whether all of the intended data has been received by the service
+program, the datastream must contain an explicit end-of-file
+indication of some kind.
+<p>
+
+For example, consider a <prgn/userv/ service for submitting a mail
+message, where message is supplied on the service's stdin.  However,
+if the calling process is interrupted before it has written all of the
+message, the service program will get EOF on the message data.  In a
+naive arrangement this would cause a half-complete message to be
+sent.  To prevent this, it is necessary to adopt some kind of explicit
+end indication; for example, the end of the message could be signalled
+by a dot on a line by itself, and dots doubled, as in SMTP.  Then the
+service program would know when the entire message had been received,
+and could avoid queueing incomplete messages.
 
-<sect>Don't give access to general-purpose utilities
+<sect id="nogeneral">Don't give access to general-purpose utilities
 <p>
 
 Do not specify general purpose programs like <prgn/mv/ or <prgn/cat/
-in <tt/execute-/ directives without careful thought about their
-arguments, and certainly not if <tt/no-suppress-args/ is specified.
+in <prgn/execute-/ directives without careful thought about their
+arguments, and certainly not if <prgn/no-suppress-args/ is specified.
 If you do so it will give the caller much more privilige than you
 probably intend.
 <p>