47a88a
From 5560ca0e51919bc5aeccb22584e24219040dc78b Mon Sep 17 00:00:00 2001
47a88a
From: Jakub Filak <jfilak@redhat.com>
47a88a
Date: Tue, 24 Mar 2015 20:57:34 +0100
47a88a
Subject: [PATCH] cli: use the DBus methods for getting problem information
47a88a
47a88a
The dump directory is no longer accessible by non-root users and we also
47a88a
want to get rid of direct access to allow administrators (wheel members)
47a88a
see problem data without the need to ChownProblem directory before.
47a88a
47a88a
Related: #1224984
47a88a
47a88a
Signed-off-by: Jakub Filak <jfilak@redhat.com>
47a88a
---
47a88a
 src/cli/abrt-cli-core.c | 74 ++++++++++++++++++++++++-------------------------
47a88a
 src/cli/abrt-cli-core.h |  4 ++-
47a88a
 src/cli/list.c          | 45 +++++++++++-------------------
47a88a
 src/cli/process.c       |  6 +---
47a88a
 src/cli/status.c        | 66 +++++++++++++------------------------------
47a88a
 5 files changed, 77 insertions(+), 118 deletions(-)
47a88a
47a88a
diff --git a/src/cli/abrt-cli-core.c b/src/cli/abrt-cli-core.c
47a88a
index 23a74a8..77a37f7 100644
47a88a
--- a/src/cli/abrt-cli-core.c
47a88a
+++ b/src/cli/abrt-cli-core.c
47a88a
@@ -39,24 +39,22 @@ vector_of_problem_data_t *new_vector_of_problem_data(void)
47a88a
     return g_ptr_array_new_with_free_func((void (*)(void*)) &problem_data_free);
47a88a
 }
47a88a
 
47a88a
-static int
47a88a
-append_problem_data(struct dump_dir *dd, void *arg)
47a88a
+vector_of_problem_data_t *fetch_crash_infos(void)
47a88a
 {
47a88a
-    vector_of_problem_data_t *vpd = arg;
47a88a
-
47a88a
-    problem_data_t *problem_data = create_problem_data_from_dump_dir(dd);
47a88a
-    problem_data_add(problem_data, CD_DUMPDIR, dd->dd_dirname,
47a88a
-                            CD_FLAG_TXT + CD_FLAG_ISNOTEDITABLE + CD_FLAG_LIST);
47a88a
-    g_ptr_array_add(vpd, problem_data);
47a88a
-    return 0;
47a88a
-}
47a88a
+    GList *problems = get_problems_over_dbus(/*don't authorize*/false);
47a88a
+    if (problems == ERR_PTR)
47a88a
+        return NULL;
47a88a
 
47a88a
-vector_of_problem_data_t *fetch_crash_infos(GList *dir_list)
47a88a
-{
47a88a
     vector_of_problem_data_t *vpd = new_vector_of_problem_data();
47a88a
 
47a88a
-    for (GList *li = dir_list; li; li = li->next)
47a88a
-        for_each_problem_in_dir(li->data, getuid(), append_problem_data, vpd);
47a88a
+    for (GList *iter = problems; iter; iter = g_list_next(iter))
47a88a
+    {
47a88a
+        problem_data_t *problem_data = get_full_problem_data_over_dbus((const char *)(iter->data));
47a88a
+        if (problem_data == ERR_PTR)
47a88a
+            continue;
47a88a
+
47a88a
+        g_ptr_array_add(vpd, problem_data);
47a88a
+    }
47a88a
 
47a88a
     return vpd;
47a88a
 }
47a88a
@@ -74,36 +72,38 @@ static bool isxdigit_str(const char *str)
47a88a
     return true;
47a88a
 }
47a88a
 
47a88a
-struct name_resolution_param {
47a88a
-    const char *shortcut;
47a88a
-    unsigned strlen_shortcut;
47a88a
-    char *found_name;
47a88a
-};
47a88a
-
47a88a
-static int find_dir_by_hash(struct dump_dir *dd, void *arg)
47a88a
+char *find_problem_by_hash(const char *hash, GList *problems)
47a88a
 {
47a88a
-    struct name_resolution_param *param = arg;
47a88a
-    char hash_str[SHA1_RESULT_LEN*2 + 1];
47a88a
-    str_to_sha1str(hash_str, dd->dd_dirname);
47a88a
-    if (strncasecmp(param->shortcut, hash_str, param->strlen_shortcut) == 0)
47a88a
+    unsigned hash_len = strlen(hash);
47a88a
+    if (!isxdigit_str(hash) || hash_len < 5)
47a88a
+        return NULL;
47a88a
+
47a88a
+    char *found_name = NULL;
47a88a
+    for (GList *iter = problems; iter; iter = g_list_next(iter))
47a88a
     {
47a88a
-        if (param->found_name)
47a88a
-            error_msg_and_die(_("'%s' identifies more than one problem directory"), param->shortcut);
47a88a
-        param->found_name = xstrdup(dd->dd_dirname);
47a88a
+        char hash_str[SHA1_RESULT_LEN*2 + 1];
47a88a
+        str_to_sha1str(hash_str, (const char *)(iter->data));
47a88a
+        if (strncasecmp(hash, hash_str, hash_len) == 0)
47a88a
+        {
47a88a
+            if (found_name)
47a88a
+                error_msg_and_die(_("'%s' identifies more than one problem directory"), hash);
47a88a
+            found_name = xstrdup((const char *)(iter->data));
47a88a
+        }
47a88a
     }
47a88a
-    return 0;
47a88a
+
47a88a
+    return found_name;
47a88a
 }
47a88a
 
47a88a
 char *hash2dirname(const char *hash)
47a88a
 {
47a88a
-    unsigned hash_len = strlen(hash);
47a88a
-    if (!isxdigit_str(hash) || hash_len < 5)
47a88a
+    /* Try loading by dirname hash */
47a88a
+    GList *problems = get_problems_over_dbus(/*don't authorize*/false);
47a88a
+    if (problems == ERR_PTR)
47a88a
         return NULL;
47a88a
 
47a88a
-    /* Try loading by dirname hash */
47a88a
-    struct name_resolution_param param = { hash, hash_len, NULL };
47a88a
-    GList *dir_list = get_problem_storages();
47a88a
-    for (GList *li = dir_list; li; li = li->next)
47a88a
-        for_each_problem_in_dir(li->data, getuid(), find_dir_by_hash, ¶m;;
47a88a
-    return param.found_name;
47a88a
+    char *found_name = find_problem_by_hash(hash, problems);
47a88a
+
47a88a
+    g_list_free_full(problems, free);
47a88a
+
47a88a
+    return found_name;
47a88a
 }
47a88a
diff --git a/src/cli/abrt-cli-core.h b/src/cli/abrt-cli-core.h
47a88a
index 83d0b5d..33b2ea6 100644
47a88a
--- a/src/cli/abrt-cli-core.h
47a88a
+++ b/src/cli/abrt-cli-core.h
47a88a
@@ -28,9 +28,11 @@ problem_data_t *get_problem_data(vector_of_problem_data_t *vector, unsigned i);
47a88a
 
47a88a
 void free_vector_of_problem_data(vector_of_problem_data_t *vector);
47a88a
 vector_of_problem_data_t *new_vector_of_problem_data(void);
47a88a
-vector_of_problem_data_t *fetch_crash_infos(GList *dir_list);
47a88a
+vector_of_problem_data_t *fetch_crash_infos(void);
47a88a
 
47a88a
 /* Returns malloced string, or NULL if not found: */
47a88a
+char *find_problem_by_hash(const char *hash, GList *problems);
47a88a
+/* Returns malloced string, or NULL if not found: */
47a88a
 char *hash2dirname(const char *hash);
47a88a
 
47a88a
 
47a88a
diff --git a/src/cli/list.c b/src/cli/list.c
47a88a
index ccb5f3b..1594906 100644
47a88a
--- a/src/cli/list.c
47a88a
+++ b/src/cli/list.c
47a88a
@@ -30,33 +30,28 @@
47a88a
  *       ~/.abrt/spool and /var/tmp/abrt? needs more _meditation_.
47a88a
  */
47a88a
 
47a88a
-static problem_data_t *load_problem_data(const char *dump_dir_name)
47a88a
+static problem_data_t *load_problem_data(const char *problem_id)
47a88a
 {
47a88a
-    /* First, try loading by dirname */
47a88a
-    int sv_logmode = logmode;
47a88a
-    logmode = 0; /* suppress EPERM/EACCES errors in opendir */
47a88a
-    struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ DD_OPEN_READONLY);
47a88a
-    logmode = sv_logmode;
47a88a
+    char *name2 = NULL;
47a88a
+
47a88a
+    /* First, check if there is a problem with the passed id */
47a88a
+    GList *problems = get_problems_over_dbus(/*don't authorize*/false);
47a88a
+    GList *item = g_list_find_custom(problems, problem_id, (GCompareFunc)strcmp);
47a88a
 
47a88a
     /* (git requires at least 5 char hash prefix, we do the same) */
47a88a
-    if (!dd && errno == ENOENT)
47a88a
+    if (item == NULL)
47a88a
     {
47a88a
         /* Try loading by dirname hash */
47a88a
-        char *name2 = hash2dirname(dump_dir_name);
47a88a
-        if (name2)
47a88a
-            dd = dd_opendir(name2, /*flags:*/ DD_OPEN_READONLY);
47a88a
-        free(name2);
47a88a
-    }
47a88a
+        name2 = find_problem_by_hash(problem_id, problems);
47a88a
+        if (name2 == NULL)
47a88a
+            return NULL;
47a88a
 
47a88a
-    if (!dd)
47a88a
-        return NULL;
47a88a
+        problem_id = name2;
47a88a
+    }
47a88a
 
47a88a
-    problem_data_t *problem_data = create_problem_data_from_dump_dir(dd);
47a88a
-    problem_data_add(problem_data, CD_DUMPDIR, dd->dd_dirname,
47a88a
-                            CD_FLAG_TXT + CD_FLAG_ISNOTEDITABLE + CD_FLAG_LIST);
47a88a
-    dd_close(dd);
47a88a
+    problem_data_t *problem_data = get_full_problem_data_over_dbus(problem_id);
47a88a
 
47a88a
-    return problem_data;
47a88a
+    return (problem_data == ERR_PTR ? NULL : problem_data);
47a88a
 }
47a88a
 
47a88a
 /** Prints basic information about a crash to stdout. */
47a88a
@@ -176,7 +171,7 @@ static bool print_crash_list(vector_of_problem_data_t *crash_list, int detailed,
47a88a
 int cmd_list(int argc, const char **argv)
47a88a
 {
47a88a
     const char *program_usage_string = _(
47a88a
-        "& list [options] [DIR]..."
47a88a
+        "& list [options]"
47a88a
         );
47a88a
 
47a88a
     int opt_not_reported = 0;
47a88a
@@ -194,15 +189,8 @@ int cmd_list(int argc, const char **argv)
47a88a
     };
47a88a
 
47a88a
     parse_opts(argc, (char **)argv, program_options, program_usage_string);
47a88a
-    argv += optind;
47a88a
-
47a88a
-    GList *D_list = NULL;
47a88a
-    while (*argv)
47a88a
-        D_list = g_list_append(D_list, xstrdup(*argv++));
47a88a
-    if (!D_list)
47a88a
-        D_list = get_problem_storages();
47a88a
 
47a88a
-    vector_of_problem_data_t *ci = fetch_crash_infos(D_list);
47a88a
+    vector_of_problem_data_t *ci = fetch_crash_infos();
47a88a
 
47a88a
     g_ptr_array_sort_with_data(ci, &cmp_problem_data, (char *) FILENAME_LAST_OCCURRENCE);
47a88a
 
47a88a
@@ -212,7 +200,6 @@ int cmd_list(int argc, const char **argv)
47a88a
     print_crash_list(ci, opt_detailed, opt_not_reported, opt_since, opt_until, CD_TEXT_ATT_SIZE_BZ);
47a88a
 
47a88a
     free_vector_of_problem_data(ci);
47a88a
-    list_free_with_free(D_list);
47a88a
 
47a88a
 #if SUGGEST_AUTOREPORTING != 0
47a88a
     load_abrt_conf();
47a88a
diff --git a/src/cli/process.c b/src/cli/process.c
47a88a
index 7f4fff5..39462f9 100644
47a88a
--- a/src/cli/process.c
47a88a
+++ b/src/cli/process.c
47a88a
@@ -152,18 +152,14 @@ int cmd_process(int argc, const char **argv)
47a88a
     };
47a88a
 
47a88a
     parse_opts(argc, (char **)argv, program_options, program_usage_string);
47a88a
-    argv += optind;
47a88a
 
47a88a
-    GList *D_list = get_problem_storages();
47a88a
-
47a88a
-    vector_of_problem_data_t *ci = fetch_crash_infos(D_list);
47a88a
+    vector_of_problem_data_t *ci = fetch_crash_infos();
47a88a
 
47a88a
     g_ptr_array_sort_with_data(ci, &cmp_problem_data, (char *) FILENAME_LAST_OCCURRENCE);
47a88a
 
47a88a
     process_crashes(ci, opt_since);
47a88a
 
47a88a
     free_vector_of_problem_data(ci);
47a88a
-    list_free_with_free(D_list);
47a88a
 
47a88a
     return 0;
47a88a
 }
47a88a
diff --git a/src/cli/status.c b/src/cli/status.c
47a88a
index 1de2d41..68bdd0e 100644
47a88a
--- a/src/cli/status.c
47a88a
+++ b/src/cli/status.c
47a88a
@@ -21,53 +21,36 @@
47a88a
 #include <sys/types.h>
47a88a
 #include "problem_api.h"
47a88a
 
47a88a
-struct time_range {
47a88a
-    unsigned count;
47a88a
-    unsigned long since;
47a88a
-};
47a88a
-
47a88a
-static int count_dir_if_newer_than(struct dump_dir *dd, void *arg)
47a88a
-{
47a88a
-    struct time_range *me = arg;
47a88a
-
47a88a
-    if (dd_exist(dd, FILENAME_REPORTED_TO))
47a88a
-        return 0;
47a88a
-
47a88a
-    char *time_str = dd_load_text(dd, FILENAME_LAST_OCCURRENCE);
47a88a
-    long val = atol(time_str);
47a88a
-    free(time_str);
47a88a
-    if (val < me->since)
47a88a
-        return 0;
47a88a
-
47a88a
-    me->count++;
47a88a
-    return 0;
47a88a
-}
47a88a
-
47a88a
-static void count_problems_in_dir(gpointer data, gpointer arg)
47a88a
+static unsigned int count_problem_dirs(unsigned long since)
47a88a
 {
47a88a
-    char *path = data;
47a88a
-    struct time_range *me = arg;
47a88a
+    unsigned count = 0;
47a88a
 
47a88a
-    log_info("scanning '%s' for problems since %lu", path, me->since);
47a88a
+    GList *problems = get_problems_over_dbus(/*don't authorize*/false);
47a88a
+    for (GList *iter = problems; iter != NULL; iter = g_list_next(iter))
47a88a
+    {
47a88a
+        const char *problem_id = (const char *)iter->data;
47a88a
+        if (test_exist_over_dbus(problem_id, FILENAME_REPORTED_TO))
47a88a
+            continue;
47a88a
 
47a88a
-    for_each_problem_in_dir(path, getuid(), count_dir_if_newer_than, me);
47a88a
-}
47a88a
+        char *time_str = load_text_over_dbus(problem_id, FILENAME_LAST_OCCURRENCE);
47a88a
+        if (time_str == NULL)
47a88a
+            continue;
47a88a
 
47a88a
-static unsigned int count_problem_dirs(GList *paths, unsigned long since)
47a88a
-{
47a88a
-    struct time_range me;
47a88a
-    me.count = 0;
47a88a
-    me.since = since;
47a88a
+        long val = atol(time_str);
47a88a
+        free(time_str);
47a88a
+        if (val < since)
47a88a
+            return 0;
47a88a
 
47a88a
-    g_list_foreach(paths, count_problems_in_dir, &me);
47a88a
+        count++;
47a88a
+    }
47a88a
 
47a88a
-    return me.count;
47a88a
+    return count;
47a88a
 }
47a88a
 
47a88a
 int cmd_status(int argc, const char **argv)
47a88a
 {
47a88a
     const char *program_usage_string = _(
47a88a
-        "& status [DIR]..."
47a88a
+        "& status"
47a88a
         );
47a88a
 
47a88a
     int opt_bare = 0; /* must be _int_, OPT_BOOL expects that! */
47a88a
@@ -81,17 +64,8 @@ int cmd_status(int argc, const char **argv)
47a88a
     };
47a88a
 
47a88a
     parse_opts(argc, (char **)argv, program_options, program_usage_string);
47a88a
-    argv += optind;
47a88a
-
47a88a
-    GList *problem_dir_list = NULL;
47a88a
-    while (*argv)
47a88a
-        problem_dir_list = g_list_append(problem_dir_list, xstrdup(*argv++));
47a88a
-    if (!problem_dir_list)
47a88a
-        problem_dir_list = get_problem_storages();
47a88a
-
47a88a
-    unsigned int problem_count = count_problem_dirs(problem_dir_list, opt_since);
47a88a
 
47a88a
-    list_free_with_free(problem_dir_list);
47a88a
+    unsigned int problem_count = count_problem_dirs(opt_since);
47a88a
 
47a88a
     /* show only if there is at least 1 problem or user set the -v */
47a88a
     if (problem_count > 0 || g_verbose > 0)
47a88a
-- 
47a88a
2.4.3
47a88a