source: branches/samhain-2_2-branch/src/sh_hash.c@ 272

Last change on this file since 272 was 40, checked in by rainer, 18 years ago

Fix for tickets #13, #14, #15, #16, #17

File size: 82.5 KB
Line 
1/* SAMHAIN file system integrity testing */
2/* Copyright (C) 1999, 2000, 2001, 2002 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/* define this if you want version 1.3 style database file */
23/* #define OLD_BUG */
24
25/* make sure state changes of a file are always reported, even
26 * with reportonlyonce=true
27 */
28/* #define REPLACE_OLD *//* moved to samhain.h */
29
30#include <stdlib.h>
31#include <string.h>
32#include <stdio.h>
33#include <sys/types.h>
34#include <sys/stat.h>
35#include <unistd.h>
36
37#ifdef MAJOR_IN_MKDEV
38#include <sys/mkdev.h>
39#else
40#ifdef MAJOR_IN_SYSMACROS
41#include <sys/sysmacros.h>
42#endif
43#endif
44
45#ifdef HAVE_MEMORY_H
46#include <memory.h>
47#endif
48
49#if defined(SH_WITH_CLIENT) || defined(SH_STANDALONE)
50
51#include "sh_hash.h"
52#include "sh_utils.h"
53#include "sh_error.h"
54#include "sh_tiger.h"
55#include "sh_gpg.h"
56#include "sh_unix.h"
57#include "sh_files.h"
58#include "sh_ignore.h"
59
60#if defined(SH_WITH_CLIENT)
61#include "sh_forward.h"
62#endif
63
64#undef FIL__
65#define FIL__ _("sh_hash.c")
66
67static char * all_items (file_type * theFile, char * fileHash, int is_new);
68
69#define QUOTE_CHAR '='
70
71char * unquote_string (const char * str)
72{
73 int i = 0, t1, t2;
74 char * tmp = NULL;
75 size_t len, l2, j, k = 0;
76
77 SL_ENTER(_("unquote_string"));
78
79 if (str != NULL)
80 {
81 len = sl_strlen(str);
82 l2 = len - 2;
83 tmp = SH_ALLOC(len + 1);
84
85 for (j = 0; j <= len; ++j)
86 {
87 if (str[j] != QUOTE_CHAR)
88 {
89 tmp[k] = str[j];
90 }
91 else if (str[j] == QUOTE_CHAR && j < l2)
92 {
93 t1 = sh_util_hexchar(str[j+1]);
94 t2 = sh_util_hexchar(str[j+2]);
95 if ((t1|t2) >= 0)
96 {
97 i = 16 * t1 + t2;
98 tmp[k] = i;
99 j += 2;
100 }
101 else
102 {
103 tmp[k] = str[j];
104 }
105 }
106 else
107 tmp[k] = str[j];
108 ++k;
109 }
110 }
111 SL_RETURN(tmp, _("unquote_string"));
112}
113
114static char i2h[2];
115
116char * int2hex (unsigned char i)
117{
118 static char hexchars[] = "0123456789ABCDEF";
119
120 i2h[0] = hexchars[(((i) & 0xF0) >> 4)]; /* high */
121 i2h[1] = hexchars[((i) & 0x0F)]; /* low */
122
123 return i2h;
124}
125
126
127char * quote_string (const char * str)
128{
129 char * tmp;
130 char * tmp2;
131 size_t len, l2, j, i = 0, k = 0;
132
133 SL_ENTER(_("quote_string"));
134
135 if (str == NULL)
136 {
137 SL_RETURN(NULL, _("quote_string"));
138 }
139
140 len = sl_strlen(str);
141
142 for (j = 0; j < len; ++j)
143 if (str[j] == '\n' || str[j] == QUOTE_CHAR) ++i;
144
145 l2 = len + 1;
146 if (sl_ok_muls(3, i) && sl_ok_adds(l2, (3*i)))
147 {
148 tmp = SH_ALLOC(len + 1 + 3*i);
149 }
150 else
151 {
152 sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
153 _("integer overflow"),
154 _("quote_string"));
155 SL_RETURN(NULL, _("quote_string"));
156 }
157
158 for (j = 0; j <= len; ++j)
159 {
160 if (str[j] == '\n')
161 {
162 tmp2 = int2hex((unsigned char) '\n'); /* was 'n', fixed in 1.5.4 */
163 tmp[k] = QUOTE_CHAR; ++k;
164 tmp[k] = tmp2[0]; ++k;
165 tmp[k] = tmp2[1];
166 }
167 else if (str[j] == QUOTE_CHAR)
168 {
169 tmp2 = int2hex((unsigned char) QUOTE_CHAR);
170 tmp[k] = QUOTE_CHAR; ++k;
171 tmp[k] = tmp2[0]; ++k;
172 tmp[k] = tmp2[1];
173 }
174 else
175 {
176 tmp[k] = str[j];
177 }
178 ++k;
179 }
180 SL_RETURN(tmp, _("quote_string"));
181}
182
183static UINT32 * swap_32 (UINT32 * iptr)
184{
185#ifdef WORDS_BIGENDIAN
186 unsigned char swap;
187 unsigned char * ii = (unsigned char *) iptr;
188 swap = ii[0]; ii[0] = ii[3]; ii[3] = swap;
189 swap = ii[1]; ii[1] = ii[2]; ii[2] = swap;
190 return iptr;
191#else
192 return iptr;
193#endif
194}
195
196static UINT64 * swap_64 (UINT64 * iptr)
197{
198#ifdef WORDS_BIGENDIAN
199#ifdef UINT64_IS_32
200 swap_32 ((UINT32*) iptr);
201#else
202 unsigned char swap;
203 unsigned char * ii = (unsigned char *) iptr;
204 swap = ii[0]; ii[0] = ii[7]; ii[7] = swap;
205 swap = ii[1]; ii[1] = ii[6]; ii[6] = swap;
206 swap = ii[2]; ii[2] = ii[5]; ii[5] = swap;
207 swap = ii[3]; ii[3] = ii[4]; ii[4] = swap;
208#endif
209 return iptr;
210#else
211 return iptr;
212#endif
213}
214
215static unsigned short * swap_short (unsigned short * iptr)
216{
217#ifdef WORDS_BIGENDIAN
218 if (sizeof(short) == 4)
219 swap_32 ((UINT32*) iptr);
220 else
221 {
222 /* alignment problem */
223 unsigned char swap;
224 static unsigned short ooop;
225 unsigned char * ii;
226 ooop = *iptr;
227 ii = (unsigned char *) &ooop;
228 /* printf("SWAP0: %hd %d\n", *iptr, sizeof(unsigned short)); */
229 swap = ii[0]; ii[0] = ii[1]; ii[1] = swap;
230 /* printf("SWAP1: %hd\n", (unsigned short) ooop); */
231#ifndef OLD_BUG
232 return &ooop;
233#endif
234 }
235 return iptr;
236#else
237 return iptr;
238#endif
239}
240
241
242/* MAX_PATH_STORE must be >= KEY_LEN
243 */
244#define MAX_PATH_STORE 12287
245
246typedef struct store_info {
247 /*
248 char fullpath[MAX_PATH_STORE+2];
249 char linkpath[MAX_PATH_STORE+2];
250 */
251 UINT32 mode;
252 UINT32 linkmode;
253
254 UINT64 dev;
255 UINT64 rdev;
256 UINT32 hardlinks;
257 UINT32 ino;
258 UINT64 size;
259 UINT64 atime;
260 UINT64 mtime;
261 UINT64 ctime;
262 UINT32 owner;
263 UINT32 group;
264
265#ifdef OLD_BUG
266#if defined(__linux__)
267 UINT32 attributes;
268 char c_attributes[16];
269#endif
270#else
271 /* #if defined(__linux__) */
272 UINT32 attributes;
273 char c_attributes[16];
274 /* endif */
275#endif
276 unsigned short mark;
277 char c_owner[USER_MAX+2];
278 char c_group[GROUP_MAX+2];
279 char c_mode[11];
280 char checksum[KEY_LEN+1];
281} sh_filestore_t;
282
283typedef struct file_info {
284 sh_filestore_t theFile;
285 char * fullpath;
286 char * linkpath;
287 int visited;
288 int reported;
289 int allignore;
290 unsigned long modi_mask;
291 struct file_info * next;
292} sh_file_t;
293
294 static char *policy[] = {
295 N_("[]"),
296 N_("[ReadOnly]"),
297 N_("[LogFiles]"),
298 N_("[GrowingLogs]"),
299 N_("[IgnoreNone]"),
300 N_("[IgnoreAll]"),
301 N_("[Attributes]"),
302 N_("[User0]"),
303 N_("[User1]"),
304 N_("[User2]"),
305 N_("[User3]"),
306 N_("[User4]"),
307 N_("[Prelink]"),
308 NULL
309 };
310
311
312/**********************************
313 *
314 * hash table functions
315 *
316 **********************************
317 */
318
319#include "sh_hash.h"
320
321/* must fit an int */
322/* #define TABSIZE 2048 */
323#define TABSIZE 65536
324
325/* must fit an unsigned short */
326/* changed for V0.8, as the */
327/* database format has changed */
328
329/* changed again for V0.9 */
330/* #define REC_MAGIC 19 */
331/* changed again for V1.3 */
332#ifdef OLD_BUG
333#define REC_MAGIC 20
334#else
335/* changed again for V1.4 */
336#define REC_MAGIC 21
337#endif
338
339
340/**************************************************************
341 *
342 * create a file_type from a sh_file_t
343 *
344 **************************************************************/
345static file_type * sh_hash_create_ft (const sh_file_t * p, char * fileHash)
346{
347 file_type * theFile;
348#if defined(__linux__) || defined(HAVE_STAT_FLAGS)
349 int i = 16;
350#endif
351
352 SL_ENTER(_("sh_hash_create_ft"));
353
354 theFile = SH_ALLOC(sizeof(file_type));
355
356 sl_strlcpy(theFile->c_mode, p->theFile.c_mode, 11);
357 theFile->mode = p->theFile.mode;
358#if defined(__linux__) || defined(HAVE_STAT_FLAGS)
359 sl_strlcpy(theFile->c_attributes, p->theFile.c_attributes, i /* 16 */);
360 theFile->attributes = p->theFile.attributes;
361#endif
362
363 sl_strlcpy(theFile->fullpath, p->fullpath, PATH_MAX);
364 if (p->linkpath != NULL && theFile->c_mode[0] == 'l')
365 {
366 sl_strlcpy(theFile->linkpath, p->linkpath, PATH_MAX);
367 }
368 else
369 {
370 theFile->linkpath[0] = '-';
371 theFile->linkpath[1] = '\0';
372 }
373 sl_strlcpy(fileHash, p->theFile.checksum, KEY_LEN+1);
374
375 theFile->mtime = p->theFile.mtime;
376 theFile->ctime = p->theFile.ctime;
377 theFile->atime = p->theFile.atime;
378
379 theFile->size = p->theFile.size;
380
381 sl_strlcpy(theFile->c_group, p->theFile.c_group, GROUP_MAX+2);
382 theFile->group = p->theFile.group;
383 sl_strlcpy(theFile->c_owner, p->theFile.c_owner, USER_MAX+2);
384 theFile->owner = p->theFile.owner;
385
386 theFile->ino = p->theFile.ino;
387 theFile->rdev = p->theFile.rdev;
388 theFile->dev = p->theFile.dev;
389 theFile->hardlinks = p->theFile.hardlinks;
390
391 SL_RETURN((theFile), _("sh_hash_create_ft"));
392}
393
394static sh_file_t * hashsearch (char * s);
395
396static sh_file_t * tab[TABSIZE];
397
398/**************************************************************
399 *
400 * compute hash function
401 *
402 **************************************************************/
403
404static int hashfunc(char *s)
405{
406 unsigned int n = 0;
407
408 for ( ; *s; s++)
409 n = 31 * n + *s;
410
411 return n & (TABSIZE - 1); /* % TABSIZE */;
412}
413
414
415int hashreport_missing( char *fullpath, int level)
416{
417 sh_file_t * p;
418 char * tmp;
419 char fileHash[KEY_LEN + 1];
420 file_type * theFile;
421 char * str;
422
423 /* -------- find the entry for the file ---------------- */
424
425 if (sl_strlen(fullpath) <= MAX_PATH_STORE)
426 p = hashsearch(fullpath);
427 else
428 p = hashsearch( sh_tiger_hash(fullpath,
429 TIGER_DATA,
430 sl_strlen(fullpath))
431 );
432 if (p == NULL)
433 return -1;
434
435 theFile = sh_hash_create_ft (p, fileHash);
436 str = all_items(theFile, fileHash, 0);
437 tmp = sh_util_safe_name(fullpath);
438 sh_error_handle (level, FIL__, __LINE__, 0,
439 MSG_FI_MISS2, tmp, str);
440 SH_FREE(tmp);
441 SH_FREE(str);
442 SH_FREE(theFile);
443 return 0;
444}
445
446
447/**************************************************************
448 *
449 * search for files not visited, and check whether they exist
450 *
451 **************************************************************/
452static void hash_unvisited (int j,
453 sh_file_t *prev, sh_file_t *p, ShErrLevel level)
454{
455 struct stat buf;
456 int i;
457 char * tmp;
458 char * ptr;
459 char fileHash[KEY_LEN + 1];
460 file_type * theFile;
461
462 char * str;
463
464
465 SL_ENTER(_("hash_unvisited"));
466
467 if (p->next != NULL)
468 hash_unvisited (j, p, p->next, level);
469
470 if (p->fullpath == NULL)
471 {
472 SL_RET0(_("hash_unvisited"));
473 }
474
475 /* Kernel info
476 */
477 if (p->fullpath[0] == 'K')
478 {
479 SL_RET0(_("hash_unvisited"));
480 }
481
482 /* visited = FALSE: not seen;
483 * visited = 99: not seen, and already checked
484 * reported = FALSE: not reported yet
485 * allignore = FALSE: not under IgnoreAll
486 *
487 * Files/directories under IgnoreAll are noticed as missing already
488 * during the file check.
489 */
490 if ((p->visited == S_FALSE || p->visited == 99) && p->reported == S_FALSE
491 && p->allignore == S_FALSE)
492 {
493 i = retry_lstat(FIL__, __LINE__, p->fullpath, &buf);
494
495 /* if file does not exist
496 */
497 if (0 != i)
498 {
499 ptr = sh_util_dirname (p->fullpath);
500 if (ptr)
501 {
502 /* If any of the parent directories is under IgnoreAll
503 */
504 if (0 != sh_files_is_allignore(ptr))
505 level = ShDFLevel[SH_LEVEL_ALLIGNORE];
506 SH_FREE(ptr);
507 }
508 if (p->visited != 99)
509 {
510 if (S_FALSE == sh_ignore_chk_del(p->fullpath))
511 {
512 tmp = sh_util_safe_name(p->fullpath);
513
514 theFile = sh_hash_create_ft (p, fileHash);
515 str = all_items(theFile, fileHash, 0);
516 sh_error_handle (level, FIL__, __LINE__, 0,
517 MSG_FI_MISS2, tmp, str);
518 SH_FREE(str);
519 SH_FREE(theFile);
520
521 SH_FREE(tmp);
522 }
523 }
524
525 /* We rewrite the db on update, thus we need to push this out
526 * if the user does not want to purge it from the db.
527 */
528 if (sh.flag.checkSum == SH_CHECK_INIT &&
529 sh.flag.update == S_TRUE &&
530 S_FALSE == sh_util_ask_update(p->fullpath))
531 {
532 theFile = sh_hash_create_ft (p, fileHash);
533 sh_hash_pushdata (theFile, fileHash);
534 SH_FREE(theFile);
535 }
536
537 if (sh.flag.reportonce == S_TRUE)
538 {
539#ifdef REPLACE_OLD
540 /* Remove the old entry
541 */
542 if (prev == p)
543 tab[j] = p->next;
544 else
545 prev->next = p->next;
546 if (p->fullpath)
547 {
548 SH_FREE(p->fullpath);
549 p->fullpath = NULL;
550 }
551 if (p->linkpath)
552 {
553 SH_FREE(p->linkpath);
554 p->linkpath = NULL;
555 }
556 SH_FREE(p);
557 p = NULL;
558 SL_RET0(_("hash_unvisited"));
559#else
560 p->reported = S_TRUE;
561#endif
562 }
563 }
564 }
565
566 else if (p->visited == S_TRUE && p->reported == S_TRUE
567 && p->allignore == S_FALSE)
568 {
569 if (S_FALSE == sh_ignore_chk_new(p->fullpath))
570 {
571 tmp = sh_util_safe_name(p->fullpath);
572
573 theFile = sh_hash_create_ft (p, fileHash);
574 str = all_items(theFile, fileHash, 0);
575 sh_error_handle (level, FIL__, __LINE__, 0,
576 MSG_FI_MISS2, tmp, str);
577 SH_FREE(str);
578 SH_FREE(theFile);
579
580 SH_FREE(tmp);
581 }
582
583 p->reported = S_FALSE;
584 }
585
586 if (sh.flag.reportonce == S_FALSE)
587 p->reported = S_FALSE;
588
589 p->visited = S_FALSE;
590 SL_RET0(_("hash_unvisited"));
591}
592
593
594/*********************************************************************
595 *
596 * Search for files in the database that have been deleted from disk.
597 *
598 *********************************************************************/
599void sh_hash_unvisited (ShErrLevel level)
600{
601 int i;
602
603 SL_ENTER(_("sh_hash_unvisited"));
604 for (i = 0; i < TABSIZE; ++i)
605 {
606 if (tab[i] != NULL)
607 hash_unvisited (i, tab[i], tab[i], level);
608 }
609 SL_RET0(_("hash_unvisited"));
610}
611
612
613/**********************************************************************
614 *
615 * delete hash array
616 *
617 **********************************************************************/
618static void hash_kill (sh_file_t *p)
619{
620 SL_ENTER(_("hash_kill"));
621
622 if (p == NULL)
623 SL_RET0(_("hash_kill"));
624
625 if (p->next != NULL)
626 hash_kill (p->next);
627
628 if (p->fullpath)
629 {
630 SH_FREE(p->fullpath);
631 p->fullpath = NULL;
632 }
633 if (p->linkpath)
634 {
635 SH_FREE(p->linkpath);
636 p->linkpath = NULL;
637 }
638 SH_FREE(p);
639 p = NULL;
640 SL_RET0(_("hash_kill"));
641}
642
643
644/***********************************************************************
645 *
646 * get info out of hash array
647 *
648 ***********************************************************************/
649static sh_file_t * hashsearch (char * s)
650{
651 sh_file_t * p;
652
653 SL_ENTER(_("hashsearch"));
654
655 if (s)
656 {
657 for (p = tab[hashfunc(s)]; p; p = p->next)
658 if ((p->fullpath != NULL) && (0 == strcmp(s, p->fullpath)))
659 SL_RETURN( p, _("hashsearch"));
660 }
661 SL_RETURN( NULL, _("hashsearch"));
662}
663
664
665/***********************************************************************
666 *
667 * insert into hash array
668 *
669 ***********************************************************************/
670static void hashinsert (sh_file_t * s)
671{
672 sh_file_t * p;
673 sh_file_t * q;
674 int key;
675
676 SL_ENTER(_("hashinsert"));
677
678 key = hashfunc(s->fullpath);
679
680 if (tab[key] == NULL)
681 {
682 tab[key] = s;
683 tab[key]->next = NULL;
684 SL_RET0(_("hashinsert"));
685 }
686 else
687 {
688 p = tab[key];
689 while (1)
690 {
691 if (p && p->fullpath &&
692 0 == strcmp(s->fullpath, p->fullpath))
693 {
694 q = p->next;
695 SH_FREE(p->fullpath);
696 if(p->linkpath)
697 SH_FREE(p->linkpath);
698 memcpy(p, s, sizeof(sh_file_t));
699 p->next = q;
700 SH_FREE(s);
701 s = NULL;
702 SL_RET0(_("hashinsert"));
703 }
704 else
705 if (p->next == NULL)
706 {
707 p->next = s;
708 p->next->next = NULL;
709 SL_RET0(_("hashinsert"));
710 }
711 p = p->next;
712 }
713 }
714 /* notreached */
715}
716
717
718/******************************************************************
719 *
720 * Get a single line
721 *
722 ******************************************************************/
723static FILE * sh_fin_fd = NULL;
724
725static int sh_hash_getline (FILE * fd, char * line, int sizeofline)
726{
727 register int n = 0;
728 char * res;
729
730 if (sizeofline < 2) {
731 if (sizeofline > 0) line[0] = '\0';
732 return 0;
733 }
734 res = fgets(line, sizeofline, fd);
735 if (res == NULL)
736 {
737 line[0] = '\0';
738 return -1;
739 }
740 n = strlen(line);
741 if (n > 1) {
742 --n;
743 line[n] = '\0'; /* remove terminating '\n' */
744 }
745 return n;
746}
747
748static void sh_hash_getline_end ()
749{
750 fclose (sh_fin_fd);
751 sh_fin_fd = NULL;
752 return;
753}
754
755/******************************************************************
756 *
757 * ------- Check functions -------
758 *
759 ******************************************************************/
760
761static int IsInit = 0;
762
763
764/******************************************************************
765 *
766 * Fast forward to start of data
767 *
768 ******************************************************************/
769int sh_hash_setdataent (SL_TICKET fd, char * line, int size, const char * file)
770{
771 long i;
772 extern int get_the_fd (SL_TICKET ticket);
773
774 SL_ENTER(_("sh_hash_setdataent"));
775
776 sl_rewind (fd);
777
778 if (sh_fin_fd != NULL)
779 {
780 fclose (sh_fin_fd);
781 sh_fin_fd = NULL;
782 }
783
784 sh_fin_fd = fdopen(get_the_fd(fd), "rb");
785 if (!sh_fin_fd)
786 {
787 dlog(1, FIL__, __LINE__,
788 _("The file signature database: %s is not readable.\n"),
789 (NULL == file) ? _("(null)") : file);
790 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_P_NODATA,
791 ( (NULL == file) ? _("(null)") : file)
792 );
793 aud_exit (FIL__, __LINE__, EXIT_FAILURE);
794 }
795
796 while (1)
797 {
798 i = sh_hash_getline (sh_fin_fd, line, size);
799 if (i < 0 )
800 {
801 SH_FREE(line);
802 dlog(1, FIL__, __LINE__,
803 _("The file signature database: %s does not\ncontain any data, or the start-of-file marker is missing (unlikely,\nunless modified by hand).\n"),
804 (NULL == file) ? _("(null)") : file);
805
806 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_P_NODATA,
807 ( (NULL == file) ? _("(null)") : file)
808 );
809 aud_exit (FIL__, __LINE__, EXIT_FAILURE);
810 }
811
812#if defined(SH_STEALTH)
813 if (0 == sl_strncmp (line, N_("[SOF]"), 5))
814#else
815 if (0 == sl_strncmp (line, _("[SOF]"), 5))
816#endif
817 break;
818 }
819 SL_RETURN( 1, _("sh_hash_setdataent"));
820}
821
822static int sh_hash_setdataent_old (SL_TICKET fd, char * line, int size,
823 char * file)
824{
825 long i;
826
827 SL_ENTER(_("sh_hash_setdataent_old"));
828
829 sl_rewind (fd);
830
831 while (1)
832 {
833 i = sh_unix_getline (fd, line, size-1);
834 if (i < 0 )
835 {
836 SH_FREE(line);
837 dlog(1, FIL__, __LINE__,
838 _("The file signature database: %s does not\ncontain any data, or the start-of-file marker is missing (unlikely,\nunless modified by hand).\n"),
839 (NULL == file) ? _("(null)") : file);
840
841 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_P_NODATA,
842 ( (NULL == file) ? _("(null)") : file)
843 );
844 aud_exit (FIL__, __LINE__, EXIT_FAILURE);
845 }
846
847#if defined(SH_STEALTH)
848 if (0 == sl_strncmp (line, N_("[SOF]"), 5))
849#else
850 if (0 == sl_strncmp (line, _("[SOF]"), 5))
851#endif
852 break;
853 }
854 SL_RETURN( 1, _("sh_hash_setdataent_old"));
855}
856
857/******************************************************************
858 *
859 * Read next record
860 *
861 ******************************************************************/
862sh_file_t * sh_hash_getdataent (SL_TICKET fd, char * line, int size)
863{
864 sh_file_t * p;
865 sh_filestore_t ft;
866 long i;
867 size_t len;
868 char * fullpath;
869 char * linkpath;
870 char * tmp;
871
872 SL_ENTER(_("sh_hash_getdataent"));
873
874 (void) fd;
875
876 /* Read next record -- Part One
877 */
878 p = SH_ALLOC(sizeof(sh_file_t));
879
880 i = fread (&ft, sizeof(sh_filestore_t), 1, sh_fin_fd);
881 /* i = sl_read(fd, &ft, sizeof(sh_filestore_t)); */
882 /* if ( SL_ISERROR(i) || i == 0) */
883 if (i < 1)
884 {
885 SH_FREE(p);
886 SL_RETURN( NULL, _("sh_hash_getdataent"));
887 }
888
889 swap_32(&(ft.mode));
890 swap_32(&(ft.linkmode));
891 swap_64(&(ft.dev));
892 swap_64(&(ft.rdev));
893 swap_32(&(ft.hardlinks));
894 swap_32(&(ft.ino));
895 swap_64(&(ft.size));
896 swap_64(&(ft.atime));
897 swap_64(&(ft.mtime));
898 swap_64(&(ft.ctime));
899 swap_32(&(ft.owner));
900 swap_32(&(ft.group));
901#if defined(__linux__) || defined(HAVE_STAT_FLAGS)
902 swap_32(&(ft.attributes));
903#endif
904#ifdef OLD_BUG
905 swap_short(&(ft.mark));
906#else
907 ft.mark = *(swap_short(&(ft.mark)));
908#endif
909
910 if (ft.mark != REC_MAGIC)
911 {
912 SH_FREE(p);
913 SL_RETURN( NULL, _("sh_hash_getdataent"));
914 }
915
916 /* Read next record -- Part Two -- Fullpath
917 */
918 i = sh_hash_getline (sh_fin_fd, line, size);
919 if (i < 0 )
920 {
921 SH_FREE(line);
922 SH_FREE(p);
923 dlog(1, FIL__, __LINE__,
924 _("There is a corrupt record in the file signature database: %s\nThe file path is missing.\n"),
925 (NULL == file_path('D', 'R'))? _("(null)"):file_path('D', 'R'));
926 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_P_NODATA,
927 ( (NULL == file_path('D', 'R')) ? _("(null)") :
928 file_path('D', 'R'))
929 );
930 aud_exit (FIL__, __LINE__,EXIT_FAILURE);
931 }
932
933 tmp = unquote_string (line);
934 len = sl_strlen(tmp)+1;
935 fullpath = SH_ALLOC(len);
936 (void) sl_strlcpy (fullpath, tmp, len);
937 if (tmp)
938 SH_FREE(tmp);
939 if (fullpath[len-2] == '\n')
940 fullpath[len-2] = '\0';
941
942 /* Read next record -- Part Three -- Linkpath
943 */
944 i = sh_hash_getline (sh_fin_fd, line, size);
945 if (i < 0 )
946 {
947 SH_FREE(line);
948 SH_FREE(fullpath);
949 SH_FREE(p);
950 dlog(1, FIL__, __LINE__,
951 _("There is a corrupt record in the file signature database: %s\nThe link path (or its placeholder) is missing.\n"),
952 (NULL == file_path('D', 'R'))? _("(null)"):file_path('D', 'R'));
953 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_P_NODATA,
954 ( (NULL == file_path('D', 'R')) ? _("(null)") :
955 file_path('D', 'R'))
956 );
957 aud_exit (FIL__, __LINE__,EXIT_FAILURE);
958 }
959
960 tmp = unquote_string (line);
961 len = sl_strlen(tmp)+1;
962 linkpath = SH_ALLOC(len);
963 (void) sl_strlcpy (linkpath, tmp, len);
964 if (tmp)
965 SH_FREE(tmp);
966 if (linkpath[len-2] == '\n')
967 linkpath[len-2] = '\0';
968
969 /* Read next record -- Part Four -- Decode
970 */
971#if defined(SH_STEALTH)
972 sh_do_decode(fullpath, sl_strlen(fullpath));
973
974#if defined(__linux__) || defined(HAVE_STAT_FLAGS)
975 sh_do_decode(ft.c_attributes, sl_strlen(ft.c_attributes));
976#endif
977
978 sh_do_decode(ft.c_mode, sl_strlen(ft.c_mode));
979 sh_do_decode(ft.c_owner, sl_strlen(ft.c_owner));
980 sh_do_decode(ft.c_group, sl_strlen(ft.c_group));
981 sh_do_decode(ft.checksum, sl_strlen(ft.checksum));
982
983
984 if (ft.c_mode[0] == 'l')
985 {
986 sh_do_decode(linkpath, sl_strlen(linkpath));
987 }
988#endif
989
990 memcpy( &(*p).theFile, &ft, sizeof(sh_filestore_t) );
991 p->visited = S_FALSE;
992 p->reported = S_FALSE;
993 p->allignore = S_FALSE;
994 p->modi_mask = 0L;
995 p->fullpath = fullpath;
996 p->linkpath = linkpath;
997
998 /* set to an invalid value
999 */
1000 ft.mark = (REC_MAGIC + 5);
1001
1002 SL_RETURN( p, _("sh_hash_getdataent"));
1003}
1004
1005/******************************************************************
1006 *
1007 * Initialize
1008 *
1009 ******************************************************************/
1010void sh_hash_init ()
1011{
1012
1013#define FGETS_BUF 16384
1014
1015 sh_file_t * p;
1016 SL_TICKET fd = (-1);
1017 long i;
1018 int count = 0;
1019 char * line = NULL;
1020
1021#if defined(WITH_GPG) || defined(WITH_PGP)
1022 extern int get_the_fd (SL_TICKET ticket);
1023 FILE * fin_cp;
1024
1025 char * buf = NULL;
1026 int bufc;
1027 int flag_pgp = S_FALSE;
1028 int flag_nohead = S_FALSE;
1029 SL_TICKET fdTmp = (-1);
1030 SL_TICKET open_tmp (void);
1031#endif
1032
1033 SL_ENTER(_("sh_hash_init"));
1034
1035 if (IsInit == 1)
1036 SL_RET0(_("sh_hash_init"));
1037
1038 for (i = 0; i < TABSIZE; ++i)
1039 tab[i] = NULL;
1040
1041#if defined(SH_WITH_CLIENT)
1042
1043 /* Data file from Server
1044 */
1045
1046 if (fd == (-1) && 0 == sl_strcmp(file_path('D', 'R'), _("REQ_FROM_SERVER")))
1047 {
1048 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_D_DSTART);
1049 fd = sh_forward_req_file(_("DATA"));
1050 if (SL_ISERROR(fd))
1051 {
1052 dlog(1, FIL__, __LINE__,
1053 _("Could not retrieve the file signature database from the server(errnum = %ld).\nPossible reasons include:\n - the server is not running,\n - session key negotiation failed (see the manual for proper setup), or\n - the server cannot access the file.\n"), fd);
1054 sh_error_handle ((-1), FIL__, __LINE__, fd, MSG_EXIT_ABORT1,
1055 sh.prg_name);
1056 aud_exit (FIL__, __LINE__, EXIT_FAILURE);
1057 }
1058 sl_rewind (fd);
1059
1060 tiger_fd = fd;
1061 sl_strlcpy (sh.data.hash,
1062 sh_tiger_hash (file_path('C', 'R'), /*irrelevant, TIGER_FD*/
1063 TIGER_FD, 0),
1064 KEY_LEN+1);
1065 sl_rewind (fd);
1066 }
1067 else
1068#endif
1069 /* Local data file
1070 */
1071
1072 if (fd == (-1))
1073 {
1074 if ( SL_ISERROR(fd = sl_open_read(file_path('D', 'R'), SL_YESPRIV)))
1075 {
1076 TPT(( 0, FIL__, __LINE__, _("msg=<Error opening: %s>\n"),
1077 file_path('D', 'R')));
1078 dlog(1, FIL__, __LINE__,
1079 _("Could not open the local file signature database for reading because\nof the following error: %s (errnum = %ld)\nIf this is a permission problem, you need to change file permissions\nto make the file readable for the effective UID: %d\n"),
1080 sl_get_errmsg(), fd, (int) sl_ret_euid());
1081 sh_error_handle ((-1), FIL__, __LINE__, fd, MSG_EXIT_ABORT1,
1082 sh.prg_name);
1083 aud_exit (FIL__, __LINE__, EXIT_FAILURE);
1084 }
1085
1086 TPT(( 0, FIL__, __LINE__, _("msg=<Opened database: %s>\n"),
1087 file_path('D', 'R')));
1088
1089 tiger_fd = fd;
1090 if (0 != sl_strncmp(sh.data.hash,
1091 sh_tiger_hash (file_path('D', 'R'), TIGER_FD, 0),
1092 KEY_LEN)
1093 && sh.flag.checkSum != SH_CHECK_INIT)
1094 {
1095 dlog(1, FIL__, __LINE__,
1096 _("The checksum of the file signature database has changed since startup.\n"));
1097 sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_AUTH,
1098 ( (NULL == file_path('D', 'R')) ? _("(null)") :
1099 file_path('D', 'R') )
1100 );
1101 aud_exit (FIL__, __LINE__, EXIT_FAILURE);
1102 }
1103 sl_rewind (fd);
1104
1105 } /* new 1.4.8 */
1106
1107 if (sig_termfast == 1) /* SIGTERM */
1108 {
1109 TPT((0, FIL__, __LINE__, _("msg=<Terminate.>\n")));
1110 --sig_raised; --sig_urgent;
1111 aud_exit (FIL__, __LINE__, EXIT_SUCCESS);
1112 }
1113
1114#if defined(WITH_GPG) || defined(WITH_PGP)
1115 /* new 1.4.8: also checked for server data */
1116
1117 /* extract the data and copy to temporary file
1118 */
1119 fdTmp = open_tmp();
1120
1121 fin_cp = fdopen(get_the_fd(fd), "rb");
1122 buf = SH_ALLOC(FGETS_BUF);
1123
1124 while (NULL != fgets(buf, FGETS_BUF, fin_cp))
1125 {
1126 bufc = 0;
1127 while (bufc < FGETS_BUF) {
1128 if (buf[bufc] == '\n') { ++bufc; break; }
1129 ++bufc;
1130 }
1131
1132 if (sig_termfast == 1) /* SIGTERM */
1133 {
1134 TPT((0, FIL__, __LINE__, _("msg=<Terminate.>\n")));
1135 --sig_raised; --sig_urgent;
1136 aud_exit (FIL__, __LINE__, EXIT_SUCCESS);
1137 }
1138
1139 if (flag_pgp == S_FALSE &&
1140 (0 == sl_strcmp(buf, _("-----BEGIN PGP SIGNED MESSAGE-----\n"))||
1141 0 == sl_strcmp(buf, _("-----BEGIN PGP MESSAGE-----\n")))
1142 )
1143 {
1144 flag_pgp = S_TRUE;
1145 sl_write(fdTmp, buf, bufc);
1146 continue;
1147 }
1148
1149 if (flag_pgp == S_TRUE && flag_nohead == S_FALSE)
1150 {
1151 if (buf[0] == '\n')
1152 {
1153 flag_nohead = S_TRUE;
1154 sl_write(fdTmp, buf, 1);
1155 continue;
1156 }
1157 else if (0 == sl_strncmp(buf, _("Hash:"), 5) ||
1158 0 == sl_strncmp(buf, _("NotDashEscaped:"), 15))
1159 {
1160 sl_write(fdTmp, buf, bufc);
1161 continue;
1162 }
1163 else
1164 continue;
1165 }
1166
1167 if (flag_pgp == S_TRUE && buf[0] == '\n')
1168 {
1169 sl_write(fdTmp, buf, 1);
1170 }
1171 else if (flag_pgp == S_TRUE)
1172 {
1173 /* sl_write_line(fdTmp, buf, bufc); */
1174 sl_write(fdTmp, buf, bufc);
1175 }
1176
1177 if (flag_pgp == S_TRUE &&
1178 0 == sl_strcmp(buf, _("-----END PGP SIGNATURE-----\n")))
1179 break;
1180 }
1181 SH_FREE(buf);
1182 sl_close(fd);
1183 fclose(fin_cp);
1184
1185 fd = fdTmp;
1186 sl_rewind (fd);
1187
1188 /* Validate signature of open file.
1189 */
1190 if (0 != sh_gpg_check_sign (0, fd, 2))
1191 {
1192 aud_exit (FIL__, __LINE__, EXIT_FAILURE);
1193 }
1194 sl_rewind (fd);
1195#endif
1196 /* } new 1.4.8 check sig also for files downloaded from server */
1197
1198 line = SH_ALLOC(MAX_PATH_STORE+1);
1199
1200 /* fast forward to start of data
1201 */
1202 sh_hash_setdataent(fd, line, MAX_PATH_STORE, file_path('D', 'R'));
1203
1204 while (1)
1205 {
1206 if (sig_termfast == 1) /* SIGTERM */
1207 {
1208 TPT((0, FIL__, __LINE__, _("msg=<Terminate.>\n")));
1209 --sig_raised; --sig_urgent;
1210 aud_exit (FIL__, __LINE__, EXIT_SUCCESS);
1211 }
1212
1213 p = sh_hash_getdataent (fd, line, MAX_PATH_STORE);
1214 if (p != NULL)
1215 {
1216 hashinsert (p);
1217 ++count;
1218 }
1219 else
1220 break;
1221 }
1222
1223 if (line != NULL)
1224 SH_FREE(line);
1225
1226 /* Always keep db in memory, so we have no open file
1227 */
1228 sl_close (fd);
1229 sh_hash_getline_end();
1230 fd = -1;
1231
1232 /* --- Initialization done successfully. ---
1233 */
1234 IsInit = 1;
1235 SL_RET0(_("sh_hash_init"));
1236}
1237
1238/*****************************************************************
1239 *
1240 * delete hash array
1241 *
1242 *****************************************************************/
1243void sh_hash_hashdelete ()
1244{
1245 int i;
1246
1247 SL_ENTER(_("sh_hash_hashdelete"));
1248
1249 if (IsInit == 0)
1250 SL_RET0(_("sh_hash_hashdelete"));
1251 for (i = 0; i < TABSIZE; ++i)
1252 if (tab[i] != NULL)
1253 {
1254 hash_kill (tab[i]);
1255 tab[i] = NULL;
1256 }
1257 IsInit = 0;
1258 SL_RET0(_("sh_hash_hashdelete"));
1259}
1260
1261/******************************************************************
1262 *
1263 * Insert a file into the database.
1264 *
1265 ******************************************************************/
1266static int pushdata_isfirst = 1;
1267static SL_TICKET pushdata_fd = -1;
1268
1269static int pushdata_stdout = S_FALSE;
1270
1271static char * sh_db_version_string = NULL;
1272
1273int sh_hash_pushdata_stdout (const char * str)
1274{
1275 if (!str)
1276 { pushdata_stdout = S_TRUE; return 0; }
1277 return -1;
1278}
1279
1280int sh_hash_version_string(const char * str)
1281{
1282 if (str)
1283 {
1284 if (sh_db_version_string != NULL) {
1285 SH_FREE(sh_db_version_string);
1286 }
1287 if (0 == sl_strncmp(str, _("NULL"), 4))
1288 {
1289 sh_db_version_string = NULL;
1290 return 0;
1291 }
1292 sh_db_version_string = sh_util_strdup(str);
1293 return 0;
1294 }
1295 return -1;
1296}
1297
1298
1299void sh_hash_pushdata (file_type * buf, char * fileHash)
1300{
1301 static long p_count = 0;
1302
1303 int status = 0;
1304
1305 char * tmp;
1306 size_t tmp_len = 0;
1307 size_t old_len = 0;
1308
1309 sh_filestore_t p;
1310
1311 struct stat sbuf;
1312
1313 char * fullpath = NULL;
1314 char * linkpath = NULL;
1315
1316 char * line = NULL;
1317
1318 char timestring[81];
1319 char * timep;
1320
1321#if !defined(__linux__) && !defined(HAVE_STAT_FLAGS)
1322 int i;
1323#endif
1324
1325 SL_ENTER(_("sh_hash_pushdata"));
1326
1327 fullpath = SH_ALLOC(MAX_PATH_STORE+1);
1328 linkpath = SH_ALLOC(MAX_PATH_STORE+1);
1329
1330 linkpath[0] = '-';
1331 linkpath[1] = '\0';
1332 fullpath[0] = '-';
1333 fullpath[1] = '\0';
1334
1335 if (!buf) {
1336 memset(&p, '\0', sizeof(sh_filestore_t));
1337 }
1338
1339 if ((pushdata_stdout == S_TRUE) && (sh.flag.update == S_TRUE))
1340 {
1341 dlog(1, FIL__, __LINE__,
1342 _("You cannot write the database to stdout when you use update rather than init.\n"));
1343 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_EXIT_ABORTS,
1344 _("Writing database to stdout with update"),
1345 sh.prg_name,
1346 _("sh_hash_pushdata"));
1347 aud_exit(FIL__, __LINE__, EXIT_FAILURE);
1348 }
1349
1350 if ((pushdata_stdout == S_TRUE) && (sl_is_suid()))
1351 {
1352 dlog(1, FIL__, __LINE__,
1353 _("You cannot write the database to stdout when running with suid privileges.\n"));
1354 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_EXIT_ABORTS,
1355 _("Writing database to stdout when suid"),
1356 sh.prg_name,
1357 _("sh_hash_pushdata"));
1358 aud_exit(FIL__, __LINE__, EXIT_FAILURE);
1359 }
1360
1361
1362 if ((pushdata_stdout == S_FALSE) &&
1363 ( (NULL == file_path('D', 'W')) ||
1364 (0 == sl_strcmp(file_path('D', 'W'), _("REQ_FROM_SERVER"))) ))
1365 {
1366 dlog(1, FIL__, __LINE__,
1367 _("You need to configure a local path for initializing the database\nlike ./configure --with-data-file=REQ_FROM_SERVER/some/local/path\n"));
1368 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_EXIT_ABORTS,
1369 _("No local path for database specified"),
1370 sh.prg_name,
1371 _("sh_hash_pushdata"));
1372 aud_exit(FIL__, __LINE__, EXIT_FAILURE);
1373 }
1374
1375
1376 if ((pushdata_stdout == S_FALSE) && (pushdata_isfirst == 1))
1377 {
1378 /* Warn that file already exists; file_path != NULL here because
1379 * checked above
1380 */
1381 if (0 == retry_lstat(FIL__, __LINE__, file_path('D', 'W'), &sbuf))
1382 {
1383 if (sh.flag.update == S_FALSE)
1384 {
1385 sh_error_handle((-1), FIL__, __LINE__, 0, MSG_FI_DBEX,
1386 file_path('D', 'W'));
1387 }
1388 }
1389 }
1390
1391
1392 if (sh.flag.update == S_FALSE)
1393 {
1394 if (pushdata_stdout == S_FALSE)
1395 {
1396 pushdata_fd = -1;
1397 if ( SL_ISERROR(pushdata_fd = sl_open_write(file_path('D', 'W'), SL_YESPRIV))) {
1398 SH_FREE(fullpath);
1399 SH_FREE(linkpath);
1400 sh_error_handle((-1), FIL__, __LINE__, pushdata_fd, MSG_E_ACCESS,
1401 geteuid(), file_path('D', 'W'));
1402 SL_RET0(_("sh_hash_pushdata"));
1403 }
1404 if ( SL_ISERROR(status = sl_forward(pushdata_fd))) {
1405 SH_FREE(fullpath);
1406 SH_FREE(linkpath);
1407 sh_error_handle((-1), FIL__, __LINE__, status, MSG_E_SUBGPATH,
1408 _("Fast forward failed"), _("sh_hash_pushdata"),
1409 file_path('D', 'W'));
1410 SL_RET0(_("sh_hash_pushdata"));
1411 }
1412 }
1413 }
1414 else /* update == TRUE */
1415 {
1416 if (pushdata_isfirst == 1)
1417 {
1418 TPT((0, FIL__, __LINE__, _("msg=<Update.>\n")))
1419 if ( SL_ISERROR(pushdata_fd = sl_open_rdwr(file_path('D', 'W'), SL_YESPRIV))){
1420 SH_FREE(fullpath);
1421 SH_FREE(linkpath);
1422 sh_error_handle((-1), FIL__, __LINE__, pushdata_fd, MSG_E_ACCESS,
1423 geteuid(), file_path('D', 'W'));
1424 SL_RET0(_("sh_hash_pushdata"));
1425 }
1426 line = SH_ALLOC(MAX_PATH_STORE+1);
1427 if (SL_ISERROR(sh_hash_setdataent_old (pushdata_fd, line,
1428 MAX_PATH_STORE,
1429 file_path('D', 'W'))))
1430 {
1431 SH_FREE(fullpath);
1432 SH_FREE(linkpath);
1433 SH_FREE(line);
1434 SL_RET0(_("sh_hash_pushdata"));
1435 }
1436 SH_FREE(line);
1437 }
1438 }
1439
1440 if (buf != NULL && buf->fullpath != NULL) {
1441
1442 old_len = sl_strlen(buf->fullpath);
1443#if defined(SH_STEALTH)
1444 sh_do_encode(buf->fullpath, old_len);
1445#endif
1446 tmp = quote_string(buf->fullpath);
1447 tmp_len = sl_strlen(tmp);
1448#if defined(SH_STEALTH)
1449 sh_do_decode(buf->fullpath, old_len);
1450#endif
1451
1452 if (tmp && tmp_len <= MAX_PATH_STORE)
1453 {
1454 sl_strlcpy(fullpath, buf->fullpath, MAX_PATH_STORE+1);
1455 /*
1456 if (sl_strlen(buf->fullpath) < (MAX_PATH_STORE-3))
1457 {
1458 fullpath[MAX_PATH_STORE-2] = '\0';
1459 fullpath[MAX_PATH_STORE-1] = '\n';
1460 }
1461 */
1462 }
1463 else
1464 {
1465 sl_strlcpy(fullpath,
1466 sh_tiger_hash (buf->fullpath,
1467 TIGER_DATA, old_len),
1468 KEY_LEN+1);
1469 }
1470 if (tmp) SH_FREE(tmp);
1471 }
1472
1473#if defined(SH_STEALTH)
1474 sh_do_encode(fullpath, sl_strlen(fullpath));
1475#endif
1476
1477 tmp = quote_string(fullpath);
1478 if (tmp) {
1479 sl_strlcpy(fullpath, tmp, MAX_PATH_STORE+1);
1480 SH_FREE(tmp);
1481 }
1482
1483 if (buf != NULL && buf->c_mode[0] == 'l' && buf->linkpath != NULL)
1484 {
1485
1486 old_len = sl_strlen(buf->linkpath);
1487#if defined(SH_STEALTH)
1488 sh_do_encode(buf->linkpath, old_len);
1489#endif
1490 tmp = quote_string(buf->linkpath);
1491 tmp_len = sl_strlen(tmp);
1492#if defined(SH_STEALTH)
1493 sh_do_decode(buf->linkpath, old_len);
1494#endif
1495
1496 if (tmp && tmp_len <= MAX_PATH_STORE)
1497 {
1498 sl_strlcpy(linkpath, buf->linkpath, MAX_PATH_STORE+1);
1499 }
1500 else
1501 {
1502 sl_strlcpy(linkpath,
1503 sh_tiger_hash (buf->linkpath,
1504 TIGER_DATA, old_len),
1505 KEY_LEN+1);
1506 }
1507 if (tmp) SH_FREE(tmp);
1508
1509#if defined(SH_STEALTH)
1510 sh_do_encode(linkpath, sl_strlen(linkpath));
1511#endif
1512 tmp = quote_string(linkpath);
1513 if (tmp)
1514 {
1515 sl_strlcpy(linkpath, tmp, MAX_PATH_STORE+1);
1516 SH_FREE(tmp);
1517 }
1518 }
1519
1520 if (buf != NULL) {
1521 p.mark = REC_MAGIC;
1522 sl_strlcpy(p.c_mode, buf->c_mode, 11);
1523 sl_strlcpy(p.c_group, buf->c_group, GROUP_MAX+1);
1524 sl_strlcpy(p.c_owner, buf->c_owner, USER_MAX+1);
1525 if (fileHash) {
1526 sl_strlcpy(p.checksum, fileHash, KEY_LEN+1);
1527 }
1528#if defined(__linux__) || defined(HAVE_STAT_FLAGS)
1529 sl_strlcpy(p.c_attributes, buf->c_attributes, 13);
1530#else
1531 for (i = 0; i < 12; ++i) p.c_attributes[i] = '-';
1532 p.c_attributes[12] = '\0';
1533#endif
1534
1535#if defined(SH_STEALTH)
1536 sh_do_encode(p.c_mode, sl_strlen(p.c_mode));
1537 sh_do_encode(p.c_owner, sl_strlen(p.c_owner));
1538 sh_do_encode(p.c_group, sl_strlen(p.c_group));
1539 sh_do_encode(p.checksum, sl_strlen(p.checksum));
1540
1541 sh_do_encode(p.c_attributes, sl_strlen(p.c_attributes));
1542#endif
1543
1544#if defined(__linux__) || defined(HAVE_STAT_FLAGS)
1545 p.attributes = (UINT32) buf->attributes;
1546#else
1547 p.attributes = 0;
1548#endif
1549 p.linkmode = (UINT32) buf->linkmode;
1550 p.hardlinks = (UINT32) buf->hardlinks;
1551 p.dev = (UINT64) buf->dev;
1552 p.rdev = (UINT64) buf->rdev;
1553 p.mode = (UINT32) buf->mode;
1554 p.ino = (UINT32) buf->ino;
1555 p.size = (UINT64) buf->size;
1556 p.mtime = (UINT64) buf->mtime;
1557 p.atime = (UINT64) buf->atime;
1558 p.ctime = (UINT64) buf->ctime;
1559 p.owner = (UINT32) buf->owner;
1560 p.group = (UINT32) buf->group;
1561
1562 swap_32(&(p.mode));
1563 swap_32(&(p.linkmode));
1564 swap_64(&(p.dev));
1565 swap_64(&(p.rdev));
1566 swap_32(&(p.hardlinks));
1567 swap_32(&(p.ino));
1568 swap_64(&(p.size));
1569 swap_64(&(p.atime));
1570 swap_64(&(p.mtime));
1571 swap_64(&(p.ctime));
1572 swap_32(&(p.owner));
1573 swap_32(&(p.group));
1574 swap_32(&(p.attributes));
1575
1576#ifdef OLD_BUG
1577 swap_short(&(p.mark));
1578#else
1579 p.mark = *(swap_short(&(p.mark)));
1580#endif
1581 }
1582
1583 /* write the start marker
1584 */
1585 if (pushdata_isfirst == 1)
1586 {
1587 if (sh.flag.update == S_FALSE)
1588 {
1589 if (sh_db_version_string != NULL)
1590 {
1591 if (pushdata_stdout == S_FALSE)
1592 {
1593 sl_write (pushdata_fd, _("\n#Host "), 7);
1594 sl_write (pushdata_fd, sh.host.name,
1595 sl_strlen(sh.host.name));
1596 sl_write (pushdata_fd, _(" Version "), 9);
1597 sl_write (pushdata_fd, sh_db_version_string,
1598 sl_strlen(sh_db_version_string));
1599 sl_write (pushdata_fd, _(" Date "), 6);
1600 timep = sh_unix_time(0);
1601 sl_strlcpy(timestring, timep, sizeof(timestring));
1602 sl_write (pushdata_fd, timestring, sl_strlen(timestring));
1603 sl_write (pushdata_fd, "\n", 1);
1604 } else {
1605 printf (_("\n#Host "));
1606 printf ("%s", sh.host.name);
1607 printf (_(" Version "));
1608 printf ("%s", sh_db_version_string);
1609 printf (_(" Date "));
1610 timep = sh_unix_time(0);
1611 sl_strlcpy(timestring, timep, sizeof(timestring));
1612 printf ("%s\n", timestring);
1613 }
1614 }
1615
1616 if (pushdata_stdout == S_FALSE)
1617 {
1618#if defined(SH_STEALTH)
1619 sl_write (pushdata_fd, "\n", 1);
1620 sl_write_line (pushdata_fd, N_("[SOF]"), 5);
1621#else
1622 sl_write_line (pushdata_fd, _("\n[SOF]"), 6);
1623#endif
1624 }
1625 else
1626 {
1627#if defined(SH_STEALTH)
1628 printf ("\n%s\n", N_("[SOF]"));
1629#else
1630 printf ("%s\n", _("\n[SOF]"));
1631#endif
1632 }
1633 }
1634 pushdata_isfirst = 0;
1635 }
1636
1637 if (pushdata_stdout == S_FALSE)
1638 {
1639 sl_write (pushdata_fd, &p, sizeof(sh_filestore_t));
1640 sl_write_line (pushdata_fd, fullpath, sl_strlen(fullpath));
1641 sl_write_line (pushdata_fd, linkpath, sl_strlen(linkpath));
1642 } else {
1643 fwrite (&p, sizeof(sh_filestore_t), 1, stdout);
1644 printf ("%s\n", fullpath);
1645 printf ("%s\n", linkpath);
1646 }
1647
1648 ++p_count;
1649
1650 if ((sh.flag.update != S_TRUE) && (pushdata_stdout == S_FALSE))
1651 {
1652 sl_close (pushdata_fd);
1653 pushdata_fd = -1;
1654 }
1655
1656 SH_FREE(fullpath);
1657 SH_FREE(linkpath);
1658
1659 SL_RET0(_("sh_hash_pushdata"));
1660}
1661
1662int sh_hash_writeout()
1663{
1664 sh_file_t * p;
1665 int i;
1666 file_type * f;
1667 char fileHash[KEY_LEN + 1];
1668
1669 SL_ENTER(_("sh_hash_writeout"));
1670
1671 if (S_TRUE == file_is_remote())
1672 {
1673 sh_error_handle((-1), FIL__, __LINE__, S_FALSE, MSG_E_SUBGEN,
1674 _("Baseline database is remote"), _("sh_hash_writeout"));
1675 SL_RETURN (1, _("sh_hash_writeout"));
1676 }
1677
1678 if (!SL_ISERROR(pushdata_fd))
1679 {
1680 sl_close(pushdata_fd);
1681 pushdata_fd = -1;
1682 }
1683 pushdata_isfirst = 1;
1684
1685 for (i = 0; i < TABSIZE; ++i)
1686 {
1687 for (p = tab[i]; p; p = p->next)
1688 {
1689 f = sh_hash_create_ft (p, fileHash);
1690 sh_hash_pushdata (f, fileHash);
1691 SH_FREE(f);
1692 }
1693 }
1694
1695 if (!SL_ISERROR(pushdata_fd))
1696 {
1697 sl_close(pushdata_fd);
1698 pushdata_fd = -1;
1699 }
1700 pushdata_isfirst = 1;
1701
1702 SL_RETURN (0, _("sh_hash_writeout"));
1703}
1704
1705
1706/*********************************************************************
1707 *
1708 * Check whether a file is present in the database.
1709 *
1710 *********************************************************************/
1711static sh_file_t * sh_hash_have_it_int (char * newname)
1712{
1713 sh_file_t * p;
1714
1715 SL_ENTER(_("sh_hash_have_it"));
1716
1717 if (newname == NULL)
1718 SL_RETURN( (NULL), _("sh_hash_have_it"));
1719
1720 if (IsInit != 1)
1721 sh_hash_init();
1722 if (sl_strlen(newname) <= MAX_PATH_STORE)
1723 p = hashsearch(newname);
1724 else
1725 p = hashsearch ( sh_tiger_hash(newname, TIGER_DATA, sl_strlen(newname)) );
1726 if (p == NULL)
1727 SL_RETURN( (NULL), _("sh_hash_have_it"));
1728 /*
1729 if (p->allignore == S_FALSE &&
1730 (p->modi_mask & MODI_CHK) != 0 &&
1731 (p->modi_mask & MODI_MOD) != 0)
1732 SL_RETURN( (1), _("sh_hash_have_it"));
1733 */
1734 SL_RETURN( (p), _("sh_hash_have_it"));
1735}
1736
1737int sh_hash_have_it (char * newname)
1738{
1739 sh_file_t * p = sh_hash_have_it_int (newname);
1740
1741 if (!p) return (-1);
1742 if (p->allignore == S_FALSE &&
1743 (p->modi_mask & MODI_CHK) != 0 &&
1744 (p->modi_mask & MODI_MOD) != 0)
1745 return 1;
1746 return 0;
1747}
1748
1749int sh_hash_get_it (char * newname, file_type * tmpFile)
1750{
1751 sh_file_t * p = sh_hash_have_it_int (newname);
1752 if (!p)
1753 return (-1);
1754 sl_strlcpy(tmpFile->fullpath, p->fullpath, PATH_MAX);
1755 sl_strlcpy(tmpFile->linkpath, p->linkpath, PATH_MAX);
1756 tmpFile->size = p->theFile.size;
1757 tmpFile->mtime = p->theFile.mtime;
1758 tmpFile->ctime = p->theFile.ctime;
1759 return 0;
1760}
1761
1762
1763/*****************************************************************
1764 *
1765 * Set a file's status to 'visited'. This is required for
1766 * files that should be ignored, and may be present in the
1767 * database, but not on disk.
1768 *
1769 *****************************************************************/
1770static int sh_hash_set_visited_int (char * newname, int flag)
1771{
1772 sh_file_t * p;
1773
1774 SL_ENTER(_("sh_hash_set_visited_int"));
1775
1776 if (newname == NULL)
1777 SL_RETURN((-1), _("sh_hash_set_visited_int"));
1778 if (IsInit != 1)
1779 sh_hash_init();
1780
1781 if (sl_strlen(newname) <= MAX_PATH_STORE)
1782 p = hashsearch(newname);
1783 else
1784 p = hashsearch (sh_tiger_hash(newname, TIGER_DATA, sl_strlen(newname)));
1785
1786 if (p == NULL)
1787 SL_RETURN((-1), _("sh_hash_set_visited_int"));
1788 if (flag == 99)
1789 {
1790 p->visited = 99;
1791 p->reported = S_FALSE;
1792 }
1793 else
1794 {
1795 p->visited = S_TRUE;
1796 p->reported = flag;
1797 }
1798 SL_RETURN((0), _("sh_hash_set_visited_int"));
1799}
1800
1801
1802/* cause the record to be deleted without a 'missing' message
1803 */
1804int sh_hash_set_missing (char * newname)
1805{
1806 int i;
1807 SL_ENTER(_("sh_hash_set_visited"));
1808 i = sh_hash_set_visited_int(newname, 99);
1809 SL_RETURN(i, _("sh_hash_set_visited"));
1810}
1811
1812int sh_hash_set_visited (char * newname)
1813{
1814 int i;
1815 SL_ENTER(_("sh_hash_set_visited"));
1816 i = sh_hash_set_visited_int(newname, S_TRUE);
1817 SL_RETURN(i, _("sh_hash_set_visited"));
1818}
1819
1820int sh_hash_set_visited_true (char * newname)
1821{
1822 int i;
1823 SL_ENTER(_("sh_hash_set_visited_true"));
1824 i = sh_hash_set_visited_int(newname, S_FALSE);
1825 SL_RETURN(i, _("sh_hash_set_visited_true"));
1826}
1827
1828
1829/******************************************************************
1830 *
1831 * Data entry for arbitrary data into database
1832 *
1833 ******************************************************************/
1834
1835static char * sh_hash_charhex( unsigned char i )
1836{
1837 static char i2h[2];
1838 int j, k;
1839
1840 j = i / 16;
1841 k = i - (j*16);
1842
1843 if (j < 10) i2h[0] = '0'+j;
1844 else i2h[0] = 'A'+(j-10);
1845
1846 if (k < 10) i2h[1] = '0'+k;
1847 else i2h[1] = 'A'+(k-10);
1848
1849 return i2h;
1850}
1851
1852void sh_hash_push2db (char * key, unsigned long val1,
1853 unsigned long val2, unsigned long val3,
1854 unsigned char * str, int size)
1855{
1856 file_type tmpFile;
1857 int i = 0;
1858 char * p;
1859
1860 sl_strlcpy(tmpFile.fullpath, key, PATH_MAX);
1861 tmpFile.size = val1;
1862 tmpFile.mtime = val2;
1863 tmpFile.ctime = val3;
1864
1865 tmpFile.atime = 0;
1866 tmpFile.mode = 0;
1867 tmpFile.owner = 0;
1868 tmpFile.group = 0;
1869 sl_strlcpy(tmpFile.c_owner, _("root"), 5);
1870 sl_strlcpy(tmpFile.c_group, _("root"), 5);
1871
1872 if ((str != NULL) && (size < (PATH_MAX/2)-1))
1873 {
1874 tmpFile.c_mode[0] = 'l';
1875 tmpFile.c_mode[1] = 'r'; tmpFile.c_mode[2] = 'w';
1876 tmpFile.c_mode[3] = 'x'; tmpFile.c_mode[4] = 'r';
1877 tmpFile.c_mode[5] = 'w'; tmpFile.c_mode[6] = 'x';
1878 tmpFile.c_mode[7] = 'r'; tmpFile.c_mode[8] = 'w';
1879 tmpFile.c_mode[9] = 'x'; tmpFile.c_mode[10] = '\0';
1880 for (i = 0; i < size; ++i)
1881 {
1882 p = sh_hash_charhex (str[i]);
1883 tmpFile.linkpath[2*i] = p[0];
1884 tmpFile.linkpath[2*i+1] = p[1];
1885 tmpFile.linkpath[2*i+2] = '\0';
1886 }
1887 }
1888 else
1889 {
1890 tmpFile.c_mode[0] = '-';
1891 tmpFile.c_mode[1] = '-'; tmpFile.c_mode[2] = '-';
1892 tmpFile.c_mode[3] = '-'; tmpFile.c_mode[4] = '-';
1893 tmpFile.c_mode[5] = '-'; tmpFile.c_mode[6] = '-';
1894 tmpFile.c_mode[7] = '-'; tmpFile.c_mode[8] = '-';
1895 tmpFile.c_mode[9] = '-'; tmpFile.c_mode[10] = '\0';
1896 tmpFile.linkpath[0] = '-'; tmpFile.linkpath[1] = '\0';
1897 }
1898
1899 if (sh.flag.checkSum == SH_CHECK_CHECK &&
1900 sh.flag.update == S_TRUE)
1901 sh_hash_pushdata_memory (&tmpFile,
1902 _("000000000000000000000000000000000000000000000000"));
1903 else
1904 sh_hash_pushdata (&tmpFile,
1905 _("000000000000000000000000000000000000000000000000"));
1906
1907 return;
1908}
1909
1910extern int sh_util_hextobinary (char * binary, char * hex, int bytes);
1911
1912char * sh_hash_db2pop (char * key, unsigned long * val1,
1913 unsigned long * val2, unsigned long * val3,
1914 int * size)
1915{
1916 file_type tmpFile;
1917 size_t len;
1918 char * p;
1919 int i;
1920
1921 *size = 0;
1922
1923 if (0 == sh_hash_get_it (key, &tmpFile))
1924 {
1925 *val1 = tmpFile.size;
1926 *val2 = tmpFile.mtime;
1927 *val3 = tmpFile.ctime;
1928
1929 if (tmpFile.linkpath[0] != '-')
1930 {
1931 len = strlen(tmpFile.linkpath);
1932
1933 p = SH_ALLOC((len/2)+1);
1934 i = sh_util_hextobinary (p, tmpFile.linkpath, len);
1935
1936 if (i == 0)
1937 {
1938 *size = (len/2);
1939 p[*size] = '\0';
1940 return p;
1941 }
1942 else
1943 {
1944 SH_FREE(p);
1945 *size = 0;
1946 return NULL;
1947 }
1948 }
1949 else
1950 {
1951 *size = 0;
1952 return NULL;
1953 }
1954 }
1955 else
1956 {
1957 *size = -1;
1958 *val1 = 0;
1959 *val2 = 0;
1960 *val3 = 0;
1961 return NULL;
1962 }
1963}
1964
1965
1966
1967
1968/******************************************************************
1969 *
1970 * Data entry in hash table
1971 *
1972 ******************************************************************/
1973sh_file_t * sh_hash_push_int (file_type * buf, char * fileHash)
1974{
1975 sh_file_t * fp;
1976 sh_filestore_t p;
1977
1978 size_t len;
1979 char * fullpath;
1980 char * linkpath;
1981
1982 SL_ENTER(_("sh_hash_push_int"));
1983
1984 fp = SH_ALLOC(sizeof(sh_file_t));
1985
1986 p.mark = REC_MAGIC;
1987 sl_strlcpy(p.c_mode, buf->c_mode, 11);
1988 sl_strlcpy(p.c_group, buf->c_group, GROUP_MAX+1);
1989 sl_strlcpy(p.c_owner, buf->c_owner, USER_MAX+1);
1990 sl_strlcpy(p.checksum, fileHash, KEY_LEN+1);
1991#if defined(__linux__) || defined(HAVE_STAT_FLAGS)
1992 sl_strlcpy(p.c_attributes, buf->c_attributes, 13);
1993#endif
1994
1995#if defined(__linux__) || defined(HAVE_STAT_FLAGS)
1996 p.attributes = (UINT32) buf->attributes;
1997#endif
1998 p.linkmode = (UINT32) buf->linkmode;
1999 p.hardlinks = (UINT32) buf->hardlinks;
2000 p.dev = (UINT64) buf->dev;
2001 p.rdev = (UINT64) buf->rdev;
2002 p.mode = (UINT32) buf->mode;
2003 p.ino = (UINT32) buf->ino;
2004 p.size = (UINT64) buf->size;
2005 p.mtime = (UINT64) buf->mtime;
2006 p.atime = (UINT64) buf->atime;
2007 p.ctime = (UINT64) buf->ctime;
2008 p.owner = (UINT32) buf->owner;
2009 p.group = (UINT32) buf->group;
2010
2011 memcpy( &(*fp).theFile, &p, sizeof(sh_filestore_t) );
2012 fp->visited = S_FALSE;
2013 fp->reported = S_FALSE;
2014 fp->allignore = S_FALSE;
2015 fp->modi_mask = 0L;
2016
2017 len = sl_strlen(buf->fullpath);
2018 if (len <= MAX_PATH_STORE)
2019 {
2020 fullpath = SH_ALLOC(len+1);
2021 sl_strlcpy(fullpath, buf->fullpath, len+1);
2022 }
2023 else
2024 {
2025 fullpath = SH_ALLOC(KEY_LEN + 1);
2026 sl_strlcpy(fullpath,
2027 sh_tiger_hash (buf->fullpath, TIGER_DATA, len),
2028 KEY_LEN+1);
2029 }
2030 fp->fullpath = fullpath;
2031
2032 if (buf->c_mode[0] == 'l')
2033 {
2034 len = sl_strlen(buf->linkpath);
2035 if (len <= MAX_PATH_STORE)
2036 {
2037 linkpath = SH_ALLOC(len+1);
2038 sl_strlcpy(linkpath, buf->linkpath, len+1);
2039 }
2040 else
2041 {
2042 linkpath = SH_ALLOC(KEY_LEN + 1);
2043 sl_strlcpy(linkpath,
2044 sh_tiger_hash (buf->linkpath, TIGER_DATA, len),
2045 KEY_LEN+1);
2046 }
2047 fp->linkpath = linkpath;
2048 }
2049 else
2050 fp->linkpath = NULL;
2051
2052 SL_RETURN( fp, _("sh_hash_push_int"));
2053}
2054
2055#ifdef HAVE_INTTYPES_H
2056#include <inttypes.h>
2057#else
2058#ifdef HAVE_STDINT_H
2059#include <stdint.h>
2060#endif
2061#endif
2062
2063#ifndef PRIu64
2064#ifdef HAVE_LONG_32
2065#define PRIu64 "llu"
2066#else
2067#define PRIu64 "lu"
2068#endif
2069#endif
2070
2071char * sh_hash_size_format()
2072{
2073 static char form_rval[81];
2074
2075 SL_ENTER(_("sh_hash_size_format"));
2076
2077
2078#ifdef SH_USE_XML
2079 sl_snprintf(form_rval, 80, _("%s%s%s%s%s"),
2080 _("size_old=\"%"), PRIu64, _("\" size_new=\"%"), PRIu64, "\" ");
2081#else
2082 sl_snprintf(form_rval, 80, _("%s%s%s%s%s"),
2083 _("size_old=<%"), PRIu64, _(">, size_new=<%"), PRIu64, ">, ");
2084#endif
2085
2086 SL_RETURN( form_rval, _("sh_hash_size_format"));
2087}
2088
2089
2090#ifdef SH_USE_XML
2091static char * all_items (file_type * theFile, char * fileHash, int is_new)
2092{
2093 char timstr1c[32];
2094 char timstr1a[32];
2095 char timstr1m[32];
2096
2097 char * tmp_lnk;
2098 char * format;
2099
2100 char * tmp = SH_ALLOC(SH_BUFSIZE);
2101 char * msg = SH_ALLOC(SH_BUFSIZE);
2102
2103 tmp[0] = '\0';
2104 msg[0] = '\0';
2105
2106
2107#if defined(__linux__) || defined(HAVE_STAT_FLAGS)
2108 if (is_new)
2109 format = _("mode_new=\"%s\" attr_new=\"%s\" imode_new=\"%ld\" iattr_new=\"%ld\" ");
2110 else
2111 format = _("mode_old=\"%s\" attr_old=\"%s\" imode_old=\"%ld\" iattr_old=\"%ld\" ");
2112 sl_snprintf(tmp, SH_BUFSIZE, format,
2113 theFile->c_mode,
2114 theFile->c_attributes,
2115 (long) theFile->mode,
2116 (long) theFile->attributes
2117 );
2118#else
2119 if (is_new)
2120 format = _("mode_new=\"%s\" imode_new=\"%ld\" ");
2121 else
2122 format = _("mode_old=\"%s\" imode_old=\"%ld\" ");
2123
2124 sl_snprintf(tmp, SH_BUFSIZE, format,
2125 theFile->c_mode,
2126 (long) theFile->mode
2127 );
2128#endif
2129 sl_strlcat(msg, tmp, SH_BUFSIZE);
2130
2131 if (is_new)
2132 format = _("hardlinks_new=\"%lu\" ");
2133 else
2134 format = _("hardlinks_old=\"%lu\" ");
2135 sl_snprintf(tmp, SH_BUFSIZE, format,
2136 (unsigned long) theFile->hardlinks);
2137 sl_strlcat(msg, tmp, SH_BUFSIZE);
2138
2139
2140 if (is_new)
2141 format = _("idevice_new=\"%lu\" ");
2142 else
2143 format = _("idevice_old=\"%lu\" ");
2144 sl_snprintf(tmp, SH_BUFSIZE, format, (unsigned long) theFile->rdev);
2145 sl_strlcat(msg, tmp, SH_BUFSIZE);
2146
2147
2148 if (is_new)
2149 format = _("inode_new=\"%lu\" ");
2150 else
2151 format = _("inode_old=\"%lu\" ");
2152 sl_snprintf(tmp, SH_BUFSIZE, format, (unsigned long) theFile->ino);
2153 sl_strlcat(msg, tmp, SH_BUFSIZE);
2154
2155 /*
2156 * also report device for prelude
2157 */
2158#if defined(HAVE_LIBPRELUDE) && defined(HAVE_LIBPRELUDE_9)
2159 if (is_new)
2160 format = _("dev_new=\"%lu,%lu\" ");
2161 else
2162 format = _("dev_old=\"%lu,%lu\" ");
2163 sl_snprintf(tmp, SH_BUFSIZE, format,
2164 (unsigned long) major(theFile->dev),
2165 (unsigned long) minor(theFile->dev));
2166 sl_strlcat(msg, tmp, SH_BUFSIZE);
2167#endif
2168
2169
2170 if (is_new)
2171 format = _("owner_new=\"%s\" iowner_new=\"%ld\" ");
2172 else
2173 format = _("owner_old=\"%s\" iowner_old=\"%ld\" ");
2174 sl_snprintf(tmp, SH_BUFSIZE, format,
2175 theFile->c_owner, (long) theFile->owner);
2176 sl_strlcat(msg, tmp, SH_BUFSIZE);
2177
2178
2179 if (is_new)
2180 format = _("group_new=\"%s\" igroup_new=\"%ld\" ");
2181 else
2182 format = _("group_old=\"%s\" igroup_old=\"%ld\" ");
2183 sl_snprintf(tmp, SH_BUFSIZE, format,
2184 theFile->c_group, (long) theFile->group);
2185 sl_strlcat(msg, tmp, SH_BUFSIZE);
2186
2187
2188 if (is_new)
2189 sl_snprintf(tmp, SH_BUFSIZE, sh_hash_size_format(),
2190 (UINT64) 0, (UINT64) theFile->size);
2191 else
2192 sl_snprintf(tmp, SH_BUFSIZE, sh_hash_size_format(),
2193 (UINT64) theFile->size, (UINT64) 0);
2194 sl_strlcat(msg, tmp, SH_BUFSIZE);
2195
2196
2197 sl_strlcpy (timstr1c, sh_unix_gmttime (theFile->ctime), 32);
2198 if (is_new)
2199 sl_snprintf(tmp, SH_BUFSIZE, _("ctime_new=\"%s\" "), timstr1c);
2200 else
2201 sl_snprintf(tmp, SH_BUFSIZE, _("ctime_old=\"%s\" "), timstr1c);
2202 sl_strlcat(msg, tmp, SH_BUFSIZE);
2203
2204 sl_strlcpy (timstr1a, sh_unix_gmttime (theFile->atime), 32);
2205 if (is_new)
2206 sl_snprintf(tmp, SH_BUFSIZE, _("atime_new=\"%s\" "), timstr1a);
2207 else
2208 sl_snprintf(tmp, SH_BUFSIZE, _("atime_old=\"%s\" "), timstr1a);
2209 sl_strlcat(msg, tmp, SH_BUFSIZE);
2210
2211 sl_strlcpy (timstr1m, sh_unix_gmttime (theFile->mtime), 32);
2212 if (is_new)
2213 sl_snprintf(tmp, SH_BUFSIZE, _("mtime_new=\"%s\" "), timstr1m);
2214 else
2215 sl_snprintf(tmp, SH_BUFSIZE, _("mtime_old=\"%s\" "), timstr1m);
2216 sl_strlcat(msg, tmp, SH_BUFSIZE);
2217
2218 if (is_new)
2219 sl_snprintf(tmp, SH_BUFSIZE, _("chksum_new=\"%s\" "), fileHash);
2220 else
2221 sl_snprintf(tmp, SH_BUFSIZE, _("chksum_old=\"%s\" "), fileHash);
2222 sl_strlcat(msg, tmp, SH_BUFSIZE);
2223
2224 if (theFile->c_mode[0] == 'l')
2225 {
2226 tmp_lnk = sh_util_safe_name(theFile->linkpath);
2227 if (tmp_lnk)
2228 {
2229 if (is_new)
2230 sl_snprintf(tmp, SH_BUFSIZE, _("link_new=\"%s\" "), tmp_lnk);
2231 else
2232 sl_snprintf(tmp, SH_BUFSIZE, _("link_old=\"%s\" "), tmp_lnk);
2233 SH_FREE(tmp_lnk);
2234 sl_strlcat(msg, tmp, SH_BUFSIZE);
2235 }
2236 }
2237
2238 SH_FREE(tmp);
2239 return (msg);
2240}
2241#else
2242static char * all_items (file_type * theFile, char * fileHash, int is_new)
2243{
2244 char timstr1c[32];
2245 char timstr1a[32];
2246 char timstr1m[32];
2247
2248 char * tmp_lnk;
2249 char * format;
2250
2251 char * tmp = SH_ALLOC(SH_BUFSIZE);
2252 char * msg = SH_ALLOC(SH_BUFSIZE);
2253
2254 tmp[0] = '\0';
2255 msg[0] = '\0';
2256
2257
2258#if defined(__linux__) || defined(HAVE_STAT_FLAGS)
2259 if (is_new)
2260 format = _("mode_new=<%s>, attr_new=<%s>, imode_new=<%ld>, iattr_new=<%ld>, ");
2261 else
2262 format = _("mode_old=<%s>, attr_old=<%s>, imode_old=<%ld>, iattr_old=<%ld>, ");
2263 sl_snprintf(tmp, SH_BUFSIZE, format,
2264 theFile->c_mode,
2265 theFile->c_attributes,
2266 (long) theFile->mode,
2267 (long) theFile->attributes
2268 );
2269#else
2270 if (is_new)
2271 format = _("mode_new=<%s>, imode_new=<%ld>, ");
2272 else
2273 format = _("mode_old=<%s>, imode_old=<%ld>, ");
2274
2275 sl_snprintf(tmp, SH_BUFSIZE, format,
2276 theFile->c_mode,
2277 (long) theFile->mode
2278 );
2279#endif
2280 sl_strlcat(msg, tmp, SH_BUFSIZE);
2281
2282 if (is_new)
2283 format = _("hardlinks_new=<%lu>, ");
2284 else
2285 format = _("hardlinks_old=<%lu>, ");
2286 sl_snprintf(tmp, SH_BUFSIZE, format,
2287 (unsigned long) theFile->hardlinks);
2288 sl_strlcat(msg, tmp, SH_BUFSIZE);
2289
2290
2291 if (is_new)
2292 format = _("idevice_new=<%lu>, ");
2293 else
2294 format = _("idevice_old=<%lu>, ");
2295 sl_snprintf(tmp, SH_BUFSIZE, format, (unsigned long) theFile->rdev);
2296 sl_strlcat(msg, tmp, SH_BUFSIZE);
2297
2298
2299 if (is_new)
2300 format = _("inode_new=<%lu>, ");
2301 else
2302 format = _("inode_old=<%lu>, ");
2303 sl_snprintf(tmp, SH_BUFSIZE, format, (unsigned long) theFile->ino);
2304 sl_strlcat(msg, tmp, SH_BUFSIZE);
2305
2306
2307 /*
2308 * also report device for prelude
2309 */
2310#if defined(HAVE_LIBPRELUDE) && defined(HAVE_LIBPRELUDE_9)
2311 if (is_new)
2312 format = _("dev_new=<%lu,%lu>, ");
2313 else
2314 format = _("dev_old=<%lu,%lu>, ");
2315 sl_snprintf(tmp, SH_BUFSIZE, format,
2316 (unsigned long) major(theFile->dev),
2317 (unsigned long) minor(theFile->dev));
2318 sl_strlcat(msg, tmp, SH_BUFSIZE);
2319#endif
2320
2321 if (is_new)
2322 format = _("owner_new=<%s>, iowner_new=<%ld>, ");
2323 else
2324 format = _("owner_old=<%s>, iowner_old=<%ld>, ");
2325 sl_snprintf(tmp, SH_BUFSIZE, format,
2326 theFile->c_owner, (long) theFile->owner);
2327 sl_strlcat(msg, tmp, SH_BUFSIZE);
2328
2329
2330 if (is_new)
2331 format = _("group_new=<%s>, igroup_new=<%ld>, ");
2332 else
2333 format = _("group_old=<%s>, igroup_old=<%ld>, ");
2334 sl_snprintf(tmp, SH_BUFSIZE, format,
2335 theFile->c_group, (long) theFile->group);
2336 sl_strlcat(msg, tmp, SH_BUFSIZE);
2337
2338
2339 if (is_new)
2340 sl_snprintf(tmp, SH_BUFSIZE, sh_hash_size_format(),
2341 (UINT64) 0, (UINT64) theFile->size);
2342 else
2343 sl_snprintf(tmp, SH_BUFSIZE, sh_hash_size_format(),
2344 (UINT64) theFile->size, (UINT64) 0);
2345 sl_strlcat(msg, tmp, SH_BUFSIZE);
2346
2347
2348 sl_strlcpy (timstr1c, sh_unix_gmttime (theFile->ctime), 32);
2349 if (is_new)
2350 sl_snprintf(tmp, SH_BUFSIZE, _("ctime_new=<%s>, "), timstr1c);
2351 else
2352 sl_snprintf(tmp, SH_BUFSIZE, _("ctime_old=<%s>, "), timstr1c);
2353 sl_strlcat(msg, tmp, SH_BUFSIZE);
2354
2355 sl_strlcpy (timstr1a, sh_unix_gmttime (theFile->atime), 32);
2356 if (is_new)
2357 sl_snprintf(tmp, SH_BUFSIZE, _("atime_new=<%s>, "), timstr1a);
2358 else
2359 sl_snprintf(tmp, SH_BUFSIZE, _("atime_old=<%s>, "), timstr1a);
2360 sl_strlcat(msg, tmp, SH_BUFSIZE);
2361
2362 sl_strlcpy (timstr1m, sh_unix_gmttime (theFile->mtime), 32);
2363 if (is_new)
2364 sl_snprintf(tmp, SH_BUFSIZE, _("mtime_new=<%s>, "), timstr1m);
2365 else
2366 sl_snprintf(tmp, SH_BUFSIZE, _("mtime_old=<%s>, "), timstr1m);
2367 sl_strlcat(msg, tmp, SH_BUFSIZE);
2368
2369 if (is_new)
2370 sl_snprintf(tmp, SH_BUFSIZE, _("chksum_new=<%s>"), fileHash);
2371 else
2372 sl_snprintf(tmp, SH_BUFSIZE, _("chksum_old=<%s>"), fileHash);
2373 sl_strlcat(msg, tmp, SH_BUFSIZE);
2374
2375 if (theFile->c_mode[0] == 'l')
2376 {
2377 tmp_lnk = sh_util_safe_name(theFile->linkpath);
2378 if (tmp_lnk)
2379 {
2380 if (is_new)
2381 sl_snprintf(tmp, SH_BUFSIZE, _(", link_new=<%s> "), tmp_lnk);
2382 else
2383 sl_snprintf(tmp, SH_BUFSIZE, _(", link_old=<%s> "), tmp_lnk);
2384 SH_FREE(tmp_lnk);
2385 sl_strlcat(msg, tmp, SH_BUFSIZE);
2386 }
2387 }
2388
2389 SH_FREE(tmp);
2390 return (msg);
2391}
2392#endif
2393
2394void sh_hash_pushdata_memory (file_type * theFile, char * fileHash)
2395{
2396 sh_file_t * p;
2397
2398 SL_ENTER(_("sh_hash_pushdata_memory"));
2399
2400 p = sh_hash_push_int(theFile, fileHash);
2401 if (p)
2402 {
2403 hashinsert (p);
2404 p->modi_mask = theFile->check_mask;
2405 }
2406
2407 SL_RET0(_("sh_hash_pushdata_memory"));
2408}
2409
2410
2411/*****************************************************************
2412 *
2413 * Compare a file with the database status.
2414 *
2415 *****************************************************************/
2416int sh_hash_compdata (int class, file_type * theFile, char * fileHash,
2417 char * policy_override, int severity_override)
2418{
2419 char * msg;
2420 sh_file_t * p;
2421 char * tmp;
2422 char * tmp_path;
2423 char * tmp_lnk;
2424 char * tmp_lnk_old;
2425
2426 char * str;
2427
2428 char timstr1c[32];
2429 char timstr2c[32];
2430 char timstr1a[32];
2431 char timstr2a[32];
2432 char timstr1m[32];
2433 char timstr2m[32];
2434 char linkHash[KEY_LEN+1];
2435 int maxcomp;
2436
2437 char change_code[16];
2438 int i;
2439
2440 unsigned long modi_mask = 0;
2441
2442 char log_policy[32];
2443 int log_severity;
2444
2445 SL_ENTER(_("sh_hash_compdata"));
2446
2447 if (IsInit != 1) sh_hash_init();
2448
2449 if (severity_override < 0)
2450 log_severity = ShDFLevel[class];
2451 else
2452 log_severity = severity_override;
2453
2454 if (policy_override != NULL)
2455 sl_strlcpy (log_policy, policy_override, 32);
2456
2457 /* -------- find the entry for the file ---------------- */
2458
2459 if (sl_strlen(theFile->fullpath) <= MAX_PATH_STORE)
2460 p = hashsearch(theFile->fullpath);
2461 else
2462 p = hashsearch( sh_tiger_hash(theFile->fullpath,
2463 TIGER_DATA,
2464 sl_strlen(theFile->fullpath))
2465 );
2466
2467
2468 /* --------- Not found in database. ------------
2469 */
2470
2471 if (p == NULL)
2472 {
2473 if (sh.flag.reportonce == S_TRUE)
2474 {
2475 p = sh_hash_push_int(theFile, fileHash);
2476 hashinsert (p);
2477 if (p)
2478 p->modi_mask = theFile->check_mask;
2479
2480 }
2481
2482 if (S_FALSE == sh_ignore_chk_new(theFile->fullpath))
2483 {
2484 tmp = sh_util_safe_name(theFile->fullpath);
2485
2486 str = all_items (theFile, fileHash, 1);
2487 sh_error_handle (log_severity, FIL__, __LINE__, 0,
2488 MSG_FI_ADD2,
2489 tmp, str);
2490 SH_FREE(str);
2491
2492 SH_FREE(tmp);
2493 }
2494
2495 if (p)
2496 p->visited = S_TRUE;
2497 if (sh.flag.reportonce == S_TRUE)
2498 theFile->reported = S_TRUE;
2499
2500 if (sh.flag.isdaemon == S_FALSE && sh.flag.update == S_TRUE )
2501 {
2502 if (S_FALSE == sh_util_ask_update (theFile->fullpath))
2503 {
2504 SL_RETURN(1, _("sh_hash_compdata"));
2505 }
2506 }
2507 SL_RETURN(0, _("sh_hash_compdata"));
2508 }
2509 else
2510 {
2511 p->modi_mask = theFile->check_mask;
2512 }
2513
2514 /* initialize change_code */
2515 for (i = 0; i < 15; ++i)
2516 change_code[i] = '-';
2517 change_code[15] = '\0';
2518
2519 TPT ((0, FIL__, __LINE__, _("file=<%s>, cs_old=<%s>, cs_new=<%s>\n"),
2520 theFile->fullpath, fileHash, p->theFile.checksum));
2521
2522 if ( (fileHash != NULL) && (p->theFile.checksum != NULL) &&
2523 (strncmp (fileHash, p->theFile.checksum, KEY_LEN) != 0) &&
2524 (theFile->check_mask & MODI_CHK) != 0)
2525 {
2526 if ((theFile->check_mask & MODI_SGROW) == 0)
2527 {
2528 modi_mask |= MODI_CHK;
2529 change_code[0] = 'C';
2530 TPT ((0, FIL__, __LINE__, _("mod=<checksum>")));
2531 }
2532 else
2533 {
2534 if (0 != strncmp (&fileHash[KEY_LEN + 1],
2535 p->theFile.checksum, KEY_LEN))
2536 {
2537 modi_mask |= MODI_CHK;
2538 change_code[0] = 'C';
2539 TPT ((0, FIL__, __LINE__, _("mod=<checksum>")));
2540 }
2541 else
2542 {
2543 p->theFile.size = theFile->size;
2544 sl_strlcpy(p->theFile.checksum, fileHash, KEY_LEN+1);
2545 }
2546 }
2547 }
2548
2549 if (p->theFile.c_mode[0] == 'l')
2550 {
2551 if (sl_strlen(theFile->linkpath) >= MAX_PATH_STORE)
2552 {
2553 sl_strlcpy(linkHash,
2554 sh_tiger_hash(theFile->linkpath,
2555 TIGER_DATA,
2556 sl_strlen(theFile->linkpath)),
2557 MAX_PATH_STORE+1);
2558 maxcomp = MAX_PATH_STORE;
2559 }
2560 else
2561 {
2562 sl_strlcpy(linkHash, theFile->linkpath, KEY_LEN + 1);
2563 maxcomp = KEY_LEN;
2564 }
2565
2566 if ( sl_strncmp (linkHash, p->linkpath, maxcomp) != 0 &&
2567 (theFile->check_mask & MODI_LNK) != 0)
2568 {
2569 modi_mask |= MODI_LNK;
2570 change_code[1] = 'L';
2571 TPT ((0, FIL__, __LINE__, _("mod=<link>")));
2572 }
2573 }
2574
2575 if (p->theFile.c_mode[0] == 'c' || p->theFile.c_mode[0] == 'b')
2576 {
2577 if ( ( major(theFile->rdev) != major((dev_t)p->theFile.rdev) ||
2578 minor(theFile->rdev) != minor((dev_t)p->theFile.rdev) ) &&
2579 (theFile->check_mask & MODI_RDEV) != 0)
2580 {
2581 modi_mask |= MODI_RDEV;
2582 change_code[2] = 'D';
2583 TPT ((0, FIL__, __LINE__, _("mod=<rdev>")));
2584 }
2585 }
2586
2587 /* cast to UINT32 in case ino_t is not 32bit
2588 */
2589 if ( (UINT32) theFile->ino != (UINT32) p->theFile.ino &&
2590 (theFile->check_mask & MODI_INO) != 0)
2591 {
2592 modi_mask |= MODI_INO;
2593 change_code[3] = 'I';
2594 TPT ((0, FIL__, __LINE__, _("mod=<inode>")));
2595 }
2596
2597 if ( theFile->hardlinks != (nlink_t) p->theFile.hardlinks &&
2598 (theFile->check_mask & MODI_HLN) != 0)
2599 {
2600 modi_mask |= MODI_HLN;
2601 change_code[4] = 'H';
2602 TPT ((0, FIL__, __LINE__, _("mod=<hardlink>")));
2603 }
2604
2605
2606 if ( ( (theFile->mode != p->theFile.mode)
2607#if defined(__linux__) || defined(HAVE_STAT_FLAGS)
2608 || (theFile->attributes != p->theFile.attributes)
2609#endif
2610 )
2611 && (theFile->check_mask & MODI_MOD) != 0)
2612 {
2613 modi_mask |= MODI_MOD;
2614 change_code[5] = 'M';
2615 TPT ((0, FIL__, __LINE__, _("mod=<mode>")));
2616 /*
2617 * report link path if switch link/no link
2618 */
2619 if ((theFile->check_mask & MODI_LNK) != 0 &&
2620 (theFile->c_mode[0] != p->theFile.c_mode[0]) &&
2621 (theFile->c_mode[0] == 'l' || p->theFile.c_mode[0] == 'l'))
2622 {
2623 modi_mask |= MODI_LNK;
2624 change_code[1] = 'L';
2625 TPT ((0, FIL__, __LINE__, _("mod=<link>")));
2626 }
2627 }
2628
2629 if ( theFile->owner != (uid_t) p->theFile.owner &&
2630 (theFile->check_mask & MODI_USR) != 0)
2631 {
2632 modi_mask |= MODI_USR;
2633 change_code[6] = 'U';
2634 TPT ((0, FIL__, __LINE__, _("mod=<user>")));
2635 }
2636
2637 if ( theFile->group != (gid_t) p->theFile.group &&
2638 (theFile->check_mask & MODI_GRP) != 0)
2639 {
2640 modi_mask |= MODI_GRP;
2641 change_code[7] = 'G';
2642 TPT ((0, FIL__, __LINE__, _("mod=<group>")));
2643 }
2644
2645
2646 if ( theFile->mtime != (time_t) p->theFile.mtime &&
2647 (theFile->check_mask & MODI_MTM) != 0)
2648 {
2649 modi_mask |= MODI_MTM;
2650 change_code[8] = 'T';
2651 TPT ((0, FIL__, __LINE__, _("mod=<mtime>")));
2652 }
2653
2654 if ( theFile->atime != (time_t) p->theFile.atime &&
2655 (theFile->check_mask & MODI_ATM) != 0)
2656 {
2657 modi_mask |= MODI_ATM;
2658 change_code[8] = 'T';
2659 TPT ((0, FIL__, __LINE__, _("mod=<atime>")));
2660 }
2661
2662
2663 /* Resetting the access time will set a new ctime. Thus, either we ignore
2664 * the access time or the ctime for NOIGNORE
2665 */
2666 if ( theFile->ctime != (time_t) p->theFile.ctime &&
2667 (theFile->check_mask & MODI_CTM) != 0)
2668 {
2669 modi_mask |= MODI_CTM;
2670 change_code[8] = 'T';
2671 TPT ((0, FIL__, __LINE__, _("mod=<ctime>")));
2672 }
2673
2674 if ( theFile->size != (off_t) p->theFile.size &&
2675 (theFile->check_mask & MODI_SIZ) != 0)
2676 {
2677 if ((theFile->check_mask & MODI_SGROW) == 0 ||
2678 theFile->size < (off_t) p->theFile.size)
2679 {
2680 modi_mask |= MODI_SIZ;
2681 change_code[9] = 'S';
2682 TPT ((0, FIL__, __LINE__, _("mod=<size>")));
2683 }
2684 }
2685 change_code[10] = '\0';
2686
2687 /* --- Report full details. ---
2688 */
2689 if (modi_mask != 0 && sh.flag.fulldetail == S_TRUE)
2690 {
2691 if ((theFile->check_mask & MODI_ATM) == 0)
2692 modi_mask = MASK_READONLY_;
2693 else
2694 modi_mask = MASK_NOIGNORE_;
2695 }
2696
2697 /* --- Report on modified files. ---
2698 */
2699 if (modi_mask != 0 && p->reported == S_FALSE)
2700 {
2701 tmp = SH_ALLOC(SH_BUFSIZE);
2702 msg = SH_ALLOC(SH_BUFSIZE);
2703 msg[0] = '\0';
2704
2705 if ( ((modi_mask & MODI_MOD) != 0)
2706#if defined(HAVE_LIBPRELUDE) && defined(HAVE_LIBPRELUDE_9)
2707 || ((modi_mask & MODI_USR) != 0)
2708 || ((modi_mask & MODI_GRP) != 0)
2709#endif
2710 )
2711 {
2712#if defined(__linux__) || defined(HAVE_STAT_FLAGS)
2713 sl_snprintf(tmp, SH_BUFSIZE,
2714#ifdef SH_USE_XML
2715 _("mode_old=\"%s\" mode_new=\"%s\" attr_old=\"%s\" attr_new=\"%s\" imode_old=\"%ld\" imode_new=\"%ld\" iattr_old=\"%ld\" iattr_new=\"%ld\" "),
2716#else
2717 _("mode_old=<%s>, mode_new=<%s>, attr_old=<%s>, attr_new=<%s>, "),
2718#endif
2719 p->theFile.c_mode, theFile->c_mode,
2720 p->theFile.c_attributes, theFile->c_attributes
2721#ifdef SH_USE_XML
2722 , (long) p->theFile.mode, (long) theFile->mode,
2723 (long) p->theFile.attributes,
2724 (long) theFile->attributes
2725#endif
2726 );
2727#else
2728#ifdef SH_USE_XML
2729 sl_snprintf(tmp, SH_BUFSIZE,
2730 _("mode_old=\"%s\" mode_new=\"%s\" imode_old=\"%ld\" imode_new=\"%ld\" "),
2731#else
2732 sl_snprintf(tmp, SH_BUFSIZE, _("mode_old=<%s>, mode_new=<%s>, "),
2733#endif
2734 p->theFile.c_mode, theFile->c_mode
2735#ifdef SH_USE_XML
2736 , (long) p->theFile.mode, (long) theFile->mode
2737#endif
2738 );
2739#endif
2740 sl_strlcat(msg, tmp, SH_BUFSIZE);
2741#ifdef REPLACE_OLD
2742 if ((modi_mask & MODI_MOD) != 0)
2743 {
2744 /*
2745 * We postpone update if sh.flag.update == S_TRUE because
2746 * in interactive mode the user may not accept the change.
2747 */
2748 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
2749 {
2750 sl_strlcpy(p->theFile.c_mode, theFile->c_mode, 11);
2751 p->theFile.mode = theFile->mode;
2752#if defined(__linux__) || defined(HAVE_STAT_FLAGS)
2753 sl_strlcpy(p->theFile.c_attributes,theFile->c_attributes,16);
2754 p->theFile.attributes = theFile->attributes;
2755#endif
2756 }
2757 }
2758#endif
2759 }
2760
2761 if ((modi_mask & MODI_HLN) != 0)
2762 {
2763 sl_snprintf(tmp, SH_BUFSIZE,
2764#ifdef SH_USE_XML
2765 _("hardlinks_old=\"%lu\" hardlinks_new=\"%lu\" "),
2766#else
2767 _("hardlinks_old=<%lu>, hardlinks_new=<%lu>, "),
2768#endif
2769 (unsigned long) p->theFile.hardlinks,
2770 (unsigned long) theFile->hardlinks);
2771 sl_strlcat(msg, tmp, SH_BUFSIZE);
2772#ifdef REPLACE_OLD
2773 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
2774 p->theFile.hardlinks = theFile->hardlinks;
2775#endif
2776 }
2777
2778 if ((modi_mask & MODI_RDEV) != 0)
2779 {
2780 sl_snprintf(tmp, SH_BUFSIZE,
2781#ifdef SH_USE_XML
2782 _("device_old=\"%lu,%lu\" device_new=\"%lu,%lu\" idevice_old=\"%lu\" idevice_new=\"%lu\" "),
2783#else
2784 _("device_old=<%lu,%lu>, device_new=<%lu,%lu>, "),
2785#endif
2786 (unsigned long) major(p->theFile.rdev),
2787 (unsigned long) minor(p->theFile.rdev),
2788 (unsigned long) major(theFile->rdev),
2789 (unsigned long) minor(theFile->rdev)
2790#ifdef SH_USE_XML
2791 , (unsigned long) p->theFile.rdev,
2792 (unsigned long) theFile->rdev
2793#endif
2794 );
2795 sl_strlcat(msg, tmp, SH_BUFSIZE);
2796#ifdef REPLACE_OLD
2797 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
2798 p->theFile.rdev = theFile->rdev;
2799#endif
2800 }
2801
2802 if ((modi_mask & MODI_INO) != 0)
2803 {
2804 sl_snprintf(tmp, SH_BUFSIZE,
2805#ifdef SH_USE_XML
2806 _("inode_old=\"%lu\" inode_new=\"%lu\" "),
2807#else
2808 _("inode_old=<%lu>, inode_new=<%lu>, "),
2809#endif
2810 (unsigned long) p->theFile.ino,
2811 (unsigned long) theFile->ino);
2812 sl_strlcat(msg, tmp, SH_BUFSIZE);
2813#ifdef REPLACE_OLD
2814 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
2815 {
2816 p->theFile.ino = theFile->ino;
2817 p->theFile.dev = theFile->dev;
2818 }
2819#endif
2820 }
2821
2822
2823 /*
2824 * also report device for prelude
2825 */
2826#if defined(HAVE_LIBPRELUDE) && defined(HAVE_LIBPRELUDE_9)
2827 if ((modi_mask & MODI_INO) != 0)
2828 {
2829 sl_snprintf(tmp, SH_BUFSIZE,
2830#ifdef SH_USE_XML
2831 _("dev_old=\"%lu,%lu\" dev_new=\"%lu,%lu\" "),
2832#else
2833 _("dev_old=<%lu,%lu>, dev_new=<%lu,%lu>, "),
2834#endif
2835 (unsigned long) major(p->theFile.dev),
2836 (unsigned long) minor(p->theFile.dev),
2837 (unsigned long) major(theFile->dev),
2838 (unsigned long) minor(theFile->dev)
2839 );
2840 sl_strlcat(msg, tmp, SH_BUFSIZE);
2841#ifdef REPLACE_OLD
2842 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
2843 p->theFile.dev = theFile->dev;
2844#endif
2845 }
2846#endif
2847
2848 if ( ((modi_mask & MODI_USR) != 0)
2849#if defined(HAVE_LIBPRELUDE) && defined(HAVE_LIBPRELUDE_9)
2850 || ((modi_mask & MODI_MOD) != 0)
2851#endif
2852 )
2853 {
2854#ifdef SH_USE_XML
2855 sl_snprintf(tmp, SH_BUFSIZE,
2856 _("owner_old=\"%s\" owner_new=\"%s\" iowner_old=\"%ld\" iowner_new=\"%ld\" "),
2857#else
2858 sl_snprintf(tmp, SH_BUFSIZE,
2859 _("owner_old=<%s>, owner_new=<%s>, iowner_old=<%ld>, iowner_new=<%ld>, "),
2860#endif
2861 p->theFile.c_owner, theFile->c_owner,
2862 (long) p->theFile.owner, (long) theFile->owner
2863 );
2864 sl_strlcat(msg, tmp, SH_BUFSIZE);
2865#ifdef REPLACE_OLD
2866 if ((modi_mask & MODI_USR) != 0) {
2867 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
2868 {
2869 sl_strlcpy(p->theFile.c_owner, theFile->c_owner, USER_MAX+2);
2870 p->theFile.owner = theFile->owner;
2871 }
2872 }
2873#endif
2874 }
2875
2876 if ( ((modi_mask & MODI_GRP) != 0)
2877#if defined(HAVE_LIBPRELUDE) && defined(HAVE_LIBPRELUDE_9)
2878 || ((modi_mask & MODI_MOD) != 0)
2879#endif
2880 )
2881 {
2882#ifdef SH_USE_XML
2883 sl_snprintf(tmp, SH_BUFSIZE,
2884 _("group_old=\"%s\" group_new=\"%s\" igroup_old=\"%ld\" igroup_new=\"%ld\" "),
2885 p->theFile.c_group, theFile->c_group,
2886 (long) p->theFile.group, (long) theFile->group);
2887#else
2888 sl_snprintf(tmp, SH_BUFSIZE,
2889 _("group_old=<%s>, group_new=<%s>, igroup_old=<%ld>, igroup_new=<%ld>, "),
2890 p->theFile.c_group, theFile->c_group,
2891 (long) p->theFile.group, (long) theFile->group);
2892#endif
2893
2894 sl_strlcat(msg, tmp, SH_BUFSIZE);
2895#ifdef REPLACE_OLD
2896 if ((modi_mask & MODI_GRP) != 0) {
2897 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
2898 {
2899 sl_strlcpy(p->theFile.c_group, theFile->c_group, GROUP_MAX+2);
2900 p->theFile.group = theFile->group;
2901 }
2902 }
2903#endif
2904 }
2905
2906 if ((modi_mask & MODI_SIZ) != 0)
2907 {
2908 sl_snprintf(tmp, SH_BUFSIZE, sh_hash_size_format(),
2909 (UINT64) p->theFile.size,
2910 (UINT64) theFile->size);
2911 sl_strlcat(msg, tmp, SH_BUFSIZE);
2912#ifdef REPLACE_OLD
2913 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
2914 p->theFile.size = theFile->size;
2915#endif
2916 }
2917
2918 if ((modi_mask & MODI_CTM) != 0)
2919 {
2920 sl_strlcpy (timstr1c, sh_unix_gmttime (p->theFile.ctime), 32);
2921 sl_strlcpy (timstr2c, sh_unix_gmttime (theFile->ctime), 32);
2922#ifdef SH_USE_XML
2923 sl_snprintf(tmp, SH_BUFSIZE, _("ctime_old=\"%s\" ctime_new=\"%s\" "),
2924 timstr1c, timstr2c);
2925#else
2926 sl_snprintf(tmp, SH_BUFSIZE, _("ctime_old=<%s>, ctime_new=<%s>, "),
2927 timstr1c, timstr2c);
2928#endif
2929 sl_strlcat(msg, tmp, SH_BUFSIZE);
2930#ifdef REPLACE_OLD
2931 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
2932 p->theFile.ctime = theFile->ctime;
2933#endif
2934 }
2935
2936 if ((modi_mask & MODI_ATM) != 0)
2937 {
2938 sl_strlcpy (timstr1a, sh_unix_gmttime (p->theFile.atime), 32);
2939 sl_strlcpy (timstr2a, sh_unix_gmttime (theFile->atime), 32);
2940#ifdef SH_USE_XML
2941 sl_snprintf(tmp, SH_BUFSIZE, _("atime_old=\"%s\" atime_new=\"%s\" "),
2942 timstr1a, timstr2a);
2943#else
2944 sl_snprintf(tmp, SH_BUFSIZE, _("atime_old=<%s>, atime_new=<%s>, "),
2945 timstr1a, timstr2a);
2946#endif
2947 sl_strlcat(msg, tmp, SH_BUFSIZE);
2948#ifdef REPLACE_OLD
2949 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
2950 p->theFile.atime = theFile->atime;
2951#endif
2952 }
2953
2954 if ((modi_mask & MODI_MTM) != 0)
2955 {
2956 sl_strlcpy (timstr1m, sh_unix_gmttime (p->theFile.mtime), 32);
2957 sl_strlcpy (timstr2m, sh_unix_gmttime (theFile->mtime), 32);
2958#ifdef SH_USE_XML
2959 sl_snprintf(tmp, SH_BUFSIZE, _("mtime_old=\"%s\" mtime_new=\"%s\" "),
2960 timstr1m, timstr2m);
2961#else
2962 sl_snprintf(tmp, SH_BUFSIZE, _("mtime_old=<%s>, mtime_new=<%s>, "),
2963 timstr1m, timstr2m);
2964#endif
2965 sl_strlcat(msg, tmp, SH_BUFSIZE);
2966#ifdef REPLACE_OLD
2967 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
2968 p->theFile.mtime = theFile->mtime;
2969#endif
2970 }
2971
2972
2973 if ((modi_mask & MODI_CHK) != 0)
2974 {
2975 sl_snprintf(tmp, SH_BUFSIZE,
2976#ifdef SH_USE_XML
2977 _("chksum_old=\"%s\" chksum_new=\"%s\" "),
2978#else
2979 _("chksum_old=<%s>, chksum_new=<%s>, "),
2980#endif
2981 p->theFile.checksum, fileHash);
2982 sl_strlcat(msg, tmp, SH_BUFSIZE);
2983#ifdef REPLACE_OLD
2984 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
2985 sl_strlcpy(p->theFile.checksum, fileHash, KEY_LEN+1);
2986#endif
2987 }
2988
2989
2990 if ((modi_mask & MODI_LNK) != 0 && theFile->c_mode[0] == 'l')
2991 {
2992 tmp_lnk = sh_util_safe_name(theFile->linkpath);
2993 tmp_lnk_old = sh_util_safe_name(p->linkpath);
2994#ifdef SH_USE_XML
2995 sl_snprintf(tmp, SH_BUFSIZE, _("link_old=\"%s\" link_new=\"%s\" "),
2996 tmp_lnk_old, tmp_lnk);
2997#else
2998 sl_snprintf(tmp, SH_BUFSIZE, _("link_old=<%s>, link_new=<%s>"),
2999 tmp_lnk_old, tmp_lnk);
3000#endif
3001 SH_FREE(tmp_lnk);
3002 SH_FREE(tmp_lnk_old);
3003 sl_strlcat(msg, tmp, SH_BUFSIZE);
3004#ifdef REPLACE_OLD
3005 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
3006 {
3007 if (p->linkpath != NULL)
3008 SH_FREE(p->linkpath);
3009 p->linkpath = sh_util_strdup(theFile->linkpath);
3010 }
3011#endif
3012 }
3013
3014
3015 tmp_path = sh_util_safe_name(theFile->fullpath);
3016 sh_error_handle(log_severity, FIL__, __LINE__,
3017 (long) modi_mask, MSG_FI_CHAN,
3018 (policy_override == NULL) ? _(policy[class]):log_policy,
3019 change_code, tmp_path, msg);
3020
3021 SH_FREE(tmp_path);
3022 SH_FREE(tmp);
3023 SH_FREE(msg);
3024
3025#ifndef REPLACE_OLD
3026 p->reported = S_TRUE;
3027#endif
3028
3029 if (S_TRUE == sh.flag.update)
3030 {
3031 if (S_FALSE == sh_util_ask_update(theFile->fullpath))
3032 {
3033 /* user does not want to update, thus we replace
3034 * with data from the baseline database
3035 */
3036 sl_strlcpy(theFile->c_mode, p->theFile.c_mode, 11);
3037 theFile->mode = p->theFile.mode;
3038#if defined(__linux__) || defined(HAVE_STAT_FLAGS)
3039 sl_strlcpy(theFile->c_attributes, p->theFile.c_attributes, 16);
3040 theFile->attributes = p->theFile.attributes;
3041#endif
3042
3043 if (theFile->c_mode[0] == 'l') /* c_mode is already copied */
3044 {
3045 sl_strlcpy(theFile->linkpath, p->linkpath, PATH_MAX);
3046 }
3047 else
3048 {
3049 theFile->linkpath[0] = '-';
3050 theFile->linkpath[1] = '\0';
3051 }
3052
3053 sl_strlcpy(fileHash, p->theFile.checksum, KEY_LEN+1);
3054
3055 theFile->mtime = p->theFile.mtime;
3056 theFile->ctime = p->theFile.ctime;
3057 theFile->atime = p->theFile.atime;
3058
3059 theFile->size = p->theFile.size;
3060
3061 sl_strlcpy(theFile->c_group, p->theFile.c_group, GROUP_MAX+2);
3062 theFile->group = p->theFile.group;
3063 sl_strlcpy(theFile->c_owner, p->theFile.c_owner, USER_MAX+2);
3064 theFile->owner = p->theFile.owner;
3065
3066 theFile->ino = p->theFile.ino;
3067 theFile->rdev = p->theFile.rdev;
3068 theFile->dev = p->theFile.dev;
3069 theFile->hardlinks = p->theFile.hardlinks;
3070
3071 p->visited = S_TRUE;
3072 SL_RETURN(1, _("sh_hash_compdata"));
3073 }
3074 else if (sh.flag.reportonce == S_TRUE)
3075 {
3076 /* we replace the data in the in-memory copy of the
3077 * baseline database, because otherwise we would get
3078 * another warning if the suidcheck runs
3079 */
3080 sl_strlcpy(p->theFile.c_mode, theFile->c_mode, 11);
3081 p->theFile.mode = theFile->mode;
3082#if defined(__linux__) || defined(HAVE_STAT_FLAGS)
3083 sl_strlcpy(p->theFile.c_attributes, theFile->c_attributes, 16);
3084 p->theFile.attributes = theFile->attributes;
3085#endif
3086
3087 if (theFile->c_mode[0] == 'l')
3088 {
3089 if (p->linkpath != NULL)
3090 SH_FREE(p->linkpath);
3091 p->linkpath = sh_util_strdup(theFile->linkpath);
3092 }
3093 else
3094 {
3095 if (p->linkpath != NULL) {
3096 p->linkpath[0] = '-';
3097 p->linkpath[1] = '\0';
3098 } else {
3099 p->linkpath = SH_ALLOC(2);
3100 p->linkpath[0] = '-';
3101 p->linkpath[1] = '\0';
3102 }
3103 }
3104
3105 sl_strlcpy(p->theFile.checksum, fileHash, KEY_LEN+1);
3106
3107 p->theFile.mtime = theFile->mtime;
3108 p->theFile.ctime = theFile->ctime;
3109 p->theFile.atime = theFile->atime;
3110
3111 p->theFile.size = theFile->size;
3112
3113 sl_strlcpy(p->theFile.c_group, theFile->c_group, GROUP_MAX+2);
3114 p->theFile.group = theFile->group;
3115 sl_strlcpy(p->theFile.c_owner, theFile->c_owner, USER_MAX+2);
3116 p->theFile.owner = theFile->owner;
3117
3118 p->theFile.ino = theFile->ino;
3119 p->theFile.rdev = theFile->rdev;
3120 p->theFile.dev = theFile->dev;
3121 p->theFile.hardlinks = theFile->hardlinks;
3122 }
3123 }
3124 }
3125
3126 p->visited = S_TRUE;
3127
3128 SL_RETURN(0, _("sh_hash_compdata"));
3129}
3130
3131int hash_full_tree ()
3132{
3133 sh_file_t * p;
3134 int i;
3135
3136 SL_ENTER(_("sh_hash_compdata"));
3137
3138 if (IsInit != 1)
3139 SL_RETURN(0, _("sh_hash_compdata"));
3140
3141 for (i = 0; i < TABSIZE; ++i)
3142 {
3143 for (p = tab[i]; p; p = p->next)
3144 p->allignore = S_FALSE;
3145 }
3146 SL_RETURN (0, _("sh_hash_compdata"));
3147}
3148
3149
3150int hash_remove_tree (char * s)
3151{
3152 sh_file_t * p;
3153 size_t len;
3154 unsigned int i;
3155
3156 SL_ENTER(_("hash_remove_tree"));
3157
3158 if (!s || *s == '\0')
3159 SL_RETURN ((-1), _("hash_remove_tree"));
3160
3161 len = sl_strlen(s);
3162
3163 if (IsInit != 1)
3164 sh_hash_init();
3165
3166 for (i = 0; i < TABSIZE; ++i)
3167 {
3168 for (p = tab[i]; p; p = p->next)
3169 {
3170 if (p->fullpath && 0 == strncmp(s, p->fullpath, len))
3171 {
3172 p->allignore = S_TRUE;
3173 }
3174 }
3175 }
3176 SL_RETURN ((0), _("hash_remove_tree"));
3177}
3178
3179#if TIME_WITH_SYS_TIME
3180#include <sys/time.h>
3181#include <time.h>
3182#else
3183#if HAVE_SYS_TIME_H
3184#include <sys/time.h>
3185#else
3186#include <time.h>
3187#endif
3188#endif
3189
3190static int ListFullDetail = S_FALSE;
3191static int ListWithDelimiter = S_FALSE;
3192
3193int set_full_detail (const char * c)
3194{
3195 ListFullDetail = S_TRUE;
3196 /* warning: unused parameter `c' */
3197 if (c)
3198 return 0;
3199 else
3200 return 0;
3201}
3202
3203int set_list_delimited (const char * c)
3204{
3205 ListFullDetail = S_TRUE;
3206 ListWithDelimiter = S_TRUE;
3207 /* warning: unused parameter `c' */
3208 if (c)
3209 return 0;
3210 else
3211 return 0;
3212}
3213
3214void sh_hash_list_db_entry_full_detail (sh_file_t * p)
3215{
3216 char * tmp;
3217 char str[81];
3218
3219 if (ListWithDelimiter == S_TRUE)
3220 {
3221 printf(_("%7ld, %7ld, %10s, %5d, %12s, %5d, %3d, %-8s, %5d, %-8s, %5d, "),
3222 (unsigned long) p->theFile.ino, (unsigned long) p->theFile.dev,
3223 p->theFile.c_mode, (int) p->theFile.mode,
3224 p->theFile.c_attributes, (int) p->theFile.attributes,
3225 (int) p->theFile.hardlinks,
3226 p->theFile.c_owner, (int) p->theFile.owner,
3227 p->theFile.c_group, (int) p->theFile.group);
3228 }
3229 else
3230 {
3231 printf(_("%7ld %7ld %10s %5d %12s %5d %3d %-8s %5d %-8s %5d "),
3232 (unsigned long) p->theFile.ino, (unsigned long) p->theFile.dev,
3233 p->theFile.c_mode, (int) p->theFile.mode,
3234 p->theFile.c_attributes, (int) p->theFile.attributes,
3235 (int) p->theFile.hardlinks,
3236 p->theFile.c_owner, (int) p->theFile.owner,
3237 p->theFile.c_group, (int) p->theFile.group);
3238 }
3239
3240 if ('c' == p->theFile.c_mode[0] || 'b' == p->theFile.c_mode[0])
3241 sl_snprintf(str, 80, "%"PRIu64, p->theFile.rdev);
3242 else
3243 sl_snprintf(str, 80, "%"PRIu64, p->theFile.size);
3244
3245 printf( _(" %8s"), str);
3246 if (ListWithDelimiter == S_TRUE)
3247 putchar(',');
3248
3249 printf( _(" %s"), sh_unix_gmttime (p->theFile.ctime));
3250 if (ListWithDelimiter == S_TRUE)
3251 putchar(',');
3252 printf( _(" %s"), sh_unix_gmttime (p->theFile.mtime));
3253 if (ListWithDelimiter == S_TRUE)
3254 putchar(',');
3255 printf( _(" %s"), sh_unix_gmttime (p->theFile.atime));
3256 if (ListWithDelimiter == S_TRUE)
3257 putchar(',');
3258 printf( _(" %s"), p->theFile.checksum);
3259 if (ListWithDelimiter == S_TRUE)
3260 putchar(',');
3261
3262 tmp = sh_util_safe_name(p->fullpath);
3263 printf( _(" %s"), tmp);
3264 SH_FREE(tmp);
3265 if (ListWithDelimiter == S_TRUE)
3266 putchar(',');
3267
3268 if ('l' == p->theFile.c_mode[0])
3269 {
3270 tmp = sh_util_safe_name(p->linkpath);
3271 if (ListWithDelimiter == S_TRUE)
3272 printf(_(" %s\n"), tmp);
3273 else
3274 printf(_(" -> %s\n"), tmp);
3275 SH_FREE(tmp);
3276 }
3277 else
3278 printf("\n");
3279
3280 return;
3281}
3282
3283void sh_hash_list_db_entry (sh_file_t * p)
3284{
3285 char nowtime[128];
3286 char thetime[128];
3287 char * tmp;
3288 time_t now = time(NULL);
3289 time_t then = (time_t) p->theFile.mtime;
3290
3291 strftime(thetime, 127, _("%b %d %Y"), gmtime(&then));
3292 strftime(nowtime, 127, _("%b %d %Y"), gmtime(&now));
3293 if (0 == strncmp(&nowtime[7], &thetime[7], 4))
3294 strftime(thetime, 127, _("%b %d %H:%M"), gmtime(&then));
3295
3296 tmp = sh_util_safe_name(p->fullpath);
3297 if ('c' == p->theFile.c_mode[0] || 'b' == p->theFile.c_mode[0])
3298 printf(_("%10s %3d %-8s %-8s %3d,%4d %s %s"),
3299 p->theFile.c_mode, (int) p->theFile.hardlinks,
3300 p->theFile.c_owner, p->theFile.c_group,
3301 (int) major((dev_t)p->theFile.rdev),
3302 (int) minor((dev_t)p->theFile.rdev),
3303 thetime,
3304 tmp);
3305 else
3306 printf(_("%10s %3d %-8s %-8s %8ld %s %s"),
3307 p->theFile.c_mode, (int) p->theFile.hardlinks,
3308 p->theFile.c_owner, p->theFile.c_group, (long) p->theFile.size,
3309 thetime,
3310 tmp);
3311 SH_FREE(tmp);
3312
3313 if ('l' == p->theFile.c_mode[0])
3314 {
3315 tmp = sh_util_safe_name(p->linkpath);
3316 printf(_(" -> %s\n"), tmp);
3317 SH_FREE(tmp);
3318 }
3319 else
3320 printf("\n");
3321
3322 return;
3323}
3324
3325int sh_hash_list_db (const char * db_file)
3326{
3327 sh_file_t * p;
3328 SL_TICKET fd;
3329 char * line;
3330
3331 if (!db_file)
3332 {
3333 _exit(EXIT_FAILURE);
3334 return -1;
3335 }
3336 if (sl_is_suid())
3337 {
3338 fprintf(stderr, _("ERROR: insufficient privilege\n"));
3339 _exit (EXIT_FAILURE);
3340 return -1; /* for Mac OSX compiler */
3341 }
3342 if (0 == strcmp(db_file, _("default")))
3343 db_file = file_path('D', 'W');
3344 if (!db_file)
3345 {
3346 _exit(EXIT_FAILURE);
3347 return -1;
3348 }
3349
3350 line = SH_ALLOC(MAX_PATH_STORE+1);
3351
3352 if ( SL_ISERROR(fd = sl_open_read(db_file, SL_YESPRIV)))
3353 {
3354 fprintf(stderr, _("ERROR: can't open %s for read (errnum = %ld)\n"),
3355 db_file, fd);
3356 _exit(EXIT_FAILURE);
3357 return -1;
3358 }
3359
3360 /* fast forward to start of data
3361 */
3362 sh_hash_setdataent(fd, line, MAX_PATH_STORE, db_file);
3363
3364 while (1)
3365 {
3366 p = sh_hash_getdataent (fd, line, MAX_PATH_STORE);
3367 if ((p != NULL) && (p->fullpath[0] != 'K'))
3368 {
3369 if (ListFullDetail == S_FALSE)
3370 sh_hash_list_db_entry (p);
3371 else
3372 sh_hash_list_db_entry_full_detail (p);
3373 }
3374 else if (p == NULL)
3375 {
3376 break;
3377 }
3378 }
3379
3380 if (line != NULL)
3381 SH_FREE(line);
3382 sl_close (fd);
3383
3384 fflush(NULL);
3385
3386 _exit(EXIT_SUCCESS);
3387 return 0;
3388}
3389
3390/* if defined(SH_WITH_CLIENT) || defined(SH_STANDALONE) */
3391#endif
Note: See TracBrowser for help on using the repository browser.