return &pakfire->subgid;
}
+/*
+ Maps any UID/GIDs to the SUBUID/SUBGIDs so that we can transparently
+ copy files in and out of the jail environment.
+*/
+static unsigned int pakfire_map_id(struct pakfire* pakfire,
+ const struct pakfire_subid* subid, const unsigned int id) {
+ // Nothing to do if we are running on root
+ if (pakfire_on_root(pakfire))
+ return id;
+
+ // Map the ID
+ unsigned int mapped_id = subid->id + id;
+
+ // Check if the ID is in range
+ if (id > subid->length) {
+ ERROR(pakfire, "Mapped ID is out of range. Setting to %u\n", subid->id);
+ mapped_id = subid->id;
+ }
+
+ DEBUG(pakfire, "Mapping UID/GID %u to %u\n", id, mapped_id);
+
+ return mapped_id;
+}
+
+static unsigned int pakfire_unmap_id(struct pakfire* pakfire,
+ const struct pakfire_subid* subid, const unsigned int id) {
+ // Nothing to do if we are running on root
+ if (pakfire_on_root(pakfire))
+ return id;
+
+ // Unmap the ID
+ int unmapped_id = id - subid->id;
+
+ // Check if the ID is in range
+ if (unmapped_id < 0) {
+ ERROR(pakfire, "Mapped ID is out of range. Setting to %d\n", subid->id);
+ unmapped_id = subid->id;
+ }
+
+ DEBUG(pakfire, "Mapping UID/GID %d from %d\n", unmapped_id, id);
+
+ return unmapped_id;
+}
+
static int log_priority(const char* priority) {
char* end;
static const char* pakfire_user_lookup(void* data, la_int64_t uid) {
struct pakfire* pakfire = (struct pakfire*)data;
+ DEBUG(pakfire, "Looking up name for UID %ld\n", uid);
+
+ // Unmap the UID first
+ uid = pakfire_unmap_id(pakfire, &pakfire->subuid, uid);
+
// Fast path for "root"
if (uid == 0)
return "root";
static const char* pakfire_group_lookup(void* data, la_int64_t gid) {
struct pakfire* pakfire = (struct pakfire*)data;
+ DEBUG(pakfire, "Looking up name for GID %ld\n", gid);
+
+ // Unmap the GID first
+ gid = pakfire_unmap_id(pakfire, &pakfire->subgid, gid);
+
// Fast path for "root"
if (gid == 0)
return "root";
static la_int64_t pakfire_uid_lookup(void* data, const char* name, la_int64_t uid) {
struct pakfire* pakfire = (struct pakfire*)data;
+ DEBUG(pakfire, "Looking up UID for '%s' (%ld)\n", name, uid);
+
// Fast path for "root"
if (strcmp(name, "root") == 0)
- return 0;
+ return pakfire_map_id(pakfire, &pakfire->subuid, 0);
// Find a matching entry in /etc/passwd
struct passwd* entry = pakfire_getpwnam(pakfire, name);
if (!entry) {
ERROR(pakfire, "Could not retrieve UID for '%s': %m\n", name);
- return 0;
+ return pakfire_map_id(pakfire, &pakfire->subuid, 0);
}
DEBUG(pakfire, "Mapping %s to UID %d\n", name, entry->pw_uid);
- return entry->pw_uid;
+ return pakfire_map_id(pakfire, &pakfire->subuid, entry->pw_uid);
}
-static la_int64_t pakfire_gid_lookup(void* data, const char* name, la_int64_t uid) {
+static la_int64_t pakfire_gid_lookup(void* data, const char* name, la_int64_t gid) {
struct pakfire* pakfire = (struct pakfire*)data;
+ DEBUG(pakfire, "Looking up GID for '%s' (%ld)\n", name, gid);
+
// Fast path for "root"
if (strcmp(name, "root") == 0)
- return 0;
+ return pakfire_map_id(pakfire, &pakfire->subgid, 0);
// Find a matching entry in /etc/group
struct group* entry = pakfire_getgrnam(pakfire, name);
if (!entry) {
ERROR(pakfire, "Could not retrieve GID for '%s': %m\n", name);
- return 0;
+ return pakfire_map_id(pakfire, &pakfire->subgid, 0);
}
DEBUG(pakfire, "Mapping %s to GID %d\n", name, entry->gr_gid);
- return entry->gr_gid;
+ return pakfire_map_id(pakfire, &pakfire->subgid, entry->gr_gid);
}
struct archive* pakfire_make_archive_disk_writer(struct pakfire* pakfire, int internal) {