From 2a54555aa2144f56a2ba518c48830c60da78c4d4 Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Tue, 14 Dec 2010 11:34:34 +0200 Subject: [PATCH] Split user+group caching to separate source (again), rename - We'll want to unify this and the similar caching done in librpmbuild, so we need to expose these in the ABI at least, rename to get them namespaced and use a separate source module (again) as this is a pretty distinct functionality. - This would really belong to librpmio but leaving here for now... --- lib/Makefile.am | 2 +- lib/fsm.c | 6 +- lib/misc.c | 162 ---------------------------------------------------- lib/misc.h | 19 ------- lib/rpmug.c | 174 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/rpmug.h | 16 ++++++ lib/verify.c | 7 ++- 7 files changed, 198 insertions(+), 188 deletions(-) create mode 100644 lib/rpmug.c create mode 100644 lib/rpmug.h diff --git a/lib/Makefile.am b/lib/Makefile.am index 1717f95..356c258 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -36,7 +36,7 @@ librpm_la_SOURCES = \ verify.c rpmlock.c rpmlock.h misc.h \ rpmscript.h rpmscript.c legacy.c merge.c \ rpmliblua.c rpmliblua.h rpmchroot.c rpmchroot.h \ - rpmplugins.c rpmplugins.h + rpmplugins.c rpmplugins.h rpmug.c rpmug.h librpm_la_LDFLAGS = -version-info 2:0:0 diff --git a/lib/fsm.c b/lib/fsm.c index 59ff7d0..52add47 100644 --- a/lib/fsm.c +++ b/lib/fsm.c @@ -25,7 +25,7 @@ #define fsmUNSAFE fsmStage #include "lib/rpmfi_internal.h" /* XXX fi->apath, ... */ #include "lib/rpmte_internal.h" /* XXX rpmfs */ -#include "lib/misc.h" /* XXX unameToUid() and gnameToGid() */ +#include "lib/rpmug.h" #include "debug.h" @@ -736,14 +736,14 @@ static int fsmMapAttrs(FSM_t fsm) uid_t uid = 0; gid_t gid = 0; - if (user && unameToUid(user, &uid)) { + if (user && rpmugUid(user, &uid)) { if (fsm->goal == FSM_PKGINSTALL) rpmlog(RPMLOG_WARNING, _("user %s does not exist - using root\n"), user); finalMode &= ~S_ISUID; /* turn off suid bit */ } - if (group && gnameToGid(group, &gid)) { + if (group && rpmugGid(group, &gid)) { if (fsm->goal == FSM_PKGINSTALL) rpmlog(RPMLOG_WARNING, _("group %s does not exist - using root\n"), group); diff --git a/lib/misc.c b/lib/misc.c index 03b59f5..3ea41a5 100644 --- a/lib/misc.c +++ b/lib/misc.c @@ -3,12 +3,6 @@ */ #include "system.h" - -#include -#include -#include -#include - #include "lib/misc.h" #include "debug.h" @@ -28,159 +22,3 @@ unsigned int hashFunctionString(const char * string) hash += (hash << 15); return hash; } - -/* 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 - who owned the last file. Those two values are cached, everything else - is looked up via getpw() and getgr() functions. If this performs - too poorly I'll have to implement it properly :-( */ - -int unameToUid(const char * thisUname, uid_t * uid) -{ -static char * lastUname = NULL; - static size_t lastUnameLen = 0; - static size_t lastUnameAlloced; - static uid_t lastUid; - struct passwd * pwent; - size_t thisUnameLen; - - if (!thisUname) { - lastUnameLen = 0; - return -1; - } else if (rstreq(thisUname, "root")) { - *uid = 0; - return 0; - } - - thisUnameLen = strlen(thisUname); - if (lastUname == NULL || thisUnameLen != lastUnameLen || - !rstreq(thisUname, lastUname)) - { - if (lastUnameAlloced < thisUnameLen + 1) { - lastUnameAlloced = thisUnameLen + 10; - lastUname = xrealloc(lastUname, lastUnameAlloced); /* XXX memory leak */ - } - strcpy(lastUname, thisUname); - - pwent = getpwnam(thisUname); - if (pwent == NULL) { - /* FIX: shrug */ - endpwent(); - pwent = getpwnam(thisUname); - if (pwent == NULL) return -1; - } - - lastUid = pwent->pw_uid; - } - - *uid = lastUid; - - return 0; -} - -int gnameToGid(const char * thisGname, gid_t * gid) -{ -static char * lastGname = NULL; - static size_t lastGnameLen = 0; - static size_t lastGnameAlloced; - static gid_t lastGid; - size_t thisGnameLen; - struct group * grent; - - if (thisGname == NULL) { - lastGnameLen = 0; - return -1; - } else if (rstreq(thisGname, "root")) { - *gid = 0; - return 0; - } - - thisGnameLen = strlen(thisGname); - if (lastGname == NULL || thisGnameLen != lastGnameLen || - !rstreq(thisGname, lastGname)) - { - if (lastGnameAlloced < thisGnameLen + 1) { - lastGnameAlloced = thisGnameLen + 10; - lastGname = xrealloc(lastGname, lastGnameAlloced); /* XXX memory leak */ - } - strcpy(lastGname, thisGname); - - grent = getgrnam(thisGname); - if (grent == NULL) { - /* FIX: shrug */ - endgrent(); - grent = getgrnam(thisGname); - if (grent == NULL) { - return -1; - } - } - lastGid = grent->gr_gid; - } - - *gid = lastGid; - - return 0; -} - -const char * uidToUname(uid_t uid) -{ - static uid_t lastUid = (uid_t) -1; -static char * lastUname = NULL; - static size_t lastUnameLen = 0; - - if (uid == (uid_t) -1) { - lastUid = (uid_t) -1; - return NULL; - } else if (uid == (uid_t) 0) { - return "root"; - } else if (uid == lastUid) { - return lastUname; - } else { - struct passwd * pwent = getpwuid(uid); - size_t len; - - if (pwent == NULL) return NULL; - - lastUid = uid; - len = strlen(pwent->pw_name); - if (lastUnameLen < len + 1) { - lastUnameLen = len + 20; - lastUname = xrealloc(lastUname, lastUnameLen); - } - strcpy(lastUname, pwent->pw_name); - - return lastUname; - } -} - -const char * gidToGname(gid_t gid) -{ - static gid_t lastGid = (gid_t) -1; -static char * lastGname = NULL; - static size_t lastGnameLen = 0; - - if (gid == (gid_t) -1) { - lastGid = (gid_t) -1; - return NULL; - } else if (gid == (gid_t) 0) { - return "root"; - } else if (gid == lastGid) { - return lastGname; - } else { - struct group * grent = getgrgid(gid); - size_t len; - - if (grent == NULL) return NULL; - - lastGid = gid; - len = strlen(grent->gr_name); - if (lastGnameLen < len + 1) { - lastGnameLen = len + 20; - lastGname = xrealloc(lastGname, lastGnameLen); - } - strcpy(lastGname, grent->gr_name); - - return lastGname; - } -} diff --git a/lib/misc.h b/lib/misc.h index 2cec97e..958561c 100644 --- a/lib/misc.h +++ b/lib/misc.h @@ -39,25 +39,6 @@ headerTagFormatFunction rpmHeaderFormatFuncByName(const char *fmt); RPM_GNUC_INTERNAL headerTagFormatFunction rpmHeaderFormatFuncByValue(rpmtdFormats fmt); -/* - * These may be called w/ a NULL argument to flush the cache -- they return - * -1 if the user can't be found. - */ -RPM_GNUC_INTERNAL -int unameToUid(const char * thisUname, uid_t * uid); - -RPM_GNUC_INTERNAL -int gnameToGid(const char * thisGname, gid_t * gid); - -/* - * Call w/ -1 to flush the cache, returns NULL if the user can't be found. - */ -RPM_GNUC_INTERNAL -const char * uidToUname(uid_t uid); - -RPM_GNUC_INTERNAL -const char * gidToGname(gid_t gid); - #ifdef __cplusplus } #endif diff --git a/lib/rpmug.c b/lib/rpmug.c new file mode 100644 index 0000000..47aa6cc --- /dev/null +++ b/lib/rpmug.c @@ -0,0 +1,174 @@ +#include "system.h" + +#include +#include +#include +#include + +#include "lib/rpmug.h" +#include "debug.h" + +/* + * These really ought to use hash tables. I just made the + * guess that most files would be owned by root or the same person/group + * who owned the last file. Those two values are cached, everything else + * is looked up via getpw() and getgr() functions. If this performs + * too poorly I'll have to implement it properly :-( + */ + +int rpmugUid(const char * thisUname, uid_t * uid) +{ + static char * lastUname = NULL; + static size_t lastUnameLen = 0; + static size_t lastUnameAlloced; + static uid_t lastUid; + struct passwd * pwent; + size_t thisUnameLen; + + if (!thisUname) { + lastUnameLen = 0; + return -1; + } else if (rstreq(thisUname, "root")) { + *uid = 0; + return 0; + } + + thisUnameLen = strlen(thisUname); + if (lastUname == NULL || thisUnameLen != lastUnameLen || + !rstreq(thisUname, lastUname)) + { + if (lastUnameAlloced < thisUnameLen + 1) { + lastUnameAlloced = thisUnameLen + 10; + lastUname = xrealloc(lastUname, lastUnameAlloced); /* XXX memory leak */ + } + strcpy(lastUname, thisUname); + + pwent = getpwnam(thisUname); + if (pwent == NULL) { + /* FIX: shrug */ + endpwent(); + pwent = getpwnam(thisUname); + if (pwent == NULL) return -1; + } + + lastUid = pwent->pw_uid; + } + + *uid = lastUid; + + return 0; +} + +int rpmugGid(const char * thisGname, gid_t * gid) +{ + static char * lastGname = NULL; + static size_t lastGnameLen = 0; + static size_t lastGnameAlloced; + static gid_t lastGid; + size_t thisGnameLen; + struct group * grent; + + if (thisGname == NULL) { + lastGnameLen = 0; + return -1; + } else if (rstreq(thisGname, "root")) { + *gid = 0; + return 0; + } + + thisGnameLen = strlen(thisGname); + if (lastGname == NULL || thisGnameLen != lastGnameLen || + !rstreq(thisGname, lastGname)) + { + if (lastGnameAlloced < thisGnameLen + 1) { + lastGnameAlloced = thisGnameLen + 10; + lastGname = xrealloc(lastGname, lastGnameAlloced); /* XXX memory leak */ + } + strcpy(lastGname, thisGname); + + grent = getgrnam(thisGname); + if (grent == NULL) { + /* FIX: shrug */ + endgrent(); + grent = getgrnam(thisGname); + if (grent == NULL) { + return -1; + } + } + lastGid = grent->gr_gid; + } + + *gid = lastGid; + + return 0; +} + +const char * rpmugUname(uid_t uid) +{ + static uid_t lastUid = (uid_t) -1; + static char * lastUname = NULL; + static size_t lastUnameLen = 0; + + if (uid == (uid_t) -1) { + lastUid = (uid_t) -1; + return NULL; + } else if (uid == (uid_t) 0) { + return "root"; + } else if (uid == lastUid) { + return lastUname; + } else { + struct passwd * pwent = getpwuid(uid); + size_t len; + + if (pwent == NULL) return NULL; + + lastUid = uid; + len = strlen(pwent->pw_name); + if (lastUnameLen < len + 1) { + lastUnameLen = len + 20; + lastUname = xrealloc(lastUname, lastUnameLen); + } + strcpy(lastUname, pwent->pw_name); + + return lastUname; + } +} + +const char * rpmugGname(gid_t gid) +{ + static gid_t lastGid = (gid_t) -1; + static char * lastGname = NULL; + static size_t lastGnameLen = 0; + + if (gid == (gid_t) -1) { + lastGid = (gid_t) -1; + return NULL; + } else if (gid == (gid_t) 0) { + return "root"; + } else if (gid == lastGid) { + return lastGname; + } else { + struct group * grent = getgrgid(gid); + size_t len; + + if (grent == NULL) return NULL; + + lastGid = gid; + len = strlen(grent->gr_name); + if (lastGnameLen < len + 1) { + lastGnameLen = len + 20; + lastGname = xrealloc(lastGname, lastGnameLen); + } + strcpy(lastGname, grent->gr_name); + + return lastGname; + } +} + +void rpmugFree(void) +{ + rpmugUid(NULL, NULL); + rpmugGid(NULL, NULL); + rpmugUname(-1); + rpmugGname(-1); +} diff --git a/lib/rpmug.h b/lib/rpmug.h new file mode 100644 index 0000000..7dbe77d --- /dev/null +++ b/lib/rpmug.h @@ -0,0 +1,16 @@ +#ifndef _RPMUG_H +#define _RPMUG_H + +#include + +int rpmugUid(const char * name, uid_t * uid); + +int rpmugGid(const char * name, gid_t * gid); + +const char * rpmugUname(uid_t uid); + +const char * rpmugGname(gid_t gid); + +void rpmugFree(void); + +#endif /* _RPMUG_H */ diff --git a/lib/verify.c b/lib/verify.c index a71847f..3be357d 100644 --- a/lib/verify.c +++ b/lib/verify.c @@ -21,9 +21,10 @@ #include #include -#include "lib/misc.h" /* uidToUname(), gnameToGid */ +#include "lib/misc.h" #include "lib/rpmchroot.h" #include "lib/rpmte_internal.h" /* rpmteProcess() */ +#include "lib/rpmug.h" #include "debug.h" @@ -238,14 +239,14 @@ int rpmVerifyFile(const rpmts ts, const rpmfi fi, } if (flags & RPMVERIFY_USER) { - const char * name = uidToUname(sb.st_uid); + const char * name = rpmugUname(sb.st_uid); const char * fuser = rpmfiFUser(fi); if (name == NULL || fuser == NULL || !rstreq(name, fuser)) *res |= RPMVERIFY_USER; } if (flags & RPMVERIFY_GROUP) { - const char * name = gidToGname(sb.st_gid); + const char * name = rpmugGname(sb.st_gid); const char * fgroup = rpmfiFGroup(fi); if (name == NULL || fgroup == NULL || !rstreq(name, fgroup)) *res |= RPMVERIFY_GROUP; -- 2.7.4