source: trunk/src/sh_hash.c@ 4

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

More fixes for update function, released 2.1.1 version.

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