summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 0d95967)
raw | patch | inline | side by side (parent: 0d95967)
author | Florian Forster <octo@leeloo.lan.home.verplant.org> | |
Thu, 1 Oct 2009 08:28:10 +0000 (10:28 +0200) | ||
committer | Florian Forster <octo@leeloo.lan.home.verplant.org> | |
Thu, 1 Oct 2009 08:28:10 +0000 (10:28 +0200) |
This tries to solve the read-from-any-file-issue more elegantly by
dropping privileges first thing after start-up and regaining privileges
just to open the sockets.
This has the advantage that the "-f" option is available for all users
again and files are opened according to *their* permissions.
Systems not supporting the _POSIX_SAVED_IDS feature still behave as
before, i. e. if real and effective user IDs don't match, only "-" may
be specified as input file.
dropping privileges first thing after start-up and regaining privileges
just to open the sockets.
This has the advantage that the "-f" option is available for all users
again and files are opened according to *their* permissions.
Systems not supporting the _POSIX_SAVED_IDS feature still behave as
before, i. e. if real and effective user IDs don't match, only "-" may
be specified as input file.
src/oping.c | patch | blob | history |
diff --git a/src/oping.c b/src/oping.c
index 3d1edddccb4819479d125387b8a5da3c40428622..d27f187963dc511395c54bad8566f6f2c9d12562 100644 (file)
--- a/src/oping.c
+++ b/src/oping.c
# include <string.h>
# include <errno.h>
# include <assert.h>
-# include <unistd.h>
#else
# error "You don't have the standard C99 header files installed"
#endif /* STDC_HEADERS */
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
#if HAVE_MATH_H
# include <math.h>
#endif
# include <signal.h>
#endif
+#if HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+
#include "oping.h"
+#ifndef _POSIX_SAVED_IDS
+# define _POSIX_SAVED_IDS 0
+#endif
+
typedef struct ping_context
{
char host[NI_MAXHOST];
exit (status);
}
-static _Bool is_setuid (void)
-{
- return (getuid () != geteuid ());
-}
-
static int read_options (int argc, char **argv)
{
int optchar;
break;
case 'f':
- if (is_setuid () && (strcmp ("-", optarg) != 0))
- {
- fprintf (stderr, "For security reasons the `-f' option "
- "is disabled if real and effective "
- "user IDs don't match. Sorry.\n");
- }
- else
{
if (opt_filename != NULL)
free (opt_filename);
int optind;
int i;
+ int status;
+#if _POSIX_SAVED_IDS
+ uid_t saved_set_uid;
+
+ /* Save the old effective user id */
+ saved_set_uid = geteuid ();
+ /* Set the effective user ID to the real user ID without changing the
+ * saved set-user ID */
+ status = seteuid (getuid ());
+ if (status != 0)
+ {
+ fprintf (stderr, "Temporarily dropping privileges "
+ "failed: %s\n", strerror (errno));
+ exit (EXIT_FAILURE);
+ }
+#endif
optind = read_options (argc, argv);
- if ((optind >= argc) && (opt_filename == NULL)) {
- usage_exit (argv[0], 1);
+#if !_POSIX_SAVED_IDS
+ /* Cannot temporarily drop privileges -> reject every file but "-". */
+ if ((opt_filename != NULL)
+ && (strcmp ("-", opt_filename) != 0)
+ && (getuid () != geteuid ()))
+ {
+ fprintf (stderr, "Your real and effective user IDs don't "
+ "match. Reading from a file (option '-f')\n"
+ "is therefore too risky. You can still read "
+ "from STDIN using '-f -' if you like.\n"
+ "Sorry.\n");
+ exit (EXIT_FAILURE);
}
+#endif
- if (geteuid () != 0)
- {
- fprintf (stderr, "Need superuser privileges to open a RAW socket. Sorry.\n");
- return (1);
+ if ((optind >= argc) && (opt_filename == NULL)) {
+ usage_exit (argv[0], 1);
}
if ((ping = ping_construct ()) == NULL)
return (1);
}
+#if _POSIX_SAVED_IDS
+ /* Regain privileges */
+ status = seteuid (saved_set_uid);
+ if (status != 0)
+ {
+ fprintf (stderr, "Temporarily re-gaining privileges "
+ "failed: %s\n", strerror (errno));
+ exit (EXIT_FAILURE);
+ }
+#endif
+
while (fgets(line, sizeof(line), infile))
{
/* Strip whitespace */
}
}
+#if _POSIX_SAVED_IDS
+ /* Drop privileges */
+ status = seteuid (getuid ());
+ if (status != 0)
+ {
+ fprintf (stderr, "Temporarily dropping privileges "
+ "failed: %s\n", strerror (errno));
+ exit (EXIT_FAILURE);
+ }
+#endif
+
fclose(infile);
}
+#if _POSIX_SAVED_IDS
+ /* Regain privileges */
+ status = seteuid (saved_set_uid);
+ if (status != 0)
+ {
+ fprintf (stderr, "Temporarily re-gaining privileges "
+ "failed: %s\n", strerror (errno));
+ exit (EXIT_FAILURE);
+ }
+#endif
+
for (i = optind; i < argc; i++)
{
if (ping_host_add (ping, argv[i]) < 0)
}
}
- /* Drop root privileges if we're setuid-root. */
- setuid (getuid ());
+ /* Permanently drop root privileges if we're setuid-root. */
+ status = setuid (getuid ());
+ if (status != 0)
+ {
+ fprintf (stderr, "Dropping privileges failed: %s\n",
+ strerror (errno));
+ exit (EXIT_FAILURE);
+ }
+
+#if _POSIX_SAVED_IDS
+ saved_set_uid = (uid_t) -1;
+#endif
i = 0;
for (iter = ping_iterator_get (ping);