home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ARM Club 3
/
TheARMClub_PDCD3.iso
/
hensa
/
security
/
login_1
/
c
/
login
< prev
next >
Wrap
Text File
|
1995-08-29
|
4KB
|
181 lines
/* vi:tabstop=4:shiftwidth=4:smartindent
*
* login.c - Unix style login program. Uses /etc/passwd.
*
*/
#include "login.h"
#include "sysvars.h"
#include <sys/stat.h>
int main(int argc, char **argv)
{
struct passwd *pw;
struct stat s;
char login[1024], pass[1024], prompt[1024], *host;
int fail;
#ifdef crypt
init_des();
#endif
/* Disable escape.
*/
signal(SIGINT, SIG_IGN);
/* Create a login prompt. gethostname(), under standard
* UnixLib always returns "acornXX" where XX is the hexadecimal
* Econet station number. Pretty boring, so we allow the HOST
* system variable to override this.
*/
host = getenv("HOST");
if (host == NULL)
{
host = gethostname();
}
sprintf(prompt, "%s login: ", host);
do
{
fail = 0;
/* If the username was specified on the command line then
* copy it. Otherwise read it from the keyboard and unset
* argc to force subsequent reads to come from the keyboard.
*/
if (argc == 2)
{
strcpy(login, argv[1]);
argc = 0;
}
else
{
get(prompt, login, 1);
}
/* Read the user's login details. If they are not found then
* get a dummy password.
*/
pw = getpwnam(login);
if (pw == NULL)
{
get("Password: ", pass, 0);
fail = 1;
}
else
{
/* If a password exists for this accounf then ask for it.
*/
if (pw->pw_passwd[0] != 0)
{
get("Password: ", pass, 0);
/* Extract the salt and crypted password and
* encrypt the entered password. Compare these.
*/
strncpy(login, pw->pw_passwd, 2);
login[2] = '\0';
if (strcmp(pw->pw_passwd, crypt(pass, login)))
{
fail = 1;
}
/* Whatever happens, overwrite the plaintext password
* string to prevent it lying around in memory.
*/
strcpy(pass, " ");
}
}
if (fail)
{
printf("Login Incorrect\n");
}
}
while (fail);
/* Set the readonly user-specific variables.
*/
/* User name.
*/
writeable("USER");
readonly("USER", pw->pw_name);
/* Numeric User-ID.
*/
writeable("Unix$uid");
sprintf(login, "%d", pw->pw_uid);
readonly("Unix$uid", login);
/* Numeric Group-ID.
*/
writeable("Unix$gid");
sprintf(login, "%d", pw->pw_gid);
readonly("Unix$gid", login);
/* NAME and HOME do not need to be readonly in my opinion.
* If this is needed then the readonly utility may be used
* in /etc/loginrc.
*/
writeable("NAME");
setenv("NAME", pw->pw_gecos);
writeable("HOME");
setenv("HOME", pw->pw_dir);
/* Set the user-root directory. I can't find the system call required
* to do this.
*/
sprintf(login, "*%%Urd %s", __uname(pw->pw_dir, 0));
system(login);
/* Run the system login file, if present (/etc/loginrc)
*/
if (stat("/etc/loginrc", &s) != -1)
{
sprintf(login, "run %s", __uname("/etc/loginrc", 0));
system(login);
}
/* Change directory to the User's home and run any .login file present.
*/
chdir(pw->pw_dir);
if (stat(".login", &s) != -1)
{
system("run /login");
}
/* Check for the existance of a mailbox file in the
* mail directory.
*/
sprintf(login, "<Mail$Dir>/%s", pw->pw_name);
if (stat(login, &s) != -1)
{
puts("You have mail");
}
/* The SHELL variable is used by UnixLib. Unless you have a proper
* shell installed, then it is not safe to set it. Therefore I've
* left this facility out.
writeable("SHELL")
setenv("SHELL", pw->pw_shell);
*/
/* In lieu of such a SHELL variable, I use the pw_shell variable to
* store immediate commands to run. So, if the passwd entry contains
* a shell starting with "*" then it is run immediately. This is useful
* for system functions. e.g. Logging in with the user-id shutdown
* will run the *shutdown command if the passwd file contains the
* following line.
* shutdown::4:0:System Shutdown:/:*shutdown
*/
if (pw->pw_shell[0] == '*')
{
system(pw->pw_shell);
}
exit(0);
}