if(authent.length >= MAX_KTXT_LEN) { krb5_warnx(context, "received bad rlen (%lu)", (unsigned long)rlen); make_you_loose_packet (KADM_LENGTH_ERROR, reply); return; }
decode_packet(krb5_context context,	      krb5_keytab keytab,	      struct sockaddr_in *admin_addr,	      struct sockaddr_in *client_addr,	      krb5_data message,	      krb5_data *reply){    int ret;    KTEXT_ST authent;    AUTH_DAT ad;    MSG_DAT msg_dat;    off_t off = 0;    unsigned long rlen;    char sname[] = "changepw", sinst[] = "kerberos";    unsigned long checksum;    des_key_schedule schedule;    char *msg = message.data;    void *kadm_handle;    krb5_principal client;    char *client_str;    krb5_keytab_entry entry;        if(message.length < KADM_VERSIZE       || strncmp(msg, KADM_VERSTR, KADM_VERSIZE) != 0) {	make_you_loose_packet (KADM_BAD_VER, reply);	return;    }    off = KADM_VERSIZE;    off += _krb5_get_int(msg + off, &rlen, 4);    memset(&authent, 0, sizeof(authent));    authent.length = message.length - rlen - KADM_VERSIZE - 4;    memcpy(authent.dat, (char*)msg + off, authent.length);    off += authent.length;        {	krb5_principal principal;	krb5_keyblock *key;	ret = krb5_make_principal(context, &principal, NULL, 				  "changepw", "kerberos", NULL);	if (ret) {	    krb5_warn (context, ret, "krb5_make_principal");	    make_you_loose_packet (KADM_NOMEM, reply);	    return;	}	ret = krb5_kt_get_entry (context, keytab, principal, 0,				 ETYPE_DES_CBC_MD5, &entry);	krb5_kt_close (context, keytab);	if (ret) {	    krb5_free_principal(context, principal);	    make_you_loose_packet (KADM_NO_AUTH, reply);	    return;	}	ret = krb5_copy_keyblock (context, &entry.keyblock,& key);	krb5_kt_free_entry(context, &entry);	krb5_free_principal(context, principal);	if(ret) {	    if(ret == KRB5_KT_NOTFOUND)		make_you_loose_packet(KADM_NO_AUTH, reply);	    else		/* XXX */		make_you_loose_packet(KADM_NO_AUTH, reply);	    krb5_warn(context, ret, "krb5_kt_read_service_key");	    return;	}		if(key->keyvalue.length != 8)	    krb5_abortx(context, "key has wrong length (%lu)", 			(unsigned long)key->keyvalue.length);	krb_set_key(key->keyvalue.data, 0);	krb5_free_keyblock(context, key);    }        ret = krb_rd_req(&authent, sname, sinst, 		     client_addr->sin_addr.s_addr, &ad, NULL);    if(ret) {	make_you_loose_packet(krb_err_base + ret, reply);	krb5_warnx(context, "krb_rd_req: %d", ret);	return;    }    ret = krb5_425_conv_principal(context, ad.pname, ad.pinst, ad.prealm,				  &client);    if (ret) {	krb5_warnx (context, "krb5_425_conv_principal: %d", ret);	make_you_loose_packet (KADM_NOMEM, reply);	return;    }    krb5_unparse_name(context, client, &client_str);    ret = kadm5_init_with_password_ctx(context, 				       client_str, 				       NULL,				       KADM5_ADMIN_SERVICE,				       NULL, 0, 0, 				       &kadm_handle);    if (ret) {	krb5_warn (context, ret, "kadm5_init_with_password_ctx");	make_you_loose_packet (KADM_NOMEM, reply);	goto out;    }        checksum = des_quad_cksum((void *)(msg + off), NULL, rlen, 0, &ad.session);    if(checksum != ad.checksum) {	krb5_warnx(context, "decode_packet: bad checksum");	make_you_loose_packet (KADM_BAD_CHK, reply);	goto out;    }    des_set_key(&ad.session, schedule);    ret = krb_rd_priv(msg + off, rlen, schedule, &ad.session, 		      client_addr, admin_addr, &msg_dat);    if (ret) {	make_you_loose_packet (krb_err_base + ret, reply);	krb5_warnx(context, "krb_rd_priv: %d", ret);	goto out;    }    {	krb5_data d, r;	int retval;	d.data   = msg_dat.app_data;	d.length = msg_dat.app_length;		retval = dispatch(context, kadm_handle,			  client, client_str, d, &r);	krb5_data_alloc(reply, r.length + 26);	reply->length = krb_mk_priv(r.data, reply->data, r.length, 				    schedule, &ad.session, 				    admin_addr, client_addr);	if((ssize_t)reply->length < 0) {	    make_you_loose_packet(KADM_NO_ENCRYPT, reply);	    goto out;	}    }out:    krb5_free_principal(context, client);    free(client_str);}