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