--- /dev/null
+Fri Jan 30 16:06:13 1998 Tom Yu <tlyu@mit.edu>
+
+ * kpasswd.c:
+ * kpasswd.M:
+ * Makefile.in:
+ * configure.in: New: Cygnus kpasswd client.
+
+Mon Mar 31 23:49:34 1997 Marc Horowitz <marc@cygnus.com>
+
+ * Makefile.in (install-all install-kdc install-server install-client install-unix): install the new man page
+
+Sat Mar 29 14:31:51 1997 Mark Eichin <eichin@cygnus.com>
+
+ * kpasswd.c (main): use fprintf correctly in usage.
+
+Tue Mar 4 21:47:48 1997 Marc Horowitz <marc@cygnus.com>
+
+ * kpasswd.c (main): retool for new init_creds interface
+
+Wed Feb 19 21:00:12 1997 Marc Horowitz <marc@cygnus.com>
+
+ * kpasswd.c: use the string version of the chpw result_code in the
+ error message.
+
+Mon Feb 3 17:50:30 1997 Marc Horowitz <marc@cygnus.com>
+
+ * kpasswd.c: new password change client
+ * Makefile.in: new directory
--- /dev/null
+CFLAGS = $(CCOPTS) $(DEFS) $(LOCALINCLUDE)
+PROG_LIBPATH=-L$(TOPLIBD)
+PROG_RPATH=$(KRB5_LIBDIR)
+
+##DOSBUILDTOP=..\..
+
+kpasswd: kpasswd.o $(KRB5_BASE_DEPLIBS)
+ $(CC_LINK) -o kpasswd kpasswd.o $(KRB5_BASE_LIBS)
+
+kpasswd.o: $(srcdir)/kpasswd.c
+
+all-unix:: kpasswd
+all-windows:: kpasswd.exe
+
+clean-unix::
+ $(RM) kpasswd.o kpasswd
+
+clean-windows::
+ $(RM) kpasswd.obj kpasswd.exe
+
+install-all install-kdc install-server install-client install-unix::
+ $(INSTALL_PROGRAM) kpasswd $(DESTDIR)$(CLIENT_BINDIR)/`echo kpasswd|sed '$(transform)'`
+ $(INSTALL_DATA) $(srcdir)/kpasswd.M $(DESTDIR)$(CLIENT_MANDIR)/`echo kpasswd|sed '$(transform)'`.1;
+
+kpasswd.exe: kpasswd.obj
+ link /out:kpasswd.exe kpasswd.obj $(BUILDTOP)\lib\libkrb5.lib
--- /dev/null
+.\" clients/kpasswd/kpasswd.M
+.\"
+.\" Copyright 1995 by the Massachusetts Institute of Technology.
+.\"
+.\" Export of this software from the United States of America may
+.\" require a specific license from the United States Government.
+.\" It is the responsibility of any person or organization contemplating
+.\" export to obtain such a license before exporting.
+.\"
+.\" WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+.\" distribute this software and its documentation for any purpose and
+.\" without fee is hereby granted, provided that the above copyright
+.\" notice appear in all copies and that both that copyright notice and
+.\" this permission notice appear in supporting documentation, and that
+.\" the name of M.I.T. not be used in advertising or publicity pertaining
+.\" to distribution of the software without specific, written prior
+.\" permission. M.I.T. makes no representations about the suitability of
+.\" this software for any purpose. It is provided "as is" without express
+.\" or implied warranty.
+.\" "
+.so man1/header.doc
+.TH KPASSWD 1 \*h
+.SH NAME
+kpasswd \- change a user's Kerberos password
+.SH SYNOPSIS
+.B kpasswd
+[\fIprincipal\fP]
+.SH DESCRIPTION
+.PP
+The
+.I kpasswd
+command is used to change a Kerberos principal's password.
+.I Kpasswd
+prompts for the current Kerberos password, which is used to obtain a
+.B changepw
+ticket from the
+.SM KDC
+for the user's Kerberos realm. If
+.B kpasswd
+successfully obtains the
+.B changepw
+ticket, the user is prompted twice for the new password, and the
+password is changed.
+.PP
+If the principal is governed by a policy that specifies the length and/or
+number of character classes required in the new password, the new
+password must conform to the policy. (The five character classes are
+lower case, upper case, numbers, punctuation, and all other characters.)
+.SH OPTIONS
+.TP
+.I principal
+change the password for the Kerberos principal
+.IR principal .
+Otherwise,
+.I kpasswd
+uses the principal name from an existing ccache if there is one; if
+not, the principal is derived from the identity of the user
+invoking the
+.I kpasswd
+command.
+.SH PORTS
+.B kpasswd
+looks first for kpasswd_server = host:port in the [realms] section of
+the krb5.conf file under the current realm. If that is missing,
+.B kpasswd
+looks for the admin_server entry, but substitutes 464 for the port.
+.SH SEE ALSO
+kadmin(8), kadmind(8)
+.SH BUGS
+.PP
+.B kpasswd
+may not work with multi-homed hosts running on the Solaris platform.
--- /dev/null
+#include <stdio.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <unistd.h>
+
+#include <krb5.h>
+
+#define P1 "Enter new password: "
+#define P2 "Enter it again: "
+
+int main(int argc, char *argv[])
+{
+ krb5_error_code ret;
+ krb5_context context;
+ krb5_principal princ;
+ char *pname;
+ struct passwd *pwd;
+ krb5_ccache ccache;
+ krb5_get_init_creds_opt opts;
+ krb5_creds creds;
+
+ krb5_timestamp now;
+ krb5_data ap_req;
+ krb5_auth_context auth_context;
+ char pw[1024];
+ int pwlen;
+ krb5_data chpw_req, chpw_rep;
+ int result_code;
+ krb5_data result_code_string, result_string;
+
+ if (argc > 2) {
+ fprintf(stderr, "usage: %s [principal]\n", argv[0]);
+ exit(1);
+ }
+
+ pname = argv[1];
+
+ if (ret = krb5_init_context(&context)) {
+ com_err(argv[0], ret, "initializing kerberos library");
+ exit(1);
+ }
+
+ krb5_init_ets(context);
+
+ /* in order, use the first of:
+ - a name specified on the command line
+ - the principal name from an existing ccache
+ - the name corresponding to the ruid of the process
+
+ otherwise, it's an error.
+ */
+
+ if (pname) {
+ if (ret = krb5_parse_name(context, pname, &princ)) {
+ com_err(argv[0], ret, "parsing client name");
+ exit(1);
+ }
+ } else if ((ret = krb5_cc_default(context, &ccache)) != KRB5_CC_NOTFOUND) {
+ if (ret) {
+ com_err(argv[0], ret, "opening default ccache");
+ exit(1);
+ }
+
+ if (ret = krb5_cc_get_principal(context, ccache, &princ)) {
+ com_err(argv[0], ret, "getting principal from ccache");
+ exit(1);
+ }
+
+ if (ret = krb5_cc_close(context, ccache)) {
+ com_err(argv[0], ret, "closing ccache");
+ exit(1);
+ }
+ } else if (pwd = getpwuid(getuid())) {
+ if (ret = krb5_parse_name(context, pwd->pw_name, &princ)) {
+ com_err(argv[0], ret, "parsing client name");
+ exit(1);
+ }
+ } else {
+ com_err(argv[0], 0,
+ "no matching password entry while looking for username");
+ exit(1);
+ }
+
+ krb5_get_init_creds_opt_init(&opts);
+ krb5_get_init_creds_opt_set_tkt_life(&opts, 5*60);
+ krb5_get_init_creds_opt_set_renew_life(&opts, 0);
+ krb5_get_init_creds_opt_set_forwardable(&opts, 0);
+ krb5_get_init_creds_opt_set_proxiable(&opts, 0);
+
+ if (ret = krb5_get_init_creds_password(context, &creds, princ, NULL,
+ krb5_prompter_posix, NULL,
+ 0, "kadmin/changepw", &opts)) {
+ if (ret == KRB5KRB_AP_ERR_BAD_INTEGRITY)
+ com_err(argv[0], 0,
+ "Password incorrect while getting initial ticket");
+ else
+ com_err(argv[0], ret, "getting initial ticket");
+ exit(1);
+ }
+
+ pwlen = sizeof(pw);
+ if (ret = krb5_read_password(context, P1, P2, pw, &pwlen)) {
+ com_err(argv[0], ret, "while reading password");
+ exit(1);
+ }
+
+ if (ret = krb5_change_password(context, &creds, pw,
+ &result_code, &result_code_string,
+ &result_string)) {
+ com_err(argv[0], ret, "changing password");
+ exit(1);
+ }
+
+ if (result_code) {
+ printf("%.*s%s%.*s\n",
+ result_code_string.length, result_code_string.data,
+ result_string.length?": ":"",
+ result_string.length, result_string.data);
+ exit(2);
+ }
+
+ free(result_string.data);
+ free(result_code_string.data);
+
+ printf("Password changed.\n");
+ exit(0);
+}