blob: 8250cd446d84c76a777bdb74725ccad0ce0fb543 [file] [log] [blame]
Bernhard Reutner-Fischerc5280e82005-09-20 21:09:31 +00001/* vi: set sw=4 ts=4: */
2/*
3 * password utility routines.
4 *
5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
Denis Vlasenko0c68a872008-12-02 22:56:59 +00006 * Copyright (C) 2008 by Tito Ragusa <farmatito@tiscali.it>
Bernhard Reutner-Fischerc5280e82005-09-20 21:09:31 +00007 *
Denys Vlasenko0ef64bd2010-08-16 20:14:46 +02008 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
Bernhard Reutner-Fischerc5280e82005-09-20 21:09:31 +00009 */
10
Denis Vlasenko7d219aa2006-10-05 10:17:08 +000011#include "libbb.h"
Bernhard Reutner-Fischerc5280e82005-09-20 21:09:31 +000012
Denis Vlasenko0c68a872008-12-02 22:56:59 +000013/* TODO: maybe change API to return malloced data?
14 * This will allow to stop using libc functions returning
15 * pointers to static data (getpwuid)
Denis Vlasenko3734b942007-07-27 11:20:10 +000016 */
Denis Vlasenko0c68a872008-12-02 22:56:59 +000017
Denis Vlasenkod7a805e2008-12-03 19:05:55 +000018struct passwd* FAST_FUNC xgetpwnam(const char *name)
19{
20 struct passwd *pw = getpwnam(name);
21 if (!pw)
22 bb_error_msg_and_die("unknown user %s", name);
23 return pw;
24}
25
Denis Vlasenko15437e32008-12-05 16:23:06 +000026struct group* FAST_FUNC xgetgrnam(const char *name)
27{
28 struct group *gr = getgrnam(name);
29 if (!gr)
30 bb_error_msg_and_die("unknown group %s", name);
31 return gr;
32}
33
Denis Vlasenko0c68a872008-12-02 22:56:59 +000034
35struct passwd* FAST_FUNC xgetpwuid(uid_t uid)
Denis Vlasenkobecd8c52006-12-01 21:34:20 +000036{
Denis Vlasenko0c68a872008-12-02 22:56:59 +000037 struct passwd *pw = getpwuid(uid);
38 if (!pw)
39 bb_error_msg_and_die("unknown uid %u", (unsigned)uid);
40 return pw;
Denis Vlasenkobecd8c52006-12-01 21:34:20 +000041}
42
Denis Vlasenko0c68a872008-12-02 22:56:59 +000043struct group* FAST_FUNC xgetgrgid(gid_t gid)
Denis Vlasenko3734b942007-07-27 11:20:10 +000044{
Denis Vlasenko0c68a872008-12-02 22:56:59 +000045 struct group *gr = getgrgid(gid);
46 if (!gr)
47 bb_error_msg_and_die("unknown gid %u", (unsigned)gid);
48 return gr;
Bernhard Reutner-Fischerc5280e82005-09-20 21:09:31 +000049}
Bernhard Reutner-Fischerc5280e82005-09-20 21:09:31 +000050
Denis Vlasenko0c68a872008-12-02 22:56:59 +000051char* FAST_FUNC xuid2uname(uid_t uid)
Bernhard Reutner-Fischerc5280e82005-09-20 21:09:31 +000052{
Denis Vlasenko0c68a872008-12-02 22:56:59 +000053 struct passwd *pw = xgetpwuid(uid);
54 return pw->pw_name;
Bernhard Reutner-Fischerc5280e82005-09-20 21:09:31 +000055}
Bernhard Reutner-Fischerc5280e82005-09-20 21:09:31 +000056
Denis Vlasenko0c68a872008-12-02 22:56:59 +000057char* FAST_FUNC xgid2group(gid_t gid)
58{
59 struct group *gr = xgetgrgid(gid);
60 return gr->gr_name;
61}
62
63char* FAST_FUNC uid2uname(uid_t uid)
64{
65 struct passwd *pw = getpwuid(uid);
66 return (pw) ? pw->pw_name : NULL;
67}
68
69char* FAST_FUNC gid2group(gid_t gid)
70{
71 struct group *gr = getgrgid(gid);
72 return (gr) ? gr->gr_name : NULL;
73}
74
Denys Vlasenko7d65abe2011-03-01 16:27:13 +010075char* FAST_FUNC uid2uname_utoa(uid_t uid)
Denis Vlasenko0c68a872008-12-02 22:56:59 +000076{
77 char *name = uid2uname(uid);
78 return (name) ? name : utoa(uid);
79}
80
Denys Vlasenko7d65abe2011-03-01 16:27:13 +010081char* FAST_FUNC gid2group_utoa(gid_t gid)
Denis Vlasenko0c68a872008-12-02 22:56:59 +000082{
83 char *name = gid2group(gid);
84 return (name) ? name : utoa(gid);
85}
86
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +000087long FAST_FUNC xuname2uid(const char *name)
Bernhard Reutner-Fischerc5280e82005-09-20 21:09:31 +000088{
89 struct passwd *myuser;
90
Denis Vlasenkod7a805e2008-12-03 19:05:55 +000091 myuser = xgetpwnam(name);
Bernhard Reutner-Fischerc5280e82005-09-20 21:09:31 +000092 return myuser->pw_uid;
93}
Bernhard Reutner-Fischerc5280e82005-09-20 21:09:31 +000094
Denis Vlasenko0c68a872008-12-02 22:56:59 +000095long FAST_FUNC xgroup2gid(const char *name)
96{
97 struct group *mygroup;
98
Denis Vlasenko15437e32008-12-05 16:23:06 +000099 mygroup = xgetgrnam(name);
Denis Vlasenko0c68a872008-12-02 22:56:59 +0000100 return mygroup->gr_gid;
101}
102
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +0000103unsigned long FAST_FUNC get_ug_id(const char *s,
104 long FAST_FUNC (*xname2id)(const char *))
Bernhard Reutner-Fischerc5280e82005-09-20 21:09:31 +0000105{
106 unsigned long r;
Bernhard Reutner-Fischerc5280e82005-09-20 21:09:31 +0000107
Denis Vlasenkobecd8c52006-12-01 21:34:20 +0000108 r = bb_strtoul(s, NULL, 10);
109 if (errno)
Denis Vlasenko9a44c4f2006-12-28 05:44:47 +0000110 return xname2id(s);
Bernhard Reutner-Fischerc5280e82005-09-20 21:09:31 +0000111 return r;
112}
Denys Vlasenkocffe28e2013-11-26 13:46:18 +0100113
114/* Experimental "mallocing" API.
115 * The goal is nice: "we want to support a case when "guests" group is very large"
116 * but the code is butt-ugly.
117 */
118#if 0
119static char *find_latest(char last, char *cp)
120{
121 if (!cp)
122 return last;
123 cp += strlen(cp) + 1;
124 if (last < cp)
125 last = cp;
126 return last;
127}
128
129struct group* FAST_FUNC xmalloc_getgrnam(const char *name)
130{
131 struct {
132 struct group gr;
133 // May still be not enough!
134 char buf[64*1024 - sizeof(struct group) - 16];
135 } *s;
136 struct group *grp;
137 int r;
138 char *last;
139 char **gr_mem;
140
141 s = xmalloc(sizeof(*s));
142 r = getgrnam_r(name, &s->gr, s->buf, sizeof(s->buf), &grp);
143 if (!grp) {
144 free(s);
145 return grp;
146 }
147 last = find_latest(s->buf, grp->gr_name);
148 last = find_latest(last, grp->gr_passwd);
149 gr_mem = grp->gr_mem;
150 while (*gr_mem)
151 last = find_latest(last, *gr_mem++);
152 gr_mem++; /* points past NULL */
153 if (last < (char*)gr_mem)
154 last = (char*)gr_mem;
155//FIXME: what if we get not only truncated, but also moved here?
156// grp->gr_name pointer and friends are invalid now!!!
157 s = xrealloc(s, last - (char*)s);
158 return grp;
159}
160#endif