blob: d5e651cc8a64cc99cfe6fee96fb8a090325c9620 [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
maxwen27116ba2015-08-14 21:41:28 +020018struct passwd* FAST_FUNC safegetpwnam(const char *name)
Denis Vlasenkod7a805e2008-12-03 19:05:55 +000019{
20 struct passwd *pw = getpwnam(name);
maxwen27116ba2015-08-14 21:41:28 +020021#ifdef __BIONIC__
22 if (pw && !pw->pw_passwd) {
23 pw->pw_passwd = "";
24 }
25#endif
26 return pw;
27}
28
29struct passwd* FAST_FUNC safegetpwuid(uid_t uid)
30{
31 struct passwd *pw = getpwuid(uid);
32#ifdef __BIONIC__
33 if (pw && !pw->pw_passwd) {
34 pw->pw_passwd = "";
35 }
36#endif
37 return pw;
38}
39
40struct passwd* FAST_FUNC xgetpwnam(const char *name)
41{
42 struct passwd *pw = safegetpwnam(name);
Denis Vlasenkod7a805e2008-12-03 19:05:55 +000043 if (!pw)
44 bb_error_msg_and_die("unknown user %s", name);
45 return pw;
46}
47
Denis Vlasenko15437e32008-12-05 16:23:06 +000048struct group* FAST_FUNC xgetgrnam(const char *name)
49{
50 struct group *gr = getgrnam(name);
51 if (!gr)
52 bb_error_msg_and_die("unknown group %s", name);
53 return gr;
54}
55
Denis Vlasenko0c68a872008-12-02 22:56:59 +000056struct passwd* FAST_FUNC xgetpwuid(uid_t uid)
Denis Vlasenkobecd8c52006-12-01 21:34:20 +000057{
maxwen27116ba2015-08-14 21:41:28 +020058 struct passwd *pw = safegetpwuid(uid);
Denis Vlasenko0c68a872008-12-02 22:56:59 +000059 if (!pw)
60 bb_error_msg_and_die("unknown uid %u", (unsigned)uid);
61 return pw;
Denis Vlasenkobecd8c52006-12-01 21:34:20 +000062}
63
Denis Vlasenko0c68a872008-12-02 22:56:59 +000064struct group* FAST_FUNC xgetgrgid(gid_t gid)
Denis Vlasenko3734b942007-07-27 11:20:10 +000065{
Denis Vlasenko0c68a872008-12-02 22:56:59 +000066 struct group *gr = getgrgid(gid);
67 if (!gr)
68 bb_error_msg_and_die("unknown gid %u", (unsigned)gid);
69 return gr;
Bernhard Reutner-Fischerc5280e82005-09-20 21:09:31 +000070}
Bernhard Reutner-Fischerc5280e82005-09-20 21:09:31 +000071
Denis Vlasenko0c68a872008-12-02 22:56:59 +000072char* FAST_FUNC xuid2uname(uid_t uid)
Bernhard Reutner-Fischerc5280e82005-09-20 21:09:31 +000073{
Denis Vlasenko0c68a872008-12-02 22:56:59 +000074 struct passwd *pw = xgetpwuid(uid);
75 return pw->pw_name;
Bernhard Reutner-Fischerc5280e82005-09-20 21:09:31 +000076}
Bernhard Reutner-Fischerc5280e82005-09-20 21:09:31 +000077
Denis Vlasenko0c68a872008-12-02 22:56:59 +000078char* FAST_FUNC xgid2group(gid_t gid)
79{
80 struct group *gr = xgetgrgid(gid);
81 return gr->gr_name;
82}
83
84char* FAST_FUNC uid2uname(uid_t uid)
85{
86 struct passwd *pw = getpwuid(uid);
87 return (pw) ? pw->pw_name : NULL;
88}
89
90char* FAST_FUNC gid2group(gid_t gid)
91{
92 struct group *gr = getgrgid(gid);
93 return (gr) ? gr->gr_name : NULL;
94}
95
Denys Vlasenko7d65abe2011-03-01 16:27:13 +010096char* FAST_FUNC uid2uname_utoa(uid_t uid)
Denis Vlasenko0c68a872008-12-02 22:56:59 +000097{
98 char *name = uid2uname(uid);
99 return (name) ? name : utoa(uid);
100}
101
Denys Vlasenko7d65abe2011-03-01 16:27:13 +0100102char* FAST_FUNC gid2group_utoa(gid_t gid)
Denis Vlasenko0c68a872008-12-02 22:56:59 +0000103{
104 char *name = gid2group(gid);
105 return (name) ? name : utoa(gid);
106}
107
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +0000108long FAST_FUNC xuname2uid(const char *name)
Bernhard Reutner-Fischerc5280e82005-09-20 21:09:31 +0000109{
110 struct passwd *myuser;
111
Denis Vlasenkod7a805e2008-12-03 19:05:55 +0000112 myuser = xgetpwnam(name);
Bernhard Reutner-Fischerc5280e82005-09-20 21:09:31 +0000113 return myuser->pw_uid;
114}
Bernhard Reutner-Fischerc5280e82005-09-20 21:09:31 +0000115
Denis Vlasenko0c68a872008-12-02 22:56:59 +0000116long FAST_FUNC xgroup2gid(const char *name)
117{
118 struct group *mygroup;
119
Denis Vlasenko15437e32008-12-05 16:23:06 +0000120 mygroup = xgetgrnam(name);
Denis Vlasenko0c68a872008-12-02 22:56:59 +0000121 return mygroup->gr_gid;
122}
123
Denis Vlasenkodefc1ea2008-06-27 02:52:20 +0000124unsigned long FAST_FUNC get_ug_id(const char *s,
125 long FAST_FUNC (*xname2id)(const char *))
Bernhard Reutner-Fischerc5280e82005-09-20 21:09:31 +0000126{
127 unsigned long r;
Bernhard Reutner-Fischerc5280e82005-09-20 21:09:31 +0000128
Denis Vlasenkobecd8c52006-12-01 21:34:20 +0000129 r = bb_strtoul(s, NULL, 10);
130 if (errno)
Denis Vlasenko9a44c4f2006-12-28 05:44:47 +0000131 return xname2id(s);
Bernhard Reutner-Fischerc5280e82005-09-20 21:09:31 +0000132 return r;
133}
maxwen27116ba2015-08-14 21:41:28 +0200134
135/* Experimental "mallocing" API.
136 * The goal is nice: "we want to support a case when "guests" group is very large"
137 * but the code is butt-ugly.
138 */
139#if 0
140static char *find_latest(char last, char *cp)
141{
142 if (!cp)
143 return last;
144 cp += strlen(cp) + 1;
145 if (last < cp)
146 last = cp;
147 return last;
148}
149
150struct group* FAST_FUNC xmalloc_getgrnam(const char *name)
151{
152 struct {
153 struct group gr;
154 // May still be not enough!
155 char buf[64*1024 - sizeof(struct group) - 16];
156 } *s;
157 struct group *grp;
158 int r;
159 char *last;
160 char **gr_mem;
161
162 s = xmalloc(sizeof(*s));
163 r = getgrnam_r(name, &s->gr, s->buf, sizeof(s->buf), &grp);
164 if (!grp) {
165 free(s);
166 return grp;
167 }
168 last = find_latest(s->buf, grp->gr_name);
169 last = find_latest(last, grp->gr_passwd);
170 gr_mem = grp->gr_mem;
171 while (*gr_mem)
172 last = find_latest(last, *gr_mem++);
173 gr_mem++; /* points past NULL */
174 if (last < (char*)gr_mem)
175 last = (char*)gr_mem;
176//FIXME: what if we get not only truncated, but also moved here?
177// grp->gr_name pointer and friends are invalid now!!!
178 s = xrealloc(s, last - (char*)s);
179 return grp;
180}
181#endif