eurofile: drop eft_wuauth code

the copyright holders forbid commercial use of the code which makes it
non-free
This commit is contained in:
Rolf Leggewie 2012-03-31 20:16:22 +02:00
parent d8c54147aa
commit 3a0e53fd6c
16 changed files with 0 additions and 4662 deletions

View File

@ -1,111 +0,0 @@
src/authlib contains an authentication library derived from wu-ftpd.
It has been adapted for use with eftd by Georg v.Zezschwitz
Source code in src/authlib carries copyright notices and license
conditions of different people and organizations. This file is only
a summary therof and does neither claim to be complete nor correct.
Refer to the source files for the authoritative copyright
and license statements.
/* Copyright (c) 1989 The Regents of the University of California. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. 2.
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. 3. All advertising
* materials mentioning features or use of this software must display the
* following acknowledgement: This product includes software developed by the
* University of California, Berkeley and its contributors. 4. Neither the
* name of the University nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
* Redistribution and use in source and binary forms are permitted
* provided that: (1) source distributions retain this entire copyright
* notice and comment, and (2) distributions including binaries display
* the following acknowledgement: ``This product includes software
* developed by the University of California, Berkeley and its contributors''
* in the documentation or other materials provided with the distribution
* and in all advertising materials mentioning features or use of this
* software. 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/* 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.
*/
/* This software is Copyright 1997 by Stan Barber.
*
* Permission is hereby granted to copy, reproduce, redistribute or otherwise
* use this software as long as: there is no monetary profit gained
* specifically from the use or reproduction of this software, it is not
* sold, rented, traded or otherwise marketed, and this copyright notice is
* included prominently in any copy made.
*
* The author make no claims as to the fitness or correctness of this software
* for any use whatsoever, and it is provided as is. Any use of this software
* is at the user's own risk.
*/

View File

@ -1,182 +0,0 @@
.\" $Id: eft_wuauth.5,v 1.1 1999/06/30 16:51:02 he Exp $
.\" Copyright (c) 1985, 1988 The Regents of the University of California.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms are permitted provided
.\" that: (1) source distributions retain this entire copyright notice and
.\" comment, and (2) distributions including binaries display the following
.\" acknowledgement: ``This product includes software developed by the
.\" University of California, Berkeley and its contributors'' in the
.\" documentation or other materials provided with the distribution and in
.\" all advertising materials mentioning features or use of this software.
.\" 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
.\" ORIGINAL: ftpd.8 6.8 (Berkeley) 6/24/90
.\"
.\" @(#)$Original-Id: ftpd.8,v 1.5 1997/01/14 22:45:27 sob Exp sob $
.\"
.TH EFT_WUAUTH 5 "Jan 10, 1997"
.UC 5
.SH NAME
eft_wuauth \- authentication for eftp4linux Eurofile server based on wuftpd.
.SH DESCRIPTION
If the eftp4linux Eurofile server
.I eftd
is compiled with the CONFIG_EFTD_WUAUTH configuration option,
it uses user authentication code derived from
.I wuftpd,
the Washington University ftp daemon.
.PP
In that case
.I eftd
authenticates users according to four rules.
.IP 1)
The user name must be in the password data base,
.IR /etc/passwd ,
or whatever is appropriate for the operating system,
and the password must not be null. In this case a password
must be provided by the client before any file operations
may be performed.
.IP 2)
The user name must not appear in the file
.IR /etc/isdn/eftusers .
.IP 3)
The user must have a standard shell returned by
.IR getusershell (3).
If login failed for certain users, maybe that's because their login
shell is not listed in /etc/shells.
.IP 4)
If the user name is ``anonymous'' or ``ftp'', an
anonymous ftp account must be present in the password
file (user ``ftp''). In this case the user is allowed
to log in by specifying any password (by convention this
is given as the client host's name).
.PP
In the last case,
.I eftd
takes special measures to restrict the client's access privileges.
The server performs a
.IR chroot (2)
command to the home directory of the ``ftp'' user.
In order that system security is not breached, it is recommended
that the ``ftp'' subtree be constructed with care; the following
rules are recommended.
.IP ~ftp)
Make the home directory owned by super-user and unwritable by anyone.
.IP ~ftp/bin)
Make this directory owned by the super-user and unwritable by
anyone. This contains auxilary programs that might be forked by
.IR eftd(8)
or
.IR ftpd(8).
These programs should have mode 111.
.IR eftd(8)
currently does not need any auxilary programs. Thus, you only need to
put files here if you also want to provide anonymous ftp service.
.IP ~ftp/etc)
Make this directory owned by the super-user and unwritable by
anyone. The files
.IR passwd (5)
and
.IR group (5)
must be present for eftd
to be able to produce owner names rather than numbers in file headers
and extended format directory (T-DIR primitive) listings. Depending
on the operating system, there may be other required files. Check your
manual page for the
.IR getpwent (3)
library routine.
The password field in
.I passwd
is not used, and should not contain real encrypted passwords.
These files should be mode 444 and owned by the super-user.
Don't use the system's /etc/passwd file as the password file or
the system's /etc/group file as the group file in the ~ftp/etc directory.
.IP ~ftp/pub)
Create a subdirectory in ~ftp/pub
with the appropriate mode (777 or 733) if you want to allow normal
users to upload files.
.PP
The Eurofile file server also allows for finer grained access control
by means of the files /etc/isdn/eftaccess and /etc/isdn/efthosts.
.SH "COPYING"
The main part of eftp4linux is licensed under the LGPL. However,
eft servers using the wuauth authentication libray also contain code
copyrighted by the University of California, Berkeley,
by the Washington University in Saint Louis, and their contributors.
That code is subject to a BSD style licences with advertisment clause:
Copyright (c) 1990 The Regents of the University of California.
All rights reserved.
This code is derived from software contributed to Berkeley by
Chris Torek.
Redistribution and use in source and binary forms are permitted
provided that: (1) source distributions retain this entire
copyright notice and comment, and (2) distributions including binaries
display the following acknowledgement: ``This product includes software
developed by the University of California, Berkeley and its contributors''
in the documentation or other materials provided with the distribution
and in all advertising materials mentioning features or use of this
software. 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
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.
.SH "SEE ALSO"
.BR eftd(1) ,
.BR shells(5) ,
.BR getusershell(3) ,
.BR eftaccess(5) ,
.BR efthosts(5) ,
.BR eft_xferlog(5) ,
.BR umask(2)
.SH BUGS
The anonymous account is inherently dangerous and should be
avoided when possible.
The eftaccess amd efthosts files are currently not yet working as documented.

View File

@ -1,43 +0,0 @@
#
# Makefile for Linux 1.2.13 with gcc 2.6.3
#
# $Id: Makefile,v 1.2 2006/01/15 15:08:55 keil Exp $
#
CC = gcc
AR = ar cq
RANLIB = ranlib
LIBC = /lib/libc.a
IFLAGS =
LFLAGS =
MYCFLAGS = -O6 -fomit-frame-pointer -fno-strength-reduce -pipe ${IFLAGS} ${LFLAGS}
CFLAGS = -g
SRCS = strcasestr.c access.c divfunc.c private.c acl.c main.c sigfix.c \
# extensions.c
OBJS = strcasestr.o access.o divfunc.o private.o acl.o main.o sigfix.o \
# extensions.o
libwuauth.a: $(OBJS)
-rm -f libwuauth.a
${AR} libwuauth.a $(OBJS)
${RANLIB} libwuauth.a
clean:
-rm -f *.o libwuauth.a *~ #*#
ftp.h:
install -c -m 444 ftp.h /usr/include/arpa
.c.o:
${CC} ${CFLAGS} ${MYCFLAGS} -c $<
strcasestr.o: strcasestr.c
${CC} ${CFLAGS} ${MYCFLAGS} -c strcasestr.c
authuser.o: authuser.c
${CC} ${CFLAGS} ${MYCFLAGS} -c authuser.c
snprintf.o: snprintf.c
${CC} ${CFLAGS} ${MYCFLAGS} -c snprintf.c

View File

@ -1,94 +0,0 @@
/*
AUTHLIB
Date: 980525
Changes:
980622 some minor changes (name changes, pathnames) for ease
inclusion in eftp4linux source tree by Henner Eisen.
*/
This library is derived from some parts of wu-ftpd, the FTP server
of the Washington University. (See copyright restrictions at
the beginning of any source file containing WU code).
It was written for use with eftd, the Euro File Transfer Daemon
written by Henner Eisen for isdn4linux.
As eftd is rather tighly related to the Linux OS, some OS independent
parts have been removed for more readability (E.g. an ANSI C compiler
is required).
It passes the function "wuftp_check_user" to the outside as main
benefit:
int wuftp_check_user (char *name, char *passwd, char *isdnno)
Arguments:
- name = The user name.
Use ftp, anonymous or blank for anonymous logins
- passwd = The password the client issued
- isdnno = Instead of an IP-no as when used with ftpd, the isdn
number of the client can or should be passed.
Returns:
- 0 On failure.
The user/password combination is wrong or the user
is not allowed to log in.
See "autherrmsg" for further information.
- 1 On successful login.
If the user is using a guest account (e.g., an
anonymous user), a chroot/chdir will have been
performed by the library.
The user id of the running program is set to the
user id of the user logged in.
This library tries to keep close to the auth-schemes as used by
wu-ftpd. However, some adaptions have taken place:
- Like with wu-ftpd, you might either set the pathnames of
ftpaccess, ftphosts, ftpusers... in "pathnames.h" or
declare their directory in config.h.
However, all files related to this library are starting with
"eft" instead of "ftp". Therefore, e.g. users forbidden to
login through this library are listed in "eftusers".
- The guest-server directive may be used to restrict anonymous
access by isdn-nr (instead of alias or fqdn-dns-name).
However, the user will not get informed about other servers.
- Whereever you might restrict or enable the access in the
config files by ip-number or fqdn-name, the isdn-nr will
be used instead of ip-name or ip-number.
List of exported variables:
IMPORTED:
use_accessfile Defaults to 0
If set to 1 before calling wuftp_check_user,
eftaccess will be interpreted and applied.
EXPORTED:
char *autherrmsg - Whenever authentication has proceeded, this string
is set to either an explanation why access was
not granted or a welcome message like
"guest login o.k., access restrictions apply"
int guest 0 if normal user, 1 if "chrooted"
int anonymous 0 if normal user, 1 if anonymous login
Enjoy!
Georg v.Zezschwitz, georg@auf-der-er.de
This product includes software developed by the Washington University
in Saint Louis and its contributors.
This product includes software developed by the University of
California, Berkeley and its contributors.

View File

@ -1,924 +0,0 @@
/* 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.
*/
#ifndef lint
static char rcsid[] = "@(#)$Id: access.c,v 1.2 1999/10/05 21:23:23 he Exp $";
#endif /* not lint */
#include <stdio.h>
#include <errno.h>
#include <string.h>
#ifdef SYSSYSLOG
#include <sys/syslog.h>
#else
#include <syslog.h>
#endif
#include <time.h>
#include <ctype.h>
#include <pwd.h>
#include <grp.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <sys/param.h>
#include "config.h"
#include "pathnames.h"
#include "extensions.h"
#if defined(SVR4) || defined(ISC)
#include <fcntl.h>
#endif
extern char remotehost[],
remoteaddr[],
*aclbuf;
extern int nameserved,
anonymous,
guest,
use_accessfile;
char Shutdown[MAXPATHLEN];
#define MAXLINE 80
static char incline[MAXLINE];
int pidfd = -1;
extern int fnmatch();
/*************************************************************************/
/* 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
#ifdef __STDC__
parsetime(char *whattime)
#else
parsetime(whattime)
char *whattime;
#endif
{
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
#ifdef __STDC__
validtime(char *ptr)
#else
validtime(ptr)
char *ptr;
#endif
{
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;
}
}
/*************************************************************************/
/* FUNCTION : hostmatch */
/* PURPOSE : Match remote hostname or address against a glob string */
/* ARGUMENTS : The string to match */
/* RETURNS : 0 if no match, 1 if a match occurs */
/*************************************************************************/
int
#ifdef __STDC__
hostmatch(char *addr)
#else
hostmatch(addr)
char *addr;
#endif
{
FILE *incfile;
char *ptr;
int found = 0;
if (addr == NULL) return(0);
if (isdigit(*addr))
return(!fnmatch(addr, remoteaddr, NULL));
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: %s", addr, strerror(errno));
return(0);
}
while (!found && (fgets(incline, MAXLINE, incfile) != NULL)) {
ptr = strtok(incline, " \t\n");
if (ptr && hostmatch(ptr))
found = 1;
while (!found && ((ptr = strtok(NULL, " \t\n")) != NULL)) {
if (ptr && hostmatch(ptr))
found = 1;
}
}
fclose(incfile);
return(found);
}
else
{ /* match a hostname or hostname glob */
char *addrncase,*hostncase;
int i,j;
/* must convert both to lower case for match */
if ((addrncase = (char *)malloc(strlen(addr)+1)) == NULL)
return(0);
if ((hostncase = (char *)malloc(strlen(remotehost)+1)) == NULL){
free(addrncase);
return(0);
}
j = strlen(addr) + 1;
for (i = 0;i < j; i++)
addrncase[i] = tolower(addr[i]);
j = strlen(remotehost) + 1;
for (i = 0;i < j; i++)
hostncase[i] = tolower(remotehost[i]);
found = !fnmatch(addrncase, hostncase, NULL);
free(addrncase);
free(hostncase);
return(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
#ifdef __STDC__
acl_guestgroup(struct passwd *pw)
#else
acl_guestgroup(pw)
struct passwd *pw;
#endif
{
struct aclmember *entry = NULL;
struct group *grp;
int which;
char **member;
/* guestgroup <group> [<group> ...] */
while (getaclentry("guestgroup", &entry)) {
for (which = 0; (which < MAXARGS) && ARG[which]; which++) {
if (!(grp = getgrnam(ARG[which])))
continue;
if (pw->pw_gid == grp->gr_gid)
return (1);
for (member = grp->gr_mem; *member; member++) {
if (!strcmp(*member, 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
#ifdef __STDC__
acl_autogroup(struct passwd *pw)
#else
acl_autogroup(pw)
struct passwd *pw;
#endif
{
char class[1024];
struct aclmember *entry = NULL;
struct group *grp;
int which;
(void) acl_getclass(class);
/* autogroup <group> <class> [<class> ...] */
while (getaclentry("autogroup", &entry)) {
if (!ARG0 || !ARG1)
continue;
if ((grp = getgrnam(ARG0))) {
for (which = 1; (which < MAXARGS) && ARG[which]; which++) {
if (!strcmp(ARG[which], class)) {
pw->pw_gid = grp->gr_gid;
endgrent();
return;
}
}
} else
syslog(LOG_ERR, "autogroup: set group %s not found", ARG0);
endgrent();
}
}
/*************************************************************************/
/* 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. */
/* ARGUMENTS : pointer to buffer to class name, pointer to ACL buffer */
/*************************************************************************/
void
#ifdef __STDC__
acl_setfunctions(void)
#else
acl_setfunctions()
#endif
{
char class[1024];
extern int log_incoming_xfers,
log_outbound_xfers,
mangleopts,
log_commands,
lgi_failure_threshold;
struct aclmember *entry = NULL;
int l_compress,
l_tar,
inbound = 0,
outbound = 0,
which,
set;
log_incoming_xfers = 0;
log_outbound_xfers = 0;
log_commands = 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) && !strcmp(ARG0, "yes"))
priv_setup(_PATH_PRIVATE);
#endif /* !NO_PRIVATE */
entry = (struct aclmember *) NULL;
set = 0;
while (!set && getaclentry("compress", &entry)) {
l_compress = 0;
if (!strcasecmp(ARG0, "yes"))
l_compress = 1;
for (which = 1; (which < MAXARGS) && ARG[which]; which++) {
if (!fnmatch(ARG[which], class, NULL)) {
mangleopts |= l_compress * (O_COMPRESS | O_UNCOMPRESS);
set = 1;
}
}
}
entry = (struct aclmember *) NULL;
set = 0;
while (!set && getaclentry("tar", &entry)) {
l_tar = 0;
if (!strcasecmp(ARG0, "yes"))
l_tar = 1;
for (which = 1; (which < MAXARGS) && ARG[which]; which++) {
if (!fnmatch(ARG[which], class, NULL)) {
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 (!strcasecmp(ARG0, "commands")) {
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")) {
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;
}
}
}
/*************************************************************************/
/* 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
#ifdef __STDC__
acl_getclass(char *classbuf)
#else
acl_getclass(classbuf)
char *classbuf;
#endif
{
int which;
struct aclmember *entry = NULL;
while (getaclentry("class", &entry)) {
if (ARG0)
strcpy(classbuf, ARG0);
for (which = 2; (which < MAXARGS) && ARG[which]; which++) {
if (anonymous && strcasestr(ARG1, "anonymous") &&
hostmatch(ARG[which]))
return (1);
if (guest && strcasestr(ARG1, "guest") && hostmatch(ARG[which]))
return (1);
if (!guest && !anonymous && strcasestr(ARG1, "real") &&
hostmatch(ARG[which]))
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
#ifdef __STDC__
acl_getlimit(char *class, char *msgpathbuf)
#else
acl_getlimit(class,msgpathbuf)
char *class;
char *msgpathbuf;
#endif
{
int limit;
struct aclmember *entry = NULL;
if (msgpathbuf)
*msgpathbuf = '\0';
/* limit <class> <n> <times> [<message_file>] */
while (getaclentry("limit", &entry)) {
if (!ARG0 || !ARG1 || !ARG2)
continue;
if (!strcmp(class, ARG0)) {
limit = atoi(ARG1);
if (validtime(ARG2)) {
if (ARG3 && msgpathbuf)
strcpy(msgpathbuf, ARG3);
return (limit);
}
}
}
return (-1);
}
/*************************************************************************/
/* FUNCTION : acl_deny */
/* PURPOSE : Scan the ACL buffer and determine a deny command applies */
/* ARGUMENTS : pointer class name, pointer to ACL buffer */
/*************************************************************************/
int
#ifdef __STDC__
acl_deny(char *msgpathbuf)
#else
acl_deny(msgpathbuf)
char *msgpathbuf;
#endif
{
struct aclmember *entry = NULL;
if (msgpathbuf)
*msgpathbuf = (char) NULL;
/* deny <addrglob> [<message_file>] */
while (getaclentry("deny", &entry)) {
if (!ARG0)
continue;
if (!nameserved && !strcmp(ARG0, "!nameserved")) {
if (ARG1)
strcpy(msgpathbuf, entry->arg[1]);
return (1);
}
if (hostmatch(ARG0)) {
if (ARG1)
strcpy(msgpathbuf, entry->arg[1]);
return (1);
}
}
return (0);
}
/*************************************************************************/
/* FUNCTION : acl_countusers */
/* PURPOSE : Check the anonymous FTP access lists to see if this */
/* access is permitted. */
/* ARGUMENTS : none */
/*************************************************************************/
int
#ifdef __STDC__
acl_countusers(char *class)
#else
acl_countusers(class)
char *class;
#endif
{
int count,
which;
char pidfile[MAXPATHLEN];
pid_t buf[MAXUSERS];
#ifndef HAVE_FLOCK
struct flock arg;
#endif
/*
* if pidfd was not opened previously...
* pidfd must stay open after the chroot(~ftp)
*/
sprintf(pidfile, _PATH_PIDNAMES, class);
if (pidfd < 0) {
pidfd = open(pidfile, O_RDWR | O_CREAT, 0644);
}
if (pidfd < 0) {
syslog(LOG_ERR, "cannot open pid file %s: %s", pidfile,
strerror(errno));
return -1;
}
#ifdef HAVE_FLOCK
while (flock(pidfd, LOCK_EX)) {
syslog(LOG_ERR, "sleeping: flock of pid file failed: %s",
#else
arg.l_type = F_WRLCK;
arg.l_whence = arg.l_start = arg.l_len = 0;
while ( -1 == fcntl( pidfd, F_SETLK, &arg) ) {
syslog(LOG_ERR, "sleeping: fcntl lock of pid file failed: %s",
#endif
strerror(errno));
sleep(1);
}
lseek(pidfd, 0, L_SET);
count = 0;
if (read(pidfd, buf, sizeof(buf)) == sizeof(buf)) {
for (which = 0; which < MAXUSERS; which++)
if (buf[which] && !kill(buf[which], 0))
count++;
}
#ifdef HAVE_FLOCK
flock(pidfd, LOCK_UN);
#else
arg.l_type = F_UNLCK; arg.l_whence = arg.l_start = arg.l_len = 0;
fcntl(pidfd, F_SETLK, &arg);
#endif
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 */
/*************************************************************************/
void
#ifdef __STDC__
acl_join(char *class)
#else
acl_join(class)
char *class;
#endif
{
int which,
avail;
pid_t buf[MAXUSERS];
char pidfile[MAXPATHLEN];
pid_t procid;
#ifndef HAVE_FLOCK
struct flock arg;
#endif
/*
* if pidfd was not opened previously...
* pidfd must stay open after the chroot(~ftp)
*/
sprintf(pidfile, _PATH_PIDNAMES, class);
if (pidfd < 0) {
pidfd = open(pidfile, O_RDWR | O_CREAT, 0644);
}
if (pidfd < 0) {
syslog(LOG_ERR, "cannot open pid file %s: %s", pidfile,
strerror(errno));
return;
}
#ifdef HAVE_FLOCK
while (flock(pidfd, LOCK_EX)) {
syslog(LOG_ERR, "sleeping: flock of pid file failed: %s",
#else
arg.l_type = F_WRLCK;
arg.l_whence = arg.l_start = arg.l_len = 0;
while ( -1 == fcntl( pidfd, F_SETLK, &arg) ) {
syslog(LOG_ERR, "sleeping: fcntl lock of pid file failed: %s",
#endif
strerror(errno));
sleep(1);
}
procid = getpid();
lseek(pidfd, 0, L_SET);
if (read(pidfd, buf, sizeof(buf)) < sizeof(buf))
for (which = 0; which < MAXUSERS; buf[which++] = 0)
continue;
avail = 0;
for (which = 0; which < MAXUSERS; which++) {
if ((buf[which] == 0) || (kill(buf[which], 0) == -1)) {
avail = which;
buf[which] = 0;
} else if (buf[which] == procid) {
/* already exists in pid file... */
#ifdef HAVE_FLOCK
flock(pidfd, LOCK_UN);
#else
arg.l_type = F_UNLCK; arg.l_whence = arg.l_start = arg.l_len = 0;
fcntl(pidfd, F_SETLK, &arg);
#endif
return;
}
}
buf[avail] = procid;
lseek(pidfd, 0, L_SET);
write(pidfd, buf, sizeof(buf));
#ifdef HAVE_FLOCK
flock(pidfd, LOCK_UN);
#else
arg.l_type = F_UNLCK; arg.l_whence = arg.l_start = arg.l_len = 0;
fcntl(pidfd, F_SETLK, &arg);
#endif
}
/*************************************************************************/
/* FUNCTION : acl_remove */
/* PURPOSE : remove the current process to the list of processes in */
/* the specified class. */
/* ARGUMENTS : The name of the class to remove */
/*************************************************************************/
void
#ifdef __STDC__
acl_remove(void)
#else
acl_remove()
#endif
{
char class[1024];
int which,
avail;
pid_t buf[MAXUSERS];
char pidfile[MAXPATHLEN];
pid_t procid;
#ifndef HAVE_FLOCK
struct flock arg;
#endif
if (!acl_getclass(class)) {
return;
}
/*
* if pidfd was not opened previously...
* pidfd must stay open after the chroot(~ftp)
*/
sprintf(pidfile, _PATH_PIDNAMES, class);
if (pidfd < 0) {
pidfd = open(pidfile, O_RDWR | O_CREAT, 0644);
}
if (pidfd < 0) {
syslog(LOG_ERR, "cannot open pid file %s: %s", pidfile,
strerror(errno));
return;
}
#ifdef HAVE_FLOCK
while (flock(pidfd, LOCK_EX)) {
syslog(LOG_ERR, "sleeping: flock of pid file failed: %s",
#else
arg.l_type = F_WRLCK;
arg.l_whence = arg.l_start = arg.l_len = 0;
while ( -1 == fcntl( pidfd, F_SETLK, &arg) ) {
syslog(LOG_ERR, "sleeping: fcntl lock of pid file failed: %s",
#endif
strerror(errno));
sleep(1);
}
procid = getpid();
lseek(pidfd, 0, L_SET);
if (read(pidfd, buf, sizeof(buf)) < sizeof(buf))
for (which = 0; which < MAXUSERS; buf[which++] = 0)
continue;
avail = 0;
for (which = 0; which < MAXUSERS; which++) {
if ((buf[which] == 0) || (kill(buf[which], 0) == -1)) {
avail = which;
buf[which] = 0;
} else if (buf[which] == procid) {
buf[which] = 0;
}
}
lseek(pidfd, 0, L_SET);
write(pidfd, buf, sizeof(buf));
#ifdef HAVE_FLOCK
flock(pidfd, LOCK_UN);
#else
arg.l_type = F_UNLCK; arg.l_whence = arg.l_start = arg.l_len = 0;
fcntl(pidfd, F_SETLK, &arg);
#endif
close(pidfd);
pidfd = -1;
}
/*************************************************************************/
/* FUNCTION : pr_mesg */
/* PURPOSE : Display a message to the user */
/* ARGUMENTS : message code, name of file to display */
/*************************************************************************/
void
#ifdef __STDC__
pr_mesg(int msgcode, char *msgfile)
#else
pr_mesg(msgcode,msgfile)
int msgcode;
char *msgfile;
#endif
{
FILE *infile;
char inbuf[1024],
outbuf[1024],
*cr;
if (msgfile && (int)strlen(msgfile) > 0) {
infile = fopen(msgfile, "r");
if (infile) {
while (fgets(inbuf, 255, infile) != NULL) {
if ((cr = strchr(inbuf, '\n')) != NULL)
*cr = '\0';
/*
msg_massage(inbuf, outbuf);
lreply(msgcode, "%s", outbuf);
*/
}
fclose(infile);
}
}
}
/*************************************************************************/
/* FUNCTION : access_init */
/* PURPOSE : Read and parse the access lists to set things up */
/* ARGUMENTS : none */
/* return: != 0 if error ist detected */
/*************************************************************************/
int
#ifdef __STDC__
access_init(void)
#else
access_init()
#endif
{
struct aclmember *entry;
extern char *eft_access;
int ret;
/* if (!readacl(_PATH_FTPACCESS)) changed -- he */
if (!readacl(eft_access)){
if(use_accessfile){
fprintf(stderr,"readacl() failed (file: %s)\n", eft_access);
return 1;
}
}
ret = parseacl();
Shutdown[0] = '\0';
entry = (struct aclmember *) NULL;
if (getaclentry("shutdown", &entry) && ARG0 != NULL)
(void) strncpy(Shutdown, ARG0, sizeof(Shutdown));
if( ret && use_accessfile) return 1;
return 0;
}
/*************************************************************************/
/* FUNCTION : access_ok */
/* PURPOSE : Check the anonymous FTP access lists to see if this */
/* access is permitted. */
/* ARGUMENTS : none */
/*************************************************************************/
int
#ifdef __STDC__
access_ok(int msgcode)
#else
access_ok(msgcode)
int msgcode;
#endif
{
char class[1024],
msgfile[MAXPATHLEN];
int limit;
if (!use_accessfile)
return (1);
if (aclbuf == NULL) {
syslog(LOG_NOTICE,
"ACCESS DENIED (error reading access file) TO %s [%s]",
remotehost, remoteaddr);
return (0);
}
if (acl_deny(msgfile)) {
pr_mesg(msgcode, msgfile);
syslog(LOG_NOTICE, "ACCESS DENIED (deny command) TO %s [%s]",
remotehost, remoteaddr);
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 [%s]",
remotehost, remoteaddr);
return (0);
}
/* if no limits defined, no limits apply -- access OK */
limit = acl_getlimit(class, msgfile);
if ((limit == -1) || (acl_countusers(class) < limit)) {
acl_join(class);
return (1);
} else {
#ifdef LOG_TOOMANY
syslog(LOG_NOTICE, "ACCESS DENIED (user limit %d; class %s) TO %s [%s]",
limit, class, remotehost, remoteaddr);
#endif
pr_mesg(msgcode, msgfile);
return (-1);
}
/* NOTREACHED */
}

View File

@ -1,200 +0,0 @@
/* 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.
*/
#ifndef lint
char * rcsid = "$Id: acl.c,v 1.2 1999/10/05 21:23:23 he Exp $";
#endif
#include "config.h"
#include <stdio.h>
#include <errno.h>
#include <string.h>
#ifdef SYSSYSLOG
#include <sys/syslog.h>
#else
#include <syslog.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include "pathnames.h"
#include "extensions.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 *
#ifdef __STDC__
getaclentry(char *keyword, struct aclmember **next)
#else
getaclentry(keyword,next)
char *keyword;
struct aclmember **next;
#endif
{
do {
if (!*next)
*next = aclmembers;
else
*next = (*next)->next;
} while (*next && strcmp((*next)->keyword, keyword));
return (*next);
}
/*************************************************************************/
/* FUNCTION : parseacl */
/* PURPOSE : Parse the acl buffer into its components */
/* ARGUMENTS : A pointer to the acl file */
/* RETURNS : != 0 if error is detected */
/*************************************************************************/
int
#ifdef __STDC__
parseacl(void)
#else
parseacl()
#endif
{
char *ptr,
*aclptr = aclbuf,
*line;
int cnt;
struct aclmember *member,
*acltail;
if (!aclbuf || !(*aclbuf))
return 1;
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-1) != '\\')
*ptr = '\0';
ptr = strtok(line, " \t");
if (ptr) {
member = (struct aclmember *) calloc(1, sizeof(struct aclmember));
(void) strcpy(member->keyword, ptr);
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;
}
}
return 0;
}
/*************************************************************************/
/* FUNCTION : readacl */
/* PURPOSE : Read the acl into memory */
/* ARGUMENTS : The pathname of the acl */
/* RETURNS : 0 if error, 1 if no error */
/*************************************************************************/
int
#ifdef __STDC__
readacl(char *aclpath)
#else
readacl(aclpath)
char *aclpath;
#endif
{
FILE *aclfile;
struct stat finfo;
extern int use_accessfile;
if (!use_accessfile)
return (0);
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((unsigned) finfo.st_size + 1))) {
syslog(LOG_ERR, "could not malloc aclbuf (%d bytes)", 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));
aclbuf = NULL;
(void) fclose(aclfile);
return (0);
}
*(aclbuf + finfo.st_size) = '\0';
}
(void) fclose(aclfile);
return (1);
}

View File

@ -1,68 +0,0 @@
/*
* Linux configuration file
* $Id: config.h,v 1.3 2002/07/06 00:11:18 keil Exp $
*/
#if 0
#include <linux/version.h>
#else
#define LINUX_VERSION_CODE 0x020404
#endif
#if defined(LINUX_VERSION_CODE)
#if LINUX_VERSION_CODE >= 66061
/* 1.2.13 or later */
#define HAVE_DIRFD
#endif
#endif
#undef BSD
#define HAVE_DIRENT
#define HAVE_FLOCK
#define HAVE_FTW
#define HAVE_GETCWD
#define HAVE_GETDTABLESIZE
#undef HAVE_PSTAT
#define HAVE_ST_BLKSIZE
#undef HAVE_SYSINFO
#define HAVE_SYSCONF
#define HAVE_UT_UT_HOST
#define HAVE_VPRINTF
#define HAVE_SNPRINTF
#define LINUX
#define OVERWRITE
#undef REGEX
#define SPT_TYPE SPT_REUSEARGV
#define SHADOW_PASSWORD
#define UPLOAD
#undef USG
#define SVR4
#define FACILITY LOG_DAEMON
#define HAVE_SYS_VFS
#define HAVE_SYMLINK
#define UTMAXTYPE
/* #define USE_ETC */
#define USE_LOG
#define USE_VAR
#define VAR_RUN
#define VIRTUAL
#define NEED_SIGFIX
#if !defined(__USE_POSIX)
#define __USE_POSIX
#endif
#include <limits.h>
#ifndef NBBY
#define NBBY 8
#endif
#ifndef NCARGS
#ifdef _POSIX_ARG_MAX
#define NCARGS _POSIX_ARG_MAX
#endif
#endif
#include <stdlib.h> /* here instead of in all the srcs. _H*/
#include <unistd.h>
typedef void SIGNAL_TYPE;
#include "../config.h"
#define realpath realpath_on_steroids /* hack to work around unistd.h */

View File

@ -1,231 +0,0 @@
/* 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.
*/
#include <stdio.h>
#include <errno.h>
#include <malloc.h>
#include <string.h>
#ifdef SYSSYSLOG
#include <sys/syslog.h>
#else
#include <syslog.h>
#endif
#include <time.h>
#include <pwd.h>
#include <setjmp.h>
#include <grp.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <sys/param.h>
#if defined(HAVE_STATVFS)
#include <sys/statvfs.h>
#elif defined(HAVE_SYS_VFS)
#include <sys/vfs.h>
#elif defined(HAVE_SYS_MOUNT)
#include <sys/mount.h>
#endif
#include <unistd.h>
#include <arpa/ftp.h>
#include "pathnames.h"
#include "extensions.h"
extern char remotehost[];
/*************************************************************************/
/* FUNCTION : msg_massage */
/* PURPOSE : Scan a message line for magic cookies, replacing them as */
/* needed. */
/* ARGUMENTS : pointer input and output buffers */
/*************************************************************************/
void
#ifdef __STDC__
msg_massage(char *inbuf, char *outbuf)
#else
msg_massage(inbuf,outbuf)
char *inbuf;
char *outbuf;
#endif
{
char *inptr = inbuf;
char *outptr = outbuf;
char buffer[MAXPATHLEN];
time_t curtime;
int limit;
extern struct passwd *pw;
struct aclmember *entry;
(void) acl_getclass(buffer);
limit = acl_getlimit(buffer, NULL);
while (*inptr) {
if (*inptr != '%')
*outptr++ = *inptr;
else {
entry = NULL;
switch (*++inptr) {
case 'E':
if ( (getaclentry("email", &entry)) && ARG0 )
sprintf(outptr, "%s", ARG0);
else
*outptr = '\0';
break;
case 'N':
sprintf(outptr, "%d", acl_countusers(buffer));
break;
case 'M':
if (limit > 0){
sprintf(outptr, "%d", limit);
}else{
strcpy(outptr,"unlimited");
}
break;
case 'T':
(void) time(&curtime);
strncpy(outptr, ctime(&curtime), 24);
*(outptr + 24) = '\0';
break;
case 'F':
#if defined(HAVE_STATVFS) || defined(HAVE_SYS_VFS) || defined(HAVE_SYS_MOUNT)
sprintf(outptr, "%lu", getSize("."));
#endif
break;
case 'C':
#define HAVE_GETCWD 1 /* Hack by HE to force getcwd, #include'ing config.h
* should be better but causes other problems */
#ifdef HAVE_GETCWD
(void) getcwd(outptr, MAXPATHLEN);
#else
(void) getwd(outptr);
#endif
break;
case 'R':
strcpy(outptr, remotehost);
break;
/*
case 'L':
strcpy(outptr, hostname);
break;
*/
case 'U':
if (pw)
strcpy(outptr, pw->pw_name);
else
strcpy(outptr, "[unknown]");
break;
/*
case 's':
strncpy(outptr, shuttime, 24);
*(outptr + 24) = '\0';
break;
case 'd':
strncpy(outptr, disctime, 24);
*(outptr + 24) = '\0';
break;
case 'r':
strncpy(outptr, denytime, 24);
*(outptr + 24) = '\0';
break;
*/
/* KH : cookie %u for RFC931 name */
/*
case 'u':
if (authenticated) strncpy(outptr, authuser, 24);
else strcpy(outptr,"[unknown]");
*(outptr + 24) = '\0';
break;
*/
case '%':
*outptr++ = '%';
*outptr = '\0';
break;
default:
*outptr++ = '%';
*outptr++ = '?';
*outptr = '\0';
break;
}
while (*outptr)
outptr++;
}
inptr++;
}
*outptr = '\0';
}
void reply (int msg, char *str) {
fprintf (stderr, "%d - %s\n", msg, str);
}
void expand_id(void) {
struct aclmember *entry = NULL;
struct passwd *pwent;
struct group *grent;
char buf[BUFSIZ];
while (getaclentry("upload", &entry) && ARG0 && ARG1 && ARG2 != NULL) {
if (ARG3 && ARG4) {
pwent = getpwnam(ARG3);
grent = getgrnam(ARG4);
if (pwent) sprintf(buf, "%d", pwent->pw_uid);
else sprintf(buf, "%d", 0);
ARG3 = (char *) malloc(strlen(buf) + 1);
strcpy(ARG3, buf);
if (grent) sprintf(buf, "%d", grent->gr_gid);
else sprintf(buf, "%d", 0);
ARG4 = (char *) malloc(strlen(buf) + 1);
strcpy(ARG4, buf);
endgrent();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,44 +0,0 @@
#ifndef FNM_PATHNAME
#define FNM_PATHNAME 0x01 /* Slash must be matched by slash. */
#endif
#ifndef FNM_NOESCAPE
#define FNM_NOESCAPE 0x02 /* Disable backslash escaping. */
#endif
#ifndef FNM_PERIOD
#define FNM_PERIOD 0x04 /* Period must be matched by period. */
#endif
#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 MAXUSERS 1024
#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

View File

@ -1,369 +0,0 @@
/*
* @(#) hostacc.c - Implementation of host access for the
* experimental FTP daemon developed at
* Washington University.
* $Id: hostacc.c,v 1.1 1999/06/30 17:19:34 he Exp $
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* AUTHOR
* Bart Muijzer <bartm@cv.ruu.nl>
*
* 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 "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(pcRuser, pcRhost, pcRaddr)
char *pcRuser,
*pcRhost,
*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];
((pcHost != NULL) && !iLineMatch);
pcHost=ptHtmp->ha_hosts[++iInd])
{
if (isdigit(*pcHost))
{
iLineMatch = !fnmatch(pcHost, pcRaddr, NULL);
}
else
{
iLineMatch = !fnmatch(pcHost, pcRhost, NULL);
}
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()
{
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 {
fatal("Can't open host access file");
iHaSize = iHaInd;
return (-1);
}
}
ha_arr=(hacc_t*)malloc((iHaMalloc=10)*sizeof(hacc_t));
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)
{
fatal("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 {
fatal("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
{
fatal("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)
{
fatal("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()
{
static int iHaInd;
static hacc_t ptTmp;
if (iFirstTim)
{
iFirstTim = 0;
iHaInd = 0;
}
if (iHaInd >= iHaSize)
return ((hacc_t *)NULL);
else {
#ifdef USG
memmove(&ptTmp, &(ha_arr[iHaInd]), sizeof(hacc_t));
#else
bcopy(&(ha_arr[iHaInd]), &ptTmp, sizeof(hacc_t));
#endif
iHaInd++;
return(&ptTmp);
}
}
/* ------------------------------------------------------------------------ *\
* FUNCTION : endhacc *
* PURPOSE : Free allocated data structures for host access *
* ARGUMENTS : None *
* RETURNS : -1 on failure, 0 otherwise *
\* ------------------------------------------------------------------------ */
static int endhacc()
{
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 fatal(pcMsg)
char *pcMsg;
{
syslog(LOG_INFO, "host_access: %s", pcMsg);
}
static char *strnsav(pcStr,iLen)
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 */

View File

@ -1,596 +0,0 @@
#include <syslog.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/file.h>
#include <sys/wait.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#define FTP_NAMES
#include <arpa/ftp.h>
#include <arpa/inet.h>
#include <arpa/telnet.h>
#include <ctype.h>
#include <stdio.h>
#include <signal.h>
#include <pwd.h>
#include <setjmp.h>
#include <netdb.h>
#include <errno.h>
#include <string.h>
#ifdef SYSSYSLOG
#include <sys/syslog.h>
#else
#include <syslog.h>
#endif
#include <time.h>
#include "config.h"
#include "extensions.h"
#ifdef SHADOW_PASSWORD
#include <shadow.h>
#endif
#include "pathnames.h"
#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN 64
#endif
char * eft_access = _PATH_FTPACCESS;
char remoteaddr [MAXHOSTNAMELEN];
char remotehost [MAXHOSTNAMELEN];
/* nameserved==1: remoteaddr!=remotehost */
/* nameserved==0: remoteaddr==remotehost */
int nameserved = 1;
char guestpw[MAXHOSTNAMELEN];
char privatepw[MAXHOSTNAMELEN];
int log_commands = 0;
int logging = 0;
/* File transfer logging */
int xferlog = 0;
int log_outbound_xfers = 0;
int log_incoming_xfers = 0;
/* --he char logfile[MAXPATHLEN];*/
char * logfile = _PATH_XFERLOG;
int guest;
int anonymous = 1;
/* Make use of /etc/eftaccess ? */
int use_accessfile = 0;
/* How many attempts for the user to login ? */
int lgi_failure_threshold = 5;
/* The password structure of the logged in user */
struct passwd *pw;
/* The options, if (un)compressing etc. is allowed */
int mangleopts = 0;
char autherrmsg [256];
#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 SPACELEFT(buf, ptr) (sizeof buf - ((ptr) - buf))
#ifdef HAVE_DIRENT
#include <dirent.h>
#else
#include <sys/dir.h>
#endif
#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN 64 /* may be too big */
#endif
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE !TRUE
#endif
extern int errno;
extern int pidfd
;
extern char *ctime(const time_t *);
#ifndef NO_CRYPT_PROTO
extern char *crypt(const char *, const char *);
#endif
extern FILE *ftpd_popen(char *program, char *type, int closestderr),
*fopen(const char *, const char *),
*freopen(const char *, const char *, FILE *);
extern int ftpd_pclose(FILE *iop),
fclose(FILE *);
extern char *wu_getline(),
*realpath(const char *pathname, char *result);
extern char version[];
extern char *home; /* pointer to home directory for glob */
extern char cbuf[];
extern off_t restart_point;
#ifdef VIRTUAL
int virtual_mode=0;
char virtual_root[MAXPATHLEN];
char virtual_banner[MAXPATHLEN];
#endif
#ifdef LOG_FAILED
#define MAXUSERNAMELEN 32
char the_user[MAXUSERNAMELEN];
#endif
SIGNAL_TYPE lostconn(int sig);
SIGNAL_TYPE randomsig(int sig);
SIGNAL_TYPE myoob(int sig);
FILE *getdatasock(char *mode),
*dataconn(char *name, off_t size, char *mode);
void reply(int, char *fmt, ...);
void lreply(int, char *fmt, ...);
#ifdef NEED_SIGFIX
extern sigset_t block_sigmask; /* defined in sigfix.c */
#endif
struct aclmember *entry = NULL;
void end_login(void);
void send_data(FILE *, FILE *, off_t);
void dolog(struct sockaddr_in *);
static char ttyline[20];
int checkuser(char *name)
{
register FILE *fd;
register char *p;
char line[BUFSIZ];
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 (strcmp(line, name) == 0) {
(void) fclose(fd);
return (1);
}
}
(void) fclose(fd);
}
return (0);
}
/* Helper function for sgetpwnam(). */
char * sgetsave(char *s)
{
char *new;
new = (char *) malloc(strlen(s) + 1);
if (new == NULL) {
strcpy (autherrmsg, "Local resource failure: malloc");
return NULL;
/* 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;
char *sgetsave(char *s);
if ((p = getpwnam(name)) == NULL)
return p;
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);
if (save.pw_name==NULL) return NULL;
save.pw_passwd = sgetsave(p->pw_passwd);
if (save.pw_passwd==NULL) return NULL;
#ifdef SHADOW_PASSWORD
if (p) {
struct spwd *spw;
setspent();
if ((spw = getspnam(p->pw_name)) != NULL) {
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);
if (save.pw_passwd==NULL) return NULL;
}
/* 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("");
if (save.pw_passwd==NULL) return NULL;
}
#endif
/* marekm's fix for linux proc file system shadow passwd exposure problem */
endspent();
}
#endif
save.pw_gecos = sgetsave(p->pw_gecos);
if (save.pw_gecos==NULL) return NULL;
save.pw_dir = sgetsave(p->pw_dir);
if (save.pw_dir==NULL) return NULL;
save.pw_shell = sgetsave(p->pw_shell);
if (save.pw_shell==NULL) return NULL;
#ifdef M_UNIX
ret = &save;
DONE:
endpwent();
#endif
return(&save);
}
#ifdef SKEY
/*
* 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 */
int wuftp_check_user (char *user, char *passw, char *isdnno) {
char *shell;
char *getusershell();
int passwarn = 0;
int rval = 1;
char *xpasswd, *salt;
if(access_init()) return 0;
strcpy (remotehost, isdnno);
strcpy (remoteaddr, isdnno);
nameserved = 0;
anonymous = 0;
acl_remove ();
if (!strcasecmp(user, "ftp") || !strcasecmp(user, "anonymous") ||
!user[0]) {
struct aclmember *entry = NULL;
int machineok=1;
if (checkuser("ftp") || checkuser("anonymous")) {
sprintf (autherrmsg, "User %s access denied.", user);
syslog(LOG_NOTICE,
"EFT LOGIN REFUSED (eft in %s) FROM %s, %s",
_PATH_FTPUSERS, remotehost, user);
return 0;
/*
** 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 isdn-numbers listed.
**
** the format of the "guestserver" line is
** guestserver [<isdn-number-rule1> [<isdn-number-ruleN>]]
** that is, "guestserver" will forbid anonymous access on all machines
** while "guestserver 40* 30*" will allow anonymous access on
** all callers coming from Hamburg or Berlin.
**
*/
} else if (getaclentry("guestserver", &entry)
&& entry->arg[0] && (int)strlen(entry->arg[0]) > 0) {
int machinecount = 0;
machineok=0;
for (machinecount=0;
entry->arg[machinecount] && (entry->arg[machinecount])[0];
machinecount++) {
if (!fnmatch(entry->arg[machinecount], isdnno,0)) {
machineok++;
break;
}
}
}
if (!machineok) {
strcpy (autherrmsg, "Guest login not allowed from given number.");
syslog(LOG_NOTICE,
"EFT LOGIN REFUSED (number not in guestservers) FROM %s, %s",
remotehost, user);
return 0;
} else if ((pw = sgetpwnam("ftp")) != NULL) {
anonymous = 1; /* for the access_ok call */
if (access_ok(530) < 1) {
sprintf (autherrmsg, "User %s access denied.", user);
syslog(LOG_NOTICE,
"EFT LOGIN REFUSED (access denied) FROM %s, %s",
remotehost, user);
return 0;
} else {
askpasswd = 1;
if (use_accessfile)
acl_setfunctions();
}
} else {
sprintf (autherrmsg, "User %s unknown.", user);
syslog(LOG_NOTICE,
"EFT LOGIN REFUSED (ftp not in /etc/passwd) FROM %s, %s",
remotehost, user);
return 0;
}
}
#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?! */
sprintf (autherrmsg, "User %s unknown.", user);
syslog (LOG_NOTICE,
"EFT LOGIN REFUSED (not anonymous) FROM %s, %s",
remotehost, user);
return 0;
}
/* fall here if username okay in any case */
#endif /* ANON_ONLY */
if ((pw = sgetpwnam(user)) != NULL) {
char *cp;
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(user)) {
sprintf (autherrmsg, "User %s access denied.", user);
syslog(LOG_NOTICE,
"EFT LOGIN REFUSED (bad shell or username in %s) FROM %s, %s",
_PATH_FTPUSERS, remotehost, user);
pw = (struct passwd *) NULL;
return 0;
}
/* 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 (access_ok(530) < 1) {
sprintf (autherrmsg, "User %s access denied.", user);
syslog(LOG_NOTICE, "EFT LOGIN REFUSED (access denied) FROM %s, %s",
remotehost, user);
return 0;
} else
if (use_accessfile) /* see above. _H*/
acl_setfunctions();
#ifdef SKEY
#ifdef SKEY_NAME
/* this is the old way, but freebsd uses it */
pwok = skeyaccess(user, NULL, remotehost, remoteaddr);
#else
/* this is the new way */
pwok = skeyaccess(pw, NULL, remotehost, remoteaddr);
#endif
#else
#endif
askpasswd = 1;
/* Delay before reading passwd after first failed attempt to slow down
* passwd-guessing programs. */
if (login_attempts)
sleep((unsigned) login_attempts);
if (!askpasswd) return 1; /* Hey man, we got it! */
if (!anonymous) { /* "ftp" is only account allowed no password */
*guestpw = '\0';
if (pw == NULL)
salt = "xx";
else
salt = pw->pw_passwd;
xpasswd = crypt(passw, salt);
/* The strcmp does not catch null passwords! */
if (pw !=NULL && *pw->pw_passwd != '\0' &&
strcmp(xpasswd, pw->pw_passwd) == 0) {
rval = 0;
}
if(rval){
strcpy (autherrmsg, "Login incorrect.");
#ifdef LOG_FAILED
if (! strcmp (passw, "NULL"))
syslog(LOG_NOTICE, "REFUSED \"NULL\" from %s, %s",
remotehost, the_user);
else
syslog(LOG_INFO, "failed login from %s, %s",
remotehost, the_user);
#endif
acl_remove();
pw = NULL;
if (++login_attempts >= lgi_failure_threshold) {
syslog(LOG_NOTICE, "repeated login failures from %s",
remotehost);
exit(0);
}
return 0;
}
/* ANONYMOUS USER PROCESSING STARTS HERE */
} else {
char *pwin, *pwout = guestpw;
struct aclmember *entry = NULL;
int valid;
if (!*passw) {
strcpy(guestpw, "[none_given]");
} else {
int cnt = sizeof(guestpw) - 2;
for (pwin = passw; *pwin && cnt--; pwin++)
if (!isgraph(*pwin))
*pwout++ = '_';
else
*pwout++ = *pwin;
}
}
/* if logging is enabled, open logfile before chroot or set group ID */
if (log_outbound_xfers || log_incoming_xfers) {
xferlog = open(logfile, O_WRONLY | O_APPEND | O_CREAT, 0660);
if (xferlog < 0) {
syslog(LOG_ERR, "cannot open logfile %s: %s", logfile,
strerror(errno));
xferlog = 0;
}
}
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 */
anonymous=!guest;
}
/* END AUTHENTICATION */
login_attempts = 0; /* this time successful */
/* SET GROUP ID STARTS HERE */
(void) setegid((gid_t) pw->pw_gid);
(void) initgroups(pw->pw_name, pw->pw_gid);
expand_id();
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 VIRTUAL
if (virtual_mode && !guest) {
if (pw->pw_dir)
free(pw->pw_dir);
pw->pw_dir = sgetsave(virtual_root);
}
#endif
/* determine root and home directory */
if ((sp = strstr(pw->pw_dir, "/./")) == NULL) {
if (chroot(pw->pw_dir) < 0 || chdir("/") < 0) {
strcpy (autherrmsg, "Can't set guest privileges.");
goto bad;
}
} else{
*sp++ = '\0';
if (chroot(pw->pw_dir) < 0 || chdir(++sp) < 0) {
strcpy (autherrmsg, "Can't set guest privileges.");
goto bad;
}
}
}
#ifdef HAVE_SETREUID
if (setreuid(-1, (uid_t) pw->pw_uid) < 0) {
#else
if (seteuid((uid_t) pw->pw_uid) < 0) {
#endif
strcpy (autherrmsg, "Can't set uid.");
goto bad;
}
if (!anonymous && !guest) {
if (chdir(pw->pw_dir) < 0) {
if (chdir("/") < 0) {
sprintf(autherrmsg, "User %s: can't change directory to %s.",
pw->pw_name, pw->pw_dir);
goto bad;
} else
strcpy(autherrmsg, "No directory! Logging in with home=/");
}
}
if (anonymous) {
strcpy (autherrmsg, "Guest login ok, access restrictions apply.");
if (logging)
syslog(LOG_INFO, "ANONYMOUS FTP LOGIN FROM %s, %s",
remotehost, passw);
} else {
sprintf (autherrmsg, "User %s logged in.%s", pw->pw_name, guest ?
" Access restrictions apply." : "");
if (logging)
syslog(LOG_INFO, "FTP LOGIN FROM %s [%s], %s",
remotehost, remoteaddr, pw->pw_name);
} /* anonymous */
/* home = pw->pw_dir; */ /* home dir for globbing */
return 1;
bad:
/* Forget all about it... */
if (xferlog)
close(xferlog);
xferlog = 0;
delay_signaling(); /* we can't allow any signals while euid==0: kinch */
(void) seteuid((uid_t) 0);
pw = NULL;
anonymous = 0;
guest = 0;
return 0;
}

View File

@ -1,148 +0,0 @@
/* Copyright (c) 1989 The Regents of the University of California. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. 2.
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. 3. All advertising
* materials mentioning features or use of this software must display the
* following acknowledgement: This product includes software developed by the
* University of California, Berkeley and its contributors. 4. Neither the
* name of the University nor the names of its contributors may be used to
* endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)$Id: pathnames.h,v 1.1 1999/06/30 17:19:36 he Exp $ based on
* pathnames.h 5.2 (Berkeley) 6/1/90
*/
#define _PATH_EXECPATH "/bin/eft-exec"
#ifdef USE_ETC
#define _PATH_FTPUSERS "/etc/eftusers"
#define _PATH_FTPACCESS "/etc/eftaccess"
#define _PATH_CVT "/etc/eftconversions"
#define _PATH_PRIVATE "/etc/eftgroups"
#else
#ifdef USE_I4L_CONFDIR
#define _PATH_FTPUSERS CONFIG_I4L_CONFDIR "/eftusers"
#define _PATH_FTPACCESS CONFIG_I4L_CONFDIR "/eftaccess"
#define _PATH_CVT CONFIG_I4L_CONFDIR "/eftconversions"
#define _PATH_PRIVATE CONFIG_I4L_CONFDIR "/eftgroups"
#else
#ifdef USE_ETC_EFTD
#define _PATH_FTPUSERS "/etc/eftd/eftusers"
#define _PATH_FTPACCESS "/etc/eftd/eftaccess"
#define _PATH_CVT "/etc/eftd/eftconversions"
#define _PATH_PRIVATE "/etc/eftd/eftgroups"
#else
#ifdef USE_LOCAL_ETC
#define _PATH_FTPUSERS "/usr/local/etc/eftusers"
#define _PATH_FTPACCESS "/usr/local/etc/eftaccess"
#define _PATH_CVT "/usr/local/etc/eftconversions"
#define _PATH_PRIVATE "/usr/local/etc/eftgroups"
#else
#define _PATH_FTPUSERS "/usr/local/lib/eftd/eftusers"
#define _PATH_FTPACCESS "/usr/local/lib/eftd/eftaccess"
#define _PATH_CVT "/usr/local/lib/eftd/eftconversions"
#define _PATH_PRIVATE "/usr/local/lib/eftd/eftgroups"
#endif
#endif
#endif
#endif
#ifdef USE_VAR
#ifdef USE_PID
#define _PATH_PIDNAMES "/var/pid/eft.pids-%s"
#else
#ifdef VAR_RUN
#define _PATH_PIDNAMES "/var/run/eft.pids-%s"
#else
#define _PATH_PIDNAMES "/var/adm/eft.pids-%s"
#endif
#endif
#ifdef USE_LOG
#define _PATH_XFERLOG "/var/log/xferlog"
#else
#define _PATH_XFERLOG "/var/adm/xferlog"
#endif
#else
#ifndef _PATH_PIDNAMES
#define _PATH_PIDNAMES "/usr/local/lib/eftd/pids/%s"
#endif
#ifndef _PATH_XFERLOG
#define _PATH_XFERLOG "/usr/local/logs/xferlog"
#endif
#endif
#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
#ifndef _PATH_UTMP
#define _PATH_UTMP "/etc/utmp"
#endif
#ifndef _PATH_WTMP
#define _PATH_WTMP "/usr/adm/wtmp"
#endif
#ifndef _PATH_LASTLOG
#ifdef SOLARIS_2
#define _PATH_LASTLOG "/var/adm/lastlog"
#else
#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
#ifdef HOST_ACCESS
#ifdef USE_ETC
#define _PATH_FTPHOSTS "/etc/efthosts"
#else
#ifdef USE_I4L_CONFDIR
#define _PATH_FTPHOSTS CONFIG_I4L_CONFDIR "/efthosts"
#else
#ifdef USE_ETC_FTPD
#define _PATH_FTPHOSTS "/etc/eftd/efthosts"
#else
#ifdef USE_LOCAL_ETC
#define _PATH_FTPHOSTS "/usr/local/etc/efthosts"
#else
#define _PATH_FTPHOSTS "/usr/local/lib/eftd/efthosts"
#endif
#endif
#endif
#endif
#endif

View File

@ -1,326 +0,0 @@
/* 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.
*/
#ifndef lint
static char rcsid[] = "@(#)$Id: private.c,v 1.1 1999/06/30 17:19:37 he Exp $";
#endif /* not lint */
#ifndef NO_PRIVATE
#include "config.h"
#include <stdio.h>
#include <errno.h>
#include <string.h>
#ifdef SYSSYSLOG
#include <sys/syslog.h>
#else
#include <syslog.h>
#endif
#include <grp.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/file.h>
#include "pathnames.h"
#include "extensions.h"
#define MAXGROUPLEN 100
char *passbuf = NULL;
char groupname[MAXGROUPLEN];
int group_given = 0;
struct acgrp {
char gname[MAXGROUPLEN]; /* access group name */
char gpass[MAXGROUPLEN]; /* access group password */
char gr_name[MAXGROUPLEN]; /* group to setgid() to */
gid_t gr_gid;
struct acgrp *next;
};
struct acgrp *privptr;
extern int lgi_failure_threshold,
autospout_free;
extern char remotehost[],
remoteaddr[],
*autospout;
int group_attempts;
void
#ifdef __STDC__
parsepriv(void)
#else
parsepriv()
#endif
{
char *ptr;
char *acptr = passbuf,
*line;
char *argv[3],
*p,
*val;
struct acgrp *aptr,
*privtail = (struct acgrp *) NULL;
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++) {
while ((val = (char *) strsep(&p, ":\n")) != NULL
&& *val == '\0' && p != NULL)
;
argv[n] = val;
if (argv[n][0] == ' ')
argv[n] = NULL;
}
/* check their were 3 fields, if not skip the line... */
if (n != 3 || p != NULL)
continue;
if ((gr = getgrnam((char *) argv[2])) != NULL) {
aptr = (struct acgrp *) calloc(1, sizeof(struct acgrp));
/* add element to end of list */
if (privtail)
privtail->next = aptr;
privtail = aptr;
if (!privptr)
privptr = aptr;
strcpy(aptr->gname, (char *) argv[0]);
strcpy(aptr->gpass, (char *) argv[1]);
strcpy(aptr->gr_name, (char *) argv[2]);
aptr->gr_gid = 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
#ifdef __STDC__
priv_setup(char *path)
#else
priv_setup(path)
char *path;
#endif
{
FILE *prvfile;
struct stat finfo;
passbuf = (char *) 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((unsigned) finfo.st_size + 1))) {
(void) syslog(LOG_ERR, "could not malloc passbuf (%d bytes)",
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 */
/*************************************************************************/
struct acgrp *
#ifdef __STDC__
priv_getent(char *group)
#else
priv_getent(group)
char *group;
#endif
{
struct acgrp *ptr;
for (ptr = privptr; ptr; ptr=ptr->next)
if (!strcmp(group, ptr->gname))
return(ptr);
return (NULL);
}
/*************************************************************************/
/* FUNCTION : priv_group */
/* PURPOSE : */
/* ARGUMENTS : */
/*************************************************************************/
void
#ifdef __STDC__
priv_group(char *group)
#else
priv_group(group)
char *group;
#endif
{
if ((int)strlen(group) < MAXGROUPLEN) {
strncpy(groupname, group, MAXGROUPLEN);
group_given = 1;
reply(200, "Request for access to group %s accepted.", group);
} else {
group_given = 0;
reply(500, "Illegal group name");
}
}
/*************************************************************************/
/* FUNCTION : priv_gpass */
/* PURPOSE : validate the group access request, and if OK place user */
/* in the proper group. */
/* ARGUMENTS : group access password */
/*************************************************************************/
void
#ifdef __STDC__
priv_gpass(char *gpass)
#else
priv_gpass(gpass)
char *gpass;
#endif
{
char *xgpass,
*salt;
#ifndef NO_CRYPT_PROTO
#ifdef __STDC__
char *crypt(const char *, const char *);
#else
#ifdef _M_UNIX
char *crypt(char *, char *);
#else
char *crypt();
#endif
#endif
#endif
struct acgrp *grp;
struct group *gr;
uid_t uid;
gid_t gid;
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;
if (passbuf != NULL) {
grp = priv_getent(groupname);
if (grp == NULL)
salt = "xx"; /* XXX */
else
salt = grp->gpass;
xgpass = crypt(gpass, salt);
} else
grp = NULL;
/* The strcmp does not catch null passwords! */
if (grp == NULL || *grp->gpass == '\0' || strcmp(xgpass, grp->gpass)) {
reply(530, "Group access request incorrect.");
grp = NULL;
if (++group_attempts >= lgi_failure_threshold) {
syslog(LOG_NOTICE,
"repeated group access failures from %s [%s], group %s",
remotehost, remoteaddr, groupname);
exit(0);
}
sleep(group_attempts); /* slow down password crackers */
return;
}
uid = geteuid();
gid = grp->gr_gid;
delay_signaling(); /* we can't allow any signals while euid==0: kinch */
seteuid(0);
setegid(gid);
seteuid(uid);
enable_signaling(); /* we can allow signals once again: kinch */
reply(200, "Group access enabled.");
group_attempts = 0;
}
#endif /* !NO_PRIVATE */

View File

@ -1,80 +0,0 @@
/* This software is Copyright 1997 by Stan Barber.
*
* Permission is hereby granted to copy, reproduce, redistribute or otherwise
* use this software as long as: there is no monetary profit gained
* specifically from the use or reproduction of this software, it is not
* sold, rented, traded or otherwise marketed, and this copyright notice is
* included prominently in any copy made.
*
* The author make no claims as to the fitness or correctness of this software
* for any use whatsoever, and it is provided as is. Any use of this software
* is at the user's own risk.
*/
#ifndef lint
static char * rcsid = "$Id: sigfix.c,v 1.1 1999/06/30 17:19:37 he Exp $";
#endif
#include "config.h"
/*
* delay_signaling(), enable_signaling - delay signal delivery for a while
*
* Original Author: Wietse Venema with small changes by Dave Kinchlea and
* Stan Barber
*/
/*
* Some folks (notably those who do Linux hacking) say this fix is needed.
* Others (notably the FreeBSD and BSDI folks) say if isn't.
* I am making it possible to include of exclude it.
* Just define NEED_SIGFIX and you get it.
*/
#ifdef NEED_SIGFIX
#include <sys/types.h>
#include <sys/signal.h>
#include <syslog.h>
static sigset_t saved_sigmask;
sigset_t block_sigmask; /* used in ftpd.c */
static int delaying;
static int init_done;
#endif
/* enable_signaling - deliver delayed signals and disable signal delay */
#ifdef __STDC__
int enable_signaling(void)
#else
int enable_signaling()
#endif
{
#ifdef NEED_SIGFIX
if (delaying != 0) {
delaying = 0;
if (sigprocmask(SIG_SETMASK, &saved_sigmask, (sigset_t *) 0) < 0) {
syslog(LOG_ERR, "sigprocmask: %m");
return (-1);
}
}
#endif
return (0);
}
/* delay_signaling - save signal mask and block all signals */
#ifdef __STDC__
int delay_signaling(void)
#else
int delay_signaling()
#endif
{
#ifdef NEED_SIGFIX
if (delaying == 0) {
delaying = 1;
if (sigprocmask(SIG_BLOCK, &block_sigmask, &saved_sigmask) < 0) {
syslog(LOG_ERR, "sigprocmask: %m");
return (-1);
}
}
#endif
return (0);
}

View File

@ -1,55 +0,0 @@
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Chris Torek.
*
* Redistribution and use in source and binary forms are permitted
* provided that: (1) source distributions retain this entire copyright
* notice and comment, and (2) distributions including binaries display
* the following acknowledgement: ``This product includes software
* developed by the University of California, Berkeley and its contributors''
* in the documentation or other materials provided with the distribution
* and in all advertising materials mentioning features or use of this
* software. 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)strcasestr.c 5.1 (Berkeley) 5/15/90";
#endif /* LIBC_SCCS and not lint */
#include <string.h>
/*
* Find the first occurrence of find in s.
*/
char *
#ifdef __STDC__
strcasestr(register char *s, register char *find)
#else
strcasestr(s,find)
register char *s;
register char *find;
#endif
{
register char c,
sc;
register size_t len;
if ((c = *find++) != 0) {
len = strlen(find);
do {
do {
if ((sc = *s++) == 0)
return (NULL);
} while (sc != c);
} while (strncasecmp(s, find, len) != 0);
s--;
}
return ((char *) s);
}