summaryrefslogtreecommitdiffstats
path: root/src/nis.c
diff options
context:
space:
mode:
authorNalin Dahyabhai <nalin@localhost.localdomain>2008-04-01 22:22:01 -0400
committerNalin Dahyabhai <nalin@localhost.localdomain>2008-04-01 22:22:01 -0400
commit81b0da5fcc1e086c74076df86a8dbd28cf16a625 (patch)
tree1a6007fc33dd08a1530de6d7dd1180d387731796 /src/nis.c
parent179d675259f4f8a04d19db49831f27099bcabc23 (diff)
downloadslapi-nis-81b0da5fcc1e086c74076df86a8dbd28cf16a625.tar.gz
slapi-nis-81b0da5fcc1e086c74076df86a8dbd28cf16a625.tar.xz
slapi-nis-81b0da5fcc1e086c74076df86a8dbd28cf16a625.zip
- finish getting the basic NIS server going again
Diffstat (limited to 'src/nis.c')
-rw-r--r--src/nis.c247
1 files changed, 189 insertions, 58 deletions
diff --git a/src/nis.c b/src/nis.c
index e487415..0d74f13 100644
--- a/src/nis.c
+++ b/src/nis.c
@@ -19,8 +19,41 @@
#include "nis.h"
#include "plugin.h"
-#define DUMMY_KEY "leeroy"
-#define DUMMY_VAL "jimbo:*K*:1234:5678:Leeroy Jenkins:/home/leeroy:/bin/bash"
+static ssize_t
+nis_write_with_retry(struct plugin_state *state,
+ int fd, const void *buffer, ssize_t length)
+{
+ ssize_t sent, i;
+ sent = 0;
+ while ((sent != -1) && (sent != length)) {
+ i = write(fd, ((unsigned char *)buffer) + sent, length - sent);
+ 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), length, sent,
+ fd);
+ sent = -1;
+ break;
+ }
+ break;
+ default:
+ sent += i;
+ break;
+ }
+ }
+ return sent;
+}
/* Send a reply which _could_ be sent over a datagram. */
static void
@@ -30,8 +63,7 @@ nis_reply_fragment(struct plugin_state *state, int client,
bool_t first_fragment, bool_t last_fragment)
{
uint32_t len;
- struct iovec iov[2];
- ssize_t i;
+ ssize_t i, sent;
if (client_addr != NULL) {
/* It's a datagram socket, so there's nothing to do but send
* the data by itself. */
@@ -49,19 +81,19 @@ nis_reply_fragment(struct plugin_state *state, int client,
/* Calculate the fragment length bytes. */
len = htonl(xdr_getpos(reply_xdrs) |
(last_fragment ? 0x80000000 : 0));
- slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
- "Stream reply (4+%d bytes)\n",
- xdr_getpos(reply_xdrs));
/* Send the data to the client. */
- iov[0].iov_base = &len;
- iov[0].iov_len = 4;
- iov[1].iov_base = reply_buf;
- iov[1].iov_len = xdr_getpos(reply_xdrs);
- i = writev(client, iov, 2);
- if (i != (4 + xdr_getpos(reply_xdrs))) {
+ if ((nis_write_with_retry(state, client, &len, 4) == 4) &&
+ (nis_write_with_retry(state, client, reply_buf,
+ xdr_getpos(reply_xdrs)) ==
+ xdr_getpos(reply_xdrs))) {
slapi_log_error(SLAPI_LOG_PLUGIN,
state->plugin_desc->spd_id,
- "Error sending stream reply!\n");
+ "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");
}
}
}
@@ -102,6 +134,9 @@ nis_domain(struct plugin_state *state,
domain, *reply_bool ? "TRUE" : "FALSE");
}
} else {
+ slapi_log_error(SLAPI_LOG_PLUGIN,
+ state->plugin_desc->spd_id,
+ "argument parsing error\n");
/* XXX */
}
}
@@ -150,6 +185,8 @@ nis_first(struct plugin_state *state,
struct ypresp_key_val *reply_key_val)
{
struct ypreq_nokey req_nokey;
+ bool_t 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)) {
@@ -166,7 +203,11 @@ nis_first(struct plugin_state *state,
req_nokey.map,
reply_key_val->status);
} else {
- reply_key_val->status = YP_NOKEY;
+ 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);
@@ -321,58 +362,100 @@ 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,
- bool_t *reply_more)
+ struct ypresp_all *reply_all)
{
- char domain[YPMAXDOMAIN + 1], *p;
- int i;
- keydat_t keydat;
- bool_t more;
struct ypreq_nokey req_nokey;
- struct ypresp_key_val reply_key_val;
+ keydat_t *reply_key;
+ valdat_t *reply_val;
+ bool_t supported;
- memset(&reply_key_val, 0, sizeof(reply_key_val));
- *reply_more = FALSE;
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_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_more = TRUE;
+ 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);
- slapi_log_error(SLAPI_LOG_PLUGIN,
- state->plugin_desc->spd_id,
- "all(%s/%s) -> %d\n",
- req_nokey.domain,
- req_nokey.map,
- *reply_more);
+ /* 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 {
- xdr_setpos(reply_xdrs, 0);
- xdr_ypresp_key_val(reply_xdrs, &reply_key_val);
- keydat = reply_key_val.keydat;
- more = map_next(state,
- req_nokey.domain, req_nokey.map,
- keydat.keydat_len,
- 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);
- xdr_bool(reply_xdrs, &more);
+ /* 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,
- FALSE, !more);
- } while(more);
- } else {
- *reply_more = FALSE;
- nis_reply(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 */
@@ -394,6 +477,7 @@ nis_process_request(struct plugin_state *state, int client,
int superuser, send_reply, 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;
@@ -448,6 +532,12 @@ nis_process_request(struct plugin_state *state, int client,
"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,
@@ -478,6 +568,8 @@ nis_process_request(struct plugin_state *state, int client,
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;
@@ -491,6 +583,8 @@ nis_process_request(struct plugin_state *state, int client,
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;
}
@@ -510,10 +604,17 @@ nis_process_request(struct plugin_state *state, int client,
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;
@@ -526,6 +627,9 @@ nis_process_request(struct plugin_state *state, int client,
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;
@@ -537,6 +641,9 @@ nis_process_request(struct plugin_state *state, int client,
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;
@@ -548,6 +655,9 @@ nis_process_request(struct plugin_state *state, int client,
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;
@@ -559,23 +669,35 @@ nis_process_request(struct plugin_state *state, int client,
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_bool, 0, sizeof(reply_bool));
- accepted->ar_results.where = (caddr_t) &reply_bool;
- accepted->ar_results.proc = (xdrproc_t) &xdr_bool;
+ 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_bool);
+ &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;
@@ -587,6 +709,9 @@ nis_process_request(struct plugin_state *state, int client,
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;
@@ -598,6 +723,9 @@ nis_process_request(struct plugin_state *state, int client,
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;
@@ -609,6 +737,9 @@ nis_process_request(struct plugin_state *state, int client,
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;