> Anton Bobrov wrote: >> Mike, i just asked our NSS folks here and this is what i got, quote:
Hi, I'm one of the NSS folks that was asked. >> "You can only have one writer process with no readers, or multiple >> readers with no writer ." That is a limitation of the old Berkeley DB code used by NSS. The Berkeley DB code organizes a DB file as a linear array of "pages" of 16KB (by default). It keeps in process memory an LRU page cache of 8-16 pages. If any page changes on disk while a copy of that page is cached, you have cache inconsistency. This may well lead to DB corruption and/or crashes. The old Berkeley DB code simply was not designed for concurrent access in any way, shape or form, IMO. As long as the DB remains strictly unmodified on disk, it can be safely shared by any number of processes that do not change it. But as soon as any page in the file changes, you can expect that all processes that are using that DB will begin to report DB errors, and maybe crash. In order to make a change to a Berkeley DB that is in use by multiple processes simultaneously, it is necessary to first get ALL of the processes to close the DBs and flush their caches. Then one process can modify it, and close it, (flushing its caches). Then all the others can reopen it and begin to use it again. >> so what that essentially means to you is that you cannot modify sec >> db on the fly and have to prevent that from happening by any means >> necessary. from your ldap enabled app i would suggest calling NSSs >> own NSS_Shutdown() then making whatever changes you need to make to >> secdb then calling ldapssl* init functions again which will trigger >> NSS_Init/ialize() further down the line and your ldap app has up to >> date secdb then. NSS_Shutdown returns a value indicating success for failure. It can fail. It DOES fail if the process that calls it is still holding references to objects created by NSS. In order for NSS_Shutdown to succeed, EVERY reference counted object created by NSS must first be freed. That includes the objects NSS creates for the application when the application sets up an SSL socket. You cannot shut down NSS while any SSL socket remains allocated or in use. That includes the SSL client session cache. You must empty (flush) the SSL client cache to shutdown NSS. When NSS shuts down, all the pointers that it has ever given out to objects become invalid. If the application is holding on to a pointer that it got from NSS, and then it shuts down and restarts NSS, and then reuses that "stale" pointer, a crash is likely to ensue. libldap *may* be holding references to NSS objects when you try to shutdown NSS. In general, I would not expect that you will be able to shutdown NSS underneath libldap, without the awareness and participation of libldap. IMO, your best bet to to get libldap to shut down everything it knows about NSS and then shut down NSS. I don't know if libldap has functions to do such a shut down, or not. http://lxr.mozilla.org/mozilla/search?string=NSS_Shutdown suggests that it does not. Mike wrote: > Thanks for the info, Anton. Do you think I need to redo all 3 init > steps after the NSS_Shutdown (ldapssl_clientauth_init, ldapssl_init, > and ldapssl_enable_clientauth)? I tried this approach and got a core > dump in the ldapssl_enable_clientauth call: Did you check the value returned by NSS_Shutdown? I'll bet it failed. > I tried putting a check around this call so it doesn't get called again > after NSS_Shutdown, but then the second sasl_bind cored. I've been > digging through NSS code to try and see what's going on, but was hoping > someone might see this and have more insight. > > Mike I think there are some other possible avenues for you to explore. I gather that you have one (possibly more than one) SSL client process using the cert DB for a long time, possibly holding an SSL connection open for a long time. During that long duration of that client process's lifetime, you want to change the cert used for client auth. It might help if we understood what is motivating that change. Hopefully client auth cert renewal is rather infrequent. If it is frequent, then I think we should ask why that is. Perhaps you need to be using multiple client auth certs concurrently, changing your choice among them from time to time, leaving them all in the cert DB for a long time, rather than changing the cert DB contents frequently. If there's only one process holding the cert DB open for a long time, and if cert renewal is frequent and that is unavoidable, then I'd say the solution is for your process to do the cert updates itself, in process, rather than doing some hand off scheme, effectively passing the cert DB back and forth between an SSL client process and a cert DB update process. The only issue I see with that approach is that libldap appears to open the cert DB read-only. In order to be able to update it from your program, you'd have to open it read-write. That's feasible. I would be cleanest if libldap was extended to do that, but you could do it yourself, with your own alternative implementation of ldapssl_clientauth_init(). If you have multiple processes holding the cert DB open in parallel for a lone time, then your choices would seem to be: a) give each one its own copy of the DB, so it can modify that DB itself (requires that the DB be opened read-write), or b) create some means for a big synchronized shutdown & restart of all the processes, or c) create a new cert DB (and key DB) with the new cert/key, and then do a phased migration of the processes from the old db to the new one. This avoids synchronized shutdown and restart. You can shutdown the processes (or NSS within the processes) one at a time, and immediately restart it using another database (which could be in another directory, or could have a different DB file name prefix; did you know that cert and key DBs can have file name prefixes?), and do this in a progressive manner until all processes have switched over. I hope this message saves you some time, so you won't have to go and figure all this out by trial and error. -- Nelson B _______________________________________________ dev-tech-ldap mailing list [email protected] https://lists.mozilla.org/listinfo/dev-tech-ldap
