source: trunk/src/sh_hash.c@ 11

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

Support *BSD file flags

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