From: ian
-[back]
- [Abstract]
- [Copyright Notice]
- [Contents]
- [next]
+[ previous ]
+[ Contents ]
+[ 1 ]
+[ 2 ]
+[ 3 ]
+[ 4 ]
+[ 5 ]
+[ 6 ]
+[ next ]
-User service daemon and client specification - Chapter 2
-
-Client program usage
+User service daemon and client specification
+
Chapter 2 - Client program usage
-
-userv options [--] service-user service-name [argument ...]
-userv options -B|--builtin [--] builtin-service [info-argument ...]
+ userv options [--] service-user service-name [argument ...]
+ userv options -B|--builtin [--] builtin-service [info-argument ...]
-
-service-user specifies which user is to provide the service. -The user may be a login name or a numeric uid, or - to indicate -that the service user is to be the same as the calling user. -
+service-user specifies which user is to provide the service. The +user may be a login name or a numeric uid, or - to indicate that +the service user is to be the same as the calling user.-The service name is interpreted by the userv[1] -daemon on behalf of the service user. It will often be the name of a -program. -
+The service name is interpreted by the userv[1] daemon on behalf of the service user. It will often be the +name of a program.-Single-letter options may be combined as is usual with Unix programs, -and the value for such an option may appear in the same argument or in -the next. - +Single-letter options may be combined as is usual with Unix programs, and the +value for such an option may appear in the same argument or in the next.
--override
option to specify a string consisting of
+--override
option to specify a string consisting of
execute-builtin
followed by the builtin-service
requested, and requesting a service user of - (indicating the
calling user).
-If the builtin service being requested requires a
-service-argument then this must be supplied to the client in the
-same argument as the builtin-service. See Directives for changing execution settings, subsection 4.2.4 for details of the builtin services available,
-and Security-overriding options, section 2.2 for details of the --override
-options.
+
+If the builtin service being requested requires a service-argument
+then this must be supplied to the client in the same argument as the
+builtin-service. See Directives for changing execution
+settings, Section 4.2.4 for details of the builtin services available, and
+Security-overriding options, Section
+2.2 for details of the --override
options.
+
The actual service name passed will be the builtin-service; note
-that this actual service name (as opposed to the override data) and
-the info-arguments supplied will be ignored by most builtin
-services; the override mechanism and execute-builtin
will be
-used to ensure that the right builtin service is called with the right
+that this actual service name (as opposed to the override data) and the
+info-arguments supplied will be ignored by most builtin services;
+the override mechanism and execute-builtin
will be used to ensure
+that the right builtin service is called with the right
service-arguments.
+
cat
invoked by the client; the other file descriptor passed to
+cat
will be one inherited by the client program from the caller or
+one opened by the client program on behalf of the caller.
-cat
invoked by the client; the
-other file descriptor passed to cat
will be one inherited by
-the client program from the caller or one opened by the client program
-on behalf of the caller.
-
+The descriptor in the service program that should be connected must be -specified as fd, either as a decimal number or as one of the -strings stdin, stdout or stderr. The next argument is -a filename which will be opened by the client with the privileges of -the calling user. +specified as fd, either as a decimal number or as one of the strings +stdin, stdout or stderr. The next +argument is a filename which will be opened by the client with the privileges +of the calling user. -modifiers is used to specify whether the file or descriptor is -to be read from or written to. It consists of a series of words -separated by commas. A comma may separate the modifiers from -the fd and is required if fd is not numeric. +
+modifiers is used to specify whether the file or descriptor is to be +read from or written to. It consists of a series of words separated by commas. +A comma may separate the modifiers from the fd and is +required if fd is not numeric.
The modifier words are: -
-If no modifiers which imply read or write are used it -is as if write had been specified, except that if the -filedescriptor 0 of the service is being opened (either specified -numerically or with stdin) it is as if overwrite had been +If no modifiers which imply read or write +are used it is as if write had been specified, except that if the +filedescriptor 0 of the service is being opened (either specified numerically +or with stdin) it is as if overwrite had been specified (or write if only fd was specified). -
The client will also use O_NOCTTY when opening files specified by the caller, to avoid changing its controlling terminal. -
-By default stdin, stdout and stderr of the service will be connected -to the corresponding descriptors on the client. Diagnostics from -the client and daemon will also appear on stderr. -
+By default stdin, stdout and stderr of the service will be connected to the +corresponding descriptors on the client. Diagnostics from the client and +daemon will also appear on stderr.If wait is specified, the client will wait for the pipe to be -closed, and only exit after this has happened. This means that either -the receiving end of the pipe connection was closed while data was -still available at the sending end, or that the end of file was -reached on the reading file descriptor. Errors encountered reading or -writing in the client at this stage will be considered a system error -and cause the client to exit with status 255, but will not cause -disconnection at the service side since the service has already -exited. -
+closed, and only exit after this has happened. This means that either the +receiving end of the pipe connection was closed while data was still available +at the sending end, or that the end of file was reached on the reading file +descriptor. Errors encountered reading or writing in the client at this stage +will be considered a system error and cause the client to exit with status 255, +but will not cause disconnection at the service side since the service has +already exited.
If close is specified the client will immediately close the pipe
connection by killing the relevant copy of cat
. If the service
-uses the descriptor it will get SIGPIPE
(or EPIPE
) for a
-writing descriptor or end of file for a reading one; the descriptor
+uses the descriptor it will get SIGPIPE
(or EPIPE
)
+for a writing descriptor or end of file for a reading one; the descriptor
opened by or passed to the client will also be closed.
-
If nowait is specified then the client will not wait and the -connection will remain open after the client terminates. Data may -continue to be passed between the inheritors of the relevant -descriptor on the service side and the corresponding file or -descriptor on the client side until either side closes their -descriptor. This should not usually be specified for stderr (or -stdout if --signals stdout is used) since diagnostics from -the service side may arrive after the client has exited and be -confused with expected output. -
+connection will remain open after the client terminates. Data may continue to +be passed between the inheritors of the relevant descriptor on the service side +and the corresponding file or descriptor on the client side until either side +closes their descriptor. This should not usually be specified for stderr (or +stdout if --signals stdout is used) since diagnostics from the +service side may arrive after the client has exited and be confused with +expected output.-The default is wait for writing file descriptors and close -for reading ones. -
- ---file
or --fdwait
option - even by a
+The default is wait for writing file descriptors and
+close for reading ones.
+--file
or --fdwait
option - even by a
--file
which does not specify an action on termination (in this
case the default will be used, as described above).
-
-_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 wait
family of system calls.)
+_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 wait
family of
+system calls.)
The method may be one of the following: -
-Problems such as client usage errors, the service not being found or -permission being denied or failure of a system call are system errors. -An error message describing the problem will be printed on the -client's stderr, and the client's exit status will be 255. If the -client dies due to a signal this should be treated as a serious system -error. -
- -SIGPIPE
the exit
-status of the client will be zero, even if it would have been
-something else according to the exit status method specified. This
-option has no effect on the code and description printed if the exit
-status method stdout is in use.
-
-SIGPIPE
the exit
+status of the client will be zero, even if it would have been something else
+according to the exit status method specified. This option has no effect on
+the code and description printed if the exit status method stdout
+is in use.
+-There are also some options which are available for debugging and to -allow the system administrator to override a user's policy. These -options are available only if the client is called by root or if the -calling user is the same as the service user. - +There are also some options which are available for debugging and to allow the +system administrator to override a user's policy. These options are available +only if the client is called by root or if the calling user is the same as the +service user.
+User service daemon and client specification
-1.0.1ian@davenant.greenend.org.uk
+-Which services may be run by whom and under what conditions is -controlled by configuration files. -
+Which services may be run by whom and under what conditions is controlled by +configuration files.-The daemon will read these files in order. Certain directives in the -files modify the daemon's execution settings for invoking the service, -for example allowing certain file descriptors to be specified by the -client or specifying which program to execute to provide the service. -
+The daemon will read these files in order. Certain directives in the files +modify the daemon's execution settings for invoking the service, for example +allowing certain file descriptors to be specified by the client or specifying +which program to execute to provide the service.The last instance of each such setting will take effect. The directives which specify which program to execute will not stop the -configuration file from being read; they will be remembered and will -only take effect if they are not overridden by a later directive. -
+configuration file from being read; they will be remembered and will only take +effect if they are not overridden by a later directive.The daemon will first read /etc/userv/system.default. Then, by @@ -52,544 +58,691 @@ default (this behaviour may be modified), it will read a per-user file ~/.userv/rc, if it exists and the service user's shell is in /etc/shells. Finally it will read /etc/userv/system.override. -
-When it has read all of these files it will act according to the -currently values of of the execution settings. -
+When it has read all of these files it will act according to the currently +values of of the execution settings.-The configuration file is a series of directives, usually one per -line. The portion of a line following a hash character # is -taken as a comment and ignored. Each directive consists of a series -of tokens separated by linear whitespace (spaces and tabs); tokens may -be words consisting of non-space characters, or, where a string is -required, a string in double quotes. Double-quoted strings may -contain the following backslash escapes: - -
-Relative pathnames in directives are relative to the service program's -current directory (usually the service user's home directory). -Pathnames starting with the two characters ~/ are taken to be -relative to the service user's home directory. -
+Relative pathnames in directives are relative to the service program's current +directory (usually the service user's home directory). Pathnames starting with +the two characters ~/ are taken to be relative to the service +user's home directory.The following directives take effect immediately: -
cd
is cumulative. It
-is an error if the directory cannot be changed to.
-
-cd
should not be used between execute-from-directory
and
-the invocation of the service program, as the test for the
-availability of the service program would be done with the old current
-directory and the actual execution with the new (probably causing an
-error).
+cd
is cumulative. It is
+an error if the directory cannot be changed to.
-if
, catch-quit
or
+
+cd
should not be used between execute-from-directory
+and the invocation of the service program, as the test for the availability of
+the service program would be done with the old current directory and the actual
+execution with the new (probably causing an error).
+
if
, catch-quit
or
errors-push
) which were started in that file will be considered
-finished. Parsing will continue in the file which caused the file
-containing the eof
to be read.
-
-quit
is subject to the
-catch-quit
control construct.
-
-include-ifexist
-is used and the file does not exist, in which case the directive is
-silently ignored.
-
-if
, Control structure directives, subsection 4.2.3). If parameter has several values they will
-be tried in order; with include-lookup
this search will stop
-when one is found, but with include-lookup-all
the search will
-continue and any files appropriate to other values will be read too.
-
-If none of the parameter's values had a corresponding file then the
-file :default will be read, if it exists. If parameter's
+finished. Parsing will continue in the file which caused the file containing
+the eof
to be read.
+quit
is subject to the catch-quit
+control construct.
+include-ifexist
is used and the
+file does not exist, in which case the directive is silently ignored.
+if
, Control structure directives, Section
+4.2.3). If parameter has several values they will be tried in
+order; with include-lookup
this search will stop when one is
+found, but with include-lookup-all
the search will continue and
+any files appropriate to other values will be read too.
+
++If none of the parameter's values had a corresponding file then the file +:default will be read, if it exists. If parameter's list of values was empty then the file :none will be tried first and read if it exists, otherwise :default will be tried. +
It is not an error for any of the files (including :default) not -to exist, but it is an error if a file exists and cannot be read or if -the directory cannot be accessed. - -A translation will be applied to values before they are used to -construct a filename, so that the lookup cannot access dotfiles or -files in other directories: values starting with full stops will have -a colon prepended (making :.), colons will be doubled, and each -slash will be replaced with a colon followed by a hyphen :-. A -parameter value which is the empty string will be replaced with -:empty (note that this is different from a parameter not having -any values). - -
+A translation will be applied to values before they are used to construct a +filename, so that the lookup cannot access dotfiles or files in other +directories: values starting with full stops will have a colon prepended +(making :.), colons will be doubled, and each slash will be +replaced with a colon followed by a hyphen :-. A parameter value +which is the empty string will be replaced with :empty (note that +this is different from a parameter not having any values). +
-The following directives have no immediate effect, but are remembered -and have an effect on later processing of the configuration files. - +The following directives have no immediate effect, but are remembered and have +an effect on later processing of the configuration files.
system.default
configuration file has been read. This
-directive has no effect in a user's configuration file or in the
-system.override
file, as the user's configuration file has
-already been found and read by then and will not be re-read.
-
-syslog
. The default
-facility is user; the default level is error.
-
+system.default
configuration file has been read. This directive
+has no effect in a user's configuration file or in the
+system.override
file, as the user's configuration file has already
+been found and read by then and will not be re-read.
+syslog
. The default
+facility is user; the default level is
+error.
+-The following directives are used to create control structures. If -the end of the file is encountered before the end of any control -structure which was started inside it then that control structure is -considered finished. This is not an error. - +The following directives are used to create control structures. If the end of +the file is encountered before the end of any control structure which was +started inside it then that control structure is considered finished. This is +not an error.
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.
+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.
The conditions are: - -
-( condition -& condition -& condition -... -) +
+ ( condition + & condition + & condition + ... + )- +
is true if all the listed conditions are true; where | is used it is true if any of them is true. Newlines must be used to separate one -condition from the next, as shown, and the parentheses are mandatory. -These conjunctions do not do lazy evaluation. - +condition from the next, as shown, and the parentheses are mandatory. These +conjunctions do not do lazy evaluation. +
The parameters are: - -
USERV_USER
, above) and the calling uid (represented in
-decimal).
-
-USERV_USER
, above).
-
-USERV_USER
, above) and the calling uid (represented in decimal).
+USERV_USER
, above).
+--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
+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
include-lookup on it will read the :none file, or
:default if :none is not found.
-
+errors-push
and
+errors-push
and
srorre
.
-
-quit
inside catch-quit
will merely cause the
-parsing to continue at hctac
instead. Any control constructs
+quit
inside catch-quit
will merely cause
+the parsing to continue at hctac
instead. Any control constructs
started since the catch-quit
will be considered finished if a
quit
is found.
-If an error occurs inside catch-quit
the execution settings
-will be reset (as if by the reset
directive) and parsing will
-likewise continue at hctac
.
-
-If a lexical or syntax error is detected in the same configuration
-file as the catch-quit
, while looking for the hctac
-after an error or quit
, that new error will not be caught.
+
+If an error occurs inside catch-quit
the execution settings will
+be reset (as if by the reset
directive) and parsing will likewise
+continue at hctac
.
+
+If a lexical or syntax error is detected in the same configuration file as the
+catch-quit
, while looking for the hctac
after an
+error or quit
, that new error will not be caught.
+
-The following directives modify the execution settings; the server -will remember the fact that the directive was encountered and act on -it only after all the configuration has been parsed. The last -directive which modifies any particuar setting will take effect. - +The following directives modify the execution settings; the server will +remember the fact that the directive was encountered and act on it only after +all the configuration has been parsed. The last directive which +modifies any particuar setting will take effect.
execute
, execute-from-directory
and
-execute-from-path
will change this setting.
-
-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 program does not contain a slash it will
-be searched for on the service user's path.
-
-execute
, execute-from-directory
+and execute-from-path
will change this setting.
+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 program does not
+contain a slash it will be searched for on the service user's path.
++This directive is ignored if the relevant program does not exist in the +directory specified; in this case the program to execute is left at its +previous setting (or unset, if it was not set before). -
PATH
++It is an error for the test for the existence of the program to fail other than +with a `no such file or directory' indication. It is also an error for the +execution to fail if and when it is attempted (after all the configuration has +been parsed). +
PATH
(or as a pathname of an executable, if it contains a /). This
directive is very dangerous, and is only provided to make the
---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).
-
--Executes the builtin service service-name. These builtin -services display information about the server and/or the request, and -ignore any arguments passed from the service side except possibly to -print them as part of their output. They write their results to their -standard output (i.e., wherever file descriptor 1 is directed). The -builtin services are: - -
reset
-is found in a configuration file, or when an error is caught by
+--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).
+reset
is
+found in a configuration file, or when an error is caught by
catch-quit
).
-
-+In the future other builtin services may be defined which do more than just +print information. +
-.../program arg arg arg ... + .../program arg arg arg ...+
as +
-/bin/sh -c '. /etc/environment; exec "$@"' - .../program arg arg arg ... + /bin/sh -c '. /etc/environment; exec "$@"' - .../program arg arg arg ...+
no-set-environment
cancels the effect of
set-environment
.
+
execute
, execute-from-directory
or
+execute-from-path
directive. suppress-args
undoes
+the effect of no-suppress-args
.
+require-fd
, allow-fd
, ignore-fd
,
+null-fd
or reject-fd
which affected a particular file
+descriptor will take effect.
-execute
,
-execute-from-directory
or execute-from-path
directive.
-suppress-args
undoes the effect of no-suppress-args
.
-
-require-fd
,
-allow-fd
, ignore-fd
, null-fd
or reject-fd
-which affected a particular file descriptor will take effect.
-
-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
-stdin, stdout or stderr. Open-ended file descriptor
-rangers are allowed only with reject-fd
and ignore-fd
,
-as otherwise the service program would find itself with a very large
-number of file descriptors open.
-
-When the configuration has been parsed, and before the service is
-about to be executed, stderr (fd 2) must be required or allowed
-(require-fd
or allow-fd
) for writing; this is so that
-the error message printed by the server's child process if it cannot
-exec
the service program is not lost.
-
-/dev/null
for
-reading resp. writing, or both if neither read nor write
-is specified. Any specification of these file descriptors by the
-client will be silently ignored; the client will see its ends of the
-descriptors being closed immediately.
-
-
+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 stdin,
+stdout or stderr. Open-ended file descriptor rangers
+are allowed only with reject-fd
and ignore-fd
, as
+otherwise the service program would find itself with a very large number of
+file descriptors open.
-
SIGHUP
if the
-client disconnects before the main service process terminates.
+
+When the configuration has been parsed, and before the service is about to be
+executed, stderr (fd 2) must be required or allowed (require-fd
or
+allow-fd
) for writing; this is so that the error message printed
+by the server's child process if it cannot exec
the service
+program is not lost.
+
/dev/null
for
+reading resp. writing, or both if neither read nor
+write is specified. Any specification of these file descriptors
+by the client will be silently ignored; the client will see its ends of the
+descriptors being closed immediately.
+SIGHUP
if the client
+disconnects before the main service process terminates.
no-disconnect-hup
cancels disconnect-hup
.
-If one of the reading descriptors specified when the client is called
-gets a read error, or if the service is disconnected for some other
-reason, then the SIGHUP
will be delivered before the
-writing end(s) of the service's reading pipe(s) are closed, so that
-the client can distinguish disconnection from reading EOF on a pipe.
+
+If one of the reading descriptors specified when the client is called gets a
+read error, or if the service is disconnected for some other reason, then the
+SIGHUP
will be delivered before the writing end(s) of the
+service's reading pipe(s) are closed, so that the client can distinguish
+disconnection from reading EOF on a pipe.
+
-cd ~/ -reject -no-set-environment -suppress-args -allow-fd 0 read -allow-fd 1-2 write -reject-fd 3- -disconnect-hup + cd ~/ + reject + no-set-environment + suppress-args + allow-fd 0 read + allow-fd 1-2 write + reject-fd 3- + disconnect-hup- +
If no execute
, execute-from-path
,
-execute-from-directory
or builtin
is interpreted before
-all the files are read then the request is rejected.
-
execute-from-directory
or builtin
is interpreted
+before all the files are read then the request is rejected.
-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 errors-
family
-of directives, above).
-
errors-
family of directives, above).
-The error will cause processing of the configuration files to cease at
-that point, unless the error was inside a catch-quit
construct.
-In this case the settings controlling the program's execution will be
-reset to the defaults as if a reset
directive had been issued,
-and parsing continues after hctac
.
-
catch-quit
construct. In
+this case the settings controlling the program's execution will be reset to the
+defaults as if a reset
directive had been issued, and parsing
+continues after hctac
.
-The default configuration processing is as if the daemon were parsing -an overall configuration file whose contents were as follows: +The default configuration processing is as if the daemon were parsing an +overall configuration file whose contents were as follows:
-reset -user-rcfile ~/.userv/rc -errors-to-stderr -include /etc/userv/system.default -if grep service-user-shell /etc/shells - errors-push - catch-quit - include-ifexist file specified by most recent user-rcfile directive - hctac - srorre -fi -include /etc/userv/system.override -quit + reset + user-rcfile ~/.userv/rc + errors-to-stderr + include /etc/userv/system.default + if grep service-user-shell /etc/shells + errors-push + catch-quit + include-ifexist file specified by most recent user-rcfile directive + hctac + srorre + fi + include /etc/userv/system.override + quit-
If one of the --override
options to the client is used then it
-will instead be as if the daemon were parsing an overall configuration
-as follows:
+will instead be as if the daemon were parsing an overall configuration as
+follows:
-reset -errors-to-stderr -include file containing configuration data sent by client -quit + reset + errors-to-stderr + include file containing configuration data sent by client + quit-
+User service daemon and client specification
-1.0.1ian@davenant.greenend.org.uk
+The daemon which is handling the service user side of things will read -configuration files to decide what to do. If it decides to allow the -service to be provided it will fork a subprocess to execute the -service. -
+configuration files to decide what to do. If it decides to allow the service +to be provided it will fork a subprocess to execute the service.-The service will have no controlling terminal, but it will be a -process group leader. -
+The service will have no controlling terminal, but it will be a process group +leader.
-If the client is killed or times out or a file or descriptor being
-read or written by the client process gets an error then the service
-will be disconnected from the client. The client will return an exit
-status of 255 and some the service's pipes may be closed at the other
-end. The service will become a child of init
. The service may
-well not notice the disconnection, though writing to a pipe after this
-may produce a SIGPIPE
and the facility exists to have a
-SIGHUP
sent to the service on disconnection.
-
init
. The service may well not notice the
+disconnection, though writing to a pipe after this may produce a
+SIGPIPE
and the facility exists to have a SIGHUP
sent
+to the service on disconnection.
-The service program's standard filedescriptors, and possibly other
-file descriptors, will be connected to pipes or to
-/dev/null
. The userv
client/daemon pair will arrange
-that data is copied between the files or file descriptors specified to
-to the client by the caller and these these pipes.
-
/dev/null
. The
+userv
client/daemon pair will arrange that data is copied between
+the files or file descriptors specified to to the client by the caller and
+these these pipes.
-Pipes which may be written to will be closed if a write error occurs
-on the corresponding client-side file or descriptor, which may result
-in a SIGPIPE
in the service program; pipes open for reading
-will get EOF
if the client-side file descriptor gets EOF
-or an error.
-
SIGPIPE
in the service program; pipes open for reading will get
+EOF
if the client-side file descriptor gets EOF
or an
+error.
-If the service closes one of its reading file descriptors the writing
-end of the corresponding pipe will generate a SIGPIPE
when
-attempts are made by the client/daemon pair to write to it. This will
-not be considered an error; rather, the relevant pipe will be
-discarded and the corresponding file or file descriptor held by the
-client will be closed.
-
SIGPIPE
when attempts are
+made by the client/daemon pair to write to it. This will not be considered an
+error; rather, the relevant pipe will be discarded and the corresponding file
+or file descriptor held by the client will be closed.
-Likewise, if one of the file descriptors held by the client for
-writing by the service is a pipe whose other end is closed by the
-caller then the client/daemon pair will see an error when trying to
-copy data provided by the service. This too will not be considered an
-error; rather, the pipe correspondong to that descriptor will be
-closed and any further writes will cause the service to get a
-SIGPIPE
.
-
SIGPIPE
.
-Note that not all write errors or broken pipes on file descriptors may
-be visible to the service, since buffered data may be discarded by the
-operating system and there will be a finite interval between the error
-happening and the service being disconnected from the client or the
-next write causing a SIGPIPE
.
-
SIGPIPE
.
-Read errors on file descriptors (and disconnection) will only be
-visible to the service and distinguishable from normal end of file if
+Read errors on file descriptors (and disconnection) will only be visible to the
+service and distinguishable from normal end of file if
disconnect-hup
is in effect.
-
-Read and write errors (other than broken pipes, as described above) -will always be visible to the caller; they are system errors, and will -therefore cause the client to print an error message to stderr and -return with an exit status of 255. -
+Read and write errors (other than broken pipes, as described above) will always +be visible to the caller; they are system errors, and will therefore cause the +client to print an error message to stderr and return with an exit status of +255.
-If the main service program process exits while it still has running
-children any file descriptors held by those children can remain open,
-depending on the use of wait, nowait or close for the
-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
-SIGHUP
even if a read or write error occurs or the client
-disconnects before then.
-
SIGHUP
even if a read
+or write error occurs or the client disconnects before then.
The service will have some information in environment variables: -
LOGNAME
variable is
+LOGNAME
variable is
set (or, if that is unset, if the USER
variable is set) in the
-environment passed to the client by the caller then the password entry
-for that login name will be looked up; if that password entry's uid is
-the same as that of the calling process then that login name will be
-used, otherwise (or if neither LOGNAME
nor USER
is set)
-the calling process's uid will be looked up to determine their login
-name (and if this lookup fails then the service will not be invoked).
-
-USERV_GID
. If no name can be found for any of the
-calling process's group(s) then the service will not be invoked.
-
-LOGNAME
nor USER
is set) the calling
+process's uid will be looked up to determine their login name (and if this
+lookup fails then the service will not be invoked).
+USERV_GID
. If no name can be found for any of the calling
+process's group(s) then the service will not be invoked.
+--hidecwd
flag was used then this variable will be set to an
-empty string (this is not considered an error).
-
---hidecwd
flag was used then this variable will be set to an empty
+string (this is not considered an error).
+HOME
, PATH
, SHELL
, LOGNAME
and USER
-will be set appropriately (according to the details of the service
-user).
-
+
+HOME
, PATH
, SHELL
, LOGNAME
+and USER
will be set appropriately (according to the details of
+the service user).
+User service daemon and client specification
-1.0.1ian@davenant.greenend.org.uk
+
-There is a daemon which invokes user service programs (henceforth
-`services') in response to requests by callers of a companion client
-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 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'.
-
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'.
-The daemon and the client are responsible for ensuring that -information is safely carried across the security boundary between the -two users, and that the processes on either side cannot interact with -each other in any unexpected ways. -
+The daemon and the client are responsible for ensuring that information is +safely carried across the security boundary between the two users, and that the +processes on either side cannot interact with each other in any unexpected +ways.+User service daemon and client specification
-1.0.1ian@davenant.greenend.org.uk
+-The information described below is the only information which passes -between the caller and the service. +
+The information described below is the only information which passes between +the caller and the service.
service
parameter, and is used by the
+service
parameter, and is used by the
execute-from-directory
and 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
+configuration directives. It is usually used to select which service program
+to invoke. It is also passed to the service program in the
USERV_SERVICE
environment variable.
+SIGPIPE
(or EPIPE
if
-SIGPIPE
is caught or ignored) in the service.
-
-Likewise, the service can close filedescriptors specified for reading,
-which will cause the corresponding filedescriptors passed by the
-caller to be closed, so that if these are pipes processes which write
-to them will receive SIGPIPE
or EPIPE
.
-
-no-suppress-args
is set then arguments passed to the client
-by its caller will be passed on, verbatim, to the service.
-
-disconnect-hup
is set then the service will also be sent a
-SIGHUP
.
-
-LOGNAME
(or 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.
-
-This login name and the calling uid are available in the configuration
-language in the calling-user
parameter and are passed to the
-service program in environment variables USERV_USER
and
-USERV_UID
.
-
-The shell corresponding to that login name (according to the password
-entry) is available as in the configuration language's
-calling-user-shell
parameter.
-
-If no relevant password entry can be found then no service will be
-invoked.
++Data may be passed into the service through reading pipes and out of it through +writing pipes. These pipes can remain open only until the service and client +have terminated, or can be made to stay open after the client has terminated +and (if the service program forks) the main service process has exited; the +behaviour is controlled by options passed to the client by its caller. -
calling-group
parameter and are passed to the service in
-environment variables.
+
+The caller can arrange that a writing pipe be connected to a pipe or similar
+object and cause attempts to write to that descriptor by the service to
+generate a SIGPIPE
(or EPIPE
if SIGPIPE
+is caught or ignored) in the service.
-If no name can be found for a numeric group to which the calling
-process belongs then no service will be invoked.
+
+Likewise, the service can close filedescriptors specified for reading, which
+will cause the corresponding filedescriptors passed by the caller to be closed,
+so that if these are pipes processes which write to them will receive
+SIGPIPE
or EPIPE
.
+
no-suppress-args
is set then arguments passed to the client by
+its caller will be passed on, verbatim, to the service.
+disconnect-hup
+is set then the service will also be sent a SIGHUP
.
+LOGNAME
(or 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.
---hidecwd
,
-to the service program in the 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.
+
+This login name and the calling uid are available in the configuration language
+in the calling-user
parameter and are passed to the service
+program in environment variables USERV_USER
and
+USERV_UID
.
-
+The shell corresponding to that login name (according to the password entry) is
+available as in the configuration language's calling-user-shell
+parameter.
-
+If no relevant password entry can be found then no service will be invoked. +
calling-group
parameter and are passed to the service in
+environment variables.
++If no name can be found for a numeric group to which the calling process +belongs then no service will be invoked. +
--hidecwd
, to the
+service program in the 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.
++User service daemon and client specification
-1.0.1ian@davenant.greenend.org.uk
+
The companion package, userv-utils
, contains a selection of
-example services, some of which are useful tools in their own right.
-See the README
in its top-level directory for details.
-
README
in its top-level directory for details.
-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. -
+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.
userv
-using applications and system services which hide
-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) ~/.userv/service, where service
-is the service name or application in question.
-
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)
+~/.userv/service, where service is the
+service name or application in question.
-If desired, a dot-directory inside ~/.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. -
+If desired, a dot-directory inside ~/.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.
However, 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.
-
-Currently most Unix systems have many components which need to run as -root, even though most of their activity does not strictly require -it. This gives rise to a large and complex body of code which must be -trusted with the security of the system. -
+Currently most Unix systems have many components which need to run as root, +even though most of their activity does not strictly require it. This gives +rise to a large and complex body of code which must be trusted with the +security of the system.
If they were to use userv
, many of these subsystems would no
longer need any unusual privilege.
-
-cron
and at
, lpr
and the system's mail transfer
-agent (sendmail
, smail
, exim
or the like) all
-fall into this category, though userv
-based versions of these
-programs are not currently available.
-
cron
and at
, lpr
and the system's mail
+transfer agent (sendmail
, smail
, exim
or
+the like) all fall into this category, though userv
-based versions
+of these programs are not currently available.
userv
-using facilities
-userv
-using facilities
-There is a danger that people reimplementing the facilities I mention
-above using userv
will discard much of the security benefit by
-using a naive implementation technique. This will become clearer with
-an example:
-
userv
will discard much of the security benefit by using a
+naive implementation technique. This will become clearer with an example:
-Consider the lpr
program. In current systems this needs to
-have an absolutely privileged component in order to support delayed
-printing without copying: when the user queues a file to be printed
-the filename is stored in the print queue, rather than a copy of it,
-and the printer daemon accesses the file directly when it is ready to
-print the job. In order that the user can print files which are not
-world-readable the daemon is given root privilege so that it can open
-the file in the context of the user, rather than its own.
-
lpr
program. In current systems this needs to have
+an absolutely privileged component in order to support delayed printing without
+copying: when the user queues a file to be printed the filename is stored in
+the print queue, rather than a copy of it, and the printer daemon accesses the
+file directly when it is ready to print the job. In order that the user can
+print files which are not world-readable the daemon is given root privilege so
+that it can open the file in the context of the user, rather than its own.
A simple-minded approach to converting this scheme to use userv
-might involve giving the printer daemon (the lp
user) the
-ability to read the file by allowing them to run cat
(or a
-special-purpose file-reading program) as any user. The lpr
-program would use a userv
service to store the filename in the
-printer daemon's queues, and the daemon would read the file later when
-it felt like it.
-
lp
user) the ability
+to read the file by allowing them to run cat
(or a special-purpose
+file-reading program) as any user. The lpr
program would use a
+userv
service to store the filename in the printer daemon's
+queues, and the daemon would read the file later when it felt like it.
-However, this would allow the printer daemon to read any file on the
-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 lp
user will give the user the
-ability to read any file on the system.
-
lp
user
+will give the user the ability to read any file on the system.
-Instead, it is necessary to keep a record of which files the daemon
-has been asked to print outside the control of the print daemon.
-This record could be kept by a new root-privileged component, but this
-is not necessary: the record of which files a user has asked to be
-printed can be kept under the control of the user in question. The
-submission program lpr
will make a record in an area under the
-user's control before communicating with the print server, and the
-print server would be given the ability to run a special file-reading
-program which would only allow files to be read which were listed in
-the user's file of things they'd asked to print.
-
lpr
will
+make a record in an area under the user's control before communicating with the
+print server, and the print server would be given the ability to run a special
+file-reading program which would only allow files to be read which were listed
+in the user's file of things they'd asked to print.
-Now security holes in most of the printing system do not critically -affect the security of the entire system: they only allow the attacker -to read and interfere with print jobs. Bugs in the programs run by the -print server to read users' files (and to remove entries from the list -of files when it has done with them) will still be serious, but this -program can be quite simple. -
+Now security holes in most of the printing system do not critically affect the +security of the entire system: they only allow the attacker to read and +interfere with print jobs. Bugs in the programs run by the print server to +read users' files (and to remove entries from the list of files when it has +done with them) will still be serious, but this program can be quite simple.
Similar considerations apply to many userv
-based versions of
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 -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. -
+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 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.userv
can often replace sudo
, but not really
-userv
can often replace sudo
, but not really
-userv
is not intended as a general-purpose system
-administration tool with which system administrators can execute
-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.
-
userv
is not intended as a general-purpose system administration
+tool with which system administrators can execute 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.
-However, its use when restricted to running particular programs in
-particular ways is very similar to many common uses of
-sudo
[2]. userv
is
-generally much better than restricted 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 sudo
, have not been designed to run in a
-partially hostile environment. userv
allows these programs to
-be run in a safer environment and should be used instead.
-
sudo
[2]. userv
is generally
+much better than restricted 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
+sudo
, have not been designed to run in a partially hostile
+environment. userv
allows these programs to be run in a safer
+environment and should be used instead.
-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 userv
and not to the same object as was presented by
-the caller.
-
userv
and not to the same object as was presented by the caller.
-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. -
+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.
For example, consider a 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.
-
-Do not specify general purpose programs like mv
or cat
-in execute-
directives without careful thought about their
-arguments, and certainly not if no-suppress-args
is specified.
-If you do so it will give the caller much more privilige than you
+Do not specify general purpose programs like mv
or
+cat
in execute-
directives without careful thought
+about their arguments, and certainly not if no-suppress-args
is
+specified. If you do so it will give the caller much more privilige than you
probably intend.
-
-It is a shame that I have to say this here, but inexperienced
-administrators have made similar mistakes with programs like
-sudo
.
-
sudo
.
+User service daemon and client specification
-1.0.1ian@davenant.greenend.org.uk
+
-userv
is
-short for `user services', and is pronounced `you-serve'.
-
-sudo
is a program which allows users to
-execute certain programs as root, according to configuration files
-specified by the system administrator.
-
userv
is short for `user services', and is pronounced `you-serve'.
- [Abstract]
- [Copyright Notice]
- [Contents]
+
+sudo
is a program which allows users to execute certain programs
+as root, according to configuration files specified by the system
+administrator.
+User service daemon and client specification
-1.0.1ian@davenant.greenend.org.uk
+