source: branches/samhain-2_2-branch/src/sh_calls.c@ 440

Last change on this file since 440 was 22, checked in by rainer, 19 years ago

Minor code revisions.

File size: 18.2 KB
Line 
1/* SAMHAIN file system integrity testing */
2/* Copyright (C) 1999 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#ifdef HOST_IS_HPUX
23#define _XOPEN_SOURCE_EXTENDED
24#endif
25
26#include <stdlib.h>
27#include <string.h>
28#include <errno.h>
29
30#include <sys/types.h>
31#include <unistd.h>
32#include <sys/stat.h>
33#include <fcntl.h>
34#include <signal.h>
35#include <sys/socket.h>
36#include <netinet/in.h>
37
38#ifndef S_SPLINT_S
39#include <arpa/inet.h>
40#else
41#define AF_INET 2
42#endif
43
44#include <time.h>
45
46#ifndef HAVE_LSTAT
47#define lstat stat
48#endif
49
50#include "samhain.h"
51#include "sh_error.h"
52#include "sh_calls.h"
53
54#undef FIL__
55#define FIL__ _("sh_calls.c")
56
57char aud_err_message[64];
58
59typedef struct cht_struct
60{
61 char * str;
62 unsigned long val;
63} cht_type;
64
65static cht_type aud_tab[] =
66{
67 { N_("execve"), AUD_EXEC },
68 { N_("utime"), AUD_UTIME },
69 { N_("unlink"), AUD_UNLINK },
70 { N_("dup"), AUD_DUP },
71 { N_("chdir"), AUD_CHDIR },
72 { N_("open"), AUD_OPEN },
73 { N_("kill"), AUD_KILL },
74 { N_("exit"), AUD_EXIT },
75 { N_("fork"), AUD_FORK },
76 { N_("setuid"), AUD_SETUID },
77 { N_("setgid"), AUD_SETGID },
78 { N_("pipe"), AUD_PIPE },
79 { NULL, 0 }
80};
81
82/* Set aud functions
83 */
84int sh_aud_set_functions(const char * str_s)
85{
86 int i = 0;
87
88 SL_ENTER(_("sh_aud_set_functions"));
89
90 if (str_s == NULL)
91 return -1;
92
93 while (aud_tab[i].str != NULL)
94 {
95 if (NULL != sl_strstr (str_s, _(aud_tab[i].str)))
96 {
97 sh.flag.audit = 1;
98 sh.flag.aud_mask |= aud_tab[i].val;
99 }
100 ++i;
101 }
102
103 SL_RETURN(0,_("sh_aud_set_functions"));
104}
105
106
107
108
109/* Need to catch EINTR for these functions.
110 */
111long int retry_sigaction(char * file, int line,
112 int signum, const struct sigaction *act,
113 struct sigaction *oldact)
114{
115 int error;
116 long int val_retry = -1;
117 errno = 0;
118
119 SL_ENTER(_("retry_sigaction"));
120
121 do {
122 val_retry = sigaction(signum, act, oldact);
123 } while (val_retry < 0 && errno == EINTR);
124
125 error = errno;
126 if (val_retry < 0) {
127 sh_error_handle ((-1), file, line, error, MSG_ERR_SIGACT,
128 sh_error_message(error),
129 (long) signum );
130 }
131 errno = error;
132 SL_RETURN(val_retry, _("retry_sigaction"));
133}
134
135static struct in_addr bind_addr;
136static int use_bind_addr = 0;
137
138int sh_calls_set_bind_addr (const char * str)
139{
140 static int reject = 0;
141
142 if (reject == 1)
143 return (0);
144
145 if (sh.flag.opts == S_TRUE)
146 reject = 1;
147
148 if (0 == /*@-unrecog@*/inet_aton(str, &bind_addr)/*@+unrecog@*/)
149 {
150 return -1;
151 }
152 use_bind_addr = 1;
153 return 0;
154}
155
156
157long int retry_connect(char * file, int line, int sockfd,
158 struct sockaddr *serv_addr, int addrlen)
159{
160 int error;
161 long int val_retry = 0;
162 static struct sockaddr_in new_addr;
163
164 SL_ENTER(_("retry_connect"));
165
166 errno = 0;
167
168 if (0 != use_bind_addr)
169 {
170 memcpy(&new_addr.sin_addr, &bind_addr, sizeof(struct in_addr));
171 new_addr.sin_family = AF_INET;
172
173 val_retry = /*@-unrecog@*/bind(sockfd,
174 (struct sockaddr*)&new_addr,
175 sizeof(struct sockaddr_in))/*@+unrecog@*/;
176 }
177
178 if (val_retry == 0)
179 {
180 do {
181 val_retry =
182 /*@-unrecog@*/connect(sockfd, serv_addr, addrlen)/*@+unrecog@*/;
183 } while (val_retry < 0 && errno == EINTR);
184 }
185
186 error = errno;
187 if (val_retry != 0) {
188 /* ugly cast back to struct sockaddr_in :-(
189 */
190 sh_error_handle ((-1), file, line, error, MSG_ERR_CONNECT,
191 sh_error_message(error),
192 (long) sockfd,
193 /*@-unrecog -type@*/
194 (long) ntohs(((struct sockaddr_in *)serv_addr)->sin_port),
195 /*@+unrecog +type@*/
196#ifdef HAVE_INET_ATON
197 /*@-unrecog -type@*/
198 inet_ntoa( ((struct sockaddr_in *)serv_addr)->sin_addr )
199 /*@+unrecog +type@*/
200#else
201 _("unknown")
202#endif
203 );
204 }
205 errno = error;
206 SL_RETURN(val_retry, _("retry_connect"));
207}
208
209long int retry_accept(char * file, int line, int fd,
210 struct sockaddr *serv_addr, int * addrlen)
211{
212 int error;
213 long int val_retry = -1;
214 ACCEPT_TYPE_ARG3 my_addrlen = (ACCEPT_TYPE_ARG3) *addrlen;
215
216 errno = 0;
217
218 SL_ENTER(_("retry_accept"));
219
220 do {
221 val_retry = /*@-unrecog@*/accept(fd, serv_addr, &my_addrlen)/*@+unrecog@*/;
222 } while (val_retry < 0 && errno == EINTR);
223 *addrlen = (int) my_addrlen;
224 error = errno;
225 if (val_retry < 0) {
226 sh_error_handle ((-1), file, line, error, MSG_ERR_ACCEPT,
227 sh_error_message(error),
228 (long) fd );
229 }
230 errno = error;
231 SL_RETURN(val_retry, _("retry_accept"));
232}
233
234long int retry_lstat(char * file, int line,
235 const char *file_name, struct stat *buf)
236{
237 int error;
238 long int val_retry = -1;
239
240 SL_ENTER(_("retry_lstat"));
241
242 do {
243 val_retry = /*@-unrecog@*/lstat (file_name, buf)/*@+unrecog@*/;
244 } while (val_retry < 0 && errno == EINTR);
245 error = errno;
246 if (val_retry < 0) {
247 (void) sl_strlcpy(aud_err_message, sh_error_message(error), 64);
248 sh_error_handle ((-1), file, line, error, MSG_ERR_LSTAT,
249 sh_error_message(error),
250 file_name );
251 }
252 errno = error;
253 SL_RETURN(val_retry, _("retry_lstat"));
254}
255
256long int retry_stat(char * file, int line,
257 const char *file_name, struct stat *buf)
258{
259 int error;
260 long int val_retry = -1;
261
262 SL_ENTER(_("retry_stat"));
263
264 do {
265 val_retry = stat (file_name, buf);
266 } while (val_retry < 0 && errno == EINTR);
267 error = errno;
268 if (val_retry < 0) {
269 (void) sl_strlcpy(aud_err_message, sh_error_message(error), 64);
270 sh_error_handle ((-1), file, line, error, MSG_ERR_STAT,
271 sh_error_message(error),
272 file_name );
273 }
274 errno = error;
275 SL_RETURN(val_retry, _("retry_stat"));
276}
277
278long int retry_fstat(char * file, int line, int filed, struct stat *buf)
279{
280 int error;
281 long int val_retry = -1;
282
283 SL_ENTER(_("retry_fstat"));
284
285 do {
286 val_retry = fstat (filed, buf);
287 } while (val_retry < 0 && errno == EINTR);
288 error = errno;
289 if (val_retry < 0) {
290 sh_error_handle ((-1), file, line, error, MSG_ERR_FSTAT,
291 sh_error_message(error),
292 (long) filed );
293 }
294 errno = error;
295 SL_RETURN(val_retry, _("retry_fstat"));
296}
297
298long int retry_fcntl(char * file, int line, int fd, int cmd, long arg)
299{
300 int error;
301 long int val_retry = -1;
302 errno = 0;
303
304 SL_ENTER(_("retry_fcntl"));
305
306 if (cmd == F_GETFD || cmd == F_GETFL)
307 {
308 do {
309 val_retry = fcntl(fd, cmd);
310 } while (val_retry < 0 && errno == EINTR);
311 }
312 else
313 {
314 do {
315 val_retry = fcntl(fd, cmd, arg);
316 } while (val_retry < 0 && errno == EINTR);
317 }
318 error = errno;
319 if (val_retry < 0) {
320 sh_error_handle ((-1), file, line, error, MSG_ERR_FCNTL,
321 sh_error_message(error),
322 (long) fd, (long) cmd, arg );
323 }
324 errno = error;
325 SL_RETURN(val_retry, _("retry_fcntl"));
326}
327
328long int retry_msleep (int sec, int millisec)
329{
330 int result = 0;
331#if defined(HAVE_NANOSLEEP)
332 struct timespec req, rem;
333#endif
334
335 SL_ENTER(_("retry_fcntl"));
336
337 errno = 0;
338 if (millisec > 999) millisec = 999;
339 if (millisec < 0) millisec = 0;
340 if (sec < 0) sec = 0;
341
342#if defined(HAVE_NANOSLEEP)
343 /*@-usedef@*/
344 req.tv_sec = sec; rem.tv_sec = 0;
345 req.tv_nsec = millisec * 1000000; rem.tv_nsec = 0;
346 /*@+usedef@*/
347 do {
348 result = /*@-unrecog@*/nanosleep(&req, &rem)/*@+unrecog@*/;
349
350 req.tv_sec = rem.tv_sec; rem.tv_sec = 0;
351 req.tv_nsec = rem.tv_nsec; rem.tv_nsec = 0;
352
353 } while ((result == -1) && (errno == EINTR));
354#else
355 if (sec > 0)
356 {
357 sleep (sec);
358 }
359 else
360 {
361#ifdef HAVE_USLEEP
362 if (millisec > 0)
363 {
364 usleep(1000 * millisec);
365 }
366#else
367 if (millisec > 0)
368 {
369 sleep (1);
370 }
371#endif
372 }
373#endif
374 SL_RETURN(result, _("retry_msleep"));
375}
376
377/***************************************************
378 *
379 * Audit these functions.
380 *
381 ***************************************************/
382
383long int retry_aud_execve (char * file, int line,
384 const char *dateiname, char * argv[],
385 char * envp[])
386{
387 uid_t a = geteuid();
388 gid_t b = getegid();
389 int i;
390 int error;
391
392 SL_ENTER(_("retry_aud_execve"));
393
394 if (sh.flag.audit != 0 && (sh.flag.aud_mask & AUD_EXEC) != 0)
395 sh_error_handle ((-1), file, line, 0, MSG_AUD_EXEC,
396 dateiname, (long) a, (long) b );
397 do {
398 i = execve(dateiname, argv, envp);
399 } while (i < 0 && errno == EINTR);
400
401 error = errno;
402 if (i < 0) {
403 sh_error_handle ((-1), file, line, error, MSG_ERR_EXEC, sh_error_message(error),
404 dateiname, (long) a, (long) b );
405 }
406 errno = error;
407 SL_RETURN(i, _("retry_aud_execve"));
408}
409
410
411long int retry_aud_utime (char * file, int line,
412 char * path, struct utimbuf *buf)
413{
414 long int val_return;
415 int error;
416 errno = 0;
417
418 SL_ENTER(_("retry_aud_utime"));
419
420 do {
421 val_return = utime (path, buf);
422 } while (val_return < 0 && errno == EINTR);
423
424 error = errno;
425 if (sh.flag.audit != 0 && (sh.flag.aud_mask & AUD_UTIME) != 0)
426 sh_error_handle ((-1), file, line, 0, MSG_AUD_UTIME,
427 path,
428 (unsigned long) buf->actime,
429 (unsigned long) buf->modtime);
430 if (val_return < 0) {
431 sh_error_handle ((-1), file, line, error, MSG_ERR_UTIME,
432 sh_error_message(error),
433 path,
434 (unsigned long) buf->actime,
435 (unsigned long) buf->modtime);
436 }
437 errno = error;
438 SL_RETURN(val_return, _("retry_aud_utime"));
439}
440
441long int retry_aud_unlink (char * file, int line,
442 char * path)
443{
444 long int val_return;
445 int error;
446 errno = 0;
447
448 SL_ENTER(_("retry_aud_unlink"));
449
450 do {
451 val_return = unlink (path);
452 } while (val_return < 0 && errno == EINTR);
453
454 error = errno;
455 if (sh.flag.audit != 0 && (sh.flag.aud_mask & AUD_UNLINK) != 0)
456 sh_error_handle ((-1), file, line, 0, MSG_AUD_UNLINK,
457 path);
458 if (val_return < 0) {
459 sh_error_handle ((-1), file, line, error, MSG_ERR_UNLINK, sh_error_message(error),
460 path);
461 }
462 errno = error;
463 SL_RETURN(val_return, _("retry_aud_unlink"));
464}
465
466long int retry_aud_dup2 (char * file, int line,
467 int fd, int fd2)
468{
469 long int val_return;
470 int error;
471 errno = 0;
472
473 SL_ENTER(_("retry_aud_dup2"));
474
475 do {
476 val_return = dup2 (fd, fd2);
477 } while (val_return < 0 && errno == EINTR);
478
479 error = errno;
480 if (sh.flag.audit != 0 && (sh.flag.aud_mask & AUD_DUP) != 0)
481 sh_error_handle ((-1), file, line, 0, MSG_AUD_DUP,
482 (long) fd, val_return);
483 if (val_return < 0) {
484 sh_error_handle ((-1), file, line, error, MSG_ERR_DUP,
485 sh_error_message(error),
486 (long) fd, val_return);
487 }
488 errno = error;
489 SL_RETURN(val_return, _("retry_aud_dup2"));
490}
491
492long int retry_aud_dup (char * file, int line,
493 int fd)
494{
495 long int val_return;
496 int error;
497 errno = 0;
498
499 SL_ENTER(_("retry_aud_dup"));
500
501 do {
502 val_return = dup (fd);
503 } while (val_return < 0 && errno == EINTR);
504 error = errno;
505 if (sh.flag.audit != 0 && (sh.flag.aud_mask & AUD_DUP) != 0)
506 sh_error_handle ((-1), file, line, 0, MSG_AUD_DUP,
507 (long) fd, val_return);
508 if (val_return < 0) {
509 sh_error_handle ((-1), file, line, error, MSG_ERR_DUP,
510 sh_error_message(error),
511 (long) fd, val_return);
512 }
513 errno = error;
514 SL_RETURN(val_return, _("retry_aud_dup"));
515}
516
517
518
519long int retry_aud_chdir (char * file, int line,
520 const char *path)
521{
522 long int val_return;
523 int error = 0;
524 errno = 0;
525
526 SL_ENTER(_("retry_aud_chdir"));
527
528 do {
529 val_return = chdir (path);
530 } while (val_return < 0 && errno == EINTR);
531
532 error = errno;
533 if (sh.flag.audit != 0 && (sh.flag.aud_mask & AUD_CHDIR) != 0)
534 sh_error_handle ((-1), file, line, 0, MSG_AUD_CHDIR,
535 path);
536 if (val_return < 0) {
537 sh_error_handle ((-1), file, line, error, MSG_ERR_CHDIR, sh_error_message(error),
538 path);
539 }
540 errno = error;
541 SL_RETURN(val_return, _("retry_aud_chdir"));
542}
543
544
545long int aud_open_noatime (char * file, int line, int privs,
546 const char *pathname, int flags, mode_t mode,
547 int * o_noatime)
548{
549 long int val_return;
550 int error;
551
552 SL_ENTER(_("aud_open"));
553
554 val_return = open (pathname, *o_noatime|flags, mode);
555 if ((val_return < 0) && (*o_noatime != 0))
556 {
557 val_return = open (pathname, flags, mode);
558 if (val_return >= 0)
559 *o_noatime = 0;
560 }
561 error = errno;
562 /*@-noeffect@*/
563 (void) privs; /* fix compiler warning */
564 /*@+noeffect@*/
565
566 if (val_return < 0)
567 {
568 (void) sl_strlcpy(aud_err_message, sh_error_message(error), 64);
569 }
570
571 if (sh.flag.audit != 0 && (sh.flag.aud_mask & AUD_OPEN) != 0)
572 {
573 sh_error_handle ((-1), file, line, 0, MSG_AUD_OPEN,
574 pathname, (long) flags, (long) mode, val_return);
575 }
576 if (val_return < 0) {
577 sh_error_handle ((-1), file, line, error, MSG_ERR_OPEN,
578 sh_error_message(error),
579 pathname, (long) flags, (long) mode, val_return);
580 }
581 errno = error;
582 SL_RETURN(val_return, _("aud_open"));
583}
584
585long int aud_open (char * file, int line, int privs,
586 const char *pathname, int flags, mode_t mode)
587{
588 long int val_return;
589 int error;
590
591 SL_ENTER(_("aud_open"));
592
593 val_return = open (pathname, flags, mode);
594 error = errno;
595 /*@-noeffect@*/
596 (void) privs; /* fix compiler warning */
597 /*@+noeffect@*/
598
599 if (val_return < 0)
600 {
601 (void) sl_strlcpy(aud_err_message, sh_error_message(error), 64);
602 }
603
604 if (sh.flag.audit != 0 && (sh.flag.aud_mask & AUD_OPEN) != 0)
605 {
606 sh_error_handle ((-1), file, line, 0, MSG_AUD_OPEN,
607 pathname, (long) flags, (long) mode, val_return);
608 }
609 if (val_return < 0) {
610 sh_error_handle ((-1), file, line, error, MSG_ERR_OPEN,
611 sh_error_message(error),
612 pathname, (long) flags, (long) mode, val_return);
613 }
614 errno = error;
615 SL_RETURN(val_return, _("aud_open"));
616}
617
618long int aud_kill (char * file, int line, pid_t pid, int sig)
619{
620 int myerror;
621 long int val_return = kill (pid, sig);
622 myerror = errno;
623
624 SL_ENTER(_("aud_kill"));
625
626 if (sh.flag.audit != 0 && (sh.flag.aud_mask & AUD_KILL) != 0)
627 sh_error_handle ((-1), file, line, 0, MSG_AUD_KILL,
628 (long) pid, (long) sig);
629 if (val_return < 0) {
630 sh_error_handle ((-1), file, line, myerror, MSG_ERR_KILL,
631 sh_error_message(myerror),
632 (long) pid, (long) sig);
633 }
634 errno = myerror;
635 SL_RETURN(val_return, _("aud_kill"));
636}
637
638/*@noreturn@*/
639void aud_exit (char * file, int line, int fd)
640{
641 if (sh.flag.audit != 0 && (sh.flag.aud_mask & AUD_EXIT) != 0)
642 sh_error_handle ((-1), file, line, 0, MSG_AUD_EXIT,
643 (long) fd);
644
645 SL_ENTER(_("aud_exit"));
646
647 sh.flag.exit = fd;
648 exit(fd);
649}
650
651/*@noreturn@*/
652void aud__exit (char * file, int line, int fd)
653{
654 if (sh.flag.audit != 0 && (sh.flag.aud_mask & AUD_EXIT) != 0)
655 sh_error_handle ((-1), file, line, 0, MSG_AUD_EXIT,
656 (long) fd);
657
658 SL_ENTER(_("aud__exit"));
659
660 sh.flag.exit = fd;
661 _exit(fd);
662}
663
664pid_t aud_fork (char * file, int line)
665{
666 int error;
667 pid_t i = fork();
668
669 error = errno;
670 SL_ENTER(_("aud_fork"));
671
672 if (sh.flag.audit != 0 && (sh.flag.aud_mask & AUD_FORK) != 0 && (i > 0))
673 sh_error_handle ((-1), file, line, 0, MSG_AUD_FORK,
674 (long) i);
675 if (i == (pid_t) -1) {
676 sh_error_handle ((-1), file, line, error, MSG_ERR_FORK,
677 sh_error_message(error),
678 (long) i);
679 }
680 errno = error;
681 SL_RETURN(i, _("aud_fork"));
682}
683
684int aud_setuid (char * file, int line, uid_t uid)
685{
686 int error = 0;
687 int i = 0;
688
689 SL_ENTER(_("aud_setuid"));
690
691 if (uid != (uid_t) 0) {
692 i = setuid(uid);
693 error = errno;
694 }
695 if (sh.flag.audit != 0 && (sh.flag.aud_mask & AUD_SETUID) != 0)
696 sh_error_handle ((-1), file, line, 0, MSG_AUD_SETUID,
697 (long) uid);
698 if (uid == (uid_t) 0) {
699 i = setuid(uid);
700 error = errno;
701 }
702 if (i < 0) {
703 sh_error_handle ((-1), file, line, error, MSG_ERR_SETUID,
704 sh_error_message(error),
705 (long) uid);
706 }
707 errno = error;
708 SL_RETURN(i, _("aud_setuid"));
709}
710
711int aud_setgid (char * file, int line, gid_t gid)
712{
713 int error = 0;
714 int i = 0;
715
716 SL_ENTER(_("aud_setgid"));
717
718 if (gid != (gid_t) 0) {
719 i = setgid(gid);
720 error = errno;
721 }
722
723 if (sh.flag.audit != 0 && (sh.flag.aud_mask & AUD_SETGID) != 0)
724 sh_error_handle ((-1), file, line, 0, MSG_AUD_SETGID,
725 (long) gid);
726 if (gid == (gid_t) 0) {
727 i = setgid(gid);
728 error = errno;
729 }
730 if (i < 0) {
731 sh_error_handle ((-1), file, line, error, MSG_ERR_SETGID,
732 sh_error_message(error),
733 (long) gid);
734 }
735 errno = error;
736 SL_RETURN(i, _("aud_setgid"));
737}
738
739int aud_pipe (char * file, int line, int * modus)
740{
741 int error;
742 int i = pipe (modus);
743
744 SL_ENTER(_("aud_pipe"));
745
746 error = errno;
747 if (sh.flag.audit != 0 && (sh.flag.aud_mask & AUD_PIPE) != 0)
748 {
749 if (i < 0)
750 sh_error_handle ((-1), file, line, 0, MSG_AUD_PIPE,
751 (long) 0, (long) 0);
752 else
753 sh_error_handle ((-1), file, line, 0, MSG_AUD_PIPE,
754 (long) modus[0], (long) modus[1]);
755 }
756 if (i < 0) {
757 if (i < 0)
758 sh_error_handle ((-1), file, line, error, MSG_ERR_PIPE,
759 sh_error_message(error),
760 (long) 0, (long) 0);
761 else
762 sh_error_handle ((-1), file, line, error, MSG_ERR_PIPE,
763 sh_error_message(error),
764 (long) modus[0], (long) modus[1]);
765 }
766 SL_RETURN(i, _("aud_pipe"));
767}
Note: See TracBrowser for help on using the repository browser.