limiting singleuser access
Jim Knutson
knutson%marconi.sw.MCC.COM at mcc.com
Sat Jul 22 01:09:27 AEST 1989
This has been discussed before, but we use root's .profile and a special
program to limit singleuser access. The special program prompts for a
root password, but also gives the user the capability to type halt or
reboot and get the machine going again. Note that root's default shell
cannot be /bin/sh for this to work.
Jim Knutson
knutson at mcc.com
cs.utexas.edu!milano!knutson
---- /.profile ----
trap "" 3
trap "" 8
trap "" 18
PATH=/etc:/usr/etc:/usr/ucb:/bin:/usr/bin:.
PATH=$PATH:/usr/hosts:/usr/local/bin:/usr/local/etc
TZ=CST6CDT
export PATH TERM TZ
stty dec
###### Use a locking program to prompt for password when single-user ######
SULOCK=/etc/.singleuserlock
echo "Entering single-user mode."
if [ -x $SULOCK ]; then
$SULOCK
fi
trap 3
trap 8
trap 18
TERM=sun
USER=root
HOME=/
export TERM USER HOME
---- singleuserlock.c ----
/* example written by Bruce G. Barnett <barnett at ge-crd.arpa> */
#include <stdio.h>
#include <signal.h>
#include <pwd.h>
#include <sys/reboot.h>
#include <sys/time.h>
#include <errno.h>
#define ROOT_UID 0
#define MAXTRIES 4 /* number of tries for password */
#define ALARM 60 /* seconds for alarm */
#define INIT_PID 1 /* PID of init */
struct passwd *pwd;
struct passwd *getpwuid();
char *strcpy();
char *crypt();
char *getpass();
char *pw;
char pwbuf[32];
int numtries;
int timeout();
main()
{
(void) signal(SIGINT, SIG_IGN);
(void) signal(SIGQUIT, SIG_IGN);
(void) signal(SIGTSTP, SIG_IGN);
(void) signal(SIGALRM, timeout);
/* get the password entry for root */
/* use 0 if you want to hard-wire the passwd for root */
/* else use getuid() */
if(geteuid() != ROOT_UID) {
(void) fprintf(stderr, "Permission denied.\n");
exit(1);
}
pwd=getpwuid(ROOT_UID);
if (pwd == NULL ) {
(void) fprintf(stderr,"Cannot get password entry for root.\n");
doreboot(RB_HALT);
}
(void) alarm(ALARM);
while (numtries<MAXTRIES) {
(void) fprintf(stderr,
"Enter: root password, \"halt\", or \"reboot\".\n");
(void) strcpy(pwbuf, getpass("Password:"));
pw = crypt(pwbuf, pwd->pw_passwd);
if (strcmp(pw, pwd->pw_passwd) == 0 )
exit(0);
if(strcmp(pwbuf, "halt") == 0) {
(void) fprintf(stderr, "System halting...\n");
doreboot(RB_HALT);
}
if(strcmp(pwbuf, "reboot") == 0) {
(void) fprintf(stderr, "System rebooting...\n");
doreboot(RB_AUTOBOOT);
}
(void) fprintf(stderr, "Incorrect password.\n");
numtries++;
}
(void) alarm(0);
(void) fprintf(stderr, "Root login failed. System halting....\n");
doreboot(RB_HALT);
}
timeout()
{
(void) alarm(0);
(void) fprintf(stderr, "\nTime out after %d seconds.\n", ALARM);
(void) fprintf(stderr, "System halting...\n");
doreboot(RB_HALT);
}
doreboot(howto)
int howto;
{
int i;
extern int errno;
(void) alarm(0);
sync();
if(kill(INIT_PID, SIGTSTP) == -1)
(void) fprintf(stderr, "Can't idle init.\n");
sleep(1);
(void) kill(-1, SIGTERM);
sleep(5);
sync();
for(i=0; ; i++) {
if(kill(-1, SIGKILL) == -1) {
if(errno == ESRCH)
break;
}
if(i>5) {
(void) fprintf(stderr,
"CAUTION: some process(es) wouldn't die.\n");
break;
}
}
sync();
reboot(howto);
/* If the reboot() fails, make sure that the system does nothing */
pause();
}
More information about the Comp.sys.sun
mailing list