Bug Summary

File:src/usr.bin/id/id.c
Warning:line 213, column 28
Although the value stored to 'eid' is used in the enclosing expression, the value is never actually read from 'eid'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name id.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.bin/id/obj -resource-dir /usr/local/llvm16/lib/clang/16 -internal-isystem /usr/local/llvm16/lib/clang/16/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.bin/id/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fcf-protection=branch -fno-jump-tables -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/scan/2024-01-11-140451-98009-1 -x c /usr/src/usr.bin/id/id.c
1/* $OpenBSD: id.c,v 1.30 2023/05/30 16:44:16 op Exp $ */
2
3/*-
4 * Copyright (c) 1991, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#include <sys/types.h>
33#include <sys/socket.h> /* getrtable() lives here */
34
35#include <err.h>
36#include <errno(*__errno()).h>
37#include <grp.h>
38#include <pwd.h>
39#include <stdio.h>
40#include <stdlib.h>
41#include <string.h>
42#include <unistd.h>
43#include <limits.h>
44#include <login_cap.h>
45
46void current(void);
47void pretty(struct passwd *);
48void group(struct passwd *, int);
49void usage(void);
50void user(struct passwd *);
51struct passwd *
52 who(char *);
53
54int
55main(int argc, char *argv[])
56{
57 struct group *gr;
58 struct passwd *pw;
59 int ch, cflag, Gflag, gflag, nflag, pflag, Rflag, rflag, uflag;
60 uid_t uid;
61 gid_t gid;
62 const char *opts;
63
64 if (pledge("stdio getpw", NULL((void *)0)) == -1)
65 err(1, "pledge");
66
67 cflag = Gflag = gflag = nflag = pflag = Rflag = rflag = uflag = 0;
68
69 if (strcmp(getprogname(), "groups") == 0) {
70 Gflag = 1;
71 nflag = 1;
72 opts = "";
73 if (argc > 2)
74 usage();
75 } else if (strcmp(getprogname(), "whoami") == 0) {
76 uflag = 1;
77 nflag = 1;
78 opts = "";
79 if (argc > 1)
80 usage();
81 } else
82 opts = "cGgnpRru";
83
84 while ((ch = getopt(argc, argv, opts)) != -1)
85 switch(ch) {
86 case 'c':
87 cflag = 1;
88 break;
89 case 'G':
90 Gflag = 1;
91 break;
92 case 'g':
93 gflag = 1;
94 break;
95 case 'n':
96 nflag = 1;
97 break;
98 case 'p':
99 pflag = 1;
100 break;
101 case 'R':
102 Rflag = 1;
103 break;
104 case 'r':
105 rflag = 1;
106 break;
107 case 'u':
108 uflag = 1;
109 break;
110 default:
111 usage();
112 }
113 argc -= optind;
114 argv += optind;
115
116 switch (cflag + Gflag + gflag + pflag + Rflag + uflag) {
117 case 1:
118 break;
119 case 0:
120 if (!nflag && !rflag)
121 break;
122 /* FALLTHROUGH */
123 default:
124 usage();
125 }
126
127 if (strcmp(opts, "") != 0 && argc > 1)
128 usage();
129
130 if (Rflag) {
131 if (argc != 0)
132 usage();
133 printf("%d\n", getrtable());
134 exit(0);
135 }
136
137 pw = *argv ? who(*argv) : NULL((void *)0);
138
139 if (cflag) {
140 if (pw == NULL((void *)0))
141 pw = getpwuid(getuid());
142 if (pw != NULL((void *)0) && pw->pw_class != NULL((void *)0) && *pw->pw_class != '\0')
143 (void)printf("%s\n", pw->pw_class);
144 else
145 (void)printf("%s\n", LOGIN_DEFCLASS"default");
146 exit(0);
147 }
148
149 if (gflag) {
150 gid = pw ? pw->pw_gid : rflag ? getgid() : getegid();
151 if (nflag && (gr = getgrgid(gid)))
152 (void)printf("%s\n", gr->gr_name);
153 else
154 (void)printf("%u\n", gid);
155 exit(0);
156 }
157
158 if (uflag) {
159 uid = pw ? pw->pw_uid : rflag ? getuid() : geteuid();
160 if (nflag && (pw = getpwuid(uid)))
161 (void)printf("%s\n", pw->pw_name);
162 else
163 (void)printf("%u\n", uid);
164 exit(0);
165 }
166
167 if (Gflag) {
168 group(pw, nflag);
169 exit(0);
170 }
171
172 if (pflag) {
173 pretty(pw);
174 exit(0);
175 }
176
177 if (pw)
178 user(pw);
179 else
180 current();
181 exit(0);
182}
183
184void
185pretty(struct passwd *pw)
186{
187 struct group *gr;
188 uid_t eid, rid;
189 char *login;
190
191 if (pw) {
192 (void)printf("uid\t%s\n", pw->pw_name);
193 (void)printf("groups\t");
194 group(pw, 1);
195 } else {
196 if ((login = getlogin()) == NULL((void *)0))
197 err(1, "getlogin");
198
199 pw = getpwuid(rid = getuid());
200 if (pw == NULL((void *)0) || strcmp(login, pw->pw_name))
201 (void)printf("login\t%s\n", login);
202 if (pw)
203 (void)printf("uid\t%s\n", pw->pw_name);
204 else
205 (void)printf("uid\t%u\n", rid);
206
207 if ((eid = geteuid()) != rid) {
208 if ((pw = getpwuid(eid)))
209 (void)printf("euid\t%s\n", pw->pw_name);
210 else
211 (void)printf("euid\t%u\n", eid);
212 }
213 if ((rid = getgid()) != (eid = getegid())) {
Although the value stored to 'eid' is used in the enclosing expression, the value is never actually read from 'eid'
214 if ((gr = getgrgid(rid)))
215 (void)printf("rgid\t%s\n", gr->gr_name);
216 else
217 (void)printf("rgid\t%u\n", rid);
218 }
219 (void)printf("groups\t");
220 group(NULL((void *)0), 1);
221 }
222 if (pw != NULL((void *)0) && pw->pw_class != NULL((void *)0) && *pw->pw_class != '\0')
223 (void)printf("class\t%s\n", pw->pw_class);
224}
225
226void
227current(void)
228{
229 struct group *gr;
230 struct passwd *pw;
231 int cnt, ngroups;
232 uid_t uid, euid;
233 gid_t groups[NGROUPS_MAX16], gid, egid, lastgid;
234 char *prefix;
235
236 uid = getuid();
237 (void)printf("uid=%u", uid);
238 if ((pw = getpwuid(uid)))
239 (void)printf("(%s)", pw->pw_name);
240 if ((euid = geteuid()) != uid) {
241 (void)printf(" euid=%u", euid);
242 if ((pw = getpwuid(euid)))
243 (void)printf("(%s)", pw->pw_name);
244 }
245 gid = getgid();
246 (void)printf(" gid=%u", gid);
247 if ((gr = getgrgid(gid)))
248 (void)printf("(%s)", gr->gr_name);
249 if ((egid = getegid()) != gid) {
250 (void)printf(" egid=%u", egid);
251 if ((gr = getgrgid(egid)))
252 (void)printf("(%s)", gr->gr_name);
253 }
254 if ((ngroups = getgroups(NGROUPS_MAX16, groups))) {
255 for (prefix = " groups=", lastgid = (gid_t)-1, cnt = 0;
256 cnt < ngroups; prefix = ", ", lastgid = gid) {
257 gid = groups[cnt++];
258 if (lastgid == gid)
259 continue;
260 (void)printf("%s%u", prefix, gid);
261 if ((gr = getgrgid(gid)))
262 (void)printf("(%s)", gr->gr_name);
263 }
264 }
265 (void)printf("\n");
266}
267
268void
269user(struct passwd *pw)
270{
271 gid_t gid, groups[NGROUPS_MAX16 + 1];
272 int cnt, ngroups;
273 uid_t uid;
274 struct group *gr;
275 char *prefix;
276
277 uid = pw->pw_uid;
278 (void)printf("uid=%u(%s)", uid, pw->pw_name);
279 (void)printf(" gid=%u", pw->pw_gid);
280 if ((gr = getgrgid(pw->pw_gid)))
281 (void)printf("(%s)", gr->gr_name);
282 ngroups = NGROUPS_MAX16 + 1;
283 (void) getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups);
284 prefix = " groups=";
285 for (cnt = 0; cnt < ngroups;) {
286 gid = groups[cnt];
287 (void)printf("%s%u", prefix, gid);
288 prefix = ", ";
289 if ((gr = getgrgid(gid)))
290 (void)printf("(%s)", gr->gr_name);
291 /* Skip same gid entries. */
292 while (++cnt < ngroups && gid == groups[cnt])
293 ;
294 }
295 (void)printf("\n");
296}
297
298void
299group(struct passwd *pw, int nflag)
300{
301 int cnt, ngroups;
302 gid_t gid, groups[NGROUPS_MAX16 + 1];
303 struct group *gr;
304 char *prefix;
305
306 if (pw) {
307 ngroups = NGROUPS_MAX16 + 1;
308 (void) getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups);
309 } else {
310 groups[0] = getgid();
311 ngroups = getgroups(NGROUPS_MAX16, groups + 1) + 1;
312 }
313 prefix = "";
314 for (cnt = 0; cnt < ngroups;) {
315 gid = groups[cnt];
316 if (nflag) {
317 if ((gr = getgrgid(gid)))
318 (void)printf("%s%s", prefix, gr->gr_name);
319 else
320 (void)printf("%s%u", prefix, gid);
321 } else {
322 (void)printf("%s%u", prefix, gid);
323 }
324 prefix = " ";
325 /* Skip same gid entries. */
326 while (++cnt < ngroups && gid == groups[cnt])
327 ;
328 }
329 (void)printf("\n");
330}
331
332struct passwd *
333who(char *u)
334{
335 struct passwd *pw;
336 uid_t uid;
337 const char *errstr;
338
339 /*
340 * Translate user argument into a pw pointer. First, try to
341 * get it as specified. If that fails, try it as a number.
342 */
343 if ((pw = getpwnam(u)))
344 return(pw);
345 uid = strtonum(u, 0, UID_MAX0xffffffffU, &errstr);
346 if (!errstr && (pw = getpwuid(uid)))
347 return(pw);
348 errx(1, "%s: No such user", u);
349 /* NOTREACHED */
350}
351
352void
353usage(void)
354{
355 if (strcmp(getprogname(), "groups") == 0) {
356 (void)fprintf(stderr(&__sF[2]), "usage: groups [user]\n");
357 } else if (strcmp(getprogname(), "whoami") == 0) {
358 (void)fprintf(stderr(&__sF[2]), "usage: whoami\n");
359 } else {
360 (void)fprintf(stderr(&__sF[2]), "usage: id [user]\n");
361 (void)fprintf(stderr(&__sF[2]), " id -c [user]\n");
362 (void)fprintf(stderr(&__sF[2]), " id -G [-n] [user]\n");
363 (void)fprintf(stderr(&__sF[2]), " id -g [-nr] [user]\n");
364 (void)fprintf(stderr(&__sF[2]), " id -p [user]\n");
365 (void)fprintf(stderr(&__sF[2]), " id -R\n");
366 (void)fprintf(stderr(&__sF[2]), " id -u [-nr] [user]\n");
367 }
368 exit(1);
369}