diff options
author | Nikki VonHollen <vonhollen@google.com> | 2011-12-20 15:11:23 -0800 |
---|---|---|
committer | David Zeuthen <davidz@redhat.com> | 2011-12-22 17:59:33 -0500 |
commit | 674357c20c1b6cb421fea6eb6924b274ec477c0e (patch) | |
tree | f434c0d7f0e0d5d932ce6e8b27fad31005b92d5f /src/polkitbackend | |
parent | 15d2e90a54009efb31300d8b59292d71ce98a5b2 (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.c | 63 | ||||
-rw-r--r-- | src/polkitbackend/polkitbackendlocalauthorizationstore.c | 34 |
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; |