summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNalin Dahyabhai <nalin.dahyabhai@pobox.com>2009-02-11 21:29:55 -0500
committerNalin Dahyabhai <nalin.dahyabhai@pobox.com>2009-02-11 21:29:55 -0500
commit689aeb76c0cf1a704499a790e8e9439b0395cb2d (patch)
tree7d847e2824ef58cbc8820a564fac0af0a1bdb5ea /src
parent13e818b9df6c15076ba9f6d23adaf480c98a6d93 (diff)
downloadslapi-nis-689aeb76c0cf1a704499a790e8e9439b0395cb2d.tar.gz
slapi-nis-689aeb76c0cf1a704499a790e8e9439b0395cb2d.tar.xz
slapi-nis-689aeb76c0cf1a704499a790e8e9439b0395cb2d.zip
- first (non-working) pass at registering with rpcbind
Diffstat (limited to 'src')
-rw-r--r--src/plug-nis.c35
-rw-r--r--src/portmap.c155
-rw-r--r--src/portmap.h3
3 files changed, 173 insertions, 20 deletions
diff --git a/src/plug-nis.c b/src/plug-nis.c
index 19ff1dc..8e0b203 100644
--- a/src/plug-nis.c
+++ b/src/plug-nis.c
@@ -97,7 +97,10 @@ plugin_startup(Slapi_PBlock *pb)
/* Kick off any other NIS servers on the local box. */
portmap_unregister(plugin_description.spd_id,
state->pmap_client_socket,
- YPPROG, YPVERS, AF_INET);
+ YPPROG, YPVERS, AF_INET, IPPROTO_TCP);
+ portmap_unregister(plugin_description.spd_id,
+ state->pmap_client_socket,
+ YPPROG, YPVERS, AF_INET, IPPROTO_UDP);
/* Register our listening ports. */
for (i = 0; i < state->n_listeners; i++) {
if (state->listener[i].pf != PF_INET) {
@@ -158,7 +161,10 @@ plugin_shutdown(Slapi_PBlock *pb)
/* Clear our registration with the portmapper. */
portmap_unregister(plugin_description.spd_id,
state->pmap_client_socket,
- YPPROG, YPVERS, AF_INET);
+ YPPROG, YPVERS, AF_INET, IPPROTO_TCP);
+ portmap_unregister(plugin_description.spd_id,
+ state->pmap_client_socket,
+ YPPROG, YPVERS, AF_INET, IPPROTO_UDP);
}
wrap_stop_thread(state->tid);
map_done(state);
@@ -252,6 +258,7 @@ plugin_state_init(Slapi_PBlock *pb, struct plugin_state **lstate)
struct plugin_state *state = NULL;
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
+ struct sockaddr_un sockun;
state = malloc(sizeof(*state));
if (state == NULL) {
@@ -289,6 +296,29 @@ plugin_state_init(Slapi_PBlock *pb, struct plugin_state **lstate)
#endif
/* Create a socket for use in communicating with the portmapper. */
+#ifdef HAVE_LIBTIRPC
+ sockfd = socket(PF_LOCAL, SOCK_STREAM, 0);
+ if (sockfd == -1) {
+ slapi_log_error(SLAPI_LOG_FATAL, state->plugin_desc->spd_id,
+ "error allocating portmap client socket\n");
+ goto failed;
+ }
+ memset(&sockun, 0, sizeof(sockun));
+ sockun.sun_family = AF_LOCAL;
+ strcpy(sockun.sun_path, _PATH_RPCBINDSOCK);
+ if (connect(sockfd, (struct sockaddr *) &sockun, sizeof(sockun)) != 0) {
+ if ((getenv(NIS_PLUGIN_CONTINUE_WITHOUT_PORTMAP_ENV) == NULL) ||
+ !atol(getenv(NIS_PLUGIN_CONTINUE_WITHOUT_PORTMAP_ENV))) {
+ slapi_log_error(SLAPI_LOG_FATAL,
+ state->plugin_desc->spd_id,
+ "error connecting rpcbind client "
+ "socket to the service\n");
+ close(sockfd);
+ sockfd = -1;
+ goto failed;
+ }
+ }
+#else
sockfd = socket(PF_INET, SOCK_DGRAM, 0);
if (sockfd == -1) {
slapi_log_error(SLAPI_LOG_FATAL, state->plugin_desc->spd_id,
@@ -314,6 +344,7 @@ plugin_state_init(Slapi_PBlock *pb, struct plugin_state **lstate)
close(sockfd);
sockfd = -1;
}
+#endif
state->pmap_client_socket = sockfd;
/* We need to bind on privileged ports for both datagram and connected
diff --git a/src/portmap.c b/src/portmap.c
index bb5051f..3d56971 100644
--- a/src/portmap.c
+++ b/src/portmap.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Red Hat, Inc.
+ * Copyright 2008,2009 Red Hat, Inc.
*
* This Program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -49,6 +49,7 @@
#ifdef PORTMAP_MAIN
#include <stdarg.h>
+#include <stdlib.h>
#include <unistd.h>
int
slapi_log_error(int i, char *f, char *fmt, ...)
@@ -62,18 +63,39 @@ slapi_log_error(int i, char *f, char *fmt, ...)
int
main(int argc, char **argv)
{
- int s;
+ int s, ret;
struct sockaddr_in sin;
+ struct sockaddr_un sunaddr;
s = socket(PF_INET, SOCK_DGRAM, 0);
memset(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
if (bindresvport(s, &sin) != 0) {
printf("error binding to reserved port\n");
+ } else {
+ printf("bound to reserved port %d\n", ntohs(sin.sin_port));
}
+#ifdef HAVE_LIBTIRPC
+ s = socket(AF_LOCAL, SOCK_STREAM, 0);
+ memset(&sunaddr, 0, sizeof(sunaddr));
+ sunaddr.sun_family = AF_LOCAL;
+ strcpy(sunaddr.sun_path, _PATH_RPCBINDSOCK);
+ connect(s, (struct sockaddr *) &sunaddr, sizeof(sunaddr));
+#endif
setreuid(2510, 2510);
- portmap_unregister("portmap", s, YPPROG, YPVERS, AF_INET);
+ portmap_register("portmap", s, YPPROG, YPVERS, AF_INET, IPPROTO_TCP,
+ ntohs(sin.sin_port));
portmap_register("portmap", s, YPPROG, YPVERS, AF_INET, IPPROTO_UDP,
ntohs(sin.sin_port));
+ portmap_register("portmap", s, YPPROG, YPVERS, AF_INET6, IPPROTO_TCP,
+ ntohs(sin.sin_port));
+ portmap_register("portmap", s, YPPROG, YPVERS, AF_INET6, IPPROTO_UDP,
+ ntohs(sin.sin_port));
+ ret = system("rpcinfo | grep ypserv");
+ ret = system("rpcinfo -p | grep ypserv");
+ portmap_unregister("portmap", s, YPPROG, YPVERS, AF_INET, IPPROTO_TCP);
+ portmap_unregister("portmap", s, YPPROG, YPVERS, AF_INET, IPPROTO_UDP);
+ portmap_unregister("portmap", s, YPPROG, YPVERS, AF_INET6, IPPROTO_TCP);
+ portmap_unregister("portmap", s, YPPROG, YPVERS, AF_INET6, IPPROTO_UDP);
return 0;
}
#endif
@@ -82,17 +104,26 @@ static bool_t
portmap_register_work(const char *module, int resv_sock,
int program, int version,
int family, int protocol, int port,
- int proc)
+ bool_t create)
{
char portmap_buf[4000], auth_buf[4000], reply_buf[8000], *log_id;
int portmap_length, reply_length;
AUTH *auth;
XDR portmap_xdrs, auth_xdrs;
struct rpc_msg msg;
+#ifdef HAVE_LIBTIRPC
+ char address_buf[32];
+ struct rpcb rpcb;
+ int fragment_length;
+#else
struct pmap map;
+#endif
+ int prog, vers, proc;
bool_t ret = FALSE;
struct sockaddr addr;
struct sockaddr_in addr4;
+ struct sockaddr_in6 addr6;
+ struct sockaddr_un addrun;
union {
struct sockaddr_in addr4;
} client_addr;
@@ -105,13 +136,73 @@ portmap_register_work(const char *module, int resv_sock,
memset(&addr, 0, sizeof(addr));
addr.sa_family = AF_UNSPEC;
+ /* Populate the arguments for this request. */
+#ifdef HAVE_LIBTIRPC
+ rpcb.r_prog = program;
+ rpcb.r_vers = version;
+ rpcb.r_owner = module;
+ switch (family) {
+ case AF_INET:
+ snprintf(address_buf, sizeof(address_buf), "0.0.0.0.%d.%d",
+ (port >> 8) & 0xff, port & 0xff);
+ switch (protocol) {
+ case IPPROTO_TCP:
+ rpcb.r_netid = "tcp";
+ rpcb.r_addr = address_buf;
+ break;
+ case IPPROTO_UDP:
+ rpcb.r_netid = "udp";
+ rpcb.r_addr = address_buf;
+ break;
+ default:
+ rpcb.r_netid = NULL;
+ rpcb.r_addr = NULL;
+ break;
+ }
+ break;
+ case AF_INET6:
+ snprintf(address_buf, sizeof(address_buf), "::.%d.%d",
+ (port >> 8) & 0xff, port & 0xff);
+ switch (protocol) {
+ case IPPROTO_TCP:
+ rpcb.r_netid = "tcp6";
+ rpcb.r_addr = address_buf;
+ break;
+ case IPPROTO_UDP:
+ rpcb.r_netid = "udp6";
+ rpcb.r_addr = address_buf;
+ break;
+ default:
+ rpcb.r_netid = NULL;
+ rpcb.r_addr = NULL;
+ break;
+ }
+ break;
+ default:
+ rpcb.r_netid = NULL;
+ rpcb.r_addr = NULL;
+ break;
+ }
+ prog = RPCBPROG;
+ vers = RPCBVERS;
+ proc = create ? RPCBPROC_SET : RPCBPROC_UNSET;
+#else
+ map.pm_prog = program;
+ map.pm_vers = version;
+ map.pm_prot = protocol;
+ map.pm_port = port;
+ prog = PMAPPROG;
+ vers = PMAPVERS;
+ proc = create ? PMAPPROC_SET : PMAPPROC_UNSET;
+#endif
+
/* Build the RPC header. */
memset(&msg, 0, sizeof(msg));
msg.rm_xid = xid = (time(NULL) ^ port ^ protocol ^ proc);
msg.rm_direction = CALL;
msg.rm_call.cb_rpcvers = 2;
- msg.rm_call.cb_prog = PMAPPROG;
- msg.rm_call.cb_vers = PMAPVERS;
+ msg.rm_call.cb_prog = prog;
+ msg.rm_call.cb_vers = vers;
msg.rm_call.cb_proc = proc;
/* Build an authenticator. */
@@ -121,24 +212,37 @@ portmap_register_work(const char *module, int resv_sock,
msg.rm_call.cb_cred = auth->ah_cred;
msg.rm_call.cb_verf = auth->ah_verf;
- /* Populate the arguments for this request. */
- map.pm_prog = program;
- map.pm_vers = version;
- map.pm_prot = protocol;
- map.pm_port = port;
-
/* Encode the header and the arguments, then clean up temporaries. */
+#ifdef HAVE_LIBTIRPC
+ xdrmem_create(&portmap_xdrs, portmap_buf + 4, sizeof(portmap_buf) - 4,
+ XDR_ENCODE);
+#else
xdrmem_create(&portmap_xdrs, portmap_buf, sizeof(portmap_buf),
XDR_ENCODE);
+#endif
xdr_callmsg(&portmap_xdrs, &msg);
+#ifdef HAVE_LIBTIRPC
+ xdr_rpcb(&portmap_xdrs, &rpcb);
+#else
xdr_pmap(&portmap_xdrs, &map);
+#endif
portmap_length = xdr_getpos(&portmap_xdrs);
auth_destroy(auth);
xdr_destroy(&auth_xdrs);
xdr_destroy(&portmap_xdrs);
memset(&portmap_xdrs, 0, sizeof(portmap_xdrs));
- /* Connect to the local portmapper. */
+#ifdef HAVE_LIBTIRPC
+ /* Compute the message length and prepend it. */
+ fragment_length = portmap_length;
+ fragment_length |= 0x80000000;
+ portmap_buf[0] = (fragment_length >> 24) & 0xff;
+ portmap_buf[1] = (fragment_length >> 16) & 0xff;
+ portmap_buf[2] = (fragment_length >> 8) & 0xff;
+ portmap_buf[3] = (fragment_length >> 0) & 0xff;
+ portmap_length += 4;
+#else
+ /* "Connect" to the local portmapper. */
memset(&addr4, 0, sizeof(addr4));
addr4.sin_family = AF_INET;
addr4.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
@@ -150,6 +254,7 @@ portmap_register_work(const char *module, int resv_sock,
resv_sock, strerror(errno));
return FALSE;
}
+#endif
/* Transmit our request. Retry a few times if it doesn't go through. */
for (i = 1; i < 32; i *= 2) {
@@ -178,9 +283,23 @@ portmap_register_work(const char *module, int resv_sock,
/* Decode an RPC header and the returned
* boolean from the buffer. */
memset(&msg, 0, sizeof(msg));
+#ifdef HAVE_LIBTIRPC
+ fragment_length = ((reply_buf[0] << 24) |
+ (reply_buf[1] << 16) |
+ (reply_buf[2] << 8) |
+ (reply_buf[3] << 0)) &
+ 0x7fffffff;
+ if (fragment_length != reply_length - 4) {
+ fprintf(stderr, "Bad reply length!\n");
+ }
+ xdrmem_create(&portmap_xdrs,
+ reply_buf + 4, reply_length - 4,
+ XDR_DECODE);
+#else
xdrmem_create(&portmap_xdrs,
reply_buf, reply_length,
XDR_DECODE);
+#endif
msg.rm_reply.rp_acpt.ar_results.where =
(caddr_t) &ret;
msg.rm_reply.rp_acpt.ar_results.proc =
@@ -198,6 +317,7 @@ portmap_register_work(const char *module, int resv_sock,
}
}
+#ifndef HAVE_LIBTIRPC
/* Disconnect from the portmapper, but keep our socket around. */
connect(resv_sock, &addr, sizeof(addr));
if (i == 32) {
@@ -205,6 +325,7 @@ portmap_register_work(const char *module, int resv_sock,
"timeout registering with portmap service\n");
return FALSE;
}
+#endif
/* Check that the portmapper didn't just reject the request out of
* hand. */
@@ -281,7 +402,7 @@ portmap_register_work(const char *module, int resv_sock,
"portmap request succeeded\n");
} else {
slapi_log_error(SLAPI_LOG_PLUGIN, log_id,
- "portmap response did not include a reply\n");
+ "portmap request failed\n");
}
xdr_destroy(&portmap_xdrs);
@@ -294,13 +415,13 @@ portmap_register(const char *log_id, int resv_sock,
int program, int version, int family, int protocol, int port)
{
return portmap_register_work(log_id, resv_sock, program, version,
- family, protocol, port, PMAPPROC_SET);
+ family, protocol, port, TRUE);
}
bool_t
portmap_unregister(const char *log_id, int resv_sock,
- int program, int version, int family)
+ int program, int version, int family, int protocol)
{
return portmap_register_work(log_id, resv_sock, program, version,
- family, 0, 0, PMAPPROC_UNSET);
+ family, protocol, 0, FALSE);
}
diff --git a/src/portmap.h b/src/portmap.h
index ed59b67..62c687c 100644
--- a/src/portmap.h
+++ b/src/portmap.h
@@ -26,6 +26,7 @@ bool_t portmap_register(const char *log_id, int resv_sock,
int program, int version,
int family, int protocol, int port);
bool_t portmap_unregister(const char *log_id, int resv_sock,
- int program, int version, int family);
+ int program, int version,
+ int family, int protocol);
#endif