static gboolean
check_pipe_exit_status (CockpitPipe *pipe,
                        const gchar *problem,
                        const gchar *prefix)
{
  GError *error = NULL;
  gint status;

  if (problem == NULL ||
      g_str_equal (problem, "internal-error"))
    {
      status = cockpit_pipe_exit_status (pipe);
      if (!g_spawn_check_exit_status (status, &error))
        {
          g_message ("%s: %s", prefix, error->message);
          g_error_free (error);
          return FALSE;
        }
    }
  else if (problem)
    {
      g_message ("%s: %s", prefix, problem);
      return FALSE;
    }

  return TRUE;
}
Beispiel #2
0
///pdftk_pid_watch wird aufgerufen sobald der pdftk-Prozess beendet ist
void pdftk_child_watch_func (GPid pdftk_pid,gint status,gpointer user_data){
	GError *error = NULL;

	//Status abfragen
	g_spawn_check_exit_status (status,&error);
	if (error!=NULL){
		g_warning("%s",error->message);
		g_error_free(error);
		error = NULL;
	}
	//Pid schließen (ist unter UNIX nicht nötig)
	g_spawn_close_pid(pdftk_pid);
	//fertiges PDF direkt anzeigen
	GString *folderpath=NULL;
	folderpath = g_string_new ("file://");
	folderpath = g_string_append (folderpath,keyfile_get_outputdir());
	folderpath = g_string_append (folderpath,"/");
	folderpath = g_string_append (folderpath,keyfile_get_pdf_name());
	g_print("pdf_anzeigen:\t%s\n",folderpath->str);
	gtk_show_uri (NULL,folderpath->str,GDK_CURRENT_TIME,&error);
	if (error!=NULL){
		g_warning("%s",error->message);
		g_error_free(error);
		error = NULL;
	}
	g_string_free(folderpath,TRUE);
	interface_ausgrauen(TRUE);
	temp_dir_delete();
}
Beispiel #3
0
void mkimg(const char *file, const char *fmt, unsigned size_mb)
{
    gchar *cli;
    bool ret;
    int rc;
    GError *err = NULL;
    char *qemu_img_path;
    gchar *out, *out2;
    char *qemu_img_abs_path;

    qemu_img_path = getenv("QTEST_QEMU_IMG");
    g_assert(qemu_img_path);
    qemu_img_abs_path = realpath(qemu_img_path, NULL);
    g_assert(qemu_img_abs_path);

    cli = g_strdup_printf("%s create -f %s %s %uM", qemu_img_abs_path,
                          fmt, file, size_mb);
    ret = g_spawn_command_line_sync(cli, &out, &out2, &rc, &err);
    if (err || !g_spawn_check_exit_status(rc, &err)) {
        fprintf(stderr, "%s\n", err->message);
        g_error_free(err);
    }
    g_assert(ret && !err);

    g_free(out);
    g_free(out2);
    g_free(cli);
    free(qemu_img_abs_path);
}
Beispiel #4
0
/* This function hovers in a quantum superposition of horrifying and
 * beautiful.  Future generations may interpret it as modern art.
 */
gboolean
ot_test_run_libtest (const char *cmd, GError **error)
{
  gboolean ret = FALSE;
  const char *srcdir = g_getenv ("G_TEST_SRCDIR");
  int estatus;
  g_autoptr(GPtrArray) argv = g_ptr_array_new ();
  g_autoptr(GString) cmdstr = g_string_new ("");

  g_ptr_array_add (argv, "bash");
  g_ptr_array_add (argv, "-c");

  g_string_append (cmdstr, "set -xeuo pipefail; . ");
  g_string_append (cmdstr, srcdir);
  g_string_append (cmdstr, "/tests/libtest.sh; ");
  g_string_append (cmdstr, cmd);

  g_ptr_array_add (argv, cmdstr->str);
  g_ptr_array_add (argv, NULL);

  if (!g_spawn_sync (NULL, (char**)argv->pdata, NULL, G_SPAWN_SEARCH_PATH,
                     NULL, NULL, NULL, NULL, &estatus, error))
    goto out;

  if (!g_spawn_check_exit_status (estatus, error))
    goto out;

  ret = TRUE;
 out:
  return ret;
}
static void
fusermount_cleanup (const char *mountpoint)
{
  g_autoptr(GError) tmp_error = NULL;
  const char *fusermount_argv[] = { "fusermount", "-u", mountpoint, NULL};
  int estatus;

  if (!g_spawn_sync (NULL, (char**)fusermount_argv, NULL, G_SPAWN_SEARCH_PATH,
                     NULL, NULL, NULL, NULL, &estatus, &tmp_error))
    {
      g_prefix_error (&tmp_error, "Executing fusermount: ");
      goto out;
    }
  if (!g_spawn_check_exit_status (estatus, &tmp_error))
    {
      g_prefix_error (&tmp_error, "Executing fusermount: ");
      goto out;
    }

 out:
  /* We don't want a failure to unmount to be fatal, so all we do here
   * is log.  Though in practice what we *really* want is for the
   * fusermount to be in the bwrap namespace, and hence tied by the
   * kernel to the lifecycle of the container.  This would require
   * special casing for somehow doing FUSE mounts in bwrap.  Which
   * would be hard because NO_NEW_PRIVS turns off the setuid bits for
   * fuse.
   */
  if (tmp_error)
    sd_journal_print (LOG_WARNING, "%s", tmp_error->message);
}
gboolean
_rpmostree_sync_wait_on_pid (pid_t          pid,
                             GError       **error)
{
  gboolean ret = FALSE;
  pid_t r;
  int estatus;

  do
    r = waitpid (pid, &estatus, 0);
  while (G_UNLIKELY (r == -1 && errno == EINTR));

  if (r == -1)
    {
      _rpmostree_set_prefix_error_from_errno (error, errno, "waitpid: ");
      goto out;
    }

  if (!g_spawn_check_exit_status (estatus, error))
    goto out;

  ret = TRUE;
 out:
  return ret;
}
static gboolean
compat_check_exit_status (int      estatus,
                          GError **error)
{
#if GLIB_CHECK_VERSION(2, 33, 12)
        return g_spawn_check_exit_status (estatus, error);
#else
        if (!WIFEXITED (estatus)) {
                g_set_error (error,
                             G_SPAWN_ERROR,
                             G_SPAWN_ERROR_FAILED,
                             "Exited abnormally");
                return FALSE;
        }
        if (WEXITSTATUS (estatus) != 0) {
                g_set_error (error,
                             G_SPAWN_ERROR,
                             G_SPAWN_ERROR_FAILED,
                             "Exited with code %d",
                             WEXITSTATUS(estatus));
                return FALSE;
        }
        return TRUE;
#endif
}
Beispiel #8
0
static gboolean
setup_rofiles_usr (RpmOstreeBwrap *bwrap,
                   GError **error)
{
  gboolean ret = FALSE;
  int estatus;
  const char *rofiles_argv[] = { "rofiles-fuse", "./usr", NULL, NULL};
  gboolean mntpoint_created = FALSE;

  bwrap->rofiles_mnt = g_strdup ("/tmp/rofiles-fuse.XXXXXX");
  rofiles_argv[2] = bwrap->rofiles_mnt;

  if (!glnx_mkdtempat (AT_FDCWD, bwrap->rofiles_mnt, 0700, error))
    goto out;
  mntpoint_created = TRUE;

  if (!g_spawn_sync (NULL, (char**)rofiles_argv, NULL, G_SPAWN_SEARCH_PATH,
                     child_setup_fchdir, GINT_TO_POINTER (bwrap->rootfs_fd),
                     NULL, NULL, &estatus, error))
    goto out;
  if (!g_spawn_check_exit_status (estatus, error))
    goto out;

  rpmostree_bwrap_append_bwrap_argv (bwrap, "--bind", bwrap->rofiles_mnt, "/usr", NULL);

  ret = TRUE;
 out:
  if (!ret && mntpoint_created)
    (void) unlinkat (AT_FDCWD, bwrap->rofiles_mnt, AT_REMOVEDIR);
  return ret;
}
static void
on_pipe_close (CockpitPipe *pipe,
               const gchar *problem,
               gpointer user_data)
{
  CockpitPipeTransport *self = COCKPIT_PIPE_TRANSPORT (user_data);
  gboolean is_cockpit;
  GError *error = NULL;
  gint status;

  self->closed = TRUE;

  /* This function is called by the base class when it is closed */
  if (cockpit_pipe_get_pid (pipe, NULL))
    {
      is_cockpit = g_str_equal (self->name, "cockpit-bridge") ||
                   g_str_equal (self->name, "cockpit-session");

      if (problem == NULL ||
          g_str_equal (problem, "internal-error"))
        {
          status = cockpit_pipe_exit_status (pipe);
          if (WIFSIGNALED (status) && WTERMSIG (status) == SIGTERM)
            problem = "terminated";
          else if (is_cockpit && WIFEXITED (status) && WEXITSTATUS (status) == 127)
            problem = "no-cockpit";      // cockpit-bridge not installed
          else if (WIFEXITED (status) && WEXITSTATUS (status) == 255)
            problem = "terminated";      // failed or got a signal, etc.
          else if (!g_spawn_check_exit_status (status, &error))
            {
              problem = "internal-error";
              if (is_cockpit)
                g_warning ("%s: bridge program failed: %s", self->name, error->message);
              else
                g_debug ("%s: process failed: %s", self->name, error->message);
              g_error_free (error);
            }
        }
      else if (g_str_equal (problem, "not-found"))
        {
          if (is_cockpit)
            {
              g_message ("%s: failed to execute bridge: not found", self->name);
              problem = "no-cockpit";
            }
          else
            {
              g_debug ("%s: failed to run: not found", self->name);
            }
        }
    }

  g_debug ("%s: closed%s%s", self->name,
           problem ? ": " : "", problem ? problem : "");

  cockpit_transport_emit_closed (COCKPIT_TRANSPORT (self), problem);
}
Beispiel #10
0
static gboolean
sscg_make_dummy_cert (const gchar *key_file,
                      const gchar *cert_file,
                      const gchar *ca_file,
                      GError **error)
{
  gboolean ret = FALSE;
  gint exit_status;
  gchar *stderr_str = NULL;
  gchar *command_line = NULL;
  gchar *cn = get_common_name ();
  gchar *machine_id = get_machine_id ();
  gchar *org;

  if (machine_id)
    org = machine_id;
  else
    org = "";

  const gchar *argv[] = {
    "sscg", "--quiet",
    "--lifetime", "3650",
    "--key-strength", "2048",
    "--cert-key-file", key_file,
    "--cert-file", cert_file,
    "--ca-file", ca_file,
    "--hostname", cn,
    "--organization", org,
    "--subject-alt-name", "localhost",
    "--subject-alt-name", "IP:127.0.0.1/255.255.255.255",
    NULL
  };

  command_line = g_strjoinv (" ", (gchar **)argv);
  g_info ("Generating temporary certificate using: %s", command_line);

  if (!g_spawn_sync (NULL, (gchar **)argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL,
                     NULL, &stderr_str, &exit_status, error) ||
      !g_spawn_check_exit_status (exit_status, error))
    {
      /* Failure of SSCG is non-fatal */
      g_info ("Error generating temporary dummy cert using sscg, "
              "falling back to openssl");
      g_clear_error (error);
      goto out;
    }

  ret = TRUE;

out:
  g_free (stderr_str);
  g_free (command_line);
  g_free (machine_id);
  g_free (cn);
  return ret;
}
Beispiel #11
0
static void
on_dialog_closed (GPid     pid,
                  gint     status,
                  gpointer user_data)
{
  MetaPlugin *plugin = user_data;
  gboolean ok;

  ok = g_spawn_check_exit_status (status, NULL);
  meta_plugin_complete_display_change (plugin, ok);
}
Beispiel #12
0
///unoconv_pid_watch wird aufgerufen sobald der unoconv-Prozess beendet ist
void unoconv_child_watch_func (GPid unoconv_pid,gint status,gpointer user_data){
	GError *error = NULL;

	//Status abfragen
	g_spawn_check_exit_status (status,&error);
	if (error!=NULL){
		g_warning("%s",error->message);
		g_error_free(error);
		error = NULL;
	}
	//Pid schließen (ist unter UNIX nicht nötig)
	g_spawn_close_pid(unoconv_pid);

	//pdftk aufruf bauen
	GPtrArray *pdftk_argv= g_ptr_array_new ();
	//Funktion zum aufräumen setzten
	g_ptr_array_set_free_func(pdftk_argv,ptr_array_clean);

	GPid pdftk_pid=0;
	fill_g_ptr_array (pdftk_argv,"pdftk");

	//den ListStore durchlaufen lassen, und pfad bauen
	gtk_tree_model_foreach(gtk_tree_view_get_model(gui_get_gtk_tree_viewer()),treemodel_ausgabe_pdftk,(gpointer)pdftk_argv);
	fill_g_ptr_array (pdftk_argv,"output");
	//speichert den Pfad
	g_ptr_array_add(pdftk_argv,(gpointer)keyfile_get_pdf_full_path());
	g_ptr_array_add(pdftk_argv,(gpointer)NULL);

	//PDF zusammenfügen
	g_spawn_async_with_pipes (NULL,
														(gchar**)pdftk_argv->pdata,
														NULL,
														G_SPAWN_SEARCH_PATH|G_SPAWN_DO_NOT_REAP_CHILD,
														NULL,
														NULL,
														&pdftk_pid,
														NULL,
														NULL,
														NULL,
														&error);
	if (error!=NULL){
		g_warning("%s",error->message);
		g_error_free(error);
		error = NULL;
	}

	//g_child_watch einrichten, um über Programmende(pdftk) informiert zu werden
	g_child_watch_add(pdftk_pid,pdftk_child_watch_func,NULL);
	//aufräumen
	g_ptr_array_free(pdftk_argv,TRUE);
	//g_print("das PDF \"%s\" wurde unter \"%s\" erstellt\n",keyfile_get_pdf_name(),keyfile_get_outputdir());
	//Buttons wieder aktivieren
		interface_ausgrauen(TRUE);
}
Beispiel #13
0
gboolean
ide_subprocess_check_exit_status (IdeSubprocess  *self,
                                  GError        **error)
{
  gint exit_status;

  g_return_val_if_fail (IDE_IS_SUBPROCESS (self), FALSE);

  exit_status = ide_subprocess_get_exit_status (self);

  return g_spawn_check_exit_status (exit_status, error);
}
Beispiel #14
0
/**
 * @root: (allow-none): Change to this root; if %NULL, don't chroot
 *
 * Triggers are a set of programs to run on a root to regenerate cache
 * files.  This API call will simply run them against the given root.
 */
gboolean
ostree_run_triggers_in_root (GFile                  *root,
                             GCancellable           *cancellable,
                             GError                **error)
{
  gboolean ret = FALSE;
  int estatus;
  ot_lfree char *rel_triggerdir = NULL;
  ot_lobj GFile *triggerdir = NULL;
  ot_lptrarray GPtrArray *argv = NULL;

  rel_triggerdir = g_build_filename ("usr", "libexec", "ostree", "triggers.d", NULL);

  if (root)
    triggerdir = g_file_resolve_relative_path (root, rel_triggerdir);
  else
    triggerdir = g_file_new_for_path (rel_triggerdir);

  if (g_file_query_exists (triggerdir, cancellable))
    {
      argv = g_ptr_array_new ();
      if (root)
        {
          g_ptr_array_add (argv, "linux-user-chroot");
          g_ptr_array_add (argv, "--unshare-pid");
          g_ptr_array_add (argv, "--unshare-ipc");
          /* FIXME - unshare net too */
          g_ptr_array_add (argv, "--mount-proc");
          g_ptr_array_add (argv, "/proc");
          g_ptr_array_add (argv, "--mount-bind");
          g_ptr_array_add (argv, "/dev");
          g_ptr_array_add (argv, "/dev");
          g_ptr_array_add (argv, (char*)ot_gfile_get_path_cached (root));
        }
      g_ptr_array_add (argv, "ostree-run-triggers");
      g_ptr_array_add (argv, NULL);

      if (!g_spawn_sync (NULL, (char**)argv->pdata,
                         (char**) ostree_get_sysroot_environ (),
                         G_SPAWN_SEARCH_PATH,
                         NULL, NULL, NULL, NULL, &estatus, error))
        goto out;

      if (!g_spawn_check_exit_status (estatus, error))
        goto out;
    }

  ret = TRUE;
 out:
  return ret;
}
Beispiel #15
0
// Shell-out to "rm -rf -- $dir" as long as $dir is in /tmp.
static void rm_rf_tmp(const char *dir)
{
	// Sanity check, don't remove anything that's not in the temporary
	// directory. This is here to prevent unintended data loss.
	if (!g_str_has_prefix(dir, "/tmp/"))
		die("refusing to remove: %s", dir);
	const gchar *working_directory = NULL;
	gchar **argv = NULL;
	gchar **envp = NULL;
	GSpawnFlags flags = G_SPAWN_SEARCH_PATH;
	GSpawnChildSetupFunc child_setup = NULL;
	gpointer user_data = NULL;
	gchar **standard_output = NULL;
	gchar **standard_error = NULL;
	gint exit_status = 0;
	GError *error = NULL;

	argv = calloc(5, sizeof *argv);
	if (argv == NULL)
		die("cannot allocate command argument array");
	argv[0] = g_strdup("rm");
	if (argv[0] == NULL)
		die("cannot allocate memory");
	argv[1] = g_strdup("-rf");
	if (argv[1] == NULL)
		die("cannot allocate memory");
	argv[2] = g_strdup("--");
	if (argv[2] == NULL)
		die("cannot allocate memory");
	argv[3] = g_strdup(dir);
	if (argv[3] == NULL)
		die("cannot allocate memory");
	argv[4] = NULL;
	g_assert_true(g_spawn_sync
		      (working_directory, argv, envp, flags, child_setup,
		       user_data, standard_output, standard_error, &exit_status,
		       &error));
	g_assert_true(g_spawn_check_exit_status(exit_status, NULL));
	if (error != NULL) {
		g_test_message("cannot remove temporary directory: %s\n",
			       error->message);
		g_error_free(error);
	}
	g_free(argv[0]);
	g_free(argv[1]);
	g_free(argv[2]);
	g_free(argv[3]);
	g_free(argv);
}
Beispiel #16
0
int pg_util_cmdloop(const char *cmd, int timeout_s)
{
	struct timeval start, end;
	gint status;

	gettimeofday(&start, 0);
	gettimeofday(&end, 0);
	while (end.tv_sec - start.tv_sec < timeout_s) {
		g_spawn_command_line_sync(cmd, NULL, NULL, &status, NULL);
		if (g_spawn_check_exit_status(status, NULL))
			return 0;
		gettimeofday(&end, 0);
	}
	return 1;
}
Beispiel #17
0
static gboolean
run_cmd_for_invocation (GDBusMethodInvocation *invocation,
                        char **output,
                        const gchar *cmd,
                        ...)
{
  const int max_args = 20;
  const gchar *argv[max_args];

  va_list ap;
  va_start (ap, cmd);
  const gchar **p = argv;
  while (cmd && p < argv + max_args - 1)
    {
      *p++ = cmd;
      cmd = va_arg (ap, const gchar *);
    }
  *p = NULL;
  va_end (ap);

  GError *error = NULL;
  gint code;

  g_spawn_sync (NULL, (gchar **)argv, NULL,
                G_SPAWN_SEARCH_PATH | (output == NULL? G_SPAWN_STDOUT_TO_DEV_NULL : 0),
                redirect_stderr_to_stdout, NULL, output, NULL, &code, &error);
  if (error)
    {
      g_dbus_method_invocation_return_error (invocation,
                                             COCKPIT_ERROR,
                                             COCKPIT_ERROR_FAILED,
                                             "Can't run '%s': %s", argv[0], error->message);
      g_error_free (error);
      return FALSE;
    }
  else if (output == NULL && !g_spawn_check_exit_status (code, &error))
    {
      g_dbus_method_invocation_return_error (invocation,
                                             COCKPIT_ERROR,
                                             COCKPIT_ERROR_FAILED,
                                             "'%s' failed: %s", argv[0], error->message);
      g_error_free (error);
      return FALSE;
    }
  else
    return TRUE;
}
Beispiel #18
0
static void
on_phantomjs_exited (GPid pid,
                     gint status,
                     gpointer user_data)
{
  GError *error = NULL;

  if (!g_spawn_check_exit_status (status, &error))
    {
      g_critical ("phantomjs: %s", error->message);
      g_error_free (error);
      exit_code = 1;
    }

  g_main_loop_quit (loop);
  g_spawn_close_pid (pid);
}
static gboolean
openssl_make_dummy_cert (const gchar *key_file,
                         const gchar *out_file,
                         GError **error)
{
  gboolean ret = FALSE;
  gint exit_status;
  gchar *stderr_str = NULL;
  gchar *command_line = NULL;
  gchar *subject = generate_subject ();

  const gchar *argv[] = {
    "openssl",
    "req", "-x509",
    "-days", "36500",
    "-newkey", "rsa:2048",
    "-keyout", key_file,
    "-keyform", "PEM",
    "-nodes",
    "-out", out_file,
    "-outform", "PEM",
    "-subj", subject,
    NULL
  };

  command_line = g_strjoinv (" ", (gchar **)argv);
  g_info ("Generating temporary certificate using: %s", command_line);

  if (!g_spawn_sync (NULL, (gchar **)argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL,
                     NULL, &stderr_str, &exit_status, error) ||
      !g_spawn_check_exit_status (exit_status, error))
    {
      g_warning ("%s", stderr_str);
      g_prefix_error (error, "Error generating temporary self-signed dummy cert using openssl: ");
      goto out;
    }

  ret = TRUE;

out:
  g_free (stderr_str);
  g_free (command_line);
  g_free (subject);
  return ret;
}
Beispiel #20
0
int pg_util_ssh(const char *host,
		int port,
		const char *key_path,
		const char *cmd)
{
	gchar *ssh_cmd;
	gint status;

	ssh_cmd = g_strdup_printf("%s%s%s%s%s%s%u%s%s%s",
				  "ssh ", host, " -l root -q",
				  " -i ", key_path,
				  " -p ", port,
				  " -oConnectTimeout=1",
				  " -oStrictHostKeyChecking=no ", cmd);
	g_spawn_command_line_sync(ssh_cmd, NULL, NULL, &status, NULL);
	g_free(ssh_cmd);
	return g_spawn_check_exit_status(status, NULL) ? 0 : 1;
}
Beispiel #21
0
static gboolean
check_gl (GError **error)
{
        int status;
        char *argv[] = { LIBEXECDIR "/gnome-session-check-accelerated", NULL };

        if (getenv ("DISPLAY") == NULL) {
                /* Not connected to X11, someone else will take care of checking GL */
                return TRUE;
        }

        if (!g_spawn_sync (NULL, (char **) argv, NULL, 0, NULL, NULL, &gl_renderer, NULL,
                           &status, error)) {
                return FALSE;
        }

        return g_spawn_check_exit_status (status, error);
}
static void
on_pipe_close (CockpitPipe *pipe,
               const gchar *problem,
               gpointer user_data)
{
  CockpitPipeTransport *self = COCKPIT_PIPE_TRANSPORT (user_data);
  GError *error = NULL;
  gint status;

  /* This function is called by the base class when it is closed */
  if (cockpit_pipe_get_pid (pipe, NULL))
    {
      if (problem == NULL)
        {
          status = cockpit_pipe_exit_status (pipe);
          if (WIFSIGNALED (status) && WTERMSIG (status) == SIGTERM)
            problem = "terminated";
          else if (WIFEXITED (status) && WEXITSTATUS (status) == 5)
            problem = "not-authorized";  // wrong password
          else if (WIFEXITED (status) && WEXITSTATUS (status) == 6)
            problem = "unknown-hostkey";
          else if (WIFEXITED (status) && WEXITSTATUS (status) == 127)
            problem = "no-agent";        // cockpit-agent not installed
          else if (WIFEXITED (status) && WEXITSTATUS (status) == 255)
            problem = "terminated";      // ssh failed or got a signal, etc.
          else if (!g_spawn_check_exit_status (status, &error))
            {
              problem = "internal-error";
              g_warning ("%s: agent program failed: %s", self->name, error->message);
              g_error_free (error);
            }
        }
      else if (g_str_equal (problem, "not-found"))
        {
          g_message ("%s: failed to execute agent: not found", self->name);
          problem = "no-agent";
        }
    }

  g_debug ("%s: closed%s%s", self->name,
           problem ? ": " : "", problem ? problem : "");

  cockpit_transport_emit_closed (COCKPIT_TRANSPORT (self), problem);
}
Beispiel #23
0
static gboolean
handle_set_password_hash (CockpitAccount *object,
                          GDBusMethodInvocation *invocation,
                          const gchar *arg_hash)
{
    GError *error;
    Account *acc = ACCOUNT (object);
    const gchar *argv[6];
    gint status;

    if (!account_auth_check (object, invocation, acc))
        return TRUE;

    if (acc->u == NULL)
    {
        cockpit_account_complete_set_password_hash (object, invocation);
        return TRUE;
    }

    argv[0] = "/usr/sbin/usermod";
    argv[1] = "-p";
    argv[2] = arg_hash;
    argv[3] = "--";
    argv[4] = act_user_get_user_name (acc->u);
    argv[5] = NULL;

    error = NULL;
    if (g_spawn_sync (NULL, (gchar**)argv, NULL, 0, NULL, NULL, NULL, NULL, &status, &error))
        g_spawn_check_exit_status (status, &error);

    if (error)
    {
        g_dbus_method_invocation_return_error (invocation,
                                               COCKPIT_ERROR, COCKPIT_ERROR_FAILED,
                                               "Failed to change password hash via %s: %s", argv[0], error->message);
        g_error_free (error);
    }
    else
    {
        cockpit_account_complete_set_password_hash (object, invocation);
    }

    return TRUE;
}
static void
on_pipe_close (CockpitPipe *pipe,
               const gchar *problem,
               gpointer user_data)
{
  CockpitSshTransport *self = COCKPIT_SSH_TRANSPORT (user_data);
  GError *error = NULL;
  gint status;

  self->closing = TRUE;
  self->closed = TRUE;

  /* This function is called by the base class when it is closed */
  if (cockpit_pipe_get_pid (pipe, NULL))
    {
      if (problem == NULL ||
          g_str_equal (problem, "internal-error") ||
          g_str_equal (problem, "terminated"))
        {
          status = cockpit_pipe_exit_status (pipe);
          if (WIFSIGNALED (status) && WTERMSIG (status) == SIGTERM)
            problem = "terminated";
          else if (WIFEXITED (status) && WEXITSTATUS (status) == 127)
            problem = "no-cockpit";      // cockpit-bridge not installed
          else if (WIFEXITED (status) && WEXITSTATUS (status) == 255)
            problem = "terminated";      // failed or got a signal, etc.
          else if (WIFEXITED (status) && WEXITSTATUS (status) == 254)
            problem = "disconnected";    // got IO_ERR.
          else if (!g_spawn_check_exit_status (status, &error))
            {
              if (problem == NULL)
                problem = "internal-error";
              g_warning ("%s: ssh session failed: %s", self->logname, error->message);
              g_error_free (error);
            }
        }
    }

  g_debug ("%s: closed%s%s", self->logname,
           problem ? ": " : "", problem ? problem : "");

  cockpit_transport_emit_closed (COCKPIT_TRANSPORT (self), problem);
}
Beispiel #25
0
void
rpmostree_bwrap_unref (RpmOstreeBwrap *bwrap)
{
  bwrap->refcount--;
  if (bwrap->refcount > 0)
    return;

  if (bwrap->rofiles_mnt)
    {
      g_autoptr(GError) tmp_error = NULL;
      const char *fusermount_argv[] = { "fusermount", "-u", bwrap->rofiles_mnt, NULL};
      int estatus;

      if (!g_spawn_sync (NULL, (char**)fusermount_argv, NULL, G_SPAWN_SEARCH_PATH,
                         NULL, NULL, NULL, NULL, &estatus, &tmp_error))
        {
          g_prefix_error (&tmp_error, "Executing fusermount: ");
          goto out;
        }
      if (!g_spawn_check_exit_status (estatus, &tmp_error))
        {
          g_prefix_error (&tmp_error, "Executing fusermount: ");
          goto out;
        }

      (void) unlinkat (AT_FDCWD, bwrap->rofiles_mnt, AT_REMOVEDIR);
    out:
      /* We don't want a failure to unmount to be fatal, so all we do here
       * is log.  Though in practice what we *really* want is for the
       * fusermount to be in the bwrap namespace, and hence tied by the
       * kernel to the lifecycle of the container.  This would require
       * special casing for somehow doing FUSE mounts in bwrap.  Which
       * would be hard because NO_NEW_PRIVS turns off the setuid bits for
       * fuse.
       */
      if (tmp_error)
        sd_journal_print (LOG_WARNING, "%s", tmp_error->message);
    }

  g_ptr_array_unref (bwrap->argv);
  g_free (bwrap->rofiles_mnt);
  g_free (bwrap);
}
Beispiel #26
0
static gboolean
spawn_sync_require_success (char **argv,
                            GSpawnFlags flags,
                            GError **error)
{
  gboolean ret = FALSE;
  int estatus;

  if (!g_spawn_sync (NULL, argv, NULL,
                     flags, NULL, NULL,
                     NULL, NULL, &estatus, error))
    goto out;
  if (!g_spawn_check_exit_status (estatus, error))
    goto out;

  ret = TRUE;
 out:
  return ret;
}
Beispiel #27
0
static void finish_hwclock_call(GPid pid, gint status, gpointer user_data) {
	struct hwclock_call *hwclock_call = user_data;
	GError *error = NULL;

	g_spawn_close_pid(pid);

	if (g_spawn_check_exit_status(status, &error)) {
		if (hwclock_call->handler)
			(hwclock_call->handler)(hwclock_call->invocation, hwclock_call->handler_data);
	} else {
		g_printerr("hwclock failed: %s\n", error->message);
		if (hwclock_call->invocation)
			return_error(hwclock_call->invocation, G_DBUS_ERROR_FAILED, "hwclock failed: %s",
				     error->message);
		g_error_free(error);
	}

	g_free(hwclock_call->handler_data);
	g_free(hwclock_call);
}
Beispiel #28
0
static gboolean
run_xmlrpc_test (char **argv,
		 char **stdout_out,
		 char **stderr_out,
		 GError **error)
{
	gboolean ok;
	int status;

	argv[0] = g_test_build_filename (G_TEST_BUILT, "xmlrpc-test", NULL);
	ok = g_spawn_sync (NULL, argv, NULL, 0, NULL, NULL,
			   stdout_out, stderr_out, &status,
			   error);
	g_free (argv[0]);

	if (!ok)
		return FALSE;

	return g_spawn_check_exit_status (status, error);
}
Beispiel #29
0
static gboolean
handle_service_action (CockpitServices *object,
                       GDBusMethodInvocation *invocation,
                       const gchar *arg_name,
                       const gchar *arg_action)
{
  GError *error;
  Services *services = SERVICES (object);
  const gchar *argv[6];
  int i;
  gint status;

  const gchar *method = arg_action;
  gboolean force = FALSE;

  if (g_str_has_prefix (arg_action, "force-"))
    {
      force = TRUE;
      method = arg_action + strlen ("force-");
    }

  i = 0;
  argv[i++] = "pkexec";
  argv[i++] = "systemctl";
  if (force)
    argv[i++] = "--force";
  argv[i++] = method;
  argv[i++] = arg_name;
  argv[i++] = NULL;

  error = NULL;
  if (g_spawn_sync (NULL, (gchar**)argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL, &status, &error))
    g_spawn_check_exit_status (status, &error);

  if (error)
    end_invocation_take_gerror (invocation, error);
  else
    cockpit_services_complete_service_action (COCKPIT_SERVICES (services), invocation);

  return TRUE;
}
Beispiel #30
0
gboolean
rpmostree_bwrap_run (RpmOstreeBwrap *bwrap,
                     GError **error)
{
  int estatus;
  const char *current_lang = getenv ("LANG");

  g_assert (!bwrap->executed);
  bwrap->executed = TRUE;

  if (!current_lang)
    current_lang = "C";

  {
    const char *lang_var = glnx_strjoina ("LANG=", current_lang);
    /* This is similar to what systemd does, except:
     *  - We drop /usr/local, since scripts shouldn't see it.
     *  - We pull in the current process' LANG, since that's what people
     *    have historically expected from RPM scripts.
     */
    const char *bwrap_env[] = {"PATH=/usr/sbin:/usr/bin",
                               lang_var,
                               NULL};

    /* Add the final NULL */
    g_ptr_array_add (bwrap->argv, NULL);

    const char *errmsg = glnx_strjoina ("Executing bwrap(", bwrap->child_argv0, ")");
    GLNX_AUTO_PREFIX_ERROR (errmsg, error);

    if (!g_spawn_sync (NULL, (char**)bwrap->argv->pdata, (char**) bwrap_env, G_SPAWN_SEARCH_PATH,
                       bwrap_child_setup, bwrap,
                       NULL, NULL, &estatus, error))
      return FALSE;
    if (!g_spawn_check_exit_status (estatus, error))
      return FALSE;
  }

  return TRUE;
}