Splitted mbsebbs sourcetree
This commit is contained in:
@@ -4,29 +4,23 @@
|
||||
|
||||
include ../Makefile.global
|
||||
|
||||
SRCS = bank.c commonio.c filesub.c language.c mbtoberep.c \
|
||||
msgutil.c oneline.c sgetpwent.c xmalloc.c bbslist.c morefile.c \
|
||||
email.c fsedit.c lineedit.c mblang.c mbuser.c myname.c page.c \
|
||||
pwio.c shadowio.c bye.c encrypt.c funcs.c mail.c mbpasswd.c \
|
||||
mbuseradd.c newuser.c pinfo.c rad64.c timecheck.c change.c \
|
||||
SRCS = bank.c filesub.c language.c mbtoberep.c \
|
||||
msgutil.c oneline.c bbslist.c morefile.c \
|
||||
email.c fsedit.c lineedit.c mblang.c mbuser.c page.c \
|
||||
bye.c funcs.c mail.c \
|
||||
newuser.c pinfo.c timecheck.c change.c \
|
||||
exitinfo.c mball.c mbsebbs.c menu.c nextuser.c pop3.c lastcallers.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 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 \
|
||||
encrypt.h funcs.h mail.h mbuser.h myname.h page.h pwio.h shadowio.h \
|
||||
xmalloc.h change.h exitinfo.h mball.h mbuseradd.h newuser.h \
|
||||
pinfo.h rad64.h chat.h file.h getdef.h mbpasswd.h menu.h \
|
||||
safe.c timeout.c chat.c file.c mbchat.c mbstat.c misc.c \
|
||||
offline.c user.c mbnewusr.c input.c whoson.c \
|
||||
door.c dispfile.c userlist.c timestats.c logentry.c
|
||||
HDRS = bank.h filesub.h language.h mbsebbs.h misc.h offline.h \
|
||||
timeout.h bbslist.h email.h fsedit.h lineedit.h \
|
||||
mbstat.h msgutil.h oneline.h user.h bye.h morefile.h \
|
||||
funcs.h mail.h mbuser.h page.h \
|
||||
change.h exitinfo.h mball.h newuser.h \
|
||||
pinfo.h chat.h file.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 shell.h basename.h \
|
||||
pwdcheck.h pwauth.h loginprompt.h utmp.h limits.h \
|
||||
setupenv.h sub.h log.h setugid.h utent.h
|
||||
door.h dispfile.h userlist.h timestats.h logentry.h lastcallers.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 \
|
||||
@@ -52,14 +46,8 @@ MBTOBEREP_OBJS = mbtoberep.o
|
||||
MBTOBEREP_LIBS = ../lib/libmemwatch.a ../lib/libclcomm.a ../lib/libcommon.a ../lib/libdbase.a
|
||||
MBUSER_OBJS = mbuser.o
|
||||
MBUSER_LIBS = ../lib/libmemwatch.a ../lib/libclcomm.a ../lib/libcommon.a ../lib/libdbase.a
|
||||
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 shell.o basename.o \
|
||||
pwdcheck.o pwauth.o encrypt.o loginprompt.o utmp.o limits.o setupenv.o sub.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
|
||||
TARGET = mbsebbs mbnewusr mball mblang mbchat mbstat mbtoberep mbuser
|
||||
|
||||
#############################################################################################################
|
||||
|
||||
@@ -103,18 +91,6 @@ mbuser: ${MBUSER_OBJS} ${MBUSER_LIBS}
|
||||
${CC} -o mbuser ${MBUSER_OBJS} ${LIBS} ${MBUSER_LIBS}
|
||||
strip mbuser
|
||||
|
||||
mbuseradd: ${MBUSERADD_OBJS}
|
||||
${CC} -o mbuseradd ${MBUSERADD_OBJS} ${LIBS}
|
||||
strip mbuseradd
|
||||
|
||||
mbpasswd: ${MBPASSWD_OBJS}
|
||||
${CC} -o mbpasswd ${MBPASSWD_OBJS} ${LIBS}
|
||||
strip mbpasswd
|
||||
|
||||
mblogin: ${MBLOGIN_OBJS}
|
||||
${CC} -o mblogin ${MBLOGIN_OBJS} ${LIBS}
|
||||
strip mblogin
|
||||
|
||||
install: all
|
||||
@if [ "`id -un`" != "root" ] ; then \
|
||||
echo; echo " Must be root to install!"; echo; exit 3; \
|
||||
@@ -127,10 +103,8 @@ install: all
|
||||
${INSTALL} -c -s -o ${OWNER} -g ${GROUP} -m 0711 mbstat ${BINDIR}
|
||||
${INSTALL} -c -s -o ${OWNER} -g ${GROUP} -m 0711 mbtoberep ${BINDIR}
|
||||
${INSTALL} -c -s -o `id -un` -g `id -gn` -m 6711 mbuser ${BINDIR}
|
||||
${INSTALL} -c -s -o `id -un` -g `id -gn` -m 6711 mbuseradd ${BINDIR}
|
||||
${INSTALL} -c -s -o `id -un` -g `id -gn` -m 6711 mbpasswd ${BINDIR}
|
||||
${INSTALL} -c -s -o `id -un` -g `id -gn` -m 0755 mblogin ${BINDIR}
|
||||
@rm -f ${BINDIR}/mbfbgen
|
||||
@rm -f mbuseradd mbpasswd mblogin
|
||||
|
||||
filelist: Makefile
|
||||
BASE=`pwd`; \
|
||||
@@ -162,14 +136,11 @@ depend:
|
||||
# DO NOT DELETE THIS LINE - MAKE DEPEND RELIES ON IT
|
||||
# Dependencies generated by make depend
|
||||
bank.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/clcomm.h ../lib/common.h bank.h input.h language.h dispfile.h timeout.h timecheck.h whoson.h exitinfo.h
|
||||
commonio.o: ../config.h commonio.h
|
||||
filesub.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/clcomm.h filesub.h funcs.h language.h input.h misc.h timeout.h exitinfo.h change.h
|
||||
language.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/clcomm.h input.h language.h
|
||||
mbtoberep.o: ../lib/libs.h ../lib/structs.h
|
||||
msgutil.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/clcomm.h ../lib/msgtext.h ../lib/msg.h oneline.h msgutil.h
|
||||
oneline.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/clcomm.h oneline.h funcs.h input.h language.h
|
||||
sgetpwent.o: ../config.h sgetpwent.h
|
||||
xmalloc.o: ../config.h xmalloc.h
|
||||
bbslist.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/clcomm.h ../lib/common.h bbslist.h funcs.h input.h language.h
|
||||
morefile.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/clcomm.h ../lib/common.h input.h language.h morefile.h timeout.h
|
||||
email.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/msgtext.h ../lib/msg.h ../lib/common.h ../lib/clcomm.h ../lib/mbinet.h exitinfo.h language.h mail.h timeout.h msgutil.h input.h email.h whoson.h
|
||||
@@ -177,19 +148,12 @@ fsedit.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/a
|
||||
lineedit.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/clcomm.h mail.h input.h language.h timeout.h lineedit.h
|
||||
mblang.o: ../lib/libs.h ../lib/structs.h ../lib/records.h
|
||||
mbuser.o: ../lib/libs.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/clcomm.h ../lib/dbcfg.h mbuser.h
|
||||
myname.o: ../config.h
|
||||
page.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/clcomm.h dispfile.h input.h chat.h page.h timeout.h mail.h language.h
|
||||
pwio.o: ../config.h sgetpwent.h commonio.h putpwent.h pwio.h
|
||||
shadowio.o: ../config.h commonio.h shadowio.h
|
||||
bye.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/clcomm.h ../lib/common.h dispfile.h misc.h language.h bye.h
|
||||
encrypt.o: ../config.h encrypt.h
|
||||
funcs.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/msgtext.h ../lib/msg.h ../lib/clcomm.h funcs.h
|
||||
mail.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/msgtext.h ../lib/clcomm.h ../lib/msg.h mail.h funcs.h input.h language.h misc.h timeout.h oneline.h exitinfo.h lineedit.h fsedit.h filesub.h msgutil.h pop3.h email.h whoson.h
|
||||
mbpasswd.o: ../config.h encrypt.h rad64.h myname.h xmalloc.h pwio.h shadowio.h pw_util.h mbpasswd.h
|
||||
mbuseradd.o: ../config.h mbuseradd.h
|
||||
newuser.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/clcomm.h ../lib/common.h funcs.h input.h newuser.h language.h timeout.h change.h dispfile.h
|
||||
pinfo.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/clcomm.h pinfo.h input.h
|
||||
rad64.o: ../config.h rad64.h
|
||||
timecheck.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/clcomm.h ../lib/common.h timecheck.h funcs.h bye.h exitinfo.h language.h input.h
|
||||
change.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/clcomm.h change.h dispfile.h funcs.h input.h language.h misc.h timeout.h exitinfo.h bye.h
|
||||
exitinfo.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/clcomm.h funcs.h input.h language.h oneline.h misc.h bye.h timeout.h timecheck.h exitinfo.h
|
||||
@@ -203,13 +167,10 @@ safe.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/clc
|
||||
timeout.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/clcomm.h ../lib/msg.h timeout.h funcs.h bye.h filesub.h language.h
|
||||
chat.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/clcomm.h chat.h funcs.h input.h language.h misc.h whoson.h
|
||||
file.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/clcomm.h filesub.h file.h funcs.h input.h language.h misc.h timeout.h exitinfo.h whoson.h change.h
|
||||
getdef.o: ../config.h getdef.h
|
||||
mbchat.o: ../lib/libs.h ../lib/structs.h ../lib/common.h ../lib/clcomm.h
|
||||
mbstat.o: ../lib/libs.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/clcomm.h ../lib/dbcfg.h mbstat.h
|
||||
misc.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/clcomm.h ../lib/common.h funcs.h input.h language.h misc.h timeout.h exitinfo.h
|
||||
offline.o: ../lib/libs.h ../lib/structs.h ../lib/mbse.h ../lib/records.h ../lib/bluewave.h ../lib/common.h ../lib/clcomm.h ../lib/msgtext.h ../lib/msg.h mail.h funcs.h input.h language.h file.h filesub.h exitinfo.h timeout.h msgutil.h pop3.h offline.h whoson.h
|
||||
putpwent.o: ../config.h putpwent.h
|
||||
salt.o: ../config.h rad64.h getdef.h
|
||||
user.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/clcomm.h timeout.h user.h dispfile.h funcs.h input.h misc.h bye.h file.h mail.h change.h menu.h exitinfo.h language.h offline.h email.h
|
||||
mbnewusr.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/clcomm.h mbnewusr.h funcs.h input.h language.h misc.h timeout.h newuser.h
|
||||
input.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/clcomm.h ../lib/common.h input.h timeout.h language.h
|
||||
@@ -219,20 +180,4 @@ dispfile.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib
|
||||
userlist.o: ../lib/libs.h ../lib/mbse.h ../lib/structs.h ../lib/records.h ../lib/common.h ../lib/clcomm.h userlist.h language.h input.h timeout.h
|
||||
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 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
|
||||
shell.o: ../config.h mblogin.h basename.h shell.h
|
||||
basename.o: ../config.h mblogin.h basename.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 limits.h
|
||||
setupenv.o: ../config.h mblogin.h getdef.h xmalloc.h env.h setupenv.h
|
||||
sub.o: ../config.h mblogin.h sub.h
|
||||
log.o: ../config.h mblogin.h log.h
|
||||
setugid.o: ../config.h mblogin.h getdef.h setugid.h
|
||||
utent.o: ../config.h mblogin.h
|
||||
# End of generated dependencies
|
||||
|
@@ -1,17 +0,0 @@
|
||||
/*
|
||||
* basename.c - not worth copyrighting :-). Some versions of Linux libc
|
||||
* already have basename(), other versions don't. To avoid confusion,
|
||||
* we will not use the function from libc and use a different name here.
|
||||
* --marekm
|
||||
*/
|
||||
|
||||
#include "../config.h"
|
||||
#include "mblogin.h"
|
||||
#include "basename.h"
|
||||
|
||||
char *Basename(char *str)
|
||||
{
|
||||
char *cp = strrchr(str, '/');
|
||||
|
||||
return cp ? cp+1 : str;
|
||||
}
|
@@ -1,9 +0,0 @@
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef _BASENAME_H
|
||||
#define _BASENAME_H
|
||||
|
||||
|
||||
char *Basename(char *);
|
||||
|
||||
#endif
|
@@ -1,108 +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 <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <syslog.h>
|
||||
#include <stdio.h>
|
||||
#include <grp.h>
|
||||
#include "mblogin.h"
|
||||
#include <pwd.h>
|
||||
#include "getdef.h"
|
||||
#include "chowntty.h"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* is_my_tty -- determine if "tty" is the same as TTY stdin is using
|
||||
*/
|
||||
int is_my_tty(const char *tty)
|
||||
{
|
||||
struct stat by_name, by_fd;
|
||||
|
||||
if (stat (tty, &by_name) || fstat (0, &by_fd))
|
||||
return 0;
|
||||
|
||||
if (by_name.st_rdev != by_fd.st_rdev)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* chown_tty() sets the login tty to be owned by the new user ID
|
||||
* with TTYPERM modes
|
||||
*/
|
||||
void chown_tty(const char *tty, const struct passwd *info)
|
||||
{
|
||||
char buf[200], full_tty[200];
|
||||
gid_t gid;
|
||||
|
||||
gid = info->pw_gid;
|
||||
|
||||
/*
|
||||
* Change the permissions on the TTY to be owned by the user with
|
||||
* the group as determined above.
|
||||
*/
|
||||
|
||||
if (*tty != '/') {
|
||||
snprintf(full_tty, sizeof full_tty, "/dev/%s", tty);
|
||||
tty = full_tty;
|
||||
}
|
||||
|
||||
if (! is_my_tty (tty)) {
|
||||
syslog(LOG_WARNING, "unable to determine TTY name, got %s\n", tty);
|
||||
closelog();
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (chown(tty, info->pw_uid, gid) || chmod(tty, 0600)) {
|
||||
snprintf(buf, sizeof buf, "Unable to change tty %s", tty);
|
||||
syslog(LOG_WARNING, "unable to change tty `%s' for user `%s'\n", tty, info->pw_name);
|
||||
closelog();
|
||||
perror (buf);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
/*
|
||||
* Please don't add code to chown /dev/vcs* to the user logging in -
|
||||
* it's a potential security hole. I wouldn't like the previous user
|
||||
* to hold the file descriptor open and watch my screen. We don't
|
||||
* have the *BSD revoke() system call yet, and vhangup() only works
|
||||
* for tty devices (which vcs* is not). --marekm
|
||||
*/
|
||||
#endif
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef _CHOWNTTY_H
|
||||
#define _CHOWNTTY_H
|
||||
|
||||
|
||||
int is_my_tty(const char *);
|
||||
void chown_tty(const char *, const struct passwd *);
|
||||
|
||||
|
||||
#endif
|
@@ -1,767 +0,0 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* File ..................: mbuseradd/commonio.c
|
||||
* Purpose ...............: MBSE BBS Shadow Password Suite
|
||||
* Last modification date : 09-Aug-2001
|
||||
* 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 <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <utime.h>
|
||||
#include <sys/time.h>
|
||||
#ifdef SHADOW_PASSWORD
|
||||
#include <shadow.h>
|
||||
#endif
|
||||
#include "commonio.h"
|
||||
|
||||
/* local function prototypes */
|
||||
static int check_link_count (const char *);
|
||||
static int do_lock_file (const char *, const char *);
|
||||
static FILE *fopen_set_perms (const char *, const char *, const struct stat *);
|
||||
static int create_backup (const char *, FILE *);
|
||||
static void free_linked_list (struct commonio_db *);
|
||||
static void add_one_entry (struct commonio_db *, struct commonio_entry *);
|
||||
static int name_is_nis (const char *);
|
||||
static int write_all (const struct commonio_db *);
|
||||
static struct commonio_entry *find_entry_by_name (struct commonio_db *, const char *);
|
||||
|
||||
#ifdef HAVE_LCKPWDF
|
||||
static int lock_count = 0;
|
||||
#endif
|
||||
|
||||
static int check_link_count(const char *file)
|
||||
{
|
||||
struct stat sb;
|
||||
|
||||
if (stat(file, &sb) != 0)
|
||||
return 0;
|
||||
|
||||
if (sb.st_nlink != 2)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static int do_lock_file(const char *file, const char *lock)
|
||||
{
|
||||
int fd;
|
||||
int pid;
|
||||
int len;
|
||||
int retval;
|
||||
char buf[32];
|
||||
|
||||
if ((fd = open(file, O_CREAT|O_EXCL|O_WRONLY, 0600)) == -1)
|
||||
return 0;
|
||||
|
||||
pid = getpid();
|
||||
snprintf(buf, sizeof buf, "%d", pid);
|
||||
len = strlen(buf) + 1;
|
||||
if (write (fd, buf, len) != len) {
|
||||
close(fd);
|
||||
unlink(file);
|
||||
return 0;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
if (link(file, lock) == 0) {
|
||||
retval = check_link_count(file);
|
||||
unlink(file);
|
||||
return retval;
|
||||
}
|
||||
|
||||
if ((fd = open(lock, O_RDWR)) == -1) {
|
||||
unlink(file);
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
len = read(fd, buf, sizeof(buf) - 1);
|
||||
close(fd);
|
||||
if (len <= 0) {
|
||||
unlink(file);
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
buf[len] = '\0';
|
||||
if ((pid = strtol(buf, (char **) 0, 10)) == 0) {
|
||||
unlink(file);
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
if (kill(pid, 0) == 0) {
|
||||
unlink(file);
|
||||
errno = EEXIST;
|
||||
return 0;
|
||||
}
|
||||
if (unlink(lock) != 0) {
|
||||
unlink(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
retval = 0;
|
||||
if (link(file, lock) == 0 && check_link_count(file))
|
||||
retval = 1;
|
||||
|
||||
unlink(file);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static FILE *fopen_set_perms(const char *name, const char *mode, const struct stat *sb)
|
||||
{
|
||||
FILE *fp;
|
||||
mode_t mask;
|
||||
|
||||
mask = umask(0777);
|
||||
fp = fopen(name, mode);
|
||||
umask(mask);
|
||||
if (!fp)
|
||||
return NULL;
|
||||
|
||||
#ifdef HAVE_FCHOWN
|
||||
if (fchown(fileno(fp), sb->st_uid, sb->st_gid))
|
||||
goto fail;
|
||||
#else
|
||||
if (chown(name, sb->st_mode))
|
||||
goto fail;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FCHMOD
|
||||
if (fchmod(fileno(fp), sb->st_mode & 0664))
|
||||
goto fail;
|
||||
#else
|
||||
if (chmod(name, sb->st_mode & 0664))
|
||||
goto fail;
|
||||
#endif
|
||||
return fp;
|
||||
|
||||
fail:
|
||||
fclose(fp);
|
||||
unlink(name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int create_backup(const char *backup, FILE *fp)
|
||||
{
|
||||
struct stat sb;
|
||||
struct utimbuf ub;
|
||||
FILE *bkfp;
|
||||
int c;
|
||||
mode_t mask;
|
||||
|
||||
if (fstat(fileno(fp), &sb))
|
||||
return -1;
|
||||
|
||||
mask = umask(077);
|
||||
bkfp = fopen(backup, "w");
|
||||
umask(mask);
|
||||
if (!bkfp)
|
||||
return -1;
|
||||
|
||||
/* TODO: faster copy, not one-char-at-a-time. --marekm */
|
||||
rewind(fp);
|
||||
while ((c = getc(fp)) != EOF) {
|
||||
if (putc(c, bkfp) == EOF)
|
||||
break;
|
||||
}
|
||||
if (c != EOF || fflush(bkfp)) {
|
||||
fclose(bkfp);
|
||||
return -1;
|
||||
}
|
||||
if (fclose(bkfp))
|
||||
return -1;
|
||||
|
||||
ub.actime = sb.st_atime;
|
||||
ub.modtime = sb.st_mtime;
|
||||
utime(backup, &ub);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void free_linked_list(struct commonio_db *db)
|
||||
{
|
||||
struct commonio_entry *p;
|
||||
|
||||
while (db->head) {
|
||||
p = db->head;
|
||||
db->head = p->next;
|
||||
|
||||
if (p->line)
|
||||
free(p->line);
|
||||
|
||||
if (p->entry)
|
||||
db->ops->free(p->entry);
|
||||
|
||||
free(p);
|
||||
}
|
||||
db->tail = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int commonio_setname(struct commonio_db *db, const char *name)
|
||||
{
|
||||
strcpy(db->filename, name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int commonio_present(const struct commonio_db *db)
|
||||
{
|
||||
return (access(db->filename, F_OK) == 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int commonio_lock_nowait(struct commonio_db *db)
|
||||
{
|
||||
char file[1024];
|
||||
char lock[1024];
|
||||
|
||||
if (db->locked)
|
||||
return 1;
|
||||
|
||||
snprintf(file, sizeof file, "%s.%ld", db->filename, (long) getpid());
|
||||
snprintf(lock, sizeof lock, "%s.lock", db->filename);
|
||||
if (do_lock_file(file, lock)) {
|
||||
db->locked = 1;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int commonio_lock(struct commonio_db *db)
|
||||
{
|
||||
int i;
|
||||
|
||||
#ifdef HAVE_LCKPWDF
|
||||
/*
|
||||
* only if the system libc has a real lckpwdf() - the one from
|
||||
* lockpw.c calls us and would cause infinite recursion!
|
||||
*/
|
||||
if (db->use_lckpwdf) {
|
||||
/*
|
||||
* Call lckpwdf() on the first lock.
|
||||
* If it succeeds, call *_lock() only once
|
||||
* (no retries, it should always succeed).
|
||||
*/
|
||||
if (lock_count == 0) {
|
||||
if (lckpwdf() == -1)
|
||||
return 0; /* failure */
|
||||
}
|
||||
if (!commonio_lock_nowait(db)) {
|
||||
ulckpwdf();
|
||||
return 0; /* failure */
|
||||
}
|
||||
lock_count++;
|
||||
return 1; /* success */
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
* lckpwdf() not used - do it the old way.
|
||||
*/
|
||||
#ifndef LOCK_TRIES
|
||||
#define LOCK_TRIES 15
|
||||
#endif
|
||||
|
||||
#ifndef LOCK_SLEEP
|
||||
#define LOCK_SLEEP 1
|
||||
#endif
|
||||
for (i = 0; i < LOCK_TRIES; i++) {
|
||||
if (i > 0)
|
||||
sleep(LOCK_SLEEP); /* delay between retries */
|
||||
if (commonio_lock_nowait(db))
|
||||
return 1; /* success */
|
||||
/* no unnecessary retries on "permission denied" errors */
|
||||
if (geteuid() != 0)
|
||||
return 0;
|
||||
}
|
||||
return 0; /* failure */
|
||||
}
|
||||
|
||||
|
||||
|
||||
int commonio_unlock(struct commonio_db *db)
|
||||
{
|
||||
char lock[1024];
|
||||
|
||||
if (db->isopen) {
|
||||
db->readonly = 1;
|
||||
if (!commonio_close(db))
|
||||
return 0;
|
||||
}
|
||||
if (db->locked) {
|
||||
/*
|
||||
* Unlock in reverse order: remove the lock file,
|
||||
* then call ulckpwdf() (if used) on last unlock.
|
||||
*/
|
||||
db->locked = 0;
|
||||
snprintf(lock, sizeof lock, "%s.lock", db->filename);
|
||||
unlink(lock);
|
||||
#ifdef HAVE_LCKPWDF
|
||||
if (db->use_lckpwdf && lock_count > 0) {
|
||||
lock_count--;
|
||||
if (lock_count == 0)
|
||||
ulckpwdf();
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void add_one_entry(struct commonio_db *db, struct commonio_entry *p)
|
||||
{
|
||||
p->next = NULL;
|
||||
p->prev = db->tail;
|
||||
if (!db->head)
|
||||
db->head = p;
|
||||
if (db->tail)
|
||||
db->tail->next = p;
|
||||
db->tail = p;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int name_is_nis(const char *n)
|
||||
{
|
||||
return (n[0] == '+' || n[0] == '-');
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* New entries are inserted before the first NIS entry. Order is preserved
|
||||
* when db is written out.
|
||||
*/
|
||||
#ifndef KEEP_NIS_AT_END
|
||||
#define KEEP_NIS_AT_END 1
|
||||
#endif
|
||||
|
||||
#if KEEP_NIS_AT_END
|
||||
/* prototype */
|
||||
static void add_one_entry_nis (struct commonio_db *, struct commonio_entry *);
|
||||
|
||||
static void add_one_entry_nis(struct commonio_db *db, struct commonio_entry *new)
|
||||
{
|
||||
struct commonio_entry *p;
|
||||
|
||||
for (p = db->head; p; p = p->next) {
|
||||
if (name_is_nis(p->entry ? db->ops->getname(p->entry) : p->line)) {
|
||||
new->next = p;
|
||||
new->prev = p->prev;
|
||||
if (p->prev)
|
||||
p->prev->next = new;
|
||||
else
|
||||
db->head = new;
|
||||
p->prev = new;
|
||||
return;
|
||||
}
|
||||
}
|
||||
add_one_entry(db, new);
|
||||
}
|
||||
#endif /* KEEP_NIS_AT_END */
|
||||
|
||||
|
||||
|
||||
int commonio_open(struct commonio_db *db, int mode)
|
||||
{
|
||||
char buf[8192];
|
||||
char *cp;
|
||||
char *line;
|
||||
struct commonio_entry *p;
|
||||
void *entry;
|
||||
int flags = mode;
|
||||
|
||||
mode &= ~O_CREAT;
|
||||
|
||||
if (db->isopen || (mode != O_RDONLY && mode != O_RDWR)) {
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
db->readonly = (mode == O_RDONLY);
|
||||
if (!db->readonly && !db->locked) {
|
||||
errno = EACCES;
|
||||
return 0;
|
||||
}
|
||||
|
||||
db->head = db->tail = db->cursor = NULL;
|
||||
db->changed = 0;
|
||||
|
||||
db->fp = fopen(db->filename, db->readonly ? "r" : "r+");
|
||||
|
||||
/*
|
||||
* If O_CREAT was specified and the file didn't exist, it will be
|
||||
* created by commonio_close(). We have no entries to read yet. --marekm
|
||||
*/
|
||||
if (!db->fp) {
|
||||
if ((flags & O_CREAT) && errno == ENOENT) {
|
||||
db->isopen++;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (db->ops->fgets(buf, sizeof buf, db->fp)) {
|
||||
if ((cp = strrchr(buf, '\n')))
|
||||
*cp = '\0';
|
||||
|
||||
if (!(line = strdup(buf)))
|
||||
goto cleanup;
|
||||
|
||||
if (name_is_nis(line)) {
|
||||
entry = NULL;
|
||||
} else if ((entry = db->ops->parse(line))) {
|
||||
entry = db->ops->dup(entry);
|
||||
if (!entry)
|
||||
goto cleanup_line;
|
||||
}
|
||||
|
||||
p = (struct commonio_entry *) malloc(sizeof *p);
|
||||
if (!p)
|
||||
goto cleanup_entry;
|
||||
|
||||
p->entry = entry;
|
||||
p->line = line;
|
||||
p->changed = 0;
|
||||
|
||||
add_one_entry(db, p);
|
||||
}
|
||||
|
||||
db->isopen++;
|
||||
return 1;
|
||||
|
||||
cleanup_entry:
|
||||
if (entry)
|
||||
db->ops->free(entry);
|
||||
cleanup_line:
|
||||
free(line);
|
||||
cleanup:
|
||||
free_linked_list(db);
|
||||
fclose(db->fp);
|
||||
db->fp = NULL;
|
||||
errno = ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int write_all(const struct commonio_db *db)
|
||||
{
|
||||
const struct commonio_entry *p;
|
||||
void *entry;
|
||||
|
||||
for (p = db->head; p; p = p->next) {
|
||||
if (p->changed) {
|
||||
entry = p->entry;
|
||||
if (db->ops->put(entry, db->fp))
|
||||
return -1;
|
||||
} else if (p->line) {
|
||||
if (db->ops->fputs(p->line, db->fp) == EOF)
|
||||
return -1;
|
||||
if (putc('\n', db->fp) == EOF)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int commonio_close(struct commonio_db *db)
|
||||
{
|
||||
char buf[1024];
|
||||
int errors = 0;
|
||||
struct stat sb;
|
||||
|
||||
if (!db->isopen) {
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
db->isopen = 0;
|
||||
|
||||
if (!db->changed || db->readonly) {
|
||||
fclose(db->fp);
|
||||
db->fp = NULL;
|
||||
goto success;
|
||||
}
|
||||
|
||||
memset(&sb, 0, sizeof sb);
|
||||
if (db->fp) {
|
||||
if (fstat(fileno(db->fp), &sb)) {
|
||||
fclose(db->fp);
|
||||
db->fp = NULL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create backup file.
|
||||
*/
|
||||
snprintf(buf, sizeof buf, "%s-", db->filename);
|
||||
|
||||
if (create_backup(buf, db->fp))
|
||||
errors++;
|
||||
|
||||
if (fclose(db->fp))
|
||||
errors++;
|
||||
|
||||
if (errors) {
|
||||
db->fp = NULL;
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Default permissions for new [g]shadow files.
|
||||
* (passwd and group always exist...)
|
||||
*/
|
||||
sb.st_mode = 0400;
|
||||
sb.st_uid = 0;
|
||||
sb.st_gid = 0;
|
||||
}
|
||||
|
||||
snprintf(buf, sizeof buf, "%s+", db->filename);
|
||||
|
||||
db->fp = fopen_set_perms(buf, "w", &sb);
|
||||
if (!db->fp)
|
||||
goto fail;
|
||||
|
||||
if (write_all(db))
|
||||
errors++;
|
||||
|
||||
if (fflush(db->fp))
|
||||
errors++;
|
||||
#ifdef HAVE_FSYNC
|
||||
if (fsync(fileno(db->fp)))
|
||||
errors++;
|
||||
#else
|
||||
sync();
|
||||
#endif
|
||||
if (fclose(db->fp))
|
||||
errors++;
|
||||
|
||||
db->fp = NULL;
|
||||
|
||||
if (errors) {
|
||||
unlink(buf);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (rename(buf, db->filename))
|
||||
goto fail;
|
||||
|
||||
success:
|
||||
free_linked_list(db);
|
||||
return 1;
|
||||
|
||||
fail:
|
||||
free_linked_list(db);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static struct commonio_entry * find_entry_by_name(struct commonio_db *db, const char *name)
|
||||
{
|
||||
struct commonio_entry *p;
|
||||
void *ep;
|
||||
|
||||
for (p = db->head; p; p = p->next) {
|
||||
ep = p->entry;
|
||||
if (ep && strcmp(db->ops->getname(ep), name) == 0)
|
||||
break;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int commonio_update(struct commonio_db *db, const void *entry)
|
||||
{
|
||||
struct commonio_entry *p;
|
||||
void *nentry;
|
||||
|
||||
if (!db->isopen || db->readonly) {
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
if (!(nentry = db->ops->dup(entry))) {
|
||||
errno = ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
p = find_entry_by_name(db, db->ops->getname(entry));
|
||||
if (p) {
|
||||
db->ops->free(p->entry);
|
||||
p->entry = nentry;
|
||||
p->changed = 1;
|
||||
db->cursor = p;
|
||||
|
||||
db->changed = 1;
|
||||
return 1;
|
||||
}
|
||||
/* not found, new entry */
|
||||
p = (struct commonio_entry *) malloc(sizeof *p);
|
||||
if (!p) {
|
||||
db->ops->free(nentry);
|
||||
errno = ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
|
||||
p->entry = nentry;
|
||||
p->line = NULL;
|
||||
p->changed = 1;
|
||||
|
||||
#if KEEP_NIS_AT_END
|
||||
add_one_entry_nis(db, p);
|
||||
#else
|
||||
add_one_entry(db, p);
|
||||
#endif
|
||||
|
||||
db->changed = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void commonio_del_entry(struct commonio_db *db, const struct commonio_entry *p)
|
||||
{
|
||||
if (p == db->cursor)
|
||||
db->cursor = p->next;
|
||||
|
||||
if (p->prev)
|
||||
p->prev->next = p->next;
|
||||
else
|
||||
db->head = p->next;
|
||||
|
||||
if (p->next)
|
||||
p->next->prev = p->prev;
|
||||
else
|
||||
db->tail = p->prev;
|
||||
|
||||
db->changed = 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int commonio_remove(struct commonio_db *db, const char *name)
|
||||
{
|
||||
struct commonio_entry *p;
|
||||
|
||||
if (!db->isopen || db->readonly) {
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
p = find_entry_by_name(db, name);
|
||||
if (!p) {
|
||||
errno = ENOENT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
commonio_del_entry(db, p);
|
||||
|
||||
if (p->line)
|
||||
free(p->line);
|
||||
|
||||
if (p->entry)
|
||||
db->ops->free(p->entry);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const void * commonio_locate(struct commonio_db *db, const char *name)
|
||||
{
|
||||
struct commonio_entry *p;
|
||||
|
||||
if (!db->isopen) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
p = find_entry_by_name(db, name);
|
||||
if (!p) {
|
||||
errno = ENOENT;
|
||||
return NULL;
|
||||
}
|
||||
db->cursor = p;
|
||||
return p->entry;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int commonio_rewind(struct commonio_db *db)
|
||||
{
|
||||
if (!db->isopen) {
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
db->cursor = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const void * commonio_next(struct commonio_db *db)
|
||||
{
|
||||
void *entry;
|
||||
|
||||
if (!db->isopen) {
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
if (db->cursor == NULL)
|
||||
db->cursor = db->head;
|
||||
else
|
||||
db->cursor = db->cursor->next;
|
||||
|
||||
while (db->cursor) {
|
||||
entry = db->cursor->entry;
|
||||
if (entry)
|
||||
return entry;
|
||||
|
||||
db->cursor = db->cursor->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
@@ -1,112 +0,0 @@
|
||||
#ifndef _COMMONIO_H
|
||||
#define _COMMONIO_H
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Linked list entry.
|
||||
*/
|
||||
struct commonio_entry {
|
||||
char *line;
|
||||
void *entry; /* struct passwd, struct spwd, ... */
|
||||
struct commonio_entry *prev, *next;
|
||||
int changed:1;
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Operations depending on database type: passwd, group, shadow etc.
|
||||
*/
|
||||
struct commonio_ops {
|
||||
/*
|
||||
* Make a copy of the object (for example, struct passwd)
|
||||
* and all strings pointed by it, in malloced memory.
|
||||
*/
|
||||
void * (*dup) (const void *);
|
||||
|
||||
/*
|
||||
* free() the object including any strings pointed by it.
|
||||
*/
|
||||
void (*free) (void *);
|
||||
|
||||
/*
|
||||
* Return the name of the object (for example, pw_name
|
||||
* for struct passwd).
|
||||
*/
|
||||
const char * (*getname) (const void *);
|
||||
|
||||
/*
|
||||
* Parse a string, return object (in static area -
|
||||
* should be copied using the dup operation above).
|
||||
*/
|
||||
void * (*parse) (const char *);
|
||||
|
||||
/*
|
||||
* Write the object to the file (this calls putpwent()
|
||||
* for struct passwd, for example).
|
||||
*/
|
||||
int (*put) (const void *, FILE *);
|
||||
|
||||
/*
|
||||
* fgets and fputs (can be replaced by versions that
|
||||
* understand line continuation conventions).
|
||||
*/
|
||||
char * (*fgets) (char *, int, FILE *);
|
||||
int (*fputs) (const char *, FILE *);
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Database structure.
|
||||
*/
|
||||
struct commonio_db {
|
||||
/*
|
||||
* Name of the data file.
|
||||
*/
|
||||
char filename[1024];
|
||||
|
||||
/*
|
||||
* Operations from above.
|
||||
*/
|
||||
struct commonio_ops *ops;
|
||||
|
||||
/*
|
||||
* Currently open file stream.
|
||||
*/
|
||||
FILE *fp;
|
||||
|
||||
/*
|
||||
* Head, tail, current position in linked list.
|
||||
*/
|
||||
struct commonio_entry *head, *tail, *cursor;
|
||||
|
||||
/*
|
||||
* Various flags.
|
||||
*/
|
||||
int changed:1;
|
||||
int isopen:1;
|
||||
int locked:1;
|
||||
int readonly:1;
|
||||
int use_lckpwdf:1;
|
||||
};
|
||||
|
||||
|
||||
|
||||
int commonio_setname (struct commonio_db *, const char *);
|
||||
int commonio_present (const struct commonio_db *);
|
||||
int commonio_lock (struct commonio_db *);
|
||||
int commonio_lock_nowait (struct commonio_db *);
|
||||
int commonio_open (struct commonio_db *, int);
|
||||
const void *commonio_locate (struct commonio_db *, const char *);
|
||||
int commonio_update (struct commonio_db *, const void *);
|
||||
int commonio_remove (struct commonio_db *, const char *);
|
||||
int commonio_rewind (struct commonio_db *);
|
||||
const void *commonio_next (struct commonio_db *);
|
||||
int commonio_close (struct commonio_db *);
|
||||
int commonio_unlock (struct commonio_db *);
|
||||
void commonio_del_entry (struct commonio_db *, const struct commonio_entry *);
|
||||
|
||||
#endif
|
||||
|
@@ -1,159 +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.
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright 1990 - 1993, Julianne Frances Haugh
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "../config.h"
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#ifdef _XOPEN_CRYPT
|
||||
#include <crypt.h>
|
||||
#endif
|
||||
#include "encrypt.h"
|
||||
|
||||
#ifdef MD5_CRYPT
|
||||
extern char *md5_crypt();
|
||||
#endif
|
||||
|
||||
|
||||
char *pw_encrypt(const char *clear, const char *salt)
|
||||
{
|
||||
static char cipher[128];
|
||||
char *cp;
|
||||
#ifdef SW_CRYPT
|
||||
static int count;
|
||||
#endif
|
||||
|
||||
#ifdef MD5_CRYPT
|
||||
/*
|
||||
* If the salt string from the password file or from crypt_make_salt()
|
||||
* begins with the magic string, use the new algorithm.
|
||||
*/
|
||||
if (strncmp(salt, "$1$", 3) == 0)
|
||||
return md5_crypt(clear, salt);
|
||||
#endif
|
||||
|
||||
#ifdef SW_CRYPT
|
||||
/*
|
||||
* Copy over the salt. It is always the first two
|
||||
* characters of the string.
|
||||
*/
|
||||
|
||||
cipher[0] = salt[0];
|
||||
cipher[1] = salt[1];
|
||||
cipher[2] = '\0';
|
||||
|
||||
/*
|
||||
* Loop up to ten times on the cleartext password.
|
||||
* This is because the input limit for passwords is
|
||||
* 80 characters.
|
||||
*
|
||||
* The initial salt is that provided by the user, or the
|
||||
* one generated above. The subsequent salts are gotten
|
||||
* from the first two characters of the previous encrypted
|
||||
* block of characters.
|
||||
*/
|
||||
|
||||
for (count = 0;count < 10;count++) {
|
||||
cp = crypt (clear, salt);
|
||||
if (!cp) {
|
||||
perror("crypt");
|
||||
exit(1);
|
||||
}
|
||||
if (strlen(cp) != 13)
|
||||
return cp;
|
||||
strcat (cipher, cp + 2);
|
||||
salt = cipher + 11 * count + 2;
|
||||
|
||||
if (strlen (clear) > 8)
|
||||
clear += 8;
|
||||
else
|
||||
break;
|
||||
}
|
||||
#else
|
||||
cp = crypt (clear, salt);
|
||||
if (!cp) {
|
||||
/*
|
||||
* Single Unix Spec: crypt() may return a null pointer,
|
||||
* and set errno to indicate an error. The caller doesn't
|
||||
* expect us to return NULL, so...
|
||||
*/
|
||||
perror("crypt");
|
||||
exit(1);
|
||||
}
|
||||
if (strlen(cp) != 13)
|
||||
return cp; /* nonstandard crypt() in libc, better bail out */
|
||||
strcpy (cipher, cp);
|
||||
|
||||
#ifdef DOUBLESIZE
|
||||
if (strlen (clear) > 8) {
|
||||
cp = crypt (clear + 8, salt);
|
||||
if (!cp) {
|
||||
perror("crypt");
|
||||
exit(1);
|
||||
}
|
||||
strcat (cipher, cp + 2);
|
||||
}
|
||||
#endif /* DOUBLESIZE */
|
||||
#endif /* SW_CRYPT */
|
||||
return cipher;
|
||||
}
|
||||
|
||||
|
@@ -1,9 +0,0 @@
|
||||
#ifndef _ENCRYPT_H
|
||||
#define _ENCRYPT_H
|
||||
|
||||
|
||||
char *pw_encrypt(const char *, const char *);
|
||||
|
||||
|
||||
#endif
|
||||
|
253
mbsebbs/env.c
253
mbsebbs/env.c
@@ -1,253 +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 <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "mblogin.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
|
||||
/*
|
||||
* NEWENVP_STEP must be a power of two. This is the number
|
||||
* of (char *) pointers to allocate at a time, to avoid using
|
||||
* realloc() too often.
|
||||
*/
|
||||
#define NEWENVP_STEP 16
|
||||
|
||||
size_t newenvc = 0;
|
||||
char **newenvp = NULL;
|
||||
extern char **environ;
|
||||
|
||||
|
||||
static const char *forbid[] = {
|
||||
"_RLD_=",
|
||||
"BASH_ENV=", /* GNU creeping featurism strikes again... */
|
||||
"ENV=",
|
||||
"HOME=",
|
||||
"IFS=",
|
||||
"KRB_CONF=",
|
||||
"LD_", /* anything with the LD_ prefix */
|
||||
"LIBPATH=",
|
||||
"MAIL=",
|
||||
"NLSPATH=",
|
||||
"PATH=",
|
||||
"SHELL=",
|
||||
"SHLIB_PATH=",
|
||||
(char *) 0
|
||||
};
|
||||
|
||||
|
||||
|
||||
/* these are allowed, but with no slashes inside
|
||||
(to work around security problems in GNU gettext) */
|
||||
static const char *noslash[] = {
|
||||
"LANG=",
|
||||
"LANGUAGE=",
|
||||
"LC_", /* anything with the LC_ prefix */
|
||||
(char *) 0
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* initenv() must be called once before using addenv().
|
||||
*/
|
||||
void initenv(void)
|
||||
{
|
||||
newenvp = (char **)xmalloc(NEWENVP_STEP * sizeof(char *));
|
||||
*newenvp = NULL;
|
||||
}
|
||||
|
||||
|
||||
void addenv(const char *string, const char *value)
|
||||
{
|
||||
char *cp, *newstring;
|
||||
size_t i;
|
||||
size_t n;
|
||||
|
||||
if (value) {
|
||||
newstring = xmalloc(strlen(string) + strlen(value) + 2);
|
||||
sprintf(newstring, "%s=%s", string, value);
|
||||
} else {
|
||||
newstring = xstrdup(string);
|
||||
}
|
||||
|
||||
/*
|
||||
* Search for a '=' character within the string and if none is found
|
||||
* just ignore the whole string.
|
||||
*/
|
||||
|
||||
cp = strchr(newstring, '=');
|
||||
if (!cp) {
|
||||
free(newstring);
|
||||
return;
|
||||
}
|
||||
|
||||
n = (size_t)(cp - newstring);
|
||||
|
||||
for (i = 0; i < newenvc; i++) {
|
||||
if (strncmp(newstring, newenvp[i], n) == 0 &&
|
||||
(newenvp[i][n] == '=' || newenvp[i][n] == '\0'))
|
||||
break;
|
||||
}
|
||||
|
||||
if (i < newenvc) {
|
||||
free(newenvp[i]);
|
||||
newenvp[i] = newstring;
|
||||
return;
|
||||
}
|
||||
|
||||
newenvp[newenvc++] = newstring;
|
||||
|
||||
/*
|
||||
* Check whether newenvc is a multiple of NEWENVP_STEP.
|
||||
* If so we have to resize the vector.
|
||||
* the expression (newenvc & (NEWENVP_STEP - 1)) == 0
|
||||
* is equal to (newenvc % NEWENVP_STEP) == 0
|
||||
* as long as NEWENVP_STEP is a power of 2.
|
||||
*/
|
||||
|
||||
if ((newenvc & (NEWENVP_STEP - 1)) == 0) {
|
||||
char **__newenvp;
|
||||
size_t newsize;
|
||||
|
||||
/*
|
||||
* If the resize operation succeds we can
|
||||
* happily go on, else print a message.
|
||||
*/
|
||||
|
||||
newsize = (newenvc + NEWENVP_STEP) * sizeof(char *);
|
||||
__newenvp = (char **)realloc(newenvp, newsize);
|
||||
|
||||
if (__newenvp) {
|
||||
/*
|
||||
* If this is our current environment, update
|
||||
* environ so that it doesn't point to some
|
||||
* free memory area (realloc() could move it).
|
||||
*/
|
||||
if (environ == newenvp)
|
||||
environ = __newenvp;
|
||||
newenvp = __newenvp;
|
||||
} else {
|
||||
fprintf(stderr, "Environment overflow\n");
|
||||
free(newenvp[--newenvc]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The last entry of newenvp must be NULL
|
||||
*/
|
||||
|
||||
newenvp[newenvc] = NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* set_env - copy command line arguments into the environment
|
||||
*/
|
||||
void set_env(int argc, char * const *argv)
|
||||
{
|
||||
int noname = 1;
|
||||
char variable[1024];
|
||||
char *cp;
|
||||
|
||||
for ( ; argc > 0; argc--, argv++) {
|
||||
if (strlen(*argv) >= sizeof variable)
|
||||
continue; /* ignore long entries */
|
||||
|
||||
if (! (cp = strchr (*argv, '='))) {
|
||||
snprintf(variable, sizeof variable, "L%d", noname++);
|
||||
addenv(variable, *argv);
|
||||
} else {
|
||||
const char **p;
|
||||
|
||||
for (p = forbid; *p; p++)
|
||||
if (strncmp(*argv, *p, strlen(*p)) == 0)
|
||||
break;
|
||||
|
||||
if (*p) {
|
||||
strncpy(variable, *argv, cp - *argv);
|
||||
variable[cp - *argv] = '\0';
|
||||
printf("You may not change $%s\n", variable);
|
||||
continue;
|
||||
}
|
||||
|
||||
addenv(*argv, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* sanitize_env - remove some nasty environment variables
|
||||
* If you fall into a total paranoia, you should call this
|
||||
* function for any root-setuid program or anything the user
|
||||
* might change the environment with. 99% useless as almost
|
||||
* all modern Unixes will handle setuid executables properly,
|
||||
* but... I feel better with that silly precaution. -j.
|
||||
*/
|
||||
|
||||
void sanitize_env(void)
|
||||
{
|
||||
char **envp = environ;
|
||||
const char **bad;
|
||||
char **cur;
|
||||
char **move;
|
||||
|
||||
for (cur = envp; *cur; cur++) {
|
||||
for (bad = forbid; *bad; bad++) {
|
||||
if (strncmp(*cur, *bad, strlen(*bad)) == 0) {
|
||||
for (move = cur; *move; move++)
|
||||
*move = *(move + 1);
|
||||
cur--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (cur = envp; *cur; cur++) {
|
||||
for (bad = noslash; *bad; bad++) {
|
||||
if (strncmp(*cur, *bad, strlen(*bad)) != 0)
|
||||
continue;
|
||||
if (!strchr(*cur, '/'))
|
||||
continue; /* OK */
|
||||
for (move = cur; *move; move++)
|
||||
*move = *(move + 1);
|
||||
cur--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,12 +0,0 @@
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef _ENV_H
|
||||
#define _ENV_H
|
||||
|
||||
void initenv(void);
|
||||
void addenv(const char *, const char *);
|
||||
void set_env(int, char * const *);
|
||||
void sanitize_env(void);
|
||||
|
||||
#endif
|
||||
|
404
mbsebbs/getdef.c
404
mbsebbs/getdef.c
@@ -1,404 +0,0 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* $Id$
|
||||
* Purpose ...............: MBSE BBS Shadow Password Suite
|
||||
* Original Source .......: Shadow Password Suite
|
||||
* Original Copyright ....: Julianne Frances Haugh and others.
|
||||
*
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1997-2002
|
||||
*
|
||||
* 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.
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright 1991 - 1994, Julianne Frances Haugh and Chip Rosenthal
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "../config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include "getdef.h"
|
||||
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
|
||||
/*
|
||||
* A configuration item definition.
|
||||
*/
|
||||
|
||||
struct itemdef {
|
||||
const char *name; /* name of the item */
|
||||
char *value; /* value given, or NULL if no value */
|
||||
};
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* This list *must* be sorted by the "name" member.
|
||||
* It doesn't hurt that there are extra entries here
|
||||
* that are not known by the system this is running
|
||||
* on. Missing entries here gives a nasty message to
|
||||
* new bbs users.
|
||||
*/
|
||||
|
||||
#define NUMDEFS (sizeof(def_table)/sizeof(def_table[0]))
|
||||
static struct itemdef def_table[] = {
|
||||
{ "CHFN_AUTH", NULL },
|
||||
{ "CHFN_RESTRICT", NULL },
|
||||
{ "CLOSE_SESSIONS", NULL },
|
||||
{ "CONSOLE", NULL },
|
||||
{ "CONSOLE_GROUPS", NULL },
|
||||
{ "CRACKLIB_DICTPATH", NULL },
|
||||
{ "CREATE_HOME", NULL },
|
||||
{ "DEFAULT_HOME", NULL },
|
||||
{ "DIALUPS_CHECK_ENAB", NULL },
|
||||
{ "ENVIRON_FILE", NULL },
|
||||
{ "ENV_HZ", NULL },
|
||||
{ "ENV_PATH" , NULL },
|
||||
{ "ENV_ROOTPATH", NULL },
|
||||
{ "ENV_SUPATH", NULL },
|
||||
{ "ENV_TZ", NULL },
|
||||
{ "ERASECHAR", NULL },
|
||||
{ "FAILLOG_ENAB", NULL },
|
||||
{ "FAIL_DELAY", NULL },
|
||||
{ "FAKE_SHELL", NULL },
|
||||
{ "FTMP_FILE", NULL },
|
||||
{ "GID_MAX", NULL },
|
||||
{ "GID_MIN", NULL },
|
||||
{ "HUSHLOGIN_FILE", NULL },
|
||||
{ "ISSUE_FILE", NULL },
|
||||
{ "KILLCHAR", NULL },
|
||||
{ "LASTLOG_ENAB", NULL },
|
||||
{ "LOGIN_RETRIES", NULL },
|
||||
{ "LOGIN_STRING", NULL },
|
||||
{ "LOGIN_TIMEOUT", NULL },
|
||||
{ "LOG_OK_LOGINS", NULL },
|
||||
{ "LOG_UNKFAIL_ENAB", NULL },
|
||||
{ "MAIL_CHECK_ENAB", NULL },
|
||||
{ "MAIL_DIR", NULL },
|
||||
{ "MAIL_FILE", NULL },
|
||||
{ "MD5_CRYPT_ENAB", NULL },
|
||||
{ "MOTD_FILE", NULL },
|
||||
{ "NOLOGINS_FILE", NULL },
|
||||
{ "NOLOGIN_STR", NULL },
|
||||
{ "NO_PASSWORD_CONSOLE", NULL },
|
||||
{ "OBSCURE_CHECKS_ENAB", NULL },
|
||||
{ "PASS_ALWAYS_WARN", NULL },
|
||||
{ "PASS_CHANGE_TRIES", NULL },
|
||||
{ "PASS_MAX_DAYS", NULL },
|
||||
{ "PASS_MAX_LEN", NULL },
|
||||
{ "PASS_MIN_DAYS", NULL },
|
||||
{ "PASS_MIN_LEN", NULL },
|
||||
{ "PASS_WARN_AGE", NULL },
|
||||
{ "PORTTIME_CHECKS_ENAB", NULL },
|
||||
{ "QMAIL_DIR", NULL },
|
||||
{ "QUOTAS_ENAB", NULL },
|
||||
{ "SULOG_FILE", NULL },
|
||||
{ "SU_NAME", NULL },
|
||||
{ "SU_WHEEL_ONLY", NULL },
|
||||
{ "SYSLOG_SG_ENAB", NULL },
|
||||
{ "SYSLOG_SU_ENAB", NULL },
|
||||
{ "TTYGROUP", NULL },
|
||||
{ "TTYPERM", NULL },
|
||||
{ "TTYTYPE_FILE", NULL },
|
||||
{ "UID_MAX", NULL },
|
||||
{ "UID_MIN", NULL },
|
||||
{ "ULIMIT", NULL },
|
||||
{ "UMASK", NULL },
|
||||
{ "USERDEL_CMD", NULL },
|
||||
{ "USERGROUPS_ENAB", NULL },
|
||||
};
|
||||
|
||||
#ifndef LOGINDEFS
|
||||
#define LOGINDEFS "/etc/login.defs"
|
||||
#endif
|
||||
|
||||
static char def_fname[] = LOGINDEFS; /* login config defs file */
|
||||
static int def_loaded = 0; /* are defs already loaded? */
|
||||
|
||||
|
||||
/* local function prototypes */
|
||||
static struct itemdef *def_find (const char *);
|
||||
static void def_load (void);
|
||||
|
||||
|
||||
/*
|
||||
* getdef_str - get string value from table of definitions.
|
||||
*
|
||||
* Return point to static data for specified item, or NULL if item is not
|
||||
* defined. First time invoked, will load definitions from the file.
|
||||
*/
|
||||
|
||||
char *getdef_str(const char *item)
|
||||
{
|
||||
struct itemdef *d;
|
||||
|
||||
if (!def_loaded)
|
||||
def_load();
|
||||
|
||||
return ((d = def_find(item)) == NULL ? (char *)NULL : d->value);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* getdef_bool - get boolean value from table of definitions.
|
||||
*
|
||||
* Return TRUE if specified item is defined as "yes", else FALSE.
|
||||
*/
|
||||
|
||||
int getdef_bool(const char *item)
|
||||
{
|
||||
struct itemdef *d;
|
||||
|
||||
if (!def_loaded)
|
||||
def_load();
|
||||
|
||||
if ((d = def_find(item)) == NULL || d->value == NULL)
|
||||
return 0;
|
||||
|
||||
return (strcmp(d->value, "yes") == 0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* getdef_num - get numerical value from table of definitions
|
||||
*
|
||||
* Returns numeric value of specified item, else the "dflt" value if
|
||||
* the item is not defined. Octal (leading "0") and hex (leading "0x")
|
||||
* values are handled.
|
||||
*/
|
||||
|
||||
int getdef_num(const char *item, int dflt)
|
||||
{
|
||||
struct itemdef *d;
|
||||
|
||||
if (!def_loaded)
|
||||
def_load();
|
||||
|
||||
if ((d = def_find(item)) == NULL || d->value == NULL)
|
||||
return dflt;
|
||||
|
||||
return (int) strtol(d->value, (char **)NULL, 0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* getdef_long - get long integer value from table of definitions
|
||||
*
|
||||
* Returns numeric value of specified item, else the "dflt" value if
|
||||
* the item is not defined. Octal (leading "0") and hex (leading "0x")
|
||||
* values are handled.
|
||||
*/
|
||||
|
||||
long getdef_long(const char *item, long dflt)
|
||||
{
|
||||
struct itemdef *d;
|
||||
|
||||
if (!def_loaded)
|
||||
def_load();
|
||||
|
||||
if ((d = def_find(item)) == NULL || d->value == NULL)
|
||||
return dflt;
|
||||
|
||||
return strtol(d->value, (char **)NULL, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* def_find - locate named item in table
|
||||
*
|
||||
* Search through a sorted table of configurable items to locate the
|
||||
* specified configuration option.
|
||||
*/
|
||||
|
||||
static struct itemdef *def_find(const char *name)
|
||||
{
|
||||
int min, max, curr, n;
|
||||
|
||||
/*
|
||||
* Invariant - desired item in range [min:max].
|
||||
*/
|
||||
|
||||
min = 0;
|
||||
max = NUMDEFS-1;
|
||||
|
||||
/*
|
||||
* Binary search into the table. Relies on the items being
|
||||
* sorted by name.
|
||||
*/
|
||||
|
||||
while (min <= max) {
|
||||
curr = (min+max)/2;
|
||||
|
||||
if (! (n = strcmp(def_table[curr].name, name)))
|
||||
return &def_table[curr];
|
||||
|
||||
if (n < 0)
|
||||
min = curr+1;
|
||||
else
|
||||
max = curr-1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Item was never found.
|
||||
*/
|
||||
|
||||
fprintf(stderr, "mbpasswd: configuration error - unknown item '%s' (notify administrator)\r\n", name);
|
||||
syslog(LOG_CRIT, "unknown configuration item `%s'", name);
|
||||
return (struct itemdef *) NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* def_load - load configuration table
|
||||
*
|
||||
* Loads the user-configured options from the default configuration file
|
||||
*/
|
||||
|
||||
static void def_load(void)
|
||||
{
|
||||
int i;
|
||||
FILE *fp;
|
||||
struct itemdef *d;
|
||||
char buf[BUFSIZ], *name, *value, *s;
|
||||
|
||||
/*
|
||||
* Open the configuration definitions file.
|
||||
*/
|
||||
|
||||
if ((fp = fopen(def_fname, "r")) == NULL) {
|
||||
syslog(LOG_CRIT, "cannot open login definitions %s [%m]", def_fname);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Go through all of the lines in the file.
|
||||
*/
|
||||
|
||||
while (fgets(buf, sizeof(buf), fp) != NULL) {
|
||||
|
||||
/*
|
||||
* Trim trailing whitespace.
|
||||
*/
|
||||
|
||||
for (i = strlen(buf)-1 ; i >= 0 ; --i) {
|
||||
if (!isspace(buf[i]))
|
||||
break;
|
||||
}
|
||||
buf[++i] = '\0';
|
||||
|
||||
/*
|
||||
* Break the line into two fields.
|
||||
*/
|
||||
|
||||
name = buf + strspn(buf, " \t"); /* first nonwhite */
|
||||
if (*name == '\0' || *name == '#')
|
||||
continue; /* comment or empty */
|
||||
|
||||
s = name + strcspn(name, " \t"); /* end of field */
|
||||
if (*s == '\0')
|
||||
continue; /* only 1 field?? */
|
||||
|
||||
*s++ = '\0';
|
||||
value = s + strspn(s, " \"\t"); /* next nonwhite */
|
||||
*(value + strcspn(value, "\"")) = '\0';
|
||||
|
||||
/*
|
||||
* Locate the slot to save the value. If this parameter
|
||||
* is unknown then "def_find" will print an err message.
|
||||
*/
|
||||
|
||||
if ((d = def_find(name)) == NULL)
|
||||
continue;
|
||||
|
||||
/*
|
||||
* Save off the value.
|
||||
*/
|
||||
|
||||
if ((d->value = strdup(value)) == NULL) {
|
||||
fprintf(stderr, "mbpasswd: Could not allocate space for config info.\n");
|
||||
syslog(LOG_ERR, "could not allocate space for config info");
|
||||
break;
|
||||
}
|
||||
}
|
||||
(void) fclose(fp);
|
||||
|
||||
/*
|
||||
* Set the initialized flag.
|
||||
*/
|
||||
|
||||
++def_loaded;
|
||||
}
|
||||
|
||||
#ifdef CKDEFS
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
char *cp;
|
||||
struct itemdef *d;
|
||||
|
||||
def_load ();
|
||||
|
||||
for (i = 0 ; i < NUMDEFS ; ++i) {
|
||||
if ((d = def_find(def_table[i].name)) == NULL)
|
||||
printf("error - lookup '%s' failed\n", def_table[i].name);
|
||||
else
|
||||
printf("%4d %-24s %s\n", i+1, d->name, d->value);
|
||||
}
|
||||
for (i = 1;i < argc;i++) {
|
||||
if (cp = getdef_str (argv[1]))
|
||||
printf ("%s `%s'\n", argv[1], cp);
|
||||
else
|
||||
printf ("%s not found\n", argv[1]);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ifndef __FreeBSD__ */
|
@@ -1,15 +0,0 @@
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef _GETDEF_H
|
||||
#define _GETDEF_H
|
||||
|
||||
#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 */
|
@@ -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.
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Separated from setup.c. --marekm
|
||||
* Resource limits thanks to Cristian Gafton.
|
||||
*/
|
||||
|
||||
#include "../config.h"
|
||||
#include "mblogin.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include "limits.h"
|
||||
|
||||
|
||||
|
||||
void setup_limits(const struct passwd *info)
|
||||
{
|
||||
const struct group *grp;
|
||||
mode_t oldmask;
|
||||
|
||||
/*
|
||||
* if not root, and uid == gid, and username is the same as primary
|
||||
* group name, set umask group bits to be the same as owner bits
|
||||
* (examples: 022 -> 002, 077 -> 007).
|
||||
*/
|
||||
if (info->pw_uid != 0 && info->pw_uid == info->pw_gid) {
|
||||
grp = getgrgid(info->pw_gid);
|
||||
if (grp && (strcmp(info->pw_name, grp->gr_name) == 0)) {
|
||||
oldmask = umask(0777);
|
||||
umask((oldmask & ~070) | ((oldmask >> 3) & 070));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,9 +0,0 @@
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef _LIMITS_H_
|
||||
#define _LIMITS_H_
|
||||
|
||||
|
||||
void setup_limits(const struct passwd *);
|
||||
|
||||
#endif
|
@@ -1,97 +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 <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <pwd.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include "mblogin.h"
|
||||
#include <utmp.h>
|
||||
#include "log.h"
|
||||
|
||||
|
||||
/*
|
||||
* dolastlog - create lastlog entry
|
||||
*
|
||||
* A "last login" entry is created for the user being logged in. The
|
||||
* UID is extracted from the global (struct passwd) entry and the
|
||||
* TTY information is gotten from the (struct utmp).
|
||||
*/
|
||||
|
||||
void dolastlog(struct lastlog *ll, const struct passwd *pw, const char *line, const char *host)
|
||||
{
|
||||
int fd;
|
||||
off_t offset;
|
||||
struct lastlog newlog;
|
||||
|
||||
/*
|
||||
* If the file does not exist, don't create it.
|
||||
*/
|
||||
|
||||
if ((fd = open(LASTLOG_FILE, O_RDWR)) == -1)
|
||||
return;
|
||||
|
||||
/*
|
||||
* The file is indexed by UID number. Seek to the record
|
||||
* for this UID. Negative UID's will create problems, but ...
|
||||
*/
|
||||
|
||||
offset = (unsigned long) pw->pw_uid * sizeof newlog;
|
||||
|
||||
if (lseek(fd, offset, SEEK_SET) != offset) {
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the old entry so we can tell the user when they last
|
||||
* logged in. Then construct the new entry and write it out
|
||||
* the way we read the old one in.
|
||||
*/
|
||||
|
||||
if (read(fd, (char *) &newlog, sizeof newlog) != sizeof newlog)
|
||||
memzero(&newlog, sizeof newlog);
|
||||
if (ll)
|
||||
*ll = newlog;
|
||||
|
||||
time(&newlog.ll_time);
|
||||
strncpy(newlog.ll_line, line, sizeof newlog.ll_line);
|
||||
#ifdef HAVE_LL_HOST
|
||||
strncpy(newlog.ll_host, host, sizeof newlog.ll_host);
|
||||
#endif
|
||||
if (lseek(fd, offset, SEEK_SET) == offset)
|
||||
write(fd, (char *) &newlog, sizeof newlog);
|
||||
close(fd);
|
||||
}
|
||||
|
@@ -1,8 +0,0 @@
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef _LOG_LOG_H
|
||||
#define _LOG_LOG_H
|
||||
|
||||
void dolastlog(struct lastlog *, const struct passwd *, const char *, const char *);
|
||||
|
||||
#endif
|
@@ -1,169 +0,0 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* $Id$
|
||||
* Purpose ...............: MBSE BBS Shadow Password Suite
|
||||
* Original Source .......: Shadow Password Suite
|
||||
* Original Copyright ....: Julianne Frances Haugh and others.
|
||||
*
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1997-2002
|
||||
*
|
||||
* 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 <signal.h>
|
||||
#include <ctype.h>
|
||||
#include "mblogin.h"
|
||||
#include "getdef.h"
|
||||
#include "xmalloc.h"
|
||||
#include "env.h"
|
||||
#include "loginprompt.h"
|
||||
|
||||
|
||||
void login_exit(int sig)
|
||||
{
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* login_prompt - prompt the user for their login name
|
||||
*
|
||||
* login_prompt() displays the standard login prompt. If ISSUE_FILE
|
||||
* is set in login.defs, this file is displayed before the prompt.
|
||||
*/
|
||||
void login_prompt(const char *prompt, char *name, int namesize)
|
||||
{
|
||||
char buf[1024];
|
||||
#define MAX_ENV 32
|
||||
char *envp[MAX_ENV];
|
||||
int envc;
|
||||
char *cp;
|
||||
int i;
|
||||
FILE *fp;
|
||||
RETSIGTYPE (*sigquit)(int);
|
||||
#ifdef SIGTSTP
|
||||
RETSIGTYPE (*sigtstp)(int);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* There is a small chance that a QUIT character will be part of
|
||||
* some random noise during a prompt. Deal with this by exiting
|
||||
* instead of core dumping. If SIGTSTP is defined, do the same
|
||||
* thing for that signal.
|
||||
*/
|
||||
|
||||
sigquit = signal(SIGQUIT, login_exit);
|
||||
#ifdef SIGTSTP
|
||||
sigtstp = signal(SIGTSTP, login_exit);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* See if the user has configured the issue file to
|
||||
* be displayed and display it before the prompt.
|
||||
*/
|
||||
|
||||
if (prompt) {
|
||||
// cp = getdef_str("ISSUE_FILE");
|
||||
cp = NULL;
|
||||
if (cp && (fp = fopen(cp, "r"))) {
|
||||
while ((i = getc(fp)) != EOF)
|
||||
putc(i, stdout);
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
gethostname(buf, sizeof buf);
|
||||
printf(prompt, buf);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the user's response. The trailing newline will be
|
||||
* removed.
|
||||
*/
|
||||
memzero(buf, sizeof buf);
|
||||
if (fgets(buf, sizeof buf, stdin) != buf)
|
||||
exit(1);
|
||||
|
||||
cp = strchr(buf, '\n');
|
||||
if (!cp)
|
||||
exit(1);
|
||||
*cp = '\0'; /* remove \n [ must be there ] */
|
||||
|
||||
/*
|
||||
* Skip leading whitespace. This makes " username" work right.
|
||||
* Then copy the rest (up to the end or the first "non-graphic"
|
||||
* character into the username.
|
||||
*/
|
||||
|
||||
for (cp = buf;*cp == ' ' || *cp == '\t';cp++)
|
||||
;
|
||||
|
||||
// for (i = 0; i < namesize - 1 && isgraph(*cp); name[i++] = *cp++);
|
||||
/*
|
||||
* Allow double names for Fidonet login style.
|
||||
*/
|
||||
for (i = 0; i < namesize - 1 && isprint(*cp); name[i++] = *cp++);
|
||||
while (isgraph(*cp))
|
||||
cp++;
|
||||
|
||||
if (*cp)
|
||||
cp++;
|
||||
|
||||
name[i] = '\0';
|
||||
|
||||
/*
|
||||
* This is a disaster, at best. The user may have entered extra
|
||||
* environmental variables at the prompt. There are several ways
|
||||
* to do this, and I just take the easy way out.
|
||||
*/
|
||||
|
||||
if (*cp != '\0') { /* process new variables */
|
||||
char *nvar;
|
||||
int count = 1;
|
||||
|
||||
for (envc = 0; envc < MAX_ENV; envc++) {
|
||||
nvar = strtok(envc ? (char *)0 : cp, " \t,");
|
||||
if (!nvar)
|
||||
break;
|
||||
if (strchr(nvar, '=')) {
|
||||
envp[envc] = nvar;
|
||||
} else {
|
||||
envp[envc] = xmalloc(strlen(nvar) + 32);
|
||||
sprintf(envp[envc], "L%d=%s", count++, nvar);
|
||||
}
|
||||
}
|
||||
set_env(envc, envp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the SIGQUIT handler back to its original value
|
||||
*/
|
||||
|
||||
signal(SIGQUIT, sigquit);
|
||||
#ifdef SIGTSTP
|
||||
signal(SIGTSTP, sigtstp);
|
||||
#endif
|
||||
}
|
@@ -1,9 +0,0 @@
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef _LOGINPROMPT_H
|
||||
#define _LOGINPROMPT_H
|
||||
|
||||
void login_exit(int);
|
||||
void login_prompt(const char *, char *, int);
|
||||
|
||||
#endif
|
@@ -1,850 +0,0 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* $Id$
|
||||
* Purpose ...............: Login program for MBSE BBS.
|
||||
* Shadow Suite (c) ......: Julianne Frances Haugh
|
||||
*
|
||||
*****************************************************************************
|
||||
* 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 "mblogin.h"
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <syslog.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#if defined(SHADOW_PASSWORD)
|
||||
#include <shadow.h>
|
||||
#endif
|
||||
#if HAVE_UTMPX_H
|
||||
#include <utmpx.h>
|
||||
#else
|
||||
#include <utmp.h>
|
||||
#endif
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <utmp.h>
|
||||
#include "getdef.h"
|
||||
|
||||
#ifdef SVR4_SI86_EUA
|
||||
#include <sys/proc.h>
|
||||
#include <sys/sysi86.h>
|
||||
#endif
|
||||
|
||||
#ifdef UT_ADDR
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
|
||||
#include "env.h"
|
||||
#include "chowntty.h"
|
||||
#include "basename.h"
|
||||
#include "shell.h"
|
||||
#include "pwdcheck.h"
|
||||
#include "pwauth.h"
|
||||
#include "loginprompt.h"
|
||||
#include "utmp.h"
|
||||
#include "limits.h"
|
||||
#include "setupenv.h"
|
||||
#include "sub.h"
|
||||
#include "log.h"
|
||||
#include "setugid.h"
|
||||
|
||||
|
||||
/*
|
||||
* Login parameters
|
||||
*/
|
||||
#define LOGIN_DELAY 3
|
||||
#define LOGIN_TIMEOUT 300
|
||||
#define LOGIN_RETRIES 10
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Needed for MkLinux DR1/2/2.1 - J.
|
||||
*/
|
||||
#ifndef LASTLOG_FILE
|
||||
#define LASTLOG_FILE "/var/log/lastlog"
|
||||
#endif
|
||||
|
||||
const char *hostname = "";
|
||||
|
||||
struct passwd pwent, *pw;
|
||||
#if HAVE_UTMPX_H
|
||||
struct utmpx utxent, failent;
|
||||
struct utmp utent;
|
||||
#else
|
||||
struct utmp utent, failent;
|
||||
#endif
|
||||
struct lastlog lastlog;
|
||||
static int preauth_flag = 0;
|
||||
|
||||
/*
|
||||
* Global variables.
|
||||
*/
|
||||
|
||||
static int hflg = 0;
|
||||
static int pflg = 0;
|
||||
static char *Prog;
|
||||
static int amroot;
|
||||
static int timeout;
|
||||
|
||||
/*
|
||||
* External identifiers.
|
||||
*/
|
||||
|
||||
extern char **newenvp;
|
||||
extern size_t newenvc;
|
||||
extern int optind;
|
||||
extern char *optarg;
|
||||
extern char **environ;
|
||||
|
||||
|
||||
#ifndef ALARM
|
||||
#define ALARM 60
|
||||
#endif
|
||||
|
||||
#ifndef RETRIES
|
||||
#define RETRIES 3
|
||||
#endif
|
||||
|
||||
|
||||
#define NO_SHADOW "no shadow password for `%s'%s\n"
|
||||
#define BAD_PASSWD "invalid password for `%s'%s\n"
|
||||
#define BAD_DIALUP "invalid dialup password for `%s' on `%s'\n"
|
||||
#define BAD_ROOT_LOGIN "ILLEGAL ROOT LOGIN%s\n"
|
||||
#define BAD_GROUP "user `%s' not in group bbs\n"
|
||||
#define ROOT_LOGIN "ROOT LOGIN%s\n"
|
||||
#define FAILURE_CNT "exceeded failure limit for `%s'%s\n"
|
||||
#define REG_LOGIN "`%s' logged in%s\n"
|
||||
#define LOGIN_REFUSED "LOGIN `%s' REFUSED%s\n"
|
||||
#define REENABLED2 \
|
||||
"login `%s' re-enabled after temporary lockout (%d failures).\n"
|
||||
#define MANY_FAILS "REPEATED login failures%s\n"
|
||||
|
||||
/* local function prototypes */
|
||||
static void usage(void);
|
||||
static void setup_tty(void);
|
||||
static void check_flags(int, char * const *);
|
||||
static void check_nologin(char *);
|
||||
static void init_env(void);
|
||||
static RETSIGTYPE alarm_handler(int);
|
||||
int main(int, char **);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* usage - print login command usage and exit
|
||||
*
|
||||
* login [ name ]
|
||||
* login -r hostname (for rlogind)
|
||||
* login -h hostname (for telnetd, etc.)
|
||||
* login -f name (for pre-authenticated login: datakit, xterm, etc.)
|
||||
*/
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, _("usage: %s [-p] [name]\n"), Prog);
|
||||
if (!amroot)
|
||||
exit(1);
|
||||
fprintf(stderr, _(" %s [-p] [-h host] [-f name]\n"), Prog);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
static void setup_tty(void)
|
||||
{
|
||||
TERMIO termio;
|
||||
|
||||
GTTY(0, &termio); /* get terminal characteristics */
|
||||
|
||||
/*
|
||||
* Add your favorite terminal modes here ...
|
||||
*/
|
||||
termio.c_lflag |= ISIG|ICANON|ECHO|ECHOE;
|
||||
termio.c_iflag |= ICRNL;
|
||||
|
||||
#if defined(ECHOKE) && defined(ECHOCTL)
|
||||
termio.c_lflag |= ECHOKE|ECHOCTL;
|
||||
#endif
|
||||
#if defined(ECHOPRT) && defined(NOFLSH) && defined(TOSTOP)
|
||||
termio.c_lflag &= ~(ECHOPRT|NOFLSH|TOSTOP);
|
||||
#endif
|
||||
#ifdef ONLCR
|
||||
termio.c_oflag |= ONLCR;
|
||||
#endif
|
||||
|
||||
#ifdef SUN4
|
||||
|
||||
/*
|
||||
* Terminal setup for SunOS 4.1 courtesy of Steve Allen
|
||||
* at UCO/Lick.
|
||||
*/
|
||||
|
||||
termio.c_cc[VEOF] = '\04';
|
||||
termio.c_cflag &= ~CSIZE;
|
||||
termio.c_cflag |= (PARENB|CS7);
|
||||
termio.c_lflag |= (ISIG|ICANON|ECHO|IEXTEN);
|
||||
termio.c_iflag |= (BRKINT|IGNPAR|ISTRIP|IMAXBEL|ICRNL|IXON);
|
||||
termio.c_iflag &= ~IXANY;
|
||||
termio.c_oflag |= (XTABS|OPOST|ONLCR);
|
||||
#endif
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
/* leave these values unchanged if not specified in login.defs */
|
||||
termio.c_cc[VERASE] = getdef_num("ERASECHAR", termio.c_cc[VERASE]);
|
||||
termio.c_cc[VKILL] = getdef_num("KILLCHAR", termio.c_cc[VKILL]);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ttymon invocation prefers this, but these settings won't come into
|
||||
* effect after the first username login
|
||||
*/
|
||||
|
||||
STTY(0, &termio);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void check_flags(int argc, char * const *argv)
|
||||
{
|
||||
int arg;
|
||||
|
||||
/*
|
||||
* Check the flags for proper form. Every argument starting with
|
||||
* "-" must be exactly two characters long. This closes all the
|
||||
* clever rlogin, telnet, and getty holes.
|
||||
*/
|
||||
for (arg = 1; arg < argc; arg++) {
|
||||
// printf("%d <%s>\n", arg, argv[arg]);
|
||||
if (argv[arg][0] == '-' && strlen(argv[arg]) > 2)
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* nologin file is $MBSE_ROOT/etc/nologin
|
||||
*/
|
||||
static void check_nologin(char *path)
|
||||
{
|
||||
char *fname;
|
||||
|
||||
/*
|
||||
* Check to see if system is turned off for non-root users.
|
||||
* This would be useful to prevent users from logging in
|
||||
* during system maintenance. We make sure the message comes
|
||||
* out for root so she knows to remove the file if she's
|
||||
* forgotten about it ...
|
||||
*/
|
||||
|
||||
fname = calloc(PATH_MAX, sizeof(char));
|
||||
sprintf(fname, "%s/etc/nologin", path);
|
||||
if (access(fname, F_OK) == 0) {
|
||||
FILE *nlfp;
|
||||
int c;
|
||||
|
||||
/*
|
||||
* Cat the file if it can be opened, otherwise just
|
||||
* print a default message
|
||||
*/
|
||||
|
||||
if ((nlfp = fopen (fname, "r"))) {
|
||||
while ((c = getc (nlfp)) != EOF) {
|
||||
if (c == '\n')
|
||||
putchar ('\r');
|
||||
|
||||
putchar (c);
|
||||
}
|
||||
fflush (stdout);
|
||||
fclose (nlfp);
|
||||
} else
|
||||
printf("\nSystem closed for routine maintenance\n");
|
||||
|
||||
free(fname);
|
||||
closelog();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
free(fname);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void init_env(void)
|
||||
{
|
||||
#ifndef __FreeBSD__
|
||||
char *cp;
|
||||
#endif
|
||||
char *tmp;
|
||||
|
||||
if ((tmp = getenv("LANG"))) {
|
||||
addenv("LANG", tmp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add the timezone environmental variable so that time functions
|
||||
* work correctly.
|
||||
*/
|
||||
|
||||
if ((tmp = getenv("TZ"))) {
|
||||
addenv("TZ", tmp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add the clock frequency so that profiling commands work
|
||||
* correctly.
|
||||
*/
|
||||
|
||||
if ((tmp = getenv("HZ"))) {
|
||||
addenv("HZ", tmp);
|
||||
#ifndef __FreeBSD__
|
||||
} else if ((cp = getdef_str("ENV_HZ")))
|
||||
addenv(cp, NULL);
|
||||
#else
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
static RETSIGTYPE alarm_handler(int sig)
|
||||
{
|
||||
fprintf(stderr, "\nLogin timed out after %d seconds.\n", timeout);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* login - create a new login session for a user
|
||||
*
|
||||
* login is typically called by getty as the second step of a
|
||||
* new user session. getty is responsible for setting the line
|
||||
* characteristics to a reasonable set of values and getting
|
||||
* the name of the user to be logged in. login may also be
|
||||
* called to create a new user session on a pty for a variety
|
||||
* of reasons, such as X servers or network logins.
|
||||
*/
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char username[37];
|
||||
char tty[BUFSIZ];
|
||||
char userfile[PATH_MAX];
|
||||
FILE *ufp;
|
||||
struct userhdr usrconfighdr;
|
||||
struct userrec usrconfig;
|
||||
int reason = PW_LOGIN;
|
||||
int delay;
|
||||
int retries;
|
||||
int failed;
|
||||
int flag;
|
||||
int subroot = 0;
|
||||
int is_console = 0;
|
||||
int FoundName;
|
||||
const char *cp;
|
||||
char *tmp;
|
||||
char fromhost[512];
|
||||
struct passwd *pwd;
|
||||
char **envp = environ;
|
||||
static char temp_pw[2];
|
||||
static char temp_shell[] = "/bin/sh";
|
||||
#ifdef SHADOW_PASSWORD
|
||||
struct spwd *spwd=NULL;
|
||||
#endif
|
||||
#if defined(DES_RPC) || defined(KERBEROS)
|
||||
/* from pwauth.c */
|
||||
extern char *clear_pass;
|
||||
extern int wipe_clear_pass;
|
||||
|
||||
/*
|
||||
* We may need the password later, don't want pw_auth() to wipe it
|
||||
* (we do it ourselves when it is no longer needed). --marekm
|
||||
*/
|
||||
wipe_clear_pass = 0;
|
||||
#endif
|
||||
printf("\nMBSE BBS v%s\n", VERSION);
|
||||
printf("%s\n\n", COPYRIGHT);
|
||||
|
||||
/*
|
||||
* Some quick initialization.
|
||||
*/
|
||||
|
||||
sanitize_env();
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
textdomain(PACKAGE);
|
||||
|
||||
initenv();
|
||||
|
||||
username[0] = '\0';
|
||||
amroot = (getuid() == 0);
|
||||
Prog = Basename(argv[0]);
|
||||
|
||||
check_flags(argc, argv);
|
||||
|
||||
while ((flag = getopt(argc, argv, "d:h:p")) != EOF) {
|
||||
switch (flag) {
|
||||
case 'p':
|
||||
pflg++;
|
||||
break;
|
||||
case 'h':
|
||||
hflg++;
|
||||
hostname = optarg;
|
||||
reason = PW_TELNET;
|
||||
break;
|
||||
case 'd':
|
||||
/* "-d device" ignored for compatibility */
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Allow authentication bypass only if real UID is zero.
|
||||
*/
|
||||
if (hflg && !amroot) {
|
||||
fprintf(stderr, _("%s: permission denied\n"), Prog);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!isatty(0) || !isatty(1) || !isatty(2))
|
||||
exit(1); /* must be a terminal */
|
||||
|
||||
/*
|
||||
* Be picky if run by normal users (possible if installed setuid
|
||||
* root), but not if run by root. This way it still allows logins
|
||||
* even if your getty is broken, or if something corrupts utmp,
|
||||
* but users must "exec login" which will use the existing utmp
|
||||
* entry (will not overwrite remote hostname). --marekm
|
||||
*/
|
||||
checkutmp(!amroot);
|
||||
STRFCPY(tty, utent.ut_line);
|
||||
|
||||
if (hflg) {
|
||||
#ifdef UT_ADDR
|
||||
struct hostent *he;
|
||||
|
||||
/*
|
||||
* Fill in the ut_addr field (remote login IP address).
|
||||
* XXX - login from util-linux does it, but this is not
|
||||
* the right place to do it. The program that starts
|
||||
* login (telnetd, rlogind) knows the IP address, so it
|
||||
* should create the utmp entry and fill in ut_addr.
|
||||
* gethostbyname() is not 100% reliable (the remote host
|
||||
* may be unknown, etc.). --marekm
|
||||
*/
|
||||
|
||||
if ((he = gethostbyname(hostname))) {
|
||||
utent.ut_addr = *((int32_t *)(he->h_addr_list[0]));
|
||||
#endif
|
||||
#ifdef UT_HOST
|
||||
strncpy(utent.ut_host, hostname, sizeof(utent.ut_host));
|
||||
#endif
|
||||
#if HAVE_UTMPX_H
|
||||
strncpy(utxent.ut_host, hostname, sizeof(utxent.ut_host));
|
||||
#endif
|
||||
/*
|
||||
* Add remote hostname to the environment. I think
|
||||
* (not sure) I saw it once on Irix. --marekm
|
||||
*/
|
||||
addenv("REMOTEHOST", hostname);
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
/* workaround for init/getty leaving junk in ut_host at least in some
|
||||
version of RedHat. --marekm */
|
||||
else if (amroot)
|
||||
memzero(utent.ut_host, sizeof utent.ut_host);
|
||||
#endif
|
||||
|
||||
openlog("mblogin", LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_AUTH);
|
||||
setup_tty();
|
||||
umask(007);
|
||||
|
||||
if (pflg)
|
||||
while (*envp) /* add inherited environment, */
|
||||
addenv(*envp++, NULL); /* some variables change later */
|
||||
|
||||
/* preserve TERM from getty */
|
||||
if (!pflg && (tmp = getenv("TERM")))
|
||||
addenv("TERM", tmp);
|
||||
|
||||
/* preserver CONNECT messages from mgetty */
|
||||
if ((tmp = getenv("CONNECT")))
|
||||
addenv("CONNECT", tmp);
|
||||
if ((tmp = getenv("CALLER_ID")))
|
||||
addenv("CALLER_ID", tmp);
|
||||
|
||||
/* get the mbse environment */
|
||||
pw = getpwnam("mbse");
|
||||
addenv("MBSE_ROOT", pw->pw_dir);
|
||||
sprintf(userfile, "%s/etc/users.data", pw->pw_dir);
|
||||
|
||||
check_nologin(pw->pw_dir);
|
||||
|
||||
init_env();
|
||||
|
||||
if (optind < argc) { /* get the user name */
|
||||
// if (rflg || fflg)
|
||||
// usage();
|
||||
|
||||
#ifdef SVR4
|
||||
/*
|
||||
* The "-h" option can't be used with a command-line username,
|
||||
* because telnetd invokes us as: login -h host TERM=...
|
||||
*/
|
||||
|
||||
if (! hflg)
|
||||
#endif
|
||||
{
|
||||
STRFCPY(username, argv[optind]);
|
||||
strzero(argv[optind]);
|
||||
++optind;
|
||||
}
|
||||
}
|
||||
|
||||
// printf("[%s]\n", username);
|
||||
|
||||
#ifdef SVR4
|
||||
/*
|
||||
* check whether ttymon has done the prompt for us already
|
||||
*/
|
||||
|
||||
{
|
||||
char *ttymon_prompt;
|
||||
|
||||
if ((ttymon_prompt = getenv("TTYPROMPT")) != NULL && (*ttymon_prompt != 0)) {
|
||||
/* read name, without prompt */
|
||||
login_prompt((char *)0, username, sizeof username);
|
||||
}
|
||||
}
|
||||
#endif /* SVR4 */
|
||||
if (optind < argc) /* now set command line variables */
|
||||
set_env(argc - optind, &argv[optind]);
|
||||
|
||||
if (hflg)
|
||||
cp = hostname;
|
||||
else
|
||||
#ifdef UT_HOST
|
||||
if (utent.ut_host[0])
|
||||
cp = utent.ut_host;
|
||||
else
|
||||
#endif
|
||||
#if HAVE_UTMPX_H
|
||||
if (utxent.ut_host[0])
|
||||
cp = utxent.ut_host;
|
||||
else
|
||||
#endif
|
||||
cp = "";
|
||||
|
||||
if (*cp)
|
||||
snprintf(fromhost, sizeof fromhost, _(" on `%s' from `%s'"), tty, cp);
|
||||
else
|
||||
snprintf(fromhost, sizeof fromhost, _(" on `%s'"), tty);
|
||||
|
||||
top:
|
||||
/* only allow ALARM sec. for login */
|
||||
signal(SIGALRM, alarm_handler);
|
||||
timeout = LOGIN_TIMEOUT;
|
||||
if (timeout > 0)
|
||||
alarm(timeout);
|
||||
|
||||
environ = newenvp; /* make new environment active */
|
||||
delay = LOGIN_DELAY;
|
||||
retries = LOGIN_RETRIES;
|
||||
|
||||
while (1) { /* repeatedly get login/password pairs */
|
||||
failed = 0; /* haven't failed authentication yet */
|
||||
if (! username[0]) { /* need to get a login id */
|
||||
if (subroot) {
|
||||
closelog ();
|
||||
exit (1);
|
||||
}
|
||||
preauth_flag = 0;
|
||||
login_prompt(_("login: "), username, sizeof username);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Here we try usernames on unix names and Fidonet style
|
||||
* names that are stored in the bbs userdatabase.
|
||||
* The name "bbs" is for new users, don't check the bbs userfile.
|
||||
*/
|
||||
if (strcmp(username, "bbs") == 0) {
|
||||
FoundName = 1;
|
||||
} else {
|
||||
FoundName = 0;
|
||||
if ((ufp = fopen(userfile, "r"))) {
|
||||
fread(&usrconfighdr, sizeof(usrconfighdr), 1, ufp);
|
||||
while (fread(&usrconfig, usrconfighdr.recsize, 1, ufp) == 1) {
|
||||
if ((strcasecmp(usrconfig.sUserName, username) == 0) ||
|
||||
(strcasecmp(usrconfig.sHandle, username) == 0) ||
|
||||
(strcmp(usrconfig.Name, username) == 0)) {
|
||||
FoundName = 1;
|
||||
STRFCPY(username, usrconfig.Name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose(ufp);
|
||||
}
|
||||
}
|
||||
|
||||
if ((! (pwd = getpwnam(username))) || (FoundName == 0)) {
|
||||
pwent.pw_name = username;
|
||||
strcpy(temp_pw, "!");
|
||||
pwent.pw_passwd = temp_pw;
|
||||
pwent.pw_shell = temp_shell;
|
||||
|
||||
preauth_flag = 0;
|
||||
failed = 1;
|
||||
} else {
|
||||
pwent = *pwd;
|
||||
}
|
||||
#ifdef SHADOW_PASSWORD
|
||||
spwd = NULL;
|
||||
if (pwd && strcmp(pwd->pw_passwd, SHADOW_PASSWD_STRING) == 0) {
|
||||
spwd = getspnam(username);
|
||||
if (spwd)
|
||||
pwent.pw_passwd = spwd->sp_pwdp;
|
||||
else
|
||||
syslog(LOG_WARNING, NO_SHADOW, username, fromhost);
|
||||
}
|
||||
#endif /* SHADOWPWD */
|
||||
|
||||
/*
|
||||
* If the encrypted password begins with a "!", the account
|
||||
* is locked and the user cannot login, even if they have
|
||||
* been "pre-authenticated."
|
||||
*/
|
||||
if (pwent.pw_passwd[0] == '!' || pwent.pw_passwd[0] == '*')
|
||||
failed = 1;
|
||||
|
||||
/*
|
||||
* The -r and -f flags provide a name which has already
|
||||
* been authenticated by some server.
|
||||
*/
|
||||
if (preauth_flag)
|
||||
goto auth_ok;
|
||||
|
||||
if (pw_auth(pwent.pw_passwd, username, reason, (char *) 0) == 0)
|
||||
goto auth_ok;
|
||||
|
||||
/*
|
||||
* Don't log unknown usernames - I mistyped the password for
|
||||
* username at least once... Should probably use LOG_AUTHPRIV
|
||||
* for those who really want to log them. --marekm
|
||||
*/
|
||||
syslog(LOG_WARNING, BAD_PASSWD, "UNKNOWN", fromhost);
|
||||
failed = 1;
|
||||
|
||||
auth_ok:
|
||||
/*
|
||||
* This is the point where all authenticated users
|
||||
* wind up. If you reach this far, your password has
|
||||
* been authenticated and so on.
|
||||
*/
|
||||
|
||||
#if defined(RADIUS) && !(defined(DES_RPC) || defined(KERBEROS))
|
||||
if (clear_pass) {
|
||||
strzero(clear_pass);
|
||||
clear_pass = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (! failed && pwent.pw_name && pwent.pw_uid == 0 && ! is_console) {
|
||||
syslog(LOG_CRIT, BAD_ROOT_LOGIN, fromhost);
|
||||
failed = 1;
|
||||
}
|
||||
#ifdef LOGIN_ACCESS
|
||||
if (!failed && !login_access(username, *hostname ? hostname : tty)) {
|
||||
syslog(LOG_WARNING, LOGIN_REFUSED, username, fromhost);
|
||||
failed = 1;
|
||||
}
|
||||
#endif
|
||||
if (! failed)
|
||||
break;
|
||||
|
||||
memzero(username, sizeof username);
|
||||
|
||||
if (--retries <= 0)
|
||||
syslog(LOG_CRIT, MANY_FAILS, fromhost);
|
||||
#if 1
|
||||
/*
|
||||
* If this was a passwordless account and we get here,
|
||||
* login was denied (securetty, faillog, etc.). There
|
||||
* was no password prompt, so do it now (will always
|
||||
* fail - the bad guys won't see that the passwordless
|
||||
* account exists at all). --marekm
|
||||
*/
|
||||
|
||||
if (pwent.pw_passwd[0] == '\0')
|
||||
pw_auth("!", username, reason, (char *) 0);
|
||||
#endif
|
||||
/*
|
||||
* Wait a while (a la SVR4 /usr/bin/login) before attempting
|
||||
* to login the user again. If the earlier alarm occurs
|
||||
* before the sleep() below completes, login will exit.
|
||||
*/
|
||||
|
||||
if (delay > 0)
|
||||
sleep(delay);
|
||||
|
||||
puts(_("Login incorrect"));
|
||||
|
||||
} /* while (1) */
|
||||
(void) alarm (0); /* turn off alarm clock */
|
||||
#if 1
|
||||
/*
|
||||
* porttime checks moved here, after the user has been
|
||||
* authenticated. now prints a message, as suggested
|
||||
* by Ivan Nejgebauer <ian@unsux.ns.ac.yu>. --marekm
|
||||
*/
|
||||
// if (getdef_bool("PORTTIME_CHECKS_ENAB") &&
|
||||
// !isttytime(pwent.pw_name, tty, time ((time_t *) 0))) {
|
||||
// SYSLOG((LOG_WARN, BAD_TIME, username, fromhost));
|
||||
// closelog();
|
||||
// bad_time_notify();
|
||||
// exit(1);
|
||||
// }
|
||||
#endif
|
||||
|
||||
if (getenv("IFS")) /* don't export user IFS ... */
|
||||
addenv("IFS= \t\n", NULL); /* ... instead, set a safe IFS */
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
setutmp(username, tty); /* make entry in utmp & wtmp files */
|
||||
#else
|
||||
setutmp(username, tty, hostname); /* make entry in utmp & wtmp files */
|
||||
#endif
|
||||
if (pwent.pw_shell[0] == '*') { /* subsystem root */
|
||||
subsystem (&pwent); /* figure out what to execute */
|
||||
subroot++; /* say i was here again */
|
||||
endpwent (); /* close all of the file which were */
|
||||
endgrent (); /* open in the original rooted file */
|
||||
#ifdef SHADOW_PASSWORD
|
||||
endspent (); /* system. they will be re-opened */
|
||||
#endif
|
||||
#ifdef SHADOWGRP
|
||||
endsgent (); /* in the new rooted file system */
|
||||
#endif
|
||||
goto top; /* go do all this all over again */
|
||||
}
|
||||
|
||||
dolastlog(&lastlog, &pwent, utent.ut_line, hostname);
|
||||
|
||||
#ifdef SVR4_SI86_EUA
|
||||
sysi86(SI86LIMUSER, EUA_ADD_USER); /* how do we test for fail? */
|
||||
#endif
|
||||
|
||||
#ifdef AGING
|
||||
/*
|
||||
* Have to do this while we still have root privileges, otherwise
|
||||
* we don't have access to /etc/shadow. expire() closes password
|
||||
* files, and changes to the user in the child before executing
|
||||
* the passwd program. --marekm
|
||||
*/
|
||||
#ifdef SHADOW_PASSWORD
|
||||
if (spwd) { /* check for age of password */
|
||||
if (expire (&pwent, spwd)) {
|
||||
pwd = getpwnam(username);
|
||||
spwd = getspnam(username);
|
||||
if (pwd)
|
||||
pwent = *pwd;
|
||||
}
|
||||
}
|
||||
#else
|
||||
#ifdef ATT_AGE
|
||||
if (pwent.pw_age && pwent.pw_age[0]) {
|
||||
if (expire (&pwent)) {
|
||||
pwd = getpwnam(username);
|
||||
if (pwd)
|
||||
pwent = *pwd;
|
||||
}
|
||||
}
|
||||
#endif /* ATT_AGE */
|
||||
#endif /* SHADOWPWD */
|
||||
#endif /* AGING */
|
||||
|
||||
setup_limits(&pwent); /* nice, ulimit etc. */
|
||||
chown_tty(tty, &pwent);
|
||||
|
||||
if (setup_uid_gid(&pwent, is_console))
|
||||
exit(1);
|
||||
|
||||
#ifdef KERBEROS
|
||||
if (clear_pass)
|
||||
login_kerberos(username, clear_pass);
|
||||
#endif
|
||||
#ifdef DES_RPC
|
||||
if (clear_pass)
|
||||
login_desrpc(clear_pass);
|
||||
#endif
|
||||
#if defined(DES_RPC) || defined(KERBEROS)
|
||||
if (clear_pass)
|
||||
strzero(clear_pass);
|
||||
#endif
|
||||
|
||||
setup_env(&pwent); /* set env vars, cd to the home dir */
|
||||
|
||||
setlocale(LC_ALL, "");
|
||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||
textdomain(PACKAGE);
|
||||
|
||||
addenv("HUSHLOGIN=TRUE", NULL);
|
||||
|
||||
signal(SIGQUIT, SIG_DFL); /* default quit signal */
|
||||
signal(SIGTERM, SIG_DFL); /* default terminate signal */
|
||||
signal(SIGALRM, SIG_DFL); /* default alarm signal */
|
||||
signal(SIGHUP, SIG_DFL); /* added this. --marekm */
|
||||
signal(SIGINT, SIG_DFL); /* default interrupt signal */
|
||||
|
||||
endpwent(); /* stop access to password file */
|
||||
endgrent(); /* stop access to group file */
|
||||
#ifdef SHADOW_PASSWORD
|
||||
endspent(); /* stop access to shadow passwd file */
|
||||
#endif
|
||||
#ifdef SHADOWGRP
|
||||
endsgent(); /* stop access to shadow group file */
|
||||
#endif
|
||||
if (pwent.pw_uid == 0)
|
||||
syslog(LOG_NOTICE, ROOT_LOGIN, fromhost);
|
||||
else
|
||||
syslog(LOG_INFO, REG_LOGIN, username, fromhost);
|
||||
closelog();
|
||||
|
||||
sleep(3);
|
||||
shell (pwent.pw_shell, (char *) 0); /* exec the shell finally. */
|
||||
/*NOTREACHED*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@@ -1,345 +0,0 @@
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef _MBLOGIN_H
|
||||
#define _MBLOGIN_H
|
||||
|
||||
#define ISDIGIT_LOCALE(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
|
||||
|
||||
/* Take care of NLS matters. */
|
||||
|
||||
#if HAVE_LOCALE_H
|
||||
# include <locale.h>
|
||||
#endif
|
||||
#if !HAVE_SETLOCALE
|
||||
# define setlocale(Category, Locale) /* empty */
|
||||
#endif
|
||||
|
||||
#define gettext_noop(String) (String)
|
||||
/* #define gettext_def(String) "#define String" */
|
||||
|
||||
#if ENABLE_NLS
|
||||
# include <libintl.h>
|
||||
# define _(Text) gettext (Text)
|
||||
#else
|
||||
# undef bindtextdomain
|
||||
# define bindtextdomain(Domain, Directory) /* empty */
|
||||
# undef textdomain
|
||||
# define textdomain(Domain) /* empty */
|
||||
# define _(Text) Text
|
||||
#endif
|
||||
|
||||
#ifndef P_
|
||||
# ifdef PROTOTYPES
|
||||
# define P_(x) x
|
||||
# else
|
||||
# define P_(x) ()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if STDC_HEADERS
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
#else /* not STDC_HEADERS */
|
||||
# ifndef HAVE_STRCHR
|
||||
# define strchr index
|
||||
# define strrchr rindex
|
||||
# endif
|
||||
char *strchr(), *strrchr(), *strtok();
|
||||
# ifndef HAVE_MEMCPY
|
||||
# define memcpy(d, s, n) bcopy((s), (d), (n))
|
||||
# endif
|
||||
#endif /* not STDC_HEADERS */
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#if HAVE_SYS_WAIT_H
|
||||
# include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if TIME_WITH_SYS_TIME
|
||||
# include <sys/time.h>
|
||||
# include <time.h>
|
||||
#else /* not TIME_WITH_SYS_TIME */
|
||||
# if HAVE_SYS_TIME_H
|
||||
# include <sys/time.h>
|
||||
# else
|
||||
# include <time.h>
|
||||
# endif
|
||||
#endif /* not TIME_WITH_SYS_TIME */
|
||||
|
||||
#ifdef HAVE_MEMSET
|
||||
# define memzero(ptr, size) memset((void *)(ptr), 0, (size))
|
||||
#else
|
||||
# define memzero(ptr, size) bzero((char *)(ptr), (size))
|
||||
#endif
|
||||
#define strzero(s) memzero(s, strlen(s)) /* warning: evaluates twice */
|
||||
|
||||
#ifdef HAVE_DIRENT_H /* DIR_SYSV */
|
||||
# include <dirent.h>
|
||||
# define DIRECT dirent
|
||||
#else
|
||||
# ifdef HAVE_SYS_NDIR_H /* DIR_XENIX */
|
||||
# include <sys/ndir.h>
|
||||
# endif
|
||||
# ifdef HAVE_SYS_DIR_H /* DIR_??? */
|
||||
# include <sys/dir.h>
|
||||
# endif
|
||||
# ifdef HAVE_NDIR_H /* DIR_BSD */
|
||||
# include <ndir.h>
|
||||
# endif
|
||||
# define DIRECT direct
|
||||
#endif
|
||||
|
||||
#ifdef SHADOWPWD
|
||||
/*
|
||||
* Possible cases:
|
||||
* - /usr/include/shadow.h exists and includes the shadow group stuff.
|
||||
* - /usr/include/shadow.h exists, but we use our own gshadow.h.
|
||||
* - /usr/include/shadow.h doesn't exist, use our own shadow.h and gshadow.h.
|
||||
*/
|
||||
#if HAVE_SHADOW_H
|
||||
#include <shadow.h>
|
||||
#if defined(SHADOWGRP) && !defined(GSHADOW)
|
||||
#include "gshadow_.h"
|
||||
#endif
|
||||
#else /* not HAVE_SHADOW_H */
|
||||
#include "shadow_.h"
|
||||
#ifdef SHADOWGRP
|
||||
#include "gshadow_.h"
|
||||
#endif
|
||||
#endif /* not HAVE_SHADOW_H */
|
||||
#endif /* SHADOWPWD */
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#ifndef NGROUPS_MAX
|
||||
#ifdef NGROUPS
|
||||
#define NGROUPS_MAX NGROUPS
|
||||
#else
|
||||
#define NGROUPS_MAX 64
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef F_OK
|
||||
# define F_OK 0
|
||||
# define X_OK 1
|
||||
# define W_OK 2
|
||||
# define R_OK 4
|
||||
#endif
|
||||
|
||||
#if HAVE_TERMIOS_H
|
||||
# include <termios.h>
|
||||
# define STTY(fd, termio) tcsetattr(fd, TCSANOW, termio)
|
||||
# define GTTY(fd, termio) tcgetattr(fd, termio)
|
||||
# define TERMIO struct termios
|
||||
# define USE_TERMIOS
|
||||
#else /* assumed HAVE_TERMIO_H */
|
||||
# include <sys/ioctl.h>
|
||||
# include <termio.h>
|
||||
# define STTY(fd, termio) ioctl(fd, TCSETA, termio)
|
||||
# define GTTY(fd, termio) ioctl(fd, TCGETA, termio)
|
||||
# define TEMRIO struct termio
|
||||
# define USE_TERMIO
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Password aging constants
|
||||
*
|
||||
* DAY - seconds / day
|
||||
* WEEK - seconds / week
|
||||
* SCALE - seconds / aging unit
|
||||
*/
|
||||
|
||||
/* Solaris defines this in shadow.h */
|
||||
#ifndef DAY
|
||||
#define DAY (24L*3600L)
|
||||
#endif
|
||||
|
||||
#define WEEK (7*DAY)
|
||||
|
||||
#ifdef ITI_AGING
|
||||
#define SCALE 1
|
||||
#else
|
||||
#define SCALE DAY
|
||||
#endif
|
||||
|
||||
/* Copy string pointed by B to array A with size checking. It was originally
|
||||
* in lmain.c but is _very_ useful elsewhere. Some setuid root programs with
|
||||
* very sloppy coding used to assume that BUFSIZ will always be enough... */
|
||||
|
||||
/* danger - side effects */
|
||||
#define STRFCPY(A,B) \
|
||||
(strncpy((A), (B), sizeof(A) - 1), (A)[sizeof(A) - 1] = '\0')
|
||||
|
||||
/* get rid of a few ugly repeated #ifdefs in pwent.c and grent.c */
|
||||
/* XXX - this is ugly too, configure should test it and not check for
|
||||
any hardcoded system names, if possible. --marekm */
|
||||
#if defined(SVR4) || defined(AIX) || defined(__linux__)
|
||||
#define SETXXENT_TYPE void
|
||||
#define SETXXENT_RET(x) return
|
||||
#define SETXXENT_TEST(x) x; if (0) /* compiler should optimize this away */
|
||||
#else
|
||||
#define SETXXENT_TYPE int
|
||||
#define SETXXENT_RET(x) return(x)
|
||||
#define SETXXENT_TEST(x) if (x)
|
||||
#endif
|
||||
|
||||
#ifndef PASSWD_FILE
|
||||
#define PASSWD_FILE "/etc/passwd"
|
||||
#endif
|
||||
|
||||
#ifndef GROUP_FILE
|
||||
#define GROUP_FILE "/etc/group"
|
||||
#endif
|
||||
|
||||
#ifdef SHADOWPWD
|
||||
#ifndef SHADOW_FILE
|
||||
#define SHADOW_FILE "/etc/shadow"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef SHADOWGRP
|
||||
#ifndef SGROUP_FILE
|
||||
#define SGROUP_FILE "/etc/gshadow"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define PASSWD_PAG_FILE PASSWD_FILE ".pag"
|
||||
#define GROUP_PAG_FILE GROUP_FILE ".pag"
|
||||
#define SHADOW_PAG_FILE SHADOW_FILE ".pag"
|
||||
#define SGROUP_PAG_FILE SGROUP_FILE ".pag"
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL ((void *) 0)
|
||||
#endif
|
||||
|
||||
#ifdef sun /* hacks for compiling on SunOS */
|
||||
# ifndef SOLARIS
|
||||
extern int fputs();
|
||||
extern char *strdup();
|
||||
extern char *strerror();
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// #ifndef HAVE_SNPRINTF
|
||||
// #include "snprintf.h"
|
||||
// #endif
|
||||
|
||||
/*
|
||||
* string to use for the pw_passwd field in /etc/passwd when using
|
||||
* shadow passwords - most systems use "x" but there are a few
|
||||
* exceptions, so it can be changed here if necessary. --marekm
|
||||
*/
|
||||
#ifndef SHADOW_PASSWD_STRING
|
||||
#define SHADOW_PASSWD_STRING "x"
|
||||
#endif
|
||||
|
||||
#ifdef PAM_STRERROR_NEEDS_TWO_ARGS /* Linux-PAM 0.59+ */
|
||||
#define PAM_STRERROR(pamh, err) pam_strerror(pamh, err)
|
||||
#else
|
||||
#define PAM_STRERROR(pamh, err) pam_strerror(err)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#define Max_passlen 14 /* Define maximum passwd length */
|
||||
|
||||
|
||||
/*
|
||||
* Security structure
|
||||
*/
|
||||
typedef struct _security {
|
||||
unsigned int level; /* Security level */
|
||||
unsigned long flags; /* Access flags */
|
||||
unsigned long notflags; /* No Access flags */
|
||||
} securityrec;
|
||||
|
||||
/*
|
||||
* Users Control Structures (users.data)
|
||||
*/
|
||||
struct userhdr {
|
||||
long hdrsize; /* Size of header */
|
||||
long recsize; /* Size of records */
|
||||
};
|
||||
|
||||
struct userrec {
|
||||
char sUserName[36]; /* User First and Last Name */
|
||||
char Name[9]; /* Unix name */
|
||||
unsigned long xPassword; /* Users Password (CRC) */
|
||||
char sVoicePhone[20]; /* Voice Number */
|
||||
char sDataPhone[20]; /* Data/Business Number */
|
||||
char sLocation[28]; /* Users Location */
|
||||
char address[3][41]; /* Users address */
|
||||
char sDateOfBirth[12]; /* Date of Birth */
|
||||
time_t tFirstLoginDate; /* Date of First Login */
|
||||
time_t tLastLoginDate; /* Date of Last Login */
|
||||
securityrec Security; /* User Security Level */
|
||||
char sComment[81]; /* User Comment */
|
||||
char sExpiryDate[12]; /* User Expiry Date */
|
||||
securityrec ExpirySec; /* Expiry Security Level */
|
||||
char sSex[8]; /* Users Sex */
|
||||
|
||||
unsigned Hidden : 1; /* Hide User from Lists */
|
||||
unsigned HotKeys : 1; /* Hot-Keys ON/OFF */
|
||||
unsigned GraphMode : 1; /* ANSI Mode ON/OFF */
|
||||
unsigned Deleted : 1; /* Deleted Status */
|
||||
unsigned NeverDelete : 1; /* Never Delete User */
|
||||
unsigned Chat : 1; /* Has IEMSI Chatmode */
|
||||
unsigned LockedOut : 1; /* User is locked out */
|
||||
unsigned DoNotDisturb : 1; /* DoNot disturb */
|
||||
unsigned Cls : 1; /* CLS on/off */
|
||||
unsigned More : 1; /* More prompt */
|
||||
unsigned FsMsged : 1; /* Fullscreen editor */
|
||||
unsigned MailScan : 1; /* New Mail scan */
|
||||
unsigned Guest : 1; /* Is guest account */
|
||||
unsigned OL_ExtInfo : 1; /* OLR extended msg info */
|
||||
int iTotalCalls; /* Total number of calls */
|
||||
int iTimeLeft; /* Time left today */
|
||||
int iConnectTime; /* Connect time this call */
|
||||
int iTimeUsed; /* Time used today */
|
||||
int iScreenLen; /* User Screen Length */
|
||||
time_t tLastPwdChange; /* Date last password chg */
|
||||
unsigned xHangUps;
|
||||
long Credit; /* Users credit */
|
||||
int Paged; /* Times paged today */
|
||||
int xOfflineFmt;
|
||||
int LastPktNum; /* Todays Last packet number*/
|
||||
char Archiver[6]; /* Archiver to use */
|
||||
|
||||
int iLastFileArea; /* Number of last file area */
|
||||
int iLastFileGroup; /* Number of last file group*/
|
||||
char sProtocol[21]; /* Users default protocol */
|
||||
unsigned long Downloads; /* Total number of d/l's */
|
||||
unsigned long Uploads; /* Total number of uploads */
|
||||
unsigned long UploadK; /* Upload KiloBytes */
|
||||
unsigned long DownloadK; /* Download KiloBytes */
|
||||
long DownloadKToday; /* KB Downloaded today */
|
||||
long UploadKToday; /* KB Uploaded today */
|
||||
int iTransferTime; /* Last file transfer time */
|
||||
int iLastMsgArea; /* Number of last msg area */
|
||||
int iLastMsgGroup; /* Number of last msg group */
|
||||
int iPosted; /* Number of msgs posted */
|
||||
int iLanguage; /* Current Language */
|
||||
char sHandle[36]; /* Users Handle */
|
||||
int iStatus; /* WhosDoingWhat status */
|
||||
int DownloadsToday; /* Downloads today */
|
||||
int CrtDef; /* IEMSI Terminal emulation */
|
||||
int Protocol; /* IEMSI protocol */
|
||||
unsigned IEMSI : 1; /* Is this a IEMSI session */
|
||||
unsigned ieMNU : 1; /* Can do ASCII download */
|
||||
unsigned ieTAB : 1; /* Can handle TAB character */
|
||||
unsigned ieASCII8 : 1; /* Can handle 8-bit IBM-PC */
|
||||
unsigned ieNEWS : 1; /* Show bulletins */
|
||||
unsigned ieFILE : 1; /* Check for new files */
|
||||
unsigned Email : 1; /* Has private email box */
|
||||
unsigned FSemacs : 1; /* FSedit uses emacs keys */
|
||||
char Password[Max_passlen+1];/* Plain password */
|
||||
};
|
||||
|
||||
|
||||
#endif
|
@@ -1,914 +0,0 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* $Id$
|
||||
* Purpose ...............: setuid root version of passwd
|
||||
* Shadow Suite (c) ......: Julianne Frances Haugh
|
||||
*
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1997-2002
|
||||
*
|
||||
* 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 <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_SYS_RESOURCE_H
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <syslog.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#if defined(SHADOW_PASSWORD)
|
||||
#include <shadow.h>
|
||||
#endif
|
||||
#ifdef HAVE_USERSEC_H
|
||||
#include <userpw.h>
|
||||
#include <usersec.h>
|
||||
#include <userconf.h>
|
||||
#endif
|
||||
|
||||
#include "encrypt.h"
|
||||
#include "rad64.h"
|
||||
#include "myname.h"
|
||||
#include "xmalloc.h"
|
||||
#include "pwio.h"
|
||||
#include "shadowio.h"
|
||||
#include "pw_util.h"
|
||||
#include "mbpasswd.h"
|
||||
|
||||
|
||||
#ifndef AGING
|
||||
#if defined(SHADOW_PASSWORD)
|
||||
#define AGING 1
|
||||
#endif
|
||||
#else
|
||||
#if !defined(SHADOW_PASSWORD)
|
||||
#undef AGING
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static int do_update_age = 0;
|
||||
#ifndef PAM
|
||||
static char crypt_passwd[128]; /* The "old-style" password, if present */
|
||||
static int do_update_pwd = 0;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef SHADOW_PASSWORD
|
||||
static int is_shadow_pwd;
|
||||
static void check_password(const struct passwd *, const struct spwd *);
|
||||
#else /* !SHADOW_PASSWORD */
|
||||
static void check_password(const struct passwd *);
|
||||
#endif /* !SHADOW_PASSWORD */
|
||||
|
||||
#ifndef DAY
|
||||
#define DAY (24L*3600L)
|
||||
#endif
|
||||
|
||||
#define WEEK (7*DAY)
|
||||
#define SCALE DAY
|
||||
|
||||
|
||||
/*
|
||||
* string to use for the pw_passwd field in /etc/passwd when using
|
||||
* shadow passwords - most systems use "x" but there are a few
|
||||
* exceptions, so it can be changed here if necessary. --marekm
|
||||
*/
|
||||
#ifndef SHADOW_PASSWD_STRING
|
||||
#define SHADOW_PASSWD_STRING "x"
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Global variables
|
||||
*/
|
||||
|
||||
static char *name; /* The name of user whose password is being changed */
|
||||
static char *myname; /* The current user's name */
|
||||
static int force; /* Force update of locked passwords */
|
||||
|
||||
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
static void fail_exit(int status)
|
||||
{
|
||||
// gr_unlock();
|
||||
#ifdef SHADOWGRP
|
||||
if (is_shadow_grp)
|
||||
sgr_unlock();
|
||||
#endif
|
||||
#ifdef SHADOW_PASSWORD
|
||||
if (is_shadow_pwd)
|
||||
spw_unlock();
|
||||
#endif
|
||||
pw_unlock();
|
||||
exit(status);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void oom(void)
|
||||
{
|
||||
fprintf(stderr, "mbpasswd: out of memory\n");
|
||||
fail_exit(E_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* insert_crypt_passwd - add an "old-style" password to authentication string
|
||||
* result now malloced to avoid overflow, just in case. --marekm
|
||||
*/
|
||||
static char *insert_crypt_passwd(const char *string, char *passwd)
|
||||
{
|
||||
#ifdef AUTH_METHODS
|
||||
if (string && *string) {
|
||||
char *cp, *result;
|
||||
|
||||
result = xmalloc(strlen(string) + strlen(passwd) + 1);
|
||||
cp = result;
|
||||
while (*string) {
|
||||
if (string[0] == ';') {
|
||||
*cp++ = *string++;
|
||||
} else if (string[0] == '@') {
|
||||
while (*string && *string != ';')
|
||||
*cp++ = *string++;
|
||||
} else {
|
||||
while (*passwd)
|
||||
*cp++ = *passwd++;
|
||||
while (*string && *string != ';')
|
||||
string++;
|
||||
}
|
||||
}
|
||||
*cp = '\0';
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
return xstrdup(passwd);
|
||||
}
|
||||
|
||||
|
||||
static char *update_crypt_pw(char *cp)
|
||||
{
|
||||
if (do_update_pwd)
|
||||
cp = insert_crypt_passwd(cp, crypt_passwd);
|
||||
|
||||
return cp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* pwd_init - ignore signals, and set resource limits to safe
|
||||
* values. Call this before modifying password files, so that
|
||||
* it is less likely to fail in the middle of operation.
|
||||
*/
|
||||
void pwd_init(void)
|
||||
{
|
||||
#ifdef HAVE_SYS_RESOURCE_H
|
||||
struct rlimit rlim;
|
||||
|
||||
#ifdef RLIMIT_CORE
|
||||
rlim.rlim_cur = rlim.rlim_max = 0;
|
||||
setrlimit(RLIMIT_CORE, &rlim);
|
||||
#endif
|
||||
rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
|
||||
#ifdef RLIMIT_AS
|
||||
setrlimit(RLIMIT_AS, &rlim);
|
||||
#endif
|
||||
#ifdef RLIMIT_CPU
|
||||
setrlimit(RLIMIT_CPU, &rlim);
|
||||
#endif
|
||||
#ifdef RLIMIT_DATA
|
||||
setrlimit(RLIMIT_DATA, &rlim);
|
||||
#endif
|
||||
#ifdef RLIMIT_FSIZE
|
||||
setrlimit(RLIMIT_FSIZE, &rlim);
|
||||
#endif
|
||||
#ifdef RLIMIT_NOFILE
|
||||
setrlimit(RLIMIT_NOFILE, &rlim);
|
||||
#endif
|
||||
#ifdef RLIMIT_RSS
|
||||
setrlimit(RLIMIT_RSS, &rlim);
|
||||
#endif
|
||||
#ifdef RLIMIT_STACK
|
||||
setrlimit(RLIMIT_STACK, &rlim);
|
||||
#endif
|
||||
#endif /* !HAVE_SYS_RESOURCE_H */
|
||||
|
||||
signal(SIGALRM, SIG_IGN);
|
||||
signal(SIGHUP, SIG_IGN);
|
||||
signal(SIGINT, SIG_IGN);
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
signal(SIGQUIT, SIG_IGN);
|
||||
signal(SIGTERM, SIG_IGN);
|
||||
#ifdef SIGTSTP
|
||||
signal(SIGTSTP, SIG_IGN);
|
||||
#endif
|
||||
#ifdef SIGTTOU
|
||||
signal(SIGTTOU, SIG_IGN);
|
||||
#endif
|
||||
|
||||
umask(077);
|
||||
}
|
||||
#endif /* not FreeBSD */
|
||||
|
||||
|
||||
/*
|
||||
* isexpired - determine if account is expired yet
|
||||
*
|
||||
* isexpired calculates the expiration date based on the
|
||||
* password expiration criteria.
|
||||
*/
|
||||
#ifdef SHADOW_PASSWORD
|
||||
int isexpired(const struct passwd *pw, const struct spwd *sp)
|
||||
{
|
||||
#else
|
||||
int isexpired(const struct passwd *pw)
|
||||
{
|
||||
#endif
|
||||
long now;
|
||||
#ifdef HAVE_USERSEC_H
|
||||
int minage = 0;
|
||||
int maxage = 10000;
|
||||
int curage = 0;
|
||||
struct userpw *pu;
|
||||
#endif
|
||||
|
||||
now = time ((time_t *) 0) / SCALE;
|
||||
|
||||
#ifdef SHADOW_PASSWORD
|
||||
|
||||
if (!sp)
|
||||
sp = pwd_to_spwd(pw);
|
||||
|
||||
/*
|
||||
* Quick and easy - there is an expired account field
|
||||
* along with an inactive account field. Do the expired
|
||||
* one first since it is worse.
|
||||
*/
|
||||
if (sp->sp_expire > 0 && now >= sp->sp_expire)
|
||||
return 3;
|
||||
|
||||
/*
|
||||
* Last changed date 1970-01-01 (not very likely) means that
|
||||
* the password must be changed on next login (passwd -e).
|
||||
*
|
||||
* The check for "x" is a workaround for RedHat NYS libc bug -
|
||||
* if /etc/shadow doesn't exist, getspnam() still succeeds and
|
||||
* returns sp_lstchg==0 (must change password) instead of -1!
|
||||
*/
|
||||
if (sp->sp_lstchg == 0 && !strcmp(pw->pw_passwd, SHADOW_PASSWD_STRING))
|
||||
return 1;
|
||||
if (sp->sp_lstchg > 0 && sp->sp_max >= 0 && sp->sp_inact >= 0 &&
|
||||
now >= sp->sp_lstchg + sp->sp_max + sp->sp_inact)
|
||||
return 2;
|
||||
#endif
|
||||
#ifdef HAVE_USERSEC_H /*{*/
|
||||
/*
|
||||
* The aging information lives someplace else. Get it from the
|
||||
* login.cfg file
|
||||
*/
|
||||
|
||||
if (getconfattr (SC_SYS_PASSWD, SC_MINAGE, &minage, SEC_INT))
|
||||
minage = -1;
|
||||
|
||||
if (getconfattr (SC_SYS_PASSWD, SC_MAXAGE, &maxage, SEC_INT))
|
||||
maxage = -1;
|
||||
|
||||
pu = getuserpw (pw->pw_name);
|
||||
curage = (time (0) - pu->upw_lastupdate) / (7*86400L);
|
||||
|
||||
if (maxage != -1 && curage > maxage)
|
||||
return 1;
|
||||
#else /*} !HAVE_USERSEC_H */
|
||||
|
||||
/*
|
||||
* The last and max fields must be present for an account
|
||||
* to have an expired password. A maximum of >10000 days
|
||||
* is considered to be infinite.
|
||||
*/
|
||||
|
||||
#ifdef SHADOW_PASSWORD
|
||||
if (sp->sp_lstchg == -1 ||
|
||||
sp->sp_max == -1 || sp->sp_max >= (10000L*DAY/SCALE))
|
||||
return 0;
|
||||
#endif
|
||||
#ifdef ATT_AGE
|
||||
if (pw->pw_age[0] == '\0' || pw->pw_age[0] == '/')
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Calculate today's day and the day on which the password
|
||||
* is going to expire. If that date has already passed,
|
||||
* the password has expired.
|
||||
*/
|
||||
|
||||
#ifdef SHADOW_PASSWORD
|
||||
if (now >= sp->sp_lstchg + sp->sp_max)
|
||||
return 1;
|
||||
#endif
|
||||
#ifdef ATT_AGE
|
||||
if (a64l (pw->pw_age + 2) + c64i (pw->pw_age[1]) < now / 7)
|
||||
return 1;
|
||||
#endif
|
||||
#endif /*} HAVE_USERSEC_H */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* check_password - test a password to see if it can be changed
|
||||
*
|
||||
* check_password() sees if the invoker has permission to change the
|
||||
* password for the given user.
|
||||
*/
|
||||
#ifdef SHADOW_PASSWORD
|
||||
static void check_password(const struct passwd *pw, const struct spwd *sp)
|
||||
{
|
||||
#else
|
||||
static void check_password(const struct passwd *pw)
|
||||
{
|
||||
#endif
|
||||
time_t now, last, ok;
|
||||
int exp_status;
|
||||
#ifdef HAVE_USERSEC_H
|
||||
struct userpw *pu;
|
||||
#endif
|
||||
|
||||
#ifdef SHADOW_PASSWORD
|
||||
exp_status = isexpired(pw, sp);
|
||||
#else
|
||||
exp_status = isexpired(pw);
|
||||
#endif
|
||||
|
||||
now = time(NULL);
|
||||
|
||||
#ifdef SHADOW_PASSWORD
|
||||
/*
|
||||
* If the force flag is set (for new users) this check is skipped.
|
||||
*/
|
||||
if (force == 1)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Expired accounts cannot be changed ever. Passwords
|
||||
* which are locked may not be changed. Passwords where
|
||||
* min > max may not be changed. Passwords which have
|
||||
* been inactive too long cannot be changed.
|
||||
*/
|
||||
if (sp->sp_pwdp[0] == '!' || exp_status > 1 ||
|
||||
(sp->sp_max >= 0 && sp->sp_min > sp->sp_max)) {
|
||||
fprintf (stderr, "The password for %s cannot be changed.\n", sp->sp_namp);
|
||||
syslog(LOG_WARNING, "password locked for %s", sp->sp_namp);
|
||||
closelog();
|
||||
exit (E_NOPERM);
|
||||
}
|
||||
|
||||
/*
|
||||
* Passwords may only be changed after sp_min time is up.
|
||||
*/
|
||||
|
||||
last = sp->sp_lstchg * SCALE;
|
||||
ok = last + (sp->sp_min > 0 ? sp->sp_min * SCALE : 0);
|
||||
#else /* !SHADOW_PASSWORD */
|
||||
if (pw->pw_passwd[0] == '!' || exp_status > 1) {
|
||||
fprintf (stderr, "The password for %s cannot be changed.\n", pw->pw_name);
|
||||
syslog(LOG_WARNING, "password locked for %s", pw->pw_name);
|
||||
closelog();
|
||||
exit (E_NOPERM);
|
||||
}
|
||||
#ifdef ATT_AGE
|
||||
/*
|
||||
* Can always be changed if there is no age info
|
||||
*/
|
||||
|
||||
if (! pw->pw_age[0])
|
||||
return;
|
||||
|
||||
last = a64l (pw->pw_age + 2) * WEEK;
|
||||
ok = last + c64i (pw->pw_age[1]) * WEEK;
|
||||
#else /* !ATT_AGE */
|
||||
#ifdef HAVE_USERSEC_H
|
||||
pu = getuserpw(pw->pw_name);
|
||||
last = pu ? pu->upw_lastupdate : 0L;
|
||||
ok = last + (minage > 0 ? minage * WEEK : 0);
|
||||
#else
|
||||
last = 0;
|
||||
ok = 0;
|
||||
#endif
|
||||
#endif /* !ATT_AGE */
|
||||
#endif /* !SHADOW_PASSWORD */
|
||||
if (now < ok) {
|
||||
fprintf(stderr, "Sorry, the password for %s cannot be changed yet.\n", pw->pw_name);
|
||||
syslog(LOG_WARNING, "now < minimum age for `%s'", pw->pw_name);
|
||||
closelog();
|
||||
exit (E_NOPERM);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* pwd_to_spwd - create entries for new spwd structure
|
||||
*
|
||||
* pwd_to_spwd() creates a new (struct spwd) containing the
|
||||
* information in the pointed-to (struct passwd).
|
||||
*
|
||||
* This function is borrowed from the Shadow Password Suite.
|
||||
*/
|
||||
#ifdef SHADOW_PASSWORD
|
||||
struct spwd *pwd_to_spwd(const struct passwd *pw)
|
||||
{
|
||||
static struct spwd sp;
|
||||
|
||||
/*
|
||||
* Nice, easy parts first. The name and passwd map directly
|
||||
* from the old password structure to the new one.
|
||||
*/
|
||||
sp.sp_namp = pw->pw_name;
|
||||
sp.sp_pwdp = pw->pw_passwd;
|
||||
|
||||
#ifdef ATT_AGE
|
||||
/*
|
||||
* AT&T-style password aging maps the sp_min, sp_max, and
|
||||
* sp_lstchg information from the pw_age field, which appears
|
||||
* after the encrypted password.
|
||||
*/
|
||||
if (pw->pw_age[0]) {
|
||||
sp.sp_max = (c64i(pw->pw_age[0]) * WEEK) / SCALE;
|
||||
|
||||
if (pw->pw_age[1])
|
||||
sp.sp_min = (c64i(pw->pw_age[1]) * WEEK) / SCALE;
|
||||
else
|
||||
sp.sp_min = (10000L * DAY) / SCALE;
|
||||
|
||||
if (pw->pw_age[1] && pw->pw_age[2])
|
||||
sp.sp_lstchg = (a64l(pw->pw_age + 2) * WEEK) / SCALE;
|
||||
else
|
||||
sp.sp_lstchg = time((time_t *) 0) / SCALE;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
/*
|
||||
* Defaults used if there is no pw_age information.
|
||||
*/
|
||||
sp.sp_min = 0;
|
||||
sp.sp_max = (10000L * DAY) / SCALE;
|
||||
sp.sp_lstchg = time((time_t *) 0) / SCALE;
|
||||
}
|
||||
|
||||
/*
|
||||
* These fields have no corresponding information in the password
|
||||
* file. They are set to uninitialized values.
|
||||
*/
|
||||
sp.sp_warn = -1;
|
||||
sp.sp_expire = -1;
|
||||
sp.sp_inact = -1;
|
||||
sp.sp_flag = -1;
|
||||
|
||||
return &sp;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* new_password - validate old password and replace with new
|
||||
* (both old and new in global "char crypt_passwd[128]")
|
||||
*/
|
||||
static int new_password(const struct passwd *pw, char *newpasswd)
|
||||
{
|
||||
char *cp; /* Pointer to getpass() response */
|
||||
char pass[200]; /* New password */
|
||||
#ifdef HAVE_LIBCRACK_HIST
|
||||
int HistUpdate P_((const char *, const char *));
|
||||
#endif
|
||||
|
||||
sprintf(pass, "%s", newpasswd);
|
||||
|
||||
/*
|
||||
* Encrypt the password, then wipe the cleartext password.
|
||||
*/
|
||||
cp = pw_encrypt(pass, crypt_make_salt());
|
||||
memset(&pass, 0, sizeof(pass));
|
||||
|
||||
#ifdef HAVE_LIBCRACK_HIST
|
||||
HistUpdate(pw->pw_name, crypt_passwd);
|
||||
#endif
|
||||
STRFCPY(crypt_passwd, cp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
|
||||
static void update_noshadow(int shadow_locked)
|
||||
{
|
||||
const struct passwd *pw;
|
||||
struct passwd *npw;
|
||||
#ifdef ATT_AGE
|
||||
char age[5];
|
||||
long week = time((time_t *) 0) / WEEK;
|
||||
char *cp;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* call this with shadow_locked != 0 to avoid calling lckpwdf()
|
||||
* twice (which will fail). XXX - pw_lock(), pw_unlock(),
|
||||
* spw_lock(), spw_unlock() really should track the lock count
|
||||
* and call lckpwdf() only before the first lock, and ulckpwdf()
|
||||
* after the last unlock.
|
||||
*/
|
||||
if (!pw_lock()) {
|
||||
fprintf(stderr, "Cannot lock the password file; try again later.\n");
|
||||
syslog(LOG_WARNING, "can't lock password file");
|
||||
exit(E_PWDBUSY);
|
||||
}
|
||||
if (!pw_open(O_RDWR)) {
|
||||
fprintf(stderr, "Cannot open the password file.\n");
|
||||
syslog(LOG_ERR, "can't open password file");
|
||||
fail_exit(E_MISSING);
|
||||
}
|
||||
pw = pw_locate(name);
|
||||
if (!pw) {
|
||||
fprintf(stderr, "mbpasswd: user %s not found in /etc/passwd\n", name);
|
||||
fail_exit(E_NOPERM);
|
||||
}
|
||||
npw = __pw_dup(pw);
|
||||
if (!npw)
|
||||
oom();
|
||||
npw->pw_passwd = update_crypt_pw(npw->pw_passwd);
|
||||
#ifdef ATT_AGE
|
||||
memset(age, 0, sizeof(age));
|
||||
STRFCPY(age, npw->pw_age);
|
||||
|
||||
/*
|
||||
* Just changing the password - update the last change date
|
||||
* if there is one, otherwise the age just disappears.
|
||||
*/
|
||||
if (do_update_age) {
|
||||
if (strlen(age) > 2) {
|
||||
cp = l64a(week);
|
||||
age[2] = cp[0];
|
||||
age[3] = cp[1];
|
||||
} else {
|
||||
age[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
if (xflg) {
|
||||
if (age_max > 0)
|
||||
age[0] = i64c((age_max + 6) / 7);
|
||||
else
|
||||
age[0] = '.';
|
||||
|
||||
if (age[1] == '\0')
|
||||
age[1] = '.';
|
||||
}
|
||||
if (nflg) {
|
||||
if (age[0] == '\0')
|
||||
age[0] = 'z';
|
||||
|
||||
if (age_min > 0)
|
||||
age[1] = i64c((age_min + 6) / 7);
|
||||
else
|
||||
age[1] = '.';
|
||||
}
|
||||
/*
|
||||
* The last change date is added by -n or -x if it's
|
||||
* not already there.
|
||||
*/
|
||||
if ((nflg || xflg) && strlen(age) <= 2) {
|
||||
cp = l64a(week);
|
||||
age[2] = cp[0];
|
||||
age[3] = cp[1];
|
||||
}
|
||||
|
||||
/*
|
||||
* Force password change - if last change date is
|
||||
* present, it will be set to (today - max - 1 week).
|
||||
* Otherwise, just set min = max = 0 (will disappear
|
||||
* when password is changed).
|
||||
*/
|
||||
if (eflg) {
|
||||
if (strlen(age) > 2) {
|
||||
cp = l64a(week - c64i(age[0]) - 1);
|
||||
age[2] = cp[0];
|
||||
age[3] = cp[1];
|
||||
} else {
|
||||
strcpy(age, "..");
|
||||
}
|
||||
}
|
||||
|
||||
npw->pw_age = age;
|
||||
#endif
|
||||
|
||||
if (!pw_update(npw)) {
|
||||
fprintf(stderr, "Error updating the password entry.\n");
|
||||
syslog(LOG_ERR, "error updating password entry");
|
||||
fail_exit(E_FAILURE);
|
||||
}
|
||||
#ifdef NDBM
|
||||
if (pw_dbm_present() && !pw_dbm_update(npw)) {
|
||||
fprintf(stderr, _("Error updating the DBM password entry.\n"));
|
||||
SYSLOG((LOG_ERR, DBMERROR2));
|
||||
fail_exit(E_FAILURE);
|
||||
}
|
||||
endpwent();
|
||||
#endif
|
||||
if (!pw_close()) {
|
||||
fprintf(stderr, "Cannot commit password file changes.\n");
|
||||
syslog(LOG_ERR, "can't rewrite password file");
|
||||
fail_exit(E_FAILURE);
|
||||
}
|
||||
pw_unlock();
|
||||
}
|
||||
|
||||
#endif /* Not __FreeBSD__ */
|
||||
|
||||
|
||||
#ifdef SHADOW_PASSWORD
|
||||
static void update_shadow(void)
|
||||
{
|
||||
const struct spwd *sp;
|
||||
struct spwd *nsp;
|
||||
|
||||
if (!spw_lock()) {
|
||||
fprintf(stderr, "Cannot lock the password file; try again later.\n");
|
||||
syslog(LOG_WARNING, "can't lock password file");
|
||||
exit(E_PWDBUSY);
|
||||
}
|
||||
if (!spw_open(O_RDWR)) {
|
||||
fprintf(stderr, "Cannot open the password file.\n");
|
||||
syslog(LOG_ERR, "can't open password file");
|
||||
fail_exit(E_FAILURE);
|
||||
}
|
||||
sp = spw_locate(name);
|
||||
if (!sp) {
|
||||
/* Try to update the password in /etc/passwd instead. */
|
||||
spw_close();
|
||||
update_noshadow(1);
|
||||
spw_unlock();
|
||||
return;
|
||||
}
|
||||
nsp = __spw_dup(sp);
|
||||
if (!nsp)
|
||||
oom();
|
||||
nsp->sp_pwdp = update_crypt_pw(nsp->sp_pwdp);
|
||||
if (do_update_age)
|
||||
nsp->sp_lstchg = time((time_t *) 0) / SCALE;
|
||||
|
||||
if (!spw_update(nsp)) {
|
||||
fprintf(stderr, "Error updating the password entry.\n");
|
||||
syslog(LOG_ERR, "error updating password entry");
|
||||
fail_exit(E_FAILURE);
|
||||
}
|
||||
#ifdef NDBM
|
||||
if (sp_dbm_present() && !sp_dbm_update(nsp)) {
|
||||
fprintf(stderr, _("Error updating the DBM password entry.\n"));
|
||||
SYSLOG((LOG_ERR, DBMERROR2));
|
||||
fail_exit(E_FAILURE);
|
||||
}
|
||||
endspent();
|
||||
#endif
|
||||
if (!spw_close()) {
|
||||
fprintf(stderr, "Cannot commit password file changes.\n");
|
||||
syslog(LOG_ERR, "can't rewrite password file");
|
||||
fail_exit(E_FAILURE);
|
||||
}
|
||||
spw_unlock();
|
||||
}
|
||||
#endif /* SHADOWPWD */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Function will set a new password in the users password file.
|
||||
* Note that this function must run setuid root!
|
||||
*/
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
#ifndef __FreeBSD__
|
||||
const struct passwd *pw;
|
||||
const struct group *gr;
|
||||
#ifdef SHADOW_PASSWORD
|
||||
const struct spwd *sp;
|
||||
#endif
|
||||
#else
|
||||
static struct passwd *pw;
|
||||
static struct group *gr;
|
||||
int pfd, tfd;
|
||||
#endif
|
||||
char *cp;
|
||||
|
||||
|
||||
/*
|
||||
* Get my username
|
||||
*/
|
||||
pw = get_my_pwent();
|
||||
if (!pw) {
|
||||
fprintf(stderr, "mbpasswd: Cannot determine your user name.\n");
|
||||
exit(1);
|
||||
}
|
||||
myname = xstrdup(pw->pw_name);
|
||||
|
||||
/*
|
||||
* Get my groupname, this must be "bbs", other users may not
|
||||
* use this program, not even root.
|
||||
*/
|
||||
gr = getgrgid(pw->pw_gid);
|
||||
if (!gr) {
|
||||
fprintf(stderr, "mbpasswd: Cannot determine group name.\n");
|
||||
exit(E_NOPERM);
|
||||
}
|
||||
if (strcmp(gr->gr_name, (char *)"bbs")) {
|
||||
fprintf(stderr, "mbpasswd: You are not a member of group \"bbs\".\n");
|
||||
exit(E_NOPERM);
|
||||
}
|
||||
|
||||
// NOOT dit programma moet kontroleren of het is aangeroepen door mbsebbs.
|
||||
// ook kontroleren of de originele uid en gid correct zijn.
|
||||
// Gewone stervelingen mogen dit niet kunnen starten.
|
||||
// Dit programma is een groot security gat.
|
||||
|
||||
if (argc != 4) {
|
||||
printf("\nmbpasswd commandline:\n\n");
|
||||
printf("mbpasswd [-opt] [username] [newpassword]\n");
|
||||
printf("options are: -n normal password change\n");
|
||||
printf(" -f forced password change\n");
|
||||
exit(E_FAILURE);
|
||||
}
|
||||
|
||||
if (strncmp(argv[1], "-f", 2) == 0) {
|
||||
/*
|
||||
* This is a new user setting his password,
|
||||
* this program runs under account mbse.
|
||||
*/
|
||||
force = 1;
|
||||
if (strcmp(pw->pw_name, (char *)"mbse") && strcmp(pw->pw_name, (char *)"bbs")) {
|
||||
fprintf(stderr, "mbpasswd: only users `mbse' and `bbs' may do this.\n");
|
||||
exit(E_NOPERM);
|
||||
}
|
||||
} else if (strncmp(argv[1], "-n", 2) == 0) {
|
||||
/*
|
||||
* Normal password change by user, check
|
||||
* caller is the user.
|
||||
*/
|
||||
force = 0;
|
||||
if (strcmp(pw->pw_name, argv[2])) {
|
||||
fprintf(stderr, "mbpasswd: only owner may do this.\n");
|
||||
exit(E_NOPERM);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "mbpasswd: wrong option switch.\n");
|
||||
exit(E_FAILURE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check stringlengths
|
||||
*/
|
||||
if (strlen(argv[2]) > 16) {
|
||||
fprintf(stderr, "mbpasswd: Username too long\n");
|
||||
exit(E_FAILURE);
|
||||
}
|
||||
if (strlen(argv[3]) > 16) {
|
||||
fprintf(stderr, "mbpasswd: Password too long\n");
|
||||
exit(E_FAILURE);
|
||||
}
|
||||
|
||||
/*
|
||||
* We don't log into MBSE BBS logfiles but to the system logfiles,
|
||||
* because we are modifying system files not belonging to MBSE BBS.
|
||||
*/
|
||||
openlog("mbpasswd", LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_AUTH);
|
||||
|
||||
name = strdup(argv[2]);
|
||||
if ((pw = getpwnam(name)) == NULL) {
|
||||
syslog(LOG_ERR, "mbpasswd: Unknown user %s", name);
|
||||
fprintf(stderr, "mbpasswd: Unknown user %s\n", name);
|
||||
exit(E_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
#ifdef SHADOW_PASSWORD
|
||||
is_shadow_pwd = spw_file_present();
|
||||
|
||||
sp = getspnam(name);
|
||||
if (!sp)
|
||||
sp = pwd_to_spwd(pw);
|
||||
|
||||
cp = sp->sp_pwdp;
|
||||
#else
|
||||
cp = pw->pw_passwd;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* See if the user is permitted to change the password.
|
||||
* Otherwise, go ahead and set a new password.
|
||||
*/
|
||||
#ifdef SHADOW_PASSWORD
|
||||
check_password(pw, sp);
|
||||
#else
|
||||
check_password(pw);
|
||||
#endif
|
||||
|
||||
if (new_password(pw, argv[3])) {
|
||||
fprintf(stderr, "The password for %s is unchanged.\n", name);
|
||||
syslog(LOG_ERR, "The password for %s is unchanged", name);
|
||||
closelog();
|
||||
exit(E_FAILURE);
|
||||
}
|
||||
do_update_pwd = 1;
|
||||
do_update_age = 1;
|
||||
|
||||
/*
|
||||
* Before going any further, raise the ulimit to prevent
|
||||
* colliding into a lowered ulimit, and set the real UID
|
||||
* to root to protect against unexpected signals. Any
|
||||
* keyboard signals are set to be ignored.
|
||||
*/
|
||||
#ifndef __FreeBSD__
|
||||
pwd_init();
|
||||
#else
|
||||
pw_init();
|
||||
#endif
|
||||
|
||||
if (setuid(0)) {
|
||||
fprintf(stderr, "Cannot change ID to root.\n");
|
||||
syslog(LOG_ERR, "can't setuid(0)");
|
||||
closelog();
|
||||
exit(E_FAILURE);
|
||||
}
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
|
||||
#ifdef HAVE_USERSEC_H
|
||||
update_userpw(pw->pw_passwd);
|
||||
#else /* !HAVE_USERSEC_H */
|
||||
|
||||
#ifdef SHADOW_PASSWORD
|
||||
if (spw_file_present())
|
||||
update_shadow();
|
||||
else
|
||||
#endif
|
||||
update_noshadow(0);
|
||||
#endif /* !HAVE_USERSEC_H */
|
||||
|
||||
#else /* __FreeBSD__ */
|
||||
/*
|
||||
* FreeBSD password change, borrowed from the original FreeBSD sources
|
||||
*/
|
||||
|
||||
/*
|
||||
* Get the new password. Reset passwd change time to zero by
|
||||
* default.
|
||||
*/
|
||||
pw->pw_change = 0;
|
||||
pw->pw_passwd = crypt_passwd;
|
||||
|
||||
pfd = pw_lock();
|
||||
tfd = pw_tmp();
|
||||
pw_copy(pfd, tfd, pw);
|
||||
|
||||
if (!pw_mkdb(pw->pw_name))
|
||||
pw_error((char *)NULL, 0, 1);
|
||||
|
||||
#endif /* __FreeBSD__ */
|
||||
|
||||
syslog(LOG_NOTICE, "password for `%s' changed by user `%s'", name, myname);
|
||||
closelog();
|
||||
exit(E_SUCCESS);
|
||||
}
|
||||
|
||||
|
@@ -1,44 +0,0 @@
|
||||
#ifndef _MBUSERADD_H
|
||||
#define _MBUSERADD_H
|
||||
|
||||
|
||||
/* danger - side effects */
|
||||
#define STRFCPY(A,B) \
|
||||
(strncpy((A), (B), sizeof(A) - 1), (A)[sizeof(A) - 1] = '\0')
|
||||
|
||||
/*
|
||||
* exit status values
|
||||
*/
|
||||
|
||||
#define E_SUCCESS 0 /* success */
|
||||
#define E_NOPERM 1 /* permission denied */
|
||||
#define E_USAGE 2 /* invalid combination of options */
|
||||
#define E_FAILURE 3 /* unexpected failure, nothing done */
|
||||
#define E_MISSING 4 /* unexpected failure, passwd file missing */
|
||||
#define E_PWDBUSY 5 /* passwd file busy, try again later */
|
||||
#define E_BAD_ARG 6 /* invalid argument to option */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Function prototypes
|
||||
*/
|
||||
struct passwd *get_my_pwent(void);
|
||||
static int new_password (const struct passwd *, char *);
|
||||
void pwd_init(void);
|
||||
char *crypt_make_salt(void);
|
||||
char *pw_encrypt(const char *, const char *);
|
||||
int i64c(int);
|
||||
char *l64a(long);
|
||||
#ifndef __FreeBSD__
|
||||
static void fail_exit(int);
|
||||
static void oom(void);
|
||||
static void update_noshadow(int);
|
||||
#endif
|
||||
#ifdef SHADOW_PASSWORD
|
||||
struct spwd *pwd_to_spwd(const struct passwd *);
|
||||
static void update_shadow(void);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@@ -1,287 +0,0 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* File ..................: mbuseradd.c
|
||||
* Purpose ...............: setuid root version of useradd
|
||||
* Last modification date : 25-Aug-2001
|
||||
*
|
||||
*****************************************************************************
|
||||
* 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 <stdlib.h>
|
||||
#include <pwd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include "mbuseradd.h"
|
||||
|
||||
|
||||
|
||||
|
||||
int execute(char *cmd, char *file, char *in, char *out, char *err)
|
||||
{
|
||||
char buf[PATH_MAX];
|
||||
char *vector[16];
|
||||
int i;
|
||||
int pid, status, rc, sverr;
|
||||
|
||||
sprintf(buf, "%s %s", cmd, file);
|
||||
|
||||
i=0;
|
||||
vector[i++] = strtok(buf, " \t\n");
|
||||
while ((vector[i++] = strtok(NULL," \t\n")) && (i < 16));
|
||||
vector[15] = NULL;
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
|
||||
if ((pid = fork()) == 0) {
|
||||
if (in) {
|
||||
close(0);
|
||||
if (open(in, O_RDONLY) != 0) {
|
||||
perror("");
|
||||
fprintf(stderr, "mbuseradd: Reopen of stdin to %s failed\n", in);
|
||||
_exit(-1);
|
||||
}
|
||||
}
|
||||
if (out) {
|
||||
close(1);
|
||||
if (open(out, O_WRONLY | O_APPEND | O_CREAT,0600) != 1) {
|
||||
perror("");
|
||||
fprintf(stderr, "mbuseradd: Reopen of stdout to %s failed\n", out);
|
||||
_exit(-1);
|
||||
}
|
||||
}
|
||||
if (err) {
|
||||
close(2);
|
||||
if (open(err, O_WRONLY | O_APPEND | O_CREAT,0600) != 2) {
|
||||
perror("");
|
||||
fprintf(stderr, "mbuseradd: Reopen of stderr to %s failed\n", err);
|
||||
_exit(-1);
|
||||
}
|
||||
}
|
||||
rc = execv(vector[0],vector);
|
||||
fprintf(stderr, "mbuseradd: Exec \"%s\" returned %d\n", vector[0], rc);
|
||||
_exit(-1);
|
||||
}
|
||||
|
||||
do {
|
||||
rc = wait(&status);
|
||||
sverr = errno;
|
||||
} while (((rc > 0) && (rc != pid)) || ((rc == -1) && (sverr == EINTR)));
|
||||
|
||||
if (rc == -1) {
|
||||
fprintf(stderr, "mbuseradd: Wait returned %d, status %d,%d\n", rc, status >> 8, status & 0xff);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void makedir(char *path, mode_t mode, uid_t owner, gid_t group)
|
||||
{
|
||||
if (mkdir(path, mode) != 0) {
|
||||
perror("");
|
||||
fprintf(stderr, "mbuseradd: Can't create %s\n", path);
|
||||
exit(2);
|
||||
}
|
||||
if ((chown(path, owner, group)) == -1) {
|
||||
perror("");
|
||||
fprintf(stderr, "mbuseradd: Unable to change ownership of %s\n", path);
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Function will create the users name in the passwd file
|
||||
* Note that this function must run setuid root!
|
||||
*/
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *PassEnt, *temp, *shell;
|
||||
int i;
|
||||
struct passwd *pwent, *pwuser;
|
||||
|
||||
if (argc != 5)
|
||||
Help();
|
||||
|
||||
/*
|
||||
* First simple check for argument overflow
|
||||
*/
|
||||
for (i = 1; i < 5; i++) {
|
||||
if (strlen(argv[i]) > 80) {
|
||||
fprintf(stderr, "mbuseradd: Argument %d is too long\n", i);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
PassEnt = calloc(PATH_MAX, sizeof(char));
|
||||
temp = calloc(PATH_MAX, sizeof(char));
|
||||
shell = calloc(PATH_MAX, sizeof(char));
|
||||
|
||||
if (setuid(0) == -1 || setgid(1) == -1) {
|
||||
perror("");
|
||||
fprintf(stderr, "mbuseradd: Unable to setuid(root) or setgid(root)\n");
|
||||
fprintf(stderr, "Make sure that this program is set to -rwsr-sr-x\n");
|
||||
fprintf(stderr, "Owner must be root and group root\n");
|
||||
exit(1);
|
||||
}
|
||||
umask(0000);
|
||||
|
||||
/*
|
||||
* Build command to add user entry to the /etc/passwd and /etc/shadow
|
||||
* files. We use the systems own useradd program.
|
||||
*/
|
||||
#ifdef __linux__
|
||||
if ((access("/usr/bin/useradd", R_OK)) == 0)
|
||||
strcpy(temp, "/usr/bin/useradd");
|
||||
else if ((access("/bin/useradd", R_OK)) == 0)
|
||||
strcpy(temp, "/bin/useradd");
|
||||
else if ((access("/usr/sbin/useradd", R_OK)) == 0)
|
||||
strcpy(temp, "/usr/sbin/useradd");
|
||||
else if ((access("/sbin/useradd", R_OK)) == 0)
|
||||
strcpy(temp, "/sbin/useradd");
|
||||
else {
|
||||
fprintf(stderr, "mbuseradd: Can't find useradd\n");
|
||||
exit(1);
|
||||
}
|
||||
#elif __FreeBSD__
|
||||
if ((access("/usr/sbin/pw", X_OK)) == 0)
|
||||
strcpy(temp, "/usr/sbin/pw");
|
||||
else if ((access("/sbin/pw", X_OK)) == 0)
|
||||
strcpy(temp, "/sbin/pw");
|
||||
else {
|
||||
fprintf(stderr, "mbuseradd: Can't find pw\n");
|
||||
exit(1);
|
||||
}
|
||||
#else
|
||||
fprintf(stderr, "mbuseradd: Don't know how to add a user on this OS\n");
|
||||
exit(1);
|
||||
#endif
|
||||
|
||||
sprintf(shell, "%s/bin/mbsebbs", getenv("MBSE_ROOT"));
|
||||
|
||||
#ifdef __linux__
|
||||
sprintf(PassEnt, "%s -c \"%s\" -d %s/%s -g %s -s %s %s",
|
||||
temp, argv[3], argv[4], argv[2], argv[1], shell, argv[2]);
|
||||
#endif
|
||||
#ifdef __FreeBSD__
|
||||
sprintf(PassEnt, "%s useradd %s -c \"%s\" -d %s/%s -g %s -s %s",
|
||||
temp, argv[2], argv[3], argv[4], argv[2], argv[1], shell);
|
||||
#endif
|
||||
fflush(stdout);
|
||||
fflush(stdin);
|
||||
|
||||
if (system(PassEnt) != 0) {
|
||||
perror("mbuseradd: Failed to create unix account\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now create directories and files for this user.
|
||||
*/
|
||||
if ((pwent = getpwnam((char *)"mbse")) == NULL) {
|
||||
perror("mbuseradd: Can't get password entry for \"mbse\"\n");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check bbs users base home directory
|
||||
*/
|
||||
if ((access(argv[4], R_OK)) != 0)
|
||||
makedir(argv[4], 0770, pwent->pw_uid, pwent->pw_gid);
|
||||
|
||||
/*
|
||||
* Now create users home directory. Check for an existing directory,
|
||||
* some systems have already created a home directory. If one is found
|
||||
* it is removed to create a fresh one.
|
||||
*/
|
||||
sprintf(temp, "%s/%s", argv[4], argv[2]);
|
||||
if ((access(temp, R_OK)) == 0) {
|
||||
if ((access("/bin/rm", X_OK)) == 0)
|
||||
strcpy(shell, "/bin/rm");
|
||||
else if ((access("/usr/bin/rm", X_OK)) == 0)
|
||||
strcpy(shell, "/usr/bin/rm");
|
||||
else {
|
||||
fprintf(stderr, "mbuseradd: Can't find rm\n");
|
||||
exit(2);
|
||||
}
|
||||
sprintf(PassEnt, " -Rf %s", temp);
|
||||
fflush(stdout);
|
||||
fflush(stdin);
|
||||
i = execute(shell, PassEnt, (char *)"/dev/tty", (char *)"/dev/tty", (char *)"/dev/tty");
|
||||
|
||||
if (i != 0) {
|
||||
fprintf(stderr, "mbuseradd: Unable remove old home directory\n");
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Create users home directory.
|
||||
*/
|
||||
pwuser = getpwnam(argv[2]);
|
||||
makedir(temp, 0770, pwuser->pw_uid, pwent->pw_gid);
|
||||
|
||||
/*
|
||||
* Create Maildir and subdirs for Qmail.
|
||||
*/
|
||||
sprintf(temp, "%s/%s/Maildir", argv[4], argv[2]);
|
||||
makedir(temp, 0700, pwuser->pw_uid, pwent->pw_gid);
|
||||
sprintf(temp, "%s/%s/Maildir/cur", argv[4], argv[2]);
|
||||
makedir(temp, 0700, pwuser->pw_uid, pwent->pw_gid);
|
||||
sprintf(temp, "%s/%s/Maildir/new", argv[4], argv[2]);
|
||||
makedir(temp, 0700, pwuser->pw_uid, pwent->pw_gid);
|
||||
sprintf(temp, "%s/%s/Maildir/tmp", argv[4], argv[2]);
|
||||
makedir(temp, 0700, pwuser->pw_uid, pwent->pw_gid);
|
||||
|
||||
free(shell);
|
||||
free(PassEnt);
|
||||
free(temp);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Help()
|
||||
{
|
||||
fprintf(stderr, "\nmbuseradd commandline:\n\n");
|
||||
fprintf(stderr, "mbuseradd [gid] [name] [comment] [usersdir]\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@@ -1,10 +0,0 @@
|
||||
#ifndef _MBUSERADD_H
|
||||
#define _MBUSERADD_H
|
||||
|
||||
|
||||
int execute(char *, char *, char *, char *, char *);
|
||||
void makedir(char *, mode_t, uid_t, gid_t);
|
||||
void Help(void);
|
||||
|
||||
#endif
|
||||
|
@@ -1,72 +0,0 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* File ..................: mbuseradd/myname.c
|
||||
* Purpose ...............: MBSE BBS Shadow Password Suite
|
||||
* Last modification date : 25-Jul-2000
|
||||
* Original Source .......: Shadow Password Suite
|
||||
* Original Copyrioght ...: Julianne Frances Haugh and others.
|
||||
*
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1997-2000
|
||||
*
|
||||
* 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.
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* myname.c - determine the current username and get the passwd entry
|
||||
*
|
||||
* Copyright (C) 1996 Marek Michalkiewicz <marekm@i17linuxb.ists.pwr.wroc.pl>
|
||||
*
|
||||
* This code may be freely used, modified and distributed for any purpose.
|
||||
* There is no warranty, if it breaks you have to keep both pieces, etc.
|
||||
* If you improve it, please send me your changes. Thanks!
|
||||
*/
|
||||
|
||||
#include "../config.h"
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <pwd.h>
|
||||
|
||||
|
||||
struct passwd *get_my_pwent(void)
|
||||
{
|
||||
struct passwd *pw;
|
||||
const char *cp = getlogin();
|
||||
uid_t ruid = getuid();
|
||||
|
||||
/*
|
||||
* Try getlogin() first - if it fails or returns a non-existent
|
||||
* username, or a username which doesn't match the real UID, fall
|
||||
* back to getpwuid(getuid()). This should work reasonably with
|
||||
* usernames longer than the utmp limit (8 characters), as well as
|
||||
* shared UIDs - but not both at the same time...
|
||||
*
|
||||
* XXX - when running from su, will return the current user (not
|
||||
* the original user, like getlogin() does). Does this matter?
|
||||
*/
|
||||
if (cp && *cp && (pw = getpwnam(cp)) && pw->pw_uid == ruid)
|
||||
return pw;
|
||||
|
||||
return getpwuid(ruid);
|
||||
}
|
||||
|
||||
|
@@ -1,7 +0,0 @@
|
||||
#ifndef _MYNAME_H
|
||||
#define _MYNAME_H
|
||||
|
||||
struct passwd *get_my_pwent(void);
|
||||
|
||||
#endif
|
||||
|
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright 1989 - 1994, Julianne Frances Haugh
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "../config.h"
|
||||
#ifndef HAVE_PUTPWENT
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <pwd.h>
|
||||
#include "putpwent.h"
|
||||
|
||||
/*
|
||||
* putpwent - Output a (struct passwd) in character format
|
||||
*
|
||||
* putpwent() writes out a (struct passwd) in the format it appears
|
||||
* in in flat ASCII files.
|
||||
*
|
||||
* (Author: Dr. Micheal Newberry)
|
||||
*/
|
||||
|
||||
int putpwent(const struct passwd *p, FILE *f)
|
||||
{
|
||||
int status;
|
||||
|
||||
#if defined(SUN) || defined(BSD) || defined(SUN4)
|
||||
status = fprintf (f, "%s:%s:%d:%d:%s,%s:%s:%s\n",
|
||||
p->pw_name, p->pw_passwd, p->pw_uid, p->pw_gid,
|
||||
p->pw_gecos, p->pw_comment, p->pw_dir, p->pw_shell) == EOF;
|
||||
#else
|
||||
status = fprintf (f, "%s:%s", p->pw_name, p->pw_passwd) == EOF;
|
||||
#ifdef ATT_AGE
|
||||
if (p->pw_age && p->pw_age[0])
|
||||
status |= fprintf (f, ",%s", p->pw_age) == EOF;
|
||||
#endif
|
||||
status |= fprintf (f, ":%d:%d:%s", p->pw_uid, p->pw_gid,
|
||||
p->pw_gecos) == EOF;
|
||||
#ifdef ATT_COMMENT
|
||||
if (p->pw_comment && p->pw_comment[0])
|
||||
status |= fprintf (f, ",%s", p->pw_comment) == EOF;
|
||||
#endif
|
||||
status |= fprintf (f, ":%s:%s\n", p->pw_dir, p->pw_shell) == EOF;
|
||||
#endif
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -1,14 +0,0 @@
|
||||
#include "../config.h"
|
||||
|
||||
#ifndef HAVE_PUTPWENT
|
||||
|
||||
#ifndef _PUTPWENT_H
|
||||
#define _PUTPWENT_H
|
||||
|
||||
|
||||
int putpwent(const struct passwd *, FILE *);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
@@ -1,309 +0,0 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* $Id$
|
||||
* Purpose ...............: FreeBSD password utilities.
|
||||
* Remark ................: Taken from FreeBSD and modified for MBSE BBS.
|
||||
*
|
||||
*****************************************************************************
|
||||
* 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.
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1990, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <syslog.h>
|
||||
#include <err.h>
|
||||
#include <fcntl.h>
|
||||
#include <paths.h>
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "pw_util.h"
|
||||
|
||||
char *tempname;
|
||||
static int lockfd;
|
||||
|
||||
|
||||
|
||||
void pw_init()
|
||||
{
|
||||
struct rlimit rlim;
|
||||
|
||||
/* Unlimited resource limits. */
|
||||
rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
|
||||
(void)setrlimit(RLIMIT_CPU, &rlim);
|
||||
(void)setrlimit(RLIMIT_FSIZE, &rlim);
|
||||
(void)setrlimit(RLIMIT_STACK, &rlim);
|
||||
(void)setrlimit(RLIMIT_DATA, &rlim);
|
||||
(void)setrlimit(RLIMIT_RSS, &rlim);
|
||||
|
||||
/* Don't drop core (not really necessary, but GP's). */
|
||||
rlim.rlim_cur = rlim.rlim_max = 0;
|
||||
(void)setrlimit(RLIMIT_CORE, &rlim);
|
||||
|
||||
/* Turn off signals. */
|
||||
(void)signal(SIGALRM, SIG_IGN);
|
||||
(void)signal(SIGHUP, SIG_IGN);
|
||||
(void)signal(SIGINT, SIG_IGN);
|
||||
(void)signal(SIGPIPE, SIG_IGN);
|
||||
(void)signal(SIGQUIT, SIG_IGN);
|
||||
(void)signal(SIGTERM, SIG_IGN);
|
||||
|
||||
/* Create with exact permissions. */
|
||||
(void)umask(0);
|
||||
}
|
||||
|
||||
|
||||
int pw_lock()
|
||||
{
|
||||
/*
|
||||
* If the master password file doesn't exist, the system is hosed.
|
||||
* Might as well try to build one. Set the close-on-exec bit so
|
||||
* that users can't get at the encrypted passwords while editing.
|
||||
* Open should allow flock'ing the file; see 4.4BSD. XXX
|
||||
*/
|
||||
for (;;) {
|
||||
struct stat st;
|
||||
|
||||
lockfd = open(_PATH_MASTERPASSWD, O_RDONLY, 0);
|
||||
if (lockfd < 0 || fcntl(lockfd, F_SETFD, 1) == -1) {
|
||||
syslog(LOG_ERR, "%s", _PATH_MASTERPASSWD);
|
||||
fprintf(stderr, "%s: %s\n", strerror(errno), _PATH_MASTERPASSWD);
|
||||
exit(1);
|
||||
}
|
||||
if (flock(lockfd, LOCK_EX|LOCK_NB)) {
|
||||
syslog(LOG_ERR, "the password db file is busy");
|
||||
fprintf(stderr, "the password db file is busy\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the password file was replaced while we were trying to
|
||||
* get the lock, our hardlink count will be 0 and we have to
|
||||
* close and retry.
|
||||
*/
|
||||
if (fstat(lockfd, &st) < 0) {
|
||||
syslog(LOG_ERR, "fstat() failed");
|
||||
fprintf(stderr, "%s: %s\n", strerror(errno), "fstat() failed");
|
||||
exit(1);
|
||||
}
|
||||
if (st.st_nlink != 0)
|
||||
break;
|
||||
close(lockfd);
|
||||
lockfd = -1;
|
||||
}
|
||||
return (lockfd);
|
||||
}
|
||||
|
||||
|
||||
int pw_tmp()
|
||||
{
|
||||
static char path[MAXPATHLEN] = _PATH_MASTERPASSWD;
|
||||
int fd;
|
||||
char *p;
|
||||
|
||||
if ((p = strrchr(path, '/')))
|
||||
++p;
|
||||
else
|
||||
p = path;
|
||||
strcpy(p, "pw.XXXXXX");
|
||||
if ((fd = mkstemp(path)) == -1) {
|
||||
syslog(LOG_ERR, "%s", path);
|
||||
fprintf(stderr, "%s: %s\n", strerror(errno), path);
|
||||
exit(1);
|
||||
}
|
||||
tempname = path;
|
||||
return (fd);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int pw_mkdb(char *username)
|
||||
{
|
||||
int pstat;
|
||||
pid_t pid;
|
||||
|
||||
(void)fflush(stderr);
|
||||
if (!(pid = fork())) {
|
||||
if(!username) {
|
||||
syslog(LOG_WARNING, "rebuilding the database...");
|
||||
execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", tempname, NULL);
|
||||
} else {
|
||||
syslog(LOG_WARNING, "updating the database...");
|
||||
execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", "-u", username, tempname, NULL);
|
||||
}
|
||||
pw_error((char *)_PATH_PWD_MKDB, 1, 1);
|
||||
}
|
||||
pid = waitpid(pid, &pstat, 0);
|
||||
if (pid == -1 || !WIFEXITED(pstat) || WEXITSTATUS(pstat) != 0)
|
||||
return (0);
|
||||
syslog(LOG_WARNING, "done");
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void pw_error(char *name, int errn, int eval)
|
||||
{
|
||||
#ifdef YP
|
||||
extern int _use_yp;
|
||||
#endif /* YP */
|
||||
if (errn)
|
||||
syslog(LOG_WARNING, name);
|
||||
#ifdef YP
|
||||
if (_use_yp)
|
||||
syslog(LOG_WARNING, "NIS information unchanged");
|
||||
else
|
||||
#endif /* YP */
|
||||
syslog(LOG_WARNING, "%s: unchanged", _PATH_MASTERPASSWD);
|
||||
(void)unlink(tempname);
|
||||
exit(eval);
|
||||
}
|
||||
|
||||
|
||||
void pw_copy(int ffd, int tfd, struct passwd *pw)
|
||||
{
|
||||
FILE *from, *to;
|
||||
int done;
|
||||
char *p, buf[8192];
|
||||
char uidstr[20];
|
||||
char gidstr[20];
|
||||
char chgstr[20];
|
||||
char expstr[20];
|
||||
|
||||
snprintf(uidstr, sizeof(uidstr), "%d", pw->pw_uid);
|
||||
snprintf(gidstr, sizeof(gidstr), "%d", pw->pw_gid);
|
||||
snprintf(chgstr, sizeof(chgstr), "%ld", (long)pw->pw_change);
|
||||
snprintf(expstr, sizeof(expstr), "%ld", (long)pw->pw_expire);
|
||||
|
||||
if (!(from = fdopen(ffd, "r")))
|
||||
pw_error((char *)_PATH_MASTERPASSWD, 1, 1);
|
||||
if (!(to = fdopen(tfd, "w")))
|
||||
pw_error(tempname, 1, 1);
|
||||
|
||||
for (done = 0; fgets(buf, sizeof(buf), from);) {
|
||||
if (!strchr(buf, '\n')) {
|
||||
syslog(LOG_WARNING, "%s: line too long", _PATH_MASTERPASSWD);
|
||||
pw_error(NULL, 0, 1);
|
||||
}
|
||||
if (done) {
|
||||
(void)fprintf(to, "%s", buf);
|
||||
if (ferror(to))
|
||||
goto err;
|
||||
continue;
|
||||
}
|
||||
if (!(p = strchr(buf, ':'))) {
|
||||
syslog(LOG_WARNING, "%s: corrupted entry", _PATH_MASTERPASSWD);
|
||||
pw_error(NULL, 0, 1);
|
||||
}
|
||||
*p = '\0';
|
||||
if (strcmp(buf, pw->pw_name)) {
|
||||
*p = ':';
|
||||
(void)fprintf(to, "%s", buf);
|
||||
if (ferror(to))
|
||||
goto err;
|
||||
continue;
|
||||
}
|
||||
(void)fprintf(to, "%s:%s:%s:%s:%s:%s:%s:%s:%s:%s\n",
|
||||
pw->pw_name, pw->pw_passwd,
|
||||
pw->pw_fields & _PWF_UID ? uidstr : "",
|
||||
pw->pw_fields & _PWF_GID ? gidstr : "",
|
||||
pw->pw_class,
|
||||
pw->pw_fields & _PWF_CHANGE ? chgstr : "",
|
||||
pw->pw_fields & _PWF_EXPIRE ? expstr : "",
|
||||
pw->pw_gecos, pw->pw_dir, pw->pw_shell);
|
||||
done = 1;
|
||||
if (ferror(to))
|
||||
goto err;
|
||||
}
|
||||
if (!done) {
|
||||
#ifdef YP
|
||||
/* Ultra paranoid: shouldn't happen. */
|
||||
if (getuid()) {
|
||||
syslog(LOG_WARNING, "%s: not found in %s -- permission denied",
|
||||
pw->pw_name, _PATH_MASTERPASSWD);
|
||||
pw_error(NULL, 0, 1);
|
||||
} else
|
||||
#endif /* YP */
|
||||
(void)fprintf(to, "%s:%s:%s:%s:%s:%s:%s:%s:%s:%s\n",
|
||||
pw->pw_name, pw->pw_passwd,
|
||||
pw->pw_fields & _PWF_UID ? uidstr : "",
|
||||
pw->pw_fields & _PWF_GID ? gidstr : "",
|
||||
pw->pw_class,
|
||||
pw->pw_fields & _PWF_CHANGE ? chgstr : "",
|
||||
pw->pw_fields & _PWF_EXPIRE ? expstr : "",
|
||||
pw->pw_gecos, pw->pw_dir, pw->pw_shell);
|
||||
}
|
||||
|
||||
if (ferror(to))
|
||||
err: pw_error(NULL, 1, 1);
|
||||
(void)fclose(to);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
@@ -1,52 +0,0 @@
|
||||
/* $Id$
|
||||
*
|
||||
* Copyright (c) 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)pw_util.h 8.2 (Berkeley) 4/1/94
|
||||
*/
|
||||
|
||||
#ifndef _PW_UTIL_H
|
||||
#define _PW_UTIL_H
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
|
||||
void pw_error __P((char *, int, int));
|
||||
void pw_init __P((void));
|
||||
int pw_lock __P((void));
|
||||
int pw_mkdb __P((char *));
|
||||
int pw_tmp __P((void));
|
||||
void pw_copy __P((int, int, struct passwd *));
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
135
mbsebbs/pwauth.c
135
mbsebbs/pwauth.c
@@ -1,135 +0,0 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* $Id$
|
||||
* Purpose ...............: MBSE BBS Shadow Password Suite
|
||||
* Original Source .......: Shadow Password Suite
|
||||
* Original Copyright ....: Julianne Frances Haugh and others.
|
||||
*
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1997-2002
|
||||
*
|
||||
* 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 <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include "mblogin.h"
|
||||
#include "pwauth.h"
|
||||
#include "getdef.h"
|
||||
#include "encrypt.h"
|
||||
|
||||
|
||||
/* standard password prompt by default */
|
||||
static const char *PROMPT = gettext_noop("Password: ");
|
||||
int wipe_clear_pass = 1;
|
||||
char *clear_pass = NULL;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/*
|
||||
* WARNING:
|
||||
*
|
||||
* When we change a password and we are root, we don't prompt.
|
||||
* This is so root can change any password without having to
|
||||
* know it. This is a policy decision that might have to be
|
||||
* revisited.
|
||||
*/
|
||||
if (reason == PW_CHANGE && getuid () == 0)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* WARNING:
|
||||
*
|
||||
* When we are logging in a user with no ciphertext password,
|
||||
* we don't prompt for the password or anything. In reality
|
||||
* the user could just hit <ENTER>, so it doesn't really
|
||||
* matter.
|
||||
*/
|
||||
if (cipher == (char *) 0 || *cipher == '\0')
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Prompt for the password as required. FTPD and REXECD both
|
||||
* get the cleartext password for us.
|
||||
*/
|
||||
if (reason != PW_FTP && reason != PW_REXEC && !input) {
|
||||
cp = PROMPT;
|
||||
snprintf(prompt, sizeof prompt, cp, user);
|
||||
clear = getpass(prompt);
|
||||
if (!clear) {
|
||||
static char c[1];
|
||||
c[0] = '\0';
|
||||
clear = c;
|
||||
}
|
||||
input = clear;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert the cleartext password into a ciphertext string.
|
||||
* If the two match, the return value will be zero, which is
|
||||
* SUCCESS. Otherwise we see if SKEY is being used and check
|
||||
* the results there as well.
|
||||
*/
|
||||
retval = strcmp(pw_encrypt(input, cipher), cipher);
|
||||
|
||||
/*
|
||||
* Things like RADIUS authentication may need the password -
|
||||
* if the external variable wipe_clear_pass is zero, we will
|
||||
* not wipe it (the caller should wipe clear_pass when it is
|
||||
* no longer needed). --marekm
|
||||
*/
|
||||
|
||||
clear_pass = clear;
|
||||
if (wipe_clear_pass && clear && *clear)
|
||||
strzero(clear);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@@ -1,31 +0,0 @@
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef _PWAUTH_H
|
||||
#define _PWAUTH_H
|
||||
|
||||
int pw_auth(const char *program,const char *user,int flag,const char *input);
|
||||
|
||||
|
||||
/*
|
||||
* Local access
|
||||
*/
|
||||
#define PW_SU 1
|
||||
#define PW_LOGIN 2
|
||||
|
||||
/*
|
||||
* Administrative functions
|
||||
*/
|
||||
#define PW_ADD 101
|
||||
#define PW_CHANGE 102
|
||||
#define PW_DELETE 103
|
||||
|
||||
/*
|
||||
* Network access
|
||||
*/
|
||||
#define PW_TELNET 201
|
||||
#define PW_RLOGIN 202
|
||||
#define PW_FTP 203
|
||||
#define PW_REXEC 204
|
||||
|
||||
#endif
|
||||
|
@@ -1,98 +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 <pwd.h>
|
||||
#include <syslog.h>
|
||||
#include "pwauth.h"
|
||||
#include "pwdcheck.h"
|
||||
|
||||
|
||||
#ifdef HAVE_SHADOW_H
|
||||
#include <shadow.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_PAM
|
||||
// #include "pam_defs.h"
|
||||
#endif
|
||||
|
||||
#define WRONGPWD2 "incorrect password for `%s'"
|
||||
|
||||
void passwd_check(const char *user, const char *passwd, const char *progname)
|
||||
{
|
||||
#ifdef USE_PAM
|
||||
pam_handle_t *pamh = NULL;
|
||||
int retcode;
|
||||
struct pam_conv conv = { misc_conv, NULL };
|
||||
|
||||
if (pam_start(progname, user, &conv, &pamh)) {
|
||||
bailout:
|
||||
SYSLOG((LOG_WARN, WRONGPWD2, user));
|
||||
sleep(1);
|
||||
fprintf(stderr, "Incorrect password for %s.\n", user);
|
||||
exit(1);
|
||||
}
|
||||
if (pam_authenticate(pamh, 0))
|
||||
goto bailout;
|
||||
|
||||
retcode = pam_acct_mgmt(pamh, 0);
|
||||
if (retcode == PAM_NEW_AUTHTOK_REQD) {
|
||||
retcode = pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK);
|
||||
} else if (retcode)
|
||||
goto bailout;
|
||||
|
||||
if (pam_setcred(pamh, 0))
|
||||
goto bailout;
|
||||
|
||||
/* no need to establish a session; this isn't a session-oriented
|
||||
* activity... */
|
||||
|
||||
#else /* !USE_PAM */
|
||||
|
||||
#ifdef SHADOW_PASSWORD
|
||||
struct spwd *sp;
|
||||
|
||||
if ((sp = getspnam(user)))
|
||||
passwd = sp->sp_pwdp;
|
||||
endspent();
|
||||
#endif
|
||||
if (pw_auth(passwd, user, PW_LOGIN, (char *) 0) != 0) {
|
||||
syslog(LOG_WARNING, WRONGPWD2, user);
|
||||
sleep(1);
|
||||
fprintf(stderr, "Incorrect password for %s.\n", user);
|
||||
exit(1);
|
||||
}
|
||||
#endif /* !USE_PAM */
|
||||
}
|
||||
|
@@ -1,8 +0,0 @@
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef _PWDCHECK_H
|
||||
#define _PWDCHECK_H
|
||||
|
||||
void passwd_check(const char *, const char *, const char *);
|
||||
|
||||
#endif
|
250
mbsebbs/pwio.c
250
mbsebbs/pwio.c
@@ -1,250 +0,0 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* File ..................: mbuseradd/pwio.c
|
||||
* Purpose ...............: MBSE BBS Shadow Password Suite
|
||||
* Last modification date : 09-Aug-2001
|
||||
* 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.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
|
||||
#include "../config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <pwd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include "sgetpwent.h"
|
||||
#include "commonio.h"
|
||||
#ifndef HAVE_PUTPWENT
|
||||
#include "putpwent.h"
|
||||
#endif
|
||||
#include "pwio.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct passwd *__pw_dup(const struct passwd *pwent)
|
||||
{
|
||||
struct passwd *pw;
|
||||
|
||||
if (!(pw = (struct passwd *) malloc(sizeof *pw)))
|
||||
return NULL;
|
||||
*pw = *pwent;
|
||||
if (!(pw->pw_name = strdup(pwent->pw_name)))
|
||||
return NULL;
|
||||
if (!(pw->pw_passwd = strdup(pwent->pw_passwd)))
|
||||
return NULL;
|
||||
#ifdef ATT_AGE
|
||||
if (!(pw->pw_age = strdup(pwent->pw_age)))
|
||||
return NULL;
|
||||
#endif
|
||||
#ifdef ATT_COMMENT
|
||||
if (!(pw->pw_comment = strdup(pwent->pw_comment)))
|
||||
return NULL;
|
||||
#endif
|
||||
if (!(pw->pw_gecos = strdup(pwent->pw_gecos)))
|
||||
return NULL;
|
||||
if (!(pw->pw_dir = strdup(pwent->pw_dir)))
|
||||
return NULL;
|
||||
if (!(pw->pw_shell = strdup(pwent->pw_shell)))
|
||||
return NULL;
|
||||
return pw;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void *passwd_dup(const void *ent)
|
||||
{
|
||||
const struct passwd *pw = ent;
|
||||
return __pw_dup(pw);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void passwd_free(void *ent)
|
||||
{
|
||||
struct passwd *pw = ent;
|
||||
|
||||
free(pw->pw_name);
|
||||
free(pw->pw_passwd);
|
||||
#ifdef ATT_AGE
|
||||
free(pw->pw_age);
|
||||
#endif
|
||||
#ifdef ATT_COMMENT
|
||||
free(pw->pw_comment);
|
||||
#endif
|
||||
free(pw->pw_gecos);
|
||||
free(pw->pw_dir);
|
||||
free(pw->pw_shell);
|
||||
free(pw);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const char *passwd_getname(const void *ent)
|
||||
{
|
||||
const struct passwd *pw = ent;
|
||||
return pw->pw_name;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void *passwd_parse(const char *line)
|
||||
{
|
||||
return (void *) sgetpwent(line);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int passwd_put(const void *ent, FILE *file)
|
||||
{
|
||||
const struct passwd *pw = ent;
|
||||
return (putpwent(pw, file) == -1) ? -1 : 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static struct commonio_ops passwd_ops = {
|
||||
passwd_dup,
|
||||
passwd_free,
|
||||
passwd_getname,
|
||||
passwd_parse,
|
||||
passwd_put,
|
||||
fgets,
|
||||
fputs
|
||||
};
|
||||
|
||||
|
||||
|
||||
static struct commonio_db passwd_db = {
|
||||
PASSWD_FILE, /* filename */
|
||||
&passwd_ops, /* ops */
|
||||
NULL, /* fp */
|
||||
NULL, /* head */
|
||||
NULL, /* tail */
|
||||
NULL, /* cursor */
|
||||
0, /* changed */
|
||||
0, /* isopen */
|
||||
0, /* locked */
|
||||
0, /* readonly */
|
||||
1 /* use_lckpwdf */
|
||||
};
|
||||
|
||||
|
||||
|
||||
int pw_name(const char *filename)
|
||||
{
|
||||
return commonio_setname(&passwd_db, filename);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
int pw_lock(void)
|
||||
{
|
||||
return commonio_lock(&passwd_db);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
int pw_open(int mode)
|
||||
{
|
||||
return commonio_open(&passwd_db, mode);
|
||||
}
|
||||
|
||||
|
||||
|
||||
const struct passwd *pw_locate(const char *name)
|
||||
{
|
||||
return commonio_locate(&passwd_db, name);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int pw_update(const struct passwd *pw)
|
||||
{
|
||||
return commonio_update(&passwd_db, (const void *) pw);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int pw_remove(const char *name)
|
||||
{
|
||||
return commonio_remove(&passwd_db, name);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int pw_rewind(void)
|
||||
{
|
||||
return commonio_rewind(&passwd_db);
|
||||
}
|
||||
|
||||
|
||||
|
||||
const struct passwd *pw_next(void)
|
||||
{
|
||||
return commonio_next(&passwd_db);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int pw_close(void)
|
||||
{
|
||||
return commonio_close(&passwd_db);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int pw_unlock(void)
|
||||
{
|
||||
return commonio_unlock(&passwd_db);
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct commonio_entry *__pw_get_head(void)
|
||||
{
|
||||
return passwd_db.head;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void __pw_del_entry(const struct commonio_entry *ent)
|
||||
{
|
||||
commonio_del_entry(&passwd_db, ent);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -1,33 +0,0 @@
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef _PWIO_H
|
||||
#define _PWIO_H
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
|
||||
#ifndef PASSWD_FILE
|
||||
#define PASSWD_FILE "/etc/passwd"
|
||||
#endif
|
||||
|
||||
#ifndef GROUP_FILE
|
||||
#define GROUP_FILE "/etc/group"
|
||||
#endif
|
||||
|
||||
struct passwd *__pw_dup (const struct passwd *);
|
||||
void __pw_set_changed (void);
|
||||
int pw_close (void);
|
||||
const struct passwd *pw_locate (const char *);
|
||||
int pw_lock (void);
|
||||
int pw_lock_first (void);
|
||||
int pw_name (const char *);
|
||||
const struct passwd *pw_next (void);
|
||||
int pw_open (int);
|
||||
int pw_remove (const char *);
|
||||
int pw_rewind (void);
|
||||
int pw_unlock (void);
|
||||
int pw_update (const struct passwd *);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
157
mbsebbs/rad64.c
157
mbsebbs/rad64.c
@@ -1,157 +0,0 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* File ..................: mbuseradd/rad64c.c
|
||||
* Purpose ...............: MBSE BBS Shadow Password Suite
|
||||
* Last modification date : 25-Sep-2000
|
||||
* Original Source .......: Shadow Password Suite
|
||||
* Original Copyrioght ...: Julianne Frances Haugh and others.
|
||||
*
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1997-2000
|
||||
*
|
||||
* 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.
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright 1989 - 1992, Julianne Frances Haugh
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "../config.h"
|
||||
#include "rad64.h"
|
||||
|
||||
|
||||
#ifndef HAVE_C64I
|
||||
/*
|
||||
* c64i - convert a radix 64 character to an integer
|
||||
*/
|
||||
int c64i(char c)
|
||||
{
|
||||
if (c == '.')
|
||||
return (0);
|
||||
|
||||
if (c == '/')
|
||||
return (1);
|
||||
|
||||
if (c >= '0' && c <= '9')
|
||||
return (c - '0' + 2);
|
||||
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
return (c - 'A' + 12);
|
||||
|
||||
if (c >= 'a' && c <= 'z')
|
||||
return (c - 'a' + 38);
|
||||
else
|
||||
return (-1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* i64c - convert an integer to a radix 64 character
|
||||
*/
|
||||
int i64c(int i)
|
||||
{
|
||||
if (i <= 0)
|
||||
return ('.');
|
||||
|
||||
if (i == 1)
|
||||
return ('/');
|
||||
|
||||
if (i >= 2 && i < 12)
|
||||
return ('0' - 2 + i);
|
||||
|
||||
if (i >= 12 && i < 38)
|
||||
return ('A' - 12 + i);
|
||||
|
||||
if (i >= 38 && i < 63)
|
||||
return ('a' - 38 + i);
|
||||
|
||||
return ('z');
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef HAVE_A64L
|
||||
/*
|
||||
* l64a - convert a long to a string of radix 64 characters
|
||||
*/
|
||||
char *l64a(long l)
|
||||
{
|
||||
static char buf[8];
|
||||
int i = 0;
|
||||
|
||||
if (l < 0L)
|
||||
return ((char *) 0);
|
||||
|
||||
do {
|
||||
buf[i++] = i64c ((int) (l % 64));
|
||||
buf[i] = '\0';
|
||||
} while (l /= 64L, l > 0 && i < 6);
|
||||
|
||||
return (buf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* a64l - convert a radix 64 string to a long integer
|
||||
*/
|
||||
long a64l(const char *s)
|
||||
{
|
||||
int i;
|
||||
long value;
|
||||
long shift = 0;
|
||||
|
||||
for (i = 0, value = 0L;i < 6 && *s;s++) {
|
||||
value += (c64i (*s) << shift);
|
||||
shift += 6;
|
||||
}
|
||||
return (value);
|
||||
}
|
||||
|
||||
#endif /* !HAVE_A64L */
|
||||
|
@@ -1,15 +0,0 @@
|
||||
#ifndef _RAD64_H
|
||||
#define _RAD64_H
|
||||
|
||||
|
||||
#ifndef HAVE_C64I
|
||||
int c64i(char);
|
||||
int i64c(int);
|
||||
#endif
|
||||
#ifndef HAVE_A64L
|
||||
char *l64a(long);
|
||||
long a64l(const char *);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
103
mbsebbs/salt.c
103
mbsebbs/salt.c
@@ -1,103 +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.
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* salt.c - generate a random salt string for crypt()
|
||||
*
|
||||
* Written by Marek Michalkiewicz <marekm@i17linuxb.ists.pwr.wroc.pl>,
|
||||
* public domain.
|
||||
*/
|
||||
#include "../config.h"
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef TIME_WITH_SYS_TIME
|
||||
#include <time.h>
|
||||
#endif
|
||||
#include <sys/time.h>
|
||||
#include "rad64.h"
|
||||
|
||||
|
||||
#if 1
|
||||
#include "getdef.h"
|
||||
|
||||
|
||||
/*
|
||||
* Generate 8 base64 ASCII characters of random salt. If MD5_CRYPT_ENAB
|
||||
* in /etc/login.defs is "yes", the salt string will be prefixed by "$1$"
|
||||
* (magic) and pw_encrypt() will execute the MD5-based FreeBSD-compatible
|
||||
* version of crypt() instead of the standard one.
|
||||
*/
|
||||
char *crypt_make_salt(void)
|
||||
{
|
||||
struct timeval tv;
|
||||
static char result[40];
|
||||
|
||||
result[0] = '\0';
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
if (getdef_bool("MD5_CRYPT_ENAB")) {
|
||||
strcpy(result, "$1$"); /* magic for the new MD5 crypt() */
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Generate 8 chars of salt, the old crypt() will use only first 2.
|
||||
*/
|
||||
gettimeofday(&tv, (struct timezone *) 0);
|
||||
strcat(result, l64a(tv.tv_usec));
|
||||
strcat(result, l64a(tv.tv_sec + getpid() + clock()));
|
||||
|
||||
if (strlen(result) > 3 + 8) /* magic+salt */
|
||||
result[11] = '\0';
|
||||
|
||||
return result;
|
||||
}
|
||||
#else
|
||||
|
||||
/*
|
||||
* This is the old style random salt generator...
|
||||
*/
|
||||
char *crypt_make_salt(void)
|
||||
{
|
||||
time_t now;
|
||||
static unsigned long x;
|
||||
static char result[3];
|
||||
|
||||
now = time(NULL);
|
||||
x += now + getpid() + clock();
|
||||
result[0] = i64c(((x >> 18) ^ (x >> 6)) & 077);
|
||||
result[1] = i64c(((x >> 12) ^ x) & 077);
|
||||
result[2] = '\0';
|
||||
return result;
|
||||
}
|
||||
#endif
|
@@ -1,9 +0,0 @@
|
||||
#ifndef _SALT_H
|
||||
#define _SALT_H
|
||||
|
||||
|
||||
char *crypt_make_salt(void);
|
||||
|
||||
|
||||
#endif
|
||||
|
@@ -1,120 +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.
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Separated from setup.c. --marekm
|
||||
*/
|
||||
|
||||
#include "../config.h"
|
||||
#include <stdio.h>
|
||||
#include <grp.h>
|
||||
#include <syslog.h>
|
||||
#include "mblogin.h"
|
||||
#include <pwd.h>
|
||||
#include "getdef.h"
|
||||
#include "setugid.h"
|
||||
|
||||
|
||||
/*
|
||||
* setup_uid_gid() split in two functions for PAM support -
|
||||
* pam_setcred() needs to be called after initgroups(), but
|
||||
* before setuid().
|
||||
*/
|
||||
|
||||
int setup_groups(const struct passwd *info)
|
||||
{
|
||||
/*
|
||||
* Set the real group ID to the primary group ID in the password
|
||||
* file.
|
||||
*/
|
||||
if (setgid (info->pw_gid) == -1) {
|
||||
perror("setgid");
|
||||
syslog(LOG_ERR, "bad group ID `%d' for user `%s': %m\n", info->pw_gid, info->pw_name);
|
||||
closelog();
|
||||
return -1;
|
||||
}
|
||||
#ifdef HAVE_INITGROUPS
|
||||
/*
|
||||
* For systems which support multiple concurrent groups, go get
|
||||
* the group set from the /etc/group file.
|
||||
*/
|
||||
if (initgroups(info->pw_name, info->pw_gid) == -1) {
|
||||
perror("initgroups");
|
||||
syslog(LOG_ERR, "initgroups failed for user `%s': %m\n", info->pw_name);
|
||||
closelog();
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int change_uid(const struct passwd *info)
|
||||
{
|
||||
/*
|
||||
* Set the real UID to the UID value in the password file.
|
||||
*/
|
||||
#ifndef BSD
|
||||
if (setuid(info->pw_uid))
|
||||
#else
|
||||
if (setreuid(info->pw_uid, info->pw_uid))
|
||||
#endif
|
||||
{
|
||||
perror("setuid");
|
||||
syslog(LOG_ERR, "bad user ID `%d' for user `%s': %m\n", (int) info->pw_uid, info->pw_name);
|
||||
closelog();
|
||||
return -1;
|
||||
}
|
||||
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
|
||||
*
|
||||
* 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;
|
||||
|
||||
if (change_uid(info) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
@@ -1,10 +0,0 @@
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef _SETUGID_H
|
||||
#define _SETUGID_H
|
||||
|
||||
int setup_groups(const struct passwd *);
|
||||
int change_uid(const struct passwd *);
|
||||
int setup_uid_gid(const struct passwd *, int);
|
||||
|
||||
#endif
|
@@ -1,156 +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.
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Separated from setup.c. --marekm
|
||||
*/
|
||||
|
||||
#include "../config.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <syslog.h>
|
||||
#include "mblogin.h"
|
||||
#include <pwd.h>
|
||||
#include "getdef.h"
|
||||
#include "xmalloc.h"
|
||||
#include "env.h"
|
||||
#include "setupenv.h"
|
||||
|
||||
|
||||
|
||||
void addenv_path(const char *varname, const char *dirname, const char *filename)
|
||||
{
|
||||
char *buf;
|
||||
|
||||
buf = xmalloc(strlen(dirname) + strlen(filename) + 2);
|
||||
sprintf(buf, "%s/%s", dirname, filename);
|
||||
addenv(varname, buf);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void read_env_file(const char *filename)
|
||||
{
|
||||
FILE *fp;
|
||||
char buf[1024];
|
||||
char *cp, *name, *val;
|
||||
|
||||
fp = fopen(filename, "r");
|
||||
if (!fp)
|
||||
return;
|
||||
while (fgets(buf, sizeof buf, fp) == buf) {
|
||||
cp = strrchr(buf, '\n');
|
||||
if (!cp)
|
||||
break;
|
||||
*cp = '\0';
|
||||
|
||||
cp = buf;
|
||||
/* ignore whitespace and comments */
|
||||
while (*cp && isspace(*cp))
|
||||
cp++;
|
||||
if (*cp == '\0' || *cp == '#')
|
||||
continue;
|
||||
/*
|
||||
* ignore lines which don't follow the name=value format
|
||||
* (for example, the "export NAME" shell commands)
|
||||
*/
|
||||
name = cp;
|
||||
while (*cp && !isspace(*cp) && *cp != '=')
|
||||
cp++;
|
||||
if (*cp != '=')
|
||||
continue;
|
||||
/* NUL-terminate the name */
|
||||
*cp++ = '\0';
|
||||
val = cp;
|
||||
addenv(name, val);
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
/*
|
||||
* Change the current working directory to be the home directory
|
||||
* of the user. It is a fatal error for this process to be unable
|
||||
* to change to that directory. There is no "default" home
|
||||
* directory.
|
||||
*
|
||||
* We no longer do it as root - should work better on NFS-mounted
|
||||
* home directories.
|
||||
*/
|
||||
if (chdir(info->pw_dir) == -1) {
|
||||
fprintf(stderr, _("Unable to cd to \"%s\"\n"), info->pw_dir);
|
||||
syslog(LOG_WARNING, "unable to cd to `%s' for user `%s'\n", info->pw_dir, info->pw_name);
|
||||
closelog();
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the HOME environmental variable and export it.
|
||||
*/
|
||||
addenv("HOME", info->pw_dir);
|
||||
|
||||
/*
|
||||
* Create the SHELL environmental variable and export it.
|
||||
*/
|
||||
if (info->pw_shell == (char *) 0 || ! *info->pw_shell) {
|
||||
static char temp_pw_shell[] = "/bin/sh";
|
||||
info->pw_shell = temp_pw_shell;
|
||||
}
|
||||
|
||||
addenv("SHELL", info->pw_shell);
|
||||
|
||||
/*
|
||||
* Create the PATH environmental variable and export it.
|
||||
*/
|
||||
addenv("PATH=/bin:/usr/bin", NULL);
|
||||
|
||||
/*
|
||||
* Export the user name. For BSD derived systems, it's "USER", for
|
||||
* all others it's "LOGNAME". We set both of them.
|
||||
*/
|
||||
|
||||
addenv("USER", info->pw_name);
|
||||
addenv("LOGNAME", info->pw_name);
|
||||
}
|
||||
|
@@ -1,10 +0,0 @@
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef _SETUPENV_H
|
||||
#define _SETUPENV_H
|
||||
|
||||
void addenv_path(const char *, const char *, const char *);
|
||||
void read_env_file(const char *);
|
||||
void setup_env(struct passwd *);
|
||||
|
||||
#endif
|
@@ -1,167 +0,0 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* File ..................: mbuseradd/sgetpwent.c
|
||||
* Purpose ...............: MBSE BBS Shadow Password Suite
|
||||
* Last modification date : 07-Feb-2001
|
||||
* 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.
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Copyright 1989 - 1994, Julianne Frances Haugh
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of Julianne F. Haugh nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "../config.h"
|
||||
#include <stdlib.h>
|
||||
#include <pwd.h>
|
||||
#include <string.h>
|
||||
#include "sgetpwent.h"
|
||||
|
||||
|
||||
#define NFIELDS 7
|
||||
|
||||
/*
|
||||
* sgetpwent - convert a string to a (struct passwd)
|
||||
*
|
||||
* sgetpwent() parses a string into the parts required for a password
|
||||
* structure. Strict checking is made for the UID and GID fields and
|
||||
* presence of the correct number of colons. Any failing tests result
|
||||
* in a NULL pointer being returned.
|
||||
*
|
||||
* NOTE: This function uses hard-coded string scanning functions for
|
||||
* performance reasons. I am going to come up with some conditional
|
||||
* compilation glarp to improve on this in the future.
|
||||
*/
|
||||
|
||||
struct passwd * sgetpwent(const char *buf)
|
||||
{
|
||||
static struct passwd pwent;
|
||||
static char pwdbuf[1024];
|
||||
register int i;
|
||||
register char *cp;
|
||||
char *ep;
|
||||
char *fields[NFIELDS];
|
||||
|
||||
/*
|
||||
* Copy the string to a static buffer so the pointers into
|
||||
* the password structure remain valid.
|
||||
*/
|
||||
|
||||
if (strlen(buf) >= sizeof pwdbuf)
|
||||
return 0;
|
||||
strcpy(pwdbuf, buf);
|
||||
|
||||
/*
|
||||
* Save a pointer to the start of each colon separated
|
||||
* field. The fields are converted into NUL terminated strings.
|
||||
*/
|
||||
|
||||
for (cp = pwdbuf, i = 0;i < NFIELDS && cp;i++) {
|
||||
fields[i] = cp;
|
||||
while (*cp && *cp != ':')
|
||||
++cp;
|
||||
|
||||
if (*cp)
|
||||
*cp++ = '\0';
|
||||
else
|
||||
cp = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* There must be exactly NFIELDS colon separated fields or
|
||||
* the entry is invalid. Also, the UID and GID must be non-blank.
|
||||
*/
|
||||
|
||||
if (i != NFIELDS || *fields[2] == '\0' || *fields[3] == '\0')
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Each of the fields is converted the appropriate data type
|
||||
* and the result assigned to the password structure. If the
|
||||
* UID or GID does not convert to an integer value, a NULL
|
||||
* pointer is returned.
|
||||
*/
|
||||
|
||||
pwent.pw_name = fields[0];
|
||||
pwent.pw_passwd = fields[1];
|
||||
if (fields[2][0] == '\0' ||
|
||||
((pwent.pw_uid = strtol (fields[2], &ep, 10)) == 0 && *ep)) {
|
||||
return 0;
|
||||
}
|
||||
if (fields[3][0] == '\0' ||
|
||||
((pwent.pw_gid = strtol (fields[3], &ep, 10)) == 0 && *ep)) {
|
||||
return 0;
|
||||
}
|
||||
#ifdef ATT_AGE
|
||||
cp = pwent.pw_passwd;
|
||||
while (*cp && *cp != ',')
|
||||
++cp;
|
||||
|
||||
if (*cp) {
|
||||
*cp++ = '\0';
|
||||
pwent.pw_age = cp;
|
||||
} else {
|
||||
cp = 0;
|
||||
pwent.pw_age = "";
|
||||
}
|
||||
#endif
|
||||
pwent.pw_gecos = fields[4];
|
||||
#ifdef ATT_COMMENT
|
||||
pwent.pw_comment = "";
|
||||
#endif
|
||||
pwent.pw_dir = fields[5];
|
||||
pwent.pw_shell = fields[6];
|
||||
|
||||
return &pwent;
|
||||
}
|
||||
|
||||
|
@@ -1,7 +0,0 @@
|
||||
#ifndef _SGETPWENT_H
|
||||
#define _SGETPWENT_H
|
||||
|
||||
struct passwd * sgetpwent(const char *);
|
||||
|
||||
#endif
|
||||
|
@@ -1,226 +0,0 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* File ..................: mbuseradd/shadowio.c
|
||||
* Purpose ...............: MBSE BBS Shadow Password Suite
|
||||
* Last modification date : 09-Aug-2001
|
||||
* 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"
|
||||
|
||||
#ifdef SHADOW_PASSWORD
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <shadow.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#include "commonio.h"
|
||||
#include "shadowio.h"
|
||||
|
||||
|
||||
|
||||
struct spwd *__spw_dup(const struct spwd *spent)
|
||||
{
|
||||
struct spwd *sp;
|
||||
|
||||
if (!(sp = (struct spwd *) malloc(sizeof *sp)))
|
||||
return NULL;
|
||||
*sp = *spent;
|
||||
if (!(sp->sp_namp = strdup(spent->sp_namp)))
|
||||
return NULL;
|
||||
if (!(sp->sp_pwdp = strdup(spent->sp_pwdp)))
|
||||
return NULL;
|
||||
return sp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void * shadow_dup(const void *ent)
|
||||
{
|
||||
const struct spwd *sp = ent;
|
||||
return __spw_dup(sp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void shadow_free(void *ent)
|
||||
{
|
||||
struct spwd *sp = ent;
|
||||
|
||||
free(sp->sp_namp);
|
||||
free(sp->sp_pwdp);
|
||||
free(sp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const char * shadow_getname(const void *ent)
|
||||
{
|
||||
const struct spwd *sp = ent;
|
||||
return sp->sp_namp;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void * shadow_parse(const char *line)
|
||||
{
|
||||
return (void *) sgetspent(line);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int shadow_put(const void *ent, FILE *file)
|
||||
{
|
||||
const struct spwd *sp = ent;
|
||||
return (putspent(sp, file) == -1) ? -1 : 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static struct commonio_ops shadow_ops = {
|
||||
shadow_dup,
|
||||
shadow_free,
|
||||
shadow_getname,
|
||||
shadow_parse,
|
||||
shadow_put,
|
||||
fgets,
|
||||
fputs
|
||||
};
|
||||
|
||||
|
||||
|
||||
static struct commonio_db shadow_db = {
|
||||
SHADOW_FILE, /* filename */
|
||||
&shadow_ops, /* ops */
|
||||
NULL, /* fp */
|
||||
NULL, /* head */
|
||||
NULL, /* tail */
|
||||
NULL, /* cursor */
|
||||
0, /* changed */
|
||||
0, /* isopen */
|
||||
0, /* locked */
|
||||
0, /* readonly */
|
||||
1 /* use_lckpwdf */
|
||||
};
|
||||
|
||||
|
||||
|
||||
int spw_name(const char *filename)
|
||||
{
|
||||
return commonio_setname(&shadow_db, filename);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int spw_file_present(void)
|
||||
{
|
||||
return commonio_present(&shadow_db);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int spw_lock(void)
|
||||
{
|
||||
return commonio_lock(&shadow_db);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int spw_open(int mode)
|
||||
{
|
||||
return commonio_open(&shadow_db, mode);
|
||||
}
|
||||
|
||||
|
||||
|
||||
const struct spwd * spw_locate(const char *name)
|
||||
{
|
||||
return commonio_locate(&shadow_db, name);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int spw_update(const struct spwd *sp)
|
||||
{
|
||||
return commonio_update(&shadow_db, (const void *) sp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int spw_remove(const char *name)
|
||||
{
|
||||
return commonio_remove(&shadow_db, name);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int spw_rewind(void)
|
||||
{
|
||||
return commonio_rewind(&shadow_db);
|
||||
}
|
||||
|
||||
|
||||
|
||||
const struct spwd * spw_next(void)
|
||||
{
|
||||
return commonio_next(&shadow_db);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int spw_close(void)
|
||||
{
|
||||
return commonio_close(&shadow_db);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int spw_unlock(void)
|
||||
{
|
||||
return commonio_unlock(&shadow_db);
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct commonio_entry * __spw_get_head(void)
|
||||
{
|
||||
return shadow_db.head;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void __spw_del_entry(const struct commonio_entry *ent)
|
||||
{
|
||||
commonio_del_entry(&shadow_db, ent);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
@@ -1,33 +0,0 @@
|
||||
#ifndef _SHADOWIO_H
|
||||
#define _SHADOWIO_H
|
||||
|
||||
#ifdef SHADOW_PASSWORD
|
||||
#ifndef SHADOW_FILE
|
||||
#define SHADOW_FILE "/etc/shadow"
|
||||
#endif
|
||||
|
||||
#ifdef SHADOWGRP
|
||||
#ifndef SGROUP_FILE
|
||||
#define SGROUP_FILE "/etc/gshadow"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
struct spwd *__spw_dup (const struct spwd *);
|
||||
void __spw_set_changed (void);
|
||||
int spw_close (void);
|
||||
int spw_file_present (void);
|
||||
const struct spwd *spw_locate (const char *);
|
||||
int spw_lock (void);
|
||||
int spw_name (const char *);
|
||||
const struct spwd *spw_next (void);
|
||||
int spw_open (int);
|
||||
int spw_remove (const char *);
|
||||
int spw_rewind (void);
|
||||
int spw_unlock (void);
|
||||
int spw_update (const struct spwd *);
|
||||
|
||||
#endif
|
||||
|
128
mbsebbs/shell.c
128
mbsebbs/shell.c
@@ -1,128 +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 <errno.h>
|
||||
#include "mblogin.h"
|
||||
#include "basename.h"
|
||||
#include "shell.h"
|
||||
|
||||
|
||||
extern char **newenvp;
|
||||
extern size_t newenvc;
|
||||
|
||||
/*
|
||||
* shell - execute the named program
|
||||
*
|
||||
* shell begins by trying to figure out what argv[0] is going to
|
||||
* be for the named process. The user may pass in that argument,
|
||||
* or it will be the last pathname component of the file with a
|
||||
* '-' prepended. The first attempt is to just execute the named
|
||||
* file. If the errno comes back "ENOEXEC", the file is assumed
|
||||
* at first glance to be a shell script. The first two characters
|
||||
* must be "#!", in which case "/bin/sh" is executed to process
|
||||
* the file. If all that fails, give up in disgust ...
|
||||
*/
|
||||
|
||||
void shell(const char *file, const char *arg)
|
||||
{
|
||||
char arg0[1024];
|
||||
int err;
|
||||
|
||||
if (file == (char *) 0)
|
||||
exit (1);
|
||||
|
||||
/*
|
||||
* The argv[0]'th entry is usually the path name, but
|
||||
* for various reasons the invoker may want to override
|
||||
* that. So, we determine the 0'th entry only if they
|
||||
* don't want to tell us what it is themselves.
|
||||
*/
|
||||
|
||||
if (arg == (char *) 0) {
|
||||
snprintf(arg0, sizeof arg0, "-%s", Basename((char *) file));
|
||||
arg = arg0;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
printf (_("Executing shell %s\n"), file);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* First we try the direct approach. The system should be
|
||||
* able to figure out what we are up to without too much
|
||||
* grief.
|
||||
*/
|
||||
|
||||
execle (file, arg, (char *) 0, newenvp);
|
||||
err = errno;
|
||||
|
||||
/* Linux handles #! in the kernel, and bash doesn't make
|
||||
sense of "#!" so it wouldn't work anyway... --marekm */
|
||||
#ifndef __linux__
|
||||
/*
|
||||
* It is perfectly OK to have a shell script for a login
|
||||
* shell, and this code attempts to support that. It
|
||||
* relies on the standard shell being able to make sense
|
||||
* of the "#!" magic number.
|
||||
*/
|
||||
|
||||
if (err == ENOEXEC) {
|
||||
FILE *fp;
|
||||
|
||||
if ((fp = fopen (file, "r"))) {
|
||||
if (getc (fp) == '#' && getc (fp) == '!') {
|
||||
fclose (fp);
|
||||
execle ("/bin/sh", "sh",
|
||||
file, (char *) 0, newenvp);
|
||||
err = errno;
|
||||
} else {
|
||||
fclose (fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Obviously something is really wrong - I can't figure out
|
||||
* how to execute this stupid shell, so I might as well give
|
||||
* up in disgust ...
|
||||
*/
|
||||
|
||||
snprintf(arg0, sizeof arg0, "Cannot execute %s", file);
|
||||
errno = err;
|
||||
perror(arg0);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@@ -1,8 +0,0 @@
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef _SHELL_H
|
||||
#define _SHELL_H
|
||||
|
||||
void shell(const char *, const char *);
|
||||
|
||||
#endif
|
@@ -1,80 +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 <sys/types.h>
|
||||
#include <syslog.h>
|
||||
#include "mblogin.h"
|
||||
#include <pwd.h>
|
||||
#include "sub.h"
|
||||
|
||||
|
||||
#define BAD_SUBROOT2 "invalid root `%s' for user `%s'\n"
|
||||
#define NO_SUBROOT2 "no subsystem root `%s' for user `%s'\n"
|
||||
|
||||
/*
|
||||
* subsystem - change to subsystem root
|
||||
*
|
||||
* A subsystem login is indicated by the presense of a "*" as
|
||||
* the first character of the login shell. The given home
|
||||
* directory will be used as the root of a new filesystem which
|
||||
* the user is actually logged into.
|
||||
*/
|
||||
|
||||
void subsystem(const struct passwd *pw)
|
||||
{
|
||||
/*
|
||||
* The new root directory must begin with a "/" character.
|
||||
*/
|
||||
|
||||
if (pw->pw_dir[0] != '/') {
|
||||
printf("Invalid root directory \"%s\"\n", pw->pw_dir);
|
||||
syslog(LOG_WARNING, BAD_SUBROOT2, pw->pw_dir, pw->pw_name);
|
||||
closelog();
|
||||
exit (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* The directory must be accessible and the current process
|
||||
* must be able to change into it.
|
||||
*/
|
||||
|
||||
if (chdir (pw->pw_dir) || chroot (pw->pw_dir)) {
|
||||
printf("Can't change root directory to \"%s\"\n", pw->pw_dir);
|
||||
syslog(LOG_WARNING, NO_SUBROOT2, pw->pw_dir, pw->pw_name);
|
||||
closelog();
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,8 +0,0 @@
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef _SUB_H
|
||||
#define _SUB_H
|
||||
|
||||
void subsystem(const struct passwd *);
|
||||
|
||||
#endif
|
114
mbsebbs/utent.c
114
mbsebbs/utent.c
@@ -1,114 +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"
|
||||
|
||||
#ifndef HAVE_GETUTENT
|
||||
|
||||
#include "mblogin.h"
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <utmp.h>
|
||||
|
||||
|
||||
static int utmp_fd = -1;
|
||||
static struct utmp utmp_buf;
|
||||
|
||||
/*
|
||||
* setutent - open or rewind the utmp file
|
||||
*/
|
||||
|
||||
void
|
||||
setutent(void)
|
||||
{
|
||||
if (utmp_fd == -1)
|
||||
if ((utmp_fd = open (_UTMP_FILE, O_RDWR)) == -1)
|
||||
utmp_fd = open (_UTMP_FILE, O_RDONLY);
|
||||
|
||||
if (utmp_fd != -1)
|
||||
lseek (utmp_fd, (off_t) 0L, SEEK_SET);
|
||||
}
|
||||
|
||||
/*
|
||||
* endutent - close the utmp file
|
||||
*/
|
||||
|
||||
void
|
||||
endutent(void)
|
||||
{
|
||||
if (utmp_fd != -1)
|
||||
close (utmp_fd);
|
||||
|
||||
utmp_fd = -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* getutent - get the next record from the utmp file
|
||||
*/
|
||||
|
||||
struct utmp *
|
||||
getutent(void)
|
||||
{
|
||||
if (utmp_fd == -1)
|
||||
setutent ();
|
||||
|
||||
if (utmp_fd == -1)
|
||||
return 0;
|
||||
|
||||
if (read (utmp_fd, &utmp_buf, sizeof utmp_buf) != sizeof utmp_buf)
|
||||
return 0;
|
||||
|
||||
return &utmp_buf;
|
||||
}
|
||||
|
||||
/*
|
||||
* getutline - get the utmp entry matching ut_line
|
||||
*/
|
||||
|
||||
struct utmp *
|
||||
getutline(const struct utmp *utent)
|
||||
{
|
||||
struct utmp save;
|
||||
struct utmp *new;
|
||||
|
||||
save = *utent;
|
||||
while (new = getutent ())
|
||||
if (strncmp (new->ut_line, save.ut_line, sizeof new->ut_line))
|
||||
continue;
|
||||
else
|
||||
return new;
|
||||
|
||||
return (struct utmp *) 0;
|
||||
}
|
||||
#else
|
||||
extern int errno; /* warning: ANSI C forbids an empty source file */
|
||||
#endif
|
@@ -1,12 +0,0 @@
|
||||
|
||||
|
||||
#include "../config.h"
|
||||
|
||||
#ifndef HAVE_GETUTENT
|
||||
|
||||
void setutent(void);
|
||||
void endutent(void);
|
||||
struct utmp *getutent(void);
|
||||
struct utmp *getutline(const struct utmp *utent);
|
||||
|
||||
#endif
|
472
mbsebbs/utmp.c
472
mbsebbs/utmp.c
@@ -1,472 +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 "mblogin.h"
|
||||
#include <utmp.h>
|
||||
|
||||
#if HAVE_UTMPX_H
|
||||
#include <utmpx.h>
|
||||
#endif
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include "utmp.h"
|
||||
|
||||
|
||||
#if HAVE_UTMPX_H
|
||||
extern struct utmpx utxent;
|
||||
#endif
|
||||
extern struct utmp utent;
|
||||
|
||||
|
||||
#define NO_UTENT \
|
||||
"No utmp entry. You must exec \"login\" from the lowest level \"sh\""
|
||||
#define NO_TTY \
|
||||
"Unable to determine your tty name."
|
||||
|
||||
/*
|
||||
* checkutmp - see if utmp file is correct for this process
|
||||
*
|
||||
* System V is very picky about the contents of the utmp file
|
||||
* and requires that a slot for the current process exist.
|
||||
* The utmp file is scanned for an entry with the same process
|
||||
* ID. If no entry exists the process exits with a message.
|
||||
*
|
||||
* The "picky" flag is for network and other logins that may
|
||||
* use special flags. It allows the pid checks to be overridden.
|
||||
* This means that getty should never invoke login with any
|
||||
* command line flags.
|
||||
*/
|
||||
|
||||
#if defined(__linux__) /* XXX */
|
||||
|
||||
void
|
||||
checkutmp(int picky)
|
||||
{
|
||||
char *line;
|
||||
struct utmp *ut;
|
||||
pid_t pid = getpid();
|
||||
|
||||
setutent();
|
||||
|
||||
/* First, try to find a valid utmp entry for this process. */
|
||||
while ((ut = getutent()))
|
||||
if (ut->ut_pid == pid && ut->ut_line[0] && ut->ut_id[0] &&
|
||||
(ut->ut_type==LOGIN_PROCESS || ut->ut_type==USER_PROCESS))
|
||||
break;
|
||||
|
||||
/* If there is one, just use it, otherwise create a new one. */
|
||||
if (ut) {
|
||||
utent = *ut;
|
||||
} else {
|
||||
if (picky) {
|
||||
puts(NO_UTENT);
|
||||
exit(1);
|
||||
}
|
||||
line = ttyname(0);
|
||||
if (!line) {
|
||||
puts(NO_TTY);
|
||||
exit(1);
|
||||
}
|
||||
if (strncmp(line, "/dev/", 5) == 0)
|
||||
line += 5;
|
||||
memset((void *) &utent, 0, sizeof utent);
|
||||
utent.ut_type = LOGIN_PROCESS;
|
||||
utent.ut_pid = pid;
|
||||
strncpy(utent.ut_line, line, sizeof utent.ut_line);
|
||||
/* XXX - assumes /dev/tty?? */
|
||||
strncpy(utent.ut_id, utent.ut_line + 3, sizeof utent.ut_id);
|
||||
strcpy(utent.ut_user, "LOGIN");
|
||||
time(&utent.ut_time);
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(LOGIN_PROCESS)
|
||||
|
||||
void
|
||||
checkutmp(int picky)
|
||||
{
|
||||
char *line;
|
||||
struct utmp *ut;
|
||||
#if HAVE_UTMPX_H
|
||||
struct utmpx *utx;
|
||||
#endif
|
||||
pid_t pid = getpid();
|
||||
|
||||
#if HAVE_UTMPX_H
|
||||
setutxent();
|
||||
#endif
|
||||
setutent();
|
||||
|
||||
if (picky) {
|
||||
#if HAVE_UTMPX_H
|
||||
while ((utx = getutxent()))
|
||||
if (utx->ut_pid == pid)
|
||||
break;
|
||||
|
||||
if (utx)
|
||||
utxent = *utx;
|
||||
#endif
|
||||
while ((ut = getutent()))
|
||||
if (ut->ut_pid == pid)
|
||||
break;
|
||||
|
||||
if (ut)
|
||||
utent = *ut;
|
||||
|
||||
#if HAVE_UTMPX_H
|
||||
endutxent();
|
||||
#endif
|
||||
endutent();
|
||||
|
||||
if (!ut) {
|
||||
puts(NO_UTENT);
|
||||
exit(1);
|
||||
}
|
||||
#ifndef UNIXPC
|
||||
|
||||
/*
|
||||
* If there is no ut_line value in this record, fill
|
||||
* it in by getting the TTY name and stuffing it in
|
||||
* the structure. The UNIX/PC is broken in this regard
|
||||
* and needs help ...
|
||||
*/
|
||||
|
||||
if (utent.ut_line[0] == '\0')
|
||||
#endif /* !UNIXPC */
|
||||
{
|
||||
if (!(line = ttyname(0))) {
|
||||
puts(NO_TTY);
|
||||
exit(1);
|
||||
}
|
||||
if (strncmp(line, "/dev/", 5) == 0)
|
||||
line += 5;
|
||||
strncpy(utent.ut_line, line, sizeof utent.ut_line);
|
||||
#if HAVE_UTMPX_H
|
||||
strncpy(utxent.ut_line, line, sizeof utxent.ut_line);
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
if (!(line = ttyname(0))) {
|
||||
puts(NO_TTY);
|
||||
exit(1);
|
||||
}
|
||||
if (strncmp(line, "/dev/", 5) == 0)
|
||||
line += 5;
|
||||
|
||||
strncpy (utent.ut_line, line, sizeof utent.ut_line);
|
||||
if ((ut = getutline(&utent)))
|
||||
strncpy(utent.ut_id, ut->ut_id, sizeof ut->ut_id);
|
||||
|
||||
strcpy(utent.ut_user, "LOGIN");
|
||||
utent.ut_pid = getpid();
|
||||
utent.ut_type = LOGIN_PROCESS;
|
||||
time(&utent.ut_time);
|
||||
#if HAVE_UTMPX_H
|
||||
strncpy(utxent.ut_line, line, sizeof utxent.ut_line);
|
||||
if ((utx = getutxline(&utxent)))
|
||||
strncpy(utxent.ut_id, utx->ut_id, sizeof utxent.ut_id);
|
||||
|
||||
strcpy(utxent.ut_user, "LOGIN");
|
||||
utxent.ut_pid = utent.ut_pid;
|
||||
utxent.ut_type = utent.ut_type;
|
||||
gettimeofday((struct timeval *) &utxent.ut_tv, NULL);
|
||||
utent.ut_time = utxent.ut_tv.tv_sec;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#else /* !USG */
|
||||
|
||||
void
|
||||
checkutmp(int picky)
|
||||
{
|
||||
char *line;
|
||||
|
||||
/*
|
||||
* Hand-craft a new utmp entry.
|
||||
*/
|
||||
|
||||
memzero(&utent, sizeof utent);
|
||||
if (! (line = ttyname (0))) {
|
||||
puts (NO_TTY);
|
||||
exit (1);
|
||||
}
|
||||
if (strncmp (line, "/dev/", 5) == 0)
|
||||
line += 5;
|
||||
|
||||
(void) strncpy (utent.ut_line, line, sizeof utent.ut_line);
|
||||
(void) time (&utent.ut_time);
|
||||
}
|
||||
|
||||
#endif /* !USG */
|
||||
|
||||
|
||||
/*
|
||||
* Some systems already have updwtmp() and possibly updwtmpx(). Others
|
||||
* don't, so we re-implement these functions if necessary. --marekm
|
||||
*/
|
||||
|
||||
#ifndef HAVE_UPDWTMP
|
||||
void updwtmp(const char *filename, const struct utmp *ut)
|
||||
{
|
||||
int fd;
|
||||
|
||||
fd = open(filename, O_APPEND | O_WRONLY, 0);
|
||||
if (fd >= 0) {
|
||||
write(fd, (const char *) ut, sizeof(*ut));
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
#endif /* ! HAVE_UPDWTMP */
|
||||
|
||||
#ifdef HAVE_UTMPX_H
|
||||
#ifndef HAVE_UPDWTMPX
|
||||
static void
|
||||
updwtmpx(const char *filename, const struct utmpx *utx)
|
||||
{
|
||||
int fd;
|
||||
|
||||
fd = open(filename, O_APPEND | O_WRONLY, 0);
|
||||
if (fd >= 0) {
|
||||
write(fd, (const char *) utx, sizeof(*utx));
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
#endif /* ! HAVE_UPDWTMPX */
|
||||
#endif /* ! HAVE_UTMPX_H */
|
||||
|
||||
|
||||
/*
|
||||
* setutmp - put a USER_PROCESS entry in the utmp file
|
||||
*
|
||||
* setutmp changes the type of the current utmp entry to
|
||||
* USER_PROCESS. the wtmp file will be updated as well.
|
||||
*/
|
||||
|
||||
#if defined(__linux__) /* XXX */
|
||||
|
||||
void
|
||||
setutmp(const char *name, const char *line, const char *host)
|
||||
{
|
||||
utent.ut_type = USER_PROCESS;
|
||||
strncpy(utent.ut_user, name, sizeof utent.ut_user);
|
||||
time(&utent.ut_time);
|
||||
/* other fields already filled in by checkutmp above */
|
||||
setutent();
|
||||
pututline(&utent);
|
||||
endutent();
|
||||
updwtmp(_WTMP_FILE, &utent);
|
||||
}
|
||||
|
||||
#elif HAVE_UTMPX_H
|
||||
|
||||
void
|
||||
setutmp(const char *name, const char *line, const char *host)
|
||||
{
|
||||
struct utmp *utmp, utline;
|
||||
struct utmpx *utmpx, utxline;
|
||||
pid_t pid = getpid ();
|
||||
int found_utmpx = 0, found_utmp = 0;
|
||||
|
||||
/*
|
||||
* The canonical device name doesn't include "/dev/"; skip it
|
||||
* if it is already there.
|
||||
*/
|
||||
|
||||
if (strncmp (line, "/dev/", 5) == 0)
|
||||
line += 5;
|
||||
|
||||
/*
|
||||
* Update utmpx. We create an empty entry in case there is
|
||||
* no matching entry in the utmpx file.
|
||||
*/
|
||||
|
||||
setutxent ();
|
||||
setutent ();
|
||||
|
||||
while (utmpx = getutxent ()) {
|
||||
if (utmpx->ut_pid == pid) {
|
||||
found_utmpx = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (utmp = getutent ()) {
|
||||
if (utmp->ut_pid == pid) {
|
||||
found_utmp = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If the entry matching `pid' cannot be found, create a new
|
||||
* entry with the device name in it.
|
||||
*/
|
||||
|
||||
if (! found_utmpx) {
|
||||
memset ((void *) &utxline, 0, sizeof utxline);
|
||||
strncpy (utxline.ut_line, line, sizeof utxline.ut_line);
|
||||
utxline.ut_pid = getpid ();
|
||||
} else {
|
||||
utxline = *utmpx;
|
||||
if (strncmp (utxline.ut_line, "/dev/", 5) == 0) {
|
||||
memmove (utxline.ut_line, utxline.ut_line + 5,
|
||||
sizeof utxline.ut_line - 5);
|
||||
utxline.ut_line[sizeof utxline.ut_line - 5] = '\0';
|
||||
}
|
||||
}
|
||||
if (! found_utmp) {
|
||||
memset ((void *) &utline, 0, sizeof utline);
|
||||
strncpy (utline.ut_line, utxline.ut_line,
|
||||
sizeof utline.ut_line);
|
||||
utline.ut_pid = utxline.ut_pid;
|
||||
} else {
|
||||
utline = *utmp;
|
||||
if (strncmp (utline.ut_line, "/dev/", 5) == 0) {
|
||||
memmove (utline.ut_line, utline.ut_line + 5,
|
||||
sizeof utline.ut_line - 5);
|
||||
utline.ut_line[sizeof utline.ut_line - 5] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill in the fields in the utmpx entry and write it out. Do
|
||||
* the utmp entry at the same time to make sure things don't
|
||||
* get messed up.
|
||||
*/
|
||||
|
||||
strncpy (utxline.ut_user, name, sizeof utxline.ut_user);
|
||||
strncpy (utline.ut_user, name, sizeof utline.ut_user);
|
||||
|
||||
utline.ut_type = utxline.ut_type = USER_PROCESS;
|
||||
|
||||
gettimeofday(&utxline.ut_tv, NULL);
|
||||
utline.ut_time = utxline.ut_tv.tv_sec;
|
||||
|
||||
strncpy(utxline.ut_host, host ? host : "", sizeof utxline.ut_host);
|
||||
|
||||
pututxline (&utxline);
|
||||
pututline (&utline);
|
||||
|
||||
updwtmpx(_WTMP_FILE "x", &utxline);
|
||||
updwtmp(_WTMP_FILE, &utline);
|
||||
|
||||
utxent = utxline;
|
||||
utent = utline;
|
||||
}
|
||||
|
||||
#else /* !SVR4 */
|
||||
|
||||
void
|
||||
setutmp(const char *name, const char *line)
|
||||
{
|
||||
struct utmp utmp;
|
||||
int fd;
|
||||
int found = 0;
|
||||
|
||||
if ((fd = open(_UTMP_FILE, O_RDWR)) < 0)
|
||||
return;
|
||||
|
||||
#if !defined(SUN) && !defined(BSD) && !defined(SUN4) /* XXX */
|
||||
while (!found && read(fd, (char *)&utmp, sizeof utmp) == sizeof utmp) {
|
||||
if (! strncmp (line, utmp.ut_line, (int) sizeof utmp.ut_line))
|
||||
found++;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (! found) {
|
||||
|
||||
/*
|
||||
* This is a brand-new entry. Clear it out and fill it in
|
||||
* later.
|
||||
*/
|
||||
|
||||
memzero(&utmp, sizeof utmp);
|
||||
strncpy(utmp.ut_line, line, (int) sizeof utmp.ut_line);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill in the parts of the UTMP entry. BSD has just the name,
|
||||
* while System V has the name, PID and a type.
|
||||
*/
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
strncpy(utmp.ut_user, name, sizeof utent.ut_user);
|
||||
#endif
|
||||
#ifdef USER_PROCESS
|
||||
utmp.ut_type = USER_PROCESS;
|
||||
utmp.ut_pid = getpid ();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Put in the current time (common to everyone)
|
||||
*/
|
||||
|
||||
(void) time (&utmp.ut_time);
|
||||
|
||||
#ifdef UT_HOST
|
||||
/*
|
||||
* Update the host name field for systems with networking support
|
||||
*/
|
||||
|
||||
(void) strncpy (utmp.ut_host, utent.ut_host, (int) sizeof utmp.ut_host);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Locate the correct position in the UTMP file for this
|
||||
* entry.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_TTYSLOT
|
||||
(void) lseek (fd, (off_t) (sizeof utmp) * ttyslot (), SEEK_SET);
|
||||
#else
|
||||
if (found) /* Back up a splot */
|
||||
lseek (fd, (off_t) - sizeof utmp, SEEK_CUR);
|
||||
else /* Otherwise, go to the end of the file */
|
||||
lseek (fd, (off_t) 0, SEEK_END);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Scribble out the new entry and close the file. We're done
|
||||
* with UTMP, next we do WTMP (which is real easy, put it on
|
||||
* the end of the file.
|
||||
*/
|
||||
|
||||
(void) write (fd, (char *) &utmp, sizeof utmp);
|
||||
(void) close (fd);
|
||||
|
||||
updwtmp(_WTMP_FILE, &utmp);
|
||||
utent = utmp;
|
||||
}
|
||||
|
||||
#endif /* SVR4 */
|
@@ -1,27 +0,0 @@
|
||||
/* $Id$ */
|
||||
|
||||
#ifndef _UTMP_HH
|
||||
#define _UTMP_HH
|
||||
|
||||
|
||||
void checkutmp(int);
|
||||
|
||||
#ifndef HAVE_UPDWTMP
|
||||
void updwtmp(const char *, const struct utmp *);
|
||||
#endif /* ! HAVE_UPDWTMP */
|
||||
|
||||
#ifdef HAVE_UTMPX_H
|
||||
#ifndef HAVE_UPDWTMPX
|
||||
static void updwtmpx(const char *, const struct utmpx *);
|
||||
#endif /* ! HAVE_UPDWTMPX */
|
||||
#endif /* ! HAVE_UTMPX_H */
|
||||
|
||||
#if defined(__linux__) /* XXX */
|
||||
void setutmp(const char *, const char *, const char *);
|
||||
#elif HAVE_UTMPX_H
|
||||
void setutmp(const char *, const char *, const char *);
|
||||
#else /* !SVR4 */
|
||||
void setutmp(const char *, const char *);
|
||||
#endif
|
||||
|
||||
#endif
|
@@ -1,71 +0,0 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* File ..................: mbuseradd/xmalloc.c
|
||||
* Purpose ...............: MBSE BBS Shadow Password Suite
|
||||
* Last modification date : 25-Jul-2000
|
||||
* Original Source .......: Shadow Password Suite
|
||||
* Original Copyrioght ...: Julianne Frances Haugh and others.
|
||||
*
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1997-2000
|
||||
*
|
||||
* 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.
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
/* Replacements for malloc and strdup with error checking. Too trivial
|
||||
to be worth copyrighting :-). I did that because a lot of code used
|
||||
malloc and strdup without checking for NULL pointer, and I like some
|
||||
message better than a core dump... --marekm
|
||||
|
||||
Yeh, but. Remember that bailing out might leave the system in some
|
||||
bizarre state. You really want to put in error checking, then add
|
||||
some back-out failure recovery code. -- jfh */
|
||||
|
||||
|
||||
#include "../config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "xmalloc.h"
|
||||
|
||||
|
||||
|
||||
char *xmalloc(size_t size)
|
||||
{
|
||||
char *ptr;
|
||||
|
||||
ptr = malloc(size);
|
||||
if (!ptr && size) {
|
||||
fprintf(stderr, "malloc(%d) failed\n", (int) size);
|
||||
exit(13);
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
char *xstrdup(const char *str)
|
||||
{
|
||||
return strcpy(xmalloc(strlen(str) + 1), str);
|
||||
}
|
||||
|
@@ -1,8 +0,0 @@
|
||||
#ifndef _XMALLOC_H
|
||||
#define _XMALLOC_H
|
||||
|
||||
char *xmalloc(size_t);
|
||||
char *xstrdup(const char *);
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user