We need the uber record all the time now, actually, except when merely
inspecting a log file. This is important as we depend on replaying
entries written to the log in order to complete the HDB writes, and if
we don't have an uber record we can't do this step.
Also, log_init() should cleanup on error.
When new keys are added (typically via kadm5_setkey_principal_3),
truncate the key history to remove old keys, that is keys older than
the newest key which was in effect prior longer ago than the principal's
maximum ticket lifetime. This feature is controlled via the "[kadmin]"
section's "prune-key-history" boolean parameter, which defaults to false.
Currently this happens only when kadm5_setkey_principal_3()
is called directly on the server, the client API simulates
kadm5_setkey_principal_3() via a get, update, modify sequence that does
not prune the key history. The plan is to add a new kadm5 protocol RPC
and convert clients to call that instead.
In setkey_principal_3 seal keys after entry key update
Also, for now, don't check the return value of kadm5_log_modify() in
the new kadm5_s_setkey_principal_3(). This has to be addressed more
globally.
Censor stale keys in kadm5_s_get_principal
- fix int/uint confusion and use unsigned integral types for time
- improve messages
- add --verbose option
- attempt transaction recovery in ipropd-master during idle times
- begin hardening daemons against dying at the slightest provocation
- better recovery from various errors
- daemons now restart automatically in most of the many error cases
where the daemons still die
We used to update the iprop log and HDB in different orders depending on
the kadm5 operation, which then led to various race conditions.
The iprop log now functions as a two-phase commit (with roll forward)
log for HDB changes. The log is auto-truncated, keeping the latest
entries that fit in a configurable maximum number of bytes (defaults to
50MB). See the log-max-size parameter description in krb5.conf(5).
The iprop log format and the protocol remain backwards-compatible with
earlier versions of Heimdal. This is NOT a flag-day; there is NO need
to update all the slaves at once with the master, though it is advisable
in general. Rolling upgrades and downgrades should work.
The sequence of updates is now (with HDB and log open and locked):
a) check that the HDB operation will succeed if attempted,
b) append to iprop log and fsync() it,
c) write to HDB (which should fsync()),
d) mark last log record committed (no fsync in this case).
Every kadm5 write operation recover transactions not yet confirmed as
committed, thus there can be at most one unconfirmed commit on a master
KDC.
Reads via kadm5_get_principal() also attempt to lock the log, and if
successful, recover unconfirmed transactions; readers must have write
access and must win any race to lock the iprop log.
The ipropd-master daemon also attempts to recover unconfirmed
transactions when idle.
The log now starts with a nop record whose payload records the offset of
the logical end of the log: the end of the last confirmed committed
transaction. This is kown as the "uber record". Its purpose is
two-fold: act as the confirmation of committed transactions, and provide
an O(1) method of finding the end of the log (i.e., without having to
traverse the entire log front to back).
Two-phase commit makes all kadm5 writes single-operation atomic
transactions (though some kadm5 operations, such as renames of
principals, and changes to principals' aliases, use multiple low-level
HDB write operations, but still all in one transaction). One can still
hold a lock on the HDB across many operations (e.g., by using the lock
command in a kadmin -l or calling kadm5_lock()) in order to push
multiple transactions in sequence, but this sequence will not be atomic
if the process or host crashes in the middle.
As before, HDB writes which do not go through the kadm5 API are excluded
from all of this, but there should be no such writes.
Lastly, the iprop-log(1) command is enhanced as follows:
- The dump, last-version, truncate, and replay sub-commands now have an
option to not lock the log. This is useful for inspecting a running
system's log file, especially on slave KDCs.
- The dump, last-version, truncate, and replay sub-commands now take an
optional iprop log file positional argument, so that they may be used
to inspect log files other than the running system's
configured/default log file.
Extensive code review and some re-writing for clarity by Viktor Dukhovni.
The following sequence of events results in slave B having a stale HDB:
- slave A connects to master, master dumps HDB for the slave
- kadm5 operations
- slave B connects to master, master sends previously dumped HDB
slave B won't discover any updates until the next transaction.
The fix is simple: the slave should immediately call ihave() after
receiving a complete HDB.
Tests that start daemons have to "wait" for them to start.
This commit makes Heimdal daemons prep to detach (when requested) by
forking early, then having the child signal readiness to the parent when
the child really is ready. The parent exits only which the child is
ready. This means that tests will no longer need to wait for daemons.
However, tests will still need a pidfile or such so they can stop the
daemons.
Note that the --detach options should not be used on OS X from launchd,
only from tests.
Modify the NTMakefile rules for tests so that a failed test does
not prevent subsequent tests from being executed.
Change-Id: I9595ad4a1527feae7c402241bf06ab21a0b76d4a
kadmin should not permit a modify that stores invalid keys into the
database. Accepting bad key data into the database will result in
errors when those keys are eventually used.
This change does not address the general case. It does address the
specific case of the kadmin client attempting to store the magic
bogus key since that is trivial to check for and can be unintentionally
returned to kadmind by a 1.6rc2 or prior client. This can happen when
a user has get privilege but lacks the new get-keys privilege.
Change-Id: I44795e6428472b75ab1e4257ce7cb9160f0299f5
Introduce kadm5_all_keys_are_bogus() and kadm5_some_keys_are_bogus()
which will be used in later changes.
Change-Id: I3a07ffe07bee7d6eb17c3d2eae91c107e0bac255
When we added the get-keys privilege we lost the ability to setup
keytabs with the kadmin ext command. The fix is to note that we got
bogus key data and randkey (as we used to).
On Windows a file descriptor is an int value allocated by the
local module instance of the C Run Time Library. A socket handle is a
SOCKET value allocated by a Winsock Provider for the requested family and
protocol. These two values cannot be mixed and there is no mechanism for
converting between the two. The _get_osfhandle() and _open_osfhandle()
functions can work with a standard HANDLE (file, pipe, etc) but cannot be
used for a SOCKET.
The Heimdal krb5_storage_from_fd() routine counted on the osf conversion
functions working on SOCKET values. Since they do not any attempt to call
krb5_storage_from_fd() on a socket resulted in an assertion being thrown
by the C RTL.
Another problem is SOCKET value truncation when storing a 64-bit value
into a 32-bit int.
To address these problems a new krb5_storage_from_socket() routine is
introduced. This routine setups a krb5_storage that stores a socket value
as a rk_socket_t and provides a set of helper routines that always use
network ready functions.
The krb5_storage_from_fd() routines no longer use net_read() and
net_write() but provide helpers that follow their logic so that pipes can
be processed.
All call sites that allocate a socket now store the socket as rk_socket_t
and call krb5_storage_from_socket().
All locations that previously called the bare close() on a socket value
now call rk_closesocket().
Change-Id: I045f775b2a5dbf5cf803751409490bc27fffe597
kadm5_c_destroy did not use rk_closesocket when cleaning up
the context. This results in an exception on Windows since a
socket is not a file descriptor.
Change-Id: I9ebddad61f0199acb495a0773925df4f41e4fef2
In order to support plugins for kadmin that use libkadm5srv, the
libkadm5clnt library has to be versioned to avoid hijacking all
of the function calls that should go to the server library. Omit
the _kadm5_ clients from the public interface, and version
everything else.
Signed-off-by: Love Hörnquist Åstrand <lha@h5l.org>
To stop the errors when building concurrently, we make a number of
changes:
1. stop including generated files in *_SOURCES,
2. make *-protos.h and *-private.h depend on the *_SOURCES,
3. make all objects depend on *-{protos,private}.h,
4. in a few places change dir/header.h to $(srcdir)/dir/header.h,
This appears to work for me with make -j16 on a 4-way box.
synchronize the export lists on Windows and UNIX.
When new functions are exported on UNIX or Windows,
the "test" build target on Windows will verify if
the export lists are in sync.
Change-Id: I9df3607983b03ee8dc6fa7cd22f85b07a6cee784
We should not hold locks on the master's database while waiting
for network I/O which may take a terribly long time to complete as
this will block out all writers and could therefore be slightly
problematic. ipropd-master was holding a shared lock on the database
while sending a complete propation to slaves which are out of sync
with the log file. We fix this by writing what we intend to send
in record format into a file hdb_db_dir()/ipropd.dumpfile while
holding a shared lock on the database and then we send the contents
of the file after releasing the lock. We also save and re-use the file
that we generated during future complete propagation events as long
as the log is long enough to get us back to the state previously
dumped.
We can't use O_TRUNC on open because (without O_EXLOCK which is
not portable) we would be modifying the file without an exclusive
lock. So, we drop the use of O_TRUNC and use ftruncate(2) after
obtaining the lock via flock(2).