summaryrefslogtreecommitdiffstats
path: root/dbus
diff options
context:
space:
mode:
Diffstat (limited to 'dbus')
-rw-r--r--dbus/dbus-auth.c7
-rw-r--r--dbus/dbus-bus.c2
-rw-r--r--dbus/dbus-connection.c56
-rw-r--r--dbus/dbus-connection.h3
-rw-r--r--dbus/dbus-credentials.c79
-rw-r--r--dbus/dbus-credentials.h3
-rw-r--r--dbus/dbus-protocol.h2
-rw-r--r--dbus/dbus-sysdeps-unix.c52
-rw-r--r--dbus/dbus-transport.c34
-rw-r--r--dbus/dbus-transport.h3
-rw-r--r--dbus/dbus-userdb-util.c2
-rw-r--r--dbus/dbus-userdb.c2
12 files changed, 232 insertions, 13 deletions
diff --git a/dbus/dbus-auth.c b/dbus/dbus-auth.c
index 7e424aff..ec7cf312 100644
--- a/dbus/dbus-auth.c
+++ b/dbus/dbus-auth.c
@@ -1094,6 +1094,13 @@ handle_server_data_external_mech (DBusAuth *auth,
DBUS_CREDENTIAL_UNIX_PROCESS_ID,
auth->credentials))
return FALSE;
+
+ /* also copy audit data from the socket credentials
+ */
+ if (!_dbus_credentials_add_credential (auth->authorized_identity,
+ DBUS_CREDENTIAL_ADT_AUDIT_DATA_ID,
+ auth->credentials))
+ return FALSE;
if (!send_ok (auth))
return FALSE;
diff --git a/dbus/dbus-bus.c b/dbus/dbus-bus.c
index e159dae7..f97cce68 100644
--- a/dbus/dbus-bus.c
+++ b/dbus/dbus-bus.c
@@ -124,6 +124,8 @@ addresses_shutdown_func (void *data)
}
activation_bus_type = DBUS_BUS_STARTER;
+
+ initialized = FALSE;
}
static dbus_bool_t
diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c
index 2e291eee..a960a991 100644
--- a/dbus/dbus-connection.c
+++ b/dbus/dbus-connection.c
@@ -1678,21 +1678,26 @@ connection_forget_shared_unlocked (DBusConnection *connection)
if (!connection->shareable)
return;
+ _DBUS_LOCK (shared_connections);
+
if (connection->server_guid != NULL)
{
_dbus_verbose ("dropping connection to %s out of the shared table\n",
connection->server_guid);
- _DBUS_LOCK (shared_connections);
-
if (!_dbus_hash_table_remove_string (shared_connections,
connection->server_guid))
_dbus_assert_not_reached ("connection was not in the shared table");
dbus_free (connection->server_guid);
connection->server_guid = NULL;
- _DBUS_UNLOCK (shared_connections);
}
+ else
+ {
+ _dbus_list_remove (&shared_connections_no_guid, connection);
+ }
+
+ _DBUS_UNLOCK (shared_connections);
/* remove our reference held on all shareable connections */
_dbus_connection_unref_unlocked (connection);
@@ -3411,9 +3416,13 @@ _dbus_connection_read_write_dispatch (DBusConnection *connection,
dbus_bool_t dispatch)
{
DBusDispatchStatus dstatus;
- dbus_bool_t no_progress_possible;
dbus_bool_t progress_possible;
-
+
+ /* Need to grab a ref here in case we're a private connection and
+ * the user drops the last ref in a handler we call; see bug
+ * https://bugs.freedesktop.org/show_bug.cgi?id=15635
+ */
+ dbus_connection_ref (connection);
dstatus = dbus_connection_get_dispatch_status (connection);
if (dispatch && dstatus == DBUS_DISPATCH_DATA_REMAINS)
@@ -3454,6 +3463,9 @@ _dbus_connection_read_write_dispatch (DBusConnection *connection,
progress_possible = _dbus_connection_get_is_connected_unlocked (connection);
CONNECTION_UNLOCK (connection);
+
+ dbus_connection_unref (connection);
+
return progress_possible; /* TRUE if we can make more progress */
}
@@ -4973,6 +4985,40 @@ dbus_connection_get_unix_process_id (DBusConnection *connection,
}
/**
+ * 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_adt_audit_session_data (connection->transport,
+ data,
+ data_size);
+ CONNECTION_UNLOCK (connection);
+
+ return result;
+}
+
+/**
* Sets a predicate function used to determine whether a given user ID
* is allowed to connect. When an incoming connection has
* authenticated with a particular user ID, this function is called;
diff --git a/dbus/dbus-connection.h b/dbus/dbus-connection.h
index 5d7e493b..b8fd35fb 100644
--- a/dbus/dbus-connection.h
+++ b/dbus/dbus-connection.h
@@ -231,6 +231,9 @@ dbus_bool_t dbus_connection_get_unix_user (DBusConnection
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 --git a/dbus/dbus-credentials.c b/dbus/dbus-credentials.c
index 790ca06b..f21ecb27 100644
--- a/dbus/dbus-credentials.c
+++ b/dbus/dbus-credentials.c
@@ -50,6 +50,8 @@ struct DBusCredentials {
dbus_uid_t unix_uid;
dbus_pid_t unix_pid;
char *windows_sid;
+ void *adt_audit_data;
+ dbus_int32_t adt_audit_data_size;
};
/** @} */
@@ -77,6 +79,8 @@ _dbus_credentials_new (void)
creds->unix_uid = DBUS_UID_UNSET;
creds->unix_pid = DBUS_PID_UNSET;
creds->windows_sid = NULL;
+ creds->adt_audit_data = NULL;
+ creds->adt_audit_data_size = 0;
return creds;
}
@@ -129,6 +133,7 @@ _dbus_credentials_unref (DBusCredentials *credentials)
if (credentials->refcount == 0)
{
dbus_free (credentials->windows_sid);
+ dbus_free (credentials->adt_audit_data);
dbus_free (credentials);
}
}
@@ -188,6 +193,31 @@ _dbus_credentials_add_windows_sid (DBusCredentials *credentials,
}
/**
+ * Add ADT audit data to the credentials.
+ *
+ * @param credentials the object
+ * @param audit_data the audit data
+ * @param size the length of audit data
+ * @returns #FALSE if no memory
+ */
+dbus_bool_t
+_dbus_credentials_add_adt_audit_data (DBusCredentials *credentials,
+ void *audit_data,
+ dbus_int32_t size)
+{
+ void *copy;
+ copy = _dbus_memdup (audit_data, size);
+ if (copy == NULL)
+ return FALSE;
+
+ dbus_free (credentials->adt_audit_data);
+ credentials->adt_audit_data = copy;
+ credentials->adt_audit_data_size = size;
+
+ return TRUE;
+}
+
+/**
* Checks whether the given credential is present.
*
* @param credentials the object
@@ -206,6 +236,8 @@ _dbus_credentials_include (DBusCredentials *credentials,
return credentials->unix_uid != DBUS_UID_UNSET;
case DBUS_CREDENTIAL_WINDOWS_SID:
return credentials->windows_sid != NULL;
+ case DBUS_CREDENTIAL_ADT_AUDIT_DATA_ID:
+ return credentials->adt_audit_data != NULL;
}
_dbus_assert_not_reached ("Unknown credential enum value");
@@ -252,6 +284,32 @@ _dbus_credentials_get_windows_sid (DBusCredentials *credentials)
}
/**
+ * Gets the ADT audit data in the credentials, or #NULL if
+ * the credentials object doesn't contain ADT audit data.
+ *
+ * @param credentials the object
+ * @returns Solaris ADT audit data
+ */
+void *
+_dbus_credentials_get_adt_audit_data (DBusCredentials *credentials)
+{
+ return credentials->adt_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 Solaris ADT audit data size
+ */
+dbus_int32_t
+_dbus_credentials_get_adt_audit_data_size (DBusCredentials *credentials)
+{
+ return credentials->adt_audit_data_size;
+}
+
+/**
* Checks whether the first credentials object contains
* all the credentials found in the second credentials object.
*
@@ -270,7 +328,11 @@ _dbus_credentials_are_superset (DBusCredentials *credentials,
possible_subset->unix_uid == credentials->unix_uid) &&
(possible_subset->windows_sid == NULL ||
(credentials->windows_sid && strcmp (possible_subset->windows_sid,
- credentials->windows_sid) == 0));
+ credentials->windows_sid) == 0)) &&
+ (possible_subset->adt_audit_data == NULL ||
+ (credentials->adt_audit_data && memcmp (possible_subset->adt_audit_data,
+ credentials->adt_audit_data,
+ credentials->adt_audit_data_size) == 0));
}
/**
@@ -285,7 +347,8 @@ _dbus_credentials_are_empty (DBusCredentials *credentials)
return
credentials->unix_pid == DBUS_PID_UNSET &&
credentials->unix_uid == DBUS_UID_UNSET &&
- credentials->windows_sid == NULL;
+ credentials->windows_sid == NULL &&
+ credentials->adt_audit_data == NULL;
}
/**
@@ -322,6 +385,9 @@ _dbus_credentials_add_credentials (DBusCredentials *credentials,
DBUS_CREDENTIAL_UNIX_USER_ID,
other_credentials) &&
_dbus_credentials_add_credential (credentials,
+ DBUS_CREDENTIAL_ADT_AUDIT_DATA_ID,
+ other_credentials) &&
+ _dbus_credentials_add_credential (credentials,
DBUS_CREDENTIAL_WINDOWS_SID,
other_credentials);
}
@@ -360,6 +426,12 @@ _dbus_credentials_add_credential (DBusCredentials *credentials,
{
if (!_dbus_credentials_add_windows_sid (credentials, other_credentials->windows_sid))
return FALSE;
+ }
+ else if (which == DBUS_CREDENTIAL_ADT_AUDIT_DATA_ID &&
+ other_credentials->adt_audit_data != NULL)
+ {
+ if (!_dbus_credentials_add_adt_audit_data (credentials, other_credentials->adt_audit_data, other_credentials->adt_audit_data_size))
+ return FALSE;
}
return TRUE;
@@ -377,6 +449,9 @@ _dbus_credentials_clear (DBusCredentials *credentials)
credentials->unix_uid = DBUS_UID_UNSET;
dbus_free (credentials->windows_sid);
credentials->windows_sid = NULL;
+ dbus_free (credentials->adt_audit_data);
+ credentials->adt_audit_data = NULL;
+ credentials->adt_audit_data_size = 0;
}
/**
diff --git a/dbus/dbus-credentials.h b/dbus/dbus-credentials.h
index b8d7dd7a..d4c8d160 100644
--- a/dbus/dbus-credentials.h
+++ b/dbus/dbus-credentials.h
@@ -33,6 +33,7 @@ DBUS_BEGIN_DECLS
typedef enum {
DBUS_CREDENTIAL_UNIX_PROCESS_ID,
DBUS_CREDENTIAL_UNIX_USER_ID,
+ DBUS_CREDENTIAL_ADT_AUDIT_DATA_ID,
DBUS_CREDENTIAL_WINDOWS_SID
} DBusCredentialType;
@@ -51,6 +52,8 @@ dbus_bool_t _dbus_credentials_include (DBusCredentials
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);
+void * _dbus_credentials_get_adt_audit_data (DBusCredentials *credentials);
+dbus_int32_t _dbus_credentials_get_adt_audit_data_size (DBusCredentials *credentials);
dbus_bool_t _dbus_credentials_are_superset (DBusCredentials *credentials,
DBusCredentials *possible_subset);
dbus_bool_t _dbus_credentials_are_empty (DBusCredentials *credentials);
diff --git a/dbus/dbus-protocol.h b/dbus/dbus-protocol.h
index 58677dcf..814deae0 100644
--- a/dbus/dbus-protocol.h
+++ b/dbus/dbus-protocol.h
@@ -411,6 +411,8 @@ extern "C" {
#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 --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c
index 19858dd3..64d925d9 100644
--- a/dbus/dbus-sysdeps-unix.c
+++ b/dbus/dbus-sysdeps-unix.c
@@ -71,6 +71,10 @@
#include <ucred.h>
#endif
+#ifdef HAVE_ADT
+#include <bsm/adt.h>
+#endif
+
#ifndef O_BINARY
#define O_BINARY 0
#endif
@@ -1260,6 +1264,37 @@ _dbus_read_credentials_socket (int client_fd,
{
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_adt_audit_data (credentials, data, size);
+ free (data);
+ }
+ }
+ (void) adt_end_session (adth);
+ }
+#endif /* HAVE_ADT */
}
else
{
@@ -2848,7 +2883,10 @@ _dbus_get_autolaunch_address (DBusString *address,
if (pid == 0)
{
/* child process */
- int fd = open ("/dev/null", O_RDWR);
+ int maxfds;
+ int fd;
+
+ fd = open ("/dev/null", O_RDWR);
if (fd == -1)
/* huh?! can't open /dev/null? */
_exit (1);
@@ -2869,9 +2907,15 @@ _dbus_get_autolaunch_address (DBusString *address,
if (dup2 (errors_pipe[WRITE_END], 2) == -1)
_exit (1);
- close (fd);
- close (address_pipe[WRITE_END]);
- close (errors_pipe[WRITE_END]);
+ maxfds = sysconf (_SC_OPEN_MAX);
+ /* Pick something reasonable if for some reason sysconf
+ * says unlimited.
+ */
+ if (maxfds < 0)
+ maxfds = 1024;
+ /* close all inherited fds */
+ for (i = 3; i < maxfds; i++)
+ close (i);
execv (DBUS_BINDIR "/dbus-launch", argv);
diff --git a/dbus/dbus-transport.c b/dbus/dbus-transport.c
index 1e1fc97d..90291980 100644
--- a/dbus/dbus-transport.c
+++ b/dbus/dbus-transport.c
@@ -1262,6 +1262,40 @@ _dbus_transport_get_unix_process_id (DBusTransport *transport,
}
/**
+ * See dbus_connection_get_adt_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_adt_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_ADT_AUDIT_DATA_ID))
+ {
+ *data = (void *) _dbus_credentials_get_adt_audit_data (auth_identity);
+ *data_size = _dbus_credentials_get_adt_audit_data_size (auth_identity);
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+/**
* See dbus_connection_set_unix_user_function().
*
* @param transport the transport
diff --git a/dbus/dbus-transport.h b/dbus/dbus-transport.h
index 9a9e5532..691763ca 100644
--- a/dbus/dbus-transport.h
+++ b/dbus/dbus-transport.h
@@ -64,6 +64,9 @@ dbus_bool_t _dbus_transport_get_unix_user (DBusTransport
unsigned long *uid);
dbus_bool_t _dbus_transport_get_unix_process_id (DBusTransport *transport,
unsigned long *pid);
+dbus_bool_t _dbus_transport_get_adt_audit_session_data (DBusTransport *transport,
+ void **data,
+ int *data_size);
void _dbus_transport_set_unix_user_function (DBusTransport *transport,
DBusAllowUnixUserFunction function,
void *data,
diff --git a/dbus/dbus-userdb-util.c b/dbus/dbus-userdb-util.c
index 30d50832..d03a7c78 100644
--- a/dbus/dbus-userdb-util.c
+++ b/dbus/dbus-userdb-util.c
@@ -223,7 +223,7 @@ _dbus_user_database_lookup_group (DBusUserDatabase *db,
gid = n;
}
-#ifdef DBUS_ENABLE_USER_CACHE
+#ifdef DBUS_ENABLE_USERDB_CACHE
if (gid != DBUS_GID_UNSET)
info = _dbus_hash_table_lookup_ulong (db->groups, gid);
else
diff --git a/dbus/dbus-userdb.c b/dbus/dbus-userdb.c
index 0e430b2b..03d263f4 100644
--- a/dbus/dbus-userdb.c
+++ b/dbus/dbus-userdb.c
@@ -143,7 +143,7 @@ _dbus_user_database_lookup (DBusUserDatabase *db,
uid = n;
}
-#ifdef DBUS_ENABLE_USER_CACHE
+#ifdef DBUS_ENABLE_USERDB_CACHE
if (uid != DBUS_UID_UNSET)
info = _dbus_hash_table_lookup_ulong (db->users, uid);
else