static char rcsid[] = "$Id: kpasswd.c 17258 2005-06-21 01:36:03Z raeburn $";
#include <kadm5/admin.h>
#include <krb5.h>
#include "kpasswd_strings.h"
#define string_text error_message
#include "kpasswd.h"
#include <stdio.h>
#include <pwd.h>
#include <string.h>
extern char *whoami;
#define MISC_EXIT_STATUS 6
int
kpasswd(context, argc, argv)
krb5_context context;
int argc;
char *argv[];
{
int code;
krb5_ccache ccache = NULL;
krb5_principal princ = 0;
char *princ_str;
struct passwd *pw = 0;
unsigned int pwsize;
char password[255];
char msg_ret[1024], admin_realm[1024];
ovsec_kadm_principal_ent_t principal_entry = NULL;
ovsec_kadm_policy_ent_t policy_entry = NULL;
void *server_handle;
if (argc > 2) {
com_err(whoami, KPW_STR_USAGE, 0);
return(7);
}
if (argc == 2)
princ_str = strdup(argv[1]);
else {
code = krb5_cc_default(context, &ccache);
if (code == 0) {
code = krb5_cc_get_principal(context, ccache, &princ);
(void) krb5_cc_close(context, ccache);
if (code == 0) {
code = krb5_unparse_name(context, princ, &princ_str);
if (code != 0) {
com_err(whoami, code, string_text(KPW_STR_UNPARSE_NAME));
return(MISC_EXIT_STATUS);
}
}
}
if (code && code != KRB5_FCC_NOFILE) {
com_err(whoami, code, string_text(KPW_STR_WHILE_LOOKING_AT_CC));
return(MISC_EXIT_STATUS);
}
if (code != 0) {
pw = getpwuid( getuid());
if (pw == NULL) {
com_err(whoami, 0, string_text(KPW_STR_NOT_IN_PASSWD_FILE));
return(MISC_EXIT_STATUS);
}
princ_str = strdup(pw->pw_name);
}
}
display_intro_message(string_text(KPW_STR_CHANGING_PW_FOR), princ_str);
if (! princ) {
code = krb5_parse_name (context, princ_str, &princ);
if (code != 0) {
com_err(whoami, code, string_text(KPW_STR_PARSE_NAME), princ_str);
free(princ_str);
return(MISC_EXIT_STATUS);
}
}
pwsize = sizeof(password);
code = read_old_password(context, password, &pwsize);
if (code != 0) {
memset(password, 0, sizeof(password));
com_err(whoami, code, string_text(KPW_STR_WHILE_READING_PASSWORD));
krb5_free_principal(context, princ);
free(princ_str);
return(MISC_EXIT_STATUS);
}
if (pwsize == 0) {
memset(password, 0, sizeof(password));
com_err(whoami, 0, string_text(KPW_STR_NO_PASSWORD_READ));
krb5_free_principal(context, princ);
free(princ_str);
return(5);
}
admin_realm[0] = '\0';
strncat(admin_realm, krb5_princ_realm(context, princ)->data,
krb5_princ_realm(context, princ)->length);
code = ovsec_kadm_init(princ_str, password, KADM5_CHANGEPW_SERVICE,
admin_realm
,
OVSEC_KADM_STRUCT_VERSION,
OVSEC_KADM_API_VERSION_1,
NULL,
&server_handle);
if (code != 0) {
if (code == OVSEC_KADM_BAD_PASSWORD)
com_err(whoami, 0, string_text(KPW_STR_OLD_PASSWORD_INCORRECT));
else
com_err(whoami, 0, string_text(KPW_STR_CANT_OPEN_ADMIN_SERVER), admin_realm,
error_message(code));
krb5_free_principal(context, princ);
free(princ_str);
return((code == OVSEC_KADM_BAD_PASSWORD)?2:3);
}
code = ovsec_kadm_get_principal(server_handle, princ, &principal_entry);
if (code != 0) {
com_err(whoami, 0,
string_text((code == OVSEC_KADM_UNK_PRINC)
? KPW_STR_PRIN_UNKNOWN : KPW_STR_CANT_GET_POLICY_INFO),
princ_str);
krb5_free_principal(context, princ);
free(princ_str);
(void) ovsec_kadm_destroy(server_handle);
return((code == OVSEC_KADM_UNK_PRINC) ? 1 : MISC_EXIT_STATUS);
}
if ((principal_entry->aux_attributes & OVSEC_KADM_POLICY) != 0) {
code = ovsec_kadm_get_policy(server_handle,
principal_entry->policy, &policy_entry);
if (code != 0) {
com_err(whoami, 0,
string_text(KPW_STR_CANT_GET_POLICY_INFO), princ_str);
(void) ovsec_kadm_free_principal_ent(server_handle, principal_entry);
krb5_free_principal(context, princ);
free(princ_str);
(void) ovsec_kadm_destroy(server_handle);
return(MISC_EXIT_STATUS);
}
com_err(whoami, 0, string_text(KPW_STR_POLICY_EXPLANATION),
princ_str, principal_entry->policy,
policy_entry->pw_min_length, policy_entry->pw_min_classes);
code = ovsec_kadm_free_principal_ent(server_handle, principal_entry);
if (code) {
(void) ovsec_kadm_free_policy_ent(server_handle, policy_entry);
krb5_free_principal(context, princ);
free(princ_str);
com_err(whoami, code, string_text(KPW_STR_WHILE_FREEING_PRINCIPAL));
(void) ovsec_kadm_destroy(server_handle);
return(MISC_EXIT_STATUS);
}
code = ovsec_kadm_free_policy_ent(server_handle, policy_entry);
if (code) {
krb5_free_principal(context, princ);
free(princ_str);
com_err(whoami, code, string_text(KPW_STR_WHILE_FREEING_POLICY));
(void) ovsec_kadm_destroy(server_handle);
return(MISC_EXIT_STATUS);
}
}
else {
code = ovsec_kadm_free_principal_ent(server_handle, principal_entry);
if (code) {
krb5_free_principal(context, princ);
free(princ_str);
com_err(whoami, code, string_text(KPW_STR_WHILE_FREEING_PRINCIPAL));
(void) ovsec_kadm_destroy(server_handle);
return(MISC_EXIT_STATUS);
}
}
pwsize = sizeof(password);
code = read_new_password(server_handle, password, &pwsize, msg_ret, princ);
memset(password, 0, sizeof(password));
if (code)
com_err(whoami, 0, msg_ret);
krb5_free_principal(context, princ);
free(princ_str);
(void) ovsec_kadm_destroy(server_handle);
if (code == KRB5_LIBOS_CANTREADPWD)
return(5);
else if (code)
return(4);
else
return(0);
}