source: trunk/src/sh_hash.c@ 76

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

Fix for ticket #38 (csv escaping) and #39 (building on cygwin). Also optimize a bit.

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