Commit 12e4ee33 authored by David Zeuthen's avatar David Zeuthen

Make pkexec(1) use the syslogging facilities

Dec 15 13:48:05 localhost pkexec[29065]: davidz: Executing command [USER=root] [TTY=/dev/pts/8] [CWD=/root] [COMMAND=/usr/bin/pk-example-frobnicate]

Dec 15 13:49:30 localhost pkexec[29080]: davidz: The value for the SHELL variable was not found the /etc/shells file [USER=root] [TTY=/dev/pts/5] [CWD=/home/davidz] [COMMAND=/bin/bash]

Dec 15 13:49:45 localhost pkexec[29082]: davidz: The value for environment variable LC_ALL contains suscipious content [USER=root] [TTY=/dev/pts/5] [CWD=/home/davidz] [COMMAND=/bin/bash]

Dec 15 13:50:03 localhost pkexec[29086]: davidz: Error executing command as another user: Not authorized [USER=root] [TTY=/dev/pts/5] [CWD=/home/davidz] [COMMAND=/bin/bash]
Signed-off-by: default avatarDavid Zeuthen <davidz@redhat.com>
parent 5a388b6e
......@@ -23,6 +23,8 @@
# include "config.h"
#endif
#define _GNU_SOURCE
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
......@@ -33,9 +35,15 @@
#include <pwd.h>
#include <errno.h>
#include <security/pam_appl.h>
#include <syslog.h>
#include <stdarg.h>
#include <polkit/polkit.h>
static gchar *original_user_name = NULL;
static gchar *command_line = NULL;
static struct passwd *pw;
#ifndef HAVE_CLEARENV
extern char **environ;
......@@ -60,6 +68,54 @@ usage (int argc, char *argv[])
/* ---------------------------------------------------------------------------------------------------- */
static void
log_message (gint level,
gboolean print_to_stderr,
const gchar *format,
...)
{
static gboolean is_log_open = FALSE;
va_list var_args;
gchar *s;
const gchar *cwd;
const gchar *tty;
if (!is_log_open)
{
openlog ("pkexec",
LOG_PID,
LOG_AUTHPRIV); /* security/authorization messages (private) */
is_log_open = TRUE;
}
va_start (var_args, format);
s = g_strdup_vprintf (format, var_args);
va_end (var_args);
cwd = get_current_dir_name ();
tty = ttyname (0);
if (tty == NULL)
tty = "unknown";
/* first complain to syslog */
syslog (level,
"%s: %s [USER=%s] [TTY=%s] [CWD=%s] [COMMAND=%s]",
original_user_name,
s,
pw->pw_name,
tty,
cwd,
command_line);
/* and then on stderr */
if (print_to_stderr)
g_printerr ("%s\n", s);
g_free (s);
}
/* ---------------------------------------------------------------------------------------------------- */
static int
pam_conversation_function (int n,
const struct pam_message **msg,
......@@ -275,9 +331,10 @@ validate_environment_variable (const gchar *key,
/* check if it's in /etc/shells */
if (!is_valid_shell (value))
{
g_printerr ("The value for environment variable SHELL is not included in the\n"
"/etc/shells file. This incident will be reported. Bailing out.\n");
/* TODO: syslog */
log_message (LOG_CRIT, TRUE,
"The value for the SHELL variable was not found the /etc/shells file.");
g_printerr ("\n"
"This incident has been reported.\n");
goto out;
}
}
......@@ -285,10 +342,11 @@ validate_environment_variable (const gchar *key,
strstr (value, "%") != NULL ||
strstr (value, "..") != NULL)
{
g_printerr ("The value for environment variable %s contains suscipious content\n"
"indicating an exploit. This incident will be reported. Bailing out.\n",
key);
/* TODO: syslog */
log_message (LOG_CRIT, TRUE,
"The value for environment variable %s contains suscipious content.",
key);
g_printerr ("\n"
"This incident has been reported.\n");
goto out;
}
......@@ -314,11 +372,9 @@ main (int argc, char *argv[])
PolkitDetails *details;
GError *error;
gchar *action_id;
gchar *command_line;
gchar **exec_argv;
gchar *path;
struct passwd pwstruct;
struct passwd *pw;
gchar pwbuf[8192];
gchar *s;
const gchar *environment_variables_to_save[] = {
......@@ -376,6 +432,8 @@ main (int argc, char *argv[])
goto out;
}
original_user_name = g_strdup (g_get_user_name ());
/* First process options and find the command-line to invoke. Avoid using fancy library routines
* that depend on environtment variables since we haven't cleared the environment just yet.
*/
......@@ -459,6 +517,21 @@ main (int argc, char *argv[])
command_line = g_strjoinv (" ", argv + n);
exec_argv = argv + n;
/* Look up information about the user we care about - yes, the return
* value of this function is a bit funky
*/
rc = getpwnam_r (opt_user, &pwstruct, pwbuf, sizeof pwbuf, &pw);
if (rc == 0 && pw == NULL)
{
g_printerr ("User `%s' does not exist.\n", opt_user);
goto out;
}
else if (pw == NULL)
{
g_printerr ("Error getting information for user `%s': %s\n", opt_user, g_strerror (rc));
goto out;
}
/* now save the environment variables we care about */
saved_env = g_ptr_array_new ();
for (n = 0; environment_variables_to_save[n] != NULL; n++)
......@@ -490,21 +563,6 @@ main (int argc, char *argv[])
goto out;
}
/* Look up information about the user we care about - yes, the return
* value of this function is a bit funky
*/
rc = getpwnam_r (opt_user, &pwstruct, pwbuf, sizeof pwbuf, &pw);
if (rc == 0 && pw == NULL)
{
g_printerr ("User `%s' does not exist.\n", opt_user);
goto out;
}
else if (pw == NULL)
{
g_printerr ("Error getting information for user `%s': %s\n", opt_user, g_strerror (rc));
goto out;
}
/* Initialize the GLib type system - this is needed to interact with the
* PolicyKit daemon
*/
......@@ -583,14 +641,15 @@ main (int argc, char *argv[])
}
else if (polkit_authorization_result_get_is_challenge (result))
{
g_printerr ("Authorization requires authentication but no authentication agent was found.\n");
/* TODO: syslog */
g_printerr ("Error executing command as another user: No authentication agent was found.\n");
goto out;
}
else
{
g_printerr ("Not authorized.\n");
/* TODO: syslog */
log_message (LOG_WARNING, TRUE,
"Error executing command as another user: Not authorized");
g_printerr ("\n"
"This incident has been reported.\n");
goto out;
}
......@@ -704,7 +763,8 @@ main (int argc, char *argv[])
goto out;
}
/* TODO: syslog */
/* Log the fact that we're executing a command */
log_message (LOG_NOTICE, FALSE, "Executing command");
/* exec the program */
if (execv (path, exec_argv) != 0)
......@@ -740,6 +800,7 @@ main (int argc, char *argv[])
g_free (path);
g_free (command_line);
g_free (opt_user);
g_free (original_user_name);
return ret;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment