PolicyKit: Branch 'master'

David Zeuthen david at kemper.freedesktop.org
Wed Aug 12 07:09:19 PDT 2009


 configure.ac                                    |    4 +
 src/examples/frobnicate.c                       |    3 
 src/polkit/polkitunixgroup.c                    |    6 +
 src/polkit/polkitunixprocess.c                  |   95 +++++++++++++++++++++++-
 src/polkit/polkitunixprocess.h                  |    1 
 src/polkit/polkitunixuser.c                     |    6 +
 src/polkitagent/polkitagenthelper.c             |   12 +++
 src/polkitbackend/polkitbackendlocalauthority.c |    4 -
 src/polkitbackend/polkitbackendsessionmonitor.c |    7 -
 src/programs/pkexec.c                           |   46 +++++++----
 10 files changed, 153 insertions(+), 31 deletions(-)

New commits:
commit de9453f4c178fe76a4a36edb752e2ed75a329032
Author: Joe Marcus Clarke <marcus at freebsd.org>
Date:   Wed Aug 12 10:04:15 2009 -0400

    Bug 23093 – FreeBSD portability fixes
    
    There are a few issues with building polkit-0.93 on FreeBSD:
    
     * No clearenv() function on FreeBSD
    
     * While FreeBSD has a /proc, it is deprecated, and kinfo_proc should
       be used instead.
    
     * FreeBSD's printf() functions do not support the %m notation.  This
       is only supported for syslog().
    
      * You can't call GINT_TO_POINTER() on a 64-bit value, as this will
        break on 64-bit OSes.
    
    The attached patch fixes these problems.  First, a check for
    clearenv() is added to configure.  Second, I moved the check for
    process uid to polkit/polkitunixprocess.c.  This may not be ideal, but
    it seems to fit, and reduces code duplication.  Third, I replaces all
    %m with %s ... g_strerror (errno).  Finally, I replaced
    GINT_TO_POINTER() with GSIZE_TO_POINTER.
    
    Signed-off-by: David Zeuthen <davidz at redhat.com>

diff --git a/configure.ac b/configure.ac
index c236341..3ea3818 100644
--- a/configure.ac
+++ b/configure.ac
@@ -140,6 +140,8 @@ AC_CHECK_LIB(expat,XML_ParserCreate,[EXPAT_LIBS="-lexpat"],
 	     [AC_MSG_ERROR([Can't find expat library. Please install expat.])])
 AC_SUBST(EXPAT_LIBS)
 
+AC_CHECK_FUNCS(clearenv)
+
 if test "x$GCC" = "xyes"; then
   LDFLAGS="-Wl,--as-needed $LDFLAGS"
 fi
@@ -323,6 +325,8 @@ if test x$with_os_type = x; then
         with_os_type=pardus
     elif test x$operating_system = xsolaris ; then
 	with_os_type=solaris
+    elif test x$operating_system = xfreebsd ; then
+	with_os_type=freebsd
     else
         with_os_type=unknown
     fi
diff --git a/src/examples/frobnicate.c b/src/examples/frobnicate.c
index 6b6b8ff..9de4b49 100644
--- a/src/examples/frobnicate.c
+++ b/src/examples/frobnicate.c
@@ -21,6 +21,7 @@
 
 #include <glib.h>
 #include <unistd.h>
+#include <errno.h>
 #include <sys/types.h>
 
 int
@@ -38,7 +39,7 @@ main (int argc, char *argv[])
 
   if (getcwd (cwd, sizeof cwd) == NULL)
     {
-      g_printerr ("Error getting cwd: %m");
+      g_printerr ("Error getting cwd: %s", g_strerror (errno));
       goto out;
     }
 
diff --git a/src/polkit/polkitunixgroup.c b/src/polkit/polkitunixgroup.c
index 79db400..0c2e473 100644
--- a/src/polkit/polkitunixgroup.c
+++ b/src/polkit/polkitunixgroup.c
@@ -25,6 +25,7 @@
 
 #include <string.h>
 #include <grp.h>
+#include <errno.h>
 #include "polkitunixgroup.h"
 #include "polkitidentity.h"
 #include "polkiterror.h"
@@ -210,8 +211,9 @@ polkit_unix_group_new_for_name (const gchar    *name,
       g_set_error (error,
                    POLKIT_ERROR,
                    POLKIT_ERROR_FAILED,
-                   "No UNIX group with name %s: %m",
-                   name);
+                   "No UNIX group with name %s: %s",
+                   name,
+                   g_strerror (errno));
       goto out;
     }
 
diff --git a/src/polkit/polkitunixprocess.c b/src/polkit/polkitunixprocess.c
index b75203f..a3813c2 100644
--- a/src/polkit/polkitunixprocess.c
+++ b/src/polkit/polkitunixprocess.c
@@ -23,6 +23,14 @@
 #  include "config.h"
 #endif
 
+#include <sys/types.h>
+#ifndef HAVE_FREEBSD
+#include <sys/stat.h>
+#else
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <sys/user.h>
+#endif
 #include <stdlib.h>
 #include <string.h>
 #include "polkitunixprocess.h"
@@ -72,6 +80,10 @@ static void subject_iface_init (PolkitSubjectIface *subject_iface);
 static guint64 get_start_time_for_pid (pid_t    pid,
                                        GError **error);
 
+#ifdef HAVE_FREEBSD
+static gboolean get_kinfo_proc (pid_t pid, struct kinfo_proc *p);
+#endif
+
 G_DEFINE_TYPE_WITH_CODE (PolkitUnixProcess, polkit_unix_process, G_TYPE_OBJECT,
                          G_IMPLEMENT_INTERFACE (POLKIT_TYPE_SUBJECT, subject_iface_init)
                          );
@@ -187,6 +199,44 @@ polkit_unix_process_get_pid (PolkitUnixProcess *process)
 }
 
 /**
+ * polkit_unix_pid_get_uid:
+ * @pid: A process ID.
+ * @uid: A pointer to a uid_t.
+ *
+ * Gets the uid for a given @pid.
+ *
+ * Returns: 0 on success, -1 on failure.
+ */
+int
+polkit_unix_pid_get_uid (pid_t pid, uid_t *uid)
+{
+#ifndef HAVE_FREEBSD
+  struct stat statbuf;
+  char procbuf[32];
+#else
+  struct kinfo_proc p;
+#endif
+
+  g_return_val_if_fail (uid != NULL, -1);
+  g_return_val_if_fail (pid > 0, -1);
+
+#ifndef HAVE_FREEBSD
+  g_snprintf (procbuf, sizeof procbuf, "/proc/%d", pid);
+  if (stat (procbuf, &statbuf) != 0)
+    return -1;
+
+  *uid = statbuf.st_uid;
+#else
+  if (! get_kinfo_proc (pid, &p))
+    return -1;
+
+  *uid = p.ki_uid;
+#endif
+
+  return 0;
+}
+
+/**
  * polkit_unix_process_get_start_time:
  * @process: A #PolkitUnixProcess.
  *
@@ -262,7 +312,7 @@ polkit_unix_process_hash (PolkitSubject *subject)
 {
   PolkitUnixProcess *process = POLKIT_UNIX_PROCESS (subject);
 
-  return g_direct_hash (GINT_TO_POINTER ((process->pid + process->start_time))) ;
+  return g_direct_hash (GSIZE_TO_POINTER ((process->pid + process->start_time))) ;
 }
 
 static gboolean
@@ -387,14 +437,35 @@ get_pid_psinfo (pid_t pid, struct psinfo *ps)
 }
 #endif
 
+#ifdef HAVE_FREEBSD
+static gboolean
+get_kinfo_proc (pid_t pid, struct kinfo_proc *p)
+{
+  int mib[4];
+  size_t len;
+
+  len = 4;
+  sysctlnametomib ("kern.proc.pid", mib, &len);
+
+  len = sizeof (struct kinfo_proc);
+  mib[3] = pid;
+
+  if (sysctl (mib, 4, p, &len, NULL, 0) == -1)
+    return FALSE;
+
+  return TRUE;
+}
+#endif
+
 static guint64
 get_start_time_for_pid (pid_t    pid,
                         GError **error)
 {
+  guint64 start_time;
+#ifndef HAVE_FREEBSD
   gchar *filename;
   gchar *contents;
   size_t length;
-  guint64 start_time;
   gchar **tokens;
   guint num_tokens;
   gchar *p;
@@ -463,6 +534,26 @@ get_start_time_for_pid (pid_t    pid,
  out:
   g_free (filename);
   g_free (contents);
+#else
+  struct kinfo_proc p;
+
+  start_time = 0;
+
+  if (! get_kinfo_proc (pid, &p))
+    {
+      g_set_error (error,
+                   POLKIT_ERROR,
+                   POLKIT_ERROR_FAILED,
+                   "Error obtaining start time for %d (%s)",
+                   (gint) pid,
+                   g_strerror (errno));
+      goto out;
+    }
+
+  start_time = (guint64) p.ki_start.tv_sec;
+
+out:
+#endif
 
   return start_time;
 }
diff --git a/src/polkit/polkitunixprocess.h b/src/polkit/polkitunixprocess.h
index 9af2710..731ee61 100644
--- a/src/polkit/polkitunixprocess.h
+++ b/src/polkit/polkitunixprocess.h
@@ -52,6 +52,7 @@ PolkitSubject  *polkit_unix_process_new_full       (pid_t pid,
                                                     guint64 start_time);
 
 pid_t           polkit_unix_process_get_pid        (PolkitUnixProcess *process);
+int             polkit_unix_pid_get_uid            (pid_t pid, uid_t *uid);
 guint64         polkit_unix_process_get_start_time (PolkitUnixProcess *process);
 
 void            polkit_unix_process_set_pid        (PolkitUnixProcess *process,
diff --git a/src/polkit/polkitunixuser.c b/src/polkit/polkitunixuser.c
index e3d8327..1f5af13 100644
--- a/src/polkit/polkitunixuser.c
+++ b/src/polkit/polkitunixuser.c
@@ -25,6 +25,7 @@
 
 #include <string.h>
 #include <pwd.h>
+#include <errno.h>
 #include "polkitunixuser.h"
 #include "polkitidentity.h"
 #include "polkiterror.h"
@@ -210,8 +211,9 @@ polkit_unix_user_new_for_name (const gchar    *name,
       g_set_error (error,
                    POLKIT_ERROR,
                    POLKIT_ERROR_FAILED,
-                   "No UNIX user with name %s: %m",
-                   name);
+                   "No UNIX user with name %s: %s",
+                   name,
+                   g_strerror (errno));
       goto out;
     }
 
diff --git a/src/polkitagent/polkitagenthelper.c b/src/polkitagent/polkitagenthelper.c
index 437eada..f85b0d4 100644
--- a/src/polkitagent/polkitagenthelper.c
+++ b/src/polkitagent/polkitagenthelper.c
@@ -35,6 +35,18 @@
 #  define LOG_AUTHPRIV    (10<<3)
 #endif
 
+#ifndef HAVE_CLEARENV
+extern char **environ;
+
+static int
+clearenv (void)
+{
+	if (environ != NULL)
+		environ[0] = NULL;
+	return 0;
+}
+#endif
+
 /* Development aid: define PAH_DEBUG to get debugging output. Do _NOT_
  * enable this in production builds; it may leak passwords and other
  * sensitive information.
diff --git a/src/polkitbackend/polkitbackendlocalauthority.c b/src/polkitbackend/polkitbackendlocalauthority.c
index e100c56..a3fb7f2 100644
--- a/src/polkitbackend/polkitbackendlocalauthority.c
+++ b/src/polkitbackend/polkitbackendlocalauthority.c
@@ -370,7 +370,7 @@ get_users_in_group (PolkitIdentity                    *group,
   grp = getgrgid (gid);
   if (grp == NULL)
     {
-      g_warning ("Error looking up group with gid %d: %m", gid);
+      g_warning ("Error looking up group with gid %d: %s", gid, g_strerror (errno));
       goto out;
     }
 
@@ -430,7 +430,7 @@ get_groups_for_user (PolkitIdentity *user)
                     groups,
                     &num_groups) < 0)
     {
-      g_warning ("Error looking up groups for uid %d: %m", uid);
+      g_warning ("Error looking up groups for uid %d: %s", uid, g_strerror (errno));
       goto out;
     }
 
diff --git a/src/polkitbackend/polkitbackendsessionmonitor.c b/src/polkitbackend/polkitbackendsessionmonitor.c
index fbff1fa..eca8bd8 100644
--- a/src/polkitbackend/polkitbackendsessionmonitor.c
+++ b/src/polkitbackend/polkitbackendsessionmonitor.c
@@ -382,13 +382,10 @@ polkit_backend_session_monitor_get_user_for_subject (PolkitBackendSessionMonitor
   if (POLKIT_IS_UNIX_PROCESS (subject))
     {
       pid_t pid;
-      gchar *proc_path;
-      struct stat statbuf;
 
       pid = polkit_unix_process_get_pid (POLKIT_UNIX_PROCESS (subject));
 
-      proc_path = g_strdup_printf ("/proc/%d", pid);
-      if (g_stat (proc_path, &statbuf) != 0)
+      if (polkit_unix_pid_get_uid (pid, &uid) != 0)
         {
           g_set_error (error,
                        POLKIT_ERROR,
@@ -397,7 +394,7 @@ polkit_backend_session_monitor_get_user_for_subject (PolkitBackendSessionMonitor
                        pid);
           goto out;
         }
-      user = polkit_unix_user_new (statbuf.st_uid);
+      user = polkit_unix_user_new (uid);
     }
   else if (POLKIT_IS_UNIX_SESSION (subject))
     {
diff --git a/src/programs/pkexec.c b/src/programs/pkexec.c
index 55a053f..8f9efdf 100644
--- a/src/programs/pkexec.c
+++ b/src/programs/pkexec.c
@@ -35,6 +35,18 @@
 
 #include <polkit/polkit.h>
 
+#ifndef HAVE_CLEARENV
+extern char **environ;
+
+static int
+clearenv (void)
+{
+        if (environ != NULL)
+                environ[0] = NULL;
+        return 0;
+}
+#endif
+
 static void
 usage (int argc, char *argv[])
 {
@@ -188,8 +200,8 @@ main (int argc, char *argv[])
   GPtrArray *saved_env;
   gchar *opt_user;
   pid_t pid_of_caller;
+  uid_t uid_of_caller;
   struct stat statbuf;
-  gchar procbuf[32];
 
   ret = 127;
   authority = NULL;
@@ -286,7 +298,7 @@ main (int argc, char *argv[])
     }
   if (stat (path, &statbuf) != 0)
     {
-      g_printerr ("Error getting information about %s: %m\n", path);
+      g_printerr ("Error getting information about %s: %s\n", path, g_strerror (errno));
       goto out;
     }
   command_line = g_strjoinv (" ", argv + n);
@@ -312,14 +324,14 @@ main (int argc, char *argv[])
    */
   if (clearenv () != 0)
     {
-      g_printerr ("Error clearing environment: %m\n");
+      g_printerr ("Error clearing environment: %s\n", g_strerror (errno));
       goto out;
     }
 
   /* Look up information about the user we care about */
   if (getpwnam_r (opt_user, &pwstruct, pwbuf, sizeof pwbuf, &pw) != 0)
     {
-      g_printerr ("Error getting information for user %s: %m\n", opt_user);
+      g_printerr ("Error getting information for user %s: %s\n", opt_user, g_strerror (errno));
       goto out;
     }
 
@@ -340,15 +352,14 @@ main (int argc, char *argv[])
     }
 
   /* paranoia: check that the uid of pid_of_caller matches getuid() */
-  g_snprintf (procbuf, sizeof procbuf, "/proc/%d", pid_of_caller);
-  if (stat (procbuf, &statbuf) != 0)
+  if (polkit_unix_pid_get_uid (pid_of_caller, &uid_of_caller) != 0)
     {
-      g_printerr ("Error determing pid of caller (pid %d): %m\n", (gint) pid_of_caller);
+      g_printerr ("Error determing pid of caller (pid %d): %s\n", (gint) pid_of_caller, g_strerror (errno));
       goto out;
     }
-  if (statbuf.st_uid != getuid ())
+  if (uid_of_caller != getuid ())
     {
-      g_printerr ("User of caller (%d) does not match our uid (%d)\n", statbuf.st_uid, getuid ());
+      g_printerr ("User of caller (%d) does not match our uid (%d)\n", uid_of_caller, getuid ());
       goto out;
     }
 
@@ -426,9 +437,10 @@ main (int argc, char *argv[])
 
       if (!g_setenv (key, value, TRUE))
         {
-          g_printerr ("Error setting environment variable %s to '%s': %m\n",
+          g_printerr ("Error setting environment variable %s to '%s': %s\n",
                       key,
-                      value);
+                      value,
+                      g_strerror (errno));
           goto out;
         }
     }
@@ -446,7 +458,7 @@ main (int argc, char *argv[])
       setreuid (0, 0);
       if ((geteuid () != 0) || (getuid () != 0))
         {
-          g_printerr ("Error becoming uid 0: %m\n");
+          g_printerr ("Error becoming uid 0: %s\n", g_strerror (errno));
           goto out;
         }
     }
@@ -454,12 +466,12 @@ main (int argc, char *argv[])
   /* become the user */
   if (setgroups (0, NULL) != 0)
     {
-      g_printerr ("Error setting groups: %m\n");
+      g_printerr ("Error setting groups: %s\n", g_strerror (errno));
       goto out;
     }
   if (initgroups (pw->pw_name, pw->pw_gid) != 0)
     {
-      g_printerr ("Error initializing groups for %s: %m\n", pw->pw_name);
+      g_printerr ("Error initializing groups for %s: %s\n", pw->pw_name, g_strerror (errno));
       goto out;
     }
   setregid (pw->pw_gid, pw->pw_gid);
@@ -467,21 +479,21 @@ main (int argc, char *argv[])
   if ((geteuid () != pw->pw_uid) || (getuid () != pw->pw_uid) ||
       (getegid () != pw->pw_gid) || (getgid () != pw->pw_gid))
     {
-      g_printerr ("Error becoming real+effective uid %d and gid %d: %m\n", pw->pw_uid, pw->pw_gid);
+      g_printerr ("Error becoming real+effective uid %d and gid %d: %s\n", pw->pw_uid, pw->pw_gid, g_strerror (errno));
       goto out;
     }
 
   /* change to home directory */
   if (chdir (pw->pw_dir) != 0)
     {
-      g_printerr ("Error changing to home directory %s: %m\n", pw->pw_dir);
+      g_printerr ("Error changing to home directory %s: %s\n", pw->pw_dir, g_strerror (errno));
       goto out;
     }
 
   /* exec the program */
   if (execv (path, exec_argv) != 0)
     {
-      g_printerr ("Error executing %s: %m\n", path);
+      g_printerr ("Error executing %s: %s\n", path, g_strerror (errno));
       goto out;
     }
 


More information about the hal-commit mailing list