source: trunk/src/sh_hash.c@ 25

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

Minor code revisions.

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