More mblogin fixes for FreeBSD
This commit is contained in:
parent
09de95f205
commit
81c0cc8f10
@ -3,7 +3,7 @@
|
||||
* $Id$
|
||||
* Purpose ...............: MBSE BBS Shadow Password Suite
|
||||
* Original Source .......: Shadow Password Suite
|
||||
* Original Copyrioght ...: Julianne Frances Haugh and others.
|
||||
* Original Copyright ....: Julianne Frances Haugh and others.
|
||||
*
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1997-2001
|
||||
@ -31,23 +31,21 @@
|
||||
*****************************************************************************/
|
||||
|
||||
#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;
|
||||
@ -61,30 +59,17 @@ int is_my_tty(const char *tty)
|
||||
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;
|
||||
|
||||
/*
|
||||
@ -103,7 +88,7 @@ void chown_tty(const char *tty, const struct passwd *info)
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (chown(tty, info->pw_uid, gid) || chmod(tty, getdef_num("TTYPERM", 0600))) {
|
||||
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();
|
||||
|
326
mbsebbs/limits.c
326
mbsebbs/limits.c
@ -40,273 +40,13 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <syslog.h>
|
||||
#include <utmp.h>
|
||||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
#include "getdef.h"
|
||||
#include "utmp.h"
|
||||
#include "limits.h"
|
||||
|
||||
|
||||
#ifdef HAVE_SYS_RESOURCE_H
|
||||
#include <sys/resource.h>
|
||||
#define LIMITS
|
||||
#endif
|
||||
|
||||
#ifdef LIMITS
|
||||
|
||||
#ifndef LIMITS_FILE
|
||||
#define LIMITS_FILE "/etc/limits"
|
||||
#endif
|
||||
|
||||
#define LOGIN_ERROR_RLIMIT 1
|
||||
#define LOGIN_ERROR_LOGIN 2
|
||||
|
||||
|
||||
|
||||
/* Set a limit on a resource */
|
||||
/*
|
||||
* rlimit - RLIMIT_XXXX
|
||||
* value - string value to be read
|
||||
* multiplier - value*multiplier is the actual limit
|
||||
*/
|
||||
int setrlimit_value(unsigned int rlimit, const char *value, unsigned int multiplier)
|
||||
{
|
||||
struct rlimit rlim;
|
||||
long limit;
|
||||
char **endptr = (char **) &value;
|
||||
const char *value_orig = value;
|
||||
|
||||
limit = strtol(value, endptr, 10);
|
||||
if (limit == 0 && value_orig == *endptr) /* no chars read */
|
||||
return 0;
|
||||
limit *= multiplier;
|
||||
rlim.rlim_cur = limit;
|
||||
rlim.rlim_max = limit;
|
||||
if (setrlimit(rlimit, &rlim))
|
||||
return LOGIN_ERROR_RLIMIT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int set_prio(const char *value)
|
||||
{
|
||||
int prio;
|
||||
char **endptr = (char **) &value;
|
||||
|
||||
prio = strtol(value, endptr, 10);
|
||||
if ((prio == 0) && (value == *endptr))
|
||||
return 0;
|
||||
if (setpriority(PRIO_PROCESS, 0, prio))
|
||||
return LOGIN_ERROR_RLIMIT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int set_umask(const char *value)
|
||||
{
|
||||
mode_t mask;
|
||||
char **endptr = (char **) &value;
|
||||
|
||||
mask = strtol(value, endptr, 8) & 0777;
|
||||
if ((mask == 0) && (value == *endptr))
|
||||
return 0;
|
||||
umask(mask);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Function setup_user_limits - checks/set limits for the curent login
|
||||
* Original idea from Joel Katz's lshell. Ported to shadow-login
|
||||
* by Cristian Gafton - gafton@sorosis.ro
|
||||
*
|
||||
* We are passed a string of the form ('BASH' constants for ulimit)
|
||||
* [Aa][Cc][Dd][Ff][Mm][Nn][Rr][Ss][Tt][Uu][Ll][Pp]
|
||||
* (eg. 'C2F256D2048N5' or 'C2 F256 D2048 N5')
|
||||
* where:
|
||||
* [Aa]: a = RLIMIT_AS max address space (KB)
|
||||
* [Cc]: c = RLIMIT_CORE max core file size (KB)
|
||||
* [Dd]: d = RLIMIT_DATA max data size (KB)
|
||||
* [Ff]: f = RLIMIT_FSIZE max file size (KB)
|
||||
* [Mm]: m = RLIMIT_MEMLOCK max locked-in-memory address space (KB)
|
||||
* [Nn]: n = RLIMIT_NOFILE max number of open files
|
||||
* [Rr]: r = RLIMIT_RSS max resident set size (KB)
|
||||
* [Ss]: s = RLIMIT_STACK max stack size (KB)
|
||||
* [Tt]: t = RLIMIT_CPU max CPU time (MIN)
|
||||
* [Uu]: u = RLIMIT_NPROC max number of processes
|
||||
* [Kk]: k = file creation masK (umask)
|
||||
* [Ll]: l = max number of logins for this user
|
||||
* [Pp]: p = process priority -20..20 (negative = high, positive = low)
|
||||
*
|
||||
* Return value:
|
||||
* 0 = okay, of course
|
||||
* LOGIN_ERROR_RLIMIT = error setting some RLIMIT
|
||||
* LOGIN_ERROR_LOGIN = error - too many logins for this user
|
||||
*
|
||||
* buf - the limits string
|
||||
* name - the username
|
||||
*/
|
||||
int do_user_limits(const char *buf, const char *name)
|
||||
{
|
||||
const char *pp;
|
||||
int retval = 0;
|
||||
|
||||
pp = buf;
|
||||
|
||||
while (*pp != '\0') switch(*pp++) {
|
||||
#ifdef RLIMIT_AS
|
||||
case 'a':
|
||||
case 'A':
|
||||
/* RLIMIT_AS - max address space (KB) */
|
||||
retval |= setrlimit_value(RLIMIT_AS, pp, 1024);
|
||||
#endif
|
||||
#ifdef RLIMIT_CPU
|
||||
case 't':
|
||||
case 'T':
|
||||
/* RLIMIT_CPU - max CPU time (MIN) */
|
||||
retval |= setrlimit_value(RLIMIT_CPU, pp, 60);
|
||||
break;
|
||||
#endif
|
||||
#ifdef RLIMIT_DATA
|
||||
case 'd':
|
||||
case 'D':
|
||||
/* RLIMIT_DATA - max data size (KB) */
|
||||
retval |= setrlimit_value(RLIMIT_DATA, pp, 1024);
|
||||
break;
|
||||
#endif
|
||||
#ifdef RLIMIT_FSIZE
|
||||
case 'f':
|
||||
case 'F':
|
||||
/* RLIMIT_FSIZE - Maximum filesize (KB) */
|
||||
retval |= setrlimit_value(RLIMIT_FSIZE, pp, 1024);
|
||||
break;
|
||||
#endif
|
||||
#ifdef RLIMIT_NPROC
|
||||
case 'u':
|
||||
case 'U':
|
||||
/* RLIMIT_NPROC - max number of processes */
|
||||
retval |= setrlimit_value(RLIMIT_NPROC, pp, 1);
|
||||
break;
|
||||
#endif
|
||||
#ifdef RLIMIT_CORE
|
||||
case 'c':
|
||||
case 'C':
|
||||
/* RLIMIT_CORE - max core file size (KB) */
|
||||
retval |= setrlimit_value(RLIMIT_CORE, pp, 1024);
|
||||
break;
|
||||
#endif
|
||||
#ifdef RLIMIT_MEMLOCK
|
||||
case 'm':
|
||||
case 'M':
|
||||
/* RLIMIT_MEMLOCK - max locked-in-memory address space (KB) */
|
||||
retval |= setrlimit_value(RLIMIT_MEMLOCK, pp, 1024);
|
||||
break;
|
||||
#endif
|
||||
#ifdef RLIMIT_NOFILE
|
||||
case 'n':
|
||||
case 'N':
|
||||
/* RLIMIT_NOFILE - max number of open files */
|
||||
retval |= setrlimit_value(RLIMIT_NOFILE, pp, 1);
|
||||
break;
|
||||
#endif
|
||||
#ifdef RLIMIT_RSS
|
||||
case 'r':
|
||||
case 'R':
|
||||
/* RLIMIT_RSS - max resident set size (KB) */
|
||||
retval |= setrlimit_value(RLIMIT_RSS, pp, 1024);
|
||||
break;
|
||||
#endif
|
||||
#ifdef RLIMIT_STACK
|
||||
case 's':
|
||||
case 'S':
|
||||
/* RLIMIT_STACK - max stack size (KB) */
|
||||
retval |= setrlimit_value(RLIMIT_STACK, pp, 1024);
|
||||
break;
|
||||
#endif
|
||||
case 'k':
|
||||
case 'K':
|
||||
retval |= set_umask(pp);
|
||||
break;
|
||||
case 'l':
|
||||
case 'L':
|
||||
/* LIMIT the number of concurent logins, not for MBSE BBS. */
|
||||
break;
|
||||
case 'p':
|
||||
case 'P':
|
||||
retval |= set_prio(pp);
|
||||
break;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int setup_user_limits(const char *uname)
|
||||
{
|
||||
/* TODO: allow and use @group syntax --cristiang */
|
||||
FILE *fil;
|
||||
char buf[1024];
|
||||
char name[1024];
|
||||
char limits[1024];
|
||||
char deflimits[1024];
|
||||
char tempbuf[1024];
|
||||
|
||||
/* init things */
|
||||
memzero(buf, sizeof(buf));
|
||||
memzero(name, sizeof(name));
|
||||
memzero(limits, sizeof(limits));
|
||||
memzero(deflimits, sizeof(deflimits));
|
||||
memzero(tempbuf, sizeof(tempbuf));
|
||||
|
||||
/* start the checks */
|
||||
fil = fopen(LIMITS_FILE, "r");
|
||||
if (fil == NULL) {
|
||||
#if 0 /* no limits file is ok, not everyone is a BOFH :-). --marekm */
|
||||
SYSLOG((LOG_WARN, NO_LIMITS, uname, LIMITS_FILE));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
/* The limits file have the following format:
|
||||
* - '#' (comment) chars only as first chars on a line;
|
||||
* - username must start on first column
|
||||
* A better (smarter) checking should be done --cristiang */
|
||||
while (fgets(buf, 1024, fil) != NULL) {
|
||||
if (buf[0]=='#' || buf[0]=='\n')
|
||||
continue;
|
||||
memzero(tempbuf, sizeof(tempbuf));
|
||||
/* a valid line should have a username, then spaces,
|
||||
* then limits
|
||||
* we allow the format:
|
||||
* username L2 D2048 R4096
|
||||
* where spaces={' ',\t}. Also, we reject invalid limits.
|
||||
* Imposing a limit should be done with care, so a wrong
|
||||
* entry means no care anyway :-). A '-' as a limits
|
||||
* strings means no limits --cristiang */
|
||||
if (sscanf(buf, "%s%[ACDFMNRSTULPacdfmnrstulp0-9 \t-]",
|
||||
name, tempbuf) == 2) {
|
||||
if (strcmp(name, uname) == 0) {
|
||||
strcpy(limits, tempbuf);
|
||||
break;
|
||||
} else if (strcmp(name, "*") == 0) {
|
||||
strcpy(deflimits, tempbuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(fil);
|
||||
if (limits[0] == '\0') {
|
||||
/* no user specific limits */
|
||||
if (deflimits[0] == '\0') /* no default limits */
|
||||
return 0;
|
||||
strcpy(limits, deflimits); /* use the default limits */
|
||||
}
|
||||
return do_user_limits(limits, uname);
|
||||
}
|
||||
#endif /* LIMITS */
|
||||
|
||||
|
||||
void setup_usergroups(const struct passwd *info)
|
||||
void setup_limits(const struct passwd *info)
|
||||
{
|
||||
const struct group *grp;
|
||||
mode_t oldmask;
|
||||
@ -325,67 +65,3 @@ void setup_usergroups(const struct passwd *info)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* set the process nice, ulimit, and umask from the password file entry
|
||||
*/
|
||||
|
||||
void setup_limits(const struct passwd *info)
|
||||
{
|
||||
char *cp;
|
||||
int i;
|
||||
long l;
|
||||
|
||||
if (getdef_bool("USERGROUPS_ENAB"))
|
||||
setup_usergroups(info);
|
||||
|
||||
/*
|
||||
* See if the GECOS field contains values for NICE, UMASK or ULIMIT.
|
||||
* If this feature is enabled in /etc/login.defs, we make those
|
||||
* values the defaults for this login session.
|
||||
*/
|
||||
|
||||
if (getdef_bool("QUOTAS_ENAB")) {
|
||||
#ifdef LIMITS
|
||||
if (info->pw_uid != 0)
|
||||
if (setup_user_limits(info->pw_name) & LOGIN_ERROR_LOGIN) {
|
||||
fprintf(stderr, _("Too many logins.\n"));
|
||||
sleep(2);
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
for (cp = info->pw_gecos ; cp != NULL ; cp = strchr (cp, ',')) {
|
||||
if (*cp == ',')
|
||||
cp++;
|
||||
|
||||
if (strncmp (cp, "pri=", 4) == 0) {
|
||||
i = atoi (cp + 4);
|
||||
if (i >= -20 && i <= 20)
|
||||
(void) nice (i);
|
||||
|
||||
continue;
|
||||
}
|
||||
if (strncmp (cp, "ulimit=", 7) == 0) {
|
||||
l = strtol (cp + 7, (char **) 0, 10);
|
||||
set_filesize_limit(l);
|
||||
continue;
|
||||
}
|
||||
if (strncmp (cp, "umask=", 6) == 0) {
|
||||
i = strtol (cp + 6, (char **) 0, 8) & 0777;
|
||||
(void) umask (i);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void set_filesize_limit(int blocks)
|
||||
{
|
||||
struct rlimit rlimit_fsize;
|
||||
|
||||
rlimit_fsize.rlim_cur = rlimit_fsize.rlim_max = 512L * blocks;
|
||||
setrlimit(RLIMIT_FSIZE, &rlimit_fsize);
|
||||
}
|
||||
|
||||
|
@ -4,14 +4,6 @@
|
||||
#define _LIMITS_H_
|
||||
|
||||
|
||||
int setrlimit_value(unsigned int, const char *, unsigned int);
|
||||
int set_prio(const char *);
|
||||
int set_umask(const char *);
|
||||
int check_logins(const char *, const char *);
|
||||
int do_user_limits(const char *, const char *);
|
||||
int setup_user_limits(const char *);
|
||||
void setup_usergroups(const struct passwd *);
|
||||
void setup_limits(const struct passwd *);
|
||||
void set_filesize_limit(int);
|
||||
|
||||
#endif
|
||||
|
@ -3,7 +3,7 @@
|
||||
* $Id$
|
||||
* Purpose ...............: MBSE BBS Shadow Password Suite
|
||||
* Original Source .......: Shadow Password Suite
|
||||
* Original Copyrioght ...: Julianne Frances Haugh and others.
|
||||
* Original Copyright ....: Julianne Frances Haugh and others.
|
||||
*
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1997-2002
|
||||
@ -46,13 +46,14 @@ 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];
|
||||
@ -85,7 +86,8 @@ void login_prompt(const char *prompt, char *name, int namesize)
|
||||
*/
|
||||
|
||||
if (prompt) {
|
||||
cp = getdef_str("ISSUE_FILE");
|
||||
// cp = getdef_str("ISSUE_FILE");
|
||||
cp = NULL;
|
||||
if (cp && (fp = fopen(cp, "r"))) {
|
||||
while ((i = getc(fp)) != EOF)
|
||||
putc(i, stdout);
|
||||
@ -101,7 +103,6 @@ void login_prompt(const char *prompt, char *name, int namesize)
|
||||
* Read the user's response. The trailing newline will be
|
||||
* removed.
|
||||
*/
|
||||
|
||||
memzero(buf, sizeof buf);
|
||||
if (fgets(buf, sizeof buf, stdin) != buf)
|
||||
exit(1);
|
||||
|
@ -74,6 +74,15 @@
|
||||
#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.
|
||||
*/
|
||||
@ -140,7 +149,7 @@ extern char **environ;
|
||||
static void usage(void);
|
||||
static void setup_tty(void);
|
||||
static void check_flags(int, char * const *);
|
||||
static void check_nologin(void);
|
||||
static void check_nologin(char *);
|
||||
static void init_env(void);
|
||||
static RETSIGTYPE alarm_handler(int);
|
||||
int main(int, char **);
|
||||
@ -163,9 +172,6 @@ usage(void)
|
||||
if (!amroot)
|
||||
exit(1);
|
||||
fprintf(stderr, _(" %s [-p] [-h host] [-f name]\n"), Prog);
|
||||
#ifdef RLOGIN
|
||||
fprintf(stderr, _(" %s [-p] -r host\n"), Prog);
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -207,9 +213,12 @@ static void setup_tty(void)
|
||||
termio.c_iflag &= ~IXANY;
|
||||
termio.c_oflag |= (XTABS|OPOST|ONLCR);
|
||||
#endif
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
/* leave these values unchanged if not specified in login.defs */
|
||||
termio.c_cc[VERASE] = getdef_num("ERASECHAR", termio.c_cc[VERASE]);
|
||||
termio.c_cc[VKILL] = getdef_num("KILLCHAR", termio.c_cc[VKILL]);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* ttymon invocation prefers this, but these settings won't come into
|
||||
@ -239,7 +248,10 @@ static void check_flags(int argc, char * const *argv)
|
||||
|
||||
|
||||
|
||||
static void check_nologin(void)
|
||||
/*
|
||||
* nologin file is $MBSE_ROOT/etc/nologin
|
||||
*/
|
||||
static void check_nologin(char *path)
|
||||
{
|
||||
char *fname;
|
||||
|
||||
@ -251,8 +263,9 @@ static void check_nologin(void)
|
||||
* forgotten about it ...
|
||||
*/
|
||||
|
||||
fname = getdef_str("NOLOGINS_FILE");
|
||||
if (fname != NULL && access(fname, F_OK) == 0) {
|
||||
fname = calloc(PATH_MAX, sizeof(char));
|
||||
sprintf(fname, "%s/etc/nologin", path);
|
||||
if (access(fname, F_OK) == 0) {
|
||||
FILE *nlfp;
|
||||
int c;
|
||||
|
||||
@ -273,23 +286,22 @@ static void check_nologin(void)
|
||||
} else
|
||||
printf("\nSystem closed for routine maintenance\n");
|
||||
|
||||
/*
|
||||
* Non-root users must exit. Root gets the message, but
|
||||
* gets to login.
|
||||
*/
|
||||
if (pwent.pw_uid != 0) {
|
||||
free(fname);
|
||||
closelog();
|
||||
exit(0);
|
||||
}
|
||||
printf("\n[Disconnect bypassed -- root login allowed.]\n");
|
||||
}
|
||||
|
||||
free(fname);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void init_env(void)
|
||||
{
|
||||
char *cp, *tmp;
|
||||
#ifndef __FreeBSD__
|
||||
char *cp;
|
||||
#endif
|
||||
char *tmp;
|
||||
|
||||
if ((tmp = getenv("LANG"))) {
|
||||
addenv("LANG", tmp);
|
||||
@ -311,8 +323,12 @@ static void init_env(void)
|
||||
|
||||
if ((tmp = getenv("HZ"))) {
|
||||
addenv("HZ", tmp);
|
||||
#ifndef __FreeBSD__
|
||||
} else if ((cp = getdef_str("ENV_HZ")))
|
||||
addenv(cp, NULL);
|
||||
#else
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -471,24 +487,8 @@ int main(int argc, char **argv)
|
||||
#endif
|
||||
|
||||
openlog("mblogin", LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_AUTH);
|
||||
|
||||
setup_tty();
|
||||
|
||||
umask(getdef_num("UMASK", 077));
|
||||
|
||||
{
|
||||
/*
|
||||
* Use the ULIMIT in the login.defs file, and if
|
||||
* there isn't one, use the default value. The
|
||||
* user may have one for themselves, but otherwise,
|
||||
* just take what you get.
|
||||
*/
|
||||
|
||||
long limit = getdef_long("ULIMIT", -1L);
|
||||
|
||||
if (limit != -1)
|
||||
set_filesize_limit(limit);
|
||||
}
|
||||
umask(007);
|
||||
|
||||
if (pflg)
|
||||
while (*envp) /* add inherited environment, */
|
||||
@ -509,6 +509,8 @@ int main(int argc, char **argv)
|
||||
addenv("MBSE_ROOT", pw->pw_dir);
|
||||
sprintf(userfile, "%s/etc/users.data", pw->pw_dir);
|
||||
|
||||
check_nologin(pw->pw_dir);
|
||||
|
||||
init_env();
|
||||
|
||||
if (optind < argc) { /* get the user name */
|
||||
@ -572,13 +574,13 @@ int main(int argc, char **argv)
|
||||
top:
|
||||
/* only allow ALARM sec. for login */
|
||||
signal(SIGALRM, alarm_handler);
|
||||
timeout = getdef_num("LOGIN_TIMEOUT", ALARM);
|
||||
timeout = LOGIN_TIMEOUT;
|
||||
if (timeout > 0)
|
||||
alarm(timeout);
|
||||
|
||||
environ = newenvp; /* make new environment active */
|
||||
delay = getdef_num("FAIL_DELAY", 1);
|
||||
retries = getdef_num("LOGIN_RETRIES", RETRIES);
|
||||
delay = LOGIN_DELAY;
|
||||
retries = LOGIN_RETRIES;
|
||||
|
||||
while (1) { /* repeatedly get login/password pairs */
|
||||
failed = 0; /* haven't failed authentication yet */
|
||||
@ -588,22 +590,18 @@ top:
|
||||
exit (1);
|
||||
}
|
||||
preauth_flag = 0;
|
||||
#ifndef LOGIN_PROMPT
|
||||
#ifdef __linux__ /* hostname login: - like in util-linux login */
|
||||
login_prompt(_("\n%s login: "), username, sizeof username);
|
||||
#else
|
||||
login_prompt(_("login: "), username, sizeof username);
|
||||
#endif
|
||||
#else
|
||||
login_prompt(LOGIN_PROMPT, username, sizeof username);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Here we try usernames on unix names and Fidonet style
|
||||
* names that are stored in the bbs userdatabase.
|
||||
* The name "bbs" is for new users, don't check the bbs userfile.
|
||||
*/
|
||||
if (strcmp(username, "bbs") == 0) {
|
||||
FoundName = 1;
|
||||
} else {
|
||||
FoundName = 0;
|
||||
if ((ufp = fopen(userfile, "r"))) {
|
||||
fread(&usrconfighdr, sizeof(usrconfighdr), 1, ufp);
|
||||
@ -618,6 +616,7 @@ top:
|
||||
}
|
||||
fclose(ufp);
|
||||
}
|
||||
}
|
||||
|
||||
if ((! (pwd = getpwnam(username))) || (FoundName == 0)) {
|
||||
pwent.pw_name = username;
|
||||
@ -664,7 +663,7 @@ top:
|
||||
* 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);
|
||||
syslog(LOG_WARNING, BAD_PASSWD, "UNKNOWN", fromhost);
|
||||
failed = 1;
|
||||
|
||||
auth_ok:
|
||||
@ -694,28 +693,6 @@ auth_ok:
|
||||
if (! failed)
|
||||
break;
|
||||
|
||||
if (getdef_str("FTMP_FILE") != NULL) {
|
||||
const char *failent_user;
|
||||
#if HAVE_UTMPX_H
|
||||
failent = utxent;
|
||||
gettimeofday(&(failent.ut_tv), NULL);
|
||||
#else
|
||||
failent = utent;
|
||||
time(&failent.ut_time);
|
||||
#endif
|
||||
if (pwd) {
|
||||
failent_user = pwent.pw_name;
|
||||
} else {
|
||||
if (getdef_bool("LOG_UNKFAIL_ENAB"))
|
||||
failent_user = username;
|
||||
else
|
||||
failent_user = "UNKNOWN";
|
||||
}
|
||||
strncpy(failent.ut_user, failent_user, sizeof(failent.ut_user));
|
||||
#ifdef USER_PROCESS
|
||||
failent.ut_type = USER_PROCESS;
|
||||
#endif
|
||||
}
|
||||
memzero(username, sizeof username);
|
||||
|
||||
if (--retries <= 0)
|
||||
@ -760,8 +737,6 @@ auth_ok:
|
||||
// }
|
||||
#endif
|
||||
|
||||
check_nologin();
|
||||
|
||||
if (getenv("IFS")) /* don't export user IFS ... */
|
||||
addenv("IFS= \t\n", NULL); /* ... instead, set a safe IFS */
|
||||
|
||||
@ -783,7 +758,7 @@ auth_ok:
|
||||
#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
|
||||
@ -865,9 +840,8 @@ auth_ok:
|
||||
else
|
||||
syslog(LOG_INFO, REG_LOGIN, username, fromhost);
|
||||
closelog();
|
||||
if ((tmp = getdef_str("FAKE_SHELL")) != NULL) {
|
||||
shell(tmp, pwent.pw_shell); /* fake shell */
|
||||
}
|
||||
|
||||
sleep(3);
|
||||
shell (pwent.pw_shell, (char *) 0); /* exec the shell finally. */
|
||||
/*NOTREACHED*/
|
||||
return 0;
|
||||
|
@ -222,9 +222,6 @@ void pwd_init(void)
|
||||
#ifdef RLIMIT_STACK
|
||||
setrlimit(RLIMIT_STACK, &rlim);
|
||||
#endif
|
||||
#else /* !HAVE_SYS_RESOURCE_H */
|
||||
set_filesize_limit(30000);
|
||||
/* don't know how to set the other limits... */
|
||||
#endif /* !HAVE_SYS_RESOURCE_H */
|
||||
|
||||
signal(SIGALRM, SIG_IGN);
|
||||
|
@ -3,7 +3,7 @@
|
||||
* $Id$
|
||||
* Purpose ...............: MBSE BBS Shadow Password Suite
|
||||
* Original Source .......: Shadow Password Suite
|
||||
* Original Copyrioght ...: Julianne Frances Haugh and others.
|
||||
* Original Copyright ....: Julianne Frances Haugh and others.
|
||||
*
|
||||
*****************************************************************************
|
||||
* Copyright (C) 1997-2002
|
||||
@ -100,7 +100,6 @@ int pw_auth(const char *cipher, const char *user, int reason, const char *input)
|
||||
* get the cleartext password for us.
|
||||
*/
|
||||
if (reason != PW_FTP && reason != PW_REXEC && !input) {
|
||||
if (! (cp = getdef_str ("LOGIN_STRING")))
|
||||
cp = PROMPT;
|
||||
snprintf(prompt, sizeof prompt, cp, user);
|
||||
clear = getpass(prompt);
|
||||
|
@ -109,8 +109,6 @@ void read_env_file(const char *filename)
|
||||
*/
|
||||
void setup_env(struct passwd *info)
|
||||
{
|
||||
char *cp, *envf;
|
||||
|
||||
/*
|
||||
* Change the current working directory to be the home directory
|
||||
* of the user. It is a fatal error for this process to be unable
|
||||
@ -118,32 +116,23 @@ void setup_env(struct passwd *info)
|
||||
* directory.
|
||||
*
|
||||
* We no longer do it as root - should work better on NFS-mounted
|
||||
* home directories. Some systems default to HOME=/, so we make
|
||||
* this a configurable option. --marekm
|
||||
* 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;
|
||||
@ -154,9 +143,7 @@ void setup_env(struct passwd *info)
|
||||
/*
|
||||
* Create the PATH environmental variable and export it.
|
||||
*/
|
||||
|
||||
cp = getdef_str( info->pw_uid == 0 ? "ENV_SUPATH" : "ENV_PATH" );
|
||||
addenv(cp ? cp : "PATH=/bin:/usr/bin", NULL);
|
||||
addenv("PATH=/bin:/usr/bin", NULL);
|
||||
|
||||
/*
|
||||
* Export the user name. For BSD derived systems, it's "USER", for
|
||||
@ -165,34 +152,5 @@ void setup_env(struct passwd *info)
|
||||
|
||||
addenv("USER", info->pw_name);
|
||||
addenv("LOGNAME", info->pw_name);
|
||||
|
||||
/*
|
||||
* MAILDIR environment variable for Qmail
|
||||
*/
|
||||
// if ((cp=getdef_str("QMAIL_DIR")))
|
||||
// addenv_path("MAILDIR", info->pw_dir, cp);
|
||||
|
||||
/*
|
||||
* Create the MAIL environmental variable and export it. login.defs
|
||||
* knows the prefix.
|
||||
*/
|
||||
|
||||
// if ((cp=getdef_str("MAIL_DIR")))
|
||||
// addenv_path("MAIL", cp, info->pw_name);
|
||||
// else if ((cp=getdef_str("MAIL_FILE")))
|
||||
// addenv_path("MAIL", info->pw_dir, cp);
|
||||
// else {
|
||||
//#if defined(MAIL_SPOOL_FILE)
|
||||
// addenv_path("MAIL", info->pw_dir, MAIL_SPOOL_FILE);
|
||||
//#elif defined(MAIL_SPOOL_DIR)
|
||||
// addenv_path("MAIL", MAIL_SPOOL_DIR, info->pw_name);
|
||||
//#endif
|
||||
// }
|
||||
|
||||
/*
|
||||
* Read environment from optional config file. --marekm
|
||||
*/
|
||||
if ((envf = getdef_str("ENVIRON_FILE")))
|
||||
read_env_file(envf);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user