From b81884dcf41a6ee84c9ef5633acd2193bee60005 Mon Sep 17 00:00:00 2001 From: Jakub Filak Date: Wed, 15 Apr 2015 15:19:40 +0200 Subject: [LIBREPORT PATCH] dump_dir: allow creating of a new dir w/o chowning it Split dd_create() in to dd_create_skeleton() creating the directory and intializing struct dd* and dd_reset_ownership() updating UID and GUI to the deemed values. We need this because we have to avoid situations where root is using a directory owned by a regular user. Related: #1211835 Signed-off-by: Jakub Filak --- src/include/dump_dir.h | 2 ++ src/lib/dump_dir.c | 39 ++++++++++++++++++++++++++++++++------- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/include/dump_dir.h b/src/include/dump_dir.h index 124511e..71cf66f 100644 --- a/src/include/dump_dir.h +++ b/src/include/dump_dir.h @@ -60,6 +60,8 @@ struct dump_dir { void dd_close(struct dump_dir *dd); struct dump_dir *dd_opendir(const char *dir, int flags); +struct dump_dir *dd_create_skeleton(const char *dir, uid_t uid, mode_t mode); +int dd_reset_ownership(struct dump_dir *dd); /* Pass uid = (uid_t)-1L to disable chown'ing of newly created files * (IOW: if you aren't running under root): */ diff --git a/src/lib/dump_dir.c b/src/lib/dump_dir.c index 28439af..fabad0b 100644 --- a/src/lib/dump_dir.c +++ b/src/lib/dump_dir.c @@ -455,7 +455,10 @@ struct dump_dir *dd_opendir(const char *dir, int flags) return dd; } -/* Create a fresh empty debug dump dir. +/* Create a fresh empty debug dump dir which is owned bu the calling user. If + * you want to create the directory with meaningful ownership you should + * consider using dd_create() function or you can modify the ownership + * afterwards by calling dd_reset_ownership() function. * * ABRT owns dump dir: * We should not allow users to write new files or write into existing ones, @@ -511,7 +514,7 @@ struct dump_dir *dd_opendir(const char *dir, int flags) * this runs under 0:0 * - clients: setroubleshootd, abrt python */ -struct dump_dir *dd_create(const char *dir, uid_t uid, mode_t mode) +struct dump_dir *dd_create_skeleton(const char *dir, uid_t uid, mode_t mode) { /* a little trick to copy read bits from file mode to exec bit of dir mode*/ mode_t dir_mode = mode | ((mode & 0444) >> 2); @@ -601,13 +604,35 @@ struct dump_dir *dd_create(const char *dir, uid_t uid, mode_t mode) else error_msg("User %lu does not exist, using gid 0", (long)uid); #endif + } - if (lchown(dir, dd->dd_uid, dd->dd_gid) == -1) - { - perror_msg("Can't change '%s' ownership to %lu:%lu", dir, - (long)dd->dd_uid, (long)dd->dd_gid); - } + return dd; +} + +/* Resets ownership of the given directory to UID and GID according to values + * in dd_create_skeleton(). + */ +int dd_reset_ownership(struct dump_dir *dd) +{ + const int r =lchown(dd->dd_dirname, dd->dd_uid, dd->dd_gid); + if (r < 0) + { + perror_msg("Can't change '%s' ownership to %lu:%lu", dd->dd_dirname, + (long)dd->dd_uid, (long)dd->dd_gid); } + return r; +} + +/* Calls dd_create_skeleton() and dd_reset_ownership(). + */ +struct dump_dir *dd_create(const char *dir, uid_t uid, mode_t mode) +{ + struct dump_dir *dd = dd_create_skeleton(dir, uid, mode); + if (dd == NULL) + return NULL; + + /* ignore results */ + dd_reset_ownership(dd); return dd; } -- 1.8.3.1