[6800] in Kerberos
Re: allowing multiple usernames
daemon@ATHENA.MIT.EDU (Derrick J. Brashear)
Fri Mar 1 19:04:47 1996
To: kerberos@MIT.EDU
Date: Fri, 1 Mar 1996 15:57:27 -0500
From: "Derrick J. Brashear" <shadow+@andrew.cmu.edu>
Excerpts from netnews.comp.protocols.kerberos: 1-Mar-96 Re: allowing
multiple usern.. by Dennis Putnam@atlodbs1.h
> > More specifics: one sub-domain requires a specific username format
> > (ie. sweiler1), others allow free choice (ie. samuel or weiler). I
> > don't think there are any cases where one username is used by
> > different people on different systems (happily). To gain wide acceptance,
> > free choice will have to be permitted, but the first group mentioned
> > may not go for it.
Steal the aname support from Kerberos 5, continue using many local
usernames, but map all of a user's local usernames to a single Kerberos
name. Or rather, on each group's set of machines, a file called
/etc/aname (actually presumably a database) would exist, mapping a given
kerberos name to a local username. Each group is responsible for their
own sets of mappings.
Then use something like this to let people log in with their kerberos name
#include <krb.h>
#include <ndbm.h>
#include <stdio.h>
#include <sys/file.h>
#include <strings.h>
#include <sys/syslog.h>
#include <sys/errno.h>
extern int errno;
/*
* antoln converts an authentication name into a local name by looking up
* the authentication name in the /etc/aname dbm database.
*
* If the /etc/aname file can not be opened it will set the
* local name to the principal name. Thus, in this case it performs as
* the identity function.
*
* The name instance and realm are passed to antoln through
* the AUTH_DAT structure (ad).
*/
static char lrealm[REALM_SZ] = "";
an_to_ln(ad,lname)
AUTH_DAT *ad;
char *lname;
{
static DBM *aname = NULL;
char keyname[ANAME_SZ+INST_SZ+REALM_SZ+2];
if(!(*lrealm) && (krb_get_lrealm(lrealm,1) == KFAILURE))
return(KFAILURE);
if((strcmp(ad->pinst,"") && strcmp(ad->pinst,"root")) ||
strcmp(ad->prealm,lrealm)) {
datum val;
datum key;
/*
* Non-local name (or) non-null and non-root instance.
* Look up in dbm file.
*/
if (!aname) {
if ((aname = dbm_open("/etc/aname", O_RDONLY, 0))
== NULL) return (KFAILURE);
}
/* Construct dbm lookup key. */
an_to_a(ad, keyname);
key.dptr = keyname;
key.dsize = strlen(keyname)+1;
flock(dbm_dirfno(aname), LOCK_SH);
val = dbm_fetch(aname, key);
flock(dbm_dirfno(aname), LOCK_UN);
if (!val.dptr) {
dbm_close(aname);
return(KFAILURE);
}
/* Got it! */
strcpy(lname,val.dptr);
return(KSUCCESS);
} else strcpy(lname,ad->pname);
return(KSUCCESS);
}
an_to_a(ad, str)
AUTH_DAT *ad;
char *str;
{
strcpy(str, ad->pname);
if(*ad->pinst) {
strcat(str, ".");
strcat(str, ad->pinst);
}
strcat(str, "@");
strcat(str, ad->prealm);
}
/*
* Parse a string of the form "user[.instance][@realm]"
* into a struct AUTH_DAT.
*/
a_to_an(str, ad)
AUTH_DAT *ad;
char *str;
{
char *buf = (char *)malloc(strlen(str)+1);
char *rlm, *inst, *princ;
if(!(*lrealm) && (krb_get_lrealm(lrealm,1) == KFAILURE)) {
free(buf);
return(KFAILURE);
}
/* destructive string hacking is more fun.. */
strcpy(buf, str);
if (rlm = index(buf, '@')) {
*rlm++ = '\0';
}
if (inst = index(buf, '.')) {
*inst++ = '\0';
}
strcpy(ad->pname, buf);
if(inst) strcpy(ad->pinst, inst);
else *ad->pinst = '\0';
if (rlm) strcpy(ad->prealm, rlm);
else strcpy(ad->prealm, lrealm);
free(buf);
return(KSUCCESS);
}
-D