/* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING * * Openvision retains the copyright to derivative works of * this source code. Do *NOT* create a derivative of this * source code before consulting with your legal department. * Do *NOT* integrate *ANY* of this source code into another * product before consulting with your legal department. * * For further information, read the top-level Openvision * copyright which is contained in the top-level MIT Kerberos * copyright. * * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING * */ /* * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved */ #include #include #include #include #include #include #include static bool_t _xdr_kadm5_principal_ent_rec(XDR *xdrs, kadm5_principal_ent_rec *objp, int v); bool_t xdr_krb5_salttype(XDR *xdrs, krb5_int32 *objp); /* SUNWresync121 XXX */ /* * Function: xdr_ui_4 * * Purpose: XDR function which serves as a wrapper for xdr_u_int, * to prevent compiler warnings about type clashes between u_int32 * and krb5_ui_4. */ bool_t xdr_ui_4(XDR *xdrs, krb5_ui_4 *objp) { /* Assumes that krb5_ui_4 and u_int32 are both four bytes long. This should not be a harmful assumption. */ return xdr_u_int(xdrs, (uint32_t *) objp); } /* * Function: xdr_nullstring * * Purpose: XDR function for "strings" that are either NULL-terminated * or NULL. */ bool_t xdr_nullstring(XDR *xdrs, char **objp) { u_int size; if (xdrs->x_op == XDR_ENCODE) { if (*objp == NULL) size = 0; else size = strlen(*objp) + 1; } if (! xdr_u_int(xdrs, &size)) { return FALSE; } switch (xdrs->x_op) { case XDR_DECODE: if (size == 0) { *objp = NULL; return TRUE; } else if (*objp == NULL) { *objp = (char *) mem_alloc(size); if (*objp == NULL) { errno = ENOMEM; return FALSE; } } return (xdr_opaque(xdrs, *objp, size)); case XDR_ENCODE: if (size != 0) return (xdr_opaque(xdrs, *objp, size)); return TRUE; case XDR_FREE: if (*objp != NULL) mem_free(*objp, size); *objp = NULL; return TRUE; } return FALSE; } /* * Function: xdr_nulltype * * Purpose: XDR function for arbitrary pointer types that are either * NULL or contain data. */ bool_t xdr_nulltype(XDR *xdrs, void **objp, xdrproc_t proc) { bool_t null; switch (xdrs->x_op) { case XDR_DECODE: if (!xdr_bool(xdrs, &null)) return FALSE; if (null) { *objp = NULL; return TRUE; } return (*proc)(xdrs, objp); case XDR_ENCODE: if (*objp == NULL) null = TRUE; else null = FALSE; if (!xdr_bool(xdrs, &null)) return FALSE; if (null == FALSE) return (*proc)(xdrs, objp); return TRUE; case XDR_FREE: if (*objp) return (*proc)(xdrs, objp); return TRUE; } return FALSE; } bool_t xdr_krb5_timestamp(XDR *xdrs, krb5_timestamp *objp) { /* This assumes that int32 and krb5_timestamp are the same size. This shouldn't be a problem, since we've got a unit test which checks for this. */ if (!xdr_int(xdrs, (int32_t *) objp)) { return (FALSE); } return (TRUE); } bool_t xdr_krb5_kvno(XDR *xdrs, krb5_kvno *objp) { unsigned char tmp; tmp = '\0'; /* for purify, else xdr_u_char performs a umr */ if (xdrs->x_op == XDR_ENCODE) tmp = (unsigned char) *objp; if (!xdr_u_char(xdrs, &tmp)) return (FALSE); if (xdrs->x_op == XDR_DECODE) *objp = (krb5_kvno) tmp; return (TRUE); } bool_t xdr_krb5_deltat(XDR *xdrs, krb5_deltat *objp) { /* This assumes that int32 and krb5_deltat are the same size. This shouldn't be a problem, since we've got a unit test which checks for this. */ if (!xdr_int(xdrs, (int32_t *) objp)) { return (FALSE); } return (TRUE); } bool_t xdr_krb5_flags(XDR *xdrs, krb5_flags *objp) { /* This assumes that int32 and krb5_flags are the same size. This shouldn't be a problem, since we've got a unit test which checks for this. */ if (!xdr_int(xdrs, (int32_t *) objp)) { return (FALSE); } return (TRUE); } bool_t xdr_krb5_ui_4(XDR *xdrs, krb5_ui_4 *objp) { if (!xdr_u_int(xdrs, (uint32_t *) objp)) { return (FALSE); } return (TRUE); } bool_t xdr_krb5_int16(XDR *xdrs, krb5_int16 *objp) { int tmp; tmp = (int) *objp; if (!xdr_int(xdrs, &tmp)) return(FALSE); *objp = (krb5_int16) tmp; return(TRUE); } /* * Function: xdr_krb5_ui_2 * * Purpose: XDR function which serves as a wrapper for xdr_u_int, * to prevent compiler warnings about type clashes between u_int * and krb5_ui_2. */ bool_t xdr_krb5_ui_2(XDR *xdrs, krb5_ui_2 *objp) { unsigned int tmp; tmp = (unsigned int) *objp; if (!xdr_u_int(xdrs, &tmp)) return(FALSE); *objp = (krb5_ui_2) tmp; return(TRUE); } bool_t xdr_krb5_key_data_nocontents(XDR *xdrs, krb5_key_data *objp) { /* * Note that this function intentionally DOES NOT tranfer key * length or contents! xdr_krb5_key_data in adb_xdr.c does, but * that is only for use within the server-side library. */ unsigned int tmp; if (xdrs->x_op == XDR_DECODE) memset((char *) objp, 0, sizeof(krb5_key_data)); if (!xdr_krb5_int16(xdrs, &objp->key_data_ver)) { return (FALSE); } if (!xdr_krb5_int16(xdrs, &objp->key_data_kvno)) { return (FALSE); } if (!xdr_krb5_int16(xdrs, &objp->key_data_type[0])) { return (FALSE); } if (objp->key_data_ver > 1) { if (!xdr_krb5_int16(xdrs, &objp->key_data_type[1])) { return (FALSE); } } /* * kadm5_get_principal on the server side allocates and returns * key contents when asked. Even though this function refuses to * transmit that data, it still has to *free* the data at the * appropriate time to avoid a memory leak. */ if (xdrs->x_op == XDR_FREE) { tmp = (unsigned int) objp->key_data_length[0]; if (!xdr_bytes(xdrs, (char **) &objp->key_data_contents[0], &tmp, ~0)) return FALSE; tmp = (unsigned int) objp->key_data_length[1]; if (!xdr_bytes(xdrs, (char **) &objp->key_data_contents[1], &tmp, ~0)) return FALSE; } return (TRUE); } bool_t xdr_krb5_key_salt_tuple(XDR *xdrs, krb5_key_salt_tuple *objp) { if (!xdr_krb5_enctype(xdrs, &objp->ks_enctype)) return FALSE; if (!xdr_krb5_salttype(xdrs, &objp->ks_salttype)) return FALSE; return TRUE; } bool_t xdr_krb5_tl_data(XDR *xdrs, krb5_tl_data **tl_data_head) { krb5_tl_data *tl, *tl2; bool_t more; unsigned int len; switch (xdrs->x_op) { case XDR_FREE: tl = tl2 = *tl_data_head; while (tl) { tl2 = tl->tl_data_next; free(tl->tl_data_contents); free(tl); tl = tl2; } break; case XDR_ENCODE: tl = *tl_data_head; while (1) { more = (tl != NULL); if (!xdr_bool(xdrs, &more)) return FALSE; if (tl == NULL) break; if (!xdr_krb5_int16(xdrs, &tl->tl_data_type)) return FALSE; len = tl->tl_data_length; if (!xdr_bytes(xdrs, (char **) &tl->tl_data_contents, &len, ~0)) return FALSE; tl = tl->tl_data_next; } break; case XDR_DECODE: tl = NULL; while (1) { if (!xdr_bool(xdrs, &more)) return FALSE; if (more == FALSE) break; tl2 = (krb5_tl_data *) malloc(sizeof(krb5_tl_data)); if (tl2 == NULL) return FALSE; memset((char *) tl2, 0, sizeof(krb5_tl_data)); if (!xdr_krb5_int16(xdrs, &tl2->tl_data_type)) return FALSE; if (!xdr_bytes(xdrs, (char **)&tl2->tl_data_contents, &len, ~0)) return FALSE; tl2->tl_data_length = len; tl2->tl_data_next = tl; tl = tl2; } *tl_data_head = tl; break; } return TRUE; } bool_t xdr_kadm5_ret_t(XDR *xdrs, kadm5_ret_t *objp) { uint32_t tmp; if (xdrs->x_op == XDR_ENCODE) tmp = (uint32_t) *objp; if (!xdr_u_int(xdrs, &tmp)) return (FALSE); if (xdrs->x_op == XDR_DECODE) *objp = (kadm5_ret_t) tmp; return (TRUE); } bool_t xdr_kadm5_principal_ent_rec_v1(XDR *xdrs, kadm5_principal_ent_rec *objp) { return _xdr_kadm5_principal_ent_rec(xdrs, objp, KADM5_API_VERSION_1); } bool_t xdr_kadm5_principal_ent_rec(XDR *xdrs, kadm5_principal_ent_rec *objp) { return _xdr_kadm5_principal_ent_rec(xdrs, objp, KADM5_API_VERSION_2); } static bool_t _xdr_kadm5_principal_ent_rec(XDR *xdrs, kadm5_principal_ent_rec *objp, int v) { unsigned int n; if (!xdr_krb5_principal(xdrs, &objp->principal)) { return (FALSE); } if (!xdr_krb5_timestamp(xdrs, &objp->princ_expire_time)) { return (FALSE); } if (!xdr_krb5_timestamp(xdrs, &objp->last_pwd_change)) { return (FALSE); } if (!xdr_krb5_timestamp(xdrs, &objp->pw_expiration)) { return (FALSE); } if (!xdr_krb5_deltat(xdrs, &objp->max_life)) { return (FALSE); } if (v == KADM5_API_VERSION_1) { if (!xdr_krb5_principal(xdrs, &objp->mod_name)) { return (FALSE); } } else { if (!xdr_nulltype(xdrs, (void **) &objp->mod_name, xdr_krb5_principal)) { return (FALSE); } } if (!xdr_krb5_timestamp(xdrs, &objp->mod_date)) { return (FALSE); } if (!xdr_krb5_flags(xdrs, &objp->attributes)) { return (FALSE); } if (!xdr_krb5_kvno(xdrs, &objp->kvno)) { return (FALSE); } if (!xdr_krb5_kvno(xdrs, &objp->mkvno)) { return (FALSE); } if (!xdr_nullstring(xdrs, &objp->policy)) { return (FALSE); } if (!xdr_long(xdrs, &objp->aux_attributes)) { return (FALSE); } if (v != KADM5_API_VERSION_1) { if (!xdr_krb5_deltat(xdrs, &objp->max_renewable_life)) { return (FALSE); } if (!xdr_krb5_timestamp(xdrs, &objp->last_success)) { return (FALSE); } if (!xdr_krb5_timestamp(xdrs, &objp->last_failed)) { return (FALSE); } if (!xdr_krb5_kvno(xdrs, &objp->fail_auth_count)) { return (FALSE); } if (!xdr_krb5_int16(xdrs, &objp->n_key_data)) { return (FALSE); } if (!xdr_krb5_int16(xdrs, &objp->n_tl_data)) { return (FALSE); } if (!xdr_nulltype(xdrs, (void **) &objp->tl_data, xdr_krb5_tl_data)) { return FALSE; } n = objp->n_key_data; if (!xdr_array(xdrs, (caddr_t *) &objp->key_data, &n, ~0, sizeof(krb5_key_data), xdr_krb5_key_data_nocontents)) { return (FALSE); } } return (TRUE); } bool_t xdr_kadm5_policy_ent_rec(XDR *xdrs, kadm5_policy_ent_rec *objp) { if (!xdr_nullstring(xdrs, &objp->policy)) { return (FALSE); } /* these all used to be u_int32, but it's stupid for sized types to be exposed at the api, and they're the same as longs on the wire. */ if (!xdr_long(xdrs, &objp->pw_min_life)) { return (FALSE); } if (!xdr_long(xdrs, &objp->pw_max_life)) { return (FALSE); } if (!xdr_long(xdrs, &objp->pw_min_length)) { return (FALSE); } if (!xdr_long(xdrs, &objp->pw_min_classes)) { return (FALSE); } if (!xdr_long(xdrs, &objp->pw_history_num)) { return (FALSE); } if (!xdr_long(xdrs, &objp->policy_refcnt)) { return (FALSE); } return (TRUE); } bool_t xdr_cprinc_arg(XDR *xdrs, cprinc_arg *objp) { if (!xdr_ui_4(xdrs, &objp->api_version)) { return (FALSE); } if (objp->api_version == KADM5_API_VERSION_1) { if (!xdr_kadm5_principal_ent_rec_v1(xdrs, &objp->rec)) { return (FALSE); } } else { if (!xdr_kadm5_principal_ent_rec(xdrs, &objp->rec)) { return (FALSE); } } if (!xdr_long(xdrs, &objp->mask)) { return (FALSE); } if (!xdr_nullstring(xdrs, &objp->passwd)) { return (FALSE); } return (TRUE); } bool_t xdr_cprinc3_arg(XDR *xdrs, cprinc3_arg *objp) { if (!xdr_ui_4(xdrs, &objp->api_version)) { return (FALSE); } if (objp->api_version == KADM5_API_VERSION_1) { if (!xdr_kadm5_principal_ent_rec_v1(xdrs, &objp->rec)) { return (FALSE); } } else { if (!xdr_kadm5_principal_ent_rec(xdrs, &objp->rec)) { return (FALSE); } } if (!xdr_long(xdrs, &objp->mask)) { return (FALSE); } if (!xdr_array(xdrs, (caddr_t *)&objp->ks_tuple, (unsigned int *)&objp->n_ks_tuple, ~0, sizeof(krb5_key_salt_tuple), xdr_krb5_key_salt_tuple)) { return (FALSE); } if (!xdr_nullstring(xdrs, &objp->passwd)) { return (FALSE); } return (TRUE); } bool_t xdr_generic_ret(XDR *xdrs, generic_ret *objp) { if (!xdr_ui_4(xdrs, &objp->api_version)) { return (FALSE); } if (!xdr_kadm5_ret_t(xdrs, &objp->code)) { return (FALSE); } return(TRUE); } bool_t xdr_dprinc_arg(XDR *xdrs, dprinc_arg *objp) { if (!xdr_ui_4(xdrs, &objp->api_version)) { return (FALSE); } if (!xdr_krb5_principal(xdrs, &objp->princ)) { return (FALSE); } return (TRUE); } bool_t xdr_mprinc_arg(XDR *xdrs, mprinc_arg *objp) { if (!xdr_ui_4(xdrs, &objp->api_version)) { return (FALSE); } if (objp->api_version == KADM5_API_VERSION_1) { if (!xdr_kadm5_principal_ent_rec_v1(xdrs, &objp->rec)) { return (FALSE); } } else { if (!xdr_kadm5_principal_ent_rec(xdrs, &objp->rec)) { return (FALSE); } } if (!xdr_long(xdrs, &objp->mask)) { return (FALSE); } return (TRUE); } bool_t xdr_rprinc_arg(XDR *xdrs, rprinc_arg *objp) { if (!xdr_ui_4(xdrs, &objp->api_version)) { return (FALSE); } if (!xdr_krb5_principal(xdrs, &objp->src)) { return (FALSE); } if (!xdr_krb5_principal(xdrs, &objp->dest)) { return (FALSE); } return (TRUE); } bool_t xdr_gprincs_arg(XDR *xdrs, gprincs_arg *objp) { if (!xdr_ui_4(xdrs, &objp->api_version)) { return (FALSE); } if (!xdr_nullstring(xdrs, &objp->exp)) { return (FALSE); } return (TRUE); } bool_t xdr_gprincs_ret(XDR *xdrs, gprincs_ret *objp) { if (!xdr_ui_4(xdrs, &objp->api_version)) { return (FALSE); } if (!xdr_kadm5_ret_t(xdrs, &objp->code)) { return (FALSE); } if (objp->code == KADM5_OK) { if (!xdr_int(xdrs, &objp->count)) { return (FALSE); } if (!xdr_array(xdrs, (caddr_t *) &objp->princs, (unsigned int *) &objp->count, ~0, sizeof(char *), xdr_nullstring)) { return (FALSE); } } return (TRUE); } bool_t xdr_chpass_arg(XDR *xdrs, chpass_arg *objp) { if (!xdr_ui_4(xdrs, &objp->api_version)) { return (FALSE); } if (!xdr_krb5_principal(xdrs, &objp->princ)) { return (FALSE); } if (!xdr_nullstring(xdrs, &objp->pass)) { return (FALSE); } return (TRUE); } bool_t xdr_chpass3_arg(XDR *xdrs, chpass3_arg *objp) { if (!xdr_ui_4(xdrs, &objp->api_version)) { return (FALSE); } if (!xdr_krb5_principal(xdrs, &objp->princ)) { return (FALSE); } if (!xdr_bool(xdrs, (bool_t *) &objp->keepold)) { /* SUNWresync121 XXX */ return (FALSE); } if (!xdr_array(xdrs, (caddr_t *)&objp->ks_tuple, (unsigned int*)&objp->n_ks_tuple, ~0, sizeof(krb5_key_salt_tuple), xdr_krb5_key_salt_tuple)) { return (FALSE); } if (!xdr_nullstring(xdrs, &objp->pass)) { return (FALSE); } return (TRUE); } bool_t xdr_setv4key_arg(XDR *xdrs, setv4key_arg *objp) { unsigned int n_keys = 1; if (!xdr_ui_4(xdrs, &objp->api_version)) { return (FALSE); } if (!xdr_krb5_principal(xdrs, &objp->princ)) { return (FALSE); } if (!xdr_array(xdrs, (caddr_t *) &objp->keyblock, &n_keys, ~0, sizeof(krb5_keyblock), xdr_krb5_keyblock)) { return (FALSE); } return (TRUE); } bool_t xdr_setkey_arg(XDR *xdrs, setkey_arg *objp) { if (!xdr_ui_4(xdrs, &objp->api_version)) { return (FALSE); } if (!xdr_krb5_principal(xdrs, &objp->princ)) { return (FALSE); } if (!xdr_array(xdrs, (caddr_t *) &objp->keyblocks, (unsigned int *) &objp->n_keys, ~0, sizeof(krb5_keyblock), xdr_krb5_keyblock)) { return (FALSE); } return (TRUE); } bool_t xdr_setkey3_arg(XDR *xdrs, setkey3_arg *objp) { if (!xdr_ui_4(xdrs, &objp->api_version)) { return (FALSE); } if (!xdr_krb5_principal(xdrs, &objp->princ)) { return (FALSE); } if (!xdr_bool(xdrs, (bool_t *) &objp->keepold)) { /* SUNWresync121 XXX */ return (FALSE); } if (!xdr_array(xdrs, (caddr_t *) &objp->ks_tuple, (unsigned int *) &objp->n_ks_tuple, ~0, sizeof(krb5_key_salt_tuple), xdr_krb5_key_salt_tuple)) { return (FALSE); } if (!xdr_array(xdrs, (caddr_t *) &objp->keyblocks, (unsigned int *) &objp->n_keys, ~0, sizeof(krb5_keyblock), xdr_krb5_keyblock)) { return (FALSE); } return (TRUE); } bool_t xdr_chrand_arg(XDR *xdrs, chrand_arg *objp) { if (!xdr_ui_4(xdrs, &objp->api_version)) { return (FALSE); } if (!xdr_krb5_principal(xdrs, &objp->princ)) { return (FALSE); } return (TRUE); } bool_t xdr_chrand3_arg(XDR *xdrs, chrand3_arg *objp) { if (!xdr_ui_4(xdrs, &objp->api_version)) { return (FALSE); } if (!xdr_krb5_principal(xdrs, &objp->princ)) { return (FALSE); } if (!xdr_bool(xdrs, (bool_t *) &objp->keepold)) { /* SUNWresync121 XXX */ return (FALSE); } if (!xdr_array(xdrs, (caddr_t *)&objp->ks_tuple, (unsigned int*)&objp->n_ks_tuple, ~0, sizeof(krb5_key_salt_tuple), xdr_krb5_key_salt_tuple)) { return (FALSE); } return (TRUE); } bool_t xdr_chrand_ret(XDR *xdrs, chrand_ret *objp) { if (!xdr_ui_4(xdrs, &objp->api_version)) { return (FALSE); } if (!xdr_kadm5_ret_t(xdrs, &objp->code)) { return (FALSE); } if (objp->api_version == KADM5_API_VERSION_1) { if(objp->code == KADM5_OK) { if (!xdr_krb5_keyblock(xdrs, &objp->key)) { return (FALSE); } } } else { if (objp->code == KADM5_OK) { if (!xdr_array(xdrs, (char **)&objp->keys, (unsigned int *)&objp->n_keys, ~0, sizeof(krb5_keyblock), xdr_krb5_keyblock)) return FALSE; } } return (TRUE); } bool_t xdr_gprinc_arg(XDR *xdrs, gprinc_arg *objp) { if (!xdr_ui_4(xdrs, &objp->api_version)) { return (FALSE); } if (!xdr_krb5_principal(xdrs, &objp->princ)) { return (FALSE); } if ((objp->api_version > KADM5_API_VERSION_1) && !xdr_long(xdrs, &objp->mask)) { return FALSE; } return (TRUE); } bool_t xdr_gprinc_ret(XDR *xdrs, gprinc_ret *objp) { if (!xdr_ui_4(xdrs, &objp->api_version)) { return (FALSE); } if (!xdr_kadm5_ret_t(xdrs, &objp->code)) { return (FALSE); } if(objp->code == KADM5_OK) { if (objp->api_version == KADM5_API_VERSION_1) { if (!xdr_kadm5_principal_ent_rec_v1(xdrs, &objp->rec)) { return (FALSE); } } else { if (!xdr_kadm5_principal_ent_rec(xdrs, &objp->rec)) { return (FALSE); } } } return (TRUE); } bool_t xdr_cpol_arg(XDR *xdrs, cpol_arg *objp) { if (!xdr_ui_4(xdrs, &objp->api_version)) { return (FALSE); } if (!xdr_kadm5_policy_ent_rec(xdrs, &objp->rec)) { return (FALSE); } if (!xdr_long(xdrs, &objp->mask)) { return (FALSE); } return (TRUE); } bool_t xdr_dpol_arg(XDR *xdrs, dpol_arg *objp) { if (!xdr_ui_4(xdrs, &objp->api_version)) { return (FALSE); } if (!xdr_nullstring(xdrs, &objp->name)) { return (FALSE); } return (TRUE); } bool_t xdr_mpol_arg(XDR *xdrs, mpol_arg *objp) { if (!xdr_ui_4(xdrs, &objp->api_version)) { return (FALSE); } if (!xdr_kadm5_policy_ent_rec(xdrs, &objp->rec)) { return (FALSE); } if (!xdr_long(xdrs, &objp->mask)) { return (FALSE); } return (TRUE); } bool_t xdr_gpol_arg(XDR *xdrs, gpol_arg *objp) { if (!xdr_ui_4(xdrs, &objp->api_version)) { return (FALSE); } if (!xdr_nullstring(xdrs, &objp->name)) { return (FALSE); } return (TRUE); } bool_t xdr_gpol_ret(XDR *xdrs, gpol_ret *objp) { if (!xdr_ui_4(xdrs, &objp->api_version)) { return (FALSE); } if (!xdr_kadm5_ret_t(xdrs, &objp->code)) { return (FALSE); } if(objp->code == KADM5_OK) { if (!xdr_kadm5_policy_ent_rec(xdrs, &objp->rec)) return (FALSE); } return (TRUE); } bool_t xdr_gpols_arg(XDR *xdrs, gpols_arg *objp) { if (!xdr_ui_4(xdrs, &objp->api_version)) { return (FALSE); } if (!xdr_nullstring(xdrs, &objp->exp)) { return (FALSE); } return (TRUE); } bool_t xdr_gpols_ret(XDR *xdrs, gpols_ret *objp) { if (!xdr_ui_4(xdrs, &objp->api_version)) { return (FALSE); } if (!xdr_kadm5_ret_t(xdrs, &objp->code)) { return (FALSE); } if (objp->code == KADM5_OK) { if (!xdr_int(xdrs, &objp->count)) { return (FALSE); } if (!xdr_array(xdrs, (caddr_t *) &objp->pols, (unsigned int *) &objp->count, ~0, sizeof(char *), xdr_nullstring)) { return (FALSE); } } return (TRUE); } bool_t xdr_getprivs_ret(XDR *xdrs, getprivs_ret *objp) { if (!xdr_ui_4(xdrs, &objp->api_version)) { return (FALSE); } if (! xdr_kadm5_ret_t(xdrs, &objp->code) || ! xdr_long(xdrs, &objp->privs)) return FALSE; return TRUE; } bool_t xdr_krb5_principal(XDR *xdrs, krb5_principal *objp) { int ret; char *p = NULL; krb5_principal pr = NULL; static krb5_context context = NULL; /* using a static context here is ugly, but should work ok, and the other solutions are even uglier */ if (!context && kadm5_init_krb5_context(&context)) return(FALSE); switch(xdrs->x_op) { case XDR_ENCODE: if (*objp) { if((ret = krb5_unparse_name(context, *objp, &p)) != 0) return FALSE; } if(!xdr_nullstring(xdrs, &p)) return FALSE; if (p) free(p); break; case XDR_DECODE: if(!xdr_nullstring(xdrs, &p)) return FALSE; if (p) { ret = krb5_parse_name(context, p, &pr); if(ret != 0) return FALSE; *objp = pr; free(p); } else *objp = NULL; break; case XDR_FREE: if(*objp != NULL) krb5_free_principal(context, *objp); break; } return TRUE; } bool_t xdr_krb5_octet(XDR *xdrs, krb5_octet *objp) { if (!xdr_u_char(xdrs, objp)) return (FALSE); return (TRUE); } bool_t xdr_krb5_enctype(XDR *xdrs, krb5_enctype *objp) { /* * This used to be xdr_krb5_keytype, but keytypes and enctypes have * been merged into only enctypes. However, randkey_principal * already ensures that only a key of ENCTYPE_DES_CBC_CRC will be * returned to v1 clients, and ENCTYPE_DES_CBC_CRC has the same * value as KEYTYPE_DES used too, which is what all v1 clients * expect. Therefore, IMHO, just encoding whatever enctype we get * is safe. */ if (!xdr_u_int(xdrs, (unsigned int *) objp)) return (FALSE); return (TRUE); } bool_t xdr_krb5_salttype(XDR *xdrs, krb5_int32 *objp) { if (!xdr_int(xdrs, (int32_t *) objp)) return FALSE; return TRUE; } bool_t xdr_krb5_keyblock(XDR *xdrs, krb5_keyblock *objp) { /* XXX This only works because free_keyblock assumes ->contents is allocated by malloc() */ if(!xdr_krb5_enctype(xdrs, &objp->enctype)) return FALSE; if(!xdr_bytes(xdrs, (char **) &objp->contents, (unsigned int *) &objp->length, ~0)) return FALSE; return TRUE; }