rpm
4.5
|
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 } else if (strcmp(thisUname, "root") == 0) { 00029 /*@-boundswrite@*/ 00030 *uid = 0; 00031 /*@=boundswrite@*/ 00032 return 0; 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 /*@-boundswrite@*/ 00044 strcpy(lastUname, thisUname); 00045 /*@=boundswrite@*/ 00046 00047 pwent = getpwnam(thisUname); 00048 if (pwent == NULL) { 00049 /*@-internalglobs@*/ /* FIX: shrug */ 00050 endpwent(); 00051 /*@=internalglobs@*/ 00052 pwent = getpwnam(thisUname); 00053 if (pwent == NULL) return -1; 00054 } 00055 00056 lastUid = pwent->pw_uid; 00057 } 00058 00059 /*@-boundswrite@*/ 00060 *uid = lastUid; 00061 /*@=boundswrite@*/ 00062 00063 return 0; 00064 } 00065 00066 int gnameToGid(const char * thisGname, gid_t * gid) 00067 { 00068 /*@only@*/ static char * lastGname = NULL; 00069 static size_t lastGnameLen = 0; 00070 static size_t lastGnameAlloced; 00071 static gid_t lastGid; 00072 size_t thisGnameLen; 00073 struct group * grent; 00074 00075 if (thisGname == NULL) { 00076 lastGnameLen = 0; 00077 return -1; 00078 } else if (strcmp(thisGname, "root") == 0) { 00079 /*@-boundswrite@*/ 00080 *gid = 0; 00081 /*@=boundswrite@*/ 00082 return 0; 00083 } 00084 00085 thisGnameLen = strlen(thisGname); 00086 if (lastGname == NULL || thisGnameLen != lastGnameLen || 00087 strcmp(thisGname, lastGname) != 0) 00088 { 00089 if (lastGnameAlloced < thisGnameLen + 1) { 00090 lastGnameAlloced = thisGnameLen + 10; 00091 lastGname = xrealloc(lastGname, lastGnameAlloced); /* XXX memory leak */ 00092 } 00093 /*@-boundswrite@*/ 00094 strcpy(lastGname, thisGname); 00095 /*@=boundswrite@*/ 00096 00097 grent = getgrnam(thisGname); 00098 if (grent == NULL) { 00099 /*@-internalglobs@*/ /* FIX: shrug */ 00100 endgrent(); 00101 /*@=internalglobs@*/ 00102 grent = getgrnam(thisGname); 00103 if (grent == NULL) { 00104 /* XXX The FHS package needs group/uucp w/o getgrnam, filesystem needs adm */ 00105 if (strcmp(thisGname, "uucp") == 0) { 00106 /*@-boundswrite@*/ 00107 *gid = lastGid = 14; 00108 /*@=boundswrite@*/ 00109 return 0; 00110 } else 00111 if (strcmp(thisGname, "mail") == 0) { 00112 /*@-boundswrite@*/ 00113 *gid = lastGid = 12; 00114 /*@=boundswrite@*/ 00115 return 0; 00116 } else 00117 if (strcmp(thisGname, "adm") == 0) { 00118 /*@-boundswrite@*/ 00119 *gid = lastGid = 4; 00120 /*@=boundswrite@*/ 00121 return 0; 00122 } else 00123 return -1; 00124 } 00125 } 00126 lastGid = grent->gr_gid; 00127 } 00128 00129 /*@-boundswrite@*/ 00130 *gid = lastGid; 00131 /*@=boundswrite@*/ 00132 00133 return 0; 00134 } 00135 00136 char * uidToUname(uid_t uid) 00137 { 00138 static uid_t lastUid = (uid_t) -1; 00139 /*@only@*/ static char * lastUname = NULL; 00140 static size_t lastUnameLen = 0; 00141 00142 if (uid == (uid_t) -1) { 00143 lastUid = (uid_t) -1; 00144 return NULL; 00145 } else if (uid == (uid_t) 0) { 00146 return "root"; 00147 } else if (uid == lastUid) { 00148 return lastUname; 00149 } else { 00150 struct passwd * pwent = getpwuid(uid); 00151 size_t len; 00152 00153 if (pwent == NULL) return NULL; 00154 00155 lastUid = uid; 00156 len = strlen(pwent->pw_name); 00157 if (lastUnameLen < len + 1) { 00158 lastUnameLen = len + 20; 00159 lastUname = xrealloc(lastUname, lastUnameLen); 00160 } 00161 /*@-boundswrite@*/ 00162 strcpy(lastUname, pwent->pw_name); 00163 /*@=boundswrite@*/ 00164 00165 return lastUname; 00166 } 00167 } 00168 00169 char * gidToGname(gid_t gid) 00170 { 00171 static gid_t lastGid = (gid_t) -1; 00172 /*@only@*/ static char * lastGname = NULL; 00173 static size_t lastGnameLen = 0; 00174 00175 if (gid == (gid_t) -1) { 00176 lastGid = (gid_t) -1; 00177 return NULL; 00178 } else if (gid == (gid_t) 0) { 00179 return "root"; 00180 } else if (gid == lastGid) { 00181 return lastGname; 00182 } else { 00183 struct group * grent = getgrgid(gid); 00184 size_t len; 00185 00186 if (grent == NULL) return NULL; 00187 00188 lastGid = gid; 00189 len = strlen(grent->gr_name); 00190 if (lastGnameLen < len + 1) { 00191 lastGnameLen = len + 20; 00192 lastGname = xrealloc(lastGname, lastGnameLen); 00193 } 00194 /*@-boundswrite@*/ 00195 strcpy(lastGname, grent->gr_name); 00196 /*@=boundswrite@*/ 00197 00198 return lastGname; 00199 } 00200 }