diff -up nss-3.12.5/mozilla/security/nss/lib/sysinit/nsssysinit.c.547860 nss-3.12.5/mozilla/security/nss/lib/sysinit/nsssysinit.c --- nss-3.12.5/mozilla/security/nss/lib/sysinit/nsssysinit.c.547860 2010-01-06 17:57:30.722388282 -0800 +++ nss-3.12.5/mozilla/security/nss/lib/sysinit/nsssysinit.c 2010-01-06 18:20:59.713397530 -0800 @@ -50,6 +50,7 @@ */ #ifdef XP_UNIX +#include #include #include @@ -108,12 +109,26 @@ getSystemDB(void) { return PORT_Strdup(NSS_DEFAULT_SYSTEM); } +static PRBool +userIsRoot() +{ + /* this works for linux and all unixes that we know off + though it isn't stated as such in POSIX documentation */ + return getuid() == 0; +} + +static PRBool +userCanModifySystemDB() +{ + return (access(NSS_DEFAULT_SYSTEM, W_OK) == 0); +} + #else #ifdef XP_WIN static char * getUserDB(void) { - /* use the registry to find the user's NSS_DIR. if no entry exists, creaate + /* use the registry to find the user's NSS_DIR. if no entry exists, create * one in the users Appdir location */ return NULL; } @@ -121,13 +136,28 @@ getUserDB(void) static char * getSystemDB(void) { - /* use the registry to find the system's NSS_DIR. if no entry exists, creaate + /* use the registry to find the system's NSS_DIR. if no entry exists, create * one based on the windows system data area */ return NULL; } +static PRBool +userIsRoot() +{ + /* use the registry to find if the user is the system administrator. */ + return PR_FALSE; +} + +static PRBool +userCanModifySystemDB() +{ + /* use the registry to find if the user has administrative privilege + * to modify the system's nss database. */ + return PR_FALSE; +} + #else -#error "Need to write getUserDB and get SystemDB functions" +#error "Need to write getUserDB, SystemDB, userIsRoot, and userCanModifySystemDB functions" #endif #endif @@ -225,7 +255,8 @@ get_list(char *filename, char *stripped_ if (userdb && !strcmp(filename, userdb)) filename = NULL; - if (userdb != NULL) { + /* Don't open root's user DB */ + if (userdb != NULL && !userIsRoot()) { /* return a list of databases to open. First the user Database */ module_list[next++] = PR_smprintf( "library= " @@ -245,7 +276,8 @@ get_list(char *filename, char *stripped_ userdb, stripped_parameters); } - if (filename && 0 /* This doesn't actually work. If we register + if (filename && !userIsRoot() && 0 + /* This doesn't actually work. If we register both this and the sysdb (in either order) then only one of them actually shows up */) { module_list[next++] = PR_smprintf( @@ -255,13 +287,14 @@ get_list(char *filename, char *stripped_ "NSS=\"%sflags=internal\"",filename, filename, nssflags); } - /* now the system database (always read only) */ + /* now the system database (always read only unless it's root) */ if (sysdb) { - module_list[next++] = PR_smprintf( + const char *readonly = userCanModifySystemDB() ? "" : "flags=readonly"; + module_list[next++] = PR_smprintf( "library= " "module=\"NSS system database\" " - "parameters=\"configdir='sql:%s' tokenDescription='NSS system database' flags=readonly\" " - "NSS=\"%sflags=internal,critical\"",sysdb, nssflags); + "parameters=\"configdir='sql:%s' tokenDescription='NSS system database' %s\" " + "NSS=\"%sflags=internal,critical\"",sysdb, readonly, nssflags); } /* that was the last module */