From: Greg Hudson Date: Tue, 31 Aug 2010 01:40:19 +0000 (+0000) Subject: For the password quality interface: X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=71f887d2566241acb305158a0167fd9b7f8ac387;p=thirdparty%2Fkrb5.git For the password quality interface: * Add a languages argument to the check method to allow localization of error messages (currently no languages are ever passed, though). * Add an error code KADM5_PASS_Q_GENERIC. * In most built-in modules and the combo module, set an error message with krb5_set_error_message. git-svn-id: svn://anonsvn.mit.edu/krb5/branches/plugins2@24279 dc483132-0cff-0310-8789-dd5450dbe970 --- diff --git a/pwqual_combo/combo.c b/pwqual_combo/combo.c index 34e6daa167..1a52ef4834 100644 --- a/pwqual_combo/combo.c +++ b/pwqual_combo/combo.c @@ -135,7 +135,7 @@ combo_open(krb5_context context, const char *dict_file, static krb5_error_code combo_check(krb5_context context, krb5_pwqual_moddata data, const char *password, const char *policy_name, - krb5_principal princ) + krb5_principal princ, const char **languages) { combo_moddata dict = (combo_moddata)data; size_t i, j, len, pwlen; @@ -153,8 +153,12 @@ combo_check(krb5_context context, krb5_pwqual_moddata data, continue; remainder = password + len; for (i = 0; i < dict->word_count; i++) { - if (strcasecmp(remainder, dict->word_list[i]) == 0) + if (strcasecmp(remainder, dict->word_list[i]) == 0) { + krb5_set_error_message(context, KADM5_PASS_Q_DICT, + "Password may not be a pair of " + "dictionary words"); return KADM5_PASS_Q_DICT; + } } } diff --git a/src/include/krb5/pwqual_plugin.h b/src/include/krb5/pwqual_plugin.h index 8fe5c61b68..61f8062774 100644 --- a/src/include/krb5/pwqual_plugin.h +++ b/src/include/krb5/pwqual_plugin.h @@ -67,16 +67,24 @@ typedef krb5_error_code /* * Mandatory: Check a password for the principal princ, which has an associated * password policy named policy_name (or no associated policy if policy_name is - * NULL). Return one of the following errors if the password check fails: + * NULL). The parameter languages, if not NULL, contains a null-terminated + * list of client-specified language tags as defined in RFC 5646. The method + * should return one of the following errors if the password fails quality + * standards: * - * - KADM5_PASS_Q_TOOSHORT - * - KADM5_PASS_Q_CLASS - * - KADM5_PASS_Q_DICT + * - KADM5_PASS_Q_TOOSHORT: password should be longer + * - KADM5_PASS_Q_CLASS: password must have more character classes + * - KADM5_PASS_Q_DICT: password contains dictionary words + * - KADM5_PASS_Q_GENERIC: unspecified quality failure + * + * The module should also set an extended error message with + * krb5_set_error_message(). The message may be localized according to one of + * the language tags in languages. */ typedef krb5_error_code (*krb5_pwqual_check_fn)(krb5_context context, krb5_pwqual_moddata data, const char *password, const char *policy_name, - krb5_principal princ); + krb5_principal princ, const char **languages); /* Optional: Release resources used by module data. */ typedef void diff --git a/src/lib/kadm5/kadm_err.et b/src/lib/kadm5/kadm_err.et index a6086b1119..5530ccafa5 100644 --- a/src/lib/kadm5/kadm_err.et +++ b/src/lib/kadm5/kadm_err.et @@ -61,4 +61,5 @@ error_code KADM5_SETKEY3_ETYPE_MISMATCH, "Mismatched enctypes for setkey3" error_code KADM5_MISSING_KRB5_CONF_PARAMS, "Missing parameters in krb5.conf required for kadmin client" error_code KADM5_XDR_FAILURE, "XDR encoding error" error_code KADM5_CANT_RESOLVE, "Cannot resolve network address for admin server in requested realm" +error_code KADM5_PASS_Q_GENERIC, "Unspecified password quality failure" end diff --git a/src/lib/kadm5/srv/pwqual.c b/src/lib/kadm5/srv/pwqual.c index cc92612d05..646bfcb3c4 100644 --- a/src/lib/kadm5/srv/pwqual.c +++ b/src/lib/kadm5/srv/pwqual.c @@ -111,5 +111,5 @@ k5_pwqual_check(krb5_context context, pwqual_handle handle, krb5_principal princ) { return handle->vt.check(context, handle->data, password, policy_name, - princ); + princ, NULL); } diff --git a/src/lib/kadm5/srv/pwqual_dict.c b/src/lib/kadm5/srv/pwqual_dict.c index 18892a0e74..2df9a8b94c 100644 --- a/src/lib/kadm5/srv/pwqual_dict.c +++ b/src/lib/kadm5/srv/pwqual_dict.c @@ -214,7 +214,7 @@ dict_open(krb5_context context, const char *dict_file, static krb5_error_code dict_check(krb5_context context, krb5_pwqual_moddata data, const char *password, const char *policy_name, - krb5_principal princ) + krb5_principal princ, const char **languages) { dict_moddata dict = (dict_moddata)data; diff --git a/src/lib/kadm5/srv/pwqual_empty.c b/src/lib/kadm5/srv/pwqual_empty.c index ba25502581..df3505aaf5 100644 --- a/src/lib/kadm5/srv/pwqual_empty.c +++ b/src/lib/kadm5/srv/pwqual_empty.c @@ -35,12 +35,15 @@ static krb5_error_code empty_check(krb5_context context, krb5_pwqual_moddata data, const char *password, const char *policy_name, - krb5_principal princ) + krb5_principal princ, const char **languages) { /* Unlike other built-in modules, this one operates even for principals * with no password policy. */ - if (*password == '\0') + if (*password == '\0') { + krb5_set_error_message(context, KADM5_PASS_Q_TOOSHORT, + "Empty passwords are not allowed"); return KADM5_PASS_Q_TOOSHORT; + } return 0; } diff --git a/src/lib/kadm5/srv/pwqual_hesiod.c b/src/lib/kadm5/srv/pwqual_hesiod.c index f8862a3e2e..993992d193 100644 --- a/src/lib/kadm5/srv/pwqual_hesiod.c +++ b/src/lib/kadm5/srv/pwqual_hesiod.c @@ -94,7 +94,7 @@ str_check_gecos(char *gecos, const char *pwstr) static krb5_error_code hesiod_check(krb5_context context, krb5_pwqual_moddata data, const char *password, const char *policy_name, - krb5_principal princ) + krb5_principal princ, const char **languages) { #ifdef HESIOD extern struct passwd *hes_getpwnam(); @@ -108,12 +108,12 @@ hesiod_check(krb5_context context, krb5_pwqual_moddata data, n = krb5_princ_size(handle->context, princ); for (i = 0; i < n; i++) { - cp = krb5_princ_component(handle->context, princ, i)->data; - if (strcasecmp(cp, password) == 0) - return KADM5_PASS_Q_DICT; ent = hes_getpwnam(cp); - if (ent && ent->pw_gecos && str_check_gecos(ent->pw_gecos, password)) + if (ent && ent->pw_gecos && str_check_gecos(ent->pw_gecos, password)) { + krb5_set_error_message(context, KADM5_PASS_Q_DICT, + "Password maynot match user information."); return KADM5_PASS_Q_DICT; + } } #endif /* HESIOD */ return 0; diff --git a/src/lib/kadm5/srv/pwqual_princ.c b/src/lib/kadm5/srv/pwqual_princ.c index 06393a1b8d..dfe5f20339 100644 --- a/src/lib/kadm5/srv/pwqual_princ.c +++ b/src/lib/kadm5/srv/pwqual_princ.c @@ -35,7 +35,7 @@ static krb5_error_code princ_check(krb5_context context, krb5_pwqual_moddata data, const char *password, const char *policy_name, - krb5_principal princ) + krb5_principal princ, const char **languages) { int i, n; char *cp; @@ -51,8 +51,11 @@ princ_check(krb5_context context, krb5_pwqual_moddata data, return KADM5_PASS_Q_DICT; for (i = 0; i < n; i++) { cp = krb5_princ_component(handle->context, princ, i)->data; - if (strcasecmp(cp, password) == 0) + if (strcasecmp(cp, password) == 0) { + krb5_set_error_message(context, KADM5_PASS_Q_DICT, + "Password may not match principal name"); return KADM5_PASS_Q_DICT; + } } return 0;