> 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

Reply via email to