FreeIPA maintains the policy name reference internally, and hand- marshals an osa_princ_ent_t value containing the policy name (with the other fields set to trivial values). I note this to affirm that we need to expose a marshalling function, not just an unmarshalling function. The libkadm5_srv XDR code for osa_princ_ent_t (lib/kadm5/srv/adb_xdr.c) depends on kadmin protocol XDR code (lib/kadm5/kadm_rpc_xdr.c) in several ways. The dependencies are: xdr_nullstring xdr_krb5_int16 xdr_krb5_ui_2 xdr_krb5_kvno We cannot use libkadm5srv functions (public or private) from libkdb5 because it would create a dependency cycle. So simply moving the osa_princ_ent_t XDR code to libkdb5 requires us to resolve these dependencies. xdr_nullstring is a 48-line function. It is similar to xdr_string(), but it adds one to the string length and encodes the string terminator. Null strings are then marshalled as a zero length with no following bytes. We could conceivably push this into librpc, although there is nothing equivalent in libtirpc or Solaris's RPC. xdr_krb5_kvno() is just xdr_u_int(). For xdr_krb5_int16 and xdr_krb5_ui_2, we could abuse xdr_short() and xdr_u_short() (already done in plugins/kdb/db2/pol_xdr.c for policy n_tl_data) or, more correctly, we could add 16-bit integer XDR functions to complement our 32-bit integer functions. libtirpc and Solaris do have 16-bit XDR functions; unfortunately, our existing 32-bit XDR integer function names do not match theirs. We have xdr_int32() and xdr_u_int32(). libtirpc has xdr_int32_t(), xdr_u_int32_t(), and xdr_uint32_t(). Solaris has xdr_int32_t() and xdr_uint32_t(). Alternatively we could rewrite the osa_princ_ent_t code using k5buf and k5input. Because XDR variable-length objects are 32-bit aligned, this code would be more fiddly than usual and there would be some risk of incompatibility.