[5100] in Kerberos
Mods to kerberize login.c
daemon@ATHENA.MIT.EDU (Mike Muuss)
Fri May 5 15:11:04 1995
Date: Fri, 5 May 95 14:47:44 EDT
From: Mike Muuss <mike@arl.mil>
To: Wolfgang Rupprecht <wolfgang@wsrcc.com>
Cc: kerberos@MIT.EDU
Wolfgang writes -
> The FAQ mentions that its possible to do xdm/login using the kerberos
> database for validating the login password (instead of using the
> second field of /etc/password or /etc/shadow). Does anyone have such
> a hacked xdm or login?
Assuming you have the source to /bin/login.c, it's pretty easy. Here
is how we do it. In the main body of login, this is done....
if (usererr == -1 && *pwd->pw_passwd != '\0') {
(void)setpriority(PRIO_PROCESS, 0, -4);
/* ARL mod for KERBEROS long passwords */
passwd = getLONGpass("Password:");
# if defined(KERBEROS)
if (pwd == &nouser)
i = -1;
else
i = krb5_login( pwd->pw_name, passwd, pwd->pw_uid );
# endif
/* Check against local /etc/passwd entry */
if (i != 0 && invalid == FALSE) {
further on,
if (invalid) {
printf("Login incorrect\n");
......
}
# if defined(KERBEROS)
if (!invalid) {
/* Only print this if login is correct */
switch(i) {
case -1:
break;
case 0:
printf("Kerberos5 Tickets Granted\n");
break;
case 1:
printf("*** Please see your system administrator to register with Kerberos5 ***\n\n");
/* invalid = TRUE; /* KERBEROS_ONLY */
break;
case 2:
printf("Unable to grant Kerberos5 tickets (password mis-match)\n");
/* invalid = TRUE; /* KERBEROS_ONLY */
break;
default:
printf("Internal error %d, please run 'kinit' to acquire Kerberos5 Tickets\n", i);
break;
}
}
# endif
And then, down at the bottom, add this modest block of code:
#if defined(KERBEROS)
/*
* Kerberos 5 Helper routine for use inside /bin/login.
* Derrived from the MIT source code to "kinit".
*
* Copyright 1990 by the Massachusetts Institute of Technology.
* All Rights Reserved.
*
* Export of this software from the United States of America may
* require a specific license from the United States Government.
* It is the responsibility of any person or organization contemplating
* export to obtain such a license before exporting.
*
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
* distribute this software and its documentation for any purpose and
* without fee is hereby granted, provided that the above copyright
* notice appear in all copies and that both that copyright notice and
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
* permission. M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
*/
#ifndef lint
static char RCSid[] = "@(#)$Header: login.c,v 1.9 94/04/09 03:46:42 mike Exp $ (ARL)";
#endif
#include <krb5/krb5.h>
#include <krb5/ext-proto.h>
#include <krb5/los-proto.h>
/*
* K R B 5 _ L O G I N
*
* Helper routine for use inside /bin/login to initialize the
* Kerberos 5 credentials cache.
*
* Since krb5_cc_initialize() is called while we are still running as
* root, the credential cache file is owned by root, and unreadable
* by the ultimate user. Change it over to him before surrendering privs.
*
* Author -
* Michael John Muuss
*
* Source -
* The U. S. Army Research Laboratory
* Aberdeen Proving Ground, Maryland 21005-5068 USA
*
* Distribution Status -
* Original work: Copyright MIT (see above).
* These modifications are Public Domain, Distribution Unlimitied.
*
* Returns -
* 0 Success
* 1 User is not a Kerberos principal
* 2 Password mis-match
* >=3 Internal error
*/
int
krb5_login( user, password, uid )
char *user;
char *password;
int uid;
{
static krb5_data tgtname = {
KRB5_TGS_NAME_SIZE,
KRB5_TGS_NAME
};
krb5_ccache ccache = NULL;
krb5_address **my_addresses;
krb5_error_code code;
krb5_principal me;
krb5_principal server;
krb5_creds my_creds;
krb5_timestamp now;
char ccname[128];
if (password == (char *)0 || password[0] == '\0') return 14;
/* Pilfer path from lib/krb5/os/ccdefname.c */
sprintf(ccname, "FILE:/tmp/krb5cc_%d", uid);
if (code = krb5_cc_resolve(ccname, &ccache)) return 3;
if (code = krb5_parse_name (user, &me)) return 4;
if (code = krb5_cc_initialize (ccache, me)) return 5;
if (chown( ccname+5, uid, 1 ) < 0) return 6;
if (code = krb5_build_principal_ext(&server,
krb5_princ_realm(me)->length,
krb5_princ_realm(me)->data,
tgtname.length, tgtname.data,
krb5_princ_realm(me)->length,
krb5_princ_realm(me)->data,
0)) return 7;
if (code = krb5_os_localaddr(&my_addresses)) return 8;
if (code = krb5_timeofday(&now)) return 9;
memset((char *)&my_creds, 0, sizeof(my_creds));
my_creds.client = me;
my_creds.server = server;
my_creds.times.starttime = 0; /* start timer now */
my_creds.times.endtime = now + 60*60*14; /* ARL: 14 hours */
my_creds.times.renew_till = 0;
/* Use encrypted timestamp preauth ONLY. kinit is too lax */
code = krb5_get_in_tkt_with_password(KDC_OPT_FORWARDABLE,
my_addresses,
KRB5_PADATA_ENC_TIMESTAMP,
ETYPE_DES_CBC_CRC,
KEYTYPE_DES,
password,
ccache,
&my_creds, 0);
krb5_free_principal(server);
krb5_free_addresses(my_addresses);
if (code == KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN) return 1;
if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY) return 2;
if (code == KRB5KDC_PREAUTH_FAILED) return 10;
if (code == KRB5KRB_ERR_GENERIC) return 11;
if (code) return 12; /* some other error */
return 0;
}
#endif /* KERBEROS */