diff options
Diffstat (limited to 'third_party/heimdal/appl/dceutils')
-rw-r--r-- | third_party/heimdal/appl/dceutils/ChangeLog | 39 | ||||
-rw-r--r-- | third_party/heimdal/appl/dceutils/Makefile.am | 37 | ||||
-rw-r--r-- | third_party/heimdal/appl/dceutils/NTMakefile | 35 | ||||
-rw-r--r-- | third_party/heimdal/appl/dceutils/README.dcedfs | 59 | ||||
-rw-r--r-- | third_party/heimdal/appl/dceutils/README.original | 335 | ||||
-rw-r--r-- | third_party/heimdal/appl/dceutils/dfspag.exp | 3 | ||||
-rw-r--r-- | third_party/heimdal/appl/dceutils/dpagaix.c | 23 | ||||
-rw-r--r-- | third_party/heimdal/appl/dceutils/k5dce.h | 165 | ||||
-rw-r--r-- | third_party/heimdal/appl/dceutils/k5dcecon.c | 792 | ||||
-rw-r--r-- | third_party/heimdal/appl/dceutils/testpag.c | 150 |
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"); + } + } +} |