troglobit / sysklogd

BSD syslog daemon with syslog()/syslogp() API replacement for Linux, RFC3164 + RFC5424
https://troglobit.com/sysklogd.html
Other
89 stars 20 forks source link

RFE: Add option for configuration file check #74

Closed opty77 closed 3 months ago

opty77 commented 4 months ago

Please add an option (e.g. -N) for configuration file check:

diff -Naur a/sysklogd-2.5.2/src/syslogd.c b/sysklogd-2.5.2/src/syslogd.c
--- a/sysklogd-2.5.2/src/syslogd.c  2023-08-21 17:18:44.000000000 +0200
+++ b/sysklogd-2.5.2/src/syslogd.c  2024-05-28 15:50:26.538393301 +0200
@@ -141,6 +141,7 @@
 static char     *emptystring = "";
 static int   Initialized = 0;    /* set when we have initialized ourselves */
 static int   MarkInterval = 20 * 60; /* interval between marks in seconds */
+static int   CheckConf = 0;      /* check .conf file flag */
 static int   family = PF_UNSPEC;     /* protocol family (IPv4, IPv6 or both) */
 static int   mask_C1 = 1;        /* mask characters from 0x80 - 0x9F */
 static int   send_to_all;        /* send message to all IPv4/IPv6 addresses */
@@ -329,7 +330,7 @@
 int usage(int code)
 {
    printf("Usage:\n"
-          "  syslogd [-468AdFHKknsTtv?] [-a PEER] [-b NAME] [-f FILE] [-m INTERVAL]\n"
+          "  syslogd [-468AdFHKkNnsTtv?] [-a PEER] [-b NAME] [-f FILE] [-m INTERVAL]\n"
           "                             [-P PID_FILE] [-p SOCK_PATH] [-r SIZE[:NUM]]\n"
           "Options:\n"
           "  -4        Force IPv4 only\n"
@@ -364,6 +365,7 @@
           "  -K        Disable kernel logging, useful in container use-cases\n"
           "  -k        Allow logging with facility 'kernel', otherwise remapped to 'user'\n"
           "  -m MINS   Interval between MARK messages, 0 to disable, default: 20 min\n"
+          "  -N        Check .conf file\n"
           "  -n        Disable DNS query for every request\n"
           "  -P FILE   File to store the process ID, default: %s\n"
           "  -p PATH   Path to UNIX domain socket, multiple -p create multiple sockets.\n"
@@ -396,8 +398,10 @@
    int bflag = 0;
    char *ptr;
    int ch;
+   FILE *fp;
+   int ret = 0;

-   while ((ch = getopt(argc, argv, "468Aa:b:C:cdHFf:Kkm:nP:p:r:sTtv?")) != EOF) {
+   while ((ch = getopt(argc, argv, "468Aa:b:C:cdHFf:Kkm:NnP:p:r:sTtv?")) != EOF) {
        switch ((char)ch) {
        case '4':
            family = PF_INET;
@@ -468,6 +472,10 @@
            MarkInterval = atoi(optarg) * 60;
            break;

+       case 'N':
+           CheckConf = 1;
+           break;
+
        case 'n':
            resolve = 0;
            break;
@@ -520,6 +528,24 @@
    if ((argc -= optind))
        return usage(1);

+   if (CheckConf) {
+       fp = fopen(ConfFile, "r");
+       if (!fp) {
+           printf("Cannot open %s: %s\n", ConfFile, strerror(errno));
+           return 1;
+       }
+
+       /* TODO: Duplicate code, see below. */
+       if (Debug) {
+           debugging_on = 1;
+           setlinebuf(stdout);
+       }
+
+       ret = cfparse(fp, NULL, NULL);
+       fclose(fp);
+       return ret;
+   }
+
    /* Default to listen to :514 (syslog/udp) */
    if (!bflag)
        addpeer(&(struct peer) {
@@ -3072,21 +3098,30 @@
        if (syncfile)
            f->f_flags |= SYNC_FILE;
        if (*p == '|') {
-           f->f_file = open(++p, O_RDWR | O_NONBLOCK | O_NOCTTY);
+           /* See below. */
+           if (!CheckConf) {
+               f->f_file = open(++p, O_RDWR | O_NONBLOCK | O_NOCTTY);
+           }
            f->f_type = F_PIPE;
        } else {
-           f->f_file = open(p, O_CREATE | O_NONBLOCK | O_NOCTTY, 0644);
+            /* See below. */
+           if (!CheckConf) {
+               f->f_file = open(p, O_CREATE | O_NONBLOCK | O_NOCTTY, 0644);
+           }
            f->f_type = F_FILE;
        }

-       if (f->f_file < 0) {
-           f->f_file = -1;
-           ERR("Error opening log file: %s", p);
-           break;
-       }
-       if (isatty(f->f_file)) {
-           f->f_type = F_TTY;
-           untty();
+       /* Allow unprivileged user to check configuration file. */
+       if (!CheckConf) {
+           if (f->f_file < 0) {
+               f->f_file = -1;
+               ERR("Error opening log file: %s", p);
+               break;
+           }
+           if (isatty(f->f_file)) {
+               f->f_type = F_TTY;
+               untty();
+           }
        }
        if (strcmp(p, ctty) == 0)
            f->f_type = F_CONSOLE;
@@ -3195,6 +3230,7 @@
    char  cbuf[BUFSIZ];
    char *cline;
    char *p;
+   int ret = 0;

    if (!fp)
        return 1;
@@ -3250,11 +3286,12 @@
                if (!fpi) {
                    logit("Failed opening %s: %s\n",
                          gl.gl_pathv[i], strerror(errno));
+                   ret = 1;
                    continue;
                }

                logit("Parsing %s ...\n", gl.gl_pathv[i]);
-               cfparse(fpi, newf, newn);
+               ret = cfparse(fpi, newf, newn);
                fclose(fpi);
            }
            globfree(&gl);
@@ -3263,24 +3300,29 @@

        cfk = cfkey_match(cline);
        if (cfk) {
-           if (!strcmp(cfk->key, "notify"))
+           if (!CheckConf && !strcmp(cfk->key, "notify"))
                notifier_add(newn, cline);
            continue;
        }

        f = cfline(cline);
-       if (!f)
+       if (!f) {
+           ret = 1;
            continue;
+       }

-       SIMPLEQ_INSERT_TAIL(newf, f, f_link);
+       if (!CheckConf)
+           SIMPLEQ_INSERT_TAIL(newf, f, f_link);
    }

    if (secure_str) {
        int val;

        val = atoi(secure_str);
-       if (val < 0 || val > 2)
+       if (val < 0 || val > 2) {
            logit("Invalid value to secure_mode = %s\n", secure_str);
+           ret = 1;
+       }
        else
            secure_mode = val;

@@ -3288,6 +3330,9 @@
        secure_str = NULL;
    }

+   if (CheckConf)
+       return ret;
+
    return 0;
 }

Sorry for not creating a PR.

opty77 commented 4 months ago

Maybe also add an argument level:

opty77 commented 3 months ago

LOI