rpm  5.4.4
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 _pw, *pwent = NULL;
00023     char _b[BUFSIZ];
00024     size_t _nb = sizeof(_b);
00025     size_t thisUnameLen;
00026 
00027 #ifdef  SUSE_REFERENCE
00028 news
00029 uucp
00030 man
00031 nobody
00032 wwwrun
00033 mail
00034 lp
00035 #endif
00036     if (thisUname == NULL) {
00037         lastUnameLen = 0;
00038         return -1;
00039 #if !defined(RPM_VENDOR_OPENPKG) /* no-hard-coded-ugid */
00040     } else if (strcmp(thisUname, "root") == 0) {
00041         *uid = 0;
00042         return 0;
00043 #endif
00044     }
00045 
00046     thisUnameLen = strlen(thisUname);
00047     if (lastUname == NULL || thisUnameLen != lastUnameLen ||
00048         strcmp(thisUname, lastUname) != 0)
00049     {
00050         if (lastUnameAlloced < thisUnameLen + 1) {
00051             lastUnameAlloced = thisUnameLen + 10;
00052             lastUname = (char *) DRD_xrealloc(lastUname, lastUnameAlloced);
00053         }
00054         strcpy(lastUname, thisUname);
00055 
00056         if (getpwnam_r(thisUname, &_pw, _b, _nb, &pwent) || pwent == NULL) {
00057             /*@-internalglobs@*/ /* FIX: shrug */
00058             endpwent();
00059             /*@=internalglobs@*/
00060             if (getpwnam_r(thisUname, &_pw, _b, _nb, &pwent) || pwent == NULL)
00061                 return -1;
00062         }
00063         lastUid = pwent->pw_uid;
00064     }
00065 
00066     *uid = lastUid;
00067 
00068     return 0;
00069 }
00070 
00071 int gnameToGid(const char * thisGname, gid_t * gid)
00072 {
00073 /*@only@*/ static char * lastGname = NULL;
00074     static size_t lastGnameLen = 0;
00075     static size_t lastGnameAlloced;
00076     static gid_t lastGid;
00077     struct group _gr, *grent = NULL;
00078     char _b[BUFSIZ];
00079     size_t _nb = sizeof(_b);
00080     size_t thisGnameLen;
00081 
00082 #ifdef  SUSE_REFERENCE
00083 news
00084 dialout
00085 uucp
00086 lp
00087 #endif
00088     if (thisGname == NULL) {
00089         lastGnameLen = 0;
00090         return -1;
00091 #if !defined(RPM_VENDOR_OPENPKG) /* no-hard-coded-ugid */
00092     } else if (strcmp(thisGname, "root") == 0) {
00093         *gid = 0;
00094         return 0;
00095 #endif
00096     }
00097 
00098     thisGnameLen = strlen(thisGname);
00099     if (lastGname == NULL || thisGnameLen != lastGnameLen ||
00100         strcmp(thisGname, lastGname) != 0)
00101     {
00102         if (lastGnameAlloced < thisGnameLen + 1) {
00103             lastGnameAlloced = thisGnameLen + 10;
00104             lastGname = (char *) DRD_xrealloc(lastGname, lastGnameAlloced);
00105         }
00106         strcpy(lastGname, thisGname);
00107 
00108         if (getgrnam_r(thisGname, &_gr, _b, _nb, &grent) || grent == NULL) {
00109             /*@-internalglobs@*/ /* FIX: shrug */
00110             endgrent();
00111             /*@=internalglobs@*/
00112             if (getgrnam_r(thisGname, &_gr, _b, _nb, &grent) || grent == NULL) {
00113 #if !defined(RPM_VENDOR_OPENPKG) /* no-hard-coded-ugid */
00114                 /* XXX The filesystem package needs group/lock w/o getgrnam. */
00115                 if (strcmp(thisGname, "lock") == 0) {
00116                     *gid = lastGid = 54;
00117                     return 0;
00118                 } else
00119                 if (strcmp(thisGname, "mail") == 0) {
00120                     *gid = lastGid = 12;
00121                     return 0;
00122                 } else
00123 #endif
00124                 return -1;
00125             }
00126         }
00127         lastGid = grent->gr_gid;
00128     }
00129 
00130     *gid = lastGid;
00131 
00132     return 0;
00133 }
00134 
00135 char * uidToUname(uid_t uid)
00136 {
00137     static uid_t lastUid = (uid_t) -1;
00138 /*@only@*/ static char * lastUname = NULL;
00139     static size_t lastUnameLen = 0;
00140 
00141     if (uid == (uid_t) -1) {
00142         lastUid = (uid_t) -1;
00143         return NULL;
00144 #if !defined(RPM_VENDOR_OPENPKG) /* no-hard-coded-ugid */
00145     } else if (uid == (uid_t) 0) {
00146         return (char *) "root";
00147 #endif
00148     } else if (uid == lastUid) {
00149         return lastUname;
00150     } else {
00151         struct passwd _pw, *pwent = NULL;
00152         char _b[BUFSIZ];
00153         size_t _nb = sizeof(_b);
00154         size_t len;
00155 
00156         if (getpwuid_r(uid, &_pw, _b, _nb, &pwent) || pwent == NULL)
00157             return NULL;
00158 
00159         lastUid = uid;
00160         len = strlen(pwent->pw_name);
00161         if (lastUnameLen < len + 1) {
00162             lastUnameLen = len + 20;
00163             lastUname = (char *) DRD_xrealloc(lastUname, lastUnameLen);
00164         }
00165         strcpy(lastUname, pwent->pw_name);
00166 
00167         return lastUname;
00168     }
00169 }
00170 
00171 char * gidToGname(gid_t gid)
00172 {
00173     static gid_t lastGid = (gid_t) -1;
00174 /*@only@*/ static char * lastGname = NULL;
00175     static size_t lastGnameLen = 0;
00176 
00177     if (gid == (gid_t) -1) {
00178         lastGid = (gid_t) -1;
00179         return NULL;
00180 #if !defined(RPM_VENDOR_OPENPKG) /* no-hard-coded-ugid */
00181     } else if (gid == (gid_t) 0) {
00182         return (char *) "root";
00183 #endif
00184     } else if (gid == lastGid) {
00185         return lastGname;
00186     } else {
00187         struct group _gr, *grent = NULL;
00188         char _b[BUFSIZ];
00189         size_t _nb = sizeof(_b);
00190         size_t len;
00191 
00192         if (getgrgid_r(gid, &_gr, _b, _nb, &grent) || grent == NULL)
00193             return NULL;
00194 
00195         lastGid = gid;
00196         len = strlen(grent->gr_name);
00197         if (lastGnameLen < len + 1) {
00198             lastGnameLen = len + 20;
00199             lastGname = (char *) DRD_xrealloc(lastGname, lastGnameLen);
00200         }
00201         strcpy(lastGname, grent->gr_name);
00202 
00203         return lastGname;
00204     }
00205 }