uniconfd.cc

00001 #include "wvautoconf.h"
00002 #ifdef HAVE_UNISTD_H
00003 # include <unistd.h>
00004 #endif
00005 #ifdef HAVE_GETOPT_H
00006 # include <getopt.h>
00007 #endif
00008 
00009 #ifndef _WIN32
00010 #include <signal.h>
00011 #include <sys/types.h>
00012 #include <sys/stat.h>
00013 #endif
00014 
00015 #ifdef WITH_SLP
00016 #include "wvslp.h"
00017 #endif
00018 
00019 #include "wvlogrcv.h"
00020 #include "uniconfdaemon.h"
00021 #include "uniclientconn.h"
00022 #include "unisecuregen.h"
00023 #include "unipermgen.h"
00024 #include "wvx509.h"
00025 #include "uniconfroot.h"
00026 #include "wvstrutils.h"
00027 #include "wvfileutils.h"
00028 #include "wvstreamsdaemon.h"
00029 
00030 #ifdef WITH_SLP
00031 #include "slp.h"
00032 #endif
00033 
00034 #ifdef _WIN32
00035 #pragma comment(linker, "/include:?UniRegistryGenMoniker@@3V?$WvMoniker@VIUniConfGen@@@@A")
00036 #pragma comment(linker, "/include:?UniPStoreGenMoniker@@3V?$WvMoniker@VIUniConfGen@@@@A")
00037 #pragma comment(linker, "/include:?UniIniGenMoniker@@3V?$WvMoniker@VIUniConfGen@@@@A")
00038 #endif
00039 
00040 #define DEFAULT_CONFIG_FILE "ini:uniconf.ini"
00041 
00042 
00043 static WvMap<WvString, IUniConfGen*> namedgens(42);
00044 
00045 
00046 static IUniConfGen *creator(WvStringParm s)
00047 {
00048     IUniConfGen* gen = namedgens[s];
00049 
00050     if (gen)
00051         gen->addRef();
00052 
00053     return gen;
00054 }
00055 
00056 WvMoniker<IUniConfGen> UniNamedMoniker("named", creator);
00057 
00058 
00059 class UniConfd : public WvStreamsDaemon
00060 {
00061     bool needauth;
00062     int port;
00063     int sslport;
00064     WvString unixport, permmon, unix_mode;
00065     time_t commit_interval;
00066 
00067     UniConfRoot cfg;
00068     bool first_time;
00069     IUniConfGen *permgen;
00070     
00071     bool namedgen_cb(WvStringParm option, void *)
00072     {
00073         WvString name(option);
00074         WvString moniker;
00075         char* ptr;
00076 
00077         ptr = strchr(name.edit(), '=');
00078 
00079         if (!ptr)
00080             return false;
00081 
00082         *ptr = 0;
00083         moniker = ptr + 1;
00084 
00085         namedgens.add(name, wvcreate<IUniConfGen>("temp:"), true);
00086         return true;
00087     }
00088 
00089     void commit_stream_cb(WvStream &s, void *)
00090     {
00091         cfg.commit();
00092         cfg.refresh();
00093         if (permgen)
00094             permgen->refresh();
00095             
00096         s.alarm(commit_interval * 1000);
00097     }
00098     
00099     void startup(WvStreamsDaemon &, void *)
00100     {
00101         if (first_time)
00102         {
00103             WvStringList::Iter i(_extra_args);
00104             for (i.rewind(); i.next(); )
00105             {
00106                 WvString path = *i, moniker;
00107                 char *cptr = strchr(path.edit(), '=');
00108                 if (!cptr)
00109                 {
00110                     moniker = path;
00111                     path = "/";
00112                 }
00113                 else
00114                 {
00115                     *cptr = 0;
00116                     moniker = cptr+1;
00117                 }
00118                 
00119                 log("Mounting '%s' on '%s': ", moniker, path);
00120                 IUniConfGen *gen = cfg[path].mount(moniker, false);
00121                 if (gen && gen->isok())
00122                     log("ok.\n");
00123                 else
00124                     log("FAILED!\n");
00125             }
00126             
00127             cfg.refresh();
00128         }
00129 
00130         permgen = !!permmon ? wvcreate<IUniConfGen>(permmon) : NULL;
00131         
00132         UniConfDaemon *daemon = new UniConfDaemon(cfg, needauth, permgen);
00133         add_die_stream(daemon, true, "uniconfd");
00134 
00135 #ifndef _WIN32
00136         if (!!unixport)
00137         {
00138             // FIXME: THIS IS NOT SAFE!
00139             mkdirp(getdirname(unixport));
00140             ::unlink(unixport);
00141             if (!daemon->setupunixsocket(unixport))
00142                 exit(3);
00143             if (!!unix_mode && unix_mode.num())
00144             {
00145                 log("Setting mode on %s to: %s\n", unixport, unix_mode);
00146                 mode_t mode;
00147                 sscanf(unix_mode.edit(), "%o", &mode);
00148                 chmod(unixport, mode);
00149             }
00150         }
00151 #endif
00152 
00153         if (port && !daemon->setuptcpsocket(WvIPPortAddr("0.0.0.0", port)))
00154         {
00155             die();
00156             return;
00157         }
00158 
00159         if (sslport)
00160         {
00161             WvString dName = encode_hostname_as_DN(fqdomainname());
00162             WvX509Mgr *x509cert = new WvX509Mgr(dName, 1024);
00163             if (!x509cert->isok())
00164             {
00165                 log(WvLog::Critical,
00166                     "Couldn't generate X509 certificate: SSL not available.\n");
00167                 die();
00168                 return;
00169             }
00170             else if (!daemon->setupsslsocket(
00171                         WvIPPortAddr("0.0.0.0", sslport), x509cert))
00172             {
00173                 die();
00174                 return;
00175             }
00176         }
00177     
00178 #ifdef WITH_SLP
00179         WvSlp slp;
00180 
00181         if (first_time)
00182         {
00183             // Now that we're this far...
00184             
00185             // Register UniConf service with SLP 
00186             if (port)
00187                 slp.add_service("uniconf.niti", fqdomainname(), port);
00188         
00189             // Register UniConf SSL service with SLP 
00190             if (sslport)
00191                 slp.add_service("uniconfs.niti", fqdomainname(), sslport);
00192         }
00193 #endif
00194     
00195         WvStream *commit_stream = new WvStream;
00196         commit_stream->setcallback(WvStreamCallback(this,
00197                 &UniConfd::commit_stream_cb), NULL);
00198         commit_stream->alarm(commit_interval * 1000);
00199         add_die_stream(commit_stream, true, "commit");
00200         
00201         if (first_time)
00202             first_time = false;
00203     }
00204     
00205 public:
00206 
00207     UniConfd() :
00208             WvStreamsDaemon("uniconfd", WVSTREAMS_RELEASE,
00209                 WvStreamsDaemonCallback(this, &UniConfd::startup)),
00210             needauth(false),
00211             port(DEFAULT_UNICONF_DAEMON_TCP_PORT),
00212             sslport(DEFAULT_UNICONF_DAEMON_SSL_PORT),
00213             commit_interval(5*60),
00214             first_time(true),
00215             permgen(NULL)
00216     {
00217         args.zap();
00218         
00219         daemonize = true;
00220 
00221         args.add_reset_bool_option('f', "foreground",
00222                 "Run in foreground (non-forking)", daemonize);
00223         args.add_option('d', "debug",
00224                 "Print debug messages (can be used multiple times)",
00225                 WvArgs::NoArgCallback(this, &UniConfd::inc_log_level));
00226 
00227         args.add_option(0, "pid-file",
00228                 "Specify the .pid file to use", "filename",
00229                 pid_file);
00230         args.add_set_bool_option('a', "need-auth",
00231                 "Require authentication on incoming connections", needauth);
00232         args.add_option('A', "check-access",
00233                 "Check all accesses against perms moniker", "moniker",
00234                 permmon);
00235         args.add_option('p', "tcp",
00236                 "Listen on given TCP port (default=4111; 0 to disable)", "port",
00237                 port);
00238         args.add_option('s', "ssl",
00239                 "Listen on given TCP/SSL port (default=4112; 0 to disable)", "port",
00240                 sslport);
00241 #ifndef _WIN32
00242         args.add_option('u', "unix",
00243                 "Listen on given Unix socket filename (default=disabled)", "filename",
00244                 unixport);
00245         args.add_option('m', "unix-mode",
00246                 "Set the Unix socket to 'mode' (default to uniconfd users umask)", "mode",
00247                 unix_mode);
00248         args.add_option('n', "named-gen",
00249                 "creates a \"named\" moniker 'name' from 'moniker'",
00250                 "name=moniker",
00251                 WvArgs::ArgCallback(this, &UniConfd::namedgen_cb), NULL);
00252 #endif
00253         args.add_optional_arg("MONIKERS", true);
00254         args.set_email("<" PACKAGE_BUGREPORT ">");
00255     }
00256     
00257     
00258 };
00259 
00260 int main(int argc, char **argv)
00261 {
00262     UniConfd uniconfd;
00263    
00264     return uniconfd.run(argc, argv);
00265 }

Generated on Sun Sep 24 20:10:48 2006 for WvStreams by  doxygen 1.4.7