19e7c127fSCraig Rodrigues /* $OpenBSD: yp.c,v 1.14 2015/02/11 01:26:00 pelikan Exp $ */ 29e7c127fSCraig Rodrigues /* $FreeBSD$ */ 39e7c127fSCraig Rodrigues /* 49e7c127fSCraig Rodrigues * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org> 59e7c127fSCraig Rodrigues * 69e7c127fSCraig Rodrigues * Permission to use, copy, modify, and distribute this software for any 79e7c127fSCraig Rodrigues * purpose with or without fee is hereby granted, provided that the above 89e7c127fSCraig Rodrigues * copyright notice and this permission notice appear in all copies. 99e7c127fSCraig Rodrigues * 109e7c127fSCraig Rodrigues * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 119e7c127fSCraig Rodrigues * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 129e7c127fSCraig Rodrigues * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 139e7c127fSCraig Rodrigues * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 149e7c127fSCraig Rodrigues * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 159e7c127fSCraig Rodrigues * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 169e7c127fSCraig Rodrigues * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 179e7c127fSCraig Rodrigues */ 189e7c127fSCraig Rodrigues 199e7c127fSCraig Rodrigues #include <sys/types.h> 2066b5c05dSCraig Rodrigues #include <sys/param.h> 219e7c127fSCraig Rodrigues #include <sys/queue.h> 229e7c127fSCraig Rodrigues #include <sys/socket.h> 239e7c127fSCraig Rodrigues #include <sys/select.h> 249e7c127fSCraig Rodrigues #include <sys/tree.h> 259e7c127fSCraig Rodrigues 269e7c127fSCraig Rodrigues #include <netinet/in.h> 279e7c127fSCraig Rodrigues #include <arpa/inet.h> 289e7c127fSCraig Rodrigues 299e7c127fSCraig Rodrigues #include <errno.h> 309e7c127fSCraig Rodrigues #include <event.h> 319e7c127fSCraig Rodrigues #include <fcntl.h> 329e7c127fSCraig Rodrigues #include <unistd.h> 339e7c127fSCraig Rodrigues #include <pwd.h> 349e7c127fSCraig Rodrigues #include <stdio.h> 359e7c127fSCraig Rodrigues #include <stdlib.h> 369e7c127fSCraig Rodrigues #include <string.h> 379e7c127fSCraig Rodrigues #include <limits.h> 389e7c127fSCraig Rodrigues 399e7c127fSCraig Rodrigues #include <rpc/rpc.h> 409e7c127fSCraig Rodrigues #include <rpc/xdr.h> 419e7c127fSCraig Rodrigues #include <rpc/pmap_clnt.h> 429e7c127fSCraig Rodrigues #include <rpc/pmap_prot.h> 439e7c127fSCraig Rodrigues #include <rpc/pmap_rmt.h> 449e7c127fSCraig Rodrigues #include <rpcsvc/yp.h> 459e7c127fSCraig Rodrigues #include <rpcsvc/ypclnt.h> 469e7c127fSCraig Rodrigues 479e7c127fSCraig Rodrigues #include "ypldap.h" 489e7c127fSCraig Rodrigues 499e7c127fSCraig Rodrigues void yp_dispatch(struct svc_req *, SVCXPRT *); 509e7c127fSCraig Rodrigues void yp_disable_events(void); 519e7c127fSCraig Rodrigues void yp_fd_event(int, short, void *); 529e7c127fSCraig Rodrigues int yp_check(struct svc_req *); 539e7c127fSCraig Rodrigues int yp_valid_domain(char *, struct ypresp_val *); 549e7c127fSCraig Rodrigues void yp_make_val(struct ypresp_val *, char *, int); 559e7c127fSCraig Rodrigues void yp_make_keyval(struct ypresp_key_val *, char *, char *); 569e7c127fSCraig Rodrigues 579e7c127fSCraig Rodrigues static struct env *env; 589e7c127fSCraig Rodrigues 599e7c127fSCraig Rodrigues struct yp_event { 609e7c127fSCraig Rodrigues TAILQ_ENTRY(yp_event) ye_entry; 619e7c127fSCraig Rodrigues struct event ye_event; 629e7c127fSCraig Rodrigues }; 639e7c127fSCraig Rodrigues 649e7c127fSCraig Rodrigues struct yp_data { 659e7c127fSCraig Rodrigues SVCXPRT *yp_trans_udp; 669e7c127fSCraig Rodrigues SVCXPRT *yp_trans_tcp; 679e7c127fSCraig Rodrigues TAILQ_HEAD(, yp_event) yd_events; 689e7c127fSCraig Rodrigues }; 699e7c127fSCraig Rodrigues 709e7c127fSCraig Rodrigues void 719e7c127fSCraig Rodrigues yp_disable_events(void) 729e7c127fSCraig Rodrigues { 739e7c127fSCraig Rodrigues struct yp_event *ye; 749e7c127fSCraig Rodrigues 759e7c127fSCraig Rodrigues while ((ye = TAILQ_FIRST(&env->sc_yp->yd_events)) != NULL) { 769e7c127fSCraig Rodrigues TAILQ_REMOVE(&env->sc_yp->yd_events, ye, ye_entry); 779e7c127fSCraig Rodrigues event_del(&ye->ye_event); 789e7c127fSCraig Rodrigues free(ye); 799e7c127fSCraig Rodrigues } 809e7c127fSCraig Rodrigues } 819e7c127fSCraig Rodrigues 829e7c127fSCraig Rodrigues void 839e7c127fSCraig Rodrigues yp_enable_events(void) 849e7c127fSCraig Rodrigues { 859e7c127fSCraig Rodrigues int i; 869e7c127fSCraig Rodrigues struct yp_event *ye; 879e7c127fSCraig Rodrigues 88*db891e21SMarcelo Araujo for (i = 0; i < getdtablesize(); i++) { 899e7c127fSCraig Rodrigues if ((ye = calloc(1, sizeof(*ye))) == NULL) 909e7c127fSCraig Rodrigues fatal(NULL); 919e7c127fSCraig Rodrigues event_set(&ye->ye_event, i, EV_READ, yp_fd_event, NULL); 929e7c127fSCraig Rodrigues event_add(&ye->ye_event, NULL); 939e7c127fSCraig Rodrigues TAILQ_INSERT_TAIL(&env->sc_yp->yd_events, ye, ye_entry); 949e7c127fSCraig Rodrigues } 959e7c127fSCraig Rodrigues } 969e7c127fSCraig Rodrigues 979e7c127fSCraig Rodrigues void 989e7c127fSCraig Rodrigues yp_fd_event(int fd, short event, void *p) 999e7c127fSCraig Rodrigues { 1009e7c127fSCraig Rodrigues svc_getreq_common(fd); 1019e7c127fSCraig Rodrigues yp_disable_events(); 1029e7c127fSCraig Rodrigues yp_enable_events(); 1039e7c127fSCraig Rodrigues } 1049e7c127fSCraig Rodrigues 1059e7c127fSCraig Rodrigues void 1069e7c127fSCraig Rodrigues yp_init(struct env *x_env) 1079e7c127fSCraig Rodrigues { 1089e7c127fSCraig Rodrigues struct yp_data *yp; 1099e7c127fSCraig Rodrigues 1109e7c127fSCraig Rodrigues if ((yp = calloc(1, sizeof(*yp))) == NULL) 1119e7c127fSCraig Rodrigues fatal(NULL); 1129e7c127fSCraig Rodrigues TAILQ_INIT(&yp->yd_events); 1139e7c127fSCraig Rodrigues 1149e7c127fSCraig Rodrigues env = x_env; 1159e7c127fSCraig Rodrigues env->sc_yp = yp; 1169e7c127fSCraig Rodrigues 1179e7c127fSCraig Rodrigues (void)pmap_unset(YPPROG, YPVERS); 1189e7c127fSCraig Rodrigues 1199e7c127fSCraig Rodrigues if ((yp->yp_trans_udp = svcudp_create(RPC_ANYSOCK)) == NULL) 1209e7c127fSCraig Rodrigues fatal("cannot create udp service"); 1219e7c127fSCraig Rodrigues if ((yp->yp_trans_tcp = svctcp_create(RPC_ANYSOCK, 0, 0)) == NULL) 1229e7c127fSCraig Rodrigues fatal("cannot create tcp service"); 1239e7c127fSCraig Rodrigues 1249e7c127fSCraig Rodrigues if (!svc_register(yp->yp_trans_udp, YPPROG, YPVERS, 1259e7c127fSCraig Rodrigues yp_dispatch, IPPROTO_UDP)) { 1269e7c127fSCraig Rodrigues fatal("unable to register (YPPROG, YPVERS, udp)"); 1279e7c127fSCraig Rodrigues } 1289e7c127fSCraig Rodrigues if (!svc_register(yp->yp_trans_tcp, YPPROG, YPVERS, 1299e7c127fSCraig Rodrigues yp_dispatch, IPPROTO_TCP)) { 1309e7c127fSCraig Rodrigues fatal("unable to register (YPPROG, YPVERS, tcp)"); 1319e7c127fSCraig Rodrigues } 1329e7c127fSCraig Rodrigues } 1339e7c127fSCraig Rodrigues 1349e7c127fSCraig Rodrigues /* 1359e7c127fSCraig Rodrigues * lots of inspiration from ypserv by Mats O Jansson 1369e7c127fSCraig Rodrigues */ 1379e7c127fSCraig Rodrigues void 1389e7c127fSCraig Rodrigues yp_dispatch(struct svc_req *req, SVCXPRT *trans) 1399e7c127fSCraig Rodrigues { 1409e7c127fSCraig Rodrigues xdrproc_t xdr_argument; 1419e7c127fSCraig Rodrigues xdrproc_t xdr_result; 1429e7c127fSCraig Rodrigues char *result; 1439e7c127fSCraig Rodrigues char *(*cb)(char *, struct svc_req *); 1449e7c127fSCraig Rodrigues union { 1459e7c127fSCraig Rodrigues domainname ypproc_domain_2_arg; 1469e7c127fSCraig Rodrigues domainname ypproc_domain_nonack_2_arg; 1479e7c127fSCraig Rodrigues ypreq_key ypproc_match_2_arg; 1489e7c127fSCraig Rodrigues ypreq_nokey ypproc_first_2_arg; 1499e7c127fSCraig Rodrigues ypreq_key ypproc_next_2_arg; 1509e7c127fSCraig Rodrigues ypreq_xfr ypproc_xfr_2_arg; 1519e7c127fSCraig Rodrigues ypreq_nokey ypproc_all_2_arg; 1529e7c127fSCraig Rodrigues ypreq_nokey ypproc_master_2_arg; 1539e7c127fSCraig Rodrigues ypreq_nokey ypproc_order_2_arg; 1549e7c127fSCraig Rodrigues domainname ypproc_maplist_2_arg; 1559e7c127fSCraig Rodrigues } argument; 1569e7c127fSCraig Rodrigues 1579e7c127fSCraig Rodrigues xdr_argument = (xdrproc_t) xdr_void; 1589e7c127fSCraig Rodrigues xdr_result = (xdrproc_t) xdr_void; 1599e7c127fSCraig Rodrigues cb = NULL; 1609e7c127fSCraig Rodrigues switch (req->rq_proc) { 1619e7c127fSCraig Rodrigues case YPPROC_NULL: 1629e7c127fSCraig Rodrigues xdr_argument = (xdrproc_t) xdr_void; 1639e7c127fSCraig Rodrigues xdr_result = (xdrproc_t) xdr_void; 1649e7c127fSCraig Rodrigues if (yp_check(req) == -1) 1659e7c127fSCraig Rodrigues return; 1669e7c127fSCraig Rodrigues result = NULL; 1679e7c127fSCraig Rodrigues if (!svc_sendreply(trans, (xdrproc_t) xdr_void, 1689e7c127fSCraig Rodrigues (void *)&result)) 1699e7c127fSCraig Rodrigues svcerr_systemerr(trans); 1709e7c127fSCraig Rodrigues return; 1719e7c127fSCraig Rodrigues case YPPROC_DOMAIN: 1729e7c127fSCraig Rodrigues xdr_argument = (xdrproc_t) xdr_domainname; 1739e7c127fSCraig Rodrigues xdr_result = (xdrproc_t) xdr_bool; 1749e7c127fSCraig Rodrigues if (yp_check(req) == -1) 1759e7c127fSCraig Rodrigues return; 1769e7c127fSCraig Rodrigues cb = (void *)ypproc_domain_2_svc; 1779e7c127fSCraig Rodrigues break; 1789e7c127fSCraig Rodrigues case YPPROC_DOMAIN_NONACK: 1799e7c127fSCraig Rodrigues xdr_argument = (xdrproc_t) xdr_domainname; 1809e7c127fSCraig Rodrigues xdr_result = (xdrproc_t) xdr_bool; 1819e7c127fSCraig Rodrigues if (yp_check(req) == -1) 1829e7c127fSCraig Rodrigues return; 1839e7c127fSCraig Rodrigues cb = (void *)ypproc_domain_nonack_2_svc; 1849e7c127fSCraig Rodrigues break; 1859e7c127fSCraig Rodrigues case YPPROC_MATCH: 1869e7c127fSCraig Rodrigues xdr_argument = (xdrproc_t) xdr_ypreq_key; 1879e7c127fSCraig Rodrigues xdr_result = (xdrproc_t) xdr_ypresp_val; 1889e7c127fSCraig Rodrigues if (yp_check(req) == -1) 1899e7c127fSCraig Rodrigues return; 1909e7c127fSCraig Rodrigues cb = (void *)ypproc_match_2_svc; 1919e7c127fSCraig Rodrigues break; 1929e7c127fSCraig Rodrigues case YPPROC_FIRST: 1939e7c127fSCraig Rodrigues xdr_argument = (xdrproc_t) xdr_ypreq_nokey; 1949e7c127fSCraig Rodrigues xdr_result = (xdrproc_t) xdr_ypresp_key_val; 1959e7c127fSCraig Rodrigues if (yp_check(req) == -1) 1969e7c127fSCraig Rodrigues return; 1979e7c127fSCraig Rodrigues cb = (void *)ypproc_first_2_svc; 1989e7c127fSCraig Rodrigues break; 1999e7c127fSCraig Rodrigues case YPPROC_NEXT: 2009e7c127fSCraig Rodrigues xdr_argument = (xdrproc_t) xdr_ypreq_key; 2019e7c127fSCraig Rodrigues xdr_result = (xdrproc_t) xdr_ypresp_key_val; 2029e7c127fSCraig Rodrigues if (yp_check(req) == -1) 2039e7c127fSCraig Rodrigues return; 2049e7c127fSCraig Rodrigues cb = (void *)ypproc_next_2_svc; 2059e7c127fSCraig Rodrigues break; 2069e7c127fSCraig Rodrigues case YPPROC_XFR: 2079e7c127fSCraig Rodrigues if (yp_check(req) == -1) 2089e7c127fSCraig Rodrigues return; 2099e7c127fSCraig Rodrigues svcerr_noproc(trans); 2109e7c127fSCraig Rodrigues return; 2119e7c127fSCraig Rodrigues case YPPROC_CLEAR: 2129e7c127fSCraig Rodrigues log_debug("ypproc_clear"); 2139e7c127fSCraig Rodrigues if (yp_check(req) == -1) 2149e7c127fSCraig Rodrigues return; 2159e7c127fSCraig Rodrigues svcerr_noproc(trans); 2169e7c127fSCraig Rodrigues return; 2179e7c127fSCraig Rodrigues case YPPROC_ALL: 2189e7c127fSCraig Rodrigues log_debug("ypproc_all"); 2199e7c127fSCraig Rodrigues if (yp_check(req) == -1) 2209e7c127fSCraig Rodrigues return; 2219e7c127fSCraig Rodrigues cb = (void *)ypproc_all_2_svc; 2229e7c127fSCraig Rodrigues break; 2239e7c127fSCraig Rodrigues case YPPROC_MASTER: 2249e7c127fSCraig Rodrigues log_debug("ypproc_master"); 2259e7c127fSCraig Rodrigues if (yp_check(req) == -1) 2269e7c127fSCraig Rodrigues return; 2279e7c127fSCraig Rodrigues cb = (void *)ypproc_master_2_svc; 2289e7c127fSCraig Rodrigues break; 2299e7c127fSCraig Rodrigues case YPPROC_ORDER: 2309e7c127fSCraig Rodrigues log_debug("ypproc_order"); 2319e7c127fSCraig Rodrigues if (yp_check(req) == -1) 2329e7c127fSCraig Rodrigues return; 2339e7c127fSCraig Rodrigues svcerr_noproc(trans); 2349e7c127fSCraig Rodrigues return; 2359e7c127fSCraig Rodrigues case YPPROC_MAPLIST: 2369e7c127fSCraig Rodrigues log_debug("ypproc_maplist"); 2379e7c127fSCraig Rodrigues if (yp_check(req) == -1) 2389e7c127fSCraig Rodrigues return; 2399e7c127fSCraig Rodrigues cb = (void *)ypproc_maplist_2_svc; 2409e7c127fSCraig Rodrigues break; 2419e7c127fSCraig Rodrigues default: 2429e7c127fSCraig Rodrigues svcerr_noproc(trans); 2439e7c127fSCraig Rodrigues return; 2449e7c127fSCraig Rodrigues } 2459e7c127fSCraig Rodrigues (void)memset(&argument, 0, sizeof(argument)); 2469e7c127fSCraig Rodrigues 2479e7c127fSCraig Rodrigues if (!svc_getargs(trans, xdr_argument, (caddr_t)&argument)) { 2489e7c127fSCraig Rodrigues svcerr_decode(trans); 2499e7c127fSCraig Rodrigues return; 2509e7c127fSCraig Rodrigues } 2519e7c127fSCraig Rodrigues result = (*cb)((char *)&argument, req); 2529e7c127fSCraig Rodrigues if (result != NULL && !svc_sendreply(trans, xdr_result, result)) 2539e7c127fSCraig Rodrigues svcerr_systemerr(trans); 2549e7c127fSCraig Rodrigues if (!svc_freeargs(trans, xdr_argument, (caddr_t)&argument)) { 2559e7c127fSCraig Rodrigues /* 2569e7c127fSCraig Rodrigues * ypserv does it too. 2579e7c127fSCraig Rodrigues */ 2589e7c127fSCraig Rodrigues fatal("unable to free arguments"); 2599e7c127fSCraig Rodrigues } 2609e7c127fSCraig Rodrigues } 2619e7c127fSCraig Rodrigues 2629e7c127fSCraig Rodrigues int 2639e7c127fSCraig Rodrigues yp_check(struct svc_req *req) 2649e7c127fSCraig Rodrigues { 2659e7c127fSCraig Rodrigues struct sockaddr_in *caller; 2669e7c127fSCraig Rodrigues 2679e7c127fSCraig Rodrigues caller = svc_getcaller(req->rq_xprt); 2689e7c127fSCraig Rodrigues /* 2699e7c127fSCraig Rodrigues * We might want to know who we allow here. 2709e7c127fSCraig Rodrigues */ 2719e7c127fSCraig Rodrigues return (0); 2729e7c127fSCraig Rodrigues } 2739e7c127fSCraig Rodrigues 2749e7c127fSCraig Rodrigues int 2759e7c127fSCraig Rodrigues yp_valid_domain(char *domain, struct ypresp_val *res) 2769e7c127fSCraig Rodrigues { 2779e7c127fSCraig Rodrigues if (domain == NULL) { 2789e7c127fSCraig Rodrigues log_debug("NULL domain !"); 2799e7c127fSCraig Rodrigues return (-1); 2809e7c127fSCraig Rodrigues } 2819e7c127fSCraig Rodrigues if (strcmp(domain, env->sc_domainname) != 0) { 2829e7c127fSCraig Rodrigues res->stat = YP_NODOM; 2839e7c127fSCraig Rodrigues return (-1); 2849e7c127fSCraig Rodrigues } 2859e7c127fSCraig Rodrigues return (0); 2869e7c127fSCraig Rodrigues } 2879e7c127fSCraig Rodrigues 2889e7c127fSCraig Rodrigues bool_t * 2899e7c127fSCraig Rodrigues ypproc_domain_2_svc(domainname *arg, struct svc_req *req) 2909e7c127fSCraig Rodrigues { 2919e7c127fSCraig Rodrigues static bool_t res; 2929e7c127fSCraig Rodrigues 2939e7c127fSCraig Rodrigues res = (bool_t)1; 2949e7c127fSCraig Rodrigues if (strcmp(*arg, env->sc_domainname) != 0) 2959e7c127fSCraig Rodrigues res = (bool_t)0; 2969e7c127fSCraig Rodrigues return (&res); 2979e7c127fSCraig Rodrigues } 2989e7c127fSCraig Rodrigues 2999e7c127fSCraig Rodrigues bool_t * 3009e7c127fSCraig Rodrigues ypproc_domain_nonack_2_svc(domainname *arg, struct svc_req *req) 3019e7c127fSCraig Rodrigues { 3029e7c127fSCraig Rodrigues static bool_t res; 3039e7c127fSCraig Rodrigues 3049e7c127fSCraig Rodrigues if (strcmp(*arg, env->sc_domainname) != 0) 3059e7c127fSCraig Rodrigues return NULL; 3069e7c127fSCraig Rodrigues res = (bool_t)1; 3079e7c127fSCraig Rodrigues return (&res); 3089e7c127fSCraig Rodrigues } 3099e7c127fSCraig Rodrigues 3109e7c127fSCraig Rodrigues ypresp_val * 3119e7c127fSCraig Rodrigues ypproc_match_2_svc(ypreq_key *arg, struct svc_req *req) 3129e7c127fSCraig Rodrigues { 3139e7c127fSCraig Rodrigues struct userent ukey; 3149e7c127fSCraig Rodrigues struct userent *ue; 3159e7c127fSCraig Rodrigues struct groupent gkey; 3169e7c127fSCraig Rodrigues struct groupent *ge; 3179e7c127fSCraig Rodrigues static struct ypresp_val res; 3189e7c127fSCraig Rodrigues const char *estr; 3199e7c127fSCraig Rodrigues char *bp, *cp; 3209e7c127fSCraig Rodrigues char key[YPMAXRECORD+1]; 3219e7c127fSCraig Rodrigues 3229e7c127fSCraig Rodrigues log_debug("matching '%.*s' in map %s", arg->key.keydat_len, 3239e7c127fSCraig Rodrigues arg->key.keydat_val, arg->map); 3249e7c127fSCraig Rodrigues 3259e7c127fSCraig Rodrigues if (yp_valid_domain(arg->domain, (struct ypresp_val *)&res) == -1) 3269e7c127fSCraig Rodrigues return (&res); 3279e7c127fSCraig Rodrigues 3289e7c127fSCraig Rodrigues if (env->sc_user_names == NULL) { 3299e7c127fSCraig Rodrigues /* 3309e7c127fSCraig Rodrigues * tree not ready. 3319e7c127fSCraig Rodrigues */ 3329e7c127fSCraig Rodrigues return (NULL); 3339e7c127fSCraig Rodrigues } 3349e7c127fSCraig Rodrigues 3359e7c127fSCraig Rodrigues if (arg->key.keydat_len > YPMAXRECORD) { 3369e7c127fSCraig Rodrigues log_debug("argument too long"); 3379e7c127fSCraig Rodrigues return (NULL); 3389e7c127fSCraig Rodrigues } 3399e7c127fSCraig Rodrigues bzero(key, sizeof(key)); 3409e7c127fSCraig Rodrigues (void)strncpy(key, arg->key.keydat_val, arg->key.keydat_len); 3419e7c127fSCraig Rodrigues 3429e7c127fSCraig Rodrigues if (strcmp(arg->map, "passwd.byname") == 0 || 3439e7c127fSCraig Rodrigues strcmp(arg->map, "master.passwd.byname") == 0) { 3449e7c127fSCraig Rodrigues ukey.ue_line = key; 3459e7c127fSCraig Rodrigues if ((ue = RB_FIND(user_name_tree, env->sc_user_names, 3469e7c127fSCraig Rodrigues &ukey)) == NULL) { 3479e7c127fSCraig Rodrigues res.stat = YP_NOKEY; 3489e7c127fSCraig Rodrigues return (&res); 3499e7c127fSCraig Rodrigues } 3509e7c127fSCraig Rodrigues 3519e7c127fSCraig Rodrigues yp_make_val(&res, ue->ue_line, 1); 3529e7c127fSCraig Rodrigues return (&res); 3539e7c127fSCraig Rodrigues } else if (strcmp(arg->map, "passwd.byuid") == 0 || 3549e7c127fSCraig Rodrigues strcmp(arg->map, "master.passwd.byuid") == 0) { 3559e7c127fSCraig Rodrigues ukey.ue_uid = strtonum(key, 0, UID_MAX, &estr); 3569e7c127fSCraig Rodrigues if (estr) { 3579e7c127fSCraig Rodrigues res.stat = YP_BADARGS; 3589e7c127fSCraig Rodrigues return (&res); 3599e7c127fSCraig Rodrigues } 3609e7c127fSCraig Rodrigues 3619e7c127fSCraig Rodrigues if ((ue = RB_FIND(user_uid_tree, &env->sc_user_uids, 3629e7c127fSCraig Rodrigues &ukey)) == NULL) { 3639e7c127fSCraig Rodrigues res.stat = YP_NOKEY; 3649e7c127fSCraig Rodrigues return (&res); 3659e7c127fSCraig Rodrigues } 3669e7c127fSCraig Rodrigues 3679e7c127fSCraig Rodrigues yp_make_val(&res, ue->ue_line, 1); 3689e7c127fSCraig Rodrigues return (&res); 3699e7c127fSCraig Rodrigues } else if (strcmp(arg->map, "group.bygid") == 0) { 3709e7c127fSCraig Rodrigues gkey.ge_gid = strtonum(key, 0, GID_MAX, &estr); 3719e7c127fSCraig Rodrigues if (estr) { 3729e7c127fSCraig Rodrigues res.stat = YP_BADARGS; 3739e7c127fSCraig Rodrigues return (&res); 3749e7c127fSCraig Rodrigues } 3759e7c127fSCraig Rodrigues if ((ge = RB_FIND(group_gid_tree, &env->sc_group_gids, 3769e7c127fSCraig Rodrigues &gkey)) == NULL) { 3779e7c127fSCraig Rodrigues res.stat = YP_NOKEY; 3789e7c127fSCraig Rodrigues return (&res); 3799e7c127fSCraig Rodrigues } 3809e7c127fSCraig Rodrigues 3819e7c127fSCraig Rodrigues yp_make_val(&res, ge->ge_line, 1); 3829e7c127fSCraig Rodrigues return (&res); 3839e7c127fSCraig Rodrigues } else if (strcmp(arg->map, "group.byname") == 0) { 3849e7c127fSCraig Rodrigues gkey.ge_line = key; 3859e7c127fSCraig Rodrigues if ((ge = RB_FIND(group_name_tree, env->sc_group_names, 3869e7c127fSCraig Rodrigues &gkey)) == NULL) { 3879e7c127fSCraig Rodrigues res.stat = YP_NOKEY; 3889e7c127fSCraig Rodrigues return (&res); 3899e7c127fSCraig Rodrigues } 3909e7c127fSCraig Rodrigues 3919e7c127fSCraig Rodrigues yp_make_val(&res, ge->ge_line, 1); 3929e7c127fSCraig Rodrigues return (&res); 3939e7c127fSCraig Rodrigues } else if (strcmp(arg->map, "netid.byname") == 0) { 3949e7c127fSCraig Rodrigues bp = cp = key; 3959e7c127fSCraig Rodrigues 3969e7c127fSCraig Rodrigues if (strncmp(bp, "unix.", strlen("unix.")) != 0) { 3979e7c127fSCraig Rodrigues res.stat = YP_BADARGS; 3989e7c127fSCraig Rodrigues return (&res); 3999e7c127fSCraig Rodrigues } 4009e7c127fSCraig Rodrigues 4019e7c127fSCraig Rodrigues bp += strlen("unix."); 4029e7c127fSCraig Rodrigues 4039e7c127fSCraig Rodrigues if (*bp == '\0') { 4049e7c127fSCraig Rodrigues res.stat = YP_BADARGS; 4059e7c127fSCraig Rodrigues return (&res); 4069e7c127fSCraig Rodrigues } 4079e7c127fSCraig Rodrigues 4089e7c127fSCraig Rodrigues if (!(cp = strsep(&bp, "@"))) { 4099e7c127fSCraig Rodrigues res.stat = YP_BADARGS; 4109e7c127fSCraig Rodrigues return (&res); 4119e7c127fSCraig Rodrigues } 4129e7c127fSCraig Rodrigues 4139e7c127fSCraig Rodrigues if (strcmp(bp, arg->domain) != 0) { 4149e7c127fSCraig Rodrigues res.stat = YP_BADARGS; 4159e7c127fSCraig Rodrigues return (&res); 4169e7c127fSCraig Rodrigues } 4179e7c127fSCraig Rodrigues 4189e7c127fSCraig Rodrigues ukey.ue_uid = strtonum(cp, 0, UID_MAX, &estr); 4199e7c127fSCraig Rodrigues if (estr) { 4209e7c127fSCraig Rodrigues res.stat = YP_BADARGS; 4219e7c127fSCraig Rodrigues return (&res); 4229e7c127fSCraig Rodrigues } 4239e7c127fSCraig Rodrigues 4249e7c127fSCraig Rodrigues if ((ue = RB_FIND(user_uid_tree, &env->sc_user_uids, 4259e7c127fSCraig Rodrigues &ukey)) == NULL) { 4269e7c127fSCraig Rodrigues res.stat = YP_NOKEY; 4279e7c127fSCraig Rodrigues return (&res); 4289e7c127fSCraig Rodrigues } 4299e7c127fSCraig Rodrigues 4309e7c127fSCraig Rodrigues yp_make_val(&res, ue->ue_netid_line, 0); 4319e7c127fSCraig Rodrigues return (&res); 4329e7c127fSCraig Rodrigues 4339e7c127fSCraig Rodrigues } else { 4349e7c127fSCraig Rodrigues log_debug("unknown map %s", arg->map); 4359e7c127fSCraig Rodrigues res.stat = YP_NOMAP; 4369e7c127fSCraig Rodrigues return (&res); 4379e7c127fSCraig Rodrigues } 4389e7c127fSCraig Rodrigues } 4399e7c127fSCraig Rodrigues 4409e7c127fSCraig Rodrigues ypresp_key_val * 4419e7c127fSCraig Rodrigues ypproc_first_2_svc(ypreq_nokey *arg, struct svc_req *req) 4429e7c127fSCraig Rodrigues { 4439e7c127fSCraig Rodrigues static struct ypresp_key_val res; 4449e7c127fSCraig Rodrigues 4459e7c127fSCraig Rodrigues if (yp_valid_domain(arg->domain, (struct ypresp_val *)&res) == -1) 4469e7c127fSCraig Rodrigues return (&res); 4479e7c127fSCraig Rodrigues 4489e7c127fSCraig Rodrigues if (strcmp(arg->map, "passwd.byname") == 0 || 4499e7c127fSCraig Rodrigues strcmp(arg->map, "master.passwd.byname") == 0) { 4509e7c127fSCraig Rodrigues if (env->sc_user_lines == NULL) 4519e7c127fSCraig Rodrigues return (NULL); 4529e7c127fSCraig Rodrigues 4539e7c127fSCraig Rodrigues yp_make_keyval(&res, env->sc_user_lines, env->sc_user_lines); 4549e7c127fSCraig Rodrigues } else if (strcmp(arg->map, "group.byname") == 0) { 4559e7c127fSCraig Rodrigues if (env->sc_group_lines == NULL) 4569e7c127fSCraig Rodrigues return (NULL); 4579e7c127fSCraig Rodrigues 4589e7c127fSCraig Rodrigues yp_make_keyval(&res, env->sc_group_lines, env->sc_group_lines); 4599e7c127fSCraig Rodrigues } else { 4609e7c127fSCraig Rodrigues log_debug("unknown map %s", arg->map); 4619e7c127fSCraig Rodrigues res.stat = YP_NOMAP; 4629e7c127fSCraig Rodrigues } 4639e7c127fSCraig Rodrigues 4649e7c127fSCraig Rodrigues return (&res); 4659e7c127fSCraig Rodrigues } 4669e7c127fSCraig Rodrigues 4679e7c127fSCraig Rodrigues ypresp_key_val * 4689e7c127fSCraig Rodrigues ypproc_next_2_svc(ypreq_key *arg, struct svc_req *req) 4699e7c127fSCraig Rodrigues { 4709e7c127fSCraig Rodrigues struct userent ukey; 4719e7c127fSCraig Rodrigues struct userent *ue; 4729e7c127fSCraig Rodrigues struct groupent gkey; 4739e7c127fSCraig Rodrigues struct groupent *ge; 4749e7c127fSCraig Rodrigues char *line; 4759e7c127fSCraig Rodrigues static struct ypresp_key_val res; 4769e7c127fSCraig Rodrigues char key[YPMAXRECORD+1]; 4779e7c127fSCraig Rodrigues 4789e7c127fSCraig Rodrigues if (yp_valid_domain(arg->domain, (struct ypresp_val *)&res) == -1) 4799e7c127fSCraig Rodrigues return (&res); 4809e7c127fSCraig Rodrigues 4819e7c127fSCraig Rodrigues if (strcmp(arg->map, "passwd.byname") == 0 || 4829e7c127fSCraig Rodrigues strcmp(arg->map, "master.passwd.byname") == 0) { 4839e7c127fSCraig Rodrigues bzero(key, sizeof(key)); 4849e7c127fSCraig Rodrigues (void)strncpy(key, arg->key.keydat_val, 4859e7c127fSCraig Rodrigues arg->key.keydat_len); 4869e7c127fSCraig Rodrigues ukey.ue_line = key; 4879e7c127fSCraig Rodrigues if ((ue = RB_FIND(user_name_tree, env->sc_user_names, 4889e7c127fSCraig Rodrigues &ukey)) == NULL) { 4899e7c127fSCraig Rodrigues /* 4909e7c127fSCraig Rodrigues * canacar's trick: 4919e7c127fSCraig Rodrigues * the user might have been deleted in between calls 4929e7c127fSCraig Rodrigues * to next since the tree may be modified by a reload. 4939e7c127fSCraig Rodrigues * next should still return the next user in 4949e7c127fSCraig Rodrigues * lexicographical order, hence insert the search key 4959e7c127fSCraig Rodrigues * and look up the next field, then remove it again. 4969e7c127fSCraig Rodrigues */ 4979e7c127fSCraig Rodrigues RB_INSERT(user_name_tree, env->sc_user_names, &ukey); 4989e7c127fSCraig Rodrigues if ((ue = RB_NEXT(user_name_tree, &env->sc_user_names, 4999e7c127fSCraig Rodrigues &ukey)) == NULL) { 5009e7c127fSCraig Rodrigues RB_REMOVE(user_name_tree, env->sc_user_names, 5019e7c127fSCraig Rodrigues &ukey); 5029e7c127fSCraig Rodrigues res.stat = YP_NOKEY; 5039e7c127fSCraig Rodrigues return (&res); 5049e7c127fSCraig Rodrigues } 5059e7c127fSCraig Rodrigues RB_REMOVE(user_name_tree, env->sc_user_names, &ukey); 5069e7c127fSCraig Rodrigues } 5079e7c127fSCraig Rodrigues line = ue->ue_line + (strlen(ue->ue_line) + 1); 5089e7c127fSCraig Rodrigues line = line + (strlen(line) + 1); 5099e7c127fSCraig Rodrigues yp_make_keyval(&res, line, line); 5109e7c127fSCraig Rodrigues return (&res); 5119e7c127fSCraig Rodrigues 5129e7c127fSCraig Rodrigues 5139e7c127fSCraig Rodrigues } else if (strcmp(arg->map, "group.byname") == 0) { 5149e7c127fSCraig Rodrigues bzero(key, sizeof(key)); 5159e7c127fSCraig Rodrigues (void)strncpy(key, arg->key.keydat_val, 5169e7c127fSCraig Rodrigues arg->key.keydat_len); 5179e7c127fSCraig Rodrigues 5189e7c127fSCraig Rodrigues gkey.ge_line = key; 5199e7c127fSCraig Rodrigues if ((ge = RB_FIND(group_name_tree, env->sc_group_names, 5209e7c127fSCraig Rodrigues &gkey)) == NULL) { 5219e7c127fSCraig Rodrigues /* 5229e7c127fSCraig Rodrigues * canacar's trick reloaded. 5239e7c127fSCraig Rodrigues */ 5249e7c127fSCraig Rodrigues RB_INSERT(group_name_tree, env->sc_group_names, &gkey); 5259e7c127fSCraig Rodrigues if ((ge = RB_NEXT(group_name_tree, &env->sc_group_names, 5269e7c127fSCraig Rodrigues &gkey)) == NULL) { 5279e7c127fSCraig Rodrigues RB_REMOVE(group_name_tree, env->sc_group_names, 5289e7c127fSCraig Rodrigues &gkey); 5299e7c127fSCraig Rodrigues res.stat = YP_NOKEY; 5309e7c127fSCraig Rodrigues return (&res); 5319e7c127fSCraig Rodrigues } 5329e7c127fSCraig Rodrigues RB_REMOVE(group_name_tree, env->sc_group_names, &gkey); 5339e7c127fSCraig Rodrigues } 5349e7c127fSCraig Rodrigues 5359e7c127fSCraig Rodrigues line = ge->ge_line + (strlen(ge->ge_line) + 1); 5369e7c127fSCraig Rodrigues line = line + (strlen(line) + 1); 5379e7c127fSCraig Rodrigues yp_make_keyval(&res, line, line); 5389e7c127fSCraig Rodrigues return (&res); 5399e7c127fSCraig Rodrigues } else { 5409e7c127fSCraig Rodrigues log_debug("unknown map %s", arg->map); 5419e7c127fSCraig Rodrigues res.stat = YP_NOMAP; 5429e7c127fSCraig Rodrigues return (&res); 5439e7c127fSCraig Rodrigues } 5449e7c127fSCraig Rodrigues } 5459e7c127fSCraig Rodrigues 5469e7c127fSCraig Rodrigues ypresp_all * 5479e7c127fSCraig Rodrigues ypproc_all_2_svc(ypreq_nokey *arg, struct svc_req *req) 5489e7c127fSCraig Rodrigues { 5499e7c127fSCraig Rodrigues static struct ypresp_all res; 5509e7c127fSCraig Rodrigues 5519e7c127fSCraig Rodrigues if (yp_valid_domain(arg->domain, (struct ypresp_val *)&res) == -1) 5529e7c127fSCraig Rodrigues return (&res); 5539e7c127fSCraig Rodrigues 5549e7c127fSCraig Rodrigues svcerr_auth(req->rq_xprt, AUTH_FAILED); 5559e7c127fSCraig Rodrigues return (NULL); 5569e7c127fSCraig Rodrigues } 5579e7c127fSCraig Rodrigues 5589e7c127fSCraig Rodrigues ypresp_master * 5599e7c127fSCraig Rodrigues ypproc_master_2_svc(ypreq_nokey *arg, struct svc_req *req) 5609e7c127fSCraig Rodrigues { 5619e7c127fSCraig Rodrigues static struct ypresp_master res; 5629e7c127fSCraig Rodrigues 5639e7c127fSCraig Rodrigues if (yp_valid_domain(arg->domain, (struct ypresp_val *)&res) == -1) 5649e7c127fSCraig Rodrigues return (&res); 5659e7c127fSCraig Rodrigues 5669e7c127fSCraig Rodrigues res.stat = YP_YPERR; 5679e7c127fSCraig Rodrigues return (&res); 5689e7c127fSCraig Rodrigues } 5699e7c127fSCraig Rodrigues 5709e7c127fSCraig Rodrigues ypresp_maplist * 5719e7c127fSCraig Rodrigues ypproc_maplist_2_svc(domainname *arg, struct svc_req *req) 5729e7c127fSCraig Rodrigues { 5739e7c127fSCraig Rodrigues size_t i; 5749e7c127fSCraig Rodrigues static struct { 5759e7c127fSCraig Rodrigues char *name; 5769e7c127fSCraig Rodrigues int cond; 5779e7c127fSCraig Rodrigues } mapnames[] = { 5789e7c127fSCraig Rodrigues { "passwd.byname", YPMAP_PASSWD_BYNAME }, 5799e7c127fSCraig Rodrigues { "passwd.byuid", YPMAP_PASSWD_BYUID }, 5809e7c127fSCraig Rodrigues { "master.passwd.byname", YPMAP_MASTER_PASSWD_BYNAME }, 5819e7c127fSCraig Rodrigues { "master.passwd.byuid", YPMAP_MASTER_PASSWD_BYUID }, 5829e7c127fSCraig Rodrigues { "group.byname", YPMAP_GROUP_BYNAME }, 5839e7c127fSCraig Rodrigues { "group.bygid", YPMAP_GROUP_BYGID }, 5849e7c127fSCraig Rodrigues { "netid.byname", YPMAP_NETID_BYNAME }, 5859e7c127fSCraig Rodrigues }; 5869e7c127fSCraig Rodrigues static ypresp_maplist res; 5879e7c127fSCraig Rodrigues static struct ypmaplist maps[sizeof(mapnames) / sizeof(mapnames[0])]; 5889e7c127fSCraig Rodrigues 5899e7c127fSCraig Rodrigues if (yp_valid_domain(*arg, (struct ypresp_val *)&res) == -1) 5909e7c127fSCraig Rodrigues return (&res); 5919e7c127fSCraig Rodrigues 5929e7c127fSCraig Rodrigues res.stat = YP_TRUE; 5939e7c127fSCraig Rodrigues res.maps = NULL; 5949e7c127fSCraig Rodrigues for (i = 0; i < sizeof(mapnames) / sizeof(mapnames[0]); i++) { 5959e7c127fSCraig Rodrigues if (!(env->sc_flags & mapnames[i].cond)) 5969e7c127fSCraig Rodrigues continue; 5979e7c127fSCraig Rodrigues maps[i].map = mapnames[i].name; 5989e7c127fSCraig Rodrigues maps[i].next = res.maps; 5999e7c127fSCraig Rodrigues res.maps = &maps[i]; 6009e7c127fSCraig Rodrigues } 6019e7c127fSCraig Rodrigues 6029e7c127fSCraig Rodrigues return (&res); 6039e7c127fSCraig Rodrigues } 6049e7c127fSCraig Rodrigues 6059e7c127fSCraig Rodrigues void 6069e7c127fSCraig Rodrigues yp_make_val(struct ypresp_val *res, char *line, int replacecolon) 6079e7c127fSCraig Rodrigues { 6089e7c127fSCraig Rodrigues static char buf[LINE_WIDTH]; 6099e7c127fSCraig Rodrigues 6109e7c127fSCraig Rodrigues bzero(buf, sizeof(buf)); 6119e7c127fSCraig Rodrigues 6129e7c127fSCraig Rodrigues if (replacecolon) 6139e7c127fSCraig Rodrigues line[strlen(line)] = ':'; 6149e7c127fSCraig Rodrigues (void)strlcpy(buf, line, sizeof(buf)); 6159e7c127fSCraig Rodrigues if (replacecolon) 6169e7c127fSCraig Rodrigues line[strcspn(line, ":")] = '\0'; 6179e7c127fSCraig Rodrigues log_debug("sending out %s", buf); 6189e7c127fSCraig Rodrigues 6199e7c127fSCraig Rodrigues res->stat = YP_TRUE; 6209e7c127fSCraig Rodrigues res->val.valdat_len = strlen(buf); 6219e7c127fSCraig Rodrigues res->val.valdat_val = buf; 6229e7c127fSCraig Rodrigues } 6239e7c127fSCraig Rodrigues 6249e7c127fSCraig Rodrigues void 6259e7c127fSCraig Rodrigues yp_make_keyval(struct ypresp_key_val *res, char *key, char *line) 6269e7c127fSCraig Rodrigues { 6279e7c127fSCraig Rodrigues static char keybuf[YPMAXRECORD+1]; 6289e7c127fSCraig Rodrigues static char buf[LINE_WIDTH]; 6299e7c127fSCraig Rodrigues 6309e7c127fSCraig Rodrigues bzero(keybuf, sizeof(keybuf)); 6319e7c127fSCraig Rodrigues bzero(buf, sizeof(buf)); 6329e7c127fSCraig Rodrigues 6339e7c127fSCraig Rodrigues (void)strlcpy(keybuf, key, sizeof(keybuf)); 6349e7c127fSCraig Rodrigues res->key.keydat_len = strlen(keybuf); 6359e7c127fSCraig Rodrigues res->key.keydat_val = keybuf; 6369e7c127fSCraig Rodrigues 6379e7c127fSCraig Rodrigues if (*line == '\0') { 6389e7c127fSCraig Rodrigues res->stat = YP_NOMORE; 6399e7c127fSCraig Rodrigues return; 6409e7c127fSCraig Rodrigues } 6419e7c127fSCraig Rodrigues res->stat = YP_TRUE; 6429e7c127fSCraig Rodrigues line[strlen(line)] = ':'; 6439e7c127fSCraig Rodrigues (void)strlcpy(buf, line, sizeof(buf)); 6449e7c127fSCraig Rodrigues line[strcspn(line, ":")] = '\0'; 6459e7c127fSCraig Rodrigues log_debug("sending out %s => %s", keybuf, buf); 6469e7c127fSCraig Rodrigues 6479e7c127fSCraig Rodrigues res->val.valdat_len = strlen(buf); 6489e7c127fSCraig Rodrigues res->val.valdat_val = buf; 6499e7c127fSCraig Rodrigues } 650