rpm  4.5
ugid.c
Go to the documentation of this file.
1 
5 #include "system.h"
6 #include "ugid.h"
7 #include "debug.h"
8 
9 /* unameToUid(), uidTouname() and the group variants are really poorly
10  implemented. They really ought to use hash tables. I just made the
11  guess that most files would be owned by root or the same person/group
12  who owned the last file. Those two values are cached, everything else
13  is looked up via getpw() and getgr() functions. If this performs
14  too poorly I'll have to implement it properly :-( */
15 
16 int unameToUid(const char * thisUname, uid_t * uid)
17 {
18 /*@only@*/ static char * lastUname = NULL;
19  static size_t lastUnameLen = 0;
20  static size_t lastUnameAlloced;
21  static uid_t lastUid;
22  struct passwd * pwent;
23  size_t thisUnameLen;
24 
25  if (!thisUname) {
26  lastUnameLen = 0;
27  return -1;
28  } else if (strcmp(thisUname, "root") == 0) {
29 /*@-boundswrite@*/
30  *uid = 0;
31 /*@=boundswrite@*/
32  return 0;
33  }
34 
35  thisUnameLen = strlen(thisUname);
36  if (lastUname == NULL || thisUnameLen != lastUnameLen ||
37  strcmp(thisUname, lastUname) != 0)
38  {
39  if (lastUnameAlloced < thisUnameLen + 1) {
40  lastUnameAlloced = thisUnameLen + 10;
41  lastUname = xrealloc(lastUname, lastUnameAlloced); /* XXX memory leak */
42  }
43 /*@-boundswrite@*/
44  strcpy(lastUname, thisUname);
45 /*@=boundswrite@*/
46 
47  pwent = getpwnam(thisUname);
48  if (pwent == NULL) {
49  /*@-internalglobs@*/ /* FIX: shrug */
50  endpwent();
51  /*@=internalglobs@*/
52  pwent = getpwnam(thisUname);
53  if (pwent == NULL) return -1;
54  }
55 
56  lastUid = pwent->pw_uid;
57  }
58 
59 /*@-boundswrite@*/
60  *uid = lastUid;
61 /*@=boundswrite@*/
62 
63  return 0;
64 }
65 
66 int gnameToGid(const char * thisGname, gid_t * gid)
67 {
68 /*@only@*/ static char * lastGname = NULL;
69  static size_t lastGnameLen = 0;
70  static size_t lastGnameAlloced;
71  static gid_t lastGid;
72  size_t thisGnameLen;
73  struct group * grent;
74 
75  if (thisGname == NULL) {
76  lastGnameLen = 0;
77  return -1;
78  } else if (strcmp(thisGname, "root") == 0) {
79 /*@-boundswrite@*/
80  *gid = 0;
81 /*@=boundswrite@*/
82  return 0;
83  }
84 
85  thisGnameLen = strlen(thisGname);
86  if (lastGname == NULL || thisGnameLen != lastGnameLen ||
87  strcmp(thisGname, lastGname) != 0)
88  {
89  if (lastGnameAlloced < thisGnameLen + 1) {
90  lastGnameAlloced = thisGnameLen + 10;
91  lastGname = xrealloc(lastGname, lastGnameAlloced); /* XXX memory leak */
92  }
93 /*@-boundswrite@*/
94  strcpy(lastGname, thisGname);
95 /*@=boundswrite@*/
96 
97  grent = getgrnam(thisGname);
98  if (grent == NULL) {
99  /*@-internalglobs@*/ /* FIX: shrug */
100  endgrent();
101  /*@=internalglobs@*/
102  grent = getgrnam(thisGname);
103  if (grent == NULL) {
104  /* XXX The FHS package needs group/uucp w/o getgrnam, filesystem needs adm */
105  if (strcmp(thisGname, "uucp") == 0) {
106 /*@-boundswrite@*/
107  *gid = lastGid = 14;
108 /*@=boundswrite@*/
109  return 0;
110  } else
111  if (strcmp(thisGname, "mail") == 0) {
112 /*@-boundswrite@*/
113  *gid = lastGid = 12;
114 /*@=boundswrite@*/
115  return 0;
116  } else
117  if (strcmp(thisGname, "adm") == 0) {
118 /*@-boundswrite@*/
119  *gid = lastGid = 4;
120 /*@=boundswrite@*/
121  return 0;
122  } else
123  return -1;
124  }
125  }
126  lastGid = grent->gr_gid;
127  }
128 
129 /*@-boundswrite@*/
130  *gid = lastGid;
131 /*@=boundswrite@*/
132 
133  return 0;
134 }
135 
136 char * uidToUname(uid_t uid)
137 {
138  static uid_t lastUid = (uid_t) -1;
139 /*@only@*/ static char * lastUname = NULL;
140  static size_t lastUnameLen = 0;
141 
142  if (uid == (uid_t) -1) {
143  lastUid = (uid_t) -1;
144  return NULL;
145  } else if (uid == (uid_t) 0) {
146  return "root";
147  } else if (uid == lastUid) {
148  return lastUname;
149  } else {
150  struct passwd * pwent = getpwuid(uid);
151  size_t len;
152 
153  if (pwent == NULL) return NULL;
154 
155  lastUid = uid;
156  len = strlen(pwent->pw_name);
157  if (lastUnameLen < len + 1) {
158  lastUnameLen = len + 20;
159  lastUname = xrealloc(lastUname, lastUnameLen);
160  }
161 /*@-boundswrite@*/
162  strcpy(lastUname, pwent->pw_name);
163 /*@=boundswrite@*/
164 
165  return lastUname;
166  }
167 }
168 
169 char * gidToGname(gid_t gid)
170 {
171  static gid_t lastGid = (gid_t) -1;
172 /*@only@*/ static char * lastGname = NULL;
173  static size_t lastGnameLen = 0;
174 
175  if (gid == (gid_t) -1) {
176  lastGid = (gid_t) -1;
177  return NULL;
178  } else if (gid == (gid_t) 0) {
179  return "root";
180  } else if (gid == lastGid) {
181  return lastGname;
182  } else {
183  struct group * grent = getgrgid(gid);
184  size_t len;
185 
186  if (grent == NULL) return NULL;
187 
188  lastGid = gid;
189  len = strlen(grent->gr_name);
190  if (lastGnameLen < len + 1) {
191  lastGnameLen = len + 20;
192  lastGname = xrealloc(lastGname, lastGnameLen);
193  }
194 /*@-boundswrite@*/
195  strcpy(lastGname, grent->gr_name);
196 /*@=boundswrite@*/
197 
198  return lastGname;
199  }
200 }