ftp.nice.ch/peanuts/GeneralData/Documents/user-groups/rmNUG/dialupip.tar.gz#/dialupip/src/dumisc/dulogin.c

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.