On Monday, I proposed a alternative method of obtaining and AFS PAG and token when used with OpenSSH or any other deamon.
I now have a test working using openssh-snap-20040122. This relies on an external program referred to as get-afs-token which accepts at least two parameters: -setpag - Use the AFS Kernel mods to set the AFS PAG of the parent process. -path <directory> - Get a AFS token for the cell containing this directory. The get-afs-token program would be provided by the OpenAFS or Kerberos communities, and could be a link to aklog, afslog or gssklog. I have tried this with my version of aklog, called ak5log, and with gssklog. The aklog already accepted these parameters and afslog only need a minor addition as did the gssklog. Here is the sample code used with OpenSSH. Note that the get_afs_token routine does not require any AFS or Kerberos header files. --- ./,session.c Tue Jan 20 18:00:46 2004 +++ ./session.c Fri Jan 30 11:38:02 2004 @@ -66,6 +66,10 @@ #include "ssh-gss.h" #endif +#ifdef ANL_AFS_PAG +int get_afs_token(char * pgm, char ** env, char *homedir, int setpag); +#endif + /* func */ Session *session_new(void); @@ -1419,6 +1423,14 @@ */ environ = env; +#ifdef ANL_AFS_PAG + /* Get PAG and AFS token using external program and KRB5CCNAME */ + if (options.kerberos_get_afs_token) { + debug("Getting AFS token"); + get_afs_token(NULL, env, pw->pw_dir, 1); + } +#endif + #if defined(HEIMDAL) && defined(AFS) /* * At this point, we check to see if AFS is active and if we have @@ -2216,3 +2228,119 @@ if (!use_privsep || mm_is_monitor()) session_destroy_all(session_pty_cleanup2); } + +#ifdef ANL_AFS_PAG +/* gafstoken.c + + A generic routine to get an AFS token by calling + an external program. + + This routine is generic in that it does not depend on + any specific implementation of AFS, or Kerberos. + This will allow a deamon to be configured, compiled + and linked without any AFS or Kerberos dependencies + and can thus avoid conflicts between these packages. + The resulting deamon executable can be run on a system with + or without AFS. + + Examples of external programs that could be called + are aklog, afslog, gssklog, klog, ak5log or even a script + to call one of these. + + The external program is expected to support + (or ignore) the -setpag and -path <homedir> + + Parameters to gafstoken: + + char * external_program - path to the executable + this would be set by configure, or defaulted + in some way. If NULL a built in location is used. + + char **env - Environment to run under. This + should include any environment variables needed + by the external program such as KRB5CCNAME + or X509_USER_PROXY These would have been set + by GSSAPI or PAM. If NULL, the current environment + is used. + + char * homedir - A file location, if in AFS the + external program will attempt to get a token + for the cell containing it. If NULL attempt + to get a token for the default cell of the client. + + int setpag - Used to tell external program to get + an AFS PAG. The caller's process must be a process + that will be an ancestor of the user's process. + + Returns: + -1 - some system error, see errno; + 0 - the external program if present was called and + MAY have worked. + + The caller should not need to test the return code, and should + continue with or without the AFS token or PAG. + + */ + +#ifndef _PATH_AFS_EXTERNAL_PROGRAM +#define _PATH_AFS_EXTERNAL_PROGRAM "/usr/libexec/get-afs-token" +#endif + +int +get_afs_token(char * external_program, + char ** env, + char * homedir, + int setpag) +{ + pid_t pid; + int status; + struct stat stx; + char * ppath = _PATH_AFS_EXTERNAL_PROGRAM; + char * args[5]; /* arg0, -setpag, -path, homedir, NULL */ + int argi = 0; + + if (external_program) + ppath = external_program; + + /* test if external program exists */ + if (stat(ppath, &stx)) + return 0; /* does not exist, skip getting PAG and token */ + + args[argi++] = "getafstoken"; + if (setpag) + args[argi++] = "-setpag"; + if (homedir) { + args[argi++] = "-path"; + args[argi++] = homedir; + } + args[argi] = NULL; + + if ((pid = fork()) < 0) { + return -1; /* see errno */ + } + + if (pid == 0) { + /* Don't want any output confusing the deamon */ + close(1); + open("/dev/null",O_WRONLY); + close(2); + open("/dev/null",O_WRONLY); + + if (env) + execve(ppath, args, env); + else + execv(ppath, args); + exit(127); /* exec failed! Should never get here */ + } + + while (waitpid(pid, &status, 0) < 0) { + if (errno != EINTR) + break; + } + + /* we could set a return code based on status, + * be we want to go on with or without a token */ + + return 0; +} +#endif --- ./,Makefile.in Fri Nov 21 06:48:55 2003 +++ ./Makefile.in Thu Jan 29 11:22:40 2004 @@ -22,6 +22,7 @@ [EMAIL PROTECTED]@ [EMAIL PROTECTED]@/ssh ASKPASS_PROGRAM=$(libexecdir)/ssh-askpass +AFS_EXTERNAL_PROGRAM=$(libexecdir)/get-afs-token SFTP_SERVER=$(libexecdir)/sftp-server SSH_KEYSIGN=$(libexecdir)/ssh-keysign RAND_HELPER=$(libexecdir)/ssh-rand-helper @@ -32,6 +33,7 @@ PATHS= -DSSHDIR=\"$(sysconfdir)\" \ -D_PATH_SSH_PROGRAM=\"$(SSH_PROGRAM)\" \ -D_PATH_SSH_ASKPASS_DEFAULT=\"$(ASKPASS_PROGRAM)\" \ + -D_PATH_AFS_EXTERNAL_PROGRAM=\"$(AFS_EXTERNAL_PROGRAM)\" \ -D_PATH_SFTP_SERVER=\"$(SFTP_SERVER)\" \ -D_PATH_SSH_KEY_SIGN=\"$(SSH_KEYSIGN)\" \ -D_PATH_SSH_PIDDIR=\"$(piddir)\" \ "Douglas E. Engert" wrote: > > Rather then implementing kafs in MIT Kerberos, I would like to > suggest an alternative which has advantages to all parties. > > The OpenSSH sshd needs to do two things: > (1) sets a PAG in the kernel, > (2) obtains an AFS token storing it in the kernel. > > It can use the Kerberos credentials either obtained via GSSAPI > delegation, PAM or other kerberos login code in the sshd. > > The above two actions can be accomplished by a separate process, > which can be forked and execd by the sshd and passed the environment > which may have a KREB5CCNAME pointing at the Kerberos ticket cache > Other parameters such as the home directory could also be passed. > > This would then allow simple code in OpenSSH that does not depend > on OpenAFS, Hiemdal or MIT code to fork/exec the process that does > all the work. This would be called by the process that would > eventially become the user's shell process and is run as the user. > > OpenSSH could be built on systems that may or may not have AFS > installed and run on a system with or without AFS. The decision > is based on the existence of the executable and any options > in sshd_config. > > In its simplest form, all that is needed is: > > system("/usr/ssh/libexec/aklog -setpag") > > This is a little over simplified as there should be a test if the > executable exists, processing of some return codes, making sure the > environment is set, setting some time limit. etc. But the point is > there is no compile dependence on OpenAFS, MIT or Hiemdal by the > OpenSSH sshd, and any failure of the process will not effect the sshd. > > We have been using something like this for years which issues a > syscall to set a PAG for the current process, then fork/exec ak5log. > Our current mode to OpenSSH in session.c is as simple as: > > krb5_afs_pag_env(NULL, env); > > It is currently built with the MIT Kerberos code for historic reasons, > but could be seperate as it has no real dependency on the MIT code. > > I would hope that the members of the OpenSSH community who use OpenAFS, > Hiemdal and/or MIT could agree on a simple command line interface that > would encourage the builders of OpenSSH to always have this enabled. > > -- > > Douglas E. Engert <[EMAIL PROTECTED]> > Argonne National Laboratory > 9700 South Cass Avenue > Argonne, Illinois 60439 > (630) 252-5444 -- Douglas E. Engert <[EMAIL PROTECTED]> Argonne National Laboratory 9700 South Cass Avenue Argonne, Illinois 60439 (630) 252-5444 ________________________________________________ Kerberos mailing list [EMAIL PROTECTED] https://mailman.mit.edu/mailman/listinfo/kerberos