chiark / gitweb /
Proper version.h.
[userv.git] / spec.sgml
1 <!doctype debiandoc system>
2 <book>
3 <title>User service daemon and client specification
4 <author>Ian Jackson <email>ian@chiark.greenend.org.uk
5 <version>draft 0.17
6
7 <abstract>
8 This is a specification for a Unix system facility to allow one
9 program to invoke another when only limited trust exists
10 between them.
11
12 <copyright>
13 Copyright 1996-1997 Ian Jackson.
14 <p>
15
16 <prgn/userv/ is free software; you can redistribute it and/or modify
17 it under the terms of the GNU General Public License as published by
18 the Free Software Foundation; either version 2 of the License, or (at
19 your option) any later version.
20 <p>
21
22 This program is distributed in the hope that it will be useful, but
23 <em/without any warranty/; without even the implied warranty of
24 <em/merchantability/ or <em/fitness for a particular purpose/.  See
25 the GNU General Public License for more details.
26 <p>
27
28 You should have received a copy of the GNU General Public License
29 along with <prgn/userv/; if not, write to the Free Software
30 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31
32 <toc sect>
33
34 <chapt id="intro">Introduction
35 <p>
36 There is a daemon which invokes user service programs (henceforth
37 `services') in response to requests by callers of a companion client
38 program (henceforth the `client') and according to rules set forth in
39 system-wide and user-specific configuration files.  The companion
40 client program is setuid root, and negotiates with the daemon through
41 an <tt/AF_UNIX/ socket and associated objects in a system-wide private
42 directory set aside for the purpose.  The user who wishes the service
43 to be performed and calls the client is called the `calling user'; the
44 process which calls the client is called the `calling process'.
45
46 <p>
47 The daemon and the client are responsible for ensuring that
48 information is safely carried across the security boundary between the
49 two users, and that the processes on either side cannot interact with
50 each other in any unexpected ways.
51
52 <chapt id="client">Client program usage
53
54 <p>
55 <example>
56 userv <var/options/ [--] <var/service-user/ <var/service-name/ [<var/argument/ ...]
57 </example>
58 <p>
59
60 <var/service-user/ specifies which user is to provide the service.
61 The user may be a login name or a numeric uid.
62 <p>
63
64 The service name is interpreted by the userv<footnote><tt/userv/ is
65 short for `user services', and is pronounced `you-serve'.</footnote>
66 daemon on behalf of the service user.  It will often be the name of a
67 program.
68
69 <sect>Options
70 <p>
71
72 Single-letter options may be combined as is usual with Unix programs,
73 and the value for such an option may appear in the same argument or in
74 the next.
75
76 <taglist>
77 <tag/<tt/-f<var/fd/[<var/modifiers/]=<var/filename///
78 <tag/<tt/--file <var/fd/[<var/modifiers/]=<var/filename///
79 <item>
80 Requests that data be copied in and out of the service using pipes.
81 For each file or descriptor this will be done by creating a pipe, one
82 end of which is passed to the service program and the other end of
83 which is passed to a copy of <prgn/cat/ invoked by the client; the
84 other file descriptor passed to <prgn/cat/ will be one inherited by
85 the client program from the caller or one opened by the client program
86 on behalf of the caller.
87 <p>
88
89 The descriptor in the service program that should be connected must be
90 specified as <var/fd/, either as a decimal number or as one of the
91 strings <tt/stdin/, <tt/stdout/ or <tt/stderr/.  The next argument is
92 a filename which will be opened by the client with the privileges of
93 the calling user.
94
95 <p>
96 <var/modifiers/ is used to specify whether the file or descriptor is
97 to be read from or written to.  It consists of a series of words
98 separated by commas.  A comma may separate the <var/modifiers/ from
99 the <var/fd/ and is required if <var/fd/ is not numeric.
100
101 <p>
102 The modifier words are:
103 <taglist compact>
104 <tag/<tt/read//
105 <item>
106 <tt/O_RDONLY/: Allow reading and not writing.  May not be used with
107 <tt/write/ or things that imply it.
108
109 <tag/<tt/write//
110 <item>
111 <tt/O_WRONLY/: Allow writing and not reading.  <em/Doesn't truncate or
112 create/ without <tt/truncate/ or <tt/create/.  <tt/write/ or things
113 that imply it may not be used with <tt/read/.
114
115 <tag/<tt/overwrite//
116 <item>
117 Equivalent to <tt/write,create,truncate/.
118
119 <tag/<tt/create//
120 <tag/<tt/creat//
121 <item>
122 <tt/O_CREAT/: Creates the file if necessary.  Implies <tt/write/.
123
124 <tag/<tt/exclusive//
125 <tag/<tt/excl//
126 <item>
127 <tt/O_EXCL/: Fails if the file already exists.  Implies <tt/write/ and
128 <tt/create/.  May not be used with <tt/truncate/.
129
130 <tag/<tt/truncate//
131 <tag/<tt/trunc//
132 <item>
133 <tt/O_TRUNC/: Truncate any existing file.  Implies <tt/write/.
134 May not be used with <tt/exclusive/.
135
136 <tag/<tt/append//
137 <item>
138 <tt/O_APPEND/: All writes will append to the file.  Implies <tt/write/.
139
140 <tag/<tt/sync//
141 <item>
142 <tt/O_SYNC/: Do writes synchronously.  Implies <tt/write/.
143
144 <tag/<tt/wait//
145 <tag/<tt/nowait//
146 <tag/<tt/close//
147 <item>
148
149 These modifiers control the behaviour of the client, with respect to
150 the pipes carrying data to and from the service, when the service
151 terminates.  See below.
152
153 <tag/<tt/fd//
154 <item>
155 The <var/filename/ is not a filename but a numeric file descriptor.
156 One or both of <tt/read/ and <tt/write/ must be specified, and no
157 other words are allowed.  The <var/filename/ may also be <tt/stdin/,
158 <tt/stdout/ or <tt/stderr/ for file descriptor 0, 1 or 2 respectively.
159
160 </taglist>
161 <p>
162
163 If no <var/modifiers/ which imply <tt/read/ or <tt/write/ are used it
164 is as if <tt/read/ had been specified, except that if the
165 filedescriptor 1 or 2 of the service is being opened (either specified
166 numerically or with <tt/stdout/ or <tt/stderr/) it is as if
167 <tt/overwrite/ had been specified (or <tt/write/ if only <tt/fd/ was
168 specified).
169 <p>
170
171 The client will also use <tt/O_NOCTTY/ when opening files specified by
172 the caller, to avoid changing its controlling terminal.
173 <p>
174
175 By default stdin, stdout and stderr of the service will be connected
176 to the corresponding descriptors on the client.  Diagnostics from
177 the client and daemon will also appear on stderr.
178 <p>
179
180 If <tt/wait/ is specified, the client will wait for the pipe to be
181 closed, and only exit after this has happened.  This means that either
182 the receiving end of the pipe connection was closed while data was
183 still available at the sending end, or that the end of file was
184 reached on the reading file descriptor.  Errors encountered reading or
185 writing in the client at this stage will be considered a system error
186 and cause the client to exit with status 255, but will not cause
187 disconnection at the service side since the service has already
188 exited.
189 <p>
190
191 If <tt/close/ is specified the client will immediately close the pipe
192 connection by killing the relevant copy of <prgn/cat/.  If the service
193 uses the descriptor it will get <prgn/SIGPIPE/ (or <prgn/EPIPE/) for a
194 writing descriptor or end of file for a reading one; the descriptor
195 opened by or passed to the client will also be closed.
196 <p>
197
198 If <tt/nowait/ is specified then the client will not wait and the
199 connection will remain open after the client terminates.  Data may
200 continue to be passed between the inheritors of the relevant
201 descriptor on the service side and the corresponding file or
202 descriptor on the client side until either side closes their
203 descriptor.  This should not usually be specified for stderr (or
204 stdout if <tt/--signals stdout/ is used) since diagnostics from
205 the service side may arrive after the client has exited and be
206 confused with expected output.
207 <p>
208
209 The default is <tt/wait/ for writing file descriptors and <tt/close/
210 for reading ones.
211
212 <tag/<tt/-w<var/fd/=<var/action///
213 <tag/<tt/--fdwait<var/fd/=<var/action///
214 <item>
215 Sets the action on termination of the service for the specified file
216 descriptor; <var/action/ must be <tt/wait/, <tt/nowait/ or <tt/close/
217 as described above.  The file descriptor must be specified as open
218 when this option is encountered; this option is overridden by any
219 later <tt/--file/ or <tt/--fdwait/ option - even by a <tt/--file/
220 which does not specify an action on termination (in this case the
221 default will be used, as described above).
222
223 <tag/<tt/-D<var/name/=<var/value///
224 <tag/<tt/--defvar <var/name/=<var/value///
225 <item>
226 Set a user-defined variable <var/name/ to <var/value/.  These
227 user-defined variables are made available in the configuration
228 language as the parameters <tt/u-<var/name// and are passed to the
229 service in environment variables <tt/USERV_U_<var/name//.  <var/name/
230 may contain only alphanumerics and underscores, and must start with a
231 letter.  If several definitions are given for the same <var/name/ then
232 only the last is effective.
233
234 <tag/<tt/-t <var/seconds///
235 <tag/<tt/--timeout <var/seconds///
236 <item>
237 Time out the service if it takes longer than <var/seconds/ seconds (a
238 positive integer, in decimal).  Timeout will produce a diagnostic on
239 stderr and an exit status of 255.  If <var/seconds/ is zero then no
240 timeout will be implemented (this is the default).
241
242 <tag/<tt/-S/ <var/method//
243 <tag/<tt/--signals/ <var/method//
244 <item>
245 Affects the handling of the exit status when the service terminates
246 due to a signal.  (The client will always finish by calling <tt/exit/,
247 so that only numbers from 0 to 255 can be returned and not the full
248 range of numbers and signal indications which can be returned by the
249 <tt/wait/ family of system calls.)
250 <p>
251
252 The <var/method/ may be one of the following:
253 <taglist compact>
254 <tag/<var/status/
255 <item>
256 The client's exit status will be <var/status/.  This will not be
257 distinguishable from the service really having exited with code
258 <var/status/.  This method is the default, with a <var/status/ of 254.
259
260 <tag/<tt/number//
261 <tag/<tt/number-nocore//
262 <item>
263 The client's exit status will be the number of the signal which caused
264 the termination of the service.  If <tt/number/ is used rather than
265 <tt/number-nocore/ then 128 will be added if the service dumped core.
266 <tt/number/ is very like the exit code mangling done by the Bourne
267 shell.
268
269 <tag/<tt/highbit//
270 <item>The client's exit status will be the number of the signal with
271 128 added.  If the service exits normally with an exit code of greater
272 than 127 then 127 will be returned.
273
274 <tag/<tt/stdout//
275 <item>
276 The service's numeric wait status as two decimal numbers (high byte
277 first) and a textual description of its meaning will be printed to the
278 client's standard output.  It will be preceded by a newline and
279 followed by an extra newline, and the numbers are separated from each
280 other and from the textual description by single spaces.  The exit
281 status of the client will be zero, unless a system error occurs in
282 which case no exit status and description will be printed to stdout,
283 and an error message will be printed to stderr as usual.
284 </taglist>
285
286 <p>
287 Problems such as client usage errors, the service not being found or
288 permission being denied or failure of a system call are system errors.
289 An error message describing the problem will be printed on the
290 client's stderr, and the client's exit status will be 255.  If the
291 client dies due to a signal this should be treated as a serious system
292 error.
293
294 <tag/<tt/-H//
295 <tag/<tt/--hidecwd//
296 <item>
297 Prevents the calling process's current directory name from being
298 passed to the service; the null string will be passed instead.
299
300 <tag/<tt/-P//
301 <tag/<tt/--sigpipe//
302 <item>
303 If the service program is terminated due to a <prgn/SIGPIPE/ the exit
304 status of the client will be zero, even if it would have been
305 something else according to the exit status method specified.  This
306 option has no effect on the code and description printed if the exit
307 status method <tt/stdout/ is in use.
308
309 <tag/<tt/-h//
310 <tag/<tt/--help//
311 <tag/<tt/--copyright//
312 <item>
313 <tt/-h/ or <tt/--help/ prints the client's usage message;
314 <tt/--copyright/ prints the copyright and lack of warranty notice.
315
316 </taglist>
317
318 <sect>Security-overriding options
319 <p>
320
321 There are also some options which are available for debugging and to
322 allow the system administrator to override a user's policy.  These
323 options are available only if the client is called by root or if the
324 calling user is the same as the service user.
325
326 <taglist>
327
328 <tag/<tt/--override <var/configuration-data///
329 <tag/<tt/--override-file <var/filename///
330 <item>
331 Do not read the usual configuration files.  Instead, the client sends
332 <var/configuration-data/ (followed by a newline) or the contents of
333 <var/filename/ (which is opened in the context of the client) to the
334 daemon and the daemon uses that data instead.  The
335 <var/configuration-data/ must all be in one argument.  It will have a
336 single newline appended so that a single directive can easily be
337 given, but if more than one directive is required it will have to
338 contain one or more real newlines.
339
340 <tag/<tt/--spoof-user <var/user///
341 <item>
342 Pretend to the service that it is being called by <var/user/ (which
343 may be a username or a uid).  This will also affect the group and
344 supplementary groups supplied to the service; they will be the
345 standard group and supplementary groups for <var/user/.
346
347 </taglist>
348
349
350 <chapt id="envir">Execution environment of the service program
351 <p>
352
353 The daemon which is handling the service user side of things will read
354 configuration files to decide what to do.  If it decides to allow the
355 service to be provided it will fork a subprocess to execute the
356 service.
357 <p>
358
359 The service will have no controlling terminal, but it will be a
360 process group leader.
361 <p>
362
363 If the client is killed or times out or a file or descriptor being
364 read or written by the client process gets an error then the service
365 will be disconnected from the client.  The client will return an exit
366 status of 255 and some the service's pipes may be closed at the other
367 end.  The service will become a child of <prgn/init/.  The service may
368 well not notice the disconnection, though writing to a pipe after this
369 may produce a <prgn/SIGPIPE/ and the facility exists to have a
370 <prgn/SIGHUP/ sent to the service on disconnection.
371
372 <sect>File descriptors
373 <p>
374
375 The service program's standard filedescriptors, and possibly other
376 file descriptors, will be connected to pipes or to
377 <prgn>/dev/null</>.  The <prgn/userv/ client/daemon pair will arrange
378 that data is copied between the files or file descriptors specified to
379 to the client by the caller and these these pipes.
380 <p>
381
382 Pipes which may be written to will be closed if a write error occurs
383 on the corresponding client-side file or descriptor, which may result
384 in a <prgn/SIGPIPE/ in the service program; pipes open for reading
385 will get <prgn/EOF/ if the client-side file descriptor gets <prgn/EOF/
386 or an error.
387 <p>
388
389 If the service closes one of its reading file descriptors the writing
390 end of the corresponding pipe will generate a <prgn/SIGPIPE/ when
391 attempts are made by the client/daemon pair to write to it.  This will
392 not be considered an error; rather, the relevant pipe will be
393 discarded and the corresponding file or file descriptor held by the
394 client will be closed.
395 <p>
396
397 Likewise, if one of the file descriptors held by the client for
398 writing by the service is a pipe whose other end is closed by the
399 caller then the client/daemon pair will see an error when trying to
400 copy data provided by the service.  This too will not be considered an
401 error; rather, the pipe correspondong to that descriptor will be
402 closed and any further writes will cause the service to get a
403 <prgn/SIGPIPE/.
404 <p>
405
406 Note that not all write errors or broken pipes on file descriptors may
407 be visible to the service, since buffered data may be discarded by the
408 operating system and there will be a finite interval between the error
409 happening and the service being disconnected from the client or the
410 next write causing a <prgn/SIGPIPE/.
411 <p>
412
413 Read errors on file descriptors (and disconnection) will only be
414 visible to the service and distinguishable from normal end of file if
415 <tt/disconnect-hup/ is in effect.
416 <p>
417
418 Read and write errors (other than broken pipes, as described above)
419 will always be visible to the caller; they are system errors, and will
420 therefore cause the client to print an error message to stderr and
421 return with an exit status of 255.
422 <p>
423
424 If the main service program process exits while it still has running
425 children any file descriptors held by those children can remain open,
426 depending on the use of <tt/wait/, <tt/nowait/ or <tt/close/ for the
427 relevant file descriptor in the client's arguments.  By default
428 writing filedescriptors remain open and the client will wait for them
429 to be closed at the service end, and reading file descriptors are
430 closed immediately.  These leftover child processes will not get a any
431 <tt/SIGHUP/ even if a read or write error occurs or the client
432 disconnects before then.
433
434 <sect>Environment
435 <p>
436
437 The service will have some information in environment variables:
438 <taglist compact>
439 <tag/<tt/USERV_USER//
440 <item>
441 The login name of the calling user.  If the <prgn/LOGNAME/ variable is
442 set (or, if that is unset, if the <prgn/USER/ variable is set) in the
443 environment passed to the client by the caller then the password entry
444 for that login name will be looked up; if that password entry's uid is
445 the same as that of the calling process then that login name will be
446 used, otherwise (or if neither <prgn/LOGNAME/ nor <prgn/USER/ is set)
447 the calling process's uid will be looked up to determine their login
448 name (and if this lookup fails then the service will not be invoked).
449
450 <tag/<tt/USERV_UID//
451 <item>
452 The uid of the calling process.
453
454 <tag/<tt/USERV_GID//
455 <item>
456 The gid and supplementary group list of the calling process: first the
457 group in gid and then those in the supplementary group list, in
458 decimal, separated by spaces.
459
460 <tag/<tt/USERV_GROUP//
461 <item>
462 The group names of the calling process, listed in the same way as the
463 ids are in <tt/USERV_GID/.  If no name can be found for any of the
464 calling process's group(s) then the service will not be invoked.
465
466 <tag/<tt/USERV_CWD//
467 <item>
468 The client's current working directory name (this directory may not be
469 accessible to the service).  If it could not be determined or the
470 <tt/--hidecwd/ flag was used then this variable will be set to an
471 empty string (this is not considered an error).
472
473 <tag/<tt/USERV_SERVICE//
474 <item>
475 The service name requested by the caller.
476
477 <tag/<tt/USERV_U_<var/name///
478 <item>
479 The value supplied to the client by the caller using -D<var/name/.
480
481 </taglist>
482
483 <prgn/HOME/, <prgn/PATH/, <prgn/SHELL/, <prgn/LOGNAME/ and <prgn/USER/
484 will be set appropriately (according to the details of the service
485 user).
486
487
488 <chapt id="config">Service-side configuration
489 <p>
490
491 Which services may be run by whom and under what conditions is
492 controlled by configuration files.
493 <p>
494
495 The daemon will read these files in order.  Certain directives in the
496 files modify the daemon's execution settings for invoking the service,
497 for example allowing certain file descriptors to be specified by the
498 client or specifying which program to execute to provide the service.
499 <p>
500
501 The <em/last/ instance of each such setting will take effect.  The
502 directives which specify which program to execute will not stop the
503 configuration file from being read; they will be remembered and will
504 only take effect if they are not overridden by a later directive.
505 <p>
506
507 The daemon will first read <tt>/etc/userv/system.default</>.  Then, by
508 default (this behaviour may be modified), it will read a per-user file
509 <tt>~/.userv/rc</>, if it exists and the service user's shell is in
510 <tt>/etc/shells</>.  Finally it will read
511 <tt>/etc/userv/system.override</>.
512 <p>
513
514 When it has read all of these files it will act according to the
515 currently values of of the execution settings.
516
517 <sect>Configuration file syntax
518 <p>
519
520 The configuration file is a series of directives, usually one per
521 line.  The portion of a line following a hash character <tt/#/ is
522 taken as a comment and ignored.  Each directive consists of a series
523 of tokens separated by linear whitespace (spaces and tabs); tokens may
524 be words consisting of non-space characters, or, where a string is
525 required, a string in double quotes.  Double-quoted strings may
526 contain the following backslash escapes:
527
528 <taglist compact>
529 <tag/<tt/\n//<item>newline
530 <tag/<tt/\t//<item>tab
531 <tag/<tt/\r//<item>carriage return
532 <tag/<tt/\<var/OOO///<item>character whose octal code is <var/OOO/
533 <tag/<tt/\x<var/XX///<item>character whose hex code is <var/XX/
534 <tag/<tt/\<var/punctuation///<item>literal punctuation character (eg <tt/\\/, <tt/\"/)
535 <tag/<tt/\<var/newline// (ie, backslash at end of line)/
536 <item>string continues on next line
537 </taglist>
538 <p>
539
540 Relative pathnames in directives are relative to the service program's
541 current directory (usually the service user's home directory).
542 Pathnames starting with the two characters <tt>~/</> are taken to be
543 relative to the service user's home directory.
544
545 <sect>Configuration file directives
546 <p>
547
548 <sect1>Immediate directives
549 <p>
550
551 The following directives take effect immediately:
552
553 <taglist>
554 <tag/<tt/cd <var/pathname///
555 <item>
556 Change directory in the service program.  <prgn/cd/ is cumulative.  It
557 is an error if the directory cannot be changed to.
558 <p>
559
560 <prgn/cd/ should not be used between <prgn/execute-from-directory/ and
561 the invocation of the service program, as the test for the
562 availability of the service program would be done with the old current
563 directory and the actual execution with the new (probably causing an
564 error).
565
566 <tag/<tt/eof//
567 <item>
568 Stop reading the configuration file in question, as if end of file had
569 been reached.  Any control constructs (<tt/if/, <tt/catch-quit/ or
570 <tt/errors-push/) which were started in that file will be considered
571 finished.  Parsing will continue in the file which caused the file
572 containing the <tt/eof/ to be read.
573
574 <tag/<tt/quit//
575 <item>
576 Stop reading configuration files and act immediately on the current
577 settings.  The behaviour of <tt/quit/ is subject to the
578 <tt/catch-quit/ control construct.
579
580 <tag/<tt/include <var/filename///
581 <tag/<tt/include-ifexist <var/filename///
582 <item>
583 Read the configuration file <var/filename/, and then return to this
584 file and continue parsing it with the next directive.  It is an error
585 if the file cannot be opened and read, unless <tt/include-ifexist/ is
586 used and the file does not exist, in which case the directive is
587 silently ignored.
588
589 <tag/<tt/include-lookup <var/parameter/ <var/directory///
590 <tag/<tt/include-lookup-all <var/parameter/ <var/directory///
591 <item>
592 Read the configuration file in <var/directory/ whose name is the value
593 of <var/parameter/ (see the description of <tt/if/, above).  If
594 <var/parameter/ has several values they will be tried in order; with
595 <tt/include-lookup/ this search will stop when one is found, but with
596 <tt/include-lookup-all/ the search will continue and any files
597 appropriate to other values will be read too.
598 <p>
599
600 If none of the parameter's values had a corresponding file then the
601 file <tt/:default/ will be read, if it exists.  If <var/parameter/'s
602 list of values was empty then the file <tt/:none/ will be tried first
603 and read if it exists, otherwise <tt/:default/ will be tried.
604 <p>
605
606 It is not an error for any of the files (including <tt/:default/) not
607 to exist, but it is an error if a file exists and cannot be read or if
608 the directory cannot be accessed.
609
610 <p>
611 A translation will be applied to values before they are used to
612 construct a filename, so that the lookup cannot access dotfiles or
613 files in other directories: values starting with full stops will have
614 a colon prepended (making <tt/:./), colons will be doubled, and each
615 slash will be replaced with a colon followed by a hyphen <tt>:-</>.  A
616 parameter value which is the empty string will be replaced with
617 <tt/:empty/ (note that this is different from a parameter not having
618 any values).
619
620 <tag/<tt/include-directory <var/directory///
621 <item>
622 Read configuration from all files in directory <var/directory/ which
623 are plain files whose names consist only of alphanumerics and hyphens
624 and start with an alphanumeric.  They will be read in lexical order.
625 It is an error for the directory not to exist or for it or any of the
626 files found not to be read successfully, or for anything with an
627 appropriate name not to be a plain file or a symbolic link to a plain
628 file.
629
630 <tag/<tt/error <var/text ...///
631 <item>
632 Causes an error whose message includes the descriptive string
633 <var/text/.  <var/text/ may consist of several tokens with intervening
634 whitespace.  The whitespace will be included in the message as found
635 in the configuration file: all the characters until the end of the
636 line will be included verbatim, unless they are part of a
637 double-quoted string, in which case the usual meaning of the string
638 (i.e., after backslash escape processing) will be used.  Comments and
639 linear whitespace at the end of the line (or just before the comment)
640 will still be ignored.
641
642 <tag/<tt/message <var/text ...///
643 <item>
644 Causes a message including the descriptive string <var/text/ to be
645 delivered as if it were an error message, but does not actually cause
646 an error.
647 </taglist>
648
649 <sect1>Directives with delayed effect
650 <p>
651
652 The following directives have no immediate effect, but are remembered
653 and have an effect on later processing of the configuration files.
654
655 <taglist>
656 <tag/<tt/user-rcfile <var/filename///
657 <item>
658 Specifies that the file <var/filename/ should be read instead of the
659 user's <tt>~/.userv/rc</>.  This does <em/not/ happen immediately;
660 instead, the setting is remembered and used after the
661 <tt/system.default/ configuration file has been read.  This directive
662 has no effect in a user's configuration file or in the
663 <tt/system.override/ file, as the user's configuration file has
664 already been found and read by then and will not be re-read.
665
666 <tag/<tt/errors-to-stderr//
667 <item>
668 Causes error messages to be delivered to the client's stderr.
669
670 <tag/<tt/errors-to-file/ <var/filename//
671 <item>
672 Error messages will be written to <var/filename/, which will be opened
673 in the context of and with the privileges of the service user.
674
675 <tag/<tt/errors-to-syslog/ [<var/facility/ [<var/level/]]/
676 <item>
677 Error messages will be delivered using <prgn/syslog/.  The default
678 <var/facility/ is <tt/daemon/; the default <var/level/ is <tt/error/.
679 </taglist>
680
681 <sect1>Control structure directives
682 <p>
683
684 The following directives are used to create control structures.  If
685 the end of the file is encountered before the end of any control
686 structure which was started inside it then that control structure is
687 considered finished.  This is not an error.
688
689 <taglist>
690 <tag/<tt/if <var/condition///
691 <tag/<tt/elif <var/condition///
692 <tag/<tt/else//
693 <tag/<tt/fi//
694 <item>
695 Lines following <tt/if/ are interpreted only if the condition is true.
696 Many conditions are properties of parameter values.  Most parameters
697 have a single string as a value; however, some may yield zero or
698 several strings, in which case the condition is true if it is true of
699 any of the strings individually.  Parameters are described below.
700 <p>
701
702 The conditions are:
703
704 <taglist compact>
705 <tag/<tt/glob <var/parameter/ <var/glob-pattern/ ...//
706 <item>
707 The value of the parameter whose name is given matches one of the glob
708 patterns (anchored at both ends; backslashes can be used to escape
709 metacharacters).
710
711 <tag/<tt/range <var/parameter/ <var/min/ <var/max///
712 <item>
713 The value of the parameter is a nonnegative integer and lies within
714 the range specified.  <var/min/ or <var/max/ may be <tt/$/ to indicate
715 no lower or upper limit, respectively.
716
717 <tag/<tt/grep <var/parameter/ <var/filename///
718 <item>
719 The <var/filename/ refers to a file one of whose lines is the value of
720 the parameter (leading or trailing whitespace on each line and empty
721 lines in the file are ignored).  It is an error for the file not to be
722 opened and read.
723
724 <tag/<tt/! <var/condition///
725 <item>
726 The <var/condition/ is <em/not/ true.
727
728 <tag/Conjunctions: <tt/&amp;/ and <tt/|//
729 <item>
730 <example>
731 ( <var/condition/
732 &amp; <var/condition/
733 &amp; <var/condition/
734 ...
735 )
736 </example>
737 is true if all the listed conditions are true; where <tt/|/ is used it
738 is true if any of them is true.  Newlines must be used to separate one
739 condition from the next, as shown, and the parentheses are mandatory.
740 These conjunctions do not do lazy evaluation.
741 </taglist>
742 <p>
743
744 The parameters are:
745
746 <taglist compact>
747 <tag/<tt/service//
748 <item>
749 The service name specified when the client was called.
750
751 <tag/<tt/calling-user//
752 <item>
753 Two strings: the login name of the calling user (determined as for
754 <tt/USERV_USER/, above) and the calling uid (represented in decimal).
755
756 <tag/<tt/calling-group//
757 <item>
758 Several strings: the primary and supplementary group names and gids
759 (in decimal) of the calling process.  All the group names come first,
760 and then the gids.  If the first supplementary group is the same as
761 the primary group then it is elided.
762
763 <tag/<tt/calling-user-shell//
764 <item>
765 The calling user's shell, as listed in the password entry for the
766 calling login name (as determined for <tt/USERV_USER/, above).
767
768 <tag/<tt/service-user//
769 <item>
770 Two strings: the name of the service user (as specified to the client)
771 and their uid (represented in decimal).
772
773 <tag/<tt/service-group//
774 <item>
775 Several strings: the primary and supplementary group names and gids
776 (in decimal) of the service user.
777
778 <tag/<tt/service-user-shell//
779 <item>
780 The service user's shell, as listed in their password entry.
781
782 <tag/<tt/u-<var/name///
783 <item>
784 The value of the user-defined variable <var/name/ passed by the caller
785 using the <tt/-D/ command-line option to the client.  If the variable
786 was not defined then this parameter is an empty list of strings; in
787 this case any condition which tests it will be false, and
788 <tt/include-lookup/ on it will read the <tt/:none/ file, or
789 <tt/:default/ if <tt/:none/ is not found.
790
791 </taglist>
792
793 <tag/<tt/errors-push/ <var/filename//
794 <tag/<tt/srorre//
795 <item>
796 Stacks the error handling behaviour currently in effect.  Any changes
797 to error handling will take effect only between <tt/errors-push/ and
798 <tt/srorre/.
799
800 <tag/<tt/catch-quit//
801 <tag/<tt/hctac//
802 <item>
803 Any use of <tt/quit/ inside <tt/catch-quit/ will merely cause the
804 parsing to continue at <tt/hctac/ instead.  Any control constructs
805 started since the <tt/catch-quit/ will be considered finished if a
806 <tt/quit/ is found.
807 <p>
808
809 If an error occurs inside <tt/catch-quit/ the execution settings will
810 be reset (as if by the <tt/reset/ directive) and parsing will likewise
811 continue at <tt/hctac/.
812 <p>
813
814 If a serious lexical or syntax error is detected in the same
815 configuration file as the <tt/catch-quit/, while looking for the
816 <tt/hctac/, that error will not be caught.
817
818 </taglist>
819
820 <sect1>Directives for changing execution settings
821 <p>
822
823 The following directives modify the execution settings; the server
824 will remember the fact that the directive was encountered and act on
825 it only after all the configuration has been parsed.  The <em/last/
826 directive which modifies any particuar setting will take effect.
827
828 <taglist>
829 <tag/<tt/reject//
830 <item>
831 Reject the request.  <tt/execute/, <tt/execute-from-directory/ and
832 <tt/execute-from-path/ will change this setting.
833
834 <tag/<tt/execute <var/pathname/ [<var/argument/ ...]//
835 <item>
836 Execute the program <var/pathname/, with the arguments as specified,
837 followed by any arguments given to the client if <tt/no-suppress-args/
838 is in effect.  It is an error for the execution to fail when it is
839 attempted (after all the configuration has been parsed).
840
841 <tag/<tt/execute-from-directory <var/pathname/ [<var/argument/ ...]//
842 <item>
843 Take all the characters after the last slash of the service name
844 specified when the client was called, and execute that program in the
845 directory named by <var/pathname/ as if it had been specified for
846 <var/execute/.  The part of the service name used may contain only
847 alphanumerics and hyphens and must start with an alphanumeric (and it
848 must be non-empty), otherwise it is an error.
849 <p>
850
851 This directive is ignored if the relevant program does not exist in
852 the directory specified; in this case the program to execute is left
853 at its previous setting (or unset, if it was not set before).
854 <p>
855
856 It is an error for the test for the existence of the program to fail
857 other than with a `no such file or directory' indication.  It is also
858 an error for the execution to fail if and when it is attempted (after
859 all the configuration has been parsed).
860
861 <tag/<tt/execute-from-path//
862 <item>
863 <var/service/ is interpreted as a program on the default <prgn/PATH/
864 (or as a pathname of an executable, if it contains a <tt>/</>).  This
865 directive is <em/very dangerous/, and is only provided to make the
866 <tt/--override/ options effective.  It should not normally be used.
867 It is an error for the execution to fail when it is attempted (after
868 all the configuration has been parsed).
869
870 <tag/<tt/set-environment//
871 <tag/<tt/no-set-environment//
872 <item>
873 Runs <tt>/etc/environment</> to set the service user's environment.
874 This adds the overhead of invoking a shell, but doesn't cause any
875 shell (de)mangling of the service's arguments.  This is achieved by
876 invoking
877 <example>
878 .../program arg arg arg ...
879 </example>
880 as
881 <example>
882 /bin/sh -c '. /etc/environment; exec "$@"' - .../program arg arg arg ...
883 </example>
884 <tt/no-set-environment/ cancels the effect of <tt/set-environment/.
885
886 <tag/<tt/no-suppress-args//
887 <tag/<tt/suppress-args//
888 <item>
889 Include any arguments given to the client as arguments to the program
890 invoked as a result of an <tt/execute/ or <tt/execute-from-directory/
891 directive.  <tt/suppress-args/ undoes the effect of
892 <tt/no-suppress-args/.
893
894 <tag/<tt/require-fd <var/fd-range/ read|write//
895 <item>
896 Insist that the filedescriptor(s) be opened for reading resp. writing.
897 It is an error if any descriptor marked as required when the service
898 is about to be invoked (after the configuration has been parsed) was
899 not specified when the client was invoked.  Each file descriptor has a
900 separate setting, and the last one of <tt/require-fd/, <tt/allow-fd/,
901 <tt/ignore-fd/, <tt/null-fd/ or <tt/reject-fd/ which affected a
902 particular file descriptor will take effect.
903 <p>
904
905 <var/fd-range/ may be a single number, two numbers separated by a
906 hyphen, or one number followed by a hyphen (indicating all descriptors
907 from that number onwards).  It may also be one of the words
908 <tt/stdin/, <tt/stdout/ or <tt/stderr/.  Open-ended file descriptor
909 rangers are allowed only with <tt/reject-fd/ and <tt/ignore-fd/, as
910 otherwise the service program would find itself with a very large
911 number of file descriptors open.
912 <p>
913
914 When the configuration has been parsed, and before the service is
915 about to be executed, stderr (fd 2) must be required or allowed
916 (<tt/require-fd/ or <tt/allow-fd/) for writing; this is so that the
917 error message printed by the server's child process if it cannot
918 <prgn/exec/ the service program is not lost.
919
920 <tag/<tt/allow-fd <var/fd-range/ [read|write]//
921 <item>
922 Allow the descriptor(s) to be opened for reading resp. writing, or
923 either if neither <tt/read/ nor <tt/write/ is specified.  If a
924 particular descriptor not specified by the client then it will be open
925 onto <tt>/dev/null</> (for reading, writing, or both, depending on
926 whether <tt/read/, <tt/write/ or neither was specified).
927
928 <tag/<tt/null-fd <var/fd-range/ [read|write]//
929 <item>
930 Specify that the descriptor(s) be opened onto <prgn>/dev/null</> for
931 reading resp. writing, or both if neither <tt/read/ nor <tt/write/
932 is specified.  Any specification of these file descriptors by the
933 client will be silently ignored; the client will see its ends of the
934 descriptors being closed immediately.
935
936 <tag/<tt/reject-fd <var/fd-range///
937 <item>
938 Do not allow the descriptor(s) to be specified by the client.  It is
939 an error if any descriptor(s) marked for rejection are specified when
940 the service is about to be invoked (after the configuration has been
941 parsed).
942
943 <tag/<tt/ignore-fd <var/fd-range///
944 <item>
945 Silently ignore any specification by the client of those
946 descriptor(s).  The pipes corresponding to these descriptors will be
947 closed just before the service is invoked.
948
949 <tag/<tt/disconnect-hup//
950 <tag/<tt/no-disconnect-hup//
951 <item>
952 Causes the service's process group to get a <prgn/SIGHUP/ if the
953 client disconnects before the main service process terminates.
954 <tt/no-disconnect-hup/ cancels <tt/disconnect-hup/.
955 <p>
956
957 If one of the reading descriptors specified when the client is called
958 gets a read error, or if the service is disconnected for some other
959 reason, then the <prgn/SIGHUP/ will be delivered <em/before/ the
960 writing end(s) of the service's reading pipe(s) are closed, so that
961 the client can distinguish disconnection from reading EOF on a pipe.
962
963 <tag/<tt/reset//
964 <item>
965 Resets the execution settings to the default.  This is equivalent to:
966 <example>
967 cd ~/
968 reject
969 no-set-environment
970 suppress-args
971 allow-fd 0 read
972 allow-fd 1-2 write
973 reject-fd 3-
974 disconnect-hup
975 </example>
976
977 </taglist>
978
979 If no <tt/execute/, <tt/execute-from-path/ or
980 <tt/execute-from-directory/ is interpreted before all the files are
981 read then the request is rejected.
982
983
984 <sect>Errors in the configuration file
985 <p>
986
987 If a syntax error or other problem occurs when processing a
988 configuration file then a diagnostic will be issued, to wherever the
989 error messages are currently being sent (see the <tt/errors-/ family
990 of directives, above).
991 <p>
992
993 The error will cause processing of the configuration files to cease at
994 that point, unless the error was inside a <tt/catch-quit/ construct.
995 In this case the settings controlling the program's execution will be
996 reset to the defaults as if a <tt/reset/ directive had been issued,
997 and parsing continues after <tt/hctac/.
998
999
1000 <sect>Defaults
1001 <p>
1002
1003 The default configuration processing is as if the daemon were parsing
1004 an overall configuration file whose contents were as follows:
1005
1006 <example>
1007 reset
1008 user-rcfile ~/.userv/rc
1009 errors-to-stderr
1010 include /etc/userv/system.default
1011 if grep service-user-shell /etc/shells
1012    errors-push
1013      catch-quit
1014        include-ifexist <var/file specified by most recent user-rcfile directive/
1015      hctac
1016    srorre
1017 fi
1018 include /etc/userv/system.override
1019 quit
1020 </example>
1021 <p>
1022
1023 If one of the <tt/override/ options to the client is used then it will
1024 be as if the daemon were parsing an overall configuration as follows:
1025
1026 <example>
1027 reset
1028 errors-to-stderr
1029 include <var/file containing configuration data sent by client/
1030 quit
1031 </example>
1032
1033
1034 <chapt id="ipass">Information passed through the client/daemon combination
1035 <p>
1036
1037 The information described below is the only information which passes
1038 between the caller and the service.
1039
1040 <list>
1041 <item>
1042 The service name supplied by the caller is available in the
1043 configuration language for deciding whether and which service program
1044 to invoke, in the <tt/service/ parameter, and is used by the
1045 <tt/execute-from-directory/ and <tt/execute-from-path/ configuration
1046 directives.  It is usually used to select which service program to
1047 invoke.  It is also passed to the service program in the
1048 <tt/USERV_SERVICE/ environment variable.
1049
1050 <item>
1051 File descriptors specified by the client and allowed according to the
1052 configuration language will be connected.  Each file descriptor is
1053 opened for reading or writing.  Communication is via pipes, one end of
1054 each pipe being open on the appropriate file descriptor in the service
1055 program (when it is invoked) and the other end being held by the
1056 client process, which will read and write files it opens on behalf of
1057 its caller or file descriptors it is passed by its caller.
1058 <p>
1059
1060 Data may be passed into the service through reading pipes and out of
1061 it through writing pipes.  These pipes can remain open only until the
1062 service and client have terminated, or can be made to stay open after
1063 the client has terminated and (if the service program forks) the main
1064 service process has exited; the behaviour is controlled by options
1065 passed to the client by its caller.
1066 <p>
1067
1068 The caller can arrange that a writing pipe be connected to a pipe or
1069 similar object and cause attempts to write to that descriptor by the
1070 service to generate a <prgn/SIGPIPE/ (or <prgn/EPIPE/ if
1071 <prgn/SIGPIPE/ is caught or ignored) in the service.
1072 <p>
1073
1074 Likewise, the service can close filedescriptors specified for reading,
1075 which will cause the corresponding filedescriptors passed by the
1076 caller to be closed, so that if these are pipes processes which write
1077 to them will receive <prgn/SIGPIPE/ or <prgn/EPIPE/.
1078
1079 <item>
1080 If <tt/no-suppress-args/ is set then arguments passed to the client by
1081 its caller will be passed on, verbatim, to the service.
1082
1083 <item>
1084 Fatal signals and system call failures experienced by the client will
1085 result in the disconnection of the service from the client and
1086 possibly some of the communication file descriptors described above;
1087 if <tt/disconnect-hup/ is set they will also cause the service to get
1088 a <prgn/SIGHUP/.
1089
1090 <item>
1091 The value of the <tt/LOGNAME/ (or <tt/USER/) environment variable as
1092 passed to the client will be used as the login name of the calling
1093 user if the uid of the calling process matches the uid corresponding
1094 to that login name.  Otherwise the calling uid's password entry will
1095 be used to determine the calling user's login name.
1096 <p>
1097
1098 This login name and the calling uid are available in the configuration
1099 language in the <tt/calling-user/ parameter and are passed to the
1100 service program in environment variables <tt/USERV_USER/ and
1101 <tt/USERV_UID/.
1102 <p>
1103
1104 The shell corresponding to that login name (according to the password
1105 entry) is available as in the configuration language's
1106 <tt/calling-user-shell/ parameter.
1107 <p>
1108
1109 If no relevant password entry can be found then no service will be
1110 invoked.
1111
1112 <item>
1113 The numeric values and textual names for calling gid and supplementary
1114 group list are available in the configuration language in the
1115 <tt/calling-group/ parameter and are passed to the service in
1116 environment variables.
1117 <p>
1118
1119 If no name can be found for a numeric group to which the calling
1120 process belongs then no service will be invoked.
1121
1122 <item>
1123 The name of the current working directory in which the client was
1124 invoked is passed, if available and not hidden using <tt/--hidecwd/,
1125 to the service program in the <tt/USERV_CWD/ variable.  This grants no
1126 special access to that directory unless it is a subdirectory of a
1127 directory which is executable (searchable) but not readable by the
1128 service user.
1129
1130 <item>
1131 Settings specified by the caller using the
1132 <tt/-D<var/name/=<var/value// option to the client are available in
1133 the configuration language as the corresponding <tt/u-<var/name//
1134 parameters and are passed to the service program in environment
1135 variables <tt/USERV_U_<var/name//.
1136
1137 <item>
1138 If the calling user is root or the same as the service user then
1139 options may be given to the client which bypass the usual security
1140 features; in this case other information may pass between the caller
1141 and the service.
1142
1143 </list>
1144
1145 <chapt id="notes">Applications and notes on use
1146 <p>
1147
1148 <sect>Reducing the number of absolutely privileged subsystems
1149 <p>
1150
1151 Currently most Unix systems have many components which need to run as
1152 root, even though most of their activity does not strictly require
1153 it.  This gives rise to a large and complex body of code which must be
1154 trusted with the security of the system.
1155 <p>
1156
1157 Using <prgn/userv/ many of these subsystems no longer need any unusual
1158 privilege.
1159 <p>
1160
1161 <prgn/cron/ and <prgn/at/, <prgn/lpr/ and the system's mail transfer
1162 agent (<prgn/sendmail/, <prgn/smail/, <prgn/exim/ or the like) all
1163 fall into this category.
1164
1165 <sect>Do not give away excessive privilege to <prgn/userv/-using facilities
1166 <p>
1167
1168 There is a danger that people reimplementing the facilities I mention
1169 above using <prgn/userv/ will discard much of the security benefit by
1170 using a naive implementation technique.  This will become clearer with
1171 an example:
1172 <p>
1173
1174 Consider the <prgn/lpr/ program.  In current systems this needs to
1175 have an absolutely privileged component in order to support delayed
1176 printing without copying: when the user queues a file to be printed
1177 the filename is stored in the print queue, rather than a copy of it,
1178 and the printer daemon accesses the file directly when it is ready to
1179 print the job.  In order that the user can print files which are not
1180 world-readable the daemon is given root privilege so that it can open
1181 the file in the context of the user, rather than its own.
1182 <p>
1183
1184 A simple-minded approach to converting this scheme to use <prgn/userv/
1185 might involve giving the printer daemon (the <tt/lp/ user) the ability
1186 to read the file by allowing them to run <prgn/cat/ (or a
1187 special-purpose file-reading program) as any user.  The <prgn/lpr/
1188 program would use a <prgn/userv/ service to store the filename in the
1189 printer daemon's queues, and the daemon would read the file later when
1190 it felt like it.
1191 <p>
1192
1193 However, this would allow the printer daemon to read any file on the
1194 system, whether or not someone had asked for it to be printed.  Since
1195 many files will contain passwords and other security-critical
1196 information this is nearly as bad as giving the daemon root access in
1197 the first place.  Any security holes in the print server which allow a
1198 user to execute commands as the <tt/lp/ user will give the user the
1199 ability to read any file on the system.
1200 <p>
1201
1202 Instead, it is necessary to keep a record of which files the daemon
1203 has been asked to print <em/outside/ the control of the print daemon.
1204 This record could be kept by a new root-privileged component, but this
1205 is not necessary: the record of which files a user has asked to be
1206 printed can be kept under the control of the user in question.  The
1207 submission program <prgn/lpr/ will make a record in an area under the
1208 user's control before communicating with the print server, and the
1209 print server would be given the ability to run a special file-reading
1210 program which would only allow files to be read which were listed in
1211 the user's file of things they'd asked to print.
1212 <p>
1213
1214 Now security holes in most of the printing system do not critically
1215 affect the security of the entire system: they only allow the attacker
1216 to read and interfere with print jobs.  Bugs in the programs run by the
1217 print server to read users' files (and to remove entries from the list
1218 of files when it has done with them) will still be serious, but this
1219 program can be quite simple.
1220 <p>
1221
1222 Similar considerations apply to many <prgn/userv/-based versions of
1223 facilities which currently run as root.
1224 <p>
1225
1226 It is debatable whether the user-controlled state should be kept in
1227 the user's filespace (in dotfiles, say) or kept in a separate area set
1228 aside for the purpose; however, using the user's home directory (and
1229 probably creating a separate subdirectory of it as a dotfile to
1230 contain many subsystems' state) has fewer implications for the rest of
1231 the system and makes it entirely clear where the security boundaries
1232 lie.
1233
1234 <sect><prgn/userv/ is not a replacement for <prgn/really/ and <prgn/sudo/
1235 <p>
1236
1237 <prgn/userv/ is not intended as a general-purpose system
1238 administration tool with which system administrators can execute
1239 privileged programs when they need to.  It is unsuitable for this
1240 purpose precisely because it enforces a strong separation between the
1241 calling and the called program, which is undesirable in this context.
1242 <p>
1243
1244 Its facilities for restricting activities to running certain programs
1245 may at first glance seem to provide similar functionality to
1246 <prgn/sudo/<footnote><prgn/sudo/ is a program which allows users to
1247 execute certain programs as root, according to configuration files
1248 specified by the system administrator.</footnote>.  However, the
1249 separation mentioned above is a problem here too, particular for
1250 interaction - it can be hard for a <prgn/userv/ service program to
1251 interact with its real caller or the user in question.
1252
1253 <sect>Don't give access to general-purpose utilities
1254 <p>
1255
1256 Do not specify general purpose programs like <prgn/mv/ or <prgn/cat/
1257 in <tt/execute-/ directives without careful thought about their
1258 arguments, and certainly not if <tt/no-suppress-args/ is specified.
1259 If you do so it will give the caller much more privilige than you
1260 probably intend.
1261 <p>
1262
1263 It is a shame that I have to say this here, but inexperienced
1264 administrators have made similar mistakes with programs like
1265 <prgn/sudo/.
1266
1267 </book>