Print this page
3808 sulogin should reset console to text mode
Reviewed by: Jason King <jason.brian.king@gmail.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
   1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */

  21 /*




  22  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 /*
  27  *      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T
  28  *      All rights reserved.
  29  *
  30  *      Copyright (c) 1987, 1988 Microsoft Corporation.
  31  *      All rights reserved.
  32  */
  33 
  34 /*
  35  *      sulogin - special login program exec'd from init to let user
  36  *      come up single user, or go to default init state straight away.
  37  *
  38  *      Explain the scoop to the user, prompt for an authorized user
  39  *      name or ^D and then prompt for password or ^D.  If the password
  40  *      is correct, check if the user is authorized, if so enter
  41  *      single user. ^D exits sulogin, and init will go to default init state.


  58 #include <pwd.h>
  59 #include <shadow.h>
  60 #include <stdlib.h>
  61 #include <stdio.h>
  62 #include <signal.h>
  63 #include <siginfo.h>
  64 #include <utmpx.h>
  65 #include <unistd.h>
  66 #include <ucontext.h>
  67 #include <string.h>
  68 #include <strings.h>
  69 #include <deflt.h>
  70 #include <limits.h>
  71 #include <errno.h>
  72 #include <crypt.h>
  73 #include <auth_attr.h>
  74 #include <auth_list.h>
  75 #include <nss_dbdefs.h>
  76 #include <user_attr.h>
  77 #include <sys/vt.h>

  78 
  79 /*
  80  * Intervals to sleep after failed login
  81  */
  82 #ifndef SLEEPTIME
  83 #define SLEEPTIME       4       /* sleeptime before login incorrect msg */
  84 #endif
  85 
  86 #define SLEEPTIME_MAX   5       /* maximum sleeptime */
  87 
  88 /*
  89  *      the name of the file containing the login defaults we deliberately
  90  *      use the same file as login(1)
  91  */
  92 
  93 #define DEFAULT_LOGIN   "/etc/default/login"
  94 #define DEFAULT_SULOGIN "/etc/default/sulogin"
  95 #define DEFAULT_CONSOLE "/dev/console"
  96 
  97 static char     shell[] = "/sbin/sh";


 425 static void
 426 setupsigs()
 427 {
 428         sa.sa_handler = noop;
 429         sa.sa_flags = 0;
 430         (void) sigemptyset(&sa.sa_mask);
 431         (void) sigaction(SIGINT, &sa, NULL);
 432         (void) sigaction(SIGQUIT, &sa, NULL);
 433 
 434         sa.sa_handler = termhandler;
 435         sa.sa_flags = 0;
 436         (void) sigemptyset(&sa.sa_mask);
 437         (void) sigaction(SIGTERM, &sa, NULL);
 438         (void) sigaction(SIGKILL, &sa, NULL);
 439         (void) sigaction(SIGHUP, &sa, NULL);
 440 }
 441 
 442 static void
 443 main_loop(char *devname, boolean_t cttyflag)
 444 {
 445         int             fd, i;
 446         char            *user = NULL;           /* authorized user */
 447         char            *pass;                  /* password from user */
 448         char            *cpass;                 /* crypted password */
 449         struct spwd     spwd;
 450         struct spwd     *lshpw;                 /* local shadow */
 451         char            shadow[NSS_BUFLEN_SHADOW];
 452         FILE            *sysmsgfd;
 453 
 454         for (i = 0; i < 3; i++)
 455                 (void) close(i);
 456         if (cttyflag == B_FALSE) {
 457                 if (setsid() == -1)
 458                         exit(EXIT_FAILURE);
 459         }
 460         if ((fd = open(devname, O_RDWR)) < 0)
 461                 exit(EXIT_FAILURE);
 462 
 463         /*
 464          * In system maintenance mode, all virtual console instances
 465          * of the svc:/system/console-login service are not available
 466          * any more, and only the system console is available. So here
 467          * we always switch to the system console in case at the moment
 468          * the active console isn't it.
 469          */
 470         (void) ioctl(fd, VT_ACTIVATE, 1);
 471 
 472         if (fd != 0)
 473                 (void) dup2(fd, STDIN_FILENO);
 474         if (fd != 1)
 475                 (void) dup2(fd, STDOUT_FILENO);
 476         if (fd != 2)
 477                 (void) dup2(fd, STDERR_FILENO);
 478         if (fd > 2)
 479                 (void) close(fd);
 480 






 481         sysmsgfd = fopen("/dev/sysmsg", "w");
 482 
 483         sanitize_tty(fileno(stdin));
 484 
 485         for (;;) {
 486                 do {
 487                         (void) printf("\nEnter user name for system "
 488                             "maintenance (control-d to bypass): ");
 489                         user = sulogin_getinput(devname, ECHOON);
 490                         if (user == NULL) {
 491                                 /* signal other children to exit */
 492                                 (void) sigsend(P_PID, masterpid, SIGUSR1);
 493                                 /* ^D, so straight to default init state */
 494                                 exit(EXIT_FAILURE);
 495                         }
 496                 } while (user[0] == '\0');
 497                 (void) printf("Enter %s password (control-d to bypass): ",
 498                     user);
 499 
 500                 if ((pass = sulogin_getinput(devname, ECHOOFF)) == NULL) {


   1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
  24  */
  25 
  26 /*
  27  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  28  * Use is subject to license terms.
  29  */
  30 
  31 /*
  32  *      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T
  33  *      All rights reserved.
  34  *
  35  *      Copyright (c) 1987, 1988 Microsoft Corporation.
  36  *      All rights reserved.
  37  */
  38 
  39 /*
  40  *      sulogin - special login program exec'd from init to let user
  41  *      come up single user, or go to default init state straight away.
  42  *
  43  *      Explain the scoop to the user, prompt for an authorized user
  44  *      name or ^D and then prompt for password or ^D.  If the password
  45  *      is correct, check if the user is authorized, if so enter
  46  *      single user. ^D exits sulogin, and init will go to default init state.


  63 #include <pwd.h>
  64 #include <shadow.h>
  65 #include <stdlib.h>
  66 #include <stdio.h>
  67 #include <signal.h>
  68 #include <siginfo.h>
  69 #include <utmpx.h>
  70 #include <unistd.h>
  71 #include <ucontext.h>
  72 #include <string.h>
  73 #include <strings.h>
  74 #include <deflt.h>
  75 #include <limits.h>
  76 #include <errno.h>
  77 #include <crypt.h>
  78 #include <auth_attr.h>
  79 #include <auth_list.h>
  80 #include <nss_dbdefs.h>
  81 #include <user_attr.h>
  82 #include <sys/vt.h>
  83 #include <sys/kd.h>
  84 
  85 /*
  86  * Intervals to sleep after failed login
  87  */
  88 #ifndef SLEEPTIME
  89 #define SLEEPTIME       4       /* sleeptime before login incorrect msg */
  90 #endif
  91 
  92 #define SLEEPTIME_MAX   5       /* maximum sleeptime */
  93 
  94 /*
  95  *      the name of the file containing the login defaults we deliberately
  96  *      use the same file as login(1)
  97  */
  98 
  99 #define DEFAULT_LOGIN   "/etc/default/login"
 100 #define DEFAULT_SULOGIN "/etc/default/sulogin"
 101 #define DEFAULT_CONSOLE "/dev/console"
 102 
 103 static char     shell[] = "/sbin/sh";


 431 static void
 432 setupsigs()
 433 {
 434         sa.sa_handler = noop;
 435         sa.sa_flags = 0;
 436         (void) sigemptyset(&sa.sa_mask);
 437         (void) sigaction(SIGINT, &sa, NULL);
 438         (void) sigaction(SIGQUIT, &sa, NULL);
 439 
 440         sa.sa_handler = termhandler;
 441         sa.sa_flags = 0;
 442         (void) sigemptyset(&sa.sa_mask);
 443         (void) sigaction(SIGTERM, &sa, NULL);
 444         (void) sigaction(SIGKILL, &sa, NULL);
 445         (void) sigaction(SIGHUP, &sa, NULL);
 446 }
 447 
 448 static void
 449 main_loop(char *devname, boolean_t cttyflag)
 450 {
 451         int             fd, fb, i;
 452         char            *user = NULL;           /* authorized user */
 453         char            *pass;                  /* password from user */
 454         char            *cpass;                 /* crypted password */
 455         struct spwd     spwd;
 456         struct spwd     *lshpw;                 /* local shadow */
 457         char            shadow[NSS_BUFLEN_SHADOW];
 458         FILE            *sysmsgfd;
 459 
 460         for (i = 0; i < 3; i++)
 461                 (void) close(i);
 462         if (cttyflag == B_FALSE) {
 463                 if (setsid() == -1)
 464                         exit(EXIT_FAILURE);
 465         }
 466         if ((fd = open(devname, O_RDWR)) < 0)
 467                 exit(EXIT_FAILURE);
 468 
 469         /*
 470          * In system maintenance mode, all virtual console instances
 471          * of the svc:/system/console-login service are not available
 472          * any more, and only the system console is available. So here
 473          * we always switch to the system console in case at the moment
 474          * the active console isn't it.
 475          */
 476         (void) ioctl(fd, VT_ACTIVATE, 1);
 477 
 478         if (fd != 0)
 479                 (void) dup2(fd, STDIN_FILENO);
 480         if (fd != 1)
 481                 (void) dup2(fd, STDOUT_FILENO);
 482         if (fd != 2)
 483                 (void) dup2(fd, STDERR_FILENO);
 484         if (fd > 2)
 485                 (void) close(fd);
 486 
 487         /* Stop progress bar and reset console mode to text */
 488         if ((fb = open("/dev/fb", O_RDONLY)) >= 0) {
 489                 (void) ioctl(fb, KDSETMODE, KD_RESETTEXT);
 490                 (void) close(fb);
 491         }
 492 
 493         sysmsgfd = fopen("/dev/sysmsg", "w");
 494 
 495         sanitize_tty(fileno(stdin));
 496 
 497         for (;;) {
 498                 do {
 499                         (void) printf("\nEnter user name for system "
 500                             "maintenance (control-d to bypass): ");
 501                         user = sulogin_getinput(devname, ECHOON);
 502                         if (user == NULL) {
 503                                 /* signal other children to exit */
 504                                 (void) sigsend(P_PID, masterpid, SIGUSR1);
 505                                 /* ^D, so straight to default init state */
 506                                 exit(EXIT_FAILURE);
 507                         }
 508                 } while (user[0] == '\0');
 509                 (void) printf("Enter %s password (control-d to bypass): ",
 510                     user);
 511 
 512                 if ((pass = sulogin_getinput(devname, ECHOOFF)) == NULL) {