[OpenAFS] Automatic AFS authentication on more than 1 cell

Marcus Watts mdw@umich.edu
Thu, 28 Feb 2002 06:19:28 -0500


Giovanni Bracco <bracco@frascati.enea.it> writes:
> In the implementation it would be better not to modify the pam arguments 
> but to add another file of the same type as "ThisCell" like "OtherCells" 
> containing al list of cells,comma separated. If the file does not exist 
> nothing new is performed. Does it sound reasonable?

It would be better if this were per-user.  If every user in ThisCell
exists under the same principal name in OtherCells, then why
have 2 cells?  Chances are, you have some people who are missing,
and sooner or later, unless your various system administrators coordinate
things carefully, you'll end up with duplicate names, or people with
different names in different cells.

Here at the university of michigan, we've tried to support a slightly
more flexible scheme:
each user can have a file,
	.principals
that specifies additional realms in which to get kerberos tickets.
Thid idea is to have one or more lines like this:
	# this line ignored
	@ENGIN.UMICH.EDU
	marcus@WELL.COM &
	mwatts@CYBERSPACE.ORG
Once authentication is accepted in the primary realm, login (or
whatever) can then go off & get these additional tickets,
potentially under a different name, and possibly in the background.

Here's some sample code to do this (will need some slight
fixups to work with openafs):

do_principals(whoami, principals, passwd)
	char *whoami;
	char *principals;
	char *passwd;
{
	int pass;
	char *cp;
	FILE *fp;
	char line[512];
	int passlim;
	char word[512];
	char name[MAXKTCNAMELEN], inst[MAXKTCNAMELEN];
	char cell[MAXKTCREALMLEN], realm[MAXKTCREALMLEN], lrealm[MAXKTCREALMLEN];
	char *reason;
	long password_expires;
	AFS_sigreturntype (*oldsig)();

	*lrealm = 0;
	if (!principals || !passwd) return;
	passlim = 1;
	for (pass = 0; pass < passlim; ++pass) {
		fp = fopen(principals, "r");
		if (!*lrealm &&  ka_ExpandCell((char*)0, lrealm, (int*)0))
			*lrealm = 0;
		if (!fp) break;
		while (fgets(line, sizeof line, fp)) {
			cp = getword(line, word);
			if (*word == '#') continue;
			while (*cp && isspace(*cp)) ++cp;
			ka_ParseLoginName(word, name, inst, cell);
			if (!*name) strcpy(name, whoami);
			if (!*cell) strcpy(cell, lrealm);
			else ka_ExpandCell(cell, realm, (int*)0);
			if (!strcasecmp(realm, lrealm))
				continue;
			if (pass ^ (*cp == '&'))
			{
				passlim = 2;
				continue;
			}
			if(ka_UserAuthenticateGeneral(
				   KA_USERAUTH_VERSION,
				   name, /* kerberos name */
				   inst, /* instance */
				    realm, /* realm */
				    passwd, /* password */
				    0, /* default lifetime */
				    &password_expires,
				    0, /* spare 2 */
				    &reason /* error string */
				    ))
			{
fprintf (stderr,"Cannot authenticate in %s - %s\n",
realm, reason);
			}
		}
		fclose(fp);
		if (passlim == 2)
		{
			oldsig = signal(SIGCHLD, SIG_IGN);
			if (fork())
			{
				(void) signal(SIGCHLD, oldsig);
				return;
			}
		}
	}
	if (passlim == 2) _exit(0);
}

				-Marcus Watts
				UM ITCS Umich Systems Group