From: Joe Marcus Clarke Date: Wed, 12 Aug 2009 14:04:15 +0000 (-0400) Subject: Bug 23093 – FreeBSD portability fixes X-Git-Tag: 0.94~5 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=de9453f4c178fe76a4a36edb752e2ed75a329032;p=platform%2Fupstream%2Fpolkit.git 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 --- 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 #include +#include #include 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 #include +#include #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 +#ifndef HAVE_FREEBSD +#include +#else +#include +#include +#include +#endif #include #include #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 #include +#include #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 +#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; }