Initial import of KTH eBones. This has been cleaned up to only include

the "core" Kerberos functionality. The rest of the userland will get their
own changes later.
This commit is contained in:
Mark Murray 1997-09-04 06:04:33 +00:00
commit 03656ac1b0
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor-crypto/kerberosIV/dist/; revision=29085
svn path=/vendor-crypto/kerberosIV/0.9.6/; revision=29087; tag=vendor/kerberosIV/0.9.6
368 changed files with 82832 additions and 0 deletions

166
crypto/kerberosIV/COPYRIGHT Normal file
View file

@ -0,0 +1,166 @@
Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
(Royal Institute of Technology, Stockholm, Sweden).
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. 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.
3. All advertising materials mentioning features or use of this software
must display the following acknowledgement:
This product includes software developed by the Kungliga Tekniska
Högskolan and its contributors.
4. Neither the name of the Institute nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
Copyright (C) 1995 Eric Young (eay@mincom.oz.au)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the copyright
notice, this list of conditions and the following disclaimer.
2. 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.
3. All advertising materials mentioning features or use of this software
must display the following acknowledgement:
This product includes software developed by Eric Young (eay@mincom.oz.au)
THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 AUTHOR 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.
Copyright (c) 1983, 1990 The Regents of the University of California.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. 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.
3. All advertising materials mentioning features or use of this software
must display the following acknowledgement:
This product includes software developed by the University of
California, Berkeley and its contributors.
4. Neither the name of the University nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
Copyright (C) 1990 by the Massachusetts Institute of Technology
Export of this software from the United States of America is assumed
to require a specific license from the United States Government.
It is the responsibility of any person or organization contemplating
export to obtain such a license before exporting.
WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
distribute this software and its documentation for any purpose and
without fee is hereby granted, provided that the above copyright
notice appear in all copies and that both that copyright notice and
this permission notice appear in supporting documentation, and that
the name of M.I.T. not be used in advertising or publicity pertaining
to distribution of the software without specific, written prior
permission. M.I.T. makes no representations about the suitability of
this software for any purpose. It is provided "as is" without express
or implied warranty.
Copyright 1987, 1989 by the Student Information Processing Board
of the Massachusetts Institute of Technology
Permission to use, copy, modify, and distribute this software
and its documentation for any purpose and without fee is
hereby granted, provided that the above copyright notice
appear in all copies and that both that copyright notice and
this permission notice appear in supporting documentation,
and that the names of M.I.T. and the M.I.T. S.I.P.B. not be
used in advertising or publicity pertaining to distribution
of the software without specific, written prior permission.
M.I.T. and the M.I.T. S.I.P.B. make no representations about
the suitability of this software for any purpose. It is
provided "as is" without express or implied warranty.
Copyright 1992 Simmule Turner and Rich Salz. All rights reserved.
This software is not subject to any license of the American Telephone
and Telegraph Company or of the Regents of the University of California.
Permission is granted to anyone to use this software for any purpose on
any computer system, and to alter it and redistribute it freely, subject
to the following restrictions:
1. The authors are not responsible for the consequences of use of this
software, no matter how awful, even if they arise from flaws in it.
2. The origin of this software must not be misrepresented, either by
explicit claim or by omission. Since few users ever read sources,
credits must appear in the documentation.
3. Altered versions must be plainly marked as such, and must not be
misrepresented as being the original software. Since few users
ever read sources, credits must appear in the documentation.
4. This notice may not be removed or altered.

3761
crypto/kerberosIV/ChangeLog Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,70 @@
# $Id: Makefile.in,v 1.30 1997/05/20 18:58:34 bg Exp $
srcdir = @srcdir@
prefix = @prefix@
VPATH = @srcdir@
SHELL = /bin/sh
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
TRAVELKIT = appl/kauth/kauth kuser/klist appl/telnet/telnet/telnet \
appl/ftp/ftp/ftp appl/kx/kx appl/kx/rxtelnet
@SET_MAKE@
SUBDIRS = util include lib kuser server slave admin kadmin appl man doc
all:
for i in $(SUBDIRS); \
do (cd $$i && $(MAKE) $(MFLAGS) all); done
Wall:
make CFLAGS="-g -Wall -Wno-comment -Wmissing-prototypes -Wmissing-declarations -D__USE_FIXED_PROTOTYPES__"
check:
cd lib && $(MAKE) $(MFLAGS) check
install:
$(MKINSTALLDIRS) $(prefix)
for i in $(SUBDIRS); \
do (cd $$i && $(MAKE) $(MFLAGS) install); done
install-strip:
$(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' install
uninstall:
for i in $(SUBDIRS); \
do (cd $$i && $(MAKE) $(MFLAGS) uninstall); done
travelkit: all
$(MKINSTALLDIRS) tmp
for i in $(TRAVELKIT); \
do $(INSTALL_PROGRAM) $$i tmp; done
(cd tmp; tar cf ../travelkit.tar `for i in $(TRAVELKIT); do basename $$i; done`)
rm -rf tmp
travelkit-strip:
$(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' travelkit
TAGS:
find . -name '*.[chyl]' -print | etags -
clean:
for i in $(SUBDIRS); \
do (cd $$i && $(MAKE) $(MFLAGS) clean); done
mostlyclean: clean
distclean:
$(MAKE) clean
for i in $(SUBDIRS); \
do (cd $$i && $(MAKE) $(MFLAGS) distclean); done
rm -f Makefile config.status config.cache config.log version.h newversion.h.in version.h.in *~
realclean:
for i in $(SUBDIRS); \
do (cd $$i && $(MAKE) $(MFLAGS) realclean); done
.PHONY: all install install-strip uninstall travelkit travelkit-strip clean distclean realclean mostlyclean

563
crypto/kerberosIV/NEWS Normal file
View file

@ -0,0 +1,563 @@
Minor changes in release 0.9.6:
* utmp(x) works correctly on systems with utmpx.
* A security-related bug in ftpd fixed.
* Compiles on solaris 2.4, 2.6 and on WinNT/95 with cygwin32 beta18.
* New option `-w' to rxtelnet, rxterm.
Major changes in release 0.9.5:
* We made some changes to be compatible with the other kerberised ftp
implementations and this means that an old kerberised ftp client will
not be able to talk to a new ftp server. So try to upgrade your ftp
clients and servers at the same time. The reason for this change is
described in more detail below.
* The interpretation of /etc/ftpusers has changed slightly, see
ftpusers(5). These changes come from NetBSD.
* The function `des_quad_cksum', which is used by `krb_rd_safe', and
`krb_mk_safe', has never been compatible with MIT's DES
library. This has now been fixed.
This fix will however break some programs that used those functions,
for instance `ftp'. In this version `krb_rd_safe' is modified to
accept checksums of both the new and the old format; `krb_mk_safe'
will always emit checksums of the new type *unless* `krb_rd_safe'
has detected that the client is using the old checksum (this feature
may be removed in some future release).
If you have programs that use `krb_mk_safe' and `krb_rd_safe' you
should upgrade all clients before upgrading your servers. Client is
here defined as the program that first calls `krb_rd_safe'.
If you are using some protocol that talks to more than one client or
server in one session, the heuristics to detect which kind of
checksum to use might fail.
The problem with `des_quad_cksum' was just a byte-order problem, so
there are no security problems with using the old versions. Thanks
to Derrick J Brashear <shadow@DEMENTIA.ORG> for pointing in the
right general direction.
* Rewrote kx to work always open TCP connections in the same
direction. This was needed to make it work through NATs and is
generally a cleaner way of doing it. Also added `tenletxr'.
Unfortunately the new protocol is not compatible with the old one.
The new kx and kxd programs try to figure out if they are talking to
old versions.
* Quite a bit of new functionality in otp. Changed default hash
function to `md5'. Fixed implementation of SHA and added downcasing
of seed to conform with `draft-ietf-otp-01.txt'. All verification
examples in the draft now work.
* Fixed buffer overflows.
* Add history/line editing in kadmin and ftp.
* utmp/utmpx and wtmp/wtmpx might work better on strange machines.
* Bug fixes for `rsh -n' and `rcp -x'.
* reget now works in ftp and ftpd. Passive mode works. Other minor
bug fixes as well.
* New option `-g umask' to ftpd for specifying the umask for anonymous users.
* Fix for `-l' option in rxtelnet and rxterm.
* XOVER support in popper.
* Better support for building shared libraries.
* Better support for talking to the KDC over TCP. This could make it
easier to use brain-damaged firewalls.
* Support FreeBSD-style MD5 /etc/passwd.
* New option `-createuser' to afslog.
* Upgraded to work with socks5-v1.0r1.
* Almost compiles and works on OS/2 with EMX, and Win95/NT with gnu-win32.
* Merged in win32-telnet, see README-WIN32 for more details.
* Possibly fixed telnet bug on HP-UX 10.
* Updated man-pages.
* Support for NetBSD/OpenBSD manual page circus.
* Bug fixes.
Major changes in release 0.9.3:
* kx has been rewritten and is now a lot easier to use. Two new
scripts: rxtelnet and rxterm. It also works on machines such as
Cray where the X-libraries cannot talk unix sockets.
* experimental OTP (RFC1938). Included in login, ftpd, and popper.
* authentication modules: PAM for linux, SIA for OSF/1, and
afskauthlib for Irix.
* popper now has the UIDL command.
* ftpd can now tar and compress files and directories on the fly, also
added a find site command.
* updated documentation and man pages.
* Change kuserok so that it acts as if luser@LOCALREALM is always an
entry of .klogin, even when it's not possible to verify that there
is no such file or the file is unreadable.
* Support for SRV-records.
* Socks v5 support.
* rcp is AFS-aware.
* allow for other transport mechanisms than udp (useful for firewall
tormented souls); as a side effect the format of krb.conf had to
become more flexible
* sample programs included.
* work arounds for Linux networking bugs in rlogind and rlogin.
* more portable
* quite a number of improvments/bugfixes
* New platforms: HP-UX 10, Irix 6.2
Major changes in release 0.9.2a:
* fix annoying bug with kauth (et al) returning incorrect error
Major changes in release 0.9.2:
* service `kerberos-iv' and port 750 has been registered with IANA.
* Bugfixes.
- Compiles with gcc on AIX.
- Compiles with really old resolvers.
- ftp works with afs string-to-key.
- shared libraries should work on Linux/ELF.
- some potential buffer overruns.
- general code clean-up.
* Better Cray/UNICOS support.
* New platforms: AIX 4.2, IRIX 6.1, and Linux 2.0
Major changes in release 0.9.1:
* Mostly bugfixes.
- No hardcoded references to /usr/athena
- Better Linux support with rlogin
- Fix for broken handling of NULL password in kadmind (such as with
`ksrvutil change')
- AFS-aware programs should work on AIX systems without AFS
* New platforms: Digital UNIX 4.0 and Fujitsu UXP/V
* New mechanism to determine realm from hostname based on DNS. To find
the realm of a.b.c.d it tries to find krb4-realm.a.b.c.d and then
krb4-realm.b.c.d and so on. The entry in DNS should be a TXT record
with the realm name.
krb4-realm.pdc.kth.se. 7200 TXT "NADA.KTH.SE"
Major changes in release 0.9:
* Tested platforms:
Dec Alpha OSF/1 3.2 with cc -std1
HP 9000/735 HP/UX 9.05 with gcc
DEC Pmax Ultrix 4.4 with gcc (cc does not work)
IBM RS/6000 AIX 4.1 with xlc (gcc works, cc does not)
SGI IRIX 5.3 with cc
Sun SunOS 4.1.4 with gcc (cc is not ANSI and does not work)
Sun SunOS 5.5 with gcc
Intel i386 NetBSD 1.2 with gcc
Intel i386 Linux 1.3.95 with gcc
Cray J90 Unicos 9 with cc
* Mostly ported to Crays running Unicos 9.
* S/Key-support in ftpd.
* Delete operation supported in kerberos database.
* Cleaner and more portable code.
* Even less bugs than before.
* kpopper now supports the old pop3 protocol and has been renamed to popper.
* rsh can be renamed remsh.
* Experimental program for forwarding IP over a kerberos tunnel.
* Updated to libdes 3.23.
Major changes in release 0.8:
* New programs: ftp & ftpd.
* New programs: kx & kxd. These programs forward X connections over
kerberos-encrypted connections.
* Incorporated version 3.21 of libdes.
* login: No double utmp-entries on Solaris.
* kafs
* Better guessing of what realm a cell belongs to.
* Support for authenticating to several cells. Reads
/usr/vice/etc/TheseCells, if present.
* ksrvutil: Support for generating AFS keys.
* login, su, rshd, rlogind: tries to counter possible NIS-attack.
* xnlock: several bug fixes and support for more than one screen.
* Default port number for ekshell changed from 2106 to 545. kauth
port changed from 4711 to 2120.
* Rumored to work on Fujitsu UXP/V and Cray UNICOS.
Major changes in release 0.7:
* New experimental masterkey generation. Enable with
--enable-random-mkey. Also the default place for the master key has
moved from /.k to /var/kerberos/master-key. This is customizable
with --with-mkey=file. If you don't want you master key to be on the
same backup medium as your database, remember to use this flag. All
relevant programs still checks for /.k.
* `-t' option to kadmin.
* Kpopper uses kuserok to verify if user is allowed to pop mail.
* Kpopper tries to locate the mail spool directory: /var/mail or
/var/spool/mail.
* kauth has ability to get ticket on a remove host with the `-h' option.
* afslog (aklog clone) and pagsh included.
* New format for /etc/krb.equiv.
* Better multi-homed hosts support in kauth, rcp, rlogin, rlogind,
rshd, telnet, telnetd.
* rlogind works on ultrix and aix 3.2.
* lots of bug fixes.
Major changes in release 0.6:
* Tested platforms:
DEC/Alpha OSF3.2
HP700 HPux 9.x
Dec/Pmax Ultrix 4.4 (rlogind not working)
IBM RS/6000 AIX 3.2 (rlogind not working)
IBM RS/6000 AIX 4.1
SGI Irix 5.3
Sun Sunos 4.1.x
Sun Sunos 5.4
386 BSD/OS 2.0.1
386 NetBSD 1.1
386 Linux 1.2.13
It is rumored to work to some extent on NextStep 3.3.
* ksrvutil get to create new keys and put them in the database at the
same time.
* Support for S/Key in login.
* kstring2key: new program to show string to key conversion.
* Kerberos server should now listen on all available network
interfaces and on both port 88 and 750.
* Timeout in kpopper.
* Support password quality checks in kadmind. Use --with-crack-lib to
link kadmind with cracklib. The patches in cracklib.patch are needed.
* Movemail from emacs 19.30.
* Logging format uses four digits for years.
* Fallback if port numbers are not listed in /etc/services.
* Relesed version 0.5
* lib/des/read_pwd.c: Redifine TIOCGETP and TIOCSETP so that the
same code is used both for posix termios and others.
* rsh, rlogin: Add environment variable RSTAR_NO_WARN which when
set to "yes" make warnings about "rlogin: warning, using standard
rlogin: remote host doesn't support Kerberos." go away.
* admin/kdb_util.c (load_db) lib/kdb/krb_dbm.c (kerb_db_update):
Optimized so that it can handle large databases, previously a
10000 entry DB would take *many* minutes, this can now be done in
under a minute.
* Changes in server/kerberos.c, kadmin/*.c slave/*.c to support 64
bit machines. Source should now be free of 64 bit assumptions.
* admin/copykey.c (copy_from_key): New functions for copying to
and from keys. Neccessary to solve som problems with longs on 64
bit machines in kdb_init, kdb_edit, kdb_util and ext_srvtab.
* lib/kdb/krb_kdb_utils.c (kdb_verify_master_key): More problems
with longs on 64 bit machines.
* appl/bsd/login.c (main): Lots of stuff to support Psoriasis
login. Courtesy of gertz@lysator.liu.se.
* configure.in, all Makefile.in's: Support for Linux shared
libraries. Courtesy of svedja@lysator.liu.se.
* lib/krb/cr_err_reply.c server/kerberos.c: Moved int req_act_vno
= KRB_PROT_VERSION; from server kode to libkrb where it really
belongs.
* appl/bsd/forkpty.c (forkpty): New function that allocates master
and slave ptys in a portable way. Used by rlogind.
* appl/telnet/telnetd/sys_term.c (start_login): Under SunOS5 the
same utmpx slot got used by sevral sessions. Courtesy of
gertz@lysator.liu.se.
* util/{ss, et}/Makefile.in (LEX): Use flex or lex. Courtesy of
svedja@lysator.liu.se.
* Fix the above Makefiles to work around bugs in Solaris and OSF/1
make rules that was triggered by VPATH functionality in the yacc
and lex rules.
* appl/kpopper/pop_log.c (pop_log) appl/kpopper/pop_msg.c (pop_msg):
Use stdarg instead of varargs. The code is still broken though,
you'll realize that on a machine with 64 bit pointers and 32 bit
int:s and no vsprintf, let's hope there will be no such beasts ;-).
* appl/telnet/telnetd/sys_term.c (getptyslave): Not all systems
have (or need) modules ttcompat and pckt so don't flag it as a
fatal error if they don't exist.
* kadmin/admin_server.c (kadm_listen) kadmind/kadm_ser_wrap.c
(kadm_listen): Add kludge for kadmind running on a multihomed
server. #ifdef:ed under MULTIHOMED_KADMIN. Change in acconfig.h
if you need this feature.
* appl/Makefile.in (SUBDIRS): Add applications movemail kpopper
and xnlock.
* appl/bsd/rlogin.c (main): New rlogind.c, forkpty() is not
implemented yet though.
* appl/xnlock/Makefile.in: Some stubs for X11 programs in
configure.in as well as a kerberized version of xnlock.
* appl/bsd/{rlogin.c, rsh.c, rcp.c}: Add code to support fallback
port numbers if they can not be found using getservbyname.
* appl/bsd/klogin.c (klogin): Use differnet ticket files for each
login so that a malicous user won't be able to destroy our tickets
with a failed login attempt.
* lib/kafs/afssys.c (k_afsklog): First we try afs.cell@REALM, if
there is no such thing try afs@CELL instead. There is now two
arguments to k_afslog(char *cell, char *realm).
* kadmin/admin_server.c (kadm_listen): If we are multihomed we
need to figure out which local address that is used this time
since it is used in "direction" comparison.
* kadmin/kadm_ser_wrap.c (kadm_ser_init): Fallback to use default
port number.
* lib/krb/send_to_kdc.c (send_to_kdc): Default port number
(KRB_PORT) was not in network byte order.
* lib/krb/send_to_kdc.c (send_recv): Linux clears timeout struct
when selecting.
* appl/bsd/rcp.c, appl/bsd/rlogin.c, appl/bsd/rsh.c:
Now does fallback if there isn't any entries in /etc/services for
klogin/kshell. This also made the code a bit more pretty.
* appl/bsd/login.c: Added support for lots of more struct utmp fields.
If there is no ttyslot() use setutent and friends.
* appl/bsd/Makefile.in, appl/bsd/rlogind.c, appl/bsd/rshd.c:
Added extern iruserok().
* appl/bsd/iruserok.c: Initial revision
* appl/bsd/bsd_locl.h: Must include sys/filio.h on Psoriasis.
* appl/bsd/Makefile.in: New install
* appl/bsd/pathnames.h: Fix default path, rsh and rlogin.
* appl/bsd/rshd.c: Extend default PATH with bindir to find rcp.
* appl/bsd/login.c (login): If there is no ttyslot use setutent
and friends. Added support for lots of more struct utmp fields.
* server/kerberos.c (main) lib/kafs/afssys.c appl/bsd/bsd_locl.h:
Must include sys/filio.h on Psoriasis to find _IOW and FIO* macros.
* appl/bsd/rlogind.c (doit): Use _PATH_DEFPATH rather than
_PATH_DEF.
* appl/bsd/login.c, su.c (main): Use fallback to bourne shell if
running as root.
* appl/bsd/su.c (main): Update usage message to reflect that '-'
option must come after the ordinary options and before login-id.
* appl/telnet/telnetd/telnetd.c (doit): If remote host name is to
long to fit into utmp try to remove domain part if it does match
our local domain.
(main): Add new option -L /bin/login so that it is possible to
specify an alternate login program.
* appl/telnet/telnet/commands.c (env_init): When exporting
variable DISPLAY and if hostname is not the full name, try to get
the full name from DNS.
* appl/telnet/telnet/main.c (main): Option -k realm was broken due
to a bogous external declaration.
* kadmin/kadmin.c (add_new_key): Kadmin now properly sets
lifetime, expiration date and attributes in add_new_key command.
* appl/bsd/su.c (main): Don't handle '-' option with getopt.
* appl/telnet/telnet/externs.h: Removed protection for multiple
inclusions of termio(s).h since it broke definition of termio
macro on POSIX systems.
* lib/krb/lifetime.c (krb_life_to_time): If you want to disable
AFS compatible long lifetimes set krb_no_long_lifetimes = 1.
Please note that the long lifetimes are 100% compatible up to
10h so this should rarely be necessary.
* lib/krb/krb_equiv.c (krb_equiv): If you don't want to use
ipaddress protection of tickets set krb_ignore_ip_address. This
makes it possible for an intruder to steal a ticket and then use
it from som other machine anywhere on the net.
* kadmin/kadm_ser_wrap.c (kadm_ser_init): Don't bind to only one
local address. Accept request on all interfaces.
* admin/kdb_edit.c (change_principal): Don't accept illegal
dates. Courtesy of gertz@lysator.liu.se.
* configure.in: AIX specific libraries needed when using standard
libc routine getttyent, IBM should be ashamed!
* lib/krb/recvauth.c (krb_recvauth): Long that should be int32_t
problem.
* Added strdup for su and rlogin.
* Fix for old syslog macros in appl/bsd/bsd_locl.
* lib/kdb/krb_dbm.c (kerb_db_rename) admin/kdb_destroy.c: New
ifdef HAVE_NEW_DB for new databases residing in one file only.
* appl/bsd/rlogin.c (oob): Add workaround for Linux.
* appl/bsd/getpass.c: New routine that reads up to 127 char
passwords. Used in su.c and login.c.
* appl/telnet/telnetd/sys_term.c (login_tty): Ioctl TIOCSCTTY
should not be used on HP-UX.
==========================*** Released 0.2? ***=============================
ksrvutil
If there is a dot in the about to be added principals name there is
no need to ask for instance name.
kerberos & kadmind
Logfiles are created with small permissions (600).
krb.conf and krb.realms
Use domain part as realm name if there is no match in krb.realms.
Use kerberos.REALMNAME if there is no match in krb.realms.
rlogin
The rlogin client is supported both with and without encryption,
there is no rlogind yet though.
login
There is login program that supports the -f option. Both kerberos
and /etc/passwd authentication is enabled.
Vendors login programs typically have no -f option (needed by
telnetd) and also does not know how to verify passwords againts
kerberos.
appl/bsd/*
Now uses POSIX signals.
kdb_edit, kadmin
Generate random passwords if administrator enters empty password.
lib/kafs
New library to support AFS. Routines:
int k_hasafs(void);
int k_afsklog(...); or some other name
int k_setpag(void);
int k_unlog(void);
int k_pioctl(char *, int, struct ViceIoctl *, int);
Library supports more than one single entry point AFS syscalls
(needed be HP/UX and OSF/1 when running DFS). Doesn't rely on
transarc headers or library code. Same binaries can be used both on
machines running AFS and others.
This library is used in telnetd, login and the r* programs.
telnet & telnetd
Based on telnet.95.05.31.NE but with the encryption hacks from
ftp.funet.fi:/pub/unix/security/esrasrc-1.0 added. This encryption
stuff needed some more modifications (done by joda@nada.kth.se)
before it was usable. Telnet has also been modified to use GNU
autoconf.
Numerous other changes that are long since forgotten.

View file

@ -0,0 +1,74 @@
Problems compiling Kerberos
===========================
Many compilers require a switch to become ANSI compliant. Since kth-krb
is written in ANSI C it is necessary to specify the name of the compiler
to be used and the required switch to make it ANSI compliant. This is
most easily done when running configure using the `env' command. For
instance to build under HP-UX using the native compiler do:
datan$ env CC="cc -Ae" ./configure
In general `gcc' works. The following combinations have also been
verified to successfully compile the distribution:
`HP-UX'
`cc -Ae'
`Digital UNIX'
`cc -std1'
`AIX'
`xlc'
`Solaris 2.x'
`cc' (unbundled one)
`IRIX'
`cc'
Linux problems
--------------
Some systems have lost `/usr/include/ndbm.h' which is necessary to
build kth-krb correctly. There is a `ndbm.h.Linux' right next to the
source distribution.
There has been reports of non-working `libdb' on some Linux
distributions. If that happens, use the `--without-berkeley-db' when
configuring.
HP-UX problems
--------------
The shared library `/usr/lib/libndbm.sl' doesn't exist on all systems.
To make problems even worse, there is never an archive version for
static linking either. Therefore, when building "truly portable"
binaries first install GNU gdbm or Berkeley DB, and make sure that you
are linking against that library.
Cray problems
-------------
`rlogind' won't work on Crays until `forkpty()' has been ported, in the
mean time use `telnetd'.
AIX problems
------------
`gcc' version 2.7.2.1 has a bug which makes it miscompile
`appl/telnet/telnetd/sys_term.c' (and possibily `appl/bsd/forkpty.c'),
if used with too much optimization.
C2 problems
-----------
The programs that checks passwords works with `passwd', OTP, and
Kerberos paswords. This is problem if you use C2 security (or use some
other password database), that normally keeps passwords in some obscure
place. If you want to use Kerberos with C2 security you will have to
think about what kind of changes are necessary. See also the discussion
about Digital's SIA and C2 security, see *Note Digital SIA::.

44
crypto/kerberosIV/README Normal file
View file

@ -0,0 +1,44 @@
This is a severly hacked up version of Eric Young's eBones-p9 kerberos
version. The DES library has been updated with his 3.23 version and
numerous patches collected over the years have been applied to both
the kerberos and DES sources, most notably the CMU patches for extended
lifetimes that AFS uses. There is also support for AFS built into most
programs.
The source has been changed to use ANSI C and POSIX to the largest
possible extent. The code in util/et and appl/bsd have not been
updated in this way though (they really need it).
Telnet and telnetd are based on the telnet.95.10.23.NE.tar.Z. Kerberos
authentication is the default and warnings are issued by telnetd if
the telnet client does not turn on encryption.
The r* programs in appl/bsd have been updated with newer sources from
NetBSD and FreeBSD. NOTE: use of telnet is prefered to the use of
rlogin which is a temporary hack and not an Internet standard (and has
only been documented quite recently). Telnet uses kerberos
authentication to prevent the passing of cleartext passwords and is
thus superior to rlogin.
The distribution has been configured to primarily use kerberos
authentication with a fallback to /etc/passwd passwords. This should
make it easy to do a slow migration to kerberos. OTP support is also
included in login, popper, and ftpd.
All programs in this distribution follow these conventions:
/usr/athena/bin: User programs
/usr/athena/sbin: Administrator programs
/usr/athena/libexec: Daemons
/etc: Configuration files
/var/log: Logfiles
/var/kerberos: Kerberos database and ACL files
A W3-page is at http://www.pdc.kth.se/kth-krb/
You can get some documentation from ftp://ftp.pdc.kth.se/pub/krb/doc.
Please report bugs and problems to kth-krb-bugs@nada.kth.se
There is a mailing list discussing kerberos at krb4@sics.se, send a
message to majordomo@sics.se to subscribe.

View file

@ -0,0 +1,30 @@
It should be possible to build several of the libraries and the GUI
telnet ``voodoo'' on Win95/NT. In case you don't want to try there
are binaries available at
ftp://ftp.pdc.kth.se/pub/krb/binaries/i386-unknown-winnt4.0.
In case you want to build from source and possibly hack some on them
yourself here's a short guide:
You need to build the libraries (DLLs) first and in this order:
lib/roken
lib/des
lib/krb
lib/kclient
And then the two applications:
appl/krbmanager
appl/voodoo
In each case there is a Visual-C++ generated makefile with the name
*.mak in the corresponding directory. You might be able to load that
into Microsoft whatever Studio and you might be able to just run nmake
on them.
Once you have ended up with 4 DLLs and 2 EXEs you only have to place
them in a directory in your PATH and start voodoo.
In case it doesn't work, you have discovered bugs or added some more
features the mail address to use is <kth-krb-bugs@nada.kth.se>

42
crypto/kerberosIV/TODO Normal file
View file

@ -0,0 +1,42 @@
-*- indented-text -*-
rlogind, rshd, popper, ftpd (telnetd uses nonce?)
Add a replay cache.
telnet, rlogin, rsh, rcp
Some form of support for ticket forwarding, perhaps only for AFS tickets.
telnet, telnetd
Add negotiation for keep-alives.
rlogind
Fix utmp logging.
documentation
Write more info on:
* how to use
rshd
Read default environment from /etc/default/login and other files.
Encryption without secondary port is bugged, it currently does no
encryption. But, nobody uses it anyway.
autoconf
libraries
generate archive and shared libraries in some portable way.
k_get_all_addrs
for Cray UNICOS
ftpd
kx
Compress and recode X protocol?
kip
Other kinds of encapsulations?
Tunnel device as loadable kernel module.
Speed?
BUGS
Where?

View file

@ -0,0 +1,282 @@
/* $Id: acconfig.h,v 1.71 1997/06/01 22:32:24 assar Exp $ */
/* Define this if RETSIGTYPE == void */
#undef VOID_RETSIGTYPE
/* Define this if struct utmp have ut_user */
#undef HAVE_UT_USER
/* Define this if struct utmp have ut_host */
#undef HAVE_UT_HOST
/* Define this if struct utmp have ut_addr */
#undef HAVE_UT_ADDR
/* Define this if struct utmp have ut_type */
#undef HAVE_UT_TYPE
/* Define this if struct utmp have ut_pid */
#undef HAVE_UT_PID
/* Define this if struct utmp have ut_id */
#undef HAVE_UT_ID
/* Define this if struct utmpx have ut_syslen */
#undef HAVE_UT_SYSLEN
/* Define this if struct winsize is declared in sys/termios.h */
#undef HAVE_STRUCT_WINSIZE
/* Define this if struct winsize have ws_xpixel */
#undef HAVE_WS_XPIXEL
/* Define this if struct winsize have ws_ypixel */
#undef HAVE_WS_YPIXEL
/* Define this to be the directory where the dictionary for cracklib */
/* resides */
#undef DICTPATH
/* Define this if you want to use SOCKS v5 */
#undef SOCKS
/* Define this to the path of the mail spool directory */
#undef KRB4_MAILDIR
/* Define this if `struct sockaddr' includes sa_len */
#undef SOCKADDR_HAS_SA_LEN
/* Define this if `struct siaentity' includes ouid */
#undef SIAENTITY_HAS_OUID
/* Define if getlogin has POSIX flavour, as opposed to BSD */
#undef POSIX_GETLOGIN
/* Define if getpwnam_r has POSIX flavour */
#undef POSIX_GETPWNAM_R
/* define if getcwd() is broken (such as in SunOS) */
#undef BROKEN_GETCWD
/* define if the system is missing a prototype for crypt() */
#undef NEED_CRYPT_PROTO
/* define if the system is missing a prototype for strtok_r() */
#undef NEED_STRTOK_R_PROTO
/* define if /bin/ls takes -A */
#undef HAVE_LS_A
/* define if you have h_errno */
#undef HAVE_H_ERRNO
/* define if you have h_errlist but not hstrerror */
#undef HAVE_H_ERRLIST
/* define if you have h_nerr but not hstrerror */
#undef HAVE_H_NERR
/* define if your system doesn't declare h_errlist */
#undef HAVE_H_ERRLIST_DECLARATION
/* define if your system doesn't declare h_nerr */
#undef HAVE_H_NERR_DECLARATION
/* define this if you need a declaration for h_errno */
#undef HAVE_H_ERRNO_DECLARATION
/* define if you need a declaration for optarg */
#undef HAVE_OPTARG_DECLARATION
/* define if you need a declaration for optind */
#undef HAVE_OPTIND_DECLARATION
/* define if you need a declaration for opterr */
#undef HAVE_OPTERR_DECLARATION
/* define if you need a declaration for optopt */
#undef HAVE_OPTOPT_DECLARATION
/* define if you need a declaration for __progname */
#undef HAVE___PROGNAME_DECLARATION
@BOTTOM@
#undef HAVE_INT8_T
#undef HAVE_INT16_T
#undef HAVE_INT32_T
#undef HAVE_INT64_T
#undef HAVE_U_INT8_T
#undef HAVE_U_INT16_T
#undef HAVE_U_INT32_T
#undef HAVE_U_INT64_T
#define RCSID(msg) \
static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg }
/*
* Set ORGANIZATION to be the desired organization string printed
* by the 'kinit' program. It may have spaces.
*/
#define ORGANIZATION "eBones International"
#if 0
#undef BINDIR
#undef LIBDIR
#undef LIBEXECDIR
#undef SBINDIR
#endif
#if 0
#define KRB_CNF_FILES { "/etc/krb.conf", "/etc/kerberosIV/krb.conf", 0}
#define KRB_RLM_FILES { "/etc/krb.realms", "/etc/kerberosIV/krb.realms", 0}
#define KRB_EQUIV "/etc/krb.equiv"
#define KEYFILE "/etc/srvtab"
#define KRBDIR "/var/kerberos"
#define DBM_FILE KRBDIR "/principal"
#define DEFAULT_ACL_DIR KRBDIR
#define KRBLOG "/var/log/kerberos.log" /* master server */
#define KRBSLAVELOG "/var/log/kerberos_slave.log" /* slave server */
#define KADM_SYSLOG "/var/log/admin_server.syslog"
#define K_LOGFIL "/var/log/kpropd.log"
#endif
/* Maximum values on all known systems */
#define MaxHostNameLen (64+4)
#define MaxPathLen (1024+4)
/*
* Define NDBM if you are using the 4.3 ndbm library (which is part of
* libc). If not defined, 4.2 dbm will be assumed.
*/
#if defined(HAVE_DBM_FIRSTKEY)
#define NDBM
#endif
/* ftp stuff -------------------------------------------------- */
#define KERBEROS
/* telnet stuff ----------------------------------------------- */
/* define this if you have kerberos 4 */
#undef KRB4
/* define this if you want encryption */
#undef ENCRYPTION
/* define this if you want authentication */
#undef AUTHENTICATION
#if defined(ENCRYPTION) && !defined(AUTHENTICATION)
#define AUTHENTICATION 1
#endif
/* Set this if you want des encryption */
#undef DES_ENCRYPTION
/* Set this to the default system lead string for telnetd
* can contain %-escapes: %s=sysname, %m=machine, %r=os-release
* %v=os-version, %t=tty, %h=hostname, %d=date and time
*/
#undef USE_IM
/* define this if you want diagnostics in telnetd */
#undef DIAGNOSTICS
/* define this if you want support for broken ENV_{VALUE,VAR} systems */
#undef ENV_HACK
/* */
#undef OLD_ENVIRON
/* Used with login -p */
#undef LOGIN_ARGS
/* Define if there are working stream ptys */
#undef STREAMSPTY
/* set this to a sensible login */
#ifndef LOGIN_PATH
#define LOGIN_PATH BINDIR "/login"
#endif
/* ------------------------------------------------------------ */
/*
* Define this if your ndbm-library really is berkeley db and creates
* files that ends in .db.
*/
#undef HAVE_NEW_DB
/* Define this if you have a working getmsg */
#undef HAVE_GETMSG
/* Define to enable new master key code */
#undef RANDOM_MKEY
/* Location of the master key file, default value lives in <kdc.h> */
#undef MKEYFILE
/* Define if you don't want support for afs, might be a good idea on
AIX if you don't have afs */
#undef NO_AFS
/* Define if you have a readline compatible library */
#undef HAVE_READLINE
#ifdef VOID_RETSIGTYPE
#define SIGRETURN(x) return
#else
#define SIGRETURN(x) return (RETSIGTYPE)(x)
#endif
/* Define this if your compiler supports '#pragma weak' */
#undef HAVE_PRAGMA_WEAK
/* Temporary fixes for krb_{rd,mk}_safe */
#define DES_QUAD_GUESS 0
#define DES_QUAD_NEW 1
#define DES_QUAD_OLD 2
/* Set this to one of the constants above to specify default checksum
type to emit */
#undef DES_QUAD_DEFAULT
/*
* AIX braindamage!
*/
#if _AIX
#define _ALL_SOURCE
#define _POSIX_SOURCE
/* this is left for hysteric reasons :-) */
#define unix /* well, ok... */
#endif
/*
* SunOS braindamage! (Sun include files are generally braindead)
*/
#if (defined(sun) || defined(__sun))
#if defined(__svr4__) || defined(__SVR4)
#define SunOS 5
#else
#define SunOS 4
#endif
#endif
#if defined(__sgi) || defined(sgi)
#if defined(__SYSTYPE_SVR4) || defined(_SYSTYPE_SVR4)
#define IRIX 5
#else
#define IRIX 4
#endif
#endif
/* IRIX 4 braindamage */
#if IRIX == 4 && !defined(__STDC__)
#define __STDC__ 0
#endif

543
crypto/kerberosIV/aclocal.m4 vendored Normal file
View file

@ -0,0 +1,543 @@
dnl
dnl $Id: aclocal.m4,v 1.38 1997/05/18 18:47:30 assar Exp $
dnl
dnl
dnl General tests
dnl
dnl
dnl Look for function in any of the specified libraries
dnl
dnl AC_FIND_FUNC_NO_LIBS(func, libraries, includes, arguments)
AC_DEFUN(AC_FIND_FUNC_NO_LIBS, [
AC_MSG_CHECKING([for $1])
AC_CACHE_VAL(ac_cv_funclib_$1,
[
if eval "test \"\$ac_cv_func_$1\" != yes" ; then
ac_save_LIBS="$LIBS"
for ac_lib in "" $2; do
if test -n "$ac_lib"; then
ac_lib="-l$ac_lib"
LIBS="$ac_lib $ac_save_LIBS"
fi
AC_TRY_LINK([$3],[$1($4)],eval "if test -n \"$ac_lib\";then ac_cv_funclib_$1=$ac_lib; else ac_cv_funclib_$1=yes; fi";break)
done
eval "ac_cv_funclib_$1=\${ac_cv_funclib_$1-no}"
LIBS="$ac_save_LIBS"
fi
])
eval "ac_res=\$ac_cv_funclib_$1"
# autoheader tricks *sigh*
: << END
@@@funcs="$funcs $1"@@@
@@@libs="$libs $2"@@@
END
changequote(, )dnl
eval "ac_tr_func=HAVE_`echo $1 | tr '[a-z]' '[A-Z]'`"
eval "ac_tr_lib=HAVE_LIB`echo $ac_res | sed -e 's/-l//' | tr '[a-z]' '[A-Z]'`"
eval "LIB_$1=$ac_res"
changequote([, ])dnl
case "$ac_res" in
yes)
eval "ac_cv_func_$1=yes"
eval "LIB_$1="
AC_DEFINE_UNQUOTED($ac_tr_func)
AC_MSG_RESULT([yes])
;;
no)
eval "ac_cv_func_$1=no"
eval "LIB_$1="
AC_MSG_RESULT([no])
;;
*)
eval "ac_cv_func_$1=yes"
eval "ac_cv_lib_`echo "$ac_res" | sed 's/-l//'`=yes"
AC_DEFINE_UNQUOTED($ac_tr_func)
AC_DEFINE_UNQUOTED($ac_tr_lib)
AC_MSG_RESULT([yes, in $ac_res])
;;
esac
AC_SUBST(LIB_$1)
])
dnl AC_FIND_FUNC(func, libraries, includes, arguments)
AC_DEFUN(AC_FIND_FUNC, [
AC_FIND_FUNC_NO_LIBS([$1], [$2], [$3], [$4])
if test -n "$LIB_$1"; then
LIBS="$LIB_$1 $LIBS"
fi
])
dnl
dnl Same as AC _REPLACE_FUNCS, just define HAVE_func if found in normal
dnl libraries
AC_DEFUN(AC_BROKEN,
[for ac_func in $1
do
AC_CHECK_FUNC($ac_func, [
changequote(, )dnl
ac_tr_func=HAVE_`echo $ac_func | tr '[a-z]' '[A-Z]'`
changequote([, ])dnl
AC_DEFINE_UNQUOTED($ac_tr_func)],[LIBOBJS="$LIBOBJS ${ac_func}.o"])
# autoheader tricks *sigh*
: << END
@@@funcs="$funcs $1"@@@
END
done
AC_SUBST(LIBOBJS)dnl
])
dnl
dnl Mix between AC_FIND_FUNC and AC_BROKEN
dnl
AC_DEFUN(AC_FIND_IF_NOT_BROKEN,
[AC_FIND_FUNC([$1], [$2], [$3], [$4])
if eval "test \"$ac_cv_func_$1\" != yes"; then
LIBOBJS="$LIBOBJS $1.o"
fi
AC_SUBST(LIBOBJS)dnl
])
dnl
dnl
dnl
dnl AC_TEST_PACKAGE(package,header,lib,linkline)
AC_DEFUN(AC_TEST_PACKAGE,
[
AC_MSG_CHECKING(for $1)
AC_ARG_WITH($1,
[ --with-$1=dir use $1 in dir],
[if test "$with_$1" = "no"; then
with_$1=
fi]
)
AC_ARG_WITH($1-lib,
[ --with-$1-lib=dir use $1-lib in dir],
[if test "$withval" = "yes" -o "$withval" = "no"; then
AC_MSG_ERROR([No argument for --with-$1-lib])
elif test "X$with_$1" = "X"; then
with_$1=yes
fi]
)
AC_ARG_WITH($1-include,
[ --with-$1-include=dir use $1-include in dir],
[if test "$withval" = "yes" -o "$withval" = "no"; then
AC_MSG_ERROR([No argument for --with-$1-include])
elif test "X$with_$1" = "X"; then
with_$1=yes
fi]
)
define([foo], translit($1, [a-z], [A-Z]))
: << END
@@@syms="$syms foo"@@@
END
if test -n "$with_$1"; then
AC_DEFINE([foo])
if test "$with_$1" != "yes"; then
$1_dir=$with_$1
fi
dnl Try to find include
if test -n "$with_$1_include"; then
trydir=$with_$1_include
elif test "$with_$1" != "yes"; then
trydir="$with_$1 $with_$1/include"
else
trydir=
fi
found=
for i in $trydir ""; do
if test -n "$i"; then
if test -f $i/$2; then
found=yes; res=$i; break
fi
else
AC_TRY_CPP([#include <$2>], [found=yes; res=$i; break])
fi
done
if test -n "$found"; then
$1_include=$res
else
AC_MSG_ERROR(Cannot find $2)
fi
dnl Try to find lib
if test -n "$with_$1_lib"; then
trydir=$with_$1_lib
elif test "$with_$1" != "yes"; then
trydir="$with_$1 $with_$1/lib"
else
trydir=
fi
found=
for i in $trydir ""; do
if test -n "$i"; then
if test -f $i/$3; then
found=yes; res=$i; break
fi
else
old_LIBS=$LIBS
LIBS="$4 $LIBS"
AC_TRY_LINK([], [], [found=yes; res=$i; LIBS=$old_LIBS; break])
LIBS=$old_LIBS
fi
done
if test -n "$found"; then
$1_lib=$res
else
AC_MSG_ERROR(Cannot find $3)
fi
AC_MSG_RESULT([headers $$1_include, libraries $$1_lib])
AC_DEFINE_UNQUOTED(foo)
if test -n "$$1_include"; then
foo[INCLUDE]="-I$$1_include"
fi
AC_SUBST(foo[INCLUDE])
if test -n "$$1_lib"; then
foo[LIB]="-L$$1_lib"
fi
foo[LIB]="$foo[LIB] $4"
AC_SUBST(foo[LIB])
else
AC_MSG_RESULT(no)
fi
undefine([foo])
])
dnl
dnl Check if we need the declaration of a variable
dnl
dnl AC_HAVE_DECLARATION(includes, variable)
AC_DEFUN(AC_CHECK_DECLARATION, [
AC_MSG_CHECKING([if $2 is properly declared])
AC_CACHE_VAL(ac_cv_var_$2_declaration, [
AC_TRY_COMPILE([$1
extern struct { int foo; } $2;],
[$2.foo = 1;],
eval "ac_cv_var_$2_declaration=no",
eval "ac_cv_var_$2_declaration=yes")
])
ac_tr_var=[HAVE_]translit($2, [a-z], [A-Z])[_DECLARATION]
define([foo], [HAVE_]translit($2, [a-z], [A-Z])[_DECLARATION])
: << END
@@@syms="$syms foo"@@@
END
undefine([foo])
AC_MSG_RESULT($ac_cv_var_$2_declaration)
if eval "test \"\$ac_cv_var_$2_declaration\" = yes"; then
AC_DEFINE_UNQUOTED($ac_tr_var)
fi
])
dnl
dnl
dnl
dnl AC_CHECK_VAR(includes, variable)
AC_DEFUN(AC_CHECK_VAR, [
AC_MSG_CHECKING(for $2)
AC_CACHE_VAL(ac_cv_var_$2, [
AC_TRY_LINK([extern int $2;
int foo() { return $2; }],
[foo()],
ac_cv_var_$2=yes, ac_cv_var_$2=no)
])
eval "ac_tr_var=[HAVE_]translit($2,[a-z],[A-Z])"
define([foo], [HAVE_]translit($2, [a-z], [A-Z]))
: << END
@@@syms="$syms foo"@@@
END
undefine([foo])
AC_MSG_RESULT(`eval echo \\$ac_cv_var_$2`)
if test `eval echo \\$ac_cv_var_$2` = yes; then
AC_DEFINE_UNQUOTED($ac_tr_var)
AC_CHECK_DECLARATION([$1],[$2])
fi
])
dnl
dnl Check if we need the prototype for a function
dnl
dnl AC_NEED_PROTO(includes, function)
AC_DEFUN(AC_NEED_PROTO, [
AC_CACHE_CHECK([if $2 needs a prototype], ac_cv_func_$2_noproto,
AC_TRY_COMPILE([$1],
[struct foo { int foo; } xx;
extern int $2 (struct foo*);
$2(&xx);
],
eval "ac_cv_func_$2_noproto=yes",
eval "ac_cv_func_$2_noproto=no"))
define([foo], [NEED_]translit($2, [a-z], [A-Z])[_PROTO])
if test "$ac_cv_func_$2_noproto" = yes; then
AC_DEFINE(foo)
fi
: << END
@@@syms="$syms foo"@@@
END
undefine([foo])
])
dnl AC_MSG_RESULT($ac_cv_func_$3_proto)
dnl if eval "test \"\$ac_cv_func_$3_proto\" = yes"; then
dnl AC_DEFINE_UNQUOTED($ac_tr_func)
dnl fi
dnl ])
dnl
dnl AC_DEFUN(AC_NEED_PROTO, [
dnl AC_MSG_CHECKING([if $3 needs a proto])
dnl AC_CACHE_VAL(ac_cv_func_$3_proto, [
dnl AC_TRY_COMPILE([$1],
dnl [$2],
dnl eval "ac_cv_func_$3_proto=no",
dnl eval "ac_cv_func_$3_proto=yes")
dnl ])
dnl changequote(, )dnl
dnl eval "ac_tr_func=NEED_`echo $3 | tr '[a-z]' '[A-Z]'`_PROTO"
dnl changequote([, ])dnl
dnl
dnl define([foo], [NEED_]translit($3, [a-z], [A-Z])[_PROTO])
dnl : << END
dnl @@@syms="$syms foo"@@@
dnl END
dnl undefine([foo])
dnl
dnl AC_MSG_RESULT($ac_cv_func_$3_proto)
dnl if eval "test \"\$ac_cv_func_$3_proto\" = yes"; then
dnl AC_DEFINE_UNQUOTED($ac_tr_func)
dnl fi
dnl ])
AC_DEFUN(AC_GROK_TYPE, [
AC_CACHE_VAL(ac_cv_type_$1,
AC_TRY_COMPILE([
#include "confdefs.h"
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_BITYPES_H
#include <sys/bitypes.h>
#endif
#ifdef HAVE_BIND_BITYPES_H
#include <bind/bitypes.h>
#endif
#ifdef HAVE_NETINET_IN6_MACHTYPES_H
#include <netinet/in6_machtypes.h>
#endif
],
$i x;
,
eval ac_cv_type_$1=yes,
eval ac_cv_type_$1=no))])
AC_DEFUN(AC_GROK_TYPES, [
for i in $1; do
AC_MSG_CHECKING(for $i)
AC_GROK_TYPE($i)
eval ac_res=\$ac_cv_type_$i
if test "$ac_res" = yes; then
type=HAVE_`echo $i | tr '[a-z]' '[A-Z]'`
AC_DEFINE_UNQUOTED($type)
fi
AC_MSG_RESULT($ac_res)
done
])
dnl
dnl Specific tests
dnl
dnl
dnl We prefer byacc or yacc because they do not use `alloca'
dnl
AC_DEFUN(AC_KRB_PROG_YACC,
[AC_CHECK_PROGS(YACC, byacc yacc 'bison -y')])
dnl
dnl Also look for EMXOMF for OS/2
dnl
AC_DEFUN(AC_KRB_PROG_RANLIB,
[AC_CHECK_PROGS(RANLIB, ranlib EMXOMF, :)])
dnl
dnl Better test for ln -s, ln or cp
dnl
AC_DEFUN(AC_KRB_PROG_LN_S,
[AC_MSG_CHECKING(for ln -s or something else)
AC_CACHE_VAL(ac_cv_prog_LN_S,
[rm -f conftestdata
if ln -s X conftestdata 2>/dev/null
then
rm -f conftestdata
ac_cv_prog_LN_S="ln -s"
else
touch conftestdata1
if ln conftestdata1 conftestdata2; then
rm -f conftestdata*
ac_cv_prog_LN_S=ln
else
ac_cv_prog_LN_S=cp
fi
fi])dnl
LN_S="$ac_cv_prog_LN_S"
AC_MSG_RESULT($ac_cv_prog_LN_S)
AC_SUBST(LN_S)dnl
])
dnl
dnl NEXTSTEP is not posix compliant by default,
dnl you need a switch -posix to the compiler
dnl
AC_DEFUN(AC_KRB_SYS_NEXTSTEP, [
AC_MSG_CHECKING(for NEXTSTEP)
AC_CACHE_VAL(krb_cv_sys_nextstep,
AC_EGREP_CPP(yes,
[#ifdef NeXT
yes
#endif
], krb_cv_sys_nextstep=yes, krb_cv_sys_nextstep=no) )
if test "$krb_cv_sys_nextstep" = "yes"; then
CFLAGS="$CFLAGS -posix"
LIBS="$LIBS -posix"
fi
AC_MSG_RESULT($krb_cv_sys_nextstep)
])
dnl
dnl AIX have a very different syscall convention
dnl
AC_DEFUN(AC_KRB_SYS_AIX, [
AC_MSG_CHECKING(for AIX)
AC_CACHE_VAL(krb_cv_sys_aix,
AC_EGREP_CPP(yes,
[#ifdef _AIX
yes
#endif
], krb_cv_sys_aix=yes, krb_cv_sys_aix=no) )
AC_MSG_RESULT($krb_cv_sys_aix)
])
dnl
dnl test for broken getcwd in (SunOS braindamage)
dnl
AC_DEFUN(AC_KRB_FUNC_GETCWD_BROKEN, [
if test "$ac_cv_func_getcwd" = yes; then
AC_MSG_CHECKING(if getcwd is broken)
AC_CACHE_VAL(ac_cv_func_getcwd_broken, [
ac_cv_func_getcwd_broken=no
AC_TRY_RUN([
#include <errno.h>
char *getcwd(char*, int);
void *popen(char *cmd, char *mode)
{
errno = ENOTTY;
return 0;
}
int main()
{
char *ret;
ret = getcwd(0, 1024);
if(ret == 0 && errno == ENOTTY)
return 0;
return 1;
}
], ac_cv_func_getcwd_broken=yes,:,:)
])
if test "$ac_cv_func_getcwd_broken" = yes; then
AC_DEFINE(BROKEN_GETCWD, 1)dnl
LIBOBJS="$LIBOBJS getcwd.o"
AC_SUBST(LIBOBJS)dnl
AC_MSG_RESULT($ac_cv_func_getcwd_broken)
else
AC_MSG_RESULT([seems ok])
fi
fi
])
AC_DEFUN(AC_HAVE_PRAGMA_WEAK, [
if test "${with_shared}" = "yes"; then
AC_MSG_CHECKING(for pragma weak)
AC_CACHE_VAL(ac_have_pragma_weak, [
ac_have_pragma_weak=no
cat > conftest_foo.$ac_ext <<'EOF'
[#]line __oline__ "configure"
#include "confdefs.h"
#pragma weak foo = _foo
int _foo = 17;
EOF
cat > conftest_bar.$ac_ext <<'EOF'
[#]line __oline__ "configure"
#include "confdefs.h"
extern int foo;
int t() {
return foo;
}
int main() {
return t();
}
EOF
if AC_TRY_EVAL('CC -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest_foo.$ac_ext conftest_bar.$ac_ext 1>&AC_FD_CC'); then
ac_have_pragma_weak=yes
fi
rm -rf conftest*
])
if test "$ac_have_pragma_weak" = "yes"; then
AC_DEFINE(HAVE_PRAGMA_WEAK, 1)dnl
fi
AC_MSG_RESULT($ac_have_pragma_weak)
fi
])
dnl
dnl Search for struct winsize
dnl
AC_DEFUN(AC_KRB_STRUCT_WINSIZE, [
AC_MSG_CHECKING(for struct winsize)
AC_CACHE_VAL(ac_cv_struct_winsize, [
ac_cv_struct_winsize=no
for i in sys/termios.h sys/ioctl.h; do
AC_EGREP_HEADER(
changequote(, )dnl
struct[ ]*winsize,dnl
changequote([,])dnl
$i, ac_cv_struct_winsize=yes; break)dnl
done
])
if test "$ac_cv_struct_winsize" = "yes"; then
AC_DEFINE(HAVE_STRUCT_WINSIZE, 1)dnl
fi
AC_MSG_RESULT($ac_cv_struct_winsize)
AC_EGREP_HEADER(ws_xpixel, termios.h, AC_DEFINE(HAVE_WS_XPIXEL))
AC_EGREP_HEADER(ws_ypixel, termios.h, AC_DEFINE(HAVE_WS_YPIXEL))
])

View file

@ -0,0 +1,104 @@
# $Id: Makefile.in,v 1.26 1997/05/04 08:33:50 assar Exp $
SHELL = /bin/sh
srcdir = @srcdir@
VPATH = @srcdir@
CC = @CC@
AR = ar
RANLIB = @RANLIB@
DEFS = @DEFS@
CFLAGS = @CFLAGS@
LD_FLAGS = @LD_FLAGS@
LIBS = @LIBS@
LIB_DBM = @LIB_DBM@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
prefix = @prefix@
exec_prefix = @exec_prefix@
libdir = @libdir@
sbindir = @sbindir@
transform=@program_transform_name@
EXECSUFFIX=@EXECSUFFIX@
PROGS = ext_srvtab$(EXECSUFFIX) \
kdb_destroy$(EXECSUFFIX) \
kdb_edit$(EXECSUFFIX) \
kdb_init$(EXECSUFFIX) \
kdb_util$(EXECSUFFIX) \
kstash$(EXECSUFFIX)
SOURCES = ext_srvtab.c kdb_destroy.c kdb_edit.c \
kdb_init.c kdb_util.c kstash.c
OBJECTS = ext_srvtab.o kdb_destroy.o kdb_edit.o \
kdb_init.o kdb_util.o kstash.o
all: $(PROGS)
Wall:
make CFLAGS="-g -Wall -Wno-comment -Wmissing-prototypes -Wmissing-declarations -D__USE_FIXED_PROTOTYPES__"
.c.o:
$(CC) -c $(CPPFLAGS) $(DEFS) -I../include -I$(srcdir) $(CFLAGS) $<
install: all
$(MKINSTALLDIRS) $(sbindir)
for x in $(PROGS); do \
$(INSTALL_PROGRAM) $$x $(sbindir)/`echo $$x|sed '$(transform)'`; \
done
uninstall:
for x in $(PROGS); do \
rm -f $(sbindir)/`echo $$x|sed '$(transform)'`; \
done
TAGS: $(SOURCES)
etags $(SOURCES)
check:
clean:
rm -f *.a *.o $(PROGS)
mostlyclean: clean
distclean: clean
rm -f Makefile *.tab.c *~
realclean: distclean
rm -f TAGS
dist: $(DISTFILES)
for file in $(DISTFILES); do \
ln $$file ../`cat ../.fname`/lib \
|| cp -p $$file ../`cat ../.fname`/lib; \
done
KLIB=-L../lib/kdb -lkdb -L../lib/krb -lkrb -L../lib/des -ldes
LIBROKEN= -L../lib/roken -lroken
ext_srvtab$(EXECSUFFIX): ext_srvtab.o
$(CC) $(LD_FLAGS) $(LDFLAGS) -o $@ ext_srvtab.o $(KLIB) $(LIBROKEN) $(LIB_DBM) $(LIBS) $(LIBROKEN)
kdb_destroy$(EXECSUFFIX): kdb_destroy.o
$(CC) $(LD_FLAGS) $(LDFLAGS) -o $@ kdb_destroy.o $(KLIB) $(LIBROKEN) $(LIB_DBM) $(LIBS) $(LIBROKEN)
kdb_edit$(EXECSUFFIX): kdb_edit.o
$(CC) $(LD_FLAGS) $(LDFLAGS) -o $@ kdb_edit.o $(KLIB) $(LIBROKEN) $(LIB_DBM) $(LIBS) $(LIBROKEN)
kdb_init$(EXECSUFFIX): kdb_init.o
$(CC) $(LD_FLAGS) $(LDFLAGS) -o $@ kdb_init.o $(KLIB) $(LIBROKEN) $(LIB_DBM) $(LIBS) $(LIBROKEN)
kdb_util$(EXECSUFFIX): kdb_util.o
$(CC) $(LD_FLAGS) $(LDFLAGS) -o $@ kdb_util.o $(KLIB) $(LIBROKEN) $(LIB_DBM) $(LIBS) $(LIBROKEN)
kstash$(EXECSUFFIX): kstash.o
$(CC) $(LD_FLAGS) $(LDFLAGS) -o $@ kstash.o $(KLIB) $(LIBROKEN) $(LIB_DBM) $(LIBS) $(LIBROKEN)
$(OBJECTS): ../include/config.h

View file

@ -0,0 +1,91 @@
/*
* Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Kungliga Tekniska
* Högskolan and its contributors.
*
* 4. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*/
/* $Id: adm_locl.h,v 1.16 1997/04/20 05:46:14 assar Exp $ */
#ifndef __adm_locl_h
#define __adm_locl_h
#include "config.h"
#include "protos.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef TIME_WITH_SYS_TIME
#include <sys/time.h>
#include <time.h>
#elif defined(HAVE_SYS_TIME_H)
#include <sys/time.h>
#else
#include <time.h>
#endif /* !TIME_WITH_SYS_TIME */
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#include <signal.h>
#include <errno.h>
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#include <err.h>
#include <roken.h>
#include <des.h>
#include <krb.h>
#include <krb_db.h>
#include <kdc.h>
#include <kadm.h>
#endif /* __adm_locl_h */

View file

@ -0,0 +1,143 @@
/*
* Copyright 1987, 1988 by the Massachusetts Institute of Technology.
*
* For copying and distribution information, please see the file
* <mit-copyright.h>.
*
* Description
*/
#include "adm_locl.h"
RCSID("$Id: ext_srvtab.c,v 1.13 1997/05/02 14:27:33 assar Exp $");
static des_cblock master_key;
static des_cblock session_key;
static des_key_schedule master_key_schedule;
static char realm[REALM_SZ];
static void
usage(void)
{
fprintf(stderr,
"Usage: %s [-n] [-r realm] instance [instance ...]\n",
__progname);
exit(1);
}
static void
StampOutSecrets(void)
{
memset(master_key, 0, sizeof master_key);
memset(session_key, 0, sizeof session_key);
memset(master_key_schedule, 0, sizeof master_key_schedule);
}
static void
Die(void)
{
StampOutSecrets();
exit(1);
}
static void
FWrite(void *p, int size, int n, FILE *f)
{
if (fwrite(p, size, n, f) != n) {
printf("Error writing output file. Terminating.\n");
Die();
}
}
int
main(int argc, char **argv)
{
FILE *fout;
char fname[1024];
int fopen_errs = 0;
int arg;
Principal princs[40];
int more;
int prompt = KDB_GET_PROMPT;
int n, i;
set_progname (argv[0]);
memset(realm, 0, sizeof(realm));
/* Parse commandline arguments */
if (argc < 2)
usage();
else {
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "-n") == 0)
prompt = FALSE;
else if (strcmp(argv[i], "-r") == 0) {
if (++i >= argc)
usage();
else {
strcpy(realm, argv[i]);
/*
* This is to humor the broken way commandline
* argument parsing is done. Later, this
* program ignores everything that starts with -.
*/
argv[i][0] = '-';
}
}
else if (argv[i][0] == '-')
usage();
else
if (!k_isinst(argv[i])) {
warnx("bad instance name: %s", argv[i]);
usage();
}
}
}
if (kdb_get_master_key (prompt, &master_key, master_key_schedule) != 0)
errx (1, "Couldn't read master key.");
if (kdb_verify_master_key (&master_key, master_key_schedule, stderr) < 0) {
exit(1);
}
/* For each arg, search for instances of arg, and produce */
/* srvtab file */
if (!realm[0])
if (krb_get_lrealm(realm, 1) != KSUCCESS)
errx (1, "couldn't get local realm");
umask(077);
for (arg = 1; arg < argc; arg++) {
if (argv[arg][0] == '-')
continue;
snprintf(fname, sizeof(fname), "%s-new-srvtab", argv[arg]);
if ((fout = fopen(fname, "w")) == NULL) {
warn("Couldn't create file '%s'.", fname);
fopen_errs++;
continue;
}
printf("Generating '%s'....\n", fname);
n = kerb_get_principal("*", argv[arg], &princs[0], 40, &more);
if (more)
fprintf(stderr, "More than 40 found...\n");
for (i = 0; i < n; i++) {
FWrite(princs[i].name, strlen(princs[i].name) + 1, 1, fout);
FWrite(princs[i].instance, strlen(princs[i].instance) + 1,
1, fout);
FWrite(realm, strlen(realm) + 1, 1, fout);
FWrite(&princs[i].key_version,
sizeof(princs[i].key_version), 1, fout);
copy_to_key(&princs[i].key_low, &princs[i].key_high, session_key);
kdb_encrypt_key (&session_key, &session_key,
&master_key, master_key_schedule, DES_DECRYPT);
FWrite(session_key, sizeof session_key, 1, fout);
}
fclose(fout);
}
StampOutSecrets();
return fopen_errs; /* 0 errors if successful */
}

View file

@ -0,0 +1,57 @@
/*
* Copyright 1988 by the Massachusetts Institute of Technology.
*
* For copying and distribution information, please see the file
* <mit-copyright.h>.
*
* Description.
*/
#include "adm_locl.h"
RCSID("$Id: kdb_destroy.c,v 1.7 1997/03/31 02:25:21 assar Exp $");
int
main(int argc, char **argv)
{
char answer[10]; /* user input */
char dbm[256]; /* database path and name */
char dbm1[256]; /* database path and name */
#ifdef HAVE_NEW_DB
char *file; /* database file names */
#else
char *file1, *file2; /* database file names */
#endif
set_progname (argv[0]);
strcpy(dbm, DBM_FILE);
#ifdef HAVE_NEW_DB
file = strcat(dbm, ".db");
#else
strcpy(dbm1, DBM_FILE);
file1 = strcat(dbm, ".dir");
file2 = strcat(dbm1, ".pag");
#endif
printf("You are about to destroy the Kerberos database ");
printf("on this machine.\n");
printf("Are you sure you want to do this (y/n)? ");
fgets(answer, sizeof(answer), stdin);
if (answer[0] == 'y' || answer[0] == 'Y') {
#ifdef HAVE_NEW_DB
if (unlink(file) == 0)
#else
if (unlink(file1) == 0 && unlink(file2) == 0)
#endif
{
warnx ("Database deleted at %s", DBM_FILE);
return 0;
}
else
warn ("Database cannot be deleted at %s", DBM_FILE);
} else
warnx ("Database not deleted at %s", DBM_FILE);
return 1;
}

View file

@ -0,0 +1,404 @@
/*
* Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
* of Technology.
*
* For copying and distribution information, please see the file
* <mit-copyright.h>.
*
* This routine changes the Kerberos encryption keys for principals,
* i.e., users or services.
*/
/*
* exit returns 0 ==> success -1 ==> error
*/
#include "adm_locl.h"
RCSID("$Id: kdb_edit.c,v 1.25 1997/05/07 01:34:05 assar Exp $");
#ifdef DEBUG
extern kerb_debug;
#endif
#define zaptime(foo) memset((foo), 0, sizeof(*(foo)))
static int nflag = 0;
static int debug;
static des_cblock new_key;
static int i, j;
static int more;
static char input_name[ANAME_SZ];
static char input_instance[INST_SZ];
#define MAX_PRINCIPAL 10
static Principal principal_data[MAX_PRINCIPAL];
static Principal old_principal;
static Principal default_princ;
static des_cblock master_key;
static des_cblock session_key;
static des_key_schedule master_key_schedule;
static char pw_str[255];
static long master_key_version;
static void
Usage(void)
{
fprintf(stderr, "Usage: %s [-n]\n", __progname);
exit(1);
}
static char *
n_gets(char *buf, int size)
{
char *p;
char *ret;
ret = fgets(buf, size, stdin);
if (ret && (p = strchr(buf, '\n')))
*p = 0;
return ret;
}
static int
change_principal(void)
{
static char temp[255];
int creating = 0;
int editpw = 0;
int changed = 0;
long temp_long; /* Don't change to int32_t, used by scanf */
int n;
struct tm *tp, edate;
fprintf(stdout, "\nPrincipal name: ");
fflush(stdout);
if (!n_gets(input_name, sizeof(input_name)) || *input_name == '\0')
return 0;
fprintf(stdout, "Instance: ");
fflush(stdout);
/* instance can be null */
n_gets(input_instance, sizeof(input_instance));
j = kerb_get_principal(input_name, input_instance, principal_data,
MAX_PRINCIPAL, &more);
if (!j) {
fprintf(stdout, "\n\07\07<Not found>, Create [y] ? ");
fflush(stdout);
n_gets(temp, sizeof(temp)); /* Default case should work, it didn't */
if (temp[0] != 'y' && temp[0] != 'Y' && temp[0] != '\0')
return -1;
/* make a new principal, fill in defaults */
j = 1;
creating = 1;
strcpy(principal_data[0].name, input_name);
strcpy(principal_data[0].instance, input_instance);
principal_data[0].old = NULL;
principal_data[0].exp_date = default_princ.exp_date;
if (strcmp(input_instance, "admin") == 0)
principal_data[0].max_life = 1 + (CLOCK_SKEW/(5*60)); /*5+5 minutes*/
else if (strcmp(input_instance, "root") == 0)
principal_data[0].max_life = 96; /* 8 hours */
else
principal_data[0].max_life = default_princ.max_life;
principal_data[0].attributes = default_princ.attributes;
principal_data[0].kdc_key_ver = (unsigned char) master_key_version;
principal_data[0].key_version = 0; /* bumped up later */
}
tp = k_localtime(&principal_data[0].exp_date);
snprintf(principal_data[0].exp_date_txt,
sizeof(principal_data[0].exp_date_txt),
"%4d-%02d-%02d",
tp->tm_year + 1900,
tp->tm_mon + 1, tp->tm_mday); /* January is 0, not 1 */
for (i = 0; i < j; i++) {
for (;;) {
fprintf(stdout,
"\nPrincipal: %s, Instance: %s, kdc_key_ver: %d",
principal_data[i].name, principal_data[i].instance,
principal_data[i].kdc_key_ver);
fflush(stdout);
editpw = 1;
changed = 0;
if (!creating) {
/*
* copy the existing data so we can use the old values
* for the qualifier clause of the replace
*/
principal_data[i].old = (char *) &old_principal;
memcpy(&old_principal, &principal_data[i],
sizeof(old_principal));
printf("\nChange password [n] ? ");
n_gets(temp, sizeof(temp));
if (strcmp("y", temp) && strcmp("Y", temp))
editpw = 0;
}
/* password */
if (editpw) {
#ifdef NOENCRYPTION
placebo_read_pw_string(pw_str, sizeof pw_str,
"\nNew Password: ", TRUE);
#else
if(des_read_pw_string(pw_str, sizeof pw_str,
"\nNew Password: ", TRUE))
continue;
#endif
if ( strcmp(pw_str, "RANDOM") == 0
|| strcmp(pw_str, "") == 0) {
printf("\nRandom password [y] ? ");
n_gets(temp, sizeof(temp));
if (!strcmp("n", temp) || !strcmp("N", temp)) {
/* no, use literal */
#ifdef NOENCRYPTION
memset(new_key, 0, sizeof(des_cblock));
new_key[0] = 127;
#else
des_string_to_key(pw_str, &new_key);
#endif
memset(pw_str, 0, sizeof pw_str); /* "RANDOM" */
} else {
#ifdef NOENCRYPTION
memset(new_key, 0, sizeof(des_cblock));
new_key[0] = 127;
#else
des_new_random_key(&new_key);
#endif
memset(pw_str, 0, sizeof pw_str);
}
} else if (!strcmp(pw_str, "NULL")) {
printf("\nNull Key [y] ? ");
n_gets(temp, sizeof(temp));
if (!strcmp("n", temp) || !strcmp("N", temp)) {
/* no, use literal */
#ifdef NOENCRYPTION
memset(new_key, 0, sizeof(des_cblock));
new_key[0] = 127;
#else
des_string_to_key(pw_str, &new_key);
#endif
memset(pw_str, 0, sizeof pw_str); /* "NULL" */
} else {
principal_data[i].key_low = 0;
principal_data[i].key_high = 0;
goto null_key;
}
} else {
#ifdef NOENCRYPTION
memset(new_key, 0, sizeof(des_cblock));
new_key[0] = 127;
#else
des_string_to_key(pw_str, &new_key);
#endif
memset(pw_str, 0, sizeof pw_str);
}
/* seal it under the kerberos master key */
kdb_encrypt_key (&new_key, &new_key,
&master_key, master_key_schedule,
DES_ENCRYPT);
copy_from_key(new_key,
&principal_data[i].key_low,
&principal_data[i].key_high);
memset(new_key, 0, sizeof(new_key));
null_key:
/* set master key version */
principal_data[i].kdc_key_ver =
(unsigned char) master_key_version;
/* bump key version # */
principal_data[i].key_version++;
fprintf(stdout,
"\nPrincipal's new key version = %d\n",
principal_data[i].key_version);
fflush(stdout);
changed = 1;
}
/* expiration date */
fprintf(stdout, "Expiration date (enter yyyy-mm-dd) [ %s ] ? ",
principal_data[i].exp_date_txt);
fflush(stdout);
zaptime(&edate);
while (n_gets(temp, sizeof(temp)) && ((n = strlen(temp)) >
sizeof(principal_data[0].exp_date_txt))) {
bad_date:
fprintf(stdout, "\07\07Date Invalid\n");
fprintf(stdout,
"Expiration date (enter yyyy-mm-dd) [ %s ] ? ",
principal_data[i].exp_date_txt);
fflush(stdout);
zaptime(&edate);
}
if (*temp) {
if (sscanf(temp, "%d-%d-%d", &edate.tm_year,
&edate.tm_mon, &edate.tm_mday) != 3)
goto bad_date;
edate.tm_mon--; /* January is 0, not 1 */
edate.tm_hour = 23; /* nearly midnight at the end of the */
edate.tm_min = 59; /* specified day */
if (krb_check_tm (edate))
goto bad_date;
edate.tm_year -= 1900;
temp_long = tm2time (edate, 1);
strcpy(principal_data[i].exp_date_txt, temp);
principal_data[i].exp_date = temp_long;
changed = 1;
}
/* maximum lifetime */
fprintf(stdout, "Max ticket lifetime (*5 minutes) [ %d ] ? ",
principal_data[i].max_life);
fflush(stdout);
while (n_gets(temp, sizeof(temp)) && *temp) {
if (sscanf(temp, "%ld", &temp_long) != 1)
goto bad_life;
if (temp_long > 255 || (temp_long < 0)) {
bad_life:
fprintf(stdout, "\07\07Invalid, choose 0-255\n");
fprintf(stdout,
"Max ticket lifetime (*5 minutes) [ %d ] ? ",
principal_data[i].max_life);
fflush(stdout);
continue;
}
changed = 1;
/* dont clobber */
principal_data[i].max_life = (unsigned short) temp_long;
break;
}
/* attributes */
fprintf(stdout, "Attributes [ %d ] ? ",
principal_data[i].attributes);
fflush(stdout);
while (n_gets(temp, sizeof(temp)) && *temp) {
if (sscanf(temp, "%ld", &temp_long) != 1)
goto bad_att;
if (temp_long > 65535 || (temp_long < 0)) {
bad_att:
fprintf(stdout, "\07\07Invalid, choose 0-65535\n");
fprintf(stdout, "Attributes [ %d ] ? ",
principal_data[i].attributes);
fflush(stdout);
continue;
}
changed = 1;
/* dont clobber */
principal_data[i].attributes =
(unsigned short) temp_long;
break;
}
/*
* remaining fields -- key versions and mod info, should
* not be directly manipulated
*/
if (changed) {
if (kerb_put_principal(&principal_data[i], 1)) {
fprintf(stdout,
"\nError updating Kerberos database");
} else {
fprintf(stdout, "Edit O.K.");
}
} else {
fprintf(stdout, "Unchanged");
}
memset(&principal_data[i].key_low, 0, 4);
memset(&principal_data[i].key_high, 0, 4);
fflush(stdout);
break;
}
}
if (more) {
fprintf(stdout, "\nThere were more tuples found ");
fprintf(stdout, "than there were space for");
}
return 1;
}
static void
cleanup(void)
{
memset(master_key, 0, sizeof(master_key));
memset(session_key, 0, sizeof(session_key));
memset(master_key_schedule, 0, sizeof(master_key_schedule));
memset(principal_data, 0, sizeof(principal_data));
memset(new_key, 0, sizeof(new_key));
memset(pw_str, 0, sizeof(pw_str));
}
int
main(int argc, char **argv)
{
/* Local Declarations */
long n;
set_progname (argv[0]);
while (--argc > 0 && (*++argv)[0] == '-')
for (i = 1; argv[0][i] != '\0'; i++) {
switch (argv[0][i]) {
/* debug flag */
case 'd':
debug = 1;
continue;
/* debug flag */
#ifdef DEBUG
case 'l':
kerb_debug |= 1;
continue;
#endif
case 'n': /* read MKEYFILE for master key */
nflag = 1;
continue;
default:
warnx ("illegal flag \"%c\"", argv[0][i]);
Usage(); /* Give message and die */
}
}
fprintf(stdout, "Opening database...\n");
fflush(stdout);
kerb_init();
if (argc > 0)
if (kerb_db_set_name(*argv) != 0)
errx (1, "Could not open altername database name");
if (kdb_get_master_key ((nflag == 0) ? KDB_GET_PROMPT : 0,
&master_key, master_key_schedule) != 0)
errx (1, "Couldn't read master key.");
if ((master_key_version = kdb_verify_master_key(&master_key,
master_key_schedule,
stdout)) < 0)
return 1;
/* Initialize non shared random sequence */
des_init_random_number_generator(&master_key);
/* lookup the default values */
n = kerb_get_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST,
&default_princ, 1, &more);
if (n != 1)
errx (1, "Kerberos error on default value lookup, %ld found.", n);
fprintf(stdout, "Previous or default values are in [brackets] ,\n");
fprintf(stdout, "enter return to leave the same, or new value.\n");
while (change_principal()) {
}
cleanup();
return 0;
}

View file

@ -0,0 +1,174 @@
/*
* Copyright 1987, 1988 by the Massachusetts Institute of Technology.
*
* For copying and distribution information, please see the file
* <mit-copyright.h>.
*
* program to initialize the database, reports error if database file
* already exists.
*/
#include "adm_locl.h"
RCSID("$Id: kdb_init.c,v 1.23 1997/03/30 17:45:05 assar Exp $");
enum ap_op {
NULL_KEY, /* setup null keys */
MASTER_KEY, /* use master key as new key */
RANDOM_KEY /* choose a random key */
};
static des_cblock master_key;
static des_key_schedule master_key_schedule;
/* use a return code to indicate success or failure. check the return */
/* values of the routines called by this routine. */
static int
add_principal(char *name, char *instance, enum ap_op aap_op, int maxlife)
{
Principal principal;
struct tm *tm;
des_cblock new_key;
memset(&principal, 0, sizeof(principal));
strncpy(principal.name, name, ANAME_SZ);
strncpy(principal.instance, instance, INST_SZ);
switch (aap_op) {
case NULL_KEY:
principal.key_low = 0;
principal.key_high = 0;
break;
case RANDOM_KEY:
#ifdef NOENCRYPTION
memset(new_key, 0, sizeof(des_cblock));
new_key[0] = 127;
#else
des_new_random_key(&new_key);
#endif
kdb_encrypt_key (&new_key, &new_key, &master_key, master_key_schedule,
DES_ENCRYPT);
copy_from_key(new_key, &principal.key_low, &principal.key_high);
memset(new_key, 0, sizeof(new_key));
break;
case MASTER_KEY:
memcpy(new_key, master_key, sizeof (des_cblock));
kdb_encrypt_key (&new_key, &new_key, &master_key, master_key_schedule,
DES_ENCRYPT);
copy_from_key(new_key, &principal.key_low, &principal.key_high);
break;
}
principal.exp_date = 946702799; /* Happy new century */
strncpy(principal.exp_date_txt, "12/31/99", DATE_SZ);
principal.mod_date = time(0);
tm = k_localtime(&principal.mod_date);
principal.attributes = 0;
principal.max_life = maxlife;
principal.kdc_key_ver = 1;
principal.key_version = 1;
strncpy(principal.mod_name, "db_creation", ANAME_SZ);
strncpy(principal.mod_instance, "", INST_SZ);
principal.old = 0;
if (kerb_db_put_principal(&principal, 1) != 1)
return -1; /* FAIL */
/* let's play it safe */
memset(new_key, 0, sizeof (des_cblock));
memset(&principal.key_low, 0, 4);
memset(&principal.key_high, 0, 4);
return 0;
}
int
main(int argc, char **argv)
{
char realm[REALM_SZ];
char *cp;
int code;
char *database;
set_progname (argv[0]);
if (argc > 3) {
fprintf(stderr, "Usage: %s [realm-name] [database-name]\n", argv[0]);
return 1;
}
if (argc == 3) {
database = argv[2];
--argc;
} else
database = DBM_FILE;
/* Do this first, it'll fail if the database exists */
if ((code = kerb_db_create(database)) != 0)
err (1, "Couldn't create database %s", database);
kerb_db_set_name(database);
if (argc == 2)
strncpy(realm, argv[1], REALM_SZ);
else {
if (krb_get_lrealm(realm, 1) != KSUCCESS)
strcpy(realm, KRB_REALM);
fprintf(stderr, "Realm name [default %s ]: ", realm);
if (fgets(realm, sizeof(realm), stdin) == NULL)
errx (1, "\nEOF reading realm");
if ((cp = strchr(realm, '\n')))
*cp = '\0';
if (!*realm) /* no realm given */
if (krb_get_lrealm(realm, 1) != KSUCCESS)
strcpy(realm, KRB_REALM);
}
if (!k_isrealm(realm))
errx (1, "Bad kerberos realm name \"%s\"", realm);
#ifndef RANDOM_MKEY
printf("You will be prompted for the database Master Password.\n");
printf("It is important that you NOT FORGET this password.\n");
#else
printf("To generate a master key, please enter some random data.\n");
printf("You do not have to remember this.\n");
#endif
fflush(stdout);
if (kdb_get_master_key (KDB_GET_TWICE, &master_key,
master_key_schedule) != 0)
errx (1, "Couldn't read master key.");
#ifdef RANDOM_MKEY
if(kdb_kstash(&master_key, MKEYFILE) < 0)
err (1, "Error writing master key");
fprintf(stderr, "Wrote master key to %s\n", MKEYFILE);
#endif
/* Initialize non shared random sequence */
des_init_random_number_generator(&master_key);
/* Maximum lifetime for changepw.kerberos (kadmin) tickets, 10 minutes */
#define ADMLIFE (1 + (CLOCK_SKEW/(5*60)))
/* Maximum lifetime for ticket granting tickets, 4 days or 21.25h */
#define TGTLIFE ((krb_life_to_time(0, 162) >= 24*60*60) ? 161 : 255)
/* This means that default lifetimes have not been initialized */
#define DEFLIFE 255
#define NOLIFE 0
if (
add_principal(KERB_M_NAME, KERB_M_INST, MASTER_KEY, NOLIFE) ||
add_principal(KERB_DEFAULT_NAME, KERB_DEFAULT_INST, NULL_KEY,DEFLIFE)||
add_principal(KRB_TICKET_GRANTING_TICKET, realm, RANDOM_KEY, TGTLIFE)||
add_principal(PWSERV_NAME, KRB_MASTER, RANDOM_KEY, ADMLIFE)
) {
putc ('\n', stderr);
errx (1, "couldn't initialize database.");
}
/* play it safe */
memset(master_key, 0, sizeof (des_cblock));
memset(master_key_schedule, 0, sizeof (des_key_schedule));
return 0;
}

View file

@ -0,0 +1,496 @@
/*
* Copyright 1987, 1988 by the Massachusetts Institute of Technology.
*
* For copying and distribution information, please see the file
* <mit-copyright.h>.
*
* Kerberos database manipulation utility. This program allows you to
* dump a kerberos database to an ascii readable file and load this
* file into the database. Read locking of the database is done during a
* dump operation. NO LOCKING is done during a load operation. Loads
* should happen with other processes shutdown.
*
* Written July 9, 1987 by Jeffrey I. Schiller
*/
#include "adm_locl.h"
RCSID("$Id: kdb_util.c,v 1.35 1997/05/07 00:57:45 assar Exp $");
static des_cblock master_key, new_master_key;
static des_key_schedule master_key_schedule, new_master_key_schedule;
#define zaptime(foo) memset((foo), 0, sizeof(*(foo)))
/* cv_key is a procedure which takes a principle and changes its key,
either for a new method of encrypting the keys, or a new master key.
if cv_key is null no transformation of key is done (other than net byte
order). */
struct callback_args {
void (*cv_key)(Principal *);
FILE *output_file;
};
static void
print_time(FILE *file, time_t timeval)
{
struct tm *tm;
tm = gmtime(&timeval);
fprintf(file, " %04d%02d%02d%02d%02d",
tm->tm_year + 1900,
tm->tm_mon + 1,
tm->tm_mday,
tm->tm_hour,
tm->tm_min);
}
static long
time_explode(char *cp)
{
char wbuf[5];
struct tm tp;
int local;
zaptime(&tp); /* clear out the struct */
if (strlen(cp) > 10) { /* new format */
strncpy(wbuf, cp, 4);
wbuf[4] = 0;
tp.tm_year = atoi(wbuf) - 1900;
cp += 4; /* step over the year */
local = 0; /* GMT */
} else { /* old format: local time,
year is 2 digits, assuming 19xx */
wbuf[0] = *cp++;
wbuf[1] = *cp++;
wbuf[2] = 0;
tp.tm_year = atoi(wbuf);
local = 1; /* local */
}
wbuf[0] = *cp++;
wbuf[1] = *cp++;
wbuf[2] = 0;
tp.tm_mon = atoi(wbuf)-1;
wbuf[0] = *cp++;
wbuf[1] = *cp++;
tp.tm_mday = atoi(wbuf);
wbuf[0] = *cp++;
wbuf[1] = *cp++;
tp.tm_hour = atoi(wbuf);
wbuf[0] = *cp++;
wbuf[1] = *cp++;
tp.tm_min = atoi(wbuf);
return(tm2time(tp, local));
}
static int
dump_db_1(void *arg, Principal *principal)
{ /* replace null strings with "*" */
struct callback_args *a = (struct callback_args *)arg;
if (principal->instance[0] == '\0') {
principal->instance[0] = '*';
principal->instance[1] = '\0';
}
if (principal->mod_name[0] == '\0') {
principal->mod_name[0] = '*';
principal->mod_name[1] = '\0';
}
if (principal->mod_instance[0] == '\0') {
principal->mod_instance[0] = '*';
principal->mod_instance[1] = '\0';
}
if (a->cv_key != NULL) {
(*a->cv_key) (principal);
}
fprintf(a->output_file, "%s %s %d %d %d %d %x %x",
principal->name,
principal->instance,
principal->max_life,
principal->kdc_key_ver,
principal->key_version,
principal->attributes,
(int)htonl (principal->key_low),
(int)htonl (principal->key_high));
print_time(a->output_file, principal->exp_date);
print_time(a->output_file, principal->mod_date);
fprintf(a->output_file, " %s %s\n",
principal->mod_name,
principal->mod_instance);
return 0;
}
static int
dump_db (char *db_file, FILE *output_file, void (*cv_key) (Principal *))
{
struct callback_args a;
a.cv_key = cv_key;
a.output_file = output_file;
kerb_db_iterate ((k_iter_proc_t)dump_db_1, &a);
return fflush(output_file);
}
static int
add_file(void *db, FILE *file)
{
int ret;
int lineno = 0;
char line[1024];
unsigned long key[2]; /* yes, long */
Principal pr;
char exp_date[64], mod_date[64];
int life, kkvno, kvno;
while(1){
memset(&pr, 0, sizeof(pr));
errno = 0;
if(fgets(line, sizeof(line), file) == NULL){
if(errno != 0)
err (1, "fgets");
break;
}
lineno++;
ret = sscanf(line, "%s %s %d %d %d %hd %lx %lx %s %s %s %s",
pr.name, pr.instance,
&life, &kkvno, &kvno,
&pr.attributes,
&key[0], &key[1],
exp_date, mod_date,
pr.mod_name, pr.mod_instance);
if(ret != 12){
warnx("Line %d malformed (ignored)", lineno);
continue;
}
pr.key_low = ntohl (key[0]);
pr.key_high = ntohl (key[1]);
pr.max_life = life;
pr.kdc_key_ver = kkvno;
pr.key_version = kvno;
pr.exp_date = time_explode(exp_date);
pr.mod_date = time_explode(mod_date);
if (pr.instance[0] == '*')
pr.instance[0] = 0;
if (pr.mod_name[0] == '*')
pr.mod_name[0] = 0;
if (pr.mod_instance[0] == '*')
pr.mod_instance[0] = 0;
if (kerb_db_update(db, &pr, 1) != 1) {
warn ("store %s.%s aborted",
pr.name, pr.instance);
return 1;
}
}
return 0;
}
static void
load_db (char *db_file, FILE *input_file)
{
long *db;
int temp1;
int code;
char *temp_db_file;
temp1 = strlen(db_file)+2;
temp_db_file = malloc (temp1);
strcpy(temp_db_file, db_file);
strcat(temp_db_file, "~");
/* Create the database */
if ((code = kerb_db_create(temp_db_file)) != 0)
err (1, "creating temp database %s", temp_db_file);
kerb_db_set_name(temp_db_file);
db = kerb_db_begin_update();
if (db == NULL)
err (1, "opening temp database %s", temp_db_file);
if(add_file(db, input_file))
errx (1, "Load aborted");
kerb_db_end_update(db);
if ((code = kerb_db_rename(temp_db_file, db_file)) != 0)
warn("database rename failed");
fclose(input_file);
free(temp_db_file);
}
static void
merge_db(char *db_file, FILE *input_file)
{
void *db;
db = kerb_db_begin_update();
if(db == NULL)
err (1, "Couldn't open database");
if(add_file(db, input_file))
errx (1, "Merge aborted");
kerb_db_end_update(db);
}
static void
update_ok_file (char *file_name)
{
/* handle slave locking/failure stuff */
char *file_ok;
int fd;
static char ok[]=".dump_ok";
asprintf (&file_ok, "%s%s", file_name, ok);
if (file_ok == NULL)
errx (1, "out of memory");
if ((fd = open(file_ok, O_WRONLY|O_CREAT|O_TRUNC, 0400)) < 0)
err (1, "Error creating %s", file_ok);
free(file_ok);
close(fd);
}
static void
convert_key_new_master (Principal *p)
{
des_cblock key;
/* leave null keys alone */
if ((p->key_low == 0) && (p->key_high == 0)) return;
/* move current key to des_cblock for encryption, special case master key
since that's changing */
if ((strncmp (p->name, KERB_M_NAME, ANAME_SZ) == 0) &&
(strncmp (p->instance, KERB_M_INST, INST_SZ) == 0)) {
memcpy (key, new_master_key, sizeof(des_cblock));
(p->key_version)++;
} else {
copy_to_key(&p->key_low, &p->key_high, key);
kdb_encrypt_key (&key, &key, &master_key, master_key_schedule, DES_DECRYPT);
}
kdb_encrypt_key (&key, &key, &new_master_key, new_master_key_schedule, DES_ENCRYPT);
copy_from_key(key, &(p->key_low), &(p->key_high));
memset(key, 0, sizeof (key)); /* a little paranoia ... */
(p->kdc_key_ver)++;
}
static void
clear_secrets (void)
{
memset(master_key, 0, sizeof (des_cblock));
memset(master_key_schedule, 0, sizeof (des_key_schedule));
memset(new_master_key, 0, sizeof (des_cblock));
memset(new_master_key_schedule, 0, sizeof (des_key_schedule));
}
static void
convert_new_master_key (char *db_file, FILE *out)
{
#ifdef RANDOM_MKEY
errx (1, "Sorry, this function is not available with "
"the new master key scheme.");
#else
printf ("\n\nEnter the CURRENT master key.");
if (kdb_get_master_key (KDB_GET_PROMPT, &master_key,
master_key_schedule) != 0) {
clear_secrets ();
errx (1, "Couldn't get master key.");
}
if (kdb_verify_master_key (&master_key, master_key_schedule, stderr) < 0) {
clear_secrets ();
exit (1);
}
printf ("\n\nNow enter the NEW master key. Do not forget it!!");
if (kdb_get_master_key (KDB_GET_TWICE, &new_master_key,
new_master_key_schedule) != 0) {
clear_secrets ();
errx (1, "Couldn't get new master key.");
}
dump_db (db_file, out, convert_key_new_master);
{
char fname[128];
snprintf(fname, sizeof(fname), "%s.new", MKEYFILE);
kdb_kstash(&new_master_key, fname);
}
#endif /* RANDOM_MKEY */
}
static void
convert_key_old_db (Principal *p)
{
des_cblock key;
/* leave null keys alone */
if ((p->key_low == 0) && (p->key_high == 0)) return;
copy_to_key(&p->key_low, &p->key_high, key);
#ifndef NOENCRYPTION
des_pcbc_encrypt((des_cblock *)key,(des_cblock *)key,
(long)sizeof(des_cblock),master_key_schedule,
(des_cblock *)master_key_schedule, DES_DECRYPT);
#endif
/* make new key, new style */
kdb_encrypt_key (&key, &key, &master_key, master_key_schedule, DES_ENCRYPT);
copy_from_key(key, &(p->key_low), &(p->key_high));
memset(key, 0, sizeof (key)); /* a little paranoia ... */
}
static void
convert_old_format_db (char *db_file, FILE *out)
{
des_cblock key_from_db;
Principal principal_data[1];
int n, more;
if (kdb_get_master_key (KDB_GET_PROMPT, &master_key,
master_key_schedule) != 0L) {
clear_secrets();
errx (1, "Couldn't get master key.");
}
/* can't call kdb_verify_master_key because this is an old style db */
/* lookup the master key version */
n = kerb_get_principal(KERB_M_NAME, KERB_M_INST, principal_data,
1 /* only one please */, &more);
if ((n != 1) || more)
errx (1, "verify_master_key: Kerberos error on master key lookup, %d found.\n", n);
/* set up the master key */
fprintf(stderr, "Current Kerberos master key version is %d.\n",
principal_data[0].kdc_key_ver);
/*
* now use the master key to decrypt (old style) the key in the db, had better
* be the same!
*/
copy_to_key(&principal_data[0].key_low,
&principal_data[0].key_high,
key_from_db);
#ifndef NOENCRYPTION
des_pcbc_encrypt(&key_from_db,&key_from_db,(long)sizeof(key_from_db),
master_key_schedule,(des_cblock *)master_key_schedule, DES_DECRYPT);
#endif
/* the decrypted database key had better equal the master key */
n = memcmp(master_key, key_from_db, sizeof(master_key));
memset(key_from_db, 0, sizeof(key_from_db));
if (n) {
fprintf(stderr, "\n\07\07verify_master_key: Invalid master key, ");
fprintf(stderr, "does not match database.\n");
exit (1);
}
fprintf(stderr, "Master key verified.\n");
dump_db (db_file, out, convert_key_old_db);
}
int
main(int argc, char **argv)
{
int ret;
FILE *file;
enum {
OP_LOAD,
OP_MERGE,
OP_DUMP,
OP_SLAVE_DUMP,
OP_NEW_MASTER,
OP_CONVERT_OLD_DB
} op;
char *file_name;
char *db_name;
set_progname (argv[0]);
if (argc != 3 && argc != 4) {
fprintf(stderr, "Usage: %s operation file [database name].\n",
argv[0]);
fprintf(stderr, "Operation is one of: "
"load, merge, dump, slave_dump, new_master_key, "
"convert_old_db\n");
exit(1);
}
if (argc == 3)
db_name = DBM_FILE;
else
db_name = argv[3];
ret = kerb_db_set_name (db_name);
/* this makes starting slave servers ~14.3 times easier */
if(ret && strcmp(argv[1], "load") == 0)
ret = kerb_db_create (db_name);
if(ret)
err (1, "Can't open database");
if (!strcmp(argv[1], "load"))
op = OP_LOAD;
else if (!strcmp(argv[1], "merge"))
op = OP_MERGE;
else if (!strcmp(argv[1], "dump"))
op = OP_DUMP;
else if (!strcmp(argv[1], "slave_dump"))
op = OP_SLAVE_DUMP;
else if (!strcmp(argv[1], "new_master_key"))
op = OP_NEW_MASTER;
else if (!strcmp(argv[1], "convert_old_db"))
op = OP_CONVERT_OLD_DB;
else {
warnx ("%s is an invalid operation.", argv[1]);
warnx ("Valid operations are \"load\", \"merge\", "
"\"dump\", \"slave_dump\", \"new_master_key\", "
"and \"convert_old_db\"");
return 1;
}
file_name = argv[2];
file = fopen(file_name, (op == OP_LOAD || op == OP_MERGE) ? "r" : "w");
if (file == NULL)
err (1, "open %s", argv[2]);
switch (op) {
case OP_DUMP:
if ((dump_db (db_name, file, (void (*)(Principal *)) 0) == EOF) ||
(fclose(file) == EOF))
err (1, "%s", file_name);
break;
case OP_SLAVE_DUMP:
if ((dump_db (db_name, file, (void (*)(Principal *)) 0) == EOF) ||
(fclose(file) == EOF))
err (1, "%s", file_name);
update_ok_file (file_name);
break;
case OP_LOAD:
load_db (db_name, file);
break;
case OP_MERGE:
merge_db (db_name, file);
break;
case OP_NEW_MASTER:
convert_new_master_key (db_name, file);
printf("Don't forget to do a `kdb_util load %s' to reload the database!\n", file_name);
break;
case OP_CONVERT_OLD_DB:
convert_old_format_db (db_name, file);
printf("Don't forget to do a `kdb_util load %s' to reload the database!\n", file_name);
break;
}
return 0;
}

View file

@ -0,0 +1,56 @@
/*
* Copyright 1985, 1986, 1987, 1988 by the Massachusetts Institute
* of Technology
*
* For copying and distribution information, please see the file
* <mit-copyright.h>.
*
* Description.
*/
#include "adm_locl.h"
RCSID("$Id: kstash.c,v 1.10 1997/03/30 17:35:37 assar Exp $");
/* change this later, but krblib_dbm needs it for now */
static des_cblock master_key;
static des_key_schedule master_key_schedule;
static void
clear_secrets(void)
{
memset(master_key_schedule, 0, sizeof(master_key_schedule));
memset(master_key, 0, sizeof(master_key));
}
int
main(int argc, char **argv)
{
long n;
int ret = 0;
set_progname (argv[0]);
if ((n = kerb_init()))
errx(1, "Kerberos db and cache init failed = %ld\n", n);
if (kdb_get_master_key (KDB_GET_PROMPT, &master_key,
master_key_schedule) != 0) {
clear_secrets();
errx(1, "Couldn't read master key.");
}
if (kdb_verify_master_key (&master_key, master_key_schedule, stderr) < 0) {
clear_secrets();
return 1;
}
ret = kdb_kstash(&master_key, MKEYFILE);
if(ret < 0)
warn("writing master key");
else
fprintf(stderr, "Wrote master key to %s\n", MKEYFILE);
clear_secrets();
return ret;
}

View file

@ -0,0 +1,43 @@
# $Id: Makefile.in,v 1.27 1997/05/20 18:58:37 bg Exp $
srcdir = @srcdir@
VPATH = @srcdir@
SHELL = /bin/sh
@SET_MAKE@
SUBDIRS = sample kauth bsd movemail afsutil \
kpopper xnlock kx otp @APPL_KIP_DIR@ ftp telnet
all:
for i in $(SUBDIRS); \
do (cd $$i && $(MAKE) $(MFLAGS) all); done
Wall:
make CFLAGS="-g -Wall -Wno-comment -Wmissing-prototypes -Wmissing-declarations -D__USE_FIXED_PROTOTYPES__"
install:
for i in $(SUBDIRS); \
do (cd $$i && $(MAKE) $(MFLAGS) install); done
uninstall:
for i in $(SUBDIRS); \
do (cd $$i && $(MAKE) $(MFLAGS) uninstall); done
clean:
for i in $(SUBDIRS); \
do (cd $$i && $(MAKE) $(MFLAGS) clean); done
mostlyclean: clean
distclean:
for i in $(SUBDIRS);\
do (cd $$i && $(MAKE) $(MFLAGS) distclean); done
rm -f Makefile *~
realclean:
for i in $(SUBDIRS); \
do (cd $$i && $(MAKE) $(MFLAGS) realclean); done
.PHONY: all install uninstall clean distclean realclean mostlyclean

View file

@ -0,0 +1,135 @@
# $Id: Makefile.in,v 1.56 1997/05/20 20:35:04 assar Exp $
SHELL = /bin/sh
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
topdir = ../..
CC = @CC@
AR = ar
RANLIB = @RANLIB@
DEFS = @DEFS@ -DBINDIR='"$(bindir)"'
CFLAGS = @CFLAGS@
LD_FLAGS = @LD_FLAGS@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
LIBS = @LIBS@
LIB_DBM = @LIB_DBM@
MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
prefix = @prefix@
exec_prefix = @exec_prefix@
libdir = @libdir@
libexecdir = @libexecdir@
bindir = @bindir@
transform=@program_transform_name@
EXECSUFFIX=@EXECSUFFIX@
# Beware, these are all setuid root programs
PROG_SUIDBIN = rsh$(EXECSUFFIX) \
rcp$(EXECSUFFIX) \
rlogin$(EXECSUFFIX) \
su$(EXECSUFFIX)
PROG_BIN = login$(EXECSUFFIX)
PROG_LIBEXEC = rshd$(EXECSUFFIX) \
rlogind$(EXECSUFFIX)
PROGS = $(PROG_SUIDBIN) $(PROG_BIN) $(PROG_LIBEXEC)
SOURCES = rsh.c kcmd.c krcmd.c rlogin.c rcp.c rcp_util.c rshd.c \
login.c klogin.c login_access.c su.c rlogind.c iruserok.c \
login_fbtab.c forkpty.c sysv_default.c sysv_environ.c sysv_shadow.c \
utmp_login.c utmpx_login.c stty_default.c encrypt.c rcmd_util.c tty.c
rsh_OBJS = rsh.o kcmd.o krcmd.o encrypt.o rcmd_util.o
rcp_OBJS = rcp.o rcp_util.o kcmd.o krcmd.o encrypt.o rcmd_util.o
rlogin_OBJS = rlogin.o kcmd.o krcmd.o encrypt.o rcmd_util.o
login_OBJS = login.o klogin.o login_fbtab.o login_access.o \
sysv_default.o sysv_environ.o sysv_shadow.o \
utmp_login.o utmpx_login.o stty_default.o tty.o
su_OBJS = su.o
rshd_OBJS = rshd.o iruserok.o encrypt.o rcmd_util.o
rlogind_OBJS = rlogind.o iruserok.o forkpty.o encrypt.o rcmd_util.o tty.o
all: $(PROGS)
Wall:
make CFLAGS="-g -Wall -Wno-comment -Wmissing-prototypes -Wmissing-declarations -D__USE_FIXED_PROTOTYPES__"
.c.o:
$(CC) -c $(CPPFLAGS) $(DEFS) -I../../include -I$(srcdir) $(CFLAGS) $<
install: all
$(MKINSTALLDIRS) $(libexecdir)
for x in $(PROG_LIBEXEC); do \
$(INSTALL_PROGRAM) $$x $(libexecdir)/`echo $$x| sed '$(transform)'`; \
done
$(MKINSTALLDIRS) $(bindir)
for x in $(PROG_BIN); do \
$(INSTALL_PROGRAM) $$x $(bindir)/`echo $$x| sed '$(transform)'`; \
done
-for x in $(PROG_SUIDBIN); do \
$(INSTALL_PROGRAM) -o root -m 04555 $$x $(bindir)/`echo $$x| sed '$(transform)'`; \
done
uninstall:
for x in $(PROG_LIBEXEC); do \
rm -f $(libexecdir)/`echo $$x| sed '$(transform)'`; \
done
for x in $(PROG_BIN); do \
rm -f $(bindir)/`echo $$x| sed '$(transform)'`; \
done
for x in $(PROG_SUIDBIN); do \
rm -f $(bindir)/`echo $$x| sed '$(transform)'`; \
done
TAGS: $(SOURCES)
etags $(SOURCES)
check:
clean:
rm -f *.a *.o $(PROGS)
mostlyclean: clean
distclean: clean
rm -f Makefile *.tab.c *~
realclean: distclean
rm -f TAGS
dist: $(DISTFILES)
for file in $(DISTFILES); do \
ln $$file ../`cat ../.fname`/lib \
|| cp -p $$file ../`cat ../.fname`/lib; \
done
KLIB=-L../../lib/krb -lkrb -L../../lib/des -ldes
KLIB_AFS=@KRB_KAFS_LIB@ $(KLIB)
OTPLIB=-L../../lib/otp -lotp
LIBROKEN=-L../../lib/roken -lroken
rcp$(EXECSUFFIX): $(rcp_OBJS)
$(CC) $(LD_FLAGS) $(LDFLAGS) -o $@ $(rcp_OBJS) $(KLIB_AFS) $(LIBROKEN) $(LIBS) $(LIBROKEN)
rsh$(EXECSUFFIX): $(rsh_OBJS)
$(CC) $(LD_FLAGS) $(LDFLAGS) -o $@ $(rsh_OBJS) $(KLIB) $(LIBROKEN) $(LIBS) $(LIBROKEN)
rshd$(EXECSUFFIX): $(rshd_OBJS)
$(CC) $(LD_FLAGS) $(LDFLAGS) -o $@ $(rshd_OBJS) $(KLIB_AFS) $(LIBROKEN) $(LIBS) $(LIBROKEN)
rlogin$(EXECSUFFIX): $(rlogin_OBJS)
$(CC) $(LD_FLAGS) $(LDFLAGS) -o $@ $(rlogin_OBJS) $(KLIB) $(LIBROKEN) $(LIBS) $(LIBROKEN)
rlogind$(EXECSUFFIX): $(rlogind_OBJS)
$(CC) $(LD_FLAGS) $(LDFLAGS) -o $@ $(rlogind_OBJS) $(KLIB_AFS) $(LIBROKEN) $(LIBS) $(LIBROKEN)
login$(EXECSUFFIX): $(login_OBJS)
$(CC) $(LD_FLAGS) $(LDFLAGS) -o $@ $(login_OBJS) $(OTPLIB) $(KLIB_AFS) $(LIBROKEN) $(LIB_DBM) $(LIBS) $(LIBROKEN)
su$(EXECSUFFIX): $(su_OBJS)
$(CC) $(LD_FLAGS) $(LDFLAGS) -o $@ $(su_OBJS) $(KLIB_AFS) $(LIBROKEN) $(LIBS) $(LIBROKEN)

View file

@ -0,0 +1,20 @@
This login has additional functionalities. They are all based on (part of)
Wietse Venema's logdaemon package.
The following defines can be used:
1) LOGIN_ACCESS to allow access control on a per tty/user combination
2) LOGALL to log all logins
-Guido
This login has some of Berkeley's paranoid/broken (depending on your point
of view) Kerberos code conditionalized out, so that by default it works like
klogin does at MIT-LCS. You can define KLOGIN_PARANOID to re-enable this code.
This define also controls whether a warning message is printed when logging
into a system with no krb.conf file, which usually means that Kerberos is
not configured.
-GAWollman
(removed S/Key, /assar)

View file

@ -0,0 +1,380 @@
/*
* Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Kungliga Tekniska
* Högskolan and its contributors.
*
* 4. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*/
/* $Id: bsd_locl.h,v 1.98 1997/05/25 01:14:17 assar Exp $ */
#define LOGALL
#define KERBEROS
#define KLOGIN_PARANOID
#define LOGIN_ACCESS
#define PASSWD_FALLBACK
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
/* Any better way to test NO_MOTD? */
#if (SunOS == 5) || defined(__hpux)
#define NO_MOTD
#endif
#ifdef HAVE_SHADOW_H
#define SYSV_SHADOW
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <setjmp.h>
#include <stdarg.h>
#include <errno.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef TIME_WITH_SYS_TIME
#include <sys/time.h>
#include <time.h>
#elif defined(HAVE_SYS_TIME_H)
#include <sys/time.h>
#else
#include <time.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifndef S_ISTXT
#ifdef S_ISVTX
#define S_ISTXT S_ISVTX
#else
#define S_ISTXT 0
#endif
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_DIRENT_H
#include <dirent.h>
#endif
#include <signal.h>
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
#endif /* HAVE_SYS_RESOURCE_H */
#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#ifndef NCARGS
#define NCARGS 0x100000 /* (absolute) max # characters in exec arglist */
#endif
#ifdef HAVE_PWD_H
#include <pwd.h>
#endif
#ifdef HAVE_GRP_H
#include <grp.h>
#endif
#ifdef HAVE_UTIME_H
#include <utime.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_NETINET_IN_SYSTM_H
#include <netinet/in_systm.h>
#endif
#ifdef HAVE_NETINET_IP_H
#include <netinet/ip.h>
#endif
#ifdef HAVE_NETINET_TCP_H
#include <netinet/tcp.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#if defined(HAVE_SYS_IOCTL_H) && SunOS != 4
#include <sys/ioctl.h>
#endif
#ifdef HAVE_SYS_IOCCOM_H
#include <sys/ioccom.h>
#endif
#ifdef HAVE_SYS_SOCKIO_H
#include <sys/sockio.h>
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#ifdef HAVE_SYS_FILIO_H
#include <sys/filio.h>
#endif
#ifdef HAVE_SYS_STREAM_H
#ifdef HAVE_SYS_UIO_H
#include <sys/uio.h>
#endif /* HAVE_SYS_UIO_H */
#include <sys/stream.h>
#endif /* HAVE_SYS_STREAM_H */
#ifdef HAVE_SYS_PTYVAR_H
#ifdef HAVE_SYS_PROC_H
#include <sys/proc.h>
#endif
#ifdef HAVE_SYS_TTY_H
#include <sys/tty.h>
#endif
#ifdef HAVE_SYS_PTYIO_H
#include <sys/ptyio.h>
#endif
#include <sys/ptyvar.h>
#endif /* HAVE_SYS_PTYVAR_H */
/* Cray stuff */
#ifdef HAVE_UDB_H
#include <udb.h>
#endif
#ifdef HAVE_SYS_CATEGORY_H
#include <sys/category.h>
#endif
/* Strange ioctls that are not always defined */
#ifndef TIOCPKT_FLUSHWRITE
#define TIOCPKT_FLUSHWRITE 0x02
#endif
#ifndef TIOCPKT_NOSTOP
#define TIOCPKT_NOSTOP 0x10
#endif
#ifndef TIOCPKT_DOSTOP
#define TIOCPKT_DOSTOP 0x20
#endif
#ifndef TIOCPKT
#define TIOCPKT _IOW('t', 112, int) /* pty: set/clear packet mode */
#endif
#ifdef HAVE_LASTLOG_H
#include <lastlog.h>
#endif
#ifdef HAVE_LOGIN_H
#include <login.h>
#endif
#ifdef HAVE_TTYENT_H
#include <ttyent.h>
#endif
#ifdef HAVE_STROPTS_H
#include <stropts.h>
#endif
#ifdef HAVE_UTMP_H
#include <utmp.h>
#endif
#ifndef UT_NAMESIZE
#define UT_NAMESIZE sizeof(((struct utmp *)0)->ut_name)
#endif
#ifdef HAVE_UTMPX_H
#include <utmpx.h>
#endif
#ifdef HAVE_USERPW_H
#include <userpw.h>
#endif /* HAVE_USERPW_H */
#ifdef HAVE_USERSEC_H
#include <usersec.h>
#endif /* HAVE_USERSEC_H */
#ifndef PRIO_PROCESS
#define PRIO_PROCESS 0
#endif
#include <err.h>
#include <roken.h>
#ifdef SOCKS
#include <socks.h>
#endif
#include <des.h>
#include <krb.h>
#include <kafs.h>
int kcmd(int *sock, char **ahost, u_int16_t rport, char *locuser,
char *remuser, char *cmd, int *fd2p, KTEXT ticket,
char *service, char *realm, CREDENTIALS *cred,
Key_schedule schedule, MSG_DAT *msg_data,
struct sockaddr_in *laddr, struct sockaddr_in *faddr,
int32_t authopts);
int krcmd(char **ahost, u_int16_t rport, char *remuser, char *cmd,
int *fd2p, char *realm);
int krcmd_mutual(char **ahost, u_int16_t rport, char *remuser,
char *cmd,int *fd2p, char *realm,
CREDENTIALS *cred, Key_schedule sched);
int klogin(struct passwd *pw, char *instance, char *localhost, char *password);
typedef struct {
int cnt;
char *buf;
} BUF;
char *colon(char *cp);
int okname(char *cp0);
int susystem(char *s, int userid);
int forkpty(int *amaster, char *name,
struct termios *termp, struct winsize *winp);
#ifndef MODEMASK
#define MODEMASK (S_ISUID|S_ISGID|S_ISTXT|S_IRWXU|S_IRWXG|S_IRWXO)
#endif
#ifdef HAVE_PATHS_H
#include <paths.h>
#endif
#ifdef HAVE_MAILLOCK_H
#include <maillock.h>
#endif
#include "pathnames.h"
void stty_default (void);
int utmpx_login(char *line, char *user, char *host);
extern char **environ;
void sysv_newenv(int argc, char **argv, struct passwd *pwd,
char *term, int pflag);
int login_access(char *user, char *from);
#ifndef HAVE_IRUSEROK
int iruserok(u_int32_t raddr, int superuser, const char *ruser,
const char *luser);
#endif
void fatal(int f, const char *msg, int syserr);
extern int LEFT_JUSTIFIED;
int des_enc_read(int fd,char *buf,int len,des_key_schedule sched,
des_cblock *iv);
int des_enc_write(int fd,char *buf,int len,des_key_schedule sched,
des_cblock *iv);
void sysv_defaults(void);
void utmp_login(char *tty, char *username, char *hostname);
void sleepexit (int);
#ifndef HAVE_SETPRIORITY
#define setpriority(which, who, niceval) 0
#endif
#ifndef HAVE_GETPRIORITY
#define getpriority(which, who) 0
#endif
#ifdef HAVE_TERMIOS_H
#include <termios.h>
#endif
#ifndef _POSIX_VDISABLE
#define _POSIX_VDISABLE 0
#endif /* _POSIX_VDISABLE */
#if SunOS == 4
#include <sys/ttold.h>
#endif
#if defined(_AIX)
#include <sys/termio.h>
#endif
#ifndef CEOF
#define CEOF 04
#endif
/* concession to Sun */
#ifndef SIGUSR1
#define SIGUSR1 30
#endif
#ifndef TIOCPKT_WINDOW
#define TIOCPKT_WINDOW 0x80
#endif
int get_shell_port(int kerberos, int encryption);
int get_login_port(int kerberos, int encryption);
int speed_t2int (speed_t);
speed_t int2speed_t (int);
void ip_options_and_die (int sock, struct sockaddr_in *);
void warning(const char *fmt, ...)
#ifdef __GNUC__
__attribute__ ((format (printf, 1, 2)))
#endif
;
char *clean_ttyname (char *tty);
char *make_id (char *tty);
void prepare_utmp (struct utmp *utmp, char *tty, char *username,
char *hostname);

View file

@ -0,0 +1,311 @@
/* Copyright (C) 1995 Eric Young (eay@mincom.oz.au)
* All rights reserved.
*
* This file is part of an SSL implementation written
* by Eric Young (eay@mincom.oz.au).
* The implementation was written so as to conform with Netscapes SSL
* specification. This library and applications are
* FREE FOR COMMERCIAL AND NON-COMMERCIAL USE
* as long as the following conditions are aheared to.
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed. If this code is used in a product,
* Eric Young should be given attribution as the author of the parts used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Eric Young (eay@mincom.oz.au)
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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 AUTHOR 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.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.]
*/
#include "bsd_locl.h"
RCSID("$Id: encrypt.c,v 1.3 1996/04/30 13:50:54 bg Exp $");
#undef BSIZE
/* used in des_read and des_write */
#define MAXWRITE (1024*16)
#define BSIZE (MAXWRITE+4)
/* replacements for htonl and ntohl since I have no idea what to do
* when faced with machines with 8 byte longs. */
#define HDRSIZE 4
#define n2l(c,l) (l =((u_int32_t)(*((c)++)))<<24, \
l|=((u_int32_t)(*((c)++)))<<16, \
l|=((u_int32_t)(*((c)++)))<< 8, \
l|=((u_int32_t)(*((c)++))))
#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \
*((c)++)=(unsigned char)(((l)>>16)&0xff), \
*((c)++)=(unsigned char)(((l)>> 8)&0xff), \
*((c)++)=(unsigned char)(((l) )&0xff))
/* This has some uglies in it but it works - even over sockets. */
extern int errno;
int des_rw_mode=DES_PCBC_MODE;
int LEFT_JUSTIFIED = 0;
int
des_enc_read(int fd, char *buf, int len, struct des_ks_struct *sched, des_cblock *iv)
{
/* data to be unencrypted */
int net_num=0;
unsigned char net[BSIZE];
/* extra unencrypted data
* for when a block of 100 comes in but is des_read one byte at
* a time. */
static char unnet[BSIZE];
static int unnet_start=0;
static int unnet_left=0;
int i;
long num=0,rnum;
unsigned char *p;
/* left over data from last decrypt */
if (unnet_left != 0)
{
if (unnet_left < len)
{
/* we still still need more data but will return
* with the number of bytes we have - should always
* check the return value */
memcpy(buf,&(unnet[unnet_start]),unnet_left);
/* eay 26/08/92 I had the next 2 lines
* reversed :-( */
i=unnet_left;
unnet_start=unnet_left=0;
}
else
{
memcpy(buf,&(unnet[unnet_start]),len);
unnet_start+=len;
unnet_left-=len;
i=len;
}
return(i);
}
/* We need to get more data. */
if (len > MAXWRITE) len=MAXWRITE;
/* first - get the length */
net_num=0;
while (net_num < HDRSIZE)
{
i=read(fd,&(net[net_num]),(unsigned int)HDRSIZE-net_num);
if ((i == -1) && (errno == EINTR)) continue;
if (i <= 0) return(0);
net_num+=i;
}
/* we now have at net_num bytes in net */
p=net;
num=0;
n2l(p,num);
/* num should be rounded up to the next group of eight
* we make sure that we have read a multiple of 8 bytes from the net.
*/
if ((num > MAXWRITE) || (num < 0)) /* error */
return(-1);
rnum=(num < 8)?8:((num+7)/8*8);
net_num=0;
while (net_num < rnum)
{
i=read(fd,&(net[net_num]),(unsigned int)rnum-net_num);
if ((i == -1) && (errno == EINTR)) continue;
if (i <= 0) return(0);
net_num+=i;
}
/* Check if there will be data left over. */
if (len < num)
{
if (des_rw_mode & DES_PCBC_MODE)
des_pcbc_encrypt((des_cblock *)net,(des_cblock *)unnet,
num,sched,iv,DES_DECRYPT);
else
des_cbc_encrypt((des_cblock *)net,(des_cblock *)unnet,
num,sched,iv,DES_DECRYPT);
memcpy(buf,unnet,len);
unnet_start=len;
unnet_left=num-len;
/* The following line is done because we return num
* as the number of bytes read. */
num=len;
}
else
{
/* >output is a multiple of 8 byes, if len < rnum
* >we must be careful. The user must be aware that this
* >routine will write more bytes than he asked for.
* >The length of the buffer must be correct.
* FIXED - Should be ok now 18-9-90 - eay */
if (len < rnum)
{
char tmpbuf[BSIZE];
if (des_rw_mode & DES_PCBC_MODE)
des_pcbc_encrypt((des_cblock *)net,
(des_cblock *)tmpbuf,
num,sched,iv,DES_DECRYPT);
else
des_cbc_encrypt((des_cblock *)net,
(des_cblock *)tmpbuf,
num,sched,iv,DES_DECRYPT);
/* eay 26/08/92 fix a bug that returned more
* bytes than you asked for (returned len bytes :-( */
if (LEFT_JUSTIFIED || (len >= 8))
memcpy(buf,tmpbuf,num);
else
memcpy(buf,tmpbuf+(8-num),num); /* Right justified */
}
else if (num >= 8)
{
if (des_rw_mode & DES_PCBC_MODE)
des_pcbc_encrypt((des_cblock *)net,
(des_cblock *)buf,num,sched,iv,
DES_DECRYPT);
else
des_cbc_encrypt((des_cblock *)net,
(des_cblock *)buf,num,sched,iv,
DES_DECRYPT);
}
else
{
if (des_rw_mode & DES_PCBC_MODE)
des_pcbc_encrypt((des_cblock *)net,
(des_cblock *)buf,8,sched,iv,
DES_DECRYPT);
else
des_cbc_encrypt((des_cblock *)net,
(des_cblock *)buf,8,sched,iv,
DES_DECRYPT);
if (!LEFT_JUSTIFIED)
memcpy(buf, buf+(8-num), num); /* Right justified */
}
}
return(num);
}
int
des_enc_write(int fd, char *buf, int len, struct des_ks_struct *sched, des_cblock *iv)
{
long rnum;
int i,j,k,outnum;
char outbuf[BSIZE+HDRSIZE];
char shortbuf[8];
char *p;
static int start=1;
/* If we are sending less than 8 bytes, the same char will look
* the same if we don't pad it out with random bytes */
if (start)
{
start=0;
srand(time(NULL));
}
/* lets recurse if we want to send the data in small chunks */
if (len > MAXWRITE)
{
j=0;
for (i=0; i<len; i+=k)
{
k=des_enc_write(fd,&(buf[i]),
((len-i) > MAXWRITE)?MAXWRITE:(len-i),sched,iv);
if (k < 0)
return(k);
else
j+=k;
}
return(j);
}
/* write length first */
p=outbuf;
l2n(len,p);
/* pad short strings */
if (len < 8)
{
if (LEFT_JUSTIFIED)
{
p=shortbuf;
memcpy(shortbuf,buf,(unsigned int)len);
for (i=len; i<8; i++)
shortbuf[i]=rand();
rnum=8;
}
else
{
p=shortbuf;
for (i=0; i<8-len; i++)
shortbuf[i]=rand();
memcpy(shortbuf + 8 - len, buf, len);
rnum=8;
}
}
else
{
p=buf;
rnum=((len+7)/8*8); /* round up to nearest eight */
}
if (des_rw_mode & DES_PCBC_MODE)
des_pcbc_encrypt((des_cblock *)p,(des_cblock *)&(outbuf[HDRSIZE]),
(long)((len<8)?8:len),sched,iv,DES_ENCRYPT);
else
des_cbc_encrypt((des_cblock *)p,(des_cblock *)&(outbuf[HDRSIZE]),
(long)((len<8)?8:len),sched,iv,DES_ENCRYPT);
/* output */
outnum=rnum+HDRSIZE;
for (j=0; j<outnum; j+=i)
{
/* eay 26/08/92 I was not doing writing from where we
* got upto. */
i=write(fd,&(outbuf[j]),(unsigned int)(outnum-j));
if (i == -1)
{
if (errno == EINTR)
i=0;
else /* This is really a bad error - very bad
* It will stuff-up both ends. */
return(-1);
}
}
return(len);
}

View file

@ -0,0 +1,461 @@
/*
* Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Kungliga Tekniska
* Högskolan and its contributors.
*
* 4. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*/
#include "bsd_locl.h"
#ifndef HAVE_FORKPTY
RCSID("$Id: forkpty.c,v 1.52 1997/05/25 07:37:01 assar Exp $");
/* Only CRAY is known to have problems with forkpty(). */
#if defined(CRAY)
static int forkpty_ok = 0;
#else
static int forkpty_ok = 1;
#endif
#ifndef HAVE_PTSNAME
static char *ptsname(int fd)
{
#ifdef HAVE_TTYNAME
return ttyname(fd);
#else
return NULL;
#endif
}
#endif
#ifndef HAVE_GRANTPT
#define grantpt(fdm) (0)
#endif
#ifndef HAVE_UNLOCKPT
#define unlockpt(fdm) (0)
#endif
#ifndef HAVE_VHANGUP
#define vhangup() (0)
#endif
#ifndef HAVE_REVOKE
static
void
revoke(char *line)
{
int slave;
RETSIGTYPE (*ofun)();
if ( (slave = open(line, O_RDWR)) < 0)
return;
ofun = signal(SIGHUP, SIG_IGN);
vhangup();
signal(SIGHUP, ofun);
/*
* Some systems (atleast SunOS4) want to have the slave end open
* at all times to prevent a race in the child. Login will close
* it so it should really not be a problem. However for the
* paranoid we use the close on exec flag so it will only be open
* in the parent. Additionally since this will be the controlling
* tty of rlogind the final vhangup() in rlogind should hangup all
* processes. A working revoke would of course have been prefered
* though (sigh).
*/
fcntl(slave, F_SETFD, 1);
/* close(slave); */
}
#endif
static int pty_major, pty_minor;
static void
pty_scan_start(void)
{
pty_major = -1;
pty_minor = 0;
}
static char *bsd_1 = "0123456789abcdefghijklmnopqrstuv";
/* there are many more */
static char *bsd_2 = "pqrstuvwxyzabcdefghijklmnoABCDEFGHIJKLMNOPQRSTUVWXYZ";
static int
pty_scan_next(char *buf, size_t sz)
{
#ifdef CRAY
if(++pty_major >= sysconf(_SC_CRAY_NPTY))
return -1;
snprintf(buf, sz, "/dev/pty/%03d", pty_major);
#else
if(++pty_major == strlen(bsd_1)){
pty_major = 0;
if(++pty_minor == strlen(bsd_2))
return -1;
}
#ifdef __hpux
snprintf(buf, sz, "/dev/ptym/pty%c%c", bsd_2[pty_major], bsd_1[pty_minor]);
#else
snprintf(buf, sz, "/dev/pty%c%c", bsd_2[pty_major], bsd_1[pty_minor]);
#endif /* __hpux */
#endif /* CRAY */
return 0;
}
static void
pty_scan_tty(char *buf, size_t sz)
{
#ifdef CRAY
snprintf(buf, sz, "/dev/ttyp%03d", pty_major);
#elif defined(__hpux)
snprintf(buf, sz, "/dev/pty/tty%c%c", bsd_2[pty_major], bsd_1[pty_minor]);
#else
snprintf(buf, sz, "/dev/tty%c%c", bsd_2[pty_major], bsd_1[pty_minor]);
#endif
}
static int
ptym_open_streams_flavor(char *pts_name, int *streams_pty)
{
/* Try clone device master ptys */
const char *const clone[] = { "/dev/ptc", "/dev/ptmx",
"/dev/ptm", "/dev/ptym/clone", 0 };
int fdm;
const char *const *q;
for (q = clone; *q; q++) {
fdm = open(*q, O_RDWR);
if (fdm >= 0)
break;
}
if (fdm >= 0) {
char *ptr1;
if ((ptr1 = ptsname(fdm)) != NULL) /* Get slave's name */
strcpy(pts_name, ptr1); /* Return name of slave */
else {
close(fdm);
return(-4);
}
if (grantpt(fdm) < 0) { /* Grant access to slave */
close(fdm);
return(-2);
}
if (unlockpt(fdm) < 0) { /* Clear slave's lock flag */
close(fdm);
return(-3);
}
return(fdm); /* return fd of master */
}
return -1;
}
static int
ptym_open_bsd_flavor(char *pts_name, int *streams_pty)
{
int fdm;
char ptm[MaxPathLen];
pty_scan_start();
while (pty_scan_next(ptm, sizeof(ptm)) != -1) {
fdm = open(ptm, O_RDWR);
if (fdm < 0)
continue;
#if SunOS == 4
/* Avoid a bug in SunOS4 ttydriver */
if (fdm > 0) {
int pgrp;
if ((ioctl(fdm, TIOCGPGRP, &pgrp) == -1)
&& (errno == EIO))
/* All fine */;
else {
close(fdm);
continue;
}
}
#endif
pty_scan_tty(pts_name, sizeof(ptm));
#if CRAY
/* this is some magic from the telnet code */
{
struct stat sb;
if(stat(pts_name, &sb) < 0) {
close(fdm);
continue;
}
if(sb.st_uid || sb.st_gid || sb.st_mode != 0600) {
chown(pts_name, 0, 0);
chmod(pts_name, 0600);
close(fdm);
fdm = open(ptm, 2);
if (fdm < 0)
continue;
}
}
/*
* Now it should be safe...check for accessability.
*/
if (access(pts_name, 6) != 0){
/* no tty side to pty so skip it */
close(fdm);
continue;
}
#endif
return fdm; /* All done! */
}
/* We failed to find BSD style pty */
errno = ENOENT;
return -1;
}
/*
*
* Open a master pty either using the STREAM flavor or the BSD flavor.
* Depending on if there are any free ptys in the different classes we
* need to try both. Normally try STREAMS first and then BSD.
*
* Kludge alert: Under HP-UX 10 and perhaps other systems STREAM ptys
* doesn't get initialized properly so we try them in different order
* until the problem has been resolved.
*
*/
static int
ptym_open(char *pts_name, size_t pts_name_sz, int *streams_pty)
{
int fdm;
#ifdef HAVE__GETPTY
{
char *p = _getpty(&fdm, O_RDWR, 0600, 1);
if (p) {
*streams_pty = 1;
strcpy (pts_name, p);
return fdm;
}
}
#endif
#ifdef STREAMSPTY
fdm = ptym_open_streams_flavor(pts_name, streams_pty);
if (fdm >= 0)
{
*streams_pty = 1;
return fdm;
}
#endif
fdm = ptym_open_bsd_flavor(pts_name, streams_pty);
if (fdm >= 0)
{
*streams_pty = 0;
return fdm;
}
#ifndef STREAMSPTY
fdm = ptym_open_streams_flavor(pts_name, streams_pty);
if (fdm >= 0)
{
*streams_pty = 1;
return fdm;
}
#endif
return -1;
}
static int
maybe_push_modules(int fd, char **modules)
{
#ifdef I_PUSH
char **p;
int err;
for(p=modules; *p; p++){
err=ioctl(fd, I_FIND, *p);
if(err == 1)
break;
if(err < 0 && errno != EINVAL)
return -17;
/* module not pushed or does not exist */
}
/* p points to null or to an already pushed module, now push all
modules before this one */
for(p--; p >= modules; p--){
err = ioctl(fd, I_PUSH, *p);
if(err < 0 && errno != EINVAL)
return -17;
}
#endif
return 0;
}
static int
ptys_open(int fdm, char *pts_name, int streams_pty)
{
int fds;
if (streams_pty) {
/* Streams style slave ptys */
if ( (fds = open(pts_name, O_RDWR)) < 0) {
close(fdm);
return(-5);
}
{
char *ttymodules[] = { "ttcompat", "ldterm", "ptem", NULL };
char *ptymodules[] = { "pckt", NULL };
if(maybe_push_modules(fds, ttymodules)<0){
close(fdm);
close(fds);
return -6;
}
if(maybe_push_modules(fdm, ptymodules)<0){
close(fdm);
close(fds);
return -7;
}
}
} else {
/* BSD style slave ptys */
struct group *grptr;
int gid;
if ( (grptr = getgrnam("tty")) != NULL)
gid = grptr->gr_gid;
else
gid = -1; /* group tty is not in the group file */
/* Grant access to slave */
chown(pts_name, getuid(), gid);
chmod(pts_name, S_IRUSR | S_IWUSR | S_IWGRP);
if ( (fds = open(pts_name, O_RDWR)) < 0) {
close(fdm);
return(-1);
}
}
return(fds);
}
int
forkpty(int *ptrfdm,
char *slave_name,
struct termios *slave_termios,
struct winsize *slave_winsize)
{
int fdm, fds, streams_pty;
pid_t pid;
char pts_name[20];
if (!forkpty_ok)
fatal(0, "Protocol not yet supported, use telnet", 0);
if ( (fdm = ptym_open(pts_name, sizeof(pts_name), &streams_pty)) < 0)
return -1;
if (slave_name != NULL)
strcpy(slave_name, pts_name); /* Return name of slave */
pid = fork();
if (pid < 0)
return(-1);
else if (pid == 0) { /* Child */
if (setsid() < 0)
fatal(0, "setsid() failure", errno);
revoke(slave_name);
#if defined(NeXT) || defined(ultrix)
/* The NeXT is severely broken, this makes things slightly
* better but we still doesn't get a working pty. If there
* where a TIOCSCTTY we could perhaps fix things but... The
* same problem also exists in xterm! */
if (setpgrp(0, 0) < 0)
fatal(0, "NeXT kludge failed setpgrp", errno);
#endif
/* SVR4 acquires controlling terminal on open() */
if ( (fds = ptys_open(fdm, pts_name, streams_pty)) < 0)
return -1;
close(fdm); /* All done with master in child */
#if defined(TIOCSCTTY) && !defined(CIBAUD) && !defined(__hpux)
/* 44BSD way to acquire controlling terminal */
/* !CIBAUD to avoid doing this under SunOS */
if (ioctl(fds, TIOCSCTTY, (char *) 0) < 0)
return -1;
#endif
#if defined(NeXT)
{
int t = open("/dev/tty", O_RDWR);
if (t < 0)
fatal(0, "Failed to open /dev/tty", errno);
close(fds);
fds = t;
}
#endif
/* Set slave's termios and window size */
if (slave_termios != NULL) {
if (tcsetattr(fds, TCSANOW, slave_termios) < 0)
return -1;
}
#ifdef TIOCSWINSZ
if (slave_winsize != NULL) {
if (ioctl(fds, TIOCSWINSZ, slave_winsize) < 0)
return -1;
}
#endif
/* slave becomes stdin/stdout/stderr of child */
if (dup2(fds, STDIN_FILENO) != STDIN_FILENO)
return -1;
if (dup2(fds, STDOUT_FILENO) != STDOUT_FILENO)
return -1;
if (dup2(fds, STDERR_FILENO) != STDERR_FILENO)
return -1;
if (fds > STDERR_FILENO)
close(fds);
return(0); /* child returns 0 just like fork() */
}
else { /* Parent */
*ptrfdm = fdm; /* Return fd of master */
return(pid); /* Parent returns pid of child */
}
}
#endif /* HAVE_FORKPTY */

View file

@ -0,0 +1,279 @@
/*
* Copyright (c) 1983, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*/
#include "bsd_locl.h"
RCSID("$Id: iruserok.c,v 1.15 1997/03/23 04:54:00 assar Exp $");
#ifndef HAVE_IRUSEROK
int __check_rhosts_file = 1;
char *__rcmd_errstr = 0;
/*
* Returns "true" if match, 0 if no match.
*/
static
int
__icheckhost(u_int32_t raddr, const char *lhost)
{
struct hostent *hp;
u_long laddr;
char **pp;
/* Try for raw ip address first. */
if (isdigit(*lhost) && (long)(laddr = inet_addr(lhost)) != -1)
return (raddr == laddr);
/* Better be a hostname. */
if ((hp = gethostbyname(lhost)) == NULL)
return (0);
/* Spin through ip addresses. */
for (pp = hp->h_addr_list; *pp; ++pp)
if (memcmp(&raddr, *pp, sizeof(u_long)) == 0)
return (1);
/* No match. */
return (0);
}
#ifndef HAVE_INNETGR
static int
innetgr(const char *netgroup, const char *machine,
const char *user, const char *domain)
{
return 0;
}
#endif
/*
* Returns 0 if ok, -1 if not ok.
*/
static
int
__ivaliduser(FILE *hostf, u_int32_t raddr, const char *luser,
const char *ruser)
{
char *user, *p;
int ch;
char buf[MaxHostNameLen + 128]; /* host + login */
char hname[MaxHostNameLen];
struct hostent *hp;
/* Presumed guilty until proven innocent. */
int userok = 0, hostok = 0;
#ifdef HAVE_YP_GET_DEFAULT_DOMAIN
char *ypdomain;
if (yp_get_default_domain(&ypdomain))
ypdomain = NULL;
#else
#define ypdomain NULL
#endif
/* We need to get the damn hostname back for netgroup matching. */
if ((hp = gethostbyaddr((char *)&raddr,
sizeof(u_long),
AF_INET)) == NULL)
return (-1);
strncpy(hname, hp->h_name, sizeof(hname));
hname[sizeof(hname) - 1] = '\0';
while (fgets(buf, sizeof(buf), hostf)) {
p = buf;
/* Skip lines that are too long. */
if (strchr(p, '\n') == NULL) {
while ((ch = getc(hostf)) != '\n' && ch != EOF);
continue;
}
if (*p == '\n' || *p == '#') {
/* comment... */
continue;
}
while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') {
*p = isupper(*p) ? tolower(*p) : *p;
p++;
}
if (*p == ' ' || *p == '\t') {
*p++ = '\0';
while (*p == ' ' || *p == '\t')
p++;
user = p;
while (*p != '\n' && *p != ' ' &&
*p != '\t' && *p != '\0')
p++;
} else
user = p;
*p = '\0';
/*
* Do +/- and +@/-@ checking. This looks really nasty,
* but it matches SunOS's behavior so far as I can tell.
*/
switch(buf[0]) {
case '+':
if (!buf[1]) { /* '+' matches all hosts */
hostok = 1;
break;
}
if (buf[1] == '@') /* match a host by netgroup */
hostok = innetgr((char *)&buf[2],
(char *)&hname, NULL, ypdomain);
else /* match a host by addr */
hostok = __icheckhost(raddr,(char *)&buf[1]);
break;
case '-': /* reject '-' hosts and all their users */
if (buf[1] == '@') {
if (innetgr((char *)&buf[2],
(char *)&hname, NULL, ypdomain))
return(-1);
} else {
if (__icheckhost(raddr,(char *)&buf[1]))
return(-1);
}
break;
default: /* if no '+' or '-', do a simple match */
hostok = __icheckhost(raddr, buf);
break;
}
switch(*user) {
case '+':
if (!*(user+1)) { /* '+' matches all users */
userok = 1;
break;
}
if (*(user+1) == '@') /* match a user by netgroup */
userok = innetgr(user+2, NULL, (char *)ruser,
ypdomain);
else /* match a user by direct specification */
userok = !(strcmp(ruser, user+1));
break;
case '-': /* if we matched a hostname, */
if (hostok) { /* check for user field rejections */
if (!*(user+1))
return(-1);
if (*(user+1) == '@') {
if (innetgr(user+2, NULL,
(char *)ruser, ypdomain))
return(-1);
} else {
if (!strcmp(ruser, user+1))
return(-1);
}
}
break;
default: /* no rejections: try to match the user */
if (hostok)
userok = !(strcmp(ruser,*user ? user : luser));
break;
}
if (hostok && userok)
return(0);
}
return (-1);
}
/*
* New .rhosts strategy: We are passed an ip address. We spin through
* hosts.equiv and .rhosts looking for a match. When the .rhosts only
* has ip addresses, we don't have to trust a nameserver. When it
* contains hostnames, we spin through the list of addresses the nameserver
* gives us and look for a match.
*
* Returns 0 if ok, -1 if not ok.
*/
int
iruserok(u_int32_t raddr, int superuser, const char *ruser, const char *luser)
{
char *cp;
struct stat sbuf;
struct passwd *pwd;
FILE *hostf;
uid_t uid;
int first;
char pbuf[MaxPathLen];
first = 1;
hostf = superuser ? NULL : fopen(_PATH_HEQUIV, "r");
again:
if (hostf) {
if (__ivaliduser(hostf, raddr, luser, ruser) == 0) {
fclose(hostf);
return (0);
}
fclose(hostf);
}
if (first == 1 && (__check_rhosts_file || superuser)) {
first = 0;
if ((pwd = k_getpwnam((char*)luser)) == NULL)
return (-1);
strcpy(pbuf, pwd->pw_dir);
strcat(pbuf, "/.rhosts");
/*
* Change effective uid while opening .rhosts. If root and
* reading an NFS mounted file system, can't read files that
* are protected read/write owner only.
*/
uid = geteuid();
seteuid(pwd->pw_uid);
hostf = fopen(pbuf, "r");
seteuid(uid);
if (hostf == NULL)
return (-1);
/*
* If not a regular file, or is owned by someone other than
* user or root or if writeable by anyone but the owner, quit.
*/
cp = NULL;
if (lstat(pbuf, &sbuf) < 0)
cp = ".rhosts lstat failed";
else if (!S_ISREG(sbuf.st_mode))
cp = ".rhosts not regular file";
else if (fstat(fileno(hostf), &sbuf) < 0)
cp = ".rhosts fstat failed";
else if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid)
cp = "bad .rhosts owner";
else if (sbuf.st_mode & (S_IWGRP|S_IWOTH))
cp = ".rhosts writeable by other than owner";
/* If there were any problems, quit. */
if (cp) {
__rcmd_errstr = cp;
fclose(hostf);
return (-1);
}
goto again;
}
return (-1);
}
#endif /* !HAVE_IRUSEROK */

View file

@ -0,0 +1,270 @@
/*
* Copyright (c) 1983, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*/
#include "bsd_locl.h"
RCSID("$Id: kcmd.c,v 1.19 1997/05/02 14:27:42 assar Exp $");
#define START_PORT 5120 /* arbitrary */
static int
getport(int *alport)
{
struct sockaddr_in sin;
int s;
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
s = socket(AF_INET, SOCK_STREAM, 0);
if (s < 0)
return (-1);
for (;;) {
sin.sin_port = htons((u_short)*alport);
if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
return (s);
if (errno != EADDRINUSE) {
close(s);
return (-1);
}
(*alport)--;
#ifdef ATHENA_COMPAT
if (*alport == IPPORT_RESERVED/2) {
#else
if (*alport == IPPORT_RESERVED) {
#endif
close(s);
errno = EAGAIN; /* close */
return (-1);
}
}
}
int
kcmd(int *sock,
char **ahost,
u_int16_t rport,
char *locuser,
char *remuser,
char *cmd,
int *fd2p,
KTEXT ticket,
char *service,
char *realm,
CREDENTIALS *cred,
Key_schedule schedule,
MSG_DAT *msg_data,
struct sockaddr_in *laddr,
struct sockaddr_in *faddr,
int32_t authopts)
{
int s, timo = 1;
pid_t pid;
struct sockaddr_in sin, from;
char c;
#ifdef ATHENA_COMPAT
int lport = IPPORT_RESERVED - 1;
#else
int lport = START_PORT;
#endif
struct hostent *hp;
int rc;
char *host_save;
int status;
pid = getpid();
hp = gethostbyname(*ahost);
if (hp == NULL) {
/* fprintf(stderr, "%s: unknown host\n", *ahost); */
return (-1);
}
host_save = strdup(hp->h_name);
if (host_save == NULL)
return -1;
*ahost = host_save;
/* If realm is null, look up from table */
if (realm == NULL || realm[0] == '\0')
realm = krb_realmofhost(host_save);
for (;;) {
s = getport(&lport);
if (s < 0) {
if (errno == EAGAIN)
warnx("kcmd(socket): All ports in use\n");
else
warn("kcmd: socket");
return (-1);
}
sin.sin_family = hp->h_addrtype;
memcpy (&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
sin.sin_port = rport;
if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
break;
close(s);
if (errno == EADDRINUSE) {
lport--;
continue;
}
/*
* don't wait very long for Kerberos rcmd.
*/
if (errno == ECONNREFUSED && timo <= 4) {
/* sleep(timo); don't wait at all here */
timo *= 2;
continue;
}
if (hp->h_addr_list[1] != NULL) {
warn ("kcmd: connect (%s)",
inet_ntoa(sin.sin_addr));
hp->h_addr_list++;
memcpy(&sin.sin_addr,
hp->h_addr_list[0],
sizeof(sin.sin_addr));
fprintf(stderr, "Trying %s...\n",
inet_ntoa(sin.sin_addr));
continue;
}
if (errno != ECONNREFUSED)
warn ("connect(%s)", hp->h_name);
return (-1);
}
lport--;
if (fd2p == 0) {
write(s, "", 1);
lport = 0;
} else {
char num[8];
int s2 = getport(&lport), s3;
int len = sizeof(from);
if (s2 < 0) {
status = -1;
goto bad;
}
listen(s2, 1);
snprintf(num, sizeof(num), "%d", lport);
if (write(s, num, strlen(num) + 1) != strlen(num) + 1) {
warn("kcmd(write): setting up stderr");
close(s2);
status = -1;
goto bad;
}
{
fd_set fds;
FD_ZERO(&fds);
FD_SET(s, &fds);
FD_SET(s2, &fds);
status = select(FD_SETSIZE, &fds, NULL, NULL, NULL);
if(FD_ISSET(s, &fds)){
warnx("kcmd: connection unexpectedly closed.");
close(s2);
status = -1;
goto bad;
}
}
s3 = accept(s2, (struct sockaddr *)&from, &len);
close(s2);
if (s3 < 0) {
warn ("kcmd: accept");
lport = 0;
status = -1;
goto bad;
}
*fd2p = s3;
from.sin_port = ntohs((u_short)from.sin_port);
if (from.sin_family != AF_INET ||
from.sin_port >= IPPORT_RESERVED) {
warnx("kcmd(socket): "
"protocol failure in circuit setup.");
status = -1;
goto bad2;
}
}
/*
* Kerberos-authenticated service. Don't have to send locuser,
* since its already in the ticket, and we'll extract it on
* the other side.
*/
/* write(s, locuser, strlen(locuser)+1); */
/* set up the needed stuff for mutual auth, but only if necessary */
if (authopts & KOPT_DO_MUTUAL) {
int sin_len;
*faddr = sin;
sin_len = sizeof(struct sockaddr_in);
if (getsockname(s, (struct sockaddr *)laddr, &sin_len) < 0) {
warn("kcmd(getsockname)");
status = -1;
goto bad2;
}
}
if ((status = krb_sendauth(authopts, s, ticket, service, *ahost,
realm, (unsigned long) getpid(), msg_data,
cred, schedule,
laddr,
faddr,
"KCMDV0.1")) != KSUCCESS)
goto bad2;
write(s, remuser, strlen(remuser)+1);
write(s, cmd, strlen(cmd)+1);
if ((rc = read(s, &c, 1)) != 1) {
if (rc == -1)
warn("read(%s)", *ahost);
else
warnx("kcmd: bad connection with remote host");
status = -1;
goto bad2;
}
if (c != '\0') {
while (read(s, &c, 1) == 1) {
write(2, &c, 1);
if (c == '\n')
break;
}
status = -1;
goto bad2;
}
*sock = s;
return (KSUCCESS);
bad2:
if (lport)
close(*fd2p);
bad:
close(s);
return (status);
}

View file

@ -0,0 +1,184 @@
/*-
* Copyright (c) 1990, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*/
#include "bsd_locl.h"
RCSID("$Id: klogin.c,v 1.20 1997/05/02 14:27:42 assar Exp $");
#ifdef KERBEROS
#define VERIFY_SERVICE "rcmd"
extern int notickets;
extern char *krbtkfile_env;
static char tkt_location[MaxPathLen];
/*
* Attempt to log the user in using Kerberos authentication
*
* return 0 on success (will be logged in)
* 1 if Kerberos failed (try local password in login)
*/
int
klogin(struct passwd *pw, char *instance, char *localhost, char *password)
{
int kerror;
AUTH_DAT authdata;
KTEXT_ST ticket;
struct hostent *hp;
u_int32_t faddr;
char realm[REALM_SZ], savehost[MaxHostNameLen];
extern int noticketsdontcomplain;
#ifdef KLOGIN_PARANOID
noticketsdontcomplain = 0; /* enable warning message */
#endif
/*
* Root logins don't use Kerberos.
* If we have a realm, try getting a ticket-granting ticket
* and using it to authenticate. Otherwise, return
* failure so that we can try the normal passwd file
* for a password. If that's ok, log the user in
* without issuing any tickets.
*/
if (strcmp(pw->pw_name, "root") == 0 ||
krb_get_lrealm(realm, 0) != KSUCCESS)
return (1);
noticketsdontcomplain = 0; /* enable warning message */
/*
* get TGT for local realm
* tickets are stored in a file named TKT_ROOT plus uid
* except for user.root tickets.
*/
if (strcmp(instance, "root") != 0)
snprintf(tkt_location, sizeof(tkt_location),
"%s%u_%u",
TKT_ROOT, (unsigned)pw->pw_uid, (unsigned)getpid());
else {
snprintf(tkt_location, sizeof(tkt_location),
"%s_root_%d", TKT_ROOT,
(unsigned)pw->pw_uid);
}
krbtkfile_env = tkt_location;
krb_set_tkt_string(tkt_location);
kerror = krb_get_pw_in_tkt(pw->pw_name, instance,
realm, KRB_TICKET_GRANTING_TICKET, realm,
DEFAULT_TKT_LIFE, password);
/*
* If we got a TGT, get a local "rcmd" ticket and check it so as to
* ensure that we are not talking to a bogus Kerberos server.
*
* There are 2 cases where we still allow a login:
* 1: the VERIFY_SERVICE doesn't exist in the KDC
* 2: local host has no srvtab, as (hopefully) indicated by a
* return value of RD_AP_UNDEC from krb_rd_req().
*/
if (kerror != INTK_OK) {
if (kerror != INTK_BADPW && kerror != KDC_PR_UNKNOWN) {
syslog(LOG_ERR, "Kerberos intkt error: %s",
krb_get_err_text(kerror));
dest_tkt();
}
return (1);
}
if (chown(TKT_FILE, pw->pw_uid, pw->pw_gid) < 0)
syslog(LOG_ERR, "chown tkfile (%s): %m", TKT_FILE);
strncpy(savehost, krb_get_phost(localhost), sizeof(savehost));
savehost[sizeof(savehost)-1] = '\0';
#ifdef KLOGIN_PARANOID
/*
* if the "VERIFY_SERVICE" doesn't exist in the KDC for this host,
* don't allow kerberos login, also log the error condition.
*/
kerror = krb_mk_req(&ticket, VERIFY_SERVICE, savehost, realm, 33);
if (kerror == KDC_PR_UNKNOWN) {
syslog(LOG_NOTICE,
"warning: TGT not verified (%s); %s.%s not registered, or srvtab is wrong?",
krb_get_err_text(kerror), VERIFY_SERVICE, savehost);
notickets = 0;
return (1);
}
if (kerror != KSUCCESS) {
warnx("unable to use TGT: (%s)", krb_get_err_text(kerror));
syslog(LOG_NOTICE, "unable to use TGT: (%s)",
krb_get_err_text(kerror));
dest_tkt();
return (1);
}
if (!(hp = gethostbyname(localhost))) {
syslog(LOG_ERR, "couldn't get local host address");
dest_tkt();
return (1);
}
memcpy(&faddr, hp->h_addr, sizeof(faddr));
kerror = krb_rd_req(&ticket, VERIFY_SERVICE, savehost, faddr,
&authdata, "");
if (kerror == KSUCCESS) {
notickets = 0;
return (0);
}
/* undecipherable: probably didn't have a srvtab on the local host */
if (kerror == RD_AP_UNDEC) {
syslog(LOG_NOTICE, "krb_rd_req: (%s)\n", krb_get_err_text(kerror));
dest_tkt();
return (1);
}
/* failed for some other reason */
warnx("unable to verify %s ticket: (%s)", VERIFY_SERVICE,
krb_get_err_text(kerror));
syslog(LOG_NOTICE, "couldn't verify %s ticket: %s", VERIFY_SERVICE,
krb_get_err_text(kerror));
dest_tkt();
return (1);
#else
notickets = 0;
return (0);
#endif
}
#endif

View file

@ -0,0 +1,117 @@
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*/
#include "bsd_locl.h"
RCSID("$Id: krcmd.c,v 1.10 1997/03/30 18:20:18 joda Exp $");
#define SERVICE_NAME "rcmd"
/*
* krcmd: simplified version of Athena's "kcmd"
* returns a socket attached to the destination, -1 or krb error on error
* if fd2p is non-NULL, another socket is filled in for it
*/
int
krcmd(char **ahost, u_short rport, char *remuser, char *cmd, int *fd2p, char *realm)
{
int sock = -1, err = 0;
KTEXT_ST ticket;
long authopts = 0L;
err = kcmd(
&sock,
ahost,
rport,
NULL, /* locuser not used */
remuser,
cmd,
fd2p,
&ticket,
SERVICE_NAME,
realm,
(CREDENTIALS *) NULL, /* credentials not used */
0, /* key schedule not used */
(MSG_DAT *) NULL, /* MSG_DAT not used */
(struct sockaddr_in *) NULL, /* local addr not used */
(struct sockaddr_in *) NULL, /* foreign addr not used */
authopts
);
if (err > KSUCCESS && err < MAX_KRB_ERRORS) {
warning("krcmd: %s", krb_get_err_text(err));
return(-1);
}
if (err < 0)
return(-1);
return(sock);
}
int
krcmd_mutual(char **ahost, u_short rport, char *remuser, char *cmd, int *fd2p, char *realm, CREDENTIALS *cred, Key_schedule sched)
{
int sock, err;
KTEXT_ST ticket;
MSG_DAT msg_dat;
struct sockaddr_in laddr, faddr;
long authopts = KOPT_DO_MUTUAL;
err = kcmd(
&sock,
ahost,
rport,
NULL, /* locuser not used */
remuser,
cmd,
fd2p,
&ticket,
SERVICE_NAME,
realm,
cred, /* filled in */
sched, /* filled in */
&msg_dat, /* filled in */
&laddr, /* filled in */
&faddr, /* filled in */
authopts
);
if (err > KSUCCESS && err < MAX_KRB_ERRORS) {
warnx("krcmd_mutual: %s", krb_get_err_text(err));
return(-1);
}
if (err < 0)
return (-1);
return(sock);
}

View file

@ -0,0 +1,990 @@
/*-
* Copyright (c) 1980, 1987, 1988, 1991, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*/
/*
* login [ name ]
* login -h hostname (for telnetd, etc.)
* login -f name (for pre-authenticated login: datakit, xterm, etc.)
*/
#include "bsd_locl.h"
RCSID("$Id: login.c,v 1.104 1997/05/20 20:35:06 assar Exp $");
#include <otp.h>
#include "sysv_default.h"
#ifdef SYSV_SHADOW
#include "sysv_shadow.h"
#endif
static void badlogin (char *);
static void checknologin (void);
static void dolastlog (int);
static void getloginname (int);
static int rootterm (char *);
static char *stypeof (char *);
static RETSIGTYPE timedout (int);
static int doremotelogin (char *);
void login_fbtab (char *, uid_t, gid_t);
#ifdef KERBEROS
int klogin (struct passwd *, char *, char *, char *);
#endif
#define TTYGRPNAME "tty" /* name of group to own ttys */
/*
* This bounds the time given to login. Change it in
* `/etc/default/login'.
*/
static u_int login_timeout;
#ifdef KERBEROS
int notickets = 1;
int noticketsdontcomplain = 1;
char *instance;
char *krbtkfile_env;
int authok;
#endif
#ifdef HAVE_SHADOW_H
static struct spwd *spwd = NULL;
#endif
static char *ttyprompt;
static struct passwd *pwd;
static int failures;
static char term[64], *hostname, *username, *tty;
static char rusername[100], lusername[100];
static int
change_passwd(struct passwd *who)
{
int status;
int pid;
int wpid;
switch (pid = fork()) {
case -1:
warn("fork /bin/passwd");
sleepexit(1);
case 0:
execlp("/bin/passwd", "passwd", who->pw_name, (char *) 0);
_exit(1);
default:
while ((wpid = wait(&status)) != -1 && wpid != pid)
/* void */ ;
return (status);
}
}
#ifndef NO_MOTD /* message of the day stuff */
jmp_buf motdinterrupt;
static RETSIGTYPE
sigint(int signo)
{
longjmp(motdinterrupt, 1);
}
static void
motd(void)
{
int fd, nchars;
RETSIGTYPE (*oldint)();
char tbuf[8192];
if ((fd = open(_PATH_MOTDFILE, O_RDONLY, 0)) < 0)
return;
oldint = signal(SIGINT, sigint);
if (setjmp(motdinterrupt) == 0)
while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
write(fileno(stdout), tbuf, nchars);
signal(SIGINT, oldint);
close(fd);
}
#endif /* !NO_MOTD */
#define AUTH_NONE 0
#define AUTH_OTP 1
/*
* getpwnam and try to detect the worst form of NIS attack.
*/
static struct passwd *
paranoid_getpwnam (char *user)
{
struct passwd *p;
p = k_getpwnam (user);
if (p == NULL)
return p;
if (p->pw_uid == 0 && strcmp (username, "root") != 0) {
syslog (LOG_ALERT,
"NIS attack, user %s has uid 0", username);
return NULL;
}
return p;
}
int
main(int argc, char **argv)
{
struct group *gr;
int ask, ch, cnt, fflag, hflag, pflag, quietlog, nomailcheck;
int rootlogin, rval;
int rflag;
int changepass = 0;
uid_t uid;
char *domain, *p, passwd[128], *ttyn;
char tbuf[MaxPathLen + 2], tname[sizeof(_PATH_TTY) + 10];
char localhost[MaxHostNameLen];
char full_hostname[MaxHostNameLen];
int auth_level = AUTH_NONE;
OtpContext otp_ctx;
int mask = 022; /* Default umask (set below) */
int maxtrys = 5; /* Default number of allowed failed logins */
set_progname(argv[0]);
openlog("login", LOG_ODELAY, LOG_AUTH);
/* Read defaults file and set the login timeout period. */
sysv_defaults();
login_timeout = atoi(default_timeout);
maxtrys = atoi(default_maxtrys);
if (sscanf(default_umask, "%o", &mask) != 1 || (mask & ~0777))
syslog(LOG_WARNING, "bad umask default: %s", default_umask);
else
umask(mask);
signal(SIGALRM, timedout);
alarm(login_timeout);
signal(SIGQUIT, SIG_IGN);
signal(SIGINT, SIG_IGN);
setpriority(PRIO_PROCESS, 0, 0);
/*
* -p is used by getty to tell login not to destroy the environment
* -f is used to skip a second login authentication
* -h is used by other servers to pass the name of the remote
* host to login so that it may be placed in utmp and wtmp
* -r is used by old-style rlogind to execute the autologin protocol
*/
*full_hostname = '\0';
domain = NULL;
if (k_gethostname(localhost, sizeof(localhost)) < 0)
syslog(LOG_ERR, "couldn't get local hostname: %m");
else
domain = strchr(localhost, '.');
fflag = hflag = pflag = rflag = 0;
uid = getuid();
while ((ch = getopt(argc, argv, "a:d:fh:pr:")) != EOF)
switch (ch) {
case 'a':
if (strcmp (optarg, "none") == 0)
auth_level = AUTH_NONE;
else if (strcmp (optarg, "otp") == 0)
auth_level = AUTH_OTP;
else
warnx ("bad value for -a: %s", optarg);
break;
case 'd':
break;
case 'f':
fflag = 1;
break;
case 'h':
if (rflag || hflag) {
printf("Only one of -r and -h allowed\n");
exit(1);
}
if (uid)
errx(1, "-h option: %s", strerror(EPERM));
hflag = 1;
strncpy(full_hostname, optarg, sizeof(full_hostname)-1);
if (domain && (p = strchr(optarg, '.')) &&
strcasecmp(p, domain) == 0)
*p = 0;
hostname = optarg;
break;
case 'p':
if (getuid()) {
warnx("-p for super-user only.");
exit(1);
}
pflag = 1;
break;
case 'r':
if (rflag || hflag) {
warnx("Only one of -r and -h allowed\n");
exit(1);
}
if (getuid()) {
warnx("-r for super-user only.");
exit(1);
}
rflag = 1;
strncpy(full_hostname, optarg, sizeof(full_hostname)-1);
if (domain && (p = strchr(optarg, '.')) &&
strcasecmp(p, domain) == 0)
*p = 0;
hostname = optarg;
fflag = (doremotelogin(full_hostname) == 0);
break;
case '?':
default:
if (!uid)
syslog(LOG_ERR, "invalid flag %c", ch);
fprintf(stderr,
"usage: login [-fp] [-a otp]"
"[-h hostname | -r hostname] [username]\n");
exit(1);
}
argc -= optind;
argv += optind;
if (geteuid() != 0) {
warnx("only root may use login, use su");
/* Or install login setuid root, which is not necessary */
sleep(10);
exit(1);
}
/*
* Figure out if we should ask for the username or not. The name
* may be given on the command line or via the environment, and
* it may even be in the terminal input queue.
*/
if (rflag) {
username = lusername;
ask = 0;
} else
if (*argv && strchr(*argv, '=')) {
ask = 1;
} else
if (*argv && strcmp(*argv, "-") == 0) {
argc--;
argv++;
ask = 1;
} else
if (*argv) {
username = *argv;
ask = 0;
argc--;
argv++;
} else if ((ttyprompt = getenv("TTYPROMPT")) && *ttyprompt) {
getloginname(0);
ask = 0;
} else
ask = 1;
/* Default tty settings. */
stty_default();
for (cnt = getdtablesize(); cnt > 2; cnt--)
close(cnt);
/*
* Determine the tty name. BSD takes the basename, SYSV4 takes
* whatever remains after stripping the "/dev/" prefix. The code
* below should produce sensible results in either environment.
*/
ttyn = ttyname(STDIN_FILENO);
if (ttyn == NULL || *ttyn == '\0') {
snprintf(tname, sizeof(tname), "%s??", _PATH_TTY);
ttyn = tname;
}
if ((tty = strchr(ttyn + 1, '/')))
++tty;
else
tty = ttyn;
for (cnt = 0;; ask = 1) {
char prompt[128], ss[256];
if (ask) {
fflag = 0;
getloginname(1);
}
rootlogin = 0;
rval = 1;
#ifdef KERBEROS
if ((instance = strchr(username, '.')) != NULL) {
if (strcmp(instance, ".root") == 0)
rootlogin = 1;
*instance++ = '\0';
} else
instance = "";
#endif
if (strlen(username) > UT_NAMESIZE)
username[UT_NAMESIZE] = '\0';
/*
* Note if trying multiple user names; log failures for
* previous user name, but don't bother logging one failure
* for nonexistent name (mistyped username).
*/
if (failures && strcmp(tbuf, username)) {
if (failures > (pwd ? 0 : 1))
badlogin(tbuf);
failures = 0;
}
strcpy(tbuf, username);
pwd = paranoid_getpwnam (username);
/*
* if we have a valid account name, and it doesn't have a
* password, or the -f option was specified and the caller
* is root or the caller isn't changing their uid, don't
* authenticate.
*/
if (pwd) {
if (pwd->pw_uid == 0)
rootlogin = 1;
if (fflag && (uid == 0 || uid == pwd->pw_uid)) {
/* already authenticated */
break;
} else if (pwd->pw_passwd[0] == '\0') {
/* pretend password okay */
rval = 0;
goto ttycheck;
}
}
fflag = 0;
setpriority(PRIO_PROCESS, 0, -4);
if (otp_challenge (&otp_ctx, username,
ss, sizeof(ss)) == 0)
snprintf (prompt, sizeof(prompt), "%s's %s Password: ",
username, ss);
else {
if (auth_level == AUTH_NONE)
snprintf(prompt, sizeof(prompt), "%s's Password: ",
username);
else {
char *s;
rval = 1;
s = otp_error(&otp_ctx);
if(s)
printf ("OTP: %s\n", s);
continue;
}
}
if (des_read_pw_string (passwd, sizeof(passwd) - 1, prompt, 0))
continue;
passwd[sizeof(passwd) - 1] = '\0';
/* Verify it somehow */
if (otp_verify_user (&otp_ctx, passwd) == 0)
rval = 0;
else if (pwd == NULL)
;
else if (auth_level == AUTH_NONE) {
uid_t pwd_uid = pwd->pw_uid;
rval = unix_verify_user (username, passwd);
if (rval == 0)
{
if (rootlogin && pwd_uid != 0)
rootlogin = 0;
}
else
{
rval = klogin(pwd, instance, localhost, passwd);
if (rval != 0 && rootlogin && pwd_uid != 0)
rootlogin = 0;
if (rval == 0)
authok = 1;
}
} else {
char *s;
rval = 1;
if ((s = otp_error(&otp_ctx)))
printf ("OTP: %s\n", s);
}
memset (passwd, 0, sizeof(passwd));
setpriority (PRIO_PROCESS, 0, 0);
/*
* Santa Claus, give me a portable and reentrant getpwnam.
*/
pwd = paranoid_getpwnam (username);
ttycheck:
/*
* If trying to log in as root without Kerberos,
* but with insecure terminal, refuse the login attempt.
*/
#ifdef KERBEROS
if (authok == 0)
#endif
if (pwd && !rval && rootlogin && !rootterm(tty)
&& !rootterm(ttyn)) {
warnx("%s login refused on this terminal.",
pwd->pw_name);
if (hostname)
syslog(LOG_NOTICE,
"LOGIN %s REFUSED FROM %s ON TTY %s",
pwd->pw_name, hostname, tty);
else
syslog(LOG_NOTICE,
"LOGIN %s REFUSED ON TTY %s",
pwd->pw_name, tty);
continue;
}
if (rval == 0)
break;
printf("Login incorrect\n");
failures++;
/* max number of attemps and delays taken from defaults file */
/* we allow maxtrys tries, but after 2 we start backing off */
if (++cnt > 2) {
if (cnt >= maxtrys) {
badlogin(username);
sleepexit(1);
}
sleep((u_int)((cnt - 2) * atoi(default_sleep)));
}
}
/* committed to login -- turn off timeout */
alarm(0);
endpwent();
#if defined(HAVE_GETUDBNAM) && defined(HAVE_SETLIM)
{
struct udb *udb;
long t;
const long maxcpu = 46116860184; /* some random constant */
udb = getudbnam(pwd->pw_name);
if(udb == UDB_NULL){
warnx("Failed to get UDB entry.");
exit(1);
}
t = udb->ue_pcpulim[UDBRC_INTER];
if(t == 0 || t > maxcpu)
t = CPUUNLIM;
else
t *= 100 * CLOCKS_PER_SEC;
if(limit(C_PROC, 0, L_CPU, t) < 0)
warn("limit C_PROC");
t = udb->ue_jcpulim[UDBRC_INTER];
if(t == 0 || t > maxcpu)
t = CPUUNLIM;
else
t *= 100 * CLOCKS_PER_SEC;
if(limit(C_JOBPROCS, 0, L_CPU, t) < 0)
warn("limit C_JOBPROCS");
nice(udb->ue_nice[UDBRC_INTER]);
}
#endif
/* if user not super-user, check for disabled logins */
if (!rootlogin)
checknologin();
if (chdir(pwd->pw_dir) < 0) {
printf("No home directory %s!\n", pwd->pw_dir);
if (chdir("/"))
exit(0);
pwd->pw_dir = "/";
printf("Logging in with home = \"/\".\n");
}
quietlog = access(_PATH_HUSHLOGIN, F_OK) == 0;
nomailcheck = access(_PATH_NOMAILCHECK, F_OK) == 0;
#if defined(HAVE_PASSWD_CHANGE) && defined(HAVE_PASSWD_EXPIRE)
if (pwd->pw_change || pwd->pw_expire)
gettimeofday(&tp, (struct timezone *)NULL);
if (pwd->pw_change)
if (tp.tv_sec >= pwd->pw_change) {
printf("Sorry -- your password has expired.\n");
changepass=1;
} else if (pwd->pw_change - tp.tv_sec <
2 * DAYSPERWEEK * SECSPERDAY && !quietlog)
printf("Warning: your password expires on %s",
ctime(&pwd->pw_change));
if (pwd->pw_expire)
if (tp.tv_sec >= pwd->pw_expire) {
printf("Sorry -- your account has expired.\n");
sleepexit(1);
} else if (pwd->pw_expire - tp.tv_sec <
2 * DAYSPERWEEK * SECSPERDAY && !quietlog)
printf("Warning: your account expires on %s",
ctime(&pwd->pw_expire));
#endif /* defined(HAVE_PASSWD_CHANGE) && defined(HAVE_PASSWD_EXPIRE) */
/* Nothing else left to fail -- really log in. */
/*
* Update the utmp files, both BSD and SYSV style.
*/
if (utmpx_login(tty, username, hostname ? hostname : "") != 0
&& !fflag) {
printf("No utmpx entry. You must exec \"login\" from the lowest level \"sh\".\n");
sleepexit(0);
}
utmp_login(ttyn, username, hostname ? hostname : "");
dolastlog(quietlog);
/*
* Set device protections, depending on what terminal the
* user is logged in. This feature is used on Suns to give
* console users better privacy.
*/
login_fbtab(tty, pwd->pw_uid, pwd->pw_gid);
chown(ttyn, pwd->pw_uid,
(gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid);
chmod(ttyn, S_IRUSR | S_IWUSR | S_IWGRP);
setgid(pwd->pw_gid);
initgroups(username, pwd->pw_gid);
if (*pwd->pw_shell == '\0')
pwd->pw_shell = _PATH_BSHELL;
/*
* Set up a new environment. With SYSV, some variables are always
* preserved; some varables are never preserved, and some variables
* are always clobbered. With BSD, nothing is always preserved, and
* some variables are always clobbered. We add code to make sure
* that LD_* and IFS are never preserved.
*/
if (term[0] == '\0')
strncpy(term, stypeof(tty), sizeof(term));
/* set up a somewhat censored environment. */
sysv_newenv(argc, argv, pwd, term, pflag);
#ifdef KERBEROS
if (krbtkfile_env)
setenv("KRBTKFILE", krbtkfile_env, 1);
#endif
if (tty[sizeof("tty")-1] == 'd')
syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name);
/* If fflag is on, assume caller/authenticator has logged root login. */
if (rootlogin && fflag == 0)
if (hostname)
syslog(LOG_NOTICE, "ROOT LOGIN (%s) ON %s FROM %s",
username, tty, hostname);
else
syslog(LOG_NOTICE, "ROOT LOGIN (%s) ON %s", username, tty);
#ifdef KERBEROS
if (!quietlog && notickets == 1 && !noticketsdontcomplain)
printf("Warning: no Kerberos tickets issued.\n");
#endif
#ifdef LOGALL
/*
* Syslog each successful login, so we don't have to watch hundreds
* of wtmp or lastlogin files.
*/
if (hostname) {
syslog(LOG_INFO, "login from %s as %s", hostname, pwd->pw_name);
} else {
syslog(LOG_INFO, "login on %s as %s", tty, pwd->pw_name);
}
#endif
#ifndef NO_MOTD
/*
* Optionally show the message of the day. System V login leaves
* motd and mail stuff up to the shell startup file.
*/
if (!quietlog) {
struct stat st;
#if 0
printf("%s\n\t%s %s\n\n",
"Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994",
"The Regents of the University of California. ",
"All rights reserved.");
#endif
motd();
if(!nomailcheck){
snprintf(tbuf, sizeof(tbuf), "%s/%s", _PATH_MAILDIR, pwd->pw_name);
if (stat(tbuf, &st) == 0 && st.st_size != 0)
printf("You have %smail.\n",
(st.st_mtime > st.st_atime) ? "new " : "");
}
}
#endif /* NO_MOTD */
#ifdef LOGIN_ACCESS
if (login_access(pwd->pw_name, hostname ? full_hostname : tty) == 0) {
printf("Permission denied\n");
if (hostname)
syslog(LOG_NOTICE, "%s LOGIN REFUSED FROM %s",
pwd->pw_name, hostname);
else
syslog(LOG_NOTICE, "%s LOGIN REFUSED ON %s",
pwd->pw_name, tty);
sleepexit(1);
}
#endif
signal(SIGALRM, SIG_DFL);
signal(SIGQUIT, SIG_DFL);
signal(SIGINT, SIG_DFL);
signal(SIGTSTP, SIG_IGN);
tbuf[0] = '-';
strcpy(tbuf + 1, (p = strrchr(pwd->pw_shell, '/')) ?
p + 1 : pwd->pw_shell);
#ifdef HAVE_SETLOGIN
if (setlogin(pwd->pw_name) < 0)
syslog(LOG_ERR, "setlogin() failure: %m");
#endif
#ifdef HAVE_SETPCRED
if (setpcred (pwd->pw_name, NULL) == -1)
syslog(LOG_ERR, "setpcred() failure: %m");
#endif /* HAVE_SETPCRED */
#if defined(SYSV_SHADOW) && defined(HAVE_GETSPNAM)
spwd = getspnam (username);
endspent ();
#endif
/* Discard permissions last so can't get killed and drop core. */
{
int uid = rootlogin ? 0 : pwd->pw_uid;
if(setuid(uid) != 0){
warn("setuid(%d)", uid);
if(!rootlogin)
exit(1);
}
}
/*
* After dropping privileges and after cleaning up the environment,
* optionally run, as the user, /bin/passwd.
*/
if (pwd->pw_passwd[0] == 0 &&
strcasecmp(default_passreq, "YES") == 0) {
printf("You don't have a password. Choose one.\n");
if (change_passwd(pwd))
sleepexit(0);
changepass = 0;
}
#ifdef SYSV_SHADOW
if (spwd && sysv_expire(spwd)) {
if (change_passwd(pwd))
sleepexit(0);
changepass = 0;
}
#endif /* SYSV_SHADOW */
if (changepass) {
int res;
if ((res=system(_PATH_CHPASS)))
sleepexit(1);
}
if (k_hasafs()) {
char cell[64];
k_setpag();
if(k_afs_cell_of_file(pwd->pw_dir, cell, sizeof(cell)) == 0)
k_afsklog(cell, 0);
k_afsklog(0, 0);
}
execlp(pwd->pw_shell, tbuf, 0);
if (getuid() == 0) {
warnx("Can't exec %s, trying %s\n",
pwd->pw_shell, _PATH_BSHELL);
execlp(_PATH_BSHELL, tbuf, 0);
err(1, "%s", _PATH_BSHELL);
}
err(1, "%s", pwd->pw_shell);
return 1;
}
#ifdef KERBEROS
#define NBUFSIZ (UT_NAMESIZE + 1 + 5) /* .root suffix */
#else
#define NBUFSIZ (UT_NAMESIZE + 1)
#endif
static void
getloginname(int prompt)
{
int ch;
char *p;
static char nbuf[NBUFSIZ];
for (;;) {
if (prompt)
if (ttyprompt && *ttyprompt)
printf("%s", ttyprompt);
else
printf("login: ");
prompt = 1;
for (p = nbuf; (ch = getchar()) != '\n'; ) {
if (ch == EOF) {
badlogin(username);
exit(0);
}
if (p < nbuf + (NBUFSIZ - 1))
*p++ = ch;
}
if (p > nbuf)
if (nbuf[0] == '-')
warnx("login names may not start with '-'.");
else {
*p = '\0';
username = nbuf;
break;
}
}
}
static int
rootterm(char *ttyn)
{
#ifndef HAVE_TTYENT_H
return (default_console == 0 || strcmp(default_console, ttyname(0)) == 0);
#else
struct ttyent *t;
return ((t = getttynam(ttyn)) && t->ty_status & TTY_SECURE);
#endif
}
static RETSIGTYPE
timedout(int signo)
{
fprintf(stderr, "Login timed out after %d seconds\n",
login_timeout);
exit(0);
}
static void
checknologin(void)
{
int fd, nchars;
char tbuf[8192];
if ((fd = open(_PATH_NOLOGIN, O_RDONLY, 0)) >= 0) {
while ((nchars = read(fd, tbuf, sizeof(tbuf))) > 0)
write(fileno(stdout), tbuf, nchars);
sleepexit(0);
}
}
static void
dolastlog(int quiet)
{
#if defined(HAVE_LASTLOG_H) || defined(HAVE_LOGIN_H) || defined(SYSV_SHADOW)
struct lastlog ll;
int fd;
if ((fd = open(_PATH_LASTLOG, O_RDWR, 0)) >= 0) {
lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), SEEK_SET);
#ifdef SYSV_SHADOW
if (read(fd, &ll, sizeof(ll)) == sizeof(ll) &&
ll.ll_time != 0) {
if (pwd->pw_uid && spwd && spwd->sp_inact > 0
&& ll.ll_time / (24 * 60 * 60)
+ spwd->sp_inact < time(0)) {
printf("Your account has been inactive too long.\n");
sleepexit(1);
}
if (!quiet) {
printf("Last login: %.*s ",
24-5, ctime(&ll.ll_time));
if (*ll.ll_host != '\0') {
printf("from %.*s\n",
(int)sizeof(ll.ll_host),
ll.ll_host);
} else
printf("on %.*s\n",
(int)sizeof(ll.ll_line),
ll.ll_line);
}
}
lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), SEEK_SET);
#else /* SYSV_SHADOW */
if (!quiet) {
if (read(fd, &ll, sizeof(ll)) == sizeof(ll) &&
ll.ll_time != 0) {
printf("Last login: %.*s ",
24-5, ctime(&ll.ll_time));
if (*ll.ll_host != '\0')
printf("from %.*s\n",
(int)sizeof(ll.ll_host),
ll.ll_host);
else
printf("on %.*s\n",
(int)sizeof(ll.ll_line),
ll.ll_line);
}
lseek(fd, (off_t)pwd->pw_uid * sizeof(ll), SEEK_SET);
}
#endif /* SYSV_SHADOW */
memset(&ll, 0, sizeof(ll));
time(&ll.ll_time);
strncpy(ll.ll_line, tty, sizeof(ll.ll_line));
if (hostname)
strncpy(ll.ll_host, hostname, sizeof(ll.ll_host));
write(fd, &ll, sizeof(ll));
close(fd);
}
#endif /* DOLASTLOG */
}
static void
badlogin(char *name)
{
if (failures == 0)
return;
if (hostname) {
syslog(LOG_NOTICE, "%d LOGIN FAILURE%s FROM %s",
failures, failures > 1 ? "S" : "", hostname);
syslog(LOG_AUTHPRIV|LOG_NOTICE,
"%d LOGIN FAILURE%s FROM %s, %s",
failures, failures > 1 ? "S" : "", hostname, name);
} else {
syslog(LOG_NOTICE, "%d LOGIN FAILURE%s ON %s",
failures, failures > 1 ? "S" : "", tty);
syslog(LOG_AUTHPRIV|LOG_NOTICE,
"%d LOGIN FAILURE%s ON %s, %s",
failures, failures > 1 ? "S" : "", tty, name);
}
}
#undef UNKNOWN
#define UNKNOWN "su"
static char *
stypeof(char *ttyid)
{
/* TERM is probably a better guess than anything else. */
char *term = getenv("TERM");
if (term != 0 && term[0] != 0)
return term;
{
#ifndef HAVE_TTYENT_H
return UNKNOWN;
#else
struct ttyent *t;
return (ttyid && (t = getttynam(ttyid)) ? t->ty_type : UNKNOWN);
#endif
}
}
static void
xgetstr(char *buf, int cnt, char *err)
{
char ch;
do {
if (read(0, &ch, sizeof(ch)) != sizeof(ch))
exit(1);
if (--cnt < 0) {
fprintf(stderr, "%s too long\r\n", err);
sleepexit(1);
}
*buf++ = ch;
} while (ch);
}
/*
* Some old rlogind's unknowingly pass remuser, locuser and
* terminal_type/speed so we need to take care of that part of the
* protocol here. Also, we can't make a getpeername(2) on the socket
* so we have to trust that rlogind resolved the name correctly.
*/
static int
doremotelogin(char *host)
{
int code;
char *cp;
xgetstr(rusername, sizeof (rusername), "remuser");
xgetstr(lusername, sizeof (lusername), "locuser");
xgetstr(term, sizeof(term), "Terminal type");
cp = strchr(term, '/');
if (cp != 0)
*cp = 0; /* For now ignore speed/bg */
pwd = k_getpwnam(lusername);
if (pwd == NULL)
return(-1);
code = ruserok(host, (pwd->pw_uid == 0), rusername, lusername);
if (code == 0)
syslog(LOG_NOTICE,
"Warning: An old rlogind accepted login probably from host %s",
host);
return(code);
}
void
sleepexit(int eval)
{
sleep(5);
exit(eval);
}

View file

@ -0,0 +1,221 @@
/*
* This module implements a simple but effective form of login access
* control based on login names and on host (or domain) names, internet
* addresses (or network numbers), or on terminal line names in case of
* non-networked logins. Diagnostics are reported through syslog(3).
*
* Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
*/
#include "bsd_locl.h"
RCSID("$Id: login_access.c,v 1.15 1997/06/01 03:12:28 assar Exp $");
#ifdef LOGIN_ACCESS
/* Delimiters for fields and for lists of users, ttys or hosts. */
static char fs[] = ":"; /* field separator */
static char sep[] = ", \t"; /* list-element separator */
/* Constants to be used in assignments only, not in comparisons... */
#define YES 1
#define NO 0
static int list_match(char *list, char *item, int (*match_fn)(char *, char *));
static int user_match(char *tok, char *string);
static int from_match(char *tok, char *string);
static int string_match(char *tok, char *string);
/* login_access - match username/group and host/tty with access control file */
int login_access(char *user, char *from)
{
FILE *fp;
char line[BUFSIZ];
char *perm; /* becomes permission field */
char *users; /* becomes list of login names */
char *froms; /* becomes list of terminals or hosts */
int match = NO;
int end;
int lineno = 0; /* for diagnostics */
char *foo;
/*
* Process the table one line at a time and stop at the first match.
* Blank lines and lines that begin with a '#' character are ignored.
* Non-comment lines are broken at the ':' character. All fields are
* mandatory. The first field should be a "+" or "-" character. A
* non-existing table means no access control.
*/
if ((fp = fopen(_PATH_LOGACCESS, "r")) != 0) {
while (!match && fgets(line, sizeof(line), fp)) {
lineno++;
if (line[end = strlen(line) - 1] != '\n') {
syslog(LOG_ERR, "%s: line %d: missing newline or line too long",
_PATH_LOGACCESS, lineno);
continue;
}
if (line[0] == '#')
continue; /* comment line */
while (end > 0 && isspace(line[end - 1]))
end--;
line[end] = 0; /* strip trailing whitespace */
if (line[0] == 0) /* skip blank lines */
continue;
foo = NULL;
if (!(perm = strtok_r(line, fs, &foo))
|| !(users = strtok_r(NULL, fs, &foo))
|| !(froms = strtok_r(NULL, fs, &foo))
|| strtok_r(NULL, fs, &foo)) {
syslog(LOG_ERR, "%s: line %d: bad field count",
_PATH_LOGACCESS,
lineno);
continue;
}
if (perm[0] != '+' && perm[0] != '-') {
syslog(LOG_ERR, "%s: line %d: bad first field",
_PATH_LOGACCESS,
lineno);
continue;
}
match = (list_match(froms, from, from_match)
&& list_match(users, user, user_match));
}
fclose(fp);
} else if (errno != ENOENT) {
syslog(LOG_ERR, "cannot open %s: %m", _PATH_LOGACCESS);
}
return (match == 0 || (line[0] == '+'));
}
/* list_match - match an item against a list of tokens with exceptions */
static int
list_match(char *list, char *item, int (*match_fn)(char *, char *))
{
char *tok;
int match = NO;
char *foo = NULL;
/*
* Process tokens one at a time. We have exhausted all possible matches
* when we reach an "EXCEPT" token or the end of the list. If we do find
* a match, look for an "EXCEPT" list and recurse to determine whether
* the match is affected by any exceptions.
*/
for (tok = strtok_r(list, sep, &foo);
tok != NULL;
tok = strtok_r(NULL, sep, &foo)) {
if (strcasecmp(tok, "EXCEPT") == 0) /* EXCEPT: give up */
break;
if ((match = (*match_fn) (tok, item)) != 0) /* YES */
break;
}
/* Process exceptions to matches. */
if (match != NO) {
while ((tok = strtok_r(NULL, sep, &foo)) && strcasecmp(tok, "EXCEPT"))
/* VOID */ ;
if (tok == 0 || list_match(NULL, item, match_fn) == NO)
return (match);
}
return (NO);
}
/* netgroup_match - match group against machine or user */
static int netgroup_match(char *group, char *machine, char *user)
{
#ifdef HAVE_YP_GET_DEFAULT_DOMAIN
static char *mydomain = 0;
if (mydomain == 0)
yp_get_default_domain(&mydomain);
return (innetgr(group, machine, user, mydomain));
#else
syslog(LOG_ERR, "NIS netgroup support not configured");
return 0;
#endif
}
/* user_match - match a username against one token */
static int user_match(char *tok, char *string)
{
struct group *group;
int i;
/*
* If a token has the magic value "ALL" the match always succeeds.
* Otherwise, return YES if the token fully matches the username, or if
* the token is a group that contains the username.
*/
if (tok[0] == '@') { /* netgroup */
return (netgroup_match(tok + 1, (char *) 0, string));
} else if (string_match(tok, string)) { /* ALL or exact match */
return (YES);
} else if ((group = getgrnam(tok)) != 0) { /* try group membership */
for (i = 0; group->gr_mem[i]; i++)
if (strcasecmp(string, group->gr_mem[i]) == 0)
return (YES);
}
return (NO);
}
/* from_match - match a host or tty against a list of tokens */
static int from_match(char *tok, char *string)
{
int tok_len;
int str_len;
/*
* If a token has the magic value "ALL" the match always succeeds. Return
* YES if the token fully matches the string. If the token is a domain
* name, return YES if it matches the last fields of the string. If the
* token has the magic value "LOCAL", return YES if the string does not
* contain a "." character. If the token is a network number, return YES
* if it matches the head of the string.
*/
if (tok[0] == '@') { /* netgroup */
return (netgroup_match(tok + 1, string, (char *) 0));
} else if (string_match(tok, string)) { /* ALL or exact match */
return (YES);
} else if (tok[0] == '.') { /* domain: match last fields */
if ((str_len = strlen(string)) > (tok_len = strlen(tok))
&& strcasecmp(tok, string + str_len - tok_len) == 0)
return (YES);
} else if (strcasecmp(tok, "LOCAL") == 0) { /* local: no dots */
if (strchr(string, '.') == 0)
return (YES);
} else if (tok[(tok_len = strlen(tok)) - 1] == '.' /* network */
&& strncmp(tok, string, tok_len) == 0) {
return (YES);
}
return (NO);
}
/* string_match - match a string against one token */
static int string_match(char *tok, char *string)
{
/*
* If the token has the magic value "ALL" the match always succeeds.
* Otherwise, return YES if the token fully matches the string.
*/
if (strcasecmp(tok, "ALL") == 0) { /* all: always matches */
return (YES);
} else if (strcasecmp(tok, string) == 0) { /* try exact match */
return (YES);
}
return (NO);
}
#endif /* LOGIN_ACCES */

View file

@ -0,0 +1,144 @@
/************************************************************************
* Copyright 1995 by Wietse Venema. All rights reserved.
*
* This material was originally written and compiled by Wietse Venema at
* Eindhoven University of Technology, The Netherlands, in 1990, 1991,
* 1992, 1993, 1994 and 1995.
*
* Redistribution and use in source and binary forms are permitted
* provided that this entire copyright notice is duplicated in all such
* copies.
*
* This software is provided "as is" and without any expressed or implied
* warranties, including, without limitation, the implied warranties of
* merchantibility and fitness for any particular purpose.
************************************************************************/
/*
SYNOPSIS
void login_fbtab(tty, uid, gid)
char *tty;
uid_t uid;
gid_t gid;
DESCRIPTION
This module implements device security as described in the
SunOS 4.1.x fbtab(5) and SunOS 5.x logindevperm(4) manual
pages. The program first looks for /etc/fbtab. If that file
cannot be opened it attempts to process /etc/logindevperm.
We expect entries with the folowing format:
Comments start with a # and extend to the end of the line.
Blank lines or lines with only a comment are ignored.
All other lines consist of three fields delimited by
whitespace: a login device (/dev/console), an octal
permission number (0600), and a ":"-delimited list of
devices (/dev/kbd:/dev/mouse). All device names are
absolute paths. A path that ends in "/*" refers to all
directory entries except "." and "..".
If the tty argument (relative path) matches a login device
name (absolute path), the permissions of the devices in the
":"-delimited list are set as specified in the second
field, and their ownership is changed to that of the uid
and gid arguments.
DIAGNOSTICS
Problems are reported via the syslog daemon with severity
LOG_ERR.
BUGS
AUTHOR
Wietse Venema (wietse@wzv.win.tue.nl)
Eindhoven University of Technology
The Netherlands
*/
#include "bsd_locl.h"
RCSID("$Id: login_fbtab.c,v 1.10 1997/06/01 03:12:54 assar Exp $");
void login_protect (char *, char *, int, uid_t, gid_t);
void login_fbtab (char *tty, uid_t uid, gid_t gid);
#define WSPACE " \t\n"
/* login_fbtab - apply protections specified in /etc/fbtab or logindevperm */
void
login_fbtab(char *tty, uid_t uid, gid_t gid)
{
FILE *fp;
char buf[BUFSIZ];
char *devname;
char *cp;
int prot;
char *table;
char *foo;
if ((fp = fopen(table = _PATH_FBTAB, "r")) == 0
&& (fp = fopen(table = _PATH_LOGINDEVPERM, "r")) == 0)
return;
while (fgets(buf, sizeof(buf), fp)) {
if ((cp = strchr(buf, '#')) != 0)
*cp = 0; /* strip comment */
foo = NULL;
if ((cp = devname = strtok_r(buf, WSPACE, &foo)) == 0)
continue; /* empty or comment */
if (strncmp(devname, "/dev/", 5) != 0
|| (cp = strtok_r(NULL, WSPACE, &foo)) == 0
|| *cp != '0'
|| sscanf(cp, "%o", &prot) == 0
|| prot == 0
|| (prot & 0777) != prot
|| (cp = strtok_r(NULL, WSPACE, &foo)) == 0) {
syslog(LOG_ERR, "%s: bad entry: %s", table, cp ? cp : "(null)");
continue;
}
if (strcmp(devname + 5, tty) == 0) {
foo = NULL;
for (cp = strtok_r(cp, ":", &foo);
cp;
cp = strtok_r(NULL, ":", &foo)) {
login_protect(table, cp, prot, uid, gid);
}
}
}
fclose(fp);
}
/* login_protect - protect one device entry */
void
login_protect(char *table, char *path, int mask, uid_t uid, gid_t gid)
{
char buf[BUFSIZ];
int pathlen = strlen(path);
struct dirent *ent;
DIR *dir;
if (strcmp("/*", path + pathlen - 2) != 0) {
if (chmod(path, mask) && errno != ENOENT)
syslog(LOG_ERR, "%s: chmod(%s): %m", table, path);
if (chown(path, uid, gid) && errno != ENOENT)
syslog(LOG_ERR, "%s: chown(%s): %m", table, path);
} else {
strcpy(buf, path);
buf[pathlen - 1] = 0;
if ((dir = opendir(buf)) == 0) {
syslog(LOG_ERR, "%s: opendir(%s): %m", table, path);
} else {
while ((ent = readdir(dir)) != 0) {
if (strcmp(ent->d_name, ".") != 0
&& strcmp(ent->d_name, "..") != 0) {
strcpy(buf + pathlen - 1, ent->d_name);
login_protect(table, buf, mask, uid, gid);
}
}
closedir(dir);
}
}
}

View file

@ -0,0 +1,191 @@
/*
* Copyright (c) 1989 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* from: @(#)pathnames.h 5.2 (Berkeley) 4/9/90
* $Id: pathnames.h,v 1.23 1996/11/17 06:36:42 joda Exp $
*/
/******* First fix default path, we stick to _PATH_DEFPATH everywhere */
#if !defined(_PATH_DEFPATH) && defined(_PATH_USERPATH)
#define _PATH_DEFPATH _PATH_USERPATH
#endif
#if defined(_PATH_DEFPATH) && !defined(_DEF_PATH)
#define _DEF_PATH _PATH_DEFPATH
#endif
#if !defined(_PATH_DEFPATH) && defined(_DEF_PATH)
#define _PATH_DEFPATH _DEF_PATH
#endif
#ifndef _PATH_DEFPATH
#define _PATH_DEFPATH "/usr/ucb:/usr/bin:/bin"
#define _DEF_PATH _PATH_DEFPATH
#endif /* !_PATH_DEFPATH */
#ifndef _PATH_DEFSUPATH
#define _PATH_DEFSUPATH "/usr/sbin:" _DEF_PATH
#endif /* _PATH_DEFSUPATH */
/******* Default PATH fixed! */
#undef _PATH_RLOGIN /* Redifine rlogin */
#define _PATH_RLOGIN BINDIR "/rlogin"
#undef _PATH_RSH /* Redifine rsh */
#define _PATH_RSH BINDIR "/rsh"
#undef _PATH_LOGIN
#define _PATH_LOGIN BINDIR "/login"
/******* The rest is fallback defaults */
#ifndef _PATH_DEV
#define _PATH_DEV "/dev/"
#endif
#ifndef _PATH_CP
#define _PATH_CP "/bin/cp"
#endif /* _PATH_CP */
#ifndef _PATH_SHELLS
#define _PATH_SHELLS "/etc/shells"
#endif /* _PATH_SHELLS */
#ifndef _PATH_BSHELL
#define _PATH_BSHELL "/bin/sh"
#endif /* _PATH_BSHELL */
#ifndef _PATH_CSHELL
#define _PATH_CSHELL "/bin/csh"
#endif /* _PATH_CSHELL */
#ifndef _PATH_NOLOGIN
#define _PATH_NOLOGIN "/etc/nologin"
#endif /* _PATH_NOLOGIN */
#ifndef _PATH_TTY
#define _PATH_TTY "/dev/tty"
#endif /* _PATH_TTY */
#ifndef _PATH_HUSHLOGIN
#define _PATH_HUSHLOGIN ".hushlogin"
#endif /* _PATH_HUSHLOGIN */
#ifndef _PATH_NOMAILCHECK
#define _PATH_NOMAILCHECK ".nomailcheck"
#endif /* _PATH_NOMAILCHECK */
#ifndef _PATH_MOTDFILE
#define _PATH_MOTDFILE "/etc/motd"
#endif /* _PATH_MOTDFILE */
#ifndef _PATH_LOGACCESS
#define _PATH_LOGACCESS "/etc/login.access"
#endif /* _PATH_LOGACCESS */
#ifndef _PATH_HEQUIV
#define _PATH_HEQUIV "/etc/hosts.equiv"
#endif
#ifndef _PATH_FBTAB
#define _PATH_FBTAB "/etc/fbtab"
#endif /* _PATH_FBTAB */
#ifndef _PATH_LOGINDEVPERM
#define _PATH_LOGINDEVPERM "/etc/logindevperm"
#endif /* _PATH_LOGINDEVPERM */
#ifndef _PATH_CHPASS
#define _PATH_CHPASS "/usr/bin/passwd"
#endif /* _PATH_CHPASS */
#if defined(__hpux)
#define __FALLBACK_MAILDIR__ "/usr/mail"
#else
#define __FALLBACK_MAILDIR__ "/usr/spool/mail"
#endif
#ifndef KRB4_MAILDIR
#ifndef _PATH_MAILDIR
#ifdef MAILDIR
#define _PATH_MAILDIR MAILDIR
#else
#define _PATH_MAILDIR __FALLBACK_MAILDIR__
#endif
#endif /* _PATH_MAILDIR */
#define KRB4_MAILDIR _PATH_MAILDIR
#endif
#ifndef _PATH_LASTLOG
#define _PATH_LASTLOG "/var/adm/lastlog"
#endif
#if defined(UTMP_FILE) && !defined(_PATH_UTMP)
#define _PATH_UTMP UTMP_FILE
#endif
#ifndef _PATH_UTMP
#define _PATH_UTMP "/etc/utmp"
#endif
#if defined(WTMP_FILE) && !defined(_PATH_WTMP)
#define _PATH_WTMP WTMP_FILE
#endif
#ifndef _PATH_WTMP
#define _PATH_WTMP "/usr/adm/wtmp"
#endif
#ifndef _PATH_ETC_DEFAULT_LOGIN
#define _PATH_ETC_DEFAULT_LOGIN "/etc/default/login"
#endif
#ifndef _PATH_ETC_ENVIRONMENT
#define _PATH_ETC_ENVIRONMENT "/etc/environment"
#endif
/*
* NeXT KLUDGE ALERT!!!!!!!!!!!!!!!!!!
* Some sort of bug in the NEXTSTEP cpp.
*/
#ifdef NeXT
#undef _PATH_DEFSUPATH
#define _PATH_DEFSUPATH "/usr/sbin:/usr/ucb:/usr/bin:/bin"
#undef _PATH_RLOGIN
#define _PATH_RLOGIN "/usr/athena/bin/rlogin"
#undef _PATH_RSH
#define _PATH_RSH "/usr/athena/bin/rsh"
#undef _PATH_LOGIN
#define _PATH_LOGIN "/usr/athena/bin/login"
#endif

View file

@ -0,0 +1,246 @@
/*
* Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Kungliga Tekniska
* Högskolan and its contributors.
*
* 4. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*/
#include "bsd_locl.h"
RCSID("$Id: rcmd_util.c,v 1.15 1997/05/02 14:27:44 assar Exp $");
int
get_login_port(int kerberos, int encryption)
{
char *service="login";
int port=htons(513);
if(kerberos && encryption){
service="eklogin";
port=htons(2105);
}
if(kerberos && !encryption){
service="klogin";
port=htons(543);
}
return k_getportbyname (service, "tcp", port);
}
int
get_shell_port(int kerberos, int encryption)
{
char *service="shell";
int port=htons(514);
if(kerberos && encryption){
service="ekshell";
port=htons(545);
}
if(kerberos && !encryption){
service="kshell";
port=htons(544);
}
return k_getportbyname (service, "tcp", port);
}
/*
* On reasonable systems, `cf[gs]et[io]speed' use values of bit/s
* directly, and the following functions are just identity functions.
* This is however a slower way of doing those
* should-be-but-are-not-always idenity functions.
*/
static struct { int speed; int bps; } conv[] = {
#ifdef B0
{B0, 0},
#endif
#ifdef B50
{B50, 50},
#endif
#ifdef B75
{B75, 75},
#endif
#ifdef B110
{B110, 110},
#endif
#ifdef B134
{B134, 134},
#endif
#ifdef B150
{B150, 150},
#endif
#ifdef B200
{B200, 200},
#endif
#ifdef B300
{B300, 300},
#endif
#ifdef B600
{B600, 600},
#endif
#ifdef B1200
{B1200, 1200},
#endif
#ifdef B1800
{B1800, 1800},
#endif
#ifdef B2400
{B2400, 2400},
#endif
#ifdef B4800
{B4800, 4800},
#endif
#ifdef B9600
{B9600, 9600},
#endif
#ifdef B19200
{B19200, 19200},
#endif
#ifdef B38400
{B38400, 38400},
#endif
#ifdef B57600
{B57600, 57600},
#endif
#ifdef B115200
{B115200, 115200},
#endif
#ifdef B153600
{B153600, 153600},
#endif
#ifdef B230400
{B230400, 230400},
#endif
#ifdef B307200
{B307200, 307200},
#endif
#ifdef B460800
{B460800, 460800},
#endif
};
#define N (sizeof(conv)/sizeof(*conv))
int
speed_t2int (speed_t s)
{
int l, r, m;
l = 0;
r = N - 1;
while(l <= r) {
m = (l + r) / 2;
if (conv[m].speed == s)
return conv[m].bps;
else if(conv[m].speed < s)
l = m + 1;
else
r = m - 1;
}
return -1;
}
/*
*
*/
speed_t
int2speed_t (int i)
{
int l, r, m;
l = 0;
r = N - 1;
while(l <= r) {
m = (l + r) / 2;
if (conv[m].bps == i)
return conv[m].speed;
else if(conv[m].bps < i)
l = m + 1;
else
r = m - 1;
}
return -1;
}
/*
* If there are any IP options on `sock', die.
*/
void
ip_options_and_die (int sock, struct sockaddr_in *fromp)
{
#if defined(IP_OPTIONS) && defined(HAVE_GETSOCKOPT)
u_char optbuf[BUFSIZ/3], *cp;
char lbuf[BUFSIZ], *lp;
int optsize = sizeof(optbuf), ipproto;
struct protoent *ip;
if ((ip = getprotobyname("ip")) != NULL)
ipproto = ip->p_proto;
else
ipproto = IPPROTO_IP;
if (getsockopt(sock, ipproto, IP_OPTIONS,
(void *)optbuf, &optsize) == 0 &&
optsize != 0) {
lp = lbuf;
for (cp = optbuf; optsize > 0; cp++, optsize--, lp += 3)
snprintf(lp, sizeof(lbuf) - (lp - lbuf), " %2.2x", *cp);
syslog(LOG_NOTICE,
"Connection received from %s using IP options (dead):%s",
inet_ntoa(fromp->sin_addr), lbuf);
exit(1);
}
#endif
}
void
warning(const char *fmt, ...)
{
char *rstar_no_warn = getenv("RSTAR_NO_WARN");
va_list args;
va_start(args, fmt);
if (rstar_no_warn == NULL)
rstar_no_warn = "";
if (strncmp(rstar_no_warn, "yes", 3) != 0) {
/* XXX */
fprintf(stderr, "%s: warning, using standard ", __progname);
warnx(fmt, args);
}
va_end(args);
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,97 @@
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*/
#include "bsd_locl.h"
RCSID("$Id: rcp_util.c,v 1.7 1996/11/17 20:23:05 assar Exp $");
char *
colon(char *cp)
{
if (*cp == ':') /* Leading colon is part of file name. */
return (0);
for (; *cp; ++cp) {
if (*cp == ':')
return (cp);
if (*cp == '/')
return (0);
}
return (0);
}
int
okname(char *cp0)
{
int c;
char *cp;
cp = cp0;
do {
c = *cp;
if (c & 0200)
goto bad;
if (!isalpha(c) && !isdigit(c) && c != '_' && c != '-')
goto bad;
} while (*++cp);
return (1);
bad: warnx("%s: invalid user name", cp0);
return (0);
}
int
susystem(char *s, int userid)
{
RETSIGTYPE (*istat)(), (*qstat)();
int status;
pid_t pid;
pid = fork();
switch (pid) {
case -1:
return (127);
case 0:
setuid(userid);
execl(_PATH_BSHELL, "sh", "-c", s, NULL);
_exit(127);
}
istat = signal(SIGINT, SIG_IGN);
qstat = signal(SIGQUIT, SIG_IGN);
if (waitpid(pid, &status, 0) < 0)
status = -1;
signal(SIGINT, istat);
signal(SIGQUIT, qstat);
return (status);
}

View file

@ -0,0 +1,707 @@
/*
* Copyright (c) 1983, 1990, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*/
/*
* rlogin - remote login
*/
#include "bsd_locl.h"
RCSID("$Id: rlogin.c,v 1.61 1997/05/25 01:14:47 assar Exp $");
CREDENTIALS cred;
Key_schedule schedule;
int use_kerberos = 1, doencrypt;
char dst_realm_buf[REALM_SZ], *dest_realm = NULL;
#ifndef CCEQ
#define c2uc(x) ((unsigned char) x)
#define CCEQ__(val, c) (c == val ? val != c2uc(_POSIX_VDISABLE) : 0)
#define CCEQ(val, c) CCEQ__(c2uc(val), c2uc(c))
#endif
int eight, rem;
struct termios deftty;
int noescape;
char escapechar = '~';
struct winsize winsize;
int parent, rcvcnt;
char rcvbuf[8 * 1024];
int child;
static void
echo(char c)
{
char *p;
char buf[8];
p = buf;
c &= 0177;
*p++ = escapechar;
if (c < ' ') {
*p++ = '^';
*p++ = c + '@';
} else if (c == 0177) {
*p++ = '^';
*p++ = '?';
} else
*p++ = c;
*p++ = '\r';
*p++ = '\n';
write(STDOUT_FILENO, buf, p - buf);
}
static void
mode(int f)
{
struct termios tty;
switch (f) {
case 0:
tcsetattr(0, TCSANOW, &deftty);
break;
case 1:
tcgetattr(0, &deftty);
tty = deftty;
/* This is loosely derived from sys/compat/tty_compat.c. */
tty.c_lflag &= ~(ECHO|ICANON|ISIG|IEXTEN);
tty.c_iflag &= ~ICRNL;
tty.c_oflag &= ~OPOST;
tty.c_cc[VMIN] = 1;
tty.c_cc[VTIME] = 0;
if (eight) {
tty.c_iflag &= IXOFF;
tty.c_cflag &= ~(CSIZE|PARENB);
tty.c_cflag |= CS8;
}
tcsetattr(0, TCSANOW, &tty);
break;
default:
return;
}
}
static void
done(int status)
{
int w, wstatus;
mode(0);
if (child > 0) {
/* make sure catch_child does not snap it up */
signal(SIGCHLD, SIG_DFL);
if (kill(child, SIGKILL) >= 0)
while ((w = wait(&wstatus)) > 0 && w != child);
}
exit(status);
}
static
RETSIGTYPE
catch_child(int foo)
{
int status;
int pid;
for (;;) {
pid = waitpid(-1, &status, WNOHANG|WUNTRACED);
if (pid == 0)
return;
/* if the child (reader) dies, just quit */
if (pid < 0 || (pid == child && !WIFSTOPPED(status)))
done(WTERMSIG(status) | WEXITSTATUS(status));
}
/* NOTREACHED */
}
/*
* There is a race in the SunOS5 rlogind. If the slave end has not yet
* been opened by the child when setting tty size the size is reset to
* zero when the child opens it. Therefore we send the window update
* twice.
*/
static int tty_kludge = 1;
/* Return the number of OOB bytes processed. */
static int
oob_real(void)
{
struct termios tty;
int atmark, n, out, rcvd;
char waste[BUFSIZ], mark;
out = O_RDWR;
rcvd = 0;
if (recv(rem, &mark, 1, MSG_OOB) < 0) {
return -1;
}
if (mark & TIOCPKT_WINDOW) {
/* Let server know about window size changes */
kill(parent, SIGUSR1);
} else if (tty_kludge) {
/* Let server know about window size changes */
kill(parent, SIGUSR1);
tty_kludge = 0;
}
if (!eight && (mark & TIOCPKT_NOSTOP)) {
tcgetattr(0, &tty);
tty.c_iflag &= ~IXON;
tcsetattr(0, TCSANOW, &tty);
}
if (!eight && (mark & TIOCPKT_DOSTOP)) {
tcgetattr(0, &tty);
tty.c_iflag |= (deftty.c_iflag & IXON);
tcsetattr(0, TCSANOW, &tty);
}
if (mark & TIOCPKT_FLUSHWRITE) {
#ifdef TCOFLUSH
tcflush(1, TCOFLUSH);
#else
ioctl(1, TIOCFLUSH, (char *)&out);
#endif
for (;;) {
if (ioctl(rem, SIOCATMARK, &atmark) < 0) {
warn("ioctl");
break;
}
if (atmark)
break;
n = read(rem, waste, sizeof (waste));
if (n <= 0)
break;
}
/*
* Don't want any pending data to be output, so clear the recv
* buffer. If we were hanging on a write when interrupted,
* don't want it to restart. If we were reading, restart
* anyway.
*/
rcvcnt = 0;
}
/* oob does not do FLUSHREAD (alas!) */
return 1;
}
/* reader: read from remote: line -> 1 */
static int
reader(void)
{
int n, remaining;
char *bufp;
int kludgep = 1;
bufp = rcvbuf;
for (;;) {
fd_set readfds, exceptfds;
while ((remaining = rcvcnt - (bufp - rcvbuf)) > 0) {
n = write(STDOUT_FILENO, bufp, remaining);
if (n < 0) {
if (errno != EINTR)
return (-1);
continue;
}
bufp += n;
}
bufp = rcvbuf;
rcvcnt = 0;
FD_ZERO (&readfds);
FD_SET (rem, &readfds);
FD_ZERO (&exceptfds);
if (kludgep)
FD_SET (rem, &exceptfds);
if (select(rem+1, &readfds, 0, &exceptfds, 0) == -1) {
if (errno == EINTR)
continue; /* Got signal */
else
errx(1, "select failed mysteriously");
}
if (!FD_ISSET(rem, &exceptfds) && !FD_ISSET(rem, &readfds)) {
warnx("select: nothing to read?");
continue;
}
if (FD_ISSET(rem, &exceptfds)) {
int foo = oob_real ();
if (foo >= 1)
continue; /* First check if there is more OOB data. */
else if (foo < 0)
kludgep = 0;
}
if (!FD_ISSET(rem, &readfds))
continue; /* Nothing to read. */
kludgep = 1;
#ifndef NOENCRYPTION
if (doencrypt)
rcvcnt = des_enc_read(rem, rcvbuf,
sizeof(rcvbuf),
schedule, &cred.session);
else
#endif
rcvcnt = read(rem, rcvbuf, sizeof (rcvbuf));
if (rcvcnt == 0)
return (0);
if (rcvcnt < 0) {
if (errno == EINTR)
continue;
warn("read");
return (-1);
}
}
}
/*
* Send the window size to the server via the magic escape
*/
static void
sendwindow(void)
{
char obuf[4 + 4 * sizeof (u_int16_t)];
unsigned short *p;
p = (u_int16_t *)(obuf + 4);
obuf[0] = 0377;
obuf[1] = 0377;
obuf[2] = 's';
obuf[3] = 's';
*p++ = htons(winsize.ws_row);
*p++ = htons(winsize.ws_col);
#ifdef HAVE_WS_XPIXEL
*p++ = htons(winsize.ws_xpixel);
#else
*p++ = htons(0);
#endif
#ifdef HAVE_WS_YPIXEL
*p++ = htons(winsize.ws_ypixel);
#else
*p++ = htons(0);
#endif
#ifndef NOENCRYPTION
if(doencrypt)
des_enc_write(rem, obuf, sizeof(obuf), schedule,
&cred.session);
else
#endif
write(rem, obuf, sizeof(obuf));
}
static
RETSIGTYPE
sigwinch(int foo)
{
struct winsize ws;
if (get_window_size(0, &ws) == 0 &&
memcmp(&ws, &winsize, sizeof(ws))) {
winsize = ws;
sendwindow();
}
}
static void
stop(int all)
{
mode(0);
signal(SIGCHLD, SIG_IGN);
kill(all ? 0 : getpid(), SIGTSTP);
signal(SIGCHLD, catch_child);
mode(1);
#ifdef SIGWINCH
kill(SIGWINCH, getpid()); /* check for size changes, if caught */
#endif
}
/*
* writer: write to remote: 0 -> line.
* ~. terminate
* ~^Z suspend rlogin process.
* ~<delayed-suspend char> suspend rlogin process, but leave reader alone.
*/
static void
writer(void)
{
int bol, local, n;
char c;
bol = 1; /* beginning of line */
local = 0;
for (;;) {
n = read(STDIN_FILENO, &c, 1);
if (n <= 0) {
if (n < 0 && errno == EINTR)
continue;
break;
}
/*
* If we're at the beginning of the line and recognize a
* command character, then we echo locally. Otherwise,
* characters are echo'd remotely. If the command character
* is doubled, this acts as a force and local echo is
* suppressed.
*/
if (bol) {
bol = 0;
if (!noescape && c == escapechar) {
local = 1;
continue;
}
} else if (local) {
local = 0;
if (c == '.' || CCEQ(deftty.c_cc[VEOF], c)) {
echo(c);
break;
}
if (CCEQ(deftty.c_cc[VSUSP], c)) {
bol = 1;
echo(c);
stop(1);
continue;
}
#ifdef VDSUSP
/* Is VDSUSP called something else on Linux?
* Perhaps VDELAY is a better thing? */
if (CCEQ(deftty.c_cc[VDSUSP], c)) {
bol = 1;
echo(c);
stop(0);
continue;
}
#endif /* VDSUSP */
if (c != escapechar)
#ifndef NOENCRYPTION
if (doencrypt)
des_enc_write(rem, &escapechar,1, schedule, &cred.session);
else
#endif
write(rem, &escapechar, 1);
}
if (doencrypt) {
#ifdef NOENCRYPTION
if (write(rem, &c, 1) == 0) {
#else
if (des_enc_write(rem, &c, 1, schedule, &cred.session) == 0) {
#endif
warnx("line gone");
break;
}
} else
if (write(rem, &c, 1) == 0) {
warnx("line gone");
break;
}
bol = CCEQ(deftty.c_cc[VKILL], c) ||
CCEQ(deftty.c_cc[VEOF], c) ||
CCEQ(deftty.c_cc[VINTR], c) ||
CCEQ(deftty.c_cc[VSUSP], c) ||
c == '\r' || c == '\n';
}
}
static
RETSIGTYPE
lostpeer(int foo)
{
signal(SIGPIPE, SIG_IGN);
warnx("\aconnection closed.\r");
done(1);
}
/*
* This is called in the parent when the reader process gets the
* out-of-band (urgent) request to turn on the window-changing
* protocol. It is signalled from the child(reader).
*/
static
RETSIGTYPE
sigusr1(int foo)
{
/*
* Now we now daemon supports winsize hack,
*/
sendwindow();
#ifdef SIGWINCH
signal(SIGWINCH, sigwinch); /* so we start to support it */
#endif
SIGRETURN(0);
}
static void
doit(void)
{
signal(SIGINT, SIG_IGN);
signal(SIGHUP, SIG_IGN);
signal(SIGQUIT, SIG_IGN);
signal(SIGCHLD, catch_child);
/*
* Child sends parent this signal for window size hack.
*/
signal(SIGUSR1, sigusr1);
signal(SIGPIPE, lostpeer);
mode(1);
parent = getpid();
child = fork();
if (child == -1) {
warn("fork");
done(1);
}
if (child == 0) {
signal(SIGCHLD, SIG_IGN);
signal(SIGTTOU, SIG_IGN);
if (reader() == 0)
errx(1, "connection closed.\r");
sleep(1);
errx(1, "\aconnection closed.\r");
}
writer();
warnx("closed connection.\r");
done(0);
}
static void
usage(void)
{
fprintf(stderr,
"usage: rlogin [ -%s]%s[-e char] [ -l username ] host\n",
"8DEKLdx", " [-k realm] ");
exit(1);
}
static u_int
getescape(char *p)
{
long val;
int len;
if ((len = strlen(p)) == 1) /* use any single char, including '\' */
return ((u_int)*p);
/* otherwise, \nnn */
if (*p == '\\' && len >= 2 && len <= 4) {
val = strtol(++p, NULL, 8);
for (;;) {
if (!*++p)
return ((u_int)val);
if (*p < '0' || *p > '8')
break;
}
}
warnx("illegal option value -- e");
usage();
return 0;
}
int
main(int argc, char **argv)
{
struct passwd *pw;
int sv_port, user_port = 0;
int argoff, ch, dflag, Dflag, one, uid;
char *host, *user, term[1024];
argoff = dflag = Dflag = 0;
one = 1;
host = user = NULL;
set_progname(argv[0]);
/* handle "rlogin host flags" */
if (argc > 2 && argv[1][0] != '-') {
host = argv[1];
argoff = 1;
}
#define OPTIONS "8DEKLde:k:l:xp:"
while ((ch = getopt(argc - argoff, argv + argoff, OPTIONS)) != EOF)
switch(ch) {
case '8':
eight = 1;
break;
case 'D':
Dflag = 1;
break;
case 'E':
noescape = 1;
break;
case 'K':
use_kerberos = 0;
break;
case 'd':
dflag = 1;
break;
case 'e':
noescape = 0;
escapechar = getescape(optarg);
break;
case 'k':
dest_realm = dst_realm_buf;
strncpy(dest_realm, optarg, REALM_SZ);
break;
case 'l':
user = optarg;
break;
case 'x':
doencrypt = 1;
break;
case 'p':
user_port = htons(atoi(optarg));
break;
case '?':
default:
usage();
}
optind += argoff;
argc -= optind;
argv += optind;
/* if haven't gotten a host yet, do so */
if (!host && !(host = *argv++))
usage();
if (*argv)
usage();
if (!(pw = k_getpwuid(uid = getuid())))
errx(1, "unknown user id.");
if (!user)
user = pw->pw_name;
if (user_port)
sv_port = user_port;
else
sv_port = get_login_port(use_kerberos, doencrypt);
{
char *p = getenv("TERM");
struct termios tty;
int i;
if (p == NULL)
p = "network";
if (tcgetattr(0, &tty) == 0
&& (i = speed_t2int (cfgetospeed(&tty))) > 0)
snprintf (term, sizeof(term),
"%s/%d",
p, i);
else
snprintf (term, sizeof(term),
"%s",
p);
}
get_window_size(0, &winsize);
try_connect:
if (use_kerberos) {
struct hostent *hp;
/* Fully qualify hostname (needed for krb_realmofhost). */
hp = gethostbyname(host);
if (hp != NULL && !(host = strdup(hp->h_name))) {
errno = ENOMEM;
err(1, NULL);
}
rem = KSUCCESS;
errno = 0;
if (dest_realm == NULL)
dest_realm = krb_realmofhost(host);
if (doencrypt)
rem = krcmd_mutual(&host, sv_port, user, term, 0,
dest_realm, &cred, schedule);
else
rem = krcmd(&host, sv_port, user, term, 0,
dest_realm);
if (rem < 0) {
use_kerberos = 0;
if (user_port == 0)
sv_port = get_login_port(use_kerberos,
doencrypt);
if (errno == ECONNREFUSED)
warning("remote host doesn't support Kerberos");
if (errno == ENOENT)
warning("can't provide Kerberos auth data");
goto try_connect;
}
} else {
if (doencrypt)
errx(1, "the -x flag requires Kerberos authentication.");
if (geteuid() != 0)
errx(1, "not installed setuid root, "
"only root may use non kerberized rlogin");
rem = rcmd(&host, sv_port, pw->pw_name, user, term, 0);
}
if (rem < 0)
exit(1);
#ifdef HAVE_SETSOCKOPT
#ifdef SO_DEBUG
if (dflag &&
setsockopt(rem, SOL_SOCKET, SO_DEBUG, (void *)&one,
sizeof(one)) < 0)
warn("setsockopt");
#endif
#ifdef TCP_NODELAY
if (Dflag &&
setsockopt(rem, IPPROTO_TCP, TCP_NODELAY, (void *)&one,
sizeof(one)) < 0)
warn("setsockopt(TCP_NODELAY)");
#endif
#ifdef IP_TOS
one = IPTOS_LOWDELAY;
if (setsockopt(rem, IPPROTO_IP, IP_TOS, (void *)&one, sizeof(int)) < 0)
warn("setsockopt(IP_TOS)");
#endif /* IP_TOS */
#endif /* HAVE_SETSOCKOPT */
setuid(uid);
doit();
return 0;
}

View file

@ -0,0 +1,934 @@
/*-
* Copyright (c) 1983, 1988, 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*/
/*
* remote login server:
* \0
* remuser\0
* locuser\0
* terminal_type/speed\0
* data
*/
#include "bsd_locl.h"
RCSID("$Id: rlogind.c,v 1.100 1997/05/25 01:15:20 assar Exp $");
extern int __check_rhosts_file;
char *INSECURE_MESSAGE =
"\r\n*** Connection not encrypted! Communication may be eavesdropped. ***"
"\r\n*** Use telnet or rlogin -x instead! ***\r\n";
#ifndef NOENCRYPTION
char *SECURE_MESSAGE =
"This rlogin session is using DES encryption for all transmissions.\r\n";
#else
#define SECURE_MESSAGE INSECURE_MESSAGE
#endif
AUTH_DAT *kdata;
KTEXT ticket;
u_char auth_buf[sizeof(AUTH_DAT)];
u_char tick_buf[sizeof(KTEXT_ST)];
Key_schedule schedule;
int doencrypt, retval, use_kerberos, vacuous;
#define ARGSTR "Daip:lnkvxL:"
char *env[2];
#define NMAX 30
char lusername[NMAX+1], rusername[NMAX+1];
static char term[64] = "TERM=";
#define ENVSIZE (sizeof("TERM=")-1) /* skip null for concatenation */
int keepalive = 1;
int check_all = 0;
int no_delay = 0;
struct passwd *pwd;
static const char *new_login = _PATH_LOGIN;
static void doit (int, struct sockaddr_in *);
static int control (int, char *, int);
static void protocol (int, int);
static RETSIGTYPE cleanup (int);
void fatal (int, const char *, int);
static int do_rlogin (struct sockaddr_in *);
static void setup_term (int);
static int do_krb_login (struct sockaddr_in *);
static void usage (void);
static int
readstream(int p, char *ibuf, int bufsize)
{
#ifndef HAVE_GETMSG
return read(p, ibuf, bufsize);
#else
static int flowison = -1; /* current state of flow: -1 is unknown */
static struct strbuf strbufc, strbufd;
static unsigned char ctlbuf[BUFSIZ];
static int use_read = 1;
int flags = 0;
int ret;
struct termios tsp;
struct iocblk ip;
char vstop, vstart;
int ixon;
int newflow;
if (use_read)
{
ret = read(p, ibuf, bufsize);
if (ret < 0 && errno == EBADMSG)
use_read = 0;
else
return ret;
}
strbufc.maxlen = BUFSIZ;
strbufc.buf = (char *)ctlbuf;
strbufd.maxlen = bufsize-1;
strbufd.len = 0;
strbufd.buf = ibuf+1;
ibuf[0] = 0;
ret = getmsg(p, &strbufc, &strbufd, &flags);
if (ret < 0) /* error of some sort -- probably EAGAIN */
return(-1);
if (strbufc.len <= 0 || ctlbuf[0] == M_DATA) {
/* data message */
if (strbufd.len > 0) { /* real data */
return(strbufd.len + 1); /* count header char */
} else {
/* nothing there */
errno = EAGAIN;
return(-1);
}
}
/*
* It's a control message. Return 1, to look at the flag we set
*/
switch (ctlbuf[0]) {
case M_FLUSH:
if (ibuf[1] & FLUSHW)
ibuf[0] = TIOCPKT_FLUSHWRITE;
return(1);
case M_IOCTL:
memcpy(&ip, (ibuf+1), sizeof(ip));
switch (ip.ioc_cmd) {
#ifdef TCSETS
case TCSETS:
case TCSETSW:
case TCSETSF:
memcpy(&tsp,
(ibuf+1 + sizeof(struct iocblk)),
sizeof(tsp));
vstop = tsp.c_cc[VSTOP];
vstart = tsp.c_cc[VSTART];
ixon = tsp.c_iflag & IXON;
break;
#endif
default:
errno = EAGAIN;
return(-1);
}
newflow = (ixon && (vstart == 021) && (vstop == 023)) ? 1 : 0;
if (newflow != flowison) { /* it's a change */
flowison = newflow;
ibuf[0] = newflow ? TIOCPKT_DOSTOP : TIOCPKT_NOSTOP;
return(1);
}
}
/* nothing worth doing anything about */
errno = EAGAIN;
return(-1);
#endif
}
#ifdef HAVE_UTMPX_H
static int
logout(const char *line)
{
struct utmpx utmpx, *utxp;
int ret = 1;
setutxent ();
memset(&utmpx, 0, sizeof(utmpx));
utmpx.ut_type = USER_PROCESS;
strncpy(utmpx.ut_line, line, sizeof(utmpx.ut_line));
utxp = getutxline(&utmpx);
if (utxp) {
strcpy(utxp->ut_user, "");
utxp->ut_type = DEAD_PROCESS;
#ifdef _STRUCT___EXIT_STATUS
utxp->ut_exit.__e_termination = 0;
utxp->ut_exit.__e_exit = 0;
#elif defined(__osf__) /* XXX */
utxp->ut_exit.ut_termination = 0;
utxp->ut_exit.ut_exit = 0;
#else
utxp->ut_exit.e_termination = 0;
utxp->ut_exit.e_exit = 0;
#endif
gettimeofday(&utxp->ut_tv, NULL);
pututxline(utxp);
#ifdef WTMPX_FILE
updwtmpx(WTMPX_FILE, utxp);
#else
ret = 0;
#endif
}
endutxent();
return ret;
}
#else
static int
logout(const char *line)
{
FILE *fp;
struct utmp ut;
int rval;
if (!(fp = fopen(_PATH_UTMP, "r+")))
return(0);
rval = 1;
while (fread(&ut, sizeof(struct utmp), 1, fp) == 1) {
if (!ut.ut_name[0] ||
strncmp(ut.ut_line, line, sizeof(ut.ut_line)))
continue;
memset(ut.ut_name, 0, sizeof(ut.ut_name));
#ifdef HAVE_UT_HOST
memset(ut.ut_host, 0, sizeof(ut.ut_host));
#endif
time(&ut.ut_time);
fseek(fp, (long)-sizeof(struct utmp), SEEK_CUR);
fwrite(&ut, sizeof(struct utmp), 1, fp);
fseek(fp, (long)0, SEEK_CUR);
rval = 0;
}
fclose(fp);
return(rval);
}
#endif
#ifndef HAVE_LOGWTMP
static void
logwtmp(const char *line, const char *name, const char *host)
{
struct utmp ut;
struct stat buf;
int fd;
memset (&ut, 0, sizeof(ut));
if ((fd = open(_PATH_WTMP, O_WRONLY|O_APPEND, 0)) < 0)
return;
if (!fstat(fd, &buf)) {
strncpy(ut.ut_line, line, sizeof(ut.ut_line));
strncpy(ut.ut_name, name, sizeof(ut.ut_name));
#ifdef HAVE_UT_HOST
strncpy(ut.ut_host, host, sizeof(ut.ut_host));
#endif
#ifdef HAVE_UT_PID
ut.ut_pid = getpid();
#endif
#ifdef HAVE_UT_TYPE
if(name[0])
ut.ut_type = USER_PROCESS;
else
ut.ut_type = DEAD_PROCESS;
#endif
time(&ut.ut_time);
if (write(fd, &ut, sizeof(struct utmp)) !=
sizeof(struct utmp))
ftruncate(fd, buf.st_size);
}
close(fd);
}
#endif
int
main(int argc, char **argv)
{
struct sockaddr_in from;
int ch, fromlen, on;
int interactive = 0;
int portnum = 0;
set_progname(argv[0]);
openlog("rlogind", LOG_PID | LOG_CONS, LOG_AUTH);
opterr = 0;
while ((ch = getopt(argc, argv, ARGSTR)) != EOF)
switch (ch) {
case 'D':
no_delay = 1;
break;
case 'a':
break;
case 'i':
interactive = 1;
break;
case 'p':
portnum = htons(atoi(optarg));
break;
case 'l':
__check_rhosts_file = 0;
break;
case 'n':
keepalive = 0;
break;
case 'k':
use_kerberos = 1;
break;
case 'v':
vacuous = 1;
break;
case 'x':
doencrypt = 1;
break;
case 'L':
new_login = optarg;
break;
case '?':
default:
usage();
break;
}
argc -= optind;
argv += optind;
if (use_kerberos && vacuous) {
usage();
fatal(STDERR_FILENO, "only one of -k and -v allowed", 0);
}
if (interactive) {
if(portnum == 0)
portnum = get_login_port (use_kerberos, doencrypt);
mini_inetd (portnum);
}
fromlen = sizeof (from);
if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
syslog(LOG_ERR,"Can't get peer name of remote host: %m");
fatal(STDERR_FILENO, "Can't get peer name of remote host", 1);
}
on = 1;
#ifdef HAVE_SETSOCKOPT
#ifdef SO_KEEPALIVE
if (keepalive &&
setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, (void *)&on,
sizeof (on)) < 0)
syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
#endif
#ifdef TCP_NODELAY
if (no_delay &&
setsockopt(0, IPPROTO_TCP, TCP_NODELAY, (void *)&on,
sizeof(on)) < 0)
syslog(LOG_WARNING, "setsockopt (TCP_NODELAY): %m");
#endif
#ifdef IP_TOS
on = IPTOS_LOWDELAY;
if (setsockopt(0, IPPROTO_IP, IP_TOS, (void *)&on, sizeof(int)) < 0)
syslog(LOG_WARNING, "setsockopt (IP_TOS): %m");
#endif
#endif /* HAVE_SETSOCKOPT */
doit(0, &from);
return 0;
}
int child;
int netf;
char line[MaxPathLen];
int confirmed;
struct winsize win = { 0, 0, 0, 0 };
static void
doit(int f, struct sockaddr_in *fromp)
{
int master, pid, on = 1;
int authenticated = 0;
char hostname[2 * MaxHostNameLen + 1];
char c;
alarm(60);
read(f, &c, 1);
if (c != 0)
exit(1);
if (vacuous)
fatal(f, "Remote host requires Kerberos authentication", 0);
alarm(0);
inaddr2str (fromp->sin_addr, hostname, sizeof(hostname));
if (use_kerberos) {
retval = do_krb_login(fromp);
if (retval == 0)
authenticated++;
else if (retval > 0)
fatal(f, krb_get_err_text(retval), 0);
write(f, &c, 1);
confirmed = 1; /* we sent the null! */
} else {
fromp->sin_port = ntohs((u_short)fromp->sin_port);
if (fromp->sin_family != AF_INET ||
fromp->sin_port >= IPPORT_RESERVED ||
fromp->sin_port < IPPORT_RESERVED/2) {
syslog(LOG_NOTICE, "Connection from %s on illegal port",
inet_ntoa(fromp->sin_addr));
fatal(f, "Permission denied", 0);
}
ip_options_and_die (0, fromp);
if (do_rlogin(fromp) == 0)
authenticated++;
}
if (confirmed == 0) {
write(f, "", 1);
confirmed = 1; /* we sent the null! */
}
#ifndef NOENCRYPTION
if (doencrypt)
des_enc_write(f, SECURE_MESSAGE,
strlen(SECURE_MESSAGE),
schedule, &kdata->session);
else
#endif
write(f, INSECURE_MESSAGE, strlen(INSECURE_MESSAGE));
netf = f;
pid = forkpty(&master, line, NULL, NULL);
if (pid < 0) {
if (errno == ENOENT)
fatal(f, "Out of ptys", 0);
else
fatal(f, "Forkpty", 1);
}
if (pid == 0) {
if (f > 2) /* f should always be 0, but... */
close(f);
setup_term(0);
if (lusername[0] == '-'){
syslog(LOG_ERR, "tried to pass user \"%s\" to login",
lusername);
fatal(STDERR_FILENO, "invalid user", 0);
}
if (authenticated) {
if (use_kerberos && (pwd->pw_uid == 0))
syslog(LOG_INFO|LOG_AUTH,
"ROOT Kerberos login from %s on %s\n",
krb_unparse_name_long(kdata->pname,
kdata->pinst,
kdata->prealm),
hostname);
execl(new_login, "login", "-p",
"-h", hostname, "-f", "--", lusername, 0);
} else
execl(new_login, "login", "-p",
"-h", hostname, "--", lusername, 0);
fatal(STDERR_FILENO, new_login, 1);
/*NOTREACHED*/
}
/*
* If encrypted, don't turn on NBIO or the des read/write
* routines will croak.
*/
if (!doencrypt)
ioctl(f, FIONBIO, &on);
ioctl(master, FIONBIO, &on);
ioctl(master, TIOCPKT, &on);
signal(SIGTSTP, SIG_IGN);
signal(SIGCHLD, cleanup);
setsid();
protocol(f, master);
signal(SIGCHLD, SIG_IGN);
cleanup(0);
}
const char magic[2] = { 0377, 0377 };
/*
* Handle a "control" request (signaled by magic being present)
* in the data stream. For now, we are only willing to handle
* window size changes.
*/
static int
control(int master, char *cp, int n)
{
struct winsize w;
char *p;
u_int32_t tmp;
if (n < 4 + 4 * sizeof (u_int16_t) || cp[2] != 's' || cp[3] != 's')
return (0);
#ifdef TIOCSWINSZ
p = cp + 4;
p += krb_get_int(p, &tmp, 2, 0);
w.ws_row = tmp;
p += krb_get_int(p, &tmp, 2, 0);
w.ws_col = tmp;
p += krb_get_int(p, &tmp, 2, 0);
#ifdef HAVE_WS_XPIXEL
w.ws_xpixel = tmp;
#endif
p += krb_get_int(p, &tmp, 2, 0);
#ifdef HAVE_WS_YPIXEL
w.ws_ypixel = tmp;
#endif
ioctl(master, TIOCSWINSZ, &w);
#endif
return p - cp;
}
static
void
send_oob(int fd, char c)
{
static char last_oob = 0xFF;
#if (SunOS == 5) || defined(__hpux)
/*
* PSoriasis and HP-UX always send TIOCPKT_DOSTOP at startup so we
* can avoid sending OOB data and thus not break on Linux by merging
* TIOCPKT_DOSTOP into the first TIOCPKT_WINDOW.
*/
static int oob_kludge = 2;
if (oob_kludge == 2)
{
oob_kludge--; /* First time send nothing */
return;
}
else if (oob_kludge == 1)
{
oob_kludge--; /* Second time merge TIOCPKT_WINDOW */
c |= TIOCPKT_WINDOW;
}
#endif
#define pkcontrol(c) ((c)&(TIOCPKT_FLUSHWRITE|TIOCPKT_NOSTOP|TIOCPKT_DOSTOP))
c = pkcontrol(c);
/* Multiple OOB data breaks on Linux, avoid it when possible. */
if (c != last_oob)
send(fd, &c, 1, MSG_OOB);
last_oob = c;
}
/*
* rlogin "protocol" machine.
*/
static void
protocol(int f, int master)
{
char pibuf[1024+1], fibuf[1024], *pbp, *fbp;
int pcc = 0, fcc = 0;
int cc, nfd, n;
char cntl;
unsigned char oob_queue = 0;
/*
* Must ignore SIGTTOU, otherwise we'll stop
* when we try and set slave pty's window shape
* (our controlling tty is the master pty).
*/
signal(SIGTTOU, SIG_IGN);
send_oob(f, TIOCPKT_WINDOW); /* indicate new rlogin */
if (f > master)
nfd = f + 1;
else
nfd = master + 1;
if (nfd > FD_SETSIZE) {
syslog(LOG_ERR, "select mask too small, increase FD_SETSIZE");
fatal(f, "internal error (select mask too small)", 0);
}
for (;;) {
fd_set ibits, obits, ebits, *omask;
FD_ZERO(&ebits);
FD_ZERO(&ibits);
FD_ZERO(&obits);
omask = (fd_set *)NULL;
if (fcc) {
FD_SET(master, &obits);
omask = &obits;
} else
FD_SET(f, &ibits);
if (pcc >= 0)
if (pcc) {
FD_SET(f, &obits);
omask = &obits;
} else
FD_SET(master, &ibits);
FD_SET(master, &ebits);
if ((n = select(nfd, &ibits, omask, &ebits, 0)) < 0) {
if (errno == EINTR)
continue;
fatal(f, "select", 1);
}
if (n == 0) {
/* shouldn't happen... */
sleep(5);
continue;
}
if (FD_ISSET(master, &ebits)) {
cc = readstream(master, &cntl, 1);
if (cc == 1 && pkcontrol(cntl)) {
#if 0 /* Kludge around */
send_oob(f, cntl);
#endif
oob_queue = cntl;
if (cntl & TIOCPKT_FLUSHWRITE) {
pcc = 0;
FD_CLR(master, &ibits);
}
}
}
if (FD_ISSET(f, &ibits)) {
#ifndef NOENCRYPTION
if (doencrypt)
fcc = des_enc_read(f, fibuf,
sizeof(fibuf),
schedule, &kdata->session);
else
#endif
fcc = read(f, fibuf, sizeof(fibuf));
if (fcc < 0 && errno == EWOULDBLOCK)
fcc = 0;
else {
char *cp;
int left, n;
if (fcc <= 0)
break;
fbp = fibuf;
top:
for (cp = fibuf; cp < fibuf+fcc-1; cp++)
if (cp[0] == magic[0] &&
cp[1] == magic[1]) {
left = fcc - (cp-fibuf);
n = control(master, cp, left);
if (n) {
left -= n;
if (left > 0)
memmove(cp, cp+n, left);
fcc -= n;
goto top; /* n^2 */
}
}
FD_SET(master, &obits); /* try write */
}
}
if (FD_ISSET(master, &obits) && fcc > 0) {
cc = write(master, fbp, fcc);
if (cc > 0) {
fcc -= cc;
fbp += cc;
}
}
if (FD_ISSET(master, &ibits)) {
pcc = readstream(master, pibuf, sizeof (pibuf));
pbp = pibuf;
if (pcc < 0 && errno == EWOULDBLOCK)
pcc = 0;
else if (pcc <= 0)
break;
else if (pibuf[0] == 0) {
pbp++, pcc--;
if (!doencrypt)
FD_SET(f, &obits); /* try write */
} else {
if (pkcontrol(pibuf[0])) {
oob_queue = pibuf[0];
#if 0 /* Kludge around */
send_oob(f, pibuf[0]);
#endif
}
pcc = 0;
}
}
if ((FD_ISSET(f, &obits)) && pcc > 0) {
#ifndef NOENCRYPTION
if (doencrypt)
cc = des_enc_write(f, pbp, pcc, schedule, &kdata->session);
else
#endif
cc = write(f, pbp, pcc);
if (cc < 0 && errno == EWOULDBLOCK) {
/*
* This happens when we try write after read
* from p, but some old kernels balk at large
* writes even when select returns true.
*/
if (!FD_ISSET(master, &ibits))
sleep(5);
continue;
}
if (cc > 0) {
pcc -= cc;
pbp += cc;
/* Only send urg data when normal data
* has just been sent.
* Linux has deep problems with more
* than one byte of OOB data.
*/
if (oob_queue) {
send_oob (f, oob_queue);
oob_queue = 0;
}
}
}
}
}
static RETSIGTYPE
cleanup(int signo)
{
char *p = clean_ttyname (line);
if (logout(p) == 0)
logwtmp(p, "", "");
chmod(line, 0666);
chown(line, 0, 0);
*p = 'p';
chmod(line, 0666);
chown(line, 0, 0);
shutdown(netf, 2);
signal(SIGHUP, SIG_IGN);
#ifdef HAVE_VHANGUP
vhangup();
#endif /* HAVE_VHANGUP */
exit(1);
}
void
fatal(int f, const char *msg, int syserr)
{
int len;
char buf[BUFSIZ], *bp = buf;
/*
* Prepend binary one to message if we haven't sent
* the magic null as confirmation.
*/
if (!confirmed)
*bp++ = '\01'; /* error indicator */
if (syserr)
snprintf(bp, sizeof(buf) - (bp - buf),
"rlogind: %s: %s.\r\n",
msg, strerror(errno));
else
snprintf(bp, sizeof(buf) - (bp - buf),
"rlogind: %s.\r\n", msg);
len = strlen(bp);
#ifndef NOENCRYPTION
if (doencrypt)
des_enc_write(f, buf, bp + len - buf, schedule, &kdata->session);
else
#endif
write(f, buf, bp + len - buf);
exit(1);
}
static void
xgetstr(char *buf, int cnt, char *errmsg)
{
char c;
do {
if (read(0, &c, 1) != 1)
exit(1);
if (--cnt < 0)
fatal(STDOUT_FILENO, errmsg, 0);
*buf++ = c;
} while (c != 0);
}
static int
do_rlogin(struct sockaddr_in *dest)
{
xgetstr(rusername, sizeof(rusername), "remuser too long");
xgetstr(lusername, sizeof(lusername), "locuser too long");
xgetstr(term+ENVSIZE, sizeof(term)-ENVSIZE, "Terminal type too long");
pwd = k_getpwnam(lusername);
if (pwd == NULL)
return (-1);
if (pwd->pw_uid == 0 && strcmp("root", lusername) != 0)
{
syslog(LOG_ALERT, "NIS attack, user %s has uid 0", lusername);
return (-1);
}
return (iruserok(dest->sin_addr.s_addr,
(pwd->pw_uid == 0),
rusername,
lusername));
}
static void
setup_term(int fd)
{
char *cp = strchr(term+ENVSIZE, '/');
char *speed;
struct termios tt;
tcgetattr(fd, &tt);
if (cp) {
int s;
*cp++ = '\0';
speed = cp;
cp = strchr(speed, '/');
if (cp)
*cp++ = '\0';
s = int2speed_t (atoi (speed));
if (s > 0) {
cfsetospeed (&tt, s);
cfsetispeed (&tt, s);
}
}
tt.c_iflag &= ~INPCK;
tt.c_iflag |= ICRNL|IXON;
tt.c_oflag |= OPOST|ONLCR;
#ifdef TAB3
tt.c_oflag |= TAB3;
#endif /* TAB3 */
#ifdef ONLRET
tt.c_oflag &= ~ONLRET;
#endif /* ONLRET */
tt.c_lflag |= (ECHO|ECHOE|ECHOK|ISIG|ICANON);
tt.c_cflag &= ~PARENB;
tt.c_cflag |= CS8;
tt.c_cc[VMIN] = 1;
tt.c_cc[VTIME] = 0;
tt.c_cc[VEOF] = CEOF;
tcsetattr(fd, TCSAFLUSH, &tt);
env[0] = term;
env[1] = 0;
environ = env;
}
#define VERSION_SIZE 9
/*
* Do the remote kerberos login to the named host with the
* given inet address
*
* Return 0 on valid authorization
* Return -1 on valid authentication, no authorization
* Return >0 for error conditions
*/
static int
do_krb_login(struct sockaddr_in *dest)
{
int rc;
char instance[INST_SZ], version[VERSION_SIZE];
long authopts = 0L; /* !mutual */
struct sockaddr_in faddr;
kdata = (AUTH_DAT *) auth_buf;
ticket = (KTEXT) tick_buf;
k_getsockinst(0, instance, sizeof(instance));
if (doencrypt) {
rc = sizeof(faddr);
if (getsockname(0, (struct sockaddr *)&faddr, &rc))
return (-1);
authopts = KOPT_DO_MUTUAL;
rc = krb_recvauth(
authopts, 0,
ticket, "rcmd",
instance, dest, &faddr,
kdata, "", schedule, version);
des_set_key(&kdata->session, schedule);
} else
rc = krb_recvauth(
authopts, 0,
ticket, "rcmd",
instance, dest, (struct sockaddr_in *) 0,
kdata, "", 0, version);
if (rc != KSUCCESS)
return (rc);
xgetstr(lusername, sizeof(lusername), "locuser");
/* get the "cmd" in the rcmd protocol */
xgetstr(term+ENVSIZE, sizeof(term)-ENVSIZE, "Terminal type");
pwd = k_getpwnam(lusername);
if (pwd == NULL)
return (-1);
if (pwd->pw_uid == 0 && strcmp("root", lusername) != 0)
{
syslog(LOG_ALERT, "NIS attack, user %s has uid 0", lusername);
return (-1);
}
/* returns nonzero for no access */
if (kuserok(kdata, lusername) != 0)
return (-1);
return (0);
}
static void
usage(void)
{
syslog(LOG_ERR,
"usage: rlogind [-Dailn] [-p port] [-x] [-L login] [-k | -v]");
exit(1);
}

View file

@ -0,0 +1,353 @@
/*-
* Copyright (c) 1983, 1990 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*/
#include "bsd_locl.h"
RCSID("$Id: rsh.c,v 1.35 1997/03/30 18:20:22 joda Exp $");
CREDENTIALS cred;
Key_schedule schedule;
int use_kerberos = 1, doencrypt;
char dst_realm_buf[REALM_SZ], *dest_realm;
/*
* rsh - remote shell
*/
int rfd2;
static void
usage(void)
{
fprintf(stderr,
"usage: rsh [-ndKx] [-k realm] [-l login] host [command]\n");
exit(1);
}
static char *
copyargs(char **argv)
{
int cc;
char **ap, *p;
char *args;
cc = 0;
for (ap = argv; *ap; ++ap)
cc += strlen(*ap) + 1;
if (!(args = malloc(cc)))
errx(1, "Out of memory.");
for (p = args, ap = argv; *ap; ++ap) {
strcpy(p, *ap);
for (p = strcpy(p, *ap); *p; ++p);
if (ap[1])
*p++ = ' ';
}
return(args);
}
static RETSIGTYPE
sendsig(int signo_)
{
char signo = signo_;
#ifndef NOENCRYPTION
if (doencrypt)
des_enc_write(rfd2, &signo, 1, schedule, &cred.session);
else
#endif
write(rfd2, &signo, 1);
}
static void
talk(int nflag, sigset_t omask, int pid, int rem)
{
int cc, wc;
char *bp;
fd_set readfrom, ready, rembits;
char buf[BUFSIZ];
if (pid == 0) {
if (nflag)
goto done;
close(rfd2);
reread: errno = 0;
if ((cc = read(0, buf, sizeof buf)) <= 0)
goto done;
bp = buf;
rewrite: FD_ZERO(&rembits);
FD_SET(rem, &rembits);
if (select(16, 0, &rembits, 0, 0) < 0) {
if (errno != EINTR)
err(1, "select");
goto rewrite;
}
if (!FD_ISSET(rem, &rembits))
goto rewrite;
#ifndef NOENCRYPTION
if (doencrypt)
wc = des_enc_write(rem, bp, cc, schedule, &cred.session);
else
#endif
wc = write(rem, bp, cc);
if (wc < 0) {
if (errno == EWOULDBLOCK)
goto rewrite;
goto done;
}
bp += wc;
cc -= wc;
if (cc == 0)
goto reread;
goto rewrite;
done:
shutdown(rem, 1);
exit(0);
}
if (sigprocmask(SIG_SETMASK, &omask, 0) != 0)
warn("sigprocmask");
FD_ZERO(&readfrom);
FD_SET(rem, &readfrom);
FD_SET(rfd2, &readfrom);
do {
ready = readfrom;
if (select(16, &ready, 0, 0, 0) < 0) {
if (errno != EINTR)
err(1, "select");
continue;
}
if (FD_ISSET(rfd2, &ready)) {
errno = 0;
#ifndef NOENCRYPTION
if (doencrypt)
cc = des_enc_read(rfd2, buf, sizeof buf,
schedule, &cred.session);
else
#endif
cc = read(rfd2, buf, sizeof buf);
if (cc <= 0) {
if (errno != EWOULDBLOCK)
FD_CLR(rfd2, &readfrom);
} else
write(2, buf, cc);
}
if (FD_ISSET(rem, &ready)) {
errno = 0;
#ifndef NOENCRYPTION
if (doencrypt)
cc = des_enc_read(rem, buf, sizeof buf,
schedule, &cred.session);
else
#endif
cc = read(rem, buf, sizeof buf);
if (cc <= 0) {
if (errno != EWOULDBLOCK)
FD_CLR(rem, &readfrom);
} else
write(1, buf, cc);
}
} while (FD_ISSET(rfd2, &readfrom) || FD_ISSET(rem, &readfrom));
}
int
main(int argc, char **argv)
{
struct passwd *pw;
int sv_port;
sigset_t omask;
int argoff, ch, dflag, nflag, nfork, one, pid, rem, uid;
char *args, *host, *user, *local_user;
argoff = dflag = nflag = nfork = 0;
one = 1;
host = user = NULL;
pid = 1;
set_progname(argv[0]);
/* handle "rsh host flags" */
if (!host && argc > 2 && argv[1][0] != '-') {
host = argv[1];
argoff = 1;
}
#define OPTIONS "+8KLde:k:l:nwx"
while ((ch = getopt(argc - argoff, argv + argoff, OPTIONS)) != EOF)
switch(ch) {
case 'K':
use_kerberos = 0;
break;
case 'L': /* -8Lew are ignored to allow rlogin aliases */
case 'e':
case 'w':
case '8':
break;
case 'd':
dflag = 1;
break;
case 'l':
user = optarg;
break;
case 'k':
dest_realm = dst_realm_buf;
strncpy(dest_realm, optarg, REALM_SZ);
break;
case 'n':
nflag = nfork = 1;
break;
case 'x':
doencrypt = 1;
break;
case '?':
default:
usage();
}
optind += argoff;
/* if haven't gotten a host yet, do so */
if (!host && !(host = argv[optind++]))
usage();
/* if no further arguments, must have been called as rlogin. */
if (!argv[optind]) {
*argv = "rlogin";
setuid(getuid());
execv(_PATH_RLOGIN, argv);
err(1, "can't exec %s", _PATH_RLOGIN);
}
argc -= optind;
argv += optind;
#ifndef __CYGWIN32__
if (!(pw = k_getpwuid(uid = getuid())))
errx(1, "unknown user id.");
local_user = pw->pw_name;
if (!user)
user = local_user;
#else
if (!user)
errx(1, "Sorry, you need to specify the username (with -l)");
local_user = user;
#endif
/* -n must still fork but does not turn of the -n functionality */
if (doencrypt)
nfork = 0;
args = copyargs(argv);
sv_port=get_shell_port(use_kerberos, doencrypt);
try_connect:
if (use_kerberos) {
rem = KSUCCESS;
errno = 0;
if (dest_realm == NULL)
dest_realm = krb_realmofhost(host);
if (doencrypt)
rem = krcmd_mutual(&host, sv_port, user, args,
&rfd2, dest_realm, &cred, schedule);
else
rem = krcmd(&host, sv_port, user, args, &rfd2,
dest_realm);
if (rem < 0) {
if (errno == ECONNREFUSED)
warning("remote host doesn't support Kerberos");
if (errno == ENOENT)
warning("can't provide Kerberos auth data");
use_kerberos = 0;
sv_port=get_shell_port(use_kerberos, doencrypt);
goto try_connect;
}
} else {
if (doencrypt)
errx(1, "the -x flag requires Kerberos authentication.");
if (geteuid() != 0)
errx(1, "not installed setuid root, "
"only root may use non kerberized rsh");
rem = rcmd(&host, sv_port, local_user, user, args, &rfd2);
}
if (rem < 0)
exit(1);
if (rfd2 < 0)
errx(1, "can't establish stderr.");
#if defined(SO_DEBUG) && defined(HAVE_SETSOCKOPT)
if (dflag) {
if (setsockopt(rem, SOL_SOCKET, SO_DEBUG, (void *)&one,
sizeof(one)) < 0)
warn("setsockopt");
if (setsockopt(rfd2, SOL_SOCKET, SO_DEBUG, (void *)&one,
sizeof(one)) < 0)
warn("setsockopt");
}
#endif
setuid(uid);
{
sigset_t sigmsk;
sigemptyset(&sigmsk);
sigaddset(&sigmsk, SIGINT);
sigaddset(&sigmsk, SIGQUIT);
sigaddset(&sigmsk, SIGTERM);
if (sigprocmask(SIG_BLOCK, &sigmsk, &omask) != 0)
warn("sigprocmask");
}
if (signal(SIGINT, SIG_IGN) != SIG_IGN)
signal(SIGINT, sendsig);
if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
signal(SIGQUIT, sendsig);
if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
signal(SIGTERM, sendsig);
if (!nfork) {
pid = fork();
if (pid < 0)
err(1, "fork");
}
if (!doencrypt) {
ioctl(rfd2, FIONBIO, &one);
ioctl(rem, FIONBIO, &one);
}
talk(nflag, omask, pid, rem);
if (!nflag)
kill(pid, SIGKILL);
exit(0);
}

View file

@ -0,0 +1,635 @@
/*-
* Copyright (c) 1988, 1989, 1992, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*/
/*
* remote shell server:
* [port]\0
* remuser\0
* locuser\0
* command\0
* data
*/
#include "bsd_locl.h"
RCSID("$Id: rshd.c,v 1.51 1997/05/13 09:42:39 bg Exp $");
extern char *__rcmd_errstr; /* syslog hook from libc/net/rcmd.c. */
extern int __check_rhosts_file;
static int keepalive = 1;
static int log_success; /* If TRUE, log all successful accesses */
static int new_pag = 1; /* Put process in new PAG by default */
static int no_inetd = 0;
static int sent_null;
static void doit (struct sockaddr_in *);
static void error (const char *, ...)
#ifdef __GNUC__
__attribute__ ((format (printf, 1, 2)))
#endif
;
static void usage (void);
#define VERSION_SIZE 9
#define SECURE_MESSAGE "This rsh session is using DES encryption for all transmissions.\r\n"
#define OPTIONS "alnkvxLp:Pi"
AUTH_DAT authbuf;
KTEXT_ST tickbuf;
int doencrypt, use_kerberos, vacuous;
Key_schedule schedule;
int
main(int argc, char *argv[])
{
struct linger linger;
int ch, on = 1, fromlen;
struct sockaddr_in from;
int portnum = 0;
set_progname(argv[0]);
openlog("rshd", LOG_PID | LOG_ODELAY, LOG_DAEMON);
opterr = 0;
while ((ch = getopt(argc, argv, OPTIONS)) != EOF)
switch (ch) {
case 'a':
break;
case 'l':
__check_rhosts_file = 0;
break;
case 'n':
keepalive = 0;
break;
case 'k':
use_kerberos = 1;
break;
case 'v':
vacuous = 1;
break;
case 'x':
doencrypt = 1;
break;
case 'L':
log_success = 1;
break;
case 'p':
portnum = htons(atoi(optarg));
break;
case 'P':
new_pag = 0;
break;
case 'i':
no_inetd = 1;
break;
case '?':
default:
usage();
break;
}
argc -= optind;
argv += optind;
if (use_kerberos && vacuous) {
syslog(LOG_ERR, "only one of -k and -v allowed");
exit(2);
}
if (doencrypt && !use_kerberos) {
syslog(LOG_ERR, "-k is required for -x");
exit(2);
}
if (no_inetd) {
if(portnum == 0)
portnum = get_shell_port (use_kerberos, doencrypt);
mini_inetd (portnum);
}
fromlen = sizeof (from);
if (getpeername(0, (struct sockaddr *)&from, &fromlen) < 0) {
syslog(LOG_ERR, "getpeername: %m");
_exit(1);
}
#ifdef HAVE_SETSOCKOPT
#ifdef SO_KEEPALIVE
if (keepalive &&
setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, (void *)&on,
sizeof(on)) < 0)
syslog(LOG_WARNING, "setsockopt (SO_KEEPALIVE): %m");
#endif
#ifdef SO_LINGER
linger.l_onoff = 1;
linger.l_linger = 60; /* XXX */
if (setsockopt(0, SOL_SOCKET, SO_LINGER, (void *)&linger,
sizeof (linger)) < 0)
syslog(LOG_WARNING, "setsockopt (SO_LINGER): %m");
#endif
#endif /* HAVE_SETSOCKOPT */
doit(&from);
/* NOTREACHED */
return 0;
}
char username[20] = "USER=";
char homedir[64] = "HOME=";
char shell[64] = "SHELL=";
char path[100] = "PATH=";
char *envinit[] =
{homedir, shell, path, username, 0};
static void
xgetstr(char *buf, int cnt, char *err)
{
char c;
do {
if (read(STDIN_FILENO, &c, 1) != 1)
exit(1);
*buf++ = c;
if (--cnt == 0) {
error("%s too long\n", err);
exit(1);
}
} while (c != 0);
}
static void
doit(struct sockaddr_in *fromp)
{
struct passwd *pwd;
u_short port;
fd_set ready, readfrom;
int cc, nfd, pv[2], pid, s;
int one = 1;
const char *errorhost = "";
char *errorstr;
char *cp, sig, buf[BUFSIZ];
char cmdbuf[NCARGS+1], locuser[16], remuser[16];
char remotehost[2 * MaxHostNameLen + 1];
AUTH_DAT *kdata;
KTEXT ticket;
char instance[INST_SZ], version[VERSION_SIZE];
struct sockaddr_in fromaddr;
int rc;
long authopts;
int pv1[2], pv2[2];
fd_set wready, writeto;
fromaddr = *fromp;
signal(SIGINT, SIG_DFL);
signal(SIGQUIT, SIG_DFL);
signal(SIGTERM, SIG_DFL);
#ifdef DEBUG
{ int t = open(_PATH_TTY, 2);
if (t >= 0) {
ioctl(t, TIOCNOTTY, (char *)0);
close(t);
}
}
#endif
fromp->sin_port = ntohs((u_short)fromp->sin_port);
if (fromp->sin_family != AF_INET) {
syslog(LOG_ERR, "malformed \"from\" address (af %d)\n",
fromp->sin_family);
exit(1);
}
if (!use_kerberos) {
ip_options_and_die (0, fromp);
if (fromp->sin_port >= IPPORT_RESERVED ||
fromp->sin_port < IPPORT_RESERVED/2) {
syslog(LOG_NOTICE|LOG_AUTH,
"Connection from %s on illegal port %u",
inet_ntoa(fromp->sin_addr),
fromp->sin_port);
exit(1);
}
}
alarm(60);
port = 0;
for (;;) {
char c;
if ((cc = read(STDIN_FILENO, &c, 1)) != 1) {
if (cc < 0)
syslog(LOG_NOTICE, "read: %m");
shutdown(0, 1+1);
exit(1);
}
if (c== 0)
break;
port = port * 10 + c - '0';
}
alarm(0);
if (port != 0) {
int lport = IPPORT_RESERVED - 1;
s = rresvport(&lport);
if (s < 0) {
syslog(LOG_ERR, "can't get stderr port: %m");
exit(1);
}
if (!use_kerberos)
if (port >= IPPORT_RESERVED) {
syslog(LOG_ERR, "2nd port not reserved\n");
exit(1);
}
fromp->sin_port = htons(port);
if (connect(s, (struct sockaddr *)fromp, sizeof (*fromp)) < 0) {
syslog(LOG_INFO, "connect second port %d: %m", port);
exit(1);
}
}
if (vacuous) {
error("rshd: remote host requires Kerberos authentication\n");
exit(1);
}
errorstr = NULL;
inaddr2str (fromp->sin_addr, remotehost, sizeof(remotehost));
if (use_kerberos) {
kdata = &authbuf;
ticket = &tickbuf;
authopts = 0L;
k_getsockinst(0, instance, sizeof(instance));
version[VERSION_SIZE - 1] = '\0';
if (doencrypt) {
struct sockaddr_in local_addr;
rc = sizeof(local_addr);
if (getsockname(0, (struct sockaddr *)&local_addr,
&rc) < 0) {
syslog(LOG_ERR, "getsockname: %m");
error("rlogind: getsockname: %m");
exit(1);
}
authopts = KOPT_DO_MUTUAL;
rc = krb_recvauth(authopts, 0, ticket,
"rcmd", instance, &fromaddr,
&local_addr, kdata, "", schedule,
version);
#ifndef NOENCRYPTION
des_set_key(&kdata->session, schedule);
#else
memset(schedule, 0, sizeof(schedule));
#endif
} else
rc = krb_recvauth(authopts, 0, ticket, "rcmd",
instance, &fromaddr,
(struct sockaddr_in *) 0,
kdata, "", 0, version);
if (rc != KSUCCESS) {
error("Kerberos authentication failure: %s\n",
krb_get_err_text(rc));
exit(1);
}
} else
xgetstr(remuser, sizeof(remuser), "remuser");
xgetstr(locuser, sizeof(locuser), "locuser");
xgetstr(cmdbuf, sizeof(cmdbuf), "command");
setpwent();
pwd = k_getpwnam(locuser);
if (pwd == NULL) {
syslog(LOG_INFO|LOG_AUTH,
"%s@%s as %s: unknown login. cmd='%.80s'",
remuser, remotehost, locuser, cmdbuf);
if (errorstr == NULL)
errorstr = "Login incorrect.\n";
goto fail;
}
if (pwd->pw_uid == 0 && strcmp("root", locuser) != 0)
{
syslog(LOG_ALERT, "NIS attack, user %s has uid 0", locuser);
if (errorstr == NULL)
errorstr = "Login incorrect.\n";
goto fail;
}
if (chdir(pwd->pw_dir) < 0) {
chdir("/");
#ifdef notdef
syslog(LOG_INFO|LOG_AUTH,
"%s@%s as %s: no home directory. cmd='%.80s'",
remuser, remotehost, locuser, cmdbuf);
error("No remote directory.\n");
exit(1);
#endif
}
if (use_kerberos) {
if (pwd->pw_passwd != 0 && *pwd->pw_passwd != '\0') {
if (kuserok(kdata, locuser) != 0) {
syslog(LOG_INFO|LOG_AUTH,
"Kerberos rsh denied to %s",
krb_unparse_name_long(kdata->pname,
kdata->pinst,
kdata->prealm));
error("Permission denied.\n");
exit(1);
}
}
} else
if (errorstr ||
pwd->pw_passwd != 0 && *pwd->pw_passwd != '\0' &&
iruserok(fromp->sin_addr.s_addr, pwd->pw_uid == 0,
remuser, locuser) < 0) {
if (__rcmd_errstr)
syslog(LOG_INFO|LOG_AUTH,
"%s@%s as %s: permission denied (%s). cmd='%.80s'",
remuser, remotehost, locuser,
__rcmd_errstr, cmdbuf);
else
syslog(LOG_INFO|LOG_AUTH,
"%s@%s as %s: permission denied. cmd='%.80s'",
remuser, remotehost, locuser, cmdbuf);
fail:
if (errorstr == NULL)
errorstr = "Permission denied.\n";
error(errorstr, errorhost);
exit(1);
}
if (pwd->pw_uid && !access(_PATH_NOLOGIN, F_OK)) {
error("Logins currently disabled.\n");
exit(1);
}
write(STDERR_FILENO, "\0", 1);
sent_null = 1;
if (port) {
if (pipe(pv) < 0) {
error("Can't make pipe.\n");
exit(1);
}
if (doencrypt) {
if (pipe(pv1) < 0) {
error("Can't make 2nd pipe.\n");
exit(1);
}
if (pipe(pv2) < 0) {
error("Can't make 3rd pipe.\n");
exit(1);
}
}
pid = fork();
if (pid == -1) {
error("Can't fork; try again.\n");
exit(1);
}
if (pid) {
if (doencrypt) {
static char msg[] = SECURE_MESSAGE;
close(pv1[1]);
close(pv2[0]);
#ifndef NOENCRYPTION
des_enc_write(s, msg, sizeof(msg) - 1, schedule, &kdata->session);
#else
write(s, msg, sizeof(msg) - 1);
#endif
} else {
close(0);
close(1);
}
close(2);
close(pv[1]);
FD_ZERO(&readfrom);
FD_SET(s, &readfrom);
FD_SET(pv[0], &readfrom);
if (pv[0] > s)
nfd = pv[0];
else
nfd = s;
if (doencrypt) {
FD_ZERO(&writeto);
FD_SET(pv2[1], &writeto);
FD_SET(pv1[0], &readfrom);
FD_SET(STDIN_FILENO, &readfrom);
nfd = max(nfd, pv2[1]);
nfd = max(nfd, pv1[0]);
} else
ioctl(pv[0], FIONBIO, (char *)&one);
/* should set s nbio! */
nfd++;
do {
ready = readfrom;
if (doencrypt) {
wready = writeto;
if (select(nfd, &ready,
&wready, 0,
(struct timeval *) 0) < 0)
break;
} else
if (select(nfd, &ready, 0,
0, (struct timeval *)0) < 0)
break;
if (FD_ISSET(s, &ready)) {
int ret;
if (doencrypt)
#ifndef NOENCRYPTION
ret = des_enc_read(s, &sig, 1, schedule, &kdata->session);
#else
ret = read(s, &sig, 1);
#endif
else
ret = read(s, &sig, 1);
if (ret <= 0)
FD_CLR(s, &readfrom);
else
kill(-pid, sig);
}
if (FD_ISSET(pv[0], &ready)) {
errno = 0;
cc = read(pv[0], buf, sizeof(buf));
if (cc <= 0) {
shutdown(s, 1+1);
FD_CLR(pv[0], &readfrom);
} else {
if (doencrypt)
#ifndef NOENCRYPTION
des_enc_write(s, buf, cc, schedule, &kdata->session);
#else
write(s, buf, cc);
#endif
else
(void)
write(s, buf, cc);
}
}
if (doencrypt && FD_ISSET(pv1[0], &ready)) {
errno = 0;
cc = read(pv1[0], buf, sizeof(buf));
if (cc <= 0) {
shutdown(pv1[0], 1+1);
FD_CLR(pv1[0], &readfrom);
} else
#ifndef NOENCRYPTION
des_enc_write(STDOUT_FILENO, buf, cc, schedule, &kdata->session);
#else
write(STDOUT_FILENO, buf, cc);
#endif
}
if (doencrypt
&& FD_ISSET(STDIN_FILENO, &ready)
&& FD_ISSET(pv2[1], &wready)) {
errno = 0;
#ifndef NOENCRYPTION
cc = des_enc_read(STDIN_FILENO, buf, sizeof(buf), schedule, &kdata->session);
#else
cc = read(STDIN_FILENO, buf, sizeof(buf));
#endif
if (cc <= 0) {
shutdown(STDIN_FILENO, 0);
FD_CLR(STDIN_FILENO, &readfrom);
close(pv2[1]);
FD_CLR(pv2[1], &writeto);
} else
write(pv2[1], buf, cc);
}
} while (FD_ISSET(s, &readfrom) ||
(doencrypt && FD_ISSET(pv1[0], &readfrom)) ||
FD_ISSET(pv[0], &readfrom));
exit(0);
}
setsid();
close(s);
close(pv[0]);
if (doencrypt) {
close(pv1[0]);
close(pv2[1]);
dup2(pv1[1], 1);
dup2(pv2[0], 0);
close(pv1[1]);
close(pv2[0]);
}
dup2(pv[1], 2);
close(pv[1]);
}
if (*pwd->pw_shell == '\0')
pwd->pw_shell = _PATH_BSHELL;
#ifdef HAVE_SETLOGIN
if (setlogin(pwd->pw_name) < 0)
syslog(LOG_ERR, "setlogin() failed: %m");
#endif
#ifdef HAVE_SETPCRED
if (setpcred (pwd->pw_name, NULL) == -1)
syslog(LOG_ERR, "setpcred() failure: %m");
#endif /* HAVE_SETPCRED */
setgid((gid_t)pwd->pw_gid);
initgroups(pwd->pw_name, pwd->pw_gid);
setuid((uid_t)pwd->pw_uid);
strncat(homedir, pwd->pw_dir, sizeof(homedir)-6);
/* Need to extend path to find rcp */
strncat(path, BINDIR, sizeof(path)-1);
strncat(path, ":", sizeof(path)-1);
strncat(path, _PATH_DEFPATH, sizeof(path)-1);
path[sizeof(path)-1] = '\0';
strncat(shell, pwd->pw_shell, sizeof(shell)-7);
strncat(username, pwd->pw_name, sizeof(username)-6);
cp = strrchr(pwd->pw_shell, '/');
if (cp)
cp++;
else
cp = pwd->pw_shell;
endpwent();
if (log_success || pwd->pw_uid == 0) {
if (use_kerberos)
syslog(LOG_INFO|LOG_AUTH,
"Kerberos shell from %s on %s as %s, cmd='%.80s'",
krb_unparse_name_long(kdata->pname,
kdata->pinst,
kdata->prealm),
remotehost, locuser, cmdbuf);
else
syslog(LOG_INFO|LOG_AUTH, "%s@%s as %s: cmd='%.80s'",
remuser, remotehost, locuser, cmdbuf);
}
if (k_hasafs()) {
if (new_pag)
k_setpag(); /* Put users process in an new pag */
k_afsklog(0, 0);
}
execle(pwd->pw_shell, cp, "-c", cmdbuf, 0, envinit);
err(1, pwd->pw_shell);
}
/*
* Report error to client. Note: can't be used until second socket has
* connected to client, or older clients will hang waiting for that
* connection first.
*/
static void
error(const char *fmt, ...)
{
va_list ap;
int len;
char *bp, buf[BUFSIZ];
va_start(ap, fmt);
bp = buf;
if (sent_null == 0) {
*bp++ = 1;
len = 1;
} else
len = 0;
len = vsnprintf (bp, sizeof(buf) - len, fmt, ap);
write (STDERR_FILENO, buf, len);
va_end(ap);
}
static void
usage()
{
syslog(LOG_ERR,
"usage: rshd [-alnkvxLPi] [-p port]");
exit(2);
}

View file

@ -0,0 +1,105 @@
/*
* Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Kungliga Tekniska
* Högskolan and its contributors.
*
* 4. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*/
#include "bsd_locl.h"
RCSID("$Id: stty_default.c,v 1.6 1997/04/01 08:17:17 joda Exp $");
#include <termios.h>
/* HP-UX 9.0 termios doesn't define these */
#ifndef FLUSHO
#define FLUSHO 0
#endif
#ifndef XTABS
#define XTABS 0
#endif
#ifndef OXTABS
#define OXTABS XTABS
#endif
/* Ultrix... */
#ifndef ECHOPRT
#define ECHOPRT 0
#endif
#ifndef ECHOCTL
#define ECHOCTL 0
#endif
#ifndef ECHOKE
#define ECHOKE 0
#endif
#ifndef IMAXBEL
#define IMAXBEL 0
#endif
#define Ctl(x) ((x) ^ 0100)
void
stty_default(void)
{
struct termios termios;
/*
* Finalize the terminal settings. Some systems default to 8 bits,
* others to 7, so we should leave that alone.
*/
tcgetattr(0, &termios);
termios.c_iflag |= (BRKINT|IGNPAR|ICRNL|IXON|IMAXBEL);
termios.c_iflag &= ~IXANY;
termios.c_lflag |= (ISIG|IEXTEN|ICANON|ECHO|ECHOE|ECHOK|ECHOCTL|ECHOKE);
termios.c_lflag &= ~(ECHOPRT|TOSTOP|FLUSHO);
termios.c_oflag |= (OPOST|ONLCR);
termios.c_oflag &= ~OXTABS;
termios.c_cc[VINTR] = Ctl('C');
termios.c_cc[VERASE] = Ctl('H');
termios.c_cc[VKILL] = Ctl('U');
termios.c_cc[VEOF] = Ctl('D');
termios.c_cc[VSUSP] = Ctl('Z');
tcsetattr(0, TCSANOW, &termios);
}

View file

@ -0,0 +1,452 @@
/*
* Copyright (c) 1988 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*/
#include "bsd_locl.h"
RCSID ("$Id: su.c,v 1.59 1997/05/26 17:45:54 bg Exp $");
#ifdef SYSV_SHADOW
#include "sysv_shadow.h"
#endif
static int kerberos (char *username, char *user, int uid);
static int chshell (char *sh);
static char *ontty (void);
static int koktologin (char *name, char *realm, char *toname);
static int chshell (char *sh);
/* Handle '-' option after all the getopt options */
#define ARGSTR "Kflmi:"
static int use_kerberos = 1;
static char *root_inst = "root";
int
main (int argc, char **argv)
{
struct passwd *pwd;
char *p, **g;
struct group *gr;
uid_t ruid;
int asme, ch, asthem, fastlogin, prio;
enum { UNSET, YES, NO } iscsh = UNSET;
char *user, *shell, *avshell, *username, **np;
char shellbuf[MaxPathLen], avshellbuf[MaxPathLen];
set_progname (argv[0]);
asme = asthem = fastlogin = 0;
while ((ch = getopt (argc, argv, ARGSTR)) != EOF)
switch ((char) ch) {
case 'K':
use_kerberos = 0;
break;
case 'f':
fastlogin = 1;
break;
case 'l':
asme = 0;
asthem = 1;
break;
case 'm':
asme = 1;
asthem = 0;
break;
case 'i':
root_inst = optarg;
break;
case '?':
default:
fprintf (stderr,
"usage: su [-Kflm] [-i root-instance] [-] [login]\n");
exit (1);
}
/* Don't handle '-' option with getopt */
if (optind < argc && strcmp (argv[optind], "-") == 0) {
asme = 0;
asthem = 1;
optind++;
}
argv += optind;
if (use_kerberos) {
int fd = open (KEYFILE, O_RDONLY);
if (fd >= 0)
close (fd);
else
use_kerberos = 0;
}
errno = 0;
prio = getpriority (PRIO_PROCESS, 0);
if (errno)
prio = 0;
setpriority (PRIO_PROCESS, 0, -2);
openlog ("su", LOG_CONS, 0);
/* get current login name and shell */
ruid = getuid ();
username = getlogin ();
if (username == NULL || (pwd = k_getpwnam (username)) == NULL ||
pwd->pw_uid != ruid)
pwd = k_getpwuid (ruid);
if (pwd == NULL)
errx (1, "who are you?");
username = strdup (pwd->pw_name);
if (asme)
if (pwd->pw_shell && *pwd->pw_shell)
shell = strcpy (shellbuf, pwd->pw_shell);
else {
shell = _PATH_BSHELL;
iscsh = NO;
}
/* get target login information, default to root */
user = *argv ? *argv : "root";
np = *argv ? argv : argv - 1;
pwd = k_getpwnam (user);
if (pwd == NULL)
errx (1, "unknown login %s", user);
if (pwd->pw_uid == 0 && strcmp ("root", user) != 0) {
syslog (LOG_ALERT, "NIS attack, user %s has uid 0", user);
errx (1, "unknown login %s", user);
}
if (!use_kerberos || kerberos (username, user, pwd->pw_uid)) {
#ifndef PASSWD_FALLBACK
errx (1, "won't use /etc/passwd authentication");
#endif
/* getpwnam() is not reentrant and kerberos might use it! */
pwd = k_getpwnam (user);
if (pwd == NULL)
errx (1, "unknown login %s", user);
/* only allow those in group zero to su to root. */
if (pwd->pw_uid == 0 && (gr = getgrgid ((gid_t) 0)))
for (g = gr->gr_mem;; ++g) {
if (!*g) {
#if 1
/* if group 0 is empty or only
contains root su is still ok. */
if (gr->gr_mem[0] == 0)
break; /* group 0 is empty */
if (gr->gr_mem[1] == 0 &&
strcmp (gr->gr_mem[0], "root") == 0)
break; /* only root in group 0 */
#endif
errx (1, "you are not in the correct group to su %s.",
user);
}
if (!strcmp (username, *g))
break;
}
/* if target requires a password, verify it */
if (ruid && *pwd->pw_passwd) {
char prompt[128];
char passwd[256];
snprintf (prompt, sizeof(prompt), "%s's Password: ", pwd->pw_name);
if (des_read_pw_string (passwd, sizeof (passwd),
prompt, 0)) {
memset (passwd, 0, sizeof (passwd));
exit (1);
}
if (strcmp (pwd->pw_passwd,
crypt (passwd, pwd->pw_passwd))) {
memset (passwd, 0, sizeof (passwd));
syslog (LOG_AUTH | LOG_WARNING,
"BAD SU %s to %s%s", username,
user, ontty ());
errx (1, "Sorry");
}
memset (passwd, 0, sizeof (passwd));
}
}
if (asme) {
/* if asme and non-standard target shell, must be root */
if (!chshell (pwd->pw_shell) && ruid)
errx (1, "permission denied (shell '%s' not in /etc/shells).",
pwd->pw_shell);
} else if (pwd->pw_shell && *pwd->pw_shell) {
shell = pwd->pw_shell;
iscsh = UNSET;
} else {
shell = _PATH_BSHELL;
iscsh = NO;
}
if ((p = strrchr (shell, '/')) != 0)
avshell = p + 1;
else
avshell = shell;
/* if we're forking a csh, we want to slightly muck the args */
if (iscsh == UNSET)
iscsh = strcmp (avshell, "csh") ? NO : YES;
/* set permissions */
if (setgid (pwd->pw_gid) < 0)
err (1, "setgid");
if (initgroups (user, pwd->pw_gid))
errx (1, "initgroups failed.");
if (setuid (pwd->pw_uid) < 0)
err (1, "setuid");
if (!asme) {
if (asthem) {
char *k = getenv ("KRBTKFILE");
char *t = getenv ("TERM");
environ = malloc (10 * sizeof (char *));
environ[0] = NULL;
setenv ("PATH", _PATH_DEFPATH, 1);
if (t)
setenv ("TERM", t, 1);
if (k)
setenv ("KRBTKFILE", k, 1);
if (chdir (pwd->pw_dir) < 0)
errx (1, "no directory");
}
if (asthem || pwd->pw_uid)
setenv ("USER", pwd->pw_name, 1);
setenv ("HOME", pwd->pw_dir, 1);
setenv ("SHELL", shell, 1);
}
if (iscsh == YES) {
if (fastlogin)
*np-- = "-f";
if (asme)
*np-- = "-m";
}
if (asthem) {
avshellbuf[0] = '-';
strcpy (avshellbuf + 1, avshell);
avshell = avshellbuf;
} else if (iscsh == YES) {
/* csh strips the first character... */
avshellbuf[0] = '_';
strcpy (avshellbuf + 1, avshell);
avshell = avshellbuf;
}
*np = avshell;
if (ruid != 0)
syslog (LOG_NOTICE | LOG_AUTH, "%s to %s%s",
username, user, ontty ());
setpriority (PRIO_PROCESS, 0, prio);
if (k_hasafs ()) {
int code;
if (k_setpag () != 0)
warn ("setpag");
code = k_afsklog (0, 0);
if (code != KSUCCESS && code != KDC_PR_UNKNOWN)
warnx ("afsklog: %s", krb_get_err_text (code));
}
execv (shell, np);
warn ("execv(%s)", shell);
if (getuid () == 0) {
execv (_PATH_BSHELL, np);
warn ("execv(%s)", _PATH_BSHELL);
}
exit (1);
}
static int
chshell (char *sh)
{
char *cp;
while ((cp = getusershell ()) != NULL)
if (!strcmp (cp, sh))
return (1);
return (0);
}
static char *
ontty (void)
{
char *p;
static char buf[MaxPathLen + 4];
buf[0] = 0;
if ((p = ttyname (STDERR_FILENO)) != 0)
snprintf (buf, sizeof(buf), " on %s", p);
return (buf);
}
static int
kerberos (char *username, char *user, int uid)
{
KTEXT_ST ticket;
AUTH_DAT authdata;
struct hostent *hp;
int kerno;
u_long faddr;
char lrealm[REALM_SZ], krbtkfile[MaxPathLen];
char hostname[MaxHostNameLen], savehost[MaxHostNameLen];
if (krb_get_lrealm (lrealm, 1) != KSUCCESS)
return (1);
if (koktologin (username, lrealm, user) && !uid) {
#ifndef PASSWD_FALLBACK
warnx ("not in %s's ACL.", user);
#endif
return (1);
}
snprintf (krbtkfile, sizeof(krbtkfile),
"%s_%s_to_%s_%u", TKT_ROOT, username, user,
(unsigned) getpid ());
setenv ("KRBTKFILE", krbtkfile, 1);
krb_set_tkt_string (krbtkfile);
/*
* Little trick here -- if we are su'ing to root, we need to get a ticket
* for "xxx.root", where xxx represents the name of the person su'ing.
* Otherwise (non-root case), we need to get a ticket for "yyy.", where
* yyy represents the name of the person being su'd to, and the instance
* is null
*
* We should have a way to set the ticket lifetime, with a system default
* for root.
*/
{
char prompt[128];
char passw[256];
snprintf (prompt, sizeof(prompt),
"%s's Password: ",
krb_unparse_name_long ((uid == 0 ? username : user),
(uid == 0 ? root_inst : ""),
lrealm));
if (des_read_pw_string (passw, sizeof (passw), prompt, 0)) {
memset (passw, 0, sizeof (passw));
return (1);
}
if (strlen(passw) == 0)
return (1); /* Empty passwords is not allowed */
kerno = krb_get_pw_in_tkt ((uid == 0 ? username : user),
(uid == 0 ? root_inst : ""), lrealm,
KRB_TICKET_GRANTING_TICKET,
lrealm,
DEFAULT_TKT_LIFE,
passw);
memset (passw, 0, strlen (passw));
}
if (kerno != KSUCCESS) {
if (kerno == KDC_PR_UNKNOWN) {
warnx ("principal unknown: %s",
krb_unparse_name_long ((uid == 0 ? username : user),
(uid == 0 ? root_inst : ""),
lrealm));
return (1);
}
warnx ("unable to su: %s", krb_get_err_text (kerno));
syslog (LOG_NOTICE | LOG_AUTH,
"BAD SU: %s to %s%s: %s",
username, user, ontty (), krb_get_err_text (kerno));
return (1);
}
if (chown (krbtkfile, uid, -1) < 0) {
warn ("chown");
unlink (krbtkfile);
return (1);
}
setpriority (PRIO_PROCESS, 0, -2);
if (k_gethostname (hostname, sizeof (hostname)) == -1) {
warn ("gethostname");
dest_tkt ();
return (1);
}
strncpy (savehost, krb_get_phost (hostname), sizeof (savehost));
savehost[sizeof (savehost) - 1] = '\0';
kerno = krb_mk_req (&ticket, "rcmd", savehost, lrealm, 33);
if (kerno == KDC_PR_UNKNOWN) {
warnx ("Warning: TGT not verified.");
syslog (LOG_NOTICE | LOG_AUTH,
"%s to %s%s, TGT not verified (%s); "
"%s.%s not registered?",
username, user, ontty (), krb_get_err_text (kerno),
"rcmd", savehost);
#ifdef KLOGIN_PARANOID
/*
* if the "VERIFY_SERVICE" doesn't exist in the KDC for this host, *
* don't allow kerberos login, also log the error condition.
*/
warnx ("Trying local password!");
return (1);
#endif
} else if (kerno != KSUCCESS) {
warnx ("Unable to use TGT: %s", krb_get_err_text (kerno));
syslog (LOG_NOTICE | LOG_AUTH, "failed su: %s to %s%s: %s",
username, user, ontty (), krb_get_err_text (kerno));
dest_tkt ();
return (1);
} else {
if (!(hp = gethostbyname (hostname))) {
warnx ("can't get addr of %s", hostname);
dest_tkt ();
return (1);
}
memcpy (&faddr, hp->h_addr, sizeof (faddr));
if ((kerno = krb_rd_req (&ticket, "rcmd", savehost, faddr,
&authdata, "")) != KSUCCESS) {
warnx ("unable to verify rcmd ticket: %s",
krb_get_err_text (kerno));
syslog (LOG_NOTICE | LOG_AUTH,
"failed su: %s to %s%s: %s", username,
user, ontty (), krb_get_err_text (kerno));
dest_tkt ();
return (1);
}
}
fprintf (stderr, "Don't forget to kdestroy before exiting the shell.\n");
return (0);
}
static int
koktologin (char *name, char *realm, char *toname)
{
return krb_kuserok (name,
strcmp (toname, "root") == 0 ? root_inst : "",
realm,
toname);
}

View file

@ -0,0 +1,95 @@
/* Author: Wietse Venema <wietse@wzv.win.tue.nl> */
#include "bsd_locl.h"
RCSID("$Id: sysv_default.c,v 1.9 1997/03/31 01:47:59 assar Exp $");
#include "sysv_default.h"
/*
* Default values for stuff that can be read from the defaults file. The
* SunOS 5.1 documentation is incomplete and often disagrees with reality.
*/
static char default_umask_value[] = "022";
char *default_console = 0;
char *default_altsh = "YES";
char *default_passreq = "NO";
char *default_timezone= 0;
char *default_hz = 0;
char *default_path = _PATH_DEFPATH;
char *default_supath = _PATH_DEFSUPATH;
char *default_ulimit = 0;
char *default_timeout = "60";
char *default_umask = default_umask_value;
char *default_sleep = "4";
char *default_maxtrys = "5";
static struct sysv_default {
char **valptr;
char *prefix;
int prefix_len;
} defaults[] = {
{&default_console, "CONSOLE=", sizeof("CONSOLE=") -1},
{&default_altsh, "ALTSHELL=", sizeof("ALTSHELL=") -1},
{&default_passreq, "PASSREQ=", sizeof("PASSREQ=") -1},
{&default_timezone, "TIMEZONE=", sizeof("TIMEZONE=") -1},
{&default_hz, "HZ=", sizeof("HZ=") -1},
{&default_path, "PATH=", sizeof("PATH=") -1},
{&default_supath, "SUPATH=", sizeof("SUPATH=") -1},
{&default_ulimit, "ULIMIT=", sizeof("ULIMIT=") -1},
{&default_timeout, "TIMEOUT=", sizeof("TIMEOUT=") -1},
{&default_umask, "UMASK=", sizeof("UMASK=") -1},
{&default_sleep, "SLEEPTIME=", sizeof("SLEEPTIME=") -1},
{&default_maxtrys, "MAXTRYS=", sizeof("MAXTRYS=") -1},
{0},
};
#define trim(s) { \
char *cp = s + strlen(s); \
while (cp > s && isspace(cp[-1])) \
cp--; \
*cp = 0; \
}
/* sysv_defaults - read login defaults file */
void
sysv_defaults()
{
struct sysv_default *dp;
FILE *fp;
char buf[BUFSIZ];
if ((fp = fopen(_PATH_ETC_DEFAULT_LOGIN, "r"))) {
/* Stupid quadratic algorithm. */
while (fgets(buf, sizeof(buf), fp)) {
/* Skip comments and blank lines. */
if (buf[0] == '#')
continue;
trim(buf);
if (buf[0] == 0)
continue;
/* Assign defaults from file. */
#define STREQN(x,y,l) (x[0] == y[0] && strncmp(x,y,l) == 0)
for (dp = defaults; dp->valptr; dp++) {
if (STREQN(buf, dp->prefix, dp->prefix_len)) {
if ((*(dp->valptr) = strdup(buf + dp->prefix_len)) == 0) {
warnx("Insufficient memory resources - try later.");
sleepexit(1);
}
break;
}
}
}
fclose(fp);
}
}

View file

@ -0,0 +1,18 @@
/* Author: Wietse Venema <wietse@wzv.win.tue.nl> */
/* $Id: sysv_default.h,v 1.5 1996/10/27 23:51:14 assar Exp $ */
extern char *default_console;
extern char *default_altsh;
extern char *default_passreq;
extern char *default_timezone;
extern char *default_hz;
extern char *default_path;
extern char *default_supath;
extern char *default_ulimit;
extern char *default_timeout;
extern char *default_umask;
extern char *default_sleep;
extern char *default_maxtrys;
void sysv_defaults(void);

View file

@ -0,0 +1,192 @@
/* Author: Wietse Venema <wietse@wzv.win.tue.nl> */
#include "bsd_locl.h"
RCSID("$Id: sysv_environ.c,v 1.21 1997/05/14 17:34:15 joda Exp $");
#ifdef HAVE_ULIMIT_H
#include <ulimit.h>
#endif
#ifndef UL_SETFSIZE
#define UL_SETFSIZE 2
#endif
#include "sysv_default.h"
/*
* Set
*/
static void
read_etc_environment (void)
{
FILE *f;
char buf[BUFSIZ];
f = fopen(_PATH_ETC_ENVIRONMENT, "r");
if (f) {
char *val;
while (fgets (buf, sizeof(buf), f) != NULL) {
if (buf[0] == '\n' || buf[0] == '#')
continue;
buf[strlen(buf) - 1] = '\0';
val = strchr (buf, '=');
if (val == NULL)
continue;
*val = '\0';
setenv(buf, val + 1, 1);
}
fclose (f);
}
}
/*
* Environment variables that are preserved (but may still be overruled by
* other means). Only TERM and TZ appear to survive (SunOS 5.1). These are
* typically inherited from the ttymon process.
*/
static struct preserved {
char *name;
char *value;
} preserved[] = {
{"TZ", 0},
{"TERM", 0},
{0},
};
/*
* Environment variables that are not preserved and that cannot be specified
* via commandline or stdin. Except for the LD_xxx (runtime linker) stuff,
* the list applies to most SYSV systems. The manpage mentions only that
* SHELL and PATH are censored. HOME, LOGNAME and MAIL are always
* overwritten; they are in the list to make the censoring explicit.
*/
static struct censored {
char *prefix;
int length;
} censored[] = {
{"SHELL=", sizeof("SHELL=") - 1},
{"HOME=", sizeof("HOME=") - 1},
{"LOGNAME=", sizeof("LOGNAME=") - 1},
{"MAIL=", sizeof("MAIL=") - 1},
{"CDPATH=", sizeof("CDPATH=") - 1},
{"IFS=", sizeof("IFS=") - 1},
{"PATH=", sizeof("PATH=") - 1},
{"LD_", sizeof("LD_") - 1},
{0},
};
/* sysv_newenv - set up final environment after logging in */
void sysv_newenv(int argc, char **argv, struct passwd *pwd,
char *term, int pflag)
{
unsigned umask_val;
long limit_val;
char buf[BUFSIZ];
int count = 0;
struct censored *cp;
struct preserved *pp;
/* Preserve a selection of the environment. */
for (pp = preserved; pp->name; pp++)
pp->value = getenv(pp->name);
/*
* Note: it is a bad idea to assign a static array to the global environ
* variable. Reason is that putenv() can run into problems when it tries
* to realloc() the environment table. Instead, we just clear environ[0]
* and let putenv() work things out.
*/
if (!pflag && environ)
environ[0] = 0;
/* Restore preserved environment variables. */
for (pp = preserved; pp->name; pp++)
if (pp->value)
setenv(pp->name, pp->value, 1);
/* The TERM definition from e.g. rlogind can override an existing one. */
if (term[0])
setenv("TERM", term, 1);
/*
* Environment definitions from the command line overrule existing ones,
* but can be overruled by definitions from stdin. Some variables are
* censored.
*
* Omission: we do not support environment definitions from stdin.
*/
#define STREQN(x,y,l) (x[0] == y[0] && strncmp(x,y,l) == 0)
while (argc && *argv) {
if (strchr(*argv, '=') == 0) {
snprintf(buf, sizeof(buf), "L%d", count++);
setenv(buf, *argv, 1);
} else {
for (cp = censored; cp->prefix; cp++)
if (STREQN(*argv, cp->prefix, cp->length))
break;
if (cp->prefix == 0)
putenv(*argv);
}
argc--, argv++;
}
/* PATH is always reset. */
setenv("PATH", pwd->pw_uid ? default_path : default_supath, 1);
/* Undocumented: HOME, MAIL and LOGNAME are always reset (SunOS 5.1). */
setenv("HOME", pwd->pw_dir, 1);
{
char *sep = "/";
if(KRB4_MAILDIR[strlen(KRB4_MAILDIR) - 1] == '/')
sep = "";
k_concat(buf, sizeof(buf), KRB4_MAILDIR, sep, pwd->pw_name, NULL);
}
setenv("MAIL", buf, 1);
setenv("LOGNAME", pwd->pw_name, 1);
setenv("USER", pwd->pw_name, 1);
/*
* Variables that may be set according to specifications in the defaults
* file. HZ and TZ are set only if they are still uninitialized.
*
* Extension: when ALTSHELL=YES, we set the SHELL variable even if it is
* /bin/sh.
*/
if (strcasecmp(default_altsh, "YES") == 0)
setenv("SHELL", pwd->pw_shell, 1);
if (default_hz)
setenv("HZ", default_hz, 0);
if (default_timezone)
setenv("TZ", default_timezone, 0);
/* Non-environment stuff. */
if (default_umask) {
if (sscanf(default_umask, "%o", &umask_val) == 1 && umask_val)
umask(umask_val);
}
#ifdef HAVE_ULIMIT
if (default_ulimit) {
if (sscanf(default_ulimit, "%ld", &limit_val) == 1 && limit_val)
if (ulimit(UL_SETFSIZE, limit_val) < 0)
warn ("ulimit(UL_SETFSIZE, %ld)", limit_val);
}
#endif
read_etc_environment();
}

View file

@ -0,0 +1,45 @@
/* Author: Wietse Venema <wietse@wzv.win.tue.nl> */
#include "bsd_locl.h"
RCSID("$Id: sysv_shadow.c,v 1.7 1997/03/23 04:56:05 assar Exp $");
#ifdef SYSV_SHADOW
#include <sysv_shadow.h>
/* sysv_expire - check account and password expiration times */
int
sysv_expire(struct spwd *spwd)
{
long today;
tzset();
today = time(0);
if (spwd->sp_expire > 0) {
if (today > spwd->sp_expire) {
printf("Your account has expired.\n");
sleepexit(1);
} else if (spwd->sp_expire - today < 14) {
printf("Your account will expire in %d days.\n",
(int)(spwd->sp_expire - today));
return (0);
}
}
if (spwd->sp_max > 0) {
if (today > (spwd->sp_lstchg + spwd->sp_max)) {
printf("Your password has expired. Choose a new one.\n");
return (1);
} else if (spwd->sp_warn > 0
&& (today > (spwd->sp_lstchg + spwd->sp_max - spwd->sp_warn))) {
printf("Your password will expire in %d days.\n",
(int)(spwd->sp_lstchg + spwd->sp_max - today));
return (0);
}
}
return (0);
}
#endif /* SYSV_SHADOW */

View file

@ -0,0 +1,5 @@
/* $Id: sysv_shadow.h,v 1.6 1997/03/23 04:55:51 assar Exp $ */
#include <shadow.h>
extern sysv_expire(struct spwd *);

View file

@ -0,0 +1,75 @@
/*
* Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Kungliga Tekniska
* Högskolan and its contributors.
*
* 4. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*/
#include "bsd_locl.h"
RCSID("$Id: tty.c,v 1.2 1997/05/25 01:14:22 assar Exp $");
/*
* Clean the tty name. Return a pointer to the cleaned version.
*/
char *
clean_ttyname (char *tty)
{
char *res = tty;
if (strncmp (res, _PATH_DEV, strlen(_PATH_DEV)) == 0)
res += strlen(_PATH_DEV);
if (strncmp (res, "pty/", 4) == 0)
res += 4;
if (strncmp (res, "ptym/", 5) == 0)
res += 5;
return res;
}
/*
* Generate a name usable as an `ut_id', typically without `tty'.
*/
char *
make_id (char *tty)
{
char *res = tty;
if (strncmp (res, "pts/", 4) == 0)
res += 4;
if (strncmp (res, "tty", 3) == 0)
res += 3;
return res;
}

View file

@ -0,0 +1,121 @@
/*
* Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Kungliga Tekniska
* Högskolan and its contributors.
*
* 4. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*/
#include "bsd_locl.h"
RCSID("$Id: utmp_login.c,v 1.13 1997/05/20 13:46:21 assar Exp $");
void
prepare_utmp (struct utmp *utmp, char *tty, char *username, char *hostname)
{
char *ttyx = clean_ttyname (tty);
memset(utmp, 0, sizeof(*utmp));
utmp->ut_time = time(NULL);
strncpy(utmp->ut_line, ttyx, sizeof(utmp->ut_line));
strncpy(utmp->ut_name, username, sizeof(utmp->ut_name));
# ifdef HAVE_UT_USER
strncpy(utmp->ut_user, username, sizeof(utmp->ut_user));
# endif
# ifdef HAVE_UT_ADDR
if (hostname[0]) {
struct hostent *he;
if ((he = gethostbyname(hostname)))
memcpy(&utmp->ut_addr, he->h_addr_list[0],
sizeof(utmp->ut_addr));
}
# endif
# ifdef HAVE_UT_HOST
strncpy(utmp->ut_host, hostname, sizeof(utmp->ut_host));
# endif
# ifdef HAVE_UT_TYPE
utmp->ut_type = USER_PROCESS;
# endif
# ifdef HAVE_UT_PID
utmp->ut_pid = getpid();
# endif
# ifdef HAVE_UT_ID
strncpy(utmp->ut_id, make_id(ttyx), sizeof(utmp->ut_id));
# endif
}
#ifdef HAVE_UTMPX_H
void utmp_login(char *tty, char *username, char *hostname) { return; }
#else
/* update utmp and wtmp - the BSD way */
void utmp_login(char *tty, char *username, char *hostname)
{
struct utmp utmp;
int fd;
prepare_utmp (&utmp, tty, username, hostname);
#ifdef HAVE_SETUTENT
utmpname(_PATH_UTMP);
setutent();
pututline(&utmp);
endutent();
#else
#ifdef HAVE_TTYSLOT
{
int ttyno;
ttyno = ttyslot();
if (ttyno > 0 && (fd = open(_PATH_UTMP, O_WRONLY, 0)) >= 0) {
lseek(fd, (long)(ttyno * sizeof(struct utmp)), SEEK_SET);
write(fd, &utmp, sizeof(struct utmp));
close(fd);
}
}
#endif /* HAVE_TTYSLOT */
#endif /* HAVE_SETUTENT */
if ((fd = open(_PATH_WTMP, O_WRONLY|O_APPEND, 0)) >= 0) {
write(fd, &utmp, sizeof(struct utmp));
close(fd);
}
}
#endif /* !HAVE_UTMPX_H */

View file

@ -0,0 +1,88 @@
/* Author: Wietse Venema <wietse@wzv.win.tue.nl> */
#include "bsd_locl.h"
RCSID("$Id: utmpx_login.c,v 1.20 1997/06/01 03:13:15 assar Exp $");
/* utmpx_login - update utmp and wtmp after login */
#ifndef HAVE_UTMPX_H
int utmpx_login(char *line, char *user, char *host) { return 0; }
#else
static void
utmpx_update(struct utmpx *ut, char *line, char *user, char *host)
{
struct timeval tmp;
char *clean_tty = clean_ttyname(line);
strncpy(ut->ut_line, clean_tty, sizeof(ut->ut_line));
#ifdef HAVE_UT_ID
strncpy(ut->ut_id, make_id(clean_tty), sizeof(ut->ut_id));
#endif
strncpy(ut->ut_user, user, sizeof(ut->ut_user));
strncpy(ut->ut_host, host, sizeof(ut->ut_host));
#ifdef HAVE_UT_SYSLEN
ut->ut_syslen = strlen(host) + 1;
if (ut->ut_syslen > sizeof(ut->ut_host))
ut->ut_syslen = sizeof(ut->ut_host);
#endif
ut->ut_type = USER_PROCESS;
gettimeofday (&tmp, 0);
ut->ut_tv.tv_sec = tmp.tv_sec;
ut->ut_tv.tv_usec = tmp.tv_usec;
pututxline(ut);
#ifdef WTMPX_FILE
updwtmpx(WTMPX_FILE, ut);
#elif defined(WTMP_FILE)
{
struct utmp utmp;
int fd;
prepare_utmp (&utmp, line, user, host);
if ((fd = open(_PATH_WTMP, O_WRONLY|O_APPEND, 0)) >= 0) {
write(fd, &utmp, sizeof(struct utmp));
close(fd);
}
}
#endif
}
int
utmpx_login(char *line, char *user, char *host)
{
struct utmpx *ut;
pid_t mypid = getpid();
int ret = (-1);
/*
* SYSV4 ttymon and login use tty port names with the "/dev/" prefix
* stripped off. Rlogind and telnetd, on the other hand, make utmpx
* entries with device names like /dev/pts/nnn. We therefore cannot use
* getutxline(). Return nonzero if no utmp entry was found with our own
* process ID for a login or user process.
*/
while ((ut = getutxent())) {
/* Try to find a reusable entry */
if (ut->ut_pid == mypid
&& ( ut->ut_type == INIT_PROCESS
|| ut->ut_type == LOGIN_PROCESS
|| ut->ut_type == USER_PROCESS)) {
utmpx_update(ut, line, user, host);
ret = 0;
break;
}
}
if (ret == -1) {
/* Grow utmpx file by one record. */
struct utmpx newut;
memset(&newut, 0, sizeof(newut));
newut.ut_pid = mypid;
utmpx_update(&newut, line, user, host);
ret = 0;
}
endutxent();
return (ret);
}
#endif /* HAVE_UTMPX_H */

View file

@ -0,0 +1,41 @@
# $Id: Makefile.in,v 1.9 1997/03/23 13:03:54 assar Exp $
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
SHELL = /bin/sh
@SET_MAKE@
CC = @CC@
RANLIB = @RANLIB@
DEFS = @DEFS@
CFLAGS = @CFLAGS@
INSTALL = @INSTALL@
prefix = @prefix@
SUBDIRS=common ftp ftpd
all:
for i in $(SUBDIRS); \
do (cd $$i && $(MAKE) $(MFLAGS) all); done
install: all
for i in $(SUBDIRS); \
do (cd $$i && $(MAKE) $(MFLAGS) install); done
uninstall:
for i in $(SUBDIRS); \
do (cd $$i && $(MAKE) $(MFLAGS) uninstall); done
clean cleandir:
for i in $(SUBDIRS); \
do (cd $$i && $(MAKE) $(MFLAGS) clean); done
distclean:
for i in $(SUBDIRS); \
do (cd $$i && $(MAKE) $(MFLAGS) distclean); done
rm -f Makefile *~

View file

@ -0,0 +1,52 @@
# $Id: Makefile.in,v 1.17 1997/05/18 20:00:06 assar Exp $
SHELL = /bin/sh
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
CC = @CC@
AR = ar
RANLIB = @RANLIB@
DEFS = @DEFS@
CFLAGS = @CFLAGS@
INSTALL = @INSTALL@
prefix = @prefix@
SOURCES = base64.c glob.c sockbuf.c buffer.c
OBJECTS = $(libcommon_OBJS)
libcommon_OBJS = base64.o glob.o sockbuf.o buffer.o
LIBNAME = $(LIBPREFIX)common
LIBEXT = a
LIBPREFIX = @LIBPREFIX@
LIB = $(LIBNAME).$(LIBEXT)
all: $(LIB)
.c.o:
$(CC) -c $(CFLAGS) -I$(srcdir) -I../../../include $(DEFS) $<
$(LIB): $(libcommon_OBJS)
rm -f $@
ar cr $@ $(libcommon_OBJS)
-$(RANLIB) $@
install:
uninstall:
TAGS: $(SOURCES)
etags $(SOURCES)
clean cleandir:
rm -f *~ *.o libcommon.a core \#*
distclean:
rm -f Makefile
$(OBJECTS): ../../../include/config.h

View file

@ -0,0 +1,149 @@
/*
* Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Kungliga Tekniska
* Högskolan and its contributors.
*
* 4. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
RCSID("$Id: base64.c,v 1.6 1997/05/30 17:24:06 assar Exp $");
#endif
#include <stdlib.h>
#include <string.h>
#include "base64.h"
static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static int pos(char c)
{
char *p;
for(p = base64; *p; p++)
if(*p == c)
return p - base64;
return -1;
}
int base64_encode(const void *data, int size, char **str)
{
char *s, *p;
int i;
int c;
unsigned char *q;
p = s = (char*)malloc(size*4/3+4);
q = (unsigned char*)data;
i=0;
for(i = 0; i < size;){
c=q[i++];
c*=256;
if(i < size)
c+=q[i];
i++;
c*=256;
if(i < size)
c+=q[i];
i++;
p[0]=base64[(c&0x00fc0000) >> 18];
p[1]=base64[(c&0x0003f000) >> 12];
p[2]=base64[(c&0x00000fc0) >> 6];
p[3]=base64[(c&0x0000003f) >> 0];
if(i > size)
p[3]='=';
if(i > size+1)
p[2]='=';
p+=4;
}
*p=0;
*str = s;
return strlen(s);
}
int base64_decode(const char *str, void *data)
{
const char *p;
unsigned char *q;
int c;
int x;
int done = 0;
q=(unsigned char*)data;
for(p=str; *p && !done; p+=4){
x = pos(p[0]);
if(x >= 0)
c = x;
else{
done = 3;
break;
}
c*=64;
x = pos(p[1]);
if(x >= 0)
c += x;
else
return -1;
c*=64;
if(p[2] == '=')
done++;
else{
x = pos(p[2]);
if(x >= 0)
c += x;
else
return -1;
}
c*=64;
if(p[3] == '=')
done++;
else{
if(done)
return -1;
x = pos(p[3]);
if(x >= 0)
c += x;
else
return -1;
}
if(done < 3)
*q++=(c&0x00ff0000)>>16;
if(done < 2)
*q++=(c&0x0000ff00)>>8;
if(done < 1)
*q++=(c&0x000000ff)>>0;
}
return q - (unsigned char*)data;
}

View file

@ -0,0 +1,47 @@
/*
* Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Kungliga Tekniska
* Högskolan and its contributors.
*
* 4. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*/
/* $Id: base64.h,v 1.5 1997/04/01 08:17:19 joda Exp $ */
#ifndef _BASE64_H_
#define _BASE64_H_
int base64_encode(const void *data, int size, char **str);
int base64_decode(const char *str, void *data);
#endif

View file

@ -0,0 +1,73 @@
/*
* Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Kungliga Tekniska
* Högskolan and its contributors.
*
* 4. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*/
#include "common.h"
#include <stdio.h>
#include "roken.h"
RCSID("$Id: buffer.c,v 1.1 1997/05/18 19:59:24 assar Exp $");
/*
* Allocate a buffer enough to handle st->st_blksize, if
* there is such a field, otherwise BUFSIZ.
*/
void *
alloc_buffer (void *oldbuf, size_t *sz, struct stat *st)
{
size_t new_sz;
new_sz = BUFSIZ;
#ifdef HAVE_ST_BLKSIZE
if (st)
new_sz = max(BUFSIZ, st->st_blksize);
#endif
if(new_sz > *sz) {
if (oldbuf)
free (oldbuf);
oldbuf = malloc (new_sz);
if (oldbuf == NULL) {
warn ("malloc");
*sz = 0;
return NULL;
}
*sz = new_sz;
}
return oldbuf;
}

View file

@ -0,0 +1,62 @@
/*
* Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Kungliga Tekniska
* Högskolan and its contributors.
*
* 4. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*/
/* $Id: common.h,v 1.9 1997/05/18 19:59:58 assar Exp $ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifndef __COMMON_H__
#define __COMMON_H__
#include "base64.h"
void set_buffer_size(int, int);
#include <stdlib.h>
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
void *alloc_buffer (void *oldbuf, size_t *sz, struct stat *st);
#endif /* __COMMON_H__ */

View file

@ -0,0 +1,835 @@
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Guido van Rossum.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*/
/*
* glob(3) -- a superset of the one defined in POSIX 1003.2.
*
* The [!...] convention to negate a range is supported (SysV, Posix, ksh).
*
* Optional extra services, controlled by flags not defined by POSIX:
*
* GLOB_QUOTE:
* Escaping convention: \ inhibits any special meaning the following
* character might have (except \ at end of string is retained).
* GLOB_MAGCHAR:
* Set in gl_flags if pattern contained a globbing character.
* GLOB_NOMAGIC:
* Same as GLOB_NOCHECK, but it will only append pattern if it did
* not contain any magic characters. [Used in csh style globbing]
* GLOB_ALTDIRFUNC:
* Use alternately specified directory access functions.
* GLOB_TILDE:
* expand ~user/foo to the /home/dir/of/user/foo
* GLOB_BRACE:
* expand {1,2}{a,b} to 1a 1b 2a 2b
* gl_matchc:
* Number of matches in the current invocation of glob.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#include <ctype.h>
#ifdef HAVE_DIRENT_H
#include <dirent.h>
#endif
#include <errno.h>
#ifdef HAVE_PWD_H
#include <pwd.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "glob.h"
#include "roken.h"
#define CHAR_DOLLAR '$'
#define CHAR_DOT '.'
#define CHAR_EOS '\0'
#define CHAR_LBRACKET '['
#define CHAR_NOT '!'
#define CHAR_QUESTION '?'
#define CHAR_QUOTE '\\'
#define CHAR_RANGE '-'
#define CHAR_RBRACKET ']'
#define CHAR_SEP '/'
#define CHAR_STAR '*'
#define CHAR_TILDE '~'
#define CHAR_UNDERSCORE '_'
#define CHAR_LBRACE '{'
#define CHAR_RBRACE '}'
#define CHAR_SLASH '/'
#define CHAR_COMMA ','
#ifndef DEBUG
#define M_QUOTE 0x8000
#define M_PROTECT 0x4000
#define M_MASK 0xffff
#define M_ASCII 0x00ff
typedef u_short Char;
#else
#define M_QUOTE 0x80
#define M_PROTECT 0x40
#define M_MASK 0xff
#define M_ASCII 0x7f
typedef char Char;
#endif
#define CHAR(c) ((Char)((c)&M_ASCII))
#define META(c) ((Char)((c)|M_QUOTE))
#define M_ALL META('*')
#define M_END META(']')
#define M_NOT META('!')
#define M_ONE META('?')
#define M_RNG META('-')
#define M_SET META('[')
#define ismeta(c) (((c)&M_QUOTE) != 0)
static int compare (const void *, const void *);
static void g_Ctoc (const Char *, char *);
static int g_lstat (Char *, struct stat *, glob_t *);
static DIR *g_opendir (Char *, glob_t *);
static Char *g_strchr (Char *, int);
#ifdef notdef
static Char *g_strcat (Char *, const Char *);
#endif
static int g_stat (Char *, struct stat *, glob_t *);
static int glob0 (const Char *, glob_t *);
static int glob1 (Char *, glob_t *);
static int glob2 (Char *, Char *, Char *, glob_t *);
static int glob3 (Char *, Char *, Char *, Char *, glob_t *);
static int globextend (const Char *, glob_t *);
static const Char * globtilde (const Char *, Char *, glob_t *);
static int globexp1 (const Char *, glob_t *);
static int globexp2 (const Char *, const Char *, glob_t *, int *);
static int match (Char *, Char *, Char *);
#ifdef DEBUG
static void qprintf (const char *, Char *);
#endif
int
glob(const char *pattern,
int flags,
int (*errfunc)(const char *, int),
glob_t *pglob)
{
const u_char *patnext;
int c;
Char *bufnext, *bufend, patbuf[MaxPathLen+1];
patnext = (u_char *) pattern;
if (!(flags & GLOB_APPEND)) {
pglob->gl_pathc = 0;
pglob->gl_pathv = NULL;
if (!(flags & GLOB_DOOFFS))
pglob->gl_offs = 0;
}
pglob->gl_flags = flags & ~GLOB_MAGCHAR;
pglob->gl_errfunc = errfunc;
pglob->gl_matchc = 0;
bufnext = patbuf;
bufend = bufnext + MaxPathLen;
if (flags & GLOB_QUOTE) {
/* Protect the quoted characters. */
while (bufnext < bufend && (c = *patnext++) != CHAR_EOS)
if (c == CHAR_QUOTE) {
if ((c = *patnext++) == CHAR_EOS) {
c = CHAR_QUOTE;
--patnext;
}
*bufnext++ = c | M_PROTECT;
}
else
*bufnext++ = c;
}
else
while (bufnext < bufend && (c = *patnext++) != CHAR_EOS)
*bufnext++ = c;
*bufnext = CHAR_EOS;
if (flags & GLOB_BRACE)
return globexp1(patbuf, pglob);
else
return glob0(patbuf, pglob);
}
/*
* Expand recursively a glob {} pattern. When there is no more expansion
* invoke the standard globbing routine to glob the rest of the magic
* characters
*/
static int globexp1(const Char *pattern, glob_t *pglob)
{
const Char* ptr = pattern;
int rv;
/* Protect a single {}, for find(1), like csh */
if (pattern[0] == CHAR_LBRACE && pattern[1] == CHAR_RBRACE && pattern[2] == CHAR_EOS)
return glob0(pattern, pglob);
while ((ptr = (const Char *) g_strchr((Char *) ptr, CHAR_LBRACE)) != NULL)
if (!globexp2(ptr, pattern, pglob, &rv))
return rv;
return glob0(pattern, pglob);
}
/*
* Recursive brace globbing helper. Tries to expand a single brace.
* If it succeeds then it invokes globexp1 with the new pattern.
* If it fails then it tries to glob the rest of the pattern and returns.
*/
static int globexp2(const Char *ptr, const Char *pattern,
glob_t *pglob, int *rv)
{
int i;
Char *lm, *ls;
const Char *pe, *pm, *pl;
Char patbuf[MaxPathLen + 1];
/* copy part up to the brace */
for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++)
continue;
ls = lm;
/* Find the balanced brace */
for (i = 0, pe = ++ptr; *pe; pe++)
if (*pe == CHAR_LBRACKET) {
/* Ignore everything between [] */
for (pm = pe++; *pe != CHAR_RBRACKET && *pe != CHAR_EOS; pe++)
continue;
if (*pe == CHAR_EOS) {
/*
* We could not find a matching CHAR_RBRACKET.
* Ignore and just look for CHAR_RBRACE
*/
pe = pm;
}
}
else if (*pe == CHAR_LBRACE)
i++;
else if (*pe == CHAR_RBRACE) {
if (i == 0)
break;
i--;
}
/* Non matching braces; just glob the pattern */
if (i != 0 || *pe == CHAR_EOS) {
*rv = glob0(patbuf, pglob);
return 0;
}
for (i = 0, pl = pm = ptr; pm <= pe; pm++)
switch (*pm) {
case CHAR_LBRACKET:
/* Ignore everything between [] */
for (pl = pm++; *pm != CHAR_RBRACKET && *pm != CHAR_EOS; pm++)
continue;
if (*pm == CHAR_EOS) {
/*
* We could not find a matching CHAR_RBRACKET.
* Ignore and just look for CHAR_RBRACE
*/
pm = pl;
}
break;
case CHAR_LBRACE:
i++;
break;
case CHAR_RBRACE:
if (i) {
i--;
break;
}
/* FALLTHROUGH */
case CHAR_COMMA:
if (i && *pm == CHAR_COMMA)
break;
else {
/* Append the current string */
for (lm = ls; (pl < pm); *lm++ = *pl++)
continue;
/*
* Append the rest of the pattern after the
* closing brace
*/
for (pl = pe + 1; (*lm++ = *pl++) != CHAR_EOS;)
continue;
/* Expand the current pattern */
#ifdef DEBUG
qprintf("globexp2:", patbuf);
#endif
*rv = globexp1(patbuf, pglob);
/* move after the comma, to the next string */
pl = pm + 1;
}
break;
default:
break;
}
*rv = 0;
return 0;
}
/*
* expand tilde from the passwd file.
*/
static const Char *
globtilde(const Char *pattern, Char *patbuf, glob_t *pglob)
{
struct passwd *pwd;
char *h;
const Char *p;
Char *b;
if (*pattern != CHAR_TILDE || !(pglob->gl_flags & GLOB_TILDE))
return pattern;
/* Copy up to the end of the string or / */
for (p = pattern + 1, h = (char *) patbuf; *p && *p != CHAR_SLASH;
*h++ = *p++)
continue;
*h = CHAR_EOS;
if (((char *) patbuf)[0] == CHAR_EOS) {
/*
* handle a plain ~ or ~/ by expanding $HOME
* first and then trying the password file
*/
if ((h = getenv("HOME")) == NULL) {
if ((pwd = k_getpwuid(getuid())) == NULL)
return pattern;
else
h = pwd->pw_dir;
}
}
else {
/*
* Expand a ~user
*/
if ((pwd = k_getpwnam((char*) patbuf)) == NULL)
return pattern;
else
h = pwd->pw_dir;
}
/* Copy the home directory */
for (b = patbuf; *h; *b++ = *h++)
continue;
/* Append the rest of the pattern */
while ((*b++ = *p++) != CHAR_EOS)
continue;
return patbuf;
}
/*
* The main glob() routine: compiles the pattern (optionally processing
* quotes), calls glob1() to do the real pattern matching, and finally
* sorts the list (unless unsorted operation is requested). Returns 0
* if things went well, nonzero if errors occurred. It is not an error
* to find no matches.
*/
static int
glob0(const Char *pattern, glob_t *pglob)
{
const Char *qpatnext;
int c, err, oldpathc;
Char *bufnext, patbuf[MaxPathLen+1];
qpatnext = globtilde(pattern, patbuf, pglob);
oldpathc = pglob->gl_pathc;
bufnext = patbuf;
/* We don't need to check for buffer overflow any more. */
while ((c = *qpatnext++) != CHAR_EOS) {
switch (c) {
case CHAR_LBRACKET:
c = *qpatnext;
if (c == CHAR_NOT)
++qpatnext;
if (*qpatnext == CHAR_EOS ||
g_strchr((Char *) qpatnext+1, CHAR_RBRACKET) == NULL) {
*bufnext++ = CHAR_LBRACKET;
if (c == CHAR_NOT)
--qpatnext;
break;
}
*bufnext++ = M_SET;
if (c == CHAR_NOT)
*bufnext++ = M_NOT;
c = *qpatnext++;
do {
*bufnext++ = CHAR(c);
if (*qpatnext == CHAR_RANGE &&
(c = qpatnext[1]) != CHAR_RBRACKET) {
*bufnext++ = M_RNG;
*bufnext++ = CHAR(c);
qpatnext += 2;
}
} while ((c = *qpatnext++) != CHAR_RBRACKET);
pglob->gl_flags |= GLOB_MAGCHAR;
*bufnext++ = M_END;
break;
case CHAR_QUESTION:
pglob->gl_flags |= GLOB_MAGCHAR;
*bufnext++ = M_ONE;
break;
case CHAR_STAR:
pglob->gl_flags |= GLOB_MAGCHAR;
/* collapse adjacent stars to one,
* to avoid exponential behavior
*/
if (bufnext == patbuf || bufnext[-1] != M_ALL)
*bufnext++ = M_ALL;
break;
default:
*bufnext++ = CHAR(c);
break;
}
}
*bufnext = CHAR_EOS;
#ifdef DEBUG
qprintf("glob0:", patbuf);
#endif
if ((err = glob1(patbuf, pglob)) != 0)
return(err);
/*
* If there was no match we are going to append the pattern
* if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified
* and the pattern did not contain any magic characters
* GLOB_NOMAGIC is there just for compatibility with csh.
*/
if (pglob->gl_pathc == oldpathc &&
((pglob->gl_flags & GLOB_NOCHECK) ||
((pglob->gl_flags & GLOB_NOMAGIC) &&
!(pglob->gl_flags & GLOB_MAGCHAR))))
return(globextend(pattern, pglob));
else if (!(pglob->gl_flags & GLOB_NOSORT))
qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc,
pglob->gl_pathc - oldpathc, sizeof(char *), compare);
return(0);
}
static int
compare(const void *p, const void *q)
{
return(strcmp(*(char **)p, *(char **)q));
}
static int
glob1(Char *pattern, glob_t *pglob)
{
Char pathbuf[MaxPathLen+1];
/* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */
if (*pattern == CHAR_EOS)
return(0);
return(glob2(pathbuf, pathbuf, pattern, pglob));
}
/*
* The functions glob2 and glob3 are mutually recursive; there is one level
* of recursion for each segment in the pattern that contains one or more
* meta characters.
*/
#ifndef S_ISLNK
#if defined(S_IFLNK) && defined(S_IFMT)
#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
#else
#define S_ISLNK(mode) 0
#endif
#endif
static int
glob2(Char *pathbuf, Char *pathend, Char *pattern, glob_t *pglob)
{
struct stat sb;
Char *p, *q;
int anymeta;
/*
* Loop over pattern segments until end of pattern or until
* segment with meta character found.
*/
for (anymeta = 0;;) {
if (*pattern == CHAR_EOS) { /* End of pattern? */
*pathend = CHAR_EOS;
if (g_lstat(pathbuf, &sb, pglob))
return(0);
if (((pglob->gl_flags & GLOB_MARK) &&
pathend[-1] != CHAR_SEP) && (S_ISDIR(sb.st_mode)
|| (S_ISLNK(sb.st_mode) &&
(g_stat(pathbuf, &sb, pglob) == 0) &&
S_ISDIR(sb.st_mode)))) {
*pathend++ = CHAR_SEP;
*pathend = CHAR_EOS;
}
++pglob->gl_matchc;
return(globextend(pathbuf, pglob));
}
/* Find end of next segment, copy tentatively to pathend. */
q = pathend;
p = pattern;
while (*p != CHAR_EOS && *p != CHAR_SEP) {
if (ismeta(*p))
anymeta = 1;
*q++ = *p++;
}
if (!anymeta) { /* No expansion, do next segment. */
pathend = q;
pattern = p;
while (*pattern == CHAR_SEP)
*pathend++ = *pattern++;
} else /* Need expansion, recurse. */
return(glob3(pathbuf, pathend, pattern, p, pglob));
}
/* CHAR_NOTREACHED */
}
static int
glob3(Char *pathbuf, Char *pathend, Char *pattern, Char *restpattern,
glob_t *pglob)
{
struct dirent *dp;
DIR *dirp;
int err;
char buf[MaxPathLen];
/*
* The readdirfunc declaration can't be prototyped, because it is
* assigned, below, to two functions which are prototyped in glob.h
* and dirent.h as taking pointers to differently typed opaque
* structures.
*/
struct dirent *(*readdirfunc)(void *);
*pathend = CHAR_EOS;
errno = 0;
if ((dirp = g_opendir(pathbuf, pglob)) == NULL) {
/* TODO: don't call for ENOENT or ENOTDIR? */
if (pglob->gl_errfunc) {
g_Ctoc(pathbuf, buf);
if (pglob->gl_errfunc(buf, errno) ||
pglob->gl_flags & GLOB_ERR)
return (GLOB_ABEND);
}
return(0);
}
err = 0;
/* Search directory for matching names. */
if (pglob->gl_flags & GLOB_ALTDIRFUNC)
readdirfunc = pglob->gl_readdir;
else
readdirfunc = (struct dirent *(*)(void *))readdir;
while ((dp = (*readdirfunc)(dirp))) {
u_char *sc;
Char *dc;
/* Initial CHAR_DOT must be matched literally. */
if (dp->d_name[0] == CHAR_DOT && *pattern != CHAR_DOT)
continue;
for (sc = (u_char *) dp->d_name, dc = pathend;
(*dc++ = *sc++) != CHAR_EOS;)
continue;
if (!match(pathend, pattern, restpattern)) {
*pathend = CHAR_EOS;
continue;
}
err = glob2(pathbuf, --dc, restpattern, pglob);
if (err)
break;
}
if (pglob->gl_flags & GLOB_ALTDIRFUNC)
(*pglob->gl_closedir)(dirp);
else
closedir(dirp);
return(err);
}
/*
* Extend the gl_pathv member of a glob_t structure to accomodate a new item,
* add the new item, and update gl_pathc.
*
* This assumes the BSD realloc, which only copies the block when its size
* crosses a power-of-two boundary; for v7 realloc, this would cause quadratic
* behavior.
*
* Return 0 if new item added, error code if memory couldn't be allocated.
*
* Invariant of the glob_t structure:
* Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and
* gl_pathv points to (gl_offs + gl_pathc + 1) items.
*/
static int
globextend(const Char *path, glob_t *pglob)
{
char **pathv;
int i;
u_int newsize;
char *copy;
const Char *p;
newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs);
pathv = pglob->gl_pathv ?
realloc(pglob->gl_pathv, newsize) :
malloc(newsize);
if (pathv == NULL)
return(GLOB_NOSPACE);
if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) {
/* first time around -- clear initial gl_offs items */
pathv += pglob->gl_offs;
for (i = pglob->gl_offs; --i >= 0; )
*--pathv = NULL;
}
pglob->gl_pathv = pathv;
for (p = path; *p++;)
continue;
if ((copy = malloc(p - path)) != NULL) {
g_Ctoc(path, copy);
pathv[pglob->gl_offs + pglob->gl_pathc++] = copy;
}
pathv[pglob->gl_offs + pglob->gl_pathc] = NULL;
return(copy == NULL ? GLOB_NOSPACE : 0);
}
/*
* pattern matching function for filenames. Each occurrence of the *
* pattern causes a recursion level.
*/
static int
match(Char *name, Char *pat, Char *patend)
{
int ok, negate_range;
Char c, k;
while (pat < patend) {
c = *pat++;
switch (c & M_MASK) {
case M_ALL:
if (pat == patend)
return(1);
do
if (match(name, pat, patend))
return(1);
while (*name++ != CHAR_EOS);
return(0);
case M_ONE:
if (*name++ == CHAR_EOS)
return(0);
break;
case M_SET:
ok = 0;
if ((k = *name++) == CHAR_EOS)
return(0);
if ((negate_range = ((*pat & M_MASK) == M_NOT)) != CHAR_EOS)
++pat;
while (((c = *pat++) & M_MASK) != M_END)
if ((*pat & M_MASK) == M_RNG) {
if (c <= k && k <= pat[1])
ok = 1;
pat += 2;
} else if (c == k)
ok = 1;
if (ok == negate_range)
return(0);
break;
default:
if (*name++ != c)
return(0);
break;
}
}
return(*name == CHAR_EOS);
}
/* Free allocated data belonging to a glob_t structure. */
void
globfree(glob_t *pglob)
{
int i;
char **pp;
if (pglob->gl_pathv != NULL) {
pp = pglob->gl_pathv + pglob->gl_offs;
for (i = pglob->gl_pathc; i--; ++pp)
if (*pp)
free(*pp);
free(pglob->gl_pathv);
}
}
static DIR *
g_opendir(Char *str, glob_t *pglob)
{
char buf[MaxPathLen];
if (!*str)
strcpy(buf, ".");
else
g_Ctoc(str, buf);
if (pglob->gl_flags & GLOB_ALTDIRFUNC)
return((*pglob->gl_opendir)(buf));
return(opendir(buf));
}
static int
g_lstat(Char *fn, struct stat *sb, glob_t *pglob)
{
char buf[MaxPathLen];
g_Ctoc(fn, buf);
if (pglob->gl_flags & GLOB_ALTDIRFUNC)
return((*pglob->gl_lstat)(buf, sb));
return(lstat(buf, sb));
}
static int
g_stat(Char *fn, struct stat *sb, glob_t *pglob)
{
char buf[MaxPathLen];
g_Ctoc(fn, buf);
if (pglob->gl_flags & GLOB_ALTDIRFUNC)
return((*pglob->gl_stat)(buf, sb));
return(stat(buf, sb));
}
static Char *
g_strchr(Char *str, int ch)
{
do {
if (*str == ch)
return (str);
} while (*str++);
return (NULL);
}
#ifdef notdef
static Char *
g_strcat(Char *dst, const Char *src)
{
Char *sdst = dst;
while (*dst++)
continue;
--dst;
while((*dst++ = *src++) != CHAR_EOS)
continue;
return (sdst);
}
#endif
static void
g_Ctoc(const Char *str, char *buf)
{
char *dc;
for (dc = buf; (*dc++ = *str++) != CHAR_EOS;)
continue;
}
#ifdef DEBUG
static void
qprintf(const Char *str, Char *s)
{
Char *p;
printf("%s:\n", str);
for (p = s; *p; p++)
printf("%c", CHAR(*p));
printf("\n");
for (p = s; *p; p++)
printf("%c", *p & M_PROTECT ? '"' : ' ');
printf("\n");
for (p = s; *p; p++)
printf("%c", ismeta(*p) ? '_' : ' ');
printf("\n");
}
#endif

View file

@ -0,0 +1,84 @@
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Guido van Rossum.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* @(#)glob.h 8.1 (Berkeley) 6/2/93
*/
#ifndef _GLOB_H_
#define _GLOB_H_
struct stat;
typedef struct {
int gl_pathc; /* Count of total paths so far. */
int gl_matchc; /* Count of paths matching pattern. */
int gl_offs; /* Reserved at beginning of gl_pathv. */
int gl_flags; /* Copy of flags parameter to glob. */
char **gl_pathv; /* List of paths matching pattern. */
/* Copy of errfunc parameter to glob. */
int (*gl_errfunc) (const char *, int);
/*
* Alternate filesystem access methods for glob; replacement
* versions of closedir(3), readdir(3), opendir(3), stat(2)
* and lstat(2).
*/
void (*gl_closedir) (void *);
struct dirent *(*gl_readdir) (void *);
void *(*gl_opendir) (const char *);
int (*gl_lstat) (const char *, struct stat *);
int (*gl_stat) (const char *, struct stat *);
} glob_t;
#define GLOB_APPEND 0x0001 /* Append to output from previous call. */
#define GLOB_DOOFFS 0x0002 /* Use gl_offs. */
#define GLOB_ERR 0x0004 /* Return on error. */
#define GLOB_MARK 0x0008 /* Append / to matching directories. */
#define GLOB_NOCHECK 0x0010 /* Return pattern itself if nothing matches. */
#define GLOB_NOSORT 0x0020 /* Don't sort. */
#define GLOB_ALTDIRFUNC 0x0040 /* Use alternately specified directory funcs. */
#define GLOB_BRACE 0x0080 /* Expand braces ala csh. */
#define GLOB_MAGCHAR 0x0100 /* Pattern had globbing characters. */
#define GLOB_NOMAGIC 0x0200 /* GLOB_NOCHECK without magic chars (csh). */
#define GLOB_QUOTE 0x0400 /* Quote special chars with \. */
#define GLOB_TILDE 0x0800 /* Expand tilde names from the passwd file. */
#define GLOB_NOSPACE (-1) /* Malloc call failed. */
#define GLOB_ABEND (-2) /* Unignored error. */
int glob (const char *, int, int (*)(const char *, int), glob_t *);
void globfree (glob_t *);
#endif /* !_GLOB_H_ */

View file

@ -0,0 +1,61 @@
/*
* Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Kungliga Tekniska
* Högskolan and its contributors.
*
* 4. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*/
#include "common.h"
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
RCSID("$Id: sockbuf.c,v 1.2 1997/05/11 10:01:48 assar Exp $");
void
set_buffer_size(int fd, int read)
{
#if defined(SO_RCVBUF) && defined(SO_SNDBUF) && defined(HAVE_SETSOCKOPT)
size_t size = 4194304;
while(size >= 131072 &&
setsockopt(fd, SOL_SOCKET, read ? SO_RCVBUF : SO_SNDBUF,
(void *)&size, sizeof(size)) < 0)
size /= 2;
#endif
}

View file

@ -0,0 +1,76 @@
#
# $Id: Makefile.in,v 1.24 1997/03/23 13:03:55 assar Exp $
#
SHELL = /bin/sh
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
topdir = ../../..
CC = @CC@
RANLIB = @RANLIB@
DEFS = @DEFS@
CFLAGS = @CFLAGS@
CPPFLAGS= @CPPFLAGS@ -I. -I$(srcdir) -I$(topdir) -I$(top_srcdir) -I$(topdir)/include -I$(top_srcdir)/include -I$(srcdir)/../common @INCLUDE_readline@
LD_FLAGS = @LD_FLAGS@
LIB_tgetent = @LIB_tgetent@
LIBS = @LIBS@ @LIB_readline@
MKINSTALLDIRS = $(top_srcdir)/mkinstalldirs
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
libdir = @libdir@
transform=@program_transform_name@
EXECSUFFIX=@EXECSUFFIX@
INCTOP = $(topdir)/include
LIBTOP = $(topdir)/lib
PROGS = ftp$(EXECSUFFIX)
ftp_OBJS = cmds.o cmdtab.o ftp.o krb4.o main.o ruserpass.o domacro.o \
globals.o kauth.o
ftp_SOURCES = cmds.c cmdtab.c ftp.c krb4.c main.c ruserpass.c \
domacro.c globals.c kauth.c
OBJECTS = $(ftp_OBJS)
SOURCES = $(ftp_SOURCES)
all: $(PROGS)
.c.o:
$(CC) -c $(CFLAGS) $(CPPFLAGS) $(DEFS) $<
install: all
$(MKINSTALLDIRS) $(bindir)
for x in $(PROGS); do \
$(INSTALL_PROGRAM) $$x $(bindir)/`echo $$x | sed '$(transform)'`; \
done
uninstall:
for x in $(PROGS); do \
rm -f $(bindir)/`echo $$x | sed '$(transform)'`; \
done
ftp$(EXECSUFFIX): $(ftp_OBJS) # ../common/libcommon.a
$(CC) $(LD_FLAGS) $(LDFLAGS) -o $@ $(ftp_OBJS) -L../common -lcommon -L$(LIBTOP)/krb -lkrb -L$(LIBTOP)/des -ldes -L$(LIBTOP)/roken -lroken $(LIBS) -L$(LIBTOP)/roken -lroken
TAGS: $(SOURCES)
etags $(SOURCES)
clean cleandir:
rm -f *~ *.o core ftp \#*
distclean:
rm -f Makefile
$(OBJECTS): ../../../include/config.h

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,193 @@
/*
* Copyright (c) 1985, 1989, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*/
#include "ftp_locl.h"
/*
* User FTP -- Command Tables.
*/
char accounthelp[] = "send account command to remote server";
char appendhelp[] = "append to a file";
char asciihelp[] = "set ascii transfer type";
char beephelp[] = "beep when command completed";
char binaryhelp[] = "set binary transfer type";
char casehelp[] = "toggle mget upper/lower case id mapping";
char cdhelp[] = "change remote working directory";
char cduphelp[] = "change remote working directory to parent directory";
char chmodhelp[] = "change file permissions of remote file";
char connecthelp[] = "connect to remote tftp";
char crhelp[] = "toggle carriage return stripping on ascii gets";
char deletehelp[] = "delete remote file";
char debughelp[] = "toggle/set debugging mode";
char dirhelp[] = "list contents of remote directory";
char disconhelp[] = "terminate ftp session";
char domachelp[] = "execute macro";
char formhelp[] = "set file transfer format";
char globhelp[] = "toggle metacharacter expansion of local file names";
char hashhelp[] = "toggle printing `#' for each buffer transferred";
char helphelp[] = "print local help information";
char idlehelp[] = "get (set) idle timer on remote side";
char lcdhelp[] = "change local working directory";
char lshelp[] = "list contents of remote directory";
char macdefhelp[] = "define a macro";
char mdeletehelp[] = "delete multiple files";
char mdirhelp[] = "list contents of multiple remote directories";
char mgethelp[] = "get multiple files";
char mkdirhelp[] = "make directory on the remote machine";
char mlshelp[] = "list contents of multiple remote directories";
char modtimehelp[] = "show last modification time of remote file";
char modehelp[] = "set file transfer mode";
char mputhelp[] = "send multiple files";
char newerhelp[] = "get file if remote file is newer than local file ";
char nlisthelp[] = "nlist contents of remote directory";
char nmaphelp[] = "set templates for default file name mapping";
char ntranshelp[] = "set translation table for default file name mapping";
char porthelp[] = "toggle use of PORT cmd for each data connection";
char prompthelp[] = "force interactive prompting on multiple commands";
char proxyhelp[] = "issue command on alternate connection";
char pwdhelp[] = "print working directory on remote machine";
char quithelp[] = "terminate ftp session and exit";
char quotehelp[] = "send arbitrary ftp command";
char receivehelp[] = "receive file";
char regethelp[] = "get file restarting at end of local file";
char remotehelp[] = "get help from remote server";
char renamehelp[] = "rename file";
char restarthelp[]= "restart file transfer at bytecount";
char rmdirhelp[] = "remove directory on the remote machine";
char rmtstatushelp[]="show status of remote machine";
char runiquehelp[] = "toggle store unique for local files";
char resethelp[] = "clear queued command replies";
char sendhelp[] = "send one file";
char passivehelp[] = "enter passive transfer mode";
char sitehelp[] = "send site specific command to remote server\n\t\tTry \"rhelp site\" or \"site help\" for more information";
char shellhelp[] = "escape to the shell";
char sizecmdhelp[] = "show size of remote file";
char statushelp[] = "show current status";
char structhelp[] = "set file transfer structure";
char suniquehelp[] = "toggle store unique on remote machine";
char systemhelp[] = "show remote system type";
char tenexhelp[] = "set tenex file transfer type";
char tracehelp[] = "toggle packet tracing";
char typehelp[] = "set file transfer type";
char umaskhelp[] = "get (set) umask on remote side";
char userhelp[] = "send new user information";
char verbosehelp[] = "toggle verbose mode";
char prothelp[] = "set protection level";
char kauthhelp[] = "get remote tokens";
char klisthelp[] = "show remote tickets";
char aklog[] = "obtain remote AFS tokens";
struct cmd cmdtab[] = {
{ "!", shellhelp, 0, 0, 0, shell },
{ "$", domachelp, 1, 0, 0, domacro },
{ "account", accounthelp, 0, 1, 1, account},
{ "append", appendhelp, 1, 1, 1, put },
{ "ascii", asciihelp, 0, 1, 1, setascii },
{ "bell", beephelp, 0, 0, 0, setbell },
{ "binary", binaryhelp, 0, 1, 1, setbinary },
{ "bye", quithelp, 0, 0, 0, quit },
{ "case", casehelp, 0, 0, 1, setcase },
{ "cd", cdhelp, 0, 1, 1, cd },
{ "cdup", cduphelp, 0, 1, 1, cdup },
{ "chmod", chmodhelp, 0, 1, 1, do_chmod },
{ "close", disconhelp, 0, 1, 1, disconnect },
{ "cr", crhelp, 0, 0, 0, setcr },
{ "delete", deletehelp, 0, 1, 1, delete },
{ "debug", debughelp, 0, 0, 0, setdebug },
{ "dir", dirhelp, 1, 1, 1, ls },
{ "disconnect", disconhelp, 0, 1, 1, disconnect },
{ "form", formhelp, 0, 1, 1, setform },
{ "get", receivehelp, 1, 1, 1, get },
{ "glob", globhelp, 0, 0, 0, setglob },
{ "hash", hashhelp, 0, 0, 0, sethash },
{ "help", helphelp, 0, 0, 1, help },
{ "idle", idlehelp, 0, 1, 1, ftp_idle },
{ "image", binaryhelp, 0, 1, 1, setbinary },
{ "lcd", lcdhelp, 0, 0, 0, lcd },
{ "ls", lshelp, 1, 1, 1, ls },
{ "macdef", macdefhelp, 0, 0, 0, macdef },
{ "mdelete", mdeletehelp, 1, 1, 1, mdelete },
{ "mdir", mdirhelp, 1, 1, 1, mls },
{ "mget", mgethelp, 1, 1, 1, mget },
{ "mkdir", mkdirhelp, 0, 1, 1, makedir },
{ "mls", mlshelp, 1, 1, 1, mls },
{ "mode", modehelp, 0, 1, 1, setftmode },
{ "modtime", modtimehelp, 0, 1, 1, modtime },
{ "mput", mputhelp, 1, 1, 1, mput },
{ "newer", newerhelp, 1, 1, 1, newer },
{ "nmap", nmaphelp, 0, 0, 1, setnmap },
{ "nlist", nlisthelp, 1, 1, 1, ls },
{ "ntrans", ntranshelp, 0, 0, 1, setntrans },
{ "open", connecthelp, 0, 0, 1, setpeer },
{ "passive", passivehelp, 0, 0, 0, setpassive },
{ "prompt", prompthelp, 0, 0, 0, setprompt },
{ "proxy", proxyhelp, 0, 0, 1, doproxy },
{ "sendport", porthelp, 0, 0, 0, setport },
{ "put", sendhelp, 1, 1, 1, put },
{ "pwd", pwdhelp, 0, 1, 1, pwd },
{ "quit", quithelp, 0, 0, 0, quit },
{ "quote", quotehelp, 1, 1, 1, quote },
{ "recv", receivehelp, 1, 1, 1, get },
{ "reget", regethelp, 1, 1, 1, reget },
{ "rstatus", rmtstatushelp, 0, 1, 1, rmtstatus },
{ "rhelp", remotehelp, 0, 1, 1, rmthelp },
{ "rename", renamehelp, 0, 1, 1, renamefile },
{ "reset", resethelp, 0, 1, 1, reset },
{ "restart", restarthelp, 1, 1, 1, restart },
{ "rmdir", rmdirhelp, 0, 1, 1, removedir },
{ "runique", runiquehelp, 0, 0, 1, setrunique },
{ "send", sendhelp, 1, 1, 1, put },
{ "site", sitehelp, 0, 1, 1, site },
{ "size", sizecmdhelp, 1, 1, 1, sizecmd },
{ "status", statushelp, 0, 0, 1, status },
{ "struct", structhelp, 0, 1, 1, setstruct },
{ "system", systemhelp, 0, 1, 1, syst },
{ "sunique", suniquehelp, 0, 0, 1, setsunique },
{ "tenex", tenexhelp, 0, 1, 1, settenex },
{ "trace", tracehelp, 0, 0, 0, settrace },
{ "type", typehelp, 0, 1, 1, settype },
{ "user", userhelp, 0, 1, 1, user },
{ "umask", umaskhelp, 0, 1, 1, do_umask },
{ "verbose", verbosehelp, 0, 0, 0, setverbose },
{ "?", helphelp, 0, 0, 1, help },
{ "prot", prothelp, 0, 1, 0, sec_prot },
{ "kauth", kauthhelp, 0, 1, 0, kauth },
{ "klist", klisthelp, 0, 1, 0, klist },
{ 0 },
};
int NCMDS = (sizeof (cmdtab) / sizeof (cmdtab[0])) - 1;

View file

@ -0,0 +1,138 @@
/*
* Copyright (c) 1985, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*/
#include "ftp_locl.h"
RCSID("$Id: domacro.c,v 1.5 1996/11/17 20:23:10 assar Exp $");
void
domacro(int argc, char **argv)
{
int i, j, count = 2, loopflg = 0;
char *cp1, *cp2, line2[200];
struct cmd *c;
if (argc < 2 && !another(&argc, &argv, "macro name")) {
printf("Usage: %s macro_name.\n", argv[0]);
code = -1;
return;
}
for (i = 0; i < macnum; ++i) {
if (!strncmp(argv[1], macros[i].mac_name, 9)) {
break;
}
}
if (i == macnum) {
printf("'%s' macro not found.\n", argv[1]);
code = -1;
return;
}
strcpy(line2, line);
TOP:
cp1 = macros[i].mac_start;
while (cp1 != macros[i].mac_end) {
while (isspace(*cp1)) {
cp1++;
}
cp2 = line;
while (*cp1 != '\0') {
switch(*cp1) {
case '\\':
*cp2++ = *++cp1;
break;
case '$':
if (isdigit(*(cp1+1))) {
j = 0;
while (isdigit(*++cp1)) {
j = 10*j + *cp1 - '0';
}
cp1--;
if (argc - 2 >= j) {
strcpy(cp2, argv[j+1]);
cp2 += strlen(argv[j+1]);
}
break;
}
if (*(cp1+1) == 'i') {
loopflg = 1;
cp1++;
if (count < argc) {
strcpy(cp2, argv[count]);
cp2 += strlen(argv[count]);
}
break;
}
/* intentional drop through */
default:
*cp2++ = *cp1;
break;
}
if (*cp1 != '\0') {
cp1++;
}
}
*cp2 = '\0';
makeargv();
c = getcmd(margv[0]);
if (c == (struct cmd *)-1) {
printf("?Ambiguous command\n");
code = -1;
}
else if (c == 0) {
printf("?Invalid command\n");
code = -1;
}
else if (c->c_conn && !connected) {
printf("Not connected.\n");
code = -1;
}
else {
if (verbose) {
printf("%s\n",line);
}
(*c->c_handler)(margc, margv);
if (bell && c->c_bell) {
putchar('\007');
}
strcpy(line, line2);
makeargv();
argc = margc;
argv = margv;
}
if (cp1 != macros[i].mac_end) {
cp1++;
}
}
if (loopflg && ++count < argc) {
goto TOP;
}
}

View file

@ -0,0 +1,167 @@
/*-
* Copyright (c) 1994 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* @(#)extern.h 8.3 (Berkeley) 10/9/94
*/
/* $Id: extern.h,v 1.13 1997/04/20 05:46:48 assar Exp $ */
#include <setjmp.h>
#include <stdlib.h>
#ifdef TIME_WITH_SYS_TIME
#include <sys/time.h>
#include <time.h>
#elif defined(HAVE_SYS_TIME_H)
#include <sys/time.h>
#else
#include <time.h>
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
void abort_remote (FILE *);
void abortpt (int);
void abortrecv (int);
void account (int, char **);
int another (int *, char ***, char *);
void blkfree (char **);
void cd (int, char **);
void cdup (int, char **);
void changetype (int, int);
void cmdabort (int);
void cmdscanner (int);
int command (char *fmt, ...);
int confirm (char *, char *);
FILE *dataconn (char *);
void delete (int, char **);
void disconnect (int, char **);
void do_chmod (int, char **);
void do_umask (int, char **);
void domacro (int, char **);
char *domap (char *);
void doproxy (int, char **);
char *dotrans (char *);
int empty (fd_set *, int);
void fatal (char *);
void get (int, char **);
struct cmd *getcmd (char *);
int getit (int, char **, int, char *);
int getreply (int);
int globulize (char **);
char *gunique (char *);
void help (int, char **);
char *hookup (char *, int);
void ftp_idle (int, char **);
int initconn (void);
void intr (int);
void lcd (int, char **);
int login (char *);
RETSIGTYPE lostpeer (int);
void ls (int, char **);
void macdef (int, char **);
void makeargv (void);
void makedir (int, char **);
void mdelete (int, char **);
void mget (int, char **);
void mls (int, char **);
void modtime (int, char **);
void mput (int, char **);
char *onoff (int);
void newer (int, char **);
void proxtrans (char *, char *, char *);
void psabort (int);
void pswitch (int);
void ptransfer (char *, long, struct timeval *, struct timeval *);
void put (int, char **);
void pwd (int, char **);
void quit (int, char **);
void quote (int, char **);
void quote1 (char *, int, char **);
void recvrequest (char *, char *, char *, char *, int);
void reget (int, char **);
char *remglob (char **, int);
void removedir (int, char **);
void renamefile (int, char **);
void reset (int, char **);
void restart (int, char **);
void rmthelp (int, char **);
void rmtstatus (int, char **);
int ruserpass (char *, char **, char **, char **);
void sendrequest (char *, char *, char *, int);
void setascii (int, char **);
void setbell (int, char **);
void setbinary (int, char **);
void setcase (int, char **);
void setcr (int, char **);
void setdebug (int, char **);
void setform (int, char **);
void setftmode (int, char **);
void setglob (int, char **);
void sethash (int, char **);
void setnmap (int, char **);
void setntrans (int, char **);
void setpassive (int, char **);
void setpeer (int, char **);
void setport (int, char **);
void setprompt (int, char **);
void setrunique (int, char **);
void setstruct (int, char **);
void setsunique (int, char **);
void settenex (int, char **);
void settrace (int, char **);
void settype (int, char **);
void setverbose (int, char **);
void shell (int, char **);
void site (int, char **);
void sizecmd (int, char **);
char *slurpstring (void);
void status (int, char **);
void syst (int, char **);
void tvsub (struct timeval *, struct timeval *, struct timeval *);
void user (int, char **);
extern jmp_buf abortprox;
extern int abrtflag;
extern struct cmd cmdtab[];
extern FILE *cout;
extern int data;
extern char *home;
extern jmp_buf jabort;
extern int proxy;
extern char reply_string[];
extern off_t restart_point;
extern int NCMDS;
extern char username[32];
extern char myhostname[];
extern char *mydomain;

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,145 @@
/*
* Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Kungliga Tekniska
* Högskolan and its contributors.
*
* 4. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*/
/* $Id: ftp_locl.h,v 1.29 1997/05/20 18:40:28 bg Exp $ */
#ifndef __FTP_LOCL_H__
#define __FTP_LOCL_H__
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <sys/cdefs.h>
#ifdef HAVE_PWD_H
#include <pwd.h>
#endif
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#ifdef TIME_WITH_SYS_TIME
#include <sys/time.h>
#include <time.h>
#elif defined(HAVE_SYS_TIME_H)
#include <sys/time.h>
#else
#include <time.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
#endif
#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_NETINET_IN_SYSTM_H
#include <netinet/in_systm.h>
#endif
#ifdef HAVE_NETINET_IP_H
#include <netinet/ip.h>
#endif
#ifdef HAVE_ARPA_FTP_H
#include <arpa/ftp.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef HAVE_ARPA_TELNET_H
#include <arpa/telnet.h>
#endif
#include <errno.h>
#include <ctype.h>
#include <glob.h>
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
#include <err.h>
#ifdef SOCKS
#include <socks.h>
extern int LIBPREFIX(fclose) __P((FILE *));
#endif
#include "ftp_var.h"
#include "extern.h"
#include "common.h"
#include "pathnames.h"
#include <des.h>
#include <krb.h>
#include "krb4.h"
#include "roken.h"
#if defined(__sun__) && !defined(__svr4)
int fclose(FILE*);
int pclose(FILE*);
#endif
#endif /* __FTP_LOCL_H__ */

View file

@ -0,0 +1,127 @@
/*
* Copyright (c) 1985, 1989, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* @(#)ftp_var.h 8.4 (Berkeley) 10/9/94
*/
/*
* FTP global variables.
*/
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#include <setjmp.h>
/*
* Options and other state info.
*/
extern int trace; /* trace packets exchanged */
extern int hash; /* print # for each buffer transferred */
extern int sendport; /* use PORT cmd for each data connection */
extern int verbose; /* print messages coming back from server */
extern int connected; /* connected to server */
extern int fromatty; /* input is from a terminal */
extern int interactive; /* interactively prompt on m* cmds */
extern int debug; /* debugging level */
extern int bell; /* ring bell on cmd completion */
extern int doglob; /* glob local file names */
extern int autologin; /* establish user account on connection */
extern int proxy; /* proxy server connection active */
extern int proxflag; /* proxy connection exists */
extern int sunique; /* store files on server with unique name */
extern int runique; /* store local files with unique name */
extern int mcase; /* map upper to lower case for mget names */
extern int ntflag; /* use ntin ntout tables for name translation */
extern int mapflag; /* use mapin mapout templates on file names */
extern int code; /* return/reply code for ftp command */
extern int crflag; /* if 1, strip car. rets. on ascii gets */
extern char pasv[64]; /* passive port for proxy data connection */
extern int passivemode; /* passive mode enabled */
extern char *altarg; /* argv[1] with no shell-like preprocessing */
extern char ntin[17]; /* input translation table */
extern char ntout[17]; /* output translation table */
extern char mapin[MaxPathLen]; /* input map template */
extern char mapout[MaxPathLen]; /* output map template */
extern char typename[32]; /* name of file transfer type */
extern int type; /* requested file transfer type */
extern int curtype; /* current file transfer type */
extern char structname[32]; /* name of file transfer structure */
extern int stru; /* file transfer structure */
extern char formname[32]; /* name of file transfer format */
extern int form; /* file transfer format */
extern char modename[32]; /* name of file transfer mode */
extern int mode; /* file transfer mode */
extern char bytename[32]; /* local byte size in ascii */
extern int bytesize; /* local byte size in binary */
extern char *hostname; /* name of host connected to */
extern int unix_server; /* server is unix, can use binary for ascii */
extern int unix_proxy; /* proxy is unix, can use binary for ascii */
extern jmp_buf toplevel; /* non-local goto stuff for cmd scanner */
extern char line[200]; /* input line buffer */
extern char *stringbase; /* current scan point in line buffer */
extern char argbuf[200]; /* argument storage buffer */
extern char *argbase; /* current storage point in arg buffer */
extern int margc; /* count of arguments on input line */
extern char **margv; /* args parsed from input line */
extern int margvlen; /* how large margv is currently */
extern int cpend; /* flag: if != 0, then pending server reply */
extern int mflag; /* flag: if != 0, then active multi command */
extern int options; /* used during socket creation */
/*
* Format of command table.
*/
struct cmd {
char *c_name; /* name of command */
char *c_help; /* help string */
char c_bell; /* give bell when command completes */
char c_conn; /* must be connected to use command */
char c_proxy; /* proxy server may execute */
void (*c_handler) (int, char **); /* function to call */
};
struct macel {
char mac_name[9]; /* macro name */
char *mac_start; /* start of macro in macbuf */
char *mac_end; /* end of macro in macbuf */
};
extern int macnum; /* number of defined macros */
extern struct macel macros[16];
extern char macbuf[4096];

View file

@ -0,0 +1,76 @@
#include "ftp_locl.h"
RCSID("$Id: globals.c,v 1.6 1996/08/26 22:46:26 assar Exp $");
/*
* Options and other state info.
*/
int trace; /* trace packets exchanged */
int hash; /* print # for each buffer transferred */
int sendport; /* use PORT cmd for each data connection */
int verbose; /* print messages coming back from server */
int connected; /* connected to server */
int fromatty; /* input is from a terminal */
int interactive; /* interactively prompt on m* cmds */
int debug; /* debugging level */
int bell; /* ring bell on cmd completion */
int doglob; /* glob local file names */
int autologin; /* establish user account on connection */
int proxy; /* proxy server connection active */
int proxflag; /* proxy connection exists */
int sunique; /* store files on server with unique name */
int runique; /* store local files with unique name */
int mcase; /* map upper to lower case for mget names */
int ntflag; /* use ntin ntout tables for name translation */
int mapflag; /* use mapin mapout templates on file names */
int code; /* return/reply code for ftp command */
int crflag; /* if 1, strip car. rets. on ascii gets */
char pasv[64]; /* passive port for proxy data connection */
int passivemode; /* passive mode enabled */
char *altarg; /* argv[1] with no shell-like preprocessing */
char ntin[17]; /* input translation table */
char ntout[17]; /* output translation table */
char mapin[MaxPathLen]; /* input map template */
char mapout[MaxPathLen]; /* output map template */
char typename[32]; /* name of file transfer type */
int type; /* requested file transfer type */
int curtype; /* current file transfer type */
char structname[32]; /* name of file transfer structure */
int stru; /* file transfer structure */
char formname[32]; /* name of file transfer format */
int form; /* file transfer format */
char modename[32]; /* name of file transfer mode */
int mode; /* file transfer mode */
char bytename[32]; /* local byte size in ascii */
int bytesize; /* local byte size in binary */
char *hostname; /* name of host connected to */
int unix_server; /* server is unix, can use binary for ascii */
int unix_proxy; /* proxy is unix, can use binary for ascii */
jmp_buf toplevel; /* non-local goto stuff for cmd scanner */
char line[200]; /* input line buffer */
char *stringbase; /* current scan point in line buffer */
char argbuf[200]; /* argument storage buffer */
char *argbase; /* current storage point in arg buffer */
int margc; /* count of arguments on input line */
char **margv; /* args parsed from input line */
int margvlen; /* how large margv is currently */
int cpend; /* flag: if != 0, then pending server reply */
int mflag; /* flag: if != 0, then active multi command */
int options; /* used during socket creation */
/*
* Format of command table.
*/
int macnum; /* number of defined macros */
struct macel macros[16];
char macbuf[4096];
char username[32];
/* these are set in ruserpass */
char myhostname[MaxHostNameLen];
char *mydomain;

View file

@ -0,0 +1,145 @@
/*
* Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Kungliga Tekniska
* Högskolan and its contributors.
*
* 4. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*/
#include "ftp_locl.h"
RCSID("$Id: kauth.c,v 1.14 1997/05/11 04:08:04 assar Exp $");
void kauth(int argc, char **argv)
{
int ret;
char buf[1024];
des_cblock key;
des_key_schedule schedule;
KTEXT_ST tkt, tktcopy;
char *name;
char *p;
int overbose;
char passwd[100];
int tmp;
if(argc > 2){
printf("usage: %s [principal]\n", argv[0]);
code = -1;
return;
}
if(argc == 2)
name = argv[1];
else
name = username;
overbose = verbose;
verbose = 0;
ret = command("SITE KAUTH %s", name);
if(ret != CONTINUE){
verbose = overbose;
code = -1;
return;
}
verbose = overbose;
p = strstr(reply_string, "T=");
if(!p){
printf("Bad reply from server.\n");
code = -1;
return;
}
p += 2;
tmp = base64_decode(p, &tkt.dat);
if(tmp < 0){
printf("Failed to decode base64 in reply.\n");
code = -1;
return;
}
tkt.length = tmp;
tktcopy.length = tkt.length;
p = strstr(reply_string, "P=");
if(!p){
printf("Bad reply from server.\n");
verbose = overbose;
code = -1;
return;
}
name = p + 2;
for(; *p && *p != ' ' && *p != '\r' && *p != '\n'; p++);
*p = 0;
snprintf(buf, sizeof(buf), "Password for %s:", name);
if (des_read_pw_string (passwd, sizeof(passwd)-1, buf, 0))
*passwd = '\0';
des_string_to_key (passwd, &key);
des_key_sched(&key, schedule);
des_pcbc_encrypt((des_cblock*)tkt.dat, (des_cblock*)tktcopy.dat,
tkt.length,
schedule, &key, DES_DECRYPT);
if (strcmp ((char*)tktcopy.dat + 8,
KRB_TICKET_GRANTING_TICKET) != 0) {
afs_string_to_key (passwd, krb_realmofhost(hostname), &key);
des_key_sched (&key, schedule);
des_pcbc_encrypt((des_cblock*)tkt.dat, (des_cblock*)tktcopy.dat,
tkt.length,
schedule, &key, DES_DECRYPT);
}
memset(key, 0, sizeof(key));
memset(schedule, 0, sizeof(schedule));
memset(passwd, 0, sizeof(passwd));
base64_encode(tktcopy.dat, tktcopy.length, &p);
memset (tktcopy.dat, 0, tktcopy.length);
ret = command("SITE KAUTH %s %s", name, p);
free(p);
if(ret != COMPLETE){
code = -1;
return;
}
code = 0;
}
void klist(int argc, char **argv)
{
int ret;
if(argc != 1){
printf("usage: %s\n", argv[0]);
code = -1;
return;
}
ret = command("SITE KLIST");
code = (ret == COMPLETE);
}

View file

@ -0,0 +1,567 @@
/*
* Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Kungliga Tekniska
* Högskolan and its contributors.
*
* 4. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*/
#include "ftp_locl.h"
RCSID("$Id: krb4.c,v 1.18 1997/05/11 04:08:05 assar Exp $");
static KTEXT_ST krb4_adat;
static des_cblock key;
static des_key_schedule schedule;
static char *data_buffer;
extern struct sockaddr_in hisctladdr, myctladdr;
int auth_complete;
static int command_prot;
static int auth_pbsz;
static int data_prot;
static int request_data_prot;
static struct {
int level;
char *name;
} level_names[] = {
{ prot_clear, "clear" },
{ prot_safe, "safe" },
{ prot_confidential, "confidential" },
{ prot_private, "private" }
};
static char *level_to_name(int level)
{
int i;
for(i = 0; i < sizeof(level_names) / sizeof(level_names[0]); i++)
if(level_names[i].level == level)
return level_names[i].name;
return "unknown";
}
static int name_to_level(char *name)
{
int i;
for(i = 0; i < sizeof(level_names) / sizeof(level_names[0]); i++)
if(!strncasecmp(level_names[i].name, name, strlen(name)))
return level_names[i].level;
return -1;
}
void sec_status(void)
{
if(auth_complete){
printf("Using KERBEROS_V4 for authentication.\n");
command_prot = prot_private; /* this variable is not used */
printf("Using %s command channel.\n",
level_to_name(command_prot));
printf("Using %s data channel.\n",
level_to_name(data_prot));
if(auth_pbsz > 0)
printf("Protection buffer size: %d.\n", auth_pbsz);
}else{
printf("Not using any security mechanism.\n");
}
}
static int
sec_prot_internal(int level)
{
int ret;
char *p;
int s = 1048576;
int old_verbose = verbose;
verbose = 0;
if(!auth_complete){
printf("No security data exchange has taken place.\n");
return -1;
}
if(level){
ret = command("PBSZ %d", s);
if(ret != COMPLETE){
printf("Failed to set protection buffer size.\n");
return -1;
}
auth_pbsz = s;
p = strstr(reply_string, "PBSZ=");
if(p)
sscanf(p, "PBSZ=%d", &s);
if(s < auth_pbsz)
auth_pbsz = s;
if(data_buffer)
free(data_buffer);
data_buffer = malloc(auth_pbsz);
}
verbose = old_verbose;
ret = command("PROT %c", level["CSEP"]); /* XXX :-) */
if(ret != COMPLETE){
printf("Failed to set protection level.\n");
return -1;
}
data_prot = level;
return 0;
}
void
sec_prot(int argc, char **argv)
{
int level = -1;
if(argc != 2){
printf("usage: %s (clear | safe | confidential | private)\n",
argv[0]);
code = -1;
return;
}
if(!auth_complete){
printf("No security data exchange has taken place.\n");
code = -1;
return;
}
level = name_to_level(argv[1]);
if(level == -1){
printf("usage: %s (clear | safe | confidential | private)\n",
argv[0]);
code = -1;
return;
}
if(level == prot_confidential){
printf("Confidential protection is not defined with Kerberos.\n");
code = -1;
return;
}
if(sec_prot_internal(level) < 0){
code = -1;
return;
}
code = 0;
}
void
sec_set_protection_level(void)
{
if(auth_complete && data_prot != request_data_prot)
sec_prot_internal(request_data_prot);
}
int
sec_request_prot(char *level)
{
int l = name_to_level(level);
if(l == -1)
return -1;
request_data_prot = l;
return 0;
}
int sec_getc(FILE *F)
{
if(auth_complete && data_prot)
return krb4_getc(F);
else
return getc(F);
}
int sec_read(int fd, void *data, int length)
{
if(auth_complete && data_prot)
return krb4_read(fd, data, length);
else
return read(fd, data, length);
}
static int
krb4_recv(int fd)
{
int len;
MSG_DAT m;
int kerror;
krb_net_read(fd, &len, sizeof(len));
len = ntohl(len);
krb_net_read(fd, data_buffer, len);
if(data_prot == prot_safe)
kerror = krb_rd_safe(data_buffer, len, &key,
&hisctladdr, &myctladdr, &m);
else
kerror = krb_rd_priv(data_buffer, len, schedule, &key,
&hisctladdr, &myctladdr, &m);
if(kerror){
return -1;
}
memmove(data_buffer, m.app_data, m.app_length);
return m.app_length;
}
int krb4_getc(FILE *F)
{
static int bytes;
static int index;
if(bytes == 0){
bytes = krb4_recv(fileno(F));
index = 0;
}
if(bytes){
bytes--;
return (unsigned char)data_buffer[index++];
}
return EOF;
}
int krb4_read(int fd, char *data, int length)
{
static int left;
static int index;
static int eof;
int len = left;
int rx = 0;
if(eof){
eof = 0;
return 0;
}
if(left){
if(length < len)
len = length;
memmove(data, data_buffer + index, len);
length -= len;
index += len;
rx += len;
left -= len;
}
while(length){
len = krb4_recv(fd);
if(len == 0){
if(rx)
eof = 1;
return rx;
}
if(len > length){
left = len - length;
len = index = length;
}
memmove(data, data_buffer, len);
length -= len;
data += len;
rx += len;
}
return rx;
}
static int
krb4_encode(char *from, char *to, int length)
{
if(data_prot == prot_safe)
return krb_mk_safe(from, to, length, &key,
&myctladdr, &hisctladdr);
else
return krb_mk_priv(from, to, length, schedule, &key,
&myctladdr, &hisctladdr);
}
static int
krb4_overhead(int len)
{
if(data_prot == prot_safe)
return 31;
else
return 26;
}
static char p_buf[1024];
static int p_index;
int
sec_putc(int c, FILE *F)
{
if(data_prot){
if((c == '\n' && p_index) || p_index == sizeof(p_buf)){
sec_write(fileno(F), p_buf, p_index);
p_index = 0;
}
p_buf[p_index++] = c;
return c;
}
return putc(c, F);
}
static int
sec_send(int fd, char *from, int length)
{
int bytes;
bytes = krb4_encode(from, data_buffer, length);
bytes = htonl(bytes);
krb_net_write(fd, &bytes, sizeof(bytes));
krb_net_write(fd, data_buffer, ntohl(bytes));
return length;
}
int
sec_fflush(FILE *F)
{
if(data_prot){
if(p_index){
sec_write(fileno(F), p_buf, p_index);
p_index = 0;
}
sec_send(fileno(F), NULL, 0);
}
fflush(F);
return 0;
}
int
sec_write(int fd, char *data, int length)
{
int len = auth_pbsz;
int tx = 0;
if(data_prot == prot_clear)
return write(fd, data, length);
len -= krb4_overhead(len);
while(length){
if(length < len)
len = length;
sec_send(fd, data, len);
length -= len;
data += len;
tx += len;
}
return tx;
}
static int
do_auth(char *service, char *host, int checksum)
{
int ret;
CREDENTIALS cred;
char sname[SNAME_SZ], inst[INST_SZ], realm[REALM_SZ];
strcpy(sname, service);
strcpy(inst, krb_get_phost(host));
strcpy(realm, krb_realmofhost(host));
ret = krb_mk_req(&krb4_adat, sname, inst, realm, checksum);
if(ret)
return ret;
strcpy(sname, service);
strcpy(inst, krb_get_phost(host));
strcpy(realm, krb_realmofhost(host));
ret = krb_get_cred(sname, inst, realm, &cred);
memmove(&key, &cred.session, sizeof(des_cblock));
des_key_sched(&key, schedule);
memset(&cred, 0, sizeof(cred));
return ret;
}
int
do_klogin(char *host)
{
int ret;
char *p;
int len;
char adat[1024];
MSG_DAT msg_data;
int checksum;
int old_verbose = verbose;
verbose = 0;
printf("Trying KERBEROS_V4...\n");
ret = command("AUTH KERBEROS_V4");
if(ret != CONTINUE){
if(code == 504){
printf("Kerberos 4 is not supported by the server.\n");
}else if(code == 534){
printf("KERBEROS_V4 rejected as security mechanism.\n");
}else if(ret == ERROR)
printf("The server doesn't understand the FTP "
"security extensions.\n");
verbose = old_verbose;
return -1;
}
checksum = getpid();
ret = do_auth("ftp", host, checksum);
if(ret == KDC_PR_UNKNOWN)
ret = do_auth("rcmd", host, checksum);
if(ret){
printf("%s\n", krb_get_err_text(ret));
verbose = old_verbose;
return ret;
}
base64_encode(krb4_adat.dat, krb4_adat.length, &p);
ret = command("ADAT %s", p);
free(p);
if(ret != COMPLETE){
printf("Server didn't accept auth data.\n");
verbose = old_verbose;
return -1;
}
p = strstr(reply_string, "ADAT=");
if(!p){
printf("Remote host didn't send adat reply.\n");
verbose = old_verbose;
return -1;
}
p+=5;
len = base64_decode(p, adat);
if(len < 0){
printf("Failed to decode base64 from server.\n");
verbose = old_verbose;
return -1;
}
ret = krb_rd_safe(adat, len, &key,
&hisctladdr, &myctladdr, &msg_data);
if(ret){
printf("Error reading reply from server: %s.\n",
krb_get_err_text(ret));
verbose = old_verbose;
return -1;
}
{
/* the draft doesn't tell what size the return has */
int i;
u_int32_t cs = 0;
for(i = 0; i < msg_data.app_length; i++)
cs = (cs<<8) + msg_data.app_data[i];
if(cs - checksum != 1){
printf("Bad checksum returned from server.\n");
verbose = old_verbose;
return -1;
}
}
auth_complete = 1;
verbose = old_verbose;
return 0;
}
void
krb4_quit(void)
{
auth_complete = 0;
}
int krb4_write_enc(FILE *F, char *fmt, va_list ap)
{
int len;
char *p;
char buf[1024];
char enc[1024];
vsnprintf(buf, sizeof(buf), fmt, ap);
len = krb_mk_priv(buf, enc, strlen(buf), schedule, &key,
&myctladdr, &hisctladdr);
base64_encode(enc, len, &p);
fprintf(F, "ENC %s", p);
free (p);
return 0;
}
int krb4_read_msg(char *s, int priv)
{
int len;
int ret;
char buf[1024];
MSG_DAT m;
int code;
len = base64_decode(s + 4, buf);
if(priv)
ret = krb_rd_priv(buf, len, schedule, &key,
&hisctladdr, &myctladdr, &m);
else
ret = krb_rd_safe(buf, len, &key, &hisctladdr, &myctladdr, &m);
if(ret){
printf("%s\n", krb_get_err_text(ret));
return -1;
}
m.app_data[m.app_length] = 0;
if(m.app_data[3] == '-')
code = 0;
else
sscanf((char*)m.app_data, "%d", &code);
strncpy(s, (char*)m.app_data, strlen((char*)m.app_data));
s[m.app_length] = 0;
len = strlen(s);
if(s[len-1] == '\n')
s[len-1] = 0;
return code;
}
int
krb4_read_mic(char *s)
{
return krb4_read_msg(s, 0);
}
int
krb4_read_enc(char *s)
{
return krb4_read_msg(s, 1);
}

View file

@ -0,0 +1,81 @@
/*
* Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Kungliga Tekniska
* Högskolan and its contributors.
*
* 4. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*/
/* $Id: krb4.h,v 1.10 1997/04/01 08:17:22 joda Exp $ */
#ifndef __KRB4_H__
#define __KRB4_H__
#include <stdio.h>
#include <stdarg.h>
extern int auth_complete;
void sec_status(void);
enum { prot_clear, prot_safe, prot_confidential, prot_private };
void sec_prot(int, char**);
int sec_getc(FILE *F);
int sec_putc(int c, FILE *F);
int sec_fflush(FILE *F);
int sec_read(int fd, void *data, int length);
int sec_write(int fd, char *data, int length);
int krb4_getc(FILE *F);
int krb4_read(int fd, char *data, int length);
void sec_set_protection_level(void);
int sec_request_prot(char *level);
void kauth(int, char **);
void klist(int, char **);
void krb4_quit(void);
int krb4_write_enc(FILE *F, char *fmt, va_list ap);
int krb4_read_msg(char *s, int priv);
int krb4_read_mic(char *s);
int krb4_read_enc(char *s);
int do_klogin(char *host);
#endif /* __KRB4_H__ */

View file

@ -0,0 +1,542 @@
/*
* Copyright (c) 1985, 1989, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*/
/*
* FTP User Program -- Command Interface.
*/
#include "ftp_locl.h"
RCSID("$Id: main.c,v 1.20 1997/04/20 16:14:55 joda Exp $");
int
main(int argc, char **argv)
{
int ch, top;
struct passwd *pw = NULL;
char homedir[MaxPathLen];
struct servent *sp;
set_progname(argv[0]);
sp = getservbyname("ftp", "tcp");
if (sp == 0)
errx(1, "ftp/tcp: unknown service");
doglob = 1;
interactive = 1;
autologin = 1;
while ((ch = getopt(argc, argv, "dgintv")) != EOF) {
switch (ch) {
case 'd':
options |= SO_DEBUG;
debug++;
break;
case 'g':
doglob = 0;
break;
case 'i':
interactive = 0;
break;
case 'n':
autologin = 0;
break;
case 't':
trace++;
break;
case 'v':
verbose++;
break;
default:
fprintf(stderr,
"usage: ftp [-dgintv] [host [port]]\n");
exit(1);
}
}
argc -= optind;
argv += optind;
fromatty = isatty(fileno(stdin));
if (fromatty)
verbose++;
cpend = 0; /* no pending replies */
proxy = 0; /* proxy not active */
passivemode = 0; /* passive mode not active */
crflag = 1; /* strip c.r. on ascii gets */
sendport = -1; /* not using ports */
/*
* Set up the home directory in case we're globbing.
*/
pw = k_getpwuid(getuid());
if (pw != NULL) {
home = homedir;
strcpy(home, pw->pw_dir);
}
if (argc > 0) {
char *xargv[5];
if (setjmp(toplevel))
exit(0);
signal(SIGINT, intr);
signal(SIGPIPE, lostpeer);
xargv[0] = (char*)__progname;
xargv[1] = argv[0];
xargv[2] = argv[1];
xargv[3] = argv[2];
xargv[4] = NULL;
setpeer(argc+1, xargv);
}
if(setjmp(toplevel) == 0)
top = 1;
else
top = 0;
if (top) {
signal(SIGINT, intr);
signal(SIGPIPE, lostpeer);
}
for (;;) {
cmdscanner(top);
top = 1;
}
}
void
intr(int sig)
{
longjmp(toplevel, 1);
}
#ifndef SHUT_RDWR
#define SHUT_RDWR 2
#endif
RETSIGTYPE
lostpeer(int sig)
{
if (connected) {
if (cout != NULL) {
shutdown(fileno(cout), SHUT_RDWR);
fclose(cout);
cout = NULL;
}
if (data >= 0) {
shutdown(data, SHUT_RDWR);
close(data);
data = -1;
}
connected = 0;
}
pswitch(1);
if (connected) {
if (cout != NULL) {
shutdown(fileno(cout), SHUT_RDWR);
fclose(cout);
cout = NULL;
}
connected = 0;
}
proxflag = 0;
pswitch(0);
SIGRETURN(0);
}
/*
char *
tail(filename)
char *filename;
{
char *s;
while (*filename) {
s = strrchr(filename, '/');
if (s == NULL)
break;
if (s[1])
return (s + 1);
*s = '\0';
}
return (filename);
}
*/
#ifndef HAVE_READLINE
static char *
readline(char *prompt)
{
char buf[BUFSIZ];
printf ("%s", prompt);
fflush (stdout);
if(fgets(buf, sizeof(buf), stdin) == NULL)
return NULL;
if (buf[strlen(buf) - 1] == '\n')
buf[strlen(buf) - 1] = '\0';
return strdup(buf);
}
static void
add_history(char *p)
{
}
#else
/* These should not really be here */
char *readline(char *);
void add_history(char *);
#endif
/*
* Command parser.
*/
void
cmdscanner(int top)
{
struct cmd *c;
int l;
if (!top)
putchar('\n');
for (;;) {
if (fromatty) {
char *p;
p = readline("ftp> ");
if(p == NULL)
quit(0, 0);
strncpy(line, p, sizeof(line));
line[sizeof(line) - 1] = 0;
add_history(p);
free(p);
} else{
if (fgets(line, sizeof line, stdin) == NULL)
quit(0, 0);
}
/* XXX will break on long lines */
l = strlen(line);
if (l == 0)
break;
if (line[--l] == '\n') {
if (l == 0)
break;
line[l] = '\0';
} else if (l == sizeof(line) - 2) {
printf("sorry, input line too long\n");
while ((l = getchar()) != '\n' && l != EOF)
/* void */;
break;
} /* else it was a line without a newline */
makeargv();
if (margc == 0) {
continue;
}
c = getcmd(margv[0]);
if (c == (struct cmd *)-1) {
printf("?Ambiguous command\n");
continue;
}
if (c == 0) {
printf("?Invalid command\n");
continue;
}
if (c->c_conn && !connected) {
printf("Not connected.\n");
continue;
}
(*c->c_handler)(margc, margv);
if (bell && c->c_bell)
putchar('\007');
if (c->c_handler != help)
break;
}
signal(SIGINT, intr);
signal(SIGPIPE, lostpeer);
}
struct cmd *
getcmd(char *name)
{
char *p, *q;
struct cmd *c, *found;
int nmatches, longest;
longest = 0;
nmatches = 0;
found = 0;
for (c = cmdtab; (p = c->c_name); c++) {
for (q = name; *q == *p++; q++)
if (*q == 0) /* exact match? */
return (c);
if (!*q) { /* the name was a prefix */
if (q - name > longest) {
longest = q - name;
nmatches = 1;
found = c;
} else if (q - name == longest)
nmatches++;
}
}
if (nmatches > 1)
return ((struct cmd *)-1);
return (found);
}
/*
* Slice a string up into argc/argv.
*/
int slrflag;
void
makeargv(void)
{
char **argp;
argp = margv;
stringbase = line; /* scan from first of buffer */
argbase = argbuf; /* store from first of buffer */
slrflag = 0;
for (margc = 0; ; margc++) {
/* Expand array if necessary */
if (margc == margvlen) {
margv = (margvlen == 0)
? (char **)malloc(20 * sizeof(char *))
: (char **)realloc(margv,
(margvlen + 20)*sizeof(char *));
if (margv == NULL)
errx(1, "cannot realloc argv array");
margvlen += 20;
argp = margv + margc;
}
if ((*argp++ = slurpstring()) == NULL)
break;
}
}
/*
* Parse string into argbuf;
* implemented with FSM to
* handle quoting and strings
*/
char *
slurpstring(void)
{
int got_one = 0;
char *sb = stringbase;
char *ap = argbase;
char *tmp = argbase; /* will return this if token found */
if (*sb == '!' || *sb == '$') { /* recognize ! as a token for shell */
switch (slrflag) { /* and $ as token for macro invoke */
case 0:
slrflag++;
stringbase++;
return ((*sb == '!') ? "!" : "$");
/* NOTREACHED */
case 1:
slrflag++;
altarg = stringbase;
break;
default:
break;
}
}
S0:
switch (*sb) {
case '\0':
goto OUT;
case ' ':
case '\t':
sb++; goto S0;
default:
switch (slrflag) {
case 0:
slrflag++;
break;
case 1:
slrflag++;
altarg = sb;
break;
default:
break;
}
goto S1;
}
S1:
switch (*sb) {
case ' ':
case '\t':
case '\0':
goto OUT; /* end of token */
case '\\':
sb++; goto S2; /* slurp next character */
case '"':
sb++; goto S3; /* slurp quoted string */
default:
*ap++ = *sb++; /* add character to token */
got_one = 1;
goto S1;
}
S2:
switch (*sb) {
case '\0':
goto OUT;
default:
*ap++ = *sb++;
got_one = 1;
goto S1;
}
S3:
switch (*sb) {
case '\0':
goto OUT;
case '"':
sb++; goto S1;
default:
*ap++ = *sb++;
got_one = 1;
goto S3;
}
OUT:
if (got_one)
*ap++ = '\0';
argbase = ap; /* update storage pointer */
stringbase = sb; /* update scan pointer */
if (got_one) {
return (tmp);
}
switch (slrflag) {
case 0:
slrflag++;
break;
case 1:
slrflag++;
altarg = (char *) 0;
break;
default:
break;
}
return NULL;
}
#define HELPINDENT ((int) sizeof ("directory"))
/*
* Help command.
* Call each command handler with argc == 0 and argv[0] == name.
*/
void
help(int argc, char **argv)
{
struct cmd *c;
if (argc == 1) {
int i, j, w, k;
int columns, width = 0, lines;
printf("Commands may be abbreviated. Commands are:\n\n");
for (c = cmdtab; c < &cmdtab[NCMDS]; c++) {
int len = strlen(c->c_name);
if (len > width)
width = len;
}
width = (width + 8) &~ 7;
columns = 80 / width;
if (columns == 0)
columns = 1;
lines = (NCMDS + columns - 1) / columns;
for (i = 0; i < lines; i++) {
for (j = 0; j < columns; j++) {
c = cmdtab + j * lines + i;
if (c->c_name && (!proxy || c->c_proxy)) {
printf("%s", c->c_name);
}
else if (c->c_name) {
for (k=0; k < strlen(c->c_name); k++) {
putchar(' ');
}
}
if (c + lines >= &cmdtab[NCMDS]) {
printf("\n");
break;
}
w = strlen(c->c_name);
while (w < width) {
w = (w + 8) &~ 7;
putchar('\t');
}
}
}
return;
}
while (--argc > 0) {
char *arg;
arg = *++argv;
c = getcmd(arg);
if (c == (struct cmd *)-1)
printf("?Ambiguous help command %s\n", arg);
else if (c == (struct cmd *)0)
printf("?Invalid help command %s\n", arg);
else
printf("%-*s\t%s\n", HELPINDENT,
c->c_name, c->c_help);
}
}

View file

@ -0,0 +1,44 @@
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* @(#)pathnames.h 8.1 (Berkeley) 6/6/93
*/
#ifdef HAVE_PATHS_H
#include <paths.h>
#endif
#define _PATH_TMP_XXX "/tmp/ftpXXXXXX"
#ifndef _PATH_BSHELL
#define _PATH_BSHELL "/bin/sh"
#endif

View file

@ -0,0 +1,274 @@
/*
* Copyright (c) 1985, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*/
#include "ftp_locl.h"
RCSID("$Id: ruserpass.c,v 1.10 1997/05/02 14:27:55 assar Exp $");
static int token (void);
static FILE *cfile;
#define DEFAULT 1
#define LOGIN 2
#define PASSWD 3
#define ACCOUNT 4
#define MACDEF 5
#define PROT 6
#define ID 10
#define MACH 11
static char tokval[100];
static struct toktab {
char *tokstr;
int tval;
} toktab[]= {
{ "default", DEFAULT },
{ "login", LOGIN },
{ "password", PASSWD },
{ "passwd", PASSWD },
{ "account", ACCOUNT },
{ "machine", MACH },
{ "macdef", MACDEF },
{ "prot", PROT },
{ NULL, 0 }
};
int
ruserpass(char *host, char **aname, char **apass, char **aacct)
{
char *hdir, buf[BUFSIZ], *tmp;
int t, i, c, usedefault = 0;
struct stat stb;
if(k_gethostname(myhostname, MaxHostNameLen) < 0)
strcpy(myhostname, "");
if((mydomain = strchr(myhostname, '.')) == NULL)
mydomain = myhostname;
else
mydomain++;
hdir = getenv("HOME");
if (hdir == NULL)
hdir = ".";
snprintf(buf, sizeof(buf), "%s/.netrc", hdir);
cfile = fopen(buf, "r");
if (cfile == NULL) {
if (errno != ENOENT)
warn("%s", buf);
return (0);
}
next:
while ((t = token())) switch(t) {
case DEFAULT:
usedefault = 1;
/* FALL THROUGH */
case MACH:
if (!usedefault) {
if (token() != ID)
continue;
/*
* Allow match either for user's input host name
* or official hostname. Also allow match of
* incompletely-specified host in local domain.
*/
if (strcasecmp(host, tokval) == 0)
goto match;
if (strcasecmp(hostname, tokval) == 0)
goto match;
if ((tmp = strchr(hostname, '.')) != NULL &&
tmp++ &&
strcasecmp(tmp, mydomain) == 0 &&
strncasecmp(hostname, tokval, tmp-hostname) == 0 &&
tokval[tmp - hostname] == '\0')
goto match;
if ((tmp = strchr(host, '.')) != NULL &&
tmp++ &&
strcasecmp(tmp, mydomain) == 0 &&
strncasecmp(host, tokval, tmp - host) == 0 &&
tokval[tmp - host] == '\0')
goto match;
continue;
}
match:
while ((t = token()) && t != MACH && t != DEFAULT) switch(t) {
case LOGIN:
if (token())
if (*aname == 0) {
*aname = strdup(tokval);
} else {
if (strcmp(*aname, tokval))
goto next;
}
break;
case PASSWD:
if ((*aname == NULL || strcmp(*aname, "anonymous")) &&
fstat(fileno(cfile), &stb) >= 0 &&
(stb.st_mode & 077) != 0) {
warnx("Error: .netrc file is readable by others.");
warnx("Remove password or make file unreadable by others.");
goto bad;
}
if (token() && *apass == 0) {
*apass = strdup(tokval);
}
break;
case ACCOUNT:
if (fstat(fileno(cfile), &stb) >= 0
&& (stb.st_mode & 077) != 0) {
warnx("Error: .netrc file is readable by others.");
warnx("Remove account or make file unreadable by others.");
goto bad;
}
if (token() && *aacct == 0) {
*aacct = strdup(tokval);
}
break;
case MACDEF:
if (proxy) {
fclose(cfile);
return (0);
}
while ((c=getc(cfile)) != EOF && c == ' ' || c == '\t');
if (c == EOF || c == '\n') {
printf("Missing macdef name argument.\n");
goto bad;
}
if (macnum == 16) {
printf("Limit of 16 macros have already been defined\n");
goto bad;
}
tmp = macros[macnum].mac_name;
*tmp++ = c;
for (i=0; i < 8 && (c=getc(cfile)) != EOF &&
!isspace(c); ++i) {
*tmp++ = c;
}
if (c == EOF) {
printf("Macro definition missing null line terminator.\n");
goto bad;
}
*tmp = '\0';
if (c != '\n') {
while ((c=getc(cfile)) != EOF && c != '\n');
}
if (c == EOF) {
printf("Macro definition missing null line terminator.\n");
goto bad;
}
if (macnum == 0) {
macros[macnum].mac_start = macbuf;
}
else {
macros[macnum].mac_start = macros[macnum-1].mac_end + 1;
}
tmp = macros[macnum].mac_start;
while (tmp != macbuf + 4096) {
if ((c=getc(cfile)) == EOF) {
printf("Macro definition missing null line terminator.\n");
goto bad;
}
*tmp = c;
if (*tmp == '\n') {
if (*(tmp-1) == '\0') {
macros[macnum++].mac_end = tmp - 1;
break;
}
*tmp = '\0';
}
tmp++;
}
if (tmp == macbuf + 4096) {
printf("4K macro buffer exceeded\n");
goto bad;
}
break;
case PROT:
token();
if(sec_request_prot(tokval) < 0)
warnx("Unknown protection level \"%s\"", tokval);
break;
default:
warnx("Unknown .netrc keyword %s", tokval);
break;
}
goto done;
}
done:
fclose(cfile);
return (0);
bad:
fclose(cfile);
return (-1);
}
static int
token(void)
{
char *cp;
int c;
struct toktab *t;
if (feof(cfile) || ferror(cfile))
return (0);
while ((c = getc(cfile)) != EOF &&
(c == '\n' || c == '\t' || c == ' ' || c == ','))
continue;
if (c == EOF)
return (0);
cp = tokval;
if (c == '"') {
while ((c = getc(cfile)) != EOF && c != '"') {
if (c == '\\')
c = getc(cfile);
*cp++ = c;
}
} else {
*cp++ = c;
while ((c = getc(cfile)) != EOF
&& c != '\n' && c != '\t' && c != ' ' && c != ',') {
if (c == '\\')
c = getc(cfile);
*cp++ = c;
}
}
*cp = 0;
if (tokval[0] == 0)
return (0);
for (t = toktab; t->tokstr; t++)
if (!strcmp(t->tokstr, tokval))
return (t->tval);
return (ID);
}

View file

@ -0,0 +1,84 @@
#
# $Id: Makefile.in,v 1.31 1997/05/02 17:49:27 assar Exp $
#
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
topdir = ../../..
SHELL = /bin/sh
CC = @CC@
YACC = @YACC@
RANLIB = @RANLIB@
DEFS = @DEFS@
CFLAGS = @CFLAGS@
LD_FLAGS = @LD_FLAGS@
LIBS = @LIBS@
LIB_DBM = @LIB_DBM@
MKINSTALLDIRS = $(top_srcdir)/mkinstalldirs
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
prefix = @prefix@
exec_prefix = @exec_prefix@
libdir = @libdir@
libexecdir = @libexecdir@
transform=@program_transform_name@
EXECSUFFIX=@EXECSUFFIX@
ATHENA = ../../..
INCTOP = $(ATHENA)/include
LIBTOP = $(ATHENA)/lib
LIBKAFS = @KRB_KAFS_LIB@
LIBKRB = -L$(LIBTOP)/krb -lkrb
LIBDES = -L$(LIBTOP)/des -ldes
LIBOTP = -L$(LIBTOP)/otp -lotp
LIBROKEN= -L$(LIBTOP)/roken -lroken
PROGS = ftpd$(EXECSUFFIX)
ftpd_SOURCES = ftpd.c ftpcmd.c logwtmp.c popen.c auth.c krb4.c kauth.c
ftpd_OBJS = ftpd.o ftpcmd.o logwtmp.o popen.o auth.o krb4.o kauth.o
SOURCES = $(ftpd_SOURCES)
OBJECTS = $(ftpd_OBJS)
all: $(PROGS)
.c.o:
$(CC) -c $(CFLAGS) -I$(srcdir) -I$(srcdir)/../common -I$(INCTOP) $(DEFS) $<
install: all
$(MKINSTALLDIRS) $(libexecdir)
for x in $(PROGS); do \
$(INSTALL_PROGRAM) $$x $(libexecdir)/`echo $$x | sed '$(transform)'`; \
done
uninstall:
for x in $(PROGS); do \
rm -f $(libexecdir)/`echo $$x | sed '$(transform)'`; \
done
ftpd$(EXECSUFFIX): $(ftpd_OBJS)
$(CC) $(LD_FLAGS) $(LDFLAGS) -o $@ $(ftpd_OBJS) -L../common -lcommon $(LIBKAFS) $(LIBKRB) $(LIBOTP) $(LIBDES) $(LIBROKEN) $(LIB_DBM) $(LIBS) $(LIBROKEN)
ftpcmd.c: ftpcmd.y
$(YACC) $(YFLAGS) $<
chmod a-w y.tab.c
mv -f y.tab.c ftpcmd.c
TAGS: $(SOURCES)
etags $(SOURCES)
clean cleandir:
rm -f *~ *.o core ftpd ftpcmd.c \#*
distclean:
rm -f Makefile

View file

@ -0,0 +1,249 @@
/*
* Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Kungliga Tekniska
* Högskolan and its contributors.
*
* 4. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
RCSID("$Id: auth.c,v 1.11 1997/05/04 23:09:00 assar Exp $");
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#if defined(HAVE_SYS_IOCTL_H) && SunOS != 4
#include <sys/ioctl.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "extern.h"
#include "krb4.h"
#include "auth.h"
static struct at auth_types [] = {
{ "KERBEROS_V4", krb4_auth, krb4_adat, krb4_pbsz, krb4_prot, krb4_ccc,
krb4_mic, krb4_conf, krb4_enc, krb4_read, krb4_write, krb4_userok,
krb4_vprintf },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 }
};
struct at *ct;
int data_protection;
int buffer_size;
unsigned char *data_buffer;
int auth_complete;
char *protection_names[] = {
"clear", "safe",
"confidential", "private"
};
void auth_init(void)
{
}
char *ftp_command;
int prot_level;
void new_ftp_command(char *command)
{
ftp_command = command;
}
void delete_ftp_command(void)
{
if(ftp_command){
free(ftp_command);
ftp_command = NULL;
}
}
int auth_ok(void)
{
return ct && auth_complete;
}
void auth(char *auth)
{
for(ct=auth_types; ct->name; ct++){
if(!strcasecmp(auth, ct->name)){
ct->auth(auth);
return;
}
}
reply(504, "%s is not a known security mechanism", auth);
}
void adat(char *auth)
{
if(ct && !auth_complete)
ct->adat(auth);
else
reply(503, "You must (re)issue an AUTH first.");
}
void pbsz(int size)
{
int old = buffer_size;
if(auth_ok())
ct->pbsz(size);
else
reply(503, "Incomplete security data exchange.");
if(buffer_size != old){
if(data_buffer)
free(data_buffer);
data_buffer = malloc(buffer_size + 4);
}
}
void prot(char *pl)
{
int p = -1;
if(buffer_size == 0){
reply(503, "No protection buffer size negotiated.");
return;
}
if(!strcasecmp(pl, "C"))
p = prot_clear;
if(!strcasecmp(pl, "S"))
p = prot_safe;
if(!strcasecmp(pl, "E"))
p = prot_confidential;
if(!strcasecmp(pl, "P"))
p = prot_private;
if(p == -1){
reply(504, "Unrecognized protection level.");
return;
}
if(auth_ok()){
if(ct->prot(p)){
reply(536, "%s does not support %s protection.",
ct->name, protection_names[p]);
}else{
data_protection = p;
reply(200, "Data protection is %s.",
protection_names[data_protection]);
}
}else{
reply(503, "Incomplete security data exchange.");
}
}
void ccc(void)
{
if(auth_ok()){
if(!ct->ccc())
prot_level = prot_clear;
}else
reply(503, "Incomplete security data exchange.");
}
void mic(char *msg)
{
if(auth_ok()){
if(!ct->mic(msg))
prot_level = prot_safe;
}else
reply(503, "Incomplete security data exchange.");
}
void conf(char *msg)
{
if(auth_ok()){
if(!ct->conf(msg))
prot_level = prot_confidential;
}else
reply(503, "Incomplete security data exchange.");
}
void enc(char *msg)
{
if(auth_ok()){
if(!ct->enc(msg))
prot_level = prot_private;
}else
reply(503, "Incomplete security data exchange.");
}
int auth_read(int fd, void *data, int length)
{
if(auth_ok() && data_protection)
return ct->read(fd, data, length);
else
return read(fd, data, length);
}
int auth_write(int fd, void *data, int length)
{
if(auth_ok() && data_protection)
return ct->write(fd, data, length);
else
return write(fd, data, length);
}
void auth_vprintf(const char *fmt, va_list ap)
{
if(auth_ok() && prot_level){
ct->vprintf(fmt, ap);
}else
vprintf(fmt, ap);
}
void auth_printf(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
auth_vprintf(fmt, ap);
va_end(ap);
}

View file

@ -0,0 +1,109 @@
/*
* Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Kungliga Tekniska
* Högskolan and its contributors.
*
* 4. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*/
/* $Id: auth.h,v 1.9 1997/05/11 11:04:28 assar Exp $ */
#ifndef __AUTH_H__
#define __AUTH_H__
#include <stdarg.h>
struct at {
char *name;
int (*auth)(char*);
int (*adat)(char*);
int (*pbsz)(int);
int (*prot)(int);
int (*ccc)(void);
int (*mic)(char*);
int (*conf)(char*);
int (*enc)(char*);
int (*read)(int, void*, int);
int (*write)(int, void*, int);
int (*userok)(char*);
int (*vprintf)(const char*, va_list);
};
extern struct at *ct;
enum protection_levels {
prot_clear, prot_safe, prot_confidential, prot_private
};
extern char *protection_names[];
extern char *ftp_command;
extern int prot_level;
void delete_ftp_command(void);
extern int data_protection;
extern int buffer_size;
extern unsigned char *data_buffer;
extern int auth_complete;
void auth_init(void);
int auth_ok(void);
void auth(char*);
void adat(char*);
void pbsz(int);
void prot(char*);
void ccc(void);
void mic(char*);
void conf(char*);
void enc(char*);
int auth_read(int, void*, int);
int auth_write(int, void*, int);
void auth_vprintf(const char *fmt, va_list ap)
#ifdef __GNUC__
__attribute__ ((format (printf, 1, 0)))
#endif
;
void auth_printf(const char *fmt, ...)
#ifdef __GNUC__
__attribute__ ((format (printf, 1, 2)))
#endif
;
void new_ftp_command(char *command);
#endif /* __AUTH_H__ */

View file

@ -0,0 +1,141 @@
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* @(#)extern.h 8.2 (Berkeley) 4/4/94
*/
#ifndef _EXTERN_H_
#define _EXTERN_H_
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#include <stdio.h>
#include <stdarg.h>
#include <setjmp.h>
#ifdef HAVE_PWD_H
#include <pwd.h>
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
void abor(void);
void blkfree(char **);
char **copyblk(char **);
void cwd(char *);
void do_delete(char *);
void dologout(int);
void fatal(char *);
int filename_check(char *);
int ftpd_pclose(FILE *);
FILE *ftpd_popen(char *, char *, int, int);
char *getline(char *, int);
void logwtmp(char *, char *, char *);
void lreply(int, const char *, ...)
#ifdef __GNUC__
__attribute__ ((format (printf, 2, 3)))
#endif
;
void makedir(char *);
void nack(char *);
void nreply(const char *, ...)
#ifdef __GNUC__
__attribute__ ((format (printf, 1, 2)))
#endif
;
void pass(char *);
void passive(void);
void perror_reply(int, char *);
void pwd(void);
void removedir(char *);
void renamecmd(char *, char *);
char *renamefrom(char *);
void reply(int, const char *, ...)
#ifdef __GNUC__
__attribute__ ((format (printf, 2, 3)))
#endif
;
void retrieve(char *, char *);
void send_file_list(char *);
void setproctitle(const char *, ...)
#ifdef __GNUC__
__attribute__ ((format (printf, 1, 2)))
#endif
;
void statcmd(void);
void statfilecmd(char *);
void do_store(char *, char *, int);
void upper(char *);
void user(char *);
void yyerror(char *);
void kauth(char *, char*);
void klist(void);
int find(char *);
int do_login(int code, char *passwd);
int klogin(char *name, char *password);
const char *ftp_rooted(const char *path);
extern struct sockaddr_in ctrl_addr, his_addr;
extern char hostname[];
extern struct sockaddr_in data_dest;
extern int logged_in;
extern struct passwd *pw;
extern int guest;
extern int logging;
extern int type;
extern int oobflag;
extern off_t file_size;
extern off_t byte_count;
extern jmp_buf urgcatch;
extern int form;
extern int debug;
extern int ftpd_timeout;
extern int maxtimeout;
extern int pdata;
extern char hostname[], remotehost[];
extern char proctitle[];
extern int usedefault;
extern int transflag;
extern char tmpline[];
#endif /* _EXTERN_H_ */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,325 @@
/*
* Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Kungliga Tekniska
* Högskolan and its contributors.
*
* 4. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
RCSID("$Id: kauth.c,v 1.14 1997/05/07 02:21:30 assar Exp $");
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#include <roken.h>
#include <des.h>
#include <krb.h>
#include <kafs.h>
#include "extern.h"
#include "krb4.h"
#include "auth.h"
#include "base64.h"
static KTEXT_ST cip;
static unsigned int lifetime;
static time_t local_time;
static krb_principal pr;
static int
save_tkt(char *user, char *instance, char *realm, void *arg,
int (*key_proc)(char*, char*, char*, void*, des_cblock*), KTEXT *cipp)
{
local_time = time(0);
memmove(&cip, *cipp, sizeof(cip));
return -1;
}
static int
store_ticket(KTEXT cip)
{
char *ptr;
des_cblock session;
krb_principal sp;
unsigned char kvno;
KTEXT_ST tkt;
int left = cip->length;
int kerror;
time_t kdc_time;
ptr = (char *) cip->dat;
/* extract session key */
memmove(session, ptr, 8);
ptr += 8;
left -= 8;
if (strnlen(ptr, left) == left)
return(INTK_BADPW);
/* extract server's name */
strcpy(sp.name, ptr);
ptr += strlen(sp.name) + 1;
left -= strlen(sp.name) + 1;
if (strnlen(ptr, left) == left)
return(INTK_BADPW);
/* extract server's instance */
strcpy(sp.instance, ptr);
ptr += strlen(sp.instance) + 1;
left -= strlen(sp.instance) + 1;
if (strnlen(ptr, left) == left)
return(INTK_BADPW);
/* extract server's realm */
strcpy(sp.realm,ptr);
ptr += strlen(sp.realm) + 1;
left -= strlen(sp.realm) + 1;
if(left < 3)
return INTK_BADPW;
/* extract ticket lifetime, server key version, ticket length */
/* be sure to avoid sign extension on lifetime! */
lifetime = (unsigned char) ptr[0];
kvno = (unsigned char) ptr[1];
tkt.length = (unsigned char) ptr[2];
ptr += 3;
left -= 3;
if (tkt.length > left)
return(INTK_BADPW);
/* extract ticket itself */
memmove(tkt.dat, ptr, tkt.length);
ptr += tkt.length;
left -= tkt.length;
/* Here is where the time should be verified against the KDC.
* Unfortunately everything is sent in host byte order (receiver
* makes wrong) , and at this stage there is no way for us to know
* which byteorder the KDC has. So we simply ignore the time,
* there are no security risks with this, the only thing that can
* happen is that we might receive a replayed ticket, which could
* at most be useless.
*/
#if 0
/* check KDC time stamp */
memmove(&kdc_time, ptr, sizeof(kdc_time));
if (swap_bytes) swap_u_long(kdc_time);
ptr += 4;
if (abs((int)(local_time - kdc_time)) > CLOCK_SKEW) {
return(RD_AP_TIME); /* XXX should probably be better
code */
}
#endif
/* initialize ticket cache */
if (tf_create(TKT_FILE) != KSUCCESS)
return(INTK_ERR);
if (tf_put_pname(pr.name) != KSUCCESS ||
tf_put_pinst(pr.instance) != KSUCCESS) {
tf_close();
return(INTK_ERR);
}
kerror = tf_save_cred(sp.name, sp.instance, sp.realm, session,
lifetime, kvno, &tkt, local_time);
tf_close();
return(kerror);
}
void kauth(char *principal, char *ticket)
{
char *p;
int ret;
ret = krb_parse_name(principal, &pr);
if(ret){
reply(500, "Bad principal: %s.", krb_get_err_text(ret));
return;
}
if(pr.realm[0] == 0)
krb_get_lrealm(pr.realm, 1);
if(ticket){
cip.length = base64_decode(ticket, &cip.dat);
if(cip.length == -1){
reply(500, "Failed to decode data.");
return;
}
ret = store_ticket(&cip);
if(ret){
reply(500, "Kerberos error: %s.", krb_get_err_text(ret));
memset(&cip, 0, sizeof(cip));
return;
}
if(k_hasafs())
k_afsklog(0, 0);
reply(200, "Tickets will be destroyed on exit.");
return;
}
ret = krb_get_in_tkt (pr.name,
pr.instance,
pr.realm,
KRB_TICKET_GRANTING_TICKET,
pr.realm,
DEFAULT_TKT_LIFE,
NULL, save_tkt, NULL);
if(ret != INTK_BADPW){
reply(500, "Kerberos error: %s.", krb_get_err_text(ret));
return;
}
base64_encode(cip.dat, cip.length, &p);
reply(300, "P=%s T=%s", krb_unparse_name(&pr), p);
free(p);
memset(&cip, 0, sizeof(cip));
}
static char *
short_date(int32_t dp)
{
char *cp;
time_t t = (time_t)dp;
if (t == (time_t)(-1L)) return "*** Never *** ";
cp = ctime(&t) + 4;
cp[15] = '\0';
return (cp);
}
void klist(void)
{
int err;
char *file = tkt_string();
krb_principal pr;
char buf1[128], buf2[128];
int header = 1;
CREDENTIALS c;
err = tf_init(file, R_TKT_FIL);
if(err != KSUCCESS){
reply(500, "%s", krb_get_err_text(err));
return;
}
tf_close();
/*
* We must find the realm of the ticket file here before calling
* tf_init because since the realm of the ticket file is not
* really stored in the principal section of the file, the
* routine we use must itself call tf_init and tf_close.
*/
err = krb_get_tf_realm(file, pr.realm);
if(err != KSUCCESS){
reply(500, "%s", krb_get_err_text(err));
return;
}
err = tf_init(file, R_TKT_FIL);
if(err != KSUCCESS){
reply(500, "%s", krb_get_err_text(err));
return;
}
err = tf_get_pname(pr.name);
if(err != KSUCCESS){
reply(500, "%s", krb_get_err_text(err));
return;
}
err = tf_get_pinst(pr.instance);
if(err != KSUCCESS){
reply(500, "%s", krb_get_err_text(err));
return;
}
/*
* You may think that this is the obvious place to get the
* realm of the ticket file, but it can't be done here as the
* routine to do this must open the ticket file. This is why
* it was done before tf_init.
*/
lreply(200, "Principal: %s", krb_unparse_name(&pr));
while ((err = tf_get_cred(&c)) == KSUCCESS) {
if (header) {
lreply(200, "%-15s %-15s %s",
" Issued", " Expires", " Principal (kvno)");
header = 0;
}
strcpy(buf1, short_date(c.issue_date));
c.issue_date = krb_life_to_time(c.issue_date, c.lifetime);
if (time(0) < (unsigned long) c.issue_date)
strcpy(buf2, short_date(c.issue_date));
else
strcpy(buf2, ">>> Expired <<< ");
lreply(200, "%s %s %s (%d)", buf1, buf2,
krb_unparse_name_long(c.service, c.instance, c.realm), c.kvno);
}
if (header && err == EOF) {
lreply(200, "No tickets in file.");
}
reply(200, "");
}

View file

@ -0,0 +1,372 @@
/*
* Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Kungliga Tekniska
* Högskolan and its contributors.
*
* 4. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
RCSID("$Id: krb4.c,v 1.19 1997/05/11 09:00:07 assar Exp $");
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#ifdef HAVE_NETINET_IN_h
#include <netinet/in.h>
#endif
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <krb.h>
#include "base64.h"
#include "extern.h"
#include "auth.h"
#include "krb4.h"
#include <roken.h>
static AUTH_DAT auth_dat;
static des_key_schedule schedule;
int krb4_auth(char *auth)
{
auth_complete = 0;
reply(334, "Using authentication type %s; ADAT must follow", auth);
return 0;
}
int krb4_adat(char *auth)
{
KTEXT_ST tkt;
char *p;
int kerror;
u_int32_t cs;
char msg[35]; /* size of encrypted block */
int len;
char inst[INST_SZ];
memset(&tkt, 0, sizeof(tkt));
len = base64_decode(auth, tkt.dat);
if(len < 0){
reply(501, "Failed to decode base64 data.");
return -1;
}
tkt.length = len;
k_getsockinst(0, inst, sizeof(inst));
kerror = krb_rd_req(&tkt, "ftp", inst, 0, &auth_dat, "");
if(kerror == RD_AP_UNDEC){
k_getsockinst(0, inst, sizeof(inst));
kerror = krb_rd_req(&tkt, "rcmd", inst, 0, &auth_dat, "");
}
if(kerror){
reply(535, "Error reading request: %s.", krb_get_err_text(kerror));
return -1;
}
des_set_key(&auth_dat.session, schedule);
cs = auth_dat.checksum + 1;
{
unsigned char tmp[4];
tmp[0] = (cs >> 24) & 0xff;
tmp[1] = (cs >> 16) & 0xff;
tmp[2] = (cs >> 8) & 0xff;
tmp[3] = cs & 0xff;
len = krb_mk_safe(tmp, msg, 4, &auth_dat.session,
&ctrl_addr, &his_addr);
}
if(len < 0){
reply(535, "Error creating reply: %s.", strerror(errno));
return -1;
}
base64_encode(msg, len, &p);
reply(235, "ADAT=%s", p);
auth_complete = 1;
free(p);
return 0;
}
int krb4_pbsz(int size)
{
if(size > 1048576) /* XXX arbitrary number */
size = 1048576;
buffer_size = size;
reply(200, "OK PBSZ=%d", buffer_size);
return 0;
}
int krb4_prot(int level)
{
if(level == prot_confidential)
return -1;
return 0;
}
int krb4_ccc(void)
{
reply(534, "Don't event think about it.");
return -1;
}
int krb4_mic(char *msg)
{
int len;
int kerror;
MSG_DAT m_data;
char *tmp, *cmd;
cmd = strdup(msg);
len = base64_decode(msg, cmd);
if(len < 0){
reply(501, "Failed to decode base 64 data.");
free(cmd);
return -1;
}
kerror = krb_rd_safe(cmd, len, &auth_dat.session,
&his_addr, &ctrl_addr, &m_data);
if(kerror){
reply(535, "Error reading request: %s.", krb_get_err_text(kerror));
free(cmd);
return -1;
}
tmp = malloc(strlen(msg) + 1);
snprintf(tmp, strlen(msg) + 1, "%.*s", (int)m_data.app_length, m_data.app_data);
if(!strstr(tmp, "\r\n"))
strcat(tmp, "\r\n");
new_ftp_command(tmp);
free(cmd);
return 0;
}
int krb4_conf(char *msg)
{
prot_level = prot_safe;
reply(537, "Protection level not supported.");
return -1;
}
int krb4_enc(char *msg)
{
int len;
int kerror;
MSG_DAT m_data;
char *tmp, *cmd;
cmd = strdup(msg);
len = base64_decode(msg, cmd);
if(len < 0){
reply(501, "Failed to decode base 64 data.");
free(cmd);
return -1;
}
kerror = krb_rd_priv(cmd, len, schedule, &auth_dat.session,
&his_addr, &ctrl_addr, &m_data);
if(kerror){
reply(535, "Error reading request: %s.", krb_get_err_text(kerror));
free(cmd);
return -1;
}
tmp = strdup(msg);
snprintf(tmp, strlen(msg) + 1, "%.*s", (int)m_data.app_length, m_data.app_data);
if(!strstr(tmp, "\r\n"))
strcat(tmp, "\r\n");
new_ftp_command(tmp);
free(cmd);
return 0;
}
int krb4_read(int fd, void *data, int length)
{
static int left;
static char *extra;
static int eof;
int len, bytes, tx = 0;
MSG_DAT m_data;
int kerror;
if(eof){ /* if we haven't reported an end-of-file, do so */
eof = 0;
return 0;
}
if(left){
if(length > left)
bytes = left;
else
bytes = length;
memmove(data, extra, bytes);
left -= bytes;
if(left)
memmove(extra, extra + bytes, left);
else
free(extra);
length -= bytes;
tx += bytes;
}
while(length){
unsigned char tmp[4];
if(krb_net_read(fd, tmp, 4) < 4){
reply(400, "Unexpected end of file.\n");
return -1;
}
len = (tmp[0] << 24) | (tmp[1] << 16) | (tmp[2] << 8) | tmp[3];
krb_net_read(fd, data_buffer, len);
if(data_protection == prot_safe)
kerror = krb_rd_safe(data_buffer, len, &auth_dat.session,
&his_addr, &ctrl_addr, &m_data);
else
kerror = krb_rd_priv(data_buffer, len, schedule, &auth_dat.session,
&his_addr, &ctrl_addr, &m_data);
if(kerror){
reply(400, "Failed to read data: %s.", krb_get_err_text(kerror));
return -1;
}
bytes = m_data.app_length;
if(bytes == 0){
if(tx) eof = 1;
return tx;
}
if(bytes > length){
left = bytes - length;
bytes = length;
extra = malloc(left);
memmove(extra, m_data.app_data + bytes, left);
}
memmove((unsigned char*)data + tx, m_data.app_data, bytes);
tx += bytes;
length -= bytes;
}
return tx;
}
int krb4_write(int fd, void *data, int length)
{
int len, bytes, tx = 0;
len = buffer_size;
if(data_protection == prot_safe)
len -= 31; /* always 31 bytes overhead */
else
len -= 26; /* at most 26 bytes */
do{
if(length < len)
len = length;
if(data_protection == prot_safe)
bytes = krb_mk_safe(data, data_buffer+4, len, &auth_dat.session,
&ctrl_addr, &his_addr);
else
bytes = krb_mk_priv(data, data_buffer+4, len, schedule,
&auth_dat.session,
&ctrl_addr, &his_addr);
if(bytes == -1){
reply(535, "Failed to make packet: %s.", strerror(errno));
return -1;
}
data_buffer[0] = (bytes >> 24) & 0xff;
data_buffer[1] = (bytes >> 16) & 0xff;
data_buffer[2] = (bytes >> 8) & 0xff;
data_buffer[3] = bytes & 0xff;
if(krb_net_write(fd, data_buffer, bytes+4) < 0)
return -1;
length -= len;
data = (unsigned char*)data + len;
tx += len;
}while(length);
return tx;
}
int krb4_userok(char *name)
{
if(!kuserok(&auth_dat, name)){
do_login(232, name);
}else{
reply(530, "User %s access denied.", name);
}
return 0;
}
int
krb4_vprintf(const char *fmt, va_list ap)
{
char buf[10240];
char *p;
char *enc;
int code;
int len;
vsnprintf (buf, sizeof(buf), fmt, ap);
enc = malloc(strlen(buf) + 31);
if(prot_level == prot_safe){
len = krb_mk_safe((u_char*)buf, (u_char*)enc, strlen(buf), &auth_dat.session,
&ctrl_addr, &his_addr);
code = 631;
}else if(prot_level == prot_private){
len = krb_mk_priv((u_char*)buf, (u_char*)enc, strlen(buf), schedule,
&auth_dat.session, &ctrl_addr, &his_addr);
code = 632;
}else{
len = 0; /* XXX */
code = 631;
}
base64_encode(enc, len, &p);
fprintf(stdout, "%d %s\r\n", code, p);
free(enc);
free(p);
return 0;
}

View file

@ -0,0 +1,61 @@
/*
* Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Kungliga Tekniska
* Högskolan and its contributors.
*
* 4. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*/
/* $Id: krb4.h,v 1.6 1997/04/01 08:17:29 joda Exp $ */
#ifndef __KRB4_H__
#define __KRB4_H__
#include <stdarg.h>
int krb4_auth(char *auth);
int krb4_adat(char *auth);
int krb4_pbsz(int size);
int krb4_prot(int level);
int krb4_ccc(void);
int krb4_mic(char *msg);
int krb4_conf(char *msg);
int krb4_enc(char *msg);
int krb4_read(int fd, void *data, int length);
int krb4_write(int fd, void *data, int length);
int krb4_userok(char *name);
int krb4_vprintf(const char *fmt, va_list ap);
#endif /* __KRB4_H__ */

View file

@ -0,0 +1,136 @@
/*
* Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Kungliga Tekniska
* Högskolan and its contributors.
*
* 4. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
RCSID("$Id: logwtmp.c,v 1.10 1997/05/25 15:17:56 assar Exp $");
#endif
#include <stdio.h>
#include <string.h>
#ifdef TIME_WITH_SYS_TIME
#include <sys/time.h>
#include <time.h>
#elif defined(HAVE_SYS_TIME_H)
#include <sys/time.h>
#else
#include <time.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_UTMP_H
#include <utmp.h>
#endif
#ifdef HAVE_UTMPX_H
#include <utmpx.h>
#endif
#include "extern.h"
#ifndef WTMP_FILE
#ifdef _PATH_WTMP
#define WTMP_FILE _PATH_WTMP
#else
#define WTMP_FILE "/var/adm/wtmp"
#endif
#endif
void
logwtmp(char *line, char *name, char *host)
{
static int init = 0;
static int fd, fdx;
struct timeval tv;
struct utmp ut;
#ifdef WTMPX_FILE
struct utmpx utx;
#endif
memset(&ut, 0, sizeof(struct utmp));
#ifdef HAVE_UT_TYPE
if(name[0])
ut.ut_type = USER_PROCESS;
else
ut.ut_type = DEAD_PROCESS;
#endif
strncpy(ut.ut_line, line, sizeof(ut.ut_line));
strncpy(ut.ut_name, name, sizeof(ut.ut_name));
#ifdef HAVE_UT_PID
ut.ut_pid = getpid();
#endif
#ifdef HAVE_UT_HOST
strncpy(ut.ut_host, host, sizeof(ut.ut_host));
#endif
ut.ut_time = time(NULL);
#ifdef WTMPX_FILE
strncpy(utx.ut_line, line, sizeof(utx.ut_line));
strncpy(utx.ut_user, name, sizeof(utx.ut_user));
strncpy(utx.ut_host, host, sizeof(utx.ut_host));
#ifdef HAVE_UT_SYSLEN
utx.ut_syslen = strlen(host) + 1;
if (utx.ut_syslen > sizeof(utx.ut_host))
utx.ut_syslen = sizeof(utx.ut_host);
#endif
gettimeofday (&tv, 0);
utx.ut_tv.tv_sec = tv.tv_sec;
utx.ut_tv.tv_usec = tv.tv_usec;
if(name[0])
utx.ut_type = USER_PROCESS;
else
utx.ut_type = DEAD_PROCESS;
#endif
if(!init){
fd = open(WTMP_FILE, O_WRONLY|O_APPEND, 0);
#ifdef WTMPX_FILE
fdx = open(WTMPX_FILE, O_WRONLY|O_APPEND, 0);
#endif
init = 1;
}
if(fd >= 0) {
write(fd, &ut, sizeof(struct utmp)); /* XXX */
#ifdef WTMPX_FILE
write(fdx, &utx, sizeof(struct utmpx));
#endif
}
}

View file

@ -0,0 +1,55 @@
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* @(#)pathnames.h 8.1 (Berkeley) 6/4/93
*/
#ifdef HAVE_PATHS_H
#include <paths.h>
#endif
#ifndef _PATH_DEVNULL
#define _PATH_DEVNULL "/dev/null"
#endif
#ifndef _PATH_NOLOGIN
#define _PATH_NOLOGIN "/etc/nologin"
#endif
#ifndef _PATH_BSHELL
#define _PATH_BSHELL "/bin/sh"
#endif
#define _PATH_FTPUSERS "/etc/ftpusers"
#define _PATH_FTPCHROOT "/etc/ftpchroot"
#define _PATH_FTPWELCOME "/etc/ftpwelcome"
#define _PATH_FTPLOGINMESG "/etc/motd"

View file

@ -0,0 +1,224 @@
/*
* Copyright (c) 1988, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software written by Ken Arnold and
* published in UNIX Review, Vol. 6, No. 8.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
RCSID("$Id: popen.c,v 1.16 1997/06/01 03:14:06 assar Exp $");
#endif
#include <sys/types.h>
#ifdef TIME_WITH_SYS_TIME
#include <sys/time.h>
#include <time.h>
#elif defined(HAVE_SYS_TIME_H)
#include <sys/time.h>
#else
#include <time.h>
#endif
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
#endif
#include <sys/wait.h>
#include <errno.h>
#include <glob.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "extern.h"
#include <roken.h>
/*
* Special version of popen which avoids call to shell. This ensures
* no one may create a pipe to a hidden program as a side effect of a
* list or dir command.
*/
static int *pids;
static int fds;
extern int dochroot;
/* return path prepended with ~ftp if that file exists, otherwise
* return path unchanged
*/
const char *
ftp_rooted(const char *path)
{
static char home[MaxPathLen] = "";
static char newpath[MaxPathLen];
struct passwd *pwd;
if(!home[0])
if((pwd = k_getpwnam("ftp")))
strcpy(home, pwd->pw_dir);
snprintf(newpath, sizeof(newpath), "%s/%s", home, path);
if(access(newpath, X_OK))
strcpy(newpath, path);
return newpath;
}
FILE *
ftpd_popen(char *program, char *type, int do_stderr, int no_glob)
{
char *cp;
FILE *iop;
int argc, gargc, pdes[2], pid;
char **pop, *argv[100], *gargv[1000];
char *foo;
if (strcmp(type, "r") && strcmp(type, "w"))
return (NULL);
if (!pids) {
/* This function is ugly and should be rewritten, in
* modern unices there is no such thing as a maximum
* filedescriptor.
*/
fds = getdtablesize();
pids = (int*)calloc(fds, sizeof(int));
if(!pids)
return NULL;
}
if (pipe(pdes) < 0)
return (NULL);
/* break up string into pieces */
for (argc = 0, cp = program;; cp = NULL) {
foo = NULL;
if (!(argv[argc++] = strtok_r(cp, " \t\n", &foo)))
break;
}
gargv[0] = (char*)ftp_rooted(argv[0]);
/* glob each piece */
for (gargc = argc = 1; argv[argc]; argc++) {
glob_t gl;
int flags = GLOB_BRACE|GLOB_NOCHECK|GLOB_QUOTE|GLOB_TILDE;
memset(&gl, 0, sizeof(gl));
if (no_glob || glob(argv[argc], flags, NULL, &gl))
gargv[gargc++] = strdup(argv[argc]);
else
for (pop = gl.gl_pathv; *pop; pop++)
gargv[gargc++] = strdup(*pop);
globfree(&gl);
}
gargv[gargc] = NULL;
iop = NULL;
switch(pid = fork()) {
case -1: /* error */
close(pdes[0]);
close(pdes[1]);
goto pfree;
/* NOTREACHED */
case 0: /* child */
if (*type == 'r') {
if (pdes[1] != STDOUT_FILENO) {
dup2(pdes[1], STDOUT_FILENO);
close(pdes[1]);
}
if(do_stderr)
dup2(STDOUT_FILENO, STDERR_FILENO);
close(pdes[0]);
} else {
if (pdes[0] != STDIN_FILENO) {
dup2(pdes[0], STDIN_FILENO);
close(pdes[0]);
}
close(pdes[1]);
}
execv(gargv[0], gargv);
gargv[0] = argv[0];
execv(gargv[0], gargv);
_exit(1);
}
/* parent; assume fdopen can't fail... */
if (*type == 'r') {
iop = fdopen(pdes[0], type);
close(pdes[1]);
} else {
iop = fdopen(pdes[1], type);
close(pdes[0]);
}
pids[fileno(iop)] = pid;
pfree:
for (argc = 1; gargv[argc] != NULL; argc++)
free(gargv[argc]);
return (iop);
}
int
ftpd_pclose(FILE *iop)
{
int fdes, status;
pid_t pid;
sigset_t sigset, osigset;
/*
* pclose returns -1 if stream is not associated with a
* `popened' command, or, if already `pclosed'.
*/
if (pids == 0 || pids[fdes = fileno(iop)] == 0)
return (-1);
fclose(iop);
sigemptyset(&sigset);
sigaddset(&sigset, SIGINT);
sigaddset(&sigset, SIGQUIT);
sigaddset(&sigset, SIGHUP);
sigprocmask(SIG_BLOCK, &sigset, &osigset);
while ((pid = waitpid(pids[fdes], &status, 0)) < 0 && errno == EINTR)
continue;
sigprocmask(SIG_SETMASK, &osigset, NULL);
pids[fdes] = 0;
if (pid < 0)
return (pid);
if (WIFEXITED(status))
return (WEXITSTATUS(status));
return (1);
}

View file

@ -0,0 +1,112 @@
# $Id: Makefile.in,v 1.33 1997/04/05 21:24:35 assar Exp $
SHELL = /bin/sh
srcdir = @srcdir@
VPATH = @srcdir@
topdir = ../..
CC = @CC@
AR = ar
RANLIB = @RANLIB@
DEFS = @DEFS@ -DBINDIR='"$(bindir)"'
CFLAGS = @CFLAGS@
LD_FLAGS = @LD_FLAGS@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
LIBS = @LIBS@
MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
prefix = @prefix@
exec_prefix = @exec_prefix@
libdir = @libdir@
libexecdir = @libexecdir@
bindir = @bindir@
transform=@program_transform_name@
EXECSUFFIX=@EXECSUFFIX@
PROG_BIN = kauth$(EXECSUFFIX) ksrvtgt
PROG_LIBEXEC = kauthd$(EXECSUFFIX)
PROGS = $(PROG_BIN) $(PROG_LIBEXEC)
SOURCES_KAUTH = kauth.c rkinit.c
SOURCES_KAUTHD = kauthd.c
SOURCES_COMMON = encdata.c marshall.c
OBJECTS_KAUTH = kauth.o rkinit.o
OBJECTS_KAUTHD = kauthd.o
OBJECTS_COMMON = marshall.o encdata.o
OBJECTS = $(OBJECTS_KAUTH) $(OBJECTS_KAUTHD)
SOURCES = $(SOURCES_KAUTH) $(SOURCES_KAUTHD) $(SOURCES_COMMON)
KRB_KAFS_LIB = @KRB_KAFS_LIB@
all: $(PROGS)
Wall:
make CFLAGS="-g -Wall -Wno-comment -Wmissing-prototypes -Wmissing-declarations -D__USE_FIXED_PROTOTYPES__"
.c.o:
$(CC) -c $(CPPFLAGS) $(DEFS) -I../../include -I$(srcdir) $(CFLAGS) $<
install: all
$(MKINSTALLDIRS) $(bindir) $(libexecdir)
for x in $(PROG_BIN); do \
$(INSTALL_PROGRAM) $$x $(bindir)/`echo $$x| sed '$(transform)'`; \
done
if test -f $(bindir)/zrefresh -o -r $(bindir)/zrefresh; then \
true; \
else \
$(INSTALL_PROGRAM) $(srcdir)/zrefresh $(bindir)/`echo zrefresh | sed '$(transform)'`; \
fi
for x in $(PROG_LIBEXEC); do \
$(INSTALL_PROGRAM) $$x $(libexecdir)/`echo $$x| sed '$(transform)'`; \
done
uninstall:
for x in $(PROG_BIN); do \
rm -f $(bindir)/`echo $$x| sed '$(transform)'`; \
done
for x in $(PROG_LIBEXEC); do \
rm -f $(libexecdir)/`echo $$x| sed '$(transform)'`; \
done
TAGS: $(SOURCES)
etags $(SOURCES)
check:
clean:
rm -f *.a *.o $(PROGS)
mostlyclean: clean
distclean: clean
rm -f Makefile *.tab.c *~
realclean: distclean
rm -f TAGS
dist: $(DISTFILES)
for file in $(DISTFILES); do \
ln $$file ../`cat ../.fname`/lib \
|| cp -p $$file ../`cat ../.fname`/lib; \
done
KLIB=-L../../lib/krb -lkrb -L../../lib/des -ldes
LIBROKEN=-L../../lib/roken -lroken
kauth$(EXECSUFFIX): $(OBJECTS_KAUTH) $(OBJECTS_COMMON)
$(CC) $(LD_FLAGS) $(LDFLAGS) -o $@ $(OBJECTS_KAUTH) $(OBJECTS_COMMON) $(KRB_KAFS_LIB) $(KLIB) $(LIBROKEN) $(LIBS) $(LIBROKEN)
kauthd$(EXECSUFFIX): $(OBJECTS_KAUTHD) $(OBJECTS_COMMON)
$(CC) $(LD_FLAGS) $(LDFLAGS) -o $@ $(OBJECTS_KAUTHD) $(OBJECTS_COMMON) $(KLIB) $(LIBROKEN) $(LIBS) $(LIBROKEN)
ksrvtgt: ksrvtgt.in
sed -e "s!%bindir%!$(bindir)!" $(srcdir)/ksrvtgt.in > $@
chmod +x $@
$(OBJECTS): ../../include/config.h

View file

@ -0,0 +1,101 @@
/*
* Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Kungliga Tekniska
* Högskolan and its contributors.
*
* 4. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*/
#include "kauth.h"
RCSID("$Id: encdata.c,v 1.9 1997/04/01 08:17:30 joda Exp $");
int
write_encrypted (int fd, void *buf, size_t len, des_key_schedule schedule,
des_cblock *session, struct sockaddr_in *me,
struct sockaddr_in *him)
{
void *outbuf;
int32_t outlen, l;
int i;
unsigned char tmp[4];
outbuf = malloc(len + 30);
if (outbuf == NULL)
return -1;
outlen = krb_mk_priv (buf, outbuf, len, schedule, session, me, him);
if (outlen < 0) {
free(outbuf);
return -1;
}
l = outlen;
for(i = 3; i >= 0; i--, l = l >> 8)
tmp[i] = l & 0xff;
if (krb_net_write (fd, tmp, 4) != 4 ||
krb_net_write (fd, outbuf, outlen) != outlen) {
free(outbuf);
return -1;
}
free(outbuf);
return 0;
}
int
read_encrypted (int fd, void *buf, size_t len, void **ret,
des_key_schedule schedule, des_cblock *session,
struct sockaddr_in *him, struct sockaddr_in *me)
{
int status;
int32_t l;
MSG_DAT msg;
unsigned char tmp[4];
l = krb_net_read (fd, tmp, 4);
if (l != 4)
return l;
l = (tmp[0] << 24) | (tmp[1] << 16) | (tmp[2] << 8) | tmp[3];
if (l > len)
return -1;
if (krb_net_read (fd, buf, l) != l)
return -1;
status = krb_rd_priv (buf, l, schedule, session, him, me, &msg);
if (status != RD_AP_OK) {
fprintf (stderr, "read_encrypted: %s\n",
krb_get_err_text(status));
return -1;
}
*ret = msg.app_data;
return msg.app_length;
}

View file

@ -0,0 +1,312 @@
/*
* Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Kungliga Tekniska
* Högskolan and its contributors.
*
* 4. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*/
/*
* Little program that reads an srvtab or password and
* creates a suitable ticketfile and associated AFS tokens.
*
* If an optional command is given the command is executed in a
* new PAG and when the command exits the tickets are destroyed.
*/
#include "kauth.h"
RCSID("$Id: kauth.c,v 1.75 1997/05/02 15:09:24 assar Exp $");
krb_principal princ;
static char srvtab[MaxPathLen + 1];
static int lifetime = DEFAULT_TKT_LIFE;
static char remote_tktfile[MaxPathLen + 1];
static char remoteuser[100];
static char *cell = 0;
static void
usage(void)
{
fprintf(stderr,
"Usage: %s [-n <name>] [-r remoteuser] [-t remote ticketfile]"
"[-l lifetime (in minutes) ] [-h hosts... ]"
"[-f srvtab ] [-c AFS cell name ] [command ... ]\n",
__progname);
fprintf(stderr, "\nA fully qualified name can be given user[.instance][@realm]\nRealm is converted to uppercase!\n");
exit(1);
}
static void
doexec(int argc, char **argv)
{
int status;
pid_t ret;
switch (fork()) {
case -1:
err (1, "fork");
break;
case 0:
/* in child */
execvp(argv[0], argv);
err (1, "Can't exec program ``%s''", argv[0]);
break;
default:
/* in parent */
do {
ret = wait(&status);
} while ((ret > 0 && !WIFEXITED(status)) || (ret < 0 && errno == EINTR));
if (ret < 0)
perror("wait");
dest_tkt();
if (k_hasafs())
k_unlog();
break;
}
}
static RETSIGTYPE
renew(int sig)
{
int code;
signal(SIGALRM, renew);
code = krb_get_svc_in_tkt(princ.name, princ.instance, princ.realm,
KRB_TICKET_GRANTING_TICKET,
princ.realm, lifetime, srvtab);
if (code)
warnx ("%s", krb_get_err_text(code));
else if (k_hasafs())
{
if ((code = k_afsklog(cell, NULL)) != 0 && code != KDC_PR_UNKNOWN) {
warnx ("%s", krb_get_err_text(code));
}
}
alarm(krb_life_to_time(0, lifetime)/2 - 60);
SIGRETURN(0);
}
static int
zrefresh(void)
{
switch (fork()) {
case -1:
err (1, "Warning: Failed to fork zrefresh");
return -1;
case 0:
/* Child */
execlp("zrefresh", "zrefresh", 0);
execl(BINDIR "/zrefresh", "zrefresh", 0);
exit(1);
default:
/* Parent */
break;
}
return 0;
}
static int
key_to_key(char *user, char *instance, char *realm, void *arg,
des_cblock *key)
{
memcpy(key, arg, sizeof(des_cblock));
return 0;
}
int
main(int argc, char **argv)
{
int code, more_args;
int ret;
int c;
char *file;
int pflag = 0;
char passwd[100];
des_cblock key;
char **host;
int nhost;
char tf[MaxPathLen];
set_progname (argv[0]);
if ((file = getenv("KRBTKFILE")) == 0)
file = TKT_FILE;
memset(&princ, 0, sizeof(princ));
memset(srvtab, 0, sizeof(srvtab));
*remoteuser = '\0';
nhost = 0;
while ((c = getopt(argc, argv, "r:t:f:hl:n:c:")) != EOF)
switch (c) {
case 'f':
strncpy(srvtab, optarg, sizeof(srvtab));
break;
case 't':
strncpy(remote_tktfile, optarg, sizeof(remote_tktfile));
break;
case 'r':
strncpy(remoteuser, optarg, sizeof(remoteuser));
break;
case 'l':
lifetime = atoi(optarg);
if (lifetime == -1)
lifetime = 255;
else if (lifetime < 5)
lifetime = 1;
else
lifetime = krb_time_to_life(0, lifetime*60);
if (lifetime > 255)
lifetime = 255;
break;
case 'n':
if ((code = krb_parse_name(optarg, &princ)) != 0) {
warnx ("%s", krb_get_err_text(code));
usage();
}
strupr(princ.realm);
pflag = 1;
break;
case 'c':
cell = optarg;
break;
case 'h':
host = argv + optind;
for(nhost = 0; optind < argc && *argv[optind] != '-'; ++optind)
++nhost;
break;
case '?':
default:
usage();
break;
}
/* Look for kerberos name */
if (!pflag && optind < argc && krb_parse_name(argv[optind], &princ) == 0) {
++optind;
strupr(princ.realm);
}
if (princ.name[0] == '\0' && krb_get_default_principal (princ.name,
princ.instance,
princ.realm) < 0)
errx (1, "Could not get default principal");
if (*remoteuser == '\0')
strcpy (remoteuser, princ.name);
more_args = argc - optind;
if (princ.realm[0] == '\0')
if (krb_get_lrealm(princ.realm, 1) != KSUCCESS)
strcpy(princ.realm, KRB_REALM);
if (more_args) {
int f;
do{
snprintf(tf, sizeof(tf),
TKT_ROOT "%u_%u",
(unsigned)getuid(),
(unsigned)(getpid()*time(0)));
f = open(tf, O_CREAT|O_EXCL|O_RDWR);
}while(f < 0);
close(f);
unlink(tf);
setenv("KRBTKFILE", tf, 1);
krb_set_tkt_string (tf);
}
if (srvtab[0])
{
signal(SIGALRM, renew);
code = read_service_key (princ.name, princ.instance, princ.realm, 0,
srvtab, (char *)&key);
if (code == KSUCCESS)
code = krb_get_in_tkt(princ.name, princ.instance, princ.realm,
KRB_TICKET_GRANTING_TICKET,
princ.realm, lifetime,
key_to_key, NULL, key);
alarm(krb_life_to_time(0, lifetime)/2 - 60);
}
else {
char prompt[128];
snprintf(prompt, sizeof(prompt), "%s's Password: ", krb_unparse_name(&princ));
if (des_read_pw_string(passwd, sizeof(passwd)-1, prompt, 0)){
memset(passwd, 0, sizeof(passwd));
exit(1);
}
des_string_to_key (passwd, &key);
code = krb_get_in_tkt (princ.name, princ.instance, princ.realm,
KRB_TICKET_GRANTING_TICKET,
princ.realm, lifetime,
key_to_key, NULL, key);
if(code == INTK_BADPW) {
afs_string_to_key (passwd, princ.realm, &key);
code = krb_get_in_tkt (princ.name, princ.instance, princ.realm,
KRB_TICKET_GRANTING_TICKET,
princ.realm, lifetime,
key_to_key, NULL, key);
}
memset(passwd, 0, sizeof(passwd));
}
if (code) {
memset (key, 0, sizeof(key));
errx (1, "%s", krb_get_err_text(code));
}
if (k_hasafs()) {
if (more_args)
k_setpag();
if ((code = k_afsklog(cell, NULL)) != 0 && code != KDC_PR_UNKNOWN)
warnx ("%s", krb_get_err_text(code));
}
for(ret = 0; nhost-- > 0; host++)
ret += rkinit(&princ, lifetime, remoteuser, remote_tktfile, &key, *host);
if (ret)
return ret;
if (more_args)
doexec(more_args, &argv[optind]);
else
zrefresh();
return 0;
}

View file

@ -0,0 +1,118 @@
/*
* Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Kungliga Tekniska
* Högskolan and its contributors.
*
* 4. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*/
/* $Id: kauth.h,v 1.18 1997/05/20 18:40:31 bg Exp $ */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /* HAVE_CONFIG_H */
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <signal.h>
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#include <errno.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_PWD_H
#include <pwd.h>
#endif
#ifdef HAVE_GRP_H
#include <grp.h>
#endif
#ifdef TIME_WITH_SYS_TIME
#include <sys/time.h>
#include <time.h>
#elif defined(HAVE_SYS_TIME_H)
#include <sys/time.h>
#else
#include <time.h>
#endif
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
#endif /* HAVE_SYS_RESOURCE_H */
#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#ifdef HAVE_NETDB_H
#include <netdb.h>
#endif
#ifdef SOCKS
#include <socks.h>
#endif
#include <err.h>
#include <krb.h>
#include <kafs.h>
#include <roken.h>
#define KAUTH_PORT 2120
#define KAUTH_VERSION "RKINIT.0"
int rkinit (krb_principal*, int, char*, char*, des_cblock*, char*);
int write_encrypted (int, void*, size_t, des_key_schedule,
des_cblock*, struct sockaddr_in*, struct sockaddr_in*);
int read_encrypted (int, void*, size_t, void **, des_key_schedule,
des_cblock*, struct sockaddr_in*, struct sockaddr_in*);
unsigned pack_args (char *, krb_principal*, int, char*, char*);
int unpack_args (char*, krb_principal*, int*, char*, char*);

View file

@ -0,0 +1,201 @@
/*
* Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Kungliga Tekniska
* Högskolan and its contributors.
*
* 4. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*/
#include "kauth.h"
RCSID("$Id: kauthd.c,v 1.22 1997/05/18 20:37:55 assar Exp $");
krb_principal princ;
static char locuser[SNAME_SZ + 1];
static int lifetime;
static char tktfile[MaxPathLen + 1];
struct remote_args {
int sock;
des_key_schedule *schedule;
des_cblock *session;
struct sockaddr_in *me, *her;
};
static int
decrypt_remote_tkt (char *user, char *inst, char *realm, void *varg,
key_proc_t key_proc, KTEXT *cipp)
{
char buf[BUFSIZ];
void *ptr;
int len;
KTEXT cip = *cipp;
struct remote_args *args = (struct remote_args *)varg;
write_encrypted (args->sock, cip->dat, cip->length,
*args->schedule, args->session, args->me,
args->her);
len = read_encrypted (args->sock, buf, sizeof(buf), &ptr, *args->schedule,
args->session, args->her, args->me);
memcpy(cip->dat, ptr, cip->length);
return 0;
}
static int
doit(int sock)
{
int status;
KTEXT_ST ticket;
AUTH_DAT auth;
char instance[INST_SZ + 1];
des_key_schedule schedule;
struct sockaddr_in thisaddr, thataddr;
int addrlen;
int len;
char buf[BUFSIZ];
void *data;
struct passwd *passwd;
char version[KRB_SENDAUTH_VLEN + 1];
char remotehost[MaxHostNameLen];
addrlen = sizeof(thisaddr);
if (getsockname (sock, (struct sockaddr *)&thisaddr, &addrlen) < 0 ||
addrlen != sizeof(thisaddr)) {
return 1;
}
addrlen = sizeof(thataddr);
if (getpeername (sock, (struct sockaddr *)&thataddr, &addrlen) < 0 ||
addrlen != sizeof(thataddr)) {
return 1;
}
inaddr2str (thataddr.sin_addr, remotehost, sizeof(remotehost));
k_getsockinst (sock, instance, sizeof(instance));
status = krb_recvauth (KOPT_DO_MUTUAL, sock, &ticket, "rcmd", instance,
&thataddr, &thisaddr, &auth, "", schedule,
version);
if (status != KSUCCESS ||
strncmp(version, KAUTH_VERSION, KRB_SENDAUTH_VLEN) != 0) {
return 1;
}
len = read_encrypted (sock, buf, sizeof(buf), &data, schedule,
&auth.session, &thataddr, &thisaddr);
if (len < 0) {
write_encrypted (sock, "read_enc failed",
sizeof("read_enc failed") - 1, schedule,
&auth.session, &thisaddr, &thataddr);
return 1;
}
if (unpack_args(data, &princ, &lifetime, locuser,
tktfile)) {
write_encrypted (sock, "unpack_args failed",
sizeof("unpack_args failed") - 1, schedule,
&auth.session, &thisaddr, &thataddr);
return 1;
}
if( kuserok(&auth, locuser) != 0) {
snprintf(buf, sizeof(buf), "%s cannot get tickets for %s",
locuser, krb_unparse_name(&princ));
syslog (LOG_ERR, buf);
write_encrypted (sock, buf, strlen(buf), schedule,
&auth.session, &thisaddr, &thataddr);
return 1;
}
passwd = k_getpwnam (locuser);
if (passwd == NULL) {
snprintf (buf, sizeof(buf), "No user '%s'", locuser);
syslog (LOG_ERR, buf);
write_encrypted (sock, buf, strlen(buf), schedule,
&auth.session, &thisaddr, &thataddr);
return 1;
}
if (setgid (passwd->pw_gid) ||
initgroups(passwd->pw_name, passwd->pw_gid) ||
setuid(passwd->pw_uid)) {
snprintf (buf, sizeof(buf), "Could not change user");
syslog (LOG_ERR, buf);
write_encrypted (sock, buf, strlen(buf), schedule,
&auth.session, &thisaddr, &thataddr);
return 1;
}
write_encrypted (sock, "ok", sizeof("ok") - 1, schedule,
&auth.session, &thisaddr, &thataddr);
if (*tktfile == 0)
snprintf(tktfile, sizeof(tktfile), "%s%u", TKT_ROOT, (unsigned)getuid());
krb_set_tkt_string (tktfile);
{
struct remote_args arg;
arg.sock = sock;
arg.schedule = &schedule;
arg.session = &auth.session;
arg.me = &thisaddr;
arg.her = &thataddr;
status = krb_get_in_tkt (princ.name, princ.instance, princ.realm,
KRB_TICKET_GRANTING_TICKET,
princ.realm,
lifetime, NULL, decrypt_remote_tkt, &arg);
}
if (status == KSUCCESS) {
syslog (LOG_INFO, "from %s(%s): %s -> %s",
remotehost,
inet_ntoa(thataddr.sin_addr),
locuser,
krb_unparse_name (&princ));
write_encrypted (sock, "ok", sizeof("ok") - 1, schedule,
&auth.session, &thisaddr, &thataddr);
return 0;
} else {
snprintf (buf, sizeof(buf), "TGT failed: %s", krb_get_err_text(status));
syslog (LOG_NOTICE, buf);
write_encrypted (sock, buf, strlen(buf), schedule,
&auth.session, &thisaddr, &thataddr);
return 1;
}
}
int
main (int argc, char **argv)
{
openlog ("kauthd", LOG_ODELAY, LOG_AUTH);
if(argc > 1 && strcmp(argv[1], "-i") == 0)
mini_inetd (k_getportbyname("kauth", "tcp", htons(KAUTH_PORT)));
return doit(STDIN_FILENO);
}

View file

@ -0,0 +1,14 @@
#! /bin/sh
# $Id: ksrvtgt.in,v 1.2 1997/04/05 21:29:17 assar Exp $
usage="Usage: `basename $0` name instance [[realm] srvtab]"
if [ $# -lt 2 -o $# -gt 4 ]; then
echo "$usage"
exit 1
fi
srvtab="${4-${3-/etc/srvtab}}"
realm="${4+@$3}"
%bindir%/kauth -n "$1.$2$realm" -l 5 -f "$srvtab "

View file

@ -0,0 +1,97 @@
/*
* Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Kungliga Tekniska
* Högskolan and its contributors.
*
* 4. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*/
#include "kauth.h"
RCSID("$Id: marshall.c,v 1.7 1997/04/01 08:17:32 joda Exp $");
unsigned
pack_args (char *buf, krb_principal *pr, int lifetime,
char *locuser, char *tktfile)
{
char *p;
p = buf;
strcpy (p, pr->name);
p += strlen (pr->name) + 1;
strcpy (p, pr->instance);
p += strlen (pr->instance) + 1;
strcpy (p, pr->realm);
p += strlen (pr->realm) + 1;
*p++ = (unsigned char)lifetime;
strcpy(p, locuser);
p += strlen (locuser) + 1;
strcpy(p, tktfile);
p += strlen(tktfile) + 1;
return p - buf;
}
int
unpack_args (char *buf, krb_principal *pr, int *lifetime,
char *locuser, char *tktfile)
{
int len;
len = strlen(buf);
if (len > SNAME_SZ)
return -1;
strncpy(pr->name, buf, len + 1);
buf += len + 1;
len = strlen (buf);
if (len > INST_SZ)
return -1;
strncpy (pr->instance, buf, len + 1);
buf += len + 1;
len = strlen (buf);
if (len > REALM_SZ)
return -1;
strncpy (pr->realm, buf, len + 1);
buf += len + 1;
*lifetime = (unsigned char)*buf++;
len = strlen(buf);
if (len > SNAME_SZ)
return -1;
strncpy (locuser, buf, len + 1);
buf += len + 1;
len = strlen(buf);
if (len > MaxPathLen)
return -1;
strncpy (tktfile, buf, len + 1);
buf += len + 1;
return 0;
}

View file

@ -0,0 +1,222 @@
/*
* Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Kungliga Tekniska
* Högskolan and its contributors.
*
* 4. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*/
#include "kauth.h"
RCSID("$Id: rkinit.c,v 1.19 1997/04/01 08:17:33 joda Exp $");
static struct in_addr *
getalladdrs (char *hostname, unsigned *count)
{
struct hostent *hostent;
struct in_addr **h;
struct in_addr *addr;
unsigned naddr;
unsigned maxaddr;
hostent = gethostbyname (hostname);
if (hostent == NULL) {
warnx ("gethostbyname '%s' failed: %s\n",
hostname,
#ifdef HAVE_H_ERRNO
hstrerror(h_errno)
#else
"unknown error"
#endif
);
return NULL;
}
maxaddr = 1;
naddr = 0;
addr = malloc(sizeof(*addr) * maxaddr);
if (addr == NULL) {
warnx ("out of memory");
return NULL;
}
for (h = (struct in_addr **)(hostent->h_addr_list);
*h != NULL;
h++) {
if (naddr >= maxaddr) {
maxaddr *= 2;
addr = realloc (addr, sizeof(*addr) * maxaddr);
if (addr == NULL) {
warnx ("out of memory");
return NULL;
}
}
addr[naddr++] = **h;
}
addr = realloc (addr, sizeof(*addr) * naddr);
if (addr == NULL) {
warnx ("out of memory");
return NULL;
}
*count = naddr;
return addr;
}
static int
doit_host (krb_principal *princ, int lifetime, char *locuser,
char *tktfile, des_cblock *key, int s, char *hostname)
{
char buf[BUFSIZ];
int inlen;
KTEXT_ST text;
CREDENTIALS cred;
MSG_DAT msg;
int status;
des_key_schedule schedule;
struct sockaddr_in thisaddr, thataddr;
int addrlen;
void *ret;
addrlen = sizeof(thisaddr);
if (getsockname (s, (struct sockaddr *)&thisaddr, &addrlen) < 0 ||
addrlen != sizeof(thisaddr)) {
warn ("getsockname(%s)", hostname);
return 1;
}
addrlen = sizeof(thataddr);
if (getpeername (s, (struct sockaddr *)&thataddr, &addrlen) < 0 ||
addrlen != sizeof(thataddr)) {
warn ("getpeername(%s)", hostname);
return 1;
}
status = krb_sendauth (KOPT_DO_MUTUAL, s, &text, "rcmd",
hostname, krb_realmofhost (hostname),
getpid(), &msg, &cred, schedule,
&thisaddr, &thataddr, KAUTH_VERSION);
if (status != KSUCCESS) {
warnx ("%s: %s\n", hostname, krb_get_err_text(status));
return 1;
}
inlen = pack_args (buf, princ, lifetime, locuser, tktfile);
if (write_encrypted(s, buf, inlen, schedule, &cred.session,
&thisaddr, &thataddr) < 0) {
warn ("write to %s", hostname);
return 1;
}
inlen = read_encrypted (s, buf, sizeof(buf), &ret, schedule,
&cred.session, &thataddr, &thisaddr);
if (inlen < 0) {
warn ("read from %s failed", hostname);
return 1;
}
if (strncmp(ret, "ok", inlen) != 0) {
warnx ("error from %s: %.*s\n",
hostname, inlen, (char *)ret);
return 1;
}
inlen = read_encrypted (s, buf, sizeof(buf), &ret, schedule,
&cred.session, &thataddr, &thisaddr);
if (inlen < 0) {
warn ("read from %s", hostname);
return 1;
}
{
des_key_schedule key_s;
des_key_sched(key, key_s);
des_pcbc_encrypt(ret, ret, inlen, key_s, key, DES_DECRYPT);
memset(key_s, 0, sizeof(key_s));
}
write_encrypted (s, ret, inlen, schedule, &cred.session,
&thisaddr, &thataddr);
inlen = read_encrypted (s, buf, sizeof(buf), &ret, schedule,
&cred.session, &thataddr, &thisaddr);
if (inlen < 0) {
warn ("read from %s", hostname);
return 1;
}
if (strncmp(ret, "ok", inlen) != 0) {
warnx ("error from %s: %.*s\n",
hostname, inlen, (char *)ret);
return 1;
}
return 0;
}
int
rkinit (krb_principal *princ, int lifetime, char *locuser,
char *tktfile, des_cblock *key, char *hostname)
{
struct in_addr *addr;
unsigned naddr;
unsigned i;
int port;
int success;
addr = getalladdrs (hostname, &naddr);
if (addr == NULL)
return 1;
port = k_getportbyname ("kauth", "tcp", htons(KAUTH_PORT));
success = 0;
for (i = 0; !success && i < naddr; ++i) {
struct sockaddr_in a;
int s;
memset(&a, 0, sizeof(a));
a.sin_family = AF_INET;
a.sin_port = port;
a.sin_addr = addr[i];
s = socket (AF_INET, SOCK_STREAM, 0);
if (s < 0) {
warn("socket");
return 1;
}
if (connect(s, (struct sockaddr *)&a, sizeof(a)) < 0) {
warn("connect(%s)", hostname);
continue;
}
success = success || !doit_host (princ, lifetime,
locuser, tktfile, key,
s, hostname);
close (s);
}
return !success;
}

View file

@ -0,0 +1,12 @@
#!/bin/sh
#
# @(#) $Id: zrefresh,v 1.3 1996/06/09 19:21:59 joda Exp $
#
# Substitute this script with a real zrefresh if running Zephyr. For
# instance:
#
# if [ -f "$WGFILE" ] ; then
# zctl load
# fi
exit 0

View file

@ -0,0 +1,96 @@
# $Id: Makefile.in,v 1.12 1997/03/23 13:04:03 assar Exp $
SHELL = /bin/sh
srcdir = @srcdir@
VPATH = @srcdir@
CC = @CC@
AR = ar
DEFS = @DEFS@
CFLAGS = @CFLAGS@
LD_FLAGS = @LD_FLAGS@
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
LIBS = @LIBS@
MKINSTALLDIRS = @top_srcdir@/mkinstalldirs
prefix = @prefix@
exec_prefix = @exec_prefix@
libexecdir = @libexecdir@
libdir = @libdir@
bindir = @bindir@
transform=@program_transform_name@
EXECSUFFIX=@EXECSUFFIX@
PROG_BIN = kip$(EXECSUFFIX)
PROG_LIBEXEC = kipd$(EXECSUFFIX)
PROGS = $(PROG_BIN) $(PROG_LIBEXEC)
SOURCES_KIP = kip.c
SOURCES_KIPD = kipd.c
SOURCES_COMMON = common.c
OBJECTS_KIP = kip.o common.o
OBJECTS_KIPD = kipd.o common.o
OBJECTS = $(OBJECTS_KIP) $(OBJECTS_KIPD)
SOURCES = $(SOURCES_KIP) $(SOURCES_KIPD) $(SOURCES_COMMON)
all: $(PROGS)
Wall:
make CFLAGS="-g -Wall -Wno-comment -Wmissing-prototypes -Wmissing-declarations -D__USE_FIXED_PROTOTYPES__"
.c.o:
$(CC) -c $(CPPFLAGS) $(DEFS) -I../../include -I$(srcdir) $(CFLAGS) $<
install: all
$(MKINSTALLDIRS) $(bindir) $(libexecdir)
for x in $(PROG_BIN); do \
$(INSTALL_PROGRAM) $$x $(bindir)/`echo $$x | sed '$(transform)'`; \
done
for x in $(PROG_LIBEXEC); do \
$(INSTALL_PROGRAM) $$x $(libexecdir)/`echo $$x | sed '$(transform)'`; \
done
uninstall:
for x in $(PROG_BIN); do \
rm -f $(bindir)/`echo $$x | sed '$(transform)'`; \
done
for x in $(PROG_LIBEXEC); do \
rm -f $(libexecdir)/`echo $$x | sed '$(transform)'`; \
done
TAGS: $(SOURCES)
etags $(SOURCES)
check:
clean:
rm -f *.a *.o $(PROGS)
mostlyclean: clean
distclean: clean
rm -f Makefile *.tab.c *~
realclean: distclean
rm -f TAGS
dist: $(DISTFILES)
for file in $(DISTFILES); do \
ln $$file ../`cat ../.fname`/lib \
|| cp -p $$file ../`cat ../.fname`/lib; \
done
KLIB=-L../../lib/krb -lkrb -L../../lib/des -ldes
LIBROKEN=-L../../lib/roken -lroken
kip$(EXECSUFFIX): $(OBJECTS_KIP)
$(CC) $(LD_FLAGS) $(LDFLAGS) -o $@ $(OBJECTS_KIP) $(KLIB) $(LIBROKEN) $(LIBS) $(LIBROKEN)
kipd$(EXECSUFFIX): $(OBJECTS_KIPD)
$(CC) $(LD_FLAGS) $(LDFLAGS) -o $@ $(OBJECTS_KIPD) $(KLIB) $(LIBROKEN) $(LIBS) $(LIBROKEN)
$(OBJECTS): ../../include/config.h

View file

@ -0,0 +1,178 @@
/*
* Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Kungliga Tekniska
* Högskolan and its contributors.
*
* 4. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*/
#include "kip.h"
RCSID("$Id: common.c,v 1.12 1997/05/02 14:28:06 assar Exp $");
/*
* Copy packets from `tundev' to `netdev' or vice versa.
* Mode is used when reading from `tundev'
*/
int
copy_packets (int tundev, int netdev, int mtu, des_cblock *iv,
des_key_schedule schedule)
{
des_cblock iv1, iv2;
int num1 = 0, num2 = 0;
u_char *buf;
buf = malloc (mtu + 2);
if (buf == NULL) {
warnx("malloc(%d) failed", mtu);
return 1;
}
memcpy (&iv1, iv, sizeof(iv1));
memcpy (&iv2, iv, sizeof(iv2));
for (;;) {
fd_set fdset;
int ret, len;
FD_ZERO(&fdset);
FD_SET(tundev, &fdset);
FD_SET(netdev, &fdset);
ret = select (max(tundev, netdev)+1, &fdset, NULL, NULL, NULL);
if (ret < 0 && errno != EINTR) {
warn ("select");
return 1;
}
if (FD_ISSET(tundev, &fdset)) {
ret = read (tundev, buf + 2, mtu);
if (ret == 0)
return 0;
if (ret < 0) {
if (errno == EINTR)
continue;
else {
warn("read");
return ret;
}
}
buf[0] = ret >> 8;
buf[1] = ret & 0xFF;
ret += 2;
des_cfb64_encrypt (buf, buf, ret, schedule,
&iv1, &num1, DES_ENCRYPT);
ret = krb_net_write (netdev, buf, ret);
if (ret < 0) {
warn("write");
return ret;
}
}
if (FD_ISSET(netdev, &fdset)) {
ret = read (netdev, buf, 2);
if (ret == 0)
return 0;
if (ret < 0) {
if (errno == EINTR)
continue;
else {
warn("read");
return ret;
}
}
des_cfb64_encrypt (buf, buf, 2, schedule,
&iv2, &num2, DES_DECRYPT);
len = (buf[0] << 8 ) | buf[1];
ret = krb_net_read (netdev, buf + 2, len);
if (ret == 0)
return 0;
if (ret < 0) {
if (errno == EINTR)
continue;
else {
warn("read");
return ret;
}
}
des_cfb64_encrypt (buf + 2, buf + 2, len, schedule,
&iv2, &num2, DES_DECRYPT);
ret = krb_net_write (tundev, buf + 2, len);
if (ret < 0) {
warn("write");
return ret;
}
}
}
}
/*
* Signal handler that justs waits for the children when they die.
*/
RETSIGTYPE
childhandler (int sig)
{
pid_t pid;
int status;
do {
pid = waitpid (-1, &status, WNOHANG|WUNTRACED);
} while(pid > 0);
signal (SIGCHLD, childhandler);
SIGRETURN(0);
}
/*
* Find a free tunnel device and open it.
*/
int
tunnel_open (void)
{
int fd;
int i;
char name[64];
for (i = 0; i < 256; ++i) {
snprintf (name, sizeof(name), "%s%s%d", _PATH_DEV, TUNDEV, i);
fd = open (name, O_RDWR, 0);
if (fd >= 0)
break;
if (errno == ENOENT || errno == ENODEV) {
warn("open %s", name);
return fd;
}
}
if (fd < 0)
warn("open %s" ,name);
return fd;
}

View file

@ -0,0 +1,179 @@
/*
* Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Kungliga Tekniska
* Högskolan and its contributors.
*
* 4. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*/
#include "kip.h"
RCSID("$Id: kip.c,v 1.15 1997/05/11 10:54:51 assar Exp $");
static void
usage()
{
fprintf (stderr, "Usage: %s host\n",
__progname);
exit (1);
}
/*
* Establish authenticated connection
*/
static int
connect_host (char *host, des_cblock *key, des_key_schedule schedule)
{
CREDENTIALS cred;
KTEXT_ST text;
MSG_DAT msg;
int status;
struct sockaddr_in thisaddr, thataddr;
int addrlen;
struct hostent *hostent;
int s;
u_char b;
char **p;
hostent = gethostbyname (host);
if (hostent == NULL) {
warnx ("gethostbyname '%s': %s", host,
#ifdef HAVE_H_ERRNO
hstrerror(h_errno)
#else
"unknown error"
#endif
);
return -1;
}
memset (&thataddr, 0, sizeof(thataddr));
thataddr.sin_family = AF_INET;
thataddr.sin_port = k_getportbyname ("kip", "tcp", htons(KIPPORT));
for(p = hostent->h_addr_list; *p; ++p) {
int one = 1;
memcpy (&thataddr.sin_addr, *p, sizeof(thataddr.sin_addr));
s = socket (AF_INET, SOCK_STREAM, 0);
if (s < 0) {
warn ("socket");
return -1;
}
#if defined(TCP_NODELAY) && defined(HAVE_SETSOCKOPT)
setsockopt (s, IPPROTO_TCP, TCP_NODELAY, (void *)&one, sizeof(one));
#endif
if (connect (s, (struct sockaddr *)&thataddr, sizeof(thataddr)) < 0) {
warn ("connect(%s)", host);
close (s);
continue;
} else {
break;
}
}
if (*p == NULL)
return -1;
addrlen = sizeof(thisaddr);
if (getsockname (s, (struct sockaddr *)&thisaddr, &addrlen) < 0 ||
addrlen != sizeof(thisaddr)) {
warn ("getsockname(%s)", host);
return -1;
}
status = krb_sendauth (KOPT_DO_MUTUAL, s, &text, "rcmd",
host, krb_realmofhost (host),
getpid(), &msg, &cred, schedule,
&thisaddr, &thataddr, KIP_VERSION);
if (status != KSUCCESS) {
warnx("%s: %s", host,
krb_get_err_text(status));
return -1;
}
if (read (s, &b, sizeof(b)) != sizeof(b)) {
warn ("read");
return -1;
}
if (b) {
char buf[BUFSIZ];
read (s, buf, sizeof(buf));
buf[BUFSIZ - 1] = '\0';
warnx ("%s: %s", host, buf);
return -1;
}
memcpy(key, &cred.session, sizeof(des_cblock));
return s;
}
/*
* Connect to the given host.
*/
static int
doit (char *host)
{
des_key_schedule schedule;
des_cblock iv;
int other, this;
struct ifreq ifreq;
int sock;
other = connect_host (host, &iv, schedule);
if (other < 0)
return 1;
this = tunnel_open ();
if (this < 0)
return 1;
return copy_packets (this, other, TUNMTU, &iv, schedule);
}
/*
* kip - forward IP packets over a kerberos-encrypted channel.
*
*/
int
main(int argc, char **argv)
{
set_progname (argv[0]);
if (argc != 2)
usage ();
return doit (argv[1]);
}

View file

@ -0,0 +1,106 @@
/*
* Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Kungliga Tekniska
* Högskolan and its contributors.
*
* 4. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*/
/* $Id: kip.h,v 1.16 1997/05/20 18:40:31 bg Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <pwd.h>
#include <signal.h>
#include <paths.h>
#include <fcntl.h>
#ifdef HAVE_SYSLOG_H
#include <syslog.h>
#endif
#include <sys/types.h>
#ifdef TIME_WITH_SYS_TIME
#include <sys/time.h>
#include <time.h>
#elif defined(HAVE_SYS_TIME_H)
#include <sys/time.h>
#else
#include <time.h>
#endif
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
#endif
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/sockio.h>
#include <net/if.h>
#ifdef HAVE_NET_IF_VAR_H
#include <net/if_var.h>
#endif
#include <net/if_tun.h>
#include <err.h>
#ifdef SOCKS
#include <socks.h>
#endif
#include <krb.h>
#include <roken.h>
#define TUNDEV "tun"
#define KIPPORT 2112
#define KIP_VERSION "KIPSRV.0"
int
copy_packets (int tundev, int netdev, int mtu, des_cblock *iv,
des_key_schedule schedule);
RETSIGTYPE childhandler (int);
int
tunnel_open (void);

View file

@ -0,0 +1,128 @@
/*
* Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. 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.
*
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the Kungliga Tekniska
* Högskolan and its contributors.
*
* 4. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
*/
#include "kip.h"
RCSID("$Id: kipd.c,v 1.13 1997/05/18 20:38:01 assar Exp $");
static int
fatal (int fd, char *s)
{
u_char err = 1;
write (fd, &err, sizeof(err));
write (fd, s, strlen(s)+1);
syslog(LOG_ERR, s);
return err;
}
static int
recv_conn (int sock, des_cblock *key, des_key_schedule schedule,
struct sockaddr_in *retaddr)
{
int status;
KTEXT_ST ticket;
AUTH_DAT auth;
char instance[INST_SZ + 1];
struct sockaddr_in thisaddr, thataddr;
int addrlen;
char version[KRB_SENDAUTH_VLEN + 1];
u_char ok = 0;
struct passwd *passwd;
addrlen = sizeof(thisaddr);
if (getsockname (sock, (struct sockaddr *)&thisaddr, &addrlen) < 0 ||
addrlen != sizeof(thisaddr)) {
return 1;
}
addrlen = sizeof(thataddr);
if (getpeername (sock, (struct sockaddr *)&thataddr, &addrlen) < 0 ||
addrlen != sizeof(thataddr)) {
return 1;
}
k_getsockinst (sock, instance, sizeof(instance));
status = krb_recvauth (KOPT_DO_MUTUAL, sock, &ticket, "rcmd", instance,
&thataddr, &thisaddr, &auth, "", schedule,
version);
if (status != KSUCCESS ||
strncmp(version, KIP_VERSION, KRB_SENDAUTH_VLEN) != 0) {
return 1;
}
passwd = k_getpwnam ("root");
if (passwd == NULL)
return fatal (sock, "Cannot find root");
if (kuserok(&auth, "root") != 0)
return fatal (sock, "Permission denied");
if (write (sock, &ok, sizeof(ok)) != sizeof(ok))
return 1;
memcpy(key, &auth.session, sizeof(des_cblock));
*retaddr = thataddr;
return 0;
}
static int
doit(int sock)
{
struct sockaddr_in thataddr;
des_key_schedule schedule;
des_cblock key;
int this;
if (recv_conn (sock, &key, schedule, &thataddr))
return 1;
this = tunnel_open ();
if (this < 0)
fatal (sock, "Cannot open " _PATH_DEV TUNDEV);
return copy_packets (this, sock, TUNMTU, &key, schedule);
}
/*
* kipd - receive forwarded IP
*/
int
main (int argc, char **argv)
{
set_progname (argv[0]);
openlog(__progname, LOG_PID|LOG_CONS, LOG_DAEMON);
signal (SIGCHLD, childhandler);
return doit(0);
}

696
crypto/kerberosIV/config.guess vendored Normal file
View file

@ -0,0 +1,696 @@
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 93, 94, 95, 1996 Free Software Foundation, Inc.
#
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Written by Per Bothner <bothner@cygnus.com>.
# The master version of this file is at the FSF in /home/gd/gnu/lib.
#
# This script attempts to guess a canonical system name similar to
# config.sub. If it succeeds, it prints the system name on stdout, and
# exits with 0. Otherwise, it exits with 1.
#
# The plan is that this can be called by configure scripts if you
# don't specify an explicit system type (host/target name).
#
# Only a few systems have been added to this list; please add others
# (but try to keep the structure clean).
#
# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
# (ghazi@noc.rutgers.edu 8/24/94.)
if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
PATH=$PATH:/.attbin ; export PATH
fi
UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15
# Note: order is significant - the case branches are not exclusive.
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
alpha:OSF1:*:*)
# A Vn.n version is a released version.
# A Tn.n version is a released field test version.
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
echo alpha-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//'`
exit 0 ;;
21064:Windows_NT:50:3)
echo alpha-dec-winnt3.5
exit 0 ;;
Amiga*:UNIX_System_V:4.0:*)
echo m68k-cbm-sysv4
exit 0;;
amiga:NetBSD:*:*)
echo m68k-cbm-netbsd${UNAME_RELEASE}
exit 0 ;;
amiga:OpenBSD:*:*)
echo m68k-cbm-openbsd${UNAME_RELEASE}
exit 0 ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
echo arm-acorn-riscix${UNAME_RELEASE}
exit 0;;
Pyramid*:OSx*:*:*|MIS*:OSx*:*:*)
# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
if test "`(/bin/universe) 2>/dev/null`" = att ; then
echo pyramid-pyramid-sysv3
else
echo pyramid-pyramid-bsd
fi
exit 0 ;;
NILE:*:*:dcosx)
echo pyramid-pyramid-svr4
exit 0 ;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
i86pc:SunOS:5.*:*)
echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
# SunOS6. Hard to guess exactly what SunOS6 will be like, but
# it's likely to be more like Solaris than SunOS4.
echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
sun4*:SunOS:*:*)
case "`/usr/bin/arch -k`" in
Series*|S4*)
UNAME_RELEASE=`uname -v`
;;
esac
# Japanese Language versions have a version number like `4.1.3-JL'.
echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
exit 0 ;;
sun3*:SunOS:*:*)
echo m68k-sun-sunos${UNAME_RELEASE}
exit 0 ;;
aushp:SunOS:*:*)
echo sparc-auspex-sunos${UNAME_RELEASE}
exit 0 ;;
atari*:NetBSD:*:*)
echo m68k-atari-netbsd${UNAME_RELEASE}
exit 0 ;;
atari*:OpenBSD:*:*)
echo m68k-atari-openbsd${UNAME_RELEASE}
exit 0 ;;
sun3*:NetBSD:*:*)
echo m68k-sun-netbsd${UNAME_RELEASE}
exit 0 ;;
sun3*:OpenBSD:*:*)
echo m68k-sun-openbsd${UNAME_RELEASE}
exit 0 ;;
mac68k:NetBSD:*:*)
echo m68k-apple-netbsd${UNAME_RELEASE}
exit 0 ;;
mac68k:OpenBSD:*:*)
echo m68k-apple-openbsd${UNAME_RELEASE}
exit 0 ;;
powerpc:machten:*:*)
echo powerpc-apple-machten${UNAME_RELEASE}
exit 0 ;;
RISC*:Mach:*:*)
echo mips-dec-mach_bsd4.3
exit 0 ;;
RISC*:ULTRIX:*:*)
echo mips-dec-ultrix${UNAME_RELEASE}
exit 0 ;;
VAX*:ULTRIX*:*:*)
echo vax-dec-ultrix${UNAME_RELEASE}
exit 0 ;;
mips:*:*:UMIPS | mips:*:*:RISCos)
sed 's/^ //' << EOF >dummy.c
int main (argc, argv) int argc; char **argv; {
#if defined (host_mips) && defined (MIPSEB)
#if defined (SYSTYPE_SYSV)
printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
#endif
#if defined (SYSTYPE_SVR4)
printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
#endif
#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
#endif
#endif
exit (-1);
}
EOF
${CC-cc} dummy.c -o dummy \
&& ./dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
&& rm dummy.c dummy && exit 0
rm -f dummy.c dummy
echo mips-mips-riscos${UNAME_RELEASE}
exit 0 ;;
Night_Hawk:Power_UNIX:*:*)
echo powerpc-harris-powerunix
exit 0 ;;
m88k:CX/UX:7*:*)
echo m88k-harris-cxux7
exit 0 ;;
m88k:*:4*:R4*)
echo m88k-motorola-sysv4
exit 0 ;;
m88k:*:3*:R3*)
echo m88k-motorola-sysv3
exit 0 ;;
AViiON:dgux:*:*)
# DG/UX returns AViiON for all architectures
UNAME_PROCESSOR=`/usr/bin/uname -p`
if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \
-o ${TARGET_BINARY_INTERFACE}x = x ] ; then
echo m88k-dg-dgux${UNAME_RELEASE}
else
echo m88k-dg-dguxbcs${UNAME_RELEASE}
fi
else echo i586-dg-dgux${UNAME_RELEASE}
fi
exit 0 ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
echo m88k-dolphin-sysv3
exit 0 ;;
M88*:*:R3*:*)
# Delta 88k system running SVR3
echo m88k-motorola-sysv3
exit 0 ;;
XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
echo m88k-tektronix-sysv3
exit 0 ;;
Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
echo m68k-tektronix-bsd
exit 0 ;;
*:IRIX*:*:*)
echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
exit 0 ;;
????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
i?86:AIX:*:*)
echo i386-ibm-aix
exit 0 ;;
*:AIX:2:3)
if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
sed 's/^ //' << EOF >dummy.c
#include <sys/systemcfg.h>
main()
{
if (!__power_pc())
exit(1);
puts("powerpc-ibm-aix3.2.5");
exit(0);
}
EOF
${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
rm -f dummy.c dummy
echo rs6000-ibm-aix3.2.5
elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
echo rs6000-ibm-aix3.2.4
else
echo rs6000-ibm-aix3.2
fi
exit 0 ;;
*:AIX:*:4)
if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then
IBM_ARCH=rs6000
else
IBM_ARCH=powerpc
fi
if [ -x /usr/bin/oslevel ] ; then
IBM_REV=`/usr/bin/oslevel`
else
IBM_REV=4.${UNAME_RELEASE}
fi
echo ${IBM_ARCH}-ibm-aix${IBM_REV}
exit 0 ;;
*:AIX:*:*)
echo rs6000-ibm-aix
exit 0 ;;
ibmrt:4.4BSD:*|romp-ibm:BSD:*)
echo romp-ibm-bsd4.4
exit 0 ;;
ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and
echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
exit 0 ;; # report: romp-ibm BSD 4.3
*:BOSX:*:*)
echo rs6000-bull-bosx
exit 0 ;;
DPX/2?00:B.O.S.:*:*)
echo m68k-bull-sysv3
exit 0 ;;
9000/[34]??:4.3bsd:1.*:*)
echo m68k-hp-bsd
exit 0 ;;
hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
echo m68k-hp-bsd4.4
exit 0 ;;
9000/[3478]??:HP-UX:*:*)
case "${UNAME_MACHINE}" in
9000/31? ) HP_ARCH=m68000 ;;
9000/[34]?? ) HP_ARCH=m68k ;;
9000/7?? | 9000/8?[1679] ) HP_ARCH=hppa1.1 ;;
9000/8?? ) HP_ARCH=hppa1.0 ;;
esac
HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
echo ${HP_ARCH}-hp-hpux${HPUX_REV}
exit 0 ;;
3050*:HI-UX:*:*)
sed 's/^ //' << EOF >dummy.c
#include <unistd.h>
int
main ()
{
long cpu = sysconf (_SC_CPU_VERSION);
/* The order matters, because CPU_IS_HP_MC68K erroneously returns
true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
results, however. */
if (CPU_IS_PA_RISC (cpu))
{
switch (cpu)
{
case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
default: puts ("hppa-hitachi-hiuxwe2"); break;
}
}
else if (CPU_IS_HP_MC68K (cpu))
puts ("m68k-hitachi-hiuxwe2");
else puts ("unknown-hitachi-hiuxwe2");
exit (0);
}
EOF
${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
rm -f dummy.c dummy
echo unknown-hitachi-hiuxwe2
exit 0 ;;
9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
echo hppa1.1-hp-bsd
exit 0 ;;
9000/8??:4.3bsd:*:*)
echo hppa1.0-hp-bsd
exit 0 ;;
hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
echo hppa1.1-hp-osf
exit 0 ;;
hp8??:OSF1:*:*)
echo hppa1.0-hp-osf
exit 0 ;;
i?86:OSF1:*:*)
if [ -x /usr/sbin/sysversion ] ; then
echo ${UNAME_MACHINE}-unknown-osf1mk
else
echo ${UNAME_MACHINE}-unknown-osf1
fi
exit 0 ;;
parisc*:Lites*:*:*)
echo hppa1.1-hp-lites
exit 0 ;;
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
echo c1-convex-bsd
exit 0 ;;
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
else echo c2-convex-bsd
fi
exit 0 ;;
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
echo c34-convex-bsd
exit 0 ;;
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
echo c38-convex-bsd
exit 0 ;;
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
echo c4-convex-bsd
exit 0 ;;
CRAY*X-MP:*:*:*)
echo xmp-cray-unicos
exit 0 ;;
CRAY*Y-MP:*:*:*)
echo ymp-cray-unicos${UNAME_RELEASE}
exit 0 ;;
CRAY*[A-Z]90:*:*:*)
echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
-e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
exit 0 ;;
CRAY*TS:*:*:*)
echo t90-cray-unicos${UNAME_RELEASE}
exit 0 ;;
CRAY-2:*:*:*)
echo cray2-cray-unicos
exit 0 ;;
F300:UNIX_System_V:*:*)
FUJITSU_SYS=`uname -p | tr [A-Z] [a-z] | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit 0 ;;
F301:UNIX_System_V:*:*)
echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'`
exit 0 ;;
hp3[0-9][05]:NetBSD:*:*)
echo m68k-hp-netbsd${UNAME_RELEASE}
exit 0 ;;
hp3[0-9][05]:OpenBSD:*:*)
echo m68k-hp-openbsd${UNAME_RELEASE}
exit 0 ;;
i?86:BSD/386:*:* | *:BSD/OS:*:*)
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
exit 0 ;;
*:FreeBSD:*:*)
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
exit 0 ;;
*:NetBSD:*:*)
echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
exit 0 ;;
*:OpenBSD:*:*)
echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
exit 0 ;;
i*:CYGWIN*:*)
echo i386-pc-cygwin32
exit 0 ;;
p*:CYGWIN*:*)
echo powerpcle-unknown-cygwin32
exit 0 ;;
prep*:SunOS:5.*:*)
echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
*:GNU:*:*)
echo `echo ${UNAME_MACHINE}|sed -e 's,/.*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
exit 0 ;;
*:Linux:*:*)
# The BFD linker knows what the default object file format is, so
# first see if it will tell us.
ld_help_string=`ld --help 2>&1`
if echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: elf_i.86"; then
echo "${UNAME_MACHINE}-pc-linux-gnu" ; exit 0
elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: i.86linux"; then
echo "${UNAME_MACHINE}-pc-linux-gnuaout" ; exit 0
elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: i.86coff"; then
echo "${UNAME_MACHINE}-pc-linux-gnucoff" ; exit 0
elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: m68kelf"; then
echo "${UNAME_MACHINE}-unknown-linux-gnu" ; exit 0
elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: m68klinux"; then
echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0
elif echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations: elf32ppc"; then
echo "powerpc-unknown-linux-gnu" ; exit 0
elif test "${UNAME_MACHINE}" = "alpha" ; then
echo alpha-unknown-linux-gnu ; exit 0
elif test "${UNAME_MACHINE}" = "sparc" ; then
echo sparc-unknown-linux-gnu ; exit 0
else
# Either a pre-BFD a.out linker (linux-gnuoldld) or one that does not give us
# useful --help. Gcc wants to distinguish between linux-gnuoldld and linux-gnuaout.
test ! -d /usr/lib/ldscripts/. \
&& echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0
# Determine whether the default compiler is a.out or elf
cat >dummy.c <<EOF
main(argc, argv)
int argc;
char *argv[];
{
#ifdef __ELF__
printf ("%s-pc-linux-gnu\n", argv[1]);
#else
printf ("%s-pc-linux-gnuaout\n", argv[1]);
#endif
return 0;
}
EOF
${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
rm -f dummy.c dummy
fi ;;
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions
# are messed up and put the nodename in both sysname and nodename.
i?86:DYNIX/ptx:4*:*)
echo i386-sequent-sysv4
exit 0 ;;
i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*)
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE}
else
echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
fi
exit 0 ;;
i?86:*:3.2:*)
if test -f /usr/options/cb.name; then
UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
elif /bin/uname -X 2>/dev/null >/dev/null ; then
UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
(/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
(/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
&& UNAME_MACHINE=i586
echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
else
echo ${UNAME_MACHINE}-pc-sysv32
fi
exit 0 ;;
Intel:Mach:3*:*)
echo i386-pc-mach3
exit 0 ;;
paragon:*:*:*)
echo i860-intel-osf1
exit 0 ;;
i860:*:4.*:*) # i860-SVR4
if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
else # Add other i860-SVR4 vendors below as they are discovered.
echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
fi
exit 0 ;;
mini*:CTIX:SYS*5:*)
# "miniframe"
echo m68010-convergent-sysv
exit 0 ;;
M68*:*:R3V[567]*:*)
test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
OS_REL=''
test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& echo i486-ncr-sysv4.3${OS_REL} && exit 0
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
&& echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& echo i486-ncr-sysv4 && exit 0 ;;
m68*:LynxOS:2.*:*)
echo m68k-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
mc68030:UNIX_System_V:4.*:*)
echo m68k-atari-sysv4
exit 0 ;;
i?86:LynxOS:2.*:*)
echo i386-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
TSUNAMI:LynxOS:2.*:*)
echo sparc-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*)
echo rs6000-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
SM[BE]S:UNIX_SV:*:*)
echo mips-dde-sysv${UNAME_RELEASE}
exit 0 ;;
RM*:SINIX-*:*:*)
echo mips-sni-sysv4
exit 0 ;;
*:SINIX-*:*:*)
if uname -p 2>/dev/null >/dev/null ; then
UNAME_MACHINE=`(uname -p) 2>/dev/null`
echo ${UNAME_MACHINE}-sni-sysv4
else
echo ns32k-sni-sysv
fi
exit 0 ;;
*:UNIX_System_V:4*:FTX*)
# From Gerald Hewes <hewes@openmarket.com>.
# How about differentiating between stratus architectures? -djm
echo hppa1.1-stratus-sysv4
exit 0 ;;
*:*:*:FTX*)
# From seanf@swdc.stratus.com.
echo i860-stratus-sysv4
exit 0 ;;
mc68*:A/UX:*:*)
echo m68k-apple-aux${UNAME_RELEASE}
exit 0 ;;
R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:*)
if [ -d /usr/nec ]; then
echo mips-nec-sysv${UNAME_RELEASE}
else
echo mips-unknown-sysv${UNAME_RELEASE}
fi
exit 0 ;;
PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
# says <Richard.M.Bartel@ccMail.Census.GOV>
echo i586-unisys-sysv4
exit 0 ;;
*:OS/2:*:*)
echo ${UNAME_MACHINE}-pc-os2_emx
exit 0 ;;
esac
#echo '(No uname command or uname output not recognized.)' 1>&2
#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
cat >dummy.c <<EOF
#ifdef _SEQUENT_
# include <sys/types.h>
# include <sys/utsname.h>
#endif
main ()
{
#if defined (sony)
#if defined (MIPSEB)
/* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
I don't know.... */
printf ("mips-sony-bsd\n"); exit (0);
#else
#include <sys/param.h>
printf ("m68k-sony-newsos%s\n",
#ifdef NEWSOS4
"4"
#else
""
#endif
); exit (0);
#endif
#endif
#if defined (__arm) && defined (__acorn) && defined (__unix)
printf ("arm-acorn-riscix"); exit (0);
#endif
#if defined (hp300) && !defined (hpux)
printf ("m68k-hp-bsd\n"); exit (0);
#endif
#if defined (NeXT)
#if !defined (__ARCHITECTURE__)
#define __ARCHITECTURE__ "m68k"
#endif
int version;
version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
exit (0);
#endif
#if defined (MULTIMAX) || defined (n16)
#if defined (UMAXV)
printf ("ns32k-encore-sysv\n"); exit (0);
#else
#if defined (CMU)
printf ("ns32k-encore-mach\n"); exit (0);
#else
printf ("ns32k-encore-bsd\n"); exit (0);
#endif
#endif
#endif
#if defined (__386BSD__)
printf ("i386-pc-bsd\n"); exit (0);
#endif
#if defined (sequent)
#if defined (i386)
printf ("i386-sequent-dynix\n"); exit (0);
#endif
#if defined (ns32000)
printf ("ns32k-sequent-dynix\n"); exit (0);
#endif
#endif
#if defined (_SEQUENT_)
struct utsname un;
uname(&un);
if (strncmp(un.version, "V2", 2) == 0) {
printf ("i386-sequent-ptx2\n"); exit (0);
}
if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
printf ("i386-sequent-ptx1\n"); exit (0);
}
printf ("i386-sequent-ptx\n"); exit (0);
#endif
#if defined (vax)
#if !defined (ultrix)
printf ("vax-dec-bsd\n"); exit (0);
#else
printf ("vax-dec-ultrix\n"); exit (0);
#endif
#endif
#if defined (alliant) && defined (i860)
printf ("i860-alliant-bsd\n"); exit (0);
#endif
exit (1);
}
EOF
${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0
rm -f dummy.c dummy
# Apollos put the system type in the environment.
test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
# Convex versions that predate uname can use getsysinfo(1)
if [ -x /usr/convex/getsysinfo ]
then
case `getsysinfo -f cpu_type` in
c1*)
echo c1-convex-bsd
exit 0 ;;
c2*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
else echo c2-convex-bsd
fi
exit 0 ;;
c34*)
echo c34-convex-bsd
exit 0 ;;
c38*)
echo c38-convex-bsd
exit 0 ;;
c4*)
echo c4-convex-bsd
exit 0 ;;
esac
fi
#echo '(Unable to guess system type)' 1>&2
exit 1

Some files were not shown because too many files have changed in this diff Show more