ba7b222e36bac28710a7f43739283302b617e7f5Glenn Barry/*
ba7b222e36bac28710a7f43739283302b617e7f5Glenn Barry * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
ba7b222e36bac28710a7f43739283302b617e7f5Glenn Barry * Use is subject to license terms.
ba7b222e36bac28710a7f43739283302b617e7f5Glenn Barry */
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb/*
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb** set password functions added by Paul W. Nelson, Thursby Software Systems, Inc.
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb*/
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb#include <string.h>
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb#include "k5-int.h"
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/* #include "krb5_err.h" */
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb#include "auth_con.h"
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtbkrb5_error_code
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5int_mk_chpw_req(
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_context context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_auth_context auth_context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data *ap_req,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char *passwd,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data *packet)
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb{
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_error_code ret = 0;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_data clearpw;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_data cipherpw;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_replay_data replay;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb char *ptr;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb cipherpw.data = NULL;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if ((ret = krb5_auth_con_setflags(context, auth_context,
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb KRB5_AUTH_CONTEXT_DO_SEQUENCE)))
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb goto cleanup;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb clearpw.length = strlen(passwd);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb clearpw.data = passwd;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if ((ret = krb5_mk_priv(context, auth_context,
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb &clearpw, &cipherpw, &replay)))
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb goto cleanup;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb packet->length = 6 + ap_req->length + cipherpw.length;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb packet->data = (char *) malloc(packet->length);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if (packet->data == NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan {
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ret = ENOMEM;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ptr = packet->data;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb /* length */
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan *ptr++ = (packet->length>> 8) & 0xff;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb *ptr++ = packet->length & 0xff;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb /* version == 0x0001 big-endian */
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb *ptr++ = 0;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb *ptr++ = 1;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb /* ap_req length, big-endian */
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb *ptr++ = (ap_req->length>>8) & 0xff;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb *ptr++ = ap_req->length & 0xff;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb /* ap-req data */
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb memcpy(ptr, ap_req->data, ap_req->length);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ptr += ap_req->length;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb /* krb-priv of password */
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb memcpy(ptr, cipherpw.data, cipherpw.length);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtbcleanup:
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if(cipherpw.data != NULL) /* allocated by krb5_mk_priv */
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb free(cipherpw.data);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb return(ret);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb}
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtbkrb5_error_code
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtbkrb5int_rd_chpw_rep(krb5_context context, krb5_auth_context auth_context, krb5_data *packet, int *result_code, krb5_data *result_data)
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb{
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb char *ptr;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb int plen, vno;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_data ap_rep;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_ap_rep_enc_part *ap_rep_enc;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_error_code ret;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_data cipherresult;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_data clearresult;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error *krberror = NULL;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_replay_data replay;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_keyblock *tmp;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if (packet->length < 4)
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb /* either this, or the server is printing bad messages,
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb or the caller passed in garbage */
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb return(KRB5KRB_AP_ERR_MODIFIED);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ptr = packet->data;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb /* verify length */
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb plen = (*ptr++ & 0xff);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb plen = (plen<<8) | (*ptr++ & 0xff);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (plen != packet->length)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * MS KDCs *may* send back a KRB_ERROR. Although
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * not 100% correct via RFC3244, it's something
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * we can workaround here.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (krb5_is_krb_error(packet)) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((ret = krb5_rd_error(context, packet, &krberror)))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return(ret);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (krberror->e_data.data == NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ret = ERROR_TABLE_BASE_krb5 + (krb5_error_code) krberror->error;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_free_error(context, krberror);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return (ret);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return(KRB5KRB_AP_ERR_MODIFIED);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* Solaris Kerberos */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (krberror != NULL) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_free_error(context, krberror);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krberror = NULL;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb /* verify version number */
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb vno = (*ptr++ & 0xff);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb vno = (vno<<8) | (*ptr++ & 0xff);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if (vno != 1)
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb return(KRB5KDC_ERR_BAD_PVNO);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb /* read, check ap-rep length */
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ap_rep.length = (*ptr++ & 0xff);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ap_rep.length = (ap_rep.length<<8) | (*ptr++ & 0xff);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if (ptr + ap_rep.length >= packet->data + packet->length)
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb return(KRB5KRB_AP_ERR_MODIFIED);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if (ap_rep.length) {
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb /* verify ap_rep */
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ap_rep.data = ptr;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ptr += ap_rep.length;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb /*
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb * Save send_subkey to later smash recv_subkey.
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb */
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ret = krb5_auth_con_getsendsubkey(context, auth_context, &tmp);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if (ret)
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb return ret;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ret = krb5_rd_rep(context, auth_context, &ap_rep, &ap_rep_enc);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if (ret) {
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_free_keyblock(context, tmp);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb return(ret);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb }
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_free_ap_rep_enc_part(context, ap_rep_enc);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb /* extract and decrypt the result */
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb cipherresult.data = ptr;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb cipherresult.length = (packet->data + packet->length) - ptr;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb /*
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb * Smash recv_subkey to be send_subkey, per spec.
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb */
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ret = krb5_auth_con_setrecvsubkey(context, auth_context, tmp);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_free_keyblock(context, tmp);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if (ret)
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb return ret;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ret = krb5_rd_priv(context, auth_context, &cipherresult, &clearresult,
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb &replay);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if (ret)
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb return(ret);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb } else {
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb cipherresult.data = ptr;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb cipherresult.length = (packet->data + packet->length) - ptr;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if ((ret = krb5_rd_error(context, &cipherresult, &krberror)))
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb return(ret);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb clearresult = krberror->e_data;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb }
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if (clearresult.length < 2) {
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ret = KRB5KRB_AP_ERR_MODIFIED;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb goto cleanup;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb }
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ptr = clearresult.data;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb *result_code = (*ptr++ & 0xff);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb *result_code = (*result_code<<8) | (*ptr++ & 0xff);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if ((*result_code < KRB5_KPASSWD_SUCCESS) ||
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb (*result_code > KRB5_KPASSWD_INITIAL_FLAG_NEEDED)) {
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ret = KRB5KRB_AP_ERR_MODIFIED;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb goto cleanup;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb }
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb /* all success replies should be authenticated/encrypted */
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if ((ap_rep.length == 0) && (*result_code == KRB5_KPASSWD_SUCCESS)) {
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ret = KRB5KRB_AP_ERR_MODIFIED;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb goto cleanup;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb }
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb result_data->length = (clearresult.data + clearresult.length) - ptr;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if (result_data->length) {
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb result_data->data = (char *) malloc(result_data->length);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if (result_data->data == NULL) {
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ret = ENOMEM;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb goto cleanup;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb }
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb memcpy(result_data->data, ptr, result_data->length);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb } else {
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb result_data->data = NULL;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb }
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ret = 0;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtbcleanup:
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if (ap_rep.length) {
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_xfree(clearresult.data);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb } else {
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_free_error(context, krberror);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb }
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb return(ret);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb}
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtbkrb5_error_code KRB5_CALLCONV
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtbkrb5_chpw_result_code_string(krb5_context context, int result_code, char **code_string)
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb{
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb switch (result_code) {
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb case KRB5_KPASSWD_MALFORMED:
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb *code_string = "Malformed request error";
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb break;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb case KRB5_KPASSWD_HARDERROR:
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb *code_string = "Server error";
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb break;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb case KRB5_KPASSWD_AUTHERROR:
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb *code_string = "Authentication error";
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb break;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb case KRB5_KPASSWD_SOFTERROR:
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb *code_string = "Password change rejected";
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb break;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb default:
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb *code_string = "Password change failed";
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb break;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb }
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb return(0);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb}
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtbkrb5_error_code
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtbkrb5int_mk_setpw_req(
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_context context,
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_auth_context auth_context,
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_data *ap_req,
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_principal targprinc,
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb char *passwd,
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_data *packet )
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb{
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_error_code ret;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_data cipherpw;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_data *encoded_setpw;
ba7b222e36bac28710a7f43739283302b617e7f5Glenn Barry struct krb5_setpw_req req;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb char *ptr;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
ba7b222e36bac28710a7f43739283302b617e7f5Glenn Barry cipherpw.data = NULL;
ba7b222e36bac28710a7f43739283302b617e7f5Glenn Barry cipherpw.length = 0;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if ((ret = krb5_auth_con_setflags(context, auth_context,
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb KRB5_AUTH_CONTEXT_DO_SEQUENCE)))
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb return(ret);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
ba7b222e36bac28710a7f43739283302b617e7f5Glenn Barry req.target = targprinc;
ba7b222e36bac28710a7f43739283302b617e7f5Glenn Barry req.password.data = passwd;
ba7b222e36bac28710a7f43739283302b617e7f5Glenn Barry req.password.length = strlen(passwd);
ba7b222e36bac28710a7f43739283302b617e7f5Glenn Barry ret = encode_krb5_setpw_req(&req, &encoded_setpw);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if (ret) {
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb return ret;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb }
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if ( (ret = krb5_mk_priv(context, auth_context, encoded_setpw, &cipherpw, NULL)) != 0) {
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_free_data( context, encoded_setpw);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb return(ret);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb }
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_free_data( context, encoded_setpw);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb packet->length = 6 + ap_req->length + cipherpw.length;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb packet->data = (char *) malloc(packet->length);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if (packet->data == NULL) {
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ret = ENOMEM;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb goto cleanup;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb }
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ptr = packet->data;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb/*
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb** build the packet -
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb*/
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb/* put in the length */
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb *ptr++ = (packet->length>>8) & 0xff;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb *ptr++ = packet->length & 0xff;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb/* put in the version */
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb *ptr++ = (char)0xff;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb *ptr++ = (char)0x80;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb/* the ap_req length is big endian */
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb *ptr++ = (ap_req->length>>8) & 0xff;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb *ptr++ = ap_req->length & 0xff;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb/* put in the request data */
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb memcpy(ptr, ap_req->data, ap_req->length);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ptr += ap_req->length;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb/*
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb** put in the "private" password data -
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb*/
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb memcpy(ptr, cipherpw.data, cipherpw.length);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ret = 0;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb cleanup:
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if (cipherpw.data)
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_free_data_contents(context, &cipherpw);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if ((ret != 0) && packet->data) {
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb free( packet->data);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb packet->data = NULL;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb }
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb return ret;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb}
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtbkrb5_error_code
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtbkrb5int_rd_setpw_rep( krb5_context context, krb5_auth_context auth_context, krb5_data *packet,
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb int *result_code, krb5_data *result_data )
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb{
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb char *ptr;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb unsigned int message_length, version_number;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_data ap_rep;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_ap_rep_enc_part *ap_rep_enc;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_error_code ret;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_data cipherresult;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_data clearresult;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_keyblock *tmpkey;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb/*
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb** validate the packet length -
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb*/
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if (packet->length < 4)
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb return(KRB5KRB_AP_ERR_MODIFIED);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ptr = packet->data;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb/*
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb** see if it is an error
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb*/
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if (krb5_is_krb_error(packet)) {
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_error *krberror;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if ((ret = krb5_rd_error(context, packet, &krberror)))
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb return(ret);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if (krberror->e_data.data == NULL) {
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ret = ERROR_TABLE_BASE_krb5 + (krb5_error_code) krberror->error;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_free_error(context, krberror);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb return (ret);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb }
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb clearresult = krberror->e_data;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krberror->e_data.data = NULL; /*So we can free it later*/
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krberror->e_data.length = 0;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_free_error(context, krberror);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb } else { /* Not an error*/
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb/*
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb** validate the message length -
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb** length is big endian
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb*/
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb message_length = (((ptr[0] << 8)&0xff) | (ptr[1]&0xff));
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ptr += 2;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb/*
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb** make sure the message length and packet length agree -
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb*/
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if (message_length != packet->length)
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb return(KRB5KRB_AP_ERR_MODIFIED);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb/*
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb** get the version number -
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb*/
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb version_number = (((ptr[0] << 8)&0xff) | (ptr[1]&0xff));
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ptr += 2;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb/*
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb** make sure we support the version returned -
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb*/
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb/*
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb** set password version is 0xff80, change password version is 1
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb*/
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (version_number != 1 && version_number != 0xff80)
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb return(KRB5KDC_ERR_BAD_PVNO);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb/*
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb** now fill in ap_rep with the reply -
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb*/
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb/*
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb** get the reply length -
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb*/
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ap_rep.length = (((ptr[0] << 8)&0xff) | (ptr[1]&0xff));
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ptr += 2;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb/*
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb** validate ap_rep length agrees with the packet length -
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb*/
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if (ptr + ap_rep.length >= packet->data + packet->length)
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb return(KRB5KRB_AP_ERR_MODIFIED);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb/*
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb** if data was returned, set the ap_rep ptr -
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb*/
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if( ap_rep.length ) {
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ap_rep.data = ptr;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ptr += ap_rep.length;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb /*
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb * Save send_subkey to later smash recv_subkey.
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb */
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ret = krb5_auth_con_getsendsubkey(context, auth_context, &tmpkey);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if (ret)
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb return ret;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ret = krb5_rd_rep(context, auth_context, &ap_rep, &ap_rep_enc);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if (ret) {
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_free_keyblock(context, tmpkey);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb return(ret);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb }
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_free_ap_rep_enc_part(context, ap_rep_enc);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb/*
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb** now decrypt the result -
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb*/
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb cipherresult.data = ptr;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb cipherresult.length = (packet->data + packet->length) - ptr;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb /*
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb * Smash recv_subkey to be send_subkey, per spec.
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb */
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ret = krb5_auth_con_setrecvsubkey(context, auth_context, tmpkey);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_free_keyblock(context, tmpkey);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if (ret)
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb return ret;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ret = krb5_rd_priv(context, auth_context, &cipherresult, &clearresult,
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb NULL);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if (ret)
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb return(ret);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb } /*We got an ap_rep*/
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb else
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb return (KRB5KRB_AP_ERR_MODIFIED);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb } /*Response instead of error*/
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb/*
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb** validate the cleartext length
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb*/
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if (clearresult.length < 2) {
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ret = KRB5KRB_AP_ERR_MODIFIED;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb goto cleanup;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb }
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb/*
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb** now decode the result -
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb*/
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ptr = clearresult.data;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb *result_code = (((ptr[0] << 8)&0xff) | (ptr[1]&0xff));
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ptr += 2;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb/*
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb** result code 5 is access denied
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb*/
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if ((*result_code < KRB5_KPASSWD_SUCCESS) || (*result_code > 5))
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb {
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ret = KRB5KRB_AP_ERR_MODIFIED;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb goto cleanup;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb }
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb/*
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb** all success replies should be authenticated/encrypted
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb*/
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if( (ap_rep.length == 0) && (*result_code == KRB5_KPASSWD_SUCCESS) )
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb {
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ret = KRB5KRB_AP_ERR_MODIFIED;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb goto cleanup;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb }
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if (result_data) {
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb result_data->length = (clearresult.data + clearresult.length) - ptr;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if (result_data->length)
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb {
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb result_data->data = (char *) malloc(result_data->length);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if (result_data->data)
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb memcpy(result_data->data, ptr, result_data->length);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb }
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb else
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb result_data->data = NULL;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb }
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb ret = 0;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb cleanup:
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_free_data_contents(context, &clearresult);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb return(ret);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb}
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtbkrb5_error_code
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtbkrb5int_setpw_result_code_string( krb5_context context, int result_code, const char **code_string )
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb{
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb switch (result_code)
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb {
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb case KRB5_KPASSWD_MALFORMED:
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb *code_string = "Malformed request error";
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb break;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb case KRB5_KPASSWD_HARDERROR:
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb *code_string = "Server error";
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb break;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb case KRB5_KPASSWD_AUTHERROR:
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb *code_string = "Authentication error";
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb break;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb case KRB5_KPASSWD_SOFTERROR:
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb *code_string = "Password change rejected";
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb break;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb case 5: /* access denied */
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb *code_string = "Access denied";
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb break;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb case 6: /* bad version */
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb *code_string = "Wrong protocol version";
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb break;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb case 7: /* initial flag is needed */
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb *code_string = "Initial password required";
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb break;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb case 0:
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb *code_string = "Success";
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb default:
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb *code_string = "Password change failed";
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb break;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb }
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb return(0);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb}
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb