⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 su.c

📁 Unix/Linux下转换用户ID的su程序源码
💻 C
📖 第 1 页 / 共 2 页
字号:
  if (unencrypted == NULL)    {      error (0, 0, _("getpass: cannot open /dev/tty"));      return 0;    }  encrypted = crypt (unencrypted, correct);  memset (unencrypted, 0, strlen (unencrypted));  return strcmp (encrypted, correct) == 0;}/* Update `environ' for the new shell based on PW, with SHELL being   the value for the SHELL environment variable.  */static voidmodify_environment (const struct passwd *pw, const char *shell)/* [<][>][^][v][top][bottom][index][help] */{  char *term;  if (simulate_login)    {      /* Leave TERM unchanged.  Set HOME, SHELL, USER, LOGNAME, PATH.         Unset all other environment variables.  */      term = getenv ("TERM");      environ = (char **) xmalloc (2 * sizeof (char *));      environ[0] = 0;      if (term)        xputenv (concat ("TERM", "=", term));      xputenv (concat ("HOME", "=", pw->pw_dir));      xputenv (concat ("SHELL", "=", shell));      xputenv (concat ("USER", "=", pw->pw_name));      xputenv (concat ("LOGNAME", "=", pw->pw_name));      xputenv (concat ("PATH", "=", pw->pw_uid                       ? DEFAULT_LOGIN_PATH : DEFAULT_ROOT_LOGIN_PATH));    }  else    {      /* Set HOME, SHELL, and if not becoming a super-user,         USER and LOGNAME.  */      if (change_environment)        {          xputenv (concat ("HOME", "=", pw->pw_dir));          xputenv (concat ("SHELL", "=", shell));          if (pw->pw_uid)            {              xputenv (concat ("USER", "=", pw->pw_name));              xputenv (concat ("LOGNAME", "=", pw->pw_name));            }        }    }}/* Become the user and group(s) specified by PW.  */static voidchange_identity (const struct passwd *pw)/* [<][>][^][v][top][bottom][index][help] */{#ifdef HAVE_INITGROUPS  errno = 0;  if (initgroups (pw->pw_name, pw->pw_gid) == -1)    error (1, errno, _("cannot set groups"));  endgrent ();#endif  if (setgid (pw->pw_gid))    error (1, errno, _("cannot set group id"));  if (setuid (pw->pw_uid))    error (1, errno, _("cannot set user id"));}/* Run SHELL, or DEFAULT_SHELL if SHELL is empty.   If COMMAND is nonzero, pass it to the shell with the -c option.   If ADDITIONAL_ARGS is nonzero, pass it to the shell as more   arguments.  */static voidrun_shell (const char *shell, const char *command, char **additional_args)/* [<][>][^][v][top][bottom][index][help] */{  const char **args;  int argno = 1;  if (additional_args)    args = (const char **) xmalloc (sizeof (char *)                                    * (10 + elements (additional_args)));  else    args = (const char **) xmalloc (sizeof (char *) * 10);  if (simulate_login)    {      char *arg0;      char *shell_basename;      shell_basename = basename (shell);      arg0 = xmalloc (strlen (shell_basename) + 2);      arg0[0] = '-';      strcpy (arg0 + 1, shell_basename);      args[0] = arg0;    }  else    args[0] = basename (shell);  if (fast_startup)    args[argno++] = "-f";  if (command)    {      args[argno++] = "-c";      args[argno++] = command;    }  if (additional_args)    for (; *additional_args; ++additional_args)      args[argno++] = *additional_args;  args[argno] = NULL;  execv (shell, (char **) args);  error (1, errno, _("cannot run %s"), shell);}/* Return 1 if SHELL is a restricted shell (one not returned by   getusershell), else 0, meaning it is a standard shell.  */static intrestricted_shell (const char *shell)/* [<][>][^][v][top][bottom][index][help] */{  char *line;  setusershell ();  while ((line = getusershell ()) != NULL)    {      if (*line != '#' && strcmp (line, shell) == 0)        {          endusershell ();          return 0;        }    }  endusershell ();  return 1;}static voidusage (int status)/* [<][>][^][v][top][bottom][index][help] */{  if (status != 0)    fprintf (stderr, _("Try `%s --help' for more information.\n"),             program_name);  else    {      printf (_("Usage: %s [OPTION]... [-] [USER [ARG]...]\n"), program_name);      printf (_("\Change the effective user id and group id to that of USER.\n\\n\  -, -l, --login               make the shell a login shell\n\  -c, --commmand=COMMAND       pass a single COMMAND to the shell with -c\n\  -f, --fast                   pass -f to the shell (for csh or tcsh)\n\  -m, --preserve-environment   do not reset environment variables\n\  -p                           same as -m\n\  -s, --shell=SHELL            run SHELL if /etc/shells allows it\n\      --help                   display this help and exit\n\      --version                output version information and exit\n\\n\A mere - implies -l.   If USER not given, assume root.\n\"));      puts (_("\nReport bugs to sh-utils-bugs@gnu.ai.mit.edu"));    }  exit (status);}intmain (int argc, char **argv)/* [<][>][^][v][top][bottom][index][help] */{  int optc;  const char *new_user = DEFAULT_USER;  char *command = 0;  char **additional_args = 0;  char *shell = 0;  struct passwd *pw;  struct passwd pw_copy;  program_name = argv[0];  setlocale (LC_ALL, "");  bindtextdomain (PACKAGE, LOCALEDIR);  textdomain (PACKAGE);  fast_startup = 0;  simulate_login = 0;  change_environment = 1;  while ((optc = getopt_long (argc, argv, "c:flmps:", longopts, (int *) 0))         != EOF)    {      switch (optc)        {        case 0:          break;        case 'c':          command = optarg;          break;        case 'f':          fast_startup = 1;          break;        case 'l':          simulate_login = 1;          break;        case 'm':        case 'p':          change_environment = 0;          break;        case 's':          shell = optarg;          break;        default:          usage (1);        }    }  if (show_version)    {      printf ("su (%s) %s\n", GNU_PACKAGE, VERSION);      exit (0);    }  if (show_help)    usage (0);  if (optind < argc && !strcmp (argv[optind], "-"))    {      simulate_login = 1;      ++optind;    }  if (optind < argc)    new_user = argv[optind++];  if (optind < argc)    additional_args = argv + optind;  pw = getpwnam (new_user);  if (pw == 0)    error (1, 0, _("user %s does not exist"), new_user);  endpwent ();  /* Make a copy of the password information and point pw at the local     copy instead.  Otherwise, some systems (e.g. Linux) would clobber     the static data through the getlogin call from log_su.  */  pw_copy = *pw;  pw = &pw_copy;  pw->pw_name = xstrdup (pw->pw_name);  pw->pw_dir = xstrdup (pw->pw_dir);  pw->pw_shell = xstrdup (pw->pw_shell);  if (!correct_password (pw))    {#ifdef SYSLOG_FAILURE      log_su (pw, 0);#endif      error (1, 0, _("incorrect password"));    }#ifdef SYSLOG_SUCCESS  else    {      log_su (pw, 1);    }#endif  if (pw->pw_shell == 0 || pw->pw_shell[0] == 0)    pw->pw_shell = (char *) DEFAULT_SHELL;  if (shell == 0 && change_environment == 0)    shell = getenv ("SHELL");  if (shell != 0 && getuid () && restricted_shell (pw->pw_shell))    {      /* The user being su'd to has a nonstandard shell, and so is         probably a uucp account or has restricted access.  Don't         compromise the account by allowing access with a standard         shell.  */      error (0, 0, _("using restricted shell %s"), pw->pw_shell);      shell = 0;    }  if (shell == 0)    {      shell = xstrdup (pw->pw_shell);    }  modify_environment (pw, shell);  change_identity (pw);  if (simulate_login && chdir (pw->pw_dir))    error (0, errno, _("warning: cannot change directory to %s"), pw->pw_dir);  run_shell (shell, command, additional_args);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -