summaryrefslogtreecommitdiffstats
path: root/src/windows/cns
diff options
context:
space:
mode:
authorKeith Vetter <keithv@fusion.com>1995-05-31 00:30:24 +0000
committerKeith Vetter <keithv@fusion.com>1995-05-31 00:30:24 +0000
commitf581566cc0892118a8d35a927be4ea854c80f239 (patch)
tree3906d00b6e5f5a842d9053aed3aef8b77521d726 /src/windows/cns
parent4006345f4798a71d7918892579270b3053256a6b (diff)
downloadkrb5-f581566cc0892118a8d35a927be4ea854c80f239.tar.gz
krb5-f581566cc0892118a8d35a927be4ea854c80f239.tar.xz
krb5-f581566cc0892118a8d35a927be4ea854c80f239.zip
Added k5 password changing code for the cns program (untested, waiting for
a server.) git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@5918 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/windows/cns')
-rw-r--r--src/windows/cns/.Sanitize1
-rw-r--r--src/windows/cns/changelo7
-rw-r--r--src/windows/cns/cns.c38
-rw-r--r--src/windows/cns/cns.h8
-rw-r--r--src/windows/cns/kpasswd.c215
-rw-r--r--src/windows/cns/makefile2
6 files changed, 240 insertions, 31 deletions
diff --git a/src/windows/cns/.Sanitize b/src/windows/cns/.Sanitize
index 0dd688f185..a9f9a8ad5c 100644
--- a/src/windows/cns/.Sanitize
+++ b/src/windows/cns/.Sanitize
@@ -44,6 +44,7 @@ cns.def
cns.h
cns.ico
cns.rc
+kpasswd.c
krbini.h
makefile
tktlist.c
diff --git a/src/windows/cns/changelo b/src/windows/cns/changelo
index 9e70e5f50a..4dee962fdb 100644
--- a/src/windows/cns/changelo
+++ b/src/windows/cns/changelo
@@ -1,3 +1,10 @@
+Tue May 30 17:28:04 1995 Keith Vetter (keithv@fusion.com)
+
+ * kpasswd.c: new file for k5 password changing.
+ * makefile: added new file to obj list.
+ * cns.c: added call to kpasswd stuff.
+ * cns.h: added prototype for kpasswd stuff.
+
Thu Apr 27 11:46:42 1995 Keith Vetter (keithv@fusion.com)
* cns.c, cns.rc, krbini.h: K5 no longer has conf and realms files
diff --git a/src/windows/cns/cns.c b/src/windows/cns/cns.c
index 844777b3bc..d4f3249164 100644
--- a/src/windows/cns/cns.c
+++ b/src/windows/cns/cns.c
@@ -493,43 +493,21 @@ change_password (
#ifdef KRB5 /* FIXME */
char *msg; // Message string
krb5_error_code code; // Return value
-
- krb5_error_code //FIXME INTERFACE
- krb5_change_password(
- krb5_context context,
- char *user,
- char *realm,
- char *old_password,
- char *new_password,
- char **text);
-
- code = krb5_change_password (k5_context, name, realm, oldpw, newpw, &msg);
+ code = k5_change_password (k5_context, name, realm, oldpw, newpw, &msg);
if (msg != NULL) {
MessageBox (NULL, msg, NULL, MB_ICONEXCLAMATION);
- //WHO FREES THIS SPACE??? free (msg);
- } else if (code)
- com_err (NULL, code, "while changing password.");
+ } else if (code) {
+ if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY)
+ MessageBox (NULL, "Password incorrect", NULL, MB_ICONEXCLAMATION);
+ else
+ com_err (NULL, code, "while changing password.");
+ }
return (code == 0);
-#endif
-} /* change_password */
-/*+*/
-#ifdef KRB5
-krb5_error_code //FIXME INTERFACE
-krb5_change_password(
- krb5_context context,
- char *user,
- char *realm,
- char *old_password,
- char *new_password,
- char **text)
-{
- *text = "Changing passwords is not yet implemented";
- return -1;
-}
#endif /* KRB5 */
+}
/*+
* Function: Process WM_COMMAND messages for the password dialog.
*
diff --git a/src/windows/cns/cns.h b/src/windows/cns/cns.h
index deac2f64c1..35a50e94c1 100644
--- a/src/windows/cns/cns.h
+++ b/src/windows/cns/cns.h
@@ -153,6 +153,14 @@ time_t kwin_get_epoch(void);
static int k5_get_lrealm (char *realm);
static krb5_error_code k5_init_ccache (krb5_ccache *ccache);
static int k5_name_from_ccache (krb5_ccache k5_ccache);
+ krb5_error_code k5_change_password (
+ krb5_context context,
+ char *user,
+ char *realm,
+ char *old_password,
+ char *new_password,
+ char **text);
+
#endif
HICON kwin_get_icon(time_t expiration);
diff --git a/src/windows/cns/kpasswd.c b/src/windows/cns/kpasswd.c
new file mode 100644
index 0000000000..2a79b84f70
--- /dev/null
+++ b/src/windows/cns/kpasswd.c
@@ -0,0 +1,215 @@
+/*+*************************************************************************
+**
+** k5passwd
+**
+** Changes your password in the Kerberos V5. This should have been
+** part of the kadm stuff but we're forced to build a nicer API on top
+** of the calls they provide.
+**
+***************************************************************************/
+#ifdef KRB5
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "krb5.h"
+#include "com_err.h"
+#include "adm.h"
+#include "adm_proto.h"
+
+static const char *kadm_replies[] = {
+ "Operation successful", /* KRB5_ADM_SUCCESS */
+ "Command not recognized", /* KRB5_ADM_CMD_UNKNOWN */
+ "Password unacceptable to server", /* KRB5_ADM_PW_UNACCEPT */
+ "Old password incorrect", /* KRB5_ADM_BAD_PW */
+ "Invalid ticket (TKT_FLAG_INITIAL not set)",/* KRB5_ADM_NOT_IN_TKT */
+ "Server refused password change", /* KRB5_ADM_CANT_CHANGE */
+ "Language not supported", /* KRB5_ADM_LANG_NOT_SUPPORTED */
+};
+static const char *kadm_replies_unknown = "UNKNOWN ERROR";
+static char errbuf[1024]; /* For response from kadm */
+
+/*+*************************************************************************
+**
+** get_admin_response
+**
+** Builds into a static buffer the replies sent back by the admin server.
+**
+***************************************************************************/
+static char *
+get_admin_response (
+ krb5_int32 status, // Type of error
+ krb5_int32 nreplies, // Size of reply
+ krb5_data * reply) // Buffer of messages
+{
+ char *ptr; // For building the response
+ char *end = errbuf + sizeof (errbuf); // So we don't overflow
+ int i; // Index
+ int n; // Length
+
+ if (status <= KRB5_ADM_LANG_NOT_SUPPORTED) // Is it of a known type???
+ strcpy (errbuf, kadm_replies[status]);
+ else
+ strcpy (errbuf, kadm_replies_unknown); // Unknown error type
+ ptr = errbuf + strlen (errbuf); // Point at the end
+
+ if (nreplies > 0) { // Are there more message?
+ *ptr++ = ':';
+ *ptr = '\0';
+ }
+
+ for (i = 0; i < nreplies; ++i) { // Append additional messages
+ *ptr++ = '\n';
+
+ n = reply[i].length; // Easier to work with
+ if (ptr + n + 2 >= errbuf) // Check for overflow
+ break;
+ memcpy (ptr, reply[i].data, n); // Add the message
+ ptr += n; // Point to the end
+ *ptr = '\0';
+ }
+
+ return errbuf;
+}
+/*+*************************************************************************
+**
+** keyadmin_send_recieve
+**
+** Sends a command to the key admin and reads the reply.
+**
+***************************************************************************/
+static krb5_error_code
+keyadmin_send_receive (
+ krb5_context k5context,
+ int * conn_socket,
+ krb5_auth_context * auth_context,
+ krb5_int32 nargs,
+ krb5_data * arglist,
+ krb5_int32 * cmd_stat,
+ krb5_int32 * nreplies,
+ krb5_data ** reply)
+{
+ krb5_error_code kret;
+
+ kret = krb5_send_adm_cmd (k5context, conn_socket, auth_context,
+ nargs, arglist);
+
+ if (! kret)
+ kret = krb5_read_adm_reply (k5context, conn_socket, auth_context,
+ cmd_stat, nreplies, reply);
+
+ return kret;
+}
+/*+*************************************************************************
+**
+** k5_change_password
+**
+** Bundles all the crude needed to change the password into one file.
+**
+***************************************************************************/
+krb5_error_code
+k5_change_password (
+ krb5_context k5context,
+ char *user,
+ char *realm,
+ char *opasswd,
+ char *npasswd,
+ char **text)
+{
+ krb5_error_code kret, kret2;
+ krb5_auth_context * auth_context;
+ krb5_ccache ccache;
+ int conn_socket; /* Socket for talking over */
+ krb5_int32 nreplies;
+ krb5_data data[3];
+ krb5_data * reply;
+ krb5_int32 status;
+ char * name;
+
+ *text = NULL; /* Be safe */
+ name = malloc (strlen (user) + strlen (realm) + 2);
+ if (name == NULL)
+ return ENOMEM;
+ sprintf (name, "%s@%s", user, realm);
+
+/*
+** Establish the connection.
+*/
+ kret = krb5_adm_connect (k5context, name, NULL, opasswd, &conn_socket,
+ &auth_context, &ccache);
+ if (kret)
+ goto done;
+/*
+** Check to see if it's an acceptable password
+*/
+ data[0].data = KRB5_ADM_CHECKPW_CMD;
+ data[0].length = strlen (data[0].data);
+ data[1].data = npasswd;
+ data[1].length = strlen (npasswd);
+
+ kret = keyadmin_send_receive (k5context, &conn_socket, auth_context,
+ 2, data, &status, &nreplies, &reply);
+ if (kret) /* Some external error */
+ goto cleanup;
+
+ if (status != KRB5_ADM_SUCCESS) { /* Some problem??? */
+ kret = status;
+ *text = get_admin_response (status, nreplies, reply);
+ krb5_free_adm_data (k5context, nreplies, reply);
+
+ goto quit;
+ }
+ krb5_free_adm_data (k5context, nreplies, reply);
+
+/*
+** The new password is ok, so now actually change the password
+*/
+ data[0].data = KRB5_ADM_CHANGEPW_CMD;
+ data[0].length = strlen (data[0].data);
+ data[1].data = opasswd;
+ data[1].length = strlen (opasswd);
+ data[2].data = npasswd;
+ data[2].length = strlen (npasswd);
+
+ kret = keyadmin_send_receive (k5context, &conn_socket, auth_context,
+ 3, data, &status, &nreplies, &reply);
+ if (kret)
+ goto cleanup;
+
+ if (status != KRB5_ADM_SUCCESS) {
+ kret = status;
+ *text = get_admin_response (status, nreplies, reply);
+ krb5_free_adm_data (k5context, nreplies, reply);
+
+ goto quit;
+ }
+
+ krb5_free_adm_data (k5context, nreplies, reply);
+/*+
+** Need to send quit command.
+*/
+ quit:
+ data[0].data = KRB5_ADM_QUIT_CMD;
+ data[0].length = strlen (data[0].data);
+
+ kret2 = keyadmin_send_receive (k5context, &conn_socket, auth_context,
+ 1, data, &status, &nreplies, &reply);
+ if (kret2) {
+ if (! kret)
+ kret = kret2;
+ } else if (status != KRB5_ADM_SUCCESS) {
+ if (! kret)
+ kret = status;
+ if (*text == NULL)
+ *text = get_admin_response (status, nreplies, reply);
+ }
+ krb5_free_adm_data (k5context, nreplies, reply);
+
+ cleanup:
+ krb5_adm_disconnect (k5context, &conn_socket, auth_context, ccache);
+ done:
+ free (name);
+
+ return kret;
+}
+
+#endif /* KRB5 */
diff --git a/src/windows/cns/makefile b/src/windows/cns/makefile
index ca67f7b6fc..0f3fff350c 100644
--- a/src/windows/cns/makefile
+++ b/src/windows/cns/makefile
@@ -2,7 +2,7 @@
# Works for both k4 and k5 releases.
#
NAME = cns
-OBJS = cns.obj tktlist.obj
+OBJS = cns.obj tktlist.obj kpasswd.obj
##### Options
DEBUG = 1