PolicyKit: Branch 'master' - 3 commits

David Zeuthen david at kemper.freedesktop.org
Thu Nov 29 12:48:37 PST 2007


 src/kit/Makefile.am                       |    1 
 src/kit/kit-entity.c                      |  163 ++++++++++++++++++++++++++++++
 src/kit/kit-entity.h                      |   52 +++++++++
 src/kit/kit-memory.c                      |    5 
 src/kit/kit-test-main.c                   |    1 
 src/kit/kit-test.h                        |    1 
 src/kit/kit.h                             |    1 
 src/polkit-dbus/polkit-read-auth-helper.c |   70 ------------
 src/polkit-grant/polkit-revoke-helper.c   |   50 ++++++++-
 src/polkit/polkit-authorization-db.c      |  146 +++++++++++++++++++++++---
 src/polkit/polkit-policy-cache.c          |    5 
 11 files changed, 400 insertions(+), 95 deletions(-)

New commits:
commit 8687a34801460b00aaaed1c49d2daa4eacfd8dbe
Author: David Zeuthen <davidz at redhat.com>
Date:   Thu Nov 29 15:47:15 2007 -0500

    fix unit tests for polkit-authorization-db.c

diff --git a/src/polkit-dbus/polkit-read-auth-helper.c b/src/polkit-dbus/polkit-read-auth-helper.c
index 0d640d3..4663b68 100644
--- a/src/polkit-dbus/polkit-read-auth-helper.c
+++ b/src/polkit-dbus/polkit-read-auth-helper.c
@@ -151,76 +151,6 @@ out:
         return ret;
 }
 
-#ifdef POLKIT_BUILD_TESTS
-static struct passwd *
-kit_getpwnam (const char *username)
-{
-        struct passwd *pw;
-        FILE *f;
-        const char *passwd_file;
-
-        f = NULL;
-        pw = NULL;
-
-        if ((passwd_file = getenv ("POLKIT_TEST_PASSWD_FILE")) == NULL)
-                return getpwnam (username);
-
-        f = fopen (passwd_file, "r");
-        if (f == NULL)
-                goto out;
-
-        while ((pw = fgetpwent (f)) != NULL) {
-                if (strcmp (pw->pw_name, username) == 0)
-                        goto out;
-        }
-
-out:
-        if (f != NULL)
-                fclose (f);
-        return pw;
-}
-
-static struct passwd *
-kit_getpwuid (uid_t uid)
-{
-        struct passwd *pw;
-        FILE *f;
-        const char *passwd_file;
-
-        f = NULL;
-        pw = NULL;
-
-        if ((passwd_file = getenv ("POLKIT_TEST_PASSWD_FILE")) == NULL)
-                return getpwuid (uid);
-
-        f = fopen (passwd_file, "r");
-        if (f == NULL)
-                goto out;
-
-        while ((pw = fgetpwent (f)) != NULL) {
-                if (pw->pw_uid == uid)
-                        goto out;
-        }
-
-out:
-        if (f != NULL)
-                fclose (f);
-        return pw;
-}
-#else
-static struct passwd *
-kit_getpwnam (const char *username)
-{
-        return getpwnam (username);
-}
-
-static struct passwd *
-kit_getpwuid (uid_t uid)
-{
-        return getpwuid (uid);
-}
-#endif
-
 static polkit_bool_t
 dump_auths_all (const char *root)
 {
diff --git a/src/polkit-grant/polkit-revoke-helper.c b/src/polkit-grant/polkit-revoke-helper.c
index 614eed1..31da7c7 100644
--- a/src/polkit-grant/polkit-revoke-helper.c
+++ b/src/polkit-grant/polkit-revoke-helper.c
@@ -107,11 +107,13 @@ main (int argc, char *argv[])
 
         ret = 1;
 
+#ifndef POLKIT_BUILD_TESTS
         /* clear the entire environment to avoid attacks using with libraries honoring environment variables */
         if (clearenv () != 0)
                 goto out;
         /* set a minimal environment */
         setenv ("PATH", "/usr/sbin:/usr/bin:/sbin:/bin", 1);
+#endif
 
         openlog ("polkit-revoke-helper", LOG_CONS | LOG_PID, LOG_AUTHPRIV);
 
@@ -132,6 +134,14 @@ main (int argc, char *argv[])
         invoking_uid = getuid ();
 
         /* check that we are setgid polkituser */
+#ifdef POLKIT_BUILD_TESTS
+        char *pretend;
+        if ((pretend = getenv ("POLKIT_TEST_PRETEND_TO_BE_UID")) != NULL) {
+                invoking_uid = atoi (pretend);
+                goto skip_check;
+        }
+        kit_warning ("foo %s", pretend);
+#endif
         egid = getegid ();
         group = getgrgid (egid);
         if (group == NULL) {
@@ -142,6 +152,9 @@ main (int argc, char *argv[])
                 fprintf (stderr, "polkit-revoke-helper: needs to be setgid " POLKIT_GROUP "\n");
                 goto out;
         }
+#ifdef POLKIT_BUILD_TESTS
+skip_check:
+#endif
 
         entry_to_remove = argv[1];
         target_type = argv[2];
@@ -181,21 +194,38 @@ main (int argc, char *argv[])
 
         not_granted_by_self = FALSE;
 
+#ifdef POLKIT_BUILD_TESTS
+        char *test_dir;
+        char dir_run[256];
+        char dir_lib[256];
+
+        if ((test_dir = getenv ("POLKIT_TEST_LOCALSTATE_DIR")) == NULL) {
+                test_dir = PACKAGE_LOCALSTATE_DIR;
+        }
+        kit_assert ((size_t) snprintf (dir_run, sizeof (dir_run), "%s/run/PolicyKit", test_dir) < sizeof (dir_run));
+        kit_assert ((size_t) snprintf (dir_lib, sizeof (dir_lib), "%s/lib/PolicyKit", test_dir) < sizeof (dir_lib));
+
+#else
+        char *dir_run = PACKAGE_LOCALSTATE_DIR "/run/PolicyKit";
+        char *dir_lib = PACKAGE_LOCALSTATE_DIR "/lib/PolicyKit";
+#endif
+
+
         is_one_shot = FALSE;
         if (strcmp (scope, "scope=process") == 0) {
-                root = PACKAGE_LOCALSTATE_DIR "/run/PolicyKit";
+                root = dir_run;
         } else if (strcmp (scope, "scope=process-one-shot") == 0) {
-                root = PACKAGE_LOCALSTATE_DIR "/run/PolicyKit";
+                root = dir_run;
                 is_one_shot = TRUE;
         } else if (strcmp (scope, "scope=session") == 0) {
-                root = PACKAGE_LOCALSTATE_DIR "/run/PolicyKit";
+                root = dir_run;
         } else if (strcmp (scope, "scope=always") == 0) {
-                root = PACKAGE_LOCALSTATE_DIR "/lib/PolicyKit";
+                root = dir_lib;
         } else if (strcmp (scope, "scope=grant") == 0 ||
                    strcmp (scope, "scope=grant-negative") == 0) {
                 unsigned int n;
 
-                root = PACKAGE_LOCALSTATE_DIR "/lib/PolicyKit";
+                root = dir_lib;
 
                 for (n = 1; n < num_tokens; n++) {
                         if (strncmp (tokens[n], "granted-by=", sizeof ("granted-by=") - 1) == 0) {
@@ -223,6 +253,7 @@ main (int argc, char *argv[])
                 goto out;
         }
 
+
         if (invoking_uid != 0) {
                 /* Check that the caller is privileged to do this... basically, callers can only
                  * revoke auths granted by themselves...
@@ -240,7 +271,7 @@ main (int argc, char *argv[])
                 }
         }
 
-        pw = getpwuid (uid_to_revoke);
+        pw = kit_getpwuid (uid_to_revoke);
         if (pw == NULL) {
                 fprintf (stderr, "polkit-revoke-helper: cannot lookup user name for uid %d\n", uid_to_revoke);
                 goto out;
@@ -309,11 +340,18 @@ main (int argc, char *argv[])
          */
         ret = 0;
 
+#ifdef POLKIT_BUILD_TESTS
+        if (test_dir != NULL)
+                goto no_reload;
+#endif
         /* trigger a reload */
         if (utimes (PACKAGE_LOCALSTATE_DIR "/lib/misc/PolicyKit.reload", NULL) != 0) {
                 fprintf (stderr, "Error updating access+modification time on file '%s': %m\n", 
                          PACKAGE_LOCALSTATE_DIR "/lib/misc/PolicyKit.reload");
         }
+#ifdef POLKIT_BUILD_TESTS
+no_reload:
+#endif
 
 out:
 
diff --git a/src/polkit/polkit-authorization-db.c b/src/polkit/polkit-authorization-db.c
index 5f1bcd3..66ebcce 100644
--- a/src/polkit/polkit-authorization-db.c
+++ b/src/polkit/polkit-authorization-db.c
@@ -317,9 +317,15 @@ _authdb_get_auths_for_uid (PolKitAuthorizationDB *authdb,
                              &standard_output, /* char       **stdout */
                              NULL,             /* char       **stderr */
                              &exit_status)) {  /* int         *exit_status */
-                polkit_error_set_error (error, 
-                                        POLKIT_ERROR_GENERAL_ERROR, 
-                                        "Error spawning read auth helper: %m");
+                if (errno == ENOMEM) {
+                        polkit_error_set_error (error, 
+                                                POLKIT_ERROR_OUT_OF_MEMORY, 
+                                                "Error spawning read auth helper: OOM");
+                } else {
+                        polkit_error_set_error (error, 
+                                                POLKIT_ERROR_GENERAL_ERROR, 
+                                                "Error spawning read auth helper: %m");
+                }
                 goto out;
         }
 
@@ -754,6 +760,8 @@ typedef struct {
 
         polkit_bool_t *out_is_authorized;
         polkit_bool_t *out_is_negative_authorized;
+
+        PolKitError *error;
 } CheckData;
 
 static polkit_bool_t 
@@ -766,7 +774,6 @@ _check_auth_for_caller (PolKitAuthorizationDB *authdb, PolKitAuthorization *auth
         polkit_uint64_t caller_pid_start_time;
         CheckData *cd = (CheckData *) user_data;
         PolKitAuthorizationConstraint *constraint;
-        PolKitError *error;
 
         ret = FALSE;
 
@@ -790,12 +797,14 @@ _check_auth_for_caller (PolKitAuthorizationDB *authdb, PolKitAuthorization *auth
 
                         /* it's a match already; revoke if asked to do so */
                         if (cd->revoke_if_one_shot) {
-                                error = NULL;
-                                if (!polkit_authorization_db_revoke_entry (authdb, auth, &error)) {
-                                        kit_warning ("Cannot revoke one-shot auth: %s: %s", 
-                                                   polkit_error_get_error_name (error),
-                                                   polkit_error_get_error_message (error));
-                                        polkit_error_free (error);
+                                cd->error = NULL;
+                                if (!polkit_authorization_db_revoke_entry (authdb, auth, &(cd->error))) {
+                                        //kit_warning ("Cannot revoke one-shot auth: %s: %s", 
+                                        //           polkit_error_get_error_name (cd->error),
+                                        //           polkit_error_get_error_message (cd->error));
+                                        /* stop iterating */
+                                        ret = TRUE;
+                                        goto no_match;
                                 }
                         }
                 }
@@ -886,6 +895,7 @@ polkit_authorization_db_is_caller_authorized (PolKitAuthorizationDB *authdb,
 
         cd.caller = caller;
         cd.revoke_if_one_shot = revoke_if_one_shot;
+        cd.error = NULL;
 
         cd.caller_pid_start_time = polkit_sysdeps_get_start_time_for_pid (cd.caller_pid);
         if (cd.caller_pid_start_time == 0) {
@@ -931,6 +941,15 @@ polkit_authorization_db_is_caller_authorized (PolKitAuthorizationDB *authdb,
                 goto out;
         }
 
+        if (polkit_error_is_set (cd.error)) {
+                if (error != NULL) {
+                        *error = cd.error;
+                } else {
+                        polkit_error_free (cd.error);
+                }
+                goto out;
+        }
+
         ret = TRUE;
 
 out:
@@ -955,7 +974,7 @@ polkit_authorization_db_revoke_entry (PolKitAuthorizationDB *authdb,
                                       PolKitAuthorization   *auth,
                                       PolKitError           **error)
 {
-        char *helper_argv[] = {PACKAGE_LIBEXEC_DIR "/polkit-revoke-helper", "", NULL, NULL, NULL};
+        char *helper_argv[] = {NULL, "", NULL, NULL, NULL};
         const char *auth_file_entry;
         polkit_bool_t ret;
         int exit_status;
@@ -968,9 +987,28 @@ polkit_authorization_db_revoke_entry (PolKitAuthorizationDB *authdb,
         auth_file_entry = _polkit_authorization_get_authfile_entry (auth);
         //g_debug ("should delete line '%s'", auth_file_entry);
 
+#ifdef POLKIT_BUILD_TESTS
+        char helper_buf[256];
+        char *helper_bin_dir;
+        if ((helper_bin_dir = getenv ("POLKIT_TEST_BUILD_DIR")) != NULL) {
+                kit_assert ((size_t) snprintf (helper_buf, sizeof (helper_buf), "%s/src/polkit-grant/polkit-revoke-helper", helper_bin_dir) < sizeof (helper_buf));
+                helper_argv[0] = helper_buf;
+        } else {
+                helper_argv[0] = PACKAGE_LIBEXEC_DIR "/polkit-revoke-helper";
+        }
+#else
+        helper_argv[0] = PACKAGE_LIBEXEC_DIR "/polkit-revoke-helper";
+#endif
+
         helper_argv[1] = (char *) auth_file_entry;
         helper_argv[2] = "uid";
         helper_argv[3] = kit_strdup_printf ("%d", polkit_authorization_get_uid (auth));
+        if (helper_argv[3] == NULL) {
+                polkit_error_set_error (error, 
+                                        POLKIT_ERROR_OUT_OF_MEMORY, 
+                                        "Out of memory");
+                goto out;
+        }
 
         if (!kit_spawn_sync (NULL,             /* const char  *working_directory */
                              0,                /* flags */
@@ -980,9 +1018,15 @@ polkit_authorization_db_revoke_entry (PolKitAuthorizationDB *authdb,
                              NULL,             /* char       **stdout */
                              NULL,             /* char       **stderr */
                              &exit_status)) {  /* int         *exit_status */
-                polkit_error_set_error (error, 
-                                        POLKIT_ERROR_GENERAL_ERROR, 
-                                        "Error spawning revoke helper: %m");
+                if (errno == ENOMEM) {
+                        polkit_error_set_error (error, 
+                                                POLKIT_ERROR_OUT_OF_MEMORY, 
+                                                "Error spawning revoke helper: OOM");
+                } else {
+                        polkit_error_set_error (error, 
+                                                POLKIT_ERROR_GENERAL_ERROR, 
+                                                "Error spawning revoke helper: %m");
+                }
                 goto out;
         }
 
@@ -1097,8 +1141,7 @@ _run_test (void)
                 "";
         const char test_pu2_lib[] =
                 "";
-        const char test_pu3_run[] =
-                "";
+        char test_pu3_run[512];
         const char test_pu3_lib[] =
                 "";
         PolKitCaller *caller;
@@ -1106,10 +1149,23 @@ _run_test (void)
         polkit_bool_t is_auth;
         polkit_bool_t is_neg;
         PolKitError *error;
+        polkit_uint64_t start_time;
+
 
         adb = NULL;
         caller = NULL;
         action = NULL;
+
+        start_time = polkit_sysdeps_get_start_time_for_pid (getpid ());
+        if (start_time == 0)
+                goto out;
+        
+        if (snprintf (test_pu3_run, sizeof (test_pu3_run), 
+                      "scope=process:pid=%d:pid-start-time=%lld:action-id=org.example.per-process:when=1196307507:auth-as=500:constraint=none\n"
+                      "scope=process-one-shot:pid=%d:pid-start-time=%lld:action-id=org.example.per-process-one-shot:when=1196307507:auth-as=500:constraint=none\n",
+                      getpid (), start_time,
+                      getpid (), start_time) >= (int) sizeof (test_pu3_run))
+                goto fail;
         
         if (setenv ("POLKIT_TEST_LOCALSTATE_DIR", TEST_DATA_DIR "authdb-test", 1) != 0)
                 goto fail;
@@ -1117,7 +1173,7 @@ _run_test (void)
         if (setenv ("POLKIT_TEST_BUILD_DIR", TEST_BUILD_DIR, 1) != 0)
                 goto fail;
 
-        if (setenv ("POLKIT_TEST_PASSWD_FILE", TEST_DATA_DIR "authdb-test/passwd", 1) != 0)
+        if (setenv ("KIT_TEST_PASSWD_FILE", TEST_DATA_DIR "authdb-test/passwd", 1) != 0)
                 goto fail;
 
         /* create test users */
@@ -1170,6 +1226,11 @@ _run_test (void)
         if (polkit_authorization_db_is_caller_authorized (adb, action, caller, FALSE, &is_auth, &is_neg, &error)) {
                 kit_assert (! polkit_error_is_set (error) && is_auth && !is_neg);
         } else {
+                //kit_warning ("%p: %d: %s: %s", 
+                //             error, 
+                //             polkit_error_get_error_code (error), 
+                //            polkit_error_get_error_name (error),
+                //             polkit_error_get_error_message (error));
                 kit_assert (polkit_error_is_set (error) && 
                             polkit_error_get_error_code (error) == POLKIT_ERROR_OUT_OF_MEMORY);
                 polkit_error_free (error);
@@ -1225,6 +1286,55 @@ _run_test (void)
 
         _polkit_authorization_db_invalidate_cache (adb);
 
+        /* test: pu3 is authorized for org.example.per-process */
+        if (!polkit_action_set_action_id (action, "org.example.per-process"))
+                goto out;
+
+        kit_assert (polkit_caller_set_uid (caller, 50403));
+        if (setenv ("POLKIT_TEST_PRETEND_TO_BE_UID", "50403", 1) != 0)
+                goto fail;
+        error = NULL;
+        if (polkit_authorization_db_is_caller_authorized (adb, action, caller, FALSE, &is_auth, &is_neg, &error)) {
+                kit_assert (! polkit_error_is_set (error) && is_auth && !is_neg);
+        } else {
+                kit_assert (polkit_error_is_set (error) && 
+                            polkit_error_get_error_code (error) == POLKIT_ERROR_OUT_OF_MEMORY);
+                polkit_error_free (error);
+        }
+
+        /* test: pu3 is authorized for org.example.per-process-one-shot just once */
+        if (!polkit_action_set_action_id (action, "org.example.per-process-one-shot"))
+                goto out;
+
+        kit_assert (polkit_caller_set_uid (caller, 50403));
+        if (setenv ("POLKIT_TEST_PRETEND_TO_BE_UID", "50403", 1) != 0)
+                goto fail;
+        error = NULL;
+        if (polkit_authorization_db_is_caller_authorized (adb, action, caller, TRUE, &is_auth, &is_neg, &error)) {
+                kit_assert (! polkit_error_is_set (error) && is_auth && !is_neg);
+
+                _polkit_authorization_db_invalidate_cache (adb);
+
+                if (polkit_authorization_db_is_caller_authorized (adb, action, caller, TRUE, &is_auth, &is_neg, &error)) {
+                        if (is_auth || is_neg) {
+                                kit_warning ("pu3 shouldn't be authorized for something twice: %d %d", is_auth, is_neg);
+                                goto fail;
+                        }
+                } else {
+                        if (polkit_error_is_set (error)) {
+                                kit_assert (polkit_error_get_error_code (error) == POLKIT_ERROR_OUT_OF_MEMORY);
+                                polkit_error_free (error);
+                        }
+                }
+        } else {
+                kit_assert (polkit_error_is_set (error) && 
+                            polkit_error_get_error_code (error) == POLKIT_ERROR_OUT_OF_MEMORY);
+                polkit_error_free (error);
+        }
+
+
+        _polkit_authorization_db_invalidate_cache (adb);
+
 out:
 
         if (action != NULL)
@@ -1250,7 +1360,7 @@ out:
         if (unsetenv ("POLKIT_TEST_BUILD_DIR") != 0)
                 goto fail;
 
-        if (unsetenv ("POLKIT_TEST_PASSWD_FILE") != 0)
+        if (unsetenv ("KIT_TEST_PASSWD_FILE") != 0)
                 goto fail;
 
         return TRUE;
diff --git a/src/polkit/polkit-policy-cache.c b/src/polkit/polkit-policy-cache.c
index 3e3d7ba..6a80909 100644
--- a/src/polkit/polkit-policy-cache.c
+++ b/src/polkit/polkit-policy-cache.c
@@ -148,7 +148,10 @@ _polkit_policy_cache_new (const char *dirname, polkit_bool_t load_descriptions,
 
                 if (pf == NULL) {
                         if (polkit_error_get_error_code (pk_error) == POLKIT_ERROR_OUT_OF_MEMORY) {
-                                polkit_error_set_error (error, POLKIT_ERROR_OUT_OF_MEMORY, "Out of memory");
+                                if (error != NULL)
+                                        *error = pk_error;
+                                else
+                                        polkit_error_free (pk_error);
                                 goto out;
                         }
 
commit 2de93f9b2152cf262a0daa0357e5da8566724833
Author: David Zeuthen <davidz at redhat.com>
Date:   Thu Nov 29 00:07:40 2007 -0500

    add test-friendly abstractions for getpwnam and getpwuid

diff --git a/src/kit/Makefile.am b/src/kit/Makefile.am
index 16eb69f..abd12bf 100644
--- a/src/kit/Makefile.am
+++ b/src/kit/Makefile.am
@@ -28,6 +28,7 @@ libkit_la_SOURCES =					\
 	kit-file.h		kit-file.c		\
 	kit-spawn.h		kit-spawn.c		\
 	kit-message.h		kit-message.c		\
+	kit-entity.h		kit-entity.c		\
 	$(NULL)
 
 
diff --git a/src/kit/kit-entity.c b/src/kit/kit-entity.c
new file mode 100644
index 0000000..0bd550f
--- /dev/null
+++ b/src/kit/kit-entity.c
@@ -0,0 +1,163 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/***************************************************************************
+ *
+ * kit-entity.c : Entity management
+ *
+ * Copyright (C) 2007 David Zeuthen, <david at fubar.dk>
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#define _GNU_SOURCE
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#ifdef BUILT_R_DYNAMIC
+#include <execinfo.h>
+#endif
+
+#include <kit/kit-entity.h>
+#include <kit/kit-test.h>
+
+/**
+ * SECTION:kit-entity
+ * @title: Entity management
+ * @short_description: Entity management
+ *
+ * Functions used for entity management.
+ **/
+
+#ifdef KIT_BUILD_TESTS
+
+/**
+ * kit_getpwnam:
+ * @username: user name to look up
+ *
+ * Like getpwnam(3) from the standard C library but tweaked for unit
+ * testing. TODO: explain how.
+ *
+ * Returns: See getpwnam(3)
+ */
+struct passwd *
+kit_getpwnam (const char *username)
+{
+        struct passwd *pw;
+        FILE *f;
+        const char *passwd_file;
+
+        f = NULL;
+        pw = NULL;
+
+        if ((passwd_file = getenv ("KIT_TEST_PASSWD_FILE")) == NULL)
+                return getpwnam (username);
+
+        f = fopen (passwd_file, "r");
+        if (f == NULL)
+                goto out;
+
+        while ((pw = fgetpwent (f)) != NULL) {
+                if (strcmp (pw->pw_name, username) == 0)
+                        goto out;
+        }
+
+out:
+        if (f != NULL)
+                fclose (f);
+        return pw;
+}
+
+/**
+ * kit_getpwuid:
+ * @username: user name to look up
+ *
+ * Like getpwuid(3) from the standard C library but tweaked for unit
+ * testing. TODO: explain how.
+ *
+ * Returns: See getpwuid(3)
+ */
+struct passwd *
+kit_getpwuid (uid_t uid)
+{
+        struct passwd *pw;
+        FILE *f;
+        const char *passwd_file;
+
+        f = NULL;
+        pw = NULL;
+
+        if ((passwd_file = getenv ("KIT_TEST_PASSWD_FILE")) == NULL)
+                return getpwuid (uid);
+
+        f = fopen (passwd_file, "r");
+        if (f == NULL)
+                goto out;
+
+        while ((pw = fgetpwent (f)) != NULL) {
+                if (pw->pw_uid == uid)
+                        goto out;
+        }
+
+out:
+        if (f != NULL)
+                fclose (f);
+        return pw;
+}
+
+#else
+
+struct passwd *
+kit_getpwnam (const char *username)
+{
+        return getpwnam (username);
+}
+
+struct passwd *
+kit_getpwuid (uid_t uid)
+{
+        return getpwuid (uid);
+}
+#endif
+
+
+#ifdef KIT_BUILD_TESTS
+
+static kit_bool_t
+_run_test (void)
+{
+        return TRUE;
+}
+
+KitTest _test_entity = {
+        "kit_entity",
+        NULL,
+        NULL,
+        _run_test
+};
+
+#endif /* KIT_BUILD_TESTS */
diff --git a/src/kit/kit-entity.h b/src/kit/kit-entity.h
new file mode 100644
index 0000000..91b4e51
--- /dev/null
+++ b/src/kit/kit-entity.h
@@ -0,0 +1,52 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
+/***************************************************************************
+ *
+ * kit-entity.h : Entity management
+ *
+ * Copyright (C) 2007 David Zeuthen, <david at fubar.dk>
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy,
+ * modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#if !defined (KIT_COMPILATION) && !defined(_KIT_INSIDE_KIT_H)
+#error "Only <kit/kit.h> can be included directly, this file may disappear or change contents."
+#endif
+
+#ifndef KIT_ENTITY_H
+#define KIT_ENTITY_H
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <kit/kit.h>
+
+KIT_BEGIN_DECLS
+
+struct passwd *kit_getpwnam (const char *username);
+struct passwd *kit_getpwuid (uid_t uid);
+
+KIT_END_DECLS
+
+#endif /* KIT_ENTITY_H */
+
+
diff --git a/src/kit/kit-test-main.c b/src/kit/kit-test-main.c
index 2505d9b..ccdcf79 100644
--- a/src/kit/kit-test-main.c
+++ b/src/kit/kit-test-main.c
@@ -39,6 +39,7 @@ static KitTest *tests[] = {
         &_test_hash,
         &_test_file,
         &_test_spawn,
+        &_test_entity,
 };
 
 int 
diff --git a/src/kit/kit-test.h b/src/kit/kit-test.h
index c43c65c..a3869c4 100644
--- a/src/kit/kit-test.h
+++ b/src/kit/kit-test.h
@@ -63,6 +63,7 @@ extern KitTest _test_list;
 extern KitTest _test_file;
 extern KitTest _test_spawn;
 extern KitTest _test_message;
+extern KitTest _test_entity;
 
 KIT_END_DECLS
 
diff --git a/src/kit/kit.h b/src/kit/kit.h
index c5ab267..6030e57 100644
--- a/src/kit/kit.h
+++ b/src/kit/kit.h
@@ -144,6 +144,7 @@ do {
 #include <kit/kit-spawn.h>
 #include <kit/kit-message.h>
 #include <kit/kit-test.h>
+#include <kit/kit-entity.h>
 
 #undef _KIT_INSIDE_KIT_H
 
commit d73be3a8ae92b66f9fe0aac7c1891c2ddfd870a4
Author: David Zeuthen <davidz at redhat.com>
Date:   Thu Nov 29 00:06:54 2007 -0500

    only fail the Nth alloc, not all allocs greater than N

diff --git a/src/kit/kit-memory.c b/src/kit/kit-memory.c
index 57858be..50d9abc 100644
--- a/src/kit/kit-memory.c
+++ b/src/kit/kit-memory.c
@@ -100,6 +100,11 @@ kit_malloc (size_t bytes)
 
         if (_fail_nth != -1 && _total_allocs == _fail_nth) {
                 errno = ENOMEM;
+                _total_allocs++;
+
+                //fprintf (stderr, "  Failing alloc @\n");
+                //kit_print_backtrace ();
+
                 return NULL;
         }
 


More information about the hal-commit mailing list