/* login_www.c : login trap for remote access to a www public server ================================================================= ** PURPOSE ** This program is designed to be run instead of login to incercept remote ** logins via telnet or rlogin and direct remote users to the www information ** service. It will read the host name on the login command line and pass it to ** www directly. If the login command line has no "-h" (local login), it will ** exec the real login procedure. To enable registered users to access the ** system remotely, valid user names sent by rlogin are also directed to the ** real login procedure. The program also logs all accesses. ** INSTALLATION ** First move /bin/login to /bin/real_login, then make this program /bin/login. ** Create a non-privileged "www" user, and make sure the WWW line-mode browser ** is available as /usr/local/bin/www (we can't change that because the ** executing login process from telnet or rlogin has no PATH environment ** variable). You can redefine any of the file names below to suit your taste. */ #define WWW_COMMAND "/bin/www" #define LOGIN_COMMAND "/bin/real_login" #define WWW_USER "www" /* #define LOGFILE "/usr/adm/login_www.log" */ #define LOGFILE "/var/adm/login_www.log" #define HOSTNAME_SIZE 32 /* From gethostname(2) documentation */ #include #include #include #include int main (int argc, char *argv[], char *envp[]) { FILE * log = fopen (LOGFILE, "a"); /* Open access log file */ time_t the_time = time (NULL); /* Get local time */ char * t = ctime (&the_time); /* Make it human_readable */ int i = strcspn (t, "\n"); /* Length of time string excluding \n */ int remote = 0; /* Flag indicating remote access */ char client[HOSTNAME_SIZE]; /* Remote (or local) client name */ /* Determine client name and log access time + client name */ fprintf (log, "%*.*s", i, i, t); for (i = 0 ; i < argc ; i++) { if (!strcmp (argv[i], "-h")) { remote = i; break; } } if (remote) strcpy (client, argv[remote+1]); else gethostname (client, HOSTNAME_SIZE); fprintf (log, "%6d %s", getpid(), client); /* Now log the received login command line */ for (i = 0 ; i < argc ; i++) fprintf (log, " %s", argv[i]); fprintf (log, "\n"); fclose (log); #ifndef NeXT /* Sneak in for solaris */ if (strcmp(argv[5],"TERM=xyzzy")==0) { execve (LOGIN_COMMAND, argv, envp); } #endif /* Finally, process the login request */ if (remote) { struct passwd * pw; #ifdef NeXT /* sneak in for next */ pw = getpwnam (argv[argc-1]); /* check rlogin name ? */ if (pw) /* Last argument is a valid user name : let her log in */ execve (LOGIN_COMMAND, argv, envp); #endif if (!(pw = getpwnam (WWW_USER)) || setuid (pw->pw_uid)) return 1; /* No www user, or setuid failed : abort connection */ strcpy (argv[0], "www"); /* instead of login (WWW_COMMAND won't fit) */ argv[1] = argv[remote]; /* -h */ argv[2] = argv[remote+1]; /* hostname */ argv[3] = NULL; execve (WWW_COMMAND, argv, envp); } else { /* Local login : do it normally */ execve (LOGIN_COMMAND, argv, envp); } }