This is dulogin.c in view mode; [Download] [Up]
/*
** Copyright (c) 1991 Bolt Beranek and Newman, Inc.
** All rights reserved.
**
** Redistribution and use in source and binary forms are permitted
** provided that: (1) source distributions retain this entire copyright
** notice and comment, and (2) distributions including binaries display
** the following acknowledgement: ``This product includes software
** developed by Bolt Beranek and Newman, Inc. and CREN/CSNET'' in the
** documentation or other materials provided with the distribution and in
** all advertising materials mentioning features or use of this software.
** Neither the name of Bolt Beranek and Newman nor CREN/CSNET may be used
** to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
** WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#include <stdio.h>
#include <signal.h>
#include <pwd.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/file.h>
#include <utmp.h>
#include <sgtty.h>
#ifndef sun
#include <ttyent.h>
#endif
#include <syslog.h>
#include <grp.h>
#define GROUPNAME "dialupip"
/* Time given to login. Not static so it can easily be adb'd. */
int timeout = 60;
static char nolog[] = "/etc/nologin";
extern char *strcat();
extern char *strrchr();
extern char *ttyname();
extern char *crypt();
extern char *getpass();
extern time_t time();
extern long lseek();
extern char *strcpy();
extern char *strncpy();
extern unsigned int sleep();
#ifdef GROUPNAME
/*
** See if the user is in the dialup group.
*/
static int
inthegroup(name, pwd)
char *name;
struct passwd *pwd;
{
char **names;
struct group *gp;
/* Quick tests -- see if the group exists, and if it is the user's primary
* group. */
if ((gp = getgrnam(GROUPNAME)) == NULL)
return 0;
if (gp->gr_gid == pwd->pw_gid)
return 1;
/* The hard way -- check all members of the group. */
for (names = gp->gr_mem; *names; names++)
if (strcmp(name, *names) == 0)
return 1;
return 0;
}
#endif /* GROUPNAME */
/*
** Get a login name.
*/
static struct passwd *
getloginname(up)
struct utmp *up;
{
static struct passwd nouser;
struct passwd *pw;
char buff[sizeof up->ut_name + 1];
char *p;
int c;
while (up->ut_name[0] == '\0') {
(void)printf("login: ");
for (p = up->ut_name; (c = getchar()) != '\n'; ) {
if (c == ' ')
c = '_';
if (c == EOF)
exit(0);
if (p < &up->ut_name[sizeof up->ut_name])
*p++ = c;
}
}
(void)strncpy(buff, up->ut_name, sizeof up->ut_name);
buff[sizeof up->ut_name] = '\0';
if ((pw = getpwnam(buff)) == NULL) {
/* Not in passwd -- guarantee they can't login by putting something
* illegal in the encrypted password. */
(void)strcpy(nouser.pw_passwd, "*");
return &nouser;
}
return pw;
}
/*
** Catch timeout and exit.
*/
static void
timedout()
{
(void)printf("Login timed out after %d seconds\n", timeout);
exit(0);
}
static void
sleepandexit(t, x)
unsigned int t;
int x;
{
(void)sleep(t);
(void)close(0);
(void)close(1);
(void)close(2);
exit(x);
}
main(argc, argv)
int argc;
char *argv[];
{
FILE *F;
struct utmp utmp;
struct passwd *pwd;
char *p;
char *tty;
char *ttyn;
char minusname[16];
int count;
int f;
int i;
int valid;
/* Skip silly argument. */
if (argc > 1 && strcmp(argv[1], "-p") == 0) {
argc--;
argv++;
}
/* Catch signals, up our priority. */
(void)signal(SIGALRM, timedout);
(void)alarm((unsigned int)timeout);
(void)signal(SIGQUIT, SIG_IGN);
(void)signal(SIGINT, SIG_IGN);
(void)setpriority(PRIO_PROCESS, 0, -20);
/* Set up the line, close other descriptors. */
i = 0;
(void)ioctl(0, TIOCNXCL, (caddr_t)0);
(void)ioctl(0, FIONBIO, (caddr_t)&i);
(void)ioctl(0, FIOASYNC, (caddr_t)&i);
for (i = getdtablesize(); i > 2; i--)
(void)close(i);
/* Set up the name of the TTY. */
ttyn = ttyname(0);
if (ttyn == (char *)NULL || *ttyn == '\0')
ttyn = "/dev/tty??";
if ((tty = strrchr(ttyn, '/')) == NULL)
tty = ttyn;
else
tty++;
/* Set up syslog. */
#ifdef ultrix
(void)openlog("login", LOG_PID);
#else
#ifdef sun
(void)openlog("login", LOG_PID);
#else
(void)openlog("login", LOG_ODELAY, LOG_AUTH);
#endif /* sun */
#endif /* ultrix */
(void)bzero((char *)&utmp, sizeof utmp);
for (count = 0, valid = 0; !valid; ) {
i = OTTYDISC;
(void)ioctl(0, TIOCSETD, (caddr_t)&i);
/* Get login name, if specified try the one on the command line. */
if (argv[1] && *argv[1]) {
(void)strncpy(utmp.ut_name, argv[1], sizeof utmp.ut_name);
/* Only do that once. */
argv[1] = NULL;
}
else
utmp.ut_name[0] = '\0';
pwd = getloginname(&utmp);
/* If a password exists for this user, prompt for one and verify it. */
if (pwd->pw_passwd[0] == '\0')
valid = 1;
else {
p = crypt(getpass("Password:"), pwd->pw_passwd);
valid = strcmp(p, pwd->pw_passwd) == 0;
}
/* If user not super-user, check for logins disabled. */
if (pwd->pw_uid != 0 && (F = fopen(nolog, "r")) != NULL) {
while ((i = getc(F)) != EOF)
(void)putchar(i);
(void)fflush(stdout);
(void)fclose(F);
sleepandexit(5, 0);
}
if (!valid) {
(void)printf("Login incorrect\n");
if (++count >= 5) {
syslog(LOG_CRIT, "REPEATED LOGIN FAILURES ON %s, %.*s",
tty, sizeof utmp.ut_name, utmp.ut_name);
(void)ioctl(0, TIOCHPCL, (caddr_t)(struct sgttyb *)NULL);
sleepandexit(10, 1);
}
}
if (!valid)
continue;
#ifdef GROUPNAME
if (!inthegroup(utmp.ut_name, pwd)) {
(void)printf("Not in the \"%s\" group.\n", GROUPNAME);
sleepandexit(10, 1);
exit(1);
}
#endif /* GROUPNAME */
if (*pwd->pw_shell == '\0') {
(void)printf("No login shell.\n");
sleepandexit(10, 1);
}
if (chdir(pwd->pw_dir) < 0) {
if (chdir("/") < 0) {
(void)printf("No directory!\n");
valid = 0;
}
else {
pwd->pw_dir = "/";
(void)printf("No directory! Logging in with home=%s\n",
pwd->pw_dir);
}
}
}
/* We're committed -- shut off the timeout. */
(void)alarm(0);
/* Update utmp and wtmp. */
(void)time(&utmp.ut_time);
i = ttyslot();
if (i > 0 && (f = open("/etc/utmp", O_WRONLY)) >= 0) {
(void)lseek(f, (long) (i * sizeof (utmp)), 0);
(void)strncpy(utmp.ut_line, tty, sizeof (utmp.ut_line));
utmp.ut_line[sizeof utmp.ut_line - 1] = '\0';
(void)write(f, (char *)&utmp, sizeof utmp);
(void)close(f);
}
if ((f = open("/usr/adm/wtmp", O_WRONLY | O_APPEND)) >= 0) {
(void)write(f, (char *)&utmp, sizeof utmp);
(void)close(f);
}
/* Set up various permissions and access rights. */
(void)chown(ttyn, pwd->pw_uid, pwd->pw_gid);
(void)chmod(ttyn, 0622);
(void)setgid(pwd->pw_gid);
(void)setgroups(1, &pwd->pw_gid);
(void)setuid(pwd->pw_uid);
/* Log interesting entries. */
if (tty[sizeof ("tty") - 1] == 'd')
syslog(LOG_INFO, "DIALUP %s, %s", tty, pwd->pw_name);
if (pwd->pw_uid == 0)
syslog(LOG_NOTICE, "ROOT LOGIN %s", tty);
/* Set signals and priority. */
(void)signal(SIGALRM, SIG_DFL);
(void)signal(SIGQUIT, SIG_DFL);
(void)signal(SIGINT, SIG_DFL);
(void)signal(SIGTSTP, SIG_IGN);
(void)setpriority(PRIO_PROCESS, 0, 0);
/* Set up the shell, and go. */
if ((p = strrchr(pwd->pw_shell, '/')) == NULL)
p = pwd->pw_shell;
else
p++;
(void)sprintf(minusname, "-%s", p);
(void)execlp(pwd->pw_shell, minusname, 0);
perror(pwd->pw_shell);
(void)printf("No shell.\n");
exit(0);
}
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.