|
|
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 |
}
|