Files
oldlinux-files/bin/qpl-init/login/login.c
2024-02-19 00:21:52 -05:00

149 lines
3.0 KiB
C

/*
login.c
by qpliu@phoenix.princeton.edu 1992
a rudimentary way to avoid being root on linux 0.11
no motd or other messages or .hushlogin
no passwords
no /etc/nologin
no checking if term is secure
*/
#include <pwd.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <ttyent.h>
#define DEFAULT_SHELL "/bin/bash"
#define TIMEOUT 60
#define STIMEOUT "60"
extern char **environ;
static void do_login (char *);
static int check_passwd (struct passwd *);
static void timeout ();
static void setenviron ();
static char savenv = 0;
static struct passwd *entry;
void
main (int argc, char **argv)
{
char login[L_cuserid];
if (argc > 1)
if (!(strcmp ("-p", *(argv + 1)))) {
--argc; ++argv; savenv = 1;
}
if (argc > 1)
do_login (*++argv);
for (;;) {
fputs ("login: ", stdout);
fflush (stdout);
signal (SIGALRM, timeout);
alarm (TIMEOUT);
fgets (login, L_cuserid, stdin);
alarm (0);
signal (SIGALRM, SIG_DFL);
if (feof (stdin)) exit(0);
if (*login == '\n') continue;
if (login [strlen (login) - 1] == '\n')
login [strlen (login) - 1] = '\0';
else { /* discard rest of line */
char junk[80];
do fgets (junk, 80, stdin);
while (junk [strlen (junk) - 1] != '\n');
}
do_login (login);
}
}
static void
do_login (char *login)
{
entry = getpwnam (login);
if (check_passwd (entry)) {
puts ("Login incorrect");
return;
}
if (setgid (entry->pw_gid)) {
perror ("setgid");
return;
}
if (setuid (entry->pw_uid)) {
setgid (0);
perror ("setuid");
return;
}
if (chdir (entry->pw_dir))
perror ("Couldn't chdir");
{
char *p, *d, *e;
if (!(e = entry->pw_shell)) e = DEFAULT_SHELL;
p = strrchr (e, '/');
if (!p++) p = e;
if (!p) p = DEFAULT_SHELL;
d = (char *)malloc (strlen(p) + 1);
*d = '-'; *(d+1) = '\0';
strcat(d, p);
setenviron ();
execl(e, d, (char *)0);
perror("No shell");
}
}
static int
check_passwd (struct passwd *entry)
{
/* room to get and check actual (yuck) passwords */
return entry ? 0 : 1;
}
static void
timeout ()
{
/* printf ("Login timed out after %d seconds\n", TIMEOUT); */
/* 8k for 1 printf too big */
puts ("Login timed out after " STIMEOUT " seconds");
exit (0);
}
extern char *ttyname (int);
static void
setenviron ()
{
/* too much bother, man pages say HOME, SHELL, TERM, USER set */
char **c = environ, *d;
while (*c) free (*(c++));
free (environ);
c = (char **)malloc (5 * sizeof (char *));
environ = c;
d = ttyname (0);
if (d) {
d += 5; /* "/dev/" */
d = getttynam (d)->ty_type;
}
*c = (char *)malloc ((5 + strlen (entry->pw_dir)) * sizeof (char));
strcpy (*c, "HOME="); strcat (*c, entry->pw_dir);
*++c = (char *)malloc ((6 + strlen (entry->pw_shell)) * sizeof (char));
strcpy (*c, "SHELL="); strcat (*c, entry->pw_shell);
*++c = (char *)malloc ((5 + strlen (d)) * sizeof (char));
strcpy (*c, "TERM="); strcat (*c, d);
*++c = (char *)malloc ((5 + strlen (entry->pw_name)) * sizeof (char));
strcpy (*c, "NAME="); strcat (*c, entry->pw_name);
*++c = (char *)0;
endttyent ();
}