New functions: process_flags(), check_flags(),

check_perms(). Split out of main().
This commit is contained in:
nekral-guest
2007-12-28 22:05:51 +00:00
parent dc1dccd9e2
commit 566b357f99
2 changed files with 124 additions and 93 deletions

View File

@ -2,6 +2,8 @@
* src/chpasswd.c: Before pam_end(), the return value of the previous * src/chpasswd.c: Before pam_end(), the return value of the previous
pam API was already checked. No need to validate it again. 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> 2007-12-28 Nicolas François <nicolas.francois@centraliens.net>

View File

@ -61,6 +61,9 @@ static int is_shadow_pwd;
/* local function prototypes */ /* local function prototypes */
static void usage (void); 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 * usage - display usage message and exit
@ -89,113 +92,100 @@ static void usage (void)
exit (E_USAGE); 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]; int option_index = 0;
char *name; int c;
char *newpwd; static struct option long_options[] = {
char *cp; {"crypt-method", required_argument, NULL, 'c'},
{"encrypted", no_argument, NULL, 'e'},
const struct spwd *sp; {"help", no_argument, NULL, 'h'},
struct spwd newsp; {"md5", no_argument, NULL, 'm'},
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'},
#ifdef USE_SHA_CRYPT #ifdef USE_SHA_CRYPT
{"sha-rounds", required_argument, NULL, 's'}, {"sha-rounds", required_argument, NULL, 's'},
#endif #endif
{NULL, 0, NULL, '\0'} {NULL, 0, NULL, '\0'}
}; };
while ((c = while ((c = getopt_long (argc, argv,
getopt_long (argc, argv,
#ifdef USE_SHA_CRYPT #ifdef USE_SHA_CRYPT
"c:ehms:", "c:ehms:",
#else #else
"c:ehm", "c:ehm",
#endif #endif
long_options, long_options, &option_index)) != -1) {
&option_index)) != -1) { switch (c) {
switch (c) { case 'c':
case 'c': cflg = 1;
cflg = 1; crypt_method = optarg;
crypt_method = optarg; break;
break; case 'e':
case 'e': eflg = 1;
eflg = 1; break;
break; case 'h':
case 'h': usage ();
usage (); break;
break; case 'm':
case 'm': md5flg = 1;
md5flg = 1; break;
break;
#ifdef USE_SHA_CRYPT #ifdef USE_SHA_CRYPT
case 's': case 's':
sflg = 1; sflg = 1;
if (!getlong(optarg, &sha_rounds)) { if (!getlong(optarg, &sha_rounds)) {
fprintf (stderr, fprintf (stderr,
_("%s: invalid numeric argument '%s'\n"), _("%s: invalid numeric argument '%s'\n"),
Prog, optarg); Prog, optarg);
usage ();
}
break;
#endif
case 0:
/* long option */
break;
default:
usage (); usage ();
break;
} }
break;
#endif
case 0:
/* long option */
break;
default:
usage ();
break;
} }
} }
/* validate options */ /* 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) { if (sflg && !cflg) {
fprintf (stderr, fprintf (stderr,
_("%s: %s flag is ONLY allowed with the %s flag\n"), _("%s: %s flag is ONLY allowed with the %s flag\n"),
Prog, "-s", "-c"); Prog, "-s", "-c");
usage (); usage ();
} }
if ((eflg && (md5flg || cflg)) || if ((eflg && (md5flg || cflg)) ||
(md5flg && cflg)) { (md5flg && cflg)) {
fprintf (stderr, fprintf (stderr,
_("%s: the -c, -e, and -m flags are exclusive\n"), _("%s: the -c, -e, and -m flags are exclusive\n"),
Prog); Prog);
usage (); usage ();
} }
if (cflg) { if (cflg) {
if ( 0 != strcmp (crypt_method, "DES") if ( (0 != strcmp (crypt_method, "DES"))
&& 0 != strcmp (crypt_method, "MD5") && (0 != strcmp (crypt_method, "MD5"))
&& 0 != strcmp (crypt_method, "NONE") && (0 != strcmp (crypt_method, "NONE"))
#ifdef USE_SHA_CRYPT #ifdef USE_SHA_CRYPT
&& 0 != strcmp (crypt_method, "SHA256") && (0 != strcmp (crypt_method, "SHA256"))
&& 0 != strcmp (crypt_method, "SHA512") && (0 != strcmp (crypt_method, "SHA512"))
#endif #endif
) { ) {
fprintf (stderr, fprintf (stderr,
@ -204,21 +194,32 @@ int main (int argc, char **argv)
usage (); 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 #ifdef USE_PAM
retval = PAM_SUCCESS; pam_handle_t *pamh = NULL;
int retval = PAM_SUCCESS;
{ struct passwd *pampw;
struct passwd *pampw; pampw = getpwuid (getuid ()); /* local, no need for xgetpwuid */
pampw = getpwuid (getuid ()); /* local, no need for xgetpwuid */ if (pampw == NULL) {
if (pampw == NULL) { retval = PAM_USER_UNKNOWN;
retval = PAM_USER_UNKNOWN; }
}
if (retval == PAM_SUCCESS) { if (retval == PAM_SUCCESS) {
retval = pam_start ("chpasswd", pampw->pw_name, retval = pam_start ("chpasswd", pampw->pw_name, &conv, &pamh);
&conv, &pamh);
}
} }
if (retval == PAM_SUCCESS) { if (retval == PAM_SUCCESS) {
@ -240,6 +241,34 @@ int main (int argc, char **argv)
exit (1); exit (1);
} }
#endif /* USE_PAM */ #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 * Lock the password file and open it for reading. This will bring