security/nss/lib/util/utilmod.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     4 /* 
     5  * The following code handles the storage of PKCS 11 modules used by the
     6  * NSS. For the rest of NSS, only one kind of database handle exists:
     7  *
     8  *     SFTKDBHandle
     9  *
    10  * There is one SFTKDBHandle for each key database and one for each cert 
    11  * database. These databases are opened as associated pairs, one pair per
    12  * slot. SFTKDBHandles are reference counted objects.
    13  *
    14  * Each SFTKDBHandle points to a low level database handle (SDB). This handle
    15  * represents the underlying physical database. These objects are not 
    16  * reference counted, and are 'owned' by their respective SFTKDBHandles.
    17  */
    19 #include "prprf.h" 
    20 #include "prsystem.h"
    21 #include "secport.h"
    22 #include "utilpars.h" 
    23 #include "secerr.h"
    25 #if defined (_WIN32)
    26 #include <io.h>
    27 #endif
    28 #ifdef XP_UNIX
    29 #include <unistd.h>
    30 #endif
    32 #include <sys/types.h>
    33 #include <sys/stat.h>
    34 #include <fcntl.h>
    36 #if defined (_WIN32)
    37 #define os_open _open
    38 #define os_fdopen _fdopen
    39 #define os_stat _stat
    40 #define os_truncate_open_flags _O_CREAT|_O_RDWR|_O_TRUNC
    41 #define os_append_open_flags _O_CREAT|_O_RDWR|_O_APPEND
    42 #define os_open_permissions_type int
    43 #define os_open_permissions_default _S_IREAD | _S_IWRITE
    44 #define os_stat_type struct _stat
    45 #else
    46 #define os_open open
    47 #define os_fdopen fdopen
    48 #define os_stat stat
    49 #define os_truncate_open_flags O_CREAT|O_RDWR|O_TRUNC
    50 #define os_append_open_flags O_CREAT|O_RDWR|O_APPEND
    51 #define os_open_permissions_type mode_t
    52 #define os_open_permissions_default 0600
    53 #define os_stat_type struct stat
    54 #endif
    56 /****************************************************************
    57  *
    58  * Secmod database.
    59  *
    60  * The new secmod database is simply a text file with each of the module
    61  * entries in the following form:
    62  *
    63  * #
    64  * # This is a comment The next line is the library to load
    65  * library=libmypkcs11.so
    66  * name="My PKCS#11 module"
    67  * params="my library's param string"
    68  * nss="NSS parameters"
    69  * other="parameters for other libraries and applications"
    70  * 
    71  * library=libmynextpk11.so
    72  * name="My other PKCS#11 module"
    73  */
    76 /*
    77  * Smart string cat functions. Automatically manage the memory.
    78  * The first parameter is the source string. If it's null, we 
    79  * allocate memory for it. If it's not, we reallocate memory
    80  * so the the concanenated string fits.
    81  */
    82 static char *
    83 nssutil_DupnCat(char *baseString, const char *str, int str_len)
    84 {
    85     int len = (baseString ? PORT_Strlen(baseString) : 0) + 1;
    86     char *newString;
    88     len += str_len;
    89     newString = (char *) PORT_Realloc(baseString,len);
    90     if (newString == NULL) {
    91 	PORT_Free(baseString);
    92 	return NULL;
    93     }
    94     if (baseString == NULL) *newString = 0;
    95     return PORT_Strncat(newString,str, str_len);
    96 }
    98 /* Same as nssutil_DupnCat except it concatenates the full string, not a
    99  * partial one */
   100 static char *
   101 nssutil_DupCat(char *baseString, const char *str)
   102 {
   103     return nssutil_DupnCat(baseString, str, PORT_Strlen(str));
   104 }
   106 /* function to free up all the memory associated with a null terminated
   107  * array of module specs */
   108 static SECStatus
   109 nssutil_releaseSpecList(char **moduleSpecList)
   110 {
   111     if (moduleSpecList) {
   112 	char **index;
   113 	for(index = moduleSpecList; *index; index++) {
   114 	    PORT_Free(*index);
   115 	}
   116 	PORT_Free(moduleSpecList);
   117     }
   118     return SECSuccess;
   119 }
   121 #define SECMOD_STEP 10
   122 static SECStatus
   123 nssutil_growList(char ***pModuleList, int *useCount, int last)
   124 {
   125     char **newModuleList;
   127     *useCount += SECMOD_STEP;
   128     newModuleList = (char **)PORT_Realloc(*pModuleList,
   129 					  *useCount*sizeof(char *));
   130     if (newModuleList == NULL) {
   131 	return SECFailure;
   132     }
   133     PORT_Memset(&newModuleList[last],0, sizeof(char *)*SECMOD_STEP);
   134     *pModuleList = newModuleList;
   135     return SECSuccess;
   136 }
   138 static 
   139 char *_NSSUTIL_GetOldSecmodName(const char *dbname,const char *filename)
   140 {
   141     char *file = NULL;
   142     char *dirPath = PORT_Strdup(dbname);
   143     char *sep;
   145     sep = PORT_Strrchr(dirPath,*NSSUTIL_PATH_SEPARATOR);
   146 #ifdef _WIN32
   147     if (!sep) {
   148 	/* utilparst.h defines NSSUTIL_PATH_SEPARATOR as "/" for all
   149 	 * platforms. */
   150 	sep = PORT_Strrchr(dirPath,'\\');
   151     }
   152 #endif
   153     if (sep) {
   154 	*sep = 0;
   155 	file = PR_smprintf("%s"NSSUTIL_PATH_SEPARATOR"%s", dirPath, filename);
   156     } else {
   157 	file = PR_smprintf("%s", filename);
   158     }
   159     PORT_Free(dirPath);
   160     return file;
   161 }
   163 static SECStatus nssutil_AddSecmodDBEntry(const char *appName,
   164                                           const char *filename,
   165                                           const char *dbname,
   166                                           char *module, PRBool rw);
   168 enum lfopen_mode { lfopen_truncate, lfopen_append };
   170 FILE *
   171 lfopen(const char *name, enum lfopen_mode om, os_open_permissions_type open_perms)
   172 {
   173     int fd;
   174     FILE *file;
   176     fd = os_open(name,
   177                  (om == lfopen_truncate) ? os_truncate_open_flags : os_append_open_flags,
   178                  open_perms);
   179     if (fd < 0) {
   180 	return NULL;
   181     }
   182     file = os_fdopen(fd, (om == lfopen_truncate) ? "w+" : "a+");
   183     if (!file) {
   184 	close(fd);
   185     }
   186     /* file inherits fd */
   187     return file;
   188 }
   190 #define MAX_LINE_LENGTH 2048
   192 /*
   193  * Read all the existing modules in out of the file.
   194  */
   195 static char **
   196 nssutil_ReadSecmodDB(const char *appName, 
   197 		    const char *filename, const char *dbname, 
   198 		    char *params, PRBool rw)
   199 {
   200     FILE *fd = NULL;
   201     char **moduleList = NULL;
   202     int moduleCount = 1;
   203     int useCount = SECMOD_STEP;
   204     char line[MAX_LINE_LENGTH];
   205     PRBool internal = PR_FALSE;
   206     PRBool skipParams = PR_FALSE;
   207     char *moduleString = NULL;
   208     char *paramsValue=NULL;
   209     PRBool failed = PR_TRUE;
   211     moduleList = (char **) PORT_ZAlloc(useCount*sizeof(char **));
   212     if (moduleList == NULL) return NULL;
   214     if (dbname == NULL) {
   215 	goto return_default;
   216     }
   218     /* do we really want to use streams here */
   219     fd = fopen(dbname, "r");
   220     if (fd == NULL) goto done;
   222     /*
   223      * the following loop takes line separated config lines and collapses
   224      * the lines to a single string, escaping and quoting as necessary.
   225      */
   226     /* loop state variables */
   227     moduleString = NULL;  /* current concatenated string */
   228     internal = PR_FALSE;	     /* is this an internal module */
   229     skipParams = PR_FALSE;	   /* did we find an override parameter block*/
   230     paramsValue = NULL;		   /* the current parameter block value */
   231     while (fgets(line, sizeof(line), fd) != NULL) { 
   232 	int len = PORT_Strlen(line);
   234 	/* remove the ending newline */
   235 	if (len && line[len-1] == '\n') {
   236 	    len--;
   237 	    line[len] = 0;
   238 	}
   239 	if (*line == '#') {
   240 	    continue;
   241 	}
   242 	if (*line != 0) {
   243 	    /*
   244 	     * The PKCS #11 group standard assumes blocks of strings
   245 	     * separated by new lines, clumped by new lines. Internally
   246 	     * we take strings separated by spaces, so we may need to escape
   247 	     * certain spaces.
   248 	     */
   249 	    char *value = PORT_Strchr(line,'=');
   251 	    /* there is no value, write out the stanza as is */
   252 	    if (value == NULL || value[1] == 0) {
   253 		if (moduleString) {
   254 		    moduleString = nssutil_DupnCat(moduleString," ", 1);
   255 		    if (moduleString == NULL) goto loser;
   256 		}
   257 	        moduleString = nssutil_DupCat(moduleString, line);
   258 		if (moduleString == NULL) goto loser;
   259 	    /* value is already quoted, just write it out */
   260 	    } else if (value[1] == '"') {
   261 		if (moduleString) {
   262 		    moduleString = nssutil_DupnCat(moduleString," ", 1);
   263 		    if (moduleString == NULL) goto loser;
   264 		}
   265 	        moduleString = nssutil_DupCat(moduleString, line);
   266 		if (moduleString == NULL) goto loser;
   267 		/* we have an override parameter section, remember that
   268 		 * we found this (see following comment about why this
   269 		 * is necessary). */
   270 	        if (PORT_Strncasecmp(line, "parameters", 10) == 0) {
   271 			skipParams = PR_TRUE;
   272 		}
   273 	    /*
   274 	     * The internal token always overrides it's parameter block
   275 	     * from the passed in parameters, so wait until then end
   276 	     * before we include the parameter block in case we need to 
   277 	     * override it. NOTE: if the parameter block is quoted with ("),
   278 	     * this override does not happen. This allows you to override
   279 	     * the application's parameter configuration.
   280 	     *
   281 	     * parameter block state is controlled by the following variables:
   282 	     *  skipParams - Bool : set to true of we have an override param
   283 	     *    block (all other blocks, either implicit or explicit are
   284 	     *    ignored).
   285 	     *  paramsValue - char * : pointer to the current param block. In
   286 	     *    the absence of overrides, paramsValue is set to the first
   287 	     *    parameter block we find. All subsequent blocks are ignored.
   288 	     *    When we find an internal token, the application passed
   289 	     *    parameters take precident.
   290 	     */
   291 	    } else if (PORT_Strncasecmp(line, "parameters", 10) == 0) {
   292 		/* already have parameters */
   293 		if (paramsValue) {
   294 			continue;
   295 		}
   296 		paramsValue = NSSUTIL_Quote(&value[1], '"');
   297 		if (paramsValue == NULL) goto loser;
   298 		continue;
   299 	    } else {
   300 	    /* may need to quote */
   301 	        char *newLine;
   302 		if (moduleString) {
   303 		    moduleString = nssutil_DupnCat(moduleString," ", 1);
   304 		    if (moduleString == NULL) goto loser;
   305 		}
   306 		moduleString = nssutil_DupnCat(moduleString,line,value-line+1);
   307 		if (moduleString == NULL)  goto loser;
   308 	        newLine = NSSUTIL_Quote(&value[1],'"');
   309 		if (newLine == NULL) goto loser;
   310 		moduleString = nssutil_DupCat(moduleString,newLine);
   311 	        PORT_Free(newLine);
   312 		if (moduleString == NULL) goto loser;
   313 	    }
   315 	    /* check to see if it's internal? */
   316 	    if (PORT_Strncasecmp(line, "NSS=", 4) == 0) {
   317 		/* This should be case insensitive! reviewers make
   318 		 * me fix it if it's not */
   319 		if (PORT_Strstr(line,"internal")) {
   320 		    internal = PR_TRUE;
   321 		    /* override the parameters */
   322 		    if (paramsValue) {
   323 			PORT_Free(paramsValue);
   324 		    }
   325 		    paramsValue = NSSUTIL_Quote(params, '"');
   326 		}
   327 	    }
   328 	    continue;
   329 	}
   330 	if ((moduleString == NULL) || (*moduleString == 0)) {
   331 	    continue;
   332 	}
   334 	/* 
   335 	 * if we are here, we have found a complete stanza. Now write out
   336 	 * any param section we may have found.
   337 	 */
   338 	if (paramsValue) {
   339 	    /* we had an override */
   340 	    if (!skipParams) {
   341 		moduleString = nssutil_DupnCat(moduleString," parameters=", 12);
   342 		if (moduleString == NULL) goto loser;
   343 		moduleString = nssutil_DupCat(moduleString, paramsValue);
   344 		if (moduleString == NULL) goto loser;
   345 	    }
   346 	    PORT_Free(paramsValue);
   347 	    paramsValue = NULL;
   348 	}
   350 	if ((moduleCount+1) >= useCount) {
   351 	    SECStatus rv;
   352 	    rv = nssutil_growList(&moduleList, &useCount,  moduleCount+1);
   353 	    if (rv != SECSuccess) {
   354 		goto loser;
   355 	    }
   356 	}
   358 	if (internal) {
   359 	    moduleList[0] = moduleString;
   360 	} else {
   361 	    moduleList[moduleCount] = moduleString;
   362 	    moduleCount++;
   363 	}
   364 	moduleString = NULL;
   365 	internal = PR_FALSE;
   366 	skipParams = PR_FALSE;
   367     } 
   369     if (moduleString) {
   370 	PORT_Free(moduleString);
   371 	moduleString = NULL;
   372     }
   373 done:
   374     /* if we couldn't open a pkcs11 database, look for the old one */
   375     if (fd == NULL) {
   376 	char *olddbname = _NSSUTIL_GetOldSecmodName(dbname,filename);
   377 	PRStatus status;
   379 	/* couldn't get the old name */
   380 	if (!olddbname) {
   381 	    goto bail;
   382 	}
   384 	/* old one exists */
   385 	status = PR_Access(olddbname, PR_ACCESS_EXISTS);
   386 	if (status == PR_SUCCESS) {
   387 	    PR_smprintf_free(olddbname);
   388 	    PORT_ZFree(moduleList, useCount*sizeof(char **));
   389 	    PORT_SetError(SEC_ERROR_LEGACY_DATABASE);
   390 	    return NULL;
   391 	}
   393 bail:
   394 	if (olddbname) {
   395 	    PR_smprintf_free(olddbname);
   396 	}
   397     }
   399 return_default:
   401     if (!moduleList[0]) {
   402 	char * newParams;
   403 	moduleString = PORT_Strdup(NSSUTIL_DEFAULT_INTERNAL_INIT1);
   404 	newParams = NSSUTIL_Quote(params,'"');
   405 	if (newParams == NULL) goto loser;
   406 	moduleString = nssutil_DupCat(moduleString, newParams);
   407 	PORT_Free(newParams);
   408 	if (moduleString == NULL) goto loser;
   409 	moduleString = nssutil_DupCat(moduleString, 
   410 					NSSUTIL_DEFAULT_INTERNAL_INIT2);
   411 	if (moduleString == NULL) goto loser;
   412 	moduleString = nssutil_DupCat(moduleString,
   413 					NSSUTIL_DEFAULT_SFTKN_FLAGS);
   414 	if (moduleString == NULL) goto loser;
   415 	moduleString = nssutil_DupCat(moduleString, 
   416 					NSSUTIL_DEFAULT_INTERNAL_INIT3);
   417 	if (moduleString == NULL) goto loser;
   418 	moduleList[0] = moduleString;
   419 	moduleString = NULL;
   420     }
   421     failed = PR_FALSE;
   423 loser:
   424     /*
   425      * cleanup
   426      */
   427     /* deal with trust cert db here */
   428     if (moduleString) {
   429 	PORT_Free(moduleString);
   430 	moduleString = NULL;
   431     }
   432     if (paramsValue) {
   433 	PORT_Free(paramsValue);
   434 	paramsValue = NULL;
   435     }
   436     if (failed || (moduleList[0] == NULL)) {
   437 	/* This is wrong! FIXME */
   438 	nssutil_releaseSpecList(moduleList);
   439 	moduleList = NULL;
   440 	failed = PR_TRUE;
   441     }
   442     if (fd != NULL) {
   443 	fclose(fd);
   444     } else if (!failed && rw) {
   445 	/* update our internal module */
   446 	nssutil_AddSecmodDBEntry(appName, filename, dbname, moduleList[0], rw);
   447     }
   448     return moduleList;
   449 }
   451 static SECStatus
   452 nssutil_ReleaseSecmodDBData(const char *appName, 
   453 			const char *filename, const char *dbname, 
   454 			char **moduleSpecList, PRBool rw)
   455 {
   456     if (moduleSpecList) {
   457 	nssutil_releaseSpecList(moduleSpecList);
   458     }
   459     return SECSuccess;
   460 }
   463 /*
   464  * Delete a module from the Data Base
   465  */
   466 static SECStatus
   467 nssutil_DeleteSecmodDBEntry(const char *appName,
   468                             const char *filename,
   469                             const char *dbname,
   470                             char *args,
   471                             PRBool rw)
   472 {
   473     /* SHDB_FIXME implement */
   474     os_stat_type stat_existing;
   475     os_open_permissions_type file_mode;
   476     FILE *fd = NULL;
   477     FILE *fd2 = NULL;
   478     char line[MAX_LINE_LENGTH];
   479     char *dbname2 = NULL;
   480     char *block = NULL;
   481     char *name = NULL;
   482     char *lib = NULL;
   483     int name_len, lib_len;
   484     PRBool skip = PR_FALSE;
   485     PRBool found = PR_FALSE;
   487     if (dbname == NULL) {
   488 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
   489 	return SECFailure;
   490     }
   492     if (!rw) {
   493 	PORT_SetError(SEC_ERROR_READ_ONLY);
   494 	return SECFailure;
   495     }
   497     dbname2 = PORT_Strdup(dbname);
   498     if (dbname2 == NULL) goto loser;
   499     dbname2[strlen(dbname)-1]++;
   501     /* get the permissions of the existing file, or use the default */
   502     if (!os_stat(dbname, &stat_existing)) {
   503 	file_mode = stat_existing.st_mode;
   504     } else {
   505 	file_mode = os_open_permissions_default;
   506     }
   508     /* do we really want to use streams here */
   509     fd = fopen(dbname, "r");
   510     if (fd == NULL) goto loser;
   512     fd2 = lfopen(dbname2, lfopen_truncate, file_mode);
   514     if (fd2 == NULL) goto loser;
   516     name = NSSUTIL_ArgGetParamValue("name",args);
   517     if (name) {
   518 	name_len = PORT_Strlen(name);
   519     }
   520     lib = NSSUTIL_ArgGetParamValue("library",args);
   521     if (lib) {
   522 	lib_len = PORT_Strlen(lib);
   523     }
   526     /*
   527      * the following loop takes line separated config files and collapses
   528      * the lines to a single string, escaping and quoting as necessary.
   529      */
   530     /* loop state variables */
   531     block = NULL;
   532     skip = PR_FALSE;
   533     while (fgets(line, sizeof(line), fd) != NULL) { 
   534 	/* If we are processing a block (we haven't hit a blank line yet */
   535 	if (*line != '\n') {
   536 	    /* skip means we are in the middle of a block we are deleting */
   537 	    if (skip) {
   538 		continue;
   539 	    }
   540 	    /* if we haven't found the block yet, check to see if this block
   541 	     * matches our requirements */
   542 	    if (!found && ((name && (PORT_Strncasecmp(line,"name=",5) == 0) &&
   543 		 (PORT_Strncmp(line+5,name,name_len) == 0))  ||
   544 	        (lib && (PORT_Strncasecmp(line,"library=",8) == 0) &&
   545 		 (PORT_Strncmp(line+8,lib,lib_len) == 0)))) {
   547 		/* yup, we don't need to save any more data, */
   548 		PORT_Free(block);
   549 		block=NULL;
   550 		/* we don't need to collect more of this block */
   551 		skip = PR_TRUE;
   552 		/* we don't need to continue searching for the block */
   553 		found =PR_TRUE;
   554 		continue;
   555 	    }
   556 	    /* not our match, continue to collect data in this block */
   557 	    block = nssutil_DupCat(block,line);
   558 	    continue;
   559 	}
   560 	/* we've collected a block of data that wasn't the module we were
   561 	 * looking for, write it out */
   562 	if (block) {
   563 	    fwrite(block, PORT_Strlen(block), 1, fd2);
   564 	    PORT_Free(block);
   565 	    block = NULL;
   566 	}
   567 	/* If we didn't just delete the this block, keep the blank line */
   568 	if (!skip) {
   569 	    fputs(line,fd2);
   570 	}
   571 	/* we are definately not in a deleted block anymore */
   572 	skip = PR_FALSE;
   573     } 
   574     fclose(fd);
   575     fclose(fd2);
   576     if (found) {
   577 	/* rename dbname2 to dbname */
   578 	PR_Delete(dbname);
   579 	PR_Rename(dbname2,dbname);
   580     } else {
   581 	PR_Delete(dbname2);
   582     }
   583     PORT_Free(dbname2);
   584     PORT_Free(lib);
   585     PORT_Free(name);
   586     PORT_Free(block);
   587     return SECSuccess;
   589 loser:
   590     if (fd != NULL) {
   591 	fclose(fd);
   592     }
   593     if (fd2 != NULL) {
   594 	fclose(fd2);
   595     }
   596     if (dbname2) {
   597 	PR_Delete(dbname2);
   598 	PORT_Free(dbname2);
   599     }
   600     PORT_Free(lib);
   601     PORT_Free(name);
   602     return SECFailure;
   603 }
   605 /*
   606  * Add a module to the Data base 
   607  */
   608 static SECStatus
   609 nssutil_AddSecmodDBEntry(const char *appName,
   610                         const char *filename, const char *dbname,
   611                          char *module, PRBool rw)
   612 {
   613     os_stat_type stat_existing;
   614     os_open_permissions_type file_mode;
   615     FILE *fd = NULL;
   616     char *block = NULL;
   617     PRBool libFound = PR_FALSE;
   619     if (dbname == NULL) {
   620 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
   621 	return SECFailure;
   622     }
   624     /* can't write to a read only module */
   625     if (!rw) {
   626 	PORT_SetError(SEC_ERROR_READ_ONLY);
   627 	return SECFailure;
   628     }
   630     /* remove the previous version if it exists */
   631     (void) nssutil_DeleteSecmodDBEntry(appName, filename, dbname, module, rw);
   633     /* get the permissions of the existing file, or use the default */
   634     if (!os_stat(dbname, &stat_existing)) {
   635 	file_mode = stat_existing.st_mode;
   636     } else {
   637 	file_mode = os_open_permissions_default;
   638     }
   640     fd = lfopen(dbname, lfopen_append, file_mode);
   641     if (fd == NULL) {
   642 	return SECFailure;
   643     }
   644     module = NSSUTIL_ArgStrip(module);
   645     while (*module) {
   646 	int count;
   647 	char *keyEnd = PORT_Strchr(module,'=');
   648 	char *value;
   650 	if (PORT_Strncmp(module, "library=", 8) == 0) {
   651 	   libFound=PR_TRUE;
   652 	}
   653 	if (keyEnd == NULL) {
   654 	    block = nssutil_DupCat(block, module);
   655 	    break;
   656 	}
   657 	block = nssutil_DupnCat(block, module, keyEnd-module+1);
   658 	if (block == NULL) { goto loser; }
   659 	value = NSSUTIL_ArgFetchValue(&keyEnd[1], &count);
   660 	if (value) {
   661 	    block = nssutil_DupCat(block, NSSUTIL_ArgStrip(value));
   662 	    PORT_Free(value);
   663 	}
   664 	if (block == NULL) { goto loser; }
   665 	block = nssutil_DupnCat(block, "\n", 1);
   666 	module = keyEnd + 1 + count;
   667 	module = NSSUTIL_ArgStrip(module);
   668     }
   669     if (block) {
   670 	if (!libFound) {
   671 	    fprintf(fd,"library=\n");
   672 	}
   673 	fwrite(block, PORT_Strlen(block), 1, fd);
   674 	fprintf(fd,"\n");
   675 	PORT_Free(block);
   676 	block = NULL;
   677     }
   678     fclose(fd);
   679     return SECSuccess;
   681 loser:
   682     PORT_Free(block);
   683     fclose(fd);
   684     return SECFailure;
   685 }
   688 char **
   689 NSSUTIL_DoModuleDBFunction(unsigned long function,char *parameters, void *args)
   690 {
   691     char *secmod = NULL;
   692     char *appName = NULL;
   693     char *filename = NULL;
   694     NSSDBType dbType = NSS_DB_TYPE_NONE;
   695     PRBool rw;
   696     static char *success="Success";
   697     char **rvstr = NULL;
   700     secmod = _NSSUTIL_GetSecmodName(parameters, &dbType, &appName,
   701 				    &filename, &rw);
   702     if ((dbType == NSS_DB_TYPE_LEGACY) || 
   703 	 (dbType == NSS_DB_TYPE_MULTIACCESS)) {
   704 	/* we can't handle the old database, only softoken can */
   705 	PORT_SetError(SEC_ERROR_LEGACY_DATABASE);
   706 	rvstr =  NULL;
   707 	goto done;
   708     }
   710     switch (function) {
   711     case SECMOD_MODULE_DB_FUNCTION_FIND:
   712         rvstr = nssutil_ReadSecmodDB(appName,filename,
   713 				     secmod,(char *)parameters,rw);
   714         break;
   715     case SECMOD_MODULE_DB_FUNCTION_ADD:
   716         rvstr = (nssutil_AddSecmodDBEntry(appName, filename,
   717                                           secmod, (char *)args, rw)
   718                  == SECSuccess) ? &success: NULL;
   719         break;
   720     case SECMOD_MODULE_DB_FUNCTION_DEL:
   721         rvstr = (nssutil_DeleteSecmodDBEntry(appName, filename,
   722                                              secmod, (char *)args, rw)
   723                  == SECSuccess) ? &success: NULL;
   724         break;
   725     case SECMOD_MODULE_DB_FUNCTION_RELEASE:
   726         rvstr = (nssutil_ReleaseSecmodDBData(appName, filename,
   727                                              secmod, (char **)args, rw)
   728                  == SECSuccess) ? &success: NULL;
   729         break;
   730     }
   731 done:
   732     if (secmod) PR_smprintf_free(secmod);
   733     if (appName) PORT_Free(appName);
   734     if (filename) PORT_Free(filename);
   735     return rvstr;
   736 }

mercurial