[5100] in Kerberos

home help back first fref pref prev next nref lref last post

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 */

home help back first fref pref prev next nref lref last post