From 21aa2747e8f0048759aab184b07dd6389666d5e6 Mon Sep 17 00:00:00 2001
From: Khem Raj <raj.khem@gmail.com>
Date: Wed, 22 May 2019 13:18:55 -0700
Subject: [PATCH] make netgroup support optional

On at least Linux/musl and Linux/uclibc, netgroup
support is not available.  PolKit fails to compile on these systems
for that reason.

This change makes netgroup support conditional on the presence of the
setnetgrent(3) function which is required for the support to work.  If
that function is not available on the system, an error will be returned
to the administrator if unix-netgroup: is specified in configuration.

Fixes bug 50145.

Closes polkit/polkit#14.
Signed-off-by: A. Wilcox <AWilcox@Wilcox-Tech.com>
Signed-off-by: Khem Raj <raj.khem@gmail.com>
---
 configure.ac                                     |  2 +-
 src/polkit/polkitidentity.c                      | 16 ++++++++++++++++
 src/polkit/polkitunixnetgroup.c                  |  3 +++
 .../polkitbackendinteractiveauthority.c          | 14 ++++++++------
 src/polkitbackend/polkitbackendjsauthority.cpp   |  2 ++
 test/polkit/polkitidentitytest.c                 |  9 ++++++++-
 test/polkit/polkitunixnetgrouptest.c             |  3 +++
 .../test-polkitbackendjsauthority.c              |  2 ++
 8 files changed, 43 insertions(+), 8 deletions(-)

--- a/configure.ac
+++ b/configure.ac
@@ -99,7 +99,7 @@ AC_CHECK_LIB(expat,XML_ParserCreate,[EXP
 	     [AC_MSG_ERROR([Can't find expat library. Please install expat.])])
 AC_SUBST(EXPAT_LIBS)
 
-AC_CHECK_FUNCS(clearenv fdatasync)
+AC_CHECK_FUNCS(clearenv fdatasync setnetgrent)
 
 if test "x$GCC" = "xyes"; then
   LDFLAGS="-Wl,--as-needed $LDFLAGS"
--- a/src/polkit/polkitidentity.c
+++ b/src/polkit/polkitidentity.c
@@ -182,7 +182,15 @@ polkit_identity_from_string  (const gcha
     }
   else if (g_str_has_prefix (str, "unix-netgroup:"))
     {
+#ifndef HAVE_SETNETGRENT
+      g_set_error (error,
+                   POLKIT_ERROR,
+                   POLKIT_ERROR_FAILED,
+                   "Netgroups are not available on this machine ('%s')",
+                   str);
+#else
       identity = polkit_unix_netgroup_new (str + sizeof "unix-netgroup:" - 1);
+#endif
     }
 
   if (identity == NULL && (error != NULL && *error == NULL))
@@ -344,6 +352,13 @@ polkit_identity_new_for_gvariant (GVaria
       GVariant *v;
       const char *name;
 
+#ifndef HAVE_SETNETGRENT
+      g_set_error (error,
+                   POLKIT_ERROR,
+                   POLKIT_ERROR_FAILED,
+                   "Netgroups are not available on this machine");
+      goto out;
+#else
       v = lookup_asv (details_gvariant, "name", G_VARIANT_TYPE_STRING, error);
       if (v == NULL)
         {
@@ -353,6 +368,7 @@ polkit_identity_new_for_gvariant (GVaria
       name = g_variant_get_string (v, NULL);
       ret = polkit_unix_netgroup_new (name);
       g_variant_unref (v);
+#endif
     }
   else
     {
--- a/src/polkit/polkitunixnetgroup.c
+++ b/src/polkit/polkitunixnetgroup.c
@@ -194,6 +194,9 @@ polkit_unix_netgroup_set_name (PolkitUni
 PolkitIdentity *
 polkit_unix_netgroup_new (const gchar *name)
 {
+#ifndef HAVE_SETNETGRENT
+  g_assert_not_reached();
+#endif
   g_return_val_if_fail (name != NULL, NULL);
   return POLKIT_IDENTITY (g_object_new (POLKIT_TYPE_UNIX_NETGROUP,
                                        "name", name,
--- a/src/polkitbackend/polkitbackendinteractiveauthority.c
+++ b/src/polkitbackend/polkitbackendinteractiveauthority.c
@@ -2233,25 +2233,26 @@ get_users_in_net_group (PolkitIdentity
   GList *ret;
 
   ret = NULL;
+#ifdef HAVE_SETNETGRENT
   name = polkit_unix_netgroup_get_name (POLKIT_UNIX_NETGROUP (group));
 
-#ifdef HAVE_SETNETGRENT_RETURN
+# ifdef HAVE_SETNETGRENT_RETURN
   if (setnetgrent (name) == 0)
     {
       g_warning ("Error looking up net group with name %s: %s", name, g_strerror (errno));
       goto out;
     }
-#else
+# else
   setnetgrent (name);
-#endif
+# endif /* HAVE_SETNETGRENT_RETURN */
 
   for (;;)
     {
-#if defined(HAVE_NETBSD) || defined(HAVE_OPENBSD)
+# if defined(HAVE_NETBSD) || defined(HAVE_OPENBSD)
       const char *hostname, *username, *domainname;
-#else
+# else
       char *hostname, *username, *domainname;
-#endif
+# endif /* defined(HAVE_NETBSD) || defined(HAVE_OPENBSD) */
       PolkitIdentity *user;
       GError *error = NULL;
 
@@ -2282,6 +2283,7 @@ get_users_in_net_group (PolkitIdentity
 
  out:
   endnetgrent ();
+#endif /* HAVE_SETNETGRENT */
   return ret;
 }
 
--- a/src/polkitbackend/polkitbackendjsauthority.cpp
+++ b/src/polkitbackend/polkitbackendjsauthority.cpp
@@ -1502,6 +1502,7 @@ js_polkit_user_is_in_netgroup (JSContext
 
   JS::CallArgs args = JS::CallArgsFromVp (argc, vp);
 
+#ifdef HAVE_SETNETGRENT
   JS::RootedString usrstr (authority->priv->cx);
   usrstr = args[0].toString();
   user = JS_EncodeStringToUTF8 (cx, usrstr);
@@ -1519,6 +1520,7 @@ js_polkit_user_is_in_netgroup (JSContext
 
   JS_free (cx, netgroup);
   JS_free (cx, user);
+#endif
 
   ret = true;
 
--- a/test/polkit/polkitidentitytest.c
+++ b/test/polkit/polkitidentitytest.c
@@ -19,6 +19,7 @@
  * Author: Nikki VonHollen <vonhollen@google.com>
  */
 
+#include "config.h"
 #include "glib.h"
 #include <polkit/polkit.h>
 #include <polkit/polkitprivate.h>
@@ -145,11 +146,15 @@ struct ComparisonTestData comparison_tes
   {"unix-group:root", "unix-group:jane", FALSE},
   {"unix-group:jane", "unix-group:jane", TRUE},
 
+#ifdef HAVE_SETNETGRENT
   {"unix-netgroup:foo", "unix-netgroup:foo", TRUE},
   {"unix-netgroup:foo", "unix-netgroup:bar", FALSE},
+#endif
 
   {"unix-user:root", "unix-group:root", FALSE},
+#ifdef HAVE_SETNETGRENT
   {"unix-user:jane", "unix-netgroup:foo", FALSE},
+#endif
 
   {NULL},
 };
@@ -181,11 +186,13 @@ main (int argc, char *argv[])
   g_test_add_data_func ("/PolkitIdentity/group_string_2", "unix-group:jane", test_string);
   g_test_add_data_func ("/PolkitIdentity/group_string_3", "unix-group:users", test_string);
 
+#ifdef HAVE_SETNETGRENT
   g_test_add_data_func ("/PolkitIdentity/netgroup_string", "unix-netgroup:foo", test_string);
+  g_test_add_data_func ("/PolkitIdentity/netgroup_gvariant", "unix-netgroup:foo", test_gvariant);
+#endif
 
   g_test_add_data_func ("/PolkitIdentity/user_gvariant", "unix-user:root", test_gvariant);
   g_test_add_data_func ("/PolkitIdentity/group_gvariant", "unix-group:root", test_gvariant);
-  g_test_add_data_func ("/PolkitIdentity/netgroup_gvariant", "unix-netgroup:foo", test_gvariant);
 
   add_comparison_tests ();
 
--- a/test/polkit/polkitunixnetgrouptest.c
+++ b/test/polkit/polkitunixnetgrouptest.c
@@ -19,6 +19,7 @@
  * Author: Nikki VonHollen <vonhollen@google.com>
  */
 
+#include "config.h"
 #include "glib.h"
 #include <polkit/polkit.h>
 #include <string.h>
@@ -69,7 +70,9 @@ int
 main (int argc, char *argv[])
 {
   g_test_init (&argc, &argv, NULL);
+#ifdef HAVE_SETNETGRENT
   g_test_add_func ("/PolkitUnixNetgroup/new", test_new);
   g_test_add_func ("/PolkitUnixNetgroup/set_name", test_set_name);
+#endif
   return g_test_run ();
 }
--- a/test/polkitbackend/test-polkitbackendjsauthority.c
+++ b/test/polkitbackend/test-polkitbackendjsauthority.c
@@ -137,12 +137,14 @@ test_get_admin_identities (void)
         "unix-group:users"
       }
     },
+#ifdef HAVE_SETNETGRENT
     {
       "net.company.action3",
       {
         "unix-netgroup:foo"
       }
     },
+#endif
   };
   guint n;