Commit 40c8b8ae authored by Joe Clarke's avatar Joe Clarke Committed by David Zeuthen
Browse files

add support for FreeBSD

On Mon, 2008-04-21 at 15:06 -0400, David Zeuthen wrote:
> On Sat, 2008-04-19 at 01:34 -0400, Joe Marcus Clarke wrote:
> > I'm seeing a few PK problems on FreeBSD, but I'm not sure if this is a
> > problem with our port, or an issue in general.  First, all of the tests
> > David mentioned earlier (with polkit-auth) work.  The built-in tests
> > also appear to work.  PK consumers also seem to work.
> >
> > What I'm noticing is that PolicyKit-gnome doesn't update in real-time.
> > For example, if I launch polkit-gnome-authorization, then change a
> > policy, the changes don't reflect in the GUI until I restart
> > polkit-gnome-authorization.  Also, I'm not seeing any UI changes in
> > polkit-gnome-example when I click on the various buttons (though
> > polkit-gnome-manager does launch).
>
> This suggests that file monitoring of /var/lib/misc/PolicyKit.reload is
> somehow botched. Is polkit_context_io_func() in polkit-context.c ever
> called if you do
>
>  # touch /var/lib/misc/PolicyKit.reload
>
> Is it called if you manually grant/revoke an authorization using
> polkit-auth(1)? (And does /var/lib/misc/PolicyKit.reload change mtime
> in that case?)

Thanks for your advice.  I was not monitoring the reload file for
attribute changes, so I was missing the mtime change.  That is working
now.

I updated the PK diff with the portability fix.  I didn't actually use
the Solaris code as it caused a slew of compiler warnings and other
problems.  Instead, I went with creating a kit-lib.[ch] to store the
missing functions.  As for strndup(), I stuck that in kit-string.c.  I
wrapped all of these functions with configure checks to avoid
hard-coding OS checks.  This should make it easier to port PK to other
platforms.

I would still like your advice on the IO problem with PK-gnome.  I have
changed io_watch_have_data() in polkit-gnome-manager.c to return FALSE
instead of TRUE to auto-remove the IO watch.  As I said, FreeBSD's
poll() continuously indicates EOF as a G_IO_IN condition until it is
handled.  By returning FALSE here, the infinite loop is fixed, and I
didn't notice any other problems.

What problems could this cause?  Is there a better way of handling this?
Thanks.

http://www.marcuscom.com/downloads/pk/

Joe

--
Joe Marcus Clarke
FreeBSD GNOME Team      ::      gnome@FreeBSD.org
FreeNode / #freebsd-gnome
http://www.FreeBSD.org/gnome
parent b9c851f1
......@@ -179,7 +179,7 @@ PKG_CHECK_MODULES(DBUS_GLIB, [dbus-glib-1 >= 0.73])
AC_SUBST(DBUS_GLIB_CFLAGS)
AC_SUBST(DBUS_GLIB_LIBS)
AC_CHECK_FUNCS(getgrouplist)
AC_CHECK_FUNCS(getgrouplist readdir64 getline strndup clearenv)
EXPAT_LIB=""
AC_ARG_WITH(expat, [ --with-expat=<dir> Use expat from here],
......@@ -471,7 +471,8 @@ AM_CONDITIONAL(OS_TYPE_RED_HAT, test x$with_os_type = xredhat, [Running on Red H
AM_CONDITIONAL(OS_TYPE_SUSE, test x$with_os_type = xsuse, [Running on SUSE OS'es])
AM_CONDITIONAL(OS_TYPE_GENTOO, test x$with_os_type = xgentoo, [Running on Gentoo OS'es])
AM_CONDITIONAL(OS_TYPE_PARDUS, test x$with_os_type = xpardus, [Running on Pardus OS'es])
AM_CONDITIONAL(OS_TYPE_SALARIS, test x$with_os_type = xsolaris, [Running os Solaris OS'es])
AM_CONDITIONAL(OS_TYPE_SOLARIS, test x$with_os_type = xsolaris, [Running os Solaris OS'es])
AM_CONDITIONAL(OS_TYPE_FREEBSD, test x$with_os_type = xfreebsd, [Running on FreeBSD OS'es])
AC_ARG_WITH(pam-include, [ --with-pam-include=<file> pam file to include])
......@@ -491,6 +492,11 @@ elif test x$with_os_type = xsuse -o x$with_os_type = xsolaris ; then
PAM_FILE_INCLUDE_ACCOUNT=common-account
PAM_FILE_INCLUDE_PASSWORD=common-password
PAM_FILE_INCLUDE_SESSION=common-session
elif test x$with_os_type = xfreebsd ; then
PAM_FILE_INCLUDE_AUTH=system
PAM_FILE_INCLUDE_ACCOUNT=system
PAM_FILE_INCLUDE_PASSWORD=system
PAM_FILE_INCLUDE_SESSION=system
else
PAM_FILE_INCLUDE_AUTH=system-auth
PAM_FILE_INCLUDE_ACCOUNT=system-auth
......@@ -516,8 +522,30 @@ case "$host_os" in
*solaris*)
AC_DEFINE([HAVE_SOLARIS], 1, [Is this a Solaris system?])
;;
*freebsd*)
AC_DEFINE([HAVE_FREEBSD], 1, [Is this a FreeBSD system?])
;;
esac
have_inotify=no
AC_CHECK_HEADERS([linux/inotify.h], [have_inotify=yes])
AC_CHECK_HEADERS([sys/inotify.h], [have_inotify=yes])
AM_CONDITIONAL(HAVE_INOTIFY, test "x$have_inotify" = "xyes")
if test "x$have_inotify" = "xyes" ; then
AC_DEFINE([HAVE_INOTIFY], 1, [Enable Linux inotify() usage])
fi
have_kqueue=yes
AC_CHECK_FUNCS([kqueue],,have_kqueue=no)
AM_CONDITIONAL(HAVE_KQUEUE, test "x$have_kqueue" = "xyes")
if test "x$have_kqueue" = "xyes" ; then
AC_DEFINE([HAVE_KQUEUE], 1, [Enable BSD kqueue() usage])
fi
# ********************
# Internationalisation
# ********************
......
......@@ -23,6 +23,7 @@ libkit_la_SOURCES = \
kit-test.h kit-test.c \
kit-memory.h kit-memory.c \
kit-string.h kit-string.c \
kit-lib.h kit-lib.c \
kit-list.h kit-list.c \
kit-hash.h kit-hash.c \
kit-file.h kit-file.c \
......
......@@ -283,7 +283,11 @@ _kit_get_num_fd (void)
DIR *dir;
char buf[128];
ssize_t num;
#ifdef HAVE_READDIR64
struct dirent64 *d;
#else
struct dirent *d;
#endif
num = -1;
......@@ -296,7 +300,11 @@ _kit_get_num_fd (void)
}
num = -2;
#ifdef HAVE_READDIR64
while ((d = readdir64 (dir)) != NULL) {
#else
while ((d = readdir (dir)) != NULL) {
#endif
if (d->d_name == NULL)
continue;
num++;
......
......@@ -34,6 +34,7 @@
#ifndef KIT_FILE_H
#define KIT_FILE_H
#include <sys/stat.h>
#include <kit/kit.h>
#ifdef HAVE_SOLARIS
#include <sys/types.h>
......
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
/***************************************************************************
*
* kit-lib.c : General utilities
*
* Copyright (C) 2007 David Zeuthen, <david@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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <kit/kit.h>
#include "kit-test.h"
#ifndef HAVE_GETLINE
ssize_t
kit_getline (char **lineptr, size_t *n, FILE *stream)
{
char *line, *p;
long size, copy;
if (lineptr == NULL || n == NULL) {
errno = EINVAL;
return (ssize_t) -1;
}
if (ferror (stream))
return (ssize_t) -1;
/* Make sure we have a line buffer to start with. */
if (*lineptr == NULL || *n < 2) /* !seen and no buf yet need 2 chars. */ {
#ifndef MAX_CANON
#define MAX_CANON 256
#endif
if (!*lineptr)
line = (char *) malloc (MAX_CANON);
else
line = (char *) realloc (*lineptr, MAX_CANON);
if (line == NULL)
return (ssize_t) -1;
*lineptr = line;
*n = MAX_CANON;
}
line = *lineptr;
size = *n;
copy = size;
p = line;
while (1) {
long len;
while (--copy > 0) {
int c = getc (stream);
if (c == EOF)
goto lose;
else if ((*p++ = c) == '\n')
goto win;
}
/* Need to enlarge the line buffer. */
len = p - line;
size *= 2;
line = (char *) realloc (line, size);
if (line == NULL)
goto lose;
*lineptr = line;
*n = size;
p = line + len;
copy = size - len;
}
lose:
if (p == *lineptr)
return (ssize_t) -1;
/* Return a partial line since we got an error in the middle. */
win:
*p = '\0';
return p - *lineptr;
}
#else
ssize_t
kit_getline (char **lineptr, size_t *n, FILE *f)
{
return getline (lineptr, n, f);
}
#endif
#ifndef HAVE_CLEARENV
extern char **environ;
int
kit_clearenv (void)
{
if (environ != NULL)
environ[0] = NULL;
return 0;
}
#else
int
kit_clearenv (void)
{
return clearenv ();
}
#endif
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
/***************************************************************************
*
* kit-string.h : General utilities
*
* Copyright (C) 2007 David Zeuthen, <david@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_LIB_H
#define KIT_LIB_H
#include <sys/types.h>
#include <stdio.h>
#include <kit/kit.h>
KIT_BEGIN_DECLS
ssize_t kit_getline (char **lineptr, size_t *n, FILE *f);
int kit_clearenv (void);
KIT_END_DECLS
#endif /* KIT_LIB_H */
......@@ -40,6 +40,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <kit/kit.h>
#include "kit-test.h"
......
......@@ -113,6 +113,28 @@ out:
#else
#ifndef HAVE_STRNDUP
static char
*strndup ( const char *s, size_t n)
{
size_t nAvail;
char *p;
if ( !s )
return NULL;
if ( strlen(s) > n )
nAvail = n + 1;
else
nAvail = strlen(s) + 1;
p = malloc ( nAvail );
memcpy ( p, s, nAvail );
p[nAvail - 1] = '\0';
return p;
}
#endif
char *
kit_strdup (const char *s)
{
......
......@@ -148,6 +148,7 @@ do {
#endif
#include <kit/kit-memory.h>
#include <kit/kit-string.h>
#include <kit/kit-lib.h>
#include <kit/kit-list.h>
#include <kit/kit-hash.h>
#include <kit/kit-file.h>
......
......@@ -39,6 +39,7 @@
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <grp.h>
#include <pwd.h>
......@@ -159,7 +160,11 @@ dump_auths_all (const char *root)
{
DIR *dir;
int dfd;
#ifdef HAVE_READDIR64
struct dirent64 *d;
#else
struct dirent *d;
#endif
polkit_bool_t ret;
ret = FALSE;
......@@ -176,7 +181,11 @@ dump_auths_all (const char *root)
goto out;
}
#ifdef HAVE_READDIR64
while ((d = readdir64(dir)) != NULL) {
#else
while ((d = readdir(dir)) != NULL) {
#endif
unsigned int n, m;
uid_t uid;
size_t name_len;
......@@ -291,15 +300,8 @@ main (int argc, char *argv[])
#ifndef POLKIT_BUILD_TESTS
/* clear the entire environment to avoid attacks using with libraries honoring environment variables */
#ifdef HAVE_SOLARIS
extern char **environ;
if (environ != NULL)
environ[0] = NULL;
#else
if (clearenv () != 0)
if (kit_clearenv () != 0)
goto out;
#endif
/* set a minimal environment */
setenv ("PATH", "/usr/sbin:/usr/bin:/sbin:/bin", 1);
#endif
......
......@@ -40,6 +40,9 @@
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef HAVE_FREEBSD
#include <sys/param.h>
#endif
#include <security/pam_appl.h>
#include <grp.h>
#include <pwd.h>
......@@ -76,15 +79,8 @@ main (int argc, char *argv[])
ret = 1;
/* clear the entire environment to avoid attacks using with libraries honoring environment variables */
#ifdef HAVE_SOLARIS
extern char **environ;
if (environ != NULL)
environ[0] = NULL;
#else
if (clearenv () != 0)
if (kit_clearenv () != 0)
goto out;
#endif
/* set a minimal environment */
setenv ("PATH", "/usr/sbin:/usr/bin:/sbin:/bin", 1);
......
......@@ -128,15 +128,8 @@ main (int argc, char *argv[])
ret = 1;
/* clear the entire environment to avoid attacks using with libraries honoring environment variables */
#ifdef HAVE_SOLARIS
extern char **environ;
if (environ != NULL)
environ[0] = NULL;
#else
if (clearenv () != 0)
if (kit_clearenv () != 0)
goto out;
#endif
/* set a minimal environment */
setenv ("PATH", "/usr/sbin:/usr/bin:/sbin:/bin", 1);
......
......@@ -60,7 +60,7 @@ polkit_grant_helper_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ $(top_builddir)/src/polkit/l
if POLKIT_AUTHFW_PAM
polkit_grant_helper_pam_SOURCES = polkit-grant-helper-pam.c
polkit_grant_helper_pam_LDADD = @AUTH_LIBS@
polkit_grant_helper_pam_LDADD = @AUTH_LIBS@ $(top_builddir)/src/polkit/libpolkit.la
endif
if POLKIT_AUTHFW_SHADOW
......
......@@ -70,15 +70,8 @@ main (int argc, char *argv[])
ret = 1;
/* clear the entire environment to avoid attacks using with libraries honoring environment variables */
#ifdef HAVE_SOLARIS
extern char **environ;
if (environ != NULL)
environ[0] = NULL;
#else
if (clearenv () != 0)
if (kit_clearenv () != 0)
goto out;
#endif
/* set a minimal environment */
setenv ("PATH", "/usr/sbin:/usr/bin:/sbin:/bin", 1);
......
......@@ -41,6 +41,8 @@
#include <syslog.h>
#include <security/pam_appl.h>
#include <kit/kit.h>
#ifdef HAVE_SOLARIS
#define LOG_AUTHPRIV (10<<3)
#endif
......@@ -67,15 +69,8 @@ main (int argc, char *argv[])
pam_h = NULL;
/* clear the entire environment to avoid attacks using with libraries honoring environment variables */
#ifdef HAVE_SOLARIS
extern char **environ;
if (environ != NULL)
environ[0] = NULL;
#else
if (clearenv () != 0)
if (kit_clearenv () != 0)
goto error;
#endif
/* set a minimal environment */
setenv ("PATH", "/usr/sbin:/usr/bin:/sbin:/bin", 1);
......
......@@ -57,6 +57,8 @@
#include <glib.h>
#include <kit/kit.h>
#include <polkit-dbus/polkit-dbus.h>
// #include <polkit/polkit-grant-database.h>
......@@ -564,15 +566,8 @@ main (int argc, char *argv[])
ret = 3;
/* clear the entire environment to avoid attacks using with libraries honoring environment variables */
#ifdef HAVE_SOLARIS
extern char **environ;
if (environ != NULL)
environ[0] = NULL;
#else
if (clearenv () != 0)
if (kit_clearenv () != 0)
goto out;
#endif
/* set a minimal environment */
setenv ("PATH", "/usr/sbin:/usr/bin:/sbin:/bin", 1);
......
......@@ -39,6 +39,7 @@
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <glib.h>
#include "polkit-grant.h"
......@@ -302,7 +303,7 @@ polkit_grant_io_func (PolKitGrant *polkit_grant, int fd)
g_return_if_fail (polkit_grant != NULL);
g_return_if_fail (polkit_grant->helper_is_running);
while (getline (&line, &line_len, polkit_grant->child_stdout_f) != -1) {
while (kit_getline (&line, &line_len, polkit_grant->child_stdout_f) != -1) {
if (strlen (line) > 0 &&
line[strlen (line) - 1] == '\n')
line[strlen (line) - 1] = '\0';
......@@ -543,49 +544,6 @@ error:
return FALSE;
}
#ifdef HAVE_SOLARIS
#define BUFFER_LEN 256
ssize_t getline (char **lineptr, size_t *n, FILE *f)
{
char ch;
size_t m = 0;
ssize_t buf_len = 0;
char * buf = NULL;
char * p = NULL;
while ( (ch = getc(f)) !=EOF )
{
if (errno != 0)
return -1;
if ( m++ >= buf_len )
{
buf_len += BUFFER_LEN;
buf = (char *) realloc(buf, buf_len + 1);
if ( buf == NULL )
{
return -1;
}
p = buf + buf_len - BUFFER_LEN;
}
if ( ch == '\n' )
break;
*p = ch;
p++;
}
if ( m == 0 )
{
return -1;
} else {
*p = '\0';
*lineptr = buf;
*n = m;
return m;
}
}
#endif
#ifdef POLKIT_BUILD_TESTS
static polkit_bool_t
......
......@@ -112,15 +112,8 @@ main (int argc, char *argv[])
#ifndef POLKIT_BUILD_TESTS
/* clear the entire environment to avoid attacks using with libraries honoring environment variables */
#ifdef HAVE_SOLARIS
extern char **environ;
if (environ != NULL)
environ[0] = NULL;
#else
if (clearenv () != 0)
if (kit_clearenv () != 0)
goto out;
#endif
/* set a minimal environment */
setenv ("PATH", "/usr/sbin:/usr/bin:/sbin:/bin", 1);
#endif
......
......@@ -39,7 +39,6 @@
#include <grp.h>
#include <unistd.h>
#include <errno.h>
#include <sys/inotify.h>
#include <regex.h>
#include <syslog.h>
#include <regex.h>
......
......@@ -43,7 +43,13 @@
#include <port.h>
#include <sys/stat.h>
#else
#ifdef HAVE_INOTIFY
#include <sys/inotify.h>
#elif HAVE_KQUEUE
#include <sys/event.h>
#include <sys/time.h>
#include <fcntl.h>
#endif
#endif
#include <syslog.h>
......@@ -111,11 +117,19 @@ struct _PolKitContext
polkit_bool_t load_descriptions;
#ifdef HAVE_INOTIFY
int inotify_fd;
int inotify_fd_watch_id;
int inotify_config_wd;