Blame SOURCES/0002-popt-memopy.patch

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