Bug Summary

File:src/usr.sbin/tokenadm/tokenadm.c
Warning:line 81, column 2
Value stored to 'pmode' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name tokenadm.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -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 -fno-rounding-math -mconstructor-aliases -munwind-tables -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.sbin/tokenadm/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/usr.sbin/tokenadm/../../libexec/login_token -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.sbin/tokenadm/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -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/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/usr.sbin/tokenadm/tokenadm.c
1/* $OpenBSD: tokenadm.c,v 1.12 2016/03/22 00:06:55 bluhm Exp $ */
2
3/*-
4 * Copyright (c) 1995 Migration Associates Corp. All Rights Reserved
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Berkeley Software Design,
17 * Inc.
18 * 4. The name of Berkeley Software Design, Inc. may not be used to endorse
19 * or promote products derived from this software without specific prior
20 * written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY BERKELEY SOFTWARE DESIGN, INC. ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL BERKELEY SOFTWARE DESIGN, INC. BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 *
34 * BSDI $From: tokenadm.c,v 1.2 1996/10/17 00:54:28 prb Exp $
35 */
36
37#include <sys/signal.h>
38#include <sys/resource.h>
39#include <sys/time.h>
40
41#include <err.h>
42#include <errno(*__errno()).h>
43#include <stdio.h>
44#include <syslog.h>
45#include <stdlib.h>
46#include <unistd.h>
47#include <limits.h>
48#include <string.h>
49
50#include "token.h"
51#include "tokendb.h"
52
53
54typedef enum { LIST, ENABLE, DISABLE, REMOVE, MODECH } what_t;
55typedef enum {
56 NOBANNER = 0x01,
57 TERSE = 0x02,
58 ENONLY = 0x04,
59 DISONLY = 0x08,
60 ONECOL = 0x10,
61 REVERSE = 0x20
62} how_t;
63
64static int force_unlock(char *);
65static int process_record(char *, unsigned, unsigned);
66static int process_modes(char *, unsigned, unsigned);
67static void print_record(TOKENDB_Rec *, how_t);
68
69extern int
70main(int argc, char **argv)
71{
72 int c, errors;
73 u_int emode, dmode, pmode;
74 struct rlimit cds;
75 what_t what;
76 how_t how;
77 TOKENDB_Rec tokenrec;
78
79 what = LIST;
80 emode = dmode = 0;
81 pmode = 0;
Value stored to 'pmode' is never read
82 errors = 0;
83 how = 0;
84
85 (void)signal(SIGQUIT3, SIG_IGN(void (*)(int))1);
86 (void)signal(SIGINT2, SIG_IGN(void (*)(int))1);
87 (void)setpriority(PRIO_PROCESS0, 0, 0);
88
89 openlog(NULL((void *)0), LOG_ODELAY0x04, LOG_AUTH(4<<3));
90
91 /*
92 * Make sure we never dump core as we might have a
93 * valid user shared-secret in memory.
94 */
95
96 cds.rlim_cur = 0;
97 cds.rlim_max = 0;
98 if (setrlimit(RLIMIT_CORE4, &cds) < 0)
99 syslog(LOG_ERR3, "couldn't set core dump size to 0: %m");
100
101 if (pledge("stdio rpath wpath cpath fattr flock getpw", NULL((void *)0)) == -1)
102 err(1, "pledge");
103
104 if (token_init(argv[0]) < 0) {
105 syslog(LOG_ERR3, "unknown token type");
106 errx(1, "unknown token type");
107 }
108
109 while ((c = getopt(argc, argv, "BDERT1dem:r")) != -1)
110 switch (c) {
111 case 'B':
112 if (what != LIST)
113 goto usage;
114 how |= NOBANNER;
115 break;
116 case 'T':
117 if (what != LIST)
118 goto usage;
119 how |= TERSE;
120 break;
121 case '1':
122 if (what != LIST)
123 goto usage;
124 how |= ONECOL;
125 break;
126 case 'D':
127 if (what != LIST)
128 goto usage;
129 how |= DISONLY;
130 break;
131 case 'E':
132 if (what != LIST)
133 goto usage;
134 how |= ENONLY;
135 break;
136 case 'R':
137 if (what != LIST)
138 goto usage;
139 how |= REVERSE;
140 break;
141 case 'd':
142 if (what != LIST || how)
143 goto usage;
144 what = DISABLE;
145 break;
146 case 'e':
147 if (what != LIST || how)
148 goto usage;
149 what = ENABLE;
150 break;
151 case 'r':
152 if (what != LIST || emode || dmode || how)
153 goto usage;
154 what = REMOVE;
155 break;
156 case 'm':
157 if (what == REMOVE || how)
158 goto usage;
159 if (*optarg == '-') {
160 if ((c = token_mode(optarg+1)) == 0)
161 errx(1, "%s: unknown mode", optarg+1);
162 dmode |= c;
163 } else {
164 if ((c = token_mode(optarg)) == 0)
165 errx(1, "%s: unknown mode", optarg);
166 emode |= c;
167 }
168 break;
169 default:
170 goto usage;
171 }
172
173 if (what == LIST && (dmode || emode))
174 what = MODECH;
175
176 if (what == LIST) {
177 if ((how & (ENONLY|DISONLY)) == 0)
178 how |= ENONLY|DISONLY;
179 if (!(how & NOBANNER)) {
180 if ((how & (TERSE|ONECOL)) == (TERSE|ONECOL)) {
181 printf("User\n");
182 printf("----------------\n");
183 } else if (how & (TERSE)) {
184 printf("User ");
185 printf("User ");
186 printf("User ");
187 printf("User\n");
188 printf("---------------- ");
189 printf("---------------- ");
190 printf("---------------- ");
191 printf("----------------\n");
192 } else {
193 printf("User Status Modes\n");
194 printf("---------------- -------- -----\n");
195 }
196 }
197
198 if (optind >= argc) {
199 if (tokendb_firstrec(how & REVERSE, &tokenrec))
200 exit(0);
201 do
202 print_record(&tokenrec, how);
203 while (tokendb_nextrec(how & REVERSE, &tokenrec) == 0);
204 print_record(NULL((void *)0), how);
205 exit(0);
206 }
207 }
208
209 if (optind >= argc) {
210usage:
211 fprintf(stderr(&__sF[2]),
212 "usage: %sadm [-1BDdEeRrT] [-m [-]mode] [user ...]\n",
213 tt->name);
214 exit(1);
215 }
216
217 argv += optind - 1;
218 while (*++argv)
219 switch (what) {
220 case LIST:
221 if (tokendb_getrec(*argv, &tokenrec)) {
222 printf("%s: no such user\n", *argv);
223 break;
224 }
225 print_record(&tokenrec, how);
226 break;
227 case REMOVE:
228 if (tokendb_delrec(*argv)) {
229 warnx("%s: could not remove", *argv);
230 errors++;
231 }
232 break;
233 case DISABLE:
234 if (process_record(*argv, ~TOKEN_ENABLED0x2, 0)) {
235 warnx("%s: could not disable", *argv);
236 ++errors;
237 }
238 if (emode || dmode)
239 goto modech;
240 break;
241 case ENABLE:
242 if (process_record(*argv, ~TOKEN_ENABLED0x2, TOKEN_ENABLED0x2)) {
243 warnx("%s: could not enable", *argv);
244 ++errors;
245 }
246 if (emode || dmode)
247 goto modech;
248 break;
249 modech:
250 case MODECH:
251 if (process_modes(*argv, ~dmode, emode)) {
252 warnx("%s: could not change modes", *argv);
253 ++errors;
254 }
255 break;
256 }
257
258 if (what == LIST)
259 print_record(NULL((void *)0), how);
260
261 exit(errors);
262}
263
264/*
265 * Process a user record
266 */
267
268static int
269process_record(char *username, unsigned and_mask, unsigned or_mask)
270{
271 int count = 0;
272 TOKENDB_Rec tokenrec;
273
274retry:
275 switch (tokendb_lockrec(username, &tokenrec, TOKEN_LOCKED0x1)) {
276 case 0:
277 tokenrec.flags &= and_mask;
278 tokenrec.flags |= or_mask;
279 tokenrec.flags &= ~TOKEN_LOCKED0x1;
280 if (!tokendb_putrec(username, &tokenrec))
281 return (0);
282 else
283 return (-1);
284 case 1:
285 sleep(1);
286 if (count++ < 60)
287 goto retry;
288 if (force_unlock(username))
289 return (1);
290 goto retry;
291
292 case ENOENT2:
293 warnx("%s: nonexistent user", username);
294 return (1);
295 default:
296 return (-1);
297 }
298}
299
300static int
301process_modes(char *username, unsigned and_mask, unsigned or_mask)
302{
303 int count = 0;
304 TOKENDB_Rec tokenrec;
305
306retry:
307 switch (tokendb_lockrec(username, &tokenrec, TOKEN_LOCKED0x1)) {
308 case 0:
309 tokenrec.mode &= and_mask;
310 tokenrec.mode |= or_mask;
311 /*
312 * When ever we set up for rim mode (even if we are
313 * already set up for it) reset the rim key
314 */
315 if (or_mask & TOKEN_RIM0x8)
316 memset(tokenrec.rim, 0, sizeof(tokenrec.rim));
317 tokenrec.flags &= ~TOKEN_LOCKED0x1;
318 if (!tokendb_putrec(username, &tokenrec))
319 return (0);
320 else
321 return (-1);
322 case 1:
323 sleep(1);
324 if (count++ < 60)
325 goto retry;
326 if (force_unlock(username))
327 return (1);
328 goto retry;
329
330 case ENOENT2:
331 warnx("%s: nonexistent user", username);
332 return (1);
333 default:
334 return (-1);
335 }
336}
337
338/*
339 * Force remove a user record-level lock.
340 */
341
342static int
343force_unlock(char *username)
344{
345 TOKENDB_Rec tokenrec;
346
347 if (tokendb_getrec(username, &tokenrec))
348 return (-1);
349
350 tokenrec.flags &= ~TOKEN_LOCKED0x1;
351 tokenrec.flags &= ~TOKEN_LOGIN0x4;
352
353 if (tokendb_putrec(username, &tokenrec))
354 return (1);
355
356 return (0);
357}
358
359/*
360 * Print a database record according to user a specified format
361 */
362
363static void
364print_record(TOKENDB_Rec *rec, how_t how)
365{
366 static int count = 0;
367 int i;
368
369 if (rec == NULL((void *)0)) {
370 if ((count & 3) && (how & (TERSE|ONECOL)) == TERSE)
371 printf("\n");
372 return;
373 }
374
375 if (rec->flags & TOKEN_ENABLED0x2) {
376 if ((how & ENONLY) == 0)
377 return;
378 } else {
379 if ((how & DISONLY) == 0)
380 return;
381 }
382
383 switch (how & (TERSE|ONECOL)) {
384 case 0:
385 case ONECOL:
386 printf("%-16s %-8s", rec->uname,
387 rec->flags & TOKEN_ENABLED0x2 ? "enabled" : "disabled");
388
389 for (i = 1; i; i <<= 1)
390 if (rec->mode & i)
391 printf(" %s", token_getmode(i));
392 printf("\n");
393 break;
394 case TERSE:
395 if ((count & 3) == 3)
396 printf("%s\n", rec->uname);
397 else
398 printf("%-16s ", rec->uname);
399 break;
400 case TERSE|ONECOL:
401 printf("%s\n", rec->uname);
402 break;
403 }
404 ++count;
405}