Split user+group caching to separate source (again), rename
authorPanu Matilainen <pmatilai@redhat.com>
Tue, 14 Dec 2010 09:34:34 +0000 (11:34 +0200)
committerPanu Matilainen <pmatilai@redhat.com>
Wed, 15 Dec 2010 07:22:08 +0000 (09:22 +0200)
- 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
lib/fsm.c
lib/misc.c
lib/misc.h
lib/rpmug.c [new file with mode: 0644]
lib/rpmug.h [new file with mode: 0644]
lib/verify.c

index 1717f95..356c258 100644 (file)
@@ -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
 
index 59ff7d0..52add47 100644 (file)
--- 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);
index 03b59f5..3ea41a5 100644 (file)
@@ -3,12 +3,6 @@
  */
 
 #include "system.h"
-
-#include <pwd.h>
-#include <grp.h>
-#include <rpm/rpmlog.h>
-#include <rpm/rpmstring.h>
-
 #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;
-    }
-}
index 2cec97e..958561c 100644 (file)
@@ -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 (file)
index 0000000..47aa6cc
--- /dev/null
@@ -0,0 +1,174 @@
+#include "system.h"
+
+#include <pwd.h>
+#include <grp.h>
+#include <rpm/rpmlog.h>
+#include <rpm/rpmstring.h>
+
+#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 (file)
index 0000000..7dbe77d
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef _RPMUG_H
+#define _RPMUG_H
+
+#include <sys/types.h>
+
+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 */
index a71847f..3be357d 100644 (file)
 #include <rpm/rpmdb.h>
 #include <rpm/rpmfileutil.h>
 
-#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;