home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / security / login_1 / c / login < prev    next >
Text File  |  1995-08-29  |  4KB  |  181 lines

  1. /* vi:tabstop=4:shiftwidth=4:smartindent
  2.  *
  3.  * login.c - Unix style login program. Uses /etc/passwd.
  4.  *
  5.  */
  6.  
  7. #include "login.h"
  8. #include "sysvars.h"
  9. #include <sys/stat.h>
  10.  
  11. int    main(int argc, char **argv)
  12. {
  13.     struct passwd *pw;
  14.     struct stat    s;
  15.  
  16.     char login[1024], pass[1024], prompt[1024], *host;
  17.     int  fail;
  18.  
  19. #ifdef crypt
  20.     init_des();
  21. #endif
  22.  
  23.     /* Disable escape.
  24.      */
  25.     signal(SIGINT, SIG_IGN);
  26.  
  27.     /* Create a login prompt. gethostname(), under standard
  28.      * UnixLib always returns "acornXX" where XX is the hexadecimal
  29.      * Econet station number. Pretty boring, so we allow the HOST
  30.      * system variable to override this.
  31.      */
  32.     host = getenv("HOST");
  33.     if (host == NULL)
  34.     {
  35.         host = gethostname();
  36.     }
  37.     sprintf(prompt, "%s login: ", host);
  38.  
  39.     do 
  40.     {
  41.         fail = 0;
  42.  
  43.         /* If the username was specified on the command line then
  44.          * copy it. Otherwise read it from the keyboard and unset
  45.          * argc to force subsequent reads to come from the keyboard.
  46.          */
  47.         if (argc == 2)
  48.         {
  49.             strcpy(login, argv[1]);
  50.             argc = 0;
  51.         }
  52.         else
  53.         {
  54.             get(prompt, login, 1);
  55.         }
  56.  
  57.         /* Read the user's login details. If they are not found then
  58.          * get a dummy password.
  59.          */
  60.         pw = getpwnam(login);
  61.         if (pw == NULL)
  62.         {
  63.             get("Password: ", pass, 0);
  64.             fail = 1;
  65.         }
  66.         else
  67.         {
  68.             /* If a password exists for this accounf then ask for it.
  69.              */
  70.             if (pw->pw_passwd[0] != 0)
  71.             {
  72.                 get("Password: ", pass, 0);
  73.  
  74.                 /* Extract the salt and crypted password and
  75.                  * encrypt the entered password. Compare these.
  76.                  */
  77.                 strncpy(login, pw->pw_passwd, 2);
  78.                 login[2] = '\0';
  79.  
  80.                 if (strcmp(pw->pw_passwd, crypt(pass, login)))
  81.                 {
  82.                     fail = 1;
  83.                 }
  84.  
  85.                 /* Whatever happens, overwrite the plaintext password
  86.                  * string to prevent it lying around in memory.
  87.                  */
  88.                 strcpy(pass, "          ");
  89.             }
  90.         }
  91.         if (fail)
  92.         {
  93.             printf("Login Incorrect\n");
  94.         }
  95.     }
  96.     while (fail);
  97.  
  98.     /* Set the readonly user-specific variables.
  99.      */
  100.  
  101.     /* User name.
  102.      */
  103.     writeable("USER");
  104.     readonly("USER", pw->pw_name);
  105.  
  106.     /* Numeric User-ID.
  107.      */
  108.     writeable("Unix$uid");
  109.     sprintf(login, "%d", pw->pw_uid);
  110.     readonly("Unix$uid", login);
  111.  
  112.     /* Numeric Group-ID.
  113.      */
  114.     writeable("Unix$gid");
  115.     sprintf(login, "%d", pw->pw_gid);
  116.     readonly("Unix$gid", login);
  117.  
  118.     /* NAME and HOME do not need to be readonly in my opinion.
  119.      * If this is needed then the readonly utility may be used
  120.      * in /etc/loginrc.
  121.      */
  122.     writeable("NAME");
  123.     setenv("NAME", pw->pw_gecos);
  124.  
  125.     writeable("HOME");
  126.     setenv("HOME", pw->pw_dir);
  127.  
  128.     /* Set the user-root directory. I can't find the system call required
  129.      * to do this.
  130.      */
  131.     sprintf(login, "*%%Urd %s", __uname(pw->pw_dir, 0));
  132.     system(login);
  133.  
  134.     /* Run the system login file, if present (/etc/loginrc)
  135.      */
  136.     if (stat("/etc/loginrc", &s) != -1)
  137.     {
  138.         sprintf(login, "run %s", __uname("/etc/loginrc", 0));
  139.         system(login);
  140.     }
  141.  
  142.     /* Change directory to the User's home and run any .login file present.
  143.      */
  144.     chdir(pw->pw_dir);
  145.     if (stat(".login", &s) != -1)
  146.     {
  147.         system("run /login");
  148.     }
  149.  
  150.     /* Check for the existance of a mailbox file in the 
  151.      * mail directory.
  152.      */
  153.     sprintf(login, "<Mail$Dir>/%s", pw->pw_name);
  154.     if (stat(login, &s) != -1)
  155.     {
  156.         puts("You have mail");
  157.     }
  158.  
  159.     /* The SHELL variable is used by UnixLib. Unless you have a proper
  160.      * shell installed, then it is not safe to set it. Therefore I've
  161.      * left this facility out.
  162.     writeable("SHELL")
  163.     setenv("SHELL", pw->pw_shell);
  164.      */
  165.  
  166.     /* In lieu of such a SHELL variable, I use the pw_shell variable to
  167.      * store immediate commands to run. So, if the passwd entry contains 
  168.      * a shell starting with "*" then it is run immediately. This is useful
  169.      * for system functions. e.g. Logging in with the user-id shutdown
  170.      * will run the *shutdown command if the passwd file contains the
  171.      * following line.
  172.      * shutdown::4:0:System Shutdown:/:*shutdown
  173.      */
  174.     if (pw->pw_shell[0] == '*')
  175.     {
  176.         system(pw->pw_shell);
  177.     }
  178.  
  179.     exit(0);
  180. }
  181.