Blame lib/rpmug.c

2ff057
#include "system.h"
2ff057
2ff057
#include <pthread.h>
2ff057
#include <pwd.h>
2ff057
#include <grp.h>
2ff057
#include <netdb.h>
2ff057
#include <rpm/rpmlog.h>
2ff057
#include <rpm/rpmstring.h>
2ff057
2ff057
#include "lib/misc.h"
2ff057
#include "lib/rpmug.h"
2ff057
#include "debug.h"
2ff057
2ff057
/* 
2ff057
 * These really ought to use hash tables. I just made the
2ff057
 * guess that most files would be owned by root or the same person/group
2ff057
 * who owned the last file. Those two values are cached, everything else
2ff057
 * is looked up via getpw() and getgr() functions.  If this performs
2ff057
 * too poorly I'll have to implement it properly :-(
2ff057
 */
2ff057
2ff057
int rpmugUid(const char * thisUname, uid_t * uid)
2ff057
{
2ff057
    static char * lastUname = NULL;
2ff057
    static size_t lastUnameLen = 0;
2ff057
    static size_t lastUnameAlloced;
2ff057
    static uid_t lastUid;
2ff057
    struct passwd * pwent;
2ff057
    size_t thisUnameLen;
2ff057
2ff057
    if (!thisUname) {
2ff057
	lastUnameLen = 0;
2ff057
	return -1;
2ff057
    } else if (rstreq(thisUname, UID_0_USER)) {
2ff057
	*uid = 0;
2ff057
	return 0;
2ff057
    }
2ff057
2ff057
    thisUnameLen = strlen(thisUname);
2ff057
    if (lastUname == NULL || thisUnameLen != lastUnameLen ||
2ff057
	!rstreq(thisUname, lastUname))
2ff057
    {
2ff057
	if (lastUnameAlloced < thisUnameLen + 1) {
2ff057
	    lastUnameAlloced = thisUnameLen + 10;
2ff057
	    lastUname = xrealloc(lastUname, lastUnameAlloced);	/* XXX memory leak */
2ff057
	}
2ff057
	strcpy(lastUname, thisUname);
2ff057
2ff057
	pwent = getpwnam(thisUname);
2ff057
	if (pwent == NULL) {
2ff057
	    /* FIX: shrug */
2ff057
	    endpwent();
2ff057
	    pwent = getpwnam(thisUname);
2ff057
	    if (pwent == NULL) return -1;
2ff057
	}
2ff057
2ff057
	lastUid = pwent->pw_uid;
2ff057
    }
2ff057
2ff057
    *uid = lastUid;
2ff057
2ff057
    return 0;
2ff057
}
2ff057
2ff057
int rpmugGid(const char * thisGname, gid_t * gid)
2ff057
{
2ff057
    static char * lastGname = NULL;
2ff057
    static size_t lastGnameLen = 0;
2ff057
    static size_t lastGnameAlloced;
2ff057
    static gid_t lastGid;
2ff057
    size_t thisGnameLen;
2ff057
    struct group * grent;
2ff057
2ff057
    if (thisGname == NULL) {
2ff057
	lastGnameLen = 0;
2ff057
	return -1;
2ff057
    } else if (rstreq(thisGname, GID_0_GROUP)) {
2ff057
	*gid = 0;
2ff057
	return 0;
2ff057
    }
2ff057
2ff057
    thisGnameLen = strlen(thisGname);
2ff057
    if (lastGname == NULL || thisGnameLen != lastGnameLen ||
2ff057
	!rstreq(thisGname, lastGname))
2ff057
    {
2ff057
	if (lastGnameAlloced < thisGnameLen + 1) {
2ff057
	    lastGnameAlloced = thisGnameLen + 10;
2ff057
	    lastGname = xrealloc(lastGname, lastGnameAlloced);	/* XXX memory leak */
2ff057
	}
2ff057
	strcpy(lastGname, thisGname);
2ff057
2ff057
	grent = getgrnam(thisGname);
2ff057
	if (grent == NULL) {
2ff057
	    /* FIX: shrug */
2ff057
	    endgrent();
2ff057
	    grent = getgrnam(thisGname);
2ff057
	    if (grent == NULL) {
2ff057
		return -1;
2ff057
	    }
2ff057
	}
2ff057
	lastGid = grent->gr_gid;
2ff057
    }
2ff057
2ff057
    *gid = lastGid;
2ff057
2ff057
    return 0;
2ff057
}
2ff057
2ff057
const char * rpmugUname(uid_t uid)
2ff057
{
2ff057
    static uid_t lastUid = (uid_t) -1;
2ff057
    static char * lastUname = NULL;
2ff057
    static size_t lastUnameLen = 0;
2ff057
2ff057
    if (uid == (uid_t) -1) {
2ff057
	lastUid = (uid_t) -1;
2ff057
	return NULL;
2ff057
    } else if (uid == (uid_t) 0) {
2ff057
	return UID_0_USER;
2ff057
    } else if (uid == lastUid) {
2ff057
	return lastUname;
2ff057
    } else {
2ff057
	struct passwd * pwent = getpwuid(uid);
2ff057
	size_t len;
2ff057
2ff057
	if (pwent == NULL) return NULL;
2ff057
2ff057
	lastUid = uid;
2ff057
	len = strlen(pwent->pw_name);
2ff057
	if (lastUnameLen < len + 1) {
2ff057
	    lastUnameLen = len + 20;
2ff057
	    lastUname = xrealloc(lastUname, lastUnameLen);
2ff057
	}
2ff057
	strcpy(lastUname, pwent->pw_name);
2ff057
2ff057
	return lastUname;
2ff057
    }
2ff057
}
2ff057
2ff057
const char * rpmugGname(gid_t gid)
2ff057
{
2ff057
    static gid_t lastGid = (gid_t) -1;
2ff057
    static char * lastGname = NULL;
2ff057
    static size_t lastGnameLen = 0;
2ff057
2ff057
    if (gid == (gid_t) -1) {
2ff057
	lastGid = (gid_t) -1;
2ff057
	return NULL;
2ff057
    } else if (gid == (gid_t) 0) {
2ff057
	return GID_0_GROUP;
2ff057
    } else if (gid == lastGid) {
2ff057
	return lastGname;
2ff057
    } else {
2ff057
	struct group * grent = getgrgid(gid);
2ff057
	size_t len;
2ff057
2ff057
	if (grent == NULL) return NULL;
2ff057
2ff057
	lastGid = gid;
2ff057
	len = strlen(grent->gr_name);
2ff057
	if (lastGnameLen < len + 1) {
2ff057
	    lastGnameLen = len + 20;
2ff057
	    lastGname = xrealloc(lastGname, lastGnameLen);
2ff057
	}
2ff057
	strcpy(lastGname, grent->gr_name);
2ff057
2ff057
	return lastGname;
2ff057
    }
2ff057
}
2ff057
2ff057
static void loadLibs(void)
2ff057
{
2ff057
    (void) getpwnam(UID_0_USER);
2ff057
    endpwent();
2ff057
    (void) getgrnam(GID_0_GROUP);
2ff057
    endgrent();
2ff057
    (void) gethostbyname("localhost");
2ff057
}
2ff057
2ff057
int rpmugInit(void)
2ff057
{
2ff057
    static pthread_once_t libsLoaded = PTHREAD_ONCE_INIT;
2ff057
2ff057
    pthread_once(&libsLoaded, loadLibs);
2ff057
    return 0;
2ff057
}
2ff057
2ff057
void rpmugFree(void)
2ff057
{
2ff057
    rpmugUid(NULL, NULL);
2ff057
    rpmugGid(NULL, NULL);
2ff057
    rpmugUname(-1);
2ff057
    rpmugGname(-1);
2ff057
}