KERBEROS and DCE INTEROPERABILITY ROUTINES

WHAT'S NEW

When k5dcecon was examining the ticket caches looking to 
update one with a newer TGT, it might update the wrong
one for the correct user.  This problem was reported by PNNL,
and is now fixed.

Any Kerberized application can now use a forwarded TGT to establish a
DCE context, or can use a previously established DCE context. This is
both a functional improvement and a performance improvement.

BACKGROUND

The MIT Kerberos 5 Release 1.x and DCE 1.1 can interoperate in a
number of ways. This is possible because:

 o DCE used Kerberos 5 internally. Based on the MIT code as of beta 4
   or so, with additional changes. 

 o The DCE security server can act as a K5 KDC, as defined in RFC 1510
   and responds on port 88. 

 o On the clients, DCE and Kerberos use the same format for the ticket
   cache, and then can share it. The KRB5CCNAME environment variable points
   at the cache.   
 
 o On the clients, DCE and Kerberos use the same format for the srvtab
   file. DCE refers to is a /krb5/v5srvtab and Kerberos as
   /etc/krb5.keytab. They can be symlinked.  

 o MIT has added many options to the krb5.conf configuration file
   which allows newer features of Release 1.0 to be turned off to match
   the earlier version of Kerberos upon which DCE is based. 

 o DCE will accept a externally obtained Kerberos TGT in place of a
   password when establishing a DCE context. 

There are some areas where they differ, including the following:
 
 o Administration of the database and the keytab files is done by the
   DCE routines, rather the the Kerberos kadmin.

 o User password changes must be done using the DCE commands. Kpasswd
   does not work. (But there are mods to Kerberos to use the v5passwd 
   with DCE.  

 o DCE goes beyond authentication only, and provides authorization via
   the PAC, and the dce-ptgt tickets stored in the cache. Thus a
   Kerberos KDC can not act as a DCE security server. 

 o A DCE cell and Kerberos realm can cross-realm authenticate, but 
   there can be no intermediate realms. (There are other problems
   in this area as well. But directly connected realms/cells do work.)

 o You can't link a module with the DCE library and the Kerberos
   library. They have conflicting routines, static data and structures.  
 
One of the main features of DCE is the Distributed File System
DFS. Access to DFS requires authentication and authorization, and when
one uses a Kerberized network utility such as telnet, a forwarded
Kerberos ticket can be used to establish the DCE context to allow
access to DFS.  


NEW TO THIS RELEASE

This release introduces sharing of a DCE context, and PAG, and allows
any Kerberized application to establish or share the context. This is
made possible by using an undocumented feature of DCE which is on at
least the Transarc and IBM releases of DCE 1.1.

I am in the process of trying to get this contributed to the general
DCE 1.2.2 release as a patch, so it could be included in other vendors
products.  HP has expressed interest in doing this, as well as the
OpenGroup if the modification is contributed. You can help by
requesting Transarc and/or IBM to submit this modification to the
OpenGroup and ask your vendor to adopt this modification.

The feature is a modification to the setpag() system call which will
allow an authorized process to set the PAG to a specific value, and
thus allow unrelated processes to share the same PAG.

This then allows the Kerberized daemons such as kshd, to exec a DCE
module which established the DCE context. Kshd then sets the
KRB5CCNAME environment variable and then issues the setpag() to use
this context. This solves the linking problem. This is done via the
k5dfspag.c routine.

The k5dfspag.c code is compiled with the lib/krb5/os routines and
included in the libkrb5. A daemon calls krb5_dfs_pag after the
krb5_kuserok has determined that the Kerberos principal and local
userid pair are acceptable. This should be done early so as to give
the daemon access to the home directory which may be located on DFS.  
If the .k5login file is used by krb5_kuserok it will need to be
accessed by the daemon and will need special ACL handling.  

The krb5_dfs_pag routine will exec the k5dcecon module to do all the
real work. Upon return, if a PAG is obtained, krb5_dfs_pag with set
the PAG for the current process to the returned PAG value. It will
also set the KRB5CCNAME environment as well. Under DCE the PAG value
is the nnnnnnn part of the name of the cache:
FILE:/opt/dcelocal/var/security/creds/dcecred_nnnnnnnn. 

The k5dcecon routine will attempt to use TGT which may have been
forwarded, to convert it to a DCE context. If there is no TGT, an
attempt will be made to join an existing PAG for the local userid, and
Kerberos principal. If there are existing PAGs, and a forwarded TGT,
k5dcecon will check the lifetime of the forwarded TGT, and if it is
less than the lifetime of the PAG, it will just join the PAG. If it
is greater, it will refresh the PAG using the forwarded TGT. 
This approach has the advantage of not requiring many new tickets from
having to be obtained, and allows one to refresh a DCE context, or use
an already established context. 

If the system also has AFS, the AFS krb5_afs_pag should be called
after the krb5_dfs_pag, since cache pointed at via the KRB5CCNAME may
have changed, such as if a DFS PAG has been joined. The AFS code does
not have the capability to join an existing AFS PAG, but can use the
same cache which might already had a
afsx/<afs.cell.name>@<k5.realm.name> service ticket.


WHAT'S IN THIS RELEASE

The k5prelogin, k5dcelogin, k5afslogin (with ak5log) were designed to
be slipped in between telnetd or klogind and login.krb5. They would
use a forwarded Kerberos ticket to establish a DCE context.  They are
the older programs which are included here. They work on all DCE
platforms, and don't take advantage of the undocumented setpag
feature. (A version of k5dcelogin is being included with DCE 1.2.2)
 
K5dcecon is the new program which can be used to create, update or
join a DCE context. k5dcecon returns KRB5CCNAME string which contains
the PAG.

k5dfspag.c is to be built in the MIT Kerberos 5 release 1.0 patchlevel
1 and added to the libkrb5. It will exec k5dcecon and upon return set
the KRB5CCNAME and PAG. Mods to Kerberized klogind, rshd, telnetd,
ftpd are available to use the k5dfspag. 

Testpag.c is a test programs to see if the PAG can be set.

The cpwkey.c routine can be used to change a key in the DCE registry,
by adding the key directly, or by setting the salt/pepper and password
or by providing the key and the pepper. This could be useful when
coping keys from a K4 or AFS database to DCE. It can also be used when
setting a DCE to K5 cross-cell key.  This program is a test program
For mass inserts, it should be rewritten to read from stdin.

K5dcelogin can also be called directly, much like dce_login.
I use the following commands in effect do the same thing as dce_login
and get a forwardable ticket, DCE context and an AFS token:

  #!/bin/csh
  # simulate a dce_login using krb5 kinit and k5dcelogin
  #
  setenv KRB5CCNAME FILE:/tmp/krb5cc_p$$
  /krb5/bin/kinit -f
  exec /krb5/sbin/k5dcelogin /krb5/sbin/k5afslogin /bin/csh
  #exec /krb5/sbin/k5dcelogin  /bin/csh

This could be useful in a mixed cell where "AS_REQ" messages are
handled by a K5 KDC, but DCE RPCs are handled by the DCE security
server.

TESTING THE SETPAG

The krb5_dfs_pag routine relies on an undocumented feature which is
in the AIX and Transarc Solaris ports of DCE and has been recently
added to the SGI version.  To test if this feature is present 
on some other DFS implementation use the testpag routine. 

The testpag routine attempts to set a PAG value to one you supply. It
uses the afs_syscall with the afs_setpag, and passes the supplied 
PAG value as the next parameter. On an unmodifed system, this 
will be ignored, and a new will be set. You should also check that
if run as a user, you cannot join a PAG owned by another user. 
When run as root, any PAG should be usable. 

On a machine with DFS running, do a dce_login to get a DCE context and
PAG. ECHO the KRB5CCNAME and look at the nnnnnnnn at the end. It
should look like an 8 char hex value, which may be 41ffxxxx on some
systems. 

Su to root and unsetenv KRB5CCNAME. Do a testpag -n nnnnnnnn where
nnnnnnnn is the PAG obtained for the above name. 

It should look like this example on an AIX 4.1.4 system:

   pembroke# ./testpag -n 63dc9997
   calling k5dcepag newpag=63dc9997
   PAG returned = 63dc9997

You will be running under a new shell with the PAG and KRB5CCNAME set.
If the PAG returned is the same as the newpag, then it worked. You can
further verify this by doing a DCE klist, cd to DFS and a DCE klist
again. The klist should show some tickets for DFS servers.

If the PAG returned is not the same, and repeated attempts show a
returned PAG decremented by 1 from the previous returned PAG, then
this system does not have the modification For example: 
 
   # ./testpag -n 41fffff9
   calling k5dcepag newpag=41fffff9
   PAG returned = 41fffff8
   # ./testpag -n 41fffff9
   calling k5dcepag newpag=41fffff9
   PAG returned = 41fffff7

In this case the syscall is ignoring the newpag parameter. 

Running it with -n 0 should get the next PAG value with or without
this modification. 

If the DFS kernel extensions are not installed, you would get
something like this:

  caliban.ctd.anl.gov% ./testpag -n 012345678
  calling k5dcepag newpag=012345678
  Setpag failed with a system error
  PAG returned = ffffffff
  Not a good pag value

If you DFS implementation does not have this modification, you could
attempt to install it yourself. But this requires source and requires
modifications to the kernel extensions. At the end of this note is an
untested sample using the DCE 1.2.2 source code. You can also contact
your system vendor and ask for this modification.

UNICOS has a similar function setppag(newpag) which can be used to set
the PAG of the parent. Contact me if you are interested. 

HOW TO INSTALL

Examine the k5dfspag.c file to make sure the DFS syscalls are correct
for your platform. See the /opt/dcelocal/share/include/dcedfs/syscall.h
on Solaris for example. 

You should build the testpag routine and make sure it works before 
adding all the other mods. If it fails you can still use the klogind
and telnetd with the k5prelogin and k5dcelogin code. 

If you intend to install with a prefix other than /krb5, change:
DPAGAIX and K5DCECON in k5dfspag.c; the three references in
k5prelogin.c; and the DESTDIR in the Makefile.

Get k5101.cdiff.xxxxxx.tar file and install the mods for ANL_DFS_PAG
and ANL_DCE to the MIT Kerberos 5 source. These mods turn on some DCE
related changes and the calls to krb5_dfs_pag. 

Symlink or copy the k5dfspag.c to the src/lib/krb5/os directory. 

Add the -DANL_DFS_PAG and -DANL_DCE flags to the configuration. 

Configure and Build the Kerberos v5. 

Modify the k5dce Makefile for your system. 

Build the k5dcecon and related programs. 

Install both the MIT Kerberos v5 and the k5dcecon and dpagaix if AIX.    

The makefile can also build k5dcelogin and k5prelogin.  The install
can install k5dcelogin, k5prelogin and update the links for login.krb5
-> k5prelogin and moving login.krb5 to login.k5. If you will be using
the k5dcecon/k5dfspag with the Kerberos mods, you don't need
k5prelogin, or the links changed, and may not need k5dcelogin.

Note that Transarc has obfuscated the entries to the lib, and 
the 1.0.3a is different from the 1.1. You may need to build two
versions of the k5dcelogin and/or k5dcecon one for each. 

AIX ONLY

The dpagaix routine is needed for AIX because of the way they do the 
syscalls. 

The following fix.aix.libdce.mk is not needed if dce 2.1.0.21
has been installed. This PTF exposed the needed entrypoints. 

The fix.aix.libdce.mk is a Makefile for AIX 4.x to add the required
external entry points to the libdce.a.  These are needed by k5dcecon
and k5dcelogin.  A bug report was submitted to IBM on this, and it was
rejected. But since DCE 1.2.2 will have a k5dcelogin, this should not
be needed with 1.2.2

Copy /usr/lib/libdce.a to /usr/libdce.a.orig before starting. Copy the
makefile to its own directory. It will create a new libdce.a which you
need to copy back to /usr/lib/libdce.a You will need to reboot the
machine.  See the /usr/lpp/dce/examples/inst/README.AIX for a similar
procedure.  IBM was not responsive in a request to have these added.

UNTESTED KERNEL EXTENSION FOR SETPAG

*** src/file/osi/,osi_pag.c  Wed Oct  2 13:03:05 1996
--- src/file/osi/osi_pag.c   Mon Jul 28 13:53:13 1997
***************
*** 293,298 ****
--- 293,302 ----
      int code;
  
      osi_MakePreemptionRight();
+    /* allow sharing of a PAG by non child processes DEE- 6/6/97 */
+    if (unused && osi_GetUID(osi_getucred()) == 0) {
+     newpag = unused;
+    } else {
      osi_mutex_enter(&osi_pagLock);
      now = osi_Time();
      soonest = osi_firstPagTime +
***************
*** 309,314 ****
--- 313,319 ----
      }
      osi_mutex_exit(&osi_pagLock);
      newpag = osi_genpag();
+    }
      osi_pcred_lock(p);
      credp = crcopy(osi_getucred());
      code = osi_SetPagInCred(credp, newpag);

Created     07/08/96
Modified    09/30/96
Modified    11/19/96
Modified    12/19/96
Modified    06/20/97
Modified    07/28/97
Modified    02/18/98

 Douglas E. Engert  <DEEngert@anl.gov>
 Argonne National Laboratory
 9700 South Cass Avenue
 Argonne, Illinois  60439 
 (630) 252-5444
