/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
*/
#include "k5-int.h"
#include "com_err.h"
#include "init_creds_ctx.h"
/* Solaris Kerberos begin */
#include <admin.h>
#include <locale.h>
#include <syslog.h>
/* Solaris Kerberos end */
/*
* Solaris Kerberos:
* See the function's definition for the description of this interface.
*/
krb5_principal, char *,
krb5_prompter_fct, void *,
krb5_deltat, char *,
krb5_kdc_rep **);
void *prompter_data,
void *gak_data)
{
char *clientstr;
/* If there's already a key of the correct etype, we're done.
If the etype is wrong, free the existing key, and make
a new one.
XXX This was the old behavior, and was wrong in hw preauth
cases. Is this new behavior -- always asking -- correct in all
cases? */
}
}
return(ret);
/* PROMPTER_INVOCATION */
1, &prompt))))) {
return(ret);
}
}
return(ret);
} else {
}
return(ret);
}
const char *password)
{
char *s;
if (s == NULL)
return ENOMEM;
}
return 0;
}
char *password,
void *data,
char *in_tkt_service,
{
/*
* Solaris Kerberos:
* We call our own private function that returns the as_reply back to
* the caller. This structure contains information, such as
* key-expiration and last-req fields. Entities such as pam_krb5 can
* The original "prompter" interface is not granular enough for PAM,
* as it will perform all passes w/o coordination with other modules.
*/
}
/*
* Solaris Kerberos:
* See krb5_get_init_creds_password()'s comments for the justification of this
* private function. Caller must free ptr_as_reply if non-NULL.
*/
char *password,
void *data,
char *in_tkt_service,
{
int use_master;
int tries;
/* krb5_get_init_creds_opt *chpw_opts = NULL; */ /* Solaris Kerberos */
/* Solaris Kerberos begin */
void *server_handle;
/* Solaris Kerberos end */
use_master = 0;
goto cleanup;
}
} else {
}
/* first try: get the requested tkt from any kdc */
krb5_get_as_key_password, (void *) &pw0,
&use_master, &as_reply);
/* check for success */
if (ret == 0)
goto cleanup;
/* If all the kdc's are unavailable, or if the error was due to a
user interrupt, fail */
if ((ret == KRB5_KDC_UNREACH) ||
(ret == KRB5_LIBOS_PWDINTR) ||
(ret == KRB5_REALM_CANT_RESOLVE))
goto cleanup;
/* if the reply did not come from the master kdc, try again with
the master kdc */
if (!use_master) {
use_master = 1;
if (as_reply) {
}
/* Solaris Kerberos */
krb5_get_as_key_password, (void *) &pw0,
&use_master, &as_reply);
if (ret2 == 0) {
ret = 0;
goto cleanup;
}
/* if the master is unreachable, return the error from the
slave we were able to contact or reset the use_master flag */
if ((ret2 != KRB5_KDC_UNREACH) &&
(ret2 != KRB5_REALM_CANT_RESOLVE) &&
(ret2 != KRB5_REALM_UNKNOWN))
else {
use_master = 0;
/* Solaris - if 2nd try failed, reset 1st err msg */
}
}
}
#ifdef USE_KIM
if (ret == KRB5KDC_ERR_KEY_EXP)
goto cleanup; /* Login library will deal appropriately with this error */
#endif
/* at this point, we have an error from the master. if the error
is not password expired, or if it is but there's no prompter,
return this error */
if ((ret != KRB5KDC_ERR_KEY_EXP) ||
goto cleanup;
/* historically the default has been to prompt for password change.
* if the change password prompt option has not been set, we continue
* to prompt. Prompting is only disabled if the option has been set
* and the value has been set to false.
*/
goto cleanup;
/* ok, we have an expired password. Give the user a few chances
to change it */
/* use a minimal set of options */
sizeof(banner));
/* PROMPTER_INVOCATION */
goto cleanup;
} else {
int result_code;
&result_string)))
goto cleanup;
/* the change succeeded. go on */
if (result_code == 0) {
break;
}
/* set this in case the retry loop falls through */
if (result_code != KRB5_KPASSWD_SOFTERROR) {
goto cleanup;
}
/* the error was soft, so try again */
/* 100 is I happen to know that no code_string will be longer
than 100 chars */
(int) result_string.length,
}
}
if (ret)
goto cleanup;
/* the password change was successful. Get an initial ticket
from the master. this is the last try. the return from this
is final. */
krb5_get_as_key_password, (void *) &pw0,
&use_master, &as_reply);
/* Solaris Kerberos */
if (err_msg_1)
/* if getting the password was successful, then check to see if the
password is about to expire, and warn if so */
if (ret == 0) {
int hours;
/* XXX 7 days should be configurable. This is all pretty ad hoc,
and could probably be improved if I was willing to screw around
with timezones, etc. */
/*
* below.
*/
if (prompter &&
(!in_tkt_service ||
(hours >= 0)) {
if (hours < 1)
"Warning: Your password will expire in less than one hour.");
else if (hours <= 48)
"Warning: Your password will expire in %d hour%s.",
else
"Warning: Your password will expire in %d days.",
hours/24);
/* ignore an error here */
/* PROMPTER_INVOCATION */
} else if (prompter &&
(!in_tkt_service ||
/*
* Check the last_req fields
*/
break;
break;
if (delta < 3600)
"Warning: Your password will expire in less than one hour on %s",
ts);
"Warning: Your password will expire in %d hour%s on %s",
else
"Warning: Your password will expire in %d days on %s",
/* ignore an error here */
/* PROMPTER_INVOCATION */
}
}
}
/* Solaris Kerberos begin */
/* if (chpw_opts) */
/* krb5_get_init_creds_opt_free(context, chpw_opts); */
/* Solaris Kerberos end */
/*
* Solaris Kerberos:
* Argument, ptr_as_reply, being returned to caller if success and non-NULL.
*/
if (ptr_as_reply == NULL)
else
*ptr_as_reply = as_reply;
}
return(ret);
}
/*
Rewrites get_in_tkt in terms of newer get_init_creds API.
Attempts to get an initial ticket for creds->client to use server
creds->server, (realm is taken from creds->client), with options
options, and using creds->times.starttime, creds->times.endtime,
creds->times.renew_till as from, till, and rtime.
creds->times.renew_till is ignored unless the RENEWABLE option is requested.
If addrs is non-NULL, it is used for the addresses requested. If it is
null, the system standard addresses are used.
If password is non-NULL, it is converted using the cryptosystem entry
point for a string conversion routine, seeded with the client's name.
If password is passed as NULL, the password is read from the terminal,
and then converted into a key.
A succesful call will place the ticket in the credentials cache ccache.
returns system errors, encryption errors
*/
{
char * server;
int use_master = 0;
return EINVAL;
} else {
}
if (retval)
return (retval);
if (retval) {
return (retval);
}
if (retval) {
return (retval);
}
/* store it in the ccache! */
if (ccache)
return (retval);
return retval;
}