From 37e9fe0b866afeed0fb5afc3212808211d8f874f Mon Sep 17 00:00:00 2001 From: Stephen Seo Date: Fri, 10 Jan 2025 16:44:31 +0900 Subject: [PATCH] Impl extract UID/GID remapping format ver 1 & 2 --- src/archiver.c | 171 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 169 insertions(+), 2 deletions(-) diff --git a/src/archiver.c b/src/archiver.c index 4fbbdea..e182cbd 100644 --- a/src/archiver.c +++ b/src/archiver.c @@ -6760,7 +6760,51 @@ int simple_archiver_parse_archive_version_1(FILE *in_f, int_fast8_t do_extract, if (state && (state->parsed->flags & 0x400)) { file_info->uid = state->parsed->uid; } else { - file_info->uid = u32; + if (state) { + const char *mapped_uid_user = simple_archiver_hash_map_get( + state->parsed->users_infos.UidToUname, &u32, sizeof(uint32_t)); + uint32_t remapped_uid; + if (state->parsed->flags & 0x4000) { + // Prefer UID first. + if (simple_archiver_get_uid_mapping(state->parsed->mappings, + state->parsed->users_infos, + u32, + &remapped_uid, + NULL) == 0) { + file_info->uid = remapped_uid; + } else if (mapped_uid_user + && simple_archiver_get_user_mapping(state->parsed->mappings, + state->parsed->users_infos, + mapped_uid_user, + &remapped_uid, + NULL) == 0) { + file_info->uid = remapped_uid; + } else { + file_info->uid = u32; + } + } else { + // Prefer Username first. + if (mapped_uid_user + && simple_archiver_get_user_mapping(state->parsed->mappings, + state->parsed->users_infos, + mapped_uid_user, + &remapped_uid, + NULL) == 0) { + file_info->uid = remapped_uid; + } else if (simple_archiver_get_uid_mapping( + state->parsed->mappings, + state->parsed->users_infos, + u32, + &remapped_uid, + NULL) == 0) { + file_info->uid = remapped_uid; + } else { + file_info->uid = u32; + } + } + } else { + file_info->uid = u32; + } } if (fread(buf, 1, 4, in_f) != 4) { @@ -6771,7 +6815,52 @@ int simple_archiver_parse_archive_version_1(FILE *in_f, int_fast8_t do_extract, if (state && (state->parsed->flags & 0x800)) { file_info->gid = state->parsed->gid; } else { - file_info->gid = u32; + if (state) { + // Check remappings. + const char *mapped_gid_group = simple_archiver_hash_map_get( + state->parsed->users_infos.GidToGname, &u32, sizeof(uint32_t)); + uint32_t remapped_gid; + if (state->parsed->flags & 0x8000) { + // Prefer GID first. + if (simple_archiver_get_gid_mapping(state->parsed->mappings, + state->parsed->users_infos, + u32, + &remapped_gid, + NULL) == 0) { + file_info->gid = remapped_gid; + } else if (mapped_gid_group + && simple_archiver_get_group_mapping(state->parsed->mappings, + state->parsed->users_infos, + mapped_gid_group, + &remapped_gid, + NULL) == 0) { + file_info->gid = remapped_gid; + } else { + file_info->gid = u32; + } + } else { + // Prefer Group first. + if (mapped_gid_group + && simple_archiver_get_group_mapping(state->parsed->mappings, + state->parsed->users_infos, + mapped_gid_group, + &remapped_gid, + NULL) == 0) { + file_info->gid = remapped_gid; + } else if (simple_archiver_get_gid_mapping( + state->parsed->mappings, + state->parsed->users_infos, + u32, + &remapped_gid, + NULL) == 0) { + file_info->gid = remapped_gid; + } else { + file_info->gid = u32; + } + } + } else { + file_info->gid = u32; + } } if (fread(buf, 1, 8, in_f) != 8) { @@ -7258,6 +7347,84 @@ int simple_archiver_parse_archive_version_2(FILE *in_f, int_fast8_t do_extract, gid); } + if (state) { + // Check uid remapping. + const char *mapped_uid_user = simple_archiver_hash_map_get( + state->parsed->users_infos.UidToUname, &uid, sizeof(uint32_t)); + uint32_t remapped_uid; + if (state->parsed->flags & 0x4000) { + // Prefer UID first. + if (simple_archiver_get_uid_mapping(state->parsed->mappings, + state->parsed->users_infos, + uid, + &remapped_uid, + NULL) == 0) { + uid = remapped_uid; + } else if (mapped_uid_user + && simple_archiver_get_user_mapping(state->parsed->mappings, + state->parsed->users_infos, + mapped_uid_user, + &remapped_uid, + NULL) == 0) { + uid = remapped_uid; + } + } else { + // Prefer Username first. + if (mapped_uid_user + && simple_archiver_get_user_mapping(state->parsed->mappings, + state->parsed->users_infos, + mapped_uid_user, + &remapped_uid, + NULL) == 0) { + uid = remapped_uid; + } else if (simple_archiver_get_uid_mapping(state->parsed->mappings, + state->parsed->users_infos, + uid, + &remapped_uid, + NULL) == 0) { + uid = remapped_uid; + } + } + + // Check GID remapping. + const char *mapped_gid_group = simple_archiver_hash_map_get( + state->parsed->users_infos.GidToGname, &gid, sizeof(uint32_t)); + uint32_t remapped_gid; + if (state->parsed->flags & 0x8000) { + // Prefer GID first. + if (simple_archiver_get_gid_mapping(state->parsed->mappings, + state->parsed->users_infos, + gid, + &remapped_gid, + NULL) == 0) { + gid = remapped_gid; + } else if (mapped_gid_group + && simple_archiver_get_group_mapping(state->parsed->mappings, + state->parsed->users_infos, + mapped_gid_group, + &remapped_gid, + NULL) == 0) { + gid = remapped_gid; + } + } else { + // Prefer Group first. + if (mapped_gid_group + && simple_archiver_get_group_mapping(state->parsed->mappings, + state->parsed->users_infos, + mapped_gid_group, + &remapped_gid, + NULL) == 0) { + gid = remapped_gid; + } else if (simple_archiver_get_gid_mapping(state->parsed->mappings, + state->parsed->users_infos, + gid, + &remapped_gid, + NULL) == 0) { + gid = remapped_gid; + } + } + } + __attribute__((cleanup(simple_archiver_helper_cleanup_c_string))) char *abs_path_dir = realpath(".", NULL); if (!abs_path_dir) { -- 2.49.0