diff options
author | Matthias Clasen <mclasen@redhat.com> | 2010-03-25 14:43:54 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2010-03-25 14:43:54 -0400 |
commit | 224b7e93a27a1ab5cf2eec2f56bc3adafd02e7af (patch) | |
tree | a5ed9cd6c60171d62cafd1f883d5647012ccce8b | |
parent | f9a5229aa7f1eae3a0481a41e88d7edbc15a649c (diff) |
Set loginuid properly when running commands on behalf of a user
This makes the audit log have the right information
-rw-r--r-- | src/daemon.c | 33 | ||||
-rw-r--r-- | src/user.c | 156 | ||||
-rw-r--r-- | src/util.c | 72 | ||||
-rw-r--r-- | src/util.h | 4 |
4 files changed, 87 insertions, 178 deletions
diff --git a/src/daemon.c b/src/daemon.c index 50ae3b9..7f6a088 100644 --- a/src/daemon.c +++ b/src/daemon.c @@ -1022,8 +1022,6 @@ daemon_create_user_authorized_cb (Daemon *daemon, CreateUserData *cd = data; User *user; GError *error; - gchar *std_err, *std_out; - gint status; gchar *argv[8]; if (getpwnam (cd->user_name) != NULL) { @@ -1055,27 +1053,13 @@ daemon_create_user_authorized_cb (Daemon *daemon, argv[5] = NULL; } - std_out = NULL; - std_err = NULL; error = NULL; - if (!g_spawn_sync (NULL, argv, NULL, 0, NULL, NULL, &std_out, &std_err, &status, &error)) { + if (!spawn_with_login_uid (context, argv, &error)) { throw_error (context, ERROR_FAILED, "running '%s' failed: %s", argv[0], error->message); g_error_free (error); - g_free (std_out); - g_free (std_err); return; } - if (WEXITSTATUS (status) != 0) { - throw_error (context, ERROR_FAILED, "useradd returned an error: %s", std_err); - g_free (std_out); - g_free (std_err); - return; - } - - g_free (std_out); - g_free (std_err); - user = daemon_local_find_user_by_name (daemon, cd->user_name); dbus_g_method_return (context, user_local_get_object_path (user)); @@ -1121,8 +1105,6 @@ daemon_delete_user_authorized_cb (Daemon *daemon, { DeleteUserData *ud = data; GError *error; - gchar *std_err, *std_out; - gint status; gchar *filename; struct passwd *pwent; gchar *argv[4]; @@ -1148,21 +1130,10 @@ daemon_delete_user_authorized_cb (Daemon *daemon, argv[2] = NULL; } - std_out = NULL; - std_err = NULL; error = NULL; - if (!g_spawn_sync (NULL, argv, NULL, 0, NULL, NULL, &std_out, &std_err, &status, &error)) { + if (!spawn_with_login_uid (context, argv, &error)) { throw_error (context, ERROR_FAILED, "running '%s' failed: %s", argv[0], error->message); g_error_free (error); - g_free (std_out); - g_free (std_err); - return; - } - - if (WEXITSTATUS (status) != 0) { - throw_error (context, ERROR_FAILED, "userdel returned an error: %s", std_err); - g_free (std_out); - g_free (std_err); return; } @@ -769,8 +769,6 @@ user_change_real_name_authorized_cb (Daemon *daemon, { gchar *name = data; GError *error; - gint status; - gchar *std_out, *std_err; gchar *argv[5]; if (g_strcmp0 (user->real_name, name) != 0) { @@ -784,27 +782,13 @@ user_change_real_name_authorized_cb (Daemon *daemon, argv[3] = user->user_name; argv[4] = NULL; - std_out = NULL; - std_err = NULL; error = NULL; - if (!g_spawn_sync (NULL, argv, NULL, 0, NULL, NULL, &std_out, &std_err, &status, &error)) { + if (!spawn_with_login_uid (context, argv, &error)) { throw_error (context, ERROR_FAILED, "running '%s' failed: %s", argv[0], error->message); g_error_free (error); - g_free (std_out); - g_free (std_err); return; } - if (WEXITSTATUS (status) != 0) { - throw_error (context, ERROR_FAILED, "usermod returned an error: %s", std_err); - g_free (std_out); - g_free (std_err); - return; - } - - g_free (std_out); - g_free (std_err); - g_free (user->real_name); user->real_name = g_strdup (name); @@ -865,8 +849,6 @@ user_change_user_name_authorized_cb (Daemon *daemon, gchar *name = data; gchar *old_name; GError *error; - gint status; - gchar *std_out, *std_err; gchar *argv[5]; if (g_strcmp0 (user->user_name, name) != 0) { @@ -881,27 +863,13 @@ user_change_user_name_authorized_cb (Daemon *daemon, argv[3] = user->user_name; argv[4] = NULL; - std_out = NULL; - std_err = NULL; error = NULL; - if (!g_spawn_sync (NULL, argv, NULL, 0, NULL, NULL, &std_out, &std_err, &status, &error)) { + if (!spawn_with_login_uid (context, argv, &error)) { throw_error (context, ERROR_FAILED, "running '%s' failed: %s", argv[0], error->message); g_error_free (error); - g_free (std_out); - g_free (std_err); return; } - if (WEXITSTATUS (status) != 0) { - throw_error (context, ERROR_FAILED, "usermod returned an error: %s", std_err); - g_free (std_out); - g_free (std_err); - return; - } - - g_free (std_out); - g_free (std_err); - g_free (user->user_name); user->user_name = g_strdup (name); @@ -1154,8 +1122,6 @@ user_change_home_dir_authorized_cb (Daemon *daemon, { gchar *home_dir = data; GError *error; - gint status; - gchar *std_out, *std_err; gchar *argv[6]; if (g_strcmp0 (user->home_dir, home_dir) != 0) { @@ -1170,27 +1136,13 @@ user_change_home_dir_authorized_cb (Daemon *daemon, argv[4] = user->user_name; argv[5] = NULL; - std_out = NULL; - std_err = NULL; error = NULL; - if (!g_spawn_sync (NULL, argv, NULL, 0, NULL, NULL, &std_out, &std_err, &status, &error)) { + if (!spawn_with_login_uid (context, argv, &error)) { throw_error (context, ERROR_FAILED, "running '%s' failed: %s", argv[0], error->message); g_error_free (error); - g_free (std_out); - g_free (std_err); return; } - if (WEXITSTATUS (status) != 0) { - throw_error (context, ERROR_FAILED, "usermod returned an error: %s", std_err); - g_free (std_out); - g_free (std_err); - return; - } - - g_free (std_out); - g_free (std_err); - g_free (user->home_dir); user->home_dir = g_strdup (home_dir); @@ -1247,8 +1199,6 @@ user_change_shell_authorized_cb (Daemon *daemon, { gchar *shell = data; GError *error; - gint status; - gchar *std_out, *std_err; gchar *argv[5]; if (g_strcmp0 (user->shell, shell) != 0) { @@ -1262,27 +1212,13 @@ user_change_shell_authorized_cb (Daemon *daemon, argv[3] = user->user_name; argv[4] = NULL; - std_out = NULL; - std_err = NULL; error = NULL; - if (!g_spawn_sync (NULL, argv, NULL, 0, NULL, NULL, &std_out, &std_err, &status, &error)) { + if (!spawn_with_login_uid (context, argv, &error)) { throw_error (context, ERROR_FAILED, "running '%s' failed: %s", argv[0], error->message); g_error_free (error); - g_free (std_out); - g_free (std_err); - return; - } - - if (WEXITSTATUS (status) != 0) { - throw_error (context, ERROR_FAILED, "usermod returned an error: %s", std_err); - g_free (std_out); - g_free (std_err); return; } - g_free (std_out); - g_free (std_err); - g_free (user->shell); user->shell = g_strdup (shell); @@ -1532,8 +1468,6 @@ user_change_locked_authorized_cb (Daemon *daemon, { gboolean locked = GPOINTER_TO_INT (data); GError *error; - gint status; - gchar *std_out, *std_err; gchar *argv[4]; if (user->locked != locked) { @@ -1545,27 +1479,13 @@ user_change_locked_authorized_cb (Daemon *daemon, argv[2] = user->user_name; argv[3] = NULL; - std_out = NULL; - std_err = NULL; error = NULL; - if (!g_spawn_sync (NULL, argv, NULL, 0, NULL, NULL, &std_out, &std_err, &status, &error)) { + if (!spawn_with_login_uid (context, argv, &error)) { throw_error (context, ERROR_FAILED, "running '%s' failed: %s", argv[0], error->message); g_error_free (error); - g_free (std_out); - g_free (std_err); - return; - } - - if (WEXITSTATUS (status) != 0) { - throw_error (context, ERROR_FAILED, "usermod returned an error: %s", std_err); - g_free (std_out); - g_free (std_err); return; } - g_free (std_out); - g_free (std_err); - user->locked = locked; g_signal_emit (user, signals[CHANGED], 0); @@ -1602,8 +1522,6 @@ user_change_account_type_authorized_cb (Daemon *daemon, { gint account_type = GPOINTER_TO_INT (data); GError *error; - gint status; - gchar *std_out, *std_err; gid_t groups[20]; gint n_groups; GString *str; @@ -1664,27 +1582,13 @@ user_change_account_type_authorized_cb (Daemon *daemon, g_string_free (str, FALSE); - std_out = NULL; - std_err = NULL; error = NULL; - if (!g_spawn_sync (NULL, argv, NULL, 0, NULL, NULL, &std_out, &std_err, &status, &error)) { + if (!spawn_with_login_uid (context, argv, &error)) { throw_error (context, ERROR_FAILED, "running '%s' failed: %s", argv[0], error->message); g_error_free (error); - g_free (std_out); - g_free (std_err); return; } - if (WEXITSTATUS (status) != 0) { - throw_error (context, ERROR_FAILED, "usermod returned an error: %s", std_err); - g_free (std_out); - g_free (std_err); - return; - } - - g_free (std_out); - g_free (std_err); - user->account_type = account_type; g_signal_emit (user, signals[CHANGED], 0); @@ -1726,8 +1630,6 @@ user_change_password_mode_authorized_cb (Daemon *daemon, { gint mode = GPOINTER_TO_INT (data); GError *error; - gint status; - gchar *std_out, *std_err; gchar *argv[4]; if (user->password_mode != mode) { @@ -1745,27 +1647,13 @@ user_change_password_mode_authorized_cb (Daemon *daemon, argv[2] = user->user_name; argv[3] = NULL; - std_out = NULL; - std_err = NULL; error = NULL; - if (!g_spawn_sync (NULL, argv, NULL, 0, NULL, NULL, &std_out, &std_err, &status, &error)) { + if (!spawn_with_login_uid (context, argv, &error)) { throw_error (context, ERROR_FAILED, "running '%s' failed: %s", argv[0], error->message); g_error_free (error); - g_free (std_out); - g_free (std_err); return; } - if (WEXITSTATUS (status) != 0) { - throw_error (context, ERROR_FAILED, "passwd returned an error: %s", std_err); - g_free (std_out); - g_free (std_err); - return; - } - - g_free (std_out); - g_free (std_err); - g_free (user->password_hint); user->password_hint = NULL; @@ -1785,20 +1673,10 @@ user_change_password_mode_authorized_cb (Daemon *daemon, argv[2] = user->user_name; argv[3] = NULL; - std_out = NULL; - std_err = NULL; error = NULL; - if (!g_spawn_sync (NULL, argv, NULL, 0, NULL, NULL, &std_out, &std_err, &status, &error)) { + if (!spawn_with_login_uid (context, argv, &error)) { throw_error (context, ERROR_FAILED, "running '%s' failed: %s", argv[0], error->message); g_error_free (error); - g_free (std_out); - g_free (std_err); - return; - } - if (WEXITSTATUS (status) != 0) { - throw_error (context, ERROR_FAILED, "usermod returned an error: %s", std_err); - g_free (std_out); - g_free (std_err); return; } @@ -1870,8 +1748,6 @@ user_change_password_authorized_cb (Daemon *daemon, { gchar **strings = data; GError *error; - gint status; - gchar *std_out, *std_err; gchar *argv[5]; sys_log (context, @@ -1886,27 +1762,13 @@ user_change_password_authorized_cb (Daemon *daemon, argv[3] = user->user_name; argv[4] = NULL; - std_out = NULL; - std_err = NULL; error = NULL; - if (!g_spawn_sync (NULL, argv, NULL, 0, NULL, NULL, &std_out, &std_err, &status, &error)) { + if (!spawn_with_login_uid (context, argv, &error)) { throw_error (context, ERROR_FAILED, "running '%s' failed: %s", argv[0], error->message); g_error_free (error); - g_free (std_out); - g_free (std_err); return; } - if (WEXITSTATUS (status) != 0) { - throw_error (context, ERROR_FAILED, "usermod returned an error: %s", std_err); - g_free (std_out); - g_free (std_err); - return; - } - - g_free (std_out); - g_free (std_err); - if (user->password_mode != PASSWORD_MODE_REGULAR) { user->password_mode = PASSWORD_MODE_REGULAR; g_object_notify (G_OBJECT (user), "password-mode"); @@ -21,7 +21,14 @@ #include "config.h" +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <wait.h> + #include <syslog.h> + #include <dbus/dbus-glib.h> #include <dbus/dbus-glib-lowlevel.h> @@ -142,3 +149,68 @@ sys_log (DBusGMethodInvocation *context, g_free (real_format); } + +static gint +get_caller_uid (DBusGMethodInvocation *context) +{ + PolkitSubject *subject; + gchar *cmdline; + gint pid; + gint uid; + + subject = polkit_system_bus_name_new (dbus_g_method_get_sender (context)); + cmdline = _polkit_subject_get_cmdline (subject, &pid, &uid); + + g_object_unref (subject); + g_free (cmdline); + + return uid; +} + +static void +setup_loginuid (gpointer data) +{ + const char *id = data; + int fd; + + fd = open ("/proc/self/loginuid", O_WRONLY); + write (fd, id, strlen (id)); + close (fd); +} + +gboolean +spawn_with_login_uid (DBusGMethodInvocation *context, + gchar *argv[], + GError **error) +{ + GError *local_error; + gchar loginuid[20]; + gchar *std_err; + gint status; + + g_snprintf (loginuid, 20, "%d", get_caller_uid (context)); + + local_error = NULL; + std_err = NULL; + + if (!g_spawn_sync (NULL, argv, NULL, 0, setup_loginuid, loginuid, NULL, &std_err, &status, &local_error)) { + g_propagate_error (error, local_error); + g_free (std_err); + return FALSE; + } + + if (WEXITSTATUS (status) != 0) { + g_set_error (error, + G_SPAWN_ERROR, + G_SPAWN_ERROR_FAILED, + "%s returned an error (%d): %s", + argv[0], WEXITSTATUS(status), std_err); + g_free (std_err); + return FALSE; + } + + g_free (std_err); + + return TRUE; +} + @@ -31,6 +31,10 @@ void sys_log (DBusGMethodInvocation *context, const gchar *format, ...); +gboolean spawn_with_login_uid (DBusGMethodInvocation *context, + gchar *argv[], + GError **error); + G_END_DECLS #endif /* __UTIL_H__ */ |