#ifdef HAVE_CONFIG_H #include "../config.h" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include "map.h" #include "nis.h" #include "plugin.h" static ssize_t nis_write_with_retry(struct plugin_state *state, int fd, const void *buffer1, ssize_t length1, const void *buffer2, ssize_t length2) { ssize_t sent, i; struct iovec iov[2]; int iovc; sent = 0; while ((sent != -1) && (sent < (length1 + length2))) { if (sent < length1) { iov[0].iov_base = ((char *) buffer1) + sent; iov[0].iov_len = length1 - sent; iov[1].iov_base = (char *) buffer2; iov[1].iov_len = length2; iovc = 2; } else { iov[0].iov_base = ((char *) buffer2) + (sent - length1); iov[0].iov_len = length2 - (sent - length1); iovc = 1; } i = writev(fd, &iov[0], iovc); switch (i) { case 0: sent = -1; break; case -1: switch (errno) { case EAGAIN: continue; break; default: slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "Got error %s sending " "%d bytes (at %d) to %d.\n", strerror(errno), length1 + length2, sent, fd); sent = -1; break; } break; default: sent += i; break; } } return sent; } /* Send a reply which _could_ be sent over a datagram. */ static void nis_reply_fragment(struct plugin_state *state, int client, struct sockaddr *client_addr, socklen_t client_addrlen, struct rpc_msg *reply, XDR *reply_xdrs, char *reply_buf, bool_t first_fragment, bool_t last_fragment) { uint32_t len; if (client_addr != NULL) { /* It's a datagram socket, so there's nothing to do but send * the data by itself. */ xdr_replymsg(reply_xdrs, reply); slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "Sending datagram reply (%d bytes).\n", xdr_getpos(reply_xdrs)); sendto(client, reply_buf, xdr_getpos(reply_xdrs), 0, client_addr, client_addrlen); } else { /* Record reply - one fragment. */ if (first_fragment) { xdr_replymsg(reply_xdrs, reply); } /* Calculate the fragment length bytes. */ len = htonl(xdr_getpos(reply_xdrs) | (last_fragment ? 0x80000000 : 0)); /* Send the data to the client. */ if (nis_write_with_retry(state, client, &len, 4, reply_buf, xdr_getpos(reply_xdrs)) == 4 + xdr_getpos(reply_xdrs)) { slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "Stream reply (4+%d bytes) sent.\n", xdr_getpos(reply_xdrs)); } else { slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "Stream reply (4+%d bytes) failed!\n"); } } } /* Send an entire reply datagram or record at once. */ static void nis_reply(struct plugin_state *state, int client, struct sockaddr *client_addr, socklen_t client_addrlen, struct rpc_msg *reply, XDR *reply_xdrs, char *reply_buf) { nis_reply_fragment(state, client, client_addr, client_addrlen, reply, reply_xdrs, reply_buf, TRUE, TRUE); } /* Indicate whether or not we serve the specified domain. */ static void nis_domain(struct plugin_state *state, int client, struct sockaddr *client_addr, socklen_t client_addrlen, XDR *request_xdrs, PRBool reply_on_failure, struct rpc_msg *reply, XDR *reply_xdrs, char *reply_buf, bool_t *reply_bool) { char *domain; *reply_bool = FALSE; if (xdr_string(request_xdrs, &domain, YPMAXDOMAIN)) { map_supports_domain(state, domain, reply_bool); if (*reply_bool || reply_on_failure) { slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "domain(%s) -> %s\n", domain, *reply_bool ? "TRUE" : "FALSE"); nis_reply(state, client, client_addr, client_addrlen, reply, reply_xdrs, reply_buf); } else { slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "domain(%s) -> %d (no reply)\n", domain, *reply_bool ? "TRUE" : "FALSE"); } } else { slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "argument parsing error\n"); /* XXX */ } } static void nis_match(struct plugin_state *state, int client, struct sockaddr *client_addr, socklen_t client_addrlen, XDR *request_xdrs, struct rpc_msg *reply, XDR *reply_xdrs, char *reply_buf, struct ypresp_val *reply_val) { struct ypreq_key req_key; memset(&req_key, 0, sizeof(req_key)); memset(reply_val, 0, sizeof(*reply_val)); if (xdr_ypreq_key(request_xdrs, &req_key)) { if (map_match(state, req_key.domain, req_key.map, req_key.keydat.keydat_len, req_key.keydat.keydat_val, &reply_val->valdat.valdat_len, &reply_val->valdat.valdat_val)) { reply_val->status = YP_TRUE; slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "match(%s/%s/%.*s) -> %d\n", req_key.domain, req_key.map, (int) req_key.keydat.keydat_len, req_key.keydat.keydat_val, reply_val->status); } else { reply_val->status = YP_NOKEY; } nis_reply(state, client, client_addr, client_addrlen, reply, reply_xdrs, reply_buf); } else { /* XXX */ } } static void nis_first(struct plugin_state *state, int client, struct sockaddr *client_addr, socklen_t client_addrlen, XDR *request_xdrs, struct rpc_msg *reply, XDR *reply_xdrs, char *reply_buf, struct ypresp_key_val *reply_key_val) { struct ypreq_nokey req_nokey; PRBool map_supported; memset(&req_nokey, 0, sizeof(req_nokey)); memset(reply_key_val, 0, sizeof(*reply_key_val)); if (xdr_ypreq_nokey(request_xdrs, &req_nokey)) { if (map_first(state, req_nokey.domain, req_nokey.map, &reply_key_val->keydat.keydat_len, &reply_key_val->keydat.keydat_val, &reply_key_val->valdat.valdat_len, &reply_key_val->valdat.valdat_val)) { reply_key_val->status = YP_TRUE; slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "first(%s/%s) -> %d\n", req_nokey.domain, req_nokey.map, reply_key_val->status); } else { map_supported = FALSE; map_supports_map(state, req_nokey.domain, req_nokey.map, &map_supported); reply_key_val->status = map_supported ? YP_NOKEY : YP_NOMAP; } nis_reply(state, client, client_addr, client_addrlen, reply, reply_xdrs, reply_buf); } else { /* XXX */ } } static void nis_next(struct plugin_state *state, int client, struct sockaddr *client_addr, socklen_t client_addrlen, XDR *request_xdrs, struct rpc_msg *reply, XDR *reply_xdrs, char *reply_buf, struct ypresp_key_val *reply_key_val) { struct ypreq_key req_key; memset(&req_key, 0, sizeof(req_key)); memset(reply_key_val, 0, sizeof(*reply_key_val)); if (xdr_ypreq_key(request_xdrs, &req_key)) { if (map_next(state, req_key.domain, req_key.map, req_key.keydat.keydat_len, req_key.keydat.keydat_val, &reply_key_val->keydat.keydat_len, &reply_key_val->keydat.keydat_val, &reply_key_val->valdat.valdat_len, &reply_key_val->valdat.valdat_val)) { reply_key_val->status = YP_TRUE; slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "next(%s/%s/%.*s) -> %d\n", req_key.keydat.keydat_len, req_key.keydat.keydat_val, req_key.domain, req_key.map, reply_key_val->status); } else { reply_key_val->status = YP_NOKEY; slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "next(%s/%s/%.*s) -> no more!\n", req_key.keydat.keydat_len, req_key.keydat.keydat_val, req_key.domain, req_key.map); } nis_reply(state, client, client_addr, client_addrlen, reply, reply_xdrs, reply_buf); } else { /* XXX */ } } static void nis_master(struct plugin_state *state, int client, struct sockaddr *client_addr, socklen_t client_addrlen, XDR *request_xdrs, struct rpc_msg *reply, XDR *reply_xdrs, char *reply_buf, struct ypresp_master *reply_master) { struct ypreq_nokey req_nokey; memset(&req_nokey, 0, sizeof(req_nokey)); memset(reply_master, 0, sizeof(*reply_master)); if (xdr_ypreq_nokey(request_xdrs, &req_nokey)) { reply_master->status = YP_TRUE; reply_master->master = "me, right here"; /* XXX */ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "master(%s/%s) -> %s\n", req_nokey.domain, req_nokey.map, reply_master->master); nis_reply(state, client, client_addr, client_addrlen, reply, reply_xdrs, reply_buf); } else { /* XXX */ } } static void nis_order(struct plugin_state *state, int client, struct sockaddr *client_addr, socklen_t client_addrlen, XDR *request_xdrs, struct rpc_msg *reply, XDR *reply_xdrs, char *reply_buf, struct ypresp_order *reply_order) { struct ypreq_nokey req_nokey; memset(&req_nokey, 0, sizeof(req_nokey)); memset(reply_order, 0, sizeof(*reply_order)); if (xdr_ypreq_nokey(request_xdrs, &req_nokey)) { reply_order->status = YP_TRUE; if (map_order(state, req_nokey.domain, req_nokey.map, &reply_order->ordernum)) { reply_order->status = YP_TRUE; slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "order(%s/%s) -> %d\n", req_nokey.domain, req_nokey.map, reply_order->ordernum); } else { reply_order->status = YP_FALSE; slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "order(%s/%s) -> ?\n", req_nokey.domain, req_nokey.map); } nis_reply(state, client, client_addr, client_addrlen, reply, reply_xdrs, reply_buf); } else { /* XXX */ } } static void nis_maplist(struct plugin_state *state, int client, struct sockaddr *client_addr, socklen_t client_addrlen, XDR *request_xdrs, struct rpc_msg *reply, XDR *reply_xdrs, char *reply_buf, struct ypresp_maplist *reply_maplist) { char *domain; struct ypmaplist *list; memset(reply_maplist, 0, sizeof(*reply_maplist)); if (xdr_string(request_xdrs, &domain, YPMAXDOMAIN)) { reply_maplist->status = YP_TRUE; reply_maplist->list = NULL; /* XXX */ if (reply_maplist->list == NULL) { slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "maplist(%s) -> (none)\n", domain); } else { for (list = reply_maplist->list; list != NULL; list = list->next) { slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "maplist(%s) -> %s\n", domain, list->map); } } nis_reply(state, client, client_addr, client_addrlen, reply, reply_xdrs, reply_buf); } else { /* XXX */ } } static void nis_all(struct plugin_state *state, int client, struct sockaddr *client_addr, socklen_t client_addrlen, XDR *request_xdrs, struct rpc_msg *reply, XDR *reply_xdrs, char *reply_buf, struct ypresp_all *reply_all) { struct ypreq_nokey req_nokey; keydat_t *reply_key; valdat_t *reply_val; PRBool supported; memset(&req_nokey, 0, sizeof(req_nokey)); reply_key = &reply_all->ypresp_all_u.val.keydat; reply_val = &reply_all->ypresp_all_u.val.valdat; if (xdr_ypreq_nokey(request_xdrs, &req_nokey)) { if (!map_supports_map(state, req_nokey.domain, req_nokey.map, &supported) || !supported) { /* No entries? No such map final status. */ reply_all->more = TRUE; reply_all->ypresp_all_u.val.status = YP_NOMAP; reply_key->keydat_len = 0; reply_val->valdat_len = 0; nis_reply_fragment(state, client, client_addr, client_addrlen, reply, reply_xdrs, reply_buf, TRUE, FALSE); /* End of data. */ reply_all->more = FALSE; xdr_setpos(reply_xdrs, 0); xdr_ypresp_all(reply_xdrs, reply_all); nis_reply_fragment(state, client, client_addr, client_addrlen, reply, reply_xdrs, reply_buf, FALSE, TRUE); } else { bool_t first; reply_all->more = TRUE; reply_all->ypresp_all_u.val.status = YP_TRUE; reply_all->more = map_first(state, req_nokey.domain, req_nokey.map, &reply_key->keydat_len, &reply_key->keydat_val, &reply_val->valdat_len, &reply_val->valdat_val); first = TRUE; do { /* Send back a result. If it's the first * entry, also send back the reply header. */ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "all(%s/%s) -> (%.*s),%d\n", req_nokey.domain, req_nokey.map, reply_key->keydat_len, reply_key->keydat_val, reply_all->more); nis_reply_fragment(state, client, client_addr, client_addrlen, reply, reply_xdrs, reply_buf, first, FALSE); first = FALSE; /* Find the next entry. */ reply_all->more = map_next(state, req_nokey.domain, req_nokey.map, reply_key->keydat_len, reply_key->keydat_val, &reply_key->keydat_len, &reply_key->keydat_val, &reply_val->valdat_len, &reply_val->valdat_val); /* If we got an entry, encode it. */ if (reply_all->more) { xdr_setpos(reply_xdrs, 0); xdr_ypresp_all(reply_xdrs, reply_all); } } while (reply_all->more); /* Send the end-of-map marker. */ reply_all->ypresp_all_u.val.status = YP_NOMORE; reply_key->keydat_len = 0; reply_val->valdat_len = 0; xdr_setpos(reply_xdrs, 0); reply_all->more = TRUE; xdr_ypresp_all(reply_xdrs, reply_all); /* End of data. */ reply_all->more = FALSE; xdr_ypresp_all(reply_xdrs, reply_all); /* Bundle those two chunks into one reply. */ nis_reply_fragment(state, client, client_addr, client_addrlen, reply, reply_xdrs, reply_buf, FALSE, TRUE); slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "all(%s/%s) done\n", req_nokey.domain, req_nokey.map); } } else { /* XXX */ } } /* Process a NIS request in the buffer. If we get a client address, then we * assume that the client is a datagram client, otherwise we assume it's a * stream client. */ void nis_process_request(struct plugin_state *state, int client, struct sockaddr *client_addr, socklen_t client_addrlen, char *request_buf, size_t request_buflen) { XDR request_xdrs, reply_xdrs, auth_xdrs; AUTH *request_auth, *reply_auth; char reply_buf[64000], auth_buf[64000]; struct rpc_msg request, reply; int superuser, auth_flavor, auth_len; struct ypresp_val reply_val; struct ypresp_key_val reply_key_val; struct ypresp_all reply_all; struct ypresp_master reply_master; struct ypresp_order reply_order; struct ypresp_maplist reply_maplist; struct accepted_reply *accepted; PRBool reply_bool; memset(&request_xdrs, 0, sizeof(request_xdrs)); memset(&reply_xdrs, 0, sizeof(reply_xdrs)); memset(&request, 0, sizeof(request)); memset(&reply, 0, sizeof(reply)); /* Parse the client request and make sure it looks like an RPC. */ xdrmem_create(&request_xdrs, request_buf, request_buflen, XDR_DECODE); if (!xdr_callmsg(&request_xdrs, &request)) { slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "error parsing client RPC request!\n"); return; } if (request.rm_direction != CALL) { slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "client didn't send us an actual request\n"); goto done; } /* Now we know we've got a request to respond to. */ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "client request prog=%d,ver=%d,proc=%d\n", request.rm_call.cb_prog, request.rm_call.cb_vers, request.rm_call.cb_proc); xdrmem_create(&reply_xdrs, reply_buf, sizeof(reply_buf), XDR_ENCODE); /* Validate the client's credentials. */ auth_flavor = request.rm_call.cb_cred.oa_flavor; switch (auth_flavor) { case AUTH_SYS: request_auth = authunix_create_default(); break; case AUTH_NONE: default: request_auth = authnone_create(); break; } if (auth_validate(request_auth, &request.rm_call.cb_cred)) { switch (auth_flavor) { case AUTH_SYS: slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "validated auth_sys creds\n"); superuser = 0; break; case AUTH_NONE: slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "validated \"none\" creds\n"); superuser = 0; break; default: slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "validated other creds\n"); superuser = 0; break; } } else { slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "failed to validate client creds\n"); superuser = 0; } auth_destroy(request_auth); /* Build the authenticator for our response. */ xdrmem_create(&auth_xdrs, auth_buf, sizeof(auth_buf), XDR_ENCODE); switch (auth_flavor) { case AUTH_SYS: reply_auth = authunix_create_default(); break; case AUTH_NONE: default: reply_auth = authnone_create(); break; } auth_marshall(reply_auth, &auth_xdrs); auth_destroy(reply_auth); auth_len = xdr_getpos(&auth_xdrs); xdr_destroy(&auth_xdrs); slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "built reply authenticator\n"); /* Fill out the common RPC reply fields. */ reply.rm_xid = request.rm_xid; reply.rm_direction = REPLY; /* If the request isn't meant for us, return an error. */ if ((request.rm_direction != CALL) || (request.rm_call.cb_rpcvers != 2) || (request.rm_call.cb_prog != YPPROG) || (request.rm_call.cb_vers != YPVERS)) { reply.rm_reply.rp_stat = MSG_DENIED; reply.rm_reply.rp_rjct.rj_stat = RPC_MISMATCH; xdr_replymsg(&reply_xdrs, &reply); slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "program request mismatch\n"); goto send_reply; } /* Fill in the default reply - success, no data returned. */ reply.rm_reply.rp_stat = MSG_ACCEPTED; accepted = &reply.rm_reply.rp_acpt; accepted->ar_stat = SUCCESS; accepted->ar_results.where = (caddr_t) NULL; accepted->ar_results.proc = (xdrproc_t) xdr_void; /* Now figure out what we were asked to do. */ switch (request.rm_call.cb_proc) { default: /* If we don't know the specific request, we'll return a * mismatch error. */ reply.rm_reply.rp_stat = MSG_DENIED; reply.rm_reply.rp_rjct.rj_stat = RPC_MISMATCH; break; case YPPROC_NULL: slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "yp_null()\n"); /* Do nothing. The default successful reply is fine. */ break; case YPPROC_DOMAIN: case YPPROC_DOMAIN_NONACK: slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, request.rm_call.cb_proc == YPPROC_DOMAIN ? "yp_domain()\n" : "yp_domainnonack()\n"); /* Change the reply data to be a boolean. */ memset(&reply_bool, 0, sizeof(reply_bool)); accepted->ar_results.where = (caddr_t) &reply_bool; accepted->ar_results.proc = (xdrproc_t) xdr_bool; /* Call the real function. */ nis_domain(state, client, client_addr, client_addrlen, &request_xdrs, request.rm_call.cb_proc == YPPROC_DOMAIN, &reply, &reply_xdrs, reply_buf, &reply_bool); goto sent_reply; break; case YPPROC_MATCH: slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "yp_match()\n"); /* Change the reply data to be a resp_val. */ memset(&reply_val, 0, sizeof(reply_val)); accepted->ar_results.where = (caddr_t) &reply_val; accepted->ar_results.proc = (xdrproc_t) xdr_ypresp_val; /* Call the real function. */ nis_match(state, client, client_addr, client_addrlen, &request_xdrs, &reply, &reply_xdrs, reply_buf, &reply_val); goto sent_reply; break; case YPPROC_FIRST: slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "yp_first()\n"); /* Change the reply data to be a resp_key_val. */ memset(&reply_key_val, 0, sizeof(reply_key_val)); accepted->ar_results.where = (caddr_t) &reply_key_val; accepted->ar_results.proc = (xdrproc_t) xdr_ypresp_key_val; /* Call the real function. */ nis_first(state, client, client_addr, client_addrlen, &request_xdrs, &reply, &reply_xdrs, reply_buf, &reply_key_val); goto sent_reply; break; case YPPROC_NEXT: slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "yp_next()\n"); /* Change the reply data to be a resp_key_val. */ memset(&reply_key_val, 0, sizeof(reply_key_val)); accepted->ar_results.where = (caddr_t) &reply_key_val; accepted->ar_results.proc = (xdrproc_t) xdr_ypresp_key_val; /* Call the real function. */ nis_next(state, client, client_addr, client_addrlen, &request_xdrs, &reply, &reply_xdrs, reply_buf, &reply_key_val); goto sent_reply; break; case YPPROC_XFR: slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "yp_xfr()\n"); /* Do nothing. The default successful reply is fine. */ break; case YPPROC_CLEAR: slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "yp_clear()\n"); /* Do nothing. The default successful reply is fine. */ break; case YPPROC_ALL: slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "yp_all()\n"); /* Set the result type to a boolean. */ memset(&reply_all, 0, sizeof(reply_all)); accepted->ar_results.where = (caddr_t) &reply_all; accepted->ar_results.proc = (xdrproc_t) &xdr_ypresp_all; /* Call the real function. */ nis_all(state, client, client_addr, client_addrlen, &request_xdrs, &reply, &reply_xdrs, reply_buf, &reply_all); goto sent_reply; break; case YPPROC_MASTER: slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "yp_master()\n"); /* Change reply type to be a resp_master. */ memset(&reply_master, 0, sizeof(reply_master)); accepted->ar_results.where = (caddr_t) &reply_master; accepted->ar_results.proc = (xdrproc_t) xdr_ypresp_master; /* Call the real function. */ nis_master(state, client, client_addr, client_addrlen, &request_xdrs, &reply, &reply_xdrs, reply_buf, &reply_master); goto sent_reply; break; case YPPROC_ORDER: slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "yp_order()\n"); /* Change reply type to be a resp_order. */ memset(&reply_order, 0, sizeof(reply_order)); accepted->ar_results.where = (caddr_t) &reply_order; accepted->ar_results.proc = (xdrproc_t) xdr_ypresp_order; /* Call the real function. */ nis_order(state, client, client_addr, client_addrlen, &request_xdrs, &reply, &reply_xdrs, reply_buf, &reply_order); goto sent_reply; break; case YPPROC_MAPLIST: slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "yp_maplist()\n"); /* Change reply type to be a resp_maplist. */ memset(&reply_maplist, 0, sizeof(reply_maplist)); accepted->ar_results.where = (caddr_t) &reply_maplist; accepted->ar_results.proc = (xdrproc_t) xdr_ypresp_maplist; /* Call the real function. */ nis_maplist(state, client, client_addr, client_addrlen, &request_xdrs, &reply, &reply_xdrs, reply_buf, &reply_maplist); goto sent_reply; break; case YPPROC_NEWXFR: slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, "yp_newxfr()\n"); reply.rm_reply.rp_stat = MSG_DENIED; reply.rm_reply.rp_rjct.rj_stat = RPC_MISMATCH; break; } send_reply: nis_reply(state, client, client_addr, client_addrlen, &reply, &reply_xdrs, reply_buf); sent_reply: xdr_destroy(&reply_xdrs); done: xdr_destroy(&request_xdrs); return; }