📄 su.c
字号:
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 + -