Each call to kadm5_init_* on the client or server creates a new API handle. The handles encapsulate the API and structure versions specified by kadm5_init_*'s caller and all other internal data needed by the library. A process can have multiple open API handles simultaneously by calling kadm5_init_* multiple times, and call can specify a different version, client or service principal, and so forth.
Each kadm5 function verifies the handle it is given with the
CHECK_HANDLE or _KADM5_CHECK_HANDLE macros. The CHECK_HANDLE macro
differs for the client and server library because the handle types
used by those libraries differ, so it is defined in both
client_internal.h
and
server_internal.h
in the library
source directory. In each header file, CHECK_HANDLE first calls
GENERIC_CHECK_HANDLE, defined in
admin_internal.h
, which
verifies the magic number, API version, and structure version that is
contained in both client and server handles. CHECK_HANDLE then calls
either CLIENT_CHECK_HANDLE or SERVER_CHECK_HANDLE respectively to
verify the client- or server-library specific handle fields.
The CHECK_HANDLE macro is useful because it inlines the handle check instead of requiring a separate function call. However, using CHECK_HANDLE means that a source file cannot be compiled once and included into both the client and server library, because CHECK_HANDLE is always either specific to either the client or server library, not both. There are a number of functions that can be implemented with the same code in both the client and server libraries, however, including all of the kadm5_free functions and kadm5_chpass_principal_util. The _KADM5_CHECK_HANDLE macro solves this problem; instead of inlining the handle check, it calls the function _kadm5_check_handle which is defined separately in both the client and server library, in client_init.c and server_init.c. Since these two files are only compiled once and put in a single library, they simply verify the handle they are passed with CHECK_HANDLE and return the result.