From 7c08aa9b0aa10f4d13e7317c9a7353399188dba4 Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Wed, 21 Sep 2016 13:45:25 -0400 Subject: [PATCH] Enhance checking on NSS database permissions to include directory Previously I was checking the NSS database files for readability but not the database directory itself. Since it starts as root if the directory permissions didn't allow read by the Apache user but the files themselves did then startup would continue but blow up due to the inability to chdir into the directory. BZ #1312583 --- nss_engine_init.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/nss_engine_init.c b/nss_engine_init.c index cd71989..03ac644 100644 --- a/nss_engine_init.c +++ b/nss_engine_init.c @@ -51,8 +51,7 @@ static char *version_components[] = { NULL }; -/* See if a uid or gid can read a file at a given path. Ignore world - * read permissions. +/* See if a uid or gid can read a file at a given path. * * Return 0 on failure or file doesn't exist * Return 1 on success @@ -65,14 +64,14 @@ static int check_path(uid_t uid, gid_t gid, char *filepath, apr_pool_t *p) if ((rv = apr_stat(&finfo, filepath, APR_FINFO_PROT | APR_FINFO_OWNER, p)) == APR_SUCCESS) { if (((uid == finfo.user) && - ((finfo.protection & APR_FPROT_UREAD))) || + (finfo.protection & APR_FPROT_UREAD)) || ((gid == finfo.group) && - ((finfo.protection & APR_FPROT_GREAD))) + (finfo.protection & APR_FPROT_GREAD)) || + (finfo.protection & APR_FPROT_WREAD) ) { return 1; } - return 0; } return 0; } @@ -158,6 +157,11 @@ static void nss_init_SSLLibrary(server_rec *base_server, apr_pool_t *p) } } + if (strncasecmp(mc->pCertificateDatabase, "sql:", 4) == 0) + dbdir = (char *)mc->pCertificateDatabase + 4; + else + dbdir = (char *)mc->pCertificateDatabase; + /* Assuming everything is ok so far, check the cert database permissions * for the server user before Apache starts forking. We die now or * get stuck in an endless loop not able to read the NSS database. @@ -172,6 +176,13 @@ static void nss_init_SSLLibrary(server_rec *base_server, apr_pool_t *p) "Checking permissions for user %s: uid %d gid %d", mc->user, pw->pw_uid, pw->pw_gid); + if (!(check_path(pw->pw_uid, pw->pw_gid, dbdir, p))) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, base_server, + "Server user %s lacks read access to NSS " + "database directory %s.", mc->user, dbdir); + nss_die(); + } + if (strncasecmp(mc->pCertificateDatabase, "sql:", 4) == 0) { apr_snprintf(filepath, 1024, "%s/key4.db", mc->pCertificateDatabase+4); @@ -231,10 +242,6 @@ static void nss_init_SSLLibrary(server_rec *base_server, apr_pool_t *p) else return; } - if (strncasecmp(mc->pCertificateDatabase, "sql:", 4) == 0) - dbdir = (char *)mc->pCertificateDatabase + 4; - else - dbdir = (char *)mc->pCertificateDatabase; if (chdir(dbdir) != 0) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, base_server, "Unable to change directory to %s", mc->pCertificateDatabase); -- 2.5.5