--- rpm-4.3.3/lib/psm.c.nss	2005-10-14 12:13:02.000000000 +0400
+++ rpm-4.3.3/lib/psm.c	2005-10-14 12:18:35.000000000 +0400
@@ -1828,20 +1828,6 @@
 	if (rootDir != NULL && !(rootDir[0] == '/' && rootDir[1] == '\0')
 	 && !rpmtsChrootDone(ts) && !psm->chrootDone)
 	{
-	    static int _pw_loaded = 0;
-	    static int _gr_loaded = 0;
-
-	    if (!_pw_loaded) {
-		(void)getpwnam("root");
-		endpwent();
-		_pw_loaded++;
-	    }
-	    if (!_gr_loaded) {
-		(void)getgrnam("root");
-		endgrent();
-		_gr_loaded++;
-	    }
-
 	    xx = chdir("/");
 	    /*@-superuser@*/
 	    rc = chroot(rootDir);
--- rpm-4.3.3/rpmio/ugid.c.nss	2005-10-14 12:13:17.000000000 +0400
+++ rpm-4.3.3/rpmio/ugid.c	2005-10-14 12:21:30.000000000 +0400
@@ -3,9 +3,313 @@
  */
 
 #include "system.h"
+#include <sys/param.h>
 #include "ugid.h"
 #include "debug.h"
 
+/* In-VPS password/group access routines */
+
+struct passwd * vpsgetpwnam(const char * name)
+{
+    static struct passwd res;
+    FILE * vpspasswd;
+    static char buffer[MAXPATHLEN];
+    int len = strlen(name);
+    char * uname, * passwd, * uid, * gid, * comment, * home, * shell;
+
+    memset(&res,0,sizeof(struct passwd));
+    memset(buffer,0,sizeof(buffer));
+    
+    vpspasswd = fopen("/etc/passwd","r");
+
+    if(vpspasswd == NULL)
+	return NULL;
+
+    while(fgets(buffer,sizeof(buffer),vpspasswd))
+    {
+	if((strncmp(buffer,name,len) == 0) && (buffer[len] == ':'))
+	{	/* Record for required user found */
+	    uname = buffer;
+	    res.pw_name = uname;
+	    
+	    passwd = strchr(uname,':');
+	    if(!passwd)
+	    {
+		fclose(vpspasswd);
+		return NULL;
+	    }
+	    
+	    *passwd = 0;
+	    passwd++;
+	    res.pw_passwd = passwd;
+	    
+	    uid = strchr(passwd,':');
+	    if(!uid)
+	    {
+		fclose(vpspasswd);
+		return NULL;
+	    }
+	    
+	    *uid = 0;
+	    uid++;
+	    res.pw_uid = atoi(uid);
+	    
+	    gid = strchr(uid,':');
+	    if(!gid)
+	    {
+		fclose(vpspasswd);
+		return &res;	/* Actually dpkg need uid field. Leave others not filled */
+	    }
+	    
+	    *gid = 0;
+	    gid++;
+	    res.pw_gid = atoi(gid);
+
+	    comment = strchr(gid,':');
+	    if(!comment)
+	    {
+		fclose(vpspasswd);
+		return &res;
+	    }
+	    
+	    *comment = 0;
+	    comment++;
+	    res.pw_gecos = comment;
+
+	    home = strchr(comment,':');
+	    if(!home)
+	    {
+		fclose(vpspasswd);
+		return &res;
+	    }
+	    
+	    *home = 0;
+	    home++;
+	    res.pw_dir = home;
+
+	    shell = strchr(home,':');
+	    if(!shell)
+	    {
+		fclose(vpspasswd);
+		return &res;
+	    }
+	    
+	    *shell = 0;
+	    shell++;
+	    res.pw_shell = shell;
+
+	    fclose(vpspasswd);
+	    return &res;
+	}
+    }
+    
+    fclose(vpspasswd);
+    
+    return NULL;
+}
+
+struct passwd * vpsgetpwuid(uid_t id)
+{
+    static struct passwd res;
+    FILE * vpspasswd;
+    static char buffer[MAXPATHLEN];
+    /**/
+    char * uname, * passwd, * uid, * gid, * comment, * home, * shell;
+
+    memset(&res,0,sizeof(struct passwd));
+    memset(buffer,0,sizeof(buffer));
+    
+    vpspasswd = fopen("/etc/passwd","r");
+
+    if(vpspasswd == NULL)
+	return NULL;
+
+    while(fgets(buffer,sizeof(buffer),vpspasswd))
+    {
+	uname = buffer;
+	
+	passwd = strchr(uname,':');
+	if(!passwd)
+	    continue;
+
+	*passwd = 0;
+	passwd++;
+
+	uid = strchr(passwd,':');
+	if(!uid)
+	    continue;
+	
+	*uid = 0;
+	uid++;
+
+	if(id == atoi(uid))
+	{	/* Record for required user found */
+	    res.pw_name = uname;
+	    
+	    res.pw_passwd = passwd;
+	    
+	    res.pw_uid = id;
+	    
+	    gid = strchr(uid,':');
+	    if(!gid)
+	    {
+		fclose(vpspasswd);
+		return &res;	/* Actually dpkg need uid field. Leave others not filled */
+	    }
+	    
+	    *gid = 0;
+	    gid++;
+	    res.pw_gid = atoi(gid);
+
+	    comment = strchr(gid,':');
+	    if(!comment)
+	    {
+		fclose(vpspasswd);
+		return &res;
+	    }
+	    
+	    *comment = 0;
+	    comment++;
+	    res.pw_gecos = comment;
+
+	    home = strchr(comment,':');
+	    if(!home)
+	    {
+		fclose(vpspasswd);
+		return &res;
+	    }
+	    
+	    *home = 0;
+	    home++;
+	    res.pw_dir = home;
+
+	    shell = strchr(home,':');
+	    if(!shell)
+	    {
+		fclose(vpspasswd);
+		return &res;
+	    }
+	    
+	    *shell = 0;
+	    shell++;
+	    res.pw_shell = shell;
+	    
+	    fclose(vpspasswd);
+	    return &res;
+	}
+    }
+    
+    fclose(vpspasswd);
+    
+    return NULL;
+}
+
+struct group * vpsgetgrnam(const char * name)
+{
+    static struct group res;
+    FILE * vpsgroup;
+    static char buffer[MAXPATHLEN];
+    int len = strlen(name);
+    char * gname,* passwd, * gid;
+
+    memset(&res,0,sizeof(struct group));
+    memset(buffer,0,sizeof(buffer));
+
+    vpsgroup = fopen("/etc/group","r");
+
+    if(vpsgroup == NULL)
+	return NULL;
+
+    while(fgets(buffer,sizeof(buffer),vpsgroup))
+    {
+	if((strncmp(buffer,name,len) == 0) && (buffer[len] == ':'))
+	{	/* Record for required group found */
+	    gname = buffer;
+	    res.gr_name = gname;
+
+	    passwd = strchr(gname,':');
+	    if(!passwd)
+	    {
+		fclose(vpsgroup);
+		return NULL;
+	    }
+	    
+	    *passwd = 0;
+	    passwd++;
+	    res.gr_passwd = passwd;
+
+	    gid = strchr(passwd,':');
+	    if(!gid)
+	    {
+		fclose(vpsgroup);
+		return NULL;
+	    }
+	    
+	    *gid = 0;
+	    gid++;
+	    res.gr_gid = atoi(gid);
+	    
+	    fclose(vpsgroup);
+	    return &res;
+	}
+    }
+    
+    fclose(vpsgroup);
+    
+    return NULL;
+}
+
+struct group * vpsgetgrgid(gid_t id)
+{
+    static struct group res;
+    FILE * vpsgroup;
+    static char buffer[MAXPATHLEN];
+    /**/
+    char * gname,* passwd, * gid;
+
+    memset(&res,0,sizeof(struct group));
+    memset(buffer,0,sizeof(buffer));
+
+    vpsgroup = fopen("/etc/group","r");
+
+    if(vpsgroup == NULL)
+	return NULL;
+
+    while(fgets(buffer,sizeof(buffer),vpsgroup))
+    {
+	gname = buffer;
+
+	passwd = strchr(gname,':');
+	if(!passwd)
+	    continue;
+	*passwd = 0;
+	passwd++;
+
+	gid = strchr(passwd,':');
+	if(!gid)
+	    continue;
+	*gid = 0;
+	gid++;
+
+	if(id == atoi(gid))
+	{	/* Record for required group found */
+	    res.gr_name = gname;
+
+	    res.gr_passwd = passwd;
+
+	    res.gr_gid = id;
+
+	    fclose(vpsgroup);
+	    
+	    return &res;
+	}
+    }
+    
+    fclose(vpsgroup);
+    
+    return NULL;
+}
+
 /* unameToUid(), uidTouname() and the group variants are really poorly
    implemented. They really ought to use hash tables. I just made the
    guess that most files would be owned by root or the same person/group
@@ -44,12 +348,12 @@
 	strcpy(lastUname, thisUname);
 /*@=boundswrite@*/
 
-	pwent = getpwnam(thisUname);
+	pwent = vpsgetpwnam(thisUname);
 	if (pwent == NULL) {
 	    /*@-internalglobs@*/ /* FIX: shrug */
-	    endpwent();
+/*	    endpwent();*/
 	    /*@=internalglobs@*/
-	    pwent = getpwnam(thisUname);
+	    pwent = vpsgetpwnam(thisUname);
 	    if (pwent == NULL) return -1;
 	}
 
@@ -94,12 +398,12 @@
 	strcpy(lastGname, thisGname);
 /*@=boundswrite@*/
 
-	grent = getgrnam(thisGname);
+	grent = vpsgetgrnam(thisGname);
 	if (grent == NULL) {
 	    /*@-internalglobs@*/ /* FIX: shrug */
-	    endgrent();
+/*	    endgrent();*/
 	    /*@=internalglobs@*/
-	    grent = getgrnam(thisGname);
+	    grent = vpsgetgrnam(thisGname);
 	    if (grent == NULL) {
 		/* XXX The filesystem package needs group/lock w/o getgrnam. */
 		if (strcmp(thisGname, "lock") == 0) {
@@ -137,7 +441,7 @@
     } else if (uid == lastUid) {
 	return lastUname;
     } else {
-	struct passwd * pwent = getpwuid(uid);
+	struct passwd * pwent = vpsgetpwuid(uid);
 	size_t len;
 
 	if (pwent == NULL) return NULL;
@@ -170,7 +474,7 @@
     } else if (gid == lastGid) {
 	return lastGname;
     } else {
-	struct group * grent = getgrgid(gid);
+	struct group * grent = vpsgetgrgid(gid);
 	size_t len;
 
 	if (grent == NULL) return NULL;
