From 7029886dba72c0504dfc528893dc7d6e98d51e07 Mon Sep 17 00:00:00 2001 From: Theodore Tso Date: Wed, 27 May 1998 19:51:25 +0000 Subject: Folded in enhancements from Cygnus's Kerbnet-1.2 (plus our changes made since Cygnus's last snapshot). See ChangeLog from Cygnus (included in the ChangeLog file) for more details. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@10598 dc483132-0cff-0310-8789-dd5450dbe970 --- src/windows/cns/kpasswd.c | 266 +++++++++++++--------------------------------- 1 file changed, 71 insertions(+), 195 deletions(-) (limited to 'src/windows/cns/kpasswd.c') diff --git a/src/windows/cns/kpasswd.c b/src/windows/cns/kpasswd.c index 2f1327126c..8d867f02d8 100644 --- a/src/windows/cns/kpasswd.c +++ b/src/windows/cns/kpasswd.c @@ -1,213 +1,89 @@ /* - * - * 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. - * + * Copyright (c) 1997 Cygnus Solutions. + * + * Author: Michael Graff */ -#ifdef KRB5 - #include #include #include + #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; - char foo[1024]; - int i; - - 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; -} +#include "cns.h" +#include "../lib/gic.h" /* * k5_change_password * - * Bundles all the crud needed to change the password into one file. + * Use the new functions to change the password. */ krb5_error_code -k5_change_password (krb5_context k5context, char *user, char *realm, - char *opasswd, char *npasswd, char **text) +k5_change_password(HWND hwnd, krb5_context context, 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); - ccache = (krb5_ccache)NULL; - - /* - * Establish the connection. - */ - kret = krb5_adm_connect(k5context, name, NULL, opasswd, &conn_socket, - &auth_context, &ccache, "kadm.tk", 0); - 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; + krb5_error_code ret; + krb5_data result_string; + krb5_data result_code_string; + int result_code; + krb5_get_init_creds_opt opts; + krb5_creds creds; + krb5_principal princ; + char *name; + gic_data gd; + + *text = NULL; + + name = malloc(strlen(user) + strlen(realm) + 2); + if (name == NULL) { + *text = "Failed to allocate memory while changing password"; + return 1; + } + sprintf(name, "%s@%s", user, realm); + + ret = krb5_parse_name(context, name, &princ); + free(name); + if (ret) { + *text = "while parsing name"; + return ret; + } + + 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); + + gd.hinstance = hinstance; + gd.hwnd = hwnd; + gd.id = ID_VARDLG; + + ret = krb5_get_init_creds_password(context, &creds, princ, opasswd, gic_prompter, + &gd, 0, "kadmin/changepw", &opts); + if (ret) { + *text = "while getting creds"; + return ret; + } + + ret = krb5_change_password(context, &creds, npasswd, &result_code, &result_code_string, + &result_string); + if (ret) { + *text = "while changing password"; + return ret; + } + + if (result_code) { + *text = malloc(result_code_string.length + result_string.length + 3); + if (*text == NULL) + return -1; + + sprintf(*text, "%.*s%s%.*s", + result_code_string.length, result_code_string.data, + (result_string.length ? ": " : ""), + result_string.length, result_string.data); + } + + return 0; } - -#endif /* KRB5 */ -- cgit