Bug Summary

File:src/usr.sbin/ypldap/yp.c
Warning:line 273, column 3
Value stored to 'xdr_result' is never read

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 yp.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.sbin/ypldap/obj -resource-dir /usr/local/llvm16/lib/clang/16 -I /usr/src/usr.sbin/ypldap -internal-isystem /usr/local/llvm16/lib/clang/16/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.sbin/ypldap/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.sbin/ypldap/yp.c
1/* $OpenBSD: yp.c,v 1.22 2023/07/18 13:06:33 claudio Exp $ */
2/*
3 * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <sys/types.h>
19#include <sys/queue.h>
20#include <sys/socket.h>
21#include <sys/select.h>
22#include <sys/tree.h>
23#include <sys/stat.h>
24
25#include <netinet/in.h>
26#include <arpa/inet.h>
27
28#include <errno(*__errno()).h>
29#include <event.h>
30#include <fcntl.h>
31#include <unistd.h>
32#include <pwd.h>
33#include <stdio.h>
34#include <stdlib.h>
35#include <string.h>
36#include <limits.h>
37
38#include <rpc/rpc.h>
39#include <rpc/xdr.h>
40#include <rpc/pmap_clnt.h>
41#include <rpc/pmap_prot.h>
42#include <rpc/pmap_rmt.h>
43#include <rpcsvc/yp.h>
44#include <rpcsvc/ypclnt.h>
45
46#include "ypldap.h"
47#include "log.h"
48
49#define BINDINGDIR"/var/yp/binding" "/var/yp/binding"
50
51void yp_dispatch(struct svc_req *, SVCXPRT *);
52void yp_disable_events(void);
53void yp_fd_event(int, short, void *);
54int yp_check(struct svc_req *);
55int yp_valid_domain(char *, struct ypresp_val *);
56void yp_make_val(struct ypresp_val *, char *, int);
57void yp_make_keyval(struct ypresp_key_val *, char *, char *);
58int yp_write_binding(int, int);
59
60static struct env *env;
61
62struct yp_event {
63 TAILQ_ENTRY(yp_event)struct { struct yp_event *tqe_next; struct yp_event **tqe_prev
; }
ye_entry;
64 struct event ye_event;
65};
66
67struct yp_data {
68 SVCXPRT *yp_trans_udp;
69 SVCXPRT *yp_trans_tcp;
70 TAILQ_HEAD(, yp_event)struct { struct yp_event *tqh_first; struct yp_event **tqh_last
; }
yd_events;
71};
72
73void
74yp_disable_events(void)
75{
76 struct yp_event *ye;
77
78 while ((ye = TAILQ_FIRST(&env->sc_yp->yd_events)((&env->sc_yp->yd_events)->tqh_first)) != NULL((void *)0)) {
79 TAILQ_REMOVE(&env->sc_yp->yd_events, ye, ye_entry)do { if (((ye)->ye_entry.tqe_next) != ((void *)0)) (ye)->
ye_entry.tqe_next->ye_entry.tqe_prev = (ye)->ye_entry.tqe_prev
; else (&env->sc_yp->yd_events)->tqh_last = (ye)
->ye_entry.tqe_prev; *(ye)->ye_entry.tqe_prev = (ye)->
ye_entry.tqe_next; ; ; } while (0)
;
80 event_del(&ye->ye_event);
81 free(ye);
82 }
83}
84
85void
86yp_enable_events(void)
87{
88 int i;
89 extern fd_set *__svc_fdset;
90 extern int __svc_fdsetsize;
91 struct yp_event *ye;
92
93 for (i = 0; i < __svc_fdsetsize; i++) {
94 if (FD_ISSET(i, __svc_fdset)__fd_isset((i), (__svc_fdset))) {
95 if ((ye = calloc(1, sizeof(*ye))) == NULL((void *)0))
96 fatal(NULL((void *)0));
97 event_set(&ye->ye_event, i, EV_READ0x02, yp_fd_event, NULL((void *)0));
98 event_add(&ye->ye_event, NULL((void *)0));
99 TAILQ_INSERT_TAIL(&env->sc_yp->yd_events, ye, ye_entry)do { (ye)->ye_entry.tqe_next = ((void *)0); (ye)->ye_entry
.tqe_prev = (&env->sc_yp->yd_events)->tqh_last; *
(&env->sc_yp->yd_events)->tqh_last = (ye); (&
env->sc_yp->yd_events)->tqh_last = &(ye)->ye_entry
.tqe_next; } while (0)
;
100 }
101 }
102}
103
104void
105yp_fd_event(int fd, short event, void *p)
106{
107 svc_getreq_common(fd);
108 yp_disable_events();
109 yp_enable_events();
110}
111
112void
113yp_init(struct env *x_env)
114{
115 struct sockaddr_in addr;
116 struct yp_data *yp;
117 int s, udpport, tcpport;
118
119 if ((yp = calloc(1, sizeof(*yp))) == NULL((void *)0))
120 fatal(NULL((void *)0));
121 TAILQ_INIT(&yp->yd_events)do { (&yp->yd_events)->tqh_first = ((void *)0); (&
yp->yd_events)->tqh_last = &(&yp->yd_events)
->tqh_first; } while (0)
;
122
123 env = x_env;
124 env->sc_yp = yp;
125
126 switch (env->sc_bind_mode) {
127 case BIND_MODE_LOCAL:
128 addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK)(__uint32_t)(__builtin_constant_p(((u_int32_t)(0x7f000001))) ?
(__uint32_t)(((__uint32_t)(((u_int32_t)(0x7f000001))) & 0xff
) << 24 | ((__uint32_t)(((u_int32_t)(0x7f000001))) &
0xff00) << 8 | ((__uint32_t)(((u_int32_t)(0x7f000001))
) & 0xff0000) >> 8 | ((__uint32_t)(((u_int32_t)(0x7f000001
))) & 0xff000000) >> 24) : __swap32md(((u_int32_t)(
0x7f000001))))
;
129 addr.sin_len = sizeof(struct sockaddr_in);
130 addr.sin_family = AF_INET2;
131
132 s = socket(AF_INET2, SOCK_DGRAM2, IPPROTO_UDP17);
133 if (s == -1)
134 fatal("cannot create udp socket");
135 addr.sin_port = 0;
136 if (bindresvport(s, &addr))
137 fatal("cannot bind udp socket");
138 if ((yp->yp_trans_udp = svcudp_create(s)) == NULL((void *)0))
139 fatal("cannot create udp service");
140 udpport = ntohs(addr.sin_port)(__uint16_t)(__builtin_constant_p(addr.sin_port) ? (__uint16_t
)(((__uint16_t)(addr.sin_port) & 0xffU) << 8 | ((__uint16_t
)(addr.sin_port) & 0xff00U) >> 8) : __swap16md(addr
.sin_port))
;
141
142 s = socket(AF_INET2, SOCK_STREAM1, IPPROTO_TCP6);
143 if (s == -1)
144 fatal("cannot create tcp socket");
145 addr.sin_port = 0;
146 if (bindresvport(s, &addr))
147 fatal("cannot bind tcp socket");
148 if ((yp->yp_trans_tcp = svctcp_create(s, 0, 0)) == NULL((void *)0))
149 fatal("cannot create tcp service");
150 tcpport = ntohs(addr.sin_port)(__uint16_t)(__builtin_constant_p(addr.sin_port) ? (__uint16_t
)(((__uint16_t)(addr.sin_port) & 0xffU) << 8 | ((__uint16_t
)(addr.sin_port) & 0xff00U) >> 8) : __swap16md(addr
.sin_port))
;
151
152 /* protocol 0 means don't register with portmap */
153 if (!svc_register(yp->yp_trans_udp, YPPROG((u_long)100004), YPVERS((u_long)2),
154 yp_dispatch, 0)) {
155 fatal("unable to register (YPPROG, YPVERS, udp)");
156 }
157 if (!svc_register(yp->yp_trans_tcp, YPPROG((u_long)100004), YPVERS((u_long)2),
158 yp_dispatch, 0)) {
159 fatal("unable to register (YPPROG, YPVERS, tcp)");
160 }
161
162 if (yp_write_binding(udpport, tcpport))
163 fatal("cannot write yp binding file");
164
165 break;
166
167 case BIND_MODE_PORTMAP:
168 (void)pmap_unset(YPPROG((u_long)100004), YPVERS((u_long)2));
169
170 if ((yp->yp_trans_udp = svcudp_create(RPC_ANYSOCK-1)) == NULL((void *)0))
171 fatal("cannot create udp service");
172 if ((yp->yp_trans_tcp = svctcp_create(RPC_ANYSOCK-1, 0, 0)) ==
173 NULL((void *)0))
174 fatal("cannot create tcp service");
175
176 if (!svc_register(yp->yp_trans_udp, YPPROG((u_long)100004), YPVERS((u_long)2),
177 yp_dispatch, IPPROTO_UDP17)) {
178 fatal("unable to register (YPPROG, YPVERS, udp)");
179 }
180 if (!svc_register(yp->yp_trans_tcp, YPPROG((u_long)100004), YPVERS((u_long)2),
181 yp_dispatch, IPPROTO_TCP6)) {
182 fatal("unable to register (YPPROG, YPVERS, tcp)");
183 }
184 break;
185 }
186}
187
188int
189yp_write_binding(int udpport, int tcpport)
190{
191 char path[PATH_MAX1024];
192 struct ypbind_resp ybr;
193 struct iovec iov[3];
194 struct in_addr bindaddr;
195 u_short ypbind, ypserv_tcp, ypserv_udp;
196 ssize_t total;
197 int fd;
198
199 snprintf(path, sizeof path, "%s/%s.%ld", BINDINGDIR"/var/yp/binding", env->sc_domainname,
200 YPVERS((u_long)2));
201 fd = open(path, O_CREAT0x0200|O_SHLOCK0x0010|O_RDWR0x0002|O_TRUNC0x0400, 0644);
202 if (fd == -1) {
203 (void)mkdir(BINDINGDIR"/var/yp/binding", 0755);
204 fd = open(path, O_CREAT0x0200|O_SHLOCK0x0010|O_RDWR0x0002|O_TRUNC0x0400,
205 0644);
206 if (fd == -1)
207 return -1;
208 }
209
210 if (fchmod(fd, 0644) == -1)
211 return -1;
212
213 iov[0].iov_base = (caddr_t)&ypbind;
214 iov[0].iov_len = sizeof ypbind;
215 iov[1].iov_base = (caddr_t)&ybr;
216 iov[1].iov_len = sizeof ybr;
217 iov[2].iov_base = (caddr_t)&ypserv_tcp;
218 iov[2].iov_len = sizeof ypserv_tcp;
219
220 bindaddr.s_addr = htonl(INADDR_LOOPBACK)(__uint32_t)(__builtin_constant_p(((u_int32_t)(0x7f000001))) ?
(__uint32_t)(((__uint32_t)(((u_int32_t)(0x7f000001))) & 0xff
) << 24 | ((__uint32_t)(((u_int32_t)(0x7f000001))) &
0xff00) << 8 | ((__uint32_t)(((u_int32_t)(0x7f000001))
) & 0xff0000) >> 8 | ((__uint32_t)(((u_int32_t)(0x7f000001
))) & 0xff000000) >> 24) : __swap32md(((u_int32_t)(
0x7f000001))))
;
221 ypserv_tcp = htons(tcpport)(__uint16_t)(__builtin_constant_p(tcpport) ? (__uint16_t)(((__uint16_t
)(tcpport) & 0xffU) << 8 | ((__uint16_t)(tcpport) &
0xff00U) >> 8) : __swap16md(tcpport))
;
222 ypserv_udp = htons(udpport)(__uint16_t)(__builtin_constant_p(udpport) ? (__uint16_t)(((__uint16_t
)(udpport) & 0xffU) << 8 | ((__uint16_t)(udpport) &
0xff00U) >> 8) : __swap16md(udpport))
;
223 ypbind = 0;
224 memset(&ybr, 0, sizeof ybr);
225 ybr.ypbind_status = YPBIND_SUCC_VAL;
226 memmove(&ybr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr,
227 &bindaddr,
228 sizeof(ybr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr));
229 memmove(&ybr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port,
230 &ypserv_udp,
231 sizeof(ybr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port));
232
233 total = iov[0].iov_len + iov[1].iov_len + iov[2].iov_len;
234 if (writev(fd, iov, sizeof(iov)/sizeof(iov[0])) !=
235 total) {
236 close(fd);
237 unlink(path);
238 return -1;
239 }
240
241 return 0;
242}
243
244/*
245 * lots of inspiration from ypserv by Mats O Jansson
246 */
247void
248yp_dispatch(struct svc_req *req, SVCXPRT *trans)
249{
250 xdrproc_t xdr_argument;
251 xdrproc_t xdr_result;
252 char *result;
253 char *(*cb)(char *, struct svc_req *);
254 union {
255 domainname ypproc_domain_2_arg;
256 domainname ypproc_domain_nonack_2_arg;
257 ypreq_key ypproc_match_2_arg;
258 ypreq_nokey ypproc_first_2_arg;
259 ypreq_key ypproc_next_2_arg;
260 ypreq_xfr ypproc_xfr_2_arg;
261 ypreq_nokey ypproc_all_2_arg;
262 ypreq_nokey ypproc_master_2_arg;
263 ypreq_nokey ypproc_order_2_arg;
264 domainname ypproc_maplist_2_arg;
265 } argument;
266
267 xdr_argument = (xdrproc_t) xdr_void;
268 xdr_result = (xdrproc_t) xdr_void;
269 cb = NULL((void *)0);
270 switch (req->rq_proc) {
271 case YPPROC_NULL((u_long)0):
272 xdr_argument = (xdrproc_t) xdr_void;
273 xdr_result = (xdrproc_t) xdr_void;
Value stored to 'xdr_result' is never read
274 if (yp_check(req) == -1)
275 return;
276 result = NULL((void *)0);
277 if (!svc_sendreply(trans, (xdrproc_t) xdr_void,
278 (void *)&result))
279 svcerr_systemerr(trans);
280 return;
281 case YPPROC_DOMAIN((u_long)1):
282 xdr_argument = (xdrproc_t) xdr_domainname;
283 xdr_result = (xdrproc_t) xdr_bool;
284 if (yp_check(req) == -1)
285 return;
286 cb = (void *)ypproc_domain_2_svc;
287 break;
288 case YPPROC_DOMAIN_NONACK((u_long)2):
289 xdr_argument = (xdrproc_t) xdr_domainname;
290 xdr_result = (xdrproc_t) xdr_bool;
291 if (yp_check(req) == -1)
292 return;
293 cb = (void *)ypproc_domain_nonack_2_svc;
294 break;
295 case YPPROC_MATCH((u_long)3):
296 xdr_argument = (xdrproc_t) xdr_ypreq_key;
297 xdr_result = (xdrproc_t) xdr_ypresp_val;
298 if (yp_check(req) == -1)
299 return;
300 cb = (void *)ypproc_match_2_svc;
301 break;
302 case YPPROC_FIRST((u_long)4):
303 xdr_argument = (xdrproc_t) xdr_ypreq_nokey;
304 xdr_result = (xdrproc_t) xdr_ypresp_key_val;
305 if (yp_check(req) == -1)
306 return;
307 cb = (void *)ypproc_first_2_svc;
308 break;
309 case YPPROC_NEXT((u_long)5):
310 xdr_argument = (xdrproc_t) xdr_ypreq_key;
311 xdr_result = (xdrproc_t) xdr_ypresp_key_val;
312 if (yp_check(req) == -1)
313 return;
314 cb = (void *)ypproc_next_2_svc;
315 break;
316 case YPPROC_XFR((u_long)6):
317 if (yp_check(req) == -1)
318 return;
319 svcerr_noproc(trans);
320 return;
321 case YPPROC_CLEAR((u_long)7):
322 log_debug("ypproc_clear");
323 if (yp_check(req) == -1)
324 return;
325 svcerr_noproc(trans);
326 return;
327 case YPPROC_ALL((u_long)8):
328 log_debug("ypproc_all");
329 xdr_argument = (xdrproc_t) xdr_ypreq_nokey;
330 xdr_result = (xdrproc_t) xdr_ypresp_all;
331 if (yp_check(req) == -1)
332 return;
333 cb = (void *)ypproc_all_2_svc;
334 break;
335 case YPPROC_MASTER((u_long)9):
336 xdr_argument = (xdrproc_t) xdr_ypreq_nokey;
337 xdr_result = (xdrproc_t) xdr_ypresp_master;
338 if (yp_check(req) == -1)
339 return;
340 cb = (void *)ypproc_master_2_svc;
341 break;
342 case YPPROC_ORDER((u_long)10):
343 log_debug("ypproc_order");
344 if (yp_check(req) == -1)
345 return;
346 svcerr_noproc(trans);
347 return;
348 case YPPROC_MAPLIST((u_long)11):
349 xdr_argument = (xdrproc_t) xdr_domainname;
350 xdr_result = (xdrproc_t) xdr_ypresp_maplist;
351 if (yp_check(req) == -1)
352 return;
353 cb = (void *)ypproc_maplist_2_svc;
354 break;
355 default:
356 svcerr_noproc(trans);
357 return;
358 }
359 (void)memset(&argument, 0, sizeof(argument));
360
361 if (!svc_getargs(trans, xdr_argument, (caddr_t)&argument)(*(trans)->xp_ops->xp_getargs)((trans), (xdr_argument),
((caddr_t)&argument))
) {
362 svcerr_decode(trans);
363 return;
364 }
365 result = (*cb)((char *)&argument, req);
366 if (result != NULL((void *)0) && !svc_sendreply(trans, xdr_result, result))
367 svcerr_systemerr(trans);
368 if (!svc_freeargs(trans, xdr_argument, (caddr_t)&argument)(*(trans)->xp_ops->xp_freeargs)((trans), (xdr_argument)
, ((caddr_t)&argument))
) {
369 /*
370 * ypserv does it too.
371 */
372 fatal("unable to free arguments");
373 }
374}
375
376int
377yp_check(struct svc_req *req)
378{
379#ifdef notyet
380 struct sockaddr_in *caller;
381
382 caller = svc_getcaller(req->rq_xprt)(&(req->rq_xprt)->xp_raddr);
383 /*
384 * We might want to know who we allow here.
385 */
386#endif
387 return (0);
388}
389
390int
391yp_valid_domain(char *domain, struct ypresp_val *res)
392{
393 if (domain == NULL((void *)0)) {
394 log_debug("NULL domain !");
395 return (-1);
396 }
397 if (strcmp(domain, env->sc_domainname) != 0) {
398 res->stat = YP_NODOM;
399 return (-1);
400 }
401 return (0);
402}
403
404bool_tint32_t *
405ypproc_domain_2_svc(domainname *arg, struct svc_req *req)
406{
407 static bool_tint32_t res;
408
409 res = (bool_tint32_t)1;
410 if (strcmp(*arg, env->sc_domainname) != 0)
411 res = (bool_tint32_t)0;
412 return (&res);
413}
414
415bool_tint32_t *
416ypproc_domain_nonack_2_svc(domainname *arg, struct svc_req *req)
417{
418 static bool_tint32_t res;
419
420 if (strcmp(*arg, env->sc_domainname) != 0)
421 return NULL((void *)0);
422 res = (bool_tint32_t)1;
423 return (&res);
424}
425
426ypresp_val *
427ypproc_match_2_svc(ypreq_key *arg, struct svc_req *req)
428{
429 struct userent ukey;
430 struct userent *ue;
431 struct groupent gkey;
432 struct groupent *ge;
433 static struct ypresp_val res;
434 const char *estr;
435 char *bp, *cp;
436 char key[YPMAXRECORD1024+1];
437
438 log_debug("matching '%.*s' in map %s", arg->key.keydat_len,
439 arg->key.keydat_val, arg->map);
440
441 if (yp_valid_domain(arg->domain, (struct ypresp_val *)&res) == -1)
442 return (&res);
443
444 if (env->sc_user_names == NULL((void *)0)) {
445 /*
446 * tree not ready.
447 */
448 return (NULL((void *)0));
449 }
450
451 if (arg->key.keydat_len > YPMAXRECORD1024) {
452 log_debug("argument too long");
453 return (NULL((void *)0));
454 }
455 memset(key, 0, sizeof(key));
456 (void)strncpy(key, arg->key.keydat_val, arg->key.keydat_len);
457
458 if (strcmp(arg->map, "passwd.byname") == 0 ||
459 strcmp(arg->map, "master.passwd.byname") == 0) {
460 ukey.ue_line = key;
461 if ((ue = RB_FIND(user_name_tree, env->sc_user_names,user_name_tree_RB_FIND(env->sc_user_names, &ukey)
462 &ukey)user_name_tree_RB_FIND(env->sc_user_names, &ukey)) == NULL((void *)0)) {
463 res.stat = YP_NOKEY;
464 return (&res);
465 }
466
467 yp_make_val(&res, ue->ue_line, 1);
468 return (&res);
469 } else if (strcmp(arg->map, "passwd.byuid") == 0 ||
470 strcmp(arg->map, "master.passwd.byuid") == 0) {
471 ukey.ue_uid = strtonum(key, 0, UID_MAX0xffffffffU, &estr);
472 if (estr) {
473 res.stat = YP_BADARGS;
474 return (&res);
475 }
476
477 if ((ue = RB_FIND(user_uid_tree, &env->sc_user_uids,user_uid_tree_RB_FIND(&env->sc_user_uids, &ukey)
478 &ukey)user_uid_tree_RB_FIND(&env->sc_user_uids, &ukey)) == NULL((void *)0)) {
479 res.stat = YP_NOKEY;
480 return (&res);
481 }
482
483 yp_make_val(&res, ue->ue_line, 1);
484 return (&res);
485 } else if (strcmp(arg->map, "group.bygid") == 0) {
486 gkey.ge_gid = strtonum(key, 0, GID_MAX0xffffffffU, &estr);
487 if (estr) {
488 res.stat = YP_BADARGS;
489 return (&res);
490 }
491 if ((ge = RB_FIND(group_gid_tree, &env->sc_group_gids,group_gid_tree_RB_FIND(&env->sc_group_gids, &gkey)
492 &gkey)group_gid_tree_RB_FIND(&env->sc_group_gids, &gkey)) == NULL((void *)0)) {
493 res.stat = YP_NOKEY;
494 return (&res);
495 }
496
497 yp_make_val(&res, ge->ge_line, 1);
498 return (&res);
499 } else if (strcmp(arg->map, "group.byname") == 0) {
500 gkey.ge_line = key;
501 if ((ge = RB_FIND(group_name_tree, env->sc_group_names,group_name_tree_RB_FIND(env->sc_group_names, &gkey)
502 &gkey)group_name_tree_RB_FIND(env->sc_group_names, &gkey)) == NULL((void *)0)) {
503 res.stat = YP_NOKEY;
504 return (&res);
505 }
506
507 yp_make_val(&res, ge->ge_line, 1);
508 return (&res);
509 } else if (strcmp(arg->map, "netid.byname") == 0) {
510 bp = cp = key;
511
512 if (strncmp(bp, "unix.", strlen("unix.")) != 0) {
513 res.stat = YP_BADARGS;
514 return (&res);
515 }
516
517 bp += strlen("unix.");
518
519 if (*bp == '\0') {
520 res.stat = YP_BADARGS;
521 return (&res);
522 }
523
524 if (!(cp = strsep(&bp, "@"))) {
525 res.stat = YP_BADARGS;
526 return (&res);
527 }
528
529 if (strcmp(bp, arg->domain) != 0) {
530 res.stat = YP_BADARGS;
531 return (&res);
532 }
533
534 ukey.ue_uid = strtonum(cp, 0, UID_MAX0xffffffffU, &estr);
535 if (estr) {
536 res.stat = YP_BADARGS;
537 return (&res);
538 }
539
540 if ((ue = RB_FIND(user_uid_tree, &env->sc_user_uids,user_uid_tree_RB_FIND(&env->sc_user_uids, &ukey)
541 &ukey)user_uid_tree_RB_FIND(&env->sc_user_uids, &ukey)) == NULL((void *)0)) {
542 res.stat = YP_NOKEY;
543 return (&res);
544 }
545
546 yp_make_val(&res, ue->ue_netid_line, 0);
547 return (&res);
548
549 } else {
550 log_debug("unknown map %s", arg->map);
551 res.stat = YP_NOMAP;
552 return (&res);
553 }
554}
555
556ypresp_key_val *
557ypproc_first_2_svc(ypreq_nokey *arg, struct svc_req *req)
558{
559 static struct ypresp_key_val res;
560
561 if (yp_valid_domain(arg->domain, (struct ypresp_val *)&res) == -1)
562 return (&res);
563
564 if (strcmp(arg->map, "passwd.byname") == 0 ||
565 strcmp(arg->map, "master.passwd.byname") == 0) {
566 if (env->sc_user_lines == NULL((void *)0))
567 return (NULL((void *)0));
568
569 yp_make_keyval(&res, env->sc_user_lines, env->sc_user_lines);
570 } else if (strcmp(arg->map, "group.byname") == 0) {
571 if (env->sc_group_lines == NULL((void *)0))
572 return (NULL((void *)0));
573
574 yp_make_keyval(&res, env->sc_group_lines, env->sc_group_lines);
575 } else {
576 log_debug("unknown map %s", arg->map);
577 res.stat = YP_NOMAP;
578 }
579
580 return (&res);
581}
582
583ypresp_key_val *
584ypproc_next_2_svc(ypreq_key *arg, struct svc_req *req)
585{
586 struct userent ukey;
587 struct userent *ue;
588 struct groupent gkey;
589 struct groupent *ge;
590 char *line;
591 static struct ypresp_key_val res;
592 char key[YPMAXRECORD1024+1];
593
594 if (yp_valid_domain(arg->domain, (struct ypresp_val *)&res) == -1)
595 return (&res);
596
597 if (strcmp(arg->map, "passwd.byname") == 0 ||
598 strcmp(arg->map, "master.passwd.byname") == 0) {
599 memset(key, 0, sizeof(key));
600 (void)strncpy(key, arg->key.keydat_val,
601 arg->key.keydat_len);
602 ukey.ue_line = key;
603 if ((ue = RB_NFIND(user_name_tree, env->sc_user_names,user_name_tree_RB_NFIND(env->sc_user_names, &ukey)
604 &ukey)user_name_tree_RB_NFIND(env->sc_user_names, &ukey)) == NULL((void *)0)) {
605 res.stat = YP_NOKEY;
606 return (&res);
607 }
608 line = ue->ue_line + (strlen(ue->ue_line) + 1);
609 line = line + (strlen(line) + 1);
610 yp_make_keyval(&res, line, line);
611 return (&res);
612
613
614 } else if (strcmp(arg->map, "group.byname") == 0) {
615 memset(key, 0, sizeof(key));
616 (void)strncpy(key, arg->key.keydat_val,
617 arg->key.keydat_len);
618
619 gkey.ge_line = key;
620 if ((ge = RB_NFIND(group_name_tree, env->sc_group_names,group_name_tree_RB_NFIND(env->sc_group_names, &gkey)
621 &gkey)group_name_tree_RB_NFIND(env->sc_group_names, &gkey)) == NULL((void *)0)) {
622 res.stat = YP_NOKEY;
623 return (&res);
624 }
625
626 line = ge->ge_line + (strlen(ge->ge_line) + 1);
627 line = line + (strlen(line) + 1);
628 yp_make_keyval(&res, line, line);
629 return (&res);
630 } else {
631 log_debug("unknown map %s", arg->map);
632 res.stat = YP_NOMAP;
633 return (&res);
634 }
635}
636
637ypresp_all *
638ypproc_all_2_svc(ypreq_nokey *arg, struct svc_req *req)
639{
640 static struct ypresp_all res;
641
642 if (yp_valid_domain(arg->domain, (struct ypresp_val *)&res) == -1)
643 return (&res);
644
645 svcerr_auth(req->rq_xprt, AUTH_FAILED);
646 return (NULL((void *)0));
647}
648
649ypresp_master *
650ypproc_master_2_svc(ypreq_nokey *arg, struct svc_req *req)
651{
652 static struct ypresp_master res;
653 static char master[YPMAXPEER64 + 1];
654
655 memset(&res, 0, sizeof(res));
656 if (yp_valid_domain(arg->domain, (struct ypresp_val *)&res) == -1)
657 return (&res);
658 if (gethostname(master, sizeof(master)) == 0) {
659 res.peer = (peername)master;
660 res.stat = YP_TRUE;
661 } else
662 res.stat = YP_NOKEY;
663 return (&res);
664}
665
666ypresp_maplist *
667ypproc_maplist_2_svc(domainname *arg, struct svc_req *req)
668{
669 size_t i;
670 static struct {
671 char *name;
672 int cond;
673 } mapnames[] = {
674 { "passwd.byname", YPMAP_PASSWD_BYNAME0x00000001 },
675 { "passwd.byuid", YPMAP_PASSWD_BYUID0x00000002 },
676 { "master.passwd.byname", YPMAP_MASTER_PASSWD_BYNAME0x00000004 },
677 { "master.passwd.byuid", YPMAP_MASTER_PASSWD_BYUID0x00000008 },
678 { "group.byname", YPMAP_GROUP_BYNAME0x00000010 },
679 { "group.bygid", YPMAP_GROUP_BYGID0x00000020 },
680 { "netid.byname", YPMAP_NETID_BYNAME0x00000040 },
681 };
682 static ypresp_maplist res;
683 static struct ypmaplist maps[sizeof(mapnames) / sizeof(mapnames[0])];
684
685 if (yp_valid_domain(*arg, (struct ypresp_val *)&res) == -1)
686 return (&res);
687
688 res.stat = YP_TRUE;
689 res.maps = NULL((void *)0);
690 for (i = 0; i < sizeof(mapnames) / sizeof(mapnames[0]); i++) {
691 if (!(env->sc_flags & mapnames[i].cond))
692 continue;
693 maps[i].map = mapnames[i].name;
694 maps[i].next = res.maps;
695 res.maps = &maps[i];
696 }
697
698 return (&res);
699}
700
701void
702yp_make_val(struct ypresp_val *res, char *line, int replacecolon)
703{
704 static char buf[LINE_WIDTH1024];
705
706 memset(buf, 0, sizeof(buf));
707
708 if (replacecolon)
709 line[strlen(line)] = ':';
710 (void)strlcpy(buf, line, sizeof(buf));
711 if (replacecolon)
712 line[strcspn(line, ":")] = '\0';
713 log_debug("sending out %s", buf);
714
715 res->stat = YP_TRUE;
716 res->val.valdat_len = strlen(buf);
717 res->val.valdat_val = buf;
718}
719
720void
721yp_make_keyval(struct ypresp_key_val *res, char *key, char *line)
722{
723 static char keybuf[YPMAXRECORD1024+1];
724 static char buf[LINE_WIDTH1024];
725
726 memset(keybuf, 0, sizeof(keybuf));
727 memset(buf, 0, sizeof(buf));
728
729 (void)strlcpy(keybuf, key, sizeof(keybuf));
730 res->key.keydat_len = strlen(keybuf);
731 res->key.keydat_val = keybuf;
732
733 if (*line == '\0') {
734 res->stat = YP_NOMORE;
735 return;
736 }
737 res->stat = YP_TRUE;
738 line[strlen(line)] = ':';
739 (void)strlcpy(buf, line, sizeof(buf));
740 line[strcspn(line, ":")] = '\0';
741 log_debug("sending out %s => %s", keybuf, buf);
742
743 res->val.valdat_len = strlen(buf);
744 res->val.valdat_val = buf;
745}