Imported Upstream version 2.4.3
[platform/upstream/audit.git] / src / auditd-sendmail.c
1 /* auditd-sendmail.c --
2  * Copyright 2005 Red Hat Inc., Durham, North Carolina.
3  * All Rights Reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  * Authors:
20  *   Steve Grubb <sgrubb@redhat.com>
21  *
22  */
23
24 #include "config.h"
25 #include <stdio.h>
26 #include <unistd.h>             // for access()
27 #include <string.h>
28 #include <stdlib.h>
29 #include <signal.h>
30 #include "libaudit.h"
31 #include "private.h"
32 #include "auditd-config.h"
33
34 extern const char *email_command;
35 static int safe_popen(pid_t *pid, const char *mail_acct);
36
37 // returns 1 on error & 0 if OK
38 int sendmail(const char *subject, const char *content, const char *mail_acct)
39 {
40         pid_t pid;
41
42         if (access(email_command, 01) == 0)
43         {       
44                 FILE *mail;
45                 int fd;
46
47                 fd = safe_popen(&pid, mail_acct);
48                 if (fd < 0) 
49                         return 1;
50                 mail = fdopen(fd, "w");
51                 if (mail == NULL) {
52                         kill(pid, SIGKILL);
53                         close(fd);
54                         audit_msg(LOG_ERR, "Error - starting mail"); 
55                         return 1;
56                 }
57
58                 fprintf(mail, "To: %s\n", mail_acct);
59                 fprintf(mail, "From: root\n");
60 //              fprintf(mail, "X-Sender: %s\n", mail_acct);
61                 fprintf(mail, "Subject: %s\n\n", subject); // End of Header
62                 fprintf(mail, "%s\n", content);
63                 fprintf(mail, ".\n\n");         // Close it up...
64                 fclose(mail);
65                 return 0;
66         } else
67                 audit_msg(LOG_ERR, "Error - %s isn't executable",
68                         email_command); 
69         return 1;       
70 }
71
72 static int safe_popen(pid_t *pid, const char *mail_acct)
73 {
74         char *argv[4];
75         char acct[256];
76         int pipe_fd[2];
77         struct sigaction sa;
78
79         if (pipe(pipe_fd)) {
80                 audit_msg(LOG_ALERT,
81                 "Audit daemon failed to create pipe while sending email alert");
82                 return -1;
83         }
84
85         *pid = fork();
86         if (*pid < 0) {
87                 close(pipe_fd[0]);
88                 close(pipe_fd[1]);
89                 audit_msg(LOG_ALERT,
90                     "Audit daemon failed to fork while sending email alert");
91                 return -1;
92         }
93         if (*pid) {       /* Parent */
94                 close(pipe_fd[0]);      // adjust pipe
95                 return pipe_fd[1];
96         }
97         /* Child */
98         sigfillset (&sa.sa_mask);
99         sigprocmask (SIG_UNBLOCK, &sa.sa_mask, 0);
100
101         close(pipe_fd[1]);      // adjust pipe
102         dup2(pipe_fd[0], 0);
103
104         /* Make email acct param */
105         snprintf(acct, sizeof(acct), "-f%s", mail_acct);
106
107         /* Stuff arg list */
108         argv[0] = (char *)email_command;
109         argv[1] = (char *)"-t";
110         argv[2] = acct;
111         argv[3] = NULL;
112         execve(email_command, argv, NULL);
113         audit_msg(LOG_ALERT, "Audit daemon failed to exec %s", email_command);
114         exit(1);
115 }
116