|
|
3a204fb |
From 9513fab99fa25f665adedf2fac6f5809a4987f2d Mon Sep 17 00:00:00 2001
|
|
|
3a204fb |
From: Jakub Filak <jfilak@redhat.com>
|
|
|
3a204fb |
Date: Thu, 4 Jun 2015 18:41:58 +0200
|
|
|
3a204fb |
Subject: [PATCH] dd: set owner to UID when creating dd from problem data
|
|
|
3a204fb |
|
|
|
3a204fb |
That is how the creating of a new dump directory from a problem data was
|
|
|
3a204fb |
working before the patches adding the meta-data owner and the patches
|
|
|
3a204fb |
dividing the dump directory owner to the FS owner of the dump directory
|
|
|
3a204fb |
and the owner of the problem.
|
|
|
3a204fb |
|
|
|
3a204fb |
The created dump directory must be accessible to the uid from
|
|
|
3a204fb |
FILENAME_UID but must have the requested FS owner.
|
|
|
3a204fb |
|
|
|
3a204fb |
Signed-off-by: Jakub Filak <jfilak@redhat.com>
|
|
|
3a204fb |
---
|
|
|
3a204fb |
src/lib/create_dump_dir.c | 55 ++++++++++++++++++++++++++++-------
|
|
|
3a204fb |
tests/dump_dir.at | 73 +++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
3a204fb |
2 files changed, 117 insertions(+), 11 deletions(-)
|
|
|
3a204fb |
|
|
|
3a204fb |
diff --git a/src/lib/create_dump_dir.c b/src/lib/create_dump_dir.c
|
|
|
3a204fb |
index dec75fa..3c9e01d 100644
|
|
|
3a204fb |
--- a/src/lib/create_dump_dir.c
|
|
|
3a204fb |
+++ b/src/lib/create_dump_dir.c
|
|
|
3a204fb |
@@ -22,6 +22,18 @@
|
|
|
3a204fb |
|
|
|
3a204fb |
#define NEW_PD_SUFFIX ".new"
|
|
|
3a204fb |
|
|
|
3a204fb |
+static uid_t parse_uid(const char *uid_str)
|
|
|
3a204fb |
+{
|
|
|
3a204fb |
+ assert(sizeof(uid_t) == sizeof(unsigned));
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ uid_t uid = (uid_t)-1;
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ if (try_atou(uid_str, &uid) != 0)
|
|
|
3a204fb |
+ error_msg(_("uid value is not valid: '%s'"), uid_str);
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ return uid;
|
|
|
3a204fb |
+}
|
|
|
3a204fb |
+
|
|
|
3a204fb |
static struct dump_dir *try_dd_create(const char *base_dir_name, const char *dir_name, uid_t uid)
|
|
|
3a204fb |
{
|
|
|
3a204fb |
char *path = concat_path_file(base_dir_name, dir_name);
|
|
|
3a204fb |
@@ -85,9 +97,38 @@ struct dump_dir *create_dump_dir(const char *base_dir_name, const char *type, ui
|
|
|
3a204fb |
* reporting from anaconda where we can't read /etc/{system,redhat}-release
|
|
|
3a204fb |
* and os_release is taken from anaconda
|
|
|
3a204fb |
*/
|
|
|
3a204fb |
- const uid_t crashed_uid = dd_exist(dd, FILENAME_UID) ? /*uid already saved*/-1 : uid;
|
|
|
3a204fb |
+ char *uid_str = dd_load_text_ext(dd, FILENAME_UID, DD_LOAD_TEXT_RETURN_NULL_ON_FAILURE);
|
|
|
3a204fb |
+ const uid_t crashed_uid = uid_str != NULL ? /*uid already saved*/-1 : uid;
|
|
|
3a204fb |
dd_create_basic_files(dd, crashed_uid, NULL);
|
|
|
3a204fb |
|
|
|
3a204fb |
+ /* If crashed uid is (uid_t)-1, then dd_create_basic_files() didn't set the
|
|
|
3a204fb |
+ * dd owner and the dd owner remained on fs owner (the default owner used
|
|
|
3a204fb |
+ * when creating a new dump directory).
|
|
|
3a204fb |
+ *
|
|
|
3a204fb |
+ * Our callers expect, that the dd owner is set to value of UID (it used to
|
|
|
3a204fb |
+ * be the case before the dd owner was introduced), so we have to try to
|
|
|
3a204fb |
+ * get UID from the dump directory, parse it and use the parse value.
|
|
|
3a204fb |
+ * Errors are not critical, because the dump directory is already owned by
|
|
|
3a204fb |
+ * the fs owner.
|
|
|
3a204fb |
+ */
|
|
|
3a204fb |
+ if (crashed_uid == (uid_t)-1 && uid_str != NULL)
|
|
|
3a204fb |
+ {
|
|
|
3a204fb |
+ uid_t owner_uid = parse_uid(uid_str);
|
|
|
3a204fb |
+ if (owner_uid != (uid_t)-1)
|
|
|
3a204fb |
+ {
|
|
|
3a204fb |
+ log_notice("Changing owner of the new problem to: %s", uid_str);
|
|
|
3a204fb |
+ /* Ignore errors, the old value is preseverd or fs uid will be used
|
|
|
3a204fb |
+ * instead. The function prints out good error messges.*/
|
|
|
3a204fb |
+ dd_set_owner(dd, owner_uid);
|
|
|
3a204fb |
+ }
|
|
|
3a204fb |
+ else
|
|
|
3a204fb |
+ log_notice("Failed to parse UID, keeping the default owner.");
|
|
|
3a204fb |
+ }
|
|
|
3a204fb |
+ else
|
|
|
3a204fb |
+ log_notice("No UID provided, keeping the default owner.");
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ free(uid_str);
|
|
|
3a204fb |
+
|
|
|
3a204fb |
problem_id[strlen(problem_id) - strlen(NEW_PD_SUFFIX)] = '\0';
|
|
|
3a204fb |
char* new_path = concat_path_file(base_dir_name, problem_id);
|
|
|
3a204fb |
log_info("Renaming from '%s' to '%s'", dd->dd_dirname, new_path);
|
|
|
3a204fb |
@@ -156,17 +197,9 @@ struct dump_dir *create_dump_dir_from_problem_data(problem_data_t *problem_data,
|
|
|
3a204fb |
|
|
|
3a204fb |
if (uid_str)
|
|
|
3a204fb |
{
|
|
|
3a204fb |
- char *endptr;
|
|
|
3a204fb |
- errno = 0;
|
|
|
3a204fb |
- long val = strtol(uid_str, &endptr, 10);
|
|
|
3a204fb |
-
|
|
|
3a204fb |
- if (errno != 0 || endptr == uid_str || *endptr != '\0' || INT_MAX < val)
|
|
|
3a204fb |
- {
|
|
|
3a204fb |
- error_msg(_("uid value is not valid: '%s'"), uid_str);
|
|
|
3a204fb |
+ uid = parse_uid(uid_str);
|
|
|
3a204fb |
+ if (uid == (uid_t)-1)
|
|
|
3a204fb |
return NULL;
|
|
|
3a204fb |
- }
|
|
|
3a204fb |
-
|
|
|
3a204fb |
- uid = (uid_t)val;
|
|
|
3a204fb |
}
|
|
|
3a204fb |
|
|
|
3a204fb |
return create_dump_dir_from_problem_data_ext(problem_data, base_dir_name, uid);
|
|
|
3a204fb |
diff --git a/tests/dump_dir.at b/tests/dump_dir.at
|
|
|
3a204fb |
index cc0148c..0e491ce 100644
|
|
|
3a204fb |
--- a/tests/dump_dir.at
|
|
|
3a204fb |
+++ b/tests/dump_dir.at
|
|
|
3a204fb |
@@ -532,3 +532,76 @@ int main(void)
|
|
|
3a204fb |
return 0;
|
|
|
3a204fb |
}
|
|
|
3a204fb |
]])
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+## --------------- ##
|
|
|
3a204fb |
+## create_dump_dir ##
|
|
|
3a204fb |
+## --------------- ##
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+AT_TESTFUN([create_dump_dir],
|
|
|
3a204fb |
+[[
|
|
|
3a204fb |
+#include "internal_libreport.h"
|
|
|
3a204fb |
+#include <assert.h>
|
|
|
3a204fb |
+#
|
|
|
3a204fb |
+int main(void)
|
|
|
3a204fb |
+{
|
|
|
3a204fb |
+ g_verbose = 3;
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ char template[] = "/tmp/XXXXXX";
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ if (mkdtemp(template) == NULL) {
|
|
|
3a204fb |
+ perror("mkdtemp()");
|
|
|
3a204fb |
+ return EXIT_FAILURE;
|
|
|
3a204fb |
+ }
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ printf("Base dump dir path: %s\n", template);
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ dd_g_fs_group_gid = getegid();
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ problem_data_t *pd = problem_data_new();
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ problem_data_add_text_editable(pd, FILENAME_TYPE, "attest");
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ {
|
|
|
3a204fb |
+ fprintf(stderr, "=== NO UID - geteuid() ===\n");
|
|
|
3a204fb |
+ struct dump_dir *no_uid_dd_geteuid = create_dump_dir_from_problem_data_ext(pd, template, geteuid());
|
|
|
3a204fb |
+ assert(no_uid_dd_geteuid != NULL);
|
|
|
3a204fb |
+ assert(dd_get_owner(no_uid_dd_geteuid) == geteuid());
|
|
|
3a204fb |
+ assert(dd_delete(no_uid_dd_geteuid) == 0);
|
|
|
3a204fb |
+ fprintf(stderr, "=== NO UID - geteuid() ===\n");
|
|
|
3a204fb |
+ }
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ {
|
|
|
3a204fb |
+ fprintf(stderr, "=== NO UID - NO UID ===\n");
|
|
|
3a204fb |
+ struct dump_dir *no_uid_dd_nouid = create_dump_dir_from_problem_data_ext(pd, template, (uid_t)-1L);
|
|
|
3a204fb |
+ assert(no_uid_dd_nouid != NULL);
|
|
|
3a204fb |
+ assert(dd_get_owner(no_uid_dd_nouid) == geteuid());
|
|
|
3a204fb |
+ assert(dd_delete(no_uid_dd_nouid) == 0);
|
|
|
3a204fb |
+ fprintf(stderr, "=== NO UID - NO UID ===\n");
|
|
|
3a204fb |
+ }
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ char buf[sizeof(long)*3 + 2];
|
|
|
3a204fb |
+ snprintf(buf, sizeof(buf), "%ld", (long)(geteuid() + 1));
|
|
|
3a204fb |
+ problem_data_add_text_editable(pd, FILENAME_UID, buf);
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ {
|
|
|
3a204fb |
+ fprintf(stderr, "=== UID - geteuid() ===\n");
|
|
|
3a204fb |
+ struct dump_dir *uid_dd_geteuid = create_dump_dir_from_problem_data_ext(pd, template, geteuid());
|
|
|
3a204fb |
+ assert(uid_dd_geteuid != NULL);
|
|
|
3a204fb |
+ assert(dd_get_owner(uid_dd_geteuid) == (geteuid() + 1));
|
|
|
3a204fb |
+ assert(dd_delete(uid_dd_geteuid) == 0);
|
|
|
3a204fb |
+ fprintf(stderr, "=== UID - geteuid() ===\n");
|
|
|
3a204fb |
+ }
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ {
|
|
|
3a204fb |
+ fprintf(stderr, "=== UID - NO UID ===\n");
|
|
|
3a204fb |
+ struct dump_dir *uid_dd_nouid = create_dump_dir_from_problem_data_ext(pd, template, (uid_t)-1L);
|
|
|
3a204fb |
+ assert(uid_dd_nouid != NULL);
|
|
|
3a204fb |
+ assert(dd_get_owner(uid_dd_nouid) == (geteuid() + 1));
|
|
|
3a204fb |
+ assert(dd_delete(uid_dd_nouid) == 0);
|
|
|
3a204fb |
+ fprintf(stderr, "=== UID - NO UID ===\n");
|
|
|
3a204fb |
+ }
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ assert(rmdir(template) == 0);
|
|
|
3a204fb |
+ return EXIT_SUCCESS;
|
|
|
3a204fb |
+}
|
|
|
3a204fb |
+]])
|
|
|
3a204fb |
--
|
|
|
3a204fb |
2.1.0
|
|
|
3a204fb |
|