source: trunk/src/sh_hash.c@ 132

Last change on this file since 132 was 132, checked in by rainer, 17 years ago

Make utility functions thread-safe.

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