diff --git a/.files b/.files
index d229323..f0aa441 100644
Binary files a/.files and b/.files differ
diff --git a/.rev b/.rev
index ce3e804..ea1b87f 100644
--- a/.rev
+++ b/.rev
@@ -2174,4 +2174,12 @@ See bugzilla 1167537 for the gory details.
- Initialize the libgcrypt library [bnc#1167343]
791720
+
+ 133d57e28fa59b334193b6e94a8102b4
+ 4.15.1
+
+ dimstar_suse
+ - Fix verification of DSA2 signatures with libgrcypt [bnc#1165731]
+ 793802
+
diff --git a/gcryptdsa2.diff b/gcryptdsa2.diff
new file mode 100644
index 0000000..b9d1037
--- /dev/null
+++ b/gcryptdsa2.diff
@@ -0,0 +1,19 @@
+--- ./rpmio/digest_libgcrypt.c.orig
++++ ./rpmio/digest_libgcrypt.c
+@@ -302,10 +302,16 @@ static int pgpVerifySigDSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig, uint8_t *hash, si
+ struct pgpDigSigDSA_s *sig = pgpsig->data;
+ gcry_sexp_t sexp_sig = NULL, sexp_data = NULL, sexp_pkey = NULL;
+ int rc = 1;
++ size_t qlen;
+
+ if (!sig || !key)
+ return rc;
+
++ qlen = (mpi_get_nbits(key->q) + 7) / 8;
++ if (qlen < 20)
++ qlen = 20; /* sanity */
++ if (hashlen > qlen)
++ hashlen = qlen; /* dsa2: truncate hash to qlen */
+ gcry_sexp_build(&sexp_sig, NULL, "(sig-val (dsa (r %M) (s %M)))", sig->r, sig->s);
+ gcry_sexp_build(&sexp_data, NULL, "(data (flags raw) (value %b))", (int)hashlen, (const char *)hash);
+ gcry_sexp_build(&sexp_pkey, NULL, "(public-key (dsa (p %M) (q %M) (g %M) (y %M)))", key->p, key->q, key->g, key->y);
diff --git a/ndb_backport2.diff b/ndb_backport2.diff
new file mode 100644
index 0000000..8f15b8b
--- /dev/null
+++ b/ndb_backport2.diff
@@ -0,0 +1,305 @@
+--- ./lib/backend/ndb/glue.c.orig 2020-04-03 10:24:27.954135180 +0000
++++ ./lib/backend/ndb/glue.c 2020-04-14 09:48:23.304231127 +0000
+@@ -143,9 +143,6 @@ static int ndb_Open(rpmdb rdb, rpmDbiTag
+ free(path);
+ dbi->dbi_db = ndbenv->pkgdb = pkgdb;
+ rpmpkgSetFsync(pkgdb, ndbenv->dofsync);
+-
+- if ((oflags & (O_RDWR | O_RDONLY)) == O_RDONLY)
+- dbi->dbi_flags |= DBI_RDONLY;
+ } else {
+ unsigned int id;
+ rpmidxdb idxdb = 0;
+@@ -184,20 +181,20 @@ static int ndb_Open(rpmdb rdb, rpmDbiTag
+ ndb_CheckIndexSync(ndbenv->pkgdb, ndbenv->xdb);
+ }
+ if (rpmxdbLookupBlob(ndbenv->xdb, &id, rpmtag, 0, 0) == RPMRC_NOTFOUND) {
++ oflags = O_RDWR|O_CREAT;
+ dbi->dbi_flags |= DBI_CREATED;
+ }
+ rpmlog(RPMLOG_DEBUG, "opening db index %s tag=%d\n", dbiName(dbi), rpmtag);
+- if (rpmidxOpenXdb(&idxdb, rdb->db_pkgs->dbi_db, ndbenv->xdb, rpmtag)) {
++ if (rpmidxOpenXdb(&idxdb, rdb->db_pkgs->dbi_db, ndbenv->xdb, rpmtag, oflags)) {
+ perror("rpmidxOpenXdb");
+ ndb_Close(dbi, 0);
+ return 1;
+ }
+ dbi->dbi_db = idxdb;
+-
+- if (rpmxdbIsRdonly(ndbenv->xdb))
+- dbi->dbi_flags |= DBI_RDONLY;
+ }
+
++ if ((oflags & (O_RDWR | O_RDONLY)) == O_RDONLY)
++ dbi->dbi_flags |= DBI_RDONLY;
+
+ if (dbip != NULL)
+ *dbip = dbi;
+--- ./lib/backend/ndb/rpmidx.c.orig 2019-11-13 09:19:29.305710571 +0000
++++ ./lib/backend/ndb/rpmidx.c 2020-04-14 09:48:23.304231127 +0000
+@@ -885,13 +885,17 @@ int rpmidxOpen(rpmidxdb *idxdbp, rpmpkgd
+ return RPMRC_FAIL;
+ }
+
+-int rpmidxOpenXdb(rpmidxdb *idxdbp, rpmpkgdb pkgdb, rpmxdb xdb, unsigned int xdbtag)
++int rpmidxOpenXdb(rpmidxdb *idxdbp, rpmpkgdb pkgdb, rpmxdb xdb, unsigned int xdbtag, int flags)
+ {
+ rpmidxdb idxdb;
+ unsigned int id;
+ *idxdbp = 0;
+ int rc;
+
++ if (rpmxdbIsRdonly(xdb) && (flags & (O_RDONLY|O_RDWR)) != O_RDONLY) {
++ errno = EACCES;
++ return RPMRC_FAIL;
++ }
+ if (rpmxdbLock(xdb, 0))
+ return RPMRC_FAIL;
+ rc = rpmxdbLookupBlob(xdb, &id, xdbtag, IDXDB_XDB_SUBTAG, 0);
+@@ -907,7 +911,7 @@ int rpmidxOpenXdb(rpmidxdb *idxdbp, rpmp
+ idxdb->xdbid = id;
+ idxdb->pkgdb = pkgdb;
+ idxdb->pagesize = rpmxdbPagesize(xdb);
+- idxdb->rdonly = rpmxdbIsRdonly(xdb) ? 1 : 0;
++ idxdb->rdonly = (flags & (O_RDONLY|O_RDWR)) == O_RDONLY ? 1 : 0;
+ if (!id) {
+ if (rpmidxInit(idxdb)) {
+ free(idxdb);
+--- ./lib/backend/ndb/rpmidx.h.orig 2019-06-26 14:17:31.406985703 +0000
++++ ./lib/backend/ndb/rpmidx.h 2020-04-14 09:48:23.304231127 +0000
+@@ -5,7 +5,7 @@ struct rpmidxdb_s;
+ typedef struct rpmidxdb_s *rpmidxdb;
+
+ int rpmidxOpen(rpmidxdb *idxdbp, rpmpkgdb pkgdb, const char *filename, int flags, int mode);
+-int rpmidxOpenXdb(rpmidxdb *idxdbp, rpmpkgdb pkgdb, rpmxdb xdb, unsigned int xdbtag);
++int rpmidxOpenXdb(rpmidxdb *idxdbp, rpmpkgdb pkgdb, rpmxdb xdb, unsigned int xdbtag, int flags);
+ int rpmidxDelXdb(rpmpkgdb pkgdb, rpmxdb xdb, unsigned int xdbtag);
+ void rpmidxClose(rpmidxdb idxdbp);
+
+--- ./lib/backend/ndb/rpmxdb.c.orig 2020-04-03 10:24:27.954135180 +0000
++++ ./lib/backend/ndb/rpmxdb.c 2020-04-14 09:48:23.304231127 +0000
+@@ -36,7 +36,7 @@ typedef struct rpmxdb_s {
+ unsigned int usergeneration;
+
+ unsigned char *mapped;
+- int mapflags;
++ int mappedrw;
+ unsigned int mappedlen;
+
+ struct xdb_slot {
+@@ -57,6 +57,7 @@ typedef struct rpmxdb_s {
+ unsigned int usedblobpages;
+ unsigned int systempagesize;
+ int dofsync;
++ unsigned int locked_excl;
+ } *rpmxdb;
+
+
+@@ -125,17 +126,19 @@ static void unmapmem(void *addr, size_t
+ #define ROUNDTOSYSTEMPAGE(xdb, size) (((size) + (xdb->systempagesize - 1)) & ~(xdb->systempagesize - 1))
+
+ /* xdb header mapping functions */
+-static int mapheader(rpmxdb xdb, unsigned int slotnpages)
++static int mapheader(rpmxdb xdb, unsigned int slotnpages, int rw)
+ {
+ unsigned char *mapped;
+ size_t mappedlen = slotnpages * xdb->pagesize;
++ int mapflags = rw ? PROT_READ | PROT_WRITE : PROT_READ;
+
+ mappedlen = ROUNDTOSYSTEMPAGE(xdb, mappedlen);
+- mapped = mapmem(xdb->mapped, xdb->mappedlen, mappedlen, xdb->mapflags, xdb->fd, 0);
++ mapped = mapmem(xdb->mapped, xdb->mappedlen, mappedlen, mapflags, xdb->fd, 0);
+ if ((void *)mapped == MAP_FAILED)
+ return RPMRC_FAIL;
+ xdb->mapped = mapped;
+ xdb->mappedlen = mappedlen;
++ xdb->mappedrw = rw;
+ return RPMRC_OK;
+ }
+
+@@ -247,7 +250,7 @@ static int rpmxdbReadHeaderRaw(rpmxdb xd
+ return RPMRC_OK;
+ }
+
+-static int rpmxdbReadHeader(rpmxdb xdb)
++static int rpmxdbReadHeader(rpmxdb xdb, int rw)
+ {
+ struct xdb_slot *slot;
+ unsigned int slotnpages, pagesize, generation, usergeneration;
+@@ -261,6 +264,11 @@ static int rpmxdbReadHeader(rpmxdb xdb)
+
+ if (xdb->mapped) {
+ if (le2ha(xdb->mapped + XDB_OFFSET_GENERATION) == xdb->generation) {
++ if (rw && !xdb->mappedrw) {
++ unmapheader(xdb);
++ if (mapheader(xdb, xdb->slotnpages, rw))
++ return RPMRC_FAIL;
++ }
+ return RPMRC_OK;
+ }
+ unmapheader(xdb);
+@@ -273,9 +281,8 @@ static int rpmxdbReadHeader(rpmxdb xdb)
+ if (stb.st_size % pagesize != 0)
+ return RPMRC_FAIL;
+ xdb->pagesize = pagesize;
+- xdb->mapflags = xdb->rdonly ? PROT_READ : PROT_READ | PROT_WRITE;
+
+- if (mapheader(xdb, slotnpages))
++ if (mapheader(xdb, slotnpages, rw))
+ return RPMRC_FAIL;
+
+ /* read in all slots */
+@@ -368,6 +375,8 @@ static int rpmxdbReadHeader(rpmxdb xdb)
+ nslot->mapcallback(xdb, nslot->mapcallbackdata, 0, 0);
+ }
+ }
++ } else {
++ nslot->mapped = slot->mapped;
+ }
+ }
+ }
+@@ -382,17 +391,14 @@ static int rpmxdbReadHeader(rpmxdb xdb)
+ return RPMRC_OK;
+ }
+
+-static int rpmxdbWriteHeader(rpmxdb xdb)
++static void rpmxdbWriteHeader(rpmxdb xdb)
+ {
+- if (!xdb->mapped)
+- return RPMRC_FAIL;
+ h2lea(XDB_MAGIC, xdb->mapped + XDB_OFFSET_MAGIC);
+ h2lea(XDB_VERSION, xdb->mapped + XDB_OFFSET_VERSION);
+ h2lea(xdb->generation, xdb->mapped + XDB_OFFSET_GENERATION);
+ h2lea(xdb->slotnpages, xdb->mapped + XDB_OFFSET_SLOTNPAGES);
+ h2lea(xdb->pagesize, xdb->mapped + XDB_OFFSET_PAGESIZE);
+ h2lea(xdb->usergeneration, xdb->mapped + XDB_OFFSET_USERGENERATION);
+- return RPMRC_OK;
+ }
+
+ static void rpmxdbUpdateSlot(rpmxdb xdb, struct xdb_slot *slot)
+@@ -473,19 +479,25 @@ static int rpmxdbInitInternal(rpmxdb xdb
+ /* we use the master pdb for locking */
+ static int rpmxdbLockOnly(rpmxdb xdb, int excl)
+ {
++ int rc;
+ if (excl && xdb->rdonly)
+ return RPMRC_FAIL;
+- return rpmpkgLock(xdb->pkgdb, excl);
++ rc = rpmpkgLock(xdb->pkgdb, excl);
++ if (!rc && excl)
++ xdb->locked_excl++;
++ return rc;
+ }
+
+-/* this is the same as rpmxdbLockReadHeader. It does the
++/* This is similar to rpmxdbLockReadHeader. It does the
+ * ReadHeader to sync the mappings if xdb moved some blobs.
++ * Note that we just ask for rad-only access in the
++ * rpmxdbReadHeader call.
+ */
+ int rpmxdbLock(rpmxdb xdb, int excl)
+ {
+ if (rpmxdbLockOnly(xdb, excl))
+ return RPMRC_FAIL;
+- if (rpmxdbReadHeader(xdb)) {
++ if (rpmxdbReadHeader(xdb, 0)) {
+ rpmxdbUnlock(xdb, excl);
+ return RPMRC_FAIL;
+ }
+@@ -494,14 +506,25 @@ int rpmxdbLock(rpmxdb xdb, int excl)
+
+ int rpmxdbUnlock(rpmxdb xdb, int excl)
+ {
++ if (excl && xdb->locked_excl) {
++ xdb->locked_excl--;
++ if (!xdb->locked_excl && xdb->mapped && xdb->mappedrw) {
++ unmapheader(xdb);
++ mapheader(xdb, xdb->slotnpages, 0);
++ }
++ }
+ return rpmpkgUnlock(xdb->pkgdb, excl);
+ }
+
++/* Like rpmxdbLock, but map the header rw if excl is set.
++ * This is what the functions in this module use, whereas
++ * rpmidx uses rpmxdbLock.
++ */
+ static int rpmxdbLockReadHeader(rpmxdb xdb, int excl)
+ {
+ if (rpmxdbLockOnly(xdb, excl))
+ return RPMRC_FAIL;
+- if (rpmxdbReadHeader(xdb)) {
++ if (rpmxdbReadHeader(xdb, excl)) {
+ rpmxdbUnlock(xdb, excl);
+ return RPMRC_FAIL;
+ }
+@@ -594,6 +617,8 @@ void rpmxdbClose(rpmxdb xdb)
+ }
+ if (xdb->slots)
+ free(xdb->slots);
++ if (xdb->mapped)
++ unmapheader(xdb);
+ if (xdb->fd >= 0)
+ close(xdb->fd);
+ if (xdb->filename)
+@@ -623,7 +648,8 @@ static int moveblobto(rpmxdb xdb, struct
+ didmap = 0;
+ oldpagecnt = oldslot->pagecnt;
+ if (!oldslot->mapped && oldpagecnt) {
+- oldslot->mapflags = PROT_READ;
++ if (!oldslot->mapcallback)
++ oldslot->mapflags = PROT_READ;
+ if (mapslot(xdb, oldslot))
+ return RPMRC_FAIL;
+ didmap = 1;
+@@ -772,7 +798,7 @@ static int addslotpage(rpmxdb xdb)
+ return RPMRC_FAIL;
+
+ /* remap the header */
+- if (mapheader(xdb, xdb->slotnpages + 1))
++ if (mapheader(xdb, xdb->slotnpages + 1, xdb->mappedrw))
+ return RPMRC_FAIL;
+
+ /* update the header */
+@@ -852,7 +878,8 @@ int rpmxdbLookupBlob(rpmxdb xdb, unsigne
+ {
+ struct xdb_slot *slot;
+ unsigned int i, nslots;
+- if (rpmxdbLockReadHeader(xdb, flags ? 1 : 0))
++ int excl = flags ? 1 : 0;
++ if (rpmxdbLockReadHeader(xdb, excl))
+ return RPMRC_FAIL;
+ nslots = xdb->nslots;
+ slot = 0;
+@@ -865,18 +892,18 @@ int rpmxdbLookupBlob(rpmxdb xdb, unsigne
+ i = 0;
+ if (i && (flags & O_TRUNC) != 0) {
+ if (rpmxdbResizeBlob(xdb, i, 0)) {
+- rpmxdbUnlock(xdb, flags ? 1 : 0);
++ rpmxdbUnlock(xdb, excl);
+ return RPMRC_FAIL;
+ }
+ }
+ if (!i && (flags & O_CREAT) != 0) {
+ if (createblob(xdb, &i, blobtag, subtag)) {
+- rpmxdbUnlock(xdb, flags ? 1 : 0);
++ rpmxdbUnlock(xdb, excl);
+ return RPMRC_FAIL;
+ }
+ }
+ *idp = i;
+- rpmxdbUnlock(xdb, flags ? 1 : 0);
++ rpmxdbUnlock(xdb, excl);
+ return i ? RPMRC_OK : RPMRC_NOTFOUND;
+ }
+
+--- ./lib/rpmdb.c.orig 2020-04-03 10:24:27.954135180 +0000
++++ ./lib/rpmdb.c 2020-04-14 09:48:23.304231127 +0000
+@@ -2622,6 +2622,7 @@ int rpmdbRebuild(const char * prefix, rp
+ }
+
+ rpmdbClose(olddb);
++ dbCtrl(newdb, DB_CTRL_INDEXSYNC);
+ rpmdbClose(newdb);
+
+ if (failed) {
diff --git a/python-rpm.spec b/python-rpm.spec
index 109159d..093afb5 100644
--- a/python-rpm.spec
+++ b/python-rpm.spec
@@ -1,7 +1,7 @@
#
# spec file for package python-rpm
#
-# Copyright (c) 2020 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2020 SUSE LLC
# Copyright (c) 2017 Neal Gompa .
#
# All modifications and additions to the file contributed by third parties
@@ -13,7 +13,7 @@
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
#
diff --git a/rpm.changes b/rpm.changes
index c677046..0f82168 100644
--- a/rpm.changes
+++ b/rpm.changes
@@ -1,4 +1,17 @@
-------------------------------------------------------------------
+Tue Apr 14 11:50:49 CEST 2020 - mls@suse.de
+
+- Fix verification of DSA2 signatures with libgrcypt [bnc#1165731]
+ * new patch: gcryptdsa2.diff
+- Do not map the index database read-write all the time
+ * new patch: ndb_backport2.diff
+
+-------------------------------------------------------------------
+Tue Apr 14 08:16:30 UTC 2020 - Fabian Vogt
+
+- Fix name of Packages DB file in rpmconfigcheck
+
+-------------------------------------------------------------------
Fri Apr 3 12:34:42 CEST 2020 - mls@suse.de
- Initialize the libgcrypt library [bnc#1167343]
diff --git a/rpm.spec b/rpm.spec
index eb31d89..ef53e8e 100644
--- a/rpm.spec
+++ b/rpm.spec
@@ -1,7 +1,7 @@
#
# spec file for package rpm
#
-# Copyright (c) 2020 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2020 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -12,7 +12,7 @@
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.
-# Please submit bugfixes or comments via http://bugs.opensuse.org/
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
#
@@ -132,6 +132,8 @@ Patch120: disable_bdb.diff
Patch121: ndb_backport.diff
Patch122: db_conversion.diff
Patch123: initgcrypt.diff
+Patch124: gcryptdsa2.diff
+Patch125: ndb_backport2.diff
Patch6464: auto-config-update-aarch64-ppc64le.diff
BuildRoot: %{_tmppath}/%{name}-%{version}-build
#
@@ -256,7 +258,7 @@ cp config.guess config.sub db/dist/
%patch -P 93 -P 94 -P 99
%patch -P 100 -P 102 -P 103
%patch -P 109 -P 117
-%patch -P 118 -P 119 -P 120 -P 121 -P 122 -P 123
+%patch -P 118 -P 119 -P 120 -P 121 -P 122 -P 123 -P 124 -P 125
%ifarch aarch64 ppc64le riscv64
%patch6464
diff --git a/rpmconfigcheck b/rpmconfigcheck
index 7e668d6..8427395 100644
--- a/rpmconfigcheck
+++ b/rpmconfigcheck
@@ -7,7 +7,7 @@
#
configcheckfile=/var/adm/rpmconfigcheck
-packages=/var/lib/rpm/Packages
+packages=/var/lib/rpm/Packages.db
if test -s $packages -a \( ! -e $configcheckfile -o -s $configcheckfile -o ! $packages -ot $configcheckfile \) ; then
echo "Searching for unresolved configuration files"