summaryrefslogtreecommitdiffstats
path: root/login-utils/chsh.c
diff options
context:
space:
mode:
authorSami Kerola2011-11-23 23:04:12 +0100
committerSami Kerola2011-11-29 17:58:00 +0100
commit0a065b7ae692e4eabfae5994f728023c5772fb8c (patch)
tree61f3b37cc3aa8f06bee5d2b69f7acd4a017ec890 /login-utils/chsh.c
parentchfn: fix coding style (diff)
downloadkernel-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/chsh.c')
-rw-r--r--login-utils/chsh.c565
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;
}