Same changes as for chpasswd:

* src/chpasswd.c: main() split in process_flags(), check_flags(),
	check_perms(), open_files(), and close_files().
This commit is contained in:
nekral-guest 2007-12-28 22:54:35 +00:00
parent 8dc959ea1f
commit 28cd038c35
2 changed files with 163 additions and 107 deletions

View File

@ -1,3 +1,9 @@
2007-12-28 Nicolas François <nicolas.francois@centraliens.net>
Same changes for chgpasswd:
* src/chpasswd.c: main() split in process_flags(), check_flags(),
check_perms(), open_files(), and close_files().
2007-12-28 Nicolas François <nicolas.francois@centraliens.net> 2007-12-28 Nicolas François <nicolas.francois@centraliens.net>
* src/chpasswd.c: Before pam_end(), the return value of the previous * src/chpasswd.c: Before pam_end(), the return value of the previous

View File

@ -64,6 +64,11 @@ static int is_shadow_grp;
/* 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);
static void open_files (void);
static void close_files (void);
/* /*
* usage - display usage message and exit * usage - display usage message and exit
@ -92,36 +97,13 @@ static void usage (void)
exit (1); exit (1);
} }
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;
#ifdef SHADOWGRP
const struct sgrp *sg;
struct sgrp newsg;
#endif
const struct group *gr;
struct group newgr;
int errors = 0;
int line = 0;
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 option_index = 0;
int c; int c;
static struct option long_options[] = { static struct option long_options[] = {
@ -135,15 +117,13 @@ int main (int argc, char **argv)
{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;
@ -177,15 +157,25 @@ int main (int argc, char **argv)
break; 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 (void)
{
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,
@ -193,6 +183,7 @@ int main (int argc, char **argv)
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")
@ -208,11 +199,24 @@ 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) {
@ -220,9 +224,7 @@ int main (int argc, char **argv)
} }
if (retval == PAM_SUCCESS) { if (retval == PAM_SUCCESS) {
retval = pam_start ("chgpasswd", pampw->pw_name, retval = pam_start ("chgpasswd", pampw->pw_name, &conv, &pamh);
&conv, &pamh);
}
} }
if (retval == PAM_SUCCESS) { if (retval == PAM_SUCCESS) {
@ -244,10 +246,16 @@ int main (int argc, char **argv)
exit (1); exit (1);
} }
#endif /* USE_PAM */ #endif /* USE_PAM */
}
/*
* open_files - lock and open the group databases
*/
static void open_files (void)
{
/* /*
* Lock the group file and open it for reading. This will bring * Lock the group file and open it for reading and writing. This will
* all of the entries into memory where they may be updated. * bring all of the entries into memory where they may be updated.
*/ */
if (!gr_lock ()) { if (!gr_lock ()) {
fprintf (stderr, _("%s: can't lock group file\n"), Prog); fprintf (stderr, _("%s: can't lock group file\n"), Prog);
@ -258,8 +266,9 @@ int main (int argc, char **argv)
gr_unlock (); gr_unlock ();
exit (1); exit (1);
} }
#ifdef SHADOWGRP #ifdef SHADOWGRP
is_shadow_grp = sgr_file_present (); /* Do the same for the shadowed database, if it exist */
if (is_shadow_grp) { if (is_shadow_grp) {
if (!sgr_lock ()) { if (!sgr_lock ()) {
fprintf (stderr, _("%s: can't lock gshadow file\n"), fprintf (stderr, _("%s: can't lock gshadow file\n"),
@ -276,6 +285,63 @@ int main (int argc, char **argv)
} }
} }
#endif #endif
}
/*
* close_files - close and unlock the group databases
*/
static void close_files (void)
{
#ifdef SHADOWGRP
if (is_shadow_grp) {
if (!sgr_close ()) {
fprintf (stderr,
_("%s: error updating shadow file\n"), Prog);
gr_unlock ();
exit (1);
}
sgr_unlock ();
}
#endif
if (!gr_close ()) {
fprintf (stderr, _("%s: error updating password file\n"), Prog);
exit (1);
}
gr_unlock ();
}
int main (int argc, char **argv)
{
char buf[BUFSIZ];
char *name;
char *newpwd;
char *cp;
#ifdef SHADOWGRP
const struct sgrp *sg;
struct sgrp newsg;
#endif
const struct group *gr;
struct group newgr;
int errors = 0;
int line = 0;
int ok;
Prog = Basename (argv[0]);
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
process_flags(argc, argv);
check_perms ();
is_shadow_grp = sgr_file_present ();
open_files ();
/* /*
* Read each line, separating the group name from the password. The * Read each line, separating the group name from the password. The
@ -402,28 +468,12 @@ int main (int argc, char **argv)
gr_unlock (); gr_unlock ();
exit (1); exit (1);
} }
#ifdef SHADOWGRP
if (is_shadow_grp) { close_files ();
if (!sgr_close ()) {
fprintf (stderr,
_("%s: error updating shadow file\n"), Prog);
gr_unlock ();
exit (1);
}
sgr_unlock ();
}
#endif
if (!gr_close ()) {
fprintf (stderr, _("%s: error updating password file\n"), Prog);
exit (1);
}
nscd_flush_cache ("group"); nscd_flush_cache ("group");
gr_unlock ();
#ifdef USE_PAM #ifdef USE_PAM
if (retval == PAM_SUCCESS)
pam_end (pamh, PAM_SUCCESS); pam_end (pamh, PAM_SUCCESS);
#endif /* USE_PAM */ #endif /* USE_PAM */