Converted from CVS
This commit is contained in:
1
unix/.cvsignore
Normal file
1
unix/.cvsignore
Normal file
@@ -0,0 +1 @@
|
||||
filelist login.defs mblogin mbpasswd mbuseradd
|
115
unix/Makefile
Normal file
115
unix/Makefile
Normal file
@@ -0,0 +1,115 @@
|
||||
# Makefile for MBSE BBS under Linux
|
||||
# Copyright (c) 1998, 2001 by M. Broek.
|
||||
# $Id: Makefile,v 1.12 2007/05/27 12:50:48 mbse Exp $
|
||||
|
||||
include ../Makefile.global
|
||||
|
||||
SRCS = commonio.c putpwent.c salt.c sgetpwent.c xmalloc.c myname.c encrypt.c \
|
||||
pwio.c shadowio.c mbpasswd.c mbuseradd.c rad64.c getdef.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
|
||||
HDRS = commonio.h putpwent.h salt.h sgetpwent.h xmalloc.h myname.h encrypt.h \
|
||||
pwio.h shadowio.h mbpasswd.h mbuseradd.h rad64.h getdef.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
|
||||
MBUSERADD_OBJS = mbuseradd.o xmalloc.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 \
|
||||
mblogin.o
|
||||
OTHER = Makefile login.defs.in
|
||||
TARGET = mbuseradd mbpasswd mblogin
|
||||
|
||||
#############################################################################################################
|
||||
|
||||
.c.o:
|
||||
${CC} ${CFLAGS} ${INCLUDES} ${DEFINES} -c $<
|
||||
|
||||
all: ${TARGET}
|
||||
|
||||
clean:
|
||||
rm -f ${TARGET} *.o *.h~ *.c~ core filelist Makefile.bak
|
||||
|
||||
mbuseradd: ${MBUSERADD_OBJS}
|
||||
${CC} -o mbuseradd ${MBUSERADD_OBJS} ${LDFLAGS} ${LIBS}
|
||||
|
||||
mbpasswd: ${MBPASSWD_OBJS}
|
||||
${CC} -o mbpasswd ${MBPASSWD_OBJS} ${LDFLAGS} ${LIBS}
|
||||
|
||||
mblogin: ${MBLOGIN_OBJS}
|
||||
${CC} -o mblogin ${MBLOGIN_OBJS} ${LDFLAGS} ${LIBS}
|
||||
|
||||
install: all
|
||||
@if [ "`id -un`" != "root" ] ; then \
|
||||
echo; echo " Must be root to install!"; echo; exit 3; \
|
||||
fi
|
||||
${INSTALL} -c -s -o ${ROWNER} -g ${RGROUP} -m 6711 mbuseradd ${BINDIR}
|
||||
${INSTALL} -c -s -o ${ROWNER} -g ${RGROUP} -m 6711 mbpasswd ${BINDIR}
|
||||
${INSTALL} -c -s -o ${ROWNER} -g ${RGROUP} -m 0755 mblogin ${BINDIR}
|
||||
@if [ ! -f ${ETCDIR}/login.defs ] ; then \
|
||||
${INSTALL} -c -o ${OWNER} -g ${GROUP} -m 0644 login.defs ${ETCDIR} ; \
|
||||
echo "${INSTALL} -c -o ${OWNER} -g ${GROUP} -m 0644 login.defs ${ETCDIR}" ; \
|
||||
else \
|
||||
${INSTALL} -c -o ${OWNER} -g ${GROUP} -m 0644 login.defs ${ETCDIR}/login.defs.new ; \
|
||||
echo "${INSTALL} -c -o ${OWNER} -g ${GROUP} -m 0644 login.defs ${ETCDIR}/login.defs.new" ; \
|
||||
fi
|
||||
|
||||
filelist: Makefile
|
||||
BASE=`pwd`; \
|
||||
BASE=`basename $${BASE}`; \
|
||||
(for f in ${SRCS} ${HDRS} ${OTHER} ; do echo ${PACKAGE}-${VERSION}/$${BASE}/$$f; done) >filelist
|
||||
|
||||
depend:
|
||||
@rm -f Makefile.bak; \
|
||||
mv Makefile Makefile.bak; \
|
||||
sed -e '/^# DO NOT DELETE/,$$d' Makefile.bak >Makefile; \
|
||||
${ECHO} '# DO NOT DELETE THIS LINE - MAKE DEPEND RELIES ON IT' \
|
||||
>>Makefile; \
|
||||
${ECHO} '# Dependencies generated by make depend' >>Makefile; \
|
||||
for f in ${SRCS}; \
|
||||
do \
|
||||
${ECHO} "Dependencies for $$f:\c"; \
|
||||
${ECHO} "`basename $$f .c`.o:\c" >>Makefile; \
|
||||
for h in `sed -n -e \
|
||||
's/^#[ ]*include[ ]*"\([^"]*\)".*/\1/p' $$f`; \
|
||||
do \
|
||||
${ECHO} " $$h\c"; \
|
||||
${ECHO} " $$h\c" >>Makefile; \
|
||||
done; \
|
||||
${ECHO} " done."; \
|
||||
${ECHO} "" >>Makefile; \
|
||||
done; \
|
||||
${ECHO} '# End of generated dependencies' >>Makefile
|
||||
|
||||
# DO NOT DELETE THIS LINE - MAKE DEPEND RELIES ON IT
|
||||
# Dependencies generated by make depend
|
||||
commonio.o: ../config.h commonio.h
|
||||
putpwent.o: ../config.h putpwent.h
|
||||
salt.o: ../config.h rad64.h getdef.h
|
||||
sgetpwent.o: ../config.h sgetpwent.h
|
||||
xmalloc.o: ../config.h xmalloc.h
|
||||
myname.o: ../config.h
|
||||
encrypt.o: ../config.h encrypt.h
|
||||
pwio.o: ../config.h sgetpwent.h commonio.h putpwent.h pwio.h
|
||||
shadowio.o: ../config.h commonio.h shadowio.h
|
||||
mbpasswd.o: ../config.h encrypt.h rad64.h myname.h xmalloc.h pwio.h shadowio.h pw_util.h getdef.h mbpasswd.h
|
||||
mbuseradd.o: ../config.h xmalloc.h mbuseradd.h
|
||||
rad64.o: ../config.h rad64.h
|
||||
getdef.o: ../config.h getdef.h
|
||||
pw_util.o: ../config.h pw_util.h
|
||||
mblogin.o: ../config.h mblogin.h ../lib/users.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 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
|
||||
# End of generated dependencies
|
17
unix/basename.c
Normal file
17
unix/basename.c
Normal file
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
9
unix/basename.h
Normal file
9
unix/basename.h
Normal file
@@ -0,0 +1,9 @@
|
||||
/* $Id: basename.h,v 1.1 2002/01/05 13:57:10 mbroek Exp $ */
|
||||
|
||||
#ifndef _BASENAME_H
|
||||
#define _BASENAME_H
|
||||
|
||||
|
||||
char *Basename(char *);
|
||||
|
||||
#endif
|
123
unix/chowntty.c
Normal file
123
unix/chowntty.c
Normal file
@@ -0,0 +1,123 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* $Id: chowntty.c,v 1.2 2003/08/15 20:05:36 mbroek Exp $
|
||||
* 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, 59 Temple Place, Suite 330, Boston, MA 02111-1307 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];
|
||||
char *group; /* TTY group name or number */
|
||||
struct group *grent;
|
||||
gid_t gid;
|
||||
|
||||
/*
|
||||
* * See if login.defs has some value configured for the port group
|
||||
* * ID. Otherwise, use the user's primary group ID.
|
||||
* */
|
||||
|
||||
if (! (group = getdef_str ("TTYGROUP")))
|
||||
gid = info->pw_gid;
|
||||
else if (group[0] >= '0' && group[0] <= '9')
|
||||
gid = atoi (group);
|
||||
else if ((grent = getgrnam (group)))
|
||||
gid = grent->gr_gid;
|
||||
else
|
||||
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
|
||||
}
|
11
unix/chowntty.h
Normal file
11
unix/chowntty.h
Normal file
@@ -0,0 +1,11 @@
|
||||
/* $Id: chowntty.h,v 1.1 2002/01/05 13:57:10 mbroek Exp $ */
|
||||
|
||||
#ifndef _CHOWNTTY_H
|
||||
#define _CHOWNTTY_H
|
||||
|
||||
|
||||
int is_my_tty(const char *);
|
||||
void chown_tty(const char *, const struct passwd *);
|
||||
|
||||
|
||||
#endif
|
766
unix/commonio.c
Normal file
766
unix/commonio.c
Normal file
@@ -0,0 +1,766 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* $Id: commonio.c,v 1.3 2005/07/14 19:25:58 mbse Exp $
|
||||
* Purpose ...............: MBSE BBS Shadow Password Suite
|
||||
* Original Source .......: Shadow Password Suite
|
||||
* Original Copyright ....: Julianne Frances Haugh and others.
|
||||
*
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1997-2005
|
||||
*
|
||||
* 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, 59 Temple Place, Suite 330, Boston, MA 02111-1307 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;
|
||||
}
|
||||
|
112
unix/commonio.h
Normal file
112
unix/commonio.h
Normal file
@@ -0,0 +1,112 @@
|
||||
#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
|
||||
|
160
unix/encrypt.c
Normal file
160
unix/encrypt.c
Normal file
@@ -0,0 +1,160 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* $Id: encrypt.c,v 1.4 2005/04/12 17:25:42 mbse Exp $
|
||||
* Purpose ...............: MBSE BBS Shadow Password Suite
|
||||
* Original Source .......: Shadow Password Suite
|
||||
* Original Copyright ....: Julianne Frances Haugh and others.
|
||||
*
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1997-2003
|
||||
*
|
||||
* 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, 59 Temple Place, Suite 330, Boston, MA 02111-1307 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>
|
||||
#include <stdlib.h>
|
||||
#ifdef HAVE_CRYPT_H
|
||||
#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;
|
||||
}
|
||||
|
||||
|
9
unix/encrypt.h
Normal file
9
unix/encrypt.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef _ENCRYPT_H
|
||||
#define _ENCRYPT_H
|
||||
|
||||
|
||||
char *pw_encrypt(const char *, const char *);
|
||||
|
||||
|
||||
#endif
|
||||
|
253
unix/env.c
Normal file
253
unix/env.c
Normal file
@@ -0,0 +1,253 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* $Id: env.c,v 1.3 2005/08/30 17:53:35 mbse Exp $
|
||||
* Purpose ...............: MBSE BBS Shadow Password Suite
|
||||
* Original Source .......: Shadow Password Suite
|
||||
* Original Copyright ....: Julianne Frances Haugh and others.
|
||||
*
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1997-2005
|
||||
*
|
||||
* 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, 59 Temple Place, Suite 330, Boston, MA 02111-1307 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);
|
||||
snprintf(newstring, strlen(string) + strlen(value) + 2, "%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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
12
unix/env.h
Normal file
12
unix/env.h
Normal file
@@ -0,0 +1,12 @@
|
||||
/* $Id: env.h,v 1.1 2002/01/05 13:57:10 mbroek Exp $ */
|
||||
|
||||
#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
|
||||
|
339
unix/getdef.c
Normal file
339
unix/getdef.c
Normal file
@@ -0,0 +1,339 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* $Id: getdef.c,v 1.4 2005/08/30 17:53:35 mbse Exp $
|
||||
* Purpose ...............: MBSE BBS Shadow Password Suite
|
||||
* Original Source .......: Shadow Password Suite
|
||||
* Original Copyright ....: Julianne Frances Haugh and others.
|
||||
*
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1997-2005
|
||||
*
|
||||
* 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, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
#include "../config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <sys/param.h>
|
||||
#include <pwd.h>
|
||||
#include "getdef.h"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* 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[] = {
|
||||
{ "ALLOW_MBSE", NULL },
|
||||
{ "ASK_NEWUSER", NULL },
|
||||
{ "DEFAULT_HOME", NULL },
|
||||
{ "ENV_HZ", NULL },
|
||||
{ "ENV_PATH" , NULL },
|
||||
{ "ENV_TZ", NULL },
|
||||
{ "ERASECHAR", NULL },
|
||||
{ "FAIL_DELAY", NULL },
|
||||
{ "ISSUE_FILE", NULL },
|
||||
{ "KILLCHAR", NULL },
|
||||
{ "LASTLOG_ENAB", NULL },
|
||||
{ "LOGIN_RETRIES", NULL },
|
||||
{ "LOGIN_TIMEOUT", NULL },
|
||||
{ "LOG_OK_LOGINS", NULL },
|
||||
{ "LOG_UNKFAIL_ENAB", NULL },
|
||||
{ "MD5_CRYPT_ENAB", NULL },
|
||||
{ "NEWUSER_ACCOUNT", NULL },
|
||||
{ "NOLOGINS_FILE", NULL },
|
||||
{ "TTYGROUP", NULL },
|
||||
{ "TTYPERM", NULL },
|
||||
{ "ULIMIT", NULL },
|
||||
{ "UMASK", NULL },
|
||||
{ "USERGROUPS_ENAB", NULL },
|
||||
};
|
||||
|
||||
|
||||
static int def_loaded = 0; /* are defs already loaded? */
|
||||
|
||||
|
||||
/* local function prototypes */
|
||||
static struct itemdef *def_find (const char *);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* 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, "getdef(): configuration error - unknown item '%s' (notify administrator)\r\n", name);
|
||||
syslog(LOG_CRIT, "getdef(): unknown configuration item `%s'", name);
|
||||
return (struct itemdef *) NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* def_load - load configuration table
|
||||
*
|
||||
* Loads the user-configured options from the default configuration file
|
||||
*/
|
||||
void def_load(void)
|
||||
{
|
||||
int i;
|
||||
FILE *fp;
|
||||
struct itemdef *d;
|
||||
char buf[BUFSIZ], def_fname[PATH_MAX], *name, *value, *s;
|
||||
struct passwd *pw;
|
||||
|
||||
/*
|
||||
* Get MBSE BBS root directory
|
||||
*/
|
||||
if ((pw = getpwnam("mbse")) == NULL) {
|
||||
syslog(LOG_CRIT, "cannot find user `mbse' in password file");
|
||||
return;
|
||||
}
|
||||
snprintf(def_fname, PATH_MAX, "%s/etc/login.defs", pw->pw_dir);
|
||||
|
||||
/*
|
||||
* 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, "getdef: Could not allocate space for config info.\n");
|
||||
syslog(LOG_ERR, "getdef: 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
|
||||
|
13
unix/getdef.h
Normal file
13
unix/getdef.h
Normal file
@@ -0,0 +1,13 @@
|
||||
/* $Id: getdef.h,v 1.2 2002/01/11 21:07:04 mbroek Exp $ */
|
||||
|
||||
#ifndef _GETDEF_H
|
||||
#define _GETDEF_H
|
||||
|
||||
|
||||
int getdef_bool(const char *);
|
||||
long getdef_long(const char *, long);
|
||||
int getdef_num(const char *, int);
|
||||
char *getdef_str(const char *);
|
||||
void def_load (void);
|
||||
|
||||
#endif /* _GETDEF_H */
|
67
unix/limits.c
Normal file
67
unix/limits.c
Normal file
@@ -0,0 +1,67 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* $Id: limits.c,v 1.2 2003/08/15 20:05:36 mbroek Exp $
|
||||
* 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, 59 Temple Place, Suite 330, Boston, MA 02111-1307 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
9
unix/limits.h
Normal file
9
unix/limits.h
Normal file
@@ -0,0 +1,9 @@
|
||||
/* $Id: limits.h,v 1.2 2002/01/06 13:24:24 mbroek Exp $ */
|
||||
|
||||
#ifndef _LIMITS_H_H
|
||||
#define _LIMITS_H_H
|
||||
|
||||
|
||||
void setup_limits(const struct passwd *);
|
||||
|
||||
#endif
|
97
unix/log.c
Normal file
97
unix/log.c
Normal file
@@ -0,0 +1,97 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* $Id: log.c,v 1.2 2003/08/15 20:05:36 mbroek Exp $
|
||||
* 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, 59 Temple Place, Suite 330, Boston, MA 02111-1307 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);
|
||||
}
|
||||
|
8
unix/log.h
Normal file
8
unix/log.h
Normal file
@@ -0,0 +1,8 @@
|
||||
/* $Id: log.h,v 1.1 2002/01/05 13:57:10 mbroek Exp $ */
|
||||
|
||||
#ifndef _LOG_LOG_H
|
||||
#define _LOG_LOG_H
|
||||
|
||||
void dolastlog(struct lastlog *, const struct passwd *, const char *, const char *);
|
||||
|
||||
#endif
|
146
unix/login.defs.in
Normal file
146
unix/login.defs.in
Normal file
@@ -0,0 +1,146 @@
|
||||
#
|
||||
# $MBSE_ROOT/etc/login.defs - Configuration control definitions for mblogin.
|
||||
#
|
||||
# $Id: login.defs.in,v 1.3 2004/11/28 18:23:13 mbse Exp $
|
||||
|
||||
# Three items must be defined: MAIL_DIR, ENV_SUPATH, and ENV_PATH.
|
||||
# If unspecified, some arbitrary (and possibly incorrect) value will
|
||||
# be assumed. All other items are optional - if not specified then
|
||||
# the described action or option will be inhibited.
|
||||
#
|
||||
# Comment lines (lines beginning with "#") and blank lines are ignored.
|
||||
#
|
||||
|
||||
#
|
||||
# Allow user "mbse" to login and get a shell. You better leave this to "no"
|
||||
# and install ssh if you want to login using a shell.
|
||||
#
|
||||
ALLOW_MBSE no
|
||||
|
||||
#
|
||||
# Ask a user when his username is not found if he wants to register as new
|
||||
# user. If not, the user has to use the special account to start mbnewusr.
|
||||
# If no, it is not bbs user friendly,
|
||||
# If yes, usernames may be easy guessed, but most bbses do it like this.
|
||||
#
|
||||
ASK_NEWUSER yes
|
||||
|
||||
#
|
||||
# The newuser account name, defaults to "bbs". If you change this change it
|
||||
# in the password files, change it in mbsetup and in this file. Better
|
||||
# leave this unchanged.
|
||||
#
|
||||
NEWUSER_ACCOUNT bbs
|
||||
|
||||
#
|
||||
# Delay in seconds before being allowed another attempt after a login failure
|
||||
#
|
||||
FAIL_DELAY 3
|
||||
|
||||
#
|
||||
# Enable display of unknown usernames when login failures are recorded.
|
||||
#
|
||||
LOG_UNKFAIL_ENAB no
|
||||
|
||||
#
|
||||
# Enable logging of successful logins
|
||||
#
|
||||
LOG_OK_LOGINS no
|
||||
|
||||
#
|
||||
# Enable logging of lastlog login time info.
|
||||
#
|
||||
LASTLOG_ENAB yes
|
||||
|
||||
#
|
||||
# If defined, this file will be output before each login prompt.
|
||||
# Should not be needed, mgetty and getty will do this already.
|
||||
#
|
||||
ISSUE_FILE @prefix@/etc/issue
|
||||
|
||||
#
|
||||
# If defined, name of file whose presence which will inhibit non-root
|
||||
# logins. The contents of this file should be a message indicating
|
||||
# why logins are inhibited.
|
||||
#
|
||||
NOLOGINS_FILE /etc/nologin
|
||||
|
||||
#
|
||||
# If defined, an HZ environment parameter spec.
|
||||
#
|
||||
# for Linux/x86
|
||||
ENV_HZ HZ=100
|
||||
# For Linux/Alpha...
|
||||
#ENV_HZ HZ=1024
|
||||
|
||||
#
|
||||
# *REQUIRED* The default PATH settings, for superuser and normal users.
|
||||
#
|
||||
# (they are minimal, add the rest in the shell startup files)
|
||||
ENV_PATH PATH=/usr/local/bin:/bin:/usr/bin:@prefix@/bin
|
||||
|
||||
#
|
||||
# Terminal permissions
|
||||
#
|
||||
# TTYGROUP Login tty will be assigned this group ownership.
|
||||
# TTYPERM Login tty will be set to this permission.
|
||||
#
|
||||
# If you have a "write" program which is "setgid" to a special group
|
||||
# which owns the terminals, define TTYGROUP to the group number and
|
||||
# TTYPERM to 0620. Otherwise leave TTYGROUP commented out and assign
|
||||
# TTYPERM to either 622 or 600.
|
||||
#
|
||||
TTYGROUP tty
|
||||
TTYPERM 0620
|
||||
|
||||
#
|
||||
# Login configuration initializations:
|
||||
#
|
||||
# ERASECHAR Terminal ERASE character ('\010' = backspace).
|
||||
# KILLCHAR Terminal KILL character ('\025' = CTRL/U).
|
||||
# UMASK Default "umask" value.
|
||||
# ULIMIT Default "ulimit" value.
|
||||
#
|
||||
# The ERASECHAR and KILLCHAR are used only on System V machines.
|
||||
# The ULIMIT is used only if the system supports it.
|
||||
# (now it works with setrlimit too; ulimit is in 512-byte units)
|
||||
#
|
||||
# Prefix these values with "0" to get octal, "0x" to get hexadecimal.
|
||||
#
|
||||
ERASECHAR 0177
|
||||
KILLCHAR 025
|
||||
UMASK 007
|
||||
|
||||
#
|
||||
# Max number of login retries if password is bad
|
||||
#
|
||||
LOGIN_RETRIES 5
|
||||
|
||||
#
|
||||
# Max time in seconds for login
|
||||
#
|
||||
LOGIN_TIMEOUT 60
|
||||
|
||||
#
|
||||
# Only works if compiled with MD5_CRYPT defined:
|
||||
# If set to "yes", new passwords will be encrypted using the MD5-based
|
||||
# algorithm compatible with the one used by recent releases of FreeBSD.
|
||||
# It supports passwords of unlimited length and longer salt strings.
|
||||
# Set to "no" if you need to copy encrypted passwords to other systems
|
||||
# which don't understand the new algorithm. Default is "no".
|
||||
#
|
||||
MD5_CRYPT_ENAB yes
|
||||
|
||||
#
|
||||
# Should login be allowed if we can't cd to the home directory?
|
||||
# Default in no.
|
||||
#
|
||||
DEFAULT_HOME no
|
||||
|
||||
#
|
||||
# Enable setting of the umask group bits to be the same as owner bits
|
||||
# (examples: 022 -> 002, 077 -> 007) for non-root users, if the uid is
|
||||
# the same as gid, and username is the same as the primary group name.
|
||||
#
|
||||
USERGROUPS_ENAB yes
|
||||
|
168
unix/loginprompt.c
Normal file
168
unix/loginprompt.c
Normal file
@@ -0,0 +1,168 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* $Id: loginprompt.c,v 1.3 2005/08/30 17:53:35 mbse Exp $
|
||||
* Purpose ...............: MBSE BBS Shadow Password Suite
|
||||
* Original Source .......: Shadow Password Suite
|
||||
* Original Copyright ....: Julianne Frances Haugh and others.
|
||||
*
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1997-2005
|
||||
*
|
||||
* 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, 59 Temple Place, Suite 330, Boston, MA 02111-1307 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");
|
||||
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);
|
||||
snprintf(envp[envc], strlen(nvar) + 32, "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
|
||||
}
|
9
unix/loginprompt.h
Normal file
9
unix/loginprompt.h
Normal file
@@ -0,0 +1,9 @@
|
||||
/* $Id: loginprompt.h,v 1.1 2002/01/05 13:57:10 mbroek Exp $ */
|
||||
|
||||
#ifndef _LOGINPROMPT_H
|
||||
#define _LOGINPROMPT_H
|
||||
|
||||
void login_exit(int);
|
||||
void login_prompt(const char *, char *, int);
|
||||
|
||||
#endif
|
848
unix/mblogin.c
Normal file
848
unix/mblogin.c
Normal file
@@ -0,0 +1,848 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* $Id: mblogin.c,v 1.9 2007/08/26 15:05:33 mbse Exp $
|
||||
* Purpose ...............: Login program for MBSE BBS.
|
||||
* Shadow Suite (c) ......: Julianne Frances Haugh
|
||||
*
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1997-2007
|
||||
*
|
||||
* 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, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "../config.h"
|
||||
#include "mblogin.h"
|
||||
#include "../lib/users.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 defined(__NetBSD__)
|
||||
#undef HAVE_UTMPX_H
|
||||
#endif
|
||||
#if HAVE_UTMPX_H
|
||||
#include <utmpx.h>
|
||||
#endif
|
||||
#include <utmp.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.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(void);
|
||||
static void init_env(void);
|
||||
static RETSIGTYPE alarm_handler(int);
|
||||
int main(int, char **);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* usage - print login command usage and exit
|
||||
*
|
||||
* login [ name ]
|
||||
* login -a hostname (for NetBSD)
|
||||
* 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
|
||||
|
||||
/* 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]);
|
||||
|
||||
/*
|
||||
* 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++) {
|
||||
if (argv[arg][0] == '-' && strlen(argv[arg]) > 2)
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void check_nologin(void)
|
||||
{
|
||||
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 = getdef_str("NOLOGINS_FILE");
|
||||
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)
|
||||
{
|
||||
char *cp, *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);
|
||||
} else if ((cp = getdef_str("ENV_HZ"))) {
|
||||
addenv(cp, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
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;
|
||||
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
|
||||
|
||||
/*
|
||||
* 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, "a:d:h:p")) != EOF) {
|
||||
switch (flag) {
|
||||
case 'p':
|
||||
pflg++;
|
||||
break;
|
||||
#ifdef __NetBSD__
|
||||
case 'a':
|
||||
#endif
|
||||
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 */
|
||||
|
||||
if (hflg) {
|
||||
/*
|
||||
* Only show this before a prompt from telnetd
|
||||
*/
|
||||
printf("\nMBSE BBS v%s (Release: %s)\n", VERSION, ReleaseDate);
|
||||
printf("%s\n\n", COPYRIGHT);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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(getdef_num("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);
|
||||
snprintf(userfile, PATH_MAX, "%s/etc/users.data", pw->pw_dir);
|
||||
|
||||
check_nologin();
|
||||
|
||||
init_env();
|
||||
|
||||
if (optind < argc) { /* get the user name */
|
||||
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
||||
#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 = getdef_num("LOGIN_TIMEOUT", ALARM);
|
||||
if (timeout > 0)
|
||||
alarm(timeout);
|
||||
|
||||
environ = newenvp; /* make new environment active */
|
||||
delay = getdef_num("FAIL_DELAY", 1);
|
||||
retries = getdef_num("LOGIN_RETRIES", 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 allowed from login.defs accept the name "mbse".
|
||||
*/
|
||||
FoundName = 0;
|
||||
if (strcmp(username, getdef_str("NEWUSER_ACCOUNT")) == 0) {
|
||||
FoundName = 1;
|
||||
}
|
||||
if ((getdef_bool("ALLOW_MBSE") != 0) && (strcmp(username, "mbse") == 0)) {
|
||||
FoundName = 1;
|
||||
}
|
||||
if (! FoundName) {
|
||||
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 (!FoundName) {
|
||||
if (getdef_bool("ASK_NEWUSER") != 0) {
|
||||
/*
|
||||
* User entered none excisting name, offer him/her the choice
|
||||
* to register as a new user.
|
||||
*/
|
||||
login_prompt(_("Do you want to register as new user? [y/N]: "), username, sizeof username);
|
||||
if ((username[0] && (toupper(username[0]) == 'Y'))) {
|
||||
FoundName = 1;
|
||||
preauth_flag = 0;
|
||||
STRFCPY(username, getdef_str("NEWUSER_ACCOUNT"));
|
||||
syslog(LOG_WARNING, "unknown user wants to register");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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, (pwd || getdef_bool("LOG_UNKFAIL_ENAB")) ? username : "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 (getenv("IFS")) /* don't export user IFS ... */
|
||||
addenv("IFS= \t\n", NULL); /* ... instead, set a safe IFS */
|
||||
|
||||
setutmp(username, tty, hostname); /* make entry in utmp & wtmp files */
|
||||
|
||||
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 */
|
||||
}
|
||||
|
||||
if (getdef_bool("LASTLOG_ENAB")) /* give last login and log this one */
|
||||
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();
|
||||
|
||||
shell (pwent.pw_shell, (char *) 0); /* exec the shell finally. */
|
||||
/*NOTREACHED*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
248
unix/mblogin.h
Normal file
248
unix/mblogin.h
Normal file
@@ -0,0 +1,248 @@
|
||||
/* $Id: mblogin.h,v 1.3 2003/12/23 18:33:42 mbroek Exp $ */
|
||||
|
||||
#ifndef _MBLOGIN_H
|
||||
#define _MBLOGIN_H
|
||||
|
||||
#define ReleaseDate __DATE__
|
||||
|
||||
#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
|
||||
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
||||
|
||||
#endif
|
1163
unix/mbpasswd.c
Normal file
1163
unix/mbpasswd.c
Normal file
File diff suppressed because it is too large
Load Diff
47
unix/mbpasswd.h
Normal file
47
unix/mbpasswd.h
Normal file
@@ -0,0 +1,47 @@
|
||||
#ifndef _MBPASSWD_H
|
||||
#define _MBPASSWD_H
|
||||
|
||||
/* $Id: mbpasswd.h,v 1.4 2005/08/27 12:06:49 mbse Exp $ */
|
||||
|
||||
|
||||
/* 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);
|
||||
#if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__)
|
||||
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
|
||||
char *Basename(char *);
|
||||
|
||||
#endif
|
||||
|
518
unix/mbuseradd.c
Normal file
518
unix/mbuseradd.c
Normal file
@@ -0,0 +1,518 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* $Id: mbuseradd.c,v 1.24 2007/05/28 10:40:24 mbse Exp $
|
||||
* Purpose ...............: setuid root version of useradd
|
||||
*
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1997-2007
|
||||
*
|
||||
* 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, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "../config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <pwd.h>
|
||||
#include <sys/types.h>
|
||||
#include <grp.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 <syslog.h>
|
||||
#include <time.h>
|
||||
|
||||
#if (defined(__FreeBSD__) && __FreeBSD_version >= 600000)
|
||||
#define FreeBSD_sysctl 1
|
||||
#endif
|
||||
|
||||
#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(FreeBSD_sysctl)
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
#include "xmalloc.h"
|
||||
#include "mbuseradd.h"
|
||||
|
||||
|
||||
/*
|
||||
* Milliseconds timer, returns 0 on success.
|
||||
*/
|
||||
int msleep(int msecs)
|
||||
{
|
||||
int rc;
|
||||
struct timespec req, rem;
|
||||
|
||||
rem.tv_sec = 0;
|
||||
rem.tv_nsec = 0;
|
||||
req.tv_sec = msecs / 1000;
|
||||
req.tv_nsec = (msecs % 1000) * 1000000;
|
||||
|
||||
while (1) {
|
||||
rc = nanosleep(&req, &rem);
|
||||
if (rc == 0)
|
||||
break;
|
||||
if ((errno == EINVAL) || (errno == EFAULT))
|
||||
break;
|
||||
|
||||
/*
|
||||
* Error was EINTR, run timer again to complete.
|
||||
*/
|
||||
req.tv_sec = rem.tv_sec;
|
||||
req.tv_nsec = rem.tv_nsec;
|
||||
rem.tv_sec = 0;
|
||||
rem.tv_nsec = 0;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int execute(char **args, char *in, char *out, char *err)
|
||||
{
|
||||
char buf[PATH_MAX];
|
||||
int i, pid, status = 0, rc = 0;
|
||||
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (args[i])
|
||||
snprintf(buf + strlen(buf), PATH_MAX - strlen(buf), " %s", args[i]);
|
||||
else
|
||||
break;
|
||||
}
|
||||
syslog(LOG_WARNING, "Execute:%s", buf);
|
||||
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
|
||||
if ((pid = fork()) == 0) {
|
||||
msleep(150);
|
||||
if (in) {
|
||||
close(0);
|
||||
if (open(in, O_RDONLY) != 0) {
|
||||
syslog(LOG_WARNING, "Reopen of stdin to %s failed", in);
|
||||
_exit(-1);
|
||||
}
|
||||
}
|
||||
if (out) {
|
||||
close(1);
|
||||
if (open(out, O_WRONLY | O_APPEND | O_CREAT,0600) != 1) {
|
||||
syslog(LOG_WARNING, "Reopen of stdout to %s failed", out);
|
||||
_exit(-1);
|
||||
}
|
||||
}
|
||||
if (err) {
|
||||
close(2);
|
||||
if (open(err, O_WRONLY | O_APPEND | O_CREAT,0600) != 2) {
|
||||
syslog(LOG_WARNING, "Reopen of stderr to %s failed", err);
|
||||
_exit(-1);
|
||||
}
|
||||
}
|
||||
rc = execv(args[0],args);
|
||||
syslog(LOG_WARNING, "Exec \"%s\" returned %d", args[0], rc);
|
||||
_exit(-1);
|
||||
}
|
||||
|
||||
do {
|
||||
rc = wait(&status);
|
||||
} while (((rc > 0) && (rc != pid)) || ((rc == -1) && (errno == EINTR)));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void makedir(char *path, mode_t mode, uid_t owner, gid_t group)
|
||||
{
|
||||
if (mkdir(path, mode) != 0) {
|
||||
syslog(LOG_WARNING, "Can't create directory %s:%s", path, strerror(errno));
|
||||
exit(2);
|
||||
}
|
||||
if ((chown(path, owner, group)) == -1) {
|
||||
syslog(LOG_WARNING, "Unable to change ownership of %s", path);
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Internal version of basename to make this better portable.
|
||||
*/
|
||||
char *Basename(char *str)
|
||||
{
|
||||
char *cp = strrchr(str, '/');
|
||||
|
||||
return cp ? cp+1 : str;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* 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 *temp, *shell, *homedir, *args[16], *parent;
|
||||
int i;
|
||||
struct passwd *pwent, *pwuser;
|
||||
struct group *gr;
|
||||
pid_t ppid;
|
||||
#if defined(__OpenBSD__)
|
||||
#define ARG_SIZE 60
|
||||
static char **s, buf[ARG_SIZE];
|
||||
size_t siz = 100;
|
||||
char **p;
|
||||
int mib[4];
|
||||
#elif defined(__NetBSD__) || defined(FreeBSD_sysctl)
|
||||
static char **s;
|
||||
size_t siz = 100;
|
||||
int mib[4];
|
||||
#else
|
||||
FILE *fp;
|
||||
#endif
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check calling username
|
||||
*/
|
||||
ppid = getuid();
|
||||
pwent = getpwuid(ppid);
|
||||
if (!pwent) {
|
||||
fprintf(stderr, "mbuseradd: Cannot determine your user name.\n");
|
||||
exit(1);
|
||||
}
|
||||
if (strcmp(pwent->pw_name, (char *)"mbse") && strcmp(pwent->pw_name, (char *)"bbs")) {
|
||||
fprintf(stderr, "mbuseradd: only users `mbse' and `bbs' may do this.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get my groupname, this must be "bbs", other users may not
|
||||
* use this program, not even root.
|
||||
*/
|
||||
gr = getgrgid(pwent->pw_gid);
|
||||
if (!gr) {
|
||||
fprintf(stderr, "mbuseradd: Cannot determine group name.\n");
|
||||
exit(1);
|
||||
}
|
||||
if (strcmp(gr->gr_name, (char *)"bbs")) {
|
||||
fprintf(stderr, "mbuseradd: You are not a member of group `bbs'.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find out the name of our parent.
|
||||
*/
|
||||
temp = calloc(PATH_MAX, sizeof(char));
|
||||
ppid = getppid();
|
||||
|
||||
#if defined(__OpenBSD__)
|
||||
/*
|
||||
* Systems that use sysctl to get process information
|
||||
*/
|
||||
mib[0] = CTL_KERN;
|
||||
mib[1] = KERN_PROC_ARGS;
|
||||
mib[2] = ppid;
|
||||
mib[3] = KERN_PROC_ARGV;
|
||||
if ((s = realloc(s, siz)) == NULL) {
|
||||
fprintf(stderr, "mbuseradd: no memory\n");
|
||||
exit(1);
|
||||
}
|
||||
if (sysctl(mib, 4, s, &siz, NULL, 0) == -1) {
|
||||
perror("");
|
||||
fprintf(stderr, "mbuseradd: sysctl call failed\n");
|
||||
exit(1);
|
||||
}
|
||||
buf[0] = '\0';
|
||||
for (p = s; *p != NULL; p++) {
|
||||
if (p != s)
|
||||
strlcat(buf, " ", sizeof(buf));
|
||||
strlcat(buf, *p, sizeof(buf));
|
||||
}
|
||||
parent = xstrcpy(buf);
|
||||
#elif defined(__NetBSD__)
|
||||
/*
|
||||
* Systems that use sysctl to get process information
|
||||
*/
|
||||
mib[0] = CTL_KERN;
|
||||
mib[1] = KERN_PROC_ARGS;
|
||||
mib[2] = ppid;
|
||||
mib[3] = KERN_PROC_ARGV;
|
||||
if ((s = realloc(s, siz)) == NULL) {
|
||||
fprintf(stderr, "mbuseradd: no memory\n");
|
||||
exit(1);
|
||||
}
|
||||
if (sysctl(mib, 4, s, &siz, NULL, 0) == -1) {
|
||||
perror("");
|
||||
fprintf(stderr, "mbuseradd: sysctl call failed\n");
|
||||
exit(1);
|
||||
}
|
||||
parent = xstrcpy((char *)s);
|
||||
#elif defined(FreeBSD_sysctl)
|
||||
/*
|
||||
* For FreeBSD 6.0 and later.
|
||||
*/
|
||||
mib[0] = CTL_KERN;
|
||||
mib[1] = KERN_PROC;
|
||||
mib[2] = KERN_PROC_ARGS;
|
||||
mib[3] = ppid;
|
||||
if ((s = realloc(s, siz)) == NULL) {
|
||||
fprintf(stderr, "mbuseradd: no memory\n");
|
||||
exit(1);
|
||||
}
|
||||
if (sysctl(mib, 4, s, &siz, NULL, 0) == -1) {
|
||||
perror("");
|
||||
fprintf(stderr, "mbuseradd: sysctl call failed\n");
|
||||
exit(1);
|
||||
}
|
||||
parent = xstrcpy((char *)s);
|
||||
#else
|
||||
/*
|
||||
* Systems with /proc filesystem like Linux, old FreeBSD
|
||||
*/
|
||||
snprintf(temp, PATH_MAX, "/proc/%d/cmdline", ppid);
|
||||
if ((fp = fopen(temp, "r")) == NULL) {
|
||||
fprintf(stderr, "mbuseradd: can't read %s\n", temp);
|
||||
exit(1);
|
||||
}
|
||||
fgets(temp, PATH_MAX-1, fp);
|
||||
fclose(fp);
|
||||
parent = xstrcpy(Basename(temp));
|
||||
#endif
|
||||
|
||||
if (strcmp((char *)"-mbnewusr", parent)) {
|
||||
fprintf(stderr, "mbuseradd: illegal parent \"%s\"\n", parent);
|
||||
free(temp);
|
||||
free(parent);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(args, 0, sizeof(args));
|
||||
|
||||
shell = calloc(PATH_MAX, sizeof(char));
|
||||
homedir = 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);
|
||||
|
||||
/*
|
||||
* 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("mbuseradd", LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_AUTH);
|
||||
syslog(LOG_WARNING, "mbuseradd %s %s %s %s", argv[1], argv[2], argv[3], argv[4]);
|
||||
|
||||
/*
|
||||
* Build command to add user entry to the /etc/passwd and /etc/shadow
|
||||
* files. We use the systems own useradd program.
|
||||
*/
|
||||
#if defined(__linux__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
if ((access("/usr/bin/useradd", R_OK)) == 0)
|
||||
args[0] = (char *)"/usr/bin/useradd";
|
||||
else if ((access("/bin/useradd", R_OK)) == 0)
|
||||
args[0] = (char *)"/bin/useradd";
|
||||
else if ((access("/usr/sbin/useradd", R_OK)) == 0)
|
||||
args[0] = (char *)"/usr/sbin/useradd";
|
||||
else if ((access("/sbin/useradd", R_OK)) == 0)
|
||||
args[0] = (char *)"/sbin/useradd";
|
||||
else {
|
||||
syslog(LOG_WARNING, "Can't find useradd");
|
||||
exit(1);
|
||||
}
|
||||
#elif __FreeBSD__
|
||||
if ((access("/usr/sbin/pw", X_OK)) == 0)
|
||||
args[0] = (char *)"/usr/sbin/pw";
|
||||
else if ((access("/sbin/pw", X_OK)) == 0)
|
||||
args[0] = (char *)"/sbin/pw";
|
||||
else {
|
||||
syslog(LOG_WARNING, "Can't find pw");
|
||||
exit(1);
|
||||
}
|
||||
#else
|
||||
#error "Don't know how to add a user on this OS"
|
||||
#endif
|
||||
|
||||
snprintf(shell, PATH_MAX, "%s/bin/mbsebbs", getenv("MBSE_ROOT"));
|
||||
snprintf(homedir, PATH_MAX, "%s/%s", argv[4], argv[2]);
|
||||
|
||||
#if defined(__linux__)
|
||||
args[1] = (char *)"-c";
|
||||
args[2] = argv[3];
|
||||
args[3] = (char *)"-d";
|
||||
args[4] = homedir;
|
||||
args[5] = (char *)"-g";
|
||||
args[6] = argv[1];
|
||||
args[7] = (char *)"-s";
|
||||
args[8] = shell;
|
||||
args[9] = argv[2];
|
||||
args[10] = NULL;
|
||||
#elif defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
args[1] = (char *)"-c";
|
||||
args[2] = argv[3];
|
||||
args[3] = (char *)"-d";
|
||||
args[4] = homedir;
|
||||
args[5] = (char *)"-g";
|
||||
args[6] = argv[1];
|
||||
args[7] = (char *)"-s";
|
||||
args[8] = shell;
|
||||
args[9] = (char *)"-m";
|
||||
args[10] = argv[2];
|
||||
args[11] = NULL;
|
||||
#elif defined(__FreeBSD__)
|
||||
args[1] = (char *)"useradd";
|
||||
args[2] = argv[2];
|
||||
args[3] = (char *)"-c";
|
||||
args[4] = argv[3];
|
||||
args[5] = (char *)"-d";
|
||||
args[6] = homedir;
|
||||
args[7] = (char *)"-g";
|
||||
args[8] = argv[1];
|
||||
args[9] = (char *)"-s";
|
||||
args[10] = shell;
|
||||
args[11] = NULL;
|
||||
#else
|
||||
#error "Don't know how to add a user on this OS"
|
||||
#endif
|
||||
|
||||
if (execute(args, (char *)"/dev/tty", (char *)"/dev/tty", (char *)"/dev/tty") != 0) {
|
||||
syslog(LOG_WARNING, "Failed to create unix account");
|
||||
exit(1);
|
||||
}
|
||||
syslog(LOG_WARNING, "Created Unix account");
|
||||
|
||||
/*
|
||||
* Now create directories and files for this user.
|
||||
*/
|
||||
if ((pwent = getpwnam((char *)"mbse")) == NULL) {
|
||||
syslog(LOG_WARNING, "Can't get password entry for \"mbse\"");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* Check bbs users base home directory
|
||||
*/
|
||||
if ((access(argv[4], R_OK)) != 0) {
|
||||
syslog(LOG_WARNING, "No bbs base homedirectory, creating..");
|
||||
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.
|
||||
*/
|
||||
if ((access(homedir, R_OK)) == 0) {
|
||||
if ((access("/bin/rm", X_OK)) == 0)
|
||||
args[0] = (char *)"/bin/rm";
|
||||
else if ((access("/usr/bin/rm", X_OK)) == 0)
|
||||
args[0] = (char *)"/usr/bin/rm";
|
||||
else {
|
||||
syslog(LOG_WARNING, "Can't find rm");
|
||||
exit(2);
|
||||
}
|
||||
args[1] = (char *)"-Rf";
|
||||
args[2] = homedir;
|
||||
args[3] = NULL;
|
||||
i = execute(args, (char *)"/dev/tty", (char *)"/dev/tty", (char *)"/dev/tty");
|
||||
if (i != 0) {
|
||||
syslog(LOG_WARNING, "Unable remove old home directory");
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Create users home directory.
|
||||
*/
|
||||
if ((pwuser = getpwnam(argv[2])) == NULL) {
|
||||
syslog(LOG_WARNING, "Can't get passwd entry for %s", argv[2]);
|
||||
exit(2);
|
||||
}
|
||||
makedir(homedir, 0770, pwuser->pw_uid, pwent->pw_gid);
|
||||
|
||||
/*
|
||||
* Create Maildir and subdirs for Qmail.
|
||||
*/
|
||||
snprintf(temp, PATH_MAX, "%s/%s/Maildir", argv[4], argv[2]);
|
||||
makedir(temp, 0700, pwuser->pw_uid, pwent->pw_gid);
|
||||
snprintf(temp, PATH_MAX, "%s/%s/Maildir/cur", argv[4], argv[2]);
|
||||
makedir(temp, 0700, pwuser->pw_uid, pwent->pw_gid);
|
||||
snprintf(temp, PATH_MAX, "%s/%s/Maildir/new", argv[4], argv[2]);
|
||||
makedir(temp, 0700, pwuser->pw_uid, pwent->pw_gid);
|
||||
snprintf(temp, PATH_MAX, "%s/%s/Maildir/tmp", argv[4], argv[2]);
|
||||
makedir(temp, 0700, pwuser->pw_uid, pwent->pw_gid);
|
||||
|
||||
#ifdef _VPOPMAIL_PATH
|
||||
snprintf(temp, PATH_MAX, "%s/vadduser", _VPOPMAIL_PATH);
|
||||
args[0] = temp;
|
||||
args[1] = argv[2];
|
||||
args[2] = argv[2];
|
||||
args[3] = NULL;
|
||||
|
||||
if (execute(args, (char *)"/dev/tty", (char *)"/dev/tty", (char *)"/dev/tty") != 0) {
|
||||
syslog(LOG_WARNING, "Failed to create vpopmail account");
|
||||
} else {
|
||||
syslog(LOG_WARNING, "Created vpopmail account");
|
||||
}
|
||||
#endif
|
||||
|
||||
free(shell);
|
||||
free(temp);
|
||||
free(homedir);
|
||||
syslog(LOG_WARNING, "Added system account for user\"%s\"", argv[2]);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Help()
|
||||
{
|
||||
fprintf(stderr, "\nmbuseradd commandline:\n\n");
|
||||
fprintf(stderr, "mbuseradd [gid] [name] [comment] [usersdir]\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
10
unix/mbuseradd.h
Normal file
10
unix/mbuseradd.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#ifndef _MBUSERADD_H
|
||||
#define _MBUSERADD_H
|
||||
|
||||
|
||||
int execute(char **, char *, char *, char *);
|
||||
void makedir(char *, mode_t, uid_t, gid_t);
|
||||
void Help(void);
|
||||
|
||||
#endif
|
||||
|
72
unix/myname.c
Normal file
72
unix/myname.c
Normal file
@@ -0,0 +1,72 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* 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, 59 Temple Place, Suite 330, Boston, MA 02111-1307 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);
|
||||
}
|
||||
|
||||
|
7
unix/myname.h
Normal file
7
unix/myname.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#ifndef _MYNAME_H
|
||||
#define _MYNAME_H
|
||||
|
||||
struct passwd *get_my_pwent(void);
|
||||
|
||||
#endif
|
||||
|
73
unix/putpwent.c
Normal file
73
unix/putpwent.c
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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
|
||||
|
14
unix/putpwent.h
Normal file
14
unix/putpwent.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#include "../config.h"
|
||||
|
||||
#ifndef HAVE_PUTPWENT
|
||||
|
||||
#ifndef _PUTPWENT_H
|
||||
#define _PUTPWENT_H
|
||||
|
||||
|
||||
int putpwent(const struct passwd *, FILE *);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
348
unix/pw_util.c
Normal file
348
unix/pw_util.c
Normal file
@@ -0,0 +1,348 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* $Id: pw_util.c,v 1.11 2004/12/28 15:30:53 mbse Exp $
|
||||
* Purpose ...............: FreeBSD/NetBSD password utilities.
|
||||
* Remark ................: Taken from FreeBSD and modified for MBSE BBS.
|
||||
*
|
||||
*****************************************************************************
|
||||
* 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, 59 Temple Place, Suite 330, Boston, MA 02111-1307 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.
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
|
||||
#include "../config.h"
|
||||
#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 <errno.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 for %s...", username);
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||
execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", "-u", username, tempname, NULL);
|
||||
#elif defined(__NetBSD__)
|
||||
execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", tempname, NULL);
|
||||
#else
|
||||
#error "Not FreeBSD, OpenBSD or NetBSD - don't know what to do"
|
||||
#endif
|
||||
}
|
||||
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;
|
||||
}
|
||||
for (p = buf; *p != '\n'; p++)
|
||||
if (*p != ' ' && *p != '\t')
|
||||
break;
|
||||
if (*p == '#' || *p == '\n') {
|
||||
(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;
|
||||
}
|
||||
#if defined(__FreeBSD__)
|
||||
(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);
|
||||
#elif defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
(void)fprintf(to, "%s:%s:%s:%s:%s:%s:%s:%s:%s:%s\n",
|
||||
pw->pw_name, pw->pw_passwd,
|
||||
uidstr, gidstr,
|
||||
pw->pw_class,
|
||||
chgstr, expstr,
|
||||
pw->pw_gecos, pw->pw_dir, pw->pw_shell);
|
||||
#else
|
||||
#error "Not FreeBSD, OpenBSD or NetBSD - don't know what to do"
|
||||
#endif
|
||||
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 */
|
||||
#if defined(__FreeBSD__)
|
||||
(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);
|
||||
#elif defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
(void)fprintf(to, "%s:%s:%s:%s:%s:%s:%s:%s:%s:%s\n",
|
||||
pw->pw_name, pw->pw_passwd,
|
||||
uidstr, gidstr,
|
||||
pw->pw_class,
|
||||
chgstr, expstr,
|
||||
pw->pw_gecos, pw->pw_dir, pw->pw_shell);
|
||||
#else
|
||||
#error "Not FreeBSD, OpenBSD or NetBSD - don't know what to do"
|
||||
#endif
|
||||
}
|
||||
|
||||
if (ferror(to))
|
||||
err: pw_error(NULL, 1, 1);
|
||||
(void)fclose(to);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
52
unix/pw_util.h
Normal file
52
unix/pw_util.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/* $Id: pw_util.h,v 1.3 2004/12/28 15:30:53 mbse Exp $
|
||||
*
|
||||
* 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
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
|
||||
void pw_error __P((char *, int, int));
|
||||
void pw_init __P((void));
|
||||
int pw_lock __P((void));
|
||||
int pw_mkdb __P((char *));
|
||||
int pw_tmp __P((void));
|
||||
void pw_copy __P((int, int, struct passwd *));
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
135
unix/pwauth.c
Normal file
135
unix/pwauth.c
Normal file
@@ -0,0 +1,135 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* $Id: pwauth.c,v 1.4 2003/08/15 20:05:36 mbroek Exp $
|
||||
* 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, 59 Temple Place, Suite 330, Boston, MA 02111-1307 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;
|
||||
}
|
||||
|
||||
|
31
unix/pwauth.h
Normal file
31
unix/pwauth.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/* $Id: pwauth.h,v 1.1 2002/01/05 13:57:10 mbroek Exp $ */
|
||||
|
||||
#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
|
||||
|
98
unix/pwdcheck.c
Normal file
98
unix/pwdcheck.c
Normal file
@@ -0,0 +1,98 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* $Id: pwdcheck.c,v 1.2 2003/08/15 20:05:36 mbroek Exp $
|
||||
* 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, 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 */
|
||||
}
|
||||
|
8
unix/pwdcheck.h
Normal file
8
unix/pwdcheck.h
Normal file
@@ -0,0 +1,8 @@
|
||||
/* $Id: pwdcheck.h,v 1.1 2002/01/05 13:57:10 mbroek Exp $ */
|
||||
|
||||
#ifndef _PWDCHECK_H
|
||||
#define _PWDCHECK_H
|
||||
|
||||
void passwd_check(const char *, const char *, const char *);
|
||||
|
||||
#endif
|
249
unix/pwio.c
Normal file
249
unix/pwio.c
Normal file
@@ -0,0 +1,249 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* $Id: pwio.c,v 1.5 2004/12/28 15:30:53 mbse Exp $
|
||||
* 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, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||||
*****************************************************************************/
|
||||
|
||||
#if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__)
|
||||
|
||||
#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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__)
|
||||
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
|
||||
|
33
unix/pwio.h
Normal file
33
unix/pwio.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/* $Id: pwio.h,v 1.3 2004/12/28 15:30:53 mbse Exp $ */
|
||||
|
||||
#ifndef _PWIO_H
|
||||
#define _PWIO_H
|
||||
|
||||
#if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__)
|
||||
|
||||
#ifndef PASSWD_FILE
|
||||
#define PASSWD_FILE "/etc/passwd"
|
||||
#endif
|
||||
|
||||
#ifndef GROUP_FILE
|
||||
#define GROUP_FILE "/etc/group"
|
||||
#endif
|
||||
|
||||
struct passwd *__pw_dup (const struct passwd *);
|
||||
void __pw_set_changed (void);
|
||||
int pw_close (void);
|
||||
const struct passwd *pw_locate (const char *);
|
||||
int pw_lock (void);
|
||||
int pw_lock_first (void);
|
||||
int pw_name (const char *);
|
||||
const struct passwd *pw_next (void);
|
||||
int pw_open (int);
|
||||
int pw_remove (const char *);
|
||||
int pw_rewind (void);
|
||||
int pw_unlock (void);
|
||||
int pw_update (const struct passwd *);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
157
unix/rad64.c
Normal file
157
unix/rad64.c
Normal file
@@ -0,0 +1,157 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* 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, 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 */
|
||||
|
15
unix/rad64.h
Normal file
15
unix/rad64.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#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
|
||||
|
101
unix/salt.c
Normal file
101
unix/salt.c
Normal file
@@ -0,0 +1,101 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* $Id: salt.c,v 1.2 2003/08/15 20:05:36 mbroek Exp $
|
||||
* 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, 59 Temple Place, Suite 330, Boston, MA 02111-1307 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';
|
||||
|
||||
if (getdef_bool("MD5_CRYPT_ENAB")) {
|
||||
strcpy(result, "$1$"); /* magic for the new MD5 crypt() */
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
9
unix/salt.h
Normal file
9
unix/salt.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef _SALT_H
|
||||
#define _SALT_H
|
||||
|
||||
|
||||
char *crypt_make_salt(void);
|
||||
|
||||
|
||||
#endif
|
||||
|
120
unix/setugid.c
Normal file
120
unix/setugid.c
Normal file
@@ -0,0 +1,120 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* $Id: setugid.c,v 1.3 2003/08/15 20:05:36 mbroek Exp $
|
||||
* 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, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||||
*****************************************************************************/
|
||||
|
||||
/*
|
||||
* Separated from setup.c. --marekm
|
||||
*/
|
||||
|
||||
#include "../config.h"
|
||||
#include <stdio.h>
|
||||
#include <syslog.h>
|
||||
#include "mblogin.h"
|
||||
#include <pwd.h>
|
||||
#include <grp.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;
|
||||
}
|
10
unix/setugid.h
Normal file
10
unix/setugid.h
Normal file
@@ -0,0 +1,10 @@
|
||||
/* $Id: setugid.h,v 1.1 2002/01/05 13:57:10 mbroek Exp $ */
|
||||
|
||||
#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
|
111
unix/setupenv.c
Normal file
111
unix/setupenv.c
Normal file
@@ -0,0 +1,111 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* $Id: setupenv.c,v 1.2 2003/08/15 20:05:36 mbroek Exp $
|
||||
* 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, 59 Temple Place, Suite 330, Boston, MA 02111-1307 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"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* change to the user's home directory
|
||||
* set the HOME, SHELL, MAIL, PATH, and LOGNAME or USER environmental
|
||||
* variables.
|
||||
*/
|
||||
void setup_env(struct passwd *info)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
/*
|
||||
* 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) {
|
||||
static char temp_pw_dir[] = "/";
|
||||
if (!getdef_bool("DEFAULT_HOME") || chdir("/") == -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);
|
||||
}
|
||||
puts(_("No directory, logging in with HOME=/"));
|
||||
info->pw_dir = temp_pw_dir;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
cp = getdef_str("ENV_PATH");
|
||||
addenv(cp ? cp : "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);
|
||||
}
|
||||
|
8
unix/setupenv.h
Normal file
8
unix/setupenv.h
Normal file
@@ -0,0 +1,8 @@
|
||||
/* $Id: setupenv.h,v 1.1 2002/01/05 13:57:10 mbroek Exp $ */
|
||||
|
||||
#ifndef _SETUPENV_H
|
||||
#define _SETUPENV_H
|
||||
|
||||
void setup_env(struct passwd *);
|
||||
|
||||
#endif
|
167
unix/sgetpwent.c
Normal file
167
unix/sgetpwent.c
Normal file
@@ -0,0 +1,167 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* 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, 59 Temple Place, Suite 330, Boston, MA 02111-1307 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;
|
||||
}
|
||||
|
||||
|
7
unix/sgetpwent.h
Normal file
7
unix/sgetpwent.h
Normal file
@@ -0,0 +1,7 @@
|
||||
#ifndef _SGETPWENT_H
|
||||
#define _SGETPWENT_H
|
||||
|
||||
struct passwd * sgetpwent(const char *);
|
||||
|
||||
#endif
|
||||
|
226
unix/shadowio.c
Normal file
226
unix/shadowio.c
Normal file
@@ -0,0 +1,226 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* 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, 59 Temple Place, Suite 330, Boston, MA 02111-1307 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
|
||||
|
33
unix/shadowio.h
Normal file
33
unix/shadowio.h
Normal file
@@ -0,0 +1,33 @@
|
||||
#ifndef _SHADOWIO_H
|
||||
#define _SHADOWIO_H
|
||||
|
||||
#ifdef SHADOW_PASSWORD
|
||||
#ifndef SHADOW_FILE
|
||||
#define SHADOW_FILE "/etc/shadow"
|
||||
#endif
|
||||
|
||||
#ifdef SHADOWGRP
|
||||
#ifndef SGROUP_FILE
|
||||
#define SGROUP_FILE "/etc/gshadow"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
struct spwd *__spw_dup (const struct spwd *);
|
||||
void __spw_set_changed (void);
|
||||
int spw_close (void);
|
||||
int spw_file_present (void);
|
||||
const struct spwd *spw_locate (const char *);
|
||||
int spw_lock (void);
|
||||
int spw_name (const char *);
|
||||
const struct spwd *spw_next (void);
|
||||
int spw_open (int);
|
||||
int spw_remove (const char *);
|
||||
int spw_rewind (void);
|
||||
int spw_unlock (void);
|
||||
int spw_update (const struct spwd *);
|
||||
|
||||
#endif
|
||||
|
128
unix/shell.c
Normal file
128
unix/shell.c
Normal file
@@ -0,0 +1,128 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* $Id: shell.c,v 1.2 2003/08/15 20:05:36 mbroek Exp $
|
||||
* 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, 59 Temple Place, Suite 330, Boston, MA 02111-1307 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);
|
||||
}
|
||||
|
||||
|
8
unix/shell.h
Normal file
8
unix/shell.h
Normal file
@@ -0,0 +1,8 @@
|
||||
/* $Id: shell.h,v 1.1 2002/01/05 13:57:10 mbroek Exp $ */
|
||||
|
||||
#ifndef _SHELL_H
|
||||
#define _SHELL_H
|
||||
|
||||
void shell(const char *, const char *);
|
||||
|
||||
#endif
|
80
unix/sub.c
Normal file
80
unix/sub.c
Normal file
@@ -0,0 +1,80 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* $Id: sub.c,v 1.2 2003/08/15 20:05:36 mbroek Exp $
|
||||
* 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, 59 Temple Place, Suite 330, Boston, MA 02111-1307 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
8
unix/sub.h
Normal file
8
unix/sub.h
Normal file
@@ -0,0 +1,8 @@
|
||||
/* $Id: sub.h,v 1.1 2002/01/05 13:57:10 mbroek Exp $ */
|
||||
|
||||
#ifndef _SUB_H
|
||||
#define _SUB_H
|
||||
|
||||
void subsystem(const struct passwd *);
|
||||
|
||||
#endif
|
503
unix/utmp.c
Normal file
503
unix/utmp.c
Normal file
@@ -0,0 +1,503 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* $Id: utmp.c,v 1.7 2004/12/28 15:30:53 mbse Exp $
|
||||
* 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, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "../config.h"
|
||||
#include "mblogin.h"
|
||||
#include <utmp.h>
|
||||
|
||||
#if HAVE_UTMPX_H
|
||||
#include <utmpx.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
#if HAVE_LIBUTIL_H
|
||||
#include <libutil.h>
|
||||
#endif
|
||||
#if HAVE_UTIL_H
|
||||
#include <util.h>
|
||||
#endif
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include "utmp.h"
|
||||
|
||||
#if defined(__NetBSD__)
|
||||
#undef LOGIN_PROCESS
|
||||
#undef HAVE_UTMPX_H
|
||||
#endif
|
||||
|
||||
#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 */
|
||||
|
||||
/*
|
||||
* Also used for FreeBSD
|
||||
*/
|
||||
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;
|
||||
|
||||
printf("setutmp HAVE_UTMP_H\n");
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
#elif __FreeBSD__ || __NetBSD__ || __OpenBSD__
|
||||
|
||||
/*
|
||||
* FreeBSD/NetBSD/OpenBSD version, simple and mean.
|
||||
*/
|
||||
void setutmp(const char *name, const char *line, const char *host)
|
||||
{
|
||||
struct utmp utmp;
|
||||
|
||||
memset(&utmp, 0, sizeof(utmp));
|
||||
|
||||
strncpy(utmp.ut_line, line, (int) sizeof utmp.ut_line);
|
||||
strncpy(utmp.ut_name, name, sizeof utent.ut_name);
|
||||
strncpy(utmp.ut_host, host, sizeof utent.ut_host);
|
||||
(void) time (&utmp.ut_time);
|
||||
|
||||
login(&utmp);
|
||||
utent = utmp;
|
||||
}
|
||||
|
||||
|
||||
#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.
|
||||
*/
|
||||
|
||||
strncpy(utmp.ut_user, name, sizeof utent.ut_user);
|
||||
#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 */
|
29
unix/utmp.h
Normal file
29
unix/utmp.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/* $Id: utmp.h,v 1.4 2004/12/28 15:30:53 mbse Exp $ */
|
||||
|
||||
#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 *);
|
||||
#elif __FreeBSD__ || __NetBSD__ || __OpenBSD__
|
||||
void setutmp(const char *, const char *, const char *);
|
||||
#else /* !SVR4 */
|
||||
void setutmp(const char *, const char *);
|
||||
#endif
|
||||
|
||||
#endif
|
83
unix/xmalloc.c
Normal file
83
unix/xmalloc.c
Normal file
@@ -0,0 +1,83 @@
|
||||
/*****************************************************************************
|
||||
*
|
||||
* $Id: xmalloc.c,v 1.3 2005/08/27 12:06:49 mbse Exp $
|
||||
* Purpose ...............: MBSE BBS Shadow Password Suite
|
||||
* Original Source .......: Shadow Password Suite
|
||||
* Original Copyrioght ...: Julianne Frances Haugh and others.
|
||||
*
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1997-2005
|
||||
*
|
||||
* 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, 59 Temple Place, Suite 330, Boston, MA 02111-1307 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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
char *xstrcpy(char *src)
|
||||
{
|
||||
char *tmp;
|
||||
|
||||
if (src == NULL)
|
||||
return(NULL);
|
||||
tmp = xmalloc(strlen(src)+1);
|
||||
strcpy(tmp, src);
|
||||
return tmp;
|
||||
}
|
||||
|
11
unix/xmalloc.h
Normal file
11
unix/xmalloc.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef _XMALLOC_H
|
||||
#define _XMALLOC_H
|
||||
|
||||
/* $Id: xmalloc.h,v 1.2 2005/08/27 12:06:49 mbse Exp $ */
|
||||
|
||||
char *xmalloc(size_t);
|
||||
char *xstrdup(const char *);
|
||||
char *xstrcpy(char *);
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user