Updates for mblogin

This commit is contained in:
Michiel Broek 2002-01-04 21:10:21 +00:00
parent ce20472e98
commit 971a39b565
22 changed files with 74 additions and 1230 deletions

View File

@ -121,6 +121,9 @@
/* Define if you have the <lastlog.h> header file. */
#undef HAVE_LASTLOG_H
/* Define if you have the initgroups function. */
#undef HAVE_INITGROUPS
/* Define if you have ut_host in struct utmp. */
#undef UT_HOST

View File

@ -13,9 +13,9 @@ SRCS = bank.c commonio.c filesub.c language.c mbtoberep.c \
safe.c timeout.c chat.c file.c getdef.c mbchat.c mbstat.c misc.c \
offline.c putpwent.c salt.c user.c mbnewusr.c input.c whoson.c \
door.c dispfile.c userlist.c timestats.c logentry.c pw_util.c \
mblogin.c env.c chowntty.c ttytype.c shell.c basename.c \
failure.c pwdcheck.c pwauth.c loginprompt.c utmp.c limits.c \
setupenv.c sub.c ulimit.c log.c tz.c setugid.c utent.c
mblogin.c env.c chowntty.c shell.c basename.c \
pwdcheck.c pwauth.c loginprompt.c utmp.c limits.c \
setupenv.c sub.c log.c setugid.c utent.c
HDRS = bank.h commonio.h filesub.h language.h mbsebbs.h misc.h offline.h \
putpwent.h salt.h timeout.h bbslist.h email.h fsedit.h lineedit.h \
mbstat.h msgutil.h oneline.h sgetpwent.h user.h bye.h morefile.h \
@ -24,9 +24,9 @@ HDRS = bank.h commonio.h filesub.h language.h mbsebbs.h misc.h offline.h \
pinfo.h rad64.h chat.h file.h getdef.h mbpasswd.h menu.h \
nextuser.h pop3.h safe.h timecheck.h mbnewusr.h input.h whoson.h \
door.h dispfile.h userlist.h timestats.h logentry.h lastcallers.h pw_util.h \
mblogin.h env.h chowntty.h ttytype.h shell.h basename.h \
failure.h pwdcheck.h pwauth.h loginprompt.h utmp.h limits.h \
setupenv.h sub.h ulimit.h log.h tz.h setugid.h utent.h
mblogin.h env.h chowntty.h shell.h basename.h \
pwdcheck.h pwauth.h loginprompt.h utmp.h limits.h \
setupenv.h sub.h log.h setugid.h utent.h
MBSEBBS_OBJS = bank.o bbslist.o chat.o file.o funcs.o mail.o menu.o \
misc.o pinfo.o nextuser.o oneline.o page.o fsedit.o \
bye.o change.o mbsebbs.o safe.o timeout.o user.o timecheck.o \
@ -55,9 +55,9 @@ MBUSER_LIBS = ../lib/libmemwatch.a ../lib/libclcomm.a ../lib/libcommon.a ../lib/
MBUSERADD_OBJS = mbuseradd.o
MBPASSWD_OBJS = mbpasswd.o commonio.o pwio.o shadowio.o sgetpwent.o \
xmalloc.o myname.o rad64.o salt.o getdef.o encrypt.o putpwent.o pw_util.o
MBLOGIN_OBJS = getdef.o env.o chowntty.o ttytype.o shell.o basename.o failure.o \
MBLOGIN_OBJS = getdef.o env.o chowntty.o shell.o basename.o \
pwdcheck.o pwauth.o encrypt.o loginprompt.o utmp.o limits.o setupenv.o sub.o \
xmalloc.o ulimit.o log.o tz.o setugid.o utent.o mblogin.o
xmalloc.o log.o setugid.o utent.o mblogin.o
OTHER = Makefile
TARGET = mbsebbs mbnewusr mball mblang mbchat mbstat mbtoberep mbuser mbuseradd mbpasswd mblogin
@ -220,23 +220,19 @@ userlist.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib
timestats.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h timestats.h funcs.h language.h input.h exitinfo.h
logentry.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/clcomm.h logentry.h
pw_util.o: pw_util.h
mblogin.o: ../config.h mblogin.h getdef.h env.h chowntty.h ttytype.h basename.h shell.h failure.h pwdcheck.h pwauth.h loginprompt.h utmp.h limits.h setupenv.h sub.h ulimit.h log.h tz.h setugid.h
mblogin.o: ../config.h mblogin.h getdef.h env.h chowntty.h basename.h shell.h pwdcheck.h pwauth.h loginprompt.h utmp.h limits.h setupenv.h sub.h log.h setugid.h
env.o: ../config.h mblogin.h xmalloc.h
chowntty.o: ../config.h mblogin.h getdef.h chowntty.h
ttytype.o: ../config.h mblogin.h getdef.h env.h ttytype.h
shell.o: ../config.h mblogin.h basename.h shell.h
basename.o: ../config.h mblogin.h basename.h
failure.o: ../config.h mblogin.h getdef.h failure.h
pwdcheck.o: ../config.h mblogin.h pwauth.h pwdcheck.h
pwauth.o: ../config.h mblogin.h pwauth.h getdef.h encrypt.h
loginprompt.o: ../config.h mblogin.h getdef.h xmalloc.h env.h loginprompt.h
utmp.o: ../config.h mblogin.h utmp.h
limits.o: ../config.h mblogin.h getdef.h utmp.h ulimit.h
limits.o: ../config.h mblogin.h getdef.h utmp.h limits.h
setupenv.o: ../config.h mblogin.h getdef.h xmalloc.h env.h setupenv.h
sub.o: ../config.h mblogin.h sub.h
ulimit.o: ../config.h ulimit.h
log.o: ../config.h mblogin.h log.h
tz.o: ../config.h mblogin.h getdef.h tz.h
setugid.o: ../config.h mblogin.h getdef.h setugid.h
utent.o: ../config.h mblogin.h
# End of generated dependencies

View File

@ -3,7 +3,7 @@
* $Id$
* Purpose ...............: MBSE BBS Shadow Password Suite
* Original Source .......: Shadow Password Suite
* Original Copyrioght ...: Julianne Frances Haugh and others.
* Original Copyright ....: Julianne Frances Haugh and others.
*
*****************************************************************************
* Copyright (C) 1997-2001

View File

@ -1,273 +0,0 @@
/*****************************************************************************
*
* $Id$
* Purpose ...............: MBSE BBS Shadow Password Suite
* Original Source .......: Shadow Password Suite
* Original Copyrioght ...: Julianne Frances Haugh and others.
*
*****************************************************************************
* Copyright (C) 1997-2001
*
* Michiel Broek FIDO: 2:280/2802
* Beekmansbos 10
* 1971 BV IJmuiden
* the Netherlands
*
* This file is part of MBSE BBS.
*
* This BBS is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* MBSE BBS is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MBSE BBS; see the file COPYING. If not, write to the Free
* Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*****************************************************************************/
#include "../config.h"
#include <fcntl.h>
#include <stdio.h>
#include "mblogin.h"
#include "getdef.h"
#include <utmp.h>
#include "failure.h"
#define YEAR (365L*DAY)
/*
* failure - make failure entry
*
* failure() creates a new (struct faillog) entry or updates an
* existing one with the current failed login information.
*/
void failure(uid_t uid, const char *tty, struct faillog *fl)
{
int fd;
/*
* Don't do anything if failure logging isn't set up.
*/
if ((fd = open(FAILLOG_FILE, O_RDWR)) < 0)
return;
/*
* The file is indexed by uid value meaning that shared UID's
* share failure log records. That's OK since they really
* share just about everything else ...
*/
lseek(fd, (off_t) (sizeof *fl) * uid, SEEK_SET);
if (read(fd, (char *) fl, sizeof *fl) != sizeof *fl)
memzero(fl, sizeof *fl);
/*
* Update the record. We increment the failure count to log the
* latest failure. The only concern here is overflow, and we'll
* check for that. The line name and time of day are both
* updated as well.
*/
if (fl->fail_cnt + 1 > 0)
fl->fail_cnt++;
strncpy(fl->fail_line, tty, sizeof fl->fail_line);
time(&fl->fail_time);
/*
* Seek back to the correct position in the file and write the
* record out. Ideally we should lock the file in case the same
* account is being logged simultaneously. But the risk doesn't
* seem that great.
*/
lseek(fd, (off_t) (sizeof *fl) * uid, SEEK_SET);
write(fd, (char *) fl, sizeof *fl);
close(fd);
}
static int too_many_failures(const struct faillog *fl)
{
time_t now;
if (fl->fail_max == 0 || fl->fail_cnt < fl->fail_max)
return 0;
if (fl->fail_locktime == 0)
return 1; /* locked until reset manually */
time(&now);
if (fl->fail_time + fl->fail_locktime > now)
return 0; /* enough time since last failure */
return 1;
}
/*
* failcheck - check for failures > allowable
*
* failcheck() is called AFTER the password has been validated. If the
* account has been "attacked" with too many login failures, failcheck()
* returns FALSE to indicate that the login should be denied even though
* the password is valid.
*/
int failcheck(uid_t uid, struct faillog *fl, int failed)
{
int fd;
struct faillog fail;
/*
* Suppress the check if the log file isn't there.
*/
if ((fd = open(FAILLOG_FILE, O_RDWR)) < 0)
return 1;
/*
* Get the record from the file and determine if the user has
* exceeded the failure limit. If "max" is zero, any number
* of failures are permitted. Only when "max" is non-zero and
* "cnt" is greater than or equal to "max" is the account
* considered to be locked.
*
* If read fails, there is no record for this user yet (the
* file is initially zero length and extended by writes), so
* no need to reset the count.
*/
lseek (fd, (off_t) (sizeof *fl) * uid, SEEK_SET);
if (read(fd, (char *) fl, sizeof *fl) != sizeof *fl) {
close(fd);
return 1;
}
if (too_many_failures(fl)) {
close(fd);
return 0;
}
/*
* The record is updated if this is not a failure. The count will
* be reset to zero, but the rest of the information will be left
* in the record in case someone wants to see where the failed
* login originated.
*/
if (!failed) {
fail = *fl;
fail.fail_cnt = 0;
lseek (fd, (off_t) sizeof fail * uid, SEEK_SET);
write (fd, (char *) &fail, sizeof fail);
}
close (fd);
return 1;
}
/*
* failprint - print line of failure information
*
* failprint takes a (struct faillog) entry and formats it into a
* message which is displayed at login time.
*/
void failprint(const struct faillog *fail)
{
struct tm *tp;
#if HAVE_STRFTIME
char lasttimeb[256];
char *lasttime = lasttimeb;
const char *fmt;
#else
char *lasttime;
#endif
time_t NOW;
if (fail->fail_cnt == 0)
return;
tp = localtime (&(fail->fail_time));
time(&NOW);
#if HAVE_STRFTIME
/*
* Only print as much date and time info as it needed to
* know when the failure was.
*/
if (NOW - fail->fail_time >= YEAR)
fmt = "%Y";
else if (NOW - fail->fail_time >= DAY)
fmt = "%A %T";
else
fmt = "%T";
strftime(lasttimeb, sizeof lasttimeb, fmt, tp);
#else
/*
* Do the same thing, but don't use strftime since it
* probably doesn't exist on this system
*/
lasttime = asctime (tp);
lasttime[24] = '\0';
if (NOW - fail->fail_time < YEAR)
lasttime[19] = '\0';
if (NOW - fail->fail_time < DAY)
lasttime = lasttime + 11;
if (*lasttime == ' ')
lasttime++;
#endif
printf ("%d %s since last login. Last was %s on %s.\n",
fail->fail_cnt, fail->fail_cnt > 1 ? "failures":"failure",
lasttime, fail->fail_line);
}
/*
* failtmp - update the cummulative failure log
*
* failtmp updates the (struct utmp) formatted failure log which
* maintains a record of all login failures.
*/
void failtmp(const struct utmp *failent)
{
char *ftmp;
int fd;
/*
* Get the name of the failure file. If no file has been defined
* in login.defs, don't do this.
*/
if (!(ftmp = getdef_str("FTMP_FILE")))
return;
/*
* Open the file for append. It must already exist for this
* feature to be used.
*/
if ((fd = open(ftmp, O_WRONLY|O_APPEND)) == -1)
return;
/*
* Output the new failure record and close the log file.
*/
write(fd, (const char *) failent, sizeof *failent);
close(fd);
}

View File

@ -1,42 +0,0 @@
/* $Id$ */
#ifndef _FAILURE_H_
#define _FAILURE_H_
#include <utmp.h>
/*
* failure - make failure entry
*
* failure() creates a new (struct faillog) entry or updates an
* existing one with the current failed login information.
*/
extern void failure(uid_t, const char *, struct faillog *);
/*
* failcheck - check for failures > allowable
*
* failcheck() is called AFTER the password has been validated. If the
* account has been "attacked" with too many login failures, failcheck()
* returns FALSE to indicate that the login should be denied even though
* the password is valid.
*/
extern int failcheck(uid_t, struct faillog *, int);
/*
* failprint - print line of failure information
*
* failprint takes a (struct faillog) entry and formats it into a
* message which is displayed at login time.
*/
extern void failprint(const struct faillog *);
/*
* failtmp - update the cummulative failure log
*
* failtmp updates the (struct utmp) formatted failure log which
* maintains a record of all login failures.
*/
extern void failtmp(const struct utmp *);
#endif

View File

@ -1,13 +1,12 @@
/*****************************************************************************
*
* File ..................: mbuseradd/getdef.c
* $Id$
* Purpose ...............: MBSE BBS Shadow Password Suite
* Last modification date : 09-Aug-2001
* Original Source .......: Shadow Password Suite
* Original Copyrioght ...: Julianne Frances Haugh and others.
* Original Copyright ....: Julianne Frances Haugh and others.
*
*****************************************************************************
* Copyright (C) 1997-2001
* Copyright (C) 1997-2002
*
* Michiel Broek FIDO: 2:280/2802
* Beekmansbos 10
@ -69,6 +68,8 @@
#include "getdef.h"
#ifndef __FreeBSD__
/*
* A configuration item definition.
*/
@ -399,3 +400,5 @@ int main(int argc, char **argv)
exit(0);
}
#endif
#endif /* ifndef __FreeBSD__ */

View File

@ -1,10 +1,15 @@
/* $Id$ */
#ifndef _GETDEF_H
#define _GETDEF_H
/* getdef.c */
#ifndef __FreeBSD__
int getdef_bool(const char *);
long getdef_long(const char *, long);
int getdef_num(const char *, int);
char *getdef_str(const char *);
#endif
#endif /* _GETDEF_H */

View File

@ -46,7 +46,8 @@
#include <grp.h>
#include "getdef.h"
#include "utmp.h"
#include "ulimit.h"
#include "limits.h"
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
@ -62,6 +63,8 @@
#define LOGIN_ERROR_RLIMIT 1
#define LOGIN_ERROR_LOGIN 2
/* Set a limit on a resource */
/*
* rlimit - RLIMIT_XXXX
@ -114,50 +117,6 @@ int set_umask(const char *value)
}
/* Counts the number of user logins and check against the limit */
int check_logins(const char *name, const char *maxlogins)
{
struct utmp *ut;
unsigned int limit, count;
char **endptr = (char **) &maxlogins;
const char *ml_orig = maxlogins;
limit = strtol(maxlogins, endptr, 10);
if (limit == 0 && ml_orig == *endptr) /* no chars read */
return 0;
if (limit == 0) /* maximum 0 logins ? */ {
syslog(LOG_WARNING, "No logins allowed for `%s'\n", name);
return LOGIN_ERROR_LOGIN;
}
setutent();
count = 0;
while ((ut = getutent())) {
#ifdef USER_PROCESS
if (ut->ut_type != USER_PROCESS)
continue;
#endif
#ifndef __FreeBSD__
if (ut->ut_user[0] == '\0')
continue;
if (strncmp(name, ut->ut_user, sizeof(ut->ut_user)) != 0)
continue;
#endif
if (++count > limit)
break;
}
endutent();
/*
* This is called after setutmp(), so the number of logins counted
* includes the user who is currently trying to log in.
*/
if (count > limit) {
syslog(LOG_WARNING, "Too many logins (max %d) for %s\n", limit, name);
return LOGIN_ERROR_LOGIN;
}
return 0;
}
/* Function setup_user_limits - checks/set limits for the curent login
* Original idea from Joel Katz's lshell. Ported to shadow-login
@ -272,8 +231,7 @@ int do_user_limits(const char *buf, const char *name)
break;
case 'l':
case 'L':
/* LIMIT the number of concurent logins */
retval |= check_logins(name, pp);
/* LIMIT the number of concurent logins, not for MBSE BBS. */
break;
case 'p':
case 'P':
@ -283,6 +241,8 @@ int do_user_limits(const char *buf, const char *name)
return retval;
}
int setup_user_limits(const char *uname)
{
/* TODO: allow and use @group syntax --cristiang */
@ -420,3 +380,12 @@ void setup_limits(const struct passwd *info)
}
void set_filesize_limit(int blocks)
{
struct rlimit rlimit_fsize;
rlimit_fsize.rlim_cur = rlimit_fsize.rlim_max = 512L * blocks;
setrlimit(RLIMIT_FSIZE, &rlimit_fsize);
}

View File

@ -12,5 +12,6 @@ int do_user_limits(const char *, const char *);
int setup_user_limits(const char *);
void setup_usergroups(const struct passwd *);
void setup_limits(const struct passwd *);
void set_filesize_limit(int);
#endif

View File

@ -61,10 +61,8 @@
#include "env.h"
#include "chowntty.h"
#include "ttytype.h"
#include "basename.h"
#include "shell.h"
#include "failure.h"
#include "pwdcheck.h"
#include "pwauth.h"
#include "loginprompt.h"
@ -72,9 +70,7 @@
#include "limits.h"
#include "setupenv.h"
#include "sub.h"
#include "ulimit.h"
#include "log.h"
#include "tz.h"
#include "setugid.h"
@ -126,7 +122,6 @@ extern char **environ;
#define RETRIES 3
#endif
static struct faillog faillog;
#define NO_SHADOW "no shadow password for `%s'%s\n"
#define BAD_PASSWD "invalid password for `%s'%s\n"
@ -307,8 +302,7 @@ static void init_env(void)
if ((tmp = getenv("TZ"))) {
addenv("TZ", tmp);
} else if ((cp = getdef_str("ENV_TZ")))
addenv(*cp == '/' ? tz(cp) : cp, NULL);
}
/*
* Add the clock frequency so that profiling commands work
@ -697,19 +691,11 @@ auth_ok:
failed = 1;
}
#endif
if (pwd && getdef_bool("FAILLOG_ENAB") && ! failcheck (pwent.pw_uid, &faillog, failed)) {
syslog(LOG_CRIT, FAILURE_CNT, username, fromhost);
failed = 1;
}
if (! failed)
break;
/* don't log non-existent users */
if (pwd && getdef_bool("FAILLOG_ENAB"))
failure (pwent.pw_uid, tty, &faillog);
if (getdef_str("FTMP_FILE") != NULL) {
const char *failent_user;
#if HAVE_UTMPX_H
failent = utxent;
gettimeofday(&(failent.ut_tv), NULL);
@ -725,13 +711,10 @@ auth_ok:
else
failent_user = "UNKNOWN";
}
#ifndef __FreeBSD__
strncpy(failent.ut_user, failent_user, sizeof(failent.ut_user));
#endif
#ifdef USER_PROCESS
failent.ut_type = USER_PROCESS;
#endif
failtmp(&failent);
}
memzero(username, sizeof username);
@ -863,9 +846,6 @@ auth_ok:
addenv("HUSHLOGIN=TRUE", NULL);
if (getdef_str("TTYTYPE_FILE") != NULL && getenv("TERM") == NULL)
ttytype (tty);
signal(SIGQUIT, SIG_DFL); /* default quit signal */
signal(SIGTERM, SIG_DFL); /* default terminate signal */
signal(SIGALRM, SIG_DFL); /* default alarm signal */

View File

@ -247,26 +247,6 @@ extern char *strerror();
/*
* login failure logging file format
*
* The login failure file is maintained by login(1) and faillog(8)
* Each record in the file represents a separate UID and the file
* is indexed in that fashion.
*/
struct faillog {
short fail_cnt; /* failures since last success */
short fail_max; /* failures before turning account off */
char fail_line[12]; /* last failure occured here */
time_t fail_time; /* last failure occured then */
/*
* If nonzero, the account will be re-enabled if there are no
* failures for fail_locktime seconds since last failure.
*/
long fail_locktime;
};
#define Max_passlen 14 /* Define maximum passwd length */

View File

@ -41,104 +41,35 @@
#include "getdef.h"
#include "encrypt.h"
#ifdef SKEY
#include <skey.h>
#endif
#ifdef OPIE
#include <opie.h>
#endif
#ifdef __linux__ /* standard password prompt by default */
/* standard password prompt by default */
static const char *PROMPT = gettext_noop("Password: ");
#else
static const char *PROMPT = gettext_noop("%s's Password: ");
#endif
#ifdef AUTH_METHODS
/*
* Look-up table for bound-in methods. Put the name that the
* method is known by in the password field as "name" and a
* pointer to the function
*/
struct method {
char *name;
int (*func) P_((const char *, int, const char *));
};
#ifdef PAD_AUTH
int pad_auth();
#endif
static struct method methods[] = {
#ifdef PAD_AUTH
{ "pad", pad_auth },
#endif
{ "", 0 }
};
#endif /* AUTH_METHODS */
int wipe_clear_pass = 1;
char *clear_pass = NULL;
/*
* _old_auth - perform getpass/crypt authentication
*
* _old_auth gets the user's cleartext password and encrypts it
* using the salt in the encrypted password. The results are
* compared.
*/
static int _old_auth(const char *cipher, const char *user, int reason, const char *input)
/*
* pw_auth gets the user's cleartext password and encrypts it
* using the salt in the encrypted password. The results are
* compared.
*/
int pw_auth(const char *cipher, const char *user, int reason, const char *input)
{
char prompt[1024];
char *clear = NULL;
const char *cp;
int retval;
#ifdef SKEY
int use_skey = 0;
char challenge_info[40];
struct skey skey;
#endif
#ifdef OPIE
int use_opie = 0;
char o_challenge_info[OPIE_CHALLENGE_MAX + 1];
struct opie opie;
/*
* This implementation is based almost entirely on the SKEY code
* above. Thus the opie struct is called skey, etc. I am unaware
* if the system works at the same time, but I cannot imagine why
* anyone would want to do this....
* -- A.R.
* Mod: 5/14/98 A.R.
* Made the OPIE code separate from the S/Key code. Now
* (conceivably) both can be compiled in and function apart from
* one another (assuming a sysadmin really wants to maintain OPIE
* and an S/Key databases....).
*
* Also cleaned up the code a bit. Will be adding second-prompt
* support (the traditional Echo-on S/Key/OPIE-only prompts to let
* the users see the one-time passwords they are typing/pasting
* in....
* -- A.R.
*/
#endif
/*
* There are programs for adding and deleting authentication data.
*/
if (reason == PW_ADD || reason == PW_DELETE)
return 0;
/*
* There are even programs for changing the user name ...
*/
if (reason == PW_CHANGE && input != (char *) 0)
return 0;
@ -150,7 +81,6 @@ static int _old_auth(const char *cipher, const char *user, int reason, const cha
* know it. This is a policy decision that might have to be
* revisited.
*/
if (reason == PW_CHANGE && getuid () == 0)
return 0;
@ -162,61 +92,16 @@ static int _old_auth(const char *cipher, const char *user, int reason, const cha
* the user could just hit <ENTER>, so it doesn't really
* matter.
*/
if (cipher == (char *) 0 || *cipher == '\0')
return 0;
#ifdef SKEY
/*
* If the user has an S/KEY entry show them the pertinent info
* and then we can try validating the created cyphertext and the SKEY.
* If there is no SKEY information we default to not using SKEY.
*/
if (skeychallenge (&skey, user, challenge_info) == 0)
use_skey = 1;
#endif
#ifdef OPIE
/*
* Ditto above, for OPIE passwords.
* -- AR
*/
o_challenge_info[0] = '\0';
if (opiechallenge(&opie, user, o_challenge_info) == 0)
use_opie = 1;
if (use_opie == 0)
opieverify(&opie, (char *)NULL);
/*
* This call to opieverify is necessary within OPIE's interface:
* Every call to opiechallenge(), which checks to see if the user
* has an OPIE password, and if so get the challenge, must be
* accompanied by exactly one call to opieverify, which clears
* any outstanding locks, and otherwise cleans up.
* -- AR
*/
#endif
/*
* Prompt for the password as required. FTPD and REXECD both
* get the cleartext password for us.
*/
if (reason != PW_FTP && reason != PW_REXEC && !input) {
if (! (cp = getdef_str ("LOGIN_STRING")))
cp = PROMPT;
#ifdef SKEY
if (use_skey)
printf ("[%s]\n", challenge_info);
#endif
#ifdef OPIE
if (use_opie)
printf("[ %s ]\n", o_challenge_info);
#endif
snprintf(prompt, sizeof prompt, cp, user);
clear = getpass(prompt);
if (!clear) {
@ -233,72 +118,8 @@ static int _old_auth(const char *cipher, const char *user, int reason, const cha
* SUCCESS. Otherwise we see if SKEY is being used and check
* the results there as well.
*/
retval = strcmp(pw_encrypt(input, cipher), cipher);
#ifdef OPIE
/*
* This is required because using OPIE, opieverify() MUST be called
* opiechallenge() above even if OPIE isn't being used in this case,
* so locks get released, etc.
* -- AR
*/
if ((retval == 0) && use_opie)
opieverify(&opie, (char *)NULL);
#endif
#if (defined(SKEY) || defined(OPIE))
/*
* If (1) The password fails to match, and
* (2) The password is empty and
* (3) We are using OPIE or S/Key, then
* ...Re-prompt, with echo on.
* -- AR 8/22/1999
*/
if (retval && !input[0] &&
(0
#ifdef SKEY
|| use_skey
#endif
#ifdef OPIE
|| use_opie
#endif
)) {
strncat(prompt, _("(Echo on) "),
(sizeof(prompt) - strlen(prompt)));
clear = getpass_with_echo(prompt);
if (!clear) {
static char c[1];
c[0] = '\0';
clear = c;
}
input = clear;
}
#endif
#ifdef SKEY
if (retval && use_skey) {
int passcheck = -1;
#if 0 /* some skey libs don't have skey_passcheck. --marekm */
passcheck = skey_passcheck(user, input);
#else
if (skeyverify(&skey, input) == 0)
passcheck = skey.n;
#endif /* if 0 */
if (passcheck > 0)
retval = 0;
}
#endif
#ifdef OPIE
if (retval && use_opie) {
if (opieverify(&opie, input) == 0)
retval = 0;
}
#endif /* OPIE */
/*
* Things like RADIUS authentication may need the password -
* if the external variable wipe_clear_pass is zero, we will
@ -312,264 +133,4 @@ static int _old_auth(const char *cipher, const char *user, int reason, const cha
return retval;
}
#ifdef AUTH_METHODS
/*
* _pw_auth - perform alternate password authentication
*
* pw_auth executes the alternate password authentication method
* described in the user's password entry. _pw_auth does the real
* work, pw_auth splits the authentication string into individual
* command names.
*/
static int _pw_auth(const char *command, const char *user, int reason, const char *input)
{
RETSIGTYPE (*sigint)();
RETSIGTYPE (*sigquit)();
#ifdef SIGTSTP
RETSIGTYPE (*sigtstp)();
#endif
int pid;
int status;
int i;
char * const argv[5];
int argc = 0;
int pipes[2];
char *empty_env = NULL;
int use_pipe;
/*
* Start with a quick sanity check. ALL command names must
* be fully-qualified path names.
*/
if (command[0] != '/')
return -1;
/*
* Set the keyboard signals to be ignored. When the user kills
* the child we don't want the parent dying as well.
*/
sigint = signal (SIGINT, SIG_IGN);
sigquit = signal (SIGQUIT, SIG_IGN);
#ifdef SIGTSTP
sigtstp = signal (SIGTSTP, SIG_IGN);
#endif
/*
* FTP and REXEC reasons don't give the program direct access
* to the user. This means that the program can only get input
* from this function. So we set up a pipe for that purpose.
*/
use_pipe = (reason == PW_FTP || reason == PW_REXEC);
if (use_pipe)
if (pipe (pipes))
return -1;
/*
* The program will be forked off with the parent process waiting
* on the child to tell it how successful it was.
*/
switch (pid = fork ()) {
/*
* The fork() failed completely. Clean up as needed and
* return to the caller.
*/
case -1:
if (use_pipe) {
close (pipes[0]);
close (pipes[1]);
}
return -1;
case 0:
/*
* Let the child catch the SIGINT and SIGQUIT
* signals. The parent, however, will continue
* to ignore them.
*/
signal (SIGINT, SIG_DFL);
signal (SIGQUIT, SIG_DFL);
/*
* Set up the command line. The first argument is
* the name of the command being executed. The
* second is the command line option for the reason,
* and the third is the user name.
*/
argv[argc++] = command;
switch (reason) {
case PW_SU: argv[argc++] = "-s"; break;
case PW_LOGIN: argv[argc++] = "-l"; break;
case PW_ADD: argv[argc++] = "-a"; break;
case PW_CHANGE: argv[argc++] = "-c"; break;
case PW_DELETE: argv[argc++] = "-d"; break;
case PW_TELNET: argv[argc++] = "-t"; break;
case PW_RLOGIN: argv[argc++] = "-r"; break;
case PW_FTP: argv[argc++] = "-f"; break;
case PW_REXEC: argv[argc++] = "-x"; break;
}
if (reason == PW_CHANGE && input)
argv[argc++] = input;
argv[argc++] = user;
argv[argc] = (char *) 0;
/*
* The FTP and REXEC reasons use a pipe to communicate
* with the parent. The other standard I/O descriptors
* are closed and re-opened as /dev/null.
*/
if (use_pipe) {
close (0);
close (1);
close (2);
if (dup (pipes[0]) != 0)
exit (1);
close (pipes[0]);
close (pipes[1]);
if (open ("/dev/null", O_WRONLY) != 1)
exit (1);
if (open ("/dev/null", O_WRONLY) != 2)
exit (1);
}
/*
* Now we execute the command directly.
* Do it with empty environment for safety. --marekm
*/
execve(command, argv, &empty_env);
_exit((errno == ENOENT) ? 127 : 126);
/*NOTREACHED*/
default:
/*
* FTP and REXEC cause a single line of text to be
* sent to the child over a pipe that was set up
* earlier.
*/
if (use_pipe) {
close (pipes[0]);
if (input)
write (pipes[1], input, strlen (input));
write (pipes[1], "\n", 1);
close (pipes[1]);
}
/*
* Wait on the child to die. When it does you will
* get the exit status and use that to determine if
* the authentication program was successful.
*/
while ((i = wait (&status)) != pid && i != -1)
;
/*
* Re-set the signals to their earlier values.
*/
signal (SIGINT, sigint);
signal (SIGQUIT, sigquit);
#ifdef SIGTSTP
signal (SIGTSTP, sigtstp);
#endif
/*
* Make sure we found the right process!
*/
if (i == -1)
return -1;
if (status == 0)
return 0;
else
return -1;
}
/*NOTREACHED*/
}
/*
* _builtin_auth - lookup routine in table and execute
*/
static int _builtin_auth(const char *command, const char *user, int reason, const char *input)
{
int i;
/*
* Scan the table, looking for a match. If we fall off
* the end, it must mean that this method isn't supported,
* so we fail the authentication.
*/
for (i = 0;methods[i].name[0];i++) {
if (! strcmp (command, methods[i].name))
break;
}
if (methods[i].name[0] == '\0')
return -1;
/*
* Call the pointed to function with the other three
* arguments.
*/
return (methods[i].func) (user, reason, input);
}
#endif /* AUTH_METHODS */
/*
* This function does the real work. It splits the list of program names
* up into individual programs and executes them one at a time.
*/
int pw_auth(const char *command, const char *user, int reason, const char *input)
{
#ifdef AUTH_METHODS
char buf[256];
char *cmd, *end;
int rc;
/*
* Quick little sanity check ...
*/
if (strlen (command) >= sizeof buf)
return -1;
strcpy(buf, command); /* safe (because of the above check) --marekm */
/*
* Find each command and make sure it is NUL-terminated. Then
* invoke _pw_auth to actually run the program. The first
* failing program ends the whole mess.
*/
for (cmd = buf;cmd;cmd = end) {
if ((end = strchr (cmd, ';')))
*end++ = '\0';
if (cmd[0] != '@')
rc = _old_auth (cmd, user, reason, input);
else if (cmd[1] == '/')
rc = _pw_auth (cmd + 1, user, reason, input);
else
rc = _builtin_auth (cmd + 1, user, reason, input);
if (rc)
return -1;
}
return 0;
#else
return _old_auth(command, user, reason, input);
#endif
}

View File

@ -77,6 +77,8 @@ int setup_groups(const struct passwd *info)
return 0;
}
int change_uid(const struct passwd *info)
{
/*
@ -96,30 +98,21 @@ int change_uid(const struct passwd *info)
return 0;
}
/*
* setup_uid_gid() performs the following steps -
*
* set the group ID to the value from the password file entry
* set the supplementary group IDs
* optionally call specified function which may add more groups
* set the user ID to the value from the password file entry
*
* Returns 0 on success, or -1 on failure.
*/
int setup_uid_gid(const struct passwd *info, int is_console)
{
if (setup_groups(info) < 0)
return -1;
#ifdef HAVE_INITGROUPS
if (is_console) {
char *cp = getdef_str("CONSOLE_GROUPS");
if (cp && add_groups(cp))
perror("Warning: add_groups");
}
#endif /* HAVE_INITGROUPS */
if (change_uid(info) < 0)
return -1;

View File

@ -60,6 +60,7 @@ void addenv_path(const char *varname, const char *dirname, const char *filename)
}
void read_env_file(const char *filename)
{
FILE *fp;
@ -93,85 +94,6 @@ void read_env_file(const char *filename)
/* NUL-terminate the name */
*cp++ = '\0';
val = cp;
#if 0 /* XXX untested, and needs rewrite with fewer goto's :-) */
/*
(state, char_type) -> (state, action)
state: unquoted, single_quoted, double_quoted, escaped, double_quoted_escaped
char_type: normal, white, backslash, single, double
action: remove_curr, remove_curr_skip_next, remove_prev, finish XXX
*/
no_quote:
if (*cp == '\\') {
/* remove the backslash */
remove_char(cp);
/* skip over the next character */
if (*cp)
cp++;
goto no_quote;
} else if (*cp == '\'') {
/* remove the quote */
remove_char(cp);
/* now within single quotes */
goto s_quote;
} else if (*cp == '"') {
/* remove the quote */
remove_char(cp);
/* now within double quotes */
goto d_quote;
} else if (*cp == '\0') {
/* end of string */
goto finished;
} else if (isspace(*cp)) {
/* unescaped whitespace - end of string */
*cp = '\0';
goto finished;
} else {
cp++;
goto no_quote;
}
s_quote:
if (*cp == '\'') {
/* remove the quote */
remove_char(cp);
/* unquoted again */
goto no_quote;
} else if (*cp == '\0') {
/* end of string */
goto finished;
} else {
/* preserve everything within single quotes */
cp++;
goto s_quote;
}
d_quote:
if (*cp == '\"') {
/* remove the quote */
remove_char(cp);
/* unquoted again */
goto no_quote;
} else if (*cp == '\\') {
cp++;
/* if backslash followed by double quote, remove backslash
else skip over the backslash and following char */
if (*cp == '"')
remove_char(cp - 1);
else if (*cp)
cp++;
goto d_quote;
} eise if (*cp == '\0') {
/* end of string */
goto finished;
} else {
/* preserve everything within double quotes */
goto d_quote;
}
finished:
#endif /* 0 */
/*
* XXX - should handle quotes, backslash escapes, etc.
* like the shell does.
*/
addenv(name, val);
}
fclose(fp);
@ -179,12 +101,12 @@ finished:
/*
* change to the user's home directory
* set the HOME, SHELL, MAIL, PATH, and LOGNAME or USER environmental
* variables.
*/
void setup_env(struct passwd *info)
{
char *cp, *envf;
@ -247,25 +169,25 @@ void setup_env(struct passwd *info)
/*
* MAILDIR environment variable for Qmail
*/
if ((cp=getdef_str("QMAIL_DIR")))
addenv_path("MAILDIR", info->pw_dir, cp);
// if ((cp=getdef_str("QMAIL_DIR")))
// addenv_path("MAILDIR", info->pw_dir, cp);
/*
* Create the MAIL environmental variable and export it. login.defs
* knows the prefix.
*/
if ((cp=getdef_str("MAIL_DIR")))
addenv_path("MAIL", cp, info->pw_name);
else if ((cp=getdef_str("MAIL_FILE")))
addenv_path("MAIL", info->pw_dir, cp);
else {
#if defined(MAIL_SPOOL_FILE)
addenv_path("MAIL", info->pw_dir, MAIL_SPOOL_FILE);
#elif defined(MAIL_SPOOL_DIR)
addenv_path("MAIL", MAIL_SPOOL_DIR, info->pw_name);
#endif
}
// if ((cp=getdef_str("MAIL_DIR")))
// addenv_path("MAIL", cp, info->pw_name);
// else if ((cp=getdef_str("MAIL_FILE")))
// addenv_path("MAIL", info->pw_dir, cp);
// else {
//#if defined(MAIL_SPOOL_FILE)
// addenv_path("MAIL", info->pw_dir, MAIL_SPOOL_FILE);
//#elif defined(MAIL_SPOOL_DIR)
// addenv_path("MAIL", MAIL_SPOOL_DIR, info->pw_name);
//#endif
// }
/*
* Read environment from optional config file. --marekm
@ -273,3 +195,4 @@ void setup_env(struct passwd *info)
if ((envf = getdef_str("ENVIRON_FILE")))
read_env_file(envf);
}

View File

@ -3,7 +3,7 @@
* $Id$
* Purpose ...............: MBSE BBS Shadow Password Suite
* Original Source .......: Shadow Password Suite
* Original Copyrioght ...: Julianne Frances Haugh and others.
* Original Copyright ....: Julianne Frances Haugh and others.
*
*****************************************************************************
* Copyright (C) 1997-2001

View File

@ -1,90 +0,0 @@
/*****************************************************************************
*
* $Id$
* Purpose ...............: MBSE BBS Shadow Password Suite
* Original Source .......: Shadow Password Suite
* Original Copyrioght ...: Julianne Frances Haugh and others.
*
*****************************************************************************
* Copyright (C) 1997-2001
*
* Michiel Broek FIDO: 2:280/2802
* Beekmansbos 10
* 1971 BV IJmuiden
* the Netherlands
*
* This file is part of MBSE BBS.
*
* This BBS is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* MBSE BBS is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MBSE BBS; see the file COPYING. If not, write to the Free
* Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*****************************************************************************/
#include "../config.h"
#include <stdio.h>
#include "mblogin.h"
#include "getdef.h"
#include "env.h"
#include "ttytype.h"
// extern char *getenv();
/*
* ttytype - set ttytype from port to terminal type mapping database
*/
void ttytype(const char *line)
{
FILE *fp;
char buf[BUFSIZ];
char *typefile;
char *cp;
char type[BUFSIZ];
char port[BUFSIZ];
if (getenv ("TERM"))
return;
if ((typefile=getdef_str("TTYTYPE_FILE")) == NULL )
return;
if (access(typefile, F_OK))
return;
if (! (fp = fopen (typefile, "r"))) {
perror (typefile);
return;
}
while (fgets(buf, sizeof buf, fp)) {
if (buf[0] == '#')
continue;
if ((cp = strchr (buf, '\n')))
*cp = '\0';
#if defined(SUN) || defined(BSD) || defined(SUN4)
if ((sscanf (buf, "%s \"%*[^\"]\" %s", port, type) == 2 ||
sscanf (buf, "%s %*s %s", port, type) == 2) &&
strcmp (line, port) == 0)
break;
#else /* USG */
if (sscanf (buf, "%s %s", type, port) == 2 &&
strcmp (line, port) == 0)
break;
#endif
}
if (! feof (fp) && ! ferror (fp))
addenv("TERM", type);
fclose (fp);
}

View File

@ -1,8 +0,0 @@
/* $Id$ */
#ifndef _TTYTYPE_H
#define _TTYTYPE_H
void ttytype(const char *);
#endif

View File

@ -1,67 +0,0 @@
/*****************************************************************************
*
* $Id$
* Purpose ...............: MBSE BBS Shadow Password Suite
* Original Source .......: Shadow Password Suite
* Original Copyright ....: Julianne Frances Haugh and others.
*
*****************************************************************************
* Copyright (C) 1997-2001
*
* Michiel Broek FIDO: 2:280/2802
* Beekmansbos 10
* 1971 BV IJmuiden
* the Netherlands
*
* This file is part of MBSE BBS.
*
* This BBS is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* MBSE BBS is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MBSE BBS; see the file COPYING. If not, write to the Free
* Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*****************************************************************************/
#include "../config.h"
#include <stdio.h>
#include <string.h>
#include "mblogin.h"
#include "getdef.h"
#include "tz.h"
/*
* tz - return local timezone name
*
* tz() determines the name of the local timezone by reading the
* contents of the file named by ``fname''.
*/
char *tz(const char *fname)
{
FILE *fp = 0;
static char tzbuf[BUFSIZ];
const char *def_tz;
if ((fp = fopen(fname,"r")) == NULL ||
fgets (tzbuf, sizeof (tzbuf), fp) == NULL) {
if (! (def_tz = getdef_str ("ENV_TZ")) || def_tz[0] == '/')
def_tz = "TZ=CST6CDT";
strcpy (tzbuf, def_tz);
} else
tzbuf[strlen(tzbuf) - 1] = '\0';
if (fp)
(void) fclose(fp);
return tzbuf;
}

View File

@ -1,8 +0,0 @@
/* $Id$ */
#ifndef _TZTZ_H
#define _TZTZ_H
char *tz(const char *);
#endif

View File

@ -1,66 +0,0 @@
/*****************************************************************************
*
* $Id$
* Purpose ...............: MBSE BBS Shadow Password Suite
* Original Source .......: Shadow Password Suite
* Original Copyright ....: Julianne Frances Haugh and others.
*
*****************************************************************************
* Copyright (C) 1997-2001
*
* Michiel Broek FIDO: 2:280/2802
* Beekmansbos 10
* 1971 BV IJmuiden
* the Netherlands
*
* This file is part of MBSE BBS.
*
* This BBS is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* MBSE BBS is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MBSE BBS; see the file COPYING. If not, write to the Free
* Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*****************************************************************************/
#include "../config.h"
#if HAVE_ULIMIT_H
#include <ulimit.h>
#ifndef UL_SETFSIZE
#ifdef UL_SFILLIM
#define UL_SETFSIZE UL_SFILLIM
#else
#define UL_SETFSIZE 2
#endif
#endif
#elif HAVE_SYS_RESOURCE_H
#include <sys/time.h> /* for struct timeval on sunos4 */
/* XXX - is the above ok or should it be <time.h> on ultrix? */
#include <sys/resource.h>
#endif
#include "ulimit.h"
void set_filesize_limit(int blocks)
{
#if HAVE_ULIMIT_H
ulimit(UL_SETFSIZE, blocks);
#elif defined(RLIMIT_FSIZE)
struct rlimit rlimit_fsize;
rlimit_fsize.rlim_cur = rlimit_fsize.rlim_max = 512L * blocks;
setrlimit(RLIMIT_FSIZE, &rlimit_fsize);
#endif
}

View File

@ -1,9 +0,0 @@
/* $Id$ */
#ifndef _ULIMIT_H_H
#define _ULIMIT_H_H
void set_filesize_limit(int);
#endif

View File

@ -48,13 +48,6 @@ extern struct utmpx utxent;
#endif
extern struct utmp utent;
// extern struct utmp *getutent();
// extern struct utmp *getutline();
// extern void setutent();
// extern void endutent();
// extern time_t time();
// extern char *ttyname();
// extern long lseek();
#define NO_UTENT \
"No utmp entry. You must exec \"login\" from the lowest level \"sh\""