summaryrefslogtreecommitdiffstats
path: root/src/lib/krb5/os/changepw.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/krb5/os/changepw.c')
-rw-r--r--src/lib/krb5/os/changepw.c115
1 files changed, 100 insertions, 15 deletions
diff --git a/src/lib/krb5/os/changepw.c b/src/lib/krb5/os/changepw.c
index 60cb3a9158..a4f5422f39 100644
--- a/src/lib/krb5/os/changepw.c
+++ b/src/lib/krb5/os/changepw.c
@@ -24,6 +24,10 @@
* or implied warranty.
*
*/
+/*
+ * krb5_set_password - Implements set password per RFC 3244
+ * Added by Paul W. Nelson, Thursby Software Systems, Inc.
+ */
#define NEED_SOCKETS
#include "fake-addrinfo.h"
@@ -69,8 +73,16 @@ krb5_locate_kpasswd(krb5_context context, const krb5_data *realm,
}
+/*
+** The logic for setting and changing a password is mostly the same
+** krb5_change_set_password handles both cases
+** if set_password_for is NULL, then a password change is performed,
+** otherwise, the password is set for the principal indicated in set_password_for
+*/
krb5_error_code KRB5_CALLCONV
-krb5_change_password(krb5_context context, krb5_creds *creds, char *newpw, int *result_code, krb5_data *result_code_string, krb5_data *result_string)
+krb5_change_set_password(
+ krb5_context context, krb5_creds *creds, char *newpw, krb5_principal set_password_for,
+ int *result_code, krb5_data *result_code_string, krb5_data *result_string)
{
krb5_auth_context auth_context;
krb5_data ap_req, chpw_req, chpw_rep;
@@ -104,7 +116,7 @@ krb5_change_password(krb5_context context, krb5_creds *creds, char *newpw, int *
goto cleanup;
if ((code = krb5_locate_kpasswd(context,
- krb5_princ_realm(context, creds->client),
+ krb5_princ_realm(context, set_password_for),
&al)))
goto cleanup;
@@ -218,14 +230,15 @@ krb5_change_password(krb5_context context, krb5_creds *creds, char *newpw, int *
if ((code = krb5_auth_con_setaddrs(context, auth_context,
&local_kaddr, NULL))) {
- code = SOCKET_ERRNO;
- goto cleanup;
+ goto cleanup;
}
- if ((code = krb5_mk_chpw_req(context, auth_context, &ap_req,
- newpw, &chpw_req)))
+ if( set_password_for )
+ code = krb5int_mk_setpw_req(context, auth_context, &ap_req, set_password_for, newpw, &chpw_req);
+ else
+ code = krb5int_mk_chpw_req(context, auth_context, &ap_req, newpw, &chpw_req);
+ if (code)
{
- code = SOCKET_ERRNO;
goto cleanup;
}
@@ -289,19 +302,23 @@ krb5_change_password(krb5_context context, krb5_creds *creds, char *newpw, int *
NULL, &remote_kaddr)))
goto cleanup;
- if ((code = krb5_rd_chpw_rep(context, auth_context, &chpw_rep,
- &local_result_code,
- result_string)))
- goto cleanup;
+ if( set_password_for )
+ code = krb5int_rd_setpw_rep(context, auth_context, &chpw_rep, &local_result_code, result_string);
+ else
+ code = krb5int_rd_chpw_rep(context, auth_context, &chpw_rep, &local_result_code, result_string);
+ if (code)
+ goto cleanup;
if (result_code)
*result_code = local_result_code;
if (result_code_string) {
- if ((code = krb5_chpw_result_code_string(context,
- local_result_code,
- &code_string)))
- goto cleanup;
+ if( set_password_for )
+ code = krb5_setpw_result_code_string(context, local_result_code, (const char **)&code_string);
+ else
+ code = krb5_chpw_result_code_string(context, local_result_code, &code_string);
+ if(code)
+ goto cleanup;
result_code_string->length = strlen(code_string);
result_code_string->data = malloc(result_code_string->length);
@@ -343,3 +360,71 @@ cleanup:
return(code);
}
+
+krb5_error_code KRB5_CALLCONV
+krb5_change_password(krb5_context context, krb5_creds *creds, char *newpw, int *result_code, krb5_data *result_code_string, krb5_data *result_string)
+{
+ return krb5_change_set_password(
+ context, creds, newpw, NULL, result_code, result_code_string, result_string );
+}
+
+/*
+ * krb5_set_password - Implements set password per RFC 3244
+ *
+ */
+
+krb5_error_code KRB5_CALLCONV
+krb5_set_password(
+ krb5_context context,
+ krb5_creds *creds,
+ char *newpw,
+ krb5_principal change_password_for,
+ int *result_code, krb5_data *result_code_string, krb5_data *result_string
+ )
+{
+ return krb5_change_set_password(
+ context, creds, newpw, change_password_for, result_code, result_code_string, result_string );
+}
+
+krb5_error_code KRB5_CALLCONV
+krb5_set_password_using_ccache(
+ krb5_context context,
+ krb5_ccache ccache,
+ char *newpw,
+ krb5_principal change_password_for,
+ int *result_code, krb5_data *result_code_string, krb5_data *result_string
+ )
+{
+ krb5_creds creds;
+ krb5_creds *credsp;
+ krb5_error_code code;
+
+/*
+** get the proper creds for use with krb5_set_password -
+*/
+ memset( &creds, 0, sizeof(creds) );
+/*
+** first get the principal for the password service -
+*/
+ code = krb5_cc_get_principal( context, ccache, &creds.client );
+ if( !code )
+ {
+ code = krb5_build_principal( context, &creds.server,
+ krb5_princ_realm(context, change_password_for)->length,
+ krb5_princ_realm(context, change_password_for)->data,
+ "kadmin", "changepw", NULL );
+ if(!code)
+ {
+ code = krb5_get_credentials(context, 0, ccache, &creds, &credsp);
+ if( ! code )
+ {
+ code = krb5_set_password(context, credsp, newpw, change_password_for,
+ result_code, result_code_string,
+ result_string);
+ krb5_free_creds(context, credsp);
+ }
+ }
+ krb5_free_cred_contents(context, &creds);
+ }
+ return code;
+}