diff -Nur dbus-1.2.1/bus/driver.c dbus-1.2.1-new/bus/driver.c --- dbus-1.2.1/bus/driver.c 2008-04-04 23:24:08.000000000 +0800 +++ dbus-1.2.1-new/bus/driver.c 2008-04-30 17:51:54.749029000 +0800 @@ -34,6 +34,9 @@ #include #include #include +#ifdef HAVE_ADT +#include +#endif static dbus_bool_t bus_driver_send_welcome_message (DBusConnection *connection, DBusMessage *hello_message, @@ -1272,6 +1275,84 @@ return FALSE; } +#ifdef HAVE_ADT +static dbus_bool_t +bus_driver_handle_get_adt_audit_session_data (DBusConnection *connection, + BusTransaction *transaction, + DBusMessage *message, + DBusError *error) +{ + const char *service; + DBusString str; + BusRegistry *registry; + BusService *serv; + DBusConnection *conn; + DBusMessage *reply; + adt_export_data_t *data = NULL; + size_t data_size; + unsigned char *data_bytes = (unsigned char *)&data; + + _DBUS_ASSERT_ERROR_IS_CLEAR (error); + + registry = bus_connection_get_registry (connection); + + service = NULL; + reply = NULL; + + if (! dbus_message_get_args (message, error, + DBUS_TYPE_STRING, &service, + DBUS_TYPE_INVALID)) + goto failed; + + _dbus_verbose ("asked for audit session data for connection %s\n", service); + + _dbus_string_init_const (&str, service); + serv = bus_registry_lookup (registry, &str); + if (serv == NULL) + { + dbus_set_error (error, + DBUS_ERROR_NAME_HAS_NO_OWNER, + "Could not get audit session data for name '%s': no such name", service); + goto failed; + } + + conn = bus_service_get_primary_owners_connection (serv); + + reply = dbus_message_new_method_return (message); + if (reply == NULL) + goto oom; + + if (!dbus_connection_get_adt_audit_session_data (conn, &data, &data_size)) + { + dbus_set_error (error, + DBUS_ERROR_ADT_AUDIT_DATA_UNKNOWN, + "Could not determine audit session data for '%s'", service); + goto failed; + } + + if (! dbus_message_append_args (reply, + DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &data, data_size, + DBUS_TYPE_INVALID)) + goto oom; + + if (! bus_transaction_send_from_driver (transaction, connection, reply)) + goto oom; + + dbus_message_unref (reply); + + return TRUE; + + oom: + BUS_SET_OOM (error); + + failed: + _DBUS_ASSERT_ERROR_IS_SET (error); + if (reply) + dbus_message_unref (reply); + return FALSE; +} +#endif /* HAVE_ADT */ + static dbus_bool_t bus_driver_handle_get_connection_selinux_security_context (DBusConnection *connection, BusTransaction *transaction, @@ -1503,6 +1584,12 @@ DBUS_TYPE_STRING_AS_STRING, DBUS_TYPE_UINT32_AS_STRING, bus_driver_handle_get_connection_unix_process_id }, +#ifdef HAVE_ADT + { "GetAdtAuditSessionData", + DBUS_TYPE_STRING_AS_STRING, + DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING, + bus_driver_handle_get_adt_audit_session_data }, +#endif { "GetConnectionSELinuxSecurityContext", DBUS_TYPE_STRING_AS_STRING, DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING, diff -Nur dbus-1.2.1/configure.in dbus-1.2.1-new/configure.in --- dbus-1.2.1/configure.in 2008-04-05 02:23:23.000000000 +0800 +++ dbus-1.2.1-new/configure.in 2008-04-30 17:47:47.380894000 +0800 @@ -1028,6 +1028,24 @@ AC_DEFINE(HAVE_LIBAUDIT,1,[audit daemon SELinux support]) fi +# Check for ADT API +AC_MSG_CHECKING(for ADT API) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +adt_user_context = ADT_USER; +]], [[]])], [ check_adt_audit=yes ], [ check_adt_audit=no ]) + +if test ${check_adt_audit} = yes +then + AC_DEFINE([HAVE_ADT], [], [Adt audit API]) + ADT_LIBS="-lbsm" + LIBS="-lbsm $LIBS" + AC_MSG_RESULT(yes) +else + AC_MSG_RESULT(no) +fi + + #### Set up final flags DBUS_CLIENT_CFLAGS= DBUS_CLIENT_LIBS="$THREAD_LIBS" @@ -1035,7 +1053,7 @@ AC_SUBST(DBUS_CLIENT_LIBS) DBUS_BUS_CFLAGS="$XML_CFLAGS" -DBUS_BUS_LIBS="$XML_LIBS $SELINUX_LIBS $INTLLIBS $THREAD_LIBS" +DBUS_BUS_LIBS="$XML_LIBS $SELINUX_LIBS $INTLLIBS $THREAD_LIBS $ADT_LIBS" AC_SUBST(DBUS_BUS_CFLAGS) AC_SUBST(DBUS_BUS_LIBS) diff -Nur dbus-1.2.1/dbus/dbus-auth.c dbus-1.2.1-new/dbus/dbus-auth.c --- dbus-1.2.1/dbus/dbus-auth.c 2008-04-04 23:24:08.000000000 +0800 +++ dbus-1.2.1-new/dbus/dbus-auth.c 2008-04-30 17:47:47.382497000 +0800 @@ -1094,6 +1094,15 @@ DBUS_CREDENTIAL_UNIX_PROCESS_ID, auth->credentials)) return FALSE; + +#ifdef HAVE_ADT + /* also copy audit data from the socket credentials + */ + if (!_dbus_credentials_add_credential (auth->authorized_identity, + DBUS_CREDENTIAL_AUDIT_DATA_ID, + auth->credentials)) + return FALSE; +#endif if (!send_ok (auth)) return FALSE; diff -Nur dbus-1.2.1/dbus/dbus-connection.c dbus-1.2.1-new/dbus/dbus-connection.c --- dbus-1.2.1/dbus/dbus-connection.c 2008-04-04 23:24:08.000000000 +0800 +++ dbus-1.2.1-new/dbus/dbus-connection.c 2008-04-30 17:50:48.407069000 +0800 @@ -4963,6 +4963,53 @@ return result; } +#ifdef HAVE_ADT +/** + * Gets the ADT audit data of the connection if any. + * Returns #TRUE if the structure pointer is returned. + * Always returns #FALSE prior to authenticating the + * connection. + * + * @param connection the connection + * @param data return location for audit data + * @returns #TRUE if audit data is filled in with a valid ucred pointer + */ +dbus_bool_t +dbus_connection_get_adt_audit_session_data (DBusConnection *connection, + void **data, + dbus_int32_t *data_size) +{ + dbus_bool_t result; + + _dbus_return_val_if_fail (connection != NULL, FALSE); + _dbus_return_val_if_fail (data != NULL, FALSE); + _dbus_return_val_if_fail (data_size != NULL, FALSE); + + CONNECTION_LOCK (connection); + + if (!_dbus_transport_get_is_authenticated (connection->transport)) + result = FALSE; + else + result = _dbus_transport_get_audit_session_data (connection->transport, + data, + data_size); + CONNECTION_UNLOCK (connection); + + return result; +} +#else +dbus_bool_t +dbus_connection_get_adt_audit_session_data (DBusConnection *connection, + void **data, + dbus_int32_t *data_size) +{ + *data = NULL; + *data_size = NULL; + + return FALSE; +} +#endif /* HAVE_ADT */ + /** * Sets a predicate function used to determine whether a given user ID * is allowed to connect. When an incoming connection has diff -Nur dbus-1.2.1/dbus/dbus-connection.h dbus-1.2.1-new/dbus/dbus-connection.h --- dbus-1.2.1/dbus/dbus-connection.h 2008-04-04 23:24:08.000000000 +0800 +++ dbus-1.2.1-new/dbus/dbus-connection.h 2008-04-30 17:47:47.386606000 +0800 @@ -231,6 +231,9 @@ unsigned long *uid); dbus_bool_t dbus_connection_get_unix_process_id (DBusConnection *connection, unsigned long *pid); +dbus_bool_t dbus_connection_get_adt_audit_session_data (DBusConnection *connection, + void **data, + dbus_int32_t *data_size); void dbus_connection_set_unix_user_function (DBusConnection *connection, DBusAllowUnixUserFunction function, void *data, diff -Nur dbus-1.2.1/dbus/dbus-credentials.c dbus-1.2.1-new/dbus/dbus-credentials.c --- dbus-1.2.1/dbus/dbus-credentials.c 2008-04-04 23:24:08.000000000 +0800 +++ dbus-1.2.1-new/dbus/dbus-credentials.c 2008-04-30 17:47:47.388557000 +0800 @@ -50,6 +50,10 @@ dbus_uid_t unix_uid; dbus_pid_t unix_pid; char *windows_sid; +#ifdef HAVE_ADT + adt_export_data_t *audit_data; + size_t audit_data_size; +#endif }; /** @} */ @@ -77,6 +81,10 @@ creds->unix_uid = DBUS_UID_UNSET; creds->unix_pid = DBUS_PID_UNSET; creds->windows_sid = NULL; +#ifdef HAVE_ADT + creds->audit_data = NULL; + creds->audit_data_size = 0; +#endif return creds; } @@ -129,6 +137,9 @@ if (credentials->refcount == 0) { dbus_free (credentials->windows_sid); +#ifdef HAVE_ADT + dbus_free (credentials->audit_data); +#endif dbus_free (credentials); } } @@ -187,6 +198,33 @@ return TRUE; } +#ifdef HAVE_ADT +/** + * Add ADT audit data to the credentials. + * + * @param credentials the object + * @param audit_data the audit data + * @param audit_data_size the length of audit data + * @returns #FALSE if no memory + */ +dbus_bool_t +_dbus_credentials_add_audit_data (DBusCredentials *credentials, + adt_export_data_t *audit_data, + size_t audit_data_size) +{ + void *copy; + copy = _dbus_memdup (audit_data, audit_data_size); + if (copy == NULL) + return FALSE; + + dbus_free (credentials->audit_data); + credentials->audit_data = copy; + credentials->audit_data_size = audit_data_size; + + return TRUE; +} +#endif /* HAVE_ADT */ + /** * Checks whether the given credential is present. * @@ -206,6 +244,10 @@ return credentials->unix_uid != DBUS_UID_UNSET; case DBUS_CREDENTIAL_WINDOWS_SID: return credentials->windows_sid != NULL; +#ifdef HAVE_ADT + case DBUS_CREDENTIAL_AUDIT_DATA_ID: + return credentials->audit_data != NULL; +#endif } _dbus_assert_not_reached ("Unknown credential enum value"); @@ -251,6 +293,34 @@ return credentials->windows_sid; } +#ifdef HAVE_ADT +/** + * Gets the Solairs audit data in the credentials, or #NULL if + * the credentials object doesn't contain ADT audit data. + * + * @param credentials the object + * @returns Solairs audit data + */ +adt_export_data_t* +_dbus_credentials_get_audit_data (DBusCredentials *credentials) +{ + return credentials->audit_data; +} + +/** + * Gets the ADT audit data size in the credentials, or 0 if + * the credentials object doesn't contain ADT audit data. + * + * @param credentials the object + * @returns Solairs audit data size + */ +size_t +_dbus_credentials_get_audit_data_size (DBusCredentials *credentials) +{ + return credentials->audit_data_size; +} +#endif /* HAVE_ADT */ + /** * Checks whether the first credentials object contains * all the credentials found in the second credentials object. @@ -321,6 +391,11 @@ _dbus_credentials_add_credential (credentials, DBUS_CREDENTIAL_UNIX_USER_ID, other_credentials) && +#ifdef HAVE_ADT + _dbus_credentials_add_credential (credentials, + DBUS_CREDENTIAL_AUDIT_DATA_ID, + other_credentials) && +#endif _dbus_credentials_add_credential (credentials, DBUS_CREDENTIAL_WINDOWS_SID, other_credentials); @@ -360,7 +435,15 @@ { if (!_dbus_credentials_add_windows_sid (credentials, other_credentials->windows_sid)) return FALSE; + } +#ifdef HAVE_ADT + else if (which == DBUS_CREDENTIAL_AUDIT_DATA_ID && + other_credentials->audit_data != NULL) + { + if (!_dbus_credentials_add_audit_data (credentials, other_credentials->audit_data, other_credentials->audit_data_size)) + return FALSE; } +#endif return TRUE; } @@ -377,6 +460,11 @@ credentials->unix_uid = DBUS_UID_UNSET; dbus_free (credentials->windows_sid); credentials->windows_sid = NULL; +#ifdef HAVE_ADT + dbus_free (credentials->audit_data); + credentials->audit_data = NULL; + credentials->audit_data_size = 0; +#endif } /** diff -Nur dbus-1.2.1/dbus/dbus-credentials.h dbus-1.2.1-new/dbus/dbus-credentials.h --- dbus-1.2.1/dbus/dbus-credentials.h 2008-04-04 23:24:08.000000000 +0800 +++ dbus-1.2.1-new/dbus/dbus-credentials.h 2008-04-30 17:47:47.389429000 +0800 @@ -27,12 +27,18 @@ #include #include #include +#ifdef HAVE_ADT +#include +#endif DBUS_BEGIN_DECLS typedef enum { DBUS_CREDENTIAL_UNIX_PROCESS_ID, DBUS_CREDENTIAL_UNIX_USER_ID, +#ifdef HAVE_ADT + DBUS_CREDENTIAL_AUDIT_DATA_ID, +#endif DBUS_CREDENTIAL_WINDOWS_SID } DBusCredentialType; @@ -51,6 +57,10 @@ dbus_pid_t _dbus_credentials_get_unix_pid (DBusCredentials *credentials); dbus_uid_t _dbus_credentials_get_unix_uid (DBusCredentials *credentials); const char* _dbus_credentials_get_windows_sid (DBusCredentials *credentials); +#ifdef HAVE_ADT +adt_export_data_t* _dbus_credentials_get_audit_data (DBusCredentials *credentials); +size_t _dbus_credentials_get_audit_data_size (DBusCredentials *credentials); +#endif dbus_bool_t _dbus_credentials_are_superset (DBusCredentials *credentials, DBusCredentials *possible_subset); dbus_bool_t _dbus_credentials_are_empty (DBusCredentials *credentials); diff -Nur dbus-1.2.1/dbus/dbus-protocol.h dbus-1.2.1-new/dbus/dbus-protocol.h --- dbus-1.2.1/dbus/dbus-protocol.h 2008-04-04 23:24:08.000000000 +0800 +++ dbus-1.2.1-new/dbus/dbus-protocol.h 2008-04-30 17:47:47.390416000 +0800 @@ -411,6 +411,8 @@ #define DBUS_ERROR_INVALID_FILE_CONTENT "org.freedesktop.DBus.Error.InvalidFileContent" /** Asked for SELinux security context and it wasn't available. */ #define DBUS_ERROR_SELINUX_SECURITY_CONTEXT_UNKNOWN "org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown" +/** Asked for ADT audit data and it wasn't available. */ +#define DBUS_ERROR_ADT_AUDIT_DATA_UNKNOWN "org.freedesktop.DBus.Error.AdtAuditDataUnknown" /** There's already an object with the requested object path. */ #define DBUS_ERROR_OBJECT_PATH_IN_USE "org.freedesktop.DBus.Error.ObjectPathInUse" diff -Nur dbus-1.2.1/dbus/dbus-sysdeps-unix.c dbus-1.2.1-new/dbus/dbus-sysdeps-unix.c --- dbus-1.2.1/dbus/dbus-sysdeps-unix.c 2008-04-04 23:24:08.000000000 +0800 +++ dbus-1.2.1-new/dbus/dbus-sysdeps-unix.c 2008-04-30 17:47:47.392654000 +0800 @@ -1260,6 +1260,37 @@ { pid_read = ucred_getpid (ucred); uid_read = ucred_geteuid (ucred); +#ifdef HAVE_ADT + /* generate audit session data based on socket ucred */ + adt_session_data_t *adth = NULL; + adt_export_data_t *data = NULL; + size_t size = 0; + if (adt_start_session (&adth, NULL, 0) || (adth == NULL)) + { + _dbus_verbose ("Failed to adt_start_session(): %s\n", _dbus_strerror (errno)); + } + else + { + if (adt_set_from_ucred (adth, ucred, ADT_NEW)) + { + _dbus_verbose ("Failed to adt_set_from_ucred(): %s\n", _dbus_strerror (errno)); + } + else + { + size = adt_export_session_data (adth, &data); + if (size <= 0) + { + _dbus_verbose ("Failed to adt_export_session_data(): %s\n", _dbus_strerror (errno)); + } + else + { + _dbus_credentials_add_audit_data (credentials, data, size); + free (data); + } + } + (void) adt_end_session(adth); + } +#endif /* HAVE_ADT */ } else { diff -Nur dbus-1.2.1/dbus/dbus-transport.c dbus-1.2.1-new/dbus/dbus-transport.c --- dbus-1.2.1/dbus/dbus-transport.c 2008-04-04 23:24:08.000000000 +0800 +++ dbus-1.2.1-new/dbus/dbus-transport.c 2008-04-30 17:47:47.393723000 +0800 @@ -1261,6 +1261,42 @@ return FALSE; } +#ifdef HAVE_ADT +/** + * See dbus_connection_get_audit_session_data(). + * + * @param transport the transport + * @param data return location for the ADT audit data + * @param data_size return length of audit data + * @returns #TRUE if audit data is filled in with a valid ucred + */ +dbus_bool_t +_dbus_transport_get_audit_session_data (DBusTransport *transport, + void **data, + int *data_size) +{ + DBusCredentials *auth_identity; + + *data = NULL; + *data_size = 0; + + if (!transport->authenticated) + return FALSE; + + auth_identity = _dbus_auth_get_identity (transport->auth); + + if (_dbus_credentials_include (auth_identity, + DBUS_CREDENTIAL_AUDIT_DATA_ID)) + { + *data = (void *) _dbus_credentials_get_audit_data (auth_identity); + *data_size = _dbus_credentials_get_audit_data_size (auth_identity); + return TRUE; + } + else + return FALSE; +} +#endif /* HAVE_ADT */ + /** * See dbus_connection_set_unix_user_function(). * diff -Nur dbus-1.2.1/dbus/dbus-transport.h dbus-1.2.1-new/dbus/dbus-transport.h --- dbus-1.2.1/dbus/dbus-transport.h 2008-04-04 23:24:08.000000000 +0800 +++ dbus-1.2.1-new/dbus/dbus-transport.h 2008-04-30 17:47:47.395657000 +0800 @@ -64,6 +64,11 @@ unsigned long *uid); dbus_bool_t _dbus_transport_get_unix_process_id (DBusTransport *transport, unsigned long *pid); +#ifdef HAVE_ADT +dbus_bool_t _dbus_transport_get_audit_session_data (DBusTransport *transport, + void **data, + int *data_size); +#endif void _dbus_transport_set_unix_user_function (DBusTransport *transport, DBusAllowUnixUserFunction function, void *data,