|
|
3a204fb |
From ad27acbb2104d4172a33dd82ef9d94c8f5dba617 Mon Sep 17 00:00:00 2001
|
|
|
3a204fb |
From: Jakub Filak <jfilak@redhat.com>
|
|
|
3a204fb |
Date: Thu, 28 May 2015 11:47:39 +0200
|
|
|
3a204fb |
Subject: [PATCH] dd: add owner to meta-data
|
|
|
3a204fb |
|
|
|
3a204fb |
Use 'nobody' user to mark dump directories which have no owner and are
|
|
|
3a204fb |
publicly readable and chownable. The 'nobody' should not be used
|
|
|
3a204fb |
directly but through the function set_no_owner() which is a substitution
|
|
|
3a204fb |
for adding S_IROTH (man 2 open) to dump dir mode.
|
|
|
3a204fb |
|
|
|
3a204fb |
Use meta-data to get the owner only if the dump directory is owned by
|
|
|
3a204fb |
super-user, because it is the only state when we can trust that value.
|
|
|
3a204fb |
|
|
|
3a204fb |
Related: #354
|
|
|
3a204fb |
|
|
|
3a204fb |
Signed-off-by: Jakub Filak <jfilak@redhat.com>
|
|
|
3a204fb |
---
|
|
|
3a204fb |
src/include/dump_dir.h | 21 ++++++
|
|
|
3a204fb |
src/lib/dump_dir.c | 195 ++++++++++++++++++++++++++++++++++++++++++++++++-
|
|
|
3a204fb |
tests/dump_dir.at | 110 ++++++++++++++++++++++++++++
|
|
|
3a204fb |
3 files changed, 322 insertions(+), 4 deletions(-)
|
|
|
3a204fb |
|
|
|
3a204fb |
diff --git a/src/include/dump_dir.h b/src/include/dump_dir.h
|
|
|
3a204fb |
index f33eb99..b37b262 100644
|
|
|
3a204fb |
--- a/src/include/dump_dir.h
|
|
|
3a204fb |
+++ b/src/include/dump_dir.h
|
|
|
3a204fb |
@@ -141,6 +141,26 @@ int dd_rename(struct dump_dir *dd, const char *new_path);
|
|
|
3a204fb |
*/
|
|
|
3a204fb |
int dd_chown(struct dump_dir *dd, uid_t new_uid);
|
|
|
3a204fb |
|
|
|
3a204fb |
+/* Sets a new owner (does NOT chown the directory)
|
|
|
3a204fb |
+ *
|
|
|
3a204fb |
+ * Does not validate the passed uid.
|
|
|
3a204fb |
+ * The given dump_dir must be opened for writing.
|
|
|
3a204fb |
+ */
|
|
|
3a204fb |
+int dd_set_owner(struct dump_dir *dd, uid_t owner);
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+/* Makes the dump directory owned by nobody.
|
|
|
3a204fb |
+ *
|
|
|
3a204fb |
+ * The directory will be accessible for all users.
|
|
|
3a204fb |
+ * The given dump_dir must be opened for writing.
|
|
|
3a204fb |
+ */
|
|
|
3a204fb |
+int dd_set_no_owner(struct dump_dir *dd);
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+/* Gets the owner
|
|
|
3a204fb |
+ *
|
|
|
3a204fb |
+ * If meta-data misses owner, returns fs owner.
|
|
|
3a204fb |
+ * Can be used with DD_OPEN_FD_ONLY.
|
|
|
3a204fb |
+ */
|
|
|
3a204fb |
+uid_t dd_get_owner(struct dump_dir *dd);
|
|
|
3a204fb |
|
|
|
3a204fb |
/* reported_to handling */
|
|
|
3a204fb |
#define add_reported_to_data libreport_add_reported_to_data
|
|
|
3a204fb |
@@ -187,6 +207,7 @@ int dd_accessible_by_uid(struct dump_dir *dd, uid_t uid);
|
|
|
3a204fb |
enum {
|
|
|
3a204fb |
DD_STAT_ACCESSIBLE_BY_UID = 1,
|
|
|
3a204fb |
DD_STAT_OWNED_BY_UID = DD_STAT_ACCESSIBLE_BY_UID << 1,
|
|
|
3a204fb |
+ DD_STAT_NO_OWNER = DD_STAT_OWNED_BY_UID << 1,
|
|
|
3a204fb |
};
|
|
|
3a204fb |
|
|
|
3a204fb |
/* Gets information about a dump directory for particular uid.
|
|
|
3a204fb |
diff --git a/src/lib/dump_dir.c b/src/lib/dump_dir.c
|
|
|
3a204fb |
index 9ba2352..2cd14bb 100644
|
|
|
3a204fb |
--- a/src/lib/dump_dir.c
|
|
|
3a204fb |
+++ b/src/lib/dump_dir.c
|
|
|
3a204fb |
@@ -88,6 +88,7 @@
|
|
|
3a204fb |
// parent dump directory. It is not a fatal error, if the meta-data directory
|
|
|
3a204fb |
// does not exist (backward compatibility).
|
|
|
3a204fb |
#define META_DATA_DIR_NAME ".libreport"
|
|
|
3a204fb |
+#define META_DATA_FILE_OWNER "owner"
|
|
|
3a204fb |
|
|
|
3a204fb |
enum {
|
|
|
3a204fb |
/* Try to create meta-data dir if it does not exist */
|
|
|
3a204fb |
@@ -106,6 +107,8 @@ static char *load_text_file(const char *path, unsigned flags);
|
|
|
3a204fb |
static char *load_text_file_at(int dir_fd, const char *name, unsigned flags);
|
|
|
3a204fb |
static void copy_file_from_chroot(struct dump_dir* dd, const char *name,
|
|
|
3a204fb |
const char *chroot_dir, const char *file_path);
|
|
|
3a204fb |
+static bool save_binary_file_at(int dir_fd, const char *name, const char* data,
|
|
|
3a204fb |
+ unsigned size, uid_t uid, gid_t gid, mode_t mode);
|
|
|
3a204fb |
|
|
|
3a204fb |
static bool isdigit_str(const char *str)
|
|
|
3a204fb |
{
|
|
|
3a204fb |
@@ -136,6 +139,22 @@ static bool exist_file_dir_at(int dir_fd, const char *name)
|
|
|
3a204fb |
#define dd_validate_element_name(name) \
|
|
|
3a204fb |
(str_is_correct_filename(name) && (strcmp(META_DATA_DIR_NAME, name) != 0))
|
|
|
3a204fb |
|
|
|
3a204fb |
+/* nobody user should not own any file */
|
|
|
3a204fb |
+static int get_no_owner_uid(uid_t *uid)
|
|
|
3a204fb |
+{
|
|
|
3a204fb |
+ struct passwd *pw = getpwnam("nobody");
|
|
|
3a204fb |
+ if (pw == NULL)
|
|
|
3a204fb |
+ {
|
|
|
3a204fb |
+ perror_msg("can't get nobody's uid");
|
|
|
3a204fb |
+ if (errno == 0)
|
|
|
3a204fb |
+ return -ENOENT;
|
|
|
3a204fb |
+ return -errno;
|
|
|
3a204fb |
+ }
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ *uid = pw->pw_uid;
|
|
|
3a204fb |
+ return 0;
|
|
|
3a204fb |
+}
|
|
|
3a204fb |
+
|
|
|
3a204fb |
/* Opens the file in the three following steps:
|
|
|
3a204fb |
* 1. open the file with O_PATH (get a file descriptor for operations with
|
|
|
3a204fb |
* inode) and O_NOFOLLOW (do not dereference symbolick links)
|
|
|
3a204fb |
@@ -611,6 +630,113 @@ static int dd_get_meta_data_dir_fd(struct dump_dir *dd, int flags)
|
|
|
3a204fb |
return dd->dd_md_fd;
|
|
|
3a204fb |
}
|
|
|
3a204fb |
|
|
|
3a204fb |
+/* Tries to safely overwrite the existing file.
|
|
|
3a204fb |
+ *
|
|
|
3a204fb |
+ * The functions writes the new value to a temporary file and if the temporary
|
|
|
3a204fb |
+ * file is successfully created, then moves the tmp file to the old file name.
|
|
|
3a204fb |
+ *
|
|
|
3a204fb |
+ * If the meta-data directory does not exist, the function will try to create
|
|
|
3a204fb |
+ * it.
|
|
|
3a204fb |
+ */
|
|
|
3a204fb |
+static int dd_meta_data_save_text(struct dump_dir *dd, const char *name, const char *data)
|
|
|
3a204fb |
+{
|
|
|
3a204fb |
+ if (!dd->locked)
|
|
|
3a204fb |
+ error_msg_and_die("dump_dir is not opened"); /* bug */
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ if (!str_is_correct_filename(name))
|
|
|
3a204fb |
+ error_msg_and_die("Cannot save meta-data. '%s' is not a valid file name", name);
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ int dd_md_fd = dd_get_meta_data_dir_fd(dd, DD_MD_GET_CREATE);
|
|
|
3a204fb |
+ if (dd_md_fd < 0)
|
|
|
3a204fb |
+ {
|
|
|
3a204fb |
+ error_msg("Can't save meta-data: '%s'", name);
|
|
|
3a204fb |
+ return dd_md_fd;
|
|
|
3a204fb |
+ }
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ char *tmp_name = xasprintf("~%s.tmp", name);
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ int ret = -1;
|
|
|
3a204fb |
+ if (!save_binary_file_at(dd_md_fd, tmp_name, data, strlen(data), dd->dd_uid, dd->dd_gid, dd->mode))
|
|
|
3a204fb |
+ goto finito;
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ /* man 2 rename
|
|
|
3a204fb |
+ *
|
|
|
3a204fb |
+ * If newpath already exists it will be atomically replaced (subject to a
|
|
|
3a204fb |
+ * few conditions; see ERRORS below), so that there is no point at which
|
|
|
3a204fb |
+ * another process attempting to access newpath will find it missing.
|
|
|
3a204fb |
+ */
|
|
|
3a204fb |
+ if (renameat(dd_md_fd, tmp_name, dd_md_fd, name))
|
|
|
3a204fb |
+ {
|
|
|
3a204fb |
+ ret = -errno;
|
|
|
3a204fb |
+ perror_msg("Failed to move temporary file '%s' to '%s'", tmp_name, name);
|
|
|
3a204fb |
+ goto finito;
|
|
|
3a204fb |
+ }
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ ret = 0;
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+finito:
|
|
|
3a204fb |
+ free(tmp_name);
|
|
|
3a204fb |
+ return ret;
|
|
|
3a204fb |
+}
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+int dd_set_owner(struct dump_dir *dd, uid_t owner)
|
|
|
3a204fb |
+{
|
|
|
3a204fb |
+ /* I was tempted to use the keyword static, but we should have reentracy
|
|
|
3a204fb |
+ * always on mind. Who knows! */
|
|
|
3a204fb |
+ char long_str[sizeof(long) * 3 + 2];
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ if (owner == (uid_t)-1)
|
|
|
3a204fb |
+ {
|
|
|
3a204fb |
+ owner = getuid();
|
|
|
3a204fb |
+ if (owner < 0)
|
|
|
3a204fb |
+ perror_msg_and_die("%s: getuid", __func__);
|
|
|
3a204fb |
+ }
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ snprintf(long_str, sizeof(long_str), "%li", (long)owner);
|
|
|
3a204fb |
+ const int ret = dd_meta_data_save_text(dd, META_DATA_FILE_OWNER, long_str);
|
|
|
3a204fb |
+ if (ret < 0)
|
|
|
3a204fb |
+ error_msg("The dump dir owner wasn't set to '%s'", long_str);
|
|
|
3a204fb |
+ return ret;
|
|
|
3a204fb |
+}
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+int dd_set_no_owner(struct dump_dir *dd)
|
|
|
3a204fb |
+{
|
|
|
3a204fb |
+ uid_t no_owner_uid = (uid_t)-1;
|
|
|
3a204fb |
+ int ret = get_no_owner_uid(&no_owner_uid);
|
|
|
3a204fb |
+ if (ret < 0)
|
|
|
3a204fb |
+ return ret;
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ return dd_set_owner(dd, no_owner_uid);
|
|
|
3a204fb |
+}
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+uid_t dd_get_owner(struct dump_dir *dd)
|
|
|
3a204fb |
+{
|
|
|
3a204fb |
+ static const long long MAX_UID_T = (1ULL << (sizeof(uid_t)*8 - 1)) - 1;
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ int dd_md_fd = dd_get_meta_data_dir_fd(dd, /*no create*/0);
|
|
|
3a204fb |
+ if (dd_md_fd < 0)
|
|
|
3a204fb |
+ {
|
|
|
3a204fb |
+ log_info("No meta-data, using fs owner.");
|
|
|
3a204fb |
+ return dd->dd_uid;
|
|
|
3a204fb |
+ }
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ long long owner = -1;
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ int ret = read_number_from_file_at(dd_md_fd, META_DATA_FILE_OWNER, "UID",
|
|
|
3a204fb |
+ sizeof(uid_t), MAX_UID_T, -1, &owner);
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ if (ret < 0)
|
|
|
3a204fb |
+ {
|
|
|
3a204fb |
+ if (ret != -ENOENT)
|
|
|
3a204fb |
+ return ret;
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ log_info("No meta-data 'owner', using fs owner.");
|
|
|
3a204fb |
+ return dd->dd_uid;
|
|
|
3a204fb |
+ }
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ return (uid_t)owner;
|
|
|
3a204fb |
+}
|
|
|
3a204fb |
+
|
|
|
3a204fb |
/* A helper function useful for traversing directories.
|
|
|
3a204fb |
*
|
|
|
3a204fb |
* DIR* d opendir(dir_fd); ... closedir(d); closes also dir_fd but we want to
|
|
|
3a204fb |
@@ -1026,6 +1152,12 @@ struct dump_dir *dd_create_skeleton(const char *dir, uid_t uid, mode_t mode, int
|
|
|
3a204fb |
goto fail;
|
|
|
3a204fb |
}
|
|
|
3a204fb |
|
|
|
3a204fb |
+ if (dd_set_owner(dd, dd->dd_uid) < 0)
|
|
|
3a204fb |
+ {
|
|
|
3a204fb |
+ log_debug("Failed to initialized 'owner'");
|
|
|
3a204fb |
+ goto fail;
|
|
|
3a204fb |
+ }
|
|
|
3a204fb |
+
|
|
|
3a204fb |
if (uid != (uid_t)-1L)
|
|
|
3a204fb |
{
|
|
|
3a204fb |
dd->dd_uid = 0;
|
|
|
3a204fb |
@@ -1087,6 +1219,11 @@ int dd_reset_ownership(struct dump_dir *dd)
|
|
|
3a204fb |
if (dd_chown_meta_data(dd, dd->dd_uid, dd->dd_gid) != 0)
|
|
|
3a204fb |
error_msg("Failed to reset ownership of meta-data");
|
|
|
3a204fb |
|
|
|
3a204fb |
+ /* We ignore failures above, so we will ignore failures here too.
|
|
|
3a204fb |
+ * The meta-data owner already exist (created by dd_create_skeleton).
|
|
|
3a204fb |
+ */
|
|
|
3a204fb |
+ dd_set_owner(dd, dd->dd_uid);
|
|
|
3a204fb |
+
|
|
|
3a204fb |
return r;
|
|
|
3a204fb |
}
|
|
|
3a204fb |
|
|
|
3a204fb |
@@ -1122,8 +1259,14 @@ void dd_create_basic_files(struct dump_dir *dd, uid_t uid, const char *chroot_di
|
|
|
3a204fb |
free(time_str);
|
|
|
3a204fb |
|
|
|
3a204fb |
/* it doesn't make sense to create the uid file if uid == -1 */
|
|
|
3a204fb |
+ /* and 'owner' is set since dd_create_skeleton */
|
|
|
3a204fb |
if (uid != (uid_t)-1L)
|
|
|
3a204fb |
{
|
|
|
3a204fb |
+ /* Failure is not a problem here, because we still have the fs
|
|
|
3a204fb |
+ * attributes and there is only a little chance that the old value
|
|
|
3a204fb |
+ * gets lost. */
|
|
|
3a204fb |
+ dd_set_owner(dd, uid);
|
|
|
3a204fb |
+
|
|
|
3a204fb |
snprintf(long_str, sizeof(long_str), "%li", (long)uid);
|
|
|
3a204fb |
dd_save_text(dd, FILENAME_UID, long_str);
|
|
|
3a204fb |
}
|
|
|
3a204fb |
@@ -1436,6 +1579,9 @@ next:
|
|
|
3a204fb |
dd->dd_gid = groups_gid;
|
|
|
3a204fb |
}
|
|
|
3a204fb |
|
|
|
3a204fb |
+ if (chown_res == 0)
|
|
|
3a204fb |
+ chown_res = dd_set_owner(dd, (long)dd->dd_uid);
|
|
|
3a204fb |
+
|
|
|
3a204fb |
return chown_res;
|
|
|
3a204fb |
}
|
|
|
3a204fb |
|
|
|
3a204fb |
@@ -1812,7 +1958,45 @@ static bool uid_in_group(uid_t uid, gid_t gid)
|
|
|
3a204fb |
int dd_stat_for_uid(struct dump_dir *dd, uid_t uid)
|
|
|
3a204fb |
{
|
|
|
3a204fb |
int ddstat = 0;
|
|
|
3a204fb |
- if (uid == 0 || (dd->mode & S_IROTH))
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ if (uid == 0)
|
|
|
3a204fb |
+ {
|
|
|
3a204fb |
+ log_debug("directory accessible by super-user");
|
|
|
3a204fb |
+ ddstat |= DD_STAT_ACCESSIBLE_BY_UID;
|
|
|
3a204fb |
+ }
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+#define DD_OWNER_FLAGS (DD_STAT_ACCESSIBLE_BY_UID | DD_STAT_OWNED_BY_UID)
|
|
|
3a204fb |
+ if (dd->dd_uid == 0)
|
|
|
3a204fb |
+ {
|
|
|
3a204fb |
+ log_debug("directory owned by super-user: checking meta-data");
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ const uid_t owner = dd_get_owner(dd);
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ if (owner < 0)
|
|
|
3a204fb |
+ goto fsattributes;
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ if (owner == uid)
|
|
|
3a204fb |
+ {
|
|
|
3a204fb |
+ log_debug("meta-data: %ld uid owns directory", (long)uid);
|
|
|
3a204fb |
+ ddstat |= DD_OWNER_FLAGS;
|
|
|
3a204fb |
+ goto finito;
|
|
|
3a204fb |
+ }
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ uid_t no_owner_uid = (uid_t)-1;
|
|
|
3a204fb |
+ int ret = get_no_owner_uid(&no_owner_uid);
|
|
|
3a204fb |
+ if ( ret >= 0
|
|
|
3a204fb |
+ && owner == no_owner_uid)
|
|
|
3a204fb |
+ {
|
|
|
3a204fb |
+ log_debug("meta-data: directory is accessible by %ld uid", (long)uid);
|
|
|
3a204fb |
+ ddstat |= DD_STAT_ACCESSIBLE_BY_UID;
|
|
|
3a204fb |
+ ddstat |= DD_STAT_NO_OWNER;
|
|
|
3a204fb |
+ }
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ goto finito;
|
|
|
3a204fb |
+ }
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+fsattributes:
|
|
|
3a204fb |
+ if (dd->mode & S_IROTH)
|
|
|
3a204fb |
{
|
|
|
3a204fb |
log_debug("directory is accessible by %ld uid", (long)uid);
|
|
|
3a204fb |
ddstat |= DD_STAT_ACCESSIBLE_BY_UID;
|
|
|
3a204fb |
@@ -1824,11 +2008,14 @@ int dd_stat_for_uid(struct dump_dir *dd, uid_t uid)
|
|
|
3a204fb |
if (uid_in_group(uid, dd->dd_gid))
|
|
|
3a204fb |
#endif
|
|
|
3a204fb |
{
|
|
|
3a204fb |
- log_debug("%ld uid owns directory", (long)uid);
|
|
|
3a204fb |
- ddstat |= DD_STAT_ACCESSIBLE_BY_UID;
|
|
|
3a204fb |
- ddstat |= DD_STAT_OWNED_BY_UID;
|
|
|
3a204fb |
+ log_debug("fs attributes: %ld uid owns directory", (long)uid);
|
|
|
3a204fb |
+ ddstat |= DD_OWNER_FLAGS;
|
|
|
3a204fb |
}
|
|
|
3a204fb |
|
|
|
3a204fb |
+#undef DD_OWNER_FLAGS
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+finito:
|
|
|
3a204fb |
+ log_debug("UID=%d, %s: %o", uid, dd->dd_dirname, ddstat);
|
|
|
3a204fb |
return ddstat;
|
|
|
3a204fb |
}
|
|
|
3a204fb |
|
|
|
3a204fb |
diff --git a/tests/dump_dir.at b/tests/dump_dir.at
|
|
|
3a204fb |
index 4bf479e..cc0148c 100644
|
|
|
3a204fb |
--- a/tests/dump_dir.at
|
|
|
3a204fb |
+++ b/tests/dump_dir.at
|
|
|
3a204fb |
@@ -203,6 +203,11 @@ int main(int argc, char **argv)
|
|
|
3a204fb |
assert(fstatat(dd->dd_fd, ".libreport", &path_md_st, 0) == 0);
|
|
|
3a204fb |
assert(md_st.st_ino = path_md_st.st_ino);
|
|
|
3a204fb |
|
|
|
3a204fb |
+ struct stat owner_md_st;
|
|
|
3a204fb |
+ assert(fstatat(dd->dd_md_fd, "owner", &owner_md_st, 0) == 0);
|
|
|
3a204fb |
+ assert((dd_st.st_mode & 0666) == (owner_md_st.st_mode & 0666));
|
|
|
3a204fb |
+ assert(geteuid() == dd_get_owner(dd));
|
|
|
3a204fb |
+
|
|
|
3a204fb |
dd_create_basic_files(dd, (uid_t)-1, NULL);
|
|
|
3a204fb |
dd_save_text(dd, FILENAME_TYPE, "attest");
|
|
|
3a204fb |
|
|
|
3a204fb |
@@ -329,6 +334,111 @@ int main(int argc, char **argv)
|
|
|
3a204fb |
}
|
|
|
3a204fb |
]])
|
|
|
3a204fb |
|
|
|
3a204fb |
+## -------- ##
|
|
|
3a204fb |
+## dd_owner ##
|
|
|
3a204fb |
+## -------- ##
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+AT_TESTFUN([dd_owner],
|
|
|
3a204fb |
+[[
|
|
|
3a204fb |
+#include "internal_libreport.h"
|
|
|
3a204fb |
+#include <errno.h>
|
|
|
3a204fb |
+#include <assert.h>
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+int main(int argc, char **argv)
|
|
|
3a204fb |
+{
|
|
|
3a204fb |
+ g_verbose = 3;
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ char template[] = "/tmp/XXXXXX/dump_dir";
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ char *last_slash = strrchr(template, '/');
|
|
|
3a204fb |
+ *last_slash = '\0';
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ if (mkdtemp(template) == NULL) {
|
|
|
3a204fb |
+ perror("mkdtemp()");
|
|
|
3a204fb |
+ return EXIT_FAILURE;
|
|
|
3a204fb |
+ }
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ *last_slash = '/';
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ printf("Dump dir path: %s\n", template);
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ {
|
|
|
3a204fb |
+ fprintf(stderr, "TEST === default owner\n");
|
|
|
3a204fb |
+ struct dump_dir *dd = dd_create(template, (uid_t)-1, 0640);
|
|
|
3a204fb |
+ assert(dd != NULL);
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ assert(geteuid() == dd_get_owner(dd));
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ assert(dd_delete(dd) == 0);
|
|
|
3a204fb |
+ }
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ {
|
|
|
3a204fb |
+ fprintf(stderr, "TEST === create basic files w/o UID\n");
|
|
|
3a204fb |
+ struct dump_dir *dd = dd_create(template, (uid_t)-1, 0640);
|
|
|
3a204fb |
+ assert(dd != NULL);
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ dd_create_basic_files(dd, (uid_t)-1, NULL);
|
|
|
3a204fb |
+ assert(geteuid() == dd_get_owner(dd));
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ assert(dd_delete(dd) == 0);
|
|
|
3a204fb |
+ }
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ {
|
|
|
3a204fb |
+ fprintf(stderr, "TEST === create basic files with UID\n");
|
|
|
3a204fb |
+ struct dump_dir *dd = dd_create(template, (uid_t)-1, 0640);
|
|
|
3a204fb |
+ assert(dd != NULL);
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ dd_create_basic_files(dd, (geteuid() + 1), NULL);
|
|
|
3a204fb |
+ assert((geteuid() + 1) == dd_get_owner(dd));
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ assert(dd_delete(dd) == 0);
|
|
|
3a204fb |
+ }
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ {
|
|
|
3a204fb |
+ fprintf(stderr, "TEST === set no owner\n");
|
|
|
3a204fb |
+ struct dump_dir *dd = dd_create(template, (uid_t)-1, 0640);
|
|
|
3a204fb |
+ assert(dd != NULL);
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ dd_set_no_owner(dd);
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ struct passwd *nobody_pw= getpwnam("nobody");
|
|
|
3a204fb |
+ assert(nobody_pw != NULL);
|
|
|
3a204fb |
+ assert(nobody_pw->pw_uid == dd_get_owner(dd));
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ assert(dd_delete(dd) == 0);
|
|
|
3a204fb |
+ }
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ {
|
|
|
3a204fb |
+ fprintf(stderr, "TEST === set artibrary owner\n");
|
|
|
3a204fb |
+ struct dump_dir *dd = dd_create(template, (uid_t)-1, 0640);
|
|
|
3a204fb |
+ assert(dd != NULL);
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ dd_set_owner(dd, (geteuid() + 2));
|
|
|
3a204fb |
+ assert((geteuid() + 2) == dd_get_owner(dd));
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ assert(dd_delete(dd) == 0);
|
|
|
3a204fb |
+ }
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ {
|
|
|
3a204fb |
+ fprintf(stderr, "TEST === chown no owner\n");
|
|
|
3a204fb |
+ struct dump_dir *dd = dd_create(template, (uid_t)-1, 0640);
|
|
|
3a204fb |
+ assert(dd != NULL);
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ dd_set_no_owner(dd);
|
|
|
3a204fb |
+ assert(geteuid() != dd_get_owner(dd));
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ dd_chown(dd, geteuid());
|
|
|
3a204fb |
+ assert(geteuid() == dd_get_owner(dd));
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ assert(dd_delete(dd) == 0);
|
|
|
3a204fb |
+ }
|
|
|
3a204fb |
+ *last_slash = '\0';
|
|
|
3a204fb |
+ assert(rmdir(template) == 0);
|
|
|
3a204fb |
+
|
|
|
3a204fb |
+ return EXIT_SUCCESS;
|
|
|
3a204fb |
+}
|
|
|
3a204fb |
+]])
|
|
|
3a204fb |
+
|
|
|
3a204fb |
## -------------- ##
|
|
|
3a204fb |
## recursive_lock ##
|
|
|
3a204fb |
## -------------- ##
|
|
|
3a204fb |
--
|
|
|
3a204fb |
2.1.0
|
|
|
3a204fb |
|