From: nekral-guest Date: Fri, 28 Dec 2007 22:05:51 +0000 (+0000) Subject: New functions: process_flags(), check_flags(), X-Git-Tag: 4.1.1~240 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=566b357f996e2ab52872fa1f86794b100dc20013;p=shadow New functions: process_flags(), check_flags(), check_perms(). Split out of main(). --- diff --git a/ChangeLog b/ChangeLog index c6cb89af..02889ae8 100644 --- 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 diff --git a/src/chpasswd.c b/src/chpasswd.c index bd7d41e7..4abc5dda 100644 --- a/src/chpasswd.c +++ b/src/chpasswd.c @@ -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