new upstream release (3.3.0); modify package compatibility for Stretch
[ossec-hids.git] / src / os_maild / maild.c
old mode 100755 (executable)
new mode 100644 (file)
index 976796e..1542956
@@ -1,6 +1,3 @@
-/* @(#) $Id: ./src/os_maild/maild.c, 2011/09/08 dcid Exp $
- */
-
 /* Copyright (C) 2009 Trend Micro Inc.
  * All rights reserved.
  *
@@ -8,50 +5,69 @@
  * and/or modify it under the terms of the GNU General Public
  * License (version 2) as published by the FSF - Free Software
  * Foundation.
- *
- * License details at the LICENSE file included with OSSEC or
- * online at: http://www.ossec.net/en/licensing.html
  */
 
-
-#ifndef MAILD
-   #define MAILD
-#endif
+#include "shared.h"
+#include "maild.h"
+#include "mail_list.h"
 
 #ifndef ARGV0
-   #define ARGV0 "ossec-maild"
+#define ARGV0 "ossec-maild"
 #endif
 
-#include "shared.h"
-#include "maild.h"
-#include "mail_list.h"
+/* Global variables */
+unsigned int mail_timeout;
+unsigned int   _g_subject_level;
+char _g_subject[SUBJECT_SIZE + 2];
+
+/* Prototypes */
+static void OS_Run(MailConfig *mail) __attribute__((nonnull)) __attribute__((noreturn));
+static void help_maild(void) __attribute__((noreturn));
 
-void OS_Run(MailConfig *mail);
+
+/* Print help statement */
+static void help_maild()
+{
+    print_header();
+    print_out("  %s: -[Vhdtf] [-u user] [-g group] [-c config] [-D dir]", ARGV0);
+    print_out("    -V          Version and license message");
+    print_out("    -h          This help message");
+    print_out("    -d          Execute in debug mode. This parameter");
+    print_out("                can be specified multiple times");
+    print_out("                to increase the debug level.");
+    print_out("    -t          Test configuration");
+    print_out("    -f          Run in foreground");
+    print_out("    -u <user>   User to run as (default: %s)", MAILUSER);
+    print_out("    -g <group>  Group to run as (default: %s)", GROUPGLOBAL);
+    print_out("    -c <config> Configuration file to use (default: %s)", DEFAULTCPATH);
+    print_out("    -D <dir>    Directory to chroot into (default: %s)", DEFAULTDIR);
+    print_out(" ");
+    exit(1);
+}
 
 int main(int argc, char **argv)
 {
-    int c, test_config = 0,run_foreground = 0;
-    int uid = 0,gid = 0;
-    char *dir  = DEFAULTDIR;
-    char *user = MAILUSER;
-    char *group = GROUPGLOBAL;
-    char *cfg = DEFAULTCPATH;
+    int c, test_config = 0, run_foreground = 0;
+    uid_t uid;
+    gid_t gid;
+    const char *dir  = DEFAULTDIR;
+    const char *user = MAILUSER;
+    const char *group = GROUPGLOBAL;
+    const char *cfg = DEFAULTCPATH;
 
     /* Mail Structure */
     MailConfig mail;
 
-
-    /* Setting the name */
+    /* Set the name */
     OS_SetName(ARGV0);
 
-
-    while((c = getopt(argc, argv, "Vdhtfu:g:D:c:")) != -1){
-        switch(c){
+    while ((c = getopt(argc, argv, "Vdhtfu:g:D:c:")) != -1) {
+        switch (c) {
             case 'V':
                 print_version();
                 break;
             case 'h':
-                help(ARGV0);
+                help_maild();
                 break;
             case 'd':
                 nowDebug();
@@ -60,130 +76,125 @@ int main(int argc, char **argv)
                 run_foreground = 1;
                 break;
             case 'u':
-                if(!optarg)
-                    ErrorExit("%s: -u needs an argument",ARGV0);
-                user=optarg;
+                if (!optarg) {
+                    ErrorExit("%s: -u needs an argument", ARGV0);
+                }
+                user = optarg;
                 break;
             case 'g':
-                if(!optarg)
-                    ErrorExit("%s: -g needs an argument",ARGV0);
-                group=optarg;
+                if (!optarg) {
+                    ErrorExit("%s: -g needs an argument", ARGV0);
+                }
+                group = optarg;
                 break;
             case 'D':
-                if(!optarg)
-                    ErrorExit("%s: -D needs an argument",ARGV0);
-                dir=optarg;
+                if (!optarg) {
+                    ErrorExit("%s: -D needs an argument", ARGV0);
+                }
+                dir = optarg;
                 break;
             case 'c':
-                if(!optarg)
-                    ErrorExit("%s: -c needs an argument",ARGV0);
+                if (!optarg) {
+                    ErrorExit("%s: -c needs an argument", ARGV0);
+                }
                 cfg = optarg;
                 break;
             case 't':
                 test_config = 1;
                 break;
             default:
-                help(ARGV0);
+                help_maild();
                 break;
         }
-
     }
 
-    /* Starting daemon */
-    debug1(STARTED_MSG,ARGV0);
+    /* Start daemon */
+    debug1(STARTED_MSG, ARGV0);
 
-    /*Check if the user/group given are valid */
+    /* Check if the user/group given are valid */
     uid = Privsep_GetUser(user);
     gid = Privsep_GetGroup(group);
-    if((uid < 0)||(gid < 0))
-        ErrorExit(USER_ERROR,ARGV0,user,group);
+    if (uid == (uid_t) - 1 || gid == (gid_t) - 1) {
+        ErrorExit(USER_ERROR, ARGV0, user, group);
+    }
 
-    /* Reading configuration */
-    if(MailConf(test_config, cfg, &mail) < 0)
+    /* Read configuration */
+    if (MailConf(test_config, cfg, &mail) < 0) {
         ErrorExit(CONFIG_ERROR, ARGV0, cfg);
+    }
 
-
-    /* Reading internal options */
+    /* Read internal options */
     mail.strict_checking = getDefine_Int("maild",
                                          "strict_checking",
-                                          0, 1);
+                                         0, 1);
 
     /* Get groupping */
     mail.groupping = getDefine_Int("maild",
                                    "groupping",
-                                    0, 1);
+                                   0, 1);
 
-    /* Getting subject type */
+    /* Get subject type */
     mail.subject_full = getDefine_Int("maild",
                                       "full_subject",
                                       0, 1);
 
-#ifdef GEOIP
+#ifdef LIBGEOIP_ENABLED
     /* Get GeoIP */
     mail.geoip = getDefine_Int("maild",
                                "geoip",
                                0, 1);
 #endif
 
-
     /* Exit here if test config is set */
-    if(test_config)
+    if (test_config) {
         exit(0);
+    }
 
-
-    if(!run_foreground)
-    {
+    if (!run_foreground) {
         nowDaemon();
         goDaemon();
     }
 
-
     /* Privilege separation */
-    if(Privsep_SetGroup(gid) < 0)
-        ErrorExit(SETGID_ERROR,ARGV0,group);
-
-
-    /* chrooting */
-    if(Privsep_Chroot(dir) < 0)
-        ErrorExit(CHROOT_ERROR,ARGV0,dir);
-
-    nowChroot();
-
-
-
-    /* Changing user */
-    if(Privsep_SetUser(uid) < 0)
-        ErrorExit(SETUID_ERROR,ARGV0,user);
-
+    if (Privsep_SetGroup(gid) < 0) {
+        ErrorExit(SETGID_ERROR, ARGV0, group, errno, strerror(errno));
+    }
 
-    debug1(PRIVSEP_MSG,ARGV0,dir,user);
+    if (mail.smtpserver[0] != '/') {
+        /* chroot */
+        if (Privsep_Chroot(dir) < 0) {
+            ErrorExit(CHROOT_ERROR, ARGV0, dir, errno, strerror(errno));
+        }
+        nowChroot();
+        debug1(CHROOT_MSG, ARGV0, dir);
+    }
 
+    /* Change user */
+    if (Privsep_SetUser(uid) < 0) {
+        ErrorExit(SETUID_ERROR, ARGV0, user, errno, strerror(errno));
+    }
 
+    debug1(PRIVSEP_MSG, ARGV0, user);
 
     /* Signal manipulation */
     StartSIG(ARGV0);
 
-
-
-    /* Creating PID files */
-    if(CreatePID(ARGV0, getpid()) < 0)
+    /* Create PID files */
+    if (CreatePID(ARGV0, getpid()) < 0) {
         ErrorExit(PID_ERROR, ARGV0);
-
+    }
 
     /* Start up message */
     verbose(STARTUP_MSG, ARGV0, (int)getpid());
 
-
-    /* the real daemon now */
+    /* The real daemon now */
     OS_Run(&mail);
-    exit(0);
 }
 
-
-/* OS_Run: Read the queue and send the appropriate alerts.
- * not supposed to return..
+/* Read the queue and send the appropriate alerts
+ * Not supposed to return
  */
-void OS_Run(MailConfig *mail)
+static void OS_Run(MailConfig *mail)
 {
     MailMsg *msg;
     MailMsg *s_msg = NULL;
@@ -201,173 +212,110 @@ void OS_Run(MailConfig *mail)
 
     file_queue *fileq;
 
-
-    /* Getting currently time before starting */
+    /* Get current time before starting */
     tm = time(NULL);
     p = localtime(&tm);
     thishour = p->tm_hour;
 
-
-    /* Init file queue */
+    /* Initialize file queue */
     i = 0;
     i |= CRALERT_MAIL_SET;
     os_calloc(1, sizeof(file_queue), fileq);
     Init_FileQueue(fileq, p, i);
 
-
-    /* Creating the list */
+    /* Create the list */
     OS_CreateMailList(MAIL_LIST_SIZE);
 
-
-    /* Setting default timeout */
+    /* Set default timeout */
     mail_timeout = DEFAULT_TIMEOUT;
 
-
-    /* Clearing global vars */
+    /* Clear global variables */
     _g_subject_level = 0;
-    memset(_g_subject, '\0', SUBJECT_SIZE +2);
+    memset(_g_subject, '\0', SUBJECT_SIZE + 2);
 
-
-    while(1)
-    {
+    while (1) {
         tm = time(NULL);
         p = localtime(&tm);
 
 
-        /* SMS messages are sent without delay */
-        if(msg_sms)
-        {
-            pid_t pid;
-
-            pid = fork();
-
-            if(pid < 0)
-            {
-                merror("%s: Fork failed. cause: %d - %s", ARGV0, errno, strerror(errno));
-                merror(FORK_ERROR, ARGV0);
-                sleep(30);
-                continue;
-            }
-            else if (pid == 0)
-            {
-                if(OS_Sendsms(mail, p, msg_sms) < 0)
-                    merror(SNDMAIL_ERROR, ARGV0, mail->smtpserver);
-
-                exit(0);
-            }
-
-
-            /* Freeing sms structure */
-            FreeMailMsg(msg_sms);
-            msg_sms = NULL;
-
-
-            /* Increasing child count */
-            childcount++;
-        }
-
-
         /* If mail_timeout == NEXTMAIL_TIMEOUT, we will try to get
          * more messages, before sending anything
          */
-        if((mail_timeout == NEXTMAIL_TIMEOUT) && (p->tm_hour == thishour))
-        {
-            /* getting more messages */
+        if ((mail_timeout == NEXTMAIL_TIMEOUT) && (p->tm_hour == thishour)) {
+            /* Get more messages */
         }
 
-
-        /* Hour changed. Send all supressed mails */
-        else if(((mailtosend < mail->maxperhour) && (mailtosend != 0))||
-                ((p->tm_hour != thishour) && (childcount < MAXCHILDPROCESS)))
-        {
+        /* Hour changed: send all suppressed mails */
+        else if (((mailtosend < mail->maxperhour) && (mailtosend != 0)) ||
+                 ((p->tm_hour != thishour) && (childcount < MAXCHILDPROCESS))) {
             MailNode *mailmsg;
             pid_t pid;
 
-            /* Checking if we have anything to sent */
+            /* Check if we have anything to send */
             mailmsg = OS_CheckLastMail();
-            if(mailmsg == NULL)
-            {
-                /* dont fork in here */
+            if (mailmsg == NULL) {
+                /* Don't fork in here */
                 goto snd_check_hour;
             }
 
+            fflush(fileq->fp);
             pid = fork();
-            if(pid < 0)
-            {
-                merror("%s: Fork failed. cause: %d - %s", ARGV0, errno, strerror(errno));
-                merror(FORK_ERROR, ARGV0);
+            if (pid < 0) {
+                merror(FORK_ERROR, ARGV0, errno, strerror(errno));
                 sleep(30);
                 continue;
-            }
-            else if (pid == 0)
-            {
-                if(OS_Sendmail(mail, p) < 0)
-                    merror(SNDMAIL_ERROR,ARGV0,mail->smtpserver);
+            } else if (pid == 0) {
+                if (OS_Sendmail(mail, p) < 0) {
+                    merror(SNDMAIL_ERROR, ARGV0, mail->smtpserver);
+                }
 
                 exit(0);
             }
 
-            /* Cleaning the memory */
+            /* Clean the memory */
             mailmsg = OS_PopLastMail();
-            do
-            {
+            do {
                 FreeMail(mailmsg);
                 mailmsg = OS_PopLastMail();
-            }while(mailmsg);
-
+            } while (mailmsg);
 
-            /* Increasing child count */
+            /* Increase child count */
             childcount++;
 
-
-            /* Clearing global vars */
+            /* Clear global variables */
             _g_subject[0] = '\0';
-            _g_subject[SUBJECT_SIZE -1] = '\0';
+            _g_subject[SUBJECT_SIZE - 1] = '\0';
             _g_subject_level = 0;
 
-
-            /* Cleaning up set values */
-            if(mail->gran_to)
-            {
+            /* Clean up set values */
+            if (mail->gran_to) {
                 i = 0;
-                while(mail->gran_to[i] != NULL)
-                {
-                    if(s_msg && mail->gran_set[i] == DONOTGROUP)
-                    {
+                while (mail->gran_to[i] != NULL) {
+                    if (s_msg && mail->gran_set[i] == DONOTGROUP) {
                         mail->gran_set[i] = FULL_FORMAT;
-                    }
-                    else
-                    {
+                    } else {
                         mail->gran_set[i] = 0;
                     }
                     i++;
                 }
             }
 
-            snd_check_hour:
+snd_check_hour:
             /* If we sent everything */
-            if(p->tm_hour != thishour)
-            {
+            if (p->tm_hour != thishour) {
                 thishour = p->tm_hour;
 
                 mailtosend = 0;
             }
         }
 
-        /* Saved message for the do_not_group option.
-         */
-        if(s_msg)
-        {
-            /* We need to set the remaining do no group to
-             * full format.
-             */
-            if(mail->gran_to)
-            {
+        /* Saved message for the do_not_group option */
+        if (s_msg) {
+            /* Set the remaining do no group to full format */
+            if (mail->gran_to) {
                 i = 0;
-                while(mail->gran_to[i] != NULL)
-                {
-                    if(mail->gran_set[i] == DONOTGROUP)
-                    {
+                while (mail->gran_to[i] != NULL) {
+                    if (mail->gran_set[i] == DONOTGROUP) {
                         mail->gran_set[i] = FULL_FORMAT;
                     }
                     i++;
@@ -381,57 +329,38 @@ void OS_Run(MailConfig *mail)
             continue;
         }
 
-
         /* Receive message from queue */
-        if((msg = OS_RecvMailQ(fileq, p, mail, &msg_sms)) != NULL)
-        {
-            /* If the e-mail priority is do_not_group, we first will
+        if ((msg = OS_RecvMailQ(fileq, p, mail, &msg_sms)) != NULL) {
+            /* If the e-mail priority is do_not_group,
              * flush all previous entries and then send it.
-             * We use s_msg to hold the pointer to the message
-             * while we flush it.
+             * Use s_msg to hold the pointer to the message while we flush it.
              */
-            if(mail->priority == DONOTGROUP)
-            {
+            if (mail->priority == DONOTGROUP) {
                 s_msg = msg;
-            }
-            else
-            {
+            } else {
                 OS_AddMailtoList(msg);
             }
 
-
             /* Change timeout to see if any new message is coming shortly */
-            if(mail->groupping)
-            {
+            if (mail->groupping) {
                 /* If priority is set, send email now */
-                if(mail->priority)
-                {
+                if (mail->priority) {
                     mail_timeout = DEFAULT_TIMEOUT;
 
-                    /* If do_not_group is set, we do not increase the
-                     * list count in here.
-                     */
-                    if(mail->priority != DONOTGROUP)
-                    {
+                    /* If do_not_group is set, we do not increase the list count */
+                    if (mail->priority != DONOTGROUP) {
                         mailtosend++;
                     }
-                }
-                else
-                {
+                } else {
                     /* 5 seconds only */
                     mail_timeout = NEXTMAIL_TIMEOUT;
                 }
-            }
-            else
-            {
+            } else {
                 /* Send message by itself */
                 mailtosend++;
             }
-        }
-        else
-        {
-            if(mail_timeout == NEXTMAIL_TIMEOUT)
-            {
+        } else {
+            if (mail_timeout == NEXTMAIL_TIMEOUT) {
                 mailtosend++;
 
                 /* Default timeout */
@@ -439,38 +368,32 @@ void OS_Run(MailConfig *mail)
             }
         }
 
-
-        /* Waiting for the childs .. */
-        while (childcount)
-        {
+        /* Wait for the children */
+        while (childcount) {
             int wp;
             int p_status;
-            wp = waitpid((pid_t) -1, &p_status, WNOHANG);
-            if (wp < 0)
-            {
-                merror(WAITPID_ERROR, ARGV0);
+            wp = waitpid((pid_t) - 1, &p_status, WNOHANG);
+            if (wp < 0) {
+                merror(WAITPID_ERROR, ARGV0, errno, strerror(errno));
                 n_errs++;
             }
 
             /* if = 0, we still need to wait for the child process */
-            else if (wp == 0)
+            else if (wp == 0) {
                 break;
-            else
-            {
-                if(p_status != 0)
-                {
-                    merror(CHLDWAIT_ERROR,ARGV0,p_status);
-                    merror(SNDMAIL_ERROR,ARGV0,mail->smtpserver);
+            } else {
+                if (p_status != 0) {
+                    merror(CHLDWAIT_ERROR, ARGV0, p_status);
+                    merror(SNDMAIL_ERROR, ARGV0, mail->smtpserver);
                     n_errs++;
                 }
                 childcount--;
             }
 
             /* Too many errors */
-            if(n_errs > 6)
-            {
-                merror(TOOMANY_WAIT_ERROR,ARGV0);
-                merror(SNDMAIL_ERROR,ARGV0,mail->smtpserver);
+            if (n_errs > 6) {
+                merror(TOOMANY_WAIT_ERROR, ARGV0);
+                merror(SNDMAIL_ERROR, ARGV0, mail->smtpserver);
                 exit(1);
             }
         }
@@ -478,4 +401,3 @@ void OS_Run(MailConfig *mail)
     }
 }
 
-/* EOF */