13421 apache: o.o.o.rad.ContainerException: system error: error talking to slave
13426 TLS transport auto-generates readable private keys
13429 file browsing API hard codes incorrect attributes
/*
* 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 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#include <sys/wait.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <locale.h>
#include <libscf.h>
#include <errno.h>
#include <string.h>
#include <libxml/parser.h>
#include "rad_object.h"
#include "rad_module.h"
#include "rad_xport.h"
#include "rad_pam.h"
#include "rad_ticket.h"
#include "rad_control.h"
#include "rad_log.h"
#include "rad_smf.h"
#include "rad_util.h"
#include "api_config.h"
#if !defined(TEXT_DOMAIN)
#define TEXT_DOMAIN "SYS_TEST"
#endif
container_t rad_container = CONTAINER_INITIALIZER;
container_t rad_container_unauth = CONTAINER_INITIALIZER;
container_t rad_container_control = CONTAINER_INITIALIZER;
int rad_exit_failure = 1;
int rad_exit_config = 1;
boolean_t rad_isproxy = B_FALSE;
data_t *moduledirs;
const char *
_umem_debug_init()
{
return ("default");
}
/*
* rad(1M) Configuration
* ---------------------
*
* rad(1M) configuration can be obtained from two sources. Firstly, if
* rad is started from SMF and the -s option is specified, it will obtain
* configuration from the corresponding service instance. Secondly,
* command line arguments can be provided to specify a particular
* configuration. If configuration is available from both sources,
* command line configuration is processed before SMF configuration.
*
* There are two things that are configurable in rad(1M).
*
* 1) The set of directories to scan for modules:
* SMF: config/moduledir astring[]
* Command line: '-m <moduledir>' option
*
* 2) The set of endpoints to listen on
* SMF: <pgname>:xport_<xport type> / *
* Command line: '-t <transport>[:opt1[=val1][,opt2[=val2]...]]'
*
* Available transports are 'stdin', 'tcp', 'tls', and 'uds'.
* All transports take a 'proto' option, which defaults to 'rad'.
* 'tcp' and 'tls' require a 'port' option. 'uds' requires a
* 'path' option.
*/
static int
rad_service_wait()
{
int status;
pid_t pid;
int fds[2];
if (pipe(fds) == -1)
rad_log(RL_FATAL, "unable to create pipe: %s", strerror(errno));
if ((pid = fork()) == -1)
rad_log(RL_FATAL, "unable to fork daemon: %s", strerror(errno));
if (pid > 0) {
pid_t wpid;
(void) close(fds[1]);
if (read(fds[0], &status, sizeof (status)) == sizeof (status))
_exit(status);
do {
wpid = waitpid(pid, &status, 0);
} while (wpid != pid && errno == EINTR);
if (WIFEXITED(status))
_exit(WEXITSTATUS(status));
_exit(SMF_EXIT_ERR_FATAL);
}
(void) close(fds[0]);
return (fds[1]);
}
static void
rad_service_done(int fd)
{
int status = SMF_EXIT_OK;
(void) write(fd, &status, sizeof (status));
}
/* -s is for SMF consumption only; not documented */
static const char *usage =
"Usage: rad [ -d ] [ -S fmri ] [ -m moduledir ] [ -t transport ]\n";
int
main(int argc, char **argv)
{
int opt, i;
int nxport = 0, nmoddir = 0;
const char *xports[argc], *moddirs[argc];
boolean_t smf_startup = B_FALSE;
boolean_t smf_config = B_FALSE;
const char *smf_fmri = NULL;
sigset_t hupset;
int svc_fd = -1;
(void) umask(077);
(void) setlocale(LC_ALL, "");
(void) textdomain(TEXT_DOMAIN);
(void) sigemptyset(&hupset);
(void) sigaddset(&hupset, SIGHUP);
(void) sigprocmask(SIG_BLOCK, &hupset, NULL);
(void) sigignore(SIGPIPE);
(void) sigignore(SIGCHLD);
while ((opt = getopt(argc, argv, "dpsS:t:m:")) != EOF) {
switch (opt) {
case 't':
xports[nxport++] = optarg;
break;
case 'm':
moddirs[nmoddir++] = optarg;
break;
case 'p':
rad_isproxy = B_TRUE;
break;
case 's':
smf_startup = B_TRUE;
smf_config = B_TRUE;
rad_exit_failure = SMF_EXIT_ERR_FATAL;
rad_exit_config = SMF_EXIT_ERR_CONFIG;
break;
case 'S':
/* Read config from specified FMRI */
smf_config = B_TRUE;
smf_fmri = optarg;
break;
case 'd':
rad_loglevel = RL_ALL;
break;
default:
(void) fprintf(stderr, usage);
exit(2);
}
}
moduledirs = rad_strarray(moddirs, nmoddir, lt_copy);
if (smf_config) {
data_t *config = rad_smf_read_pg_byname(smf_fmri, "config",
&t__radconfig);
if (config == NULL)
rad_log(RL_CONFIG,
"unable to read configuration from service\n");
data_t *modules = struct_get(config, "moduledir");
data_t *debug = struct_get(config, "debug");
if (debug != NULL && debug->d_data.boolean)
rad_loglevel = RL_ALL;
moduledirs = array_combine(moduledirs, data_ref(modules));
}
/* parent exits, child returns */
if (smf_startup)
svc_fd = rad_service_wait();
xmlInitParser(); /* So libxml consumers are MT safe */
rad_ticket_init();
rad_pam_init();
rad_module_init();
rad_control_init();
if (moduledirs->d_rsize == 0)
rad_log(RL_CONFIG, "No module directories specified.\n");
for (i = 0; i < moduledirs->d_rsize; i++)
rad_module_scan(moduledirs->d_data.array[i]->d_data.string);
for (i = 0; i < nxport; i++)
rad_xport_parse(xports[i]);
if (smf_startup) {
/*
* Only process SMF-configured transports when really
* run as a service.
*/
rad_xport_smf();
rad_service_done(svc_fd);
}
(void) sigprocmask(SIG_UNBLOCK, &hupset, NULL);
for (;;)
pause();
}