--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/rad/mod/xport_tcp/mod_tcp.c Fri May 18 11:08:12 2012 -0400
@@ -0,0 +1,168 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <bsm/adt_event.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <rad/adr_stream.h>
+#include "rad_object.h"
+#include "rad_modapi.h"
+#include "rad_modapi_xport.h"
+#include "rad_connection.h"
+#include "rad_xport.h"
+#include "../rad_listen.h"
+
+#include "api_tcp.h"
+
+static char *pam_service = "rad-tcp";
+
+static void
+tcp_run(void *arg)
+{
+ radmod_connection_t *conn = arg;
+ rad_proto_handle(conn);
+ rad_conn_free(conn);
+}
+
+static rad_moderr_t
+tcp_listen(rad_thread_t *arg)
+{
+ int fd;
+ data_t *d, *data = rad_thread_arg(arg);
+
+ int port = data_to_integer(struct_get(data, "port"));
+ d = struct_get(data, "proto");
+ const char *protostr = d != NULL ? data_to_string(d) : "rad";
+ d = struct_get(data, "localonly");
+ boolean_t local = d != NULL ? data_to_boolean(d) : B_TRUE;
+ d = struct_get(data, "noauth");
+ boolean_t noauth = d != NULL ? data_to_boolean(d) : B_FALSE;
+ d = struct_get(data, "pam_service");
+ if (d != NULL) {
+ pam_service = (char *)data_to_string(d);
+ }
+
+ rad_subject_t *subject = NULL;
+
+ rad_protocol_t *proto = rad_proto_find(protostr);
+ if (proto == NULL) {
+ rad_log(RL_ERROR, "unable to find protocol '%s'", protostr);
+ return (rm_config);
+ }
+
+ if (noauth) {
+ ucred_t *uc = ucred_get(P_MYID);
+ if (uc == NULL ||
+ (subject = rad_subject_create_ucred(uc, B_FALSE,
+ pam_service)) == NULL) {
+ rad_log(RL_ERROR, "failed to allocate subject");
+ return (rm_system);
+ }
+ rad_log(RL_WARN, "AUTHORIZING ANONYMOUS TCP CONNECTIONS");
+ }
+
+ if ((fd = listen_on_port(port, local)) < 0) {
+ rad_log(RL_ERROR, "error starting server on port %d", port);
+ return (rm_system);
+ }
+
+ rad_thread_ack(arg, rm_ok);
+ for (;;) {
+ int afd;
+
+ rad_log(RL_DEBUG, "Waiting for connection");
+ if ((afd = accept(fd, 0, 0)) == -1) {
+ rad_log(RL_ERROR, "error in accept(): %s\n",
+ strerror(errno));
+ continue;
+ }
+ rad_log(RL_DEBUG, "Connection accepted");
+
+ adr_stream_t *stream = adr_stream_create_fd(afd);
+ if (stream == NULL)
+ continue;
+
+ radmod_connection_t *conn = rad_conn_create_fd(afd, B_TRUE);
+ if (conn == NULL) {
+ adr_stream_close(stream);
+ adr_stream_free(stream);
+ rad_log(RL_WARN, "failed to allocate connection");
+ continue;
+ }
+ conn->rm_conn_xport = stream;
+ conn->rm_conn_proto_ops = proto;
+ conn->rm_conn_pam_service = pam_service;
+
+ if (noauth) {
+ assert(subject != NULL);
+ rad_subject_ref(subject);
+ if (!rad_conn_setsubject(conn, subject)) {
+ rad_log(RL_WARN,
+ "failed to set connection subject");
+ rad_conn_close(conn);
+ rad_conn_free(conn);
+ continue;
+ }
+ }
+
+ if (rad_thread_create_async(tcp_run, conn) != rm_ok) {
+ rad_conn_close(conn);
+ rad_conn_free(conn);
+ }
+ }
+}
+
+static rad_moderr_t
+starter(data_t *data)
+{
+ /*
+ * Validate parameters
+ */
+ data_t *port = struct_get(data, "port");
+ if (port == NULL) {
+ rad_log(RL_ERROR, "Port required\n");
+ return (rm_config);
+ }
+
+ return (rad_thread_create(tcp_listen, data));
+}
+
+static rad_modinfo_t modinfo = { "xport_tcp", "TCP transport module" };
+
+int
+_rad_init(void *handle)
+{
+ if (rad_module_register(handle, RAD_MODVERSION, &modinfo) == -1)
+ return (-1);
+
+ rad_xport_register("tcp", &t__tcp, starter);
+ return (0);
+}