Currently, postfix creates (empty, table-less) sqlite database if not exists,
which is kinda unexpected provided postfix can not even load data to it.
Also, the database is always open in read-write mode, despite postfix only
performs queries.

Also, when open actually fails, the error message is unhelpful:

Unfortunately, sqlite does not give good hint about the reason why
the database can't be open, for example:

  fatal: sqlite:/etc/postfix/db.cf: Can't open database: \
        unable to open database file?

Obviously this is an sqlite omission/defect, but we can work around it
in postfix by also providing the strerror(errno) here.

This small patch changes sqlite3_open() into sqlite3_open_v2() which accepts
2 more arguments, notable open flags (similar to open(2)) - where we only
pass SQLITE_OPEN_READONLY, without SQLITE_OPEN_CREATE.  And expands an error
message, so it becomes like this:

  fatal: sqlite:/etc/postfix/db.cf: Can't open database: \
        unable to open database file (No such file or directory)?

Maybe it's also a good idea to provide the name of the file it tried to
open too - not the .cf one but the actual database one.

sqlite3_open_v2() is available since sqlite version 3.5.0 (see
https://www.sqlite.org/34to35.html), and compatibility wrapper is provided
for older releases, exactly like sqlite3_prepare_v2(). 

Signed-off-by: Michael Tokarev <m...@tls.msk.ru>

diff --git a/src/global/dict_sqlite.c b/src/global/dict_sqlite.c
index 7d6608a6..c23a798f 100644
--- a/src/global/dict_sqlite.c
+++ b/src/global/dict_sqlite.c
@@ -52,6 +52,7 @@
 
 #include <sys_defs.h>
 #include <string.h>
+#include <errno.h>
 
 #ifdef HAS_SQLITE
 #include <sqlite3.h>
@@ -59,6 +60,9 @@
 #if !defined(SQLITE_VERSION_NUMBER) || (SQLITE_VERSION_NUMBER < 3005004)
 #define sqlite3_prepare_v2 sqlite3_prepare
 #endif
+#if !defined(SQLITE_VERSION_NUMBER) || (SQLITE_VERSION_NUMBER < 3005000)
+#define sqlite3_open_v2(fname,ppDB,flags,zVfs) sqlite_open(fname,ppDB)
+#endif
 
 /* Utility library. */
 
@@ -320,9 +324,11 @@ DICT   *dict_sqlite_open(const char *name, int open_flags, 
int dict_flags)
     dict_sqlite->parser = parser;
     sqlite_parse_config(dict_sqlite, name);
 
-    if (sqlite3_open(dict_sqlite->dbpath, &dict_sqlite->db))
-       msg_fatal("%s:%s: Can't open database: %s\n",
-                 DICT_TYPE_SQLITE, name, sqlite3_errmsg(dict_sqlite->db));
+    if (sqlite3_open_v2(dict_sqlite->dbpath, &dict_sqlite->db,
+                       SQLITE_OPEN_READONLY, NULL))
+       msg_fatal("%s:%s: Can't open database: %s (%s)\n",
+                 DICT_TYPE_SQLITE, name, sqlite3_errmsg(dict_sqlite->db),
+                 strerror(errno));
 
     dict_sqlite->dict.owner = cfg_get_owner(dict_sqlite->parser);
 
_______________________________________________
Postfix-devel mailing list -- postfix-devel@postfix.org
To unsubscribe send an email to postfix-devel-le...@postfix.org

Reply via email to