summaryrefslogtreecommitdiffstats
path: root/third_party/heimdal/appl/dceutils
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/heimdal/appl/dceutils')
-rw-r--r--third_party/heimdal/appl/dceutils/ChangeLog39
-rw-r--r--third_party/heimdal/appl/dceutils/Makefile.am37
-rw-r--r--third_party/heimdal/appl/dceutils/NTMakefile35
-rw-r--r--third_party/heimdal/appl/dceutils/README.dcedfs59
-rw-r--r--third_party/heimdal/appl/dceutils/README.original335
-rw-r--r--third_party/heimdal/appl/dceutils/dfspag.exp3
-rw-r--r--third_party/heimdal/appl/dceutils/dpagaix.c23
-rw-r--r--third_party/heimdal/appl/dceutils/k5dce.h165
-rw-r--r--third_party/heimdal/appl/dceutils/k5dcecon.c792
-rw-r--r--third_party/heimdal/appl/dceutils/testpag.c150
10 files changed, 1638 insertions, 0 deletions
diff --git a/third_party/heimdal/appl/dceutils/ChangeLog b/third_party/heimdal/appl/dceutils/ChangeLog
new file mode 100644
index 0000000..f583aeb
--- /dev/null
+++ b/third_party/heimdal/appl/dceutils/ChangeLog
@@ -0,0 +1,39 @@
+2007-12-13 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * Makefile.am: Add missing files, from Buchan Milne.
+
+2006-08-08 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * k5dcecon.c: Check for seteuid failure, prompted by MIT advisory.
+
+2005-04-06 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * testpag.c: use NULL as last argument to execl, not 0
+
+2002-08-12 Johan Danielsson <joda@pdc.kth.se>
+
+ * Makefile.am: rename dpagaix_LDFLAGS etc to appease automake
+
+2001-08-24 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am (dpagaix): make sure of using $(EXEEXT) just to
+ please automake (this is aix-only code)
+
+2001-02-07 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am (dpagaix): needs to be linked with ld, add an
+ explicit command for it. from Ake Sandgren <ake@cs.umu.se>
+
+2000-10-02 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: link with roken on everything except irix, where
+ apperently it fails. reported by Ake Sandgren <ake@cs.umu.se>
+
+2000-07-17 Johan Danielsson <joda@pdc.kth.se>
+
+ * Makefile.am: set compiler flags
+
+2000-07-01 Assar Westerlund <assar@sics.se>
+
+ * imported stuff from Ake Sandgren <ake@cs.umu.se>
+
diff --git a/third_party/heimdal/appl/dceutils/Makefile.am b/third_party/heimdal/appl/dceutils/Makefile.am
new file mode 100644
index 0000000..6fa9d1a
--- /dev/null
+++ b/third_party/heimdal/appl/dceutils/Makefile.am
@@ -0,0 +1,37 @@
+# $Id$
+
+include $(top_srcdir)/Makefile.am.common
+
+
+DFSPROGS = k5dcecon
+if AIX
+AIX_DFSPROGS = dpagaix
+endif
+
+libexec_PROGRAMS = $(DFSPROGS) $(AIX_DFSPROGS)
+
+dpagaix_CFLAGS = $(dpagaix_cflags)
+dpagaix_LDFLAGS = $(dpagaix_ldflags)
+dpagaix_LDADD = $(dpagaix_ldadd)
+
+dpagaix$(EXEEXT): $(dpagaix_OBJECTS)
+ ld -edpagaix -o dpagaix$(EXEEXT) $(dpagaix_OBJECTS) $(srcdir)/dfspag.exp
+
+LIB_dce = -ldce
+
+k5dcecon_SOURCES = k5dcecon.c k5dce.h
+
+dpagaix_SOURCES = dpagaix.c
+
+EXTRA_DIST = \
+ NTMakefile \
+ dfspag.exp \
+ README.dcedfs \
+ README.original \
+ testpag.c
+
+if IRIX
+LDADD = $(LIB_dce)
+else
+LDADD = $(LIB_roken) $(LIB_dce)
+endif
diff --git a/third_party/heimdal/appl/dceutils/NTMakefile b/third_party/heimdal/appl/dceutils/NTMakefile
new file mode 100644
index 0000000..eb27eb4
--- /dev/null
+++ b/third_party/heimdal/appl/dceutils/NTMakefile
@@ -0,0 +1,35 @@
+########################################################################
+#
+# Copyright (c) 2009, Secure Endpoints Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# - Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+RELDIR=appl\dceutils
+
+!include ../../windows/NTMakefile.w32
+
diff --git a/third_party/heimdal/appl/dceutils/README.dcedfs b/third_party/heimdal/appl/dceutils/README.dcedfs
new file mode 100644
index 0000000..5849ad6
--- /dev/null
+++ b/third_party/heimdal/appl/dceutils/README.dcedfs
@@ -0,0 +1,59 @@
+This is a set of patches and files to get a DFS ticket from a k5 ticket.
+This code comes from Doug Engert, Argonne Nat. Lab (See dce/README.original
+for more info)
+
+The files in dce are;
+testpag: for testing if this is at all possible.
+k5dfspag: included in libkrb5
+k5dcecon: Creates (or searches for) the actual DFSPAG ticketfile.
+dpagaix: An AIX syscall stub.
+README.original: Original README file from Doug Engert
+
+
+Certain applications (rshd/telnetd) have been patched to call the
+functions in k5dfspag when the situation is right. They are ifdef
+with DCE. The patches are also originally from Doug but they
+where against MIT krb5 code and have been merged into heimdal by me.
+I will try to fix ftpd soon...
+
+There is also an ifdefs for DCE && AIX that can be used to make AIX
+use DCE for getting group/passwd entries. This is needed if one is running
+with a bare bones passwd/group file and AUTHSTATE set to DCE (This will be
+more or less clear to people doing this...) I have forced this on for now.
+
+k5dfspag.c is in lib/krb5
+k5dfspag.c is dependent on DCE only.
+It is also POSIX systems only. There are defines for the location of
+k5dcecon and dpagaix that needs a correct configure setting.
+
+k5dcecon needs no special things for the compile except whatever is needed
+on the target system to compile dce programs.
+(On aix the dce compile flags are: -D_THREAD_SAFE -D_AIX32_THREADS=1 -D_AIX41 -D_AES_SOURCE or one can use xlc_r4 if it is version 3.6.4 or later)
+
+k5dcecon wants the following libs (on aix 4.3):
+-ldce (and setenv from somewhere)
+
+dpagaix is only needed on AIX (see k5dfspag.c).
+dpagaix needs dfspag.exp and is linked with
+ld -edpagaix -o dpagaix dpagaix.o dfspag.exp
+
+
+Hope to get this into heimdal soon :-) although I know that you will have to
+change some things to get it cleanly into configure. Since I don't know the
+structure of the code (heimdal), nor enough of configure, good enough I
+just won't try it myself.
+
+One more thing, to get this to work one has to put fcache_version = x in
+krb5.conf where x = whatever the DCE implementation understands, (usually
+1 or 2).
+Thanks for adding that...
+
+
+Åke Sandgren (ake@hpc2n.umu.se)
+HPC2N
+Umeå University
+Sweden
+
+PS
+I have now added patches for configure.in and some Makefile.am's to get this
+all cleanly (I hope) into heimdal.
diff --git a/third_party/heimdal/appl/dceutils/README.original b/third_party/heimdal/appl/dceutils/README.original
new file mode 100644
index 0000000..0887023
--- /dev/null
+++ b/third_party/heimdal/appl/dceutils/README.original
@@ -0,0 +1,335 @@
+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
diff --git a/third_party/heimdal/appl/dceutils/dfspag.exp b/third_party/heimdal/appl/dceutils/dfspag.exp
new file mode 100644
index 0000000..ed39788
--- /dev/null
+++ b/third_party/heimdal/appl/dceutils/dfspag.exp
@@ -0,0 +1,3 @@
+#!/unix
+* kernel extentions used to get the pag
+kafs_syscall syscall
diff --git a/third_party/heimdal/appl/dceutils/dpagaix.c b/third_party/heimdal/appl/dceutils/dpagaix.c
new file mode 100644
index 0000000..304a9a2
--- /dev/null
+++ b/third_party/heimdal/appl/dceutils/dpagaix.c
@@ -0,0 +1,23 @@
+/*
+ * dpagaix.c
+ * On AIX we need to get the kernel extentions
+ * with the DFS kafs_syscall in it.
+ * We might be running on a system
+ * where DFS is not active.
+ * So we use this dummy routine which
+ * might not load to do the dirty work
+ *
+ * DCE does this with the /usr/lib/drivers/dfsloadobj
+ *
+ */
+
+ int dpagaix(parm1, parm2, parm3, parm4, parm5, parm6)
+ int parm1;
+ int parm2;
+ int parm3;
+ int parm4;
+ int parm5;
+ int parm6;
+ {
+ return(kafs_syscall(parm1, parm2, parm3, parm4, parm5, parm6));
+ }
diff --git a/third_party/heimdal/appl/dceutils/k5dce.h b/third_party/heimdal/appl/dceutils/k5dce.h
new file mode 100644
index 0000000..dd32865
--- /dev/null
+++ b/third_party/heimdal/appl/dceutils/k5dce.h
@@ -0,0 +1,165 @@
+/* dummy K5 routines which are needed to get this to
+ * compile without having access ti the DCE versions
+ * of the header files.
+ * Thiis is very crude, and OSF needs to expose the K5
+ * API.
+ */
+
+#ifdef sun
+/* Transarc obfuscates these routines */
+#ifdef DCE_1_1
+
+#define krb5_init_ets _dce_PkjKqOaklP
+#define krb5_copy_creds _dce_LuFxPiITzD
+#define krb5_unparse_name _dce_LWHtAuNgRV
+#define krb5_get_default_realm _dce_vDruhprWGh
+#define krb5_build_principal _dce_qwAalSzTtF
+#define krb5_build_principal_ext _dce_vhafIQlejW
+#define krb5_build_principal_va _dce_alsqToMmuJ
+#define krb5_cc_default _dce_KZRshhTXhE
+#define krb5_cc_default_name _dce_bzJVAjHXVQ
+#define sec_login_krb5_add_cred _dce_ePDtOJTZvU
+
+#else /* DCE 1.0.3a */
+
+#define krb5_init_ets _dce_BmLRpOVsBo
+#define krb5_copy_creds _dce_VGwSEBNwaf
+#define krb5_unparse_name _dce_PgAOkJoMXA
+#define krb5_get_default_realm _dce_plVOzStKyK
+#define krb5_build_principal _dce_uAKSsluIFy
+#define krb5_build_principal_ext _dce_tRMpPiRada
+#define krb5_build_principal_va _dce_SxnLejZemH
+#define krb5_cc_default _dce_SeKosWFnsv
+#define krb5_cc_default_name _dce_qJeaphJWVc
+#define sec_login_krb5_add_cred _dce_uHwRasumsN
+
+#endif
+#endif
+
+/* Define the bare minimum k5 structures which are needed
+ * by this program. Since the krb5 includes are not supplied
+ * with DCE, these were based on the MIT Kerberos 5 beta 3
+ * which should match the DCE as of 1.0.3 at least.
+ * The tricky one is the krb5_creds, since one is allocated
+ * by this program, and it needs access to the client principal
+ * in it.
+ * Note that there are no function prototypes, so there is no
+ * compile time checking.
+ * DEE 07/11/95
+ */
+#define NPROTOTYPE(x) ()
+typedef int krb5_int32; /* assuming all DCE systems are 32 bit */
+typedef short krb5short; /* assuming short is 16 bit */
+typedef krb5_int32 krb5_error_code;
+typedef unsigned char krb5_octet;
+typedef krb5_octet krb5_boolean;
+typedef krb5short krb5_keytype; /* in k5.2 it's a short */
+typedef krb5_int32 krb5_flags;
+typedef krb5_int32 krb5_timestamp; /* is a time_t in krb5.h */
+
+typedef char * krb5_pointer; /* pointer to unexposed data */
+
+typedef struct _krb5_ccache {
+ struct _krb5_cc_ops *ops;
+ krb5_pointer data;
+} *krb5_ccache;
+
+typedef struct _krb5_cc_ops {
+ char *prefix;
+ char *(*get_name) NPROTOTYPE((krb5_ccache));
+ krb5_error_code (*resolve) NPROTOTYPE((krb5_ccache *, char *));
+ krb5_error_code (*gen_new) NPROTOTYPE((krb5_ccache *));
+ krb5_error_code (*init) NPROTOTYPE((krb5_ccache, krb5_principal));
+ krb5_error_code (*destroy) NPROTOTYPE((krb5_ccache));
+ krb5_error_code (*close) NPROTOTYPE((krb5_ccache));
+ krb5_error_code (*store) NPROTOTYPE((krb5_ccache, krb5_creds *));
+ krb5_error_code (*retrieve) NPROTOTYPE((krb5_ccache, krb5_flags,
+ krb5_creds *, krb5_creds *));
+ krb5_error_code (*get_princ) NPROTOTYPE((krb5_ccache,
+ krb5_principal *));
+ krb5_error_code (*get_first) NPROTOTYPE((krb5_ccache,
+ krb5_cc_cursor *));
+ krb5_error_code (*get_next) NPROTOTYPE((krb5_ccache, krb5_cc_cursor *,
+ krb5_creds *));
+ krb5_error_code (*end_get) NPROTOTYPE((krb5_ccache, krb5_cc_cursor *));
+ krb5_error_code (*remove_cred) NPROTOTYPE((krb5_ccache, krb5_flags,
+ krb5_creds *));
+ krb5_error_code (*set_flags) NPROTOTYPE((krb5_ccache, krb5_flags));
+} krb5_cc_ops;
+
+typedef struct _krb5_keyblock {
+ krb5_keytype keytype;
+ int length;
+ krb5_octet *contents;
+} krb5_keyblock;
+
+typedef struct _krb5_ticket_times {
+ krb5_timestamp authtime;
+ krb5_timestamp starttime;
+ krb5_timestamp endtime;
+ krb5_timestamp renew_till;
+} krb5_ticket_times;
+
+typedef krb5_pointer krb5_cc_cursor;
+
+typedef struct _krb5_data {
+ int length;
+ char *data;
+} krb5_data;
+
+typedef struct _krb5_authdata {
+ int ad_type;
+ int length;
+ krb5_octet *contents;
+} krb5_authdata;
+
+typedef struct _krb5_creds {
+ krb5_pointer client;
+ krb5_pointer server;
+ krb5_keyblock keyblock;
+ krb5_ticket_times times;
+ krb5_boolean is_skey;
+ krb5_flags ticket_flags;
+ krb5_pointer **addresses;
+ krb5_data ticket;
+ krb5_data second_ticket;
+ krb5_pointer **authdata;
+} krb5_creds;
+
+typedef krb5_pointer krb5_principal;
+
+#define KRB5_CC_END 336760974
+#define KRB5_TC_OPENCLOSE 0x00000001
+
+/* Ticket flags */
+/* flags are 32 bits; each host is responsible to put the 4 bytes
+ representing these bits into net order before transmission */
+/* #define TKT_FLG_RESERVED 0x80000000 */
+#define TKT_FLG_FORWARDABLE 0x40000000
+#define TKT_FLG_FORWARDED 0x20000000
+#define TKT_FLG_PROXIABLE 0x10000000
+#define TKT_FLG_PROXY 0x08000000
+#define TKT_FLG_MAY_POSTDATE 0x04000000
+#define TKT_FLG_POSTDATED 0x02000000
+#define TKT_FLG_INVALID 0x01000000
+#define TKT_FLG_RENEWABLE 0x00800000
+#define TKT_FLG_INITIAL 0x00400000
+#define TKT_FLG_PRE_AUTH 0x00200000
+#define TKT_FLG_HW_AUTH 0x00100000
+#ifdef PK_INIT
+#define TKT_FLG_PUBKEY_PREAUTH 0x00080000
+#define TKT_FLG_DIGSIGN_PREAUTH 0x00040000
+#define TKT_FLG_PRIVKEY_PREAUTH 0x00020000
+#endif
+
+
+#define krb5_cc_get_principal(cache, principal) (*(cache)->ops->get_princ)(cache, principal)
+#define krb5_cc_set_flags(cache, flags) (*(cache)->ops->set_flags)(cache, flags)
+#define krb5_cc_get_name(cache) (*(cache)->ops->get_name)(cache)
+#define krb5_cc_start_seq_get(cache, cursor) (*(cache)->ops->get_first)(cache, cursor)
+#define krb5_cc_next_cred(cache, cursor, creds) (*(cache)->ops->get_next)(cache, cursor, creds)
+#define krb5_cc_destroy(cache) (*(cache)->ops->destroy)(cache)
+#define krb5_cc_end_seq_get(cache, cursor) (*(cache)->ops->end_get)(cache, cursor)
+
+/* end of k5 dummy typedefs */
+
diff --git a/third_party/heimdal/appl/dceutils/k5dcecon.c b/third_party/heimdal/appl/dceutils/k5dcecon.c
new file mode 100644
index 0000000..c905625
--- /dev/null
+++ b/third_party/heimdal/appl/dceutils/k5dcecon.c
@@ -0,0 +1,792 @@
+/*
+ * (c) Copyright 1995 HEWLETT-PACKARD COMPANY
+ *
+ * To anyone who acknowledges that this file is provided
+ * "AS IS" without any express or implied warranty:
+ * permission to use, copy, modify, and distribute this
+ * file for any purpose is hereby granted without fee,
+ * provided that the above copyright notice and this
+ * notice appears in all copies, and that the name of
+ * Hewlett-Packard Company not be used in advertising or
+ * publicity pertaining to distribution of the software
+ * without specific, written prior permission. Hewlett-
+ * Packard Company makes no representations about the
+ * suitability of this software for any purpose.
+ *
+ */
+/*
+ * k5dcecon - Program to convert a K5 TGT to a DCE context,
+ * for use with DFS and its PAG.
+ *
+ * The program is designed to be called as a sub process,
+ * and return via stdout the name of the cache which implies
+ * the PAG which should be used. This program itself does not
+ * use the cache or PAG itself, so the PAG in the kernel for
+ * this program may not be set.
+ *
+ * The calling program can then use the name of the cache
+ * to set the KRB5CCNAME and PAG for itself and its children.
+ *
+ * If no ticket was passed, an attemplt to join an existing
+ * PAG will be made.
+ *
+ * If a forwarded K5 TGT is passed in, either a new DCE
+ * context will be created, or an existing one will be updated.
+ * If the same ticket was already used to create an existing
+ * context, it will be joined instead.
+ *
+ * Parts of this program are based on k5dceauth,c which was
+ * given to me by HP and by the k5dcelogin.c which I developed.
+ * A slightly different version of k5dcelogin.c, was added to
+ * DCE 1.2.2
+ *
+ * D. E. Engert 6/17/97 ANL
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <locale.h>
+#include <pwd.h>
+#include <string.h>
+#include <time.h>
+
+#include <errno.h>
+#include "k5dce.h"
+
+#include <dce/sec_login.h>
+#include <dce/dce_error.h>
+#include <dce/passwd.h>
+
+/* #define DEBUG */
+#if defined(DEBUG)
+#define DEEDEBUG(A) fprintf(stderr,A); fflush(stderr)
+#define DEEDEBUG2(A,B) fprintf(stderr,A,B); fflush(stderr)
+#else
+#define DEEDEBUG(A)
+#define DEEDEBUG2(A,B)
+#endif
+
+#ifdef __hpux
+#define seteuid(A) setresuid(-1,A,-1)
+#endif
+
+
+int k5dcecreate (uid_t, char *, char*, krb5_creds **);
+int k5dcecon (uid_t, char *, char *);
+int k5dcegettgt (krb5_ccache *, char *, char *, krb5_creds **);
+int k5dcematch (uid_t, char *, char *, off_t *, krb5_creds **);
+int k5dcesession (uid_t, char *, krb5_creds **, int *,krb5_flags);
+
+
+char *progname = "k5dcecon";
+static time_t now;
+
+#ifdef notdef
+#ifdef _AIX
+/*---------------------------------------------*/
+ /* AIX with DCE 1.1 does not have the com_err in the libdce.a
+ * do a half hearted job of substituting for it.
+ */
+void com_err(char *p1, int code, ...)
+{
+ int lst;
+ dce_error_string_t err_string;
+ dce_error_inq_text(code, err_string, &lst);
+ fprintf(stderr,"Error %d in %s: %s\n", code, p1, err_string );
+}
+
+/*---------------------------------------------*/
+void krb5_init_ets()
+{
+
+}
+#endif
+#endif
+
+
+/*------------------------------------------------*/
+/* find a cache to use for our new pag */
+/* Since there is no simple way to determine which
+ * caches are associated with a pag, we will have
+ * do look around and see what makes most sense on
+ * different systems.
+ * on a Solaris system, and in the DCE source,
+ * the pags always start with a 41.
+ * this is not true on the IBM, where there does not
+ * appear to be any pattern.
+ *
+ * But since we are always certifing our creds when
+ * they are received, we can us that fact, and look
+ * at the first word of the associated data file
+ * to see that it has a "5". If not don't use.
+ */
+
+int k5dcesession(luid, pname, tgt, ppag, tflags)
+ uid_t luid;
+ char *pname;
+ krb5_creds **tgt;
+ int *ppag;
+ krb5_flags tflags;
+{
+ DIR *dirp;
+ struct dirent *direntp;
+ off_t size;
+ krb5_timestamp endtime;
+ int better = 0;
+ krb5_creds *xtgt;
+
+ char prev_name[17] = "";
+ krb5_timestamp prev_endtime;
+ off_t prev_size;
+ u_long prev_pag = 0;
+
+ char ccname[64] = "FILE:/opt/dcelocal/var/security/creds/";
+
+ error_status_t st;
+ sec_login_handle_t lcontext = 0;
+ dce_error_string_t err_string;
+ int lst;
+
+ DEEDEBUG2("k5dcesession looking for flags %8.8x\n",tflags);
+
+ dirp = opendir("/opt/dcelocal/var/security/creds/");
+ if (dirp == NULL) {
+ return 1;
+ }
+
+ while ( (direntp = readdir( dirp )) != NULL ) {
+
+/*
+ * (but root has the ffffffff which we are not interested in)
+ */
+ if (strncmp(direntp->d_name,"dcecred_",8) == 0 &&
+ (strlen(direntp->d_name) == 16)) {
+
+ /* looks like a cache name, lets do the stat, etc */
+
+ strcpy(ccname+38,direntp->d_name);
+ if (!k5dcematch(luid, pname, ccname, &size, &xtgt)) {
+
+ /* it's one of our caches, see if it is better
+ * i.e. the endtime is farther, and if the endtimes
+ * are the same, take the larger, as he who has the
+ * most tickets wins.
+ * it must also had the same set of flags at least
+ * i.e. if the forwarded TGT is forwardable, this one must
+ * be as well.
+ */
+
+ DEEDEBUG2("Cache:%s",direntp->d_name);
+ DEEDEBUG2(" size:%d",size);
+ DEEDEBUG2(" flags:%8.8x",xtgt->ticket_flags);
+ DEEDEBUG2(" %s",ctime((time_t *)&xtgt->times.endtime));
+
+ if ((xtgt->ticket_flags & tflags) == tflags ) {
+ if (prev_name[0]) {
+ if (xtgt->times.endtime > prev_endtime) {
+ better = 1;
+ } else if ((xtgt->times.endtime = prev_endtime)
+ && (size > prev_size)){
+ better = 1;
+ }
+ } else { /* the first */
+ if (xtgt->times.endtime >= now) {
+ better = 1;
+ }
+ }
+ if (better) {
+ strcpy(prev_name, direntp->d_name);
+ prev_endtime = xtgt->times.endtime;
+ prev_size = size;
+ sscanf(prev_name+8,"%8X",&prev_pag);
+ *tgt = xtgt;
+ better = 0;
+ }
+ }
+ }
+ }
+ }
+ (void)closedir( dirp );
+
+ if (!prev_name[0])
+ return 1; /* failed to find one */
+
+ DEEDEBUG2("Best: %s\n",prev_name);
+
+ if (ppag)
+ *ppag = prev_pag;
+
+ strcpy(ccname+38,prev_name);
+ setenv("KRB5CCNAME",ccname,1);
+
+ return(0);
+}
+
+
+/*----------------------------------------------*/
+/* see if this cache is for this this principal */
+
+int k5dcematch(luid, pname, ccname, sizep, tgt)
+ uid_t luid;
+ char *pname;
+ char *ccname;
+ off_t *sizep; /* size of the file */
+ krb5_creds **tgt;
+{
+
+ krb5_ccache cache;
+ struct stat stbuf;
+ char ccdata[256];
+ int fd;
+ int status;
+
+ /* DEEDEBUG2("k5dcematch called: cache=%s\n",ccname+38); */
+
+ if (strncmp(ccname,"FILE:",5) == 0) {
+
+ strcpy(ccdata,ccname+5);
+ strcat(ccdata,".data");
+
+ /* DEEDEBUG2("Checking the .data file for %s\n",ccdata); */
+
+ if (stat(ccdata, &stbuf))
+ return(1);
+
+ if (stbuf.st_uid != luid)
+ return(1);
+
+ if ((fd = open(ccdata,O_RDONLY)) == -1)
+ return(1);
+
+ if ((read(fd,&status,4)) != 4) {
+ close(fd);
+ return(1);
+ }
+
+ /* DEEDEBUG2(".data file status = %d\n", status); */
+
+ if (status != 5)
+ return(1);
+
+ if (stat(ccname+5, &stbuf))
+ return(1);
+
+ if (stbuf.st_uid != luid)
+ return(1);
+
+ *sizep = stbuf.st_size;
+ }
+
+ return(k5dcegettgt(&cache, ccname, pname, tgt));
+}
+
+
+/*----------------------------------------*/
+/* k5dcegettgt - get the tgt from a cache */
+
+int k5dcegettgt(pcache, ccname, pname, tgt)
+ krb5_ccache *pcache;
+ char *ccname;
+ char *pname;
+ krb5_creds **tgt;
+
+{
+ krb5_ccache cache;
+ krb5_cc_cursor cur;
+ krb5_creds creds;
+ int code;
+ int found = 1;
+ krb5_principal princ;
+ char *kusername;
+ krb5_flags flags;
+ char *sname, *realm, *tgtname = NULL;
+
+ /* Since DCE does not expose much of the Kerberos interface,
+ * we will have to use what we can. This means setting the
+ * KRB5CCNAME for each file we want to test
+ * We will also not worry about freeing extra cache structures
+ * as this this routine is also not exposed, and this should not
+ * effect this module.
+ * We should also free the creds contents, but that is not exposed
+ * either.
+ */
+
+ setenv("KRB5CCNAME",ccname,1);
+ cache = NULL;
+ *tgt = NULL;
+
+ if (code = krb5_cc_default(pcache)) {
+ com_err(progname, code, "while getting ccache");
+ goto return2;
+ }
+
+ DEEDEBUG("Got cache\n");
+ flags = 0;
+ if (code = krb5_cc_set_flags(*pcache, flags)) {
+ com_err(progname, code,"While setting flags");
+ goto return2;
+ }
+ DEEDEBUG("Set flags\n");
+ if (code = krb5_cc_get_principal(*pcache, &princ)) {
+ com_err(progname, code, "While getting princ");
+ goto return1;
+ }
+ DEEDEBUG("Got principal\n");
+ if (code = krb5_unparse_name(princ, &kusername)) {
+ com_err(progname, code, "While unparsing principal");
+ goto return1;
+ }
+
+ DEEDEBUG2("Unparsed to \"%s\"\n", kusername);
+ DEEDEBUG2("pname is \"%s\"\n", pname);
+ if (strcmp(kusername, pname) != 0) {
+ DEEDEBUG("Principals not equal\n");
+ goto return1;
+ }
+ DEEDEBUG("Principals equal\n");
+
+ realm = strchr(pname,'@');
+ realm++;
+
+ if ((tgtname = malloc(9 + 2 * strlen(realm))) == 0) {
+ fprintf(stderr,"Malloc failed for tgtname\n");
+ goto return1;
+ }
+
+ strcpy(tgtname,"krbtgt/");
+ strcat(tgtname,realm);
+ strcat(tgtname,"@");
+ strcat(tgtname,realm);
+
+ DEEDEBUG2("Getting tgt %s\n", tgtname);
+ if (code = krb5_cc_start_seq_get(*pcache, &cur)) {
+ com_err(progname, code, "while starting to retrieve tickets");
+ goto return1;
+ }
+
+ while (!(code = krb5_cc_next_cred(*pcache, &cur, &creds))) {
+ krb5_creds *cred = &creds;
+
+ if (code = krb5_unparse_name(cred->server, &sname)) {
+ com_err(progname, code, "while unparsing server name");
+ continue;
+ }
+
+ if (strncmp(sname, tgtname, strlen(tgtname)) == 0) {
+ DEEDEBUG("FOUND\n");
+ if (code = krb5_copy_creds(&creds, tgt)) {
+ com_err(progname, code, "while copying TGT");
+ goto return1;
+ }
+ found = 0;
+ break;
+ }
+ /* we should do a krb5_free_cred_contents(creds); */
+ }
+
+ if (code = krb5_cc_end_seq_get(*pcache, &cur)) {
+ com_err(progname, code, "while finishing retrieval");
+ goto return2;
+ }
+
+return1:
+ flags = KRB5_TC_OPENCLOSE;
+ krb5_cc_set_flags(*pcache, flags); /* force a close */
+
+return2:
+ if (tgtname)
+ free(tgtname);
+
+ return(found);
+}
+
+
+/*------------------------------------------*/
+/* Convert a forwarded TGT to a DCE context */
+int k5dcecon(luid, luser, pname)
+ uid_t luid;
+ char *luser;
+ char *pname;
+{
+
+ krb5_creds *ftgt = NULL;
+ krb5_creds *tgt = NULL;
+ unsigned32 dfspag;
+ boolean32 reset_passwd = 0;
+ int lst;
+ dce_error_string_t err_string;
+ char *shell_prog;
+ krb5_ccache fcache;
+ char *ccname;
+ char *kusername;
+ char *urealm;
+ char *cp;
+ int pag;
+ int code;
+ krb5_timestamp endtime;
+
+
+ /* If there is no cache to be converted, we should not be here */
+
+ if ((ccname = getenv("KRB5CCNAME")) == NULL) {
+ DEEDEBUG("No KRB5CCNAME\n");
+ return(1);
+ }
+
+ if (k5dcegettgt(&fcache, ccname, pname, &ftgt)) {
+ fprintf(stderr, "%s: Did not find TGT\n", progname);
+ return(1);
+ }
+
+
+ DEEDEBUG2("flags=%x\n",ftgt->ticket_flags);
+ if (!(ftgt->ticket_flags & TKT_FLG_FORWARDABLE)){
+ fprintf(stderr,"Ticket not forwardable\n");
+ return(0); /* but OK to continue */
+ }
+
+ setenv("KRB5CCNAME","",1);
+
+#define TKT_ACCEPTABLE (TKT_FLG_FORWARDABLE | TKT_FLG_PROXIABLE \
+ | TKT_FLG_MAY_POSTDATE | TKT_FLG_RENEWABLE | TKT_FLG_HW_AUTH \
+ | TKT_FLG_PRE_AUTH)
+
+ if (!k5dcesession(luid, pname, &tgt, &pag,
+ (ftgt->ticket_flags & TKT_ACCEPTABLE))) {
+ if (ftgt->times.endtime > tgt->times.endtime) {
+ DEEDEBUG("Updating existing cache\n");
+ return(k5dceupdate(&ftgt, pag));
+ } else {
+ DEEDEBUG("Using existing cache\n");
+ return(0); /* use the original one */
+ }
+ }
+ /* see if the tgts match up */
+
+ if ((code = k5dcecreate(luid, luser, pname, &ftgt))) {
+ return (code);
+ }
+
+ /*
+ * Destroy the Kerberos5 cred cache file.
+ * but don't care about the return code.
+ */
+
+ DEEDEBUG("Destroying the old cache\n");
+ if ((code = krb5_cc_destroy(fcache))) {
+ com_err(progname, code, "while destroying Kerberos5 ccache");
+ }
+ return (0);
+}
+
+
+/*--------------------------------------------------*/
+/* k5dceupdate - update the cache with a new TGT */
+/* Assumed that the KRB5CCNAME has been set */
+
+int k5dceupdate(krbtgt, pag)
+ krb5_creds **krbtgt;
+ int pag;
+{
+
+ krb5_ccache ccache;
+ int code;
+
+ if (code = krb5_cc_default(&ccache)) {
+ com_err(progname, code, "while opening cache for update");
+ return(2);
+ }
+
+ if (code = ccache->ops->init(ccache,(*krbtgt)->client)) {
+ com_err(progname, code, "while reinitilizing cache");
+ return(3);
+ }
+
+ /* krb5_cc_store_cred */
+ if (code = ccache->ops->store(ccache, *krbtgt)) {
+ com_err(progname, code, "while updating cache");
+ return(2);
+ }
+
+ sec_login_pag_new_tgt(pag, (*krbtgt)->times.endtime);
+ return(0);
+}
+/*--------------------------------------------------*/
+/* k5dcecreate - create a new DCE context */
+
+int k5dcecreate(luid, luser, pname, krbtgt)
+ uid_t luid;
+ char *luser;
+ char *pname;
+ krb5_creds **krbtgt;
+{
+
+ char *cp;
+ char *urealm;
+ char *username;
+ char *defrealm;
+ uid_t uid;
+
+ error_status_t st;
+ sec_login_handle_t lcontext = 0;
+ sec_login_auth_src_t auth_src = 0;
+ boolean32 reset_passwd = 0;
+ int lst;
+ dce_error_string_t err_string;
+
+ setenv("KRB5CCNAME","",1); /* make sure it not misused */
+
+ uid = getuid();
+ DEEDEBUG2("uid=%d\n",uid);
+
+ /* if run as root, change to user, so as to have the
+ * cache created for the local user even if cross-cell
+ * If run as a user, let standard file protection work.
+ */
+
+ if (uid == 0) {
+ if (seteuid(luid) < 0)
+ goto abort;
+ }
+
+ cp = strchr(pname,'@');
+ *cp = '\0';
+ urealm = ++cp;
+
+ DEEDEBUG2("basename=%s\n",cp);
+ DEEDEBUG2("realm=%s\n",urealm);
+
+ /* now build the username as a single string or a /.../cell/user
+ * if this is a cross cell
+ */
+
+ if ((username = malloc(7+strlen(pname)+strlen(urealm))) == 0) {
+ fprintf(stderr,"Malloc failed for username\n");
+ goto abort;
+ }
+ if (krb5_get_default_realm(&defrealm)) {
+ DEEDEBUG("krb5_get_default_realm failed\n");
+ goto abort;
+ }
+
+
+ if (strcmp(urealm,defrealm) == 0) {
+ strcpy(username,pname);
+ } else {
+ strcpy(username,"/.../");
+ strcat(username,urealm);
+ strcat(username,"/");
+ strcat(username,pname);
+ }
+
+ /*
+ * Setup a DCE login context
+ */
+
+ if (sec_login_setup_identity((unsigned_char_p_t)username,
+ (sec_login_external_tgt|sec_login_proxy_cred),
+ &lcontext, &st)) {
+ /*
+ * Add our TGT.
+ */
+ DEEDEBUG("Adding our new TGT\n");
+ sec_login_krb5_add_cred(lcontext, *krbtgt, &st);
+ if (st) {
+ dce_error_inq_text(st, err_string, &lst);
+ fprintf(stderr,
+ "Error while adding credentials for %s because %s\n",
+ username, err_string);
+ goto abort;
+ }
+ DEEDEBUG("validating and certifying\n");
+ /*
+ * Now "validate" and certify the identity,
+ * usually we would pass a password here, but...
+ * sec_login_valid_and_cert_ident
+ * sec_login_validate_identity
+ */
+
+ if (sec_login_validate_identity(lcontext, 0, &reset_passwd,
+ &auth_src, &st)) {
+ DEEDEBUG2("validate_identity st=%d\n",st);
+ if (st) {
+ dce_error_inq_text(st, err_string, &lst);
+ fprintf(stderr, "Validation error for %s because %s\n",
+ username, err_string);
+ goto abort;
+ }
+ if (!sec_login_certify_identity(lcontext,&st)) {
+ dce_error_inq_text(st, err_string, &lst);
+ fprintf(stderr,
+ "Credentials not certified because %s\n",err_string);
+ }
+ if (reset_passwd) {
+ fprintf(stderr,
+ "Password must be changed for %s\n", username);
+ }
+ if (auth_src == sec_login_auth_src_local) {
+ fprintf(stderr,
+ "Credentials obtained from local registry for %s\n",
+ username);
+ }
+ if (auth_src == sec_login_auth_src_overridden) {
+ fprintf(stderr, "Validated %s from local override entry, no network credentials obtained\n", username);
+ goto abort;
+
+ }
+ /*
+ * Actually create the cred files.
+ */
+ DEEDEBUG("Ceating new cred files.\n");
+ sec_login_set_context(lcontext, &st);
+ if (st) {
+ dce_error_inq_text(st, err_string, &lst);
+ fprintf(stderr,
+ "Unable to set context for %s because %s\n",
+ username, err_string);
+ goto abort;
+ }
+
+ /*
+ * Now free up the local context and leave the
+ * network context with its pag
+ */
+#if 0
+ sec_login_release_context(&lcontext, &st);
+ if (st) {
+ dce_error_inq_text(st, err_string, &lst);
+ fprintf(stderr,
+ "Unable to release context for %s because %s\n",
+ username, err_string);
+ goto abort;
+ }
+#endif
+ }
+ else {
+ DEEDEBUG2("validate failed %d\n",st);
+ dce_error_inq_text(st, err_string, &lst);
+ fprintf(stderr,
+ "Unable to validate %s because %s\n", username,
+ err_string);
+ goto abort;
+ }
+ }
+ else {
+ dce_error_inq_text(st, err_string, &lst);
+ fprintf(stderr,
+ "Unable to setup login entry for %s because %s\n",
+ username, err_string);
+ goto abort;
+ }
+
+ done:
+ /* if we were root, get back to root */
+
+ DEEDEBUG2("sec_login_inq_pag %8.8x\n",
+ sec_login_inq_pag(lcontext, &st));
+
+ if (uid == 0) {
+ seteuid(0);
+ }
+
+ DEEDEBUG("completed\n");
+ return(0);
+
+ abort:
+ if (uid == 0) {
+ seteuid(0);
+ }
+
+ DEEDEBUG("Aborting\n");
+ return(2);
+}
+
+
+
+/*-------------------------------------------------*/
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ int status;
+ extern int optind;
+ extern char *optarg;
+ int rv;
+
+ char *lusername = NULL;
+ char *pname = NULL;
+ int fflag = 0;
+ struct passwd *pw;
+ uid_t luid;
+ uid_t myuid;
+ char *ccname;
+ krb5_creds *tgt = NULL;
+
+#ifdef DEBUG
+ close(2);
+ open("/tmp/k5dce.debug",O_WRONLY|O_CREAT|O_APPEND, 0600);
+#endif
+
+ if (myuid = getuid()) {
+ DEEDEBUG2("UID = %d\n",myuid);
+ exit(33); /* must be root to run this, get out now */
+ }
+
+ while ((rv = getopt(argc,argv,"l:p:fs")) != -1) {
+ DEEDEBUG2("Arg = %c\n", rv);
+ switch(rv) {
+ case 'l': /* user name */
+ lusername = optarg;
+ DEEDEBUG2("Optarg = %s\n", optarg);
+ break;
+ case 'p': /* principal name */
+ pname = optarg;
+ DEEDEBUG2("Optarg = %s\n", optarg);
+ break;
+ case 'f': /* convert a forwarded TGT to a context */
+ fflag++;
+ break;
+ case 's': /* old test parameter, ignore it */
+ break;
+ }
+ }
+
+ setlocale(LC_ALL, "");
+ krb5_init_ets();
+ time(&now); /* set time to check expired tickets */
+
+ /* if lusername == NULL, Then user is passed as the USER= variable */
+
+ if (!lusername) {
+ lusername = getenv("USER");
+ if (!lusername) {
+ fprintf(stderr, "USER not in environment\n");
+ return(3);
+ }
+ }
+
+ if ((pw = getpwnam(lusername)) == NULL) {
+ fprintf(stderr, "Who are you?\n");
+ return(44);
+ }
+
+ luid = pw->pw_uid;
+
+ if (fflag) {
+ status = k5dcecon(luid, lusername, pname);
+ } else {
+ status = k5dcesession(luid, pname, &tgt, NULL, 0);
+ }
+
+ if (!status) {
+ printf("%s",getenv("KRB5CCNAME")); /* return via stdout to caller */
+ DEEDEBUG2("KRB5CCNAME=%s\n",getenv("KRB5CCNAME"));
+ }
+
+ DEEDEBUG2("Returning status %d\n",status);
+ return (status);
+}
diff --git a/third_party/heimdal/appl/dceutils/testpag.c b/third_party/heimdal/appl/dceutils/testpag.c
new file mode 100644
index 0000000..8c9bf4a
--- /dev/null
+++ b/third_party/heimdal/appl/dceutils/testpag.c
@@ -0,0 +1,150 @@
+/* Test the k5dcepag routine by setting a pag, and
+ * and execing a shell under this pag.
+ *
+ * This allows you to join a PAG which was created
+ * earlier by some other means.
+ * for example k5dcecon
+ *
+ * Must be run as root for testing only.
+ *
+ */
+
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <setjmp.h>
+#include <errno.h>
+
+#define POSIX_SETJMP
+#define POSIX_SIGNALS
+
+#ifdef POSIX_SIGNALS
+typedef struct sigaction handler;
+#define handler_init(H,F) (sigemptyset(&(H).sa_mask), \
+ (H).sa_flags=0, \
+ (H).sa_handler=(F))
+#define handler_swap(S,NEW,OLD) sigaction(S, &NEW, &OLD)
+#define handler_set(S,OLD) sigaction(S, &OLD, NULL)
+#else
+typedef sigtype (*handler)();
+#define handler_init(H,F) ((H) = (F))
+#define handler_swap(S,NEW,OLD) ((OLD) = signal ((S), (NEW)))
+
+#define handler_set(S,OLD) (signal ((S), (OLD)))
+#endif
+
+typedef void sigtype;
+
+/*
+ * We could include the dcedfs/syscall.h which should have these
+ * numbers, but it has extra baggage. So for
+ * simplicity sake now, we define these here.
+ */
+
+
+#define AFSCALL_SETPAG 2
+#define AFSCALL_GETPAG 11
+
+#if defined(sun)
+#define AFS_SYSCALL 72
+
+#elif defined(hpux)
+/* assume HPUX 10 + or is it 50 */
+#define AFS_SYSCALL 326
+
+#elif defined(_AIX)
+#define DPAGAIX "dpagaix"
+/* #define DPAGAIX "/krb5/sbin/dpagaix" */
+
+#elif defined(sgi) || defined(_sgi)
+#define AFS_SYSCALL 206+1000
+
+#else
+#define AFS_SYSCALL (Unknown_DFS_AFS_SYSCALL)
+#endif
+
+static sigjmp_buf setpag_buf;
+
+static sigtype mysig()
+{
+ siglongjmp(setpag_buf, 1);
+}
+
+
+int krb5_dfs_newpag(new_pag)
+ int new_pag;
+{
+ handler sa1, osa1;
+ handler sa2, osa2;
+ int pag = -1;
+
+ handler_init (sa1, mysig);
+ handler_init (sa2, mysig);
+ handler_swap (SIGSYS, sa1, osa1);
+ handler_swap (SIGSEGV, sa2, osa2);
+
+ if (sigsetjmp(setpag_buf, 1) == 0) {
+#if defined(_AIX)
+ int (*dpagaix)(int, int, int, int, int, int);
+
+ if (dpagaix = load(DPAGAIX, 0, 0))
+ pag = (*dpagaix)(AFSCALL_SETPAG, new_pag, 0, 0, 0, 0);
+#else
+ pag = syscall(AFS_SYSCALL,AFSCALL_SETPAG, new_pag, 0, 0, 0, 0);
+#endif
+ handler_set (SIGSYS, osa1);
+ handler_set (SIGSEGV, osa2);
+ return(pag);
+ }
+
+ fprintf(stderr,"Setpag failed with a system error\n");
+ /* syscall failed! return 0 */
+ handler_set (SIGSYS, osa1);
+ handler_set (SIGSEGV, osa2);
+ return(-1);
+}
+
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ extern int optind;
+ extern char *optarg;
+ int rv;
+ int rc;
+ unsigned int pag;
+ unsigned int newpag = 0;
+ char ccname[256];
+ int nflag = 0;
+
+ while((rv = getopt(argc,argv,"n:")) != -1) {
+ switch(rv) {
+ case 'n':
+ nflag++;
+ sscanf(optarg,"%8x",&newpag);
+ break;
+ default:
+ printf("Usage: k5dcepagt -n pag \n");
+ exit(1);
+ }
+ }
+
+ if (nflag) {
+ fprintf (stderr,"calling k5dcepag newpag=%8.8x\n",newpag);
+ pag = krb5_dfs_newpag(newpag);
+
+ fprintf (stderr,"PAG returned = %8.8x\n",pag);
+ if ((pag != 0) && (pag != -1)) {
+ sprintf (ccname,
+ "FILE:/opt/dcelocal/var/security/creds/dcecred_%8.8x",
+ pag);
+ esetenv("KRB5CCNAME",ccname,1);
+ execl("/bin/csh", "csh", NULL);
+ }
+ else {
+ fprintf(stderr," Not a good pag value\n");
+ }
+ }
+}