Blob Blame History Raw
diff -up ./nss/lib/nss/config.mk.check_policy_file ./nss/lib/nss/config.mk
--- ./nss/lib/nss/config.mk.check_policy_file	2016-03-16 14:44:30.254078910 -0700
+++ ./nss/lib/nss/config.mk	2016-03-16 14:44:30.290079522 -0700
@@ -104,3 +104,7 @@ DEFINES += -DWIN32_NSS3_DLL_COMPAT
 DLLFLAGS += -EXPORT:mktemp=nss_mktemp,PRIVATE
 endif
 endif
+
+ifdef POLICY_FILE
+DEFINES += -DPOLICY_FILE=\"$(POLICY_FILE)\" -DPOLICY_PATH=\"$(POLICY_PATH)\"
+endif
diff -up ./nss/lib/nss/nssinit.c.check_policy_file ./nss/lib/nss/nssinit.c
--- ./nss/lib/nss/nssinit.c.check_policy_file	2016-02-26 12:51:11.000000000 -0800
+++ ./nss/lib/nss/nssinit.c	2016-03-16 15:08:54.455301088 -0700
@@ -335,7 +335,7 @@ nss_FindExternalRoot(const char *dbpath,
  * set statics (from PKCS11_Configure, for instance), and uses it to kick off
  * the loading of the various PKCS #11 modules.
  */
-static SECStatus
+static SECMODModule *
 nss_InitModules(const char *configdir, const char *certPrefix, 
 		const char *keyPrefix, const char *secmodName, 
 		const char *updateDir, const char *updCertPrefix, 
@@ -345,7 +345,7 @@ nss_InitModules(const char *configdir, c
 		PRBool noModDB, PRBool forceOpen, PRBool optimizeSpace,
 		PRBool isContextInit)
 {
-    SECStatus rv = SECFailure;
+    SECMODModule *module = NULL;
     char *moduleSpec = NULL;
     char *flags = NULL;
     char *lconfigdir = NULL;
@@ -360,12 +360,12 @@ nss_InitModules(const char *configdir, c
 
     if (NSS_InitializePRErrorTable() != SECSuccess) {
 	PORT_SetError(SEC_ERROR_NO_MEMORY);
-	return rv;
+	return NULL;
     }
 
     flags = nss_makeFlags(readOnly,noCertDB,noModDB,forceOpen,
 					pwRequired, optimizeSpace);
-    if (flags == NULL) return rv;
+    if (flags == NULL) return NULL;
 
     /*
      * configdir is double nested, and Windows uses the same character
@@ -432,14 +432,16 @@ loser:
     if (lupdateName) PORT_Free(lupdateName);
 
     if (moduleSpec) {
-	SECMODModule *module = SECMOD_LoadModule(moduleSpec,NULL,PR_TRUE);
+	module = SECMOD_LoadModule(moduleSpec,NULL,PR_TRUE);
 	PR_smprintf_free(moduleSpec);
 	if (module) {
-	    if (module->loaded) rv=SECSuccess;
-	    SECMOD_DestroyModule(module);
+	    if (!module->loaded) {
+	        SECMOD_DestroyModule(module);
+		module = NULL;
+	    }
 	}
     }
-    return rv;
+    return module;
 }
 
 /*
@@ -525,7 +527,7 @@ nss_Init(const char *configdir, const ch
 		 PRBool allowAlreadyInitializedModules,
 		 PRBool dontFinalizeModules)
 {
-    SECStatus rv = SECFailure;
+    SECMODModule *parent = NULL;
     PKIX_UInt32 actualMinorVersion = 0;
     PKIX_Error *pkixError = NULL;
     PRBool isReallyInitted;
@@ -635,13 +637,13 @@ nss_Init(const char *configdir, const ch
     /* Skip the module init if we are already initted and we are trying
      * to init with noCertDB and noModDB */
     if (!(isReallyInitted && noCertDB && noModDB)) {
-	rv = nss_InitModules(configdir, certPrefix, keyPrefix, secmodName, 
+	parent = nss_InitModules(configdir, certPrefix, keyPrefix, secmodName, 
 		updateDir, updCertPrefix, updKeyPrefix, updateID, 
 		updateName, configName, configStrings, passwordRequired,
 		readOnly, noCertDB, noModDB, forceOpen, optimizeSpace, 
 		(initContextPtr != NULL));
 
-	if (rv != SECSuccess) {
+	if (parent == NULL) {
 	    goto loser;
 	}
     }
@@ -680,7 +682,24 @@ nss_Init(const char *configdir, const ch
 		}
 	    }
 	}
-
+#ifdef POLICY_FILE
+        if (PR_Access(POLICY_PATH "/" POLICY_FILE, PR_ACCESS_READ_OK) == PR_SUCCESS ) {
+	    SECMODModule *module = SECMOD_LoadModule(
+		"name=\"Policy File\" "
+		"parameters=\"configdir='sql:" POLICY_PATH "' "
+		"secmod='" POLICY_FILE "' "
+		"flags=readOnly,noCertDB,forceSecmodChoice,forceOpen\" "
+		"NSS=\"flags=internal,moduleDB,skipFirst,moduleDBOnly,critical\"",
+		parent, PR_TRUE); 
+	    if (module) {
+		PRBool isLoaded = module->loaded;
+		SECMOD_DestroyModule(module);
+		if (!isLoaded) {
+		    goto loser;
+		}
+	    }
+	}
+#endif
 	pk11sdr_Init();
 	cert_CreateSubjectKeyIDHashTable();
 
@@ -721,6 +740,9 @@ nss_Init(const char *configdir, const ch
     if (initContextPtr && configStrings) {
 	PR_smprintf_free(configStrings);
     }
+    if (parent) {
+	SECMOD_DestroyModule(parent);
+    }
 
     return SECSuccess;
 
@@ -737,6 +759,9 @@ loser:
     /* We failed to init, allow one to move forward */
     PZ_NotifyCondVar(nssInitCondition);
     PZ_Unlock(nssInitLock);
+    if (parent) {
+	SECMOD_DestroyModule(parent);
+    }
     return SECFailure;
 }
 
diff -up ./nss/lib/pk11wrap/pk11pars.c.check_policy_file ./nss/lib/pk11wrap/pk11pars.c
--- ./nss/lib/pk11wrap/pk11pars.c.check_policy_file	2016-02-26 12:51:11.000000000 -0800
+++ ./nss/lib/pk11wrap/pk11pars.c	2016-03-16 14:44:30.291079539 -0700
@@ -110,6 +110,7 @@ secmod_NewModule(void)
 						  *other flags are set */
 #define SECMOD_FLAG_MODULE_DB_SKIP_FIRST    0x02
 #define SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB 0x04
+#define SECMOD_FLAG_MODULE_DB_POLICY_ONLY   0x08
 
 
 /* private flags for internal (field in SECMODModule). */
@@ -704,6 +705,9 @@ SECMOD_CreateModuleEx(const char *librar
 	if (NSSUTIL_ArgHasFlag("flags","defaultModDB",nssc)) {
 	    flags |= SECMOD_FLAG_MODULE_DB_DEFAULT_MODDB;
 	}
+	if (NSSUTIL_ArgHasFlag("flags","policyOnly",nssc)) {
+	    flags |= SECMOD_FLAG_MODULE_DB_POLICY_ONLY;
+	}
 	/* additional moduleDB flags could be added here in the future */
 	mod->isModuleDB = (PRBool) flags;
     }
@@ -743,6 +747,14 @@ SECMOD_GetDefaultModDBFlag(SECMODModule
 }
 
 PRBool
+secmod_PolicyOnly(SECMODModule *mod)
+{
+   char flags = (char) mod->isModuleDB;
+
+   return (flags & SECMOD_FLAG_MODULE_DB_POLICY_ONLY) ? PR_TRUE : PR_FALSE;
+}
+
+PRBool
 secmod_IsInternalKeySlot(SECMODModule *mod)
 {
    char flags = (char) mod->internal;
@@ -1526,6 +1538,12 @@ SECMOD_LoadModule(char *modulespec,SECMO
     if (!module) {
 	goto loser;
     }
+
+    /* a policy only stanza doesn't actually get 'loaded'. policy has already
+     * been parsed as a side effect of the CreateModuleEx call */
+    if (secmod_PolicyOnly(module)) {
+	return module;
+    }
     if (parent) {
     	module->parent = SECMOD_ReferenceModule(parent);
 	if (module->internal && secmod_IsInternalKeySlot(parent)) {