source: trunk/src/sh_hash.c@ 18

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

Optimized version of tiger algorithm, and basic ingredients for unit testing (part 2)

File size: 80.4 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, 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 (char * str)
1264{
1265 if (!str)
1266 { pushdata_stdout = S_TRUE; return 0; }
1267 return -1;
1268}
1269
1270int sh_hash_version_string(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, 50) != 0) &&
2488 (theFile->check_mask & MODI_CHK) != 0)
2489 {
2490 modi_mask |= MODI_CHK;
2491 change_code[0] = 'C';
2492 TPT ((0, FIL__, __LINE__, _("mod=<checksum>")));
2493 }
2494
2495 if (p->theFile.c_mode[0] == 'l')
2496 {
2497 if (sl_strlen(theFile->linkpath) >= MAX_PATH_STORE)
2498 {
2499 sl_strlcpy(linkHash,
2500 sh_tiger_hash(theFile->linkpath,
2501 TIGER_DATA,
2502 sl_strlen(theFile->linkpath)),
2503 MAX_PATH_STORE+1);
2504 maxcomp = MAX_PATH_STORE;
2505 }
2506 else
2507 {
2508 sl_strlcpy(linkHash, theFile->linkpath, KEY_LEN + 1);
2509 maxcomp = KEY_LEN;
2510 }
2511
2512 if ( sl_strncmp (linkHash, p->linkpath, maxcomp) != 0 &&
2513 (theFile->check_mask & MODI_LNK) != 0)
2514 {
2515 modi_mask |= MODI_LNK;
2516 change_code[1] = 'L';
2517 TPT ((0, FIL__, __LINE__, _("mod=<link>")));
2518 }
2519 }
2520
2521 if (p->theFile.c_mode[0] == 'c' || p->theFile.c_mode[0] == 'b')
2522 {
2523 if ( ( major(theFile->rdev) != major((dev_t)p->theFile.rdev) ||
2524 minor(theFile->rdev) != minor((dev_t)p->theFile.rdev) ) &&
2525 (theFile->check_mask & MODI_RDEV) != 0)
2526 {
2527 modi_mask |= MODI_RDEV;
2528 change_code[2] = 'D';
2529 TPT ((0, FIL__, __LINE__, _("mod=<rdev>")));
2530 }
2531 }
2532
2533 /* cast to UINT32 in case ino_t is not 32bit
2534 */
2535 if ( (UINT32) theFile->ino != (UINT32) p->theFile.ino &&
2536 (theFile->check_mask & MODI_INO) != 0)
2537 {
2538 modi_mask |= MODI_INO;
2539 change_code[3] = 'I';
2540 TPT ((0, FIL__, __LINE__, _("mod=<inode>")));
2541 }
2542
2543 if ( theFile->hardlinks != (nlink_t) p->theFile.hardlinks &&
2544 (theFile->check_mask & MODI_HLN) != 0)
2545 {
2546 modi_mask |= MODI_HLN;
2547 change_code[4] = 'H';
2548 TPT ((0, FIL__, __LINE__, _("mod=<hardlink>")));
2549 }
2550
2551
2552 if ( ( (theFile->mode != p->theFile.mode)
2553#if defined(__linux__) || defined(HAVE_STAT_FLAGS)
2554 || (theFile->attributes != p->theFile.attributes)
2555#endif
2556 )
2557 && (theFile->check_mask & MODI_MOD) != 0)
2558 {
2559 modi_mask |= MODI_MOD;
2560 change_code[5] = 'M';
2561 TPT ((0, FIL__, __LINE__, _("mod=<mode>")));
2562 /*
2563 * report link path if switch link/no link
2564 */
2565 if ((theFile->check_mask & MODI_LNK) != 0 &&
2566 (theFile->c_mode[0] != p->theFile.c_mode[0]) &&
2567 (theFile->c_mode[0] == 'l' || p->theFile.c_mode[0] == 'l'))
2568 {
2569 modi_mask |= MODI_LNK;
2570 change_code[1] = 'L';
2571 TPT ((0, FIL__, __LINE__, _("mod=<link>")));
2572 }
2573 }
2574
2575 if ( theFile->owner != (uid_t) p->theFile.owner &&
2576 (theFile->check_mask & MODI_USR) != 0)
2577 {
2578 modi_mask |= MODI_USR;
2579 change_code[6] = 'U';
2580 TPT ((0, FIL__, __LINE__, _("mod=<user>")));
2581 }
2582
2583 if ( theFile->group != (gid_t) p->theFile.group &&
2584 (theFile->check_mask & MODI_GRP) != 0)
2585 {
2586 modi_mask |= MODI_GRP;
2587 change_code[7] = 'G';
2588 TPT ((0, FIL__, __LINE__, _("mod=<group>")));
2589 }
2590
2591
2592 if ( theFile->mtime != (time_t) p->theFile.mtime &&
2593 (theFile->check_mask & MODI_MTM) != 0)
2594 {
2595 modi_mask |= MODI_MTM;
2596 change_code[8] = 'T';
2597 TPT ((0, FIL__, __LINE__, _("mod=<mtime>")));
2598 }
2599
2600 if ( theFile->atime != (time_t) p->theFile.atime &&
2601 (theFile->check_mask & MODI_ATM) != 0)
2602 {
2603 modi_mask |= MODI_ATM;
2604 change_code[8] = 'T';
2605 TPT ((0, FIL__, __LINE__, _("mod=<atime>")));
2606 }
2607
2608
2609 /* Resetting the access time will set a new ctime. Thus, either we ignore
2610 * the access time or the ctime for NOIGNORE
2611 */
2612 if ( theFile->ctime != (time_t) p->theFile.ctime &&
2613 (theFile->check_mask & MODI_CTM) != 0)
2614 {
2615 modi_mask |= MODI_CTM;
2616 change_code[8] = 'T';
2617 TPT ((0, FIL__, __LINE__, _("mod=<ctime>")));
2618 }
2619
2620 if ( theFile->size != (off_t) p->theFile.size &&
2621 (theFile->check_mask & MODI_SIZ) != 0)
2622 {
2623 if (class == SH_LEVEL_LOGGROW && theFile->size < (off_t) p->theFile.size)
2624 {
2625 modi_mask |= MODI_SIZ;
2626 change_code[9] = 'S';
2627 TPT ((0, FIL__, __LINE__, _("mod=<size>")));
2628 }
2629 else if (class != SH_LEVEL_LOGGROW)
2630 {
2631 modi_mask |= MODI_SIZ;
2632 change_code[9] = 'S';
2633 TPT ((0, FIL__, __LINE__, _("mod=<size>")));
2634 }
2635 }
2636 change_code[10] = '\0';
2637
2638 /* --- Report full details. ---
2639 */
2640 if (modi_mask != 0 && sh.flag.fulldetail == S_TRUE)
2641 {
2642 if ((theFile->check_mask & MODI_ATM) == 0)
2643 modi_mask = MASK_READONLY_;
2644 else
2645 modi_mask = MASK_NOIGNORE_;
2646 }
2647
2648 /* --- Report on modified files. ---
2649 */
2650 if (modi_mask != 0 && p->reported == S_FALSE)
2651 {
2652 tmp = SH_ALLOC(SH_BUFSIZE);
2653 msg = SH_ALLOC(SH_BUFSIZE);
2654 msg[0] = '\0';
2655
2656 if ( ((modi_mask & MODI_MOD) != 0)
2657#if defined(HAVE_LIBPRELUDE) && defined(HAVE_LIBPRELUDE_9)
2658 || ((modi_mask & MODI_USR) != 0)
2659 || ((modi_mask & MODI_GRP) != 0)
2660#endif
2661 )
2662 {
2663#if defined(__linux__) || defined(HAVE_STAT_FLAGS)
2664 sl_snprintf(tmp, SH_BUFSIZE,
2665#ifdef SH_USE_XML
2666 _("mode_old=\"%s\" mode_new=\"%s\" attr_old=\"%s\" attr_new=\"%s\" imode_old=\"%ld\" imode_new=\"%ld\" iattr_old=\"%ld\" iattr_new=\"%ld\" "),
2667#else
2668 _("mode_old=<%s>, mode_new=<%s>, attr_old=<%s>, attr_new=<%s>, "),
2669#endif
2670 p->theFile.c_mode, theFile->c_mode,
2671 p->theFile.c_attributes, theFile->c_attributes
2672#ifdef SH_USE_XML
2673 , (long) p->theFile.mode, (long) theFile->mode,
2674 (long) p->theFile.attributes,
2675 (long) theFile->attributes
2676#endif
2677 );
2678#else
2679#ifdef SH_USE_XML
2680 sl_snprintf(tmp, SH_BUFSIZE,
2681 _("mode_old=\"%s\" mode_new=\"%s\" imode_old=\"%ld\" imode_new=\"%ld\" "),
2682#else
2683 sl_snprintf(tmp, SH_BUFSIZE, _("mode_old=<%s>, mode_new=<%s>, "),
2684#endif
2685 p->theFile.c_mode, theFile->c_mode
2686#ifdef SH_USE_XML
2687 , (long) p->theFile.mode, (long) theFile->mode
2688#endif
2689 );
2690#endif
2691 sl_strlcat(msg, tmp, SH_BUFSIZE);
2692#ifdef REPLACE_OLD
2693 if ((modi_mask & MODI_MOD) != 0)
2694 {
2695 /*
2696 * We postpone update if sh.flag.update == S_TRUE because
2697 * in interactive mode the user may not accept the change.
2698 */
2699 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
2700 {
2701 sl_strlcpy(p->theFile.c_mode, theFile->c_mode, 11);
2702 p->theFile.mode = theFile->mode;
2703#if defined(__linux__) || defined(HAVE_STAT_FLAGS)
2704 sl_strlcpy(p->theFile.c_attributes,theFile->c_attributes,16);
2705 p->theFile.attributes = theFile->attributes;
2706#endif
2707 }
2708 }
2709#endif
2710 }
2711
2712 if ((modi_mask & MODI_HLN) != 0)
2713 {
2714 sl_snprintf(tmp, SH_BUFSIZE,
2715#ifdef SH_USE_XML
2716 _("hardlinks_old=\"%ld\" hardlinks_new=\"%ld\" "),
2717#else
2718 _("hardlinks_old=<%ld>, hardlinks_new=<%ld>, "),
2719#endif
2720 (unsigned long) p->theFile.hardlinks,
2721 (unsigned long) theFile->hardlinks);
2722 sl_strlcat(msg, tmp, SH_BUFSIZE);
2723#ifdef REPLACE_OLD
2724 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
2725 p->theFile.hardlinks = theFile->hardlinks;
2726#endif
2727 }
2728
2729 if ((modi_mask & MODI_RDEV) != 0)
2730 {
2731 sl_snprintf(tmp, SH_BUFSIZE,
2732#ifdef SH_USE_XML
2733 _("device_old=\"%ld,%ld\" device_new=\"%ld,%ld\" idevice_old=\"%ld\" idevice_new=\"%ld\" "),
2734#else
2735 _("device_old=<%ld,%ld>, device_new=<%ld,%ld>, "),
2736#endif
2737 (unsigned long) major(p->theFile.rdev),
2738 (unsigned long) minor(p->theFile.rdev),
2739 (unsigned long) major(theFile->rdev),
2740 (unsigned long) minor(theFile->rdev)
2741#ifdef SH_USE_XML
2742 , (unsigned long) p->theFile.rdev,
2743 (unsigned long) theFile->rdev
2744#endif
2745 );
2746 sl_strlcat(msg, tmp, SH_BUFSIZE);
2747#ifdef REPLACE_OLD
2748 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
2749 p->theFile.rdev = theFile->rdev;
2750#endif
2751 }
2752
2753 if ((modi_mask & MODI_INO) != 0)
2754 {
2755 sl_snprintf(tmp, SH_BUFSIZE,
2756#ifdef SH_USE_XML
2757 _("inode_old=\"%ld\" inode_new=\"%ld\" "),
2758#else
2759 _("inode_old=<%ld>, inode_new=<%ld>, "),
2760#endif
2761 (unsigned long) p->theFile.ino,
2762 (unsigned long) theFile->ino);
2763 sl_strlcat(msg, tmp, SH_BUFSIZE);
2764#ifdef REPLACE_OLD
2765 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
2766 p->theFile.ino = theFile->ino;
2767#endif
2768 }
2769
2770 if ( ((modi_mask & MODI_USR) != 0)
2771#if defined(HAVE_LIBPRELUDE) && defined(HAVE_LIBPRELUDE_9)
2772 || ((modi_mask & MODI_MOD) != 0)
2773#endif
2774 )
2775 {
2776#ifdef SH_USE_XML
2777 sl_snprintf(tmp, SH_BUFSIZE, _("owner_old=\"%s\" owner_new=\"%s\" iowner_old=\"%ld\" iowner_new=\"%ld\" "),
2778#else
2779 sl_snprintf(tmp, SH_BUFSIZE, _("owner_old=<%s>, owner_new=<%s>, "),
2780#endif
2781 p->theFile.c_owner, theFile->c_owner
2782#ifdef SH_USE_XML
2783 , (long) p->theFile.owner, (long) theFile->owner
2784#endif
2785 );
2786 sl_strlcat(msg, tmp, SH_BUFSIZE);
2787#ifdef REPLACE_OLD
2788 if ((modi_mask & MODI_USR) != 0) {
2789 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
2790 {
2791 sl_strlcpy(p->theFile.c_owner, theFile->c_owner, USER_MAX+2);
2792 p->theFile.owner = theFile->owner;
2793 }
2794 }
2795#endif
2796 }
2797
2798 if ( ((modi_mask & MODI_GRP) != 0)
2799#if defined(HAVE_LIBPRELUDE) && defined(HAVE_LIBPRELUDE_9)
2800 || ((modi_mask & MODI_MOD) != 0)
2801#endif
2802 )
2803 {
2804#ifdef SH_USE_XML
2805 sl_snprintf(tmp, SH_BUFSIZE, _("group_old=\"%s\" group_new=\"%s\" igroup_old=\"%ld\" igroup_new=\"%ld\" "),
2806 p->theFile.c_group, theFile->c_group,
2807 (long) p->theFile.group, (long) theFile->group);
2808#else
2809 sl_snprintf(tmp, SH_BUFSIZE, _("group_old=<%s>, group_new=<%s>, "),
2810 p->theFile.c_group, theFile->c_group);
2811#endif
2812
2813 sl_strlcat(msg, tmp, SH_BUFSIZE);
2814#ifdef REPLACE_OLD
2815 if ((modi_mask & MODI_GRP) != 0) {
2816 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
2817 {
2818 sl_strlcpy(p->theFile.c_group, theFile->c_group, GROUP_MAX+2);
2819 p->theFile.group = theFile->group;
2820 }
2821 }
2822#endif
2823 }
2824
2825 if ((modi_mask & MODI_SIZ) != 0)
2826 {
2827 sl_snprintf(tmp, SH_BUFSIZE, sh_hash_size_format(),
2828 (UINT64) p->theFile.size,
2829 (UINT64) theFile->size);
2830 sl_strlcat(msg, tmp, SH_BUFSIZE);
2831#ifdef REPLACE_OLD
2832 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
2833 p->theFile.size = theFile->size;
2834#endif
2835 }
2836
2837 if ((modi_mask & MODI_CTM) != 0)
2838 {
2839 sl_strlcpy (timstr1c, sh_unix_gmttime (p->theFile.ctime), 32);
2840 sl_strlcpy (timstr2c, sh_unix_gmttime (theFile->ctime), 32);
2841#ifdef SH_USE_XML
2842 sl_snprintf(tmp, SH_BUFSIZE, _("ctime_old=\"%s\" ctime_new=\"%s\" "),
2843 timstr1c, timstr2c);
2844#else
2845 sl_snprintf(tmp, SH_BUFSIZE, _("ctime_old=<%s>, ctime_new=<%s>, "),
2846 timstr1c, timstr2c);
2847#endif
2848 sl_strlcat(msg, tmp, SH_BUFSIZE);
2849#ifdef REPLACE_OLD
2850 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
2851 p->theFile.ctime = theFile->ctime;
2852#endif
2853 }
2854
2855 if ((modi_mask & MODI_ATM) != 0)
2856 {
2857 sl_strlcpy (timstr1a, sh_unix_gmttime (p->theFile.atime), 32);
2858 sl_strlcpy (timstr2a, sh_unix_gmttime (theFile->atime), 32);
2859#ifdef SH_USE_XML
2860 sl_snprintf(tmp, SH_BUFSIZE, _("atime_old=\"%s\" atime_new=\"%s\" "),
2861 timstr1a, timstr2a);
2862#else
2863 sl_snprintf(tmp, SH_BUFSIZE, _("atime_old=<%s>, atime_new=<%s>, "),
2864 timstr1a, timstr2a);
2865#endif
2866 sl_strlcat(msg, tmp, SH_BUFSIZE);
2867#ifdef REPLACE_OLD
2868 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
2869 p->theFile.atime = theFile->atime;
2870#endif
2871 }
2872
2873 if ((modi_mask & MODI_MTM) != 0)
2874 {
2875 sl_strlcpy (timstr1m, sh_unix_gmttime (p->theFile.mtime), 32);
2876 sl_strlcpy (timstr2m, sh_unix_gmttime (theFile->mtime), 32);
2877#ifdef SH_USE_XML
2878 sl_snprintf(tmp, SH_BUFSIZE, _("mtime_old=\"%s\" mtime_new=\"%s\" "),
2879 timstr1m, timstr2m);
2880#else
2881 sl_snprintf(tmp, SH_BUFSIZE, _("mtime_old=<%s>, mtime_new=<%s>, "),
2882 timstr1m, timstr2m);
2883#endif
2884 sl_strlcat(msg, tmp, SH_BUFSIZE);
2885#ifdef REPLACE_OLD
2886 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
2887 p->theFile.mtime = theFile->mtime;
2888#endif
2889 }
2890
2891
2892 if ((modi_mask & MODI_CHK) != 0)
2893 {
2894 sl_snprintf(tmp, SH_BUFSIZE,
2895#ifdef SH_USE_XML
2896 _("chksum_old=\"%s\" chksum_new=\"%s\" "),
2897#else
2898 _("chksum_old=<%s>, chksum_new=<%s>, "),
2899#endif
2900 p->theFile.checksum, fileHash);
2901 sl_strlcat(msg, tmp, SH_BUFSIZE);
2902#ifdef REPLACE_OLD
2903 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
2904 sl_strlcpy(p->theFile.checksum, fileHash, KEY_LEN+1);
2905#endif
2906 }
2907
2908
2909 if ((modi_mask & MODI_LNK) != 0 && theFile->c_mode[0] == 'l')
2910 {
2911 tmp_lnk = sh_util_safe_name(theFile->linkpath);
2912 tmp_lnk_old = sh_util_safe_name(p->linkpath);
2913#ifdef SH_USE_XML
2914 sl_snprintf(tmp, SH_BUFSIZE, _("link_old=\"%s\" link_new=\"%s\" "),
2915 tmp_lnk_old, tmp_lnk);
2916#else
2917 sl_snprintf(tmp, SH_BUFSIZE, _("link_old=<%s>, link_new=<%s>"),
2918 tmp_lnk_old, tmp_lnk);
2919#endif
2920 SH_FREE(tmp_lnk);
2921 SH_FREE(tmp_lnk_old);
2922 sl_strlcat(msg, tmp, SH_BUFSIZE);
2923#ifdef REPLACE_OLD
2924 if (sh.flag.reportonce == S_TRUE && sh.flag.update == S_FALSE)
2925 {
2926 if (p->linkpath != NULL)
2927 SH_FREE(p->linkpath);
2928 p->linkpath = (char*)SH_ALLOC (sl_strlen(theFile->linkpath) + 1);
2929 sl_strlcpy(p->linkpath, theFile->linkpath,
2930 sl_strlen(theFile->linkpath) + 1);
2931 }
2932#endif
2933 }
2934
2935
2936 tmp_path = sh_util_safe_name(theFile->fullpath);
2937 sh_error_handle(log_severity, FIL__, __LINE__,
2938 (long) modi_mask, MSG_FI_CHAN,
2939 (policy_override == NULL) ? _(policy[class]):log_policy,
2940 change_code, tmp_path, msg);
2941
2942 SH_FREE(tmp_path);
2943 SH_FREE(tmp);
2944 SH_FREE(msg);
2945
2946#ifndef REPLACE_OLD
2947 p->reported = S_TRUE;
2948#endif
2949
2950 if (S_TRUE == sh.flag.update)
2951 {
2952 if (S_FALSE == sh_util_ask_update(theFile->fullpath))
2953 {
2954 /* user does not want to update, thus we replace
2955 * with data from the baseline database
2956 */
2957 sl_strlcpy(theFile->c_mode, p->theFile.c_mode, 11);
2958 theFile->mode = p->theFile.mode;
2959#if defined(__linux__) || defined(HAVE_STAT_FLAGS)
2960 sl_strlcpy(theFile->c_attributes, p->theFile.c_attributes, 16);
2961 theFile->attributes = p->theFile.attributes;
2962#endif
2963
2964 if (theFile->c_mode[0] == 'l') /* c_mode is already copied */
2965 {
2966 sl_strlcpy(theFile->linkpath, p->linkpath, PATH_MAX);
2967 }
2968 else
2969 {
2970 theFile->linkpath[0] = '-';
2971 theFile->linkpath[1] = '\0';
2972 }
2973
2974 sl_strlcpy(fileHash, p->theFile.checksum, KEY_LEN+1);
2975
2976 theFile->mtime = p->theFile.mtime;
2977 theFile->ctime = p->theFile.ctime;
2978 theFile->atime = p->theFile.atime;
2979
2980 theFile->size = p->theFile.size;
2981
2982 sl_strlcpy(theFile->c_group, p->theFile.c_group, GROUP_MAX+2);
2983 theFile->group = p->theFile.group;
2984 sl_strlcpy(theFile->c_owner, p->theFile.c_owner, USER_MAX+2);
2985 theFile->owner = p->theFile.owner;
2986
2987 theFile->ino = p->theFile.ino;
2988 theFile->rdev = p->theFile.rdev;
2989 theFile->dev = p->theFile.dev;
2990 theFile->hardlinks = p->theFile.hardlinks;
2991
2992 p->visited = S_TRUE;
2993 SL_RETURN(1, _("sh_hash_compdata"));
2994 }
2995 else if (sh.flag.reportonce == S_TRUE)
2996 {
2997 /* we replace the data in the in-memory copy of the
2998 * baseline database, because otherwise we would get
2999 * another warning if the suidcheck runs
3000 */
3001 sl_strlcpy(p->theFile.c_mode, theFile->c_mode, 11);
3002 p->theFile.mode = theFile->mode;
3003#if defined(__linux__) || defined(HAVE_STAT_FLAGS)
3004 sl_strlcpy(p->theFile.c_attributes, theFile->c_attributes, 16);
3005 p->theFile.attributes = theFile->attributes;
3006#endif
3007
3008 if (theFile->c_mode[0] == 'l')
3009 {
3010 if (p->linkpath != NULL)
3011 SH_FREE(p->linkpath);
3012 p->linkpath = SH_ALLOC(1 + strlen(theFile->linkpath));
3013 sl_strlcpy(p->linkpath, theFile->linkpath,
3014 1 + strlen(theFile->linkpath));
3015 }
3016 else
3017 {
3018 if (p->linkpath != NULL) {
3019 p->linkpath[0] = '-';
3020 p->linkpath[1] = '\0';
3021 } else {
3022 p->linkpath = SH_ALLOC(2);
3023 p->linkpath[0] = '-';
3024 p->linkpath[1] = '\0';
3025 }
3026 }
3027
3028 sl_strlcpy(p->theFile.checksum, fileHash, KEY_LEN+1);
3029
3030 p->theFile.mtime = theFile->mtime;
3031 p->theFile.ctime = theFile->ctime;
3032 p->theFile.atime = theFile->atime;
3033
3034 p->theFile.size = theFile->size;
3035
3036 sl_strlcpy(p->theFile.c_group, theFile->c_group, GROUP_MAX+2);
3037 p->theFile.group = theFile->group;
3038 sl_strlcpy(p->theFile.c_owner, theFile->c_owner, USER_MAX+2);
3039 p->theFile.owner = theFile->owner;
3040
3041 p->theFile.ino = theFile->ino;
3042 p->theFile.rdev = theFile->rdev;
3043 p->theFile.dev = theFile->dev;
3044 p->theFile.hardlinks = theFile->hardlinks;
3045 }
3046 }
3047 }
3048
3049 p->visited = S_TRUE;
3050
3051 SL_RETURN(0, _("sh_hash_compdata"));
3052}
3053
3054int hash_full_tree ()
3055{
3056 sh_file_t * p;
3057 int i;
3058
3059 SL_ENTER(_("sh_hash_compdata"));
3060
3061 if (IsInit != 1)
3062 SL_RETURN(0, _("sh_hash_compdata"));
3063
3064 for (i = 0; i < TABSIZE; ++i)
3065 {
3066 for (p = tab[i]; p; p = p->next)
3067 p->allignore = S_FALSE;
3068 }
3069 SL_RETURN (0, _("sh_hash_compdata"));
3070}
3071
3072
3073int hash_remove_tree (char * s)
3074{
3075 sh_file_t * p;
3076 size_t len;
3077 unsigned int i;
3078
3079 SL_ENTER(_("hash_remove_tree"));
3080
3081 if (!s || *s == '\0')
3082 SL_RETURN ((-1), _("hash_remove_tree"));
3083
3084 len = sl_strlen(s);
3085
3086 if (IsInit != 1)
3087 sh_hash_init();
3088
3089 for (i = 0; i < TABSIZE; ++i)
3090 {
3091 for (p = tab[i]; p; p = p->next)
3092 {
3093 if (p->fullpath && 0 == strncmp(s, p->fullpath, len))
3094 {
3095 p->allignore = S_TRUE;
3096 }
3097 }
3098 }
3099 SL_RETURN ((0), _("hash_remove_tree"));
3100}
3101
3102#if TIME_WITH_SYS_TIME
3103#include <sys/time.h>
3104#include <time.h>
3105#else
3106#if HAVE_SYS_TIME_H
3107#include <sys/time.h>
3108#else
3109#include <time.h>
3110#endif
3111#endif
3112
3113static int ListFullDetail = S_FALSE;
3114static int ListWithDelimiter = S_FALSE;
3115
3116int set_full_detail (char * c)
3117{
3118 ListFullDetail = S_TRUE;
3119 /* warning: unused parameter `c' */
3120 if (c)
3121 return 0;
3122 else
3123 return 0;
3124}
3125
3126int set_list_delimited (char * c)
3127{
3128 ListFullDetail = S_TRUE;
3129 ListWithDelimiter = S_TRUE;
3130 /* warning: unused parameter `c' */
3131 if (c)
3132 return 0;
3133 else
3134 return 0;
3135}
3136
3137void sh_hash_list_db_entry_full_detail (sh_file_t * p)
3138{
3139 char * tmp;
3140 char str[81];
3141
3142 if (ListWithDelimiter == S_TRUE)
3143 {
3144 printf(_("%7ld, %10s, %5d, %12s, %5d, %3d, %-8s, %5d, %-8s, %5d, "),
3145 (unsigned long) p->theFile.ino,
3146 p->theFile.c_mode, (int) p->theFile.mode,
3147 p->theFile.c_attributes, (int) p->theFile.attributes,
3148 (int) p->theFile.hardlinks,
3149 p->theFile.c_owner, (int) p->theFile.owner,
3150 p->theFile.c_group, (int) p->theFile.group);
3151 }
3152 else
3153 {
3154 printf(_("%7ld %10s %5d %12s %5d %3d %-8s %5d %-8s %5d "),
3155 (unsigned long) p->theFile.ino,
3156 p->theFile.c_mode, (int) p->theFile.mode,
3157 p->theFile.c_attributes, (int) p->theFile.attributes,
3158 (int) p->theFile.hardlinks,
3159 p->theFile.c_owner, (int) p->theFile.owner,
3160 p->theFile.c_group, (int) p->theFile.group);
3161 }
3162
3163 if ('c' == p->theFile.c_mode[0] || 'b' == p->theFile.c_mode[0])
3164 sl_snprintf(str, 80, "%"PRIi64, p->theFile.rdev);
3165 else
3166 sl_snprintf(str, 80, "%"PRIi64, p->theFile.size);
3167
3168 printf( _(" %8s"), str);
3169 if (ListWithDelimiter == S_TRUE)
3170 putchar(',');
3171
3172 printf( _(" %s"), sh_unix_gmttime (p->theFile.ctime));
3173 if (ListWithDelimiter == S_TRUE)
3174 putchar(',');
3175 printf( _(" %s"), sh_unix_gmttime (p->theFile.mtime));
3176 if (ListWithDelimiter == S_TRUE)
3177 putchar(',');
3178 printf( _(" %s"), sh_unix_gmttime (p->theFile.atime));
3179 if (ListWithDelimiter == S_TRUE)
3180 putchar(',');
3181 printf( _(" %s"), p->theFile.checksum);
3182 if (ListWithDelimiter == S_TRUE)
3183 putchar(',');
3184
3185 tmp = sh_util_safe_name(p->fullpath);
3186 printf( _(" %s"), tmp);
3187 SH_FREE(tmp);
3188 if (ListWithDelimiter == S_TRUE)
3189 putchar(',');
3190
3191 if ('l' == p->theFile.c_mode[0])
3192 {
3193 tmp = sh_util_safe_name(p->linkpath);
3194 if (ListWithDelimiter == S_TRUE)
3195 printf(_(" %s\n"), tmp);
3196 else
3197 printf(_(" -> %s\n"), tmp);
3198 SH_FREE(tmp);
3199 }
3200 else
3201 printf("\n");
3202
3203 return;
3204}
3205
3206void sh_hash_list_db_entry (sh_file_t * p)
3207{
3208 char nowtime[128];
3209 char thetime[128];
3210 char * tmp;
3211 time_t now = time(NULL);
3212 time_t then = (time_t) p->theFile.mtime;
3213
3214 strftime(thetime, 127, _("%b %d %Y"), gmtime(&then));
3215 strftime(nowtime, 127, _("%b %d %Y"), gmtime(&now));
3216 if (0 == strncmp(&nowtime[7], &thetime[7], 4))
3217 strftime(thetime, 127, _("%b %d %H:%M"), gmtime(&then));
3218
3219 tmp = sh_util_safe_name(p->fullpath);
3220 if ('c' == p->theFile.c_mode[0] || 'b' == p->theFile.c_mode[0])
3221 printf(_("%10s %3d %-8s %-8s %3d,%4d %s %s"),
3222 p->theFile.c_mode, (int) p->theFile.hardlinks,
3223 p->theFile.c_owner, p->theFile.c_group,
3224 (int) major((dev_t)p->theFile.rdev),
3225 (int) minor((dev_t)p->theFile.rdev),
3226 thetime,
3227 tmp);
3228 else
3229 printf(_("%10s %3d %-8s %-8s %8ld %s %s"),
3230 p->theFile.c_mode, (int) p->theFile.hardlinks,
3231 p->theFile.c_owner, p->theFile.c_group, (long) p->theFile.size,
3232 thetime,
3233 tmp);
3234 SH_FREE(tmp);
3235
3236 if ('l' == p->theFile.c_mode[0])
3237 {
3238 tmp = sh_util_safe_name(p->linkpath);
3239 printf(_(" -> %s\n"), tmp);
3240 SH_FREE(tmp);
3241 }
3242 else
3243 printf("\n");
3244
3245 return;
3246}
3247
3248int sh_hash_list_db (char * db_file)
3249{
3250 sh_file_t * p;
3251 SL_TICKET fd;
3252 char * line;
3253
3254 if (!db_file)
3255 {
3256 _exit(EXIT_FAILURE);
3257 return -1;
3258 }
3259 if (sl_is_suid())
3260 {
3261 fprintf(stderr, _("ERROR: insufficient privilege\n"));
3262 _exit (EXIT_FAILURE);
3263 return -1; /* for Mac OSX compiler */
3264 }
3265 if (0 == strcmp(db_file, _("default")))
3266 db_file = file_path('D', 'W');
3267 if (!db_file)
3268 {
3269 _exit(EXIT_FAILURE);
3270 return -1;
3271 }
3272
3273 line = SH_ALLOC(MAX_PATH_STORE+1);
3274
3275 if ( SL_ISERROR(fd = sl_open_read(db_file, SL_YESPRIV)))
3276 {
3277 fprintf(stderr, _("ERROR: can't open %s for read (errnum = %ld)\n"),
3278 db_file, fd);
3279 _exit(EXIT_FAILURE);
3280 return -1;
3281 }
3282
3283 /* fast forward to start of data
3284 */
3285 sh_hash_setdataent(fd, line, MAX_PATH_STORE, db_file);
3286
3287 while (1)
3288 {
3289 p = sh_hash_getdataent (fd, line, MAX_PATH_STORE);
3290 if ((p != NULL) && (p->fullpath[0] != 'K'))
3291 {
3292 if (ListFullDetail == S_FALSE)
3293 sh_hash_list_db_entry (p);
3294 else
3295 sh_hash_list_db_entry_full_detail (p);
3296 }
3297 else if (p == NULL)
3298 {
3299 break;
3300 }
3301 }
3302
3303 if (line != NULL)
3304 SH_FREE(line);
3305 sl_close (fd);
3306
3307 fflush(NULL);
3308
3309 _exit(EXIT_SUCCESS);
3310 return 0;
3311}
3312
3313/* if defined(SH_WITH_CLIENT) || defined(SH_STANDALONE) */
3314#endif
Note: See TracBrowser for help on using the repository browser.