Blame safeugid.diff

Bernhard M. Wiedemann 1250f9
--- ./lib/rpmchroot.c.orig	2012-11-07 12:55:24.000000000 +0000
Bernhard M. Wiedemann 1250f9
+++ ./lib/rpmchroot.c	2014-02-20 12:50:05.360815211 +0000
Bernhard M. Wiedemann 1250f9
@@ -66,6 +66,7 @@ int rpmChrootIn(void)
Bernhard M. Wiedemann 1250f9
     } else if (rootState.chrootDone == 0) {
Bernhard M. Wiedemann 1250f9
 	if (chdir("/") == 0 && chroot(rootState.rootDir) == 0) {
Bernhard M. Wiedemann 1250f9
 	    rootState.chrootDone = 1;
Bernhard M. Wiedemann 1250f9
+	    rpmugChroot(1);
Bernhard M. Wiedemann 1250f9
 	} else {
Bernhard M. Wiedemann 1250f9
 	    rpmlog(RPMLOG_ERR, _("Unable to change root directory: %m\n"));
Bernhard M. Wiedemann 1250f9
 	    rc = -1;
Bernhard M. Wiedemann 1250f9
@@ -91,6 +92,7 @@ int rpmChrootOut(void)
Bernhard M. Wiedemann 1250f9
     } else if (rootState.chrootDone == 1) {
Bernhard M. Wiedemann 1250f9
 	if (chroot(".") == 0 && fchdir(rootState.cwd) == 0) {
Bernhard M. Wiedemann 1250f9
 	    rootState.chrootDone = 0;
Bernhard M. Wiedemann 1250f9
+	    rpmugChroot(0);
Bernhard M. Wiedemann 1250f9
 	} else {
Bernhard M. Wiedemann 1250f9
 	    rpmlog(RPMLOG_ERR, _("Unable to restore root directory: %m\n"));
Bernhard M. Wiedemann 1250f9
 	    rc = -1;
Bernhard M. Wiedemann 1250f9
--- ./lib/rpmug.c.orig	2014-02-05 13:04:37.000000000 +0000
Bernhard M. Wiedemann 1250f9
+++ ./lib/rpmug.c	2014-02-20 12:50:05.361815211 +0000
Bernhard M. Wiedemann 1250f9
@@ -10,6 +10,47 @@
Bernhard M. Wiedemann 1250f9
 #include "lib/rpmug.h"
Bernhard M. Wiedemann 1250f9
 #include "debug.h"
Bernhard M. Wiedemann 1250f9
 
Bernhard M. Wiedemann 1250f9
+#if defined(__GLIBC__)
Bernhard M. Wiedemann 1250f9
+
Bernhard M. Wiedemann 1250f9
+static int inchroot;
Bernhard M. Wiedemann 1250f9
+
Bernhard M. Wiedemann 1250f9
+/*
Bernhard M. Wiedemann 1250f9
+ * Unfortunatelly glibc caches nss/nscd data and there is no
Bernhard M. Wiedemann 1250f9
+ * good way to flush those caches when we did a chroot(). Thus
Bernhard M. Wiedemann 1250f9
+ * we need to parse /etc/passwd and /etc/group ourselfs.
Bernhard M. Wiedemann 1250f9
+ */
Bernhard M. Wiedemann 1250f9
+static int safe_lookup(const char * file, const char * name)
Bernhard M. Wiedemann 1250f9
+{
Bernhard M. Wiedemann 1250f9
+    FILE *fp;
Bernhard M. Wiedemann 1250f9
+    int l;
Bernhard M. Wiedemann 1250f9
+    char buf[4096], *p;
Bernhard M. Wiedemann 1250f9
+
Bernhard M. Wiedemann 1250f9
+    if (!name || !*name)
Bernhard M. Wiedemann 1250f9
+	return -1;
Bernhard M. Wiedemann 1250f9
+    l = strlen(name);
Bernhard M. Wiedemann 1250f9
+    if ((fp = fopen(file, "r")) == 0)
Bernhard M. Wiedemann 1250f9
+	return -1;
Bernhard M. Wiedemann 1250f9
+    while ((p = fgets(buf, sizeof(buf), fp)) != 0) {
Bernhard M. Wiedemann 1250f9
+	if (*p == '#')
Bernhard M. Wiedemann 1250f9
+	    continue;
Bernhard M. Wiedemann 1250f9
+	while (*p && (*p == ' ' || *p == '\t'))
Bernhard M. Wiedemann 1250f9
+	    p++;
Bernhard M. Wiedemann 1250f9
+	if (strncmp(p, name, l) != 0 || p[l] != ':')
Bernhard M. Wiedemann 1250f9
+	    continue;
Bernhard M. Wiedemann 1250f9
+	p = strchr(p + l + 1, ':');
Bernhard M. Wiedemann 1250f9
+	if (!p)
Bernhard M. Wiedemann 1250f9
+	    continue;
Bernhard M. Wiedemann 1250f9
+	fclose(fp);
Bernhard M. Wiedemann 1250f9
+	p++;
Bernhard M. Wiedemann 1250f9
+	while (*p && (*p == ' ' || *p == '\t'))
Bernhard M. Wiedemann 1250f9
+	    p++;
Bernhard M. Wiedemann 1250f9
+	return atoi(p);
Bernhard M. Wiedemann 1250f9
+    }
Bernhard M. Wiedemann 1250f9
+    fclose(fp);
Bernhard M. Wiedemann 1250f9
+    return -1;
Bernhard M. Wiedemann 1250f9
+}
Bernhard M. Wiedemann 1250f9
+#endif
Bernhard M. Wiedemann 1250f9
+
Bernhard M. Wiedemann 1250f9
 /* 
Bernhard M. Wiedemann 1250f9
  * These really ought to use hash tables. I just made the
Bernhard M. Wiedemann 1250f9
  * guess that most files would be owned by root or the same person/group
Bernhard M. Wiedemann 1250f9
@@ -43,17 +84,28 @@ int rpmugUid(const char * thisUname, uid
Bernhard M. Wiedemann 1250f9
 	    lastUnameAlloced = thisUnameLen + 10;
Bernhard M. Wiedemann 1250f9
 	    lastUname = xrealloc(lastUname, lastUnameAlloced);	/* XXX memory leak */
Bernhard M. Wiedemann 1250f9
 	}
Bernhard M. Wiedemann 1250f9
-	strcpy(lastUname, thisUname);
Bernhard M. Wiedemann 1250f9
 
Bernhard M. Wiedemann 1250f9
-	pwent = getpwnam(thisUname);
Bernhard M. Wiedemann 1250f9
-	if (pwent == NULL) {
Bernhard M. Wiedemann 1250f9
-	    /* FIX: shrug */
Bernhard M. Wiedemann 1250f9
-	    endpwent();
Bernhard M. Wiedemann 1250f9
+#if defined(__GLIBC__)
Bernhard M. Wiedemann 1250f9
+	if (inchroot) {
Bernhard M. Wiedemann 1250f9
+	    int uid =  safe_lookup("/etc/passwd", thisUname);
Bernhard M. Wiedemann 1250f9
+	    if (uid < 0)
Bernhard M. Wiedemann 1250f9
+		return -1;
Bernhard M. Wiedemann 1250f9
+	    lastUid = uid;
Bernhard M. Wiedemann 1250f9
+	} else
Bernhard M. Wiedemann 1250f9
+#endif
Bernhard M. Wiedemann 1250f9
+	{
Bernhard M. Wiedemann 1250f9
 	    pwent = getpwnam(thisUname);
Bernhard M. Wiedemann 1250f9
-	    if (pwent == NULL) return -1;
Bernhard M. Wiedemann 1250f9
+	    if (pwent == NULL) {
Bernhard M. Wiedemann 1250f9
+		/* FIX: shrug */
Bernhard M. Wiedemann 1250f9
+		endpwent();
Bernhard M. Wiedemann 1250f9
+		pwent = getpwnam(thisUname);
Bernhard M. Wiedemann 1250f9
+		if (pwent == NULL) return -1;
Bernhard M. Wiedemann 1250f9
+	    }
Bernhard M. Wiedemann 1250f9
+	    lastUid = pwent->pw_uid;
Bernhard M. Wiedemann 1250f9
 	}
Bernhard M. Wiedemann 1250f9
 
Bernhard M. Wiedemann 1250f9
-	lastUid = pwent->pw_uid;
Bernhard M. Wiedemann 1250f9
+	strcpy(lastUname, thisUname);
Bernhard M. Wiedemann 1250f9
+	lastUnameLen = thisUnameLen;
Bernhard M. Wiedemann 1250f9
     }
Bernhard M. Wiedemann 1250f9
 
Bernhard M. Wiedemann 1250f9
     *uid = lastUid;
Bernhard M. Wiedemann 1250f9
@@ -86,18 +138,29 @@ int rpmugGid(const char * thisGname, gid
Bernhard M. Wiedemann 1250f9
 	    lastGnameAlloced = thisGnameLen + 10;
Bernhard M. Wiedemann 1250f9
 	    lastGname = xrealloc(lastGname, lastGnameAlloced);	/* XXX memory leak */
Bernhard M. Wiedemann 1250f9
 	}
Bernhard M. Wiedemann 1250f9
-	strcpy(lastGname, thisGname);
Bernhard M. Wiedemann 1250f9
 
Bernhard M. Wiedemann 1250f9
-	grent = getgrnam(thisGname);
Bernhard M. Wiedemann 1250f9
-	if (grent == NULL) {
Bernhard M. Wiedemann 1250f9
-	    /* FIX: shrug */
Bernhard M. Wiedemann 1250f9
-	    endgrent();
Bernhard M. Wiedemann 1250f9
+#if defined(__GLIBC__)
Bernhard M. Wiedemann 1250f9
+	if (inchroot) {
Bernhard M. Wiedemann 1250f9
+	    int gid =  safe_lookup("/etc/group", thisGname);
Bernhard M. Wiedemann 1250f9
+	    if (gid < 0)
Bernhard M. Wiedemann 1250f9
+		return -1;
Bernhard M. Wiedemann 1250f9
+	    lastGid = gid;
Bernhard M. Wiedemann 1250f9
+	} else
Bernhard M. Wiedemann 1250f9
+#endif
Bernhard M. Wiedemann 1250f9
+	{
Bernhard M. Wiedemann 1250f9
 	    grent = getgrnam(thisGname);
Bernhard M. Wiedemann 1250f9
 	    if (grent == NULL) {
Bernhard M. Wiedemann 1250f9
-		return -1;
Bernhard M. Wiedemann 1250f9
+		/* FIX: shrug */
Bernhard M. Wiedemann 1250f9
+		endgrent();
Bernhard M. Wiedemann 1250f9
+		grent = getgrnam(thisGname);
Bernhard M. Wiedemann 1250f9
+		if (grent == NULL) {
Bernhard M. Wiedemann 1250f9
+		    return -1;
Bernhard M. Wiedemann 1250f9
+		}
Bernhard M. Wiedemann 1250f9
 	    }
Bernhard M. Wiedemann 1250f9
+	    lastGid = grent->gr_gid;
Bernhard M. Wiedemann 1250f9
 	}
Bernhard M. Wiedemann 1250f9
-	lastGid = grent->gr_gid;
Bernhard M. Wiedemann 1250f9
+	strcpy(lastGname, thisGname);
Bernhard M. Wiedemann 1250f9
+	lastGnameLen = thisGnameLen;
Bernhard M. Wiedemann 1250f9
     }
Bernhard M. Wiedemann 1250f9
 
Bernhard M. Wiedemann 1250f9
     *gid = lastGid;
Bernhard M. Wiedemann 1250f9
@@ -109,7 +172,7 @@ const char * rpmugUname(uid_t uid)
Bernhard M. Wiedemann 1250f9
 {
Bernhard M. Wiedemann 1250f9
     static uid_t lastUid = (uid_t) -1;
Bernhard M. Wiedemann 1250f9
     static char * lastUname = NULL;
Bernhard M. Wiedemann 1250f9
-    static size_t lastUnameLen = 0;
Bernhard M. Wiedemann 1250f9
+    static size_t lastUnameAlloced = 0;
Bernhard M. Wiedemann 1250f9
 
Bernhard M. Wiedemann 1250f9
     if (uid == (uid_t) -1) {
Bernhard M. Wiedemann 1250f9
 	lastUid = (uid_t) -1;
Bernhard M. Wiedemann 1250f9
@@ -126,9 +189,9 @@ const char * rpmugUname(uid_t uid)
Bernhard M. Wiedemann 1250f9
 
Bernhard M. Wiedemann 1250f9
 	lastUid = uid;
Bernhard M. Wiedemann 1250f9
 	len = strlen(pwent->pw_name);
Bernhard M. Wiedemann 1250f9
-	if (lastUnameLen < len + 1) {
Bernhard M. Wiedemann 1250f9
-	    lastUnameLen = len + 20;
Bernhard M. Wiedemann 1250f9
-	    lastUname = xrealloc(lastUname, lastUnameLen);
Bernhard M. Wiedemann 1250f9
+	if (lastUnameAlloced < len + 1) {
Bernhard M. Wiedemann 1250f9
+	    lastUnameAlloced = len + 20;
Bernhard M. Wiedemann 1250f9
+	    lastUname = xrealloc(lastUname, lastUnameAlloced);
Bernhard M. Wiedemann 1250f9
 	}
Bernhard M. Wiedemann 1250f9
 	strcpy(lastUname, pwent->pw_name);
Bernhard M. Wiedemann 1250f9
 
Bernhard M. Wiedemann 1250f9
@@ -140,7 +203,7 @@ const char * rpmugGname(gid_t gid)
Bernhard M. Wiedemann 1250f9
 {
Bernhard M. Wiedemann 1250f9
     static gid_t lastGid = (gid_t) -1;
Bernhard M. Wiedemann 1250f9
     static char * lastGname = NULL;
Bernhard M. Wiedemann 1250f9
-    static size_t lastGnameLen = 0;
Bernhard M. Wiedemann 1250f9
+    static size_t lastGnameAlloced = 0;
Bernhard M. Wiedemann 1250f9
 
Bernhard M. Wiedemann 1250f9
     if (gid == (gid_t) -1) {
Bernhard M. Wiedemann 1250f9
 	lastGid = (gid_t) -1;
Bernhard M. Wiedemann 1250f9
@@ -157,9 +220,9 @@ const char * rpmugGname(gid_t gid)
Bernhard M. Wiedemann 1250f9
 
Bernhard M. Wiedemann 1250f9
 	lastGid = gid;
Bernhard M. Wiedemann 1250f9
 	len = strlen(grent->gr_name);
Bernhard M. Wiedemann 1250f9
-	if (lastGnameLen < len + 1) {
Bernhard M. Wiedemann 1250f9
-	    lastGnameLen = len + 20;
Bernhard M. Wiedemann 1250f9
-	    lastGname = xrealloc(lastGname, lastGnameLen);
Bernhard M. Wiedemann 1250f9
+	if (lastGnameAlloced < len + 1) {
Bernhard M. Wiedemann 1250f9
+	    lastGnameAlloced = len + 20;
Bernhard M. Wiedemann 1250f9
+	    lastGname = xrealloc(lastGname, lastGnameAlloced);
Bernhard M. Wiedemann 1250f9
 	}
Bernhard M. Wiedemann 1250f9
 	strcpy(lastGname, grent->gr_name);
Bernhard M. Wiedemann 1250f9
 
Bernhard M. Wiedemann 1250f9
@@ -189,3 +252,16 @@ void rpmugFree(void)
Bernhard M. Wiedemann 1250f9
     rpmugUname(-1);
Bernhard M. Wiedemann 1250f9
     rpmugGname(-1);
Bernhard M. Wiedemann 1250f9
 }
Bernhard M. Wiedemann 1250f9
+
Bernhard M. Wiedemann 1250f9
+void rpmugChroot(int in)
Bernhard M. Wiedemann 1250f9
+{
Bernhard M. Wiedemann 1250f9
+    /* tell libc to drop caches / file descriptors */
Bernhard M. Wiedemann 1250f9
+    endpwent();
Bernhard M. Wiedemann 1250f9
+    endgrent();
Bernhard M. Wiedemann 1250f9
+    /* drop our own caches */
Bernhard M. Wiedemann 1250f9
+    rpmugUid(NULL, NULL);
Bernhard M. Wiedemann 1250f9
+    rpmugGid(NULL, NULL);
Bernhard M. Wiedemann 1250f9
+#if defined(__GLIBC__)
Bernhard M. Wiedemann 1250f9
+    inchroot = in;
Bernhard M. Wiedemann 1250f9
+#endif
Bernhard M. Wiedemann 1250f9
+}
Bernhard M. Wiedemann 1250f9
--- ./lib/rpmug.h.orig	2014-02-05 13:04:02.000000000 +0000
Bernhard M. Wiedemann 1250f9
+++ ./lib/rpmug.h	2014-02-20 12:50:05.362815211 +0000
Bernhard M. Wiedemann 1250f9
@@ -15,4 +15,6 @@ int rpmugInit(void);
Bernhard M. Wiedemann 1250f9
 
Bernhard M. Wiedemann 1250f9
 void rpmugFree(void);
Bernhard M. Wiedemann 1250f9
 
Bernhard M. Wiedemann 1250f9
+void rpmugChroot(int in);
Bernhard M. Wiedemann 1250f9
+
Bernhard M. Wiedemann 1250f9
 #endif /* _RPMUG_H */