source: trunk/src/sh_hash.c@ 32

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

Support for server-to-server relay and more user policies

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