00001
#include <signal.h>
00002
00003
#include "wvcrash.h"
00004
#include "wvlog.h"
00005
#include "wvlogrcv.h"
00006
#include "uniconf.h"
00007
#include "uniconfdaemon.h"
00008
#include "uniclientconn.h"
00009
#include "unisecuregen.h"
00010
#include "unipermgen.h"
00011
#include "wvx509.h"
00012
#include "uniconfroot.h"
00013
#include "strutils.h"
00014
00015 #define DEFAULT_CONFIG_FILE "ini:uniconf.ini"
00016
00017 static UniConfDaemon *
globdaemon = NULL;
00018
00019
00020 static void sighandler_die(
int sig)
00021 {
00022
globdaemon->
close();
00023 signal(sig, SIG_DFL);
00024 }
00025
00026
00027 static void usage()
00028 {
00029
wverr->
print(
00030
"uniconfdaemon usage: uniconfdaemon "
00031
"[-mount mountpoint moniker perms] [-p port] [-ssl sslport] [-d level]\n"
00032
" mountpoint - the point to mount the config keys under\n"
00033
" moniker - the moniker, eg. ini:myfile\n"
00034
" perms - moniker to get permissions from (optional)\n"
00035
" level - the debug level\n"
00036
" Critical, Error, Warning, Notice, Info, or Debug[1-5]\n"
00037
" port - the port to listen on for TCP connections (use 0 to disallow)\n"
00038
" sslport - the port to listen on for SSL-encrypted TCP connections (use 0 to disallow)\n");
00039 exit(2);
00040 }
00041
00042
00043 static WvLog::LogLevel
findloglevel(
char *arg)
00044 {
00045
if (!strcasecmp(arg,
"Critical"))
00046
return WvLog::Critical;
00047
else if (!strcasecmp(arg,
"Error"))
00048
return WvLog::Error;
00049
else if (!strcasecmp(arg,
"Warning"))
00050
return WvLog::Warning;
00051
else if (!strcasecmp(arg,
"Notice"))
00052
return WvLog::Notice;
00053
else if (!strcasecmp(arg,
"Info"))
00054
return WvLog::Info;
00055
else if (!strcasecmp(arg,
"Debug1"))
00056
return WvLog::Debug1;
00057
else if (!strcasecmp(arg,
"Debug2"))
00058
return WvLog::Debug2;
00059
else if (!strcasecmp(arg,
"Debug3"))
00060
return WvLog::Debug3;
00061
else if (!strcasecmp(arg,
"Debug4"))
00062
return WvLog::Debug4;
00063
else if (!strcasecmp(arg,
"Debug5"))
00064
return WvLog::Debug5;
00065
else
00066
return WvLog::Info;
00067 }
00068
00069
00070 static void trymount(
const UniConf &cfg,
const UniConfKey &key,
00071
WvStringParm location,
WvStringParm perms = WvString::null)
00072 {
00073
UniConfGen *gen;
00074
WvString errormsg;
00075
if (perms.isnull())
00076 {
00077 errormsg =
WvString(
"Unable to mount \"%s\" at \"%s\"\n",
00078 location, key);
00079 gen = cfg[key].mount(location);
00080 }
00081
else
00082 {
00083 errormsg =
WvString(
"Unable to mount \"%s\" at \"%s\","
00084
"with permissions source \"%s\"\n",
00085 location, key, perms);
00086 gen = cfg[key].mountgen(
new UniSecureGen(location,
00087
new UniPermGen(perms)));
00088 }
00089
00090
if (! gen || ! gen->
isok())
00091 {
00092
wverr->
print(errormsg);
00093 exit(1);
00094 }
00095 }
00096
00097 int main(
int argc,
char **argv)
00098 {
00099 signal(SIGINT,
sighandler_die);
00100 signal(SIGTERM,
sighandler_die);
00101 signal(SIGPIPE, SIG_IGN);
00102
wvcrash_setup(argv[0]);
00103
00104
WvLogConsole logcons(2, WvLog::Info);
00105
00106
UniConfRoot root;
00107 UniConf cfg(root);
00108
00109
bool mountattempt =
false;
00110
bool needauth =
false;
00111
unsigned int port =
DEFAULT_UNICONF_DAEMON_TCP_PORT;
00112
unsigned int sslport =
DEFAULT_UNICONF_DAEMON_SSL_PORT;
00113
00114
for (
int i = 1; i < argc; i++)
00115 {
00116
if (!strcmp(argv[i],
"-mount"))
00117 {
00118
if (argc < i + 3)
usage();
00119
WvString mountpoint = argv[i + 1];
00120
WvString mountloc = argv[i + 2];
00121
WvString perms;
00122
if (argc < i + 4 || argv[i + 3][0] ==
'-')
00123 i += 2;
00124
else
00125 {
00126 perms = argv[i + 3];
00127 i += 3;
00128 needauth =
true;
00129 }
00130
trymount(cfg, mountpoint, mountloc, perms);
00131 mountattempt =
true;
00132 }
00133
else if (!strcmp(argv[i],
"-p"))
00134 {
00135
if (argc < i + 2)
usage();
00136 port =
WvString(argv[i + 1]).num();
00137 i += 1;
00138 }
00139
else if (!strcmp(argv[i],
"-ssl"))
00140 {
00141
if (argc < i + 2)
usage();
00142 sslport =
WvString(argv[i + 1]).num();
00143 i += 1;
00144 }
00145
else if (!strcmp(argv[i],
"-d"))
00146 {
00147
if (argc < i + 2)
usage();
00148 logcons.
level(
findloglevel(argv[i + 1]));
00149 i += 1;
00150 }
00151
else
00152
usage();
00153 }
00154
00155
if (!mountattempt)
00156
trymount(cfg, UniConfKey::EMPTY,
DEFAULT_CONFIG_FILE);
00157
00158
globdaemon =
new UniConfDaemon(cfg, needauth);
00159
00160
00161 system(
"mkdir -p /tmp/uniconf");
00162 system(
"rm -f /tmp/uniconf/uniconfsocket");
00163
if (!
globdaemon->
setupunixsocket(
"/tmp/uniconf/uniconfsocket"))
00164 exit(1);
00165
if (port && !
globdaemon->
setuptcpsocket(
WvIPPortAddr(
"0.0.0.0", port)))
00166 exit(1);
00167
00168
if (sslport)
00169 {
00170
WvString dName =
encode_hostname_as_DN(
fqdomainname());
00171
WvX509Mgr *x509cert =
new WvX509Mgr(dName, 1024);
00172
if (!x509cert->
isok())
00173 {
00174
WvLog log(
"uniconfdaemon", WvLog::Error);
00175
log(
"Couldn't generate X509 certificate: SSL not available\n");
00176 }
00177
else if (sslport && !
globdaemon->
setupsslsocket(
WvIPPortAddr(
"0.0.0.0", sslport), x509cert))
00178 exit(1);
00179 }
00180
00181
00182 pid_t pid = fork();
00183
if (pid <= 0)
00184 {
00185
while (
globdaemon->
isok())
00186 {
00187
if (
globdaemon->
select(5000))
00188
globdaemon->
callback();
00189
else
00190 {
00191
00192 cfg.commit();
00193 cfg.refresh();
00194 }
00195 }
00196
globdaemon->
close();
00197
delete globdaemon;
00198 }
00199
else
00200 {
00201 _exit(0);
00202 }
00203
00204
return 0;
00205 }