~ubuntu-branches/ubuntu/trusty/policykit-1/trusty

« back to all changes in this revision

Viewing changes to src/polkitbackend/polkitbackendlocalauthority.c

  • Committer: Package Import Robot
  • Author(s): Martin Pitt
  • Date: 2012-01-06 12:28:54 UTC
  • mfrom: (1.1.9)
  • Revision ID: package-import@ubuntu.com-20120106122854-ib9s0ej8akqiy0lb
Tags: 0.104-1
* New upstream release.
  - Add support for netgroups. (LP: #724052)
* debian/rules: Disable systemd support, continue to work with ConsokeKit.
* 05_revert-admin-identities-unix-group-wheel.patch: Refresh to apply
  cleanly.
* debian/libpolkit-gobject-1-0.symbols: Add new symbols from this new
  release.
* debian/rules: Do not let test failures fail the build. The new test suite
  also runs a test against the system D-BUS/ConsoleKit, which can't work on
  buildds.

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
#include <errno.h>
24
24
#include <pwd.h>
25
25
#include <grp.h>
 
26
#include <netdb.h>
26
27
#include <string.h>
27
28
#include <glib/gstdio.h>
28
29
#include <locale.h>
52
53
static GList *get_users_in_group (PolkitIdentity              *group,
53
54
                                  gboolean                     include_root);
54
55
 
 
56
static GList *get_users_in_net_group (PolkitIdentity          *group,
 
57
                                      gboolean                 include_root);
 
58
 
55
59
static GList *get_groups_for_user (PolkitIdentity              *user);
56
60
 
57
61
/* ---------------------------------------------------------------------------------------------------- */
58
62
 
59
63
typedef struct
60
64
{
 
65
  gchar *config_path;
61
66
  PolkitBackendConfigSource *config_source;
62
67
 
 
68
  gchar **authorization_store_paths;
63
69
  GList *authorization_stores;
64
 
 
65
 
  GFileMonitor *sysconf_dir_monitor;
66
 
  GFileMonitor *localstate_dir_monitor;
 
70
  GList *authorization_store_monitors;
67
71
 
68
72
} PolkitBackendLocalAuthorityPrivate;
69
73
 
70
74
/* ---------------------------------------------------------------------------------------------------- */
71
75
 
 
76
enum
 
77
{
 
78
  PROP_0,
 
79
 
 
80
  // Path overrides used for unit testing
 
81
  PROP_CONFIG_PATH,
 
82
  PROP_AUTH_STORE_PATHS,
 
83
};
 
84
 
 
85
/* ---------------------------------------------------------------------------------------------------- */
 
86
 
72
87
static GList *polkit_backend_local_authority_get_admin_auth_identities (PolkitBackendInteractiveAuthority *authority,
73
88
                                                                        PolkitSubject                     *caller,
74
89
                                                                        PolkitSubject                     *subject,
169
184
static void
170
185
add_all_authorization_stores (PolkitBackendLocalAuthority *authority)
171
186
{
 
187
  PolkitBackendLocalAuthorityPrivate *priv;
172
188
  guint n;
173
189
  GList *directories;
174
190
  GList *l;
175
191
 
 
192
  priv = POLKIT_BACKEND_LOCAL_AUTHORITY_GET_PRIVATE (authority);
176
193
  directories = NULL;
177
194
 
178
 
  for (n = 0; n < 2; n++)
 
195
  for (n = 0; priv->authorization_store_paths && priv->authorization_store_paths[n]; n++)
179
196
    {
180
197
      const gchar *toplevel_path;
181
198
      GFile *toplevel_directory;
185
202
 
186
203
      error = NULL;
187
204
 
188
 
      if (n == 0)
189
 
        toplevel_path = PACKAGE_LOCALSTATE_DIR "/lib/polkit-1/localauthority";
190
 
      else
191
 
        toplevel_path = PACKAGE_SYSCONF_DIR "/polkit-1/localauthority";
192
 
 
 
205
      toplevel_path = priv->authorization_store_paths[n];
193
206
      toplevel_directory = g_file_new_for_path (toplevel_path);
194
207
      directory_enumerator = g_file_enumerate_children (toplevel_directory,
195
208
                                                        "standard::name,standard::type",
276
289
polkit_backend_local_authority_init (PolkitBackendLocalAuthority *authority)
277
290
{
278
291
  PolkitBackendLocalAuthorityPrivate *priv;
 
292
 
 
293
  priv = POLKIT_BACKEND_LOCAL_AUTHORITY_GET_PRIVATE (authority);
 
294
 
 
295
  priv->config_path = NULL;
 
296
  priv->authorization_store_paths = NULL;
 
297
}
 
298
 
 
299
static void
 
300
polkit_backend_local_authority_constructed (GObject *object)
 
301
{
 
302
  PolkitBackendLocalAuthority *authority;
 
303
  PolkitBackendLocalAuthorityPrivate *priv;
279
304
  GFile *config_directory;
280
305
  guint n;
281
306
 
 
307
  authority = POLKIT_BACKEND_LOCAL_AUTHORITY (object);
282
308
  priv = POLKIT_BACKEND_LOCAL_AUTHORITY_GET_PRIVATE (authority);
283
309
 
284
 
  config_directory = g_file_new_for_path (PACKAGE_SYSCONF_DIR "/polkit-1/localauthority.conf.d");
 
310
  g_debug ("Using config directory `%s'", priv->config_path);
 
311
  config_directory = g_file_new_for_path (priv->config_path);
285
312
  priv->config_source = polkit_backend_config_source_new (config_directory);
286
313
  g_object_unref (config_directory);
287
314
 
288
315
  add_all_authorization_stores (authority);
289
316
 
290
317
  /* Monitor the toplevels */
291
 
  for (n = 0; n < 2; n++)
 
318
  priv->authorization_store_monitors = NULL;
 
319
  for (n = 0; priv->authorization_store_paths && priv->authorization_store_paths[n]; n++)
292
320
    {
293
321
      const gchar *toplevel_path;
294
322
      GFile *toplevel_directory;
295
323
      GFileMonitor *monitor;
296
324
      GError *error;
297
325
 
298
 
      if (n == 0)
299
 
        toplevel_path = PACKAGE_LOCALSTATE_DIR "/lib/polkit-1/localauthority";
300
 
      else
301
 
        toplevel_path = PACKAGE_SYSCONF_DIR "/polkit-1/localauthority";
302
 
 
 
326
      toplevel_path = priv->authorization_store_paths[n];
303
327
      toplevel_directory = g_file_new_for_path (toplevel_path);
304
328
 
305
329
      error = NULL;
322
346
                        G_CALLBACK (on_toplevel_authority_store_monitor_changed),
323
347
                        authority);
324
348
 
325
 
      if (n == 0)
326
 
        priv->sysconf_dir_monitor = monitor;
327
 
      else
328
 
        priv->localstate_dir_monitor = monitor;
 
349
      priv->authorization_store_monitors = g_list_append (priv->authorization_store_monitors, monitor);
329
350
 
330
351
      g_object_unref (toplevel_directory);
331
352
    }
 
353
 
 
354
  G_OBJECT_CLASS (polkit_backend_local_authority_parent_class)->constructed (object);
332
355
}
333
356
 
334
357
static void
342
365
 
343
366
  purge_all_authorization_stores (local_authority);
344
367
 
345
 
  if (priv->sysconf_dir_monitor != NULL)
346
 
    g_object_unref (priv->sysconf_dir_monitor);
347
 
  if (priv->localstate_dir_monitor != NULL)
348
 
    g_object_unref (priv->localstate_dir_monitor);
 
368
  g_list_free_full (priv->authorization_store_monitors, g_object_unref);
349
369
 
350
370
  if (priv->config_source != NULL)
351
371
    g_object_unref (priv->config_source);
352
372
 
 
373
  g_free (priv->config_path);
 
374
  g_strfreev (priv->authorization_store_paths);
 
375
 
353
376
  G_OBJECT_CLASS (polkit_backend_local_authority_parent_class)->finalize (object);
354
377
}
355
378
 
372
395
}
373
396
 
374
397
static void
 
398
polkit_backend_local_authority_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec)
 
399
{
 
400
  PolkitBackendLocalAuthority *local_authority;
 
401
  PolkitBackendLocalAuthorityPrivate *priv;
 
402
 
 
403
  local_authority = POLKIT_BACKEND_LOCAL_AUTHORITY (object);
 
404
  priv = POLKIT_BACKEND_LOCAL_AUTHORITY_GET_PRIVATE (local_authority);
 
405
 
 
406
  switch (property_id)
 
407
    {
 
408
      case PROP_CONFIG_PATH:
 
409
        g_free (priv->config_path);
 
410
        priv->config_path = g_value_dup_string (value);
 
411
        break;
 
412
      case PROP_AUTH_STORE_PATHS:
 
413
        g_strfreev (priv->authorization_store_paths);
 
414
        priv->authorization_store_paths = g_strsplit (g_value_get_string (value), ";", 0);
 
415
        break;
 
416
      default:
 
417
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 
418
        break;
 
419
    }
 
420
}
 
421
 
 
422
static void
375
423
polkit_backend_local_authority_class_init (PolkitBackendLocalAuthorityClass *klass)
376
424
{
377
425
  GObjectClass *gobject_class;
378
426
  PolkitBackendAuthorityClass *authority_class;
379
427
  PolkitBackendInteractiveAuthorityClass *interactive_authority_class;
 
428
  GParamSpec *pspec;
380
429
 
381
430
  gobject_class = G_OBJECT_CLASS (klass);
382
431
  authority_class = POLKIT_BACKEND_AUTHORITY_CLASS (klass);
383
432
  interactive_authority_class = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_CLASS (klass);
384
433
 
 
434
  gobject_class->set_property                           = polkit_backend_local_authority_set_property;
385
435
  gobject_class->finalize                               = polkit_backend_local_authority_finalize;
 
436
  gobject_class->constructed                            = polkit_backend_local_authority_constructed;
386
437
  authority_class->get_name                             = polkit_backend_local_authority_get_name;
387
438
  authority_class->get_version                          = polkit_backend_local_authority_get_version;
388
439
  authority_class->get_features                         = polkit_backend_local_authority_get_features;
389
440
  interactive_authority_class->get_admin_identities     = polkit_backend_local_authority_get_admin_auth_identities;
390
441
  interactive_authority_class->check_authorization_sync = polkit_backend_local_authority_check_authorization_sync;
391
442
 
 
443
  pspec = g_param_spec_string ("config-path",
 
444
                               "Local Authority Configuration Path",
 
445
                               "Path to directory of LocalAuthority config files.",
 
446
                               PACKAGE_SYSCONF_DIR "/polkit-1/localauthority.conf.d",
 
447
                               G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE);
 
448
  g_object_class_install_property (gobject_class, PROP_CONFIG_PATH, pspec);
 
449
 
 
450
  pspec = g_param_spec_string ("auth-store-paths",
 
451
                               "Local Authorization Store Paths",
 
452
                               "Semi-colon separated list of Authorization Store 'top' directories.",
 
453
                               PACKAGE_LOCALSTATE_DIR "/lib/polkit-1/localauthority;"
 
454
                               PACKAGE_SYSCONF_DIR "/polkit-1/localauthority",
 
455
                               G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE);
 
456
  g_object_class_install_property (gobject_class, PROP_AUTH_STORE_PATHS, pspec);
 
457
 
392
458
  g_type_class_add_private (klass, sizeof (PolkitBackendLocalAuthorityPrivate));
393
459
}
394
460
 
445
511
        {
446
512
          ret = g_list_concat (ret, get_users_in_group (identity, FALSE));
447
513
        }
 
514
      else if (POLKIT_IS_UNIX_NETGROUP (identity))
 
515
        {
 
516
          ret =  g_list_concat (ret, get_users_in_net_group (identity, FALSE));
 
517
        }
448
518
      else
449
519
        {
450
520
          g_warning ("Unsupported identity %s", admin_identities[n]);
598
668
      PolkitIdentity *user;
599
669
      GError *error;
600
670
 
601
 
      if (!include_root && strcmp (grp->gr_mem[n], "root") == 0)
 
671
      if (!include_root && g_strcmp0 (grp->gr_mem[n], "root") == 0)
602
672
        continue;
603
673
 
604
674
      error = NULL;
621
691
}
622
692
 
623
693
static GList *
 
694
get_users_in_net_group (PolkitIdentity                    *group,
 
695
                        gboolean                           include_root)
 
696
{
 
697
  const gchar *name;
 
698
  GList *ret;
 
699
 
 
700
  ret = NULL;
 
701
  name = polkit_unix_netgroup_get_name (POLKIT_UNIX_NETGROUP (group));
 
702
 
 
703
  if (setnetgrent (name) == 0)
 
704
    {
 
705
      g_warning ("Error looking up net group with name %s: %s", name, g_strerror (errno));
 
706
      goto out;
 
707
    }
 
708
 
 
709
  for (;;)
 
710
    {
 
711
      char *hostname, *username, *domainname;
 
712
      PolkitIdentity *user;
 
713
      GError *error = NULL;
 
714
 
 
715
      if (getnetgrent (&hostname, &username, &domainname) == 0)
 
716
        break;
 
717
 
 
718
      /* Skip NULL entries since we never want to make everyone an admin
 
719
       * Skip "-" entries which mean "no match ever" in netgroup land */
 
720
      if (username == NULL || g_strcmp0 (username, "-") == 0)
 
721
        continue;
 
722
 
 
723
      /* TODO: Should we match on hostname? Maybe only allow "-" as a hostname
 
724
       * for safety. */
 
725
 
 
726
      user = polkit_unix_user_new_for_name (username, &error);
 
727
      if (user == NULL)
 
728
        {
 
729
          g_warning ("Unknown username '%s' in unix-netgroup: %s", username, error->message);
 
730
          g_error_free (error);
 
731
        }
 
732
      else
 
733
        {
 
734
          ret = g_list_prepend (ret, user);
 
735
        }
 
736
    }
 
737
 
 
738
  ret = g_list_reverse (ret);
 
739
 
 
740
 out:
 
741
  endnetgrent ();
 
742
  return ret;
 
743
}
 
744
 
 
745
 
 
746
static GList *
624
747
get_groups_for_user (PolkitIdentity *user)
625
748
{
626
749
  uid_t uid;