rpm  5.2.1
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 #if !defined(RPM_VENDOR_OPENPKG) /* no-hard-coded-ugid */
29  } else if (strcmp(thisUname, "root") == 0) {
30  *uid = 0;
31  return 0;
32 #endif
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  strcpy(lastUname, thisUname);
44 
45  pwent = getpwnam(thisUname);
46  if (pwent == NULL) {
47  /*@-internalglobs@*/ /* FIX: shrug */
48  endpwent();
49  /*@=internalglobs@*/
50  pwent = getpwnam(thisUname);
51  if (pwent == NULL) return -1;
52  }
53 
54  lastUid = pwent->pw_uid;
55  }
56 
57  *uid = lastUid;
58 
59  return 0;
60 }
61 
62 int gnameToGid(const char * thisGname, gid_t * gid)
63 {
64 /*@only@*/ static char * lastGname = NULL;
65  static size_t lastGnameLen = 0;
66  static size_t lastGnameAlloced;
67  static gid_t lastGid;
68  size_t thisGnameLen;
69  struct group * grent;
70 
71  if (thisGname == NULL) {
72  lastGnameLen = 0;
73  return -1;
74 #if !defined(RPM_VENDOR_OPENPKG) /* no-hard-coded-ugid */
75  } else if (strcmp(thisGname, "root") == 0) {
76  *gid = 0;
77  return 0;
78 #endif
79  }
80 
81  thisGnameLen = strlen(thisGname);
82  if (lastGname == NULL || thisGnameLen != lastGnameLen ||
83  strcmp(thisGname, lastGname) != 0)
84  {
85  if (lastGnameAlloced < thisGnameLen + 1) {
86  lastGnameAlloced = thisGnameLen + 10;
87  lastGname = xrealloc(lastGname, lastGnameAlloced); /* XXX memory leak */
88  }
89  strcpy(lastGname, thisGname);
90 
91  grent = getgrnam(thisGname);
92  if (grent == NULL) {
93  /*@-internalglobs@*/ /* FIX: shrug */
94  endgrent();
95  /*@=internalglobs@*/
96  grent = getgrnam(thisGname);
97  if (grent == NULL) {
98 #if !defined(RPM_VENDOR_OPENPKG) /* no-hard-coded-ugid */
99  /* XXX The filesystem package needs group/lock w/o getgrnam. */
100  if (strcmp(thisGname, "lock") == 0) {
101  *gid = lastGid = 54;
102  return 0;
103  } else
104  if (strcmp(thisGname, "mail") == 0) {
105  *gid = lastGid = 12;
106  return 0;
107  } else
108 #endif
109  return -1;
110  }
111  }
112  lastGid = grent->gr_gid;
113  }
114 
115  *gid = lastGid;
116 
117  return 0;
118 }
119 
120 char * uidToUname(uid_t uid)
121 {
122  static uid_t lastUid = (uid_t) -1;
123 /*@only@*/ static char * lastUname = NULL;
124  static size_t lastUnameLen = 0;
125 
126  if (uid == (uid_t) -1) {
127  lastUid = (uid_t) -1;
128  return NULL;
129 #if !defined(RPM_VENDOR_OPENPKG) /* no-hard-coded-ugid */
130  } else if (uid == (uid_t) 0) {
131  return "root";
132 #endif
133  } else if (uid == lastUid) {
134  return lastUname;
135  } else {
136  struct passwd * pwent = getpwuid(uid);
137  size_t len;
138 
139  if (pwent == NULL) return NULL;
140 
141  lastUid = uid;
142  len = strlen(pwent->pw_name);
143  if (lastUnameLen < len + 1) {
144  lastUnameLen = len + 20;
145  lastUname = xrealloc(lastUname, lastUnameLen);
146  }
147  strcpy(lastUname, pwent->pw_name);
148 
149  return lastUname;
150  }
151 }
152 
153 char * gidToGname(gid_t gid)
154 {
155  static gid_t lastGid = (gid_t) -1;
156 /*@only@*/ static char * lastGname = NULL;
157  static size_t lastGnameLen = 0;
158 
159  if (gid == (gid_t) -1) {
160  lastGid = (gid_t) -1;
161  return NULL;
162 #if !defined(RPM_VENDOR_OPENPKG) /* no-hard-coded-ugid */
163  } else if (gid == (gid_t) 0) {
164  return "root";
165 #endif
166  } else if (gid == lastGid) {
167  return lastGname;
168  } else {
169  struct group * grent = getgrgid(gid);
170  size_t len;
171 
172  if (grent == NULL) return NULL;
173 
174  lastGid = gid;
175  len = strlen(grent->gr_name);
176  if (lastGnameLen < len + 1) {
177  lastGnameLen = len + 20;
178  lastGname = xrealloc(lastGname, lastGnameLen);
179  }
180  strcpy(lastGname, grent->gr_name);
181 
182  return lastGname;
183  }
184 }