diff options
author | Sami Kerola | 2011-11-23 23:04:12 +0100 |
---|---|---|
committer | Sami Kerola | 2011-11-29 17:58:00 +0100 |
commit | 0a065b7ae692e4eabfae5994f728023c5772fb8c (patch) | |
tree | 61f3b37cc3aa8f06bee5d2b69f7acd4a017ec890 /login-utils | |
parent | chfn: fix coding style (diff) | |
download | kernel-qcow2-util-linux-0a065b7ae692e4eabfae5994f728023c5772fb8c.tar.gz kernel-qcow2-util-linux-0a065b7ae692e4eabfae5994f728023c5772fb8c.tar.xz kernel-qcow2-util-linux-0a065b7ae692e4eabfae5994f728023c5772fb8c.zip |
chsh: fix coding style
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
Diffstat (limited to 'login-utils')
-rw-r--r-- | login-utils/chsh.c | 565 |
1 files changed, 290 insertions, 275 deletions
diff --git a/login-utils/chsh.c b/login-utils/chsh.c index f6a5c9fa1..3aa4f350b 100644 --- a/login-utils/chsh.c +++ b/login-utils/chsh.c @@ -19,178 +19,182 @@ * * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL> * - added Native Language Support - * - * */ -#include <sys/types.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <unistd.h> -#include <pwd.h> -#include <errno.h> + #include <ctype.h> +#include <errno.h> #include <getopt.h> +#include <pwd.h> #include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <unistd.h> -#include "pamfail.h" #include "c.h" +#include "env.h" #include "islocal.h" -#include "setpwnam.h" #include "nls.h" -#include "env.h" +#include "pamfail.h" #include "pathnames.h" +#include "setpwnam.h" #include "xalloc.h" #ifdef HAVE_LIBSELINUX -#include <selinux/selinux.h> -#include <selinux/av_permissions.h> -#include "selinux_utils.h" +# include <selinux/selinux.h> +# include <selinux/av_permissions.h> +# include "selinux_utils.h" #endif struct sinfo { - char *username; - char *shell; + char *username; + char *shell; }; -static void parse_argv (int argc, char *argv[], struct sinfo *pinfo); -static char *prompt (char *question, char *def_val); -static int check_shell (char *shell); -static int get_shell_list (char *shell); +static void parse_argv(int argc, char **argv, struct sinfo *pinfo); +static char *prompt(char *question, char *def_val); +static int check_shell(char *shell); +static int get_shell_list(char *shell); static void __attribute__((__noreturn__)) usage (FILE *fp) { - fputs(USAGE_HEADER, fp); - fprintf(fp, _(" %s [options] [username]\n"), program_invocation_short_name); - fputs(USAGE_OPTIONS, fp); - fputs(_(" -s, --shell <shell> specify login shell\n"), fp); - fputs(_(" -l, --list-shells print list of shells and exit\n"), fp); - fputs(USAGE_SEPARATOR, fp); - fputs(_(" -u, --help display this help and exit\n"), fp); - fputs(_(" -v, --version output version information and exit\n"), fp); - fprintf(fp, USAGE_MAN_TAIL("chsh(1)")); - exit(fp == stderr ? EXIT_FAILURE : EXIT_SUCCESS); + fputs(USAGE_HEADER, fp); + fprintf(fp, _(" %s [options] [username]\n"), program_invocation_short_name); + fputs(USAGE_OPTIONS, fp); + fputs(_(" -s, --shell <shell> specify login shell\n"), fp); + fputs(_(" -l, --list-shells print list of shells and exit\n"), fp); + fputs(USAGE_SEPARATOR, fp); + fputs(_(" -u, --help display this help and exit\n"), fp); + fputs(_(" -v, --version output version information and exit\n"), fp); + fprintf(fp, USAGE_MAN_TAIL("chsh(1)")); + exit(fp == stderr ? EXIT_FAILURE : EXIT_SUCCESS); } -int -main (int argc, char *argv[]) { - char *shell, *oldshell; - uid_t uid; - struct sinfo info; - struct passwd *pw; - - sanitize_env(); - setlocale(LC_ALL, ""); - bindtextdomain(PACKAGE, LOCALEDIR); - textdomain(PACKAGE); - - uid = getuid (); - memset(&info, 0, sizeof(info)); - - parse_argv (argc, argv, &info); - pw = NULL; - if (! info.username) { - pw = getpwuid (uid); - if (! pw) - errx(EXIT_FAILURE, _("you (user %d) don't exist."), uid); - } - else { - pw = getpwnam (info.username); - if (! pw) - errx(EXIT_FAILURE, _("user \"%s\" does not exist."), - info.username); - } - - if (!(is_local(pw->pw_name))) - errx(EXIT_FAILURE, _("can only change local entries.")); +int main(int argc, char **argv) +{ + char *shell, *oldshell; + uid_t uid; + struct sinfo info; + struct passwd *pw; + + sanitize_env(); + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + uid = getuid(); + memset(&info, 0, sizeof(info)); + + parse_argv(argc, argv, &info); + pw = NULL; + if (!info.username) { + pw = getpwuid(uid); + if (!pw) + errx(EXIT_FAILURE, _("you (user %d) don't exist."), + uid); + } else { + pw = getpwnam(info.username); + if (!pw) + errx(EXIT_FAILURE, _("user \"%s\" does not exist."), + info.username); + } + + if (!(is_local(pw->pw_name))) + errx(EXIT_FAILURE, _("can only change local entries.")); #ifdef HAVE_LIBSELINUX - if (is_selinux_enabled() > 0) { - if(uid == 0) { - if (checkAccess(pw->pw_name,PASSWD__CHSH)!=0) { - security_context_t user_context; - if (getprevcon(&user_context) < 0) - user_context = (security_context_t) NULL; - - errx(EXIT_FAILURE, _("%s is not authorized to change the shell of %s"), - user_context ? : _("Unknown user context"), - pw->pw_name); + if (is_selinux_enabled() > 0) { + if (uid == 0) { + if (checkAccess(pw->pw_name, PASSWD__CHSH) != 0) { + security_context_t user_context; + if (getprevcon(&user_context) < 0) + user_context = + (security_context_t) NULL; + + errx(EXIT_FAILURE, + _("%s is not authorized to change the shell of %s"), + user_context ? : _("Unknown user context"), + pw->pw_name); + } + } + if (setupDefaultContext("/etc/passwd") != 0) + errx(EXIT_FAILURE, + _("can't set default context for /etc/passwd")); } - } - if (setupDefaultContext("/etc/passwd") != 0) - errx(EXIT_FAILURE, _("can't set default context for /etc/passwd")); - } #endif - oldshell = pw->pw_shell; - if (oldshell == NULL || *oldshell == '\0') - oldshell = _PATH_BSHELL; /* default */ + oldshell = pw->pw_shell; + if (oldshell == NULL || *oldshell == '\0') + oldshell = _PATH_BSHELL; /* default */ - /* reality check */ - if (uid != 0 && uid != pw->pw_uid) { - errno = EACCES; - err(EXIT_FAILURE, _("running UID doesn't match UID of user we're " - "altering, shell change denied")); - } - if (uid != 0 && !get_shell_list(oldshell)) { - errno = EACCES; - err(EXIT_FAILURE, _("your shell is not in /etc/shells, " - "shell change denied")); - } + /* reality check */ + if (uid != 0 && uid != pw->pw_uid) { + errno = EACCES; + err(EXIT_FAILURE, + _("running UID doesn't match UID of user we're " + "altering, shell change denied")); + } + if (uid != 0 && !get_shell_list(oldshell)) { + errno = EACCES; + err(EXIT_FAILURE, _("your shell is not in /etc/shells, " + "shell change denied")); + } - shell = info.shell; + shell = info.shell; - printf( _("Changing shell for %s.\n"), pw->pw_name ); + printf(_("Changing shell for %s.\n"), pw->pw_name); #ifdef REQUIRE_PASSWORD - if (uid != 0) { - pam_handle_t *pamh = NULL; - struct pam_conv conv = { misc_conv, NULL }; - int retcode; - - retcode = pam_start("chsh", pw->pw_name, &conv, &pamh); - if (pam_fail_check(pamh, retcode)) - exit(EXIT_FAILURE); - - retcode = pam_authenticate(pamh, 0); - if (pam_fail_check(pamh, retcode)) - exit(EXIT_FAILURE); - - retcode = pam_acct_mgmt(pamh, 0); - if (retcode == PAM_NEW_AUTHTOK_REQD) - retcode = pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK); - if (pam_fail_check(pamh, retcode)) - exit(EXIT_FAILURE); - - retcode = pam_setcred(pamh, 0); - if (pam_fail_check(pamh, retcode)) - exit(EXIT_FAILURE); - - pam_end(pamh, 0); - /* no need to establish a session; this isn't a session-oriented - * activity... */ - } -#endif /* REQUIRE_PASSWORD */ - - if (! shell) { - shell = prompt (_("New shell"), oldshell); - if (! shell) - return EXIT_SUCCESS; - } - - if (check_shell (shell) < 0) - return EXIT_FAILURE; - - if (! strcmp (pw->pw_shell, shell)) - errx (EXIT_SUCCESS, _("Shell not changed.")); - pw->pw_shell = shell; - if (setpwnam (pw) < 0) { - warn(_("setpwnam failed\n" - "Shell *NOT* changed. Try again later.")); - return EXIT_FAILURE; - } - printf (_("Shell changed.\n")); - return EXIT_SUCCESS; + if (uid != 0) { + pam_handle_t *pamh = NULL; + struct pam_conv conv = { misc_conv, NULL }; + int retcode; + + retcode = pam_start("chsh", pw->pw_name, &conv, &pamh); + if (pam_fail_check(pamh, retcode)) + exit(EXIT_FAILURE); + + retcode = pam_authenticate(pamh, 0); + if (pam_fail_check(pamh, retcode)) + exit(EXIT_FAILURE); + + retcode = pam_acct_mgmt(pamh, 0); + if (retcode == PAM_NEW_AUTHTOK_REQD) + retcode = + pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK); + if (pam_fail_check(pamh, retcode)) + exit(EXIT_FAILURE); + + retcode = pam_setcred(pamh, 0); + if (pam_fail_check(pamh, retcode)) + exit(EXIT_FAILURE); + + pam_end(pamh, 0); + /* no need to establish a session; this isn't a + * session-oriented activity... */ + } +#endif /* REQUIRE_PASSWORD */ + + if (!shell) { + shell = prompt(_("New shell"), oldshell); + if (!shell) + return EXIT_SUCCESS; + } + + if (check_shell(shell) < 0) + return EXIT_FAILURE; + + if (!strcmp(pw->pw_shell, shell)) + errx(EXIT_SUCCESS, _("Shell not changed.")); + pw->pw_shell = shell; + if (setpwnam(pw) < 0) { + warn(_("setpwnam failed\n" + "Shell *NOT* changed. Try again later.")); + return EXIT_FAILURE; + } + printf(_("Shell changed.\n")); + return EXIT_SUCCESS; } /* @@ -198,75 +202,78 @@ main (int argc, char *argv[]) { * parse the command line arguments, and fill in "pinfo" with any * information from the command line. */ -static void -parse_argv (int argc, char *argv[], struct sinfo *pinfo) { - int index, c; - - static struct option long_options[] = { - { "shell", required_argument, 0, 's' }, - { "list-shells", no_argument, 0, 'l' }, - { "help", no_argument, 0, 'u' }, - { "version", no_argument, 0, 'v' }, - { NULL, no_argument, 0, '0' }, - }; - - optind = c = 0; - while (c != EOF) { - c = getopt_long (argc, argv, "s:luv", long_options, &index); - switch (c) { - case -1: - break; - case 'v': - printf (UTIL_LINUX_VERSION); - exit (EXIT_SUCCESS); - case 'u': - usage (stdout); - case 'l': - get_shell_list (NULL); - exit (EXIT_SUCCESS); - case 's': - if (! optarg) - usage (stderr); - pinfo->shell = optarg; - break; - default: - usage (stderr); +static void parse_argv(int argc, char **argv, struct sinfo *pinfo) +{ + int index, c; + + static struct option long_options[] = { + {"shell", required_argument, 0, 's'}, + {"list-shells", no_argument, 0, 'l'}, + {"help", no_argument, 0, 'u'}, + {"version", no_argument, 0, 'v'}, + {NULL, no_argument, 0, '0'}, + }; + + optind = c = 0; + while (c != EOF) { + c = getopt_long(argc, argv, "s:luv", long_options, &index); + switch (c) { + case -1: + break; + case 'v': + printf(UTIL_LINUX_VERSION); + exit(EXIT_SUCCESS); + case 'u': + usage(stdout); + case 'l': + get_shell_list(NULL); + exit(EXIT_SUCCESS); + case 's': + if (!optarg) + usage(stderr); + pinfo->shell = optarg; + break; + default: + usage(stderr); + } + } + /* done parsing arguments. check for a username. */ + if (optind < argc) { + if (optind + 1 < argc) + usage(stderr); + pinfo->username = argv[optind]; } - } - /* done parsing arguments. check for a username. */ - if (optind < argc) { - if (optind + 1 < argc) - usage (stderr); - pinfo->username = argv[optind]; - } } - /* * prompt () -- * ask the user for a given field and return it. */ -static char * -prompt (char *question, char *def_val) { - int len; - char *ans, *cp; - char buf[BUFSIZ]; - - if (! def_val) def_val = ""; - printf("%s [%s]: ", question, def_val); - *buf = 0; - if (fgets (buf, sizeof (buf), stdin) == NULL) - errx (EXIT_FAILURE, _("Aborted.")); - /* remove the newline at the end of buf. */ - ans = buf; - while (isspace (*ans)) ans++; - len = strlen (ans); - while (len > 0 && isspace (ans[len-1])) len--; - if (len <= 0) return NULL; - ans[len] = 0; - cp = (char *) xmalloc (len + 1); - strcpy (cp, ans); - return cp; +static char *prompt(char *question, char *def_val) +{ + int len; + char *ans, *cp; + char buf[BUFSIZ]; + + if (!def_val) + def_val = ""; + printf("%s [%s]: ", question, def_val); + *buf = 0; + if (fgets(buf, sizeof(buf), stdin) == NULL) + errx(EXIT_FAILURE, _("Aborted.")); + /* remove the newline at the end of buf. */ + ans = buf; + while (isspace(*ans)) + ans++; + len = strlen(ans); + while (len > 0 && isspace(ans[len - 1])) + len--; + if (len <= 0) + return NULL; + ans[len] = 0; + cp = (char *)xmalloc(len + 1); + strcpy(cp, ans); + return cp; } /* @@ -274,52 +281,57 @@ prompt (char *question, char *def_val) { * an error and return (-1). * if the shell is a bad idea, print a warning. */ -static int -check_shell (char *shell) { - unsigned int i, c; - - if (!shell) - return -1; - - if (*shell != '/') { - warnx (_("shell must be a full path name")); - return -1; - } - if (access (shell, F_OK) < 0) { - warnx (_("\"%s\" does not exist"), shell); - return -1; - } - if (access (shell, X_OK) < 0) { - printf (_("\"%s\" is not executable"), shell); - return -1; - } - /* keep /etc/passwd clean. */ - for (i = 0; i < strlen (shell); i++) { - c = shell[i]; - if (c == ',' || c == ':' || c == '=' || c == '"' || c == '\n') { - warnx (_("'%c' is not allowed"), c); - return -1; +static int check_shell(char *shell) +{ + unsigned int i, c; + + if (!shell) + return -1; + + if (*shell != '/') { + warnx(_("shell must be a full path name")); + return -1; + } + if (access(shell, F_OK) < 0) { + warnx(_("\"%s\" does not exist"), shell); + return -1; } - if (iscntrl (c)) { - warnx (_("control characters are not allowed")); - return -1; + if (access(shell, X_OK) < 0) { + printf(_("\"%s\" is not executable"), shell); + return -1; + } + /* keep /etc/passwd clean. */ + for (i = 0; i < strlen(shell); i++) { + c = shell[i]; + if (c == ',' || c == ':' || c == '=' || c == '"' || c == '\n') { + warnx(_("'%c' is not allowed"), c); + return -1; + } + if (iscntrl(c)) { + warnx(_("control characters are not allowed")); + return -1; + } } - } #ifdef ONLY_LISTED_SHELLS - if (! get_shell_list (shell)) { - if (!getuid()) - warnx(_("Warning: \"%s\" is not listed in /etc/shells."), shell); - else - errx(EXIT_FAILURE, _("\"%s\" is not listed in /etc/shells.\n" - "Use %s -l to see list."), shell, program_invocation_short_name); - } + if (!get_shell_list(shell)) { + if (!getuid()) + warnx(_ + ("Warning: \"%s\" is not listed in /etc/shells."), + shell); + else + errx(EXIT_FAILURE, + _("\"%s\" is not listed in /etc/shells.\n" + "Use %s -l to see list."), shell, + program_invocation_short_name); + } #else - if (! get_shell_list (shell)) { - warnx(_("\"%s\" is not listed in /etc/shells.\n" - "Use %s -l to see list."), shell, program_invocation_short_name); - } + if (!get_shell_list(shell)) { + warnx(_("\"%s\" is not listed in /etc/shells.\n" + "Use %s -l to see list."), shell, + program_invocation_short_name); + } #endif - return 0; + return 0; } /* @@ -327,37 +339,40 @@ check_shell (char *shell) { * return true. if not, return false. * if the given shell is NULL, /etc/shells is outputted to stdout. */ -static int -get_shell_list (char *shell_name) { - FILE *fp; - int found; - int len; - char buf[PATH_MAX]; - - found = false; - fp = fopen ("/etc/shells", "r"); - if (! fp) { - if (! shell_name) - warnx (_("No known shells.")); - return true; - } - while (fgets (buf, sizeof (buf), fp) != NULL) { - /* ignore comments */ - if (*buf == '#') continue; - len = strlen (buf); - /* strip the ending newline */ - if (buf[len - 1] == '\n') buf[len - 1] = 0; - /* ignore lines that are too damn long */ - else continue; - /* check or output the shell */ - if (shell_name) { - if (! strcmp (shell_name, buf)) { - found = true; - break; - } +static int get_shell_list(char *shell_name) +{ + FILE *fp; + int found; + int len; + char buf[PATH_MAX]; + + found = false; + fp = fopen("/etc/shells", "r"); + if (!fp) { + if (!shell_name) + warnx(_("No known shells.")); + return true; + } + while (fgets(buf, sizeof(buf), fp) != NULL) { + /* ignore comments */ + if (*buf == '#') + continue; + len = strlen(buf); + /* strip the ending newline */ + if (buf[len - 1] == '\n') + buf[len - 1] = 0; + /* ignore lines that are too damn long */ + else + continue; + /* check or output the shell */ + if (shell_name) { + if (!strcmp(shell_name, buf)) { + found = true; + break; + } + } else + printf("%s\n", buf); } - else printf ("%s\n", buf); - } - fclose (fp); - return found; + fclose(fp); + return found; } |