]> granicus.if.org Git - shadow/commitdiff
* Split also check_perms() out of main().
authornekral-guest <nekral-guest@5a98b0ae-9ef6-0310-add3-de5d479b70d7>
Mon, 31 Dec 2007 14:54:46 +0000 (14:54 +0000)
committernekral-guest <nekral-guest@5a98b0ae-9ef6-0310-add3-de5d479b70d7>
Mon, 31 Dec 2007 14:54:46 +0000 (14:54 +0000)
* Before pam_end(), the return value of the previous
  pam API was already checked. No need to validate it again.

ChangeLog
src/chsh.c

index f18bac435e4492e304990b5c6a36381bc6a490c6..5823054aa179754dab9bd2a3a9de44968d64ef0c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,8 @@
 2007-12-31  Nicolas François  <nicolas.francois@centraliens.net>
 
-       * src/chsh.c: Split process_flags() out of main().
+       * src/chsh.c: Split process_flags(), and check_perms() out of main().
+       * src/chsh.c: Before pam_end(), the return value of the previous
+       pam API was already checked. No need to validate it again.
 
 2007-12-31  Nicolas François  <nicolas.francois@centraliens.net>
 
index 008da868f0d055aac36a83ae2fd49796cd2332bb..d554a4e0ca6344b187c25b392ff98737c3782ebc 100644 (file)
@@ -72,6 +72,7 @@ static void new_fields (void);
 static int check_shell (const char *);
 static int restricted_shell (const char *);
 static void process_flags (int argc, char **argv);
+static void check_perms (const struct passwd *pw);
 
 /*
  * usage - print command line syntax and exit
@@ -208,6 +209,107 @@ static void process_flags (int argc, char **argv)
        }
 }
 
+/*
+ * check_perms - check if the caller is allowed to add a group
+ *
+ *     Non-root users are only allowed to change their shell, if their current
+ *     shell is not a restricted shell.
+ *
+ *     Non-root users must be authenticated.
+ *
+ *     It will not return if the user is not allowed.
+ */
+static void check_perms (const struct passwd *pw)
+{
+#ifdef USE_PAM
+       pam_handle_t *pamh = NULL;
+       int retval;
+       struct passwd *pampw;
+#endif
+
+       /*
+        * Non-privileged users are only allowed to change the shell if the
+        * UID of the user matches the current real UID.
+        */
+       if (!amroot && pw->pw_uid != getuid ()) {
+               SYSLOG ((LOG_WARN, "can't change shell for `%s'", user));
+               closelog ();
+               fprintf (stderr,
+                        _("You may not change the shell for %s.\n"), user);
+               exit (1);
+       }
+
+       /*
+        * Non-privileged users are only allowed to change the shell if it
+        * is not a restricted one.
+        */
+       if (!amroot && restricted_shell (pw->pw_shell)) {
+               SYSLOG ((LOG_WARN, "can't change shell for `%s'", user));
+               closelog ();
+               fprintf (stderr,
+                        _("You may not change the shell for %s.\n"), user);
+               exit (1);
+       }
+#ifdef WITH_SELINUX
+       /*
+        * If the UID of the user does not match the current real UID,
+        * check if the change is allowed by SELinux policy.
+        */
+       if ((pw->pw_uid != getuid ())
+           && (is_selinux_enabled () > 0)
+           && (selinux_check_passwd_access (PASSWD__CHSH) != 0)) {
+               SYSLOG ((LOG_WARN, "can't change shell for `%s'", user));
+               closelog ();
+               fprintf (stderr,
+                        _("You may not change the shell for %s.\n"), user);
+               exit (1);
+       }
+#endif
+
+#ifndef USE_PAM
+       /*
+        * Non-privileged users are optionally authenticated (must enter
+        * the password of the user whose information is being changed)
+        * before any changes can be made. Idea from util-linux
+        * chfn/chsh.  --marekm
+        */
+       if (!amroot && getdef_bool ("CHSH_AUTH")) {
+               passwd_check (pw->pw_name, pw->pw_passwd, "chsh");
+        }
+
+#else                          /* !USE_PAM */
+       retval = PAM_SUCCESS;
+
+       pampw = getpwuid (getuid ()); /* local, no need for xgetpwuid */
+       if (pampw == NULL) {
+               retval = PAM_USER_UNKNOWN;
+       }
+
+       if (retval == PAM_SUCCESS) {
+               retval = pam_start ("chsh", pampw->pw_name, &conv, &pamh);
+       }
+
+       if (retval == PAM_SUCCESS) {
+               retval = pam_authenticate (pamh, 0);
+               if (retval != PAM_SUCCESS) {
+                       pam_end (pamh, retval);
+               }
+       }
+
+       if (retval == PAM_SUCCESS) {
+               retval = pam_acct_mgmt (pamh, 0);
+               if (retval != PAM_SUCCESS) {
+                       pam_end (pamh, retval);
+               }
+       }
+
+       if (retval != PAM_SUCCESS) {
+               fprintf (stderr, _("%s: PAM authentication failed\n"), Prog);
+               exit (E_NOPERM);
+       }
+#endif                         /* USE_PAM */
+}
+
 /*
  * chsh - this command controls changes to the user's shell
  *
@@ -221,11 +323,6 @@ int main (int argc, char **argv)
        const struct passwd *pw;        /* Password entry from /etc/passwd   */
        struct passwd pwent;    /* New password entry                */
 
-#ifdef USE_PAM
-       pam_handle_t *pamh = NULL;
-       int retval;
-#endif
-
        sanitize_env ();
 
        setlocale (LC_ALL, "");
@@ -295,90 +392,7 @@ int main (int argc, char **argv)
        }
 #endif
 
-       /*
-        * Non-privileged users are only allowed to change the shell if the
-        * UID of the user matches the current real UID.
-        */
-       if (!amroot && pw->pw_uid != getuid ()) {
-               SYSLOG ((LOG_WARN, "can't change shell for `%s'", user));
-               closelog ();
-               fprintf (stderr,
-                        _("You may not change the shell for %s.\n"), user);
-               exit (1);
-       }
-
-       /*
-        * Non-privileged users are only allowed to change the shell if it
-        * is not a restricted one.
-        */
-       if (!amroot && restricted_shell (pw->pw_shell)) {
-               SYSLOG ((LOG_WARN, "can't change shell for `%s'", user));
-               closelog ();
-               fprintf (stderr,
-                        _("You may not change the shell for %s.\n"), user);
-               exit (1);
-       }
-#ifdef WITH_SELINUX
-       /*
-        * If the UID of the user does not match the current real UID,
-        * check if the change is allowed by SELinux policy.
-        */
-       if ((pw->pw_uid != getuid ())
-           && (is_selinux_enabled () > 0)
-           && (selinux_check_passwd_access (PASSWD__CHSH) != 0)) {
-               SYSLOG ((LOG_WARN, "can't change shell for `%s'", user));
-               closelog ();
-               fprintf (stderr,
-                        _("You may not change the shell for %s.\n"), user);
-               exit (1);
-       }
-#endif
-
-#ifndef USE_PAM
-       /*
-        * Non-privileged users are optionally authenticated (must enter
-        * the password of the user whose information is being changed)
-        * before any changes can be made. Idea from util-linux
-        * chfn/chsh.  --marekm
-        */
-       if (!amroot && getdef_bool ("CHSH_AUTH"))
-               passwd_check (pw->pw_name, pw->pw_passwd, "chsh");
-
-#else                          /* !USE_PAM */
-       retval = PAM_SUCCESS;
-
-       {
-               struct passwd *pampw;
-               pampw = getpwuid (getuid ()); /* local, no need for xgetpwuid */
-               if (pampw == NULL) {
-                       retval = PAM_USER_UNKNOWN;
-               }
-
-               if (retval == PAM_SUCCESS) {
-                       retval = pam_start ("chsh", pampw->pw_name,
-                                           &conv, &pamh);
-               }
-       }
-
-       if (retval == PAM_SUCCESS) {
-               retval = pam_authenticate (pamh, 0);
-               if (retval != PAM_SUCCESS) {
-                       pam_end (pamh, retval);
-               }
-       }
-
-       if (retval == PAM_SUCCESS) {
-               retval = pam_acct_mgmt (pamh, 0);
-               if (retval != PAM_SUCCESS) {
-                       pam_end (pamh, retval);
-               }
-       }
-
-       if (retval != PAM_SUCCESS) {
-               fprintf (stderr, _("%s: PAM authentication failed\n"), Prog);
-               exit (E_NOPERM);
-       }
-#endif                         /* USE_PAM */
+       check_perms (pw);
 
        /*
         * Now get the login shell. Either get it from the password
@@ -501,8 +515,7 @@ int main (int argc, char **argv)
        nscd_flush_cache ("passwd");
 
 #ifdef USE_PAM
-       if (retval == PAM_SUCCESS)
-               pam_end (pamh, PAM_SUCCESS);
+       pam_end (pamh, PAM_SUCCESS);
 #endif                         /* USE_PAM */
 
        closelog ();