home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / security / shadow-3.1.4 / lmain.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-04-05  |  15.3 KB  |  706 lines

  1. /*
  2.  * Copyright 1989, 1990, 1991, 1992, John F. Haugh II
  3.  * All rights reserved.
  4.  *
  5.  * Permission is granted to copy and create derivative works for any
  6.  * non-commercial purpose, provided this copyright notice is preserved
  7.  * in all copies of source code, or included in human readable form
  8.  * and conspicuously displayed on all copies of object code or
  9.  * distribution media.
  10.  */
  11.  
  12. #include "config.h"
  13. #include <sys/types.h>
  14. #include <sys/stat.h>
  15. #include <stdio.h>
  16. #include "pwd.h"
  17. #include <utmp.h>
  18. #include <time.h>
  19. #include <signal.h>
  20. #ifndef    BSD
  21. #include <string.h>
  22. #include <memory.h>
  23. #else
  24. #include <strings.h>
  25. #define    strchr    index
  26. #define    strrchr    rindex
  27. #endif
  28. #ifndef    BSD
  29. #include <termio.h>
  30. #else
  31. #include <sgtty.h>
  32. #endif
  33. #ifdef    STDLIB_H
  34. #include <stdlib.h>
  35. #endif
  36. #ifdef    UNISTD_H
  37. #include <unistd.h>
  38. #endif
  39.  
  40. #include "lastlog.h"
  41. #include "faillog.h"
  42. #include "shadow.h"
  43.  
  44. #if !defined(BSD) && !defined(SUN)
  45. #define    bzero(a,n)    memset(a, 0, n);
  46. #endif
  47.  
  48. #ifdef    USE_SYSLOG
  49. #include <syslog.h>
  50.  
  51. #ifndef    LOG_WARN
  52. #define    LOG_WARN    LOG_WARNING
  53. #endif
  54. #endif
  55.  
  56. #ifndef    lint
  57. static    char    sccsid[] = "@(#)lmain.c    3.19    20:36:55    3/7/92";
  58. #endif
  59.  
  60.                     /* danger - side effects */
  61. #define STRFCPY(A,B)    strncpy((A), (B), sizeof(A)), *((A)+sizeof(A)-1) = '\0'
  62.  
  63. #if defined(RLOGIN) || defined(UT_HOST)
  64. char    host[BUFSIZ];
  65. char    term[128] = "TERM=";
  66. #endif
  67.  
  68. struct    passwd    pwent;
  69. struct    utmp    utent;
  70. struct    lastlog    lastlog;
  71. int    pflg;
  72. int    rflg;
  73. int    fflg;
  74. #ifdef    RLOGIN
  75. int    hflg;
  76. #endif
  77. int    preauth_flag;
  78. #if defined(USG) || defined(SUN4)
  79. struct    termio    termio;
  80. #endif
  81.  
  82. #ifndef    MAXENV
  83. #define    MAXENV    64
  84. #endif
  85.  
  86. /*
  87.  * Global variables.
  88.  */
  89.  
  90. char    *newenvp[MAXENV];
  91. char    *Prog;
  92. int    newenvc = 0;
  93. int    maxenv = MAXENV;
  94.  
  95. /*
  96.  * External identifiers.
  97.  */
  98.  
  99. extern    char    *getenv ();
  100. extern    char    *getpass ();
  101. extern    char    *tz ();
  102. extern    void    checkutmp ();
  103. extern    void    addenv ();
  104. extern    void    setenv ();
  105. extern    unsigned alarm ();
  106. extern    void    login ();
  107. extern    void    setutmp ();
  108. extern    void    subsystem ();
  109. extern    void    log ();
  110. extern    void    setup ();
  111. extern    int    expire ();
  112. extern    void    motd ();
  113. extern    void    mailcheck ();
  114. extern    void    shell ();
  115. extern    long    a64l ();
  116. extern    int    c64i ();
  117. extern    char    *getdef_str();
  118. extern    int    getdef_bool();
  119. extern    int    getdef_num();
  120. extern    long    getdef_long();
  121. extern    int    optind;
  122. extern    char    *optarg;
  123. extern    char    **environ;
  124.  
  125. #ifdef HAVE_ULIMIT
  126. extern    long    ulimit();
  127. #endif
  128.  
  129. #ifndef    ALARM
  130. #define    ALARM    60
  131. #endif
  132.  
  133. #ifndef    RETRIES
  134. #define    RETRIES    3
  135. #endif
  136.  
  137. struct    faillog    faillog;
  138.  
  139. struct    utmp    failent;
  140.  
  141. #define    NO_SHADOW    "no shadow password for `%s' on `%s'\n"
  142. #define    BAD_PASSWD    "invalid password for `%s' on `%s'\n"
  143. #define    BAD_DIALUP    "invalid dialup password for `%s' on `%s'\n"
  144. #define    BAD_TIME    "invalid login time for `%s' on `%s'\n"
  145. #define    BAD_ROOT_LOGIN    "ILLEGAL ROOT LOGIN ON TTY `%s'\n"
  146. #define    ROOT_LOGIN    "ROOT LOGIN ON TTY `%s'\n"
  147. #define    FAILURE_CNT    "exceeded failure limit for `%s' on `%s'\n"
  148. #define    NOT_A_TTY    "not a tty\n"
  149. #define    NOT_ROOT    "-r or -f flag and not ROOT on `%s'\n"
  150.  
  151. /*
  152.  * usage - print login command usage and exit
  153.  *
  154.  * login [ name ]
  155.  * login -r hostname    (for rlogind)
  156.  * login -h hostname    (for telnetd, etc.)
  157.  * login -f name    (for pre-authenticated login: datakit, xterm, etc.)
  158.  */
  159.  
  160. void
  161. usage ()
  162. {
  163.     fprintf (stderr, "usage: login [ -p ] [ name ]\n");
  164. #ifdef    RLOGIN
  165.     fprintf (stderr, "       login [ -p ] -r name\n");
  166.     fprintf (stderr, "       login [ -p ] [ -f name ] -h host\n");
  167. #else
  168.     fprintf (stderr, "       login [ -p ] -f name\n");
  169. #endif    /* RLOGIN */
  170.     exit (1);
  171. }
  172.  
  173. #ifdef    RLOGIN
  174. rlogin (remote_host, name, namelen)
  175. char    *remote_host;
  176. char    *name;
  177. int    namelen;
  178. {
  179.     struct    passwd    *pwd;
  180.     char    remote_name[32];
  181.     char    *cp;
  182.  
  183.     get_remote_string (remote_name, sizeof remote_name);
  184.     get_remote_string (name, namelen);
  185.     get_remote_string (term + 5, sizeof term - 5);
  186.     if (cp = strchr (term, '/'))
  187.         *cp = '\0';
  188.  
  189. #if defined(USG) || defined(SUN4)
  190.     (void) ioctl (0, TCGETA, &termio);
  191.  
  192.     termio.c_iflag |= ICRNL|IXON;
  193.     termio.c_oflag |= OPOST|ONLCR;
  194.     termio.c_lflag |= ICANON|ECHO|ECHOE;
  195.     (void) ioctl (0, TCSETA, &termio);
  196. #endif
  197.     if (! (pwd = getpwnam (name)))
  198.         return 0;
  199.  
  200.     /*
  201.      * ruserok() returns 0 for success on modern systems, and 1 on
  202.      * older ones.  If you are having trouble with people logging
  203.      * in without giving a required password, THIS is the culprit -
  204.      * go fix the #define in config.h.
  205.      */
  206.  
  207.     return ruserok (remote_host, pwd->pw_uid == 0,
  208.                 remote_name, name) == RUSEROK;
  209. }
  210.  
  211. get_remote_string (buf, size)
  212. char    *buf;
  213. int    size;
  214. {
  215.     for (;;) {
  216.         if (read (0, buf, 1) != 1)
  217.               exit (1);
  218.         if (*buf == '\0')
  219.             return;
  220.         if (--size > 0)
  221.             ++buf;
  222.     }
  223.     /*NOTREACHED*/
  224. }
  225. #endif
  226.  
  227. /*
  228.  * login - create a new login session for a user
  229.  *
  230.  *    login is typically called by getty as the second step of a
  231.  *    new user session.  getty is responsible for setting the line
  232.  *    characteristics to a reasonable set of values and getting
  233.  *    the name of the user to be logged in.  login may also be
  234.  *    called to create a new user session on a pty for a variety
  235.  *    of reasons, such as X servers or network logins.
  236.  *
  237.  *    the flags which login supports are
  238.  *    
  239.  *    -p - preserve the environment
  240.  *    -r - perform autologin protocol for rlogin
  241.  *    -f - do not perform authentication, user is preauthenticated
  242.  *    -h - the name of the remote host
  243.  */
  244.  
  245. int
  246. main (argc, argv, envp)
  247. int    argc;
  248. char    **argv;
  249. char    **envp;
  250. {
  251.     char    name[32];
  252.     char    pass[32];
  253.     char    tty[BUFSIZ];
  254.     int    retries;
  255.     int    failed;
  256.     int    flag;
  257.     int    subroot = 0;
  258.     char    *fname;
  259.     char    *cp;
  260.     char    *tmp;
  261.     char    buff[128];
  262.     struct    passwd    *pwd;
  263.     struct    spwd    *spwd;
  264.     struct    spwd    *getspnam();
  265.  
  266.     /*
  267.      * Some quick initialization.
  268.      */
  269.  
  270.     name[0] = '\0';
  271.  
  272.     /*
  273.      * Get the utmp file entry and get the tty name from it.  The
  274.      * current process ID must match the process ID in the utmp
  275.      * file if there are no additional flags on the command line.
  276.      */
  277.  
  278.     checkutmp (argc == 1 || argv[1][0] != '-');
  279.     STRFCPY (tty, utent.ut_line);
  280.  
  281.     if (Prog = strrchr (argv[0], '/'))
  282.         Prog++;
  283.     else
  284.         Prog = argv[0];
  285.  
  286. #ifdef    RLOGIN
  287.     while ((flag = getopt (argc, argv, "pr:f:h:")) != EOF)
  288. #else
  289.     while ((flag = getopt (argc, argv, "pf:")) != EOF)
  290. #endif
  291.     {
  292.         switch (flag) {
  293.             case 'p': pflg++;
  294.                 break;
  295.             case 'f':
  296.                 fflg++;
  297.                 preauth_flag++;
  298.                 STRFCPY (name, optarg);
  299.                 break;
  300. #ifdef    RLOGIN
  301.             case 'r':
  302.                 rflg++;
  303.                 STRFCPY (host, optarg);
  304. #ifdef    UT_HOST
  305.                 STRFCPY (utent.ut_host, optarg);
  306. #endif    /*UT_HOST*/
  307.                 if (rlogin (host, name, sizeof name))
  308.                     preauth_flag++;
  309.  
  310.                 break;
  311.             case 'h':
  312.                 hflg++;
  313.                 STRFCPY (host, optarg);
  314. #ifdef    UT_HOST
  315.                 STRFCPY (utent.ut_host, optarg);
  316. #endif    /*UT_HOST*/
  317.                 break;
  318. #endif    /*RLOGIN*/
  319.             default:
  320.                 usage ();
  321.         }
  322.     }
  323.  
  324. #ifdef    RLOGIN
  325.     /*
  326.      * Neither -h nor -f should be combined with -r.
  327.      */
  328.  
  329.     if (rflg && (hflg || fflg))
  330.         usage ();
  331. #endif
  332.  
  333.     /*
  334.      * Allow authentication bypass only if real UID is zero.
  335.      */
  336.  
  337.     if ((rflg || fflg) && getuid () != 0) {
  338.         fprintf(stderr, "%s: permission denied\n", Prog);
  339.         exit (1);
  340.     }
  341.  
  342. #ifdef    USE_SYSLOG
  343.     openlog (Prog, LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_AUTH);
  344. #endif
  345.  
  346.     if (! isatty (0) || ! isatty (1) || ! isatty (2)) {
  347. #ifdef    USE_SYSLOG
  348.         closelog ();
  349. #endif
  350.         exit (1);        /* must be a terminal */
  351.     }
  352. #ifndef    BSD
  353.     (void) ioctl (0, TCGETA, &termio); /* get terminal characteristics */
  354.  
  355.     /*
  356.      * Add your favorite terminal modes here ...
  357.      */
  358.  
  359.     termio.c_lflag |= ISIG;
  360.  
  361.     termio.c_cc[VERASE] = getdef_num("ERASECHAR", '\b');
  362.     termio.c_cc[VKILL] = getdef_num("KILLCHAR", '\025');
  363. #ifdef SVR4
  364.     /*
  365.      * ttymon invocation prefers this, but these settings won't come into
  366.      * effect after the first username login 
  367.      */
  368.  
  369.     (void) ioctl (0, TCSETA, &termio);
  370. #else
  371.      (void) ioctl (0, TCSETAF, &termio);
  372. #endif
  373. #endif    /* !BSD */
  374.     umask (getdef_num("UMASK", 0));
  375. #ifdef HAVE_ULIMIT
  376.     {
  377.         /* 
  378.          * Use the ULIMIT in the login.defs file, and if
  379.          * there isn't one, use the default value.  The
  380.          * user may have one for themselves, but otherwise,
  381.          * just take what you get.
  382.          */
  383.  
  384.         long limit = getdef_long("ULIMIT", -1L);
  385.  
  386.         if (limit != -1)
  387.             ulimit (2, limit);
  388.     }
  389. #endif
  390.  
  391.     /*
  392.      * The entire environment will be preserved if the -p flag
  393.      * is used.
  394.      */
  395.  
  396.     if (pflg)
  397.         while (*envp)        /* add inherited environment, */
  398.             addenv (*envp++); /* some variables change later */
  399.  
  400. #ifdef    RLOGIN
  401.     if (term[5] != '\0')        /* see if anything after "TERM=" */
  402.         addenv (term);
  403. #endif
  404.     /*
  405.      * Add the timezone environmental variable so that time functions
  406.      * work correctly.
  407.      */
  408.  
  409.     if (tmp = getenv ("TZ")) {
  410.         strcat (strcpy (buff, "TZ="), tmp);
  411.         addenv (buff);
  412.     } else if (cp = getdef_str ("ENV_TZ"))
  413.         addenv (*cp == '/' ? tz (cp):cp);
  414.  
  415.     /* 
  416.      * Add the clock frequency so that profiling commands work
  417.      * correctly.
  418.      */
  419.  
  420.     if (tmp = getenv("HZ")) {
  421.         strcat (strcpy (buff, "HZ="), tmp);
  422.         addenv (buff);
  423.     } else if (cp = getdef_str("ENV_HZ"))
  424.         addenv (cp);
  425.  
  426.     if (optind < argc) {        /* get the user name */
  427.         if (rflg || fflg)
  428.             usage ();
  429.  
  430.         STRFCPY (name, argv[optind]);
  431.         ++optind;
  432.     }
  433. #ifdef SVR4
  434.     /*
  435.      * check whether ttymon has done the prompt for us already
  436.      */
  437.  
  438.     {
  439.         char *ttymon_prompt;
  440.  
  441.         if ((ttymon_prompt = getenv("TTYPROMPT")) != NULL &&
  442.             (*ttymon_prompt != 0)) {
  443.         login(name, 0);    /* read name, without prompt */
  444.         }
  445.     }
  446. #endif /* SVR4 */
  447.     if (optind < argc)        /* now set command line variables */
  448.             setenv (argc - optind, &argv[optind]);
  449.  
  450. top:
  451.     (void) alarm (ALARM);        /* only allow ALARM sec. for login */
  452.  
  453.     environ = newenvp;        /* make new environment active */
  454.     retries = RETRIES;
  455.     while (1) {    /* repeatedly get login/password pairs */
  456.         pass[0] = '\0';
  457.  
  458.         if (! name[0]) {    /* need to get a login id */
  459.             if (subroot) {
  460. #ifdef    USE_SYSLOG
  461.                 closelog ();
  462. #endif
  463.                 exit (1);
  464.             }
  465. #ifdef    RLOGIN
  466.             preauth_flag = 0;
  467. #endif
  468.             login (name, "login: ");
  469.             continue;
  470.         }
  471.         if (! (pwd = getpwnam (name)))
  472.             pwent.pw_name = (char *) 0;
  473.         else
  474.             pwent = *pwd;
  475.  
  476.         if (pwent.pw_name) {
  477.             if (! (spwd = getspnam (name)))
  478. #ifdef    USE_SYSLOG
  479.                 syslog (LOG_WARN, NO_SHADOW, name, tty);
  480. #else
  481.                 ;
  482. #endif
  483.             else
  484.                 pwent.pw_passwd = spwd->sp_pwdp;
  485.             failed = 0;    /* hasn't failed validation yet */
  486.         } else
  487.             failed = 1;    /* will never pass validation */
  488.  
  489. #ifdef    RLOGIN
  490.         /*
  491.          * The -r and -f flags provide a name which has already
  492.          * been authenticated by some server.
  493.          */
  494.  
  495.         if (pwent.pw_name && preauth_flag)
  496.             goto have_name;
  497. #endif    /*RLOGIN*/
  498.  
  499.     /*
  500.      * Get the user's password.  One will only be prompted for
  501.      * if the pw_passwd (or sp_passwd) field is non-blank.  It
  502.      * will then be checked against the password entry, along
  503.      * with other options which prevent logins.
  504.      */
  505.         cp = 0;
  506.         if ((! pwent.pw_name || (strlen (pwent.pw_passwd) > 0))
  507.                 && ! (cp = getpass ("Password:")))
  508.             continue;
  509.  
  510.         if (cp) {
  511.             STRFCPY (pass, cp);
  512.             bzero (cp, strlen (cp));
  513.         }
  514.         if (! valid (pass, &pwent)) { /* check encrypted passwords */
  515. #ifdef    USE_SYSLOG
  516.             syslog (LOG_WARN, BAD_PASSWD, name, tty);
  517. #endif
  518.             failed = 1;
  519.         }
  520.         bzero (pass, sizeof pass);
  521.  
  522.         /*
  523.          * This is the point where password-authenticated users
  524.          * wind up.  If you reach this far, your password has
  525.          * been authenticated and so on.
  526.          */
  527.  
  528. #ifdef    RLOGIN
  529. have_name:
  530. #endif
  531.         if (getdef_bool("DIALUPS_CHECK_ENAB")) {
  532.             alarm (30);
  533.             if (pwent.pw_name &&
  534.                     ! dialcheck (tty, pwent.pw_shell[0] ?
  535.                     pwent.pw_shell:"/bin/sh")) {
  536. #ifdef    USE_SYSLOG
  537.                 syslog (LOG_WARN, BAD_DIALUP, name, tty);
  538. #endif
  539.                 failed = 1;
  540.             }
  541.         }
  542.         if (getdef_bool("PORTTIME_CHECKS_ENAB") &&
  543.             pwent.pw_name &&
  544.             ! isttytime (pwent.pw_name, tty, time ((time_t *) 0))
  545.         ) {
  546. #ifdef    USE_SYSLOG
  547.                 syslog (LOG_WARN, BAD_TIME, name, tty);
  548. #endif
  549.                 failed = 1;
  550.         }
  551.         if (! failed && pwent.pw_name && pwent.pw_uid == 0 &&
  552.                 ! console (tty)) {
  553. #ifdef    USE_SYSLOG
  554.             syslog (LOG_CRIT, BAD_ROOT_LOGIN, tty);
  555. #endif
  556.             failed = 1;
  557.         }
  558.         if (getdef_bool("FAILLOG_ENAB") && pwent.pw_name &&
  559.                 ! failcheck (pwent.pw_uid, &faillog, failed)) {
  560. #ifdef    USE_SYSLOG
  561.             syslog (LOG_CRIT, FAILURE_CNT, name, tty);
  562. #endif
  563.             failed = 1;
  564.         }
  565.         if (! failed)
  566.             break;
  567.  
  568.         puts ("Login incorrect");
  569. #ifdef    RLOGIN
  570.         if (rflg || fflg) {
  571. #ifdef    USE_SYSLOG
  572.             closelog ();
  573. #endif
  574.             exit (1);
  575.         }
  576. #endif    /*RLOGIN*/
  577.  
  578.         /* don't log non-existent users */
  579.         if (getdef_bool("FAILLOG_ENAB") && pwent.pw_name)
  580.             failure (pwent.pw_uid, tty, &faillog);
  581.         if (getdef_str("FTMP_FILE") != NULL) {
  582.             failent = utent;
  583.  
  584.             if (pwent.pw_name)
  585.                 STRFCPY (failent.ut_name, pwent.pw_name);
  586.             else
  587.                 if (getdef_bool("LOG_UNKFAIL_ENAB"))
  588.                     STRFCPY (failent.ut_name, name);
  589.                 else
  590.                     STRFCPY (failent.ut_name, "UNKNOWN");
  591.             time (&failent.ut_time);
  592. #ifdef    USG_UTMP
  593.             failent.ut_type = USER_PROCESS;
  594. #endif
  595.             failtmp (&failent);
  596.         }
  597.  
  598.         if (--retries <= 0) {    /* only allow so many failures */
  599. #ifdef    USE_SYSLOG
  600.             closelog ();
  601. #endif
  602.             exit (1);
  603.         }
  604.         bzero (name, sizeof name);
  605.         bzero (pass, sizeof pass);
  606.     }
  607.     (void) alarm (0);        /* turn off alarm clock */
  608.  
  609.     /*
  610.      * Check to see if system is turned off for non-root users.
  611.      * This would be useful to prevent users from logging in
  612.      * during system maintenance.
  613.      */
  614.  
  615.     fname = getdef_str("NOLOGINS_FILE");
  616.     if (pwent.pw_uid != 0 && fname != NULL && access (fname, 0) == 0) {
  617.         FILE    *nlfp;
  618.         int    c;
  619.  
  620.         if (nlfp = fopen (fname, "r")) {
  621.             while ((c = getc (nlfp)) != EOF) {
  622.                 if (c == '\n')
  623.                     putchar ('\r');
  624.  
  625.                 putchar (c);
  626.             }
  627.             fflush (stdout);
  628.             fclose (nlfp);
  629.         } else
  630.             printf ("\r\nSystem closed for routine maintenance\n");
  631.  
  632. #ifdef    USE_SYSLOG
  633.         closelog ();
  634. #endif
  635.         exit (0);
  636.     }
  637.     if (getenv ("IFS"))        /* don't export user IFS ... */
  638.         addenv ("IFS= \t\n");    /* ... instead, set a safe IFS */
  639.  
  640.     setutmp (name, tty);        /* make entry in utmp & wtmp files */
  641.     if (pwent.pw_shell[0] == '*') {    /* subsystem root */
  642.         subsystem (&pwent);    /* figure out what to execute */
  643.         subroot++;        /* say i was here again */
  644.         endpwent ();        /* close all of the file which were */
  645.         endgrent ();        /* open in the original rooted file */
  646.         endspent ();        /* system.  they will be re-opened */
  647.         endsgent ();        /* in the new rooted file system */
  648.         goto top;        /* go do all this all over again */
  649.     }
  650.  
  651.     if (getdef_bool("LASTLOG_ENAB"))
  652.         log ();            /* give last login and log this one */
  653.     setup (&pwent);            /* set UID, GID, HOME, etc ... */
  654. #ifdef    AGING
  655.     if (spwd) {            /* check for age of password */
  656.         if (expire (&pwent, spwd)) {
  657.             spwd = getspnam (name);
  658.             pwd = getpwnam (name);
  659.             pwent = *pwd;
  660.         }
  661.     }
  662. #ifdef    ATT_AGE
  663.     else if (pwent.pw_age && pwent.pw_age[0]) {
  664.         if (expire (&pwent, (void *) 0)) {
  665.             pwd = getpwnam (name);
  666.             pwent = *pwd;
  667.         }
  668.     }
  669. #endif    /* ATT_AGE */
  670. #endif    /* AGING */
  671.     if (! hushed (&pwent)) {
  672.         motd ();        /* print the message of the day */
  673.         if (getdef_bool ("FAILLOG_ENAB") && faillog.fail_cnt != 0)
  674.             failprint (&faillog);
  675.         if (getdef_bool ("LASTLOG_ENAB") && lastlog.ll_time != 0)
  676.             printf ("Last login: %.19s on %s\n",
  677.                 ctime (&lastlog.ll_time), lastlog.ll_line);
  678. #ifdef    AGING
  679.         agecheck (&pwent, spwd);
  680. #endif    /* AGING */
  681.         mailcheck ();    /* report on the status of mail */
  682.     }
  683.     if (getdef_str("TTYTYPE_FILE") != NULL && getenv("TERM") == NULL)
  684.           ttytype (tty);
  685.  
  686.     signal (SIGINT, SIG_DFL);    /* default interrupt signal */
  687.     signal (SIGQUIT, SIG_DFL);    /* default quit signal */
  688.     signal (SIGTERM, SIG_DFL);    /* default terminate signal */
  689.     signal (SIGALRM, SIG_DFL);    /* default alarm signal */
  690.  
  691.     endpwent ();            /* stop access to password file */
  692.     endgrent ();            /* stop access to group file */
  693.     endspent ();            /* stop access to shadow passwd file */
  694. #ifdef    SHADOWGRP
  695.     endsgent ();            /* stop access to shadow group file */
  696. #endif
  697. #ifdef    USE_SYSLOG
  698.     if (pwent.pw_uid == 0)
  699.         syslog (LOG_INFO, ROOT_LOGIN, tty);
  700.  
  701.     closelog ();
  702. #endif
  703.     shell (pwent.pw_shell, (char *) 0); /* exec the shell finally. */
  704.     /*NOTREACHED*/
  705. }
  706.