2 * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
4 * This file is part of GnuPG.
6 * GnuPG is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * GnuPG 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.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
27 #include <sys/types.h>
43 #if defined(HAVE_DOSISH_SYSTEM)
44 #define ftruncate chsize
47 #if defined(HAVE_DOSISH_SYSTEM) || defined(__CYGWIN__)
48 #define MY_O_BINARY O_BINARY
55 * Yes, this is a very simple implementation. We should really
56 * use a page aligned buffer and read complete pages.
57 * To implement a simple trannsaction system, this is sufficient.
59 typedef struct cache_ctrl_struct
*CACHE_CTRL
;
60 struct cache_ctrl_struct
{
67 char data
[TRUST_RECORD_LEN
];
70 #define MAX_CACHE_ENTRIES_SOFT 200 /* may be increased while in a */
71 #define MAX_CACHE_ENTRIES_HARD 10000 /* transaction to this one */
72 static CACHE_CTRL cache_list
;
73 static int cache_entries
;
74 static int cache_is_dirty
;
76 /* a type used to pass infomation to cmp_krec_fpr */
77 struct cmp_krec_fpr_struct
{
83 /* a type used to pass infomation to cmp_[s]dir */
84 struct cmp_xdir_struct
{
91 static DOTLOCK lockhandle
;
93 static int db_fd
= -1;
94 static int in_transaction
;
96 static void open_db(void);
97 static void migrate_from_v2 (void);
101 /*************************************
102 ************* record cache **********
103 *************************************/
106 * Get the data from therecord cache and return a
107 * pointer into that cache. Caller should copy
108 * the return data. NULL is returned on a cache miss.
111 get_record_from_cache( ulong recno
)
115 for( r
= cache_list
; r
; r
= r
->next
) {
116 if( r
->flags
.used
&& r
->recno
== recno
)
124 write_cache_item( CACHE_CTRL r
)
129 if( lseek( db_fd
, r
->recno
* TRUST_RECORD_LEN
, SEEK_SET
) == -1 ) {
130 rc
= gpg_error_from_errno (errno
);
131 log_error(_("trustdb rec %lu: lseek failed: %s\n"),
132 r
->recno
, strerror(errno
) );
135 n
= write( db_fd
, r
->data
, TRUST_RECORD_LEN
);
136 if( n
!= TRUST_RECORD_LEN
) {
137 rc
= gpg_error_from_errno (errno
);
138 log_error(_("trustdb rec %lu: write failed (n=%d): %s\n"),
139 r
->recno
, n
, strerror(errno
) );
147 * Put data into the cache. This function may flush the
148 * some cache entries if there is not enough space available.
151 put_record_into_cache( ulong recno
, const char *data
)
153 CACHE_CTRL r
, unused
;
157 /* see whether we already cached this one */
158 for( unused
= NULL
, r
= cache_list
; r
; r
= r
->next
) {
159 if( !r
->flags
.used
) {
163 else if( r
->recno
== recno
) {
164 if( !r
->flags
.dirty
) {
165 /* Hmmm: should we use a a copy and compare? */
166 if( memcmp(r
->data
, data
, TRUST_RECORD_LEN
) ) {
171 memcpy( r
->data
, data
, TRUST_RECORD_LEN
);
174 if( r
->flags
.used
) {
181 /* not in the cache: add a new entry */
182 if( unused
) { /* reuse this entry */
186 memcpy( r
->data
, data
, TRUST_RECORD_LEN
);
192 /* see whether we reached the limit */
193 if( cache_entries
< MAX_CACHE_ENTRIES_SOFT
) { /* no */
194 r
= xmalloc ( sizeof *r
);
197 memcpy( r
->data
, data
, TRUST_RECORD_LEN
);
199 r
->next
= cache_list
;
205 /* cache is full: discard some clean entries */
207 int n
= clean_count
/ 3; /* discard a third of the clean entries */
210 for( unused
= NULL
, r
= cache_list
; r
; r
= r
->next
) {
211 if( r
->flags
.used
&& !r
->flags
.dirty
) {
224 memcpy( r
->data
, data
, TRUST_RECORD_LEN
);
230 /* no clean entries: have to flush some dirty entries */
231 if( in_transaction
) {
232 /* but we can't do this while in a transaction
233 * we increase the cache size instead */
234 if( cache_entries
< MAX_CACHE_ENTRIES_HARD
) { /* no */
235 if( opt
.debug
&& !(cache_entries
% 100) )
236 log_debug("increasing tdbio cache size\n");
237 r
= xmalloc ( sizeof *r
);
240 memcpy( r
->data
, data
, TRUST_RECORD_LEN
);
242 r
->next
= cache_list
;
248 log_info(_("trustdb transaction too large\n"));
249 return GPG_ERR_RESOURCE_LIMIT
;
252 int n
= dirty_count
/ 5; /* discard some dirty entries */
256 if( make_dotlock( lockhandle
, -1 ) )
257 log_fatal("can't acquire lock - giving up\n");
261 for( unused
= NULL
, r
= cache_list
; r
; r
= r
->next
) {
262 if( r
->flags
.used
&& r
->flags
.dirty
) {
263 int rc
= write_cache_item( r
);
274 if( !opt
.lock_once
) {
275 if( !release_dotlock( lockhandle
) )
282 memcpy( r
->data
, data
, TRUST_RECORD_LEN
);
295 return cache_is_dirty
;
300 * Flush the cache. This cannot be used while in a transaction.
311 log_bug("tdbio: syncing while in transaction\n");
313 if( !cache_is_dirty
)
317 if( make_dotlock( lockhandle
, -1 ) )
318 log_fatal("can't acquire lock - giving up\n");
323 for( r
= cache_list
; r
; r
= r
->next
) {
324 if( r
->flags
.used
&& r
->flags
.dirty
) {
325 int rc
= write_cache_item( r
);
331 if( did_lock
&& !opt
.lock_once
) {
332 if( !release_dotlock( lockhandle
) )
341 /* The transaction code is disabled in the 1.2.x branch, as it is not
342 yet used. It will be enabled in 1.3.x. */
345 * Simple transactions system:
346 * Everything between begin_transaction and end/cancel_transaction
347 * is not immediatly written but at the time of end_transaction.
351 tdbio_begin_transaction()
356 log_bug("tdbio: nested transactions\n");
357 /* flush everything out */
366 tdbio_end_transaction()
370 if( !in_transaction
)
371 log_bug("tdbio: no active transaction\n");
373 if( make_dotlock( lockhandle
, -1 ) )
374 log_fatal("can't acquire lock - giving up\n");
378 #warning block_all_signals is not yet available in ../common/signals.c
379 /* block_all_signals(); */
382 /* unblock_all_signals(); */
383 if( !opt
.lock_once
) {
384 if( !release_dotlock( lockhandle
) )
391 tdbio_cancel_transaction()
395 if( !in_transaction
)
396 log_bug("tdbio: no active transaction\n");
398 /* remove all dirty marked entries, so that the original ones
399 * are read back the next time */
400 if( cache_is_dirty
) {
401 for( r
= cache_list
; r
; r
= r
->next
) {
402 if( r
->flags
.used
&& r
->flags
.dirty
) {
414 #endif /* transaction code */
418 /********************************************************
419 **************** cached I/O functions ******************
420 ********************************************************/
426 if( !release_dotlock(lockhandle
) )
431 /* Caller must sync */
433 tdbio_update_version_record (void)
438 memset( &rec
, 0, sizeof rec
);
440 rc
=tdbio_read_record( 0, &rec
, RECTYPE_VER
);
443 rec
.r
.ver
.created
= make_timestamp();
444 rec
.r
.ver
.marginals
= opt
.marginals_needed
;
445 rec
.r
.ver
.completes
= opt
.completes_needed
;
446 rec
.r
.ver
.cert_depth
= opt
.max_cert_depth
;
447 rec
.r
.ver
.trust_model
= opt
.trust_model
;
448 rc
=tdbio_write_record(&rec
);
455 create_version_record (void)
460 memset( &rec
, 0, sizeof rec
);
461 rec
.r
.ver
.version
= 3;
462 rec
.r
.ver
.created
= make_timestamp();
463 rec
.r
.ver
.marginals
= opt
.marginals_needed
;
464 rec
.r
.ver
.completes
= opt
.completes_needed
;
465 rec
.r
.ver
.cert_depth
= opt
.max_cert_depth
;
466 if(opt
.trust_model
==TM_PGP
|| opt
.trust_model
==TM_CLASSIC
)
467 rec
.r
.ver
.trust_model
= opt
.trust_model
;
469 rec
.r
.ver
.trust_model
= TM_PGP
;
470 rec
.rectype
= RECTYPE_VER
;
472 rc
= tdbio_write_record( &rec
);
481 tdbio_set_dbname( const char *new_dbname
, int create
)
484 static int initialized
= 0;
492 fname
=make_filename(opt
.homedir
,"trustdb" EXTSEP_S
"gpg", NULL
);
493 else if (*new_dbname
!= DIRSEP_C
)
495 if (strchr(new_dbname
, DIRSEP_C
) )
496 fname
= make_filename (new_dbname
, NULL
);
498 fname
= make_filename (opt
.homedir
, new_dbname
, NULL
);
501 fname
= xstrdup (new_dbname
);
503 if( access( fname
, R_OK
) ) {
504 if( errno
!= ENOENT
) {
505 log_error( _("%s: can't access: %s\n"), fname
, strerror(errno
) );
507 return GPG_ERR_TRUSTDB
;
513 char *p
= strrchr( fname
, DIRSEP_C
);
518 if( access( fname
, F_OK
) ) {
519 try_make_homedir( fname
);
520 log_fatal( _("%s: directory does not exist!\n"), fname
);
528 lockhandle
= create_dotlock( db_name
);
530 log_fatal( _("%s: can't create lock\n"), db_name
);
531 if( make_dotlock( lockhandle
, -1 ) )
532 log_fatal( _("%s: can't make lock\n"), db_name
);
533 #endif /* __riscos__ */
535 fp
=fopen( fname
, "wb" );
538 log_fatal( _("%s: can't create: %s\n"), fname
, strerror(errno
) );
540 db_fd
= open( db_name
, O_RDWR
| MY_O_BINARY
);
542 log_fatal( _("%s: can't open: %s\n"), db_name
, strerror(errno
) );
546 lockhandle
= create_dotlock( db_name
);
548 log_fatal( _("%s: can't create lock\n"), db_name
);
549 #endif /* !__riscos__ */
551 rc
= create_version_record ();
553 log_fatal( _("%s: failed to create version record: %s"),
554 fname
, gpg_strerror (rc
));
555 /* and read again to check that we are okay */
556 if( tdbio_read_record( 0, &rec
, RECTYPE_VER
) )
557 log_fatal( _("%s: invalid trustdb created\n"), db_name
);
560 log_info(_("%s: trustdb created\n"), db_name
);
586 assert( db_fd
== -1 );
589 lockhandle
= create_dotlock( db_name
);
591 log_fatal( _("%s: can't create lock\n"), db_name
);
593 if (make_dotlock( lockhandle
, -1 ) )
594 log_fatal( _("%s: can't make lock\n"), db_name
);
595 #endif /* __riscos__ */
596 db_fd
= open (db_name
, O_RDWR
| MY_O_BINARY
);
597 if (db_fd
== -1 && errno
== EACCES
) {
598 db_fd
= open (db_name
, O_RDONLY
| MY_O_BINARY
);
600 log_info (_("NOTE: trustdb not writable\n"));
603 log_fatal( _("%s: can't open: %s\n"), db_name
, strerror(errno
) );
605 /* check whether we need to do a version migration */
607 n
= read (db_fd
, buf
, 5);
608 while (n
==-1 && errno
== EINTR
);
609 if (n
== 5 && !memcmp (buf
, "\x01gpg\x02", 5))
614 /* read the version record */
615 if (tdbio_read_record (0, &rec
, RECTYPE_VER
) )
616 log_fatal( _("%s: invalid trustdb\n"), db_name
);
621 * Make a hashtable: type 0 = trust hash
624 create_hashtable( TRUSTREC
*vr
, int type
)
631 offset
= lseek( db_fd
, 0, SEEK_END
);
633 log_fatal("trustdb: lseek to end failed: %s\n", strerror(errno
) );
634 recnum
= offset
/ TRUST_RECORD_LEN
;
635 assert(recnum
); /* this is will never be the first record */
638 vr
->r
.ver
.trusthashtbl
= recnum
;
640 /* Now write the records */
641 n
= (256+ITEMS_PER_HTBL_RECORD
-1) / ITEMS_PER_HTBL_RECORD
;
642 for(i
=0; i
< n
; i
++, recnum
++ ) {
643 memset( &rec
, 0, sizeof rec
);
644 rec
.rectype
= RECTYPE_HTBL
;
646 rc
= tdbio_write_record( &rec
);
648 log_fatal( _("%s: failed to create hashtable: %s\n"),
649 db_name
, gpg_strerror (rc
));
651 /* update the version record */
652 rc
= tdbio_write_record( vr
);
656 log_fatal( _("%s: error updating version record: %s\n"),
657 db_name
, gpg_strerror (rc
));
662 tdbio_db_matches_options()
664 static int yes_no
= -1;
671 rc
= tdbio_read_record( 0, &vr
, RECTYPE_VER
);
673 log_fatal( _("%s: error reading version record: %s\n"),
674 db_name
, gpg_strerror (rc
) );
676 yes_no
= vr
.r
.ver
.marginals
== opt
.marginals_needed
677 && vr
.r
.ver
.completes
== opt
.completes_needed
678 && vr
.r
.ver
.cert_depth
== opt
.max_cert_depth
679 && vr
.r
.ver
.trust_model
== opt
.trust_model
;
686 tdbio_read_model(void)
691 rc
= tdbio_read_record( 0, &vr
, RECTYPE_VER
);
693 log_fatal( _("%s: error reading version record: %s\n"),
694 db_name
, gpg_strerror (rc
) );
695 return vr
.r
.ver
.trust_model
;
699 * Return the nextstamp value.
702 tdbio_read_nextcheck ()
707 rc
= tdbio_read_record( 0, &vr
, RECTYPE_VER
);
709 log_fatal( _("%s: error reading version record: %s\n"),
710 db_name
, gpg_strerror (rc
) );
711 return vr
.r
.ver
.nextcheck
;
714 /* Return true when the stamp was actually changed. */
716 tdbio_write_nextcheck (ulong stamp
)
721 rc
= tdbio_read_record( 0, &vr
, RECTYPE_VER
);
723 log_fatal( _("%s: error reading version record: %s\n"),
724 db_name
, gpg_strerror (rc
) );
726 if (vr
.r
.ver
.nextcheck
== stamp
)
729 vr
.r
.ver
.nextcheck
= stamp
;
730 rc
= tdbio_write_record( &vr
);
732 log_fatal( _("%s: error writing version record: %s\n"),
733 db_name
, gpg_strerror (rc
) );
740 * Return the record number of the trusthash tbl or create a new one.
743 get_trusthashrec(void)
745 static ulong trusthashtbl
; /* record number of the trust hashtable */
747 if( !trusthashtbl
) {
751 rc
= tdbio_read_record( 0, &vr
, RECTYPE_VER
);
753 log_fatal( _("%s: error reading version record: %s\n"),
754 db_name
, gpg_strerror (rc
) );
755 if( !vr
.r
.ver
.trusthashtbl
)
756 create_hashtable( &vr
, 0 );
758 trusthashtbl
= vr
.r
.ver
.trusthashtbl
;
766 * Update a hashtable.
767 * table gives the start of the table, key and keylen is the key,
768 * newrecnum is the record number to insert.
771 upd_hashtable( ulong table
, byte
*key
, int keylen
, ulong newrecnum
)
773 TRUSTREC lastrec
, rec
;
782 hashrec
+= msb
/ ITEMS_PER_HTBL_RECORD
;
783 rc
= tdbio_read_record( hashrec
, &rec
, RECTYPE_HTBL
);
785 log_error ("upd_hashtable in `%s': read failed: %s\n", db_name
,
790 item
= rec
.r
.htbl
.item
[msb
% ITEMS_PER_HTBL_RECORD
];
791 if( !item
) { /* insert a new item into the hash table */
792 rec
.r
.htbl
.item
[msb
% ITEMS_PER_HTBL_RECORD
] = newrecnum
;
793 rc
= tdbio_write_record( &rec
);
795 log_error ("upd_hashtable in `%s': write htbl failed: %s\n",
796 db_name
, gpg_strerror (rc
) );
800 else if( item
!= newrecnum
) { /* must do an update */
802 rc
= tdbio_read_record( item
, &rec
, 0 );
804 log_error( "upd_hashtable: read item failed: %s\n",
809 if( rec
.rectype
== RECTYPE_HTBL
) {
812 if( level
>= keylen
) {
813 log_error( "hashtable has invalid indirections.\n");
814 return GPG_ERR_TRUSTDB
;
818 else if( rec
.rectype
== RECTYPE_HLST
) { /* extend list */
819 /* see whether the key is already in this list */
821 for(i
=0; i
< ITEMS_PER_HLST_RECORD
; i
++ ) {
822 if( rec
.r
.hlst
.rnum
[i
] == newrecnum
) {
823 return 0; /* okay, already in the list */
826 if( rec
.r
.hlst
.next
) {
827 rc
= tdbio_read_record( rec
.r
.hlst
.next
,
830 log_error( "upd_hashtable: read hlst failed: %s\n",
836 break; /* not there */
838 /* find the next free entry and put it in */
840 for(i
=0; i
< ITEMS_PER_HLST_RECORD
; i
++ ) {
841 if( !rec
.r
.hlst
.rnum
[i
] ) {
842 rec
.r
.hlst
.rnum
[i
] = newrecnum
;
843 rc
= tdbio_write_record( &rec
);
845 log_error( "upd_hashtable: write hlst failed: %s\n",
847 return rc
; /* done */
850 if( rec
.r
.hlst
.next
) {
851 rc
= tdbio_read_record( rec
.r
.hlst
.next
,
852 &rec
, RECTYPE_HLST
);
854 log_error( "upd_hashtable: read hlst failed: %s\n",
859 else { /* add a new list record */
860 rec
.r
.hlst
.next
= item
= tdbio_new_recnum();
861 rc
= tdbio_write_record( &rec
);
863 log_error( "upd_hashtable: write hlst failed: %s\n",
867 memset( &rec
, 0, sizeof rec
);
868 rec
.rectype
= RECTYPE_HLST
;
870 rec
.r
.hlst
.rnum
[0] = newrecnum
;
871 rc
= tdbio_write_record( &rec
);
873 log_error( "upd_hashtable: write ext hlst failed: %s\n",
875 return rc
; /* done */
877 } /* end loop over hlst slots */
879 else if( rec
.rectype
== RECTYPE_TRUST
) { /* insert a list record */
880 if( rec
.recnum
== newrecnum
) {
883 item
= rec
.recnum
; /* save number of key record */
884 memset( &rec
, 0, sizeof rec
);
885 rec
.rectype
= RECTYPE_HLST
;
886 rec
.recnum
= tdbio_new_recnum();
887 rec
.r
.hlst
.rnum
[0] = item
; /* old keyrecord */
888 rec
.r
.hlst
.rnum
[1] = newrecnum
; /* and new one */
889 rc
= tdbio_write_record( &rec
);
891 log_error( "upd_hashtable: write new hlst failed: %s\n",
895 /* update the hashtable record */
896 lastrec
.r
.htbl
.item
[msb
% ITEMS_PER_HTBL_RECORD
] = rec
.recnum
;
897 rc
= tdbio_write_record( &lastrec
);
899 log_error( "upd_hashtable: update htbl failed: %s\n",
901 return rc
; /* ready */
904 log_error( "hashtbl %lu: %lu/%d points to an invalid record %lu\n",
905 table
, hashrec
, (msb
% ITEMS_PER_HTBL_RECORD
), item
);
907 return GPG_ERR_TRUSTDB
;
916 * Drop an entry from a hashtable
917 * table gives the start of the table, key and keylen is the key,
920 drop_from_hashtable( ulong table
, byte
*key
, int keylen
, ulong recnum
)
931 hashrec
+= msb
/ ITEMS_PER_HTBL_RECORD
;
932 rc
= tdbio_read_record( hashrec
, &rec
, RECTYPE_HTBL
);
934 log_error ("drop_from_hashtable `%s': read failed: %s\n",
935 db_name
, gpg_strerror (rc
) );
939 item
= rec
.r
.htbl
.item
[msb
% ITEMS_PER_HTBL_RECORD
];
940 if( !item
) /* not found - forget about it */
943 if( item
== recnum
) { /* tables points direct to the record */
944 rec
.r
.htbl
.item
[msb
% ITEMS_PER_HTBL_RECORD
] = 0;
945 rc
= tdbio_write_record( &rec
);
947 log_error ("drop_from_hashtable `%s': write htbl failed: %s\n",
948 db_name
, gpg_strerror (rc
) );
952 rc
= tdbio_read_record( item
, &rec
, 0 );
954 log_error( "drop_from_hashtable: read item failed: %s\n",
959 if( rec
.rectype
== RECTYPE_HTBL
) {
962 if( level
>= keylen
) {
963 log_error( "hashtable has invalid indirections.\n");
964 return GPG_ERR_TRUSTDB
;
969 if( rec
.rectype
== RECTYPE_HLST
) {
971 for(i
=0; i
< ITEMS_PER_HLST_RECORD
; i
++ ) {
972 if( rec
.r
.hlst
.rnum
[i
] == recnum
) {
973 rec
.r
.hlst
.rnum
[i
] = 0; /* drop */
974 rc
= tdbio_write_record( &rec
);
976 log_error ("drop_from_hashtable `%s': "
977 "write htbl failed: %s\n",
978 db_name
, gpg_strerror (rc
) );
982 if( rec
.r
.hlst
.next
) {
983 rc
= tdbio_read_record( rec
.r
.hlst
.next
,
986 log_error( "drop_from_hashtable: read hlst failed: %s\n",
992 return 0; /* key not in table */
996 log_error( "hashtbl %lu: %lu/%d points to wrong record %lu\n",
997 table
, hashrec
, (msb
% ITEMS_PER_HTBL_RECORD
), item
);
998 return GPG_ERR_TRUSTDB
;
1004 * Lookup a record via the hashtable tablewith key/keylen and return the
1005 * result in rec. cmp() should return if the record is the desired one.
1006 * Returns -1 if not found, 0 if found or another errocode
1009 lookup_hashtable( ulong table
, const byte
*key
, size_t keylen
,
1010 int (*cmpfnc
)(void*, const TRUSTREC
*), void *cmpdata
,
1014 ulong hashrec
, item
;
1021 hashrec
+= msb
/ ITEMS_PER_HTBL_RECORD
;
1022 rc
= tdbio_read_record( hashrec
, rec
, RECTYPE_HTBL
);
1024 log_error ("lookup_hashtable in `%s' failed: %s\n",
1025 db_name
, gpg_strerror (rc
) );
1029 item
= rec
->r
.htbl
.item
[msb
% ITEMS_PER_HTBL_RECORD
];
1031 return -1; /* not found */
1033 rc
= tdbio_read_record( item
, rec
, 0 );
1035 log_error ("hashtable `%s' read failed: %s\n",
1036 db_name
, gpg_strerror (rc
) );
1039 if( rec
->rectype
== RECTYPE_HTBL
) {
1042 if( level
>= keylen
) {
1043 log_error ("hashtable `%s' has invalid indirections\n", db_name
);
1044 return GPG_ERR_TRUSTDB
;
1048 else if( rec
->rectype
== RECTYPE_HLST
) {
1052 for(i
=0; i
< ITEMS_PER_HLST_RECORD
; i
++ ) {
1053 if( rec
->r
.hlst
.rnum
[i
] ) {
1056 rc
= tdbio_read_record( rec
->r
.hlst
.rnum
[i
], &tmp
, 0 );
1058 log_error( "lookup_hashtable: read item failed: %s\n",
1059 gpg_strerror (rc
) );
1062 if( (*cmpfnc
)( cmpdata
, &tmp
) ) {
1068 if( rec
->r
.hlst
.next
) {
1069 rc
= tdbio_read_record( rec
->r
.hlst
.next
, rec
, RECTYPE_HLST
);
1071 log_error( "lookup_hashtable: read hlst failed: %s\n",
1072 gpg_strerror (rc
) );
1077 return -1; /* not found */
1082 if( (*cmpfnc
)( cmpdata
, rec
) )
1083 return 0; /* really found */
1085 return -1; /* no: not found */
1090 * Update the trust hashtbl or create the table if it does not exist
1093 update_trusthashtbl( TRUSTREC
*tr
)
1095 return upd_hashtable( get_trusthashrec(),
1096 tr
->r
.trust
.fingerprint
, 20, tr
->recnum
);
1102 tdbio_dump_record( TRUSTREC
*rec
, FILE *fp
)
1105 ulong rnum
= rec
->recnum
;
1107 fprintf(fp
, "rec %5lu, ", rnum
);
1109 switch( rec
->rectype
) {
1110 case 0: fprintf(fp
, "blank\n");
1112 case RECTYPE_VER
: fprintf(fp
,
1113 "version, td=%lu, f=%lu, m/c/d=%d/%d/%d tm=%d nc=%lu (%s)\n",
1114 rec
->r
.ver
.trusthashtbl
,
1115 rec
->r
.ver
.firstfree
,
1116 rec
->r
.ver
.marginals
,
1117 rec
->r
.ver
.completes
,
1118 rec
->r
.ver
.cert_depth
,
1119 rec
->r
.ver
.trust_model
,
1120 rec
->r
.ver
.nextcheck
,
1121 strtimestamp(rec
->r
.ver
.nextcheck
)
1124 case RECTYPE_FREE
: fprintf(fp
, "free, next=%lu\n", rec
->r
.free
.next
);
1127 fprintf(fp
, "htbl,");
1128 for(i
=0; i
< ITEMS_PER_HTBL_RECORD
; i
++ )
1129 fprintf(fp
, " %lu", rec
->r
.htbl
.item
[i
] );
1133 fprintf(fp
, "hlst, next=%lu,", rec
->r
.hlst
.next
);
1134 for(i
=0; i
< ITEMS_PER_HLST_RECORD
; i
++ )
1135 fprintf(fp
, " %lu", rec
->r
.hlst
.rnum
[i
] );
1139 fprintf(fp
, "trust ");
1140 for(i
=0; i
< 20; i
++ )
1141 fprintf(fp
, "%02X", rec
->r
.trust
.fingerprint
[i
] );
1142 fprintf (fp
, ", ot=%d, d=%d, vl=%lu\n", rec
->r
.trust
.ownertrust
,
1143 rec
->r
.trust
.depth
, rec
->r
.trust
.validlist
);
1146 fprintf(fp
, "valid ");
1147 for(i
=0; i
< 20; i
++ )
1148 fprintf(fp
, "%02X", rec
->r
.valid
.namehash
[i
] );
1149 fprintf (fp
, ", v=%d, next=%lu\n", rec
->r
.valid
.validity
,
1153 fprintf(fp
, "unknown type %d\n", rec
->rectype
);
1159 * read the record with number recnum
1160 * returns: -1 on error, 0 on success
1163 tdbio_read_record( ulong recnum
, TRUSTREC
*rec
, int expected
)
1165 byte readbuf
[TRUST_RECORD_LEN
];
1166 const byte
*buf
, *p
;
1172 buf
= get_record_from_cache( recnum
);
1174 if( lseek( db_fd
, recnum
* TRUST_RECORD_LEN
, SEEK_SET
) == -1 ) {
1175 rc
= gpg_error_from_errno (errno
);
1176 log_error(_("trustdb: lseek failed: %s\n"), strerror(errno
) );
1179 n
= read( db_fd
, readbuf
, TRUST_RECORD_LEN
);
1181 return -1; /* eof */
1183 else if( n
!= TRUST_RECORD_LEN
) {
1184 rc
= gpg_error_from_errno (errno
);
1185 log_error(_("trustdb: read failed (n=%d): %s\n"), n
,
1191 rec
->recnum
= recnum
;
1194 rec
->rectype
= *p
++;
1195 if( expected
&& rec
->rectype
!= expected
) {
1196 log_error("%lu: read expected rec type %d, got %d\n",
1197 recnum
, expected
, rec
->rectype
);
1198 return GPG_ERR_TRUSTDB
;
1200 p
++; /* skip reserved byte */
1201 switch( rec
->rectype
) {
1202 case 0: /* unused (free) record */
1204 case RECTYPE_VER
: /* version record */
1205 if( memcmp(buf
+1, "gpg", 3 ) ) {
1206 log_error( _("%s: not a trustdb file\n"), db_name
);
1207 rc
= GPG_ERR_TRUSTDB
;
1209 p
+= 2; /* skip "gpg" */
1210 rec
->r
.ver
.version
= *p
++;
1211 rec
->r
.ver
.marginals
= *p
++;
1212 rec
->r
.ver
.completes
= *p
++;
1213 rec
->r
.ver
.cert_depth
= *p
++;
1214 rec
->r
.ver
.trust_model
= *p
++;
1216 rec
->r
.ver
.created
= buftoulong(p
); p
+= 4;
1217 rec
->r
.ver
.nextcheck
= buftoulong(p
); p
+= 4;
1220 rec
->r
.ver
.firstfree
=buftoulong(p
); p
+= 4;
1222 rec
->r
.ver
.trusthashtbl
=buftoulong(p
); p
+= 4;
1224 log_error( _("%s: version record with recnum %lu\n"), db_name
,
1226 rc
= GPG_ERR_TRUSTDB
;
1228 else if( rec
->r
.ver
.version
!= 3 ) {
1229 log_error( _("%s: invalid file version %d\n"), db_name
,
1230 rec
->r
.ver
.version
);
1231 rc
= GPG_ERR_TRUSTDB
;
1235 rec
->r
.free
.next
= buftoulong(p
); p
+= 4;
1238 for(i
=0; i
< ITEMS_PER_HTBL_RECORD
; i
++ ) {
1239 rec
->r
.htbl
.item
[i
] = buftoulong(p
); p
+= 4;
1243 rec
->r
.hlst
.next
= buftoulong(p
); p
+= 4;
1244 for(i
=0; i
< ITEMS_PER_HLST_RECORD
; i
++ ) {
1245 rec
->r
.hlst
.rnum
[i
] = buftoulong(p
); p
+= 4;
1249 memcpy( rec
->r
.trust
.fingerprint
, p
, 20); p
+=20;
1250 rec
->r
.trust
.ownertrust
= *p
++;
1251 rec
->r
.trust
.depth
= *p
++;
1252 rec
->r
.trust
.min_ownertrust
= *p
++;
1254 rec
->r
.trust
.validlist
= buftoulong(p
); p
+= 4;
1257 memcpy( rec
->r
.valid
.namehash
, p
, 20); p
+=20;
1258 rec
->r
.valid
.validity
= *p
++;
1259 rec
->r
.valid
.next
= buftoulong(p
); p
+= 4;
1260 rec
->r
.valid
.full_count
= *p
++;
1261 rec
->r
.valid
.marginal_count
= *p
++;
1264 log_error( "%s: invalid record type %d at recnum %lu\n",
1265 db_name
, rec
->rectype
, (ulong
)recnum
);
1266 rc
= GPG_ERR_TRUSTDB
;
1274 * Write the record at RECNUM
1277 tdbio_write_record( TRUSTREC
*rec
)
1279 byte buf
[TRUST_RECORD_LEN
], *p
;
1282 ulong recnum
= rec
->recnum
;
1287 memset(buf
, 0, TRUST_RECORD_LEN
);
1289 *p
++ = rec
->rectype
; p
++;
1290 switch( rec
->rectype
) {
1291 case 0: /* unused record */
1293 case RECTYPE_VER
: /* version record */
1296 memcpy(p
-1, "gpg", 3 ); p
+= 2;
1297 *p
++ = rec
->r
.ver
.version
;
1298 *p
++ = rec
->r
.ver
.marginals
;
1299 *p
++ = rec
->r
.ver
.completes
;
1300 *p
++ = rec
->r
.ver
.cert_depth
;
1301 *p
++ = rec
->r
.ver
.trust_model
;
1303 ulongtobuf(p
, rec
->r
.ver
.created
); p
+= 4;
1304 ulongtobuf(p
, rec
->r
.ver
.nextcheck
); p
+= 4;
1307 ulongtobuf(p
, rec
->r
.ver
.firstfree
); p
+= 4;
1309 ulongtobuf(p
, rec
->r
.ver
.trusthashtbl
); p
+= 4;
1313 ulongtobuf(p
, rec
->r
.free
.next
); p
+= 4;
1318 for(i
=0; i
< ITEMS_PER_HTBL_RECORD
; i
++ ) {
1319 ulongtobuf( p
, rec
->r
.htbl
.item
[i
]); p
+= 4;
1324 ulongtobuf( p
, rec
->r
.hlst
.next
); p
+= 4;
1325 for(i
=0; i
< ITEMS_PER_HLST_RECORD
; i
++ ) {
1326 ulongtobuf( p
, rec
->r
.hlst
.rnum
[i
]); p
+= 4;
1331 memcpy( p
, rec
->r
.trust
.fingerprint
, 20); p
+= 20;
1332 *p
++ = rec
->r
.trust
.ownertrust
;
1333 *p
++ = rec
->r
.trust
.depth
;
1334 *p
++ = rec
->r
.trust
.min_ownertrust
;
1336 ulongtobuf( p
, rec
->r
.trust
.validlist
); p
+= 4;
1340 memcpy( p
, rec
->r
.valid
.namehash
, 20); p
+= 20;
1341 *p
++ = rec
->r
.valid
.validity
;
1342 ulongtobuf( p
, rec
->r
.valid
.next
); p
+= 4;
1343 *p
++ = rec
->r
.valid
.full_count
;
1344 *p
++ = rec
->r
.valid
.marginal_count
;
1351 rc
= put_record_into_cache( recnum
, buf
);
1354 else if( rec
->rectype
== RECTYPE_TRUST
)
1355 rc
= update_trusthashtbl( rec
);
1361 tdbio_delete_record( ulong recnum
)
1366 /* Must read the record fist, so we can drop it from the hash tables */
1367 rc
= tdbio_read_record( recnum
, &rec
, 0 );
1370 else if( rec
.rectype
== RECTYPE_TRUST
) {
1371 rc
= drop_from_hashtable( get_trusthashrec(),
1372 rec
.r
.trust
.fingerprint
, 20, rec
.recnum
);
1378 /* now we can chnage it to a free record */
1379 rc
= tdbio_read_record( 0, &vr
, RECTYPE_VER
);
1381 log_fatal( _("%s: error reading version record: %s\n"),
1382 db_name
, gpg_strerror (rc
) );
1384 rec
.recnum
= recnum
;
1385 rec
.rectype
= RECTYPE_FREE
;
1386 rec
.r
.free
.next
= vr
.r
.ver
.firstfree
;
1387 vr
.r
.ver
.firstfree
= recnum
;
1388 rc
= tdbio_write_record( &rec
);
1390 rc
= tdbio_write_record( &vr
);
1395 * create a new record and return its record number
1405 /* look for unused records */
1406 rc
= tdbio_read_record( 0, &vr
, RECTYPE_VER
);
1408 log_fatal( _("%s: error reading version record: %s\n"),
1409 db_name
, gpg_strerror (rc
) );
1410 if( vr
.r
.ver
.firstfree
) {
1411 recnum
= vr
.r
.ver
.firstfree
;
1412 rc
= tdbio_read_record( recnum
, &rec
, RECTYPE_FREE
);
1414 log_error( _("%s: error reading free record: %s\n"),
1415 db_name
, gpg_strerror (rc
) );
1418 /* update dir record */
1419 vr
.r
.ver
.firstfree
= rec
.r
.free
.next
;
1420 rc
= tdbio_write_record( &vr
);
1422 log_error( _("%s: error writing dir record: %s\n"),
1423 db_name
, gpg_strerror (rc
) );
1426 /*zero out the new record */
1427 memset( &rec
, 0, sizeof rec
);
1428 rec
.rectype
= 0; /* unused record */
1429 rec
.recnum
= recnum
;
1430 rc
= tdbio_write_record( &rec
);
1432 log_fatal(_("%s: failed to zero a record: %s\n"),
1433 db_name
, gpg_strerror (rc
));
1435 else { /* not found, append a new record */
1436 offset
= lseek( db_fd
, 0, SEEK_END
);
1438 log_fatal("trustdb: lseek to end failed: %s\n", strerror(errno
) );
1439 recnum
= offset
/ TRUST_RECORD_LEN
;
1440 assert(recnum
); /* this is will never be the first record */
1441 /* we must write a record, so that the next call to this function
1442 * returns another recnum */
1443 memset( &rec
, 0, sizeof rec
);
1444 rec
.rectype
= 0; /* unused record */
1445 rec
.recnum
= recnum
;
1447 if( lseek( db_fd
, recnum
* TRUST_RECORD_LEN
, SEEK_SET
) == -1 ) {
1448 rc
= gpg_error_from_errno (errno
);
1449 log_error(_("trustdb rec %lu: lseek failed: %s\n"),
1450 recnum
, strerror(errno
) );
1453 int n
= write( db_fd
, &rec
, TRUST_RECORD_LEN
);
1454 if( n
!= TRUST_RECORD_LEN
) {
1455 rc
= gpg_error_from_errno (errno
);
1456 log_error(_("trustdb rec %lu: write failed (n=%d): %s\n"),
1457 recnum
, n
, strerror(errno
) );
1462 log_fatal(_("%s: failed to append a record: %s\n"),
1463 db_name
, gpg_strerror (rc
));
1471 cmp_trec_fpr ( void *fpr
, const TRUSTREC
*rec
)
1473 return rec
->rectype
== RECTYPE_TRUST
1474 && !memcmp( rec
->r
.trust
.fingerprint
, fpr
, 20);
1479 tdbio_search_trust_byfpr( const byte
*fingerprint
, TRUSTREC
*rec
)
1483 /* locate the trust record using the hash table */
1484 rc
= lookup_hashtable( get_trusthashrec(), fingerprint
, 20,
1485 cmp_trec_fpr
, (void*)fingerprint
, rec
);
1490 tdbio_search_trust_bypk (PKT_public_key
*pk
, TRUSTREC
*rec
)
1492 byte fingerprint
[MAX_FINGERPRINT_LEN
];
1495 fingerprint_from_pk( pk
, fingerprint
, &fingerlen
);
1496 for (; fingerlen
< 20; fingerlen
++ )
1497 fingerprint
[fingerlen
] = 0;
1498 return tdbio_search_trust_byfpr (fingerprint
, rec
);
1507 "the trustdb is corrupted; please run \"gpg --fix-trustdb\".\n") );
1512 * Migrate the trustdb as just up to gpg 1.0.6 (trustdb version 2)
1513 * to the 2.1 version as used with 1.0.6b - This is pretty trivial as needs
1514 * only to scan the tdb and insert new the new trust records. The old ones are
1515 * obsolte from now on
1528 int ottable_size
, ottable_used
;
1534 ottable
= xmalloc (ottable_size
* sizeof *ottable
);
1537 /* We have some restrictions here. We can't use the version record
1538 * and we can't use any of the old hashtables because we dropped the
1539 * code. So we first collect all ownertrusts and then use a second
1540 * pass fo find the associated keys. We have to do this all without using
1541 * the regular record read functions.
1544 /* get all the ownertrusts */
1545 if (lseek (db_fd
, 0, SEEK_SET
) == -1 )
1546 log_fatal ("migrate_from_v2: lseek failed: %s\n", strerror (errno
));
1547 for (recno
=0;;recno
++)
1550 n
= read (db_fd
, oldbuf
, 40);
1551 while (n
==-1 && errno
== EINTR
);
1555 log_fatal ("migrate_vfrom_v2: read error or short read\n");
1561 if (ottable_used
== ottable_size
)
1563 ottable_size
+= 1000;
1564 ottable
= xrealloc (ottable
, ottable_size
* sizeof *ottable
);
1566 ottable
[ottable_used
].keyrecno
= buftoulong (oldbuf
+6);
1567 ottable
[ottable_used
].ot
= oldbuf
[18];
1568 ottable
[ottable_used
].okay
= 0;
1569 memset (ottable
[ottable_used
].fpr
,0, 20);
1570 if (ottable
[ottable_used
].keyrecno
&& ottable
[ottable_used
].ot
)
1573 log_info ("found %d ownertrust records\n", ottable_used
);
1575 /* Read again and find the fingerprints */
1576 if (lseek (db_fd
, 0, SEEK_SET
) == -1 )
1577 log_fatal ("migrate_from_v2: lseek failed: %s\n", strerror (errno
));
1578 for (recno
=0;;recno
++)
1581 n
= read (db_fd
, oldbuf
, 40);
1582 while (n
==-1 && errno
== EINTR
);
1586 log_fatal ("migrate_from_v2: read error or short read\n");
1592 for (i
=0; i
< ottable_used
; i
++)
1594 if (ottable
[i
].keyrecno
== recno
)
1596 memcpy (ottable
[i
].fpr
, oldbuf
+20, 20);
1597 ottable
[i
].okay
= 1;
1603 /* got everything - create the v3 trustdb */
1604 if (ftruncate (db_fd
, 0))
1605 log_fatal ("can't truncate `%s': %s\n", db_name
, strerror (errno
) );
1606 if (create_version_record ())
1607 log_fatal ("failed to recreate version record of `%s'\n", db_name
);
1609 /* access the hash table, so it is store just after the version record,
1610 * this is not needed put a dump is more pretty */
1611 get_trusthashrec ();
1613 /* And insert the old ownertrust values */
1615 for (i
=0; i
< ottable_used
; i
++)
1617 if (!ottable
[i
].okay
)
1620 memset (&rec
, 0, sizeof rec
);
1621 rec
.recnum
= tdbio_new_recnum ();
1622 rec
.rectype
= RECTYPE_TRUST
;
1623 memcpy(rec
.r
.trust
.fingerprint
, ottable
[i
].fpr
, 20);
1624 rec
.r
.trust
.ownertrust
= ottable
[i
].ot
;
1625 if (tdbio_write_record (&rec
))
1626 log_fatal ("failed to write trust record of `%s'\n", db_name
);
1630 revalidation_mark ();
1633 log_fatal ("failed to sync `%s'\n", db_name
);
1634 log_info ("migrated %d version 2 ownertrusts\n", count
);