mirror of
https://github.com/bstansell/conserver.git
synced 2025-06-24 17:55:08 +00:00
Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
5c430d220b | |||
8cd506c093 |
26
CHANGES
26
CHANGES
@ -1,6 +1,30 @@
|
||||
CHANGES
|
||||
=======
|
||||
|
||||
version 8.1.5 (May 7, 2004):
|
||||
- changed remaining O_NDELAY flags to O_NONBLOCK
|
||||
- added PROTOCOLS file to describe the client/server protocol
|
||||
- added '#include' capability to conserver.cf file
|
||||
- added '@group' syntax to conserver.cf file to support use of
|
||||
system groups
|
||||
- added -U client option to allow client to ask for encryption
|
||||
but fall back to non-encrypted connections otherwise -
|
||||
suggested by Mike Hendon <mike.hendon@uk.nomura.com>
|
||||
- fixed bug where socket not properly deleted on exit - reported
|
||||
by William P LePera <lepera@us.ibm.com>
|
||||
- added 'initdelay' option for throttling startup of consoles -
|
||||
suggested by Jay McCanta <mccantaj@amgen.com>
|
||||
|
||||
version 8.1.4 (Apr 13, 2004):
|
||||
- fixed macro use in manpages to hopefully be more compatible
|
||||
- removed extra newline of --MARK-- range output
|
||||
- fixed bug where server -b option wasn't working - reported by
|
||||
Nathan R. Hruby <nhruby@uga.edu>
|
||||
- fixed client segfault when using -R, -t, -d, and -b options
|
||||
- added a --with-uds configure option to have all client/server
|
||||
communication happen via unix domain sockets - suggested by
|
||||
William P LePera <lepera@us.ibm.com>
|
||||
|
||||
version 8.1.3 (Mar 22, 2004):
|
||||
- fixed small memory and file descriptor leak in client when
|
||||
using '^Ec;'
|
||||
@ -698,5 +722,5 @@ before version 6.05:
|
||||
and enhancements of various types were applied.
|
||||
|
||||
#
|
||||
# $Id: CHANGES,v 1.162 2004/03/23 00:55:04 bryan Exp $
|
||||
# $Id: CHANGES,v 1.174 2004/05/07 16:04:58 bryan Exp $
|
||||
#
|
||||
|
14
INSTALL
14
INSTALL
@ -165,6 +165,9 @@ Detailed Instructions
|
||||
--with-maxmemb=MAXMEMB Specify maximum consoles per process [16]
|
||||
--with-timeout=TIMEOUT Specify connect() timeout in seconds [10]
|
||||
--with-trustrevdns Trust reverse DNS information
|
||||
--with-extmsgs Produce extended messages
|
||||
--with-uds[=DIR] Use Unix domain sockets for client/server
|
||||
communication [/tmp/conserver]
|
||||
--with-libwrap[=PATH] Compile in libwrap (tcp_wrappers) support
|
||||
--with-openssl[=PATH] Compile in OpenSSL support
|
||||
--with-dmalloc[=PATH] Compile in dmalloc support
|
||||
@ -182,10 +185,11 @@ Detailed Instructions
|
||||
A couple of notes. First, --with-libwrap will add tcp_wrappers
|
||||
lookups to all socket connections in the server. --with-openssl
|
||||
will add encryption between the client and server when you connect
|
||||
to a console. things such as 'console -q', 'console -w', etc. are
|
||||
still unencrypted, as well as connections from conserver to any
|
||||
terminal servers. --with-dmalloc should only be used to do memory
|
||||
allocation debugging and not used in production.
|
||||
to a console. --with-uds will cause the client and server to use
|
||||
unix domain sockets for their communication, eliminating the
|
||||
tcp communication they normally do (which means --with-master and
|
||||
--with-port are not used). --with-dmalloc should only be used to
|
||||
do memory allocation debugging and not used in production.
|
||||
|
||||
- Run './configure'. This will detect system specific
|
||||
information. The --prefix option will redirect where things are
|
||||
@ -274,5 +278,5 @@ Other Information And Gotchas
|
||||
|
||||
|
||||
#
|
||||
# $Id: INSTALL,v 1.37 2004/03/23 00:55:04 bryan Exp $
|
||||
# $Id: INSTALL,v 1.38 2004/04/13 18:11:58 bryan Exp $
|
||||
#
|
||||
|
290
PROTOCOL
Normal file
290
PROTOCOL
Normal file
@ -0,0 +1,290 @@
|
||||
Conserver Protocol
|
||||
==================
|
||||
|
||||
|
||||
What Is This?
|
||||
-------------
|
||||
|
||||
The following is an attempt to describe the client/server protocol used
|
||||
between the server (conserver) and the client (console). This document
|
||||
bases it's information on conserver version 8.1.4, as it's the release
|
||||
currently available. If there are changes to the client/server
|
||||
protocol, the INSTALL file should reference them and, ideally, this
|
||||
document will be updated.
|
||||
|
||||
The information is looked at from the point of the server, since it's
|
||||
the server that controls all information and triggers actions on the
|
||||
client (like a suspend). The client's perspective should be obvious
|
||||
from this information.
|
||||
|
||||
|
||||
SSL
|
||||
---
|
||||
|
||||
The client and server can negotiate an SSL connection. As far as the
|
||||
code is concerned, the SSL "layer" is transparent. Data is sent and
|
||||
received just as if it was unencrypted. Therefore, aside bringing up
|
||||
the SSL connection, the SSL bits are unimportant from a protocol
|
||||
standpoint. The client and server still send and receive the same
|
||||
information - it just happens to be encrypted to everyone else.
|
||||
|
||||
|
||||
"On-The-Wire" Data
|
||||
------------------
|
||||
|
||||
The low-level, "on-the-wire" data is encapsulated similar to the telnet
|
||||
protocol. All data is sent "as-is" with the exception of 0xFF. 0xFF is
|
||||
used as a "command character" and both the client and server expect to
|
||||
see a predefined option after it. The possible options are: 0xFF, 'E',
|
||||
'G', 'Z', and '.'.
|
||||
|
||||
The 0xFF option says to use the literal character 0xFF. So, if there is
|
||||
a 0xFF character in the data stream to be sent, the code will send two
|
||||
0xFF characters (it's similar to using '\\' in C strings to embed a
|
||||
'\').
|
||||
|
||||
The other options are used in various contexts, which will be described
|
||||
in detail below.
|
||||
|
||||
|
||||
Life As A Server
|
||||
----------------
|
||||
|
||||
There are three different interfaces presented to clients by the server.
|
||||
I'm going to name the three modes "master", "group", and "console". The
|
||||
first two are line-based, and the third is character-based.
|
||||
|
||||
To understand the differences, I must outline how conserver manages
|
||||
consoles. When conserver starts, it reads the configuration file,
|
||||
listens on the master socket, and, for each group of consoles it must
|
||||
manage (where the group size is set by -m), it forks off a copy of
|
||||
itself. Those child processes are what actually connect to the consoles
|
||||
and they each listen on a new socket for client connections. So, you
|
||||
end up with a parent process (that knows about all consoles) that
|
||||
manages the child processes (that know only about consoles it manages),
|
||||
and everyone is listening on an individual socket for connections from
|
||||
clients.
|
||||
|
||||
The parent process interacts with clients in "master" mode. That mode
|
||||
expects line-based commands and responds similarly. Because it's the
|
||||
master, it understands a certain set of commands that are different than
|
||||
in "group" mode.
|
||||
|
||||
The child processes interact with clients in "group" mode first, and
|
||||
negotiate a change to "console" mode when a client requests a connection
|
||||
to a specific console.
|
||||
|
||||
|
||||
"master" Mode
|
||||
-------------
|
||||
|
||||
When parent process gets a connection from a client, it either sends an
|
||||
"ok" string to signal it's ready or an error message (like "access from
|
||||
your host is refused") and the connection is dropped. At this point,
|
||||
there are a small number of commands recognized by the server, since
|
||||
most are restricted to "logged in" clients. Here's the list of
|
||||
available commands:
|
||||
|
||||
exit disconnect
|
||||
help this help message
|
||||
login log in
|
||||
ssl start ssl session
|
||||
|
||||
An "exit" is sent a "goodbye" response and the connection is dropped. A
|
||||
"help" is sent the list above. A "ssl" is sent an "ok" response and
|
||||
then the server expects the client to negotiate an ssl connection. A
|
||||
"login" requires one argument (the username) and is either sent an "ok",
|
||||
meaning the client is logged in, or a "passwd?" followed by the local
|
||||
hostname, asking for the user's password, which it expects next. If the
|
||||
client sends a valid password, an "ok" is sent, otherwise an error
|
||||
message and the connection is dropped.
|
||||
|
||||
Upon successful login, the commands available are:
|
||||
|
||||
call provide port for given console
|
||||
exit disconnect
|
||||
groups provide ports for group leaders
|
||||
help this help message
|
||||
master provide a list of master servers
|
||||
pid provide pid of master process
|
||||
quit* terminate conserver (SIGTERM)
|
||||
restart* restart conserver (SIGHUP)
|
||||
version provide version info for server
|
||||
* = requires admin privileges
|
||||
|
||||
"exit" and "help" are the same as before the client logged login.
|
||||
|
||||
The "call" command expects one argument, the console name to connect to.
|
||||
The server will respond with either a port number (if it's a locally
|
||||
managed console), an "@hostname" where hostname is the name of the
|
||||
remote conserver host managing the console (if it's a remotely managed
|
||||
console), or an error message (possibly multi-line). The client is not
|
||||
disconnected, whatever the response.
|
||||
|
||||
The "groups" command responds with a colon-separated list of port
|
||||
numbers, which correspond to each of the child processes running on the
|
||||
local host. The client is not disconnected.
|
||||
|
||||
The "master" command responds with a colon-separated list of "@hostname"
|
||||
names. The list includes any hosts (including the possibility of the
|
||||
local host) which have locally managed consoles. The client is not
|
||||
disconnected.
|
||||
|
||||
The "pid" command responds with the pid of the master process (in this
|
||||
case, the one the client is talking to). The client is not
|
||||
disconnected.
|
||||
|
||||
The "quit" command will shut down conserver, assuming the user has
|
||||
administrative access. It responds with a message starting with "ok" if
|
||||
successful, and an error message otherwise (like "unauthorized
|
||||
command"). The client is disconnected if it's successful.
|
||||
|
||||
The "restart" command will shut down conserver, assuming the user has
|
||||
administrative access. It responds with a message starting with "ok" if
|
||||
successful, and an error message otherwise (like "unauthorized
|
||||
command"). The client is not disconnected.
|
||||
|
||||
The "version" command responds with the version string. The client is
|
||||
not disconnected.
|
||||
|
||||
|
||||
"group" Mode
|
||||
------------
|
||||
|
||||
When a child process gets a connection from a client, it either sends an
|
||||
"ok" string to signal it's ready or an error message (like "access from
|
||||
your host is refused") and the connection is dropped. At this point,
|
||||
"group" mode acts just like "master" mode. Once the client successfully
|
||||
logs in, however, "group" mode has the recognizes the following
|
||||
commands:
|
||||
|
||||
broadcast send broadcast message
|
||||
call connect to given console
|
||||
disconnect* disconnect the given user(s)
|
||||
examine examine port and baud rates
|
||||
exit disconnect
|
||||
group show users in this group
|
||||
help this help message
|
||||
hosts show host status and user
|
||||
info show console information
|
||||
textmsg send a text message
|
||||
* = requires admin privileges
|
||||
|
||||
The "exit" and "help" commands are like the others documented above.
|
||||
|
||||
The "broadcast" command expects a text string of the message to be sent
|
||||
to all users connected to this process. An "ok" is sent as a response.
|
||||
|
||||
The "call" command expects one argument, the console name to connect to,
|
||||
just like in "master" mode. The difference here is that this requests
|
||||
the server to attach the client to the console and go into "console"
|
||||
mode. If the attachment is successful, the response will begin with a
|
||||
'[' character. If not, an error message is returned. The success
|
||||
responses are:
|
||||
|
||||
[console is read-only] - console is read only
|
||||
[read-only -- initializing] - console is initializing, and
|
||||
read-only for the time being
|
||||
[line to console is down] - console is down
|
||||
[attached] - attached read-write
|
||||
[spy] - attached read-only
|
||||
|
||||
|
||||
The "disconnect" command expects an argument of the form "user@console"
|
||||
where either the "user" or "@console" part may be omitted. Upon
|
||||
success, a response of the form "ok -- disconnected X users" is sent,
|
||||
where X is the number of users disconnected. If a user is unauthorized
|
||||
or some other problem occurs, an error message (like "unauthorized
|
||||
command") is sent.
|
||||
|
||||
The "examine" command returns a list of console information of the form
|
||||
that 'console -x' shows.
|
||||
|
||||
The "group" command returns a list of console information of the form
|
||||
that 'console -w' shows.
|
||||
|
||||
The "hosts" command returns a list of console information of the form
|
||||
that 'console -u' shows.
|
||||
|
||||
The "info" command returns a list of console information of the form
|
||||
that 'console -i' shows.
|
||||
|
||||
The "textmsg" command expects two arguments, the first being the
|
||||
recipient of the message in the form "user@console" (again, where the
|
||||
"user" or "@console" portion may be omitted) and the second being the
|
||||
string, like the "broadcast" command. The server returns "ok".
|
||||
|
||||
|
||||
"console" Mode
|
||||
--------------
|
||||
|
||||
As mentioned above, "console" mode is obtained by using the "call"
|
||||
command when connected to a child processes operating in "group" mode.
|
||||
|
||||
"console" mode should look very familiar to a user of conserver, as it's
|
||||
what the user interacts with when connected to a console. There's
|
||||
really nothings special here. Each character received from the client
|
||||
is compared to the escape sequence, and if it matches, an action occurs
|
||||
on the server side. If it doesn't match the escape sequence, the data
|
||||
is sent on to the console. All data received from the console is sent
|
||||
to the client(s). Of course, there are certain exceptions to these
|
||||
rules, based on the state of the console and the state of the client.
|
||||
And, certain escape sequences cause special behaviors to occur.
|
||||
|
||||
Most escape sequences cause the server to send information back to the
|
||||
user. Stuff like "^Ecw", "^Eci", and "^Ecu" are examples. The escape
|
||||
sequence is absorbed by the server, the server sends the client a
|
||||
variety of information, and things continue as before.
|
||||
|
||||
The more "interesting" escape sequences are the following.
|
||||
|
||||
"^Ec;" The server sends a 0xFF,'G' command sequence to the client, to
|
||||
signal a wish to move to a new console. The client then gets
|
||||
put into the same state as the "^Ecz" sequence (paused), which
|
||||
gives the client a chance to either resume the connection or
|
||||
disconnect.
|
||||
|
||||
"^Ec|" The server sends a 0xFF,'E' command sequence to the client, to
|
||||
signal a wish to have the client program interact with a
|
||||
program, as opposed to the user. The server discards all data
|
||||
until it receives one of the following command sequences from
|
||||
the client:
|
||||
|
||||
0xFF,'E' Signals successful redirection of interaction to
|
||||
a program. The server then responds with "[rw]"
|
||||
or "[ro]" to tell the client whether or not they
|
||||
have read-write access. If not, the client
|
||||
should abort the program and send the abort
|
||||
command sequence below, as other data received by
|
||||
the server will just get dropped.
|
||||
|
||||
0xFF,'.' Abort the operation. The server assumes the
|
||||
redirection didn't happen and returns the client
|
||||
to it's normal mode.
|
||||
|
||||
The server keeps the client in the "redirected" state until it
|
||||
receives a 0xFF,'.' command sequence from the client (which
|
||||
usually occurs when the client command terminates).
|
||||
|
||||
If the client is "bumped" from read-write to read-only by
|
||||
another user, the server will send the client a 0xFF,'.' command
|
||||
sequence to tell it to abort the redirection and return control
|
||||
back to the user.
|
||||
|
||||
"^Ecz" The server sends a 0xFF,'Z' command sequence to the client, to
|
||||
signal a wish to suspend to client process. The client is then
|
||||
put into a "paused" state where it receives no more data from
|
||||
the server. When the client is ready to resume receiving data,
|
||||
it sends a character of data to the server, at which point the
|
||||
server discards the character and sends back a status message of
|
||||
the form " -- MSG]". The current set of possible messages are:
|
||||
|
||||
" -- line down]"
|
||||
" -- read-only]"
|
||||
" -- attached (nologging)]"
|
||||
" -- attached]"
|
||||
" -- spy mode]"
|
||||
|
||||
#
|
||||
# $Id: PROTOCOL,v 1.1 2004/04/16 16:50:55 bryan Exp $
|
||||
#
|
@ -1,4 +1,4 @@
|
||||
.\" $Id: autologin.man,v 1.1 2003/11/04 02:36:24 bryan Exp $
|
||||
.\" $Id: autologin.man,v 1.2 2004/03/23 18:32:06 bryan Exp $
|
||||
.TH AUTOLOGIN 8L PUCC
|
||||
.SH NAME
|
||||
autologin \- create an automatic login session from /etc/inittab
|
||||
@ -112,12 +112,21 @@ environment variable set to
|
||||
ss10:2:respawn:/usr/local/etc/autologin \-e TERM=reg20 \-t/dev/tty10 \-lssinfo
|
||||
.ad
|
||||
.PP
|
||||
Adding the following line to \fI/etc/ttytab\fP on a Sun 4.1.\fIx\fP
|
||||
Adding the following line to
|
||||
.I /etc/ttytab
|
||||
on a Sun
|
||||
.RI 4.1. x
|
||||
machine establishes a root login on the console device:
|
||||
.br
|
||||
.na
|
||||
console "/usr/local/etc/autologin \-lroot \-t" xterm on local secure
|
||||
.ad
|
||||
Note that \fIinit\fP provides the \fItty\fP argument on the end of the command.
|
||||
.PP
|
||||
Note that
|
||||
.I init
|
||||
provides the
|
||||
.I tty
|
||||
argument on the end of the command.
|
||||
.SH FILES
|
||||
/bin/su
|
||||
.br
|
||||
|
3
compat.h
3
compat.h
@ -8,6 +8,9 @@
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <netinet/in.h>
|
||||
#if USE_UNIX_DOMAIN_SOCKETS
|
||||
#include <sys/un.h>
|
||||
#endif
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <ctype.h>
|
||||
|
@ -324,12 +324,18 @@
|
||||
/* Defined if we trust reverse DNS */
|
||||
#undef TRUST_REVERSE_DNS
|
||||
|
||||
/* Directory for Unix domain sockets */
|
||||
#undef UDSDIR
|
||||
|
||||
/* Defined if we produce extended messages */
|
||||
#undef USE_EXTENDED_MESSAGES
|
||||
|
||||
/* use tcp_wrappers libwrap */
|
||||
#undef USE_LIBWRAP
|
||||
|
||||
/* Defined if we use Unix domain sockets */
|
||||
#undef USE_UNIX_DOMAIN_SOCKETS
|
||||
|
||||
/* Define to 1 if on AIX 3.
|
||||
System headers sometimes define this.
|
||||
We just want to avoid a redefinition error message. */
|
||||
|
51
configure
vendored
51
configure
vendored
@ -857,6 +857,9 @@ Optional Packages:
|
||||
--with-timeout=TIMEOUT Specify connect() timeout in seconds [10]
|
||||
--with-trustrevdns Trust reverse DNS information
|
||||
--with-extmsgs Produce extended messages
|
||||
--with-uds[=DIR]
|
||||
Use Unix domain sockets for client/server
|
||||
communication [/tmp/conserver]
|
||||
--with-libwrap[=PATH]
|
||||
Compile in libwrap (tcp_wrappers) support
|
||||
--with-openssl[=PATH]
|
||||
@ -1312,6 +1315,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ac_config_headers="$ac_config_headers config.h"
|
||||
|
||||
@ -1692,6 +1696,53 @@ else
|
||||
echo "${ECHO_T}no" >&6
|
||||
fi;
|
||||
|
||||
echo "$as_me:$LINENO: checking whether to use Unix domain sockets" >&5
|
||||
echo $ECHO_N "checking whether to use Unix domain sockets... $ECHO_C" >&6
|
||||
|
||||
# Check whether --with-uds or --without-uds was given.
|
||||
if test "${with_uds+set}" = set; then
|
||||
withval="$with_uds"
|
||||
case "$withval" in
|
||||
yes)
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define UDSDIR "/tmp/conserver"
|
||||
_ACEOF
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define USE_UNIX_DOMAIN_SOCKETS 1
|
||||
_ACEOF
|
||||
|
||||
echo "$as_me:$LINENO: result: /tmp/conserver" >&5
|
||||
echo "${ECHO_T}/tmp/conserver" >&6
|
||||
;;
|
||||
no)
|
||||
echo "$as_me:$LINENO: result: no" >&5
|
||||
echo "${ECHO_T}no" >&6
|
||||
;;
|
||||
*)
|
||||
cat >>confdefs.h <<_ACEOF
|
||||
#define UDSDIR "$withval"
|
||||
_ACEOF
|
||||
|
||||
cat >>confdefs.h <<\_ACEOF
|
||||
#define USE_UNIX_DOMAIN_SOCKETS 1
|
||||
_ACEOF
|
||||
|
||||
echo "$as_me:$LINENO: result: '$withval'" >&5
|
||||
echo "${ECHO_T}'$withval'" >&6
|
||||
if expr "$withval" : '/' >/dev/null 2>&1; then
|
||||
:
|
||||
else
|
||||
echo "*** WARNING *** you may have better success using a fully-qualified path"
|
||||
echo "*** WARNING *** instead of '$withval'"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
else
|
||||
echo "$as_me:$LINENO: result: no" >&5
|
||||
echo "${ECHO_T}no" >&6
|
||||
fi;
|
||||
|
||||
ac_ext=c
|
||||
ac_cpp='$CPP $CPPFLAGS'
|
||||
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||
|
59
configure.in
59
configure.in
@ -17,9 +17,12 @@ AH_TEMPLATE([HAVE_DMALLOC], [have dmalloc support])
|
||||
AH_TEMPLATE([HAVE_SA_LEN],[Defined if sa_len member exists in struct sockaddr])
|
||||
AH_TEMPLATE([TRUST_REVERSE_DNS],[Defined if we trust reverse DNS])
|
||||
AH_TEMPLATE([USE_EXTENDED_MESSAGES],[Defined if we produce extended messages])
|
||||
AH_TEMPLATE([USE_UNIX_DOMAIN_SOCKETS],[Defined if we use Unix domain sockets])
|
||||
AH_TEMPLATE([UDSDIR], [Directory for Unix domain sockets])
|
||||
|
||||
dnl ### Normal initialization. ######################################
|
||||
AC_INIT
|
||||
AC_PREREQ(2.59)
|
||||
AC_CONFIG_SRCDIR([conserver/main.c])
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
|
||||
@ -49,7 +52,7 @@ dnl AC_MSG_RESULT($with_64bit)
|
||||
|
||||
AC_MSG_CHECKING(for port number specification)
|
||||
AC_ARG_WITH(port,
|
||||
AC_HELP_STRING([--with-port=PORT],[Specify port number @<:@conserver@:>@]),
|
||||
AS_HELP_STRING([--with-port=PORT],[Specify port number @<:@conserver@:>@]),
|
||||
[case "$withval" in
|
||||
yes|no)
|
||||
AC_DEFINE_UNQUOTED(DEFPORT, "conserver")
|
||||
@ -65,7 +68,7 @@ AC_ARG_WITH(port,
|
||||
|
||||
AC_MSG_CHECKING(for secondary channel base port)
|
||||
AC_ARG_WITH(base,
|
||||
AC_HELP_STRING([--with-base=PORT], [Base port for secondary channel @<:@0@:>@]),
|
||||
AS_HELP_STRING([--with-base=PORT], [Base port for secondary channel @<:@0@:>@]),
|
||||
[case "$withval" in
|
||||
yes|no)
|
||||
AC_DEFINE_UNQUOTED(DEFBASEPORT, "0")
|
||||
@ -81,7 +84,7 @@ AC_ARG_WITH(base,
|
||||
|
||||
AC_MSG_CHECKING(for master conserver hostname)
|
||||
AC_ARG_WITH(master,
|
||||
AC_HELP_STRING([--with-master=MASTER],[Specify master server hostname @<:@console@:>@]),
|
||||
AS_HELP_STRING([--with-master=MASTER],[Specify master server hostname @<:@console@:>@]),
|
||||
[case "$withval" in
|
||||
yes|no)
|
||||
AC_DEFINE_UNQUOTED(MASTERHOST, "console")
|
||||
@ -97,7 +100,7 @@ AC_ARG_WITH(master,
|
||||
|
||||
AC_MSG_CHECKING(for configuration filename)
|
||||
AC_ARG_WITH(cffile,
|
||||
AC_HELP_STRING([--with-cffile=CFFILE],[Specify config filename @<:@SYSCONFDIR/conserver.cf@:>@]),
|
||||
AS_HELP_STRING([--with-cffile=CFFILE],[Specify config filename @<:@SYSCONFDIR/conserver.cf@:>@]),
|
||||
[case "$withval" in
|
||||
yes|no)
|
||||
AC_DEFINE_UNQUOTED(CONFIGFILE, [SYSCONFDIR "/conserver.cf"])
|
||||
@ -117,7 +120,7 @@ AC_ARG_WITH(cffile,
|
||||
|
||||
AC_MSG_CHECKING(for password filename)
|
||||
AC_ARG_WITH(pwdfile,
|
||||
AC_HELP_STRING([--with-pwdfile=PWDFILE],[Specify password filename @<:@SYSCONFDIR/conserver.passwd@:>@]),
|
||||
AS_HELP_STRING([--with-pwdfile=PWDFILE],[Specify password filename @<:@SYSCONFDIR/conserver.passwd@:>@]),
|
||||
[case "$withval" in
|
||||
yes|no)
|
||||
AC_DEFINE_UNQUOTED(PASSWDFILE, [SYSCONFDIR "/conserver.passwd"])
|
||||
@ -137,7 +140,7 @@ AC_ARG_WITH(pwdfile,
|
||||
|
||||
AC_MSG_CHECKING(for log filename)
|
||||
AC_ARG_WITH(logfile,
|
||||
AC_HELP_STRING([--with-logfile=LOGFILE],[Specify log filename @<:@/var/log/conserver@:>@]),
|
||||
AS_HELP_STRING([--with-logfile=LOGFILE],[Specify log filename @<:@/var/log/conserver@:>@]),
|
||||
[case "$withval" in
|
||||
yes|no)
|
||||
AC_DEFINE_UNQUOTED(LOGFILEPATH, "/var/log/conserver")
|
||||
@ -154,7 +157,7 @@ AC_ARG_WITH(logfile,
|
||||
AC_SUBST(PIDFILE)
|
||||
AC_MSG_CHECKING(for PID filename)
|
||||
AC_ARG_WITH(pidfile,
|
||||
AC_HELP_STRING([--with-pidfile=PIDFILE],[Specify PID filepath @<:@/var/run/conserver.pid@:>@]),
|
||||
AS_HELP_STRING([--with-pidfile=PIDFILE],[Specify PID filepath @<:@/var/run/conserver.pid@:>@]),
|
||||
[case "$withval" in
|
||||
yes|no)
|
||||
PIDFILE="/var/run/conserver.pid"
|
||||
@ -169,7 +172,7 @@ AC_MSG_RESULT('$PIDFILE')
|
||||
|
||||
AC_MSG_CHECKING(for MAXMEMB setting)
|
||||
AC_ARG_WITH(maxmemb,
|
||||
AC_HELP_STRING([--with-maxmemb=MAXMEMB],[Specify maximum consoles per process @<:@16@:>@]),
|
||||
AS_HELP_STRING([--with-maxmemb=MAXMEMB],[Specify maximum consoles per process @<:@16@:>@]),
|
||||
[case "$withval" in
|
||||
yes|no)
|
||||
AC_DEFINE_UNQUOTED(MAXMEMB, 16)
|
||||
@ -191,7 +194,7 @@ AC_ARG_WITH(maxmemb,
|
||||
|
||||
AC_MSG_CHECKING(for connect() timeout)
|
||||
AC_ARG_WITH(timeout,
|
||||
AC_HELP_STRING([--with-timeout=TIMEOUT],[Specify connect() timeout in seconds @<:@10@:>@]),
|
||||
AS_HELP_STRING([--with-timeout=TIMEOUT],[Specify connect() timeout in seconds @<:@10@:>@]),
|
||||
[if expr "$withval" : '[[0-9]]*$' >/dev/null 2>&1 &&
|
||||
test "$withval" -gt 0 -a "$withval" -lt 300; then
|
||||
AC_DEFINE_UNQUOTED(CONNECTTIMEOUT, $withval)
|
||||
@ -205,7 +208,7 @@ AC_ARG_WITH(timeout,
|
||||
|
||||
AC_MSG_CHECKING(whether to trust reverse DNS)
|
||||
AC_ARG_WITH(trustrevdns,
|
||||
AC_HELP_STRING([--with-trustrevdns],[Trust reverse DNS information]),
|
||||
AS_HELP_STRING([--with-trustrevdns],[Trust reverse DNS information]),
|
||||
[case "$withval" in
|
||||
yes)
|
||||
AC_DEFINE(TRUST_REVERSE_DNS)
|
||||
@ -218,7 +221,7 @@ AC_ARG_WITH(trustrevdns,
|
||||
|
||||
AC_MSG_CHECKING(whether to display extended messages)
|
||||
AC_ARG_WITH(extmsgs,
|
||||
AC_HELP_STRING([--with-extmsgs],[Produce extended messages]),
|
||||
AS_HELP_STRING([--with-extmsgs],[Produce extended messages]),
|
||||
[case "$withval" in
|
||||
yes)
|
||||
AC_DEFINE(USE_EXTENDED_MESSAGES)
|
||||
@ -229,6 +232,32 @@ AC_ARG_WITH(extmsgs,
|
||||
;;
|
||||
esac],[AC_MSG_RESULT(no)])
|
||||
|
||||
AC_MSG_CHECKING(whether to use Unix domain sockets)
|
||||
AC_ARG_WITH(uds,
|
||||
AS_HELP_STRING([--with-uds@<:@=DIR@:>@ ],
|
||||
[Use Unix domain sockets for client/server communication @<:@/tmp/conserver@:>@]),
|
||||
[case "$withval" in
|
||||
yes)
|
||||
AC_DEFINE_UNQUOTED(UDSDIR, "/tmp/conserver")
|
||||
AC_DEFINE(USE_UNIX_DOMAIN_SOCKETS)
|
||||
AC_MSG_RESULT([/tmp/conserver])
|
||||
;;
|
||||
no)
|
||||
AC_MSG_RESULT(no)
|
||||
;;
|
||||
*)
|
||||
AC_DEFINE_UNQUOTED(UDSDIR, "$withval")
|
||||
AC_DEFINE(USE_UNIX_DOMAIN_SOCKETS)
|
||||
AC_MSG_RESULT('$withval')
|
||||
if expr "$withval" : '/' >/dev/null 2>&1; then
|
||||
:
|
||||
else
|
||||
echo "*** WARNING *** you may have better success using a fully-qualified path"
|
||||
echo "*** WARNING *** instead of '$withval'"
|
||||
fi
|
||||
;;
|
||||
esac],[AC_MSG_RESULT(no)])
|
||||
|
||||
dnl ### Check for compiler et al. ###################################
|
||||
AC_PROG_CC
|
||||
AC_PROG_INSTALL
|
||||
@ -315,7 +344,7 @@ AC_SUBST(CONSLIBS)
|
||||
AC_SUBST(CONSCPPFLAGS)
|
||||
AC_SUBST(CONSLDFLAGS)
|
||||
AC_ARG_WITH(libwrap,
|
||||
AC_HELP_STRING([--with-libwrap@<:@=PATH@:>@],
|
||||
AS_HELP_STRING([--with-libwrap@<:@=PATH@:>@],
|
||||
[Compile in libwrap (tcp_wrappers) support]),
|
||||
[if test "$withval" != "no"; then
|
||||
if test "$withval" != "yes"; then
|
||||
@ -365,7 +394,7 @@ AC_ARG_WITH(libwrap,
|
||||
)
|
||||
|
||||
AC_ARG_WITH(openssl,
|
||||
AC_HELP_STRING([--with-openssl@<:@=PATH@:>@],
|
||||
AS_HELP_STRING([--with-openssl@<:@=PATH@:>@],
|
||||
[Compile in OpenSSL support]),
|
||||
[if test "$withval" != "no"; then
|
||||
if test "$withval" != "yes"; then
|
||||
@ -403,7 +432,7 @@ AC_ARG_WITH(openssl,
|
||||
)
|
||||
|
||||
AC_ARG_WITH(dmalloc,
|
||||
AC_HELP_STRING([--with-dmalloc@<:@=PATH@:>@],
|
||||
AS_HELP_STRING([--with-dmalloc@<:@=PATH@:>@],
|
||||
[Compile in dmalloc support]),
|
||||
[if test "$withval" != "no"; then
|
||||
if test "$withval" != "yes"; then
|
||||
@ -478,7 +507,7 @@ dnl fi],[AC_MSG_RESULT(no)])
|
||||
|
||||
AC_MSG_CHECKING(for PAM support)
|
||||
AC_ARG_WITH(pam,
|
||||
AC_HELP_STRING([--with-pam],
|
||||
AS_HELP_STRING([--with-pam],
|
||||
[Enable PAM support]),
|
||||
[if test "$withval" = yes; then
|
||||
oLIBS="$LIBS"
|
||||
|
@ -1,5 +1,5 @@
|
||||
.\" $Id: conserver.cf.man,v 1.58 2004/02/24 02:59:36 bryan Exp $
|
||||
.TH CONSERVER.CF 5 "2004/02/24" "conserver-8.1.3" "conserver"
|
||||
.\" $Id: conserver.cf.man,v 1.63 2004/05/07 03:42:51 bryan Exp $
|
||||
.TH CONSERVER.CF 5 "2004/05/07" "conserver-8.1.5" "conserver"
|
||||
.SH NAME
|
||||
conserver.cf \- console configuration file for
|
||||
.BR conserver (8)
|
||||
@ -107,6 +107,24 @@ of things, we have:
|
||||
"defa"ult my\e defs { rw *; in\eclude "other defs" ; }
|
||||
.fi
|
||||
.ft
|
||||
.PP
|
||||
There is one special line the parser recognizes: a ``#include'' statement.
|
||||
It is of the form:
|
||||
.IP
|
||||
.B #include
|
||||
.I filename
|
||||
.PP
|
||||
Any whitespace around
|
||||
.I filename
|
||||
is ignored, but whitespace embedded inside is preserved.
|
||||
Everything in
|
||||
.I filename
|
||||
is taken literally, so none of the normal parser quoting applies.
|
||||
The
|
||||
.B #include
|
||||
must begin in ``column 0'' - no whitespace is allowed between it and
|
||||
the start of the physical line.
|
||||
There is an include file depth limit of 10 to prevent infinite recursion.
|
||||
.SH BLOCKS
|
||||
.TP 8
|
||||
.B access
|
||||
@ -123,7 +141,7 @@ fashion (top down), so order is important.
|
||||
.RS
|
||||
.TP 15
|
||||
.B admin
|
||||
.RI "[ [\fB!\fP]" username ,...
|
||||
.RI "[ [\f3!\fP]" username ,...
|
||||
| "" ]
|
||||
.br
|
||||
Define a list of users making up the admin list for the console server.
|
||||
@ -132,7 +150,18 @@ If
|
||||
matches a previously defined group name, all members of the previous
|
||||
group are applied to the admin list (with access reversed if prefixed
|
||||
with a `!').
|
||||
Otherwise, users will be granted (or denied if prefixed with `!') access.
|
||||
If
|
||||
.I username
|
||||
doesn't match a previously defined group and
|
||||
.I username
|
||||
begins with `@', the name (minus the `@') is checked against the
|
||||
host's group database.
|
||||
All users found in the group will be granted (or denied, if prefixed
|
||||
with `!') access.
|
||||
If
|
||||
.I username
|
||||
doesn't match a previous group and doesn't begin with `@', the users
|
||||
will be granted (or denied, if prefixed with `!') access.
|
||||
If the null string (``""'') is used, any
|
||||
users previously defined for the console servers's admin list are removed.
|
||||
.TP
|
||||
@ -264,7 +293,8 @@ all conserver hosts.
|
||||
.RS
|
||||
.TP 15
|
||||
.B defaultaccess
|
||||
.RB [ " rejected " | " trusted " | " allowed " ]
|
||||
.RB [ " rejected " | " trusted "
|
||||
.RB | " allowed " ]
|
||||
.br
|
||||
Set the default access permission for all hosts not matched by
|
||||
an access list (see the
|
||||
@ -272,12 +302,41 @@ an access list (see the
|
||||
command-line flag).
|
||||
.TP
|
||||
.B daemonmode
|
||||
.RB [ " yes " | " true " | " on " | " no " | " false " | " off " ]
|
||||
.RB [ " yes " | " true "
|
||||
.RB | " on " | " no "
|
||||
.RB | " false " | " off " ]
|
||||
.br
|
||||
Set whether or not to become a daemon when run (see the
|
||||
.B \-d
|
||||
command-line flag).
|
||||
.TP
|
||||
.B initdelay
|
||||
.I number
|
||||
.br
|
||||
Set the number of seconds between console initializations.
|
||||
All consoles with the same
|
||||
.B host
|
||||
value will be throttled as a group (those without a
|
||||
.B host
|
||||
value are their own group).
|
||||
In other words, each console within a group will only be initialized after
|
||||
.I number
|
||||
seconds passes from the previous initialization of a console in that group.
|
||||
Different throttle groups are initialized simultaneously.
|
||||
One warning: since consoles are split up and managed by seperate conserver
|
||||
processes, it's possible for more than one conserver process to
|
||||
have a throttle group based on a particular
|
||||
.B host
|
||||
value.
|
||||
If this happens, each conserver process will throttle their groups
|
||||
independently of the other conserver processes, which results in a
|
||||
more rapid initialization (per
|
||||
.B host
|
||||
value) than one might otherwise expect.
|
||||
If
|
||||
.I number
|
||||
is zero, all consoles are initialized without delay.
|
||||
.TP
|
||||
.B logfile
|
||||
.I filename
|
||||
.br
|
||||
@ -300,7 +359,9 @@ Set the port used by the master conserver process (see the
|
||||
command-line flag).
|
||||
.TP
|
||||
.B redirect
|
||||
.RB [ " yes " | " true " | " on " | " no " | " false " | " off " ]
|
||||
.RB [ " yes " | " true "
|
||||
.RB | " on " | " no "
|
||||
.RB | " false " | " off " ]
|
||||
.br
|
||||
Turn redirection on or off (see the
|
||||
.B \-R
|
||||
@ -309,7 +370,7 @@ command-line flag).
|
||||
.B reinitcheck
|
||||
.I number
|
||||
.br
|
||||
Set the number of seconds used between reinitialization checks (see the
|
||||
Set the number of minutes used between reinitialization checks (see the
|
||||
.B \-O
|
||||
command-line flag).
|
||||
.TP
|
||||
@ -321,7 +382,9 @@ Set the base port number used by child processes (see the
|
||||
command-line flag).
|
||||
.TP
|
||||
.B setproctitle
|
||||
.RB [ " yes " | " true " | " on " | " no " | " false " | " off " ]
|
||||
.RB [ " yes " | " true "
|
||||
.RB | " on " | " no "
|
||||
.RB | " false " | " off " ]
|
||||
.br
|
||||
Set whether or not the process title shows master/group functionality
|
||||
as well as the port number the process is listening on and how many
|
||||
@ -340,7 +403,9 @@ credentials file location (see the
|
||||
command-line flag).
|
||||
.TP
|
||||
.B sslrequired
|
||||
.RB [ " yes " | " true " | " on " | " no " | " false " | " off " ]
|
||||
.RB [ " yes " | " true "
|
||||
.RB | " on " | " no "
|
||||
.RB | " false " | " off " ]
|
||||
.br
|
||||
Set whether or not encryption is required when talking to clients (see the
|
||||
.B \-E
|
||||
@ -388,8 +453,11 @@ of their definition).
|
||||
.RS
|
||||
.TP 15
|
||||
.B baud
|
||||
.RB [ " 300 " | " 600 " | " 1800 " | " 2400 " | " 4800"
|
||||
.RB | " 9600 " | " 19200 " | " 38400 " | " 57600 " | " 115200 " ]
|
||||
.RB [ " 300 " | " 600 "
|
||||
.RB | " 1800 " | " 2400 "
|
||||
.RB | " 4800 " | " 9600 "
|
||||
.RB | " 19200 " | " 38400 "
|
||||
.RB | " 57600 " | " 115200 " ]
|
||||
.br
|
||||
Assign the baud rate to the console.
|
||||
Only consoles of type ``device'' will use this value.
|
||||
@ -411,7 +479,7 @@ as the access to the console.
|
||||
Only consoles of type ``device'' will use this value.
|
||||
.TP
|
||||
.B devicesubst
|
||||
.RI [ c = t [ n ] f "[,...]"
|
||||
[\f2c\fP=\f2t\fP[\f2n\fP]\f2f\fP[,...]
|
||||
| "" ]
|
||||
.br
|
||||
Perform character substitutions on the
|
||||
@ -419,7 +487,7 @@ Perform character substitutions on the
|
||||
value.
|
||||
A series of replacements can be defined by specifying a
|
||||
comma-separated list of
|
||||
.IR c = t [ n ] f
|
||||
\f2c\fP=\f2t\fP[\f2n\fP]\f2f\fP
|
||||
sequences where
|
||||
.I c
|
||||
is any printable character,
|
||||
@ -488,14 +556,14 @@ Assign the string
|
||||
.I command
|
||||
as the command to access the console.
|
||||
Conserver will run the command by
|
||||
invoking ``/bin/sh -ce "\fIcommand\fP"''.
|
||||
invoking ``/bin/sh -ce "\f2command\fP"''.
|
||||
If the null string (``""'') is used or no
|
||||
.B exec
|
||||
keyword is specified, conserver will use the command ``/bin/sh -i''.
|
||||
Only consoles of type ``exec'' will use this value.
|
||||
.TP
|
||||
.B execsubst
|
||||
.RI [ c = t [ n ] f "[,...]"
|
||||
[\f2c\fP=\f2t\fP[\f2n\fP]\f2f\fP[,...]
|
||||
| "" ]
|
||||
.br
|
||||
Perform character substitutions on the
|
||||
@ -543,7 +611,7 @@ use the default delay time.
|
||||
The default string is ``\en''.
|
||||
.TP
|
||||
.B idletimeout
|
||||
.BR \fInumber\fP [ s | m | h ]
|
||||
\f2number\fP[\f3s\fP|\f3m\fP|\f3h\fP]
|
||||
.br
|
||||
Set the idle timeout of the console to
|
||||
.I number
|
||||
@ -577,7 +645,7 @@ If the null string (``""'') is used, the command is unset and
|
||||
nothing is invoked.
|
||||
.TP
|
||||
.B initsubst
|
||||
.RI [ c = t [ n ] f "[,...]"
|
||||
[\f2c\fP=\f2t\fP[\f2n\fP]\f2f\fP[,...]
|
||||
| "" ]
|
||||
.br
|
||||
Perform character substitutions on the
|
||||
@ -602,7 +670,7 @@ If the null string (``""'') is used, the logfile name is unset and
|
||||
no logging will occur.
|
||||
.TP
|
||||
.B logfilemax
|
||||
.BR \fInumber\fP [ k | m ]
|
||||
\f2number\fP[\f3k\fP|\f3m\fP]
|
||||
.br
|
||||
Enable automatic rotation of
|
||||
.B logfile
|
||||
@ -772,7 +840,9 @@ Default is
|
||||
.RE
|
||||
.TP
|
||||
.B parity
|
||||
.RB [ " even " | " mark " | " none " | " odd " | " space " ]
|
||||
.RB [ " even " | " mark "
|
||||
.RB | " none " | " odd "
|
||||
.RB | " space " ]
|
||||
.br
|
||||
Set the parity option for the console.
|
||||
Only consoles of type ``device'' will use this value.
|
||||
@ -858,7 +928,7 @@ console option still applies when data is read by the server, and if enabled,
|
||||
can impact the encapsulation process.
|
||||
.TP
|
||||
.B ro
|
||||
.RI "[ [\fB!\fP]" username ,...
|
||||
.RI "[ [\f3!\fP]" username ,...
|
||||
| "" ]
|
||||
.br
|
||||
Define a list of users making up the read-only access list
|
||||
@ -868,13 +938,23 @@ If
|
||||
matches a previously defined group name, all members of the previous
|
||||
group are applied to the read-only access list (with access reversed
|
||||
if prefixed with a `!').
|
||||
Otherwise, users will be granted (or denied if prefixed with `!')
|
||||
read-only access.
|
||||
If
|
||||
.I username
|
||||
doesn't match a previously defined group and
|
||||
.I username
|
||||
begins with `@', the name (minus the `@') is checked against the
|
||||
host's group database.
|
||||
All users found in the group will be granted (or denied, if prefixed
|
||||
with `!') read-only access.
|
||||
If
|
||||
.I username
|
||||
doesn't match a previous group and doesn't begin with `@', the users
|
||||
will be granted (or denied, if prefixed with `!') read-only access.
|
||||
If the null string (``""'') is used, any
|
||||
users previously defined for the console's read-only list are removed.
|
||||
.TP
|
||||
.B rw
|
||||
.RI "[ [\fB!\fP]" username ,...
|
||||
.RI "[ [\f3!\fP]" username ,...
|
||||
| "" ]
|
||||
.br
|
||||
Define a list of users making up the read-write access list
|
||||
@ -884,14 +964,24 @@ If
|
||||
matches a previously defined group name, all members of the previous
|
||||
group are applied to the read-write access list (with access reversed
|
||||
if prefixed with a `!').
|
||||
Otherwise, users will be granted (or denied if prefixed with `!')
|
||||
read-write access.
|
||||
If
|
||||
.I username
|
||||
doesn't match a previously defined group and
|
||||
.I username
|
||||
begins with `@', the name (minus the `@') is checked against the
|
||||
host's group database.
|
||||
All users found in the group will be granted (or denied, if prefixed
|
||||
with `!') read-write access.
|
||||
If
|
||||
.I username
|
||||
doesn't match a previous group and doesn't begin with `@', the users
|
||||
will be granted (or denied, if prefixed with `!') read-write access.
|
||||
If the null string (``""'') is used, any
|
||||
users previously defined for the console's read-write list are removed.
|
||||
.TP
|
||||
.B timestamp
|
||||
[
|
||||
.RB [ \fInumber\fP [ m | h | d | l ]][ a ][ b ]
|
||||
[\f2number\fP[\f3m\fP|\f3h\fP|\f3d\fP|\f3l\fP]][\f3a\fP][\f3b\fP]
|
||||
| "" ]
|
||||
.br
|
||||
Specifies the time between timestamps applied to the console
|
||||
@ -922,7 +1012,8 @@ A
|
||||
can be specified to add logging of break sequences sent to the console.
|
||||
.TP
|
||||
.B type
|
||||
.RB [ " device " | " exec " | " host " ]
|
||||
.RB [ " device " | " exec "
|
||||
.RB | " host " ]
|
||||
.br
|
||||
Set the type of console.
|
||||
The type
|
||||
@ -951,7 +1042,7 @@ Define a user group identified as
|
||||
.RS
|
||||
.TP 15
|
||||
.B users
|
||||
.RI "[ [\fB!\fP]" username ,...
|
||||
.RI "[ [\f3!\fP]" username ,...
|
||||
| "" ]
|
||||
.br
|
||||
Define a list of users making up the group
|
||||
@ -961,8 +1052,18 @@ If
|
||||
matches a previously defined group name, all members of the previous
|
||||
group are applied to the current group (with access reversed
|
||||
if prefixed with a `!').
|
||||
Otherwise, users will be recorded with (or without if prefixed with `!')
|
||||
access.
|
||||
If
|
||||
.I username
|
||||
doesn't match a previously defined group and
|
||||
.I username
|
||||
begins with `@', the name (minus the `@') is checked against the
|
||||
host's group database.
|
||||
All users found in the group will be recorded with (or without, if prefixed
|
||||
with `!') access.
|
||||
If
|
||||
.I username
|
||||
doesn't match a previous group and doesn't begin with `@', the users
|
||||
will be recorded with (or without, if prefixed with `!') access.
|
||||
If the null string (``""'') is used, any
|
||||
users previously defined for this group are removed.
|
||||
.RE
|
||||
|
@ -1,5 +1,5 @@
|
||||
.\" $Id: conserver.passwd.man,v 1.10 2004/01/08 16:12:33 bryan Exp $
|
||||
.TH CONSERVER.PASSWD 5 "2004/01/08" "conserver-8.1.3" "conserver"
|
||||
.TH CONSERVER.PASSWD 5 "2004/01/08" "conserver-8.1.5" "conserver"
|
||||
.SH NAME
|
||||
conserver.passwd \- user access information for
|
||||
.BR conserver (8)
|
||||
|
@ -181,11 +181,11 @@
|
||||
|
||||
<H3>Downloading</H3>
|
||||
|
||||
<P>The current version, released on Mar 22, 2004, is <A
|
||||
href="8.1.3.tar.gz">8.1.3.tar.gz</A>. You can get it via
|
||||
<P>The current version, released on May 7, 2004, is <A
|
||||
href="8.1.5.tar.gz">8.1.5.tar.gz</A>. You can get it via
|
||||
<A href=
|
||||
"ftp://ftp.conserver.com/conserver/8.1.3.tar.gz">FTP</A>
|
||||
or <A href="8.1.3.tar.gz">HTTP</A>. See the <A href=
|
||||
"ftp://ftp.conserver.com/conserver/8.1.5.tar.gz">FTP</A>
|
||||
or <A href="8.1.5.tar.gz">HTTP</A>. See the <A href=
|
||||
"CHANGES">CHANGES</A> file for information on the latest
|
||||
updates.</P>
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: client.c,v 5.81 2004/03/20 14:40:40 bryan Exp $
|
||||
* $Id: client.c,v 5.83 2004/04/13 18:12:00 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -315,8 +315,7 @@ Replay(pCE, fdOut, iBack)
|
||||
if ((char *)0 != s) {
|
||||
*s = '\000';
|
||||
}
|
||||
FileWrite(fdOut, FLAGTRUE, lines[i].line->string,
|
||||
lines[i].line->used - 1);
|
||||
FileWrite(fdOut, FLAGTRUE, lines[i].line->string, -1);
|
||||
FileWrite(fdOut, FLAGTRUE, " .. ", 4);
|
||||
|
||||
/* build the end string by removing the leading "[-- MARK -- "
|
||||
@ -488,15 +487,31 @@ ClientAccessOk(pCL)
|
||||
#endif
|
||||
{
|
||||
char *peername = (char *)0;
|
||||
int retval = 1;
|
||||
|
||||
#if USE_UNIX_DOMAIN_SOCKETS
|
||||
struct in_addr addr;
|
||||
|
||||
# if HAVE_INET_ATON
|
||||
inet_aton("127.0.0.1", &addr);
|
||||
# else
|
||||
addr.s_addr = inet_addr("127.0.0.1");
|
||||
# endif
|
||||
pCL->caccess = AccType(&addr, &peername);
|
||||
if (pCL->caccess == 'r') {
|
||||
FileWrite(pCL->fd, FLAGFALSE, "access from your host refused\r\n",
|
||||
-1);
|
||||
retval = 0;
|
||||
}
|
||||
#else
|
||||
socklen_t so;
|
||||
int cfd;
|
||||
struct sockaddr_in in_port;
|
||||
int retval = 1;
|
||||
int getpeer = -1;
|
||||
|
||||
cfd = FileFDNum(pCL->fd);
|
||||
pCL->caccess = 'r';
|
||||
#if defined(USE_LIBWRAP)
|
||||
# if defined(USE_LIBWRAP)
|
||||
{
|
||||
struct request_info request;
|
||||
request_init(&request, RQ_DAEMON, progname, RQ_FILE, cfd, 0);
|
||||
@ -508,7 +523,7 @@ ClientAccessOk(pCL)
|
||||
goto setpeer;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
|
||||
so = sizeof(in_port);
|
||||
if (-1 ==
|
||||
@ -523,16 +538,22 @@ ClientAccessOk(pCL)
|
||||
-1);
|
||||
retval = 0;
|
||||
}
|
||||
|
||||
setpeer:
|
||||
#endif
|
||||
|
||||
if (pCL->peername != (STRING *)0) {
|
||||
BuildString((char *)0, pCL->peername);
|
||||
if (peername != (char *)0)
|
||||
BuildString(peername, pCL->peername);
|
||||
#if USE_UNIX_DOMAIN_SOCKETS
|
||||
else
|
||||
BuildString("127.0.0.1", pCL->peername);
|
||||
#else
|
||||
else if (getpeer != -1)
|
||||
BuildString(inet_ntoa(in_port.sin_addr), pCL->peername);
|
||||
else
|
||||
BuildString("<unknown>", pCL->peername);
|
||||
#endif
|
||||
}
|
||||
if (peername != (char *)0)
|
||||
free(peername);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: consent.c,v 5.137 2004/02/20 14:58:13 bryan Exp $
|
||||
* $Id: consent.c,v 5.138 2004/04/16 16:58:09 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -817,7 +817,7 @@ ConsInit(pCE)
|
||||
break;
|
||||
case DEVICE:
|
||||
if (-1 ==
|
||||
(cofile = open(pCE->device, O_RDWR | O_NDELAY, 0600))) {
|
||||
(cofile = open(pCE->device, O_RDWR | O_NONBLOCK, 0600))) {
|
||||
|
||||
Error("[%s] open(%s): %s: forcing down", pCE->server,
|
||||
pCE->device, strerror(errno));
|
||||
|
@ -1,6 +1,6 @@
|
||||
.\" @(#)conserver.8 01/06/91 OSU CIS; Thomas A. Fine
|
||||
.\" $Id: conserver.man,v 1.43 2004/03/23 01:02:29 bryan Exp $
|
||||
.TH CONSERVER 8 "2004/03/23" "conserver-8.1.3" "conserver"
|
||||
.\" $Id: conserver.man,v 1.46 2004/04/13 18:19:26 bryan Exp $
|
||||
.TH CONSERVER 8 "2004/04/13" "conserver-8.1.5" "conserver"
|
||||
.SH NAME
|
||||
conserver \- console server daemon
|
||||
.SH SYNOPSIS
|
||||
@ -11,7 +11,7 @@ conserver \- console server daemon
|
||||
.RB [ \-m
|
||||
.IR max ]
|
||||
.RB [ \-M
|
||||
.IR addr ]
|
||||
.IR master ]
|
||||
.RB [ \-p
|
||||
.IR port ]
|
||||
.RB [ \-b
|
||||
@ -50,7 +50,7 @@ knowledge of the distribution of consoles among servers.)
|
||||
.B Conserver
|
||||
forks a child for each group of consoles it must manage
|
||||
and assigns each process a port number to listen on.
|
||||
The maximum number of consoles managed by each child process is set using
|
||||
The maximum number of consoles managed by each child process is set using the
|
||||
.B \-m
|
||||
option.
|
||||
The
|
||||
@ -76,14 +76,31 @@ the
|
||||
.BR conserver.cf (5)
|
||||
access list.
|
||||
.PP
|
||||
When Unix domain sockets are used between the client and
|
||||
server (enabled using
|
||||
.BR --with-uds ),
|
||||
authentication checks are done on the hardcoded address ``127.0.0.1''.
|
||||
Automatic client redirection is also disabled (as if the
|
||||
.B \-R
|
||||
option was used) since the client cannot communicate with remote servers.
|
||||
The directory used to hold the sockets is checked to make sure it's empty
|
||||
when the server starts.
|
||||
The server will
|
||||
.B not
|
||||
remove any files in the directory itself, just in case the directory is
|
||||
accidentally specified as ``/etc'' or some other critical location.
|
||||
The server will do it's best to remove all the sockets when it shuts down,
|
||||
but it could stop ungracefully (crash, ``kill -9'', etc)
|
||||
and leave files behind.
|
||||
It's would then be up to the admin (or a creative startup script) to clean
|
||||
up the directory before the server will start again.
|
||||
.PP
|
||||
.B Conserver
|
||||
completely controls any connection to a console.
|
||||
All escape sequences given by the user to
|
||||
.B console
|
||||
are passed to the server without interpretation.
|
||||
The server recognizes and processes all escape sequences,
|
||||
The suspend sequence is recognized by the server and sent back to the
|
||||
client as a TCP out-of-band command, which the client processes.
|
||||
The server recognizes and processes all escape sequences.
|
||||
.PP
|
||||
The
|
||||
.B conserver
|
||||
@ -217,7 +234,7 @@ option.
|
||||
.B \-d
|
||||
Become a daemon.
|
||||
Disconnects from the controlling terminal and sends
|
||||
all output to the logfile (see
|
||||
all output (including any debug output) to the logfile (see
|
||||
.BR \-L ).
|
||||
.TP
|
||||
.B \-D
|
||||
@ -271,11 +288,20 @@ may be changed at compile time using the
|
||||
.B --with-maxmemb
|
||||
option.
|
||||
.TP
|
||||
.BI \-M addr
|
||||
Set the address to listen on.
|
||||
This allows conserver to bind to a
|
||||
.BI \-M master
|
||||
Normally, this allows conserver to bind to a
|
||||
particular IP address (like `127.0.0.1') instead of all interfaces.
|
||||
The default is to bind to all addresses.
|
||||
However, if
|
||||
.B --with-uds
|
||||
was used to enable Unix domain sockets for client/server communication,
|
||||
this points conserver to the directory where it should store the sockets.
|
||||
The default
|
||||
.IR master
|
||||
directory, ``/tmp/conserver'',
|
||||
may be changed at compile time using the
|
||||
.B --with-uds
|
||||
option.
|
||||
.TP
|
||||
.B \-n
|
||||
Obsolete (now a no-op); see
|
||||
@ -301,6 +327,9 @@ The default
|
||||
may be changed at compile time using the
|
||||
.B --with-port
|
||||
option.
|
||||
If the
|
||||
.B --with-uds
|
||||
option was used, this option is ignored.
|
||||
.TP
|
||||
.BI \-P passwd
|
||||
Read the table of authorized user data from the file
|
||||
@ -443,6 +472,9 @@ the master conserver process ID
|
||||
.TP
|
||||
.B /var/log/conserver
|
||||
log of errors and informational messages
|
||||
.TP
|
||||
.B /tmp/conserver
|
||||
directory to hold Unix domain sockets (if enabled)
|
||||
.PD
|
||||
.PP
|
||||
Additionally, output from individual consoles may be logged
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: fallback.c,v 5.60 2003/11/20 13:56:38 bryan Exp $
|
||||
* $Id: fallback.c,v 5.61 2004/04/16 16:58:09 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -210,7 +210,7 @@ GetPseudoTTY(slave, slaveFD)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (0 > (fd = open(acMaster, O_RDWR | O_NDELAY, 0))) {
|
||||
if (0 > (fd = open(acMaster, O_RDWR | O_NONBLOCK, 0))) {
|
||||
continue;
|
||||
}
|
||||
acSlave[iIndex] = *pcOne;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: group.c,v 5.291 2004/03/16 04:17:31 bryan Exp $
|
||||
* $Id: group.c,v 5.298 2004/05/07 15:39:51 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -901,6 +901,75 @@ FlagReUp(sig)
|
||||
#endif
|
||||
}
|
||||
|
||||
static struct delay {
|
||||
char *host;
|
||||
time_t last;
|
||||
struct delay *next;
|
||||
} *delays = (struct delay *)0;
|
||||
|
||||
/* returns zero if the delay has been reached, otherwise returns
|
||||
* the time when the next init should happen
|
||||
*/
|
||||
static time_t
|
||||
#if PROTOTYPES
|
||||
InitDelay(CONSENT *pCE)
|
||||
#else
|
||||
InitDelay(pCE)
|
||||
CONSENT *pCE;
|
||||
#endif
|
||||
{
|
||||
char *l;
|
||||
struct delay *d;
|
||||
|
||||
if (pCE->host != (char *)0)
|
||||
l = pCE->host;
|
||||
else
|
||||
l = "";
|
||||
|
||||
for (d = delays; d != (struct delay *)0; d = d->next) {
|
||||
if (strcmp(l, d->host) == 0) {
|
||||
if ((time((time_t *)0) - d->last) >= config->initdelay) {
|
||||
return (time_t)0;
|
||||
} else
|
||||
return d->last + config->initdelay;
|
||||
}
|
||||
}
|
||||
return (time_t)0;
|
||||
}
|
||||
|
||||
static void
|
||||
#if PROTOTYPES
|
||||
UpdateDelay(CONSENT *pCE)
|
||||
#else
|
||||
UpdateDelay(pCE)
|
||||
CONSENT *pCE;
|
||||
#endif
|
||||
{
|
||||
char *l;
|
||||
struct delay *d;
|
||||
|
||||
if (pCE->host != (char *)0)
|
||||
l = pCE->host;
|
||||
else
|
||||
l = "";
|
||||
|
||||
for (d = delays; d != (struct delay *)0; d = d->next) {
|
||||
if (strcmp(l, d->host) == 0) {
|
||||
d->last = time((time_t *)0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if ((d =
|
||||
(struct delay *)malloc(sizeof(struct delay))) ==
|
||||
(struct delay *)0)
|
||||
OutOfMem();
|
||||
if ((d->host = StrDup(l)) == (char *)0)
|
||||
OutOfMem();
|
||||
d->last = time((time_t *)0);
|
||||
d->next = delays;
|
||||
delays = d;
|
||||
}
|
||||
|
||||
static void
|
||||
#if PROTOTYPES
|
||||
ReUp(GRPENT *pGE, short automatic)
|
||||
@ -913,6 +982,9 @@ ReUp(pGE, automatic)
|
||||
CONSENT *pCE;
|
||||
int autoReUp;
|
||||
time_t tyme;
|
||||
short retry;
|
||||
static short autoup = 0;
|
||||
short wasAuto = 0;
|
||||
|
||||
if ((GRPENT *)0 == pGE)
|
||||
return;
|
||||
@ -924,19 +996,49 @@ ReUp(pGE, automatic)
|
||||
(!config->reinitcheck || (tyme < timers[T_REINIT])))
|
||||
return;
|
||||
|
||||
for (pCE = pGE->pCElist; pCE != (CONSENT *)0; pCE = pCE->pCEnext) {
|
||||
if (pCE->fup || pCE->ondemand == FLAGTRUE ||
|
||||
(automatic == 1 && !pCE->autoReUp))
|
||||
continue;
|
||||
autoReUp = pCE->autoReUp;
|
||||
if (automatic)
|
||||
Msg("[%s] automatic reinitialization", pCE->server);
|
||||
ConsInit(pCE);
|
||||
if (pCE->fup)
|
||||
FindWrite(pCE);
|
||||
else if (automatic)
|
||||
pCE->autoReUp = autoReUp;
|
||||
}
|
||||
if (automatic == -1)
|
||||
wasAuto = autoup;
|
||||
autoup = 0;
|
||||
|
||||
/* we loop here 'cause the init process could take a bit of time
|
||||
* (depending on how many things we init in the run through the
|
||||
* consoles) and we might be able to then initialize more stuff.
|
||||
* we'll eventually run through too fast, run out of consoles, or
|
||||
* have a big enough delay to go back to the main loop.
|
||||
*/
|
||||
do {
|
||||
retry = 0;
|
||||
for (pCE = pGE->pCElist; pCE != (CONSENT *)0; pCE = pCE->pCEnext) {
|
||||
short updateDelay = 0;
|
||||
|
||||
if (pCE->fup || pCE->ondemand == FLAGTRUE ||
|
||||
(automatic == 1 && !pCE->autoReUp))
|
||||
continue;
|
||||
if (config->initdelay > 0) {
|
||||
time_t t;
|
||||
if ((t = InitDelay(pCE)) > 0) {
|
||||
if (timers[T_INITDELAY] == (time_t)0 ||
|
||||
timers[T_INITDELAY] > t)
|
||||
timers[T_INITDELAY] = t;
|
||||
continue;
|
||||
} else {
|
||||
updateDelay = retry = 1;
|
||||
}
|
||||
}
|
||||
autoReUp = pCE->autoReUp;
|
||||
if (automatic > 0 || wasAuto) {
|
||||
Msg("[%s] automatic reinitialization", pCE->server);
|
||||
autoup = 1;
|
||||
}
|
||||
ConsInit(pCE);
|
||||
if (updateDelay)
|
||||
UpdateDelay(pCE);
|
||||
if (pCE->fup)
|
||||
FindWrite(pCE);
|
||||
else if (automatic > 0)
|
||||
pCE->autoReUp = autoReUp;
|
||||
}
|
||||
} while (retry);
|
||||
|
||||
/* update all the timers */
|
||||
if (automatic == 0 || automatic == 2) {
|
||||
@ -1255,7 +1357,7 @@ FlagReapVirt(sig)
|
||||
|
||||
/* on a TERM we have to cleanup utmp entries (ask ptyd to do it) (ksb)
|
||||
*/
|
||||
static void
|
||||
void
|
||||
#if PROTOTYPES
|
||||
DeUtmp(GRPENT *pGE, int sfd)
|
||||
#else
|
||||
@ -1265,7 +1367,14 @@ DeUtmp(pGE, sfd)
|
||||
#endif
|
||||
{
|
||||
CONSENT *pCE;
|
||||
#if USE_UNIX_DOMAIN_SOCKETS
|
||||
struct sockaddr_un lstn_port;
|
||||
socklen_t so;
|
||||
|
||||
so = sizeof(lstn_port);
|
||||
if (getsockname(sfd, (struct sockaddr *)&lstn_port, &so) != -1)
|
||||
unlink(lstn_port.sun_path);
|
||||
#endif
|
||||
/* shut down the socket */
|
||||
close(sfd);
|
||||
|
||||
@ -2703,7 +2812,7 @@ DoClientRead(pGE, pCLServing)
|
||||
"help this help message\r\n",
|
||||
"hosts show host status and user\r\n",
|
||||
"info show console information\r\n",
|
||||
"textmsg send a text message\r\n",
|
||||
"textmsg send a text message\r\n",
|
||||
"* = requires admin privileges\r\n",
|
||||
(char *)0
|
||||
};
|
||||
@ -4098,6 +4207,12 @@ Kiddie(pGE, sfd)
|
||||
time((time_t *)0) >= timers[T_MARK])
|
||||
Mark(pGE);
|
||||
|
||||
if (timers[T_INITDELAY] != (time_t)0 &&
|
||||
time((time_t *)0) >= timers[T_INITDELAY]) {
|
||||
timers[T_INITDELAY] = (time_t)0;
|
||||
ReUp(pGE, -1);
|
||||
}
|
||||
|
||||
if (timers[T_REINIT] != (time_t)0 &&
|
||||
time((time_t *)0) >= timers[T_REINIT])
|
||||
ReUp(pGE, 2);
|
||||
@ -4469,18 +4584,53 @@ Spawn(pGE)
|
||||
{
|
||||
pid_t pid;
|
||||
int sfd;
|
||||
#if USE_UNIX_DOMAIN_SOCKETS
|
||||
struct sockaddr_un lstn_port;
|
||||
static STRING *portPath = (STRING *)0;
|
||||
#else
|
||||
socklen_t so;
|
||||
struct sockaddr_in lstn_port;
|
||||
int true = 1;
|
||||
unsigned short portInc = 0;
|
||||
struct sockaddr_in lstn_port;
|
||||
#endif
|
||||
|
||||
/* get a socket for listening
|
||||
*/
|
||||
/* get a socket for listening */
|
||||
#if HAVE_MEMSET
|
||||
memset((void *)&lstn_port, 0, sizeof(lstn_port));
|
||||
#else
|
||||
bzero((char *)&lstn_port, sizeof(lstn_port));
|
||||
#endif
|
||||
|
||||
#if USE_UNIX_DOMAIN_SOCKETS
|
||||
lstn_port.sun_family = AF_UNIX;
|
||||
|
||||
if (portPath == (STRING *)0)
|
||||
portPath = AllocString();
|
||||
BuildStringPrint(portPath, "%s/%u", interface, pGE->id);
|
||||
if (portPath->used > sizeof(lstn_port.sun_path)) {
|
||||
Error("Spawn(): path to socket too long: %s", portPath->string);
|
||||
Bye(EX_OSERR);
|
||||
}
|
||||
strcpy(lstn_port.sun_path, portPath->string);
|
||||
|
||||
/* create a socket to listen on
|
||||
* (prepared by master so he can see the port number of the kid)
|
||||
*/
|
||||
if ((sfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
|
||||
Error("Spawn(): socket(): %s", strerror(errno));
|
||||
Bye(EX_OSERR);
|
||||
}
|
||||
|
||||
if (!SetFlags(sfd, O_NONBLOCK, 0))
|
||||
Bye(EX_OSERR);
|
||||
|
||||
if (bind(sfd, (struct sockaddr *)&lstn_port, sizeof(lstn_port)) < 0) {
|
||||
Error("Spawn(): bind(%s): %s", lstn_port.sun_path,
|
||||
strerror(errno));
|
||||
Bye(EX_OSERR);
|
||||
}
|
||||
pGE->port = pGE->id;
|
||||
#else
|
||||
lstn_port.sin_family = AF_INET;
|
||||
lstn_port.sin_addr.s_addr = bindAddr;
|
||||
lstn_port.sin_port = htons(bindBasePort);
|
||||
@ -4492,24 +4642,24 @@ Spawn(pGE)
|
||||
Error("Spawn(): socket(): %s", strerror(errno));
|
||||
Bye(EX_OSERR);
|
||||
}
|
||||
#if HAVE_SETSOCKOPT
|
||||
# if HAVE_SETSOCKOPT
|
||||
if (setsockopt
|
||||
(sfd, SOL_SOCKET, SO_REUSEADDR, (char *)&true, sizeof(true)) < 0) {
|
||||
Error("Spawn(): setsockopt(%u,SO_REUSEADDR): %s", sfd,
|
||||
strerror(errno));
|
||||
Bye(EX_OSERR);
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
|
||||
if (!SetFlags(sfd, O_NONBLOCK, 0))
|
||||
Bye(EX_OSERR);
|
||||
|
||||
while (bind(sfd, (struct sockaddr *)&lstn_port, sizeof(lstn_port)) < 0) {
|
||||
if (bindBasePort && (
|
||||
#if defined(EADDRINUSE)
|
||||
# if defined(EADDRINUSE)
|
||||
(errno == EADDRINUSE) ||
|
||||
#endif
|
||||
(errno == EACCES)) && portInc++) {
|
||||
# endif
|
||||
(errno == EACCES)) && ++portInc) {
|
||||
lstn_port.sin_port = htons(bindBasePort + portInc);
|
||||
} else {
|
||||
Error("Spawn(): bind(%hu): %s", ntohs(lstn_port.sin_port),
|
||||
@ -4524,6 +4674,7 @@ Spawn(pGE)
|
||||
Bye(EX_OSERR);
|
||||
}
|
||||
pGE->port = ntohs(lstn_port.sin_port);
|
||||
#endif
|
||||
|
||||
fflush(stderr);
|
||||
fflush(stdout);
|
||||
@ -4587,12 +4738,20 @@ Spawn(pGE)
|
||||
}
|
||||
|
||||
if (listen(sfd, SOMAXCONN) < 0) {
|
||||
#if USE_UNIX_DOMAIN_SOCKETS
|
||||
Error("Spawn(): listen(%s): %s", lstn_port.sun_path,
|
||||
strerror(errno));
|
||||
#else
|
||||
Error("Spawn(): listen(%hu): %s", pGE->port, strerror(errno));
|
||||
#endif
|
||||
Bye(EX_OSERR);
|
||||
}
|
||||
Kiddie(pGE, sfd);
|
||||
|
||||
/* should never get here...but on errors we could */
|
||||
close(sfd);
|
||||
#if USE_UNIX_DOMAIN_SOCKETS
|
||||
unlink(lstn_port.sun_path);
|
||||
#endif
|
||||
Bye(EX_SOFTWARE);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: group.h,v 5.43 2003/12/20 06:11:53 bryan Exp $
|
||||
* $Id: group.h,v 5.45 2004/05/07 03:42:49 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -41,7 +41,8 @@
|
||||
#define T_REINIT 3
|
||||
#define T_AUTOUP 4
|
||||
#define T_ROLL 5
|
||||
#define T_MAX 6 /* T_MAX *must* be last */
|
||||
#define T_INITDELAY 6
|
||||
#define T_MAX 7 /* T_MAX *must* be last */
|
||||
|
||||
/* return values used by CheckPass()
|
||||
*/
|
||||
@ -80,6 +81,7 @@ extern int ClientAccess PARAMS((CONSENT *, char *));
|
||||
extern void DestroyClient PARAMS((CONSCLIENT *));
|
||||
extern int CheckPasswd PARAMS((CONSCLIENT *, char *));
|
||||
extern void ExpandString PARAMS((char *, CONSENT *, short));
|
||||
extern void DeUtmp PARAMS((GRPENT *, int));
|
||||
#if HAVE_OPENSSL
|
||||
extern int AttemptSSL PARAMS((CONSCLIENT *));
|
||||
#endif
|
||||
|
153
conserver/main.c
153
conserver/main.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: main.c,v 5.178 2004/03/11 16:23:59 bryan Exp $
|
||||
* $Id: main.c,v 5.180 2004/05/07 03:42:49 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -41,6 +41,7 @@
|
||||
#include <version.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <dirent.h>
|
||||
#if HAVE_SYS_SOCKIO_H
|
||||
# include <sys/sockio.h>
|
||||
#endif
|
||||
@ -64,8 +65,7 @@ CONFIG *config = (CONFIG *)0;
|
||||
char *interface = (char *)0;
|
||||
CONFIG defConfig =
|
||||
{ (STRING *)0, 'r', FLAGFALSE, LOGFILEPATH, PASSWDFILE, DEFPORT,
|
||||
FLAGTRUE,
|
||||
FLAGTRUE, 0, DEFBASEPORT, (char *)0
|
||||
FLAGTRUE, FLAGTRUE, 0, DEFBASEPORT, (char *)0, 0
|
||||
#if HAVE_SETPROCTITLE
|
||||
, FLAGFALSE
|
||||
#endif
|
||||
@ -523,7 +523,7 @@ Usage(wantfull)
|
||||
#endif
|
||||
{
|
||||
static char u_terse[] =
|
||||
"[-7dDEFhinoRSuvV] [-a type] [-m max] [-M addr] [-p port] [-b port] [-c cred] [-C config] [-P passwd] [-L logfile] [-O min] [-U logfile]";
|
||||
"[-7dDEFhinoRSuvV] [-a type] [-m max] [-M master] [-p port] [-b port] [-c cred] [-C config] [-P passwd] [-L logfile] [-O min] [-U logfile]";
|
||||
static char *full[] = {
|
||||
"7 strip the high bit off all console data",
|
||||
"a type set the default access type",
|
||||
@ -546,11 +546,19 @@ Usage(wantfull)
|
||||
"i initialize console connections on demand",
|
||||
"L logfile give a new logfile path to the server process",
|
||||
"m max maximum consoles managed per process",
|
||||
"M addr address to listen on (all addresses by default)",
|
||||
#if USE_UNIX_DOMAIN_SOCKETS
|
||||
"M master directory that holds the Unix domain sockets",
|
||||
#else
|
||||
"M master address to listen on (all addresses by default)",
|
||||
#endif
|
||||
"n obsolete - see -u",
|
||||
"o reopen downed console on client connect",
|
||||
"O min reopen all downed consoles every <min> minutes",
|
||||
#if USE_UNIX_DOMAIN_SOCKETS
|
||||
"p port ignored - Unix domain sockets compiled into code",
|
||||
#else
|
||||
"p port port to listen on",
|
||||
#endif
|
||||
"P passwd give a new passwd file to the server process",
|
||||
"R disable automatic client redirection",
|
||||
"S syntax check of configuration file",
|
||||
@ -616,9 +624,13 @@ Version()
|
||||
Msg("default pidfile is `%s'", PIDFILE);
|
||||
Msg("default limit is %d member%s per group", MAXMEMB,
|
||||
MAXMEMB == 1 ? "" : "s");
|
||||
#if USE_UNIX_DOMAIN_SOCKETS
|
||||
Msg("default socket directory `%s'", UDSDIR);
|
||||
#else
|
||||
Msg("default primary port referenced as `%s'", defConfig.primaryport);
|
||||
Msg("default secondary base port referenced as `%s'",
|
||||
defConfig.secondaryport);
|
||||
#endif
|
||||
|
||||
BuildString((char *)0, acA1);
|
||||
if (optionlist[0] == (char *)0)
|
||||
@ -1153,6 +1165,94 @@ ProbeInterfaces()
|
||||
#endif
|
||||
}
|
||||
|
||||
/* This makes sure a directory exists and tries to create it if it
|
||||
* doesn't. returns 0 for success, -1 for error
|
||||
*/
|
||||
#if USE_UNIX_DOMAIN_SOCKETS
|
||||
int
|
||||
#if PROTOTYPES
|
||||
VerifyEmptyDirectory(char *d)
|
||||
#else
|
||||
VerifyEmptyDirectory(d)
|
||||
char *d;
|
||||
#endif
|
||||
{
|
||||
struct stat dstat;
|
||||
DIR *dir;
|
||||
struct dirent *de;
|
||||
STRING *path = (STRING *)0;
|
||||
int retval = 0;
|
||||
|
||||
while (1) {
|
||||
if (stat(d, &dstat) == -1) {
|
||||
if (errno == ENOENT) {
|
||||
if (mkdir(d, 0755) == -1) {
|
||||
Error("mkdir(%s): %s", d, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
CONDDEBUG((1, "VerifyEmptyDirectory: created `%s'", d));
|
||||
continue;
|
||||
} else {
|
||||
Error("stat(%s): %s", d, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (S_ISDIR(dstat.st_mode))
|
||||
break;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* now make sure it's empty...erase anything you see, etc */
|
||||
if ((dir = opendir(d)) == (DIR *) 0) {
|
||||
Error("opendir(%s): %s", d, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
while ((de = readdir(dir)) != (struct dirent *)0) {
|
||||
if ((strcmp(de->d_name, ".") == 0) ||
|
||||
(strcmp(de->d_name, "..") == 0))
|
||||
continue;
|
||||
/* we're going to just let the user deal with non-empty directories */
|
||||
Error("non-empty directory `%s'", d);
|
||||
retval = -1;
|
||||
break;
|
||||
/* this is probably too extreme. if someone happens to point conserver
|
||||
* at /etc, for example, it could (if running as root) nuke the password
|
||||
* database, config files, etc. too many important files could be
|
||||
* shredded with a small typo.
|
||||
*/
|
||||
#if 0
|
||||
if (path == (STRING *)0)
|
||||
path = AllocString();
|
||||
BuildStringPrint(path, "%s/%s", d, de->d_name);
|
||||
if (stat(path->string, &dstat) == -1) {
|
||||
Error("stat(%s): %s", path->string, strerror(errno));
|
||||
retval = -1;
|
||||
break;
|
||||
}
|
||||
if (S_ISDIR(dstat.st_mode)) {
|
||||
if (rmdir(path->string) != 0) {
|
||||
Error("rmdir(%s): %s", path->string, strerror(errno));
|
||||
retval = -1;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (unlink(path->string) != 0) {
|
||||
Error("unlink(%s): %s", path->string, strerror(errno));
|
||||
retval = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (path != (STRING *)0)
|
||||
DestroyString(path);
|
||||
|
||||
return retval;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* find out where/who we are (ksb)
|
||||
* parse optons
|
||||
* read in the config file, open the log file
|
||||
@ -1180,8 +1280,10 @@ main(argc, argv)
|
||||
char *curuser = (char *)0;
|
||||
int curuid = 0;
|
||||
GRPENT *pGE = (GRPENT *)0;
|
||||
#if !USE_UNIX_DOMAIN_SOCKETS
|
||||
#if HAVE_INET_ATON
|
||||
struct in_addr inetaddr;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
isMultiProc = 1; /* make sure stuff has the pid */
|
||||
@ -1379,34 +1481,43 @@ main(argc, argv)
|
||||
if (fSyntaxOnly)
|
||||
Msg("performing configuration file syntax check");
|
||||
|
||||
#if USE_UNIX_DOMAIN_SOCKETS
|
||||
/* Don't do any redirects if we're purely local
|
||||
* (but it allows them to see where remote consoles are)
|
||||
*/
|
||||
optConf->redirect = FLAGFALSE;
|
||||
if (interface == (char *)0)
|
||||
interface = UDSDIR;
|
||||
#else
|
||||
/* set up the address to bind to */
|
||||
if (interface == (char *)0 ||
|
||||
(interface[0] == '*' && interface[1] == '\000'))
|
||||
bindAddr = INADDR_ANY;
|
||||
else {
|
||||
#if HAVE_INET_ATON
|
||||
# if HAVE_INET_ATON
|
||||
if (inet_aton(interface, &inetaddr) == 0) {
|
||||
Error("inet_aton(%s): %s", interface, "invalid IP address");
|
||||
Bye(EX_OSERR);
|
||||
}
|
||||
bindAddr = inetaddr.s_addr;
|
||||
#else
|
||||
# else
|
||||
bindAddr = inet_addr(interface);
|
||||
if (bindAddr == (in_addr_t) (-1)) {
|
||||
Error("inet_addr(%s): %s", interface, "invalid IP address");
|
||||
Bye(EX_OSERR);
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
if (fDebug) {
|
||||
struct in_addr ba;
|
||||
ba.s_addr = bindAddr;
|
||||
CONDDEBUG((1, "main(): bind address set to `%s'", inet_ntoa(ba)));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* must do all this so IsMe() works right */
|
||||
if (gethostname(myHostname, MAXHOSTNAME) != 0) {
|
||||
Error("gethostname(): %s", interface, strerror(errno));
|
||||
Error("gethostname(): %s", strerror(errno));
|
||||
Bye(EX_OSERR);
|
||||
}
|
||||
ProbeInterfaces();
|
||||
@ -1423,6 +1534,7 @@ main(argc, argv)
|
||||
ReadCfg(pcConfig, fpConfig);
|
||||
fclose(fpConfig);
|
||||
|
||||
#if !USE_UNIX_DOMAIN_SOCKETS
|
||||
/* set up the port to bind to */
|
||||
if (optConf->primaryport != (char *)0)
|
||||
config->primaryport = StrDup(optConf->primaryport);
|
||||
@ -1482,6 +1594,7 @@ main(argc, argv)
|
||||
bindBasePort = ntohs((unsigned short)pSE->s_port);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (optConf->passwdfile != (char *)0)
|
||||
config->passwdfile = StrDup(optConf->passwdfile);
|
||||
@ -1549,6 +1662,14 @@ main(argc, argv)
|
||||
if (config->unifiedlog == (char *)0)
|
||||
OutOfMem();
|
||||
}
|
||||
|
||||
if (optConf->initdelay != 0)
|
||||
config->initdelay = optConf->initdelay;
|
||||
else if (pConfig->initdelay != 0)
|
||||
config->initdelay = pConfig->initdelay;
|
||||
else
|
||||
config->initdelay = defConfig.initdelay;
|
||||
|
||||
#if HAVE_OPENSSL
|
||||
if (optConf->sslrequired != FLAGUNKNOWN)
|
||||
config->sslrequired = optConf->sslrequired;
|
||||
@ -1580,7 +1701,13 @@ main(argc, argv)
|
||||
|
||||
if (pGroups == (GRPENT *)0 && pRCList == (REMOTE *)0) {
|
||||
Error("no consoles found in configuration file");
|
||||
} else if (!fSyntaxOnly) {
|
||||
} else if (fSyntaxOnly) {
|
||||
/* short-circuit */
|
||||
#if USE_UNIX_DOMAIN_SOCKETS
|
||||
} else if (VerifyEmptyDirectory(interface) == -1) {
|
||||
Error("Master(): %s: unusable socket directory", interface);
|
||||
#endif
|
||||
} else {
|
||||
#if HAVE_OPENSSL
|
||||
/* Prep the SSL layer */
|
||||
SetupSSL();
|
||||
@ -1603,7 +1730,6 @@ main(argc, argv)
|
||||
continue;
|
||||
|
||||
Spawn(pGE);
|
||||
|
||||
Verbose("group #%d pid %lu on port %hu", pGE->id,
|
||||
(unsigned long)pGE->pid, pGE->port);
|
||||
}
|
||||
@ -1617,8 +1743,13 @@ main(argc, argv)
|
||||
local += pGE->imembers;
|
||||
for (pRC = pRCList; (REMOTE *)0 != pRC; pRC = pRC->pRCnext)
|
||||
remote++;
|
||||
# if USE_UNIX_DOMAIN_SOCKETS
|
||||
setproctitle("master: port 0, %d local, %d remote", local,
|
||||
remote);
|
||||
#else
|
||||
setproctitle("master: port %hu, %d local, %d remote", bindPort,
|
||||
local, remote);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: main.h,v 5.51 2003/11/10 15:37:24 bryan Exp $
|
||||
* $Id: main.h,v 5.52 2004/04/13 18:12:00 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -49,6 +49,9 @@ extern CONFIG *optConf;
|
||||
extern CONFIG *config;
|
||||
extern CONFIG defConfig;
|
||||
extern CONSFILE *unifiedlog;
|
||||
#if USE_UNIX_DOMAIN_SOCKETS
|
||||
extern char *interface;
|
||||
#endif
|
||||
#if HAVE_OPENSSL
|
||||
extern SSL_CTX *ctx;
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: master.c,v 5.124 2003/12/25 19:22:00 bryan Exp $
|
||||
* $Id: master.c,v 5.126 2004/05/06 02:09:07 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -569,6 +569,10 @@ DoNormalRead(pCLServing)
|
||||
int iSep = 1;
|
||||
|
||||
if ((GRPENT *)0 != pGroups) {
|
||||
#if USE_UNIX_DOMAIN_SOCKETS
|
||||
FilePrint(pCLServing->fd, FLAGTRUE, "@0");
|
||||
iSep = 0;
|
||||
#else
|
||||
struct sockaddr_in lcl;
|
||||
socklen_t so = sizeof(lcl);
|
||||
if (-1 ==
|
||||
@ -579,22 +583,26 @@ DoNormalRead(pCLServing)
|
||||
-1);
|
||||
Error("Master(): getsockname(%u): %s",
|
||||
FileFDNum(pCLServing->fd), strerror(errno));
|
||||
Bye(EX_OSERR);
|
||||
}
|
||||
FilePrint(pCLServing->fd, FLAGTRUE, "@%s",
|
||||
inet_ntoa(lcl.sin_addr));
|
||||
iSep = 0;
|
||||
}
|
||||
if (config->redirect == FLAGTRUE) {
|
||||
REMOTE *pRC;
|
||||
for (pRC = pRCUniq; (REMOTE *)0 != pRC;
|
||||
pRC = pRC->pRCuniq) {
|
||||
FilePrint(pCLServing->fd, FLAGTRUE, ":@%s" + iSep,
|
||||
pRC->rhost);
|
||||
iSep = -1;
|
||||
} else {
|
||||
FilePrint(pCLServing->fd, FLAGTRUE, "@%s",
|
||||
inet_ntoa(lcl.sin_addr));
|
||||
iSep = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (iSep >= 0) {
|
||||
if (config->redirect == FLAGTRUE) {
|
||||
REMOTE *pRC;
|
||||
for (pRC = pRCUniq; (REMOTE *)0 != pRC;
|
||||
pRC = pRC->pRCuniq) {
|
||||
FilePrint(pCLServing->fd, FLAGTRUE,
|
||||
":@%s" + iSep, pRC->rhost);
|
||||
iSep = 0;
|
||||
}
|
||||
}
|
||||
FileWrite(pCLServing->fd, FLAGFALSE, "\r\n", -1);
|
||||
}
|
||||
FileWrite(pCLServing->fd, FLAGFALSE, "\r\n", -1);
|
||||
} else if (pCLServing->iState == S_NORMAL &&
|
||||
strcmp(pcCmd, "pid") == 0) {
|
||||
FilePrint(pCLServing->fd, FLAGFALSE, "%lu\r\n",
|
||||
@ -673,8 +681,13 @@ Master()
|
||||
int msfd;
|
||||
socklen_t so;
|
||||
fd_set rmask, wmask;
|
||||
#if USE_UNIX_DOMAIN_SOCKETS
|
||||
struct sockaddr_un master_port;
|
||||
static STRING *portPath = (STRING *)0;
|
||||
#else
|
||||
struct sockaddr_in master_port;
|
||||
int true = 1;
|
||||
#endif
|
||||
FILE *fp;
|
||||
CONSCLIENT *pCLServing = (CONSCLIENT *)0;
|
||||
CONSCLIENT *pCL = (CONSCLIENT *)0;
|
||||
@ -715,6 +728,40 @@ Master()
|
||||
#else
|
||||
bzero((char *)&master_port, sizeof(master_port));
|
||||
#endif
|
||||
|
||||
#if USE_UNIX_DOMAIN_SOCKETS
|
||||
master_port.sun_family = AF_UNIX;
|
||||
|
||||
if (portPath == (STRING *)0)
|
||||
portPath = AllocString();
|
||||
BuildStringPrint(portPath, "%s/0", interface);
|
||||
if (portPath->used > sizeof(master_port.sun_path)) {
|
||||
Error("Master(): path to socket too long: %s", portPath->string);
|
||||
return;
|
||||
}
|
||||
strcpy(master_port.sun_path, portPath->string);
|
||||
|
||||
if ((msfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
|
||||
Error("Master(): socket(AF_UNIX,SOCK_STREAM): %s",
|
||||
strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!SetFlags(msfd, O_NONBLOCK, 0))
|
||||
return;
|
||||
|
||||
if (bind(msfd, (struct sockaddr *)&master_port, sizeof(master_port)) <
|
||||
0) {
|
||||
Error("Master(): bind(%s): %s", master_port.sun_path,
|
||||
strerror(errno));
|
||||
return;
|
||||
}
|
||||
if (listen(msfd, SOMAXCONN) < 0) {
|
||||
Error("Master(): listen(%s): %s", master_port.sun_path,
|
||||
strerror(errno));
|
||||
return;
|
||||
}
|
||||
#else
|
||||
master_port.sin_family = AF_INET;
|
||||
master_port.sin_addr.s_addr = bindAddr;
|
||||
master_port.sin_port = htons(bindPort);
|
||||
@ -724,7 +771,7 @@ Master()
|
||||
strerror(errno));
|
||||
return;
|
||||
}
|
||||
#if HAVE_SETSOCKOPT
|
||||
# if HAVE_SETSOCKOPT
|
||||
if (setsockopt
|
||||
(msfd, SOL_SOCKET, SO_REUSEADDR, (char *)&true,
|
||||
sizeof(true)) < 0) {
|
||||
@ -732,7 +779,7 @@ Master()
|
||||
strerror(errno));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
# endif
|
||||
|
||||
if (!SetFlags(msfd, O_NONBLOCK, 0))
|
||||
return;
|
||||
@ -748,6 +795,7 @@ Master()
|
||||
strerror(errno));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
fp = fopen(PIDFILE, "w");
|
||||
if (fp) {
|
||||
@ -943,6 +991,9 @@ Master()
|
||||
}
|
||||
|
||||
close(msfd);
|
||||
#if USE_UNIX_DOMAIN_SOCKETS
|
||||
unlink(master_port.sun_path);
|
||||
#endif
|
||||
|
||||
/* clean up the free list */
|
||||
while (pCLmfree != (CONSCLIENT *)0) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: readcfg.c,v 5.168 2004/03/11 16:23:59 bryan Exp $
|
||||
* $Id: readcfg.c,v 5.173 2004/05/07 03:42:49 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -25,6 +25,8 @@
|
||||
|
||||
#include <compat.h>
|
||||
|
||||
#include <grp.h>
|
||||
|
||||
#include <cutil.h>
|
||||
#include <consent.h>
|
||||
#include <client.h>
|
||||
@ -143,7 +145,7 @@ int isStartup = 0;
|
||||
GRPENT *pGroupsOld = (GRPENT *)0;
|
||||
GRPENT *pGEstage = (GRPENT *)0;
|
||||
GRPENT *pGE = (GRPENT *)0;
|
||||
static unsigned int groupID = 0;
|
||||
static unsigned int groupID = 1;
|
||||
REMOTE **ppRC = (REMOTE **)0;
|
||||
|
||||
/* 'break' handling */
|
||||
@ -530,14 +532,26 @@ GroupItemUsers(id)
|
||||
|
||||
for (token = strtok(id, ALLWORDSEP); token != (char *)0;
|
||||
token = strtok(NULL, ALLWORDSEP)) {
|
||||
int not;
|
||||
short not;
|
||||
if (token[0] == '!') {
|
||||
token++;
|
||||
not = 1;
|
||||
} else
|
||||
not = 0;
|
||||
if ((pg = GroupFind(token)) == (PARSERGROUP *)0) {
|
||||
GroupAddUser(parserGroupTemp, token, not);
|
||||
if (token[0] == '@' && token[1] != '\000') {
|
||||
struct group *g;
|
||||
if ((g = getgrnam(token + 1)) == (struct group *)0) {
|
||||
if (isMaster)
|
||||
Error("unknown group name `%s': %s [%s:%d]",
|
||||
token + 1, strerror(errno), file, line);
|
||||
} else if (g->gr_mem != (char **)0) {
|
||||
char **m;
|
||||
for (m = g->gr_mem; *m != (char *)0; m++)
|
||||
GroupAddUser(parserGroupTemp, *m, not);
|
||||
}
|
||||
} else
|
||||
GroupAddUser(parserGroupTemp, token, not);
|
||||
} else {
|
||||
PARSERGROUPUSERS *pgu;
|
||||
for (pgu = pg->users; pgu != (PARSERGROUPUSERS *)0;
|
||||
@ -1946,7 +1960,19 @@ ProcessRoRw(ppCU, id)
|
||||
} else
|
||||
not = 0;
|
||||
if ((pg = GroupFind(token)) == (PARSERGROUP *)0) {
|
||||
ConsentAddUser(ppCU, token, not);
|
||||
if (token[0] == '@' && token[1] != '\000') {
|
||||
struct group *g;
|
||||
if ((g = getgrnam(token + 1)) == (struct group *)0) {
|
||||
if (isMaster)
|
||||
Error("unknown group name `%s': %s [%s:%d]",
|
||||
token + 1, strerror(errno), file, line);
|
||||
} else if (g->gr_mem != (char **)0) {
|
||||
char **m;
|
||||
for (m = g->gr_mem; *m != (char *)0; m++)
|
||||
ConsentAddUser(ppCU, *m, not);
|
||||
}
|
||||
} else
|
||||
ConsentAddUser(ppCU, token, not);
|
||||
} else {
|
||||
PARSERGROUPUSERS *pgu;
|
||||
for (pgu = pg->users; pgu != (PARSERGROUPUSERS *)0;
|
||||
@ -3088,7 +3114,7 @@ ConsoleDestroy()
|
||||
parserConsoles = parserConsoleTemp = (CONSENT *)0;
|
||||
|
||||
/* here we check on the client permissions and adjust accordingly */
|
||||
if (!isMaster) {
|
||||
if (!isMaster && pGroups != (GRPENT *)0) {
|
||||
CONSENT *pCE = (CONSENT *)0;
|
||||
CONSCLIENT *pCL = (CONSCLIENT *)0;
|
||||
CONSCLIENT *pCLnext = (CONSCLIENT *)0;
|
||||
@ -4081,6 +4107,8 @@ ConfigEnd()
|
||||
pConfig->loghostnames = parserConfigTemp->loghostnames;
|
||||
if (parserConfigTemp->reinitcheck != 0)
|
||||
pConfig->reinitcheck = parserConfigTemp->reinitcheck;
|
||||
if (parserConfigTemp->initdelay != 0)
|
||||
pConfig->initdelay = parserConfigTemp->initdelay;
|
||||
if (parserConfigTemp->secondaryport != (char *)0) {
|
||||
if (pConfig->secondaryport != (char *)0)
|
||||
free(pConfig->secondaryport);
|
||||
@ -4335,6 +4363,36 @@ ConfigItemReinitcheck(id)
|
||||
parserConfigTemp->reinitcheck = atoi(id);
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ConfigItemInitdelay(char *id)
|
||||
#else
|
||||
ConfigItemInitdelay(id)
|
||||
char *id;
|
||||
#endif
|
||||
{
|
||||
char *p;
|
||||
|
||||
CONDDEBUG((1, "ConfigItemInitdelay(%s) [%s:%d]", id, file, line));
|
||||
|
||||
if ((id == (char *)0) || (*id == '\000')) {
|
||||
parserConfigTemp->initdelay = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
for (p = id; *p != '\000'; p++)
|
||||
if (!isdigit((int)(*p)))
|
||||
break;
|
||||
|
||||
/* if it wasn't a number or the number was zero */
|
||||
if (*p != '\000') {
|
||||
if (isMaster)
|
||||
Error("invalid initdelay value `%s' [%s:%d]", id, file, line);
|
||||
return;
|
||||
}
|
||||
parserConfigTemp->initdelay = atoi(id);
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ConfigItemSecondaryport(char *id)
|
||||
@ -4508,6 +4566,7 @@ ITEM keyAccess[] = {
|
||||
ITEM keyConfig[] = {
|
||||
{"defaultaccess", ConfigItemDefaultaccess},
|
||||
{"daemonmode", ConfigItemDaemonmode},
|
||||
{"initdelay", ConfigItemInitdelay},
|
||||
{"logfile", ConfigItemLogfile},
|
||||
{"loghostnames", ConfigItemLoghostnames},
|
||||
{"passwdfile", ConfigItemPasswordfile},
|
||||
@ -4575,7 +4634,8 @@ typedef enum tokens {
|
||||
LEFTBRACE,
|
||||
RIGHTBRACE,
|
||||
SEMICOLON,
|
||||
WORD
|
||||
WORD,
|
||||
INCLUDE
|
||||
} TOKEN;
|
||||
|
||||
TOKEN
|
||||
@ -4595,14 +4655,60 @@ GetWord(fp, line, spaceok, word)
|
||||
short comment = 0;
|
||||
short sawQuote = 0;
|
||||
short quotedBackslash = 0;
|
||||
char *include = "include";
|
||||
short checkInc = -1;
|
||||
/* checkInc == -3, saw #include
|
||||
* == -2, saw nothin'
|
||||
* == -1, saw \n or start of file
|
||||
* == 0, saw "\n#"
|
||||
*/
|
||||
|
||||
BuildString((char *)0, word);
|
||||
while ((c = fgetc(fp)) != EOF) {
|
||||
if (c == '\n')
|
||||
if (c == '\n') {
|
||||
(*line)++;
|
||||
if (checkInc == -2)
|
||||
checkInc = -1;
|
||||
}
|
||||
if (comment) {
|
||||
if (c == '\n')
|
||||
comment = 0;
|
||||
if (checkInc >= 0) {
|
||||
if (include[checkInc] == '\000') {
|
||||
if (isspace(c))
|
||||
checkInc = -3;
|
||||
} else if (c == include[checkInc])
|
||||
checkInc++;
|
||||
else
|
||||
checkInc = -2;
|
||||
} else if (checkInc == -3) {
|
||||
static STRING *fname = (STRING *)0;
|
||||
if (fname == (STRING *)0)
|
||||
fname = AllocString();
|
||||
if (fname->used != 0 || !isspace(c)) {
|
||||
if (c == '\n') {
|
||||
if (fname->used > 0) {
|
||||
while (fname->used > 1 && isspace((int)
|
||||
(fname->
|
||||
string
|
||||
[fname->
|
||||
used -
|
||||
2])))
|
||||
fname->used--;
|
||||
if (fname->used > 0)
|
||||
fname->string[fname->used - 1] = '\000';
|
||||
}
|
||||
checkInc = -2;
|
||||
if (fname->used > 0) {
|
||||
BuildString((char *)0, word);
|
||||
BuildString(fname->string, word);
|
||||
BuildString((char *)0, fname);
|
||||
return INCLUDE;
|
||||
}
|
||||
} else
|
||||
BuildStringChar(c, fname);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (backslash) {
|
||||
@ -4633,6 +4739,8 @@ GetWord(fp, line, spaceok, word)
|
||||
backslash = 1;
|
||||
} else if (c == '#') {
|
||||
comment = 1;
|
||||
if (checkInc == -1)
|
||||
checkInc = 0;
|
||||
} else if (c == '"') {
|
||||
quote = 1;
|
||||
sawQuote = 1;
|
||||
@ -4689,6 +4797,282 @@ GetWord(fp, line, spaceok, word)
|
||||
return DONE;
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ParseFile(char *filename, FILE *fp, int level)
|
||||
#else
|
||||
ParseFile(filename, fp, level)
|
||||
char *filename;
|
||||
FILE *fp;
|
||||
int level;
|
||||
#endif
|
||||
{
|
||||
/* things that should be used between recursions */
|
||||
static STATES state = START;
|
||||
static STRING *word = (STRING *)0;
|
||||
static short spaceok = 0;
|
||||
static int secIndex = 0;
|
||||
static int keyIndex = 0;
|
||||
|
||||
/* other stuff that's local to each recursion */
|
||||
char *p;
|
||||
TOKEN token = DONE;
|
||||
int nextline = 1; /* "next" line number */
|
||||
|
||||
if (level >= 10) {
|
||||
if (isMaster)
|
||||
Error("ParseFile(): nesting too deep, not parsing `%s'",
|
||||
filename);
|
||||
return;
|
||||
}
|
||||
|
||||
/* set some globals */
|
||||
line = 1;
|
||||
file = filename;
|
||||
|
||||
/* if we're parsing the base file, set static vars */
|
||||
if (level == 0) {
|
||||
state = START;
|
||||
spaceok = 0;
|
||||
secIndex = 0;
|
||||
keyIndex = 0;
|
||||
}
|
||||
|
||||
/* initialize local things */
|
||||
if (word == (STRING *)0)
|
||||
word = AllocString();
|
||||
|
||||
while ((token = GetWord(fp, &nextline, spaceok, word)) != DONE) {
|
||||
if (token == INCLUDE) {
|
||||
FILE *lfp;
|
||||
if ((FILE *)0 == (lfp = fopen(word->string, "r"))) {
|
||||
if (isMaster)
|
||||
Error("ParseFile(): fopen(%s): %s", word->string,
|
||||
strerror(errno));
|
||||
} else {
|
||||
char *fname;
|
||||
/* word gets destroyed, so save the name */
|
||||
fname = StrDup(word->string);
|
||||
ParseFile(fname, lfp, level + 1);
|
||||
fclose(lfp);
|
||||
free(fname);
|
||||
}
|
||||
} else {
|
||||
switch (state) {
|
||||
case START:
|
||||
switch (token) {
|
||||
case WORD:
|
||||
for (secIndex = 0;
|
||||
(p = sections[secIndex].id) != (char *)0;
|
||||
secIndex++) {
|
||||
if (strcasecmp(word->string, p) == 0) {
|
||||
CONDDEBUG((1,
|
||||
"ReadCfg(): got keyword '%s' [%s:%d]",
|
||||
word->string, file, line));
|
||||
state = NAME;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (state == START) {
|
||||
if (isMaster)
|
||||
Error("invalid keyword '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
}
|
||||
break;
|
||||
case LEFTBRACE:
|
||||
case RIGHTBRACE:
|
||||
case SEMICOLON:
|
||||
if (isMaster)
|
||||
Error("invalid token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
break;
|
||||
case DONE: /* just shutting up gcc */
|
||||
case INCLUDE: /* just shutting up gcc */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NAME:
|
||||
switch (token) {
|
||||
case WORD:
|
||||
(*sections[secIndex].begin) (word->string);
|
||||
state = LEFTB;
|
||||
break;
|
||||
case RIGHTBRACE:
|
||||
if (isMaster)
|
||||
Error("premature token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
state = START;
|
||||
break;
|
||||
case LEFTBRACE:
|
||||
case SEMICOLON:
|
||||
if (isMaster)
|
||||
Error("invalid token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
break;
|
||||
case DONE: /* just shutting up gcc */
|
||||
case INCLUDE: /* just shutting up gcc */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case LEFTB:
|
||||
switch (token) {
|
||||
case LEFTBRACE:
|
||||
state = KEY;
|
||||
break;
|
||||
case RIGHTBRACE:
|
||||
if (isMaster)
|
||||
Error("premature token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
(*sections[secIndex].abort) ();
|
||||
state = START;
|
||||
break;
|
||||
case SEMICOLON:
|
||||
if (isMaster)
|
||||
Error("invalid token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
break;
|
||||
case WORD:
|
||||
if (isMaster)
|
||||
Error("invalid word '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
break;
|
||||
case DONE: /* just shutting up gcc */
|
||||
case INCLUDE: /* just shutting up gcc */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case KEY:
|
||||
switch (token) {
|
||||
case WORD:
|
||||
for (keyIndex = 0;
|
||||
(p =
|
||||
sections[secIndex].items[keyIndex].id) !=
|
||||
(char *)0; keyIndex++) {
|
||||
if (strcasecmp(word->string, p) == 0) {
|
||||
CONDDEBUG((1,
|
||||
"got keyword '%s' [%s:%d]",
|
||||
word->string, file, line));
|
||||
state = VALUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (state == KEY) {
|
||||
if (isMaster)
|
||||
Error("invalid keyword '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
}
|
||||
break;
|
||||
case RIGHTBRACE:
|
||||
(*sections[secIndex].end) ();
|
||||
state = START;
|
||||
break;
|
||||
case LEFTBRACE:
|
||||
if (isMaster)
|
||||
Error("invalid token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
break;
|
||||
case SEMICOLON:
|
||||
if (isMaster)
|
||||
Error("premature token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
case DONE: /* just shutting up gcc */
|
||||
case INCLUDE: /* just shutting up gcc */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case VALUE:
|
||||
switch (token) {
|
||||
case WORD:
|
||||
(*sections[secIndex].items[keyIndex].
|
||||
reg) (word->string);
|
||||
state = SEMI;
|
||||
break;
|
||||
case SEMICOLON:
|
||||
if (isMaster)
|
||||
Error("invalid token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
state = KEY;
|
||||
break;
|
||||
case RIGHTBRACE:
|
||||
if (isMaster)
|
||||
Error("premature token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
(*sections[secIndex].abort) ();
|
||||
state = START;
|
||||
break;
|
||||
case LEFTBRACE:
|
||||
if (isMaster)
|
||||
Error("invalid token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
break;
|
||||
case DONE: /* just shutting up gcc */
|
||||
case INCLUDE: /* just shutting up gcc */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SEMI:
|
||||
switch (token) {
|
||||
case SEMICOLON:
|
||||
state = KEY;
|
||||
break;
|
||||
case RIGHTBRACE:
|
||||
if (isMaster)
|
||||
Error("premature token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
(*sections[secIndex].abort) ();
|
||||
state = START;
|
||||
break;
|
||||
case LEFTBRACE:
|
||||
if (isMaster)
|
||||
Error("invalid token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
break;
|
||||
case WORD:
|
||||
if (isMaster)
|
||||
Error("invalid word '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
break;
|
||||
case DONE: /* just shutting up gcc */
|
||||
case INCLUDE: /* just shutting up gcc */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
switch (state) {
|
||||
case NAME:
|
||||
case VALUE:
|
||||
spaceok = 1;
|
||||
break;
|
||||
case KEY:
|
||||
case LEFTB:
|
||||
case START:
|
||||
case SEMI:
|
||||
spaceok = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
line = nextline;
|
||||
}
|
||||
|
||||
if (level == 0) {
|
||||
/* check for proper ending of file and do any cleanup */
|
||||
switch (state) {
|
||||
case START:
|
||||
break;
|
||||
case KEY:
|
||||
case LEFTB:
|
||||
case VALUE:
|
||||
case SEMI:
|
||||
(*sections[secIndex].abort) ();
|
||||
/* fall through */
|
||||
case NAME:
|
||||
if (isMaster)
|
||||
Error("premature EOF seen [%s:%d]", file, line);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
#if PROTOTYPES
|
||||
ReadCfg(char *filename, FILE *fp)
|
||||
@ -4698,14 +5082,7 @@ ReadCfg(filename, fp)
|
||||
FILE *fp;
|
||||
#endif
|
||||
{
|
||||
static STRING *word = (STRING *)0;
|
||||
STATES state = START;
|
||||
int secIndex = 0;
|
||||
int keyIndex = 0;
|
||||
TOKEN token = DONE;
|
||||
short spaceok = 0;
|
||||
char *p;
|
||||
int nextline = 1; /* "next" line number */
|
||||
int i;
|
||||
#if HAVE_DMALLOC && DMALLOC_MARK_READCFG
|
||||
unsigned long dmallocMarkReadCfg = 0;
|
||||
@ -4716,12 +5093,6 @@ ReadCfg(filename, fp)
|
||||
#endif
|
||||
isStartup = (pGroups == (GRPENT *)0 && pRCList == (REMOTE *)0);
|
||||
|
||||
/* initialize local things */
|
||||
if (word == (STRING *)0)
|
||||
word = AllocString();
|
||||
line = 1;
|
||||
file = filename;
|
||||
|
||||
/* initialize the break lists */
|
||||
for (i = 0; i < 9; i++) {
|
||||
if (breakList[i].seq == (STRING *)0) {
|
||||
@ -4750,215 +5121,11 @@ ReadCfg(filename, fp)
|
||||
OutOfMem();
|
||||
|
||||
/* ready to read in the data */
|
||||
while ((token = GetWord(fp, &nextline, spaceok, word)) != DONE) {
|
||||
switch (state) {
|
||||
case START:
|
||||
switch (token) {
|
||||
case WORD:
|
||||
for (secIndex = 0;
|
||||
(p = sections[secIndex].id) != (char *)0;
|
||||
secIndex++) {
|
||||
if (strcasecmp(word->string, p) == 0) {
|
||||
CONDDEBUG((1,
|
||||
"ReadCfg(): got keyword '%s' [%s:%d]",
|
||||
word->string, file, line));
|
||||
state = NAME;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (state == START) {
|
||||
if (isMaster)
|
||||
Error("invalid keyword '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
}
|
||||
break;
|
||||
case LEFTBRACE:
|
||||
case RIGHTBRACE:
|
||||
case SEMICOLON:
|
||||
if (isMaster)
|
||||
Error("invalid token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
break;
|
||||
case DONE: /* just shutting up gcc */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case NAME:
|
||||
switch (token) {
|
||||
case WORD:
|
||||
(*sections[secIndex].begin) (word->string);
|
||||
state = LEFTB;
|
||||
break;
|
||||
case RIGHTBRACE:
|
||||
if (isMaster)
|
||||
Error("premature token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
state = START;
|
||||
break;
|
||||
case LEFTBRACE:
|
||||
case SEMICOLON:
|
||||
if (isMaster)
|
||||
Error("invalid token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
break;
|
||||
case DONE: /* just shutting up gcc */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case LEFTB:
|
||||
switch (token) {
|
||||
case LEFTBRACE:
|
||||
state = KEY;
|
||||
break;
|
||||
case RIGHTBRACE:
|
||||
if (isMaster)
|
||||
Error("premature token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
(*sections[secIndex].abort) ();
|
||||
state = START;
|
||||
break;
|
||||
case SEMICOLON:
|
||||
if (isMaster)
|
||||
Error("invalid token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
break;
|
||||
case WORD:
|
||||
if (isMaster)
|
||||
Error("invalid word '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
break;
|
||||
case DONE: /* just shutting up gcc */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case KEY:
|
||||
switch (token) {
|
||||
case WORD:
|
||||
for (keyIndex = 0;
|
||||
(p =
|
||||
sections[secIndex].items[keyIndex].id) !=
|
||||
(char *)0; keyIndex++) {
|
||||
if (strcasecmp(word->string, p) == 0) {
|
||||
CONDDEBUG((1, "got keyword '%s' [%s:%d]",
|
||||
word->string, file, line));
|
||||
state = VALUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (state == KEY) {
|
||||
if (isMaster)
|
||||
Error("invalid keyword '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
}
|
||||
break;
|
||||
case RIGHTBRACE:
|
||||
(*sections[secIndex].end) ();
|
||||
state = START;
|
||||
break;
|
||||
case LEFTBRACE:
|
||||
if (isMaster)
|
||||
Error("invalid token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
break;
|
||||
case SEMICOLON:
|
||||
if (isMaster)
|
||||
Error("premature token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
case DONE: /* just shutting up gcc */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case VALUE:
|
||||
switch (token) {
|
||||
case WORD:
|
||||
(*sections[secIndex].items[keyIndex].reg) (word->
|
||||
string);
|
||||
state = SEMI;
|
||||
break;
|
||||
case SEMICOLON:
|
||||
if (isMaster)
|
||||
Error("invalid token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
state = KEY;
|
||||
break;
|
||||
case RIGHTBRACE:
|
||||
if (isMaster)
|
||||
Error("premature token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
(*sections[secIndex].abort) ();
|
||||
state = START;
|
||||
break;
|
||||
case LEFTBRACE:
|
||||
if (isMaster)
|
||||
Error("invalid token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
break;
|
||||
case DONE: /* just shutting up gcc */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SEMI:
|
||||
switch (token) {
|
||||
case SEMICOLON:
|
||||
state = KEY;
|
||||
break;
|
||||
case RIGHTBRACE:
|
||||
if (isMaster)
|
||||
Error("premature token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
(*sections[secIndex].abort) ();
|
||||
state = START;
|
||||
break;
|
||||
case LEFTBRACE:
|
||||
if (isMaster)
|
||||
Error("invalid token '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
break;
|
||||
case WORD:
|
||||
if (isMaster)
|
||||
Error("invalid word '%s' [%s:%d]",
|
||||
word->string, file, line);
|
||||
break;
|
||||
case DONE: /* just shutting up gcc */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
switch (state) {
|
||||
case NAME:
|
||||
case VALUE:
|
||||
spaceok = 1;
|
||||
break;
|
||||
case KEY:
|
||||
case LEFTB:
|
||||
case START:
|
||||
case SEMI:
|
||||
spaceok = 0;
|
||||
break;
|
||||
}
|
||||
line = nextline;
|
||||
}
|
||||
|
||||
/* check for proper ending of file and do any cleanup */
|
||||
switch (state) {
|
||||
case START:
|
||||
break;
|
||||
case KEY:
|
||||
case LEFTB:
|
||||
case VALUE:
|
||||
case SEMI:
|
||||
(*sections[secIndex].abort) ();
|
||||
/* fall through */
|
||||
case NAME:
|
||||
if (isMaster)
|
||||
Error("premature EOF seen [%s:%d]", file, line);
|
||||
break;
|
||||
}
|
||||
ParseFile(filename, fp, 0);
|
||||
|
||||
/* now clean up all the temporary space used */
|
||||
for (nextline = 0; (p = sections[nextline].id) != (char *)0;
|
||||
nextline++) {
|
||||
(*sections[nextline].destroy) ();
|
||||
for (i = 0; (p = sections[i].id) != (char *)0; i++) {
|
||||
(*sections[i].destroy) ();
|
||||
}
|
||||
|
||||
#if HAVE_DMALLOC && DMALLOC_MARK_READCFG
|
||||
@ -5002,7 +5169,7 @@ ReReadCfg(fd)
|
||||
return;
|
||||
} else {
|
||||
Error("no consoles to manage after reconfiguration - exiting");
|
||||
Bye(EX_OK);
|
||||
DeUtmp((GRPENT *)0, fd);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5095,6 +5262,14 @@ ReReadCfg(fd)
|
||||
config->reinitcheck = pConfig->reinitcheck;
|
||||
/* gets used on-the-fly */
|
||||
}
|
||||
|
||||
if (optConf->initdelay == 0) {
|
||||
if (pConfig->initdelay == 0)
|
||||
config->initdelay = defConfig.initdelay;
|
||||
else if (pConfig->initdelay != config->initdelay)
|
||||
config->initdelay = pConfig->initdelay;
|
||||
/* gets used on-the-fly */
|
||||
}
|
||||
#if HAVE_OPENSSL
|
||||
if (optConf->sslrequired == FLAGUNKNOWN) {
|
||||
if (pConfig->sslrequired == FLAGUNKNOWN)
|
||||
@ -5127,6 +5302,7 @@ ReReadCfg(fd)
|
||||
Msg("warning: `daemonmode' config option changed - you must restart for it to take effect");
|
||||
}
|
||||
}
|
||||
#if !USE_UNIX_DOMAIN_SOCKETS
|
||||
if (optConf->primaryport == (char *)0) {
|
||||
char *p;
|
||||
if (pConfig->primaryport == (char *)0)
|
||||
@ -5159,6 +5335,7 @@ ReReadCfg(fd)
|
||||
Msg("warning: `secondaryport' config option changed - you must restart for it to take effect");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if HAVE_OPENSSL
|
||||
if (optConf->sslcredentials == (char *)0) {
|
||||
if (pConfig->sslcredentials == (char *)0) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: readcfg.h,v 5.38 2003/11/10 15:37:24 bryan Exp $
|
||||
* $Id: readcfg.h,v 5.39 2004/05/07 03:42:49 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -20,6 +20,7 @@ typedef struct config {
|
||||
int reinitcheck;
|
||||
char *secondaryport;
|
||||
char *unifiedlog;
|
||||
int initdelay;
|
||||
#if HAVE_SETPROCTITLE
|
||||
FLAG setproctitle;
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: version.h,v 1.59 2004/03/16 04:17:31 bryan Exp $
|
||||
* $Id: version.h,v 1.61 2004/04/16 16:58:09 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -14,4 +14,4 @@
|
||||
@(#) Copyright 2000 conserver.com.\n\
|
||||
All rights reserved.\n"
|
||||
|
||||
#define THIS_VERSION "conserver.com version 8.1.3"
|
||||
#define THIS_VERSION "conserver.com version 8.1.5"
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: console.c,v 5.161 2004/03/20 14:40:42 bryan Exp $
|
||||
* $Id: console.c,v 5.164 2004/04/20 01:30:13 bryan Exp $
|
||||
*
|
||||
* Copyright conserver.com, 2000
|
||||
*
|
||||
@ -42,13 +42,19 @@
|
||||
|
||||
|
||||
int fReplay = 0, fVersion = 0, fStrip = 0;
|
||||
int showExecData = 1;
|
||||
#if HAVE_OPENSSL
|
||||
int fReqEncryption = 1;
|
||||
int fAllowUnencrypted = 0;
|
||||
char *pcCredFile = (char *)0;
|
||||
#endif
|
||||
int chAttn = -1, chEsc = -1;
|
||||
char *pcInMaster = /* which machine is current */
|
||||
MASTERHOST;
|
||||
char *pcInMaster =
|
||||
#if USE_UNIX_DOMAIN_SOCKETS
|
||||
UDSDIR;
|
||||
#else
|
||||
MASTERHOST; /* which machine is current */
|
||||
#endif
|
||||
char *pcPort = DEFPORT;
|
||||
unsigned short bindPort;
|
||||
CONSFILE *cfstdout;
|
||||
@ -213,6 +219,11 @@ Usage(wantfull)
|
||||
"s(S) spy on a console (and replay)",
|
||||
"t send a text message to [user][@console]",
|
||||
"u show users on the various consoles",
|
||||
#if HAVE_OPENSSL
|
||||
"U allow unencrypted connections if SSL not available",
|
||||
#else
|
||||
"U ignored - encryption not compiled into code",
|
||||
#endif
|
||||
"v be more verbose",
|
||||
"V show version information",
|
||||
"w(W) show who is on which console (on master)",
|
||||
@ -221,12 +232,13 @@ Usage(wantfull)
|
||||
};
|
||||
|
||||
fprintf(stderr,
|
||||
"usage: %s [-aAEfFsS] [-7Dv] [-c cred] [-M mach] [-p port] [-e esc] [-l username] console\n",
|
||||
"usage: %s [-aAfFsS] [-7DEUv] [-c cred] [-M mach] [-p port] [-e esc] [-l username] console\n",
|
||||
progname);
|
||||
fprintf(stderr,
|
||||
"usage: %s [-hiIPrRuVwWx] [-7Dv] [-M mach] [-p port] [-d [user][@console]] [-[bB] message] [-t [user][@console] message]\n",
|
||||
" %s [-hiIPrRuVwWx] [-7DEUv] [-c cred] [-M mach] [-p port] [-d [user][@console]] [-[bB] message] [-t [user][@console] message]\n",
|
||||
progname);
|
||||
fprintf(stderr, "usage: %s [-qQ] [-7Dv] [-M mach] [-p port]\n",
|
||||
fprintf(stderr,
|
||||
" %s [-qQ] [-7DEUv] [-c cred] [-M mach] [-p port]\n",
|
||||
progname);
|
||||
|
||||
if (wantfull) {
|
||||
@ -270,10 +282,14 @@ Version()
|
||||
acA2 = AllocString();
|
||||
|
||||
Msg("%s", THIS_VERSION);
|
||||
#if USE_UNIX_DOMAIN_SOCKETS
|
||||
Msg("default socket directory `%s\'", UDSDIR);
|
||||
#else
|
||||
Msg("default initial master server `%s\'", MASTERHOST);
|
||||
Msg("default port referenced as `%s'", DEFPORT);
|
||||
#endif
|
||||
Msg("default escape sequence `%s%s\'", FmtCtl(DEFATTN, acA1),
|
||||
FmtCtl(DEFESC, acA2));
|
||||
Msg("default port referenced as `%s'", DEFPORT);
|
||||
|
||||
BuildString((char *)0, acA1);
|
||||
if (optionlist[0] == (char *)0)
|
||||
@ -430,8 +446,13 @@ GetPort(pcToHost, sPort)
|
||||
#endif
|
||||
{
|
||||
int s;
|
||||
#if USE_UNIX_DOMAIN_SOCKETS
|
||||
struct sockaddr_un port;
|
||||
static STRING *portPath = (STRING *)0;
|
||||
#else
|
||||
struct hostent *hp = (struct hostent *)0;
|
||||
struct sockaddr_in port;
|
||||
#endif
|
||||
|
||||
#if HAVE_MEMSET
|
||||
memset((void *)(&port), '\000', sizeof(port));
|
||||
@ -439,21 +460,47 @@ GetPort(pcToHost, sPort)
|
||||
bzero((char *)(&port), sizeof(port));
|
||||
#endif
|
||||
|
||||
#if HAVE_INET_ATON
|
||||
if (inet_aton(pcToHost, &(port.sin_addr)) == 0)
|
||||
#if USE_UNIX_DOMAIN_SOCKETS
|
||||
if (portPath == (STRING *)0)
|
||||
portPath = AllocString();
|
||||
BuildStringPrint(portPath, "%s/%hu", pcInMaster, sPort);
|
||||
port.sun_family = AF_UNIX;
|
||||
if (portPath->used > sizeof(port.sun_path)) {
|
||||
Error("GetPort: path to socket too long: %s", portPath->string);
|
||||
return (CONSFILE *)0;
|
||||
}
|
||||
strcpy(port.sun_path, portPath->string);
|
||||
|
||||
CONDDEBUG((1, "GetPort: socket=%s", port.sun_path));
|
||||
|
||||
/* set up the socket to talk to the server for all consoles
|
||||
* (it will tell us who to talk to to get a real connection)
|
||||
*/
|
||||
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
|
||||
Error("socket(AF_UNIX,SOCK_STREAM): %s", strerror(errno));
|
||||
return (CONSFILE *)0;
|
||||
}
|
||||
|
||||
if (connect(s, (struct sockaddr *)(&port), sizeof(port)) < 0) {
|
||||
Error("connect(): %s: %s", port.sun_path, strerror(errno));
|
||||
return (CONSFILE *)0;
|
||||
}
|
||||
#else
|
||||
# if HAVE_INET_ATON
|
||||
if (inet_aton(pcToHost, &(port.sin_addr)) == 0)
|
||||
# else
|
||||
port.sin_addr.s_addr = inet_addr(pcToHost);
|
||||
if ((in_addr_t) (-1) == port.sin_addr.s_addr)
|
||||
#endif
|
||||
# endif
|
||||
{
|
||||
if ((struct hostent *)0 != (hp = gethostbyname(pcToHost))) {
|
||||
#if HAVE_MEMCPY
|
||||
# if HAVE_MEMCPY
|
||||
memcpy((char *)&port.sin_addr.s_addr, (char *)hp->h_addr,
|
||||
hp->h_length);
|
||||
#else
|
||||
# else
|
||||
bcopy((char *)hp->h_addr, (char *)&port.sin_addr.s_addr,
|
||||
hp->h_length);
|
||||
#endif
|
||||
# endif
|
||||
} else {
|
||||
Error("gethostbyname(%s): %s", pcToHost, hstrerror(h_errno));
|
||||
return (CONSFILE *)0;
|
||||
@ -481,11 +528,13 @@ GetPort(pcToHost, sPort)
|
||||
Error("socket(AF_INET,SOCK_STREAM): %s", strerror(errno));
|
||||
return (CONSFILE *)0;
|
||||
}
|
||||
|
||||
if (connect(s, (struct sockaddr *)(&port), sizeof(port)) < 0) {
|
||||
Error("connect(): %hu@%s: %s", ntohs(port.sin_port), pcToHost,
|
||||
strerror(errno));
|
||||
return (CONSFILE *)0;
|
||||
}
|
||||
#endif
|
||||
|
||||
return FileOpenFD(s, simpleSocket);
|
||||
}
|
||||
@ -848,6 +897,7 @@ DoExec(pcf)
|
||||
CONSFILE *pcf;
|
||||
#endif
|
||||
{
|
||||
showExecData = 1;
|
||||
FileWrite(cfstdout, FLAGFALSE, "exec: ", 6);
|
||||
|
||||
GetUserInput(execCmd);
|
||||
@ -1045,10 +1095,12 @@ Interact(pcf, pcMach)
|
||||
for (i = 0; i < l; ++i)
|
||||
acMesg[i] &= 127;
|
||||
}
|
||||
FileWrite(cfstdout, FLAGFALSE, acMesg, l);
|
||||
if (execCmdFile != (CONSFILE *)0) {
|
||||
FileWrite(execCmdFile, FLAGFALSE, acMesg, l);
|
||||
}
|
||||
if (showExecData)
|
||||
FileWrite(cfstdout, FLAGFALSE, acMesg, l);
|
||||
} else
|
||||
FileWrite(cfstdout, FLAGFALSE, acMesg, l);
|
||||
nc -= l;
|
||||
MemMove(acMesg, acMesg + l, nc);
|
||||
}
|
||||
@ -1092,6 +1144,11 @@ Interact(pcf, pcMach)
|
||||
FilePrint(cfstdout, FLAGFALSE,
|
||||
"[local command sent SIGKILL - pid %lu]\r\n",
|
||||
execCmdPid);
|
||||
} else if (acMesg[i] == 'o' || acMesg[i] == 'O') {
|
||||
showExecData = !showExecData;
|
||||
FilePrint(cfstdout, FLAGFALSE,
|
||||
"[local command data %s]\r\n",
|
||||
showExecData ? "on" : "off");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1270,6 +1327,7 @@ DoCmds(master, pports, cmdi)
|
||||
int len;
|
||||
char *ports;
|
||||
char *pcopy;
|
||||
char *serverName;
|
||||
|
||||
if ((pcopy = ports = StrDup(pports)) == (char *)0)
|
||||
OutOfMem();
|
||||
@ -1292,13 +1350,27 @@ DoCmds(master, pports, cmdi)
|
||||
} else
|
||||
server = master;
|
||||
|
||||
#if USE_UNIX_DOMAIN_SOCKETS
|
||||
serverName = "localhost";
|
||||
#else
|
||||
serverName = server;
|
||||
#endif
|
||||
|
||||
if (*ports == '\000') {
|
||||
#if USE_UNIX_DOMAIN_SOCKETS
|
||||
port = 0;
|
||||
#else
|
||||
port = htons(bindPort);
|
||||
#endif
|
||||
} else if (!isdigit((int)(ports[0]))) {
|
||||
Error("invalid port spec for %s: `%s'", server, ports);
|
||||
Error("invalid port spec for %s: `%s'", serverName, ports);
|
||||
continue;
|
||||
} else {
|
||||
#if USE_UNIX_DOMAIN_SOCKETS
|
||||
port = (short)atoi(ports);
|
||||
#else
|
||||
port = htons((short)atoi(ports));
|
||||
#endif
|
||||
}
|
||||
|
||||
attemptLogin:
|
||||
@ -1310,7 +1382,7 @@ DoCmds(master, pports, cmdi)
|
||||
t = ReadReply(pcf, 0);
|
||||
if (strcmp(t, "ok\r\n") != 0) {
|
||||
FileClose(&pcf);
|
||||
FilePrint(cfstdout, FLAGFALSE, "%s: %s", server, t);
|
||||
FilePrint(cfstdout, FLAGFALSE, "%s: %s", serverName, t);
|
||||
continue;
|
||||
}
|
||||
#if HAVE_OPENSSL
|
||||
@ -1319,9 +1391,15 @@ DoCmds(master, pports, cmdi)
|
||||
t = ReadReply(pcf, 0);
|
||||
if (strcmp(t, "ok\r\n") == 0) {
|
||||
AttemptSSL(pcf);
|
||||
}
|
||||
if (FileGetType(pcf) != SSLSocket) {
|
||||
Error("Encryption not supported by server `%s'", server);
|
||||
if (FileGetType(pcf) != SSLSocket) {
|
||||
Error("Encryption not supported by server `%s'",
|
||||
serverName);
|
||||
FileClose(&pcf);
|
||||
continue;
|
||||
}
|
||||
} else if (fAllowUnencrypted == 0) {
|
||||
Error("Encryption not supported by server `%s'",
|
||||
serverName);
|
||||
FileClose(&pcf);
|
||||
continue;
|
||||
}
|
||||
@ -1339,9 +1417,9 @@ DoCmds(master, pports, cmdi)
|
||||
if (t[7] == ' ') {
|
||||
hostname = PruneSpace(t + 7);
|
||||
if (*hostname == '\000')
|
||||
hostname = server;
|
||||
hostname = serverName;
|
||||
} else
|
||||
hostname = server;
|
||||
hostname = serverName;
|
||||
if (tmpString == (STRING *)0)
|
||||
tmpString = AllocString();
|
||||
if (tmpString->used <= 1) {
|
||||
@ -1351,7 +1429,7 @@ DoCmds(master, pports, cmdi)
|
||||
pass = GetPassword(tmpString->string);
|
||||
if (pass == (char *)0) {
|
||||
Error("could not get password from tty for `%s'",
|
||||
server);
|
||||
serverName);
|
||||
FileClose(&pcf);
|
||||
continue;
|
||||
}
|
||||
@ -1363,12 +1441,12 @@ DoCmds(master, pports, cmdi)
|
||||
tmpString->used - 1);
|
||||
t = ReadReply(pcf, 0);
|
||||
if (strcmp(t, "ok\r\n") != 0) {
|
||||
FilePrint(cfstdout, FLAGFALSE, "%s: %s", server, t);
|
||||
FilePrint(cfstdout, FLAGFALSE, "%s: %s", serverName, t);
|
||||
if (++count < 3) {
|
||||
BuildString((char *)0, tmpString);
|
||||
goto attemptLogin;
|
||||
}
|
||||
Error("too many bad passwords for `%s'", server);
|
||||
Error("too many bad passwords for `%s'", serverName);
|
||||
count = 0;
|
||||
FileClose(&pcf);
|
||||
continue;
|
||||
@ -1376,7 +1454,7 @@ DoCmds(master, pports, cmdi)
|
||||
count = 0;
|
||||
} else if (strcmp(t, "ok\r\n") != 0) {
|
||||
FileClose(&pcf);
|
||||
FilePrint(cfstdout, FLAGFALSE, "%s: %s", server, t);
|
||||
FilePrint(cfstdout, FLAGFALSE, "%s: %s", serverName, t);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1412,7 +1490,8 @@ DoCmds(master, pports, cmdi)
|
||||
Bye(EX_SOFTWARE);
|
||||
}
|
||||
} else if (result[0] != '[') { /* did we not get a connection? */
|
||||
FilePrint(cfstdout, FLAGFALSE, "%s: %s", server, result);
|
||||
FilePrint(cfstdout, FLAGFALSE, "%s: %s", serverName,
|
||||
result);
|
||||
FileClose(&pcf);
|
||||
continue;
|
||||
} else {
|
||||
@ -1452,7 +1531,7 @@ DoCmds(master, pports, cmdi)
|
||||
*/
|
||||
if (cmds[0][0] == 'd') {
|
||||
if (result[0] != 'o' || result[1] != 'k') {
|
||||
FileWrite(cfstdout, FLAGTRUE, server, -1);
|
||||
FileWrite(cfstdout, FLAGTRUE, serverName, -1);
|
||||
FileWrite(cfstdout, FLAGTRUE, ": ", 2);
|
||||
FileWrite(cfstdout, FLAGFALSE, result, len);
|
||||
} else {
|
||||
@ -1461,8 +1540,9 @@ DoCmds(master, pports, cmdi)
|
||||
} else if ((cmds[0][0] != 'b' && cmds[0][0] != 't') ||
|
||||
(result[0] != 'o' || result[1] != 'k')) {
|
||||
/* did a 'master' before this or doing a 'disconnect' */
|
||||
if (cmds[1][0] == 'm' || cmds[0][0] == 'd') {
|
||||
FileWrite(cfstdout, FLAGTRUE, server, -1);
|
||||
if ((cmds[1] != (char *)0 && cmds[1][0] == 'm') ||
|
||||
cmds[0][0] == 'd') {
|
||||
FileWrite(cfstdout, FLAGTRUE, serverName, -1);
|
||||
FileWrite(cfstdout, FLAGTRUE, ": ", 2);
|
||||
}
|
||||
FileWrite(cfstdout, FLAGFALSE, result, len);
|
||||
@ -1510,11 +1590,10 @@ main(argc, argv)
|
||||
int opt;
|
||||
int fLocal;
|
||||
static STRING *acPorts = (STRING *)0;
|
||||
static char acOpts[] = "7aAb:B:c:d:De:EfFhiIl:M:p:PqQrRsSt:uvVwWx";
|
||||
static char acOpts[] = "7aAb:B:c:d:De:EfFhiIl:M:p:PqQrRsSt:uUvVwWx";
|
||||
extern int optind;
|
||||
extern int optopt;
|
||||
extern char *optarg;
|
||||
int i;
|
||||
static STRING *textMsg = (STRING *)0;
|
||||
int cmdi;
|
||||
static STRING *consoleName = (STRING *)0;
|
||||
@ -1556,7 +1635,10 @@ main(argc, argv)
|
||||
/* fall through */
|
||||
case 'b':
|
||||
pcCmd = "broadcast";
|
||||
cmdarg = optarg;
|
||||
if (cmdarg != (char *)0)
|
||||
free(cmdarg);
|
||||
if ((cmdarg = StrDup(optarg)) == (char *)0)
|
||||
OutOfMem();
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
@ -1571,7 +1653,10 @@ main(argc, argv)
|
||||
|
||||
case 'd':
|
||||
pcCmd = "disconnect";
|
||||
cmdarg = optarg;
|
||||
if (cmdarg != (char *)0)
|
||||
free(cmdarg);
|
||||
if ((cmdarg = StrDup(optarg)) == (char *)0)
|
||||
OutOfMem();
|
||||
break;
|
||||
|
||||
case 'E':
|
||||
@ -1650,6 +1735,12 @@ main(argc, argv)
|
||||
pcCmd = textMsg->string;
|
||||
break;
|
||||
|
||||
case 'U':
|
||||
#if HAVE_OPENSSL
|
||||
fAllowUnencrypted = 1;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
pcCmd = "hosts";
|
||||
break;
|
||||
@ -1702,6 +1793,8 @@ main(argc, argv)
|
||||
Error("missing console name");
|
||||
Bye(EX_UNAVAILABLE);
|
||||
}
|
||||
if (cmdarg != (char *)0)
|
||||
free(cmdarg);
|
||||
if ((cmdarg = StrDup(argv[optind++])) == (char *)0)
|
||||
OutOfMem();
|
||||
} else if (*pcCmd == 't') {
|
||||
@ -1709,24 +1802,27 @@ main(argc, argv)
|
||||
Error("missing message text");
|
||||
Bye(EX_UNAVAILABLE);
|
||||
}
|
||||
cmdarg = argv[optind++];
|
||||
if (cmdarg != (char *)0)
|
||||
free(cmdarg);
|
||||
if ((cmdarg = StrDup(argv[optind++])) == (char *)0)
|
||||
OutOfMem();
|
||||
}
|
||||
|
||||
if (optind < argc) {
|
||||
Error("extra garbage on command line? (%s...)", argv[optind]);
|
||||
Bye(EX_UNAVAILABLE);
|
||||
}
|
||||
|
||||
#if !USE_UNIX_DOMAIN_SOCKETS
|
||||
/* if we somehow lost the port (or got an empty string), reset */
|
||||
if (pcPort == (char *)0 || pcPort[0] == '\000')
|
||||
pcPort = DEFPORT;
|
||||
|
||||
/* Look for non-numeric characters */
|
||||
for (i = 0; pcPort[i] != '\000'; i++)
|
||||
if (!isdigit((int)pcPort[i]))
|
||||
for (opt = 0; pcPort[opt] != '\000'; opt++)
|
||||
if (!isdigit((int)pcPort[opt]))
|
||||
break;
|
||||
|
||||
if (pcPort[i] == '\000') {
|
||||
if (pcPort[opt] == '\000') {
|
||||
/* numeric only */
|
||||
bindPort = atoi(pcPort);
|
||||
} else {
|
||||
@ -1739,6 +1835,7 @@ main(argc, argv)
|
||||
bindPort = ntohs((u_short) pSE->s_port);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pcUser == (char *)0 || pcUser[0] == '\000') {
|
||||
if (((pcUser = getenv("LOGNAME")) == (char *)0) &&
|
||||
@ -1836,8 +1933,9 @@ main(argc, argv)
|
||||
free(cmdarg);
|
||||
|
||||
if (*pcCmd == 'd')
|
||||
FilePrint(cfstdout, FLAGFALSE, "Disconnected %d users\n",
|
||||
disconnectCount);
|
||||
FilePrint(cfstdout, FLAGFALSE, "disconnected %d %s\n",
|
||||
disconnectCount,
|
||||
disconnectCount == 1 ? "user" : "users");
|
||||
|
||||
Bye(0);
|
||||
return 0; /* noop - Bye() terminates us */
|
||||
|
@ -1,11 +1,11 @@
|
||||
.\" $Id: console.man,v 1.45 2004/03/20 14:40:42 bryan Exp $
|
||||
.TH CONSOLE 1 "2004/03/20" "conserver-8.1.3" "conserver"
|
||||
.\" $Id: console.man,v 1.48 2004/04/20 01:30:13 bryan Exp $
|
||||
.TH CONSOLE 1 "2004/04/20" "conserver-8.1.5" "conserver"
|
||||
.SH NAME
|
||||
console \- console server client program
|
||||
.SH SYNOPSIS
|
||||
.B console
|
||||
.RB [ \-aAEfFsS ]
|
||||
.RB [ \-7Dv ]
|
||||
.RB [ \-aAfFsS ]
|
||||
.RB [ \-7DEUv ]
|
||||
.RB [ \-c
|
||||
.IR cred ]
|
||||
.BR [ \-M
|
||||
@ -20,22 +20,26 @@ console \- console server client program
|
||||
.br
|
||||
.B console
|
||||
.RB [ \-hiIPrRuVwWx ]
|
||||
.RB [ \-7Dv ]
|
||||
.RB [ \-7DEUv ]
|
||||
.RB [ \-c
|
||||
.IR cred ]
|
||||
.RB [ \-M
|
||||
.IR mach ]
|
||||
.RB [ \-p
|
||||
.IR port ]
|
||||
.RB [ \-d
|
||||
.RI [ user ][\fB@\fP console ]]
|
||||
.RI [ user ][\f3@\fP console ]]
|
||||
.RB [ \- [ bB ]
|
||||
.IR message ]
|
||||
.RB [ \-t
|
||||
.RI [ user ][\fB@\fP console ]
|
||||
.RI [ user ][\f3@\fP console ]
|
||||
.IR message ]
|
||||
.br
|
||||
.B console
|
||||
.RB [ \-qQ ]
|
||||
.RB [ \-7Dv ]
|
||||
.RB [ \-7DEUv ]
|
||||
.RB [ \-c
|
||||
.IR cred ]
|
||||
.RB [ \-M
|
||||
.IR mach ]
|
||||
.RB [ \-p
|
||||
@ -150,9 +154,13 @@ The default value is
|
||||
.B \-E
|
||||
If encryption has been built into the code
|
||||
.RB ( --with-openssl ),
|
||||
encrypted client connections are a requirement.
|
||||
This option allows the client to connect to a console
|
||||
over a non-encrypted connection.
|
||||
encrypted client connections are, by default, a requirement.
|
||||
This option disables any attempt at creating an
|
||||
encrypted connection.
|
||||
If you'd like to use encrypted connections when your server
|
||||
supports it, but fallback to non-encrypted otherwise, the
|
||||
.B \-U
|
||||
option is what you want.
|
||||
.TP
|
||||
.B \-f
|
||||
Same as
|
||||
@ -264,6 +272,18 @@ and attached users
|
||||
.RI ( user @ host
|
||||
if attached read-write, `<spies>' if only users in spy mode, or `<none>').
|
||||
.TP
|
||||
.B \-U
|
||||
If encryption has been built into the code
|
||||
.RB ( --with-openssl ),
|
||||
encrypted client connections are, by default, a requirement.
|
||||
This option allows the client to attempt an encrypted connection
|
||||
but fall back to a non-encrypted connection if the server doesn't
|
||||
support encryption.
|
||||
If the encryption handshake is failing, disabling encryption on the
|
||||
client with the
|
||||
.B \-E
|
||||
option is probably what you want.
|
||||
.TP
|
||||
.B \-v
|
||||
Be more verbose when building the connection(s).
|
||||
Use this option in combination with any of `show' options (below)
|
||||
@ -297,7 +317,7 @@ The
|
||||
options have the same effect as their lower-case variants.
|
||||
In addition, they each request the last 20 lines of the console output after
|
||||
making the connection (as if
|
||||
.RB ` ^Ecr '
|
||||
.RB `` ^Ecr ''
|
||||
were typed).
|
||||
.PP
|
||||
The
|
||||
@ -349,7 +369,7 @@ that the server can open the file for read, but not write.
|
||||
The details regarding the logging for the console.
|
||||
The comma-separated
|
||||
values will be the logfile, ``log'' or ``nolog'' (if logging is on
|
||||
or not - toggled via ^EcL), ``act'' or ``noact'' (if activity logging is
|
||||
or not - toggled via ``^EcL''), ``act'' or ``noact'' (if activity logging is
|
||||
enabled or not - the `a' timestamp option), the timestamp interval, and
|
||||
the file descriptor of the logfile.
|
||||
.TP
|
||||
@ -493,12 +513,16 @@ In the
|
||||
output, the login ``<none>'' indicates no one is
|
||||
viewing that console, and the login ``<spies>'' indicates that
|
||||
no one has a full two-way attachment.
|
||||
When no one is attached to
|
||||
a console its output is cloned to the stdout of the server process if
|
||||
.B conserver
|
||||
was started with the
|
||||
.B \-u
|
||||
option.
|
||||
.PP
|
||||
When running a local command via
|
||||
.RB `` ^Ec| '',
|
||||
you can type
|
||||
.B ^C
|
||||
to send the command a SIGHUP,
|
||||
.B ^\e
|
||||
to send the command a SIGKILL, and
|
||||
.B o
|
||||
to toggle the display of the console data.
|
||||
.SH EXAMPLES
|
||||
.TP 15
|
||||
console \-u
|
||||
|
@ -4,7 +4,7 @@
|
||||
#
|
||||
|
||||
%define pkg conserver
|
||||
%define ver 8.1.3
|
||||
%define ver 8.1.5
|
||||
|
||||
# define the name of the machine on which the main conserver
|
||||
# daemon will be running if you don't want to use the default
|
||||
|
@ -1,7 +1,7 @@
|
||||
PKG="conserver"
|
||||
NAME="Console server and client"
|
||||
CATEGORY="system"
|
||||
VERSION="8.1.3"
|
||||
VERSION="8.1.5"
|
||||
DESC="Console server and client"
|
||||
CLASSES=none
|
||||
ARCH=sparc
|
||||
|
@ -91,7 +91,7 @@ dotest 'cdc.'
|
||||
dotest 'coc.'
|
||||
|
||||
dotest EVAL "echo 'tu.' | ../console/console -M 127.0.0.1 -p 7777 -e 'tu' shell"
|
||||
dotest EVAL "../console/console -M 127.0.0.1 -p 7777 -P | sed -e 's/:.*//'"
|
||||
dotest EVAL "../console/console -M 127.0.0.1 -p 7777 -R | sed -e 's/ [^ ]*$//'"
|
||||
dotest EVAL "../console/console -M 127.0.0.1 -p 7777 -x | sed -e 's/ on [^ ]* */ on /'"
|
||||
|
||||
cleanup
|
||||
|
@ -1 +1 @@
|
||||
127.0.0.1
|
||||
version `conserver.com version
|
||||
|
Reference in New Issue
Block a user