Make sure the group and gshadow files are unlocked on exit. Add function fail_exit().
This commit is contained in:
		| @@ -1,3 +1,8 @@ | |||||||
|  | 2008-03-08  Nicolas François  <nicolas.francois@centraliens.net> | ||||||
|  |  | ||||||
|  | 	* NEWS, src/gpasswd.c: Make sure the group and gshadow files are | ||||||
|  | 	unlocked on exit. Add function fail_exit(). | ||||||
|  |  | ||||||
| 2008-03-08  Nicolas François  <nicolas.francois@centraliens.net> | 2008-03-08  Nicolas François  <nicolas.francois@centraliens.net> | ||||||
|  |  | ||||||
| 	* NEWS, src/groupdel.c: Do not rewrite the group and gshadow file | 	* NEWS, src/groupdel.c: Do not rewrite the group and gshadow file | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								NEWS
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								NEWS
									
									
									
									
									
								
							| @@ -28,6 +28,7 @@ shadow-4.1.0 -> shadow-4.1.1						UNRELEASED | |||||||
|   * Fix failures when the gshadow file is not present. |   * Fix failures when the gshadow file is not present. | ||||||
|   * When a password is moved to the gshadow file, use "x" instead of "x" |   * When a password is moved to the gshadow file, use "x" instead of "x" | ||||||
|     to indicate that the password is shadowed (consistency with grpconv). |     to indicate that the password is shadowed (consistency with grpconv). | ||||||
|  |   * Make sure the group and gshadow files are unlocked on exit. | ||||||
| - groupadd | - groupadd | ||||||
|   * New option -p/--password to specify an encrypted password. |   * New option -p/--password to specify an encrypted password. | ||||||
|   * New option -r, --system for system accounts. |   * New option -r, --system for system accounts. | ||||||
|   | |||||||
| @@ -56,7 +56,9 @@ static char *Prog; | |||||||
| /* Indicate if shadow groups are enabled on the system | /* Indicate if shadow groups are enabled on the system | ||||||
|  * (/etc/gshadow present) */ |  * (/etc/gshadow present) */ | ||||||
| static int is_shadowgrp; | static int is_shadowgrp; | ||||||
|  | static int gshadow_locked = 0; | ||||||
| #endif | #endif | ||||||
|  | static int group_locked = 0; | ||||||
|  |  | ||||||
| /* Flags set by options */ | /* Flags set by options */ | ||||||
| static int | static int | ||||||
| @@ -86,6 +88,7 @@ static unsigned long bywho = -1; | |||||||
| /* local function prototypes */ | /* local function prototypes */ | ||||||
| static void usage (void); | static void usage (void); | ||||||
| static RETSIGTYPE catch_signals (int killed); | static RETSIGTYPE catch_signals (int killed); | ||||||
|  | static void fail_exit (int status); | ||||||
| static int check_list (const char *users); | static int check_list (const char *users); | ||||||
| static void process_flags (int argc, char **argv); | static void process_flags (int argc, char **argv); | ||||||
| static void check_flags (int argc, int opt_index); | static void check_flags (int argc, int opt_index); | ||||||
| @@ -141,10 +144,25 @@ static RETSIGTYPE catch_signals (int killed) | |||||||
| 	if (killed) { | 	if (killed) { | ||||||
| 		putchar ('\n'); | 		putchar ('\n'); | ||||||
| 		fflush (stdout); | 		fflush (stdout); | ||||||
| 		exit (killed); | 		fail_exit (killed); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /* | ||||||
|  |  * fail_exit - undo as much as possible | ||||||
|  |  */ | ||||||
|  | static void fail_exit (int status) | ||||||
|  | { | ||||||
|  | 	if (group_locked) { | ||||||
|  | 		gr_unlock (); | ||||||
|  | 	} | ||||||
|  | 	if (gshadow_locked) { | ||||||
|  | 		sgr_unlock (); | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	exit (status); | ||||||
|  | } | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * check_list - check a comma-separated list of user names for validity |  * check_list - check a comma-separated list of user names for validity | ||||||
|  * |  * | ||||||
| @@ -192,7 +210,7 @@ static int check_list (const char *users) | |||||||
| static void failure (void) | static void failure (void) | ||||||
| { | { | ||||||
| 	fprintf (stderr, _("%s: Permission denied.\n"), Prog); | 	fprintf (stderr, _("%s: Permission denied.\n"), Prog); | ||||||
| 	exit (1); | 	fail_exit (1); | ||||||
| } | } | ||||||
|  |  | ||||||
| /* | /* | ||||||
| @@ -215,7 +233,7 @@ static void process_flags (int argc, char **argv) | |||||||
| 				audit_logger (AUDIT_USER_CHAUTHTOK, Prog, | 				audit_logger (AUDIT_USER_CHAUTHTOK, Prog, | ||||||
| 					      "adding to group", user, -1, 0); | 					      "adding to group", user, -1, 0); | ||||||
| #endif | #endif | ||||||
| 				exit (1); | 				fail_exit (1); | ||||||
| 			} | 			} | ||||||
| 			aflg++; | 			aflg++; | ||||||
| 			break; | 			break; | ||||||
| @@ -234,11 +252,11 @@ static void process_flags (int argc, char **argv) | |||||||
| 					 _ | 					 _ | ||||||
| 					 ("%s: shadow group passwords required for -A\n"), | 					 ("%s: shadow group passwords required for -A\n"), | ||||||
| 					 Prog); | 					 Prog); | ||||||
| 				exit (2); | 				fail_exit (2); | ||||||
| 			} | 			} | ||||||
| 			admins = optarg; | 			admins = optarg; | ||||||
| 			if (check_list (admins) != 0) { | 			if (check_list (admins) != 0) { | ||||||
| 				exit (1); | 				fail_exit (1); | ||||||
| 			} | 			} | ||||||
| 			Aflg++; | 			Aflg++; | ||||||
| 			break; | 			break; | ||||||
| @@ -260,7 +278,7 @@ static void process_flags (int argc, char **argv) | |||||||
| 			} | 			} | ||||||
| 			members = optarg; | 			members = optarg; | ||||||
| 			if (check_list (members) != 0) { | 			if (check_list (members) != 0) { | ||||||
| 				exit (1); | 				fail_exit (1); | ||||||
| 			} | 			} | ||||||
| 			Mflg++; | 			Mflg++; | ||||||
| 			break; | 			break; | ||||||
| @@ -315,17 +333,22 @@ static void open_files (void) | |||||||
| 		audit_logger (AUDIT_USER_CHAUTHTOK, Prog, | 		audit_logger (AUDIT_USER_CHAUTHTOK, Prog, | ||||||
| 		              "locking /etc/group", group, -1, 0); | 		              "locking /etc/group", group, -1, 0); | ||||||
| #endif | #endif | ||||||
| 		exit (1); | 		fail_exit (1); | ||||||
| 	} | 	} | ||||||
|  | 	group_locked++; | ||||||
| #ifdef SHADOWGRP | #ifdef SHADOWGRP | ||||||
| 	if (is_shadowgrp && (sgr_lock () == 0)) { | 	if (is_shadowgrp) { | ||||||
| 		fprintf (stderr, _("%s: can't get shadow lock\n"), Prog); | 		if (sgr_lock () == 0) { | ||||||
| 		SYSLOG ((LOG_WARN, "failed to get lock for /etc/gshadow")); | 			fprintf (stderr, | ||||||
|  | 			         _("%s: can't get shadow lock\n"), Prog); | ||||||
|  | 			SYSLOG ((LOG_WARN, "failed to get lock for /etc/gshadow")); | ||||||
| #ifdef WITH_AUDIT | #ifdef WITH_AUDIT | ||||||
| 		audit_logger (AUDIT_USER_CHAUTHTOK, Prog, | 			audit_logger (AUDIT_USER_CHAUTHTOK, Prog, | ||||||
| 		              "locking /etc/gshadow", group, -1, 0); | 			              "locking /etc/gshadow", group, -1, 0); | ||||||
| #endif | #endif | ||||||
| 		exit (1); | 			fail_exit (1); | ||||||
|  | 		} | ||||||
|  | 		gshadow_locked++; | ||||||
| 	} | 	} | ||||||
| #endif | #endif | ||||||
| 	if (gr_open (O_RDWR) == 0) { | 	if (gr_open (O_RDWR) == 0) { | ||||||
| @@ -335,7 +358,7 @@ static void open_files (void) | |||||||
| 		audit_logger (AUDIT_USER_CHAUTHTOK, Prog, | 		audit_logger (AUDIT_USER_CHAUTHTOK, Prog, | ||||||
| 		              "opening /etc/group", group, -1, 0); | 		              "opening /etc/group", group, -1, 0); | ||||||
| #endif | #endif | ||||||
| 		exit (1); | 		fail_exit (1); | ||||||
| 	} | 	} | ||||||
| #ifdef SHADOWGRP | #ifdef SHADOWGRP | ||||||
| 	if (is_shadowgrp && (sgr_open (O_RDWR) == 0)) { | 	if (is_shadowgrp && (sgr_open (O_RDWR) == 0)) { | ||||||
| @@ -345,7 +368,7 @@ static void open_files (void) | |||||||
| 		audit_logger (AUDIT_USER_CHAUTHTOK, Prog, | 		audit_logger (AUDIT_USER_CHAUTHTOK, Prog, | ||||||
| 		              "opening /etc/gshadow", group, -1, 0); | 		              "opening /etc/gshadow", group, -1, 0); | ||||||
| #endif | #endif | ||||||
| 		exit (1); | 		fail_exit (1); | ||||||
| 	} | 	} | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| @@ -366,7 +389,7 @@ static void close_files (void) | |||||||
| 		audit_logger (AUDIT_USER_CHAUTHTOK, Prog, | 		audit_logger (AUDIT_USER_CHAUTHTOK, Prog, | ||||||
| 		              "rewriting /etc/group", group, -1, 0); | 		              "rewriting /etc/group", group, -1, 0); | ||||||
| #endif | #endif | ||||||
| 		exit (1); | 		fail_exit (1); | ||||||
| 	} | 	} | ||||||
| #ifdef SHADOWGRP | #ifdef SHADOWGRP | ||||||
| 	if (is_shadowgrp && (sgr_close () == 0)) { | 	if (is_shadowgrp && (sgr_close () == 0)) { | ||||||
| @@ -376,11 +399,12 @@ static void close_files (void) | |||||||
| 		audit_logger (AUDIT_USER_CHAUTHTOK, Prog, | 		audit_logger (AUDIT_USER_CHAUTHTOK, Prog, | ||||||
| 		              "rewriting /etc/gshadow", group, -1, 0); | 		              "rewriting /etc/gshadow", group, -1, 0); | ||||||
| #endif | #endif | ||||||
| 		exit (1); | 		fail_exit (1); | ||||||
| 	} | 	} | ||||||
| 	if (is_shadowgrp) { | 	if (is_shadowgrp) { | ||||||
| 		/* TODO: same logging as in open_files & for /etc/group */ | 		/* TODO: same logging as in open_files & for /etc/group */ | ||||||
| 		sgr_unlock (); | 		sgr_unlock (); | ||||||
|  | 		gshadow_locked--; | ||||||
| 	} | 	} | ||||||
| #endif | #endif | ||||||
| 	if (gr_unlock () == 0) { | 	if (gr_unlock () == 0) { | ||||||
| @@ -391,6 +415,7 @@ static void close_files (void) | |||||||
| #endif | #endif | ||||||
| 		exit (1); | 		exit (1); | ||||||
| 	} | 	} | ||||||
|  | 	group_locked--; | ||||||
| } | } | ||||||
|  |  | ||||||
| /* | /* | ||||||
| @@ -484,7 +509,7 @@ static void update_group (struct group *gr) | |||||||
| 		audit_logger (AUDIT_USER_CHAUTHTOK, Prog, | 		audit_logger (AUDIT_USER_CHAUTHTOK, Prog, | ||||||
| 		              "updating /etc/group", group, -1, 0); | 		              "updating /etc/group", group, -1, 0); | ||||||
| #endif | #endif | ||||||
| 		exit (1); | 		fail_exit (1); | ||||||
| 	} | 	} | ||||||
| #ifdef SHADOWGRP | #ifdef SHADOWGRP | ||||||
| 	if (is_shadowgrp && (sgr_update (sg) == 0)) { | 	if (is_shadowgrp && (sgr_update (sg) == 0)) { | ||||||
| @@ -494,7 +519,7 @@ static void update_group (struct group *gr) | |||||||
| 		audit_logger (AUDIT_USER_CHAUTHTOK, Prog, | 		audit_logger (AUDIT_USER_CHAUTHTOK, Prog, | ||||||
| 		              "updating /etc/gshadow", group, -1, 0); | 		              "updating /etc/gshadow", group, -1, 0); | ||||||
| #endif | #endif | ||||||
| 		exit (1); | 		fail_exit (1); | ||||||
| 	} | 	} | ||||||
| #endif | #endif | ||||||
| } | } | ||||||
| @@ -523,7 +548,7 @@ static void get_group (struct group *gr) | |||||||
| 		audit_logger (AUDIT_USER_CHAUTHTOK, Prog, | 		audit_logger (AUDIT_USER_CHAUTHTOK, Prog, | ||||||
| 		              "opening /etc/group", group, -1, 0); | 		              "opening /etc/group", group, -1, 0); | ||||||
| #endif | #endif | ||||||
| 		exit (1); | 		fail_exit (1); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	tmpgr = gr_locate (group); | 	tmpgr = gr_locate (group); | ||||||
| @@ -548,7 +573,7 @@ static void get_group (struct group *gr) | |||||||
| 		audit_logger (AUDIT_USER_CHAUTHTOK, Prog, | 		audit_logger (AUDIT_USER_CHAUTHTOK, Prog, | ||||||
| 		              "closing /etc/group", group, -1, 0); | 		              "closing /etc/group", group, -1, 0); | ||||||
| #endif | #endif | ||||||
| 		exit (1); | 		fail_exit (1); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| #ifdef SHADOWGRP | #ifdef SHADOWGRP | ||||||
| @@ -561,7 +586,7 @@ static void get_group (struct group *gr) | |||||||
| 			audit_logger (AUDIT_USER_CHAUTHTOK, Prog, | 			audit_logger (AUDIT_USER_CHAUTHTOK, Prog, | ||||||
| 			              "opening /etc/gshadow", group, -1, 0); | 			              "opening /etc/gshadow", group, -1, 0); | ||||||
| #endif | #endif | ||||||
| 			exit (1); | 			fail_exit (1); | ||||||
| 		} | 		} | ||||||
| 		tmpsg = sgr_locate (group); | 		tmpsg = sgr_locate (group); | ||||||
| 		if (NULL != tmpsg) { | 		if (NULL != tmpsg) { | ||||||
| @@ -598,7 +623,7 @@ static void get_group (struct group *gr) | |||||||
| 			audit_logger (AUDIT_USER_CHAUTHTOK, Prog, | 			audit_logger (AUDIT_USER_CHAUTHTOK, Prog, | ||||||
| 			              "closing /etc/gshadow", group, -1, 0); | 			              "closing /etc/gshadow", group, -1, 0); | ||||||
| #endif | #endif | ||||||
| 			exit (1); | 			fail_exit (1); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| #endif				/* SHADOWGRP */ | #endif				/* SHADOWGRP */ | ||||||
| @@ -633,14 +658,14 @@ static void change_passwd (struct group *gr) | |||||||
| 	for (retries = 0; retries < RETRIES; retries++) { | 	for (retries = 0; retries < RETRIES; retries++) { | ||||||
| 		cp = getpass (_("New Password: ")); | 		cp = getpass (_("New Password: ")); | ||||||
| 		if (NULL == cp) { | 		if (NULL == cp) { | ||||||
| 			exit (1); | 			fail_exit (1); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		STRFCPY (pass, cp); | 		STRFCPY (pass, cp); | ||||||
| 		strzero (cp); | 		strzero (cp); | ||||||
| 		cp = getpass (_("Re-enter new password: ")); | 		cp = getpass (_("Re-enter new password: ")); | ||||||
| 		if (NULL == cp) { | 		if (NULL == cp) { | ||||||
| 			exit (1); | 			fail_exit (1); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		if (strcmp (pass, cp) == 0) { | 		if (strcmp (pass, cp) == 0) { | ||||||
| @@ -662,7 +687,7 @@ static void change_passwd (struct group *gr) | |||||||
|  |  | ||||||
| 	if (retries == RETRIES) { | 	if (retries == RETRIES) { | ||||||
| 		fprintf (stderr, _("%s: Try again later\n"), Prog); | 		fprintf (stderr, _("%s: Try again later\n"), Prog); | ||||||
| 		exit (1); | 		fail_exit (1); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	cp = pw_encrypt (pass, crypt_make_salt (NULL, NULL)); | 	cp = pw_encrypt (pass, crypt_make_salt (NULL, NULL)); | ||||||
| @@ -850,7 +875,7 @@ int main (int argc, char **argv) | |||||||
| 			audit_logger (AUDIT_USER_CHAUTHTOK, Prog, | 			audit_logger (AUDIT_USER_CHAUTHTOK, Prog, | ||||||
| 			              "deleting member", user, -1, 0); | 			              "deleting member", user, -1, 0); | ||||||
| #endif | #endif | ||||||
| 			exit (1); | 			fail_exit (1); | ||||||
| 		} | 		} | ||||||
| #ifdef WITH_AUDIT | #ifdef WITH_AUDIT | ||||||
| 		audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "deleting member", | 		audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "deleting member", | ||||||
| @@ -909,7 +934,7 @@ int main (int argc, char **argv) | |||||||
| 		audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "changing password", | 		audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "changing password", | ||||||
| 		              group, -1, 0); | 		              group, -1, 0); | ||||||
| #endif | #endif | ||||||
| 		exit (1); | 		fail_exit (1); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	catch_signals (0);	/* save tty modes */ | 	catch_signals (0);	/* save tty modes */ | ||||||
| @@ -944,7 +969,7 @@ int main (int argc, char **argv) | |||||||
| 		              group, -1, 0); | 		              group, -1, 0); | ||||||
| #endif | #endif | ||||||
| 		closelog (); | 		closelog (); | ||||||
| 		exit (1); | 		fail_exit (1); | ||||||
| 	} | 	} | ||||||
| 	pwd_init (); | 	pwd_init (); | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user