Bug Summary

File:src/usr.sbin/ypserv/ypxfr/ypxfr.c
Warning:line 255, column 5
Value stored to 'status' 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 ypxfr.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/ypserv/ypxfr/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/usr.sbin/ypserv/ypxfr/../common -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.sbin/ypserv/ypxfr/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/ypserv/ypxfr/ypxfr.c
1/* $OpenBSD: ypxfr.c,v 1.39 2015/02/09 23:00:15 deraadt Exp $ */
2
3/*
4 * Copyright (c) 1994 Mats O Jansson <moj@stacken.kth.se>
5 * 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 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
17 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include <sys/types.h>
30#include <sys/stat.h>
31#include <sys/socket.h>
32
33#include <netinet/in.h>
34#include <arpa/inet.h>
35
36#include <stdio.h>
37#include <stdlib.h>
38#include <unistd.h>
39#include <fcntl.h>
40#include <string.h>
41#include <netdb.h>
42
43#include <rpc/rpc.h>
44#include <rpc/xdr.h>
45#include <rpcsvc/yp.h>
46#include <rpcsvc/ypclnt.h>
47
48#include "yplib_host.h"
49#include "yplog.h"
50#include "ypdb.h"
51#include "ypdef.h"
52
53DBM *db;
54
55static int
56ypxfr_foreach(u_long status, char *keystr, int keylen, char *valstr, int vallen,
57 void *data)
58{
59 datum key, val;
60
61 if (status == YP_NOMORE)
62 return(0);
63
64 keystr[keylen] = '\0';
65 valstr[vallen] = '\0';
66
67 key.dptr = keystr;
68 key.dsize = strlen(keystr);
69
70 val.dptr = valstr;
71 val.dsize = strlen(valstr);
72
73 ypdb_store(db, key, val, YPDB_INSERT0);
74 return 0;
75}
76
77static int
78get_local_ordernum(char *domain, char *map, u_int32_t *lordernum)
79{
80 char map_path[PATH_MAX1024], order[MAX_LAST_LEN10+1];
81 char order_key[] = YP_LAST_KEY"YP_LAST_MODIFIED";
82 struct stat finfo;
83 datum k, v;
84 int status;
85 DBM *db;
86
87 /* This routine returns YPPUSH_SUCC or YPPUSH_NODOM */
88
89 status = YPPUSH_SUCC;
90
91 snprintf(map_path, sizeof map_path, "%s/%s", YP_DB_PATH"/var/yp", domain);
92 if (!((stat(map_path, &finfo) == 0) && S_ISDIR(finfo.st_mode)((finfo.st_mode & 0170000) == 0040000))) {
93 fprintf(stderr(&__sF[2]), "ypxfr: domain %s not found locally\n",
94 domain);
95 status = YPPUSH_NODOM;
96 goto bail;
97 }
98
99 snprintf(map_path, sizeof map_path, "%s/%s/%s%s",
100 YP_DB_PATH"/var/yp", domain, map, YPDB_SUFFIX".db");
101 if (!(stat(map_path, &finfo) == 0)) {
102 status = YPPUSH_NOMAP;
103 goto bail;
104 }
105
106 snprintf(map_path, sizeof map_path, "%s/%s/%s",
107 YP_DB_PATH"/var/yp", domain, map);
108 db = ypdb_open(map_path, O_RDONLY0x0000, 0444);
109 if (db == NULL((void *)0)) {
110 status = YPPUSH_DBM;
111 goto bail;
112 }
113
114 k.dptr = (char *)&order_key;
115 k.dsize = YP_LAST_LEN(sizeof("YP_LAST_MODIFIED")-1);
116
117 v = ypdb_fetch(db, k);
118
119 if (v.dptr == NULL((void *)0)) {
120 *lordernum = 0;
121 } else {
122 strlcpy(order, v.dptr, sizeof order);
123 *lordernum = (u_int32_t)atol(order);
124 }
125
126 ypdb_close(db);
127bail:
128 if (status == YPPUSH_NOMAP || status == YPPUSH_DBM) {
129 *lordernum = 0;
130 status = YPPUSH_SUCC;
131 }
132 return (status);
133
134}
135
136static int
137get_remote_ordernum(CLIENT *client, char *domain, char *map,
138 u_int32_t lordernum, u_int32_t *rordernum)
139{
140 int status;
141
142 status = yp_order_host(client, domain, map, rordernum);
143
144 if (status == 0) {
145 if (*rordernum <= lordernum)
146 status = YPPUSH_AGE;
147 else
148 status = YPPUSH_SUCC;
149 }
150 return status;
151}
152
153static int
154get_map(CLIENT *client, char *domain, char *map,
155 struct ypall_callback *incallback)
156{
157 int status;
158
159 status = yp_all_host(client, domain, map, incallback);
160 if (status == 0 || status == YPERR_NOMORE8)
161 status = YPPUSH_SUCC;
162 else
163 status = YPPUSH_YPERR;
164 return (status);
165}
166
167static DBM *
168create_db(char *domain, char *map, char *temp_map)
169{
170 return ypdb_open_suf(temp_map, O_RDWR0x0002, 0444);
171}
172
173static int
174install_db(char *domain, char *map, char *temp_map)
175{
176 char db_name[PATH_MAX1024];
177
178 snprintf(db_name, sizeof db_name, "%s/%s/%s%s",
179 YP_DB_PATH"/var/yp", domain, map, YPDB_SUFFIX".db");
180 rename(temp_map, db_name);
181 return YPPUSH_SUCC;
182}
183
184static int
185add_order(DBM *db, u_int32_t ordernum)
186{
187 char datestr[11];
188 datum key, val;
189 char keystr[] = YP_LAST_KEY"YP_LAST_MODIFIED";
190 int status;
191
192 snprintf(datestr, sizeof datestr, "%010u", ordernum);
193
194 key.dptr = keystr;
195 key.dsize = strlen(keystr);
196
197 val.dptr = datestr;
198 val.dsize = strlen(datestr);
199
200 status = ypdb_store(db, key, val, YPDB_INSERT0);
201 if (status >= 0)
202 status = YPPUSH_SUCC;
203 else
204 status = YPPUSH_DBM;
205 return (status);
206}
207
208static int
209add_master(CLIENT *client, char *domain, char *map, DBM *db)
210{
211 char keystr[] = YP_MASTER_KEY"YP_MASTER_NAME", *master = NULL((void *)0);
212 datum key, val;
213 int status;
214
215 /* Get MASTER */
216 status = yp_master_host(client, domain, map, &master);
217
218 if (master != NULL((void *)0)) {
219 key.dptr = keystr;
220 key.dsize = strlen(keystr);
221
222 val.dptr = master;
223 val.dsize = strlen(master);
224
225 status = ypdb_store(db, key, val, YPDB_INSERT0);
226 if (status >= 0)
227 status = YPPUSH_SUCC;
228 else
229 status = YPPUSH_DBM;
230 }
231 return (status);
232}
233
234static int
235add_interdomain(CLIENT *client, char *domain, char *map, DBM *db)
236{
237 char keystr[] = YP_INTERDOMAIN_KEY"YP_INTERDOMAIN", *value;
238 int vallen, status;
239 datum k, v;
240
241 /* Get INTERDOMAIN */
242
243 k.dptr = keystr;
244 k.dsize = strlen(keystr);
245
246 status = yp_match_host(client, domain, map,
247 k.dptr, k.dsize, &value, &vallen);
248 if (status == 0 && value) {
249 v.dptr = value;
250 v.dsize = vallen;
251
252 if (v.dptr != NULL((void *)0)) {
253 status = ypdb_store(db, k, v, YPDB_INSERT0);
254 if (status >= 0)
255 status = YPPUSH_SUCC;
Value stored to 'status' is never read
256 else
257 status = YPPUSH_DBM;
258 }
259 }
260 return 1;
261}
262
263static int
264add_secure(CLIENT *client, char *domain, char *map, DBM *db)
265{
266 char keystr[] = YP_SECURE_KEY"YP_SECURE", *value;
267 int vallen, status;
268 datum k, v;
269
270 /* Get SECURE */
271
272 k.dptr = keystr;
273 k.dsize = strlen(keystr);
274
275 status = yp_match_host(client, domain, map,
276 k.dptr, k.dsize, &value, &vallen);
277 if (status == 0 && value) {
278 v.dptr = value;
279 v.dsize = vallen;
280
281 if (v.dptr != NULL((void *)0)) {
282 status = ypdb_store(db, k, v, YPDB_INSERT0);
283 if (status >= 0)
284 status = YPPUSH_SUCC;
285 else
286 status = YPPUSH_DBM;
287 }
288 }
289 return status;
290}
291
292static int
293send_clear(CLIENT *client)
294{
295 struct timeval tv;
296 int status, r;
297
298 status = YPPUSH_SUCC;
299
300 tv.tv_sec = 10;
301 tv.tv_usec = 0;
302
303 /* Send CLEAR */
304 r = clnt_call(client, YPPROC_CLEAR, xdr_void, 0, xdr_void, 0, tv)((*(client)->cl_ops->cl_call)(client, ((u_long)7), xdr_void
, (caddr_t)0, xdr_void, (caddr_t)0, tv))
;
305 if (r != RPC_SUCCESS)
306 clnt_perror(client, "yp_clear: clnt_call");
307 return status;
308
309}
310
311static int
312send_reply(CLIENT *client, u_long status, u_long tid)
313{
314 struct ypresp_xfr resp;
315 struct timeval tv;
316 int r;
317
318 tv.tv_sec = 10;
319 tv.tv_usec = 0;
320
321 resp.transid = tid;
322 resp.xfrstat = status;
323
324 /* Send CLEAR */
325 r = clnt_call(client, 1, xdr_ypresp_xfr, &resp, xdr_void, 0, tv)((*(client)->cl_ops->cl_call)(client, 1, xdr_ypresp_xfr
, (caddr_t)&resp, xdr_void, (caddr_t)0, tv))
;
326 if (r != RPC_SUCCESS)
327 clnt_perror(client, "yppushresp_xdr: clnt_call");
328 return status;
329
330}
331
332static void
333usage(void)
334{
335 fprintf(stderr(&__sF[2]),
336 "usage: ypxfr [-cf] [-C tid prog ipadd port] [-d domain] "
337 "[-h host] [-s domain]\n"
338 " mapname\n");
339 exit(1);
340}
341
342int
343main(int argc, char *argv[])
344{
345 int cflag = 0, fflag = 0, Cflag = 0;
346 char *domain, *host = NULL((void *)0), *srcdomain = NULL((void *)0);
347 char *tid = NULL((void *)0), *prog = NULL((void *)0), *ipadd = NULL((void *)0);
348 char *port = NULL((void *)0), *map = NULL((void *)0);
349 int status, xfr_status, ch, srvport;
350 u_int32_t ordernum, new_ordernum;
351 struct ypall_callback callback;
352 CLIENT *client = NULL((void *)0);
353 extern char *optarg;
354
355 yp_get_default_domain(&domain);
356
357 while ((ch = getopt(argc, argv, "cd:fh:s:C:")) != -1)
358 switch (ch) {
359 case 'c':
360 cflag = 1;
361 break;
362 case 'd':
363 if (strchr(optarg, '/')) /* Ha ha, we are not listening */
364 break;
365 domain = optarg;
366 break;
367 case 'f':
368 fflag = 1;
369 break;
370 case 'h':
371 host = optarg;
372 break;
373 case 's':
374 if (strchr(optarg, '/')) /* Ha ha, we are not listening */
375 break;
376 srcdomain = optarg;
377 break;
378 case 'C':
379 if (optind + 3 >= argc)
380 usage();
381 Cflag = 1;
382 tid = optarg;
383 prog = argv[optind++];
384 ipadd = argv[optind++];
385 port = argv[optind++];
386 break;
387 default:
388 usage();
389 break;
390 }
391
392 status = YPPUSH_SUCC;
393
394 if (optind + 1 != argc)
395 usage();
396
397 map = argv[optind];
398
399 if (status > 0) {
400 ypopenlog();
401
402 yplog("ypxfr: Arguments:");
403 yplog("YP clear to local: %s", (cflag) ? "no" : "yes");
404 yplog(" Force transfer: %s", (fflag) ? "yes" : "no");
405 yplog(" domain: %s", domain);
406 yplog(" host: %s", host);
407 yplog(" source domain: %s", srcdomain);
408 yplog(" transid: %s", tid);
409 yplog(" prog: %s", prog);
410 yplog(" port: %s", port);
411 yplog(" ipadd: %s", ipadd);
412 yplog(" map: %s", map);
413
414 if (fflag != 0) {
415 ordernum = 0;
416 } else {
417 status = get_local_ordernum(domain, map, &ordernum);
418 }
419 }
420
421 if (status > 0) {
422 yplog("Get Master");
423
424 if (host == NULL((void *)0)) {
425 if (srcdomain == NULL((void *)0)) {
426 status = yp_master(domain, map, &host);
427 } else {
428 status = yp_master(srcdomain, map, &host);
429 }
430 if (status == 0) {
431 status = YPPUSH_SUCC;
432 } else {
433 status = -status;
434 }
435 }
436 }
437
438 /* XXX this is raceable if portmap has holes! */
439 if (status > 0) {
440 yplog("Check for reserved port on host: %s", host);
441
442 srvport = getrpcport(host, YPPROG((u_long)100004), YPVERS((u_long)2), IPPROTO_TCP6);
443 if (srvport >= IPPORT_RESERVED1024)
444 status = YPPUSH_REFUSED;
445 }
446
447 if (status > 0) {
448 yplog("Connect host: %s", host);
449
450 client = yp_bind_host(host, YPPROG((u_long)100004), YPVERS((u_long)2), 0, 1);
451
452 status = get_remote_ordernum(client, domain, map,
453 ordernum, &new_ordernum);
454 }
455
456 if (status == YPPUSH_SUCC) {
457 char tmpmapname[PATH_MAX1024];
458 int fd;
459
460 /* Create temporary db */
461 snprintf(tmpmapname, sizeof tmpmapname,
462 "%s/%s/ypdbXXXXXXXXXX", YP_DB_PATH"/var/yp", domain);
463 fd = mkstemp(tmpmapname);
464 if (fd == -1)
465 status = YPPUSH_DBM;
466 else
467 close(fd);
468
469 if (status > 0) {
470 db = create_db(domain, map, tmpmapname);
471 if (db == NULL((void *)0))
472 status = YPPUSH_DBM;
473 }
474
475 /* Add ORDER */
476 if (status > 0)
477 status = add_order(db, new_ordernum);
478
479 /* Add MASTER */
480 if (status > 0)
481 status = add_master(client, domain, map, db);
482
483 /* Add INTERDOMAIN */
484 if (status > 0)
485 status = add_interdomain(client, domain, map, db);
486
487 /* Add SECURE */
488 if (status > 0)
489 status = add_secure(client, domain, map, db);
490
491 if (status > 0) {
492 callback.foreach = ypxfr_foreach;
493 status = get_map(client, domain, map, &callback);
494 }
495
496 /* Close db */
497 if (db != NULL((void *)0))
498 ypdb_close(db);
499
500 /* Rename db */
501 if (status > 0) {
502 status = install_db(domain, map, tmpmapname);
503 } else {
504 unlink(tmpmapname);
505 status = YPPUSH_SUCC;
506 }
507 }
508
509 xfr_status = status;
510
511 if (client != NULL((void *)0))
512 clnt_destroy(client)((*(client)->cl_ops->cl_destroy)(client));
513
514 /* YP_CLEAR */
515
516 if (!cflag) {
517 client = yp_bind_local(YPPROG((u_long)100004), YPVERS((u_long)2));
518 status = send_clear(client);
519 clnt_destroy(client)((*(client)->cl_ops->cl_destroy)(client));
520 }
521
522 if (Cflag > 0) {
523 /* Send Response */
524 client = yp_bind_host(ipadd, atoi(prog), 1, atoi(port), 0);
525 status = send_reply(client, xfr_status, atoi(tid));
526 clnt_destroy(client)((*(client)->cl_ops->cl_destroy)(client));
527 }
528 return (0);
529}