aeac84
commit 3e70bc230962b3539d742ea1b886c5d63b303cd6
aeac84
Author: Tomas Halman <thalman@redhat.com>
aeac84
Date:   Fri Sep 23 14:08:21 2022 +0200
aeac84
aeac84
    Correct popt memory handling
aeac84
    
aeac84
    In the code of libusers we use popt library but we release popt context
aeac84
    too early. In older versions, popt leaked memory, so it worked anyway.
aeac84
    
aeac84
    With this patch poptFeeContext() call is moved to the end of main()
aeac84
    function.
aeac84
    
aeac84
    The patch also unifies the way utilities terminate in case of an error.
aeac84
    
aeac84
    Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2125904
aeac84
aeac84
diff --git a/apps/lchage.c b/apps/lchage.c
aeac84
index 1a4f048..3620e75 100644
aeac84
--- a/apps/lchage.c
aeac84
+++ b/apps/lchage.c
aeac84
@@ -71,13 +71,14 @@ main(int argc, const char **argv)
aeac84
 	long shadowMin = INVALID_LONG, shadowMax = INVALID_LONG,
aeac84
 	     shadowLastChange = INVALID_LONG, shadowInactive = INVALID_LONG,
aeac84
 	     shadowExpire = INVALID_LONG, shadowWarning = INVALID_LONG;
aeac84
-	const char *user;
aeac84
-	struct lu_context *ctx;
aeac84
-	struct lu_ent *ent;
aeac84
+	const char *user = NULL;
aeac84
+	struct lu_context *ctx = NULL;
aeac84
+	struct lu_ent *ent = NULL;
aeac84
 	struct lu_error *error = NULL;
aeac84
 	int interactive = FALSE;
aeac84
 	int list_only = FALSE;
aeac84
 	int c;
aeac84
+	int result;
aeac84
 
aeac84
 	poptContext popt;
aeac84
 	struct poptOption options[] = {
aeac84
@@ -118,7 +119,8 @@ main(int argc, const char **argv)
aeac84
 		fprintf(stderr, _("Error parsing arguments: %s.\n"),
aeac84
 			poptStrerror(c));
aeac84
 		poptPrintUsage(popt, stderr, 0);
aeac84
-		exit(1);
aeac84
+		result = 1;
aeac84
+		goto done;
aeac84
 	}
aeac84
 	user = poptGetArg(popt);
aeac84
 
aeac84
@@ -126,11 +128,10 @@ main(int argc, const char **argv)
aeac84
 	if (user == NULL) {
aeac84
 		fprintf(stderr, _("No user name specified.\n"));
aeac84
 		poptPrintUsage(popt, stderr, 0);
aeac84
-		return 1;
aeac84
+		result = 1;
aeac84
+		goto done;
aeac84
 	}
aeac84
 
aeac84
-	poptFreeContext(popt);
aeac84
-
aeac84
 	/* Start up the library. */
aeac84
 	ctx = lu_start(user, lu_user, NULL, NULL,
aeac84
 		       interactive ? lu_prompt_console :
aeac84
@@ -138,7 +139,8 @@ main(int argc, const char **argv)
aeac84
 	if (ctx == NULL) {
aeac84
 		fprintf(stderr, _("Error initializing %s: %s.\n"), PACKAGE,
aeac84
 			lu_strerror(error));
aeac84
-		return 1;
aeac84
+		result = 1;
aeac84
+		goto done;
aeac84
 	}
aeac84
 
aeac84
 	ent = lu_ent_new();
aeac84
@@ -146,7 +148,8 @@ main(int argc, const char **argv)
aeac84
 	/* Look up information about the user. */
aeac84
 	if (lu_user_lookup_name(ctx, user, ent, &error) == FALSE) {
aeac84
 		fprintf(stderr, _("User %s does not exist.\n"), user);
aeac84
-		return 2;
aeac84
+		result = 2;
aeac84
+		goto done;
aeac84
 	}
aeac84
 
aeac84
 	if (list_only) {
aeac84
@@ -242,7 +245,8 @@ main(int argc, const char **argv)
aeac84
 				  "%s\n"), user, lu_strerror(error));
aeac84
 			lu_audit_logger(AUDIT_USER_MGMT, "change-age", user,
aeac84
 				AUDIT_NO_ID, 0);
aeac84
-			return 3;
aeac84
+			result = 3;
aeac84
+			goto done;
aeac84
 		}
aeac84
 		lu_audit_logger(AUDIT_USER_MGMT, "change-age", user,
aeac84
 				AUDIT_NO_ID, 1);
aeac84
@@ -250,9 +254,14 @@ main(int argc, const char **argv)
aeac84
 		lu_nscd_flush_cache(LU_NSCD_CACHE_PASSWD);
aeac84
 	}
aeac84
 
aeac84
-	lu_ent_free(ent);
aeac84
+	result = 0;
aeac84
+
aeac84
+ done:
aeac84
+	if (ent) lu_ent_free(ent);
aeac84
 
aeac84
-	lu_end(ctx);
aeac84
+	if (ctx) lu_end(ctx);
aeac84
+
aeac84
+	poptFreeContext(popt);
aeac84
 
aeac84
-	return 0;
aeac84
+	return result;
aeac84
 }
aeac84
diff --git a/apps/lchfn.c b/apps/lchfn.c
aeac84
index 137f85f..dcc616f 100644
aeac84
--- a/apps/lchfn.c
aeac84
+++ b/apps/lchfn.c
aeac84
@@ -41,11 +41,12 @@ main(int argc, const char **argv)
aeac84
 {
aeac84
 	const char *user, *gecos;
aeac84
 	const char *name, *office, *officephone, *homephone;
aeac84
-	struct lu_context *ctx;
aeac84
+	struct lu_context *ctx = NULL;
aeac84
 	struct lu_error *error = NULL;
aeac84
-	struct lu_ent *ent;
aeac84
+	struct lu_ent *ent = NULL;
aeac84
 	int interactive = FALSE;
aeac84
 	int c;
aeac84
+	int result;
aeac84
 	struct lu_prompt prompts[7];
aeac84
 	poptContext popt;
aeac84
 	struct poptOption options[] = {
aeac84
@@ -53,7 +54,8 @@ main(int argc, const char **argv)
aeac84
 		 N_("prompt for all information"), NULL},
aeac84
 		POPT_AUTOHELP POPT_TABLEEND
aeac84
 	};
aeac84
-	char **fields, *p;
aeac84
+	char **fields = NULL;
aeac84
+	char *p;
aeac84
 	size_t fields_len;
aeac84
 	size_t pcount, i;
aeac84
 
aeac84
@@ -70,7 +72,8 @@ main(int argc, const char **argv)
aeac84
 		fprintf(stderr, _("Error parsing arguments: %s.\n"),
aeac84
 			poptStrerror(c));
aeac84
 		poptPrintUsage(popt, stderr, 0);
aeac84
-		exit(1);
aeac84
+		result = 1;
aeac84
+		goto done;
aeac84
 	}
aeac84
 	user = poptGetArg(popt);
aeac84
 
aeac84
@@ -86,11 +89,11 @@ main(int argc, const char **argv)
aeac84
 			fprintf(stderr, _("No user name specified, no name "
aeac84
 				"for uid %d.\n"), getuid());
aeac84
 			poptPrintUsage(popt, stderr, 0);
aeac84
-			exit(1);
aeac84
+			result = 1;
aeac84
+			goto done;
aeac84
 		}
aeac84
 	}
aeac84
 
aeac84
-	poptFreeContext(popt);
aeac84
 
aeac84
 	/* Give the user some idea of what's going on. */
aeac84
 	g_print(_("Changing finger information for %s.\n"), user);
aeac84
@@ -102,7 +105,8 @@ main(int argc, const char **argv)
aeac84
 	if (ctx == NULL) {
aeac84
 		fprintf(stderr, _("Error initializing %s: %s.\n"), PACKAGE,
aeac84
 			lu_strerror(error));
aeac84
-		return 1;
aeac84
+		result = 1;
aeac84
+		goto done;
aeac84
 	}
aeac84
 
aeac84
 	/* Authenticate the user to the "chfn" service. */
aeac84
@@ -112,7 +116,8 @@ main(int argc, const char **argv)
aeac84
 	ent = lu_ent_new();
aeac84
 	if (lu_user_lookup_name(ctx, user, ent, &error) == FALSE) {
aeac84
 		fprintf(stderr, _("User %s does not exist.\n"), user);
aeac84
-		exit(1);
aeac84
+		result = 1;
aeac84
+		goto done;
aeac84
 	}
aeac84
 
aeac84
 	/* Read the user's GECOS information. */
aeac84
@@ -206,7 +211,8 @@ main(int argc, const char **argv)
aeac84
 	if (lu_prompt_console(prompts, pcount, NULL, &error) == FALSE) {
aeac84
 		fprintf(stderr,
aeac84
 			_("Finger information not changed:  input error.\n"));
aeac84
-		exit(1);
aeac84
+		result = 1;
aeac84
+		goto done;
aeac84
 	}
aeac84
 
aeac84
 	/* Now iterate over the answers and figure things out. */
aeac84
@@ -272,14 +278,20 @@ main(int argc, const char **argv)
aeac84
 	} else {
aeac84
 		fprintf(stderr, _("Finger information not changed: %s.\n"),
aeac84
 			lu_strerror(error));
aeac84
-		return 1;
aeac84
+		result = 1;
aeac84
+		goto done;
aeac84
 	}
aeac84
 
aeac84
+	result = 0;
aeac84
+
aeac84
+ done:
aeac84
 	g_strfreev(fields);
aeac84
 
aeac84
-	lu_ent_free(ent);
aeac84
+	if (ent) lu_ent_free(ent);
aeac84
 
aeac84
-	lu_end(ctx);
aeac84
+	if (ctx) lu_end(ctx);
aeac84
+
aeac84
+	poptFreeContext(popt);
aeac84
 
aeac84
-	return 0;
aeac84
+	return result;
aeac84
 }
aeac84
diff --git a/apps/lchsh.c b/apps/lchsh.c
aeac84
index 555ed2e..58b2a34 100644
aeac84
--- a/apps/lchsh.c
aeac84
+++ b/apps/lchsh.c
aeac84
@@ -33,12 +33,13 @@ int
aeac84
 main(int argc, const char **argv)
aeac84
 {
aeac84
 	const char *user;
aeac84
-	struct lu_context *ctx;
aeac84
+	struct lu_context *ctx = NULL;
aeac84
 	struct lu_error *error = NULL;
aeac84
-	struct lu_ent *ent;
aeac84
+	struct lu_ent *ent = NULL;
aeac84
 	char *shell;
aeac84
 	int interactive = FALSE;
aeac84
 	int c;
aeac84
+	int result;
aeac84
 	poptContext popt;
aeac84
 	struct poptOption options[] = {
aeac84
 		{"interactive", 'i', POPT_ARG_NONE, &interactive, 0,
aeac84
@@ -59,7 +60,8 @@ main(int argc, const char **argv)
aeac84
 		fprintf(stderr, _("Error parsing arguments: %s.\n"),
aeac84
 			poptStrerror(c));
aeac84
 		poptPrintUsage(popt, stderr, 0);
aeac84
-		exit(1);
aeac84
+		result = 1;
aeac84
+		goto done;
aeac84
 	}
aeac84
 	user = poptGetArg(popt);
aeac84
 
aeac84
@@ -75,12 +77,11 @@ main(int argc, const char **argv)
aeac84
 			fprintf(stderr, _("No user name specified, no name for "
aeac84
 				"uid %d.\n"), getuid());
aeac84
 			poptPrintUsage(popt, stderr, 0);
aeac84
-			exit(1);
aeac84
+			result = 1;
aeac84
+			goto done;
aeac84
 		}
aeac84
 	}
aeac84
 
aeac84
-	poptFreeContext(popt);
aeac84
-
aeac84
 	/* Give the user some idea of what's going on. */
aeac84
 	g_print(_("Changing shell for %s.\n"), user);
aeac84
 
aeac84
@@ -91,7 +92,8 @@ main(int argc, const char **argv)
aeac84
 	if (ctx == NULL) {
aeac84
 		fprintf(stderr, _("Error initializing %s: %s.\n"), PACKAGE,
aeac84
 			lu_strerror(error));
aeac84
-		return 1;
aeac84
+		result = 1;
aeac84
+		goto done;
aeac84
 	}
aeac84
 
aeac84
 	/* Authenticate the user if we need to. */
aeac84
@@ -101,7 +103,8 @@ main(int argc, const char **argv)
aeac84
 	ent = lu_ent_new();
aeac84
 	if (lu_user_lookup_name(ctx, user, ent, &error) == FALSE) {
aeac84
 		fprintf(stderr, _("User %s does not exist.\n"), user);
aeac84
-		exit(1);
aeac84
+		result = 1;
aeac84
+		goto done;
aeac84
 	}
aeac84
 
aeac84
 	/* Read the user's shell. */
aeac84
@@ -123,7 +126,8 @@ main(int argc, const char **argv)
aeac84
 				lu_strerror(error));
aeac84
 			lu_audit_logger(AUDIT_USER_MGMT, "change-shell", user,
aeac84
 				AUDIT_NO_ID, 0);
aeac84
-			return 1;
aeac84
+			result = 1;
aeac84
+			goto done;
aeac84
 		}
aeac84
 		/* Modify the in-memory structure's shell attribute. */
aeac84
 		lu_ent_set_string(ent, LU_LOGINSHELL, prompts[0].value);
aeac84
@@ -142,13 +146,19 @@ main(int argc, const char **argv)
aeac84
 				lu_strerror(error));
aeac84
 			lu_audit_logger(AUDIT_USER_MGMT, "change-shell", user,
aeac84
 				AUDIT_NO_ID, 0);
aeac84
-			return 1;
aeac84
+			result = 1;
aeac84
+			goto done;
aeac84
 		}
aeac84
 	}
aeac84
 
aeac84
-	lu_ent_free(ent);
aeac84
+	result = 0;
aeac84
+
aeac84
+ done:
aeac84
+	if (ent) lu_ent_free(ent);
aeac84
 
aeac84
-	lu_end(ctx);
aeac84
+	if (ctx) lu_end(ctx);
aeac84
+
aeac84
+	poptFreeContext(popt);
aeac84
 
aeac84
-	return 0;
aeac84
+	return result;
aeac84
 }
aeac84
diff --git a/apps/lgroupadd.c b/apps/lgroupadd.c
aeac84
index 3fa2a1d..05bb1a5 100644
aeac84
--- a/apps/lgroupadd.c
aeac84
+++ b/apps/lgroupadd.c
aeac84
@@ -34,12 +34,13 @@ main(int argc, const char **argv)
aeac84
 {
aeac84
 	const char *name, *gid_number_str = NULL;
aeac84
 	gid_t gidNumber = LU_VALUE_INVALID_ID;
aeac84
-	struct lu_context *ctx;
aeac84
-	struct lu_ent *ent;
aeac84
+	struct lu_context *ctx = NULL;
aeac84
+	struct lu_ent *ent = NULL;
aeac84
 	struct lu_error *error = NULL;
aeac84
 	int interactive = FALSE;
aeac84
 	int system_account = FALSE;
aeac84
 	int c;
aeac84
+	int result;
aeac84
 
aeac84
 	poptContext popt;
aeac84
 	struct poptOption options[] = {
aeac84
@@ -65,7 +66,8 @@ main(int argc, const char **argv)
aeac84
 		fprintf(stderr, _("Error parsing arguments: %s.\n"),
aeac84
 			poptStrerror(c));
aeac84
 		poptPrintUsage(popt, stderr, 0);
aeac84
-		exit(1);
aeac84
+		result = 1;
aeac84
+		goto done;
aeac84
 	}
aeac84
 	name = poptGetArg(popt);
aeac84
 
aeac84
@@ -73,7 +75,8 @@ main(int argc, const char **argv)
aeac84
 	if (name == NULL) {
aeac84
 		fprintf(stderr, _("No group name specified.\n"));
aeac84
 		poptPrintUsage(popt, stderr, 0);
aeac84
-		return 1;
aeac84
+		result = 1;
aeac84
+		goto done;
aeac84
 	}
aeac84
 
aeac84
 	if (gid_number_str != NULL) {
aeac84
@@ -87,13 +90,12 @@ main(int argc, const char **argv)
aeac84
 			fprintf(stderr, _("Invalid group ID %s\n"),
aeac84
 				gid_number_str);
aeac84
 			poptPrintUsage(popt, stderr, 0);
aeac84
-			return 1;
aeac84
+			result = 1;
aeac84
+			goto done;
aeac84
 		}
aeac84
 		gidNumber = val;
aeac84
 	}
aeac84
 
aeac84
-	poptFreeContext(popt);
aeac84
-
aeac84
 	/* Start up the library. */
aeac84
 	ctx = lu_start(NULL, 0, NULL, NULL,
aeac84
 		       interactive ? lu_prompt_console :
aeac84
@@ -101,7 +103,8 @@ main(int argc, const char **argv)
aeac84
 	if (ctx == NULL) {
aeac84
 		fprintf(stderr, _("Error initializing %s: %s.\n"), PACKAGE,
aeac84
 			lu_strerror(error));
aeac84
-		return 1;
aeac84
+		result = 1;
aeac84
+		goto done;
aeac84
 	}
aeac84
 
aeac84
 	/* Create a group entity object holding sensible defaults for a
aeac84
@@ -120,17 +123,22 @@ main(int argc, const char **argv)
aeac84
 			lu_strerror(error));
aeac84
 		lu_audit_logger(AUDIT_ADD_GROUP, "add-group", name,
aeac84
 				AUDIT_NO_ID, 0);
aeac84
-		return 2;
aeac84
+		result = 2;
aeac84
+		goto done;
aeac84
 	}
aeac84
 
aeac84
 	lu_nscd_flush_cache(LU_NSCD_CACHE_GROUP);
aeac84
 
aeac84
-	lu_ent_free(ent);
aeac84
-
aeac84
-	lu_end(ctx);
aeac84
-
aeac84
 	lu_audit_logger(AUDIT_ADD_GROUP, "add-group", name,
aeac84
 				AUDIT_NO_ID, 1);
aeac84
+	result = 0;
aeac84
+
aeac84
+ done:
aeac84
+	if (ent) lu_ent_free(ent);
aeac84
+
aeac84
+	if (ctx) lu_end(ctx);
aeac84
+
aeac84
+	poptFreeContext(popt);
aeac84
 
aeac84
-	return 0;
aeac84
+	return result;
aeac84
 }
aeac84
diff --git a/apps/lgroupdel.c b/apps/lgroupdel.c
aeac84
index c5ccbed..f427924 100644
aeac84
--- a/apps/lgroupdel.c
aeac84
+++ b/apps/lgroupdel.c
aeac84
@@ -30,12 +30,13 @@
aeac84
 int
aeac84
 main(int argc, const char **argv)
aeac84
 {
aeac84
-	struct lu_context *ctx;
aeac84
-	struct lu_ent *ent;
aeac84
+	struct lu_context *ctx = NULL;
aeac84
+	struct lu_ent *ent = NULL;
aeac84
 	struct lu_error *error = NULL;
aeac84
 	const char *group;
aeac84
 	int interactive = FALSE;
aeac84
 	int c;
aeac84
+	int result;
aeac84
 
aeac84
 	poptContext popt;
aeac84
 	struct poptOption options[] = {
aeac84
@@ -57,7 +58,8 @@ main(int argc, const char **argv)
aeac84
 		fprintf(stderr, _("Error parsing arguments: %s.\n"),
aeac84
 			poptStrerror(c));
aeac84
 		poptPrintUsage(popt, stderr, 0);
aeac84
-		exit(1);
aeac84
+		result = 1;
aeac84
+		goto done;
aeac84
 	}
aeac84
 	group = poptGetArg(popt);
aeac84
 
aeac84
@@ -65,11 +67,10 @@ main(int argc, const char **argv)
aeac84
 	if (group == NULL) {
aeac84
 		fprintf(stderr, _("No group name specified.\n"));
aeac84
 		poptPrintUsage(popt, stderr, 0);
aeac84
-		return 1;
aeac84
+		result = 1;
aeac84
+		goto done;
aeac84
 	}
aeac84
 
aeac84
-	poptFreeContext(popt);
aeac84
-
aeac84
 	/* Start up the library. */
aeac84
 	ctx = lu_start(NULL, 0, NULL, NULL,
aeac84
 		       interactive ? lu_prompt_console :
aeac84
@@ -77,14 +78,16 @@ main(int argc, const char **argv)
aeac84
 	if (ctx == NULL) {
aeac84
 		fprintf(stderr, _("Error initializing %s: %s.\n"), PACKAGE,
aeac84
 			lu_strerror(error));
aeac84
-		return 1;
aeac84
+		result = 1;
aeac84
+		goto done;
aeac84
 	}
aeac84
 
aeac84
 	/* Look up the group structure. */
aeac84
 	ent = lu_ent_new();
aeac84
 	if (lu_group_lookup_name(ctx, group, ent, &error) == FALSE) {
aeac84
 		fprintf(stderr, _("Group %s does not exist.\n"), group);
aeac84
-		return 2;
aeac84
+		result = 2;
aeac84
+		goto done;
aeac84
 	}
aeac84
 
aeac84
 	/* Delete the group. */
aeac84
@@ -93,17 +96,22 @@ main(int argc, const char **argv)
aeac84
 			group, lu_strerror(error));
aeac84
 		lu_audit_logger(AUDIT_DEL_GROUP, "delete-group", group,
aeac84
 				AUDIT_NO_ID, 0);
aeac84
-		return 3;
aeac84
+		result = 3;
aeac84
+		goto done;
aeac84
 	}
aeac84
 
aeac84
 	lu_nscd_flush_cache(LU_NSCD_CACHE_GROUP);
aeac84
 
aeac84
-	lu_ent_free(ent);
aeac84
-
aeac84
-	lu_end(ctx);
aeac84
-
aeac84
 	lu_audit_logger(AUDIT_DEL_GROUP, "delete-group", group,
aeac84
 			AUDIT_NO_ID, 1);
aeac84
+	result = 0;
aeac84
+
aeac84
+ done:
aeac84
+	if (ent) lu_ent_free(ent);
aeac84
+
aeac84
+	if (ctx) lu_end(ctx);
aeac84
+
aeac84
+	poptFreeContext(popt);
aeac84
 
aeac84
-	return 0;
aeac84
+	return result;
aeac84
 }
aeac84
diff --git a/apps/lgroupmod.c b/apps/lgroupmod.c
aeac84
index 20be85f..8ade0ab 100644
aeac84
--- a/apps/lgroupmod.c
aeac84
+++ b/apps/lgroupmod.c
aeac84
@@ -39,14 +39,16 @@ main(int argc, const char **argv)
aeac84
 	char **admins, **members;
aeac84
 	gid_t gidNumber = LU_VALUE_INVALID_ID;
aeac84
 	gid_t oldGidNumber = LU_VALUE_INVALID_ID;
aeac84
-	struct lu_context *ctx;
aeac84
-	struct lu_ent *ent;
aeac84
+	struct lu_context *ctx = NULL;
aeac84
+	struct lu_ent *ent = NULL;
aeac84
+	struct lu_ent *user_ent;
aeac84
 	struct lu_error *error = NULL;
aeac84
 	GPtrArray *users = NULL;
aeac84
 	GValue val;
aeac84
 	int change = FALSE, lock = FALSE, unlock = FALSE;
aeac84
 	int interactive = FALSE;
aeac84
 	int c;
aeac84
+	int result;
aeac84
 
aeac84
 	poptContext popt;
aeac84
 	struct poptOption options[] = {
aeac84
@@ -85,14 +87,16 @@ main(int argc, const char **argv)
aeac84
 		fprintf(stderr, _("Error parsing arguments: %s.\n"),
aeac84
 			poptStrerror(c));
aeac84
 		poptPrintUsage(popt, stderr, 0);
aeac84
-		exit(1);
aeac84
+		result = 1;
aeac84
+		goto done;
aeac84
 	}
aeac84
 	group = poptGetArg(popt);
aeac84
 
aeac84
 	if (group == NULL) {
aeac84
 		fprintf(stderr, _("No group name specified.\n"));
aeac84
 		poptPrintUsage(popt, stderr, 0);
aeac84
-		return 1;
aeac84
+		result = 1;
aeac84
+		goto done;
aeac84
 	}
aeac84
 	if (gid_number_str != NULL) {
aeac84
 		intmax_t val;
aeac84
@@ -105,32 +109,34 @@ main(int argc, const char **argv)
aeac84
 			fprintf(stderr, _("Invalid group ID %s\n"),
aeac84
 				gid_number_str);
aeac84
 			poptPrintUsage(popt, stderr, 0);
aeac84
-			return 1;
aeac84
+			result = 1;
aeac84
+			goto done;
aeac84
 		}
aeac84
 		gidNumber = val;
aeac84
 	}
aeac84
 
aeac84
-	poptFreeContext(popt);
aeac84
-
aeac84
 	ctx = lu_start(NULL, 0, NULL, NULL,
aeac84
 		       interactive ? lu_prompt_console :
aeac84
 		       lu_prompt_console_quiet, NULL, &error);
aeac84
 	if (ctx == NULL) {
aeac84
 		fprintf(stderr, _("Error initializing %s: %s.\n"), PACKAGE,
aeac84
 			lu_strerror(error));
aeac84
-		return 1;
aeac84
+		result = 1;
aeac84
+		goto done;
aeac84
 	}
aeac84
 
aeac84
 	if (lock && unlock) {
aeac84
 		fprintf(stderr, _("Both -L and -U specified.\n"));
aeac84
-		return 2;
aeac84
+		result = 2;
aeac84
+		goto done;
aeac84
 	}
aeac84
 
aeac84
 	ent = lu_ent_new();
aeac84
 
aeac84
 	if (lu_group_lookup_name(ctx, group, ent, &error) == FALSE) {
aeac84
 		fprintf(stderr, _("Group %s does not exist.\n"), group);
aeac84
-		return 3;
aeac84
+		result = 3;
aeac84
+		goto done;
aeac84
 	}
aeac84
 
aeac84
 	if (userPassword) {
aeac84
@@ -141,7 +147,8 @@ main(int argc, const char **argv)
aeac84
 			lu_audit_logger(AUDIT_GRP_CHAUTHTOK,
aeac84
 					"changing-group-passwd", group,
aeac84
 					AUDIT_NO_ID, 0);
aeac84
-			return 4;
aeac84
+			result = 4;
aeac84
+			goto done;
aeac84
 		}
aeac84
 		lu_audit_logger(AUDIT_GRP_CHAUTHTOK,
aeac84
 				"changing-group-passwd", group,
aeac84
@@ -156,7 +163,8 @@ main(int argc, const char **argv)
aeac84
 			lu_audit_logger(AUDIT_GRP_CHAUTHTOK,
aeac84
 					"changing-group-passwd", group,
aeac84
 					AUDIT_NO_ID, 0);
aeac84
-			return 5;
aeac84
+			result = 5;
aeac84
+			goto done;
aeac84
 		}
aeac84
 		lu_audit_logger(AUDIT_GRP_CHAUTHTOK,
aeac84
 				"changing-group-passwd", group,
aeac84
@@ -171,7 +179,8 @@ main(int argc, const char **argv)
aeac84
 			lu_audit_logger(AUDIT_GRP_MGMT,
aeac84
 					"changing-group-lock", group,
aeac84
 					AUDIT_NO_ID, 0);
aeac84
-			return 6;
aeac84
+			result = 6;
aeac84
+			goto done;
aeac84
 		}
aeac84
 		lu_audit_logger(AUDIT_GRP_MGMT,
aeac84
 				"changing-group-lock", group,
aeac84
@@ -186,7 +195,8 @@ main(int argc, const char **argv)
aeac84
 			lu_audit_logger(AUDIT_GRP_MGMT,
aeac84
 					"changing-group-lock", group,
aeac84
 					AUDIT_NO_ID, 0);
aeac84
-			return 7;
aeac84
+			result = 7;
aeac84
+			goto done;
aeac84
 		}
aeac84
 		lu_audit_logger(AUDIT_GRP_MGMT,
aeac84
 				"changing-group-lock", group,
aeac84
@@ -268,7 +278,8 @@ main(int argc, const char **argv)
aeac84
 		lu_audit_logger(AUDIT_GRP_MGMT,
aeac84
 				"changing-group-members", group,
aeac84
 				AUDIT_NO_ID, 0);
aeac84
-		return 8;
aeac84
+		result = 8;
aeac84
+		goto done;
aeac84
 	}
aeac84
 	lu_audit_logger(AUDIT_GRP_MGMT,
aeac84
 			"changing-group-members", group,
aeac84
@@ -289,15 +300,14 @@ main(int argc, const char **argv)
aeac84
 			lu_audit_logger(AUDIT_GRP_MGMT,
aeac84
 				"changing-group-id", group,
aeac84
 				AUDIT_NO_ID, 0);
aeac84
-			return 8;
aeac84
+			result = 8;
aeac84
+			goto done;
aeac84
 		}
aeac84
 		lu_audit_logger(AUDIT_GRP_MGMT,
aeac84
 			"changing-group-id", group,
aeac84
 			AUDIT_NO_ID, 1);
aeac84
 	}
aeac84
 
aeac84
-	lu_ent_free(ent);
aeac84
-
aeac84
 	lu_nscd_flush_cache(LU_NSCD_CACHE_GROUP);
aeac84
 
aeac84
 	if (oldGidNumber != LU_VALUE_INVALID_ID &&
aeac84
@@ -305,22 +315,29 @@ main(int argc, const char **argv)
aeac84
 		size_t i;
aeac84
 
aeac84
 		for (i = 0; i < users->len; i++) {
aeac84
-			ent = g_ptr_array_index(users, i);
aeac84
-			if (lu_ent_get_first_id(ent, LU_GIDNUMBER)
aeac84
+			user_ent = g_ptr_array_index(users, i);
aeac84
+			if (lu_ent_get_first_id(user_ent, LU_GIDNUMBER)
aeac84
 			    == oldGidNumber) {
aeac84
-				lu_ent_set_id(ent, LU_GIDNUMBER, gidNumber);
aeac84
-				lu_user_modify(ctx, ent, &error);
aeac84
+				lu_ent_set_id(user_ent, LU_GIDNUMBER, gidNumber);
aeac84
+				lu_user_modify(ctx, user_ent, &error);
aeac84
 				if (error != NULL)
aeac84
 					lu_error_free(&error);
aeac84
 			}
aeac84
-			lu_ent_free(ent);
aeac84
+			lu_ent_free(user_ent);
aeac84
 		}
aeac84
 		g_ptr_array_free(users, TRUE);
aeac84
 
aeac84
 		lu_nscd_flush_cache(LU_NSCD_CACHE_PASSWD);
aeac84
 	}
aeac84
 
aeac84
-	lu_end(ctx);
aeac84
+	result = 0;
aeac84
+
aeac84
+ done:
aeac84
+	if (ent) lu_ent_free(ent);
aeac84
+
aeac84
+	if (ctx) lu_end(ctx);
aeac84
+
aeac84
+	poptFreeContext(popt);
aeac84
 
aeac84
-	return 0;
aeac84
+	return result;
aeac84
 }
aeac84
diff --git a/apps/lid.c b/apps/lid.c
aeac84
index 4b8afd9..cdcc122 100644
aeac84
--- a/apps/lid.c
aeac84
+++ b/apps/lid.c
aeac84
@@ -103,12 +103,13 @@ int
aeac84
 main(int argc, const char **argv)
aeac84
 {
aeac84
 	const char *name;
aeac84
-	struct lu_context *ctx;
aeac84
+	struct lu_context *ctx = NULL;
aeac84
 	struct lu_error *error = NULL;
aeac84
-	struct lu_ent *ent;
aeac84
+	struct lu_ent *ent = NULL;
aeac84
 	int interactive = FALSE;
aeac84
 	int groupflag = FALSE, nameonly = FALSE;
aeac84
 	int c;
aeac84
+	int result;
aeac84
 	poptContext popt;
aeac84
 	struct poptOption options[] = {
aeac84
 		{"interactive", 'i', POPT_ARG_NONE, &interactive, 0,
aeac84
@@ -133,7 +134,8 @@ main(int argc, const char **argv)
aeac84
 		fprintf(stderr, _("Error parsing arguments: %s.\n"),
aeac84
 			poptStrerror(c));
aeac84
 		poptPrintUsage(popt, stderr, 0);
aeac84
-		exit(1);
aeac84
+		result = 1;
aeac84
+		goto done;
aeac84
 	}
aeac84
 	name = poptGetArg(popt);
aeac84
 
aeac84
@@ -150,7 +152,8 @@ main(int argc, const char **argv)
aeac84
 				fprintf(stderr, _("No group name specified, "
aeac84
 					"no name for gid %d.\n"), getgid());
aeac84
 				poptPrintUsage(popt, stderr, 0);
aeac84
-				exit(1);
aeac84
+				result = 1;
aeac84
+				goto done;
aeac84
 			}
aeac84
 		} else {
aeac84
 			struct passwd *pwd;
aeac84
@@ -165,20 +168,20 @@ main(int argc, const char **argv)
aeac84
 					"no name for uid %d.\n"),
aeac84
 					getuid());
aeac84
 				poptPrintUsage(popt, stderr, 0);
aeac84
-				exit(1);
aeac84
+				result = 1;
aeac84
+				goto done;
aeac84
 			}
aeac84
 		}
aeac84
 	}
aeac84
 
aeac84
-	poptFreeContext(popt);
aeac84
-
aeac84
 	ctx = lu_start(name, groupflag ? lu_user : lu_group, NULL, NULL,
aeac84
 		       interactive ? lu_prompt_console :
aeac84
 		       lu_prompt_console_quiet, NULL, &error);
aeac84
 	if (ctx == NULL) {
aeac84
 		fprintf(stderr, _("Error initializing %s: %s.\n"), PACKAGE,
aeac84
 			lu_strerror(error));
aeac84
-		return 1;
aeac84
+		result = 1;
aeac84
+		goto done;
aeac84
 	}
aeac84
 
aeac84
 	ent = lu_ent_new();
aeac84
@@ -190,9 +193,9 @@ main(int argc, const char **argv)
aeac84
 			lu_error_free(&error);
aeac84
 		} else
aeac84
 			fprintf(stderr, _("%s does not exist\n"), name);
aeac84
-		return 1;
aeac84
+		result = 1;
aeac84
+		goto done;
aeac84
 	}
aeac84
-	lu_ent_free(ent);
aeac84
 
aeac84
 	if (nameonly)
aeac84
 		do_nameonly(ctx, name,
aeac84
@@ -207,7 +210,14 @@ main(int argc, const char **argv)
aeac84
 				LU_GROUPNAME, LU_GIDNUMBER, "gid");
aeac84
 	}
aeac84
 
aeac84
-	lu_end(ctx);
aeac84
+	result = 0;
aeac84
+
aeac84
+ done:
aeac84
+	if (ent) lu_ent_free(ent);
aeac84
+
aeac84
+	if (ctx) lu_end(ctx);
aeac84
+
aeac84
+	poptFreeContext(popt);
aeac84
 
aeac84
-	return 0;
aeac84
+	return result;
aeac84
 }
aeac84
diff --git a/apps/lnewusers.c b/apps/lnewusers.c
aeac84
index 1a5a5cb..6f9760a 100644
aeac84
--- a/apps/lnewusers.c
aeac84
+++ b/apps/lnewusers.c
aeac84
@@ -31,11 +31,13 @@
aeac84
 int
aeac84
 main(int argc, const char **argv)
aeac84
 {
aeac84
-	struct lu_context *ctx;
aeac84
+	struct lu_context *ctx = NULL;
aeac84
 	struct lu_error *error = NULL;
aeac84
-	struct lu_ent *ent, *groupEnt;
aeac84
+	struct lu_ent *ent = NULL;
aeac84
+	struct lu_ent *groupEnt = NULL;
aeac84
 	int interactive = FALSE, nocreatehome = FALSE, nocreatemail = FALSE;
aeac84
 	int c;
aeac84
+	int result;
aeac84
 	char *file = NULL;
aeac84
 	FILE *fp = stdin;
aeac84
 	char buf[LINE_MAX];
aeac84
@@ -66,11 +68,10 @@ main(int argc, const char **argv)
aeac84
 		fprintf(stderr, _("Error parsing arguments: %s.\n"),
aeac84
 			poptStrerror(c));
aeac84
 		poptPrintUsage(popt, stderr, 0);
aeac84
-		exit(1);
aeac84
+		result = 1;
aeac84
+		goto done;
aeac84
 	}
aeac84
 
aeac84
-	poptFreeContext(popt);
aeac84
-
aeac84
 	/* Start up the library. */
aeac84
 	ctx = lu_start(NULL, lu_user, NULL, NULL,
aeac84
 		       interactive ? lu_prompt_console :
aeac84
@@ -78,7 +79,8 @@ main(int argc, const char **argv)
aeac84
 	if (ctx == NULL) {
aeac84
 		fprintf(stderr, _("Error initializing %s: %s.\n"), PACKAGE,
aeac84
 			lu_strerror(error));
aeac84
-		return 1;
aeac84
+		result = 1;
aeac84
+		goto done;
aeac84
 	}
aeac84
 
aeac84
 	/* Open the file we're going to look at. */
aeac84
@@ -87,7 +89,8 @@ main(int argc, const char **argv)
aeac84
 		if (fp == NULL) {
aeac84
 			fprintf(stderr, _("Error opening `%s': %s.\n"),
aeac84
 				file, strerror(errno));
aeac84
-			return 2;
aeac84
+			result = 2;
aeac84
+			goto done;
aeac84
 		}
aeac84
 	} else {
aeac84
 		fp = stdin;
aeac84
@@ -305,10 +308,15 @@ main(int argc, const char **argv)
aeac84
 		lu_ent_clear_all(groupEnt);
aeac84
 	}
aeac84
 
aeac84
-	lu_ent_free(groupEnt);
aeac84
-	lu_ent_free(ent);
aeac84
+	result = 0;
aeac84
+
aeac84
+ done:
aeac84
+	if (groupEnt) lu_ent_free(groupEnt);
aeac84
+	if (ent) lu_ent_free(ent);
aeac84
 
aeac84
-	lu_end(ctx);
aeac84
+	if (ctx) lu_end(ctx);
aeac84
+
aeac84
+	poptFreeContext(popt);
aeac84
 
aeac84
-	return 0;
aeac84
+	return result;
aeac84
 }
aeac84
diff --git a/apps/lpasswd.c b/apps/lpasswd.c
aeac84
index 64f0b87..6218cab 100644
aeac84
--- a/apps/lpasswd.c
aeac84
+++ b/apps/lpasswd.c
aeac84
@@ -32,12 +32,13 @@
aeac84
 int
aeac84
 main(int argc, const char **argv)
aeac84
 {
aeac84
-	struct lu_context *ctx;
aeac84
-	struct lu_ent *ent;
aeac84
+	struct lu_context *ctx = NULL;
aeac84
+	struct lu_ent *ent = NULL;
aeac84
 	struct lu_error *error = NULL;
aeac84
 	char *password = NULL, *cryptedPassword = NULL;
aeac84
 	const char *user;
aeac84
 	int c;
aeac84
+	int result;
aeac84
 	int plain_fd = -1, crypted_fd = -1;
aeac84
 	int interactive = 0, groupflag = 0;
aeac84
 	poptContext popt;
aeac84
@@ -71,7 +72,8 @@ main(int argc, const char **argv)
aeac84
 		fprintf(stderr, _("Error parsing arguments: %s.\n"),
aeac84
 			poptStrerror(c));
aeac84
 		poptPrintUsage(popt, stderr, 0);
aeac84
-		exit(1);
aeac84
+		result = 1;
aeac84
+		goto done;
aeac84
 	}
aeac84
 	user = poptGetArg(popt);
aeac84
 
aeac84
@@ -84,19 +86,19 @@ main(int argc, const char **argv)
aeac84
 		} else {
aeac84
 			fprintf(stderr, _("No user name specified.\n"));
aeac84
 			poptPrintUsage(popt, stderr, 0);
aeac84
-			return 1;
aeac84
+			result = 1;
aeac84
+			goto done;
aeac84
 		}
aeac84
 	}
aeac84
 
aeac84
-	poptFreeContext(popt);
aeac84
-
aeac84
 	ctx = lu_start(user, groupflag ? lu_group : lu_user, NULL, NULL,
aeac84
 		       interactive ? lu_prompt_console :
aeac84
 		       lu_prompt_console_quiet, NULL, &error);
aeac84
 	if (ctx == NULL) {
aeac84
 		fprintf(stderr, _("Error initializing %s: %s.\n"), PACKAGE,
aeac84
 			lu_strerror(error));
aeac84
-		return 1;
aeac84
+		result = 1;
aeac84
+		goto done;
aeac84
 	}
aeac84
 
aeac84
 	lu_authenticate_unprivileged(ctx, user, "passwd");
aeac84
@@ -132,7 +134,8 @@ main(int argc, const char **argv)
aeac84
 				} else {
aeac84
 					fprintf(stderr, _("Password change "
aeac84
 						"canceled.\n"));
aeac84
-					return 1;
aeac84
+					result = 1;
aeac84
+					goto done;
aeac84
 				}
aeac84
 			}
aeac84
 			if (error) {
aeac84
@@ -146,12 +149,14 @@ main(int argc, const char **argv)
aeac84
 	if (!groupflag) {
aeac84
 		if (lu_user_lookup_name(ctx, user, ent, &error) == FALSE) {
aeac84
 			fprintf(stderr, _("User %s does not exist.\n"), user);
aeac84
-			return 2;
aeac84
+			result = 2;
aeac84
+			goto done;
aeac84
 		}
aeac84
 	} else {
aeac84
 		if (lu_group_lookup_name(ctx, user, ent, &error) == FALSE) {
aeac84
 			fprintf(stderr, _("Group %s does not exist.\n"), user);
aeac84
-			return 2;
aeac84
+			result = 2;
aeac84
+			goto done;
aeac84
 		}
aeac84
 	}
aeac84
 
aeac84
@@ -164,7 +169,8 @@ main(int argc, const char **argv)
aeac84
 			fprintf(stderr,
aeac84
 				_("Error reading from file descriptor %d.\n"),
aeac84
 				plain_fd);
aeac84
-			return 1;
aeac84
+			result = 1;
aeac84
+			goto done;
aeac84
 		}
aeac84
 		while ((i > 0) &&
aeac84
 		       ((buf[i - 1] == '\r') || (buf[i - 1] == '\n')))
aeac84
@@ -181,7 +187,8 @@ main(int argc, const char **argv)
aeac84
 			fprintf(stderr,
aeac84
 				_("Error reading from file descriptor %d.\n"),
aeac84
 				crypted_fd);
aeac84
-			return 1;
aeac84
+			result = 1;
aeac84
+			goto done;
aeac84
 		}
aeac84
 		while ((i > 0) &&
aeac84
 		       ((buf[i - 1] == '\r') || (buf[i - 1] == '\n')))
aeac84
@@ -203,7 +210,8 @@ main(int argc, const char **argv)
aeac84
 			fprintf(stderr, _("Error setting password for user "
aeac84
 					  "%s: %s.\n"), user,
aeac84
 				lu_strerror(error));
aeac84
-			return 3;
aeac84
+			result = 3;
aeac84
+			goto done;
aeac84
 		}
aeac84
 		lu_nscd_flush_cache(LU_NSCD_CACHE_PASSWD);
aeac84
 	} else {
aeac84
@@ -212,16 +220,21 @@ main(int argc, const char **argv)
aeac84
 			fprintf(stderr, _("Error setting password for group "
aeac84
 					  "%s: %s.\n"), user,
aeac84
 				lu_strerror(error));
aeac84
-			return 3;
aeac84
+			result = 3;
aeac84
+			goto done;
aeac84
 		}
aeac84
 		lu_nscd_flush_cache(LU_NSCD_CACHE_GROUP);
aeac84
 	}
aeac84
 
aeac84
-	lu_ent_free(ent);
aeac84
+	fprintf(stderr, _("Password changed.\n"));
aeac84
+	result = 0;
aeac84
+
aeac84
+ done:
aeac84
+	if (ent) lu_ent_free(ent);
aeac84
 
aeac84
-	lu_end(ctx);
aeac84
+	if (ctx) lu_end(ctx);
aeac84
 
aeac84
-	fprintf(stderr, _("Password changed.\n"));
aeac84
+	poptFreeContext(popt);
aeac84
 
aeac84
-	return 0;
aeac84
+	return result;
aeac84
 }
aeac84
diff --git a/apps/luseradd.c b/apps/luseradd.c
aeac84
index 9d7f4f1..96a5ade 100644
aeac84
--- a/apps/luseradd.c
aeac84
+++ b/apps/luseradd.c
aeac84
@@ -38,14 +38,16 @@ main(int argc, const char **argv)
aeac84
 		   *uid_number_str = NULL, *commonName = NULL,
aeac84
 		   *givenName = NULL, *surname = NULL, *roomNumber = NULL,
aeac84
 		   *telephoneNumber = NULL, *homePhone = NULL;
aeac84
-	struct lu_context *ctx;
aeac84
-	struct lu_ent *ent, *groupEnt;
aeac84
+	struct lu_context *ctx = NULL;
aeac84
+	struct lu_ent *ent = NULL;
aeac84
+	struct lu_ent *groupEnt = NULL;
aeac84
 	struct lu_error *error = NULL;
aeac84
 	uid_t uidNumber = LU_VALUE_INVALID_ID;
aeac84
 	gid_t gidNumber;
aeac84
 	int dont_create_group = FALSE, dont_create_home = FALSE,
aeac84
 	    system_account = FALSE, interactive = FALSE, create_group;
aeac84
 	int c;
aeac84
+	int result;
aeac84
 	intmax_t imax;
aeac84
 	char *p;
aeac84
 
aeac84
@@ -103,7 +105,8 @@ main(int argc, const char **argv)
aeac84
 		fprintf(stderr, _("Error parsing arguments: %s.\n"),
aeac84
 			poptStrerror(c));
aeac84
 		poptPrintUsage(popt, stderr, 0);
aeac84
-		exit(1);
aeac84
+		result = 1;
aeac84
+		goto done;
aeac84
 	}
aeac84
 
aeac84
 	/* Force certain flags one way or another. */
aeac84
@@ -117,7 +120,8 @@ main(int argc, const char **argv)
aeac84
 	if (name == NULL) {
aeac84
 		fprintf(stderr, _("No user name specified.\n"));
aeac84
 		poptPrintUsage(popt, stderr, 0);
aeac84
-		return 1;
aeac84
+		result = 1;
aeac84
+		goto done;
aeac84
 	}
aeac84
 	if (uid_number_str != NULL) {
aeac84
 		errno = 0;
aeac84
@@ -128,13 +132,12 @@ main(int argc, const char **argv)
aeac84
 			fprintf(stderr, _("Invalid user ID %s\n"),
aeac84
 				uid_number_str);
aeac84
 			poptPrintUsage(popt, stderr, 0);
aeac84
-			return 1;
aeac84
+			result = 1;
aeac84
+			goto done;
aeac84
 		}
aeac84
 		uidNumber = imax;
aeac84
 	}
aeac84
 
aeac84
-	poptFreeContext(popt);
aeac84
-
aeac84
 	/* Initialize the library. */
aeac84
 	ctx = lu_start(NULL, 0, NULL, NULL,
aeac84
 		       interactive ? lu_prompt_console :
aeac84
@@ -142,7 +145,8 @@ main(int argc, const char **argv)
aeac84
 	if (ctx == NULL) {
aeac84
 		fprintf(stderr, _("Error initializing %s: %s.\n"), PACKAGE,
aeac84
 			lu_strerror(error));
aeac84
-		return 1;
aeac84
+		result = 1;
aeac84
+		goto done;
aeac84
 	}
aeac84
 
aeac84
 	/* Select a group name for the user to be in. */
aeac84
@@ -163,7 +167,8 @@ main(int argc, const char **argv)
aeac84
 			if (gidNumber == LU_VALUE_INVALID_ID) {
aeac84
 				fprintf(stderr, _("Invalid group ID %s\n"),
aeac84
 					gid);
aeac84
-				return 1;
aeac84
+				result = 1;
aeac84
+				goto done;
aeac84
 			}
aeac84
 		} else
aeac84
 			/* It's not a number, so it's a group name. */
aeac84
@@ -188,7 +193,8 @@ main(int argc, const char **argv)
aeac84
 		} else {
aeac84
 			fprintf(stderr, _("Group %jd does not exist\n"),
aeac84
 				(intmax_t)gidNumber);
aeac84
-			return 1;
aeac84
+			result = 1;
aeac84
+			goto done;
aeac84
 		}
aeac84
 	}
aeac84
 
aeac84
@@ -209,10 +215,10 @@ main(int argc, const char **argv)
aeac84
 			if (error) {
aeac84
 				lu_error_free(&error);
aeac84
 			}
aeac84
-			lu_end(ctx);
aeac84
 			lu_audit_logger(AUDIT_ADD_GROUP, "add-group", name,
aeac84
 					AUDIT_NO_ID, 0);
aeac84
-			return 1;
aeac84
+			result = 1;
aeac84
+			goto done;
aeac84
 		}
aeac84
 		lu_audit_logger(AUDIT_ADD_GROUP, "add-group", name,
aeac84
 				AUDIT_NO_ID, 1);
aeac84
@@ -226,8 +232,8 @@ main(int argc, const char **argv)
aeac84
 		if (error) {
aeac84
 			lu_error_free(&error);
aeac84
 		}
aeac84
-		lu_end(ctx);
aeac84
-		return 1;
aeac84
+		result = 1;
aeac84
+		goto done;
aeac84
 	}
aeac84
 	g_assert(gidNumber != LU_VALUE_INVALID_ID);
aeac84
 
aeac84
@@ -266,7 +272,8 @@ main(int argc, const char **argv)
aeac84
 		lu_audit_logger(AUDIT_ADD_USER, "add-user", name,
aeac84
 					AUDIT_NO_ID, 0);
aeac84
 
aeac84
-		return 3;
aeac84
+		result = 3;
aeac84
+		goto done;
aeac84
 	}
aeac84
         lu_nscd_flush_cache(LU_NSCD_CACHE_PASSWD);
aeac84
 	lu_audit_logger(AUDIT_ADD_USER, "add-user", name, AUDIT_NO_ID, 1);
aeac84
@@ -292,7 +299,8 @@ main(int argc, const char **argv)
aeac84
 				homeDirectory, lu_strerror(error));
aeac84
 			lu_audit_logger(AUDIT_USER_MGMT, "add-home-dir", name,
aeac84
 				uidNumber, 0);
aeac84
-			return 7;
aeac84
+			result = 7;
aeac84
+			goto done;
aeac84
 		}
aeac84
 		lu_audit_logger(AUDIT_USER_MGMT, "add-home-dir", name,
aeac84
 				uidNumber, 1);
aeac84
@@ -301,7 +309,8 @@ main(int argc, const char **argv)
aeac84
 		if (lu_mail_spool_create(ctx, ent, &error) != TRUE) {
aeac84
 			fprintf(stderr, _("Error creating mail spool: %s\n"),
aeac84
 				lu_strerror(error));
aeac84
-			return 8;
aeac84
+			result = 8;
aeac84
+			goto done;
aeac84
 		}
aeac84
 	}
aeac84
 
aeac84
@@ -314,7 +323,8 @@ main(int argc, const char **argv)
aeac84
 			fprintf(stderr, _("Error setting password for user "
aeac84
 					  "%s: %s.\n"), name,
aeac84
 				lu_strerror(error));
aeac84
-			return 3;
aeac84
+			result = 3;
aeac84
+			goto done;
aeac84
 		}
aeac84
 	}
aeac84
 	if (cryptedUserPassword != NULL) {
aeac84
@@ -325,16 +335,22 @@ main(int argc, const char **argv)
aeac84
 				lu_strerror(error));
aeac84
 			lu_audit_logger(AUDIT_USER_CHAUTHTOK, "updating-password",
aeac84
 					name, uidNumber, 0);
aeac84
-			return 3;
aeac84
+			result = 3;
aeac84
+			goto done;
aeac84
 		}
aeac84
 		lu_audit_logger(AUDIT_USER_CHAUTHTOK, "updating-password",
aeac84
 					name, uidNumber, 1);
aeac84
 	}
aeac84
 	lu_nscd_flush_cache(LU_NSCD_CACHE_PASSWD);
aeac84
 
aeac84
-	lu_ent_free(ent);
aeac84
+	result = 0;
aeac84
+
aeac84
+ done:
aeac84
+	if (ent) lu_ent_free(ent);
aeac84
 
aeac84
-	lu_end(ctx);
aeac84
+	if (ctx) lu_end(ctx);
aeac84
+
aeac84
+	poptFreeContext(popt);
aeac84
 
aeac84
-	return 0;
aeac84
+	return result;
aeac84
 }
aeac84
diff --git a/apps/luserdel.c b/apps/luserdel.c
aeac84
index 7e20fa7..aab9d35 100644
aeac84
--- a/apps/luserdel.c
aeac84
+++ b/apps/luserdel.c
aeac84
@@ -32,13 +32,14 @@
aeac84
 int
aeac84
 main(int argc, const char **argv)
aeac84
 {
aeac84
-	struct lu_context *ctx;
aeac84
-	struct lu_ent *ent;
aeac84
+	struct lu_context *ctx = NULL;
aeac84
+	struct lu_ent *ent = NULL;
aeac84
 	struct lu_error *error = NULL;
aeac84
 	const char *user;
aeac84
 	int interactive = FALSE;
aeac84
 	int remove_home = 0, dont_remove_group = 0;
aeac84
 	int c;
aeac84
+	int result;
aeac84
 
aeac84
 	poptContext popt;
aeac84
 	struct poptOption options[] = {
aeac84
@@ -63,32 +64,34 @@ main(int argc, const char **argv)
aeac84
 		fprintf(stderr, _("Error parsing arguments: %s.\n"),
aeac84
 			poptStrerror(c));
aeac84
 		poptPrintUsage(popt, stderr, 0);
aeac84
-		exit(1);
aeac84
+		result = 1;
aeac84
+		goto done;
aeac84
 	}
aeac84
 	user = poptGetArg(popt);
aeac84
 
aeac84
 	if (user == NULL) {
aeac84
 		fprintf(stderr, _("No user name specified.\n"));
aeac84
 		poptPrintUsage(popt, stderr, 0);
aeac84
-		return 1;
aeac84
+		result = 1;
aeac84
+		goto done;
aeac84
 	}
aeac84
 
aeac84
-	poptFreeContext(popt);
aeac84
-
aeac84
 	ctx = lu_start(NULL, 0, NULL, NULL,
aeac84
 		       interactive ? lu_prompt_console :
aeac84
 		       lu_prompt_console_quiet, NULL, &error);
aeac84
 	if (ctx == NULL) {
aeac84
 		fprintf(stderr, _("Error initializing %s: %s.\n"), PACKAGE,
aeac84
 			lu_strerror(error));
aeac84
-		return 1;
aeac84
+		result = 1;
aeac84
+		goto done;
aeac84
 	}
aeac84
 
aeac84
 	ent = lu_ent_new();
aeac84
 
aeac84
 	if (lu_user_lookup_name(ctx, user, ent, &error) == FALSE) {
aeac84
 		fprintf(stderr, _("User %s does not exist.\n"), user);
aeac84
-		return 2;
aeac84
+		result = 2;
aeac84
+		goto done;
aeac84
 	}
aeac84
 
aeac84
 	if (lu_user_delete(ctx, ent, &error) == FALSE) {
aeac84
@@ -96,7 +99,8 @@ main(int argc, const char **argv)
aeac84
 			user, lu_strerror(error));
aeac84
 		lu_audit_logger(AUDIT_DEL_USER, "delete-user", user,
aeac84
 				AUDIT_NO_ID, 0);
aeac84
-		return 3;
aeac84
+		result = 3;
aeac84
+		goto done;
aeac84
 	}
aeac84
 	lu_audit_logger(AUDIT_DEL_USER, "delete-user", user,
aeac84
 			AUDIT_NO_ID, 1);
aeac84
@@ -112,19 +116,22 @@ main(int argc, const char **argv)
aeac84
 		if (gid == LU_VALUE_INVALID_ID) {
aeac84
 			fprintf(stderr, _("%s did not have a gid number.\n"),
aeac84
 				user);
aeac84
-			return 4;
aeac84
+			result = 4;
aeac84
+			goto done;
aeac84
 		}
aeac84
 		group_ent = lu_ent_new();
aeac84
 		if (lu_group_lookup_id(ctx, gid, group_ent, &error) == FALSE) {
aeac84
 			fprintf(stderr, _("No group with GID %jd exists, not "
aeac84
 					  "removing.\n"), (intmax_t)gid);
aeac84
-			return 5;
aeac84
+			result = 5;
aeac84
+			goto done;
aeac84
 		}
aeac84
 		tmp = lu_ent_get_first_string(group_ent, LU_GROUPNAME);
aeac84
 		if (tmp == NULL) {
aeac84
 			fprintf(stderr, _("Group with GID %jd did not have a "
aeac84
 					  "group name.\n"), (intmax_t)gid);
aeac84
-			return 6;
aeac84
+			result = 6;
aeac84
+			goto done;
aeac84
 		}
aeac84
 		if (strcmp(tmp, user) == 0) {
aeac84
 			if (lu_group_delete(ctx, group_ent, &error) == FALSE) {
aeac84
@@ -134,7 +141,8 @@ main(int argc, const char **argv)
aeac84
 				lu_audit_logger_with_group (AUDIT_DEL_GROUP,
aeac84
 					"delete-group", user, AUDIT_NO_ID,
aeac84
 					tmp, 0);
aeac84
-				return 7;
aeac84
+				result = 7;
aeac84
+				goto done;
aeac84
 			}
aeac84
 		}
aeac84
 		lu_audit_logger_with_group (AUDIT_DEL_GROUP,
aeac84
@@ -152,7 +160,8 @@ main(int argc, const char **argv)
aeac84
 			lu_audit_logger(AUDIT_USER_MGMT,
aeac84
 					"deleting-home-directory", user,
aeac84
 					AUDIT_NO_ID, 0);
aeac84
-			return 9;
aeac84
+			result = 9;
aeac84
+			goto done;
aeac84
 		}
aeac84
 		lu_audit_logger(AUDIT_USER_MGMT, "deleting-home-directory", user,
aeac84
 				AUDIT_NO_ID, 1);
aeac84
@@ -161,13 +170,19 @@ main(int argc, const char **argv)
aeac84
 		if (lu_mail_spool_remove(ctx, ent, &error) != TRUE) {
aeac84
 			fprintf(stderr, _("Error removing mail spool: %s"),
aeac84
 				lu_strerror(error));
aeac84
-			return 1;
aeac84
+			result = 1;
aeac84
+			goto done;
aeac84
 		}
aeac84
 	}
aeac84
 
aeac84
-	lu_ent_free(ent);
aeac84
+	result = 0;
aeac84
+
aeac84
+ done:
aeac84
+	if (ent) lu_ent_free(ent);
aeac84
 
aeac84
-	lu_end(ctx);
aeac84
+	if (ctx) lu_end(ctx);
aeac84
+
aeac84
+	poptFreeContext(popt);
aeac84
 
aeac84
-	return 0;
aeac84
+	return result;
aeac84
 }
aeac84
diff --git a/apps/lusermod.c b/apps/lusermod.c
aeac84
index 95cff85..3828796 100644
aeac84
--- a/apps/lusermod.c
aeac84
+++ b/apps/lusermod.c
aeac84
@@ -41,14 +41,15 @@ main(int argc, const char **argv)
aeac84
 	char *old_uid, *oldHomeDirectory;
aeac84
 	uid_t uidNumber = LU_VALUE_INVALID_ID;
aeac84
 	gid_t gidNumber = LU_VALUE_INVALID_ID;
aeac84
-	struct lu_context *ctx;
aeac84
-	struct lu_ent *ent;
aeac84
+	struct lu_context *ctx = NULL;
aeac84
+	struct lu_ent *ent = NULL;
aeac84
 	struct lu_error *error = NULL;
aeac84
 	GPtrArray *groups = NULL;
aeac84
 	GValue *value;
aeac84
 	int change, move_home = FALSE, lock = FALSE, unlock = FALSE;
aeac84
 	int interactive = FALSE;
aeac84
 	int c;
aeac84
+	int result;
aeac84
 
aeac84
 	poptContext popt;
aeac84
 	struct poptOption options[] = {
aeac84
@@ -104,7 +105,8 @@ main(int argc, const char **argv)
aeac84
 		fprintf(stderr, _("Error parsing arguments: %s.\n"),
aeac84
 			poptStrerror(c));
aeac84
 		poptPrintUsage(popt, stderr, 0);
aeac84
-		exit(1);
aeac84
+		result = 1;
aeac84
+		goto done;
aeac84
 	}
aeac84
 
aeac84
 	/* We need to have been passed a user name on the command-line.  We
aeac84
@@ -114,7 +116,8 @@ main(int argc, const char **argv)
aeac84
 	if (user == NULL) {
aeac84
 		fprintf(stderr, _("No user name specified.\n"));
aeac84
 		poptPrintUsage(popt, stderr, 0);
aeac84
-		return 1;
aeac84
+		result = 1;
aeac84
+		goto done;
aeac84
 	}
aeac84
 	if (gid_number_str != NULL) {
aeac84
 		intmax_t val;
aeac84
@@ -127,7 +130,8 @@ main(int argc, const char **argv)
aeac84
 			fprintf(stderr, _("Invalid group ID %s\n"),
aeac84
 				gid_number_str);
aeac84
 			poptPrintUsage(popt, stderr, 0);
aeac84
-			return 1;
aeac84
+			result = 1;
aeac84
+			goto done;
aeac84
 		}
aeac84
 		gidNumber = val;
aeac84
 	}
aeac84
@@ -142,13 +146,12 @@ main(int argc, const char **argv)
aeac84
 			fprintf(stderr, _("Invalid user ID %s\n"),
aeac84
 				uid_number_str);
aeac84
 			poptPrintUsage(popt, stderr, 0);
aeac84
-			return 1;
aeac84
+			result = 1;
aeac84
+			goto done;
aeac84
 		}
aeac84
 		uidNumber = val;
aeac84
 	}
aeac84
 
aeac84
-	poptFreeContext(popt);
aeac84
-
aeac84
 	/* Start up the library. */
aeac84
 	ctx = lu_start(NULL, 0, NULL, NULL,
aeac84
 		       interactive ? lu_prompt_console :
aeac84
@@ -156,20 +159,23 @@ main(int argc, const char **argv)
aeac84
 	if (ctx == NULL) {
aeac84
 		fprintf(stderr, _("Error initializing %s: %s.\n"), PACKAGE,
aeac84
 			lu_strerror(error));
aeac84
-		return 1;
aeac84
+		result = 1;
aeac84
+		goto done;
aeac84
 	}
aeac84
 
aeac84
 	/* Sanity-check arguments. */
aeac84
 	if (lock && unlock) {
aeac84
 		fprintf(stderr, _("Both -L and -U specified.\n"));
aeac84
-		return 2;
aeac84
+		result = 2;
aeac84
+		goto done;
aeac84
 	}
aeac84
 
aeac84
 	/* Look up the user's record. */
aeac84
 	ent = lu_ent_new();
aeac84
 	if (lu_user_lookup_name(ctx, user, ent, &error) == FALSE) {
aeac84
 		fprintf(stderr, _("User %s does not exist.\n"), user);
aeac84
-		return 3;
aeac84
+		result = 3;
aeac84
+		goto done;
aeac84
 	}
aeac84
 
aeac84
 	/* If the user's password needs to be changed, try to change it. */
aeac84
@@ -182,7 +188,8 @@ main(int argc, const char **argv)
aeac84
 			lu_audit_logger(AUDIT_USER_CHAUTHTOK,
aeac84
 					"updating-password", user,
aeac84
 					uidNumber, 0);
aeac84
-			return 5;
aeac84
+			result = 5;
aeac84
+			goto done;
aeac84
 		}
aeac84
 		lu_audit_logger(AUDIT_USER_CHAUTHTOK, "updating-password",
aeac84
 				user, uidNumber, 0);
aeac84
@@ -200,7 +207,8 @@ main(int argc, const char **argv)
aeac84
 			lu_audit_logger(AUDIT_USER_CHAUTHTOK,
aeac84
 					"updating-password", user,
aeac84
 					uidNumber, 0);
aeac84
-			return 6;
aeac84
+			result = 6;
aeac84
+			goto done;
aeac84
 		}
aeac84
 		lu_audit_logger(AUDIT_USER_CHAUTHTOK, "updating-password",
aeac84
 				user, uidNumber, 0);
aeac84
@@ -215,7 +223,8 @@ main(int argc, const char **argv)
aeac84
 			lu_audit_logger(AUDIT_USER_CHAUTHTOK,
aeac84
 					"locking-account", user,
aeac84
 					uidNumber, 0);
aeac84
-			return 7;
aeac84
+			result = 7;
aeac84
+			goto done;
aeac84
 		}
aeac84
 		lu_audit_logger(AUDIT_USER_CHAUTHTOK, "locking-account",
aeac84
 				user, uidNumber, 0);
aeac84
@@ -228,7 +237,8 @@ main(int argc, const char **argv)
aeac84
 			lu_audit_logger(AUDIT_USER_CHAUTHTOK,
aeac84
 					"unlocking-account", user,
aeac84
 					uidNumber, 0);
aeac84
-			return 8;
aeac84
+			result = 8;
aeac84
+			goto done;
aeac84
 		}
aeac84
 		lu_audit_logger(AUDIT_USER_CHAUTHTOK, "unlocking-account",
aeac84
 				user, uidNumber, 0);
aeac84
@@ -297,7 +307,8 @@ main(int argc, const char **argv)
aeac84
 			lu_audit_logger(AUDIT_USER_MGMT,
aeac84
 					"modify-account", user,
aeac84
 					uidNumber, 0);
aeac84
-		return 9;
aeac84
+		result = 9;
aeac84
+		goto done;
aeac84
 	}
aeac84
 	lu_audit_logger(AUDIT_USER_MGMT, "modify-account",
aeac84
 			user, uidNumber, 1);
aeac84
@@ -373,12 +384,14 @@ main(int argc, const char **argv)
aeac84
 		if (oldHomeDirectory == NULL) {
aeac84
 			fprintf(stderr, _("No old home directory for %s.\n"),
aeac84
 				user);
aeac84
-			return 10;
aeac84
+			result = 10;
aeac84
+			goto done;
aeac84
 		}
aeac84
 		if (homeDirectory == NULL) {
aeac84
 			fprintf(stderr, _("No new home directory for %s.\n"),
aeac84
 				user);
aeac84
-			return 11;
aeac84
+			result = 11;
aeac84
+			goto done;
aeac84
 		}
aeac84
 		if (lu_homedir_move(oldHomeDirectory, homeDirectory,
aeac84
 				    &error) == FALSE) {
aeac84
@@ -387,16 +400,22 @@ main(int argc, const char **argv)
aeac84
 				lu_strerror(error));
aeac84
 			lu_audit_logger(AUDIT_USER_MGMT, "moving-home-dir",
aeac84
 					user, uidNumber, 0);
aeac84
-			return 12;
aeac84
+			result = 12;
aeac84
+			goto done;
aeac84
 		}
aeac84
 		lu_audit_logger(AUDIT_USER_MGMT, "moving-home-dir",
aeac84
 				user, uidNumber, 1);
aeac84
 	}
aeac84
 	g_free(oldHomeDirectory);
aeac84
 
aeac84
-	lu_ent_free(ent);
aeac84
+	result = 0;
aeac84
+
aeac84
+ done:
aeac84
+	if (ent) lu_ent_free(ent);
aeac84
 
aeac84
-	lu_end(ctx);
aeac84
+	if (ctx) lu_end(ctx);
aeac84
+
aeac84
+	poptFreeContext(popt);
aeac84
 
aeac84
-	return 0;
aeac84
+	return result;
aeac84
 }