00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include "config.h"
00041
00042 #ifndef _GNU_SOURCE
00043 #define _GNU_SOURCE
00044 #endif
00045 #include <stdlib.h>
00046 #include <stdio.h>
00047 #include <unistd.h>
00048 #include <string.h>
00049 #include <syslog.h>
00050 #include <stdarg.h>
00051 #include <errno.h>
00052 #include <pwd.h>
00053 #include <grp.h>
00054 #include <ctype.h>
00055 #include <signal.h>
00056 #include <fcntl.h>
00057 #include <syslog.h>
00058
00059 #include <sys/select.h>
00060 #include <sys/types.h>
00061 #include <sys/stat.h>
00062
00063 #include <libxml/tree.h>
00064 #include <libxml/parser.h>
00065 #include <libxml/xpath.h>
00066 #include <libxml/xpathInternals.h>
00067 #include <libxml/relaxng.h>
00068
00069 #include "daemon.h"
00070 #include "daemon_util.h"
00071
00072 #include "ksm/database.h"
00073 #include "ksm/datetime.h"
00074 #include "ksm/string_util.h"
00075 #include "ksm/string_util2.h"
00076
00077 int
00078 getPermsForDrop(DAEMONCONFIG* config)
00079 {
00080 int status = 0;
00081
00082 xmlDocPtr doc = NULL;
00083 xmlDocPtr rngdoc = NULL;
00084 xmlXPathContextPtr xpathCtx = NULL;
00085 xmlXPathObjectPtr xpathObj = NULL;
00086 xmlRelaxNGParserCtxtPtr rngpctx = NULL;
00087 xmlRelaxNGValidCtxtPtr rngctx = NULL;
00088 xmlRelaxNGPtr schema = NULL;
00089 xmlChar *user_expr = (unsigned char*) "//Configuration/Enforcer/Privileges/User";
00090 xmlChar *group_expr = (unsigned char*) "//Configuration/Enforcer/Privileges/Group";
00091
00092 char* filename = NULL;
00093 char* rngfilename = OPENDNSSEC_SCHEMA_DIR "/conf.rng";
00094 char* temp_char = NULL;
00095
00096 struct passwd *pwd;
00097 struct group *grp;
00098
00099 FILE *file;
00100
00101 if (config->configfile != NULL) {
00102 filename = StrStrdup(config->configfile);
00103 } else {
00104 filename = StrStrdup(OPENDNSSEC_CONFIG_FILE);
00105 }
00106
00107
00108 doc = xmlParseFile(filename);
00109 if (doc == NULL) {
00110
00111 file = fopen(filename, "r");
00112 if (file == NULL) {
00113 log_msg(config, LOG_ERR, "Error: unable to open file \"%s\"", filename);
00114 } else {
00115 log_msg(config, LOG_ERR, "Error: unable to parse file \"%s\"", filename);
00116 fclose(file);
00117 }
00118 return(-1);
00119 }
00120
00121
00122 rngdoc = xmlParseFile(rngfilename);
00123 if (rngdoc == NULL) {
00124
00125 file = fopen(rngfilename, "r");
00126 if (file == NULL) {
00127 log_msg(config, LOG_ERR, "Error: unable to open file \"%s\"", rngfilename);
00128 } else {
00129 log_msg(config, LOG_ERR, "Error: unable to parse file \"%s\"", rngfilename);
00130 fclose(file);
00131 }
00132 return(-1);
00133 }
00134
00135
00136 rngpctx = xmlRelaxNGNewDocParserCtxt(rngdoc);
00137 if (rngpctx == NULL) {
00138 log_msg(config, LOG_ERR, "Error: unable to create XML RelaxNGs parser context");
00139 return(-1);
00140 }
00141
00142
00143 schema = xmlRelaxNGParse(rngpctx);
00144 if (schema == NULL) {
00145 log_msg(config, LOG_ERR, "Error: unable to parse a schema definition resource");
00146 return(-1);
00147 }
00148
00149
00150 rngctx = xmlRelaxNGNewValidCtxt(schema);
00151 if (rngctx == NULL) {
00152 log_msg(config, LOG_ERR, "Error: unable to create RelaxNGs validation context based on the schema");
00153 return(-1);
00154 }
00155
00156 xmlRelaxNGSetValidErrors(rngctx,
00157 (xmlRelaxNGValidityErrorFunc) log_xml_error,
00158 (xmlRelaxNGValidityWarningFunc) log_xml_warn,
00159 NULL);
00160
00161
00162 status = xmlRelaxNGValidateDoc(rngctx,doc);
00163 if (status != 0) {
00164 log_msg(config, LOG_ERR, "Error validating file \"%s\"", filename);
00165 return(-1);
00166 }
00167
00168
00169
00170 xpathCtx = xmlXPathNewContext(doc);
00171 if(xpathCtx == NULL) {
00172 log_msg(config, LOG_ERR,"Error: unable to create new XPath context");
00173 xmlFreeDoc(doc);
00174 return(-1);
00175 }
00176
00177
00178 xpathObj = xmlXPathEvalExpression(group_expr, xpathCtx);
00179 if(xpathObj == NULL) {
00180 log_msg(config, LOG_ERR, "Error: unable to evaluate xpath expression: %s", group_expr);
00181 xmlXPathFreeContext(xpathCtx);
00182 xmlFreeDoc(doc);
00183 return(-1);
00184 }
00185 if (xpathObj->nodesetval != NULL && xpathObj->nodesetval->nodeNr > 0) {
00186 temp_char = (char*) xmlXPathCastToString(xpathObj);
00187 StrAppend(&config->groupname, temp_char);
00188 StrFree(temp_char);
00189 xmlXPathFreeObject(xpathObj);
00190 } else {
00191 config->groupname = NULL;
00192 }
00193
00194
00195 xpathObj = xmlXPathEvalExpression(user_expr, xpathCtx);
00196 if(xpathObj == NULL) {
00197 log_msg(config, LOG_ERR, "Error: unable to evaluate xpath expression: %s", user_expr);
00198 xmlXPathFreeContext(xpathCtx);
00199 xmlFreeDoc(doc);
00200 return(-1);
00201 }
00202 if (xpathObj->nodesetval != NULL && xpathObj->nodesetval->nodeNr > 0) {
00203 temp_char = (char*) xmlXPathCastToString(xpathObj);
00204 StrAppend(&config->username, temp_char);
00205 StrFree(temp_char);
00206 xmlXPathFreeObject(xpathObj);
00207 } else {
00208 config->username = NULL;
00209 }
00210
00211
00212 if (config->username != NULL) {
00213
00214 if ((pwd = getpwnam(config->username)) == NULL) {
00215 syslog(LOG_ERR, "user '%s' does not exist. exiting...\n", config->username);
00216 exit(1);
00217 } else {
00218 config->uid = pwd->pw_uid;
00219 }
00220 endpwent();
00221 }
00222 if (config->groupname) {
00223
00224 if ((grp = getgrnam(config->groupname)) == NULL) {
00225 syslog(LOG_ERR, "group '%s' does not exist. exiting...\n", config->groupname);
00226 exit(1);
00227 } else {
00228 config->gid = grp->gr_gid;
00229 }
00230 endgrent();
00231 }
00232
00233 xmlXPathFreeContext(xpathCtx);
00234 xmlRelaxNGFree(schema);
00235 xmlRelaxNGFreeValidCtxt(rngctx);
00236 xmlRelaxNGFreeParserCtxt(rngpctx);
00237 xmlFreeDoc(doc);
00238 xmlFreeDoc(rngdoc);
00239 StrFree(filename);
00240
00241 return 0;
00242 }
00243
00244
00245 void log_init(int facility, const char *program_name)
00246 {
00247 openlog(program_name, 0, facility);
00248 }
00249
00250
00251 void log_switch(int facility, const char *facility_name, const char *program_name, int verbose)
00252 {
00253 closelog();
00254 openlog(program_name, 0, facility);
00255 if (verbose) {
00256 log_msg(NULL, LOG_INFO, "Switched log facility to: %s", facility_name);
00257 }
00258 }
00259
00260
00261 void
00262 log_msg(DAEMONCONFIG *config, int priority, const char *format, ...)
00263 {
00264
00265 va_list args;
00266 if (config && config->debug) priority = LOG_ERR;
00267 va_start(args, format);
00268 vsyslog(priority, format, args);
00269 va_end(args);
00270 }
00271
00272
00273
00274
00275 void
00276 ksm_log_msg(const char *format)
00277 {
00278 if (strncmp(format, "ERROR:", 6) == 0) {
00279 syslog(LOG_ERR, "%s", format);
00280 }
00281 else if (strncmp(format, "INFO:", 5) == 0) {
00282 syslog(LOG_INFO, "%s", format);
00283 }
00284 else if (strncmp(format, "WARNING:", 8) == 0) {
00285 syslog(LOG_WARNING, "%s", format);
00286 }
00287 else if (strncmp(format, "DEBUG:", 6) == 0) {
00288 syslog(LOG_DEBUG, "%s", format);
00289 }
00290 else {
00291 syslog(LOG_ERR, "%s", format);
00292 }
00293 }
00294
00295
00296 void
00297 log_xml_error(void *ignore, const char *format, ...)
00298 {
00299 va_list args;
00300
00301 (void) ignore;
00302
00303
00304 va_start(args, format);
00305 vsyslog(LOG_ERR, format, args);
00306 va_end(args);
00307 }
00308
00309
00310 void
00311 log_xml_warn(void *ignore, const char *format, ...)
00312 {
00313 va_list args;
00314
00315 (void) ignore;
00316
00317
00318 va_start(args, format);
00319 vsyslog(LOG_INFO, format, args);
00320 va_end(args);
00321 }
00322
00323 static void
00324 usage(const char* prog)
00325 {
00326 fprintf(stderr, "Usage: %s [OPTION]...\n", prog);
00327 fprintf(stderr, "OpenDNSSEC Enforcer version %s\n\n", VERSION);
00328 fprintf(stderr, "Supported options:\n");
00329 fprintf(stderr, " -c <file> Use alternate conf.xml.\n");
00330 fprintf(stderr, " -d Debug.\n");
00331 fprintf(stderr, " -1 Run once, then exit.\n");
00332
00333 fprintf(stderr, " -P pidfile Specify the PID file to write.\n");
00334
00335 fprintf(stderr, " -V Print version.\n");
00336 fprintf(stderr, " -[?|h] This help.\n");
00337 }
00338
00339 static void
00340 version(void)
00341 {
00342 fprintf(stderr, "%s version %s\n", PACKAGE_NAME, PACKAGE_VERSION);
00343 fprintf(stderr, "Written by %s.\n\n", AUTHOR_NAME);
00344 fprintf(stderr, "%s. This is free software.\n", COPYRIGHT_STR);
00345 fprintf(stderr, "See source files for more license information\n");
00346 exit(0);
00347 }
00348
00349 int
00350 write_data(DAEMONCONFIG *config, FILE *file, const void *data, size_t size)
00351 {
00352 size_t result;
00353
00354 if (size == 0)
00355 return 1;
00356
00357 result = fwrite(data, 1, size, file);
00358
00359 if (result == 0) {
00360 log_msg(config, LOG_ERR, "write failed: %s", strerror(errno));
00361 return 0;
00362 } else if (result < size) {
00363 log_msg(config, LOG_ERR, "short write (disk full?)");
00364 return 0;
00365 } else {
00366 return 1;
00367 }
00368 }
00369
00370 int
00371 writepid (DAEMONCONFIG *config)
00372 {
00373 FILE * fd;
00374 char pidbuf[32];
00375
00376 snprintf(pidbuf, sizeof(pidbuf), "%lu\n", (unsigned long) config->pid);
00377
00378 if ((fd = fopen(config->pidfile, "w")) == NULL ) {
00379 return -1;
00380 }
00381
00382 if (!write_data(config, fd, pidbuf, strlen(pidbuf))) {
00383 fclose(fd);
00384 return -1;
00385 }
00386 fclose(fd);
00387
00388 if (chown(config->pidfile, config->uid, config->gid) == -1) {
00389 log_msg(config, LOG_ERR, "cannot chown(%u,%u) %s: %s",
00390 (unsigned) config->uid, (unsigned) config->gid,
00391 config->pidfile, strerror(errno));
00392 return -1;
00393 }
00394
00395 return 0;
00396 }
00397
00398 int
00399 createPidDir (DAEMONCONFIG *config)
00400 {
00401 char* directory = NULL;
00402 char* slash;
00403 struct stat stat_ret;
00404 char *path = getenv("PWD");
00405
00406
00407 if (*config->pidfile != '/') {
00408 StrAppend(&directory, path);
00409 StrAppend(&directory, "/");
00410 StrAppend(&directory, config->pidfile);
00411 } else {
00412 directory = StrStrdup(config->pidfile);
00413 }
00414 slash = strrchr(directory, '/');
00415 *slash = 0;
00416
00417
00418 if (stat(directory, &stat_ret) != 0) {
00419
00420 if (errno != ENOENT) {
00421 log_msg(config, LOG_ERR, "cannot stat directory %s: %s",
00422 directory, strerror(errno));
00423 return -1;
00424 }
00425 }
00426
00427 if (S_ISDIR(stat_ret.st_mode)) {
00428
00429 } else {
00430
00431 if (make_directory(config, directory) != 0) {
00432 StrFree(directory);
00433 return -1;
00434 }
00435 }
00436 StrFree(directory);
00437
00438 return 0;
00439 }
00440
00441 int make_directory(DAEMONCONFIG* config, const char* path) {
00442
00443 char* parent;
00444 char* slash;
00445 struct stat stat_ret;
00446
00447 parent = StrStrdup(path);
00448 slash = strrchr(parent, '/');
00449
00450 *slash = 0;
00451
00452 stat(parent, &stat_ret);
00453
00454 if (!S_ISDIR(stat_ret.st_mode)) {
00455
00456 make_directory(config, parent);
00457
00458 }
00459
00460 StrFree(parent);
00461
00462 if (mkdir(path, (S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) != 0) {
00463 log_msg(NULL, LOG_ERR, "cannot create directory %s: %s\n",
00464 path, strerror(errno));
00465 return 1;
00466 }
00467
00468
00469 if (chown(path, config->uid, config->gid) == -1) {
00470 log_msg(config, LOG_ERR, "cannot chown(%u,%u) %s: %s",
00471 (unsigned) config->uid, (unsigned) config->gid,
00472 path, strerror(errno));
00473 return 1;
00474 }
00475
00476 return 0;
00477
00478 }
00479
00480 void
00481 cmdlParse(DAEMONCONFIG* config, int *argc, char **argv)
00482 {
00483 int c;
00484
00485
00486
00487
00488 while ((c = getopt(*argc, argv, "1c:hdV?u:P:")) != -1) {
00489 switch (c) {
00490 case '1':
00491 config->once = true;
00492 break;
00493 case 'c':
00494 config->configfile = optarg;
00495 break;
00496 case 'd':
00497 config->debug = true;
00498 break;
00499 case 'P':
00500 config->pidfile = optarg;
00501 break;
00502 case 'u':
00503 break;
00504 config->username = optarg;
00505
00506 config->gid = getgid();
00507 config->uid = getuid();
00508 if (*config->username) {
00509 struct passwd *pwd;
00510 if (isdigit(*config->username)) {
00511 char *t;
00512 config->uid = strtol(config->username, &t, 10);
00513 if (*t != 0) {
00514 if (*t != '.' || !isdigit(*++t)) {
00515 log_msg(config, LOG_ERR, "-u user or -u uid or -u uid.gid. exiting...");
00516 exit(1);
00517 }
00518 config->gid = strtol(t, &t, 10);
00519 } else {
00520
00521 if ((pwd = getpwuid(config->uid)) == NULL) {
00522 log_msg(config, LOG_ERR, "user id %u does not exist. exiting...", (unsigned) config->uid);
00523 exit(1);
00524 } else {
00525 config->gid = pwd->pw_gid;
00526 }
00527 endpwent();
00528 }
00529 } else {
00530
00531 if ((pwd = getpwnam(config->username)) == NULL) {
00532 log_msg(config, LOG_ERR, "user '%s' does not exist. exiting...", config->username);
00533 exit(1);
00534 } else {
00535 config->uid = pwd->pw_uid;
00536 config->gid = pwd->pw_gid;
00537 }
00538 endpwent();
00539 }
00540 }
00541 break;
00542 case 'h':
00543 usage(config->program);
00544 exit(0);
00545 case '?':
00546 usage(config->program);
00547 exit(0);
00548 case 'V':
00549 version();
00550 exit(0);
00551 default:
00552 usage(config->program);
00553 exit(0);
00554 }
00555 }
00556 }
00557
00558
00559
00560
00561
00562
00563 int
00564 ReadConfig(DAEMONCONFIG *config, int verbose)
00565 {
00566 xmlDocPtr doc = NULL;
00567 xmlDocPtr rngdoc = NULL;
00568 xmlXPathContextPtr xpathCtx = NULL;
00569 xmlXPathObjectPtr xpathObj = NULL;
00570 xmlRelaxNGParserCtxtPtr rngpctx = NULL;
00571 xmlRelaxNGValidCtxtPtr rngctx = NULL;
00572 xmlRelaxNGPtr schema = NULL;
00573 xmlChar *iv_expr = (unsigned char*) "//Configuration/Enforcer/Interval";
00574 xmlChar *mk_expr = (unsigned char*) "//Configuration/Enforcer/ManualKeyGeneration";
00575 xmlChar *rn_expr = (unsigned char*) "//Configuration/Enforcer/RolloverNotification";
00576 xmlChar *ds_expr = (unsigned char*) "//Configuration/Enforcer/DelegationSignerSubmitCommand";
00577 xmlChar *litexpr = (unsigned char*) "//Configuration/Enforcer/Datastore/SQLite";
00578 xmlChar *mysql_host = (unsigned char*) "//Configuration/Enforcer/Datastore/MySQL/Host";
00579 xmlChar *mysql_port = (unsigned char*) "//Configuration/Enforcer/Datastore/MySQL/Host/@port";
00580 xmlChar *mysql_db = (unsigned char*) "//Configuration/Enforcer/Datastore/MySQL/Database";
00581 xmlChar *mysql_user = (unsigned char*) "//Configuration/Enforcer/Datastore/MySQL/Username";
00582 xmlChar *mysql_pass = (unsigned char*) "//Configuration/Enforcer/Datastore/MySQL/Password";
00583 xmlChar *log_user_expr = (unsigned char*) "//Configuration/Common/Logging/Syslog/Facility";
00584
00585 int mysec = 0;
00586 char *logFacilityName;
00587 int my_log_user = DEFAULT_LOG_FACILITY;
00588 int status;
00589 int db_found = 0;
00590 char* filename = NULL;
00591 char* rngfilename = OPENDNSSEC_SCHEMA_DIR "/conf.rng";
00592
00593 char* temp_char = NULL;
00594
00595 FILE *file;
00596
00597
00598 if (config->configfile != NULL) {
00599 filename = StrStrdup(config->configfile);
00600 } else {
00601 filename = StrStrdup(OPENDNSSEC_CONFIG_FILE);
00602 }
00603
00604 if (verbose) {
00605 log_msg(config, LOG_INFO, "Reading config \"%s\"", filename);
00606 }
00607
00608
00609 doc = xmlParseFile(filename);
00610 if (doc == NULL) {
00611
00612 file = fopen(filename, "r");
00613 if (file == NULL) {
00614 log_msg(config, LOG_ERR, "Error: unable to open file \"%s\"", filename);
00615 } else {
00616 log_msg(config, LOG_ERR, "Error: unable to parse file \"%s\"", filename);
00617 fclose(file);
00618 }
00619 return(-1);
00620 }
00621
00622
00623 if (verbose) {
00624 log_msg(config, LOG_INFO, "Reading config schema \"%s\"", rngfilename);
00625 }
00626 rngdoc = xmlParseFile(rngfilename);
00627 if (rngdoc == NULL) {
00628
00629 file = fopen(rngfilename, "r");
00630 if (file == NULL) {
00631 log_msg(config, LOG_ERR, "Error: unable to open file \"%s\"", rngfilename);
00632 } else {
00633 log_msg(config, LOG_ERR, "Error: unable to parse file \"%s\"", rngfilename);
00634 fclose(file);
00635 }
00636 return(-1);
00637 }
00638
00639
00640 rngpctx = xmlRelaxNGNewDocParserCtxt(rngdoc);
00641 if (rngpctx == NULL) {
00642 log_msg(config, LOG_ERR, "Error: unable to create XML RelaxNGs parser context");
00643 return(-1);
00644 }
00645
00646
00647 schema = xmlRelaxNGParse(rngpctx);
00648 if (schema == NULL) {
00649 log_msg(config, LOG_ERR, "Error: unable to parse a schema definition resource");
00650 return(-1);
00651 }
00652
00653
00654 rngctx = xmlRelaxNGNewValidCtxt(schema);
00655 if (rngctx == NULL) {
00656 log_msg(config, LOG_ERR, "Error: unable to create RelaxNGs validation context based on the schema");
00657 return(-1);
00658 }
00659
00660 xmlRelaxNGSetValidErrors(rngctx,
00661 (xmlRelaxNGValidityErrorFunc) log_xml_error,
00662 (xmlRelaxNGValidityWarningFunc) log_xml_warn,
00663 NULL);
00664
00665
00666 status = xmlRelaxNGValidateDoc(rngctx,doc);
00667 if (status != 0) {
00668 log_msg(config, LOG_ERR, "Error validating file \"%s\"", filename);
00669 return(-1);
00670 }
00671 xmlRelaxNGFreeValidCtxt(rngctx);
00672 xmlRelaxNGFree(schema);
00673 xmlRelaxNGFreeParserCtxt(rngpctx);
00674 xmlFreeDoc(rngdoc);
00675
00676
00677
00678 xpathCtx = xmlXPathNewContext(doc);
00679 if(xpathCtx == NULL) {
00680 log_msg(config, LOG_ERR,"Error: unable to create new XPath context");
00681 xmlFreeDoc(doc);
00682 return(-1);
00683 }
00684
00685
00686 xpathObj = xmlXPathEvalExpression(iv_expr, xpathCtx);
00687 if(xpathObj == NULL) {
00688 log_msg(config, LOG_ERR, "Error: unable to evaluate xpath expression: %s", iv_expr);
00689 xmlXPathFreeContext(xpathCtx);
00690 xmlFreeDoc(doc);
00691 return(-1);
00692 }
00693
00694 temp_char = (char *)xmlXPathCastToString(xpathObj);
00695 status = DtXMLIntervalSeconds(temp_char, &mysec);
00696 if (status > 0) {
00697 log_msg(config, LOG_ERR, "Error: unable to convert Interval %s to seconds, error: %i", temp_char, status);
00698 StrFree(temp_char);
00699 return status;
00700 }
00701 else if (status == -1) {
00702 log_msg(config, LOG_INFO, "Info: converting %s to seconds; M interpreted as 31 days, Y interpreted as 365 days", temp_char);
00703 }
00704 config->interval = mysec;
00705 if (verbose) {
00706 log_msg(config, LOG_INFO, "Communication Interval: %i", config->interval);
00707 }
00708 StrFree(temp_char);
00709 xmlXPathFreeObject(xpathObj);
00710
00711
00712 xpathObj = xmlXPathEvalExpression(mk_expr, xpathCtx);
00713 if(xpathObj == NULL) {
00714 log_msg(config, LOG_ERR, "Error: unable to evaluate xpath expression: %s", mk_expr);
00715 xmlXPathFreeContext(xpathCtx);
00716 xmlFreeDoc(doc);
00717 return(-1);
00718 }
00719
00720 if (xpathObj->nodesetval != NULL && xpathObj->nodesetval->nodeNr > 0) {
00721
00722 config->manualKeyGeneration = 1;
00723 }
00724 else {
00725
00726 config->manualKeyGeneration = 0;
00727 }
00728 xmlXPathFreeObject(xpathObj);
00729
00730
00731 xpathObj = xmlXPathEvalExpression(rn_expr, xpathCtx);
00732 if(xpathObj == NULL) {
00733 log_msg(config, LOG_ERR, "Error: unable to evaluate xpath expression: %s", rn_expr);
00734 xmlXPathFreeContext(xpathCtx);
00735 xmlFreeDoc(doc);
00736 return(-1);
00737 }
00738
00739 if (xpathObj->nodesetval != NULL && xpathObj->nodesetval->nodeNr > 0) {
00740
00741 temp_char = (char *)xmlXPathCastToString(xpathObj);
00742 status = DtXMLIntervalSeconds(temp_char, &mysec);
00743 if (status > 0) {
00744 log_msg(config, LOG_ERR, "Error: unable to convert RolloverNotification %s to seconds, error: %i", temp_char, status);
00745 StrFree(temp_char);
00746 return status;
00747 }
00748 else if (status == -1) {
00749 log_msg(config, LOG_INFO, "Info: converting %s to seconds; M interpreted as 31 days, Y interpreted as 365 days", temp_char);
00750 }
00751 config->rolloverNotify = mysec;
00752 if (verbose) {
00753 log_msg(config, LOG_INFO, "Rollover Notification Interval: %i", config->rolloverNotify);
00754 }
00755 StrFree(temp_char);
00756 xmlXPathFreeObject(xpathObj);
00757 }
00758 else {
00759
00760 config->rolloverNotify = -1;
00761 }
00762
00763
00764 xpathObj = xmlXPathEvalExpression(ds_expr, xpathCtx);
00765 if(xpathObj == NULL) {
00766 log_msg(config, LOG_ERR, "Error: unable to evaluate xpath expression: %s", ds_expr);
00767 xmlXPathFreeContext(xpathCtx);
00768 xmlFreeDoc(doc);
00769 return(-1);
00770 }
00771 if (xpathObj->nodesetval != NULL && xpathObj->nodesetval->nodeNr > 0) {
00772
00773 if (config->DSSubmitCmd != NULL) {
00774 StrFree(config->DSSubmitCmd);
00775 }
00776 config->DSSubmitCmd = (char *)xmlXPathCastToString(xpathObj);
00777
00778 if (verbose) {
00779 log_msg(config, LOG_INFO, "Using command: %s to submit DS records", config->DSSubmitCmd);
00780 }
00781 xmlXPathFreeObject(xpathObj);
00782 } else {
00783 if (verbose) {
00784 log_msg(config, LOG_INFO, "No DS Submit command supplied");
00785 }
00786 config->DSSubmitCmd[0] = '\0';
00787 }
00788
00789
00790
00791 xpathObj = xmlXPathEvalExpression(litexpr, xpathCtx);
00792 if(xpathObj == NULL) {
00793 log_msg(config, LOG_ERR, "Error: unable to evaluate xpath expression: %s", litexpr);
00794 xmlXPathFreeContext(xpathCtx);
00795 xmlFreeDoc(doc);
00796 return(-1);
00797 }
00798 if(xpathObj->nodesetval != NULL && xpathObj->nodesetval->nodeNr > 0) {
00799 db_found = SQLITE_DB;
00800 if (config->schema != NULL) {
00801 StrFree(config->schema);
00802 }
00803 config->schema = xmlXPathCastToString(xpathObj);
00804 if (verbose) {
00805 log_msg(config, LOG_INFO, "SQLite database set to: %s", config->schema);
00806 }
00807 }
00808 xmlXPathFreeObject(xpathObj);
00809
00810 if (db_found == 0) {
00811 db_found = MYSQL_DB;
00812
00813
00814
00815 xpathObj = xmlXPathEvalExpression(mysql_host, xpathCtx);
00816 if(xpathObj == NULL) {
00817 log_msg(config, LOG_ERR, "Error: unable to evaluate xpath expression: %s", mysql_host);
00818 xmlXPathFreeContext(xpathCtx);
00819 xmlFreeDoc(doc);
00820 return(-1);
00821 }
00822 if(xpathObj->nodesetval != NULL && xpathObj->nodesetval->nodeNr > 0) {
00823 if (config->host != NULL) {
00824 StrFree(config->host);
00825 }
00826 config->host = xmlXPathCastToString(xpathObj);
00827 if (verbose) {
00828 log_msg(config, LOG_INFO, "MySQL database host set to: %s", config->host);
00829 }
00830 }
00831 xmlXPathFreeObject(xpathObj);
00832
00833
00834 xpathObj = xmlXPathEvalExpression(mysql_port, xpathCtx);
00835 if(xpathObj == NULL) {
00836 log_msg(config, LOG_ERR, "Error: unable to evaluate xpath expression: %s", mysql_port);
00837 xmlXPathFreeContext(xpathCtx);
00838 xmlFreeDoc(doc);
00839 return(-1);
00840 }
00841 if(xpathObj->nodesetval != NULL && xpathObj->nodesetval->nodeNr > 0) {
00842 if (config->port != NULL) {
00843 StrFree(config->port);
00844 }
00845 config->port = xmlXPathCastToString(xpathObj);
00846 if (verbose) {
00847 log_msg(config, LOG_INFO, "MySQL database port set to: %s", config->port);
00848 }
00849 }
00850 xmlXPathFreeObject(xpathObj);
00851
00852
00853 xpathObj = xmlXPathEvalExpression(mysql_db, xpathCtx);
00854 if(xpathObj == NULL) {
00855 log_msg(config, LOG_ERR, "Error: unable to evaluate xpath expression: %s", mysql_db);
00856 xmlXPathFreeContext(xpathCtx);
00857 xmlFreeDoc(doc);
00858 return(-1);
00859 }
00860 if(xpathObj->nodesetval != NULL && xpathObj->nodesetval->nodeNr > 0) {
00861 if (config->schema != NULL) {
00862 StrFree(config->schema);
00863 }
00864 config->schema = xmlXPathCastToString(xpathObj);
00865 if (verbose) {
00866 log_msg(config, LOG_INFO, "MySQL database schema set to: %s", config->schema);
00867 }
00868 } else {
00869 db_found = 0;
00870 }
00871 xmlXPathFreeObject(xpathObj);
00872
00873
00874 xpathObj = xmlXPathEvalExpression(mysql_user, xpathCtx);
00875 if(xpathObj == NULL) {
00876 log_msg(config, LOG_ERR, "Error: unable to evaluate xpath expression: %s", mysql_user);
00877 xmlXPathFreeContext(xpathCtx);
00878 xmlFreeDoc(doc);
00879 return(-1);
00880 }
00881 if(xpathObj->nodesetval != NULL && xpathObj->nodesetval->nodeNr > 0) {
00882 if (config->user != NULL) {
00883 StrFree(config->user);
00884 }
00885 config->user = xmlXPathCastToString(xpathObj);
00886 if (verbose) {
00887 log_msg(config, LOG_INFO, "MySQL database user set to: %s", config->user);
00888 }
00889 } else {
00890 db_found = 0;
00891 }
00892 xmlXPathFreeObject(xpathObj);
00893
00894
00895 xpathObj = xmlXPathEvalExpression(mysql_pass, xpathCtx);
00896 if(xpathObj == NULL) {
00897 log_msg(config, LOG_ERR, "Error: unable to evaluate xpath expression: %s", mysql_pass);
00898 xmlXPathFreeContext(xpathCtx);
00899 xmlFreeDoc(doc);
00900 return(-1);
00901 }
00902
00903
00904 if (config->password != NULL) {
00905 StrFree(config->password);
00906 }
00907 config->password = xmlXPathCastToString(xpathObj);
00908 if (verbose) {
00909 log_msg(config, LOG_INFO, "MySQL database password set");
00910 }
00911 xmlXPathFreeObject(xpathObj);
00912
00913 }
00914
00915
00916 if(db_found == 0) {
00917 log_msg(config, LOG_ERR, "Error: unable to find complete database connection expression in %s", filename);
00918 xmlXPathFreeContext(xpathCtx);
00919 xmlFreeDoc(doc);
00920 return(-1);
00921 }
00922
00923
00924 if (db_found != DbFlavour()) {
00925 log_msg(config, LOG_ERR, "Error: database in config file %s does not match libksm", filename);
00926 xmlXPathFreeContext(xpathCtx);
00927 xmlFreeDoc(doc);
00928 return(-1);
00929 }
00930
00931
00932 xpathObj = xmlXPathEvalExpression(log_user_expr, xpathCtx);
00933 if(xpathObj == NULL) {
00934 log_msg(config, LOG_ERR, "Error: unable to evaluate xpath expression: %s", log_user_expr);
00935 xmlXPathFreeContext(xpathCtx);
00936 xmlFreeDoc(doc);
00937 return(-1);
00938 }
00939
00940 if (xpathObj->nodesetval != NULL && xpathObj->nodesetval->nodeNr > 0) {
00941
00942 logFacilityName = (char *)xmlXPathCastToString(xpathObj);
00943
00944 status = get_log_user(logFacilityName, &my_log_user);
00945 if (status > 0) {
00946 log_msg(config, LOG_ERR, "Error: unable to set log user: %s, error: %i", logFacilityName, status);
00947 StrFree(logFacilityName);
00948 return status;
00949 }
00950 config->log_user = my_log_user;
00951 if (verbose) {
00952 log_msg(config, LOG_INFO, "Log User set to: %s", logFacilityName);
00953 }
00954
00955 } else {
00956
00957 logFacilityName = StrStrdup( (char *)DEFAULT_LOG_FACILITY_STRING );
00958 config->log_user = DEFAULT_LOG_FACILITY;
00959 if (verbose) {
00960 log_msg(config, LOG_INFO, "Using default log user: %s", logFacilityName);
00961 }
00962 }
00963
00964 xmlXPathFreeObject(xpathObj);
00965
00966 log_switch(my_log_user, logFacilityName, config->program, verbose);
00967
00968
00969
00970 xmlXPathFreeContext(xpathCtx);
00971 xmlFreeDoc(doc);
00972 StrFree(logFacilityName);
00973 StrFree(filename);
00974
00975 return(0);
00976
00977 }
00978
00979
00980
00981
00982
00983
00984
00985 int get_lite_lock(char *lock_filename, FILE* lock_fd)
00986 {
00987 struct flock fl;
00988 struct timeval tv;
00989
00990 if (lock_fd == NULL) {
00991 log_msg(NULL, LOG_ERR, "%s could not be opened", lock_filename);
00992 return 1;
00993 }
00994
00995 memset(&fl, 0, sizeof(struct flock));
00996 fl.l_type = F_WRLCK;
00997 fl.l_whence = SEEK_SET;
00998 fl.l_pid = getpid();
00999
01000 while (fcntl(fileno(lock_fd), F_SETLK, &fl) == -1) {
01001 if (errno == EACCES || errno == EAGAIN) {
01002 log_msg(NULL, LOG_INFO, "%s already locked, sleep", lock_filename);
01003
01004
01005 tv.tv_sec = 10;
01006 tv.tv_usec = 0;
01007 select(0, NULL, NULL, NULL, &tv);
01008
01009 } else {
01010 log_msg(NULL, LOG_INFO, "couldn't get lock on %s, %s", lock_filename, strerror(errno));
01011 return 1;
01012 }
01013 }
01014
01015 return 0;
01016
01017 }
01018
01019 int release_lite_lock(FILE* lock_fd)
01020 {
01021 struct flock fl;
01022
01023 if (lock_fd == NULL) {
01024 return 1;
01025 }
01026
01027 memset(&fl, 0, sizeof(struct flock));
01028 fl.l_type = F_UNLCK;
01029 fl.l_whence = SEEK_SET;
01030
01031 if (fcntl(fileno(lock_fd), F_SETLK, &fl) == -1) {
01032 return 1;
01033 }
01034
01035 return 0;
01036 }
01037
01038
01039 int get_log_user(const char* username, int* usernumber)
01040 {
01041 char* case_username = NULL;
01042
01043 if (username == NULL) {
01044 return 1;
01045 }
01046
01047 *usernumber = DEFAULT_LOG_FACILITY;
01048
01049 case_username = StrStrdup(username);
01050 (void) StrToUpper(case_username);
01051
01052
01053 if (strncmp(case_username, "USER", 4) == 0) {
01054 *usernumber = LOG_USER;
01055 }
01056 #ifdef LOG_KERN
01057 else if (strncmp(case_username, "KERN", 4) == 0) {
01058 *usernumber = LOG_KERN;
01059 }
01060 #endif
01061 #ifdef LOG_MAIL
01062 else if (strncmp(case_username, "MAIL", 4) == 0) {
01063 *usernumber = LOG_MAIL;
01064 }
01065 #endif
01066 #ifdef LOG_DAEMON
01067 else if (strncmp(case_username, "DAEMON", 6) == 0) {
01068 *usernumber = LOG_DAEMON;
01069 }
01070 #endif
01071 #ifdef LOG_AUTH
01072 else if (strncmp(case_username, "AUTH", 4) == 0) {
01073 *usernumber = LOG_AUTH;
01074 }
01075 #endif
01076 #ifdef LOG_SYSLOG
01077 else if (strncmp(case_username, "SYSLOG", 6) == 0) {
01078 *usernumber = LOG_SYSLOG;
01079 }
01080 #endif
01081 #ifdef LOG_LPR
01082 else if (strncmp(case_username, "LPR", 3) == 0) {
01083 *usernumber = LOG_LPR;
01084 }
01085 #endif
01086 #ifdef LOG_NEWS
01087 else if (strncmp(case_username, "NEWS", 4) == 0) {
01088 *usernumber = LOG_NEWS;
01089 }
01090 #endif
01091 #ifdef LOG_UUCP
01092 else if (strncmp(case_username, "UUCP", 4) == 0) {
01093 *usernumber = LOG_UUCP;
01094 }
01095 #endif
01096 #ifdef LOG_AUDIT
01097 else if (strncmp(case_username, "AUDIT", 5) == 0) {
01098 *usernumber = LOG_AUDIT;
01099 }
01100 #endif
01101 #ifdef LOG_CRON
01102 else if (strncmp(case_username, "CRON", 4) == 0) {
01103 *usernumber = LOG_CRON;
01104 }
01105 #endif
01106 else if (strncmp(case_username, "LOCAL0", 6) == 0) {
01107 *usernumber = LOG_LOCAL0;
01108 }
01109 else if (strncmp(case_username, "LOCAL1", 6) == 0) {
01110 *usernumber = LOG_LOCAL1;
01111 }
01112 else if (strncmp(case_username, "LOCAL2", 6) == 0) {
01113 *usernumber = LOG_LOCAL2;
01114 }
01115 else if (strncmp(case_username, "LOCAL3", 6) == 0) {
01116 *usernumber = LOG_LOCAL3;
01117 }
01118 else if (strncmp(case_username, "LOCAL4", 6) == 0) {
01119 *usernumber = LOG_LOCAL4;
01120 }
01121 else if (strncmp(case_username, "LOCAL5", 6) == 0) {
01122 *usernumber = LOG_LOCAL5;
01123 }
01124 else if (strncmp(case_username, "LOCAL6", 6) == 0) {
01125 *usernumber = LOG_LOCAL6;
01126 }
01127 else if (strncmp(case_username, "LOCAL7", 6) == 0) {
01128 *usernumber = LOG_LOCAL7;
01129 }
01130
01131 StrFree(case_username);
01132
01133 return 0;
01134
01135 }
01136