summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNalin Dahyabhai <nalin.dahyabhai@pobox.com>2008-06-10 11:47:05 -0400
committerNalin Dahyabhai <nalin.dahyabhai@pobox.com>2008-06-10 11:47:05 -0400
commitbc58ab05ad0f7d9de55d934748fc1fc9cac7fee8 (patch)
tree1b520c12a8e87886d46c03b2fceb2d2170fdc934 /src
parente10684f07d1b1fabf0c29f4db03a5c5e4b269f8d (diff)
downloadslapi-nis-bc58ab05ad0f7d9de55d934748fc1fc9cac7fee8.tar.gz
slapi-nis-bc58ab05ad0f7d9de55d934748fc1fc9cac7fee8.tar.xz
slapi-nis-bc58ab05ad0f7d9de55d934748fc1fc9cac7fee8.zip
- track whether or not the client's request came from a privileged port
- use sockaddr_storage instead of sockaddr for storing client addresses
Diffstat (limited to 'src')
-rw-r--r--src/dispatch.c57
1 files changed, 46 insertions, 11 deletions
diff --git a/src/dispatch.c b/src/dispatch.c
index 907f332..94a488b 100644
--- a/src/dispatch.c
+++ b/src/dispatch.c
@@ -66,8 +66,9 @@ struct request_info;
struct dispatch_client {
/* The client socket and address. */
int client_fd;
- struct sockaddr client_addr;
+ struct sockaddr_storage client_addr;
socklen_t client_addrlen;
+ bool_t client_secure;
/* The client state. */
enum {
client_invalid,
@@ -96,8 +97,9 @@ struct dispatch_client_data {
struct dispatch_client *connected;
struct {
int client_fd;
- struct sockaddr client_addr;
+ struct sockaddr_storage client_addr;
socklen_t client_addrlen;
+ bool_t client_secure;
char *reply_buf;
size_t reply_buf_size;
} dgram;
@@ -229,14 +231,15 @@ dispatch_securenets_add(struct plugin_state *state, const char *value)
free(tmp);
}
static bool_t
-dispatch_access(struct plugin_state *state, struct sockaddr *client_addr)
+dispatch_access(struct plugin_state *state,
+ struct sockaddr_storage *client_addr)
{
struct securenet_info *sn;
struct in_addr addr;
struct in6_addr addr6, mask6, masked6;
int i;
for (sn = state->securenet_info; sn != NULL; sn = sn->sn_next) {
- switch (client_addr->sa_family) {
+ switch (client_addr->ss_family) {
case AF_INET:
if (sn->sn_family != AF_INET) {
continue;
@@ -307,7 +310,7 @@ dispatch_reply_fragment_dgram(struct plugin_state *state,
sendto(cdata->dgram.client_fd,
cdata->dgram.reply_buf, xdr_getpos(reply_xdrs),
0,
- &cdata->dgram.client_addr,
+ (struct sockaddr *) &cdata->dgram.client_addr,
cdata->dgram.client_addrlen);
} else {
slapi_log_error(SLAPI_LOG_PLUGIN,
@@ -324,7 +327,7 @@ dispatch_reply_fragment_dgram(struct plugin_state *state,
sendto(cdata->dgram.client_fd,
cdata->dgram.reply_buf, xdr_getpos(reply_xdrs),
0,
- &cdata->dgram.client_addr,
+ (struct sockaddr *) &cdata->dgram.client_addr,
cdata->dgram.client_addrlen);
}
}
@@ -423,7 +426,7 @@ dispatch_dgram(struct plugin_state *state, int fd)
return;
}
reqsize = recvfrom(cdata.dgram.client_fd, dgram, sizeof(dgram), 0,
- &cdata.dgram.client_addr,
+ (struct sockaddr *) &cdata.dgram.client_addr,
&cdata.dgram.client_addrlen);
slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id,
"datagram request (%d bytes)\n", reqsize);
@@ -448,11 +451,27 @@ dispatch_dgram(struct plugin_state *state, int fd)
"datagram request permitted by securenets\n");
}
+ switch (cdata.dgram.client_addr.ss_family) {
+ struct sockaddr_in *sin;
+ struct sockaddr_in6 *sin6;
+ case AF_INET:
+ sin = (struct sockaddr_in *) &cdata.dgram.client_addr;
+ cdata.dgram.client_secure = sin->sin_port < 1024;
+ break;
+ case AF_INET6:
+ sin6 = (struct sockaddr_in6 *) &cdata.dgram.client_addr;
+ cdata.dgram.client_secure = sin6->sin6_port < 1024;
+ break;
+ default:
+ cdata.dgram.client_secure = FALSE;
+ break;
+ }
+
/* Handle the request. */
nis_process_request(state, dgram, reqsize,
&dispatch_reply_fragment_dgram,
&dispatch_reply_dgram,
- &cdata,
+ &cdata, cdata.dgram.client_secure,
cdata.dgram.reply_buf,
cdata.dgram.reply_buf_size,
NULL);
@@ -511,13 +530,29 @@ dispatch_accept_client(struct plugin_state *state, int fd)
free(client);
return NULL;
}
- fd = accept(fd, &client->client_addr, &client->client_addrlen);
+ fd = accept(fd, (struct sockaddr *)&client->client_addr,
+ &client->client_addrlen);
if (fd == -1) {
free(workbuf);
free(outbuf);
free(client);
return NULL;
}
+ switch (client->client_addr.ss_family) {
+ struct sockaddr_in *sin;
+ struct sockaddr_in6 *sin6;
+ case AF_INET:
+ sin = (struct sockaddr_in *) &client->client_addr;
+ client->client_secure = sin->sin_port < 1024;
+ break;
+ case AF_INET6:
+ sin6 = (struct sockaddr_in6 *) &client->client_addr;
+ client->client_secure = sin6->sin6_port < 1024;
+ break;
+ default:
+ client->client_secure = FALSE;
+ break;
+ }
#ifdef HAVE_TCPD_H
if ((request_set(state->request_info,
RQ_CLIENT_SIN, &client->client_addr,
@@ -676,7 +711,7 @@ client_read(struct plugin_state *state, struct dispatch_client *client)
client->client_query_size,
&dispatch_reply_fragment_connected,
&dispatch_reply_connected,
- &client_data,
+ &client_data, client->client_secure,
client->client_workbuf,
client->client_workbuf_size,
&client->client_query_cookie);
@@ -740,7 +775,7 @@ client_write(struct plugin_state *state, struct dispatch_client *client)
client->client_query_size,
&dispatch_reply_fragment_connected,
&dispatch_reply_connected,
- &client_data,
+ &client_data, client->client_secure,
client->client_workbuf,
client->client_workbuf_size,
&client->client_query_cookie);