- + minor refactoring
---
src/dbus/abrt-dbus.c | 71 +++++++++++++++++++++++++++++++++-------------
src/include/abrt-dbus.h | 4 ++
src/lib/Makefile.am | 3 +-
src/lib/abrt_glib.c | 54 +++++++++++++++++++++++++++++++++++
4 files changed, 111 insertions(+), 21 deletions(-)
create mode 100644 src/lib/abrt_glib.c
diff --git a/src/dbus/abrt-dbus.c b/src/dbus/abrt-dbus.c
index cf04a0d..abeadaf 100644
--- a/src/dbus/abrt-dbus.c
+++ b/src/dbus/abrt-dbus.c
@@ -6,6 +6,7 @@
#include "libabrt.h"
#include "abrt-polkit.h"
#include "abrt-dbus.h"
+#include "dump_dir.h"
GMainLoop *loop;
guint g_timeout;
@@ -34,6 +35,9 @@ static const gchar introspection_xml[] =
" <method name='ChownProblemDir'>"
" <arg type='s' name='problem_dir' direction='in'/>"
" </method>"
+ " <method name='DeleteProblem'>"
+ " <arg type='as' name='problem_dir' direction='in'/>"
+ " </method>"
" <method name='Quit' />"
" </interface>"
"</node>";
@@ -131,6 +135,25 @@ static bool uid_in_group(uid_t uid, gid_t gid)
return FALSE;
}
+/*
+ 0 - user doesn't have access
+ 1 - user has access
+*/
+static int dir_accessible_by_uid(const char* dir_path, uid_t uid)
+{
+ struct stat statbuf;
+ if (stat(dir_path, &statbuf) == 0 && S_ISDIR(statbuf.st_mode))
+ {
+ if (uid == 0 || uid_in_group(uid, statbuf.st_gid))
+ {
+ VERB1 log("caller has access to the requested directory %s", dir_path);
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
static GList* scan_directory(const char *path, uid_t caller_uid)
{
GList *list = NULL;
@@ -185,19 +208,7 @@ static GVariant *get_problem_dirs_for_uid(uid_t uid, const char *dump_location)
{
GList *dirs = scan_directory(dump_location, uid);
- GVariantBuilder *builder;
- builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
- while (dirs)
- {
- g_variant_builder_add(builder, "s", (char*)dirs->data);
- free(dirs->data);
- dirs = g_list_delete_link(dirs, dirs);
- }
-
- GVariant *response = g_variant_new("(as)", builder);
- g_variant_builder_unref(builder);
-
- return response;
+ return variant_from_string_list(dirs);
}
static void handle_method_call(GDBusConnection *connection,
@@ -331,8 +342,9 @@ static void handle_method_call(GDBusConnection *connection,
g_dbus_method_invocation_return_dbus_error(invocation,
"org.freedesktop.problems.ChownError",
strerror(errno));
+ else
+ g_dbus_method_invocation_return_value(invocation, NULL);
- g_dbus_method_invocation_return_value(invocation, NULL);
dd_close(dd);
return;
}
@@ -390,10 +402,7 @@ static void handle_method_call(GDBusConnection *connection,
| DD_FAIL_QUIETLY_ENOENT
| DD_FAIL_QUIETLY_EACCES);
if (not_reportable_reason)
- g_variant_builder_add (builder, "{ss}", xstrdup(FILENAME_NOT_REPORTABLE), dd_load_text_ext(dd, FILENAME_NOT_REPORTABLE, 0
- | DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE
- | DD_FAIL_QUIETLY_ENOENT
- | DD_FAIL_QUIETLY_EACCES));
+ g_variant_builder_add (builder, "{ss}", xstrdup(FILENAME_NOT_REPORTABLE), not_reportable_reason);
/* the source of the problem:
* - first we try to load component, as we use it on Fedora
*/
@@ -406,7 +415,6 @@ static void handle_method_call(GDBusConnection *connection,
if (!source)
{
source = dd_load_text_ext(dd, FILENAME_EXECUTABLE, 0
- | DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE
| DD_FAIL_QUIETLY_ENOENT
| DD_FAIL_QUIETLY_EACCES
);
@@ -434,6 +442,30 @@ static void handle_method_call(GDBusConnection *connection,
return;
}
+ else if (g_strcmp0(method_name, "DeleteProblem") == 0)
+ {
+ VERB1 log("DeleteProblem");
+
+ GList *problem_dirs = string_list_from_variant(parameters);
+
+ while (problem_dirs)
+ {
+ if (!dir_accessible_by_uid((const char*)problem_dirs->data, caller_uid))
+ {
+ if (polkit_check_authorization_dname(caller, "org.freedesktop.problems.getall") != PolkitYes)
+ { // if user didn't provide correct credentials, just move to the next dir
+ problem_dirs = g_list_next((const char*)problem_dirs->data);
+ continue;
+ }
+ }
+ delete_dump_dir((const char*)problem_dirs->data);
+ problem_dirs = g_list_next(problem_dirs);
+ }
+
+ g_dbus_method_invocation_return_value(invocation, NULL);
+ return;
+ }
+
else if (g_strcmp0(method_name, "Quit") == 0)
{
VERB1 log("Quit");
@@ -441,7 +473,6 @@ static void handle_method_call(GDBusConnection *connection,
g_dbus_method_invocation_return_value(invocation, NULL);
g_main_loop_quit(loop);
-
}
}
diff --git a/src/include/abrt-dbus.h b/src/include/abrt-dbus.h
index 898dd94..dfc5b80 100644
--- a/src/include/abrt-dbus.h
+++ b/src/include/abrt-dbus.h
@@ -5,4 +5,8 @@
#define ABRT_DBUS_OBJECT "/org/freedesktop/problems"
#define ABRT_DBUS_IFACE "org.freedesktop.problems"
+GList *string_list_from_variant(GVariant *variant);
+
+GVariant *variant_from_string_list(GList *strings);
+
#endif /* ABRTDBUS_H_ */
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index bbeb687..4ea19ef 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -8,7 +8,8 @@ libabrt_la_SOURCES = \
abrt_conf.c \
hooklib.c \
daemon_is_ok.c \
- kernel.c
+ kernel.c \
+ abrt_glib.c
libabrt_la_CPPFLAGS = \
-Wall -Wwrite-strings -Werror \
diff --git a/src/lib/abrt_glib.c b/src/lib/abrt_glib.c
new file mode 100644
index 0000000..c54a33a
--- /dev/null
+++ b/src/lib/abrt_glib.c
@@ -0,0 +1,54 @@
+/*
+ Copyright (C) 2011 ABRT team
+ Copyright (C) 2011 RedHat Inc
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+#include <glib-2.0/glib.h>
+#include "libabrt.h"
+
+GList *string_list_from_variant(GVariant *variant)
+{
+ GList *list = NULL;
+ GVariantIter *iter;
+ gchar *str;
+ g_variant_get(variant, "(as)", &iter);
+ while (g_variant_iter_loop(iter, "s", &str))
+ {
+ VERB1 log("adding: %s", str);
+ list = g_list_prepend(list, xstrdup(str));
+ }
+ g_variant_unref(variant);
+
+ return list;
+}
+
+GVariant *variant_from_string_list(GList *strings)
+{
+ GVariantBuilder *builder;
+ builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
+
+ while (strings)
+ {
+ g_variant_builder_add(builder, "s", (char*)strings->data);
+ free(strings->data);
+ strings = g_list_delete_link(strings, strings);
+ }
+
+ GVariant *variant = g_variant_new("(as)", builder);
+ g_variant_builder_unref(builder);
+
+ return variant;
+}
\ No newline at end of file
--
1.7.7.6