]> granicus.if.org Git - shadow/commitdiff
Also split update_shell() out of main().
authornekral-guest <nekral-guest@5a98b0ae-9ef6-0310-add3-de5d479b70d7>
Mon, 31 Dec 2007 15:06:22 +0000 (15:06 +0000)
committernekral-guest <nekral-guest@5a98b0ae-9ef6-0310-add3-de5d479b70d7>
Mon, 31 Dec 2007 15:06:22 +0000 (15:06 +0000)
ChangeLog
src/chsh.c

index 5823054aa179754dab9bd2a3a9de44968d64ef0c..f8457a5347bc13538f53e78d9dedb3a06b618e87 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,7 @@
 2007-12-31  Nicolas François  <nicolas.francois@centraliens.net>
 
-       * src/chsh.c: Split process_flags(), and check_perms() out of main().
+       * src/chsh.c: Split process_flags(), check_perms(), and update_shell()
+       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.
 
index d554a4e0ca6344b187c25b392ff98737c3782ebc..3da44b6880fdbc345f64720cd21ca19ab9820593 100644 (file)
@@ -73,6 +73,7 @@ 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);
+static void update_shell (const char *user, char *loginsh);
 
 /*
  * usage - print command line syntax and exit
@@ -310,6 +311,103 @@ static void check_perms (const struct passwd *pw)
 #endif                         /* USE_PAM */
 }
 
+/*
+ * update_shell - update the user's shell in the passwd database
+ *
+ *     Commit the user's entry after changing her shell field.
+ *
+ *     It will not return in case of error.
+ */
+static void update_shell (const char *user, char *loginsh)
+{
+       const struct passwd *pw;        /* Password entry from /etc/passwd   */
+       struct passwd pwent;            /* New password entry                */
+
+       /*
+        * Before going any further, raise the ulimit to prevent
+        * colliding into a lowered ulimit, and set the real UID
+        * to root to protect against unexpected signals. Any
+        * keyboard signals are set to be ignored.
+        */
+       if (setuid (0) != 0) {
+               SYSLOG ((LOG_ERR, "can't setuid(0)"));
+               closelog ();
+               fprintf (stderr, _("Cannot change ID to root.\n"));
+               exit (1);
+       }
+       pwd_init ();
+
+       /*
+        * The passwd entry is now ready to be committed back to
+        * the password file. Get a lock on the file and open it.
+        */
+       if (pw_lock () == 0) {
+               SYSLOG ((LOG_WARN, "can't lock /etc/passwd"));
+               closelog ();
+               fprintf (stderr,
+                        _
+                        ("Cannot lock the password file; try again later.\n"));
+               exit (1);
+       }
+       if (pw_open (O_RDWR) == 0) {
+               SYSLOG ((LOG_ERR, "can't open /etc/passwd"));
+               closelog ();
+               fprintf (stderr, _("Cannot open the password file.\n"));
+               pw_unlock ();
+               exit (1);
+       }
+
+       /*
+        * Get the entry to update using pw_locate() - we want the real
+        * one from /etc/passwd, not the one from getpwnam() which could
+        * contain the shadow password if (despite the warnings) someone
+        * enables AUTOSHADOW (or SHADOW_COMPAT in libc).  --marekm
+        */
+       pw = pw_locate (user);
+       if (NULL == pw) {
+               pw_unlock ();
+               fprintf (stderr,
+                        _("%s: %s not found in /etc/passwd\n"), Prog, user);
+               exit (1);
+       }
+
+       /*
+        * Make a copy of the entry, then change the shell field. The other
+        * fields remain unchanged.
+        */
+       pwent = *pw;
+       pwent.pw_shell = loginsh;
+
+       /*
+        * Update the passwd file entry. If there is a DBM file, update
+        * that entry as well.
+        */
+       if (pw_update (&pwent) == 0) {
+               SYSLOG ((LOG_ERR, "error updating passwd entry"));
+               closelog ();
+               fprintf (stderr, _("Error updating the password entry.\n"));
+               pw_unlock ();
+               exit (1);
+       }
+
+       /*
+        * Changes have all been made, so commit them and unlock the file.
+        */
+       if (pw_close () == 0) {
+               SYSLOG ((LOG_ERR, "can't rewrite /etc/passwd"));
+               closelog ();
+               fprintf (stderr, _("Cannot commit password file changes.\n"));
+               pw_unlock ();
+               exit (1);
+       }
+       if (pw_unlock () == 0) {
+               SYSLOG ((LOG_ERR, "can't unlock /etc/passwd"));
+               closelog ();
+               fprintf (stderr, _("Cannot unlock the password file.\n"));
+               exit (1);
+       }
+}
+
 /*
  * chsh - this command controls changes to the user's shell
  *
@@ -321,7 +419,6 @@ int main (int argc, char **argv)
        char *user;             /* User name                         */
        int sflg = 0;           /* -s - set shell from command line  */
        const struct passwd *pw;        /* Password entry from /etc/passwd   */
-       struct passwd pwent;    /* New password entry                */
 
        sanitize_env ();
 
@@ -427,89 +524,8 @@ int main (int argc, char **argv)
                exit (1);
        }
 
-       /*
-        * Before going any further, raise the ulimit to prevent
-        * colliding into a lowered ulimit, and set the real UID
-        * to root to protect against unexpected signals. Any
-        * keyboard signals are set to be ignored.
-        */
-       if (setuid (0)) {
-               SYSLOG ((LOG_ERR, "can't setuid(0)"));
-               closelog ();
-               fprintf (stderr, _("Cannot change ID to root.\n"));
-               exit (1);
-       }
-       pwd_init ();
-
-       /*
-        * The passwd entry is now ready to be committed back to
-        * the password file. Get a lock on the file and open it.
-        */
-       if (!pw_lock ()) {
-               SYSLOG ((LOG_WARN, "can't lock /etc/passwd"));
-               closelog ();
-               fprintf (stderr,
-                        _
-                        ("Cannot lock the password file; try again later.\n"));
-               exit (1);
-       }
-       if (!pw_open (O_RDWR)) {
-               SYSLOG ((LOG_ERR, "can't open /etc/passwd"));
-               closelog ();
-               fprintf (stderr, _("Cannot open the password file.\n"));
-               pw_unlock ();
-               exit (1);
-       }
-
-       /*
-        * Get the entry to update using pw_locate() - we want the real
-        * one from /etc/passwd, not the one from getpwnam() which could
-        * contain the shadow password if (despite the warnings) someone
-        * enables AUTOSHADOW (or SHADOW_COMPAT in libc).  --marekm
-        */
-       pw = pw_locate (user);
-       if (!pw) {
-               pw_unlock ();
-               fprintf (stderr,
-                        _("%s: %s not found in /etc/passwd\n"), Prog, user);
-               exit (1);
-       }
-
-       /*
-        * Make a copy of the entry, then change the shell field. The other
-        * fields remain unchanged.
-        */
-       pwent = *pw;
-       pwent.pw_shell = loginsh;
-
-       /*
-        * Update the passwd file entry. If there is a DBM file, update
-        * that entry as well.
-        */
-       if (!pw_update (&pwent)) {
-               SYSLOG ((LOG_ERR, "error updating passwd entry"));
-               closelog ();
-               fprintf (stderr, _("Error updating the password entry.\n"));
-               pw_unlock ();
-               exit (1);
-       }
+       update_shell (user, loginsh);
 
-       /*
-        * Changes have all been made, so commit them and unlock the file.
-        */
-       if (!pw_close ()) {
-               SYSLOG ((LOG_ERR, "can't rewrite /etc/passwd"));
-               closelog ();
-               fprintf (stderr, _("Cannot commit password file changes.\n"));
-               pw_unlock ();
-               exit (1);
-       }
-       if (!pw_unlock ()) {
-               SYSLOG ((LOG_ERR, "can't unlock /etc/passwd"));
-               closelog ();
-               fprintf (stderr, _("Cannot unlock the password file.\n"));
-               exit (1);
-       }
        SYSLOG ((LOG_INFO, "changed user `%s' shell to `%s'", user, loginsh));
 
        nscd_flush_cache ("passwd");