]> granicus.if.org Git - shadow/commitdiff
New functions: process_flags(), check_flags(),
authornekral-guest <nekral-guest@5a98b0ae-9ef6-0310-add3-de5d479b70d7>
Fri, 28 Dec 2007 22:05:51 +0000 (22:05 +0000)
committernekral-guest <nekral-guest@5a98b0ae-9ef6-0310-add3-de5d479b70d7>
Fri, 28 Dec 2007 22:05:51 +0000 (22:05 +0000)
check_perms(). Split out of main().

ChangeLog
src/chpasswd.c

index c6cb89afb0f37d416824339c7931a5729a7a2342..02889ae84d65d4943e5c2977337f399f9727f702 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,8 @@
 
        * src/chpasswd.c: Before pam_end(), the return value of the previous
        pam API was already checked. No need to validate it again.
+       * src/chpasswd.c: New functions: process_flags(), check_flags(),
+       check_perms(). Split out of main().
 
 2007-12-28  Nicolas François  <nicolas.francois@centraliens.net>
 
index bd7d41e702cf1d6ee5cb3203993eefd9c14fa77a..4abc5ddae5c7845a21b694bd2c66505c3570488c 100644 (file)
@@ -61,6 +61,9 @@ static int is_shadow_pwd;
 
 /* local function prototypes */
 static void usage (void);
+static void process_flags (int argc, char **argv);
+static void check_flags (void);
+static void check_perms (void);
 
 /*
  * usage - display usage message and exit
@@ -89,113 +92,100 @@ static void usage (void)
        exit (E_USAGE);
 }
 
-int main (int argc, char **argv)
+/*
+ * process_flags - parse the command line options
+ *
+ *     It will not return if an error is encountered.
+ */
+static void process_flags (int argc, char **argv)
 {
-       char buf[BUFSIZ];
-       char *name;
-       char *newpwd;
-       char *cp;
-
-       const struct spwd *sp;
-       struct spwd newsp;
-
-       const struct passwd *pw;
-       struct passwd newpw;
-       int errors = 0;
-       int line = 0;
-       long now = time ((long *) 0) / (24L * 3600L);
-       int ok;
-
-#ifdef USE_PAM
-       pam_handle_t *pamh = NULL;
-       int retval;
-#endif
-
-       Prog = Basename (argv[0]);
-
-       setlocale (LC_ALL, "");
-       bindtextdomain (PACKAGE, LOCALEDIR);
-       textdomain (PACKAGE);
-
-       {
-               int option_index = 0;
-               int c;
-               static struct option long_options[] = {
-                       {"crypt-method", required_argument, NULL, 'c'},
-                       {"encrypted", no_argument, NULL, 'e'},
-                       {"help", no_argument, NULL, 'h'},
-                       {"md5", no_argument, NULL, 'm'},
+       int option_index = 0;
+       int c;
+       static struct option long_options[] = {
+               {"crypt-method", required_argument, NULL, 'c'},
+               {"encrypted", no_argument, NULL, 'e'},
+               {"help", no_argument, NULL, 'h'},
+               {"md5", no_argument, NULL, 'm'},
 #ifdef USE_SHA_CRYPT
-                       {"sha-rounds", required_argument, NULL, 's'},
+               {"sha-rounds", required_argument, NULL, 's'},
 #endif
-                       {NULL, 0, NULL, '\0'}
-               };
+               {NULL, 0, NULL, '\0'}
+       };
 
-               while ((c =
-                       getopt_long (argc, argv,
+       while ((c = getopt_long (argc, argv,
 #ifdef USE_SHA_CRYPT
-                                    "c:ehms:",
+                                "c:ehms:",
 #else
-                                    "c:ehm",
+                                "c:ehm",
 #endif
-                                    long_options,
-                                    &option_index)) != -1) {
-                       switch (c) {
-                       case 'c':
-                               cflg = 1;
-                               crypt_method = optarg;
-                               break;
-                       case 'e':
-                               eflg = 1;
-                               break;
-                       case 'h':
-                               usage ();
-                               break;
-                       case 'm':
-                               md5flg = 1;
-                               break;
+                                long_options, &option_index)) != -1) {
+               switch (c) {
+               case 'c':
+                       cflg = 1;
+                       crypt_method = optarg;
+                       break;
+               case 'e':
+                       eflg = 1;
+                       break;
+               case 'h':
+                       usage ();
+                       break;
+               case 'm':
+                       md5flg = 1;
+                       break;
 #ifdef USE_SHA_CRYPT
-                       case 's':
-                               sflg = 1;
-                               if (!getlong(optarg, &sha_rounds)) {
-                                       fprintf (stderr,
-                                                _("%s: invalid numeric argument '%s'\n"),
-                                                Prog, optarg);
-                                       usage ();
-                               }
-                               break;
-#endif
-                       case 0:
-                               /* long option */
-                               break;
-                       default:
+               case 's':
+                       sflg = 1;
+                       if (!getlong(optarg, &sha_rounds)) {
+                               fprintf (stderr,
+                                        _("%s: invalid numeric argument '%s'\n"),
+                                        Prog, optarg);
                                usage ();
-                               break;
                        }
+                       break;
+#endif
+               case 0:
+                       /* long option */
+                       break;
+               default:
+                       usage ();
+                       break;
                }
        }
 
        /* validate options */
+       check_flags ();
+}
+
+/*
+ * check_flags - check flags and parameters consistency
+ *
+ *     It will not return if an error is encountered.
+ */
+static void check_flags ()
+{
        if (sflg && !cflg) {
                fprintf (stderr,
-                        _("%s: %s flag is ONLY allowed with the %s flag\n"),
-                        Prog, "-s", "-c");
+                        _("%s: %s flag is ONLY allowed with the %s flag\n"),
+                        Prog, "-s", "-c");
                usage ();
        }
+
        if ((eflg && (md5flg || cflg)) ||
            (md5flg && cflg)) {
                fprintf (stderr,
-                        _("%s: the -c, -e, and -m flags are exclusive\n"),
-                        Prog);
+                        _("%s: the -c, -e, and -m flags are exclusive\n"),
+                        Prog);
                usage ();
        }
+
        if (cflg) {
-               if (   0 != strcmp (crypt_method, "DES")
-                   && 0 != strcmp (crypt_method, "MD5")
-                   && 0 != strcmp (crypt_method, "NONE")
+               if (   (0 != strcmp (crypt_method, "DES"))
+                   && (0 != strcmp (crypt_method, "MD5"))
+                   && (0 != strcmp (crypt_method, "NONE"))
 #ifdef USE_SHA_CRYPT
-                   && 0 != strcmp (crypt_method, "SHA256")
-                   && 0 != strcmp (crypt_method, "SHA512")
+                   && (0 != strcmp (crypt_method, "SHA256"))
+                   && (0 != strcmp (crypt_method, "SHA512"))
 #endif
                    ) {
                        fprintf (stderr,
@@ -204,21 +194,32 @@ int main (int argc, char **argv)
                        usage ();
                }
        }
+}
 
+/*
+ * check_perms - check if the caller is allowed to add a group
+ *
+ *     With PAM support, the setuid bit can be set on groupadd to allow
+ *     non-root users to groups.
+ *     Without PAM support, only users who can write in the group databases
+ *     can add groups.
+ *
+ *     It will not return if the user is not allowed.
+ */
+static void check_perms (void)
+{
 #ifdef USE_PAM
-       retval = PAM_SUCCESS;
+       pam_handle_t *pamh = NULL;
+       int retval = PAM_SUCCESS;
 
-       {
-               struct passwd *pampw;
-               pampw = getpwuid (getuid ()); /* local, no need for xgetpwuid */
-               if (pampw == NULL) {
-                       retval = PAM_USER_UNKNOWN;
-               }
+       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 ("chpasswd", pampw->pw_name,
-                                           &conv, &pamh);
-               }
+       if (retval == PAM_SUCCESS) {
+               retval = pam_start ("chpasswd", pampw->pw_name, &conv, &pamh);
        }
 
        if (retval == PAM_SUCCESS) {
@@ -240,6 +241,34 @@ int main (int argc, char **argv)
                exit (1);
        }
 #endif                         /* USE_PAM */
+}
+
+int main (int argc, char **argv)
+{
+       char buf[BUFSIZ];
+       char *name;
+       char *newpwd;
+       char *cp;
+
+       const struct spwd *sp;
+       struct spwd newsp;
+
+       const struct passwd *pw;
+       struct passwd newpw;
+       int errors = 0;
+       int line = 0;
+       long now = time ((long *) 0) / (24L * 3600L);
+       int ok;
+
+       Prog = Basename (argv[0]);
+
+       setlocale (LC_ALL, "");
+       bindtextdomain (PACKAGE, LOCALEDIR);
+       textdomain (PACKAGE);
+
+       process_flags (argc, argv);
+
+       check_perms ();
 
        /*
         * Lock the password file and open it for reading. This will bring