10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb/*
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb * lib/krb5/os/changepw.c
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb *
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb * Copyright 1990,1999,2001 by the Massachusetts Institute of Technology.
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb * All Rights Reserved.
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb *
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb * Export of this software from the United States of America may
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb * require a specific license from the United States Government.
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb * It is the responsibility of any person or organization contemplating
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb * export to obtain such a license before exporting.
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb *
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb * distribute this software and its documentation for any purpose and
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb * without fee is hereby granted, provided that the above copyright
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb * notice appear in all copies and that both that copyright notice and
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb * this permission notice appear in supporting documentation, and that
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb * the name of M.I.T. not be used in advertising or publicity pertaining
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb * to distribution of the software without specific, written prior
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb * permission. Furthermore if you modify this software you must label
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb * your software as modified software and not distribute it in such a
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb * fashion that it might be confused with the original M.I.T. software.
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb * M.I.T. makes no representations about the suitability of
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb * this software for any purpose. It is provided "as is" without express
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb * or implied warranty.
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb *
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb */
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb/*
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb * krb5_set_password - Implements set password per RFC 3244
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb * Added by Paul W. Nelson, Thursby Software Systems, Inc.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Modified by Todd Stecher, Isilon Systems, to use krb1.4 socket infrastructure
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb */
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb#include "fake-addrinfo.h"
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb#include "k5-int.h"
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb#include "os-proto.h"
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan#include "cm.h"
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb#include <stdio.h>
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb#include <errno.h>
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb#ifndef GETSOCKNAME_ARG3_TYPE
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb#define GETSOCKNAME_ARG3_TYPE int
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb#endif
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstruct sendto_callback_context {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_context context;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_auth_context auth_context;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_principal set_password_for;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char *newpw;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data ap_req;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan};
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb/*
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb * Wrapper function for the two backends
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb */
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtbstatic krb5_error_code
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtbkrb5_locate_kpasswd(krb5_context context, const krb5_data *realm,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct addrlist *addrlist, krb5_boolean useTcp)
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb{
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_error_code code;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int sockType = (useTcp ? SOCK_STREAM : SOCK_DGRAM);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan code = krb5int_locate_server (context, realm, addrlist,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan locate_service_kpasswd, sockType, 0);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if (code == KRB5_REALM_CANT_RESOLVE || code == KRB5_REALM_UNKNOWN) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan code = krb5int_locate_server (context, realm, addrlist,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan locate_service_kadmin, SOCK_STREAM, 0);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if (!code) {
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb /* Success with admin_server but now we need to change the
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan port number to use DEFAULT_KPASSWD_PORT and the socktype. */
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb int i;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan for (i=0; i<addrlist->naddrs; i++) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct addrinfo *a = addrlist->addrs[i].ai;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if (a->ai_family == AF_INET)
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb sa2sin (a->ai_addr)->sin_port = htons(DEFAULT_KPASSWD_PORT);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (sockType != SOCK_STREAM)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan a->ai_socktype = sockType;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb }
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb }
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb }
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb return (code);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb}
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/**
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * This routine is used for a callback in sendto_kdc.c code. Simply
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * put, we need the client addr to build the krb_priv portion of the
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * password request.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic void kpasswd_sendto_msg_cleanup (void* callback_context, krb5_data* message)
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct sendto_callback_context *ctx = callback_context;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_free_data_contents(ctx->context, message);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalanstatic int kpasswd_sendto_msg_callback(struct conn_state *conn, void *callback_context, krb5_data* message)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code code = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct sockaddr_storage local_addr;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_address local_kaddr;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct sendto_callback_context *ctx = callback_context;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan GETSOCKNAME_ARG3_TYPE addrlen;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data output;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan memset (message, 0, sizeof(krb5_data));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * We need the local addr from the connection socket
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan addrlen = sizeof(local_addr);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (getsockname(conn->fd, ss2sa(&local_addr), &addrlen) < 0) {
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb code = SOCKET_ERRNO;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb goto cleanup;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb }
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /* some brain-dead OS's don't return useful information from
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * the getsockname call. Namely, windows and solaris. */
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ss2sin(&local_addr)->sin_addr.s_addr != 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan local_kaddr.addrtype = ADDRTYPE_INET;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan local_kaddr.length = sizeof(ss2sin(&local_addr)->sin_addr);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan local_kaddr.contents = (krb5_octet *) &ss2sin(&local_addr)->sin_addr;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_address **addrs;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan code = krb5_os_localaddr(ctx->context, &addrs);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (code)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan local_kaddr.magic = addrs[0]->magic;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan local_kaddr.addrtype = addrs[0]->addrtype;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan local_kaddr.length = addrs[0]->length;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan local_kaddr.contents = malloc(addrs[0]->length);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (local_kaddr.contents == NULL && addrs[0]->length != 0) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan code = errno;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_free_addresses(ctx->context, addrs);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb goto cleanup;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan memcpy(local_kaddr.contents, addrs[0]->contents, addrs[0]->length);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_free_addresses(ctx->context, addrs);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * TBD: Does this tamper w/ the auth context in such a way
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * to break us? Yes - provide 1 per conn-state / host...
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((code = krb5_auth_con_setaddrs(ctx->context, ctx->auth_context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &local_kaddr, NULL)))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (ctx->set_password_for)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan code = krb5int_mk_setpw_req(ctx->context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx->auth_context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &ctx->ap_req,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx->set_password_for,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx->newpw,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &output);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan code = krb5int_mk_chpw_req(ctx->context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx->auth_context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &ctx->ap_req,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ctx->newpw,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &output);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (code)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan message->length = output.length;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan message->data = output.data;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalancleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return code;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan}
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan/*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan** The logic for setting and changing a password is mostly the same
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan** krb5_change_set_password handles both cases
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan** if set_password_for is NULL, then a password change is performed,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan** otherwise, the password is set for the principal indicated in set_password_for
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan*/
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_error_code KRB5_CALLCONV
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalankrb5_change_set_password(krb5_context context, krb5_creds *creds, char *newpw,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_principal set_password_for,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int *result_code, krb5_data *result_code_string,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data *result_string)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_data chpw_rep;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_address remote_kaddr;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_boolean useTcp = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan GETSOCKNAME_ARG3_TYPE addrlen;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code code = 0;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan char *code_string;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan int local_result_code;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct sendto_callback_context callback_ctx;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct sendto_callback_info callback_info;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct sockaddr_storage remote_addr;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan struct addrlist al = ADDRLIST_INIT;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan memset( &callback_ctx, 0, sizeof(struct sendto_callback_context));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan callback_ctx.context = context;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan callback_ctx.newpw = newpw;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan callback_ctx.set_password_for = set_password_for;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((code = krb5_auth_con_init(callback_ctx.context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &callback_ctx.auth_context)))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((code = krb5_mk_req_extended(callback_ctx.context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &callback_ctx.auth_context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan AP_OPTS_USE_SUBKEY,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan NULL,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan creds,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &callback_ctx.ap_req)))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan do {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((code = krb5_locate_kpasswd(callback_ctx.context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_princ_realm(callback_ctx.context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan creds->server),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &al, useTcp)))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb addrlen = sizeof(remote_addr);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan callback_info.context = (void*) &callback_ctx;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan callback_info.pfn_callback = kpasswd_sendto_msg_callback;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan callback_info.pfn_cleanup = kpasswd_sendto_msg_cleanup;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((code = krb5int_sendto(callback_ctx.context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan NULL,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &al,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &callback_info,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &chpw_rep,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan NULL,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan NULL,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ss2sa(&remote_addr),
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &addrlen,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan NULL,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan NULL,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan NULL
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ))) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * Here we may want to switch to TCP on some errors.
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan * right?
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb }
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb remote_kaddr.addrtype = ADDRTYPE_INET;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb remote_kaddr.length = sizeof(ss2sin(&remote_addr)->sin_addr);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb remote_kaddr.contents = (krb5_octet *) &ss2sin(&remote_addr)->sin_addr;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if ((code = krb5_auth_con_setaddrs(callback_ctx.context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan callback_ctx.auth_context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan NULL,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &remote_kaddr)))
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (set_password_for)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan code = krb5int_rd_setpw_rep(callback_ctx.context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan callback_ctx.auth_context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &chpw_rep,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &local_result_code,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan result_string);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan code = krb5int_rd_chpw_rep(callback_ctx.context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan callback_ctx.auth_context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &chpw_rep,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &local_result_code,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan result_string);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (code) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (code == KRB5KRB_ERR_RESPONSE_TOO_BIG && !useTcp ) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5int_free_addrlist (&al);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan useTcp = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan continue;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb }
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if (result_code)
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb *result_code = local_result_code;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if (result_code_string) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (set_password_for)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan code = krb5int_setpw_result_code_string(callback_ctx.context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan local_result_code,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan (const char **)&code_string);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan else
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan code = krb5_chpw_result_code_string(callback_ctx.context,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan local_result_code,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan &code_string);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if(code)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan goto cleanup;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb result_code_string->length = strlen(code_string);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb result_code_string->data = malloc(result_code_string->length);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb if (result_code_string->data == NULL) {
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb code = ENOMEM;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb goto cleanup;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb }
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb strncpy(result_code_string->data, code_string, result_code_string->length);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb }
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (code == KRB5KRB_ERR_RESPONSE_TOO_BIG && !useTcp ) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5int_free_addrlist (&al);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan useTcp = 1;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } else {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan break;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan } while (TRUE);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtbcleanup:
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (callback_ctx.auth_context != NULL)
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_auth_con_free(callback_ctx.context, callback_ctx.auth_context);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5int_free_addrlist (&al);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_free_data_contents(callback_ctx.context, &callback_ctx.ap_req);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb return(code);
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb}
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtbkrb5_error_code KRB5_CALLCONV
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtbkrb5_change_password(krb5_context context, krb5_creds *creds, char *newpw, int *result_code, krb5_data *result_code_string, krb5_data *result_string)
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb{
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb return krb5_change_set_password(
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb context, creds, newpw, NULL, result_code, result_code_string, result_string );
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb}
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb/*
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb * krb5_set_password - Implements set password per RFC 3244
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb *
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb */
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtbkrb5_error_code KRB5_CALLCONV
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtbkrb5_set_password(
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_context context,
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_creds *creds,
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb char *newpw,
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_principal change_password_for,
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb int *result_code, krb5_data *result_code_string, krb5_data *result_string
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb )
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb{
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb return krb5_change_set_password(
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb context, creds, newpw, change_password_for, result_code, result_code_string, result_string );
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb}
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtbkrb5_error_code KRB5_CALLCONV
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtbkrb5_set_password_using_ccache(
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_context context,
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_ccache ccache,
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb char *newpw,
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb krb5_principal change_password_for,
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb int *result_code, krb5_data *result_code_string, krb5_data *result_string
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb )
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb{
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_creds creds;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_creds *credsp;
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_error_code code;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ** get the proper creds for use with krb5_set_password -
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan memset (&creds, 0, sizeof(creds));
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan /*
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan ** first get the principal for the password service -
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan */
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan code = krb5_cc_get_principal (context, ccache, &creds.client);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!code) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan code = krb5_build_principal(context, &creds.server,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_princ_realm(context, change_password_for)->length,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_princ_realm(context, change_password_for)->data,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan "kadmin", "changepw", NULL);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!code) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan code = krb5_get_credentials(context, 0, ccache, &creds, &credsp);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan if (!code) {
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan code = krb5_set_password(context, credsp, newpw, change_password_for,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan result_code, result_code_string,
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan result_string);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_free_creds(context, credsp);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan krb5_free_cred_contents(context, &creds);
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan }
159d09a20817016f09b3ea28d1bdada4a336bb91Mark Phalan return code;
10db1377dafab8ba3feedef26db9c5d8539a5cd1gtb}