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.