Matthias Clasen 7097ae
From 0a4c2503e0a6b1bdb34f3fa8f6644250eccbc445 Mon Sep 17 00:00:00 2001
Matthias Clasen 7097ae
From: Matthias Clasen <mclasen@redhat.com>
Matthias Clasen 7097ae
Date: Fri, 19 Mar 2010 19:28:56 -0400
Matthias Clasen 7097ae
Subject: [PATCH] Avoid extraneous commandline parsing
Matthias Clasen 7097ae
Matthias Clasen 7097ae
Switch to using g_spawn_sync instead of g_spawn_command_line_sync
Matthias Clasen 7097ae
to avoid the pointless roundtrip through a commandline parser, avoiding
Matthias Clasen 7097ae
some security pitfalls.
Matthias Clasen 7097ae
---
Matthias Clasen 7097ae
 src/daemon.c |   46 ++++++++++++++++--------
Matthias Clasen 7097ae
 src/user.c   |  115 ++++++++++++++++++++++++++++++++++------------------------
Matthias Clasen 7097ae
 2 files changed, 98 insertions(+), 63 deletions(-)
Matthias Clasen 7097ae
Matthias Clasen 7097ae
diff --git a/src/daemon.c b/src/daemon.c
Matthias Clasen 7097ae
index a962dc3..18a23fe 100644
Matthias Clasen 7097ae
--- a/src/daemon.c
Matthias Clasen 7097ae
+++ b/src/daemon.c
Matthias Clasen 7097ae
@@ -922,7 +922,7 @@ typedef struct {
Matthias Clasen 7097ae
         DBusGMethodInvocation *context;
Matthias Clasen 7097ae
 } ListUserData;
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
-ListUserData *
Matthias Clasen 7097ae
+static ListUserData *
Matthias Clasen 7097ae
 list_user_data_new (Daemon                *daemon,
Matthias Clasen 7097ae
                     DBusGMethodInvocation *context)
Matthias Clasen 7097ae
 {
Matthias Clasen 7097ae
@@ -1006,11 +1006,10 @@ daemon_create_user_authorized_cb (Daemon                *daemon,
Matthias Clasen 7097ae
 {
Matthias Clasen 7097ae
         CreateUserData *cd = data;
Matthias Clasen 7097ae
         User *user;
Matthias Clasen 7097ae
-        gchar *cmdline;
Matthias Clasen 7097ae
         GError *error;
Matthias Clasen 7097ae
         gchar *std_err, *std_out;
Matthias Clasen 7097ae
         gint status;
Matthias Clasen 7097ae
-        const gchar *grouparg;
Matthias Clasen 7097ae
+        gchar *argv[8];
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
         if (getpwnam (cd->user_name) != NULL) {
Matthias Clasen 7097ae
                 throw_error (context, ERROR_USER_EXISTS, "A user with name '%s' already exists", cd->user_name);
Matthias Clasen 7097ae
@@ -1022,22 +1021,32 @@ daemon_create_user_authorized_cb (Daemon                *daemon,
Matthias Clasen 7097ae
                           "create user '%s'",
Matthias Clasen 7097ae
                           cd->user_name);
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
+        argv[0] = "/usr/sbin/useradd";
Matthias Clasen 7097ae
+        argv[1] = "-m";
Matthias Clasen 7097ae
+        argv[2] = "-c";
Matthias Clasen 7097ae
+        argv[3] = cd->real_name;
Matthias Clasen 7097ae
         if (cd->account_type == ACCOUNT_TYPE_ADMINISTRATOR) {
Matthias Clasen 7097ae
-                grouparg = "-G desktop_admin_r";
Matthias Clasen 7097ae
+                argv[4] = "-G";
Matthias Clasen 7097ae
+                argv[5] = "desktop_admin_r";
Matthias Clasen 7097ae
+                argv[6] = cd->user_name;
Matthias Clasen 7097ae
+                argv[7] = NULL;
Matthias Clasen 7097ae
         }
Matthias Clasen 7097ae
         else if (cd->account_type == ACCOUNT_TYPE_STANDARD) {
Matthias Clasen 7097ae
-                grouparg = "-G desktop_user_r";
Matthias Clasen 7097ae
+                argv[4] = "-G";
Matthias Clasen 7097ae
+                argv[5] = "desktop_user_r";
Matthias Clasen 7097ae
+                argv[6] = cd->user_name;
Matthias Clasen 7097ae
+                argv[7] = NULL;
Matthias Clasen 7097ae
         }
Matthias Clasen 7097ae
         else {
Matthias Clasen 7097ae
-                grouparg = "";
Matthias Clasen 7097ae
+                argv[4] = cd->user_name;
Matthias Clasen 7097ae
+                argv[5] = NULL;
Matthias Clasen 7097ae
         }
Matthias Clasen 7097ae
-        cmdline = g_strdup_printf ("/usr/sbin/useradd -m -c '%s' %s %s", cd->real_name, grouparg, cd->user_name);
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
         std_out = NULL;
Matthias Clasen 7097ae
         std_err = NULL;
Matthias Clasen 7097ae
         error = NULL;
Matthias Clasen 7097ae
-        if (!g_spawn_command_line_sync (cmdline, &std_out, &std_err, &status, &error)) {
Matthias Clasen 7097ae
-                throw_error (context, ERROR_FAILED, "running '%s' failed: %s", cmdline, error->message);
Matthias Clasen 7097ae
+        if (!g_spawn_sync (NULL, argv, NULL, 0, NULL, NULL, &std_out, &std_err, &status, &error)) {
Matthias Clasen 7097ae
+                throw_error (context, ERROR_FAILED, "running '%s' failed: %s", argv[0], error->message);
Matthias Clasen 7097ae
                 g_error_free (error);
Matthias Clasen 7097ae
                 g_free (std_out);
Matthias Clasen 7097ae
                 g_free (std_err);
Matthias Clasen 7097ae
@@ -1051,7 +1060,6 @@ daemon_create_user_authorized_cb (Daemon                *daemon,
Matthias Clasen 7097ae
                 return;
Matthias Clasen 7097ae
         }
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
-        g_free (cmdline);
Matthias Clasen 7097ae
         g_free (std_out);
Matthias Clasen 7097ae
         g_free (std_err);
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
@@ -1099,12 +1107,12 @@ daemon_delete_user_authorized_cb (Daemon                *daemon,
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
 {
Matthias Clasen 7097ae
         DeleteUserData *ud = data;
Matthias Clasen 7097ae
-        gchar *cmdline;
Matthias Clasen 7097ae
         GError *error;
Matthias Clasen 7097ae
         gchar *std_err, *std_out;
Matthias Clasen 7097ae
         gint status;
Matthias Clasen 7097ae
         gchar *filename;
Matthias Clasen 7097ae
         struct passwd *pwent;
Matthias Clasen 7097ae
+        gchar *argv[4];
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
         pwent = getpwuid (ud->uid);
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
@@ -1118,13 +1126,22 @@ daemon_delete_user_authorized_cb (Daemon                *daemon,
Matthias Clasen 7097ae
                           "delete user '%s' (%d)",
Matthias Clasen 7097ae
                           pwent->pw_name, ud->uid);
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
-        cmdline = g_strdup_printf ("/usr/sbin/userdel %s%s", ud->remove_files ? "-r " : "", pwent->pw_name);
Matthias Clasen 7097ae
+        argv[0] = "/usr/sbin/userdel";
Matthias Clasen 7097ae
+        if (ud->remove_files) {
Matthias Clasen 7097ae
+                argv[1] = "-r";
Matthias Clasen 7097ae
+                argv[2] = pwent->pw_name;
Matthias Clasen 7097ae
+                argv[3] = NULL;
Matthias Clasen 7097ae
+        }
Matthias Clasen 7097ae
+        else {
Matthias Clasen 7097ae
+                argv[1] = pwent->pw_name;
Matthias Clasen 7097ae
+                argv[2] = NULL;
Matthias Clasen 7097ae
+        }
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
         std_out = NULL;
Matthias Clasen 7097ae
         std_err = NULL;
Matthias Clasen 7097ae
         error = NULL;
Matthias Clasen 7097ae
-        if (!g_spawn_command_line_sync (cmdline, &std_out, &std_err, &status, &error)) {
Matthias Clasen 7097ae
-                throw_error (context, ERROR_FAILED, "running '%s' failed: %s", cmdline, error->message);
Matthias Clasen 7097ae
+        if (!g_spawn_sync (NULL, argv, NULL, 0, NULL, NULL, &std_out, &std_err, &status, &error)) {
Matthias Clasen 7097ae
+                throw_error (context, ERROR_FAILED, "running '%s' failed: %s", argv[0], error->message);
Matthias Clasen 7097ae
                 g_error_free (error);
Matthias Clasen 7097ae
                 g_free (std_out);
Matthias Clasen 7097ae
                 g_free (std_err);
Matthias Clasen 7097ae
@@ -1142,7 +1159,6 @@ daemon_delete_user_authorized_cb (Daemon                *daemon,
Matthias Clasen 7097ae
         g_remove (filename);
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
         g_free (filename);
Matthias Clasen 7097ae
-        g_free (cmdline);
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
         dbus_g_method_return (context);
Matthias Clasen 7097ae
 }
Matthias Clasen 7097ae
diff --git a/src/user.c b/src/user.c
Matthias Clasen 7097ae
index a235411..cfdd16c 100644
Matthias Clasen 7097ae
--- a/src/user.c
Matthias Clasen 7097ae
+++ b/src/user.c
Matthias Clasen 7097ae
@@ -737,20 +737,24 @@ user_change_real_name_authorized_cb (Daemon                *daemon,
Matthias Clasen 7097ae
         GError *error;
Matthias Clasen 7097ae
         gint status;
Matthias Clasen 7097ae
         gchar *std_out, *std_err;
Matthias Clasen 7097ae
-        gchar *cmdline;
Matthias Clasen 7097ae
+        gchar *argv[5];
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
         if (g_strcmp0 (user->real_name, name) != 0) {
Matthias Clasen 7097ae
                 daemon_local_log (daemon, context,
Matthias Clasen 7097ae
                                   "change real name of user '%s' (%d) to '%s'",
Matthias Clasen 7097ae
                                   user->user_name, user->uid, name);
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
-                cmdline = g_strdup_printf ("/usr/sbin/usermod -c '%s' %s", name, user->user_name);
Matthias Clasen 7097ae
+                argv[0] = "/usr/sbin/usermod";
Matthias Clasen 7097ae
+                argv[1] = "-c";
Matthias Clasen 7097ae
+                argv[2] = name;
Matthias Clasen 7097ae
+                argv[3] = user->user_name;
Matthias Clasen 7097ae
+                argv[4] = NULL;
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
                 std_out = NULL;
Matthias Clasen 7097ae
                 std_err = NULL;
Matthias Clasen 7097ae
                 error = NULL;
Matthias Clasen 7097ae
-                if (!g_spawn_command_line_sync (cmdline, &std_out, &std_err, &status, &error)) {
Matthias Clasen 7097ae
-                        throw_error (context, ERROR_FAILED, "running '%s' failed: %s", cmdline, error->message);
Matthias Clasen 7097ae
+                if (!g_spawn_sync (NULL, argv, NULL, 0, NULL, NULL, &std_out, &std_err, &status, &error)) {
Matthias Clasen 7097ae
+                        throw_error (context, ERROR_FAILED, "running '%s' failed: %s", argv[0], error->message);
Matthias Clasen 7097ae
                         g_error_free (error);
Matthias Clasen 7097ae
                         g_free (std_out);
Matthias Clasen 7097ae
                         g_free (std_err);
Matthias Clasen 7097ae
@@ -761,13 +765,11 @@ user_change_real_name_authorized_cb (Daemon                *daemon,
Matthias Clasen 7097ae
                         throw_error (context, ERROR_FAILED, "usermod returned an error: %s", std_err);
Matthias Clasen 7097ae
                         g_free (std_out);
Matthias Clasen 7097ae
                         g_free (std_err);
Matthias Clasen 7097ae
-                        g_free (cmdline);
Matthias Clasen 7097ae
                         return;
Matthias Clasen 7097ae
                 }
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
                 g_free (std_out);
Matthias Clasen 7097ae
                 g_free (std_err);
Matthias Clasen 7097ae
-                g_free (cmdline);
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
                 g_free (user->real_name);
Matthias Clasen 7097ae
                 user->real_name = g_strdup (name);
Matthias Clasen 7097ae
@@ -831,7 +833,7 @@ user_change_user_name_authorized_cb (Daemon                *daemon,
Matthias Clasen 7097ae
         GError *error;
Matthias Clasen 7097ae
         gint status;
Matthias Clasen 7097ae
         gchar *std_out, *std_err;
Matthias Clasen 7097ae
-        gchar *cmdline;
Matthias Clasen 7097ae
+        gchar *argv[5];
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
         if (g_strcmp0 (user->user_name, name) != 0) {
Matthias Clasen 7097ae
                 old_name = g_strdup (user->user_name);
Matthias Clasen 7097ae
@@ -839,13 +841,17 @@ user_change_user_name_authorized_cb (Daemon                *daemon,
Matthias Clasen 7097ae
                                   "change name of user '%s' (%d) to '%s'",
Matthias Clasen 7097ae
                                   old_name, user->uid, name);
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
-                cmdline = g_strdup_printf ("/usr/sbin/usermod -l %s %s", name, user->user_name);
Matthias Clasen 7097ae
+                argv[0] = "/usr/sbin/usermod";
Matthias Clasen 7097ae
+                argv[1] = "-l";
Matthias Clasen 7097ae
+                argv[2] = name;
Matthias Clasen 7097ae
+                argv[3] = user->user_name;
Matthias Clasen 7097ae
+                argv[4] = NULL;
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
                 std_out = NULL;
Matthias Clasen 7097ae
                 std_err = NULL;
Matthias Clasen 7097ae
                 error = NULL;
Matthias Clasen 7097ae
-                if (!g_spawn_command_line_sync (cmdline, &std_out, &std_err, &status, &error)) {
Matthias Clasen 7097ae
-                        throw_error (context, ERROR_FAILED, "running '%s' failed: %s", cmdline, error->message);
Matthias Clasen 7097ae
+                if (!g_spawn_sync (NULL, argv, NULL, 0, NULL, NULL, &std_out, &std_err, &status, &error)) {
Matthias Clasen 7097ae
+                        throw_error (context, ERROR_FAILED, "running '%s' failed: %s", argv[0], error->message);
Matthias Clasen 7097ae
                         g_error_free (error);
Matthias Clasen 7097ae
                         g_free (std_out);
Matthias Clasen 7097ae
                         g_free (std_err);
Matthias Clasen 7097ae
@@ -856,13 +862,11 @@ user_change_user_name_authorized_cb (Daemon                *daemon,
Matthias Clasen 7097ae
                         throw_error (context, ERROR_FAILED, "usermod returned an error: %s", std_err);
Matthias Clasen 7097ae
                         g_free (std_out);
Matthias Clasen 7097ae
                         g_free (std_err);
Matthias Clasen 7097ae
-                        g_free (cmdline);
Matthias Clasen 7097ae
                         return;
Matthias Clasen 7097ae
                 }
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
                 g_free (std_out);
Matthias Clasen 7097ae
                 g_free (std_err);
Matthias Clasen 7097ae
-                g_free (cmdline);
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
                 g_free (user->user_name);
Matthias Clasen 7097ae
                 user->user_name = g_strdup (name);
Matthias Clasen 7097ae
@@ -1118,19 +1122,25 @@ user_change_home_dir_authorized_cb (Daemon                *daemon,
Matthias Clasen 7097ae
         GError *error;
Matthias Clasen 7097ae
         gint status;
Matthias Clasen 7097ae
         gchar *std_out, *std_err;
Matthias Clasen 7097ae
-        gchar *cmdline;
Matthias Clasen 7097ae
+        gchar *argv[6];
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
         if (g_strcmp0 (user->home_dir, home_dir) != 0) {
Matthias Clasen 7097ae
                 daemon_local_log (daemon, context,
Matthias Clasen 7097ae
                                   "change home directory of user '%s' (%d) to '%s'",
Matthias Clasen 7097ae
                                   user->user_name, user->uid, home_dir);
Matthias Clasen 7097ae
-                cmdline = g_strdup_printf ("/usr/sbin/usermod -m -d '%s' %s", home_dir, user->user_name);
Matthias Clasen 7097ae
+
Matthias Clasen 7097ae
+                argv[0] = "/usr/sbin/usermod";
Matthias Clasen 7097ae
+                argv[1] = "-m";
Matthias Clasen 7097ae
+                argv[2] = "-d";
Matthias Clasen 7097ae
+                argv[3] = home_dir;
Matthias Clasen 7097ae
+                argv[4] = user->user_name;
Matthias Clasen 7097ae
+                argv[5] = NULL;
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
                 std_out = NULL;
Matthias Clasen 7097ae
                 std_err = NULL;
Matthias Clasen 7097ae
                 error = NULL;
Matthias Clasen 7097ae
-                if (!g_spawn_command_line_sync (cmdline, &std_out, &std_err, &status, &error)) {
Matthias Clasen 7097ae
-                        throw_error (context, ERROR_FAILED, "running '%s' failed: %s", cmdline, error->message);
Matthias Clasen 7097ae
+                if (!g_spawn_sync (NULL, argv, NULL, 0, NULL, NULL, &std_out, &std_err, &status, &error)) {
Matthias Clasen 7097ae
+                        throw_error (context, ERROR_FAILED, "running '%s' failed: %s", argv[0], error->message);
Matthias Clasen 7097ae
                         g_error_free (error);
Matthias Clasen 7097ae
                         g_free (std_out);
Matthias Clasen 7097ae
                         g_free (std_err);
Matthias Clasen 7097ae
@@ -1141,13 +1151,11 @@ user_change_home_dir_authorized_cb (Daemon                *daemon,
Matthias Clasen 7097ae
                         throw_error (context, ERROR_FAILED, "usermod returned an error: %s", std_err);
Matthias Clasen 7097ae
                         g_free (std_out);
Matthias Clasen 7097ae
                         g_free (std_err);
Matthias Clasen 7097ae
-                        g_free (cmdline);
Matthias Clasen 7097ae
                         return;
Matthias Clasen 7097ae
                 }
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
                 g_free (std_out);
Matthias Clasen 7097ae
                 g_free (std_err);
Matthias Clasen 7097ae
-                g_free (cmdline);
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
                 g_free (user->home_dir);
Matthias Clasen 7097ae
                 user->home_dir = g_strdup (home_dir);
Matthias Clasen 7097ae
@@ -1159,6 +1167,7 @@ user_change_home_dir_authorized_cb (Daemon                *daemon,
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
         dbus_g_method_return (context);
Matthias Clasen 7097ae
 }
Matthias Clasen 7097ae
+
Matthias Clasen 7097ae
 gboolean
Matthias Clasen 7097ae
 user_set_home_directory (User                  *user,
Matthias Clasen 7097ae
                          const gchar           *home_dir,
Matthias Clasen 7097ae
@@ -1206,20 +1215,24 @@ user_change_shell_authorized_cb (Daemon                *daemon,
Matthias Clasen 7097ae
         GError *error;
Matthias Clasen 7097ae
         gint status;
Matthias Clasen 7097ae
         gchar *std_out, *std_err;
Matthias Clasen 7097ae
-        gchar *cmdline;
Matthias Clasen 7097ae
+        gchar *argv[5];
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
         if (g_strcmp0 (user->shell, shell) != 0) {
Matthias Clasen 7097ae
                 daemon_local_log (daemon, context,
Matthias Clasen 7097ae
                                   "change shell of user '%s' (%d) to '%s'",
Matthias Clasen 7097ae
                                   user->user_name, user->uid, shell);
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
-                cmdline = g_strdup_printf ("/usr/sbin/usermod -s '%s' %s", shell, user->user_name);
Matthias Clasen 7097ae
+                argv[0] = "/usr/sbin/usermod";
Matthias Clasen 7097ae
+                argv[1] = "-s";
Matthias Clasen 7097ae
+                argv[2] = shell;
Matthias Clasen 7097ae
+                argv[3] = user->user_name;
Matthias Clasen 7097ae
+                argv[4] = NULL;
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
                 std_out = NULL;
Matthias Clasen 7097ae
                 std_err = NULL;
Matthias Clasen 7097ae
                 error = NULL;
Matthias Clasen 7097ae
-                if (!g_spawn_command_line_sync (cmdline, &std_out, &std_err, &status, &error)) {
Matthias Clasen 7097ae
-                        throw_error (context, ERROR_FAILED, "running '%s' failed: %s", cmdline, error->message);
Matthias Clasen 7097ae
+                if (!g_spawn_sync (NULL, argv, NULL, 0, NULL, NULL, &std_out, &std_err, &status, &error)) {
Matthias Clasen 7097ae
+                        throw_error (context, ERROR_FAILED, "running '%s' failed: %s", argv[0], error->message);
Matthias Clasen 7097ae
                         g_error_free (error);
Matthias Clasen 7097ae
                         g_free (std_out);
Matthias Clasen 7097ae
                         g_free (std_err);
Matthias Clasen 7097ae
@@ -1230,13 +1243,11 @@ user_change_shell_authorized_cb (Daemon                *daemon,
Matthias Clasen 7097ae
                         throw_error (context, ERROR_FAILED, "usermod returned an error: %s", std_err);
Matthias Clasen 7097ae
                         g_free (std_out);
Matthias Clasen 7097ae
                         g_free (std_err);
Matthias Clasen 7097ae
-                        g_free (cmdline);
Matthias Clasen 7097ae
                         return;
Matthias Clasen 7097ae
                 }
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
                 g_free (std_out);
Matthias Clasen 7097ae
                 g_free (std_err);
Matthias Clasen 7097ae
-                g_free (cmdline);
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
                 g_free (user->shell);
Matthias Clasen 7097ae
                 user->shell = g_strdup (shell);
Matthias Clasen 7097ae
@@ -1475,19 +1486,22 @@ user_change_locked_authorized_cb (Daemon                *daemon,
Matthias Clasen 7097ae
         GError *error;
Matthias Clasen 7097ae
         gint status;
Matthias Clasen 7097ae
         gchar *std_out, *std_err;
Matthias Clasen 7097ae
-        gchar *cmdline;
Matthias Clasen 7097ae
+        gchar *argv[4];
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
         if (user->locked != locked) {
Matthias Clasen 7097ae
                 daemon_local_log (daemon, context,
Matthias Clasen 7097ae
                                   "%s account of user '%s' (%d)",
Matthias Clasen 7097ae
                                   locked ? "locking" : "unlocking", user->user_name, user->uid);
Matthias Clasen 7097ae
-                cmdline = g_strdup_printf ("/usr/sbin/usermod -%c %s", locked ? 'L' : 'U',  user->user_name);
Matthias Clasen 7097ae
+                argv[0] = "/usr/sbin/usermod";
Matthias Clasen 7097ae
+                argv[1] = locked ? "-L" : "-U";
Matthias Clasen 7097ae
+                argv[2] = user->user_name;
Matthias Clasen 7097ae
+                argv[3] = NULL;
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
                 std_out = NULL;
Matthias Clasen 7097ae
                 std_err = NULL;
Matthias Clasen 7097ae
                 error = NULL;
Matthias Clasen 7097ae
-                if (!g_spawn_command_line_sync (cmdline, &std_out, &std_err, &status, &error)) {
Matthias Clasen 7097ae
-                        throw_error (context, ERROR_FAILED, "running '%s' failed: %s", cmdline, error->message);
Matthias Clasen 7097ae
+                if (!g_spawn_sync (NULL, argv, NULL, 0, NULL, NULL, &std_out, &std_err, &status, &error)) {
Matthias Clasen 7097ae
+                        throw_error (context, ERROR_FAILED, "running '%s' failed: %s", argv[0], error->message);
Matthias Clasen 7097ae
                         g_error_free (error);
Matthias Clasen 7097ae
                         g_free (std_out);
Matthias Clasen 7097ae
                         g_free (std_err);
Matthias Clasen 7097ae
@@ -1498,13 +1512,11 @@ user_change_locked_authorized_cb (Daemon                *daemon,
Matthias Clasen 7097ae
                         throw_error (context, ERROR_FAILED, "usermod returned an error: %s", std_err);
Matthias Clasen 7097ae
                         g_free (std_out);
Matthias Clasen 7097ae
                         g_free (std_err);
Matthias Clasen 7097ae
-                        g_free (cmdline);
Matthias Clasen 7097ae
                         return;
Matthias Clasen 7097ae
                 }
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
                 g_free (std_out);
Matthias Clasen 7097ae
                 g_free (std_err);
Matthias Clasen 7097ae
-                g_free (cmdline);
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
                 user->locked = locked;
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
@@ -1544,7 +1556,6 @@ user_change_account_type_authorized_cb (Daemon                *daemon,
Matthias Clasen 7097ae
         GError *error;
Matthias Clasen 7097ae
         gint status;
Matthias Clasen 7097ae
         gchar *std_out, *std_err;
Matthias Clasen 7097ae
-        gchar *cmdline;
Matthias Clasen 7097ae
         gid_t groups[20];
Matthias Clasen 7097ae
         gint n_groups;
Matthias Clasen 7097ae
         GString *str;
Matthias Clasen 7097ae
@@ -1552,6 +1563,7 @@ user_change_account_type_authorized_cb (Daemon                *daemon,
Matthias Clasen 7097ae
         gid_t desktop_admin_r;
Matthias Clasen 7097ae
         struct group *grp;
Matthias Clasen 7097ae
         gint i;
Matthias Clasen 7097ae
+        gchar *argv[5];
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
         if (user->account_type != account_type) {
Matthias Clasen 7097ae
                 daemon_local_log (daemon, context,
Matthias Clasen 7097ae
@@ -1596,13 +1608,19 @@ user_change_account_type_authorized_cb (Daemon                *daemon,
Matthias Clasen 7097ae
                         g_string_truncate (str, str->len - 1);
Matthias Clasen 7097ae
                 }
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
-                cmdline = g_strdup_printf ("/usr/sbin/usermod -G %s %s", str->str, user->user_name);
Matthias Clasen 7097ae
+                argv[0] = "/usr/sbin/usermod";
Matthias Clasen 7097ae
+                argv[1] = "-G";
Matthias Clasen 7097ae
+                argv[2] = str->str;
Matthias Clasen 7097ae
+                argv[3] = user->user_name;
Matthias Clasen 7097ae
+                argv[4] = NULL;
Matthias Clasen 7097ae
+
Matthias Clasen 7097ae
+                g_string_free (str, FALSE);
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
                 std_out = NULL;
Matthias Clasen 7097ae
                 std_err = NULL;
Matthias Clasen 7097ae
                 error = NULL;
Matthias Clasen 7097ae
-                if (!g_spawn_command_line_sync (cmdline, &std_out, &std_err, &status, &error)) {
Matthias Clasen 7097ae
-                        throw_error (context, ERROR_FAILED, "running '%s' failed: %s", cmdline, error->message);
Matthias Clasen 7097ae
+                if (!g_spawn_sync (NULL, argv, NULL, 0, NULL, NULL, &std_out, &std_err, &status, &error)) {
Matthias Clasen 7097ae
+                        throw_error (context, ERROR_FAILED, "running '%s' failed: %s", argv[0], error->message);
Matthias Clasen 7097ae
                         g_error_free (error);
Matthias Clasen 7097ae
                         g_free (std_out);
Matthias Clasen 7097ae
                         g_free (std_err);
Matthias Clasen 7097ae
@@ -1613,13 +1631,11 @@ user_change_account_type_authorized_cb (Daemon                *daemon,
Matthias Clasen 7097ae
                         throw_error (context, ERROR_FAILED, "usermod returned an error: %s", std_err);
Matthias Clasen 7097ae
                         g_free (std_out);
Matthias Clasen 7097ae
                         g_free (std_err);
Matthias Clasen 7097ae
-                        g_free (cmdline);
Matthias Clasen 7097ae
                         return;
Matthias Clasen 7097ae
                 }
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
                 g_free (std_out);
Matthias Clasen 7097ae
                 g_free (std_err);
Matthias Clasen 7097ae
-                g_free (cmdline);
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
                 user->account_type = account_type;
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
@@ -1664,7 +1680,7 @@ user_change_password_mode_authorized_cb (Daemon                *daemon,
Matthias Clasen 7097ae
         GError *error;
Matthias Clasen 7097ae
         gint status;
Matthias Clasen 7097ae
         gchar *std_out, *std_err;
Matthias Clasen 7097ae
-        gchar *cmdline;
Matthias Clasen 7097ae
+        gchar *argv[4];
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
         if (user->password_mode != mode) {
Matthias Clasen 7097ae
                 daemon_local_log (daemon, context,
Matthias Clasen 7097ae
@@ -1674,13 +1690,16 @@ user_change_password_mode_authorized_cb (Daemon                *daemon,
Matthias Clasen 7097ae
                 if (mode == PASSWORD_MODE_SET_AT_LOGIN ||
Matthias Clasen 7097ae
                     mode == PASSWORD_MODE_NONE) {
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
-                        cmdline = g_strdup_printf ("/usr/bin/passwd -d %s", user->user_name);
Matthias Clasen 7097ae
+                        argv[0] = "/usr/bin/passwd";
Matthias Clasen 7097ae
+                        argv[1] = "-d";
Matthias Clasen 7097ae
+                        argv[2] = user->user_name;
Matthias Clasen 7097ae
+                        argv[3] = NULL;
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
                         std_out = NULL;
Matthias Clasen 7097ae
                         std_err = NULL;
Matthias Clasen 7097ae
                         error = NULL;
Matthias Clasen 7097ae
-                        if (!g_spawn_command_line_sync (cmdline, &std_out, &std_err, &status, &error)) {
Matthias Clasen 7097ae
-                                throw_error (context, ERROR_FAILED, "running '%s' failed: %s", cmdline, error->message);
Matthias Clasen 7097ae
+                        if (!g_spawn_sync (NULL, argv, NULL, 0, NULL, NULL, &std_out, &std_err, &status, &error)) {
Matthias Clasen 7097ae
+                                throw_error (context, ERROR_FAILED, "running '%s' failed: %s", argv[0], error->message);
Matthias Clasen 7097ae
                                 g_error_free (error);
Matthias Clasen 7097ae
                                 g_free (std_out);
Matthias Clasen 7097ae
                                 g_free (std_err);
Matthias Clasen 7097ae
@@ -1691,13 +1710,11 @@ user_change_password_mode_authorized_cb (Daemon                *daemon,
Matthias Clasen 7097ae
                                 throw_error (context, ERROR_FAILED, "usermod returned an error: %s", std_err);
Matthias Clasen 7097ae
                                 g_free (std_out);
Matthias Clasen 7097ae
                                 g_free (std_err);
Matthias Clasen 7097ae
-                                g_free (cmdline);
Matthias Clasen 7097ae
                                 return;
Matthias Clasen 7097ae
                         }
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
                         g_free (std_out);
Matthias Clasen 7097ae
                         g_free (std_err);
Matthias Clasen 7097ae
-                        g_free (cmdline);
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
                         g_free (user->password_hint);
Matthias Clasen 7097ae
                         user->password_hint = NULL;
Matthias Clasen 7097ae
@@ -1774,19 +1791,23 @@ user_change_password_authorized_cb (Daemon                *daemon,
Matthias Clasen 7097ae
         GError *error;
Matthias Clasen 7097ae
         gint status;
Matthias Clasen 7097ae
         gchar *std_out, *std_err;
Matthias Clasen 7097ae
-        gchar *cmdline;
Matthias Clasen 7097ae
+        gchar *argv[5];
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
         daemon_local_log (daemon, context,
Matthias Clasen 7097ae
                           "set password and hint of user '%s' (%d)",
Matthias Clasen 7097ae
                           user->user_name, user->uid);
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
-        cmdline = g_strdup_printf ("/usr/sbin/usermod -p '%s' %s", strings[0], user->user_name);
Matthias Clasen 7097ae
+        argv[0] = "/usr/sbin/usermod";
Matthias Clasen 7097ae
+        argv[1] = "-p";
Matthias Clasen 7097ae
+        argv[2] = strings[0];
Matthias Clasen 7097ae
+        argv[3] = user->user_name;
Matthias Clasen 7097ae
+        argv[4] = NULL;
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
         std_out = NULL;
Matthias Clasen 7097ae
         std_err = NULL;
Matthias Clasen 7097ae
         error = NULL;
Matthias Clasen 7097ae
-        if (!g_spawn_command_line_sync (cmdline, &std_out, &std_err, &status, &error)) {
Matthias Clasen 7097ae
-                throw_error (context, ERROR_FAILED, "running '%s' failed: %s", cmdline, error->message);
Matthias Clasen 7097ae
+        if (!g_spawn_sync (NULL, argv, NULL, 0, NULL, NULL, &std_out, &std_err, &status, &error)) {
Matthias Clasen 7097ae
+                throw_error (context, ERROR_FAILED, "running '%s' failed: %s", argv[0], error->message);
Matthias Clasen 7097ae
                 g_error_free (error);
Matthias Clasen 7097ae
                 g_free (std_out);
Matthias Clasen 7097ae
                 g_free (std_err);
Matthias Clasen 7097ae
@@ -1797,13 +1818,11 @@ user_change_password_authorized_cb (Daemon                *daemon,
Matthias Clasen 7097ae
                 throw_error (context, ERROR_FAILED, "usermod returned an error: %s", std_err);
Matthias Clasen 7097ae
                 g_free (std_out);
Matthias Clasen 7097ae
                 g_free (std_err);
Matthias Clasen 7097ae
-                g_free (cmdline);
Matthias Clasen 7097ae
                 return;
Matthias Clasen 7097ae
         }
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
         g_free (std_out);
Matthias Clasen 7097ae
         g_free (std_err);
Matthias Clasen 7097ae
-        g_free (cmdline);
Matthias Clasen 7097ae
 
Matthias Clasen 7097ae
         if (user->password_mode != PASSWORD_MODE_REGULAR) {
Matthias Clasen 7097ae
                 user->password_mode = PASSWORD_MODE_REGULAR;
Matthias Clasen 7097ae
-- 
Matthias Clasen 7097ae
1.7.0.1
Matthias Clasen 7097ae