2N/A/* -*- mode: c; c-file-style: "bsd"; indent-tabs-mode: t -*- */
2N/A
2N/A/*
2N/A * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
2N/A */
2N/A
2N/A/*
2N/A * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved
2N/A */
2N/A
2N/A/*
2N/A * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
2N/A *
2N/A * Openvision retains the copyright to derivative works of
2N/A * this source code. Do *NOT* create a derivative of this
2N/A * source code before consulting with your legal department.
2N/A * Do *NOT* integrate *ANY* of this source code into another
2N/A * product before consulting with your legal department.
2N/A *
2N/A * For further information, read the top-level Openvision
2N/A * copyright which is contained in the top-level MIT Kerberos
2N/A * copyright.
2N/A *
2N/A * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
2N/A *
2N/A */
2N/A
2N/A#include <rpc/rpc.h>
2N/A#include <krb5.h>
2N/A#include <errno.h>
2N/A#include <kadm5/admin.h>
2N/A#include <kadm5/kadm_rpc.h>
2N/A#include <kadm5/admin_xdr.h>
2N/A#include <stdlib.h>
2N/A#include <string.h>
2N/A
2N/Astatic bool_t
2N/A_xdr_kadm5_principal_ent_rec(XDR *xdrs, kadm5_principal_ent_rec *objp,
2N/A int v);
2N/Astatic bool_t
2N/A_xdr_kadm5_policy_ent_rec(XDR *xdrs, kadm5_policy_ent_rec *objp, int vers);
2N/A
2N/A/*
2N/A * Function: xdr_ui_4
2N/A *
2N/A * Purpose: XDR function which serves as a wrapper for xdr_u_int,
2N/A * to prevent compiler warnings about type clashes between u_int32
2N/A * and krb5_ui_4.
2N/A */
2N/Abool_t xdr_ui_4(XDR *xdrs, krb5_ui_4 *objp)
2N/A{
2N/A /* Assumes that krb5_ui_4 and u_int32 are both four bytes long.
2N/A This should not be a harmful assumption. */
2N/A return xdr_u_int(xdrs, (uint32_t *) objp);
2N/A}
2N/A
2N/A
2N/A/*
2N/A * Function: xdr_nullstring
2N/A *
2N/A * Purpose: XDR function for "strings" that are either NULL-terminated
2N/A * or NULL.
2N/A */
2N/Abool_t xdr_nullstring(XDR *xdrs, char **objp)
2N/A{
2N/A u_int size;
2N/A
2N/A if (xdrs->x_op == XDR_ENCODE) {
2N/A if (*objp == NULL)
2N/A size = 0;
2N/A else
2N/A size = strlen(*objp) + 1;
2N/A }
2N/A if (! xdr_u_int(xdrs, &size)) {
2N/A return FALSE;
2N/A }
2N/A switch (xdrs->x_op) {
2N/A case XDR_DECODE:
2N/A if (size == 0) {
2N/A *objp = NULL;
2N/A return TRUE;
2N/A } else if (*objp == NULL) {
2N/A *objp = (char *) mem_alloc(size);
2N/A if (*objp == NULL) {
2N/A errno = ENOMEM;
2N/A return FALSE;
2N/A }
2N/A }
2N/A return (xdr_opaque(xdrs, *objp, size));
2N/A
2N/A case XDR_ENCODE:
2N/A if (size != 0)
2N/A return (xdr_opaque(xdrs, *objp, size));
2N/A return TRUE;
2N/A
2N/A case XDR_FREE:
2N/A if (*objp != NULL)
2N/A mem_free(*objp, size);
2N/A *objp = NULL;
2N/A return TRUE;
2N/A }
2N/A
2N/A return FALSE;
2N/A}
2N/A
2N/A/*
2N/A * Function: xdr_nulltype
2N/A *
2N/A * Purpose: XDR function for arbitrary pointer types that are either
2N/A * NULL or contain data.
2N/A */
2N/Abool_t xdr_nulltype(XDR *xdrs, void **objp, xdrproc_t proc)
2N/A{
2N/A bool_t null;
2N/A
2N/A switch (xdrs->x_op) {
2N/A case XDR_DECODE:
2N/A if (!xdr_bool(xdrs, &null))
2N/A return FALSE;
2N/A if (null) {
2N/A *objp = NULL;
2N/A return TRUE;
2N/A }
2N/A return (*proc)(xdrs, objp);
2N/A
2N/A case XDR_ENCODE:
2N/A if (*objp == NULL)
2N/A null = TRUE;
2N/A else
2N/A null = FALSE;
2N/A if (!xdr_bool(xdrs, &null))
2N/A return FALSE;
2N/A if (null == FALSE)
2N/A return (*proc)(xdrs, objp);
2N/A return TRUE;
2N/A
2N/A case XDR_FREE:
2N/A if (*objp)
2N/A return (*proc)(xdrs, objp);
2N/A return TRUE;
2N/A }
2N/A
2N/A return FALSE;
2N/A}
2N/A
2N/Abool_t
2N/Axdr_krb5_timestamp(XDR *xdrs, krb5_timestamp *objp)
2N/A{
2N/A /* This assumes that int32 and krb5_timestamp are the same size.
2N/A This shouldn't be a problem, since we've got a unit test which
2N/A checks for this. */
2N/A if (!xdr_int(xdrs, (int32_t *) objp)) {
2N/A return (FALSE);
2N/A }
2N/A return (TRUE);
2N/A}
2N/A
2N/Abool_t
2N/Axdr_krb5_kvno(XDR *xdrs, krb5_kvno *objp)
2N/A{
2N/A unsigned char tmp;
2N/A
2N/A tmp = '\0'; /* for purify, else xdr_u_char performs a umr */
2N/A
2N/A if (xdrs->x_op == XDR_ENCODE)
2N/A tmp = (unsigned char) *objp;
2N/A
2N/A if (!xdr_u_char(xdrs, &tmp))
2N/A return (FALSE);
2N/A
2N/A if (xdrs->x_op == XDR_DECODE)
2N/A *objp = (krb5_kvno) tmp;
2N/A
2N/A return (TRUE);
2N/A}
2N/A
2N/Abool_t
2N/Axdr_krb5_deltat(XDR *xdrs, krb5_deltat *objp)
2N/A{
2N/A /* This assumes that int32 and krb5_deltat are the same size.
2N/A This shouldn't be a problem, since we've got a unit test which
2N/A checks for this. */
2N/A if (!xdr_int(xdrs, (int32_t *) objp)) {
2N/A return (FALSE);
2N/A }
2N/A return (TRUE);
2N/A}
2N/A
2N/Abool_t
2N/Axdr_krb5_flags(XDR *xdrs, krb5_flags *objp)
2N/A{
2N/A /* This assumes that int32 and krb5_flags are the same size.
2N/A This shouldn't be a problem, since we've got a unit test which
2N/A checks for this. */
2N/A if (!xdr_int(xdrs, (int32_t *) objp)) {
2N/A return (FALSE);
2N/A }
2N/A return (TRUE);
2N/A}
2N/A
2N/Abool_t
2N/Axdr_krb5_ui_4(XDR *xdrs, krb5_ui_4 *objp)
2N/A{
2N/A if (!xdr_u_int(xdrs, (uint32_t *) objp)) {
2N/A return (FALSE);
2N/A }
2N/A return (TRUE);
2N/A}
2N/A
2N/Abool_t
2N/Axdr_krb5_int16(XDR *xdrs, krb5_int16 *objp)
2N/A{
2N/A int tmp;
2N/A
2N/A tmp = (int) *objp;
2N/A
2N/A if (!xdr_int(xdrs, &tmp))
2N/A return(FALSE);
2N/A
2N/A *objp = (krb5_int16) tmp;
2N/A
2N/A return(TRUE);
2N/A}
2N/A
2N/A/*
2N/A * Function: xdr_krb5_ui_2
2N/A *
2N/A * Purpose: XDR function which serves as a wrapper for xdr_u_int,
2N/A * to prevent compiler warnings about type clashes between u_int
2N/A * and krb5_ui_2.
2N/A */
2N/Abool_t
2N/Axdr_krb5_ui_2(XDR *xdrs, krb5_ui_2 *objp)
2N/A{
2N/A unsigned int tmp;
2N/A
2N/A tmp = (unsigned int) *objp;
2N/A
2N/A if (!xdr_u_int(xdrs, &tmp))
2N/A return(FALSE);
2N/A
2N/A *objp = (krb5_ui_2) tmp;
2N/A
2N/A return(TRUE);
2N/A}
2N/A
2N/A
2N/A
2N/Astatic bool_t xdr_krb5_boolean(XDR *xdrs, krb5_boolean *kbool)
2N/A{
2N/A bool_t val;
2N/A
2N/A switch (xdrs->x_op) {
2N/A case XDR_DECODE:
2N/A if (!xdr_bool(xdrs, &val))
2N/A return FALSE;
2N/A
2N/A *kbool = (val == FALSE) ? FALSE : TRUE;
2N/A return TRUE;
2N/A
2N/A case XDR_ENCODE:
2N/A val = *kbool ? TRUE : FALSE;
2N/A return xdr_bool(xdrs, &val);
2N/A
2N/A case XDR_FREE:
2N/A return TRUE;
2N/A }
2N/A
2N/A return FALSE;
2N/A}
2N/A
2N/Abool_t xdr_krb5_key_data_nocontents(XDR *xdrs, krb5_key_data *objp)
2N/A{
2N/A /*
2N/A * Note that this function intentionally DOES NOT tranfer key
2N/A * length or contents! xdr_krb5_key_data in adb_xdr.c does, but
2N/A * that is only for use within the server-side library.
2N/A */
2N/A unsigned int tmp;
2N/A
2N/A if (xdrs->x_op == XDR_DECODE)
2N/A memset(objp, 0, sizeof(krb5_key_data));
2N/A
2N/A if (!xdr_krb5_int16(xdrs, &objp->key_data_ver)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_krb5_int16(xdrs, &objp->key_data_kvno)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_krb5_int16(xdrs, &objp->key_data_type[0])) {
2N/A return (FALSE);
2N/A }
2N/A if (objp->key_data_ver > 1) {
2N/A if (!xdr_krb5_int16(xdrs, &objp->key_data_type[1])) {
2N/A return (FALSE);
2N/A }
2N/A }
2N/A /*
2N/A * kadm5_get_principal on the server side allocates and returns
2N/A * key contents when asked. Even though this function refuses to
2N/A * transmit that data, it still has to *free* the data at the
2N/A * appropriate time to avoid a memory leak.
2N/A */
2N/A if (xdrs->x_op == XDR_FREE) {
2N/A tmp = (unsigned int) objp->key_data_length[0];
2N/A if (!xdr_bytes(xdrs, (char **) &objp->key_data_contents[0],
2N/A &tmp, ~0))
2N/A return FALSE;
2N/A
2N/A tmp = (unsigned int) objp->key_data_length[1];
2N/A if (!xdr_bytes(xdrs, (char **) &objp->key_data_contents[1],
2N/A &tmp, ~0))
2N/A return FALSE;
2N/A }
2N/A
2N/A return (TRUE);
2N/A}
2N/A
2N/A
2N/Abool_t
2N/Axdr_krb5_key_salt_tuple(XDR *xdrs, krb5_key_salt_tuple *objp)
2N/A{
2N/A if (!xdr_krb5_enctype(xdrs, &objp->ks_enctype))
2N/A return FALSE;
2N/A if (!xdr_krb5_salttype(xdrs, &objp->ks_salttype))
2N/A return FALSE;
2N/A return TRUE;
2N/A}
2N/A
2N/Abool_t xdr_krb5_tl_data(XDR *xdrs, krb5_tl_data **tl_data_head)
2N/A{
2N/A krb5_tl_data *tl, *tl2;
2N/A bool_t more;
2N/A unsigned int len;
2N/A
2N/A switch (xdrs->x_op) {
2N/A case XDR_FREE:
2N/A tl = tl2 = *tl_data_head;
2N/A while (tl) {
2N/A tl2 = tl->tl_data_next;
2N/A free(tl->tl_data_contents);
2N/A free(tl);
2N/A tl = tl2;
2N/A }
2N/A break;
2N/A
2N/A case XDR_ENCODE:
2N/A tl = *tl_data_head;
2N/A while (1) {
2N/A more = (tl != NULL);
2N/A if (!xdr_bool(xdrs, &more))
2N/A return FALSE;
2N/A if (tl == NULL)
2N/A break;
2N/A if (!xdr_krb5_int16(xdrs, &tl->tl_data_type))
2N/A return FALSE;
2N/A len = tl->tl_data_length;
2N/A if (!xdr_bytes(xdrs, (char **) &tl->tl_data_contents, &len, ~0))
2N/A return FALSE;
2N/A tl = tl->tl_data_next;
2N/A }
2N/A break;
2N/A
2N/A case XDR_DECODE:
2N/A tl = NULL;
2N/A while (1) {
2N/A if (!xdr_bool(xdrs, &more))
2N/A return FALSE;
2N/A if (more == FALSE)
2N/A break;
2N/A tl2 = (krb5_tl_data *) malloc(sizeof(krb5_tl_data));
2N/A if (tl2 == NULL)
2N/A return FALSE;
2N/A memset(tl2, 0, sizeof(krb5_tl_data));
2N/A if (!xdr_krb5_int16(xdrs, &tl2->tl_data_type))
2N/A return FALSE;
2N/A if (!xdr_bytes(xdrs, (char **)&tl2->tl_data_contents, &len, ~0))
2N/A return FALSE;
2N/A tl2->tl_data_length = len;
2N/A
2N/A tl2->tl_data_next = tl;
2N/A tl = tl2;
2N/A }
2N/A
2N/A *tl_data_head = tl;
2N/A break;
2N/A }
2N/A
2N/A return TRUE;
2N/A}
2N/A
2N/Abool_t
2N/Axdr_kadm5_ret_t(XDR *xdrs, kadm5_ret_t *objp)
2N/A{
2N/A uint32_t tmp;
2N/A
2N/A if (xdrs->x_op == XDR_ENCODE)
2N/A tmp = (uint32_t) *objp;
2N/A
2N/A if (!xdr_u_int(xdrs, &tmp))
2N/A return (FALSE);
2N/A
2N/A if (xdrs->x_op == XDR_DECODE)
2N/A *objp = (kadm5_ret_t) tmp;
2N/A
2N/A return (TRUE);
2N/A}
2N/A
2N/Abool_t xdr_kadm5_principal_ent_rec(XDR *xdrs,
2N/A kadm5_principal_ent_rec *objp)
2N/A{
2N/A return _xdr_kadm5_principal_ent_rec(xdrs, objp, KADM5_API_VERSION_3);
2N/A}
2N/A
2N/Astatic bool_t
2N/A_xdr_kadm5_principal_ent_rec(XDR *xdrs, kadm5_principal_ent_rec *objp,
2N/A int v)
2N/A{
2N/A unsigned int n;
2N/A
2N/A if (!xdr_krb5_principal(xdrs, &objp->principal)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_krb5_timestamp(xdrs, &objp->princ_expire_time)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_krb5_timestamp(xdrs, &objp->last_pwd_change)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_krb5_timestamp(xdrs, &objp->pw_expiration)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_krb5_deltat(xdrs, &objp->max_life)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_nulltype(xdrs, (void **) &objp->mod_name,
2N/A xdr_krb5_principal)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_krb5_timestamp(xdrs, &objp->mod_date)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_krb5_flags(xdrs, &objp->attributes)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_krb5_kvno(xdrs, &objp->kvno)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_krb5_kvno(xdrs, &objp->mkvno)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_nullstring(xdrs, &objp->policy)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_long(xdrs, &objp->aux_attributes)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_krb5_deltat(xdrs, &objp->max_renewable_life)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_krb5_timestamp(xdrs, &objp->last_success)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_krb5_timestamp(xdrs, &objp->last_failed)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_krb5_kvno(xdrs, &objp->fail_auth_count)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_krb5_int16(xdrs, &objp->n_key_data)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_krb5_int16(xdrs, &objp->n_tl_data)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_nulltype(xdrs, (void **) &objp->tl_data,
2N/A xdr_krb5_tl_data)) {
2N/A return FALSE;
2N/A }
2N/A n = objp->n_key_data;
2N/A if (!xdr_array(xdrs, (caddr_t *) &objp->key_data,
2N/A &n, ~0, sizeof(krb5_key_data),
2N/A xdr_krb5_key_data_nocontents)) {
2N/A return (FALSE);
2N/A }
2N/A
2N/A return (TRUE);
2N/A}
2N/A
2N/Astatic bool_t
2N/A_xdr_kadm5_policy_ent_rec(XDR *xdrs, kadm5_policy_ent_rec *objp, int vers)
2N/A{
2N/A if (!xdr_nullstring(xdrs, &objp->policy)) {
2N/A return (FALSE);
2N/A }
2N/A /* these all used to be u_int32, but it's stupid for sized types
2N/A to be exposed at the api, and they're the same as longs on the
2N/A wire. */
2N/A if (!xdr_long(xdrs, &objp->pw_min_life)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_long(xdrs, &objp->pw_max_life)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_long(xdrs, &objp->pw_min_length)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_long(xdrs, &objp->pw_min_classes)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_long(xdrs, &objp->pw_history_num)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_long(xdrs, &objp->policy_refcnt)) {
2N/A return (FALSE);
2N/A }
2N/A if (vers == KADM5_API_VERSION_3) {
2N/A if (!xdr_krb5_kvno(xdrs, &objp->pw_max_fail))
2N/A return (FALSE);
2N/A if (!xdr_krb5_deltat(xdrs, &objp->pw_failcnt_interval))
2N/A return (FALSE);
2N/A if (!xdr_krb5_deltat(xdrs, &objp->pw_lockout_duration))
2N/A return (FALSE);
2N/A } else if (xdrs->x_op == XDR_DECODE) {
2N/A objp->pw_max_fail = 0;
2N/A objp->pw_failcnt_interval = 0;
2N/A objp->pw_lockout_duration = 0;
2N/A }
2N/A return (TRUE);
2N/A}
2N/A
2N/Abool_t
2N/Axdr_kadm5_policy_ent_rec(XDR *xdrs, kadm5_policy_ent_rec *objp)
2N/A{
2N/A return _xdr_kadm5_policy_ent_rec(xdrs, objp, KADM5_API_VERSION_3);
2N/A}
2N/A
2N/Abool_t
2N/Axdr_cprinc_arg(XDR *xdrs, cprinc_arg *objp)
2N/A{
2N/A if (!xdr_ui_4(xdrs, &objp->api_version)) {
2N/A return (FALSE);
2N/A }
2N/A if (!_xdr_kadm5_principal_ent_rec(xdrs, &objp->rec,
2N/A objp->api_version)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_long(xdrs, &objp->mask)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_nullstring(xdrs, &objp->passwd)) {
2N/A return (FALSE);
2N/A }
2N/A return (TRUE);
2N/A}
2N/A
2N/Abool_t
2N/Axdr_cprinc3_arg(XDR *xdrs, cprinc3_arg *objp)
2N/A{
2N/A if (!xdr_ui_4(xdrs, &objp->api_version)) {
2N/A return (FALSE);
2N/A }
2N/A if (!_xdr_kadm5_principal_ent_rec(xdrs, &objp->rec,
2N/A objp->api_version)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_long(xdrs, &objp->mask)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_array(xdrs, (caddr_t *)&objp->ks_tuple,
2N/A (unsigned int *)&objp->n_ks_tuple, ~0,
2N/A sizeof(krb5_key_salt_tuple),
2N/A xdr_krb5_key_salt_tuple)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_nullstring(xdrs, &objp->passwd)) {
2N/A return (FALSE);
2N/A }
2N/A return (TRUE);
2N/A}
2N/A
2N/Abool_t
2N/Axdr_generic_ret(XDR *xdrs, generic_ret *objp)
2N/A{
2N/A if (!xdr_ui_4(xdrs, &objp->api_version)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_kadm5_ret_t(xdrs, &objp->code)) {
2N/A return (FALSE);
2N/A }
2N/A
2N/A return(TRUE);
2N/A}
2N/A
2N/Abool_t
2N/Axdr_dprinc_arg(XDR *xdrs, dprinc_arg *objp)
2N/A{
2N/A if (!xdr_ui_4(xdrs, &objp->api_version)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_krb5_principal(xdrs, &objp->princ)) {
2N/A return (FALSE);
2N/A }
2N/A return (TRUE);
2N/A}
2N/A
2N/Abool_t
2N/Axdr_mprinc_arg(XDR *xdrs, mprinc_arg *objp)
2N/A{
2N/A if (!xdr_ui_4(xdrs, &objp->api_version)) {
2N/A return (FALSE);
2N/A }
2N/A if (!_xdr_kadm5_principal_ent_rec(xdrs, &objp->rec,
2N/A objp->api_version)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_long(xdrs, &objp->mask)) {
2N/A return (FALSE);
2N/A }
2N/A return (TRUE);
2N/A}
2N/A
2N/Abool_t
2N/Axdr_rprinc_arg(XDR *xdrs, rprinc_arg *objp)
2N/A{
2N/A if (!xdr_ui_4(xdrs, &objp->api_version)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_krb5_principal(xdrs, &objp->src)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_krb5_principal(xdrs, &objp->dest)) {
2N/A return (FALSE);
2N/A }
2N/A return (TRUE);
2N/A}
2N/A
2N/Abool_t
2N/Axdr_gprincs_arg(XDR *xdrs, gprincs_arg *objp)
2N/A{
2N/A if (!xdr_ui_4(xdrs, &objp->api_version)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_nullstring(xdrs, &objp->exp)) {
2N/A return (FALSE);
2N/A }
2N/A return (TRUE);
2N/A}
2N/A
2N/Abool_t
2N/Axdr_gprincs_ret(XDR *xdrs, gprincs_ret *objp)
2N/A{
2N/A if (!xdr_ui_4(xdrs, &objp->api_version)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_kadm5_ret_t(xdrs, &objp->code)) {
2N/A return (FALSE);
2N/A }
2N/A if (objp->code == KADM5_OK) {
2N/A if (!xdr_int(xdrs, &objp->count)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_array(xdrs, (caddr_t *) &objp->princs,
2N/A (unsigned int *) &objp->count, ~0,
2N/A sizeof(char *), xdr_nullstring)) {
2N/A return (FALSE);
2N/A }
2N/A }
2N/A
2N/A return (TRUE);
2N/A}
2N/A
2N/Abool_t
2N/Axdr_chpass_arg(XDR *xdrs, chpass_arg *objp)
2N/A{
2N/A if (!xdr_ui_4(xdrs, &objp->api_version)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_krb5_principal(xdrs, &objp->princ)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_nullstring(xdrs, &objp->pass)) {
2N/A return (FALSE);
2N/A }
2N/A return (TRUE);
2N/A}
2N/A
2N/Abool_t
2N/Axdr_chpass3_arg(XDR *xdrs, chpass3_arg *objp)
2N/A{
2N/A if (!xdr_ui_4(xdrs, &objp->api_version)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_krb5_principal(xdrs, &objp->princ)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_krb5_boolean(xdrs, &objp->keepold)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_array(xdrs, (caddr_t *)&objp->ks_tuple,
2N/A (unsigned int*)&objp->n_ks_tuple, ~0,
2N/A sizeof(krb5_key_salt_tuple),
2N/A xdr_krb5_key_salt_tuple)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_nullstring(xdrs, &objp->pass)) {
2N/A return (FALSE);
2N/A }
2N/A return (TRUE);
2N/A}
2N/A
2N/Abool_t
2N/Axdr_setv4key_arg(XDR *xdrs, setv4key_arg *objp)
2N/A{
2N/A unsigned int n_keys = 1;
2N/A
2N/A if (!xdr_ui_4(xdrs, &objp->api_version)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_krb5_principal(xdrs, &objp->princ)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_array(xdrs, (caddr_t *) &objp->keyblock,
2N/A &n_keys, ~0,
2N/A sizeof(krb5_keyblock), xdr_krb5_keyblock)) {
2N/A return (FALSE);
2N/A }
2N/A return (TRUE);
2N/A}
2N/A
2N/Abool_t
2N/Axdr_setkey_arg(XDR *xdrs, setkey_arg *objp)
2N/A{
2N/A if (!xdr_ui_4(xdrs, &objp->api_version)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_krb5_principal(xdrs, &objp->princ)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_array(xdrs, (caddr_t *) &objp->keyblocks,
2N/A (unsigned int *) &objp->n_keys, ~0,
2N/A sizeof(krb5_keyblock), xdr_krb5_keyblock)) {
2N/A return (FALSE);
2N/A }
2N/A return (TRUE);
2N/A}
2N/A
2N/Abool_t
2N/Axdr_setkey3_arg(XDR *xdrs, setkey3_arg *objp)
2N/A{
2N/A if (!xdr_ui_4(xdrs, &objp->api_version)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_krb5_principal(xdrs, &objp->princ)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_krb5_boolean(xdrs, &objp->keepold)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_array(xdrs, (caddr_t *) &objp->ks_tuple,
2N/A (unsigned int *) &objp->n_ks_tuple, ~0,
2N/A sizeof(krb5_key_salt_tuple), xdr_krb5_key_salt_tuple)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_array(xdrs, (caddr_t *) &objp->keyblocks,
2N/A (unsigned int *) &objp->n_keys, ~0,
2N/A sizeof(krb5_keyblock), xdr_krb5_keyblock)) {
2N/A return (FALSE);
2N/A }
2N/A return (TRUE);
2N/A}
2N/A
2N/Abool_t
2N/Axdr_chrand_arg(XDR *xdrs, chrand_arg *objp)
2N/A{
2N/A if (!xdr_ui_4(xdrs, &objp->api_version)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_krb5_principal(xdrs, &objp->princ)) {
2N/A return (FALSE);
2N/A }
2N/A return (TRUE);
2N/A}
2N/A
2N/Abool_t
2N/Axdr_chrand3_arg(XDR *xdrs, chrand3_arg *objp)
2N/A{
2N/A if (!xdr_ui_4(xdrs, &objp->api_version)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_krb5_principal(xdrs, &objp->princ)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_krb5_boolean(xdrs, &objp->keepold)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_array(xdrs, (caddr_t *)&objp->ks_tuple,
2N/A (unsigned int*)&objp->n_ks_tuple, ~0,
2N/A sizeof(krb5_key_salt_tuple),
2N/A xdr_krb5_key_salt_tuple)) {
2N/A return (FALSE);
2N/A }
2N/A return (TRUE);
2N/A}
2N/A
2N/Abool_t
2N/Axdr_chrand_ret(XDR *xdrs, chrand_ret *objp)
2N/A{
2N/A if (!xdr_ui_4(xdrs, &objp->api_version)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_kadm5_ret_t(xdrs, &objp->code)) {
2N/A return (FALSE);
2N/A }
2N/A if (objp->code == KADM5_OK) {
2N/A /* Solaris Kerberos */
2N/A if (!xdr_array(xdrs, (char **)&objp->keys, (unsigned int *)&objp->n_keys, ~0,
2N/A sizeof(krb5_keyblock), xdr_krb5_keyblock))
2N/A return FALSE;
2N/A }
2N/A
2N/A return (TRUE);
2N/A}
2N/A
2N/Abool_t
2N/Axdr_gprinc_arg(XDR *xdrs, gprinc_arg *objp)
2N/A{
2N/A if (!xdr_ui_4(xdrs, &objp->api_version)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_krb5_principal(xdrs, &objp->princ)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_long(xdrs, &objp->mask)) {
2N/A return FALSE;
2N/A }
2N/A
2N/A return (TRUE);
2N/A}
2N/A
2N/Abool_t
2N/Axdr_gprinc_ret(XDR *xdrs, gprinc_ret *objp)
2N/A{
2N/A if (!xdr_ui_4(xdrs, &objp->api_version)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_kadm5_ret_t(xdrs, &objp->code)) {
2N/A return (FALSE);
2N/A }
2N/A if(objp->code == KADM5_OK) {
2N/A if (!_xdr_kadm5_principal_ent_rec(xdrs, &objp->rec,
2N/A objp->api_version)) {
2N/A return (FALSE);
2N/A }
2N/A }
2N/A
2N/A return (TRUE);
2N/A}
2N/A
2N/Abool_t
2N/Axdr_cpol_arg(XDR *xdrs, cpol_arg *objp)
2N/A{
2N/A if (!xdr_ui_4(xdrs, &objp->api_version)) {
2N/A return (FALSE);
2N/A }
2N/A if (!_xdr_kadm5_policy_ent_rec(xdrs, &objp->rec,
2N/A objp->api_version)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_long(xdrs, &objp->mask)) {
2N/A return (FALSE);
2N/A }
2N/A return (TRUE);
2N/A}
2N/A
2N/Abool_t
2N/Axdr_dpol_arg(XDR *xdrs, dpol_arg *objp)
2N/A{
2N/A if (!xdr_ui_4(xdrs, &objp->api_version)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_nullstring(xdrs, &objp->name)) {
2N/A return (FALSE);
2N/A }
2N/A return (TRUE);
2N/A}
2N/A
2N/Abool_t
2N/Axdr_mpol_arg(XDR *xdrs, mpol_arg *objp)
2N/A{
2N/A if (!xdr_ui_4(xdrs, &objp->api_version)) {
2N/A return (FALSE);
2N/A }
2N/A if (!_xdr_kadm5_policy_ent_rec(xdrs, &objp->rec,
2N/A objp->api_version)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_long(xdrs, &objp->mask)) {
2N/A return (FALSE);
2N/A }
2N/A return (TRUE);
2N/A}
2N/A
2N/Abool_t
2N/Axdr_gpol_arg(XDR *xdrs, gpol_arg *objp)
2N/A{
2N/A if (!xdr_ui_4(xdrs, &objp->api_version)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_nullstring(xdrs, &objp->name)) {
2N/A return (FALSE);
2N/A }
2N/A return (TRUE);
2N/A}
2N/A
2N/Abool_t
2N/Axdr_gpol_ret(XDR *xdrs, gpol_ret *objp)
2N/A{
2N/A if (!xdr_ui_4(xdrs, &objp->api_version)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_kadm5_ret_t(xdrs, &objp->code)) {
2N/A return (FALSE);
2N/A }
2N/A if(objp->code == KADM5_OK) {
2N/A if (!_xdr_kadm5_policy_ent_rec(xdrs, &objp->rec,
2N/A objp->api_version))
2N/A return (FALSE);
2N/A }
2N/A
2N/A return (TRUE);
2N/A}
2N/A
2N/Abool_t
2N/Axdr_gpols_arg(XDR *xdrs, gpols_arg *objp)
2N/A{
2N/A if (!xdr_ui_4(xdrs, &objp->api_version)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_nullstring(xdrs, &objp->exp)) {
2N/A return (FALSE);
2N/A }
2N/A return (TRUE);
2N/A}
2N/A
2N/Abool_t
2N/Axdr_gpols_ret(XDR *xdrs, gpols_ret *objp)
2N/A{
2N/A if (!xdr_ui_4(xdrs, &objp->api_version)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_kadm5_ret_t(xdrs, &objp->code)) {
2N/A return (FALSE);
2N/A }
2N/A if (objp->code == KADM5_OK) {
2N/A if (!xdr_int(xdrs, &objp->count)) {
2N/A return (FALSE);
2N/A }
2N/A if (!xdr_array(xdrs, (caddr_t *) &objp->pols,
2N/A (unsigned int *) &objp->count, ~0,
2N/A sizeof(char *), xdr_nullstring)) {
2N/A return (FALSE);
2N/A }
2N/A }
2N/A
2N/A return (TRUE);
2N/A}
2N/A
2N/Abool_t xdr_getprivs_ret(XDR *xdrs, getprivs_ret *objp)
2N/A{
2N/A if (!xdr_ui_4(xdrs, &objp->api_version)) {
2N/A return (FALSE);
2N/A }
2N/A if (! xdr_kadm5_ret_t(xdrs, &objp->code) ||
2N/A ! xdr_long(xdrs, &objp->privs))
2N/A return FALSE;
2N/A
2N/A return TRUE;
2N/A}
2N/A
2N/Abool_t
2N/Axdr_krb5_principal(XDR *xdrs, krb5_principal *objp)
2N/A{
2N/A int ret;
2N/A char *p = NULL;
2N/A krb5_principal pr = NULL;
2N/A static krb5_context context = NULL;
2N/A
2N/A /* using a static context here is ugly, but should work
2N/A ok, and the other solutions are even uglier */
2N/A
2N/A if (!context &&
2N/A kadm5_init_krb5_context(&context))
2N/A return(FALSE);
2N/A
2N/A switch(xdrs->x_op) {
2N/A case XDR_ENCODE:
2N/A if (*objp) {
2N/A if((ret = krb5_unparse_name(context, *objp, &p)) != 0)
2N/A return FALSE;
2N/A }
2N/A if(!xdr_nullstring(xdrs, &p))
2N/A return FALSE;
2N/A if (p) free(p);
2N/A break;
2N/A case XDR_DECODE:
2N/A if(!xdr_nullstring(xdrs, &p))
2N/A return FALSE;
2N/A if (p) {
2N/A ret = krb5_parse_name(context, p, &pr);
2N/A if(ret != 0)
2N/A return FALSE;
2N/A *objp = pr;
2N/A free(p);
2N/A } else
2N/A *objp = NULL;
2N/A break;
2N/A case XDR_FREE:
2N/A if(*objp != NULL)
2N/A krb5_free_principal(context, *objp);
2N/A break;
2N/A }
2N/A return TRUE;
2N/A}
2N/A
2N/Abool_t
2N/Axdr_krb5_octet(XDR *xdrs, krb5_octet *objp)
2N/A{
2N/A if (!xdr_u_char(xdrs, objp))
2N/A return (FALSE);
2N/A return (TRUE);
2N/A}
2N/A
2N/Abool_t
2N/Axdr_krb5_enctype(XDR *xdrs, krb5_enctype *objp)
2N/A{
2N/A /*
2N/A * This used to be xdr_krb5_keytype, but keytypes and enctypes have
2N/A * been merged into only enctypes. However, randkey_principal
2N/A * already ensures that only a key of ENCTYPE_DES_CBC_CRC will be
2N/A * returned to v1 clients, and ENCTYPE_DES_CBC_CRC has the same
2N/A * value as KEYTYPE_DES used too, which is what all v1 clients
2N/A * expect. Therefore, IMHO, just encoding whatever enctype we get
2N/A * is safe.
2N/A */
2N/A
2N/A if (!xdr_u_int(xdrs, (unsigned int *) objp))
2N/A return (FALSE);
2N/A return (TRUE);
2N/A}
2N/A
2N/Abool_t
2N/Axdr_krb5_salttype(XDR *xdrs, krb5_int32 *objp)
2N/A{
2N/A if (!xdr_int(xdrs, (int32_t *) objp))
2N/A return FALSE;
2N/A return TRUE;
2N/A}
2N/A
2N/Abool_t
2N/Axdr_krb5_keyblock(XDR *xdrs, krb5_keyblock *objp)
2N/A{
2N/A /* XXX This only works because free_keyblock assumes ->contents
2N/A is allocated by malloc() */
2N/A
2N/A if(!xdr_krb5_enctype(xdrs, &objp->enctype))
2N/A return FALSE;
2N/A if(!xdr_bytes(xdrs, (char **) &objp->contents, (unsigned int *)
2N/A &objp->length, ~0))
2N/A return FALSE;
2N/A return TRUE;
2N/A}