From 6ef6ee41883a7afe349fee55f0368bb0533f4209 Mon Sep 17 00:00:00 2001 From: Johan Danielsson Date: Fri, 16 Jan 1998 23:48:01 +0000 Subject: [PATCH] Add password changing support. git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@4296 ec53bebd-3082-4978-b11e-865c3cabbd6b --- lib/auth/sia/sia.c | 187 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 178 insertions(+), 9 deletions(-) diff --git a/lib/auth/sia/sia.c b/lib/auth/sia/sia.c index f53bae640..c00233a9c 100644 --- a/lib/auth/sia/sia.c +++ b/lib/auth/sia/sia.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan + * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -40,13 +40,20 @@ #include RCSID("$Id$"); #endif +#include #include #include #include #include +#include +#include +#include #include #include +#include +#include +#include #ifndef POSIX_GETPWNAM_R @@ -97,6 +104,12 @@ posix_getpwuid_r(uid_t uid, struct passwd *pwd, #endif /* POSIX_GETPWNAM_R */ +#ifndef DEBUG +#define SIA_DEBUG(X) +#else +#define SIA_DEBUG(X) warnx X +#endif + struct state{ char ticket[MaxPathLen]; int valid; @@ -111,6 +124,7 @@ siad_init(void) int siad_chk_invoker(void) { + SIA_DEBUG(("siad_chk_invoker")); return SIADFAIL; } @@ -118,6 +132,7 @@ int siad_ses_init(SIAENTITY *entity, int pkgind) { struct state *s = malloc(sizeof(*s)); + SIA_DEBUG(("siad_ses_init")); if(s == NULL) return SIADFAIL; memset(s, 0, sizeof(*s)); @@ -128,6 +143,7 @@ siad_ses_init(SIAENTITY *entity, int pkgind) static int setup_name(SIAENTITY *e, prompt_t *p) { + SIA_DEBUG(("setup_name")); e->name = malloc(SIANAMEMIN+1); if(e->name == NULL) return SIADFAIL; @@ -142,6 +158,7 @@ setup_name(SIAENTITY *e, prompt_t *p) static int setup_password(SIAENTITY *e, prompt_t *p) { + SIA_DEBUG(("setup_password")); e->password = malloc(SIAMXPASSWORD+1); if(e->password == NULL) return SIADFAIL; @@ -163,6 +180,7 @@ common_auth(sia_collect_func_t *collect, prompt_t prompts[2], *pr; char *toname, *toinst; + SIA_DEBUG(("common_auth")); if((siastat == SIADSUCCESS) && (geteuid() == 0)) return SIADSUCCESS; if(entity == NULL) @@ -262,6 +280,7 @@ siad_ses_authent(sia_collect_func_t *collect, int siastat, int pkgind) { + SIA_DEBUG(("siad_ses_authent")); return common_auth(collect, entity, siastat, pkgind); } @@ -269,6 +288,7 @@ int siad_ses_estab(sia_collect_func_t *collect, SIAENTITY *entity, int pkgind) { + SIA_DEBUG(("siad_ses_estab")); return SIADFAIL; } @@ -277,9 +297,9 @@ siad_ses_launch(sia_collect_func_t *collect, SIAENTITY *entity, int pkgind) { - char buf[MaxPathLen]; static char env[MaxPathLen]; struct state *s = (struct state*)entity->mech[pkgind]; + SIA_DEBUG(("siad_ses_launch")); if(s->valid){ chown(s->ticket, entity->pwd->pw_uid, entity->pwd->pw_gid); snprintf(env, sizeof(env), "KRBTKFILE=%s", s->ticket); @@ -298,6 +318,7 @@ siad_ses_launch(sia_collect_func_t *collect, int siad_ses_release(SIAENTITY *entity, int pkgind) { + SIA_DEBUG(("siad_ses_release")); if(entity->mech[pkgind]) free(entity->mech[pkgind]); return SIADSUCCESS; @@ -309,6 +330,7 @@ siad_ses_suauthent(sia_collect_func_t *collect, int siastat, int pkgind) { + SIA_DEBUG(("siad_ses_suauth")); if(geteuid() != 0) return SIADFAIL; if(entity->name == NULL) @@ -326,6 +348,7 @@ siad_ses_reauthent (sia_collect_func_t *collect, int siastat, int pkgind) { + SIA_DEBUG(("siad_ses_reauthent")); return SIADFAIL; } @@ -335,16 +358,160 @@ siad_chg_finger (sia_collect_func_t *collect, int argc, char *argv[]) { + SIA_DEBUG(("siad_chg_finger")); return SIADFAIL; } -int -siad_chg_passwd (sia_collect_func_t *collect, - const char *username, - int argc, - char *argv[]) +static void +sia_message(sia_collect_func_t *collect, int rendition, + const char *title, const char *message) { - return SIADFAIL; + prompt_t prompt; + prompt.prompt = (unsigned char*)message; + (*collect)(0, rendition, (unsigned char*)title, 1, &prompt); +} + +static int +init_change(sia_collect_func_t *collect, krb_principal *princ) +{ + prompt_t prompt; + char old_pw[MAX_KPW_LEN+1]; + char *msg; + char tktstring[128]; + int ret; + + SIA_DEBUG(("init_change")); + prompt.prompt = (unsigned char*)"Old password: "; + prompt.result = (unsigned char*)old_pw; + prompt.min_result_length = 0; + prompt.max_result_length = sizeof(old_pw) - 1; + prompt.control_flags = SIARESINVIS; + asprintf(&msg, "Changing password for %s", krb_unparse_name(princ)); + if(msg == NULL){ + SIA_DEBUG(("out of memory")); + return SIADFAIL; + } + ret = (*collect)(60, SIAONELINER, (unsigned char*)msg, 1, &prompt); + free(msg); + SIA_DEBUG(("ret = %d", ret)); + if(ret != SIACOLSUCCESS) + return SIADFAIL; + snprintf(tktstring, sizeof(tktstring), + TKT_ROOT "_cpw_%u", (unsigned)getpid()); + krb_set_tkt_string(tktstring); + + ret = krb_get_pw_in_tkt(princ->name, princ->instance, princ->realm, + PWSERV_NAME, KADM_SINST, 1, old_pw); + if (ret != KSUCCESS) { + SIA_DEBUG(("krb_get_pw_in_tkt: %s", krb_get_err_text(ret))); + if (ret == INTK_BADPW) + sia_message(collect, SIAWARNING, "", "Incorrect old password."); + else + sia_message(collect, SIAWARNING, "", "Kerberos error."); + memset(old_pw, 0, sizeof(old_pw)); + return SIADFAIL; + } + if(chown(tktstring, getuid(), -1) < 0){ + dest_tkt(); + return SIADFAIL; + } + memset(old_pw, 0, sizeof(old_pw)); + return SIADSUCCESS; +} + +int +siad_chg_password (sia_collect_func_t *collect, + const char *username, + int argc, + char *argv[]) +{ + prompt_t prompts[2]; + krb_principal princ; + int ret; + char new_pw1[MAX_KPW_LEN+1]; + char new_pw2[MAX_KPW_LEN+1]; + static struct error_table *et_list; + + set_progname(argv[0]); + + SIA_DEBUG(("siad_chg_password")); + if(collect == NULL) + return SIADFAIL; + + if(username == NULL) + username = getlogin(); + + ret = krb_parse_name(username, &princ); + if(ret) + return SIADFAIL; + if(princ.realm[0] == '\0') + krb_get_lrealm(princ.realm, 1); + + if(et_list == NULL) { + initialize_kadm_error_table_r(&et_list); + initialize_krb_error_table_r(&et_list); + } + + ret = init_change(collect, &princ); + if(ret != SIADSUCCESS) + return ret; + +again: + prompts[0].prompt = (unsigned char*)"New password: "; + prompts[0].result = (unsigned char*)new_pw1; + prompts[0].min_result_length = MIN_KPW_LEN; + prompts[0].max_result_length = sizeof(new_pw1) - 1; + prompts[0].control_flags = SIARESINVIS; + prompts[1].prompt = (unsigned char*)"Verify new password: "; + prompts[1].result = (unsigned char*)new_pw2; + prompts[1].min_result_length = MIN_KPW_LEN; + prompts[1].max_result_length = sizeof(new_pw2) - 1; + prompts[1].control_flags = SIARESINVIS; + if((*collect)(120, SIAFORM, (unsigned char*)"", 2, prompts) != + SIACOLSUCCESS) { + dest_tkt(); + return SIADFAIL; + } + if(strcmp(new_pw1, new_pw2) != 0){ + sia_message(collect, SIAWARNING, "", "Password mismatch."); + goto again; + } + ret = kadm_check_pw(new_pw1); + if(ret) { + sia_message(collect, SIAWARNING, "", com_right(et_list, ret)); + goto again; + } + + memset(new_pw2, 0, sizeof(new_pw2)); + ret = kadm_init_link (PWSERV_NAME, KRB_MASTER, princ.realm); + if (ret != KADM_SUCCESS) + sia_message(collect, SIAWARNING, "Error initing kadmin connection", + com_right(et_list, ret)); + else { + des_cblock newkey; + char *pw_msg; /* message from server */ + + des_string_to_key(new_pw1, &newkey); + ret = kadm_change_pw_plain((unsigned char*)&newkey, new_pw1, &pw_msg); + memset(newkey, 0, sizeof(newkey)); + + if (ret == KADM_INSECURE_PW) + sia_message(collect, SIAWARNING, "Insecure password", pw_msg); + else if (ret != KADM_SUCCESS) + sia_message(collect, SIAWARNING, "Error changing password", + com_right(et_list, ret)); + } + memset(new_pw1, 0, sizeof(new_pw1)); + + if (ret != KADM_SUCCESS) + sia_message(collect, SIAWARNING, "", "Password NOT changed."); + else + sia_message(collect, SIAINFO, "", "Password changed."); + + dest_tkt(); + if(ret) + return SIADFAIL; + return SIADSUCCESS; } int @@ -441,5 +608,7 @@ siad_endgrent (struct sia_context *context) int siad_chk_user (const char *logname, int checkflag) { - return SIADFAIL; + if(checkflag != CHGPASSWD) + return SIADFAIL; + return SIADSUCCESS; }