[PATCH] libcreds patch
Markku Savela (none)
msa at moth.iki.fi
Thu Jan 14 03:58:19 PST 2010
From: Markku Savela <msa at moth.iki.fi>
---
bus/config-parser.c | 58 +++++++++++++++++++++++++++++++----
bus/policy.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++
bus/policy.h | 14 ++++++++
configure.in | 23 +++++++++++++-
4 files changed, 169 insertions(+), 9 deletions(-)
diff --git a/bus/config-parser.c b/bus/config-parser.c
index d8ae459..e487a71 100644
--- a/bus/config-parser.c
+++ b/bus/config-parser.c
@@ -20,6 +20,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
+#ifdef DBUS_BUS_ENABLE_CREDS
+#include <err.h>
+#include <limits.h>
+#include <sys/creds.h>
+#endif
#include "config-parser-common.h"
#include "config-parser.h"
#include "test.h"
@@ -40,6 +45,9 @@ typedef enum
POLICY_MANDATORY,
POLICY_USER,
POLICY_GROUP,
+#ifdef DBUS_BUS_ENABLE_CREDS
+ POLICY_CREDS,
+#endif
POLICY_CONSOLE
} PolicyType;
@@ -968,6 +976,9 @@ start_busconfig_child (BusConfigParser *parser,
const char *context;
const char *user;
const char *group;
+#ifdef DBUS_BUS_ENABLE_CREDS
+ const char *creds;
+#endif
const char *at_console;
if ((e = push_element (parser, ELEMENT_POLICY)) == NULL)
@@ -985,17 +996,20 @@ start_busconfig_child (BusConfigParser *parser,
"context", &context,
"user", &user,
"group", &group,
+#ifdef DBUS_BUS_ENABLE_CREDS
+ "creds", &creds,
+#endif
"at_console", &at_console,
NULL))
return FALSE;
- if (((context && user) ||
- (context && group) ||
- (context && at_console)) ||
- ((user && group) ||
- (user && at_console)) ||
- (group && at_console) ||
- !(context || user || group || at_console))
+ if ((context != NULL) +
+ (user != NULL) +
+ (group != NULL) +
+#ifdef DBUS_BUS_ENABLE_CREDS
+ (creds != NULL) +
+#endif
+ (at_console != NULL) != 1)
{
dbus_set_error (error, DBUS_ERROR_FAILED,
"<policy> element must have exactly one of (context|user|group|at_console) attributes");
@@ -1044,6 +1058,22 @@ start_busconfig_child (BusConfigParser *parser,
_dbus_warn ("Unknown group \"%s\" in message bus configuration file\n",
group);
}
+#ifdef DBUS_BUS_ENABLE_CREDS
+ else if (creds != NULL)
+ {
+ creds_type_t type;
+ creds_value_t value;
+ type = creds_str2creds(creds, &value);
+ if (type != CREDS_BAD && (value & ~CREDS_MASK) == 0)
+ {
+ e->d.policy.type = POLICY_CREDS;
+ e->d.policy.gid_uid_or_at_console = CREDS_KEY(type,value);
+ }
+ else
+ _dbus_warn("Unable to translate credential \"%s\" in message bus configuration file\n",
+ creds);
+ }
+#endif
else if (at_console != NULL)
{
dbus_bool_t t;
@@ -1615,7 +1645,21 @@ append_rule_from_element (BusConfigParser *parser,
goto nomem;
break;
+#ifdef DBUS_BUS_ENABLE_CREDS
+ case POLICY_CREDS:
+ if (!BUS_POLICY_RULE_IS_PER_CLIENT (rule))
+ {
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "<%s> rule cannot be per-group because it has bus-global semantics",
+ element_name);
+ goto failed;
+ }
+ if (!bus_policy_append_creds_rule (parser->policy, pe->d.policy.gid_uid_or_at_console,
+ rule))
+ goto nomem;
+ break;
+#endif
case POLICY_CONSOLE:
if (!bus_policy_append_console_rule (parser->policy, pe->d.policy.gid_uid_or_at_console,
rule))
diff --git a/bus/policy.c b/bus/policy.c
index bc1d2d9..cf72622 100644
--- a/bus/policy.c
+++ b/bus/policy.c
@@ -21,6 +21,10 @@
*
*/
+#ifdef DBUS_BUS_ENABLE_CREDS
+#include <limits.h>
+#include <sys/creds.h>
+#endif
#include "policy.h"
#include "services.h"
#include "test.h"
@@ -129,6 +133,9 @@ struct BusPolicy
DBusList *mandatory_rules; /**< Mandatory policy rules */
DBusHashTable *rules_by_uid; /**< per-UID policy rules */
DBusHashTable *rules_by_gid; /**< per-GID policy rules */
+#ifdef DBUS_BUS_ENABLE_CREDS
+ DBusHashTable *rules_by_creds; /**< per-CREDS policy rules */
+#endif
DBusList *at_console_true_rules; /**< console user policy rules where at_console="true"*/
DBusList *at_console_false_rules; /**< console user policy rules where at_console="false"*/
};
@@ -180,6 +187,15 @@ bus_policy_new (void)
if (policy->rules_by_gid == NULL)
goto failed;
+#ifdef DBUS_BUS_ENABLE_CREDS
+ policy->rules_by_creds = _dbus_hash_table_new (DBUS_HASH_ULONG,
+ NULL,
+ free_rule_list_func);
+ if (policy->rules_by_creds == NULL)
+ goto failed;
+
+#endif
+
return policy;
failed:
@@ -229,6 +245,14 @@ bus_policy_unref (BusPolicy *policy)
_dbus_hash_table_unref (policy->rules_by_gid);
policy->rules_by_gid = NULL;
}
+
+#ifdef DBUS_BUS_ENABLE_CREDS
+ if (policy->rules_by_creds)
+ {
+ _dbus_hash_table_unref (policy->rules_by_creds);
+ policy->rules_by_creds = NULL;
+ }
+#endif
dbus_free (policy);
}
@@ -320,6 +344,37 @@ bus_policy_create_client_policy (BusPolicy *policy,
dbus_free (groups);
}
+
+#ifdef DBUS_BUS_ENABLE_CREDS
+ if (_dbus_hash_table_get_n_entries (policy->rules_by_creds) > 0)
+ {
+ unsigned long pid;
+ creds_t creds;
+ DBusHashIter iter;
+
+ if (!dbus_connection_get_unix_process_id(connection, &pid))
+ goto failed;
+ creds = creds_gettask(pid);
+ if (creds == NULL)
+ goto failed;
+ _dbus_hash_iter_init(policy->rules_by_creds, &iter);
+ while (_dbus_hash_iter_next(&iter))
+ {
+ unsigned long id = _dbus_hash_iter_get_ulong_key (&iter);
+ DBusList **list = _dbus_hash_iter_get_value(&iter);
+
+ if (list != NULL && creds_have_p(creds, CREDS_TYPE(id), CREDS_VALUE(id)))
+ {
+ if (!add_list_to_client(list, client))
+ {
+ creds_free(creds);
+ goto nomem;
+ }
+ }
+ }
+ creds_free(creds);
+ }
+#endif
if (dbus_connection_get_unix_user (connection, &uid))
{
@@ -575,6 +630,28 @@ bus_policy_append_group_rule (BusPolicy *policy,
return TRUE;
}
+#ifdef DBUS_BUS_ENABLE_CREDS
+dbus_bool_t
+bus_policy_append_creds_rule (BusPolicy *policy,
+ long cid,
+ BusPolicyRule *rule)
+{
+ DBusList **list;
+
+ list = get_list (policy->rules_by_creds, cid);
+
+ if (list == NULL)
+ return FALSE;
+
+ if (!_dbus_list_append (list, rule))
+ return FALSE;
+
+ bus_policy_rule_ref (rule);
+
+ return TRUE;
+}
+#endif
+
dbus_bool_t
bus_policy_append_console_rule (BusPolicy *policy,
dbus_bool_t at_console,
@@ -683,6 +760,12 @@ bus_policy_merge (BusPolicy *policy,
if (!merge_id_hash (policy->rules_by_gid,
to_absorb->rules_by_gid))
return FALSE;
+#ifdef DBUS_BUS_ENABLE_CREDS
+
+ if (!merge_id_hash (policy->rules_by_creds,
+ to_absorb->rules_by_creds))
+ return FALSE;
+#endif
return TRUE;
}
diff --git a/bus/policy.h b/bus/policy.h
index 1782dbf..ca8b805 100644
--- a/bus/policy.h
+++ b/bus/policy.h
@@ -128,6 +128,20 @@ dbus_bool_t bus_policy_append_user_rule (BusPolicy *policy,
dbus_bool_t bus_policy_append_group_rule (BusPolicy *policy,
dbus_gid_t gid,
BusPolicyRule *rule);
+#ifdef DBUS_BUS_ENABLE_CREDS
+/* ..to enable use of the hash lists with long key, define some
+ constants to pack creds type and value into a long. This is
+ a temp solution, should really have a hashlist with two longs
+ as a key */
+#define CREDS_MASK (~0UL >> 3)
+#define CREDS_SHIFT (CHAR_BIT * sizeof(long) - 3)
+#define CREDS_KEY(type,value) (((value) & CREDS_MASK) | ((type) << CREDS_SHIFT))
+#define CREDS_TYPE(hashkey) (((hashkey) & ~CREDS_MASK) >> CREDS_SHIFT)
+#define CREDS_VALUE(hashkey) ((hashkey) & CREDS_MASK)
+dbus_bool_t bus_policy_append_creds_rule (BusPolicy *policy,
+ long cid,
+ BusPolicyRule *rule);
+#endif
dbus_bool_t bus_policy_append_console_rule (BusPolicy *policy,
dbus_bool_t at_console,
BusPolicyRule *rule);
diff --git a/configure.in b/configure.in
index 1f2c896..1fee781 100644
--- a/configure.in
+++ b/configure.in
@@ -112,6 +112,7 @@ AC_ARG_ENABLE(inotify, AS_HELP_STRING([--enable-inotify],[build with inotify sup
AC_ARG_ENABLE(kqueue, AS_HELP_STRING([--enable-kqueue],[build with kqueue support]),enable_kqueue=$enableval,enable_kqueue=auto)
AC_ARG_ENABLE(console-owner-file, AS_HELP_STRING([--enable-console-owner-file],[enable console owner file]),enable_console_owner_file=$enableval,enable_console_owner_file=auto)
AC_ARG_ENABLE(userdb-cache, AS_HELP_STRING([--enable-userdb-cache],[build with userdb-cache support]),enable_userdb_cache=$enableval,enable_userdb_cache=yes)
+AC_ARG_ENABLE(creds, AS_HELP_STRING([--enable-creds],[add process credentials based policy checks (linux only)]),enable_creds=$enableval,enable_creds=auto)
AC_ARG_WITH(xml, AS_HELP_STRING([--with-xml=[libxml/expat]],[XML library to use]))
AC_ARG_WITH(init-scripts, AS_HELP_STRING([--with-init-scripts=[redhat]],[Style of init scripts to install]))
@@ -889,6 +890,24 @@ if test x$have_libaudit = xyes ; then
AC_DEFINE(HAVE_LIBAUDIT,1,[audit daemon SELinux support])
fi
+# creds checks
+if test x$enable_creds = xno ; then
+ have_creds=no;
+else
+ have_creds=yes;
+ AC_CHECK_HEADERS(sys/creds.h, have_creds=yes, have_creds=no)
+ if test x$have_creds = xyes ; then
+ AC_CHECK_LIB(creds, creds_gettask,
+ have_creds=yes, have_libcreds=no)
+ fi
+fi
+
+AM_CONDITIONAL(DBUS_BUS_ENABLE_CREDS, test x$have_creds = xyes)
+if test x$have_creds = xyes ; then
+ CREDS_LIBS="-lcreds"
+ CREDS_CFLAGS="-DDBUS_BUS_ENABLE_CREDS"
+fi
+
# Check for ADT API
AC_MSG_CHECKING(for ADT API)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
@@ -928,8 +947,8 @@ DBUS_CLIENT_LIBS="$THREAD_LIBS $NETWORK_libs"
AC_SUBST(DBUS_CLIENT_CFLAGS)
AC_SUBST(DBUS_CLIENT_LIBS)
-DBUS_BUS_CFLAGS="$XML_CFLAGS"
-DBUS_BUS_LIBS="$XML_LIBS $SELINUX_LIBS $INTLLIBS $THREAD_LIBS $ADT_LIBS $NETWORK_libs"
+DBUS_BUS_CFLAGS="$XML_CFLAGS $CREDS_CFLAGS"
+DBUS_BUS_LIBS="$XML_LIBS $SELINUX_LIBS $INTLLIBS $THREAD_LIBS $ADT_LIBS $NETWORK_libs $CREDS_LIBS"
AC_SUBST(DBUS_BUS_CFLAGS)
AC_SUBST(DBUS_BUS_LIBS)
--
1.6.3.3
More information about the dbus
mailing list