]> git.ipfire.org Git - thirdparty/util-linux.git/blame - lib/pwdutils.c
Merge branch 'lsclocks/relative-time' of https://github.com/t-8ch/util-linux
[thirdparty/util-linux.git] / lib / pwdutils.c
CommitLineData
3836cd2d
KZ
1/*
2 * No copyright is claimed. This code is in the public domain; do with
3 * it what you wish.
4 */
4f5f35fc 5#include <stdlib.h>
0a002b61 6#include <assert.h>
4f5f35fc
KZ
7
8#include "c.h"
9#include "pwdutils.h"
10#include "xalloc.h"
11
12/* Returns allocated passwd and allocated pwdbuf to store passwd strings
13 * fields. In case of error returns NULL and set errno, for unknown user set
14 * errno to EINVAL
15 */
16struct passwd *xgetpwnam(const char *username, char **pwdbuf)
17{
18 struct passwd *pwd = NULL, *res = NULL;
19 int rc;
20
0a002b61
ÉN
21 assert(pwdbuf);
22 assert(username);
4f5f35fc
KZ
23
24 *pwdbuf = xmalloc(UL_GETPW_BUFSIZ);
25 pwd = xcalloc(1, sizeof(struct passwd));
26
27 errno = 0;
28 rc = getpwnam_r(username, pwd, *pwdbuf, UL_GETPW_BUFSIZ, &res);
29 if (rc != 0) {
30 errno = rc;
31 goto failed;
32 }
33 if (!res) {
34 errno = EINVAL;
35 goto failed;
36 }
37 return pwd;
38failed:
39 free(pwd);
40 free(*pwdbuf);
41 return NULL;
42}
43
dc96ca29
MHB
44/* Returns allocated group and allocated grpbuf to store group strings
45 * fields. In case of error returns NULL and set errno, for unknown group set
46 * errno to EINVAL
47 */
48struct group *xgetgrnam(const char *groupname, char **grpbuf)
49{
50 struct group *grp = NULL, *res = NULL;
51 int rc;
52
0a002b61
ÉN
53 assert(grpbuf);
54 assert(groupname);
dc96ca29
MHB
55
56 *grpbuf = xmalloc(UL_GETPW_BUFSIZ);
57 grp = xcalloc(1, sizeof(struct group));
58
59 errno = 0;
60 rc = getgrnam_r(groupname, grp, *grpbuf, UL_GETPW_BUFSIZ, &res);
61 if (rc != 0) {
62 errno = rc;
63 goto failed;
64 }
65 if (!res) {
66 errno = EINVAL;
67 goto failed;
68 }
69 return grp;
70failed:
71 free(grp);
72 free(*grpbuf);
73 return NULL;
74}
75
cd083615
QR
76struct passwd *xgetpwuid(uid_t uid, char **pwdbuf)
77{
78 struct passwd *pwd = NULL, *res = NULL;
79 int rc;
80
0a002b61 81 assert(pwdbuf);
cd083615
QR
82
83 *pwdbuf = xmalloc(UL_GETPW_BUFSIZ);
84 pwd = xcalloc(1, sizeof(struct passwd));
85
86 errno = 0;
87 rc = getpwuid_r(uid, pwd, *pwdbuf, UL_GETPW_BUFSIZ, &res);
88 if (rc != 0) {
89 errno = rc;
90 goto failed;
91 }
92 if (!res) {
93 errno = EINVAL;
94 goto failed;
95 }
96 return pwd;
97failed:
98 free(pwd);
99 free(*pwdbuf);
100 return NULL;
101}
102
1742c8d8
KZ
103char *xgetlogin(void)
104{
105 struct passwd *pw = NULL;
106 uid_t ruid;
1742c8d8
KZ
107
108 /* GNU Hurd implementation has an extension where a process can exist in a
109 * non-conforming environment, and thus be outside the realms of POSIX
110 * process identifiers; on this platform, getuid() fails with a status of
111 * (uid_t)(-1) and sets errno if a program is run from a non-conforming
112 * environment.
113 *
114 * http://austingroupbugs.net/view.php?id=511
3386b92e
ÉN
115 *
116 * The same implementation is useful for other systems, since getlogin(3)
117 * shouldn't be used as actual identification.
1742c8d8
KZ
118 */
119 errno = 0;
120 ruid = getuid();
121
122 if (errno == 0)
123 pw = getpwuid(ruid);
124 if (pw && pw->pw_name && *pw->pw_name)
125 return xstrdup(pw->pw_name);
126
127 return NULL;
128}
4f5f35fc
KZ
129
130#ifdef TEST_PROGRAM
131int main(int argc, char *argv[])
132{
1742c8d8 133 char *buf = NULL;
4f5f35fc
KZ
134 struct passwd *pwd = NULL;
135
136 if (argc != 2) {
137 fprintf(stderr, "usage: %s <username>\n", argv[0]);
138 return EXIT_FAILURE;
139 }
140
1742c8d8 141 pwd = xgetpwnam(argv[1], &buf);
4f5f35fc
KZ
142 if (!pwd)
143 err(EXIT_FAILURE, "failed to get %s pwd entry", argv[1]);
144
145 printf("Username: %s\n", pwd->pw_name);
146 printf("UID: %d\n", pwd->pw_uid);
147 printf("HOME: %s\n", pwd->pw_dir);
148 printf("GECO: %s\n", pwd->pw_gecos);
149
150 free(pwd);
1742c8d8
KZ
151 free(buf);
152
153 printf("Current: %s\n", (buf = xgetlogin()));
154 free(buf);
155
4f5f35fc
KZ
156 return EXIT_SUCCESS;
157}
158#endif /* TEST_PROGRAM */