Cover V05, I09
Article
Figure 1
Figure 2a
Figure 2b
Figure 3
Listing 1

sep96.tar


Listing 1: rma.c

/* rma.c -- Restricted Machine Access */
/* Greg A. Wade			      */

/* Configuration section              */
#define SHELL_DIR	"/usr/bin/shells/"
#define ACCESS_LIST	"/etc/accesslist"
#define MAIL_TO		"wade"
#define LOGIN_SCRIPT	"/etc/enter.sh"
#define LOGOUT_SCRIPT	"/etc/exit.sh"

#include <stdio.h>
#include <strings.h>
#include <sys/types.h>
#include <unistd.h>
#include <grp.h>
#include <stdlib.h>
#include <sys/param.h>
#include <signal.h>

#ifdef __SVR4
#include <netdb.h>
#include <fcntl.h>
#else
#include <sys/file.h>
#endif

/* Returns 1 if the user is allowed to login, */
/* otherwise 0 is returned                    */
int CanLogin( gid_t gid, char * host)
{
FILE * access_file;
struct group * gr = NULL;
char **p = NULL;
int result = 1;

if ((access_file=(FILE *)fopen(ACCESS_LIST,"r"))!=NULL) {

/* Lookup the group in ACCESS_LIST */
while((gr = (struct group*) fgetgrent(access_file))!=NULL)
if (gr->gr_gid == gid)
break ;
fclose(access_file);

if (gr==NULL)

/* Our gid is not in ACCESS_LIST..deny access */
result=0;
else {

/* search for the current machine name */
result = (*(gr->gr_passwd)=='+' ? 0 : 1);
p = gr->gr_mem;
while (*p != NULL) {
if(!strcmp(*p,host)) {
result = (! result);
break;
}
p++;
}
}
}

return(result);
}

/* Execute the script specified by LOGIN_SCRIPT */
void LoginScript(void)
{
int status;

if(fork() == 0) {
execl(LOGIN_SCRIPT,rindex(LOGIN_SCRIPT,'/'),NULL);
exit(1);
} else
wait(&status);
}

/* Execute the script specified by LOGOUT_SCRIPT */
void LogoutScript(void)
{
execl(LOGOUT_SCRIPT,rindex(LOGOUT_SCRIPT,'/'),NULL);
exit(1);
}

/* Launch the user's shell */
void Login(char ** args)
{
int status;
char *p, *cmd;

char shell_prog[MAXPATHLEN];

/* Determine the shell to run */
strcpy(shell_prog,SHELL_DIR);
if ((p = rindex(*args,'/')) != NULL)
cmd = p;
else
if(*(*args) != '-')
cmd = *args;
else
cmd = (*args)+1;

/* This fixes the SunOS su "bug" and */
/* maybe some others as well         */
if(!strcmp(cmd,"su")) {
cmd = getenv("SHELL");
if ((p = rindex(cmd,'/')) != NULL)
cmd = p;
}

strcat(shell_prog,cmd);

if(*(*args) != '-') {

/* Start a subshell */
execv(shell_prog,args);
perror("Cannot start shell");

} else

/* Start a login shell and wait        */
/* for it to exit so the LOGOUT_SCRIPT */
/* can be run                          */
if (fork() == 0) {
LoginScript();
execv(shell_prog,args);
perror("Cannot start shell");
exit(1);
} else {
wait(&status);
LogoutScript();

}
}

/* Print access violation message and send email  */
/* with /usr/ucb/Mail if configured to do so.     */
void KickOut(void)
{
int in;

printf("Access to this machine RESTRICTED!!\n");

#ifdef MAIL_TO
if((in = open("/dev/null",O_RDONLY,777)) != 0) {
dup2(in,0);
execl("/usr/ucb/Mail","Mail","-i","-s",
"ACCESS VIOLATION",MAIL_TO,NULL);
exit(1);
}
#endif

}

/* M A I N    P R O G R A M */
main (int argc, char ** argv)

{
char host[MAXHOSTNAMELEN];
uid_t gid;

/* Block some signals */
signal(SIGINT,SIG_IGN);
signal(SIGTERM,SIG_IGN);

/* Determine our hostname */
if (gethostname(host,MAXHOSTNAMELEN))
perror("Who am I...Get me HELP!!");

/* Get the user's primary gid */
gid = getgid();

/* Start the user's shell if */
/* access is allowed         */
if(CanLogin(gid,host))
Login(argv);
else
KickOut();
}
/* End of File */