Splitted mbsebbs sourcetree

This commit is contained in:
Michiel Broek
2002-01-05 13:57:10 +00:00
parent 81c0cc8f10
commit 1e6a95c4b8
64 changed files with 863 additions and 768 deletions

View File

@@ -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

View File

@@ -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;
}

View File

@@ -1,9 +0,0 @@
/* $Id$ */
#ifndef _BASENAME_H
#define _BASENAME_H
char *Basename(char *);
#endif

View File

@@ -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
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -1,9 +0,0 @@
#ifndef _ENCRYPT_H
#define _ENCRYPT_H
char *pw_encrypt(const char *, const char *);
#endif

View File

@@ -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;
}
}
}

View File

@@ -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

View File

@@ -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__ */

View File

@@ -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 */

View File

@@ -1,67 +0,0 @@
/*****************************************************************************
*
* $Id$
* Purpose ...............: MBSE BBS Shadow Password Suite
* Original Source .......: Shadow Password Suite
* Original Copyright ....: Julianne Frances Haugh and others.
*
*****************************************************************************
* Copyright (C) 1997-2001
*
* Michiel Broek FIDO: 2:280/2802
* Beekmansbos 10
* 1971 BV IJmuiden
* the Netherlands
*
* This file is part of MBSE BBS.
*
* This BBS is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* MBSE BBS is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MBSE BBS; see the file COPYING. If not, write to the Free
* Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*****************************************************************************/
/*
* 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));
}
}
}

View File

@@ -1,9 +0,0 @@
/* $Id$ */
#ifndef _LIMITS_H_
#define _LIMITS_H_
void setup_limits(const struct passwd *);
#endif

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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
}

View File

@@ -1,9 +0,0 @@
/* $Id$ */
#ifndef _LOGINPROMPT_H
#define _LOGINPROMPT_H
void login_exit(int);
void login_prompt(const char *, char *, int);
#endif

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -1,7 +0,0 @@
#ifndef _MYNAME_H
#define _MYNAME_H
struct passwd *get_my_pwent(void);
#endif

View File

@@ -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

View File

@@ -1,14 +0,0 @@
#include "../config.h"
#ifndef HAVE_PUTPWENT
#ifndef _PUTPWENT_H
#define _PUTPWENT_H
int putpwent(const struct passwd *, FILE *);
#endif
#endif

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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 */
}

View File

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

View File

@@ -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

View File

@@ -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

View File

@@ -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 */

View File

@@ -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

View File

@@ -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

View File

@@ -1,9 +0,0 @@
#ifndef _SALT_H
#define _SALT_H
char *crypt_make_salt(void);
#endif

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -1,7 +0,0 @@
#ifndef _SGETPWENT_H
#define _SGETPWENT_H
struct passwd * sgetpwent(const char *);
#endif

View File

@@ -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

View File

@@ -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

View File

@@ -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);
}

View File

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

View File

@@ -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);
}
}

View File

@@ -1,8 +0,0 @@
/* $Id$ */
#ifndef _SUB_H
#define _SUB_H
void subsystem(const struct passwd *);
#endif

View File

@@ -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

View File

@@ -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

View File

@@ -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 */

View File

@@ -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

View File

@@ -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);
}

View File

@@ -1,8 +0,0 @@
#ifndef _XMALLOC_H
#define _XMALLOC_H
char *xmalloc(size_t);
char *xstrdup(const char *);
#endif