rpm 5.2.1

rpmio/ugid.c

Go to the documentation of this file.
00001 
00005 #include "system.h"
00006 #include "ugid.h"
00007 #include "debug.h"
00008 
00009 /* unameToUid(), uidTouname() and the group variants are really poorly
00010    implemented. They really ought to use hash tables. I just made the
00011    guess that most files would be owned by root or the same person/group
00012    who owned the last file. Those two values are cached, everything else
00013    is looked up via getpw() and getgr() functions.  If this performs
00014    too poorly I'll have to implement it properly :-( */
00015 
00016 int unameToUid(const char * thisUname, uid_t * uid)
00017 {
00018 /*@only@*/ static char * lastUname = NULL;
00019     static size_t lastUnameLen = 0;
00020     static size_t lastUnameAlloced;
00021     static uid_t lastUid;
00022     struct passwd * pwent;
00023     size_t thisUnameLen;
00024 
00025     if (!thisUname) {
00026         lastUnameLen = 0;
00027         return -1;
00028 #if !defined(RPM_VENDOR_OPENPKG) /* no-hard-coded-ugid */
00029     } else if (strcmp(thisUname, "root") == 0) {
00030         *uid = 0;
00031         return 0;
00032 #endif
00033     }
00034 
00035     thisUnameLen = strlen(thisUname);
00036     if (lastUname == NULL || thisUnameLen != lastUnameLen ||
00037         strcmp(thisUname, lastUname) != 0)
00038     {
00039         if (lastUnameAlloced < thisUnameLen + 1) {
00040             lastUnameAlloced = thisUnameLen + 10;
00041             lastUname = xrealloc(lastUname, lastUnameAlloced);  /* XXX memory leak */
00042         }
00043         strcpy(lastUname, thisUname);
00044 
00045         pwent = getpwnam(thisUname);
00046         if (pwent == NULL) {
00047             /*@-internalglobs@*/ /* FIX: shrug */
00048             endpwent();
00049             /*@=internalglobs@*/
00050             pwent = getpwnam(thisUname);
00051             if (pwent == NULL) return -1;
00052         }
00053 
00054         lastUid = pwent->pw_uid;
00055     }
00056 
00057     *uid = lastUid;
00058 
00059     return 0;
00060 }
00061 
00062 int gnameToGid(const char * thisGname, gid_t * gid)
00063 {
00064 /*@only@*/ static char * lastGname = NULL;
00065     static size_t lastGnameLen = 0;
00066     static size_t lastGnameAlloced;
00067     static gid_t lastGid;
00068     size_t thisGnameLen;
00069     struct group * grent;
00070 
00071     if (thisGname == NULL) {
00072         lastGnameLen = 0;
00073         return -1;
00074 #if !defined(RPM_VENDOR_OPENPKG) /* no-hard-coded-ugid */
00075     } else if (strcmp(thisGname, "root") == 0) {
00076         *gid = 0;
00077         return 0;
00078 #endif
00079     }
00080 
00081     thisGnameLen = strlen(thisGname);
00082     if (lastGname == NULL || thisGnameLen != lastGnameLen ||
00083         strcmp(thisGname, lastGname) != 0)
00084     {
00085         if (lastGnameAlloced < thisGnameLen + 1) {
00086             lastGnameAlloced = thisGnameLen + 10;
00087             lastGname = xrealloc(lastGname, lastGnameAlloced);  /* XXX memory leak */
00088         }
00089         strcpy(lastGname, thisGname);
00090 
00091         grent = getgrnam(thisGname);
00092         if (grent == NULL) {
00093             /*@-internalglobs@*/ /* FIX: shrug */
00094             endgrent();
00095             /*@=internalglobs@*/
00096             grent = getgrnam(thisGname);
00097             if (grent == NULL) {
00098 #if !defined(RPM_VENDOR_OPENPKG) /* no-hard-coded-ugid */
00099                 /* XXX The filesystem package needs group/lock w/o getgrnam. */
00100                 if (strcmp(thisGname, "lock") == 0) {
00101                     *gid = lastGid = 54;
00102                     return 0;
00103                 } else
00104                 if (strcmp(thisGname, "mail") == 0) {
00105                     *gid = lastGid = 12;
00106                     return 0;
00107                 } else
00108 #endif
00109                 return -1;
00110             }
00111         }
00112         lastGid = grent->gr_gid;
00113     }
00114 
00115     *gid = lastGid;
00116 
00117     return 0;
00118 }
00119 
00120 char * uidToUname(uid_t uid)
00121 {
00122     static uid_t lastUid = (uid_t) -1;
00123 /*@only@*/ static char * lastUname = NULL;
00124     static size_t lastUnameLen = 0;
00125 
00126     if (uid == (uid_t) -1) {
00127         lastUid = (uid_t) -1;
00128         return NULL;
00129 #if !defined(RPM_VENDOR_OPENPKG) /* no-hard-coded-ugid */
00130     } else if (uid == (uid_t) 0) {
00131         return "root";
00132 #endif
00133     } else if (uid == lastUid) {
00134         return lastUname;
00135     } else {
00136         struct passwd * pwent = getpwuid(uid);
00137         size_t len;
00138 
00139         if (pwent == NULL) return NULL;
00140 
00141         lastUid = uid;
00142         len = strlen(pwent->pw_name);
00143         if (lastUnameLen < len + 1) {
00144             lastUnameLen = len + 20;
00145             lastUname = xrealloc(lastUname, lastUnameLen);
00146         }
00147         strcpy(lastUname, pwent->pw_name);
00148 
00149         return lastUname;
00150     }
00151 }
00152 
00153 char * gidToGname(gid_t gid)
00154 {
00155     static gid_t lastGid = (gid_t) -1;
00156 /*@only@*/ static char * lastGname = NULL;
00157     static size_t lastGnameLen = 0;
00158 
00159     if (gid == (gid_t) -1) {
00160         lastGid = (gid_t) -1;
00161         return NULL;
00162 #if !defined(RPM_VENDOR_OPENPKG) /* no-hard-coded-ugid */
00163     } else if (gid == (gid_t) 0) {
00164         return "root";
00165 #endif
00166     } else if (gid == lastGid) {
00167         return lastGname;
00168     } else {
00169         struct group * grent = getgrgid(gid);
00170         size_t len;
00171 
00172         if (grent == NULL) return NULL;
00173 
00174         lastGid = gid;
00175         len = strlen(grent->gr_name);
00176         if (lastGnameLen < len + 1) {
00177             lastGnameLen = len + 20;
00178             lastGname = xrealloc(lastGname, lastGnameLen);
00179         }
00180         strcpy(lastGname, grent->gr_name);
00181 
00182         return lastGname;
00183     }
00184 }