root/psad/tags/psad-2.1.1/psad_funcs.c

Revision 2112, 8.7 kB (checked in by mbr, 1 year ago)

minor comment fix

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /*
2 ********************************************************************************
3 *
4 *  File: psad_funcs.c
5 *
6 *  Purpose: psad_funcs.c contains several functions that are needed by
7 *           the all of the psad daemons, so putting these functions in
8 *           a single file make sense.
9 *
10 *  Author: Michael Rash (mbr@cipherdyne.org)
11 *
12 *  Credits:  (see the CREDITS file)
13 *
14 *  Copyright (C) 1999-2002 Michael Rash (mbr@cipherdyne.org)
15 *
16 *  License (GNU Public License):
17 *
18 *     This program is distributed in the hope that it will be useful,
19 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
20 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 *     GNU General Public License for more details.
22 *
23 *     You should have received a copy of the GNU General Public License
24 *     along with this program; if not, write to the Free Software
25 *     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
26 *     USA
27 *
28 ********************************************************************************
29 *
30 *  $Id$
31 */
32
33 /* includes */
34 #include "psad.h"
35
36 /* shared functions */
37 void slogr(const char *ident, const char *msg) {
38     openlog(ident, LOG_DAEMON, LOG_LOCAL7);
39     syslog(LOG_INFO, "%s", msg);
40     closelog();
41     return;
42 }
43
44 void check_unique_pid(const char *pid_file, const char *prog_name)
45 {
46     FILE *pidfile_ptr;
47     pid_t pid;
48     char pid_line[MAX_PID_SIZE+1];
49
50 #ifdef DEBUG
51     fprintf(stderr,
52         "[+] check_unique_pid(): opening pid file %s\n", pid_file);
53 #endif
54
55     if ((pidfile_ptr = fopen(pid_file, "r")) == NULL) {
56         /* the pid file must not exist (or we can't read it), so
57          * return... write_pid() will create it */
58         return;
59     }
60
61     /* read the first line of the pid_file, which will contain the
62      * process id of any running kmsgsd process */
63     if (fgets(pid_line, MAX_PID_SIZE+1, pidfile_ptr) == NULL) {
64         return;
65     }
66
67     /* turn the pid_line into an integer */
68     pid = atoi(pid_line);
69
70     /* close the pid_file now that we have read it */
71     fclose(pidfile_ptr);
72
73 #ifdef DEBUG
74     fprintf(stderr,
75         "[+] check_unique_pid(): checking pid: %d with kill 0\n", pid);
76 #endif
77
78     if (kill(pid, 0) == 0) {  /* another prog_name is already running */
79         fprintf(stderr, "[*] %s is already running as pid: %d\n",
80             prog_name, pid);
81         exit(EXIT_FAILURE);
82     } else {
83         return;
84     }
85
86     return; /* for completness */
87 }
88
89 void write_pid(const char *pid_file, const pid_t pid)
90 {
91     FILE *pidfile_ptr;
92
93     if ((pidfile_ptr = fopen(pid_file, "w")) == NULL) {
94         /* could not open the pid file */
95         fprintf(stderr, "[*] Could not open the pid file: %s", pid_file);
96         exit(EXIT_FAILURE);
97     }
98
99     /* write the pid to the pid file */
100     if (fprintf(pidfile_ptr, "%d\n", pid) == 0) {
101         fprintf(stderr, "[*] pid: %d could not be written to pid file: %s",
102                 pid, pid_file);
103         exit(EXIT_FAILURE);
104     }
105
106     /* the pid_file now that we have read it */
107     fclose(pidfile_ptr);
108
109     return;
110 }
111
112 int find_char_var(const char *search_str, char *charvar, char *line)
113 {
114     char *index_tmp;
115     int char_ctr = 0, i;
116
117     index_tmp = line;
118
119     /* look for specific variables in the config
120      * file that match the search_str */
121     for (i=0; i < strlen(search_str); i++)
122         if (index_tmp[i] != search_str[i])
123             return 0;
124
125     /* require trailing space char */
126     if (index_tmp[i] != ' ')
127         return 0;
128
129 #ifdef DEBUG
130     fprintf(stderr, "[+] find_char_var(): found %s in line: %s",
131             search_str, line);
132 #endif
133
134     /* increment the pointer past the variable name */
135     while (*index_tmp != ' ') index_tmp++;
136
137     /* increment the pointer past the whitespace
138      * before the variable value */
139     while (*index_tmp == ' ') index_tmp++;
140
141     /* make sure that the variable has a semicolon
142      * at the end of the line */
143
144     /* get the number of characters in the variable
145      * before the ending semicolon */
146     while (index_tmp[char_ctr] != ';' && index_tmp[char_ctr] != '\0' &&
147            index_tmp[char_ctr] != '\n')
148         char_ctr++;
149
150     if (index_tmp[char_ctr] != ';') {
151         fprintf(stderr,
152             "[*] find_char_var(): No ending semicolon found for: %s.\n",
153             search_str);
154         exit(EXIT_FAILURE);
155     }
156
157     if (char_ctr > MAX_GEN_LEN-1) {
158         fprintf(stderr,
159                 "[*] find_char_var(): the config line for %s is too long.  Exiting.\n",
160                 search_str);
161         exit(EXIT_FAILURE);
162     }
163
164     strncpy(charvar, index_tmp, char_ctr);
165     charvar[char_ctr] = '\0'/* replace the ';' with the NULL character */
166     return 1;
167 }
168
169 void *safe_malloc(const unsigned int len)
170 {
171     void *buf = NULL;
172     buf = malloc(len);
173     if (buf == NULL) {
174         fprintf(stderr, "[*] Could not malloc() %d bytes\n", len);
175         exit(EXIT_FAILURE);
176     }
177     return buf;
178 }
179
180 int has_sub_var(char *var_name, char *value, char *sub_var,
181     char *pre_str, char *post_str)
182 {
183     unsigned int i, sub_var_ctr = 0, found_sub_var = 0;
184     unsigned int pre_str_ctr = 0, found_pre_str = 1;
185     unsigned int post_str_ctr = 0, found_post_str = 0;
186     unsigned int found_one_var = 0;
187
188     sub_var[0]  = '\0';
189     pre_str[0]  = '\0';
190     post_str[0] = '\0';
191
192     for (i=0; i < strlen(value); i++) {
193         if (found_sub_var) {
194             if (! isdigit(value[i])
195                     && ! isalpha(value[i]) && value[i] != '_') {
196                 found_sub_var  = 0;
197                 found_post_str = 1;
198                 found_one_var  = 1;
199             } else {
200                 if (! found_one_var) {
201                     sub_var[sub_var_ctr] = value[i];
202                     sub_var_ctr++;
203                 }
204             }
205         }
206
207         if (found_pre_str && value[i] != '$') {
208             pre_str[pre_str_ctr] = value[i];
209             pre_str_ctr++;
210         }
211
212         if (found_post_str) {
213             post_str[post_str_ctr] = value[i];
214             post_str_ctr++;
215         }
216
217         if (value[i] == '$') {
218             found_sub_var = 1;
219             found_pre_str = 0;
220             pre_str[pre_str_ctr] = '\0';
221         }
222     }
223     if (sub_var_ctr >= MAX_GEN_LEN - 1) {
224         printf("[*] Sub-var length exceeds maximum of %d chars within var: %s\n",
225                 MAX_GEN_LEN, var_name);
226         exit(EXIT_FAILURE);
227     }
228     if (sub_var[0] != '\0') {
229         sub_var[sub_var_ctr]   = '\0';
230         post_str[post_str_ctr] = '\0';
231         if (strncmp(sub_var, var_name, MAX_GEN_LEN) == 0) {
232             printf("[*] Cannot have identical var to sub-var: %s\n",
233                     sub_var);
234             exit(EXIT_FAILURE);
235         }
236         return 1;
237     }
238
239     return 0;
240 }
241
242 void expand_sub_var_value(char *value, const char *sub_var,
243     const char *pre_str, const char *post_str)
244 {
245     if (strlen(sub_var) + strlen(pre_str) + strlen(post_str)
246             > MAX_GEN_LEN) {
247         printf("[*] Variable value too long: %s%s%s\n",
248             sub_var, pre_str, post_str);
249         exit(EXIT_FAILURE);
250     }
251     strlcpy(value, pre_str, MAX_GEN_LEN);
252     strlcat(value, sub_var, MAX_GEN_LEN);
253     strlcat(value, post_str, MAX_GEN_LEN);
254     return;
255 }
256
257 /*
258  * Do everything required to cleanly become a daemon: fork(), start
259  * a new session, chdir "/", and close un-needed standard filehandles.
260  */
261 void daemonize_process(const char *pid_file)
262 {
263     pid_t child_pid, sid;
264
265     if ((child_pid = fork()) < 0) {
266         fprintf(stderr, "[*] Could not fork()");
267         exit(EXIT_FAILURE);
268     }
269
270     if (child_pid > 0) {
271 #ifdef DEBUG
272         fprintf(stderr, "[+] writing pid: %d to pid file: %s\n",
273                 child_pid, pid_file);
274 #endif
275         write_pid(pid_file, child_pid);
276         exit(EXIT_SUCCESS);   /* exit the parent process */
277     }
278
279     /*
280      * Now we are in the child process
281      */
282
283     /* start a new session */
284     if ((sid = setsid()) < 0) {
285         fprintf(stderr, "[*] setsid() Could not start a new session");
286         exit(EXIT_FAILURE);
287     }
288
289     /* make "/" the current directory */
290     if ((chdir("/")) < 0) {
291         fprintf(stderr, "[*] Could not chdir() to /");
292         exit(EXIT_FAILURE);
293     }
294
295     /* reset the our umask (for completeness) */
296     umask(0);
297
298     /* close un-needed file handles */
299     close(STDIN_FILENO);
300     close(STDOUT_FILENO);
301     close(STDERR_FILENO);
302
303     return;
304 }
305
306 void send_alert_email(const char *shCmd, const char *mailCmd,
307         const char *mail_str)
308 {
309     char mail_line[MAX_MSG_LEN] = "";
310     pid_t child_pid;
311
312     strlcat(mail_line, mailCmd, MAX_MSG_LEN);
313     strlcat(mail_line, " ", MAX_MSG_LEN);
314     strlcat(mail_line, mail_str, MAX_MSG_LEN);
315     if ((child_pid = fork()) < 0)
316         /* could not fork */
317         exit(EXIT_FAILURE);
318     else if (child_pid > 0)
319         wait(NULL);  /* mail better work */
320     else
321         execle(shCmd, shCmd, "-c", mail_line, NULL, NULL);  /* don't use env */
322     return;
323 }
Note: See TracBrowser for help on using the browser.