source: trunk/src/sh_hash.c@ 39

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

Code cleanup and minor fixes

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