From 4e762ae71a675489e308ef67b9c4f35fa31042da Mon Sep 17 00:00:00 2001 From: Alexander Pyhalov Date: Thu, 7 Aug 2014 16:04:33 +0400 Subject: [PATCH] 5069 Removal of wu-ftpd Reviewed by: Josef 'Jeff' Sipek Reviewed by: Garrett D'Amore Reviewed by: Milan Jurik Reviewed by: Igor Kozhukhov Reviewed by: Gary Mills Reviewed by: Toomas Soome Reviewed by: Adam Stevko Approved by: Robert Mustacchi --- usr/src/cmd/Adm/sun/Makefile | 13 +- .../usr.sbin/in.ftpd => Adm/sun}/ftpusers | 0 usr/src/cmd/Makefile.check | 1 - usr/src/cmd/Makefile.cmd | 4 + usr/src/cmd/cmd-inet/usr.sbin/Makefile | 4 +- usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/COPYRIGHT.c | 69 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/LICENSE | 157 - .../cmd/cmd-inet/usr.sbin/in.ftpd/LICENSE.descrip | 1 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/Makefile | 122 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/access.c | 1531 ---- usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/acl.c | 195 - .../cmd/cmd-inet/usr.sbin/in.ftpd/authenticate.c | 78 - .../cmd/cmd-inet/usr.sbin/in.ftpd/authenticate.h | 40 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/authuser.h | 39 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ckconfig.c | 186 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/config.h | 268 - .../cmd/cmd-inet/usr.sbin/in.ftpd/conversions.c | 198 - .../cmd/cmd-inet/usr.sbin/in.ftpd/conversions.h | 45 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/domain.c | 324 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/extensions.c | 2365 ------ usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/extensions.h | 174 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftp.xml | 86 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpaccess | 58 - .../cmd/cmd-inet/usr.sbin/in.ftpd/ftpaddhost.sh | 319 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpcmd.y | 2523 ------ usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpconfig.sh | 394 - .../cmd/cmd-inet/usr.sbin/in.ftpd/ftpconversions | 14 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpcount.c | 544 -- usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpd.c | 8026 -------------------- usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpgroups | 4 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftphosts | 4 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftprestart.c | 343 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpservers | 4 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpshut.c | 511 -- usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/getpwnam.c | 158 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/getpwnam.h | 25 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/glob.c | 694 -- usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/gssutil.c | 1299 ---- usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/gssutil.h | 74 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/hostacc.c | 359 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/hostacc.h | 82 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/inet.c | 233 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/logwtmp.c | 198 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/pathnames.h | 152 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/paths.c | 250 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/popen.c | 324 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/private.c | 335 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/privatepw.c | 392 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/privs.c | 265 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/proto.h | 338 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/rdservers.c | 107 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/realpath.c | 361 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/restrict.c | 191 - .../cmd/cmd-inet/usr.sbin/in.ftpd/routevector.c | 292 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/svc-ftp | 62 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/timeout.c | 72 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/vers.c | 3 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/wu_config.h | 338 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/wu_fnmatch.c | 206 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/wu_fnmatch.h | 39 - usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/xferlog.c | 52 - usr/src/cmd/svc/profile/generic_limited_net.xml | 3 - usr/src/cmd/svc/profile/inetd_generic.xml | 3 - usr/src/man/man1/Makefile | 2 - usr/src/man/man1/ftp.1 | 14 +- usr/src/man/man1/ftpcount.1 | 101 - usr/src/man/man1/ftpwho.1 | 101 - usr/src/man/man1m/Makefile | 7 - usr/src/man/man1m/ftpaddhost.1m | 160 - usr/src/man/man1m/ftpconfig.1m | 118 - usr/src/man/man1m/ftprestart.1m | 116 - usr/src/man/man1m/ftpshut.1m | 287 - usr/src/man/man1m/in.ftpd.1m | 1230 --- usr/src/man/man1m/mknod.1m | 8 +- usr/src/man/man1m/sftp-server.1m | 8 +- usr/src/man/man3c/syslog.3c | 9 +- usr/src/man/man4/Makefile | 6 - usr/src/man/man4/ftpaccess.4 | 2086 ----- usr/src/man/man4/ftpconversions.4 | 254 - usr/src/man/man4/ftpgroups.4 | 111 - usr/src/man/man4/ftphosts.4 | 107 - usr/src/man/man4/ftpservers.4 | 177 - usr/src/man/man4/ftpusers.4 | 6 +- usr/src/man/man4/netrc.4 | 5 +- usr/src/man/man4/pam.conf.4 | 9 +- usr/src/man/man4/passwd.4 | 5 +- usr/src/man/man4/syslog.conf.4 | 5 - usr/src/man/man4/xferlog.4 | 433 -- usr/src/pkg/manifests/SUNWcs.man4.inc | 1 + usr/src/pkg/manifests/SUNWcs.mf | 3 +- usr/src/pkg/manifests/SUNWftp.mf | 6 +- usr/src/pkg/manifests/network-ftp.mf | 1 + .../{SUNWftp.mf => service-network-ftp.mf} | 7 +- 93 files changed, 38 insertions(+), 30896 deletions(-) rename usr/src/cmd/{cmd-inet/usr.sbin/in.ftpd => Adm/sun}/ftpusers (100%) delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/COPYRIGHT.c delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/LICENSE delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/LICENSE.descrip delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/Makefile delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/access.c delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/acl.c delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/authenticate.c delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/authenticate.h delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/authuser.h delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ckconfig.c delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/config.h delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/conversions.c delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/conversions.h delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/domain.c delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/extensions.c delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/extensions.h delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftp.xml delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpaccess delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpaddhost.sh delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpcmd.y delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpconfig.sh delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpconversions delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpcount.c delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpd.c delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpgroups delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftphosts delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftprestart.c delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpservers delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpshut.c delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/getpwnam.c delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/getpwnam.h delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/glob.c delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/gssutil.c delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/gssutil.h delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/hostacc.c delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/hostacc.h delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/inet.c delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/logwtmp.c delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/pathnames.h delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/paths.c delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/popen.c delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/private.c delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/privatepw.c delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/privs.c delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/proto.h delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/rdservers.c delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/realpath.c delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/restrict.c delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/routevector.c delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/svc-ftp delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/timeout.c delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/vers.c delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/wu_config.h delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/wu_fnmatch.c delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/wu_fnmatch.h delete mode 100644 usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/xferlog.c delete mode 100644 usr/src/man/man1/ftpcount.1 delete mode 100644 usr/src/man/man1/ftpwho.1 delete mode 100644 usr/src/man/man1m/ftpaddhost.1m delete mode 100644 usr/src/man/man1m/ftpconfig.1m delete mode 100644 usr/src/man/man1m/ftprestart.1m delete mode 100644 usr/src/man/man1m/ftpshut.1m delete mode 100644 usr/src/man/man1m/in.ftpd.1m delete mode 100644 usr/src/man/man4/ftpaccess.4 delete mode 100644 usr/src/man/man4/ftpconversions.4 delete mode 100644 usr/src/man/man4/ftpgroups.4 delete mode 100644 usr/src/man/man4/ftphosts.4 delete mode 100644 usr/src/man/man4/ftpservers.4 delete mode 100644 usr/src/man/man4/xferlog.4 copy usr/src/pkg/manifests/{SUNWftp.mf => service-network-ftp.mf} (82%) diff --git a/usr/src/cmd/Adm/sun/Makefile b/usr/src/cmd/Adm/sun/Makefile index bf80bdba30..5ab4546cb4 100644 --- a/usr/src/cmd/Adm/sun/Makefile +++ b/usr/src/cmd/Adm/sun/Makefile @@ -24,27 +24,36 @@ # ETCFILES= ioctl.syscon passwd shadow motd +FTPDFILES= ftpusers KVMFILES= README SMBFILES= smbpasswd include ../../Makefile.cmd ROOTETCFILES= $(ETCFILES:%=$(ROOTETC)/%) +ROOTETCFTPDFILES= $(FTPDFILES:%=$(ROOTETCFTPD)/%) ROOTUSRKVMFILES= $(KVMFILES:%=$(ROOTUSRKVM)/%) ROOTVARSMBFILES= $(SMBFILES:%=$(ROOTVARSMB)/%) FILEMODE= 0644 +ROOTETCFTPUSERSLINK= $(ROOTETC)/ftpusers + $(ROOTETC)/shadow := FILEMODE = 400 $(ROOTVARSMB)/smbpasswd := FILEMODE = 0400 + .KEEP_STATE: -all: $(ETCFILES) $(KVMFILES) $(SMBFILES) +$(ROOTETCFTPUSERSLINK): $(ROOTETCFTPDFILES) + $(SYMLINK) ftpd/ftpusers $@ + +all: $(ETCFILES) $(KVMFILES) $(SMBFILES) $(FTPDFILES) -install: all $(ROOTETCFILES) $(ROOTUSRKVMFILES) $(ROOTVARSMBFILES) +install: all $(ROOTETCFILES) $(ROOTETCFTPDFILES) $(ROOTUSRKVMFILES) $(ROOTVARSMBFILES) $(ROOTETCFTPUSERSLINK) clean: + $(RM) $(ROOTETCFTPUSERSLINK) lint: diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpusers b/usr/src/cmd/Adm/sun/ftpusers similarity index 100% rename from usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpusers rename to usr/src/cmd/Adm/sun/ftpusers diff --git a/usr/src/cmd/Makefile.check b/usr/src/cmd/Makefile.check index 5cd0b89828..784cc6855f 100644 --- a/usr/src/cmd/Makefile.check +++ b/usr/src/cmd/Makefile.check @@ -94,7 +94,6 @@ MANIFEST_SUBDIRS= \ cmd-inet/usr.lib/vrrpd \ cmd-inet/usr.lib/wpad \ cmd-inet/usr.sbin \ - cmd-inet/usr.sbin/in.ftpd \ cmd-inet/usr.sbin/in.rdisc \ cmd-inet/usr.sbin/in.routed \ cmd-inet/usr.sbin/in.talkd \ diff --git a/usr/src/cmd/Makefile.cmd b/usr/src/cmd/Makefile.cmd index 35fa6c4586..758369b377 100644 --- a/usr/src/cmd/Makefile.cmd +++ b/usr/src/cmd/Makefile.cmd @@ -69,6 +69,7 @@ ROOTETCTSOL= $(ROOTETCSECURITY)/tsol ROOTETCSECLIB= $(ROOTETCSECURITY)/lib ROOTETCZONES= $(ROOTETC)/zones +ROOTETCFTPD= $(ROOT)/etc/ftpd ROOTETCINET= $(ROOT)/etc/inet ROOTCCSBIN= $(ROOT)/usr/ccs/bin ROOTCCSBIN64= $(ROOTCCSBIN)/$(MACH64) @@ -331,6 +332,9 @@ $(ROOTUSRSBIN64)/%: % $(ROOTETC)/%: % $(INS.file) +$(ROOTETCFTPD)/%: % + $(INS.file) + $(ROOTETCINET)/%: % $(INS.file) diff --git a/usr/src/cmd/cmd-inet/usr.sbin/Makefile b/usr/src/cmd/cmd-inet/usr.sbin/Makefile index 0d2599827c..de4e8236d9 100644 --- a/usr/src/cmd/cmd-inet/usr.sbin/Makefile +++ b/usr/src/cmd/cmd-inet/usr.sbin/Makefile @@ -61,12 +61,12 @@ K5RSHDOBJS= in.rshd.o K5TELNETOBJS= in.telnetd.o SRCS= $(PROGSRCS) $(OTHERSRC) -SUBDIRS= bootconfchk htable ifconfig ilbadm in.ftpd in.rdisc in.routed \ +SUBDIRS= bootconfchk htable ifconfig ilbadm in.rdisc in.routed \ in.talkd inetadm inetconv ipadm ipmpstat ipqosconf ipsecutils \ kssl/kssladm kssl/ksslcfg nwamadm nwamcfg ping routeadm \ snoop sppptun traceroute wificonfig -MSGSUBDIRS= bootconfchk htable ifconfig ilbadm in.ftpd in.routed in.talkd \ +MSGSUBDIRS= bootconfchk htable ifconfig ilbadm in.routed in.talkd \ inetadm inetconv ipadm ipmpstat ipqosconf ipsecutils \ kssl/ksslcfg nwamadm nwamcfg routeadm sppptun snoop wificonfig diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/COPYRIGHT.c b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/COPYRIGHT.c deleted file mode 100644 index 694914f1a4..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/COPYRIGHT.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2001-2003 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/**************************************************************************** - - Copyright (c) 1999,2000 WU-FTPD Development Group. - All rights reserved. - - Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 - The Regents of the University of California. - Portions Copyright (c) 1993, 1994 Washington University in Saint Louis. - Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc. - Portions Copyright (c) 1989 Massachusetts Institute of Technology. - Portions Copyright (c) 1998 Sendmail, Inc. - Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman. - Portions Copyright (c) 1997 by Stan Barber. - Portions Copyright (c) 1997 by Kent Landfield. - Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 - Free Software Foundation, Inc. - - Use and distribution of this software and its source code are governed - by the terms and conditions of the WU-FTPD Software License ("LICENSE"). - - If you did not receive a copy of the license, it may be obtained online - at http://www.wu-ftpd.org/license.html. - - $Id: COPYRIGHT.c,v 1.7 2000/07/01 18:46:31 wuftpd Exp $ - -****************************************************************************/ - -#include - -void print_copyright(void); -extern char version[]; - -char *Copyright = "\n\ - Copyright (c) 1999,2000 WU-FTPD Development Group.\n\ - All rights reserved.\n\ -\n\ - Copyright 2001-2003 Sun Microsystems, Inc. All rights reserved.\n\ - Use is subject to license terms.\n\ -\n\ - Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994\n\ - The Regents of the University of California.\n\ - Portions Copyright (c) 1993, 1994 Washington University in Saint Louis.\n\ - Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc.\n\ - Portions Copyright (c) 1989 Massachusetts Institute of Technology.\n\ - Portions Copyright (c) 1998 Sendmail, Inc.\n\ - Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman.\n\ - Portions Copyright (c) 1997 by Stan Barber.\n\ - Portions Copyright (c) 1997 by Kent Landfield.\n\ - Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997\n\ - Free Software Foundation, Inc. \n\ -\n\ - Use and distribution of this software and its source code are governed \n\ - by the terms and conditions of the WU-FTPD Software License (\"LICENSE\").\n\ -\n\ - If you did not receive a copy of the license, it may be obtained online\n\ - at http://www.wu-ftpd.org/license.html.\n"; - -void print_copyright(void) -{ - printf("%s\n", Copyright); - printf("%s\n", version); -} diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/LICENSE b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/LICENSE deleted file mode 100644 index c70e53ec89..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/LICENSE +++ /dev/null @@ -1,157 +0,0 @@ -Copyright (c) 1999,2000,2001 WU-FTPD Development Group. All rights reserved. - - - WU-FTPD SOFTWARE LICENSE - -Use, modification, or redistribution (including distribution of any modified -or derived work) in any form, or on any medium, is permitted only if all the -following conditions are met: - -1. Redistributions qualify as "freeware" or "Open Source Software" under - the following terms: - - a. Redistributions are made at no charge beyond the reasonable cost - of materials and delivery. Where redistribution of this software - is as part of a larger package or combined work, this restriction - applies only to the costs of materials and delivery of this - software, not to any other costs associated with the larger package - or combined work. - - b. Redistributions are accompanied by a copy of the Source Code or by - an irrevocable offer to provide a copy of the Source Code for up - to three years at the cost of materials and delivery. Such - redistributions must allow further use, modification, and - redistribution of the Source Code under substantially the same - terms as this license. For the purposes of redistribution "Source - Code" means all files included in the original distribution, - including all modifications or additions, on a medium and in a - form allowing fully working executable programs to be produced. - -2. Redistributions of Source Code must retain the copyright notices as - they appear in each Source Code file and the COPYRIGHT file, these - license terms, and the disclaimer/limitation of liability set forth as - paragraph 6 below. - -3. Redistributions in binary form must reproduce the Copyright Notice, - these license terms, and the disclaimer/limitation of liability set - forth as paragraph 6 below, in the documentation and/or other materials - provided with the distribution. For the purposes of binary distribution - the "Copyright Notice" refers to the following language: - - Copyright (c) 1999,2000 WU-FTPD Development Group. - All rights reserved. - - Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 - The Regents of the University of California. - Portions Copyright (c) 1993, 1994 Washington University in Saint Louis. - Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc. - Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman. - Portions Copyright (c) 1998 Sendmail, Inc. - Portions Copyright (c) 1989 Massachusetts Institute of Technology. - Portions Copyright (c) 1997 Stan Barber. - Portions Copyright (c) 1997 Kent Landfield. - Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 - Free Software Foundation, Inc. - - Use and distribution of this software and its source code are - governed by the terms and conditions of the WU-FTPD Software - License ("LICENSE"). - - If you did not receive a copy of the license, it may be - obtained online at http://www.wu-ftpd.org/license.html - -4. All advertising materials mentioning features or use of this software - must display the following acknowledgement: "This product includes - software developed by the WU-FTPD Development Group, the Washington - University at Saint Louis, Berkeley Software Design, Inc., and their - contributors." - -5. Neither the name of the WU-FTPD Development Group, nor the names of any - copyright holders, nor the names of any contributors may be used to - endorse or promote products derived from this software without specific - prior written permission. The names "wuftpd" and "wu-ftpd" are - trademarks of the WU-FTPD Development Group and the Washington - University at Saint Louis. - -6. Disclaimer/Limitation of Liability: - - THIS SOFTWARE IS PROVIDED BY THE WU-FTPD DEVELOPMENT GROUP, THE - COPYRIGHT HOLDERS, AND CONTRIBUTORS, "AS IS" AND ANY EXPRESS OR IMPLIED - WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN - NO EVENT SHALL THE WU-FTPD DEVELOPMENT GROUP, THE COPYRIGHT HOLDERS, 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 DAMAGES. - -7. USE, MODIFICATION, OR REDISTRIBUTION, OF THIS SOFTWARE IMPLIES - ACCEPTANCE OF ALL TERMS AND CONDITIONS OF THIS LICENSE. - -$Id: LICENSE,v 1.4 2000/07/01 17:42:15 wuftpd Exp $ - - -Copyright (c) 1993, 1994 Washington University in Saint Louis -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 - Washington University in Saint Louis 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 WASHINGTON UNIVERSITY 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 WASHINGTON - UNIVERSITY 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) 1980, 1983, 1985, 1988, 1989, 1990 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. diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/LICENSE.descrip b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/LICENSE.descrip deleted file mode 100644 index f962efb920..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/LICENSE.descrip +++ /dev/null @@ -1 +0,0 @@ -WASHINGTON UNIVERSITY FTPD SOFTWARE diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/Makefile b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/Makefile deleted file mode 100644 index c28648fb35..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/Makefile +++ /dev/null @@ -1,122 +0,0 @@ -# -# Copyright (c) 1990, 2010, Oracle and/or its affiliates. All rights reserved. -# - -PROG= in.ftpd ftpcount ftpshut ftprestart privatepw -SCRIPTS= ftpaddhost ftpconfig -MANIFEST= ftp.xml -SVCMETHOD= svc-ftp - -include ../../../Makefile.cmd - -COMMON_OBJS= COPYRIGHT.o vers.o -FTPD_OBJS= $(COMMON_OBJS) ftpd.o ftpcmd.o glob.o logwtmp.o popen.o \ - access.o extensions.o realpath.o acl.o private.o \ - authenticate.o conversions.o rdservers.o paths.o hostacc.o \ - routevector.o restrict.o domain.o wu_fnmatch.o timeout.o \ - getpwnam.o inet.o xferlog.o gssutil.o privs.o -FTPCOUNT_OBJS= $(COMMON_OBJS) ftpcount.o rdservers.o inet.o -FTPSHUT_OBJS= $(COMMON_OBJS) ftpshut.o rdservers.o inet.o -FTPREST_OBJS= $(COMMON_OBJS) ftprestart.o rdservers.o inet.o -CKCONFIG_OBJS= $(COMMON_OBJS) ckconfig.o rdservers.o inet.o -PRIVATE_OBJS= $(COMMON_OBJS) privatepw.o -OBJS= $(FTPD_OBJS) ftpcount.o ftpshut.o ftprestart.o ckconfig.o \ - privatepw.o -SRCS= $(OBJS:%.o=%.c) -CONFIGFILES= ftpaccess ftpconversions ftpgroups ftphosts ftpservers ftpusers -ETCFTPDDIR= $(ROOTETC)/ftpd -ETCFTPDFILES= $(CONFIGFILES:%=$(ETCFTPDDIR)/%) -$(ETCFTPDFILES):= FILEMODE= 0644 -ROOTUSRSBINSCRIPTS= $(SCRIPTS:%=$(ROOTUSRSBIN)/%) -ROOTFTPCOUNT= $(ROOTUSRSBIN)/ftpcount -ROOTFTPWHO= $(ROOTUSRSBIN)/ftpwho - -ROOTMANIFESTDIR= $(ROOTSVCNETWORK) - -# I18n -POFILE= in.ftpd_all.po -POFILES= $(SCRIPTS:%=%.po) - -# When building for Solaris 8 add to CPPFLAGS: -# -Ddn_skipname=__dn_skipname -DSOLARIS_NO_AUDIT_FTPD_LOGOUT -CLOBBERFILES += ckconfig ftpwho $(SCRIPTS) -CPPFLAGS += -DBSD_COMP -D_FILE_OFFSET_BITS=64 -DINET6 -DSOLARIS_BSM_AUDIT \ - -DSOLARIS_ETC_FTPUSERS -DSENDFILE -DCLOSEFROM -DUSE_GSS \ - -DSOLARIS_GSS_USEROK -DSOLARIS_PRIVS -LDLIBS += -lsocket -lnsl -lpam -lbsm -lsendfile -lgss -YFLAGS += -d - -CERRWARN += -_gcc=-Wno-implicit-function-declaration -CERRWARN += -_gcc=-Wno-parentheses -CERRWARN += -_gcc=-Wno-unused-variable -CERRWARN += -_gcc=-Wno-uninitialized -CERRWARN += -_gcc=-Wno-unused-label -CERRWARN += -_gcc=-Wno-clobbered -CERRWARN += -_gcc=-Wno-address - -in.ftpd := LDFLAGS += $(MAPFILE.NGB:%=-M%) - -# tcov output relies on atexit(3C) registered functions being called, so stop -# _exit() from being used. Passing -l to yacc stops it generating #line -# directives which don't work with tcov. -tcov := CFLAGS += -xa -tcov := CPPFLAGS += -D_exit=exit -tcov := YFLAGS += -l - -.KEEP_STATE: - -all tcov: $(PROG) ckconfig ftpwho $(CONFIGFILES) $(SCRIPTS) - -in.ftpd: $(FTPD_OBJS) $(MAPFILE.NGB) - $(LINK.c) $(FTPD_OBJS) -o $@ $(LDLIBS) - $(POST_PROCESS) - -ftpcount: $(FTPCOUNT_OBJS) - $(LINK.c) $(FTPCOUNT_OBJS) -o $@ -lsocket -lnsl - $(POST_PROCESS) - -ftpwho: ftpcount - $(RM) $@ - $(LN) ftpcount $@ - -ftpshut: $(FTPSHUT_OBJS) - $(LINK.c) $(FTPSHUT_OBJS) -o $@ -lsocket -lnsl - $(POST_PROCESS) - -ftprestart: $(FTPREST_OBJS) - $(LINK.c) $(FTPREST_OBJS) -o $@ -lsocket -lnsl - $(POST_PROCESS) - -ckconfig: $(CKCONFIG_OBJS) - $(LINK.c) $(CKCONFIG_OBJS) -o $@ -lsocket -lnsl - $(POST_PROCESS) - -privatepw: $(PRIVATE_OBJS) - $(LINK.c) $(PRIVATE_OBJS) -o $@ - $(POST_PROCESS) - -# This causes y.tab.c to be renamed to ftpcmd.c, needed by tcov. -ftpcmd.c: ftpcmd.y - -$(ETCFTPDDIR)/%: % - $(INS.file) - -$(POFILE): $(POFILES) - $(RM) $@ - cat $(POFILES) >$@ - -$(ROOTFTPWHO): $(ROOTFTPCOUNT) - $(RM) $@ - $(LN) $(ROOTFTPCOUNT) $@ - -install: all $(ROOTUSRSBINPROG) $(ROOTFTPWHO) $(ROOTUSRSBINSCRIPTS) \ - $(ETCFTPDFILES) $(ROOTMANIFEST) $(ROOTSVCMETHOD) - -check: $(CHKMANIFEST) - -clean: - $(RM) $(OBJS) *.d *.tcov y.tab.h y.tab.c ftpcmd.c - -lint: lint_SRCS - -include ../../../Makefile.targ diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/access.c b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/access.c deleted file mode 100644 index f8cf5f795f..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/access.c +++ /dev/null @@ -1,1531 +0,0 @@ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/**************************************************************************** - - Copyright (c) 1999,2000 WU-FTPD Development Group. - All rights reserved. - - Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 - The Regents of the University of California. - Portions Copyright (c) 1993, 1994 Washington University in Saint Louis. - Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc. - Portions Copyright (c) 1989 Massachusetts Institute of Technology. - Portions Copyright (c) 1998 Sendmail, Inc. - Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman. - Portions Copyright (c) 1997 by Stan Barber. - Portions Copyright (c) 1997 by Kent Landfield. - Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 - Free Software Foundation, Inc. - - Use and distribution of this software and its source code are governed - by the terms and conditions of the WU-FTPD Software License ("LICENSE"). - - If you did not receive a copy of the license, it may be obtained online - at http://www.wu-ftpd.org/license.html. - - $Id: access.c,v 1.30 2000/07/01 18:17:38 wuftpd Exp $ - -****************************************************************************/ -#include "config.h" - -#include -#include -#include -#include - -#ifdef HAVE_SYS_SYSLOG_H -#include -#endif -#if defined(HAVE_SYSLOG_H) || (!defined(AUTOCONF) && !defined(HAVE_SYS_SYSLOG_H)) -#include -#endif - -#ifdef TIME_WITH_SYS_TIME -#include -#include -#elif defined(HAVE_SYS_TIME_H) -#include -#else -#include -#endif - -#include -#include -#include -#include - -#include -#include -#include -#include - -#ifdef HAVE_PATHS_H -#include -#endif - -#include "pathnames.h" -#include "extensions.h" -#include "proto.h" - -#if defined(HAVE_FCNTL_H) -#include -#endif - -#ifdef OTHER_PASSWD -#include "getpwnam.h" -extern char _path_passwd[]; -#ifdef SHADOW_PASSWORD -extern char _path_shadow[]; -#endif -#endif - -#if defined(USE_PAM) && defined(OTHER_PASSWD) -extern int use_pam; -#endif - -extern char remotehost[], remoteaddr[], *remoteident, *aclbuf; -extern int nameserved, anonymous, guest, TCPwindowsize, use_accessfile; -extern mode_t defumask; -char Shutdown[MAXPATHLEN]; -int keepalive = 0; -#define MAXLINE 80 -static char incline[MAXLINE]; -static int pidfd = -1; -extern int Bypass_PID_Files; - -#ifndef HELP_CRACKERS -extern char DelayedMessageFile[]; -#endif - -#include "wu_fnmatch.h" - -#define ACL_COUNT 0 -#define ACL_JOIN 1 -#define ACL_REMOVE 2 - -/*************************************************************************/ -/* FUNCTION : parse_time */ -/* PURPOSE : Check a single valid-time-string against the current time */ -/* and return whether or not a match occurs. */ -/* ARGUMENTS : a pointer to the time-string */ -/*************************************************************************/ - -int parsetime(char *whattime) -{ - static char *days[] = - {"Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Wk"}; - time_t clock; - struct tm *curtime; - int wday, start, stop, ltime, validday, loop, match; - - (void) time(&clock); - curtime = localtime(&clock); - wday = curtime->tm_wday; - validday = 0; - match = 1; - - while (match && isalpha(*whattime) && isupper(*whattime)) { - match = 0; - for (loop = 0; loop < 8; loop++) { - if (strncmp(days[loop], whattime, 2) == 0) { - whattime += 2; - match = 1; - if ((wday == loop) || ((loop == 7) && wday && (wday < 6))) { - validday = 1; - } - } - } - } - - if (!validday) { - if (strncmp(whattime, "Any", 3) == 0) { - validday = 1; - whattime += 3; - } - else - return (0); - } - - if (sscanf(whattime, "%d-%d", &start, &stop) == 2) { - ltime = curtime->tm_min + 100 * curtime->tm_hour; - if ((start < stop) && ((ltime >= start) && ltime < stop)) - return (1); - if ((start > stop) && ((ltime >= start) || ltime < stop)) - return (1); - } - else - return (1); - - return (0); -} - -/*************************************************************************/ -/* FUNCTION : validtime */ -/* PURPOSE : Break apart a set of valid time-strings and pass them to */ -/* parse_time, returning whether or not ANY matches occurred */ -/* ARGUMENTS : a pointer to the time-string */ -/*************************************************************************/ - -int validtime(char *ptr) -{ - char *nextptr; - int good; - - while (1) { - nextptr = strchr(ptr, '|'); - if (strchr(ptr, '|') == NULL) - return (parsetime(ptr)); - *nextptr = '\0'; - good = parsetime(ptr); - /* gotta restore the | or things get skipped! */ - *nextptr++ = '|'; - if (good) - return (1); - ptr = nextptr; - } -} - -#ifdef INET6 -/*************************************************************************/ -/* FUNCTION : ipv6str */ -/* PURPOSE : Convert an IPv6 address string with optional /CIDR suffix */ -/* into an IPv6 address and a CIDR, which are returned in */ -/* the arguments pointed to by in6p and cidrp. */ -/* ARGUMENTS : The IPv6 address string and pointers to in6_addr and CIDR */ -/* RETURNS : 1 if addr is an IPv6 address string, 0 if not */ -/*************************************************************************/ - -static int ipv6str(char *addr, struct in6_addr *in6p, int *cidrp) -{ - int cidr = 128; /* IPv6 addresses are 128-bits long */ - char *ptr; - - if ((ptr = strstr(addr, "/"))) - *ptr = '\0'; - - if (inet_pton(AF_INET6, addr, in6p) != 1) { - if (ptr) - *ptr = '/'; - return 0; - } - - if (ptr) { - *ptr++ = '/'; - cidr = atoi(ptr); - if (cidr < 0) - cidr = 0; - else if (cidr > 128) - cidr = 128; - } - *cidrp = cidr; - return 1; -} -#endif - -/*************************************************************************/ -/* FUNCTION : hostmatch */ -/* PURPOSE : Match remote hostname or address against a glob string */ -/* ARGUMENTS : The string to match, remote address, remote hostname */ -/* RETURNS : 0 if no match, 1 if a match occurs */ -/*************************************************************************/ - -int hostmatch(char *addr, char *remoteaddr, char *remotehost) -{ - FILE *incfile; - char *ptr, junk, s[4][4]; - int found = 1; - int not_found = 0; - int match = 0; - int i, a[4], m[4], r[4], cidr; -#ifdef INET6 - struct in6_addr addr_in6; -#endif - - if (addr == NULL) - return (0); - - if (*addr == '!') { - found = 0; - not_found = 1; - addr++; - } - - if (sscanf(addr, "%d.%d.%d.%d/%d", a, a + 1, a + 2, a + 3, &cidr) == 5) { - m[0] = 0; - m[1] = 0; - m[2] = 0; - m[3] = 0; - if (cidr < 0) - cidr = 0; - else if (cidr > 32) - cidr = 32; - for (i = 0; cidr > 8; i++) { - m[i] = 255; - cidr -= 8; - } - switch (cidr) { - case 8: - m[i] += 1; - case 7: - m[i] += 2; - case 6: - m[i] += 4; - case 5: - m[i] += 8; - case 4: - m[i] += 16; - case 3: - m[i] += 32; - case 2: - m[i] += 64; - case 1: - m[i] += 128; - } - /* make sure remoteaddr is an IPv4 address */ - if (sscanf(remoteaddr, "%d.%d.%d.%d", r, r + 1, r + 2, r + 3) != 4) - return not_found; - for (i = 0; i < 4; i++) - if ((a[i] & m[i]) != (r[i] & m[i])) - return not_found; - return found; - } - else if (sscanf(addr, "%d.%d.%d.%d:%d.%d.%d.%d", a, a + 1, a + 2, a + 3, m, m + 1, m + 2, m + 3) == 8) { - /* make sure remoteaddr is an IPv4 address */ - if (sscanf(remoteaddr, "%d.%d.%d.%d", r, r + 1, r + 2, r + 3) != 4) - return not_found; - for (i = 0; i < 4; i++) - if ((a[i] & m[i]) != (r[i] & m[i])) - return not_found; - return found; - } - else if (sscanf(addr, "%3[0-9*].%3[0-9*].%3[0-9*].%3[0-9*]%c", - s[0], s[1], s[2], s[3], &junk) == 4 && - (!strcmp(s[0],"*") || !strchr(s[0],'*')) && - (!strcmp(s[1],"*") || !strchr(s[1],'*')) && - (!strcmp(s[2],"*") || !strchr(s[2],'*')) && - (!strcmp(s[3],"*") || !strchr(s[3],'*')) ) { - /* make sure remoteaddr is an IPv4 address */ - if (sscanf(remoteaddr, "%d.%d.%d.%d", r, r + 1, r + 2, r + 3) != 4) - return not_found; - for (i = 0; i < 4; i++) - if ( (strcmp(s[i],"*")) && (atoi(s[i]) != r[i]) ) - return not_found; - return found; - } -#ifdef INET6 - else if (ipv6str(addr, &addr_in6, &cidr)) { - struct in6_addr rem_in6; - uint32_t addr32[4], rem32[4]; - int bitstozero; - - if (inet_pton6(remoteaddr, &rem_in6) != 1) - return not_found; - - memcpy(addr32, addr_in6.s6_addr, sizeof(addr32)); - memcpy(rem32, rem_in6.s6_addr, sizeof(rem32)); - - /* IPv6 addresses are 128-bits long */ - bitstozero = 128 - cidr; - - /* zero bits starting with the least significant */ - for (i = 3; (bitstozero > 0) && (i >= 0); i--, bitstozero -= 32) { - if (bitstozero >= 32) - addr32[i] = rem32[i] = 0; - else { - addr32[i] = (ntohl(addr32[i]) >> bitstozero) << bitstozero; - rem32[i] = (ntohl(rem32[i]) >> bitstozero) << bitstozero; - } - } - if (memcmp(addr32, rem32, sizeof(addr32))) - return not_found; - return found; - } -#endif - else if (*addr == '/') { - /* - * read addrglobs from named path using similar format as addrglobs - * in access file - */ - if ((incfile = fopen(addr, "r")) == NULL) { - if (errno != ENOENT) - syslog(LOG_ERR, - "cannot open addrglob file %s: %m", addr); - return (0); - } - - while (!match && (fgets(incline, MAXLINE, incfile) != NULL)) { - ptr = strtok(incline, " \t\n"); - if (ptr && hostmatch(ptr, remoteaddr, remotehost)) - match = 1; - while (!match && ((ptr = strtok(NULL, " \t\n")) != NULL)) { - if (ptr && hostmatch(ptr, remoteaddr, remotehost)) - match = 1; - } - } - fclose(incfile); - return (match ? found : not_found); - } - else { /* match a hostname or hostname glob */ - match = (!wu_fnmatch(addr, remotehost, FNM_CASEFOLD)) || - (!wu_fnmatch(addr, remoteaddr, 0)); - return (match ? found : not_found); - } -} - -/*************************************************************************/ -/* FUNCTION : acl_guestgroup */ -/* PURPOSE : If the real user is a member of any of the listed groups, */ -/* return 1. Otherwise return 0. */ -/* ARGUMENTS : pw, a pointer to the passwd struct for the user */ -/*************************************************************************/ - -int acl_guestgroup(struct passwd *pw) -{ - /* - * guestuser [ ...] - * - * If name begins with '%' treat as numeric. - * Numeric names may be ranges. - * % A single numeric UID - * %+ All UIDs greater or equal to UID - * %- All UIDs greater or equal to UID - * %- All UIDs less or equal to UID - * %- All UIDs between the two (inclusive) - * * All UIDs - */ - if (uid_match("guestuser", pw->pw_uid)) - return (1); - - /* - * guestgroup [ ...] - * - * If group begins with '%' treat as numeric. - * Numeric groups may be ranges. - * % A single GID - * %+ All GIDs greater or equal to GID - * %- All GIDs greater or equal to GID - * %- All GIDs less or equal to GID - * %- All GIDs between the two (inclusive) - * * All GIDs - */ - if (gid_match("guestgroup", pw->pw_gid, pw->pw_name)) - return (1); - - return (0); -} - -int acl_realgroup(struct passwd *pw) -{ - /* - * realuser [ ...] - * - * If name begins with '%' treat as numeric. - * Numeric names may be ranges. - * % A single numeric UID - * %+ All UIDs greater or equal to UID - * %- All UIDs greater or equal to UID - * %- All UIDs less or equal to UID - * %- All UIDs between the two (inclusive) - * * All UIDs - */ - if (uid_match("realuser", pw->pw_uid)) - return (1); - - /* - * realgroup [ ...] - * - * If group begins with '%' treat as numeric. - * Numeric groups may be ranges. - * % A single GID - * %+ All GIDs greater or equal to GID - * %- All GIDs greater or equal to GID - * %- All GIDs less or equal to GID - * %- All GIDs between the two (inclusive) - * * All GIDs - */ - if (gid_match("realgroup", pw->pw_gid, pw->pw_name)) - return (1); - - return (0); -} - -/*************************************************************************/ -/* FUNCTION : acl_autogroup */ -/* PURPOSE : If the guest user is a member of any of the classes in */ -/* the autogroup comment, cause a setegid() to the specified */ -/* group. */ -/* ARGUMENTS : pw, a pointer to the passwd struct for the user */ -/*************************************************************************/ - -void acl_autogroup(struct passwd *pw) -{ - char class[BUFSIZ]; - - struct aclmember *entry = NULL; - struct group *grp; - int which; - - (void) acl_getclass(class); - - /* autogroup [ ...] */ - while (getaclentry("autogroup", &entry)) { - if (!ARG0 || !ARG1) - continue; - for (which = 1; (which < MAXARGS) && ARG[which]; which++) { - if (!strcasecmp(ARG[which], class)) { - if (ARG0[0] == '%') - pw->pw_gid = atoi(ARG0 + 1); - else { - if ((grp = getgrnam(ARG0))) - pw->pw_gid = grp->gr_gid; - else - syslog(LOG_ERR, "autogroup: set group %s not found", ARG0); - endgrent(); - } - return; - } - } - } -} - -/*************************************************************************/ -/* FUNCTION : acl_setfunctions */ -/* PURPOSE : Scan the ACL buffer and determine what logging to perform */ -/* for this user, and whether or not user is allowed to use */ -/* the automatic TAR and COMPRESS functions. Also, set the */ -/* current process priority of this copy of the ftpd server */ -/* to a `nice' value value if this user is a member of a */ -/* group which the ftpaccess file says should be nice'd. */ -/* ARGUMENTS : none */ -/*************************************************************************/ - -void acl_setfunctions(void) -{ - char class[BUFSIZ]; - - extern int log_incoming_xfers, log_outbound_xfers, mangleopts, log_commands, - log_security, syslogmsg, lgi_failure_threshold; - - struct aclmember *entry = NULL; - - int l_compress, l_tar, inbound = 0, outbound = 0, which, set; - - log_security = 0; - - /* Initialize to the logging value specified on the command line, can't - just use the current value as it may have been set by a previous call. */ - log_incoming_xfers = (log_incoming_xfers & 2) ? 3 : 0; - log_outbound_xfers = (log_outbound_xfers & 2) ? 3 : 0; - log_commands = (log_commands & 2) ? 3 : 0; - - memset((void *) &class[0], 0, sizeof(class)); - - (void) acl_getclass(class); - - entry = (struct aclmember *) NULL; - if (getaclentry("loginfails", &entry) && ARG0 != NULL) { - lgi_failure_threshold = atoi(ARG0); - } -#ifndef NO_PRIVATE - entry = (struct aclmember *) NULL; - if (getaclentry("private", &entry) && ARG0 != NULL) - if (!strcasecmp(ARG0, "yes")) - priv_setup(_path_private); -#endif /* !NO_PRIVATE */ - - entry = (struct aclmember *) NULL; - set = 0; - while (!set && getaclentry("compress", &entry)) { - if (!ARG0) - continue; - l_compress = 0; - if (!strcasecmp(ARG0, "yes")) - l_compress = 1; - for (which = 1; (which < MAXARGS) && ARG[which]; which++) { - if (!wu_fnmatch(ARG[which], class, FNM_CASEFOLD)) { - mangleopts |= l_compress * (O_COMPRESS | O_UNCOMPRESS); - set = 1; - } - } - } - - entry = (struct aclmember *) NULL; - set = 0; - while (!set && getaclentry("tar", &entry)) { - if (!ARG0) - continue; - l_tar = 0; - if (!strcasecmp(ARG0, "yes")) - l_tar = 1; - for (which = 1; (which < MAXARGS) && ARG[which]; which++) { - if (!wu_fnmatch(ARG[which], class, FNM_CASEFOLD)) { - mangleopts |= l_tar * O_TAR; - set = 1; - } - } - } - - /* plan on expanding command syntax to include classes for each of these */ - - entry = (struct aclmember *) NULL; - while (getaclentry("log", &entry)) { - if (!ARG0) - continue; - if (!strcasecmp(ARG0, "commands")) { - if (!ARG1) - continue; - if (anonymous && strcasestr(ARG1, "anonymous")) - log_commands |= 1; - if (guest && strcasestr(ARG1, "guest")) - log_commands |= 1; - if (!guest && !anonymous && strcasestr(ARG1, "real")) - log_commands |= 1; - } - if (!strcasecmp(ARG0, "transfers")) { - if (!ARG1 || !ARG2) - continue; - set = 0; - if (strcasestr(ARG1, "anonymous") && anonymous) - set = 1; - if (strcasestr(ARG1, "guest") && guest) - set = 1; - if (strcasestr(ARG1, "real") && !guest && !anonymous) - set = 1; - if (strcasestr(ARG2, "inbound")) - inbound = 1; - if (strcasestr(ARG2, "outbound")) - outbound = 1; - if (set) - log_incoming_xfers |= inbound; - if (set) - log_outbound_xfers |= outbound; - } - if (!strcasecmp(ARG0, "security")) { - if (!ARG1) - continue; - if (strcasestr(ARG1, "anonymous") && anonymous) - log_security = 1; - if (strcasestr(ARG1, "guest") && guest) - log_security = 1; - if (strcasestr(ARG1, "real") && !guest && !anonymous) - log_security = 1; - } - if (!strcasecmp(ARG0, "syslog")) - syslogmsg = 1; - if (!strcasecmp(ARG0, "xferlog")) - syslogmsg = 0; - if (!strcasecmp(ARG0, "syslog+xferlog") - || !strcasecmp(ARG0, "xferlog+syslog")) - syslogmsg = 2; - } -} - -/*************************************************************************/ -/* FUNCTION : acl_getclass */ -/* PURPOSE : Scan the ACL buffer and determine what class user is in */ -/* ARGUMENTS : pointer to buffer to class name, pointer to ACL buffer */ -/*************************************************************************/ - -int acl_getclass(char *classbuf) -{ - int which; - struct aclmember *entry = NULL; - - while (getaclentry("class", &entry)) { - if (ARG0) - strlcpy(classbuf, ARG0, BUFSIZ); - - for (which = 2; (which < MAXARGS) && ARG[which]; which++) { - if (anonymous && strcasestr(ARG1, "anonymous") && - hostmatch(ARG[which], remoteaddr, remotehost)) - return (1); - - if (guest && strcasestr(ARG1, "guest") && hostmatch(ARG[which], remoteaddr, remotehost)) - return (1); - - if (!guest && !anonymous && strcasestr(ARG1, "real") && - hostmatch(ARG[which], remoteaddr, remotehost)) - return (1); - } - } - - *classbuf = (char) NULL; - return (0); - -} - -/*************************************************************************/ -/* FUNCTION : acl_getlimit */ -/* PURPOSE : Scan the ACL buffer and determine what limit applies to */ -/* the user */ -/* ARGUMENTS : pointer class name, pointer to ACL buffer */ -/*************************************************************************/ - -int acl_getlimit(char *class, char *msgpathbuf) -{ - int limit; - struct aclmember *entry = NULL; - - if (msgpathbuf) - *msgpathbuf = '\0'; - - /* limit [] */ - while (getaclentry("limit", &entry)) { - if (!ARG0 || !ARG1 || !ARG2) - continue; - if (!strcasecmp(class, ARG0)) { - limit = atoi(ARG1); - if (validtime(ARG2)) { - if (ARG3 && msgpathbuf) - strcpy(msgpathbuf, ARG3); - return (limit); - } - } - } - return (-1); -} - -/*************************************************************************/ -/* FUNCTION : acl_getnice */ -/* PURPOSE : Scan the ACL buffer and determine what nice value applies */ -/* to the user */ -/* ARGUMENTS : pointer class name */ -/*************************************************************************/ - -int acl_getnice(char *class) -{ - int nice_delta_for_class_found = 0; - int nice_delta = 0; - int default_nice_delta = 0; - - struct aclmember *entry = NULL; - - /* nice [] */ - while (getaclentry("nice", &entry)) { - if (!ARG0) - continue; - if (!ARG1) - default_nice_delta = atoi(ARG0); - else if (!strcasecmp(class, ARG1)) { - nice_delta_for_class_found = 1; - nice_delta = atoi(ARG0); - } - } - if (!nice_delta_for_class_found) - nice_delta = default_nice_delta; - return nice_delta; -} - - -/*************************************************************************/ -/* FUNCTION : acl_getdefumask */ -/* PURPOSE : Scan the ACL buffer to determine what umask value applies */ -/* to the user */ -/* ARGUMENTS : pointer to class name */ -/*************************************************************************/ - -void acl_getdefumask(char *class) -{ - struct aclmember *entry = NULL; - char *ptr; - unsigned int val; - - /* defumask [] */ - while (getaclentry("defumask", &entry)) { - if (!ARG0) - continue; - if (!ARG1 || !strcasecmp(class, ARG1)) { - ptr = ARG0; - val = 0; - while (*ptr && *ptr >= '0' && *ptr <= '7') - val = val * 8 + *ptr++ - '0'; - if (!*ptr && val <= 0777) { - defumask = val; - if (ARG1) - break; - } - else - syslog(LOG_WARNING, "bad umask in %s ignored: defumask %s", - _path_ftpaccess, ARG0); - } - } - umask(defumask); -} - -/*************************************************************************/ -/* FUNCTION : acl_tcpwindow */ -/* PURPOSE : Scan the ACL buffer and determine what TCP window size to */ -/* use based upon the class */ -/* ARGUMENTS : pointer to class name */ -/*************************************************************************/ - -void acl_tcpwindow(char *class) -{ - struct aclmember *entry = NULL; - - /* tcpwindow [] */ - while (getaclentry("tcpwindow", &entry)) { - if (!ARG0) - continue; - if (!ARG1) - TCPwindowsize = strtoul(ARG0, NULL, 0); - else if (!strcasecmp(class, ARG1)) { - TCPwindowsize = strtoul(ARG0, NULL, 0); - break; - } - } -} - -/*************************************************************************/ -/* FUNCTION : acl_bufsize */ -/* PURPOSE : Scan the ACL buffer and determine the send and receive */ -/* buffer sizes to use */ -/* ARGUMENTS : None */ -/*************************************************************************/ - -static void acl_bufsize() -{ - struct aclmember *entry; - extern size_t sendbufsz, recvbufsz; - - /* sendbuf [] */ - entry = (struct aclmember *) NULL; - sendbufsz = 0; - while (getaclentry("sendbuf", &entry)) { - if (!ARG0) - continue; - if (!ARG1) - sendbufsz = strtoul(ARG0, NULL, 0); - else if (type_match(ARG1)) { - sendbufsz = strtoul(ARG0, NULL, 0); - break; - } - } - - /* recvbuf [] */ - entry = (struct aclmember *) NULL; - recvbufsz = 0; - while (getaclentry("recvbuf", &entry)) { - if (!ARG0) - continue; - if (!ARG1) - recvbufsz = strtoul(ARG0, NULL, 0); - else if (type_match(ARG1)) { - recvbufsz = strtoul(ARG0, NULL, 0); - break; - } - } -} - -#ifdef TRANSFER_COUNT -#ifdef TRANSFER_LIMIT - -/*************************************************************************/ -/* FUNCTION : acl_filelimit */ -/* PURPOSE : Scan the ACL buffer and determine what file limit to use */ -/* based upon the class */ -/* ARGUMENTS : pointer to class name */ -/*************************************************************************/ - -void acl_filelimit(char *class) -{ - struct aclmember *entry = NULL; - int raw_in = 0; - int raw_out = 0; - int raw_total = 0; - int data_in = 0; - int data_out = 0; - int data_total = 0; - extern int file_limit_raw_in; - extern int file_limit_raw_out; - extern int file_limit_raw_total; - extern int file_limit_data_in; - extern int file_limit_data_out; - extern int file_limit_data_total; - - /* file-limit [] [] */ - while (getaclentry("file-limit", &entry)) { - if (!ARG0 || !ARG1) - continue; - if (!strcasecmp(ARG0, "raw")) { - if (!ARG2) - continue; - if (!strcasecmp(ARG1, "in")) { - if (!ARG3) { - if (!raw_in) - file_limit_raw_in = atoi(ARG2); - } - else if (!strcasecmp(class, ARG3)) { - raw_in = 1; - file_limit_raw_in = atoi(ARG2); - } - } - else if (!strcasecmp(ARG1, "out")) { - if (!ARG3) { - if (!raw_out) - file_limit_raw_out = atoi(ARG2); - } - else if (!strcasecmp(class, ARG3)) { - raw_out = 1; - file_limit_raw_out = atoi(ARG2); - } - } - else if (!strcasecmp(ARG1, "total")) { - if (!ARG3) { - if (!raw_total) - file_limit_raw_total = atoi(ARG2); - } - else if (!strcasecmp(class, ARG3)) { - raw_total = 1; - file_limit_raw_total = atoi(ARG2); - } - } - } - else if (!strcasecmp(ARG0, "in")) { - if (!ARG2) { - if (!data_in) - file_limit_data_in = atoi(ARG1); - } - else if (!strcasecmp(class, ARG2)) { - data_in = 1; - file_limit_data_in = atoi(ARG1); - } - } - else if (!strcasecmp(ARG0, "out")) { - if (!ARG2) { - if (!data_out) - file_limit_data_out = atoi(ARG1); - } - else if (!strcasecmp(class, ARG2)) { - data_out = 1; - file_limit_data_out = atoi(ARG1); - } - } - else if (!strcasecmp(ARG0, "total")) { - if (!ARG2) { - if (!data_total) - file_limit_data_total = atoi(ARG1); - } - else if (!strcasecmp(class, ARG2)) { - data_total = 1; - file_limit_data_total = atoi(ARG1); - } - } - } -} - -/*************************************************************************/ -/* FUNCTION : acl_datalimit */ -/* PURPOSE : Scan the ACL buffer and determine what data limit to use */ -/* based upon the class */ -/* ARGUMENTS : pointer to class name */ -/*************************************************************************/ - -void acl_datalimit(char *class) -{ - struct aclmember *entry = NULL; - int raw_in = 0; - int raw_out = 0; - int raw_total = 0; - int data_in = 0; - int data_out = 0; - int data_total = 0; - extern off_t data_limit_raw_in; - extern off_t data_limit_raw_out; - extern off_t data_limit_raw_total; - extern off_t data_limit_data_in; - extern off_t data_limit_data_out; - extern off_t data_limit_data_total; - - /* data-limit [] [] */ - while (getaclentry("data-limit", &entry)) { - if (!ARG0 || !ARG1) - continue; - if (!strcasecmp(ARG0, "raw")) { - if (!ARG2) - continue; - if (!strcasecmp(ARG1, "in")) { - if (!ARG3) { - if (!raw_in) - data_limit_raw_in = atoi(ARG2); - } - else if (!strcasecmp(class, ARG3)) { - raw_in = 1; - data_limit_raw_in = atoi(ARG2); - } - } - else if (!strcasecmp(ARG1, "out")) { - if (!ARG3) { - if (!raw_out) - data_limit_raw_out = atoi(ARG2); - } - else if (!strcasecmp(class, ARG3)) { - raw_out = 1; - data_limit_raw_out = atoi(ARG2); - } - } - else if (!strcasecmp(ARG1, "total")) { - if (!ARG3) { - if (!raw_total) - data_limit_raw_total = atoi(ARG2); - } - else if (!strcasecmp(class, ARG3)) { - raw_total = 1; - data_limit_raw_total = atoi(ARG2); - } - } - } - else if (!strcasecmp(ARG0, "in")) { - if (!ARG2) { - if (!data_in) - data_limit_data_in = atoi(ARG1); - } - else if (!strcasecmp(class, ARG2)) { - data_in = 1; - data_limit_data_in = atoi(ARG1); - } - } - else if (!strcasecmp(ARG0, "out")) { - if (!ARG2) { - if (!data_out) - data_limit_data_out = atoi(ARG1); - } - else if (!strcasecmp(class, ARG2)) { - data_out = 1; - data_limit_data_out = atoi(ARG1); - } - } - else if (!strcasecmp(ARG0, "total")) { - if (!ARG2) { - if (!data_total) - data_limit_data_total = atoi(ARG1); - } - else if (!strcasecmp(class, ARG2)) { - data_total = 1; - data_limit_data_total = atoi(ARG1); - } - } - } -} - - -#ifdef RATIO - -/*************************************************************************/ -/* FUNCTION : acl_downloadrate */ -/* PURPOSE : Scan the ACL buffer and determine what data limit to use */ -/* based upon the class */ -/* ARGUMENTS : pointer to class name */ -/*************************************************************************/ - -void acl_downloadrate(char *class) -{ - struct aclmember *entry = NULL; - extern int upload_download_rate; - int which; - - /* ul-dl-rate [ ...] */ - while (getaclentry("ul-dl-rate", &entry)) { - if (!ARG0 ) - continue; - - if (!ARG1) { - upload_download_rate = atol(ARG0); - } - else { - for (which = 1; (which < MAXARGS) && ARG[which]; which++) { - if (!strcasecmp(ARG[which], class)) - upload_download_rate = atol(ARG0); - } - } - - } -} -#endif /* RATIO */ - -#endif -#endif - -/*************************************************************************/ -/* FUNCTION : acl_deny */ -/* PURPOSE : Scan the ACL buffer and determine if access is denied. */ -/* ARGUMENTS : Pointer to buffer into which the path of the message file */ -/* is copied. */ -/*************************************************************************/ - -int acl_deny(char *msgpathbuf) -{ - struct aclmember *entry = NULL; - - if (msgpathbuf) - *msgpathbuf = (char) NULL; - - /* deny [] */ - while (getaclentry("deny", &entry)) { - if (!ARG0) - continue; - if (strcasecmp(ARG0, "!nameserved") == 0) { - if (!nameserved) { - if (ARG1) - strcpy(msgpathbuf, entry->arg[1]); - return (1); - } - } - else if (hostmatch(ARG0, remoteaddr, remotehost)) { - if (ARG1) - strcpy(msgpathbuf, entry->arg[1]); - return (1); - } - } - return (0); -} - -/*************************************************************************/ -/* FUNCTION : lock_fd */ -/* PURPOSE : Lock a file. */ -/* ARGUMENTS : File descriptor of file to lock. */ -/*************************************************************************/ - -static void lock_fd(int fd) -{ -#if !defined(HAVE_FLOCK) - struct flock arg; -#endif /* !defined(HAVE_FLOCK) */ - -#if defined(HAVE_FLOCK) - while (flock(fd, LOCK_EX)) { -# if !defined(NO_PID_SLEEP_MSGS) - syslog(LOG_ERR, "sleeping: flock of pid file failed: %m"); -# endif /* !defined(NO_PID_SLEEP_MSGS) */ -#else /* !(defined(HAVE_FLOCK)) */ - arg.l_type = F_WRLCK; - arg.l_whence = arg.l_start = arg.l_len = 0; - while (-1 == fcntl(fd, F_SETLK, &arg)) { -# if !defined(NO_PID_SLEEP_MSGS) - syslog(LOG_ERR, "sleeping: fcntl lock of pid file failed: %m"); -# endif /* !defined(NO_PID_SLEEP_MSGS) */ -#endif /* !(defined(HAVE_FLOCK)) */ - sleep(1); - } -} - -/*************************************************************************/ -/* FUNCTION : unlock_fd */ -/* PURPOSE : Unlock a file locked by lock_fd. */ -/* ARGUMENTS : File descriptor of file to unlock. */ -/*************************************************************************/ - -static void unlock_fd(int fd) -{ -#if !defined(HAVE_FLOCK) - struct flock arg; -#endif /* !defined(HAVE_FLOCK) */ - -#if defined(HAVE_FLOCK) - flock(fd, LOCK_UN); -#else /* !(defined(HAVE_FLOCK)) */ - arg.l_type = F_UNLCK; - arg.l_whence = arg.l_start = arg.l_len = 0; - fcntl(fd, F_SETLK, &arg); -#endif /* !(defined(HAVE_FLOCK)) */ -} - -/*************************************************************************/ -/* FUNCTION : limit_op */ -/* PURPOSE : Carry out the specified limit operation, returning the */ -/* number of users in the class or -1 on failure. */ -/* ARGUMENTS : Operation (ACL_COUNT/ACL_JOIN/ACL_REMOVE), user limit */ -/*************************************************************************/ - -static int limit_op(int operation, int limit) -{ - int i, j, n, count; - int bit_changed, toomany, write_all_header; - off_t offset; - pid_t pid, procid; - time_t now; - struct pidfile_header hdr; - unsigned char bits, buf[BUFSIZ]; - - if (pidfd < 0) - return (-1); - - if (lseek(pidfd, (off_t)0, SEEK_SET) != 0) - return (-1); - - if (operation == ACL_COUNT) { - lock_fd(pidfd); - n = read(pidfd, (void *)&hdr.count, sizeof(hdr.count)); - unlock_fd(pidfd); - if (n != sizeof(hdr.count)) - return (-1); - return (hdr.count); - } - - toomany = 0; - write_all_header = 0; - lock_fd(pidfd); - if (read(pidfd, (void *)&hdr, sizeof(hdr)) != sizeof(hdr)) { - hdr.count = 0; - hdr.last_checked = 0; - } - now = time(NULL); - - /* check bitmap accuracy and re-calculate the count every 15 minutes */ - if ((now >= (hdr.last_checked + (15 * 60))) || (now < hdr.last_checked)) { - count = 0; - procid = 0; - bit_changed = 0; - while ((n = read(pidfd, (void *)buf, sizeof(buf))) > 0) { - for (i = 0; i < n; i++) { - if (buf[i] == 0) { - procid += CHAR_BIT; - } - else { - bits = 1; - for (j = 0; j < CHAR_BIT; j++) { - if ((buf[i] & bits) != 0) { - if (kill(procid, 0) == 0) { - count++; - } - else { - bit_changed = 1; - buf[i] &= ~bits; - } - } - bits <<= 1; - procid++; - } - } - } - if (bit_changed) { - lseek(pidfd, (off_t)-n, SEEK_CUR); - write(pidfd, (void *)buf, n); - bit_changed = 0; - } - } - if (hdr.count != count) { - syslog(LOG_INFO, "pid file header count (%d) corrected to %d", - hdr.count, count); - hdr.count = count; - } - hdr.last_checked = time(NULL); - write_all_header = 1; - } - - /* limit set to -1 when no limit defined */ - if ((operation == ACL_JOIN) && (limit != -1) && (hdr.count >= limit)) { - /* return if no need to update the header */ - if (write_all_header == 0) { - unlock_fd(pidfd); - return (-1); - } - toomany = 1; - } - else { - /* update the count */ - if (operation == ACL_JOIN) - hdr.count++; - else if (hdr.count > 0) /* ACL_REMOVE */ - hdr.count--; - } - - /* update the header */ - lseek(pidfd, (off_t)0, SEEK_SET); - if (write_all_header) - write(pidfd, (void *)&hdr, sizeof(hdr)); - else - write(pidfd, (void *)&hdr.count, sizeof(hdr.count)); - - /* return if no need to update the bitmap */ - if (toomany) { - unlock_fd(pidfd); - return (-1); - } - - /* update the bitmap entry for the process */ - pid = getpid(); - offset = (off_t)(sizeof(hdr) + (pid/CHAR_BIT)); - lseek(pidfd, offset, SEEK_SET); - if (read(pidfd, (void *)&bits, sizeof(bits)) != sizeof(bits)) - bits = 0; - if (operation == ACL_JOIN) - bits |= (1 << (pid%CHAR_BIT)); - else /* ACL_REMOVE */ - bits &= ~(1 << (pid%CHAR_BIT)); - lseek(pidfd, offset, SEEK_SET); - write(pidfd, (void *)&bits, sizeof(bits)); - unlock_fd(pidfd); - return (hdr.count); -} - -/*************************************************************************/ -/* FUNCTION : open_pidfile */ -/* PURPOSE : Return a file descriptor of an opened PID file. */ -/* ARGUMENTS : Users class. */ -/*************************************************************************/ - -static int open_pidfile(char *class) -{ - int fd; - mode_t oldmask; - char pidfile[MAXPATHLEN]; - - snprintf(pidfile, sizeof(pidfile), _PATH_PIDNAMES, class); - oldmask = umask(0); - fd = open(pidfile, O_RDWR | O_CREAT, 0644); - (void) umask(oldmask); - if (fd < 0) - syslog(LOG_ERR, "cannot open pid file %s: %m", pidfile); - return (fd); -} - -/*************************************************************************/ -/* FUNCTION : acl_countusers */ -/* PURPOSE : Return the number of users in the specified class. */ -/* ARGUMENTS : The name of the class to count. */ -/*************************************************************************/ - -int acl_countusers(char *class) -{ - int count = 0, opidfd = pidfd; - - if (Bypass_PID_Files) - return (0); - - if (pidfd < 0) { - if ((pidfd = open_pidfile(class)) < 0) - return (-1); - } - - count = limit_op(ACL_COUNT, 0); - - /* - * acl_countusers may be called from msg_massage before the correct class - * is known, so close the pid file if we opened it. - */ - if (opidfd < 0) { - close(pidfd); - pidfd = -1; - } - return (count); -} - -/*************************************************************************/ -/* FUNCTION : acl_join */ -/* PURPOSE : Add the current process to the list of processes in the */ -/* specified class. */ -/* ARGUMENTS : The name of the class to join, user limit for the class. */ -/* RETURNS : 0 on success, -1 on failure */ -/*************************************************************************/ - -int acl_join(char *class, int limit) -{ - if (Bypass_PID_Files) - return (0); - - if (pidfd < 0) { - if ((pidfd = open_pidfile(class)) < 0) - return (-1); - } - - if (limit_op(ACL_JOIN, limit) < 0) { - /* no need to leave the pid file open as we were not added to it */ - close(pidfd); - pidfd = -1; - return (-1); - } - /* pidfd left open so can be updated after a chroot */ - return (0); -} - -/*************************************************************************/ -/* FUNCTION : acl_remove */ -/* PURPOSE : Remove the current process from the list of processes in */ -/* our class. */ -/* ARGUMENTS : None. */ -/*************************************************************************/ - -void acl_remove(void) -{ - if (pidfd < 0) - return; - (void) limit_op(ACL_REMOVE, 0); - close(pidfd); - pidfd = -1; -} - -/*************************************************************************/ -/* FUNCTION : pr_mesg */ -/* PURPOSE : Display a message to the user */ -/* ARGUMENTS : message code, name of file to display */ -/*************************************************************************/ - -void pr_mesg(int msgcode, char *msgfile) -{ - FILE *infile; - char inbuf[BUFSIZ], outbuf[BUFSIZ], *cr; - - if (msgfile && (int) strlen(msgfile) > 0) { - infile = fopen(msgfile, "r"); - if (infile) { - while (fgets(inbuf, sizeof(inbuf), infile) != NULL) { - if ((cr = strchr(inbuf, '\n')) != NULL) - *cr = '\0'; - msg_massage(inbuf, outbuf, sizeof(outbuf)); - lreply(msgcode, "%s", outbuf); - } - fclose(infile); - } - } -} - -/*************************************************************************/ -/* FUNCTION : access_init */ -/* PURPOSE : Read and parse the access lists to set things up */ -/* ARGUMENTS : none */ -/*************************************************************************/ - -void access_init(void) -{ - struct aclmember *entry; - static struct stat sbuf_last; - struct stat sbuf_cur; - - if (!use_accessfile) - return; - - if (stat(_path_ftpaccess, &sbuf_cur) != 0) { - syslog(LOG_ERR, "cannot stat access file %s: %s", _path_ftpaccess, - strerror(errno)); - return; - } - /* only reload the ftpaccess file if its changed */ - if ((sbuf_last.st_mtime == sbuf_cur.st_mtime) && - (sbuf_last.st_ino == sbuf_cur.st_ino) && - (sbuf_last.st_dev == sbuf_cur.st_dev)) - return; - - sbuf_last = sbuf_cur; - -#ifdef OTHER_PASSWD - strcpy(_path_passwd, "/etc/passwd"); -#ifdef SHADOW_PASSWORD - strcpy(_path_shadow, "/etc/shadow"); -#endif -#endif -#if defined(USE_PAM) && defined(OTHER_PASSWD) - use_pam = 1; -#endif - Shutdown[0] = '\0'; - keepalive = 0; - - if (!readacl(_path_ftpaccess)) - return; - (void) parseacl(); - - entry = (struct aclmember *) NULL; - if (getaclentry("shutdown", &entry) && ARG0 != NULL) - (void) strncpy(Shutdown, ARG0, sizeof(Shutdown)); -#ifdef OTHER_PASSWD - entry = (struct aclmember *) NULL; - while (getaclentry("passwd", &entry) && ARG0 != NULL) { - strcpy(_path_passwd, ARG0); -#ifdef USE_PAM - use_pam = 0; -#endif - } -#ifdef SHADOW_PASSWORD - entry = (struct aclmember *) NULL; - while (getaclentry("shadow", &entry) && ARG0 != NULL) { - strcpy(_path_shadow, ARG0); -#ifdef USE_PAM - use_pam = 0; -#endif - } -#endif -#endif - entry = (struct aclmember *) NULL; - if (getaclentry("keepalive", &entry) && ARG0 != NULL) - if (!strcasecmp(ARG0, "yes")) - keepalive = 1; -} - -/*************************************************************************/ -/* FUNCTION : access_ok */ -/* PURPOSE : Check the anonymous FTP access lists to see if this */ -/* access is permitted. */ -/* ARGUMENTS : reply code to use */ -/*************************************************************************/ - -int access_ok(int msgcode) -{ - char class[BUFSIZ], msgfile[MAXPATHLEN]; - int limit; - int nice_delta; - - if (!use_accessfile) - return (1); - - if (aclbuf == NULL) { - syslog(LOG_NOTICE, - "ACCESS DENIED (error reading access file) TO %s", - remoteident); - return (0); - } - if (acl_deny(msgfile)) { -#ifndef HELP_CRACKERS - memcpy(DelayedMessageFile, msgfile, sizeof(msgfile)); -#else - pr_mesg(msgcode, msgfile); -#endif - syslog(LOG_NOTICE, "ACCESS DENIED (deny command) TO %s", - remoteident); - return (0); - } - /* if user is not in any class, deny access */ - if (!acl_getclass(class)) { - syslog(LOG_NOTICE, "ACCESS DENIED (not in any class) TO %s", - remoteident); - return (0); - } - - limit = acl_getlimit(class, msgfile); - if (acl_join(class, limit) < 0) { -#ifdef LOG_TOOMANY - syslog(LOG_NOTICE, "ACCESS DENIED (user limit %d; class %s) TO %s", - limit, class, remoteident); -#endif -#ifndef HELP_CRACKERS - memcpy(DelayedMessageFile, msgfile, sizeof(msgfile)); -#else - pr_mesg(msgcode, msgfile); -#endif - return (-1); - } - - if ((nice_delta = acl_getnice(class))) { - if (nice_delta < 0) - syslog(LOG_NOTICE, "Process nice value adjusted by %d", nice_delta); - nice(nice_delta); - } - acl_getdefumask(class); - acl_tcpwindow(class); -#ifdef TRANSFER_COUNT -#ifdef TRANSFER_LIMIT - acl_filelimit(class); - acl_datalimit(class); -#ifdef RATIO - acl_downloadrate(class); -#endif -#endif -#endif - acl_bufsize(); - get_xferlog_format(); - return (1); -} diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/acl.c b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/acl.c deleted file mode 100644 index 5df3f3db47..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/acl.c +++ /dev/null @@ -1,195 +0,0 @@ -#pragma ident "%Z%%M% %I% %E% SMI" - -/**************************************************************************** - - Copyright (c) 1999,2000 WU-FTPD Development Group. - All rights reserved. - - Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 - The Regents of the University of California. - Portions Copyright (c) 1993, 1994 Washington University in Saint Louis. - Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc. - Portions Copyright (c) 1989 Massachusetts Institute of Technology. - Portions Copyright (c) 1998 Sendmail, Inc. - Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman. - Portions Copyright (c) 1997 by Stan Barber. - Portions Copyright (c) 1997 by Kent Landfield. - Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 - Free Software Foundation, Inc. - - Use and distribution of this software and its source code are governed - by the terms and conditions of the WU-FTPD Software License ("LICENSE"). - - If you did not receive a copy of the license, it may be obtained online - at http://www.wu-ftpd.org/license.html. - - $Id: acl.c,v 1.9 2000/07/01 18:17:38 wuftpd Exp $ - -****************************************************************************/ -#include "config.h" - -#include -#include -#include -#ifdef HAVE_SYS_SYSLOG_H -#include -#endif -#if defined(HAVE_SYSLOG_H) || (!defined(AUTOCONF) && !defined(HAVE_SYS_SYSLOG_H)) -#include -#endif - -#include -#include -#include - -#ifdef HAVE_PATHS_H -#include -#endif -#include "pathnames.h" -#include "extensions.h" -#include "proto.h" - -char *aclbuf = NULL; -static struct aclmember *aclmembers; - -/*************************************************************************/ -/* FUNCTION : getaclentry */ -/* PURPOSE : Retrieve a named entry from the ACL */ -/* ARGUMENTS : pointer to the keyword and a handle to the acl members */ -/* RETURNS : pointer to the acl member containing the keyword or NULL */ -/*************************************************************************/ - -struct aclmember *getaclentry(char *keyword, struct aclmember **next) -{ - do { - if (!*next) - *next = aclmembers; - else - *next = (*next)->next; - } while (*next && strcasecmp((*next)->keyword, keyword)); - - return (*next); -} - -/*************************************************************************/ -/* FUNCTION : parseacl */ -/* PURPOSE : Parse the acl buffer into its components */ -/* ARGUMENTS : A pointer to the acl file */ -/* RETURNS : nothing */ -/*************************************************************************/ - -void parseacl(void) -{ - char *ptr, *aclptr = aclbuf, *line; - int cnt; - struct aclmember *member, *acltail; - - if (!aclbuf || !(*aclbuf)) - return; - - aclmembers = (struct aclmember *) NULL; - acltail = (struct aclmember *) NULL; - - while (*aclptr != '\0') { - line = aclptr; - while (*aclptr && *aclptr != '\n') - aclptr++; - *aclptr++ = (char) NULL; - - /* deal with comments */ - if ((ptr = strchr(line, '#')) != NULL) - /* allowed escaped '#' chars for path-filter (DiB) */ - if ((ptr > aclbuf) && (*(ptr - 1) != '\\')) - *ptr = '\0'; - - ptr = strtok(line, " \t"); - if (ptr) { - member = (struct aclmember *) calloc(1, sizeof(struct aclmember)); - - if (member == NULL) { - syslog(LOG_ERR, "calloc error parsing acl"); - exit(1); - } - (void) strncpy(member->keyword, ptr, MAXKWLEN); - member->keyword[MAXKWLEN - 1] = '\0'; - cnt = 0; - while ((ptr = strtok(NULL, " \t")) != NULL) { - if (cnt >= MAXARGS) { - syslog(LOG_ERR, - "Too many args (>%d) in ftpaccess: %s %s %s %s %s ...", - MAXARGS - 1, member->keyword, member->arg[0], - member->arg[1], member->arg[2], member->arg[3]); - break; - } - member->arg[cnt++] = ptr; - } - if (acltail) - acltail->next = member; - acltail = member; - if (!aclmembers) - aclmembers = member; - } - } -} - -/*************************************************************************/ -/* FUNCTION : readacl */ -/* PURPOSE : Read the acl into memory */ -/* ARGUMENTS : The pathname of the acl */ -/* RETURNS : 0 if error, 1 if no error */ -/*************************************************************************/ - -int readacl(char *aclpath) -{ - FILE *aclfile; - struct stat finfo; - struct aclmember *member; - extern int use_accessfile; - - if (!use_accessfile) - return (0); - - while (aclmembers) { - member = aclmembers->next; - free(aclmembers); - aclmembers = member; - } - - if (aclbuf) { - free(aclbuf); - aclbuf = NULL; - } - - if ((aclfile = fopen(aclpath, "r")) == NULL) { - syslog(LOG_ERR, "cannot open access file %s: %s", aclpath, - strerror(errno)); - return (0); - } - if (fstat(fileno(aclfile), &finfo) != 0) { - syslog(LOG_ERR, "cannot fstat access file %s: %s", aclpath, - strerror(errno)); - (void) fclose(aclfile); - return (0); - } - if (finfo.st_size == 0) { - aclbuf = (char *) calloc(1, 1); - } - else { - if (!(aclbuf = (char *) malloc((size_t) finfo.st_size + 1))) { - syslog(LOG_ERR, "could not malloc aclbuf (%d bytes)", (size_t) finfo.st_size + 1); - (void) fclose(aclfile); - return (0); - } - if (!fread(aclbuf, (size_t) finfo.st_size, 1, aclfile)) { - syslog(LOG_ERR, "error reading acl file %s: %s", aclpath, - strerror(errno)); - free(aclbuf); - aclbuf = NULL; - (void) fclose(aclfile); - return (0); - } - *(aclbuf + finfo.st_size) = '\0'; - } - (void) fclose(aclfile); - return (1); -} diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/authenticate.c b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/authenticate.c deleted file mode 100644 index 8297eeeb9d..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/authenticate.c +++ /dev/null @@ -1,78 +0,0 @@ -#pragma ident "%Z%%M% %I% %E% SMI" - -/**************************************************************************** - - Copyright (c) 1999,2000 WU-FTPD Development Group. - All rights reserved. - - Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 - The Regents of the University of California. - Portions Copyright (c) 1993, 1994 Washington University in Saint Louis. - Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc. - Portions Copyright (c) 1989 Massachusetts Institute of Technology. - Portions Copyright (c) 1998 Sendmail, Inc. - Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman. - Portions Copyright (c) 1997 by Stan Barber. - Portions Copyright (c) 1997 by Kent Landfield. - Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 - Free Software Foundation, Inc. - - Use and distribution of this software and its source code are governed - by the terms and conditions of the WU-FTPD Software License ("LICENSE"). - - If you did not receive a copy of the license, it may be obtained online - at http://www.wu-ftpd.org/license.html. - - $Id: authenticate.c,v 1.9 2000/07/01 18:17:38 wuftpd Exp $ - -****************************************************************************/ -#include "config.h" -#include -#include -#include "authuser.h" -#include "authenticate.h" -#include "proto.h" - -#define AUTHNAMESIZE 100 - -char authuser[AUTHNAMESIZE]; -int authenticated; - -extern int disable_rfc931; -extern unsigned int timeout_rfc931; - -/* - * Ideally more authentication schemes would be called from here, with the - * strongest called first. One possible double-check would be to verify that - * the results of all authentication calls (returning identical data!) are - * checked against each other. - */ -int wu_authenticate(void) -{ - char *user; -#if USE_A_RFC931 - unsigned long in; - unsigned short local, remote; -#endif /* USE_A_RFC931 */ - - authenticated = 0; /* this is a bitmask, one bit per method */ - - user = "*"; - -#if USE_A_RFC931 - if (disable_rfc931 || (timeout_rfc931 == 0)) - user = "*"; - else if (auth_fd(0, &in, &local, &remote) == -1) - user = "?"; /* getpeername/getsockname failure */ - else { - if (!(user = auth_tcpuser(in, local, remote))) - user = "*"; /* remote host doesn't support RFC 931 */ - else - authenticated |= A_RFC931; - } -#endif /* USE_A_RFC931 */ - - strncpy(authuser, user, sizeof(authuser)); - authuser[AUTHNAMESIZE - 1] = '\0'; - return (0); -} diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/authenticate.h b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/authenticate.h deleted file mode 100644 index 2dab5b10c0..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/authenticate.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma ident "%Z%%M% %I% %E% SMI" - -/**************************************************************************** - Copyright (c) 1999,2000 WU-FTPD Development Group. - All rights reserved. - - Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 - The Regents of the University of California. - Portions Copyright (c) 1993, 1994 Washington University in Saint Louis. - Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc. - Portions Copyright (c) 1989 Massachusetts Institute of Technology. - Portions Copyright (c) 1998 Sendmail, Inc. - Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman. - Portions Copyright (c) 1997 by Stan Barber. - Portions Copyright (c) 1997 by Kent Landfield. - Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 - Free Software Foundation, Inc. - - Use and distribution of this software and its source code are governed - by the terms and conditions of the WU-FTPD Software License ("LICENSE"). - - If you did not receive a copy of the license, it may be obtained online - at http://www.wu-ftpd.org/license.html. - - $Id: authenticate.h,v 1.8 2000/07/01 18:17:38 wuftpd Exp $ - -****************************************************************************/ -/* - * When of the supported authentication methods the ftp server will attempt - * to use. Define as 1 to enable, 0 to disable. - */ - -#ifdef USE_RFC931 -#define USE_A_RFC931 1 /* Use RFC931-style authentication */ -#else -#define USE_A_RFC931 0 /* No RFC931-style authentication */ -#endif - -/* Bitmasks used to identify authentication methods that returned a result */ -#define A_RFC931 1 << 0; /* RFC931 */ diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/authuser.h b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/authuser.h deleted file mode 100644 index d702f8100a..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/authuser.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma ident "%Z%%M% %I% %E% SMI" - -/**************************************************************************** - - Copyright (c) 1999,2000 WU-FTPD Development Group. - All rights reserved. - - Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 - The Regents of the University of California. - Portions Copyright (c) 1993, 1994 Washington University in Saint Louis. - Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc. - Portions Copyright (c) 1989 Massachusetts Institute of Technology. - Portions Copyright (c) 1998 Sendmail, Inc. - Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman. - Portions Copyright (c) 1997 by Stan Barber. - Portions Copyright (c) 1997 by Kent Landfield. - Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 - Free Software Foundation, Inc. - - Use and distribution of this software and its source code are governed - by the terms and conditions of the WU-FTPD Software License ("LICENSE"). - - If you did not receive a copy of the license, it may be obtained online - at http://www.wu-ftpd.org/license.html. - - $Id: authuser.h,v 1.4 2000/07/01 18:36:28 wuftpd Exp $ - -****************************************************************************/ -#ifndef AUTHUSER_H -#define AUTHUSER_H - -extern unsigned short auth_tcpport; - -extern char *auth_xline(register char *user, register int fd, register long unsigned int *in); - -extern int auth_fd(register int fd, register long unsigned int *in, register short unsigned int *local, register short unsigned int *remote); - -extern char *auth_tcpuser(register long unsigned int in, register short unsigned int local, register short unsigned int remote); -#endif diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ckconfig.c b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ckconfig.c deleted file mode 100644 index 208442e5f3..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ckconfig.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/**************************************************************************** - - Copyright (c) 1999,2000 WU-FTPD Development Group. - All rights reserved. - - Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 - The Regents of the University of California. - Portions Copyright (c) 1993, 1994 Washington University in Saint Louis. - Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc. - Portions Copyright (c) 1989 Massachusetts Institute of Technology. - Portions Copyright (c) 1998 Sendmail, Inc. - Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman. - Portions Copyright (c) 1997 by Stan Barber. - Portions Copyright (c) 1997 by Kent Landfield. - Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 - Free Software Foundation, Inc. - - Use and distribution of this software and its source code are governed - by the terms and conditions of the WU-FTPD Software License ("LICENSE"). - - If you did not receive a copy of the license, it may be obtained online - at http://www.wu-ftpd.org/license.html. - - $Id: ckconfig.c,v 1.10 2000/07/01 18:17:38 wuftpd Exp $ - -****************************************************************************/ -#include "config.h" -#ifndef HOST_ACCESS -#define HOST_ACCESS 1 -#endif -#include -#include -#include -#include -#include -#include "pathnames.h" -#if defined(VIRTUAL) && defined(INET6) -#include -#endif - -/* Prototypes */ -#ifdef VIRTUAL -extern int read_servers_line(FILE *, char *, size_t, char *, size_t); -#endif -void print_copyright(void); - -int main(int argc, char **argv) -{ - struct stat sbuf; - char *sp; - char buf[1024]; - int c; - -#ifdef VIRTUAL - FILE *svrfp; - char accesspath[MAXPATHLEN]; -#ifdef INET6 - char hostaddress[INET6_ADDRSTRLEN]; -#else - char hostaddress[32]; -#endif -#endif - - if (argc > 1) { - while ((c = getopt(argc, argv, "V")) != EOF) { - switch (c) { - case 'V': - print_copyright(); - exit(0); - default: - fprintf(stderr, "usage: %s [-V]\n", argv[0]); - exit(1); - } - } - } - - /* _PATH_FTPUSERS */ - fprintf(stdout, "Checking _PATH_FTPUSERS :: %s\n", _PATH_FTPUSERS); - if ((stat(_PATH_FTPUSERS, &sbuf)) < 0) - printf("I can't find it... look in doc/examples for an example.\n"); - else - printf("ok.\n"); - -#ifdef VIRTUAL - - /* _PATH_FTPSERVERS */ - fprintf(stdout, "\nChecking _PATH_FTPSERVERS :: %s\n", _PATH_FTPSERVERS); - if ((stat(_PATH_FTPSERVERS, &sbuf)) < 0) - printf("I can't find it... look in doc/examples for an example.\n"); - else { - printf("ok.\n"); - /* Need to check the access files specified in the ftpservers file. */ - if ((svrfp = fopen(_PATH_FTPSERVERS, "r")) == NULL) - printf("I can't open it! check permissions and run ckconfig again.\n"); - else { - while (read_servers_line(svrfp, hostaddress, sizeof(hostaddress), - accesspath, sizeof(accesspath)) == 1) { - fprintf(stderr, "\nChecking accessfile for %s :: %s\n", hostaddress, accesspath); - /* - ** check to see that a valid directory value was - ** supplied and not something such as "INTERNAL" - ** - ** It is valid to have a string such as "INTERNAL" in the - ** ftpservers entry. This is not an error. Silently ignore it. - */ - if (stat(accesspath, &sbuf) == 0) { - if ((sbuf.st_mode & S_IFMT) == S_IFDIR) - printf("ok.\n"); - else { - printf("Check servers file and make sure only directories are listed...\n"); - printf("look in doc/examples for an example.\n"); - } - } - else - printf("Internal ftpaccess usage specified... ok.\n"); - } - fclose(svrfp); - } - } -#endif - - /* _PATH_FTPACCESS */ - fprintf(stdout, "\nChecking _PATH_FTPACCESS :: %s\n", _PATH_FTPACCESS); - if ((stat(_PATH_FTPACCESS, &sbuf)) < 0) - printf("I can't find it... look in doc/examples for an example.\n"); - else - printf("ok.\n"); - - /* _PATH_PIDNAMES */ - fprintf(stdout, "\nChecking _PATH_PIDNAMES :: %s\n", _PATH_PIDNAMES); - (void) strlcpy(buf, _PATH_PIDNAMES, sizeof(buf)); - sp = (char *) strrchr(buf, '/'); - *sp = '\0'; - if ((stat(buf, &sbuf)) < 0) { - printf("I can't find it...\n"); - printf("You need to make this directory [%s] in order for\n", buf); - printf("the limit and user count functions to work.\n"); - } - else - printf("ok.\n"); - - /* _PATH_CVT */ - fprintf(stdout, "\nChecking _PATH_CVT :: %s\n", _PATH_CVT); - if ((stat(_PATH_CVT, &sbuf)) < 0) - printf("I can't find it... look in doc/examples for an example.\n"); - else - printf("ok.\n"); - - /* _PATH_XFERLOG */ - fprintf(stdout, "\nChecking _PATH_XFERLOG :: %s\n", _PATH_XFERLOG); - if ((stat(_PATH_XFERLOG, &sbuf)) < 0) { - printf("I can't find it... \n"); - printf("Don't worry, it will be created automatically by the\n"); - printf("server if you do transfer logging.\n"); - } - else - printf("ok.\n"); - - /* _PATH_PRIVATE */ - fprintf(stdout, "\nChecking _PATH_PRIVATE :: %s\n", _PATH_PRIVATE); - if ((stat(_PATH_PRIVATE, &sbuf)) < 0) { - printf("I can't find it... look in doc/examples for an example.\n"); - printf("You only need this if you want SITE GROUP and SITE GPASS\n"); - printf("functionality. If you do, you will need to edit the example.\n"); - } - else - printf("ok.\n"); - - /* _PATH_FTPHOSTS */ - fprintf(stdout, "\nChecking _PATH_FTPHOSTS :: %s\n", _PATH_FTPHOSTS); - if ((stat(_PATH_FTPHOSTS, &sbuf)) < 0) { - printf("I can't find it... look in doc/examples for an example.\n"); - printf("You only need this if you are using the HOST ACCESS features\n"); - printf("of the server.\n"); - } - else - printf("ok.\n"); - return (0); -} diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/config.h b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/config.h deleted file mode 100644 index 7aa7c1af20..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/config.h +++ /dev/null @@ -1,268 +0,0 @@ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* src/config.h. Generated automatically by configure. */ -/**************************************************************************** - - Copyright (c) 1999,2000 WU-FTPD Development Group. - All rights reserved. - - Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 - The Regents of the University of California. - Portions Copyright (c) 1993, 1994 Washington University in Saint Louis. - Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc. - Portions Copyright (c) 1989 Massachusetts Institute of Technology. - Portions Copyright (c) 1998 Sendmail, Inc. - Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman. - Portions Copyright (c) 1997 by Stan Barber. - Portions Copyright (c) 1997 by Kent Landfield. - Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 - Free Software Foundation, Inc. - - Use and distribution of this software and its source code are governed - by the terms and conditions of the WU-FTPD Software License ("LICENSE"). - - If you did not receive a copy of the license, it may be obtained online - at http://www.wu-ftpd.org/license.html. - - $Id: config.h.in,v 1.31 2000/07/01 18:04:21 wuftpd Exp $ - -****************************************************************************/ - -#define SOLARIS_2 -#define SVR4 -#define HAVE_STATVFS -#define NO_UTMP -#define HAVE_FGETPWENT -#define HAVE_MKSTEMP -#define HAVE_SYS_SENDFILE_H - -/* - * Configuration file for autoconf - will be modified by configure - */ - -#define HAVE_FCNTL_H 1 -#define HAVE_DIRENT_H 1 -#define HAVE_REGEX_H 1 -#define TIME_WITH_SYS_TIME 1 -/* #undef HAVE_SYS_TIME_H */ -/* #undef HAVE_TIME_H */ -/* #undef HAVE_MNTENT_H */ -#define HAVE_SYS_MNTENT_H 1 -#define HAVE_SYS_MNTTAB_H 1 -/* #undef HAVE_NDIR_H */ -#define HAVE_STRING_H 1 -/* #undef HAVE_SYS_DIR_H */ -/* #undef HAVE_SYS_NDIR_H */ -/* #undef HAVE_SYS_QUOTA_H */ -#define HAVE_SYS_FS_UFS_QUOTA_H 1 -/* #undef HAVE_UFS_QUOTA_H */ -/* #undef HAVE_JFS_QUOTA_H */ -/* #undef HAVE_UFS_UFS_QUOTA_H */ -/* #undef HAVE_LINUX_QUOTA_H */ -#define HAVE_STDLIB_H 1 -#define HAVE_UNISTD_H 1 -#define HAVE_SYS_TYPES_H 1 -#define HAVE_GLOB_H 1 -#define HAVE_GRP_H 1 -#define HAVE_SHADOW_H 1 -/* #undef HAVE_VMSDIR_H */ - -/* #undef QUOTA_INODE */ -#define QUOTA_DEVICE -#define QSORT_IS_VOID 1 - -#define HAVE_SIGPROCMASK 1 -#define HAVE_VSNPRINTF 1 -/* #undef HAVE_DIRFD */ -/* #undef HAVE_FLOCK */ -#define HAVE_FTW 1 -#define HAVE_GETCWD 1 -#define HAVE_GETDTABLESIZE 1 -#define HAVE_GETRLIMIT 1 -/* #undef HAVE_PSTAT */ -#define HAVE_LSTAT 1 -#define HAVE_VPRINTF 1 -#define HAVE_SNPRINTF 1 -#define HAVE_REGEX 1 -#define HAVE_REGEXEC 1 -#define HAVE_SETSID 1 -#define HAVE_MEMMOVE 1 -#define HAVE_STRTOUL 1 -/* #undef HAVE_SIGLIST */ -#define FACILITY LOG_DAEMON - -#define HAVE_LIMITS_H 1 -#define HAVE_VALUES_H 1 -/* #undef HAVE_BSD_BSD_H */ -#define HAVE_SYS_PARAM_H 1 -/* #undef NEED_LIMITS_H */ -/* #undef NEED_VALUES_H */ -/* #undef NEED_BSD_BSD_H */ -#define NEED_SYS_PARAM_H 1 -#if defined(HAVE_SYS_PARAM_H) && defined(NEED_SYS_PARAM_H) -#include -#endif -#if defined(HAVE_VALUES_H) && defined(NEED_VALUES_H) -#include -#endif -#if defined(HAVE_LIMITS_H) && defined(NEED_LIMITS_H) -#include -#endif -#if defined(HAVE_BSD_BSD_H) && defined(NEED_BSD_BSD_H) -#include -#endif -/* #undef NBBY */ - -#define SIGNAL_TYPE void -#define HAVE_SETUID 1 -#define HAVE_SETEUID 1 -/* #undef HAVE_SETREUID */ -/* #undef HAVE_SETRESUID */ -#define HAVE_SETEGID 1 -/* #undef HAVE_SETREGID */ -/* #undef HAVE_SETRESGID */ -#define HAVE_ST_BLKSIZE 1 -#define HAVE_SYSCONF 1 -#define HAVE_SYS_SYSTEMINFO_H 1 -/* #undef HAVE_PATHS_H */ -#define HAVE_SYSLOG_H 1 -#define HAVE_SYS_SYSLOG_H 1 -#define HAVE_FCHDIR 1 -/* #undef HAVE_QUOTACTL */ -#define HAS_OLDSTYLE_GETMNTENT -/* #undef HAS_PW_EXPIRE */ -#define SHADOW_PASSWORD 1 -#define AUTOCONF 1 -#if _FILE_OFFSET_BITS == 64 -#define L_FORMAT "lld" -#else -#define L_FORMAT "ld" -#endif -#define T_FORMAT "ld" -#define PW_UID_FORMAT "ld" -#define GR_GID_FORMAT "ld" - -/* #undef HAVE_UT_UT_HOST */ -#define HAVE_UT_UT_EXIT_E_TERMINATION 1 - -/* Here instead of everywhere: */ -#include -#include -#ifdef HAVE_UNISTD_H -#include -#endif - -/* Newer systems will have seteuid/setegid */ -/* Older systems may have the BSD setreuid/setregid */ -/* HP/UX has setresuid/setresgid */ -/* Some SCO systems appearently have none of this. - so if HAVE_SETUID is not defined we'll presume it's - all needed since we're compiling support/sco.c */ - -#ifdef HAVE_SETUID - -#ifndef HAVE_SETEUID -#ifdef HAVE_SETREUID -#define seteuid(euid) setreuid(-1,(euid)) -#else -#ifdef HAVE_SETRESUID -#define seteuid(euid) setresuid(-1,(euid),-1) -#else -#error No seteuid() functions. -#endif -#endif -#endif - -#ifndef HAVE_SETEGID -#ifdef HAVE_SETREGID -#define setegid(egid) setregid(-1,(egid)) -#else -#ifdef HAVE_SETRESGID -#define setegid(egid) setresgid(-1,(egid),-1) -#else -#error No setegid() functions. -#endif -#endif -#endif - -#endif /* HAVE_SETUID */ - -#ifndef HAVE_FCHDIR -#define HAS_NO_FCHDIR 1 -#endif -#ifndef HAVE_QUOTACTL -#define HAS_NO_QUOTACTL -#endif -#ifdef HAVE_SYS_SYSTEMINFO_H -#define HAVE_SYSINFO 1 -#endif -#ifndef HAVE_SETSID -#define NO_SETSID 1 -#endif - -#ifndef HAVE_MEMMOVE -#define memmove(a,b,c) bcopy(b,a,c) -#endif -#ifndef HAVE_STRTOUL -#define strtoul(a,b,c) (unsigned long)strtol(a,b,c) -#endif - -#ifndef RAND_MAX -#define RAND_MAX 2147483647 -#endif - -#define USE_PAM 1 - -/* - * Socket macros which help with socket structure manipulation in a mixed - * IPv4 / IPv6 environment. - */ -#ifdef INET6 -#define HAVE_SIN6_SCOPE_ID -#ifdef HAVE__SS_FAMILY -#define ss_family __ss_family -#endif -#define SOCKSTORAGE sockaddr_storage -#define SOCK_FAMILY(ss) ((ss).ss_family) -#define SOCK_PORT(ss) ((ss).ss_family == AF_INET6 ? \ - ((struct sockaddr_in6 *)&(ss))->sin6_port : \ - ((struct sockaddr_in *)&(ss))->sin_port) -#define SOCK_LEN(ss) ((ss).ss_family == AF_INET6 ? \ - sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)) -#define SOCK_ADDR(ss) ((ss).ss_family == AF_INET6 ? \ - (void *)&((struct sockaddr_in6 *)&(ss))->sin6_addr : \ - (void *)&((struct sockaddr_in *)&(ss))->sin_addr) -#define SET_SOCK_FAMILY(ss, family) (SOCK_FAMILY(ss) = (family)) -#define SET_SOCK_PORT(ss, port) \ - ((ss).ss_family == AF_INET6 ? \ - (((struct sockaddr_in6 *)&(ss))->sin6_port = (port)) : \ - (((struct sockaddr_in *)&(ss))->sin_port = (port))) -#define SET_SOCK_ADDR4(ss, addr) ((void)(sock_set_inaddr(&(ss), (addr)))) -#define SET_SOCK_ADDR_ANY(ss) \ - ((void)((ss).ss_family == AF_INET6 ? \ - (void)(((struct sockaddr_in6 *)&(ss))->sin6_addr = \ - in6addr_any) : \ - (void)(((struct sockaddr_in *)&(ss))->sin_addr.s_addr = \ - htonl(INADDR_ANY)))) -#define SET_SOCK_SCOPE(dst, src) sock_set_scope(&(dst), &(src)) -#else -#define SOCKSTORAGE sockaddr_in -#define SOCK_FAMILY(sin) ((sin).sin_family) -#define SOCK_PORT(sin) ((sin).sin_port) -#define SOCK_LEN(sin) (sizeof(sin)) -#define SOCK_ADDR(sin) ((void *)&(sin).sin_addr) -#define SET_SOCK_FAMILY(sin, family) (SOCK_FAMILY(sin) = (family)) -#define SET_SOCK_PORT(sin, port) ((sin).sin_port = (port)) -#define SET_SOCK_ADDR4(sin, addr) ((sin).sin_addr = (addr)) -#define SET_SOCK_ADDR_ANY(sin) ((sin).sin_addr.s_addr = htonl(INADDR_ANY)) -#endif /* INET6 */ - -#define delay_signaling() -#define enable_signaling() - -#include "wu_config.h" diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/conversions.c b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/conversions.c deleted file mode 100644 index 3feabde024..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/conversions.c +++ /dev/null @@ -1,198 +0,0 @@ -#pragma ident "%Z%%M% %I% %E% SMI" - -/**************************************************************************** - - Copyright (c) 1999,2000 WU-FTPD Development Group. - All rights reserved. - - Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 - The Regents of the University of California. - Portions Copyright (c) 1993, 1994 Washington University in Saint Louis. - Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc. - Portions Copyright (c) 1989 Massachusetts Institute of Technology. - Portions Copyright (c) 1998 Sendmail, Inc. - Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman. - Portions Copyright (c) 1997 by Stan Barber. - Portions Copyright (c) 1997 by Kent Landfield. - Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 - Free Software Foundation, Inc. - - Use and distribution of this software and its source code are governed - by the terms and conditions of the WU-FTPD Software License ("LICENSE"). - - If you did not receive a copy of the license, it may be obtained online - at http://www.wu-ftpd.org/license.html. - - $Id: conversions.c,v 1.10 2000/07/01 18:17:38 wuftpd Exp $ - -****************************************************************************/ -#include "config.h" - -#include -#include -#ifdef HAVE_SYS_SYSLOG_H -#include -#endif -#if defined(HAVE_SYSLOG_H) || (!defined(AUTOCONF) && !defined(HAVE_SYS_SYSLOG_H)) -#include -#endif - -extern char *strsep(char **, const char *); - -#include -#include -#include -#include "conversions.h" -#include "extensions.h" -#include "pathnames.h" -#include "proto.h" - -/*************************************************************************/ -/* FUNCTION : readconv */ -/* PURPOSE : Read the conversions into memory */ -/* ARGUMENTS : The pathname of the conversion file */ -/* RETURNS : 0 if error, 1 if no error */ -/*************************************************************************/ - -char *convbuf = NULL; -struct convert *cvtptr; - -struct str2int { - char *string; - int value; -}; - -struct str2int c_list[] = -{ - {"T_REG", T_REG}, - {"T_ASCII", T_ASCII}, - {"T_DIR", T_DIR}, - {"O_COMPRESS", O_COMPRESS}, - {"O_UNCOMPRESS", O_UNCOMPRESS}, - {"O_TAR", O_TAR}, - {NULL, 0}, -}; - -static int conv(char *str) -{ - int rc = 0; - int counter; - - /* check for presence of ALL items in string... */ - - if (str) - for (counter = 0; c_list[counter].string; ++counter) - if (strstr(str, c_list[counter].string)) - rc = rc | c_list[counter].value; - return (rc); -} - -static int readconv(char *convpath) -{ - FILE *convfile; - struct stat finfo; - - if ((convfile = fopen(convpath, "r")) == NULL) { - if (errno != ENOENT) - syslog(LOG_ERR, "cannot open conversion file %s: %s", - convpath, strerror(errno)); - return (0); - } - if (fstat(fileno(convfile), &finfo) != 0) { - syslog(LOG_ERR, "cannot fstat conversion file %s: %s", convpath, - strerror(errno)); - (void) fclose(convfile); - return (0); - } - if (finfo.st_size == 0) { - convbuf = (char *) calloc(1, 1); - } - else { - if (!(convbuf = (char *) malloc((size_t) finfo.st_size + 1))) { - syslog(LOG_ERR, "could not malloc convbuf (%d bytes)", (size_t) finfo.st_size + 1); - (void) fclose(convfile); - return (0); - } - if (!fread(convbuf, (size_t) finfo.st_size, 1, convfile)) { - syslog(LOG_ERR, "error reading conv file %s: %s", convpath, - strerror(errno)); - convbuf = NULL; - (void) fclose(convfile); - return (0); - } - *(convbuf + finfo.st_size) = '\0'; - } - (void) fclose(convfile); - return (1); -} - -static void parseconv(void) -{ - char *ptr; - char *convptr = convbuf, *line; - char *argv[8], *p, *val; - struct convert *cptr, *cvttail = (struct convert *) NULL; - int n; - - if (!convbuf || !(*convbuf)) - return; - - /* read through convbuf, stripping comments. */ - while (*convptr != '\0') { - line = convptr; - while (*convptr && *convptr != '\n') - convptr++; - *convptr++ = '\0'; - - /* deal with comments */ - if ((ptr = strchr(line, '#')) != NULL) - *ptr = '\0'; - - if (*line == '\0') - continue; - - /* parse the lines... */ - for (n = 0, p = line; n < 8 && p != NULL; n++) { - val = (char *) strsep(&p, ":\n"); - argv[n] = val; - if ((argv[n][0] == ' ') || (argv[n][0] == '\0')) - argv[n] = NULL; - } - /* check their were 8 fields, if not skip the line... */ - if (n != 8 || p != NULL) - continue; - - /* make sure the required elements are present */ - if ((!argv[0] && !argv[1] && !argv[2] && !argv[3]) || !argv[4] || !argv[7]) - continue; - - /* add element to end of list */ - cptr = (struct convert *) calloc(1, sizeof(struct convert)); - - if (cptr == NULL) { - syslog(LOG_ERR, "calloc error parsing ftpconversions"); - exit(0); - } - if (cvttail) - cvttail->next = cptr; - cvttail = cptr; - if (!cvtptr) - cvtptr = cptr; - - cptr->stripprefix = (char *) argv[0]; - cptr->stripfix = (char *) argv[1]; - cptr->prefix = (char *) argv[2]; - cptr->postfix = (char *) argv[3]; - cptr->external_cmd = (char *) argv[4]; - cptr->types = conv((char *) argv[5]); - cptr->options = conv((char *) argv[6]); - cptr->name = (char *) argv[7]; - } -} - -void conv_init(void) -{ - if ((readconv(_path_cvt)) <= 0) - return; - parseconv(); -} diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/conversions.h b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/conversions.h deleted file mode 100644 index 0fb690b074..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/conversions.h +++ /dev/null @@ -1,45 +0,0 @@ -#pragma ident "%Z%%M% %I% %E% SMI" - -/**************************************************************************** - Copyright (c) 1999,2000 WU-FTPD Development Group. - All rights reserved. - - Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 - The Regents of the University of California. - Portions Copyright (c) 1993, 1994 Washington University in Saint Louis. - Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc. - Portions Copyright (c) 1989 Massachusetts Institute of Technology. - Portions Copyright (c) 1998 Sendmail, Inc. - Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman. - Portions Copyright (c) 1997 by Stan Barber. - Portions Copyright (c) 1997 by Kent Landfield. - Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 - Free Software Foundation, Inc. - - Use and distribution of this software and its source code are governed - by the terms and conditions of the WU-FTPD Software License ("LICENSE"). - - If you did not receive a copy of the license, it may be obtained online - at http://www.wu-ftpd.org/license.html. - - $Id: conversions.h,v 1.5 2000/07/01 18:17:38 wuftpd Exp $ - -****************************************************************************/ - -#define T_REG 1 /* regular files OK */ -#define T_DIR 2 /* directories OK */ -#define T_ASCII 4 /* ASCII transfers OK */ - -struct convert { - struct convert *next; - char *stripprefix; /* prefix to strip from real file */ - char *stripfix; /* postfix to strip from real file */ - char *prefix; /* prefix to add to real file */ - char *postfix; /* postfix to add to real file */ - char *external_cmd; /* command to do conversion */ - int types; /* types: {file,directory} OK to convert */ - int options; /* for logging: which conversion(s) used */ - char *name; /* description of conversion */ -}; - -extern struct convert *cvtptr; diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/domain.c b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/domain.c deleted file mode 100644 index 02dd23ac6c..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/domain.c +++ /dev/null @@ -1,324 +0,0 @@ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/**************************************************************************** - - Copyright (c) 1999,2000 WU-FTPD Development Group. - All rights reserved. - - Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 - The Regents of the University of California. - Portions Copyright (c) 1993, 1994 Washington University in Saint Louis. - Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc. - Portions Copyright (c) 1989 Massachusetts Institute of Technology. - Portions Copyright (c) 1998 Sendmail, Inc. - Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman. - Portions Copyright (c) 1997 by Stan Barber. - Portions Copyright (c) 1997 by Kent Landfield. - Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 - Free Software Foundation, Inc. - - Use and distribution of this software and its source code are governed - by the terms and conditions of the WU-FTPD Software License ("LICENSE"). - - If you did not receive a copy of the license, it may be obtained online - at http://www.wu-ftpd.org/license.html. - - $Id: domain.c,v 1.11 2000/07/01 18:17:38 wuftpd Exp $ - -****************************************************************************/ -/* - * domain.c - Name and address lookup and checking functions - * - * INITIAL AUTHOR - * Nikos Mouat - */ - -#include "config.h" -#include -#include -#include -#include -#ifdef HAVE_SYS_SYSLOG_H -#include -#endif -#if defined(HAVE_SYSLOG_H) || (!defined(AUTOCONF) && !defined(HAVE_SYS_SYSLOG_H)) -#include -#endif -#include -#include -#include -#include "extensions.h" -#include "proto.h" - -/* these should go in a new ftpd.h perhaps? config.h doesn't seem appropriate */ -/* and there does not appear to be a global include file */ -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE !TRUE -#endif - -/**************************************************************************** - * check_name_for_ip() - * This routine checks if the IP address in remote_socket is a valid IP - * address for name. - ***************************************************************************/ -static int check_name_for_ip(char *name, struct SOCKSTORAGE *remote_socket) -{ -#ifdef INET6 - int family; - size_t sockaddrlen, addrlen; - char *raddr, *addr; - struct addrinfo hints, *result, *ai; - - family = SOCK_FAMILY(*remote_socket); - raddr = SOCK_ADDR(*remote_socket); - if ((family == AF_INET6) && - IN6_IS_ADDR_V4MAPPED((struct in6_addr *)raddr)) { - family = AF_INET; - /* move to the IPv4 part of an IPv4-mapped IPv6 address */ - raddr += 12; - } - - if (family == AF_INET6) { - sockaddrlen = sizeof(struct sockaddr_in6); - addrlen = sizeof(struct in6_addr); - } - else { - sockaddrlen = sizeof(struct sockaddr_in); - addrlen = sizeof(struct in_addr); - } - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = family; - - if (getaddrinfo(name, NULL, &hints, &result) == 0) { - for (ai = result; ai != NULL; ai = ai->ai_next) { - if ((family == ai->ai_family) && (sockaddrlen == ai->ai_addrlen)) { - if (family == AF_INET6) - addr = (void *)&((struct sockaddr_in6 *)(ai->ai_addr))->sin6_addr; - else - addr = (void *)&((struct sockaddr_in *)(ai->ai_addr))->sin_addr; - if (memcmp(addr, raddr, addrlen) == 0) { - freeaddrinfo(result); - return TRUE; - } - } - } - freeaddrinfo(result); - } -#else - char **addrl; - struct hostent *hp; - - if ((hp = gethostbyname(name)) != NULL) { - for (addrl = hp->h_addr_list; addrl != NULL; addrl++) { - if (memcmp(&remote_socket->sin_addr, *addrl, - sizeof(struct in_addr)) == 0) - return TRUE; - } - } -#endif /* INET6 */ - - /* no matching IP's */ - return FALSE; -} - -/**************************************************************************** - * lookup() - * This routine returns the result of the lookup specified by dnsarg, - * which is either "refuse_no_reverse" or "refuse_mismatch", using the - * remote host's IP address. - ***************************************************************************/ -static int lookup(char *dnsarg) -{ - static int rhost_matches = FALSE; - static int rhost_matches_set = FALSE; - extern struct SOCKSTORAGE his_addr; - extern int rhlookup, nameserved; - extern char remotehost[]; - - /* skip lookups when not looking up the remote host's name */ - if (!rhlookup) - return FALSE; - - if (strcasecmp(dnsarg, "refuse_no_reverse") == 0) - return nameserved; - - /* refuse_mismatch */ - if (!rhost_matches_set) { - if (nameserved) { - /* - * We have the hostname based on the real IP address. Lookup - * the hostname to make sure the real IP address is listed as - * a valid address for the hostname. - */ - rhost_matches = check_name_for_ip(remotehost, &his_addr); - } - else - rhost_matches = TRUE; /* no reverse, nothing to match */ - rhost_matches_set = TRUE; - } - return rhost_matches; -} - -/**************************************************************************** - * dns_check() - * This routine returns FALSE if the operation specified by dnsarg is - * FALSE and "override" wasn't specified, otherwise it returns TRUE. - ***************************************************************************/ -static int dns_check(char *dnsarg) -{ - struct aclmember *entry = NULL; - int rc = TRUE; - - /* check the config to see if we care */ - /* dns refuse_mismatch|refuse_no_reverse [override] */ - while (getaclentry("dns", &entry)) { - if (!ARG0 || !ARG1) - continue; - if (!strcasecmp(ARG0, dnsarg)) { - FILE *msg_file; - char linebuf[MAXPATHLEN]; - char outbuf[MAXPATHLEN]; - int code = 530; - char *crptr; - - /* lookups can be slow, so only call now result is needed */ - if (!lookup(dnsarg)) { - /* ok, so we need to kick out this user */ - - /* check to see if admin wants to override */ - if (ARG2 && (!strcasecmp(ARG2, "override"))) { - /* Administrative override - but display warning anyway */ - code = 220; - } - - msg_file = fopen(ARG1, "r"); - if (msg_file != NULL) { - while (fgets(linebuf, sizeof(linebuf), msg_file)) { - if ((crptr = strchr(linebuf, '\n')) != NULL) - *crptr = '\0'; - msg_massage(linebuf, outbuf, sizeof(outbuf)); - lreply(code, "%s", outbuf); - } - fclose(msg_file); -#ifndef NO_SUCKING_NEWLINES - lreply(code, ""); -#endif - if (code == 530) { - reply(code, ""); - rc = FALSE; - } - else { - lreply(code, "Administrative Override. Permission granted."); - lreply(code, ""); - } - } - } - } - } - return rc; -} - -/**************************************************************************** - * check_rhost_reverse() - * This routine returns FALSE if the remote host's IP address has no - * associated name and access should be refused, otherwise it returns TRUE. - ***************************************************************************/ -int check_rhost_reverse(void) -{ - return dns_check("refuse_no_reverse"); -} - -/**************************************************************************** - * check_rhost_matches() - * This routine returns FALSE if the remote host's IP address isn't listed - * as a valid IP address for the remote hostname and access should be - * refused, otherwise it returns TRUE. - ***************************************************************************/ -int check_rhost_matches(void) -{ - return dns_check("refuse_mismatch"); -} - -/**************************************************************************** - * rhostlookup() - * This routine returns TRUE if the remote host's name of a connection - * from remoteaddr should be looked up, otherwise it returns FALSE. - ***************************************************************************/ -int rhostlookup(char *remoteaddr) -{ - int found, lookup, set, which; - struct aclmember *entry = NULL; - - /* default is to lookup the remote host's name */ - lookup = TRUE; - found = FALSE; - - /* rhostlookup yes|no [ ...] */ - while (!found && getaclentry("rhostlookup", &entry)) { - if (!ARG0) - continue; - if (strcasecmp(ARG0, "yes") == 0) - set = TRUE; - else if (strcasecmp(ARG0, "no") == 0) - set = FALSE; - else - continue; - - if (!ARG1) - lookup = set; - else { - for (which = 1; (which < MAXARGS) && ARG[which]; which++) { - if (hostmatch(ARG[which], remoteaddr, NULL)) { - lookup = set; - found = TRUE; - break; - } - } - } - } - return lookup; -} - -/**************************************************************************** - * set_res_options() - * set resolver options by setting the RES_OPTIONS environment variable. - * Note: name and address lookups are no longer done using DNS directly, - * so setting resolver options may have no effect. - ***************************************************************************/ -void set_res_options(void) -{ - int which; - struct aclmember *entry = NULL; - static char envbuf[BUFSIZ]; - - envbuf[0] = '\0'; - - /* dns resolveroptions [options] */ - while (getaclentry("dns", &entry)) { - if (!ARG0 || !ARG1) - continue; - /* there are other DNS options, we only care about 'resolveroptions' */ - if (strcasecmp(ARG0, "resolveroptions") == 0) { - for (which = 1; (which < MAXARGS) && ARG[which]; which++) { - if (envbuf[0] == '\0') - (void) strlcpy(envbuf, "RES_OPTIONS=", sizeof(envbuf)); - else - (void) strlcat(envbuf, " ", sizeof(envbuf)); - (void) strlcat(envbuf, ARG[which], sizeof(envbuf)); - } - } - } - if (envbuf[0] != '\0') { - if (putenv(envbuf) != 0) - syslog(LOG_WARNING, "putenv(\"%s\") failed", envbuf); - } -} diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/extensions.c b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/extensions.c deleted file mode 100644 index 71a31e8c86..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/extensions.c +++ /dev/null @@ -1,2365 +0,0 @@ -/* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -/**************************************************************************** - - Copyright (c) 1999,2000 WU-FTPD Development Group. - All rights reserved. - - Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 - The Regents of the University of California. - Portions Copyright (c) 1993, 1994 Washington University in Saint Louis. - Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc. - Portions Copyright (c) 1989 Massachusetts Institute of Technology. - Portions Copyright (c) 1998 Sendmail, Inc. - Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman. - Portions Copyright (c) 1997 by Stan Barber. - Portions Copyright (c) 1997 by Kent Landfield. - Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 - Free Software Foundation, Inc. - - Use and distribution of this software and its source code are governed - by the terms and conditions of the WU-FTPD Software License ("LICENSE"). - - If you did not receive a copy of the license, it may be obtained online - at http://www.wu-ftpd.org/license.html. - - $Id: extensions.c,v 1.48 2000/07/01 18:17:38 wuftpd Exp $ - -****************************************************************************/ -#include "config.h" - -#include -#include -#include - -#ifdef HAVE_SYS_SYSLOG_H -#include -#endif -#if defined(HAVE_SYSLOG_H) || (!defined(AUTOCONF) && !defined(HAVE_SYS_SYSLOG_H)) -#include -#endif - -#ifdef TIME_WITH_SYS_TIME -#include -#include -#else -#ifdef HAVE_SYS_TIME_H -#include -#else -#include -#endif -#endif -#include -#include -#include - -#include -#include -#include -#include - -#ifdef HAVE_SYS_FS_UFS_QUOTA_H -#include -#elif defined(HAVE_UFS_UFS_QUOTA_H) -#include -#elif defined(HAVE_UFS_QUOTA_H) -#include -#elif defined(HAVE_SYS_MNTENT_H) -#include -#elif defined(HAVE_SYS_MNTTAB_H) -#include -#endif - -#if defined(HAVE_STATVFS) -#include -#elif defined(HAVE_SYS_VFS) -#include -#elif defined(HAVE_SYS_MOUNT) -#include -#endif - -#include - -#ifdef HAVE_PATHS_H -#include -#endif -#include "pathnames.h" -#include "extensions.h" -#include "wu_fnmatch.h" -#include "proto.h" - -#if defined(HAVE_FTW) -#include -#else -#include "support/ftw.h" -#endif - -#ifdef QUOTA -struct dqblk quota; -char *time_quota(long curstate, long softlimit, long timelimit, char *timeleft); -#endif - -#ifdef HAVE_REGEX_H -#include -#endif - -#if defined(HAVE_REGEX) && defined(SVR4) && ! (defined(NO_LIBGEN)) -#include -#endif - -extern int type, transflag, ftwflag, authenticated, autospout_free, data, - pdata, anonymous, guest; -extern char chroot_path[], guestpw[]; - -#ifdef TRANSFER_COUNT -extern off_t data_count_in; -extern off_t data_count_out; -#ifdef TRANSFER_LIMIT -extern off_t data_limit_raw_in; -extern off_t data_limit_raw_out; -extern off_t data_limit_raw_total; -extern off_t data_limit_data_in; -extern off_t data_limit_data_out; -extern off_t data_limit_data_total; -#ifdef RATIO /* 1998/08/06 K.Wakui */ -#define TRUNC_KB(n) ((n)/1024+(((n)%1024)?1:0)) -extern time_t login_time; -extern time_t limit_time; -extern off_t total_free_dl; -extern int upload_download_rate; -#endif /* RATIO */ -#endif -#endif - -#ifdef OTHER_PASSWD -#include "getpwnam.h" -extern char _path_passwd[]; -#endif - -#ifdef LOG_FAILED -extern char the_user[]; -#endif - -extern char *globerr, remotehost[]; -#ifdef THROUGHPUT -extern char remoteaddr[]; -#endif - -#ifndef HAVE_REGEX -char *re_comp(const char *regex); -int re_exec(const char *p1); -#endif - -char shuttime[30], denytime[30], disctime[30]; - -FILE *dout; - -time_t newer_time; - -int show_fullinfo; - -/* This always was a bug, because neither st_size nor time_t were required to - be compatible with int, but needs fixing properly for C9X. */ - -/* Some systems use one format, some another. This takes care of the garbage */ -/* Do the system specific stuff only if we aren't autoconfed */ -#if !defined(L_FORMAT) -#if (defined(BSD) && (BSD >= 199103)) && !defined(LONGOFF_T) -#define L_FORMAT "qd" -#else -#define L_FORMAT "d" -#endif -#endif -#if !defined(T_FORMAT) -#define T_FORMAT "d" -#endif -#if !defined(PW_UID_FORMAT) -#define PW_UID_FORMAT "d" -#endif -#if !defined(GR_GID_FORMAT) -#define GR_GID_FORMAT "d" -#endif - -int snprintf(char *str, size_t count, const char *fmt,...); - -#ifdef SITE_NEWER -int check_newer(const char *path, const struct stat *st, int flag) -{ - if (st->st_mtime > newer_time) { - if (show_fullinfo != 0) { - if (flag == FTW_F || flag == FTW_D) { - fprintf(dout, "%s %" L_FORMAT " %" T_FORMAT " %s\n", - flag == FTW_F ? "F" : "D", - st->st_size, st->st_mtime, path); - } - } - else if (flag == FTW_F) - fprintf(dout, "%s\n", path); - } - - /* When an ABOR has been received (which sets ftwflag > 1) return a - * non-zero value which causes ftw to stop tree traversal and return. - */ - - return (ftwflag > 1 ? 1 : 0); -} -#endif - -#if defined(HAVE_STATVFS) -long getSize(char *s) -{ - struct statvfs buf; - - if (statvfs(s, &buf) != 0) - return (0); - - return (buf.f_bavail * buf.f_frsize / 1024); -} -#elif defined(HAVE_SYS_VFS) || defined (HAVE_SYS_MOUNT) -long getSize(char *s) -{ - struct statfs buf; - - if (statfs(s, &buf) != 0) - return (0); - - return (buf.f_bavail * buf.f_bsize / 1024); -} -#endif - -/*************************************************************************/ -/* FUNCTION : msg_massage */ -/* PURPOSE : Scan a message line for magic cookies, replacing them as */ -/* needed. */ -/* ARGUMENTS : pointer input and output buffers */ -/*************************************************************************/ - -void msg_massage(const char *inbuf, char *outbuf, size_t outlen) -{ - const char *inptr = inbuf; - char *outptr = outbuf; -#ifdef QUOTA - char timeleft[80]; -#endif - char buffer[MAXPATHLEN]; - time_t curtime; - int limit; -#ifndef LOG_FAILED - extern struct passwd *pw; -#endif - struct aclmember *entry; - -#ifdef VIRTUAL - extern int virtual_mode; - extern int virtual_ftpaccess; - extern char virtual_email[]; -#endif - extern char hostname[]; - extern char authuser[]; - - (void) acl_getclass(buffer); - limit = acl_getlimit(buffer, NULL); - - while ((outlen > 1) && (*inptr != '\0')) { - if (*inptr != '%') { - *outptr++ = *inptr; - outlen -= 1; - } - else { - entry = NULL; - switch (*++inptr) { - case 'E': -#ifdef VIRTUAL - if (virtual_mode && !virtual_ftpaccess && virtual_email[0] != '\0') - snprintf(outptr, outlen, "%s", virtual_email); - else -#endif - if ((getaclentry("email", &entry)) && ARG0) - snprintf(outptr, outlen, "%s", ARG0); - else - *outptr = '\0'; - break; - - case 'N': - snprintf(outptr, outlen, "%d", acl_countusers(buffer)); - break; - - case 'M': - if (limit == -1) - strncpy(outptr, "unlimited", outlen); - else - snprintf(outptr, outlen, "%d", limit); - break; - - case 'T': - (void) time(&curtime); - strncpy(outptr, ctime(&curtime), outlen); - if (outlen > 24) - *(outptr + 24) = '\0'; - break; - - case 'F': -#if defined(HAVE_STATVFS) || defined(HAVE_SYS_VFS) || defined(HAVE_SYS_MOUNT) - snprintf(outptr, outlen, "%lu", (long) getSize(".")); -#else - *outptr = '\0'; -#endif - break; - - case 'C': -#ifdef HAVE_GETCWD - (void) getcwd(outptr, outlen); -#else -#error wu-ftpd on this platform has security deficiencies!!! - (void) getwd(outptr); -#endif - break; - - case 'R': - strncpy(outptr, remotehost, outlen); - break; - - case 'L': - strncpy(outptr, hostname, outlen); - break; - - case 'U': - if (xferdone && anonymous) - strncpy(outptr, guestpw, outlen); - else -#ifdef LOG_FAILED - strncpy(outptr, the_user, outlen); -#else /* LOG_FAILED */ - strncpy(outptr, - (pw == NULL) ? "[unknown]" : pw->pw_name, outlen); -#endif /* LOG_FAILED */ - break; - - case 's': - strncpy(outptr, shuttime, outlen); - if (outlen > 24) - *(outptr + 24) = '\0'; - break; - - case 'd': - strncpy(outptr, disctime, outlen); - if (outlen > 24) - *(outptr + 24) = '\0'; - break; - - case 'r': - strncpy(outptr, denytime, outlen); - if (outlen > 24) - *(outptr + 24) = '\0'; - break; - -/* KH : cookie %u for RFC931 name */ - case 'u': - if (authenticated) - strncpy(outptr, authuser, outlen); - else { - if (xferdone) - snprintf(outptr, outlen, "%c", '*'); - else - strncpy(outptr, "[unknown]", outlen); - } - break; - -#ifdef QUOTA - case 'B': -#ifdef QUOTA_BLOCKS /* 1024-blocks instead of 512-blocks */ - snprintf(outptr, outlen, "%ld", quota.dqb_bhardlimit % 2 ? - (long) (quota.dqb_bhardlimit / 2 + 1) : (long) (quota.dqb_bhardlimit / 2)); -#else - snprintf(outptr, outlen, "%ld", (long) quota.dqb_bhardlimit); -#endif - break; - - case 'b': -#ifdef QUOTA_BLOCKS /* 1024-blocks instead of 512-blocks */ - snprintf(outptr, outlen, "%ld", quota.dqb_bsoftlimit % 2 ? - (long) (quota.dqb_bsoftlimit / 2 + 1) : (long) (quota.dqb_bsoftlimit / 2)); -#else - snprintf(outptr, outlen, "%ld", (long) quota.dqb_bsoftlimit); -#endif - break; - - case 'Q': -#ifdef QUOTA_BLOCKS /* 1024-blocks instead of 512-blocks */ - snprintf(outptr, outlen, "%ld", quota.dqb_curblocks % 2 ? - (long) (quota.dqb_curblocks / 2 + 1) : (long) (quota.dqb_curblocks / 2)); -#else - snprintf(outptr, outlen, "%ld", quota.dqb_curblocks); -#endif - break; - - case 'I': -#if defined(QUOTA_INODE) - snprintf(outptr, outlen, "%d", quota.dqb_ihardlimit); -#else - snprintf(outptr, outlen, "%ld", (long) quota.dqb_fhardlimit); -#endif - break; - - case 'i': -#if defined(QUOTA_INODE) - snprintf(outptr, outlen, "%d", quota.dqb_isoftlimit); -#else - snprintf(outptr, outlen, "%ld", (long) quota.dqb_fsoftlimit); -#endif - break; - - case 'q': -#if defined(QUOTA_INODE) - snprintf(outptr, outlen, "%d", quota.dqb_curinodes); -#else - snprintf(outptr, outlen, "%ld", (long) quota.dqb_curfiles); -#endif - break; - - case 'H': - time_quota(quota.dqb_curblocks, quota.dqb_bsoftlimit, -#if defined(QUOTA_INODE) - quota.dqb_btime, timeleft); -#else - quota.dqb_btimelimit, timeleft); -#endif - strncpy(outptr, timeleft, outlen); - break; - - case 'h': -#if defined(QUOTA_INODE) - time_quota(quota.dqb_curinodes, quota.dqb_isoftlimit, - quota.dqb_itime, timeleft); -#else - time_quota(quota.dqb_curfiles, quota.dqb_fsoftlimit, - quota.dqb_ftimelimit, timeleft); -#endif - strncpy(outptr, timeleft, outlen); - break; -#endif /* QUOTA */ - - case '%': - *outptr++ = '%'; - outlen -= 1; - *outptr = '\0'; - break; - -#ifdef TRANSFER_COUNT -#ifdef TRANSFER_LIMIT -#ifdef RATIO - case 'x': - switch (*++inptr) { - case 'u': /* upload bytes */ - sprintf(outptr,"%" L_FORMAT, TRUNC_KB(data_count_in) ); - break; - case 'd': /* download bytes */ - sprintf(outptr,"%" L_FORMAT, TRUNC_KB(data_count_out) ); - break; - case 'R': /* rate 1:n */ - if( upload_download_rate > 0 ) { - sprintf(outptr,"%d", upload_download_rate ); - } - else { - strcpy(outptr,"free"); - } - break; - case 'c': /* credit bytes */ - if( upload_download_rate > 0 ) { - off_t credit=( data_count_in * upload_download_rate) - (data_count_out - total_free_dl); - sprintf(outptr,"%" L_FORMAT, TRUNC_KB(credit) ); - } - else { - strcpy(outptr,"unlimited"); - } - break; - case 'T': /* time limit (minutes) */ - if( limit_time > 0 ) { - sprintf(outptr,"%d", limit_time ); - } - else { - strcpy(outptr,"unlimited"); - } - break; - case 'E': /* elapsed time from loggedin (minutes) */ - sprintf(outptr,"%d", (time(NULL)-login_time)/60 ); - break; - case 'L': /* times left until force logout (minutes) */ - if( limit_time > 0 ) { - sprintf(outptr,"%d", limit_time-(time(NULL)-login_time)/60 ); - } - else { - strcpy(outptr,"unlimited"); - } - break; - case 'U': /* upload limit */ - if( data_limit_raw_in > 0 ) { - sprintf(outptr,"%" L_FORMAT, TRUNC_KB(data_limit_raw_in)); - } - else if( data_limit_data_in > 0 ) { - sprintf(outptr,"%" L_FORMAT, TRUNC_KB(data_limit_data_in)); - } - else if( data_limit_raw_total > 0 ) { - sprintf(outptr,"%" L_FORMAT, TRUNC_KB(data_limit_raw_total)); - } - else if( data_limit_data_total > 0 ) { - sprintf(outptr,"%" L_FORMAT, TRUNC_KB(data_limit_data_total)); - } - else { - strcpy(outptr, "unlimited"); - } - break; - case 'D': /* download limit */ - if( data_limit_raw_out > 0 ) { - sprintf(outptr,"%" L_FORMAT, TRUNC_KB(data_limit_raw_out)); - } - else if( data_limit_data_out > 0 ) { - sprintf(outptr,"%" L_FORMAT, TRUNC_KB(data_limit_data_out)); - } - else if( data_limit_raw_total > 0 ) { - sprintf(outptr,"%" L_FORMAT, TRUNC_KB(data_limit_raw_total)); - } - else if( data_limit_data_total > 0 ) { - sprintf(outptr,"%" L_FORMAT, TRUNC_KB(data_limit_data_total)); - } - else { - strcpy(outptr, "unlimited"); - } - break; - default: - strcpy(outptr,"%??"); - break; - } - break; -#endif /* RATIO */ -#endif -#endif - /* File transfer logging (xferlog) */ - case 'X': - if (xferdone) { /* only if a transfer has just occurred */ - switch (*++inptr) { - case 't': - snprintf(outptr, outlen, "%d", xfervalues.transfer_time); - break; - case 's': - snprintf(outptr, outlen, "%" L_FORMAT, xfervalues.filesize); - break; - case 'n': - snprintf(outptr, outlen, "%" L_FORMAT, xfervalues.transfer_bytes); - break; - case 'P': /* absolute pathname */ - /* FALLTHROUGH */ - case 'p': /* chroot-relative pathname */ - { - char namebuf[MAXPATHLEN]; - int loop; - - if (*inptr == 'P') - wu_realpath(xfervalues.filename, namebuf, chroot_path); - else - fb_realpath(xfervalues.filename, namebuf); - for (loop = 0; namebuf[loop]; loop++) { - if (isspace(namebuf[loop]) || iscntrl(namebuf[loop])) - namebuf[loop] = '_'; - } - snprintf(outptr, outlen, "%s", namebuf); - break; - } - case 'y': - snprintf(outptr, outlen, "%c", xfervalues.transfer_type); - break; - case 'f': - snprintf(outptr, outlen, "%s", xfervalues.special_action); - break; - case 'd': - snprintf(outptr, outlen, "%c", xfervalues.transfer_direction); - break; - case 'm': - snprintf(outptr, outlen, "%c", xfervalues.access_mode); - break; - case 'a': - snprintf(outptr, outlen, "%d", xfervalues.auth); - break; - case 'r': - snprintf(outptr, outlen, "%" L_FORMAT, xfervalues.restart_offset); - break; - case 'c': - snprintf(outptr, outlen, "%c", xfervalues.completion); - break; - default: - snprintf(outptr, outlen, "%%X%c", *inptr); - break; - } - } - else - snprintf(outptr, outlen, "%%%c", *inptr); - break; - - default: - *outptr++ = '%'; - outlen -= 1; - if (outlen > 1) { - *outptr++ = *inptr; - outlen -= 1; - } - *outptr = '\0'; - break; - } - outptr[outlen - 1] = '\0'; - while (*outptr) { - outptr++; - outlen -= 1; - } - } - inptr++; - } - if (outlen > 0) - *outptr = '\0'; -} - -/*************************************************************************/ -/* FUNCTION : cwd_beenhere */ -/* PURPOSE : Return 1 if the user has already visited this directory */ -/* via C_WD. */ -/* ARGUMENTS : a power-of-two directory function code (README, MESSAGE) */ -/*************************************************************************/ - -int cwd_beenhere(int dircode) -{ - struct dirlist { - struct dirlist *next; - int dircode; - char dirname[1]; - }; - - static struct dirlist *head = NULL; - struct dirlist *curptr; - char cwd[MAXPATHLEN]; - - (void) fb_realpath(".", cwd); - - for (curptr = head; curptr != NULL; curptr = curptr->next) - if (strcmp(curptr->dirname, cwd) == 0) { - if (!(curptr->dircode & dircode)) { - curptr->dircode |= dircode; - return (0); - } - return (1); - } - curptr = (struct dirlist *) malloc(strlen(cwd) + 1 + sizeof(struct dirlist)); - - if (curptr != NULL) { - curptr->next = head; - head = curptr; - curptr->dircode = dircode; - strcpy(curptr->dirname, cwd); - } - return (0); -} - -/*************************************************************************/ -/* FUNCTION : show_banner */ -/* PURPOSE : Display a banner on the user's terminal before login */ -/* ARGUMENTS : reply code to use */ -/*************************************************************************/ - -void show_banner(int msgcode) -{ - char *crptr, linebuf[1024], outbuf[1024]; - struct aclmember *entry = NULL; - FILE *infile; - -#ifdef VIRTUAL - extern int virtual_mode; - extern int virtual_ftpaccess; - extern char virtual_banner[]; - - if (virtual_mode && !virtual_ftpaccess) { - infile = fopen(virtual_banner, "r"); - if (infile) { - while (fgets(linebuf, sizeof(linebuf), infile) != NULL) { - if ((crptr = strchr(linebuf, '\n')) != NULL) - *crptr = '\0'; - msg_massage(linebuf, outbuf, sizeof(outbuf)); - lreply(msgcode, "%s", outbuf); - } - fclose(infile); -#ifndef NO_SUCKING_NEWLINES - lreply(msgcode, ""); -#endif - } - } - else { -#endif - /* banner */ - while (getaclentry("banner", &entry)) { - if (!ARG0) - continue; - infile = fopen(ARG0, "r"); - if (infile) { - while (fgets(linebuf, sizeof(linebuf), infile) != NULL) { - if ((crptr = strchr(linebuf, '\n')) != NULL) - *crptr = '\0'; - msg_massage(linebuf, outbuf, sizeof(outbuf)); - lreply(msgcode, "%s", outbuf); - } - fclose(infile); -#ifndef NO_SUCKING_NEWLINES - lreply(msgcode, ""); -#endif - } - } -#ifdef VIRTUAL - } -#endif -} -/*************************************************************************/ -/* FUNCTION : show_message */ -/* PURPOSE : Display a message on the user's terminal if the current */ -/* conditions are right */ -/* ARGUMENTS : reply code to use, LOG_IN|CMD */ -/*************************************************************************/ - -void show_message(int msgcode, int mode) -{ - char *crptr, linebuf[1024], outbuf[1024], class[MAXPATHLEN], cwd[MAXPATHLEN]; - int show, which; - struct aclmember *entry = NULL; - FILE *infile; - - if (mode == C_WD && cwd_beenhere(1) != 0) - return; - -#ifdef HAVE_GETCWD - (void) getcwd(cwd, MAXPATHLEN - 1); -#else - (void) getwd(cwd); -#endif - (void) acl_getclass(class); - - /* message [ []] */ - while (getaclentry("message", &entry)) { - if (!ARG0) - continue; - show = 0; - - if (mode == LOG_IN && (!ARG1 || !strcasecmp(ARG1, "login"))) - if (!ARG2) - show++; - else { - for (which = 2; (which < MAXARGS) && ARG[which]; which++) - if (strcasecmp(class, ARG[which]) == 0) - show++; - } - if (mode == C_WD && ARG1 && !strncasecmp(ARG1, "cwd=", 4) && - (!strcmp((ARG1) + 4, cwd) || *(ARG1 + 4) == '*' || - !wu_fnmatch((ARG1) + 4, cwd, FNM_PATHNAME))) - if (!ARG2) - show++; - else { - for (which = 2; (which < MAXARGS) && ARG[which]; which++) - if (strcasecmp(class, ARG[which]) == 0) - show++; - } - if (show && (int) strlen(ARG0) > 0) { - infile = fopen(ARG0, "r"); - if (infile) { - while (fgets(linebuf, sizeof(linebuf), infile) != NULL) { - if ((crptr = strchr(linebuf, '\n')) != NULL) - *crptr = '\0'; - msg_massage(linebuf, outbuf, sizeof(outbuf)); - lreply(msgcode, "%s", outbuf); - } - fclose(infile); -#ifndef NO_SUCKING_NEWLINES - lreply(msgcode, ""); -#endif - } - } - } -} - -/*************************************************************************/ -/* FUNCTION : show_readme */ -/* PURPOSE : Display a message about a README file to the user if the */ -/* current conditions are right */ -/* ARGUMENTS : pointer to ACL buffer, reply code, LOG_IN|C_WD */ -/*************************************************************************/ - -void show_readme(int code, int mode) -{ - char **filelist, **sfilelist, class[MAXPATHLEN], cwd[MAXPATHLEN]; - int show, which, days; - time_t clock; - - struct stat buf; - struct tm *tp; - struct aclmember *entry = NULL; - - if (cwd_beenhere(2) != 0) - return; - -#ifdef HAVE_GETCWD - (void) getcwd(cwd, MAXPATHLEN - 1); -#else - (void) getwd(cwd); -#endif - (void) acl_getclass(class); - - /* readme {} */ - while (getaclentry("readme", &entry)) { - if (!ARG0) - continue; - show = 0; - - if (mode == LOG_IN && (!ARG1 || !strcasecmp(ARG1, "login"))) - if (!ARG2) - show++; - else { - for (which = 2; (which < MAXARGS) && ARG[which]; which++) - if (strcasecmp(class, ARG[which]) == 0) - show++; - } - if (mode == C_WD && ARG1 && !strncasecmp(ARG1, "cwd=", 4) - && (!strcmp((ARG1) + 4, cwd) || *(ARG1 + 4) == '*' || - !wu_fnmatch((ARG1) + 4, cwd, FNM_PATHNAME))) - if (!ARG2) - show++; - else { - for (which = 2; (which < MAXARGS) && ARG[which]; which++) - if (strcasecmp(class, ARG[which]) == 0) - show++; - } - if (show) { - globerr = NULL; - filelist = ftpglob(ARG0, B_TRUE); - sfilelist = filelist; /* save to free later */ - if (!globerr) { - while (filelist && *filelist) { - errno = 0; - if (!stat(*filelist, &buf) && - (buf.st_mode & S_IFMT) == S_IFREG) { - lreply(code, "Please read the file %s", *filelist); - (void) time(&clock); - tp = localtime(&clock); - days = 365 * tp->tm_year + tp->tm_yday; - tp = localtime((time_t *) & buf.st_mtime); - days -= 365 * tp->tm_year + tp->tm_yday; -/* - if (days == 0) { - lreply(code, " it was last modified on %.24s - Today", - ctime((time_t *)&buf.st_mtime)); - } else { - */ - lreply(code, - " it was last modified on %.24s - %d day%s ago", - ctime((time_t *) & buf.st_mtime), days, days == 1 ? "" : "s"); -/* - } - */ - } - filelist++; - } - } - if (sfilelist) { - blkfree(sfilelist); - free((char *) sfilelist); - } - } - } -} - -/*************************************************************************/ -/* FUNCTION : deny_badxfertype */ -/* PURPOSE : If user is in ASCII transfer mode and tries to retrieve a */ -/* binary file, abort transfer and display appropriate error */ -/* ARGUMENTS : message code to use for denial, path of file to check for */ -/* binary contents or NULL to assume binary file */ -/*************************************************************************/ - -int deny_badasciixfer(int msgcode, char *filepath) -{ - - if (type == TYPE_A && !*filepath) { - reply(msgcode, "This is a BINARY file, using ASCII mode to transfer will corrupt it."); - return (1); - } - /* The hooks are here to prevent transfers of actual binary files, not - * just TAR or COMPRESS mode files... */ - return (0); -} - -/*************************************************************************/ -/* FUNCTION : is_shutdown */ -/* PURPOSE : Check to see if the server is shutting down, if it is */ -/* arrange for the shutdown message to be sent in the next */ -/* reply to the user */ -/* ARGUMENTS : whether to arrange for a shutdown message to be sent, new */ -/* or existing connection */ -/* RETURNS : 1 if shutting down, 0 if not */ -/*************************************************************************/ - -int is_shutdown(int quiet, int new) -{ - static struct tm tmbuf; - static struct stat s_last; - static time_t last = 0, shut, deny, disc; - static int valid; - static char text[2048]; - struct stat s_cur; - - extern char *autospout, Shutdown[]; - - FILE *fp; - - int deny_off, disc_off; - - time_t curtime = time(NULL); - - char buf[1024], linebuf[1024]; - - if (Shutdown[0] == '\0' || stat(Shutdown, &s_cur)) - return (0); - - if (s_last.st_mtime != s_cur.st_mtime) { - valid = 0; - - fp = fopen(Shutdown, "r"); - if (fp == NULL) - return (0); - s_last = s_cur; - fgets(buf, sizeof(buf), fp); - if (sscanf(buf, "%d %d %d %d %d %ld %ld", &tmbuf.tm_year, &tmbuf.tm_mon, - &tmbuf.tm_mday, &tmbuf.tm_hour, &tmbuf.tm_min, &deny, &disc) != 7) { - (void) fclose(fp); - return (0); - } - valid = 1; - deny_off = 3600 * (deny / 100) + 60 * (deny % 100); - disc_off = 3600 * (disc / 100) + 60 * (disc % 100); - - tmbuf.tm_year -= 1900; - tmbuf.tm_isdst = -1; - shut = mktime(&tmbuf); - strcpy(shuttime, ctime(&shut)); - - disc = shut - disc_off; - strcpy(disctime, ctime(&disc)); - - deny = shut - deny_off; - strcpy(denytime, ctime(&deny)); - - text[0] = '\0'; - - while (fgets(buf, sizeof(buf), fp) != NULL) { - msg_massage(buf, linebuf, sizeof(linebuf)); - if ((strlen(text) + strlen(linebuf)) < sizeof(text)) - strcat(text, linebuf); - } - - (void) fclose(fp); - } - if (!valid) - return (0); - - /* if last == 0, then is_shutdown() only called with quiet == 1 so far */ - if (last == 0 && !quiet) { - autospout = text; /* warn them for the first time */ - autospout_free = 0; - last = curtime; - } - /* if a new connection and past deny time, tell caller to drop 'em */ - if (new && curtime > deny) - return (1); - - /* if past disconnect time, tell caller to drop 'em */ - if (curtime > disc) - return (1); - - /* if less than 60 seconds to disconnection, warn 'em continuously */ - if (curtime > (disc - 60) && !quiet) { - autospout = text; - autospout_free = 0; - last = curtime; - } - /* if less than 15 minutes to disconnection, warn 'em every 5 mins */ - if (curtime > (disc - 60 * 15)) { - if ((curtime - last) > (60 * 5) && !quiet) { - autospout = text; - autospout_free = 0; - last = curtime; - } - } - /* if less than 24 hours to disconnection, warn 'em every 30 mins */ - if (curtime < (disc - 24 * 60 * 60) && !quiet) { - if ((curtime - last) > (60 * 30)) { - autospout = text; - autospout_free = 0; - last = curtime; - } - } - /* if more than 24 hours to disconnection, warn 'em every 60 mins */ - if (curtime > (disc - 24 * 60 * 60) && !quiet) { - if ((curtime - last) >= (24 * 60 * 60)) { - autospout = text; - autospout_free = 0; - last = curtime; - } - } - return (0); -} - -#ifdef SITE_NEWER -void newer(char *date, char *path, int showlots) -{ - struct tm tm; - - if (sscanf(date, "%04d%02d%02d%02d%02d%02d", - &tm.tm_year, &tm.tm_mon, &tm.tm_mday, - &tm.tm_hour, &tm.tm_min, &tm.tm_sec) == 6) { - - tm.tm_year -= 1900; - tm.tm_mon--; - tm.tm_isdst = -1; - newer_time = mktime(&tm); - dout = dataconn("file list", (off_t) - 1, "w"); - - if (dout != NULL) { - /* As ftw allocates storage it needs a chance to cleanup, setting - * ftwflag prevents myoob from calling longjmp, incrementing - * ftwflag instead which causes check_newer to return non-zero - * which makes ftw return. */ - ftwflag = 1; - transflag++; - show_fullinfo = showlots; -#if defined(HAVE_FTW) - ftw(path, check_newer, -1); -#else - treewalk(path, check_newer, -1, NULL); -#endif - - /* don't send a reply if myoob has already replied */ - if (ftwflag == 1) { - if (ferror(dout) != 0) - perror_reply(550, "Data connection"); - else - reply(226, "Transfer complete."); - } - - (void) fclose(dout); - data = -1; - pdata = -1; - transflag = 0; - ftwflag = 0; - } - } - else - reply(501, "Bad DATE format"); -} -#endif - -int type_match(char *typelist) -{ - char *start, *p; - int len; - - if (typelist == NULL) - return (0); - - for (p = start = typelist; *start != '\0'; start = p) { - while (*p != '\0' && *p != ',') - p++; - len = p - start; - if (*p != '\0') - p++; - if (len == 9 && anonymous && strncasecmp(start, "anonymous", 9) == 0) - return (1); - if (len == 5 && guest && strncasecmp(start, "guest", 5) == 0) - return (1); - if (len == 4 && !guest && !anonymous && - strncasecmp(start, "real", 4) == 0) - return (1); - - if (len > 6 && strncasecmp(start, "class=", 6) == 0) { - char class[1024]; - - if ((acl_getclass(class) == 1) && (strlen(class) == len - 6) && - (strncasecmp(start + 6, class, len - 6) == 0)) - return (1); - } - } - return (0); -} - -int path_compare(char *p1, char *p2) -{ - if ((strcmp(p1, "*") == 0) || (wu_fnmatch(p1, p2, FNM_PATHNAME) == 0)) /* 0 means they matched */ - return (strlen(p1)); - else - return (-2); -} - -void expand_id(void) -{ - char class[1024]; - struct aclmember *entry = NULL; - (void) acl_getclass(class); - while (getaclentry("upload", &entry)) { - char *q; - int i = 0; - int options = 1; - int classfound = 0; - int classmatched = 0; - while (options - && (i < MAXARGS) - && ((q = entry->arg[i]) != (char *) NULL) - && (q[0] != '\0')) { - if (strcasecmp(q, "absolute") == 0) - i++; - else if (strcasecmp(q, "relative") == 0) - i++; - else if (strncasecmp(q, "class=", 6) == 0) { - i++; - classfound = 1; - if (strcasecmp(q + 6, class) == 0) - classmatched = 1; - } - else if (strcmp(q, "-") == 0) { - i++; - options = 0; - } - else - options = 0; - } - if (!classfound || classmatched) { - char buf[BUFSIZ]; - /* - * UID - */ - if (((i + 3) < MAXARGS) - && ((q = entry->arg[i + 3]) != (char *) NULL) - && (q[0] != '\0') - && (strcmp(q, "*") != 0)) { - if (q[0] == '%') - sprintf(buf, "%s", q + 1); - else { - struct passwd *pwent = getpwnam(q); - if (pwent) - sprintf(buf, "%" PW_UID_FORMAT, pwent->pw_uid); - else - sprintf(buf, "%d", 0); - } - entry->arg[i + 3] = (char *) malloc(strlen(buf) + 1); - if (entry->arg[i + 3] == NULL) { - syslog(LOG_ERR, "calloc error in expand_id"); - dologout(1); - } - strcpy(entry->arg[i + 3], buf); - } - /* - * GID - */ - if (((i + 4) < MAXARGS) - && ((q = entry->arg[i + 4]) != (char *) NULL) - && (q[0] != '\0') - && (strcmp(q, "*") != 0)) { - if (q[0] == '%') - sprintf(buf, "%s", q + 1); - else { - struct group *grent = getgrnam(q); - if (grent) - sprintf(buf, "%" GR_GID_FORMAT, grent->gr_gid); - else - sprintf(buf, "%d", 0); - endgrent(); - } - entry->arg[i + 4] = (char *) malloc(strlen(buf) + 1); - if (entry->arg[i + 4] == NULL) { - syslog(LOG_ERR, "calloc error in expand_id"); - dologout(1); - } - strcpy(entry->arg[i + 4], buf); - } - } - } -} - -int fn_check(char *name) -{ - /* check to see if this is a valid file name... path-filter - * */ - - struct aclmember *entry = NULL; - int j; - char *path; -#if ! defined(HAVE_REGEXEC) - char *sp; -#endif - -#ifdef M_UNIX -#ifdef HAVE_REGEX - char *regp; -#endif -#endif - -#ifdef HAVE_REGEXEC - regex_t regexbuf; - regmatch_t regmatchbuf; - int rval; -#endif - -#ifdef LINUX - re_syntax_options = RE_SYNTAX_POSIX_EXTENDED; -#endif - - while (getaclentry("path-filter", &entry) && ARG0 != NULL) { - if (type_match(ARG0) && ARG1 && ARG2) { - - /* - * check *only* the basename - */ - - if ((path = strrchr(name, '/'))) - ++path; - else - path = name; - - /* is it in the allowed character set? */ -#if defined(HAVE_REGEXEC) - if (regcomp(®exbuf, ARG2, REG_EXTENDED) != 0) { - reply(550, "HAVE_REGEX error"); -#elif defined(HAVE_REGEX) - if ((sp = regcmp(ARG2, (char *) 0)) == NULL) { - reply(550, "HAVE_REGEX error"); -#else - if ((sp = re_comp(ARG2)) != 0) { - perror_reply(550, sp); -#endif - return (0); - } -#if defined(HAVE_REGEXEC) - rval = regexec(®exbuf, path, 1, ®matchbuf, 0); - regfree(®exbuf); - if (rval != 0) { -#elif defined(HAVE_REGEX) -#ifdef M_UNIX - regp = regex(sp, path); - free(sp); - if (regp == NULL) { -#else - if ((regex(sp, path)) == NULL) { -#endif -#else - if ((re_exec(path)) != 1) { -#endif - pr_mesg(550, ARG1); - reply(550, "%s: Permission denied on server. (Filename (accept))", name); - return (0); - } - /* is it in any of the disallowed regexps */ - - for (j = 3; j < MAXARGS; ++j) { - /* ARGj == entry->arg[j] */ - if (entry->arg[j]) { -#if defined(HAVE_REGEXEC) - if (regcomp(®exbuf, entry->arg[j], REG_EXTENDED) != 0) { - reply(550, "HAVE_REGEX error"); -#elif defined(HAVE_REGEX) - if ((sp = regcmp(entry->arg[j], (char *) 0)) == NULL) { - reply(550, "HAVE_REGEX error"); -#else - if ((sp = re_comp(entry->arg[j])) != 0) { - perror_reply(550, sp); -#endif - return (0); - } -#if defined(HAVE_REGEXEC) - rval = regexec(®exbuf, path, 1, ®matchbuf, 0); - regfree(®exbuf); - if (rval == 0) { -#elif defined(HAVE_REGEX) -#ifdef M_UNIX - regp = regex(sp, path); - free(sp); - if (regp != NULL) { -#else - if ((regex(sp, path)) != NULL) { -#endif -#else - if ((re_exec(path)) == 1) { -#endif - pr_mesg(550, ARG1); - reply(550, "%s: Permission denied on server. (Filename (deny))", name); - return (0); - } - } - } - } - } - return (1); -} - -int dir_check(char *name, uid_t * uid, gid_t * gid, int *d_mode, int *valid) -{ - struct aclmember *entry = NULL; - int match_value = -1; - char *ap2 = NULL; - char *ap3 = NULL; - char *ap4 = NULL; - char *ap5 = NULL; - char *ap6 = NULL; - char *ap7 = NULL; - char cwdir[MAXPATHLEN]; - char *pwdir; - char abspwdir[MAXPATHLEN]; - char relpwdir[MAXPATHLEN]; - char path[MAXPATHLEN]; - char *sp; - struct stat stbuf; - int stat_result = -1; - char class[1024]; - extern char *home; - - (void) acl_getclass(class); - - *valid = 0; - /* what's our current directory? */ - - /* XXX We could use dynamic RAM to store this path, but I'd rather just bail - out with an error. The rest of wu is so crufy that a long path might - just blow up later */ - - if ((strlen(name) + 1) > sizeof(path)) { - perror_reply(550, "Path too long"); - return (-1); - } - - strcpy(path, name); - sp = strrchr(path, '/'); - if (sp) - *sp = '\0'; - else - strcpy(path, "."); - - if ((fb_realpath(path, cwdir)) == NULL) { - perror_reply(550, "Could not determine cwdir"); - return (-1); - } - - if ((fb_realpath(home, relpwdir)) == NULL) { - perror_reply(550, "Could not determine pwdir"); - return (-1); - } - - if ((wu_realpath(home, abspwdir, chroot_path)) == NULL) { - perror_reply(550, "Could not determine pwdir"); - return (-1); - } - - while (getaclentry("upload", &entry)) { - char *q; - int i = 0; - int options = 1; - int classfound = 0; - int classmatched = 0; - pwdir = abspwdir; - while (options - && (i < MAXARGS) - && ((q = entry->arg[i]) != (char *) NULL) - && (q[0] != '\0')) { - if (strcasecmp(q, "absolute") == 0) { - i++; - pwdir = abspwdir; - } - else if (strcasecmp(q, "relative") == 0) { - i++; - pwdir = relpwdir; - } - else if (strncasecmp(q, "class=", 6) == 0) { - i++; - classfound = 1; - if (strcasecmp(q + 6, class) == 0) - classmatched = 1; - } - else if (strcmp(q, "-") == 0) { - i++; - options = 0; - } - else - options = 0; - } - if (!classfound || classmatched) { - int j; - if (((i + 1) < MAXARGS) - && ((q = entry->arg[i]) != (char *) NULL) - && (q[0] != '\0') - && (0 < path_compare(q, pwdir)) - && ((j = path_compare(entry->arg[i + 1], cwdir)) >= match_value)) { - match_value = j; - - ap2 = NULL; - if (((i + 2) < MAXARGS) - && ((q = entry->arg[i + 2]) != (char *) NULL) - && (q[0] != '\0')) - ap2 = q; - - ap3 = NULL; - if (((i + 3) < MAXARGS) - && ((q = entry->arg[i + 3]) != (char *) NULL) - && (q[0] != '\0')) - ap3 = q; - - ap4 = NULL; - if (((i + 4) < MAXARGS) - && ((q = entry->arg[i + 4]) != (char *) NULL) - && (q[0] != '\0')) - ap4 = q; - - ap5 = NULL; - if (((i + 5) < MAXARGS) - && ((q = entry->arg[i + 5]) != (char *) NULL) - && (q[0] != '\0')) - ap5 = q; - - ap6 = NULL; - if (((i + 6) < MAXARGS) - && ((q = entry->arg[i + 6]) != (char *) NULL) - && (q[0] != '\0')) - ap6 = q; - - ap7 = NULL; - if (((i + 7) < MAXARGS) - && ((q = entry->arg[i + 7]) != (char *) NULL) - && (q[0] != '\0')) - ap7 = q; - } - } - } - - if (anonymous && (match_value < 0)) { - reply(550, "%s: Permission denied on server. (Upload dirs)", name); - return (0); - } - if ((ap2 && !strcasecmp(ap2, "no")) - || (ap3 && !strcasecmp(ap3, "nodirs")) - || (ap6 && !strcasecmp(ap6, "nodirs"))) { - reply(550, "%s: Permission denied on server. (Upload dirs)", name); - return (0); - } - if ((ap3 && *ap3 == '*') || (ap4 && *ap4 == '*')) - stat_result = stat(path, &stbuf); - if (ap3) { - if ((ap3[0] != '*') || (ap3[1] != '\0')) - *uid = atoi(ap3); /* the uid */ - else if (stat_result == 0) - *uid = stbuf.st_uid; - } - if (ap4) { - if ((ap4[0] != '*') || (ap4[1] != '\0')) - *gid = atoi(ap4); /* the gid */ - else if (stat_result == 0) - *gid = stbuf.st_gid; - } - if (ap7) { - sscanf(ap7, "%o", d_mode); - *valid = 1; - } - else if (ap5) { - sscanf(ap5, "%o", d_mode); - if (*d_mode & 0600) - *d_mode |= 0100; - if (*d_mode & 0060) - *d_mode |= 0010; - if (*d_mode & 0006) - *d_mode |= 0001; - *valid = 1; - } - return (1); -} - -int upl_check(char *name, uid_t * uid, gid_t * gid, int *f_mode, int *valid) -{ - int match_value = -1; - char cwdir[MAXPATHLEN]; - char *pwdir; - char abspwdir[MAXPATHLEN]; - char relpwdir[MAXPATHLEN]; - char path[MAXPATHLEN]; - char *sp; - struct stat stbuf; - int stat_result = -1; - char *ap2 = NULL; - char *ap3 = NULL; - char *ap4 = NULL; - char *ap5 = NULL; - struct aclmember *entry = NULL; - char class[1024]; - extern char *home; - - *valid = 0; - (void) acl_getclass(class); - - /* what's our current directory? */ - - /* XXX We could use dynamic RAM to store this path, but I'd rather just bail - out with an error. The rest of wu is so crufy that a long path might - just blow up later */ - - if ((strlen(name) + 1) > sizeof(path)) { - perror_reply(553, "Path too long"); - return (-1); - } - - strcpy(path, name); - sp = strrchr(path, '/'); - if (sp) - *sp = '\0'; - else - strcpy(path, "."); - - if ((fb_realpath(path, cwdir)) == NULL) { - perror_reply(553, "Could not determine cwdir"); - return (-1); - } - - if ((wu_realpath(home, abspwdir, chroot_path)) == NULL) { - perror_reply(553, "Could not determine pwdir"); - return (-1); - } - - if ((fb_realpath(home, relpwdir)) == NULL) { - perror_reply(553, "Could not determine pwdir"); - return (-1); - } - - /* - * we are doing a "best match"... ..so we keep track of what "match - * value" we have received so far... - */ - while (getaclentry("upload", &entry)) { - char *q; - int i = 0; - int options = 1; - int classfound = 0; - int classmatched = 0; - pwdir = abspwdir; - while (options - && (i < MAXARGS) - && ((q = entry->arg[i]) != (char *) NULL) - && (q[0] != '\0')) { - if (strcasecmp(q, "absolute") == 0) { - i++; - pwdir = abspwdir; - } - else if (strcasecmp(q, "relative") == 0) { - i++; - pwdir = relpwdir; - } - else if (strncasecmp(q, "class=", 6) == 0) { - i++; - classfound = 1; - if (strcasecmp(q + 6, class) == 0) - classmatched = 1; - } - else if (strcmp(q, "-") == 0) { - i++; - options = 0; - } - else - options = 0; - } - if (!classfound || classmatched) { - int j; - if (((i + 1) < MAXARGS) - && ((q = entry->arg[i]) != (char *) NULL) - && (q[0] != '\0') - && (0 < path_compare(q, pwdir)) - && ((j = path_compare(entry->arg[i + 1], cwdir)) >= match_value)) { - match_value = j; - - ap2 = NULL; - if (((i + 2) < MAXARGS) - && ((q = entry->arg[i + 2]) != (char *) NULL) - && (q[0] != '\0')) - ap2 = q; - - ap3 = NULL; - if (((i + 3) < MAXARGS) - && ((q = entry->arg[i + 3]) != (char *) NULL) - && (q[0] != '\0')) - ap3 = q; - - ap4 = NULL; - if (((i + 4) < MAXARGS) - && ((q = entry->arg[i + 4]) != (char *) NULL) - && (q[0] != '\0')) - ap4 = q; - - ap5 = NULL; - if (((i + 5) < MAXARGS) - && ((q = entry->arg[i + 5]) != (char *) NULL) - && (q[0] != '\0')) - ap5 = q; - } - } - } - - if (ap3 - && ((!strcasecmp("dirs", ap3)) - || (!strcasecmp("nodirs", ap3)))) - ap3 = NULL; - - /* - * if we did get matches ... else don't do any of this stuff - */ - if (match_value >= 0) { - if (!strcasecmp(ap2, "yes")) { - if ((ap3 && *ap3 == '*') || (ap4 && *ap4 == '*')) - stat_result = stat(path, &stbuf); - if (ap3) { - if ((ap3[0] != '*') || (ap3[1] != '\0')) - *uid = atoi(ap3); /* the uid */ - else if (stat_result == 0) - *uid = stbuf.st_uid; - } - if (ap4) { - if ((ap4[0] != '*') || (ap4[1] != '\0')) - *gid = atoi(ap4); /* the gid */ - else if (stat_result == 0) - *gid = stbuf.st_gid; - *valid = 1; - } - if (ap5) - sscanf(ap5, "%o", f_mode); /* the mode */ - } - else { - reply(553, "%s: Permission denied on server. (Upload)", name); - return (-1); - } - } - else { - /* - * upload defaults to "permitted" - */ - /* Not if anonymous */ - if (anonymous) { - reply(553, "%s: Permission denied on server. (Upload)", name); - return (-1); - } - return (1); - } - - return (match_value); -} - -int del_check(char *name) -{ - int pdelete = (anonymous ? 0 : 1); - struct aclmember *entry = NULL; - - while (getaclentry("delete", &entry) && ARG0 && ARG1 != NULL) { - if (type_match(ARG1)) - if (anonymous) { - if (*ARG0 == 'y') - pdelete = 1; - } - else if (*ARG0 == 'n') - pdelete = 0; - } - -/* H* fix: no deletion, period. You put a file here, I get to look at it. */ -#ifdef PARANOID - pdelete = 0; -#endif - - if (!pdelete) { - reply(553, "%s: Permission denied on server. (Delete)", name); - return (0); - } - else { - return (1); - } -} - -/* The following is from the Debian add-ons. */ - -#define lbasename(x) (strrchr(x,'/')?1+strrchr(x,'/'):x) - -int regexmatch(char *name, char *rgexp) -{ - -#ifdef M_UNIX -#ifdef HAVE_REGEX - char *regp; -#endif -#endif - -#ifdef HAVE_REGEXEC - regex_t regexbuf; - regmatch_t regmatchbuf; - int rval; -#else - char *sp; -#endif - -#if defined(HAVE_REGEXEC) - if (regcomp(®exbuf, rgexp, REG_EXTENDED) != 0) { - reply(553, "HAVE_REGEX error"); -#elif defined(HAVE_REGEX) - if ((sp = regcmp(rgexp, (char *) 0)) == NULL) { - reply(553, "HAVE_REGEX error"); -#else - if ((sp = re_comp(rgexp)) != 0) { - perror_reply(553, sp); -#endif - return (0); - } - -#if defined(HAVE_REGEXEC) - rval = regexec(®exbuf, name, 1, ®matchbuf, 0); - regfree(®exbuf); - if (rval != 0) { -#elif defined(HAVE_REGEX) -#ifdef M_UNIX - regp = regex(sp, name); - free(sp); - if (regp == NULL) { -#else - if ((regex(sp, name)) == NULL) { -#endif -#else - if ((re_exec(name)) != 1) { -#endif - return (0); - } - return (1); -} - -static int allow_retrieve(char *name) -{ - char realname[MAXPATHLEN + 1]; - char localname[MAXPATHLEN + 1]; - char *whichname; - int i; - struct aclmember *entry = NULL; - char *p, *q; - int options; - int classfound; - int classmatched; - char class[1024]; - - (void) acl_getclass(class); - if ((name == (char *) NULL) - || (*name == '\0')) - return 0; - fb_realpath(name, localname); - wu_realpath(name, realname, chroot_path); - while (getaclentry("allow-retrieve", &entry)) { - whichname = realname; - i = 0; - options = 1; - classfound = 0; - classmatched = 0; - while (options - && (i < MAXARGS) - && ((q = entry->arg[i]) != (char *) NULL) - && (q[0] != '\0')) { - if (strcasecmp(q, "absolute") == 0) { - i++; - whichname = realname; - } - else if (strcasecmp(q, "relative") == 0) { - i++; - whichname = localname; - } - else if (strncasecmp(q, "class=", 6) == 0) { - i++; - classfound = 1; - if (strcasecmp(q + 6, class) == 0) - classmatched = 1; - } - else if (strcmp(q, "-") == 0) { - i++; - options = 0; - } - else - options = 0; - } - if (!classfound || classmatched) { - for (; (i < MAXARGS) && ((q = entry->arg[i]) != (char *) NULL) && (q[0] != '\0'); i++) { - p = (q[0] == '/') ? whichname : lbasename(whichname); - if (!wu_fnmatch(q, p, FNM_PATHNAME | FNM_LEADING_DIR)) { - return 1; - } - } - } - } - return 0; -} - -int checknoretrieve(char *name) -{ - char realname[MAXPATHLEN + 1]; - char localname[MAXPATHLEN + 1]; - char *whichname; - int i; - struct aclmember *entry = NULL; - char *p, *q; - int options; - int classfound; - int classmatched; - char class[1024]; - - extern struct passwd *pw; - extern char *remoteident; - - (void) acl_getclass(class); - if ((name == (char *) NULL) - || (*name == '\0')) - return 0; - fb_realpath(name, localname); - wu_realpath(name, realname, chroot_path); - while (getaclentry("noretrieve", &entry)) { - whichname = realname; - i = 0; - options = 1; - classfound = 0; - classmatched = 0; - while (options - && (i < MAXARGS) - && ((q = entry->arg[i]) != (char *) NULL) - && (q[0] != '\0')) { - if (strcasecmp(q, "absolute") == 0) { - i++; - whichname = realname; - } - else if (strcasecmp(q, "relative") == 0) { - i++; - whichname = localname; - } - else if (strncasecmp(q, "class=", 6) == 0) { - i++; - classfound = 1; - if (strcasecmp(q + 6, class) == 0) - classmatched = 1; - } - else if (strcmp(q, "-") == 0) { - i++; - options = 0; - } - else - options = 0; - } - if (!classfound || classmatched) { - for (; (i < MAXARGS) && ((q = entry->arg[i]) != (char *) NULL) && (q[0] != '\0'); i++) { - p = (q[0] == '/') ? whichname : lbasename(whichname); - if (!wu_fnmatch(q, p, FNM_PATHNAME | FNM_LEADING_DIR)) { - if (!allow_retrieve(name)) { - reply(550, "%s is marked unretrievable", localname); - return 1; - } - } - } - } - } - return 0; -} - -#ifdef QUOTA - -#ifndef MNTMAXSTR -#define MNTMAXSTR 2048 /* And hope it's enough */ -#endif - -#ifdef QUOTA_DEVICE - -int path_to_device(char *pathname, char *result) -{ - FILE *fp; -#ifdef HAS_OLDSTYLE_GETMNTENT - struct mnttab static_mp; - struct mnttab *mp = &static_mp; -#else - struct mntent *mp; -#endif - struct mount_ent { - char mnt_fsname[MNTMAXSTR], mnt_dir[MNTMAXSTR]; - struct mount_ent *next; - } mountent; - struct mount_ent *current, *start, *new; - char path[1024], mnt_dir[1024], *pos; - int flag = 1; - - start = current = NULL; -#ifdef HAS_OLDSTYLE_GETMNTENT - fp = fopen(MNTTAB, "r"); -#else - fp = setmntent(MNTTAB, "r"); -#endif - if (fp == NULL) - return 0; -#ifdef HAS_OLDSTYLE_GETMNTENT - while (getmntent(fp, &static_mp) == 0) -#else - while (mp = getmntent(fp)) -#endif - { - if (!(new = (struct mount_ent *) malloc(sizeof(mountent)))) { - perror("malloc"); - flag = 0; - break; - } - - if (!start) - start = current = new; - else - current = current->next = new; - -#ifdef HAS_OLDSTYLE_GETMNTENT - strncpy(current->mnt_fsname, mp->mnt_special, strlen(mp->mnt_special) + 1); - strncpy(current->mnt_dir, mp->mnt_mountp, strlen(mp->mnt_mountp) + 1); -#else - strncpy(current->mnt_fsname, mp->mnt_fsname, strlen(mp->mnt_fsname) + 1); - strncpy(current->mnt_dir, mp->mnt_dir, strlen(mp->mnt_dir) + 1); -#endif - } -#ifdef HAS_OLDSTYLE_GETMNTENT - fclose(fp); -#else - endmntent(fp); -#endif - current->next = NULL; - - wu_realpath(pathname, path, chroot_path); - - while (*path && flag) { - current = start; - while (current && flag) { - if (strcmp(current->mnt_dir, "swap")) { - wu_realpath(current->mnt_dir, mnt_dir, chroot_path); - if (!strcmp(mnt_dir, path)) { - flag = 0; - /* no support for remote quota yet */ - if (!strchr(current->mnt_fsname, ':')) - strcpy(result, current->mnt_fsname); - } - } - current = current->next; - } - if (!((pos = strrchr(path, '/')) - path) && strlen(path) > 1) - strcpy(path, "/"); - else - path[pos - path] = '\0'; - } - while (current) { - new = current->next; - free(current); - current = new; - } - return 1; -} -#endif - -void get_quota(char *fs, int uid) -{ - char mnt_fsname[MNTMAXSTR]; -#ifdef HAS_NO_QUOTACTL - int dirfd; - struct quotctl qp; -#endif - - /* - * Getting file system quota information can take a noticeable amount - * of time, so only get quota information for specified users. - * quota-info [ ...] - */ - if (!uid_match("quota-info", uid)) - return; - -#ifdef HAS_NO_QUOTACTL - if (path_to_device(fs, mnt_fsname)) { - dirfd = open(fs, O_RDONLY); - qp.op = Q_GETQUOTA; - qp.uid = uid; - qp.addr = (char *) "a; - ioctl(dirfd, Q_QUOTACTL, &qp); - close(dirfd); - } -#else -#ifdef QUOTA_DEVICE - - if (path_to_device(fs, mnt_fsname)) -#ifdef QCMD - quotactl(QCMD(Q_GETQUOTA, USRQUOTA), mnt_fsname, uid, (char *) "a); -#else - quotactl(Q_GETQUOTA, mnt_fsname, uid, (char *) "a); -#endif -#else - quotactl(fs, QCMD(Q_GETQUOTA, USRQUOTA), uid, (char *) "a); -#endif -#endif /* HAS_NO_QUOTACTL */ -} - -char *time_quota(long curstate, long softlimit, long timelimit, char *timeleft) -{ - struct timeval tv; - - gettimeofday(&tv, NULL); - if (softlimit && curstate >= softlimit) { - if (timelimit == 0) { - strcpy(timeleft, "NOT STARTED"); - } - else if (timelimit > tv.tv_sec) { - fmttime(timeleft, timelimit - tv.tv_sec); - } - else { - strcpy(timeleft, "EXPIRED"); - } - } - else { - timeleft[0] = '\0'; - } - return (timeleft); -} - -void fmttime(char *buf, register long time) -{ - int i; - static struct { - int c_secs; /* conversion units in secs */ - char *c_str; /* unit string */ - } cunits[] = { - { - 60 *60 * 24 * 28, "months" - } , - { - 60 *60 * 24 * 7, "weeks" - } , - { - 60 *60 * 24, "days" - } , - { - 60 *60, "hours" - } , - { - 60, "mins" - } , - { - 1, "secs" - } - }; - - if (time <= 0) { - strcpy(buf, "EXPIRED"); - return; - } - for (i = 0; i < sizeof(cunits) / sizeof(cunits[0]); i++) { - if (time >= cunits[i].c_secs) - break; - } - sprintf(buf, "%.1f %s", (double) time / cunits[i].c_secs, cunits[i].c_str); -} - -#endif - -#ifdef THROUGHPUT - -int file_compare(char *patterns, char *file) -{ - char buf[MAXPATHLEN+1]; - char *cp; - char *cp2; - int i; - int matches = 0; - - strncpy(buf, patterns, sizeof(buf) - 1); - buf[sizeof(buf) - 2] = '\0'; - i = strlen(buf); - buf[i++] = ','; - buf[i++] = '\0'; - - cp = buf; - while ((cp2 = strchr(cp, ',')) != NULL) { - *cp2++ = '\0'; - if (wu_fnmatch(cp, file, FNM_PATHNAME) == 0) { - matches = 1; - break; - } - cp = cp2; - } - return matches; -} - -int remote_compare(char *patterns) -{ - char buf[MAXPATHLEN+1]; - char *cp; - char *cp2; - int i; - int matches = 0; - - strncpy(buf, patterns, sizeof(buf) - 1); - buf[sizeof(buf) - 2] = '\0'; - i = strlen(buf); - buf[i++] = ','; - buf[i++] = '\0'; - - cp = buf; - while ((cp2 = strchr(cp, ',')) != NULL) { - *cp2++ = '\0'; - if (hostmatch(cp, remoteaddr, remotehost)) { - matches = 1; - break; - } - cp = cp2; - } - return matches; -} - -void throughput_calc(char *name, int *bps, double *bpsmult) -{ - int match_value = -1; - char cwdir[MAXPATHLEN]; - char pwdir[MAXPATHLEN]; - char path[MAXPATHLEN]; - char file[MAXPATHLEN]; - char *ap3 = NULL, *ap4 = NULL; - struct aclmember *entry = NULL; - extern char *home; - char *sp; - int i; - - /* default is maximum throughput */ - *bps = -1; - *bpsmult = 1.0; - - /* XXX We could use dynamic RAM to store this path, but I'd rather just bail - out with an error. The rest of wu is so crufy that a long path might - just blow up later */ - - if ((strlen(name) + 1) > sizeof(path)) { - return; - } - - /* what's our current directory? */ - strcpy(path, name); - if ((sp = strrchr(path, '/'))) - *sp = '\0'; - else - strcpy(path, "."); - if ((sp = strrchr(name, '/'))) - strcpy(file, sp + 1); - else - strcpy(file, name); - if ((fb_realpath(path, cwdir)) == NULL) { - return; - } - - wu_realpath(home, pwdir, chroot_path); - - /* find best matching entry */ - while (getaclentry("throughput", &entry) && ARG0 && ARG1 && ARG2 && ARG3 && ARG4 && ARG5 != NULL) { - if ((0 < path_compare(ARG0, pwdir)) - && ((i = path_compare(ARG1, cwdir)) >= match_value) - ) { - if (file_compare(ARG2, file)) { - if (remote_compare(ARG5)) { - match_value = i; - ap3 = ARG3; - ap4 = ARG4; - } - } - } - } - - /* if we did get matches */ - if (match_value >= 0) { - if (strcasecmp(ap3, "oo") == 0) - *bps = -1; - else - *bps = atoi(ap3); - if (strcmp(ap4, "-") == 0) - *bpsmult = 1.0; - else - *bpsmult = atof(ap4); - } - return; -} - -void throughput_adjust(char *name) -{ - int match_value = -1; - char pwdir[MAXPATHLEN]; - char cwdir[MAXPATHLEN]; - char path[MAXPATHLEN]; - char file[MAXPATHLEN]; - char buf[MAXPATHLEN]; - char *ap3 = NULL, *ap4 = NULL; - char **pap; - struct aclmember *entry = NULL; - extern char *home; - char *sp; - int i; - - /* XXX We could use dynamic RAM to store this path, but I'd rather just bail - out with an error. The rest of wu is so crufy that a long path might - just blow up later */ - - if ((strlen(name) + 1) > sizeof(path)) { - return; - } - - /* what's our current directory? */ - strcpy(path, name); - if ((sp = strrchr(path, '/'))) - *sp = '\0'; - else - strcpy(path, "."); - if ((sp = strrchr(name, '/'))) - strcpy(file, sp + 1); - else - strcpy(file, name); - if ((fb_realpath(path, cwdir)) == NULL) { - return; - } - - wu_realpath(home, pwdir, chroot_path); - - /* find best matching entry */ - while (getaclentry("throughput", &entry) && ARG0 && ARG1 && ARG2 && ARG3 && ARG4 && ARG5 != NULL) { - if ((0 < path_compare(ARG0, pwdir)) - && ((i = path_compare(ARG1, cwdir)) >= match_value) - ) { - if (file_compare(ARG2, file)) { - if (remote_compare(ARG5)) { - match_value = i; - ap3 = ARG3; - pap = ARG; - ap4 = ARG4; - } - } - } - } - - /* if we did get matches */ - if (match_value >= 0) { - if (strcasecmp(ap3, "oo") != 0) { - if (strcmp(ap4, "-") != 0) { - sprintf(buf, "%.0f", atoi(ap3) * atof(ap4)); - pap[3] = (char *) malloc(strlen(buf) + 1); - if (pap[3] == NULL) { - syslog(LOG_ERR, "malloc error in throughput_adjust"); - dologout(1); - } - /* Use ARG6 to keep track of malloced memory */ - if (pap[6]) - free(pap[6]); - pap[6] = pap[3]; - strcpy(pap[3], buf); - } - } - } - return; -} - -#endif - -#ifdef SOLARIS_2 -static int CheckMethod = 1; -#else -static int CheckMethod = 0; -#endif - -void SetCheckMethod(const char *method) -{ - if ((strcasecmp(method, "md5") == 0) - || (strcasecmp(method, "rfc1321") == 0)) - CheckMethod = 0; - else if ((strcasecmp(method, "crc") == 0) - || (strcasecmp(method, "posix") == 0)) - CheckMethod = 1; - else { - reply(500, "Unrecognized checksum method"); - return; - } - switch (CheckMethod) { - default: - reply(200, "Checksum method is now: MD5 (RFC1321)"); - break; - case 1: - reply(200, "Checksum method is now: CRC (POSIX)"); - break; - } -} - -void ShowCheckMethod(void) -{ - switch (CheckMethod) { - default: - reply(200, "Current checksum method: MD5 (RFC1321)"); - break; - case 1: - reply(200, "Current checksum method: CRC (POSIX)"); - break; - } -} - -void CheckSum(char *pathname) -{ - char *cmd; - char buf[MAXPATHLEN]; - FILE *cmdf; - struct stat st; - - if (stat(pathname, &st) == 0) { - if ((st.st_mode & S_IFMT) != S_IFREG) { - reply(500, "%s: not a plain file.", pathname); - return; - } - } - else { - perror_reply(550, pathname); - return; - } - - switch (CheckMethod) { - default: - cmd = "/bin/md5sum"; - break; - case 1: - cmd = "/bin/cksum"; - break; - } - - if (strlen(cmd) + 1 + strlen(pathname) + 1 > sizeof(buf)) { - reply(500, "Pathname too long"); - return; - } - sprintf(buf, "%s %s", cmd, pathname); - - cmdf = ftpd_popen(buf, "r", 0); - if (!cmdf) { - perror_reply(550, cmd); - } - else { - if (fgets(buf, sizeof buf, cmdf)) { - char *crptr = strchr(buf, '\n'); - if (crptr != NULL) - *crptr = '\0'; - reply(200, "%s", buf); - } - ftpd_pclose(cmdf); - } -} - -void CheckSumLastFile(void) -{ - extern char LastFileTransferred[]; - - if (LastFileTransferred[0] == '\0') - reply(500, "Nothing transferred yet"); - else - CheckSum(LastFileTransferred); -} diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/extensions.h b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/extensions.h deleted file mode 100644 index 4e05f47552..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/extensions.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/**************************************************************************** - Copyright (c) 1999,2000 WU-FTPD Development Group. - All rights reserved. - - Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 - The Regents of the University of California. - Portions Copyright (c) 1993, 1994 Washington University in Saint Louis. - Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc. - Portions Copyright (c) 1989 Massachusetts Institute of Technology. - Portions Copyright (c) 1998 Sendmail, Inc. - Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman. - Portions Copyright (c) 1997 by Stan Barber. - Portions Copyright (c) 1997 by Kent Landfield. - Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 - Free Software Foundation, Inc. - - Use and distribution of this software and its source code are governed - by the terms and conditions of the WU-FTPD Software License ("LICENSE"). - - If you did not receive a copy of the license, it may be obtained online - at http://www.wu-ftpd.org/license.html. - - $Id: extensions.h,v 1.12 2000/07/01 18:17:39 wuftpd Exp $ - -****************************************************************************/ -#define LOG_IN 0 -#define C_WD 1 -#define BANNER 2 - -#ifndef ALIGN -#define ALIGN(x) ((x) + (sizeof(long) - (x) % sizeof(long))) -#endif - -#define O_COMPRESS (1 << 0) /* file was compressed */ -#define O_UNCOMPRESS (1 << 1) /* file was uncompressed */ -#define O_TAR (1 << 2) /* file was tar'ed */ - -#define MAXARGS 50 -#define MAXKWLEN 20 - -struct aclmember { - struct aclmember *next; - char keyword[MAXKWLEN]; - char *arg[MAXARGS]; -}; - -#define ARG0 entry->arg[0] -#define ARG1 entry->arg[1] -#define ARG2 entry->arg[2] -#define ARG3 entry->arg[3] -#define ARG4 entry->arg[4] -#define ARG5 entry->arg[5] -#define ARG6 entry->arg[6] -#define ARG7 entry->arg[7] -#define ARG8 entry->arg[8] -#define ARG9 entry->arg[9] -#define ARG entry->arg - -/* Header at start of PID file */ -struct pidfile_header { - int count; - time_t last_checked; -}; - -/* File transfer logging (xferlog) */ -#include - -#define MAXXFERSTRLEN (MAXPATHLEN + 1024) -#define MAXSPACTCHARS 4 - -struct xferstat { - char *filename; - char access_mode; - char completion; - char transfer_direction; - char transfer_type; - char special_action[MAXSPACTCHARS]; - int auth; - int transfer_time; - off_t filesize; - off_t restart_offset; - off_t transfer_bytes; -}; -extern int xferdone; -extern char xferlog_format[]; -extern struct xferstat xfervalues; - -/* Type values for the various passive modes supported by the server */ -#define TYPE_PASV 0 -#ifdef INET6 -#define TYPE_EPSV 1 -#define TYPE_LPSV 2 -#endif - -#ifdef QUOTA -#ifdef TIME_WITH_SYS_TIME -#include -#include -#else -#ifdef HAVE_SYS_TIME_H -#include -#else -#include -#endif -#endif - -#ifdef IRIX -#define QUOTA_BLOCKS -#define QUOTA_DEVICE -#include -#include -#endif - -#ifdef SOLARIS_2 -#define QUOTA_BLOCKS -#define QUOTA_DEVICE -#define HAS_OLDSTYLE_GETMNTENT -#define HAS_NO_QUOTACTL -#include -#include -#include -#include -#include -#include -#endif - -#ifdef SUNOS -#define QUOTA_BLOCKS -#define QUOTA_DEVICE -#include -#include -#endif - -#ifdef AIX -#include -#endif - -#ifdef DIGITAL -#include -#endif - -#ifdef BSDI -#include -#endif - -#ifdef LINUX -#define QUOTA_DEVICE -#include -#include -#ifdef HAVE_SYS_QUOTA_H -#include -#else -#include -#endif -#endif - -#ifdef HAVE_FCNTL_H -#include -#endif -#ifdef HAVE_SYS_QUOTA_H /* This is defined only in the autoconf'ed build */ -#include -#endif -#ifdef HAVE_MNTENT_H -#include -#endif - -#endif /* QUOTA */ diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftp.xml b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftp.xml deleted file mode 100644 index dd6e492036..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftp.xml +++ /dev/null @@ -1,86 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpaccess b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpaccess deleted file mode 100644 index ba932b06c9..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpaccess +++ /dev/null @@ -1,58 +0,0 @@ -# ident "%Z%%M% %I% %E% SMI" -# -# FTP server configuration file, see ftpaccess(4). -# - -class realusers real * -class guestusers guest * -class anonusers anonymous * - -loginfails 3 -passwd-check trivial warn -private no -shutdown /etc/ftpd/shutdown.msg -# email user@hostname -# guestuser username -# rhostlookup no - -keepalive yes -recvbuf 65536 real,guest,anonymous -sendbuf 65536 real,guest,anonymous -# flush-wait no anonymous -# passive ports 0.0.0.0/0 32768 65535 -# timeout data 600 -# timeout idle 300 - -banner /etc/ftpd/banner.msg -greeting brief -message /etc/ftpd/welcome.msg login -message .message cwd=* -readme README* login -readme README* cwd=* -# quota-info * - -chmod no anonymous -delete no anonymous -overwrite no anonymous -rename no anonymous -umask no anonymous - -compress yes realusers guestusers anonusers -tar yes realusers guestusers anonusers - -path-filter guest,anonymous /etc/ftpd/filename.msg ^[[:alnum:]._-]*$ ^[.-] - -noretrieve relative class=anonusers / -allow-retrieve relative class=anonusers /pub - -upload class=anonusers * * no nodirs -# upload class=anonusers * /incoming yes ftpadm ftpadm 0440 nodirs - -# log commands real,guest,anonymous -# log security real,guest,anonymous -# log transfers real,guest,anonymous inbound,outbound -# xferlog format %T %Xt %R %Xn %XP %Xy %Xf %Xd %Xm %U ftp %Xa %u %Xc %Xs %Xr - -# limit-time anonymous 30 -# limit anonusers 10 Wk0730-1800 /etc/ftpd/toomany.msg -# limit anonusers 50 SaSu|Any1800-0730 /etc/ftpd/toomany.msg diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpaddhost.sh b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpaddhost.sh deleted file mode 100644 index 1fa4778114..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpaddhost.sh +++ /dev/null @@ -1,319 +0,0 @@ -#!/usr/bin/ksh -# -# ident "%Z%%M% %I% %E% SMI" -# -# Copyright (c) 1997-2001 by Sun Microsystems, Inc. -# All rights reserved. -# -# -# This script sets up a virtual FTP host. -# -# Usage: -# ftpaddhost -c|-l [-b] [ -x xferlog ] hostname root_dir -# -# ftpaddhost configures virtual host hostname under directory root_dir. -# An IP address can be used for hostname. -# -# The -c (complete) option configures complete virtual hosting, which allows -# each virtual host to have its own version of the ftpaccess, ftpconversions, -# ftpgroups, ftphosts and ftpusers files. The master version of each of these -# configuration files is copied from the /etc/ftpd directory and placed in -# the /etc/ftpd/virtual-ftpd/hostname directory. If the /etc/ftpusers file -# exists it is appended to the virtual ftpusers file. If a virtual host lacks -# its own version of a configuration file, the master version is used. -# -# The -l (limited) option configures limited virtual hosting, which only -# allows a small number of parameters to be configured differently for a -# virtual host (see the virtual keyword on the ftpaccess(4) manual page). -# -# When the -b (banner) option is supplied, ftpaddhost creates a banner for -# the virtual host, useful to see that the virtual host is working. -# -# When the -x xferlog option is supplied, ftpaddhost creates a logfile entry -# which causes the transfer logs for the virtual host to be written to the -# specified file. -# -# Exit codes: 0 - success -# 1 - usage -# 2 - command failure -# - -usage() -{ - fmt=`gettext "Usage: %s -c|-l [-b] [ -x xferlog ] hostname root_dir"` - printf "$fmt\n" "$cmd" >&2 - exit 1 -} - -verify_root() -{ - # Verify caller has a real user ID of 0. - set `id` - if [ "$1" != "uid=0(root)" ] - then - fmt=`gettext "%s: Error: Only root can run %s"` - printf "$fmt\n" "$cmd" "$cmd" >&2 - exit 1 - fi -} - -# Make directory $1 with mode $2 and ownership $3. -make_dir() -{ - if [ ! -d "$1" ] - then - mkdir "$1" || exit 2 - fi - chmod "$2" "$1" - chown "$3" "$1" -} - -setup_complete_vhost() -{ - fmt=`gettext "Setting up complete virtual host %s"` - printf "$fmt\n" "$hostname" - make_dir /etc/ftpd/virtual-ftpd 755 root:sys - make_dir "/etc/ftpd/virtual-ftpd/$hostname" 755 root:sys - - fmt=`gettext "Configuration directory is %s"` - printf "$fmt\n" "/etc/ftpd/virtual-ftpd/$hostname" - - # Update the virtual host configuration file. - vhconfig=/etc/ftpd/ftpservers - - fmt=`gettext "Updating virtual hosting configuration file %s"` - printf "$fmt\n" $vhconfig - if [ -f $vhconfig ] - then - # Remove any existing entries for the virtual host. - sed "/^[ ]*$hostname[ ]/d" $vhconfig >$vhconfig.tmp.$$ - mv -f $vhconfig.tmp.$$ $vhconfig || exit 2 - fi - - echo "$hostname /etc/ftpd/virtual-ftpd/$hostname" >>$vhconfig - chmod 644 $vhconfig - chown root:sys $vhconfig - - # Make copies of the master configuration files. - for file in ftpconversions ftpgroups ftphosts ftpusers - do - target="/etc/ftpd/virtual-ftpd/$hostname/$file" - rm -f "$target" - if [ -f /etc/ftpd/$file ] - then - cp /etc/ftpd/$file "$target" || exit 2 - chmod 644 "$target" - chown root:sys "$target" - fi - done - - # Append /etc/ftpusers to the virtual hosts ftpusers. - if [ -f /etc/ftpusers ] - then - target="/etc/ftpd/virtual-ftpd/$hostname/ftpusers" - cat /etc/ftpusers >>"$target" - chmod 644 "$target" - chown root:sys "$target" - fi - - vhftpaccess="/etc/ftpd/virtual-ftpd/$hostname/ftpaccess" - rm -f "$vhftpaccess" - - # Remove any existing root or logfile entries. - sed "/^[ ]*root[ ]/d - /^[ ]*logfile[ ]/d" $ftpaccess >"$vhftpaccess" - - # Add the virtual host root. - echo "root $vhroot" >>"$vhftpaccess" - - # Add a banner to show the virtual host configuration worked. - if [ -n "$banner" ] - then - # Add a banner entry if there isn't already one. - grep "^[ ]*banner[ ]" "$vhftpaccess" >/dev/null 2>&1 - if [ $? -eq 0 ] - then - fmt=`gettext "Existing banner entry not changed in %s"` - printf "$fmt\n" "$vhftpaccess" - else - bannerf="/etc/ftpd/virtual-ftpd/$hostname/cbanner.msg" - if [ -f "$bannerf" ] - then - fmt=`gettext "Using existing banner file %s"` - printf "$fmt\n" "$bannerf" - else - fmt=`gettext "Creating banner file %s"` - printf "$fmt\n" "$bannerf" - fmt=`gettext "Complete virtual host %%L test banner"` - printf "$fmt\n" >"$bannerf" - chmod 644 "$bannerf" - chown root:sys "$bannerf" - fi - echo "banner $bannerf" >>"$vhftpaccess" - fi - fi - - # Add the transfer logfile. - if [ -n "$logfile" ] - then - echo "logfile $logfile" >>"$vhftpaccess" - fi - - chmod 644 "$vhftpaccess" - chown root:sys "$vhftpaccess" -} - -setup_limited_vhost() -{ - # Check complete virtual hosting is not configured for the host. - grep "^[ ]*$hostname[ ]" /etc/ftpd/ftpservers >/dev/null 2>&1 - if [ $? -eq 0 ] - then - fmt=`gettext "%s: Error: Complete virtual hosting already configured for %s"` - printf "$fmt\n" "$cmd" "$hostname" >&2 - exit 1 - fi - - fmt=`gettext "Setting up limited virtual host %s"` - printf "$fmt\n" "$hostname" - - # Update the ftpaccess file. - fmt=`gettext "Updating FTP server configuration file %s"` - printf "$fmt\n" $ftpaccess - - # Remove any existing entries for the virtual host. - sed "/^[ ]*virtual[ ][ ]*$hostname[ ]/d" $ftpaccess >$ftpaccess.tmp.$$ - mv -f $ftpaccess.tmp.$$ $ftpaccess || exit 2 - - # Add a limited virtual hosting entry for the virtual host. - echo "virtual $hostname root $vhroot" >>$ftpaccess - - # Add a banner to show the virtual host configuration worked. - if [ -n "$banner" ] - then - bannerf="/etc/ftpd/virtual-ftpd/$hostname/lbanner.msg" - if [ -f "$bannerf" ] - then - fmt=`gettext "Using existing banner file %s"` - printf "$fmt\n" "$bannerf" - else - fmt=`gettext "Creating banner file %s"` - printf "$fmt\n" "$bannerf" - make_dir /etc/ftpd/virtual-ftpd 755 root:sys - make_dir "/etc/ftpd/virtual-ftpd/$hostname" 755 root:sys - fmt=`gettext "Limited virtual host %%L test banner"` - printf "$fmt\n" >"$bannerf" - chmod 644 "$bannerf" - chown root:sys "$bannerf" - fi - echo "virtual $hostname banner $bannerf" >>$ftpaccess - fi - - # Add the transfer logfile. - if [ -n "$logfile" ] - then - echo "virtual $hostname logfile $logfile" >>$ftpaccess - fi - - chmod 644 $ftpaccess - chown root:sys $ftpaccess -} - -# Execution starts here. - -IFS=" -" -SHELL=/usr/bin/ksh -PATH=/usr/bin -TEXTDOMAIN=SUNW_OST_OSCMD -export SHELL PATH IFS TEXTDOMAIN - -cmd=`basename "$0"` - -verify_root - -while getopts bclx: arg -do - case $arg in - b) banner=1;; - c) complete=1;; - l) limited=1;; - x) logfile="$OPTARG";; - \?) usage;; - esac -done -shift `expr $OPTIND - 1` - -# Check arguments. -[ -z "$complete" -a -z "$limited" ] && usage -[ -n "$complete" -a -n "$limited" ] && usage - -[ $# -ne 2 ] && usage -hostname="$1" -vhroot="$2" - -[ -z "$hostname" -o -z "$vhroot" ] && usage - -echo "$hostname" | grep / >/dev/null 2>&1 -if [ $? -eq 0 ] -then - fmt=`gettext "%s: Error: hostname must not contain a /"` - printf "$fmt\n" "$cmd" >&2 - usage -fi - -echo "$vhroot" | grep "^/" >/dev/null 2>&1 -if [ $? -ne 0 ] -then - fmt=`gettext "%s: Error: root_dir must be an absolute pathname"` - printf "$fmt\n" "$cmd" >&2 - usage -fi - -if [ -n "$logfile" ] -then - echo "$logfile" | grep "^/" >/dev/null 2>&1 - if [ $? -ne 0 ] - then - fmt=`gettext "%s: Error: xferlog must be an absolute pathname"` - printf "$fmt\n" "$cmd" >&2 - usage - fi -fi - -ftpaccess=/etc/ftpd/ftpaccess -if [ ! -f $ftpaccess ] -then - fmt=`gettext "%s: Error: FTP server configuration file %s missing"` - printf "$fmt\n" "$cmd" $ftpaccess >&2 - exit 2 -fi - -grep "^ftp:" /etc/passwd >/dev/null 2>&1 -if [ $? -ne 0 ] -then - fmt=`gettext "Warning: Must create ftp user account before virtual hosts will work"` - printf "$fmt\n" -fi - -# Ignore certain signals. -trap '' 1 2 3 15 - -umask 022 - -if [ -n "$complete" ] -then - setup_complete_vhost -else - setup_limited_vhost -fi - -/usr/sbin/ftpconfig -d "$vhroot" >/dev/null -if [ $? -ne 0 ] -then - fmt=`gettext "%s: Error: ftpconfig -d %s failed"` - printf "$fmt\n" "$cmd" "$vhroot" >&2 - exit 2 -fi - -exit 0 diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpcmd.y b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpcmd.y deleted file mode 100644 index aa73384455..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpcmd.y +++ /dev/null @@ -1,2523 +0,0 @@ -/* - * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -/**************************************************************************** - Copyright (c) 1999,2000,2001 WU-FTPD Development Group. - All rights reserved. - - Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 - The Regents of the University of California. - Portions Copyright (c) 1993, 1994 Washington University in Saint Louis. - Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc. - Portions Copyright (c) 1989 Massachusetts Institute of Technology. - Portions Copyright (c) 1998 Sendmail, Inc. - Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman. - Portions Copyright (c) 1997 by Stan Barber. - Portions Copyright (c) 1997 by Kent Landfield. - Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 - Free Software Foundation, Inc. - - Use and distribution of this software and its source code are governed - by the terms and conditions of the WU-FTPD Software License ("LICENSE"). - - If you did not receive a copy of the license, it may be obtained online - at http://www.wu-ftpd.org/license.html. - - $Id: ftpcmd.y,v 1.27.2.2 2001/11/29 17:01:38 wuftpd Exp $ - -****************************************************************************/ -/* - * Grammar for FTP commands. - * See RFC 959. - */ - -%{ -#include "config.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_SYS_SYSLOG_H -#include -#endif -#if defined(HAVE_SYSLOG_H) || (!defined(AUTOCONF) && !defined(HAVE_SYS_SYSLOG_H)) -#include -#endif -#include -#include -#include -#include -#include -#include "extensions.h" -#include "pathnames.h" -#include "proto.h" - -#if defined(USE_TLS) || defined(USE_GSS) -static int pbsz_command_issued = 0; -char *cur_auth_type = NULL; -extern char *protnames[]; -#endif /* defined(USE_TLS) || defined(USE_GSS) */ - -#if defined(USE_GSS) -#include "gssutil.h" - -extern gss_info_t gss_info; -#endif /* defined(USE_GSS) */ - -extern int dolreplies; -#ifndef INTERNAL_LS -extern char ls_long[]; -extern char ls_short[]; -#endif -extern struct SOCKSTORAGE data_dest; -extern struct SOCKSTORAGE his_addr; -extern int logged_in; -extern struct passwd *pw; -extern int anonymous; -extern int logging; -extern int log_commands; -extern int log_security; -extern int type; -extern int form; -extern int debug; -extern unsigned int timeout_idle; -extern unsigned int timeout_maxidle; -extern int pdata; -extern char hostname[], remotehost[], *remoteident; -extern char remoteaddr[]; -extern char chroot_path[]; -extern char guestpw[], authuser[]; /* added. _H */ -extern char proctitle[]; -extern char *globerr; -extern int usedefault; -extern int transflag; -extern char tmpline[]; -extern int data; -extern int errno; -extern char *home; - -off_t restart_point; -int yyerrorcalled; - -extern char *strunames[]; -extern char *typenames[]; -extern char *modenames[]; -extern char *formnames[]; -extern int restricted_user; /* global flag indicating if user is restricted to home directory */ - -#ifdef TRANSFER_COUNT -extern off_t data_count_total; -extern off_t byte_count_total; -extern off_t byte_count_in; -extern int file_count_total; -extern int xfer_count_total; -#endif - -extern int retrieve_is_data; - -#ifdef VIRTUAL -extern int virtual_mode; -extern int virtual_ftpaccess; -extern char virtual_email[]; -#endif - -#ifdef IGNORE_NOOP -static int alarm_running = 0; -#endif - -static unsigned short cliport = 0; -static struct in_addr cliaddr; -static int cmd_type; -static int cmd_form; -static int cmd_bytesz; -char cbuf[16 * BUFSIZ]; -char *fromname; - -#ifndef L_FORMAT /* Autoconf detects this... */ -#if (defined(BSD) && (BSD >= 199103)) && !defined(LONGOFF_T) -#define L_FORMAT "qd" -#else -#ifdef _AIX42 -#define L_FORMAT "lld" -#else -#ifdef SOLARIS_2 -#define L_FORMAT "ld" -#else -#define L_FORMAT "d" -#endif -#endif -#endif -#endif - -#ifdef INET6 -extern int epsv_all; -int lport_error; -#endif - -/* Debian linux bison fix: moved this up, added forward decls */ - -struct tab { - char *name; - short token; - short state; - short implemented; /* 1 if command is implemented */ - char *help; -}; - -extern struct tab cmdtab[]; -extern struct tab sitetab[]; - -static void toolong(int); -void help(struct tab *ctab, char *s); -struct tab *lookup(register struct tab *p, char *cmd); -int yylex(void); - -static char *nullstr = "(null)"; -#define CHECKNULL(p) ((p) ? (p) : nullstr) - -extern int pasv_allowed(const char *remoteaddr); -extern int port_allowed(const char *remoteaddr); -%} - -%token - A B C E F I - L N P R S T - - SP CRLF COMMA STRING NUMBER - - USER PASS ACCT REIN QUIT PORT - PASV TYPE STRU MODE RETR STOR - APPE MLFL MAIL MSND MSOM MSAM - MRSQ MRCP ALLO REST RNFR RNTO - ABOR DELE CWD LIST NLST SITE - STAT HELP NOOP MKD RMD PWD - CDUP STOU SMNT SYST SIZE MDTM - EPRT EPSV LPRT LPSV - PROT PBSZ AUTH ADAT CCC - - UMASK IDLE CHMOD GROUP GPASS NEWER - MINFO INDEX EXEC ALIAS CDPATH GROUPS - CHECKMETHOD CHECKSUM - - LEXERR - -%union { - char *String; - int Number; -} - -%type STRING password pathname pathstring username method -%type NUMBER byte_size check_login form_code -%type struct_code mode_code octal_number -%type prot_code - -%start cmd_list - -%% - -cmd_list: /* empty */ - | cmd_list cmd - = { - if (fromname) { - free(fromname); - fromname = NULL; - } - restart_point = 0; - } - | cmd_list rcmd - ; - -cmd: USER SP username CRLF - = { - user($3); - if (log_commands) - syslog(LOG_INFO, "USER %s", $3); - free($3); - } - | PASS SP password CRLF - = { - if (log_commands) - if (anonymous) - syslog(LOG_INFO, "PASS %s", $3); - else - syslog(LOG_INFO, "PASS password"); - - pass($3); - free($3); - } - | PORT check_login SP host_port CRLF - = { - if (log_commands) - syslog(LOG_INFO, "PORT"); -/* H* port fix, part B: admonish the twit. - Also require login before PORT works */ - if ($2) { -#ifndef DISABLE_PORT -#ifdef INET6 - if (epsv_all) { - reply(501, "PORT not allowed after EPSV ALL"); - goto prt_done; - } -#endif - if (((sock_cmp_inaddr(&his_addr, cliaddr) == 0) - || port_allowed(inet_ntoa(cliaddr))) - && (ntohs(cliport) >= IPPORT_RESERVED)) { - usedefault = 0; - if (pdata >= 0) { - (void) close(pdata); - pdata = -1; - } - SET_SOCK_FAMILY(data_dest, SOCK_FAMILY(his_addr)); - SET_SOCK_PORT(data_dest, cliport); - SET_SOCK_ADDR4(data_dest, cliaddr); - reply(200, "PORT command successful."); - } - else { -#endif /* DISABLE_PORT */ - reply(502, "Illegal PORT Command"); -prt_done: - usedefault = 1; - syslog(LOG_WARNING, "refused PORT %s,%d from %s", - inet_ntoa(cliaddr), ntohs(cliport), remoteident); -#ifndef DISABLE_PORT - } -#endif - } - } - | EPRT check_login SP STRING CRLF - = { -#ifdef INET6 - if (log_commands) - syslog(LOG_INFO, "EPRT"); - if ($2 && $4 != NULL) { -#ifndef DISABLE_PORT - char d, fmt[32], addr[INET6_ADDRSTRLEN + 1]; - int proto; - unsigned short port; - - if (epsv_all) { - reply(501, "EPRT not allowed after EPSV ALL"); - goto eprt_done; - } - d = *((char *)$4); - if ((d < 33) || (d > 126)) { - reply(501, "Bad delimiter '%c' (%d).", d, d); - goto eprt_done; - } - if (d == '%') - (void) snprintf(fmt, sizeof(fmt), - "%%%1$c%%d%%%1$c%%%2$d[^%%%1$c]%%%1$c%%hu%%%1$c", - d, INET6_ADDRSTRLEN); - else - (void) snprintf(fmt, sizeof(fmt), - "%1$c%%d%1$c%%%2$d[^%1$c]%1$c%%hu%1$c", - d, INET6_ADDRSTRLEN); - - if (sscanf((const char *)$4, fmt, &proto, addr, &port) != 3) { - reply(501, "EPRT bad format."); - goto eprt_done; - } - port = htons(port); - - switch (proto) { - case 1: - SET_SOCK_FAMILY(data_dest, AF_INET); - break; - case 2: - memset(&data_dest, 0, sizeof(struct sockaddr_in6)); - SET_SOCK_FAMILY(data_dest, AF_INET6); - break; - default: - reply(522, "Network protocol not supported, use (1,2)"); - goto eprt_done; - } - if (inet_pton(SOCK_FAMILY(data_dest), addr, SOCK_ADDR(data_dest)) - != 1) { - reply(501, "Bad address %s.", addr); - goto eprt_done; - } - - if (((sock_cmp_addr(&his_addr, &data_dest) == 0) - || port_allowed(inet_stop(&data_dest))) - && (ntohs(port) >= IPPORT_RESERVED)) { - usedefault = 0; - if (pdata >= 0) { - (void) close(pdata); - pdata = -1; - } - SET_SOCK_PORT(data_dest, port); - SET_SOCK_SCOPE(data_dest, his_addr); - reply(200, "EPRT command successful."); - } - else { -#endif /* DISABLE_PORT */ - reply(502, "Illegal EPRT Command"); -eprt_done: - usedefault = 1; - syslog(LOG_WARNING, "refused EPRT %s from %s", - $4, remoteident); -#ifndef DISABLE_PORT - } -#endif - } - if ($4 != NULL) - free($4); -#endif /* INET6 */ - } - | LPRT check_login SP host_lport CRLF - = { -#ifdef INET6 - if (log_commands) - syslog(LOG_INFO, "LPRT"); - if ($2) { -#ifndef DISABLE_PORT - if (lport_error) - goto lprt_done; - if (((sock_cmp_addr(&his_addr, &data_dest) == 0) - || port_allowed(inet_stop(&data_dest))) - && (SOCK_PORT(data_dest) >= IPPORT_RESERVED)) { - usedefault = 0; - if (pdata >= 0) { - (void) close(pdata); - pdata = -1; - } - SET_SOCK_SCOPE(data_dest, his_addr); - reply(200, "LPRT command successful."); - } - else { -#endif /* DISABLE_PORT */ - reply(502, "Illegal LPRT Command"); -lprt_done: - usedefault = 1; - syslog(LOG_WARNING, "refused LPRT from %s", remoteident); -#ifndef DISABLE_PORT - } -#endif - } -#endif /* INET6 */ - } - | PASV check_login CRLF - = { -/* Require login for PASV, too. This actually fixes a bug -- telnet to an - unfixed wu-ftpd and type PASV first off, and it crashes! */ - if (log_commands) - syslog(LOG_INFO, "PASV"); - if ($2) -#if (defined (DISABLE_PORT) || !defined (DISABLE_PASV)) -#ifdef INET6 - if (epsv_all) - reply(501, "PASV not allowed after EPSV ALL"); - else -#endif - passive(TYPE_PASV, 0); -#else - reply(502, "Illegal PASV Command"); -#endif - } - | EPSV check_login CRLF - = { -#ifdef INET6 - if (log_commands) - syslog(LOG_INFO, "EPSV"); - if ($2) -#if (defined (DISABLE_PORT) || !defined (DISABLE_PASV)) - passive(TYPE_EPSV, 0); -#else - reply(502, "Illegal EPSV Command"); -#endif -#endif /* INET6 */ - } - | EPSV check_login SP STRING CRLF - = { -#ifdef INET6 - if (log_commands) - syslog(LOG_INFO, "EPSV"); - if ($2 && $4 != NULL) -#if (defined (DISABLE_PORT) || !defined (DISABLE_PASV)) - if (strcasecmp((const char *)$4, "ALL") == 0) { - epsv_all = 1; - reply(200, "EPSV ALL command successful."); - } - else { - int af; - char *endp; - - af = strtoul((char *)$4, &endp, 0); - if (*endp) - reply(501, "'EPSV %s':" "command not understood.", $4); - else { - /* Not allowed to specify address family 0 */ - if (af == 0) - af = -1; - passive(TYPE_EPSV, af); - } - } -#else - reply(502, "Illegal EPSV Command"); -#endif - if ($4 != NULL) - free($4); -#endif /* INET6 */ - } - | LPSV check_login CRLF - = { -#ifdef INET6 - if (log_commands) - syslog(LOG_INFO, "LPSV"); - if ($2) -#if (defined (DISABLE_PORT) || !defined (DISABLE_PASV)) - if (epsv_all) - reply(501, "LPSV not allowed after EPSV ALL"); - else - passive(TYPE_LPSV, 0); -#else - reply(502, "Illegal LPSV Command"); -#endif -#endif /* INET6 */ - } - | TYPE check_login SP type_code CRLF - = { - if (log_commands) - syslog(LOG_INFO, "TYPE %s", typenames[cmd_type]); - if ($2) - switch (cmd_type) { - - case TYPE_A: - if (cmd_form == FORM_N) { - reply(200, "Type set to A."); - type = cmd_type; - form = cmd_form; - } - else - reply(504, "Form must be N."); - break; - - case TYPE_E: - reply(504, "Type E not implemented."); - break; - - case TYPE_I: - reply(200, "Type set to I."); - type = cmd_type; - break; - - case TYPE_L: -#if NBBY == 8 - if (cmd_bytesz == 8) { - reply(200, - "Type set to L (byte size 8)."); - type = cmd_type; - } - else - reply(504, "Byte size must be 8."); -#else /* NBBY == 8 */ -#error UNIMPLEMENTED for NBBY != 8 -#endif /* NBBY == 8 */ - } - } - | STRU check_login SP struct_code CRLF - = { - if (log_commands) - syslog(LOG_INFO, "STRU %s", strunames[$4]); - if ($2) - switch ($4) { - - case STRU_F: - reply(200, "STRU F ok."); - break; - - default: - reply(504, "Unimplemented STRU type."); - } - } - | MODE check_login SP mode_code CRLF - = { - if (log_commands) - syslog(LOG_INFO, "MODE %s", modenames[$4]); - if ($2) - switch ($4) { - - case MODE_S: - reply(200, "MODE S ok."); - break; - - default: - reply(502, "Unimplemented MODE type."); - } - } - | ALLO check_login SP NUMBER CRLF - = { - if (log_commands) - syslog(LOG_INFO, "ALLO %d", $4); - if ($2) - reply(202, "ALLO command ignored."); - } - | ALLO check_login SP NUMBER SP R SP NUMBER CRLF - = { - if (log_commands) - syslog(LOG_INFO, "ALLO %d R %d", $4, $8); - if ($2) - reply(202, "ALLO command ignored."); - } - | RETR check_login SP pathname CRLF - = { - if (log_commands) - syslog(LOG_INFO, "RETR %s", CHECKNULL($4)); - if ($2 && $4 != NULL && !restrict_check($4)) { - retrieve_is_data = 1; - retrieve((char *) NULL, $4); - } - if ($4 != NULL) - free($4); - } - | STOR check_login SP pathname CRLF - = { - if (log_commands) - syslog(LOG_INFO, "STOR %s", CHECKNULL($4)); - if ($2 && $4 != NULL && !restrict_check($4)) - store($4, "w", 0); - if ($4 != NULL) - free($4); - } - | APPE check_login SP pathname CRLF - = { - if (log_commands) - syslog(LOG_INFO, "APPE %s", CHECKNULL($4)); - if ($2 && $4 != NULL && !restrict_check($4)) - store($4, "a", 0); - if ($4 != NULL) - free($4); - } - | NLST check_login CRLF - = { - if (log_commands) - syslog(LOG_INFO, "NLST"); - if ($2 && !restrict_check(".")) - send_file_list(""); - } - | NLST check_login SP STRING CRLF - = { - if (log_commands) - syslog(LOG_INFO, "NLST %s", $4); - if ($2 && $4 && !restrict_check($4)) - send_file_list($4); - if ($4 != NULL) - free($4); - } - | LIST check_login CRLF - = { - if (log_commands) - syslog(LOG_INFO, "LIST"); - if ($2 && !restrict_check(".")) { - retrieve_is_data = 0; -#ifndef INTERNAL_LS - if (anonymous && dolreplies) - retrieve(ls_long, ""); - else - retrieve(ls_short, ""); -#else - ls(NULL, 0); -#endif - } - } - | LIST check_login SP pathname CRLF - = { - if (log_commands) - syslog(LOG_INFO, "LIST %s", CHECKNULL($4)); - if ($2 && $4 != NULL && !restrict_list_check($4)) { - retrieve_is_data = 0; -#ifndef INTERNAL_LS - if (anonymous && dolreplies) - retrieve(ls_long, $4); - else - retrieve(ls_short, $4); -#else - ls($4, 0); -#endif - } - if ($4 != NULL) - free($4); - } - | STAT check_login SP pathname CRLF - = { - if (log_commands) - syslog(LOG_INFO, "STAT %s", CHECKNULL($4)); - if ($2 && $4 != NULL && !restrict_check($4)) - statfilecmd($4); - if ($4 != NULL) - free($4); - } - | STAT check_login CRLF - = { - if (log_commands) - syslog(LOG_INFO, "STAT"); - if ($2) - statcmd(); - } - | DELE check_login SP pathname CRLF - = { - if (log_commands) - syslog(LOG_INFO, "DELE %s", CHECKNULL($4)); - if ($2 && $4 != NULL && !restrict_check($4)) - delete($4); - if ($4 != NULL) - free($4); - } - | RNTO check_login SP pathname CRLF - = { - if (log_commands) - syslog(LOG_INFO, "RNTO %s", CHECKNULL($4)); - if ($2 && $4 && !restrict_check($4)) { - if (fromname) { - renamecmd(fromname, $4); - free(fromname); - fromname = NULL; - } - else { - reply(503, "Bad sequence of commands."); - } - } - if ($4) - free($4); - } - | ABOR check_login CRLF - = { - if (log_commands) - syslog(LOG_INFO, "ABOR"); - if ($2) - reply(225, "ABOR command successful."); - } - | CWD check_login CRLF - = { - if (log_commands) - syslog(LOG_INFO, "CWD"); - if ($2 && !restrict_check(home)) - cwd(home); - } - | CWD check_login SP pathname CRLF - = { - if (log_commands) - syslog(LOG_INFO, "CWD %s", CHECKNULL($4)); - if ($2 && $4 != NULL && !restrict_check($4)) - cwd($4); - if ($4 != NULL) - free($4); - } - | HELP check_login CRLF - = { - if (log_commands) - syslog(LOG_INFO, "HELP"); - if ($2) - help(cmdtab, (char *) NULL); - } - | HELP check_login SP STRING CRLF - = { - register char *cp = (char *) $4; - - if (log_commands) - syslog(LOG_INFO, "HELP %s", $4); - if ($2) - if (strncasecmp(cp, "SITE", 4) == 0) { - cp = (char *) $4 + 4; - if (*cp == ' ') - cp++; - if (*cp) - help(sitetab, cp); - else - help(sitetab, (char *) NULL); - } - else - help(cmdtab, $4); - if ($4 != NULL) - free($4); - } - | NOOP check_login CRLF - = { - if (log_commands) - syslog(LOG_INFO, "NOOP"); - if ($2) - reply(200, "NOOP command successful."); - } - | MKD check_login SP pathname CRLF - = { - if (log_commands) - syslog(LOG_INFO, "MKD %s", CHECKNULL($4)); - if ($2 && $4 != NULL && !restrict_check($4)) - makedir($4); - if ($4 != NULL) - free($4); - } - | RMD check_login SP pathname CRLF - = { - if (log_commands) - syslog(LOG_INFO, "RMD %s", CHECKNULL($4)); - if ($2 && $4 != NULL && !restrict_check($4)) - removedir($4); - if ($4 != NULL) - free($4); - } - | PWD check_login CRLF - = { - if (log_commands) - syslog(LOG_INFO, "PWD"); - if ($2) - pwd(); - } - | CDUP check_login CRLF - = { - if (log_commands) - syslog(LOG_INFO, "CDUP"); - if ($2) - if (!test_restriction("..")) - cwd(".."); - else - ack("CWD"); - } - - | SITE check_login SP HELP CRLF - = { - if (log_commands) - syslog(LOG_INFO, "SITE HELP"); - if ($2) - help(sitetab, (char *) NULL); - } - | SITE check_login SP HELP SP STRING CRLF - = { - if (log_commands) - syslog(LOG_INFO, "SITE HELP %s", $6); - if ($2) - help(sitetab, $6); - if ($6 != NULL) - free($6); - } - | SITE check_login SP UMASK CRLF - = { - mode_t oldmask; - - if (log_commands) - syslog(LOG_INFO, "SITE UMASK"); - if ($2) { - oldmask = umask(0); - (void) umask(oldmask); - reply(200, "Current UMASK is %03o", oldmask); - } - } - | SITE check_login SP UMASK SP octal_number CRLF - = { - mode_t oldmask; - struct aclmember *entry = NULL; - int ok = 1; - - if (log_commands) - syslog(LOG_INFO, "SITE UMASK %03o", $6); - if ($2) { - /* check for umask permission */ - while (getaclentry("umask", &entry) && ARG0 && ARG1 != NULL) { - if (type_match(ARG1)) - if (*ARG0 == 'n') - ok = 0; - } - if (ok && !restricted_user) { - if (($6 < 0) || ($6 > 0777)) { - reply(501, "Bad UMASK value"); - } - else { - oldmask = umask((mode_t) $6); - reply(200, "UMASK set to %03o (was %03o)", $6, oldmask); - } - } - else - reply(553, "Permission denied on server. (umask)"); - } - } - | SITE check_login SP CHMOD SP octal_number SP pathname CRLF - = { - struct aclmember *entry = NULL; - int ok = (anonymous ? 0 : 1); - - if (log_commands) - syslog(LOG_INFO, "SITE CHMOD %03o %s", $6, CHECKNULL($8)); - if ($2 && $8) { - /* check for chmod permission */ - while (getaclentry("chmod", &entry) && ARG0 && ARG1 != NULL) { - if (type_match(ARG1)) - if (anonymous) { - if (*ARG0 == 'y') - ok = 1; - } - else if (*ARG0 == 'n') - ok = 0; - } - if (ok) { -#ifdef UNRESTRICTED_CHMOD - if (chmod($8, (mode_t) $6) < 0) -#else - if (($6 < 0) || ($6 > 0777)) - reply(501, - "CHMOD: Mode value must be between 0 and 0777"); - else if (chmod($8, (mode_t) $6) < 0) -#endif - perror_reply(550, $8); - else { - char path[MAXPATHLEN]; - - wu_realpath($8, path, chroot_path); - - if (log_security) - if (anonymous) { - syslog(LOG_NOTICE, "%s of %s changed permissions for %s", guestpw, remoteident, path); - } - else { - syslog(LOG_NOTICE, "%s of %s changed permissions for %s", pw->pw_name, - remoteident, path); - } - reply(200, "CHMOD command successful."); - } - } - else - reply(553, "Permission denied on server. (chmod)"); - } - if ($8 != NULL) - free($8); - } - | SITE check_login SP IDLE CRLF - = { - if (log_commands) - syslog(LOG_INFO, "SITE IDLE"); - if ($2) - reply(200, - "Current IDLE time limit is %d seconds; max %d", - timeout_idle, timeout_maxidle); - } - | SITE check_login SP IDLE SP NUMBER CRLF - = { - if (log_commands) - syslog(LOG_INFO, "SITE IDLE %d", $6); - if ($2) - if ($6 < 30 || $6 > timeout_maxidle) { - reply(501, - "Maximum IDLE time must be between 30 and %d seconds", - timeout_maxidle); - } - else { - timeout_idle = $6; - reply(200, "Maximum IDLE time set to %d seconds", timeout_idle); - } - } - | SITE check_login SP GROUP SP username CRLF - = { -#ifndef NO_PRIVATE - if (log_commands) - syslog(LOG_INFO, "SITE GROUP %s", $6); - if (!restricted_user && $2 && $6) - priv_group($6); - free($6); -#endif /* !NO_PRIVATE */ - } - | SITE check_login SP GPASS SP password CRLF - = { -#ifndef NO_PRIVATE - if (log_commands) - syslog(LOG_INFO, "SITE GPASS password"); - if (!restricted_user && $2 && $6) - priv_gpass($6); - free($6); -#endif /* !NO_PRIVATE */ - } - | SITE check_login SP GPASS CRLF - = { -#ifndef NO_PRIVATE - if (log_commands) - syslog(LOG_INFO, "SITE GPASS"); - if (!restricted_user && $2) - priv_gpass(NULL); -#endif /* !NO_PRIVATE */ - } - | SITE check_login SP NEWER SP STRING CRLF - = { - if (log_commands) - syslog(LOG_INFO, "SITE NEWER %s", $6); -#ifdef SITE_NEWER - if ($2 && $6 && !restrict_check(".")) - newer($6, ".", 0); -#else - reply(502, "Command no longer honored by this server"); -#endif - free($6); - } - | SITE check_login SP NEWER SP STRING SP pathname CRLF - = { - if (log_commands) - syslog(LOG_INFO, "SITE NEWER %s %s", $6, - CHECKNULL($8)); -#ifdef SITE_NEWER - if ($2 && $6 && $8 && !restrict_check($8)) - newer($6, $8, 0); -#else - reply(502, "Command no longer honored by this server"); -#endif - free($6); - if ($8) - free($8); - } - | SITE check_login SP MINFO SP STRING CRLF - = { - if (log_commands) - syslog(LOG_INFO, "SITE MINFO %s", $6); -#ifdef SITE_NEWER - if ($2 && $6 && !restrict_check(".")) - newer($6, ".", 1); -#else - reply(502, "Command no longer honored by this server"); -#endif - free($6); - } - | SITE check_login SP MINFO SP STRING SP pathname CRLF - = { - if (log_commands) - syslog(LOG_INFO, "SITE MINFO %s %s", $6, - CHECKNULL($8)); -#ifdef SITE_NEWER - if ($2 && $6 && $8 && !restrict_check($8)) - newer($6, $8, 1); -#else - reply(502, "Command no longer honored by this server"); -#endif - free($6); - if ($8) - free($8); - } - | SITE check_login SP INDEX SP STRING CRLF - = { - /* this is just for backward compatibility since we - * thought of INDEX before we thought of EXEC - */ - if (!restricted_user && $2 != 0 && $6 != NULL) { - char buf[MAXPATHLEN]; - if (strlen($6) + 7 <= sizeof(buf)) { - (void) snprintf(buf, sizeof(buf), "index %s", (char *) $6); - (void) site_exec(buf); - } - } - if ($6 != NULL) - free($6); - } - | SITE check_login SP EXEC SP STRING CRLF - = { - if (!restricted_user && $2 != 0 && $6 != NULL) { - (void) site_exec((char *) $6); - } - if ($6 != NULL) - free($6); - } - - | STOU check_login - = { - char *default_filename = "ftp"; - if (log_commands) - syslog(LOG_INFO, "STOU"); - if ($2 && !restrict_check(default_filename)) - store(default_filename, "w", 1); - } - | STOU check_login SP pathname CRLF - = { - if (log_commands) - syslog(LOG_INFO, "STOU %s", CHECKNULL($4)); - if ($2 && $4 && !restrict_check($4)) - store($4, "w", 1); - if ($4 != NULL) - free($4); - } - | SYST check_login CRLF - = { - if (log_commands) - syslog(LOG_INFO, "SYST"); - if ($2) -#ifdef BSD - reply(215, "UNIX Type: L%d Version: BSD-%d", NBBY, BSD); -#elif defined(SOLARIS_2) - reply(215, "UNIX Type: L%d Version: SUNOS", NBBY); -#elif defined(unix) || defined(__unix__) - reply(215, "UNIX Type: L%d", NBBY); -#else - reply(215, "UNKNOWN Type: L%d", NBBY); -#endif /* BSD */ - } - - /* - * SIZE is not in RFC959, but Postel has blessed it and - * it will be in the updated RFC. - * - * Return size of file in a format suitable for - * using with RESTART (we just count bytes). - */ - | SIZE check_login SP pathname CRLF - = { - if (log_commands) - syslog(LOG_INFO, "SIZE %s", CHECKNULL($4)); - if ($2 && $4 && !restrict_check($4)) { - sizecmd($4); - } - if ($4 != NULL) - free($4); - } - - /* - * MDTM is not in RFC959, but Postel has blessed it and - * it will be in the updated RFC. - * - * Return modification time of file as an ISO 3307 - * style time. E.g. YYYYMMDDHHMMSS or YYYYMMDDHHMMSS.xxx - * where xxx is the fractional second (of any precision, - * not necessarily 3 digits) - */ - | MDTM check_login SP pathname CRLF - = { - if (log_commands) - syslog(LOG_INFO, "MDTM %s", CHECKNULL($4)); - if ($2 && $4 && !restrict_check($4)) { - struct stat stbuf; - - if (stat($4, &stbuf) < 0) - perror_reply(550, $4); - else if ((stbuf.st_mode & S_IFMT) != S_IFREG) { - reply(550, "%s: not a plain file.", - $4); - } - else { - register struct tm *t; - t = gmtime(&stbuf.st_mtime); - reply(213, - "%04d%02d%02d%02d%02d%02d", - t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, - t->tm_hour, t->tm_min, t->tm_sec); - } - } - if ($4 != NULL) - free($4); - } - | QUIT CRLF - = { - if (log_commands) - syslog(LOG_INFO, "QUIT"); -#ifdef TRANSFER_COUNT - if (logged_in) { - lreply(221, "You have transferred %" L_FORMAT " bytes in %d files.", data_count_total, file_count_total); - lreply(221, "Total traffic for this session was %" L_FORMAT " bytes in %d transfers.", byte_count_total, xfer_count_total); - lreply(221, "Thank you for using the FTP service on %s.", hostname); - } -#endif /* TRANSFER_COUNT */ - reply(221, "Goodbye."); - dologout(0); - } - | error CRLF - = { - yyerrok; - } - ; - -rcmd: RNFR check_login SP pathname CRLF - = { - - if (log_commands) - syslog(LOG_INFO, "RNFR %s", CHECKNULL($4)); - if ($2) - restart_point = 0; - if (fromname) { - free(fromname); - fromname = NULL; - } - if ($2 && $4 && !restrict_check($4)) { - fromname = renamefrom($4); - } - if (fromname == NULL && $4) - free($4); - } - | REST check_login SP STRING CRLF - = { - if (log_commands) - syslog(LOG_INFO, "REST %s", CHECKNULL($4)); - if ($2 && $4 != NULL) { - char *endp; - - if (fromname) { - free(fromname); - fromname = NULL; - } - errno = 0; -#if _FILE_OFFSET_BITS == 64 - restart_point = strtoll($4, &endp, 10); -#else - restart_point = strtol($4, &endp, 10); -#endif - if ((errno == 0) && (restart_point >= 0) && (*endp == '\0')) { - reply(350, "Restarting at %" L_FORMAT - ". Send STORE or RETRIEVE to initiate transfer.", - restart_point); - } - else { - restart_point = 0; - reply(501, "Bad value for REST: %s", $4); - } - } - if ($4 != NULL) - free($4); - } - - | SITE check_login SP ALIAS CRLF - = { - if (log_commands) - syslog(LOG_INFO, "SITE ALIAS"); - if ($2) - alias((char *) NULL); - } - | SITE check_login SP ALIAS SP STRING CRLF - = { - if (log_commands) - syslog(LOG_INFO, "SITE ALIAS %s", $6); - if ($2) - alias($6); - if ($6 != NULL) - free($6); - } - | SITE check_login SP GROUPS CRLF - = { - if (log_commands) - syslog(LOG_INFO, "SITE GROUPS"); - if ($2) - print_groups(); - } - | SITE check_login SP CDPATH CRLF - = { - if (log_commands) - syslog(LOG_INFO, "SITE CDPATH"); - if ($2) - cdpath(); - } - | SITE check_login SP CHECKMETHOD SP method CRLF - = { - if (log_commands) - syslog(LOG_INFO, "SITE CHECKMETHOD %s", CHECKNULL($6)); - if (($2) && ($6 != NULL)) - SetCheckMethod($6); - if ($6 != NULL) - free($6); - } - | SITE check_login SP CHECKMETHOD CRLF - = { - if (log_commands) - syslog(LOG_INFO, "SITE CHECKMETHOD"); - if ($2) - ShowCheckMethod(); - } - | SITE check_login SP CHECKSUM SP pathname CRLF - = { - if (log_commands) - syslog(LOG_INFO, "SITE CHECKSUM %s", CHECKNULL($6)); - if (($2) && ($6 != NULL) && (!restrict_check($6))) - CheckSum($6); - if ($6 != NULL) - free($6); - } - | SITE check_login SP CHECKSUM CRLF - = { - if (log_commands) - syslog(LOG_INFO, "SITE CHECKSUM"); - if ($2) - CheckSumLastFile(); - } - | PBSZ SP STRING CRLF - = { -#if defined(USE_TLS) || defined(USE_GSS) - if (log_commands) - syslog(LOG_INFO, "PBSZ %s", $3); - { - int sz = 0; -#if defined(USE_GSS) - sz = gss_setpbsz((char *)$3); -#else - reply(200, "PBSZ=%d", sz); -#endif /* defined(USE_GSS) */ - pbsz_command_issued = 1; - } -#endif /* defined(USE_TLS) || defined(USE_GSS) */ - if ($3 != NULL) - free((char *)$3); - } - | AUTH SP STRING CRLF - = { -#if defined(USE_TLS) || defined(USE_GSS) - register char *cp = (char *) $3; - if (log_commands) - syslog(LOG_INFO, "AUTH %s", $3); - /* convert to UPPER case as per RFC 2228 */ - while (*cp) { - *cp = toupper(*cp); - cp++; - } -#if defined(USE_GSS) - if (!strcmp((char *) $3, "GSSAPI")) { - if (cur_auth_type != NULL) { - reply(534, "Authentication type already set to %s", - cur_auth_type); - syslog(LOG_ERR, "Rejecting duplicate AUTH command"); - } else { - cur_auth_type = strdup((char *)$3); - reply(334, "Using AUTH type %s; ADAT must follow", - cur_auth_type); - } - } else -#endif /* defined(USE_GSS) */ - { - /* - * Previous auth_type did not work, clear the string. - */ - if (cur_auth_type != NULL) { - free(cur_auth_type); - cur_auth_type = NULL; - } - reply(504,"AUTH %s not supported.", $3); - } -#endif /* !(defined(USE_TLS)) && !defined(USE_GSS) */ - if ($3 != NULL) - free((char *)$3); - } - | PROT SP prot_code CRLF - = { -#if defined(USE_TLS) || defined(USE_GSS) - if (log_commands) - syslog(LOG_INFO, "PROT %s", protnames[$3]); - { - if (!pbsz_command_issued) { - reply(503, "PROT command not valid before PBSZ."); - } else { - switch ($3) { - case PROT_P: - reply(200, "PROT P ok."); -#if defined(USE_GSS) - gss_info.data_prot = PROT_P; -#endif /* defined(USE_GSS) */ - break; - case PROT_C: - reply(200, "PROT C ok."); -#if defined(USE_GSS) - gss_info.data_prot = PROT_C; -#endif /* defined(USE_GSS) */ - break; - case PROT_E: - reply(536, "PROT E unsupported"); - break; - case PROT_S: -#if defined(USE_GSS) - reply(200, "PROT S ok."); - gss_info.data_prot = PROT_S; -#endif /* defined(USE_GSS) */ - break; - default: - reply(504, "Invalid PROT type."); - } -#if defined(USE_GSS) - gss_adjust_buflen(); -#endif /* defined(USE_GSS) */ - } - } -#endif /* !(defined(USE_TLS) && !defined(USE_GSS)) */ - } - | ADAT SP STRING CRLF - = { -#if defined(USE_GSS) - if (log_commands) - syslog(LOG_INFO, "ADAT %s", $3); - if (cur_auth_type == NULL || strcmp(cur_auth_type, "GSSAPI")) { - reply(503, "Must identify AUTH GSSAPI before sending ADAT"); - } else - (void) gss_adat((char *)$3); -#endif - if ($3 != NULL) - free((char *)$3); - } - | CCC CRLF - = { -#if defined(USE_GSS) - if (log_commands) - syslog(LOG_INFO, "CCC"); - ccc(); -#endif /* defined(USE_GSS) */ - } - ; - -username: STRING - ; - -password: /* empty */ - = { - $$ = (char *) malloc(1); - $$[0] = '\0'; - } - | STRING - ; - -byte_size: NUMBER - ; - -host_port: NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER - = { - register char *a, *p; - - a = (char *) &cliaddr; - a[0] = $1; - a[1] = $3; - a[2] = $5; - a[3] = $7; - p = (char *) &cliport; - p[0] = $9; - p[1] = $11; - } - ; - -host_lport: NUMBER COMMA NUMBER COMMA - NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA - NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA - NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA - NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA - NUMBER COMMA NUMBER COMMA NUMBER - = { -#ifdef INET6 - char *a, *p; - struct sockaddr_in6 *data_dest_sin6; - - lport_error = 0; - if (epsv_all) { - reply(501, "LPRT not allowed after EPSV ALL"); - lport_error = 1; - goto lport_done6; - } - if ($1 != 6) { - reply(521, "Supported address families are (4, 6)"); - lport_error = 1; - goto lport_done6; - } - if (($3 != 16) || ($37 != 2)) { - reply(501, "Bad length."); - lport_error = 1; - goto lport_done6; - } - memset(&data_dest, 0, sizeof(struct sockaddr_in6)); - data_dest_sin6 = (struct sockaddr_in6 *) &data_dest; - data_dest_sin6->sin6_family = AF_INET6; - a = (char *)&data_dest_sin6->sin6_addr; - a[0] = $5; a[1] = $7; a[2] = $9; a[3] = $11; - a[4] = $13; a[5] = $15; a[6] = $17; a[7] = $19; - a[8] = $21; a[9] = $23; a[10] = $25; a[11] = $27; - a[12] = $29; a[13] = $31; a[14] = $33; a[15] = $35; - p = (char *)&data_dest_sin6->sin6_port; - p[0] = $39; p[1] = $41; -lport_done6:; -#endif /* INET6 */ - } - | NUMBER COMMA NUMBER COMMA - NUMBER COMMA NUMBER COMMA NUMBER COMMA NUMBER COMMA - NUMBER COMMA NUMBER COMMA NUMBER - = { -#ifdef INET6 - char *a, *p; - struct sockaddr_in *data_dest_sin; - - lport_error = 0; - if (epsv_all) { - reply(501, "LPRT not allowed after EPSV ALL"); - lport_error = 1; - goto lport_done4; - } - if ($1 != 4) { - reply(521, "Supported address families are (4, 6)"); - lport_error = 1; - goto lport_done4; - } - if (($3 != 4) || ($13 != 2)) { - reply(501, "Bad length."); - lport_error = 1; - goto lport_done4; - } - data_dest_sin = (struct sockaddr_in *) &data_dest; - data_dest_sin->sin_family = AF_INET; - a = (char *)&data_dest_sin->sin_addr; - a[0] = $5; a[1] = $7; a[2] = $9; a[3] = $11; - p = (char *)&data_dest_sin->sin_port; - p[0] = $15; p[1] = $17; -lport_done4:; -#endif /* INET6 */ - } - ; - -form_code: N - = { - $$ = FORM_N; - } - | T - = { - $$ = FORM_T; - } - | C - = { - $$ = FORM_C; - } - ; - -type_code: A - = { - cmd_type = TYPE_A; - cmd_form = FORM_N; - } - | A SP form_code - = { - cmd_type = TYPE_A; - cmd_form = $3; - } - | E - = { - cmd_type = TYPE_E; - cmd_form = FORM_N; - } - | E SP form_code - = { - cmd_type = TYPE_E; - cmd_form = $3; - } - | I - = { - cmd_type = TYPE_I; - } - | L - = { - cmd_type = TYPE_L; - cmd_bytesz = NBBY; - } - | L SP byte_size - = { - cmd_type = TYPE_L; - cmd_bytesz = $3; - } - /* this is for a bug in the BBN ftp */ - | L byte_size - = { - cmd_type = TYPE_L; - cmd_bytesz = $2; - } - ; - -prot_code: C - = { -#if defined(USE_GSS) - $$ = PROT_C; -#endif - } - | P - = { -#if defined(USE_GSS) - $$ = PROT_P; -#endif - } - | S - = { -#if defined(USE_GSS) - $$ = PROT_S; -#endif - } - | E - = { -#if defined(USE_GSS) - $$ = PROT_E; -#endif - } - ; - -struct_code: F - = { - $$ = STRU_F; - } - | R - = { - $$ = STRU_R; - } - | P - = { - $$ = STRU_P; - } - ; - -mode_code: S - = { - $$ = MODE_S; - } - | B - = { - $$ = MODE_B; - } - | C - = { - $$ = MODE_C; - } - ; - -pathname: pathstring - = { - /* - * Problem: this production is used for all pathname - * processing, but only gives a 550 error reply. - * This is a valid reply in some cases but not in others. - */ - if (restricted_user && logged_in && $1 && strncmp($1, "/", 1) == 0) { - /* - * This remaps the root so it is appearently at the user's home - * rather than the real root/chroot. - */ - size_t len = strlen($1) + 2; - char **globlist; - char *t = calloc(len, sizeof(char)); - if (t == NULL) { - errno = EAGAIN; - perror_reply(550, $1); - $$ = NULL; - } - else { - t[0] = '~'; - t[1] = '\0'; - if (strncmp($1, "/../", 4) == 0) - (void) strlcat(t, $1 + 3, len); - else if (strcmp($1, "/..") != 0) - (void) strlcat(t, $1, len); - globlist = ftpglob(t, B_TRUE); - if (globerr) { - reply(550, "%s", globerr); - $$ = NULL; - if (globlist) { - blkfree(globlist); - free((char *) globlist); - } - } - else if (globlist && *globlist) { - $$ = *globlist; - blkfree(&globlist[1]); - free((char *) globlist); - } - else { - if (globlist) { - blkfree(globlist); - free((char *) globlist); - } - errno = ENOENT; - perror_reply(550, $1); - $$ = NULL; - } - free(t); - } - free($1); - } - else if (logged_in && $1 && strncmp($1, "~", 1) == 0) { - char **globlist; - - globlist = ftpglob($1, B_TRUE); - if (globerr) { - reply(550, "%s", globerr); - $$ = NULL; - if (globlist) { - blkfree(globlist); - free((char *) globlist); - } - } - else if (globlist && *globlist) { - $$ = *globlist; - blkfree(&globlist[1]); - free((char *) globlist); - } - else { - if (globlist) { - blkfree(globlist); - free((char *) globlist); - } - errno = ENOENT; - perror_reply(550, $1); - $$ = NULL; - } - free($1); - } - else - $$ = $1; - } - ; - -pathstring: STRING - ; - -method: STRING - ; - -octal_number: NUMBER - = { - register int ret, dec, multby, digit; - - /* - * Convert a number that was read as decimal number - * to what it would be if it had been read as octal. - */ - dec = $1; - multby = 1; - ret = 0; - while (dec) { - digit = dec % 10; - if (digit > 7) { - ret = -1; - break; - } - ret += digit * multby; - multby *= 8; - dec /= 10; - } - $$ = ret; - } - ; - -check_login: /* empty */ - = { - if (logged_in) - $$ = 1; - else { - if (log_commands) - syslog(LOG_INFO, "cmd failure - not logged in"); - reply(530, "Please login with USER and PASS."); - $$ = 0; - yyerrorcalled = 1; - } - } - ; - -%% - -extern jmp_buf errcatch; - -#define CMD 0 /* beginning of command */ -#define ARGS 1 /* expect miscellaneous arguments */ -#define STR1 2 /* expect SP followed by STRING */ -#define STR2 3 /* expect STRING */ -#define OSTR 4 /* optional SP then STRING */ -#define ZSTR1 5 /* SP then optional STRING */ -#define ZSTR2 6 /* optional STRING after SP */ -#define SITECMD 7 /* SITE command */ -#define NSTR 8 /* Number followed by a string */ -#define STR3 9 /* expect STRING followed by optional SP then STRING */ - -struct tab cmdtab[] = -{ /* In order defined in RFC 765 */ - {"USER", USER, STR1, 1, " username"}, - {"PASS", PASS, ZSTR1, 1, " password"}, - {"ACCT", ACCT, STR1, 0, "(specify account)"}, - {"SMNT", SMNT, ARGS, 0, "(structure mount)"}, - {"REIN", REIN, ARGS, 0, "(reinitialize server state)"}, - {"QUIT", QUIT, ARGS, 1, "(terminate service)",}, - {"PORT", PORT, ARGS, 1, " h1, h2, h3, h4, p1, p2"}, - {"PASV", PASV, ARGS, 1, "(set server in passive mode)"}, -#ifdef INET6 - {"EPRT", EPRT, STR1, 1, " |af|addr|port|"}, - {"EPSV", EPSV, OSTR, 1, "[ af|ALL]"}, - {"LPRT", LPRT, ARGS, 1, " af, hal, h1, h2, ..., pal, p1, p2, ..."}, - {"LPSV", LPSV, ARGS, 1, "(set server in long passive mode)"}, -#endif - {"TYPE", TYPE, ARGS, 1, " [ A | E | I | L ]"}, - {"STRU", STRU, ARGS, 1, "(specify file structure)"}, - {"MODE", MODE, ARGS, 1, "(specify transfer mode)"}, - {"RETR", RETR, STR1, 1, " file-name"}, - {"STOR", STOR, STR1, 1, " file-name"}, - {"APPE", APPE, STR1, 1, " file-name"}, - {"MLFL", MLFL, OSTR, 0, "(mail file)"}, - {"MAIL", MAIL, OSTR, 0, "(mail to user)"}, - {"MSND", MSND, OSTR, 0, "(mail send to terminal)"}, - {"MSOM", MSOM, OSTR, 0, "(mail send to terminal or mailbox)"}, - {"MSAM", MSAM, OSTR, 0, "(mail send to terminal and mailbox)"}, - {"MRSQ", MRSQ, OSTR, 0, "(mail recipient scheme question)"}, - {"MRCP", MRCP, STR1, 0, "(mail recipient)"}, - {"ALLO", ALLO, ARGS, 1, "allocate storage (vacuously)"}, - {"REST", REST, STR1, 1, "(restart command)"}, - {"RNFR", RNFR, STR1, 1, " file-name"}, - {"RNTO", RNTO, STR1, 1, " file-name"}, - {"ABOR", ABOR, ARGS, 1, "(abort operation)"}, - {"DELE", DELE, STR1, 1, " file-name"}, - {"CWD", CWD, OSTR, 1, "[ directory-name ]"}, - {"XCWD", CWD, OSTR, 1, "[ directory-name ]"}, - {"LIST", LIST, OSTR, 1, "[ path-name ]"}, - {"NLST", NLST, OSTR, 1, "[ path-name ]"}, - {"SITE", SITE, SITECMD, 1, "site-cmd [ arguments ]"}, - {"SYST", SYST, ARGS, 1, "(get type of operating system)"}, - {"STAT", STAT, OSTR, 1, "[ path-name ]"}, - {"HELP", HELP, OSTR, 1, "[ ]"}, - {"NOOP", NOOP, ARGS, 1, ""}, - {"MKD", MKD, STR1, 1, " path-name"}, - {"XMKD", MKD, STR1, 1, " path-name"}, - {"RMD", RMD, STR1, 1, " path-name"}, - {"XRMD", RMD, STR1, 1, " path-name"}, - {"PWD", PWD, ARGS, 1, "(return current directory)"}, - {"XPWD", PWD, ARGS, 1, "(return current directory)"}, - {"CDUP", CDUP, ARGS, 1, "(change to parent directory)"}, - {"XCUP", CDUP, ARGS, 1, "(change to parent directory)"}, - {"STOU", STOU, OSTR, 1, "[ file-name ]"}, - {"SIZE", SIZE, OSTR, 1, " path-name"}, - {"MDTM", MDTM, OSTR, 1, " path-name"}, -#if defined(USE_TLS) || defined(USE_GSS) - {"PROT", PROT, ARGS, 1, " protection-level"}, - {"PBSZ", PBSZ, STR1, 1, " protection-buffer-size"}, - {"AUTH", AUTH, STR1, 1, " authentication-mechanism"}, - {"ADAT", ADAT, STR1, 1, " authentication-data"}, -#if defined(USE_GSS) - {"CCC", CCC, ARGS, 1, "(clear command channel)"}, -#endif -#endif /* defined(USE_TLS) || defined(USE_GSS) */ - {NULL, 0, 0, 0, 0} -}; - -struct tab sitetab[] = -{ - {"UMASK", UMASK, ARGS, 1, "[ umask ]"}, - {"IDLE", IDLE, ARGS, 1, "[ maximum-idle-time ]"}, - {"CHMOD", CHMOD, NSTR, 1, " mode file-name"}, - {"HELP", HELP, OSTR, 1, "[ ]"}, - {"GROUP", GROUP, STR1, 1, " access-group"}, - {"GPASS", GPASS, OSTR, 1, " access-password"}, - {"NEWER", NEWER, STR3, 1, " YYYYMMDDHHMMSS [ path-name ]"}, - {"MINFO", MINFO, STR3, 1, " YYYYMMDDHHMMSS [ path-name ]"}, - {"INDEX", INDEX, STR1, 1, " pattern"}, - {"EXEC", EXEC, STR1, 1, " command [ arguments ]"}, - {"ALIAS", ALIAS, OSTR, 1, "[ alias ] "}, - {"CDPATH", CDPATH, OSTR, 1, "[ ] "}, - {"GROUPS", GROUPS, OSTR, 1, "[ ] "}, - {"CHECKMETHOD", CHECKMETHOD, OSTR, 1, "[ crc|md5 ]"}, - {"CHECKSUM", CHECKSUM, OSTR, 1, "[ file-name ]"}, - {NULL, 0, 0, 0, 0} -}; - -struct tab *lookup(register struct tab *p, char *cmd) -{ - for (; p->name != NULL; p++) - if (strcmp(cmd, p->name) == 0) - return (p); - return (0); -} - -#include - -/* - * getline - a hacked up version of fgets to ignore TELNET escape codes. - */ -char *wu_getline(char *s, int n, register FILE *iop) -{ - register int c; - register char *cs; - char *passtxt = "PASS password\r\n"; - - cs = s; -/* tmpline may contain saved command from urgent mode interruption */ - for (c = 0; tmpline[c] != '\0' && --n > 0; ++c) { - *cs++ = tmpline[c]; - if (tmpline[c] == '\n') { - *cs++ = '\0'; - if (debug) { - if (strncasecmp(passtxt, s, 5) == 0) - syslog(LOG_DEBUG, "command: %s", passtxt); - else - syslog(LOG_DEBUG, "command: %s", s); - } - tmpline[0] = '\0'; - return (s); - } - if (c == 0) - tmpline[0] = '\0'; - } - retry: - while ((c = getc(iop)) != EOF) { -#ifdef TRANSFER_COUNT - byte_count_total++; - byte_count_in++; -#endif - c &= 0377; - if (c == IAC) { - if ((c = getc(iop)) != EOF) { -#ifdef TRANSFER_COUNT - byte_count_total++; - byte_count_in++; -#endif - c &= 0377; - switch (c) { - case WILL: - case WONT: - c = getc(iop); -#ifdef TRANSFER_COUNT - byte_count_total++; - byte_count_in++; -#endif - printf("%c%c%c", IAC, DONT, 0377 & c); - (void) fflush(stdout); - continue; - case DO: - case DONT: - c = getc(iop); -#ifdef TRANSFER_COUNT - byte_count_total++; - byte_count_in++; -#endif - printf("%c%c%c", IAC, WONT, 0377 & c); - (void) fflush(stdout); - continue; - case IAC: - break; - default: - continue; /* ignore command */ - } - } - } - *cs++ = c; - if (--n <= 0) { - /* If command does not fit to buffer then discard the rest. */ - while (c != '\n' && (c = getc(iop)) != EOF) - ; - reply(500, "Command too long"); - break; - } - if (c == '\n') - break; - } - - if (c == EOF && cs == s) { - if (ferror(iop) && (errno == EINTR)) - goto retry; - return (NULL); - } - - *cs++ = '\0'; - -#if defined(USE_GSS) - if (IS_GSSAUTH(cur_auth_type) && - (gss_info.authstate & GSS_ADAT_DONE) && - gss_info.context != GSS_C_NO_CONTEXT) { - s = sec_decode_command(s); - } else if (IS_GSSAUTH(cur_auth_type) && - (!strncmp(s, "ENC", 3) || !strncmp(s, "MIC", 3) || - !strncmp(s, "CONF", 4)) && - !(gss_info.authstate & GSS_ADAT_DONE)) { - if (debug) - syslog(LOG_DEBUG, "command: %s", s); - reply(503, "Must perform authentication before sending protected commands"); - *s = '\0'; - return(s); - } -#endif /* USE_GSS */ - if (debug) { - if (strncasecmp(passtxt, s, 5) == 0) - syslog(LOG_DEBUG, "command: %s", passtxt); - else - syslog(LOG_DEBUG, "command: %s", s); - } - return (s); -} - -static void toolong(int a) /* signal that caused this function to be called */ -{ - time_t now; - - reply(421, - "Timeout (%d seconds): closing control connection.", timeout_idle); - (void) time(&now); - if (logging) { - syslog(LOG_INFO, - "User %s timed out after %d seconds at %.24s", - (pw ? pw->pw_name : "unknown"), timeout_idle, ctime(&now)); - } - dologout(1); -} - -int yylex(void) -{ - static int cpos, state; - register char *cp, *cp2; - register struct tab *p; - int n; - time_t now; - char c = '\0'; - extern time_t limit_time; - extern time_t login_time; - - for (;;) { - switch (state) { - - case CMD: - yyerrorcalled = 0; - - setproctitle("%s: IDLE", proctitle); - - if (is_shutdown(!logged_in, 0) != 0) { - reply(221, "Server shutting down. Goodbye."); - dologout(0); - } - - time(&now); - if ((limit_time > 0) && (((now - login_time) / 60) >= limit_time)) { - reply(221, "Time limit reached. Goodbye."); - dologout(0); - } - -#ifdef IGNORE_NOOP - if (!alarm_running) { - (void) signal(SIGALRM, toolong); - (void) alarm((unsigned) timeout_idle); - alarm_running = 1; - } -#else - (void) signal(SIGALRM, toolong); - (void) alarm((unsigned) timeout_idle); -#endif - if (wu_getline(cbuf, sizeof(cbuf) - 1, stdin) == NULL) { - (void) alarm(0); - reply(221, "You could at least say goodbye."); - dologout(0); - } -#ifndef IGNORE_NOOP - (void) alarm(0); -#endif - if ((cp = strchr(cbuf, '\r'))) { - *cp++ = '\n'; - *cp = '\0'; - } - if ((cp = strpbrk(cbuf, " \n"))) - cpos = cp - cbuf; - if (cpos == 0) - cpos = 4; - c = cbuf[cpos]; - cbuf[cpos] = '\0'; - upper(cbuf); -#ifdef IGNORE_NOOP - if (strncasecmp(cbuf, "NOOP", 4) != 0) { - (void) alarm(0); - alarm_running = 0; - } -#endif - p = lookup(cmdtab, cbuf); - cbuf[cpos] = c; - if (strncasecmp(cbuf, "PASS", 4) != 0 && - strncasecmp(cbuf, "SITE GPASS", 10) != 0) { - if ((cp = strchr(cbuf, '\n'))) - *cp = '\0'; - setproctitle("%s: %s", proctitle, cbuf); - if (cp) - *cp = '\n'; - } - if (p != 0) { - if (p->implemented == 0) { - nack(p->name); - longjmp(errcatch, 0); - /* NOTREACHED */ - } - state = p->state; - yylval.String = p->name; - return (p->token); - } - break; - - case SITECMD: - if (cbuf[cpos] == ' ') { - cpos++; - return (SP); - } - cp = &cbuf[cpos]; - if ((cp2 = strpbrk(cp, " \n"))) - cpos = cp2 - cbuf; - c = cbuf[cpos]; - cbuf[cpos] = '\0'; - upper(cp); - p = lookup(sitetab, cp); - cbuf[cpos] = c; - if (p != 0) { -#ifndef PARANOID /* what GOOD is SITE *, anyways?! _H */ - if (p->implemented == 0) { -#else - if (1) { - syslog(LOG_WARNING, "refused SITE %s %s from %s of %s", - p->name, &cbuf[cpos], - anonymous ? guestpw : authuser, remoteident); -#endif /* PARANOID */ - state = CMD; - nack(p->name); - longjmp(errcatch, 0); - /* NOTREACHED */ - } - state = p->state; - yylval.String = p->name; - return (p->token); - } - state = CMD; - break; - - case OSTR: - if (cbuf[cpos] == '\n') { - state = CMD; - return (CRLF); - } - /* FALLTHROUGH */ - - case STR1: - case ZSTR1: - dostr1: - if (cbuf[cpos] == ' ') { - cpos++; - if (state == OSTR) - state = STR2; - else - ++state; - return (SP); - } - break; - - case ZSTR2: - if (cbuf[cpos] == '\n') { - state = CMD; - return (CRLF); - } - /* FALLTHROUGH */ - - case STR2: - cp = &cbuf[cpos]; - n = strlen(cp); - cpos += n - 1; - /* - * Make sure the string is nonempty and \n terminated. - */ - if (n > 1 && cbuf[cpos] == '\n') { - cbuf[cpos] = '\0'; - yylval.String = copy(cp); - cbuf[cpos] = '\n'; - state = ARGS; - return (STRING); - } - break; - - case NSTR: - if (cbuf[cpos] == ' ') { - cpos++; - return (SP); - } - if (isdigit(cbuf[cpos])) { - cp = &cbuf[cpos]; - while (isdigit(cbuf[++cpos])); - c = cbuf[cpos]; - cbuf[cpos] = '\0'; - yylval.Number = atoi(cp); - cbuf[cpos] = c; - state = STR1; - return (NUMBER); - } - state = STR1; - goto dostr1; - - case STR3: - if (cbuf[cpos] == ' ') { - cpos++; - return (SP); - } - - cp = &cbuf[cpos]; - cp2 = strpbrk(cp, " \n"); - if (cp2 != NULL) { - c = *cp2; - *cp2 = '\0'; - } - n = strlen(cp); - cpos += n; - /* - * Make sure the string is nonempty and SP terminated. - */ - if ((cp2 - cp) > 1) { - yylval.String = copy(cp); - cbuf[cpos] = c; - state = OSTR; - return (STRING); - } - break; - - case ARGS: - if (isdigit(cbuf[cpos])) { - cp = &cbuf[cpos]; - while (isdigit(cbuf[++cpos])); - c = cbuf[cpos]; - cbuf[cpos] = '\0'; - yylval.Number = atoi(cp); - cbuf[cpos] = c; - return (NUMBER); - } - switch (cbuf[cpos++]) { - - case '\n': - state = CMD; - return (CRLF); - - case ' ': - return (SP); - - case ',': - return (COMMA); - - case 'A': - case 'a': - return (A); - - case 'B': - case 'b': - return (B); - - case 'C': - case 'c': - return (C); - - case 'E': - case 'e': - return (E); - - case 'F': - case 'f': - return (F); - - case 'I': - case 'i': - return (I); - - case 'L': - case 'l': - return (L); - - case 'N': - case 'n': - return (N); - - case 'P': - case 'p': - return (P); - - case 'R': - case 'r': - return (R); - - case 'S': - case 's': - return (S); - - case 'T': - case 't': - return (T); - - } - break; - - default: - fatal("Unknown state in scanner."); - } - if (yyerrorcalled == 0) { - if ((cp = strchr(cbuf, '\n')) != NULL) - *cp = '\0'; - if (logged_in) - reply(500, "'%s': command not understood.", cbuf); - else - reply(530, "Please login with USER and PASS."); - } - state = CMD; - longjmp(errcatch, 0); - } -} - -void upper(char *s) -{ - while (*s != '\0') { - if (islower(*s)) - *s = toupper(*s); - s++; - } -} - -char *copy(char *s) -{ - char *p; - - p = strdup(s); - if (p == NULL) - fatal("Ran out of memory."); - return (p); -} - -void help(struct tab *ctab, char *s) -{ - struct aclmember *entry = NULL; - struct tab *c; - size_t width, NCMDS; - char *type; - - if (ctab == sitetab) - type = "SITE "; - else - type = ""; - width = 0, NCMDS = 0; - for (c = ctab; c->name != NULL; c++) { - size_t len = strlen(c->name); - - if (len > width) - width = len; - NCMDS++; - } - width = (width + 8) & ~7; - if (s == 0) { - register size_t i, j, w; - size_t columns, lines; - - lreply(214, "The following %scommands are recognized %s.", - type, "(* =>'s unimplemented)"); - columns = 76 / width; - if (columns == 0) - columns = 1; - lines = (NCMDS + columns - 1) / columns; - for (i = 0; i < lines; i++) { - char line[BUFSIZ], *ptr = line; - ptr += strlcpy(line, " ", sizeof(line)); - for (j = 0; j < columns; j++) { - c = ctab + j * lines + i; - (void) snprintf(ptr, line + sizeof(line) - ptr, "%s%c", - c->name, c->implemented ? ' ' : '*'); - w = strlen(c->name) + 1; - ptr += w; - if (c + lines >= &ctab[NCMDS]) - break; - while (w < width) { - *(ptr++) = ' '; - w++; - } - } - *ptr = '\0'; - lreply(0, "%s", line); - } - (void) fflush(stdout); -#ifdef VIRTUAL - if (virtual_mode && !virtual_ftpaccess && virtual_email[0] != '\0') - reply(214, "Direct comments to %s.", virtual_email); - else -#endif - if ((getaclentry("email", &entry)) && ARG0) - reply(214, "Direct comments to %s.", ARG0); - else - reply(214, "Direct comments to ftp-bugs@%s.", hostname); - return; - } - upper(s); - c = lookup(ctab, s); - if (c == (struct tab *) NULL) { - reply(502, "Unknown command %s.", s); - return; - } - if (c->implemented) - reply(214, "Syntax: %s%s %s", type, c->name, c->help); - else - reply(214, "%s%-*s\t%s; unimplemented.", type, width, - c->name, c->help); -} - -void sizecmd(char *filename) -{ - switch (type) { - case TYPE_L: - case TYPE_I:{ - struct stat stbuf; - if (stat(filename, &stbuf) < 0 || - (stbuf.st_mode & S_IFMT) != S_IFREG) - reply(550, "%s: not a plain file.", filename); - else - reply(213, "%" L_FORMAT, stbuf.st_size); - break; - } - case TYPE_A:{ - FILE *fin; - register int c; - register off_t count; - struct stat stbuf; - fin = fopen(filename, "r"); - if (fin == NULL) { - perror_reply(550, filename); - return; - } - if (fstat(fileno(fin), &stbuf) < 0 || - (stbuf.st_mode & S_IFMT) != S_IFREG) { - reply(550, "%s: not a plain file.", filename); - (void) fclose(fin); - return; - } - - count = 0; - while ((c = getc(fin)) != EOF) { - if (c == '\n') /* will get expanded to \r\n */ - count++; - count++; - } - (void) fclose(fin); - - reply(213, "%" L_FORMAT, count); - break; - } - default: - reply(504, "SIZE not implemented for Type %c.", "?AEIL"[type]); - } -} - -void site_exec(char *cmd) -{ -#ifdef PARANOID - syslog(LOG_CRIT, "REFUSED SITE_EXEC (slipped through!!): %s", cmd); -#else - char buf[MAXPATHLEN]; - char *sp = (char *) strchr(cmd, ' '), *slash, *t; - FILE *cmdf; - - - /* sanitize the command-string */ - - if (sp == 0) { - while ((slash = strchr(cmd, '/')) != 0) - cmd = slash + 1; - } - else { - while (sp && (slash = (char *) strchr(cmd, '/')) - && (slash < sp)) - cmd = slash + 1; - } - - for (t = cmd; *t && !isspace(*t); t++) { - if (isupper(*t)) { - *t = tolower(*t); - } - } - - /* build the command */ - if (strlen(_PATH_EXECPATH) + strlen(cmd) + 2 > sizeof(buf)) - return; - (void) snprintf(buf, sizeof(buf), "%s/%s", _PATH_EXECPATH, cmd); - - cmdf = ftpd_popen(buf, "r", 0); - if (!cmdf) { - perror_reply(550, cmd); - if (log_commands) - syslog(LOG_INFO, "SITE EXEC (FAIL: %m): %s", cmd); - } - else { - int lines = 0; - int maxlines = 0; - struct aclmember *entry = NULL; - char class[BUFSIZ]; - int maxfound = 0; - int defmaxlines = 20; - int which; - - (void) acl_getclass(class); - while ((getaclentry("site-exec-max-lines", &entry)) && ARG0) { - if (ARG1) - for (which = 1; (which < MAXARGS) && ARG[which]; which++) { - if (!strcasecmp(ARG[which], class)) { - maxlines = atoi(ARG0); - maxfound = 1; - } - if (!strcmp(ARG[which], "*")) - defmaxlines = atoi(ARG0); - } - else - defmaxlines = atoi(ARG0); - } - if (!maxfound) - maxlines = defmaxlines; - lreply(200, "%s", cmd); - while (fgets(buf, sizeof buf, cmdf)) { - size_t len = strlen(buf); - - if (len > 0 && buf[len - 1] == '\n') - buf[--len] = '\0'; - lreply(200, "%s", buf); - if (maxlines <= 0) - ++lines; - else if (++lines >= maxlines) { - lreply(200, "*** Truncated ***"); - break; - } - } - reply(200, " (end of '%s')", cmd); - if (log_commands) - syslog(LOG_INFO, "SITE EXEC (lines: %d): %s", lines, cmd); - ftpd_pclose(cmdf); - } -#endif /* PARANOID */ -} - -void alias(char *s) -{ - struct aclmember *entry = NULL; - - if (s != (char *) NULL) { - while (getaclentry("alias", &entry) && ARG0 && ARG1 != NULL) - if (!strcmp(ARG0, s)) { - reply(214, "%s is an alias for %s.", ARG0, ARG1); - return; - } - reply(502, "Unknown alias %s.", s); - return; - } - - lreply(214, "The following aliases are available."); - - while (getaclentry("alias", &entry) && ARG0 && ARG1 != NULL) - lreply(0, " %-8s %s", ARG0, ARG1); - (void) fflush(stdout); - - reply(214, ""); -} - -void cdpath(void) -{ - struct aclmember *entry = NULL; - - lreply(214, "The cdpath is:"); - while (getaclentry("cdpath", &entry) && ARG0 != NULL) - lreply(0, " %s", ARG0); - (void) fflush(stdout); - reply(214, ""); -} - -void print_groups(void) -{ - gid_t *groups; - int ngroups; - int maxgrp; - - maxgrp = getgroups(0, NULL); - - groups = alloca(maxgrp * sizeof (gid_t)); - - if ((ngroups = getgroups(maxgrp, groups)) < 0) { - return; - } - - lreply(214, "Group membership is:"); - ngroups--; - - for (; ngroups >= 0; ngroups--) - lreply(214, " %d", groups[ngroups]); - - (void) fflush(stdout); - reply(214, ""); -} diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpconfig.sh b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpconfig.sh deleted file mode 100644 index 60fd8b12f0..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpconfig.sh +++ /dev/null @@ -1,394 +0,0 @@ -#!/usr/bin/ksh -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2010 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# -# This script sets up anonymous FTP on the current host. -# -# Usage: -# ftpconfig [ftpdir] -# ftpconfig -d ftpdir -# -# ftpconfig without any arguments updates the files required by anonymous FTP -# in an existing ftp users home directory. -# -# If ftpdir (which must be an absolute pathname) is supplied, ftpconfig -# creates an ftp user account with a home directory of ftpdir, or updates -# an existing ftp user account to have a home directory of ftpdir. -# -# If ftpdir already exists, the files it contains which are required by -# anonymous FTP are updated, otherwise ftpdir is created containing the files -# required by anonymous FTP. -# -# The -d (directory only) option just creates a new or updates an existing -# ftpdir without creating or updating the ftp user account. This is useful -# when creating guest FTP user accounts. -# -# Exit codes: 0 - success -# 1 - usage -# 2 - command failure -# - -usage() -{ - fmt=`gettext "Usage: %s [ftpdir]\n %s -d ftpdir"` - printf "$fmt\n" "$cmd" "$cmd" >&2 - exit 1 -} - -verify_root() -{ - # Verify caller has a real user ID of 0. - set `id` - if [ "$1" != "uid=0(root)" ] - then - fmt=`gettext "%s: Error: Only root can run %s"` - printf "$fmt\n" "$cmd" "$cmd" >&2 - exit 1 - fi -} - -# Make directory $1 under $home_dir with mode $2 and ownership $3. -make_dir() -{ - # Make a special case of creating $home_dir itself - if [ -z "$1" ] - then - dir="$home_dir" - else - dir="$home_dir/$1" - fi - if [ ! -d "$dir" ] - then - mkdir "$dir" || exit 2 - fi - chmod "$2" "$dir" - chown "$3" "$dir" -} - -# Copy file $1 to under $home_dir with mode $2 and ownership $3. -copy_file() -{ - if [ -f "$1" ] - then - file="$home_dir$1" - rm -f "$file" - cp "$1" "$file" || exit 2 - chmod "$2" "$file" - chown "$3" "$file" - fi -} - -add_user() -{ - pwent=`grep "^$username:" /etc/passwd` - if [ -z "$pwent" ] - then - # No existing ftp account. - if [ -z "$home_dir" ] - then - fmt=`gettext "%s: Error: No directory specified and no existing ftp account to update"` - printf "$fmt\n" "$cmd" >&2 - exit 1 - fi - - # Create a new ftp account. - comment="Anonymous FTP" - fmt=`gettext "Creating user %s"` - printf "$fmt\n" "$username" - /usr/sbin/useradd -c "$comment" -d "$home_dir" -s "$login_shell" -g other "$username" || exit 2 - else - # ftp account already exists. - if [ -z "$home_dir" ] - then - home_dir=`echo "$pwent" | cut -d: -f6` - if [ -z "$home_dir" ] - then - fmt=`gettext "%s: Error: Existing ftp account has no home directory"` - printf "$fmt\n" "$cmd" >&2 - exit 2 - fi - else - # Update an existing ftp account. - old_dir=`echo "$pwent" | cut -d: -f6` - if [ "$old_dir" != "$home_dir" ] - then - fmt=`gettext "Updating user %s"` - printf "$fmt\n" "$username" - /usr/sbin/usermod -d "$home_dir" "$username" || exit 2 - fi - fi - fi -} - -list_pam_session() -{ - # Produce a list of the PAM session management modules. - if [ -f /etc/pam.conf ] - then - awk '($1 == "ftp" || $1 == "other") && $2 == "session" { - if ($4 !~ /^\//) printf "/usr/lib/security/" - print $4 - }' /dev/null | cut -d'>' -f2 - done | sort -u -} - -create_home_dir() -{ - if [ "$home_dir" = "/" -o "$home_dir" = "/usr" ] - then - fmt=`gettext "%s: Error: Installing FTP in %s is not permitted"` - printf "$fmt\n" "$cmd" "$home_dir" >&2 - exit 1 - fi - - if [ ! -d "$home_dir" ] - then - if [ -e "$home_dir" ] - then - fmt=`gettext "%s: Error: %s already exists but is not a directory"` - printf "$fmt\n" "$cmd" "$home_dir" >&2 - exit 2 - else - fmt=`gettext "Creating directory %s"` - printf "$fmt\n" "$home_dir" - make_dir "" 755 root:sys - fi - fi -} - -install_slash_etc() -{ - # Preserve an existing etc directory. - make_dir etc 111 root:sys - make_dir etc/ftpd 111 root:sys - - # Create a stripped down password file. - rm -f "$home_dir/etc/passwd" - awk -F: '$1 ~ /^root$|^bin$|^sys$|^ftpadm$|^ftp$/ { print $1":x:"$3":"$4":::" }' "$home_dir/etc/passwd" - chmod 444 "$home_dir/etc/passwd" - chown root:sys "$home_dir/etc/passwd" - - # Create a stripped down group file. - rm -f "$home_dir/etc/group" - awk -F: '$1 ~ /^root$|^other$|^bin$|^sys$|^ftpadm$/ { print $1"::"$3":" }' "$home_dir/etc/group" - chmod 444 "$home_dir/etc/group" - chown root:sys "$home_dir/etc/group" - - # Copy in /etc/default/init, needed for timezone. - if [ -f /etc/default/init ] - then - make_dir etc/default 111 root:sys - copy_file /etc/default/init 444 root:sys - fi - - # Copy in files used for hostname resolution - copy_file /etc/hosts 444 root:sys - copy_file /etc/resolv.conf 444 root:sys - make_dir etc/inet 111 root:sys - copy_file /etc/inet/ipnodes 444 root:sys -} - -install_slash_usr() -{ - # Preserve an existing usr directory. - make_dir usr 111 root:sys - make_dir usr/bin 111 root:bin - - if [ -h "$home_dir/bin" ] - then - rm -f "$home_dir/bin" - fi - if [ ! -e "$home_dir/bin" ] - then - ln -s ./usr/bin "$home_dir/bin" || exit 2 - chown -h root:bin "$home_dir/bin" - fi - - # Copy required dynamic libraries and PAM session management modules. - libs="/lib/nss_files.so.1 /lib/nss_dns.so.1 /lib/libresolv.so.2" - for lib in /lib/ld.so.1 $libs `list_dyn_libs $libs` `list_pam_session` - do - if [ -f "$lib" ] - then - dir=`dirname "$home_dir$lib"` - if [ ! -d "$dir" ] - then - mkdir -p "$dir" || exit 2 - fi - copy_file "$lib" 555 root:bin - fi - done - - # Copy required commands. - for prog in /usr/bin/ls `list_conv_cmds` - do - if [ -f "$prog" ] - then - dir=`dirname "$home_dir$prog"` - if [ ! -d "$dir" ] - then - mkdir -p "$dir" || exit 2 - fi - copy_file "$prog" 111 root:bin - fi - done - - # Copy timezone files. - if [ -d /usr/share/lib/zoneinfo ] - then - rm -rf "$home_dir/usr/share/lib/zoneinfo" - find /usr/share/lib/zoneinfo | cpio -pduL "$home_dir" >/dev/null 2>&1 - (cd "$home_dir/usr/share/lib"; find zoneinfo -type f | - xargs chmod 444) - rm -rf "$home_dir/usr/share/lib/zoneinfo/src" - fi - - for dir in usr lib platform - do - if [ -d "$home_dir/$dir" ] - then - (cd "$home_dir"; find $dir -type d | xargs chmod 111) - (cd "$home_dir"; find $dir -type d | xargs chown root:bin) - [ $dir != "lib" ] && chown root:sys "$home_dir/$dir" - fi - done -} - -install_slash_dev() -{ - # Preserve an existing dev directory. - make_dir dev 111 root:sys - - # Copy devices. - for devname in conslog null udp udp6 zero - do - rm -f "$home_dir/dev/$devname" - done - cpio -pduL "$home_dir" >/dev/null 2>&1 <<-EOF - /dev/conslog - /dev/null - /dev/udp - /dev/udp6 - /dev/zero - EOF - if [ $? -ne 0 ] - then - fmt=`gettext "%s: Error: Creation of devices in %s failed"` - printf "$fmt\n" "$cmd" "$home_dir/dev" >&2 - exit 2 - fi -} - -install_slash_pub() -{ - # Preserve an existing pub directory. - make_dir pub 755 root:sys -} - -update_home_dir() -{ - fmt=`gettext "Updating directory %s"` - printf "$fmt\n" "$home_dir" - install_slash_dev - install_slash_etc - install_slash_usr - install_slash_pub -} - -# Execution starts here. - -IFS=" -" -SHELL=/usr/bin/ksh -PATH=/usr/bin -TEXTDOMAIN=SUNW_OST_OSCMD -export SHELL PATH IFS TEXTDOMAIN - -cmd=`basename "$0"` -username=ftp -login_shell=/bin/true - -verify_root - -while getopts d arg -do - case $arg in - d) directory_only=1;; - \?) usage;; - esac -done -shift `expr $OPTIND - 1` - -# Check arguments. -[ $# -gt 1 ] && usage - -home_dir="$1" -if [ -n "$directory_only" -a -z "$home_dir" ] -then - fmt=`gettext "%s: Error: ftpdir required with -d option"` - printf "$fmt\n" "$cmd" >&2 - usage -fi - -if [ -n "$home_dir" ] -then - echo "$home_dir" | grep "^/" >/dev/null 2>&1 - if [ $? -ne 0 ] - then - fmt=`gettext "%s: Error: ftpdir must be an absolute pathname"` - printf "$fmt\n" "$cmd" >&2 - usage - fi -fi - -# Ignore certain signals. -trap '' 1 2 3 15 - -umask 022 -[ -z "$directory_only" ] && add_user - -create_home_dir -update_home_dir - -exit 0 diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpconversions b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpconversions deleted file mode 100644 index aaecee8f5e..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpconversions +++ /dev/null @@ -1,14 +0,0 @@ -# ident "%Z%%M% %I% %E% SMI" -# -# FTP server conversions database, see ftpconversions(4). -# - :.Z: : :/usr/bin/compress -cd -- %s:T_REG|T_ASCII:O_UNCOMPRESS:UNCOMPRESS - :.gz: : :/usr/bin/gzip -cd -- %s:T_REG|T_ASCII:O_UNCOMPRESS:GUNZIP - :.bz2: : :/usr/bin/bzip2 -cd -- %s:T_REG|T_ASCII:O_UNCOMPRESS:BUNZIP2 - : : :.Z:/usr/bin/compress -c -- %s:T_REG:O_COMPRESS:COMPRESS - : : :.gz:/usr/bin/gzip -c -- %s:T_REG:O_COMPRESS:GZIP - : : :.bz2:/usr/bin/bzip2 -c -- %s:T_REG:O_COMPRESS:BZIP2 - : : :.tar:/usr/bin/tar -cf - %s:T_REG|T_DIR:O_TAR:TAR - : : :.tar.Z:/usr/sfw/bin/gtar --use-compress-program=/usr/bin/compress -cf - -- %s:T_REG|T_DIR:O_COMPRESS|O_TAR:TAR+COMPRESS - : : :.tar.gz:/usr/sfw/bin/gtar --use-compress-program=/usr/bin/gzip -cf - -- %s:T_REG|T_DIR:O_COMPRESS|O_TAR:TAR+GZIP - : : :.tar.bz2:/usr/sfw/bin/gtar --use-compress-program=/usr/bin/bzip2 -cf - -- %s:T_REG|T_DIR:O_COMPRESS|O_TAR:TAR+BZIP2 diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpcount.c b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpcount.c deleted file mode 100644 index bcd0492c7f..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpcount.c +++ /dev/null @@ -1,544 +0,0 @@ -/* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/**************************************************************************** - - Copyright (c) 1999,2000 WU-FTPD Development Group. - All rights reserved. - - Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 - The Regents of the University of California. - Portions Copyright (c) 1993, 1994 Washington University in Saint Louis. - Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc. - Portions Copyright (c) 1989 Massachusetts Institute of Technology. - Portions Copyright (c) 1998 Sendmail, Inc. - Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman. - Portions Copyright (c) 1997 by Stan Barber. - Portions Copyright (c) 1997 by Kent Landfield. - Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 - Free Software Foundation, Inc. - - Use and distribution of this software and its source code are governed - by the terms and conditions of the WU-FTPD Software License ("LICENSE"). - - If you did not receive a copy of the license, it may be obtained online - at http://www.wu-ftpd.org/license.html. - - $Id: ftpcount.c,v 1.22 2000/07/01 18:17:39 wuftpd Exp $ - -****************************************************************************/ -#include "config.h" - -#include -#include -#include -#include -#ifdef HAVE_SYS_SYSLOG_H -#include -#endif -#if defined(HAVE_SYSLOG_H) || (!defined(AUTOCONF) && !defined(HAVE_SYS_SYSLOG_H)) -#include -#endif -#include -#include -#include -#include - -#include -#include -#include -#include - -#ifdef HAVE_PATHS_H -#include -#endif - -#if defined(VIRTUAL) && defined(INET6) -#include -#endif - -#include "pathnames.h" -#include "extensions.h" - -#if defined(HAVE_FCNTL_H) -#include -#endif - -#ifdef VIRTUAL -#define ARGS "Vv" -#else -#define ARGS "V" -#endif - -struct c_list { - char *class; - struct c_list *next; -}; - -#ifdef VIRTUAL -extern int read_servers_line(FILE *, char *, size_t, char *, size_t); -#endif - -void print_copyright(void); - -char *progname; - -/*************************************************************************/ -/* FUNCTION : parse_time */ -/* PURPOSE : Check a single valid-time-string against the current time */ -/* and return whether or not a match occurs. */ -/* ARGUMENTS : a pointer to the time-string */ -/*************************************************************************/ - -static int parsetime(char *whattime) -{ - static char *days[] = - {"Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Wk"}; - time_t clock; - struct tm *curtime; - int wday, start, stop, ltime, validday, loop, match; - - (void) time(&clock); - curtime = localtime(&clock); - wday = curtime->tm_wday; - validday = 0; - match = 1; - - while (match && isalpha(*whattime) && isupper(*whattime)) { - match = 0; - for (loop = 0; loop < 8; loop++) { - if (strncmp(days[loop], whattime, 2) == 0) { - whattime += 2; - match = 1; - if ((wday == loop) || ((loop == 7) && wday && (wday < 6))) - validday = 1; - } - } - } - - if (!validday) { - if (strncmp(whattime, "Any", 3) == 0) { - validday = 1; - whattime += 3; - } - else - return (0); - } - - if (sscanf(whattime, "%d-%d", &start, &stop) == 2) { - ltime = curtime->tm_min + 100 * curtime->tm_hour; - if ((start < stop) && ((ltime >= start) && ltime < stop)) - return (1); - if ((start > stop) && ((ltime >= start) || ltime < stop)) - return (1); - } - else - return (1); - - return (0); -} - -/*************************************************************************/ -/* FUNCTION : validtime */ -/* PURPOSE : Break apart a set of valid time-strings and pass them to */ -/* parse_time, returning whether or not ANY matches occurred */ -/* ARGUMENTS : a pointer to the time-string */ -/*************************************************************************/ - -static int validtime(char *ptr) -{ - char *nextptr; - int good; - - while (1) { - nextptr = strchr(ptr, '|'); - if (strchr(ptr, '|') == NULL) - return (parsetime(ptr)); - *nextptr = '\0'; - good = parsetime(ptr); - *nextptr++ = '|'; /* gotta restore the | or things get skipped! */ - if (good) - return (1); - ptr = nextptr; - } -} - -static int acl_getlimit(char *aclbuf, char *class) -{ - char *crptr, *ptr, linebuf[1024]; - int limit; - - while (*aclbuf != '\0') { - if (strncasecmp(aclbuf, "limit", 5) == 0) { - for (crptr = aclbuf; *crptr++ != '\n';); - *--crptr = '\0'; - (void) strlcpy(linebuf, aclbuf, sizeof(linebuf)); - *crptr = '\n'; - (void) strtok(linebuf, " \t"); /* returns "limit" */ - if ((ptr = strtok(NULL, " \t")) && (strcmp(class, ptr) == 0)) { - if ((ptr = strtok(NULL, " \t"))) { - limit = atoi(ptr); /* returns limit */ - if ((ptr = strtok(NULL, " \t")) && validtime(ptr)) - return (limit); - } - } - } - while (*aclbuf && *aclbuf++ != '\n'); - } - - return (-1); -} - -/*************************************************************************/ -/* FUNCTION : lock_fd */ -/* PURPOSE : Lock a file. */ -/* ARGUMENTS : File descriptor of file to lock. */ -/*************************************************************************/ - -static void lock_fd(int fd) -{ -#ifndef HAVE_FLOCK - struct flock arg; -#endif - -#ifdef HAVE_FLOCK - while (flock(fd, LOCK_SH)) { -#ifndef NO_PID_SLEEP_MSGS - syslog(LOG_ERR, "sleeping: flock of pid file failed: %m"); -#endif -#else - arg.l_type = F_RDLCK; - arg.l_whence = arg.l_start = arg.l_len = 0; - while (-1 == fcntl(fd, F_SETLK, &arg)) { -#ifndef NO_PID_SLEEP_MSGS - syslog(LOG_ERR, "sleeping: fcntl lock of pid file failed: %m"); -#endif -#endif /* HAVE_FLOCK */ - sleep(1); - } -#ifndef HAVE_FLOCK -#endif /* HAVE_FLOCK */ -} - -/*************************************************************************/ -/* FUNCTION : unlock_fd */ -/* PURPOSE : Unlock a file locked by lock_fd. */ -/* ARGUMENTS : File descriptor of file to unlock. */ -/*************************************************************************/ - -static void unlock_fd(int fd) -{ -#ifndef HAVE_FLOCK - struct flock arg; -#endif - -#ifdef HAVE_FLOCK - flock(fd, LOCK_UN); -#else - arg.l_type = F_UNLCK; - arg.l_whence = arg.l_start = arg.l_len = 0; - fcntl(fd, F_SETLK, &arg); -#endif /* HAVE_FLOCK */ -} - -static int acl_countusers(char *class) -{ - int i, j, n, count, pidfd; - pid_t procid; - char pidfile[MAXPATHLEN]; - char line[1024]; - FILE *ZeFile; - struct pidfile_header hdr; - struct stat pinfo; - unsigned char bits, *buf; - - snprintf(pidfile, sizeof(pidfile), _PATH_PIDNAMES, class); - pidfd = open(pidfile, O_RDONLY); - if (pidfd == -1) { - return (0); - } - - lock_fd(pidfd); - if (read(pidfd, (void *)&hdr, sizeof(hdr)) != sizeof(hdr)) { - unlock_fd(pidfd); - close(pidfd); - return (0); - } - if (strcmp(progname, "ftpcount") == 0) { - unlock_fd(pidfd); - close(pidfd); - return (hdr.count); - } - - /* - * Printing the process information can take a long time, and while we - * hold the lock no users can join or leave this class. To minimize the - * problem, read the whole PID file into memory then release the lock. - */ - if (fstat(pidfd, &pinfo) != 0) { - unlock_fd(pidfd); - close(pidfd); - return (0); - } - if ((buf = malloc((size_t)pinfo.st_size)) == NULL) { - unlock_fd(pidfd); - close(pidfd); - return (0); - } - n = read(pidfd, buf, (size_t)pinfo.st_size); - unlock_fd(pidfd); - close(pidfd); - count = 0; - procid = 0; - for (i = 0; i < n; i++) { - if (buf[i] == 0) { - procid += CHAR_BIT; - } - else { - bits = 1; - for (j = 0; j < CHAR_BIT; j++) { - if (((buf[i] & bits) != 0) && - ((kill(procid, 0) == 0) || (errno == EPERM))) { -#if defined(SVR4) -#ifdef AIX - snprintf(line, sizeof(line), "/bin/ps %d", procid); -#elif defined(sun) - snprintf(line, sizeof(line), "/usr/ucb/ps auxww %ld", procid); -#else -#if defined (LINUX_BUT_NOT_REDHAT_6_0) - snprintf(line, sizeof(line), "/bin/ps axwww %d", procid); -#else - snprintf(line, sizeof(line), "/bin/ps -f -p %d", procid); -#endif -#endif -#elif defined(M_UNIX) - snprintf(line, sizeof(line), "/bin/ps -f -p %d", procid); -#else - snprintf(line, sizeof(line), "/bin/ps %d", procid); -#endif - ZeFile = popen(line, "r"); - fgets(line, sizeof(line), ZeFile); - line[0] = '\0'; - fgets(line, sizeof(line), ZeFile); - if (line[0] != '\0') { - size_t i; - for (i = strlen(line); (i > 0) && ((line[i - 1] == ' ') || (line[i - 1] == '\n')); --i) - line[i - 1] = '\0'; - printf("%s\n", line); - count++; - } - pclose(ZeFile); - } - bits <<= 1; - procid++; - } - } - } - free(buf); - return (count); -} - -static void new_list(struct c_list **list) -{ - struct c_list *cp, *tcp; - - if (*list == NULL) { - *list = (struct c_list *) malloc(sizeof(struct c_list)); - if (*list == NULL) { - perror("malloc error in new_list"); - exit(1); - } - } - else { - cp = (*list)->next; - while (cp) { - if (cp->class) - free(cp->class); - tcp = cp; - cp = cp->next; - free(tcp); - } - } - (*list)->next = NULL; -} - -static int add_list(char *class, struct c_list **list) -{ - struct c_list *cp; - - for (cp = (*list)->next; cp; cp = cp->next) { - if (!strcmp(cp->class, class)) - return (-1); - } - - cp = (struct c_list *) malloc(sizeof(struct c_list)); - if (cp == NULL) { - perror("malloc error in add_list"); - exit(1); - } - - cp->class = strdup(class); - if (cp->class == NULL) { - perror("malloc error in add_list"); - exit(1); - } - cp->next = (*list)->next; - (*list)->next = cp; - return (1); -} - -static int display_info(char *ftpaccess, char *address) -{ - FILE *accessfile; - char class[80], linebuf[1024], *aclbuf, *myaclbuf, *crptr; - int limit; - struct stat finfo; - static struct c_list *list = NULL; - - if ((accessfile = fopen(ftpaccess, "r")) == NULL) { - if (errno != ENOENT) - fprintf(stderr, "%s: could not open access file %s: %s\n", - progname, ftpaccess, strerror(errno)); - return (1); - } - if (fstat(fileno(accessfile), &finfo) != 0) { - fprintf(stderr, "%s: could not fstat() access file %s: %s\n", - progname, ftpaccess, strerror(errno)); - fclose(accessfile); - return (1); - } - - if (finfo.st_size == 0) { - printf("%s: no service classes defined, no usage count kept\n", progname); - fclose(accessfile); - return (0); - } - else { - if (!(aclbuf = (char *) malloc((size_t) finfo.st_size + 1))) { - fprintf(stderr, "%s: could not malloc aclbuf: %s\n", - progname, strerror(errno)); - fclose(accessfile); - return (1); - } - fread(aclbuf, (size_t) finfo.st_size, 1, accessfile); - fclose(accessfile); - *(aclbuf + (size_t) finfo.st_size) = '\0'; - } - - (void) new_list(&list); - myaclbuf = aclbuf; - while (*myaclbuf != '\0') { - if (strncasecmp(myaclbuf, "class", 5) == 0) { - for (crptr = myaclbuf; *crptr++ != '\n';); - *--crptr = '\0'; - (void) strlcpy(linebuf, myaclbuf, sizeof(linebuf)); - *crptr = '\n'; - (void) strtok(linebuf, " \t"); /* returns "class" */ - /* returns class name */ - (void) strlcpy(class, strtok(NULL, " \t"), sizeof(class)); - if ((add_list(class, &list)) < 0) { - /* we have a class with multiple "class..." lines so, only - * display one count... */ - ; - } - else { - limit = acl_getlimit(myaclbuf, class); -#ifdef VIRTUAL - if (address != NULL) - printf("%s ", address); -#endif - if (strcmp(progname, "ftpcount")) { - printf("Service class %s: \n", class); - printf(" - %3d users ", acl_countusers(class)); - } - else { - printf("Service class %-20.20s - %3d users ", - class, acl_countusers(class)); - } - if (limit == -1) - printf("(no maximum)\n"); - else - printf("(%3d maximum)\n", limit); - } - } - while (*myaclbuf && *myaclbuf++ != '\n'); - } - free(aclbuf); - return (0); -} - -int main(int argc, char **argv) -{ - int c, exitval; - int virtual = 0; -#ifdef VIRTUAL - FILE *svrfp; - char *sp; - struct stat st; - char configdir[MAXPATHLEN]; - char accesspath[MAXPATHLEN]; -#ifdef INET6 - char hostaddress[INET6_ADDRSTRLEN]; -#else - char hostaddress[32]; -#endif -#endif - - if ((progname = strrchr(argv[0], '/'))) - ++progname; - else - progname = argv[0]; - - if (argc > 1) { - while ((c = getopt(argc, argv, ARGS)) != EOF) { - switch (c) { - case 'V': - print_copyright(); - exit(0); -#ifdef VIRTUAL - case 'v': - virtual = 1; - break; -#endif - default: - fprintf(stderr, "usage: %s [-" ARGS "]\n", progname); - exit(1); - } - } - } - - exitval = 0; - if ((virtual == 0) && (display_info(_PATH_FTPACCESS, NULL) != 0)) - exitval = 1; - -#ifdef VIRTUAL - /* - * Deal with the ftpaccess files at the virtual domain directory locations - * specified in the ftpservers file. - */ - if (virtual && ((svrfp = fopen(_PATH_FTPSERVERS, "r")) != NULL)) { - while (read_servers_line(svrfp, hostaddress, sizeof(hostaddress), - configdir, sizeof(configdir)) == 1) { - /* get rid of any trailing slash */ - sp = configdir + (strlen(configdir) - 1); - if (*sp == '/') - *sp = '\0'; - - /* check to see that a valid directory value was supplied */ - if ((stat(configdir, &st) == 0) && - ((st.st_mode & S_IFMT) == S_IFDIR)) { - snprintf(accesspath, sizeof(accesspath), "%s/ftpaccess", - configdir); - if (display_info(accesspath, hostaddress) != 0) - exitval = 1; - } - } - fclose(svrfp); - } -#endif - return (exitval); -} diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpd.c b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpd.c deleted file mode 100644 index 8b25401a61..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpd.c +++ /dev/null @@ -1,8026 +0,0 @@ -/* - * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -/**************************************************************************** - - Copyright (c) 1999,2000,2001 WU-FTPD Development Group. - All rights reserved. - - Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 - The Regents of the University of California. - Portions Copyright (c) 1993, 1994 Washington University in Saint Louis. - Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc. - Portions Copyright (c) 1989 Massachusetts Institute of Technology. - Portions Copyright (c) 1998 Sendmail, Inc. - Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman. - Portions Copyright (c) 1997 by Stan Barber. - Portions Copyright (c) 1997 by Kent Landfield. - Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 - Free Software Foundation, Inc. - - Use and distribution of this software and its source code are governed - by the terms and conditions of the WU-FTPD Software License ("LICENSE"). - - If you did not receive a copy of the license, it may be obtained online - at http://www.wu-ftpd.org/license.html. - - $Id: ftpd.c,v 1.111 2000/07/01 18:17:39 wuftpd Exp $ - -****************************************************************************/ -/* FTP server. */ -#include "config.h" - -#include -#include -#include -#include -#include -#include -#include - -#ifdef AIX -#include -#include -#include -#include -#endif - -#ifdef AUX -#include -#endif - -#include -#include -#include - -#define FTP_NAMES -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef INTERNAL_LS -#ifdef HAVE_GLOB_H -#include -#else -#include -#endif -#endif -#ifdef HAVE_GRP_H -#include -#endif -#include - -#define VA_LOCAL_DECL va_list ap; -#define VA_START(f) va_start(ap, f) -#define VA_END va_end(ap) - -#include "proto.h" - -#ifdef HAVE_UFS_QUOTA_H -#include -#endif -#ifdef HAVE_SYS_FS_UFS_QUOTA_H -#include -#endif - -#ifdef HAVE_SYS_SYSLOG_H -#include -#endif -#if defined(HAVE_SYSLOG_H) || (!defined(AUTOCONF) && !defined(HAVE_SYS_SYSLOG_H)) -#include -#endif -#ifdef TIME_WITH_SYS_TIME -#include -#include -#else -#ifdef HAVE_SYS_TIME_H -#include -#else -#include -#endif -#endif - -#ifdef HAVE_SYS_SENDFILE_H -#include -#endif - -#include "conversions.h" -#include "extensions.h" - -#ifdef SHADOW_PASSWORD -#include -#endif - -#include "pathnames.h" - -#ifdef M_UNIX -#include -#include -#endif - -#if defined(HAVE_FCNTL_H) -#include -#endif - -#ifdef HAVE_SYSINFO -#include -#endif - -#ifdef KERBEROS -#include -#include -#include -#endif - -#ifdef ULTRIX_AUTH -#include -#include -#endif - -#ifndef HAVE_LSTAT -#define lstat stat -#endif - -#ifdef AFS_AUTH -#include -#include -#endif - -#ifdef DCE_AUTH -#include -#include -#include -#endif - - -#ifdef HAVE_DIRENT_H -#include -#else -#include -#endif - -#if defined(USE_LONGJMP) -#define wu_longjmp(x, y) longjmp((x), (y)) -#define wu_setjmp(x) setjmp(x) -#ifndef JMP_BUF -#define JMP_BUF jmp_buf -#endif -#else -#define wu_longjmp(x, y) siglongjmp((x), (y)) -#define wu_setjmp(x) sigsetjmp((x), 1) -#ifndef JMP_BUF -#define JMP_BUF sigjmp_buf -#endif -#endif - -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 64 /* may be too big */ -#endif - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE !TRUE -#endif - -#ifdef MAIL_ADMIN -#define MAILSERVERS 10 -#define INCMAILS 10 -int mailservers = 0; -char *mailserver[MAILSERVERS]; -int incmails = 0; -char *incmail[INCMAILS]; -char *mailfrom; -char *email(char *full_address); -FILE *SockOpen(char *host, int clientPort); -char *SockGets(FILE *sockfp, char *buf, int len); -int SockWrite(char *buf, int size, int nels, FILE *sockfp); -int SockPrintf(FILE *sockfp, char *format,...); -int SockPuts(FILE *sockfp, char *buf); -int Reply(FILE *sockfp); -int Send(FILE *sockfp, char *format,...); -#endif /* MAIL_ADMIN */ - -#if defined(_SCO_DS) && !defined(SIGURG) -#define SIGURG SIGUSR1 -#endif - -/* File containing login names NOT to be used on this machine. Commonly used - * to disallow uucp. */ -extern int errno; - -extern char *ctime(const time_t *); -#ifndef NO_CRYPT_PROTO -extern char *crypt(const char *, const char *); -#endif - -extern char version[]; -extern char *home; /* pointer to home directory for glob */ -extern char cbuf[]; -extern off_t restart_point; -extern int yyerrorcalled; - -struct SOCKSTORAGE ctrl_addr; -struct SOCKSTORAGE data_source; -struct SOCKSTORAGE data_dest; -struct SOCKSTORAGE his_addr; -struct SOCKSTORAGE pasv_addr; -struct SOCKSTORAGE vect_addr; -int route_vectored = 0; -int passive_port_min = 1024; -int passive_port_max = 65535; -int restricted_user = 0; -unsigned short data_port = 0; - -#ifdef INET6 -int ctrl_v4mapped = 0; -int epsv_all = 0; -int listen_v4 = 0; /* when set, listen on IPv4 socket in standalone mode */ -#endif - -#ifdef VIRTUAL -char virtual_root[MAXPATHLEN]; -char virtual_banner[MAXPATHLEN]; -char virtual_email[MAXPATHLEN]; - -char virtual_hostname[MAXHOSTNAMELEN]; -char virtual_address[MAXHOSTNAMELEN]; - -extern int virtual_mode; -extern int virtual_ftpaccess; -#endif - -#ifdef QUOTA -extern struct dqblk quota; -#endif - -#if defined(USE_GSS) -#include "gssutil.h" - -extern gss_info_t gss_info; - -int allow_ccc = 0; -int ccc_ok = 0; -extern char *cur_auth_type; -#endif /* USE_GSS */ - -int data; -jmp_buf errcatch; -JMP_BUF urgcatch; -int logged_in = 0; -struct passwd *pw; -char chroot_path[MAXPATHLEN]; -int debug = 0; -int disable_rfc931 = 0; -extern unsigned int timeout_idle; -extern unsigned int timeout_maxidle; -extern unsigned int timeout_data; -extern unsigned int timeout_accept; -extern unsigned int timeout_connect; - -/* previously defaulted to 1, and -l or -L set them to 1, so that there was - no way to turn them *off*! Changed so that the manpage reflects common - sense. -L is way noisy; -l we'll change to be "just right". _H */ -int logging = 0; -int log_commands = 0; -int log_security = 0; -int syslogmsg = 0; -static int wtmp_logging = 1; - -#ifdef SECUREOSF -#define SecureWare /* Does this mean it works for all SecureWare? */ -#endif - -#ifdef HPUX_10_TRUSTED -#include -#endif - -#if defined(SecureWare) || defined(HPUX_10_TRUSTED) -#include -#endif - -int anonymous = 1; -int guest; -int type; -int form; -int stru; /* avoid C keyword */ -int mode; -int usedefault = 1; /* for data transfers */ -int pdata = -1; /* for passive mode */ -int transflag; -int ftwflag; -off_t file_size; -off_t byte_count; -int TCPwindowsize = 0; /* 0 = use system default */ -size_t sendbufsz; /* buffer size to use when sending data */ -size_t recvbufsz; /* buffer size to use when receiving data */ - -#ifdef TRANSFER_COUNT -off_t data_count_total = 0; /* total number of data bytes */ -off_t data_count_in = 0; -off_t data_count_out = 0; -off_t byte_count_total = 0; /* total number of general traffic */ -off_t byte_count_in = 0; -off_t byte_count_out = 0; -int file_count_total = 0; /* total number of data files */ -int file_count_in = 0; -int file_count_out = 0; -int xfer_count_total = 0; /* total number of transfers */ -int xfer_count_in = 0; -int xfer_count_out = 0; -#ifdef TRANSFER_LIMIT -int file_limit_raw_in = 0; -int file_limit_raw_out = 0; -int file_limit_raw_total = 0; -int file_limit_data_in = 0; -int file_limit_data_out = 0; -int file_limit_data_total = 0; -off_t data_limit_raw_in = 0; -off_t data_limit_raw_out = 0; -off_t data_limit_raw_total = 0; -off_t data_limit_data_in = 0; -off_t data_limit_data_out = 0; -off_t data_limit_data_total = 0; -#ifdef RATIO /* 1998/08/04 K.Wakui */ -#define TRUNC_KB(n) ((n)/1024+(((n)%1024)?1:0)) -off_t total_free_dl = 0; -int upload_download_rate = 0; -int freefile; -int is_downloadfree( char * ); -#endif /* RATIO */ -#endif -#endif - -int retrieve_is_data = 1; /* !0=data, 0=general traffic -- for 'ls' */ -char LastFileTransferred[MAXPATHLEN] = ""; - -static char *RootDirectory = NULL; - -#if !defined(CMASK) || CMASK == 0 -#undef CMASK -#define CMASK 022 -#endif -mode_t defumask = CMASK; /* default umask value */ -#ifdef ALTERNATE_CD -char defhome[] = "/"; -#endif -char tmpline[7]; -char hostname[MAXHOSTNAMELEN]; -char remotehost[MAXHOSTNAMELEN]; -char remoteaddr[MAXHOSTNAMELEN]; -char *remoteident = "[nowhere yet]"; -int rhlookup = TRUE; /* when TRUE lookup the remote hosts name */ - -#if defined(SOLARIS_2) && !defined(NAME_SERVICE_DOOR) -#define NAME_SERVICE_DOOR "/var/run/name_service_door" -#endif - -#if defined(SOLARIS_2) -int close_nsdoor(void *cb_data, int fd); -void cleanup_nscd(); -#endif - -/* log failures 27-apr-93 ehk/bm */ -#define MAXUSERNAMELEN 256 -char the_user[MAXUSERNAMELEN]; - -/* Access control and logging passwords */ -/* OFF by default. _H */ -int use_accessfile = 0; -char guestpw[MAXHOSTNAMELEN]; -char privatepw[MAXHOSTNAMELEN]; -int nameserved = 0; -extern char authuser[]; -extern int authenticated; -extern int keepalive; - -/* File transfer logging (xferlog) */ -int xferlog = 0; -int log_outbound_xfers = 0; -int log_incoming_xfers = 0; -char logfile[MAXPATHLEN]; - -/* Allow use of lreply(); this is here since some older FTP clients don't - * support continuation messages. In violation of the RFCs... */ -int dolreplies = 1; - -/* Spontaneous reply text. To be sent along with next reply to user */ -char *autospout = NULL; -int autospout_free = 0; - -/* allowed on-the-fly file manipulations (compress, tar) */ -int mangleopts = 0; - -/* number of login failures before attempts are logged and FTP *EXITS* */ -int lgi_failure_threshold = 5; - -/* Timeout intervals for retrying connections to hosts that don't accept PORT - * cmds. This is a kludge, but given the problems with TCP... */ -#define SWAITMAX 90 /* wait at most 90 seconds */ -#define SWAITINT 5 /* interval between retries */ - -int swaitmax = SWAITMAX; -int swaitint = SWAITINT; - -SIGNAL_TYPE lostconn(int sig); -SIGNAL_TYPE randomsig(int sig); -SIGNAL_TYPE myoob(int sig); -FILE *getdatasock(char *mode); -FILE *dataconn(char *name, off_t size, char *mode); -void setproctitle(const char *fmt,...); -void initsetproctitle(int, char **, char **); -void reply(int, char *fmt,...); -void lreply(int, char *fmt,...); - -#ifndef HAVE_VSNPRINTF -extern int vsnprintf(char *, size_t, const char *, va_list); -#endif - -#ifndef HAVE_SNPRINTF -extern int snprintf(char *, size_t, const char *,...); -#endif - -#ifdef NEED_SIGFIX -extern sigset_t block_sigmask; /* defined in sigfix.c */ -#endif - -char proctitle[BUFSIZ]; /* initial part of title */ - -#if defined(SKEY) && defined(OPIE) -#error YOU SHOULD NOT HAVE BOTH SKEY AND OPIE DEFINED!!!!! -#endif - -#ifdef SKEY -#include -int pwok = 0; -#endif - -#ifdef OPIE -#include -int pwok = 0; -int af_pwok = 0; -struct opie opiestate; -#endif - -#ifdef KERBEROS -void init_krb(); -void end_krb(); -char krb_ticket_name[100]; -#endif /* KERBEROS */ - -#ifdef ULTRIX_AUTH -int ultrix_check_pass(char *passwd, char *xpasswd); -#endif - -#ifdef USE_PAM -#if defined(ULTRIX_AUTH) || defined(SECUREOSF) || defined(KERBEROS) || defined(SKEY) || defined (OPIE) || defined (BSD_AUTH) -#error No other auth methods are allowed with PAM. -#endif -#include -static int pam_check_pass(char *user, char *passwd); -pam_handle_t *pamh; -#endif - -#ifndef INTERNAL_LS -/* ls program commands and options for lreplies on and off */ -char ls_long[BUFSIZ * 2]; -char ls_short[BUFSIZ * 2]; -char ls_plain[BUFSIZ * 2]; -#endif - -#define FTPD_OPTS ":4aAdiIlLoP:qQr:t:T:u:vVwWxX" -#if defined(DAEMON) -# define DAEMON_OPTS "p:sS" -#else /* !(defined(DAEMON)) */ -# define DAEMON_OPTS -#endif /* !(defined(DAEMON)) */ -#if defined(USE_GSS) -# define GSS_OPTS "CK" -#else /* !(defined(USE_GSS)) */ -# define GSS_OPTS -#endif /* !(defined(USE_GSS)) */ - -/* Some systems use one format, some another. This takes care of the garbage */ -#ifndef L_FORMAT /* Autoconf detects this... */ -#if (defined(BSD) && (BSD >= 199103)) && !defined(LONGOFF_T) -#define L_FORMAT "qd" -#else -#ifdef _AIX42 -#define L_FORMAT "lld" -#else -#ifdef SOLARIS_2 -#define L_FORMAT "ld" -#else -#define L_FORMAT "d" -#endif -#endif -#endif -#endif - -#ifdef DAEMON -int be_daemon = 0; /* Run standalone? */ -int daemon_port = 0; -static void do_daemon(void); -#endif -int Bypass_PID_Files = 0; - -#ifdef OTHER_PASSWD -#include "getpwnam.h" -char _path_passwd[MAXPATHLEN]; -#ifdef SHADOW_PASSWORD -char _path_shadow[MAXPATHLEN]; -#endif -#endif -#if defined(USE_PAM) && defined(OTHER_PASSWD) -int use_pam = 1; -#else -int use_pam = 0; -#endif - -void print_copyright(void); -char *mapping_getcwd(char *path, size_t size); - -void dolog(struct SOCKSTORAGE *); - -#ifdef THROUGHPUT -extern void throughput_calc(char *, int *, double *); -extern void throughput_adjust(char *); -#endif - -time_t login_time; -time_t limit_time = 0; - -int regexmatch(char *name, char *rgexp); - -int pasv_allowed(char *remoteaddr); -int port_allowed(char *remoteaddr); - -#if sparc && !__svr4__ -int fclose(FILE *); -#endif - -static SIGNAL_TYPE alarm_signal(int sig) -{ -} - -static FILE *draconian_FILE = NULL; - -static SIGNAL_TYPE draconian_alarm_signal(int sig) -{ - if (draconian_FILE != NULL) { - fclose(draconian_FILE); - draconian_FILE = NULL; - } - (void) signal(SIGALRM, draconian_alarm_signal); -} - -static void socket_flush_wait(FILE *file) -{ - static int flushwait = TRUE; - static int first_time = TRUE; - char c; - int set; - int fd = fileno(file); - int serrno = errno; - struct aclmember *entry; - - if (first_time) { - entry = NULL; - /* flush-wait yes|no [typelist] */ - while (getaclentry("flush-wait", &entry)) { - if (!ARG0) - continue; - if (strcasecmp(ARG0, "yes") == 0) - set = TRUE; - else if (strcasecmp(ARG0, "no") == 0) - set = FALSE; - else - continue; - - if (!ARG1) - flushwait = set; - else if (type_match(ARG1)) { - flushwait = set; - break; - } - } - first_time = FALSE; - } - if (flushwait) { - if (draconian_FILE != NULL) - shutdown(fd, 1); - if (draconian_FILE != NULL) - read(fd, &c, 1); - } - errno = serrno; -/* - * GAL - the read() here should be checked to ensure it returned 0 (indicating - * EOF) or -1 (an error occurred). Anything else (real data) is a protocol - * error. - */ -} - -static int IPClassOfService(const char *type) -{ - int ipcos = -1, value; - char *endp; - struct aclmember *entry = NULL; - - /* ipcos control|data [] */ - while (getaclentry("ipcos", &entry)) { - if (ARG0 && ARG1) { - if (strcasecmp(type, ARG0) == 0) { - if (!ARG2) { - errno = 0; - value = (int) strtol(ARG1, &endp, 0); - if ((errno == 0) && (value >= 0) && (*endp == '\0')) - ipcos = value; - } - else if (type_match(ARG2)) { - errno = 0; - value = (int) strtol(ARG1, &endp, 0); - if ((errno == 0) && (value >= 0) && (*endp == '\0')) { - ipcos = value; - break; - } - } - } - } - } - return ipcos; -} - -int main(int argc, char **argv, char **envp) -{ -#if defined(UNIXWARE) || defined(AIX) - size_t addrlen; -#else - int addrlen; -#endif - int on = 1; - int cos; - int c; -#ifndef INTERNAL_LS - int which; -#endif - extern int optopt; - extern char *optarg; - char *hp; - struct aclmember *entry; -#ifdef VIRTUAL -#if defined(UNIXWARE) || defined(AIX) - size_t virtual_len; -#else - int virtual_len; -#endif - struct SOCKSTORAGE virtual_addr; -#endif - struct servent *serv; - -#ifdef AUX - setcompat(COMPAT_POSIX | COMPAT_BSDSETUGID); -#endif - - closelog(); -#ifdef FACILITY - openlog("ftpd", LOG_PID | LOG_NDELAY, FACILITY); -#else - openlog("ftpd", LOG_PID); -#endif - -#ifdef SecureWare - setluid(1); /* make sure there is a valid luid */ - set_auth_parameters(argc, argv); - setreuid(0, 0); -#endif -#if defined(M_UNIX) && !defined(_M_UNIX) - res_init(); /* bug in old (1.1.1) resolver */ - _res.retrans = 20; /* because of fake syslog in 3.2.2 */ - setlogmask(LOG_UPTO(LOG_INFO)); -#endif - - while ((c = getopt(argc, argv, FTPD_OPTS DAEMON_OPTS GSS_OPTS)) != -1) { - switch (c) { - - case '4': -#ifdef INET6 - listen_v4 = 1; -#endif - break; - - case 'a': - use_accessfile = 1; - break; - - case 'A': - use_accessfile = 0; - break; - - case 'v': - debug = 1; - break; - - case 'd': - debug = 1; - break; - -#if defined(USE_GSS) - case 'C': - gss_info.want_creds = 1; - break; - - case 'K': - gss_info.must_gss_auth = 1; - break; -#endif /* USE_GSS */ - - case 'l': - logging = 1; - break; - - case 'L': - log_commands = 3; - break; - - case 'i': - log_incoming_xfers = 3; - break; - - case 'I': - disable_rfc931 = 1; - break; - - case 'o': - log_outbound_xfers = 3; - break; - - case 'q': - Bypass_PID_Files = 0; - break; - - case 'Q': - Bypass_PID_Files = 1; - break; - - case 'r': - if ((optarg != NULL) && (optarg[0] != '\0')) { - RootDirectory = malloc(strlen(optarg) + 1); - if (RootDirectory != NULL) - strcpy(RootDirectory, optarg); - } - break; - - case 'P': - data_port = htons(atoi(optarg)); - break; - -#ifdef DAEMON - case 'p': - daemon_port = atoi(optarg); - break; - - case 's': - be_daemon = 1; - break; - - case 'S': - be_daemon = 2; - break; -#endif /* DAEMON */ - - case 't': - timeout_idle = atoi(optarg); - if (timeout_maxidle < timeout_idle) - timeout_maxidle = timeout_idle; - break; - - case 'T': - timeout_maxidle = atoi(optarg); - if (timeout_idle > timeout_maxidle) - timeout_idle = timeout_maxidle; - break; - - case 'u': - { - unsigned int val = 0; - - while (*optarg && *optarg >= '0' && *optarg <= '7') - val = val * 8 + *optarg++ - '0'; - if (*optarg || val > 0777) - syslog(LOG_ERR, "bad value for -u"); - else - defumask = val; - break; - } - - case 'V': - print_copyright(); - exit(0); - /* NOTREACHED */ - case 'w': - wtmp_logging = 1; - break; - - case 'W': - wtmp_logging = 0; - break; - - case 'x': - syslogmsg = 2; - break; - - case 'X': - syslogmsg = 1; - break; - - case ':': - syslog(LOG_ERR, "option -%c requires an argument", optopt); - break; - - default: - syslog(LOG_ERR, "unknown option -%c ignored", optopt); - break; - } - } - initsetproctitle(argc, argv, envp); - (void) freopen(_PATH_DEVNULL, "w", stderr); - - /* Checking for random signals ... */ -#ifdef NEED_SIGFIX - sigemptyset(&block_sigmask); -#endif -#ifndef SIG_DEBUG -#ifdef SIGHUP - (void) signal(SIGHUP, randomsig); -#ifdef NEED_SIGFIX - sigaddset(&block_sigmask, SIGHUP); -#endif -#endif -#ifdef SIGINT - (void) signal(SIGINT, randomsig); -#ifdef NEED_SIGFIX - sigaddset(&block_sigmask, SIGINT); -#endif -#endif -#ifdef SIGQUIT - (void) signal(SIGQUIT, randomsig); -#ifdef NEED_SIGFIX - sigaddset(&block_sigmask, SIGQUIT); -#endif -#endif -#ifdef SIGILL - (void) signal(SIGILL, randomsig); -#ifdef NEED_SIGFIX - sigaddset(&block_sigmask, SIGILL); -#endif -#endif -#ifdef SIGTRAP - (void) signal(SIGTRAP, randomsig); -#ifdef NEED_SIGFIX - sigaddset(&block_sigmask, SIGTRAP); -#endif -#endif -#ifdef SIGIOT - (void) signal(SIGIOT, randomsig); -#ifdef NEED_SIGFIX - sigaddset(&block_sigmask, SIGIOT); -#endif -#endif -#ifdef SIGEMT - (void) signal(SIGEMT, randomsig); -#ifdef NEED_SIGFIX - sigaddset(&block_sigmask, SIGEMT); -#endif -#endif -#ifdef SIGFPE - (void) signal(SIGFPE, randomsig); -#ifdef NEED_SIGFIX - sigaddset(&block_sigmask, SIGFPE); -#endif -#endif -#ifdef SIGKILL - (void) signal(SIGKILL, randomsig); -#ifdef NEED_SIGFIX - sigaddset(&block_sigmask, SIGKILL); -#endif -#endif -#ifdef SIGBUS - (void) signal(SIGBUS, randomsig); -#ifdef NEED_SIGFIX - sigaddset(&block_sigmask, SIGBUS); -#endif -#endif -#ifdef SIGSEGV - (void) signal(SIGSEGV, randomsig); -#ifdef NEED_SIGFIX - sigaddset(&block_sigmask, SIGSEGV); -#endif -#endif -#ifdef SIGSYS - (void) signal(SIGSYS, randomsig); -#ifdef NEED_SIGFIX - sigaddset(&block_sigmask, SIGSYS); -#endif -#endif -#ifdef SIGALRM - (void) signal(SIGALRM, randomsig); -#ifdef NEED_SIGFIX - sigaddset(&block_sigmask, SIGALRM); -#endif -#endif -#ifdef SIGSTOP - (void) signal(SIGSTOP, randomsig); -#ifdef NEED_SIGFIX - sigaddset(&block_sigmask, SIGSTOP); -#endif -#endif -#ifdef SIGTSTP - (void) signal(SIGTSTP, randomsig); -#ifdef NEED_SIGFIX - sigaddset(&block_sigmask, SIGTSTP); -#endif -#endif -#ifdef SIGTTIN - (void) signal(SIGTTIN, randomsig); -#ifdef NEED_SIGFIX - sigaddset(&block_sigmask, SIGTTIN); -#endif -#endif -#ifdef SIGTTOU - (void) signal(SIGTTOU, randomsig); -#ifdef NEED_SIGFIX - sigaddset(&block_sigmask, SIGTTOU); -#endif -#endif -#ifdef SIGIO - (void) signal(SIGIO, randomsig); -#ifdef NEED_SIGFIX - sigaddset(&block_sigmask, SIGIO); -#endif -#endif -#ifdef SIGXCPU - (void) signal(SIGXCPU, randomsig); -#ifdef NEED_SIGFIX - sigaddset(&block_sigmask, SIGXCPU); -#endif -#endif -#ifdef SIGXFSZ - (void) signal(SIGXFSZ, randomsig); -#ifdef NEED_SIGFIX - sigaddset(&block_sigmask, SIGXFSZ); -#endif -#endif -#ifdef SIGWINCH - (void) signal(SIGWINCH, randomsig); -#ifdef NEED_SIGFIX - sigaddset(&block_sigmask, SIGWINCH); -#endif -#endif -#ifdef SIGVTALRM - (void) signal(SIGVTALRM, randomsig); -#ifdef NEED_SIGFIX - sigaddset(&block_sigmask, SIGVTALRM); -#endif -#endif -#ifdef SIGPROF - (void) signal(SIGPROF, randomsig); -#ifdef NEED_SIGFIX - sigaddset(&block_sigmask, SIGPROF); -#endif -#endif -#ifdef SIGUSR1 - (void) signal(SIGUSR1, randomsig); -#ifdef NEED_SIGFIX - sigaddset(&block_sigmask, SIGUSR1); -#endif -#endif -#ifdef SIGUSR2 - (void) signal(SIGUSR2, randomsig); -#ifdef NEED_SIGFIX - sigaddset(&block_sigmask, SIGUSR2); -#endif -#endif - -#ifdef SIGPIPE - (void) signal(SIGPIPE, lostconn); -#ifdef NEED_SIGFIX - sigaddset(&block_sigmask, SIGPIPE); -#endif -#endif -#ifdef SIGCHLD - (void) signal(SIGCHLD, SIG_IGN); -#ifdef NEED_SIGFIX - sigaddset(&block_sigmask, SIGCHLD); -#endif -#endif - -#ifdef SIGURG - if (signal(SIGURG, myoob) == SIG_ERR) - syslog(LOG_ERR, "signal: %m"); -#ifdef NEED_SIGFIX - sigaddset(&block_sigmask, SIGURG); -#endif -#endif -#endif /* SIG_DEBUG */ - -#ifdef VIRTUAL - virtual_root[0] = '\0'; - virtual_banner[0] = '\0'; -#endif - - setup_paths(); - -#ifdef OTHER_PASSWD - strcpy(_path_passwd, "/etc/passwd"); -#ifdef SHADOW_PASSWORD - strcpy(_path_shadow, "/etc/shadow"); -#endif -#endif - - access_init(); - -#ifdef DAEMON - if (be_daemon != 0) - do_daemon(); - else { -#endif - addrlen = sizeof(his_addr); - if (getpeername(0, (struct sockaddr *) &his_addr, &addrlen) < 0) { - syslog(LOG_ERR, "getpeername: %m"); -#ifndef DEBUG - exit(1); -#endif - } -#ifdef DAEMON - } -#endif - addrlen = sizeof(ctrl_addr); - if (getsockname(0, (struct sockaddr *) &ctrl_addr, &addrlen) < 0) { - syslog(LOG_ERR, "getsockname: %m"); -#ifndef DEBUG - exit(1); -#endif - } - /* Sanity check */ - if ((SOCK_FAMILY(ctrl_addr) != AF_INET) -#ifdef INET6 - && (SOCK_FAMILY(ctrl_addr) != AF_INET6) -#endif - ) { - syslog(LOG_ERR, "control connection address family (%d) not supported.", - SOCK_FAMILY(ctrl_addr)); -#ifndef DEBUG - exit(1); -#endif - } -#ifdef SOLARIS_BSM_AUDIT - /* Set audit characteristics */ - if (audit_settid(0)) { - syslog(LOG_ERR, "audit failure"); - exit(1); - } -#endif -#ifdef INET6 - /* IP_TOS is an IPv4 socket option */ - if (SOCK_FAMILY(ctrl_addr) == AF_INET) -#endif - if ((cos = IPClassOfService("control")) >= 0) { - if (setsockopt(0, IPPROTO_IP, IP_TOS, (char *) &cos, sizeof(int)) < 0) - syslog(LOG_WARNING, "setsockopt (IP_TOS): %m"); - } - -#ifdef TCP_NODELAY - /* - * Disable Nagle on the control channel so that we don't have to wait - * for peer's ACK before issuing our next reply. - */ - if (setsockopt(0, IPPROTO_TCP, TCP_NODELAY, &on, sizeof (on)) < 0) - syslog(LOG_WARNING, "control setsockopt TCP_NODELAY: %m"); -#endif - - if (keepalive) - if (setsockopt(0, SOL_SOCKET, SO_KEEPALIVE, (char *) &on, sizeof(on)) < 0) - syslog(LOG_ERR, "setsockopt SO_KEEPALIVE %m"); - - /* Try to handle urgent data inline */ -#ifdef SO_OOBINLINE - if (setsockopt(0, SOL_SOCKET, SO_OOBINLINE, (char *) &on, sizeof(int)) < 0) - syslog(LOG_ERR, "setsockopt (SO_OOBINLINE): %m"); -#endif - -#ifdef F_SETOWN - if (fcntl(fileno(stdin), F_SETOWN, getpid()) == -1) - syslog(LOG_ERR, "fcntl F_SETOWN: %m"); -#elif defined(SIOCSPGRP) - { - int pid; - pid = getpid(); - if (ioctl(fileno(stdin), SIOCSPGRP, &pid) == -1) - syslog(LOG_ERR, "ioctl SIOCSPGRP: %m"); - } -#endif - -#ifdef INET6 - if ((SOCK_FAMILY(ctrl_addr) == AF_INET6) && - IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&(ctrl_addr))->sin6_addr)) - ctrl_v4mapped = 1; -#endif - - if (data_port == 0) { - serv = getservbyname("ftp-data", "tcp"); - if (serv != NULL) - data_port = serv->s_port; - else - data_port = htons(ntohs(SOCK_PORT(ctrl_addr)) - 1); - } - - if (RootDirectory != NULL) { - if ((chroot(RootDirectory) < 0) - || (chdir("/") < 0)) { - syslog(LOG_ERR, "Cannot chroot to initial directory, aborting."); - exit(1); - } - } - - load_timeouts(); - - /* set resolver options */ - set_res_options(); - - dolog(&his_addr); - /* Set up default state */ - data = -1; - type = TYPE_A; - form = FORM_N; - stru = STRU_F; - mode = MODE_S; - tmpline[0] = '\0'; - yyerrorcalled = 0; - - entry = (struct aclmember *) NULL; - if ((getaclentry("hostname", &entry)) && ARG0) { - (void) strncpy(hostname, ARG0, sizeof(hostname)); - hostname[sizeof(hostname) - 1] = '\0'; - } - else { -#ifdef HAVE_SYSINFO - sysinfo(SI_HOSTNAME, hostname, sizeof(hostname)); -#else - (void) gethostname(hostname, sizeof(hostname)); -#endif -/* set the FQDN here */ - hp = wu_gethostbyname(hostname); - if (hp) { - (void) strncpy(hostname, hp, sizeof(hostname)); - hostname[sizeof(hostname) - 1] = '\0'; - } - } - route_vectored = routevector(); - conv_init(); - -#ifdef MAIL_ADMIN - incmails = 0; - mailfrom = NULL; -#endif /* MAIL_ADMIN */ -#ifdef VIRTUAL - /* - ** If virtual_mode is set at this point then an alternate ftpaccess - ** is in use. Otherwise we need to check the Master ftpaccess file - ** to see if the site is only using the "virtual" directives to - ** specify virtual site directives. - ** - ** In this manner an admin can put a virtual site in the ftpservers - ** file if they need expanded configuration support or can use the - ** minimal root/banner/logfile if they do not need any more than that. - */ - - if (virtual_mode) { - /* Get the root of the virtual server directory */ - entry = (struct aclmember *) NULL; - if (getaclentry("root", &entry)) { - if (ARG0) - strcpy(virtual_root, ARG0); - } - - /* Get the logfile to use */ - entry = (struct aclmember *) NULL; - if (getaclentry("logfile", &entry)) { - if (ARG0) - strcpy(logfile, ARG0); - } - } - else { - virtual_hostname[0] = '\0'; - virtual_address[0] = '\0'; - virtual_len = sizeof(virtual_addr); - if (getsockname(0, (struct sockaddr *) &virtual_addr, &virtual_len) == 0) { - strcpy(virtual_address, inet_stop(&virtual_addr)); - wu_gethostbyaddr(&virtual_addr, virtual_hostname, sizeof(virtual_hostname)); - entry = (struct aclmember *) NULL; - while (getaclentry("virtual", &entry)) { - if (!ARG0 || !ARG1 || !ARG2) - continue; - if (hostmatch(ARG0, virtual_address, virtual_hostname)) { - if (!strcasecmp(ARG1, "root")) { - if (debug) - syslog(LOG_DEBUG, "VirtualFTP Connect to: %s [%s]", - virtual_hostname, virtual_address); - virtual_mode = 1; - strncpy(virtual_root, ARG2, sizeof(virtual_root)); - virtual_root[sizeof(virtual_root) - 1] = '\0'; - /* reset hostname to this virtual name */ - (void) strcpy(hostname, virtual_hostname); - virtual_email[0] = '\0'; - } - if (!strcasecmp(ARG1, "banner")) { - strncpy(virtual_banner, ARG2, sizeof(virtual_banner)); - virtual_banner[sizeof(virtual_banner) - 1] = '\0'; - } - if (!strcasecmp(ARG1, "logfile")) { - strncpy(logfile, ARG2, sizeof(logfile)); - logfile[sizeof(logfile) - 1] = '\0'; - } - if (!strcasecmp(ARG1, "hostname")) { - strncpy(hostname, ARG2, sizeof(hostname)); - hostname[sizeof(hostname) - 1] = '\0'; - } - if (!strcasecmp(ARG1, "email")) { - strncpy(virtual_email, ARG2, sizeof(virtual_email)); - virtual_email[sizeof(virtual_email) - 1] = '\0'; - } -#ifdef OTHER_PASSWD - if (!strcasecmp(ARG1, "passwd")) { - strncpy(_path_passwd, ARG2, sizeof(_path_passwd)); - _path_passwd[sizeof(_path_passwd) - 1] = '\0'; -#ifdef USE_PAM - use_pam = 0; -#endif - } -#ifdef SHADOW_PASSWORD - if (!strcasecmp(ARG1, "shadow")) { - strncpy(_path_shadow, ARG2, sizeof(_path_shadow)); - _path_shadow[sizeof(_path_shadow) - 1] = '\0'; -#ifdef USE_PAM - use_pam = 0; -#endif - } -#endif -#endif -#ifdef MAIL_ADMIN - if (mailfrom == NULL) - if (!strcasecmp(ARG1, "mailfrom")) { - mailfrom = strdup(ARG2); - } - if (!strcasecmp(ARG1, "incmail")) { - if (incmails < INCMAILS) - incmail[incmails++] = strdup(ARG2); - } -#endif - } - } - if (!virtual_mode) { - entry = (struct aclmember *) NULL; - while (getaclentry("defaultserver", &entry)) { - if (!ARG0 || !ARG1) - continue; -#ifdef MAIL_ADMIN - if (mailfrom == NULL) - if (!strcasecmp(ARG0, "mailfrom")) { - mailfrom = strdup(ARG1); - } - if (!strcasecmp(ARG0, "incmail")) { - if (incmails < INCMAILS) - incmail[incmails++] = strdup(ARG1); - } -#endif - } - } - } - } - -#ifdef VIRTUAL_DEBUG - lreply(220, "_path_ftpaccess == %s", _path_ftpaccess); - lreply(220, "_path_ftpusers == %s", _path_ftpusers); - lreply(220, "_path_ftphosts == %s", _path_ftphosts); - lreply(220, "_path_private == %s", _path_private); - lreply(220, "_path_cvt == %s", _path_cvt); - if (virtual_mode) { - if (virtual_ftpaccess) - lreply(220, "VIRTUAL Mode: Using %s specific %s access file", - hostname, _path_ftpaccess); - else - lreply(220, "VIRTUAL Mode: Using Master access file %s", - _path_ftpaccess); - - lreply(220, "virtual_root == %s", virtual_root); - if (!virtual_ftpaccess) - lreply(220, "virtual_banner == %s", virtual_banner); - } - lreply(220, "logfile == %s", logfile); -#endif -#endif - - if (is_shutdown(1, 1) != 0) { - syslog(LOG_INFO, "connection refused (server shut down) from %s", - remoteident); - reply(500, "%s FTP server shut down -- please try again later.", - hostname); - exit(0); - } - -#ifdef OPIE - af_pwok = opieaccessfile(remotehost); -#endif - - /* check permitted access based on name and address lookup of remote host */ - if (!check_rhost_reverse()) { - exit(0); - } - if (!check_rhost_matches()) { - exit(0); - } - - show_banner(220); - -#ifndef INTERNAL_LS - entry = (struct aclmember *) NULL; - if (getaclentry("lslong", &entry) && ARG0 && (int) strlen(ARG0) > 0) { - strcpy(ls_long, ARG0); - for (which = 1; (which < MAXARGS) && ARG[which]; which++) { - strcat(ls_long, " "); - strcat(ls_long, ARG[which]); - } - } - else { -#if defined(SVR4) || defined(ISC) -#if defined(AIX) || defined(SOLARIS_2) - strcpy(ls_long, "/bin/ls -lA"); -#else - strcpy(ls_long, "/bin/ls -la"); -#endif -#else - strcpy(ls_long, "/bin/ls -lgA"); -#endif - } - strcat(ls_long, " %s"); - - entry = (struct aclmember *) NULL; - if (getaclentry("lsshort", &entry) && ARG0 && (int) strlen(ARG0) > 0) { - strcpy(ls_short, ARG0); - for (which = 1; (which < MAXARGS) && ARG[which]; which++) { - strcat(ls_short, " "); - strcat(ls_short, ARG[which]); - } - } - else { -#if defined(SVR4) || defined(ISC) -#if defined(AIX) || defined(SOLARIS_2) - strcpy(ls_short, "/bin/ls -lA"); -#else - strcpy(ls_short, "/bin/ls -la"); - -#endif -#else - strcpy(ls_short, "/bin/ls -lgA"); -#endif - } - strcat(ls_short, " %s"); - - entry = (struct aclmember *) NULL; - if (getaclentry("lsplain", &entry) && ARG0 && (int) strlen(ARG0) > 0) { - strcpy(ls_plain, ARG0); - for (which = 1; (which < MAXARGS) && ARG[which]; which++) { - strcat(ls_plain, " "); - strcat(ls_plain, ARG[which]); - } - } - else - strcpy(ls_plain, "/bin/ls"); - strcat(ls_plain, " %s"); -#endif /* ! INTERNAL_LS */ -#ifdef MAIL_ADMIN - mailservers = 0; - entry = (struct aclmember *) NULL; - while (getaclentry("mailserver", &entry) && ARG0 && mailservers < MAILSERVERS) - mailserver[mailservers++] = strdup(ARG0); - if (mailservers == 0) - mailserver[mailservers++] = strdup("localhost"); - if (incmails == 0) { - entry = (struct aclmember *) NULL; - while (getaclentry("incmail", &entry) && ARG0 && incmails < INCMAILS) - incmail[incmails++] = strdup(ARG0); - } - if (mailfrom == NULL) { - entry = (struct aclmember *) NULL; - if (getaclentry("mailfrom", &entry) && ARG0) - mailfrom = strdup(ARG0); - else - mailfrom = strdup("wu-ftpd"); - } -#endif /* MAIL_ADMIN */ - { -#define OUTPUT_LEN (BUFSIZ * 2) - int version_option = 0; - char output_text[OUTPUT_LEN + 1]; - int which; - - entry = NULL; - if (getaclentry("greeting", &entry) && ARG0) { - if (!strcasecmp(ARG0, "full")) - version_option = 0; - else if (!strcasecmp(ARG0, "text") && ARG1) - version_option = 3; - else if (!strcasecmp(ARG0, "terse")) - version_option = 2; - else if (!strcasecmp(ARG0, "brief")) - version_option = 1; - } - switch (version_option) { - default: - reply(220, "%s FTP server (%s) ready.", hostname, version); - break; - case 1: - reply(220, "%s FTP server ready.", hostname); - break; - case 2: - reply(220, "FTP server ready."); - break; - case 3: - output_text[0] = '\0'; - for (which = 1; (which < MAXARGS) && ARG[which]; which++) { - if (which > 1) - (void) strlcat(output_text, " ", sizeof(output_text)); - (void) strlcat(output_text, ARG[which], sizeof(output_text)); - } - reply(220, "%s", output_text); - break; - } - } - (void) setjmp(errcatch); - - for (;;) - (void) yyparse(); - /* NOTREACHED */ -} - - -SIGNAL_TYPE randomsig(int sig) -{ -#ifdef HAVE_SIGLIST - syslog(LOG_ERR, "exiting on signal %d: %s", sig, sys_siglist[sig]); -#else - syslog(LOG_ERR, "exiting on signal %d", sig); -#endif - chdir("/"); - signal(SIGIOT, SIG_DFL); - signal(SIGILL, SIG_DFL); - exit(1); - /* dologout(-1); *//* NOTREACHED */ -} - -SIGNAL_TYPE lostconn(int sig) -{ -#ifdef VERBOSE_ERROR_LOGING - syslog(LOG_INFO, "lost connection to %s", remoteident); -#else - if (debug) - syslog(LOG_DEBUG, "lost connection to %s", remoteident); -#endif - dologout(-1); -} - -static char ttyline[20]; - -#ifdef MAPPING_CHDIR -/* Keep track of the path the user has chdir'd into and respond with - * that to pwd commands. This is to avoid having the absolue disk - * path returned, which I want to avoid. - */ -char mapped_path[MAXPATHLEN] = "/"; - -#if !defined(HAVE_GETCWD) -char *mapping_getwd(char *path) -{ - strcpy(path, mapped_path); - return path; -} -#endif /* !defined(HAVE_GETCWD) */ - -char *mapping_getcwd(char *path, size_t size) -{ - (void) strlcpy(path, mapped_path, size); - return path; -} - -/* Make these globals rather than local to mapping_chdir to avoid stack overflow */ -char pathspace[MAXPATHLEN]; -char old_mapped_path[MAXPATHLEN]; - -void do_elem(char *dir) -{ - /* . */ - if (dir[0] == '.' && dir[1] == '\0') { - /* ignore it */ - return; - } - - /* .. */ - if (dir[0] == '.' && dir[1] == '.' && dir[2] == '\0') { - char *last; - /* lop the last directory off the path */ - if ((last = strrchr(mapped_path, '/'))) { - /* If start of pathname leave the / */ - if (last == mapped_path) - last++; - *last = '\0'; - } - return; - } - - /* append the dir part with a leading / unless at root */ - if (!(mapped_path[0] == '/' && mapped_path[1] == '\0')) - (void) strlcat(mapped_path, "/", sizeof(mapped_path)); - (void) strlcat(mapped_path, dir, sizeof(mapped_path)); -} - -int mapping_chdir(char *orig_path) -{ - int ret; - char *sl, *path; - - (void) strlcpy(old_mapped_path, mapped_path, sizeof(old_mapped_path)); - (void) strlcpy(pathspace, orig_path, sizeof(pathspace)); - path = pathspace; - - /* / at start of path, set the start of the mapped_path to / */ - if (path[0] == '/') { - mapped_path[0] = '/'; - mapped_path[1] = '\0'; - path++; - } - - while ((sl = strchr(path, '/'))) { - char *dir; - dir = path; - *sl = '\0'; - path = sl + 1; - if (*dir) - do_elem(dir); - if (*path == '\0') - break; - } - if (*path) - do_elem(path); - - if ((ret = chdir(mapped_path)) < 0) { - (void) strlcpy(mapped_path, old_mapped_path, sizeof(mapped_path)); - } - - return ret; -} -/* From now on use the mapping version */ - -#define chdir(d) mapping_chdir(d) -#define getwd(d) mapping_getwd(d) -#define getcwd(d,u) mapping_getcwd((d),(u)) - -#endif /* MAPPING_CHDIR */ - -/* Helper function for sgetpwnam(). */ -char *sgetsave(char *s) -{ - char *new; - - new = (char *) malloc(strlen(s) + 1); - - if (new == NULL) { - perror_reply(421, "Local resource failure: malloc"); - dologout(1); - /* NOTREACHED */ - } - (void) strcpy(new, s); - return (new); -} - -/* Save the result of a getpwnam. Used for USER command, since the data - * returned must not be clobbered by any other command (e.g., globbing). */ -struct passwd *sgetpwnam(char *name) -{ - static struct passwd save; - register struct passwd *p; -#ifdef M_UNIX - struct passwd *ret = (struct passwd *) NULL; -#endif - char *sgetsave(char *s); -#ifdef KERBEROS - register struct authorization *q; -#endif /* KERBEROS */ - -#if defined(SecureWare) || defined(HPUX_10_TRUSTED) - struct pr_passwd *pr; -#endif - -#ifdef KERBEROS - init_krb(); - q = getauthuid(p->pw_uid); - end_krb(); -#endif /* KERBEROS */ - -#ifdef M_UNIX -#if defined(SecureWare) || defined(HPUX_10_TRUSTED) - if ((pr = getprpwnam(name)) == NULL) - goto DONE; -#endif /* SecureWare || HPUX_10_TRUSTED */ -#ifdef OTHER_PASSWD - if ((p = bero_getpwnam(name, _path_passwd)) == NULL) -#else - if ((p = getpwnam(name)) == NULL) -#endif - goto DONE; -#else /* M_UNIX */ -#if defined(SecureWare) || defined(HPUX_10_TRUSTED) - if ((pr = getprpwnam(name)) == NULL) - return ((struct passwd *) pr); -#endif /* SecureWare || HPUX_10_TRUSTED */ -#ifdef OTHER_PASSWD - if ((p = bero_getpwnam(name, _path_passwd)) == NULL) -#else - if ((p = getpwnam(name)) == NULL) -#endif - return (p); -#endif /* M_UNIX */ - - if (save.pw_name) - free(save.pw_name); - if (save.pw_gecos) - free(save.pw_gecos); - if (save.pw_dir) - free(save.pw_dir); - if (save.pw_shell) - free(save.pw_shell); - if (save.pw_passwd) - free(save.pw_passwd); - - save = *p; - - save.pw_name = sgetsave(p->pw_name); - -#ifdef KERBEROS - save.pw_passwd = sgetsave(q->a_password); -#elif defined(SecureWare) || defined(HPUX_10_TRUSTED) - if (pr->uflg.fg_encrypt && pr->ufld.fd_encrypt && *pr->ufld.fd_encrypt) - save.pw_passwd = sgetsave(pr->ufld.fd_encrypt); - else - save.pw_passwd = sgetsave(""); -#else - save.pw_passwd = sgetsave(p->pw_passwd); -#endif -#ifdef SHADOW_PASSWORD - if (p && (p->pw_passwd==NULL || strlen(p->pw_passwd)<8)) { - struct spwd *spw; -#ifdef OTHER_PASSWD - if ((spw = bero_getspnam(p->pw_name, _path_shadow)) != NULL) { -#else - setspent(); - if ((spw = getspnam(p->pw_name)) != NULL) { -#endif - int expired = 0; - /*XXX Does this work on all Shadow Password Implementations? */ - /* it is supposed to work on Solaris 2.x */ - time_t now; - long today; - - now = time((time_t *) 0); - today = now / (60 * 60 * 24); - - if ((spw->sp_expire > 0) && (spw->sp_expire < today)) - expired++; - if ((spw->sp_max > 0) && (spw->sp_lstchg > 0) && - (spw->sp_lstchg + spw->sp_max < today)) - expired++; - free(save.pw_passwd); - save.pw_passwd = sgetsave(expired ? "" : spw->sp_pwdp); - } -/* Don't overwrite the password if the shadow read fails, getpwnam() is NIS - aware but getspnam() is not. */ -/* Shadow passwords are optional on Linux. --marekm */ -#if !defined(LINUX) && !defined(UNIXWARE) - else { - free(save.pw_passwd); - save.pw_passwd = sgetsave(""); - } -#endif -/* marekm's fix for linux proc file system shadow passwd exposure problem */ -#ifndef OTHER_PASSWD - endspent(); -#endif - } -#endif - save.pw_gecos = sgetsave(p->pw_gecos); - save.pw_dir = sgetsave(p->pw_dir); - save.pw_shell = sgetsave(p->pw_shell); -#ifdef M_UNIX - ret = &save; - DONE: - endpwent(); -#endif -#if defined(SecureWare) || defined(HPUX_10_TRUSTED) - endprpwent(); -#endif -#ifdef M_UNIX - return (ret); -#else - return (&save); -#endif -} -#if defined(SKEY) && !defined(__NetBSD__) -/* - * From Wietse Venema, Eindhoven University of Technology. - */ -/* skey_challenge - additional password prompt stuff */ - -char *skey_challenge(char *name, struct passwd *pwd, int pwok) -{ - static char buf[128]; - char sbuf[40]; - struct skey skey; - - /* Display s/key challenge where appropriate. */ - - if (pwd == NULL || skeychallenge(&skey, pwd->pw_name, sbuf)) - sprintf(buf, "Password required for %s.", name); - else - sprintf(buf, "%s %s for %s.", sbuf, - pwok ? "allowed" : "required", name); - return (buf); -} -#endif - -int login_attempts; /* number of failed login attempts */ -int askpasswd; /* had user command, ask for passwd */ -#ifndef HELP_CRACKERS -int DenyLoginAfterPassword; -char DelayedMessageFile[MAXPATHLEN]; -extern void pr_mesg(int msgcode, char *msgfile); -#endif - -#if defined(VIRTUAL) && defined(CLOSED_VIRTUAL_SERVER) -static int defaultserver_allow(const char *username) -{ - struct aclmember *entry = NULL; - int which; - - while (getaclentry("defaultserver", &entry)) - if (ARG0 && !strcasecmp(ARG0, "allow")) - for (which = 1; (which < MAXARGS) && ARG[which]; which++) - if (!strcasecmp(username, ARG[which]) || !strcmp("*", ARG[which])) - return (1); - return (0); -} - -static int defaultserver_deny(const char *username) -{ - struct aclmember *entry = NULL; - int which; - - while (getaclentry("defaultserver", &entry)) - if (ARG0 && !strcasecmp(ARG0, "deny")) - for (which = 1; (which < MAXARGS) && ARG[which]; which++) - if (!strcasecmp(username, ARG[which]) || !strcmp("*", ARG[which])) - return (1); - return (0); -} - -static int defaultserver_private(void) -{ - struct aclmember *entry = NULL; - - while (getaclentry("defaultserver", &entry)) - if (ARG0 && !strcasecmp(ARG0, "private")) - return (1); - return (0); -} -#endif - -/* USER command. Sets global passwd pointer pw if named account exists and is - * acceptable; sets askpasswd if a PASS command is expected. If logged in - * previously, need to reset state. If name is "ftp" or "anonymous", the - * name is not in the ftpusers file, and ftp account exists, set anonymous and - * pw, then just return. If account doesn't exist, ask for passwd anyway. - * Otherwise, check user requesting login privileges. Disallow anyone who - * does not have a standard shell as returned by getusershell(). Disallow - * anyone mentioned in the ftpusers file to allow people such as root and - * uucp to be avoided. */ - -/* - char *getusershell(); - */ -void user(char *name) -{ - char *cp; - char *shell; -#ifdef BSD_AUTH - char *auth; -#endif -#if defined(USE_GSS) - int gss_need_passwd = 1; -#endif - -/* H* fix: if we're logged in at all, we can't log in again. */ - if (logged_in) { -#ifdef VERBOSE_ERROR_LOGING - syslog(LOG_NOTICE, "FTP LOGIN REFUSED (already logged in as %s) FROM %s, %s", - pw->pw_name, remoteident, name); -#endif - reply(530, "Already logged in."); - return; - } -#ifndef HELP_CRACKERS - askpasswd = 1; - DenyLoginAfterPassword = 0; - DelayedMessageFile[0] = '\0'; -#endif -#ifdef BSD_AUTH - if ((auth = strchr(name, ':'))) - *auth++ = 0; -#endif - -#ifdef HOST_ACCESS /* 19-Mar-93 BM */ - if (!rhost_ok(name, remotehost, remoteaddr)) { -#ifndef HELP_CRACKERS - DenyLoginAfterPassword = 1; - syslog(LOG_NOTICE, "FTP LOGIN REFUSED (name in %s) FROM %s, %s", - _path_ftphosts, remoteident, name); -#else - reply(530, "User %s access denied.", name); - syslog(LOG_NOTICE, - "FTP LOGIN REFUSED (name in %s) FROM %s, %s", - _path_ftphosts, remoteident, name); - return; -#endif - } -#endif - - strncpy(the_user, name, MAXUSERNAMELEN - 1); - - anonymous = 0; - guest = 0; - - if (!strcasecmp(name, "ftp") || !strcasecmp(name, "anonymous")) { - struct aclmember *entry = NULL; - int machineok = 1; - char guestservername[MAXHOSTNAMELEN]; - guestservername[0] = '\0'; - -#ifdef NO_ANONYMOUS_ACCESS - reply(530, "Anonymous FTP access denied."); - syslog(LOG_NOTICE, "FTP LOGIN REFUSED (anonymous ftp not supported) FROM %s, %s", - remoteident, name); - return; -#else -#if defined(VIRTUAL) && defined(CLOSED_VIRTUAL_SERVER) - if (!virtual_mode && defaultserver_private()) { -#ifndef HELP_CRACKERS - DenyLoginAfterPassword = 1; - syslog(LOG_NOTICE, "FTP LOGIN REFUSED (anonymous ftp denied on default server) FROM %s, %s", - remoteident, name); -#else - reply(530, "User %s access denied.", name); - syslog(LOG_NOTICE, - "FTP LOGIN REFUSED (anonymous ftp denied on default server) FROM %s, %s", - remoteident, name); - return; -#endif - } -#endif - if (checkuser("ftp") || checkuser("anonymous")) { -#ifndef HELP_CRACKERS - DenyLoginAfterPassword = 1; - syslog(LOG_NOTICE, "FTP LOGIN REFUSED (ftp in %s) FROM %s, %s", - _path_ftpusers, remoteident, name); -#else - reply(530, "User %s access denied.", name); - syslog(LOG_NOTICE, - "FTP LOGIN REFUSED (ftp in %s) FROM %s, %s", - _path_ftpusers, remoteident, name); - return; -#endif - - /* - ** Algorithm used: - ** - if no "guestserver" directive is present, - ** anonymous access is allowed, for backward compatibility. - ** - if a "guestserver" directive is present, - ** anonymous access is restricted to the machines listed, - ** usually the machine whose CNAME on the current domain - ** is "ftp"... - ** - ** the format of the "guestserver" line is - ** guestserver [ []] - ** that is, "guestserver" will forbid anonymous access on all machines - ** while "guestserver ftp inf" will allow anonymous access on - ** the two machines whose CNAMES are "ftp.enst.fr" and "inf.enst.fr". - ** - ** if anonymous access is denied on the current machine, - ** the user will be asked to use the first machine listed (if any) - ** on the "guestserver" line instead: - ** 530- Guest login not allowed on this machine, - ** connect to ftp.enst.fr instead. - ** - ** -- - */ - } - else if (getaclentry("guestserver", &entry)) { - char *tmphost; - - /* - ** if a "guestserver" line is present, - ** default is not to allow guest logins - */ - machineok = 0; - - if (hostname[0] - && ((tmphost = wu_gethostbyname(hostname)))) { - - /* - ** hostname is the only first part of the FQDN - ** this may or may not correspond to the h_name value - ** (machines with more than one IP#, CNAMEs...) - ** -> need to fix that, calling gethostbyname on hostname - ** - ** WARNING! - ** for SunOS 4.x, you need to have a working resolver in the libc - ** for CNAMES to work properly. - ** If you don't, add "-lresolv" to the libraries before compiling! - */ - char dns_localhost[MAXHOSTNAMELEN]; - int machinecount; - - strncpy(dns_localhost, tmphost, sizeof(dns_localhost)); - dns_localhost[sizeof(dns_localhost) - 1] = '\0'; - - for (machinecount = 0; - (machinecount < MAXARGS) && entry->arg[machinecount]; - machinecount++) { - - if ((tmphost = wu_gethostbyname(entry->arg[machinecount]))) { - /* - ** remember the name of the first machine for redirection - */ - - if (!machinecount) { - strncpy(guestservername, entry->arg[machinecount], - sizeof(guestservername)); - guestservername[sizeof(guestservername) - 1] = '\0'; - } - - if (!strcasecmp(tmphost, dns_localhost)) { - machineok++; - break; - } - } - } - } - } - if (!machineok) { - if (guestservername[0]) - reply(530, - "Guest login not allowed on this machine, connect to %s instead.", - guestservername); - else - reply(530, - "Guest login not allowed on this machine."); - syslog(LOG_NOTICE, - "FTP LOGIN REFUSED (localhost not in guestservers) FROM %s, %s", - remoteident, name); - /* End of the big patch -- Nap */ - - dologout(0); - } - else if ((pw = sgetpwnam("ftp")) != NULL) { - anonymous = 1; /* for the access_ok call */ - if (access_ok(530) < 1) { -#ifndef HELP_CRACKERS - DenyLoginAfterPassword = 1; - syslog(LOG_NOTICE, "FTP LOGIN REFUSED (access denied) FROM %s, %s", - remoteident, name); - reply(331, "Guest login ok, send your complete e-mail address as password."); -#else - reply(530, "User %s access denied.", name); - syslog(LOG_NOTICE, - "FTP LOGIN REFUSED (access denied) FROM %s, %s", - remoteident, name); - dologout(0); -#endif - } - else { - askpasswd = 1; -/* H* fix: obey use_accessfile a little better. This way, things set on the - command line [like xferlog stuff] don't get stupidly overridden. - XXX: all these checks maybe should be in acl.c and access.c */ - if (use_accessfile) - acl_setfunctions(); - reply(331, "Guest login ok, send your complete e-mail address as password."); - } - } - else { -#ifndef HELP_CRACKERS - DenyLoginAfterPassword = 1; - reply(331, "Guest login ok, send your complete e-mail address as password."); - syslog(LOG_NOTICE, "FTP LOGIN REFUSED (ftp not in /etc/passwd) FROM %s, %s", - remoteident, name); -#else - reply(530, "User %s unknown.", name); - syslog(LOG_NOTICE, - "FTP LOGIN REFUSED (ftp not in /etc/passwd) FROM %s, %s", - remoteident, name); -#endif -#ifdef SOLARIS_BSM_AUDIT - audit_ftpd_no_anon(); -#endif - } - return; -#endif - } -#ifdef ANON_ONLY -/* H* fix: define the above to completely DISABLE logins by real users, - despite ftpusers, shells, or any of that rot. You can always hang your - "real" server off some other port, and access-control it. */ - - else { /* "ftp" or "anon" -- MARK your conditionals, okay?! */ -#ifndef HELP_CRACKERS - DenyLoginAfterPassword = 1; - syslog(LOG_NOTICE, "FTP LOGIN REFUSED (not anonymous) FROM %s, %s", - remoteident, name); - reply(331, "Password required for %s.", name); -#else - reply(530, "User %s unknown.", name); - syslog(LOG_NOTICE, - "FTP LOGIN REFUSED (not anonymous) FROM %s, %s", - remoteident, name); -#endif - return; - } -/* fall here if username okay in any case */ -#endif /* ANON_ONLY */ - -#if defined(VIRTUAL) && defined(CLOSED_VIRTUAL_SERVER) - if (!virtual_mode && defaultserver_deny(name) && !defaultserver_allow(name)) { -#ifndef HELP_CRACKERS - DenyLoginAfterPassword = 1; - syslog(LOG_NOTICE, "FTP LOGIN REFUSED (ftp denied on default server) FROM %s, %s", - remoteident, name); -#else - reply(530, "User %s access denied.", name); - syslog(LOG_NOTICE, - "FTP LOGIN REFUSED (ftp denied on default server) FROM %s, %s", - remoteident, name); - return; -#endif - } -#endif - -#if defined(USE_GSS) - if (gss_info.must_gss_auth && - (!IS_GSSAUTH(cur_auth_type) || - !(gss_info.authstate & GSS_ADAT_DONE))) { - reply(530, "Must perform authentication before identifying USER."); - return; - } -#endif /* USE_GSS */ - - if ((pw = sgetpwnam(name)) != NULL) { - if ((denieduid(pw->pw_uid) && !alloweduid(pw->pw_uid)) - || (deniedgid(pw->pw_gid) && !allowedgid(pw->pw_gid))) { -#ifndef HELP_CRACKERS - DenyLoginAfterPassword = 1; - syslog(LOG_NOTICE, "FTP LOGIN REFUSED (username in denied-uid) FROM %s, %s", - remoteident, name); - reply(331, "Password required for %s.", name); -#else - reply(530, "User %s access denied.", name); - syslog(LOG_NOTICE, - "FTP LOGIN REFUSED (username in denied-uid) FROM %s, %s", - remoteident, name); -#endif - return; - } -#if defined(USE_GSS) - if (IS_GSSAUTH(cur_auth_type) && - (gss_info.authstate & GSS_ADAT_DONE)) { - char buf[BUFSIZ]; - - if (gss_user(pw)) - gss_info.authstate |= GSS_USER_DONE; - - if (gss_info.must_gss_auth && - !GSSUSERAUTH_OK(gss_info)) { - reply(530, "User %s access denied", name); - if (logging) - syslog(LOG_NOTICE, "FTP GSSAPI LOGIN REFUSED FROM %s, %s", - remoteident, name); - pw = NULL; - return; - } - /* - * If GSSAPI user auth failed, or it succeeded but creds were - * not forwarded as required, prompt for password. - */ - gss_need_passwd = !GSSUSERAUTH_OK(gss_info) || - (GSSUSERAUTH_OK(gss_info) && - (gss_info.want_creds && !gss_info.have_creds)); - if (gss_need_passwd) { - snprintf(buf, sizeof(buf), - "GSSAPI user %s is authorized as %s password required", - gss_info.display_name, name); - reply(331, "%s", buf); - askpasswd = 1; - syslog(LOG_DEBUG, "%s", buf); - return; - } - } -#endif /* defined(USE_GSS) */ - -#if !defined(USE_PAM) || (defined(USE_PAM) && defined(OTHER_PASSWD)) || defined(SOLARIS_2) /* PAM should be doing these checks, not ftpd */ -#if defined(USE_PAM) && !defined(SOLARIS_2) - if(!use_pam) { -#endif - if ((shell = pw->pw_shell) == NULL || *shell == 0) - shell = _PATH_BSHELL; - while ((cp = getusershell()) != NULL) - if (strcmp(cp, shell) == 0) - break; - endusershell(); - if (cp == NULL || checkuser(name)) { -#ifndef HELP_CRACKERS - DenyLoginAfterPassword = 1; - if (cp == NULL) - syslog(LOG_NOTICE, "FTP LOGIN REFUSED (shell not in /etc/shells) FROM %s, %s", remoteident, name); - else - syslog(LOG_NOTICE, "FTP LOGIN REFUSED (username in %s) FROM %s, %s", _path_ftpusers, remoteident, name); - reply(331, "Password required for %s.", name); -#else - reply(530, "User %s access denied.", name); - if (cp == NULL) - syslog(LOG_NOTICE, "FTP LOGIN REFUSED (shell not in /etc/shells) FROM %s, %s", remoteident, name); - else - syslog(LOG_NOTICE, "FTP LOGIN REFUSED (username in %s) FROM %s, %s", _path_ftpusers, remoteident, name); -#endif /* HELP_CRACKERS */ - pw = (struct passwd *) NULL; - return; - } -#if defined(USE_PAM) && !defined(SOLARIS_2) - } /* if(!use_pam) */ -#endif -#endif /* !USE_PAM || (USE_PAM && OTHER_PASSWD) || SOLARIS_2 */ - /* if user is a member of any of the guestgroups, cause a chroot() */ - /* after they log in successfully */ - if (use_accessfile) { /* see above. _H */ - guest = acl_guestgroup(pw); - if (guest && acl_realgroup(pw)) - guest = 0; - } - } - if (access_ok(530) < 1) { -#ifndef HELP_CRACKERS - DenyLoginAfterPassword = 1; - syslog(LOG_NOTICE, "FTP LOGIN REFUSED (access denied) FROM %s, %s", - remoteident, name); - reply(331, "Password required for %s.", name); -#else - reply(530, "User %s access denied.", name); - syslog(LOG_NOTICE, "FTP LOGIN REFUSED (access denied) FROM %s, %s", - remoteident, name); -#endif - return; - } - else if (use_accessfile) /* see above. _H */ - acl_setfunctions(); - -#ifdef BSD_AUTH - if ((cp = start_auth(auth, name, pw)) != NULL) { - char *s; - - for (;;) { - s = strsep(&cp, "\n"); - if (cp == NULL || *cp == '\0') - break; - lreply(331, "%s", s); - } - reply(331, "%s", s); - } - else { -#endif /* BSD_AUTH */ -#ifdef SKEY -#ifndef __NetBSD__ -#ifdef SKEY_NAME - /* this is the old way, but freebsd uses it */ - pwok = skeyaccess(name, NULL, remotehost, remoteaddr); -#else - /* this is the new way */ - pwok = skeyaccess(pw, NULL, remotehost, remoteaddr); -#endif /* SKEY_NAME */ - reply(331, "%s", skey_challenge(name, pw, pwok)); -#else - if (skey_haskey(name) == 0) { - char *myskey; - - myskey = skey_keyinfo(name); - reply(331, "Password [%s] required for %s.", - myskey ? myskey : "error getting challenge", name); - } - else - reply(331, "Password required for %s.", name); -#endif /* __NetBSD__ */ -#else -#ifdef OPIE - { - char prompt[OPIE_CHALLENGE_MAX + 1]; - opiechallenge(&opiestate, name, prompt); - - if (askpasswd == -1) { - syslog(LOG_WARNING, "Invalid FTP user name %s attempted from %s", name, remotehost); - pwok = 0; - } - else - pwok = af_pwok && opiealways(pw->pw_dir); - reply(331, "Response to %s %s for %s.", - prompt, pwok ? "requested" : "required", name); - } -#else /* !SKEY */ - -#if defined(USE_GSS) - if (GSSUSERAUTH_OK(gss_info) && !gss_need_passwd) { - /* - * We got this far, we are allowing the GSSAPI authentication - * to succeed without further passwd prompting. Jump - * to "pass" processing. - */ - askpasswd = 0; - logged_in = 1; - pass(""); - return; - } -#endif /* defined(USE_GSS) */ - reply(331, "Password required for %s.", name); -#endif /* OPIE */ -#endif /* SKEY */ -#ifdef BSD_AUTH - } -#endif /* BSD_AUTH */ - - askpasswd = 1; - /* Delay before reading passwd after first failed attempt to slow down - * passwd-guessing programs. */ - if (login_attempts) { - enable_signaling(); /* we can allow signals once again: kinch */ - sleep((unsigned) login_attempts); - } - return; -} - -/* Check if a user is in the ftpusers file */ -int checkuser(char *name) -{ - register FILE *fd; - register char *p; - char line[BUFSIZ]; - -#ifdef SOLARIS_ETC_FTPUSERS - static int etc_ftpusers = 0; - - if (etc_ftpusers) { - strcpy(_path_ftpusers, _PATH_FTPUSERS); - etc_ftpusers = 0; - } -retry: -#endif - if ((fd = fopen(_path_ftpusers, "r")) != NULL) { - while (fgets(line, sizeof(line), fd) != NULL) - if ((p = strchr(line, '\n')) != NULL) { - *p = '\0'; - if (line[0] == '#') - continue; - if (strcasecmp(line, name) == 0) { - (void) fclose(fd); -#ifdef SOLARIS_BSM_AUDIT - audit_ftpd_excluded(name); -#endif -#ifdef SOLARIS_ETC_FTPUSERS - if (etc_ftpusers) - syslog(LOG_NOTICE, "%s is deprecated, use %s instead", _path_ftpusers, _PATH_FTPUSERS); -#endif - return (1); - } - } - (void) fclose(fd); - } -#ifdef SOLARIS_ETC_FTPUSERS - if (!etc_ftpusers && (strcmp(_path_ftpusers, _PATH_FTPUSERS) == 0)) { - strcpy(_path_ftpusers, "/etc/ftpusers"); - etc_ftpusers = 1; - goto retry; - } -#endif - return (0); -} - -int uid_match(char *keyword, uid_t uid) -{ - struct aclmember *entry = NULL; - int which; - char *ptr; - struct passwd *pw; - - /* - * keyword [ ...] - * - * uid-range may be a username or begin with '%' and be treated as numeric: - * % A single numeric UID - * %+ All UIDs greater or equal to UID - * %- All UIDs greater or equal to UID - * %- All UIDs less or equal to UID - * %- All UIDs between the two (inclusive) - * * All UIDs - */ - while (getaclentry(keyword, &entry)) { - for (which = 0; (which < MAXARGS) && ARG[which]; which++) { - if (!strcmp(ARG[which], "*")) - return (1); - if (ARG[which][0] == '%') { - if ((ptr = strchr(ARG[which] + 1, '-')) == NULL) { - if ((ptr = strchr(ARG[which] + 1, '+')) == NULL) { - if (uid == strtoul(ARG[which] + 1, NULL, 0)) - return (1); - } - else { - *ptr++ = '\0'; - if ((ARG[which][1] == '\0') - || (uid >= strtoul(ARG[which] + 1, NULL, 0))) { - *--ptr = '+'; - return (1); - } - *--ptr = '+'; - } - } - else { - *ptr++ = '\0'; - if (((ARG[which][1] == '\0') - || (uid >= strtoul(ARG[which] + 1, NULL, 0))) - && ((*ptr == '\0') - || (uid <= strtoul(ptr, NULL, 0)))) { - *--ptr = '-'; - return (1); - } - *--ptr = '-'; - } - } - else { -#ifdef OTHER_PASSWD - pw = bero_getpwnam(ARG[which], _path_passwd); -#else - pw = getpwnam(ARG[which]); -#endif - if (pw && (uid == pw->pw_uid)) - return (1); - } - } - } - return (0); -} - -int gid_match(char *keyword, gid_t gid, char *username) -{ - struct aclmember *entry = NULL; - int which; - char *ptr; - struct group *grp; - char **member; - - /* - * keyword [ ...] - * - * gid-range may be a groupname or begin with '%' and be treated as numeric: - * % A single GID - * %+ All GIDs greater or equal to GID - * %- All GIDs greater or equal to GID - * %- All GIDs less or equal to GID - * %- All GIDs between the two (inclusive) - * * All GIDs - */ - while (getaclentry(keyword, &entry)) { - for (which = 0; (which < MAXARGS) && ARG[which]; which++) { - if (!strcmp(ARG[which], "*")) - return (1); - if (ARG[which][0] == '%') { - if ((ptr = strchr(ARG[which] + 1, '-')) == NULL) { - if ((ptr = strchr(ARG[which] + 1, '+')) == NULL) { - if (gid == strtoul(ARG[which] + 1, NULL, 0)) - return (1); - } - else { - *ptr++ = '\0'; - if ((ARG[which][1] == '\0') - || (gid >= strtoul(ARG[which] + 1, NULL, 0))) { - *--ptr = '+'; - return (1); - } - *--ptr = '+'; - } - } - else { - *ptr++ = '\0'; - if (((ARG[which][1] == '\0') - || (gid >= strtoul(ARG[which] + 1, NULL, 0))) - && ((*ptr == '\0') - || (gid <= strtoul(ptr, NULL, 0)))) { - *--ptr = '-'; - return (1); - } - *--ptr = '-'; - } - } - else { - if ((grp = getgrnam(ARG[which]))) { - if (gid == grp->gr_gid) - return (1); - if (username) { - for (member = grp->gr_mem; *member; member++) - if (!strcasecmp(*member, username)) - return (1); - } - } - } - } - } - return (0); -} - -int denieduid(uid_t uid) -{ - return uid_match("deny-uid", uid); -} - -int alloweduid(uid_t uid) -{ - return uid_match("allow-uid", uid); -} - -int deniedgid(gid_t gid) -{ - return gid_match("deny-gid", gid, NULL); -} - -int allowedgid(gid_t gid) -{ - return gid_match("allow-gid", gid, NULL); -} - -/* Terminate login as previous user, if any, resetting state; used when USER - * command is given or login fails. */ - -void end_login(void) -{ - delay_signaling(); /* we can't allow any signals while euid==0: kinch */ - (void) seteuid((uid_t) 0); - if (logged_in) { - if (wtmp_logging) - wu_logwtmp(ttyline, pw->pw_name, remotehost, 0); -#ifdef USE_PAM - if (!anonymous && pamh) { - (void) pam_close_session(pamh, 0); - (void) pam_end(pamh, PAM_SUCCESS); - pamh = (pam_handle_t *)0; - } -#endif - } - pw = NULL; -#ifdef AFS_AUTH - ktc_ForgetAllTokens(); -#endif - logged_in = 0; - anonymous = 0; - guest = 0; -} - -int validate_eaddr(char *eaddr) -{ - int i, host, state; - - for (i = host = state = 0; eaddr[i] != '\0'; i++) { - switch (eaddr[i]) { - case '.': - if (!host) - return 0; - if (state == 2) - state = 3; - host = 0; - break; - case '@': - if (!host || state > 1 || !strncasecmp("ftp", eaddr + i - host, host)) - return 0; - state = 2; - host = 0; - break; - case '!': - case '%': - if (!host || state > 1) - return 0; - state = 1; - host = 0; - break; - case '-': - break; - default: - host++; - } - } - if (((state == 3) && host > 1) || ((state == 1) && host > 1)) - return 1; - else - return 0; -} - - -#if defined(VIRTUAL) && defined(CLOSED_VIRTUAL_SERVER) -static int AllowVirtualUser(const char *username) -{ - struct aclmember *entry = NULL; - int which; - - while (getaclentry("virtual", &entry)) - if (ARG0 && hostmatch(ARG0, virtual_address, virtual_hostname) - && ARG1 && !strcasecmp(ARG1, "allow")) - for (which = 2; (which < MAXARGS) && ARG[which]; which++) - if (!strcasecmp(username, ARG[which]) || !strcmp("*", ARG[which])) - return (1); - return (0); -} - -static int DenyVirtualUser(const char *username) -{ - struct aclmember *entry = NULL; - int which; - - while (getaclentry("virtual", &entry)) - if (ARG0 && hostmatch(ARG0, virtual_address, virtual_hostname) - && ARG1 && !strcasecmp(ARG1, "deny")) - for (which = 2; (which < MAXARGS) && ARG[which]; which++) - if (!strcasecmp(username, ARG[which]) || !strcmp("*", ARG[which])) - return (1); - return (0); -} - -static int DenyVirtualAnonymous(void) -{ - struct aclmember *entry = NULL; - - while (getaclentry("virtual", &entry)) - if (ARG0 && hostmatch(ARG0, virtual_address, virtual_hostname) - && ARG1 && !strcasecmp(ARG1, "private")) - return (1); - return (0); -} -#endif - -void pass(char *passwd) -{ - -#if !defined(USE_PAM) || (defined(USE_PAM) && defined(OTHER_PASSWD)) - char *xpasswd, *salt; -#endif - - int passwarn = 0; - int rval = 1; - int success_code = 230; - int cos; - -#ifdef SECUREOSF - struct pr_passwd *pr; - int crypt_alg = 0; -#endif - -#ifdef BSD_AUTH - extern int ext_auth; - extern char *check_auth(); -#endif - -#ifdef ULTRIX_AUTH - int numfails; -#endif /* ULTRIX_AUTH */ - -#ifdef HAS_PW_EXPIRE - int set_expired = FALSE; -#endif - -#ifdef AFS_AUTH - char *reason; -#endif /* AFS_AUTH */ - -#ifdef DCE_AUTH - sec_passwd_rec_t pwr; - sec_login_handle_t lhdl; - boolean32 rstpwd; - sec_login_auth_src_t asrc; - error_status_t status; -#endif /* DCE_AUTH */ - -#if defined(USE_GSS) - /* - * LOGIC: - * If [ the user presented GSSAPI creds and was authorized ] - * jump down past the password validation code. - */ - if (GSSUSERAUTH_OK(gss_info) && logged_in) { - /* - * We could reply(202, "PASS command superfluous.") here, but - * allow this for compat with some clients. - */ - success_code = 232; - goto pwd_validation_done; - } -#endif /* defined(USE_GSS) */ - - if (logged_in || askpasswd == 0) { -#ifdef VERBOSE_ERROR_LOGING - syslog(LOG_NOTICE, "FTP LOGIN REFUSED (PASS before USER) FROM %s", - remoteident); -#endif - reply(503, "Login with USER first."); - return; - } - askpasswd = 0; - - /* Disable lreply() if the first character of the password is '-' since - * some hosts don't understand continuation messages and hang... */ - - if (*passwd == '-') - dolreplies = 0; - else - dolreplies = 1; -/* ******** REGULAR/GUEST USER PASSWORD PROCESSING ********** */ - if (!anonymous) { /* "ftp" is only account allowed no password */ -#ifndef HELP_CRACKERS - if (DenyLoginAfterPassword) { - pr_mesg(530, DelayedMessageFile); - reply(530, "Login incorrect."); -#ifdef SOLARIS_BSM_AUDIT - audit_ftpd_failure(the_user); -#endif - acl_remove(); - pw = NULL; - if (++login_attempts >= lgi_failure_threshold) { - syslog(LOG_NOTICE, "repeated login failures from %s", - remoteident); - exit(0); - } - return; - } -#endif - if (*passwd == '-') - passwd++; -#ifdef USE_PAM -#ifdef OTHER_PASSWD - if (use_pam -#if defined(USE_GSS) - && !GSSUSERAUTH_OK(gss_info) -#endif - ) { -#endif - /* PAM authentication - * If PAM authenticates a user we know nothing about on the local - * system, use the generic guest account credentials. We should make - * this somehow a configurable item somewhere; later more on that. - * - * For now assume the guest (not anonymous) identity, so the site - * admins can still differentiate between the truw anonymous user and - * a little bit more special ones. Otherwise he wouldn't go the extra - * mile to have a different user database, right? - * --gaftonc */ - if (pam_check_pass(the_user, passwd)) { - rval = 0; - if (pw == NULL) { - /* assume guest account identity */ - pw = sgetpwnam("ftp"); - anonymous = 0; - guest = 1; - /* even go as far as... */ - if (pw != NULL && pw->pw_name != NULL) { - free(pw->pw_name); - pw->pw_name = sgetsave(the_user); - } - } - } -#ifdef OTHER_PASSWD - } else { -#endif -#endif /* USE_PAM */ -#if !defined(USE_PAM) || (defined(USE_PAM) && defined(OTHER_PASSWD)) -#ifdef BSD_AUTH - if (ext_auth) { - if ((salt = check_auth(the_user, passwd))) { - reply(530, "%s", salt); -#ifdef LOG_FAILED /* 27-Apr-93 EHK/BM */ - /* - * To avoid logging passwords mistakenly entered as - * usernames, only log the names of users which exist. - */ - syslog(LOG_INFO, "failed login from %s, %s", remoteident, - (pw == NULL) ? "[unknown]" : the_user); -#endif /* LOG_FAILED */ - acl_remove(); - pw = NULL; - if (++login_attempts >= lgi_failure_threshold) { - syslog(LOG_NOTICE, "repeated login failures from %s", - remoteident); - exit(0); - } - return; - } - } - else { -#endif /* BSD_AUTH */ - *guestpw = '\0'; - if (pw == NULL) - salt = "xx"; - else -#ifndef OPIE - salt = pw->pw_passwd; -#ifdef SECUREOSF - if ((pr = getprpwnam(pw->pw_name)) != NULL) { - if (pr->uflg.fg_newcrypt) - crypt_alg = pr->ufld.fd_newcrypt; - else if (pr->sflg.fg_newcrypt) - crypt_alg = pr->sfld.fd_newcrypt; - else - crypt_alg = 0; - } - else - crypt_alg = 0; - - xpasswd = dispcrypt(passwd, salt, crypt_alg); -#elif defined(SecureWare) || defined(HPUX_10_TRUSTED) - xpasswd = bigcrypt(passwd, salt); -#elif defined(KERBEROS) - xpasswd = crypt16(passwd, salt); -#elif defined(SKEY) -#ifndef __NetBSD__ - xpasswd = skey_crypt(passwd, salt, pw, pwok); - pwok = 0; -#else - if ((pw != NULL) && (pw->pw_name != NULL) && skey_haskey(pw->pw_name) == 0 && - skey_passcheck(pw->pw_name, passwd) != -1) - xpasswd = pw->pw_passwd; - else - xpasswd = crypt(passwd, salt); -#endif -#else /* !SKEY */ - xpasswd = crypt(passwd, salt); -#endif /* SKEY */ -#else /* OPIE */ - if (!opieverify(&opiestate, passwd)) - rval = 0; - xpasswd = crypt(passwd, pw->pw_passwd); -#endif /* OPIE */ -#ifdef ULTRIX_AUTH - if ((numfails = ultrix_check_pass(passwd, xpasswd)) >= 0) { -#else - if (pw != NULL) { -#ifdef AFS_AUTH - if (strcmp(pw->pw_passwd, "X") == 0) - if (ka_UserAuthenticateGeneral(KA_USERAUTH_VERSION | KA_USERAUTH_DOSETPAG, pw->pw_name, "", 0, passwd, 0, 0, 0, &reason) == 0) - rval = 0; - else - printf("230-AFS: %s", reason); - else -#endif /* AFS_AUTH */ - /* The strcmp does not catch null passwords! */ -#ifdef HAS_PW_EXPIRE - if(pw->pw_expire != NULL) { - if(pw->pw_expire && time(NULL) >= pw->pw_expire) { - set_expired = TRUE; - } - } -#endif - - if (*pw->pw_passwd != '\0' && -#ifdef HAS_PW_EXPIRE - !set_expired && -#endif - strcmp(xpasswd, pw->pw_passwd) == 0) { -#endif - rval = 0; - } -#ifdef DCE_AUTH -#ifndef ALWAYS_TRY_DCE - else -#endif /* ALWAYS_TRY_DCE */ - { - sec_login_setup_identity((unsigned_char_p_t) pw->pw_name, sec_login_no_flags, &lhdl, &status); - if (status == error_status_ok) { - printf("230-sec_login_setup_identity OK\n"); - pwr.key.tagged_union.plain = (idl_char *) passwd; - pwr.key.key_type = sec_passwd_plain; - pwr.pepper = 0; - pwr.version_number = sec_passwd_c_version_none; - /* validate password with login context */ - sec_login_valid_and_cert_ident(lhdl, &pwr, &rstpwd, &asrc, &status); - if (!rstpwd && (asrc == sec_login_auth_src_network) && (status == error_status_ok)) { - printf("230-sec_login_valid_and_cert_ident OK\n"); - sec_login_set_context(lhdl, &status); - printf("230-sec_login_set_context finished\n"); - if (status != error_status_ok) { - int pstatus; - dce_error_string_t s; - printf("230-Error status: %d:\n", status); - dce_error_inq_text(status, s, &pstatus); - printf("230-%s\n", s); - fflush(stderr); - sec_login_purge_context(lhdl, &status); - } - else { - /*sec_login_get_pwent(lhdl, &pw, &status); */ - rval = 0; - } - } - } - } -#endif /* DCE_AUTH */ - } -#ifdef USE_PAM - } -#endif -#endif /* !USE_PAM || (USE_PAM && OTHER_PASSWD) */ - if (rval) { - reply(530, "Login incorrect."); - -#ifdef LOG_FAILED /* 27-Apr-93 EHK/BM */ -/* H* add-on: yell about attempts to use the trojan. This may alarm you - if you're "stringsing" the binary and you see "NULL" pop out in just - about the same place as it would have in 2.2c! */ - if (!strcasecmp(passwd, "NULL")) - syslog(LOG_NOTICE, "REFUSED \"NULL\" from %s, %s", - remoteident, the_user); - else { - /* - * To avoid logging passwords mistakenly entered as - * usernames, only log the names of users which exist. - */ - syslog(LOG_INFO, "failed login from %s, %s", remoteident, - (pw == NULL) ? "[unknown]" : the_user); - } -#endif -#ifdef SOLARIS_BSM_AUDIT - audit_ftpd_failure(the_user); -#endif - acl_remove(); - - pw = NULL; - if (++login_attempts >= lgi_failure_threshold) { - syslog(LOG_NOTICE, "repeated login failures from %s", - remoteident); - exit(0); - } - return; - } -#ifdef BSD_AUTH - } -#endif -/* ANONYMOUS USER PROCESSING STARTS HERE */ - } - else { - char *pwin, *pwout = guestpw; - struct aclmember *entry = NULL; - int valid; - int enforce = 0; - - if (getaclentry("passwd-check", &entry) && - ARG0 && strcasecmp(ARG0, "none")) { - - if (!strcasecmp(ARG0, "rfc822")) - valid = validate_eaddr(passwd); - else if (!strcasecmp(ARG0, "trivial")) - valid = (strchr(passwd, '@') == NULL) ? 0 : 1; - else - valid = 1; - if (ARG1 && !strcasecmp(ARG1, "enforce")) - enforce = 1; - /* Block off "default" responses like mozilla@ and IE30User@ - * (at the administrator's discretion). --AC - */ - entry = NULL; - while (getaclentry("deny-email", &entry)) { - if (ARG0 - && ((strcasecmp(passwd, ARG0) == 0) - || regexmatch(passwd, ARG0) - || ((*passwd == '-') - && ((strcasecmp(passwd + 1, ARG0) == 0) - || regexmatch(passwd + 1, ARG0))))) { - valid = 0; - break; - } - } - if (!valid && enforce) { - lreply(530, "The response '%s' is not valid", passwd); - lreply(530, "Please use your e-mail address as your password"); - lreply(530, " for example: %s@%s%s", - authenticated ? authuser : "joe", remotehost, - strchr(remotehost, '.') ? "" : ".network"); - reply(530, "Login incorrect."); -#ifdef VERBOSE_ERROR_LOGING - syslog(LOG_NOTICE, "FTP ACCESS REFUSED (anonymous password not rfc822) from %s", - remoteident); -#endif -#ifdef SOLARIS_BSM_AUDIT - audit_ftpd_bad_pw(the_user); -#endif - acl_remove(); - if (++login_attempts >= lgi_failure_threshold) { - syslog(LOG_NOTICE, "repeated login failures from %s", - remoteident); - exit(0); - } - return; - } - else if (!valid) - passwarn = 1; - } - if (!*passwd) { - strcpy(guestpw, "[none_given]"); - } - else { - int cnt = sizeof(guestpw) - 2; - - for (pwin = passwd; *pwin && cnt--; pwin++) - if (!isgraph(*pwin)) - *pwout++ = '_'; - else - *pwout++ = *pwin; - } -#ifndef HELP_CRACKERS - if (DenyLoginAfterPassword) { - pr_mesg(530, DelayedMessageFile); - reply(530, "Login incorrect."); -#ifdef SOLARIS_BSM_AUDIT - audit_ftpd_failure(the_user); -#endif - acl_remove(); - pw = NULL; - if (++login_attempts >= lgi_failure_threshold) { - syslog(LOG_NOTICE, "repeated login failures from %s", - remoteident); - exit(0); - } - return; - } -#endif - } - -#if defined(USE_GSS) -pwd_validation_done: -#endif /* USE_GSS */ - /* if logging is enabled, open logfile before chroot or set group ID */ - if ((log_outbound_xfers || log_incoming_xfers) && (syslogmsg != 1)) { - mode_t oldmask; - oldmask = umask(0); - xferlog = open(logfile, O_WRONLY | O_APPEND | O_CREAT, 0640); - (void) umask(oldmask); - if (xferlog < 0) { - syslog(LOG_ERR, "cannot open logfile %s: %s", logfile, - strerror(errno)); - xferlog = 0; - } - } - -#ifdef DEBUG -/* I had a lot of trouble getting xferlog working, because of two factors: - acl_setfunctions making stupid assumptions, and sprintf LOSING. _H */ -/* - * Actually, sprintf was not losing, but the rules changed... next release - * this will be fixed the correct way, but right now, it works well enough - * -- sob - */ - syslog(LOG_INFO, "-i %d,-o %d,xferlog %s: %d", - log_incoming_xfers, log_outbound_xfers, logfile, xferlog); -#endif - enable_signaling(); /* we can allow signals once again: kinch */ - /* if autogroup command applies to user's class change pw->pw_gid */ - if (anonymous && use_accessfile) { /* see above. _H */ - (void) acl_autogroup(pw); - guest = acl_guestgroup(pw); /* the new group may be a guest */ - if (guest && acl_realgroup(pw)) - guest = 0; - anonymous = !guest; - } -/* END AUTHENTICATION */ - -/* SET GROUP ID STARTS HERE */ -#ifndef AIX - (void) setegid((gid_t) pw->pw_gid); -#else - (void) setgid((gid_t) pw->pw_gid); -#endif - (void) initgroups(pw->pw_name, pw->pw_gid); -#ifdef DEBUG - syslog(LOG_DEBUG, "initgroups has been called"); -#endif -/* WTMP PROCESSING STARTS HERE */ - if (wtmp_logging) { - /* open wtmp before chroot */ -#if ((defined(BSD) && (BSD >= 199103)) || defined(sun)) - (void) sprintf(ttyline, "ftp%ld", (long) getpid()); -#else - (void) sprintf(ttyline, "ftpd%d", getpid()); -#endif -#ifdef DEBUG - syslog(LOG_DEBUG, "about to call wtmp"); -#endif - wu_logwtmp(ttyline, pw->pw_name, remotehost, 1); - } - logged_in = 1; - - expand_id(); - -#ifdef QUOTA - memset("a, 0, sizeof(quota)); - get_quota(pw->pw_dir, pw->pw_uid); -#endif - - restricted_user = 0; - if (!anonymous) - if ((restricteduid(pw->pw_uid) && !unrestricteduid(pw->pw_uid)) - || (restrictedgid(pw->pw_gid) && !unrestrictedgid(pw->pw_gid))) - restricted_user = 1; - if (anonymous || guest) { - char *sp; - /* We MUST do a chdir() after the chroot. Otherwise the old current - * directory will be accessible as "." outside the new root! */ -#ifdef ALTERNATE_CD - home = defhome; -#endif -#ifdef VIRTUAL - if (virtual_mode && !guest) { -#ifdef CLOSED_VIRTUAL_SERVER - if (DenyVirtualAnonymous()) { -#ifdef VERBOSE_ERROR_LOGING - syslog(LOG_NOTICE, "FTP LOGIN FAILED (virtual host anonymous access denied) for %s", - remoteident); -#endif - reply(530, "Login incorrect."); - if (++login_attempts >= lgi_failure_threshold) { - syslog(LOG_NOTICE, "repeated login failures from %s", remoteident); - dologout(0); - } - goto bad; - } -#endif - /* Anonymous user in virtual_mode */ - if (pw->pw_dir) - free(pw->pw_dir); - pw->pw_dir = sgetsave(virtual_root); - } - else -#endif - - /* - * New chroot logic. - * - * If VIRTUAL is supported, the chroot for anonymous users on the - * virtual host has already been determined. Otherwise the logic - * below applies: - * - * If this is an anonymous user, the chroot directory is determined - * by the "anonymous-root" clause and the home directory is taken - * from the etc/passwd file found after chroot'ing. - * - * If this a guest user, the chroot directory is determined by the - * "guest-root" clause and the home directory is taken from the - * etc/passwd file found after chroot'ing. - * - * The effect of this logic is that the entire chroot environment - * is under the control of the ftpaccess file and the supporting - * files in the ftp environment. The system-wide passwd file is - * used only to authenticate the user. - */ - - { - struct aclmember *entry = NULL; - char *root_path = NULL; - - if (anonymous) { - char class[BUFSIZ]; - - (void) acl_getclass(class); - while (getaclentry("anonymous-root", &entry) && ARG0) { - if (!ARG1) { - if (!root_path) - root_path = ARG0; - } - else { - int which; - - for (which = 1; (which < MAXARGS) && ARG[which]; which++) { - if (!strcmp(ARG[which], "*")) { - if (!root_path) - root_path = ARG0; - } - else { - if (!strcasecmp(ARG[which], class)) - root_path = ARG0; - } - } - } - } - } - else { /* (guest) */ - while (getaclentry("guest-root", &entry) && ARG0) { - if (!ARG1) { - if (!root_path) - root_path = ARG0; - } - else { - int which; - char *ptr; - - for (which = 1; (which < MAXARGS) && ARG[which]; which++) { - if (!strcmp(ARG[which], "*")) { - if (!root_path) - root_path = ARG0; - } - else { - if (ARG[which][0] == '%') { - if ((ptr = strchr(ARG[which] + 1, '-')) == NULL) { - if ((ptr = strchr(ARG[which] + 1, '+')) == NULL) { - if (pw->pw_uid == strtoul(ARG[which] + 1, NULL, 0)) - root_path = ARG0; - } - else { - *ptr++ = '\0'; - if ((ARG[which][1] == '\0') - || (pw->pw_uid >= strtoul(ARG[which] + 1, NULL, 0))) - root_path = ARG0; - *--ptr = '+'; - } - } - else { - *ptr++ = '\0'; - if (((ARG[which][1] == '\0') - || (pw->pw_uid >= strtoul(ARG[which] + 1, NULL, 0))) - && ((*ptr == '\0') - || (pw->pw_uid <= strtoul(ptr, NULL, 0)))) - root_path = ARG0; - *--ptr = '-'; - } - } - else { -#ifdef OTHER_PASSWD - struct passwd *guest_pw = bero_getpwnam(ARG[which], _path_passwd); -#else - struct passwd *guest_pw = getpwnam(ARG[which]); -#endif - if (guest_pw && (pw->pw_uid == guest_pw->pw_uid)) - root_path = ARG0; - } - } - } - } - } - } - - if (root_path) { - struct passwd *chroot_pw = NULL; - -#if defined(VIRTUAL) && defined(CLOSED_VIRTUAL_SERVER) - if (virtual_mode && strcmp(root_path, virtual_root) && !(AllowVirtualUser(pw->pw_name) && !DenyVirtualUser(pw->pw_name))) { -#ifdef VERBOSE_ERROR_LOGING - syslog(LOG_NOTICE, "FTP LOGIN FAILED (virtual host access denied) for %s, %s", - remoteident, pw->pw_name); -#endif - reply(530, "Login incorrect."); - if (++login_attempts >= lgi_failure_threshold) { - syslog(LOG_NOTICE, "repeated login failures from %s", remoteident); - dologout(0); - } - goto bad; - } -#endif - (void) strncpy(chroot_path, root_path, sizeof(chroot_path)); - chroot_path[sizeof(chroot_path) - 1] = '\0'; - if (pw->pw_dir) - free(pw->pw_dir); - pw->pw_dir = sgetsave(chroot_path); -#if defined(SOLARIS_2) - cleanup_nscd(); -#endif - if (chroot(root_path) < 0 || chdir("/") < 0) { -#ifdef VERBOSE_ERROR_LOGING - syslog(LOG_NOTICE, "FTP LOGIN FAILED (cannot set guest privileges) for %s, %s", - remoteident, pw->pw_name); -#endif - reply(530, "Can't set guest privileges."); - goto bad; - } -#ifdef OTHER_PASSWD - if ((chroot_pw = bero_getpwuid(pw->pw_uid, _path_passwd)) != NULL) -#else - if ((chroot_pw = getpwuid(pw->pw_uid)) != NULL) -#endif - if (chdir(chroot_pw->pw_dir) >= 0) - home = sgetsave(chroot_pw->pw_dir); - goto slimy_hack; /* onea these days I'll make this structured code, honest ... */ - } - } - - /* determine root and home directory */ - - if ((sp = strstr(pw->pw_dir, "/./")) == NULL) { - (void) strncpy(chroot_path, pw->pw_dir, sizeof(chroot_path)); - chroot_path[sizeof(chroot_path) - 1] = '\0'; -#if defined(VIRTUAL) && defined(CLOSED_VIRTUAL_SERVER) - if (virtual_mode && strcmp(chroot_path, virtual_root) && !(AllowVirtualUser(pw->pw_name) && !DenyVirtualUser(pw->pw_name))) { -#ifdef VERBOSE_ERROR_LOGING - syslog(LOG_NOTICE, "FTP LOGIN FAILED (virtual host access denied) for %s, %s", - remoteident, pw->pw_name); -#endif - reply(530, "Login incorrect."); - if (++login_attempts >= lgi_failure_threshold) { - syslog(LOG_NOTICE, "repeated login failures from %s", remoteident); - dologout(0); - } - goto bad; - } -#endif -#if defined(SOLARIS_2) - cleanup_nscd(); -#endif - if (chroot(pw->pw_dir) < 0 || chdir("/") < 0) { -#ifdef VERBOSE_ERROR_LOGING - syslog(LOG_NOTICE, "FTP LOGIN FAILED (cannot set guest privileges) for %s, %s", - remoteident, pw->pw_name); -#endif - reply(530, "Can't set guest privileges."); - goto bad; - } - } - else { - *sp++ = '\0'; - (void) strncpy(chroot_path, pw->pw_dir, sizeof(chroot_path)); - chroot_path[sizeof(chroot_path) - 1] = '\0'; -#if defined(VIRTUAL) && defined(CLOSED_VIRTUAL_SERVER) - if (virtual_mode && strcmp(chroot_path, virtual_root) && !(AllowVirtualUser(pw->pw_name) && !DenyVirtualUser(pw->pw_name))) { -#ifdef VERBOSE_ERROR_LOGING - syslog(LOG_NOTICE, "FTP LOGIN FAILED (virtual host access denied) for %s, %s", - remoteident, pw->pw_name); -#endif - reply(530, "Login incorrect."); - if (++login_attempts >= lgi_failure_threshold) { - syslog(LOG_NOTICE, "repeated login failures from %s", remoteident); - dologout(0); - } - goto bad; - } -#endif -#if defined(SOLARIS_2) - cleanup_nscd(); -#endif - if (chroot(pw->pw_dir) < 0 || chdir(++sp) < 0) { -#ifdef VERBOSE_ERROR_LOGING - syslog(LOG_NOTICE, "FTP LOGIN FAILED (cannot set guest privileges) for %s, %s", - remoteident, pw->pw_name); -#endif - reply(550, "Can't set guest privileges."); - goto bad; - } -#ifdef ALTERNATE_CD - home = sp; -#endif - } - slimy_hack: - /* shut up you stupid compiler! */ { - int i = 0; - i++; - } - } -#if defined(VIRTUAL) && defined(CLOSED_VIRTUAL_SERVER) - else if (virtual_mode && !(AllowVirtualUser(pw->pw_name) && !DenyVirtualUser(pw->pw_name))) { -#ifdef VERBOSE_ERROR_LOGING - syslog(LOG_NOTICE, "FTP LOGIN FAILED (virtual host access denied) for %s, %s", - remoteident, pw->pw_name); -#endif - reply(530, "Login incorrect."); - if (++login_attempts >= lgi_failure_threshold) { - syslog(LOG_NOTICE, "repeated login failures from %s", remoteident); - dologout(0); - } - goto bad; - } -#endif -#ifdef AIX - { - /* AIX 3 lossage. Don't ask. It's undocumented. */ - priv_t priv; - - priv.pv_priv[0] = 0; - priv.pv_priv[1] = 0; -/* setgroups(NULL, NULL); */ - if (setpriv(PRIV_SET | PRIV_INHERITED | PRIV_EFFECTIVE | PRIV_BEQUEATH, - &priv, sizeof(priv_t)) < 0 || - setuidx(ID_REAL | ID_EFFECTIVE, (uid_t) pw->pw_uid) < 0 || - seteuid((uid_t) pw->pw_uid) < 0) { -#ifdef VERBOSE_ERROR_LOGING - syslog(LOG_NOTICE, "FTP LOGIN FAILED (cannot set uid) for %s, %s", - remoteident, pw->pw_name); -#endif - reply(530, "Can't set uid (AIX3)."); - goto bad; - } - } -#ifdef UID_DEBUG - lreply(success_code, "ruid=%d, euid=%d, suid=%d, luid=%d", getuidx(ID_REAL), - getuidx(ID_EFFECTIVE), getuidx(ID_SAVED), getuidx(ID_LOGIN)); - lreply(success_code, "rgid=%d, egid=%d, sgid=%d, lgid=%d", getgidx(ID_REAL), - getgidx(ID_EFFECTIVE), getgidx(ID_SAVED), getgidx(ID_LOGIN)); -#endif -#else /* AIX */ -#ifdef HAVE_SETREUID - if (setreuid(-1, (uid_t) pw->pw_uid) < 0) { -#else - if (seteuid((uid_t) pw->pw_uid) < 0) { -#endif -#ifdef VERBOSE_ERROR_LOGING - syslog(LOG_NOTICE, "FTP LOGIN FAILED (cannot set uid) for %s, %s", - remoteident, pw->pw_name); -#endif - reply(530, "Can't set uid."); - goto bad; - } -#endif /* AIX */ - if (!anonymous && !guest) { - if (chdir(pw->pw_dir) < 0) { -#ifdef PARANOID -#ifdef VERBOSE_ERROR_LOGING - syslog(LOG_NOTICE, "FTP LOGIN FAILED (cannot chdir) for %s, %s", - remoteident, pw->pw_name); -#endif - reply(530, "User %s: can't change directory to %s.", - pw->pw_name, pw->pw_dir); - goto bad; -#else /* PARANOID */ - if (restricted_user || chdir("/") < 0) { -#ifdef VERBOSE_ERROR_LOGING - syslog(LOG_NOTICE, "FTP LOGIN FAILED (cannot chdir) for %s, %s", - remoteident, pw->pw_name); -#endif - reply(530, "User %s: can't change directory to %s.", - pw->pw_name, pw->pw_dir); - goto bad; - } - else { - lreply(success_code, "No directory! Logging in with home=/"); -#ifdef ALTERNATE_CD - home = defhome; -#endif - } -#endif /* PARANOID */ - } - } - - if (passwarn) { - lreply(success_code, "The response '%s' is not valid", passwd); - lreply(success_code, - "Next time please use your e-mail address as your password"); - lreply(success_code, " for example: %s@%s%s", - authenticated ? authuser : "joe", remotehost, - strchr(remotehost, '.') ? "" : ".network"); - } - - login_attempts = 0; /* this time successful */ - - /* following two lines were inside the next scope... */ - - show_message(success_code, LOG_IN); - show_message(success_code, C_WD); - show_readme(success_code, LOG_IN); - show_readme(success_code, C_WD); - -#ifdef ULTRIX_AUTH - if (!anonymous && numfails > 0) { - lreply(success_code, - "There have been %d unsuccessful login attempts on your account", - numfails); - } -#endif /* ULTRIX_AUTH */ - - (void) is_shutdown(0, 0); /* display any shutdown messages now */ - - if (anonymous) { - - reply(success_code, "Guest login ok, access restrictions apply."); - sprintf(proctitle, "%s: anonymous/%.*s", remotehost, - (int) (sizeof(proctitle) - sizeof(remotehost) - - sizeof(": anonymous/")), passwd); - setproctitle("%s", proctitle); - if (logging) - syslog(LOG_INFO, "ANONYMOUS FTP LOGIN FROM %s, %s", - remoteident, passwd); - } - else { - reply(success_code, "User %s logged in.%s", pw->pw_name, guest ? - " Access restrictions apply." : ""); - sprintf(proctitle, "%s: %s", remotehost, pw->pw_name); - setproctitle("%s", proctitle); - if (logging) - syslog(LOG_INFO, "FTP LOGIN FROM %s, %s", remoteident, pw->pw_name); -/* H* mod: if non-anonymous user, copy it to "authuser" so everyone can - see it, since whoever he was @foreign-host is now largely irrelevant. - NMM mod: no, it isn't! Think about accounting for the transfers from or - to a shared account. */ - /* strcpy (authuser, pw->pw_name); */ - } /* anonymous */ -#ifdef ALTERNATE_CD - if (!home) -#endif - home = pw->pw_dir; /* home dir for globbing */ - (void) umask(defumask); - time(&login_time); - { - struct aclmember *entry; - entry = NULL; - while (getaclentry("limit-time", &entry) && ARG0 && ARG1) - if ((anonymous && strcasecmp(ARG0, "anonymous") == 0) - || (guest && strcasecmp(ARG0, "guest") == 0) - || ((guest | anonymous) && strcmp(ARG0, "*") == 0)) - limit_time = strtoul(ARG1, NULL, 0); - } - - /* Need to reset here as user type/class now known */ -#ifdef INET6 - /* IP_TOS is an IPv4 socket option */ - if (SOCK_FAMILY(ctrl_addr) == AF_INET) -#endif - if ((cos = IPClassOfService("control")) >= 0) { - if (setsockopt(0, IPPROTO_IP, IP_TOS, (char *) &cos, sizeof(int)) < 0) - syslog(LOG_WARNING, "setsockopt (IP_TOS): %m"); - } - -#ifdef SOLARIS_BSM_AUDIT - audit_ftpd_success(the_user); -#endif - init_privs(pw->pw_name); - return; - bad: - /* Forget all about it... */ - if (xferlog) - close(xferlog); - xferlog = 0; - acl_remove(); -#ifdef SOLARIS_BSM_AUDIT - audit_ftpd_failure(the_user); -#endif - end_login(); - return; -} - -int restricteduid(uid_t uid) -{ - return uid_match("restricted-uid", uid); -} - -int unrestricteduid(uid_t uid) -{ - return uid_match("unrestricted-uid", uid); -} - -int restrictedgid(gid_t gid) -{ - return gid_match("restricted-gid", gid, NULL); -} - -int unrestrictedgid(gid_t gid) -{ - return gid_match("unrestricted-gid", gid, NULL); -} - -char *opt_string(int options) -{ - static char buf[100]; - char *ptr = buf; - - if ((options & O_COMPRESS) != 0) /* debian fixes: NULL -> 0 */ - *ptr++ = 'C'; - if ((options & O_TAR) != 0) - *ptr++ = 'T'; - if ((options & O_UNCOMPRESS) != 0) - *ptr++ = 'U'; - if (options == 0) - *ptr++ = '_'; - *ptr++ = '\0'; - return (buf); -} - -#ifdef INTERNAL_LS -char *rpad(char *s, unsigned int len) -{ - char *a; - a = (char *) malloc(len + 1); - memset(a, ' ', len); - a[len] = 0; - if (strlen(s) <= len) - memcpy(a, s, strlen(s)); - else - strncpy(a, s, len); - return a; -} - -char *ls_file(const char *file, int nameonly, char remove_path, char classify) -{ - static const char month[12][4] = - {"Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; - - char *permissions; - struct stat s; - struct tm *t; - char *ls_entry; - char *owner, *ownerg; - char *rpowner, *rpownerg; - char *link; -#ifndef LS_NUMERIC_UIDS - struct passwd *pw; - struct group *gr; -#endif - link = NULL; - owner = NULL; - ownerg = NULL; - if (lstat(file, &s) != 0) /* File doesn't exist, or is not readable by user */ - return NULL; - ls_entry = (char *) malloc(312); - memset(ls_entry, 0, 312); - permissions = strdup("----------"); - if (S_ISLNK(s.st_mode)) { - permissions[0] = 'l'; - if (classify) - classify = '@'; - } - else if (S_ISDIR(s.st_mode)) { - permissions[0] = 'd'; - if (classify) - classify = '/'; - } - else if (S_ISBLK(s.st_mode)) - permissions[0] = 'b'; - else if (S_ISCHR(s.st_mode)) - permissions[0] = 'c'; - else if (S_ISFIFO(s.st_mode)) { - permissions[0] = 'p'; - if (classify == 1) - classify = '='; - } -#ifdef S_ISSOCK - else if (S_ISSOCK(s.st_mode)) - permissions[0] = 's'; -#endif - if ((s.st_mode & S_IRUSR) == S_IRUSR) - permissions[1] = 'r'; - if ((s.st_mode & S_IWUSR) == S_IWUSR) - permissions[2] = 'w'; - if ((s.st_mode & S_IXUSR) == S_IXUSR) { - permissions[3] = 'x'; - if (classify == 1) - classify = '*'; -#ifndef HIDE_SETUID - if ((s.st_mode & S_ISUID) == S_ISUID) - permissions[3] = 's'; -#endif - } -#ifndef HIDE_SETUID - else if ((s.st_mode & S_ISUID) == S_ISUID) - permissions[3] = 'S'; -#endif - if ((s.st_mode & S_IRGRP) == S_IRGRP) - permissions[4] = 'r'; - if ((s.st_mode & S_IWGRP) == S_IWGRP) - permissions[5] = 'w'; - if ((s.st_mode & S_IXGRP) == S_IXGRP) { - permissions[6] = 'x'; - if (classify == 1) - classify = '*'; -#ifndef HIDE_SETUID - if ((s.st_mode & S_ISGID) == S_ISGID) - permissions[6] = 's'; -#endif - } -#ifndef HIDE_SETUID - else if ((s.st_mode & S_ISGID) == S_ISGID) - permissions[6] = 'S'; -#endif - if ((s.st_mode & S_IROTH) == S_IROTH) - permissions[7] = 'r'; - if ((s.st_mode & S_IWOTH) == S_IWOTH) - permissions[8] = 'w'; - if ((s.st_mode & S_IXOTH) == S_IXOTH) { - permissions[9] = 'x'; - if (classify == 1) - classify = '*'; -#ifndef HIDE_SETUID - if ((s.st_mode & S_ISVTX) == S_ISVTX) - permissions[9] = 't'; -#endif - } -#ifndef HIDE_SETUID - else if ((s.st_mode & S_ISVTX) == S_ISVTX) - permissions[9] = 'T'; -#endif - t = localtime(&s.st_mtime); -#ifndef LS_NUMERIC_UIDS -#ifdef OTHER_PASSWD - pw = bero_getpwuid(s.st_uid, _path_passwd); -#else - pw = getpwuid(s.st_uid); -#endif - if (pw != NULL) - owner = strdup(pw->pw_name); - gr = getgrgid(s.st_gid); - if (gr != NULL) - ownerg = strdup(gr->gr_name); -#endif - if (owner == NULL) { /* Can't figure out username (or don't want to) */ - if (s.st_uid == 0) - owner = strdup("root"); - else { - owner = (char *) malloc(9); - memset(owner, 0, 9); -#ifdef SOLARIS_2 - snprintf(owner, 8, "%lu", s.st_uid); -#else - snprintf(owner, 8, "%u", s.st_uid); -#endif - } - } - if (ownerg == NULL) { /* Can't figure out groupname (or don't want to) */ - if (s.st_gid == 0) - ownerg = strdup("root"); - else { - ownerg = (char *) malloc(9); - memset(ownerg, 0, 9); -#ifdef SOLARIS_2 - snprintf(ownerg, 8, "%lu", s.st_gid); -#else - snprintf(ownerg, 8, "%u", s.st_gid); -#endif - } - } - -#ifdef HAVE_LSTAT - if (S_ISLNK(s.st_mode)) { - link = (char *) malloc(MAXPATHLEN); - memset(link, 0, MAXPATHLEN); - if (readlink(file, link, MAXPATHLEN) == -1) { - free(link); - link = NULL; - } - } -#endif - - if (remove_path != 0 && strchr(file, '/')) - file = strrchr(file, '/') + 1; - - rpowner = rpad(owner, 8); - rpownerg = rpad(ownerg, 8); - -#ifdef SOLARIS_2 -#define N_FORMAT "lu" -#else -#if defined(__FreeBSD__) || defined(__bsdi__) -#define N_FORMAT "u" -#else -#define N_FORMAT "u" -#endif -#endif - - if (nameonly) { - sprintf(ls_entry, "%s", file); - if (link != NULL) - free(link); - } - else { - if ((time(NULL) - s.st_mtime) > 6307200) { /* File is older than 6 months */ - if (link == NULL) - snprintf(ls_entry, 311, "%s %3" N_FORMAT " %s %s %8" L_FORMAT " %s %2u %5u %s", permissions, s.st_nlink, rpowner, rpownerg, s.st_size, month[t->tm_mon], t->tm_mday, 1900 + t->tm_year, file); - else { - snprintf(ls_entry, 311, "%s %3" N_FORMAT " %s %s %8" L_FORMAT " %s %2u %5u %s -> %s", permissions, s.st_nlink, rpowner, rpownerg, s.st_size, month[t->tm_mon], t->tm_mday, 1900 + t->tm_year, file, link); - free(link); - } - } - else if (link == NULL) - snprintf(ls_entry, 311, "%s %3" N_FORMAT " %s %s %8" L_FORMAT " %s %2u %02u:%02u %s", permissions, s.st_nlink, rpowner, rpownerg, s.st_size, month[t->tm_mon], t->tm_mday, t->tm_hour, t->tm_min, file); - else { - snprintf(ls_entry, 311, "%s %3" N_FORMAT " %s %s %8" L_FORMAT " %s %2u %02u:%02u %s -> %s", permissions, s.st_nlink, rpowner, rpownerg, s.st_size, month[t->tm_mon], t->tm_mday, t->tm_hour, t->tm_min, file, link); - free(link); - } - } - free(rpowner); - free(rpownerg); - free(owner); - free(ownerg); - if (classify > 1) - sprintf(ls_entry + strlen(ls_entry), "%c", classify); - strcat(ls_entry, "\r\n"); - free(permissions); - return ls_entry; -} - -void ls_dir(char *d, char ls_a, char ls_F, char ls_l, char ls_R, char omit_total, FILE *out) -{ - int total; - char *realdir; /* fixed up value to pass to glob() */ - char **subdirs; /* Subdirs to be scanned for ls -R */ - int numSubdirs = 0; - glob_t g; - char isDir; /* 0: d is a file; 1: d is some files; 2: d is dir */ - struct stat s; - char *dirlist; - unsigned long dl_size, dl_used; - char *c; - char *lsentry; - int i; -#ifndef GLOB_PERIOD - char *dperiod; -#endif - - isDir = 0; - realdir = (char *) malloc(strlen(d) + 3); - memset(realdir, 0, strlen(d) + 3); - strcpy(realdir, d); - if (strcmp(realdir, ".") == 0) - realdir[0] = '*'; - if (strcmp(realdir + strlen(realdir) - 2, "/.") == 0) - realdir[strlen(realdir) - 1] = '*'; - if (realdir[strlen(realdir) - 1] == '/') - strcat(realdir, "*"); - if (strchr(realdir, '*') || strchr(realdir, '?')) - isDir = 1; - if (strcmp(realdir, "*") == 0 || strcmp(realdir + strlen(realdir) - 2, "/*") == 0) - isDir = 2; - else { - if (lstat(realdir, &s) == 0) { - if (S_ISDIR(s.st_mode)) { - strcat(realdir, "/*"); - isDir = 2; - } - } - } - - if (isDir == 0) { - if (ls_l) { - lsentry = ls_file(realdir, 0, 0, ls_F); - if (lsentry != NULL) { - if (draconian_FILE != NULL) { - (void) signal(SIGALRM, draconian_alarm_signal); - alarm(timeout_data); -#if defined(USE_GSS) - sec_fprintf(out, "%s", lsentry); -#else - fputs(lsentry, out); -#endif /* defined(USE_GSS) */ - (void) signal(SIGALRM, SIG_DFL); - } - free(lsentry); - } - } - else { - if (draconian_FILE != NULL) { - (void) signal(SIGALRM, draconian_alarm_signal); - alarm(timeout_data); -#if defined(USE_GSS) - sec_fprintf(out, "%s", realdir); -#else - fputs(realdir, out); -#endif /* defined(USE_GSS) */ - (void) signal(SIGALRM, SIG_DFL); - } - } - free(realdir); - } - else { - if (ls_R) { - numSubdirs = 0; - subdirs = (char **) malloc(200 * sizeof(char *)); - memset(subdirs, 0, 200 * sizeof(char *)); - } - - dl_size = 65536; - dirlist = (char *) malloc(65536); - memset(dirlist, 0, 65536); - dl_used = 0; - - total = 0; - memset(&g, 0, sizeof(g)); - if (ls_a) { -#ifdef GLOB_PERIOD - if (glob(realdir, GLOB_ERR | GLOB_PERIOD, NULL, &g) != 0) - g.gl_pathc = 0; -#else - dperiod = (char *) malloc(strlen(realdir) + 2); - memset(dperiod, 0, strlen(realdir) + 2); - strcpy(dperiod, "."); - strcat(dperiod, realdir); - if (glob(dperiod, GLOB_ERR, NULL, &g) != 0) - g.gl_pathc = 0; - glob(realdir, GLOB_ERR | GLOB_APPEND, NULL, &g); - free(dperiod); -#endif - } - else if (glob(realdir, GLOB_ERR, NULL, &g) != 0) - g.gl_pathc = 0; - free(realdir); - for (i = 0; i < g.gl_pathc; i++) { - c = g.gl_pathv[i]; - if (lstat(c, &s) != -1) { - if (ls_l) { - total += s.st_blocks; - lsentry = ls_file(c, 0, 1, ls_F); - if (lsentry != NULL) { - /* This can actually happen even though the lstat() worked - - if someone deletes the file between the lstat() and ls_file() - calls. Unlikely, but better safe than sorry... */ - int flag = snprintf(dirlist + dl_used, dl_size - dl_used, "%s", lsentry); - dl_used += (flag == -1 ? dl_size - dl_used : flag); - free(lsentry); - } - } - else { - int flag; - lsentry = ls_file(c, 1, 1, ls_F); - if (lsentry != NULL) { - flag = snprintf(dirlist + dl_used, dl_size - dl_used, "%s", lsentry); - dl_used += (flag == -1 ? dl_size - dl_used : flag); - free(lsentry); - } - } - if ((ls_R != 0) && (S_ISDIR(s.st_mode)) - && (strcmp(c, "..") != 0) && (strcmp(c, ".") != 0) - && !(strlen(c) > 3 && strcmp(c + strlen(c) - 3, "/..") == 0) - && !(strlen(c) > 2 && strcmp(c + strlen(c) - 2, "/.") == 0)) { - subdirs[numSubdirs++] = strdup(c); - if ((numSubdirs % 200) == 0) - subdirs = (char **) realloc(subdirs, (numSubdirs + 200) * sizeof(char *)); - } - } - if (dl_used + 512 >= dl_size) { - dl_size += 65536; - dirlist = (char *) realloc(dirlist, dl_size); - } - } - globfree(&g); - if (ls_l && isDir == 2 && omit_total == 0) { - if (draconian_FILE != NULL) { - (void) signal(SIGALRM, draconian_alarm_signal); - alarm(timeout_data); -#if defined(USE_GSS) - sec_fprintf(out, "total %u\r\n", total); -#else - fprintf(out, "total %u\r\n", total); -#endif /* defined(USE_GSS) */ - } - } - if (draconian_FILE != NULL) { - (void) signal(SIGALRM, draconian_alarm_signal); - alarm(timeout_data); -#if defined(USE_GSS) - sec_fprintf(out, "%s", dirlist); -#else - fputs(dirlist, out); -#endif /* defined(USE_GSS) */ - } - free(dirlist); - if (ls_R) { - for (i = 0; i < numSubdirs; i++) { - if (draconian_FILE != NULL) { - (void) signal(SIGALRM, draconian_alarm_signal); - alarm(timeout_data); -#if defined(USE_GSS) - sec_fprintf(out, "\r\n%s:\r\n", subdirs[i]); -#else - fprintf(out, "\r\n%s:\r\n", subdirs[i]); -#endif /* defined(USE_GSS) */ - ls_dir(subdirs[i], ls_a, ls_F, ls_l, ls_R, 0, out); - } - free(subdirs[i]); - } - free(subdirs); - } - } -} - -void ls(char *file, char nlst) -{ - FILE *out; - char free_file = 0; - char ls_l = 0, ls_a = 0, ls_R = 0, ls_F = 0; - - if (nlst == 0) - ls_l = 1; /* LIST defaults to ls -l */ - if (file == NULL) { - file = strdup("."); - free_file = 1; - } - if (strcmp(file, "*") == 0) - file[0] = '.'; - - if (file[0] == '-') { /* options... */ - if (strchr(file, ' ') == 0) { - if (strchr(file, 'l')) - ls_l = 1; - if (strchr(file, 'a')) - ls_a = 1; - if (strchr(file, 'R')) - ls_R = 1; - if (strchr(file, 'F')) - ls_F = 1; - file = strdup("."); - free_file = 1; - } - else { - if (strchr(file, 'l') != NULL && strchr(file, 'l') < strchr(file, ' ')) - ls_l = 1; - if (strchr(file, 'a') != NULL && strchr(file, 'a') < strchr(file, ' ')) - ls_a = 1; - if (strchr(file, 'R') != NULL && strchr(file, 'R') < strchr(file, ' ')) - ls_R = 1; - if (strchr(file, 'F') != NULL && strchr(file, 'F') < strchr(file, ' ')) - ls_F = 1; - file = strchr(file, ' '); - } - } - while (file[0] == ' ') /* ignore additional whitespaces between parameters */ - file++; - if (strlen(file) == 0) { - file = strdup("."); - free_file = 1; - } - - out = dataconn("directory listing", -1, "w"); - draconian_FILE = out; - - transflag++; - - fixpath(file); - if (file[0] == '\0') { - if (free_file != 0) - free(file); - file = strdup("."); - free_file = 1; - } - - ls_dir(file, ls_a, ls_F, ls_l, ls_R, 0, out); - data = -1; - pdata = -1; - if (draconian_FILE != NULL) { - (void) signal(SIGALRM, draconian_alarm_signal); - alarm(timeout_data); -#if defined(USE_GSS) - if (sec_fflush(out) < 0) { - draconian_FILE = NULL; - alarm(0); - transflag = 0; - perror_reply(550, "Data connection"); - fclose(out); - goto ls_done; - } -#else - fflush(out); -#endif /* defined(USE_GSS) */ - } - if (draconian_FILE != NULL) { - (void) signal(SIGALRM, draconian_alarm_signal); - alarm(timeout_data); - socket_flush_wait(out); - } - if (draconian_FILE != NULL) { - (void) signal(SIGALRM, draconian_alarm_signal); - alarm(timeout_data); - fclose(out); - draconian_FILE = NULL; - } - alarm(0); - transflag = 0; - reply(226, "Transfer complete."); - ls_done: - if (free_file != 0) - free(file); -} -#endif /* INTERNAL_LS */ - -void retrieve(char *cmd, char *name) -{ - FILE *fin = NULL, *dout; - struct stat st, junk; - int (*closefunc) () = NULL; - int options = 0; - int ThisRetrieveIsData = retrieve_is_data; - time_t start_time = time(NULL); - char *logname; - char namebuf[MAXPATHLEN]; - char fnbuf[MAXPATHLEN]; - static int TransferComplete; /* static as retrieve can call itself */ - struct convert *cptr; - char realname[MAXPATHLEN]; - int stat_ret = -1; - size_t buffersize; - - TransferComplete = 0; - wu_realpath(name, realname, chroot_path); - - if (cmd == NULL && (stat_ret = stat(name, &st)) == 0) - /* there isn't a command and the file exists */ - if (use_accessfile && checknoretrieve(name)) { /* see above. _H */ - if (log_security) - if (anonymous) - syslog(LOG_NOTICE, "anonymous(%s) of %s tried to download %s (noretrieve)", - guestpw, remoteident, realname); - else - syslog(LOG_NOTICE, "%s of %s tried to download %s (noretrieve)", - pw->pw_name, remoteident, realname); - return; - } - -#ifdef TRANSFER_COUNT -#ifdef TRANSFER_LIMIT - if (retrieve_is_data) - if (((file_limit_data_out > 0) && (file_count_out >= file_limit_data_out)) - || ((file_limit_data_total > 0) && (file_count_total >= file_limit_data_total)) - || ((data_limit_data_out > 0) && (data_count_out >= data_limit_data_out)) - || ((data_limit_data_total > 0) && (data_count_total >= data_limit_data_total))) { - if (log_security) - if (anonymous) - syslog(LOG_NOTICE, "anonymous(%s) of %s tried to retrieve %s (Transfer limits exceeded)", - guestpw, remoteident, realname); - else - syslog(LOG_NOTICE, "%s of %s tried to retrieve %s (Transfer limits exceeded)", - pw->pw_name, remoteident, realname); - reply(553, "Permission denied on server. (Transfer limits exceeded)"); - return; - } - if (((file_limit_raw_out > 0) && (xfer_count_out >= file_limit_raw_out)) - || ((file_limit_raw_total > 0) && (xfer_count_total >= file_limit_raw_total)) - || ((data_limit_raw_out > 0) && (byte_count_out >= data_limit_raw_out)) - || ((data_limit_raw_total > 0) && (byte_count_total >= data_limit_raw_total))) { - if (log_security) - if (anonymous) - syslog(LOG_NOTICE, "anonymous(%s) of %s tried to retrieve %s (Transfer limits exceeded)", - guestpw, remoteident, realname); - else - syslog(LOG_NOTICE, "%s of %s tried to retrieve %s (Transfer limits exceeded)", - pw->pw_name, remoteident, realname); - reply(553, "Permission denied on server. (Transfer limits exceeded)"); - return; - } -#ifdef RATIO - if (retrieve_is_data && (upload_download_rate > 0) ) - if( freefile = is_downloadfree(name) ) { - syslog(LOG_INFO, "%s is download free.", name ); - } - else { - if ((cmd == NULL) && ((data_count_in * upload_download_rate) < (data_count_out - total_free_dl))) { - reply(550, "%s: Upload/Download ratio exceeded", name); - goto done; - } - } -#endif /* RATIO */ -#endif -#endif - - logname = (char *) NULL; - if (cmd == NULL && stat_ret != 0) { /* file does not exist */ - char *ptr; - - for (cptr = cvtptr; cptr != NULL; cptr = cptr->next) { - if (!(mangleopts & O_COMPRESS) && (cptr->options & O_COMPRESS)) - continue; - if (!(mangleopts & O_UNCOMPRESS) && (cptr->options & O_UNCOMPRESS)) - continue; - if (!(mangleopts & O_TAR) && (cptr->options & O_TAR)) - continue; - - if ((cptr->stripfix) && (cptr->postfix)) { - int pfxlen = strlen(cptr->postfix); - int sfxlen = strlen(cptr->stripfix); - int namelen = strlen(name); - - if (namelen <= pfxlen) - continue; - if (((namelen - pfxlen + sfxlen) >= sizeof(fnbuf)) || - (namelen >= sizeof(fnbuf))) - continue; - - (void) strcpy(fnbuf, name); - if (strcmp(fnbuf + namelen - pfxlen, cptr->postfix)) - continue; - *(fnbuf + namelen - pfxlen) = '\0'; - (void) strcat(fnbuf, cptr->stripfix); - if (stat(fnbuf, &st) != 0) - continue; - } - else if (cptr->postfix) { - int pfxlen = strlen(cptr->postfix); - int namelen = strlen(name); - - if ((namelen <= pfxlen) || (namelen >= sizeof(fnbuf))) - continue; - (void) strcpy(fnbuf, name); - if (strcmp(fnbuf + namelen - pfxlen, cptr->postfix)) - continue; - *(fnbuf + namelen - pfxlen) = (char) NULL; - if (stat(fnbuf, &st) != 0) - continue; - } - else if (cptr->stripfix) { - if (strlen(name) + strlen(cptr->stripfix) >= sizeof(fnbuf)) - continue; - (void) strcpy(fnbuf, name); - (void) strcat(fnbuf, cptr->stripfix); - if (stat(fnbuf, &st) != 0) - continue; - } - else { - continue; - } - - if (S_ISDIR(st.st_mode)) { - if (!cptr->types || !(cptr->types & T_DIR)) { - reply(550, "Cannot %s directories.", cptr->name); - return; - } - if ((cptr->options & O_TAR)) { - strcpy(namebuf, fnbuf); - if (strlcat(namebuf, "/.notar", sizeof(namebuf)) >= - sizeof(namebuf)) - continue; - if (stat(namebuf, &junk) == 0) { - if (log_security) - if (anonymous) - syslog(LOG_NOTICE, "anonymous(%s) of %s tried to tar %s (.notar)", - guestpw, remoteident, realname); - else - syslog(LOG_NOTICE, "%s of %s tried to tar %s (.notar)", - pw->pw_name, remoteident, realname); - reply(550, "Sorry, you may not TAR that directory."); - return; - } - } - } -/* XXX: checknoretrieve() test is weak in that if I can't get /etc/passwd - but I can tar /etc or /, I still win. Be careful out there... _H* - but you could put .notar in / and /etc and stop that ! */ - if (use_accessfile && checknoretrieve(fnbuf)) { - if (log_security) - if (anonymous) - syslog(LOG_NOTICE, "anonymous(%s) of %s tried to download %s (noretrieve)", - guestpw, remoteident, realname); - else - syslog(LOG_NOTICE, "%s of %s tried to download %s (noretrieve)", - pw->pw_name, remoteident, realname); - return; - } - - if (S_ISREG(st.st_mode) && (!cptr->types || (cptr->types & T_REG) == 0)) { - reply(550, "Cannot %s plain files.", cptr->name); - return; - } - if (S_ISREG(st.st_mode) != 0 && S_ISDIR(st.st_mode) != 0) { - reply(550, "Cannot %s special files.", cptr->name); - return; - } - if ((!cptr->types || !(cptr->types & T_ASCII)) && deny_badasciixfer(550, "")) - return; - - logname = &fnbuf[0]; - options |= cptr->options; - - strcpy(namebuf, cptr->external_cmd); - if ((ptr = strchr(namebuf, ' ')) != NULL) - *ptr = '\0'; - if (stat(namebuf, &junk) != 0) { - syslog(LOG_ERR, "external command %s not found", namebuf); - reply(550, - "Local error: conversion program not found. Cannot %s file.", - cptr->name); - return; - } - (void) retrieve(cptr->external_cmd, logname); - - goto logresults; /* transfer of converted file completed */ - } - } - - if (cmd == NULL) { /* no command */ - fin = fopen(name, "r"), closefunc = fclose; - st.st_size = 0; - } - else { /* run command */ - static char line[BUFSIZ]; - - (void) snprintf(line, sizeof(line), cmd, name), name = line; - fin = ftpd_popen(line, "r", 1), closefunc = ftpd_pclose; - st.st_size = -1; -#ifdef HAVE_ST_BLKSIZE - st.st_blksize = BUFSIZ; -#endif - } - if (fin == NULL) { - if (errno != 0) - perror_reply(550, name); - if ((errno == EACCES) || (errno == EPERM)) - if (log_security) - if (anonymous) - syslog(LOG_NOTICE, "anonymous(%s) of %s tried to download %s (file permissions)", - guestpw, remoteident, realname); - else - syslog(LOG_NOTICE, "%s of %s tried to download %s (file permissions)", - pw->pw_name, remoteident, realname); - return; - } - if (cmd == NULL && - (fstat(fileno(fin), &st) < 0 || (st.st_mode & S_IFMT) != S_IFREG)) { - reply(550, "%s: not a plain file.", name); - goto done; - } - if (restart_point) { - if (type == TYPE_A) { - register int c; - off_t i; - - i = 0; - while (i++ < restart_point) { - if ((c = getc(fin)) == EOF) { - perror_reply(550, name); - goto done; - } - if (c == '\n') - i++; - } - } - else if (lseek(fileno(fin), restart_point, SEEK_SET) < 0) { - perror_reply(550, name); - goto done; - } - } - - dout = dataconn(name, st.st_size, "w"); - if (dout == NULL) - goto done; - - if (sendbufsz > 0) { - buffersize = sendbufsz; - } - else { -#ifdef BUFFER_SIZE - buffersize = BUFFER_SIZE; -#elif HAVE_ST_BLKSIZE - buffersize = st.st_blksize * 2; -#else - buffersize = BUFSIZ * 16; -#endif - } - -#ifdef THROUGHPUT - TransferComplete = send_data(name, fin, dout, buffersize); -#else - TransferComplete = send_data(fin, dout, buffersize); -#endif -#ifdef SIGPIPE - (void) signal(SIGPIPE, SIG_IGN); -#endif - (void) fclose(dout); -#ifdef SIGPIPE - (void) signal(SIGPIPE, lostconn); -#endif - - logresults: - if (ThisRetrieveIsData) - fb_realpath((logname != NULL) ? logname : name, LastFileTransferred); - - if (log_outbound_xfers && (xferlog || syslogmsg) && (cmd == NULL)) { - char msg[MAXXFERSTRLEN]; /* see extensions.h */ - int xfertime = time(NULL) - start_time; - size_t msglen; - - if (!xfertime) - xfertime++; - - /* Gather transfer statistics */ - xfervalues.filename = (logname != NULL) ? logname : name; - xfervalues.filesize = st.st_size; - xfervalues.transfer_bytes = byte_count; - xfervalues.transfer_direction = 'o'; - xfervalues.transfer_type = (type == TYPE_A) ? 'a' : 'b'; - xfervalues.transfer_time = xfertime; - xfervalues.restart_offset = restart_point; - strlcpy(xfervalues.special_action, opt_string(options), MAXSPACTCHARS); - xfervalues.access_mode = anonymous ? 'a' : (guest ? 'g' : 'r'); - xfervalues.auth = authenticated; - xfervalues.completion = TransferComplete ? 'c' : 'i'; - - xferdone = 1; - msg_massage(xferlog_format, msg, sizeof(msg)); - xferdone = 0; - - /* Ensure msg always ends with '\n' */ - msglen = strlen(msg); - if (msglen == sizeof(msg) - 1) { - msg[sizeof(msg) - 2] = '\n'; - msg[sizeof(msg) - 1] = '\0'; - } - else { - msg[msglen] = '\n'; - msg[msglen + 1] = '\0'; - } - - if (syslogmsg != 1) - write(xferlog, msg, strlen(msg)); - if (syslogmsg != 0) { - char *msgp = msg; - /* - * To preserve the behavior when the xferlog format was fixed, skip - * over the time string if the message starts with the local time. - */ - if (strncmp(xferlog_format, "%T ", 3) == 0) - msgp += 25; - syslog(LOG_INFO, "xferlog (send): %s", msgp); - } - } - data = -1; - pdata = -1; - done: - if (closefunc) - (*closefunc) (fin); -} - -void store(char *name, char *mode, int unique) -{ - FILE *fout, *din; - struct stat st; - int TransferIncomplete = 1; - char *gunique(char *local); - time_t start_time = time(NULL); - - struct aclmember *entry = NULL; - - int fdout; - char realname[MAXPATHLEN]; - -#ifdef OVERWRITE - int overwrite = 1; - int exists = 0; - -#endif /* OVERWRITE */ - - int open_flags = 0; - -#ifdef UPLOAD - mode_t oldmask; - uid_t uid; - gid_t gid; - uid_t oldid; - int f_mode = -1, match_value = -1; - int valid = 0; - int ret, serrno; - open_flags = (O_RDWR | O_CREAT | - ((mode != NULL && *mode == 'a') ? O_APPEND : O_TRUNC)); -#endif /* UPLOAD */ - - wu_realpath(name, realname, chroot_path); - -#ifdef TRANSFER_COUNT -#ifdef TRANSFER_LIMIT - if (((file_limit_data_in > 0) && (file_count_in >= file_limit_data_in)) - || ((file_limit_data_total > 0) && (file_count_total >= file_limit_data_total)) - || ((data_limit_data_in > 0) && (data_count_in >= data_limit_data_in)) - || ((data_limit_data_total > 0) && (data_count_total >= data_limit_data_total))) { - if (log_security) - if (anonymous) - syslog(LOG_NOTICE, "anonymous(%s) of %s tried to upload %s (Transfer limits exceeded)", - guestpw, remoteident, realname); - else - syslog(LOG_NOTICE, "%s of %s tried to upload %s (Transfer limits exceeded)", - pw->pw_name, remoteident, realname); - reply(553, "Permission denied on server. (Transfer limits exceeded)"); - return; - } - if (((file_limit_raw_in > 0) && (xfer_count_in >= file_limit_raw_in)) - || ((file_limit_raw_total > 0) && (xfer_count_total >= file_limit_raw_total)) - || ((data_limit_raw_in > 0) && (byte_count_in >= data_limit_raw_in)) - || ((data_limit_raw_total > 0) && (byte_count_total >= data_limit_raw_total))) { - if (log_security) - if (anonymous) - syslog(LOG_NOTICE, "anonymous(%s) of %s tried to upload %s (Transfer limits exceeded)", - guestpw, remoteident, realname); - else - syslog(LOG_NOTICE, "%s of %s tried to upload %s (Transfer limits exceeded)", - pw->pw_name, remoteident, realname); - reply(553, "Permission denied on server. (Transfer limits exceeded)"); - return; - } -#endif -#endif - - if (unique && stat(name, &st) == 0 && - (name = gunique(name)) == NULL) - return; - - /* - * check the filename, is it legal? - */ - if ((fn_check(name)) <= 0) { - if (log_security) - if (anonymous) - syslog(LOG_NOTICE, "anonymous(%s) of %s tried to upload \"%s\" (path-filter)", - guestpw, remoteident, realname); - else - syslog(LOG_NOTICE, "%s of %s tried to upload \"%s\" (path-filter)", - pw->pw_name, remoteident, realname); - return; - } - -#ifdef OVERWRITE - /* if overwrite permission denied and file exists... then deny the user - * permission to write the file. */ - while (getaclentry("overwrite", &entry) && ARG0 && ARG1 != NULL) { - if (type_match(ARG1)) - if (strcasecmp(ARG0, "yes") != 0) { - overwrite = 0; - open_flags |= O_EXCL; - } - } - -#ifdef PARANOID - overwrite = 0; -#endif - if (!stat(name, &st)) - exists = 1; - - if (!overwrite && exists) { - if (log_security) - if (anonymous) - syslog(LOG_NOTICE, "anonymous(%s) of %s tried to overwrite %s", - guestpw, remoteident, realname); - else - syslog(LOG_NOTICE, "%s of %s tried to overwrite %s", - pw->pw_name, remoteident, realname); - reply(553, "%s: Permission denied on server. (Overwrite)", name); - return; - } -#endif /* OVERWRITE */ - -#ifdef UPLOAD - if ((match_value = upl_check(name, &uid, &gid, &f_mode, &valid)) < 0) { - if (log_security) - if (anonymous) - syslog(LOG_NOTICE, "anonymous(%s) of %s tried to upload %s (upload denied)", - guestpw, remoteident, realname); - else - syslog(LOG_NOTICE, "%s of %s tried to upload %s (upload denied)", - pw->pw_name, remoteident, realname); - return; - } - - /* do not truncate the file if we are restarting */ - if (restart_point) - open_flags &= ~O_TRUNC; - - /* if the user has an explicit new file mode, than open the file using - * that mode. We must take care to not let the umask affect the file - * mode. - * - * else open the file and let the default umask determine the file mode. */ - if (f_mode >= 0) { - oldmask = umask(0000); - fdout = open(name, open_flags, f_mode); - umask(oldmask); - } - else - fdout = open(name, open_flags, 0666); - - if (fdout < 0) { - if (log_security) - if (anonymous) - syslog(LOG_NOTICE, "anonymous(%s) of %s tried to upload %s (permissions)", - guestpw, remoteident, realname); - else - syslog(LOG_NOTICE, "%s of %s tried to upload %s (permissions)", - pw->pw_name, remoteident, realname); - perror_reply(553, name); - return; - } - /* if we have a uid and gid, then use them. */ - -#ifdef OVERWRITE - if (!exists) -#endif - if (valid > 0) { - oldid = geteuid(); - if (uid != 0) - (void) seteuid((uid_t) uid); - if ((uid == 0) || ((fchown(fdout, uid, gid)) < 0)) { - chown_priv_on(0); - ret = fchown(fdout, uid, gid); - serrno = errno; - chown_priv_off(oldid); - if (ret < 0) { - errno = serrno; - perror_reply(550, "fchown"); - return; - } - } - else - (void) seteuid(oldid); - } -#endif /* UPLOAD */ - - if (restart_point && (open_flags & O_APPEND) == 0) - mode = "r+"; - -#ifdef UPLOAD - fout = fdopen(fdout, mode); -#else - fout = fopen(name, mode); -#endif /* UPLOAD */ - - if (fout == NULL) { - if (log_security) - if (anonymous) - syslog(LOG_NOTICE, "anonymous(%s) of %s tried to upload %s (permissions)", - guestpw, remoteident, realname); - else - syslog(LOG_NOTICE, "%s of %s tried to upload %s (permissions)", - pw->pw_name, remoteident, realname); - perror_reply(553, name); - return; - } - if (restart_point && (open_flags & O_APPEND) == 0) { - if (type == TYPE_A) { - register int c; - off_t i; - - i = 0; - while (i++ < restart_point) { - if ((c = getc(fout)) == EOF) { - perror_reply(550, name); - goto done; - } - if (c == '\n') - i++; - } - /* We must do this seek to "current" position because we are - * changing from reading to writing. */ -#if _FILE_OFFSET_BITS == 64 - if (fseeko(fout, 0L, SEEK_CUR) < 0) { -#else - if (fseek(fout, 0L, SEEK_CUR) < 0) { -#endif - perror_reply(550, name); - goto done; - } - } - else if (lseek(fileno(fout), restart_point, SEEK_SET) < 0) { - perror_reply(550, name); - goto done; - } - } - din = dataconn(name, (off_t) - 1, "r"); - if (din == NULL) - goto done; - TransferIncomplete = receive_data(din, fout); - - if (fstat(fileno(fout), &st) != 0) { - /* shouldn't fail, but just in case */ - st.st_size = -1; - } - (void) fclose(din); - if (TransferIncomplete == 0) { - if (unique) - reply(226, "Transfer complete (unique file name:%s).", name); - else - reply(226, "Transfer complete."); - } - - fb_realpath(name, LastFileTransferred); - -#ifdef MAIL_ADMIN - if (anonymous && incmails > 0) { - FILE *sck = NULL; - - unsigned char temp = 0, temp2 = 0; - char pathname[MAXPATHLEN]; - while ((temp < mailservers) && (sck == NULL)) - sck = SockOpen(mailserver[temp++], 25); - if (sck == NULL) { - syslog(LOG_ERR, "Can't connect to a mailserver."); - goto mailfail; - } - if (Reply(sck) != 220) { - syslog(LOG_ERR, "Mailserver failed to initiate contact."); - goto mailfail; - } - if (Send(sck, "HELO localhost\r\n") != 250) { - syslog(LOG_ERR, "Mailserver doesn't understand HELO."); - goto mailfail; - } - if (Send(sck, "MAIL FROM: <%s>\r\n", email(mailfrom)) != 250) { - syslog(LOG_ERR, "Mailserver didn't accept MAIL FROM."); - goto mailfail; - } - for (temp = 0; temp < incmails; temp++) { - if (Send(sck, "RCPT TO: <%s>\r\n", email(incmail[temp])) == 250) - temp2++; - } - if (temp2 == 0) { - syslog(LOG_ERR, "Mailserver didn't accept any RCPT TO."); - goto mailfail; - } - if (Send(sck, "DATA\r\n") != 354) { - syslog(LOG_ERR, "Mailserver didn't accept DATA."); - goto mailfail; - } - SockPrintf(sck, "From: wu-ftpd <%s>\r\n", mailfrom); - SockPrintf(sck, "Subject: New file uploaded: %s\r\n\r\n", name); - fb_realpath(name, pathname); - SockPrintf(sck, "%s uploaded %s from %s.\r\nFile size is %" L_FORMAT ".\r\nPlease move the file where it belongs.\r\n", guestpw, pathname, remotehost, st.st_size); - if (Send(sck, ".\r\n") != 250) - syslog(LOG_ERR, "Message rejected by mailserver."); - if (Send(sck, "QUIT\r\n") != 221) - syslog(LOG_ERR, "Mailserver didn't accept QUIT."); - mailfail: - if (sck != NULL) - fclose(sck); - } -#endif /* MAIL_ADMIN */ - - if (log_incoming_xfers && (xferlog || syslogmsg)) { - char msg[MAXXFERSTRLEN]; /* see extensions.h */ - int xfertime = time(NULL) - start_time; - size_t msglen; - - if (!xfertime) - xfertime++; - - /* Gather transfer statistics */ - xfervalues.filename = name; - xfervalues.filesize = st.st_size; - xfervalues.transfer_bytes = byte_count; - xfervalues.transfer_direction = 'i'; - xfervalues.transfer_type = (type == TYPE_A) ? 'a' : 'b'; - xfervalues.transfer_time = xfertime; - xfervalues.restart_offset = restart_point; - strlcpy(xfervalues.special_action, opt_string(0), MAXSPACTCHARS); - xfervalues.access_mode = anonymous ? 'a' : (guest ? 'g' : 'r'); - xfervalues.auth = authenticated; - xfervalues.completion = TransferIncomplete ? 'i' : 'c'; - - xferdone = 1; - msg_massage(xferlog_format, msg, sizeof(msg)); - xferdone = 0; - - /* Ensure msg always ends with '\n' */ - msglen = strlen(msg); - if (msglen == sizeof(msg) - 1) { - msg[sizeof(msg) - 2] = '\n'; - msg[sizeof(msg) - 1] = '\0'; - } - else { - msg[msglen] = '\n'; - msg[msglen + 1] = '\0'; - } - - if (syslogmsg != 1) - write(xferlog, msg, strlen(msg)); - if (syslogmsg != 0) { - char *msgp = msg; - /* - * To preserve the behavior when the xferlog format was fixed, skip - * over the time string if the message starts with the local time. - */ - if (strncmp(xferlog_format, "%T ", 3) == 0) - msgp += 25; - syslog(LOG_INFO, "xferlog (recv): %s", msgp); - } - } - data = -1; - pdata = -1; - done: - (void) fclose(fout); -} - -FILE *getdatasock(char *mode) -{ - int s, on = 1, tries; - - if (data >= 0) - return (fdopen(data, mode)); - port_priv_on(0); - s = socket(SOCK_FAMILY(data_dest), SOCK_STREAM, 0); - if (s < 0) - goto bad; - if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, - (char *) &on, sizeof(on)) < 0) - goto bad; - if (keepalive) - (void) setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (char *) &on, sizeof(on)); - if (TCPwindowsize) - (void) setsockopt(s, SOL_SOCKET, (*mode == 'w' ? SO_SNDBUF : SO_RCVBUF), - (char *) &TCPwindowsize, sizeof(TCPwindowsize)); - /* anchor socket to avoid multi-homing problems */ -#ifdef INET6 - if (SOCK_FAMILY(data_dest) == SOCK_FAMILY(ctrl_addr)) - data_source = ctrl_addr; - else if ((SOCK_FAMILY(data_dest) == AF_INET) && ctrl_v4mapped) { - struct sockaddr_in6 *ctrl_sin6 = (struct sockaddr_in6 *)&ctrl_addr; - struct sockaddr_in *data_sin = (struct sockaddr_in *)&data_source; - - SET_SOCK_FAMILY(data_source, AF_INET); - memcpy(&data_sin->sin_addr, &ctrl_sin6->sin6_addr.s6_addr[12], - sizeof(struct in_addr)); - } - else { - memset(&data_source, 0, sizeof(struct sockaddr_in6)); - SET_SOCK_FAMILY(data_source, SOCK_FAMILY(data_dest)); - SET_SOCK_ADDR_ANY(data_source); - } -#else - data_source = ctrl_addr; -#endif - SET_SOCK_PORT(data_source, data_port); - -#if defined(VIRTUAL) && defined(CANT_BIND) /* can't bind to virtual address */ - SET_SOCK_ADDR_ANY(data_source); -#endif - for (tries = 1;; tries++) { - if (bind(s, (struct sockaddr *) &data_source, SOCK_LEN(data_source)) >= 0) - break; - if (errno != EADDRINUSE || tries > 10) - goto bad; - sleep(tries); - } -#if defined(M_UNIX) && !defined(_M_UNIX) /* bug in old TCP/IP release */ - { - struct linger li; - li.l_onoff = 1; - li.l_linger = 900; - if (setsockopt(s, SOL_SOCKET, SO_LINGER, - (char *) &li, sizeof(struct linger)) < 0) { - syslog(LOG_WARNING, "setsockopt (SO_LINGER): %m"); - goto bad; - } - } -#endif - port_priv_off((uid_t) pw->pw_uid); - -#ifdef INET6 - /* IP_TOS is an IPv4 socket option */ - if (SOCK_FAMILY(data_source) == AF_INET) -#endif - if ((on = IPClassOfService("data")) >= 0) { - if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *) &on, sizeof(int)) < 0) - syslog(LOG_WARNING, "setsockopt (IP_TOS): %m"); - } -#ifdef TCP_NOPUSH - /* - * Turn off push flag to keep sender TCP from sending short packets - * at the boundaries of each write(). Should probably do a SO_SNDBUF - * to set the send buffer size as well, but that may not be desirable - * in heavy-load situations. - */ - on = 1; - if (setsockopt(s, IPPROTO_TCP, TCP_NOPUSH, (char *) &on, sizeof on) < 0) - syslog(LOG_WARNING, "setsockopt (TCP_NOPUSH): %m"); -#endif - - return (fdopen(s, mode)); - bad: - on = errno; /* hold errno for return */ - port_priv_off((uid_t) pw->pw_uid); - if (s != -1) - (void) close(s); - errno = on; - return (NULL); -} - -FILE *dataconn(char *name, off_t size, char *mode) -{ - char sizebuf[32]; - FILE *file; - int retry = 0; - int on = 1; - int cval, serrno; - int cos; -#ifdef THROUGHPUT - int bps; - double bpsmult; -#endif - - file_size = size; - byte_count = 0; - if (size != (off_t) - 1) - (void) sprintf(sizebuf, " (%" L_FORMAT " bytes)", size); - else - (void) strcpy(sizebuf, ""); - if (pdata >= 0) { - struct SOCKSTORAGE from; - char dataaddr[MAXHOSTNAMELEN]; -#if defined(UNIXWARE) || defined(AIX) - size_t fromlen = sizeof(from); -#else - int fromlen = sizeof(from); -#endif - int s; -#ifdef FD_ZERO - int rv; -#endif - - if (keepalive) - (void) setsockopt(pdata, SOL_SOCKET, SO_KEEPALIVE, (char *) &on, sizeof(on)); - if (TCPwindowsize) - (void) setsockopt(pdata, SOL_SOCKET, (*mode == 'w' ? SO_SNDBUF : SO_RCVBUF), - (char *) &TCPwindowsize, sizeof(TCPwindowsize)); -#ifdef FD_ZERO - do { - struct timeval timeout; - fd_set set; - - FD_ZERO(&set); - FD_SET(pdata, &set); - - timeout.tv_usec = 0; - timeout.tv_sec = timeout_accept; -#ifdef HPUX_SELECT - rv = select(pdata + 1, (int *) &set, NULL, NULL, &timeout); -#else - rv = select(pdata + 1, &set, (fd_set *) 0, (fd_set *) 0, - (struct timeval *) &timeout); -#endif - } while ((rv == -1) && (errno == EINTR)); - if ((rv != -1) && (rv != 0)) - s = accept(pdata, (struct sockaddr *) &from, &fromlen); - else - s = -1; -#else /* FD_ZERO */ - (void) signal(SIGALRM, alarm_signal); - alarm(timeout_accept); - s = accept(pdata, (struct sockaddr *) &from, &fromlen); - alarm(0); -#endif - if (s == -1) { - reply(425, "Can't open data connection."); - (void) close(pdata); - pdata = -1; - return (NULL); - } - (void) close(pdata); - pdata = s; -#ifdef INET6 - /* IP_TOS is an IPv4 socket option */ - if (SOCK_FAMILY(from) == AF_INET) -#endif - if ((cos = IPClassOfService("data")) >= 0) - (void) setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&cos, sizeof(int)); - (void) strncpy(dataaddr, inet_stop(&from), sizeof(dataaddr)); - if (!pasv_allowed(dataaddr)) - if (strcasecmp(dataaddr, remoteaddr) != 0) { - /* - * This will log when data connection comes from an address different - * than the control connection. - */ -#ifdef FIGHT_PASV_PORT_RACE - syslog(LOG_ERR, "%s of %s: data connect from %s for %s%s", - anonymous ? guestpw : pw->pw_name, remoteident, - dataaddr, name, sizebuf); - reply(425, "Possible PASV port theft, cannot open data connection."); - (void) close(pdata); - pdata = -1; - return (NULL); -#else - syslog(LOG_NOTICE, "%s of %s: data connect from %s for %s%s", - anonymous ? guestpw : pw->pw_name, remoteident, - dataaddr, name, sizebuf); -#endif - } -#ifdef THROUGHPUT - throughput_calc(name, &bps, &bpsmult); - if (bps != -1) { - lreply(150, "Opening %s mode data connection for %s%s.", - type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf); - reply(150, "Restricting network throughput to %d bytes/s.", bps); - } - else -#endif - reply(150, "Opening %s mode data connection for %s%s.", - type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf); - return (fdopen(pdata, mode)); - } - if (data >= 0) { - reply(125, "Using existing data connection for %s%s.", - name, sizebuf); - usedefault = 1; - return (fdopen(data, mode)); - } - if (usedefault) - data_dest = his_addr; - if (SOCK_PORT(data_dest) == 0) { - reply(500, "Can't build data connection: no PORT specified"); - return (NULL); - } - usedefault = 1; - do { - file = getdatasock(mode); - if (file == NULL) { - reply(425, "Can't create data socket (%s,%d): %s.", - inet_stop(&data_source), ntohs(SOCK_PORT(data_source)), - strerror(errno)); - return (NULL); - } - data = fileno(file); - (void) signal(SIGALRM, alarm_signal); - alarm(timeout_connect); - cval = connect(data, (struct sockaddr *) &data_dest, - SOCK_LEN(data_dest)); - serrno = errno; - alarm(0); - if (cval == -1) { - /* - * When connect fails, the state of the socket is unspecified so - * it should be closed and a new socket created for each connection - * attempt. This also prevents denial of service problems when - * running on operating systems that only allow one non-connected - * socket bound to the same local address. - */ - (void) fclose(file); - data = -1; - errno = serrno; - if ((errno == EADDRINUSE || errno == EINTR) && retry < swaitmax) { - sleep((unsigned) swaitint); - retry += swaitint; - } - else { - perror_reply(425, "Can't build data connection"); - return (NULL); - } - } - } while (cval == -1); - if (keepalive) - (void) setsockopt(data, SOL_SOCKET, SO_KEEPALIVE, (char *) &on, sizeof(on)); - if (TCPwindowsize) - (void) setsockopt(data, SOL_SOCKET, (*mode == 'w' ? SO_SNDBUF : SO_RCVBUF), - (char *) &TCPwindowsize, sizeof(TCPwindowsize)); -#ifdef THROUGHPUT - throughput_calc(name, &bps, &bpsmult); - if (bps != -1) { - lreply(150, "Opening %s mode data connection for %s%s.", - type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf); - reply(150, "Restricting network throughput to %d bytes/s.", bps); - } - else -#endif - reply(150, "Opening %s mode data connection for %s%s.", - type == TYPE_A ? "ASCII" : "BINARY", name, sizebuf); - return (file); -} - -/* Tranfer the contents of "instr" to "outstr" peer using the appropriate - * encapsulation of the data subject to Mode, Structure, and Type. - * - * NB: Form isn't handled. */ - -int -#ifdef THROUGHPUT - send_data(char *name, FILE *instr, FILE *outstr, size_t blksize) -#else - send_data(FILE *instr, FILE *outstr, size_t blksize) -#endif -{ - register int c, cnt = 0; - static char *buf; - int netfd, filefd; -#ifdef THROUGHPUT - int bps; - double bpsmult; - time_t t1, t2; -#endif -#ifdef SENDFILE - int use_sf = 0; - size_t xferred; - struct stat st; - struct sendfilevec sfv; -#endif - - buf = NULL; - if (wu_setjmp(urgcatch)) { - draconian_FILE = NULL; - alarm(0); - transflag = 0; -#ifdef SIGPIPE - (void) signal(SIGPIPE, lostconn); -#endif - if (buf) - (void) free(buf); - retrieve_is_data = 1; - return (0); - } - transflag++; - -#ifdef THROUGHPUT - throughput_calc(name, &bps, &bpsmult); -#endif - - switch (type) { - - case TYPE_A: -#ifdef SIGPIPE - /* - * Ignore SIGPIPE while sending data, necessary so lostconn() isn't - * called if we write to the data connection after the client has - * closed it. - */ - (void) signal(SIGPIPE, SIG_IGN); -#endif - draconian_FILE = outstr; - (void) signal(SIGALRM, draconian_alarm_signal); - alarm(timeout_data); -#ifdef THROUGHPUT - if (bps != -1) - t1 = time(NULL); -#endif - while ((draconian_FILE != NULL) && ((c = getc(instr)) != EOF)) { - if (++byte_count % 4096 == 0) - alarm(timeout_data); - if (c == '\n') { - if (ferror(outstr)) - goto data_err; - if (++byte_count % 4096 == 0) - alarm(timeout_data); -#if defined(USE_GSS) - if (sec_putc('\r', outstr) != '\r') - goto data_err; -#else - (void) putc('\r', outstr); -#endif -#ifdef TRANSFER_COUNT - if (retrieve_is_data) { - data_count_total++; - data_count_out++; - } - byte_count_total++; - byte_count_out++; -#endif - } -#if defined(USE_GSS) - if (sec_putc(c, outstr) != c) - goto data_err; -#else - (void) putc(c, outstr); -#endif - -#ifdef TRANSFER_COUNT - if (retrieve_is_data) { - data_count_total++; - data_count_out++; - } - byte_count_total++; - byte_count_out++; -#endif -#ifdef THROUGHPUT - if (bps > 0 && (byte_count % bps) == 0) { - t2 = time(NULL); - if (t2 == t1) - sleep(1); - t1 = time(NULL); - } -#endif - } -#ifdef THROUGHPUT - if (bps != -1) - throughput_adjust(name); -#endif - if (draconian_FILE != NULL) { - alarm(timeout_data); -#if defined(USE_GSS) - if (sec_fflush(outstr) < 0) - goto data_err; -#else - fflush(outstr); -#endif /* defined(USE_GSS) */ - } - if (draconian_FILE != NULL) { - alarm(timeout_data); - socket_flush_wait(outstr); - } - transflag = 0; - if (ferror(instr)) - goto file_err; - if ((draconian_FILE == NULL) || ferror(outstr)) - goto data_err; - draconian_FILE = NULL; - alarm(0); -#ifdef SIGPIPE - (void) signal(SIGPIPE, lostconn); -#endif - reply(226, "Transfer complete."); -#ifdef TRANSFER_COUNT - if (retrieve_is_data) { - file_count_total++; - file_count_out++; - } - xfer_count_total++; - xfer_count_out++; -#endif - retrieve_is_data = 1; - return (1); - - case TYPE_I: - case TYPE_L: -#ifdef THROUGHPUT - if (bps != -1) - blksize = bps; -#endif - netfd = fileno(outstr); - filefd = fileno(instr); -#ifdef SENDFILE - /* check the input file is a regular file */ - if ((fstat(filefd, &st) == 0) && ((st.st_mode & S_IFMT) == S_IFREG)) { -#if defined(USE_GSS) - if (gss_info.data_prot == PROT_C || !IS_GSSAUTH(cur_auth_type) || - !(gss_info.authstate & GSS_ADAT_DONE)) -#endif /* defined(USE_GSS) */ - { - use_sf = 1; - /* - * Use a private sfv_flag SFV_NOWAIT to tell sendfilev(), - * when zero-copy is enabled, not to wait for all data to be - * ACKed before returning. This is important for throughput - * performance when sendfilev() is called to send small piece - * at a time. - */ - sfv.sfv_flag = SFV_NOWAIT; - sfv.sfv_fd = filefd; - sfv.sfv_off = restart_point; - sfv.sfv_len = blksize; - } - } - if (use_sf == 0) -#endif - if ((buf = (char *) malloc(blksize)) == NULL) { - transflag = 0; - perror_reply(451, "Local resource failure: malloc"); - retrieve_is_data = 1; - return (0); - } -#ifdef SIGPIPE - /* - * Ignore SIGPIPE while sending data, necessary so lostconn() isn't - * called if we write to the data connection after the client has - * closed it. - */ - (void) signal(SIGPIPE, SIG_IGN); -#endif - draconian_FILE = outstr; - (void) signal(SIGALRM, draconian_alarm_signal); - alarm(timeout_data); -#ifdef THROUGHPUT - if (bps != -1) - t1 = time(NULL); -#endif - while ((draconian_FILE != NULL) && ( -#ifdef SENDFILE - (use_sf && (cnt = sendfilev(netfd, &sfv, 1, &xferred)) > 0) - || (!use_sf && -#endif - ((cnt = read(filefd, buf, blksize)) > 0 && -#if defined(USE_GSS) - sec_write(netfd, buf, cnt) == cnt) -#else - write(netfd, buf, cnt) == cnt) -#endif /* defined(USE_GSS) */ -#ifdef SENDFILE - ) -#endif - )) { - alarm(timeout_data); -#ifdef SENDFILE - sfv.sfv_off += cnt; -#endif - byte_count += cnt; -#ifdef TRANSFER_COUNT - if (retrieve_is_data) { -#ifdef RATIO - if( freefile ) { - total_free_dl += cnt; - } -#endif /* RATIO */ - data_count_total += cnt; - data_count_out += cnt; - } - byte_count_total += cnt; - byte_count_out += cnt; -#endif -#ifdef THROUGHPUT - if (bps != -1) { - t2 = time(NULL); - if (t2 == t1) - sleep(1); - t1 = time(NULL); - } -#endif /* THROUGHPUT */ - } -#ifdef THROUGHPUT - if (bps != -1) - throughput_adjust(name); -#endif -#if defined(USE_GSS) - if (sec_fflush(outstr) < 0) - goto data_err; -#endif - transflag = 0; - if (buf) - (void) free(buf); - if (draconian_FILE != NULL) { - alarm(timeout_data); - socket_flush_wait(outstr); - } - if (cnt != 0) { -#ifdef SENDFILE - if (use_sf && cnt < 0 && errno == EPIPE) - goto data_err; -#endif - if (cnt < 0) - goto file_err; - goto data_err; - } - if (draconian_FILE == NULL) - goto data_err; - draconian_FILE = NULL; - alarm(0); -#ifdef SIGPIPE - (void) signal(SIGPIPE, lostconn); -#endif - reply(226, "Transfer complete."); -#ifdef TRANSFER_COUNT - if (retrieve_is_data) { - file_count_total++; - file_count_out++; - } - xfer_count_total++; - xfer_count_out++; -#endif - retrieve_is_data = 1; - return (1); - default: - transflag = 0; - reply(550, "Unimplemented TYPE %d in send_data", type); - retrieve_is_data = 1; - return (0); - } - - data_err: - draconian_FILE = NULL; - alarm(0); - transflag = 0; -#ifdef SIGPIPE - (void) signal(SIGPIPE, lostconn); -#endif - perror_reply(426, "Data connection"); - retrieve_is_data = 1; - return (0); - - file_err: - draconian_FILE = NULL; - alarm(0); - transflag = 0; -#ifdef SIGPIPE - (void) signal(SIGPIPE, lostconn); -#endif - perror_reply(551, "Error on input file"); - retrieve_is_data = 1; - return (0); -} - -/* Transfer data from peer to "outstr" using the appropriate encapulation of - * the data subject to Mode, Structure, and Type. - * - * N.B.: Form isn't handled. */ - -int receive_data(FILE *instr, FILE *outstr) -{ - register int c; - int rcnt = 0, n = 0, bare_lfs = 0; - static char *buf; - int netfd, filefd, wcnt; -#ifdef BUFFER_SIZE - size_t buffer_size = BUFFER_SIZE; -#else - size_t buffer_size = BUFSIZ * 16; -#endif - - buf = NULL; - if (wu_setjmp(urgcatch)) { - alarm(0); - transflag = 0; - if (buf) - (void) free(buf); - return (-1); - } - transflag++; - switch (type) { - - case TYPE_I: - case TYPE_L: -#if defined(USE_GSS) - if (GSSUSERAUTH_OK(gss_info)) - buffer_size = gss_getinbufsz(); - else -#endif - if (recvbufsz > 0) - buffer_size = recvbufsz; - if ((buf = (char *) malloc(buffer_size)) == NULL) { - transflag = 0; - perror_reply(451, "Local resource failure: malloc"); - return (-1); - } - netfd = fileno(instr); - filefd = fileno(outstr); - draconian_FILE = instr; - (void) signal(SIGALRM, draconian_alarm_signal); - alarm(timeout_data); - - while ((draconian_FILE != NULL) && -#if defined(USE_GSS) - (rcnt = sec_read(netfd, buf, buffer_size)) > 0) { -#else - (rcnt = read(netfd, buf, buffer_size)) > 0) { -#endif - for (wcnt = 0; wcnt < rcnt; wcnt += n) { - if ((n = write(filefd, &buf[wcnt], rcnt - wcnt)) == -1) - break; - } - byte_count += wcnt; -#ifdef TRANSFER_COUNT - data_count_total += wcnt; - data_count_in += wcnt; - byte_count_total += wcnt; - byte_count_in += wcnt; -#endif - if (n == -1) - break; - alarm(timeout_data); - } - transflag = 0; - (void) free(buf); - if ((rcnt == -1) || (draconian_FILE == NULL)) - goto data_err; - if (n == -1) - goto file_err; - draconian_FILE = NULL; - alarm(0); -#ifdef TRANSFER_COUNT - file_count_total++; - file_count_in++; - xfer_count_total++; - xfer_count_in++; -#endif - return (0); - - case TYPE_E: - reply(553, "TYPE E not implemented."); - transflag = 0; - return (-1); - - case TYPE_A: - draconian_FILE = instr; - (void) signal(SIGALRM, draconian_alarm_signal); - alarm(timeout_data); - while ((draconian_FILE != NULL) && -#if defined(USE_GSS) - ((c = sec_getc(instr)) != EOF) -#else - ((c = getc(instr)) != EOF) -#endif - ) { - if (++byte_count % 4096 == 0) - alarm(timeout_data); - if (c == '\n') - bare_lfs++; - while (c == '\r') { - if (ferror(outstr)) - goto file_err; - alarm(timeout_data); - if (draconian_FILE != NULL) { -#if defined(USE_GSS) - if ((c = sec_getc(instr)) != '\n') -#else - if ((c = getc(instr)) != '\n') -#endif - (void) putc('\r', outstr); -#ifdef TRANSFER_COUNT - data_count_total++; - data_count_in++; - byte_count_total++; - byte_count_in++; -#endif - if (c == EOF) /* null byte fix, noid@cyborg.larc.nasa.gov */ - goto contin2; - if (++byte_count % 4096 == 0) - alarm(timeout_data); - } - } - (void) putc(c, outstr); -#ifdef TRANSFER_COUNT - data_count_total++; - data_count_in++; - byte_count_total++; - byte_count_in++; -#endif - contin2:; - } - fflush(outstr); - if ((draconian_FILE == NULL) || ferror(instr)) - goto data_err; - if (ferror(outstr)) - goto file_err; - transflag = 0; - draconian_FILE = NULL; - alarm(0); - if (bare_lfs) { - lreply(226, "WARNING! %d bare linefeeds received in ASCII mode", bare_lfs); - lreply(0, " File may not have transferred correctly."); - } -#ifdef TRANSFER_COUNT - file_count_total++; - file_count_in++; - xfer_count_total++; - xfer_count_in++; -#endif - return (0); - default: - reply(550, "Unimplemented TYPE %d in receive_data", type); - transflag = 0; - return (-1); - } - - data_err: - draconian_FILE = NULL; - alarm(0); - transflag = 0; - perror_reply(426, "Data Connection"); - return (-1); - - file_err: - draconian_FILE = NULL; - alarm(0); - transflag = 0; - perror_reply(452, "Error writing file"); - return (-1); -} - -void statfilecmd(char *filename) -{ -#ifndef INTERNAL_LS - char line[BUFSIZ * 2], *ptr; - FILE *fin; - int c; -#endif /* ! INTERNAL_LS */ - - fixpath(filename); - if (filename[0] == '\0') - filename = "."; -#ifndef INTERNAL_LS - if (anonymous && dolreplies) - (void) snprintf(line, sizeof(line), ls_long, filename); - else - (void) snprintf(line, sizeof(line), ls_short, filename); - fin = ftpd_popen(line, "r", 0); -#endif /* ! INTERNAL_LS */ - lreply(213, "status of %s:", filename); -#ifndef INTERNAL_LS - /* - while ((c = getc(fin)) != EOF) { - if (c == '\n') { - if (ferror(stdout)) { - perror_reply(421, "control connection"); - (void) ftpd_pclose(fin); - dologout(1); - / * NOTREACHED * / - } - if (ferror(fin)) { - perror_reply(551, filename); - (void) ftpd_pclose(fin); - return; - } - (void) putc('\r', stdout); - } - (void) putc(c, stdout); - } - */ - while (fgets(line, sizeof(line), fin) != NULL) { - if ((ptr = strchr(line, '\n'))) /* clip out unnecessary newline */ - *ptr = '\0'; - lreply(0, "%s", line); - } - (void) ftpd_pclose(fin); -#else /* INTERNAL_LS */ - ls_dir(filename, 1, 0, 1, 0, 1, stdout); -#endif /* INTERNAL_LS */ - reply(213, "End of Status"); -} - -void statcmd(void) -{ - struct SOCKSTORAGE *sin; - u_char *a, *p; - unsigned short port; -#ifdef INET6 - int isv4 = 0; -#endif - - lreply(211, "%s FTP server status:", hostname); - lreply(0, " %s", version); - if (nameserved) - lreply(0, " Connected to %s (%s)", remotehost, remoteaddr); - else - lreply(0, " Connected to %s", remotehost); - - if (logged_in) { - if (anonymous) - lreply(0, " Logged in anonymously"); - else - lreply(0, " Logged in as %s", pw->pw_name); - } - else if (askpasswd) - lreply(0, " Waiting for password"); - else - lreply(0, " Waiting for user name"); - - if (type == TYPE_L) -#ifdef NBBY - lreply(0, " TYPE: %s %d; STRUcture: %s; transfer MODE: %s", - typenames[type], NBBY, strunames[stru], modenames[mode]); -#else - lreply(0, " TYPE: %s %d; STRUcture: %s; transfer MODE: %s", - typenames[type], bytesize, strunames[stru], modenames[mode]); -#endif /* NBBY */ - else - lreply(0, " TYPE: %s%s%s; STRUcture: %s; transfer MODE: %s", - typenames[type], (type == TYPE_A || type == TYPE_E) ? - ", FORM: " : "", (type == TYPE_A || type == TYPE_E) ? - formnames[form] : "", strunames[stru], modenames[mode]); - if (data != -1) - lreply(0, " Data connection open"); - else if (pdata != -1 || usedefault == 0) { - if (usedefault == 0) { - sin = &data_dest; - port = SOCK_PORT(data_dest); - } - else { - port = SOCK_PORT(pasv_addr); - if (route_vectored) - sin = &vect_addr; - else - sin = &pasv_addr; - } - a = (u_char *) SOCK_ADDR(*sin); - p = (u_char *) &port; -#define UC(b) (((int) b) & 0xff) -#ifdef INET6 - if (SOCK_FAMILY(*sin) == AF_INET) - isv4 = 1; - else if (IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)sin)->sin6_addr)) - { - isv4 = 1; - a += 12; /* move to the IPv4 part of an IPv4-mapped IPv6 address */ - } - if (epsv_all) - lreply(0, " EPSV only mode (EPSV ALL)"); - if (isv4 && !epsv_all) -#endif - lreply(0, " %s (%d,%d,%d,%d,%d,%d)", - usedefault == 0 ? "PORT" : "PASV", - UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), UC(p[0]), UC(p[1])); -#ifdef INET6 - lreply(0, " %s (|%d|%s|%d|)", usedefault == 0 ? "EPRT" : "EPSV", - isv4 ? 1 : 2, inet_stop(sin), ntohs(port)); - if (!epsv_all) - if (isv4) - lreply(0, " %s (4,4,%d,%d,%d,%d,2,%d,%d)", - usedefault == 0 ? "LPRT" : "LPSV", - UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), - UC(p[0]), UC(p[1])); - else - lreply(0, " %s (6,16,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d," - "%d,%d,%d,%d,2,%d,%d)", - usedefault == 0 ? "LPRT" : "LPSV", - UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), - UC(a[4]), UC(a[5]), UC(a[6]), UC(a[7]), - UC(a[8]), UC(a[9]), UC(a[10]), UC(a[11]), - UC(a[12]), UC(a[13]), UC(a[14]), UC(a[15]), - UC(p[0]), UC(p[1])); -#endif -#undef UC - } - else - lreply(0, " No data connection"); -#ifdef TRANSFER_COUNT - lreply(0, " %" L_FORMAT " data bytes received in %d files", data_count_in, file_count_in); - lreply(0, " %" L_FORMAT " data bytes transmitted in %d files", data_count_out, file_count_out); - lreply(0, " %" L_FORMAT " data bytes total in %d files", data_count_total, file_count_total); - lreply(0, " %" L_FORMAT " traffic bytes received in %d transfers", byte_count_in, xfer_count_in); - lreply(0, " %" L_FORMAT " traffic bytes transmitted in %d transfers", byte_count_out, xfer_count_out); - lreply(0, " %" L_FORMAT " traffic bytes total in %d transfers", byte_count_total, xfer_count_total); -#endif - reply(211, "End of status"); -} - -void fatal(char *s) -{ - reply(451, "Error in server: %s\n", s); - reply(221, "Closing connection due to server error."); - dologout(0); - /* NOTREACHED */ -} - -#define USE_REPLY_NOTFMT (1<<1) /* fmt is not a printf fmt (KLUDGE) */ -#define USE_REPLY_LONG (1<<2) /* this is a long reply; use a - */ - -void vreply(long flags, int n, char *fmt, va_list ap) -{ - char buf[BUFSIZ * 16]; - - flags &= USE_REPLY_NOTFMT | USE_REPLY_LONG; - - if (n) /* if numeric is 0, don't output one; use n==0 in place of printf's */ - sprintf(buf, "%03d%c", n, flags & USE_REPLY_LONG ? '-' : ' '); - - /* This is somewhat of a kludge for autospout. I personally think that - * autospout should be done differently, but that's not my department. -Kev - */ - if (flags & USE_REPLY_NOTFMT) - snprintf(buf + (n ? 4 : 0), n ? sizeof(buf) - 4 : sizeof(buf), "%s", fmt); - else - vsnprintf(buf + (n ? 4 : 0), n ? sizeof(buf) - 4 : sizeof(buf), fmt, ap); - -#if defined(USE_GSS) - if (IS_GSSAUTH(cur_auth_type) && - (gss_info.authstate & GSS_ADAT_DONE) && - gss_info.ctrl_prot != PROT_C) { - if (buf[strlen(buf)-1] != '\n') - strlcat(buf, "\r\n", sizeof(buf)); - (void) sec_reply(buf, sizeof(buf), n); - } -#endif - - if (debug) /* debugging output :) */ - syslog(LOG_DEBUG, "<--- %s", buf); - - /* Yes, you want the debugging output before the client output; wrapping - * stuff goes here, you see, and you want to log the cleartext and send - * the wrapped text to the client. - */ - - printf("%s\r\n", buf); /* and send it to the client */ -#ifdef TRANSFER_COUNT - byte_count_total += strlen(buf); - byte_count_out += strlen(buf); -#endif - /* - * We dont need to worry about "sec_fflush" here since "sec_reply" - * already wrapped the reply if necessary. - */ - fflush(stdout); -} - -void reply(int n, char *fmt,...) -{ - VA_LOCAL_DECL - - if (autospout != NULL) { /* deal with the autospout stuff... */ - char *p, *ptr = autospout; - - while (*ptr) { - if ((p = strchr(ptr, '\n')) != NULL) /* step through line by line */ - *p = '\0'; - - /* send a line...(note that this overrides dolreplies!) */ - vreply(USE_REPLY_LONG | USE_REPLY_NOTFMT, n, ptr, ap); - - if (p) - ptr = p + 1; /* set to the next line... (\0 is handled in the while) */ - else - break; /* oh, we're done; drop out of the loop */ - } - - if (autospout_free) { /* free autospout if necessary */ - (void) free(autospout); - autospout_free = 0; - } - autospout = 0; /* clear the autospout */ - } - - VA_START(fmt); - - /* send the reply */ - vreply(0L, n, fmt, ap); - - VA_END; -} - -void lreply(int n, char *fmt,...) -{ - VA_LOCAL_DECL - - if (!dolreplies) /* prohibited from doing long replies? */ - return; - - VA_START(fmt); - - /* send the reply */ - vreply(USE_REPLY_LONG, n, fmt, ap); - - VA_END; -} - -void ack(char *s) -{ - reply(250, "%s command successful.", s); -} - -void nack(char *s) -{ - reply(502, "%s command not implemented.", s); -} - -void yyerror(char *s) -{ - char *cp; - if (s == NULL || yyerrorcalled != 0) - return; - if ((cp = strchr(cbuf, '\n')) != NULL) - *cp = '\0'; - reply(500, "'%s': command not understood.", cbuf); - yyerrorcalled = 1; - return; -} - -void delete(char *name) -{ - struct stat st; - char realname[MAXPATHLEN]; - - /* - * delete permission? - */ - - wu_realpath(name, realname, chroot_path); - - if ((del_check(name)) == 0) { - if (log_security) - if (anonymous) - syslog(LOG_NOTICE, "anonymous(%s) of %s tried to delete %s", - guestpw, remoteident, realname); - else - syslog(LOG_NOTICE, "%s of %s tried to delete %s", - pw->pw_name, remoteident, realname); - return; - } - - if (lstat(name, &st) < 0) { - perror_reply(550, name); - return; - } - if ((st.st_mode & S_IFMT) == S_IFDIR) { - uid_t uid; - gid_t gid; - int d_mode; - int valid; - - /* - * check the directory, can we rmdir here? - */ - if ((dir_check(name, &uid, &gid, &d_mode, &valid)) <= 0) { - if (log_security) - if (anonymous) - syslog(LOG_NOTICE, "anonymous(%s) of %s tried to delete directory %s", - guestpw, remoteident, realname); - else - syslog(LOG_NOTICE, "%s of %s tried to delete directory %s", - pw->pw_name, remoteident, realname); - return; - } - - if (rmdir(name) < 0) { - if (log_security) - if (anonymous) - syslog(LOG_NOTICE, "anonymous(%s) of %s tried to delete directory %s (permissions)", - guestpw, remoteident, realname); - else - syslog(LOG_NOTICE, "%s of %s tried to delete directory %s (permissions)", - pw->pw_name, remoteident, realname); - perror_reply(550, name); - return; - } - goto done; - } - if (unlink(name) < 0) { - if (log_security) - if (anonymous) - syslog(LOG_NOTICE, "anonymous(%s) of %s tried to delete %s (permissions)", - guestpw, remoteident, realname); - else - syslog(LOG_NOTICE, "%s of %s tried to delete %s (permissions)", - pw->pw_name, remoteident, realname); - perror_reply(550, name); - return; - } - done: - { - char path[MAXPATHLEN]; - - wu_realpath(name, path, chroot_path); - - if (log_security) - if ((st.st_mode & S_IFMT) == S_IFDIR) - if (anonymous) { - syslog(LOG_NOTICE, "%s of %s deleted directory %s", guestpw, remoteident, path); - } - else { - syslog(LOG_NOTICE, "%s of %s deleted directory %s", pw->pw_name, - remoteident, path); - } - else if (anonymous) { - syslog(LOG_NOTICE, "%s of %s deleted %s", guestpw, - remoteident, path); - } - else { - syslog(LOG_NOTICE, "%s of %s deleted %s", pw->pw_name, - remoteident, path); - } - } - - ack("DELE"); -} - -void cwd(char *path) -{ - struct aclmember *entry = NULL; - char cdpath[MAXPATHLEN]; - - if (chdir(path) < 0) { - /* alias checking */ - while (getaclentry("alias", &entry) && ARG0 && ARG1 != NULL) { - if (!strcasecmp(ARG0, path)) { - if (chdir(ARG1) < 0) - perror_reply(550, path); - else { - show_message(250, C_WD); - show_readme(250, C_WD); - ack("CWD"); - } - return; - } - } - /* check for "cdpath" directories. */ - entry = (struct aclmember *) NULL; - while (getaclentry("cdpath", &entry) && ARG0 != NULL) { - snprintf(cdpath, sizeof cdpath, "%s/%s", ARG0, path); - if (chdir(cdpath) >= 0) { - show_message(250, C_WD); - show_readme(250, C_WD); - ack("CWD"); - return; - } - } - perror_reply(550, path); - } - else { - show_message(250, C_WD); - show_readme(250, C_WD); - ack("CWD"); - } -} - -void makedir(char *name) -{ - uid_t uid; - gid_t gid; - int d_mode; - mode_t oldumask; - int valid; - int ret, serrno; - uid_t oldid; - char path[MAXPATHLEN + 1]; /* for realpath() later - cky */ - char realname[MAXPATHLEN]; - - wu_realpath(name, realname, chroot_path); - /* - * check the directory, can we mkdir here? - */ - if ((dir_check(name, &uid, &gid, &d_mode, &valid)) <= 0) { - if (log_security) - if (anonymous) - syslog(LOG_NOTICE, "anonymous(%s) of %s tried to create directory %s", - guestpw, remoteident, realname); - else - syslog(LOG_NOTICE, "%s of %s tried to create directory %s", - pw->pw_name, remoteident, realname); - return; - } - - /* - * check the filename, is it legal? - */ - if ((fn_check(name)) <= 0) { - if (log_security) - if (anonymous) - syslog(LOG_NOTICE, "anonymous(%s) of %s tried to create directory %s (path-filter)", - guestpw, remoteident, realname); - else - syslog(LOG_NOTICE, "%s of %s tried to create directory %s (path-filter)", - pw->pw_name, remoteident, realname); - return; - } - - oldumask = umask(0000); - if (valid <= 0) { - d_mode = 0777; - umask(oldumask); - } - - if (mkdir(name, d_mode) < 0) { - if (errno == EEXIST) { - if (log_security) - if (anonymous) - syslog(LOG_NOTICE, "anonymous(%s) of %s tried to create directory %s (exists)", - guestpw, remoteident, realname); - else - syslog(LOG_NOTICE, "%s of %s tried to create directory %s (exists)", - pw->pw_name, remoteident, realname); - fb_realpath(name, path); - reply(521, "\"%s\" directory exists", path); - } - else { - if (log_security) - if (anonymous) - syslog(LOG_NOTICE, "anonymous(%s) of %s tried to create directory %s (permissions)", - guestpw, remoteident, realname); - else - syslog(LOG_NOTICE, "%s of %s tried to create directory %s (permissions)", - pw->pw_name, remoteident, realname); - perror_reply(550, name); - } - umask(oldumask); - return; - } - umask(oldumask); - if (valid > 0) { - oldid = geteuid(); - if (uid != 0) - (void) seteuid((uid_t) uid); - if ((uid == 0) || ((chown(name, uid, gid)) < 0)) { - chown_priv_on(0); - ret = chown(name, uid, gid); - serrno = errno; - chown_priv_off(oldid); - if (ret < 0) { - errno = serrno; - perror_reply(550, "chown"); - return; - } - } - else - (void) seteuid(oldid); - } - wu_realpath(name, path, chroot_path); - if (log_security) - if (anonymous) { - syslog(LOG_NOTICE, "%s of %s created directory %s", guestpw, remoteident, path); - } - else { - syslog(LOG_NOTICE, "%s of %s created directory %s", pw->pw_name, - remoteident, path); - } - fb_realpath(name, path); - /* According to RFC 959: - * The 257 reply to the MKD command must always contain the - * absolute pathname of the created directory. - * This is implemented here using similar code to the PWD command. - * XXX - still need to do `quote-doubling'. - */ - reply(257, "\"%s\" new directory created.", path); -} - -void removedir(char *name) -{ - uid_t uid; - gid_t gid; - int d_mode; - int valid; - char realname[MAXPATHLEN]; - - wu_realpath(name, realname, chroot_path); - - /* - * delete permission? - */ - - if ((del_check(name)) == 0) - return; - /* - * check the directory, can we rmdir here? - */ - if ((dir_check(name, &uid, &gid, &d_mode, &valid)) <= 0) { - if (log_security) - if (anonymous) - syslog(LOG_NOTICE, "anonymous(%s) of %s tried to remove directory %s", - guestpw, remoteident, realname); - else - syslog(LOG_NOTICE, "%s of %s tried to remove directory %s", - pw->pw_name, remoteident, realname); - return; - } - - if (rmdir(name) < 0) { - if (errno == EBUSY) - perror_reply(450, name); - else { - if (log_security) - if (anonymous) - syslog(LOG_NOTICE, "anonymous(%s) of %s tried to remove directory %s (permissions)", - guestpw, remoteident, realname); - else - syslog(LOG_NOTICE, "%s of %s tried to remove directory %s (permissions)", - pw->pw_name, remoteident, realname); - perror_reply(550, name); - } - } - else { - char path[MAXPATHLEN]; - - wu_realpath(name, path, chroot_path); - - if (log_security) - if (anonymous) { - syslog(LOG_NOTICE, "%s of %s deleted directory %s", guestpw, remoteident, path); - } - else { - syslog(LOG_NOTICE, "%s of %s deleted directory %s", pw->pw_name, - remoteident, path); - } - ack("RMD"); - } -} - -void pwd(void) -{ - char path[MAXPATHLEN + 1]; - char rhome[MAXPATHLEN + 1]; - char *rpath = path; /* Path to return to client */ - int pathlen; -#ifndef MAPPING_CHDIR -#ifdef HAVE_GETCWD - extern char *getcwd(); -#else - extern char *getwd(char *); -#endif -#endif /* MAPPING_CHDIR */ - -#ifdef HAVE_GETCWD - if (getcwd(path, MAXPATHLEN) == (char *) NULL) -#else - if (getwd(path) == (char *) NULL) -#endif -/* Dink! If you couldn't get the path and the buffer is now likely to - be undefined, why are you trying to PRINT it?! _H* - reply(550, "%s.", path); */ - { - fb_realpath(".", path); /* realpath_on_steroids can deal */ - } - /* relative to home directory if restricted_user */ - if (restricted_user) { - /* - * Re-adjust real path because previous call to getXwd() did - * not resolve symlink. - */ - fb_realpath(".", path); - fb_realpath(home, rhome); - pathlen = strlen(rhome); - if (pathlen && rhome[pathlen - 1] == '/') - pathlen--; - rpath = rpath + pathlen; - if (!*rpath) - strcpy(rpath, "/"); - } - reply(257, "\"%s\" is current directory.", rpath); -} - -char *renamefrom(char *name) -{ - struct stat st; - - if (lstat(name, &st) < 0) { - perror_reply(550, name); - return ((char *) 0); - } - reply(350, "File exists, ready for destination name"); - return (name); -} - -void renamecmd(char *from, char *to) -{ - int allowed = (anonymous ? 0 : 1); - char realfrom[MAXPATHLEN]; - char realto[MAXPATHLEN]; - struct aclmember *entry = NULL; -#ifdef PARANOID - struct stat st; -#endif - wu_realpath(from, realfrom, chroot_path); - wu_realpath(to, realto, chroot_path); - /* - * check the filename, is it legal? - */ - if ((fn_check(to)) == 0) { - if (log_security) - if (anonymous) - syslog(LOG_NOTICE, "anonymous(%s) of %s tried to rename %s to \"%s\" (path-filter)", - guestpw, remoteident, realfrom, realto); - else - syslog(LOG_NOTICE, "%s of %s tried to rename %s to \"%s\" (path-filter)", - pw->pw_name, remoteident, realfrom, realto); - return; - } - - /* - * if rename permission denied and file exists... then deny the user - * permission to rename the file. - */ - while (getaclentry("rename", &entry) && ARG0 && ARG1 != NULL) { - if (type_match(ARG1)) - if (anonymous) { - if (*ARG0 == 'y') - allowed = 1; - } - else if (*ARG0 == 'n') - allowed = 0; - } - if (!allowed) { - if (log_security) - if (anonymous) - syslog(LOG_NOTICE, "anonymous(%s) of %s tried to rename %s to %s", - guestpw, remoteident, realfrom, realto); - else - syslog(LOG_NOTICE, "%s of %s tried to rename %s to %s", - pw->pw_name, remoteident, realfrom, realto); - reply(553, "%s: Permission denied on server. (rename)", from); - return; - } - - -#ifdef PARANOID -/* Almost forgot about this. Don't allow renaming TO existing files -- - otherwise someone can rename "trivial" to "warez", and "warez" is gone! - XXX: This part really should do the same "overwrite" check as store(). */ - if (!stat(to, &st)) { - if (log_security) - if (anonymous) - syslog(LOG_NOTICE, "anonymous(%s) of %s tried to rename %s to %s", - guestpw, remoteident, realfrom, realto); - else - syslog(LOG_NOTICE, "%s of %s tried to rename %s to %s", - pw->pw_name, remoteident, realfrom, realto); - reply(550, "%s: Permission denied on server. (rename)", to); - return; - } -#endif - if (rename(from, to) < 0) { - if (log_security) - if (anonymous) - syslog(LOG_NOTICE, "anonymous(%s) of %s tried to rename %s to %s", - guestpw, remoteident, realfrom, realto); - else - syslog(LOG_NOTICE, "%s of %s tried to rename %s to %s", - pw->pw_name, remoteident, realfrom, realto); - perror_reply(550, "rename"); - } - else { - char frompath[MAXPATHLEN]; - char topath[MAXPATHLEN]; - - wu_realpath(from, frompath, chroot_path); - wu_realpath(to, topath, chroot_path); - - if (log_security) - if (anonymous) { - syslog(LOG_NOTICE, "%s of %s renamed %s to %s", guestpw, remoteident, frompath, topath); - } - else { - syslog(LOG_NOTICE, "%s of %s renamed %s to %s", pw->pw_name, - remoteident, frompath, topath); - } - ack("RNTO"); - } -} - -void dolog(struct SOCKSTORAGE *sin) -{ - char *blah; - int rval; - - blah = inet_stop(sin); - (void) strncpy(remoteaddr, blah, sizeof(remoteaddr)); - nameserved = 0; - (void) strncpy(remotehost, remoteaddr, sizeof(remotehost)); - - rhlookup = rhostlookup(remoteaddr); - if (rhlookup) { - if (!strcasecmp(remoteaddr, "0.0.0.0")) { - nameserved = 1; - strncpy(remotehost, "localhost", sizeof(remotehost)); - } - else { -#ifdef DNS_TRYAGAIN - int num_dns_tries = 0; - /* - * 27-Apr-93 EHK/BM - * far away connections might take some time to get their IP address - * resolved. That's why we try again -- maybe our DNS cache has the - * PTR-RR now. This code is sloppy. Far better is to check what the - * resolver returned so that in case of error, there's no need to - * try again. - */ - dns_again: -#endif /* DNS_TRYAGAIN */ - - rval = wu_gethostbyaddr(sin, remotehost, sizeof(remotehost)); - -#ifdef DNS_TRYAGAIN - if (!rval && ++num_dns_tries <= 1) { - sleep(3); - goto dns_again; /* try DNS lookup once more */ - } -#endif /* DNS_TRYAGAIN */ - - if (rval) - nameserved = 1; - } - } - - remotehost[sizeof(remotehost) - 1] = '\0'; - sprintf(proctitle, "%s: connected", remotehost); - setproctitle("%s", proctitle); - - wu_authenticate(); -/* Create a composite source identification string, to improve the logging - * when RFC 931 is being used. */ - { - int n = 20 + strlen(remotehost) + strlen(remoteaddr) + - (authenticated ? strlen(authuser + 5) : 0); - if ((remoteident = malloc(n)) == NULL) { - syslog(LOG_ERR, "malloc: %m"); -#ifndef DEBUG - exit(1); -#endif - } - else if (authenticated) - sprintf(remoteident, "%s @ %s [%s]", - authuser, remotehost, remoteaddr); - else - sprintf(remoteident, "%s [%s]", remotehost, remoteaddr); - } -#ifdef DAEMON - if (be_daemon && logging) - syslog(LOG_INFO, "connection from %s", remoteident); -#else -#if 0 /* this is redundant unless the caller doesn't do *anything*, and - tcpd will pick it up and deal with it better anyways. _H */ - if (logging) - syslog(LOG_INFO, "connection from %s", remoteident); -#endif -#endif -} - -/* Record logout in wtmp file and exit with supplied status. */ - -void dologout(int status) -{ - /* - * Prevent reception of SIGURG from resulting in a resumption - * back to the main program loop. - */ - transflag = 0; - - /* - * Cancel any pending alarm request, reception of SIGALRM would cause - * dologout() to be called again from the SIGALRM handler toolong(). - */ - (void) alarm(0); - - if (logged_in) { - delay_signaling(); /* we can't allow any signals while euid==0: kinch */ -#if defined(SOLARIS_BSM_AUDIT) && !defined(SOLARIS_NO_AUDIT_FTPD_LOGOUT) - audit_ftpd_logout(); -#endif - (void) seteuid((uid_t) 0); - if (wtmp_logging) - wu_logwtmp(ttyline, pw->pw_name, remotehost, 0); -#ifdef USE_PAM - if (!anonymous && pamh) { - (void) pam_close_session(pamh, 0); - (void) pam_end(pamh, PAM_SUCCESS); - pamh = (pam_handle_t *)0; - } -#endif - } - if (logging) - syslog(LOG_INFO, "FTP session closed"); - if (xferlog) - close(xferlog); - acl_remove(); - if (data >= 0) - close(data); - if (pdata >= 0) - close(pdata); -#ifdef AFS_AUTH - ktc_ForgetAllTokens(); -#endif - /* beware of flushing buffers after a SIGPIPE */ - _exit(status); -} - -SIGNAL_TYPE myoob(int sig) -{ - char *cp; -#ifdef SIGPIPE - void (*pipe_handler)(); -#endif - - /* only process if transfer occurring */ - if (!transflag) { -#ifdef SIGURG - (void) signal(SIGURG, myoob); -#endif - return; - } -#ifdef SIGPIPE - pipe_handler = signal(SIGPIPE, lostconn); -#endif - cp = tmpline; - if (wu_getline(cp, sizeof(tmpline) - 1, stdin) == NULL) { - reply(221, "You could at least say goodbye."); - dologout(0); - } - upper(cp); - if (strcasecmp(cp, "ABOR\r\n") == 0) { - tmpline[0] = '\0'; - reply(426, "Transfer aborted. Data connection closed."); - reply(226, "Abort successful"); -#ifdef SIGPIPE - (void) signal(SIGPIPE, pipe_handler); -#endif -#ifdef SIGURG - (void) signal(SIGURG, myoob); -#endif - if (ftwflag > 0) { - ftwflag++; - return; - } - wu_longjmp(urgcatch, 1); - } - if (strcasecmp(cp, "STAT\r\n") == 0) { - tmpline[0] = '\0'; - if (file_size != (off_t) - 1) - reply(213, "Status: %" L_FORMAT " of %" L_FORMAT " bytes transferred", - byte_count, file_size); - else - reply(213, "Status: %" L_FORMAT " bytes transferred", byte_count); - } -#ifdef SIGPIPE - (void) signal(SIGPIPE, pipe_handler); -#endif -#ifdef SIGURG - (void) signal(SIGURG, myoob); -#endif -} - -/* Note: a response of 425 is not mentioned as a possible response to the - * PASV command in RFC959. However, it has been blessed as a legitimate - * response by Jon Postel in a telephone conversation with Rick Adams on 25 - * Jan 89. */ - -void passive(int passive_mode, int proto) -{ - /* First prime number after 2^n where 4 <= n <= 16 */ - static int primes[] = {17,37,67,131,257,521,1031,2053,4099,8209,16411,32771,65537,0}; - static int prime = 0; - static int range; -#if defined(UNIXWARE) || defined(AIX) - size_t len; -#else - int len; -#endif - int bind_error, serrno; - int on = 1; - int i, j, inc, val; - unsigned short port; - register char *p, *a; - struct SOCKSTORAGE *reply_addr; - struct timeval tv; -#ifdef INET6 - int isv4 = 0; -#endif - -/* H* fix: if we already *have* a passive socket, close it first. Prevents - a whole variety of entertaining clogging attacks. */ - if (pdata >= 0) { - close(pdata); - pdata = -1; - } - if (!logged_in) { - reply(530, "Login with USER first."); - return; - } -#ifdef INET6 - switch (proto) { - case 0: - if ((passive_mode == TYPE_PASV) && (SOCK_FAMILY(ctrl_addr) == AF_INET6) - && !ctrl_v4mapped) { - reply(501, "Network protocol mismatch"); - return; - } - else - pasv_addr = ctrl_addr; - break; - case 1: - if (SOCK_FAMILY(ctrl_addr) == AF_INET) - pasv_addr = ctrl_addr; - else if (ctrl_v4mapped) { - struct sockaddr_in6 *ctrl_sin6 = (struct sockaddr_in6 *)&ctrl_addr; - struct sockaddr_in *pasv_sin = (struct sockaddr_in *)&pasv_addr; - - SET_SOCK_FAMILY(pasv_addr, AF_INET); - memcpy(&pasv_sin->sin_addr, &ctrl_sin6->sin6_addr.s6_addr[12], - sizeof(struct in_addr)); - } - else { - reply(522, "Network protocol mismatch, use (2)"); - return; - } - break; - case 2: - if ((SOCK_FAMILY(ctrl_addr) == AF_INET6) && !ctrl_v4mapped) - pasv_addr = ctrl_addr; - else { - reply(522, "Network protocol mismatch, use (1)"); - return; - } - break; - default: - reply(522, "Network protocol not supported, use (1,2)"); - return; - } -#else - pasv_addr = ctrl_addr; -#endif - - if (passive_port_min == 0 && passive_port_max == 0) { - /* let the kernel allocate the port */ - SET_SOCK_PORT(pasv_addr, 0); - } - else if (prime == 0) { - range = passive_port_max - passive_port_min + 1; - - /* find the first prime greater than the range in the primes list */ - for (i = 0; primes[i] != 0 && range >= primes[i]; i++) - ; - /* shouldn't happen, but check just in case */ - if (primes[i] == 0) { - syslog(LOG_ERR, "passive ports range too large %d-%d", passive_port_min, passive_port_max); - /* let the kernel allocate the port */ - SET_SOCK_PORT(pasv_addr, 0); - } - else - prime = primes[i]; - } - len = SOCK_LEN(pasv_addr); - - port_priv_on(0); /* necessary as port can be < 1024 */ - pdata = socket(SOCK_FAMILY(pasv_addr), SOCK_STREAM, 0); - if (pdata < 0) { - serrno = errno; - port_priv_off((uid_t) pw->pw_uid); - errno = serrno; - perror_reply(425, "Can't open passive connection"); - return; - } - if (keepalive) - (void) setsockopt(pdata, SOL_SOCKET, SO_KEEPALIVE, (char *) &on, sizeof(on)); - if (TCPwindowsize) { - (void) setsockopt(pdata, SOL_SOCKET, SO_SNDBUF, (char *) &TCPwindowsize, sizeof(TCPwindowsize)); - (void) setsockopt(pdata, SOL_SOCKET, SO_RCVBUF, (char *) &TCPwindowsize, sizeof(TCPwindowsize)); - } - - bind_error = -1; - errno = EADDRINUSE; - - /* try each port in the specified range a maximum of 3 times */ - for (i = 0; i < 3 && bind_error != 0 && \ - ((errno == EADDRINUSE) || (errno == EACCES)); i++) { - if (i > 0) - sleep(i); - if (SOCK_PORT(pasv_addr) == 0) - bind_error = bind(pdata, (struct sockaddr *) &pasv_addr, len); - else { - gettimeofday(&tv, NULL); - srand(tv.tv_usec + tv.tv_sec); - inc = 1 + (int) ((1.0 * (prime - 1) * rand()) / (RAND_MAX + 1.0)); - val = (int) ((1.0 * range * rand()) / (RAND_MAX + 1.0)); - /* - * Using the modulus operator with a prime number allows us to - * try each port in the range once. - */ - for (j = 0; j < range && bind_error != 0 && \ - ((errno == EADDRINUSE) || (errno == EACCES)); j++) { - while ((val = ((val + inc) % prime)) >= range) - ; - SET_SOCK_PORT(pasv_addr, htons(val + passive_port_min)); - bind_error = bind(pdata, (struct sockaddr *) &pasv_addr, len); - } - } - } - serrno = errno; - port_priv_off((uid_t) pw->pw_uid); - if (bind_error != 0) { - errno = serrno; - goto pasv_error; - } - - /* if the kernel allocated the port, find out which one */ - if ((SOCK_PORT(pasv_addr) == 0) && - (getsockname(pdata, (struct sockaddr *) &pasv_addr, &len) < 0)) - goto pasv_error; - - if (listen(pdata, 1) < 0) - goto pasv_error; - usedefault = 1; - if (route_vectored) - reply_addr = &vect_addr; - else - reply_addr = &pasv_addr; - a = (char *) SOCK_ADDR(*reply_addr); - port = SOCK_PORT(pasv_addr); - p = (char *) &port; - -#define UC(b) (((int) b) & 0xff) - - if (debug) { - char *s = calloc(128 + strlen(remoteident), sizeof(char)); - if (s) { - int i = ntohs(port); - sprintf(s, "PASV port %i assigned to %s", i, remoteident); - syslog(LOG_DEBUG, "%s", s); - free(s); - } - } -#ifdef INET6 - if (SOCK_FAMILY(*reply_addr) == AF_INET) - isv4 = 1; - else if (IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)reply_addr)->sin6_addr)) { - isv4 = 1; - a += 12; /* move to the IPv4 part of an IPv4-mapped IPv6 address */ - } - switch (passive_mode) { - case TYPE_PASV: - reply(227, "Entering Passive Mode (%d,%d,%d,%d,%d,%d)", - UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), UC(p[0]), UC(p[1])); - return; - case TYPE_EPSV: - reply(229, "Entering Extended Passive Mode (|||%d|)", ntohs(port)); - return; - case TYPE_LPSV: - if (isv4) { - reply(228, "Entering Long Passive Mode " - "(%d,%d,%d,%d,%d,%d,%d,%d,%d)", - 4, 4, UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), - 2, UC(p[0]), UC(p[1])); - } - else { - reply(228, "Entering Long Passive Mode " - "(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d," - "%d,%d,%d,%d,%d)", 6, 16, - UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), - UC(a[4]), UC(a[5]), UC(a[6]), UC(a[7]), - UC(a[8]), UC(a[9]), UC(a[10]), UC(a[11]), - UC(a[12]), UC(a[13]), UC(a[14]), UC(a[15]), - 2, UC(p[0]), UC(p[1])); - } - return; - } -#else - reply(227, "Entering Passive Mode (%d,%d,%d,%d,%d,%d)", UC(a[0]), - UC(a[1]), UC(a[2]), UC(a[3]), UC(p[0]), UC(p[1])); - return; -#endif /* INET6 */ - - pasv_error: - perror_reply(425, "Can't open passive connection"); - (void) close(pdata); - pdata = -1; - if (debug) { - char *s = calloc(128 + strlen(remoteident), sizeof(char)); - if (s) { - sprintf(s, "PASV port assignment assigned for %s", remoteident); - syslog(LOG_DEBUG, "%s", s); - free(s); - } - } - return; -} - -/* - * Generate unique name for file with basename "local". The file named - * "local" is already known to exist. Generates failure reply on error. - */ -char *gunique(char *local) -{ - static char new[MAXPATHLEN]; - struct stat st; - char *cp = strrchr(local, '/'); - int count = 0; - - if (cp) - *cp = '\0'; - if (stat(cp ? local : ".", &st) < 0) { - perror_reply(553, cp ? local : "."); - return ((char *) 0); - } - if (cp) - *cp = '/'; - (void) strncpy(new, local, (sizeof new) - 3); - new[sizeof(new) - 3] = '\0'; - cp = new + strlen(new); - *cp++ = '.'; - for (count = 1; count < 100; count++) { - if (count == 10) { - cp -= 2; - *cp++ = '.'; - } - (void) sprintf(cp, "%d", count); - if (stat(new, &st) < 0) - return (new); - } - reply(452, "Unique file name cannot be created."); - return ((char *) 0); -} - -/* Format and send reply containing system error number. */ - -void perror_reply(int code, char *string) -{ - /* - * If restricted user and string starts with home dir path, strip it off - * and return only the relative path. - */ - if (restricted_user && (home != NULL) && (home[0] != '\0')) { - size_t len = strlen (home); - if (strncmp (home, string, len) == 0) { - if (string[len - 1] == '/') - string += len - 1; - else if (string[len] == '/') - string += len; - else if (string[len] == '\0') - string = "/"; - } - } - reply(code, "%s: %s.", string, strerror(errno)); -} - -static char *onefile[] = -{"", 0}; - -extern char **ftpglob(register char *v, boolean_t check_ncargs); -extern char *globerr; - -void send_file_list(char *whichfiles) -{ - /* static so not clobbered by longjmp(), volatile would also work */ - static FILE *dout; - static DIR *dirp; - static char **sdirlist; - static char *wildcard = NULL; - - struct stat st; - - register char **dirlist, *dirname; - int simple = 0; - int statret; - /* This is ANSI/ISO C .. strpbrk should be in which we've - ** already included so we don't need the following line. 'sides, it - ** breaks the GNU EGCS C compiler - ** extern char *strpbrk(const char *, const char *); - */ - -#ifdef TRANSFER_COUNT -#ifdef TRANSFER_LIMIT - if (((file_limit_raw_out > 0) && (xfer_count_out >= file_limit_raw_out)) - || ((file_limit_raw_total > 0) && (xfer_count_total >= file_limit_raw_total)) - || ((data_limit_raw_out > 0) && (byte_count_out >= data_limit_raw_out)) - || ((data_limit_raw_total > 0) && (byte_count_total >= data_limit_raw_total))) { - if (log_security) - if (anonymous) - syslog(LOG_NOTICE, "anonymous(%s) of %s tried to list files (Transfer limits exceeded)", - guestpw, remoteident); - else - syslog(LOG_NOTICE, "%s of %s tried to list files (Transfer limits exceeded)", - pw->pw_name, remoteident); - reply(553, "Permission denied on server. (Transfer limits exceeded)"); - return; - } -#endif -#endif - - draconian_FILE = NULL; - dout = NULL; - dirp = NULL; - sdirlist = NULL; - wildcard = NULL; - if (strpbrk(whichfiles, "~{[*?") == NULL) { - if (whichfiles[0] == '\0') { - wildcard = strdup("*"); - if (wildcard == NULL) { - reply(550, "Memory allocation error"); - goto globfree; - } - whichfiles = wildcard; - } - else { - if (statret=stat(whichfiles, &st) < 0) - statret=lstat(whichfiles, &st); /* Check if it's a dangling symlink */ - if (statret >= 0) { - if ((st.st_mode & S_IFMT) == S_IFDIR) { - wildcard = malloc(strlen(whichfiles) + 3); - if (wildcard == NULL) { - reply(550, "Memory allocation error"); - goto globfree; - } - strcpy(wildcard, whichfiles); - strcat(wildcard, "/*"); - whichfiles = wildcard; - } - } - } - } - if (strpbrk(whichfiles, "~{[*?") != NULL) { - globerr = NULL; - dirlist = ftpglob(whichfiles, B_FALSE); - sdirlist = dirlist; /* save to free later */ - if (globerr != NULL) { - reply(550, "%s", globerr); - goto globfree; - } - else if (dirlist == NULL) { - errno = ENOENT; - perror_reply(550, whichfiles); - goto globfree; - } - } - else { - onefile[0] = whichfiles; - dirlist = onefile; - simple = 1; - } - - if (wu_setjmp(urgcatch)) { - transflag = 0; - if (dout != NULL) - (void) fclose(dout); - if (dirp != NULL) - (void) closedir(dirp); - data = -1; - pdata = -1; - goto globfree; - } - while ((dirname = *dirlist++) != NULL) { - statret=stat(dirname, &st); - if (statret < 0) - statret=lstat(dirname, &st); /* Could be a dangling symlink */ - if (statret < 0) { - /* If user typed "ls -l", etc, and the client used NLST, do what - * the user meant. */ - if (dirname[0] == '-' && *dirlist == NULL && transflag == 0) { - retrieve_is_data = 0; -#ifndef INTERNAL_LS - retrieve(ls_plain, dirname); -#else - ls(dirname, 1); -#endif - retrieve_is_data = 1; - goto globfree; - } - perror_reply(550, dirname); - if (dout != NULL) { - (void) fclose(dout); - transflag = 0; - data = -1; - pdata = -1; - } - goto globfree; - } -#ifndef NLST_SHOWS_DIRS - if ((st.st_mode & S_IFMT) != S_IFDIR) -#endif - { - if (dout == NULL) { - dout = dataconn("file list", (off_t) - 1, "w"); - if (dout == NULL) - goto globfree; - transflag++; - draconian_FILE = dout; - } - if (draconian_FILE != NULL) { - (void) signal(SIGALRM, draconian_alarm_signal); - alarm(timeout_data); -#if defined(USE_GSS) - (void) sec_fprintf(dout, "%s%s\n", dirname, - type == TYPE_A ? "\r" : ""); -#else - fprintf(dout, "%s%s\n", dirname, - type == TYPE_A ? "\r" : ""); -#endif /* USE_GSS */ - } - byte_count += strlen(dirname) + 1; -#ifdef TRANSFER_COUNT - byte_count_total += strlen(dirname) + 1; - byte_count_out += strlen(dirname) + 1; - if (type == TYPE_A) { - byte_count_total++; - byte_count_out++; - } -#endif - } - } - - if (dout != NULL) { - if (draconian_FILE != NULL) { - (void) signal(SIGALRM, draconian_alarm_signal); - alarm(timeout_data); -#if defined(USE_GSS) - if (sec_fflush(dout) < 0) { - alarm(0); - perror_reply(550, "Data connection"); - goto sfl_cleanup; /* send file list cleanup */ - } -#else - fflush(dout); -#endif /* USE_GSS */ - } - if (draconian_FILE != NULL) { - (void) signal(SIGALRM, draconian_alarm_signal); - alarm(timeout_data); - socket_flush_wait(dout); - } - } - if (dout == NULL) - reply(550, "No files found."); - else if ((draconian_FILE == NULL) || ferror(dout) != 0) { - alarm(0); - perror_reply(550, "Data connection"); - } - else { -#ifdef TRANSFER_COUNT - xfer_count_total++; - xfer_count_out++; -#endif - alarm(0); - reply(226, "Transfer complete."); - } - sfl_cleanup: - transflag = 0; - if ((dout != NULL) && (draconian_FILE != NULL)) - (void) fclose(dout); - data = -1; - pdata = -1; - globfree: - if (wildcard != NULL) { - free(wildcard); - wildcard = NULL; - } - if (sdirlist) { - blkfree(sdirlist); - free((char *) sdirlist); - } -} - -/* - ** SETPROCTITLE -- set process title for ps - ** - ** Parameters: - ** fmt -- a printf style format string. - ** a, b, c -- possible parameters to fmt. - ** - ** Returns: - ** none. - ** - ** Side Effects: - ** Clobbers argv of our main procedure so ps(1) will - ** display the title. - */ - -#define SPT_NONE 0 /* don't use it at all */ -#define SPT_REUSEARGV 1 /* cover argv with title information */ -#define SPT_BUILTIN 2 /* use libc builtin */ -#define SPT_PSTAT 3 /* use pstat(PSTAT_SETCMD, ...) */ -#define SPT_PSSTRINGS 4 /* use PS_STRINGS->... */ -#define SPT_SYSMIPS 5 /* use sysmips() supported by NEWS-OS 6 */ -#define SPT_SCO 6 /* write kernel u. area */ -#define SPT_CHANGEARGV 7 /* write our own strings into argv[] */ -#define MAXLINE 2048 /* max line length for setproctitle */ -#define SPACELEFT(buf, ptr) (sizeof buf - ((ptr) - buf)) - -#ifndef SPT_TYPE -#define SPT_TYPE SPT_REUSEARGV -#endif - -#if SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN - -#if SPT_TYPE == SPT_PSTAT -#include -#endif -#if SPT_TYPE == SPT_PSSTRINGS -#include -#include -#ifndef PS_STRINGS /* hmmmm.... apparently not available after all */ -#undef SPT_TYPE -#define SPT_TYPE SPT_REUSEARGV -#else -#ifndef NKPDE /* FreeBSD 2.0 */ -#define NKPDE 63 -typedef unsigned int *pt_entry_t; -#endif -#endif -#endif - -#if SPT_TYPE == SPT_PSSTRINGS || SPT_TYPE == SPT_CHANGEARGV -#define SETPROC_STATIC static -#else -#define SETPROC_STATIC -#endif - -#if SPT_TYPE == SPT_SYSMIPS -#include -#include -#endif - -#if SPT_TYPE == SPT_SCO -#ifdef UNIXWARE -#include -#include -#include -#include -#else /* UNIXWARE */ -#include -#include -#include -#include -#endif /* UNIXWARE */ -#if PSARGSZ > MAXLINE -#define SPT_BUFSIZE PSARGSZ -#endif -#ifndef _PATH_KMEM -#define _PATH_KMEM "/dev/kmem" -#endif /* _PATH_KMEM */ -#endif /* SPT_SCO */ - -#ifndef SPT_PADCHAR -#define SPT_PADCHAR ' ' -#endif - -#ifndef SPT_BUFSIZE -#define SPT_BUFSIZE MAXLINE -#endif - -#endif /* SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN */ - -#if SPT_TYPE == SPT_REUSEARGV || SPT_TYPE == SPT_CHANGEARGV -char **Argv = NULL; /* pointer to argument vector */ -#endif - -#if SPT_TYPE == SPT_REUSEARGV -char *LastArgv = NULL; /* end of argv */ -#endif - -/* - ** Pointers for setproctitle. - ** This allows "ps" listings to give more useful information. - */ -void initsetproctitle(argc, argv, envp) - int argc; - char **argv; - char **envp; -{ -#if SPT_TYPE == SPT_REUSEARGV - register int i, envpsize = 0; - char **newenviron; - extern char **environ; - - /* - ** Save start and extent of argv for setproctitle. - */ - - LastArgv = argv[argc - 1] + strlen(argv[argc - 1]); - if (envp != NULL) { - /* - ** Move the environment so setproctitle can use the space at - ** the top of memory. - */ - for (i = 0; envp[i] != NULL; i++) - envpsize += strlen(envp[i]) + 1; - newenviron = (char **) malloc(sizeof(char *) * (i + 1)); - if (newenviron) { - int err = 0; - for (i = 0; envp[i] != NULL; i++) { - if ((newenviron[i] = strdup(envp[i])) == NULL) { - err = 1; - break; - } - } - if (err) { - for (i = 0; newenviron[i] != NULL; i++) - free(newenviron[i]); - free(newenviron); - i = 0; - } - else { - newenviron[i] = NULL; - environ = newenviron; - } - } - else { - i = 0; - } - - /* - ** Find the last environment variable within wu-ftpd's - ** process memory area. - */ - while (i > 0 && (envp[i - 1] < argv[0] || - envp[i - 1] > (argv[argc - 1] + strlen(argv[argc - 1]) + - 1 + envpsize))) - i--; - - if (i > 0) - LastArgv = envp[i - 1] + strlen(envp[i - 1]); - } -#endif /* SPT_TYPE == SPT_REUSEARGV */ - -#if SPT_TYPE == SPT_REUSEARGV || SPT_TYPE == SPT_CHANGEARGV - Argv = argv; -#endif -} - - -#if SPT_TYPE != SPT_BUILTIN - -/*VARARGS1 */ -void setproctitle(const char *fmt,...) -{ -#if SPT_TYPE != SPT_NONE - register char *p; - register int i; - SETPROC_STATIC char buf[SPT_BUFSIZE]; - VA_LOCAL_DECL -#if SPT_TYPE == SPT_PSTAT - union pstun pst; -#endif -#if SPT_TYPE == SPT_SCO - static off_t seek_off; - static int kmemfd = -1; - static int kmempid = -1; -#ifdef UNIXWARE - off_t offset; - void *ptr; - struct mioc_rksym rks; -#endif /* UNIXWARE */ -#endif /* SPT_SCO */ - - p = buf; - - /* print ftpd: heading for grep */ - (void) strcpy(p, "ftpd: "); - p += strlen(p); - - /* print the argument string */ - VA_START(fmt); - (void) vsnprintf(p, SPACELEFT(buf, p), fmt, ap); - VA_END; - - i = strlen(buf); - -#if SPT_TYPE == SPT_PSTAT - pst.pst_command = buf; - pstat(PSTAT_SETCMD, pst, i, 0, 0); -#endif -#if SPT_TYPE == SPT_PSSTRINGS - PS_STRINGS->ps_nargvstr = 1; - PS_STRINGS->ps_argvstr = buf; -#endif -#if SPT_TYPE == SPT_SYSMIPS - sysmips(SONY_SYSNEWS, NEWS_SETPSARGS, buf); -#endif -#if SPT_TYPE == SPT_SCO - if (kmemfd < 0 || kmempid != getpid()) { - if (kmemfd >= 0) - close(kmemfd); - if ((kmemfd = open(_PATH_KMEM, O_RDWR, 0)) < 0) - return; - (void) fcntl(kmemfd, F_SETFD, 1); - kmempid = getpid(); -#ifdef UNIXWARE - seek_off = 0; - rks.mirk_symname = "upointer"; - rks.mirk_buf = &ptr; - rks.mirk_buflen = sizeof(ptr); - if (ioctl(kmemfd, MIOC_READKSYM, &rks) < 0) - return; - offset = (off_t) ptr + (off_t) & ((struct user *) 0)->u_procp; - if (lseek(kmemfd, offset, SEEK_SET) != offset) - return; - if (read(kmemfd, &ptr, sizeof(ptr)) != sizeof(ptr)) - return; - offset = (off_t) ptr + (off_t) & ((struct proc *) 0)->p_execinfo; - if (lseek(kmemfd, offset, SEEK_SET) != offset) - return; - if (read(kmemfd, &ptr, sizeof(ptr)) != sizeof(ptr)) - return; - seek_off = (off_t) ptr + (off_t) ((struct execinfo *) 0)->ei_psargs; -#else /* UNIXWARE */ - seek_off = UVUBLK + (off_t) & ((struct user *) 0)->u_psargs; -#endif /* UNIXWARE */ - } -#ifdef UNIXWARE - if (seek_off == 0) - return; -#endif /* UNIXWARE */ - buf[PSARGSZ - 1] = '\0'; - if (lseek(kmemfd, (off_t) seek_off, SEEK_SET) == seek_off) - (void) write(kmemfd, buf, PSARGSZ); -#endif /* SPT_SCO */ -#if SPT_TYPE == SPT_REUSEARGV - if (i > LastArgv - Argv[0] - 2) { - i = LastArgv - Argv[0] - 2; - buf[i] = '\0'; - } - (void) strcpy(Argv[0], buf); - p = &Argv[0][i]; - while (p < LastArgv) - *p++ = SPT_PADCHAR; - Argv[1] = NULL; -#endif -#if SPT_TYPE == SPT_CHANGEARGV - Argv[0] = buf; - Argv[1] = 0; -#endif -#endif /* SPT_TYPE != SPT_NONE */ -} - -#endif /* SPT_TYPE != SPT_BUILTIN */ - -#ifdef KERBEROS -/* thanks to gshapiro@wpi.wpi.edu for the following kerberosities */ - -void init_krb() -{ - char hostname[100]; - -#ifdef HAVE_SYSINFO - if (sysinfo(SI_HOSTNAME, hostname, sizeof(hostname)) < 0) { - perror("sysinfo"); -#else - if (gethostname(hostname, sizeof(hostname)) < 0) { - perror("gethostname"); -#endif - exit(1); - } - if (strchr(hostname, '.')) - *(strchr(hostname, '.')) = 0; - - sprintf(krb_ticket_name, "/var/dss/kerberos/tkt/tkt.%d", getpid()); - krb_set_tkt_string(krb_ticket_name); - - config_auth(); - - if (krb_svc_init("hesiod", hostname, (char *) NULL, 0, (char *) NULL, - (char *) NULL) != KSUCCESS) { - fprintf(stderr, "Couldn't initialize Kerberos\n"); - exit(1); - } -} - -void end_krb() -{ - unlink(krb_ticket_name); -} - -#endif /* KERBEROS */ - -#ifdef ULTRIX_AUTH -static int ultrix_check_pass(char *passwd, char *xpasswd) -{ - struct svcinfo *svp; - int auth_status; - - if ((svp = getsvc()) == (struct svcinfo *) NULL) { - syslog(LOG_WARNING, "getsvc() failed in ultrix_check_pass"); - return -1; - } - if (pw == (struct passwd *) NULL) { - return -1; - } - if (((svp->svcauth.seclevel == SEC_UPGRADE) && - (!strcmp(pw->pw_passwd, "*"))) - || (svp->svcauth.seclevel == SEC_ENHANCED)) { - if ((auth_status = authenticate_user(pw, passwd, "/dev/ttypXX")) >= 0) { - /* Indicate successful validation */ - return auth_status; - } - if (auth_status < 0 && errno == EPERM) { - /* Log some information about the failed login attempt. */ - switch (abs(auth_status)) { - case A_EBADPASS: - break; - case A_ESOFTEXP: - syslog(LOG_NOTICE, "password will expire soon for user %s", - pw->pw_name); - break; - case A_EHARDEXP: - syslog(LOG_NOTICE, "password has expired for user %s", - pw->pw_name); - break; - case A_ENOLOGIN: - syslog(LOG_NOTICE, "user %s attempted login to disabled acct", - pw->pw_name); - break; - } - } - } - else { - if ((*pw->pw_passwd != '\0') && (!strcmp(xpasswd, pw->pw_passwd))) { - /* passwd in /etc/passwd isn't empty && encrypted passwd matches */ - return 0; - } - } - return -1; -} -#endif /* ULTRIX_AUTH */ - -#ifdef USE_PAM -/* This is rather an abuse of PAM, but the FTP protocol doesn't allow much - * flexibility here. :-( - */ - -/* Static variables used to communicate between the conversation function - * and the server_login function - */ -static char *PAM_password; - -/* PAM conversation function - * Here we assume (for now, at least) that echo on means login name, and - * echo off means password. - */ -#ifdef SOLARIS_2 -/* Workaround bug 4430970/4413889 which causes a compiler warning, necessary - * as usr/src/Makefile.master now includes "-errwarn=%all". - */ -static int PAM_conv(int num_msg, struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) -#else -static int PAM_conv(int num_msg, const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) -#endif -{ - int replies = 0; - struct pam_response *reply = NULL; - -#define COPY_STRING(s) (s) ? strdup(s) : NULL - - reply = malloc(sizeof(struct pam_response) * num_msg); - if (!reply) - return PAM_CONV_ERR; - - for (replies = 0; replies < num_msg; replies++) { - switch (msg[replies]->msg_style) { - case PAM_PROMPT_ECHO_ON: - return PAM_CONV_ERR; - break; - case PAM_PROMPT_ECHO_OFF: - reply[replies].resp_retcode = PAM_SUCCESS; - reply[replies].resp = COPY_STRING(PAM_password); - /* PAM frees resp */ - break; - case PAM_TEXT_INFO: - /* ignore it... */ - reply[replies].resp_retcode = PAM_SUCCESS; - reply[replies].resp = NULL; - break; - case PAM_ERROR_MSG: - /* ignore it... */ - reply[replies].resp_retcode = PAM_SUCCESS; - reply[replies].resp = NULL; - break; - default: - /* Must be an error of some sort... */ - return PAM_CONV_ERR; - } - } - *resp = reply; - return PAM_SUCCESS; -} -static struct pam_conv PAM_conversation = -{ - &PAM_conv, - NULL -}; - -static int pam_check_pass(char *user, char *passwd) -{ - char tty[20]; - int pam_session = 0; - - /* Now use PAM to do authentication and session logging. Bail out if - * there are any errors. Since this is a limited protocol, and an even - * more limited function within a server speaking this protocol, we - * can't be as verbose as would otherwise make sense. - */ - PAM_password = passwd; - pamh = (pam_handle_t *)0; - if (pam_start("ftp", user, &PAM_conversation, &pamh) != PAM_SUCCESS) - return 0; - -#if ((defined(BSD) && (BSD >= 199103)) || defined(sun)) - (void) sprintf(tty, "/dev/ftp%ld", (long) getpid()); -#else - (void) sprintf(tty, "/dev/ftpd%d", getpid()); -#endif - - if (pam_set_item(pamh, PAM_TTY, tty) != PAM_SUCCESS) - goto pam_fail; - if (pam_set_item(pamh, PAM_RHOST, remotehost) != PAM_SUCCESS) - goto pam_fail; - if (pam_authenticate(pamh, PAM_DISALLOW_NULL_AUTHTOK) != PAM_SUCCESS) { -#ifdef SOLARIS_BSM_AUDIT - audit_ftpd_bad_pw(user); -#endif - goto pam_fail; - } - if (pam_acct_mgmt(pamh, 0) != PAM_SUCCESS) { -#ifdef SOLARIS_BSM_AUDIT - audit_ftpd_bad_pw(user); -#endif - goto pam_fail; - } - if (pam_open_session(pamh, 0) != PAM_SUCCESS) - goto pam_fail; - pam_session = 1; -#ifdef PAM_ESTABLISH_CRED - if (pam_setcred(pamh, PAM_ESTABLISH_CRED) != PAM_SUCCESS) - goto pam_fail; -#else - if (pam_setcred(pamh, PAM_CRED_ESTABLISH) != PAM_SUCCESS) - goto pam_fail; -#endif - /* If this point is reached, the user has been authenticated. */ - return 1; - -pam_fail: - if (pam_session) - (void) pam_close_session(pamh, 0); - (void) pam_end(pamh, 0); - pamh = (pam_handle_t *)0; - return 0; -} -#endif - -#ifdef DAEMON - -#ifdef INET6 -static struct in6_addr acl_DaemonAddress6(void) -{ - struct in6_addr rv = in6addr_any; - struct aclmember *entry = NULL; - - if (getaclentry("daemonaddress", &entry) && ARG0) { - if (inet_pton6(ARG0, &rv) != 1) - rv = in6addr_any; - } - return rv; -} -#endif /* INET6 */ -static unsigned long int acl_DaemonAddress(void) -{ - unsigned long int rv = INADDR_ANY; - struct aclmember *entry = NULL; - - if (getaclentry("daemonaddress", &entry) && ARG0) { - rv = inet_addr(ARG0); - if (rv == -1) - rv = INADDR_ANY; - } - return rv; -} - -/* I am running as a standalone daemon (not under inetd) */ -static void do_daemon(void) -{ - struct SOCKSTORAGE server; - struct servent *serv; - int pgrp; - int lsock; - int one = 1; - FILE *pidfile; - int i; -#if defined(UNIXWARE) || defined(AIX) - size_t addrlen; -#else - int addrlen; -#endif - - /* Some of this is "borrowed" from inn - lots of it isn't */ - - if (be_daemon == 2) { - /* Fork - so I'm not the owner of the process group any more */ - i = fork(); - if (i < 0) { - syslog(LOG_ERR, "cant fork %m"); - exit(1); - } - /* No need for the parent any more */ - if (i > 0) - exit(0); - -#ifdef NO_SETSID - pgrp = setpgrp(0, getpid()); -#else - pgrp = setsid(); -#endif - if (pgrp < 0) { - syslog(LOG_ERR, "cannot daemonise: %m"); - exit(1); - } - } - - if (!Bypass_PID_Files) - if ((pidfile = fopen(_PATH_FTPD_PID, "w"))) { - fprintf(pidfile, "%ld\n", (long) getpid()); - fclose(pidfile); - } - else { - syslog(LOG_ERR, "Cannot write pidfile: %m"); - } - - /* Close off all file descriptors and reopen syslog */ - if (be_daemon == 2) { - closelog(); - closefds(0); - (void) open(_PATH_DEVNULL, O_RDWR); - (void) dup2(0, 1); - /* junk stderr */ - (void) freopen(_PATH_DEVNULL, "w", stderr); - -#ifdef FACILITY - openlog("ftpd", LOG_PID | LOG_NDELAY, FACILITY); -#else - openlog("ftpd", LOG_PID); -#endif - } - - if (RootDirectory != NULL) { - if ((chroot(RootDirectory) < 0) - || (chdir("/") < 0)) { - syslog(LOG_ERR, "Cannot chroot to initial directory, aborting."); - exit(1); - } - free(RootDirectory); - RootDirectory = NULL; - } - - if (!use_accessfile) - syslog(LOG_WARNING, "FTP server started without ftpaccess file"); - - syslog(LOG_INFO, "FTP server (%s) ready.", version); - - /* Create a socket to listen on */ -#ifdef INET6 - if (listen_v4 == 0) - lsock = socket(AF_INET6, SOCK_STREAM, 0); - else -#endif - lsock = socket(AF_INET, SOCK_STREAM, 0); - if (lsock < 0) { - syslog(LOG_ERR, "Cannot create socket to listen on: %m"); - exit(1); - } - if (setsockopt(lsock, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one)) < 0) { - syslog(LOG_ERR, "Cannot set SO_REUSEADDR option: %m"); - exit(1); - } - if (keepalive) - (void) setsockopt(lsock, SOL_SOCKET, SO_KEEPALIVE, (char *) &one, sizeof(one)); - -#ifdef INET6 - if (listen_v4 == 0) { - struct sockaddr_in6 *server_sin6 = (struct sockaddr_in6 *)&server; - - memset(&server, 0, sizeof(struct sockaddr_in6)); - server_sin6->sin6_family = AF_INET6; - server_sin6->sin6_addr = acl_DaemonAddress6(); - } - else { - struct sockaddr_in *server_sin = (struct sockaddr_in *)&server; - - server_sin->sin_family = AF_INET; - server_sin->sin_addr.s_addr = acl_DaemonAddress(); - } -#else - server.sin_family = AF_INET; - server.sin_addr.s_addr = acl_DaemonAddress(); -#endif - if (daemon_port == 0) { - if (!(serv = getservbyname("ftp", "tcp"))) { - syslog(LOG_ERR, "Cannot find service ftp: %m"); - exit(1); - } - SET_SOCK_PORT(server, serv->s_port); - daemon_port = ntohs(serv->s_port); - } - else - SET_SOCK_PORT(server, htons(daemon_port)); - - if (bind(lsock, (struct sockaddr *) &server, SOCK_LEN(server)) < 0) { - syslog(LOG_ERR, "Cannot bind socket: %m"); - exit(1); - } - - listen(lsock, MAX_BACKLOG); - - sprintf(proctitle, "accepting connections on port %i", daemon_port); - setproctitle("%s", proctitle); - - while (1) { - int pid; - int msgsock; - - addrlen = sizeof(his_addr); - msgsock = accept(lsock, (struct sockaddr *) &his_addr, &addrlen); - if (msgsock < 0) { - int severity = LOG_ERR; - - if (errno == EINTR || errno == ECONNABORTED) - severity = LOG_INFO; - syslog(severity, "Accept failed: %m"); - sleep(1); - continue; - } - - /* Fork off a handler */ - pid = fork(); - if (pid < 0) { - syslog(LOG_ERR, "failed to fork: %m"); - close(msgsock); - sleep(1); - continue; - } - if (pid == 0) { - /* I am that forked off child */ - /* Only parent needs lsock */ - close(lsock); - closelog(); - /* Make sure that stdin/stdout are the new socket */ - dup2(msgsock, 0); - dup2(msgsock, 1); - if (msgsock != 0 && msgsock != 1) - close(msgsock); -#ifdef FACILITY - openlog("ftpd", LOG_PID | LOG_NDELAY, FACILITY); -#else - openlog("ftpd", LOG_PID); -#endif - setup_paths(); - access_init(); - return; - } - - /* I am the parent */ - close(msgsock); - - /* Quick check to see if any of the forked off children have - * terminated. */ - while ((pid = waitpid((pid_t) -1, (int *) 0, WNOHANG)) > 0) { - /* A child has finished */ - } - - access_init(); - } -} - -#endif /* DAEMON */ - -#ifdef RATIO -int is_downloadfree(char *fname) -{ - char rpath[MAXPATHLEN]; - char class[BUFSIZ]; - char *cp; - int which; - struct aclmember *entry = NULL; - - if( wu_realpath(fname,rpath,chroot_path) == NULL ) - return 0; - - (void) acl_getclass(class); - - if (debug) - syslog(LOG_DEBUG, "class: %s, fname: %s, rpath: %s", class, fname, rpath); - - while( getaclentry("dl-free-dir",&entry) ) { - if( ARG0 == NULL ) - continue; - if( strncmp(rpath,ARG0,strlen(ARG0)) == 0 ) { - if( ARG1 == NULL ) - return 1; - else for(which = 1; (which < MAXARGS) && ARG[which]; which++) { - if( strcmp(class,ARG[which]) == 0 ) - return 1; - } - } - } - while( getaclentry("dl-free",&entry) ) { - if( ARG0 == NULL ) - continue; - if( *(ARG0) != '/' ) { /* compare basename */ - if( (cp = strrchr(rpath,'/')) == NULL ) { - cp = rpath; - } - else { - ++cp; - } - if( strcmp(cp,ARG0) == 0 ) { - if( ARG1 == NULL ) - return 1; - else for(which = 1; (which < MAXARGS) && ARG[which]; which++) { - if( strcmp(class,ARG[which]) == 0 ) - return 1; - } - } - } - else { /* compare real path */ - if( strcmp(rpath,ARG0) == 0 ) { - if( ARG1 == NULL ) - return 1; - else for(which = 1; (which < MAXARGS) && ARG[which] ; which++) { - if( strcmp(class,ARG[which]) == 0 ) - return 1; - } - } - } - } - return 0; -} -#endif /* RATIO */ - -int pasv_allowed(char *remoteaddr) -{ - char class[MAXPATHLEN]; - int which; - struct aclmember *entry = NULL; - (void) acl_getclass(class); - while (getaclentry("pasv-allow", &entry)) { - if ((ARG0 != NULL) && (strcasecmp(class, ARG0) == 0)) - for (which = 1; (which < MAXARGS) && (ARG[which] != NULL); which++) { - if (hostmatch(ARG[which], remoteaddr, NULL)) - return 1; - } - } - return 0; -} - -int port_allowed(char *remoteaddr) -{ - char class[MAXPATHLEN]; - int which; - struct aclmember *entry = NULL; - (void) acl_getclass(class); - while (getaclentry("port-allow", &entry)) { - if ((ARG0 != NULL) && (strcasecmp(class, ARG0) == 0)) - for (which = 1; (which < MAXARGS) && (ARG[which] != NULL); which++) { - if (hostmatch(ARG[which], remoteaddr, NULL)) - return 1; - } - } - return 0; -} - -#ifdef MAIL_ADMIN -char *email(char *full_address) -{ - /* Get the plain address part from an e-mail address - (i.e. remove realname) */ - - static char *email_buf = NULL; - char *addr, *ptr; - - if (email_buf != NULL) - free(email_buf); - - email_buf = (char *) malloc(strlen(full_address) + 1); - addr = email_buf; - memset(addr, 0, strlen(full_address) + 1); - strcpy(addr, full_address); - - /* Realname type address */ - if ((ptr = (char *) strchr(addr, '<')) != NULL) { - addr = ++ptr; - if ((ptr = (char *) strchr(addr, '>')) != NULL) - *ptr = '\0'; - } - - /* user@host (Realname) type address */ - if (((char *) strchr(addr, ' ')) != NULL) - addr[strchr(addr, ' ') - addr] = '\0'; - - return addr; -} - -FILE *SockOpen(char *host, int clientPort) -{ - int sock; - unsigned long inaddr; - struct sockaddr_in ad; - FILE *fp; -#ifdef INET6 - struct sockaddr_in6 ad6; - struct addrinfo hints, *result, *res; - int af = AF_INET; -#else - struct hostent *hp; -#endif - - memset(&ad, 0, sizeof(ad)); - ad.sin_family = AF_INET; - -#ifdef INET6 - memset(&ad6, 0, sizeof(ad6)); - ad6.sin6_family = AF_INET6; - - memset(&hints, 0, sizeof(hints)); - hints.ai_flags = AI_CANONNAME; - hints.ai_family = PF_UNSPEC; - - if (getaddrinfo(host, NULL, &hints, &result) != 0) - return (FILE *) NULL; - - for (res = result; res; res = res->ai_next) { - af = res->ai_family; - if (af == AF_INET) - memcpy(&ad.sin_addr, &((struct sockaddr_in *)res->ai_addr)->sin_addr, sizeof(struct in_addr)); - else if (af == AF_INET6) - memcpy(&ad6.sin6_addr, &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, sizeof(struct in6_addr)); - else - continue; - - if (af == AF_INET6) { - ad6.sin6_port = htons(clientPort); - sock = socket(AF_INET6, SOCK_STREAM, 0); - if (sock < 0) - continue; - if (connect(sock, (struct sockaddr *) &ad6, sizeof(ad6)) != -1) - break; - close(sock); - } - else { - ad.sin_port = htons(clientPort); - sock = socket(AF_INET, SOCK_STREAM, 0); - if (sock < 0) - continue; - if (connect(sock, (struct sockaddr *) &ad, sizeof(ad)) != -1) - break; - close(sock); - } - } - freeaddrinfo(result); - if (!res) - return (FILE *) NULL; -#else - inaddr = inet_addr(host); - if (inaddr != (unsigned long) -1) - memcpy(&ad.sin_addr, &inaddr, sizeof(inaddr)); - else { - hp = gethostbyname(host); - if (hp == NULL) - return (FILE *) NULL; - memcpy(&ad.sin_addr, hp->h_addr, hp->h_length); - } - ad.sin_port = htons(clientPort); - sock = socket(AF_INET, SOCK_STREAM, 0); - if (sock < 0) - return (FILE *) NULL; - if (connect(sock, (struct sockaddr *) &ad, sizeof(ad)) < 0) { - close(sock); - return (FILE *) NULL; - } -#endif /* INET6 */ - - fp = fdopen(sock, "r+"); - setvbuf(fp, NULL, _IOLBF, 2048); - return (fp); -} - -int SockPrintf(FILE *sockfp, char *format,...) -{ - va_list ap; - char buf[16384]; - - va_start(ap, format); - vsnprintf(buf, sizeof(buf), format, ap); - buf[sizeof(buf) - 1] = '\0'; - va_end(ap); - return SockWrite(buf, 1, strlen(buf), sockfp); -} - -int SockWrite(char *buf, int size, int len, FILE *sockfp) -{ - return (fwrite(buf, size, len, sockfp)); -} - -char *SockGets(FILE *sockfp, char *buf, int len) -{ - return (fgets(buf, len, sockfp)); -} - -int SockPuts(FILE *sockfp, char *buf) -{ - int rc; - - if ((rc = SockWrite(buf, 1, strlen(buf), sockfp))) - return rc; - return SockWrite("\r\n", 1, 2, sockfp); -} - -int Reply(FILE *sockfp) -{ - char *reply, *rec, *separator; - int ret = 0; - - if ((reply = (char *) malloc(BUFSIZ)) == NULL) - return ret; - memset(reply, 0, 1024); - do { - rec = SockGets(sockfp, reply, BUFSIZ); - if (rec != NULL) { - ret = strtol(reply, &separator, 10); - } - else - ret = 250; - } while ((rec != NULL) && (separator[0] != ' ')); - free(reply); - fflush(sockfp); /* Solaris bug: need to clear buf before fwrite() */ - return ret; -} - -int Send(FILE *sockfp, char *format,...) -{ - va_list ap; - char buf[16384]; - - va_start(ap, format); - vsnprintf(buf, sizeof(buf), format, ap); - buf[sizeof(buf) - 1] = '\0'; - va_end(ap); - SockWrite(buf, 1, strlen(buf), sockfp); - return Reply(sockfp); -} -#endif /* MAIL_ADMIN */ - - -/* - * fixpath - * - * In principal, this is similar to realpath() or the mapping chdir function. - * It removes unnecessary path components. We do this to put a stop to - * attempts to cause a memory starvation DoS. - * - */ - -void fixpath(char *path) -{ - int abs = 0; - char *in; - char *out; - - if (*path == '/') { - abs = 1; - path++; - } - else if (*path == '~') { - do - path++; - while ((*path != '\0') && (*path != '/')); - if (*path == '/') - path++; - } - in = path; - out = path; - while (*in != '\0') { - if (*in == '/') - in++; - else if ((in[0] == '.') && ((in[1] == '/') || (in[1] == '\0'))) { - in++; - if (*in == '/') - in++; - } - else if ((in[0] == '.') && (in[1] == '.') && ((in[2] == '/') || (in[2] == '\0'))) { - if (out == path) { - if (abs) { - in++; - in++; - if (*in == '/') - in++; - } - else { - *out++ = *in++; - *out++ = *in++; - if (*in == '/') - *out++ = *in++; - path = out; - } - } - else { - out--; - while ((out != path) && (*--out != '/')); - in++; - in++; - if (*in == '/') - in++; - } - } - else { - do - *out++ = *in++; - while ((*in != '\0') && (*in != '/')); - if (*in == '/') - *out++ = *in++; - } - } - *out = '\0'; -} - -#if defined(SOLARIS_2) - -/* Callback function to cleanup_nscd()'s fdwalk(). - * If "fd" has the same inode, device as nscd door - * it returns 1 otherwise it returns 0. - */ -int close_nsdoor(void *cb_data, int fd) -{ - struct stat fd_buf; - struct stat *nsdoor_buf = (struct stat *) cb_data; - - if (fstat(fd, &fd_buf) != 0) { - return (0); - } - - if ((nsdoor_buf->st_dev == fd_buf.st_dev) && - (nsdoor_buf->st_ino == fd_buf.st_ino)) { - close(fd); - return (1); - } - - return (0); -} - -/* Walk through the list of open file descriptors - * of the ftp dameon and find the nscd door fd and - * close it. - */ -void cleanup_nscd() -{ - struct stat nsdoor_buf; - - if (stat(NAME_SERVICE_DOOR, &nsdoor_buf) == 0) { - fdwalk(close_nsdoor, &nsdoor_buf); - } -} - -#endif diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpgroups b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpgroups deleted file mode 100644 index a025a4694f..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpgroups +++ /dev/null @@ -1,4 +0,0 @@ -# ident "%Z%%M% %I% %E% SMI" -# -# FTP server enhanced group access file, see ftpgroups(4). -# diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftphosts b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftphosts deleted file mode 100644 index 249e56bd19..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftphosts +++ /dev/null @@ -1,4 +0,0 @@ -# ident "%Z%%M% %I% %E% SMI" -# -# FTP server individual user host access file, see ftphosts(4). -# diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftprestart.c b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftprestart.c deleted file mode 100644 index ea31b1bc3d..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftprestart.c +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/**************************************************************************** - - Copyright (c) 1999,2000 WU-FTPD Development Group. - All rights reserved. - - Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 - The Regents of the University of California. - Portions Copyright (c) 1993, 1994 Washington University in Saint Louis. - Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc. - Portions Copyright (c) 1989 Massachusetts Institute of Technology. - Portions Copyright (c) 1998 Sendmail, Inc. - Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman. - Portions Copyright (c) 1997 by Stan Barber. - Portions Copyright (c) 1997 by Kent Landfield. - Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 - Free Software Foundation, Inc. - - Use and distribution of this software and its source code are governed - by the terms and conditions of the WU-FTPD Software License ("LICENSE"). - - If you did not receive a copy of the license, it may be obtained online - at http://www.wu-ftpd.org/license.html. - - $Id: ftprestart.c,v 1.7 2000/07/01 18:17:39 wuftpd Exp $ - -****************************************************************************/ -/* ftprestart - ** - ** removes the ftpd shutdown files. - ** - ** In the previous versions of the wu-ftpd server it was recommended to - ** create a link in order for shutdown to work properly for real and - ** anonymous user, e.g. If you use ftpshut, it will create a message - ** file at the location specified in the ftpaccess shutdown directive. - ** ln -s /etc/shutmsg ~ftp/etc/shutmsg - ** - ** When ftp service is to be restarted after an ftpshut, the shutdown - ** message files must be removed. This program reads the ftpaccess - ** file and finds the location of the system shutdown file. It - ** then proceeds to construct a path to the anonymous ftp area with - ** information found in the "ftp" account. If virtual ftp servers - ** are enabled, the shutdown message files within those directories - ** are also removed. - ** - ** Initial Author: Kent Landfield - */ -#include "config.h" - -#include -#include -#include -#include -#include -#include -#include -#if defined(VIRTUAL) && defined(INET6) -#include -#endif - -#include "pathnames.h" - -#define MAXVIRTUALS 512 - -char *progname; -char *msgfiles[MAXVIRTUALS]; -int numfiles = 0; - -#ifdef VIRTUAL -extern int read_servers_line(FILE *, char *, size_t, char *, size_t); -#endif - -void print_copyright(void); - -static int newfile(char *fpath) -{ - int i; - int fnd; - - /* - ** Check to see if the message file path has already been - ** seen. If so then there is no need to create it again. - */ - - fnd = 0; - for (i = 0; i < numfiles; i++) { - if (strcmp(msgfiles[i], fpath) == 0) { - fnd = 1; - break; - } - } - if (!fnd) { - msgfiles[numfiles++] = strdup(fpath); - return (1); - } - return (0); -} - -static int remove_shutdown_file(char *path) -{ - struct stat stbuf; - int rc = 1; /* guilty until proven innocent */ - - fprintf(stderr, "%s: %s ", progname, path); - - if (stat(path, &stbuf) == 0) { - if ((rc = unlink(path)) == 0) - fprintf(stderr, "removed.\n"); - else - perror(path); - } - else - fprintf(stderr, "does not exist.\n"); - - return (rc); -} - -int main(int argc, char **argv) -{ - int c; - - char *p; - char *cp = NULL; - char linebuf[BUFSIZ]; - char shutmsg[256]; - char anonpath[MAXPATHLEN]; - FILE *accessfile; - struct passwd *pw; - -#if defined(VIRTUAL) - FILE *svrfp; - char *sp; -#ifdef INET6 - char hostaddress[INET6_ADDRSTRLEN]; -#else - char hostaddress[32]; -#endif - char root[MAXPATHLEN]; - char configdir[MAXPATHLEN]; - char accesspath[MAXPATHLEN]; - char altmsgpath[MAXPATHLEN]; - struct stat finfo; -#endif - - if ((progname = strrchr(argv[0], '/'))) - ++progname; - else - progname = argv[0]; - - if (argc > 1) { - while ((c = getopt(argc, argv, "V")) != EOF) { - switch (c) { - case 'V': - print_copyright(); - exit(0); - default: - fprintf(stderr, "usage: %s [-V]\n", progname); - exit(1); - } - } - } - - if ((accessfile = fopen(_PATH_FTPACCESS, "r")) == NULL) { - if (errno != ENOENT) - fprintf(stderr, "%s: could not open access file %s: %s\n", - progname, _PATH_FTPACCESS, strerror(errno)); - exit(1); - } - - /* - ** Search the access file for the 'shutdown' directive. - */ - - while (fgets(linebuf, BUFSIZ, accessfile) != NULL) { - if (strncasecmp(linebuf, "shutdown", 8) == 0) { - (void) strtok(linebuf, " \t"); - (void) strlcpy(shutmsg, strtok(NULL, " \t"), sizeof(shutmsg)); - cp = shutmsg; - if ((p = strchr(cp, '\n')) != NULL) - *p = '\0'; - } - } - - if (cp == NULL) { - fprintf(stderr, "%s: no shutdown path defined in ftpaccess file %s.\n", - progname, _PATH_FTPACCESS); - exit(1); - } - - msgfiles[numfiles++] = shutmsg; - - /* - ** Get the location of the anonymous ftp area and check - ** to see if there is a file shutdown file there as well. - ** If so, remove it. - */ - if ((pw = getpwnam("ftp")) != NULL) { - (void) snprintf(anonpath, sizeof(anonpath), "%s%s", pw->pw_dir, - shutmsg); - if (newfile(anonpath)) - (void) remove_shutdown_file(anonpath); - } - -#ifdef VIRTUAL - /* - ** Search the access file for virtual ftp servers. - ** If found, check if there are links/shutdown - ** message files files in the virtual server areas. - ** If so, remove them. - */ - - rewind(accessfile); - - while (fgets(linebuf, sizeof(linebuf) - 1, accessfile) != NULL) { - if (strncasecmp(linebuf, "virtual", 7) == 0) { - if ((p = strstr(linebuf, "root")) != NULL) { - p += 4; - - if ((cp = strchr(linebuf, '\n')) != NULL) - *cp = '\0'; - - /* skip to the path */ - - while (*p && isspace(*p)) - p++; - cp = p; - while (*p && isalnum(*p)) - p++; - - (void) snprintf(altmsgpath, sizeof(altmsgpath), "%s%s", cp, - shutmsg); - if (newfile(altmsgpath)) - (void) remove_shutdown_file(altmsgpath); - } - } - } - - - /* - ** Need to deal with the access files at the virtual domain directory - ** locations specified in the ftpservers file. - */ - - if ((svrfp = fopen(_PATH_FTPSERVERS, "r")) != NULL) { - while (read_servers_line(svrfp, hostaddress, sizeof(hostaddress), - configdir, sizeof(configdir)) == 1) { - /* get rid of any trailing slash */ - sp = configdir + (strlen(configdir) - 1); - if (*sp == '/') - *sp = '\0'; - - /* - ** check to see that a valid directory value was - ** supplied and not something such as "INTERNAL" - ** - ** It is valid to have a string such as "INTERNAL" in the - ** ftpservers entry. This is not an error. Silently ignore it. - */ - - if ((stat(configdir, &finfo) < 0) || - ((finfo.st_mode & S_IFMT) != S_IFDIR)) - continue; - - (void) snprintf(accesspath, sizeof(accesspath), "%s/ftpaccess", - configdir); - - (void) fclose(accessfile); - - if ((accessfile = fopen(accesspath, "r")) == NULL) { - if (errno != ENOENT) { - fprintf(stderr, "%s: could not open access file %s: %s\n", - progname, accesspath, strerror(errno)); - continue; - } - } - - /* need to find the root path */ - - while (fgets(linebuf, sizeof(linebuf) - 1, accessfile) != NULL) { - if ((sp = strstr(linebuf, "root")) != NULL) { - if ((cp = strchr(sp, '\n')) != NULL) - *cp = '\0'; /* strip newline */ - sp += 4; /* skip past "root" keyword */ - - while (*sp && isspace(*sp)) /* skip whitespace to path */ - sp++; - cp = sp; - while (*sp && !isspace(*sp)) - sp++; - *sp = '\0'; /* truncate blanks, comments etc. */ - (void) strlcpy(root, cp, sizeof(root)); - break; - } - } - - rewind(accessfile); - - /* need to find the shutdown message file path */ - - while (fgets(linebuf, sizeof(linebuf) - 1, accessfile) != NULL) { - if ((sp = strstr(linebuf, "shutdown")) != NULL) { - if ((cp = strchr(sp, '\n')) != NULL) - *cp = '\0'; /* strip newline */ - sp += 8; /* skip past "root" keyword */ - - while (*sp && isspace(*sp)) /* skip whitespace to path */ - sp++; - cp = sp; - while (*sp && !isspace(*sp)) - sp++; - *sp = '\0'; /* truncate blanks, comments etc. */ - break; - } - } - - /* - ** check to make sure the admin hasn't specified - ** a complete path in the 'shutdown' directive. - */ - if ((sp = strstr(cp, root)) == NULL) - (void) snprintf(altmsgpath, sizeof(altmsgpath), "%s%s", root, - cp); - - if (newfile(altmsgpath)) - (void) remove_shutdown_file(altmsgpath); - } - fclose(svrfp); - } -#endif /* VIRTUAL */ - - fclose(accessfile); - - /* - ** Time to remove the system wide shutdown file. - */ - return (remove_shutdown_file(shutmsg)); -} diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpservers b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpservers deleted file mode 100644 index ec67385b99..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpservers +++ /dev/null @@ -1,4 +0,0 @@ -# ident "%Z%%M% %I% %E% SMI" -# -# FTP server virtual hosting configuration file, see ftpservers(4). -# diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpshut.c b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpshut.c deleted file mode 100644 index 51b4ac8e81..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/ftpshut.c +++ /dev/null @@ -1,511 +0,0 @@ -/* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/**************************************************************************** - - Copyright (c) 1999,2000 WU-FTPD Development Group. - All rights reserved. - - Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 - The Regents of the University of California. - Portions Copyright (c) 1993, 1994 Washington University in Saint Louis. - Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc. - Portions Copyright (c) 1989 Massachusetts Institute of Technology. - Portions Copyright (c) 1998 Sendmail, Inc. - Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman. - Portions Copyright (c) 1997 by Stan Barber. - Portions Copyright (c) 1997 by Kent Landfield. - Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 - Free Software Foundation, Inc. - - Use and distribution of this software and its source code are governed - by the terms and conditions of the WU-FTPD Software License ("LICENSE"). - - If you did not receive a copy of the license, it may be obtained online - at http://www.wu-ftpd.org/license.html. - - $Id: ftpshut.c,v 1.12 2000/07/01 18:17:39 wuftpd Exp $ - -****************************************************************************/ -/* ftpshut - * ======= - * creates the ftpd shutdown file. - */ - -#include "config.h" - -#include -#include -#include -#include -#include -#ifdef TIME_WITH_SYS_TIME -#include -#include -#else -#ifdef HAVE_SYS_TIME_H -#include -#else -#include -#endif -#endif - -#include -#include -#include -#include -#if defined(VIRTUAL) && defined(INET6) -#include -#endif - -#include "pathnames.h" - -#define WIDTH 70 - -int verbose = 0; -int denyoffset = 10; /* default deny time */ -int discoffset = 5; /* default disc time */ -char *message = "System shutdown at %s"; /* default message */ - -struct tm *tp; - -#define MAXVIRTUALS 512 - -char *progname; -char *msgfiles[MAXVIRTUALS]; -int numfiles = 0; - -#ifdef VIRTUAL -extern int read_servers_line(FILE *, char *, size_t, char *, size_t); -#endif -void print_copyright(void); - -static int newfile(char *fpath) -{ - int i; - int fnd; - - /* - ** Check to see if the message file path has already been - ** seen. If so then there is no need to create it again. - */ - - fnd = 0; - for (i = 0; i < numfiles; i++) { - if (strcmp(msgfiles[i], fpath) == 0) { - fnd = 1; - break; - } - } - if (!fnd) { - msgfiles[numfiles++] = strdup(fpath); - return (1); - } - return (0); -} - -static int shutdown_msgfile(char *filename, char *buffer) -{ - FILE *fp; - mode_t oldmask; - - oldmask = umask(022); - fp = fopen(filename, "w"); - (void) umask(oldmask); - if (fp == NULL) { - fprintf(stderr, "%s: could not open shutdown file %s: %s\n", - progname, filename, strerror(errno)); - return (1); - } - - fprintf(fp, "%.4d %.2d %.2d %.2d %.2d %.4d %.4d\n", - (tp->tm_year) + 1900, - tp->tm_mon, - tp->tm_mday, - tp->tm_hour, - tp->tm_min, - denyoffset, - discoffset); - fprintf(fp, "%s\n", buffer); - fclose(fp); - if (verbose) - printf("%s: %s created\n", progname, filename); - return (0); -} - -static void massage(char *buf) -{ - char *sp = NULL; - char *ptr; - int i = 0; - int j = 0; - - ptr = buf; - - while (*ptr++ != '\0') { - ++i; - - /* if we have a space, keep track of where and at what "count" */ - - if (*ptr == ' ') { - sp = ptr; - j = i; - } - /* magic cookies... */ - - if (*ptr == '%') { - ++ptr; - switch (*ptr) { - case 'r': - case 's': - case 'd': - case 'T': - i = i + 24; - break; - case '\n': - i = 0; - break; - case 'C': - case 'R': - case 'L': - case 'U': - i = i + 10; - break; - case 'M': - case 'N': - i = i + 3; - break; - case '\0': - return; - /* break; */ - default: - i = i + 1; - break; - } - } - /* break up the long lines... */ - - if ((i >= WIDTH) && (sp != NULL)) { - *sp = '\n'; - sp = NULL; - i = i - j; - } - } -} - -static void usage(int exitval) -{ - fprintf(stderr, - "Usage: %s [-d min] [-l min] now [\"message\"]\n", progname); - fprintf(stderr, - " %s [-d min] [-l min] +dd [\"message\"]\n", progname); - fprintf(stderr, - " %s [-d min] [-l min] HHMM [\"message\"]\n", progname); - exit(exitval); -} - -int main(int argc, char **argv) -{ - time_t c_time = 0; - - char buf[BUFSIZ]; - - int c; - extern int optind; - extern char *optarg; - - FILE *accessfile; - char *aclbuf, *myaclbuf, *crptr; - char *sp = NULL; - char linebuf[1024]; - char shutmsg[BUFSIZ]; - char anonpath[MAXPATHLEN]; - struct stat finfo; - struct passwd *pwent; - -#ifdef VIRTUAL - char *cp = NULL; - FILE *svrfp; -#ifdef INET6 - char hostaddress[INET6_ADDRSTRLEN]; -#else - char hostaddress[32]; -#endif - char root[MAXPATHLEN]; - char accesspath[MAXPATHLEN]; - char configdir[MAXPATHLEN]; - char altmsgpath[MAXPATHLEN]; -#endif - - if ((progname = strrchr(argv[0], '/'))) - ++progname; - else - progname = argv[0]; - - while ((c = getopt(argc, argv, "vVl:d:")) != EOF) { - switch (c) { - case 'v': - verbose++; - break; - case 'l': - denyoffset = atoi(optarg); - break; - case 'd': - discoffset = atoi(optarg); - break; - case 'V': - print_copyright(); - exit(0); - default: - usage(-1); - } - } - - if ((accessfile = fopen(_PATH_FTPACCESS, "r")) == NULL) { - if (errno != ENOENT) - fprintf(stderr, "%s: could not open access file %s: %s\n", - progname, _PATH_FTPACCESS, strerror(errno)); - exit(1); - } - if (fstat(fileno(accessfile), &finfo) != 0) { - fprintf(stderr, "%s: could not fstat() access file %s: %s\n", - progname, _PATH_FTPACCESS, strerror(errno)); - exit(1); - } - if (finfo.st_size == 0) { - fprintf(stderr, "%s: no shutdown path defined in ftpaccess file %s.\n", - progname, _PATH_FTPACCESS); - exit(1); - } - else { - if (!(aclbuf = (char *) malloc(finfo.st_size + 1))) { - fprintf(stderr, "%s: could not malloc aclbuf: %s\n", - progname, strerror(errno)); - exit(1); - } - fread(aclbuf, finfo.st_size, 1, accessfile); - *(aclbuf + finfo.st_size) = '\0'; - } - - myaclbuf = aclbuf; - while (*myaclbuf != '\0') { - if (strncasecmp(myaclbuf, "shutdown", 8) == 0) { - for (crptr = myaclbuf; *crptr++ != '\n';); - *--crptr = '\0'; - (void) strlcpy(linebuf, myaclbuf, sizeof(linebuf)); - *crptr = '\n'; - (void) strtok(linebuf, " \t"); /* returns "shutdown" */ - sp = strtok(NULL, " \t"); /* returns shutdown path */ - /* save for future use */ - (void) strlcpy(shutmsg, sp, sizeof(shutmsg)); - } - while (*myaclbuf && *myaclbuf++ != '\n'); - } - - /* three cases - * -- now - * -- +ddd - * -- HHMM - */ - - c = -1; - - if (optind < argc) { - if (!strcasecmp(argv[optind], "now")) { - c_time = time(0); - tp = localtime(&c_time); - } - else if ((*(argv[optind])) == '+') { - c_time = time(0); - c_time += 60 * atoi(++(argv[optind])); - tp = localtime(&c_time); - } - else if ((c = atoi(argv[optind])) >= 0) { - c_time = time(0); - tp = localtime(&c_time); - tp->tm_hour = c / 100; - tp->tm_min = c % 100; - - if ((tp->tm_hour > 23) || (tp->tm_min > 59)) { - fprintf(stderr, "%s: illegal time format.\n", progname); - exit(1); - } - } - } - if (c_time <= 0) { - usage(1); - } - - if (sp == NULL) { - fprintf(stderr, "%s: no shutdown path defined in ftpaccess file %s.\n", - progname, _PATH_FTPACCESS); - exit(1); - } - - /* do we have a shutdown message? */ - if (++optind < argc) - (void) strlcpy(buf, argv[optind++], sizeof(buf)); - else - (void) strlcpy(buf, message, sizeof(buf)); - - massage(buf); - - /* - ** Create the system shutdown message file at the location - ** specified in the ftpaccess 'shutdown' directive. This - ** is for support of real system users. - */ - c = shutdown_msgfile(shutmsg, buf); - msgfiles[numfiles++] = shutmsg; - - /* - ** Determine if the site supports anonymous ftp and if so, create - ** the shutdown message file in the anonymous ftp area as well - ** so that shutdown works appropriately for both real and guest - ** accounts. Save in msgfiles array for later comparison. - */ - - if ((pwent = getpwnam("ftp")) != NULL) { - (void) snprintf(anonpath, sizeof(anonpath), "%s%s", pwent->pw_dir, - shutmsg); - if (newfile(anonpath)) - c += shutdown_msgfile(anonpath, buf); - } - -#ifdef VIRTUAL - /* - ** Search the Master access file for virtual ftp servers. - ** If found, construct a path to the shutdown message file - ** under the virtual server's root. Don't duplicate what - ** is specified in the "ftp" account directory information. - */ - - rewind(accessfile); - - while (fgets(linebuf, sizeof(linebuf) - 1, accessfile) != NULL) { - if (strncasecmp(linebuf, "virtual", 7) == 0) { - - if ((sp = strstr(linebuf, "root")) != NULL) { - if ((cp = strchr(sp, '\n')) != NULL) - *cp = '\0'; /* strip newline */ - - sp += 4; /* skip past "root" keyword */ - - while (*sp && isspace(*sp)) /* skip whitespace to root path */ - sp++; - cp = sp; - while (*sp && !isspace(*sp)) - sp++; - *sp = '\0'; /* truncate blanks, comments etc. */ - - (void) snprintf(altmsgpath, sizeof(altmsgpath), "%s%s", cp, - shutmsg); - - if (newfile(altmsgpath)) - c += shutdown_msgfile(altmsgpath, buf); - } - } - } - - /* - ** Need to deal with the access files at the virtual domain directory - ** locations specified in the ftpservers file. - */ - - if ((svrfp = fopen(_PATH_FTPSERVERS, "r")) != NULL) { - while (read_servers_line(svrfp, hostaddress, sizeof(hostaddress), - configdir, sizeof(configdir)) == 1) { - /* get rid of any trailing slash */ - sp = configdir + (strlen(configdir) - 1); - if (*sp == '/') - *sp = '\0'; - - /* - ** check to see that a valid directory value was - ** supplied and not something such as "INTERNAL" - ** - ** It is valid to have a string such as "INTERNAL" in the - ** ftpservers entry. This is not an error. Silently ignore it. - */ - - if ((stat(configdir, &finfo) < 0) || - ((finfo.st_mode & S_IFMT) != S_IFDIR)) - continue; - - (void) snprintf(accesspath, sizeof(accesspath), "%s/ftpaccess", - configdir); - - (void) fclose(accessfile); - - if ((accessfile = fopen(accesspath, "r")) == NULL) { - if (errno != ENOENT) { - fprintf(stderr, "%s: could not open access file %s: %s\n", - progname, accesspath, strerror(errno)); - continue; - } - } - - /* need to find the root path */ - - while (fgets(linebuf, sizeof(linebuf) - 1, accessfile) != NULL) { - if ((sp = strstr(linebuf, "root")) != NULL) { - if ((cp = strchr(sp, '\n')) != NULL) - *cp = '\0'; /* strip newline */ - sp += 4; /* skip past "root" keyword */ - - while (*sp && isspace(*sp)) /* skip whitespace to path */ - sp++; - cp = sp; - while (*sp && !isspace(*sp)) - sp++; - *sp = '\0'; /* truncate blanks, comments etc. */ - (void) strlcpy(root, cp, sizeof(root)); - break; - } - } - /* need to find the shutdown message file path */ - - rewind(accessfile); - - while (fgets(linebuf, sizeof(linebuf) - 1, accessfile) != NULL) { - if ((sp = strstr(linebuf, "shutdown")) != NULL) { - if ((cp = strchr(sp, '\n')) != NULL) - *cp = '\0'; /* strip newline */ - sp += 8; /* skip past "root" keyword */ - - while (*sp && isspace(*sp)) /* skip whitespace to path */ - sp++; - cp = sp; - while (*sp && !isspace(*sp)) - sp++; - *sp = '\0'; /* truncate blanks, comments etc. */ - break; - } - } - - /* - ** check to make sure the admin hasn't specified - ** a complete path in the 'shutdown' directive. - */ - if ((sp = strstr(cp, root)) == NULL) - (void) snprintf(altmsgpath, sizeof(altmsgpath), "%s%s", root, - cp); - - /* - ** Check to see if the message file has been created elsewhere. - */ - if (newfile(altmsgpath)) - c += shutdown_msgfile(altmsgpath, buf); - } - fclose(svrfp); - } -#endif /* VIRTUAL */ - - fclose(accessfile); - free(aclbuf); - exit(c > 0 ? 1 : 0); -} diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/getpwnam.c b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/getpwnam.c deleted file mode 100644 index c3a2682dab..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/getpwnam.c +++ /dev/null @@ -1,158 +0,0 @@ -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * Replacement for getpwnam - we need it to handle files other than - * /etc/passwd so we can permit different passwd files for each different - * host - * (c) 1998-2000 by Bernhard Rosenkränzer - * 19980930 Initial version - * 20000211 Various fixes - */ - -#include "config.h" -#include -#include -#include -#ifdef SHADOW_PASSWORD -# ifdef HAVE_SHADOW_H -# include -# endif -#endif - -#ifndef HAVE_FGETPWENT /* Some systems (*BSD) don't have fgetpwent... */ -#ifdef HAVE_STRINGS_H -#include -#else -#include -#endif -struct passwd *fgetpwent(FILE *stream) -{ - char *entry=(char *) malloc(1024); - struct passwd *p=(struct passwd *) malloc(sizeof(struct passwd)); - char *tmp,*tmp2; - - if(!fgets(entry,1024,stream)) { - free(entry); - free(p); - return NULL; - } - tmp=strdup(entry); - if(strchr(tmp,':')) { - *strchr(tmp,':')=0; - p->pw_name=tmp; - } else { - free(tmp); free(entry); free(p); return NULL; - } - tmp2=strchr(entry,':')+1; - tmp=strdup(tmp2); - if(strchr(tmp,':')) { - *strchr(tmp,':')=0; - p->pw_passwd=tmp; - } else { - free(tmp); free(entry); free(p->pw_name); free(p); return NULL; - } - tmp2=strchr(tmp2,':')+1; - tmp=strdup(tmp2); - if(strchr(tmp,':')) { - *strchr(tmp,':')=0; - p->pw_uid=(uid_t) atoi(tmp); - } else { - free(tmp); free(entry); free(p->pw_passwd); free(p->pw_name); free(p); return NULL; - } - free(tmp); - tmp2=strchr(tmp2,':')+1; - tmp=strdup(tmp2); - if(strchr(tmp,':')) { - *strchr(tmp,':')=0; - p->pw_gid=(gid_t) atoi(tmp); - } else { - free(tmp); free(entry); free(p->pw_passwd); free(p->pw_name); free(p); return NULL; - } - free(tmp); - tmp2=strchr(tmp2,':')+1; - tmp=strdup(tmp2); - if(strchr(tmp,':')) { - *strchr(tmp,':')=0; - p->pw_gecos=tmp; - } else { - free(tmp); free(entry); free(p->pw_passwd); free(p->pw_name); free(p); return NULL; - } - tmp2=strchr(tmp2,':')+1; - tmp=strdup(tmp2); - if(strchr(tmp,':')) { - *strchr(tmp,':')=0; - p->pw_dir=tmp; - } else { - free(tmp); free(entry); free(p->pw_gecos); free(p->pw_passwd); free(p->pw_name); free(p); return NULL; - } - tmp2=strchr(tmp2,':')+1; - if(strchr(tmp2,':')) { - free(entry); free(p->pw_dir); free(p->pw_gecos); free(p->pw_passwd); free(p->pw_name); free(p); return NULL; - } - while(strlen(tmp2) && isspace(tmp2[strlen(tmp2)-1])) - tmp2[strlen(tmp2)-1]=0; - p->pw_shell=strdup(tmp2); - free(entry); - return p; -} -#endif - - -struct passwd *bero_getpwnam(const char * name, const char * file) -{ - FILE *f; - struct passwd *p; - struct passwd *r; - - if (!strcmp(file,"/etc/passwd")) - return (getpwnam(name)); - f=fopen(file,"r"); - if(f==NULL) - return NULL; - p=NULL; - r=NULL; - while((r==NULL) && (p=fgetpwent(f))) - if(!strcasecmp(p->pw_name,name)) - r=p; - fclose(f); - return r; -} - -struct passwd *bero_getpwuid(uid_t uid, const char * file) -{ - FILE *f; - struct passwd *p; - struct passwd *r; - - if (!strcmp(file,"/etc/passwd")) - return getpwuid(uid); - f=fopen(file,"r"); - if(f==NULL) - return NULL; - p=NULL; - r=NULL; - while((r==NULL) && (p=fgetpwent(f))) - if(p->pw_uid==uid) - r=p; - fclose(f); - return r; -} - -#ifdef SHADOW_PASSWORD -struct spwd *bero_getspnam(const char * name, const char * file) -{ - FILE *f; - struct spwd *s; - struct spwd *r; - f=fopen(file,"r"); - if(f==NULL) - return NULL; - s=NULL; - r=NULL; - while((r==NULL) && (s=fgetspent(f))) - if(!strcasecmp(s->sp_namp,name)) - r=s; - fclose(f); - return r; -} -#endif diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/getpwnam.h b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/getpwnam.h deleted file mode 100644 index e3b29d3546..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/getpwnam.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * Replacement for getpwnam - we need it to handle files other than - * /etc/passwd so we can permit different passwd files for each different - * host - * (c) 1998-2000 by Bernhard Rosenkränzer - * 19980930 Initial version - * 20000211 Various fixes - */ - -#include -#include -#include -#ifdef SHADOW_PASSWORD -# ifdef HAVE_SHADOW_H -# include -# endif -#endif - -struct passwd *bero_getpwnam(const char * name, const char * file); -struct passwd *bero_getpwuid(uid_t uid, const char * file); -#ifdef SHADOW_PASSWORD -struct spwd *bero_getspnam(const char * name, const char * file); -#endif diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/glob.c b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/glob.c deleted file mode 100644 index a76ab85c79..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/glob.c +++ /dev/null @@ -1,694 +0,0 @@ -/* - * Copyright (c) 2011 Gary Mills - * - * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -/**************************************************************************** - Copyright (c) 1999,2000,2001 WU-FTPD Development Group. - All rights reserved. - - Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 - The Regents of the University of California. - Portions Copyright (c) 1993, 1994 Washington University in Saint Louis. - Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc. - Portions Copyright (c) 1989 Massachusetts Institute of Technology. - Portions Copyright (c) 1998 Sendmail, Inc. - Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman. - Portions Copyright (c) 1997 by Stan Barber. - Portions Copyright (c) 1997 by Kent Landfield. - Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 - Free Software Foundation, Inc. - - Use and distribution of this software and its source code are governed - by the terms and conditions of the WU-FTPD Software License ("LICENSE"). - - If you did not receive a copy of the license, it may be obtained online - at http://www.wu-ftpd.org/license.html. - - $Id: glob.c,v 1.14.2.2 2001/11/29 17:01:38 wuftpd Exp $ - -****************************************************************************/ -/* - * C-shell glob for random programs. - */ - -#include "config.h" - -#include -#include - -#ifdef HAVE_DIRENT_H -#include -#else -#include -#endif - -#include -#include -#include -#include -#include - -#include "proto.h" - -#define QUOTE 0200 -#define TRIM 0177 -#define eq(a,b) (strcmp(a, b)==0) -#define GAVSIZ (1024 * 8) -#define isdir(d) ((d.st_mode & S_IFMT) == S_IFDIR) - -#define GLOB_LIMIT_MALLOC 65536 -#define GLOB_LIMIT_STAT 128 -#define GLOB_LIMIT_READDIR 16384 - -#define GLOB_INDEX_MALLOC 0 -#define GLOB_INDEX_STAT 1 -#define GLOB_INDEX_READDIR 2 - -static char **gargv; /* Pointer to the (stack) arglist */ -static char **agargv; -static size_t agargv_size; -static int gargc; /* Number args in gargv */ -static size_t gnleft; -static short gflag; -static int tglob(register char); - -/* 0 = malloc(), 1 = stat(), 2 = readdir() */ -static size_t limits[] = { 0, 0, 0 }; - -/* Prototypes */ - -static char *strend(register char *); -static void addpath(char); -static void ginit(char **); -static void collect(register char *, boolean_t check_ncargs); -static void acollect(register char *, boolean_t check_ncargs); -static void sort(void); -static void expand(char *, boolean_t check_ncargs); -static void matchdir(char *, boolean_t check_ncargs); -static int execbrc(char *, char *); -static int match(char *, char *, boolean_t check_ncargs); -static int amatch(char *, char *, boolean_t check_ncargs); -static void Gcat(register char *, register char *, boolean_t check_ncargs); -static void rscan(register char **, int (*f) (register char)); -static int tglob(register char c); -static int gethdir(char *); - -int letter(register char); -int digit(register char); -int any(register int, register char *); -int blklen(register char **); -char **blkcpy(char **, register char **); - -char *globerr; -char *home; -extern int errno; - -static int globcnt; - -char *globchars = "`{[*?"; - -static char *gpath, *gpathp, *lastgpathp; -static int globbed; -static char *entp; -static char **sortbas; - -#ifdef OTHER_PASSWD -#include "getpwnam.h" -extern char _path_passwd[]; -#endif - -char **ftpglob(register char *v, boolean_t check_ncargs) -{ - char agpath[BUFSIZ]; - char *vv[2]; - - if (agargv == NULL) { - size_t inc = GAVSIZ * sizeof (char *); - - agargv = (char **) malloc(inc); - limits[GLOB_INDEX_MALLOC] += inc; - if (agargv == NULL) { - fatal("Out of memory"); - } - agargv_size = GAVSIZ; - } - fixpath(v); - if (v[0] == '\0') - v = "."; - else if ((strlen(v) > 1) && (v[strlen(v) - 1] == '/')) - v[strlen(v) - 1] = '\0'; - - vv[0] = v; - vv[1] = NULL; - globerr = NULL; - gflag = 0; - rscan(vv, tglob); - if (gflag == 0) { - vv[0] = strspl(v, ""); - return (copyblk(vv)); - } - - globerr = NULL; - gpath = agpath; - gpathp = gpath; - *gpathp = 0; - lastgpathp = &gpath[sizeof agpath - 2]; - ginit(agargv); - globcnt = 0; - collect(v, check_ncargs); - if (globcnt == 0 && (gflag & 1)) { - blkfree(gargv), gargv = 0; - return (0); - } - else - return (gargv = copyblk(gargv)); -} - -static void ginit(char **agargv) -{ - - agargv[0] = 0; - gargv = agargv; - sortbas = agargv; - gargc = 0; - gnleft = NCARGS - 4; -} - -static void collect(register char *as, boolean_t check_ncargs) -{ - if (eq(as, "{") || eq(as, "{}")) { - Gcat(as, "", check_ncargs); - sort(); - } - else - acollect(as, check_ncargs); -} - -static void acollect(register char *as, boolean_t check_ncargs) -{ - register int ogargc = gargc; - - gpathp = gpath; - *gpathp = 0; - globbed = 0; - expand(as, check_ncargs); - if (gargc != ogargc) - sort(); -} - -static int -argcmp(const void *p1, const void *p2) -{ - char *s1 = *(char **) p1; - char *s2 = *(char **) p2; - - return (strcmp(s1, s2)); -} - -static void sort(void) -{ - char **Gvp = &gargv[gargc]; - - if (!globerr) - qsort(sortbas, Gvp - sortbas, sizeof (*sortbas), argcmp); - sortbas = Gvp; -} - -static void expand(char *as, boolean_t check_ncargs) -{ - register char *cs; - register char *sgpathp, *oldcs; - struct stat stb; - - if (globerr) - return; - sgpathp = gpathp; - cs = as; - if (*cs == '~' && gpathp == gpath) { - addpath('~'); - for (cs++; letter(*cs) || digit(*cs) || *cs == '-';) - addpath(*cs++); - if (!*cs || *cs == '/') { - if (gpathp != gpath + 1) { - *gpathp = 0; - if (gethdir(gpath + 1)) - globerr = "Unknown user name after ~"; - /* memmove used as strings overlap */ - (void) memmove(gpath, gpath + 1, strlen(gpath + 1) + 1); - } - else - (void) strlcpy(gpath, home, BUFSIZ); - gpathp = strend(gpath); - } - } - while (!any(*cs, globchars)) { - if (*cs == 0) { - if (!globbed) - Gcat(gpath, "", check_ncargs); - else if (stat(gpath, &stb) >= 0) { - Gcat(gpath, "", check_ncargs); - globcnt++; - } - if (limits[GLOB_INDEX_STAT]++ >= GLOB_LIMIT_STAT) - globerr = "Arguments too long"; - goto endit; - } - addpath(*cs++); - } - oldcs = cs; - while (cs > as && *cs != '/') - cs--, gpathp--; - if (*cs == '/') - cs++, gpathp++; - *gpathp = 0; - if (*oldcs == '{') { - (void) execbrc(cs, ((char *) 0)); - return; - } - matchdir(cs, check_ncargs); - endit: - gpathp = sgpathp; - *gpathp = 0; -} - -static void matchdir(char *pattern, boolean_t check_ncargs) -{ - struct stat stb; - -#ifdef HAVE_DIRENT_H - register struct dirent *dp; -#else - register struct direct *dp; -#endif - - DIR *dirp; - - dirp = opendir(*gpath == '\0' ? "." : gpath); - if (dirp == NULL) { - if (globbed) - return; - goto patherr2; - } -#ifdef HAVE_DIRFD - if (fstat(dirfd(dirp), &stb) < 0) -#else /* HAVE_DIRFD */ - if (fstat(dirp->dd_fd, &stb) < 0) -#endif /* HAVE_DIRFD */ - goto patherr1; - if (limits[GLOB_INDEX_STAT]++ >= GLOB_LIMIT_STAT) { - globerr = "Arguments too long"; - return; - } - if (!isdir(stb)) { - errno = ENOTDIR; - goto patherr1; - } - while (!globerr && ((dp = readdir(dirp)) != NULL)) { - if (dp->d_ino == 0) - continue; - if (limits[GLOB_INDEX_READDIR]++ >= GLOB_LIMIT_READDIR) - globerr = "Arguments too long"; - else if (match(dp->d_name, pattern, check_ncargs)) { - Gcat(gpath, dp->d_name, check_ncargs); - globcnt++; - } - } - closedir(dirp); - return; - - patherr1: - closedir(dirp); - patherr2: - globerr = "Bad directory components"; -} - -static int execbrc(char *p, char *s) -{ - char restbuf[BUFSIZ + 2]; - char *restbufend = &restbuf[sizeof(restbuf)]; - register char *pe, *pm, *pl; - int brclev = 0; - char *lm, savec, *sgpathp; - - for (lm = restbuf; *p != '{'; *lm++ = *p++) { - if (lm >= restbufend) - return (0); - } - for (pe = ++p; *pe; pe++) { - switch (*pe) { - - case '{': - brclev++; - continue; - - case '}': - if (brclev == 0) - goto pend; - brclev--; - continue; - - case '[': - for (pe++; *pe && *pe != ']'; pe++) - continue; - if (!*pe) { - globerr = "Missing ]"; - return (0); - } - continue; - } - } - pend: - if (brclev || !*pe) { - globerr = "Missing }"; - return (0); - } - for (pl = pm = p; pm <= pe; pm++) { - switch (*pm & (QUOTE | TRIM)) { - - case '{': - brclev++; - continue; - - case '}': - if (brclev) { - brclev--; - continue; - } - goto doit; - - case ',' | QUOTE: - case ',': - if (brclev) - continue; - doit: - savec = *pm; - *pm = 0; - if (lm + strlen(pl) + strlen(pe + 1) >= restbufend) - return (0); - (void) strlcpy(lm, pl, restbufend - lm); - (void) strlcat(restbuf, pe + 1, sizeof(restbuf)); - *pm = savec; - if (s == 0) { - sgpathp = gpathp; - expand(restbuf, B_TRUE); - gpathp = sgpathp; - *gpathp = 0; - } - else if (amatch(s, restbuf, B_TRUE)) - return (1); - sort(); - pl = pm + 1; - continue; - - case '[': - for (pm++; *pm && *pm != ']'; pm++) - continue; - if (!*pm) { - globerr = "Missing ]"; - return (0); - } - continue; - } - } - return (0); -} - -static int match(char *s, char *p, boolean_t check_ncargs) -{ - register int c; - register char *sentp; - char sglobbed = globbed; - - if (*s == '.' && *p != '.') - return (0); - sentp = entp; - entp = s; - c = amatch(s, p, check_ncargs); - entp = sentp; - globbed = sglobbed; - return (c); -} - -static int amatch(char *s, char *p, boolean_t check_ncargs) -{ - register int scc; - int ok, lc; - char *sgpathp; - struct stat stb; - int c, cc; - - globbed = 1; - for (;;) { - scc = *s++ & TRIM; - switch (c = *p++) { - - case '{': - return (execbrc(p - 1, s - 1)); - - case '[': - ok = 0; - lc = 077777; - while ((cc = *p++)) { - if (cc == ']') { - if (ok) - break; - return (0); - } - if (cc == '-') { - if (lc <= scc && scc <= *p++) - ok++; - } - else if (scc == (lc = cc)) - ok++; - } - if (cc == 0) { - globerr = "Missing ]"; - return (0); - } - continue; - - case '*': - if (!*p) - return (1); - if (*p == '/') { - p++; - goto slash; - } else if (*p == '*') { - s--; - continue; - } - s--; - do { - if (amatch(s, p, check_ncargs)) - return (1); - } while (*s++); - return (0); - - case 0: - return (scc == 0); - - default: - if (c != scc) - return (0); - continue; - - case '?': - if (scc == 0) - return (0); - continue; - - case '/': - if (scc) - return (0); - slash: - s = entp; - sgpathp = gpathp; - while (*s) - addpath(*s++); - addpath('/'); - if (stat(gpath, &stb) == 0 && isdir(stb)) - if (*p == 0) { - Gcat(gpath, "", check_ncargs); - globcnt++; - } - else - expand(p, check_ncargs); - if (limits[GLOB_INDEX_STAT]++ >= GLOB_LIMIT_STAT) - globerr = "Arguments too long"; - gpathp = sgpathp; - *gpathp = 0; - return (0); - } - } -} - -static void Gcat(register char *s1, register char *s2, boolean_t check_ncargs) -{ - register size_t len = strlen(s1) + strlen(s2) + 1; - - if (globerr) - return; - if ((check_ncargs) && ((len + sizeof (char *)) >= gnleft)) { - globerr = "Arguments too long"; - return; - } - if (len > MAXPATHLEN) { - globerr = "Pathname too long"; - return; - } - if (gargc >= agargv_size - 1) { - char **tmp; - size_t inc = GAVSIZ * sizeof (char *); - - tmp = (char **)realloc(agargv, - inc + (agargv_size * sizeof (char *))); - limits[GLOB_INDEX_MALLOC] += inc; - if ((tmp == NULL) || - (limits[GLOB_INDEX_MALLOC] >= GLOB_LIMIT_MALLOC)) { - fatal("Out of memory"); - } else { - agargv = tmp; - agargv_size += GAVSIZ; - } - gargv = agargv; - sortbas = agargv; - } - gargc++; - if (check_ncargs) - gnleft -= len + sizeof (char *); - gargv[gargc] = 0; - gargv[gargc - 1] = strspl(s1, s2); -} - -static void addpath(char c) -{ - - if (gpathp >= lastgpathp) - globerr = "Pathname too long"; - else { - *gpathp++ = c; - *gpathp = 0; - } -} - -static void rscan(register char **t, int (*f) (register char)) -{ - register char *p, c; - - while ((p = *t++)) { - if (*p == '~') - gflag |= 2; - else if (eq(p, "{") || eq(p, "{}")) - continue; - while ((c = *p++)) - (*f) (c); - } -} -static int tglob(register char c) -{ - if (any(c, globchars)) - gflag |= c == '{' ? 2 : 1; - return (c); -} - -int letter(register char c) -{ - return (((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z')) - || (c == '_')); -} - -int digit(register char c) -{ - return (c >= '0' && c <= '9'); -} - -int any(register int c, register char *s) -{ - while (*s) - if (*s++ == c) - return (1); - return (0); -} - -int blklen(register char **av) -{ - register int i = 0; - - while (*av++) - i++; - return (i); -} - -char **blkcpy(char **oav, register char **bv) -{ - register char **av = oav; - - while ((*av++ = *bv++)) - continue; - return (oav); -} - -void blkfree(char **av0) -{ - register char **av = av0; - - if (av) { - while (*av) - free(*av++); - } -} - -char *strspl(register char *cp, register char *dp) -{ - int bufsize = strlen(cp) + strlen(dp) + 1; - char *ep = malloc(bufsize); - - limits[GLOB_INDEX_MALLOC] += bufsize; - if ((ep == NULL) || (limits[GLOB_INDEX_MALLOC] >= GLOB_LIMIT_MALLOC)) - fatal("Out of memory"); - (void) strlcpy(ep, cp, bufsize); - (void) strlcat(ep, dp, bufsize); - return (ep); -} - -char **copyblk(register char **v) -{ - size_t inc = (unsigned) ((blklen(v) + 1) * sizeof(char **)); - char **nv = (char **) malloc(inc); - - limits[GLOB_INDEX_MALLOC] += inc; - if ((nv == NULL) || (limits[GLOB_INDEX_MALLOC] >= GLOB_LIMIT_MALLOC)) - fatal("Out of memory"); - - return (blkcpy(nv, v)); -} - -static char *strend(register char *cp) -{ - while (*cp) - cp++; - return (cp); -} -/* - * Extract a home directory from the password file - * The argument points to a buffer where the name of the - * user whose home directory is sought is currently. - * We write the home directory of the user back there. - */ -static int gethdir(char *home) -{ -#ifdef OTHER_PASSWD - register struct passwd *pp = bero_getpwnam(home, _path_passwd); -#else - register struct passwd *pp = getpwnam(home); -#endif - register char *root = NULL; - if (!pp || home + strlen(pp->pw_dir) >= lastgpathp) - return (1); - root = strstr(pp->pw_dir, "/./"); - (void) strlcpy(home, root ? (root + 2) : pp->pw_dir, lastgpathp - home); - - return (0); -} diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/gssutil.c b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/gssutil.c deleted file mode 100644 index 1a90160861..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/gssutil.c +++ /dev/null @@ -1,1299 +0,0 @@ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * gssutil.c - * - * Utility routines for providing security related services to - * the FTP server. This code uses the GSSAPI (RFC 2743, 2744) - * to provide a generic security layer to the application. The - * security mechanism providing the actual security functions - * is abstracted from the application itself. In the case of the FTP - * server, the security mechanism is based on what the client chooses - * to use when it makes the secure connection. If the client's - * choice of GSS mechanism is not supported by the FTP server, the - * connection may be rejected or fall back to standard Unix/PAM - * authentication. - * - * This code is primarily intended to work with clients who choose - * the Kerberos V5 GSSAPI mechanism as their security service. - */ - -#include "config.h" - -#if defined(USE_GSS) -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#ifdef HAVE_SYS_SYSLOG_H -#include -#endif - -/* CSTYLED */ -#if defined(HAVE_SYSLOG_H) || (!defined(AUTOCONF) && !defined(HAVE_SYS_SYSLOG_H)) -#include -#endif - -#ifdef HAVE_SYSINFO -#include -#endif - -#include - -#include "gssutil.h" -#include "proto.h" - -static char *gss_services[] = { "ftp", "host", 0 }; - -gss_info_t gss_info = { - /* context */ GSS_C_NO_CONTEXT, - /* mechoid */ GSS_C_NULL_OID, - /* client */ NULL, - /* display_name */ NULL, - /* data_prot */ PROT_C, - /* ctrl_prot */ PROT_C, - /* authstate */ GSS_AUTH_NONE, - /* want_creds */ 0, - /* have_creds */ 0, - /* must_auth */ 0 -}; - - -extern char *cur_auth_type; -extern struct SOCKSTORAGE his_addr; -extern struct SOCKSTORAGE ctrl_addr; -extern int debug; - -static char *radixN = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -static char pad = '='; - -#define DEF_GSSBUF_SIZE 2028 -#define DECODELEN(l) (((3 * (l)) / 4) + 4) -#define ENCODELEN(l) (((4 * (l)) / 3) + 4) - -typedef struct { - char *buf; - size_t alloc_len; - size_t len; /* max length of buffer */ - size_t idx; /* offset to beginning of read/write data */ - size_t clen; /* length of the remaining, decrypted data from client */ -}bufrec; - -static bufrec obr = {NULL, 0, 0, 0, 0}; -static bufrec ibr = {NULL, 0, 0, 0, 0}; - -static int looping_write(int fd, const char *buf, size_t len); -static int looping_read(int fd, char *buf, size_t len); -static int radix_encode(unsigned char *inbuf, unsigned char *outbuf, - size_t len, int *outlen, int decode); -static char *radix_error(int e); -static void reply_gss_error(int code, OM_uint32 maj_stat, - OM_uint32 min_stat, gss_OID mechoid, char *s); -static void cleanup_bufrec(bufrec *brec); -static int alloc_bufrec(bufrec *brec, size_t newsz); -static int sec_putbuf(int fd, unsigned char *buf, int len); -static int sec_getbytes(int fd, char *buf, int nbytes); - -/* - * Provide a routine so that ftpd can know the max amount to read - */ -size_t -gss_getinbufsz(void) { - return (ibr.len); -} - -/* - * gss_adjust_buflen - * - * Called when the protection method changes so we can adjust the - * "useable" length of our output buffer accordingly. - */ -void -gss_adjust_buflen() -{ - OM_uint32 maj_stat, min_stat, mlen; - - /* - * If we switched to CLEAR protection, we can use the entire buffer - */ - if (gss_info.data_prot == PROT_C) { - obr.len = obr.alloc_len; - return; - } - - /* - * Otherwise, determine the maximum size that will allow for - * the GSSAPI overhead to fit into the buffer size. - */ - maj_stat = gss_wrap_size_limit(&min_stat, gss_info.context, - (gss_info.data_prot == PROT_P), - GSS_C_QOP_DEFAULT, - (OM_uint32)obr.alloc_len, &mlen); - if (maj_stat != GSS_S_COMPLETE) { - reply_gss_error(535, maj_stat, min_stat, - gss_info.mechoid, - "GSSAPI fudge determination"); - return; - } - obr.len = mlen; - - if (debug) - syslog(LOG_DEBUG, "GSSAPI alloc_len = %d len = %d", - obr.alloc_len, obr.len); -} - -static int -looping_write(int fd, const char *buf, size_t len) -{ - int cc; - register size_t wrlen = len; - - do { - cc = write(fd, buf, wrlen); - if (cc < 0) { - if (errno == EINTR) - continue; - return (cc); - } else { - buf += cc; - wrlen -= cc; - } - } while (wrlen > 0); - - return (len); -} - -static int -looping_read(int fd, char *buf, size_t len) -{ - int cc; - size_t len2 = 0; - - do { - cc = read(fd, buf, len); - if (cc < 0) { - if (errno == EINTR) - continue; - return (cc); /* errno is already set */ - } else if (cc == 0) { - return (len2); - } else { - buf += cc; - len2 += cc; - len -= cc; - } - } while (len > 0); - return (len2); -} - -static int -radix_encode(unsigned char *inbuf, unsigned char *outbuf, - size_t buflen, int *outlen, int decode) -{ - register int i, j, D; - char *p; - unsigned char c; - - if (decode) { - for (i = 0, j = 0; (j < buflen) && - inbuf[i] && inbuf[i] != pad; i++) { - if ((p = strchr(radixN, inbuf[i])) == NULL) - return (1); - D = p - radixN; - switch (i&3) { - case 0: - outbuf[j] = D <<2; - break; - case 1: - outbuf[j++] |= D >>4; - outbuf[j] = (D&15)<<4; - break; - case 2: - outbuf[j++] |= D >>2; - outbuf[j] = (D&3)<<6; - break; - case 3: - outbuf[j++] |= D; - } - } - if (j == buflen && (inbuf[i] && inbuf[i] != pad)) { - /* Oops, we ran out of space in the output buffer */ - return (4); - } - switch (i&3) { - case 1: - return (3); - case 2: if (D&15) - return (3); - if (strcmp((char *)&inbuf[i], "==")) - return (2); - break; - case 3: if (D&3) - return (3); - if (strcmp((char *)&inbuf[i], "=")) - return (2); - } - *outlen = j; - } else { - for (i = 0, j = 0; i < *outlen && j < buflen; i++) - switch (i%3) { - case 0: - outbuf[j++] = radixN[inbuf[i]>>2]; - c = (inbuf[i]&3)<<4; - break; - case 1: - outbuf[j++] = radixN[c|inbuf[i]>>4]; - c = (inbuf[i]&15)<<2; - break; - case 2: - outbuf[j++] = radixN[c|inbuf[i]>>6]; - outbuf[j++] = radixN[inbuf[i]&63]; - c = 0; - } - if (j == buflen && i < *outlen) { - /* output buffer is not big enough */ - return (4); - } - - if (i%3) outbuf[j++] = radixN[c]; - switch (i%3) { - case 1: outbuf[j++] = pad; - case 2: outbuf[j++] = pad; - } - outbuf[*outlen = j] = '\0'; - } - return (0); -} - -static char * -radix_error(int e) -{ - switch (e) { - case 0: return ("Success"); - case 1: return ("Bad character in encoding"); - case 2: return ("Encoding not properly padded"); - case 3: return ("Decoded # of bits not a multiple of 8"); - case 4: return ("Buffer size error"); - default: return ("Unknown error"); - } -} - -static void -reply_gss_error(int code, OM_uint32 maj_stat, - OM_uint32 min_stat, gss_OID mechoid, char *s) -{ - /* a lot of work just to report the error */ - OM_uint32 gmaj_stat, gmin_stat; - gss_buffer_desc msg; - int msg_ctx; - msg_ctx = 0; - - gmaj_stat = gss_display_status(&gmin_stat, maj_stat, - GSS_C_GSS_CODE, - mechoid, - (OM_uint32 *)&msg_ctx, &msg); - if (gmaj_stat == GSS_S_COMPLETE) { - lreply(code, "GSSAPI error major: %s", - (char *)msg.value); - (void) gss_release_buffer(&gmin_stat, &msg); - } - - gmaj_stat = gss_display_status(&gmin_stat, min_stat, - GSS_C_MECH_CODE, - mechoid, - (OM_uint32 *)&msg_ctx, &msg); - if (gmaj_stat == GSS_S_COMPLETE) { - lreply(code, "GSSAPI error minor: %s", (char *)msg.value); - (void) gss_release_buffer(&gmin_stat, &msg); - } - - reply(code, "GSSAPI error: %s", s); -} - - -static void -log_status(char *msg, - OM_uint32 status_code, - int status_type) -{ - OM_uint32 message_context; - gss_buffer_desc status_string; - OM_uint32 maj_status; - OM_uint32 min_status; - - /* From RFC2744: */ - message_context = 0; - - do { - maj_status = gss_display_status( - &min_status, - status_code, - status_type, - GSS_C_NO_OID, - &message_context, - &status_string); - - if (maj_status == GSS_S_COMPLETE) { - syslog(LOG_ERR, - "GSSAPI Error %s: %.*s\n", - msg ? msg : "", - (int)status_string.length, - (char *)status_string.value); - - (void) gss_release_buffer(&min_status, - &status_string); - } else { - syslog(LOG_ERR, - "log_status internal error: gss_display_status failed"); - return; - } - } while (message_context != 0); - -} - -static void -log_gss_error(char *msg, - OM_uint32 maj_stat, - OM_uint32 min_stat) -{ - log_status(msg, maj_stat, GSS_C_GSS_CODE); - log_status(msg, min_stat, GSS_C_MECH_CODE); -} - - -static void -log_gss_info(int priority, - char *luser, - char *remprinc, - gss_OID mechoid, - char *s) -{ - const char *mechStr = __gss_oid_to_mech(mechoid); - - syslog(priority, - "%s: local user=`%s', remote princ=`%s', mech=%s", - s ? s : "", - luser ? luser : "", - remprinc ? remprinc : "", - mechStr ? mechStr : ""); -} - -/* - * gss_user - * - * Handle USER command after AUTH GSSAPI - * - * Check if the remote user can login to the local system w/out a passwd. - * Use the Solaris (private) interface (__gss_userok) if possible, else do - * a basic GSS-API compare. - * - * return 0 == BAD - * 1 == OK - */ -int -gss_user(struct passwd *user_pw) -{ - int retval = 0; - OM_uint32 status, minor; - -#ifdef SOLARIS_GSS_USEROK - - int user_ok = 0; - - if (debug) - log_gss_info(LOG_DEBUG, - user_pw->pw_name, gss_info.display_name, - gss_info.mechoid, - "gss_user: start (gss_userok)"); - - /* gss_auth_rules(5) */ - status = __gss_userok(&minor, gss_info.client, - user_pw->pw_name, &user_ok); - if (status == GSS_S_COMPLETE) { - if (user_ok) { - retval = 1; /* remote user is a-ok */ - } - } - -#else /* SOLARIS_GSS_USEROK */ - - gss_name_t imported_name; - gss_name_t canon_name; - gss_buffer_desc gss_user; - OM_uint32 tmpMinor; - int match = 0; - - if (debug) - log_gss_info(LOG_DEBUG, - user_pw->pw_name, gss_info.display_name, - gss_info.mechoid, "gss_user: start"); - - gss_user.value = user_pw->pw_name; - gss_user.length = strlen(gss_user.value); - - status = gss_import_name(&minor, - &gss_user, - GSS_C_NT_USER_NAME, - &imported_name); - if (status != GSS_S_COMPLETE) { - goto out; - } - - status = gss_canonicalize_name(&minor, - imported_name, - gss_info.mechoid, - &canon_name); - if (status != GSS_S_COMPLETE) { - (void) gss_release_name(&tmpMinor, &imported_name); - goto out; - } - - status = gss_compare_name(&minor, - canon_name, - gss_info.client, - &match); - (void) gss_release_name(&tmpMinor, &canon_name); - (void) gss_release_name(&tmpMinor, &imported_name); - if (status == GSS_S_COMPLETE) { - if (match) { - retval = 1; /* remote user is a-ok */ - } - } - -out: - -#endif /* SOLARIS_GSS_USEROK */ - - if (status != GSS_S_COMPLETE) { - log_gss_info(LOG_ERR, user_pw->pw_name, - gss_info.display_name, gss_info.mechoid, - "gss_user failed"); - log_gss_error("gss_user failed", status, minor); - } - - if (debug) - syslog(LOG_DEBUG, "gss_user: end: retval=%d", retval); - - return (retval); -} - - -/* - * gss_adat - * - * Handle ADAT(Authentication Data) command data. - */ -int -gss_adat(char *adatstr) -{ - int kerror, length; - int replied = 0; - int ret_flags; - gss_buffer_desc tok, out_tok; - gss_cred_id_t deleg_creds = NULL; - OM_uint32 accept_maj, accept_min; - OM_uint32 stat_maj, stat_min; - uchar_t *gout_buf; - size_t outlen; - - length = strlen(adatstr); - outlen = DECODELEN(length); - - gout_buf = (uchar_t *)malloc(outlen); - if (gout_buf == NULL) { - reply(501, "Couldn't decode ADAT, not enough memory"); - syslog(LOG_ERR, "Couldn't decode ADAT, not enough memory"); - return (0); - } - - if ((kerror = radix_encode((unsigned char *)adatstr, - (unsigned char *)gout_buf, - outlen, &length, 1))) { - reply(501, "Couldn't decode ADAT(%s)", - radix_error(kerror)); - syslog(LOG_ERR, "Couldn't decode ADAT(%s)", - radix_error(kerror)); - return (0); - } - tok.value = gout_buf; - tok.length = length; - - gss_info.context = GSS_C_NO_CONTEXT; - - /* - * Call accept_sec_context w/GSS_C_NO_CREDENTIAL to request - * default cred and to not limit the service name to one name - * but rather accept what the clnt requests if service - * princ/keys are available. - */ - if (debug) - syslog(LOG_DEBUG, - "gss_adat: accept_sec_context will try default cred"); - - out_tok.value = NULL; - out_tok.length = 0; - - accept_maj = gss_accept_sec_context(&accept_min, - &gss_info.context, - GSS_C_NO_CREDENTIAL, - &tok, /* ADAT data */ - GSS_C_NO_CHANNEL_BINDINGS, - &gss_info.client, - &gss_info.mechoid, - &out_tok, /* output_token */ - (unsigned int *)&ret_flags, - NULL, /* ignore time_rec */ - NULL); /* delegated creds */ - - - if (debug) { - if (accept_maj == GSS_S_COMPLETE) - syslog(LOG_DEBUG, - "gss_adat: accept_maj = GSS_S_COMPLETE"); - else if (accept_maj == GSS_S_CONTINUE_NEEDED) - syslog(LOG_DEBUG, - "gss_adat: accept_maj = GSS_S_CONTINUE_NEEDED"); - } - free(gout_buf); - - if (accept_maj != GSS_S_COMPLETE && - accept_maj != GSS_S_CONTINUE_NEEDED) { - reply_gss_error(535, accept_maj, accept_min, - GSS_C_NO_OID, "accepting context"); - syslog(LOG_ERR, "failed accepting context"); - if ((ret_flags & GSS_C_DELEG_FLAG) && - deleg_creds != NULL) - (void) gss_release_cred(&stat_min, - &deleg_creds); - - (void) gss_release_buffer(&stat_min, &out_tok); - return (0); - } - - if (debug) - syslog(LOG_DEBUG, "gss_adat: out_tok.length=%d", - out_tok.length); - if (out_tok.length) { - size_t buflen = ENCODELEN(out_tok.length); - uchar_t *gbuf = (uchar_t *)malloc(buflen); - if (gbuf == NULL) { - reply(535, "Couldn't encode ADAT reply, " - "not enough memory."); - syslog(LOG_ERR, "Couldn't encode ADAT reply, " - "not enough memory."); - (void) gss_release_buffer(&stat_min, &out_tok); - return (0); - } - if ((kerror = radix_encode(out_tok.value, - (unsigned char *)gbuf, - buflen, (int *)&out_tok.length, - 0))) { - reply(535, "Couldn't encode ADAT reply(%s)", - radix_error(kerror)); - syslog(LOG_ERR, "couldn't encode ADAT reply"); - if ((ret_flags & GSS_C_DELEG_FLAG) && - deleg_creds != NULL) - (void) gss_release_cred(&stat_min, - &deleg_creds); - - (void) gss_release_buffer(&stat_min, &out_tok); - free(gbuf); - return (0); - } - - if (accept_maj == GSS_S_COMPLETE) { - reply(235, "ADAT=%s", gbuf); - replied = 1; - } else { - /* - * If the server accepts the security data, and - * requires additional data, it should respond - * with reply code 335. - */ - reply(335, "ADAT=%s", gbuf); - } - free(gbuf); - (void) gss_release_buffer(&stat_min, &out_tok); - } - if (accept_maj == GSS_S_COMPLETE) { - gss_buffer_desc namebuf; - gss_OID out_oid; - - /* GSSAPI authentication succeeded */ - gss_info.authstate = GSS_ADAT_DONE; - (void) alloc_bufrec(&obr, DEF_GSSBUF_SIZE); - (void) alloc_bufrec(&ibr, DEF_GSSBUF_SIZE); - /* - * RFC 2228 - "..., once a security data exchange completes - * successfully, if the security mechanism supports - * integrity, then integrity(via the MIC or ENC command, - * and 631 or 632 reply) must be used, ..." - */ - gss_info.ctrl_prot = PROT_S; - - stat_maj = gss_display_name(&stat_min, gss_info.client, - &namebuf, &out_oid); - if (stat_maj != GSS_S_COMPLETE) { - /* - * RFC 2228 - - * "If the server rejects the security data(if - * a checksum fails, for instance), it should - * respond with reply code 535." - */ - reply_gss_error(535, stat_maj, stat_min, - gss_info.mechoid, - "extracting GSSAPI identity name"); - syslog(LOG_ERR, "gssapi error extracting identity"); - if ((ret_flags & GSS_C_DELEG_FLAG) && - deleg_creds != NULL) - (void) gss_release_cred(&stat_min, - &deleg_creds); - return (0); - } - gss_info.display_name = (char *)namebuf.value; - - if (ret_flags & GSS_C_DELEG_FLAG) { - gss_info.have_creds = 1; - if (deleg_creds != NULL) - (void) gss_release_cred(&stat_min, - &deleg_creds); - } - - /* - * If the server accepts the security data, but does - * not require any additional data(i.e., the security - * data exchange has completed successfully), it must - * respond with reply code 235. - */ - if (!replied) { - if ((ret_flags & GSS_C_DELEG_FLAG) && - !gss_info.have_creds) - reply(235, - "GSSAPI Authentication succeeded, but " - "could not accept forwarded credentials"); - else - reply(235, "GSSAPI Authentication succeeded"); - } - return (1); - } else if (accept_maj == GSS_S_CONTINUE_NEEDED) { - /* - * If the server accepts the security data, and - * requires additional data, it should respond with - * reply code 335. - */ - reply(335, "more data needed"); - if ((ret_flags & GSS_C_DELEG_FLAG) && - deleg_creds != NULL) - (void) gss_release_cred(&stat_min, &deleg_creds); - } - - return (0); -} - -/* - * cleanup_bufrec - * - * cleanup the secure buffers - */ -static void -cleanup_bufrec(bufrec *brec) -{ - if (brec->buf) - free(brec->buf); - brec->len = 0; - brec->clen = 0; - brec->idx = 0; -} - -static int -alloc_bufrec(bufrec *brec, size_t newsz) -{ - /* - * Try to allocate a buffer, if it fails, - * divide by 2 and try again. - */ - cleanup_bufrec(brec); - - while (newsz > 0 && !(brec->buf = malloc(newsz))) { - syslog(LOG_ERR, - "malloc bufrec(%d bytes) failed, trying %d", - newsz >>= 1); - } - - if (brec->buf == NULL) - return (-1); - - brec->alloc_len = newsz; - brec->len = newsz; - brec->clen = 0; - brec->idx = 0; - return (0); -} - -/* - * Handle PBSZ command data, return value to caller. - * RFC 2228 says this is a 32 bit int, so limit max value here. - */ -unsigned int -gss_setpbsz(char *pbszstr) -{ - unsigned int newsz = 0; - char *endp; -#define MAX_PBSZ 4294967295U - - errno = 0; - newsz = (unsigned int)strtol(pbszstr, &endp, 10); - if (errno != 0 || newsz > MAX_PBSZ || *endp != '\0') { - reply(501, "Bad value for PBSZ: %s", pbszstr); - return (0); - } - - if (newsz > ibr.len) { - if (alloc_bufrec(&obr, newsz) == -1) { - perror_reply(421, "Local resource failure: malloc"); - dologout(1); - } - if (alloc_bufrec(&ibr, newsz) == -1) { - perror_reply(421, "Local resource failure: malloc"); - dologout(1); - } - } - reply(200, "PBSZ =%lu", ibr.len); - - return (ibr.len); -} - -/* - * sec_putbuf - * - * Wrap the plaintext 'buf' data using gss_wrap and send - * it out. - * - * returns: - * bytes written (success) - * -1 on error(errno set) - * -2 on security error - */ -static int -sec_putbuf(int fd, unsigned char *buf, int len) -{ - unsigned long net_len; - int ret = 0; - gss_buffer_desc in_buf, out_buf; - OM_uint32 maj_stat, min_stat; - int conf_state; - - in_buf.value = buf; - in_buf.length = len; - maj_stat = gss_wrap(&min_stat, gss_info.context, - (gss_info.data_prot == PROT_P), - GSS_C_QOP_DEFAULT, - &in_buf, &conf_state, - &out_buf); - - if (maj_stat != GSS_S_COMPLETE) { - reply_gss_error(535, maj_stat, min_stat, - gss_info.mechoid, - gss_info.data_prot == PROT_P ? - "GSSAPI wrap failed": - "GSSAPI sign failed"); - return (-2); - } - - net_len = (unsigned long)htonl((unsigned long) out_buf.length); - - if ((ret = looping_write(fd, (const char *)&net_len, 4)) != 4) { - syslog(LOG_ERR, "Error writing net_len(%d): %m", net_len); - ret = -1; - goto putbuf_done; - } - - if ((ret = looping_write(fd, out_buf.value, out_buf.length)) != - out_buf.length) { - syslog(LOG_ERR, "Error writing %d bytes: %m", out_buf.length); - ret = -1; - goto putbuf_done; - } -putbuf_done: - - gss_release_buffer(&min_stat, &out_buf); - return (ret); -} - -/* - * sec_write - * - * If GSSAPI security is established, encode the output - * and write it to the client. Else, just write it directly. - */ -int -sec_write(int fd, char *buf, int len) -{ - int nbytes = 0; - if (gss_info.data_prot == PROT_C || - !IS_GSSAUTH(cur_auth_type) || - !(gss_info.authstate & GSS_ADAT_DONE)) - nbytes = write(fd, buf, len); - else { - /* - * Fill up the buffer before actually encrypting - * and writing it out. - */ - while ((obr.idx < obr.len) && (len > 0)) { - int n, ret; - - /* how many bytes can we fit into the buffer? */ - n = (len < (obr.len - obr.idx) ? len : - obr.len - obr.idx); - memcpy(obr.buf + obr.idx, buf, n); - - obr.idx += n; - - if (obr.idx >= obr.len) { - ret = sec_putbuf(fd, (unsigned char *)obr.buf, - obr.idx); - obr.idx = 0; - if (ret < 0) - return (ret); - } - len -= n; - nbytes += n; - } - } - - return (nbytes); -} - -/* - * CCC - * - * Clear Command Channel. - * - * We will understand this command but not allow it in a secure - * connection. It is very dangerous to allow someone to degrade - * the security of the command channel. See RFC2228 for more info. - */ -void -ccc(void) -{ - /* - * Once we have negotiated security successfully, - * do not allow the control channel to be downgraded. - * It should be at least SAFE if not PRIVATE. - */ - if (IS_GSSAUTH(cur_auth_type) && - (gss_info.authstate & GSS_ADAT_DONE) == GSS_ADAT_DONE) - reply(534, "Control channel may not be downgraded"); - else { - gss_info.ctrl_prot = PROT_C; - reply(200, "CCC ok"); - } -} - -int -sec_putc(int c, FILE *stream) -{ - int ret = 0; - /* - * If we are NOT protecting the data - * OR not using the GSSAPI authentication - * OR GSSAPI data is not yet completed, send - * plaintext. - */ - if (gss_info.data_prot == PROT_C || - !IS_GSSAUTH(cur_auth_type) || - !(gss_info.authstate & GSS_ADAT_DONE)) - return (putc(c, stream)); - - /* - * Add the latest byte to the current buffer - */ - if (obr.idx < obr.len) { - obr.buf[obr.idx++] = (unsigned char)(c & 0xff); - } - - if (obr.idx == obr.len) { - ret = sec_putbuf(fileno(stream), (uchar_t *)obr.buf, obr.idx); - if (ret >= 0) - ret = 0; - obr.idx = 0; - } - - return ((ret == 0 ? c : ret)); -} - -int -sec_fprintf(FILE *stream, char *fmt, ...) -{ - int ret; - va_list ap; - va_start(ap, fmt); - - if (gss_info.data_prot == PROT_C || - !IS_GSSAUTH(cur_auth_type) || - !(gss_info.authstate & GSS_ADAT_DONE)) { - ret = vfprintf(stream, fmt, ap); - } else { - (void) vsnprintf(obr.buf, obr.len, fmt, ap); - ret = sec_putbuf(fileno(stream), (unsigned char *)obr.buf, - strlen(obr.buf)); - } - va_end(ap); - return (ret); -} - -/* - * sec_fflush - * - * If GSSAPI protection is configured, write out whatever remains - * in the output buffer using the secure routines, otherwise - * just flush the stream. - */ -int -sec_fflush(FILE *stream) -{ - int ret = 0; - if (gss_info.data_prot == PROT_C || - !IS_GSSAUTH(cur_auth_type) || - !(gss_info.authstate & GSS_ADAT_DONE)) { - fflush(stream); - return (0); - } - if (obr.idx > 0) { - ret = sec_putbuf(fileno(stream), - (unsigned char *)obr.buf, obr.idx); - obr.idx = 0; - } - - if (ret >= 0) - ret = sec_putbuf(fileno(stream), (unsigned char *)"", 0); - /* - * putbuf returns number of bytes or a negative value, - * but fflush must return 0 or -1, so adjust the return - * value so that a positive value is interpreted as success. - */ - return (ret >= 0 ? 0 : ret); -} - -/* - * sec_getbytes - * - * Read and decrypt from the secure data channel. - * - * Return: - * > 0 == number of bytes available in gssbuf - * EOF == End of file. - * -2 == GSS error. - * - */ -static int -sec_getbytes(int fd, char *buf, int nbytes) -{ - /* - * Only read from the network if our current buffer - * is all used up. - */ - if (ibr.idx >= ibr.clen) { - int kerror; - int conf_state; - unsigned int length; - gss_buffer_desc xmit_buf, msg_buf; - OM_uint32 maj_stat, min_stat; - - if ((kerror = looping_read(fd, (char *)&length, 4)) != 4) { - reply(535, "Couldn't read PROT buffer length: %d/%s", - kerror, - (kerror == -1) ? strerror(errno) : "premature EOF"); - return (-2); - } - - if ((length = (unsigned int)ntohl(length)) > ibr.len) { - reply(535, "Length(%d) > PBSZ(%d)", length, ibr.len); - return (-2); - } - - if (length > 0) { - if ((kerror = looping_read(fd, ibr.buf, length)) != - length) { - reply(535, "Couldn't read %u byte PROT buf: %s", - length, (kerror == -1) ? - strerror(errno) : "premature EOF"); - return (-2); - } - - xmit_buf.value = (char *)ibr.buf; - xmit_buf.length = length; - - conf_state = (gss_info.data_prot == PROT_P); - - /* decrypt/verify the message */ - maj_stat = gss_unwrap(&min_stat, gss_info.context, - &xmit_buf, &msg_buf, &conf_state, NULL); - if (maj_stat != GSS_S_COMPLETE) { - reply_gss_error(535, maj_stat, min_stat, - gss_info.mechoid, - (gss_info.data_prot == PROT_P)? - "failed unwrapping ENC message": - "failed unwrapping MIC message"); - return (-2); - } - - memcpy(ibr.buf, msg_buf.value, msg_buf.length); - ibr.clen = msg_buf.length; - ibr.idx = 0; - - gss_release_buffer(&min_stat, &msg_buf); - } else { - ibr.idx = 0; - ibr.clen = 0; - return (EOF); - } - } - - /* - * If there are 'nbytes' of plain text available, use them, else - * get whats available. - */ - nbytes = (nbytes < (ibr.clen - ibr.idx) ? nbytes : ibr.clen - ibr.idx); - - memcpy(buf, ibr.buf + ibr.idx, nbytes); - ibr.idx += nbytes; - - return ((nbytes == 0 ? EOF : nbytes)); -} - -/* - * Get a buffer of 'maxlen' bytes from the client. - * If we are using GSSAPI protection, use the secure - * input buffer. - */ -int -sec_read(int fd, char *buf, int maxlen) -{ - int nbytes = 0; - - if (gss_info.data_prot != PROT_C && - IS_GSSAUTH(cur_auth_type) && - (gss_info.authstate & GSS_ADAT_DONE)) { - /* Get as much data as possible */ - nbytes = sec_getbytes(fd, buf, maxlen); - if (nbytes == EOF) - nbytes = 0; - } else { - nbytes = read(fd, buf, maxlen); - } - return (nbytes); -} - -/* - * sec_getc - * - * Get a single character from the secure network buffer. - */ -int -sec_getc(FILE *stream) -{ - int nbytes; - unsigned char c; - - if (gss_info.data_prot != PROT_C && - IS_GSSAUTH(cur_auth_type) && - (gss_info.authstate & GSS_ADAT_DONE)) { - nbytes = sec_getbytes(fileno(stream), (char *)&c, 1); - if (nbytes > 0) - nbytes = (int)c; - return (nbytes); - } else - return (getc(stream)); -} - -/* - * sec_reply - * - * Securely encode a reply destined for the ftp client - * depending on the GSSAPI settings. - */ -int -sec_reply(char *buf, int bufsiz, int n) -{ - char *out = NULL, *in = NULL; - size_t inlen; - gss_buffer_desc in_buf, out_buf; - OM_uint32 maj_stat, min_stat; - int conf_state, length, kerror; - int ret = 0; - - if (debug) - syslog(LOG_DEBUG, "encoding %s", buf); - - in_buf.value = buf; - in_buf.length = strlen(buf) + 1; - maj_stat = gss_wrap(&min_stat, gss_info.context, - gss_info.ctrl_prot == PROT_P, - GSS_C_QOP_DEFAULT, - &in_buf, &conf_state, - &out_buf); - if (maj_stat != GSS_S_COMPLETE) { - syslog(LOG_ERR, "gss_wrap %s did not complete", - (gss_info.ctrl_prot == PROT_P) ? "ENC": "MIC"); - ret = -2; - gss_release_buffer(&min_stat, &out_buf); - goto end; - } else if ((gss_info.ctrl_prot == PROT_P) && !conf_state) { - syslog(LOG_ERR, "gss_wrap did not encrypt message"); - ret = -2; - gss_release_buffer(&min_stat, &out_buf); - goto end; - } else { - out = (char *)malloc(out_buf.length); - if (out == NULL) { - syslog(LOG_ERR, "Memory error allocating buffer"); - ret = -2; - gss_release_buffer(&min_stat, &out_buf); - goto end; - } - memcpy(out, out_buf.value, out_buf.length); - length = out_buf.length; - gss_release_buffer(&min_stat, &out_buf); - ret = 0; - } - /* - * Base64 encode the reply. encrypted "out" becomes - * encoded "in" buffer. - * Stick it all back in 'buf' for final output. - */ - inlen = ENCODELEN(length); - in = (char *)malloc(inlen); - if (in == NULL) { - syslog(LOG_ERR, "Memory error allocating buffer"); - ret = -2; - goto end; - } - if ((kerror = radix_encode((unsigned char *)out, - (unsigned char *)in, inlen, - &length, 0))) { - syslog(LOG_ERR, "Couldn't encode reply(%s)", - radix_error(kerror)); - strncpy(buf, in, bufsiz-1); - buf[bufsiz - 1] = '\0'; - } else { - snprintf(buf, bufsiz, "%s%c%s", - gss_info.ctrl_prot == PROT_P ? "632" : "631", - n ? ' ' : '-', in); - } -end: - if (in) free(in); - if (out) free(out); - - return (ret); -} - -/* - * sec_decode_command - * - * If a command is received which is encoded(ENC, MIC, or CONF), - * decode it here using GSSAPI. - */ -char * -sec_decode_command(char *cmd) -{ - char *out = NULL, *cp; - int len, mic, outlen; - gss_buffer_desc xmit_buf, msg_buf; - OM_uint32 maj_stat, min_stat; - int conf_state; - int kerror; - char *cs; - char *s = cmd; - - if ((cs = strpbrk(s, " \r\n"))) - *cs++ = '\0'; - upper(s); - - if ((mic = strcmp(s, "ENC")) != 0 && strcmp(s, "MIC") && - strcmp(s, "CONF")) { - reply(533, "All commands must be protected."); - syslog(LOG_ERR, "Unprotected command received %s", s); - *s = '\0'; - return (s); - } - - if ((cp = strpbrk(cs, " \r\n"))) - *cp = '\0'; - - outlen = DECODELEN(strlen(cs)); - - out = (char *)malloc(outlen); - if (out == NULL) { - reply(501, "Cannot decode response - not enough memory"); - syslog(LOG_ERR, "Cannot decode response - not enough memory"); - *s = '\0'; - return (s); - } - len = strlen(cs); - if ((kerror = radix_encode((unsigned char *)cs, - (unsigned char *)out, - outlen, &len, 1))) { - reply(501, "Can't base 64 decode argument to %s command(%s)", - mic ? "MIC" : "ENC", radix_error(kerror)); - *s = '\0'; - free(out); - return (s); - } - - if (debug) - syslog(LOG_DEBUG, "getline got %d from %s <%s >\n", - len, cs, mic ? "MIC" : "ENC"); - - xmit_buf.value = out; - xmit_buf.length = len; - - /* decrypt the message */ - conf_state = !mic; - maj_stat = gss_unwrap(&min_stat, gss_info.context, &xmit_buf, - &msg_buf, &conf_state, NULL); - if (maj_stat == GSS_S_CONTINUE_NEEDED) { - if (debug) syslog(LOG_DEBUG, "%s-unwrap continued", - mic ? "MIC" : "ENC"); - reply(535, "%s-unwrap continued, oops", mic ? "MIC" : "ENC"); - *s = 0; - free(out); - return (s); - } - - free(out); - if (maj_stat != GSS_S_COMPLETE) { - reply_gss_error(535, maj_stat, min_stat, - gss_info.mechoid, - mic ? "failed unwrapping MIC message": - "failed unwrapping ENC message"); - *s = 0; - return (s); - } - - memcpy(s, msg_buf.value, msg_buf.length); - strcpy(s + msg_buf.length-(s[msg_buf.length-1] ? 0 : 1), "\r\n"); - gss_release_buffer(&min_stat, &msg_buf); - - return (s); -} - -#endif /* defined(USE_GSS) */ diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/gssutil.h b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/gssutil.h deleted file mode 100644 index 84ee9298a1..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/gssutil.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _GSSUTIL_H -#define _GSSUTIL_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#ifdef SOLARIS_2 -#include -#else -#include -#endif - -#ifndef SOLARIS_2 -#define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name -#endif - -#ifndef g_OID_equal -#define g_OID_equal(o1, o2) \ - (((o1)->length == (o2)->length) && \ - (memcmp((o1)->elements, (o2)->elements, (int)(o1)->length) == 0)) -#endif /* g_OID_equal */ - -#define GSS_AUTH_NONE 0x00 -#define GSS_ADAT_DONE 0x01 -#define GSS_USER_DONE 0x02 -#define GSS_PWD_DONE 0x04 - -typedef struct gss_inforec { - gss_ctx_id_t context; - gss_OID mechoid; - gss_name_t client; - char *display_name; - unsigned char data_prot; - unsigned char ctrl_prot; - unsigned char authstate; - unsigned char want_creds; - unsigned char have_creds; - unsigned char must_gss_auth; -} gss_info_t; - -#define GSSUSERAUTH_OK(x) (((x).authstate & (GSS_ADAT_DONE|GSS_USER_DONE)) \ -== (GSS_ADAT_DONE|GSS_USER_DONE)) - -#define IS_GSSAUTH(s) ((s) != NULL && (strcmp((s), "GSSAPI") == 0)) - -int gss_user(struct passwd *); -int gss_adat(char *adatstr); -unsigned int gss_setpbsz(char *pbszstr); -int sec_write(int fd, char *buf, int len); -void ccc(void); -int sec_putc(int c, FILE *stream); -int sec_getc(FILE *stream); -int sec_fprintf(FILE *stream, char *fmt, ...); -int sec_fflush(FILE *stream); -int sec_read(int fd, char *buf, int maxlen); -int sec_reply(char *buf, int bufsiz, int n); -char *sec_decode_command(char *cmd); -size_t gss_getinbufsz(void); -void gss_adjust_buflen(void); - -#ifdef __cplusplus -} -#endif - -#endif /* _GSSUTIL_H */ diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/hostacc.c b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/hostacc.c deleted file mode 100644 index 9ba9a39f3a..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/hostacc.c +++ /dev/null @@ -1,359 +0,0 @@ -#pragma ident "%Z%%M% %I% %E% SMI" - -/**************************************************************************** - Copyright (c) 1999,2000 WU-FTPD Development Group. - All rights reserved. - - Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 - The Regents of the University of California. - Portions Copyright (c) 1993, 1994 Washington University in Saint Louis. - Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc. - Portions Copyright (c) 1989 Massachusetts Institute of Technology. - Portions Copyright (c) 1998 Sendmail, Inc. - Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman. - Portions Copyright (c) 1997 by Stan Barber. - Portions Copyright (c) 1997 by Kent Landfield. - Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 - Free Software Foundation, Inc. - - Use and distribution of this software and its source code are governed - by the terms and conditions of the WU-FTPD Software License ("LICENSE"). - - If you did not receive a copy of the license, it may be obtained online - at http://www.wu-ftpd.org/license.html. - - $Id: hostacc.c,v 1.8 2000/07/01 18:17:39 wuftpd Exp $ - -****************************************************************************/ -/* - * hostacc.c - Implementation of host access for the - * experimental FTP daemon developed at - * Washington University. - * - * INITIAL AUTHOR - Bart Muijzer - * - * HISTORY - * 930316 BM Created - * 930317 BM Converted to local naming convention; - * added rhost_ok(), cleanup code in enghacc() - * 930318 BM Ported to BSD; fixed memory leaks - * 930322 BM Changed algorithm: not in configfile = allow - * in configfile and match = allow|deny - * in configfile and no match = deny - */ -#include "config.h" - -#ifdef HOST_ACCESS - -#include "proto.h" -#include "hostacc.h" - -static char linbuf[MAXLEN]; /* Buffer to hold one line of config-file */ -static char unibuf[MAXLEN]; /* Buffer to hold unified line */ -static hacc_t *ha_arr; /* Array with host access information */ - -static FILE *ptFp; /* FILE * into host access config file */ -static int iHaInd = 0; /* Index in ha_arr */ -static int iHaSize; /* Will hold actual #elems in ha_arr */ -static int iFirstTim = 1; /* Used by gethacc() to see if index in */ - /* ha_arr needs to be reset */ - -/* ------------------------------------------------------------------------ *\ - * FUNCTION : rhost_ok * - * PURPOSE : Check if a host is allowed to make a connection * - * ARGUMENTS : Remote user name, remote host name, remote host address * - * RETURNS : 1 if host is granted access, 0 if not * - \* ------------------------------------------------------------------------ */ - -int rhost_ok(char *pcRuser, char *pcRhost, char *pcRaddr) -{ - hacc_t *ptHtmp; - char *pcHost; - char *ha_login; - int iInd, iLineMatch = 0, iUserSeen = 0; - - switch (sethacc()) { - case 1: - /* no hostaccess file; disable mechanism */ - return (1); - /* break; */ - case -1: - syslog(LOG_INFO, "rhost_ok: sethacc failed"); - endhacc(); - return (0); - /* break; */ - default: - break; - } - - /* user names "ftp" and "anonymous" are equivalent */ - if (!strcasecmp(pcRuser, "anonymous")) - pcRuser = "ftp"; - - while (((ptHtmp = gethacc()) != (hacc_t *) NULL) && !iLineMatch) { - if (strcasecmp(ptHtmp->ha_login, "anonymous")) - ha_login = ptHtmp->ha_login; - else - ha_login = "ftp"; - - if ((strcasecmp(pcRuser, ha_login)) && strcmp(ha_login, "*")) - /* wrong user, check rest of file */ - continue; - - /* - * We have seen a line regarding the current user. - * Remember this. - */ - iUserSeen = 1; - - for (iInd = 0, pcHost = ptHtmp->ha_hosts[0]; - ((iInd < MAXHST) && (pcHost != NULL) && !iLineMatch); - pcHost = ptHtmp->ha_hosts[++iInd]) { - iLineMatch = hostmatch(pcHost, pcRaddr, pcRhost); - if (iLineMatch) { - iLineMatch = (ptHtmp->ha_type == ALLOW) ? 1 : 0; - goto match; - } - } - } - - match: - /* - * At this point, iUserSeen == 1 if we've seen lines regarding - * the current user, and 0 otherwise. If we reached the end of - * the config file without a match we allow. Else, we allow or - * deny according to the rule found. - */ - - if (endhacc()) { - syslog(LOG_INFO, "rhost_ok: endhacc failed"); - return (0); - } - - if (iUserSeen) - return (ptHtmp == NULL) ? 0 : iLineMatch; - else - /* Nothing at all about user in configfile, allow */ - return (1); -} - -/* ------------------------------------------------------------------------ *\ - * FUNCTION : sethacc * - * PURPOSE : Initialize data structures for host access * - * ARGUMENTS : None * - * RETURNS : -1 on failure, 1 if host access file doesn't exist, * - * 0 otherwise * - \* ------------------------------------------------------------------------ */ - -static int sethacc(void) -{ - int iHaHind = 0; /* Index in list of hosts */ - char *pcBegin, *pcEnd, *pcColon; - char *pcTmp1, *pcTmp2; - int iHaMalloc = 0; /* how many elem malloced */ - - iHaInd = 0; - iFirstTim = 1; - /* Open config file */ - if ((ptFp = fopen(_path_ftphosts, "r")) == NULL) { - if (errno == ENOENT) - return (1); - else { - fatalmsg("Can't open host access file"); - iHaSize = iHaInd; - return (-1); - } - } - ha_arr = (hacc_t *) malloc((iHaMalloc = 10) * sizeof(hacc_t)); - if (ha_arr == NULL) { - syslog(LOG_ERR, "malloc error in sethacc"); - exit(0); - } - - while (fgets(linbuf, MAXLEN, ptFp) != NULL) { - iHaHind = 0; - - /* Find first non-whitespace character */ - for (pcBegin = linbuf; - ((*pcBegin == '\t') || (*pcBegin == ' ')); - pcBegin++); - - /* Get rid of comments */ - if ((pcEnd = strchr(linbuf, '#')) != NULL) - *pcEnd = '\0'; - - - /* Skip empty lines */ - if ((pcBegin == pcEnd) || (*pcBegin == '\n')) - continue; - - /* Substitute all whitespace by a single ":" so we can - * easily break on words later on. The easiest way is - * to copy the result into a temporary buffer (called - * the "unified buffer" because it will store a line in - * the same format, regardless of the format the original - * line was in). - * The result will look like: "allow:name:host:host:host" - */ - for (pcTmp1 = pcBegin, pcTmp2 = unibuf; *pcTmp1; pcTmp1++) { - if (*pcTmp1 != '\t' && *pcTmp1 != ' ' && *pcTmp1 != '\n') - *pcTmp2++ = *pcTmp1; - else - /* whitespace */ - if (*(pcTmp2 - 1) == ':') - continue; - else - *pcTmp2++ = ':'; - } - - /* Throw away trailing whitespace, now indicated by - * the last character of the unified buffer being a - * colon. Remember where the news string ends. - */ - pcEnd = (*(pcTmp2 - 1) == ':') ? (pcTmp2 - 1) : pcTmp2; - *pcEnd = '\0'; /* Terminate new string */ - - /* - * Check if we need to expand the array with - * host access information - */ - if (iHaInd >= iHaMalloc) { - ha_arr = (hacc_t *) realloc(ha_arr, (iHaMalloc += 10) * sizeof(hacc_t)); - if (!ha_arr) { - fatalmsg("Failed to realloc host access array"); - iHaSize = iHaInd; - return (-1); - } - } - - /* Store what's left of the line into the - * hacc_t structure. First the access type, - * then the loginname, and finally a list of - * hosts to which all this applies. - */ - pcBegin = unibuf; - if (!strncmp(pcBegin, "deny", 4)) { - ha_arr[iHaInd].ha_type = DENY; - pcBegin += 5; - } - else if (!strncmp(pcBegin, "allow", 5)) { - ha_arr[iHaInd].ha_type = ALLOW; - pcBegin += 6; - } - else { - fatalmsg("Format error in host access file"); - iHaSize = iHaInd; - return (-1); - } - - if ((pcColon = strchr(pcBegin, ':')) != NULL) - ha_arr[iHaInd].ha_login = - strnsav(pcBegin, (pcColon - pcBegin)); - else { - fatalmsg("Format error in host access file"); - iHaSize = iHaInd; - return (-1); - } - - pcBegin = pcColon + 1; - while ((pcColon = strchr(pcBegin, ':')) != NULL) { - ha_arr[iHaInd].ha_hosts[iHaHind++] = - strnsav(pcBegin, (pcColon - pcBegin)); - pcBegin = pcColon + 1; - if (iHaHind >= MAXHST) { - fatalmsg("Line too long"); - iHaSize = iHaInd; - return (-1); - } - } - ha_arr[iHaInd].ha_hosts[iHaHind++] = - strnsav(pcBegin, (pcEnd - pcBegin)); - ha_arr[iHaInd].ha_hosts[iHaHind] = NULL; - iHaInd++; - } - iHaSize = iHaInd; /* Record current size of ha_arr */ - return ((feof(ptFp)) ? 0 : -1); -} - -/* ------------------------------------------------------------------------ *\ - * FUNCTION : gethacc * - * PURPOSE : return pointer to the next host_access structure * - * ARGUMENTS : None * - * RETURNS : NULL on failure, pointervalue otherwise * - \* ------------------------------------------------------------------------ */ - -static hacc_t *gethacc(void) -{ - static int iHaInd; - static hacc_t ptTmp; - - if (iFirstTim) { - iFirstTim = 0; - iHaInd = 0; - } - if (iHaInd >= iHaSize) - return ((hacc_t *) NULL); - else { - memmove(&ptTmp, &(ha_arr[iHaInd]), sizeof(hacc_t)); - iHaInd++; - return (&ptTmp); - } -} - -/* ------------------------------------------------------------------------ *\ - * FUNCTION : endhacc * - * PURPOSE : Free allocated data structures for host access * - * ARGUMENTS : None * - * RETURNS : -1 on failure, 0 otherwise * - \* ------------------------------------------------------------------------ */ - -static int endhacc(void) -{ - int iInd; - hacc_t *ptHtmp; - - if (ha_arr == (hacc_t *) NULL) - return (0); - - for (ptHtmp = ha_arr; - ptHtmp < ha_arr + iHaSize && ptHtmp->ha_type; - ptHtmp++) { - ptHtmp->ha_type = 0; - if (ptHtmp->ha_login) { - free(ptHtmp->ha_login); - ptHtmp->ha_login = NULL; - } - for (iInd = 0; - iInd < MAXHST && ptHtmp->ha_hosts[iInd]; - iInd++) { - free(ptHtmp->ha_hosts[iInd]); - ptHtmp->ha_hosts[iInd] = NULL; - } - } - free(ha_arr); - ha_arr = NULL; - - if (ptFp && fclose(ptFp)) - return (-1); - return (0); -} - -/* ------------------------------------------------------------------------ */ - -static void fatalmsg(char *pcMsg) -{ - syslog(LOG_INFO, "host_access: %s", pcMsg); -} - -static char *strnsav(char *pcStr, int iLen) -{ - char *pcBuf; - - if ((pcBuf = (char *) malloc(iLen + 1)) == NULL) - return (NULL); - strncpy(pcBuf, pcStr, iLen); - pcBuf[iLen] = '\0'; - return (pcBuf); -} - -#endif /* HOST_ACCESS */ diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/hostacc.h b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/hostacc.h deleted file mode 100644 index 4e191d1347..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/hostacc.h +++ /dev/null @@ -1,82 +0,0 @@ -#pragma ident "%Z%%M% %I% %E% SMI" - -/**************************************************************************** - Copyright (c) 1999,2000 WU-FTPD Development Group. - All rights reserved. - - Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 - The Regents of the University of California. - Portions Copyright (c) 1993, 1994 Washington University in Saint Louis. - Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc. - Portions Copyright (c) 1989 Massachusetts Institute of Technology. - Portions Copyright (c) 1998 Sendmail, Inc. - Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman. - Portions Copyright (c) 1997 by Stan Barber. - Portions Copyright (c) 1997 by Kent Landfield. - Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 - Free Software Foundation, Inc. - - Use and distribution of this software and its source code are governed - by the terms and conditions of the WU-FTPD Software License ("LICENSE"). - - If you did not receive a copy of the license, it may be obtained online - at http://www.wu-ftpd.org/license.html. - - $Id: hostacc.h,v 1.9 2000/07/01 18:17:39 wuftpd Exp $ - -****************************************************************************/ -/* - * hostacc.h - Header file used in the implementation of - * host access for the WU-FTPD FTP daemon - * - * INITIAL AUTHOR - Bart Muijzer - */ - -#ifdef HOST_ACCESS - -#include -#ifdef HAVE_SYS_SYSLOG_H -#include -#endif -#if defined(HAVE_SYSLOG_H) || (!defined(AUTOCONF) && !defined(HAVE_SYS_SYSLOG_H)) -#include -#endif -#include -#include -#include - -#include "pathnames.h" /* From the ftpd sources */ - -/* - * Host Access types, as stored in the ha_type field, - * and some other constants. All of this is tunable as - * long as you don't depend on the values. - */ - -#define ALLOW 1 -#define DENY 2 - -#define MAXLEN 1024 /* Maximum length of one line in config file */ -#define MAXHST 12 /* Max. number of hosts allowed on one line */ - -/* ------------------------------------------------------------------------- */ - -/* - * Structure holding all host-access information - */ - -typedef struct { - short ha_type; /* ALLOW | DENY */ - char *ha_login; /* Loginname to investigate */ - char *ha_hosts[MAXHST]; /* Array of hostnames */ -} hacc_t; - -/* ------------------------------------------------------------------------ */ - -static int sethacc(void); -static int endhacc(void); -static hacc_t *gethacc(void); -static void fatalmsg(char *pcMsg); -static char *strnsav(char *pcStr, int iLen); - -#endif /* HOST_ACCESS */ diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/inet.c b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/inet.c deleted file mode 100644 index 0b8407cce4..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/inet.c +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Copyright 2001-2003 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * Utility functions which help with address and hostname manipulation in a - * mixed IPv4 / IPv6 environment. - */ - -#include "config.h" -#include -#include -#include -#include -#include -#include "proto.h" - -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 64 -#endif - -/* Converts a hostname into an IP address in presentation form */ -char *inet_htop(const char *hostname) -{ -#ifdef INET6 - static char abuf[INET6_ADDRSTRLEN]; - struct addrinfo hints, *result; - char *str = NULL; - void *addr = NULL; - - memset(&hints, 0, sizeof(hints)); - hints.ai_flags = AI_CANONNAME; - hints.ai_family = PF_UNSPEC; - - if (getaddrinfo(hostname, NULL, &hints, &result) == 0) { - if (result->ai_family == AF_INET) - addr = ((void *)&((struct sockaddr_in *)result->ai_addr)->sin_addr); - else if (result->ai_family == AF_INET6) - addr = ((void *)&((struct sockaddr_in6 *)result->ai_addr)->sin6_addr); - if (addr) - str = (char *)inet_ntop_native(result->ai_family, addr, abuf, - sizeof(abuf)); - freeaddrinfo(result); - return str; - } -#else - struct hostent *hp; - struct in_addr in; - - if ((hp = gethostbyname(hostname)) != NULL) { - memcpy(&in, hp->h_addr, sizeof(in)); - return inet_ntoa(in); - } -#endif - return NULL; -} - -/* - * Converts a socket structures IP address into presentation form. - * Note: returns a pointer to a buffer which is overwritten on each call. - */ -char *inet_stop(struct SOCKSTORAGE *ss) -{ -#ifdef INET6 - static char abuf[INET6_ADDRSTRLEN]; - struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ss; - - if (ss->ss_family == AF_INET6) - return (char *)inet_ntop_native(AF_INET6, &sin6->sin6_addr, abuf, sizeof (abuf)); -#endif - return inet_ntoa(((struct sockaddr_in *)ss)->sin_addr); -} - -char *wu_gethostbyname(const char *hostname) -{ -#ifdef INET6 - static char hostbuf[MAXHOSTNAMELEN]; - struct addrinfo hints, *result; - - memset(&hints, 0, sizeof(hints)); - hints.ai_flags = AI_CANONNAME; - hints.ai_family = PF_UNSPEC; - - if (getaddrinfo(hostname, NULL, &hints, &result) == 0) { - strncpy(hostbuf, result->ai_canonname, sizeof(hostbuf)); - hostbuf[sizeof(hostbuf) - 1] = '\0'; - freeaddrinfo(result); - return hostbuf; - } -#else - struct hostent *hp = gethostbyname(hostname); - - if (hp) - return hp->h_name; -#endif - return NULL; -} - -int wu_gethostbyaddr(struct SOCKSTORAGE *ss, char *hostname, int hostlen) -{ -#ifdef INET6 - char hostbuf[NI_MAXHOST]; -#else - struct hostent *hp; -#endif - - if ((ss == NULL) || (hostname == NULL) || (hostlen < 1)) - return 0; - -#ifdef INET6 - if (getnameinfo((struct sockaddr *)ss, SOCK_LEN(*ss), hostbuf, - sizeof(hostbuf), NULL, 0, NI_NAMEREQD) == 0) { - strncpy(hostname, hostbuf, hostlen); - hostname[hostlen - 1] = '\0'; - return 1; - } -#else - hp = gethostbyaddr((char *)&ss->sin_addr, sizeof(struct in_addr), AF_INET); - if (hp) { - strncpy(hostname, hp->h_name, hostlen); - hostname[hostlen - 1] = '\0'; - return 1; - } -#endif - return 0; -} - -/* Compares a socket structures IP address with addr, returning 0 on a match */ -int sock_cmp_inaddr(struct SOCKSTORAGE *ss, struct in_addr addr) { -#ifdef INET6 - if (ss->ss_family == AF_INET6) { - struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ss; - - if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) { - u_char *a = (u_char *)&sin6->sin6_addr; - - /* compare the IPv4 part of an IPv4-mapped IPv6 address */ - return memcmp(&addr, a + sizeof(struct in6_addr) - sizeof(struct in_addr), sizeof(struct in_addr)); - } - return 1; - } -#endif - return ((struct sockaddr_in *)ss)->sin_addr.s_addr != addr.s_addr; -} - -#ifdef INET6 -/* Sets a socket structures IP address to addr */ -void sock_set_inaddr(struct SOCKSTORAGE *ss, struct in_addr addr) { - if (ss->ss_family == AF_INET6) { - struct in6_addr *in6; - - in6 = &((struct sockaddr_in6 *)ss)->sin6_addr; - memset(&in6->s6_addr[0], 0, 10); - memset(&in6->s6_addr[10], 0xff, 2); - memcpy(&in6->s6_addr[12], &addr, sizeof(struct in_addr)); - return; - } - ((struct sockaddr_in *)ss)->sin_addr = addr; -} - -/* Compares two socket structure IP addresses, returning 0 if they match */ -int sock_cmp_addr(struct SOCKSTORAGE *ss1, struct SOCKSTORAGE *ss2) { - if (ss1->ss_family == AF_INET6) { - if (ss2->ss_family == AF_INET6) - return memcmp(&((struct sockaddr_in6 *)ss1)->sin6_addr, - &((struct sockaddr_in6 *)ss2)->sin6_addr, - sizeof(struct in6_addr)); - return sock_cmp_inaddr(ss1, ((struct sockaddr_in *)ss2)->sin_addr); - } - return sock_cmp_inaddr(ss2, ((struct sockaddr_in *)ss1)->sin_addr); -} - -void sock_set_scope(struct SOCKSTORAGE *dst, struct SOCKSTORAGE *src) { -#ifdef HAVE_SIN6_SCOPE_ID - struct sockaddr_in6 *src_in6 = (struct sockaddr_in6 *)src; - struct sockaddr_in6 *dst_in6 = (struct sockaddr_in6 *)dst; - - if (dst->ss_family == AF_INET6) { - if ((src->ss_family == AF_INET6) && - (memcmp(&src_in6->sin6_addr, &dst_in6->sin6_addr, - sizeof(struct in6_addr)) == 0)) - dst_in6->sin6_scope_id = src_in6->sin6_scope_id; - else - dst_in6->sin6_scope_id = 0; - } -#endif -} - -/* - * Similar to inet_pton(), str can be an IPv4 or IPv6 address, but an IPv6 - * address is returned in addr. - */ -int inet_pton6(char *str, struct in6_addr *addr) -{ - struct in_addr v4addr; - - /* Try v6 first */ - if (inet_pton(AF_INET6, str, addr) != 1) { - /* If that fails, try v4 and map it */ - if (inet_pton(AF_INET, str, &v4addr) == 1) { - memset(&addr->s6_addr[0], 0, 10); - memset(&addr->s6_addr[10], 0xff, 2); - memcpy(&addr->s6_addr[12], &v4addr, sizeof(struct in_addr)); - } - else - return 0; - } - return 1; -} - -/* - * Similar to inet_ntop(), except when addr is an IPv4-mapped IPv6 address - * returns a printable IPv4 address (not an IPv4-mapped IPv6 address). - */ -const char *inet_ntop_native(int af, const void *addr, char *dst, size_t size) -{ - const char *result; - - if (af == AF_INET6) { - if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)addr)) - result = inet_ntop(AF_INET, (char *)addr + sizeof(struct in6_addr) - - sizeof(struct in_addr), dst, size); - else - result = inet_ntop(AF_INET6, addr, dst, size); - } - else - result = inet_ntop(af, addr, dst, size); - return result; -} -#endif /* INET6 */ diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/logwtmp.c b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/logwtmp.c deleted file mode 100644 index ec17f3ee68..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/logwtmp.c +++ /dev/null @@ -1,198 +0,0 @@ -#pragma ident "%Z%%M% %I% %E% SMI" - -/**************************************************************************** - Copyright (c) 1999,2000 WU-FTPD Development Group. - All rights reserved. - - Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 - The Regents of the University of California. - Portions Copyright (c) 1993, 1994 Washington University in Saint Louis. - Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc. - Portions Copyright (c) 1989 Massachusetts Institute of Technology. - Portions Copyright (c) 1998 Sendmail, Inc. - Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman. - Portions Copyright (c) 1997 by Stan Barber. - Portions Copyright (c) 1997 by Kent Landfield. - Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 - Free Software Foundation, Inc. - - Use and distribution of this software and its source code are governed - by the terms and conditions of the WU-FTPD Software License ("LICENSE"). - - If you did not receive a copy of the license, it may be obtained online - at http://www.wu-ftpd.org/license.html. - - $Id: logwtmp.c,v 1.16 2000/07/01 18:17:39 wuftpd Exp $ - -****************************************************************************/ -#include "config.h" - -#include -#ifdef TIME_WITH_SYS_TIME -#include -#include -#else -#ifdef HAVE_SYS_TIME_H -#include -#else -#include -#endif -#endif -#include -#if defined(HAVE_FCNTL_H) -#include -#endif -#include -#ifdef SVR4 -#ifndef NO_UTMPX -#include -#ifndef _SCO_DS -#include -#endif -#endif -#endif -#ifdef BSD -#include -#else -#include -#endif -#ifdef HAVE_SYS_SYSLOG_H -#include -#endif -#if defined(HAVE_SYSLOG_H) || (!defined(AUTOCONF) && !defined(HAVE_SYS_SYSLOG_H)) -#include -#endif -#ifdef __FreeBSD__ -#include -#include -#include -#endif - -#include "pathnames.h" -#include "proto.h" - -#ifndef NO_UTMP -static int fd = -1; -#endif -#if defined(SVR4) && !defined(NO_UTMPX) -static int fdx = -1; -#endif - -/* Modified version of logwtmp that holds wtmp file open after first call, - * for use with ftp (which may chroot after login, but before logout). */ - -void wu_logwtmp(char *line, char *name, char *host, int login) -{ - struct stat buf; -#ifndef NO_UTMP - struct utmp ut; -#endif - -#if defined(SVR4) && !defined(NO_UTMPX) - /* - * Date: Tue, 09 Mar 1999 14:59:42 -0600 - * From: Chad Price - * To: wu-ftpd@wugate.wustl.edu - * Subject: Re: Problem w/ Solaris /var/adm/wtmpx and /usr/bin/last(1) - * - * I've been running Sol 2.4 since it came out, and the 'last' command - * has never worked correctly, for ftpd or logins either one. wtmpx - * often fails to close out sessions when the user logs out. As a - * result, I only use last to see who logged in, not who/when the - * logout occurred. - * - * When I first installed it, it was even worse, and they immediately - * told me to patch the system. This fixed it to semi-compus mentis, - * but not to working order. So I guess my conclusion is: ignore the - * wtmpx / last log stuff on Solaris 2.4 (and other releases of Solaris - * too from what I see in the comments), it's broken and always has - * been. I do of course stand ready to be corrected (in this case, - * pointed to a patch which really does fix it.) - * - */ - struct utmpx utx; - - if (fdx < 0 && (fdx = open(WTMPX_FILE, O_WRONLY | O_APPEND, 0)) < 0) { - syslog(LOG_ERR, "wtmpx %s %m", WTMPX_FILE); - return; - } - - if (fstat(fdx, &buf) == 0) { - memset((void *) &utx, '\0', sizeof(utx)); - (void) strncpy(utx.ut_user, name, sizeof(utx.ut_user)); - (void) strncpy(utx.ut_host, host, sizeof(utx.ut_host)); - (void) strncpy(utx.ut_id, "ftp", sizeof(utx.ut_id)); - (void) strncpy(utx.ut_line, line, sizeof(utx.ut_line)); - utx.ut_syslen = strlen(utx.ut_host) + 1; - utx.ut_pid = getpid(); - (void) time(&utx.ut_tv.tv_sec); - if (login /* name && *name */ ) { - utx.ut_type = USER_PROCESS; - } - else { - utx.ut_type = DEAD_PROCESS; - } - utx.ut_exit.e_termination = 0; - utx.ut_exit.e_exit = 0; - if (write(fdx, (char *) &utx, sizeof(struct utmpx)) != - sizeof(struct utmpx)) - (void) ftruncate(fdx, buf.st_size); - } -#endif /* defined(SVR4) && !defined(NO_UTMPX) */ - -#ifndef NO_UTMP -#ifdef __FreeBSD__ - if (strlen(host) > UT_HOSTSIZE) { - if ((host = inet_htop(host)) == NULL) - host = "invalid hostname"; - } -#endif - - if (fd < 0 && (fd = open(_PATH_WTMP, O_WRONLY | O_APPEND, 0)) < 0) { - syslog(LOG_ERR, "wtmp %s %m", _PATH_WTMP); - return; - } - if (fstat(fd, &buf) == 0) { -#ifdef UTMAXTYPE - memset((void *) &ut, 0, sizeof(ut)); -#ifdef LINUX - (void) strncpy(ut.ut_id, "", sizeof(ut.ut_id)); -#else - (void) strncpy(ut.ut_id, "ftp", sizeof(ut.ut_id)); -#endif - (void) strncpy(ut.ut_line, line, sizeof(ut.ut_line)); - ut.ut_pid = getpid(); - if (login /* name && *name */ ) { - (void) strncpy(ut.ut_user, name, sizeof(ut.ut_user)); - ut.ut_type = USER_PROCESS; - } - else - ut.ut_type = DEAD_PROCESS; -#if defined(HAVE_UT_UT_EXIT_E_TERMINATION) || (!defined(AUTOCONF) && !defined(LINUX)) - ut.ut_exit.e_termination = 0; - ut.ut_exit.e_exit = 0; -#endif -#else - (void) strncpy(ut.ut_line, line, sizeof(ut.ut_line)); - if (login) { - (void) strncpy(ut.ut_name, name, sizeof(ut.ut_name)); - } - else { - (void) strncpy(ut.ut_name, "", sizeof(ut.ut_name)); - } -#endif /* UTMAXTYPE */ -#ifdef HAVE_UT_UT_HOST /* does have host in utmp */ - if (login) { - (void) strncpy(ut.ut_host, host, sizeof(ut.ut_host)); - } - else { - (void) strncpy(ut.ut_host, "", sizeof(ut.ut_host)); - } -#endif - (void) time(&ut.ut_time); - if (write(fd, (char *) &ut, sizeof(struct utmp)) != - sizeof(struct utmp)) - (void) ftruncate(fd, buf.st_size); - } -#endif /* NO_UTMP */ -} diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/pathnames.h b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/pathnames.h deleted file mode 100644 index 344e26906f..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/pathnames.h +++ /dev/null @@ -1,152 +0,0 @@ -#pragma ident "%Z%%M% %I% %E% SMI" - -/**************************************************************************** - Copyright (c) 1999,2000 WU-FTPD Development Group. - All rights reserved. - - Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 - The Regents of the University of California. - Portions Copyright (c) 1993, 1994 Washington University in Saint Louis. - Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc. - Portions Copyright (c) 1989 Massachusetts Institute of Technology. - Portions Copyright (c) 1998 Sendmail, Inc. - Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman. - Portions Copyright (c) 1997 by Stan Barber. - Portions Copyright (c) 1997 by Kent Landfield. - Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 - Free Software Foundation, Inc. - - Use and distribution of this software and its source code are governed - by the terms and conditions of the WU-FTPD Software License ("LICENSE"). - - If you did not receive a copy of the license, it may be obtained online - at http://www.wu-ftpd.org/license.html. - - $Id: pathnames.h.in,v 1.5 2000/07/01 18:04:21 wuftpd Exp $ - -****************************************************************************/ - -#ifdef HAVE_PATHS_H -#include -#endif - -#ifdef SOLARIS_2 -#define UTMP_DIR "/var/adm" -#define WTMP_DIR "/var/adm" -#define LASTLOG_DIR "/var/adm" -#else -#define UTMP_DIR "/etc" -#define WTMP_DIR "/usr/adm" -#define LASTLOG_DIR "/usr/adm" -#endif - -#define _PATH_EXECPATH "/bin/ftp-exec" - -#ifdef VIRTUAL -/* - ** Virtual hosting requires to support many different types of customer. - ** needs. There must be complete support for the various ftpd system files - ** and their functionality. - ** - ** Supported on an individual virtual host basis: - ** ---------------------------------------------- - ** _PATH_FTPACCESS - ** _PATH_FTPUSERS - ** _PATH_PRIVATE - ** _PATH_FTPHOSTS - ** _PATH_CVT - ** - ** Set in a site's ftpaccess file - ** _PATH_XFERLOG - ** - ** Supported on a site-wide basis: - ** -------------------------------- - ** _PATH_FTPSERVERS - ** _PATH_EXECPATH - ** _PATH_PIDNAMES - ** _PATH_UTMP - ** _PATH_WTMP - ** _PATH_LASTLOG - ** _PATH_BSHELL - ** _PATH_DEVNULL - ** - ** Following are possibly overridden by VIRTUAL Hosting Configuation - ** Edit accordingly. - */ -#endif - -#undef _PATH_FTPUSERS -#undef _PATH_FTPACCESS -#undef _PATH_CVT -#undef _PATH_PRIVATE - -#define _PATH_FTPUSERS "/etc/ftpd/ftpusers" -#define _PATH_FTPACCESS "/etc/ftpd/ftpaccess" -#define _PATH_CVT "/etc/ftpd/ftpconversions" -#define _PATH_PRIVATE "/etc/ftpd/ftpgroups" - -#ifdef VIRTUAL -#undef _PATH_FTPSERVERS -#define _PATH_FTPSERVERS "/etc/ftpd/ftpservers" -#endif - -#ifdef HOST_ACCESS -#undef _PATH_FTPHOSTS -#define _PATH_FTPHOSTS "/etc/ftpd/ftphosts" -#endif - -/* _PATH_FTPD_PIDFILE is only used if DAEMON is defined */ - -#define _PATH_PIDNAMES "/var/run/ftp.pids-%s" -#define _PATH_FTPD_PID "/var/run/ftpd.pid" -#define _PATH_XFERLOG "/var/log/xferlog" - -#ifndef _PATH_UTMP -#ifdef UTMP_FILE -#define _PATH_UTMP UTMP_FILE -#endif -#endif - -#ifndef _PATH_WTMP -#ifdef WTMP_FILE -#define _PATH_WTMP WTMP_FILE -#endif -#endif - -#if defined(sun) && defined(SOLARIS_2) -#ifndef _PATH_UTMP -#define _PATH_UTMP UTMP_DIR"/utmp" -#endif -#ifndef _PATH_WTMP -#define _PATH_WTMP WTMP_DIR"/wtmp" -#endif -#ifndef _PATH_LASTLOG -#define _PATH_LASTLOG LASTLOG_DIR"/lastlog" -#endif -#else -#ifndef _PATH_UTMP -#define _PATH_UTMP "/etc/utmp" -#endif -#ifndef _PATH_WTMP -#define _PATH_WTMP "/usr/adm/wtmp" -#endif -#ifndef _PATH_LASTLOG -#define _PATH_LASTLOG "/usr/adm/lastlog" -#endif -#endif - -#ifndef _PATH_BSHELL -#define _PATH_BSHELL "/bin/sh" -#endif - -#ifndef _PATH_DEVNULL -#define _PATH_DEVNULL "/dev/null" -#endif - -#ifndef _PATHS_DEFINED_ -extern char _path_ftpaccess[]; -extern char _path_ftpusers[]; -extern char _path_ftphosts[]; -extern char _path_private[]; -extern char _path_cvt[]; -#endif diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/paths.c b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/paths.c deleted file mode 100644 index 3ea65f0d7d..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/paths.c +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/**************************************************************************** - Copyright (c) 1999,2000 WU-FTPD Development Group. - All rights reserved. - - Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 - The Regents of the University of California. - Portions Copyright (c) 1993, 1994 Washington University in Saint Louis. - Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc. - Portions Copyright (c) 1989 Massachusetts Institute of Technology. - Portions Copyright (c) 1998 Sendmail, Inc. - Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman. - Portions Copyright (c) 1997 by Stan Barber. - Portions Copyright (c) 1997 by Kent Landfield. - Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 - Free Software Foundation, Inc. - - Use and distribution of this software and its source code are governed - by the terms and conditions of the WU-FTPD Software License ("LICENSE"). - - If you did not receive a copy of the license, it may be obtained online - at http://www.wu-ftpd.org/license.html. - - $Id: paths.c,v 1.7 2000/07/01 18:17:39 wuftpd Exp $ - -****************************************************************************/ -/* - * paths.c - setting up the correct pathing to support files/directories - * - * INITAL AUTHOR - Kent Landfield - */ -#include "config.h" - -#include -#include -#include -#include -#include - -#include "pathnames.h" -#include "proto.h" - -#ifdef VIRTUAL - -#include -#include -#include -#include -#include -#include - -int virtual_mode = 0; -int virtual_ftpaccess = 0; - -extern int debug; -extern char virtual_hostname[]; -extern char virtual_address[]; - -#endif - -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 64 -#endif - -/* - ** Pathing storage - */ - -#define _PATHS_DEFINED_ 1 -char _path_ftpaccess[MAXPATHLEN]; -char _path_ftpusers[MAXPATHLEN]; -char _path_ftphosts[MAXPATHLEN]; -char _path_private[MAXPATHLEN]; -char _path_cvt[MAXPATHLEN]; - -extern char logfile[]; -extern char hostname[]; - -void setup_paths(void); - -/* - ** Virtual hosting has to support many different types of needs. There - ** must be complete support for the various ftpd system files and their - ** functionality. - ** - ** Full support on a virtual host basis: - ** ------------------------------------- - ** _PATH_FTPACCESS - ** _PATH_FTPUSERS - ** _PATH_PRIVATE - ** _PATH_FTPHOSTS - ** _PATH_CVT - ** - ** Set in a site's ftpaccess file - ** _PATH_XFERLOG - ** - ** Supported on a site basis: - ** -------------------------- - ** _PATH_FTPSERVERS - ** _PATH_EXECPATH - ** _PATH_PIDNAMES - ** _PATH_UTMP - ** _PATH_WTMP - ** _PATH_LASTLOG - ** _PATH_BSHELL - ** _PATH_DEVNULL - */ - -/* ------------------------------------------------------------------------ */ -/* FUNCTION : setup_paths */ -/* PURPOSE : Determine appropriate paths to various configuration files. */ -/* ARGUMENTS : None */ -/* RETURNS : None */ -/* ------------------------------------------------------------------------ */ - -void setup_paths(void) -{ -#ifdef VIRTUAL - char *sp; - char configdir[MAXPATHLEN]; - char filepath[MAXPATHLEN]; -#ifdef INET6 - char hostaddress[INET6_ADDRSTRLEN]; -#else - char hostaddress[32]; -#endif - FILE *svrfp; - struct stat st; -#if defined(UNIXWARE) || defined(AIX) - size_t virtual_len; -#else - int virtual_len; -#endif - struct SOCKSTORAGE virtual_addr; -#endif - - (void) strlcpy(_path_ftpaccess, _PATH_FTPACCESS, sizeof(_path_ftpaccess)); - (void) strlcpy(_path_ftpusers, _PATH_FTPUSERS, sizeof(_path_ftpusers)); - (void) strlcpy(_path_private, _PATH_PRIVATE, sizeof(_path_private)); - (void) strlcpy(_path_cvt, _PATH_CVT, sizeof(_path_cvt)); - (void) strlcpy(logfile, _PATH_XFERLOG, MAXPATHLEN); - (void) strlcpy(_path_ftphosts, _PATH_FTPHOSTS, sizeof(_path_ftphosts)); - -#ifdef VIRTUAL - /* - ** Open PATH_FTPSERVERS config file. If the file does not - ** exist then revert to using the standard _PATH_* path defines. - */ - - if ((svrfp = fopen(_PATH_FTPSERVERS, "r")) != NULL) { - /* - ** OK. The ftpservers file exists and is open. - ** - ** Format of the file is: - ** ipaddr/hostname directory-containing-configuration-files - ** - ** 208.196.145.10 /etc/ftpd/ftpaccess.somedomain/ - ** 208.196.145.200 /etc/ftpd/ftpaccess.someotherdomain/ - ** some.domain INTERNAL - ** - ** Parse the file and try to match the IP address to one found - ** in the file. If a match is found then return the path to - ** the specified directory that contains the configuration files - ** for that specific domain. If a match is not found, or an invalid - ** directory path is encountered like above, return standard paths. - ** - ** As usual, comments and blanklines are ignored. - */ - - /* get our address */ - - virtual_len = sizeof(virtual_addr); - if (getsockname(0, (struct sockaddr *) &virtual_addr, &virtual_len) == 0) { - while (read_servers_line(svrfp, hostaddress, sizeof(hostaddress), - configdir, sizeof(configdir)) == 1) { - if (!strcmp(hostaddress, inet_stop(&virtual_addr))) { - if (debug) - syslog(LOG_DEBUG, "VirtualFTP Connect to: %s", hostaddress); - (void) strlcpy(virtual_address, hostaddress, - MAXHOSTNAMELEN); - if (hostname != NULL) { - /* reset hostname to this virtual name */ - wu_gethostbyaddr(&virtual_addr, hostname, MAXHOSTNAMELEN); - (void) strlcpy(virtual_hostname, hostname, - MAXHOSTNAMELEN); - } - - /* get rid of trailing slash */ - sp = configdir + (strlen(configdir) - 1); - if (*sp == '/') - *sp = '\0'; - - /* - ** check to see that a valid directory value was - ** supplied and not something such as "INTERNAL" - */ - - if ((stat(configdir, &st) == 0) && - ((st.st_mode & S_IFMT) == S_IFDIR)) { - - (void) snprintf(filepath, sizeof(filepath), - "%s/ftpaccess", configdir); - if (access(filepath, R_OK) == 0) { - (void) strlcpy(_path_ftpaccess, filepath, - sizeof(_path_ftpaccess)); - virtual_mode = 1; - virtual_ftpaccess = 1; - } - - (void) snprintf(filepath, sizeof(filepath), - "%s/ftpusers", configdir); - if (access(filepath, R_OK) == 0) - (void) strlcpy(_path_ftpusers, filepath, - sizeof(_path_ftpusers)); - - (void) snprintf(filepath, sizeof(filepath), - "%s/ftpgroups", configdir); - if (access(filepath, R_OK) == 0) - (void) strlcpy(_path_private, filepath, - sizeof(_path_private)); - - (void) snprintf(filepath, sizeof(filepath), - "%s/ftphosts", configdir); - if (access(filepath, R_OK) == 0) - (void) strlcpy(_path_ftphosts, filepath, - sizeof(_path_ftphosts)); - - (void) snprintf(filepath, sizeof(filepath), - "%s/ftpconversions", configdir); - if (access(filepath, R_OK) == 0) - (void) strlcpy(_path_cvt, filepath, - sizeof(_path_cvt)); - } - (void) fclose(svrfp); - return; - } - } - } - (void) fclose(svrfp); - } -#endif /* VIRTUAL */ - - return; -} diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/popen.c b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/popen.c deleted file mode 100644 index 44e37bba11..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/popen.c +++ /dev/null @@ -1,324 +0,0 @@ -/* - * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -/**************************************************************************** - Copyright (c) 1999,2000 WU-FTPD Development Group. - All rights reserved. - - Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 - The Regents of the University of California. - Portions Copyright (c) 1993, 1994 Washington University in Saint Louis. - Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc. - Portions Copyright (c) 1989 Massachusetts Institute of Technology. - Portions Copyright (c) 1998 Sendmail, Inc. - Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman. - Portions Copyright (c) 1997 by Stan Barber. - Portions Copyright (c) 1997 by Kent Landfield. - Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 - Free Software Foundation, Inc. - - Use and distribution of this software and its source code are governed - by the terms and conditions of the WU-FTPD Software License ("LICENSE"). - - If you did not receive a copy of the license, it may be obtained online - at http://www.wu-ftpd.org/license.html. - - $Id: popen.c,v 1.16 2000/07/01 18:17:39 wuftpd Exp $ - -****************************************************************************/ -#include "config.h" - -#include -#include -#include -#include -#include -#include -#if defined(HAVE_FCNTL_H) -#include -#endif -#include "pathnames.h" -#include "proto.h" - -/* - * Special version of popen which avoids call to shell. This insures noone - * may create a pipe to a hidden program as a side effect of a list or dir - * command. - */ -static int popen_fd = -1; -static pid_t popen_pid = -1; -/* - * The globbed argv could end up being huge, so we must dynamically allocate - * it. Allocate it in chunks of GARGV_INC pointers. - */ -#define GARGV_INC 100 -#define ARGV_INC 5 - -static char **argv; -static char **gargv; -static int argv_size; -static int gargv_size; - -FILE *ftpd_popen(char *program, char *type, int closestderr) -{ - register char *cp; - FILE *iop = NULL; - int argc, gargc, pdes[2], i, devnullfd; - char **pop, *vv[2]; - extern char *globerr; - - /* - * ftpd never needs more than one pipe open at a time, so only one PID is - * stored (in popen_pid). Protect against multiple pipes in case this - * changes. - */ - if (popen_fd != -1) - return (NULL); - - if ((*type != 'r' && *type != 'w') || type[1]) - return (NULL); - - if (gargv == NULL) { - gargv = (char **)malloc(GARGV_INC * sizeof (char *)); - if (gargv == NULL) { - return (NULL); - } - gargv_size = GARGV_INC; - } - - if (argv == NULL) { - argv = (char **)malloc(ARGV_INC * sizeof (char *)); - if (argv == NULL) { - return (NULL); - } - argv_size = ARGV_INC; - } - - if (pipe(pdes) < 0) - return (NULL); - - /* empty the array */ - (void) memset((void *) argv, 0, argv_size * sizeof(char *)); - /* break up string into pieces */ - for (argc = 0, cp = program; ;cp = NULL) { - if (!(argv[argc++] = strtok(cp, " \t\n"))) { - break; - } - if (argc >= argv_size) { - char **tmp; - - tmp = (char **)realloc(argv, - (argv_size + ARGV_INC) * sizeof (char *)); - if (tmp == NULL) { - (void) close(pdes[0]); - (void) close(pdes[1]); - return (NULL); - } else { - argv = tmp; - argv_size += ARGV_INC; - } - } - } - - /* glob each piece */ - gargv[0] = argv[0]; - for (gargc = argc = 1; argv[argc]; argc++) { - if (!(pop = ftpglob(argv[argc], B_TRUE)) || globerr != NULL) { /* globbing failed */ - if (pop) { - blkfree(pop); - free((char *) pop); - } - vv[0] = strspl(argv[argc], ""); - vv[1] = NULL; - pop = copyblk(vv); - } - argv[argc] = (char *) pop; /* save to free later */ - while (*pop) { - gargv[gargc++] = *pop++; - if (gargc >= gargv_size) { - char **tmp; - - tmp = (char **)realloc(gargv, - (gargv_size + GARGV_INC) * sizeof (char *)); - if (tmp == NULL) { - (void) close(pdes[0]); - (void) close(pdes[1]); - goto pfree; - } else { - gargv = tmp; - gargv_size += GARGV_INC; - } - } - } - } - gargv[gargc] = NULL; - -#ifdef SIGCHLD - (void) signal(SIGCHLD, SIG_DFL); -#endif - switch (popen_pid = vfork()) { - case -1: /* error */ - (void) close(pdes[0]); - (void) close(pdes[1]); - goto pfree; - /* NOTREACHED */ - case 0: /* child */ - if (*type == 'r') { - if (pdes[1] != 1) { - dup2(pdes[1], 1); - if (closestderr) { - (void) close(2); - /* stderr output is written to fd 2, so make sure it isn't - * available to be assigned to another file */ - if ((devnullfd = open(_PATH_DEVNULL, O_RDWR)) != -1) { - if (devnullfd != 2) { - dup2(devnullfd, 2); - (void) close(devnullfd); - } - } - } - else - dup2(pdes[1], 2); /* stderr, too! */ - (void) close(pdes[1]); - } - (void) close(pdes[0]); - } - else { - if (pdes[0] != 0) { - dup2(pdes[0], 0); - (void) close(pdes[0]); - } - (void) close(pdes[1]); - } - closefds(3); - /* begin CERT suggested fixes */ - close(0); - i = geteuid(); - setid_priv_on(0); - setgid(getegid()); - setuid(i); - setid_priv_off(i); - /* end CERT suggested fixes */ - execv(gargv[0], gargv); - perror(gargv[0]); - _exit(1); - } - /* parent; assume fdopen can't fail... */ - if (*type == 'r') { - iop = fdopen(pdes[0], type); - (void) close(pdes[1]); - } - else { - iop = fdopen(pdes[1], type); - (void) close(pdes[0]); - } - popen_fd = fileno(iop); - - pfree:for (argc = 1; argv[argc]; argc++) { - blkfree((char **) argv[argc]); - free((char *) argv[argc]); - } - return (iop); -} - -int ftpd_pclose(FILE *iop) -{ - pid_t pid; -#if defined(HAVE_SIGPROCMASK) || (defined(SVR4) && !defined(AUTOCONF)) - sigset_t sig, omask; - int stat_loc; - sigemptyset(&sig); - sigaddset(&sig, SIGINT); - sigaddset(&sig, SIGQUIT); - sigaddset(&sig, SIGHUP); -#elif defined (_OSF_SOURCE) - int omask; - int status; -#else - int omask; - union wait stat_loc; -#endif - - /* pclose returns -1 if stream is not associated with a `popened' - * command, or, if already `pclosed'. */ - if ((popen_fd == -1) || (popen_fd != fileno(iop))) - return (-1); - (void) fclose(iop); -#if defined(HAVE_SIGPROCMASK) || (!defined(AUTOCONF) && defined(SVR4)) - sigprocmask(SIG_BLOCK, &sig, &omask); -#else - omask = sigblock(sigmask(SIGINT) | sigmask(SIGQUIT) | sigmask(SIGHUP)); -#endif - -#if (!defined(HAVE_SIGPROCMASK) || (!defined(SVR4) && !defined(AUTOCONF))) && defined (_OSF_SOURCE) - while ((pid = wait(&status)) != popen_pid && pid != -1); -#elif ! defined(NeXT) - while ((pid = wait((int *) &stat_loc)) != popen_pid && pid != -1); -#else - while ((pid = wait(&stat_loc)) != popen_pid && pid != -1); -#endif - popen_pid = -1; - popen_fd = -1; -#ifdef SIGCHLD - (void) signal(SIGCHLD, SIG_IGN); -#endif -#if defined(HAVE_SIGPROCMASK) || (defined(SVR4) && !defined(AUTOCONF)) - sigprocmask(SIG_SETMASK, &omask, (sigset_t *) NULL); - return (pid == -1 ? -1 : WEXITSTATUS(stat_loc)); -#else - (void) sigsetmask(omask); -#ifdef _OSF_SOURCE - return (pid == -1 ? -1 : status); -#elif defined(LINUX) - return (pid == -1 ? -1 : WEXITSTATUS(stat_loc)); -#else - return (pid == -1 ? -1 : stat_loc.w_status); -#endif -#endif -} - -#ifdef CLOSEFROM -void closefds(int startfd) -{ - closefrom(startfd); -} -#else - -#ifdef HAVE_GETRLIMIT -#include -#endif - -void closefds(int startfd) -{ - int i, fds; -#ifdef HAVE_GETRLIMIT - struct rlimit rlp; -#endif - -#ifdef OPEN_MAX - fds = OPEN_MAX; -#else - fds = 31; -#endif - -#ifdef HAVE_GETRLIMIT - if ((getrlimit(RLIMIT_NOFILE, &rlp) == 0) && - (rlp.rlim_cur != RLIM_INFINITY)) { - fds = rlp.rlim_cur; - } -#else -#ifdef HAVE_GETDTABLESIZE - if ((i = getdtablesize()) > 0) - fds = i; -#else -#ifdef HAVE_SYSCONF - fds = sysconf(_SC_OPEN_MAX); -#endif /* HAVE_SYSCONF */ -#endif /* HAVE_GETDTABLESIZE */ -#endif /* HAVE_GETRLIMIT */ - - for (i = startfd; i < fds; i++) - close(i); -} -#endif /* CLOSEFROM */ diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/private.c b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/private.c deleted file mode 100644 index 58a782537b..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/private.c +++ /dev/null @@ -1,335 +0,0 @@ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/**************************************************************************** - Copyright (c) 1999,2000 WU-FTPD Development Group. - All rights reserved. - - Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 - The Regents of the University of California. - Portions Copyright (c) 1993, 1994 Washington University in Saint Louis. - Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc. - Portions Copyright (c) 1989 Massachusetts Institute of Technology. - Portions Copyright (c) 1998 Sendmail, Inc. - Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman. - Portions Copyright (c) 1997 by Stan Barber. - Portions Copyright (c) 1997 by Kent Landfield. - Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 - Free Software Foundation, Inc. - - Use and distribution of this software and its source code are governed - by the terms and conditions of the WU-FTPD Software License ("LICENSE"). - - If you did not receive a copy of the license, it may be obtained online - at http://www.wu-ftpd.org/license.html. - - $Id: private.c,v 1.12 2000/07/01 18:17:39 wuftpd Exp $ - -****************************************************************************/ -#include "config.h" - -#ifndef NO_PRIVATE - -#include -#include - -extern char *strsep(char **, const char *); - -#include -#ifdef HAVE_SYS_SYSLOG_H -#include -#endif -#if defined(HAVE_SYSLOG_H) || (!defined(AUTOCONF) && !defined(HAVE_SYS_SYSLOG_H)) -#include -#endif -#include - -#include -#include -#include - -#ifdef HAVE_PATHS_H -#include -#endif -#include "pathnames.h" -#include "extensions.h" -#include "proto.h" - -#ifdef SECUREOSF -#define SecureWare /* Does this mean it works for all SecureWare? */ -#endif - -#ifdef HPUX_10_TRUSTED -#include -#endif - -#if defined(SecureWare) || defined(HPUX_10_TRUSTED) -#include -#endif - -#ifndef NO_CRYPT_PROTO -extern char *crypt(const char *, const char *); -#endif - -static int group_attempts, group_given; -static char *groupname, *passbuf; - -struct acgrp { - char *gname; /* access group name */ - char *gpass; /* access group password */ - gid_t gr_gid; /* group to setegid() to */ - struct acgrp *next; -}; - -static struct acgrp *privptr, *privtail; - -extern int lgi_failure_threshold; -extern char remoteident[]; - -static void add_acgrp(char *gname, char *gpass, gid_t gid) -{ - struct acgrp *aptr; - - aptr = (struct acgrp *) calloc(1, sizeof(struct acgrp)); - if (aptr == NULL) { - syslog(LOG_ERR, "calloc error in add_acgrp"); - dologout(1); - } - - /* add element to end of list */ - if (privtail) - privtail->next = aptr; - privtail = aptr; - if (!privptr) - privptr = aptr; - - aptr->gname = strdup(gname); - if (aptr->gname == NULL) { - syslog(LOG_ERR, "malloc error in add_acgrp"); - dologout(1); - } - if (gpass == NULL) - aptr->gpass = strdup(""); - else - aptr->gpass = strdup(gpass); - if (aptr->gpass == NULL) { - syslog(LOG_ERR, "malloc error in add_acgrp"); - dologout(1); - } - aptr->gr_gid = gid; -} - -static void parsepriv(void) -{ - char *ptr; - char *acptr = passbuf, *line; - char *argv[3], *p, *val; - struct group *gr; - int n; - - if (!passbuf || !(*passbuf)) - return; - - /* read through passbuf, stripping comments. */ - while (*acptr != '\0') { - line = acptr; - while (*acptr && *acptr != '\n') - acptr++; - *acptr++ = '\0'; - - /* deal with comments */ - if ((ptr = strchr(line, '#')) != NULL) - *ptr = '\0'; - - if (*line == '\0') - continue; - - /* parse the lines... */ - for (n = 0, p = line; n < 3 && p != NULL; n++) { - val = (char *) strsep(&p, ":\n"); - argv[n] = val; - if ((argv[n][0] == ' ') || (argv[n][0] == '\0')) - argv[n] = NULL; - } - /* check their were 3 fields, if not skip the line... */ - if (n != 3 || p != NULL) - continue; - - if (argv[0] && argv[2]) { - if (argv[2][0] == '%') { - gid_t gid = atoi(argv[2] + 1); - if ((gr = getgrgid(gid)) != NULL) - add_acgrp(argv[0], argv[1], gid); - } - else { - if ((gr = getgrnam((char *) argv[2])) != NULL) - add_acgrp(argv[0], argv[1], gr->gr_gid); - } - endgrent(); - } - } -} - -/*************************************************************************/ -/* FUNCTION : priv_setup */ -/* PURPOSE : Set things up to use the private access password file. */ -/* ARGUMENTS : path, the path to the private access password file */ -/*************************************************************************/ - -void priv_setup(char *path) -{ - FILE *prvfile; - struct stat finfo; - struct acgrp *aptr; - - while (privptr) { - aptr = privptr->next; - free(privptr->gname); - free(privptr->gpass); - free(privptr); - privptr = aptr; - } - privtail = NULL; - - if (passbuf) { - free(passbuf); - passbuf = NULL; - } - - if ((prvfile = fopen(path, "r")) == NULL) { - if (errno != ENOENT) - syslog(LOG_ERR, "cannot open private access file %s: %s", - path, strerror(errno)); - return; - } - if (fstat(fileno(prvfile), &finfo) != 0) { - syslog(LOG_ERR, "cannot fstat private access file %s: %s", path, - strerror(errno)); - (void) fclose(prvfile); - return; - } - if (finfo.st_size == 0) { - passbuf = (char *) calloc(1, 1); - } - else { - if (!(passbuf = (char *) malloc((size_t) finfo.st_size + 1))) { - (void) syslog(LOG_ERR, "could not malloc passbuf (%d bytes)", - (size_t) finfo.st_size + 1); - (void) fclose(prvfile); - return; - } - if (!fread(passbuf, (size_t) finfo.st_size, 1, prvfile)) { - (void) syslog(LOG_ERR, "error reading private access file %s: %s", - path, strerror(errno)); - (void) fclose(prvfile); - return; - } - *(passbuf + finfo.st_size) = '\0'; - } - (void) fclose(prvfile); - (void) parsepriv(); -} - -/*************************************************************************/ -/* FUNCTION : priv_getent */ -/* PURPOSE : Retrieve an entry from the in-memory copy of the group */ -/* access file. */ -/* ARGUMENTS : pointer to group name */ -/*************************************************************************/ - -static struct acgrp *priv_getent(char *group) -{ - struct acgrp *ptr; - - for (ptr = privptr; ptr; ptr = ptr->next) - if (!strcasecmp(group, ptr->gname)) - return (ptr); - - return (NULL); -} - -/*************************************************************************/ -/* FUNCTION : priv_group */ -/* PURPOSE : */ -/* ARGUMENTS : */ -/*************************************************************************/ - -void priv_group(char *group) -{ - if (groupname) - free(groupname); - - groupname = strdup(group); - if (groupname == NULL) { - reply(421, "Local resource failure: malloc"); - syslog(LOG_ERR, "malloc error in priv_group"); - dologout(1); - } - group_given = 1; - reply(200, "Request for access to group %s accepted.", group); -} - -/*************************************************************************/ -/* FUNCTION : priv_gpass */ -/* PURPOSE : validate the group access request, and if OK place user */ -/* in the proper group. */ -/* ARGUMENTS : group access password */ -/*************************************************************************/ - -void priv_gpass(char *gpass) -{ - char *xgpass = NULL; - struct acgrp *grp; - uid_t uid; - - if (group_given == 0) { - reply(503, "Give group name with SITE GROUP first."); - return; - } - /* OK, now they're getting a chance to specify a password. Make them - * give the group name again if they fail... */ - group_given = 0; - - grp = priv_getent(groupname); - if (passbuf && gpass && *gpass != '\0' && grp && *grp->gpass != '\0') -#if defined(SecureWare) || defined(HPUX_10_TRUSTED) - xgpass = bigcrypt(gpass, grp->gpass); -#else - xgpass = crypt(gpass, grp->gpass); -#endif - - if (!(((gpass != NULL) - && (*gpass != '\0') - && (grp != NULL) - && (*grp->gpass != '\0') - && (strcmp(xgpass, grp->gpass) == 0)) - || (((gpass == NULL) - || (*gpass == '\0')) - && (grp != NULL) - && (*grp->gpass == '\0')) - )) { - reply(530, "Group access request incorrect."); - grp = NULL; - if (++group_attempts >= lgi_failure_threshold) { - syslog(LOG_NOTICE, - "repeated group access failures from %s, group %s", - remoteident, groupname); - dologout(0); - } - sleep(group_attempts); /* slow down password crackers */ - return; - } - - uid = geteuid(); - setid_priv_on(0); - setegid(grp->gr_gid); - setid_priv_off(uid); - - reply(200, "Group access enabled."); - group_attempts = 0; -} -#endif /* !NO_PRIVATE */ diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/privatepw.c b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/privatepw.c deleted file mode 100644 index cd574ace35..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/privatepw.c +++ /dev/null @@ -1,392 +0,0 @@ -#pragma ident "%Z%%M% %I% %E% SMI" - -/**************************************************************************** - - Copyright (c) 1999,2000 WU-FTPD Development Group. - All rights reserved. - - Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 - The Regents of the University of California. Portions Copyright (c) - 1993, 1994 Washington University in Saint Louis. Portions Copyright - (c) 1996, 1998 Berkeley Software Design, Inc. Portions Copyright (c) - 1998 Sendmail, Inc. Portions Copyright (c) 1983, 1995, 1996, 1997 Eric - P. Allman. Portions Copyright (c) 1989 Massachusetts Institute of - Technology. Portions Copyright (c) 1997 by Stan Barber. Portions - Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997 Free Software - Foundation, Inc. Portions Copyright (c) 1997 by Kent Landfield. - - Use and distribution of this software and its source code are governed - by the terms and conditions of the WU-FTPD Software License ("LICENSE"). - - $Id: privatepw.c,v 1.10 2000/07/01 18:43:59 wuftpd Exp $ - -****************************************************************************/ -/* - Subsystem: WU-FTPD FTP Server - Purpose: Change WU-FTPD Guest Passwords - File Name: privatepw.c - - usage: privatepw [-c] [-f passwordfile] [-g group] accessgroup - privatepw [-d] [-f passwordfile] accessgroup - privatepw [-l] [-f passwordfile] - -c: creates a new file. - -d: deletes specified accessgroup. - -l: list contents of ftpgroups file. - -f ftpgroups: updates the specified file. - -g group: set real group to the specified group. - - This software was initially written by Kent Landfield (kent@landfield.com) - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "config.h" -#include "pathnames.h" - -#define BUFLEN 256 -#define GROUPLEN 8 - -char *tmp; -char line[BUFLEN]; -FILE *fp; -int verbose = 0; - -static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */ -"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - -void print_copyright(void); - -static void usage(void) -{ - fprintf(stderr, "usage: privatepw [-c] [-f ftpgroups] [-g group] accessgroup\n"); - fprintf(stderr, " privatepw [-d] [-f ftpgroups] accessgroup\n"); - fprintf(stderr, " privatepw [-l] [-f ftpgroups]\n"); - fprintf(stderr, "\t\t-c: creates a new file.\n"); - fprintf(stderr, "\t\t-d: deletes specified accessgroup.\n"); - fprintf(stderr, "\t\t-l: list contents of ftpgroups file.\n"); - fprintf(stderr, "\t\t-f ftpgroups: updates the specified file.\n"); - fprintf(stderr, "\t\t-g group: set real group to the specified group.\n"); - exit(1); -} - -static void to64(register char *s, register long v, register int n) -{ - while (--n >= 0) { - *s++ = itoa64[v & 0x3f]; - v >>= 6; - } -} - -static void terminate(void) -{ - if (tmp) - unlink(tmp); - exit(1); -} - -static void catchintr(void) -{ - fprintf(stderr, "Interrupted.\n"); - terminate(); -} - -static char *savit(char *s) -{ - char *d; - - if ((d = (char *) malloc(strlen(s) + 1)) == NULL) { - fprintf(stderr, "Whoa... Malloc failed.\n"); - terminate(); - } - strcpy(d, s); - return (d); -} - -static int confirmed(char *accessgroup) -{ - register int ch; - - printf("Delete %s: Are your sure ? (y/n) ", accessgroup); - ch = getc(stdin); - if (ch == 'y') - return (1); - return (0); -} - -static char *getgroup(char *msg) -{ - register int ch; - register char *p; - static char buf[GROUPLEN + 1]; - - fputs(msg, stderr); - rewind(stderr); /* implied flush */ - for (p = buf; (ch = getc(stdin)) != EOF && ch != '\n';) - if (p < buf + GROUPLEN) - *p++ = ch; - *p = '\0'; - - if (getgrnam(buf) == NULL) { - fprintf(stderr, "Invalid group \'%s\' specified\n", buf); - terminate(); - } - return (buf); -} - -static void addrecord(char *accessgroup, char *sysgroup, char *msg, FILE *f) -{ - char *pw, *cpw, salt[3]; -#ifndef NO_CRYPT_PROTO - extern char *crypt(const char *, const char *); -#endif - char *getpass(const char *prompt); - - printf("%s %s\n", msg, accessgroup); - - if (sysgroup[0] == '\0') - strcpy(sysgroup, getgroup("Real System Group to use: ")); - - pw = savit((char *) getpass("New password: ")); - if (strcmp(pw, (char *) getpass("Re-type new password: "))) { - fprintf(stderr, "They don't match, sorry.\n"); - if (tmp) - unlink(tmp); - exit(1); - } - - srand((int) time((time_t *) NULL)); - to64(&salt[0], rand(), 2); - cpw = crypt(pw, salt); - free(pw); - fprintf(f, "%s:%s:%s\n", accessgroup, cpw, sysgroup); -} - -static void list_privatefile(char *privatefile) -{ - if (verbose) - fprintf(stderr, "Private File: %s file.\n", privatefile); - - if ((fp = fopen(privatefile, "r")) == NULL) { - fprintf(stderr, "Could not open %s file.\n", privatefile); - exit(1); - } - - printf("\nWU-FTPD Private file: %s\n", privatefile); - printf("accessgroup : password : system group\n"); - printf("-------\n"); - - while (fgets(line, BUFLEN, fp) != NULL) - fputs(line, stdout); - printf("-------\n"); -} - -int main(int argc, char **argv) -{ - extern void (*signal(int sig, void (*disp) (int))) (int); - extern int getopt(int argc, char *const *argv, const char *optstring); - extern char *optarg; - extern int optind; - extern int opterr; - - struct stat stbuf; - - char realgroup[BUFLEN]; - char *passwdpath; - char *cp; - - char accessgroup[BUFLEN]; - char w[BUFLEN]; - char command[BUFLEN]; - - int create; - int delete; - int list; - int found; - int lineno; - int c; - - FILE *tfp; - -#ifdef HAVE_MKSTEMP - char tmpname[BUFLEN]; - int tfd; -#endif - - opterr = 0; - create = 0; - delete = 0; - list = 0; - - tmp = NULL; - realgroup[0] = '\0'; - - passwdpath = _PATH_PRIVATE; - - if (argc == 1) - usage(); - - while ((c = getopt(argc, argv, "Vvcdf:g:l")) != EOF) { - switch (c) { - case 'd': - delete++; - break; - case 'c': - create++; - break; - case 'f': - passwdpath = optarg; - break; - case 'g': - strcpy(realgroup, optarg); - if (getgrnam(realgroup) == NULL) { - fprintf(stderr, "Invalid group \'%s\' specified\n", realgroup); - return (1); - } - break; - case 'l': - list++; - break; - case 'v': - verbose++; - break; - case 'V': - print_copyright(); - return (0); - /* NOTREACHED */ - default: - usage(); - } - } - - if (list) { - list_privatefile(passwdpath); - return (0); - } - - if (optind >= argc) { - fprintf(stderr, "Need to specify an accessgroup name.\n"); - usage(); - } - - signal(SIGINT, (void (*)()) catchintr); - - strcpy(accessgroup, argv[optind]); - - if (create) { - if (stat(passwdpath, &stbuf) == 0) { - fprintf(stderr, "%s exists, cannot create it.\n", passwdpath); - fprintf(stderr, "Remove -c option or use the -f option to specify another.\n"); - return (1); - } - - if ((tfp = fopen(passwdpath, "w")) == NULL) { - fprintf(stderr, "Could not open \"%s\" for writing.\n", passwdpath); - perror("fopen"); - return (1); - } - - tmp = passwdpath; - - printf("Creating WU-FTPD Private file: %s\n", passwdpath); - addrecord(accessgroup, realgroup, "Adding accessgroup", tfp); - - fclose(tfp); - return (0); - } - -#ifdef HAVE_MKSTEMP - strcpy (tmpname, "/tmp/privatepwXXXXXX"); - tmp = tmpname; - if ((tfd = mkstemp(tmp)) < 0) { - fprintf(stderr, "Could not open temp file.\n"); - return (1); - } - - if ((tfp = fdopen(tfd, "w")) == NULL) { - unlink(tmp); - fprintf(stderr, "Could not open temp file.\n"); - return (1); - } -#else - tmp = tmpnam(NULL); - - if ((tfp = fopen(tmp, "w")) == NULL) { - fprintf(stderr, "Could not open temp file.\n"); - return (1); - } -#endif - - if ((fp = fopen(passwdpath, "r")) == NULL) { - fprintf(stderr, "Could not open %s file.\n", passwdpath); - fprintf(stderr, "Use -c option to create new one.\n"); - return (1); - } - - lineno = 0; - found = 0; - - while (fgets(line, BUFLEN, fp) != NULL) { - lineno++; - - if (found || (line[0] == '#') || (!line[0])) { - fputs(line, tfp); - continue; - } - - strcpy(w, line); - - if ((cp = strchr(w, ':')) == NULL) { - fprintf(stderr, "%s: line %d: invalid record format.\n", passwdpath, lineno); - continue; - } - *cp++ = '\0'; - - if ((cp = strchr(cp, ':')) == NULL) { - fprintf(stderr, "%s: line %d: invalid record format.\n", passwdpath, lineno); - continue; - } - *cp++ = '\0'; - - if (strcmp(accessgroup, w)) { - fputs(line, tfp); - continue; - } - else { - if (delete) { - if (!confirmed(accessgroup)) - terminate(); - } - else { - if (realgroup[0] == '\0') { - strcpy(realgroup, cp); - if ((cp = strchr(realgroup, '\n')) != NULL) - *cp = '\0'; - } - addrecord(accessgroup, realgroup, "Updating accessgroup", tfp); - } - found = 1; - } - } - - if (!found && !delete) - addrecord(accessgroup, realgroup, "Adding accessgroup", tfp); - else if (!found && delete) { - fprintf(stderr, "%s not found in %s.\n", accessgroup, passwdpath); - terminate(); - } - - fclose(fp); - fclose(tfp); - - sprintf(command, "cp %s %s", tmp, passwdpath); - system(command); - unlink(tmp); - return (0); -} diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/privs.c b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/privs.c deleted file mode 100644 index 912f27624f..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/privs.c +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright 2009 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* - * Least privilege support functions. - */ - -#include "config.h" - -#ifdef SOLARIS_PRIVS -#include -#ifdef HAVE_SYS_SYSLOG_H -#include -#endif -#if defined(HAVE_SYSLOG_H) || (!defined(AUTOCONF) && !defined(HAVE_SYS_SYSLOG_H)) -#include -#endif -#endif /* SOLARIS_PRIVS */ - -#include "proto.h" - -#ifdef SOLARIS_PRIVS -/* When ununitialized, this indicates we still have all privs */ -static priv_set_t *uprivs; -#endif /* SOLARIS_PRIVS */ - -#ifdef SOLARIS_PRIVS -#ifdef PRIVS_DEBUG -static void print_privs(priv_ptype_t which, const char *str) -{ - priv_set_t *privset; - char *privstr; - - if ((privset = priv_allocset()) == NULL) - return; - - (void) getppriv(which, privset); - privstr = priv_set_to_str(privset, ',', PRIV_STR_SHORT); - syslog(LOG_DEBUG, "%s: %s", str, privstr); - free(privstr); - priv_freeset(privset); -} -#endif /* PRIVS_DEBUG */ - -static void priv_on(const char *priv) -{ - /* no need to add the privilege if already have it */ - if (uprivs == NULL || priv_ismember(uprivs, priv)) - return; - - if (priv_set(PRIV_ON, PRIV_EFFECTIVE, priv, NULL) == -1) - syslog(LOG_ERR, "priv_set: error adding privilege %s: %m", priv); -} - -static void priv_off(const char *priv) -{ - /* don't remove the privilege if already had it */ - if (uprivs == NULL || priv_ismember(uprivs, priv)) - return; - - if (priv_set(PRIV_OFF, PRIV_EFFECTIVE, priv, NULL) == -1) - syslog(LOG_ERR, "priv_set: error removing privilege %s: %m", priv); -} -#endif /* SOLARIS_PRIVS */ - -/* - * init_privs() is called after a user has logged in to drop from the - * permitted privilege set those privileges which are no longer required. - */ -/*ARGSUSED*/ -void init_privs(const char *username) -{ -#ifdef SOLARIS_PRIVS - uid_t euid = geteuid(); - priv_set_t *pset1, *pset2; - - /* - * The FTP server runs with the inheritable set and the limit set - * filled in through user_attr (or with default values of basic and all). - * The privileges available to the user at login, is an intersection - * of both those sets. The only way to limit the root user is by - * changing the limit set, not by changing the I set. - */ - if ((pset1 = priv_allocset()) == NULL || - (uprivs = priv_allocset()) == NULL || - (pset2 = priv_allocset()) == NULL) { - syslog(LOG_ERR, "priv_allocset failed: %m"); - dologout(1); - } - if (getppriv(PRIV_LIMIT, pset1) == -1) { - syslog(LOG_ERR, "getppriv(limit) failed: %m"); - dologout(1); - } - if (getppriv(euid == 0 ? PRIV_PERMITTED : PRIV_INHERITABLE, pset2) == -1) { - syslog(LOG_ERR, "getppriv() failed: %m"); - dologout(1); - } - - /* Compute the permitted set after login. */ - priv_intersect(pset2, pset1); - - /* - * Set the permitted privilege set to the allowable privileges plus - * those required after init_privs() is called. Keep note of which - * effective privileges we already had in uprivs so we don't turn - * them off. - */ - priv_emptyset(pset2); - (void) priv_addset(pset2, PRIV_PROC_SETID); - (void) priv_addset(pset2, PRIV_NET_PRIVADDR); - (void) priv_addset(pset2, PRIV_FILE_DAC_READ); - (void) priv_addset(pset2, PRIV_FILE_DAC_SEARCH); - (void) priv_addset(pset2, PRIV_FILE_CHOWN); - - priv_copyset(pset2, uprivs); - priv_intersect(pset1, uprivs); - - /* Now, set the effective privileges. */ - if (setppriv(PRIV_SET, PRIV_EFFECTIVE, pset1) == -1) { - syslog(LOG_ERR, - "unable to set privileges for %s: setppriv(effective): %m", - username); - dologout(1); - } - -#if defined(SOLARIS_BSM_AUDIT) && !defined(SOLARIS_NO_AUDIT_FTPD_LOGOUT) - /* needed for audit_ftpd_logout() */ - (void) priv_addset(pset1, PRIV_PROC_AUDIT); -#endif - /* And set the permitted, adding ftpd's required privileges in the mix. */ - priv_union(pset2, pset1); - if (setppriv(PRIV_SET, PRIV_PERMITTED, pset1) == -1) { - syslog(LOG_ERR, - "unable to set privileges for %s: setppriv(permitted): %m", - username); - dologout(1); - } - /* - * setppriv() has made us privilege aware, so the effective privileges - * are no longer modified by user ID changes. - */ - priv_freeset(pset1); - priv_freeset(pset2); - - /* set the real, effective and saved group ID's */ - setid_priv_on(0); - if (setgid(getegid()) != 0) { - syslog(LOG_ERR, "setgid(%d) failed: %m", getegid()); - setid_priv_off(euid); - dologout(1); - } - /* - * Set the real and effective user ID's, leaving the saved user ID set - * to 0 so seteuid(0) succeeds. - */ - (void) seteuid(0); - if (setreuid(euid, -1) != 0) { - syslog(LOG_ERR, "setreuid(%d, -1) failed: %m", euid); - setid_priv_off(euid); - dologout(1); - } - setid_priv_off(euid); - if (seteuid(euid) != 0) { - syslog(LOG_ERR, "seteuid(%d) failed: %m", euid); - dologout(1); - } - -#ifdef PRIVS_DEBUG - print_privs(PRIV_EFFECTIVE, "effective privilege set"); - print_privs(PRIV_PERMITTED, "permitted privilege set"); - print_privs(PRIV_INHERITABLE, "inheritable privilege set"); - print_privs(PRIV_LIMIT, "limit privilege set"); -#endif /* PRIVS_DEBUG */ -#endif /* SOLARIS_PRIVS */ -} - -/* allow a process to bind to a privileged port */ -/*ARGSUSED*/ -void port_priv_on(uid_t uid) -{ - delay_signaling(); -#ifdef SOLARIS_PRIVS - priv_on(PRIV_NET_PRIVADDR); -#else - (void) seteuid(uid); -#endif -} - -/*ARGSUSED*/ -void port_priv_off(uid_t uid) -{ -#ifdef SOLARIS_PRIVS - priv_off(PRIV_NET_PRIVADDR); -#else - (void) seteuid(uid); -#endif - enable_signaling(); -} - -/* allow a process to read any file or directory and to search any directory */ -void access_priv_on(uid_t uid) -{ - delay_signaling(); -#ifdef SOLARIS_PRIVS - priv_on(PRIV_FILE_DAC_READ); - priv_on(PRIV_FILE_DAC_SEARCH); -#endif - /* necessary on Solaris for access over NFS */ - (void) seteuid(uid); -} - -void access_priv_off(uid_t uid) -{ -#ifdef SOLARIS_PRIVS - priv_off(PRIV_FILE_DAC_READ); - priv_off(PRIV_FILE_DAC_SEARCH); -#endif - (void) seteuid(uid); - enable_signaling(); -} - -/* allow a process to set its user IDs and group IDs */ -/*ARGSUSED*/ -void setid_priv_on(uid_t uid) -{ - delay_signaling(); -#ifdef SOLARIS_PRIVS - priv_on(PRIV_PROC_SETID); -#else - (void) seteuid(uid); -#endif -} - -/*ARGSUSED*/ -void setid_priv_off(uid_t uid) -{ -#ifdef SOLARIS_PRIVS - priv_off(PRIV_PROC_SETID); -#else - (void) seteuid(uid); -#endif - enable_signaling(); -} - -/* allow a process to change the ownership of files and directories */ -void chown_priv_on(uid_t uid) -{ - delay_signaling(); -#ifdef SOLARIS_PRIVS - priv_on(PRIV_FILE_CHOWN); -#endif - /* necessary on Solaris for chown over NFS */ - (void) seteuid(uid); -} - -void chown_priv_off(uid_t uid) -{ -#ifdef SOLARIS_PRIVS - priv_off(PRIV_FILE_CHOWN); -#endif - (void) seteuid(uid); - enable_signaling(); -} diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/proto.h b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/proto.h deleted file mode 100644 index 5730d2120e..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/proto.h +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved. - */ - -/**************************************************************************** - Copyright (c) 1999,2000 WU-FTPD Development Group. - All rights reserved. - - Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 - The Regents of the University of California. - Portions Copyright (c) 1993, 1994 Washington University in Saint Louis. - Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc. - Portions Copyright (c) 1989 Massachusetts Institute of Technology. - Portions Copyright (c) 1998 Sendmail, Inc. - Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman. - Portions Copyright (c) 1997 by Stan Barber. - Portions Copyright (c) 1997 by Kent Landfield. - Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 - Free Software Foundation, Inc. - - Use and distribution of this software and its source code are governed - by the terms and conditions of the WU-FTPD Software License ("LICENSE"). - - If you did not receive a copy of the license, it may be obtained online - at http://www.wu-ftpd.org/license.html. - - $Id: proto.h,v 1.10 2000/07/01 18:17:39 wuftpd Exp $ - -****************************************************************************/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - ** access.c - */ -int parsetime(char *); -int validtime(char *); -int hostmatch(char *, char *, char *); -int acl_guestgroup(struct passwd *); -int acl_realgroup(struct passwd *); -void acl_autogroup(struct passwd *); -void acl_setfunctions(void); -int acl_getclass(char *); -int acl_getlimit(char *, char *); -int acl_getnice(char *); -void acl_getdefumask(char *); -void acl_tcpwindow(char *); -void acl_filelimit(char *); -void acl_datalimit(char *); -int acl_deny(char *); -int acl_countusers(char *); -int acl_join(char *, int); -void acl_remove(void); -void pr_mesg(int, char *); -void access_init(void); -int access_ok(int); - -/* - ** acl.c - */ -struct aclmember *getaclentry(char *, struct aclmember **); -void parseacl(void); -int readacl(char *); - -/* - ** auth.c - */ -#ifdef BSD_AUTH -char *start_auth(char *, char *, struct passwd *); -#endif -char *check_auth(char *, char *); - -/* - ** authenticate.c - */ -int wu_authenticate(void); - -/* - ** conversions.c - */ -void conv_init(void); - -/* - ** domain.c - */ -int check_rhost_reverse(void); -int check_rhost_matches(void); -int rhostlookup(char *); -void set_res_options(void); - -/* - ** extensions.c - */ -#ifdef SITE_NEWER -int check_newer(const char *, const struct stat *, int); -void newer(char *date, char *path, int showlots); -#endif -long getSize(char *); -void msg_massage(const char *, char *, size_t); -int cwd_beenhere(int); -void show_banner(int); -void show_message(int, int); -void show_readme(int, int); -int deny_badasciixfer(int, char *); -int is_shutdown(int, int); -int type_match(char *typelist); -int path_compare(char *p1, char *p2); -void expand_id(void); -int fn_check(char *name); -int dir_check(char *name, uid_t * uid, gid_t * gid, int *d_mode, int *valid); -int upl_check(char *name, uid_t * uid, gid_t * gid, int *f_mode, int *valid); -int del_check(char *name); -int regexmatch(char *name, char *rgexp); -int checknoretrieve(char *name); -int path_to_device(char *pathname, char *result); -void get_quota(char *fs, int uid); -char *time_quota(long curstate, long softlimit, long timelimit, char *timeleft); -void fmttime(char *buf, register long time); -int file_compare(char *patterns, char *file); -int remote_compare(char *patterns); -void throughput_calc(char *name, int *bps, double *bpsmult); -void throughput_adjust(char *name); -void SetCheckMethod(const char *method); -void ShowCheckMethod(void); -void CheckSum(char *pathname); -void CheckSumLastFile(void); - -/* - ** ftpcmd.c - */ -char *wu_getline(char *s, int n, register FILE *iop); -int yyparse(void); -void upper(char *s); -char *copy(char *s); -void sizecmd(char *filename); -void site_exec(char *cmd); -void alias(char *s); -void cdpath(void); -void print_groups(void); - -/* - ** ftpd.c - */ - -SIGNAL_TYPE randomsig(int sig); -SIGNAL_TYPE lostconn(int sig); -char *mapping_getwd(char *path); -void do_elem(char *dir); -int mapping_chdir(char *orig_path); -char *sgetsave(char *s); -struct passwd *sgetpwnam(char *name); -char *skey_challenge(char *name, struct passwd *pwd, int pwok); -void user(char *name); -int checkuser(char *name); -int uid_match(char *keyword, uid_t uid); -int gid_match(char *keyword, gid_t gid, char *username); -int denieduid(uid_t uid); -int alloweduid(uid_t uid); -int deniedgid(gid_t gid); -int allowedgid(gid_t gid); -void end_login(void); -int validate_eaddr(char *eaddr); -void pass(char *passwd); -int restricteduid(uid_t uid); -int unrestricteduid(uid_t uid); -int restrictedgid(gid_t gid); -int unrestrictedgid(gid_t gid); -char *opt_string(int options); -void retrieve(char *cmd, char *name); -void store(char *name, char *mode, int unique); -FILE *getdatasock(char *mode); -FILE *dataconn(char *name, off_t size, char *mode); -#ifdef THROUGHPUT -int send_data(char *name, FILE *instr, FILE *outstr, size_t blksize); -#else -int send_data(FILE *instr, FILE *outstr, size_t blksize); -#endif -int receive_data(FILE *instr, FILE *outstr); -void statfilecmd(char *filename); -void statcmd(void); -void fatal(char *s); -void vreply(long flags, int n, char *fmt, va_list ap); -void reply(int, char *fmt,...); -void lreply(int, char *fmt,...); -void ack(char *s); -void nack(char *s); -void yyerror(char *s); -void delete(char *name); -void cwd(char *path); -void makedir(char *name); -void removedir(char *name); -void pwd(void); -char *renamefrom(char *name); -void renamecmd(char *from, char *to); -void dologout(int status); -SIGNAL_TYPE myoob(int sig); -void passive(int passive_mode, int proto); -char *gunique(char *local); -void perror_reply(int code, char *string); -void send_file_list(char *whichfiles); -void initsetproctitle(int argc, char **argv, char **envp); -void setproctitle(const char *fmt,...); -void init_krb(void); -void end_krb(void); - -#ifdef INTERNAL_LS -char *rpad(char *s, unsigned int len); -char *ls_file(const char *file, int nameonly, char remove_path, char classify); -void ls_dir(char *d, char ls_a, char ls_F, char ls_l, char ls_R, char omit_total, FILE *out); -void ls(char *file, char nlst); -#endif - -void fixpath(char *path); - -/* - ** glob.c - */ -void blkfree(char **); -char **ftpglob(register char *, boolean_t check_ncargs); -char *strspl(register char *, register char *); -char **copyblk(register char **); - -/* - ** hostacc.c - */ -int rhost_ok(char *pcRuser, char *pcRhost, char *pcRaddr); - -/* - ** loadavg.c - */ -/* - ** logwtmp.c - */ -void wu_logwtmp(char *line, char *name, char *host, int login); - -/* - ** paths.c - */ -void setup_paths(void); - -/* - ** popen.c - */ -FILE *ftpd_popen(char *program, char *type, int closestderr); -int ftpd_pclose(FILE *iop); -void closefds(int startfd); - -/* - ** private.c - */ -#ifndef NO_PRIVATE -void priv_setup(char *path); -void priv_group(char *group); -void priv_gpass(char *gpass); -#endif - -/* - ** rdservers.c - */ -#ifdef VIRTUAL -int read_servers_line(FILE *, char *, size_t, char *, size_t); -#endif - -/* - ** realpath.c - */ -char *fb_realpath(const char *path, char *resolved); -char *wu_realpath(const char *path, char *resolved_path, char *chroot_path); - -/* - ** restrict.c - */ -int restrict_check(char *name); -int test_restriction(char *name); -int restrict_list_check(char *name); - -/* - ** routevector.c - */ -int routevector(void); - -/* - ** timeout.c - */ -void load_timeouts(void); - -/* - ** inet.c - */ -char *inet_htop(const char *hostname); -char *inet_stop(struct SOCKSTORAGE *ss); -char *wu_gethostbyname(const char *hostname); -int wu_gethostbyaddr(struct SOCKSTORAGE *ss, char *hostname, int hostlen); -int sock_cmp_inaddr(struct SOCKSTORAGE *ss, struct in_addr addr); -#ifdef INET6 -void sock_set_inaddr(struct SOCKSTORAGE *ss, struct in_addr addr); -int sock_cmp_addr(struct SOCKSTORAGE *ss1, struct SOCKSTORAGE *ss2); -void sock_set_scope(struct SOCKSTORAGE *dst, struct SOCKSTORAGE *src); -int inet_pton6(char *str, struct in6_addr *addr); -const char *inet_ntop_native(int af, const void *addr, char *dst, size_t size); -#endif - -/* - ** xferlog.c - */ -void get_xferlog_format(void); - -/* - ** privs.c - */ -void init_privs(const char *); -void port_priv_on(uid_t); -void port_priv_off(uid_t); -void access_priv_on(uid_t); -void access_priv_off(uid_t); -void setid_priv_on(uid_t); -void setid_priv_off(uid_t); -void chown_priv_on(uid_t); -void chown_priv_off(uid_t); - -/* - ** support/getusershell.c - */ -char *getusershell(void); -void endusershell(void); diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/rdservers.c b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/rdservers.c deleted file mode 100644 index f5be3caeda..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/rdservers.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/**************************************************************************** - Copyright (c) 1999,2000 WU-FTPD Development Group. - All rights reserved. - - Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 - The Regents of the University of California. - Portions Copyright (c) 1993, 1994 Washington University in Saint Louis. - Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc. - Portions Copyright (c) 1989 Massachusetts Institute of Technology. - Portions Copyright (c) 1998 Sendmail, Inc. - Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman. - Portions Copyright (c) 1997 by Stan Barber. - Portions Copyright (c) 1997 by Kent Landfield. - Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 - Free Software Foundation, Inc. - - Use and distribution of this software and its source code are governed - by the terms and conditions of the WU-FTPD Software License ("LICENSE"). - - If you did not receive a copy of the license, it may be obtained online - at http://www.wu-ftpd.org/license.html. - - $Id: rdservers.c,v 1.4 2000/07/01 18:17:39 wuftpd Exp $ - -****************************************************************************/ -/* - * rdservers - read ftpservers file - * - * INITIAL AUTHOR - Kent Landfield - */ - -#include "config.h" - -#ifdef VIRTUAL - -#include -#include -#include -#include "proto.h" - -int read_servers_line(FILE *svrfp, char *hostaddress, size_t hsize, - char *accesspath, size_t asize) -{ - static char buffer[BUFSIZ]; - - char *hcp, *acp; - char *bcp, *ecp; - char *ap; - - while (fgets(buffer, BUFSIZ, svrfp) != NULL) { - - /* Find first non-whitespace character */ - for (bcp = buffer; ((*bcp == '\t') || (*bcp == ' ')); bcp++); - - /* Get rid of comments */ - if ((ecp = strchr(buffer, '#')) != NULL) - *ecp = '\0'; - - /* Skip empty lines */ - if ((bcp == ecp) || (*bcp == '\n')) - continue; - - /* separate parts */ - - hcp = bcp; - for (acp = hcp; - (*acp && !isspace(*acp)); acp++); - - /* better have something in access path or skip the line */ - if (!*acp) - continue; - - *acp++ = '\0'; - - while (*acp && isspace(*acp)) - acp++; - - /* again better have something in access path or skip the line */ - if (!*acp) - continue; - - ecp = acp; - - while (*ecp && (!isspace(*ecp)) && *ecp != '\n') - ++ecp; - - *ecp = '\0'; - - if ((ap = inet_htop(hcp)) != NULL) - (void) strlcpy(hostaddress, ap, hsize); - else - (void) strlcpy(hostaddress, hcp, hsize); - - (void) strlcpy(accesspath, acp, asize); - - return (1); - } - return (0); -} -#endif diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/realpath.c b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/realpath.c deleted file mode 100644 index b961f2e474..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/realpath.c +++ /dev/null @@ -1,361 +0,0 @@ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/**************************************************************************** - Copyright (c) 1999,2000 WU-FTPD Development Group. - All rights reserved. - - Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 - The Regents of the University of California. - Portions Copyright (c) 1993, 1994 Washington University in Saint Louis. - Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc. - Portions Copyright (c) 1989 Massachusetts Institute of Technology. - Portions Copyright (c) 1998 Sendmail, Inc. - Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman. - Portions Copyright (c) 1997 by Stan Barber. - Portions Copyright (c) 1997 by Kent Landfield. - Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 - Free Software Foundation, Inc. - - Use and distribution of this software and its source code are governed - by the terms and conditions of the WU-FTPD Software License ("LICENSE"). - - If you did not receive a copy of the license, it may be obtained online - at http://www.wu-ftpd.org/license.html. - - $Id: realpath.c,v 1.11 2000/07/01 18:17:39 wuftpd Exp $ - -****************************************************************************/ -/* Originally taken from FreeBSD 3.0's libc; adapted to handle chroot - * directories in BeroFTPD by Bernhard Rosenkraenzer - * - * - * Added super-user permissions so we can determine the real pathname even - * if the user cannot access the file. - */ -#include "config.h" - -#include -#include - -#include -#if defined(HAVE_FCNTL_H) -#include -#endif -#include -#include -#include -#include "proto.h" - -#ifndef MAXSYMLINKS /* Workaround for Linux libc 4.x/5.x */ -#define MAXSYMLINKS 5 -#endif - -#ifndef HAVE_LSTAT -#define lstat stat -#endif - -char *wu_realpath(const char *path, char resolved_path[MAXPATHLEN], char *chroot_path) -{ - char *ptr; - char q[MAXPATHLEN]; - - fb_realpath(path, q); - - if (chroot_path == NULL) - strcpy(resolved_path, q); - else { - strcpy(resolved_path, chroot_path); - if (q[0] != '/') { - if (strlen(resolved_path) + strlen(q) < MAXPATHLEN) - strcat(resolved_path, q); - else /* Avoid buffer overruns... */ - return NULL; - } - else if (q[1] != '\0') { - for (ptr = q; *ptr != '\0'; ptr++); - if (ptr == resolved_path || *--ptr != '/') { - if (strlen(resolved_path) + strlen(q) < MAXPATHLEN) - strcat(resolved_path, q); - else /* Avoid buffer overruns... */ - return NULL; - } - else { - if (strlen(resolved_path) + strlen(q) - 1 < MAXPATHLEN) - strcat(resolved_path, &q[1]); - else /* Avoid buffer overruns... */ - return NULL; - } - } - } - return resolved_path; -} - -/* - * char *fb_realpath(const char *path, char resolved_path[MAXPATHLEN]); - * - * Find the real name of path, by removing all ".", ".." and symlink - * components. Returns (resolved) on success, or (NULL) on failure, - * in which case the path which caused trouble is left in (resolved). - */ -char *fb_realpath(const char *path, char *resolved) -{ - struct stat sb; - int fd, n, rootd, serrno; - char *p, *q, wbuf[MAXPATHLEN]; - int symlinks = 0; - int resultcode; -#ifdef HAS_NO_FCHDIR -/* AIX Has no fchdir() so we hope the getcwd() call doesn't overrun the buffer! */ - char cwd[MAXPATHLEN + 1]; - char *pcwd; -#endif - - /* Save the starting point. */ - errno = 0; -#ifdef HAS_NO_FCHDIR -#ifdef HAVE_GETCWD - pcwd = getcwd(cwd, sizeof(cwd)); -#else - pcwd = getwd(cwd); -#endif -#else - fd = open(".", O_RDONLY); -#endif - if (EACCES == errno) { - uid_t userid = geteuid(); - access_priv_on(0); -#ifdef HAS_NO_FCHDIR -#ifdef HAVE_GETCWD - pcwd = getcwd(cwd, sizeof(cwd)); -#else - pcwd = getwd(cwd); -#endif -#else - fd = open(".", O_RDONLY); -#endif - access_priv_off(userid); - } -#ifdef HAS_NO_FCHDIR - if (pcwd == NULL) -#else - if (fd < 0) -#endif - { - (void) strcpy(resolved, "."); - return (NULL); - } - - /* - * Find the dirname and basename from the path to be resolved. - * Change directory to the dirname component. - * lstat the basename part. - * if it is a symlink, read in the value and loop. - * if it is a directory, then change to that directory. - * get the current directory name and append the basename. - */ - (void) strncpy(resolved, path, MAXPATHLEN - 1); - resolved[MAXPATHLEN - 1] = '\0'; - loop: - q = strrchr(resolved, '/'); - if (q != NULL) { - p = q + 1; - if (q == resolved) - q = "/"; - else { - do { - --q; - } while (q > resolved && *q == '/'); - q[1] = '\0'; - q = resolved; - } - errno = 0; - resultcode = chdir(q); - if (EACCES == errno) { - uid_t userid = geteuid(); - access_priv_on(0); - errno = 0; - resultcode = chdir(q); - access_priv_off(userid); - } - if (resultcode < 0) - goto err1; - } - else - p = resolved; - - /* Deal with the last component. */ - if (*p != '\0') { - errno = 0; - resultcode = lstat(p, &sb); - if (EACCES == errno) { - uid_t userid = geteuid(); - access_priv_on(0); - errno = 0; - resultcode = lstat(p, &sb); - access_priv_off(userid); - } - if (resultcode == 0) { -#ifdef HAVE_LSTAT - if (S_ISLNK(sb.st_mode)) { - if (++symlinks > MAXSYMLINKS) { - errno = ELOOP; - goto err1; - } - errno = 0; - { - size_t len = strlen(p); - char *tmp = calloc(len + 1, sizeof(char)); - if (tmp == 0) { - serrno = errno; - goto err1; - } - strcpy(tmp, p); - p = tmp; - } - n = readlink(p, resolved, MAXPATHLEN); - if (EACCES == errno) { - uid_t userid = geteuid(); - access_priv_on(0); - errno = 0; - n = readlink(p, resolved, MAXPATHLEN); - access_priv_off(userid); - } - if (n < 0) { - free(p); - goto err1; - } - free(p); - /* n should be less than MAXPATHLEN, but check to be safe */ - if (n >= MAXPATHLEN) - n = MAXPATHLEN - 1; - resolved[n] = '\0'; - goto loop; - } -#endif /* HAVE_LSTAT */ - if (S_ISDIR(sb.st_mode)) { - errno = 0; - resultcode = chdir(p); - if (EACCES == errno) { - uid_t userid = geteuid(); - access_priv_on(0); - errno = 0; - resultcode = chdir(p); - access_priv_off(userid); - } - if (resultcode < 0) - goto err1; - p = ""; - } - } - } - - /* - * Save the last component name and get the full pathname of - * the current directory. - */ - (void) strcpy(wbuf, p); - errno = 0; -#ifdef HAVE_GETCWD - resultcode = getcwd(resolved, MAXPATHLEN) == NULL ? 0 : 1; -#else - resultcode = getwd(resolved) == NULL ? 0 : 1; - if (resolved[MAXPATHLEN - 1] != '\0') { - resultcode = 0; - errno = ERANGE; - } -#endif - if (EACCES == errno) { - uid_t userid = geteuid(); - access_priv_on(0); - errno = 0; -#ifdef HAVE_GETCWD - resultcode = getcwd(resolved, MAXPATHLEN) == NULL ? 0 : 1; -#else - resultcode = getwd(resolved) == NULL ? 0 : 1; - if (resolved[MAXPATHLEN - 1] != '\0') { - resultcode = 0; - errno = ERANGE; - } -#endif - access_priv_off(userid); - } - if (resultcode == 0) - goto err1; - - /* - * Join the two strings together, ensuring that the right thing - * happens if the last component is empty, or the dirname is root. - */ - if (resolved[0] == '/' && resolved[1] == '\0') - rootd = 1; - else - rootd = 0; - - if (*wbuf) { - if (strlen(resolved) + strlen(wbuf) + !rootd + 1 > MAXPATHLEN) { - errno = ENAMETOOLONG; - goto err1; - } - if (rootd == 0) - (void) strcat(resolved, "/"); - (void) strcat(resolved, wbuf); - } - - /* Go back to where we came from. */ - errno = 0; -#ifdef HAS_NO_FCHDIR - resultcode = chdir(cwd); -#else - resultcode = fchdir(fd); -#endif - if (EACCES == errno) { - uid_t userid = geteuid(); - access_priv_on(0); - errno = 0; -#ifdef HAS_NO_FCHDIR - resultcode = chdir(cwd); -#else - resultcode = fchdir(fd); -#endif - access_priv_off(userid); - } - if (resultcode < 0) { - serrno = errno; - goto err2; - } - -#ifndef HAS_NO_FCHDIR - /* It's okay if the close fails, what's an fd more or less? */ - (void) close(fd); -#endif - return (resolved); - - err1:serrno = errno; -#ifdef HAS_NO_FCHDIR - (void) chdir(cwd); -#else - (void) fchdir(fd); -#endif - if (EACCES == errno) { - uid_t userid = geteuid(); - access_priv_on(0); -#ifdef HAS_NO_FCHDIR - (void) chdir(cwd); -#else - (void) fchdir(fd); -#endif - access_priv_off(userid); - } -#ifdef HAS_NO_FCHDIR - err2:errno = serrno; -#else - err2:(void) close(fd); - errno = serrno; -#endif - return (NULL); -} diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/restrict.c b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/restrict.c deleted file mode 100644 index 7142ef8e9d..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/restrict.c +++ /dev/null @@ -1,191 +0,0 @@ -#pragma ident "%Z%%M% %I% %E% SMI" - -/**************************************************************************** - Copyright (c) 1999,2000 WU-FTPD Development Group. - All rights reserved. - - Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 - The Regents of the University of California. - Portions Copyright (c) 1993, 1994 Washington University in Saint Louis. - Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc. - Portions Copyright (c) 1989 Massachusetts Institute of Technology. - Portions Copyright (c) 1998 Sendmail, Inc. - Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman. - Portions Copyright (c) 1997 by Stan Barber. - Portions Copyright (c) 1997 by Kent Landfield. - Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 - Free Software Foundation, Inc. - - Use and distribution of this software and its source code are governed - by the terms and conditions of the WU-FTPD Software License ("LICENSE"). - - If you did not receive a copy of the license, it may be obtained online - at http://www.wu-ftpd.org/license.html. - - $Id: restrict.c,v 1.14 2000/07/01 18:17:39 wuftpd Exp $ - -****************************************************************************/ -/* - * Contributed by Glenn Nielsen - * Mon, 18 Jan 1999 20:04:07 -0600 - */ -#include "config.h" - -#include -#include -#include -#include -#include "proto.h" - -#ifdef HAVE_GETCWD -extern char *getcwd(char *, size_t); -#else -extern char *getwd(char *); -#endif - -#ifndef TRUE -#define TRUE 1 -#define FALSE 0 -#endif - -extern char *home; -extern int restricted_user; - -/* - * name is the function parameter - * home is a global string containing the user's home directory - * - * rhome is the resolved home directory - * rname is the resolved requested filename - * curwd is the current working directory - * path is name, possibly prepended by the current working directory - */ - -int restrict_check(char *name) -{ - if (!test_restriction(name)) - return 0; - reply(550, "Permission denied on server. You are restricted to your account."); - return 1; -} - -int test_restriction(char *name) -{ - char rhome[MAXPATHLEN + 1], rname[MAXPATHLEN + 1], path[MAXPATHLEN + 1]; - - /* we're not in restrict mode so all access is OK */ - if (restricted_user == FALSE) - return 0; - - /* get resolved equivalent of user's home directory */ - fb_realpath(home, rhome); - - path[0] = '\0'; - - /* a relative path is specified, so resolve it w.r.t. current working directory */ - if ((name)[0] != '/') { - - char curwd[MAXPATHLEN + 1]; - - /* determine current working directory */ -#ifdef HAVE_GETCWD - if (getcwd(curwd, MAXPATHLEN) == (char *) NULL) { -#else - if (getwd(curwd) == (char *) NULL) { -#endif - return 1; - } /* if */ - - strcpy(path, curwd); - strcat(path, "/"); - - } /* if */ - - if ((strlen(path) + strlen(name) + 2) > sizeof(path)) { - return 1; - } - - strcat(path, name); - fb_realpath(path, rname); - strcat(rname, "/"); - - if (strncmp(rhome, rname, strlen(rhome))) { - return 1; - } /* if */ - - return 0; -} /* restrict_check */ - -int restrict_list_check(char *name) -{ - char *beg, *copy, *end; - int flag; - - beg = name; - - while (*beg != '\0') { - - flag = 0; - end = beg; - while (*end && !isspace(*end)) - ++end; - if (!*end) - flag = 1; - if (!flag) - *end = '\0'; - copy = strdup(beg); - if (!flag) - *end = ' '; - - if (!copy) { - reply(550, "Permission denied on server. Out of memory."); - return 1; - - } /* if */ - - if (restrict_check(copy)) { - free(copy); - return 1; - } - free(copy); - beg = end; - if (!flag) - ++beg; - - } /* while */ - - return 0; - -} /* restrict_list_check */ - -/* - * $Log: restrict.c,v $ - * Revision 1.14 2000/07/01 18:17:39 wuftpd - * - * Updated copyright statement for the WU-FTPD Development Group. - * - * Revision 1.13 1999/10/08 03:42:12 wuftpd - * Fixed a bug in restrict_check which could allow access outside the users home - * - * Revision 1.12 1999/09/05 02:31:50 wuftpd - * Add virtual and defaultserver support for email notification - * - * Revision 1.11 1999/09/02 19:35:48 wuftpd - * CDUP was leaking information about restrictions. - * - * Revision 1.10 1999/09/02 14:04:29 wuftpd - * Cleaning up. Indented and removed some STDC checks - * - * Revision 1.9 1999/08/24 23:41:39 wuftpd - * wu-ftpd-2.4.x RCS Ids removed and new Ids added for wu-ftpd.org usage. - * WU-FTPD Development Group copyright headers added. - * Original Copyright headers moved into the COPYRIGHT file. - * COPYPRIGHT.c added to build for ftpshut and ftpd. - * - * Revision 1.2 1996/02/20 04:54:04 root - * added #define to make gcc use HAVE_GETCWD - * - * Revision 1.1 1996/02/20 03:52:48 root - * Initial revision - * - */ diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/routevector.c b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/routevector.c deleted file mode 100644 index c0c7fc38f2..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/routevector.c +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright 2001-2003 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/**************************************************************************** - Copyright (c) 1999,2000 WU-FTPD Development Group. - All rights reserved. - - Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 - The Regents of the University of California. - Portions Copyright (c) 1993, 1994 Washington University in Saint Louis. - Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc. - Portions Copyright (c) 1989 Massachusetts Institute of Technology. - Portions Copyright (c) 1998 Sendmail, Inc. - Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman. - Portions Copyright (c) 1997 by Stan Barber. - Portions Copyright (c) 1997 by Kent Landfield. - Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 - Free Software Foundation, Inc. - - Use and distribution of this software and its source code are governed - by the terms and conditions of the WU-FTPD Software License ("LICENSE"). - - If you did not receive a copy of the license, it may be obtained online - at http://www.wu-ftpd.org/license.html. - - $Id: routevector.c,v 1.13 2000/07/01 18:17:39 wuftpd Exp $ - -****************************************************************************/ -/* - * Parse the entire ftpaccess file looking for: - * - * passive address
- * passive ports
- * - * vect_addr, passive_port_min and passive_port_max store the external IP - * address, min and max ports found whose associated address is the most - * specific match of the address the client connected from. - * - * The optional CIDR denotes the number of significant bits in the address, - * the higher the CIDR the more specific the address. If no CIDR is specified, - * the whole address is significant. - * - * When a passive data connection is requested the server listens on a port - * randomly selected between passive_port_min and passive_port_max - * (inclusive), if vect_addr is set its address is reported (if not the - * local address of the control connection is reported). Note this does not - * change the address the server actually listens on, only the address - * reported to the client. - * - * For example if the ftpaccess file includes: - * passive address 194.80.17.14 0.0.0.0/0 - * passive address 10.0.1.15 10.0.0.0/8 - * - * Clients connecting from the class-A network 10 will be told the passive - * connection is listening on IP address 10.0.1.15, while clients connecting - * from all other addresses will be told the connection is listening on - * 194.80.17.14 (a CIDR of /0 matches all addresses of the same address - * family, if IPv6 support is enabled then IPv4 and IPv6 addresses are - * supported). - */ - -#include "config.h" -#include -#include -#include -#include -#ifdef HAVE_SYS_SYSLOG_H -#include -#endif -#if defined(HAVE_SYSLOG_H) || (!defined(AUTOCONF) && !defined(HAVE_SYS_SYSLOG_H)) -#include -#endif -#include "extensions.h" -#include "proto.h" - -extern struct SOCKSTORAGE his_addr; -extern struct SOCKSTORAGE vect_addr; /* best matching external IP address */ -extern int passive_port_min; -extern int passive_port_max; - -/* significance of the external IP address and port entries */ -static int vect_sig = -1; -static int port_sig = -1; - -#ifdef INET6 -static int his_addr_family = AF_INET; -static int his_v4mapped = 0; -#endif - -/* - * Compares the address the client connected from (in his_addr) with the - * supplied address, with the specified number of bits being significant - * in the comparison. Returns 0 if the addresses match, non-zero otherwise. - */ -static int addr_cmp(void *addr, int sig) -{ - uint32_t addr32[4], rem32[4]; - int bitstozero, i, start = 0, len = sizeof(uint32_t); - char *ptr; - -#ifdef INET6 - if (his_addr_family == AF_INET) { - if (his_v4mapped) { - ptr = (char *)&((struct sockaddr_in6 *)&his_addr)->sin6_addr; - /* move to the IPv4 part of an IPv4-mapped IPv6 address */ - ptr += 12; - } - else -#endif - ptr = (char *)&((struct sockaddr_in *)&his_addr)->sin_addr; - - /* IPv4 addresses are 32-bits long */ - bitstozero = 32 - sig; - memcpy(addr32, addr, sizeof(uint32_t)); - memcpy(rem32, ptr, sizeof(uint32_t)); -#ifdef INET6 - } - else { - /* IPv6 addresses are 128-bits long */ - bitstozero = 128 - sig; - start = 3; - len = sizeof(addr32); - memcpy(addr32, addr, sizeof(addr32)); - memcpy(rem32, &((struct sockaddr_in6 *)&his_addr)->sin6_addr, sizeof(rem32)); - } -#endif - - /* zero bits starting with the least significant */ - for (i = start; (bitstozero > 0) && (i >= 0); i--, bitstozero -= 32) { - if (bitstozero >= 32) - addr32[i] = rem32[i] = 0; - else { - addr32[i] = (ntohl(addr32[i]) >> bitstozero) << bitstozero; - rem32[i] = (ntohl(rem32[i]) >> bitstozero) << bitstozero; - } - } - - /* compare the IP addresses */ - return memcmp(addr32, rem32, len); -} - -/* - * Matches a supplied IP address string against the address the client - * connected from (in his_addr). Returns 1 and updates sig if the addresses - * match and there hasn't already been a more specific match, zero otherwise. - */ -static int better_match(char *addrstr, int *sig) -{ - int addr_sig, max_sig = 32; - char *ptr; - void *addr; -#ifdef INET6 - int rval; - struct in6_addr in6; -#else - struct in_addr in; -#endif - - /* look for the optional significance (/CIDR) */ - if ((ptr = strstr(addrstr, "/"))) - *ptr = '\0'; - -#ifdef INET6 - if (his_addr_family == AF_INET6) - max_sig = 128; -#endif - - if (ptr) { - addr_sig = atoi(++ptr); - if (addr_sig < 0) - addr_sig = 0; - else if (addr_sig > max_sig) - addr_sig = max_sig; - } - else - addr_sig = max_sig; - - /* return if we already have a more specific match */ - if (addr_sig < *sig) { - if (ptr) - *--ptr = '/'; - return 0; - } - -#ifdef INET6 - rval = inet_pton6(addrstr, &in6); - if (ptr) - *--ptr = '/'; - if (rval != 1) - return 0; - - if (his_addr_family == AF_INET) { - /* convert IPv4-mapped IPv6 addresses to IPv4 addresses */ - if (IN6_IS_ADDR_V4MAPPED(&in6)) - addr = &in6.s6_addr[12]; - else - return 0; - } - else - addr = &in6.s6_addr; -#else - in.s_addr = inet_addr(addrstr); - if (ptr) - *--ptr = '/'; - if ((int)in.s_addr == -1) - return 0; - addr = &in.s_addr; -#endif - - if (addr_cmp(addr, addr_sig) == 0) { - *sig = addr_sig; - return 1; - } - return 0; -} - -static void update_address(char *externalip, char *addrstr) -{ - struct SOCKSTORAGE ext_addr; -#ifndef INET6 - struct in_addr in; -#endif - - /* validate the external IP address string */ -#ifdef INET6 - SET_SOCK_FAMILY(ext_addr, AF_INET6); - if (inet_pton6(externalip, SOCK_ADDR(ext_addr)) != 1) - return; - if ((his_addr_family == AF_INET) && - !IN6_IS_ADDR_V4MAPPED((struct in6_addr *)SOCK_ADDR(ext_addr))) - return; -#else - if ((int)(in.s_addr = inet_addr(externalip)) == -1) - return; - SET_SOCK_FAMILY(ext_addr, AF_INET); - SET_SOCK_ADDR4(ext_addr, in); -#endif - - if (better_match(addrstr, &vect_sig)) - vect_addr = ext_addr; -} - -static void update_ports(char *addrstr, char *minport, char *maxport) -{ - int min, max; - - min = atoi(minport); - max = atoi(maxport); - - /* validate the ports supplied */ - if ((min > max) || (min < 0) || (max > 65535) || (min == 0 && max != 0)) { - syslog(LOG_WARNING, "ftpaccess passive ports entry invalid: %s %s %s", addrstr, minport, maxport); - return; - } - - if (better_match(addrstr, &port_sig)) { - passive_port_min = min; - passive_port_max = max; - } -} - -int routevector(void) -{ - struct aclmember *entry = NULL; - -#ifdef INET6 - if (SOCK_FAMILY(his_addr) == AF_INET6) { - if (IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&(his_addr))->sin6_addr)) - his_v4mapped = 1; - else - his_addr_family = AF_INET6; - } -#endif - - while (getaclentry("passive", &entry)) { - if (!strcasecmp(ARG0, "address")) { - if (!ARG1 || !ARG2) - continue; - update_address(ARG1, ARG2); - } - if (!strcasecmp(ARG0, "ports")) { - if (!ARG1 || !ARG2 || !ARG3) - continue; - update_ports(ARG1, ARG2, ARG3); - } - } - return vect_sig != -1; -} diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/svc-ftp b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/svc-ftp deleted file mode 100644 index c0efb1dca4..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/svc-ftp +++ /dev/null @@ -1,62 +0,0 @@ -#!/sbin/sh -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License (the "License"). -# You may not use this file except in compliance with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -# Copyright 2009 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# - -. /lib/svc/share/ipf_include.sh - -create_ipf_rules() -{ - FMRI=$1 - ipf_file=`fmri_to_file ${FMRI} $IPF_SUFFIX` - nat_file=`fmri_to_file ${FMRI} $NAT_SUFFIX` - policy=`get_policy ${FMRI}` - - # - # Ftp uses two ports, ftp and ftp-data, see /etc/services which - # is why it's necessary to have this custom method. - # - conn_port=`$SERVINFO -p -t -s ftp 2>/dev/null` - data_port=`$SERVINFO -p -t -s ftp-data 2>/dev/null` - - echo "# $FMRI" >$ipf_file - generate_rules $FMRI $policy "tcp" "any" $conn_port $ipf_file - generate_rules $FMRI $policy "tcp" "any" $data_port $ipf_file - - # Generate a custom NAT rule here to use the ftp-proxy - # - echo "# $FMRI" >$nat_file - echo "rdr * any -> 0/32 proxy port ftp ftp/tcp" >>$nat_file -} - -case "$1" in -'ipfilter') - create_ipf_rules $2 - ;; - -*) - echo "Usage: $0 ipfilter" - ;; -esac -exit 0 diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/timeout.c b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/timeout.c deleted file mode 100644 index 6bf043c638..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/timeout.c +++ /dev/null @@ -1,72 +0,0 @@ -#pragma ident "%Z%%M% %I% %E% SMI" - -/**************************************************************************** - Copyright (c) 1999,2000 WU-FTPD Development Group. - All rights reserved. - - Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 - The Regents of the University of California. - Portions Copyright (c) 1993, 1994 Washington University in Saint Louis. - Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc. - Portions Copyright (c) 1989 Massachusetts Institute of Technology. - Portions Copyright (c) 1998 Sendmail, Inc. - Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman. - Portions Copyright (c) 1997 by Stan Barber. - Portions Copyright (c) 1997 by Kent Landfield. - Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 - Free Software Foundation, Inc. - - Use and distribution of this software and its source code are governed - by the terms and conditions of the WU-FTPD Software License ("LICENSE"). - - If you did not receive a copy of the license, it may be obtained online - at http://www.wu-ftpd.org/license.html. - - $Id: timeout.c,v 1.5 2000/07/01 18:17:39 wuftpd Exp $ - -****************************************************************************/ -#include "config.h" -#include "proto.h" - -#include -#include -#include -#include - -#include "extensions.h" - -unsigned int timeout_idle = 900; /* Command idle: 15 minutes */ -unsigned int timeout_maxidle = 7200; /* Command idle (MAX): 2 hours */ -unsigned int timeout_data = 1200; /* Data idle: 20 minutes */ -unsigned int timeout_rfc931 = 10; /* RFC931 session, total: 10 seconds */ -unsigned int timeout_accept = 120; /* Accepting data connection: 2 minutes */ -unsigned int timeout_connect = 120; /* Establishing data connection: 2 minutes */ - -void load_timeouts(void) -{ - struct aclmember *entry = NULL; - while (getaclentry("timeout", &entry)) { - if ((ARG0 != NULL) && (ARG1 != NULL)) { - unsigned long value = strtoul(ARG1, NULL, 0); - if (strcasecmp(ARG0, "rfc931") == 0) - timeout_rfc931 = value; - else if (value > 0) - if (strcasecmp(ARG0, "idle") == 0) { - timeout_idle = value; - if (timeout_maxidle < timeout_idle) - timeout_maxidle = timeout_idle; - } - else if (strcasecmp(ARG0, "maxidle") == 0) { - timeout_maxidle = value; - if (timeout_idle > timeout_maxidle) - timeout_idle = timeout_maxidle; - } - else if (strcasecmp(ARG0, "data") == 0) - timeout_data = value; - else if (strcasecmp(ARG0, "accept") == 0) - timeout_accept = value; - else if (strcasecmp(ARG0, "connect") == 0) - timeout_connect = value; - } - } -} diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/vers.c b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/vers.c deleted file mode 100644 index a76c60eac7..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/vers.c +++ /dev/null @@ -1,3 +0,0 @@ -#pragma ident "%Z%%M% %I% %E% SMI" - -char version[] = "Version wu-2.6.2+Sun"; diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/wu_config.h b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/wu_config.h deleted file mode 100644 index fe71afb310..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/wu_config.h +++ /dev/null @@ -1,338 +0,0 @@ -#pragma ident "%Z%%M% %I% %E% SMI" - -/* config.h. Generated automatically by configure. */ -/**************************************************************************** - - Copyright (c) 1999,2000 WU-FTPD Development Group. - All rights reserved. - - Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 - The Regents of the University of California. - Portions Copyright (c) 1993, 1994 Washington University in Saint Louis. - Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc. - Portions Copyright (c) 1989 Massachusetts Institute of Technology. - Portions Copyright (c) 1998 Sendmail, Inc. - Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman. - Portions Copyright (c) 1997 by Stan Barber. - Portions Copyright (c) 1997 by Kent Landfield. - Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 - Free Software Foundation, Inc. - - Use and distribution of this software and its source code are governed - by the terms and conditions of the WU-FTPD Software License ("LICENSE"). - - If you did not receive a copy of the license, it may be obtained online - at http://www.wu-ftpd.org/license.html. - - $Id: config.h.in,v 1.15 2000/07/01 17:42:15 wuftpd Exp $ - -****************************************************************************/ - -/* - * Top level config file... These values will be adjusted by autoconf. - * $Id: config.h.in,v 1.15 2000/07/01 17:42:15 wuftpd Exp $ - */ - -/* - * allow "upload" keyword in ftpaccess - */ - -#define UPLOAD 1 - -/* - * allow "overwrite" keyword in ftpaccess. - */ - -#define OVERWRITE 1 - -/* - * allow "allow/deny" for individual users. - */ - -#define HOST_ACCESS 1 - -/* - * log failed login attempts - */ - -#define LOG_FAILED 1 - -/* - * log login attempts that fail because of class connection - * limits. Busy servers may want to prevent this logging - * since it can fill up the log file and put a high load on - * syslog. - */ -#define LOG_TOOMANY 1 - -/* - * allow use of private file. (for site group and site gpass) - * NO_PRIVATE - * Define this if you don't want to use the private authentication databases. - */ - -/* #undef NO_PRIVATE */ - -/* - * Try once more on failed DNS lookups (to allow far away connections - * which might resolve slowly) - */ - -/* #undef DNS_TRYAGAIN */ - -/* - * ANON_ONLY - * Permit only anonymous logins... disables all other type - * See FIXES-2.4-HOBBIT for more information on this option. - */ - -/* #undef ANON_ONLY */ - -/* - * PARANOID - * Disable "questionable" functions - * See FIXES-2.4-HOBBIT for more information on this option. - */ - -/* #undef PARANOID */ - -/* - * SKEY - * Add SKEY support -- REQUIRES SKEY libraries - * See FIXES-2.4-HOBBIT for more information on this option. - */ - -/* #undef SKEY */ - -/* - * OPIE - * One-time Passwords In Everything (OPIE) - * Add OPIE support -- REQUIRES OPIE libraries - */ - -#if !defined (LINUX) /* Linux autodetects OPIE */ -/* #undef OPIE */ -#endif - -/* - * ALTERNATE_CD - * Causes "cd ~" to return the chroot-relative directory instead of the - * real directory. - */ -#define ALTERNATE_CD 1 - -/* - * UNRESTRICTED_CHMOD - * If defined, any valid value for the mode will be accepted. - * Otherwise, only values between 0 and 777 are accepted. - */ -/* #undef UNRESTRICTED_CHMOD */ - -/* - * USE_RFC931 - * Define this if you want to use RFC 931 'authentication' - this improves - * the logging at the cost of a possible slight delay in connection. - */ -/* #undef USE_RFC931 */ - -/* - * BUFFER_SIZE - * You can specify the buffer size for binary transfers; the defaults - * are often far too small for efficiency. - */ -/* #undef BUFFER_SIZE */ - -/* - * If you want to specify the syslog facility, you should modify CFLAGS in - * the appropriate src/makefile/Makefile.*. - */ - -/* If you want to set the paths where the configuration files, pids and logs - * are stored, you should inspect src/pathnames.h and modify the appropriate - * src/config/config.*. - */ - -/* - * RATIO - * Support for Upload/Download ratios (may download x bytes for uploading 1 byte) - */ -/* #undef RATIO */ - -/* - * OTHER_PASSWD - * Support for using alternative passwd/shadow files - */ -#define OTHER_PASSWD 1 - -/* - * DAEMON - * If ftpd called with -D then run as a standalone daemon listing on the - * ftp port. This can speed up ftpd response as all ftpd then needs to - * do is fork off a copy to handle an incoming request. Under inetd - * a new copy has to be opened and exec'd. - */ -#define DAEMON 1 - -/* - * MAX_BACKLOG - * Only used in DAEMON mode. - * This is second parameter to listen. It defines the number of incoming - * processes to allow to backlog, prior to being accept() processing them, - * before rejecting. - */ -#define MAX_BACKLOG 100 - -/* - * MAPPING_CHDIR - * Keep track of the path the user has chdir'd into and respond with - * that to pwd commands. This is to avoid having the absolue disk - * path returned. This helps avoid returning dirs like '.1/fred' - * when lots of disks make up the ftp area. - */ - -#define MAPPING_CHDIR 1 - -/* - * THROUGHPUT - * Keep track of total throughput for the user and limit if required. - */ - -#define THROUGHPUT 1 - -/* - * TRANSFER_COUNT - * Keep track of total bytes for statistics. - */ - -#define TRANSFER_COUNT 1 - -/* - * TRANSFER_LIMIT - * Limit file and bytes transferred in a session. - */ - -#define TRANSFER_LIMIT 1 - -/* - * NO_SUCKING_NEWLINES - * Don't suppress some extra blank lines on messages and banners. - */ - -/* #undef NO_SUCKING_NEWLINES */ - -/* - * HELP_CRACKERS - * Define this to help crackers break into your system by letting them - * figure out which user names exist to guess passwords on. - */ - -/* #undef HELP_CRACKERS */ - -/* - * VERBOSE_ERROR_LOGING - * Log all problems with USER and PASS as well as all rejected commands - * and denied uploads/downloads. - */ - -#define VERBOSE_ERROR_LOGING 1 - -/* - * IGNORE_NOOP - * Undefine this to let NOOP reset the idle timeout. - */ - -#define IGNORE_NOOP 1 - -/* - * CLOSED_VIRTUAL_SERVER - * Undefine this to allow real and non-owner guests to log in on a virutal server's address. - */ -#define CLOSED_VIRTUAL_SERVER 1 - -/* - * Some people don't like PASV and want to disable it. Whatever. - * PORT can be abused to attack other hosts. Let's give the option to - * disable one or the other. We'll ignore DISABLE_PASV if you defined - * DISABLE_PORT (hey, you gotta have at least one!). - */ -/* #undef DISABLE_PORT */ -/* #undef DISABLE_PASV */ - -/* - * Define this to suppress messages about PID locks causing the daemon to - * sleep. This should only be needed at busy sites. - */ -#define NO_PID_SLEEP_MSGS 1 - -/* - * Define this to require the remove end of a PASV connection to have the - * same IP as the control connection. This limits, but does not eliminate, - * the risk of PASV port race stealing the connection. It also is non-RFC - * compliant, so it may cause problems for some client sites. - */ -#define FIGHT_PASV_PORT_RACE 1 - -/* - * Define this to completely disable anonymous FTP access. - */ -/* #undef NO_ANONYMOUS_ACCESS */ - -/* - * Define this to have an ls command compiled into the daemon. That way you - * don't need to put statically linked ls's into every chroot directory. - */ -/* #undef INTERNAL_LS */ - -/* - * Define this if you want the internal ls to display UIDs/GIDs rather than - * user/group names. This is faster, but doesn't look as nice. - */ -/* #undef LS_NUMERIC_UIDS */ - -/* - * Define this if you want to hide setuid bits in the internal ls - * this might be a good idea for security. - */ -#define HIDE_SETUID 1 - -/* - * Define this if you want to support virtual servers - */ -#define VIRTUAL 1 - -/* - * Define this if you want to be able to receive mail on anonymous - * uploads - */ -#define MAIL_ADMIN 1 - -/* - * Config files in /etc by default - */ -#define USE_ETC 1 - -/* - * Define this to support quota mechanisms... - */ -#define QUOTA 1 - -/* - * The intention of SITE NEWER was to enable mirrors to quickly determine which - * files have changed since the last run. Since most mirror packages wish to - * work with all daemons (not just wu-ftpd), and since SITE NEWER is a wu-ftpd - * only feature, they don't use the feature. Therefore there seems little - * reason to continue to support it. - * - * Define this to support SITE NEWER and SITE MINFO. - */ -/* #undef SITE_NEWER */ - -/* - * Define this to revert the NLST command to showing directories. - * - * This will cause mget to have errors when it attempts to RETR the - * directory name (which is not a RETRievable object) but will revert - * the NLST command enough to quell complains from Solaris command- - * line FTP client users. - */ -#define NLST_SHOWS_DIRS 1 diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/wu_fnmatch.c b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/wu_fnmatch.c deleted file mode 100644 index 32461fd338..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/wu_fnmatch.c +++ /dev/null @@ -1,206 +0,0 @@ -#pragma ident "%Z%%M% %I% %E% SMI" - -/**************************************************************************** - Copyright (c) 1999,2000 WU-FTPD Development Group. - All rights reserved. - - Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 - The Regents of the University of California. - Portions Copyright (c) 1993, 1994 Washington University in Saint Louis. - Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc. - Portions Copyright (c) 1989 Massachusetts Institute of Technology. - Portions Copyright (c) 1998 Sendmail, Inc. - Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman. - Portions Copyright (c) 1997 by Stan Barber. - Portions Copyright (c) 1997 by Kent Landfield. - Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 - Free Software Foundation, Inc. - - Use and distribution of this software and its source code are governed - by the terms and conditions of the WU-FTPD Software License ("LICENSE"). - - If you did not receive a copy of the license, it may be obtained online - at http://www.wu-ftpd.org/license.html. - - $Id: wu_fnmatch.c,v 1.7 2000/10/25 20:18:13 wuftpd Exp $ - -****************************************************************************/ -/* - * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6. - * Compares a filename or pathname to a pattern. - */ - -#include -#include -#include -#include - -typedef int boolean; -#define FALSE 0 -#define TRUE 1 - -#include "wu_fnmatch.h" - -#define EOS '\0' - -static const char *rangematch(const char *pattern, const char *string, int flags) -{ -/* - * A bracket expression starting with an unquoted circumflex character - * produces unspecified results (IEEE 1003.2-1992, 3.13.2). This - * implementation treats it like '!', for consistency with the regular - * expression syntax. J.T. Conklin (conklin@ngai.kaleida.com) - */ - char test = *string; - boolean negate = ((*pattern == '!') || (*pattern == '^')); - boolean ok = FALSE; - if (negate) - ++pattern; - if (flags & FNM_CASEFOLD) - test = tolower((unsigned char) test); - while (*pattern != ']') { - char c = *pattern++; - if ((c == '\\') && !(flags & FNM_NOESCAPE)) - c = *pattern++; - if (c == EOS) - return (NULL); - if (flags & FNM_CASEFOLD) - c = tolower((unsigned char) c); - if (*pattern == '-') { - char c2 = pattern[1]; - if ((c2 != EOS) - && (c2 != ']')) { - pattern += 2; - if ((c2 == '\\') && !(flags & FNM_NOESCAPE)) - c2 = *pattern++; - if (c2 == EOS) - return (NULL); - if (flags & FNM_CASEFOLD) - c2 = tolower((unsigned char) c2); - /* this is a hack */ - if ((c <= test) && (test <= c2)) - ok = TRUE; - } - else if (c == test) - ok = TRUE; - } - else if (c == test) - ok = TRUE; - } - return ((ok == negate) ? NULL : pattern+1); -} - -int wu_fnmatch(const char *pattern, const char *string, int flags) -{ - const char *stringstart = string; - if ((pattern == NULL) || (string == NULL)) - return FNM_NOMATCH; - while (TRUE) { - char test; - char c = *pattern++; - switch (c) { - case EOS: -#ifdef FNM_LEADING_DIR - if ((flags & FNM_LEADING_DIR) - && (*string == '/')) - return (0); - /* - * WU-FTPD extension/correction. - * - * If the pattern ended with a '/', and we're doing - * FNM_PATHNAME matching, consider it a match if the - * previous string character was a '/' and the current - * is not a '/'. - */ - if ((flags & FNM_LEADING_DIR) - && (string != stringstart) - && (flags & FNM_PATHNAME) - && (*(string - 1) == '/')) - return (0); -#endif - return ((*string == EOS) ? 0 : FNM_NOMATCH); - case '?': - if (*string == EOS) - return (FNM_NOMATCH); - if ((*string == '/') - && (flags & FNM_PATHNAME)) - return (FNM_NOMATCH); - if ((*string == '.') - && (flags & FNM_PERIOD) - && ((string == stringstart) - || ((flags & FNM_PATHNAME) - && (*(string - 1) == '/')))) - return (FNM_NOMATCH); - ++string; - break; - case '*': - c = *pattern; - while (c == '*') - c = *++pattern; - if ((*string == '.') - && (flags & FNM_PERIOD) - && ((string == stringstart) - || ((flags & FNM_PATHNAME) - && (*(string - 1) == '/')))) - return (FNM_NOMATCH); - /* Optimize for pattern with * at end or before /. */ - if (c == EOS) - if (flags & FNM_PATHNAME) { -#ifdef FNM_LEADING_DIR - if (flags & FNM_LEADING_DIR) - return (0); -#endif - return ((strchr(string, '/') == NULL) ? 0 : FNM_NOMATCH); - } - else - return (0); - else if ((c == '/') - && (flags & FNM_PATHNAME)) { - string = strchr(string, '/'); - if (string == NULL) - return (FNM_NOMATCH); - break; - } - /* General case, use recursion. */ - for (test = *string; test != EOS; test = *++string) { - if (!wu_fnmatch(pattern, string, (flags & ~FNM_PERIOD))) - return (0); - if ((test == '/') - && (flags & FNM_PATHNAME)) - break; - } - return (FNM_NOMATCH); - case '[': - if (*string == EOS) - return (FNM_NOMATCH); - if ((*string == '/') - && (flags & FNM_PATHNAME)) - return (FNM_NOMATCH); - pattern = rangematch(pattern, string, flags); - if (pattern == NULL) - return (FNM_NOMATCH); - ++string; - break; - case '\\': - if (!(flags & FNM_NOESCAPE)) { - c = *pattern++; - if (c == EOS) { - c = '\\'; - --pattern; - } - } - /* FALLTHROUGH */ - default: - if (c == *string); -#ifdef FNM_CASEFOLD - else if ((flags & FNM_CASEFOLD) - && (tolower((unsigned char) c) == tolower((unsigned char) *string))); -#endif - else - return (FNM_NOMATCH); - string++; - break; - } - } -/* NOTREACHED */ -} diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/wu_fnmatch.h b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/wu_fnmatch.h deleted file mode 100644 index f96c839058..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/wu_fnmatch.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma ident "%Z%%M% %I% %E% SMI" - -/**************************************************************************** - Copyright (c) 1999,2000 WU-FTPD Development Group. - All rights reserved. - - Portions Copyright (c) 1980, 1985, 1988, 1989, 1990, 1991, 1993, 1994 - The Regents of the University of California. - Portions Copyright (c) 1993, 1994 Washington University in Saint Louis. - Portions Copyright (c) 1996, 1998 Berkeley Software Design, Inc. - Portions Copyright (c) 1989 Massachusetts Institute of Technology. - Portions Copyright (c) 1998 Sendmail, Inc. - Portions Copyright (c) 1983, 1995, 1996, 1997 Eric P. Allman. - Portions Copyright (c) 1997 by Stan Barber. - Portions Copyright (c) 1997 by Kent Landfield. - Portions Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997 - Free Software Foundation, Inc. - - Use and distribution of this software and its source code are governed - by the terms and conditions of the WU-FTPD Software License ("LICENSE"). - - If you did not receive a copy of the license, it may be obtained online - at http://www.wu-ftpd.org/license.html. - - $Id: wu_fnmatch.h,v 1.5 2000/07/01 18:17:39 wuftpd Exp $ - -****************************************************************************/ -#ifndef __WU_FNMATCH_H -#define __WU_FNMATCH_H 1 - -extern int wu_fnmatch(const char *pattern, const char *string, int flags); -#define FNM_NOMATCH 1 -#define FNM_PATHNAME 0x01 -#define FNM_NOESCAPE 0x02 -#define FNM_PERIOD 0x04 -#define FNM_LEADING_DIR 0x08 -#define FNM_CASEFOLD 0x10 - -#endif diff --git a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/xferlog.c b/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/xferlog.c deleted file mode 100644 index 0123ce64d3..0000000000 --- a/usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/xferlog.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include "config.h" -#include -#include "extensions.h" -#include "proto.h" - -#define DEFXFERFORMAT "%T %Xt %R %Xn %XP %Xy %Xf %Xd %Xm %U ftp %Xa %u %Xc" - -int xferdone = 0; -struct xferstat xfervalues; -char xferlog_format[MAXXFERSTRLEN] = DEFXFERFORMAT; - -/*************************************************************************/ -/* FUNCTION : get_xferlog_format */ -/* PURPOSE : Read the xferlog format string from ftpaccess into */ -/* xferlog_format if it exists otherwise load default string */ -/* ARGUMENTS : none */ -/*************************************************************************/ - -void get_xferlog_format(void) -{ - int which; - struct aclmember *entry = (struct aclmember *)NULL; - - /* xferlog format */ - xferlog_format[0] = '\0'; - while (getaclentry("xferlog", &entry)) { - if (ARG0 && (strcasecmp(ARG0, "format") == 0)) { - for (which = 1; (which < MAXARGS) && ARG[which]; which++) { - if (which > 1) { - if (strlcat(xferlog_format, " ", - sizeof(xferlog_format)) >= sizeof(xferlog_format)) - break; - } - if (strlcat(xferlog_format, ARG[which], - sizeof(xferlog_format)) >= sizeof(xferlog_format)) - break; - } - break; - } - } - - /* default xferlog format */ - if (xferlog_format[0] == '\0') - (void) strlcpy(xferlog_format, DEFXFERFORMAT, sizeof(xferlog_format)); -} diff --git a/usr/src/cmd/svc/profile/generic_limited_net.xml b/usr/src/cmd/svc/profile/generic_limited_net.xml index 3685b92f30..61e31a3b70 100644 --- a/usr/src/cmd/svc/profile/generic_limited_net.xml +++ b/usr/src/cmd/svc/profile/generic_limited_net.xml @@ -206,9 +206,6 @@ - - - diff --git a/usr/src/cmd/svc/profile/inetd_generic.xml b/usr/src/cmd/svc/profile/inetd_generic.xml index db82512db3..d07cad5294 100644 --- a/usr/src/cmd/svc/profile/inetd_generic.xml +++ b/usr/src/cmd/svc/profile/inetd_generic.xml @@ -37,9 +37,6 @@ - - - diff --git a/usr/src/man/man1/Makefile b/usr/src/man/man1/Makefile index 36d8f10155..2291d1a9c0 100644 --- a/usr/src/man/man1/Makefile +++ b/usr/src/man/man1/Makefile @@ -139,8 +139,6 @@ MANFILES= acctcom.1 \ fmtmsg.1 \ fold.1 \ ftp.1 \ - ftpcount.1 \ - ftpwho.1 \ gcore.1 \ gencat.1 \ genmsg.1 \ diff --git a/usr/src/man/man1/ftp.1 b/usr/src/man/man1/ftp.1 index 0fe300d072..448cd3d510 100644 --- a/usr/src/man/man1/ftp.1 +++ b/usr/src/man/man1/ftp.1 @@ -15,7 +15,6 @@ ftp \- file transfer program .fi .SH DESCRIPTION -.sp .LP The \fBftp\fR command is the user interface to the \fBInternet\fR standard File Transfer Protocol (\fBFTP\fR). \fBftp\fR transfers files to and from a remote @@ -29,7 +28,6 @@ to establish a connection to an \fBFTP\fR server on that host. Otherwise, When \fBftp\fR is awaiting commands from the user, it displays the prompt \fBftp>\fR. .SH OPTIONS -.sp .LP The following options can be specified at the command line, or to the command interpreter: @@ -1115,7 +1113,6 @@ marks. If any command argument which is not indicated as being optional is not specified, \fBftp\fR prompts for that argument. .SH ABORTING A FILE TRANSFER -.sp .LP To abort a file transfer, use the terminal interrupt key. Sending transfers is immediately halted. Receiving transfers are halted by sending an \fBFTP\fR @@ -1133,7 +1130,6 @@ unexpected behavior by the remote server, including violations of the ftp protocol. If the delay results from unexpected remote server behavior, the local \fBftp\fR program must be killed by hand. .SH FILE NAMING CONVENTIONS -.sp .LP Local files specified as arguments to \fBftp\fR commands are processed according to the following rules. @@ -1199,7 +1195,6 @@ by the remote server if \fBsunique\fR is on. .RE .SH FILE TRANSFER PARAMETERS -.sp .LP The \fBFTP\fR specification specifies many parameters which can affect a file transfer. @@ -1226,7 +1221,6 @@ The "transfer mode" can be one of \fBstream\fR, \fBblock\fR, or \fBcompressed\fR. \fBftp\fR supports only the default value, which is \fBstream\fR. .SH USAGE -.sp .LP See \fBlargefile\fR(5) for the description of the behavior of \fBftp\fR when encountering files greater than or equal to 2 Gbyte (2^31 bytes). @@ -1234,11 +1228,9 @@ encountering files greater than or equal to 2 Gbyte (2^31 bytes). .LP The \fBftp\fR command is IPv6-enabled. See \fBip6\fR(7P). .SH FILES -.sp .LP \fB~/.netrc\fR .SH ATTRIBUTES -.sp .LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -1254,9 +1246,8 @@ CSI enabled .TE .SH SEE ALSO -.sp .LP -\fBls\fR(1), \fBrcp\fR(1), \fBsh\fR(1), \fBtar\fR(1), \fBin.ftpd\fR(1M), +\fBls\fR(1), \fBrcp\fR(1), \fBsh\fR(1), \fBtar\fR(1), \fBpopen\fR(3C), \fBftp\fR(4), \fBftpusers\fR(4), \fBmech\fR(4), \fBnetrc\fR(4), \fBattributes\fR(5), \fBlargefile\fR(5), \fBip6\fR(7P) .sp @@ -1276,11 +1267,10 @@ Network Information Center. October 1985. Piscitello, D. \fIRFC 1639, FTP Operation Over Big Address Records (FOOBAR)\fR. Network Working Group. June 1994. .SH NOTES -.sp .LP Failure to log in can arise from an explicit denial by the remote \fBFTP\fR server because the account is listed in \fB/etc/ftpusers\fR. See -\fBin.ftpd\fR(1M) and \fBftpusers\fR(4). +\fBftpusers\fR(4). .sp .LP Correct execution of many commands depends upon proper behavior by the remote diff --git a/usr/src/man/man1/ftpcount.1 b/usr/src/man/man1/ftpcount.1 deleted file mode 100644 index 5a2d561e80..0000000000 --- a/usr/src/man/man1/ftpcount.1 +++ /dev/null @@ -1,101 +0,0 @@ -'\" te -.\" Copyright (C) 2001, Sun Microsystems, Inc. All Rights Reserved -.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License. -.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License. -.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner] -.TH FTPCOUNT 1 "Apr 25, 2003" -.SH NAME -ftpcount \- show current number of users in each FTP Server class -.SH SYNOPSIS -.LP -.nf -\fBftpcount\fR [\fB-v\fR] [\fB-V\fR] -.fi - -.SH DESCRIPTION -.sp -.LP -Use the \fBftpcount\fR command to show the current number of users logged in -and the login limit for each FTP Server class defined in the \fBftpaccess\fR(4) -file. -.SH OPTIONS -.sp -.LP -The \fBftpcount\fR command supports the following options: -.sp -.ne 2 -.na -\fB\fB-v\fR\fR -.ad -.RS 6n -Display the user counts for FTP Server classes defined in virtual host -\fBftpaccess\fR(4) files. -.RE - -.sp -.ne 2 -.na -\fB\fB-V\fR\fR -.ad -.RS 6n -Display program copyright and version information, then terminate. -.RE - -.SH EXIT STATUS -.sp -.LP -The following exit values are returned: -.sp -.ne 2 -.na -\fB\fB0\fR \fR -.ad -.RS 6n -Successful completion. -.RE - -.sp -.ne 2 -.na -\fB>\fB0\fR\fR -.ad -.RS 6n -An error occurred. -.RE - -.SH FILES -.sp -.LP -\fB/var/run/ftp.pids-\fIclassnames\fR\fR -.sp -.LP -\fB/etc/ftpd/ftpaccess\fR -.sp -.LP -\fB/etc/ftpd/ftpservers\fR -.SH ATTRIBUTES -.sp -.LP -See \fBattributes\fR(5) for descriptions of the following attributes: -.sp - -.sp -.TS -box; -c | c -l | l . -ATTRIBUTE TYPE ATTRIBUTE VALUE -_ -Interface Stability Standard -.TE - -.SH SEE ALSO -.sp -.LP -\fBftpwho\fR(1), \fBin.ftpd\fR(1M), \fBftpaccess\fR(4), \fBftpservers\fR(4), -\fBattributes\fR(5) -.SH NOTES -.sp -.LP -For separate class counts to be kept, class names defined in complete virtual -host \fBftpaccess\fR files must be unique. diff --git a/usr/src/man/man1/ftpwho.1 b/usr/src/man/man1/ftpwho.1 deleted file mode 100644 index d5cf9004fd..0000000000 --- a/usr/src/man/man1/ftpwho.1 +++ /dev/null @@ -1,101 +0,0 @@ -'\" te -.\" Copyright (C) 2001, Sun Microsystems, Inc. All Rights Reserved -.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License. -.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License. -.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner] -.TH FTPWHO 1 "Apr 25, 2003" -.SH NAME -ftpwho \- show current process information for each FTP Server user -.SH SYNOPSIS -.LP -.nf -\fBftpwho\fR [\fB-v\fR] [\fB-V\fR] -.fi - -.SH DESCRIPTION -.sp -.LP -Use the \fBftpwho\fR command to show the current process information for each -user logged in to the FTP Server. This information is in addition to -information displayed by the \fBftpcount\fR(1) command. -.SH OPTIONS -.sp -.LP -The \fBftpwho\fR command supports the following options: -.sp -.ne 2 -.na -\fB\fB-v\fR\fR -.ad -.RS 6n -Display the current process information and user counts for FTP Server classes -defined in virtual host \fBftpaccess\fR(4) files. -.RE - -.sp -.ne 2 -.na -\fB\fB-V\fR\fR -.ad -.RS 6n -Display the program copyright and version information, then terminate. -.RE - -.SH EXIT STATUS -.sp -.LP -The following exit values are returned: -.sp -.ne 2 -.na -\fB\fB0\fR \fR -.ad -.RS 6n -Successful completion. -.RE - -.sp -.ne 2 -.na -\fB>\fB0\fR\fR -.ad -.RS 6n -An error occurred. -.RE - -.SH FILES -.sp -.LP -\fB/etc/ftpd/ftpaccess\fR -.sp -.LP -\fB/var/run/ftp.pids-\fIclassname\fR\fR -.sp -.LP -\fB/etc/ftpd/ftpservers\fR -.SH ATTRIBUTES -.sp -.LP -See \fBattributes\fR(5) for descriptions of the following attributes: -.sp - -.sp -.TS -box; -c | c -l | l . -ATTRIBUTE TYPE ATTRIBUTE VALUE -_ -Interface Stability External -.TE - -.SH SEE ALSO -.sp -.LP -\fBftpcount\fR(1), \fBps\fR(1), \fBin.ftpd\fR(1M), \fBftpaccess\fR(4), -\fBftpservers\fR(4), \fBattributes\fR(5) -.SH NOTES -.sp -.LP -For separate class counts to be kept, class names defined in complete virtual -host \fBftpaccess\fR files must be unique. diff --git a/usr/src/man/man1m/Makefile b/usr/src/man/man1m/Makefile index cd58ae6a90..56fc2ebb09 100644 --- a/usr/src/man/man1m/Makefile +++ b/usr/src/man/man1m/Makefile @@ -157,10 +157,6 @@ _MANFILES= 6to4relay.1m \ fssnap_ufs.1m \ fsstat.1m \ fstyp.1m \ - ftpaddhost.1m \ - ftpconfig.1m \ - ftprestart.1m \ - ftpshut.1m \ fuser.1m \ fwflash.1m \ fwtmp.1m \ @@ -206,7 +202,6 @@ _MANFILES= 6to4relay.1m \ in.discardd.1m \ in.echod.1m \ in.fingerd.1m \ - in.ftpd.1m \ in.iked.1m \ in.lpd.1m \ in.mpathd.1m \ @@ -632,7 +627,6 @@ MANLINKS= acctcon1.1m \ dodisk.1m \ fcadm.1m \ fingerd.1m \ - ftpd.1m \ grpck.1m \ hal-find-by-capability.1m \ hal-find-by-property.1m \ @@ -741,7 +735,6 @@ poweroff.1m := LINKSRC = halt.1m comsat.1m := LINKSRC = in.comsat.1m fingerd.1m := LINKSRC = in.fingerd.1m -ftpd.1m := LINKSRC = in.ftpd.1m rarpd.1m := LINKSRC = in.rarpd.1m rdisc.1m := LINKSRC = in.rdisc.1m rexecd.1m := LINKSRC = in.rexecd.1m diff --git a/usr/src/man/man1m/ftpaddhost.1m b/usr/src/man/man1m/ftpaddhost.1m deleted file mode 100644 index 00154c490e..0000000000 --- a/usr/src/man/man1m/ftpaddhost.1m +++ /dev/null @@ -1,160 +0,0 @@ -'\" te -.\" Copyright (C) 2003, Sun Microsystems, Inc. All Rights Reserved -.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License. -.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License. -.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner] -.TH FTPADDHOST 1M "May 1, 2003" -.SH NAME -ftpaddhost \- set up a virtual FTP host -.SH SYNOPSIS -.LP -.nf -\fBftpaddhost\fR \fB-c\fR | \fB-l\fR [\fB-b\fR] [\fB-x\fR \fIxferlog\fR] \fIhostname\fR \fIroot_dir\fR -.fi - -.SH DESCRIPTION -.sp -.LP -The \fBftpaddhost\fR script is executed by the super user to set up virtual FTP -hosts. The \fBftpaddhost\fR command configures the virtual host \fIhostname\fR -under directory \fIroot_dir\fR. The value of \fIhostname\fR can be an IP -address or the name of a host. -.SH OPTIONS -.sp -.LP -The \fBftpaddhost\fR script supports the following options: -.sp -.ne 2 -.na -\fB\fB-b\fR\fR -.ad -.RS 14n -Create a banner for the virtual host. This option is useful to confirm that the -virtual host is working. -.RE - -.sp -.ne 2 -.na -\fB\fB-c\fR\fR -.ad -.RS 14n -Configure complete virtual hosting. This option allows each virtual host to -have its own version of the \fBftpaccess\fR, \fBftpconversions\fR, -\fB\fR\fBftpgroups\fR, \fBftphosts\fR, and \fBftpusers\fR files. The master -version of each of these configuration files is copied from the \fB/etc/ftpd\fR -directory and placed in the \fB/etc/ftpd/virtual-ftpd/\fIhostname\fR\fR -directory. If the \fB/etc/ftpusers\fR file exists it is appended to the virtual -\fBftpusers\fR file. If a virtual host lacks its own version of a configuration -file, the master version is used. -.RE - -.sp -.ne 2 -.na -\fB\fB-l\fR\fR -.ad -.RS 14n -Configure limited virtual hosting. This option allows a small number of -parameters to be configured differently for a virtual host. See the -\fBvirtual\fR keyword on the \fBftpaccess\fR(4) manual page. -.RE - -.sp -.ne 2 -.na -\fB\fB-x\fR \fIxferlog\fR\fR -.ad -.RS 14n -Create a logfile entry such that the transfer logs for the virtual host are -written to the specified file. An absolute path must be specified for the -\fIxferlog\fR file. -.RE - -.SH OPERANDS -.sp -.LP -The following operands are supported: -.sp -.ne 2 -.na -\fB\fIhostname\fR\fR -.ad -.RS 12n -The host name or IP address of the virtual server. -.RE - -.sp -.ne 2 -.na -\fB\fIroot_dir\fR\fR -.ad -.RS 12n -The absolute pathname of the directory under which the virtual server is set -up. -.RE - -.SH EXIT STATUS -.sp -.LP -The following exit values are returned: -.sp -.ne 2 -.na -\fB\fB0\fR \fR -.ad -.RS 6n -Successful completion -.RE - -.sp -.ne 2 -.na -\fB\fB1\fR\fR -.ad -.RS 6n -Improper usage of the command -.RE - -.sp -.ne 2 -.na -\fB\fB2\fR\fR -.ad -.RS 6n -Command failed -.RE - -.SH FILES -.sp -.ne 2 -.na -\fB\fB/etc/ftpd/virtual-ftpd/\fIhostname\fR\fR\fR -.ad -.sp .6 -.RS 4n -The configuration files directory for the virtual host \fIhostname\fR. -.RE - -.SH ATTRIBUTES -.sp -.LP -See \fBattributes\fR(5) for descriptions of the following attributes: -.sp - -.sp -.TS -box; -c | c -l | l . -ATTRIBUTE TYPE ATTRIBUTE VALUE -_ -Interface Stability Evolving -.TE - -.SH SEE ALSO -.sp -.LP -\fBftpconfig\fR(1M), \fBin.ftpd\fR(1M), \fBftpaccess\fR(4), -\fBftpconversions\fR(4), \fBftpgroups\fR(4), \fBftphosts\fR(4), -\fBftpusers\fR(4), \fBxferlog\fR(4), \fBattributes\fR(5) diff --git a/usr/src/man/man1m/ftpconfig.1m b/usr/src/man/man1m/ftpconfig.1m deleted file mode 100644 index 8cec6cee18..0000000000 --- a/usr/src/man/man1m/ftpconfig.1m +++ /dev/null @@ -1,118 +0,0 @@ -'\" te -.\" Copyright (C) 2002, Sun Microsystems, Inc. All Rights Reserved -.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License. -.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License. -.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner] -.TH FTPCONFIG 1M "May 1, 2003" -.SH NAME -ftpconfig \- set up anonymous FTP -.SH SYNOPSIS -.LP -.nf -\fBftpconfig\fR [\fIftpdir\fR] -.fi - -.LP -.nf -\fBftpconfig\fR \fB-d\fR \fIftpdir\fR -.fi - -.SH DESCRIPTION -.sp -.LP -The \fBftpconfig\fR script is executed by the super user to set up anonymous -FTP. Anonymous FTP allows users to remotely log on to the FTP server by -specifying the user name \fBftp\fR or \fBanonymous\fR and the user's email -address as password. The anonymous users are logged on to the FTP Server and -given access to a restricted file area with its own file system root. See -\fBchroot\fR(2). The FTP area has its own minimal system files. -.sp -.LP -This command will copy and set up all the components needed to operate an -anonymous FTP server, including creating the \fIftp\fR user account, creating -device nodes, copying \fB/usr/lib\fR files, and copying timezone data. The -\fBpasswd\fR and \fBgroup\fR files set up have been stripped down to prevent -malicious users from finding login names on the server. The anonymous file -area will be placed under \fBftpdir\fR. If the \fIftp\fR user account already -exists, then the current FTP area is used, and the system files in it are -updated. All other files are left untouched. This command should be run to -update the anonymous FTP area's configuration whenever a system patch is -installed, or the system is upgraded. -.SH OPTIONS -.sp -.ne 2 -.na -\fB\fB-d\fR \fR -.ad -.RS 7n -Create a new or update an existing \fIftpdir\fR without creating or updating -the \fIftp\fR user account. Use this option when creating guest FTP user -accounts. -.RE - -.SH OPERANDS -.sp -.LP -The following operands are supported: -.sp -.ne 2 -.na -\fB\fIftpdir\fR\fR -.ad -.RS 10n -The absolute pathname of the directory under which the anonymous FTP area is -set up. -.RE - -.SH EXIT STATUS -.sp -.LP -The following exit values are returned: -.sp -.ne 2 -.na -\fB\fB0\fR \fR -.ad -.RS 6n -Successful completion -.RE - -.sp -.ne 2 -.na -\fB\fB1\fR\fR -.ad -.RS 6n -Improper usage of the command -.RE - -.sp -.ne 2 -.na -\fB\fB2\fR\fR -.ad -.RS 6n -Command failed -.RE - -.SH ATTRIBUTES -.sp -.LP -See \fBattributes\fR(5) for descriptions of the following attributes: -.sp - -.sp -.TS -box; -c | c -l | l . -ATTRIBUTE TYPE ATTRIBUTE VALUE -_ -Interface Stability Evolving -.TE - -.SH SEE ALSO -.sp -.LP -\fBftpaddhost\fR(1M), \fBin.ftpd\fR(1M), \fBuseradd\fR(1M), \fBchroot\fR(2), -\fBattributes\fR(5) diff --git a/usr/src/man/man1m/ftprestart.1m b/usr/src/man/man1m/ftprestart.1m deleted file mode 100644 index a21fb6f091..0000000000 --- a/usr/src/man/man1m/ftprestart.1m +++ /dev/null @@ -1,116 +0,0 @@ -'\" te -.\" Copyright (C) 2003, Sun Microsystems, Inc. All Rights Reserved -.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License. -.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License. -.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner] -.TH FTPRESTART 1M "May 1, 2003" -.SH NAME -ftprestart \- restart previously shutdown FTP Servers -.SH SYNOPSIS -.LP -.nf -\fBftprestart\fR [\fB-V\fR] -.fi - -.SH DESCRIPTION -.sp -.LP -Use the \fBftprestart\fR command to restart an FTP Server previously shut down -by means of \fBftpshut\fR(1M). The \fBftprestart\fR command reads the -\fBshutdown\fR capability from the \fBftpaccess\fR(4) file to determine the -path of the shutdown message files. It then reenables the FTP Server by -removing any shutdown message files in the anonymous and virtual FTP Server -area, as well as the system wide shutdown message file. -.SH OPTIONS -.sp -.LP -The \fBftprestart\fR command supports the following options: -.sp -.ne 2 -.na -\fB\fB-V\fR\fR -.ad -.RS 6n -Display program copyright and version information, then terminate. -.RE - -.SH EXAMPLES -.LP -\fBExample 1 \fRSample Output from \fBftprestart\fR -.sp -.LP -The following example shows sample output from the \fBftprestart\fR command: - -.sp -.in +2 -.nf -example% \fBftprestart\fR -ftprestart: /export/home/ftp/etc/ftpd/shutdown.msg removed. -ftprestart: /export/home/virtual1/etc/ftpd/shutdown.msg removed. -ftprestart: /etc/ftpd/shutdown.msg removed. -.fi -.in -2 -.sp - -.SH EXIT STATUS -.sp -.LP -The following exit values are returned: -.sp -.ne 2 -.na -\fB\fB0\fR \fR -.ad -.RS 6n -Successful completion. -.RE - -.sp -.ne 2 -.na -\fB>\fB0\fR\fR -.ad -.RS 6n -An error occurred. -.RE - -.SH FILES -.sp -.ne 2 -.na -\fB\fB/etc/ftpd/ftpaccess\fR\fR -.ad -.RS 24n - -.RE - -.sp -.ne 2 -.na -\fB\fB/etc/ftpd/ftpservers\fR\fR -.ad -.RS 24n - -.RE - -.SH ATTRIBUTES -.sp -.LP -See \fBattributes\fR(5) for descriptions of the following attributes: -.sp - -.sp -.TS -box; -c | c -l | l . -ATTRIBUTE TYPE ATTRIBUTE VALUE -_ -Interface Stability External -.TE - -.SH SEE ALSO -.sp -.LP -\fBftpshut\fR(1M), \fBin.ftpd\fR(1M), \fBftpaccess\fR(4), \fBftpservers\fR(4), -\fBattributes\fR(5) diff --git a/usr/src/man/man1m/ftpshut.1m b/usr/src/man/man1m/ftpshut.1m deleted file mode 100644 index da221043fe..0000000000 --- a/usr/src/man/man1m/ftpshut.1m +++ /dev/null @@ -1,287 +0,0 @@ -'\" te -.\" Copyright (C) 2003, Sun Microsystems, Inc. All Rights Reserved -.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License. -.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License. -.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner] -.TH FTPSHUT 1M "May 1, 2003" -.SH NAME -ftpshut \- close down the FTP Servers at a given time -.SH SYNOPSIS -.LP -.nf -\fBftpshut\fR [\fB-V\fR] [\fB-v\fR] [\fB-l\fR \fImin\fR] [\fB-d\fR \fImin\fR] \fItime\fR - [\fIwarning-message\fR]... -.fi - -.SH DESCRIPTION -.sp -.LP -The \fBftpshut\fR command provides an automated shutdown procedure that the -superuser can use to notify FTP users when the FTP Server is shutting down. -.sp -.LP -Ten minutes before shutdown, or immediately if the value of \fItime\fR is less -than ten minutes, any new FTP Server connections will be disabled. You may -adjust the shutdown of new FTP Server connections by means of the \fB-l\fR -option. -.sp -.LP - Five minutes before shutdown, or immediately if the value of \fItime\fR is -less than five minutes, all current FTP connections will be disconnected. You -may adjust the shutdown of current FTP connections by means of the \fB-d\fR -option. -.sp -.LP - The \fBftpshut\fR command creates shutdown message files that the FTP Server -uses to determine when to shutdown. Separate shutdown message files are created -in the anonymous and virtual host FTP Server areas, in addition to the system -wide shutdown message file. Once the shutdown occurs, the server continues to -refuse connections until the appropriate shutdown message file is removed. This -normally is done by using the \fBftprestart\fR(1M) command. The location of the -shutdown message file is specified by the \fBshutdown\fR capability in the -\fBftpaccess\fR file. -.sp -.LP -The following magic cookies are available: -.sp -.ne 2 -.na -\fB\fB%s\fR\fR -.ad -.RS 6n -The time system is going to shut down. -.RE - -.sp -.ne 2 -.na -\fB\fB%r\fR\fR -.ad -.RS 6n -The time new connections will be denied. -.RE - -.sp -.ne 2 -.na -\fB\fB%d\fR\fR -.ad -.RS 6n -The time current connections will be dropped. -.RE - -.sp -.ne 2 -.na -\fB\fB%C\fR\fR -.ad -.RS 6n -The current working directory. -.RE - -.sp -.ne 2 -.na -\fB\fB%E\fR\fR -.ad -.RS 6n -The maintainer's email address as defined in the \fBftpaccess\fR file. -.RE - -.sp -.ne 2 -.na -\fB\fB%F\fR\fR -.ad -.RS 6n -The free space in the partition of \fBCWD\fR, in kilobytes. -.RE - -.sp -.ne 2 -.na -\fB\fB%L\fR\fR -.ad -.RS 6n -The local host name. -.RE - -.sp -.ne 2 -.na -\fB\fB%M\fR\fR -.ad -.RS 6n -The maximum allowed number of users in this class. -.RE - -.sp -.ne 2 -.na -\fB\fB%N\fR\fR -.ad -.RS 6n -The current number of users in this class. -.RE - -.sp -.ne 2 -.na -\fB\fB%R\fR\fR -.ad -.RS 6n -The remote host name. -.RE - -.sp -.ne 2 -.na -\fB\fB%T\fR\fR -.ad -.RS 6n -The local time (form Thu Nov 15 17:12:42 1990). -.RE - -.sp -.ne 2 -.na -\fB\fB%U\fR\fR -.ad -.RS 6n -The username given at login time. -.RE - -.SH OPTIONS -.sp -.LP -The \fBftpshut\fR command supports the following options: -.sp -.ne 2 -.na -\fB\fB-V\fR\fR -.ad -.RS 10n -Display program copyright and version information, then terminate. -.RE - -.sp -.ne 2 -.na -\fB\fB-d\fR \fImin\fR\fR -.ad -.RS 10n -The time ahead of shutdown, in minutes, that existing connections will be -disconnected upon completion of their current or next (if idle) FTP request. -.RE - -.sp -.ne 2 -.na -\fB\fB-l\fR \fImin\fR\fR -.ad -.RS 10n -The time ahead of shutdown, in minutes, that new connections will be refused. -.RE - -.sp -.ne 2 -.na -\fB\fB-v\fR\fR -.ad -.RS 10n -Verbose. Output the pathname of the shutdown message files created. -.RE - -.SH OPERANDS -.sp -.LP -The \fBftpshut\fR command supports the following operands: -.sp -.ne 2 -.na -\fB\fItime\fR\fR -.ad -.RS 19n -The \fItime\fR at which \fBftpshut\fR will bring the FTP Servers down. -\fItime\fR can have a value of \fBnow\fR, which indicates an immediate -shutdown. Alternatively, \fItime\fR can specify a future time in one of two -formats: \fB+\fR\fInumber\fR or \fIHHMM\fR. The first form brings the FTP -Server down in \fInumber\fR minutes. The second brings the FTP Server down at -the time of day indicated, using a 24-hour clock format. When using the -absolute time format, you can only specify times between now and 23:59. -.RE - -.sp -.ne 2 -.na -\fB\fIwarning-message\fR\fR -.ad -.RS 19n -The message to display that warns of the imminent shutdown. The -\fIwarning-message\fR will be formatted at 70 characters wide. \fBftpshut\fR -knows the actual string length of the magic cookies. If no warning-message is -supplied, the default message "\fBSystem shutdown at %s\fR" is used. -.RE - -.SH EXIT STATUS -.sp -.LP -The following exit values are returned: -.sp -.ne 2 -.na -\fB\fB0\fR \fR -.ad -.RS 6n -Successful completion. -.RE - -.sp -.ne 2 -.na -\fB>\fB0\fR\fR -.ad -.RS 6n -An error occurred. -.RE - -.SH FILES -.sp -.ne 2 -.na -\fB\fB/etc/ftpd/ftpaccess\fR\fR -.ad -.RS 24n - -.RE - -.sp -.ne 2 -.na -\fB\fB/etc/ftpd/ftpservers\fR\fR -.ad -.RS 24n - -.RE - -.SH ATTRIBUTES -.sp -.LP -See \fBattributes\fR(5) for descriptions of the following attributes: -.sp - -.sp -.TS -box; -c | c -l | l . -ATTRIBUTE TYPE ATTRIBUTE VALUE -_ -Interface Stability External -.TE - -.SH SEE ALSO -.sp -.LP -\fBin.ftpd\fR(1M), \fBftprestart\fR(1M), \fBshutdown\fR(1M), -\fBftpaccess\fR(4), \fBftpservers\fR(4), \fBattributes\fR(5) diff --git a/usr/src/man/man1m/in.ftpd.1m b/usr/src/man/man1m/in.ftpd.1m deleted file mode 100644 index 7fc44bbfd6..0000000000 --- a/usr/src/man/man1m/in.ftpd.1m +++ /dev/null @@ -1,1230 +0,0 @@ -'\" te -.\" Copyright (C) 2004, Sun Microsystems, Inc. All Rights Reserved -.\" Copyright 1989 AT&T -.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License. -.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License. -.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner] -.TH IN.FTPD 1M "Nov 10, 2005" -.SH NAME -in.ftpd, ftpd \- File Transfer Protocol Server -.SH SYNOPSIS -.LP -.nf -\fBin.ftpd\fR [\fB-4\fR] [\fB-A\fR] [\fB-a\fR] [\fB-C\fR] [\fB-d\fR] [\fB-I\fR] [\fB-i\fR] [\fB-K\fR] [\fB-L\fR] [\fB-l\fR] - [\fB-o\fR] [\fB-P\fR \fIdataport\fR] [\fB-p\fR \fIctrlport\fR] [\fB-Q\fR] [\fB-q\fR] - [\fB-r\fR \fIrootdir\fR] [\fB-S\fR] [\fB-s\fR] [\fB-T\fR \fImaxtimeout\fR] [\fB-t\fR \fItimeout\fR] - [\fB-u\fR \fIumask\fR] [\fB-V\fR] [\fB-v\fR] [\fB-W\fR] [\fB-w\fR] [\fB-X\fR] -.fi - -.SH DESCRIPTION -.sp -.LP -\fBin.ftpd\fR is the Internet File Transfer Protocol (FTP) server process. The -server may be invoked by the Internet daemon \fBinetd\fR(1M) each time a -connection to the FTP service is made or run as a standalone server. See -\fBservices\fR(4). -.SH OPTIONS -.sp -.LP -\fBin.ftpd\fR supports the following options: -.sp -.ne 2 -.na -\fB\fB-4\fR\fR -.ad -.RS 17n -When running in standalone mode, listen for connections on an \fBAF_INET\fR -type socket. The default is to listen on an \fBAF_INET6\fR type socket. -.RE - -.sp -.ne 2 -.na -\fB\fB-a\fR\fR -.ad -.RS 17n -Enables use of the \fBftpaccess\fR(4) file. -.RE - -.sp -.ne 2 -.na -\fB\fB-A\fR\fR -.ad -.RS 17n -Disables use of the \fBftpaccess\fR(4) file. Use of \fBftpaccess\fR is disabled -by default. -.RE - -.sp -.ne 2 -.na -\fB\fB-C\fR\fR -.ad -.RS 17n -Non-anonymous users need local credentials (for example, to authenticate to -remote fileservers). So they should be prompted for a password unless they -forwarded credentials as part of authentication. -.RE - -.sp -.ne 2 -.na -\fB\fB-d\fR\fR -.ad -.RS 17n -Writes debugging information to \fBsyslogd\fR(1M). -.RE - -.sp -.ne 2 -.na -\fB\fB-i\fR\fR -.ad -.RS 17n -Logs the names of all files received by the \fBFTP\fR Server to -\fBxferlog\fR(4). You can override the \fB-i\fR option through use of the -\fBftpaccess\fR(4) file. -.RE - -.sp -.ne 2 -.na -\fB\fB-I\fR\fR -.ad -.RS 17n -Disables the use of \fBAUTH\fR and \fBident\fR to determine the username on the -client. See \fIRFC 931\fR. The \fBFTP\fR Server is built not to use \fBAUTH\fR -and \fBident\fR. -.RE - -.sp -.ne 2 -.na -\fB\fB-K\fR\fR -.ad -.RS 17n -Connections are only allowed for users who can authenticate through the -\fBftp\fR \fBAUTH\fR mechanism. (Anonymous \fBftp\fR may also be allowed if it -is configured.) \fBftpd\fR will ask the user for a password if one is required. -.RE - -.sp -.ne 2 -.na -\fB\fB-l\fR\fR -.ad -.RS 17n -Logs each \fBFTP\fR session to \fBsyslogd\fR(1M). -.RE - -.sp -.ne 2 -.na -\fB\fB-L\fR\fR -.ad -.RS 17n -Logs all commands sent to \fBin.ftpd\fR to \fBsyslogd\fR(1M). When the \fB-L\fR -option is used, command logging will be on by default, once the FTP Server is -invoked. Because the \fBFTP\fR Server includes \fBUSER\fR commands in those -logged, if a user accidentally enters a password instead of the username, the -password will be logged. You can override the \fB-L\fR option through use of -the \fBftpaccess\fR(4) file. -.RE - -.sp -.ne 2 -.na -\fB\fB-o\fR\fR -.ad -.RS 17n -Logs the names of all files transmitted by the FTP Server to \fBxferlog\fR(4). -You can override the \fB-o\fR option through use of the \fBftpaccess\fR(4) -file. -.RE - -.sp -.ne 2 -.na -\fB\fB-P\fR \fIdataport\fR\fR -.ad -.RS 17n -The FTP Server determines the port number by looking in the \fBservices\fR(4) -file for an entry for the \fBftp-data\fR service. If there is no entry, the -daemon uses the port just prior to the control connection port. Use the -\fB-P\fR option to specify the data port number. -.RE - -.sp -.ne 2 -.na -\fB\fB-p\fR \fIctrlport\fR\fR -.ad -.RS 17n -When run in standalone mode, the \fBFTP\fR Server determines the control port -number by looking in the \fBservices\fR(4) file for an entry for the \fBftp\fR -service. Use the \fB-p\fR option to specify the control port number. -.RE - -.sp -.ne 2 -.na -\fB\fB-Q\fR\fR -.ad -.RS 17n -Disables \fBPID\fR files. This disables user limits. Large, busy sites that do -not want to impose limits on the number of concurrent users can use this option -to disable \fBPID\fR files. -.RE - -.sp -.ne 2 -.na -\fB\fB-q\fR\fR -.ad -.RS 17n -Uses \fBPID\fR files. The \fBlimit\fR directive uses \fBPID\fR files to -determine the number of current users in each access class. By default, -\fBPID\fR files are used. -.RE - -.sp -.ne 2 -.na -\fB\fB-r\fR \fIrootdir\fR\fR -.ad -.RS 17n -\fBchroot\fR(2) to \fIrootdir\fR upon loading. Use this option to improve -system security. It limits the files that can be damaged should a break in -occur through the daemon. This option is similar to anonymous \fBFTP\fR. -Additional files are needed, which vary from system to system. -.RE - -.sp -.ne 2 -.na -\fB\fB-S\fR\fR -.ad -.RS 17n -Places the daemon in standalone operation mode. The daemon runs in the -background. This is useful for startup scripts that run during system -initialization. See \fBinit.d\fR(4). -.RE - -.sp -.ne 2 -.na -\fB\fB-s\fR\fR -.ad -.RS 17n -Places the daemon in standalone operation mode. The daemon runs in the -foreground. This is useful when run from \fB/etc/inittab\fR by \fBinit\fR(1M). -.RE - -.sp -.ne 2 -.na -\fB\fB-T\fR \fImaxtimeout\fR\fR -.ad -.RS 17n -Sets the maximum allowable timeout period to \fImaxtimeout\fR seconds. The -default maximum timeout limit is 7200 second (two hours). You can override the -\fB-T\fR option through use of the \fBftpaccess\fR(4) file. -.RE - -.sp -.ne 2 -.na -\fB\fB-t\fR \fItimeout\fR\fR -.ad -.RS 17n -Sets the inactivity timeout period to \fItimeout\fR seconds. The default -timeout period is 900 seconds (15 minutes). You can override the \fB-t\fR -option through use of the \fBftpaccess\fR(4) file. -.RE - -.sp -.ne 2 -.na -\fB\fB-u\fR \fIumask\fR\fR -.ad -.RS 17n -Sets the default \fBumask\fR to \fIumask\fR. -.RE - -.sp -.ne 2 -.na -\fB\fB-V\fR\fR -.ad -.RS 17n -Displays copyright and version information, then terminate. -.RE - -.sp -.ne 2 -.na -\fB\fB-v\fR\fR -.ad -.RS 17n -Writes debugging information to \fBsyslogd\fR(1M). -.RE - -.sp -.ne 2 -.na -\fB\fB-W\fR\fR -.ad -.RS 17n -Does not record user \fBlogin\fR and \fBlogout\fR in the \fBwtmpx\fR(4) file. -.RE - -.sp -.ne 2 -.na -\fB\fB-w\fR\fR -.ad -.RS 17n -Records each user \fBlogin\fR and \fBlogout\fR in the \fBwtmpx\fR(4) file. By -default, logins and logouts are recorded. -.RE - -.sp -.ne 2 -.na -\fB\fB-X\fR\fR -.ad -.RS 17n -Writes the output from the \fB-i\fR and \fB-o\fR options to the -\fBsyslogd\fR(1M) file instead of \fBxferlog\fR(4). This allows the collection -of output from several hosts on one central loghost. You can override the -\fB-X\fR option through use of the \fBftpaccess\fR(4) file. -.RE - -.SS "Requests" -.sp -.LP -The FTP Server currently supports the following \fBFTP\fR requests. Case is not -distinguished. -.sp -.ne 2 -.na -\fB\fBABOR\fR\fR -.ad -.RS 8n -Abort previous command. -.RE - -.sp -.ne 2 -.na -\fB\fBADAT\fR\fR -.ad -.RS 8n -Send an authentication protocol message. -.RE - -.sp -.ne 2 -.na -\fB\fBALLO\fR\fR -.ad -.RS 8n -Allocate storage (vacuously). -.RE - -.sp -.ne 2 -.na -\fB\fBAUTH\fR\fR -.ad -.RS 8n -Specify an authentication protocol to be performed. Currently only -"\fBGSSAPI\fR" is supported. -.RE - -.sp -.ne 2 -.na -\fB\fBAPPE\fR\fR -.ad -.RS 8n -Append to a file. -.RE - -.sp -.ne 2 -.na -\fB\fBCCC\fR\fR -.ad -.RS 8n -Set the command channel protection mode to "\fBClear\fR" (no protection). Not -allowed if data channel is protected. -.RE - -.sp -.ne 2 -.na -\fB\fBCDUP\fR\fR -.ad -.RS 8n -Change to parent of current working directory. -.RE - -.sp -.ne 2 -.na -\fB\fBCWD\fR\fR -.ad -.RS 8n -Change working directory. -.RE - -.sp -.ne 2 -.na -\fB\fBDELE\fR\fR -.ad -.RS 8n -Delete a file. -.RE - -.sp -.ne 2 -.na -\fB\fBENC\fR\fR -.ad -.RS 8n -Send a privacy and integrity protected command (given in argument). -.RE - -.sp -.ne 2 -.na -\fB\fBEPRT\fR\fR -.ad -.RS 8n -Specify extended address for the transport connection. -.RE - -.sp -.ne 2 -.na -\fB\fBEPSV\fR\fR -.ad -.RS 8n -Extended passive command request. -.RE - -.sp -.ne 2 -.na -\fB\fBHELP\fR\fR -.ad -.RS 8n -Give help information. -.RE - -.sp -.ne 2 -.na -\fB\fBLIST\fR\fR -.ad -.RS 8n -Give list files in a directory (\fBls\fR \fB-lA\fR). -.RE - -.sp -.ne 2 -.na -\fB\fBLPRT\fR\fR -.ad -.RS 8n -Specify long address for the transport connection. -.RE - -.sp -.ne 2 -.na -\fB\fBLPSV\fR\fR -.ad -.RS 8n -Long passive command request. -.RE - -.sp -.ne 2 -.na -\fB\fBMIC\fR\fR -.ad -.RS 8n -Send an integrity protected command (given in argument). -.RE - -.sp -.ne 2 -.na -\fB\fBMKD\fR\fR -.ad -.RS 8n -Make a directory. -.RE - -.sp -.ne 2 -.na -\fB\fBMDTM\fR\fR -.ad -.RS 8n -Show last time file modified. -.RE - -.sp -.ne 2 -.na -\fB\fBMODE\fR\fR -.ad -.RS 8n -Specify data transfer \fImode\fR. -.RE - -.sp -.ne 2 -.na -\fB\fBNLST\fR\fR -.ad -.RS 8n -Give name list of files in directory (\fBls\fR). -.RE - -.sp -.ne 2 -.na -\fB\fBNOOP\fR\fR -.ad -.RS 8n -Do nothing. -.RE - -.sp -.ne 2 -.na -\fB\fBPASS\fR\fR -.ad -.RS 8n -Specify password. -.RE - -.sp -.ne 2 -.na -\fB\fBPASV\fR\fR -.ad -.RS 8n -Prepare for server-to-server transfer. -.RE - -.sp -.ne 2 -.na -\fB\fBPBSZ\fR\fR -.ad -.RS 8n -Specify a protection buffer size. -.RE - -.sp -.ne 2 -.na -\fB\fBPROT\fR\fR -.ad -.RS 8n -Specify a protection level under which to protect data transfers. Allowed -arguments: -.sp -.ne 2 -.na -\fB\fBclear\fR\fR -.ad -.RS 11n -No protection. -.RE - -.sp -.ne 2 -.na -\fB\fBsafe\fR\fR -.ad -.RS 11n -Integrity protection -.RE - -.sp -.ne 2 -.na -\fB\fBprivate\fR\fR -.ad -.RS 11n -Integrity and encryption protection -.RE - -.RE - -.sp -.ne 2 -.na -\fB\fBPORT\fR\fR -.ad -.RS 8n -Specify data connection port. -.RE - -.sp -.ne 2 -.na -\fB\fBPWD\fR\fR -.ad -.RS 8n -Print the current working directory. -.RE - -.sp -.ne 2 -.na -\fB\fBQUIT\fR\fR -.ad -.RS 8n -Terminate session. -.RE - -.sp -.ne 2 -.na -\fB\fBREST\fR\fR -.ad -.RS 8n -Restart incomplete transfer. -.RE - -.sp -.ne 2 -.na -\fB\fBRETR\fR\fR -.ad -.RS 8n -Retrieve a file. -.RE - -.sp -.ne 2 -.na -\fB\fBRMD\fR\fR -.ad -.RS 8n -Remove a directory. -.RE - -.sp -.ne 2 -.na -\fB\fBRNFR\fR\fR -.ad -.RS 8n -Specify rename-from file name. -.RE - -.sp -.ne 2 -.na -\fB\fBRNTO\fR\fR -.ad -.RS 8n -Specify rename-to file name. -.RE - -.sp -.ne 2 -.na -\fB\fBSITE\fR\fR -.ad -.RS 8n -Use nonstandard commands. -.RE - -.sp -.ne 2 -.na -\fB\fBSIZE\fR\fR -.ad -.RS 8n -Return size of file. -.RE - -.sp -.ne 2 -.na -\fB\fBSTAT\fR\fR -.ad -.RS 8n -Return status of server. -.RE - -.sp -.ne 2 -.na -\fB\fBSTOR\fR\fR -.ad -.RS 8n -Store a file. -.RE - -.sp -.ne 2 -.na -\fB\fBSTOU\fR\fR -.ad -.RS 8n -Store a file with a unique name. -.RE - -.sp -.ne 2 -.na -\fB\fBSTRU\fR\fR -.ad -.RS 8n -Specify data transfer \fIstructure\fR. -.RE - -.sp -.ne 2 -.na -\fB\fBSYST\fR\fR -.ad -.RS 8n -Show operating system type of server system. -.RE - -.sp -.ne 2 -.na -\fB\fBTYPE\fR\fR -.ad -.RS 8n -Specify data transfer \fBtype\fR. -.RE - -.sp -.ne 2 -.na -\fB\fBUSER\fR\fR -.ad -.RS 8n -Specify user name. -.RE - -.sp -.ne 2 -.na -\fB\fBXCUP\fR\fR -.ad -.RS 8n -Change to parent of current working directory. This request is deprecated. -.RE - -.sp -.ne 2 -.na -\fB\fBXCWD\fR\fR -.ad -.RS 8n -Change working directory. This request is deprecated. -.RE - -.sp -.ne 2 -.na -\fB\fBXMKD\fR\fR -.ad -.RS 8n -Make a directory. This request is deprecated. -.RE - -.sp -.ne 2 -.na -\fB\fBXPWD\fR\fR -.ad -.RS 8n -Print the current working directory. This request is deprecated. -.RE - -.sp -.ne 2 -.na -\fB\fBXRMD\fR\fR -.ad -.RS 8n -Remove a directory. This request is deprecated. -.RE - -.sp -.LP -The following nonstandard or UNIX specific commands are supported by the -\fBSITE\fR request: -.sp -.ne 2 -.na -\fB\fBALIAS\fR\fR -.ad -.RS 15n -List aliases. -.RE - -.sp -.ne 2 -.na -\fB\fBCDPATH\fR\fR -.ad -.RS 15n -List the search path used when changing directories. -.RE - -.sp -.ne 2 -.na -\fB\fBCHECKMETHOD\fR\fR -.ad -.RS 15n -List or set the \fBchecksum\fR method. -.RE - -.sp -.ne 2 -.na -\fB\fBCHECKSUM\fR\fR -.ad -.RS 15n -Give the \fBchecksum\fR of a file. -.RE - -.sp -.ne 2 -.na -\fB\fBCHMOD\fR\fR -.ad -.RS 15n -Change mode of a file. For example, \fBSITE CHMOD 755 \fIfilename\fR\fR. -.RE - -.sp -.ne 2 -.na -\fB\fBEXEC\fR\fR -.ad -.RS 15n -Execute a program. For example, \fBSITE EXEC program params\fR -.RE - -.sp -.ne 2 -.na -\fB\fBGPASS\fR\fR -.ad -.RS 15n -Give special group access password. For example, \fBSITE GPASS bar\fR. -.RE - -.sp -.ne 2 -.na -\fB\fBGROUP\fR\fR -.ad -.RS 15n -Request special group access. For example, \fBSITE GROUP foo\fR. -.RE - -.sp -.ne 2 -.na -\fB\fBGROUPS\fR\fR -.ad -.RS 15n -List supplementary group membership. -.RE - -.sp -.ne 2 -.na -\fB\fBHELP\fR\fR -.ad -.RS 15n -Give help information. For example, \fBSITE HELP\fR. -.RE - -.sp -.ne 2 -.na -\fB\fBIDLE\fR\fR -.ad -.RS 15n -Set idle-timer. For example, \fBSITE IDLE 60\fR. -.RE - -.sp -.ne 2 -.na -\fB\fBUMASK\fR\fR -.ad -.RS 15n -Change \fBumask\fR. For example, \fBSITE UMASK 002\fR. -.RE - -.sp -.LP -The remaining FTP requests specified in \fIRFC 959\fR are recognized, but not -implemented. -.sp -.LP -The \fBFTP\fR server will abort an active file transfer only when the -\fBABOR\fR command is preceded by a Telnet "Interrupt Process" (IP) signal and -a Telnet "Synch" signal in the command Telnet stream, as described in \fIRFC -959\fR. If a \fBSTAT\fR command is received during a data transfer that has -been preceded by a Telnet IP and Synch, transfer status will be returned. -.sp -.LP -\fBin.ftpd\fR interprets file names according to the "globbing" conventions -used by \fBcsh\fR(1). This allows users to utilize the metacharacters: \fB* ? [ -] { } ~\fR -.sp -.LP -\fBin.ftpd\fR authenticates users according to the following rules: -.sp -.LP -First, the user name must be in the password data base, the location of which -is specified in \fBnsswitch.conf\fR(4). An encrypted password (an -authentication token in PAM) must be present. A password must always be -provided by the client before any file operations can be performed. For -non-anonymous users, the PAM framework is used to verify that the correct -password was entered. See \fBSECURITY\fR below. -.sp -.LP -Second, the user name must not appear in either the \fB/etc/ftpusers\fR or the -\fB/etc/ftpd/ftpusers\fR file. Use of the \fB/etc/ftpusers\fR files is -deprecated, although it is still supported. -.sp -.LP -Third, the users must have a standard shell returned by \fBgetusershell\fR(3C). -.sp -.LP -Fourth, if the user name is \fBanonymous\fR or \fBftp\fR, an anonymous ftp -account must be present in the password file for user \fBftp\fR. Use -\fBftpconfig\fR(1M) to create the anonymous \fBftp\fR account and home -directory tree. -.sp -.LP -Fifth, if the GSS-API is used to authenticate the user, then -\fBgss_auth_rules\fR(5) determines user access without a password needed. -.sp -.LP -The FTP Server supports virtual hosting, which can be configured by using -\fBftpaddhost\fR(1M). -.sp -.LP -The FTP Server does not support sublogins. -.SS "General FTP Extensions" -.sp -.LP -The FTP Server has certain extensions. If the user specifies a filename that -does not exist with a \fBRETR\fR (retrieve) command, the FTP Server looks for a -conversion to change a file or directory that does into the one requested. See -\fBftpconversions\fR(4). -.sp -.LP -By convention, anonymous users supply their email address when prompted for a -password. The FTP Server attempts to validate these email addresses. A user -whose FTP client hangs on a long reply, for example, a multiline response, -should use a dash (-) as the first character of the user's password, as this -disables the Server's \fBlreply()\fR function. -.sp -.LP -The FTP Server can also log all file transmission and reception. See -\fBxferlog\fR(4) for details of the log file format. -.sp -.LP -The \fBSITE EXEC\fR command may be used to execute commands in the -\fB/bin/ftp-exec\fR directory. Take care that you understand the security -implications before copying any command into the \fB/bin/ftp-exec\fR directory. -For example, do not copy in \fB/bin/sh\fR. This would enable the user to -execute other commands through the use of \fBsh -c\fR. If you have doubts about -this feature, do not create the \fB/bin/ftp-exec\fR directory. -.SH SECURITY -.sp -.LP -For non-anonymous users, \fBin.ftpd\fR uses \fBpam\fR(3PAM) for authentication, -account management, and session management, and can use Kerberos v5 for -authentication. -.sp -.LP -The \fBPAM\fR configuration policy, listed through \fB/etc/pam.conf\fR, -specifies the module to be used for \fBin.ftpd\fR. Here is a partial -\fBpam.conf\fR file with entries for the \fBin.ftpd\fR command using the UNIX -authentication, account management, and session management module. -.sp -.in +2 -.nf -ftp auth requisite pam_authtok_get.so.1 -ftp auth required pam_dhkeys.so.1 -ftp auth required pam_unix_auth.so.1 - -ftp account required pam_unix_roles.so.1 -ftp account required pam_unix_projects.so.1 -ftp account required pam_unix_account.so.1 - -ftp session required pam_unix_session.so.1 -.fi -.in -2 - -.sp -.LP -If there are no entries for the \fBftp\fR service, then the entries for the -"other" service will be used. Unlike \fBlogin\fR, \fBpasswd\fR, and other -commands, the \fBftp\fR protocol will only support a single password. Using -multiple modules will prevent \fBin.ftpd\fR from working properly. -.sp -.LP -To use Kerberos for authentication, a \fBhost/\fR\fI\fR Kerberos -principal must exist for each Fully Qualified Domain Name associated with the -\fBin.ftpd\fR server. Each of these \fBhost/\fR\fI\fR principals must -have a \fBkeytab\fR entry in the \fB/etc/krb5/krb5.keytab\fR file on the -\fBin.ftpd\fR server. An example principal might be: -.sp -.LP -\fBhost/bigmachine.eng.example.com\fR -.sp -.LP -See \fBkadmin\fR(1M) or \fBgkadmin\fR(1M) for instructions on adding a -principal to a \fBkrb5.keytab\fR file. See \fI\fR for a discussion of Kerberos -authentication. -.sp -.LP -For anonymous users, who by convention supply their email address as a -password, \fBin.ftpd\fR validates passwords according to the \fBpasswd-check\fR -capability in the \fBftpaccess\fR file. -.SH USAGE -.sp -.LP -The \fBin.ftpd\fR command is IPv6-enabled. See \fBip6\fR(7P). -.SH FILES -.sp -.ne 2 -.na -\fB\fB/etc/ftpd/ftpaccess\fR\fR -.ad -.sp .6 -.RS 4n -FTP Server configuration file -.RE - -.sp -.ne 2 -.na -\fB\fB/etc/ftpd/ftpconversions\fR\fR -.ad -.sp .6 -.RS 4n -FTP Server conversions database -.RE - -.sp -.ne 2 -.na -\fB\fB/etc/ftpd/ftpgroups\fR\fR -.ad -.sp .6 -.RS 4n -FTP Server enhanced group access file -.RE - -.sp -.ne 2 -.na -\fB\fB/etc/ftpd/ftphosts\fR\fR -.ad -.sp .6 -.RS 4n -FTP Server individual user host access file -.RE - -.sp -.ne 2 -.na -\fB\fB/etc/ftpd/ftpservers\fR\fR -.ad -.sp .6 -.RS 4n -FTP Server virtual hosting configuration file. -.RE - -.sp -.ne 2 -.na -\fB\fB/etc/ftpd/ftpusers\fR\fR -.ad -.sp .6 -.RS 4n -File listing users for whom FTP login privileges are disallowed. -.RE - -.sp -.ne 2 -.na -\fB\fB/etc/ftpusers\fR\fR -.ad -.sp .6 -.RS 4n -File listing users for whom FTP login privileges are disallowed. This use of -this file is deprecated. -.RE - -.sp -.ne 2 -.na -\fB\fB/var/log/xferlog\fR\fR -.ad -.sp .6 -.RS 4n -FTP Server transfer log file -.RE - -.sp -.ne 2 -.na -\fB\fB/var/run/ftp.pids-\fIclassname\fR\fR\fR -.ad -.sp .6 -.RS 4n - -.RE - -.sp -.ne 2 -.na -\fB\fB/var/adm/wtmpx\fR\fR -.ad -.sp .6 -.RS 4n -Extended database files that contain the history of user access and accounting -information for the \fBwtmpx\fR database. -.RE - -.SH ATTRIBUTES -.sp -.LP -See \fBattributes\fR(5) for descriptions of the following attributes: -.sp - -.sp -.TS -box; -c | c -l | l . -ATTRIBUTE TYPE ATTRIBUTE VALUE -_ -Interface Stability External -.TE - -.SH SEE ALSO -.sp -.LP -\fBcsh\fR(1), \fBftp\fR(1), \fBftpcount\fR(1), \fBftpwho\fR(1), \fBls\fR(1), -\fBsvcs\fR(1), \fBftpaddhost\fR(1M), \fBftpconfig\fR(1M), \fBftprestart\fR(1M), -\fBftpshut\fR(1M), \fBgkadmin\fR(1M), \fBinetadm\fR(1M), \fBinetd\fR(1M), -\fBkadmin\fR(1M), \fBsvcadm\fR(1M), \fBsyslogd\fR(1M), \fBchroot\fR(2), -\fBumask\fR(2), \fBgetpwent\fR(3C), \fBgetusershell\fR(3C), \fBsyslog\fR(3C), -\fBftpaccess\fR(4), \fBftpconversions\fR(4), \fBftpgroups\fR(4), -\fBftphosts\fR(4), \fBftpservers\fR(4), \fBftpusers\fR(4), \fBgroup\fR(4), -\fBpasswd\fR(4), \fBservices\fR(4), \fBxferlog\fR(4), \fBwtmpx\fR(4), -\fBattributes\fR(5), \fBgss_auth_rules\fR(5), \fBpam_authtok_check\fR(5), -\fBpam_authtok_get\fR(5), \fBpam_authtok_store\fR(5), \fBpam_dhkeys\fR(5), -\fBpam_passwd_auth\fR(5), \fBpam_unix_account\fR(5), \fBpam_unix_auth\fR(5), -\fBpam_unix_session\fR(5), \fBsmf\fR(5), \fBip6\fR(7P) -.sp -.LP -\fI\fR -.sp -.LP -Allman, M., Ostermann, S., and Metz, C. \fIRFC 2428, FTP Extensions for IPv6 -and NATs\fR. The Internet Society. September 1998. -.sp -.LP -Piscitello, D. \fIRFC 1639, FTP Operation Over Big Address Records (FOOBAR)\fR. -Network Working Group. June 1994. -.sp -.LP -Postel, Jon, and Joyce Reynolds. \fIRFC 959, File Transfer Protocol (FTP )\fR. -Network Information Center. October 1985. -.sp -.LP -St. Johns, Mike. \fIRFC 931, Authentication Server\fR. Network Working Group. -January 1985. -.sp -.LP -Linn, J., \fIGeneric Security Service Application Program Interface Version 2, -Update 1, RFC 2743.\fR The Internet Society, January 2000. -.sp -.LP -Horowitz, M., Lunt, S., \fIFTP Security Extensions, RFC 2228\fR. The Internet -Society, October 1997. -.SH DIAGNOSTICS -.sp -.LP -\fBin.ftpd\fR logs various errors to \fBsyslogd\fR(1M), with a facility code of -daemon. -.SH NOTES -.sp -.LP -The anonymous \fBFTP\fR account is inherently dangerous and should be avoided -when possible. -.sp -.LP -The \fBFTP\fR Server must perform certain tasks as the superuser, for example, -the creation of sockets with privileged port numbers. It maintains an effective -user \fBID\fR of the logged in user, reverting to the superuser only when -necessary. -.sp -.LP -The \fBFTP\fR Server no longer supports the \fB/etc/default/ftpd\fR file. -Instead of using \fBUMASK=nnn\fR to set the umask, use the \fBdefumask\fR -capability in the \fBftpaccess\fR file. The banner greeting text capability is -also now set through the \fBftpaccess\fR file by using the greeting text -capability instead of by using \fBBANNER="..."\fR. However, unlike the -\fBBANNER\fR string, the greeting text string is not passed to the shell for -evaluation. See \fBftpaccess\fR(4). -.sp -.LP -The \fBpam_unix\fR(5) module is no longer supported. Similar functionality is -provided by \fBpam_authtok_check\fR(5), \fBpam_authtok_get\fR(5), -\fBpam_authtok_store\fR(5), \fBpam_dhkeys\fR(5), \fBpam_passwd_auth\fR(5), -\fBpam_unix_account\fR(5), \fBpam_unix_auth\fR(5), and -\fBpam_unix_session\fR(5). -.sp -.LP -The \fBin.ftpd\fR service is managed by the service management facility, -\fBsmf\fR(5), under the service identifier: -.sp -.in +2 -.nf -svc:/network/ftp -.fi -.in -2 -.sp - -.sp -.LP -Administrative actions on this service, such as enabling, disabling, or -requesting restart, can be performed using \fBsvcadm\fR(1M). Responsibility for -initiating and restarting this service is delegated to \fBinetd\fR(1M). Use -\fBinetadm\fR(1M) to make configuration changes and to view configuration -information for this service. The service's status can be queried using the -\fBsvcs\fR(1) command. diff --git a/usr/src/man/man1m/mknod.1m b/usr/src/man/man1m/mknod.1m index 79111ed71e..11c599eec1 100644 --- a/usr/src/man/man1m/mknod.1m +++ b/usr/src/man/man1m/mknod.1m @@ -23,11 +23,9 @@ mknod \- make a special file .fi .SH DESCRIPTION -.sp .LP \fBmknod\fR makes a directory entry for a special file. .SH OPTIONS -.sp .LP The following options are supported: .sp @@ -58,7 +56,6 @@ Create a FIFO (named pipe). .RE .SH OPERANDS -.sp .LP The following operands are supported: .sp @@ -91,17 +88,14 @@ A special file to be created. .RE .SH USAGE -.sp .LP See \fBlargefile\fR(5) for the description of the behavior of \fBmknod\fR when encountering files greater than or equal to 2 Gbyte ( 2^31 bytes). .SH SEE ALSO -.sp .LP -\fBftp\fR(1), \fBin.ftpd\fR(1M), \fBmknod\fR(2), \fBsymlink\fR(2), +\fBftp\fR(1), \fBmknod\fR(2), \fBsymlink\fR(2), \fBattributes\fR(5), \fBlargefile\fR(5) .SH NOTES -.sp .LP If \fBmknod\fR(2) is used to create a device, the major and minor device numbers are always interpreted by the kernel running on that machine. diff --git a/usr/src/man/man1m/sftp-server.1m b/usr/src/man/man1m/sftp-server.1m index 48c4b62c44..c258aa81fb 100644 --- a/usr/src/man/man1m/sftp-server.1m +++ b/usr/src/man/man1m/sftp-server.1m @@ -12,7 +12,6 @@ sftp-server \- SFTP server subsystem .fi .SH DESCRIPTION -.sp .LP \fBsftp-server\fR implements the server side of the SSH File Transfer Protocol as defined in the IETF \fBdraft-ietf-secsh-filexfer\fR. @@ -40,9 +39,8 @@ file. .sp .LP There is no relationship between the protocol used by \fBsftp-server\fR and the -FTP protocol (RFC 959) provided by \fBin.ftpd\fR. +FTP protocol (RFC 959). .SH OPTIONS -.sp .LP Valid options are listed below. As stated above, these are to be specified in the Subsystem declation of \fBsshd_config\fR. @@ -77,7 +75,6 @@ client. \fBDEBUG\fR and \fBDEBUG1\fR are equivalent. \fBDEBUG2\fR and .RE .SH EXIT STATUS -.sp .LP The following exit values are returned: .sp @@ -99,7 +96,6 @@ An error occurred. .RE .SH FILES -.sp .ne 2 .na \fB\fB/usr/lib/ssh/sftp-server\fR\fR @@ -109,7 +105,6 @@ Server-side binary. .RE .SH ATTRIBUTES -.sp .LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -125,7 +120,6 @@ Interface Stability Evolving .TE .SH SEE ALSO -.sp .LP \fBsftp\fR(1), \fBssh\fR(1), \fBssh-add\fR(1), \fBssh-keygen\fR(1), \fBsshd\fR(1M), \fBsshd_config\fR(4), \fBattributes\fR(5) diff --git a/usr/src/man/man3c/syslog.3c b/usr/src/man/man3c/syslog.3c index d3ca5cdd4e..3a3b78a583 100644 --- a/usr/src/man/man3c/syslog.3c +++ b/usr/src/man/man3c/syslog.3c @@ -34,7 +34,6 @@ syslog, openlog, closelog, setlogmask \- control system log .fi .SH DESCRIPTION -.sp .LP The \fBsyslog()\fR function sends a message to \fBsyslogd\fR(1M), which, depending on the configuration of \fB/etc/syslog.conf\fR, logs it in an @@ -177,7 +176,7 @@ The mail system. \fB\fBLOG_DAEMON\fR\fR .ad .RS 14n -System daemons, such as \fBin.ftpd\fR(1M). +System daemons. .RE .sp @@ -394,12 +393,10 @@ macro \fBLOG_MASK(\fIpri\fR)\fR; the mask for all priorities up to and including \fItoppri\fR is given by the macro \fBLOG_UPTO(\fItoppri\fR)\fR. The default log mask allows all priorities to be logged. .SH RETURN VALUES -.sp .LP The \fBsetlogmask()\fR function returns the previous log priority mask. The \fBcloselog()\fR, \fBopenlog()\fR and \fBsyslog()\fR functions return no value. .SH ERRORS -.sp .LP No errors are defined. .SH EXAMPLES @@ -475,7 +472,6 @@ other messages to the facility \fBLOG_LOCAL2\fR are: .sp .SH ATTRIBUTES -.sp .LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -495,9 +491,8 @@ Standard See \fBstandards\fR(5). .TE .SH SEE ALSO -.sp .LP \fBat\fR(1), \fBcrontab\fR(1), \fBlogger\fR(1), \fBlogin\fR(1), \fBlpc\fR(1B), \fBlpr\fR(1B), \fBauditd\fR(1M), \fBcron\fR(1M), \fBgetty\fR(1M), -\fBin.ftpd\fR(1M), \fBsu\fR(1M), \fBsyslogd\fR(1M), \fBprintf\fR(3UCB), +\fBsu\fR(1M), \fBsyslogd\fR(1M), \fBprintf\fR(3UCB), \fBsyslog.conf\fR(4), \fBattributes\fR(5), \fBstandards\fR(5) diff --git a/usr/src/man/man4/Makefile b/usr/src/man/man4/Makefile index cc3561746d..cb69ee7dad 100644 --- a/usr/src/man/man4/Makefile +++ b/usr/src/man/man4/Makefile @@ -70,11 +70,6 @@ _MANFILES= Intro.4 \ fspec.4 \ fstypes.4 \ ftp.4 \ - ftpaccess.4 \ - ftpconversions.4 \ - ftpgroups.4 \ - ftphosts.4 \ - ftpservers.4 \ ftpusers.4 \ fx_dptbl.4 \ gateways.4 \ @@ -210,7 +205,6 @@ _MANFILES= Intro.4 \ volume-request.4 \ wanboot.conf.4 \ warn.conf.4 \ - xferlog.4 \ ypfiles.4 \ yppasswdd.4 \ ypserv.4 \ diff --git a/usr/src/man/man4/ftpaccess.4 b/usr/src/man/man4/ftpaccess.4 deleted file mode 100644 index 5c6b29c0e0..0000000000 --- a/usr/src/man/man4/ftpaccess.4 +++ /dev/null @@ -1,2086 +0,0 @@ -'\" te -.\" Copyright (C) 2003, Sun Microsystems, Inc. All Rights Reserved -.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License. -.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License. -.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner] -.TH FTPACCESS 4 "Sep 10, 2003" -.SH NAME -ftpaccess \- FTP Server configuration file -.SH SYNOPSIS -.LP -.nf -\fB/etc/ftpd/ftpaccess\fR -.fi - -.SH DESCRIPTION -.sp -.LP -The \fBftpaccess\fR file is used to configure the operation of the FTP Server. -.SS "Access Capabilities " -.sp -.LP -The following access capabilities are supported: -.sp -.ne 2 -.na -\fB\fBautogroup\fR \fIgroupname\fR \fIclass\fR \fIclass\fR...\fR -.ad -.sp .6 -.RS 4n -If an \fIanonymous\fR user is a member of any of \fIclass\fR, the FTP Server -will perform a \fBsetegid\fR(2) to \fIgroupname\fR. This allows access to group -and owner read-only files and directories to a particular class of anonymous -users. \fIgroupname\fR is a valid group returned by \fBgetgrnam\fR(3C). -.RE - -.sp -.ne 2 -.na -\fB\fBclass\fR \fIclass\fR \fItypelist\fR \fIaddrglob\fR\fIaddrglob\fR...\fR -.ad -.sp .6 -.RS 4n -Define \fIclass\fR of users, with source addresses of the form \fIaddrglob\fR. -Multiple members of \fIclass\fR may be defined. There may be multiple -\fBclass\fR commands listing additional members of the class. If multiple -\fBclass\fR commands can apply to the current session, the first one listed in -the access file is used. If a valid class for a host is not defined, access -will be denied. \fItypelist\fR is a comma-separated list of any of the keywords -\fBanonymous\fR, \fBguest\fR, and \fBreal\fR. If the \fBreal\fR keyword is -included, the class can match users using FTP to access real accounts. If the -\fBanonymous\fR keyword is included the class can match users using anonymous -FTP. The \fBguest\fR keyword matches guest access accounts. -.sp -\fIaddrglob\fR may be a globbed domain name or a globbed numeric IPv4 address. -It may also be the name of a file, starting with a slash ('/'), which contains -additional address globs. IPv4 numeric addresses may also be specified in the -form \fBaddress:netmask\fR or \fBaddress/CIDR\fR. IPv6 numeric addresses can -only be specified with an optional \fBCIDR\fR, not using globs or netmasks. -.sp -Placing an exclamation (!) before an \fIaddrglob\fR negates the test. For -example, -.sp -.in +2 -.nf -class rmtuser real !*.example.com -.fi -.in -2 - -will classify real users from outside the \fBexample.com\fR domain as the class -\fBrmtuser\fR. Use care with this option. Remember, the result of each test is -OR'ed with other tests on the line. -.RE - -.sp -.ne 2 -.na -\fB\fBdeny\fR \fIaddrglob\fR [\fImessage_file\fR]\fR -.ad -.sp .6 -.RS 4n -Deny access to host(s) that match \fIaddrglob\fR and display -\fImessage_file\fR. If the value of \fIaddrglob\fR is \fB!nameserved\fR access -to sites without a working nameservers is denied. \fImessage_file\fR may -contain magic cookies. See \fBmessage\fR for more details. -.RE - -.sp -.ne 2 -.na -\fB\fBguestgroup\fR \fIgroupname\fR \fIgroupname\fR...\fR -.ad -.br -.na -\fB\fBguestuser\fR \fIusername\fR \fIusername\fR...\fR -.ad -.br -.na -\fB\fBrealgroup\fR \fIgroupname\fR \fIgroupname\fR...\fR -.ad -.br -.na -\fB\fBrealuser\fR \fIusername\fR \fIusername\fR...\fR -.ad -.sp .6 -.RS 4n -For \fBguestgroup\fR, if a \fIreal\fR user is a member of any \fIgroupname\fR, -the session is set up like anonymous FTP. \fIgroupname\fR is a valid group -returned by \fBgetgrnam\fR(3C). The user's home directory must be set up -exactly as anonymous FTP would be. The home directory field of the passwd entry -is divided into two directories. The first field is the root directory that -will be the argument to the \fBchroot\fR(2) call. The second field is the -user's home directory, relative to the root directory. Use a "\fB/./\fR" to -separate the two fields. For example, the following is the real entry in -\fB/etc/passwd\fR: -.sp -.in +2 -.nf -guest1:x:100:92:Guest FTP:/export/home/guests/./guest1:/bin/true -.fi -.in -2 - -When guest1 successfully logs in, the FTP Server will \fBchroot()\fR to -\fB/export/home/guests\fR and then \fBchdir\fR(2) to \fB/guest1\fR. The guest -user will only be able to access the directory structure under -\fB/export/home/guests\fR, which will look and act as \fB/\fR to \fBguest1\fR, -just as an anonymous FTP user would. The d option to \fBftpconfig\fR(1M) is -useful when creating guest FTP user accounts. The group name may be specified -by either name or numeric ID. To use a numeric group ID, place a percent sign -(\fB%\fR) before the number. You can give ranges. Use an asterisk to indicate -all groups. \fBguestuser\fR works like \fBguestgroup\fR, except that it uses -the user name or numeric ID. \fBrealuser\fR and \fBrealgroup\fR have the same -syntax, but they reverse the effect of \fBguestuser\fR and \fBguestgroup\fR. -They allow real user access when the remote user would otherwise be determined -a guest. -.sp -.in +2 -.nf -guestuser * -realgroup admin -.fi -.in -2 - -causes all non-anonymous users to be treated as guest, with the sole exception -of users in the \fBadmin\fR group, who are granted real user access. -.RE - -.sp -.ne 2 -.na -\fB\fBnice\fR \fInice-delta\fR \fIclass\fR\fR -.ad -.sp .6 -.RS 4n -Adjust the process \fBnice\fR value of the FTP server process by the indicated -\fInice-delta\fR value if the remote user is a member of the named \fIclass\fR. -If \fIclass\fR is not specified, then use \fInice-delta\fR as the default -adjustment to the FTP server process \fBnice\fR value. This default \fBnice\fR -value adjustment is used to adjust the \fBnice\fR value of the server process -only for those users who do not belong to any class for which a class-specific -\fBnice\fR directive exists in the \fBftpaccess\fR file. -.RE - -.sp -.ne 2 -.na -\fB\fBdefumask\fR \fIumask\fR \fIclass\fR\fR -.ad -.sp .6 -.RS 4n -Set the \fIumask\fR applied to files created by the FTP server if the remote -user is a member of the named class. If \fIclass\fR is not specified, then use -the \fIumask\fR as the default for classes that do not have one specified.. The -mode of files created may be specified by using the \fBupload\fR directive. -.RE - -.sp -.ne 2 -.na -\fB\fBtcpwindow\fR \fIsize\fR class\fR -.ad -.sp .6 -.RS 4n -Set the TCP window size (socket buffer size) for the data connection. Use this -to control network traffic. For instance, slow PPP dialin links may need -smaller TCP windows to speed up throughput. If you do not know what this does, -do not set it. -.RE - -.sp -.ne 2 -.na -\fB\fBipcos\fR control|data \fIvalue\fR [\fItypelist\fR]\fR -.ad -.sp .6 -.RS 4n -Set the IP Class of Service for either the control or data connection. -.sp -For connections using \fBAF_INET\fR type sockets, this sets the Type of Service -field in the IP header to the value specified. -.sp -For connections using \fBAF_INET6\fR type sockets, this sets the Traffic Class -field in the IP header to the value specified. -.sp -When configured through \fBinetd.conf\fR(4), the socket type is controlled by -the protocol field of the \fBftp\fR service. When running in standalone mode -the default socket type is \fBAF_INET6\fR. The \fBin.ftpd\fR(1M) 4 option -selects \fBAF_INET\fR. -.sp -\fItypelist\fR is a comma-separated list of any of the keywords -\fBanonymous\fR, \fBguest\fR, \fBreal\fR, and \fBclass=\fR. When \fBclass=\fR -appears, it must be followed by a class name. -.RE - -.sp -.ne 2 -.na -\fB\fBkeepalive\fR \fByes\fR|\fBno\fR\fR -.ad -.sp .6 -.RS 4n -Set the TCP \fBSO_KEEPALIVE\fR option for control and data sockets. This can be -used to control network disconnect. If \fByes\fR, then set it. If \fBno\fR, -then use the system default (usually off). You probably want to set this. -.RE - -.sp -.ne 2 -.na -\fB\fBtimeout accept\fR \fIseconds\fR\fR -.ad -.br -.na -\fB\fBtimeout connect\fR \fIseconds\fR\fR -.ad -.br -.na -\fB\fBtimeout data\fR \fIseconds\fR\fR -.ad -.br -.na -\fB\fBtimeout idle\fR \fIseconds\fR \fR -.ad -.br -.na -\fB\fBtimeout maxidle\fR \fIseconds\fR\fR -.ad -.br -.na -\fB\fBtimeout RFC931\fR \fIseconds\fR\fR -.ad -.sp .6 -.RS 4n -Set various timeout conditions. -.sp -.ne 2 -.na -\fB\fBaccept\fR\fR -.ad -.RS 11n -How long the FTP Server will wait for an incoming (PASV) data connection. The -default is 120 seconds. -.RE - -.sp -.ne 2 -.na -\fB\fBconnect\fR\fR -.ad -.RS 11n -How long the FTP Server will wait attempting to establish an outgoing (PORT) -data connection. This effects the actual connection attempt. The daemon makes -several attempts, sleeping between each attempt, before giving up. The default -is 120 seconds. -.RE - -.sp -.ne 2 -.na -\fB\fBdata\fR\fR -.ad -.RS 11n -How long the FTP Server will wait for some activity on the data connection. You -should keep this long because the remote client may have a slow link, and there -can be quite a bit of data queued for the client. The default is 1200 seconds. -.RE - -.sp -.ne 2 -.na -\fB\fBidle\fR\fR -.ad -.RS 11n -How long the FTP Server will wait for the next command. The default is 900 -seconds. The default can also be overridden by using the t option at the -command-line. This access clause overrides both. -.RE - -.sp -.ne 2 -.na -\fB\fBmaxidle\fR\fR -.ad -.RS 11n -The \fBSITE IDLE\fR command allows the remote client to establish a higher -value for the idle timeout. The \fBmaxidle\fR clause sets the upper limit that -the client may request. The default can also be overridden by using the T -option at the command-line. This access clause overrides both. The default is -7200 seconds. -.RE - -.sp -.ne 2 -.na -\fB\fBRFC931\fR\fR -.ad -.RS 11n -The maximum time the FTP server allows for the entire \fBRFC931\fR (AUTH/ident) -conversation. Setting this to zero (0) disables the server's use of this -protocol. The information obtained by means of \fBRFC931\fR is recorded in the -system logs and is not actually used in any authentication. The default is 10 -seconds. -.RE - -.RE - -.sp -.ne 2 -.na -\fB\fBfile-limit\fR \fIraw\fR \fIin\fR|\fIout\fR|\fItotal\fR \fIcount\fR -\fIclass\fR\fR -.ad -.sp .6 -.RS 4n -Limit the number of data files a user in the given class may transfer. The -limit may be placed on files \fIin\fR, \fIout\fR, or \fItotal\fR. If no class -is specified, the limit is the default for classes which do not have a limit -specified. The optional parameter \fIraw\fR applies the limit to the total -traffic rather than just data files. -.RE - -.sp -.ne 2 -.na -\fB\fBdata-limit\fR [\fIraw\fR] \fIin\fR|\fIout\fR|\fItotal\fR \fIcount\fR -[\fIclass\fR]\fR -.ad -.sp .6 -.RS 4n -Limit the number of data bytes a user in the given class may transfer. The -limit may be placed on bytes \fIin\fR, \fIout\fR, or \fItotal\fR. If no class -is specified, the limit is the default for classes which do not have a limit -specified. Note that once it has been exceeded, this limit will prevent -transfers, but it will not terminate a transfer in progress. The optional -parameter \fIraw\fR applies the limit to total traffic rather than just data -files. -.RE - -.sp -.ne 2 -.na -\fB\fBlimit-time\fR \fI*\fR|\fIanonymous\fR|\fIguest\fR \fIminutes\fR\fR -.ad -.sp .6 -.RS 4n -Limit the total time a session can take. By default, there is no limit. Real -users are never limited. -.RE - -.sp -.ne 2 -.na -\fB\fBguestserver\fR [\fIhostname\fR...]\fR -.ad -.sp .6 -.RS 4n -Control which hosts may be used for anonymous access. If used without -\fIhostname\fR, all anonymous access is denied to this site. More than one -\fIhostname\fR may be specified. Anonymous access will only be allowed on the -named machines. If access is denied, the user will be asked to use the first -\fIhostname\fR listed. -.RE - -.sp -.ne 2 -.na -\fB\fBlimit\fR \fIclass\fR \fIn\fR \fItimes\fR [\fImessage_file\fR]\fR -.ad -.sp .6 -.RS 4n -Limit \fIclass\fR to \fIn\fR users at times \fItimes\fR, displaying -\fImessage_file\fR if the user is denied access. A \fBlimit\fR check is -performed at login time only. If multiple \fBlimit\fR commands can apply to the -current session, the first applicable one is used. Failing to define a valid -limit, or a limit of -1, is equivalent to no limits. The format of \fItimes\fR -is\(cd: -.sp -.in +2 -.nf -\fIday\fR[\fIday\fR...][\fItime-range\fR][|\fIday\fR[\fIday\fR...][\fItime-range\fR]]... -.fi -.in -2 - -The value of \fIday\fR can be \fBSu\fR, \fBMo\fR, \fBTu\fR, \fBWe\fR, \fBTh\fR, -\fBFr\fR, \fBSa\fR, \fBWk\fR (for any weekday Monday through Friday), or -\fBAny\fR. \fItime-range\fR is in 24-hour clock notation. If a time range is -not specified, any time of the day is matched. Multiple \fIday\fR and -\fItime-range\fR may be specified by the "|" symbol. For example, -\fBWk1730-0900|Sa|Su\fR specifies 5:30 p.m. to 9:00 a.m., Monday through -Friday, and anytime on weekends. \fImessage_file\fR may contain magic cookies. -See \fBmessage\fR for more details. -.RE - -.sp -.ne 2 -.na -\fB\fBnoretrieve\fR [\fBabsolute\fR|\fBrelative\fR]\fR -.ad -.br -.na -\fB[\fBclass=\fR\fIclassname\fR...][-] \fIfilename\fR [\fIfilename\fR...]\fR -.ad -.sp .6 -.RS 4n -Always deny retrievability of these files. If \fIfilename\fR specifies a -pathname that begins with '/' character, then only those files are marked no -retrieve. Otherwise all files that match the \fIfilename\fR are refused -transfer. For example, \fBnoretrieve /etc/passwd core \fR specifies no one will -be able to retrieve the \fB/etc/passwd\fR file. You will be allowed to transfer -any file named \fBpasswd\fR that is not in \fB/etc\fR. -.sp -On the other hand, no one will be able to get files named \fBcore\fR, wherever -they are. Directory specifications mark all files and subdirectories in the -named directory unretrievable. The \fIfilename\fR may be specified as a file -glob. For example, -.sp -.in +2 -.nf -noretrieve /etc /home/*/.htaccess -.fi -.in -2 - -specifies that no files in \fB/etc\fR or any of its subdirectories may be -retrieved. Also, no files named \fB\&.htaccess\fR anywhere under the -\fB/home\fR directory may be retrieved. The optional first parameter selects -whether names are interpreted as absolute or relative to the current chroot'd -environment. The default is to interpret names beginning with a slash as -absolute. The \fBnoretrieve\fR restrictions may be placed upon members of -particular classes. If any \fBclass=\fR is specified, the named files cannot be -retrieved only if the current user is a member of one of the given classes. -.RE - -.sp -.ne 2 -.na -\fB\fBallow-retrieve\fR [\fBabsolute\fR|\fBrelative\fR]\fR -.ad -.br -.na -\fB[\fBclass=\fR\fIclassname\fR...][-] \fIfilename\fR [\fIfilename\fR...]\fR -.ad -.sp .6 -.RS 4n -Allows retrieval of files which would otherwise be denied by noretrieve. -.RE - -.sp -.ne 2 -.na -\fB\fBloginfails\fR \fInumber\fR\fR -.ad -.sp .6 -.RS 4n -After \fInumber\fR login failures, log a "repeated login failures" message and -terminate the FTP connection. The default value for \fInumber\fR is 5. -.RE - -.sp -.ne 2 -.na -\fB\fBprivate\fR \fByes\fR | \fBno\fR\fR -.ad -.sp .6 -.RS 4n -Allow or deny use of the \fBSITE GROUP\fR and \fBSITE GPASS\fR commands after -the user logs in. The \fBSITE GROUP\fR and \fBSITE GPASS\fR commands specify an -enhanced access group and associated password. If the group name and password -are valid, the user becomes a member of the group specified in the group access -file \fB/etc/ftpd/ftpgroups\fR by means of \fBsetegid\fR(2). See -\fBftpgroups\fR(4) for the format of the file. For this option to work for -anonymous FTP users, the FTP Server must keep \fB/etc/group\fR permanently -open and load the group access file into memory. This means that the FTP Server -now has an additional file descriptor open, and the necessary passwords and -access privileges granted to users by means of \fBSITE GROUP\fR will be static -for the duration of an FTP session. If you have an urgent need to change the -access groups or passwords now, you have to kill all of the running FTP -Servers. -.RE - -.SS "Informational Capabilities" -.sp -.LP -The following informational capabilities are supported: -.sp -.ne 2 -.na -\fB\fBgreeting\fR \fBfull\fR|\fBbrief\fR|\fBterse\fR\fR -.ad -.br -.na -\fB\fBgreeting\fR \fBtext\fR \fImessage\fR\fR -.ad -.sp .6 -.RS 4n -The \fBgreeting\fR command allows you to control how much information is given -out before the remote user logs in. \fBgreeting full\fR, which is the default -greeting, shows the hostname and daemon version. \fBgreeting brief\fR shows the -hostname. \fB greeting terse\fR simply says "FTP Server ready." Although -\fBfull\fR is the default, \fBbrief\fR is suggested. -.sp -The \fBtext\fR form allows you to specify any greeting message. \fImessage\fR -can be any string. Whitespace (spaces and tabs) is converted to a single space. -.RE - -.sp -.ne 2 -.na -\fB\fBbanner\fR \fIpath\fR\fR -.ad -.sp .6 -.RS 4n -The \fBbanner\fR command operates similarly to the \fBmessage\fR command, -except that the banner is displayed before the user enters the username. The -\fIpath\fR is relative to the real system root, not to the base of the -anonymous \fBFTP\fR directory. -.sp -Use of the \fBbanner\fR command can completely prevent non-compliant \fBFTP\fR -clients from making use of the \fBFTP\fR Server. Not all clients can handle -multi-line responses, which is how the banner is displayed. -.RE - -.sp -.ne 2 -.na -\fB\fBemail\fR \fIname\fR\fR -.ad -.sp .6 -.RS 4n -Use this command to define the email address for the FTP Server administrator. -This string will be printed every time the \fB%E\fR magic cookie is used in -message files. -.RE - -.sp -.ne 2 -.na -\fB\fBhostname\fR \fIsome.host.name\fR\fR -.ad -.sp .6 -.RS 4n -Defines the default host name of the FTP Server. This string will be printed on -the greeting message and every time the \fB%L\fR magic cookie is used. The host -name for virtual servers overrides this value. If no host name is specified, -the default host name for the local machine is used. -.RE - -.sp -.ne 2 -.na -\fB\fBmessage\fR \fIpath\fR [\fIwhen\fR [\fIclass\fR...]]\fR -.ad -.sp .6 -.RS 4n -Define a file with \fIpath\fR such that the FTP Server will display the -contents of the file to the user at login time or upon using the change working -directory command. The \fIwhen\fR parameter may be \fBLOGIN\fR or -\fBCWD=\fIdirglob\fR\fR. If \fIwhen\fRis \fBCWD=\fIdirglob\fR\fR, \fIdirglob\fR -specifies the new default directory that will trigger the notification. A -\fIdirglob\fR of "\fB*\fR" matches all directories. -.sp -The optional \fIclass\fR specification allows the message to be displayed only -to members of a particular class. More than one class may be specified. -.sp -"Magic cookies" can be present in \fIpath\fR that cause the FTP Server to -replace the cookie with a specified text string: -.sp -.ne 2 -.na -\fB\fB%T\fR\fR -.ad -.RS 6n -Local time. For example, \fBThu Nov 15 17:12:42 1990\fR. -.RE - -.sp -.ne 2 -.na -\fB\fB%F\fR\fR -.ad -.RS 6n -Free space in partition of CWD, in Kbytes. -.RE - -.sp -.ne 2 -.na -\fB\fB%C\fR\fR -.ad -.RS 6n -Current working directory. -.RE - -.sp -.ne 2 -.na -\fB\fB%E\fR\fR -.ad -.RS 6n -The email address for the FTP Server administrator. -.RE - -.sp -.ne 2 -.na -\fB\fB%R\fR\fR -.ad -.RS 6n -Remote host name. -.RE - -.sp -.ne 2 -.na -\fB\fB%L\fR\fR -.ad -.RS 6n -Local host name. -.RE - -.sp -.ne 2 -.na -\fB\fB%U\fR\fR -.ad -.RS 6n -Username given at login time. -.RE - -.sp -.ne 2 -.na -\fB\fB%u\fR\fR -.ad -.RS 6n -Username as defined by means of \fIRFC 931\fR authentication. -.RE - -.sp -.ne 2 -.na -\fB\fB%M\fR\fR -.ad -.RS 6n -Maximum allowed number of users in this class. -.RE - -.sp -.ne 2 -.na -\fB\fB%N\fR\fR -.ad -.RS 6n -Current number of users in this class. -.RE - -The following quota magic cookies are also supported but not always set (see -the \fBquota-info\fR capability): -.sp -.ne 2 -.na -\fB\fB%B\fR\fR -.ad -.RS 6n -absolute limit on disk blocks allocated -.RE - -.sp -.ne 2 -.na -\fB\fB%b\fR\fR -.ad -.RS 6n -preferred limit on disk blocks -.RE - -.sp -.ne 2 -.na -\fB\fB%Q\fR\fR -.ad -.RS 6n -current block count -.RE - -.sp -.ne 2 -.na -\fB\fB%I\fR\fR -.ad -.RS 6n -maximum number of allocated inodes (+1) -.RE - -.sp -.ne 2 -.na -\fB\fB%i\fR\fR -.ad -.RS 6n -preferred inode limit -.RE - -.sp -.ne 2 -.na -\fB\fB%q\fR\fR -.ad -.RS 6n -current number of allocated inodes -.RE - -.sp -.ne 2 -.na -\fB\fB%H\fR\fR -.ad -.RS 6n -time limit for excessive disk use -.RE - -.sp -.ne 2 -.na -\fB\fB%h\fR\fR -.ad -.RS 6n -time limit for excessive files -.RE - -The message is displayed only once to avoid annoying the user. Remember that -when messages are triggered by an anonymous or guest FTP user, they must be -relative to the base of the anonymous or guest FTP directory tree. -.RE - -.sp -.ne 2 -.na -\fB\fBquota-info\fR \fIuid-range\fR [\fIuid-range\fR...] \fR -.ad -.sp .6 -.RS 4n -Enable retrieval of quota information for users matching \fIuid-range\fR. This -sets the quota magic cookies. Retrieving quota information might cause a -significant delay when logging into the server. -.sp -\fIuid-range\fR can be a username, single UID, or a UID range. Place a percent -sign(\fB%\fR) before a number. An asterisk means "all users." -.RE - -.sp -.ne 2 -.na -\fB\fBreadme\fR \fIpathglob\fR [\fIwhen\fR [\fIclass\fR...]]\fR -.ad -.sp .6 -.RS 4n -Define a file with \fIpathglob\fR such that the FTP Server will notify the user -at login time or upon using the change working directory command that the file -exists and the date that it was modified. The \fIwhen\fR parameter may be -\fBLOGIN\fR or \fBCWD=\fIdirglob\fR\fR. If \fIwhen\fR is -\fBCWD=\fIdirglob\fR\fR, \fIdirglob\fR specifies the new default directory that -will trigger the notification. A \fIdirglob\fR of "\fB*\fR" matches all -directories. The message will only be displayed once, to avoid bothering users. -Remember that when README messages are triggered by an anonymous or guest FTP -user, the \fIpathglob\fR must be relative to the base of the anonymous or guest -FTP directory tree. -.sp -The optional \fIclass\fR specification allows the message to be displayed only -to members of a particular class. You can specify more than one class. -.RE - -.SS "Logging Capabilities" -.sp -.LP -The following logging capabilities are supported: -.sp -.ne 2 -.na -\fB\fBlog commands\fR \fItypelist\fR\fR -.ad -.sp .6 -.RS 4n -Enables logging of the individual FTP commands sent by users. \fItypelist\fR is -a comma-separated list of any of the keywords \fBanonymous\fR, \fBguest\fR, and -\fBreal\fR. Command logging information is written to the system log. -.RE - -.sp -.ne 2 -.na -\fB\fBlog transfers\fR \fItypelist\fR \fIdirections\fR\fR -.ad -.sp .6 -.RS 4n -Log file transfers made by FTP users to the \fBxferlog\fR(4) file. Logging of -incoming transfers to the server can be enabled separately from outbound -transfers from the server. \fIdirections\fR is a comma-separated list of any of -the two keywords \fBinbound\fR and \fBoutbound\fR, and will respectively cause -transfers to be logged for files sent to and from the server. -.RE - -.sp -.ne 2 -.na -\fB\fBlog security\fR \fItypelist\fR\fR -.ad -.sp .6 -.RS 4n -Enables logging of violations of security rules to the system log, including -for example, \fBnoretrieve\fR and \fB\&.notar\fR. -.RE - -.sp -.ne 2 -.na -\fB\fBlog syslog\fR\fR -.ad -.br -.na -\fB\fBlog syslog+xferlog\fR\fR -.ad -.sp .6 -.RS 4n -Redirect the logging messages for incoming and outgoing transfers to -\fBsyslog\fR. Without this option the messages are written to \fBxferlog\fR. -When you specify \fBsyslog+xferlog\fR, the transfer log messages are sent to -both the system log file and the \fBxferlog\fR file. -.RE - -.sp -.ne 2 -.na -\fB\fBxferlog\fR format \fIformatstring\fR\fR -.ad -.sp .6 -.RS 4n -Customize the format of the transfer log entry written. \fIformatstring\fR can -be any string, which might include magic cookies. Strings of whitespace -characters are converted into a single space. -.sp -The following transfer-specific magic cookies are recognized only immediately -after a transfer has been completed: -.sp -.ne 2 -.na -\fB\fB%Xt\fR\fR -.ad -.RS 7n -transfer-time -.RE - -.sp -.ne 2 -.na -\fB\fB%Xn\fR\fR -.ad -.RS 7n -bytes-transferred -.RE - -.sp -.ne 2 -.na -\fB\fB%XP\fR\fR -.ad -.RS 7n -filename -.RE - -.sp -.ne 2 -.na -\fB\fB%Xp\fR\fR -.ad -.RS 7n -chroot-filename -.RE - -.sp -.ne 2 -.na -\fB\fB%Xy\fR\fR -.ad -.RS 7n -transfer-type -.RE - -.sp -.ne 2 -.na -\fB\fB%Xf\fR\fR -.ad -.RS 7n -special-action-flag -.RE - -.sp -.ne 2 -.na -\fB\fB%Xd\fR\fR -.ad -.RS 7n -direction -.RE - -.sp -.ne 2 -.na -\fB\fB%Xm\fR\fR -.ad -.RS 7n -access-mode -.RE - -.sp -.ne 2 -.na -\fB\fB%Xa\fR\fR -.ad -.RS 7n -authentication-method -.RE - -.sp -.ne 2 -.na -\fB\fB%Xc\fR\fR -.ad -.RS 7n -completion-status -.RE - -.sp -.ne 2 -.na -\fB\fB%Xs\fR\fR -.ad -.RS 7n -file-size -.RE - -.sp -.ne 2 -.na -\fB\fB%Xr\fR\fR -.ad -.RS 7n -restart-offset -.RE - -\fBxferlog\fR(4) includes a description of these fields. If no \fBxferlog\fR -format entry is present, the default is: -.sp -.in +2 -.nf -xferlog format %T %Xt %R %Xn %XP %Xy %Xf %Xd %Xm %U ftp %Xa %u %Xc -.fi -.in -2 -.sp - -.RE - -.SS "Miscellaneous Capabilities" -.sp -.LP -The following miscellaneous capabilities are supported: -.sp -.ne 2 -.na -\fB\fBalias\fR\fI string\fR \fIdir\fR\fR -.ad -.sp .6 -.RS 4n -Define an alias, \fI string\fR, for a directory. Use this command to add the -concept of logical directories. For example: \fBalias rfc: /pub/doc/rfc\fR -would allow the user to access \fB/pub/doc/rfc\fR from any directory by the -command "\fBcd rfc:\fR". Aliases only apply to the \fBcd\fR command. -.RE - -.sp -.ne 2 -.na -\fB\fBcdpath\fR \fIdir\fR\fR -.ad -.sp .6 -.RS 4n -Define an entry in the \fBcdpath\fR. This command defines a search path that is -used when changing directories. For example: -.sp -.in +2 -.nf -cdpath /pub/packages -cdpath /.aliases -.fi -.in -2 -.sp - -would allow the user to move into any directory directly under either the -\fB/pub/packages\fR or the \fB/.aliases\fR directories. The search path is -defined by the order in which the lines appear in the \fBftpaccess\fR file. If -the user were to give the command \fBftp> cd foo\fR the directory will be -searched for in the following order: -.RS +4 -.TP -.ie t \(bu -.el o -\fB\&./foo \fR -.RE -.RS +4 -.TP -.ie t \(bu -.el o -an alias called foo -.RE -.RS +4 -.TP -.ie t \(bu -.el o -\fB/pub/packages/foo\fR -.RE -.RS +4 -.TP -.ie t \(bu -.el o -\fB/.aliases/foo\fR -.RE -The \fBcdpath\fR is only available with the \fBcd\fR command. If you have a -large number of aliases, you might want to set up an aliases directory with -links to all of the areas you wish to make available to users. -.RE - -.sp -.ne 2 -.na -\fB\fBcompress\fR \fByes\fR|\fBno\fR \fIclassglob\fR [\fIclassglob\fR...]\fR -.ad -.br -.na -\fBtar \fByes\fR|\fBno\fR \fIclassglob\fR [\fIclassglob\fR...]\fR -.ad -.sp .6 -.RS 4n -Enable the use of conversions marked with the \fBO_COMPRESS\fR, -\fBO_UNCOMPRESS\fR, and \fBO_TAR\fR options in \fB/etc/ftpd/ftpconversions\fR. -See \fBftpconversions\fR(4). -.RE - -.sp -.ne 2 -.na -\fB\fBshutdown\fR \fIpath\fR\fR -.ad -.sp .6 -.RS 4n -If the file pointed to by \fIpath\fR exists, the server will check the file -regularly to see if the server is going to be shut down. If a shutdown is -planned, the user is notified. New connections are denied after a specified -time before shutdown. Current connections are dropped at a specified time -before shutdown. -.sp -The format of the file specified by \fIpath\fR is: -.sp -.in +2 -.nf -\fIyear\fR \fImonth\fR \fIday\fR \fIhour\fR \fIminute\fR \fIdeny_offset\fR \fIdisc_offset\fR \fItext\fR -.fi -.in -2 - -.sp -.ne 2 -.na -\fB\fIyear\fR\fR -.ad -.RS 15n -A value of 1970 or greater. -.RE - -.sp -.ne 2 -.na -\fB\fImonth\fR\fR -.ad -.RS 15n -A value of 0 to 11. -.RE - -.sp -.ne 2 -.na -\fB\fIday\fR\fR -.ad -.RS 15n -A value of 1 to 31. -.RE - -.sp -.ne 2 -.na -\fB\fIhour\fR\fR -.ad -.RS 15n -A value of 0 to 23. -.RE - -.sp -.ne 2 -.na -\fB\fIminute\fR\fR -.ad -.RS 15n -A value of 0 to 59. -.RE - -.sp -.ne 2 -.na -\fB\fIdeny_offset\fR\fR -.ad -.br -.na -\fB\fIdisc_offset\fR\fR -.ad -.RS 15n -The offsets in HHMM format that new connections will be denied and existing -connections will be disconnected before the shutdown time. -.RE - -.sp -.ne 2 -.na -\fB\fItext\fR \fR -.ad -.RS 15n -Follows the normal rules for any \fImessage\fR. The following additional magic -cookies are available: -.sp -.ne 2 -.na -\fB\fB%s\fR\fR -.ad -.RS 6n -The time at which the system is going to shut down. -.RE - -.sp -.ne 2 -.na -\fB\fB%r\fR\fR -.ad -.RS 6n -The time at which new connections will be denied. -.RE - -.sp -.ne 2 -.na -\fB\fB%d\fR\fR -.ad -.RS 6n -The time at which current connections will be dropped. -.RE - -.RE - -All times are in the form: \fBddd MMM DD hh:mm:ss YYYY\fR. Only one -\fBshutdown\fR command can be present in the configuration file. You can use -the external program \fBftpshut\fR(1M) to automate generation of this file. -.RE - -.sp -.ne 2 -.na -\fB\fBdaemonaddress\fR \fIaddress\fR\fR -.ad -.sp .6 -.RS 4n -Listen only on the IP address specified. If the value is not set, then the FTP -Server will listen for connections on every IP address. This applies only when -the FTP Server is run in standalone mode. -.RE - -.sp -.ne 2 -.na -\fB\fBvirtual\fR \fIaddress\fR \fBroot\fR|\fBbanner\fR|\fBlogfile\fR -\fIpath\fR\fR -.ad -.sp .6 -.RS 4n -Enable the FTP Server limited virtual hosting capabilities. The \fIaddress\fR -is the IP address of the virtual server. The second argument specifies that the -\fIpath\fR is either the path to the \fBroot\fR of the filesystem for this -virtual server, the \fBbanner\fR presented to the user when connecting to this -virtual server, or the \fBlogfile\fR where transfers are recorded for this -virtual server. If the \fBlogfile\fR is not specified the default log file will -be used. All other message files and permissions as well as any other settings -in this file apply to all virtual servers. The \fIaddress\fR may also be -specified as a hostname rather than as an IP number. This is strongly -discouraged since, if DNS is not available at the time the FTP session begins, -the hostname will not be matched. -.RE - -.sp -.ne 2 -.na -\fB\fBroot\fR|\fBlogfile\fR \fIpath\fR\fR -.ad -.sp .6 -.RS 4n -In contrast to limited virtual hosting, complete virtual hosting allows -separate configuration files to be virtual host specific. See -\fBftpservers\fR(4). The only additions that are necessary in a virtual host's -\fBftpaccess\fR file is the \fBroot\fR directive that ensures the correct root -directory is used for the virtual host. This only works with complete virtual -hosting, which in contrast to limited virtual hosting, allows separate -configuration files to be specified for each virtual host. -.sp -\fIpath\fR is either the root of the filesystem for this virtual server or the -logfile where transfers for this virtual server are recorded. root and logfile -may only be specified when not preceded by \fBvirtual\fR \fIaddress\fR in a -virtual hosts's \fBftpaccess\fR file. -.RE - -.sp -.ne 2 -.na -\fB\fBvirtual\fR \fIaddress\fR \fBhostname\fR|\fBemail\fR \fIstring\fR\fR -.ad -.sp .6 -.RS 4n -Set the hostname shown in the greeting message and status command, or the email -address used in message files and on the HELP command, to the given -\fIstring\fR. -.RE - -.sp -.ne 2 -.na -\fB\fBvirtual\fR \fIaddress\fR \fBallow\fR \fIusername\fR -[\fIusername\fR...]\fR -.ad -.br -.na -\fB\fBvirtual\fR \fIaddress\fR \fBdeny\fR \fIusername\fR [\fIusername\fR...]\fR -.ad -.sp .6 -.RS 4n -By default, real and guest users are not allowed to log in on the virtual -server, unless they are guests that are chroot'd to the virtual root. The users -listed on the \fBvirtual allow\fR line(s) are granted access. You can grant -access to all users by giving '*' as the \fIusername\fR. The \fBvirtual deny\fR -clauses are processed after the \fBvirtual allow\fR clauses. Thus specific -users can be denied access although all users were allowed in an earlier -clause. -.RE - -.sp -.ne 2 -.na -\fB\fBvirtual\fR \fIaddress\fR \fBprivate\fR\fR -.ad -.sp .6 -.RS 4n -Deny log in access to anonymous users on the virtual server. Anonymous users -are generally allowed to log in on the virtual server if this option is not -specified. -.RE - -.sp -.ne 2 -.na -\fB\fBvirtual\fR \fIaddress\fR \fBpasswd\fR \fIfile\fR\fR -.ad -.sp .6 -.RS 4n -Use a different \fBpasswd\fR file for the virtual host. -.RE - -.sp -.ne 2 -.na -\fB\fBvirtual\fR \fIaddress\fR \fBshadow\fR \fIfile\fR\fR -.ad -.sp .6 -.RS 4n -Use a different \fBshadow\fR file for the virtual host. -.RE - -.sp -.ne 2 -.na -\fB\fBdefaultserver\fR \fBdeny\fR \fIusername\fR [\fIusername\fR...]\fR -.ad -.br -.na -\fB\fBdefaultserver\fR \fBallow\fR \fIusername\fR [\fIusername\fR...] \fR -.ad -.sp .6 -.RS 4n -By default, all users are allowed access to the non-virtual FTP Server. Use -\fBdefaultserver\fR \fBdeny\fR to revoke access for specific real and guest -users. Specify '*' to deny access to all users, except anonymous users. -Specific real and guest users can then be allowed access by using -\fBdefaultserver\fR \fBallow\fR. -.RE - -.sp -.ne 2 -.na -\fB\fBdefaultserver\fR \fBprivate\fR\fR -.ad -.sp .6 -.RS 4n -By default, all users are allowed access to the non-virtual FTP Server. Use -\fBdefaultserver\fR \fBprivate\fR to revoke access for anonymous users. -.sp -The \fBvirtual\fR and \fBdefaultserver\fR \fBallow\fR, \fBdeny\fR and -\fBprivate\fR clauses provide a means to control which users are allowed access -to which FTP Servers. -.RE - -.sp -.ne 2 -.na -\fB\fBpassive\fR \fBaddress\fR \fIexternalip\fR \fIcidr\fR\fR -.ad -.sp .6 -.RS 4n -Allow control of the address reported in response to a \fBpassive\fR command. -When any control connection matching \fIcidr\fR requests a passive data -connection (PASV), the \fIexternalip\fR address is reported. This does not -change the address that the daemon actually listens on, only the address -reported to the client. This feature allows the daemon to operate correctly -behind IP renumbering firewalls. For example: -.sp -.in +2 -.nf -passive address 10.0.1.15 10.0.0.0/8 -passive address 192.168.1.5 0.0.0.0/0 -.fi -.in -2 - -Clients connecting from the class-A network 10 will be told the passive -connection is listening on IP address 10.0.1.15 while all others will be told -the connection is listening on 192.168.1.5. Multiple passive addresses may be -specified to handle complex, or multi-gatewayed, networks. -.RE - -.sp -.ne 2 -.na -\fB\fBpassive\fR \fBports\fR \fIcidr\fR \fImin\fR \fImax\fR\fR -.ad -.sp .6 -.RS 4n -Allows control of the TCP port numbers which may be used for a passive data -connection. If the control connection matches the \fIcidr\fR, a port in the -range \fImin\fR to \fImax\fR will be randomly selected for the daemon to listen -on. This feature allows firewalls to limit the ports that remote clients may -use to connect into the protected network. -.sp -\fIcidr\fR is shorthand for an IP address followed by a slash and the number of -left-most bits that represent the network address, as opposed to the machine -address. For example, if you are using the reserved class-A network 10, instead -of a netmask of 255.0.0.0, use a CIDR of /8, as in 10.0.0.0/8, to represent -your network. -.sp -When \fImin\fR and \fImax\fR are both 0, the kernel rather than the FTP server -selects the TCP port to listen on. Kernel port selection is usually not -desirable if the kernel allocates TCP ports sequentially. If in doubt, let the -FTP server do the port selection. -.RE - -.sp -.ne 2 -.na -\fB\fBpasv-allow\fR \fIclass\fR [\fIaddrglob\fR...]\fR -.ad -.br -.na -\fB\fBport-allow\fR \fIclass\fR [\fIaddrglob\fR...]\fR -.ad -.sp .6 -.RS 4n -Normally, the FTP Server does not allow a \fBPORT\fR command to specify an -address different than that of the control connection. Nor does it allow a -\fBPASV\fR connection from another address. -.sp -The \fBport-allow\fR clause provides a list of addresses that the specified -class of user may give on a \fBPORT\fR command. These addresses will be allowed -even if they do not match the IP address of the client-side of the control -connection. -.sp -The \fBpasv-allow\fR clause provides a list of addresses that the specified -class of user may make data connections from. These addresses will be allowed -even if they do not match the IP address of the client-side of the control -connection. -.RE - -.sp -.ne 2 -.na -\fB\fBlslong\fR\fI command\fR [\fIoptions\fR...] \fR -.ad -.br -.na -\fB\fBlsshort\fR\fI command\fR [\fIoptions\fR...] \fR -.ad -.br -.na -\fB\fBlsplain\fR\fI command\fR [\fIoptions\fR...] \fR -.ad -.sp .6 -.RS 4n -Use the \fBlslong\fR, \fBlsshort\fR, and \fBlsplain\fR clauses to specify the -commands and options to use to generate directory listings. The options cannot -contain spaces, and the default values for these clauses are generally correct. -Use \fBlslong\fR, \fBlsshort\fR, or \fBlsplain\fR only if absolutely necessary. -.RE - -.sp -.ne 2 -.na -\fB\fBmailserver\fR \fIhostname\fR\fR -.ad -.sp .6 -.RS 4n -Specify the name of a mail server that will accept upload notifications for the -FTP Server. Multiple mail servers may be listed. The FTP Server will attempt to -deliver the upload notification to each, in order, until one accepts the -message. If no mail servers are specified, \fBlocalhost\fR is used. This option -is only meaningful if anyone is to be notified of anonymous uploads. See -\fBincmail\fR. -.RE - -.sp -.ne 2 -.na -\fB\fBincmail\fR \fIemailaddress\fR\fR -.ad -.br -.na -\fB\fBvirtual\fR \fIaddress\fR \fBincmail\fR \fIemailaddress\fR\fR -.ad -.br -.na -\fB\fBdefaultserver\fR \fBincmail\fR \fIemailaddress\fR\fR -.ad -.sp .6 -.RS 4n -Specify email addresses to be notified of anonymous uploads. Multiple addresses -can be specified. Each will receive a notification. If no addresses are -specified, no notifications are sent. -.sp -If addresses are specified for a virtual host, only those addresses will be -sent notification of anonymous uploads on that host. Otherwise, notifications -will be sent to the global addresses. -.sp -\fBdefaultserver\fR addresses only apply when the FTP session is not using one -of the virtual hosts. In this way, you can receive notifications for your -default anonymous area, but not see notifications to virtual hosts that do not -have their own notifications. -.RE - -.sp -.ne 2 -.na -\fB\fBmailfrom\fR \fIemailaddress\fR\fR -.ad -.br -.na -\fB\fBvirtual\fR \fIaddress\fR \fBmailfrom\fR \fIemailaddress\fR\fR -.ad -.br -.na -\fB\fBdefaultserver\fR \fBmailfrom\fR \fIemailaddress\fR\fR -.ad -.sp .6 -.RS 4n -Specify the sender's email address for anonymous upload notifications. Only one -address may be specified. If no \fBmailfrom\fR applies, email is sent from the -default mailbox name \fBwu-ftpd\fR. To avoid problems if the recipient attempts -to reply to a notification, or if downstream mail problems generate bounces, -you should ensure the \fBmailfrom\fR address is deliverable. -.RE - -.sp -.ne 2 -.na -\fB\fBsendbuf\fR \fIsize\fR [\fItypelist\fR]\fR -.ad -.br -.na -\fB\fBrecvbuf\fR \fIsize\fR [\fItypelist\fR]\fR -.ad -.sp .6 -.RS 4n -Set the send or receive buffer sizes used for binary transfers. They have no -effect on ASCII transfers. -.RE - -.sp -.ne 2 -.na -\fB\fBrhostlookup\fR yes|no [\fIaddrglob\fR ...]\fR -.ad -.sp .6 -.RS 4n -Allows or disallows the lookup of the remote host's name. Name lookups can be -slow, but skipping them means that places where an \fIaddrglob\fR is matched -(for example, in the class capability) will match only an IP address, not a -name. Also \fBdeny !nameserved\fR and \fBdns refuse_no_reverse\fR or -\fBrefuse_mismatch\fR will deny access when a name lookup is not done. The -default is to lookup the remote host's name. -.sp -Only IP addresses, not names, are matched in \fIaddrglob\fR. -.RE - -.sp -.ne 2 -.na -\fB\fBflush-wait\fR yes|no [\fItypelist\fR]\fR -.ad -.sp .6 -.RS 4n -Controls the behavior at the end of a download or directory listing. If -\fByes\fR, shutdown the data connection for sending and wait for the client to -close its end before sending a transfer complete reply on the control -connection. This is the default behavior. If \fBno\fR, close the data -connection and send the transfer complete reply without waiting for the client. -With this behavior, data loss can go undetected. -.sp -If a client hangs at the end of a directory listing, or the system has many -sockets in the \fBFIN_WAIT_2\fR state, try setting to \fBno\fR as a workaround -for broken client behavior. -.RE - -.SS "Permission Capabilities" -.sp -.LP -The following permission capabilities are supported: -.sp -.ne 2 -.na -\fB\fBchmod\fR \fByes\fR|\fBno\fR \fItypelist\fR\fR -.ad -.br -.na -\fB\fBdelete\fR \fByes\fR|\fBno\fR \fItypelist\fR\fR -.ad -.br -.na -\fB\fBoverwrite\fR \fByes\fR|\fBno\fR \fItypelist\fR\fR -.ad -.br -.na -\fB\fBrename\fR \fByes\fR|\fBno\fR \fItypelist\fR\fR -.ad -.br -.na -\fB\fBumask\fR \fByes\fR|\fBno\fR \fItypelist\fR\fR -.ad -.sp .6 -.RS 4n -Allows or disallows the ability to perform the specified function. By default, -all real and guest users are allowed. Anonymous users are only allowed -\fBoverwrite\fR and \fBumask\fR. -.sp -\fItypelist\fR is a comma-separated list of any of the keywords -\fBanonymous\fR, \fBguest\fR, \fBreal\fR and \fBclass=\fR. When \fBclass=\fR -appears, it must be followed by a classname. If any \fBclass=\fR appears, the -\fItypelist\fR restriction applies only to users in that class. -.RE - -.sp -.ne 2 -.na -\fB\fBpasswd-check\fR \fBnone\fR|\fBtrivial\fR|\fBrfc822\fR -[\fBenforce\fR|\fBwarn\fR]\fR -.ad -.sp .6 -.RS 4n -Define the level and enforcement of password checking done by the FTP Server -for anonymous FTP. -.sp -.ne 2 -.na -\fB\fBnone\fR\fR -.ad -.RS 11n -No password checking is performed. -.RE - -.sp -.ne 2 -.na -\fB\fBtrivial\fR\fR -.ad -.RS 11n -The password must contain an '@'. -.RE - -.sp -.ne 2 -.na -\fB\fBrfc822\fR\fR -.ad -.RS 11n -The password must be \fIRFC 822\fR compliant. -.RE - -.sp -.ne 2 -.na -\fB\fBwarn\fR\fR -.ad -.RS 11n -Warn, but permit the login. -.RE - -.sp -.ne 2 -.na -\fB\fBenforce\fR\fR -.ad -.RS 11n -Notify and deny the login. -.RE - -.RE - -.sp -.ne 2 -.na -\fB\fBdeny-email\fR \fIcase-insensitive-emailaddress\fR\fR -.ad -.sp .6 -.RS 4n -Consider the email address given as an argument as invalid. If -\fBpasswd-check\fR is set to \fBenforce\fR, anonymous users giving this address -as a password cannot log in. That way, you can stop users from having stupid -WWW browsers use fake addresses like IE?0User@ or mozilla@. (by using this, you -are not shutting out users using a WWW browser for ftp - you just make them -configure their browser correctly.) Only one address is allowed per line, but -you can have as many \fBdeny-email\fR addresses as you like. -.RE - -.sp -.ne 2 -.na -\fB\fBpath-filter\fR \fItypelist\fR \fImessage\fR \fIallowed_regexp\fR \fR -.ad -.br -.na -\fB[\fIdisallowed_regexp\fR...]\fR -.ad -.sp .6 -.RS 4n -For users in \fItypelist\fR, \fBpath-filter\fR defines regular expressions that -control what characters can be used in the filename of an uploaded file or -created directory. There may be multiple disallowed regular expressions. If a -filename is invalid due to failure to match the regular expression criteria, -\fImessage\fR will be displayed to the user. For example: -.sp -.in +2 -.nf -path-filter anonymous /etc/pathmsg ^[-A-Za-z0-9._]*$ ^\. ^- -.fi -.in -2 - -specifies that all upload filenames for anonymous users must be made of only -the characters A-Z, a-z, 0-9, and "._-" and may not begin with a "." or a "-". -If the filename is invalid, \fB/etc/pathmsg\fR will be displayed to the user. -.RE - -.sp -.ne 2 -.na -\fB\fBupload\fR [\fBabsolute\fR|\fBrelative\fR] -[\fBclass=\fR\fIclassname\fR]... [\fB-\fR] \fR -.ad -.br -.na -\fB\fIroot-dir\fR \fIdirglob\fR \fByes\fR|\fBno\fR \fIowner\fR \fIgroup\fR -\fImode\fR\fR -.ad -.br -.na -\fB[\fBdirs\fR|\fBnodirs\fR] [\fId_mode\fR]\fR -.ad -.sp .6 -.RS 4n -Define a directory with \fIdirglob\fR that permits or denies uploads. If it -does permit uploads, all newly created files will be owned by \fIowner\fR and -\fIgroup\fR and will have their permissions set according to \fImode\fR. -Existing files that are overwritten will retain their original ownership and -permissions. Directories are matched on a best-match basis. For example: -.sp -.in +2 -.nf -upload /var/ftp * no -upload /var/ftp /incoming yes ftp daemon 0666 -upload /var/ftp /incoming/gifs yes jlc guest 0600 nodirs -.fi -.in -2 - -would only allow uploads into \fB/incoming\fR and \fB/incoming/gifs\fR. Files -that were uploaded to \fB/incoming\fR are owned by \fBftp/daemon\fR and have -permissions of 0666. Files uploaded to \fB/incoming/gifs\fR are owned by -\fBjlc/guest\fR and have permissions of 0600. The optional "\fBdirs\fR" and -"\fBnodirs\fR" keywords can be specified to allow or disallow the creation of -new subdirectories using the \fBmkdir\fR command. If the \fBupload\fR command -is used, directory creation is allowed by default. To turn it off by default, -you must specify a user, group and mode followed by the "nodirs" keyword as the -first line where the \fBupload\fR command is used in this file. If directories -are permitted, the optional \fId_mode\fR determines the permissions for a newly -created directory. If \fId_mode\fR is omitted, the permissions are inferred -from \fImode\fR. The permissions are 0777 if \fImode\fR is also omitted. The -\fBupload\fR keyword only applies to users who have a home directory of -\fIroot-dir\fR. \fIroot-dir\fR may be specified as "*" to match any home -directory. The \fIowner\fR or \fIgroup\fR may each be specified as "*", in -which case any uploaded files or directories will be created with the ownership -of the directory in which they are created. The optional first parameter -selects whether \fIroot-dir\fR names are interpreted as absolute or relative to -the current \fBchroot'd\fR environment. The default is to interpret -\fB\fR names as absolute. You can specify any number of -\fBclass=\fIclassname\fR\fR restrictions. If any are specified, this upload -clause only takes effect if the current user is a member of one of the classes. -.sp -In the absence of any matching \fBupload\fR clause, real and guest users can -upload files and make directories, but anonymous users cannot. The mode of -uploaded files is 0666. For created directories, the mode is 0777. Both modes -are modified by the current umask setting. -.RE - -.sp -.ne 2 -.na -\fB\fBthroughput\fR \fIroot-dir\fR \fIsubdir-glob\fR \fIfile-glob-list\fR \fR -.ad -.br -.na -\fB\fIbytes-per-second\fR \fIbytes-per-second-multiply\fR \fIremote-glob-list -\fR\fR -.ad -.sp .6 -.RS 4n -Define files by means of a comma-separated \fIfile-glob-list\fR in \fBsubdir\fR -matched by \fIsubdir-glob\fR under \fIroot-dir\fR that have restricted transfer -throughput of \fIbytes-per-second\fR on download when the remote hostname or -remote IP address matches the comma-separated \fIremote-glob-list\fR. Entries -are matched on a best-match basis. For example: -.sp -.in +2 -.nf -throughput /e/ftp * * oo - * -throughput /e/ftp /sw* * 1024 0.5 * -throughput /e/ftp /sw* README oo - * -throughput /e/ftp /sw* * oo - *.foo.com -.fi -.in -2 - -would set maximum throughput per default, but restrict download to 1024 bytes -per second for any files under \fB/e/ftp/sw/\fR that are not named README. The -only exceptions are remote hosts from within the domain \fBfoo.com\fR which -always get maximum throughput. Every time a remote client has retrieved a file -under \fB/e/ftp/sw/\fR the bytes per seconds of the matched entry line are -internally multiplied by a factor, here 0.5. When the remote client retrieves -its second file, it is served with 512 bytes per second, the third time with -only 256 bytes per second, the fourth time with only 128 bytes per second, and -so on. The string "oo" for the bytes per second field means no throughput -restriction. A multiply factor of 1.0 or "-" means no change of the throughput -after every successful transfer. The \fIroot-dir\fR here must match the home -directory specified in the password database . The \fBthroughput\fR keyword -only applies to users who have a home directory of \fIroot-dir\fR. -.RE - -.sp -.ne 2 -.na -\fB\fBanonymous-root\fR \fIroot-dir\fR [\fIclass\fR...]\fR -.ad -.sp .6 -.RS 4n -\fIroot-dir\fR specifies the \fBchroot()\fR path for anonymous users. If no -anonymous-root is matched, the old method of parsing the home directory for the -FTP user is used. If no \fIclass\fR is specified, this is the root directory -for anonymous users who do not match any other anonymous-root specification. -Multiple classes may be specified on this line. If an anonymous-root is chosen -for the user, the FTP user's home directory in the -\fB\fIroot-dir\fR/etc/passwd\fR file is used to determine the initial directory -and the FTP user's home directory in the system-wide \fB/etc/passwd\fR is not -used. For example: -.sp -.in +2 -.nf -anonymous-root /home/ftp -anonymous-root /home/localftp localnet -.fi -.in -2 - -causes all anonymous users to be \fBchroot'd\fR to the directory -\fB/home/ftp\fR. If the FTP user exists in \fB/home/ftp/etc/passwd\fR, their -initial \fBCWD\fR is that home directory. Anonymous users in the class -\fBlocalnet\fR, however, are \fBchroot'd\fR to the directory -\fB/home/localftp\fR and their initial \fBCWD\fR is taken from the FTP user's -home directory in \fB/home/localftp/etc/passwd\fR. -.RE - -.sp -.ne 2 -.na -\fB\fBguest-root\fR \fIroot-dir\fR [\fIuid-range\fR...]\fR -.ad -.sp .6 -.RS 4n -\fIroot-dir\fR specifies the \fBchroot()\fR path for guest users. If no -guest-root is matched, the old method of parsing the user's home directory is -used. If no \fIuid-range\fR is specified, this is the root directory for -guestusers who do not match any other guest-root specification. Multiple UID -ranges may be given on this line. If a guest-root is chosen for the user, the -user's home directory in the \fB\fIroot-dir\fR/etc/passwd\fR file is used to -determine the initial directory and the home directory in the system-wide -\fB/etc/passwd\fR is not used. \fIuid-range\fR specifies names or numeric UID -values. To use numbers, put a percent sign (\fB%\fR) symbol before it or before -the range. Ranges are specified by giving the lower and upper bounds -(inclusive), separated by a dash. If the lower bound is omitted, it means -\fBall up to\fR. If the upper bound is omitted, it means \fBall starting -from\fR. For example: -.sp -.in +2 -.nf -guest-root /home/users -guest-root /home/staff %100-999 sally -guest-root /home/users/owner/ftp frank -.fi -.in -2 - -causes all guest users to \fBchroot()\fR to \fB/home/users\fR then starts each -user in the user's home directory, as specifiedin \fB/home/users/etc/passwd\fR. -Users in the range 100 through 999, inclusive, and user sally, will be -\fBchroot'd\fR to \fB/home/staff\fR and the \fBCWD\fR will be taken from their -entries in \fB/home/staff/etc/passwd\fR. The single user frank will be -\fBchroot'd\fR to \fB/home/users/owner/ftp\fR and the \fBCWD\fR will be from -his entry in \fB/home/users/owner/ftp/etc/passwd\fR. -.sp -The order is important for both anonymous-root and guest-root. If a user would -match multiple clauses, only the first applies; with the exception of the -clause which has no \fIclass\fR or \fIuid-range\fR, which applies only if no -other clause matches. -.RE - -.sp -.ne 2 -.na -\fB\fBdeny-uid\fR \fIuid-range\fR [\fIuid-range\fR...]\fR -.ad -.br -.na -\fB\fBdeny-gid\fR \fIgid-range\fR [\fIgid-range\fR...]\fR -.ad -.br -.na -\fB\fBallow-uid\fR \fIuid-range \fR [\fIuid-range\fR...]\fR -.ad -.br -.na -\fB\fBallow-gid\fR \fIgid-range\fR [\fIgid-range\fR...]\fR -.ad -.sp .6 -.RS 4n -Use these clauses to specify UID and GID values that will be denied access to -the FTP Server. The \fBallow-uid\fR and \fBallow-gid\fR clauses may be used to -allow access for UID and GID values which would otherwise be denied. These -checks occur before all others. \fBdeny\fR is checked before \fBallow\fR. The -default is to allow access. These clauses do not apply to anonymous users. Use -\fBdefaultserver\fR \fBprivate\fR to deny access to anonymous users. In most -cases, these clauses obviate the need for an \fBftpusers\fR(4) file. For -example, the following clauses deny FTP Server access to all privileged or -special users and groups, except the guest1 user or group. -.sp -.in +2 -.nf -deny-gid %-99 nobody noaccess nogroup -deny-uid %-99 nobody noaccess nobody4 -allow-gid guest1 -allow-uid guest1 -.fi -.in -2 - -Support for the \fBftpusers\fR file still exists, so it may be used when -changing the \fBftpaccess\fR file is not desired. In any place a single UID or -GID is allowed throughout the \fBftpaccess\fR file, either names or numbers -also may be used. To use a number, put a percent sign (\fB%\fR) symbol before -it. In places where a range is allowed, put the percent sign before the range. -A "\fB*\fR" matches all UIDs or GIDs. -.RE - -.sp -.ne 2 -.na -\fB\fBrestricted-uid\fR \fIuid-range\fR [\fIuid-range\fR...]\fR -.ad -.br -.na -\fB\fBrestricted-gid\fR \fIgid-range\fR [\fIgid-range\fR...]\fR -.ad -.br -.na -\fB\fBunrestricted-uid\fR \fIuid-range\fR [\fIuid-range\fR...]\fR -.ad -.br -.na -\fB\fBunrestricted-gid\fR \fIgid-range\fR [\fIgid-range\fR...]\fR -.ad -.sp .6 -.RS 4n -These clauses control whether or not real or guest users will be allowed access -to areas on the FTP site outside their home directories. These clauses are not -meant to replace the use of \fBguestgroup\fR and \fBguestuser\fR. Instead, use -these clauses to supplement the operation of guests. The \fBunrestricted-uid\fR -and \fBunrestricted-gid\fR clauses may be used to allow users outside their -home directories who would otherwise be restricted. -.sp -The following example shows the intended use for these clauses. Assume user -\fBdick\fR has a home directory \fB/home/dick\fR and \fBjane\fR has a home -directory \fB/home/jane\fR: -.sp -.in +2 -.nf -guest-root /home dick jane -restricted-uid dick jane -.fi -.in -2 - -While both \fBdick\fR and \fBjane\fR are \fBchroot'd\fR to \fB/home\fR, they -cannot access each other's files because they are restricted to their home -directories. However, you should not rely solely upon the FTP restrictions to -control access. As with all other FTP access rules, you should also use -directory and file permissions to support the operation of the \fBftpaccess\fR -configuration. -.RE - -.sp -.ne 2 -.na -\fB\fBsite-exec-max-lines\fR \fInumber\fR [\fIclass\fR...]\fR -.ad -.sp .6 -.RS 4n -The \fBSITE EXEC\fR feature traditionally limits the number of lines of output -that may be sent to the remote client. Use this clause to set this limit. If -this clause is omitted, the limit is 20 lines. A limit of 0 (zero) implies no -limit. Be very careful if you choose to remove the limit. If a clause is found -matching the remote user's class, that limit is used. Otherwise, the clause -with class '*', or no class given, is used. For example: -.sp -.in +2 -.nf -site-exec-max-lines 200 remote -site-exec-max-lines 0 local -site-exec-max-lines 25 -.fi -.in -2 - -limits output from \fBSITE EXEC\fR (and therefore \fBSITE INDEX\fR) to 200 -lines for remote users, specifies there is no limit at all for local users, and -sets a limit of 25 lines for all other users. -.RE - -.sp -.ne 2 -.na -\fB\fBdns refuse_mismatch\fR \fIfilename\fR [\fBoverride\fR]\fR -.ad -.sp .6 -.RS 4n -Refuse FTP sessions when the forward and reverse lookups for the remote site do -not match. Lookups are done using the system's name service as configured in -\fBnsswitch.conf\fR(4). Display the named file, like a message file, -admonishing the user. If the optional override is specified, allow the -connection after complaining. -.RE - -.sp -.ne 2 -.na -\fB\fBdns refuse_no_reverse\fR \fIfilename\fR [\fBoverride\fR]\fR -.ad -.sp .6 -.RS 4n -Refuse FTP sessions when the remote host's IP address has no associated name. -Lookups are done using the system's name service as configured in -\fBnsswitch.conf\fR(4). Display the named file, such as a message file, -admonishing the user. If the optional override is specified, allow the -connection after complaining. -.RE - -.sp -.ne 2 -.na -\fB\fBdns resolveroptions\fR [\fBoptions\fR]\fR -.ad -.sp .6 -.RS 4n -Modify certain internal resolver variables. This only has an effect when DNS is -used as the system's name service. The line takes a series of options which are -used to set the RES_OPTIONS environment variable, see resolv.conf(4) for -details. For example: -.sp -.in +2 -.nf -dns resolveroptions rotate attempts:1 -.fi -.in -2 - -turns on querying name servers round-robin and selects querying each name -server only once. -.RE - -.sp -.LP -Lines that begin with a \fB#\fR sign are treated as comment lines and are -ignored. -.SH FILES -.sp -.ne 2 -.na -\fB \fB/etc/ftpd/ftpaccess\fR\fR -.ad -.RS 24n - -.RE - -.SH ATTRIBUTES -.sp -.LP -See \fBattributes\fR(5) for descriptions of the following attributes: -.sp - -.sp -.TS -box; -c | c -l | l . -ATTRIBUTE TYPE ATTRIBUTE VALUE -_ -Interface Stability External -.TE - -.SH SEE ALSO -.sp -.LP -\fBcompress\fR(1), \fBls\fR(1), \fBtar\fR(1), \fBftpaddhost\fR(1M), -\fBftpconfig\fR(1M), \fBftpshut\fR(1M), \fBin.ftpd\fR(1M), \fBchroot\fR(2), -\fBnice\fR(2), \fBumask\fR(2), \fBgetgrnam\fR(3C), \fBresolver\fR(3RESOLV), -\fBftpconversions\fR(4), \fBftpgroups\fR(4), \fBftpservers\fR(4), -\fBftpusers\fR(4), \fBnsswitch.conf\fR(4), \fBresolv.conf\fR(4), -\fBtimezone\fR(4), \fBxferlog\fR(4), \fBattributes\fR(5), \fBfnmatch\fR(5) -.sp -.LP -Crocker, David H. \fIRFC 822, Standard For The Format Of ARPA Internet Text -Messages\fR. Network Information Center. August 1982. -.sp -.LP -St. Johns, Michael. \fIRFC 931, Authentication Server\fR. Network Working -Group. January 1985. diff --git a/usr/src/man/man4/ftpconversions.4 b/usr/src/man/man4/ftpconversions.4 deleted file mode 100644 index d810465d80..0000000000 --- a/usr/src/man/man4/ftpconversions.4 +++ /dev/null @@ -1,254 +0,0 @@ -'\" te -.\" Copyright (C) 2001, Sun Microsystems, Inc. All Rights Reserved -.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License. -.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License. -.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner] -.TH FTPCONVERSIONS 4 "May 1, 2003" -.SH NAME -ftpconversions \- FTP Server conversions database -.SH SYNOPSIS -.LP -.nf -\fB/etc/ftpd/ftpconversions\fR -.fi - -.SH DESCRIPTION -.sp -.LP -When the FTP Server, \fBin.ftpd\fR(1M), receives the retrieve (\fBRETR\fR) -command, if the specified file does not exist, it looks for a conversion to -change an existing file or directory of the same base name into the format -requested, subject to the \fBftpaccess\fR(4) \fBcompress\fR and \fBtar\fR -capabilities. -.sp -.LP -The conversions and their attributes known by \fBin.ftpd\fR(1M) are stored in -an \fBASCII\fR file of the following format. Each line in the file provides a -description for a single conversion. The fields in this file are separated by -colons (:). -.sp -.in +2 -.nf -%s:%s:%s:%s:%s:%s:%s:%s - 1 2 3 4 5 6 7 8 -.fi -.in -2 -.sp - -.sp -.LP -The fields are described as follows: -.sp -.ne 2 -.na -\fB1\fR -.ad -.RS 5n -\fBStrip prefix\fR. -.RE - -.sp -.ne 2 -.na -\fB2\fR -.ad -.RS 5n -\fBStrip postfix\fR. -.RE - -.sp -.ne 2 -.na -\fB3\fR -.ad -.RS 5n -\fBAddon prefix\fR. -.RE - -.sp -.ne 2 -.na -\fB4\fR -.ad -.RS 5n -\fBAddon postfix\fR. -.RE - -.sp -.ne 2 -.na -\fB5\fR -.ad -.RS 5n -\fBExternal command\fR. -.RE - -.sp -.ne 2 -.na -\fB6\fR -.ad -.RS 5n -\fBTypes\fR. -.RE - -.sp -.ne 2 -.na -\fB7\fR -.ad -.RS 5n -\fBOptions\fR. -.RE - -.sp -.ne 2 -.na -\fB8\fR -.ad -.RS 5n -\fBDescription\fR. -.RE - -.sp -.LP -The \fBStrip prefix\fR and \fBAddon prefix\fR fields are not currently -supported. -.sp -.LP -The \fBStrip postfix\fR and \fBaddon postfix\fR fields are extensions to be -added to or removed from the requested \fBfilename\fR in attempting to produce -the name of an existing file or directory. When the attempt succeeds, the FTP -Server runs the external command associated with the conversion. The magic -cookie \fB%s\fR in the argument is passed to the command, replaced with the -name of the existing file or directory. -.sp -.LP -\fBExternal command\fR is the absolute pathname of a command to run followed by -the appropriate options to carry out the conversion. The standard output of the -command is sent back in response to the \fBRETR\fR (retrieve) command. For -anonymous and guest users to be able to execute the command, it must be present -in their \fBchroot'd\fR hierarchy along with any necessary dynamic libraries. -.sp -.LP -\fBTypes\fR specifies the conversion type. The following values are recognized: -.sp -.ne 2 -.na -\fB\fBT_ASCII\fR\fR -.ad -.RS 11n -ASCII transfers are allowed of a file produced by the conversion. -.RE - -.sp -.ne 2 -.na -\fB\fB\fR\fBT_DIR\fR\fR -.ad -.RS 11n -Directories can be converted. -.RE - -.sp -.ne 2 -.na -\fB\fBT_REG\fR\fR -.ad -.RS 11n -Regular files can be converted. -.RE - -.sp -.LP -\fBOptions\fR are checked against the \fBftpaccess\fR(4) \fBcompress\fR and -\fBtar\fR capabilities and are recorded in the \fBspecial-action-flag\fR field -that is written to the FTP Server logfile. See \fBxferlog\fR(4). The following -options are supported: -.sp -.ne 2 -.na -\fB\fBO_COMPRESS\fR\fR -.ad -.RS 16n -conversion compresses -.RE - -.sp -.ne 2 -.na -\fB\fBO_TAR\fR\fR -.ad -.RS 16n -conversion archives -.RE - -.sp -.ne 2 -.na -\fB\fBO_UNCOMPRESS\fR\fR -.ad -.RS 16n -conversion uncompresses -.RE - -.sp -.LP -You can specify more than one option by using "\fB|\fR" to separate options. -For example, \fBO_TAR|O_COMPRESS\fR specifies that the conversion archives and -compresses. -.sp -.LP - \fBDescription\fR is a one word description of the conversion that is used in -error messages returned to the FTP client. -.sp -.LP -Lines that begin with a \fB#\fR sign are treated as comment lines and are -ignored. -.SH EXAMPLES -.LP -\fBExample 1 \fRCompressing a Regular File for Transfer -.sp -.LP -The following example specifies a conversion which generates \fBfilename.Z\fR -by compressing an existing file \fBfilename\fR. The conversion can only be -applied to regular files, not directories, and the absence of \fBT_ASCII\fR -prevents the resulting file from being transferred in ASCII mode. - -.sp -.in +2 -.nf -: : :.Z:/usr/bin/compress -c %s:T_REG:O_COMPRESS:COMPRESS -.fi -.in -2 - -.LP -\fBExample 2 \fR Uncompressing and Transferring in ASCII Mode -.sp -.LP -The following example specifies a conversion that takes \fBfilename.Z\fR and -uncompresses it to produce \fBfilename\fR, which then can be transferred in -ASCII mode. - -.sp -.in +2 -.nf -:.Z: : :/usr/bin/compress -cd %s:T_REG|T_ASCII:O_UNCOMPRESS:UNCOMPRESS -.fi -.in -2 - -.SH FILES -.sp -.ne 2 -.na -\fB\fB/etc/ftpd/ftpconversions\fR\fR -.ad -.RS 28n - -.RE - -.SH SEE ALSO -.sp -.LP -\fBldd\fR(1), \fBin.ftpd\fR(1M), \fBftpaccess\fR(4), \fBxferlog\fR(4), -\fBattributes\fR(5) diff --git a/usr/src/man/man4/ftpgroups.4 b/usr/src/man/man4/ftpgroups.4 deleted file mode 100644 index 4032b99cc9..0000000000 --- a/usr/src/man/man4/ftpgroups.4 +++ /dev/null @@ -1,111 +0,0 @@ -'\" te -.\" Copyright (C) 2003, Sun Microsystems, Inc. All Rights Reserved -.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License. -.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License. -.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner] -.TH FTPGROUPS 4 "May 1, 2003" -.SH NAME -ftpgroups \- FTP Server enhanced group access file -.SH SYNOPSIS -.LP -.nf -\fB/etc/ftpd/ftpgroups\fR -.fi - -.SH DESCRIPTION -.sp -.LP -The \fBftpgroups\fR file contains the enhanced group access information. -.sp -.LP -After login, if the \fBftpaccess\fR(4) file includes \fIprivate\fR \fIyes\fR, -the user may use the \fBSITE GROUP\fR and \fBSITE GPASS\fR commands to specify -an enhanced access group and a password for that group. If the access group -name and password are valid, the FTP Server executes \fBsetuid\fR(2) to make -the user a member of the real group listed in the \fBftpgroups\fR file. -.sp -.LP -The format for the \fBftpgroups\fR file is: -.sp -.in +2 -.nf -accessgroup:encrypted_password:real_group_name -.fi -.in -2 - -.sp -.LP -The fields are defined as follows: -.sp -.ne 2 -.na -\fB\fIaccessgroup\fR\fR -.ad -.RS 22n -An arbitrary string of alphanumeric and punctuation characters. -.RE - -.sp -.ne 2 -.na -\fB\fIencrypted_password\fR\fR -.ad -.RS 22n -The group password encrypted exactly like in \fB/etc/shadow\fR. -.RE - -.sp -.ne 2 -.na -\fB\fIreal_group_name\fR\fR -.ad -.RS 22n -The name of a valid group returned by \fBgetgrnam\fR(3C). -.RE - -.sp -.LP -The \fBprivatepw\fR utility is an administrative tool to add, delete and list -enhanced access group information in the \fBftpgroups\fR file. See -\fBprivatepw\fR(1M). Lines that begin with a \fB#\fR sign are treated as -comment lines and are ignored. -.SH FILES -.sp -.ne 2 -.na -\fB\fB/etc/ftpd/ftpgroups\fR\fR -.ad -.RS 23n - -.RE - -.sp -.ne 2 -.na -\fB\fB/etc/ftpd/ftpaccess\fR\fR -.ad -.RS 23n - -.RE - -.SH ATTRIBUTES -.sp -.LP -See \fBattributes\fR(5) for descriptions of the following attributes: -.sp - -.sp -.TS -box; -c | c -l | l . -ATTRIBUTE TYPE ATTRIBUTE VALUE -_ -Interface Stability External -.TE - -.SH SEE ALSO -.sp -.LP -\fBin.ftpd\fR(1M), \fBprivatepw\fR(1M), \fBsetuid\fR(2), \fBgetgrnam\fR(3C), -\fBftpaccess\fR(4), \fBgroup\fR(4), \fBshadow\fR(4), \fBattributes\fR(5) diff --git a/usr/src/man/man4/ftphosts.4 b/usr/src/man/man4/ftphosts.4 deleted file mode 100644 index 8265966c48..0000000000 --- a/usr/src/man/man4/ftphosts.4 +++ /dev/null @@ -1,107 +0,0 @@ -'\" te -.\" Copyright (C) 2002, Sun Microsystems, Inc. All Rights Reserved -.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License. -.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License. -.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner] -.TH FTPHOSTS 4 "May 1, 2003" -.SH NAME -ftphosts \- FTP Server individual user host access file -.SH SYNOPSIS -.LP -.nf -\fB/etc/ftpd/ftphosts\fR -.fi - -.SH DESCRIPTION -.sp -.LP -The \fBftphosts\fR file is used to allow or deny access to accounts from -specified hosts. The following access capabilities are supported: -.sp -.ne 2 -.na -\fB\fBallow \fIusername\fR \fIaddrglob\fR [\fIaddrglob\fR...]\fR\fR -.ad -.sp .6 -.RS 4n -Only allow users to login as \fIusername\fR from host(s) that match -\fIaddrglob\fR. -.RE - -.sp -.ne 2 -.na -\fB\fBdeny \fIusername\fR \fIaddrglob\fR [\fIaddrglob\fR...]\fR\fR -.ad -.sp .6 -.RS 4n -Do not allow users to login as \fIusername\fR from host(s) that match -\fIaddrglob\fR. -.RE - -.sp -.LP -A \fIusername\fR of \fB*\fR matches all users. A \fIusername\fR of -\fBanonymous\fR or \fBftp\fR specifies the anonymous user. -.sp -.LP -\fIaddrglob\fR is a regular expression that is matched against hostnames or IP -addresses. \fIaddrglob\fR may also be in the form \fBaddress:netmask\fR or -\fBaddress/CIDR\fR, or be the name of a file that starts with a slash -('\fB/\fR') and contains additional address globs. An exclamation mark -(`\fB!\fR') placed before the \fBaddrglob\fR negates the test. -.sp -.LP -The first \fBallow\fR or \fBdeny\fR entry in the \fBftphosts\fR file that -matches a \fIusername\fR and host is used. If no entry exists for a -\fIusername\fR, then access is allowed. Otherwise, a matching allow entry is -required to permit access. -.SH EXAMPLES -.sp -.LP -You can use the following \fBftphosts\fR file to allow anonymous access from -any host except those on the class A network 10, with the exception of -\fB10.0.0.*\fR IP addresses, which are allowed access: -.sp -.in +2 -.nf -allow ftp 10.0.0.* -deny ftp 10.*.*.* -allow ftp * -.fi -.in -2 - -.sp -.LP -\fB10.0.0.*\fR can be written as \fB10.0.0.0:255.255.255.0\fR or -\fB10.0.0.0/24\fR. -.SH FILES -.sp -.ne 2 -.na -\fB\fB/etc/ftpd/ftphosts\fR\fR -.ad -.RS 22n - -.RE - -.SH ATTRIBUTES -.sp -.LP -See \fBattributes\fR(5) for descriptions of the following attributes: -.sp - -.sp -.TS -box; -c | c -l | l . -ATTRIBUTE TYPE ATTRIBUTE VALUE -_ -Interface Stability External -.TE - -.SH SEE ALSO -.sp -.LP - \fBin.ftpd\fR(1M), \fBftpaccess\fR(4), \fBattributes\fR(5) diff --git a/usr/src/man/man4/ftpservers.4 b/usr/src/man/man4/ftpservers.4 deleted file mode 100644 index 743c85d038..0000000000 --- a/usr/src/man/man4/ftpservers.4 +++ /dev/null @@ -1,177 +0,0 @@ -'\" te -.\" Copyright (C) 2003, Sun Microsystems, Inc. All Rights Reserved -.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License. -.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License. -.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner] -.TH FTPSERVERS 4 "May 1, 2003" -.SH NAME -ftpservers \- FTP Server virtual hosting configuration file -.SH SYNOPSIS -.LP -.nf -/etc/ftpd/ftpservers -.fi - -.SH DESCRIPTION -.sp -.LP -The \fBftpservers\fR file is used to configure complete virtual hosting. In -contrast to limited virtual hosting, complete virtual hosting allows separate -configuration files to be specified for each virtual host. -.sp -.LP -The set of configuration files for each virtual host are placed in their own -directory. The \fBftpservers\fR file associates the address of each virtual -host with the directory its configuration files are stored in. The virtual host -configuration files must be named: -.sp -.ne 2 -.na -\fB\fBftpaccess\fR\fR -.ad -.RS 18n -Virtual host's access file -.RE - -.sp -.ne 2 -.na -\fB\fBftpusers\fR\fR -.ad -.RS 18n -Restricts the accounts that can use the virtual host -.RE - -.sp -.ne 2 -.na -\fB\fBftpgroups\fR\fR -.ad -.RS 18n -Virtual hosts enhanced group access file -.RE - -.sp -.ne 2 -.na -\fB\fBftphosts\fR\fR -.ad -.RS 18n -Allow or deny usernames access to the virtual host -.RE - -.sp -.ne 2 -.na -\fB\fBftpconversions\fR\fR -.ad -.RS 18n -Customize conversions available from the virtual host -.RE - -.sp -.LP -You do not need to put every file in each virtual host directory. If you want a -virtual host to use the master copy of a file, then do not include it in the -virtual host directory. If the file is not included, the master copy from the -\fB/etc/ftpd\fR directory will be used. -.sp -.LP -The file names must match exactly. If you misspell any of them or name them -differently, the server will not find them, and the server will use the master -copy instead. -.sp -.LP -The \fBftpaddhost\fR utility is an administrative tool to configure virtual -hosts. See \fBftpaddhost\fR(1M). -.SS "File Format" -.sp -.LP -There are two fields to each entry in the \fBftpservers\fR file: -.sp -.in +2 -.nf -address directory-containing-configuration-files -.fi -.in -2 - -.sp -.LP -For example: -.sp -.in +2 -.nf -10.196.145.10 /etc/ftpd/virtual-ftpd/10.196.145.10 -10.196.145.200 /etc/ftpd//virtual-ftpd/10.196.145.200 -some.domain INTERNAL -.fi -.in -2 - -.sp -.LP -When an FTP client connects to the FTP Server, \fBin.ftpd\fR(1M) tries to match -the IP address to which the FTP client connected with one found in the -\fBftpservers\fR file. -.sp -.LP -The \fBaddress\fR can be an IPv4 or IPv6 address, or a hostname. -.sp -.LP -If a match is found, The FTP server uses any configuration files found in the -associated directory. -.sp -.LP -If a match is not found, or an invalid directory path is encountered, the -default paths to the configuration files are used. The use of \fBINTERNAL\fR in -the example above fails the check for a specific directory, and the master -configuration files will be used. -.sp -.LP -Either the actual IP address or a specific hostname can be used to specify the -virtual host. It is better to specify the actual IP of the virtual host, as it -reduces the need for a domain lookup and eliminates DNS security related naming -issues, for example: -.sp -.in +2 -.nf -10.196.145.20 /etc/ftpd/config/faqs.org/ -ftp.some.domain /etc/ftpd/config/faqs.org/ -.fi -.in -2 - -.sp -.LP -Lines that begin with a \fB#\fR sign are treated as comment lines and are -ignored. -.SH FILES -.sp -.ne 2 -.na -\fB/etc/ftpd/ftpservers\fR -.ad -.RS 24n - -.RE - -.SH ATTRIBUTES -.sp -.LP -See \fBattributes\fR(5) for descriptions of the following attributes: -.sp - -.sp -.TS -box; -c | c -l | l . -ATTRIBUTE TYPE ATTRIBUTE VALUE -_ -Interface Stability External -.TE - -.SH SEE ALSO -.sp -.LP -\fBftpaddhost\fR(1M), \fBin.ftpd\fR(1M), \fBftpaccess\fR(4), -\fBftpconversions\fR(4), \fBftpgroups\fR(4), \fBftphosts\fR(4), -\fBftpusers\fR(4), \fBattributes\fR(5) diff --git a/usr/src/man/man4/ftpusers.4 b/usr/src/man/man4/ftpusers.4 index 0c8e244593..54ba4780ca 100644 --- a/usr/src/man/man4/ftpusers.4 +++ b/usr/src/man/man4/ftpusers.4 @@ -13,7 +13,6 @@ ftpusers \- file listing users to be disallowed ftp login privileges .fi .SH DESCRIPTION -.sp .LP The \fBftpusers\fR file lists users for whom \fBftp\fR login privileges are disallowed. Each \fBftpuser\fR entry is a single line of the form: @@ -84,7 +83,6 @@ security policy. .LP Lines that begin with \fB#\fR are treated as comment lines and are ignored. .SH FILES -.sp .ne 2 .na \fB\fB/etc/ftpd/ftpusers\fR\fR @@ -131,7 +129,6 @@ shadow password file .RE .SH ATTRIBUTES -.sp .LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -151,7 +148,6 @@ Interface Stability See below. The interface stability for \fB/etc/ftpd/ftpusers\fR is Volatile. The interface stability for \fB/etc/ftpusers\fR is (Obsolete). .SH SEE ALSO -.sp .LP -\fBlogin\fR(1), \fBin.ftpd\fR(1M), \fBftpaccess\fR(4), \fBftphosts\fR(4), +\fBlogin\fR(1), \fBftphosts\fR(4), \fBpasswd\fR(4), \fBshadow\fR(4), \fBattributes\fR(5), \fBenviron\fR(5) diff --git a/usr/src/man/man4/netrc.4 b/usr/src/man/man4/netrc.4 index b84a9c970e..3098daf61f 100644 --- a/usr/src/man/man4/netrc.4 +++ b/usr/src/man/man4/netrc.4 @@ -8,7 +8,6 @@ .SH NAME netrc \- file for ftp remote login data .SH DESCRIPTION -.sp .LP The \fB\&.netrc\fR file contains data for logging in to a remote host over the network for file transfers by \fBftp\fR(1). This file resides in the user's @@ -136,7 +135,6 @@ allows an autologin to the machine \fBray\fR using the login name \fBdemo\fR with password \fBmypassword\fR. .SH FILES -.sp .ne 2 .na \fB\fB~/.netrc\fR\fR @@ -146,6 +144,5 @@ with password \fBmypassword\fR. .RE .SH SEE ALSO -.sp .LP -\fBchmod\fR(1), \fBftp\fR(1), \fBin.ftpd\fR(1M) +\fBchmod\fR(1), \fBftp\fR(1) diff --git a/usr/src/man/man4/pam.conf.4 b/usr/src/man/man4/pam.conf.4 index 7e9274aacc..160a79032c 100644 --- a/usr/src/man/man4/pam.conf.4 +++ b/usr/src/man/man4/pam.conf.4 @@ -13,7 +13,6 @@ pam.conf \- configuration file for pluggable authentication modules .fi .SH DESCRIPTION -.sp .LP \fBpam.conf\fR is the configuration file for the Pluggable Authentication Module architecture, or \fBPAM\fR. A \fBPAM\fR module provides functionality @@ -66,7 +65,6 @@ Provides functionality to change a user's authentication token or password. Each of the four service modules can be implemented as a shared library object which can be referenced in the \fBpam.conf\fR configuration file. .SS "Simplified pam.conf Configuration File" -.sp .LP The \fBpam.conf\fR file contains a listing of services. Each service is paired with a corresponding service module. When a service is requested, its @@ -151,7 +149,6 @@ This field can be used by the modules to turn on debugging or to pass any module specific parameters such as a \fBTIMEOUT\fR value. The options supported by the modules are documented in their respective manual pages. .SS "Integrating Multiple Authentication Services With Stacking" -.sp .LP When a \fIservice_name\fR of the same \fImodule_type\fR is defined more than once, the service is said to be stacked. Each module referenced in the @@ -314,7 +311,6 @@ Some modules return \fBPAM_IGNORE\fR in certain situations. In these cases the whether or not it is \fBbinding\fR, \fBrequisite\fR, \fBrequired\fR, \fBoptional\fR, or \fBsufficient\fR. .SS "Utilities and Files" -.sp .LP The specific service names and module types for each service should be documented in the man page for that service. For instance, the \fBsshd\fR(1M) @@ -424,7 +420,6 @@ OTHER password include unix_common .sp .SH ATTRIBUTES -.sp .LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -443,9 +438,8 @@ Interface Stability See Below. .LP The format is Stable. The contents has no stability attributes. .SH SEE ALSO -.sp .LP -\fBlogin\fR(1), \fBpasswd\fR(1), \fBin.ftpd\fR(1M), \fBin.rlogind\fR(1M), +\fBlogin\fR(1), \fBpasswd\fR(1), \fBin.rlogind\fR(1M), \fBin.rshd\fR(1M), \fBin.telnetd\fR(1M), \fBin.uucpd\fR(1M), \fBinit\fR(1M), \fBrpc.rexd\fR(1M), \fBsac\fR(1M), \fBttymon\fR(1M), \fBsu\fR(1M), \fBpam\fR(3PAM), \fBsyslog\fR(3C), \fBlibpam\fR(3LIB), \fBattributes\fR(5), @@ -454,7 +448,6 @@ The format is Stable. The contents has no stability attributes. \fBpam_passwd_auth\fR(5), \fBpam_unix_account\fR(5), \fBpam_unix_auth\fR(5), \fBpam_unix_session\fR(5) .SH NOTES -.sp .LP The \fBpam_unix\fR module is no longer supported. Similar functionality is provided by \fBpam_authtok_check\fR(5), \fBpam_authtok_get\fR(5), diff --git a/usr/src/man/man4/passwd.4 b/usr/src/man/man4/passwd.4 index 5e5670d694..533f5279b4 100644 --- a/usr/src/man/man4/passwd.4 +++ b/usr/src/man/man4/passwd.4 @@ -15,7 +15,6 @@ passwd \- password file .fi .SH DESCRIPTION -.sp .LP The file \fB/etc/passwd\fR is a local source of information about users' accounts. The password file can be used in conjunction with other naming @@ -306,7 +305,6 @@ will be able to log in with their usual password, shell, and home directory, but with a \fIgcos\fR field of \fBGuest\fR .SH FILES -.sp .ne 2 .na \fB\fB/etc/nsswitch.conf\fR\fR @@ -334,12 +332,11 @@ but with a \fIgcos\fR field of \fBGuest\fR .RE .SH SEE ALSO -.sp .LP \fBchgrp\fR(1), \fBchown\fR(1), \fBfinger\fR(1), \fBgroups\fR(1), \fBlogin\fR(1), \fBnewgrp\fR(1), \fBnispasswd\fR(1), \fBpasswd\fR(1), \fBsh\fR(1), \fBsort\fR(1), \fBdomainname\fR(1M), \fBgetent\fR(1M), -\fBin.ftpd\fR(1M), \fBpassmgmt\fR(1M), \fBpwck\fR(1M), \fBpwconv\fR(1M), +\fBpassmgmt\fR(1M), \fBpwck\fR(1M), \fBpwconv\fR(1M), \fBsu\fR(1M), \fBuseradd\fR(1M), \fBuserdel\fR(1M), \fBusermod\fR(1M), \fBa64l\fR(3C), \fBcrypt\fR(3C), \fBgetpw\fR(3C), \fBgetpwnam\fR(3C), \fBgetspnam\fR(3C), \fBputpwent\fR(3C), \fBgroup\fR(4), \fBhosts.equiv\fR(4), diff --git a/usr/src/man/man4/syslog.conf.4 b/usr/src/man/man4/syslog.conf.4 index 310e5bcdd6..7dcc4f5731 100644 --- a/usr/src/man/man4/syslog.conf.4 +++ b/usr/src/man/man4/syslog.conf.4 @@ -12,7 +12,6 @@ syslog.conf \- configuration file for syslogd system log daemon .fi .SH DESCRIPTION -.sp .LP The file \fB/etc/syslog.conf\fR contains information used by the system log daemon, \fBsyslogd\fR(1M), to forward a system message to appropriate log files @@ -151,8 +150,6 @@ Designated for the BSD security/authorization system. .ad .RS 12n Designated for the file transfer system. -The current version of \fBin.ftpd\fR(1M) does not use this facility -for logging. .RE .sp @@ -405,7 +402,6 @@ All messages from the authorization system of \fBwarning\fR level or higher are logged in the file \fB/var/log/auth\fR. .SH ATTRIBUTES -.sp .LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -421,7 +417,6 @@ Interface Stability Stable .TE .SH SEE ALSO -.sp .LP \fBat\fR(1), \fBcrontab\fR(1), \fBlogger\fR(1), \fBlogin\fR(1), \fBlp\fR(1), \fBlpc\fR(1B), \fBlpr\fR(1B), \fBm4\fR(1), \fBcron\fR(1M), \fBgetty\fR(1M), diff --git a/usr/src/man/man4/xferlog.4 b/usr/src/man/man4/xferlog.4 deleted file mode 100644 index e76eb4f6a7..0000000000 --- a/usr/src/man/man4/xferlog.4 +++ /dev/null @@ -1,433 +0,0 @@ -'\" te -.\" Copyright (C) 2003, Sun Microsystems, Inc. All Rights Reserved -.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License. -.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License. -.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner] -.TH XFERLOG 4 "Apr 25, 2003" -.SH NAME -xferlog \- FTP Server transfer log file -.SH SYNOPSIS -.LP -.nf -\fB/var/log/xferlog\fR -.fi - -.SH DESCRIPTION -.sp -.LP -The \fBxferlog\fR file contains transfer logging information from the FTP -Server, \fBin.ftpd\fR(1M). You can use the logfile capability to change the -location of the log file. See \fBftpaccess\fR(4). -.sp -.LP -By default, each server entry is composed of a single line of the following -form. All fields are separated by spaces. -.sp -.in +2 -.nf -\fIcurrent-time\fR \fItransfer-time \fR \fIremote-host\fR \fIbytes-transferred\fR \e - \fIfilename\fR -\fItransfer-type\fR \fIspecial-action-flag\fR \fIdirection\fR \fIaccess-mode\fR \fIusername\fR -\fIservice-name\fR \fIauthentication-method\fR \fIauthenticated-user-id\fR \e - \fIcompletion-status\fR -.fi -.in -2 - -.sp -.LP -The \fBxferlog\fR format capability can be used to customize the transfer log -file format used. In addition to those in the default format, it also supports -\fBchroot-filename\fR, \fBfile-size\fR, and \fBrestart-offset\fR fields. See -\fBftpaccess\fR(4). -.sp -.LP -The fields are defined as follows: -.sp -.ne 2 -.na -\fB\fIcurrent-time\fR\fR -.ad -.RS 25n -The current local time in the form \fBDDD MMM dd hh:mm:ss YYYY\fR, where: -.sp -.ne 2 -.na -\fB\fBDDD\fR\fR -.ad -.RS 8n -Is the day of the week -.RE - -.sp -.ne 2 -.na -\fB\fBMMM\fR\fR -.ad -.RS 8n -Is the month -.RE - -.sp -.ne 2 -.na -\fB\fBdd\fR\fR -.ad -.RS 8n -Is the day of the month -.RE - -.sp -.ne 2 -.na -\fB\fBhh\fR\fR -.ad -.RS 8n -Is the hour -.RE - -.sp -.ne 2 -.na -\fB\fBmm\fR\fR -.ad -.RS 8n -Is the minutes -.RE - -.sp -.ne 2 -.na -\fB\fBss\fR\fR -.ad -.RS 8n -Is the seconds -.RE - -.sp -.ne 2 -.na -\fB\fBYYYY\fR\fR -.ad -.RS 8n -Is the year -.RE - -.RE - -.sp -.ne 2 -.na -\fB\fItransfer-time \fR\fR -.ad -.RS 25n -The total time in seconds for the transfer -.RE - -.sp -.ne 2 -.na -\fB\fIremote-host\fR\fR -.ad -.RS 25n -The remote host name -.RE - -.sp -.ne 2 -.na -\fB\fIbytes-transferred\fR\fR -.ad -.RS 25n -The number of bytes transferred -.RE - -.sp -.ne 2 -.na -\fB\fIfilename\fR\fR -.ad -.RS 25n -The absolute pathname of the transferred file -.RE - -.sp -.ne 2 -.na -\fB\fItransfer-type\fR\fR -.ad -.RS 25n -A single character indicating the type of transfer: -.sp -.ne 2 -.na -\fBa\fR -.ad -.RS 5n -Indicates an ascii transfer -.RE - -.sp -.ne 2 -.na -\fBb\fR -.ad -.RS 5n -Indicates a binary transfer -.RE - -.RE - -.sp -.ne 2 -.na -\fB\fIspecial-action-flag\fR\fR -.ad -.RS 25n -One or more single character flags that indicate any special action taken. The -\fIspecial-action-flag\fR can have one of more of the following values: -.sp -.ne 2 -.na -\fBC\fR -.ad -.RS 16n -File was compressed -.RE - -.sp -.ne 2 -.na -\fBU\fR -.ad -.RS 16n -File was uncompressed -.RE - -.sp -.ne 2 -.na -\fBT\fR -.ad -.RS 16n -File was archived, for example, by using \fBtar\fR(1) -.RE - -.sp -.ne 2 -.na -\fB_ (underbar)\fR -.ad -.RS 16n -No action was taken. -.RE - -.RE - -.sp -.ne 2 -.na -\fB\fIdirection\fR\fR -.ad -.RS 25n -The direction of the transfer. \fIdirection\fR can have one of the following -values: -.sp -.ne 2 -.na -\fBo\fR -.ad -.RS 5n -Outgoing -.RE - -.sp -.ne 2 -.na -\fBi\fR -.ad -.RS 5n -Incoming -.RE - -.RE - -.sp -.ne 2 -.na -\fB\fIaccess-mode\fR\fR -.ad -.RS 25n -The method by which the user is logged in. \fIaccess-mode\fR can have one of -the following values: -.sp -.ne 2 -.na -\fBa\fR -.ad -.RS 5n -For an anonymous user. -.RE - -.sp -.ne 2 -.na -\fBg\fR -.ad -.RS 5n -For a passworded guest user. See the description of the \fBguestgroup\fR -capability in \fBftpaccess\fR(4). -.RE - -.sp -.ne 2 -.na -\fBr\fR -.ad -.RS 5n -For a real, locally authenticated user -.RE - -.RE - -.sp -.ne 2 -.na -\fB\fIusername\fR\fR -.ad -.RS 25n -The local username, or if anonymous, the ID string given -.RE - -.sp -.ne 2 -.na -\fB\fIservice-name\fR\fR -.ad -.RS 25n -The name of the service invoked, usually \fBftp\fR -.RE - -.sp -.ne 2 -.na -\fB\fIauthentication-method\fR\fR -.ad -.RS 25n -The method of authentication used. \fIauthentication-method\fR can have one of -the following values: -.sp -.ne 2 -.na -\fB0\fR -.ad -.RS 5n -None -.RE - -.sp -.ne 2 -.na -\fB1\fR -.ad -.RS 5n -\fIRFC 931\fR authentication -.RE - -.RE - -.sp -.ne 2 -.na -\fB\fIauthenticated-user-id\fR\fR -.ad -.RS 25n -The user ID returned by the authentication method. A \fB*\fR is used if an -authenticated user ID is not available. -.RE - -.sp -.ne 2 -.na -\fB\fIcompletion-status\fR\fR -.ad -.RS 25n -A single character indicating the status of the transfer. -\fIcompletion-status\fR can have one of the following values: -.sp -.ne 2 -.na -\fBc\fR -.ad -.RS 5n -Indicates complete transfer -.RE - -.sp -.ne 2 -.na -\fBi\fR -.ad -.RS 5n -Indicates incomplete transfer -.RE - -.RE - -.sp -.ne 2 -.na -\fB\fIchroot-filename\fR\fR -.ad -.RS 25n -The pathname of the transferred file relative to the \fBchroot\fR point. This -will differ from the \fIfilename\fR field for anonymous and guest users. -.RE - -.sp -.ne 2 -.na -\fB\fIfile-size\fR\fR -.ad -.RS 25n -The size, in bytes, of the file on the server. -.RE - -.sp -.ne 2 -.na -\fB\fIrestart-offset\fR\fR -.ad -.RS 25n -The offset, in bytes, at which the file transfer was restarted (0 when no -restart offset was specified). -.RE - -.SH FILES -.sp -.LP -\fB/var/log/xferlog\fR -.SH ATTRIBUTES -.sp -.LP -See \fBattributes\fR(5) for descriptions of the following attributes: -.sp - -.sp -.TS -box; -c | c -l | l . -ATTRIBUTE TYPE ATTRIBUTE VALUE -_ -Interface Stability External -.TE - -.SH SEE ALSO -.sp -.LP -\fBtar\fR(1), \fBin.ftpd\fR(1M), \fBftpaccess\fR(4), \fBftpconversions\fR(4), -\fBattributes\fR(5) -.sp -.LP -StJohns, Mike. \fIRFC 931, Authentication Server\fR. Network Working Group. -January 1985. diff --git a/usr/src/pkg/manifests/SUNWcs.man4.inc b/usr/src/pkg/manifests/SUNWcs.man4.inc index 2dce05b2fd..2facf26cdf 100644 --- a/usr/src/pkg/manifests/SUNWcs.man4.inc +++ b/usr/src/pkg/manifests/SUNWcs.man4.inc @@ -41,6 +41,7 @@ file path=usr/share/man/man4/exec_attr.4 file path=usr/share/man/man4/format.dat.4 file path=usr/share/man/man4/fspec.4 file path=usr/share/man/man4/fstypes.4 +file path=usr/share/man/man4/ftpusers.4 file path=usr/share/man/man4/fx_dptbl.4 file path=usr/share/man/man4/group.4 file path=usr/share/man/man4/hosts.4 diff --git a/usr/src/pkg/manifests/SUNWcs.mf b/usr/src/pkg/manifests/SUNWcs.mf index e008feecad..14f457a1d0 100644 --- a/usr/src/pkg/manifests/SUNWcs.mf +++ b/usr/src/pkg/manifests/SUNWcs.mf @@ -1688,8 +1688,6 @@ license usr/src/cmd/cmd-inet/usr.sbin/THIRDPARTYLICENSE.route \ license=usr/src/cmd/cmd-inet/usr.sbin/THIRDPARTYLICENSE.route license usr/src/cmd/cmd-inet/usr.sbin/ifconfig/THIRDPARTYLICENSE \ license=usr/src/cmd/cmd-inet/usr.sbin/ifconfig/THIRDPARTYLICENSE -license usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/LICENSE \ - license=usr/src/cmd/cmd-inet/usr.sbin/in.ftpd/LICENSE license usr/src/cmd/cmd-inet/usr.sbin/traceroute/THIRDPARTYLICENSE \ license=usr/src/cmd/cmd-inet/usr.sbin/traceroute/THIRDPARTYLICENSE license usr/src/cmd/cron/THIRDPARTYLICENSE \ @@ -1734,6 +1732,7 @@ link path=etc/format target=../usr/sbin/format link path=etc/fsck target=../usr/sbin/fsck link path=etc/fsdb target=../usr/sbin/fsdb link path=etc/fstyp target=../usr/sbin/fstyp +link path=etc/ftpusers target=./ftpd/ftpusers link path=etc/getty target=../usr/lib/saf/ttymon link path=etc/grpck target=../usr/sbin/grpck link path=etc/halt target=../usr/sbin/halt diff --git a/usr/src/pkg/manifests/SUNWftp.mf b/usr/src/pkg/manifests/SUNWftp.mf index 486bd596de..46a1c2aa68 100644 --- a/usr/src/pkg/manifests/SUNWftp.mf +++ b/usr/src/pkg/manifests/SUNWftp.mf @@ -23,7 +23,9 @@ # Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. # +# Was renamed to service/network/ftp, both now obsolete + set name=pkg.fmri value=pkg:/SUNWftp@0.5.11,5.11-0.133 -set name=pkg.renamed value=true +set name=pkg.obsolete value=true +set name=org.opensolaris.noincorp value=true set name=variant.arch value=$(ARCH) -depend fmri=pkg:/service/network/ftp@0.5.11,5.11-0.133 type=require diff --git a/usr/src/pkg/manifests/network-ftp.mf b/usr/src/pkg/manifests/network-ftp.mf index 920d4ead35..3512d87df9 100644 --- a/usr/src/pkg/manifests/network-ftp.mf +++ b/usr/src/pkg/manifests/network-ftp.mf @@ -44,6 +44,7 @@ file path=usr/bin/ftp mode=0555 file path=usr/sbin/ping mode=4555 file path=usr/share/man/man1/ftp.1 file path=usr/share/man/man1m/ping.1m +file path=usr/share/man/man4/ftp.4 file path=usr/share/man/man4/netrc.4 legacy pkg=SUNWbip desc="Basic IP commands (/usr/sbin/ping, /bin/ftp)" \ name="Basic IP commands (Usr)" diff --git a/usr/src/pkg/manifests/SUNWftp.mf b/usr/src/pkg/manifests/service-network-ftp.mf similarity index 82% copy from usr/src/pkg/manifests/SUNWftp.mf copy to usr/src/pkg/manifests/service-network-ftp.mf index 486bd596de..97f373e71f 100644 --- a/usr/src/pkg/manifests/SUNWftp.mf +++ b/usr/src/pkg/manifests/service-network-ftp.mf @@ -21,9 +21,10 @@ # # Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright 2012 Nexenta Systems, Inc. All rights reserved. # -set name=pkg.fmri value=pkg:/SUNWftp@0.5.11,5.11-0.133 -set name=pkg.renamed value=true +set name=pkg.fmri value=pkg:/service/network/ftp@$(PKGVERS) +set name=pkg.obsolete value=true +set name=org.opensolaris.noincorp value=true set name=variant.arch value=$(ARCH) -depend fmri=pkg:/service/network/ftp@0.5.11,5.11-0.133 type=require -- 2.11.4.GIT