[pacman-dev] [WIP 1/4] use custom uid/gid lookup functions

Andrew Gregory andrew.gregory.8 at gmail.com
Sat Mar 19 13:50:14 UTC 2016


---
 lib/libalpm/add.c | 32 +++++++++++++++++++++++++++++++-
 1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c
index f5c9a95..e40ce27 100644
--- a/lib/libalpm/add.c
+++ b/lib/libalpm/add.c
@@ -106,6 +106,31 @@ int SYMEXPORT alpm_add_pkg(alpm_handle_t *handle, alpm_pkg_t *pkg)
 	return 0;
 }
 
+#include <pwd.h>
+static int64_t lookup_uid(UNUSED void *ctx, const char *uname, int64_t uid)
+{
+	struct passwd *ent = getpwnam(uname);
+	if(ent) {
+		return ent->pw_uid; /* uname exists, return assigned uid */
+	} else if((ent = getpwuid(uid))) {
+		return 0; /* uid is assigned to another user, fall back to root */
+	} else {
+		return uid; /* uid is open, package may add user in post_install */
+	}
+}
+#include <grp.h>
+static int64_t lookup_gid(UNUSED void *ctx, const char *gname, int64_t gid)
+{
+	struct group *ent = getgrnam(gname);
+	if(ent) {
+		return ent->gr_gid; /* gname exists, return assigned gid */
+	} else if((ent = getgrgid(gid))) {
+		return 0; /* gid is assigned to another group, fall back to root */
+	} else {
+		return gid; /* gid is open, package may add group in post_install */
+	}
+}
+
 static int perform_extraction(alpm_handle_t *handle, struct archive *archive,
 		struct archive_entry *entry, const char *filename)
 {
@@ -115,10 +140,15 @@ static int perform_extraction(alpm_handle_t *handle, struct archive *archive,
 	                          ARCHIVE_EXTRACT_TIME |
 	                          ARCHIVE_EXTRACT_UNLINK |
 	                          ARCHIVE_EXTRACT_SECURE_SYMLINKS;
+	struct archive *w = archive_write_disk_new();
+	archive_write_disk_set_group_lookup(w, NULL, lookup_gid, NULL);
+	archive_write_disk_set_user_lookup(w, NULL, lookup_uid, NULL);
+	archive_write_disk_set_options(w, archive_flags);
 
 	archive_entry_set_pathname(entry, filename);
 
-	ret = archive_read_extract(archive, entry, archive_flags);
+	ret = archive_read_extract2(archive, entry, w);
+	archive_write_free(w);
 	if(ret == ARCHIVE_WARN && archive_errno(archive) != ENOSPC) {
 		/* operation succeeded but a "non-critical" error was encountered */
 		_alpm_log(handle, ALPM_LOG_WARNING, _("warning given when extracting %s (%s)\n"),
-- 
2.7.2


More information about the pacman-dev mailing list