2 * Copyright (C) 2013-2014 Intel Corporation.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 * José Bollo <jose.bollo@open.eurogiciel.org>
20 * Stéphane Desneux <stephane.desneux@open.eurogiciel.org>
21 * Jean-Benoit Martin <jean-benoit.martin@open.eurogiciel.org>
32 #include <sys/types.h>
38 #ifndef NOT_PASSWD_ONLY
43 enum { iname, ipasswd, iuid, igid, icmt, idir, ishell };
45 static const char pwfile[] = "/etc/passwd";
46 static struct buffer buffer;
47 static size_t pos, lengths[7];
48 static const char *starts[7];
50 #define is(s, i) (!strncmp(s, starts[i], lengths[i]) && !s[lengths[i]])
52 /* open the passwd file */
56 return buffer_create(&buffer, pwfile);
59 /* close the passwd file */
62 buffer_destroy(&buffer);
65 /* read the passwd file */
69 const char *head = buffer.buffer + pos;
70 const char *end = buffer.buffer + buffer.length;
73 while (head != end && *head != ':' && *head != '\n') head++;
74 lengths[col] = head - starts[col];
78 pos = head - buffer.buffer;
83 pos = head - buffer.buffer;
86 while (head != end && *head != '\n') head++;
87 if (head != end) head++;
96 pos = head - buffer.buffer;
100 int pw_get(struct heap *heap, struct pwget **items)
106 for (n = 0 ; items[n] != NULL ; n++)
112 while (s && rdpw()) {
114 for (i = 0 ; i < n ; i++) {
115 if (!items[i]->set && is(items[i]->id, iuid)) {
117 user = heap_strndup(heap,
118 starts[iname], lengths[iname]);
119 home = heap_strndup(heap,
120 starts[idir], lengths[idir]);
123 items[i]->user = user;
124 items[i]->home = home;
134 int pw_has_uid(uid_t uid)
138 if (lengths[iuid] && (int)uid == atoi(starts[iuid])) {
148 int pw_get_uid(const char *name, uid_t *uid)
153 if (is(name, iname)) {
154 *uid = (uid_t)atoi(starts[iuid]);
166 int pw_get_gid(const char *name, gid_t *gid)
171 if (is(name, iname)) {
172 *gid = (gid_t)atoi(starts[igid]);
190 int pw_get(struct heap *heap, struct pwget **items)
192 char buffer[BUFSIZE];
193 struct passwd entry, *pe;
198 for (n = 0 ; items[n] != NULL ; n++) {
199 id = (uid_t)atoi(items[n]->id);
200 result = getpwuid_r(id, &entry, buffer, sizeof buffer, &pe);
202 while (items[n] != NULL) items[n++]->set = 0;
209 items[n]->user = heap_strdup(heap, pe->pw_name);
210 items[n]->home = heap_strdup(heap, pe->pw_dir);
216 int pw_has_uid(uid_t uid)
218 char buffer[BUFSIZE];
219 struct passwd entry, *pe;
222 result = getpwuid_r(uid, &entry, buffer, sizeof buffer, &pe);
223 return !result && pe;
226 int pw_get_uid(const char *name, uid_t *uid)
228 char buffer[BUFSIZE];
229 struct passwd entry, *pe;
230 int result = getpwnam_r(name, &entry, buffer, sizeof buffer, &pe);
242 int pw_get_gid(const char *name, gid_t *gid)
244 char buffer[BUFSIZE];
245 struct passwd entry, *pe;
246 int result = getpwnam_r(name, &entry, buffer, sizeof buffer, &pe);
262 int main(int argc, char**argv)
265 enum { uid, gid, names } action = uid;
266 heap_create(&heap, 1000);
268 if (!strcmp(*argv, "-u"))
270 else if (!strcmp(*argv, "-g"))
272 else if (!strcmp(*argv, "-n"))
274 else if (action == uid) {
276 int sts = pw_get_uid(*argv, &u);
277 printf("uid(%s)=%d [%d]\n", *argv, (int)u, sts);
278 } else if (action == gid) {
280 int sts = pw_get_gid(*argv, &g);
281 printf("gid(%s)=%d [%d]\n", *argv, (int)g, sts);
282 } else if (action == names) {
283 struct pwget pw = { .id = *argv }, *ppw[2] = { &pw, NULL };
284 int sts = pw_get(&heap, ppw);
285 printf("names(%s) set=%d", *argv, pw.set);
287 printf(" name=%s home=%s",
288 pw.user == HNULL ? "(null)"
289 : (char*)heap_address(&heap, pw.user),
290 pw.home == HNULL ? "(null)"
291 : (char*)heap_address(&heap, pw.home));
293 printf(" [%d]\n", sts);