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 }