[1821] in Kerberos-V5-bugs
KDC reply: starttime=0 STILL
daemon@ATHENA.MIT.EDU (Richard Basch)
Wed Feb 28 16:02:17 1996
Date: Wed, 28 Feb 1996 16:00:51 -0500
To: tytso@MIT.EDU
Cc: krb5-bugs@MIT.EDU
From: "Richard Basch" <basch@lehman.com>
Even after your ASN.1 checkin last night, I am still experiencing the
problem where the starttime is still being interpreted as 0, and I am
getting clockskew problems. Commenting out the code in the KDC that
sets it to 0, and always returning the starttime fixes the problem for
me.
My "make" is up-to-date, and the libraries installed seem to be current.
I will recompile again later to make sure that there isn't some time
skew that occurred that created some confusion, but consider this a
heads-up. Confirmation will follow...
Included is my login module for logdaemon-5.0, which can be compiled
standalone, in case anyone else wants to test it...
Richard Basch
Sr. Developer/Analyst URL: http://web.mit.edu/basch/www/home.html
Lehman Brothers, Inc. Email: basch@lehman.com, basch@mit.edu
101 Hudson St., 33rd Floor Fax: +1-201-524-5828
Jersey City, NJ 07302-3988 Voice: +1-201-524-5049
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <errno.h>
#include <pwd.h>
#include <netdb.h>
#include <krb5.h>
#include <com_err.h>
static krb5_data tgtname = {
0,
KRB5_TGS_NAME_SIZE,
KRB5_TGS_NAME
};
int
validate_kerberos(pwd, password, ccname)
struct passwd *pwd;
char *password;
char **ccname;
{
krb5_context context;
krb5_error_code kret;
krb5_ccache ccache = NULL;
krb5_creds *my_creds;
krb5_creds *ret_cred = 0;
krb5_keytab keytab;
krb5_timestamp now;
krb5_deltat lifetime = 10 * 3600;
krb5_ticket *ticket = 0;
krb5_keytab_entry ktent;
int options = KDC_OPT_FORWARDABLE;
char *status = 0;
/* Don't try to validate root */
if (!pwd || !pwd->pw_uid) return 0;
my_creds = (krb5_creds *)calloc(1, sizeof(krb5_creds));
if (my_creds == 0) return 0;
(void) krb5_init_context(&context);
(void) krb5_init_ets(context);
(void) krb5_secure_config_files(context);
(void) memset((char *)&ktent, 0, sizeof(ktent));
kret = krb5_parse_name(context, pwd->pw_name, &my_creds->client);
if (kret) goto done;
kret = krb5_build_principal_ext(context, &my_creds->server,
krb5_princ_realm(context, my_creds->client)->length,
krb5_princ_realm(context, my_creds->client)->data,
tgtname.length, tgtname.data,
krb5_princ_realm(context, my_creds->client)->length,
krb5_princ_realm(context, my_creds->client)->data,
0);
if (kret) goto done;
kret = krb5_timeofday(context, &now);
if (kret) goto done;
my_creds->times.starttime = 0;
my_creds->times.endtime = now + lifetime;
my_creds->times.renew_till = 0;
kret = krb5_get_in_tkt_with_password(context, options, 0, 0, 0,
password, 0, my_creds, 0);
if (kret == KRB5KRB_AP_ERR_BAD_INTEGRITY) {
fprintf(stderr, "login: Kerberos password incorrect\n");
kret = -1;
goto done;
}
else if (kret) goto done;
/* Store credentials */
status = " while storing credentials.";
#ifdef TEST
*ccname = krb5_cc_default_name(context);
#else
*ccname = tempnam("/tmp", "cc5_");
#endif
kret = krb5_cc_resolve(context, *ccname, &ccache);
if (kret) goto done;
kret = krb5_cc_initialize(context, ccache, my_creds->client);
if (kret) goto done;
kret = krb5_cc_store_cred(context, ccache, my_creds);
if (kret) goto done;
#ifndef TEST
if (chown(*ccname, pwd->pw_uid, -1)) {
kret = errno;
goto done;
}
#endif
/*
* Test the credentials against a local keytab entry
*/
status = " while verifying credentials.";
(void) krb5_free_creds(context, my_creds);
my_creds = (krb5_creds *)calloc(1, sizeof(krb5_creds));
if (my_creds == 0) {
kret = errno;
goto done;
}
kret = krb5_cc_get_principal(context, ccache, &my_creds->client);
if (kret) goto done;
kret = krb5_sname_to_principal(context, NULL, NULL,
KRB5_NT_SRV_HST, &my_creds->server);
if (kret) goto done;
kret = krb5_get_credentials(context, 0, ccache, my_creds, &ret_cred);
if (kret) goto done;
kret = decode_krb5_ticket(&ret_cred->ticket, &ticket);
if (kret) goto done;
/* Get the keytab entry */
kret = krb5_kt_default(context, &keytab);
if (kret) goto done;
kret = krb5_kt_get_entry(context, keytab, ticket->server,
ticket->enc_part.kvno, ticket->enc_part.enctype, &ktent);
(void) krb5_kt_close(context, keytab);
if (kret) {
status = " while getting keytab entry.";
goto done;
}
/* Now make sure we got what we expected */
kret = krb5_decrypt_tkt_part(context, &ktent.key, ticket);
if (kret) goto done;
if (ticket->enc_part2 && krb5_principal_compare(context,
ticket->enc_part2->client,
my_creds->client)) {
kret = 0;
#ifdef TEST
fprintf(stderr, "test: Kerberos tickets verified SUCCESSFULLY.\n");
#endif
} else {
fprintf(stderr, "login: Kerberos tickets not verified\n");
kret = -1;
}
done:
(void) krb5_kt_free_entry(context, &ktent);
(void) krb5_free_creds(context, my_creds);
if (ccache)
(void) krb5_cc_close(context, ccache);
if (kret == 0) return 1;
if (kret != -1)
fprintf(stderr, "login: Kerberos error: %s%s\n",
error_message(kret), status ? status : "");
return 0;
}
#ifdef TEST
int main(argc, argv)
int argc;
char *argv[];
{
krb5_context kcontext;
char password[256];
int pwsize;
krb5_error_code kret;
char *ccname;
struct passwd *pwd;
(void) krb5_init_context(&kcontext);
(void) krb5_init_ets(kcontext);
pwsize = sizeof(password);
kret = krb5_read_password(kcontext, "Password: ", 0, password, &pwsize);
if (kret) goto error;
if (argc > 1)
pwd = getpwnam(argv[1]);
else
pwd = getpwuid(getuid());
return (!validate_kerberos(pwd, password, &ccname));
error:
fprintf(stderr, "Kerberos error: %s\n", error_message(kret));
return -1;
}
#endif