source: trunk/src/sh_err_console.c@ 245

Last change on this file since 245 was 170, checked in by katerina, 17 years ago

Plenty of compiler warnings fixed, SQL query length fixed, doc update.

File size: 9.3 KB
RevLine 
[1]1/* SAMHAIN file system integrity testing */
2/* Copyright (C) 2000 Rainer Wichmann */
3/* */
4/* This program is free software; you can redistribute it */
5/* and/or modify */
6/* it under the terms of the GNU General Public License as */
7/* published by */
8/* the Free Software Foundation; either version 2 of the License, or */
9/* (at your option) any later version. */
10/* */
11/* This program is distributed in the hope that it will be useful, */
12/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
13/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
14/* GNU General Public License for more details. */
15/* */
16/* You should have received a copy of the GNU General Public License */
17/* along with this program; if not, write to the Free Software */
18/* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20#include "config_xor.h"
21
22#include <string.h>
23
24#include "samhain.h"
25#include "sh_error.h"
26#include "sh_utils.h"
27
28#undef FIL__
29#define FIL__ _("sh_err_console.c")
30
31#include <stdio.h>
32#include <sys/types.h>
33#include <fcntl.h>
34#include <unistd.h>
35#include <signal.h>
36
37extern int OnlyStderr;
38
39
40#if !defined(O_NONBLOCK)
41#if defined(O_NDELAY)
42#define O_NONBLOCK O_NDELAY
43#else
44#define O_NONBLOCK 0
45#endif
46#endif
47
48#if defined(WITH_MESSAGE_QUEUE)
49
50#if defined(HAVE_SYS_MSG_H)
51
52#include <sys/ipc.h>
53#include <sys/msg.h>
54
55struct sh_msgbuf {
56 long mtype;
57 char mtext[1]; /* <-- sizeof(mtext) will be 1+MY_MAX_MSG */
58};
59
60static int msgq_enabled = S_FALSE;
61
62/* The identifier of the message queue
63 */
64static int msgid = -1;
65
66/* Open the SysV message queue, creating it when neccesary
67 */
68static int open_ipc(void)
69{
70 key_t key;
71 int error;
[137]72#if defined(WITH_TPT)
[132]73 char errbuf[SH_ERRBUF_SIZE];
[137]74#endif
[1]75
76 SL_ENTER(_("open_ipc"));
77
78 /* get key
79 */
80 key = ftok ("/tmp", '#');
81 if (key == (key_t) -1)
82 {
83 error = errno;
84 TPT(( 0, FIL__, __LINE__, _("msg=<ftok: %s> errno=<%d>\n"),
[132]85 sh_error_message(error, errbuf, sizeof(errbuf)), error));
[1]86 SL_RETURN(-1, _("open_ipc"));
87 }
88
89 /* get message identifier
90 */
91 msgid = msgget (key, IPC_CREAT|MESSAGE_QUEUE_MODE);
92
93 if (msgid < 0)
94 {
95 error = errno;
96 TPT(( 0, FIL__, __LINE__, _("msg=<msgget: %s> errno=<%d>\n"),
[132]97 sh_error_message(error, errbuf, sizeof(errbuf)), error));
[1]98 SL_RETURN(-1, _("open_ipc"));
99 }
100
101 SL_RETURN(0, _("open_ipc"));
102}
103
104/* Close the SysV message queue
105 */
106void close_ipc (void)
107{
108 SL_ENTER(_("close_ipc"));
109
110 if (msgid != (-1))
111 (void) msgctl (msgid, IPC_RMID, NULL);
112 SL_RET0(_("close_ipc"));
113}
114
115/* Enable the message queue
116 */
[22]117int enable_msgq(const char * foo)
[1]118{
119 int i;
120
121 SL_ENTER(_("enable_msgq"));
122 i = sh_util_flagval(foo, &msgq_enabled);
123 SL_RETURN(i, _("enable_msgq"));
124}
125
126/* #define MY_MAX_MSG 254 */
127#define MY_MAX_MSG 1022
128
[170]129static int push_message_queue (const char * msg)
[1]130{
131 struct sh_msgbuf* recv_msg = NULL;
132 int rc = -1;
133 static int status = -1;
134 int error;
135 int count = 0;
[137]136#if defined(WITH_TPT)
[132]137 char errbuf[SH_ERRBUF_SIZE];
[137]138#endif
[1]139
140 SL_ENTER(_("push_message_queue"));
141
142 if (msgq_enabled == -1)
143 {
144 TPT(( 0, FIL__, __LINE__, _("msg=<msg_queue not enabled>\n")));
145 SL_RETURN(0, _("push_message_queue"));
146 }
147
148 if (status < 0)
149 {
150 TPT(( 0, FIL__, __LINE__, _("msg=<msg_queue not open>\n")));
151 status = open_ipc();
152 }
153
154 if (status < 0)
155 {
156 TPT(( 0, FIL__, __LINE__, _("msg=<open_ipc() failed>\n")));
157 SL_RETURN(-1, _("push_message_queue"));
158 }
159
160 /* struct msgbuf {
161 * long mtype;
162 * char mtext[1]; <-- sizeof(mtext) will be 1+MY_MAX_MSG
163 * }
164 */
165 recv_msg = (struct sh_msgbuf*) SH_ALLOC(sizeof(struct sh_msgbuf)+MY_MAX_MSG);
166 recv_msg->mtype = 1;
167 sl_strlcpy (recv_msg->mtext, msg, MY_MAX_MSG+1);
168
169 count = 0;
170
171 send_it:
172
173 if (count > 1)
174 {
175 SH_FREE(recv_msg);
176 SL_RETURN(-1, _("push_message_queue"));
177 }
178
179 /* send the message
180 */
181 do {
182 errno = 0;
183 rc = msgsnd(msgid, recv_msg, strlen(recv_msg->mtext)+1, IPC_NOWAIT);
184 }
185 while (rc < 0 && errno == EINTR);
186
187 if (rc == -1 && errno != EAGAIN)
188 {
189 /* EIDRM is not in OpenBSD
190 */
191 if (errno == EINVAL
192#if defined(EIDRM)
193 || errno == EIDRM
194#endif
195 )
196 {
197 TPT(( 0, FIL__, __LINE__, _("msg=<msg_queue not open>\n")));
198 status = open_ipc();
199 if (status == 0)
200 {
201 ++count;
202 goto send_it;
203 }
204 }
205 else
206 {
207 error = errno;
208 TPT(( 0, FIL__, __LINE__, _("msg=<msgsnd: %s> errno=<%d>\n"),
[132]209 sh_error_message(error, errbuf, sizeof(errbuf)), error));
[1]210 SH_FREE(recv_msg);
211 SL_RETURN(-1, _("push_message_queue"));
212 }
213 }
214
215 SH_FREE(recv_msg);
216 SL_RETURN(0, _("push_message_queue"));
217}
218/* if defined(HAVE_SYS_MSG_H) */
219#else
220
221#error **********************************************
222#error
223#error The sys/msg.h header was not found,
224#error cannot compile with --enable-message-queue
225#error
226#error **********************************************
227
228#endif
229
230#endif
231
232static int count_dev_console = 0;
233
234void reset_count_dev_console(void)
235{
236 count_dev_console = 0;
237 return;
238}
239
240/* ---- Set the console device. ----
241 */
[22]242int sh_log_set_console (const char * address)
[1]243{
244 SL_ENTER(_("sh_log_set_console"));
245 if (address != NULL && count_dev_console < 2
246 && sl_strlen(address) < SH_PATHBUF)
247 {
248 if (count_dev_console == 0)
249 (void) sl_strlcpy (sh.srvcons.name, address, SH_PATHBUF);
250 else
251 (void) sl_strlcpy (sh.srvcons.alt, address, SH_PATHBUF);
252
253 ++count_dev_console;
254 SL_RETURN(0, _("sh_log_set_console"));
255 }
256 SL_RETURN((-1), _("sh_log_set_console"));
257}
258
259#if defined(WITH_TRACE) || defined(WITH_TPT)
[170]260char * sh_log_console_name (void)
[1]261{
262 if (! sh.srvcons.name || sh.srvcons.name[0] == '\0' ||
263 0 == strcmp(sh.srvcons.name, _("NULL")))
264 return (_("/dev/console"));
265 return sh.srvcons.name;
266}
267#endif
268
269#ifndef STDERR_FILENO
270#define STDERR_FILENO 2
271#endif
272
273/* ---- Print out a message. ----
274 */
[170]275int sh_log_console (const /*@null@*/char *errmsg)
[1]276{
277 static int service_failure[2] = { 0, 0};
278 int fd[2] = { -1, -1};
279 int sflags;
280 int cc;
281 size_t len;
282 int ccMax = 1;
283 int retval = -1;
284 /* static int logkey_seen = 0; */
285 int error;
286 struct sigaction sa_new, sa_old;
287 static int blockMe = 0;
[153]288 int val_return;
[1]289
290 SL_ENTER(_("sh_log_console"));
291
292 if (errmsg == NULL || blockMe == 1)
293 {
294 SL_RETURN(0, _("sh_log_console"));
295 }
296 else
297 blockMe = 1;
298
299
300#ifdef WITH_MESSAGE_QUEUE
301 if (0 != push_message_queue (errmsg))
302 {
303 TPT(( 0, FIL__, __LINE__, _("msg=<push_message_queue() failed>\n")));
304 }
305#endif
306
307 sa_new.sa_handler = SIG_IGN;
308 (void) sigemptyset(&sa_new.sa_mask);
309 sa_new.sa_flags = 0;
310
311 /* Ignore SIGPIPE in case the console is actually a pipe.
312 */
313 (void) retry_sigaction(FIL__, __LINE__, SIGPIPE, &sa_new, &sa_old);
314
315 if (sh.flag.isdaemon == S_FALSE || OnlyStderr == S_TRUE)
316 {
317 len = strlen(errmsg);
[153]318 do {
319 val_return = write(STDERR_FILENO, errmsg, len);
320 } while (val_return < 0 && errno == EINTR);
321 do {
322 val_return = write(STDERR_FILENO, "\n", 1);
323 } while (val_return < 0 && errno == EINTR);
[1]324 /*
325 * fprintf (stderr, "%s\n", errmsg);
326 */
327 (void) retry_sigaction(FIL__, __LINE__, SIGPIPE, &sa_old, NULL);
328 blockMe = 0;
329 SL_RETURN(0, _("sh_log_console"));
330 }
331
332 /* --- daemon && initialized ---
333 */
334 if ( (OnlyStderr == S_FALSE) )
335 {
336 fd[0] = open ( sh.srvcons.name, O_WRONLY|O_APPEND|O_NOCTTY|O_NONBLOCK);
337 if (fd[0] >= 0) {
338 sflags = (int) retry_fcntl(FIL__, __LINE__, fd[0], F_GETFL, 0);
339 if (sflags >= 0)
340 {
341 (void) retry_fcntl(FIL__, __LINE__, fd[0],
342 F_SETFL, sflags & ~O_NONBLOCK);
343 }
344 }
345
346 if (sh.srvcons.alt != NULL && sh.srvcons.alt[0] != '\0')
347 {
348 fd[1] = open (sh.srvcons.alt, O_WRONLY|O_APPEND|O_NOCTTY|O_NONBLOCK);
349 if (fd[1] >= 0) {
350 sflags = (int) retry_fcntl(FIL__, __LINE__, fd[1], F_GETFL, 0);
351 if (sflags >= 0)
352 {
353 (void) retry_fcntl(FIL__, __LINE__, fd[1],
354 F_SETFL, sflags & ~O_NONBLOCK);
355 }
356 ccMax = 2;
357 }
358 }
359
360 for (cc = 0; cc < ccMax; ++cc)
361 {
362
363 if (fd[cc] < 0 && service_failure[cc] == 0)
364 {
365 error = errno;
366 sh_error_handle ((-1), FIL__, __LINE__, error, MSG_SRV_FAIL,
367 _("console"),
368 (cc == 0) ? sh.srvcons.name : sh.srvcons.alt);
369 service_failure[cc] = 1;
370 }
371
372 if (fd[cc] >= 0)
373 {
[153]374 do {
375 val_return = write(fd[cc], errmsg, strlen(errmsg));
376 } while (val_return < 0 && errno == EINTR);
377 do {
378 val_return = write(fd[cc], "\r\n", 2);
379 } while (val_return < 0 && errno == EINTR);
[1]380 (void) close(fd[cc]);
381 service_failure[cc] = 0;
382 }
383 }
384 }
385 else
386 retval = 0;
387
388 (void) retry_sigaction(FIL__, __LINE__, SIGPIPE, &sa_old, NULL);
389 blockMe = 0;
390 SL_RETURN(retval, _("sh_log_console"));
391}
392
393
Note: See TracBrowser for help on using the repository browser.