Updates for mblogin
This commit is contained in:
parent
ce20472e98
commit
971a39b565
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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__ */
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
||||
|
||||
|
455
mbsebbs/pwauth.c
455
mbsebbs/pwauth.c
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -1,8 +0,0 @@
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef _TTYTYPE_H
|
||||
#define _TTYTYPE_H
|
||||
|
||||
void ttytype(const char *);
|
||||
|
||||
#endif
|
67
mbsebbs/tz.c
67
mbsebbs/tz.c
@ -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;
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef _TZTZ_H
|
||||
#define _TZTZ_H
|
||||
|
||||
char *tz(const char *);
|
||||
|
||||
#endif
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -1,9 +0,0 @@
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef _ULIMIT_H_H
|
||||
#define _ULIMIT_H_H
|
||||
|
||||
|
||||
void set_filesize_limit(int);
|
||||
|
||||
#endif
|
@ -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\""
|
||||
|
Reference in New Issue
Block a user