> I'm not sure it's as trivial as you think.
> 
> We have been running AFS Kerberos authenticated POP for several years and
> have noticed that after a month or so, it starts taking up to 13 seconds
> of CPU time on a Sparc 1 to 'klog' (hence also, POP authenticate).
> 
> This seems to be related to lots of token/PAG creations with no explicit
> token/PAG destructions.
> 
> With POP, all one really needs to do is authenticate - no token is
> needed.  I think this was the motivation behind some questions/answers
> on info-afs in the last two months.  The best solution I saw was
> workable, but too kludgy for me.

We used to use ka_authenticate* call. But just like you said it was becoming
too slow. We use this method for modem pool access via tacacs, ARNS access, CAP
access, and all just for the purpose of authentication. Heavy modem pool usage
made us look for an alternative. 

Below is a more straight forward way of authenticating to the AFS kaserver. It
uses direct Kerberos call. The improvement was from the order of several
seconds to under a second. The code below has #ifdef to turn on time
measurement.

The catch is that you need to have a compatible kerberos library (the right
stringtokey), have kerberos server support of port 750 (the usual kerberos
server port), and have the appropriate kerberos config files installed
(krb.conf, krb.realms). But since we already have it in the environment, it was
a simple transition for us.

Andy
-------------
int try_to_login (name,password)
char *name;
char *password;
{
  int err;
  char user[ANAME_SZ];
  char instance[INST_SZ];
  char realm[REALM_SZ];
  char *cp;
  char filename[40];

#ifdef CHECKTIMING
  struct timeb  atime,btime;
  short  timeisgood;
#endif

  /* need to check that userid is not bad. It was the case that some 
     random userid (length > limit)  got here and kname_parse just 
     blindly write to the limited user,instance,realm space causing
     coredump */

  if ( 
      (!*name || !islower(*name))       /* first character of name */
||    (!strchr(name,".") && !strchr(name,"@") && (strlen(name) >= ANAME_SZ))
||    ((cp = strchr(name,".")) && ((cp - name) >= ANAME_SZ))
||    (strlen(name) >= MAX_K_NAME_SZ)
    ){
    return(-1);
  }

  user[0] = instance[0] = realm[0] = 0;
  err = kname_parse(user,instance,realm,name);
  if (err != KSUCCESS)
    return(err);

  if (!*realm) {
    err = krb_get_lrealm(realm,1);
    if (err != KSUCCESS)
      return(err);
  }

  /* set a unique ticket file */
  sprintf(filename,"%s_tacacs_%d%d",TKT_ROOT,getpid(),time((time_t *)NULL));
  krb_set_tkt_string(filename); 
  
#ifdef CHECKTIMING
  timeisgood = ftime(&atime) == -1 ? 0:1;
#endif

  /* now check user password */
  err = krb_get_pw_in_tkt(user,instance,realm,"krbtgt",realm,1,password);
  if (err == INTK_BADPW && strlen(password) > 8) {
    /* kludge in case the system enforce 8 char limit on password */
    password[8] = '\0';
    err = krb_get_pw_in_tkt(user,instance,realm,"krbtgt",realm,1,password);
  }

#ifdef CHECKTIMING
  if (!err && timeisgood && (ftime(&btime) != -1)) {
    unsigned long   msec;

    msec = (btime.time - atime.time)*1000;
    msec += (btime.millitm - atime.millitm);
    syslog(LOG_INFO,"krb_get_pw_in_tkt(%s, %u): %lu msec",user,numtry,msec);
  }
#endif

  if (err != KSUCCESS)
    return(err);
  unlink(filename);
  return(0);
}


Reply via email to