|
Packit Service |
99d1c0 |
/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
Packit Service |
99d1c0 |
/*
|
|
Packit Service |
99d1c0 |
* Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved.
|
|
Packit Service |
99d1c0 |
*/
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
#include "k5-int.h"
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
#include <kadm5/admin.h>
|
|
Packit Service |
99d1c0 |
#include "admin_internal.h"
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
#define string_text error_message
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
/*
|
|
Packit Service |
99d1c0 |
* Function: kadm5_chpass_principal_util
|
|
Packit Service |
99d1c0 |
*
|
|
Packit Service |
99d1c0 |
* Purpose: Wrapper around chpass_principal. We can read new pw, change pw and return useful messages
|
|
Packit Service |
99d1c0 |
*
|
|
Packit Service |
99d1c0 |
* Arguments:
|
|
Packit Service |
99d1c0 |
*
|
|
Packit Service |
99d1c0 |
* princ (input) a krb5b_principal structure for the
|
|
Packit Service |
99d1c0 |
* principal whose password we should change.
|
|
Packit Service |
99d1c0 |
*
|
|
Packit Service |
99d1c0 |
* new_password (input) NULL or a null terminated string with the
|
|
Packit Service |
99d1c0 |
* the principal's desired new password. If new_password
|
|
Packit Service |
99d1c0 |
* is NULL then this routine will read a new password.
|
|
Packit Service |
99d1c0 |
*
|
|
Packit Service |
99d1c0 |
* pw_ret (output) if non-NULL, points to a static buffer
|
|
Packit Service |
99d1c0 |
* containing the new password (if password is prompted
|
|
Packit Service |
99d1c0 |
* internally), or to the new_password argument (if
|
|
Packit Service |
99d1c0 |
* that is non-NULL). If the former, then the buffer
|
|
Packit Service |
99d1c0 |
* is only valid until the next call to the function,
|
|
Packit Service |
99d1c0 |
* and the caller should be sure to zero it when
|
|
Packit Service |
99d1c0 |
* it is no longer needed.
|
|
Packit Service |
99d1c0 |
*
|
|
Packit Service |
99d1c0 |
* msg_ret (output) a useful message is copied here.
|
|
Packit Service |
99d1c0 |
*
|
|
Packit Service |
99d1c0 |
* <return value> exit status of 0 for success, else the com err code
|
|
Packit Service |
99d1c0 |
* for the last significant routine called.
|
|
Packit Service |
99d1c0 |
*
|
|
Packit Service |
99d1c0 |
* Requires:
|
|
Packit Service |
99d1c0 |
*
|
|
Packit Service |
99d1c0 |
* A msg_ret should point to a buffer large enough for the messasge.
|
|
Packit Service |
99d1c0 |
*
|
|
Packit Service |
99d1c0 |
* Effects:
|
|
Packit Service |
99d1c0 |
*
|
|
Packit Service |
99d1c0 |
* Modifies:
|
|
Packit Service |
99d1c0 |
*
|
|
Packit Service |
99d1c0 |
*
|
|
Packit Service |
99d1c0 |
*/
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
kadm5_ret_t _kadm5_chpass_principal_util(void *server_handle,
|
|
Packit Service |
99d1c0 |
void *lhandle,
|
|
Packit Service |
99d1c0 |
krb5_principal princ,
|
|
Packit Service |
99d1c0 |
char *new_pw,
|
|
Packit Service |
99d1c0 |
char **ret_pw,
|
|
Packit Service |
99d1c0 |
char *msg_ret,
|
|
Packit Service |
99d1c0 |
unsigned int msg_len)
|
|
Packit Service |
99d1c0 |
{
|
|
Packit Service |
99d1c0 |
int code, code2;
|
|
Packit Service |
99d1c0 |
unsigned int pwsize;
|
|
Packit Service |
99d1c0 |
static char buffer[255];
|
|
Packit Service |
99d1c0 |
char *new_password;
|
|
Packit Service |
99d1c0 |
kadm5_principal_ent_rec princ_ent;
|
|
Packit Service |
99d1c0 |
kadm5_policy_ent_rec policy_ent;
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
_KADM5_CHECK_HANDLE(server_handle);
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
if (ret_pw)
|
|
Packit Service |
99d1c0 |
*ret_pw = NULL;
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
if (new_pw != NULL) {
|
|
Packit Service |
99d1c0 |
new_password = new_pw;
|
|
Packit Service |
99d1c0 |
} else { /* read the password */
|
|
Packit Service |
99d1c0 |
krb5_context context;
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
if ((code = (int) kadm5_init_krb5_context(&context)) == 0) {
|
|
Packit Service |
99d1c0 |
pwsize = sizeof(buffer);
|
|
Packit Service |
99d1c0 |
code = krb5_read_password(context, KADM5_PW_FIRST_PROMPT,
|
|
Packit Service |
99d1c0 |
KADM5_PW_SECOND_PROMPT,
|
|
Packit Service |
99d1c0 |
buffer, &pwsize);
|
|
Packit Service |
99d1c0 |
krb5_free_context(context);
|
|
Packit Service |
99d1c0 |
}
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
if (code == 0)
|
|
Packit Service |
99d1c0 |
new_password = buffer;
|
|
Packit Service |
99d1c0 |
else {
|
|
Packit Service |
99d1c0 |
#ifdef ZEROPASSWD
|
|
Packit Service |
99d1c0 |
memset(buffer, 0, sizeof(buffer));
|
|
Packit Service |
99d1c0 |
#endif
|
|
Packit Service |
99d1c0 |
if (code == KRB5_LIBOS_BADPWDMATCH) {
|
|
Packit Service |
99d1c0 |
strncpy(msg_ret, string_text(CHPASS_UTIL_NEW_PASSWORD_MISMATCH),
|
|
Packit Service |
99d1c0 |
msg_len - 1);
|
|
Packit Service |
99d1c0 |
msg_ret[msg_len - 1] = '\0';
|
|
Packit Service |
99d1c0 |
return(code);
|
|
Packit Service |
99d1c0 |
} else {
|
|
Packit Service |
99d1c0 |
snprintf(msg_ret, msg_len, "%s %s\n\n%s",
|
|
Packit Service |
99d1c0 |
error_message(code),
|
|
Packit Service |
99d1c0 |
string_text(CHPASS_UTIL_WHILE_READING_PASSWORD),
|
|
Packit Service |
99d1c0 |
string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED));
|
|
Packit Service |
99d1c0 |
msg_ret[msg_len - 1] = '\0';
|
|
Packit Service |
99d1c0 |
return(code);
|
|
Packit Service |
99d1c0 |
}
|
|
Packit Service |
99d1c0 |
}
|
|
Packit Service |
99d1c0 |
if (pwsize == 0) {
|
|
Packit Service |
99d1c0 |
#ifdef ZEROPASSWD
|
|
Packit Service |
99d1c0 |
memset(buffer, 0, sizeof(buffer));
|
|
Packit Service |
99d1c0 |
#endif
|
|
Packit Service |
99d1c0 |
strncpy(msg_ret, string_text(CHPASS_UTIL_NO_PASSWORD_READ), msg_len - 1);
|
|
Packit Service |
99d1c0 |
msg_ret[msg_len - 1] = '\0';
|
|
Packit Service |
99d1c0 |
return(KRB5_LIBOS_CANTREADPWD); /* could do better */
|
|
Packit Service |
99d1c0 |
}
|
|
Packit Service |
99d1c0 |
}
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
if (ret_pw)
|
|
Packit Service |
99d1c0 |
*ret_pw = new_password;
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
code = kadm5_chpass_principal(server_handle, princ, new_password);
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
#ifdef ZEROPASSWD
|
|
Packit Service |
99d1c0 |
if (!ret_pw)
|
|
Packit Service |
99d1c0 |
memset(buffer, 0, sizeof(buffer)); /* in case we read a new password */
|
|
Packit Service |
99d1c0 |
#endif
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
if (code == KADM5_OK) {
|
|
Packit Service |
99d1c0 |
strncpy(msg_ret, string_text(CHPASS_UTIL_PASSWORD_CHANGED), msg_len - 1);
|
|
Packit Service |
99d1c0 |
msg_ret[msg_len - 1] = '\0';
|
|
Packit Service |
99d1c0 |
return(0);
|
|
Packit Service |
99d1c0 |
}
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
if ((code != KADM5_PASS_Q_TOOSHORT) &&
|
|
Packit Service |
99d1c0 |
(code != KADM5_PASS_REUSE) &&(code != KADM5_PASS_Q_CLASS) &&
|
|
Packit Service |
99d1c0 |
(code != KADM5_PASS_Q_DICT) && (code != KADM5_PASS_TOOSOON)) {
|
|
Packit Service |
99d1c0 |
/* Can't get more info for other errors */
|
|
Packit Service |
99d1c0 |
snprintf(msg_ret, msg_len, "%s\n%s %s\n",
|
|
Packit Service |
99d1c0 |
string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED),
|
|
Packit Service |
99d1c0 |
error_message(code),
|
|
Packit Service |
99d1c0 |
string_text(CHPASS_UTIL_WHILE_TRYING_TO_CHANGE));
|
|
Packit Service |
99d1c0 |
return(code);
|
|
Packit Service |
99d1c0 |
}
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
/* Ok, we have a password quality error. Return a good message */
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
if (code == KADM5_PASS_REUSE) {
|
|
Packit Service |
99d1c0 |
strncpy(msg_ret, string_text(CHPASS_UTIL_PASSWORD_REUSE), msg_len - 1);
|
|
Packit Service |
99d1c0 |
msg_ret[msg_len - 1] = '\0';
|
|
Packit Service |
99d1c0 |
return(code);
|
|
Packit Service |
99d1c0 |
}
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
if (code == KADM5_PASS_Q_DICT) {
|
|
Packit Service |
99d1c0 |
strncpy(msg_ret, string_text(CHPASS_UTIL_PASSWORD_IN_DICTIONARY),
|
|
Packit Service |
99d1c0 |
msg_len - 1);
|
|
Packit Service |
99d1c0 |
msg_ret[msg_len - 1] = '\0';
|
|
Packit Service |
99d1c0 |
return(code);
|
|
Packit Service |
99d1c0 |
}
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
/* Look up policy for the remaining messages */
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
code2 = kadm5_get_principal (lhandle, princ, &princ_ent,
|
|
Packit Service |
99d1c0 |
KADM5_PRINCIPAL_NORMAL_MASK);
|
|
Packit Service |
99d1c0 |
if (code2 != 0) {
|
|
Packit Service |
99d1c0 |
snprintf(msg_ret, msg_len, "%s %s\n%s %s\n\n%s\n",
|
|
Packit Service |
99d1c0 |
error_message(code2),
|
|
Packit Service |
99d1c0 |
string_text(CHPASS_UTIL_GET_PRINC_INFO),
|
|
Packit Service |
99d1c0 |
error_message(code),
|
|
Packit Service |
99d1c0 |
string_text(CHPASS_UTIL_WHILE_TRYING_TO_CHANGE),
|
|
Packit Service |
99d1c0 |
string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED));
|
|
Packit Service |
99d1c0 |
msg_ret[msg_len - 1] = '\0';
|
|
Packit Service |
99d1c0 |
return(code);
|
|
Packit Service |
99d1c0 |
}
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
if ((princ_ent.aux_attributes & KADM5_POLICY) == 0) {
|
|
Packit Service |
99d1c0 |
/* Some module implements its own password policy. */
|
|
Packit Service |
99d1c0 |
snprintf(msg_ret, msg_len, "%s\n\n%s",
|
|
Packit Service |
99d1c0 |
error_message(code),
|
|
Packit Service |
99d1c0 |
string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED));
|
|
Packit Service |
99d1c0 |
msg_ret[msg_len - 1] = '\0';
|
|
Packit Service |
99d1c0 |
(void) kadm5_free_principal_ent(lhandle, &princ_ent);
|
|
Packit Service |
99d1c0 |
return(code);
|
|
Packit Service |
99d1c0 |
}
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
code2 = kadm5_get_policy(lhandle, princ_ent.policy,
|
|
Packit Service |
99d1c0 |
&policy_ent);
|
|
Packit Service |
99d1c0 |
if (code2 != 0) {
|
|
Packit Service |
99d1c0 |
snprintf(msg_ret, msg_len, "%s %s\n%s %s\n\n%s\n ", error_message(code2),
|
|
Packit Service |
99d1c0 |
string_text(CHPASS_UTIL_GET_POLICY_INFO),
|
|
Packit Service |
99d1c0 |
error_message(code),
|
|
Packit Service |
99d1c0 |
string_text(CHPASS_UTIL_WHILE_TRYING_TO_CHANGE),
|
|
Packit Service |
99d1c0 |
string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED));
|
|
Packit Service |
99d1c0 |
(void) kadm5_free_principal_ent(lhandle, &princ_ent);
|
|
Packit Service |
99d1c0 |
return(code);
|
|
Packit Service |
99d1c0 |
}
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
if (code == KADM5_PASS_Q_TOOSHORT) {
|
|
Packit Service |
99d1c0 |
snprintf(msg_ret, msg_len, string_text(CHPASS_UTIL_PASSWORD_TOO_SHORT),
|
|
Packit Service |
99d1c0 |
policy_ent.pw_min_length);
|
|
Packit Service |
99d1c0 |
(void) kadm5_free_principal_ent(lhandle, &princ_ent);
|
|
Packit Service |
99d1c0 |
(void) kadm5_free_policy_ent(lhandle, &policy_ent);
|
|
Packit Service |
99d1c0 |
return(code);
|
|
Packit Service |
99d1c0 |
}
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
/* Can't get more info for other errors */
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
if (code == KADM5_PASS_Q_CLASS) {
|
|
Packit Service |
99d1c0 |
snprintf(msg_ret, msg_len, string_text(CHPASS_UTIL_TOO_FEW_CLASSES),
|
|
Packit Service |
99d1c0 |
policy_ent.pw_min_classes);
|
|
Packit Service |
99d1c0 |
(void) kadm5_free_principal_ent(lhandle, &princ_ent);
|
|
Packit Service |
99d1c0 |
(void) kadm5_free_policy_ent(lhandle, &policy_ent);
|
|
Packit Service |
99d1c0 |
return(code);
|
|
Packit Service |
99d1c0 |
}
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
if (code == KADM5_PASS_TOOSOON) {
|
|
Packit Service |
99d1c0 |
time_t until;
|
|
Packit Service |
99d1c0 |
char *time_string, *ptr;
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
until = ts_incr(princ_ent.last_pwd_change, policy_ent.pw_min_life);
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
time_string = ctime(&until);
|
|
Packit Service |
99d1c0 |
if (time_string == NULL)
|
|
Packit Service |
99d1c0 |
time_string = "(error)";
|
|
Packit Service |
99d1c0 |
else if (*(ptr = &time_string[strlen(time_string)-1]) == '\n')
|
|
Packit Service |
99d1c0 |
*ptr = '\0';
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
snprintf(msg_ret, msg_len, string_text(CHPASS_UTIL_PASSWORD_TOO_SOON),
|
|
Packit Service |
99d1c0 |
time_string);
|
|
Packit Service |
99d1c0 |
(void) kadm5_free_principal_ent(lhandle, &princ_ent);
|
|
Packit Service |
99d1c0 |
(void) kadm5_free_policy_ent(lhandle, &policy_ent);
|
|
Packit Service |
99d1c0 |
return(code);
|
|
Packit Service |
99d1c0 |
}
|
|
Packit Service |
99d1c0 |
|
|
Packit Service |
99d1c0 |
/* We should never get here, but just in case ... */
|
|
Packit Service |
99d1c0 |
snprintf(msg_ret, msg_len, "%s\n%s %s\n",
|
|
Packit Service |
99d1c0 |
string_text(CHPASS_UTIL_PASSWORD_NOT_CHANGED),
|
|
Packit Service |
99d1c0 |
error_message(code),
|
|
Packit Service |
99d1c0 |
string_text(CHPASS_UTIL_WHILE_TRYING_TO_CHANGE));
|
|
Packit Service |
99d1c0 |
(void) kadm5_free_principal_ent(lhandle, &princ_ent);
|
|
Packit Service |
99d1c0 |
(void) kadm5_free_policy_ent(lhandle, &policy_ent);
|
|
Packit Service |
99d1c0 |
return(code);
|
|
Packit Service |
99d1c0 |
}
|