diff options
author | Marc Horowitz <marc@mit.edu> | 1996-07-22 20:49:46 +0000 |
---|---|---|
committer | Marc Horowitz <marc@mit.edu> | 1996-07-22 20:49:46 +0000 |
commit | edf8b4d8a6a665c2aa150993cd813ea6c5cf12e1 (patch) | |
tree | 6c2974a97b448c040fa4a31708ec5e02f187526c /src/lib/kadm5/chpass_util.c | |
parent | 013bb1391582ed9e653ae706e398ddb8d08cfcc9 (diff) | |
download | krb5-edf8b4d8a6a665c2aa150993cd813ea6c5cf12e1.tar.gz krb5-edf8b4d8a6a665c2aa150993cd813ea6c5cf12e1.tar.xz krb5-edf8b4d8a6a665c2aa150993cd813ea6c5cf12e1.zip |
this commit includes all the changes on the OV_9510_INTEGRATION and
OV_MERGE branches. This includes, but is not limited to, the new openvision
admin system, and major changes to gssapi to add functionality, and bring
the implementation in line with rfc1964. before committing, the
code was built and tested for netbsd and solaris.
git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@8774 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/lib/kadm5/chpass_util.c')
-rw-r--r-- | src/lib/kadm5/chpass_util.c | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/src/lib/kadm5/chpass_util.c b/src/lib/kadm5/chpass_util.c new file mode 100644 index 0000000000..dbf610ce30 --- /dev/null +++ b/src/lib/kadm5/chpass_util.c @@ -0,0 +1,229 @@ +/* + * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved. + * + * $Header$ + * + * + */ + + +#include <stdio.h> +#include <memory.h> +#include <time.h> + +#include <kadm5/admin.h> +#include "admin_internal.h" + +#include <krb5.h> + +#define string_text error_message + +/* + * Function: kadm5_chpass_principal_util + * + * Purpose: Wrapper around chpass_principal. We can read new pw, change pw and return useful messages + * + * Arguments: + * + * princ (input) a krb5b_principal structure for the + * principal whose password we should change. + * + * new_password (input) NULL or a null terminated string with the + * the principal's desired new password. If new_password + * is NULL then this routine will read a new password. + * + * pw_ret (output) if non-NULL, points to a static buffer + * containing the new password (if password is prompted + * internally), or to the new_password argument (if + * that is non-NULL). If the former, then the buffer + * is only valid until the next call to the function, + * and the caller should be sure to zero it when + * it is no longer needed. + * + * msg_ret (output) a useful message is copied here. + * + * <return value> exit status of 0 for success, else the com err code + * for the last significant routine called. + * + * Requires: + * + * A msg_ret should point to a buffer large enough for the messasge. + * + * Effects: + * + * Modifies: + * + * + */ + +kadm5_ret_t _kadm5_chpass_principal_util(void *server_handle, + void *lhandle, + krb5_principal princ, + char *new_pw, + char **ret_pw, + char *msg_ret) +{ + int code, code2, pwsize; + static char buffer[255]; + char *new_password; + kadm5_principal_ent_rec princ_ent; + kadm5_policy_ent_rec policy_ent; + + _KADM5_CHECK_HANDLE(server_handle); + + if (ret_pw) + *ret_pw = NULL; + + if (new_pw != NULL) { + new_password = new_pw; + } else { /* read the password */ + krb5_context context; + + if ((code = (int) krb5_init_context(&context)) == 0) { + pwsize = sizeof(buffer); + code = krb5_read_password(context, KADM5_PW_FIRST_PROMPT, + KADM5_PW_SECOND_PROMPT, + buffer, &pwsize); + krb5_free_context(context); + } + + if (code == 0) + new_password = buffer; + else { +#ifdef ZEROPASSWD + memset(buffer, 0, sizeof(buffer)); +#endif + if (code == KRB5_LIBOS_BADPWDMATCH) { + strcpy(msg_ret, string_text(CHPASS_UTIL_NEW_PASSWORD_MISMATCH)); + return(code); + } else { + sprintf(msg_ret, "%s %s\n%s\n", error_message(code), + string_text(CHPASS_UTIL_WHILE_READING_PASSWORD), + string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED)); + return(code); + } + } + if (pwsize == 0) { +#ifdef ZEROPASSWD + memset(buffer, 0, sizeof(buffer)); +#endif + strcpy(msg_ret, string_text(CHPASS_UTIL_NO_PASSWORD_READ)); + return(KRB5_LIBOS_CANTREADPWD); /* could do better */ + } + } + + if (ret_pw) + *ret_pw = new_password; + + code = kadm5_chpass_principal(server_handle, princ, new_password); + +#ifdef ZEROPASSWD + if (!ret_pw) + memset(buffer, 0, sizeof(buffer)); /* in case we read a new password */ +#endif + + if (code == KADM5_OK) { + strcpy(msg_ret, string_text(CHPASS_UTIL_PASSWORD_CHANGED)); + return(0); + } + + if ((code != KADM5_PASS_Q_TOOSHORT) && + (code != KADM5_PASS_REUSE) &&(code != KADM5_PASS_Q_CLASS) && + (code != KADM5_PASS_Q_DICT) && (code != KADM5_PASS_TOOSOON)) { + /* Can't get more info for other errors */ + sprintf(buffer, "%s %s", error_message(code), + string_text(CHPASS_UTIL_WHILE_TRYING_TO_CHANGE)); + sprintf(msg_ret, "%s\n%s\n", string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED), + buffer); + return(code); + } + + /* Ok, we have a password quality error. Return a good message */ + + if (code == KADM5_PASS_REUSE) { + strcpy(msg_ret, string_text(CHPASS_UTIL_PASSWORD_REUSE)); + return(code); + } + + if (code == KADM5_PASS_Q_DICT) { + strcpy(msg_ret, string_text(CHPASS_UTIL_PASSWORD_IN_DICTIONARY)); + return(code); + } + + /* Look up policy for the remaining messages */ + + code2 = kadm5_get_principal (lhandle, princ, &princ_ent, + KADM5_PRINCIPAL_NORMAL_MASK); + if (code2 != 0) { + sprintf(msg_ret, "%s %s\n%s %s\n\n%s\n ", error_message(code2), + string_text(CHPASS_UTIL_GET_PRINC_INFO), + error_message(code), + string_text(CHPASS_UTIL_WHILE_TRYING_TO_CHANGE), + string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED)); + return(code); + } + + if ((princ_ent.aux_attributes & KADM5_POLICY) == 0) { + sprintf(msg_ret, "%s %s\n\n%s", error_message(code), + string_text(CHPASS_UTIL_NO_POLICY_YET_Q_ERROR), + string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED)); + (void) kadm5_free_principal_ent(lhandle, &princ_ent); + return(code); + } + + code2 = kadm5_get_policy(lhandle, princ_ent.policy, + &policy_ent); + if (code2 != 0) { + sprintf(msg_ret, "%s %s\n%s %s\n\n%s\n ", error_message(code2), + string_text(CHPASS_UTIL_GET_POLICY_INFO), + error_message(code), + string_text(CHPASS_UTIL_WHILE_TRYING_TO_CHANGE), + string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED)); + (void) kadm5_free_principal_ent(lhandle, &princ_ent); + return(code); + } + + if (code == KADM5_PASS_Q_TOOSHORT) { + sprintf(msg_ret, string_text(CHPASS_UTIL_PASSWORD_TOO_SHORT), + policy_ent.pw_min_length); + (void) kadm5_free_principal_ent(lhandle, &princ_ent); + (void) kadm5_free_policy_ent(lhandle, &policy_ent); + return(code); + } + +/* Can't get more info for other errors */ + + if (code == KADM5_PASS_Q_CLASS) { + sprintf(msg_ret, string_text(CHPASS_UTIL_TOO_FEW_CLASSES), + policy_ent.pw_min_classes); + (void) kadm5_free_principal_ent(lhandle, &princ_ent); + (void) kadm5_free_policy_ent(lhandle, &policy_ent); + return(code); + } + + if (code == KADM5_PASS_TOOSOON) { + time_t until; + char *time_string, *ptr; + + until = princ_ent.last_pwd_change + policy_ent.pw_min_life; + + time_string = ctime(&until); + if (*(ptr = &time_string[strlen(time_string)-1]) == '\n') + *ptr = '\0'; + + sprintf(msg_ret, string_text(CHPASS_UTIL_PASSWORD_TOO_SOON), + time_string); + (void) kadm5_free_principal_ent(lhandle, &princ_ent); + (void) kadm5_free_policy_ent(lhandle, &policy_ent); + return(code); + } + + /* We should never get here, but just in case ... */ + sprintf(buffer, "%s %s", error_message(code), + string_text(CHPASS_UTIL_WHILE_TRYING_TO_CHANGE)); + sprintf(msg_ret, "%s\n%s\n", string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED), + buffer); + (void) kadm5_free_principal_ent(lhandle, &princ_ent); + (void) kadm5_free_policy_ent(lhandle, &policy_ent); + return(code); +} |