next up previous contents
Next: Server Main Up: API Versioning Previous: Admin server stubs   Contents

KADM5 self-reference

Some kadm5 functions call other kadm5 functions ``on their own behalf'' to perform functionality that is necessary but that does not directly affect what the client sees. For example, kadm5_chpass_principal has to enforce password policies; thus, it needs to call kadm5_get_principal and, if the principal has a policy, kadm5_get_policy and kadm5_modify_principal in the process of changing a principal's password. This leads to a complication: what API handle should kadm5_chpass_principal pass to the other kadm5 functions it calls?

The ``obvious,'' but wrong, answer is that it should pass the handle it was given by its caller. The caller may provide an API handle specifying any valid API version. Although the semantics of kadm5_chpass_principal did not change between VERSION_1 and VERSION_2, the declarations of both kadm5_get_principal and kadm5_get_policy did. Thus, to use the caller's API handle, kadm5_chpass_principal will have to have a separate code path for each API version, even though it itself did not change bewteen versions, and duplicate a lot of logic found elsewhere in the library.

Instead, each API handle contains a ``local-use handle,'' or lhandle, that kadm5 functions should use to call other kadm5 functions. For example, the client-side library's handle structure is:

typedef struct _kadm5_server_handle_t {
        krb5_ui_4       magic_number;
        krb5_ui_4       struct_version;
        krb5_ui_4       api_version;
        char *          cache_name;
        int             destroy_cache;
        CLIENT *        clnt;
        krb5_context    context;
        kadm5_config_params params;
        struct _kadm5_server_handle_t *lhandle;
} kadm5_server_handle_rec, *kadm5_server_handle_t;
The lhandle field is allocated automatically when the handle is created. All of the fields of the API handle that are accessed outside kadm5_init are also duplicated in the lhandle; however, the api_version field of the lhandle is always set to a constant value, regardless of the API version specified by the caller to kadm5_init. In the current implementation, the lhandle's api_version is always VERSION_2.

By passing the caller's handle's lhandle to recursively called kadm5 functions, a kadm5 function is assured of invoking the second kadm5 function with a known API version. Additionally, the lhandle's lhandle field points back to the lhandle, in case kadm5 functions call themselves more than one level deep; handle$->$lhandle always points to the same lhandle, no matter how many times the indirection is performed.

This scheme might break down if a kadm5 function has to call another kadm5 function to perform operations that they client will see and for its own benefit, since the semantics of the recursively-called kadm5 function may depend on the API version specified and the client may be depending on a particular version's behavior. Future implementators should avoid creating a situation in which this is possible.


next up previous contents
Next: Server Main Up: API Versioning Previous: Admin server stubs   Contents
Autobuild 2009-09-05