32c7dc0 |
Jamozed |
2020-07-06 22:43:09 |
0
|
// id.c, version 0.1.1 |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
1
|
// OMKOV coreutils implementation of POSIX id |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
2
|
// Copyright (C) 2020, Jakob Wakeling |
e2140ec |
Jamozed |
2022-03-06 15:27:45 |
3
|
// MIT Licence |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
4
|
|
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
5
|
/* |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
6
|
TODO Fix memory leak when listing supplementary groups (may be unfixable) |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
7
|
*/ |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
8
|
|
b181413 |
Jamozed |
2022-02-05 22:32:00 |
9
|
#include "util/error.h" |
b181413 |
Jamozed |
2022-02-05 22:32:00 |
10
|
#include "util/optget.h" |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
11
|
|
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
12
|
#include <grp.h> |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
13
|
#include <pwd.h> |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
14
|
#include <sys/types.h> |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
15
|
#include <unistd.h> |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
16
|
|
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
17
|
#include <stdbool.h> |
30cf081 |
Jamozed |
2020-08-28 23:01:02 |
18
|
#include <stdio.h> |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
19
|
#include <stdlib.h> |
30cf081 |
Jamozed |
2020-08-28 23:01:02 |
20
|
#include <string.h> |
32c7dc0 |
Jamozed |
2020-07-06 22:43:09 |
21
|
|
32c7dc0 |
Jamozed |
2020-07-06 22:43:09 |
22
|
#define VERSION "0.1.1" |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
23
|
|
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
24
|
typedef struct passwd pwd_t; |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
25
|
typedef struct group grp_t; |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
26
|
|
30cf081 |
Jamozed |
2020-08-28 23:01:02 |
27
|
static struct lop lops[] = { |
30cf081 |
Jamozed |
2020-08-28 23:01:02 |
28
|
{ "help", ARG_NUL, 256 }, |
30cf081 |
Jamozed |
2020-08-28 23:01:02 |
29
|
{ "version", ARG_NUL, 257 }, |
30cf081 |
Jamozed |
2020-08-28 23:01:02 |
30
|
{ NULL, 0, 0 } |
30cf081 |
Jamozed |
2020-08-28 23:01:02 |
31
|
}; |
30cf081 |
Jamozed |
2020-08-28 23:01:02 |
32
|
|
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
33
|
static char mode; |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
34
|
static bool nflag; |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
35
|
static bool rflag; |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
36
|
|
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
37
|
static inline void id(uid_t uid, uid_t euid, gid_t gid, gid_t egid); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
38
|
static inline void groups(const char *user, gid_t gid, gid_t egid); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
39
|
|
30cf081 |
Jamozed |
2020-08-28 23:01:02 |
40
|
static void hlp(void); |
30cf081 |
Jamozed |
2020-08-28 23:01:02 |
41
|
static void ver(void); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
42
|
|
32c7dc0 |
Jamozed |
2020-07-06 22:43:09 |
43
|
int main(int ac, char *av[]) { A0 = av[0]; |
30cf081 |
Jamozed |
2020-08-28 23:01:02 |
44
|
struct opt opt = OPTGET_INIT; opt.str = "Ggnru"; opt.lops = lops; |
30cf081 |
Jamozed |
2020-08-28 23:01:02 |
45
|
for (int o; (o = optget(&opt, av, 1)) != -1;) switch (o) { |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
46
|
case 'G': case 'g': case 'u': { |
32c7dc0 |
Jamozed |
2020-07-06 22:43:09 |
47
|
if (mode) { error(1, "invalid option combination"); } |
4fd512b |
Jamozed |
2020-06-28 00:02:14 |
48
|
else { mode = (char)o; } break; |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
49
|
} |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
50
|
case 'n': { nflag = true; break; } |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
51
|
case 'r': { rflag = true; break; } |
30cf081 |
Jamozed |
2020-08-28 23:01:02 |
52
|
case 256: { hlp(); return 0; } |
30cf081 |
Jamozed |
2020-08-28 23:01:02 |
53
|
case 257: { ver(); return 0; } |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
54
|
default: { return 1; } |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
55
|
} |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
56
|
|
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
57
|
if (!mode && (nflag || rflag)) { |
32c7dc0 |
Jamozed |
2020-07-06 22:43:09 |
58
|
error(1, "options 'n' and 'r' require 'G', 'g', or 'u'"); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
59
|
} |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
60
|
|
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
61
|
uid_t uid, euid; gid_t gid, egid; |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
62
|
|
32c7dc0 |
Jamozed |
2020-07-06 22:43:09 |
63
|
if (opt.ind == ac) { |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
64
|
uid = getuid(); euid = geteuid(); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
65
|
gid = getgid(); egid = getegid(); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
66
|
id (uid, euid, gid, egid); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
67
|
} |
32c7dc0 |
Jamozed |
2020-07-06 22:43:09 |
68
|
else for (char **p = &av[opt.ind]; *p; ++p) { |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
69
|
pwd_t *pwd; |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
70
|
|
32c7dc0 |
Jamozed |
2020-07-06 22:43:09 |
71
|
if (!(pwd = getpwnam(*p))) { error(1, "%s: invalid user", *p); } |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
72
|
|
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
73
|
uid = euid = pwd->pw_uid; |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
74
|
gid = egid = pwd->pw_gid; |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
75
|
id (uid, euid, gid, egid); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
76
|
} |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
77
|
|
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
78
|
return 0; |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
79
|
} |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
80
|
|
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
81
|
static inline void id(uid_t uid, uid_t euid, gid_t gid, gid_t egid) { |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
82
|
pwd_t *pwd; grp_t *grp; |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
83
|
|
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
84
|
if (mode == 'G') { |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
85
|
pwd = getpwuid(uid); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
86
|
groups(pwd->pw_name, gid, egid); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
87
|
} |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
88
|
else if (mode == 'g') { |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
89
|
grp = getgrgid(rflag ? gid : egid); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
90
|
nflag ? fputs(grp->gr_name, stdout) : printf("%u", grp->gr_gid); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
91
|
} |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
92
|
else if (mode == 'u') { |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
93
|
pwd = getpwuid(rflag ? uid : euid); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
94
|
nflag ? fputs(pwd->pw_name, stdout) : printf("%u", pwd->pw_uid); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
95
|
} |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
96
|
else { |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
97
|
pwd = getpwuid(uid); grp = getgrgid(gid); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
98
|
printf("uid=%u(%s) gid=%u(%s) ", uid, pwd->pw_name, gid, grp->gr_name); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
99
|
if (uid != euid) { |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
100
|
pwd = getpwuid(euid); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
101
|
printf("euid=%u(%s) ", euid, pwd->pw_name); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
102
|
pwd = getpwuid(uid); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
103
|
} |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
104
|
if (gid != egid) { |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
105
|
grp = getgrgid(egid); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
106
|
printf("egid=%u(%s) ", egid, grp->gr_name); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
107
|
} |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
108
|
fputs("groups=", stdout); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
109
|
groups(pwd->pw_name, gid, egid); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
110
|
} |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
111
|
fputc('\n', stdout); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
112
|
|
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
113
|
return; |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
114
|
} |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
115
|
|
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
116
|
static inline void groups(const char *user, gid_t gid, gid_t egid) { |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
117
|
grp_t *grp = getgrgid(gid); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
118
|
if (mode) { nflag ? fputs(grp->gr_name, stdout) : printf("%u", gid); } |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
119
|
else { printf("%u(%s)", gid, grp->gr_name); } |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
120
|
|
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
121
|
if (gid != egid) { |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
122
|
grp = getgrgid(egid); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
123
|
if (mode) { nflag ? printf(" %s", grp->gr_name) : printf(" %u", egid); } |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
124
|
else { printf(",%u(%s)", egid, grp->gr_name); } |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
125
|
} |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
126
|
|
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
127
|
setgrent(); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
128
|
while ((grp = getgrent()) != NULL) { |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
129
|
if (grp->gr_gid == gid || grp->gr_gid == egid) { continue; } |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
130
|
for (int i = 0; grp->gr_mem[i]; ++i) { |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
131
|
if (strcmp(grp->gr_mem[i], user) == 0) { |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
132
|
if (mode) { nflag ? printf(" %s", grp->gr_name) : |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
133
|
printf(" %u", grp->gr_gid); } |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
134
|
else { printf(",%u(%s)", grp->gr_gid, grp->gr_name); } |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
135
|
} |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
136
|
} |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
137
|
} |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
138
|
endgrent(); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
139
|
|
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
140
|
return; |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
141
|
} |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
142
|
|
30cf081 |
Jamozed |
2020-08-28 23:01:02 |
143
|
static void hlp(void) { |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
144
|
puts("id - return user identity\n"); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
145
|
puts("usage: id [-G|-g|-u] [-nr] [user...]\n"); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
146
|
puts("options:"); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
147
|
puts(" -G Output all group IDs"); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
148
|
puts(" -g Output only the effective group ID"); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
149
|
puts(" -n Output names of groups and users instead of their IDs"); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
150
|
puts(" -r Output the real ID instead of the effective ID"); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
151
|
puts(" -u Output only the effective user ID"); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
152
|
puts(" --help Display help information"); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
153
|
puts(" --version Display version information"); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
154
|
} |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
155
|
|
30cf081 |
Jamozed |
2020-08-28 23:01:02 |
156
|
static void ver(void) { |
32c7dc0 |
Jamozed |
2020-07-06 22:43:09 |
157
|
puts("OMKOV coreutils id, version " VERSION); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
158
|
puts("Copyright (C) 2020, Jakob Wakeling"); |
e2140ec |
Jamozed |
2022-03-06 15:27:45 |
159
|
puts("MIT Licence (https://opensource.org/licenses/MIT)"); |
8b4f999 |
Jamozed |
2020-06-27 14:00:03 |
160
|
} |
|
|
|
161
|
|