This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Inetutils ".
The branch, master has been updated
via 6129edc81cd2dba78628a0297c39c25b0ffb3956 (commit)
from 126e4166ea32331b792ffec665c49854826896bc (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
http://git.savannah.gnu.org/cgit/inetutils.git/commit/?id=6129edc81cd2dba78628a0297c39c25b0ffb3956
commit 6129edc81cd2dba78628a0297c39c25b0ffb3956
Author: Mats Erik Andersson <[email protected]>
Date: Sun Apr 22 00:28:24 2012 +0200
rexecd: Implement system logging.
Include a timeout in the client `rexec'
to avoid waiting locks.
diff --git a/ChangeLog b/ChangeLog
index b632cf7..1f1faaf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2012-04-22 Mats Erik Andersson <[email protected]>
+
+ rexecd: Implement syslog support.
+
+ * src/rexecd.c: Include <syslog.h>.
+ (logging, options): New variables.
+ (parse_opt): New function.
+ (argp): Insert `options' and `parse_opt'.
+ (main): Call openlog(). Do not exit at surplus arguments,
+ but make a note in syslog. Log failed getpeername().
+ (doit): New variables RHOST and RET. In addition to error()
+ and die(), make many entries in the syslog of varying severity.
+
+ * src/rexec.c (do_rexec): Add a five second alarm around
+ accept() for stderr channel, in case the server side is
+ not responding.
+
+ * doc/inetutils.texi (rexec, rexecd): Document recent
+ additions. Make option encoding for `rexec' complete.
+
2012-04-21 Mats Erik Andersson <[email protected]>
rexecd: Privilege audit and protocol conformity.
diff --git a/doc/inetutils.texi b/doc/inetutils.texi
index 1078256..180d4ca 100644
--- a/doc/inetutils.texi
+++ b/doc/inetutils.texi
@@ -1928,26 +1928,62 @@ rexec --user=@var{login} --password=@var{pass}
--host=@var{host} \
The command line arguments are as follows:
-@table @var
-@item --error
+@table @option
+@item -4
+@itemx --ipv4
+@opindex -4
+@opindex --ipv4
+Use only IPv4 connections as all times.
+
+@item -6
+@itemx --ipv6
+@opindex -6
+@opindex --ipv6
+Use only IPv6 connections.
+
+@item -a
+@itemx --ipany
+@opindex -a
+@opindex --ipany
+Allow any address family for connections. This is the default.
+
+@item -e
+@itemx --error=@var{port}
+@opindex -e
+@opindex --error
Specify the TCP port to use for stderr redirection, in case it is not
specified a random port will be used.
-@item --host
-Specify the host where connect to.
+@item -h
+@item --host=@var{name}
+@opindex -h
+@opindex --host
+Specify the host with whom to connect: symbolic name or address.
-@item --noerr
+@item -n
+@itemx --noerr
+@opindex -n
+@opindex --noerr
If specified, an error stream will not be created.
-@item --password
+@item -p
+@itemx --password=@var{passwd}
+@opindex -p
+@opindex --password
Specify the password for logging-in.
-@item --port
-Specify to which port connect to, if it is not specified by default
-use 512.
+@item -P
+@itemx --port=@var{num}
+@opindex -P
+@opindex --port
+Specify to which numerical port a connection shall be sought.
+If it is not specified, then use port 512/tcp by default.
-@item --user
-Specify the user to log into the server.
+@item -u
+@itemx --user=@var{name}
+@opindex -u
+@opindex --user
+Specify the user with whom to log into the server.
@end table
@@ -3316,7 +3352,8 @@ useful in an ``open'' environment.
@command{rexecd} is the server for the @code{Rexec} routine. The
server provides remote execution facilities with authentication based
-on user names and passwords.
+on user names and passwords. It passes error messages and notices
+to the @code{syslog} facility @samp{LOG_DAEMON}.
@example
rexecd [@var{option}]@dots{}
@@ -3364,6 +3401,21 @@ passed to the normal login shell of the user. The shell
inherits the
network connections established by rexecd.
@end enumerate
+@section Invoking
+
+The only option is as follows:
+
+@table @option
+@item -l
+@itemx --logging
+@opindex -l
+@opindex --logging
+Raise logging level for this service; use more than once for
+increased verbosity. The @code{syslog} facility in use is
+@samp{LOG_DAEMON}.
+
+@end table
+
@section Diagnostics
Except for the last one listed below, all diagnostic messages are
diff --git a/src/rexec.c b/src/rexec.c
index cbf7f7e..5b35238 100644
--- a/src/rexec.c
+++ b/src/rexec.c
@@ -307,10 +307,18 @@ do_rexec (struct arguments *arguments)
snprintf (port_str, sizeof (port_str), "%u", arguments->err_port);
safe_write (sock, port_str, strlen (port_str) + 1);
+ /* Limit waiting time in case the server fails to call back:
+ * if it aborts prematurely, or if a firewall is blocking
+ * the intended STDERR connection to reach us.
+ */
+ alarm (5);
+
err_sock = accept (serv_sock, (struct sockaddr *) &serv_addr, &len);
if (err_sock < 0)
error (EXIT_FAILURE, errno, "error accepting connection");
+ alarm (0);
+
shutdown (err_sock, SHUT_WR);
close (serv_sock);
diff --git a/src/rexecd.c b/src/rexecd.c
index 5c014fe..6042032 100644
--- a/src/rexecd.c
+++ b/src/rexecd.c
@@ -82,6 +82,7 @@
#ifdef HAVE_SHADOW_H
# include <shadow.h>
#endif
+#include <syslog.h>
#include <progname.h>
#include <argp.h>
#include <error.h>
@@ -90,11 +91,33 @@
void die (int code, const char *fmt, ...);
int doit (int f, struct sockaddr *fromp, socklen_t fromlen);
+static int logging = 0;
+
+static struct argp_option options[] = {
+ { "logging", 'l', NULL, 0, "logging of requests and errors" },
+ { NULL }
+};
+
+static error_t
+parse_opt (int key, char *arg, struct argp_state *state)
+{
+ switch (key)
+ {
+ case 'l':
+ ++logging;
+ break;
+
+ default:
+ return ARGP_ERR_UNKNOWN;
+ }
+ return 0;
+}
+
const char doc[] = "remote execution daemon";
static struct argp argp = {
- NULL,
- NULL,
+ options,
+ parse_opt,
NULL,
doc,
NULL,
@@ -121,12 +144,20 @@ main (int argc, char **argv)
iu_argp_init ("rexecd", default_program_authors);
argp_parse (&argp, argc, argv, 0, &index, NULL);
+
+ openlog ("rexecd", LOG_PID | LOG_ODELAY | LOG_NOWAIT, LOG_DAEMON);
+
if (argc > index)
- error (EXIT_FAILURE, 0, "surplus arguments");
+ /* Record this complaint locally. */
+ syslog (LOG_NOTICE, "%d extra arguments", argc - index);
fromlen = sizeof (from);
if (getpeername (sockfd, (struct sockaddr *) &from, &fromlen) < 0)
- error (EXIT_FAILURE, errno, "getpeername");
+ {
+ syslog (LOG_ERR, "getpeername: %m");
+ error (EXIT_FAILURE, errno, "getpeername");
+ }
+
doit (sockfd, (struct sockaddr *) &from, fromlen);
exit (EXIT_SUCCESS);
}
@@ -161,7 +192,8 @@ doit (int f, struct sockaddr *fromp, socklen_t fromlen)
char *cmdbuf, *cp, *namep;
char *user, *pass, *pw_password;
struct passwd *pwd;
- int s;
+ char rhost[INET6_ADDRSTRLEN];
+ int s, ret;
in_port_t port;
int pv[2], pid, cc;
fd_set readfrom, ready;
@@ -188,13 +220,28 @@ doit (int f, struct sockaddr *fromp, socklen_t fromlen)
dup2 (f, STDERR_FILENO);
}
+ ret = getnameinfo (fromp, fromlen, rhost, sizeof (rhost),
+ NULL, 0, NI_NUMERICHOST);
+ if (ret)
+ {
+ syslog (LOG_WARNING, "getnameinfo: %m");
+ strncpy (rhost, "(unknown)", sizeof (rhost));
+ }
+
+ if (logging > 1)
+ syslog (LOG_INFO, "request from \"%s\"", rhost);
+
alarm (60);
port = 0;
for (;;)
{
char c;
if (read (f, &c, 1) != 1)
- exit (EXIT_FAILURE);
+ {
+ if (logging)
+ syslog (LOG_ERR, "main socket: %m");
+ exit (EXIT_FAILURE);
+ }
if (c == 0)
break;
port = port * 10 + c - '0';
@@ -205,7 +252,11 @@ doit (int f, struct sockaddr *fromp, socklen_t fromlen)
{
s = socket (fromp->sa_family, SOCK_STREAM, 0);
if (s < 0)
- exit (EXIT_FAILURE);
+ {
+ if (logging)
+ syslog (LOG_ERR, "stderr socket: %m");
+ exit (EXIT_FAILURE);
+ }
setsockopt (s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof (one));
alarm (60);
switch (fromp->sa_family)
@@ -217,10 +268,18 @@ doit (int f, struct sockaddr *fromp, socklen_t fromlen)
((struct sockaddr_in6 *) fromp)->sin6_port = htons (port);
break;
default:
+ syslog (LOG_ERR, "unknown address family %d", fromp->sa_family);
exit (EXIT_FAILURE);
}
if (connect (s, fromp, fromlen) < 0)
- exit (EXIT_FAILURE);
+ {
+ /* Use LOG_NOTICE since the remote part might cause
+ * this error by blocking. We are less probable.
+ */
+ if (logging)
+ syslog (LOG_NOTICE, "connect: %m");
+ exit (EXIT_FAILURE);
+ }
alarm (0);
}
@@ -232,7 +291,11 @@ doit (int f, struct sockaddr *fromp, socklen_t fromlen)
pwd = getpwnam (user);
if (pwd == NULL)
- die (EXIT_FAILURE, "Login incorrect.");
+ {
+ if (logging)
+ syslog (LOG_WARNING, "no user named \"%s\"", user);
+ die (EXIT_FAILURE, "Login incorrect.");
+ }
endpwent ();
@@ -242,7 +305,11 @@ doit (int f, struct sockaddr *fromp, socklen_t fromlen)
{
namep = crypt (pass, pw_password);
if (strcmp (namep, pw_password))
- die (EXIT_FAILURE, "Password incorrect.");
+ {
+ if (logging)
+ syslog (LOG_WARNING, "password failure for \"%s\"", user);
+ die (EXIT_FAILURE, "Password incorrect.");
+ }
}
/* Step down from superuser personality.
@@ -252,22 +319,36 @@ doit (int f, struct sockaddr *fromp, socklen_t fromlen)
* case. These messages are non-standard.
*/
if (setgid ((gid_t) pwd->pw_gid) < 0)
- die (EXIT_FAILURE, "Failed group protections.");
+ {
+ syslog (LOG_DEBUG, "setgid(gid = %d): %m", pwd->pw_gid);
+ die (EXIT_FAILURE, "Failed group protections.");
+ }
#ifdef HAVE_INITGROUPS
if (initgroups (pwd->pw_name, pwd->pw_gid) < 0)
- die (EXIT_FAILURE, "Failed group protections.");
+ {
+ syslog (LOG_DEBUG, "initgroups(%s, %s): %m",
+ pwd->pw_name, pwd->pw_gid);
+ die (EXIT_FAILURE, "Failed group protections.");
+ }
#endif
if (setuid ((uid_t) pwd->pw_uid) < 0)
- die (EXIT_FAILURE, "Failed user identity.");
+ {
+ syslog (LOG_DEBUG, "setuid(uid = %d): %m", pwd->pw_uid);
+ die (EXIT_FAILURE, "Failed user identity.");
+ }
if (port)
{
pipe (pv);
pid = fork ();
if (pid == -1)
- die (EXIT_FAILURE, "Try again.");
+ {
+ if (logging)
+ syslog (LOG_ERR, "forking for \"%s\": %m", user);
+ die (EXIT_FAILURE, "Try again.");
+ }
if (pid)
{
@@ -325,7 +406,11 @@ doit (int f, struct sockaddr *fromp, socklen_t fromlen)
/* Last point of failure due to incorrect user settings. */
if (chdir (pwd->pw_dir) < 0)
- die (EXIT_FAILURE, "No remote directory.");
+ {
+ if (logging)
+ syslog (LOG_NOTICE, "\"%s\" uses invalid \"%s\"", user, pwd->pw_dir);
+ die (EXIT_FAILURE, "No remote directory.");
+ }
strcat (path, PATH_DEFPATH);
environ = envinit;
@@ -348,8 +433,12 @@ doit (int f, struct sockaddr *fromp, socklen_t fromlen)
* execution can be handed over to the requested shell.
*/
write (STDERR_FILENO, "\0", 1);
+ if (logging)
+ syslog (LOG_INFO, "accepted user \"%s\" from %s", user, rhost);
execl (pwd->pw_shell, cp, "-c", cmdbuf, NULL);
+ if (logging)
+ syslog (LOG_ERR, "execl fails for \"%s\": %m", user);
error (EXIT_FAILURE, errno, "executing %s", pwd->pw_shell);
return -1;
-----------------------------------------------------------------------
Summary of changes:
ChangeLog | 20 +++++++++
doc/inetutils.texi | 76 ++++++++++++++++++++++++++++-----
src/rexec.c | 8 ++++
src/rexecd.c | 119 +++++++++++++++++++++++++++++++++++++++++++++-------
4 files changed, 196 insertions(+), 27 deletions(-)
hooks/post-receive
--
GNU Inetutils
_______________________________________________
Commit-inetutils mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/commit-inetutils