summaryrefslogtreecommitdiff
path: root/src/polkitbackend
diff options
context:
space:
mode:
authorNikki VonHollen <vonhollen@google.com>2011-12-20 15:11:23 -0800
committerDavid Zeuthen <davidz@redhat.com>2011-12-22 17:59:33 -0500
commit674357c20c1b6cb421fea6eb6924b274ec477c0e (patch)
treef434c0d7f0e0d5d932ce6e8b27fad31005b92d5f /src/polkitbackend
parent15d2e90a54009efb31300d8b59292d71ce98a5b2 (diff)
Bug 43610 - Add netgroup support
https://bugs.freedesktop.org/show_bug.cgi?id=43610 Added netgroup support and additional unit tests with MockLibc support. Signed-off-by: David Zeuthen <davidz@redhat.com>
Diffstat (limited to 'src/polkitbackend')
-rw-r--r--src/polkitbackend/polkitbackendlocalauthority.c63
-rw-r--r--src/polkitbackend/polkitbackendlocalauthorizationstore.c34
2 files changed, 93 insertions, 4 deletions
diff --git a/src/polkitbackend/polkitbackendlocalauthority.c b/src/polkitbackend/polkitbackendlocalauthority.c
index 0f3cd65..b53eda3 100644
--- a/src/polkitbackend/polkitbackendlocalauthority.c
+++ b/src/polkitbackend/polkitbackendlocalauthority.c
@@ -23,6 +23,7 @@
#include <errno.h>
#include <pwd.h>
#include <grp.h>
+#include <netdb.h>
#include <string.h>
#include <glib/gstdio.h>
#include <locale.h>
@@ -52,6 +53,9 @@
static GList *get_users_in_group (PolkitIdentity *group,
gboolean include_root);
+static GList *get_users_in_net_group (PolkitIdentity *group,
+ gboolean include_root);
+
static GList *get_groups_for_user (PolkitIdentity *user);
/* ---------------------------------------------------------------------------------------------------- */
@@ -507,6 +511,10 @@ polkit_backend_local_authority_get_admin_auth_identities (PolkitBackendInteracti
{
ret = g_list_concat (ret, get_users_in_group (identity, FALSE));
}
+ else if (POLKIT_IS_UNIX_NETGROUP (identity))
+ {
+ ret = g_list_concat (ret, get_users_in_net_group (identity, FALSE));
+ }
else
{
g_warning ("Unsupported identity %s", admin_identities[n]);
@@ -660,7 +668,7 @@ get_users_in_group (PolkitIdentity *group,
PolkitIdentity *user;
GError *error;
- if (!include_root && strcmp (grp->gr_mem[n], "root") == 0)
+ if (!include_root && g_strcmp0 (grp->gr_mem[n], "root") == 0)
continue;
error = NULL;
@@ -683,6 +691,59 @@ get_users_in_group (PolkitIdentity *group,
}
static GList *
+get_users_in_net_group (PolkitIdentity *group,
+ gboolean include_root)
+{
+ const gchar *name;
+ GList *ret;
+
+ ret = NULL;
+ name = polkit_unix_netgroup_get_name (POLKIT_UNIX_NETGROUP (group));
+
+ if (setnetgrent (name) == 0)
+ {
+ g_warning ("Error looking up net group with name %s: %s", name, g_strerror (errno));
+ goto out;
+ }
+
+ for (;;)
+ {
+ char *hostname, *username, *domainname;
+ PolkitIdentity *user;
+ GError *error = NULL;
+
+ if (getnetgrent (&hostname, &username, &domainname) == 0)
+ break;
+
+ /* Skip NULL entries since we never want to make everyone an admin
+ * Skip "-" entries which mean "no match ever" in netgroup land */
+ if (username == NULL || g_strcmp0 (username, "-") == 0)
+ continue;
+
+ /* TODO: Should we match on hostname? Maybe only allow "-" as a hostname
+ * for safety. */
+
+ user = polkit_unix_user_new_for_name (username, &error);
+ if (user == NULL)
+ {
+ g_warning ("Unknown username '%s' in unix-netgroup: %s", username, error->message);
+ g_error_free (error);
+ }
+ else
+ {
+ ret = g_list_prepend (ret, user);
+ }
+ }
+
+ ret = g_list_reverse (ret);
+
+ out:
+ endnetgrent ();
+ return ret;
+}
+
+
+static GList *
get_groups_for_user (PolkitIdentity *user)
{
uid_t uid;
diff --git a/src/polkitbackend/polkitbackendlocalauthorizationstore.c b/src/polkitbackend/polkitbackendlocalauthorizationstore.c
index d10121f..2ddfe75 100644
--- a/src/polkitbackend/polkitbackendlocalauthorizationstore.c
+++ b/src/polkitbackend/polkitbackendlocalauthorizationstore.c
@@ -21,6 +21,7 @@
#include "config.h"
+#include <netdb.h>
#include <string.h>
#include <polkit/polkit.h>
#include "polkitbackendlocalauthorizationstore.h"
@@ -74,7 +75,12 @@ typedef struct
{
gchar *id;
+ /* Identities with glob support */
GList *identity_specs;
+
+ /* Netgroup identity strings, which can not support glob syntax */
+ GList *netgroup_identities;
+
GList *action_specs;
PolkitImplicitAuthorization result_any;
@@ -90,6 +96,7 @@ local_authorization_free (LocalAuthorization *authorization)
g_free (authorization->id);
g_list_foreach (authorization->identity_specs, (GFunc) g_pattern_spec_free, NULL);
g_list_free (authorization->identity_specs);
+ g_list_free_full (authorization->netgroup_identities, g_free);
g_list_foreach (authorization->action_specs, (GFunc) g_pattern_spec_free, NULL);
g_list_free (authorization->action_specs);
if (authorization->return_value != NULL)
@@ -135,8 +142,13 @@ local_authorization_new (GKeyFile *key_file,
}
for (n = 0; identity_strings[n] != NULL; n++)
{
- authorization->identity_specs = g_list_prepend (authorization->identity_specs,
- g_pattern_spec_new (identity_strings[n]));
+ /* Put netgroup entries in a seperate list from other identities who support glob syntax */
+ if (g_str_has_prefix (identity_strings[n], "unix-netgroup:"))
+ authorization->netgroup_identities = g_list_prepend (authorization->netgroup_identities,
+ g_strdup (identity_strings[n] + sizeof "unix-netgroup:" - 1));
+ else
+ authorization->identity_specs = g_list_prepend (authorization->identity_specs,
+ g_pattern_spec_new (identity_strings[n]));
}
action_strings = g_key_file_get_string_list (key_file,
@@ -704,7 +716,7 @@ polkit_backend_local_authorization_store_lookup (PolkitBackendLocalAuthorization
if (ll == NULL)
continue;
- /* then match the identity */
+ /* then match the identity against identity specs */
if (identity_string == NULL)
identity_string = polkit_identity_to_string (identity);
for (ll = authorization->identity_specs; ll != NULL; ll = ll->next)
@@ -712,6 +724,22 @@ polkit_backend_local_authorization_store_lookup (PolkitBackendLocalAuthorization
if (g_pattern_match_string ((GPatternSpec *) ll->data, identity_string))
break;
}
+
+ /* if no identity specs matched and identity is a user, match against netgroups */
+ if (ll == NULL && POLKIT_IS_UNIX_USER (identity))
+ {
+ PolkitUnixUser *user_identity = POLKIT_UNIX_USER (identity);
+ const gchar *user_name = polkit_unix_user_get_name (user_identity);
+ if (!user_name)
+ continue;
+
+ for (ll = authorization->netgroup_identities; ll != NULL; ll = ll->next)
+ {
+ if (innetgr ((const gchar *) ll->data, NULL, user_name, NULL))
+ break;
+ }
+ }
+
if (ll == NULL)
continue;